sh: Reduce one level of evaltree() recursion when executing 'case'.
Free expanded case text before executing commands. Remove impossible evalskip checks (expanding an argument cannot set evalskip anymore since $(break) and the like are properly executed in a subshell environment).
This commit is contained in:
parent
cdb7ebe38c
commit
a157dc4d90
@ -89,7 +89,7 @@ int oexitstatus; /* saved exit status */
|
|||||||
|
|
||||||
static void evalloop(union node *, int);
|
static void evalloop(union node *, int);
|
||||||
static void evalfor(union node *, int);
|
static void evalfor(union node *, int);
|
||||||
static void evalcase(union node *, int);
|
static union node *evalcase(union node *, int);
|
||||||
static void evalsubshell(union node *, int);
|
static void evalsubshell(union node *, int);
|
||||||
static void evalredir(union node *, int);
|
static void evalredir(union node *, int);
|
||||||
static void expredir(union node *);
|
static void expredir(union node *);
|
||||||
@ -256,7 +256,7 @@ evaltree(union node *n, int flags)
|
|||||||
evalfor(n, flags & ~EV_EXIT);
|
evalfor(n, flags & ~EV_EXIT);
|
||||||
break;
|
break;
|
||||||
case NCASE:
|
case NCASE:
|
||||||
evalcase(n, flags);
|
next = evalcase(n, flags);
|
||||||
break;
|
break;
|
||||||
case NDEFUN:
|
case NDEFUN:
|
||||||
defun(n->narg.text, n->narg.next);
|
defun(n->narg.text, n->narg.next);
|
||||||
@ -370,7 +370,7 @@ out:
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
static void
|
static union node *
|
||||||
evalcase(union node *n, int flags)
|
evalcase(union node *n, int flags)
|
||||||
{
|
{
|
||||||
union node *cp;
|
union node *cp;
|
||||||
@ -383,26 +383,24 @@ evalcase(union node *n, int flags)
|
|||||||
oexitstatus = exitstatus;
|
oexitstatus = exitstatus;
|
||||||
exitstatus = 0;
|
exitstatus = 0;
|
||||||
expandarg(n->ncase.expr, &arglist, EXP_TILDE);
|
expandarg(n->ncase.expr, &arglist, EXP_TILDE);
|
||||||
for (cp = n->ncase.cases ; cp && evalskip == 0 ; cp = cp->nclist.next) {
|
for (cp = n->ncase.cases ; cp ; cp = cp->nclist.next) {
|
||||||
for (patp = cp->nclist.pattern ; patp ; patp = patp->narg.next) {
|
for (patp = cp->nclist.pattern ; patp ; patp = patp->narg.next) {
|
||||||
if (casematch(patp, arglist.list->text)) {
|
if (casematch(patp, arglist.list->text)) {
|
||||||
|
popstackmark(&smark);
|
||||||
while (cp->nclist.next &&
|
while (cp->nclist.next &&
|
||||||
cp->type == NCLISTFALLTHRU) {
|
cp->type == NCLISTFALLTHRU) {
|
||||||
if (evalskip != 0)
|
|
||||||
break;
|
|
||||||
evaltree(cp->nclist.body,
|
evaltree(cp->nclist.body,
|
||||||
flags & ~EV_EXIT);
|
flags & ~EV_EXIT);
|
||||||
|
if (evalskip != 0)
|
||||||
|
return (NULL);
|
||||||
cp = cp->nclist.next;
|
cp = cp->nclist.next;
|
||||||
}
|
}
|
||||||
if (evalskip == 0) {
|
return (cp->nclist.body);
|
||||||
evaltree(cp->nclist.body, flags);
|
|
||||||
}
|
|
||||||
goto out;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
out:
|
|
||||||
popstackmark(&smark);
|
popstackmark(&smark);
|
||||||
|
return (NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user