sed: fix append command to match GNU sed 4.2.1

This closes one testcase failure

Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
This commit is contained in:
Denys Vlasenko 2016-05-06 18:25:56 +02:00
parent 2fbc3123a2
commit f2559e5c2b
2 changed files with 23 additions and 12 deletions

View File

@ -956,13 +956,22 @@ static void puts_maybe_newline(char *s, FILE *file, char *last_puts_char, char l
*last_puts_char = lpc; *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; char *data;
/* Output appended lines. */ /* Output appended lines. */
while ((data = (char *)llist_pop(&G.append_head))) { while ((data = (char *)llist_pop(&G.append_head)) != NULL) {
puts_maybe_newline(data, G.nonstdout, last_puts_char, last_gets_char); /* 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); 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 /* 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. * 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; char *temp = NULL;
int len; int len;
char gc; char gc;
flush_append(last_puts_char, last_gets_char); flush_append(last_puts_char);
/* will be returned if last line in the file /* will be returned if last line in the file
* doesn't end with either '\n' or '\0' */ * doesn't end with either '\n' or '\0' */
@ -1054,7 +1063,7 @@ static void process_files(void)
int substituted; int substituted;
/* Prime the pump */ /* 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 */ /* Go through every line in each file */
again: again:
@ -1068,7 +1077,7 @@ static void process_files(void)
/* Read one line in advance so we can act on the last line, /* Read one line in advance so we can act on the last line,
* the '$' address */ * 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++; linenum++;
/* For every line, go through all the commands */ /* For every line, go through all the commands */
@ -1295,7 +1304,7 @@ static void process_files(void)
free(pattern_space); free(pattern_space);
pattern_space = next_line; pattern_space = next_line;
last_gets_char = next_gets_char; 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; substituted = 0;
linenum++; linenum++;
break; break;
@ -1331,7 +1340,7 @@ static void process_files(void)
pattern_space[len] = '\n'; pattern_space[len] = '\n';
strcpy(pattern_space + len+1, next_line); strcpy(pattern_space + len+1, next_line);
last_gets_char = next_gets_char; 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++; linenum++;
break; break;
} }
@ -1435,7 +1444,7 @@ static void process_files(void)
/* Delete and such jump here. */ /* Delete and such jump here. */
discard_line: discard_line:
flush_append(&last_puts_char, last_gets_char); flush_append(&last_puts_char /*,last_gets_char*/);
free(pattern_space); free(pattern_space);
goto again; goto again;

View File

@ -135,10 +135,12 @@ testing "sed empty file plus cat" "sed -e 's/nohit//' input -" "one\ntwo" \
"" "one\ntwo" "" "one\ntwo"
testing "sed cat plus empty file" "sed -e 's/nohit//' input -" "one\ntwo" \ testing "sed cat plus empty file" "sed -e 's/nohit//' input -" "one\ntwo" \
"one\ntwo" "" "one\ntwo" ""
test x"$SKIP_KNOWN_BUGS" = x"" && {
testing "sed append autoinserts newline" "sed -e '/woot/a woo' -" \ testing "sed append autoinserts newline" "sed -e '/woot/a woo' -" \
"woot\nwoo\n" "" "woot" "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' -" \ testing "sed insert doesn't autoinsert newline" "sed -e '/woot/i woo' -" \
"woo\nwoot" "" "woot" "woo\nwoot" "" "woot"
testing "sed print autoinsert newlines" "sed -e 'p' -" "one\none" "" "one" testing "sed print autoinsert newlines" "sed -e 'p' -" "one\none" "" "one"