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 06df07d06..e4349ccad 100644 --- a/shell/ash.c +++ b/shell/ash.c | |||
@@ -8632,37 +8632,50 @@ static | |||
8632 | #endif | 8632 | #endif |
8633 | int evaltreenr(union node *, int) __attribute__ ((alias("evaltree"),__noreturn__)); | 8633 | int evaltreenr(union node *, int) __attribute__ ((alias("evaltree"),__noreturn__)); |
8634 | 8634 | ||
8635 | static int skiploop(void) | ||
8636 | { | ||
8637 | int skip = evalskip; | ||
8638 | |||
8639 | switch (skip) { | ||
8640 | case 0: | ||
8641 | break; | ||
8642 | case SKIPBREAK: | ||
8643 | case SKIPCONT: | ||
8644 | if (--skipcount <= 0) { | ||
8645 | evalskip = 0; | ||
8646 | break; | ||
8647 | } | ||
8648 | skip = SKIPBREAK; | ||
8649 | break; | ||
8650 | } | ||
8651 | return skip; | ||
8652 | } | ||
8653 | |||
8635 | static int | 8654 | static int |
8636 | evalloop(union node *n, int flags) | 8655 | evalloop(union node *n, int flags) |
8637 | { | 8656 | { |
8657 | int skip; | ||
8638 | int status; | 8658 | int status; |
8639 | 8659 | ||
8640 | loopnest++; | 8660 | loopnest++; |
8641 | status = 0; | 8661 | status = 0; |
8642 | flags &= EV_TESTED; | 8662 | flags &= EV_TESTED; |
8643 | for (;;) { | 8663 | do { |
8644 | int i; | 8664 | int i; |
8645 | 8665 | ||
8646 | i = evaltree(n->nbinary.ch1, EV_TESTED); | 8666 | i = evaltree(n->nbinary.ch1, EV_TESTED); |
8647 | if (evalskip) { | 8667 | skip = skiploop(); |
8648 | skipping: | 8668 | if (skip == SKIPFUNC) |
8649 | if (evalskip == SKIPCONT && --skipcount <= 0) { | 8669 | status = i; |
8650 | evalskip = 0; | 8670 | if (skip) |
8651 | continue; | 8671 | continue; |
8652 | } | ||
8653 | if (evalskip == SKIPBREAK && --skipcount <= 0) | ||
8654 | evalskip = 0; | ||
8655 | break; | ||
8656 | } | ||
8657 | if (n->type != NWHILE) | 8672 | if (n->type != NWHILE) |
8658 | i = !i; | 8673 | i = !i; |
8659 | if (i != 0) | 8674 | if (i != 0) |
8660 | break; | 8675 | break; |
8661 | status = evaltree(n->nbinary.ch2, flags); | 8676 | status = evaltree(n->nbinary.ch2, flags); |
8662 | if (evalskip) | 8677 | skip = skiploop(); |
8663 | goto skipping; | 8678 | } while (!(skip & ~SKIPCONT)); |
8664 | } | ||
8665 | exitstatus = status; | ||
8666 | loopnest--; | 8679 | loopnest--; |
8667 | 8680 | ||
8668 | return status; | 8681 | return status; |
@@ -8682,9 +8695,6 @@ evalfor(union node *n, int flags) | |||
8682 | arglist.lastp = &arglist.list; | 8695 | arglist.lastp = &arglist.list; |
8683 | for (argp = n->nfor.args; argp; argp = argp->narg.next) { | 8696 | for (argp = n->nfor.args; argp; argp = argp->narg.next) { |
8684 | expandarg(argp, &arglist, EXP_FULL | EXP_TILDE); | 8697 | expandarg(argp, &arglist, EXP_FULL | EXP_TILDE); |
8685 | /* XXX */ | ||
8686 | if (evalskip) | ||
8687 | goto out; | ||
8688 | } | 8698 | } |
8689 | *arglist.lastp = NULL; | 8699 | *arglist.lastp = NULL; |
8690 | 8700 | ||
@@ -8693,18 +8703,10 @@ evalfor(union node *n, int flags) | |||
8693 | for (sp = arglist.list; sp; sp = sp->next) { | 8703 | for (sp = arglist.list; sp; sp = sp->next) { |
8694 | setvar0(n->nfor.var, sp->text); | 8704 | setvar0(n->nfor.var, sp->text); |
8695 | status = evaltree(n->nfor.body, flags); | 8705 | status = evaltree(n->nfor.body, flags); |
8696 | if (evalskip) { | 8706 | if (skiploop() & ~SKIPCONT) |
8697 | if (evalskip == SKIPCONT && --skipcount <= 0) { | ||
8698 | evalskip = 0; | ||
8699 | continue; | ||
8700 | } | ||
8701 | if (evalskip == SKIPBREAK && --skipcount <= 0) | ||
8702 | evalskip = 0; | ||
8703 | break; | 8707 | break; |
8704 | } | ||
8705 | } | 8708 | } |
8706 | loopnest--; | 8709 | loopnest--; |
8707 | out: | ||
8708 | popstackmark(&smark); | 8710 | popstackmark(&smark); |
8709 | 8711 | ||
8710 | return status; | 8712 | 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 000000000..0ebd8e5a3 --- /dev/null +++ b/shell/ash_test/ash-misc/func6.right | |||
@@ -0,0 +1,2 @@ | |||
1 | Two:2 | ||
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 000000000..029c3e85e --- /dev/null +++ b/shell/ash_test/ash-misc/func6.tests | |||
@@ -0,0 +1,11 @@ | |||
1 | f1() { | ||
2 | while return 2; do :; done | ||
3 | } | ||
4 | f1 | ||
5 | echo Two:$? | ||
6 | |||
7 | f2() { | ||
8 | while :; do return 2; done | ||
9 | } | ||
10 | f2 | ||
11 | echo Two:$? | ||