diff options
-rw-r--r-- | shell/ash.c | 56 | ||||
-rw-r--r-- | shell/ash_test/ash-misc/func6.right | 2 | ||||
-rwxr-xr-x | shell/ash_test/ash-misc/func6.tests | 11 |
3 files changed, 42 insertions, 27 deletions
diff --git a/shell/ash.c b/shell/ash.c index 06df07d..e4349cc 100644 --- a/shell/ash.c +++ b/shell/ash.c @@ -8632,37 +8632,50 @@ static #endif int evaltreenr(union node *, int) __attribute__ ((alias("evaltree"),__noreturn__)); +static int skiploop(void) +{ + int skip = evalskip; + + switch (skip) { + case 0: + break; + case SKIPBREAK: + case SKIPCONT: + if (--skipcount <= 0) { + evalskip = 0; + break; + } + skip = SKIPBREAK; + break; + } + return skip; +} + static int evalloop(union node *n, int flags) { + int skip; int status; loopnest++; status = 0; flags &= EV_TESTED; - for (;;) { + do { int i; i = evaltree(n->nbinary.ch1, EV_TESTED); - if (evalskip) { - skipping: - if (evalskip == SKIPCONT && --skipcount <= 0) { - evalskip = 0; - continue; - } - if (evalskip == SKIPBREAK && --skipcount <= 0) - evalskip = 0; - break; - } + skip = skiploop(); + if (skip == SKIPFUNC) + status = i; + if (skip) + continue; if (n->type != NWHILE) i = !i; if (i != 0) break; status = evaltree(n->nbinary.ch2, flags); - if (evalskip) - goto skipping; - } - exitstatus = status; + skip = skiploop(); + } while (!(skip & ~SKIPCONT)); loopnest--; return status; @@ -8682,9 +8695,6 @@ evalfor(union node *n, int flags) arglist.lastp = &arglist.list; for (argp = n->nfor.args; argp; argp = argp->narg.next) { expandarg(argp, &arglist, EXP_FULL | EXP_TILDE); - /* XXX */ - if (evalskip) - goto out; } *arglist.lastp = NULL; @@ -8693,18 +8703,10 @@ evalfor(union node *n, int flags) for (sp = arglist.list; sp; sp = sp->next) { setvar0(n->nfor.var, sp->text); status = evaltree(n->nfor.body, flags); - if (evalskip) { - if (evalskip == SKIPCONT && --skipcount <= 0) { - evalskip = 0; - continue; - } - if (evalskip == SKIPBREAK && --skipcount <= 0) - evalskip = 0; + if (skiploop() & ~SKIPCONT) break; - } } loopnest--; - out: popstackmark(&smark); return status; diff --git a/shell/ash_test/ash-misc/func6.right b/shell/ash_test/ash-misc/func6.right new file mode 100644 index 0000000..0ebd8e5 --- /dev/null +++ b/shell/ash_test/ash-misc/func6.right @@ -0,0 +1,2 @@ +Two:2 +Two:2 diff --git a/shell/ash_test/ash-misc/func6.tests b/shell/ash_test/ash-misc/func6.tests new file mode 100755 index 0000000..029c3e8 --- /dev/null +++ b/shell/ash_test/ash-misc/func6.tests @@ -0,0 +1,11 @@ +f1() { + while return 2; do :; done +} +f1 +echo Two:$? + +f2() { + while :; do return 2; done +} +f2 +echo Two:$? |