From 6b6436c848035abfff92a86b00305847bc6c0b9d Mon Sep 17 00:00:00 2001 From: Rob Landley Date: Tue, 26 May 2020 05:23:58 -0500 Subject: Fix syntax checking for "if true; then echo hello | fi", fix some tests, slightly more elaborate debug output. --- scripts/test.sh | 2 +- tests/sh.test | 4 +++- toys/pending/sh.c | 10 ++++------ 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); -- cgit v1.2.3