diff options
author | landley <landley@69ca8d6d-28ef-0310-b511-8ec308f3f277> | 2006-05-09 03:53:55 +0000 |
---|---|---|
committer | landley <landley@69ca8d6d-28ef-0310-b511-8ec308f3f277> | 2006-05-09 03:53:55 +0000 |
commit | abc6bec2d1b0bc18d4fb93eeb6f9bf0880735aa3 (patch) | |
tree | 523e92ac10be5b5935a5a548de7a8c3a5f9aa215 | |
parent | 3c1f902d48dacded4e60c0607c7abb0a275390fd (diff) | |
download | busybox-w32-abc6bec2d1b0bc18d4fb93eeb6f9bf0880735aa3.tar.gz busybox-w32-abc6bec2d1b0bc18d4fb93eeb6f9bf0880735aa3.tar.bz2 busybox-w32-abc6bec2d1b0bc18d4fb93eeb6f9bf0880735aa3.zip |
Convert sed's static variables to a single global structure.
git-svn-id: svn://busybox.net/trunk/busybox@15041 69ca8d6d-28ef-0310-b511-8ec308f3f277
-rw-r--r-- | editors/sed.c | 253 |
1 files changed, 130 insertions, 123 deletions
diff --git a/editors/sed.c b/editors/sed.c index a3b825028..893931153 100644 --- a/editors/sed.c +++ b/editors/sed.c | |||
@@ -21,7 +21,7 @@ | |||
21 | add_cmd() is called on each line of sed command text (from a file or from | 21 | add_cmd() is called on each line of sed command text (from a file or from |
22 | the command line). It calls get_address() and parse_cmd_args(). The | 22 | the command line). It calls get_address() and parse_cmd_args(). The |
23 | resulting sed_cmd_t structures are appended to a linked list | 23 | resulting sed_cmd_t structures are appended to a linked list |
24 | (sed_cmd_head/sed_cmd_tail). | 24 | (bbg.sed_cmd_head/bbg.sed_cmd_tail). |
25 | 25 | ||
26 | add_input_file() adds a FILE * to the list of input files. We need to | 26 | add_input_file() adds a FILE * to the list of input files. We need to |
27 | know all input sources ahead of time to find the last line for the $ match. | 27 | know all input sources ahead of time to find the last line for the $ match. |
@@ -60,13 +60,14 @@ | |||
60 | 60 | ||
61 | #include <stdio.h> | 61 | #include <stdio.h> |
62 | #include <unistd.h> /* for getopt() */ | 62 | #include <unistd.h> /* for getopt() */ |
63 | #include <string.h> /* for strdup() */ | ||
64 | #include <errno.h> | 63 | #include <errno.h> |
65 | #include <ctype.h> /* for isspace() */ | 64 | #include <ctype.h> /* for isspace() */ |
66 | #include <stdlib.h> | 65 | #include <stdlib.h> |
66 | #include <string.h> | ||
67 | #include "busybox.h" | 67 | #include "busybox.h" |
68 | #include "xregex.h" | 68 | #include "xregex.h" |
69 | 69 | ||
70 | /* Each sed command turns into one of these structures. */ | ||
70 | typedef struct sed_cmd_s { | 71 | typedef struct sed_cmd_s { |
71 | /* Ordered by alignment requirements: currently 36 bytes on x86 */ | 72 | /* Ordered by alignment requirements: currently 36 bytes on x86 */ |
72 | 73 | ||
@@ -88,43 +89,52 @@ typedef struct sed_cmd_s { | |||
88 | unsigned int no_newline:1; /* Last line written by (sw) had no '\n' */ | 89 | unsigned int no_newline:1; /* Last line written by (sw) had no '\n' */ |
89 | unsigned int sub_p:1; /* (s) print option */ | 90 | unsigned int sub_p:1; /* (s) print option */ |
90 | 91 | ||
91 | |||
92 | /* GENERAL FIELDS */ | 92 | /* GENERAL FIELDS */ |
93 | char cmd; /* The command char: abcdDgGhHilnNpPqrstwxy:={} */ | 93 | char cmd; /* The command char: abcdDgGhHilnNpPqrstwxy:={} */ |
94 | struct sed_cmd_s *next; /* Next command (linked list, NULL terminated) */ | 94 | struct sed_cmd_s *next; /* Next command (linked list, NULL terminated) */ |
95 | } sed_cmd_t; | 95 | } sed_cmd_t; |
96 | 96 | ||
97 | /* globals */ | ||
98 | /* options */ | ||
99 | static int be_quiet, in_place, regex_type; | ||
100 | static FILE *nonstdout; | ||
101 | static char *outname,*hold_space; | ||
102 | |||
103 | /* List of input files */ | ||
104 | static int input_file_count,current_input_file; | ||
105 | static FILE **input_file_list; | ||
106 | |||
107 | static const char bad_format_in_subst[] = | 97 | static const char bad_format_in_subst[] = |
108 | "bad format in substitution expression"; | 98 | "bad format in substitution expression"; |
109 | static const char *const semicolon_whitespace = "; \n\r\t\v"; | 99 | static const char *const semicolon_whitespace = "; \n\r\t\v"; |
110 | 100 | ||
111 | static regmatch_t regmatch[10]; | 101 | struct sed_globals |
112 | static regex_t *previous_regex_ptr; | 102 | { |
103 | /* options */ | ||
104 | int be_quiet, in_place, regex_type; | ||
105 | FILE *nonstdout; | ||
106 | char *outname, *hold_space; | ||
107 | |||
108 | /* List of input files */ | ||
109 | int input_file_count,current_input_file; | ||
110 | FILE **input_file_list; | ||
111 | |||
112 | regmatch_t regmatch[10]; | ||
113 | regex_t *previous_regex_ptr; | ||
114 | |||
115 | /* linked list of sed commands */ | ||
116 | sed_cmd_t sed_cmd_head, *sed_cmd_tail; | ||
113 | 117 | ||
114 | /* linked list of sed commands */ | 118 | /* Linked list of append lines */ |
115 | static sed_cmd_t sed_cmd_head; | 119 | llist_t *append_head; |
116 | static sed_cmd_t *sed_cmd_tail = &sed_cmd_head; | 120 | |
121 | char *add_cmd_line; | ||
122 | |||
123 | struct pipeline { | ||
124 | char *buf; /* Space to hold string */ | ||
125 | int idx; /* Space used */ | ||
126 | int len; /* Space allocated */ | ||
127 | } pipeline; | ||
128 | } bbg; | ||
117 | 129 | ||
118 | /* Linked list of append lines */ | ||
119 | static llist_t *append_head=NULL; | ||
120 | 130 | ||
121 | void sed_free_and_close_stuff(void); | 131 | void sed_free_and_close_stuff(void); |
122 | #if ENABLE_FEATURE_CLEAN_UP | 132 | #if ENABLE_FEATURE_CLEAN_UP |
123 | void sed_free_and_close_stuff(void) | 133 | void sed_free_and_close_stuff(void) |
124 | { | 134 | { |
125 | sed_cmd_t *sed_cmd = sed_cmd_head.next; | 135 | sed_cmd_t *sed_cmd = bbg.sed_cmd_head.next; |
126 | 136 | ||
127 | llist_free_contents(append_head); | 137 | llist_free_contents(bbg.append_head); |
128 | 138 | ||
129 | while (sed_cmd) { | 139 | while (sed_cmd) { |
130 | sed_cmd_t *sed_cmd_next = sed_cmd->next; | 140 | sed_cmd_t *sed_cmd_next = sed_cmd->next; |
@@ -149,10 +159,10 @@ void sed_free_and_close_stuff(void) | |||
149 | sed_cmd = sed_cmd_next; | 159 | sed_cmd = sed_cmd_next; |
150 | } | 160 | } |
151 | 161 | ||
152 | if(hold_space) free(hold_space); | 162 | if(bbg.hold_space) free(bbg.hold_space); |
153 | 163 | ||
154 | while(current_input_file<input_file_count) | 164 | while(bbg.current_input_file<bbg.input_file_count) |
155 | fclose(input_file_list[current_input_file++]); | 165 | fclose(bbg.input_file_list[bbg.current_input_file++]); |
156 | } | 166 | } |
157 | #endif | 167 | #endif |
158 | 168 | ||
@@ -160,7 +170,7 @@ void sed_free_and_close_stuff(void) | |||
160 | 170 | ||
161 | static void cleanup_outname(void) | 171 | static void cleanup_outname(void) |
162 | { | 172 | { |
163 | if(outname) unlink(outname); | 173 | if(bbg.outname) unlink(bbg.outname); |
164 | } | 174 | } |
165 | 175 | ||
166 | /* strdup, replacing "\n" with '\n', and "\delimiter" with 'delimiter' */ | 176 | /* strdup, replacing "\n" with '\n', and "\delimiter" with 'delimiter' */ |
@@ -282,7 +292,7 @@ static int get_address(char *my_str, int *linenum, regex_t ** regex) | |||
282 | 292 | ||
283 | temp=copy_parsing_escapes(pos,next); | 293 | temp=copy_parsing_escapes(pos,next); |
284 | *regex = (regex_t *) xmalloc(sizeof(regex_t)); | 294 | *regex = (regex_t *) xmalloc(sizeof(regex_t)); |
285 | xregcomp(*regex, temp, regex_type|REG_NEWLINE); | 295 | xregcomp(*regex, temp, bbg.regex_type|REG_NEWLINE); |
286 | free(temp); | 296 | free(temp); |
287 | /* Move position to next character after last delimiter */ | 297 | /* Move position to next character after last delimiter */ |
288 | pos+=(next+1); | 298 | pos+=(next+1); |
@@ -291,7 +301,7 @@ static int get_address(char *my_str, int *linenum, regex_t ** regex) | |||
291 | } | 301 | } |
292 | 302 | ||
293 | /* Grab a filename. Whitespace at start is skipped, then goes to EOL. */ | 303 | /* Grab a filename. Whitespace at start is skipped, then goes to EOL. */ |
294 | static int parse_file_cmd(sed_cmd_t * sed_cmd, const char *filecmdstr, char **retval) | 304 | static int parse_file_cmd(sed_cmd_t *sed_cmd, const char *filecmdstr, char **retval) |
295 | { | 305 | { |
296 | int start = 0, idx, hack=0; | 306 | int start = 0, idx, hack=0; |
297 | 307 | ||
@@ -308,9 +318,9 @@ static int parse_file_cmd(sed_cmd_t * sed_cmd, const char *filecmdstr, char **re | |||
308 | return idx; | 318 | return idx; |
309 | } | 319 | } |
310 | 320 | ||
311 | static int parse_subst_cmd(sed_cmd_t * const sed_cmd, char *substr) | 321 | static int parse_subst_cmd(sed_cmd_t *const sed_cmd, char *substr) |
312 | { | 322 | { |
313 | int cflags = regex_type; | 323 | int cflags = bbg.regex_type; |
314 | char *match; | 324 | char *match; |
315 | int idx = 0; | 325 | int idx = 0; |
316 | 326 | ||
@@ -463,27 +473,21 @@ static char *parse_cmd_args(sed_cmd_t *sed_cmd, char *cmdstr) | |||
463 | 473 | ||
464 | static void add_cmd(char *cmdstr) | 474 | static void add_cmd(char *cmdstr) |
465 | { | 475 | { |
466 | static char *add_cmd_line=NULL; | ||
467 | sed_cmd_t *sed_cmd; | 476 | sed_cmd_t *sed_cmd; |
468 | int temp; | 477 | int temp; |
469 | 478 | ||
470 | /* Append this line to any unfinished line from last time. */ | 479 | /* Append this line to any unfinished line from last time. */ |
471 | if(add_cmd_line) { | 480 | if (bbg.add_cmd_line) { |
472 | int lastlen=strlen(add_cmd_line); | 481 | cmdstr = bb_xasprintf("%s\n%s", bbg.add_cmd_line, cmdstr); |
473 | char *tmp=xmalloc(lastlen+strlen(cmdstr)+2); | 482 | free(bbg.add_cmd_line); |
474 | 483 | bbg.add_cmd_line = cmdstr; | |
475 | memcpy(tmp,add_cmd_line,lastlen); | 484 | } else bbg.add_cmd_line=NULL; |
476 | tmp[lastlen]='\n'; | ||
477 | strcpy(tmp+lastlen+1,cmdstr); | ||
478 | free(add_cmd_line); | ||
479 | cmdstr=add_cmd_line=tmp; | ||
480 | } else add_cmd_line=NULL; | ||
481 | 485 | ||
482 | /* If this line ends with backslash, request next line. */ | 486 | /* If this line ends with backslash, request next line. */ |
483 | temp=strlen(cmdstr); | 487 | temp=strlen(cmdstr); |
484 | if(temp && cmdstr[temp-1]=='\\') { | 488 | if(temp && cmdstr[temp-1]=='\\') { |
485 | if(!add_cmd_line) add_cmd_line=strdup(cmdstr); | 489 | if (!bbg.add_cmd_line) bbg.add_cmd_line = bb_xstrdup(cmdstr); |
486 | add_cmd_line[temp-1]=0; | 490 | bbg.add_cmd_line[temp-1] = 0; |
487 | return; | 491 | return; |
488 | } | 492 | } |
489 | 493 | ||
@@ -498,7 +502,7 @@ static void add_cmd(char *cmdstr) | |||
498 | /* if this is a comment, jump past it and keep going */ | 502 | /* if this is a comment, jump past it and keep going */ |
499 | if (*cmdstr == '#') { | 503 | if (*cmdstr == '#') { |
500 | /* "#n" is the same as using -n on the command line */ | 504 | /* "#n" is the same as using -n on the command line */ |
501 | if (cmdstr[1] == 'n') be_quiet++; | 505 | if (cmdstr[1] == 'n') bbg.be_quiet++; |
502 | if(!(cmdstr=strpbrk(cmdstr, "\n\r"))) break; | 506 | if(!(cmdstr=strpbrk(cmdstr, "\n\r"))) break; |
503 | continue; | 507 | continue; |
504 | } | 508 | } |
@@ -520,7 +524,7 @@ static void add_cmd(char *cmdstr) | |||
520 | 524 | ||
521 | cmdstr++; | 525 | cmdstr++; |
522 | idx = get_address(cmdstr, &sed_cmd->end_line, &sed_cmd->end_match); | 526 | idx = get_address(cmdstr, &sed_cmd->end_line, &sed_cmd->end_match); |
523 | if (!idx) bb_error_msg_and_die("get_address: no address found in string\n"); | 527 | if (!idx) bb_error_msg_and_die("no address after comma\n"); |
524 | cmdstr += idx; | 528 | cmdstr += idx; |
525 | } | 529 | } |
526 | 530 | ||
@@ -542,32 +546,27 @@ static void add_cmd(char *cmdstr) | |||
542 | cmdstr = parse_cmd_args(sed_cmd, cmdstr); | 546 | cmdstr = parse_cmd_args(sed_cmd, cmdstr); |
543 | 547 | ||
544 | /* Add the command to the command array */ | 548 | /* Add the command to the command array */ |
545 | sed_cmd_tail->next = sed_cmd; | 549 | bbg.sed_cmd_tail->next = sed_cmd; |
546 | sed_cmd_tail = sed_cmd_tail->next; | 550 | bbg.sed_cmd_tail = bbg.sed_cmd_tail->next; |
547 | } | 551 | } |
548 | 552 | ||
549 | /* If we glued multiple lines together, free the memory. */ | 553 | /* If we glued multiple lines together, free the memory. */ |
550 | free(add_cmd_line); | 554 | free(bbg.add_cmd_line); |
551 | add_cmd_line=NULL; | 555 | bbg.add_cmd_line = NULL; |
552 | } | 556 | } |
553 | 557 | ||
554 | /* Append to a string, reallocating memory as necessary. */ | 558 | /* Append to a string, reallocating memory as necessary. */ |
555 | 559 | ||
556 | static struct pipeline { | ||
557 | char *buf; /* Space to hold string */ | ||
558 | int idx; /* Space used */ | ||
559 | int len; /* Space allocated */ | ||
560 | } pipeline; | ||
561 | |||
562 | #define PIPE_GROW 64 | 560 | #define PIPE_GROW 64 |
563 | 561 | ||
564 | static void pipe_putc(char c) | 562 | static void pipe_putc(char c) |
565 | { | 563 | { |
566 | if(pipeline.idx==pipeline.len) { | 564 | if(bbg.pipeline.idx==bbg.pipeline.len) { |
567 | pipeline.buf = xrealloc(pipeline.buf, pipeline.len + PIPE_GROW); | 565 | bbg.pipeline.buf = xrealloc(bbg.pipeline.buf, |
568 | pipeline.len+=PIPE_GROW; | 566 | bbg.pipeline.len + PIPE_GROW); |
567 | bbg.pipeline.len+=PIPE_GROW; | ||
569 | } | 568 | } |
570 | pipeline.buf[pipeline.idx++] = (c); | 569 | bbg.pipeline.buf[bbg.pipeline.idx++] = c; |
571 | } | 570 | } |
572 | 571 | ||
573 | static void do_subst_w_backrefs(const char *line, const char *replace) | 572 | static void do_subst_w_backrefs(const char *line, const char *replace) |
@@ -580,10 +579,10 @@ static void do_subst_w_backrefs(const char *line, const char *replace) | |||
580 | if (replace[i] == '\\' && replace[i+1]>='0' && replace[i+1]<='9') { | 579 | if (replace[i] == '\\' && replace[i+1]>='0' && replace[i+1]<='9') { |
581 | int backref=replace[++i]-'0'; | 580 | int backref=replace[++i]-'0'; |
582 | 581 | ||
583 | /* print out the text held in regmatch[backref] */ | 582 | /* print out the text held in bbg.regmatch[backref] */ |
584 | if(regmatch[backref].rm_so != -1) | 583 | if(bbg.regmatch[backref].rm_so != -1) |
585 | for (j = regmatch[backref].rm_so; j < regmatch[backref].rm_eo; j++) | 584 | for (j = bbg.regmatch[backref].rm_so; |
586 | pipe_putc(line[j]); | 585 | j < bbg.regmatch[backref].rm_eo; j++) pipe_putc(line[j]); |
587 | } | 586 | } |
588 | 587 | ||
589 | /* if we find a backslash escaped character, print the character */ | 588 | /* if we find a backslash escaped character, print the character */ |
@@ -591,14 +590,14 @@ static void do_subst_w_backrefs(const char *line, const char *replace) | |||
591 | 590 | ||
592 | /* if we find an unescaped '&' print out the whole matched text. */ | 591 | /* if we find an unescaped '&' print out the whole matched text. */ |
593 | else if (replace[i] == '&') | 592 | else if (replace[i] == '&') |
594 | for (j = regmatch[0].rm_so; j < regmatch[0].rm_eo; j++) | 593 | for (j = bbg.regmatch[0].rm_so; j < bbg.regmatch[0].rm_eo; j++) |
595 | pipe_putc(line[j]); | 594 | pipe_putc(line[j]); |
596 | /* Otherwise just output the character. */ | 595 | /* Otherwise just output the character. */ |
597 | else pipe_putc(replace[i]); | 596 | else pipe_putc(replace[i]); |
598 | } | 597 | } |
599 | } | 598 | } |
600 | 599 | ||
601 | static int do_subst_command(sed_cmd_t * sed_cmd, char **line) | 600 | static int do_subst_command(sed_cmd_t *sed_cmd, char **line) |
602 | { | 601 | { |
603 | char *oldline = *line; | 602 | char *oldline = *line; |
604 | int altered = 0; | 603 | int altered = 0; |
@@ -607,19 +606,19 @@ static int do_subst_command(sed_cmd_t * sed_cmd, char **line) | |||
607 | 606 | ||
608 | /* Handle empty regex. */ | 607 | /* Handle empty regex. */ |
609 | if (sed_cmd->sub_match == NULL) { | 608 | if (sed_cmd->sub_match == NULL) { |
610 | current_regex = previous_regex_ptr; | 609 | current_regex = bbg.previous_regex_ptr; |
611 | if(!current_regex) | 610 | if(!current_regex) |
612 | bb_error_msg_and_die("No previous regexp."); | 611 | bb_error_msg_and_die("No previous regexp."); |
613 | } else previous_regex_ptr = current_regex = sed_cmd->sub_match; | 612 | } else bbg.previous_regex_ptr = current_regex = sed_cmd->sub_match; |
614 | 613 | ||
615 | /* Find the first match */ | 614 | /* Find the first match */ |
616 | if(REG_NOMATCH==regexec(current_regex, oldline, 10, regmatch, 0)) | 615 | if(REG_NOMATCH==regexec(current_regex, oldline, 10, bbg.regmatch, 0)) |
617 | return 0; | 616 | return 0; |
618 | 617 | ||
619 | /* Initialize temporary output buffer. */ | 618 | /* Initialize temporary output buffer. */ |
620 | pipeline.buf=xmalloc(PIPE_GROW); | 619 | bbg.pipeline.buf=xmalloc(PIPE_GROW); |
621 | pipeline.len=PIPE_GROW; | 620 | bbg.pipeline.len=PIPE_GROW; |
622 | pipeline.idx=0; | 621 | bbg.pipeline.idx=0; |
623 | 622 | ||
624 | /* Now loop through, substituting for matches */ | 623 | /* Now loop through, substituting for matches */ |
625 | do { | 624 | do { |
@@ -629,7 +628,7 @@ static int do_subst_command(sed_cmd_t * sed_cmd, char **line) | |||
629 | echo " a.b" | busybox sed 's [^ .]* x g' | 628 | echo " a.b" | busybox sed 's [^ .]* x g' |
630 | The match_count check is so not to break | 629 | The match_count check is so not to break |
631 | echo "hi" | busybox sed 's/^/!/g' */ | 630 | echo "hi" | busybox sed 's/^/!/g' */ |
632 | if(!regmatch[0].rm_so && !regmatch[0].rm_eo && match_count) { | 631 | if(!bbg.regmatch[0].rm_so && !bbg.regmatch[0].rm_eo && match_count) { |
633 | pipe_putc(*(oldline++)); | 632 | pipe_putc(*(oldline++)); |
634 | continue; | 633 | continue; |
635 | } | 634 | } |
@@ -639,25 +638,25 @@ static int do_subst_command(sed_cmd_t * sed_cmd, char **line) | |||
639 | /* If we aren't interested in this match, output old line to | 638 | /* If we aren't interested in this match, output old line to |
640 | end of match and continue */ | 639 | end of match and continue */ |
641 | if(sed_cmd->which_match && sed_cmd->which_match!=match_count) { | 640 | if(sed_cmd->which_match && sed_cmd->which_match!=match_count) { |
642 | for(i=0;i<regmatch[0].rm_eo;i++) | 641 | for(i=0;i<bbg.regmatch[0].rm_eo;i++) |
643 | pipe_putc(oldline[i]); | 642 | pipe_putc(oldline[i]); |
644 | continue; | 643 | continue; |
645 | } | 644 | } |
646 | 645 | ||
647 | /* print everything before the match */ | 646 | /* print everything before the match */ |
648 | for (i = 0; i < regmatch[0].rm_so; i++) pipe_putc(oldline[i]); | 647 | for (i = 0; i < bbg.regmatch[0].rm_so; i++) pipe_putc(oldline[i]); |
649 | 648 | ||
650 | /* then print the substitution string */ | 649 | /* then print the substitution string */ |
651 | do_subst_w_backrefs(oldline, sed_cmd->string); | 650 | do_subst_w_backrefs(oldline, sed_cmd->string); |
652 | 651 | ||
653 | /* advance past the match */ | 652 | /* advance past the match */ |
654 | oldline += regmatch[0].rm_eo; | 653 | oldline += bbg.regmatch[0].rm_eo; |
655 | /* flag that something has changed */ | 654 | /* flag that something has changed */ |
656 | altered++; | 655 | altered++; |
657 | 656 | ||
658 | /* if we're not doing this globally, get out now */ | 657 | /* if we're not doing this globally, get out now */ |
659 | if (sed_cmd->which_match) break; | 658 | if (sed_cmd->which_match) break; |
660 | } while (*oldline && (regexec(current_regex, oldline, 10, regmatch, 0) != REG_NOMATCH)); | 659 | } while (*oldline && (regexec(current_regex, oldline, 10, bbg.regmatch, 0) != REG_NOMATCH)); |
661 | 660 | ||
662 | /* Copy rest of string into output pipeline */ | 661 | /* Copy rest of string into output pipeline */ |
663 | 662 | ||
@@ -665,7 +664,7 @@ static int do_subst_command(sed_cmd_t * sed_cmd, char **line) | |||
665 | pipe_putc(0); | 664 | pipe_putc(0); |
666 | 665 | ||
667 | free(*line); | 666 | free(*line); |
668 | *line = pipeline.buf; | 667 | *line = bbg.pipeline.buf; |
669 | return altered; | 668 | return altered; |
670 | } | 669 | } |
671 | 670 | ||
@@ -674,7 +673,7 @@ static sed_cmd_t *branch_to(const char *label) | |||
674 | { | 673 | { |
675 | sed_cmd_t *sed_cmd; | 674 | sed_cmd_t *sed_cmd; |
676 | 675 | ||
677 | for (sed_cmd = sed_cmd_head.next; sed_cmd; sed_cmd = sed_cmd->next) { | 676 | for (sed_cmd = bbg.sed_cmd_head.next; sed_cmd; sed_cmd = sed_cmd->next) { |
678 | if ((sed_cmd->cmd == ':') && (sed_cmd->string) && (strcmp(sed_cmd->string, label) == 0)) { | 677 | if ((sed_cmd->cmd == ':') && (sed_cmd->string) && (strcmp(sed_cmd->string, label) == 0)) { |
679 | return (sed_cmd); | 678 | return (sed_cmd); |
680 | } | 679 | } |
@@ -684,7 +683,7 @@ static sed_cmd_t *branch_to(const char *label) | |||
684 | 683 | ||
685 | static void append(char *s) | 684 | static void append(char *s) |
686 | { | 685 | { |
687 | append_head=llist_add_to_end(append_head, bb_xstrdup(s)); | 686 | bbg.append_head = llist_add_to_end(bbg.append_head, bb_xstrdup(s)); |
688 | } | 687 | } |
689 | 688 | ||
690 | static void flush_append(void) | 689 | static void flush_append(void) |
@@ -692,19 +691,20 @@ static void flush_append(void) | |||
692 | char *data; | 691 | char *data; |
693 | 692 | ||
694 | /* Output appended lines. */ | 693 | /* Output appended lines. */ |
695 | while((data = (char *)llist_pop(&append_head))) { | 694 | while((data = (char *)llist_pop(&bbg.append_head))) { |
696 | fprintf(nonstdout,"%s\n",data); | 695 | fprintf(bbg.nonstdout,"%s\n",data); |
697 | free(data); | 696 | free(data); |
698 | } | 697 | } |
699 | } | 698 | } |
700 | 699 | ||
701 | static void add_input_file(FILE *file) | 700 | static void add_input_file(FILE *file) |
702 | { | 701 | { |
703 | input_file_list=xrealloc(input_file_list,(input_file_count+1)*sizeof(FILE *)); | 702 | bbg.input_file_list=xrealloc(bbg.input_file_list, |
704 | input_file_list[input_file_count++]=file; | 703 | (bbg.input_file_count + 1) * sizeof(FILE *)); |
704 | bbg.input_file_list[bbg.input_file_count++] = file; | ||
705 | } | 705 | } |
706 | 706 | ||
707 | /* Get next line of input from input_file_list, flushing append buffer and | 707 | /* Get next line of input from bbg.input_file_list, flushing append buffer and |
708 | * noting if we ran out of files without a newline on the last line we read. | 708 | * noting if we ran out of files without a newline on the last line we read. |
709 | */ | 709 | */ |
710 | static char *get_next_line(int *no_newline) | 710 | static char *get_next_line(int *no_newline) |
@@ -713,14 +713,14 @@ static char *get_next_line(int *no_newline) | |||
713 | int len; | 713 | int len; |
714 | 714 | ||
715 | flush_append(); | 715 | flush_append(); |
716 | while (current_input_file<input_file_count) { | 716 | while (bbg.current_input_file<bbg.input_file_count) { |
717 | temp = bb_get_chunk_from_file(input_file_list[current_input_file],&len); | 717 | temp = bb_get_chunk_from_file(bbg.input_file_list[bbg.current_input_file],&len); |
718 | if (temp) { | 718 | if (temp) { |
719 | *no_newline = !(len && temp[len-1]=='\n'); | 719 | *no_newline = !(len && temp[len-1]=='\n'); |
720 | if (!*no_newline) temp[len-1] = 0; | 720 | if (!*no_newline) temp[len-1] = 0; |
721 | break; | 721 | break; |
722 | // Close this file and advance to next one | 722 | // Close this file and advance to next one |
723 | } else fclose(input_file_list[current_input_file++]); | 723 | } else fclose(bbg.input_file_list[bbg.current_input_file++]); |
724 | } | 724 | } |
725 | 725 | ||
726 | return temp; | 726 | return temp; |
@@ -744,7 +744,7 @@ static int puts_maybe_newline(char *s, FILE *file, int missing_newline, int no_n | |||
744 | return no_newline; | 744 | return no_newline; |
745 | } | 745 | } |
746 | 746 | ||
747 | #define sed_puts(s,n) missing_newline=puts_maybe_newline(s,nonstdout,missing_newline,n) | 747 | #define sed_puts(s,n) missing_newline=puts_maybe_newline(s,bbg.nonstdout,missing_newline,n) |
748 | 748 | ||
749 | /* Process all the lines in all the files */ | 749 | /* Process all the lines in all the files */ |
750 | 750 | ||
@@ -772,7 +772,8 @@ static void process_files(void) | |||
772 | linenum++; | 772 | linenum++; |
773 | restart: | 773 | restart: |
774 | /* for every line, go through all the commands */ | 774 | /* for every line, go through all the commands */ |
775 | for (sed_cmd = sed_cmd_head.next; sed_cmd; sed_cmd = sed_cmd->next) { | 775 | for (sed_cmd = bbg.sed_cmd_head.next; sed_cmd; sed_cmd = sed_cmd->next) |
776 | { | ||
776 | int old_matched, matched; | 777 | int old_matched, matched; |
777 | 778 | ||
778 | old_matched = sed_cmd->in_match; | 779 | old_matched = sed_cmd->in_match; |
@@ -828,7 +829,7 @@ restart: | |||
828 | if (sed_cmd->invert ? !matched : matched) { | 829 | if (sed_cmd->invert ? !matched : matched) { |
829 | /* Update last used regex in case a blank substitute BRE is found */ | 830 | /* Update last used regex in case a blank substitute BRE is found */ |
830 | if (sed_cmd->beg_match) { | 831 | if (sed_cmd->beg_match) { |
831 | previous_regex_ptr = sed_cmd->beg_match; | 832 | bbg.previous_regex_ptr = sed_cmd->beg_match; |
832 | } | 833 | } |
833 | 834 | ||
834 | /* actual sedding */ | 835 | /* actual sedding */ |
@@ -836,7 +837,7 @@ restart: | |||
836 | 837 | ||
837 | /* Print line number */ | 838 | /* Print line number */ |
838 | case '=': | 839 | case '=': |
839 | fprintf(nonstdout,"%d\n", linenum); | 840 | fprintf(bbg.nonstdout,"%d\n", linenum); |
840 | break; | 841 | break; |
841 | 842 | ||
842 | /* Write the current pattern space up to the first newline */ | 843 | /* Write the current pattern space up to the first newline */ |
@@ -931,7 +932,7 @@ restart: | |||
931 | 932 | ||
932 | /* Read next line from input */ | 933 | /* Read next line from input */ |
933 | case 'n': | 934 | case 'n': |
934 | if (!be_quiet) | 935 | if (!bbg.be_quiet) |
935 | sed_puts(pattern_space,no_newline); | 936 | sed_puts(pattern_space,no_newline); |
936 | if (next_line) { | 937 | if (next_line) { |
937 | free(pattern_space); | 938 | free(pattern_space); |
@@ -1007,7 +1008,7 @@ restart: | |||
1007 | } | 1008 | } |
1008 | case 'g': /* Replace pattern space with hold space */ | 1009 | case 'g': /* Replace pattern space with hold space */ |
1009 | free(pattern_space); | 1010 | free(pattern_space); |
1010 | pattern_space = strdup(hold_space ? hold_space : ""); | 1011 | pattern_space = bb_xstrdup(bbg.hold_space ? bbg.hold_space : ""); |
1011 | break; | 1012 | break; |
1012 | case 'G': /* Append newline and hold space to pattern space */ | 1013 | case 'G': /* Append newline and hold space to pattern space */ |
1013 | { | 1014 | { |
@@ -1016,42 +1017,46 @@ restart: | |||
1016 | 1017 | ||
1017 | if (pattern_space) | 1018 | if (pattern_space) |
1018 | pattern_space_size += strlen(pattern_space); | 1019 | pattern_space_size += strlen(pattern_space); |
1019 | if (hold_space) hold_space_size = strlen(hold_space); | 1020 | if (bbg.hold_space) |
1020 | pattern_space = xrealloc(pattern_space, pattern_space_size + hold_space_size); | 1021 | hold_space_size = strlen(bbg.hold_space); |
1022 | pattern_space = xrealloc(pattern_space, | ||
1023 | pattern_space_size + hold_space_size); | ||
1021 | if (pattern_space_size == 2) pattern_space[0]=0; | 1024 | if (pattern_space_size == 2) pattern_space[0]=0; |
1022 | strcat(pattern_space, "\n"); | 1025 | strcat(pattern_space, "\n"); |
1023 | if (hold_space) strcat(pattern_space, hold_space); | 1026 | if (bbg.hold_space) |
1027 | strcat(pattern_space, bbg.hold_space); | ||
1024 | no_newline=0; | 1028 | no_newline=0; |
1025 | 1029 | ||
1026 | break; | 1030 | break; |
1027 | } | 1031 | } |
1028 | case 'h': /* Replace hold space with pattern space */ | 1032 | case 'h': /* Replace hold space with pattern space */ |
1029 | free(hold_space); | 1033 | free(bbg.hold_space); |
1030 | hold_space = strdup(pattern_space); | 1034 | bbg.hold_space = bb_xstrdup(pattern_space); |
1031 | break; | 1035 | break; |
1032 | case 'H': /* Append newline and pattern space to hold space */ | 1036 | case 'H': /* Append newline and pattern space to hold space */ |
1033 | { | 1037 | { |
1034 | int hold_space_size = 2; | 1038 | int hold_space_size = 2; |
1035 | int pattern_space_size = 0; | 1039 | int pattern_space_size = 0; |
1036 | 1040 | ||
1037 | if (hold_space) hold_space_size += strlen(hold_space); | 1041 | if (bbg.hold_space) |
1042 | hold_space_size += strlen(bbg.hold_space); | ||
1038 | if (pattern_space) | 1043 | if (pattern_space) |
1039 | pattern_space_size = strlen(pattern_space); | 1044 | pattern_space_size = strlen(pattern_space); |
1040 | hold_space = xrealloc(hold_space, | 1045 | bbg.hold_space = xrealloc(bbg.hold_space, |
1041 | hold_space_size + pattern_space_size); | 1046 | hold_space_size + pattern_space_size); |
1042 | 1047 | ||
1043 | if (hold_space_size == 2) hold_space[0]=0; | 1048 | if (hold_space_size == 2) *bbg.hold_space=0; |
1044 | strcat(hold_space, "\n"); | 1049 | strcat(bbg.hold_space, "\n"); |
1045 | if (pattern_space) strcat(hold_space, pattern_space); | 1050 | if (pattern_space) strcat(bbg.hold_space, pattern_space); |
1046 | 1051 | ||
1047 | break; | 1052 | break; |
1048 | } | 1053 | } |
1049 | case 'x': /* Exchange hold and pattern space */ | 1054 | case 'x': /* Exchange hold and pattern space */ |
1050 | { | 1055 | { |
1051 | char *tmp = pattern_space; | 1056 | char *tmp = pattern_space; |
1052 | pattern_space = hold_space; | 1057 | pattern_space = bbg.hold_space; |
1053 | no_newline=0; | 1058 | no_newline=0; |
1054 | hold_space = tmp; | 1059 | bbg.hold_space = tmp; |
1055 | break; | 1060 | break; |
1056 | } | 1061 | } |
1057 | } | 1062 | } |
@@ -1064,7 +1069,7 @@ restart: | |||
1064 | discard_commands: | 1069 | discard_commands: |
1065 | /* we will print the line unless we were told to be quiet ('-n') | 1070 | /* we will print the line unless we were told to be quiet ('-n') |
1066 | or if the line was suppressed (ala 'd'elete) */ | 1071 | or if the line was suppressed (ala 'd'elete) */ |
1067 | if (!be_quiet) sed_puts(pattern_space,no_newline); | 1072 | if (!bbg.be_quiet) sed_puts(pattern_space,no_newline); |
1068 | 1073 | ||
1069 | /* Delete and such jump here. */ | 1074 | /* Delete and such jump here. */ |
1070 | discard_line: | 1075 | discard_line: |
@@ -1095,6 +1100,8 @@ int sed_main(int argc, char **argv) | |||
1095 | { | 1100 | { |
1096 | int status = EXIT_SUCCESS, opt, getpat = 1; | 1101 | int status = EXIT_SUCCESS, opt, getpat = 1; |
1097 | 1102 | ||
1103 | bbg.sed_cmd_tail=&bbg.sed_cmd_head; | ||
1104 | |||
1098 | /* destroy command strings on exit */ | 1105 | /* destroy command strings on exit */ |
1099 | if (ENABLE_FEATURE_CLEAN_UP) atexit(sed_free_and_close_stuff); | 1106 | if (ENABLE_FEATURE_CLEAN_UP) atexit(sed_free_and_close_stuff); |
1100 | 1107 | ||
@@ -1108,14 +1115,14 @@ int sed_main(int argc, char **argv) | |||
1108 | while ((opt = getopt(argc, argv, "irne:f:")) > 0) { | 1115 | while ((opt = getopt(argc, argv, "irne:f:")) > 0) { |
1109 | switch (opt) { | 1116 | switch (opt) { |
1110 | case 'i': | 1117 | case 'i': |
1111 | in_place++; | 1118 | bbg.in_place++; |
1112 | atexit(cleanup_outname); | 1119 | atexit(cleanup_outname); |
1113 | break; | 1120 | break; |
1114 | case 'r': | 1121 | case 'r': |
1115 | regex_type|=REG_EXTENDED; | 1122 | bbg.regex_type|=REG_EXTENDED; |
1116 | break; | 1123 | break; |
1117 | case 'n': | 1124 | case 'n': |
1118 | be_quiet++; | 1125 | bbg.be_quiet++; |
1119 | break; | 1126 | break; |
1120 | case 'e': | 1127 | case 'e': |
1121 | add_cmd_block(optarg); | 1128 | add_cmd_block(optarg); |
@@ -1153,13 +1160,13 @@ int sed_main(int argc, char **argv) | |||
1153 | add_cmd(""); | 1160 | add_cmd(""); |
1154 | 1161 | ||
1155 | /* By default, we write to stdout */ | 1162 | /* By default, we write to stdout */ |
1156 | nonstdout=stdout; | 1163 | bbg.nonstdout=stdout; |
1157 | 1164 | ||
1158 | /* argv[(optind)..(argc-1)] should be names of file to process. If no | 1165 | /* argv[(optind)..(argc-1)] should be names of file to process. If no |
1159 | * files were specified or '-' was specified, take input from stdin. | 1166 | * files were specified or '-' was specified, take input from stdin. |
1160 | * Otherwise, we process all the files specified. */ | 1167 | * Otherwise, we process all the files specified. */ |
1161 | if (argv[optind] == NULL) { | 1168 | if (argv[optind] == NULL) { |
1162 | if(in_place) bb_error_msg_and_die("Filename required for -i"); | 1169 | if(bbg.in_place) bb_error_msg_and_die("Filename required for -i"); |
1163 | add_input_file(stdin); | 1170 | add_input_file(stdin); |
1164 | process_files(); | 1171 | process_files(); |
1165 | } else { | 1172 | } else { |
@@ -1167,21 +1174,21 @@ int sed_main(int argc, char **argv) | |||
1167 | FILE *file; | 1174 | FILE *file; |
1168 | 1175 | ||
1169 | for (i = optind; i < argc; i++) { | 1176 | for (i = optind; i < argc; i++) { |
1170 | if(!strcmp(argv[i], "-") && !in_place) { | 1177 | if(!strcmp(argv[i], "-") && !bbg.in_place) { |
1171 | add_input_file(stdin); | 1178 | add_input_file(stdin); |
1172 | process_files(); | 1179 | process_files(); |
1173 | } else { | 1180 | } else { |
1174 | file = bb_wfopen(argv[i], "r"); | 1181 | file = bb_wfopen(argv[i], "r"); |
1175 | if (file) { | 1182 | if (file) { |
1176 | if(in_place) { | 1183 | if(bbg.in_place) { |
1177 | struct stat statbuf; | 1184 | struct stat statbuf; |
1178 | int nonstdoutfd; | 1185 | int nonstdoutfd; |
1179 | 1186 | ||
1180 | outname=bb_xstrndup(argv[i],strlen(argv[i])+6); | 1187 | bbg.outname=bb_xstrndup(argv[i],strlen(argv[i])+6); |
1181 | strcat(outname,"XXXXXX"); | 1188 | strcat(bbg.outname,"XXXXXX"); |
1182 | if(-1==(nonstdoutfd=mkstemp(outname))) | 1189 | if(-1==(nonstdoutfd=mkstemp(bbg.outname))) |
1183 | bb_error_msg_and_die("no temp file"); | 1190 | bb_error_msg_and_die("no temp file"); |
1184 | nonstdout=fdopen(nonstdoutfd,"w"); | 1191 | bbg.nonstdout=fdopen(nonstdoutfd,"w"); |
1185 | 1192 | ||
1186 | /* Set permissions of output file */ | 1193 | /* Set permissions of output file */ |
1187 | 1194 | ||
@@ -1189,20 +1196,20 @@ int sed_main(int argc, char **argv) | |||
1189 | fchmod(nonstdoutfd,statbuf.st_mode); | 1196 | fchmod(nonstdoutfd,statbuf.st_mode); |
1190 | add_input_file(file); | 1197 | add_input_file(file); |
1191 | process_files(); | 1198 | process_files(); |
1192 | fclose(nonstdout); | 1199 | fclose(bbg.nonstdout); |
1193 | 1200 | ||
1194 | nonstdout=stdout; | 1201 | bbg.nonstdout=stdout; |
1195 | unlink(argv[i]); | 1202 | unlink(argv[i]); |
1196 | rename(outname,argv[i]); | 1203 | rename(bbg.outname,argv[i]); |
1197 | free(outname); | 1204 | free(bbg.outname); |
1198 | outname=0; | 1205 | bbg.outname=0; |
1199 | } else add_input_file(file); | 1206 | } else add_input_file(file); |
1200 | } else { | 1207 | } else { |
1201 | status = EXIT_FAILURE; | 1208 | status = EXIT_FAILURE; |
1202 | } | 1209 | } |
1203 | } | 1210 | } |
1204 | } | 1211 | } |
1205 | if(input_file_count>current_input_file) process_files(); | 1212 | if(bbg.input_file_count>bbg.current_input_file) process_files(); |
1206 | } | 1213 | } |
1207 | 1214 | ||
1208 | return status; | 1215 | return status; |