redo get_addres(). save some space. possible fix a bug where the command might be set to 0 if no second address is given. dont parse sed_cmd struct to get_address, we only need the delim field.
This commit is contained in:
parent
2f8a401772
commit
1fb446795d
@ -148,7 +148,7 @@ static void destroy_cmd_strs(void)
|
|||||||
* expression delimiter (typically a forward * slash ('/')) not preceeded by
|
* expression delimiter (typically a forward * slash ('/')) not preceeded by
|
||||||
* a backslash ('\').
|
* a backslash ('\').
|
||||||
*/
|
*/
|
||||||
static int index_of_next_unescaped_regexp_delim(const struct sed_cmd * const sed_cmd, const char *str, int idx)
|
static int index_of_next_unescaped_regexp_delim(const char delimiter, const char *str, int idx)
|
||||||
{
|
{
|
||||||
int bracket = -1;
|
int bracket = -1;
|
||||||
int escaped = 0;
|
int escaped = 0;
|
||||||
@ -165,7 +165,7 @@ static int index_of_next_unescaped_regexp_delim(const struct sed_cmd * const sed
|
|||||||
escaped = 1;
|
escaped = 1;
|
||||||
else if (ch == '[')
|
else if (ch == '[')
|
||||||
bracket = idx;
|
bracket = idx;
|
||||||
else if (ch == sed_cmd->delimiter)
|
else if (ch == delimiter)
|
||||||
return idx;
|
return idx;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -176,46 +176,35 @@ static int index_of_next_unescaped_regexp_delim(const struct sed_cmd * const sed
|
|||||||
/*
|
/*
|
||||||
* returns the index in the string just past where the address ends.
|
* 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)
|
static int get_address(char *delimiter, char *my_str, int *linenum, regex_t **regex)
|
||||||
{
|
{
|
||||||
char *my_str = xstrdup(str);
|
int idx = 0;
|
||||||
int idx = 0, idx_start = 1;
|
|
||||||
char olddelimiter;
|
|
||||||
olddelimiter = sed_cmd->delimiter;
|
|
||||||
sed_cmd->delimiter = '/';
|
|
||||||
|
|
||||||
if (isdigit(my_str[idx])) {
|
if (isdigit(my_str[idx])) {
|
||||||
do {
|
char *endstr;
|
||||||
idx++;
|
*linenum = strtol(my_str, &endstr, 10);
|
||||||
} while (isdigit(my_str[idx]));
|
/* endstr shouldnt ever equal NULL */
|
||||||
my_str[idx] = 0;
|
idx = endstr - my_str;
|
||||||
*linenum = atoi(my_str);
|
|
||||||
}
|
}
|
||||||
else if (my_str[idx] == '$') {
|
else if (my_str[idx] == '$') {
|
||||||
*linenum = -1;
|
*linenum = -1;
|
||||||
idx++;
|
idx++;
|
||||||
}
|
}
|
||||||
else if (my_str[idx] == '/' || my_str[idx] == '\\') {
|
else if (my_str[idx] == '/' || my_str[idx] == '\\') {
|
||||||
|
int idx_start = 1;
|
||||||
|
|
||||||
if (my_str[idx] == '\\') {
|
if (my_str[idx] == '\\') {
|
||||||
idx_start++;
|
idx_start++;
|
||||||
sed_cmd-> delimiter = my_str[++idx];
|
*delimiter = my_str[++idx];
|
||||||
}
|
}
|
||||||
idx = index_of_next_unescaped_regexp_delim(sed_cmd, my_str, ++idx);
|
idx = index_of_next_unescaped_regexp_delim(*delimiter, my_str, ++idx);
|
||||||
if (idx == -1)
|
if (idx == -1) {
|
||||||
error_msg_and_die("unterminated match expression");
|
error_msg_and_die("unterminated match expression");
|
||||||
|
}
|
||||||
my_str[idx] = '\0';
|
my_str[idx] = '\0';
|
||||||
*regex = (regex_t *)xmalloc(sizeof(regex_t));
|
*regex = (regex_t *)xmalloc(sizeof(regex_t));
|
||||||
xregcomp(*regex, my_str+idx_start, REG_NEWLINE);
|
xregcomp(*regex, my_str+idx_start, REG_NEWLINE);
|
||||||
idx++; /* so it points to the next character after the last '/' */
|
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;
|
return idx;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -244,7 +233,7 @@ static int parse_subst_cmd(struct sed_cmd * const sed_cmd, const char *substr)
|
|||||||
|
|
||||||
/* save the match string */
|
/* save the match string */
|
||||||
oldidx = idx+1;
|
oldidx = idx+1;
|
||||||
idx = index_of_next_unescaped_regexp_delim(sed_cmd, substr, ++idx);
|
idx = index_of_next_unescaped_regexp_delim(sed_cmd->delimiter, substr, ++idx);
|
||||||
if (idx == -1)
|
if (idx == -1)
|
||||||
error_msg_and_die("bad format in substitution expression");
|
error_msg_and_die("bad format in substitution expression");
|
||||||
match = xstrndup(substr + oldidx, idx - oldidx);
|
match = xstrndup(substr + oldidx, idx - oldidx);
|
||||||
@ -263,7 +252,7 @@ static int parse_subst_cmd(struct sed_cmd * const sed_cmd, const char *substr)
|
|||||||
|
|
||||||
/* save the replacement string */
|
/* save the replacement string */
|
||||||
oldidx = idx+1;
|
oldidx = idx+1;
|
||||||
idx = index_of_next_unescaped_regexp_delim(sed_cmd, substr, ++idx);
|
idx = index_of_next_unescaped_regexp_delim(sed_cmd->delimiter, substr, ++idx);
|
||||||
if (idx == -1)
|
if (idx == -1)
|
||||||
error_msg_and_die("bad format in substitution expression");
|
error_msg_and_die("bad format in substitution expression");
|
||||||
sed_cmd->replace = xstrndup(substr + oldidx, idx - oldidx);
|
sed_cmd->replace = xstrndup(substr + oldidx, idx - oldidx);
|
||||||
@ -391,7 +380,7 @@ static int parse_file_cmd(struct sed_cmd *sed_cmd, const char *filecmdstr)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static char *parse_cmd_str(struct sed_cmd * const sed_cmd, const char *const cmdstr)
|
static char *parse_cmd_str(struct sed_cmd * const sed_cmd, char *cmdstr)
|
||||||
{
|
{
|
||||||
int idx = 0;
|
int idx = 0;
|
||||||
|
|
||||||
@ -402,13 +391,18 @@ static char *parse_cmd_str(struct sed_cmd * const sed_cmd, const char *const cmd
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
/* first part (if present) is an address: either a '$', a number or a /regex/ */
|
/* first part (if present) is an address: either a '$', a number or a /regex/ */
|
||||||
if ((cmdstr[idx] == '$') || (isdigit(cmdstr[idx])) || (cmdstr[idx] == '/') || ((cmdstr[idx] == '\\') && (cmdstr[idx+1] != '\\')))
|
idx = get_address(&sed_cmd->delimiter, cmdstr, &sed_cmd->beg_line, &sed_cmd->beg_match);
|
||||||
idx = get_address(sed_cmd, cmdstr, &sed_cmd->beg_line, &sed_cmd->beg_match);
|
|
||||||
|
|
||||||
/* second part (if present) will begin with a comma */
|
/* second part (if present) will begin with a comma */
|
||||||
if (cmdstr[idx] == ',') {
|
if (cmdstr[idx] == ',') {
|
||||||
|
int tmp_idx;
|
||||||
idx++;
|
idx++;
|
||||||
idx += get_address(sed_cmd, &cmdstr[idx], &sed_cmd->end_line, &sed_cmd->end_match);
|
tmp_idx = get_address(&sed_cmd->delimiter, &cmdstr[idx], &sed_cmd->end_line, &sed_cmd->end_match);
|
||||||
|
if (tmp_idx == 0) {
|
||||||
|
error_msg_and_die("get_address: no address found in string\n"
|
||||||
|
"\t(you probably didn't check the string you passed me)");
|
||||||
|
}
|
||||||
|
idx += tmp_idx;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* skip whitespace before the command */
|
/* skip whitespace before the command */
|
||||||
|
Loading…
x
Reference in New Issue
Block a user