static void process_delta(Node *node, enum stringwork func) { long editline = 0, linecnt = 0, adjust = 0; int editor_command; struct diffcmd dc; uchar *ptr; Glog = node->p->log; in_buffer_init((uchar *)node->p->text, 1); Gversion = node->v; cvs_number_string(&Gversion->number, Gversion_number); switch (func) { case ENTER: while( (ptr=in_get_line()) ) insertline(editline++, ptr); case EDIT: dc.dafter = dc.adprev = 0; while ((editor_command = parse_next_delta_command(&dc)) >= 0) { if (editor_command) { editline = dc.line1 + adjust; linecnt = dc.nlines; while(linecnt--) insertline(editline++, in_get_line()); adjust += dc.nlines; } else { deletelines(dc.line1 - 1 + adjust, dc.nlines); adjust -= dc.nlines; } } break; } }
int loadfile(file_t *file, const char *filename) { FILE *f; char buf[1024]; int len; f = fopen(filename, "rb"); if(!f) return 1; len = 0; for(;;) { char *ptr; int linelen; /* fill buffer */ len += fread(&buf[len], 1, sizeof(buf)-len, f); /* get line length */ ptr = memchr(buf, '\n', len); if(ptr) linelen = ptr - buf; else linelen = len; /* add new line */ insertline(file, file->line_count); if(linelen) inserttext(file, 0, file->line_count-1, buf, linelen); /* last line? */ if(!ptr) break; len -= linelen+1; memmove(buf, &buf[linelen+1], len); } fclose(f); return 0; }
/* * Add lines which are typed in by the user. * The lines are inserted just before the specified line number. * The lines are terminated by a line containing a single dot (ugly!), * or by an end of file. */ static void addlines(NUM num) { int len; while (fgets(buf, sizeof(buf), stdin)) { if ((buf[0] == '.') && (buf[1] == '\n') && (buf[2] == '\0')) return; len = strlen(buf); if (len == 0) return; if (buf[len - 1] != '\n') { fprintf(stderr, "Line too long\n"); do { len = fgetc(stdin); } while ((len != EOF) && (len != '\n')); return; } if (!insertline(num++, buf, len)) return; } }
bool playfield::solve(bool hv,const int lcnumber, const vector<int> & zeilenorder, const vector<int> & spaltenorder, vector<vector<Feldelemente> > & Feld, possiblevalueslc &posspl) { ++iterationsteps; //displayplayfield(Feld); // pruefe ob das bei den folgenden Zeilen widerspruch zu aktuellem // Feld auftritt, wenn ja gehe gleich zurück. // evt erst ab einer gewissen tiefe nutzen //if(lcnumber>=2) { bool linejispossible; for(int j=(lcnumber+1);j<size();++j) { linejispossible=false; const int & anummer=hv ? zeilenorder[j] : spaltenorder[j]; vector<vector<int> > & apermset = hv ? hpermutations[anummer] : vpermutations[anummer]; for(unsigned int k=0;k<apermset.size();++k) { if(insertline(hv,anummer,apermset[k],Feld,posspl,false)) { linejispossible=true; break; // es reicht eine moeglichkeit zu finden } } if(!linejispossible) { return false; // Falls keine der noch folgenden Spalten/Zeilen passt, braucht diese Zeile nicht weiter untersucht zu werden } } //} //} if(iterationsteps%10000==0) { cout << iterationsteps << endl; displayplayfield(Feld); } // if(iterationsteps==5000000) { // exit(0); // not ready only for profiling, delete it // } if(lcnumber == size() ) { cout << " ---- success ----" << endl; cout << "Solution found after " << iterationsteps << " iterations" << endl; return true; // Das gesamte Spielfeld ist mit gueltigen Zahlen gefuellt. } int nextnumber=lcnumber; int zsnummer=hv ? zeilenorder[lcnumber] : spaltenorder[lcnumber]; vector<vector<int> > &apermset= hv? hpermutations[zsnummer] : vpermutations[zsnummer]; vector<vector<Feldelemente> > feldkopie = Feld; possiblevalueslc possplkopie = posspl; for(unsigned int l=0;l<apermset.size();++l) { vector<int> & zeile=apermset[l]; //feldkopie=Feld; if(insertline(hv,hv ? zeilenorder[lcnumber] : spaltenorder[lcnumber],zeile,feldkopie, possplkopie,true) ) { //displayplayfield(feldkopie); if(!hv) nextnumber=lcnumber+1; else nextnumber=lcnumber; //wichtig dies explizit zu setzen, da sonst bei ruekehr aus rekusrion evt. falsch // Wenn wieder eine Zeile, muss die nummer des index erhoet werden if(solve(!hv,nextnumber,zeilenorder,spaltenorder,feldkopie,possplkopie) ) { //Loesung gefunden -> zurueck Feld=feldkopie; return true; } else { feldkopie=Feld; // Feldkopie hatte sich geandert, da zeile probiert wurde possplkopie=posspl; // muss nun wieder zurueckgesetzt werden fuer naechsten versuch } } // displayplayfield(feldkopie); // displayplayfield(Feld); } return false; }
vector<vector<int> > playfield::calculate_all_permutations(const bool &hv,const int & zsnummer) { vector<vector<vector<int> > > allblogs; vector<vector<int> > result; vector<vector<bool>> possibleinthisline; possibleinthisline.resize(size()); for(unsigned int i=0;i<possibleinthisline.size();++i){ possibleinthisline[i].resize(maxnumber+1); for(unsigned int j=0;j<possibleinthisline[i].size();++j) { possibleinthisline[i][j]=false; } } result.clear(); //vector<vector<int>> zeilen; allblogs=find_compatible_blogs( hv ? hblocks().at(zsnummer) : vblocks().at(zsnummer)); for(unsigned int l=0;l<allblogs.size();++l) { vector<vector<int> > &blogs=allblogs[l]; vector<int> zeile; int N=blogs.size(); int numberofdigits=0; int freezeros; // int placesforzero=N+1; // Anzahl der Plaetze auf denen Nullen liegen duerfen // zwischen den Bloecken und am Rand vector<int> zerosatplace; zerosatplace.assign(N+1,0); for(int i=0;i<N;++i) { numberofdigits+=blogs[i].size(); } //Anzahl der Ziffern in der Zeile bestimmen freezeros=size()-numberofdigits-(N-1); // Anzahl der frei verteilbaren Nullen ist // Spielfeldgroesse - Anzahl der Nullen zwichen Blocks - Anzahl der Ziffern if(freezeros<0){ //cout << "jetzt" << endl; continue; // Falls Bloecke nicht ins Feld passen, naechsten Satz von Bloecken betrachten } zerosatplace.back()=freezeros; // Beim ersten Versuch werden alle Nullen hinten angehaegt. zeile.clear(); bool notcomplete=true; while(notcomplete) { vector<pair<vector<int>::iterator,vector<int>::iterator> > blockgrenzen; // um nachher die Permutationen zu erzeugen blockgrenzen.resize(N); zeile.clear(); zeile.reserve(size()); //Speicher fuer Zeile allokieren zeile.insert(zeile.begin(),zerosatplace[0],0); // Nullen vor den Bloecken einfuegen for(int i=0;i<N;++i) { blockgrenzen[i].first=zeile.end(); //Anfang und Ende der Bloecke merken zeile.insert(zeile.end(),blogs[i].begin(),blogs[i].end()); blockgrenzen[i].second=zeile.end(); // umd diese nacher duchzupermutieren if(i!=N-1) { zeile.push_back(0); // obligatorische Trennungsnull zwischen Bloecken } zeile.insert(zeile.end(),zerosatplace[i+1],0); // Nullen zwischen bloecken einfuegen } bool permutefertig=false; do{ //vector<vector<Feldelemente> > feldkopie; //feldkopie=entries(); // if(zeile[0]==0) { // cout << "jetzt" << endl; // } if(insertline(hv,zsnummer,zeile,entries(),possp,false)){ result.push_back(zeile); for(unsigned int k=0;k<zeile.size();++k){ possibleinthisline[k][zeile[k]]=true; // Wert zeile[k] ist an pos k moeglich } } vector<pair<vector<int>::iterator,vector<int>::iterator> >::reverse_iterator permutiter=blockgrenzen.rbegin(); bool permutincreasefertig=false; do{ if(next_permutation(permutiter->first,permutiter->second)) { permutincreasefertig=true; } else { ++permutiter; if(permutiter==blockgrenzen.rend()) { permutincreasefertig=true; permutefertig=true; break; } else permutincreasefertig=false; } } while(!permutincreasefertig); } while(!permutefertig); vector<int>::iterator iterr=zerosatplace.end(); vector<int>::iterator iter=zerosatplace.begin(); --iterr; --iterr; //Zeiger auf vorletztes Element bool fertig; int obergrenze; do{ obergrenze=freezeros; for(iter=zerosatplace.begin();iter!=iterr;++iter) { obergrenze-=*iter; } if(*iterr<obergrenze) { ++(*iterr); fertig=true; } else { if(iter!=zerosatplace.begin()) { *iterr=0; --iterr; fertig=false; } else{ notcomplete=false; fertig=true; break; } } } while(!fertig); // Die Elemente von Zerosatplace werden so duechiteriert, dass // fuer das 1. Element die Werte 0..freezeros durchlaufen werden // fuer das 2. Element die Werte 0..frezeros-1. Element // usw das letzte Glied ergibt sich aus den anderen, so das die Summe // freezeros ist zerosatplace.back()=freezeros; for(unsigned int i=0;i<(zerosatplace.size()-1);++i) { zerosatplace.back()-=zerosatplace[i]; } //auf diese Art und Weise werden alle Permutartionen von Plätzen wo die Null sein kann durchlaufen. } } for(unsigned int k=0;k<possibleinthisline.size();++k) { int zeilennr; int spaltennr; if(hv) { zeilennr=zsnummer; spaltennr=k; } else { zeilennr=k; spaltennr=zsnummer; } for(int wert=0;wert<=maxnumber;++wert) if(feldelpos[zeilennr][spaltennr].wertpossible[wert] && possibleinthisline[k][wert]){ feldelpos[zeilennr][spaltennr].wertpossible[wert]=true; } else { if(feldelpos[zeilennr][spaltennr].wertpossible[wert]) { feldelpos[zeilennr][spaltennr].wertpossible[wert]=false; somethingchanges=true; } } } return result; }
/* editor event loop */ int editor_loop() { int ch; file_t *file; file = files[current]; ch = getch(); switch(ch) { case KEY_RESIZE: getmaxyx(screen, h, w); drawmenu(); drawscreen(); break; case KEY_F(5): /* display help */ drawhelp(); refresh(); while(!help_loop()); drawscreen(); break; case KEY_F(6): /* save */ if(file->filename[0]) { writefile(file, file->filename); file->saved = 1; } break; case KEY_F(8): /* force quit */ return 1; case KEY_F(9): /* toggle linenumbers */ show_linenumbers = !show_linenumbers; drawscreen(); break; case KEY_F(10): /* tab size */ tab_size = !tab_size; drawscreen(); break; case KEY_F(11): /* C highlight */ c_highlight = !c_highlight; drawscreen(); break; case 3: /* control-C */ if(file->selected) { /* TODO: copy */ } break; case 11: /* control-K */ if(file->line_count > 1) removeline(file, file->cursor_y); break; case 22: /* control-V */ /* TODO: paste */ break; case 24: /* control-X */ /* quit */ /* TODO: check all open files */ if(file->saved) return 1; break; case 19: /* control-S */ if(file->selected) { int y; /* end selection */ file->selected = 0; for(y = file->sel_begin_y; y <= file->sel_end_y; y++) drawline(file, y); } else { /* begin selection */ file->selected = 1; file->sel_begin_x = file->cursor_x; file->sel_begin_y = file->cursor_y; file->sel_end_x = file->cursor_x; file->sel_end_y = file->cursor_y; } break; case 21: /* control-U */ if(file->selected) { int y; /* un-indent lines */ for(y = file->sel_begin_y; y <= file->sel_end_y; y++) { if(file->lines[y].len && file->lines[y].buf[0] == '\t') removetext(file, 0, y, 1); } } break; case KEY_PPAGE: /* move half screen up */ if(file->cursor_y) { file->cursor_y -= h/2; if(file->cursor_y < 0) file->cursor_y = 0; /* don't go past end of line */ if(file->cursor_x > file->lines[file->cursor_y].len) file->cursor_x = file->lines[file->cursor_y].len; } break; case KEY_NPAGE: /* move half screen down */ if(file->cursor_y < file->line_count-1) { file->cursor_y += h/2; if(file->cursor_y > file->line_count-1) file->cursor_y = file->line_count-1; /* don't go past end of line */ if(file->cursor_x > file->lines[file->cursor_y].len) file->cursor_x = file->lines[file->cursor_y].len; } break; case KEY_UP: if(file->cursor_y) { file->cursor_y--; /* don't go past end of line */ if(file->cursor_x > file->lines[file->cursor_y].len) file->cursor_x = file->lines[file->cursor_y].len; } break; case KEY_DOWN: if(file->cursor_y < file->line_count-1) { file->cursor_y++; /* move cursor to line end */ if(file->cursor_x > file->lines[file->cursor_y].len) file->cursor_x = file->lines[file->cursor_y].len; } break; case KEY_HOME: /* go to begin of line */ if(file->cursor_x) file->cursor_x = 0; break; case KEY_END: /* go to end of line */ if(file->cursor_x < file->lines[file->cursor_y].len) file->cursor_x = file->lines[file->cursor_y].len; break; case KEY_LEFT: /* go to left one character */ if(file->cursor_x) file->cursor_x--; else if(file->cursor_y) { /* jump to end of previous line */ file->cursor_y--; file->cursor_x = file->lines[file->cursor_y].len; } break; case KEY_RIGHT: /* go right one character */ if(file->cursor_x < file->lines[file->cursor_y].len) file->cursor_x++; else if(file->cursor_y < file->line_count-1) { /* jump to begin of next line */ file->cursor_y++; file->cursor_x = 0; } break; case KEY_DC: if(file->selected) { file->selected = 0; /* delete selection */ if(file->sel_begin_y == file->sel_end_y) { /* remove characters from current line */ removetext(file, file->sel_begin_x, file->sel_begin_y, file->sel_end_x - file->sel_begin_x); } else { int y; line_t *line; /* remove ending from the first line */ removetext(file, file->sel_begin_x, file->sel_begin_y, file->lines[file->sel_begin_y].len - file->sel_begin_x); /* copy ending from the last line to the end of first line */ line = &file->lines[file->sel_end_y]; if(file->sel_end_x < line->len) { inserttext(file, file->sel_begin_x, file->sel_begin_y, &line->buf[file->sel_end_x], line->len - file->sel_end_x); } /* remove all lines between the first and last line */ for(y=0; y < file->sel_end_y-file->sel_begin_y; y++) removeline(file, file->sel_begin_y+1); file->cursor_x = file->sel_begin_x; file->cursor_y = file->sel_begin_y; } } else if(file->cursor_x < file->lines[file->cursor_y].len) { /* remove character from cursor position */ removetext(file, file->cursor_x, file->cursor_y, 1); } break; case KEY_BACKSPACE: case '\b': case 127: if(file->cursor_x) { /* remove character from cursor position */ file->cursor_x--; removetext(file, file->cursor_x, file->cursor_y, 1); } else if(file->cursor_y) { line_t *line; /* move to the end of the previous line */ file->cursor_y--; file->cursor_x = file->lines[file->cursor_y].len; /* copy text from the next line to the end of current line */ line = &file->lines[file->cursor_y+1]; if(line->len) { inserttext(file, file->cursor_x, file->cursor_y, line->buf, line->len); } /* and remove the next line */ removeline(file, file->cursor_y+1); } break; case '\r': { line_t *line; /* add new line */ insertline(file, file->cursor_y+1); line = &file->lines[file->cursor_y]; if(file->cursor_x < line->len) { /* copy ending from the current line to the next line */ inserttext(file, 0, file->cursor_y+1, &line->buf[file->cursor_x], line->len - file->cursor_x); /* and remove ending from the current line */ removetext(file, file->cursor_x, file->cursor_y, line->len - file->cursor_x); } /* move cursor to the begin of the next line */ file->cursor_y++; file->cursor_x = 0; } break; case '\t': if(file->selected) { int y; /* indent lines */ for(y = file->sel_begin_y; y <= file->sel_end_y; y++) inserttext(file, 0, y, "\t", 1); break; } /* fall trought */ default: if((ch >= ' ' && ch < 256) || ch == '\t') { unsigned char buf = ch; /* insert character at cursor position */ inserttext(file, file->cursor_x, file->cursor_y, (const char *)&buf, 1); file->cursor_x++; } break; } cursormoved(file); setcursor(); refresh(); return 0; }
int main(int argc, char **argv) { struct termios term, term_saved; file_t *file; if(argc > 2) { printf("ERROR: Invalid arguments!\n"); return 1; } newfile(); file = files[0]; if(argc == 2) { /* filename given */ strcpy(file->filename, argv[1]); loadfile(file, argv[1]); } else file->filename[0] = 0; file->saved = 1; current = 0; /* make sure we got something */ if(!file->line_count) insertline(file, 0); file->cursor_x = 0; file->cursor_y = 0; tcgetattr(0, &term_saved); /* initialize curses */ screen = initscr(); cbreak(); nonl(); noecho(); keypad(screen, TRUE); /* modify terminal settings */ tcgetattr(0, &term); term.c_lflag &= ~(IEXTEN | ISIG); term.c_iflag &= ~IXON; term.c_oflag &= ~OPOST; tcsetattr(0, TCSANOW, &term); /* setup colors */ start_color(); init_pair(1, COLOR_YELLOW, COLOR_BLACK); init_pair(2, COLOR_WHITE, COLOR_BLACK); init_pair(3, COLOR_WHITE, COLOR_BLUE); init_pair(4, COLOR_WHITE, COLOR_BLUE); init_pair(5, COLOR_GREEN, COLOR_BLACK); init_pair(6, COLOR_BLUE, COLOR_BLACK); init_pair(7, COLOR_BLACK, COLOR_BLACK); attron(COLOR_PAIR(2)); getmaxyx(screen, h, w); drawmenu(); drawscreen(); drawpos(); setcursor(); refresh(); /* main loop */ while(!editor_loop()); endwin(); /* revert terminal settings */ tcsetattr(0, TCSANOW, &term_saved); return 0; }
/* * Read lines from a file at the specified line number. * Returns TRUE if the file was successfully read. */ static BOOL readlines(char *file, NUM num) { int fd; int cc; LEN len; LEN linecount; LEN charcount; char *cp; if ((num < 1) || (num > lastnum + 1)) { fprintf(stderr, "Bad line for read\n"); return FALSE; } fd = open(file, 0); if (fd < 0) { perror(file); return FALSE; } bufp = bufbase; bufused = 0; linecount = 0; charcount = 0; printf("\"%s\", ", file); fflush(stdout); do { if (intflag) { printf("INTERRUPTED, "); bufused = 0; break; } cp = memchr(bufp, '\n', bufused); if (cp) { len = (cp - bufp) + 1; if (!insertline(num, bufp, len)) { close(fd); return FALSE; } bufp += len; bufused -= len; charcount += len; linecount++; num++; continue; } if (bufp != bufbase) { memcpy(bufbase, bufp, bufused); bufp = bufbase + bufused; } if (bufused >= bufsize) { len = (bufsize * 3) / 2; cp = realloc(bufbase, len); if (cp == NULL) { fprintf(stderr, "No memory for buffer\n"); close(fd); return FALSE; } bufbase = cp; bufp = bufbase + bufused; bufsize = len; } cc = read(fd, bufp, bufsize - bufused); bufused += cc; bufp = bufbase; } while (cc > 0); if (cc < 0) { perror(file); close(fd); return FALSE; } if (bufused) { if (!insertline(num, bufp, bufused)) { close(fd); return -1; } linecount++; charcount += bufused; } close(fd); printf("%d lines%s, %d chars\n", linecount, (bufused ? " (incomplete)" : ""), charcount); return TRUE; }