Minor code reorg: Changed the interface to index_of_next_unescaped_slash to an

interface that seems a little more sensible to me. Also broke out s///
expression parsing into it's own subroutine.
This commit is contained in:
Mark Whitley 2000-07-13 19:58:04 +00:00
parent 156959ea93
commit 06f3529ada
2 changed files with 116 additions and 96 deletions

View File

@ -162,7 +162,7 @@ static char *trim_str(const char *str)
* index_of_unescaped_slash - walks left to right through a string beginning * index_of_unescaped_slash - walks left to right through a string beginning
* at a specified index and returns the index of the next unescaped slash. * at a specified index and returns the index of the next unescaped slash.
*/ */
static int index_of_next_unescaped_slash(int idx, const char *str) static int index_of_next_unescaped_slash(const char *str, int idx)
{ {
do { do {
idx++; idx++;
@ -196,7 +196,7 @@ static int get_address(const char *str, int *line, regex_t **regex)
idx++; idx++;
} }
else if (my_str[idx] == '/') { else if (my_str[idx] == '/') {
idx = index_of_next_unescaped_slash(idx, my_str); idx = index_of_next_unescaped_slash(my_str, idx);
if (idx == -1) if (idx == -1)
fatalError("unterminated match expression\n"); fatalError("unterminated match expression\n");
my_str[idx] = '\0'; my_str[idx] = '\0';
@ -222,6 +222,59 @@ static char *strdup_substr(const char *str, int start, int end)
return newstr; return newstr;
} }
static void parse_subst_cmd(struct sed_cmd *sed_cmd, const char *substr)
{
int oldidx, cflags = REG_NEWLINE;
char *match;
int idx = 0;
/*
* the string that gets passed to this function should look like this:
* s/match/replace/gI
* || | ||
* mandatory optional
*
* (all three of the '/' slashes are mandatory)
*/
/* verify that the 's' is followed by a 'slash' */
if (substr[++idx] != '/')
fatalError("bad format in substitution expression\n");
/* save the match string */
oldidx = idx+1;
idx = index_of_next_unescaped_slash(substr, idx);
if (idx == -1)
fatalError("bad format in substitution expression\n");
match = strdup_substr(substr, oldidx, idx);
/* save the replacement string */
oldidx = idx+1;
idx = index_of_next_unescaped_slash(substr, idx);
if (idx == -1)
fatalError("bad format in substitution expression\n");
sed_cmd->replace = strdup_substr(substr, oldidx, idx);
/* process the flags */
while (substr[++idx]) {
switch (substr[idx]) {
case 'g':
sed_cmd->sub_g = 1;
break;
case 'I':
cflags |= REG_ICASE;
break;
default:
fatalError("bad option in substitution expression\n");
}
}
/* compile the regex */
sed_cmd->sub_match = (regex_t *)xmalloc(sizeof(regex_t));
xregcomp(sed_cmd->sub_match, match, cflags);
free(match);
}
static void parse_cmd_str(struct sed_cmd *sed_cmd, const char *cmdstr) static void parse_cmd_str(struct sed_cmd *sed_cmd, const char *cmdstr)
{ {
int idx = 0; int idx = 0;
@ -246,53 +299,10 @@ static void parse_cmd_str(struct sed_cmd *sed_cmd, const char *cmdstr)
if (!strchr("pds", cmdstr[idx])) /* <-- XXX add new commands here */ if (!strchr("pds", cmdstr[idx])) /* <-- XXX add new commands here */
fatalError("invalid command\n"); fatalError("invalid command\n");
sed_cmd->cmd = cmdstr[idx]; sed_cmd->cmd = cmdstr[idx];
/* special-case handling for 's' */
if (sed_cmd->cmd == 's') {
int oldidx, cflags = REG_NEWLINE;
char *match;
/* format for substitution is:
* s/match/replace/gI
* | ||
* mandatory optional
*/
/* verify that we have an 's' followed by a 'slash' */ /* special-case handling for (s)ubstitution */
if (cmdstr[++idx] != '/') if (sed_cmd->cmd == 's')
fatalError("bad format in substitution expression\n"); parse_subst_cmd(sed_cmd, &cmdstr[idx]);
/* save the match string */
oldidx = idx+1;
idx = index_of_next_unescaped_slash(idx, cmdstr);
if (idx == -1)
fatalError("bad format in substitution expression\n");
match = strdup_substr(cmdstr, oldidx, idx);
/* save the replacement string */
oldidx = idx+1;
idx = index_of_next_unescaped_slash(idx, cmdstr);
if (idx == -1)
fatalError("bad format in substitution expression\n");
sed_cmd->replace = strdup_substr(cmdstr, oldidx, idx);
/* process the flags */
while (cmdstr[++idx]) {
switch (cmdstr[idx]) {
case 'g':
sed_cmd->sub_g = 1;
break;
case 'I':
cflags |= REG_ICASE;
break;
default:
fatalError("bad option in substitution expression\n");
}
}
/* compile the regex */
sed_cmd->sub_match = (regex_t *)xmalloc(sizeof(regex_t));
xregcomp(sed_cmd->sub_match, match, cflags);
free(match);
}
} }
static void add_cmd_str(const char *cmdstr) static void add_cmd_str(const char *cmdstr)

106
sed.c
View File

@ -162,7 +162,7 @@ static char *trim_str(const char *str)
* index_of_unescaped_slash - walks left to right through a string beginning * index_of_unescaped_slash - walks left to right through a string beginning
* at a specified index and returns the index of the next unescaped slash. * at a specified index and returns the index of the next unescaped slash.
*/ */
static int index_of_next_unescaped_slash(int idx, const char *str) static int index_of_next_unescaped_slash(const char *str, int idx)
{ {
do { do {
idx++; idx++;
@ -196,7 +196,7 @@ static int get_address(const char *str, int *line, regex_t **regex)
idx++; idx++;
} }
else if (my_str[idx] == '/') { else if (my_str[idx] == '/') {
idx = index_of_next_unescaped_slash(idx, my_str); idx = index_of_next_unescaped_slash(my_str, idx);
if (idx == -1) if (idx == -1)
fatalError("unterminated match expression\n"); fatalError("unterminated match expression\n");
my_str[idx] = '\0'; my_str[idx] = '\0';
@ -222,6 +222,59 @@ static char *strdup_substr(const char *str, int start, int end)
return newstr; return newstr;
} }
static void parse_subst_cmd(struct sed_cmd *sed_cmd, const char *substr)
{
int oldidx, cflags = REG_NEWLINE;
char *match;
int idx = 0;
/*
* the string that gets passed to this function should look like this:
* s/match/replace/gI
* || | ||
* mandatory optional
*
* (all three of the '/' slashes are mandatory)
*/
/* verify that the 's' is followed by a 'slash' */
if (substr[++idx] != '/')
fatalError("bad format in substitution expression\n");
/* save the match string */
oldidx = idx+1;
idx = index_of_next_unescaped_slash(substr, idx);
if (idx == -1)
fatalError("bad format in substitution expression\n");
match = strdup_substr(substr, oldidx, idx);
/* save the replacement string */
oldidx = idx+1;
idx = index_of_next_unescaped_slash(substr, idx);
if (idx == -1)
fatalError("bad format in substitution expression\n");
sed_cmd->replace = strdup_substr(substr, oldidx, idx);
/* process the flags */
while (substr[++idx]) {
switch (substr[idx]) {
case 'g':
sed_cmd->sub_g = 1;
break;
case 'I':
cflags |= REG_ICASE;
break;
default:
fatalError("bad option in substitution expression\n");
}
}
/* compile the regex */
sed_cmd->sub_match = (regex_t *)xmalloc(sizeof(regex_t));
xregcomp(sed_cmd->sub_match, match, cflags);
free(match);
}
static void parse_cmd_str(struct sed_cmd *sed_cmd, const char *cmdstr) static void parse_cmd_str(struct sed_cmd *sed_cmd, const char *cmdstr)
{ {
int idx = 0; int idx = 0;
@ -246,53 +299,10 @@ static void parse_cmd_str(struct sed_cmd *sed_cmd, const char *cmdstr)
if (!strchr("pds", cmdstr[idx])) /* <-- XXX add new commands here */ if (!strchr("pds", cmdstr[idx])) /* <-- XXX add new commands here */
fatalError("invalid command\n"); fatalError("invalid command\n");
sed_cmd->cmd = cmdstr[idx]; sed_cmd->cmd = cmdstr[idx];
/* special-case handling for 's' */
if (sed_cmd->cmd == 's') {
int oldidx, cflags = REG_NEWLINE;
char *match;
/* format for substitution is:
* s/match/replace/gI
* | ||
* mandatory optional
*/
/* verify that we have an 's' followed by a 'slash' */ /* special-case handling for (s)ubstitution */
if (cmdstr[++idx] != '/') if (sed_cmd->cmd == 's')
fatalError("bad format in substitution expression\n"); parse_subst_cmd(sed_cmd, &cmdstr[idx]);
/* save the match string */
oldidx = idx+1;
idx = index_of_next_unescaped_slash(idx, cmdstr);
if (idx == -1)
fatalError("bad format in substitution expression\n");
match = strdup_substr(cmdstr, oldidx, idx);
/* save the replacement string */
oldidx = idx+1;
idx = index_of_next_unescaped_slash(idx, cmdstr);
if (idx == -1)
fatalError("bad format in substitution expression\n");
sed_cmd->replace = strdup_substr(cmdstr, oldidx, idx);
/* process the flags */
while (cmdstr[++idx]) {
switch (cmdstr[idx]) {
case 'g':
sed_cmd->sub_g = 1;
break;
case 'I':
cflags |= REG_ICASE;
break;
default:
fatalError("bad option in substitution expression\n");
}
}
/* compile the regex */
sed_cmd->sub_match = (regex_t *)xmalloc(sizeof(regex_t));
xregcomp(sed_cmd->sub_match, match, cflags);
free(match);
}
} }
static void add_cmd_str(const char *cmdstr) static void add_cmd_str(const char *cmdstr)