diff options
author | brian <brian@FreeBSD.org> | 2001-04-04 10:11:43 +0000 |
---|---|---|
committer | brian <brian@FreeBSD.org> | 2001-04-04 10:11:43 +0000 |
commit | 68e27cd3949748f987739e406b26b84fed55b509 (patch) | |
tree | fb4da78b74426d6d09f6e796414441e07ea0bcdb | |
parent | 91b29fba9603eb17034d95c3372fa92b725bb3ee (diff) | |
download | FreeBSD-src-68e27cd3949748f987739e406b26b84fed55b509.zip FreeBSD-src-68e27cd3949748f987739e406b26b84fed55b509.tar.gz |
A much better (more correct) fix for handling ``!'' characters
Obtained from: NetBSD
-rw-r--r-- | bin/sh/parser.c | 63 |
1 files changed, 40 insertions, 23 deletions
diff --git a/bin/sh/parser.c b/bin/sh/parser.c index 9164b60..0c9a202 100644 --- a/bin/sh/parser.c +++ b/bin/sh/parser.c @@ -253,19 +253,10 @@ andor() { STATIC union node * pipeline() { - union node *n1, *pipenode, *notnode; + union node *n1, *pipenode; struct nodelist *lp, *prev; - int negate = 0; - int savecheckkwd = checkkwd; TRACE(("pipeline: entered\n")); - checkkwd = 2; - while (readtoken() == TNOT) { - TRACE(("pipeline: TNOT recognized\n")); - negate = !negate; - } - tokpushback++; - checkkwd = savecheckkwd; n1 = command(); if (readtoken() == TPIPE) { pipenode = (union node *)stalloc(sizeof (struct npipe)); @@ -284,12 +275,6 @@ pipeline() { n1 = pipenode; } tokpushback++; - if (negate) { - notnode = (union node *)stalloc(sizeof(struct nnot)); - notnode->type = NNOT; - notnode->nnot.com = n1; - n1 = notnode; - } return n1; } @@ -301,7 +286,7 @@ command() { union node *ap, **app; union node *cp, **cpp; union node *redir, **rpp; - int t; + int t, negate = 0; checkkwd = 2; redir = NULL; @@ -316,6 +301,12 @@ command() { } tokpushback++; + while (readtoken() == TNOT) { + TRACE(("command: TNOT recognized\n")); + negate = !negate; + } + tokpushback++; + switch (readtoken()) { case TIF: n1 = (union node *)stalloc(sizeof (struct nif)); @@ -488,7 +479,8 @@ TRACE(("expecting DO got %s %s\n", tokname[got], got == TWORD ? wordtext : "")); case TWORD: case TRP: tokpushback++; - return simplecmd(rpp, redir); + n1 = simplecmd(rpp, redir); + goto checkneg; default: synexpect(-1); } @@ -510,7 +502,16 @@ TRACE(("expecting DO got %s %s\n", tokname[got], got == TWORD ? wordtext : "")); } n1->nredir.redirect = redir; } - return n1; + +checkneg: + if (negate) { + n2 = (union node *)stalloc(sizeof (struct nnot)); + n2->type = NNOT; + n2->nnot.com = n1; + return n2; + } + else + return n1; } @@ -520,7 +521,8 @@ simplecmd(rpp, redir) { union node *args, **app; union node **orig_rpp = rpp; - union node *n = NULL; + union node *n = NULL, *n2; + int negate = 0; /* If we don't have any redirections already, then we must reset */ /* rpp to be the address of the local redir variable. */ @@ -536,6 +538,12 @@ simplecmd(rpp, redir) */ orig_rpp = rpp; + while (readtoken() == TNOT) { + TRACE(("command: TNOT recognized\n")); + negate = !negate; + } + tokpushback++; + for (;;) { if (readtoken() == TWORD) { n = (union node *)stalloc(sizeof (struct narg)); @@ -559,7 +567,7 @@ simplecmd(rpp, redir) #endif n->type = NDEFUN; n->narg.next = command(); - return n; + goto checkneg; } else { tokpushback++; break; @@ -572,7 +580,16 @@ simplecmd(rpp, redir) n->ncmd.backgnd = 0; n->ncmd.args = args; n->ncmd.redirect = redir; - return n; + +checkneg: + if (negate) { + n2 = (union node *)stalloc(sizeof (struct nnot)); + n2->type = NNOT; + n2->nnot.com = n; + return n2; + } + else + return n; } STATIC union node * @@ -730,7 +747,7 @@ readtoken() { } } out: - checkkwd = 0; + checkkwd = (t == TNOT) ? savecheckkwd : 0; } #ifdef DEBUG if (!alreadyseen) |