summaryrefslogtreecommitdiff
path: root/editors/sed.c
diff options
context:
space:
mode:
authorGlenn L McGrath <bug1@ihug.co.nz>2003-09-16 05:25:43 +0000
committerGlenn L McGrath <bug1@ihug.co.nz>2003-09-16 05:25:43 +0000
commit2570b43e829ccfc0f199fe61aafc24b1bd3fc7b1 (patch)
treede00e748021d3078ea21bb90017ded81129cb4bd /editors/sed.c
parent204ff1cea49c958846cd49175fa9318b81b5756f (diff)
downloadbusybox-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.
Diffstat (limited to 'editors/sed.c')
-rw-r--r--editors/sed.c62
1 files changed, 36 insertions, 26 deletions
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
337out:
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}