Parser fix from NetBSD (christos)
authormillert <millert@openbsd.org>
Sun, 1 Dec 1996 05:09:51 +0000 (05:09 +0000)
committermillert <millert@openbsd.org>
Sun, 1 Dec 1996 05:09:51 +0000 (05:09 +0000)
- ! was only recognized in the beginning of pipelines.  Now we
  are recognizing it everywhere like ksh, so the following works.
! if [ a = b ]; then ! echo c && ! true; else ! echo d; fi

bin/sh/parser.c

index e30da0c..5205429 100644 (file)
@@ -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];