diff options
-rw-r--r-- | editors/sed.c | 38 |
1 files changed, 25 insertions, 13 deletions
diff --git a/editors/sed.c b/editors/sed.c index c8bb503ea..4e9babb9d 100644 --- a/editors/sed.c +++ b/editors/sed.c | |||
@@ -282,7 +282,7 @@ static int index_of_next_unescaped_regexp_delim(int delimiter, const char *str) | |||
282 | static int parse_regex_delim(const char *cmdstr, char **match, char **replace) | 282 | static int parse_regex_delim(const char *cmdstr, char **match, char **replace) |
283 | { | 283 | { |
284 | const char *cmdstr_ptr = cmdstr; | 284 | const char *cmdstr_ptr = cmdstr; |
285 | char delimiter; | 285 | unsigned char delimiter; |
286 | int idx = 0; | 286 | int idx = 0; |
287 | 287 | ||
288 | /* verify that the 's' or 'y' is followed by something. That something | 288 | /* verify that the 's' or 'y' is followed by something. That something |
@@ -297,7 +297,7 @@ static int parse_regex_delim(const char *cmdstr, char **match, char **replace) | |||
297 | 297 | ||
298 | /* save the replacement string */ | 298 | /* save the replacement string */ |
299 | cmdstr_ptr += idx + 1; | 299 | cmdstr_ptr += idx + 1; |
300 | idx = index_of_next_unescaped_regexp_delim(-delimiter, cmdstr_ptr); | 300 | idx = index_of_next_unescaped_regexp_delim(- (int)delimiter, cmdstr_ptr); |
301 | *replace = copy_parsing_escapes(cmdstr_ptr, idx); | 301 | *replace = copy_parsing_escapes(cmdstr_ptr, idx); |
302 | 302 | ||
303 | return ((cmdstr_ptr - cmdstr) + idx); | 303 | return ((cmdstr_ptr - cmdstr) + idx); |
@@ -322,10 +322,11 @@ static int get_address(const char *my_str, int *linenum, regex_t ** regex) | |||
322 | char *temp; | 322 | char *temp; |
323 | 323 | ||
324 | delimiter = '/'; | 324 | delimiter = '/'; |
325 | if (*my_str == '\\') delimiter = *++pos; | 325 | if (*my_str == '\\') |
326 | delimiter = *++pos; | ||
326 | next = index_of_next_unescaped_regexp_delim(delimiter, ++pos); | 327 | next = index_of_next_unescaped_regexp_delim(delimiter, ++pos); |
327 | temp = copy_parsing_escapes(pos, next); | 328 | temp = copy_parsing_escapes(pos, next); |
328 | *regex = xmalloc(sizeof(regex_t)); | 329 | *regex = xzalloc(sizeof(regex_t)); |
329 | xregcomp(*regex, temp, G.regex_type|REG_NEWLINE); | 330 | xregcomp(*regex, temp, G.regex_type|REG_NEWLINE); |
330 | free(temp); | 331 | free(temp); |
331 | /* Move position to next character after last delimiter */ | 332 | /* Move position to next character after last delimiter */ |
@@ -434,8 +435,10 @@ static int parse_subst_cmd(sed_cmd_t *sed_cmd, const char *substr) | |||
434 | /* compile the match string into a regex */ | 435 | /* compile the match string into a regex */ |
435 | if (*match != '\0') { | 436 | if (*match != '\0') { |
436 | /* If match is empty, we use last regex used at runtime */ | 437 | /* If match is empty, we use last regex used at runtime */ |
437 | sed_cmd->sub_match = xmalloc(sizeof(regex_t)); | 438 | sed_cmd->sub_match = xzalloc(sizeof(regex_t)); |
439 | dbg("xregcomp('%s',%x)", match, cflags); | ||
438 | xregcomp(sed_cmd->sub_match, match, cflags); | 440 | xregcomp(sed_cmd->sub_match, match, cflags); |
441 | dbg("regcomp ok"); | ||
439 | } | 442 | } |
440 | free(match); | 443 | free(match); |
441 | 444 | ||
@@ -717,8 +720,12 @@ static int do_subst_command(sed_cmd_t *sed_cmd, char **line_p) | |||
717 | G.previous_regex_ptr = current_regex; | 720 | G.previous_regex_ptr = current_regex; |
718 | 721 | ||
719 | /* Find the first match */ | 722 | /* Find the first match */ |
720 | if (REG_NOMATCH == regexec(current_regex, line, 10, G.regmatch, 0)) | 723 | dbg("matching '%s'", line); |
724 | if (REG_NOMATCH == regexec(current_regex, line, 10, G.regmatch, 0)) { | ||
725 | dbg("no match"); | ||
721 | return 0; | 726 | return 0; |
727 | } | ||
728 | dbg("match"); | ||
722 | 729 | ||
723 | /* Initialize temporary output buffer. */ | 730 | /* Initialize temporary output buffer. */ |
724 | G.pipeline.buf = xmalloc(PIPE_GROW); | 731 | G.pipeline.buf = xmalloc(PIPE_GROW); |
@@ -730,9 +737,10 @@ static int do_subst_command(sed_cmd_t *sed_cmd, char **line_p) | |||
730 | int i; | 737 | int i; |
731 | 738 | ||
732 | /* Work around bug in glibc regexec, demonstrated by: | 739 | /* Work around bug in glibc regexec, demonstrated by: |
733 | echo " a.b" | busybox sed 's [^ .]* x g' | 740 | * echo " a.b" | busybox sed 's [^ .]* x g' |
734 | The match_count check is so not to break | 741 | * The match_count check is so not to break |
735 | echo "hi" | busybox sed 's/^/!/g' */ | 742 | * echo "hi" | busybox sed 's/^/!/g' |
743 | */ | ||
736 | if (!G.regmatch[0].rm_so && !G.regmatch[0].rm_eo && match_count) { | 744 | if (!G.regmatch[0].rm_so && !G.regmatch[0].rm_eo && match_count) { |
737 | pipe_putc(*line++); | 745 | pipe_putc(*line++); |
738 | continue; | 746 | continue; |
@@ -763,11 +771,14 @@ static int do_subst_command(sed_cmd_t *sed_cmd, char **line_p) | |||
763 | altered++; | 771 | altered++; |
764 | 772 | ||
765 | /* if we're not doing this globally, get out now */ | 773 | /* if we're not doing this globally, get out now */ |
766 | if (sed_cmd->which_match) | 774 | if (sed_cmd->which_match != 0) |
775 | break; | ||
776 | |||
777 | if (*line == '\0') | ||
767 | break; | 778 | break; |
768 | 779 | ||
769 | //maybe (G.regmatch[0].rm_eo ? REG_NOTBOL : 0) instead of unconditional REG_NOTBOL? | 780 | //maybe (G.regmatch[0].rm_eo ? REG_NOTBOL : 0) instead of unconditional REG_NOTBOL? |
770 | } while (*line && regexec(current_regex, line, 10, G.regmatch, REG_NOTBOL) != REG_NOMATCH); | 781 | } while (regexec(current_regex, line, 10, G.regmatch, REG_NOTBOL) != REG_NOMATCH); |
771 | 782 | ||
772 | /* Copy rest of string into output pipeline */ | 783 | /* Copy rest of string into output pipeline */ |
773 | while (1) { | 784 | while (1) { |
@@ -1067,8 +1078,8 @@ static void process_files(void) | |||
1067 | } | 1078 | } |
1068 | 1079 | ||
1069 | /* actual sedding */ | 1080 | /* actual sedding */ |
1070 | //bb_error_msg("pattern_space:'%s' next_line:'%s' cmd:%c", | 1081 | dbg("pattern_space:'%s' next_line:'%s' cmd:%c", |
1071 | //pattern_space, next_line, sed_cmd->cmd); | 1082 | pattern_space, next_line, sed_cmd->cmd); |
1072 | switch (sed_cmd->cmd) { | 1083 | switch (sed_cmd->cmd) { |
1073 | 1084 | ||
1074 | /* Print line number */ | 1085 | /* Print line number */ |
@@ -1115,6 +1126,7 @@ static void process_files(void) | |||
1115 | case 's': | 1126 | case 's': |
1116 | if (!do_subst_command(sed_cmd, &pattern_space)) | 1127 | if (!do_subst_command(sed_cmd, &pattern_space)) |
1117 | break; | 1128 | break; |
1129 | dbg("do_subst_command succeeeded:'%s'", pattern_space); | ||
1118 | substituted |= 1; | 1130 | substituted |= 1; |
1119 | 1131 | ||
1120 | /* handle p option */ | 1132 | /* handle p option */ |