diff options
author | vda <vda@69ca8d6d-28ef-0310-b511-8ec308f3f277> | 2006-10-25 12:46:46 +0000 |
---|---|---|
committer | vda <vda@69ca8d6d-28ef-0310-b511-8ec308f3f277> | 2006-10-25 12:46:46 +0000 |
commit | 9b7b79ea36b7e842e3c8437db9484831eb1dda14 (patch) | |
tree | dd8da7fe39168d6c2c81441c55a12958d400b93b | |
parent | 656a38a371988abbeb559f89737f222dae1ebbd2 (diff) | |
download | busybox-w32-9b7b79ea36b7e842e3c8437db9484831eb1dda14.tar.gz busybox-w32-9b7b79ea36b7e842e3c8437db9484831eb1dda14.tar.bz2 busybox-w32-9b7b79ea36b7e842e3c8437db9484831eb1dda14.zip |
sed: mostly style fixes, very small changes in actual code
git-svn-id: svn://busybox.net/trunk/busybox@16436 69ca8d6d-28ef-0310-b511-8ec308f3f277
-rw-r--r-- | editors/sed.c | 687 |
1 files changed, 354 insertions, 333 deletions
diff --git a/editors/sed.c b/editors/sed.c index e26141571..3e33529cb 100644 --- a/editors/sed.c +++ b/editors/sed.c | |||
@@ -131,7 +131,7 @@ void sed_free_and_close_stuff(void) | |||
131 | while (sed_cmd) { | 131 | while (sed_cmd) { |
132 | sed_cmd_t *sed_cmd_next = sed_cmd->next; | 132 | sed_cmd_t *sed_cmd_next = sed_cmd->next; |
133 | 133 | ||
134 | if(sed_cmd->file) | 134 | if (sed_cmd->file) |
135 | xprint_and_close_file(sed_cmd->file); | 135 | xprint_and_close_file(sed_cmd->file); |
136 | 136 | ||
137 | if (sed_cmd->beg_match) { | 137 | if (sed_cmd->beg_match) { |
@@ -151,9 +151,9 @@ void sed_free_and_close_stuff(void) | |||
151 | sed_cmd = sed_cmd_next; | 151 | sed_cmd = sed_cmd_next; |
152 | } | 152 | } |
153 | 153 | ||
154 | if(bbg.hold_space) free(bbg.hold_space); | 154 | if (bbg.hold_space) free(bbg.hold_space); |
155 | 155 | ||
156 | while(bbg.current_input_file<bbg.input_file_count) | 156 | while (bbg.current_input_file < bbg.input_file_count) |
157 | fclose(bbg.input_file_list[bbg.current_input_file++]); | 157 | fclose(bbg.input_file_list[bbg.current_input_file++]); |
158 | } | 158 | } |
159 | #endif | 159 | #endif |
@@ -162,31 +162,31 @@ 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' */ |
169 | 169 | ||
170 | static void parse_escapes(char *dest, char *string, int len, char from, char to) | 170 | static void parse_escapes(char *dest, char *string, int len, char from, char to) |
171 | { | 171 | { |
172 | int i=0; | 172 | int i = 0; |
173 | 173 | ||
174 | while(i<len) { | 174 | while (i < len) { |
175 | if(string[i] == '\\') { | 175 | if (string[i] == '\\') { |
176 | if(!to || string[i+1] == from) { | 176 | if (!to || string[i+1] == from) { |
177 | *(dest++) = to ? to : string[i+1]; | 177 | *(dest++) = to ? to : string[i+1]; |
178 | i+=2; | 178 | i += 2; |
179 | continue; | 179 | continue; |
180 | } else *(dest++)=string[i++]; | 180 | } else *(dest++) = string[i++]; |
181 | } | 181 | } |
182 | *(dest++) = string[i++]; | 182 | *(dest++) = string[i++]; |
183 | } | 183 | } |
184 | *dest=0; | 184 | *dest = 0; |
185 | } | 185 | } |
186 | 186 | ||
187 | static char *copy_parsing_escapes(char *string, int len) | 187 | static char *copy_parsing_escapes(char *string, int len) |
188 | { | 188 | { |
189 | char *dest=xmalloc(len+1); | 189 | char *dest = xmalloc(len+1); |
190 | 190 | ||
191 | parse_escapes(dest,string,len,'n','\n'); | 191 | parse_escapes(dest,string,len,'n','\n'); |
192 | return dest; | 192 | return dest; |
@@ -243,7 +243,7 @@ static int parse_regex_delim(char *cmdstr, char **match, char **replace) | |||
243 | * (typically a 'slash') is now our regexp delimiter... */ | 243 | * (typically a 'slash') is now our regexp delimiter... */ |
244 | if (*cmdstr == '\0') | 244 | if (*cmdstr == '\0') |
245 | bb_error_msg_and_die("bad format in substitution expression"); | 245 | bb_error_msg_and_die("bad format in substitution expression"); |
246 | delimiter = *(cmdstr_ptr++); | 246 | delimiter = *cmdstr_ptr++; |
247 | 247 | ||
248 | /* save the match string */ | 248 | /* save the match string */ |
249 | idx = index_of_next_unescaped_regexp_delim(delimiter, cmdstr_ptr); | 249 | idx = index_of_next_unescaped_regexp_delim(delimiter, cmdstr_ptr); |
@@ -275,11 +275,11 @@ static int get_address(char *my_str, int *linenum, regex_t ** regex) | |||
275 | char delimiter; | 275 | char delimiter; |
276 | char *temp; | 276 | char *temp; |
277 | 277 | ||
278 | if (*my_str == '\\') delimiter = *(++pos); | 278 | delimiter = '/'; |
279 | else delimiter = '/'; | 279 | if (*my_str == '\\') delimiter = *++pos; |
280 | next = index_of_next_unescaped_regexp_delim(delimiter, ++pos); | 280 | next = index_of_next_unescaped_regexp_delim(delimiter, ++pos); |
281 | temp = copy_parsing_escapes(pos,next); | 281 | temp = copy_parsing_escapes(pos,next); |
282 | *regex = (regex_t *) xmalloc(sizeof(regex_t)); | 282 | *regex = xmalloc(sizeof(regex_t)); |
283 | xregcomp(*regex, temp, bbg.regex_type|REG_NEWLINE); | 283 | xregcomp(*regex, temp, bbg.regex_type|REG_NEWLINE); |
284 | free(temp); | 284 | free(temp); |
285 | /* Move position to next character after last delimiter */ | 285 | /* Move position to next character after last delimiter */ |
@@ -291,17 +291,19 @@ static int get_address(char *my_str, int *linenum, regex_t ** regex) | |||
291 | /* Grab a filename. Whitespace at start is skipped, then goes to EOL. */ | 291 | /* Grab a filename. Whitespace at start is skipped, then goes to EOL. */ |
292 | static int parse_file_cmd(sed_cmd_t *sed_cmd, char *filecmdstr, char **retval) | 292 | static int parse_file_cmd(sed_cmd_t *sed_cmd, char *filecmdstr, char **retval) |
293 | { | 293 | { |
294 | int start = 0, idx, hack=0; | 294 | int start = 0, idx, hack = 0; |
295 | 295 | ||
296 | /* Skip whitespace, then grab filename to end of line */ | 296 | /* Skip whitespace, then grab filename to end of line */ |
297 | while (isspace(filecmdstr[start])) start++; | 297 | while (isspace(filecmdstr[start])) start++; |
298 | idx=start; | 298 | idx = start; |
299 | while(filecmdstr[idx] && filecmdstr[idx]!='\n') idx++; | 299 | while (filecmdstr[idx] && filecmdstr[idx] != '\n') idx++; |
300 | |||
300 | /* If lines glued together, put backslash back. */ | 301 | /* If lines glued together, put backslash back. */ |
301 | if(filecmdstr[idx]=='\n') hack=1; | 302 | if (filecmdstr[idx] == '\n') hack = 1; |
302 | if(idx==start) bb_error_msg_and_die("Empty filename"); | 303 | if (idx == start) |
304 | bb_error_msg_and_die("empty filename"); | ||
303 | *retval = xstrndup(filecmdstr+start, idx-start+hack+1); | 305 | *retval = xstrndup(filecmdstr+start, idx-start+hack+1); |
304 | if(hack) *(idx+*retval)='\\'; | 306 | if (hack) (*retval)[idx] = '\\'; |
305 | 307 | ||
306 | return idx; | 308 | return idx; |
307 | } | 309 | } |
@@ -327,20 +329,20 @@ static int parse_subst_cmd(sed_cmd_t *sed_cmd, char *substr) | |||
327 | 329 | ||
328 | /* process the flags */ | 330 | /* process the flags */ |
329 | 331 | ||
330 | sed_cmd->which_match=1; | 332 | sed_cmd->which_match = 1; |
331 | while (substr[++idx]) { | 333 | while (substr[++idx]) { |
332 | /* Parse match number */ | 334 | /* Parse match number */ |
333 | if(isdigit(substr[idx])) { | 335 | if (isdigit(substr[idx])) { |
334 | if(match[0]!='^') { | 336 | if (match[0] != '^') { |
335 | /* Match 0 treated as all, multiple matches we take the last one. */ | 337 | /* Match 0 treated as all, multiple matches we take the last one. */ |
336 | char *pos=substr+idx; | 338 | char *pos = substr+idx; |
337 | sed_cmd->which_match=(unsigned short)strtol(substr+idx,&pos,10); | 339 | sed_cmd->which_match = (unsigned short)strtol(substr+idx,&pos,10); |
338 | idx=pos-substr; | 340 | idx = pos-substr; |
339 | } | 341 | } |
340 | continue; | 342 | continue; |
341 | } | 343 | } |
342 | /* Skip spaces */ | 344 | /* Skip spaces */ |
343 | if(isspace(substr[idx])) continue; | 345 | if (isspace(substr[idx])) continue; |
344 | 346 | ||
345 | switch (substr[idx]) { | 347 | switch (substr[idx]) { |
346 | /* Replace all occurrences */ | 348 | /* Replace all occurrences */ |
@@ -355,7 +357,7 @@ static int parse_subst_cmd(sed_cmd_t *sed_cmd, char *substr) | |||
355 | case 'w': | 357 | case 'w': |
356 | { | 358 | { |
357 | char *temp; | 359 | char *temp; |
358 | idx+=parse_file_cmd(sed_cmd,substr+idx,&temp); | 360 | idx += parse_file_cmd(sed_cmd,substr+idx,&temp); |
359 | 361 | ||
360 | break; | 362 | break; |
361 | } | 363 | } |
@@ -365,7 +367,7 @@ static int parse_subst_cmd(sed_cmd_t *sed_cmd, char *substr) | |||
365 | break; | 367 | break; |
366 | /* Comment */ | 368 | /* Comment */ |
367 | case '#': | 369 | case '#': |
368 | while(substr[++idx]); | 370 | while (substr[++idx]) /*skip all*/; |
369 | /* Fall through */ | 371 | /* Fall through */ |
370 | /* End of command */ | 372 | /* End of command */ |
371 | case ';': | 373 | case ';': |
@@ -393,29 +395,32 @@ out: | |||
393 | static char *parse_cmd_args(sed_cmd_t *sed_cmd, char *cmdstr) | 395 | static char *parse_cmd_args(sed_cmd_t *sed_cmd, char *cmdstr) |
394 | { | 396 | { |
395 | /* handle (s)ubstitution command */ | 397 | /* handle (s)ubstitution command */ |
396 | if (sed_cmd->cmd == 's') cmdstr += parse_subst_cmd(sed_cmd, cmdstr); | 398 | if (sed_cmd->cmd == 's') |
399 | cmdstr += parse_subst_cmd(sed_cmd, cmdstr); | ||
397 | /* handle edit cmds: (a)ppend, (i)nsert, and (c)hange */ | 400 | /* handle edit cmds: (a)ppend, (i)nsert, and (c)hange */ |
398 | else if (strchr("aic", sed_cmd->cmd)) { | 401 | else if (strchr("aic", sed_cmd->cmd)) { |
399 | if ((sed_cmd->end_line || sed_cmd->end_match) && sed_cmd->cmd != 'c') | 402 | if ((sed_cmd->end_line || sed_cmd->end_match) && sed_cmd->cmd != 'c') |
400 | bb_error_msg_and_die | 403 | bb_error_msg_and_die |
401 | ("only a beginning address can be specified for edit commands"); | 404 | ("only a beginning address can be specified for edit commands"); |
402 | for(;;) { | 405 | for (;;) { |
403 | if(*cmdstr=='\n' || *cmdstr=='\\') { | 406 | if (*cmdstr == '\n' || *cmdstr == '\\') { |
407 | cmdstr++; | ||
408 | break; | ||
409 | } else if (isspace(*cmdstr)) | ||
404 | cmdstr++; | 410 | cmdstr++; |
411 | else | ||
405 | break; | 412 | break; |
406 | } else if(isspace(*cmdstr)) cmdstr++; | ||
407 | else break; | ||
408 | } | 413 | } |
409 | sed_cmd->string = xstrdup(cmdstr); | 414 | sed_cmd->string = xstrdup(cmdstr); |
410 | parse_escapes(sed_cmd->string,sed_cmd->string,strlen(cmdstr),0,0); | 415 | parse_escapes(sed_cmd->string,sed_cmd->string,strlen(cmdstr),0,0); |
411 | cmdstr += strlen(cmdstr); | 416 | cmdstr += strlen(cmdstr); |
412 | /* handle file cmds: (r)ead */ | 417 | /* handle file cmds: (r)ead */ |
413 | } else if(strchr("rw", sed_cmd->cmd)) { | 418 | } else if (strchr("rw", sed_cmd->cmd)) { |
414 | if (sed_cmd->end_line || sed_cmd->end_match) | 419 | if (sed_cmd->end_line || sed_cmd->end_match) |
415 | bb_error_msg_and_die("Command only uses one address"); | 420 | bb_error_msg_and_die("command only uses one address"); |
416 | cmdstr += parse_file_cmd(sed_cmd, cmdstr, &sed_cmd->string); | 421 | cmdstr += parse_file_cmd(sed_cmd, cmdstr, &sed_cmd->string); |
417 | if(sed_cmd->cmd=='w') | 422 | if (sed_cmd->cmd == 'w') |
418 | sed_cmd->file=xfopen(sed_cmd->string,"w"); | 423 | sed_cmd->file = xfopen(sed_cmd->string,"w"); |
419 | /* handle branch commands */ | 424 | /* handle branch commands */ |
420 | } else if (strchr(":btT", sed_cmd->cmd)) { | 425 | } else if (strchr(":btT", sed_cmd->cmd)) { |
421 | int length; | 426 | int length; |
@@ -430,17 +435,17 @@ static char *parse_cmd_args(sed_cmd_t *sed_cmd, char *cmdstr) | |||
430 | /* translation command */ | 435 | /* translation command */ |
431 | else if (sed_cmd->cmd == 'y') { | 436 | else if (sed_cmd->cmd == 'y') { |
432 | char *match, *replace; | 437 | char *match, *replace; |
433 | int i=cmdstr[0]; | 438 | int i = cmdstr[0]; |
434 | 439 | ||
435 | cmdstr+=parse_regex_delim(cmdstr, &match, &replace)+1; | 440 | cmdstr += parse_regex_delim(cmdstr, &match, &replace)+1; |
436 | /* \n already parsed, but \delimiter needs unescaping. */ | 441 | /* \n already parsed, but \delimiter needs unescaping. */ |
437 | parse_escapes(match,match,strlen(match),i,i); | 442 | parse_escapes(match,match,strlen(match),i,i); |
438 | parse_escapes(replace,replace,strlen(replace),i,i); | 443 | parse_escapes(replace,replace,strlen(replace),i,i); |
439 | 444 | ||
440 | sed_cmd->string = xzalloc((strlen(match) + 1) * 2); | 445 | sed_cmd->string = xzalloc((strlen(match) + 1) * 2); |
441 | for (i = 0; match[i] && replace[i]; i++) { | 446 | for (i = 0; match[i] && replace[i]; i++) { |
442 | sed_cmd->string[i * 2] = match[i]; | 447 | sed_cmd->string[i*2] = match[i]; |
443 | sed_cmd->string[(i * 2) + 1] = replace[i]; | 448 | sed_cmd->string[i*2+1] = replace[i]; |
444 | } | 449 | } |
445 | free(match); | 450 | free(match); |
446 | free(replace); | 451 | free(replace); |
@@ -449,11 +454,11 @@ static char *parse_cmd_args(sed_cmd_t *sed_cmd, char *cmdstr) | |||
449 | * then it must be an invalid command. | 454 | * then it must be an invalid command. |
450 | */ | 455 | */ |
451 | else if (strchr("dDgGhHlnNpPqx={}", sed_cmd->cmd) == 0) { | 456 | else if (strchr("dDgGhHlnNpPqx={}", sed_cmd->cmd) == 0) { |
452 | bb_error_msg_and_die("Unsupported command %c", sed_cmd->cmd); | 457 | bb_error_msg_and_die("unsupported command %c", sed_cmd->cmd); |
453 | } | 458 | } |
454 | 459 | ||
455 | /* give back whatever's left over */ | 460 | /* give back whatever's left over */ |
456 | return (cmdstr); | 461 | return cmdstr; |
457 | } | 462 | } |
458 | 463 | ||
459 | 464 | ||
@@ -472,26 +477,29 @@ static void add_cmd(char *cmdstr) | |||
472 | } | 477 | } |
473 | 478 | ||
474 | /* If this line ends with backslash, request next line. */ | 479 | /* If this line ends with backslash, request next line. */ |
475 | temp=strlen(cmdstr); | 480 | temp = strlen(cmdstr); |
476 | if(temp && cmdstr[temp-1]=='\\') { | 481 | if (temp && cmdstr[temp-1] == '\\') { |
477 | if (!bbg.add_cmd_line) bbg.add_cmd_line = xstrdup(cmdstr); | 482 | if (!bbg.add_cmd_line) |
483 | bbg.add_cmd_line = xstrdup(cmdstr); | ||
478 | bbg.add_cmd_line[temp-1] = 0; | 484 | bbg.add_cmd_line[temp-1] = 0; |
479 | return; | 485 | return; |
480 | } | 486 | } |
481 | 487 | ||
482 | /* Loop parsing all commands in this line. */ | 488 | /* Loop parsing all commands in this line. */ |
483 | while(*cmdstr) { | 489 | while (*cmdstr) { |
484 | /* Skip leading whitespace and semicolons */ | 490 | /* Skip leading whitespace and semicolons */ |
485 | cmdstr += strspn(cmdstr, semicolon_whitespace); | 491 | cmdstr += strspn(cmdstr, semicolon_whitespace); |
486 | 492 | ||
487 | /* If no more commands, exit. */ | 493 | /* If no more commands, exit. */ |
488 | if(!*cmdstr) break; | 494 | if (!*cmdstr) break; |
489 | 495 | ||
490 | /* if this is a comment, jump past it and keep going */ | 496 | /* if this is a comment, jump past it and keep going */ |
491 | if (*cmdstr == '#') { | 497 | if (*cmdstr == '#') { |
492 | /* "#n" is the same as using -n on the command line */ | 498 | /* "#n" is the same as using -n on the command line */ |
493 | if (cmdstr[1] == 'n') bbg.be_quiet++; | 499 | if (cmdstr[1] == 'n') |
494 | if(!(cmdstr=strpbrk(cmdstr, "\n\r"))) break; | 500 | bbg.be_quiet++; |
501 | cmdstr = strpbrk(cmdstr, "\n\r"); | ||
502 | if (!cmdstr) break; | ||
495 | continue; | 503 | continue; |
496 | } | 504 | } |
497 | 505 | ||
@@ -512,7 +520,8 @@ static void add_cmd(char *cmdstr) | |||
512 | 520 | ||
513 | cmdstr++; | 521 | cmdstr++; |
514 | idx = get_address(cmdstr, &sed_cmd->end_line, &sed_cmd->end_match); | 522 | idx = get_address(cmdstr, &sed_cmd->end_line, &sed_cmd->end_match); |
515 | if (!idx) bb_error_msg_and_die("no address after comma"); | 523 | if (!idx) |
524 | bb_error_msg_and_die("no address after comma"); | ||
516 | cmdstr += idx; | 525 | cmdstr += idx; |
517 | } | 526 | } |
518 | 527 | ||
@@ -529,7 +538,8 @@ static void add_cmd(char *cmdstr) | |||
529 | } | 538 | } |
530 | 539 | ||
531 | /* last part (mandatory) will be a command */ | 540 | /* last part (mandatory) will be a command */ |
532 | if (!*cmdstr) bb_error_msg_and_die("missing command"); | 541 | if (!*cmdstr) |
542 | bb_error_msg_and_die("missing command"); | ||
533 | sed_cmd->cmd = *(cmdstr++); | 543 | sed_cmd->cmd = *(cmdstr++); |
534 | cmdstr = parse_cmd_args(sed_cmd, cmdstr); | 544 | cmdstr = parse_cmd_args(sed_cmd, cmdstr); |
535 | 545 | ||
@@ -549,10 +559,10 @@ static void add_cmd(char *cmdstr) | |||
549 | 559 | ||
550 | static void pipe_putc(char c) | 560 | static void pipe_putc(char c) |
551 | { | 561 | { |
552 | if(bbg.pipeline.idx==bbg.pipeline.len) { | 562 | if (bbg.pipeline.idx == bbg.pipeline.len) { |
553 | bbg.pipeline.buf = xrealloc(bbg.pipeline.buf, | 563 | bbg.pipeline.buf = xrealloc(bbg.pipeline.buf, |
554 | bbg.pipeline.len + PIPE_GROW); | 564 | bbg.pipeline.len + PIPE_GROW); |
555 | bbg.pipeline.len+=PIPE_GROW; | 565 | bbg.pipeline.len += PIPE_GROW; |
556 | } | 566 | } |
557 | bbg.pipeline.buf[bbg.pipeline.idx++] = c; | 567 | bbg.pipeline.buf[bbg.pipeline.idx++] = c; |
558 | } | 568 | } |
@@ -564,22 +574,26 @@ static void do_subst_w_backrefs(char *line, char *replace) | |||
564 | /* go through the replacement string */ | 574 | /* go through the replacement string */ |
565 | for (i = 0; replace[i]; i++) { | 575 | for (i = 0; replace[i]; i++) { |
566 | /* if we find a backreference (\1, \2, etc.) print the backref'ed * text */ | 576 | /* if we find a backreference (\1, \2, etc.) print the backref'ed * text */ |
567 | if (replace[i] == '\\' && replace[i+1]>='0' && replace[i+1]<='9') { | 577 | if (replace[i] == '\\' && replace[i+1] >= '0' && replace[i+1] <= '9') { |
568 | int backref=replace[++i]-'0'; | 578 | int backref = replace[++i]-'0'; |
569 | 579 | ||
570 | /* print out the text held in bbg.regmatch[backref] */ | 580 | /* print out the text held in bbg.regmatch[backref] */ |
571 | if(bbg.regmatch[backref].rm_so != -1) | 581 | if (bbg.regmatch[backref].rm_so != -1) { |
572 | for (j = bbg.regmatch[backref].rm_so; | 582 | j = bbg.regmatch[backref].rm_so; |
573 | j < bbg.regmatch[backref].rm_eo; j++) pipe_putc(line[j]); | 583 | while (j < bbg.regmatch[backref].rm_eo) |
584 | pipe_putc(line[j++]); | ||
585 | } | ||
574 | } | 586 | } |
575 | 587 | ||
576 | /* if we find a backslash escaped character, print the character */ | 588 | /* if we find a backslash escaped character, print the character */ |
577 | else if (replace[i] == '\\') pipe_putc(replace[++i]); | 589 | else if (replace[i] == '\\') pipe_putc(replace[++i]); |
578 | 590 | ||
579 | /* if we find an unescaped '&' print out the whole matched text. */ | 591 | /* if we find an unescaped '&' print out the whole matched text. */ |
580 | else if (replace[i] == '&') | 592 | else if (replace[i] == '&') { |
581 | for (j = bbg.regmatch[0].rm_so; j < bbg.regmatch[0].rm_eo; j++) | 593 | j = bbg.regmatch[0].rm_so; |
582 | pipe_putc(line[j]); | 594 | while (j < bbg.regmatch[0].rm_eo) |
595 | pipe_putc(line[j++]); | ||
596 | } | ||
583 | /* Otherwise just output the character. */ | 597 | /* Otherwise just output the character. */ |
584 | else pipe_putc(replace[i]); | 598 | else pipe_putc(replace[i]); |
585 | } | 599 | } |
@@ -589,24 +603,25 @@ static int do_subst_command(sed_cmd_t *sed_cmd, char **line) | |||
589 | { | 603 | { |
590 | char *oldline = *line; | 604 | char *oldline = *line; |
591 | int altered = 0; | 605 | int altered = 0; |
592 | int match_count=0; | 606 | int match_count = 0; |
593 | regex_t *current_regex; | 607 | regex_t *current_regex; |
594 | 608 | ||
595 | /* Handle empty regex. */ | 609 | /* Handle empty regex. */ |
596 | if (sed_cmd->sub_match == NULL) { | 610 | if (sed_cmd->sub_match == NULL) { |
597 | current_regex = bbg.previous_regex_ptr; | 611 | current_regex = bbg.previous_regex_ptr; |
598 | if(!current_regex) | 612 | if (!current_regex) |
599 | bb_error_msg_and_die("No previous regexp."); | 613 | bb_error_msg_and_die("No previous regexp."); |
600 | } else bbg.previous_regex_ptr = current_regex = sed_cmd->sub_match; | 614 | } else |
615 | bbg.previous_regex_ptr = current_regex = sed_cmd->sub_match; | ||
601 | 616 | ||
602 | /* Find the first match */ | 617 | /* Find the first match */ |
603 | if(REG_NOMATCH==regexec(current_regex, oldline, 10, bbg.regmatch, 0)) | 618 | if (REG_NOMATCH == regexec(current_regex, oldline, 10, bbg.regmatch, 0)) |
604 | return 0; | 619 | return 0; |
605 | 620 | ||
606 | /* Initialize temporary output buffer. */ | 621 | /* Initialize temporary output buffer. */ |
607 | bbg.pipeline.buf=xmalloc(PIPE_GROW); | 622 | bbg.pipeline.buf = xmalloc(PIPE_GROW); |
608 | bbg.pipeline.len=PIPE_GROW; | 623 | bbg.pipeline.len = PIPE_GROW; |
609 | bbg.pipeline.idx=0; | 624 | bbg.pipeline.idx = 0; |
610 | 625 | ||
611 | /* Now loop through, substituting for matches */ | 626 | /* Now loop through, substituting for matches */ |
612 | do { | 627 | do { |
@@ -616,8 +631,8 @@ static int do_subst_command(sed_cmd_t *sed_cmd, char **line) | |||
616 | echo " a.b" | busybox sed 's [^ .]* x g' | 631 | echo " a.b" | busybox sed 's [^ .]* x g' |
617 | The match_count check is so not to break | 632 | The match_count check is so not to break |
618 | echo "hi" | busybox sed 's/^/!/g' */ | 633 | echo "hi" | busybox sed 's/^/!/g' */ |
619 | if(!bbg.regmatch[0].rm_so && !bbg.regmatch[0].rm_eo && match_count) { | 634 | if (!bbg.regmatch[0].rm_so && !bbg.regmatch[0].rm_eo && match_count) { |
620 | pipe_putc(*(oldline++)); | 635 | pipe_putc(*oldline++); |
621 | continue; | 636 | continue; |
622 | } | 637 | } |
623 | 638 | ||
@@ -625,14 +640,15 @@ static int do_subst_command(sed_cmd_t *sed_cmd, char **line) | |||
625 | 640 | ||
626 | /* If we aren't interested in this match, output old line to | 641 | /* If we aren't interested in this match, output old line to |
627 | end of match and continue */ | 642 | end of match and continue */ |
628 | if(sed_cmd->which_match && sed_cmd->which_match!=match_count) { | 643 | if (sed_cmd->which_match && sed_cmd->which_match!=match_count) { |
629 | for(i=0;i<bbg.regmatch[0].rm_eo;i++) | 644 | for (i = 0; i < bbg.regmatch[0].rm_eo; i++) |
630 | pipe_putc(*(oldline++)); | 645 | pipe_putc(*oldline++); |
631 | continue; | 646 | continue; |
632 | } | 647 | } |
633 | 648 | ||
634 | /* print everything before the match */ | 649 | /* print everything before the match */ |
635 | for (i = 0; i < bbg.regmatch[0].rm_so; i++) pipe_putc(oldline[i]); | 650 | for (i = 0; i < bbg.regmatch[0].rm_so; i++) |
651 | pipe_putc(oldline[i]); | ||
636 | 652 | ||
637 | /* then print the substitution string */ | 653 | /* then print the substitution string */ |
638 | do_subst_w_backrefs(oldline, sed_cmd->string); | 654 | do_subst_w_backrefs(oldline, sed_cmd->string); |
@@ -648,7 +664,8 @@ static int do_subst_command(sed_cmd_t *sed_cmd, char **line) | |||
648 | 664 | ||
649 | /* Copy rest of string into output pipeline */ | 665 | /* Copy rest of string into output pipeline */ |
650 | 666 | ||
651 | while(*oldline) pipe_putc(*(oldline++)); | 667 | while (*oldline) |
668 | pipe_putc(*oldline++); | ||
652 | pipe_putc(0); | 669 | pipe_putc(0); |
653 | 670 | ||
654 | free(*line); | 671 | free(*line); |
@@ -662,11 +679,11 @@ static sed_cmd_t *branch_to(char *label) | |||
662 | sed_cmd_t *sed_cmd; | 679 | sed_cmd_t *sed_cmd; |
663 | 680 | ||
664 | for (sed_cmd = bbg.sed_cmd_head.next; sed_cmd; sed_cmd = sed_cmd->next) { | 681 | for (sed_cmd = bbg.sed_cmd_head.next; sed_cmd; sed_cmd = sed_cmd->next) { |
665 | if ((sed_cmd->cmd == ':') && (sed_cmd->string) && (strcmp(sed_cmd->string, label) == 0)) { | 682 | if (sed_cmd->cmd == ':' && sed_cmd->string && !strcmp(sed_cmd->string, label)) { |
666 | return (sed_cmd); | 683 | return sed_cmd; |
667 | } | 684 | } |
668 | } | 685 | } |
669 | bb_error_msg_and_die("Can't find label for jump to `%s'", label); | 686 | bb_error_msg_and_die("can't find label for jump to '%s'", label); |
670 | } | 687 | } |
671 | 688 | ||
672 | static void append(char *s) | 689 | static void append(char *s) |
@@ -679,7 +696,7 @@ static void flush_append(void) | |||
679 | char *data; | 696 | char *data; |
680 | 697 | ||
681 | /* Output appended lines. */ | 698 | /* Output appended lines. */ |
682 | while((data = (char *)llist_pop(&bbg.append_head))) { | 699 | while ((data = (char *)llist_pop(&bbg.append_head))) { |
683 | fprintf(bbg.nonstdout,"%s\n",data); | 700 | fprintf(bbg.nonstdout,"%s\n",data); |
684 | free(data); | 701 | free(data); |
685 | } | 702 | } |
@@ -687,7 +704,7 @@ static void flush_append(void) | |||
687 | 704 | ||
688 | static void add_input_file(FILE *file) | 705 | static void add_input_file(FILE *file) |
689 | { | 706 | { |
690 | bbg.input_file_list=xrealloc(bbg.input_file_list, | 707 | bbg.input_file_list = xrealloc(bbg.input_file_list, |
691 | (bbg.input_file_count + 1) * sizeof(FILE *)); | 708 | (bbg.input_file_count + 1) * sizeof(FILE *)); |
692 | bbg.input_file_list[bbg.input_file_count++] = file; | 709 | bbg.input_file_list[bbg.input_file_count++] = file; |
693 | } | 710 | } |
@@ -697,18 +714,19 @@ static void add_input_file(FILE *file) | |||
697 | */ | 714 | */ |
698 | static char *get_next_line(int *no_newline) | 715 | static char *get_next_line(int *no_newline) |
699 | { | 716 | { |
700 | char *temp=NULL; | 717 | char *temp = NULL; |
701 | int len; | 718 | int len; |
702 | 719 | ||
703 | flush_append(); | 720 | flush_append(); |
704 | while (bbg.current_input_file<bbg.input_file_count) { | 721 | while (bbg.current_input_file < bbg.input_file_count) { |
705 | temp = bb_get_chunk_from_file(bbg.input_file_list[bbg.current_input_file],&len); | 722 | temp = bb_get_chunk_from_file(bbg.input_file_list[bbg.current_input_file],&len); |
706 | if (temp) { | 723 | if (temp) { |
707 | *no_newline = !(len && temp[len-1]=='\n'); | 724 | *no_newline = !(len && temp[len-1] == '\n'); |
708 | if (!*no_newline) temp[len-1] = 0; | 725 | if (!*no_newline) temp[len-1] = 0; |
709 | break; | 726 | break; |
710 | // Close this file and advance to next one | 727 | // Close this file and advance to next one |
711 | } else fclose(bbg.input_file_list[bbg.current_input_file++]); | 728 | } else |
729 | fclose(bbg.input_file_list[bbg.current_input_file++]); | ||
712 | } | 730 | } |
713 | 731 | ||
714 | return temp; | 732 | return temp; |
@@ -720,11 +738,11 @@ static char *get_next_line(int *no_newline) | |||
720 | 738 | ||
721 | static int puts_maybe_newline(char *s, FILE *file, int missing_newline, int no_newline) | 739 | static int puts_maybe_newline(char *s, FILE *file, int missing_newline, int no_newline) |
722 | { | 740 | { |
723 | if(missing_newline) fputc('\n',file); | 741 | if (missing_newline) fputc('\n',file); |
724 | fputs(s,file); | 742 | fputs(s,file); |
725 | if(!no_newline) fputc('\n',file); | 743 | if (!no_newline) fputc('\n',file); |
726 | 744 | ||
727 | if(ferror(file)) { | 745 | if (ferror(file)) { |
728 | xfunc_error_retval = 4; /* It's what gnu sed exits with... */ | 746 | xfunc_error_retval = 4; /* It's what gnu sed exits with... */ |
729 | bb_error_msg_and_die(bb_msg_write_error); | 747 | bb_error_msg_and_die(bb_msg_write_error); |
730 | } | 748 | } |
@@ -739,20 +757,21 @@ static int puts_maybe_newline(char *s, FILE *file, int missing_newline, int no_n | |||
739 | static void process_files(void) | 757 | static void process_files(void) |
740 | { | 758 | { |
741 | char *pattern_space, *next_line; | 759 | char *pattern_space, *next_line; |
742 | int linenum = 0, missing_newline=0; | 760 | int linenum = 0, missing_newline = 0; |
743 | int no_newline,next_no_newline=0; | 761 | int no_newline,next_no_newline = 0; |
744 | 762 | ||
745 | /* Prime the pump */ | 763 | /* Prime the pump */ |
746 | next_line = get_next_line(&next_no_newline); | 764 | next_line = get_next_line(&next_no_newline); |
747 | 765 | ||
748 | /* go through every line in each file */ | 766 | /* go through every line in each file */ |
749 | for(;;) { | 767 | for (;;) { |
750 | sed_cmd_t *sed_cmd; | 768 | sed_cmd_t *sed_cmd; |
751 | int substituted=0; | 769 | int substituted = 0; |
752 | 770 | ||
753 | /* Advance to next line. Stop if out of lines. */ | 771 | /* Advance to next line. Stop if out of lines. */ |
754 | if(!(pattern_space=next_line)) break; | 772 | pattern_space = next_line; |
755 | no_newline=next_no_newline; | 773 | if (!pattern_space) break; |
774 | no_newline = next_no_newline; | ||
756 | 775 | ||
757 | /* Read one line in advance so we can act on the last line, | 776 | /* Read one line in advance so we can act on the last line, |
758 | * the '$' address */ | 777 | * the '$' address */ |
@@ -760,8 +779,7 @@ static void process_files(void) | |||
760 | linenum++; | 779 | linenum++; |
761 | restart: | 780 | restart: |
762 | /* for every line, go through all the commands */ | 781 | /* for every line, go through all the commands */ |
763 | for (sed_cmd = bbg.sed_cmd_head.next; sed_cmd; sed_cmd = sed_cmd->next) | 782 | for (sed_cmd = bbg.sed_cmd_head.next; sed_cmd; sed_cmd = sed_cmd->next) { |
764 | { | ||
765 | int old_matched, matched; | 783 | int old_matched, matched; |
766 | 784 | ||
767 | old_matched = sed_cmd->in_match; | 785 | old_matched = sed_cmd->in_match; |
@@ -769,21 +787,16 @@ restart: | |||
769 | /* Determine if this command matches this line: */ | 787 | /* Determine if this command matches this line: */ |
770 | 788 | ||
771 | /* Are we continuing a previous multi-line match? */ | 789 | /* Are we continuing a previous multi-line match? */ |
772 | |||
773 | sed_cmd->in_match = sed_cmd->in_match | 790 | sed_cmd->in_match = sed_cmd->in_match |
774 | 791 | /* Or is no range necessary? */ | |
775 | /* Or is no range necessary? */ | ||
776 | || (!sed_cmd->beg_line && !sed_cmd->end_line | 792 | || (!sed_cmd->beg_line && !sed_cmd->end_line |
777 | && !sed_cmd->beg_match && !sed_cmd->end_match) | 793 | && !sed_cmd->beg_match && !sed_cmd->end_match) |
778 | 794 | /* Or did we match the start of a numerical range? */ | |
779 | /* Or did we match the start of a numerical range? */ | ||
780 | || (sed_cmd->beg_line > 0 && (sed_cmd->beg_line == linenum)) | 795 | || (sed_cmd->beg_line > 0 && (sed_cmd->beg_line == linenum)) |
781 | 796 | /* Or does this line match our begin address regex? */ | |
782 | /* Or does this line match our begin address regex? */ | ||
783 | || (sed_cmd->beg_match && | 797 | || (sed_cmd->beg_match && |
784 | !regexec(sed_cmd->beg_match, pattern_space, 0, NULL, 0)) | 798 | !regexec(sed_cmd->beg_match, pattern_space, 0, NULL, 0)) |
785 | 799 | /* Or did we match last line of input? */ | |
786 | /* Or did we match last line of input? */ | ||
787 | || (sed_cmd->beg_line == -1 && next_line == NULL); | 800 | || (sed_cmd->beg_line == -1 && next_line == NULL); |
788 | 801 | ||
789 | /* Snapshot the value */ | 802 | /* Snapshot the value */ |
@@ -792,7 +805,7 @@ restart: | |||
792 | 805 | ||
793 | /* Is this line the end of the current match? */ | 806 | /* Is this line the end of the current match? */ |
794 | 807 | ||
795 | if(matched) { | 808 | if (matched) { |
796 | sed_cmd->in_match = !( | 809 | sed_cmd->in_match = !( |
797 | /* has the ending line come, or is this a single address command? */ | 810 | /* has the ending line come, or is this a single address command? */ |
798 | (sed_cmd->end_line ? | 811 | (sed_cmd->end_line ? |
@@ -807,9 +820,10 @@ restart: | |||
807 | 820 | ||
808 | /* Skip blocks of commands we didn't match. */ | 821 | /* Skip blocks of commands we didn't match. */ |
809 | if (sed_cmd->cmd == '{') { | 822 | if (sed_cmd->cmd == '{') { |
810 | if(sed_cmd->invert ? matched : !matched) | 823 | if (sed_cmd->invert ? matched : !matched) |
811 | while(sed_cmd && sed_cmd->cmd!='}') sed_cmd=sed_cmd->next; | 824 | while (sed_cmd && sed_cmd->cmd != '}') |
812 | if(!sed_cmd) bb_error_msg_and_die("Unterminated {"); | 825 | sed_cmd = sed_cmd->next; |
826 | if (!sed_cmd) bb_error_msg_and_die("unterminated {"); | ||
813 | continue; | 827 | continue; |
814 | } | 828 | } |
815 | 829 | ||
@@ -823,230 +837,234 @@ restart: | |||
823 | /* actual sedding */ | 837 | /* actual sedding */ |
824 | switch (sed_cmd->cmd) { | 838 | switch (sed_cmd->cmd) { |
825 | 839 | ||
826 | /* Print line number */ | 840 | /* Print line number */ |
827 | case '=': | 841 | case '=': |
828 | fprintf(bbg.nonstdout,"%d\n", linenum); | 842 | fprintf(bbg.nonstdout, "%d\n", linenum); |
829 | break; | 843 | break; |
830 | |||
831 | /* Write the current pattern space up to the first newline */ | ||
832 | case 'P': | ||
833 | { | ||
834 | char *tmp = strchr(pattern_space, '\n'); | ||
835 | 844 | ||
836 | if (tmp) { | 845 | /* Write the current pattern space up to the first newline */ |
837 | *tmp = '\0'; | 846 | case 'P': |
838 | sed_puts(pattern_space,1); | 847 | { |
839 | *tmp = '\n'; | 848 | char *tmp = strchr(pattern_space, '\n'); |
840 | break; | ||
841 | } | ||
842 | /* Fall Through */ | ||
843 | } | ||
844 | 849 | ||
845 | /* Write the current pattern space to output */ | 850 | if (tmp) { |
846 | case 'p': | 851 | *tmp = '\0'; |
847 | sed_puts(pattern_space,no_newline); | 852 | sed_puts(pattern_space,1); |
853 | *tmp = '\n'; | ||
848 | break; | 854 | break; |
849 | /* Delete up through first newline */ | ||
850 | case 'D': | ||
851 | { | ||
852 | char *tmp = strchr(pattern_space,'\n'); | ||
853 | |||
854 | if(tmp) { | ||
855 | tmp=xstrdup(tmp+1); | ||
856 | free(pattern_space); | ||
857 | pattern_space=tmp; | ||
858 | goto restart; | ||
859 | } | ||
860 | } | 855 | } |
861 | /* discard this line. */ | 856 | /* Fall Through */ |
862 | case 'd': | 857 | } |
863 | goto discard_line; | ||
864 | 858 | ||
865 | /* Substitute with regex */ | 859 | /* Write the current pattern space to output */ |
866 | case 's': | 860 | case 'p': |
867 | if(do_subst_command(sed_cmd, &pattern_space)) { | 861 | sed_puts(pattern_space,no_newline); |
868 | substituted|=1; | 862 | break; |
863 | /* Delete up through first newline */ | ||
864 | case 'D': | ||
865 | { | ||
866 | char *tmp = strchr(pattern_space,'\n'); | ||
867 | |||
868 | if (tmp) { | ||
869 | tmp = xstrdup(tmp+1); | ||
870 | free(pattern_space); | ||
871 | pattern_space = tmp; | ||
872 | goto restart; | ||
873 | } | ||
874 | } | ||
875 | /* discard this line. */ | ||
876 | case 'd': | ||
877 | goto discard_line; | ||
869 | 878 | ||
870 | /* handle p option */ | 879 | /* Substitute with regex */ |
871 | if(sed_cmd->sub_p) | 880 | case 's': |
872 | sed_puts(pattern_space,no_newline); | 881 | if (do_subst_command(sed_cmd, &pattern_space)) { |
873 | /* handle w option */ | 882 | substituted |= 1; |
874 | if(sed_cmd->file) | ||
875 | sed_cmd->no_newline=puts_maybe_newline(pattern_space, sed_cmd->file, sed_cmd->no_newline, no_newline); | ||
876 | 883 | ||
877 | } | 884 | /* handle p option */ |
878 | break; | 885 | if (sed_cmd->sub_p) |
886 | sed_puts(pattern_space,no_newline); | ||
887 | /* handle w option */ | ||
888 | if (sed_cmd->file) | ||
889 | sed_cmd->no_newline = puts_maybe_newline(pattern_space, sed_cmd->file, sed_cmd->no_newline, no_newline); | ||
879 | 890 | ||
880 | /* Append line to linked list to be printed later */ | ||
881 | case 'a': | ||
882 | { | ||
883 | append(sed_cmd->string); | ||
884 | break; | ||
885 | } | 891 | } |
892 | break; | ||
886 | 893 | ||
887 | /* Insert text before this line */ | 894 | /* Append line to linked list to be printed later */ |
888 | case 'i': | 895 | case 'a': |
889 | sed_puts(sed_cmd->string,1); | 896 | { |
890 | break; | 897 | append(sed_cmd->string); |
898 | break; | ||
899 | } | ||
891 | 900 | ||
892 | /* Cut and paste text (replace) */ | 901 | /* Insert text before this line */ |
893 | case 'c': | 902 | case 'i': |
894 | /* Only triggers on last line of a matching range. */ | 903 | sed_puts(sed_cmd->string,1); |
895 | if (!sed_cmd->in_match) sed_puts(sed_cmd->string,0); | 904 | break; |
896 | goto discard_line; | 905 | |
906 | /* Cut and paste text (replace) */ | ||
907 | case 'c': | ||
908 | /* Only triggers on last line of a matching range. */ | ||
909 | if (!sed_cmd->in_match) | ||
910 | sed_puts(sed_cmd->string,0); | ||
911 | goto discard_line; | ||
912 | |||
913 | /* Read file, append contents to output */ | ||
914 | case 'r': | ||
915 | { | ||
916 | FILE *rfile; | ||
917 | |||
918 | rfile = fopen(sed_cmd->string, "r"); | ||
919 | if (rfile) { | ||
920 | char *line; | ||
921 | |||
922 | while ((line = xmalloc_getline(rfile)) | ||
923 | != NULL) | ||
924 | append(line); | ||
925 | xprint_and_close_file(rfile); | ||
926 | } | ||
897 | 927 | ||
898 | /* Read file, append contents to output */ | 928 | break; |
899 | case 'r': | 929 | } |
900 | { | ||
901 | FILE *rfile; | ||
902 | 930 | ||
903 | rfile = fopen(sed_cmd->string, "r"); | 931 | /* Write pattern space to file. */ |
904 | if (rfile) { | 932 | case 'w': |
905 | char *line; | 933 | sed_cmd->no_newline = puts_maybe_newline(pattern_space,sed_cmd->file, sed_cmd->no_newline,no_newline); |
906 | 934 | break; | |
907 | while ((line = xmalloc_getline(rfile)) | ||
908 | != NULL) | ||
909 | append(line); | ||
910 | xprint_and_close_file(rfile); | ||
911 | } | ||
912 | 935 | ||
936 | /* Read next line from input */ | ||
937 | case 'n': | ||
938 | if (!bbg.be_quiet) | ||
939 | sed_puts(pattern_space,no_newline); | ||
940 | if (next_line) { | ||
941 | free(pattern_space); | ||
942 | pattern_space = next_line; | ||
943 | no_newline = next_no_newline; | ||
944 | next_line = get_next_line(&next_no_newline); | ||
945 | linenum++; | ||
913 | break; | 946 | break; |
914 | } | 947 | } |
915 | 948 | /* fall through */ | |
916 | /* Write pattern space to file. */ | 949 | |
917 | case 'w': | 950 | /* Quit. End of script, end of input. */ |
918 | sed_cmd->no_newline=puts_maybe_newline(pattern_space,sed_cmd->file, sed_cmd->no_newline,no_newline); | 951 | case 'q': |
919 | break; | 952 | /* Exit the outer while loop */ |
920 | 953 | free(next_line); | |
921 | /* Read next line from input */ | 954 | next_line = NULL; |
922 | case 'n': | 955 | goto discard_commands; |
923 | if (!bbg.be_quiet) | 956 | |
924 | sed_puts(pattern_space,no_newline); | 957 | /* Append the next line to the current line */ |
925 | if (next_line) { | 958 | case 'N': |
926 | free(pattern_space); | 959 | { |
927 | pattern_space = next_line; | 960 | /* If no next line, jump to end of script and exit. */ |
928 | no_newline=next_no_newline; | 961 | if (next_line == NULL) { |
929 | next_line = get_next_line(&next_no_newline); | 962 | /* Jump to end of script and exit */ |
930 | linenum++; | ||
931 | break; | ||
932 | } | ||
933 | /* fall through */ | ||
934 | |||
935 | /* Quit. End of script, end of input. */ | ||
936 | case 'q': | ||
937 | /* Exit the outer while loop */ | ||
938 | free(next_line); | 963 | free(next_line); |
939 | next_line = NULL; | 964 | next_line = NULL; |
940 | goto discard_commands; | 965 | goto discard_line; |
941 | 966 | /* append next_line, read new next_line. */ | |
942 | /* Append the next line to the current line */ | 967 | } else { |
943 | case 'N': | 968 | int len = strlen(pattern_space); |
944 | { | 969 | |
945 | /* If no next line, jump to end of script and exit. */ | 970 | pattern_space = realloc(pattern_space, len + strlen(next_line) + 2); |
946 | if (next_line == NULL) { | 971 | pattern_space[len] = '\n'; |
947 | /* Jump to end of script and exit */ | 972 | strcpy(pattern_space + len+1, next_line); |
948 | free(next_line); | 973 | no_newline = next_no_newline; |
949 | next_line = NULL; | 974 | next_line = get_next_line(&next_no_newline); |
950 | goto discard_line; | 975 | linenum++; |
951 | /* append next_line, read new next_line. */ | ||
952 | } else { | ||
953 | int len=strlen(pattern_space); | ||
954 | |||
955 | pattern_space = realloc(pattern_space, len + strlen(next_line) + 2); | ||
956 | pattern_space[len]='\n'; | ||
957 | strcpy(pattern_space+len+1, next_line); | ||
958 | no_newline=next_no_newline; | ||
959 | next_line = get_next_line(&next_no_newline); | ||
960 | linenum++; | ||
961 | } | ||
962 | break; | ||
963 | } | 976 | } |
977 | break; | ||
978 | } | ||
964 | 979 | ||
965 | /* Test/branch if substitution occurred */ | 980 | /* Test/branch if substitution occurred */ |
966 | case 't': | 981 | case 't': |
967 | if(!substituted) break; | 982 | if (!substituted) break; |
968 | substituted=0; | 983 | substituted = 0; |
969 | /* Fall through */ | 984 | /* Fall through */ |
970 | /* Test/branch if substitution didn't occur */ | 985 | /* Test/branch if substitution didn't occur */ |
971 | case 'T': | 986 | case 'T': |
972 | if (substituted) break; | 987 | if (substituted) break; |
973 | /* Fall through */ | 988 | /* Fall through */ |
974 | /* Branch to label */ | 989 | /* Branch to label */ |
975 | case 'b': | 990 | case 'b': |
976 | if (!sed_cmd->string) goto discard_commands; | 991 | if (!sed_cmd->string) goto discard_commands; |
977 | else sed_cmd = branch_to(sed_cmd->string); | 992 | else sed_cmd = branch_to(sed_cmd->string); |
978 | break; | 993 | break; |
979 | /* Transliterate characters */ | 994 | /* Transliterate characters */ |
980 | case 'y': | 995 | case 'y': |
981 | { | 996 | { |
982 | int i; | 997 | int i; |
983 | 998 | ||
984 | for (i = 0; pattern_space[i]; i++) { | 999 | for (i = 0; pattern_space[i]; i++) { |
985 | int j; | 1000 | int j; |
986 | 1001 | ||
987 | for (j = 0; sed_cmd->string[j]; j += 2) { | 1002 | for (j = 0; sed_cmd->string[j]; j += 2) { |
988 | if (pattern_space[i] == sed_cmd->string[j]) { | 1003 | if (pattern_space[i] == sed_cmd->string[j]) { |
989 | pattern_space[i] = sed_cmd->string[j + 1]; | 1004 | pattern_space[i] = sed_cmd->string[j + 1]; |
990 | break; | 1005 | break; |
991 | } | ||
992 | } | 1006 | } |
993 | } | 1007 | } |
994 | |||
995 | break; | ||
996 | } | 1008 | } |
997 | case 'g': /* Replace pattern space with hold space */ | ||
998 | free(pattern_space); | ||
999 | pattern_space = xstrdup(bbg.hold_space ? bbg.hold_space : ""); | ||
1000 | break; | ||
1001 | case 'G': /* Append newline and hold space to pattern space */ | ||
1002 | { | ||
1003 | int pattern_space_size = 2; | ||
1004 | int hold_space_size = 0; | ||
1005 | |||
1006 | if (pattern_space) | ||
1007 | pattern_space_size += strlen(pattern_space); | ||
1008 | if (bbg.hold_space) | ||
1009 | hold_space_size = strlen(bbg.hold_space); | ||
1010 | pattern_space = xrealloc(pattern_space, | ||
1011 | pattern_space_size + hold_space_size); | ||
1012 | if (pattern_space_size == 2) pattern_space[0]=0; | ||
1013 | strcat(pattern_space, "\n"); | ||
1014 | if (bbg.hold_space) | ||
1015 | strcat(pattern_space, bbg.hold_space); | ||
1016 | no_newline=0; | ||
1017 | |||
1018 | break; | ||
1019 | } | ||
1020 | case 'h': /* Replace hold space with pattern space */ | ||
1021 | free(bbg.hold_space); | ||
1022 | bbg.hold_space = xstrdup(pattern_space); | ||
1023 | break; | ||
1024 | case 'H': /* Append newline and pattern space to hold space */ | ||
1025 | { | ||
1026 | int hold_space_size = 2; | ||
1027 | int pattern_space_size = 0; | ||
1028 | |||
1029 | if (bbg.hold_space) | ||
1030 | hold_space_size += strlen(bbg.hold_space); | ||
1031 | if (pattern_space) | ||
1032 | pattern_space_size = strlen(pattern_space); | ||
1033 | bbg.hold_space = xrealloc(bbg.hold_space, | ||
1034 | hold_space_size + pattern_space_size); | ||
1035 | |||
1036 | if (hold_space_size == 2) *bbg.hold_space=0; | ||
1037 | strcat(bbg.hold_space, "\n"); | ||
1038 | if (pattern_space) strcat(bbg.hold_space, pattern_space); | ||
1039 | 1009 | ||
1040 | break; | 1010 | break; |
1041 | } | 1011 | } |
1042 | case 'x': /* Exchange hold and pattern space */ | 1012 | case 'g': /* Replace pattern space with hold space */ |
1043 | { | 1013 | free(pattern_space); |
1044 | char *tmp = pattern_space; | 1014 | pattern_space = xstrdup(bbg.hold_space ? bbg.hold_space : ""); |
1045 | pattern_space = bbg.hold_space ? : xzalloc(1); | 1015 | break; |
1046 | no_newline=0; | 1016 | case 'G': /* Append newline and hold space to pattern space */ |
1047 | bbg.hold_space = tmp; | 1017 | { |
1048 | break; | 1018 | int pattern_space_size = 2; |
1049 | } | 1019 | int hold_space_size = 0; |
1020 | |||
1021 | if (pattern_space) | ||
1022 | pattern_space_size += strlen(pattern_space); | ||
1023 | if (bbg.hold_space) | ||
1024 | hold_space_size = strlen(bbg.hold_space); | ||
1025 | pattern_space = xrealloc(pattern_space, | ||
1026 | pattern_space_size + hold_space_size); | ||
1027 | if (pattern_space_size == 2) | ||
1028 | pattern_space[0] = 0; | ||
1029 | strcat(pattern_space, "\n"); | ||
1030 | if (bbg.hold_space) | ||
1031 | strcat(pattern_space, bbg.hold_space); | ||
1032 | no_newline = 0; | ||
1033 | |||
1034 | break; | ||
1035 | } | ||
1036 | case 'h': /* Replace hold space with pattern space */ | ||
1037 | free(bbg.hold_space); | ||
1038 | bbg.hold_space = xstrdup(pattern_space); | ||
1039 | break; | ||
1040 | case 'H': /* Append newline and pattern space to hold space */ | ||
1041 | { | ||
1042 | int hold_space_size = 2; | ||
1043 | int pattern_space_size = 0; | ||
1044 | |||
1045 | if (bbg.hold_space) | ||
1046 | hold_space_size += strlen(bbg.hold_space); | ||
1047 | if (pattern_space) | ||
1048 | pattern_space_size = strlen(pattern_space); | ||
1049 | bbg.hold_space = xrealloc(bbg.hold_space, | ||
1050 | hold_space_size + pattern_space_size); | ||
1051 | |||
1052 | if (hold_space_size == 2) | ||
1053 | *bbg.hold_space = 0; | ||
1054 | strcat(bbg.hold_space, "\n"); | ||
1055 | if (pattern_space) | ||
1056 | strcat(bbg.hold_space, pattern_space); | ||
1057 | |||
1058 | break; | ||
1059 | } | ||
1060 | case 'x': /* Exchange hold and pattern space */ | ||
1061 | { | ||
1062 | char *tmp = pattern_space; | ||
1063 | pattern_space = bbg.hold_space ? : xzalloc(1); | ||
1064 | no_newline = 0; | ||
1065 | bbg.hold_space = tmp; | ||
1066 | break; | ||
1067 | } | ||
1050 | } | 1068 | } |
1051 | } | 1069 | } |
1052 | } | 1070 | } |
@@ -1071,15 +1089,15 @@ discard_line: | |||
1071 | 1089 | ||
1072 | static void add_cmd_block(char *cmdstr) | 1090 | static void add_cmd_block(char *cmdstr) |
1073 | { | 1091 | { |
1074 | int go=1; | 1092 | int go = 1; |
1075 | char *temp=xstrdup(cmdstr),*temp2=temp; | 1093 | char *temp = xstrdup(cmdstr), *temp2 = temp; |
1076 | 1094 | ||
1077 | while(go) { | 1095 | while (go) { |
1078 | int len=strcspn(temp2,"\n"); | 1096 | int len = strcspn(temp2,"\n"); |
1079 | if(!temp2[len]) go=0; | 1097 | if (!temp2[len]) go = 0; |
1080 | else temp2[len]=0; | 1098 | else temp2[len] = 0; |
1081 | add_cmd(temp2); | 1099 | add_cmd(temp2); |
1082 | temp2+=len+1; | 1100 | temp2 += len+1; |
1083 | } | 1101 | } |
1084 | free(temp); | 1102 | free(temp); |
1085 | } | 1103 | } |
@@ -1119,7 +1137,7 @@ int sed_main(int argc, char **argv) | |||
1119 | if (ENABLE_FEATURE_CLEAN_UP) atexit(sed_free_and_close_stuff); | 1137 | if (ENABLE_FEATURE_CLEAN_UP) atexit(sed_free_and_close_stuff); |
1120 | 1138 | ||
1121 | /* Lie to autoconf when it starts asking stupid questions. */ | 1139 | /* Lie to autoconf when it starts asking stupid questions. */ |
1122 | if(argc==2 && !strcmp(argv[1],"--version")) { | 1140 | if (argc==2 && !strcmp(argv[1],"--version")) { |
1123 | printf("This is not GNU sed version 4.0\n"); | 1141 | printf("This is not GNU sed version 4.0\n"); |
1124 | exit(0); | 1142 | exit(0); |
1125 | } | 1143 | } |
@@ -1143,7 +1161,7 @@ int sed_main(int argc, char **argv) | |||
1143 | add_files_link(opt_f); | 1161 | add_files_link(opt_f); |
1144 | } | 1162 | } |
1145 | /* if we didn't get a pattern from -e or -f, use argv[optind] */ | 1163 | /* if we didn't get a pattern from -e or -f, use argv[optind] */ |
1146 | if(!(opt & 0x18)) { | 1164 | if (!(opt & 0x18)) { |
1147 | if (argv[optind] == NULL) | 1165 | if (argv[optind] == NULL) |
1148 | bb_show_usage(); | 1166 | bb_show_usage(); |
1149 | else | 1167 | else |
@@ -1159,7 +1177,8 @@ int sed_main(int argc, char **argv) | |||
1159 | * files were specified or '-' was specified, take input from stdin. | 1177 | * files were specified or '-' was specified, take input from stdin. |
1160 | * Otherwise, we process all the files specified. */ | 1178 | * Otherwise, we process all the files specified. */ |
1161 | if (argv[optind] == NULL) { | 1179 | if (argv[optind] == NULL) { |
1162 | if(bbg.in_place) bb_error_msg_and_die(bb_msg_requires_arg, "-i"); | 1180 | if (bbg.in_place) |
1181 | bb_error_msg_and_die(bb_msg_requires_arg, "-i"); | ||
1163 | add_input_file(stdin); | 1182 | add_input_file(stdin); |
1164 | process_files(); | 1183 | process_files(); |
1165 | } else { | 1184 | } else { |
@@ -1170,7 +1189,7 @@ int sed_main(int argc, char **argv) | |||
1170 | struct stat statbuf; | 1189 | struct stat statbuf; |
1171 | int nonstdoutfd; | 1190 | int nonstdoutfd; |
1172 | 1191 | ||
1173 | if(!strcmp(argv[i], "-") && !bbg.in_place) { | 1192 | if (!strcmp(argv[i], "-") && !bbg.in_place) { |
1174 | add_input_file(stdin); | 1193 | add_input_file(stdin); |
1175 | process_files(); | 1194 | process_files(); |
1176 | continue; | 1195 | continue; |
@@ -1180,16 +1199,16 @@ int sed_main(int argc, char **argv) | |||
1180 | status = EXIT_FAILURE; | 1199 | status = EXIT_FAILURE; |
1181 | continue; | 1200 | continue; |
1182 | } | 1201 | } |
1183 | if(!bbg.in_place) { | 1202 | if (!bbg.in_place) { |
1184 | add_input_file(file); | 1203 | add_input_file(file); |
1185 | continue; | 1204 | continue; |
1186 | } | 1205 | } |
1187 | 1206 | ||
1188 | bbg.outname=xstrndup(argv[i],strlen(argv[i])+6); | 1207 | bbg.outname = xasprintf("%sXXXXXX", argv[i]); |
1189 | strcat(bbg.outname,"XXXXXX"); | 1208 | nonstdoutfd = mkstemp(bbg.outname); |
1190 | if(-1==(nonstdoutfd=mkstemp(bbg.outname))) | 1209 | if (-1 == nonstdoutfd) |
1191 | bb_error_msg_and_die("no temp file"); | 1210 | bb_error_msg_and_die("no temp file"); |
1192 | bbg.nonstdout=fdopen(nonstdoutfd,"w"); | 1211 | bbg.nonstdout = fdopen(nonstdoutfd,"w"); |
1193 | 1212 | ||
1194 | /* Set permissions of output file */ | 1213 | /* Set permissions of output file */ |
1195 | 1214 | ||
@@ -1199,13 +1218,15 @@ int sed_main(int argc, char **argv) | |||
1199 | process_files(); | 1218 | process_files(); |
1200 | fclose(bbg.nonstdout); | 1219 | fclose(bbg.nonstdout); |
1201 | 1220 | ||
1202 | bbg.nonstdout=stdout; | 1221 | bbg.nonstdout = stdout; |
1203 | unlink(argv[i]); | 1222 | /* unlink(argv[i]); */ |
1223 | // FIXME: error check / message? | ||
1204 | rename(bbg.outname,argv[i]); | 1224 | rename(bbg.outname,argv[i]); |
1205 | free(bbg.outname); | 1225 | free(bbg.outname); |
1206 | bbg.outname=0; | 1226 | bbg.outname = 0; |
1207 | } | 1227 | } |
1208 | if(bbg.input_file_count>bbg.current_input_file) process_files(); | 1228 | if (bbg.input_file_count > bbg.current_input_file) |
1229 | process_files(); | ||
1209 | } | 1230 | } |
1210 | 1231 | ||
1211 | return status; | 1232 | return status; |