summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorjilles <jilles@FreeBSD.org>2010-11-02 23:44:29 +0000
committerjilles <jilles@FreeBSD.org>2010-11-02 23:44:29 +0000
commit000173def65316b21deddb738309d1f6643d6851 (patch)
treec6529bbc325307b325b642cc929cce790ae62f8e
parentfa419e93b75ab1483de6709c29a456e1dd6422f8 (diff)
downloadFreeBSD-src-000173def65316b21deddb738309d1f6643d6851.zip
FreeBSD-src-000173def65316b21deddb738309d1f6643d6851.tar.gz
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
-rw-r--r--bin/sh/parser.c99
-rw-r--r--tools/regression/bin/sh/parser/alias3.06
2 files changed, 55 insertions, 50 deletions
diff --git a/bin/sh/parser.c b/bin/sh/parser.c
index 23db5e7..01907e8 100644
--- a/bin/sh/parser.c
+++ b/bin/sh/parser.c
@@ -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 last token started */
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", tokname[got], got == TWORD ? wordtext : ""));
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", tokname[got], got == TWORD ? wordtext : ""));
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", tokname[got], got == TWORD ? wordtext : ""));
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", tokname[got], got == TWORD ? wordtext : ""));
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", tokname[got], got == TWORD ? wordtext : ""));
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", tokname[got], got == TWORD ? wordtext : ""));
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 : ""));
diff --git a/tools/regression/bin/sh/parser/alias3.0 b/tools/regression/bin/sh/parser/alias3.0
new file mode 100644
index 0000000..e0721e2
--- /dev/null
+++ b/tools/regression/bin/sh/parser/alias3.0
@@ -0,0 +1,6 @@
+# $FreeBSD$
+
+alias alias0=exit
+x=alias0
+eval 'case $x in "alias0") alias0 0;; esac'
+exit 1
OpenPOWER on IntegriCloud