diff options
Diffstat (limited to 'editors')
-rw-r--r-- | editors/awk.c | 2 | ||||
-rw-r--r-- | editors/sed.c | 167 |
2 files changed, 86 insertions, 83 deletions
diff --git a/editors/awk.c b/editors/awk.c index e91c37678..b776dd796 100644 --- a/editors/awk.c +++ b/editors/awk.c | |||
@@ -1470,7 +1470,7 @@ static int awk_split(char *s, node *spl, char **slist) | |||
1470 | } | 1470 | } |
1471 | } else { /* space split */ | 1471 | } else { /* space split */ |
1472 | while (*s) { | 1472 | while (*s) { |
1473 | while (isspace(*s)) s++; | 1473 | s = skip_whitespace(s); |
1474 | if (! *s) break; | 1474 | if (! *s) break; |
1475 | n++; | 1475 | n++; |
1476 | while (*s && !isspace(*s)) | 1476 | while (*s && !isspace(*s)) |
diff --git a/editors/sed.c b/editors/sed.c index 30f35ce22..e26141571 100644 --- a/editors/sed.c +++ b/editors/sed.c | |||
@@ -63,29 +63,29 @@ | |||
63 | 63 | ||
64 | /* Each sed command turns into one of these structures. */ | 64 | /* Each sed command turns into one of these structures. */ |
65 | typedef struct sed_cmd_s { | 65 | typedef struct sed_cmd_s { |
66 | /* Ordered by alignment requirements: currently 36 bytes on x86 */ | 66 | /* Ordered by alignment requirements: currently 36 bytes on x86 */ |
67 | 67 | ||
68 | /* address storage */ | 68 | /* address storage */ |
69 | regex_t *beg_match; /* sed -e '/match/cmd' */ | 69 | regex_t *beg_match; /* sed -e '/match/cmd' */ |
70 | regex_t *end_match; /* sed -e '/match/,/end_match/cmd' */ | 70 | regex_t *end_match; /* sed -e '/match/,/end_match/cmd' */ |
71 | regex_t *sub_match; /* For 's/sub_match/string/' */ | 71 | regex_t *sub_match; /* For 's/sub_match/string/' */ |
72 | int beg_line; /* 'sed 1p' 0 == apply commands to all lines */ | 72 | int beg_line; /* 'sed 1p' 0 == apply commands to all lines */ |
73 | int end_line; /* 'sed 1,3p' 0 == one line only. -1 = last line ($) */ | 73 | int end_line; /* 'sed 1,3p' 0 == one line only. -1 = last line ($) */ |
74 | 74 | ||
75 | FILE *file; /* File (sw) command writes to, -1 for none. */ | 75 | FILE *file; /* File (sw) command writes to, -1 for none. */ |
76 | char *string; /* Data string for (saicytb) commands. */ | 76 | char *string; /* Data string for (saicytb) commands. */ |
77 | 77 | ||
78 | unsigned short which_match; /* (s) Which match to replace (0 for all) */ | 78 | unsigned short which_match; /* (s) Which match to replace (0 for all) */ |
79 | 79 | ||
80 | /* Bitfields (gcc won't group them if we don't) */ | 80 | /* Bitfields (gcc won't group them if we don't) */ |
81 | unsigned int invert:1; /* the '!' after the address */ | 81 | unsigned int invert:1; /* the '!' after the address */ |
82 | unsigned int in_match:1; /* Next line also included in match? */ | 82 | unsigned int in_match:1; /* Next line also included in match? */ |
83 | unsigned int no_newline:1; /* Last line written by (sw) had no '\n' */ | 83 | unsigned int no_newline:1; /* Last line written by (sw) had no '\n' */ |
84 | unsigned int sub_p:1; /* (s) print option */ | 84 | unsigned int sub_p:1; /* (s) print option */ |
85 | 85 | ||
86 | /* GENERAL FIELDS */ | 86 | /* GENERAL FIELDS */ |
87 | char cmd; /* The command char: abcdDgGhHilnNpPqrstwxy:={} */ | 87 | char cmd; /* The command char: abcdDgGhHilnNpPqrstwxy:={} */ |
88 | struct sed_cmd_s *next; /* Next command (linked list, NULL terminated) */ | 88 | struct sed_cmd_s *next; /* Next command (linked list, NULL terminated) */ |
89 | } sed_cmd_t; | 89 | } sed_cmd_t; |
90 | 90 | ||
91 | static const char *const semicolon_whitespace = "; \n\r\t\v"; | 91 | static const char *const semicolon_whitespace = "; \n\r\t\v"; |
@@ -162,7 +162,7 @@ void sed_free_and_close_stuff(void) | |||
162 | 162 | ||
163 | static void cleanup_outname(void) | 163 | static void cleanup_outname(void) |
164 | { | 164 | { |
165 | if(bbg.outname) unlink(bbg.outname); | 165 | if(bbg.outname) unlink(bbg.outname); |
166 | } | 166 | } |
167 | 167 | ||
168 | /* strdup, replacing "\n" with '\n', and "\delimiter" with 'delimiter' */ | 168 | /* strdup, replacing "\n" with '\n', and "\delimiter" with 'delimiter' */ |
@@ -343,36 +343,36 @@ static int parse_subst_cmd(sed_cmd_t *sed_cmd, char *substr) | |||
343 | if(isspace(substr[idx])) continue; | 343 | if(isspace(substr[idx])) continue; |
344 | 344 | ||
345 | switch (substr[idx]) { | 345 | switch (substr[idx]) { |
346 | /* Replace all occurrences */ | 346 | /* Replace all occurrences */ |
347 | case 'g': | 347 | case 'g': |
348 | if (match[0] != '^') sed_cmd->which_match = 0; | 348 | if (match[0] != '^') sed_cmd->which_match = 0; |
349 | break; | 349 | break; |
350 | /* Print pattern space */ | 350 | /* Print pattern space */ |
351 | case 'p': | 351 | case 'p': |
352 | sed_cmd->sub_p = 1; | 352 | sed_cmd->sub_p = 1; |
353 | break; | 353 | break; |
354 | /* Write to file */ | 354 | /* Write to file */ |
355 | case 'w': | 355 | case 'w': |
356 | { | 356 | { |
357 | char *temp; | 357 | char *temp; |
358 | idx+=parse_file_cmd(sed_cmd,substr+idx,&temp); | 358 | idx+=parse_file_cmd(sed_cmd,substr+idx,&temp); |
359 | 359 | ||
360 | break; | 360 | break; |
361 | } | 361 | } |
362 | /* Ignore case (gnu exension) */ | 362 | /* Ignore case (gnu exension) */ |
363 | case 'I': | 363 | case 'I': |
364 | cflags |= REG_ICASE; | 364 | cflags |= REG_ICASE; |
365 | break; | 365 | break; |
366 | /* Comment */ | 366 | /* Comment */ |
367 | case '#': | 367 | case '#': |
368 | while(substr[++idx]); | 368 | while(substr[++idx]); |
369 | /* Fall through */ | 369 | /* Fall through */ |
370 | /* End of command */ | 370 | /* End of command */ |
371 | case ';': | 371 | case ';': |
372 | case '}': | 372 | case '}': |
373 | goto out; | 373 | goto out; |
374 | default: | 374 | default: |
375 | bb_error_msg_and_die("bad option in substitution expression"); | 375 | bb_error_msg_and_die("bad option in substitution expression"); |
376 | } | 376 | } |
377 | } | 377 | } |
378 | out: | 378 | out: |
@@ -420,7 +420,7 @@ static char *parse_cmd_args(sed_cmd_t *sed_cmd, char *cmdstr) | |||
420 | } else if (strchr(":btT", sed_cmd->cmd)) { | 420 | } else if (strchr(":btT", sed_cmd->cmd)) { |
421 | int length; | 421 | int length; |
422 | 422 | ||
423 | while(isspace(*cmdstr)) cmdstr++; | 423 | cmdstr = skip_whitespace(cmdstr); |
424 | length = strcspn(cmdstr, semicolon_whitespace); | 424 | length = strcspn(cmdstr, semicolon_whitespace); |
425 | if (length) { | 425 | if (length) { |
426 | sed_cmd->string = xstrndup(cmdstr, length); | 426 | sed_cmd->string = xstrndup(cmdstr, length); |
@@ -517,7 +517,7 @@ static void add_cmd(char *cmdstr) | |||
517 | } | 517 | } |
518 | 518 | ||
519 | /* skip whitespace before the command */ | 519 | /* skip whitespace before the command */ |
520 | while (isspace(*cmdstr)) cmdstr++; | 520 | cmdstr = skip_whitespace(cmdstr); |
521 | 521 | ||
522 | /* Check for inversion flag */ | 522 | /* Check for inversion flag */ |
523 | if (*cmdstr == '!') { | 523 | if (*cmdstr == '!') { |
@@ -525,7 +525,7 @@ static void add_cmd(char *cmdstr) | |||
525 | cmdstr++; | 525 | cmdstr++; |
526 | 526 | ||
527 | /* skip whitespace before the command */ | 527 | /* skip whitespace before the command */ |
528 | while (isspace(*cmdstr)) cmdstr++; | 528 | cmdstr = skip_whitespace(cmdstr); |
529 | } | 529 | } |
530 | 530 | ||
531 | /* last part (mandatory) will be a command */ | 531 | /* last part (mandatory) will be a command */ |
@@ -724,7 +724,7 @@ static int puts_maybe_newline(char *s, FILE *file, int missing_newline, int no_n | |||
724 | fputs(s,file); | 724 | fputs(s,file); |
725 | if(!no_newline) fputc('\n',file); | 725 | if(!no_newline) fputc('\n',file); |
726 | 726 | ||
727 | if(ferror(file)) { | 727 | if(ferror(file)) { |
728 | xfunc_error_retval = 4; /* It's what gnu sed exits with... */ | 728 | xfunc_error_retval = 4; /* It's what gnu sed exits with... */ |
729 | bb_error_msg_and_die(bb_msg_write_error); | 729 | bb_error_msg_and_die(bb_msg_write_error); |
730 | } | 730 | } |
@@ -1167,40 +1167,43 @@ int sed_main(int argc, char **argv) | |||
1167 | FILE *file; | 1167 | FILE *file; |
1168 | 1168 | ||
1169 | for (i = optind; i < argc; i++) { | 1169 | for (i = optind; i < argc; i++) { |
1170 | struct stat statbuf; | ||
1171 | int nonstdoutfd; | ||
1172 | |||
1170 | if(!strcmp(argv[i], "-") && !bbg.in_place) { | 1173 | if(!strcmp(argv[i], "-") && !bbg.in_place) { |
1171 | add_input_file(stdin); | 1174 | add_input_file(stdin); |
1172 | process_files(); | 1175 | process_files(); |
1173 | } else { | 1176 | continue; |
1174 | file = bb_wfopen(argv[i], "r"); | ||
1175 | if (file) { | ||
1176 | if(bbg.in_place) { | ||
1177 | struct stat statbuf; | ||
1178 | int nonstdoutfd; | ||
1179 | |||
1180 | bbg.outname=xstrndup(argv[i],strlen(argv[i])+6); | ||
1181 | strcat(bbg.outname,"XXXXXX"); | ||
1182 | if(-1==(nonstdoutfd=mkstemp(bbg.outname))) | ||
1183 | bb_error_msg_and_die("no temp file"); | ||
1184 | bbg.nonstdout=fdopen(nonstdoutfd,"w"); | ||
1185 | |||
1186 | /* Set permissions of output file */ | ||
1187 | |||
1188 | fstat(fileno(file),&statbuf); | ||
1189 | fchmod(nonstdoutfd,statbuf.st_mode); | ||
1190 | add_input_file(file); | ||
1191 | process_files(); | ||
1192 | fclose(bbg.nonstdout); | ||
1193 | |||
1194 | bbg.nonstdout=stdout; | ||
1195 | unlink(argv[i]); | ||
1196 | rename(bbg.outname,argv[i]); | ||
1197 | free(bbg.outname); | ||
1198 | bbg.outname=0; | ||
1199 | } else add_input_file(file); | ||
1200 | } else { | ||
1201 | status = EXIT_FAILURE; | ||
1202 | } | ||
1203 | } | 1177 | } |
1178 | file = bb_wfopen(argv[i], "r"); | ||
1179 | if (!file) { | ||
1180 | status = EXIT_FAILURE; | ||
1181 | continue; | ||
1182 | } | ||
1183 | if(!bbg.in_place) { | ||
1184 | add_input_file(file); | ||
1185 | continue; | ||
1186 | } | ||
1187 | |||
1188 | bbg.outname=xstrndup(argv[i],strlen(argv[i])+6); | ||
1189 | strcat(bbg.outname,"XXXXXX"); | ||
1190 | if(-1==(nonstdoutfd=mkstemp(bbg.outname))) | ||
1191 | bb_error_msg_and_die("no temp file"); | ||
1192 | bbg.nonstdout=fdopen(nonstdoutfd,"w"); | ||
1193 | |||
1194 | /* Set permissions of output file */ | ||
1195 | |||
1196 | fstat(fileno(file),&statbuf); | ||
1197 | fchmod(nonstdoutfd,statbuf.st_mode); | ||
1198 | add_input_file(file); | ||
1199 | process_files(); | ||
1200 | fclose(bbg.nonstdout); | ||
1201 | |||
1202 | bbg.nonstdout=stdout; | ||
1203 | unlink(argv[i]); | ||
1204 | rename(bbg.outname,argv[i]); | ||
1205 | free(bbg.outname); | ||
1206 | bbg.outname=0; | ||
1204 | } | 1207 | } |
1205 | if(bbg.input_file_count>bbg.current_input_file) process_files(); | 1208 | if(bbg.input_file_count>bbg.current_input_file) process_files(); |
1206 | } | 1209 | } |