ash,hush: handle a few more bkslash-newline cases
authorDenys Vlasenko <vda.linux@googlemail.com>
Sun, 1 Apr 2018 01:04:55 +0000 (03:04 +0200)
committerDenys Vlasenko <vda.linux@googlemail.com>
Sun, 1 Apr 2018 01:04:55 +0000 (03:04 +0200)
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
shell/ash.c
shell/ash_test/ash-parsing/bkslash_newline1.right [new file with mode: 0644]
shell/ash_test/ash-parsing/bkslash_newline1.tests [new file with mode: 0755]
shell/ash_test/ash-parsing/bkslash_newline2.right [new file with mode: 0644]
shell/ash_test/ash-parsing/bkslash_newline2.tests [new file with mode: 0755]
shell/hush.c
shell/hush_test/hush-parsing/bkslash_newline1.right [new file with mode: 0644]
shell/hush_test/hush-parsing/bkslash_newline1.tests [new file with mode: 0755]
shell/hush_test/hush-parsing/bkslash_newline2.right [new file with mode: 0644]
shell/hush_test/hush-parsing/bkslash_newline2.tests [new file with mode: 0755]

index a7767b4f84424640701c44149f40fcf718005d9f..454bc3317415731c5692fa09d992d37b815eb91b 100644 (file)
@@ -12649,7 +12649,7 @@ xxreadtoken(void)
                                        break; /* return readtoken1(...) */
 
                                if ((int)(p - xxreadtoken_chars) >= xxreadtoken_singles) {
-                                       int cc = pgetc();
+                                       int cc = pgetc_eatbnl();
                                        if (cc == c) {    /* double occurrence? */
                                                p += xxreadtoken_doubles + 1;
                                        } else {
diff --git a/shell/ash_test/ash-parsing/bkslash_newline1.right b/shell/ash_test/ash-parsing/bkslash_newline1.right
new file mode 100644 (file)
index 0000000..97ea0c1
--- /dev/null
@@ -0,0 +1,4 @@
+and1
+and2
+or1
+ok
diff --git a/shell/ash_test/ash-parsing/bkslash_newline1.tests b/shell/ash_test/ash-parsing/bkslash_newline1.tests
new file mode 100755 (executable)
index 0000000..6e374c4
--- /dev/null
@@ -0,0 +1,8 @@
+echo and1 &\
+& echo and2
+
+echo or1 |\
+| echo NOT SHOWN
+
+case w in a) echo SKIP;\
+; w) echo ok;; esac;
diff --git a/shell/ash_test/ash-parsing/bkslash_newline2.right b/shell/ash_test/ash-parsing/bkslash_newline2.right
new file mode 100644 (file)
index 0000000..c863c54
--- /dev/null
@@ -0,0 +1,4 @@
+Line with one backslash:
+\
+
+Ok:0
diff --git a/shell/ash_test/ash-parsing/bkslash_newline2.tests b/shell/ash_test/ash-parsing/bkslash_newline2.tests
new file mode 100755 (executable)
index 0000000..47d6304
--- /dev/null
@@ -0,0 +1,4 @@
+echo Line with one backslash:
+echo '\
+'
+echo Ok:$?
index 533d45ac33686dc7d56241af476f326c01421c94..4b8641d198917e4aa3c9268f88420ba684725887 100644 (file)
@@ -4980,8 +4980,14 @@ static struct pipe *parse_stream(char **pstring,
                nommu_addchr(&ctx.as_string, ch);
 
                next = '\0';
-               if (ch != '\n')
+               if (ch != '\n') {
                        next = i_peek(input);
+                       /* Can't use i_peek_and_eat_bkslash_nl(input) here:
+                        *  echo '\
+                        *  '
+                        * will break.
+                        */
+               }
 
                is_special = "{}<>;&|()#'" /* special outside of "str" */
                                "\\$\"" IF_HUSH_TICK("`") /* always special */
@@ -5375,7 +5381,7 @@ static struct pipe *parse_stream(char **pstring,
                        /* Eat multiple semicolons, detect
                         * whether it means something special */
                        while (1) {
-                               ch = i_peek(input);
+                               ch = i_peek_and_eat_bkslash_nl(input);
                                if (ch != ';')
                                        break;
                                ch = i_getch(input);
@@ -5397,6 +5403,8 @@ static struct pipe *parse_stream(char **pstring,
                        if (done_word(&dest, &ctx)) {
                                goto parse_error;
                        }
+                       if (next == '\\')
+                               next = i_peek_and_eat_bkslash_nl(input);
                        if (next == '&') {
                                ch = i_getch(input);
                                nommu_addchr(&ctx.as_string, ch);
@@ -5413,6 +5421,8 @@ static struct pipe *parse_stream(char **pstring,
                        if (ctx.ctx_res_w == RES_MATCH)
                                break; /* we are in case's "word | word)" */
 #endif
+                       if (next == '\\')
+                               next = i_peek_and_eat_bkslash_nl(input);
                        if (next == '|') { /* || */
                                ch = i_getch(input);
                                nommu_addchr(&ctx.as_string, ch);
diff --git a/shell/hush_test/hush-parsing/bkslash_newline1.right b/shell/hush_test/hush-parsing/bkslash_newline1.right
new file mode 100644 (file)
index 0000000..97ea0c1
--- /dev/null
@@ -0,0 +1,4 @@
+and1
+and2
+or1
+ok
diff --git a/shell/hush_test/hush-parsing/bkslash_newline1.tests b/shell/hush_test/hush-parsing/bkslash_newline1.tests
new file mode 100755 (executable)
index 0000000..6e374c4
--- /dev/null
@@ -0,0 +1,8 @@
+echo and1 &\
+& echo and2
+
+echo or1 |\
+| echo NOT SHOWN
+
+case w in a) echo SKIP;\
+; w) echo ok;; esac;
diff --git a/shell/hush_test/hush-parsing/bkslash_newline2.right b/shell/hush_test/hush-parsing/bkslash_newline2.right
new file mode 100644 (file)
index 0000000..c863c54
--- /dev/null
@@ -0,0 +1,4 @@
+Line with one backslash:
+\
+
+Ok:0
diff --git a/shell/hush_test/hush-parsing/bkslash_newline2.tests b/shell/hush_test/hush-parsing/bkslash_newline2.tests
new file mode 100755 (executable)
index 0000000..47d6304
--- /dev/null
@@ -0,0 +1,4 @@
+echo Line with one backslash:
+echo '\
+'
+echo Ok:$?