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:
parent
156959ea93
commit
06f3529ada
106
editors/sed.c
106
editors/sed.c
@ -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
106
sed.c
@ -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)
|
||||||
|
Loading…
Reference in New Issue
Block a user