diff options
-rw-r--r-- | editors/sed.c | 73 |
1 files changed, 36 insertions, 37 deletions
diff --git a/editors/sed.c b/editors/sed.c index 6ee4693cb..96e0dd88b 100644 --- a/editors/sed.c +++ b/editors/sed.c | |||
@@ -104,7 +104,7 @@ typedef struct sed_cmd_s { | |||
104 | } sed_cmd_t; | 104 | } sed_cmd_t; |
105 | 105 | ||
106 | /* globals */ | 106 | /* globals */ |
107 | static sed_cmd_t *sed_cmds = NULL; /* growable arrary holding a sequence of sed cmds */ | 107 | static sed_cmd_t **sed_cmds = NULL; /* growable arrary holding a sequence of sed cmds */ |
108 | static int ncmds = 0; /* number of sed commands */ | 108 | static int ncmds = 0; /* number of sed commands */ |
109 | 109 | ||
110 | /*static char *cur_file = NULL;*/ /* file currently being processed XXX: do I need this? */ | 110 | /*static char *cur_file = NULL;*/ /* file currently being processed XXX: do I need this? */ |
@@ -120,19 +120,19 @@ static void destroy_cmd_strs(void) | |||
120 | /* destroy all the elements in the array */ | 120 | /* destroy all the elements in the array */ |
121 | while (--ncmds >= 0) { | 121 | while (--ncmds >= 0) { |
122 | 122 | ||
123 | if (sed_cmds[ncmds].beg_match) { | 123 | if (sed_cmds[ncmds]->beg_match) { |
124 | regfree(sed_cmds[ncmds].beg_match); | 124 | regfree(sed_cmds[ncmds]->beg_match); |
125 | free(sed_cmds[ncmds].beg_match); | 125 | free(sed_cmds[ncmds]->beg_match); |
126 | } | 126 | } |
127 | if (sed_cmds[ncmds].end_match) { | 127 | if (sed_cmds[ncmds]->end_match) { |
128 | regfree(sed_cmds[ncmds].end_match); | 128 | regfree(sed_cmds[ncmds]->end_match); |
129 | free(sed_cmds[ncmds].end_match); | 129 | free(sed_cmds[ncmds]->end_match); |
130 | } | 130 | } |
131 | if (sed_cmds[ncmds].sub_match) { | 131 | if (sed_cmds[ncmds]->sub_match) { |
132 | regfree(sed_cmds[ncmds].sub_match); | 132 | regfree(sed_cmds[ncmds]->sub_match); |
133 | free(sed_cmds[ncmds].sub_match); | 133 | free(sed_cmds[ncmds]->sub_match); |
134 | } | 134 | } |
135 | free(sed_cmds[ncmds].replace); | 135 | free(sed_cmds[ncmds]->replace); |
136 | } | 136 | } |
137 | 137 | ||
138 | /* destroy the array */ | 138 | /* destroy the array */ |
@@ -382,8 +382,6 @@ static int parse_file_cmd(sed_cmd_t *sed_cmd, const char *filecmdstr) | |||
382 | 382 | ||
383 | static char *parse_cmd_str(sed_cmd_t * const sed_cmd, char *cmdstr) | 383 | static char *parse_cmd_str(sed_cmd_t * const sed_cmd, char *cmdstr) |
384 | { | 384 | { |
385 | int idx = 0; | ||
386 | |||
387 | /* parse the command | 385 | /* parse the command |
388 | * format is: [addr][,addr]cmd | 386 | * format is: [addr][,addr]cmd |
389 | * |----||-----||-| | 387 | * |----||-----||-| |
@@ -391,29 +389,29 @@ static char *parse_cmd_str(sed_cmd_t * const sed_cmd, char *cmdstr) | |||
391 | */ | 389 | */ |
392 | 390 | ||
393 | /* first part (if present) is an address: either a '$', a number or a /regex/ */ | 391 | /* first part (if present) is an address: either a '$', a number or a /regex/ */ |
394 | idx = get_address(&sed_cmd->delimiter, cmdstr, &sed_cmd->beg_line, &sed_cmd->beg_match); | 392 | cmdstr += get_address(&sed_cmd->delimiter, cmdstr, &sed_cmd->beg_line, &sed_cmd->beg_match); |
395 | 393 | ||
396 | /* second part (if present) will begin with a comma */ | 394 | /* second part (if present) will begin with a comma */ |
397 | if (cmdstr[idx] == ',') { | 395 | if (*cmdstr == ',') { |
398 | int tmp_idx; | 396 | int tmp_idx; |
399 | idx++; | 397 | cmdstr++; |
400 | tmp_idx = get_address(&sed_cmd->delimiter, &cmdstr[idx], &sed_cmd->end_line, &sed_cmd->end_match); | 398 | tmp_idx = get_address(&sed_cmd->delimiter, cmdstr, &sed_cmd->end_line, &sed_cmd->end_match); |
401 | if (tmp_idx == 0) { | 399 | if (tmp_idx == 0) { |
402 | error_msg_and_die("get_address: no address found in string\n" | 400 | error_msg_and_die("get_address: no address found in string\n" |
403 | "\t(you probably didn't check the string you passed me)"); | 401 | "\t(you probably didn't check the string you passed me)"); |
404 | } | 402 | } |
405 | idx += tmp_idx; | 403 | cmdstr += tmp_idx; |
406 | } | 404 | } |
407 | 405 | ||
408 | /* skip whitespace before the command */ | 406 | /* skip whitespace before the command */ |
409 | while (isspace(cmdstr[idx])) | 407 | while (isspace(*cmdstr)) |
410 | idx++; | 408 | cmdstr++; |
411 | 409 | ||
412 | /* there my be the inversion flag between part2 and part3 */ | 410 | /* there my be the inversion flag between part2 and part3 */ |
413 | sed_cmd->invert = 0; | 411 | sed_cmd->invert = 0; |
414 | if (cmdstr[idx] == '!') { | 412 | if (*cmdstr == '!') { |
415 | sed_cmd->invert = 1; | 413 | sed_cmd->invert = 1; |
416 | idx++; | 414 | cmdstr++; |
417 | 415 | ||
418 | #ifdef SED_FEATURE_STRICT_CHECKING | 416 | #ifdef SED_FEATURE_STRICT_CHECKING |
419 | /* According to the spec | 417 | /* According to the spec |
@@ -421,48 +419,49 @@ static char *parse_cmd_str(sed_cmd_t * const sed_cmd, char *cmdstr) | |||
421 | * and conforming applications shall not follow a '!' character | 419 | * and conforming applications shall not follow a '!' character |
422 | * with <blank>s. | 420 | * with <blank>s. |
423 | */ | 421 | */ |
424 | if (isblank(cmdstr[idx]) { | 422 | if (isblank(*cmdstr) { |
425 | error_msg_and_die("blank follows '!'"); | 423 | error_msg_and_die("blank follows '!'"); |
426 | } | 424 | } |
427 | #else | 425 | #else |
428 | /* skip whitespace before the command */ | 426 | /* skip whitespace before the command */ |
429 | while (isspace(cmdstr[idx])) | 427 | while (isspace(*cmdstr)) |
430 | idx++; | 428 | cmdstr++; |
431 | #endif | 429 | #endif |
432 | } | 430 | } |
433 | 431 | ||
434 | /* last part (mandatory) will be a command */ | 432 | /* last part (mandatory) will be a command */ |
435 | if (cmdstr[idx] == '\0') | 433 | if (*cmdstr == '\0') |
436 | error_msg_and_die("missing command"); | 434 | error_msg_and_die("missing command"); |
437 | sed_cmd->cmd = cmdstr[idx]; | 435 | |
436 | sed_cmd->cmd = *cmdstr; | ||
438 | 437 | ||
439 | /* if it was a single-letter command that takes no arguments (such as 'p' | 438 | /* if it was a single-letter command that takes no arguments (such as 'p' |
440 | * or 'd') all we need to do is increment the index past that command */ | 439 | * or 'd') all we need to do is increment the index past that command */ |
441 | if (strchr("pd=", sed_cmd->cmd)) { | 440 | if (strchr("pd=", sed_cmd->cmd)) { |
442 | idx++; | 441 | cmdstr++; |
443 | } | 442 | } |
444 | /* handle (s)ubstitution command */ | 443 | /* handle (s)ubstitution command */ |
445 | else if (sed_cmd->cmd == 's') { | 444 | else if (sed_cmd->cmd == 's') { |
446 | idx += parse_subst_cmd(sed_cmd, &cmdstr[idx]); | 445 | cmdstr += parse_subst_cmd(sed_cmd, cmdstr); |
447 | } | 446 | } |
448 | /* handle edit cmds: (a)ppend, (i)nsert, and (c)hange */ | 447 | /* handle edit cmds: (a)ppend, (i)nsert, and (c)hange */ |
449 | else if (strchr("aic", sed_cmd->cmd)) { | 448 | else if (strchr("aic", sed_cmd->cmd)) { |
450 | if ((sed_cmd->end_line || sed_cmd->end_match) && sed_cmd->cmd != 'c') | 449 | if ((sed_cmd->end_line || sed_cmd->end_match) && sed_cmd->cmd != 'c') |
451 | error_msg_and_die("only a beginning address can be specified for edit commands"); | 450 | error_msg_and_die("only a beginning address can be specified for edit commands"); |
452 | idx += parse_edit_cmd(sed_cmd, &cmdstr[idx]); | 451 | cmdstr += parse_edit_cmd(sed_cmd, cmdstr); |
453 | } | 452 | } |
454 | /* handle file cmds: (r)ead */ | 453 | /* handle file cmds: (r)ead */ |
455 | else if (sed_cmd->cmd == 'r') { | 454 | else if (sed_cmd->cmd == 'r') { |
456 | if (sed_cmd->end_line || sed_cmd->end_match) | 455 | if (sed_cmd->end_line || sed_cmd->end_match) |
457 | error_msg_and_die("Command only uses one address"); | 456 | error_msg_and_die("Command only uses one address"); |
458 | idx += parse_file_cmd(sed_cmd, &cmdstr[idx]); | 457 | cmdstr += parse_file_cmd(sed_cmd, cmdstr); |
459 | } | 458 | } |
460 | else { | 459 | else { |
461 | error_msg_and_die("Unsupported command %c", sed_cmd->cmd); | 460 | error_msg_and_die("Unsupported command %c", sed_cmd->cmd); |
462 | } | 461 | } |
463 | 462 | ||
464 | /* give back whatever's left over */ | 463 | /* give back whatever's left over */ |
465 | return (char *)&cmdstr[idx]; | 464 | return(cmdstr); |
466 | } | 465 | } |
467 | 466 | ||
468 | static void add_cmd_str(const char * const cmdstr) | 467 | static void add_cmd_str(const char * const cmdstr) |
@@ -483,11 +482,11 @@ static void add_cmd_str(const char * const cmdstr) | |||
483 | continue; | 482 | continue; |
484 | } | 483 | } |
485 | /* grow the array */ | 484 | /* grow the array */ |
486 | sed_cmds = xrealloc(sed_cmds, sizeof(sed_cmd_t) * (++ncmds)); | 485 | sed_cmds = xrealloc(sed_cmds, sizeof(sed_cmd_t *) * (++ncmds)); |
487 | /* zero new element */ | 486 | /* zero new element */ |
488 | memset(&sed_cmds[ncmds-1], 0, sizeof(sed_cmd_t)); | 487 | sed_cmds[ncmds-1] = xcalloc(1, sizeof(sed_cmd_t)); |
489 | /* load command string into new array element, get remainder */ | 488 | /* load command string into new array element, get remainder */ |
490 | mystr = parse_cmd_str(&sed_cmds[ncmds-1], mystr); | 489 | mystr = parse_cmd_str(sed_cmds[ncmds-1], mystr); |
491 | 490 | ||
492 | } while (mystr && strlen(mystr)); | 491 | } while (mystr && strlen(mystr)); |
493 | } | 492 | } |
@@ -676,7 +675,7 @@ static void process_file(FILE *file) | |||
676 | 675 | ||
677 | /* for every line, go through all the commands */ | 676 | /* for every line, go through all the commands */ |
678 | for (i = 0; i < ncmds; i++) { | 677 | for (i = 0; i < ncmds; i++) { |
679 | sed_cmd_t *sed_cmd = &sed_cmds[i]; | 678 | sed_cmd_t *sed_cmd = sed_cmds[i]; |
680 | int deleted = 0; | 679 | int deleted = 0; |
681 | 680 | ||
682 | /* | 681 | /* |
@@ -745,7 +744,7 @@ static void process_file(FILE *file) | |||
745 | * (this is quite possibly the second printing) */ | 744 | * (this is quite possibly the second printing) */ |
746 | if (sed_cmd->sub_p) | 745 | if (sed_cmd->sub_p) |
747 | altered |= do_subst_command(sed_cmd, &line); | 746 | altered |= do_subst_command(sed_cmd, &line); |
748 | if (altered && (i+1 >= ncmds || sed_cmds[i+1].cmd != 's')) | 747 | if (altered && (i+1 >= ncmds || sed_cmds[i+1]->cmd != 's')) |
749 | puts(line); | 748 | puts(line); |
750 | 749 | ||
751 | break; | 750 | break; |