aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--editors/sed.c38
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)
282static int parse_regex_delim(const char *cmdstr, char **match, char **replace) 282static 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 */