void evaltree(union node *n, int flags) { int do_etest; union node *next; struct stackmark smark; setstackmark(&smark); do_etest = 0; if (n == NULL) { TRACE(("evaltree(NULL) called\n")); exitstatus = 0; goto out; } do { next = NULL; #ifndef NO_HISTORY displayhist = 1; /* show history substitutions done with fc */ #endif TRACE(("evaltree(%p: %d) called\n", (void *)n, n->type)); switch (n->type) { case NSEMI: evaltree(n->nbinary.ch1, flags & ~EV_EXIT); if (evalskip) goto out; next = n->nbinary.ch2; break; case NAND: evaltree(n->nbinary.ch1, EV_TESTED); if (evalskip || exitstatus != 0) { goto out; } next = n->nbinary.ch2; break; case NOR: evaltree(n->nbinary.ch1, EV_TESTED); if (evalskip || exitstatus == 0) goto out; next = n->nbinary.ch2; break; case NREDIR: evalredir(n, flags); break; case NSUBSHELL: evalsubshell(n, flags); do_etest = !(flags & EV_TESTED); break; case NBACKGND: evalsubshell(n, flags); break; case NIF: { evaltree(n->nif.test, EV_TESTED); if (evalskip) goto out; if (exitstatus == 0) next = n->nif.ifpart; else if (n->nif.elsepart) next = n->nif.elsepart; else exitstatus = 0; break; } case NWHILE: case NUNTIL: evalloop(n, flags & ~EV_EXIT); break; case NFOR: evalfor(n, flags & ~EV_EXIT); break; case NCASE: next = evalcase(n); break; case NCLIST: next = n->nclist.body; break; case NCLISTFALLTHRU: if (n->nclist.body) { evaltree(n->nclist.body, flags & ~EV_EXIT); if (evalskip) goto out; } next = n->nclist.next; break; case NDEFUN: defun(n->narg.text, n->narg.next); exitstatus = 0; break; case NNOT: evaltree(n->nnot.com, EV_TESTED); if (evalskip) goto out; exitstatus = !exitstatus; break; case NPIPE: evalpipe(n); do_etest = !(flags & EV_TESTED); break; case NCMD: evalcommand(n, flags, (struct backcmd *)NULL); do_etest = !(flags & EV_TESTED); break; default: out1fmt("Node type = %d\n", n->type); flushout(&output); break; } n = next; popstackmark(&smark); setstackmark(&smark); } while (n != NULL); out: popstackmark(&smark); if (pendingsig) dotrap(); if (eflag && exitstatus != 0 && do_etest) exitshell(exitstatus); if (flags & EV_EXIT) exraise(EXEXIT); }
void evaltree(shinstance *psh, union node *n, int flags) { if (n == NULL) { TRACE((psh, "evaltree(NULL) called\n")); psh->exitstatus = 0; goto out; } #ifndef SMALL psh->displayhist = 1; /* show history substitutions done with fc */ #endif TRACE((psh, "pid %d, evaltree(%p: %d, %d) called\n", sh_getpid(psh), n, n->type, flags)); switch (n->type) { case NSEMI: evaltree(psh, n->nbinary.ch1, flags & EV_TESTED); if (psh->evalskip) goto out; evaltree(psh, n->nbinary.ch2, flags); break; case NAND: evaltree(psh, n->nbinary.ch1, EV_TESTED); if (psh->evalskip || psh->exitstatus != 0) goto out; evaltree(psh, n->nbinary.ch2, flags); break; case NOR: evaltree(psh, n->nbinary.ch1, EV_TESTED); if (psh->evalskip || psh->exitstatus == 0) goto out; evaltree(psh, n->nbinary.ch2, flags); break; case NREDIR: expredir(psh, n->nredir.redirect); redirect(psh, n->nredir.redirect, REDIR_PUSH); evaltree(psh, n->nredir.n, flags); popredir(psh); break; case NSUBSHELL: evalsubshell(psh, n, flags); break; case NBACKGND: evalsubshell(psh, n, flags); break; case NIF: { evaltree(psh, n->nif.test, EV_TESTED); if (psh->evalskip) goto out; if (psh->exitstatus == 0) evaltree(psh, n->nif.ifpart, flags); else if (n->nif.elsepart) evaltree(psh, n->nif.elsepart, flags); else psh->exitstatus = 0; break; } case NWHILE: case NUNTIL: evalloop(psh, n, flags); break; case NFOR: evalfor(psh, n, flags); break; case NCASE: evalcase(psh, n, flags); break; case NDEFUN: defun(psh, n->narg.text, n->narg.next); psh->exitstatus = 0; break; case NNOT: evaltree(psh, n->nnot.com, EV_TESTED); psh->exitstatus = !psh->exitstatus; break; case NPIPE: evalpipe(psh, n); break; case NCMD: evalcommand(psh, n, flags, (struct backcmd *)NULL); break; default: out1fmt(psh, "Node type = %d\n", n->type); flushout(&psh->output); break; } out: if (psh->pendingsigs) dotrap(psh); if ((flags & EV_EXIT) != 0) exitshell(psh, psh->exitstatus); }
void evaltree(union node *n, int flags) { int do_etest; do_etest = 0; if (n == NULL) { TRACE(("evaltree(NULL) called\n")); exitstatus = 0; goto out; } #ifndef NO_HISTORY displayhist = 1; /* show history substitutions done with fc */ #endif TRACE(("evaltree(%p: %d) called\n", (void *)n, n->type)); switch (n->type) { case NSEMI: evaltree(n->nbinary.ch1, flags & ~EV_EXIT); if (evalskip) goto out; evaltree(n->nbinary.ch2, flags); break; case NAND: evaltree(n->nbinary.ch1, EV_TESTED); if (evalskip || exitstatus != 0) { goto out; } evaltree(n->nbinary.ch2, flags); break; case NOR: evaltree(n->nbinary.ch1, EV_TESTED); if (evalskip || exitstatus == 0) goto out; evaltree(n->nbinary.ch2, flags); break; case NREDIR: oexitstatus = exitstatus; expredir(n->nredir.redirect); redirect(n->nredir.redirect, REDIR_PUSH); evaltree(n->nredir.n, flags); popredir(); break; case NSUBSHELL: evalsubshell(n, flags); do_etest = !(flags & EV_TESTED); break; case NBACKGND: evalsubshell(n, flags); break; case NIF: { evaltree(n->nif.test, EV_TESTED); if (evalskip) goto out; if (exitstatus == 0) evaltree(n->nif.ifpart, flags); else if (n->nif.elsepart) evaltree(n->nif.elsepart, flags); else exitstatus = 0; break; } case NWHILE: case NUNTIL: evalloop(n, flags & ~EV_EXIT); break; case NFOR: evalfor(n, flags & ~EV_EXIT); break; case NCASE: evalcase(n, flags); break; case NDEFUN: defun(n->narg.text, n->narg.next); exitstatus = 0; break; case NNOT: evaltree(n->nnot.com, EV_TESTED); exitstatus = !exitstatus; break; case NPIPE: evalpipe(n); do_etest = !(flags & EV_TESTED); break; case NCMD: evalcommand(n, flags, (struct backcmd *)NULL); do_etest = !(flags & EV_TESTED); break; default: out1fmt("Node type = %d\n", n->type); flushout(&output); break; } out: if (pendingsigs) dotrap(); if ((flags & EV_EXIT) || (eflag && exitstatus != 0 && do_etest)) exitshell(exitstatus); }
void evaltree(union node *n, int flags) { bool do_etest; do_etest = false; if (n == NULL || nflag) { TRACE(("evaltree(%s) called\n", n == NULL ? "NULL" : "-n")); if (nflag == 0) exitstatus = 0; goto out; } #ifndef SMALL displayhist = 1; /* show history substitutions done with fc */ #endif #ifdef NODETYPENAME TRACE(("pid %d, evaltree(%p: %s(%d), %#x) called\n", getpid(), n, NODETYPENAME(n->type), n->type, flags)); #else TRACE(("pid %d, evaltree(%p: %d, %#x) called\n", getpid(), n, n->type, flags)); #endif switch (n->type) { case NSEMI: evaltree(n->nbinary.ch1, flags & EV_TESTED); if (nflag || evalskip) goto out; evaltree(n->nbinary.ch2, flags); break; case NAND: evaltree(n->nbinary.ch1, EV_TESTED); if (nflag || evalskip || exitstatus != 0) goto out; evaltree(n->nbinary.ch2, flags); break; case NOR: evaltree(n->nbinary.ch1, EV_TESTED); if (nflag || evalskip || exitstatus == 0) goto out; evaltree(n->nbinary.ch2, flags); break; case NREDIR: expredir(n->nredir.redirect); redirect(n->nredir.redirect, REDIR_PUSH | REDIR_KEEP); evaltree(n->nredir.n, flags); popredir(); break; case NSUBSHELL: evalsubshell(n, flags); do_etest = !(flags & EV_TESTED); break; case NBACKGND: evalsubshell(n, flags); break; case NIF: { evaltree(n->nif.test, EV_TESTED); if (nflag || evalskip) goto out; if (exitstatus == 0) evaltree(n->nif.ifpart, flags); else if (n->nif.elsepart) evaltree(n->nif.elsepart, flags); else exitstatus = 0; break; } case NWHILE: case NUNTIL: evalloop(n, flags); break; case NFOR: evalfor(n, flags); break; case NCASE: evalcase(n, flags); break; case NDEFUN: defun(n->narg.text, n->narg.next); exitstatus = 0; break; case NNOT: evaltree(n->nnot.com, EV_TESTED); exitstatus = !exitstatus; break; case NPIPE: evalpipe(n); do_etest = !(flags & EV_TESTED); break; case NCMD: evalcommand(n, flags, NULL); do_etest = !(flags & EV_TESTED); break; default: #ifdef NODETYPENAME out1fmt("Node type = %d(%s)\n", n->type, NODETYPENAME(n->type)); #else out1fmt("Node type = %d\n", n->type); #endif flushout(&output); break; } out: if (pendingsigs) dotrap(); if ((flags & EV_EXIT) != 0 || (eflag && exitstatus != 0 && do_etest)) exitshell(exitstatus); }