summaryrefslogtreecommitdiffstats
path: root/bin/sh/parser.c
diff options
context:
space:
mode:
authorsteve <steve@FreeBSD.org>1996-12-14 06:20:03 +0000
committersteve <steve@FreeBSD.org>1996-12-14 06:20:03 +0000
commitc58aca035e2c61510b619368861598623eb95e52 (patch)
tree049d84189a59de29d49254b609a318b17ee59387 /bin/sh/parser.c
parenta958416f1b4a022c358b94db0b8e6bcc6cb54ee0 (diff)
downloadFreeBSD-src-c58aca035e2c61510b619368861598623eb95e52.zip
FreeBSD-src-c58aca035e2c61510b619368861598623eb95e52.tar.gz
Merge in NetBSD mods and -Wall cleaning.
Obtained from: NetBSD, me
Diffstat (limited to 'bin/sh/parser.c')
-rw-r--r--bin/sh/parser.c166
1 files changed, 121 insertions, 45 deletions
diff --git a/bin/sh/parser.c b/bin/sh/parser.c
index 1874531..e400b45 100644
--- a/bin/sh/parser.c
+++ b/bin/sh/parser.c
@@ -33,11 +33,11 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * $Id$
+ * $Id: parser.c,v 1.16 1996/09/10 02:42:33 peter Exp $
*/
#ifndef lint
-static char sccsid[] = "@(#)parser.c 8.7 (Berkeley) 5/16/95";
+static char const sccsid[] = "@(#)parser.c 8.7 (Berkeley) 5/16/95";
#endif /* not lint */
#include <stdlib.h>
@@ -120,7 +120,7 @@ STATIC int readtoken1 __P((int, char const *, char *, int));
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));
/*
@@ -129,7 +129,7 @@ STATIC void setprompt __P((int));
*/
union node *
-parsecmd(interact)
+parsecmd(interact)
int interact;
{
int t;
@@ -151,7 +151,7 @@ parsecmd(interact)
STATIC union node *
-list(nlflag)
+list(nlflag)
int nlflag;
{
union node *n1, *n2, *n3;
@@ -249,16 +249,10 @@ andor() {
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));
@@ -277,12 +271,6 @@ pipeline() {
n1 = pipenode;
}
tokpushback++;
- if (negate) {
- notnode = (union node *)stalloc(sizeof (struct nnot));
- notnode->type = NNOT;
- notnode->nnot.com = n1;
- n1 = notnode;
- }
return n1;
}
@@ -294,12 +282,13 @@ command() {
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;
@@ -308,6 +297,12 @@ command() {
}
tokpushback++;
+ while (readtoken() == TNOT) {
+ TRACE(("command: TNOT recognized\n"));
+ negate = !negate;
+ }
+ tokpushback++;
+
switch (readtoken()) {
case TIF:
n1 = (union node *)stalloc(sizeof (struct nif));
@@ -473,14 +468,15 @@ TRACE(("expecting DO got %s %s\n", tokname[got], got == TWORD ? wordtext : ""));
*/
if (!redir)
synexpect(-1);
- case TAND: /* XXX merge query! */
- case TOR: /* XXX merge query! */
+ case TAND:
+ case TOR:
case TNL:
case TEOF:
case TWORD:
case TRP:
tokpushback++;
- return simplecmd(rpp, redir);
+ n1 = simplecmd(rpp, redir);
+ goto checkneg;
default:
synexpect(-1);
}
@@ -502,7 +498,16 @@ TRACE(("expecting DO got %s %s\n", tokname[got], got == TWORD ? wordtext : ""));
}
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;
}
@@ -512,7 +517,8 @@ simplecmd(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. */
@@ -528,6 +534,12 @@ simplecmd(rpp, redir)
*/
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));
@@ -551,7 +563,7 @@ simplecmd(rpp, redir)
#endif
n->type = NDEFUN;
n->narg.next = command();
- return n;
+ goto checkneg;
} else {
tokpushback++;
break;
@@ -564,7 +576,16 @@ simplecmd(rpp, redir)
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 *
@@ -593,7 +614,7 @@ void fixredir(n, text, err)
else if (text[0] == '-' && text[1] == '\0')
n->ndup.dupfd = -1;
else {
-
+
if (err)
synerror("Bad fd number");
else
@@ -704,12 +725,12 @@ readtoken() {
/*
* 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]));
@@ -724,7 +745,7 @@ readtoken() {
}
}
out:
- checkkwd = 0;
+ checkkwd = (t == TNOT) ? savecheckkwd : 0;
}
#ifdef DEBUG
if (!alreadyseen)
@@ -1207,7 +1228,7 @@ badsub: synerror("Bad substitution");
subtype = p - types + VSNORMAL;
break;
case '%':
- case '#':
+ case '#':
{
int cc = c;
subtype = c == '#' ? VSTRIMLEFT :
@@ -1248,6 +1269,11 @@ parsebackq: {
struct jmploc jmploc;
struct jmploc *volatile savehandler;
int savelen;
+ int saveprompt;
+#if __GNUC__
+ /* Avoid longjmp clobbering */
+ (void) &saveprompt;
+#endif
savepbq = parsebackquote;
if (setjmp(jmploc.loc)) {
@@ -1276,20 +1302,53 @@ parsebackq: {
int savelen;
char *str;
+
STARTSTACKSTR(out);
- while ((c = pgetc ()) != '`') {
- if (c == PEOF) {
- startlinno = plinno;
- synerror("EOF in backquote substitution");
- }
- if (c == '\\') {
- c = pgetc ();
+ for (;;) {
+ if (needprompt) {
+ setprompt(2);
+ needprompt = 0;
+ }
+ switch (c = pgetc()) {
+ case '`':
+ goto done;
+
+ case '\\':
+ if ((c = pgetc()) == '\n') {
+ plinno++;
+ if (doprompt)
+ setprompt(2);
+ else
+ setprompt(0);
+ /*
+ * If eating a newline, avoid putting
+ * the newline into the new character
+ * stream (via the STPUTC after the
+ * switch).
+ */
+ continue;
+ }
if (c != '\\' && c != '`' && c != '$'
&& (!dblquote || c != '"'))
STPUTC('\\', out);
- }
- STPUTC(c, out);
+ break;
+
+ case '\n':
+ plinno++;
+ needprompt = doprompt;
+ break;
+
+ case PEOF:
+ startlinno = plinno;
+ synerror("EOF in backquote substitution");
+ break;
+
+ default:
+ break;
+ }
+ STPUTC(c, out);
}
+done:
STPUTC('\0', out);
savelen = out - stackblock();
if (savelen > 0) {
@@ -1304,13 +1363,30 @@ parsebackq: {
*nlpp = (struct nodelist *)stalloc(sizeof (struct nodelist));
(*nlpp)->next = NULL;
parsebackquote = oldstyle;
+
+ if (oldstyle) {
+ saveprompt = doprompt;
+ doprompt = 0;
+ }
+
n = list(0);
- if (!oldstyle && (readtoken() != TRP))
- synexpect(TRP);
+
+ if (oldstyle)
+ doprompt = saveprompt;
+ else {
+ if (readtoken() != TRP)
+ synexpect(TRP);
+ }
+
(*nlpp)->n = n;
- /* Start reading from old file again. */
- if (oldstyle)
+ if (oldstyle) {
+ /*
+ * Start reading from old file again, ignoring any pushed back
+ * tokens left from the backquote parsing
+ */
popfile();
+ tokpushback = 0;
+ }
while (stackblocksize() <= savelen)
growstackblock();
STARTSTACKSTR(out);
@@ -1416,7 +1492,7 @@ goodname(name)
*/
STATIC void
-synexpect(token)
+synexpect(token)
int token;
{
char msg[64];
OpenPOWER on IntegriCloud