From 7aa651a6a4496d848f86de9b1e6b3a003256a01f Mon Sep 17 00:00:00 2001 From: Rob Landley Date: Tue, 13 Nov 2012 17:14:08 -0600 Subject: Reindent to two spaces per level. Remove vi: directives that haven't worked right in years (ubuntu broke its' vim implementation). Remove trailing spaces. Add/remove blank lines. Re-wordwrap in places. Update documentation with new coding style. The actual code should be the same afterward, this is just cosmetic refactoring. --- toys/posix/sed.c | 133 ++++++++++++++++++++++++++++++++++++++++++------------- 1 file changed, 101 insertions(+), 32 deletions(-) (limited to 'toys/posix/sed.c') diff --git a/toys/posix/sed.c b/toys/posix/sed.c index a3ba9e38..15099cc6 100644 --- a/toys/posix/sed.c +++ b/toys/posix/sed.c @@ -1,21 +1,24 @@ -/* vi: set sw=4 ts=4: +/* sed.c - Stream editor. * - * sed.c - Stream editor. - * - * Copyright 2008 Rob Landley + * Copyright 2012 Rob Landley * * See http://opengroup.org/onlinepubs/9699919799/utilities/sed.c USE_SED(NEWTOY(sed, "irne*", TOYFLAG_BIN)) config SED - bool "sed" - default n - help - usage: sed [-irn] {command | [-e command]...} [FILE...] + bool "sed" + default n + help + usage: sed [-irn] {command | [-e command]...} [FILE...] + + Stream EDitor, transforms text by appling script of command to each line + of input. - Stream EDitor, transforms text by appling commands to each line - of input. + -e Add expression to the command script (if no -e, use first argument) + -i Modify file in place + -n No default output (p commands only) + -r Use extended regular expression syntex */ #define FOR_sed @@ -23,40 +26,106 @@ config SED #include "lib/xregcomp.h" GLOBALS( - struct arg_list *commands; + struct arg_list *scripts; + struct double_list *commands; + + void *parsed; ) +// Digested version of what sed commands can actually tell use to do. + + struct sed_command { - // Doubly linked list of commands. - struct sed_command *next, *prev; + // double_list compatibility (easier to create in-order) + struct sed_command *next, *prev; - // Regexes for s/match/data/ and /match_begin/,/match_end/command - regex_t *match, *match_begin, *match_end; + // data string for (saicytb) + char c, *data; + // Regexes for s/match/data/ and /begin/,/end/command + regex_t *match, *begin, *end; + // 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 + int which, outfd; +}; - // For numeric ranges ala 10,20command - int first_line, last_line; +// Space. Space. Gotta get past space. Spaaaaaaaace! (But not newline.) +void spaceorb(char **s) +{ + while (**s == ' ' || **s == '\t') *s++; +} - // Which match to replace, 0 for all. - int which; +void parse_scripts(void) +{ + struct sed_command *commands = 0; + struct arg_list *script; + int which = 0; + long l; - // s and w commands can write to a file. Slight optimization: we use 0 - // instead of -1 to mean no file here, because even when there's no stdin - // our input file would take fd 0. - int outfd; + for (script = TT.scripts; *script; script = script->next) { + char *str = script->arg, *s; + struct sed_command *cmd; - // Data string for (saicytb) - char *data; + which++; + for (i=1;;) { + if (!*str) break; - // Which command letter is this? - char command; -}; + cmd = xzalloc(sizeof(struct sed_command)); + + // Identify prefix + for (;;) { + long l; + + spaceorb(&str); + if (*str == '$') { + l = -1; + str++; + } else if (isdigit(*str)) l = strtol(str, &str, 10); + else if (!cmd->lstart) break; + else goto parse_fail; + + 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"); + } + l = stridx("{bcdDgGhHlnNpPstwxyrqia= \t#:}", *str); + if (l == -1) goto parse_fail; + + + } + } + + return; + +parse_fail: + error_exit("bad expression %d@%d: %s", which, i, script->arg+i); +} void sed_main(void) { - struct arg_list *test; + char **files=toys.optargs; + + // If no -e, use first argument + if (!TT.scripts) { + if (!*files) error_exit("Need script"); + (TT.scripts=xzalloc(sizeof(struct arg_list)))->arg=*(files++); + } + - for (test = TT.commands; test; test = test->next) - dprintf(2,"command=%s\n",test->arg); + { + struct arg_list *test; - printf("Hello world\n"); + for (test = TT.commands; test; test = test->next) + dprintf(2,"command=%s\n",test->arg); + while (*files) dprintf(2,"file=%s\n", *(files++)); + } } -- cgit v1.2.3