if (negate) { notnode = (union node *)stalloc(sizeof (struct nnot)); notnode->type = NNOT; notnode->nnot.com = n1; n1 = notnode; }
STATIC union node *pipeline __P((void));STATIC union node *command __P((void));STATIC union node *simplecmd __P((union node **, union node *));STATIC union node *makename __P((void));STATIC void parsefname __P((void));STATIC void parseheredoc __P((void));STATIC int peektoken __P((void));STATIC int readtoken __P((void));STATIC int xxreadtoken __P((void));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)); /* * Read and parse a command.  Returns NEOF on end of file.  (NULL is a * valid parse tree indicating a blank line.) */union node *parsecmd(interact) 	int interact;{	int t;	doprompt = interact;	if (doprompt)		setprompt(1);	else		setprompt(0);	needprompt = 0;	t = readtoken();	if (t == TEOF)		return NEOF;	if (t == TNL)		return NULL;	tokpushback++;	return list(1);}STATIC union node *list(nlflag) 	int nlflag;{	union node *n1, *n2, *n3;	int tok;	checkkwd = 2;	if (nlflag == 0 && tokendlist[peektoken()])		return NULL;	n1 = NULL;	for (;;) {		n2 = andor();		tok = readtoken();		if (tok == TBACKGND) {			if (n2->type == NCMD || n2->type == NPIPE) {				n2->ncmd.backgnd = 1;			} else if (n2->type == NREDIR) {				n2->type = NBACKGND;			} else {				n3 = (union node *)stalloc(sizeof (struct nredir));				n3->type = NBACKGND;				n3->nredir.n = n2;				n3->nredir.redirect = NULL;				n2 = n3;			}		}		if (n1 == NULL) {			n1 = n2;		}		else {			n3 = (union node *)stalloc(sizeof (struct nbinary));			n3->type = NSEMI;			n3->nbinary.ch1 = n1;			n3->nbinary.ch2 = n2;			n1 = n3;		}		switch (tok) {		case TBACKGND:		case TSEMI:			tok = readtoken();			/* fall through */		case TNL:			if (tok == TNL) {				parseheredoc();				if (nlflag)					return n1;			} else {				tokpushback++;			}			checkkwd = 2;			if (tokendlist[peektoken()])				return n1;			break;		case TEOF:			if (heredoclist)				parseheredoc();			else				pungetc();		/* push back EOF on input */			return n1;		default:			if (nlflag)				synexpect(-1);			tokpushback++;			return n1;		}	}}STATIC union node *andor() {	union node *n1, *n2, *n3;	int t;	n1 = pipeline();	for (;;) {		if ((t = readtoken()) == TAND) {			t = NAND;		} else if (t == TOR) {			t = NOR;		} else {			tokpushback++;			return n1;		}		n2 = pipeline();		n3 = (union node *)stalloc(sizeof (struct nbinary));		n3->type = t;		n3->nbinary.ch1 = n1;		n3->nbinary.ch2 = n2;		n1 = n3;	}}STATIC union node *pipeline() {	union node *n1, *pipenode, *notnode;	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));		pipenode->type = NPIPE;		pipenode->npipe.backgnd = 0;		lp = (struct nodelist *)stalloc(sizeof (struct nodelist));		pipenode->npipe.cmdlist = lp;		lp->n = n1;		do {			prev = lp;			lp = (struct nodelist *)stalloc(sizeof (struct nodelist));			lp->n = command();			prev->next = lp;		} while (readtoken() == TPIPE);		lp->next = NULL;		n1 = pipenode;	}	tokpushback++;	if (negate) {		notnode = (union node *)stalloc(sizeof (struct nnot));		notnode->type = NNOT;		notnode->nnot.com = n1;		n1 = notnode;	}	return n1;}