changeset 808:c6eb6208c9b9

Sed's still just a stub, but clean it up enough so it at least compiles.
author Rob Landley <rob@landley.net>
date Sun, 24 Feb 2013 13:48:15 -0600
parents 5aa90a446d52
children f753e5192cbb
files toys/pending/sed.c
diffstat 1 files changed, 51 insertions(+), 44 deletions(-) [+]
line wrap: on
line diff
--- a/toys/pending/sed.c	Sun Feb 24 12:51:40 2013 -0600
+++ b/toys/pending/sed.c	Sun Feb 24 13:48:15 2013 -0600
@@ -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 @@
 #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 @@
   // 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 @@
 };
 
 //  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;
 
-  for (script = TT.scripts; *script; script = script->next) {
-    char *str = script->arg, *s;
+  // Loop through list of scripts collated from command line and/or files
+
+  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 @@
 
       // Identify prefix
       for (;;) {
-        long l;
+        spaceorb(&str);
+        if (*str == '^') {
+          if (cmd->lstart) goto parse_fail;
+          cmd->lstart = -1;
+          str++;
+          continue;
+        } else if (*str == '$') {
+          cmd->lstop = LONG_MAX;
+          str++;
+          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 (*str == '$') {
-          l = -1;
-          str++;
-        } else if (isdigit(*str)) l = strtol(str, &str, 10);
-        else if (!cmd->lstart) break;
-        else goto parse_fail;
+        if (*str != ',') break;
+        str++;
+      }
+      i = stridx("{bcdDgGhHlnNpPstwxyrqia= \t#:}", *str);
+      if (i == -1) 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;
-
-
+      dlist_add_nomalloc((struct double_list **)&TT.commands,
+                         (struct double_list *)cmd);
+      exit(1);
     }
   }
 
@@ -117,15 +129,10 @@
   // 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++));
 }