ash,hush: handle a few more bkslash-newline cases
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
diff --git a/shell/ash.c b/shell/ash.c
index a7767b4..454bc33 100644
--- a/shell/ash.c
+++ b/shell/ash.c
@@ -12649,7 +12649,7 @@
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
index 0000000..97ea0c1
--- /dev/null
+++ b/shell/ash_test/ash-parsing/bkslash_newline1.right
@@ -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
index 0000000..6e374c4
--- /dev/null
+++ b/shell/ash_test/ash-parsing/bkslash_newline1.tests
@@ -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
index 0000000..c863c54
--- /dev/null
+++ b/shell/ash_test/ash-parsing/bkslash_newline2.right
@@ -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
index 0000000..47d6304
--- /dev/null
+++ b/shell/ash_test/ash-parsing/bkslash_newline2.tests
@@ -0,0 +1,4 @@
+echo Line with one backslash:
+echo '\
+'
+echo Ok:$?
diff --git a/shell/hush.c b/shell/hush.c
index 533d45a..4b8641d 100644
--- a/shell/hush.c
+++ b/shell/hush.c
@@ -4980,8 +4980,14 @@
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 @@
/* 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 @@
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 @@
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
index 0000000..97ea0c1
--- /dev/null
+++ b/shell/hush_test/hush-parsing/bkslash_newline1.right
@@ -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
index 0000000..6e374c4
--- /dev/null
+++ b/shell/hush_test/hush-parsing/bkslash_newline1.tests
@@ -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
index 0000000..c863c54
--- /dev/null
+++ b/shell/hush_test/hush-parsing/bkslash_newline2.right
@@ -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
index 0000000..47d6304
--- /dev/null
+++ b/shell/hush_test/hush-parsing/bkslash_newline2.tests
@@ -0,0 +1,4 @@
+echo Line with one backslash:
+echo '\
+'
+echo Ok:$?