diff options
Diffstat (limited to 'toys/pending')
-rw-r--r-- | toys/pending/sed.c | 89 |
1 files changed, 48 insertions, 41 deletions
diff --git a/toys/pending/sed.c b/toys/pending/sed.c index 15099cc6..0ce25aca 100644 --- a/toys/pending/sed.c +++ b/toys/pending/sed.c @@ -4,7 +4,7 @@ * * See http://opengroup.org/onlinepubs/9699919799/utilities/sed.c -USE_SED(NEWTOY(sed, "irne*", TOYFLAG_BIN)) +USE_SED(NEWTOY(sed, "irne*f*", TOYFLAG_BIN)) config SED bool "sed" @@ -26,10 +26,10 @@ config SED #include "lib/xregcomp.h" GLOBALS( + struct arg_list *files; struct arg_list *scripts; - struct double_list *commands; - void *parsed; + void *commands; ) // Digested version of what sed commands can actually tell use to do. @@ -42,7 +42,7 @@ struct sed_command { // data string for (saicytb) char c, *data; // Regexes for s/match/data/ and /begin/,/end/command - regex_t *match, *begin, *end; + regex_t *rmatch, *rbegin, *rend; // For numeric ranges ala 10,20command long lstart, lstop; // Which match to replace, 0 for all. s and w commands can write to a file @@ -50,22 +50,26 @@ struct sed_command { }; // Space. Space. Gotta get past space. Spaaaaaaaace! (But not newline.) -void spaceorb(char **s) +static void spaceorb(char **s) { - while (**s == ' ' || **s == '\t') *s++; + while (**s == ' ' || **s == '\t') ++*s; } -void parse_scripts(void) +// Parse sed commands + +static void parse_scripts(void) { - struct sed_command *commands = 0; struct arg_list *script; - int which = 0; - long l; + int which = 0, i; + + // Loop through list of scripts collated from command line and/or files - for (script = TT.scripts; *script; script = script->next) { - char *str = script->arg, *s; + for (script = TT.scripts; script; script = script->next) { + char *str = script->arg; struct sed_command *cmd; + // we can get multiple commands from a string (semicolons and such) + which++; for (i=1;;) { if (!*str) break; @@ -74,33 +78,41 @@ void parse_scripts(void) // Identify prefix for (;;) { - long l; - spaceorb(&str); - if (*str == '$') { - l = -1; + if (*str == '^') { + if (cmd->lstart) goto parse_fail; + cmd->lstart = -1; + str++; + continue; + } else if (*str == '$') { + cmd->lstop = LONG_MAX; str++; - } else if (isdigit(*str)) l = strtol(str, &str, 10); - else if (!cmd->lstart) break; - else goto parse_fail; + break; + } else if (isdigit(*str)) { + long ll = strtol(str, &str, 10); + + if (ll<0) goto parse_fail; + if (cmd->lstart) { + cmd->lstop = ll; + break; + } else cmd->lstart = ll; + } else if (*str == '/' || *str == '\\') { + // set begin/end + printf("regex\n"); + exit(1); + } else if (!cmd->lstart && !cmd->rbegin) break; + else goto parse_fail; // , with no range after it spaceorb(&str); - if (!cmd->lstart) { - if (!l) goto parse_fail; - cmd->lstart = l; - if (*str != ',') break; - str++; - continue; - } - cmd->lstop = l; - break; - } else if (*str == '/') { - printf("regex\n"); + if (*str != ',') break; + str++; } - l = stridx("{bcdDgGhHlnNpPstwxyrqia= \t#:}", *str); - if (l == -1) goto parse_fail; - + i = stridx("{bcdDgGhHlnNpPstwxyrqia= \t#:}", *str); + if (i == -1) goto parse_fail; + dlist_add_nomalloc((struct double_list **)&TT.commands, + (struct double_list *)cmd); + exit(1); } } @@ -117,15 +129,10 @@ void sed_main(void) // If no -e, use first argument if (!TT.scripts) { if (!*files) error_exit("Need script"); - (TT.scripts=xzalloc(sizeof(struct arg_list)))->arg=*(files++); + (TT.scripts = xzalloc(sizeof(struct arg_list)))->arg = *(files++); } + parse_scripts(); - { - struct arg_list *test; - - for (test = TT.commands; test; test = test->next) - dprintf(2,"command=%s\n",test->arg); - while (*files) dprintf(2,"file=%s\n", *(files++)); - } + while (*files) dprintf(2,"file=%s\n", *(files++)); } |