Author: jilles
Date: Tue Nov  2 23:44:29 2010
New Revision: 214709
URL: http://svn.freebsd.org/changeset/base/214709

Log:
  sh: Fix some issues with aliases and case, by importing dash checkkwd code.
  
  This moves the function of the noaliases variable into the checkkwd
  variable. This way it is properly reset on errors and aliases can be used
  normally in the commands for each case (the case labels recognize the
  keyword esac but no aliases).
  
  The new code is clearer as well.
  
  Obtained from:        dash

Added:
  head/tools/regression/bin/sh/parser/alias3.0   (contents, props changed)
Modified:
  head/bin/sh/parser.c

Modified: head/bin/sh/parser.c
==============================================================================
--- head/bin/sh/parser.c        Tue Nov  2 23:43:44 2010        (r214708)
+++ head/bin/sh/parser.c        Tue Nov  2 23:44:29 2010        (r214709)
@@ -69,6 +69,11 @@ __FBSDID("$FreeBSD$");
 #define        EOFMARKLEN      79
 #define        PROMPTLEN       128
 
+/* values of checkkwd variable */
+#define CHKALIAS       0x1
+#define CHKKWD         0x2
+#define CHKNL          0x4
+
 /* values returned by readtoken */
 #include "token.h"
 
@@ -102,9 +107,6 @@ static int startlinno;              /* line # where 
 static int funclinno;          /* line # where the current function started */
 static struct parser_temp *parser_temp;
 
-/* XXX When 'noaliases' is set to one, no alias expansion takes place. */
-static int noaliases = 0;
-
 
 static union node *list(int, int);
 static union node *andor(void);
@@ -230,7 +232,7 @@ list(int nlflag, int erflag)
        union node *ntop, *n1, *n2, *n3;
        int tok;
 
-       checkkwd = 2;
+       checkkwd = CHKNL | CHKKWD | CHKALIAS;
        if (!nlflag && !erflag && tokendlist[peektoken()])
                return NULL;
        ntop = n1 = NULL;
@@ -283,7 +285,7 @@ list(int nlflag, int erflag)
                        } else {
                                tokpushback++;
                        }
-                       checkkwd = 2;
+                       checkkwd = CHKNL | CHKKWD | CHKALIAS;
                        if (!nlflag && !erflag && tokendlist[peektoken()])
                                return ntop;
                        break;
@@ -339,7 +341,7 @@ pipeline(void)
        int negate, t;
 
        negate = 0;
-       checkkwd = 2;
+       checkkwd = CHKNL | CHKKWD | CHKALIAS;
        TRACE(("pipeline: entered\n"));
        while (readtoken() == TNOT)
                negate = !negate;
@@ -355,7 +357,7 @@ pipeline(void)
                do {
                        prev = lp;
                        lp = (struct nodelist *)stalloc(sizeof (struct 
nodelist));
-                       checkkwd = 2;
+                       checkkwd = CHKNL | CHKKWD | CHKALIAS;
                        t = readtoken();
                        tokpushback++;
                        if (t == TNOT)
@@ -388,7 +390,7 @@ command(void)
        union node *redir, **rpp;
        int t;
 
-       checkkwd = 2;
+       checkkwd = CHKNL | CHKKWD | CHKALIAS;
        redir = NULL;
        n1 = NULL;
        rpp = &redir;
@@ -429,7 +431,7 @@ command(void)
                }
                if (readtoken() != TFI)
                        synexpect(TFI);
-               checkkwd = 1;
+               checkkwd = CHKKWD | CHKALIAS;
                break;
        case TWHILE:
        case TUNTIL: {
@@ -445,7 +447,7 @@ TRACE(("expecting DO got %s %s\n", tokna
                n1->nbinary.ch2 = list(0, 0);
                if (readtoken() != TDONE)
                        synexpect(TDONE);
-               checkkwd = 1;
+               checkkwd = CHKKWD | CHKALIAS;
                break;
        }
        case TFOR:
@@ -487,7 +489,7 @@ TRACE(("expecting DO got %s %s\n", tokna
                        if (lasttoken != TNL && lasttoken != TSEMI)
                                tokpushback++;
                }
-               checkkwd = 2;
+               checkkwd = CHKNL | CHKKWD | CHKALIAS;
                if ((t = readtoken()) == TDO)
                        t = TDONE;
                else if (t == TBEGIN)
@@ -497,7 +499,7 @@ TRACE(("expecting DO got %s %s\n", tokna
                n1->nfor.body = list(0, 0);
                if (readtoken() != t)
                        synexpect(t);
-               checkkwd = 1;
+               checkkwd = CHKKWD | CHKALIAS;
                break;
        case TCASE:
                n1 = (union node *)stalloc(sizeof (struct ncase));
@@ -513,8 +515,7 @@ TRACE(("expecting DO got %s %s\n", tokna
                if (lasttoken != TWORD || ! equal(wordtext, "in"))
                        synerror("expecting \"in\"");
                cpp = &n1->ncase.cases;
-               noaliases = 1;  /* turn off alias expansion */
-               checkkwd = 2, readtoken();
+               checkkwd = CHKNL | CHKKWD, readtoken();
                while (lasttoken != TESAC) {
                        *cpp = cp = (union node *)stalloc(sizeof (struct 
nclist));
                        cp->type = NCLIST;
@@ -526,28 +527,28 @@ TRACE(("expecting DO got %s %s\n", tokna
                                ap->type = NARG;
                                ap->narg.text = wordtext;
                                ap->narg.backquote = backquotelist;
-                               if (checkkwd = 2, readtoken() != TPIPE)
+                               checkkwd = CHKNL | CHKKWD;
+                               if (readtoken() != TPIPE)
                                        break;
                                app = &ap->narg.next;
                                readtoken();
                        }
                        ap->narg.next = NULL;
                        if (lasttoken != TRP)
-                               noaliases = 0, synexpect(TRP);
+                               synexpect(TRP);
                        cp->nclist.body = list(0, 0);
 
-                       checkkwd = 2;
+                       checkkwd = CHKNL | CHKKWD | CHKALIAS;
                        if ((t = readtoken()) != TESAC) {
                                if (t != TENDCASE)
-                                       noaliases = 0, synexpect(TENDCASE);
+                                       synexpect(TENDCASE);
                                else
-                                       checkkwd = 2, readtoken();
+                                       checkkwd = CHKNL | CHKKWD, readtoken();
                        }
                        cpp = &cp->nclist.next;
                }
-               noaliases = 0;  /* reset alias expansion */
                *cpp = NULL;
-               checkkwd = 1;
+               checkkwd = CHKKWD | CHKALIAS;
                break;
        case TLP:
                n1 = (union node *)stalloc(sizeof (struct nredir));
@@ -556,13 +557,13 @@ TRACE(("expecting DO got %s %s\n", tokna
                n1->nredir.redirect = NULL;
                if (readtoken() != TRP)
                        synexpect(TRP);
-               checkkwd = 1;
+               checkkwd = CHKKWD | CHKALIAS;
                break;
        case TBEGIN:
                n1 = list(0, 0);
                if (readtoken() != TEND)
                        synexpect(TEND);
-               checkkwd = 1;
+               checkkwd = CHKKWD | CHKALIAS;
                break;
        /* Handle an empty command like other simple commands.  */
        case TBACKGND:
@@ -796,7 +797,6 @@ static int
 readtoken(void)
 {
        int t;
-       int savecheckkwd = checkkwd;
        struct alias *ap;
 #ifdef DEBUG
        int alreadyseen = tokpushback;
@@ -805,25 +805,24 @@ readtoken(void)
        top:
        t = xxreadtoken();
 
-       if (checkkwd) {
-               /*
-                * eat newlines
-                */
-               if (checkkwd == 2) {
-                       checkkwd = 0;
-                       while (t == TNL) {
-                               parseheredoc();
-                               t = xxreadtoken();
-                       }
-               } else
-                       checkkwd = 0;
-               /*
-                * check for keywords and aliases
-                */
-               if (t == TWORD && !quoteflag)
-               {
-                       const char * const *pp;
+       /*
+        * eat newlines
+        */
+       if (checkkwd & CHKNL) {
+               while (t == TNL) {
+                       parseheredoc();
+                       t = xxreadtoken();
+               }
+       }
 
+       /*
+        * check for keywords and aliases
+        */
+       if (t == TWORD && !quoteflag)
+       {
+               const char * const *pp;
+
+               if (checkkwd & CHKKWD)
                        for (pp = parsekwd; *pp; pp++) {
                                if (**pp == *wordtext && equal(*pp, wordtext))
                                {
@@ -832,16 +831,16 @@ readtoken(void)
                                        goto out;
                                }
                        }
-                       if (noaliases == 0 &&
-                           (ap = lookupalias(wordtext, 1)) != NULL) {
-                               pushstring(ap->val, strlen(ap->val), ap);
-                               checkkwd = savecheckkwd;
-                               goto top;
-                       }
+               if (checkkwd & CHKALIAS &&
+                   (ap = lookupalias(wordtext, 1)) != NULL) {
+                       pushstring(ap->val, strlen(ap->val), ap);
+                       goto top;
                }
-out:
-               checkkwd = (t == TNOT) ? savecheckkwd : 0;
        }
+out:
+       if (t != TNOT)
+               checkkwd = 0;
+
 #ifdef DEBUG
        if (!alreadyseen)
            TRACE(("token %s %s\n", tokname[t], t == TWORD ? wordtext : ""));

Added: head/tools/regression/bin/sh/parser/alias3.0
==============================================================================
--- /dev/null   00:00:00 1970   (empty, because file is newly added)
+++ head/tools/regression/bin/sh/parser/alias3.0        Tue Nov  2 23:44:29 
2010        (r214709)
@@ -0,0 +1,6 @@
+# $FreeBSD$
+
+alias alias0=exit
+x=alias0
+eval 'case $x in "alias0") alias0 0;; esac'
+exit 1
_______________________________________________
svn-src-head@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/svn-src-head
To unsubscribe, send any mail to "svn-src-head-unsubscr...@freebsd.org"

Reply via email to