diff options
author | Glenn L McGrath <bug1@ihug.co.nz> | 2003-09-16 05:25:43 +0000 |
---|---|---|
committer | Glenn L McGrath <bug1@ihug.co.nz> | 2003-09-16 05:25:43 +0000 |
commit | 2570b43e829ccfc0f199fe61aafc24b1bd3fc7b1 (patch) | |
tree | de00e748021d3078ea21bb90017ded81129cb4bd | |
parent | 204ff1cea49c958846cd49175fa9318b81b5756f (diff) | |
download | busybox-w32-2570b43e829ccfc0f199fe61aafc24b1bd3fc7b1.tar.gz busybox-w32-2570b43e829ccfc0f199fe61aafc24b1bd3fc7b1.tar.bz2 busybox-w32-2570b43e829ccfc0f199fe61aafc24b1bd3fc7b1.zip |
Configuration option to define wether to follows GNU sed's behaviour
or the posix standard.
Put the cleanup code back the way it was.
-rw-r--r-- | editors/Config.in | 13 | ||||
-rw-r--r-- | editors/sed.c | 62 | ||||
-rw-r--r-- | libbb/get_line_from_file.c | 3 | ||||
-rw-r--r-- | testsuite/sed/sed-append-next-line | 7 | ||||
-rw-r--r-- | testsuite/sed/sed-append-next-line-gnu | 14 |
5 files changed, 70 insertions, 29 deletions
diff --git a/editors/Config.in b/editors/Config.in index 14b698f5d..bced12cb1 100644 --- a/editors/Config.in +++ b/editors/Config.in | |||
@@ -42,6 +42,19 @@ config CONFIG_FEATURE_SED_EMBEDED_NEWLINE | |||
42 | It works by translating '\n' to "\n" and back. | 42 | It works by translating '\n' to "\n" and back. |
43 | It may introduce unexpected results if you use "\n" in your text. | 43 | It may introduce unexpected results if you use "\n" in your text. |
44 | 44 | ||
45 | config CONFIG_FEATURE_SED_GNU_COMPATABILITY | ||
46 | bool " Behave consistent with GNU sed" | ||
47 | default y | ||
48 | depends on CONFIG_SED | ||
49 | help | ||
50 | Where GNU sed doesnt follow the posix standard, do as GNU sed does. | ||
51 | Current difference are in | ||
52 | - N command with odd number of lines (see GNU sed info page) | ||
53 | - Blanks before substitution flags eg. | ||
54 | GNU sed interprets 's/a/b/ g' as 's/a/b/g' | ||
55 | Standard says 's/a/b/ g' should be 's/a/b/;g' | ||
56 | - GNU sed allows blanks between a '!' and the function. | ||
57 | |||
45 | config CONFIG_VI | 58 | config CONFIG_VI |
46 | bool "vi" | 59 | bool "vi" |
47 | default n | 60 | default n |
diff --git a/editors/sed.c b/editors/sed.c index a5a9d41a0..8b98a3182 100644 --- a/editors/sed.c +++ b/editors/sed.c | |||
@@ -45,9 +45,11 @@ | |||
45 | - GNU extensions | 45 | - GNU extensions |
46 | - and more. | 46 | - and more. |
47 | 47 | ||
48 | Bugs: | 48 | Todo: |
49 | 49 | ||
50 | - lots | 50 | - Create a wrapper around regex to make libc's regex conform with sed |
51 | - Fix bugs | ||
52 | |||
51 | 53 | ||
52 | Reference http://www.opengroup.org/onlinepubs/007904975/utilities/sed.html | 54 | Reference http://www.opengroup.org/onlinepubs/007904975/utilities/sed.html |
53 | */ | 55 | */ |
@@ -298,7 +300,15 @@ static int parse_subst_cmd(sed_cmd_t * const sed_cmd, const char *substr) | |||
298 | } | 300 | } |
299 | 301 | ||
300 | /* process the flags */ | 302 | /* process the flags */ |
301 | while (substr[++idx]) { | 303 | #ifndef CONFIG_FEATURE_SED_GNU_COMPATABILITY |
304 | idx++; | ||
305 | #else | ||
306 | /* GNU sed allows blanks before the flag, this can lead to an incosistent | ||
307 | * interpretation of 's/a/b/ g' as being either 's/a/b/g' or 's/a/b/;g'. | ||
308 | * which results in very different behaviour. | ||
309 | */ | ||
310 | while (substr[++idx]) | ||
311 | #endif | ||
302 | switch (substr[idx]) { | 312 | switch (substr[idx]) { |
303 | case 'g': | 313 | case 'g': |
304 | if (match[0] != '^') { | 314 | if (match[0] != '^') { |
@@ -312,16 +322,20 @@ static int parse_subst_cmd(sed_cmd_t * const sed_cmd, const char *substr) | |||
312 | case 'p': | 322 | case 'p': |
313 | sed_cmd->sub_p = 1; | 323 | sed_cmd->sub_p = 1; |
314 | break; | 324 | break; |
325 | #ifdef CONFIG_FEATURE_SED_GNU_COMPATABILITY | ||
315 | default: | 326 | default: |
316 | /* any whitespace or semicolon trailing after a s/// is ok */ | 327 | /* any whitespace or semicolon trailing after a s/// is ok */ |
317 | if (strchr(semicolon_whitespace, substr[idx])) | 328 | if (strchr(semicolon_whitespace, substr[idx])) |
318 | goto out; | 329 | goto out; |
319 | /* else */ | ||
320 | bb_error_msg_and_die("bad option in substitution expression"); | 330 | bb_error_msg_and_die("bad option in substitution expression"); |
331 | #endif | ||
321 | } | 332 | } |
322 | } | ||
323 | 333 | ||
324 | out: | 334 | #ifndef CONFIG_FEATURE_SED_GNU_COMPATABILITY |
335 | idx++; | ||
336 | #else | ||
337 | out: | ||
338 | #endif | ||
325 | /* compile the match string into a regex */ | 339 | /* compile the match string into a regex */ |
326 | if (*match != '\0') { | 340 | if (*match != '\0') { |
327 | /* If match is empty, we use last regex used at runtime */ | 341 | /* If match is empty, we use last regex used at runtime */ |
@@ -556,15 +570,12 @@ static char *add_cmd(char *cmdstr) | |||
556 | sed_cmd->invert = 1; | 570 | sed_cmd->invert = 1; |
557 | cmdstr++; | 571 | cmdstr++; |
558 | 572 | ||
559 | #ifdef SED_FEATURE_STRICT_CHECKING | 573 | #ifdef CONFIG_FEATURE_SED_GNU_COMPATABILITY |
560 | /* According to the spec | 574 | /* According to the spec |
561 | * It is unspecified whether <blank>s can follow a '!' character, | 575 | * It is unspecified whether <blank>s can follow a '!' character, |
562 | * and conforming applications shall not follow a '!' character | 576 | * and conforming applications shall not follow a '!' character |
563 | * with <blank>s. | 577 | * with <blank>s. |
564 | */ | 578 | */ |
565 | if (isblank(cmdstr[idx]) { | ||
566 | bb_error_msg_and_die("blank follows '!'");} | ||
567 | #else | ||
568 | /* skip whitespace before the command */ | 579 | /* skip whitespace before the command */ |
569 | while (isspace(*cmdstr)) { | 580 | while (isspace(*cmdstr)) { |
570 | cmdstr++; | 581 | cmdstr++; |
@@ -931,7 +942,6 @@ static void process_file(FILE * file) | |||
931 | } | 942 | } |
932 | /* we also print the line if we were given the 'p' flag | 943 | /* we also print the line if we were given the 'p' flag |
933 | * (this is quite possibly the second printing) */ | 944 | * (this is quite possibly the second printing) */ |
934 | // if ((sed_cmd->sub_p) && (!altered || substituted)) { | ||
935 | if ((sed_cmd->sub_p) && (altered || substituted)) { | 945 | if ((sed_cmd->sub_p) && (altered || substituted)) { |
936 | puts(pattern_space); | 946 | puts(pattern_space); |
937 | } | 947 | } |
@@ -1007,20 +1017,25 @@ static void process_file(FILE * file) | |||
1007 | } | 1017 | } |
1008 | break; | 1018 | break; |
1009 | case 'N': /* Append the next line to the current line */ | 1019 | case 'N': /* Append the next line to the current line */ |
1010 | if (next_line) { | 1020 | if (next_line == NULL) { |
1011 | pattern_space = | ||
1012 | realloc(pattern_space, | ||
1013 | strlen(pattern_space) + strlen(next_line) + 2); | ||
1014 | strcat(pattern_space, "\n"); | ||
1015 | strcat(pattern_space, next_line); | ||
1016 | next_line = bb_get_chomped_line_from_file(file); | ||
1017 | linenum++; | ||
1018 | } else { | ||
1019 | /* Jump to end of script and exist */ | 1021 | /* Jump to end of script and exist */ |
1020 | deleted = 1; | 1022 | deleted = 1; |
1021 | free(next_line); | 1023 | free(next_line); |
1024 | #ifdef CONFIG_FEATURE_SED_GNU_COMPATABILITY | ||
1025 | /* GNU sed will add the newline character | ||
1026 | * The GNU sed info page labels this as a bug that wont be fixed | ||
1027 | */ | ||
1028 | next_line = calloc(1,1); | ||
1029 | #else | ||
1022 | next_line = NULL; | 1030 | next_line = NULL; |
1031 | break; | ||
1032 | #endif | ||
1023 | } | 1033 | } |
1034 | pattern_space = realloc(pattern_space, strlen(pattern_space) + strlen(next_line) + 2); | ||
1035 | strcat(pattern_space, "\n"); | ||
1036 | strcat(pattern_space, next_line); | ||
1037 | next_line = bb_get_chomped_line_from_file(file); | ||
1038 | linenum++; | ||
1024 | break; | 1039 | break; |
1025 | case 't': | 1040 | case 't': |
1026 | if (substituted) | 1041 | if (substituted) |
@@ -1164,13 +1179,11 @@ extern int sed_main(int argc, char **argv) | |||
1164 | { | 1179 | { |
1165 | int opt, status = EXIT_SUCCESS; | 1180 | int opt, status = EXIT_SUCCESS; |
1166 | 1181 | ||
1167 | #if 0 /* This doesnt seem to be working */ | ||
1168 | #ifdef CONFIG_FEATURE_CLEAN_UP | 1182 | #ifdef CONFIG_FEATURE_CLEAN_UP |
1169 | /* destroy command strings on exit */ | 1183 | /* destroy command strings on exit */ |
1170 | if (atexit(destroy_cmd_strs) == -1) | 1184 | if (atexit(destroy_cmd_strs) == -1) |
1171 | bb_perror_msg_and_die("atexit"); | 1185 | bb_perror_msg_and_die("atexit"); |
1172 | #endif | 1186 | #endif |
1173 | #endif | ||
1174 | 1187 | ||
1175 | /* do normal option parsing */ | 1188 | /* do normal option parsing */ |
1176 | while ((opt = getopt(argc, argv, "ne:f:")) > 0) { | 1189 | while ((opt = getopt(argc, argv, "ne:f:")) > 0) { |
@@ -1223,8 +1236,5 @@ extern int sed_main(int argc, char **argv) | |||
1223 | } | 1236 | } |
1224 | } | 1237 | } |
1225 | 1238 | ||
1226 | #ifdef CONFIG_FEATURE_CLEAN_UP | ||
1227 | destroy_cmd_strs(); | ||
1228 | #endif | ||
1229 | return status; | 1239 | return status; |
1230 | } | 1240 | } |
diff --git a/libbb/get_line_from_file.c b/libbb/get_line_from_file.c index 3b6e1e778..9a831f184 100644 --- a/libbb/get_line_from_file.c +++ b/libbb/get_line_from_file.c | |||
@@ -40,7 +40,7 @@ static char *private_get_line_from_file(FILE *file, int c) | |||
40 | 40 | ||
41 | while ((ch = getc(file)) != EOF) { | 41 | while ((ch = getc(file)) != EOF) { |
42 | /* grow the line buffer as necessary */ | 42 | /* grow the line buffer as necessary */ |
43 | if (idx > linebufsz-2) { | 43 | if (idx > linebufsz - 2) { |
44 | linebuf = xrealloc(linebuf, linebufsz += GROWBY); | 44 | linebuf = xrealloc(linebuf, linebufsz += GROWBY); |
45 | } | 45 | } |
46 | linebuf[idx++] = (char)ch; | 46 | linebuf[idx++] = (char)ch; |
@@ -51,7 +51,6 @@ static char *private_get_line_from_file(FILE *file, int c) | |||
51 | break; | 51 | break; |
52 | } | 52 | } |
53 | } | 53 | } |
54 | |||
55 | if (linebuf) { | 54 | if (linebuf) { |
56 | if (ferror(file)) { | 55 | if (ferror(file)) { |
57 | free(linebuf); | 56 | free(linebuf); |
diff --git a/testsuite/sed/sed-append-next-line b/testsuite/sed/sed-append-next-line index 380b7935d..e7f72f476 100644 --- a/testsuite/sed/sed-append-next-line +++ b/testsuite/sed/sed-append-next-line | |||
@@ -1,4 +1,6 @@ | |||
1 | busybox sed -n 'N;p'>output <<EOF | 1 | # XFAIL |
2 | # This will fail if CONFIG_FEATURE_SED_GNU_COMPATABILITY is defined | ||
3 | busybox sed 'N;p'>output <<EOF | ||
2 | a | 4 | a |
3 | b | 5 | b |
4 | c | 6 | c |
@@ -6,4 +8,7 @@ EOF | |||
6 | cmp -s output - <<EOF | 8 | cmp -s output - <<EOF |
7 | a | 9 | a |
8 | b | 10 | b |
11 | a | ||
12 | b | ||
13 | c | ||
9 | EOF | 14 | EOF |
diff --git a/testsuite/sed/sed-append-next-line-gnu b/testsuite/sed/sed-append-next-line-gnu new file mode 100644 index 000000000..d7aba8c2c --- /dev/null +++ b/testsuite/sed/sed-append-next-line-gnu | |||
@@ -0,0 +1,14 @@ | |||
1 | # FEATURE: CONFIG_FEATURE_SED_GNU_COMPATABILITY | ||
2 | busybox sed 'N;p'>output <<EOF | ||
3 | a | ||
4 | b | ||
5 | c | ||
6 | EOF | ||
7 | cmp -s output - <<EOF | ||
8 | a | ||
9 | b | ||
10 | a | ||
11 | b | ||
12 | c | ||
13 | |||
14 | EOF | ||