diff -urN netbsd-sh/mksyntax.c ash-0.3.7.orig/mksyntax.c --- netbsd-sh/mksyntax.c Fri Jan 12 17:50:38 2001 +++ ash-0.3.7.orig/mksyntax.c Mon Apr 23 22:16:46 2001 @@ -238,14 +238,14 @@ add("$", "CVAR"); add("}", "CENDVAR"); /* ':/' for tilde expansion, '-' for [a\-x] pattern ranges */ - add("!*?[=~:/-", "CCTL"); + add("!*?[=~:/-]", "CCTL"); print("dqsyntax"); init(); fputs("\n/* syntax table used when in single quotes */\n", cfile); add("\n", "CNL"); add("'", "CENDQUOTE"); /* ':/' for tilde expansion, '-' for [a\-x] pattern ranges */ - add("!*?[=~:/-", "CCTL"); + add("!*?[=~:/-]\\", "CCTL"); print("sqsyntax"); init(); fputs("\n/* syntax table used when in arithmetic */\n", cfile); diff -urN netbsd-sh/parser.c ash-0.3.7.orig/parser.c --- netbsd-sh/parser.c Fri Jan 12 17:50:39 2001 +++ ash-0.3.7.orig/parser.c Mon Apr 23 22:16:46 2001 @@ -221,6 +221,7 @@ union node *n1, *n2, *n3; int t; + checkkwd = 1; n1 = pipeline(); for (;;) { if ((t = readtoken()) == TAND) { @@ -231,6 +232,7 @@ tokpushback++; return n1; } + checkkwd = 2; n2 = pipeline(); n3 = (union node *)stalloc(sizeof (struct nbinary)); n3->type = t; @@ -250,9 +252,11 @@ negate = 0; TRACE(("pipeline: entered\n")); - while (readtoken() == TNOT) + if (readtoken() == TNOT) { negate = !negate; - tokpushback++; + checkkwd = 1; + } else + tokpushback++; n1 = command(); if (readtoken() == TPIPE) { pipenode = (union node *)stalloc(sizeof (struct npipe)); @@ -264,6 +268,7 @@ do { prev = lp; lp = (struct nodelist *)stalloc(sizeof (struct nodelist)); + checkkwd = 2; lp->n = command(); prev->next = lp; } while (readtoken() == TPIPE); @@ -288,9 +293,8 @@ union node *ap, **app; union node *cp, **cpp; union node *redir, **rpp; - int t, negate = 0; + int t; - checkkwd = 2; redir = NULL; n1 = NULL; rpp = &redir; @@ -303,12 +307,6 @@ } tokpushback++; - while (readtoken() == TNOT) { - TRACE(("command: TNOT recognized\n")); - negate = !negate; - } - tokpushback++; - switch (readtoken()) { case TIF: n1 = (union node *)stalloc(sizeof (struct nif)); @@ -417,6 +415,8 @@ cpp = &n1->ncase.cases; checkkwd = 2, readtoken(); do { + if (lasttoken == TLP) + readtoken(); *cpp = cp = (union node *)stalloc(sizeof (struct nclist)); cp->type = NCLIST; app = &cp->nclist.pattern; @@ -464,21 +464,22 @@ break; /* Handle an empty command like other simple commands. */ case TSEMI: + case TAND: + case TOR: + case TNL: + case TEOF: + case TRP: + case TBACKGND: /* * An empty command before a ; doesn't make much sense, and * should certainly be disallowed in the case of `if ;'. */ if (!redir) synexpect(-1); - case TAND: - case TOR: - case TNL: - case TEOF: case TWORD: - case TRP: tokpushback++; n1 = simplecmd(rpp, redir); - goto checkneg; + return n1; default: synexpect(-1); /* NOTREACHED */ @@ -502,15 +503,7 @@ n1->nredir.redirect = redir; } -checkneg: - if (negate) { - n2 = (union node *)stalloc(sizeof (struct nnot)); - n2->type = NNOT; - n2->nnot.com = n1; - return n2; - } - else - return n1; + return n1; } @@ -520,8 +513,7 @@ { union node *args, **app; union node **orig_rpp = rpp; - union node *n = NULL, *n2; - int negate = 0; + union node *n = NULL; /* If we don't have any redirections already, then we must reset */ /* rpp to be the address of the local redir variable. */ @@ -537,12 +529,6 @@ */ 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)); @@ -565,8 +551,9 @@ synerror("Bad function name"); #endif n->type = NDEFUN; + checkkwd = 2; n->narg.next = command(); - goto checkneg; + return n; } else { tokpushback++; break; @@ -579,16 +566,7 @@ n->ncmd.backgnd = 0; n->ncmd.args = args; n->ncmd.redirect = redir; - -checkneg: - if (negate) { - n2 = (union node *)stalloc(sizeof (struct nnot)); - n2->type = NNOT; - n2->nnot.com = n; - return n2; - } - else - return n; + return n; } STATIC union node * @@ -743,7 +721,7 @@ } } out: - checkkwd = (t == TNOT) ? savecheckkwd : 0; + checkkwd = 0; } #ifdef DEBUG if (!alreadyseen) @@ -882,6 +860,7 @@ int varnest; /* levels of variables expansion */ int arinest; /* levels of arithmetic expansion */ int parenlevel; /* levels of parens in arithmetic */ + int dqvarnest; /* levels of variables expansion within double quotes */ int oldstyle; char const *prevsyntax; /* syntax before arithmetic */ #if __GNUC__ @@ -892,6 +871,7 @@ (void) &varnest; (void) &arinest; (void) &parenlevel; + (void) &dqvarnest; (void) &oldstyle; (void) &prevsyntax; (void) &syntax; @@ -906,6 +886,7 @@ varnest = 0; arinest = 0; parenlevel = 0; + dqvarnest = 0; STARTSTACKSTR(out); loop: { /* for each line, until end of word */ @@ -938,7 +919,8 @@ USTPUTC(c, out); break; case CCTL: - if (eofmark == NULL || dblquote) + if ((eofmark == NULL || dblquote) && + dqvarnest == 0) USTPUTC(CTLESC, out); USTPUTC(c, out); break; @@ -983,7 +965,8 @@ if (arinest) { syntax = ARISYNTAX; dblquote = 0; - } else if (eofmark == NULL) { + } else if (eofmark == NULL && + dqvarnest == 0) { syntax = BASESYNTAX; dblquote = 0; } @@ -996,6 +979,9 @@ case CENDVAR: /* '}' */ if (varnest > 0) { varnest--; + if (dqvarnest > 0) { + dqvarnest--; + } USTPUTC(CTLENDVAR, out); } else { USTPUTC(c, out); @@ -1260,8 +1248,12 @@ if (dblquote || arinest) flags |= VSQUOTE; *(stackblock() + typeloc) = subtype | flags; - if (subtype != VSNORMAL) + if (subtype != VSNORMAL) { varnest++; + if (dblquote) { + dqvarnest++; + } + } } goto parsesub_return; }