aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--editors/sed.c73
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 */
107static sed_cmd_t *sed_cmds = NULL; /* growable arrary holding a sequence of sed cmds */ 107static sed_cmd_t **sed_cmds = NULL; /* growable arrary holding a sequence of sed cmds */
108static int ncmds = 0; /* number of sed commands */ 108static 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
383static char *parse_cmd_str(sed_cmd_t * const sed_cmd, char *cmdstr) 383static 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
468static void add_cmd_str(const char * const cmdstr) 467static 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;