aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRob Landley <rob@landley.net>2014-12-21 23:17:06 -0600
committerRob Landley <rob@landley.net>2014-12-21 23:17:06 -0600
commitc09b79dc71d986213d37805131b89a135202263e (patch)
tree7ec6b682faaeef191606098fa5bd5bda8dd799f2
parent1a1e0a9d325dd1ca7461a8e8203dd47bab6a8bc1 (diff)
downloadtoybox-c09b79dc71d986213d37805131b89a135202263e.tar.gz
Another sed bug. (The e2fsprogs build uses multiple line continuations on the same command.)
-rw-r--r--tests/sed.test2
-rw-r--r--toys/posix/sed.c24
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;