From c09b79dc71d986213d37805131b89a135202263e Mon Sep 17 00:00:00 2001 From: Rob Landley Date: Sun, 21 Dec 2014 23:17:06 -0600 Subject: Another sed bug. (The e2fsprogs build uses multiple line continuations on the same command.) --- tests/sed.test | 2 ++ toys/posix/sed.c | 24 +++++++++++------------- 2 files changed, 13 insertions(+), 13 deletions(-) diff --git a/tests/sed.test b/tests/sed.test index 789a1a51..dfc76023 100644 --- a/tests/sed.test +++ b/tests/sed.test @@ -75,6 +75,8 @@ testing "sed c range" "sed '2,4c blah'" "one\nblah\nfive\nsix" "" \ testing "sed c {range}" "sed -e '2,4{c blah' -e '}'" \ "one\nblah\nblah\nblah\nfive\nsix" \ "" "one\ntwo\nthree\nfour\nfive\nsix" +testing "sed c multiple continuation" \ + "sed -e 'c\\' -e 'two\\' -e ''" "two\n\n" "" "hello" testing "sed D further processing depends on whether line is blank" \ "sed -e '/one/,/three/{' -e 'i meep' -e'N;2D;}'" \ "meep\nmeep\ntwo\nthree\n" "" "one\ntwo\nthree\n" diff --git a/toys/posix/sed.c b/toys/posix/sed.c index 7f070208..65a6fe0f 100644 --- a/toys/posix/sed.c +++ b/toys/posix/sed.c @@ -753,6 +753,7 @@ static void jewel_of_judgement(char **pline, long len) int i; // Append additional line to pattern argument string? + // We temporarily repurpose "hit" to indicate line continuations if (corwin && corwin->prev->hit) { // Remove half-finished entry from list so remalloc() doesn't confuse it TT.pattern = TT.pattern->prev; @@ -917,33 +918,30 @@ writenow: reg = extend_string((void *)&corwin, s, reg-(char*)corwin, len); free(s); } else if (strchr("abcirtTw:", c)) { - int end, class; + int end; // Trim whitespace from "b ;" and ": blah " but only first space in "w x " - while (isspace(*line)) { - if (!strchr("btT", c) || *line != '\n') line++; - else break; - } + while (isspace(*line) && *line != '\n') line++; append: - class = !strchr("btT:", c); - end = strcspn(line, class ? "\n" : "; \t\r\n\v\f"); - - if (!end) { - if (!strchr("btT", c)) break; - continue; + if (!(end = strcspn(line, strchr("btT:", c) ? "; \t\r\n\v\f" : "\n"))) { + if (strchr("btT", c)) continue; + else if (!corwin->arg1) break; } // Extend allocation to include new string. We use offsets instead of // pointers so realloc() moving stuff doesn't break things. Do it // here instead of toybuf so there's no maximum size. if (!corwin->arg1) corwin->arg1 = reg - (char*)corwin; - reg = extend_string((void *)&corwin, line, reg - (char *)corwin, end); + else if ((corwin+1) != (void *)reg) *(reg++) = '\n'; + reg = extend_string((void *)&corwin, line, reg - (char *)corwin, end); + line += end; // Line continuation? (Two slightly different input methods, -e with // embedded newline vs -f line by line. Must parse both correctly.) - if (class && line[-1] == '\\') { + if (!strchr("btT:", c) && line[-1] == '\\') { + // reg is next available space, so reg[-1] is the null terminator reg[-2] = 0; if (*line && line[1]) { reg -= 2; -- cgit v1.2.3