diff options
Diffstat (limited to 'shell/ash.c')
-rw-r--r-- | shell/ash.c | 56 |
1 files changed, 29 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; |