172339Sabial#define Extern extern
272339Sabial#include <sys/types.h>
372339Sabial#include <signal.h>
472339Sabial#define _NSIG NSIG
572339Sabial#include <errno.h>
672339Sabial#include <setjmp.h>
772339Sabial#include "sh.h"
872339Sabial
972339Sabial/* -------- csyn.c -------- */
1072339Sabial/*
1172339Sabial * shell: syntax (C version)
1272339Sabial */
1372339Sabial
1472339Sabialtypedef union {
1572339Sabial	char	*cp;
1672339Sabial	char	**wp;
1772339Sabial	int	i;
1872339Sabial	struct	op *o;
1972339Sabial} YYSTYPE;
2072339Sabial#define	WORD	256
2172339Sabial#define	LOGAND	257
2272339Sabial#define	LOGOR	258
2372339Sabial#define	BREAK	259
2472339Sabial#define	IF	260
2572339Sabial#define	THEN	261
2672339Sabial#define	ELSE	262
2772339Sabial#define	ELIF	263
2872339Sabial#define	FI	264
2972339Sabial#define	CASE	265
3072339Sabial#define	ESAC	266
3172339Sabial#define	FOR	267
3272339Sabial#define	WHILE	268
3372339Sabial#define	UNTIL	269
3472339Sabial#define	DO	270
3572339Sabial#define	DONE	271
3672339Sabial#define	IN	272
3772339Sabial#define	YYERRCODE 300
3872339Sabial
3972339Sabial/* flags to yylex */
4072339Sabial#define	CONTIN	01	/* skip new lines to complete command */
4172339Sabial
4272339Sabial/* #include "sh.h" */
4372339Sabial#define	SYNTAXERR	zzerr()
4472339Sabialstatic	int	startl;
4572339Sabialstatic	int	peeksym;
4672339Sabialstatic	int	nlseen;
4772339Sabialstatic	int	iounit = IODEFAULT;
4872339Sabial
4972339Sabialstatic	YYSTYPE	yylval;
5072339Sabial
5172339Sabial_PROTOTYPE(static struct op *pipeline, (int cf ));
5272339Sabial_PROTOTYPE(static struct op *andor, (void));
5372339Sabial_PROTOTYPE(static struct op *c_list, (void));
5472339Sabial_PROTOTYPE(static int synio, (int cf ));
5572339Sabial_PROTOTYPE(static void musthave, (int c, int cf ));
5672339Sabial_PROTOTYPE(static struct op *simple, (void));
5772339Sabial_PROTOTYPE(static struct op *nested, (int type, int mark ));
5872339Sabial_PROTOTYPE(static struct op *command, (int cf ));
5972339Sabial_PROTOTYPE(static struct op *dogroup, (int onlydone ));
6072339Sabial_PROTOTYPE(static struct op *thenpart, (void));
6172339Sabial_PROTOTYPE(static struct op *elsepart, (void));
6272339Sabial_PROTOTYPE(static struct op *caselist, (void));
6372339Sabial_PROTOTYPE(static struct op *casepart, (void));
6472339Sabial_PROTOTYPE(static char **pattern, (void));
6572339Sabial_PROTOTYPE(static char **wordlist, (void));
6672339Sabial_PROTOTYPE(static struct op *list, (struct op *t1, struct op *t2 ));
6772339Sabial_PROTOTYPE(static struct op *block, (int type, struct op *t1, struct op *t2, char **wp ));
6872339Sabial_PROTOTYPE(static struct op *newtp, (void));
6972339Sabial_PROTOTYPE(static struct op *namelist, (struct op *t ));
7072339Sabial_PROTOTYPE(static char **copyw, (void));
7172339Sabial_PROTOTYPE(static void word, (char *cp ));
7272339Sabial_PROTOTYPE(static struct ioword **copyio, (void));
7372339Sabial_PROTOTYPE(static struct ioword *io, (int u, int f, char *cp ));
7472339Sabial_PROTOTYPE(static void zzerr, (void));
7572339Sabial_PROTOTYPE(void yyerror, (char *s ));
7672339Sabial_PROTOTYPE(static int yylex, (int cf ));
7772339Sabial_PROTOTYPE(int collect, (int c, int c1 ));
7872339Sabial_PROTOTYPE(int dual, (int c ));
7972339Sabial_PROTOTYPE(static void diag, (int ec ));
8072339Sabial_PROTOTYPE(static char *tree, (unsigned size ));
8172339Sabial_PROTOTYPE(void printf, (char *s ));
8272339Sabial
8372339Sabialint
8472339Sabialyyparse()
8572339Sabial{
8672339Sabial	startl  = 1;
8772339Sabial	peeksym = 0;
8872339Sabial	yynerrs = 0;
8972339Sabial	outtree = c_list();
9072339Sabial	musthave('\n', 0);
9172339Sabial	return(yynerrs!=0);
9272339Sabial}
9372339Sabial
9472339Sabialstatic struct op *
9572339Sabialpipeline(cf)
9672339Sabialint cf;
9772339Sabial{
9872339Sabial	register struct op *t, *p;
9972339Sabial	register int c;
10072339Sabial
10172339Sabial	t = command(cf);
10272339Sabial	if (t != NULL) {
10372339Sabial		while ((c = yylex(0)) == '|') {
10472339Sabial			if ((p = command(CONTIN)) == NULL)
10572339Sabial				SYNTAXERR;
10672339Sabial			if (t->type != TPAREN && t->type != TCOM) {
10772339Sabial				/* shell statement */
10872339Sabial				t = block(TPAREN, t, NOBLOCK, NOWORDS);
10972339Sabial			}
11072339Sabial			t = block(TPIPE, t, p, NOWORDS);
11172339Sabial		}
11272339Sabial		peeksym = c;
11372339Sabial	}
11472339Sabial	return(t);
11572339Sabial}
11672339Sabial
11772339Sabialstatic struct op *
11872339Sabialandor()
11972339Sabial{
12072339Sabial	register struct op *t, *p;
12172339Sabial	register int c;
12272339Sabial
12372339Sabial	t = pipeline(0);
12472339Sabial	if (t != NULL) {
12572339Sabial		while ((c = yylex(0)) == LOGAND || c == LOGOR) {
12672339Sabial			if ((p = pipeline(CONTIN)) == NULL)
12772339Sabial				SYNTAXERR;
12872339Sabial			t = block(c == LOGAND? TAND: TOR, t, p, NOWORDS);
12972339Sabial		}
13072339Sabial		peeksym = c;
13172339Sabial	}
13272339Sabial	return(t);
13372339Sabial}
13472339Sabial
13572339Sabialstatic struct op *
13672339Sabialc_list()
13772339Sabial{
13872339Sabial	register struct op *t, *p;
13972339Sabial	register int c;
14072339Sabial
14172339Sabial	t = andor();
14272339Sabial	if (t != NULL) {
14372339Sabial		if((peeksym = yylex(0)) == '&')
14472339Sabial			t = block(TASYNC, t, NOBLOCK, NOWORDS);
14572339Sabial		while ((c = yylex(0)) == ';' || c == '&' || (multiline && c == '\n')) {
14672339Sabial			if ((p = andor()) == NULL)
14772339Sabial				return(t);
14872339Sabial			if((peeksym = yylex(0)) == '&')
14972339Sabial				p = block(TASYNC, p, NOBLOCK, NOWORDS);
15072339Sabial			t = list(t, p);
15172339Sabial		}
15272339Sabial		peeksym = c;
15372339Sabial	}
15472339Sabial	return(t);
15572339Sabial}
15672339Sabial
15772339Sabial
15872339Sabialstatic int
15972339Sabialsynio(cf)
16072339Sabialint cf;
16172339Sabial{
16272339Sabial	register struct ioword *iop;
16372339Sabial	register int i;
16472339Sabial	register int c;
16572339Sabial
16672339Sabial	if ((c = yylex(cf)) != '<' && c != '>') {
16772339Sabial		peeksym = c;
16872339Sabial		return(0);
16972339Sabial	}
17072339Sabial	i = yylval.i;
17172339Sabial	musthave(WORD, 0);
17272339Sabial	iop = io(iounit, i, yylval.cp);
17372339Sabial	iounit = IODEFAULT;
17472339Sabial	if (i & IOHERE)
17572339Sabial		markhere(yylval.cp, iop);
17672339Sabial	return(1);
17772339Sabial}
17872339Sabial
17972339Sabialstatic void
18072339Sabialmusthave(c, cf)
18172339Sabialint c, cf;
18272339Sabial{
18372339Sabial	if ((peeksym = yylex(cf)) != c)
18472339Sabial		SYNTAXERR;
18572339Sabial	peeksym = 0;
18672339Sabial}
18772339Sabial
18872339Sabialstatic struct op *
18972339Sabialsimple()
19072339Sabial{
19172339Sabial	register struct op *t;
19272339Sabial
19372339Sabial	t = NULL;
19472339Sabial	for (;;) {
19572339Sabial		switch (peeksym = yylex(0)) {
19672339Sabial		case '<':
19772339Sabial		case '>':
19872339Sabial			(void) synio(0);
19972339Sabial			break;
20072339Sabial
20172339Sabial		case WORD:
20272339Sabial			if (t == NULL) {
20372339Sabial				t = newtp();
20472339Sabial				t->type = TCOM;
20572339Sabial			}
20672339Sabial			peeksym = 0;
20772339Sabial			word(yylval.cp);
20872339Sabial			break;
20972339Sabial
21072339Sabial		default:
21172339Sabial			return(t);
21272339Sabial		}
21372339Sabial	}
21472339Sabial}
21572339Sabial
21672339Sabialstatic struct op *
21772339Sabialnested(type, mark)
21872339Sabialint type, mark;
21972339Sabial{
22072339Sabial	register struct op *t;
22172339Sabial
22272339Sabial	multiline++;
22372339Sabial	t = c_list();
22472339Sabial	musthave(mark, 0);
22572339Sabial	multiline--;
22672339Sabial	return(block(type, t, NOBLOCK, NOWORDS));
22772339Sabial}
22872339Sabial
22972339Sabialstatic struct op *
23072339Sabialcommand(cf)
23172339Sabialint cf;
23272339Sabial{
23372339Sabial	register struct op *t;
23472339Sabial	struct wdblock *iosave;
23572339Sabial	register int c;
23672339Sabial
23772339Sabial	iosave = iolist;
23872339Sabial	iolist = NULL;
23972339Sabial	if (multiline)
24072339Sabial		cf |= CONTIN;
24172339Sabial	while (synio(cf))
24272339Sabial		cf = 0;
24372339Sabial	switch (c = yylex(cf)) {
24472339Sabial	default:
24572339Sabial		peeksym = c;
24672339Sabial		if ((t = simple()) == NULL) {
24772339Sabial			if (iolist == NULL)
24872339Sabial				return((struct op *)NULL);
24972339Sabial			t = newtp();
25072339Sabial			t->type = TCOM;
25172339Sabial		}
25272339Sabial		break;
25372339Sabial
25472339Sabial	case '(':
25572339Sabial		t = nested(TPAREN, ')');
25672339Sabial		break;
25772339Sabial
25872339Sabial	case '{':
25972339Sabial		t = nested(TBRACE, '}');
26072339Sabial		break;
26172339Sabial
26272339Sabial	case FOR:
26372339Sabial		t = newtp();
26472339Sabial		t->type = TFOR;
26572339Sabial		musthave(WORD, 0);
26672339Sabial		startl = 1;
26772339Sabial		t->str = yylval.cp;
26872339Sabial		multiline++;
26972339Sabial		t->words = wordlist();
27072339Sabial		if ((c = yylex(0)) != '\n' && c != ';')
27172339Sabial			peeksym = c;
27272339Sabial		t->left = dogroup(0);
27372339Sabial		multiline--;
27472339Sabial		break;
27572339Sabial
27672339Sabial	case WHILE:
27772339Sabial	case UNTIL:
27872339Sabial		multiline++;
27972339Sabial		t = newtp();
28072339Sabial		t->type = c == WHILE? TWHILE: TUNTIL;
28172339Sabial		t->left = c_list();
28272339Sabial		t->right = dogroup(1);
28372339Sabial		t->words = NULL;
28472339Sabial		multiline--;
28572339Sabial		break;
28672339Sabial
28772339Sabial	case CASE:
28872339Sabial		t = newtp();
28972339Sabial		t->type = TCASE;
29072339Sabial		musthave(WORD, 0);
29172339Sabial		t->str = yylval.cp;
29272339Sabial		startl++;
29372339Sabial		multiline++;
29472339Sabial		musthave(IN, CONTIN);
29572339Sabial		startl++;
29672339Sabial		t->left = caselist();
29772339Sabial		musthave(ESAC, 0);
29872339Sabial		multiline--;
29972339Sabial		break;
30072339Sabial
30172339Sabial	case IF:
30272339Sabial		multiline++;
30372339Sabial		t = newtp();
30472339Sabial		t->type = TIF;
30572339Sabial		t->left = c_list();
30672339Sabial		t->right = thenpart();
30772339Sabial		musthave(FI, 0);
30872339Sabial		multiline--;
30972339Sabial		break;
31072339Sabial	}
31172339Sabial	while (synio(0))
31272339Sabial		;
31372339Sabial	t = namelist(t);
31472339Sabial	iolist = iosave;
31572339Sabial	return(t);
31672339Sabial}
31772339Sabial
31872339Sabialstatic struct op *
31972339Sabialdogroup(onlydone)
32072339Sabialint onlydone;
32172339Sabial{
32272339Sabial	register int c;
32372339Sabial	register struct op *list;
32472339Sabial
32572339Sabial	c = yylex(CONTIN);
32672339Sabial	if (c == DONE && onlydone)
32772339Sabial		return((struct op *)NULL);
32872339Sabial	if (c != DO)
32972339Sabial		SYNTAXERR;
33072339Sabial	list = c_list();
33172339Sabial	musthave(DONE, 0);
33272339Sabial	return(list);
33372339Sabial}
33472339Sabial
33572339Sabialstatic struct op *
33672339Sabialthenpart()
33772339Sabial{
33872339Sabial	register int c;
33972339Sabial	register struct op *t;
34072339Sabial
34172339Sabial	if ((c = yylex(0)) != THEN) {
34272339Sabial		peeksym = c;
34372339Sabial		return((struct op *)NULL);
34472339Sabial	}
34572339Sabial	t = newtp();
34672339Sabial	t->type = 0;
34772339Sabial	t->left = c_list();
34872339Sabial	if (t->left == NULL)
34972339Sabial		SYNTAXERR;
35072339Sabial	t->right = elsepart();
35172339Sabial	return(t);
35272339Sabial}
35372339Sabial
35472339Sabialstatic struct op *
35572339Sabialelsepart()
35672339Sabial{
35772339Sabial	register int c;
35872339Sabial	register struct op *t;
35972339Sabial
36072339Sabial	switch (c = yylex(0)) {
36172339Sabial	case ELSE:
36272339Sabial		if ((t = c_list()) == NULL)
36372339Sabial			SYNTAXERR;
36472339Sabial		return(t);
36572339Sabial
36672339Sabial	case ELIF:
36772339Sabial		t = newtp();
36872339Sabial		t->type = TELIF;
36972339Sabial		t->left = c_list();
37072339Sabial		t->right = thenpart();
37172339Sabial		return(t);
37272339Sabial
37372339Sabial	default:
37472339Sabial		peeksym = c;
37572339Sabial		return((struct op *)NULL);
37672339Sabial	}
37772339Sabial}
37872339Sabial
37972339Sabialstatic struct op *
38072339Sabialcaselist()
38172339Sabial{
38272339Sabial	register struct op *t;
38372339Sabial
38472339Sabial	t = NULL;
38572339Sabial	while ((peeksym = yylex(CONTIN)) != ESAC)
38672339Sabial		t = list(t, casepart());
38772339Sabial	return(t);
38872339Sabial}
38972339Sabial
39072339Sabialstatic struct op *
39172339Sabialcasepart()
39272339Sabial{
39372339Sabial	register struct op *t;
39472339Sabial
39572339Sabial	t = newtp();
39672339Sabial	t->type = TPAT;
39772339Sabial	t->words = pattern();
39872339Sabial	musthave(')', 0);
39972339Sabial	t->left = c_list();
40072339Sabial	if ((peeksym = yylex(CONTIN)) != ESAC)
40172339Sabial		musthave(BREAK, CONTIN);
40272339Sabial	return(t);
40372339Sabial}
40472339Sabial
40572339Sabialstatic char **
40672339Sabialpattern()
40772339Sabial{
40872339Sabial	register int c, cf;
40972339Sabial
41072339Sabial	cf = CONTIN;
41172339Sabial	do {
41272339Sabial		musthave(WORD, cf);
41372339Sabial		word(yylval.cp);
41472339Sabial		cf = 0;
41572339Sabial	} while ((c = yylex(0)) == '|');
41672339Sabial	peeksym = c;
41772339Sabial	word(NOWORD);
41872339Sabial	return(copyw());
41972339Sabial}
42072339Sabial
42172339Sabialstatic char **
42272339Sabialwordlist()
42372339Sabial{
42472339Sabial	register int c;
42572339Sabial
42672339Sabial	if ((c = yylex(0)) != IN) {
42772339Sabial		peeksym = c;
42872339Sabial		return((char **)NULL);
42972339Sabial	}
43072339Sabial	startl = 0;
43172339Sabial	while ((c = yylex(0)) == WORD)
43272339Sabial		word(yylval.cp);
43372339Sabial	word(NOWORD);
43472339Sabial	peeksym = c;
43572339Sabial	return(copyw());
43672339Sabial}
43772339Sabial
43872339Sabial/*
43972339Sabial * supporting functions
44072339Sabial */
44172339Sabialstatic struct op *
44272339Sabiallist(t1, t2)
44372339Sabialregister struct op *t1, *t2;
44472339Sabial{
44572339Sabial	if (t1 == NULL)
44672339Sabial		return(t2);
44772339Sabial	if (t2 == NULL)
44872339Sabial		return(t1);
44972339Sabial	return(block(TLIST, t1, t2, NOWORDS));
45072339Sabial}
45172339Sabial
45272339Sabialstatic struct op *
45372339Sabialblock(type, t1, t2, wp)
45472339Sabialint type;
45572339Sabialstruct op *t1, *t2;
45672339Sabialchar **wp;
45772339Sabial{
45872339Sabial	register struct op *t;
45972339Sabial
46072339Sabial	t = newtp();
46172339Sabial	t->type = type;
46272339Sabial	t->left = t1;
46372339Sabial	t->right = t2;
46472339Sabial	t->words = wp;
46572339Sabial	return(t);
46672339Sabial}
46772339Sabial
46872339Sabialstruct res {
46972339Sabial	char	*r_name;
47072339Sabial	int	r_val;
47172339Sabial} restab[] = {
47272339Sabial	"for",		FOR,
47372339Sabial	"case",		CASE,
47472339Sabial	"esac",		ESAC,
47572339Sabial	"while",	WHILE,
47672339Sabial	"do",		DO,
47772339Sabial	"done",		DONE,
47872339Sabial	"if",		IF,
47972339Sabial	"in",		IN,
48072339Sabial	"then",		THEN,
48172339Sabial	"else",		ELSE,
48272339Sabial	"elif",		ELIF,
48372339Sabial	"until",	UNTIL,
48472339Sabial	"fi",		FI,
48572339Sabial
48672339Sabial	";;",		BREAK,
48772339Sabial	"||",		LOGOR,
48872339Sabial	"&&",		LOGAND,
48972339Sabial	"{",		'{',
49072339Sabial	"}",		'}',
49172339Sabial
49272339Sabial	0,
49372339Sabial};
49472339Sabial
49572339Sabialint
49672339Sabialrlookup(n)
49772339Sabialregister char *n;
49872339Sabial{
49972339Sabial	register struct res *rp;
50072339Sabial
50172339Sabial	for (rp = restab; rp->r_name; rp++)
50272339Sabial		if (strcmp(rp->r_name, n) == 0)
50372339Sabial			return(rp->r_val);
50472339Sabial	return(0);
50572339Sabial}
50672339Sabial
50772339Sabialstatic struct op *
50872339Sabialnewtp()
50972339Sabial{
51072339Sabial	register struct op *t;
51172339Sabial
51272339Sabial	t = (struct op *)tree(sizeof(*t));
51372339Sabial	t->type = 0;
51472339Sabial	t->words = NULL;
51572339Sabial	t->ioact = NULL;
51672339Sabial	t->left = NULL;
51772339Sabial	t->right = NULL;
51872339Sabial	t->str = NULL;
51972339Sabial	return(t);
52072339Sabial}
52172339Sabial
52272339Sabialstatic struct op *
52372339Sabialnamelist(t)
52472339Sabialregister struct op *t;
52572339Sabial{
52672339Sabial	if (iolist) {
52772339Sabial		iolist = addword((char *)NULL, iolist);
52872339Sabial		t->ioact = copyio();
52972339Sabial	} else
53072339Sabial		t->ioact = NULL;
53172339Sabial	if (t->type != TCOM) {
53272339Sabial		if (t->type != TPAREN && t->ioact != NULL) {
53372339Sabial			t = block(TPAREN, t, NOBLOCK, NOWORDS);
53472339Sabial			t->ioact = t->left->ioact;
53572339Sabial			t->left->ioact = NULL;
53672339Sabial		}
53772339Sabial		return(t);
53872339Sabial	}
53972339Sabial	word(NOWORD);
54072339Sabial	t->words = copyw();
54172339Sabial	return(t);
54272339Sabial}
54372339Sabial
54472339Sabialstatic char **
54572339Sabialcopyw()
54672339Sabial{
54772339Sabial	register char **wd;
54872339Sabial
54972339Sabial	wd = getwords(wdlist);
55072339Sabial	wdlist = 0;
55172339Sabial	return(wd);
55272339Sabial}
55372339Sabial
55472339Sabialstatic void
55572339Sabialword(cp)
55672339Sabialchar *cp;
55772339Sabial{
55872339Sabial	wdlist = addword(cp, wdlist);
55972339Sabial}
56072339Sabial
56172339Sabialstatic struct ioword **
56272339Sabialcopyio()
56372339Sabial{
56472339Sabial	register struct ioword **iop;
56572339Sabial
56672339Sabial	iop = (struct ioword **) getwords(iolist);
56772339Sabial	iolist = 0;
56872339Sabial	return(iop);
56972339Sabial}
57072339Sabial
57172339Sabialstatic struct ioword *
57272339Sabialio(u, f, cp)
57372339Sabialint u;
57472339Sabialint f;
57572339Sabialchar *cp;
57672339Sabial{
57772339Sabial	register struct ioword *iop;
57872339Sabial
57972339Sabial	iop = (struct ioword *) tree(sizeof(*iop));
58072339Sabial	iop->io_unit = u;
58172339Sabial	iop->io_flag = f;
58272339Sabial	iop->io_name = cp;
58372339Sabial	iolist = addword((char *)iop, iolist);
58472339Sabial	return(iop);
58572339Sabial}
58672339Sabial
58772339Sabialstatic void
58872339Sabialzzerr()
58972339Sabial{
59072339Sabial	yyerror("syntax error");
59172339Sabial}
59272339Sabial
59372339Sabialvoid
59472339Sabialyyerror(s)
59572339Sabialchar *s;
59672339Sabial{
59772339Sabial	yynerrs++;
59872339Sabial	if (talking && e.iop <= iostack) {
59972339Sabial		multiline = 0;
60072339Sabial		while (eofc() == 0 && yylex(0) != '\n')
60172339Sabial			;
60272339Sabial	}
60372339Sabial	err(s);
60472339Sabial	fail();
60572339Sabial}
60672339Sabial
60772339Sabialstatic int
60872339Sabialyylex(cf)
60972339Sabialint cf;
61072339Sabial{
61172339Sabial	register int c, c1;
61272339Sabial	int atstart;
61372339Sabial
61472339Sabial	if ((c = peeksym) > 0) {
61572339Sabial		peeksym = 0;
61672339Sabial		if (c == '\n')
61772339Sabial			startl = 1;
61872339Sabial		return(c);
61972339Sabial	}
62072339Sabial	nlseen = 0;
62172339Sabial	e.linep = line;
62272339Sabial	atstart = startl;
62372339Sabial	startl = 0;
62472339Sabial	yylval.i = 0;
62572339Sabial
62672339Sabialloop:
62772339Sabial	while ((c = getc(0)) == ' ' || c == '\t')
62872339Sabial		;
62972339Sabial	switch (c) {
63072339Sabial	default:
63172339Sabial		if (any(c, "0123456789")) {
63272339Sabial			unget(c1 = getc(0));
63372339Sabial			if (c1 == '<' || c1 == '>') {
63472339Sabial				iounit = c - '0';
63572339Sabial				goto loop;
63672339Sabial			}
63772339Sabial			*e.linep++ = c;
63872339Sabial			c = c1;
63972339Sabial		}
64072339Sabial		break;
64172339Sabial
64272339Sabial	case '#':
64372339Sabial		while ((c = getc(0)) != 0 && c != '\n')
64472339Sabial			;
64572339Sabial		unget(c);
64672339Sabial		goto loop;
64772339Sabial
64872339Sabial	case 0:
64972339Sabial		return(c);
65072339Sabial
65172339Sabial	case '$':
65272339Sabial		*e.linep++ = c;
65372339Sabial		if ((c = getc(0)) == '{') {
65472339Sabial			if ((c = collect(c, '}')) != '\0')
65572339Sabial				return(c);
65672339Sabial			goto pack;
65772339Sabial		}
65872339Sabial		break;
65972339Sabial
66072339Sabial	case '`':
66172339Sabial	case '\'':
66272339Sabial	case '"':
66372339Sabial		if ((c = collect(c, c)) != '\0')
66472339Sabial			return(c);
66572339Sabial		goto pack;
66672339Sabial
66772339Sabial	case '|':
66872339Sabial	case '&':
66972339Sabial	case ';':
67072339Sabial		if ((c1 = dual(c)) != '\0') {
67172339Sabial			startl = 1;
67272339Sabial			return(c1);
67372339Sabial		}
67472339Sabial		startl = 1;
67572339Sabial		return(c);
67672339Sabial	case '^':
67772339Sabial		startl = 1;
67872339Sabial		return('|');
67972339Sabial	case '>':
68072339Sabial	case '<':
68172339Sabial		diag(c);
68272339Sabial		return(c);
68372339Sabial
68472339Sabial	case '\n':
68572339Sabial		nlseen++;
68672339Sabial		gethere();
68772339Sabial		startl = 1;
68872339Sabial		if (multiline || cf & CONTIN) {
68972339Sabial			if (talking && e.iop <= iostack)
69072339Sabial				prs(cprompt->value);
69172339Sabial			if (cf & CONTIN)
69272339Sabial				goto loop;
69372339Sabial		}
69472339Sabial		return(c);
69572339Sabial
69672339Sabial	case '(':
69772339Sabial	case ')':
69872339Sabial		startl = 1;
69972339Sabial		return(c);
70072339Sabial	}
70172339Sabial
70272339Sabial	unget(c);
70372339Sabial
70472339Sabialpack:
70572339Sabial	while ((c = getc(0)) != 0 && !any(c, "`$ '\"\t;&<>()|^\n"))
70672339Sabial		if (e.linep >= elinep)
70772339Sabial			err("word too long");
70872339Sabial		else
70972339Sabial			*e.linep++ = c;
71072339Sabial	unget(c);
71172339Sabial	if(any(c, "\"'`$"))
71272339Sabial		goto loop;
71372339Sabial	*e.linep++ = '\0';
71472339Sabial	if (atstart && (c = rlookup(line))!=0) {
71572339Sabial		startl = 1;
71672339Sabial		return(c);
71772339Sabial	}
71872339Sabial	yylval.cp = strsave(line, areanum);
71972339Sabial	return(WORD);
72072339Sabial}
72172339Sabial
72272339Sabialint
72372339Sabialcollect(c, c1)
72472339Sabialregister c, c1;
72572339Sabial{
72672339Sabial	char s[2];
72772339Sabial
72872339Sabial	*e.linep++ = c;
72972339Sabial	while ((c = getc(c1)) != c1) {
73072339Sabial		if (c == 0) {
73172339Sabial			unget(c);
73272339Sabial			s[0] = c1;
73372339Sabial			s[1] = 0;
73472339Sabial			prs("no closing "); yyerror(s);
73572339Sabial			return(YYERRCODE);
73672339Sabial		}
73772339Sabial		if (talking && c == '\n' && e.iop <= iostack)
73872339Sabial			prs(cprompt->value);
73972339Sabial		*e.linep++ = c;
74072339Sabial	}
74172339Sabial	*e.linep++ = c;
74272339Sabial	return(0);
74372339Sabial}
74472339Sabial
74572339Sabialint
74672339Sabialdual(c)
74772339Sabialregister c;
74872339Sabial{
74972339Sabial	char s[3];
75072339Sabial	register char *cp = s;
75172339Sabial
75272339Sabial	*cp++ = c;
75372339Sabial	*cp++ = getc(0);
75472339Sabial	*cp = 0;
75572339Sabial	if ((c = rlookup(s)) == 0)
75672339Sabial		unget(*--cp);
75772339Sabial	return(c);
75872339Sabial}
75972339Sabial
76072339Sabialstatic void
76172339Sabialdiag(ec)
76272339Sabialregister int ec;
76372339Sabial{
76472339Sabial	register int c;
76572339Sabial
76672339Sabial	c = getc(0);
76772339Sabial	if (c == '>' || c == '<') {
76872339Sabial		if (c != ec)
76972339Sabial			zzerr();
77072339Sabial		yylval.i = ec == '>'? IOWRITE|IOCAT: IOHERE;
77172339Sabial		c = getc(0);
77272339Sabial	} else
77372339Sabial		yylval.i = ec == '>'? IOWRITE: IOREAD;
77472339Sabial	if (c != '&' || yylval.i == IOHERE)
77572339Sabial		unget(c);
77672339Sabial	else
77772339Sabial		yylval.i |= IODUP;
77872339Sabial}
77972339Sabial
78072339Sabialstatic char *
78172339Sabialtree(size)
78272339Sabialunsigned size;
78372339Sabial{
78472339Sabial	register char *t;
78572339Sabial
78672339Sabial	if ((t = getcell(size)) == NULL) {
78772339Sabial		prs("command line too complicated\n");
78872339Sabial		fail();
78972339Sabial		/* NOTREACHED */
79072339Sabial	}
79172339Sabial	return(t);
79272339Sabial}
79372339Sabial
79472339Sabial/* VARARGS1 */
79572339Sabial/* ARGSUSED */
79672339Sabialvoid
79772339Sabialprintf(s)	/* yyparse calls it */
79872339Sabialchar *s;
79972339Sabial{
80072339Sabial}
80172339Sabial
802