svn commit: r214709 - in head: bin/sh tools/regression/bin/sh/parser

Jilles Tjoelker jilles at FreeBSD.org
Tue Nov 2 23:44:30 UTC 2010


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


More information about the svn-src-all mailing list