-/* $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
#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 */
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));
/*
*/
union node *
-parsecmd(interact)
+parsecmd(interact)
int interact;
{
int t;
STATIC union node *
-list(nlflag)
+list(nlflag)
int nlflag;
{
union node *n1, *n2, *n3;
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));
n1 = pipenode;
}
tokpushback++;
- if (negate) {
- notnode = (union node *)stalloc(sizeof (struct nnot));
- notnode->type = NNOT;
- notnode->nnot.com = n1;
- n1 = notnode;
- }
return n1;
}
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;
}
tokpushback++;
+ while (readtoken() == TNOT) {
+ TRACE(("command: TNOT recognized\n"));
+ negate = !negate;
+ }
+ tokpushback++;
+
switch (readtoken()) {
case TIF:
n1 = (union node *)stalloc(sizeof (struct nif));
case TWORD:
case TRP:
tokpushback++;
- return simplecmd(rpp, redir);
+ n1 = simplecmd(rpp, redir);
+ goto checkneg;
default:
synexpect(-1);
}
}
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. */
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));
#endif
n->type = NDEFUN;
n->narg.next = command();
- return n;
+ goto checkneg;
} else {
tokpushback++;
break;
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 *
else if (text[0] == '-' && text[1] == '\0')
n->ndup.dupfd = -1;
else {
-
+
if (err)
synerror("Bad fd number");
else
#ifdef DEBUG
int alreadyseen = tokpushback;
#endif
-
+
top:
t = xxreadtoken();
/*
* 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]));
}
}
out:
- checkkwd = 0;
+ checkkwd = (t == TNOT) ? savecheckkwd : 0;
}
#ifdef DEBUG
if (!alreadyseen)
} else
USTPUTC(')', out);
} else {
- /*
+ /*
* unbalanced parens
* (don't 2nd guess - no error)
*/
subtype = p - types + VSNORMAL;
break;
case '%':
- case '#':
+ case '#':
{
int cc = c;
subtype = c == '#' ? VSTRIMLEFT :
int savelen;
char *str;
-
+
STARTSTACKSTR(out);
for (;;) {
if (needprompt) {
break;
case PEOF:
- startlinno = plinno;
+ startlinno = plinno;
synerror("EOF in backquote substitution");
- break;
+ break;
default:
break;
*/
STATIC void
-synexpect(token)
+synexpect(token)
int token;
{
char msg[64];