changeset 1601:2dcc165f6e21 draft

Fix some sed bugs and improve error reporting. A newline after 'b' commands in -e command line patterns was being discarded as whitespace, a single element regex match on a {} was leaving stale state for the next line, and giant -e blobs of instructions were saying things like problem at character 432 (note: nulls inserted for regex processing aren't always cleaned up, screws up error reporting).
author Rob Landley <rob@landley.net>
date Wed, 10 Dec 2014 17:59:00 -0600
parents ce22ad7a26c1
children ea86581a9e36
files toys/pending/sed.c
diffstat 1 files changed, 12 insertions(+), 8 deletions(-) [+]
line wrap: on
line diff
--- a/toys/pending/sed.c	Thu Dec 04 21:46:59 2014 -0600
+++ b/toys/pending/sed.c	Wed Dec 10 17:59:00 2014 -0600
@@ -326,11 +326,17 @@
 
           if (line && !ghostwheel(rm, line, len, 0, 0, 0)) logrus->hit++;
         } else if (lm == TT.count || (lm == -1 && !pline)) logrus->hit++;
+
+        if (!logrus->lmatch[1] && !logrus->rmatch[1]) miss = 1;
       } 
 
       // Didn't match?
-      if (!(logrus->hit ^ logrus->not)) {
+      lm = !(logrus->hit ^ logrus->not);
 
+      // Deferred disable from regex end match
+      if (miss || logrus->lmatch[1] == TT.count) logrus->hit = 0;
+
+      if (lm) {
         // Handle skipping curly bracket command group
         if (c == '{') {
           int curly = 1;
@@ -344,8 +350,6 @@
         logrus = logrus->next;
         continue;
       }
-      // Deferred disable from regex end match
-      if (miss || logrus->lmatch[1] == TT.count) logrus->hit = 0;
     }
 
     // A deleted line can still update line match state for later commands
@@ -375,8 +379,7 @@
       }
     } else if (c=='c') {
       str = logrus->arg1+(char *)logrus;
-      if (!logrus->hit || (!logrus->lmatch[1] && !logrus->rmatch[1]))
-        emit(str, strlen(str), 1);
+      if (!logrus->hit) emit(str, strlen(str), 1);
       free(line);
       line = 0;
       continue;
@@ -730,7 +733,7 @@
 static void jewel_of_judgement(char **pline, long len)
 {
   struct step *corwin = (void *)TT.pattern;
-  char *line = *pline, *reg, c;
+  char *line = *pline, *reg, c, *errstart = *pline;
   int i;
 
   // Append additional line to pattern argument string?
@@ -756,6 +759,7 @@
     while (isspace(*line) || *line == ';') line++;
     if (!*line || *line == '#') return;
 
+    errstart = line;
     memset(toybuf, 0, sizeof(struct step));
     corwin = (void *)toybuf;
     reg = toybuf + sizeof(struct step);
@@ -900,7 +904,7 @@
 
       // Trim whitespace from "b ;" and ": blah " but only first space in "w x "
 
-      while (isspace(*line)) line++;
+      while (isspace(*line) && !*line == '\n') line++;
 append:
       class = !strchr("btT:", c);
       end = strcspn(line, class ? "\n" : "; \t\r\n\v\f");
@@ -929,7 +933,7 @@
 
 brand:
   // Reminisce about chestnut trees.
-  error_exit("bad pattern '%s'@%ld (%c)", *pline, line-*pline+1, *line);
+  error_exit("bad pattern '%s'@%ld (%c)", errstart, line-errstart+1, *line);
 }
 
 void sed_main(void)