aboutsummaryrefslogtreecommitdiff
path: root/bin
diff options
context:
space:
mode:
authorBrian Somers <brian@FreeBSD.org>2001-04-04 10:11:43 +0000
committerBrian Somers <brian@FreeBSD.org>2001-04-04 10:11:43 +0000
commit6c0bde79a8c285c580bf5ed0c973afb78866da34 (patch)
tree73b8c97e09a30e508d02c8ba7556efac61ce39be /bin
parent6a5e9ec9402c90d379c672eb7f57f292afc50a78 (diff)
downloadsrc-6c0bde79a8c285c580bf5ed0c973afb78866da34.tar.gz
src-6c0bde79a8c285c580bf5ed0c973afb78866da34.zip
A much better (more correct) fix for handling ``!'' characters
Obtained from: NetBSD
Notes
Notes: svn path=/head/; revision=75160
Diffstat (limited to 'bin')
-rw-r--r--bin/sh/parser.c63
1 files changed, 40 insertions, 23 deletions
diff --git a/bin/sh/parser.c b/bin/sh/parser.c
index 9164b6031ae0..0c9a202271bd 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)