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.
diff --git a/editors/sed.c b/editors/sed.c
index 21f8681..8ae34f8 100644
--- a/editors/sed.c
+++ b/editors/sed.c
@@ -162,7 +162,7 @@
* 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.
*/
-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 {
idx++;
@@ -196,7 +196,7 @@
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)
fatalError("unterminated match expression\n");
my_str[idx] = '\0';
@@ -222,6 +222,59 @@
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)
{
int idx = 0;
@@ -246,53 +299,10 @@
if (!strchr("pds", cmdstr[idx])) /* <-- XXX add new commands here */
fatalError("invalid command\n");
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' */
- if (cmdstr[++idx] != '/')
- fatalError("bad format in substitution expression\n");
-
- /* 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);
- }
+ /* special-case handling for (s)ubstitution */
+ if (sed_cmd->cmd == 's')
+ parse_subst_cmd(sed_cmd, &cmdstr[idx]);
}
static void add_cmd_str(const char *cmdstr)