From f8ea3f2ec14fcca38fac543cc4e9b519992d32bd Mon Sep 17 00:00:00 2001 From: Rob Landley Date: Sun, 28 May 2023 12:52:11 -0500 Subject: [PATCH] Fix if/while block return code (test value was leaking through), and fix while to call test each time through the loop (not just first time). --- tests/sh.test | 4 ++++ toys/pending/sh.c | 17 +++++++++++------ 2 files changed, 15 insertions(+), 6 deletions(-) diff --git a/tests/sh.test b/tests/sh.test index 4f4d4cb2..b36966d6 100644 --- a/tests/sh.test +++ b/tests/sh.test @@ -121,6 +121,10 @@ testing "eval0" "$SH -c 'eval echo \$*' one two three" "two three\n" "" "" # Change EVAL to call sh -c for us, using "bash" explicitly for the host. export EVAL="timeout 10 $SH -c" +testing 'test return code' 'if false; then echo true; fi; echo $?' '0\n' '' '' +testing 'test return code 2' 'if true; the false; fi; echo $?' '1\n' '' '' +testing 'test return code 3' 'x=0; while [ $((x++)) -lt 2 ]; do echo $x; done; echo $?' '1\n2\n0\n' '' '' + testing 'trailing $ is literal' 'echo $' '$\n' '' '' # TODO testing 'empty +() is literal' 'echo +()' '+()\n' '' '' diff --git a/toys/pending/sh.c b/toys/pending/sh.c index d97c2bbe..9272631b 100644 --- a/toys/pending/sh.c +++ b/toys/pending/sh.c @@ -3861,9 +3861,11 @@ static void run_lines(void) } // Handle if/else/elif statement - } else if (!strcmp(s, "then")) + } else if (!strcmp(s, "then")) { +do_then: TT.ff->blk->run = TT.ff->blk->run && !toys.exitval; - else if (!strcmp(s, "else") || !strcmp(s, "elif")) + toys.exitval = 0; + } else if (!strcmp(s, "else") || !strcmp(s, "elif")) TT.ff->blk->run = !TT.ff->blk->run; // Loop @@ -3871,9 +3873,11 @@ static void run_lines(void) struct sh_blockstack *blk = TT.ff->blk; ss = *blk->start->arg->v; - if (!strcmp(ss, "while")) blk->run = blk->run && !toys.exitval; - else if (!strcmp(ss, "until")) blk->run = blk->run && toys.exitval; - else if (!strcmp(ss, "select")) { + if (!strcmp(ss, "while")) goto do_then; + else if (!strcmp(ss, "until")) { + blk->run = blk->run && toys.exitval; + toys.exitval = 0; + } else if (!strcmp(ss, "select")) { if (!(ss = get_next_line(0, 3)) || ss==(void *)1) { TT.ff->pl = pop_block(); printf("\n"); @@ -3913,7 +3917,8 @@ static void run_lines(void) // repeating block? if (TT.ff->blk->run && !strcmp(s, "done")) { - TT.ff->pl = TT.ff->blk->middle; + TT.ff->pl = (**TT.ff->blk->start->arg->v == 'w') + ? TT.ff->blk->start->next : TT.ff->blk->middle; continue; } -- 2.39.2