sed: fix append command to match GNU sed 4.2.1
authorDenys Vlasenko <vda.linux@googlemail.com>
Fri, 6 May 2016 16:25:56 +0000 (18:25 +0200)
committerDenys Vlasenko <vda.linux@googlemail.com>
Fri, 6 May 2016 16:25:56 +0000 (18:25 +0200)
This closes one testcase failure

Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
editors/sed.c
testsuite/sed.tests

index 7f18fd0c4d42a5ebbefdbc607cdddad0b1707773..f37c37d88cf37ff0429efb09579a3a5d697277fc 100644 (file)
@@ -956,13 +956,22 @@ static void puts_maybe_newline(char *s, FILE *file, char *last_puts_char, char l
        *last_puts_char = lpc;
 }
 
-static void flush_append(char *last_puts_char, char last_gets_char)
+static void flush_append(char *last_puts_char)
 {
        char *data;
 
        /* Output appended lines. */
-       while ((data = (char *)llist_pop(&G.append_head))) {
-               puts_maybe_newline(data, G.nonstdout, last_puts_char, last_gets_char);
+       while ((data = (char *)llist_pop(&G.append_head)) != NULL) {
+               /* Append command does not respect "nonterminated-ness"
+                * of last line. Try this:
+                * $ echo -n "woot" | sed -e '/woot/a woo' -
+                * woot
+                * woo
+                * (both lines are terminated with \n)
+                * Therefore we do not propagate "last_gets_char" here,
+                * pass '\n' instead:
+                */
+               puts_maybe_newline(data, G.nonstdout, last_puts_char, '\n');
                free(data);
        }
 }
@@ -970,13 +979,13 @@ static void flush_append(char *last_puts_char, char last_gets_char)
 /* Get next line of input from G.input_file_list, flushing append buffer and
  * noting if we ran out of files without a newline on the last line we read.
  */
-static char *get_next_line(char *gets_char, char *last_puts_char, char last_gets_char)
+static char *get_next_line(char *gets_char, char *last_puts_char)
 {
        char *temp = NULL;
        int len;
        char gc;
 
-       flush_append(last_puts_char, last_gets_char);
+       flush_append(last_puts_char);
 
        /* will be returned if last line in the file
         * doesn't end with either '\n' or '\0' */
@@ -1054,7 +1063,7 @@ static void process_files(void)
        int substituted;
 
        /* Prime the pump */
-       next_line = get_next_line(&next_gets_char, &last_puts_char, '\n' /*last_gets_char*/);
+       next_line = get_next_line(&next_gets_char, &last_puts_char);
 
        /* Go through every line in each file */
  again:
@@ -1068,7 +1077,7 @@ static void process_files(void)
 
        /* Read one line in advance so we can act on the last line,
         * the '$' address */
-       next_line = get_next_line(&next_gets_char, &last_puts_char, last_gets_char);
+       next_line = get_next_line(&next_gets_char, &last_puts_char);
        linenum++;
 
        /* For every line, go through all the commands */
@@ -1295,7 +1304,7 @@ static void process_files(void)
                                free(pattern_space);
                                pattern_space = next_line;
                                last_gets_char = next_gets_char;
-                               next_line = get_next_line(&next_gets_char, &last_puts_char, last_gets_char);
+                               next_line = get_next_line(&next_gets_char, &last_puts_char);
                                substituted = 0;
                                linenum++;
                                break;
@@ -1331,7 +1340,7 @@ static void process_files(void)
                        pattern_space[len] = '\n';
                        strcpy(pattern_space + len+1, next_line);
                        last_gets_char = next_gets_char;
-                       next_line = get_next_line(&next_gets_char, &last_puts_char, last_gets_char);
+                       next_line = get_next_line(&next_gets_char, &last_puts_char);
                        linenum++;
                        break;
                }
@@ -1435,7 +1444,7 @@ static void process_files(void)
 
        /* Delete and such jump here. */
  discard_line:
-       flush_append(&last_puts_char, last_gets_char);
+       flush_append(&last_puts_char /*,last_gets_char*/);
        free(pattern_space);
 
        goto again;
index c4b6fa278fbc4d141ba382047c261c0f588e1332..a71f8b1f00c5e797afd148b68e7f164725b46fc5 100755 (executable)
@@ -135,10 +135,12 @@ testing "sed empty file plus cat" "sed -e 's/nohit//' input -" "one\ntwo" \
        "" "one\ntwo"
 testing "sed cat plus empty file" "sed -e 's/nohit//' input -" "one\ntwo" \
        "one\ntwo" ""
-test x"$SKIP_KNOWN_BUGS" = x"" && {
 testing "sed append autoinserts newline" "sed -e '/woot/a woo' -" \
        "woot\nwoo\n" "" "woot"
-}
+testing "sed append autoinserts newline 2" "sed -e '/oot/a woo' - input" \
+       "woot\nwoo\nboot\nwoo\n" "boot" "woot"
+testing "sed append autoinserts newline 3" "sed -e '/oot/a woo' -i input && cat input" \
+       "boot\nwoo\n" "boot" ""
 testing "sed insert doesn't autoinsert newline" "sed -e '/woot/i woo' -" \
        "woo\nwoot" "" "woot"
 testing "sed print autoinsert newlines" "sed -e 'p' -" "one\none" "" "one"