diff options
author | Denys Vlasenko <vda.linux@googlemail.com> | 2016-05-06 18:25:56 +0200 |
---|---|---|
committer | Denys Vlasenko <vda.linux@googlemail.com> | 2016-05-06 18:25:56 +0200 |
commit | f2559e5c2b7bd2c5fa0dd8e88d0a931da92a23af (patch) | |
tree | c5ca1cc1e5110cdb51822833da26cb8463bdd023 | |
parent | 2fbc3123a2d94a85317b2269c724939db7e18fbf (diff) | |
download | busybox-w32-f2559e5c2b7bd2c5fa0dd8e88d0a931da92a23af.tar.gz busybox-w32-f2559e5c2b7bd2c5fa0dd8e88d0a931da92a23af.tar.bz2 busybox-w32-f2559e5c2b7bd2c5fa0dd8e88d0a931da92a23af.zip |
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>
-rw-r--r-- | editors/sed.c | 29 | ||||
-rwxr-xr-x | testsuite/sed.tests | 6 |
2 files changed, 23 insertions, 12 deletions
diff --git a/editors/sed.c b/editors/sed.c index 7f18fd0c4..f37c37d88 100644 --- a/editors/sed.c +++ b/editors/sed.c | |||
@@ -956,13 +956,22 @@ static void puts_maybe_newline(char *s, FILE *file, char *last_puts_char, char l | |||
956 | *last_puts_char = lpc; | 956 | *last_puts_char = lpc; |
957 | } | 957 | } |
958 | 958 | ||
959 | static void flush_append(char *last_puts_char, char last_gets_char) | 959 | static void flush_append(char *last_puts_char) |
960 | { | 960 | { |
961 | char *data; | 961 | char *data; |
962 | 962 | ||
963 | /* Output appended lines. */ | 963 | /* Output appended lines. */ |
964 | while ((data = (char *)llist_pop(&G.append_head))) { | 964 | while ((data = (char *)llist_pop(&G.append_head)) != NULL) { |
965 | puts_maybe_newline(data, G.nonstdout, last_puts_char, last_gets_char); | 965 | /* Append command does not respect "nonterminated-ness" |
966 | * of last line. Try this: | ||
967 | * $ echo -n "woot" | sed -e '/woot/a woo' - | ||
968 | * woot | ||
969 | * woo | ||
970 | * (both lines are terminated with \n) | ||
971 | * Therefore we do not propagate "last_gets_char" here, | ||
972 | * pass '\n' instead: | ||
973 | */ | ||
974 | puts_maybe_newline(data, G.nonstdout, last_puts_char, '\n'); | ||
966 | free(data); | 975 | free(data); |
967 | } | 976 | } |
968 | } | 977 | } |
@@ -970,13 +979,13 @@ static void flush_append(char *last_puts_char, char last_gets_char) | |||
970 | /* Get next line of input from G.input_file_list, flushing append buffer and | 979 | /* Get next line of input from G.input_file_list, flushing append buffer and |
971 | * noting if we ran out of files without a newline on the last line we read. | 980 | * noting if we ran out of files without a newline on the last line we read. |
972 | */ | 981 | */ |
973 | static char *get_next_line(char *gets_char, char *last_puts_char, char last_gets_char) | 982 | static char *get_next_line(char *gets_char, char *last_puts_char) |
974 | { | 983 | { |
975 | char *temp = NULL; | 984 | char *temp = NULL; |
976 | int len; | 985 | int len; |
977 | char gc; | 986 | char gc; |
978 | 987 | ||
979 | flush_append(last_puts_char, last_gets_char); | 988 | flush_append(last_puts_char); |
980 | 989 | ||
981 | /* will be returned if last line in the file | 990 | /* will be returned if last line in the file |
982 | * doesn't end with either '\n' or '\0' */ | 991 | * doesn't end with either '\n' or '\0' */ |
@@ -1054,7 +1063,7 @@ static void process_files(void) | |||
1054 | int substituted; | 1063 | int substituted; |
1055 | 1064 | ||
1056 | /* Prime the pump */ | 1065 | /* Prime the pump */ |
1057 | next_line = get_next_line(&next_gets_char, &last_puts_char, '\n' /*last_gets_char*/); | 1066 | next_line = get_next_line(&next_gets_char, &last_puts_char); |
1058 | 1067 | ||
1059 | /* Go through every line in each file */ | 1068 | /* Go through every line in each file */ |
1060 | again: | 1069 | again: |
@@ -1068,7 +1077,7 @@ static void process_files(void) | |||
1068 | 1077 | ||
1069 | /* Read one line in advance so we can act on the last line, | 1078 | /* Read one line in advance so we can act on the last line, |
1070 | * the '$' address */ | 1079 | * the '$' address */ |
1071 | next_line = get_next_line(&next_gets_char, &last_puts_char, last_gets_char); | 1080 | next_line = get_next_line(&next_gets_char, &last_puts_char); |
1072 | linenum++; | 1081 | linenum++; |
1073 | 1082 | ||
1074 | /* For every line, go through all the commands */ | 1083 | /* For every line, go through all the commands */ |
@@ -1295,7 +1304,7 @@ static void process_files(void) | |||
1295 | free(pattern_space); | 1304 | free(pattern_space); |
1296 | pattern_space = next_line; | 1305 | pattern_space = next_line; |
1297 | last_gets_char = next_gets_char; | 1306 | last_gets_char = next_gets_char; |
1298 | next_line = get_next_line(&next_gets_char, &last_puts_char, last_gets_char); | 1307 | next_line = get_next_line(&next_gets_char, &last_puts_char); |
1299 | substituted = 0; | 1308 | substituted = 0; |
1300 | linenum++; | 1309 | linenum++; |
1301 | break; | 1310 | break; |
@@ -1331,7 +1340,7 @@ static void process_files(void) | |||
1331 | pattern_space[len] = '\n'; | 1340 | pattern_space[len] = '\n'; |
1332 | strcpy(pattern_space + len+1, next_line); | 1341 | strcpy(pattern_space + len+1, next_line); |
1333 | last_gets_char = next_gets_char; | 1342 | last_gets_char = next_gets_char; |
1334 | next_line = get_next_line(&next_gets_char, &last_puts_char, last_gets_char); | 1343 | next_line = get_next_line(&next_gets_char, &last_puts_char); |
1335 | linenum++; | 1344 | linenum++; |
1336 | break; | 1345 | break; |
1337 | } | 1346 | } |
@@ -1435,7 +1444,7 @@ static void process_files(void) | |||
1435 | 1444 | ||
1436 | /* Delete and such jump here. */ | 1445 | /* Delete and such jump here. */ |
1437 | discard_line: | 1446 | discard_line: |
1438 | flush_append(&last_puts_char, last_gets_char); | 1447 | flush_append(&last_puts_char /*,last_gets_char*/); |
1439 | free(pattern_space); | 1448 | free(pattern_space); |
1440 | 1449 | ||
1441 | goto again; | 1450 | goto again; |
diff --git a/testsuite/sed.tests b/testsuite/sed.tests index c4b6fa278..a71f8b1f0 100755 --- a/testsuite/sed.tests +++ b/testsuite/sed.tests | |||
@@ -135,10 +135,12 @@ testing "sed empty file plus cat" "sed -e 's/nohit//' input -" "one\ntwo" \ | |||
135 | "" "one\ntwo" | 135 | "" "one\ntwo" |
136 | testing "sed cat plus empty file" "sed -e 's/nohit//' input -" "one\ntwo" \ | 136 | testing "sed cat plus empty file" "sed -e 's/nohit//' input -" "one\ntwo" \ |
137 | "one\ntwo" "" | 137 | "one\ntwo" "" |
138 | test x"$SKIP_KNOWN_BUGS" = x"" && { | ||
139 | testing "sed append autoinserts newline" "sed -e '/woot/a woo' -" \ | 138 | testing "sed append autoinserts newline" "sed -e '/woot/a woo' -" \ |
140 | "woot\nwoo\n" "" "woot" | 139 | "woot\nwoo\n" "" "woot" |
141 | } | 140 | testing "sed append autoinserts newline 2" "sed -e '/oot/a woo' - input" \ |
141 | "woot\nwoo\nboot\nwoo\n" "boot" "woot" | ||
142 | testing "sed append autoinserts newline 3" "sed -e '/oot/a woo' -i input && cat input" \ | ||
143 | "boot\nwoo\n" "boot" "" | ||
142 | testing "sed insert doesn't autoinsert newline" "sed -e '/woot/i woo' -" \ | 144 | testing "sed insert doesn't autoinsert newline" "sed -e '/woot/i woo' -" \ |
143 | "woo\nwoot" "" "woot" | 145 | "woo\nwoot" "" "woot" |
144 | testing "sed print autoinsert newlines" "sed -e 'p' -" "one\none" "" "one" | 146 | testing "sed print autoinsert newlines" "sed -e 'p' -" "one\none" "" "one" |