summaryrefslogtreecommitdiff
path: root/bin/sh
diff options
context:
space:
mode:
Diffstat (limited to 'bin/sh')
-rw-r--r--bin/sh/parser.c99
1 files changed, 60 insertions, 39 deletions
diff --git a/bin/sh/parser.c b/bin/sh/parser.c
index e30da0c5457..5205429be43 100644
--- a/bin/sh/parser.c
+++ b/bin/sh/parser.c
@@ -1,5 +1,5 @@
-/* $OpenBSD: parser.c,v 1.5 1996/10/20 00:55:02 millert Exp $ */
-/* $NetBSD: parser.c,v 1.29 1996/05/09 19:40:08 christos Exp $ */
+/* $OpenBSD: parser.c,v 1.6 1996/12/01 05:09:51 millert Exp $ */
+/* $NetBSD: parser.c,v 1.31 1996/11/25 20:22:00 christos Exp $ */
/*-
* Copyright (c) 1991, 1993
@@ -41,7 +41,7 @@
#if 0
static char sccsid[] = "@(#)parser.c 8.7 (Berkeley) 5/16/95";
#else
-static char rcsid[] = "$NetBSD: parser.c,v 1.29 1996/05/09 19:40:08 christos Exp $";
+static char rcsid[] = "$OpenBSD: parser.c,v 1.6 1996/12/01 05:09:51 millert Exp $";
#endif
#endif /* not lint */
@@ -123,7 +123,7 @@ STATIC int readtoken1 __P((int, char const *, char *, int));
STATIC int noexpand __P((char *));
STATIC void synexpect __P((int));
STATIC void synerror __P((char *));
-STATIC void setprompt __P((int));
+STATIC void setprompt __P((int));
/*
@@ -132,7 +132,7 @@ STATIC void setprompt __P((int));
*/
union node *
-parsecmd(interact)
+parsecmd(interact)
int interact;
{
int t;
@@ -154,7 +154,7 @@ parsecmd(interact)
STATIC union node *
-list(nlflag)
+list(nlflag)
int nlflag;
{
union node *n1, *n2, *n3;
@@ -252,16 +252,10 @@ andor() {
STATIC union node *
pipeline() {
- union node *n1, *pipenode, *notnode;
+ union node *n1, *pipenode;
struct nodelist *lp, *prev;
- int negate = 0;
TRACE(("pipeline: entered\n"));
- while (readtoken() == TNOT) {
- TRACE(("pipeline: TNOT recognized\n"));
- negate = !negate;
- }
- tokpushback++;
n1 = command();
if (readtoken() == TPIPE) {
pipenode = (union node *)stalloc(sizeof (struct npipe));
@@ -280,12 +274,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;
}
@@ -297,12 +285,13 @@ command() {
union node *ap, **app;
union node *cp, **cpp;
union node *redir, **rpp;
- int t;
+ int t, negate = 0;
checkkwd = 2;
redir = NULL;
n1 = NULL;
rpp = &redir;
+
/* Check for redirection which may precede command */
while (readtoken() == TREDIR) {
*rpp = n2 = redirnode;
@@ -311,6 +300,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));
@@ -481,7 +476,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);
}
@@ -503,17 +499,27 @@ 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;
}
STATIC union node *
-simplecmd(rpp, redir)
+simplecmd(rpp, redir)
union node **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. */
@@ -522,13 +528,19 @@ simplecmd(rpp, redir)
args = NULL;
app = &args;
- /*
+ /*
* We save the incoming value, because we need this for shell
* functions. There can not be a redirect or an argument between
- * the function name and the open parenthesis.
+ * the function name and the open parenthesis.
*/
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));
@@ -552,7 +564,7 @@ simplecmd(rpp, redir)
#endif
n->type = NDEFUN;
n->narg.next = command();
- return n;
+ goto checkneg;
} else {
tokpushback++;
break;
@@ -565,7 +577,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 *
@@ -594,7 +615,7 @@ void fixredir(n, text, err)
else if (text[0] == '-' && text[1] == '\0')
n->ndup.dupfd = -1;
else {
-
+
if (err)
synerror("Bad fd number");
else
@@ -686,7 +707,7 @@ readtoken() {
#ifdef DEBUG
int alreadyseen = tokpushback;
#endif
-
+
top:
t = xxreadtoken();
@@ -705,12 +726,12 @@ readtoken() {
/*
* check for keywords and aliases
*/
- if (t == TWORD && !quoteflag)
+ if (t == TWORD && !quoteflag)
{
register char * const *pp;
for (pp = (char **)parsekwd; *pp; pp++) {
- if (**pp == *wordtext && equal(*pp, wordtext))
+ if (**pp == *wordtext && equal(*pp, wordtext))
{
lasttoken = t = pp - parsekwd + KWDOFFSET;
TRACE(("keyword %s recognized\n", tokname[t]));
@@ -724,7 +745,7 @@ readtoken() {
}
}
out:
- checkkwd = 0;
+ checkkwd = (t == TNOT) ? savecheckkwd : 0;
}
#ifdef DEBUG
if (!alreadyseen)
@@ -989,7 +1010,7 @@ readtoken1(firstc, syntax, eofmark, striptabs)
} else
USTPUTC(')', out);
} else {
- /*
+ /*
* unbalanced parens
* (don't 2nd guess - no error)
*/
@@ -1195,7 +1216,7 @@ badsub: synerror("Bad substitution");
subtype = p - types + VSNORMAL;
break;
case '%':
- case '#':
+ case '#':
{
int cc = c;
subtype = c == '#' ? VSTRIMLEFT :
@@ -1265,7 +1286,7 @@ parsebackq: {
int savelen;
char *str;
-
+
STARTSTACKSTR(out);
for (;;) {
if (needprompt) {
@@ -1302,9 +1323,9 @@ parsebackq: {
break;
case PEOF:
- startlinno = plinno;
+ startlinno = plinno;
synerror("EOF in backquote substitution");
- break;
+ break;
default:
break;
@@ -1455,7 +1476,7 @@ goodname(name)
*/
STATIC void
-synexpect(token)
+synexpect(token)
int token;
{
char msg[64];