/* * Returns the index of the third delimiter */ static int parse_regex_delim(const char *cmdstr, char **match, char **replace) { const char *cmdstr_ptr = cmdstr; char delimiter; int idx = 0; /* verify that the 's' or 'y' is followed by something. That something * (typically a 'slash') is now our regexp delimiter... */ if (*cmdstr == '\0') bb_error_msg_and_die(bad_format_in_subst); delimiter = *(cmdstr_ptr++); /* save the match string */ idx = index_of_next_unescaped_regexp_delim(delimiter, cmdstr_ptr); if (idx == -1) { bb_error_msg_and_die(bad_format_in_subst); } *match = copy_parsing_slashn(cmdstr_ptr, idx); /* save the replacement string */ cmdstr_ptr += idx + 1; idx = index_of_next_unescaped_regexp_delim(delimiter, cmdstr_ptr); if (idx == -1) { bb_error_msg_and_die(bad_format_in_subst); } *replace = copy_parsing_slashn(cmdstr_ptr, idx); return ((cmdstr_ptr - cmdstr) + idx); }
/* * returns the index in the string just past where the address ends. */ static int get_address(const char *my_str, int *linenum, regex_t ** regex) { const char *pos = my_str; if (isdigit(*my_str)) { *linenum = strtol(my_str, (char**)&pos, 10); /* endstr shouldn't ever equal NULL */ } else if (*my_str == '$') { *linenum = -1; pos++; } else if (*my_str == '/' || *my_str == '\\') { int next; char delimiter; char *temp; delimiter = '/'; if (*my_str == '\\') delimiter = *++pos; next = index_of_next_unescaped_regexp_delim(delimiter, ++pos); if (next != 0) { temp = copy_parsing_escapes(pos, next); G.previous_regex_ptr = *regex = xzalloc(sizeof(regex_t)); xregcomp(*regex, temp, G.regex_type); free(temp); } else { *regex = G.previous_regex_ptr; if (!G.previous_regex_ptr) bb_error_msg_and_die("no previous regexp"); } /* Move position to next character after last delimiter */ pos += (next+1); } return pos - my_str; }
/* * returns the index in the string just past where the address ends. */ static int get_address(const char *my_str, int *linenum, regex_t ** regex) { const char *pos = my_str; if (isdigit(*my_str)) { *linenum = strtol(my_str, (char**)&pos, 10); /* endstr shouldnt ever equal NULL */ } else if (*my_str == '$') { *linenum = -1; pos++; } else if (*my_str == '/' || *my_str == '\\') { int next; char delimiter; char *temp; delimiter = '/'; if (*my_str == '\\') delimiter = *++pos; next = index_of_next_unescaped_regexp_delim(delimiter, ++pos); temp = copy_parsing_escapes(pos, next); *regex = xmalloc(sizeof(regex_t)); xregcomp(*regex, temp, G.regex_type|REG_NEWLINE); free(temp); /* Move position to next character after last delimiter */ pos += (next+1); } return pos - my_str; }
/* * returns the index in the string just past where the address ends. */ static int get_address(char *my_str, int *linenum, regex_t ** regex) { char *pos = my_str; if (isdigit(*my_str)) { *linenum = strtol(my_str, &pos, 10); /* endstr shouldnt ever equal NULL */ } else if (*my_str == '$') { *linenum = -1; pos++; } else if (*my_str == '/' || *my_str == '\\') { int next; char delimiter; char *temp; if (*my_str == '\\') delimiter = *(++pos); else delimiter = '/'; next = index_of_next_unescaped_regexp_delim(delimiter, ++pos); if (next == -1) bb_error_msg_and_die("unterminated match expression"); temp=copy_parsing_slashn(pos,next); *regex = (regex_t *) xmalloc(sizeof(regex_t)); xregcomp(*regex, temp, REG_NEWLINE); free(temp); /* Move position to next character after last delimiter */ pos+=(next+1); } return pos - my_str; }
/* * Returns the index of the third delimiter */ static int parse_regex_delim(const char *cmdstr, char **match, char **replace) { const char *cmdstr_ptr = cmdstr; unsigned char delimiter; int idx = 0; /* verify that the 's' or 'y' is followed by something. That something * (typically a 'slash') is now our regexp delimiter... */ if (*cmdstr == '\0') bb_error_msg_and_die("bad format in substitution expression"); delimiter = *cmdstr_ptr++; /* save the match string */ idx = index_of_next_unescaped_regexp_delim(delimiter, cmdstr_ptr); *match = copy_parsing_escapes(cmdstr_ptr, idx); /* save the replacement string */ cmdstr_ptr += idx + 1; idx = index_of_next_unescaped_regexp_delim(- (int)delimiter, cmdstr_ptr); *replace = copy_parsing_escapes(cmdstr_ptr, idx); return ((cmdstr_ptr - cmdstr) + idx); }
/* * returns the index in the string just past where the address ends. */ static int get_address(struct sed_cmd *sed_cmd, const char *str, int *linenum, regex_t **regex) { char *my_str = strdup(str); int idx = 0; char olddelimiter; olddelimiter = sed_cmd->delimiter; sed_cmd->delimiter = '/'; if (isdigit(my_str[idx])) { do { idx++; } while (isdigit(my_str[idx])); my_str[idx] = 0; *linenum = atoi(my_str); } else if (my_str[idx] == '$') { *linenum = -1; idx++; } else if (my_str[idx] == '/') { idx = index_of_next_unescaped_regexp_delim(sed_cmd, my_str, ++idx); if (idx == -1) error_msg_and_die("unterminated match expression"); my_str[idx] = '\0'; *regex = (regex_t *)xmalloc(sizeof(regex_t)); xregcomp(*regex, my_str+1, REG_NEWLINE); idx++; /* so it points to the next character after the last '/' */ } else { error_msg("get_address: no address found in string\n" "\t(you probably didn't check the string you passed me)"); idx = -1; } free(my_str); sed_cmd->delimiter = olddelimiter; return idx; }
static int parse_subst_cmd(struct sed_cmd * const sed_cmd, const char *substr) { int oldidx, cflags = REG_NEWLINE; char *match; int idx = 0; int j; /* * the string that gets passed to this function should look like this: * s/match/replace/gIp * || | ||| * mandatory optional * * (all three of the '/' slashes are mandatory) */ /* verify that the 's' is followed by something. That something * (typically a 'slash') is now our regexp delimiter... */ if (!substr[++idx]) error_msg_and_die("bad format in substitution expression"); else sed_cmd->delimiter=substr[idx]; /* save the match string */ oldidx = idx+1; idx = index_of_next_unescaped_regexp_delim(sed_cmd, substr, ++idx); if (idx == -1) error_msg_and_die("bad format in substitution expression"); match = xstrndup(substr + oldidx, idx - oldidx); /* determine the number of back references in the match string */ /* Note: we compute this here rather than in the do_subst_command() * function to save processor time, at the expense of a little more memory * (4 bits) per sed_cmd */ /* sed_cmd->num_backrefs = 0; */ /* XXX: not needed? --apparently not */ for (j = 0; match[j]; j++) { /* GNU/POSIX sed does not save more than nine backrefs */ if (match[j] == '\\' && match[j+1] == '(' && sed_cmd->num_backrefs <= 9) sed_cmd->num_backrefs++; } /* save the replacement string */ oldidx = idx+1; idx = index_of_next_unescaped_regexp_delim(sed_cmd, substr, ++idx); if (idx == -1) error_msg_and_die("bad format in substitution expression"); sed_cmd->replace = xstrndup(substr + oldidx, idx - oldidx); /* process the flags */ while (substr[++idx]) { switch (substr[idx]) { case 'g': sed_cmd->sub_g = 1; break; case 'I': cflags |= REG_ICASE; break; case 'p': sed_cmd->sub_p = 1; break; default: /* any whitespace or semicolon trailing after a s/// is ok */ if (strchr("; \t\v\n\r", substr[idx])) goto out; /* else */ error_msg_and_die("bad option in substitution expression"); } } out: /* compile the match string into a regex */ sed_cmd->sub_match = (regex_t *)xmalloc(sizeof(regex_t)); xregcomp(sed_cmd->sub_match, match, cflags); free(match); return idx; }