- /* get the current command and parse it*/
- if (fgets(buffer, bufsize, ed_cmds) == NULL) {
- return line;
- }
- startline = strtol(buffer, &idx, 10);
- if (startline < line) {
- return ED_ORDERING;
- }
- if (*idx == ',') {
- idx++;
- stopline = strtol(idx, &idx, 10);
- }
- else {
- stopline = startline;
- }
- if (*idx == 'c') {
- mode = MODE_CHANGED;
- if (Debug == true) {
- std::clog << "changing from line " << startline
- << " to " << stopline << std::endl;
- }
- }
- else if (*idx == 'a') {
- mode = MODE_ADDED;
- if (Debug == true) {
- std::clog << "adding after line " << startline << std::endl;
- }
- }
- else if (*idx == 'd') {
- mode = MODE_DELETED;
- if (Debug == true) {
- std::clog << "deleting from line " << startline
- << " to " << stopline << std::endl;
- }
- }
- else {
- return ED_PARSER;
- }
- /* get the current position */
- pos = ftell(ed_cmds);
- /* if this is add or change then go to the next full stop */
- if ((mode == MODE_CHANGED) || (mode == MODE_ADDED)) {
- do {
- fgets(buffer, bufsize, ed_cmds);
- while ((strlen(buffer) == (bufsize - 1))
- && (buffer[bufsize - 2] != '\n')) {
- fgets(buffer, bufsize, ed_cmds);
- buffer[0] = ' ';
- }
- } while (strncmp(buffer, ".", 1) != 0);
- }
- /* do the recursive call */
- line = ed_rec(ed_cmds, in_file, out_file, line, buffer, bufsize,
- hash);
- /* pass on errors */
- if (line < 0) {
- return line;
- }
- /* apply our hunk */
- fseek(ed_cmds, pos, SEEK_SET);
- /* first wind to the current position */
- if (mode != MODE_ADDED) {
- startline -= 1;
- }
- while (line < startline) {
- fgets(buffer, bufsize, in_file);
- written = fwrite(buffer, 1, strlen(buffer), out_file);
- hash->Add((unsigned char*)buffer, written);
- while ((strlen(buffer) == (bufsize - 1))
- && (buffer[bufsize - 2] != '\n')) {
- fgets(buffer, bufsize, in_file);
- written = fwrite(buffer, 1, strlen(buffer), out_file);
- hash->Add((unsigned char*)buffer, written);
- }
- line++;
- }
- /* include from ed script */
- if ((mode == MODE_ADDED) || (mode == MODE_CHANGED)) {
- do {
- fgets(buffer, bufsize, ed_cmds);
- if (strncmp(buffer, ".", 1) != 0) {
- written = fwrite(buffer, 1, strlen(buffer), out_file);
- hash->Add((unsigned char*)buffer, written);
- while ((strlen(buffer) == (bufsize - 1))
- && (buffer[bufsize - 2] != '\n')) {
- fgets(buffer, bufsize, ed_cmds);
- written = fwrite(buffer, 1, strlen(buffer), out_file);
- hash->Add((unsigned char*)buffer, written);
- }
- }
- else {
- break;
- }
- } while (1);
- }
- /* ignore the corresponding number of lines from input */
- if ((mode == MODE_DELETED) || (mode == MODE_CHANGED)) {
- while (line < stopline) {
- fgets(buffer, bufsize, in_file);
- while ((strlen(buffer) == (bufsize - 1))
- && (buffer[bufsize - 2] != '\n')) {
- fgets(buffer, bufsize, in_file);
- }
- line++;
- }
- }
- return line;
-}
+ // which command to execute on this line(s)?
+ switch (*idx) {
+ case MODE_CHANGED:
+ if (Debug == true)
+ std::clog << "Change from line " << startline << " to " << stopline << std::endl;
+ break;
+ case MODE_ADDED:
+ if (Debug == true)
+ std::clog << "Insert after line " << startline << std::endl;
+ break;
+ case MODE_DELETED:
+ if (Debug == true)
+ std::clog << "Delete from line " << startline << " to " << stopline << std::endl;
+ break;
+ default:
+ _error->Error("rred: Unknown ed command '%c'. Abort.", *idx);
+ return ED_PARSER;
+ }
+ unsigned char mode = *idx;
+
+ // save the current position
+ unsigned const long pos = ftell(ed_cmds);
+
+ // if this is add or change then go to the next full stop
+ if (mode == MODE_CHANGED || mode == MODE_ADDED) {
+ do
+ ignoreLineInFile(ed_cmds, buffer);
+ while (strncmp(buffer, ".", 1) != 0);
+ }
+
+ // do the recursive call - the last command is the one we need to execute at first
+ const State child = applyFile(ed_cmds, in_file, out_file, line, buffer, hash);
+ if (child != ED_OK) {
+ return child;
+ }
+
+ // change and delete are working on "line" - add is done after "line"
+ if (mode != MODE_ADDED)
+ line++;
+
+ // first wind to the current position and copy over all unchanged lines
+ while (line < startline) {
+ fgets(buffer, BUF_SIZE, in_file);
+ copyLineFromFileToFile(in_file, out_file, hash, buffer);
+ line++;
+ }
+
+ if (mode != MODE_ADDED)
+ line--;