aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRob Landley <rob@landley.net>2020-05-26 05:23:58 -0500
committerRob Landley <rob@landley.net>2020-05-26 05:23:58 -0500
commit6b6436c848035abfff92a86b00305847bc6c0b9d (patch)
tree2f41aad9c2410858e30fac21a9b10b03257573ce
parentbc6ce6628c2517aa419b5551b8d378da794b84f2 (diff)
downloadtoybox-6b6436c848035abfff92a86b00305847bc6c0b9d.tar.gz
Fix syntax checking for "if true; then echo hello | fi", fix some tests,
slightly more elaborate debug output.
-rwxr-xr-xscripts/test.sh2
-rw-r--r--tests/sh.test4
-rw-r--r--toys/pending/sh.c10
3 files changed, 8 insertions, 8 deletions
diff --git a/scripts/test.sh b/scripts/test.sh
index ede105ea..20f76d09 100755
--- a/scripts/test.sh
+++ b/scripts/test.sh
@@ -4,7 +4,7 @@ source scripts/runtest.sh
source scripts/portability.sh
TOPDIR="$PWD"
-FILES="$PWD"/tests/files
+export FILES="$PWD"/tests/files
trap 'kill $(jobs -p) 2>/dev/null; exit 1' INT
diff --git a/tests/sh.test b/tests/sh.test
index 7bab1a60..6e3944fb 100644
--- a/tests/sh.test
+++ b/tests/sh.test
@@ -41,7 +41,9 @@ testing "exec3" '$C -c "{ exec readlink /proc/self/fd/0;} < /proc/self/exe"' \
"$(readlink -f $C)\n" "" ""
testing 'arg shift' "$SH -c '"'for i in "" 2 1 1 1; do echo $? $1; shift $i; done'"' one two three four five" \
"0 two\n0 three\n0 five\n0\n1\n" "" ""
-testing '(subshell)' '$C -c "(echo hello)"' 'hello\n' '' ''
+testing '(subshell)' '$SH -c "(echo hello)"' 'hello\n' '' ''
+testing 'syntax' '$SH -c "if true; then echo hello | fi" 2>/dev/null || echo x'\
+ 'x\n' '' ''
# The bash man page is lying when it says $_ starts with an absolute path.
ln -s $(which $SH) bash
diff --git a/toys/pending/sh.c b/toys/pending/sh.c
index d868841d..55fdec5b 100644
--- a/toys/pending/sh.c
+++ b/toys/pending/sh.c
@@ -1731,7 +1731,7 @@ if (BUGBUG>1) dprintf(255, "{%d:%s}\n", pl->type, ex ? ex : (sp->expect ? "*" :
// Parse next word and detect overflow (too many nested quotes).
if ((end = parse_word(start, 0)) == (void *)1) goto flush;
-if (BUGBUG>1) dprintf(255, "[%.*s] ", end ? (int)(end-start) : 0, start);
+if (BUGBUG>1) dprintf(255, "[%.*s:%s] ", end ? (int)(end-start) : 0, start, ex ? : "");
// Is this a new pipeline segment?
if (!pl) {
pl = xzalloc(sizeof(struct sh_pipeline));
@@ -1891,11 +1891,9 @@ if (BUGBUG>1) dprintf(255, "[%.*s] ", end ? (int)(end-start) : 0, start);
// If we got here we expect a specific word to end this block: is this it?
else if (!strcmp(s, ex)) {
+
// can't "if | then" or "while && do", only ; & or newline works
- if (last && (strcmp(ex, "then") || strcmp(last, "&"))) {
- s = end;
- goto flush;
- }
+ if (last && strcmp(last, "&")) goto flush;
free(dlist_lpop(&sp->expect));
pl->type = anystr(s, tails) ? 3 : 2;
@@ -2617,7 +2615,7 @@ if (BUGBUG) dprintf(255, "line=%s\n", new);
// returns 0 if line consumed, command if it needs more data
prompt = parse_line(new, &scratch);
-if (BUGBUG) dump_state(&scratch);
+if (BUGBUG) dprintf(255, "prompt=%d\n", prompt), dump_state(&scratch);
if (prompt != 1) {
// TODO: ./blah.sh one two three: put one two three in scratch.arg
if (!prompt) run_function(scratch.pipeline);