# HG changeset patch # User Rob Landley # Date 1418255940 21600 # Node ID 2dcc165f6e210d4629dd0910f2a7a276b5b22084 # Parent ce22ad7a26c14e0b83c8513211e01838413655f4 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). diff -r ce22ad7a26c1 -r 2dcc165f6e21 toys/pending/sed.c --- 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)