diff options
| author | Denis Vlasenko <vda.linux@googlemail.com> | 2007-11-13 16:48:10 +0000 |
|---|---|---|
| committer | Denis Vlasenko <vda.linux@googlemail.com> | 2007-11-13 16:48:10 +0000 |
| commit | 40276648ab31822068c3408ae43a5ecaafd03a5c (patch) | |
| tree | a10fa0510807ec1d784aae112c512ef40b1922ac | |
| parent | 6df9e3c9a38095c0c56728a81926aca53d28733f (diff) | |
| download | busybox-w32-40276648ab31822068c3408ae43a5ecaafd03a5c.tar.gz busybox-w32-40276648ab31822068c3408ae43a5ecaafd03a5c.tar.bz2 busybox-w32-40276648ab31822068c3408ae43a5ecaafd03a5c.zip | |
sed: support GNU-like '\t' escape in substitutions
| -rw-r--r-- | editors/sed.c | 14 | ||||
| -rw-r--r-- | testsuite/README | 4 | ||||
| -rwxr-xr-x | testsuite/sed.tests | 1 |
3 files changed, 13 insertions, 6 deletions
diff --git a/editors/sed.c b/editors/sed.c index f75fceea5..0f5cab2b7 100644 --- a/editors/sed.c +++ b/editors/sed.c | |||
| @@ -173,7 +173,7 @@ static void cleanup_outname(void) | |||
| 173 | if (G.outname) unlink(G.outname); | 173 | if (G.outname) unlink(G.outname); |
| 174 | } | 174 | } |
| 175 | 175 | ||
| 176 | /* strdup, replacing "\n" with '\n', and "\delimiter" with 'delimiter' */ | 176 | /* strcpy, replacing "\from" with 'to'. If to is NUL, replacing "\any" with 'any' */ |
| 177 | 177 | ||
| 178 | static void parse_escapes(char *dest, const char *string, int len, char from, char to) | 178 | static void parse_escapes(char *dest, const char *string, int len, char from, char to) |
| 179 | { | 179 | { |
| @@ -188,9 +188,10 @@ static void parse_escapes(char *dest, const char *string, int len, char from, ch | |||
| 188 | } | 188 | } |
| 189 | *dest++ = string[i++]; | 189 | *dest++ = string[i++]; |
| 190 | } | 190 | } |
| 191 | /* TODO: is it safe wrt a string with trailing '\\' ? */ | ||
| 191 | *dest++ = string[i++]; | 192 | *dest++ = string[i++]; |
| 192 | } | 193 | } |
| 193 | *dest = 0; | 194 | *dest = '\0'; |
| 194 | } | 195 | } |
| 195 | 196 | ||
| 196 | static char *copy_parsing_escapes(const char *string, int len) | 197 | static char *copy_parsing_escapes(const char *string, int len) |
| @@ -198,6 +199,8 @@ static char *copy_parsing_escapes(const char *string, int len) | |||
| 198 | char *dest = xmalloc(len + 1); | 199 | char *dest = xmalloc(len + 1); |
| 199 | 200 | ||
| 200 | parse_escapes(dest, string, len, 'n', '\n'); | 201 | parse_escapes(dest, string, len, 'n', '\n'); |
| 202 | /* GNU sed also recognizes \t */ | ||
| 203 | parse_escapes(dest, dest, strlen(dest), 't', '\t'); | ||
| 201 | return dest; | 204 | return dest; |
| 202 | } | 205 | } |
| 203 | 206 | ||
| @@ -205,7 +208,7 @@ static char *copy_parsing_escapes(const char *string, int len) | |||
| 205 | /* | 208 | /* |
| 206 | * index_of_next_unescaped_regexp_delim - walks left to right through a string | 209 | * index_of_next_unescaped_regexp_delim - walks left to right through a string |
| 207 | * beginning at a specified index and returns the index of the next regular | 210 | * beginning at a specified index and returns the index of the next regular |
| 208 | * expression delimiter (typically a forward * slash ('/')) not preceded by | 211 | * expression delimiter (typically a forward slash ('/')) not preceded by |
| 209 | * a backslash ('\'). A negative delimiter disables square bracket checking. | 212 | * a backslash ('\'). A negative delimiter disables square bracket checking. |
| 210 | */ | 213 | */ |
| 211 | static int index_of_next_unescaped_regexp_delim(int delimiter, const char *str) | 214 | static int index_of_next_unescaped_regexp_delim(int delimiter, const char *str) |
| @@ -425,7 +428,8 @@ static const char *parse_cmd_args(sed_cmd_t *sed_cmd, const char *cmdstr) | |||
| 425 | break; | 428 | break; |
| 426 | } | 429 | } |
| 427 | sed_cmd->string = xstrdup(cmdstr); | 430 | sed_cmd->string = xstrdup(cmdstr); |
| 428 | parse_escapes(sed_cmd->string, sed_cmd->string, strlen(cmdstr), 0, 0); | 431 | /* "\anychar" -> "anychar" */ |
| 432 | parse_escapes(sed_cmd->string, sed_cmd->string, strlen(cmdstr), '\0', '\0'); | ||
| 429 | cmdstr += strlen(cmdstr); | 433 | cmdstr += strlen(cmdstr); |
| 430 | /* handle file cmds: (r)ead */ | 434 | /* handle file cmds: (r)ead */ |
| 431 | } else if (strchr("rw", sed_cmd->cmd)) { | 435 | } else if (strchr("rw", sed_cmd->cmd)) { |
| @@ -1337,7 +1341,7 @@ int sed_main(int argc, char **argv) | |||
| 1337 | // FIXME: error check / message? | 1341 | // FIXME: error check / message? |
| 1338 | rename(G.outname, argv[i]); | 1342 | rename(G.outname, argv[i]); |
| 1339 | free(G.outname); | 1343 | free(G.outname); |
| 1340 | G.outname = 0; | 1344 | G.outname = NULL; |
| 1341 | } | 1345 | } |
| 1342 | if (G.input_file_count > G.current_input_file) | 1346 | if (G.input_file_count > G.current_input_file) |
| 1343 | process_files(); | 1347 | process_files(); |
diff --git a/testsuite/README b/testsuite/README index 377f20ef8..a44846dbb 100644 --- a/testsuite/README +++ b/testsuite/README | |||
| @@ -4,7 +4,9 @@ Update: doesn't work as described. Try "make check" from parent dir... | |||
| 4 | To run the test suite, change to this directory and run "./runtest". It will | 4 | To run the test suite, change to this directory and run "./runtest". It will |
| 5 | run all of the test cases, and list those with unexpected outcomes. Adding the | 5 | run all of the test cases, and list those with unexpected outcomes. Adding the |
| 6 | -v option will cause it to show expected outcomes as well. To only run the test | 6 | -v option will cause it to show expected outcomes as well. To only run the test |
| 7 | cases for particular applets, specify them as parameters to runtest. | 7 | cases for particular applets: |
| 8 | |||
| 9 | ./runtest <applet1> <applet2>... | ||
| 8 | 10 | ||
| 9 | The test cases for an applet reside in the subdirectory of the applet name. The | 11 | The test cases for an applet reside in the subdirectory of the applet name. The |
| 10 | name of the test case should be the assertion that is tested. The test case | 12 | name of the test case should be the assertion that is tested. The test case |
diff --git a/testsuite/sed.tests b/testsuite/sed.tests index a054de6d7..7471ed5fc 100755 --- a/testsuite/sed.tests +++ b/testsuite/sed.tests | |||
| @@ -57,6 +57,7 @@ testing "sed s arbitrary delimiter" "sed -e 's woo boing '" "boing\n" "" "woo\n" | |||
| 57 | testing "sed s chains" "sed -e s/foo/bar/ -e s/bar/baz/" "baz\n" "" "foo\n" | 57 | testing "sed s chains" "sed -e s/foo/bar/ -e s/bar/baz/" "baz\n" "" "foo\n" |
| 58 | testing "sed s chains2" "sed -e s/foo/bar/ -e s/baz/nee/" "bar\n" "" "foo\n" | 58 | testing "sed s chains2" "sed -e s/foo/bar/ -e s/baz/nee/" "bar\n" "" "foo\n" |
| 59 | testing "sed s [delimiter]" "sed -e 's@[@]@@'" "onetwo" "" "one@two" | 59 | testing "sed s [delimiter]" "sed -e 's@[@]@@'" "onetwo" "" "one@two" |
| 60 | testing "sed s with \\t (GNU ext)" "sed 's/\t/ /'" "one two" "" "one\ttwo" | ||
| 60 | 61 | ||
| 61 | # branch | 62 | # branch |
| 62 | testing "sed b (branch)" "sed -e 'b one;p;: one'" "foo\n" "" "foo\n" | 63 | testing "sed b (branch)" "sed -e 'b one;p;: one'" "foo\n" "" "foo\n" |
