xref: /original-bsd/bin/csh/parse.c (revision 81f6297c)
1 /*
2  * Copyright (c) 1980 Regents of the University of California.
3  * All rights reserved.  The Berkeley software License Agreement
4  * specifies the terms and conditions for redistribution.
5  */
6 
7 #ifndef lint
8 static char sccsid[] = "@(#)parse.c	5.1 (Berkeley) 06/04/85";
9 #endif not lint
10 
11 #include "sh.h"
12 
13 /*
14  * C shell
15  */
16 
17 /*
18  * Perform aliasing on the word list lex
19  * Do a (very rudimentary) parse to separate into commands.
20  * If word 0 of a command has an alias, do it.
21  * Repeat a maximum of 20 times.
22  */
23 alias(lex)
24 	register struct wordent *lex;
25 {
26 	int aleft = 21;
27 	jmp_buf osetexit;
28 
29 	getexit(osetexit);
30 	setexit();
31 	if (haderr) {
32 		resexit(osetexit);
33 		reset();
34 	}
35 	if (--aleft == 0)
36 		error("Alias loop");
37 	asyntax(lex->next, lex);
38 	resexit(osetexit);
39 }
40 
41 asyntax(p1, p2)
42 	register struct wordent *p1, *p2;
43 {
44 
45 	while (p1 != p2)
46 		if (any(p1->word[0], ";&\n"))
47 			p1 = p1->next;
48 		else {
49 			asyn0(p1, p2);
50 			return;
51 		}
52 }
53 
54 asyn0(p1, p2)
55 	struct wordent *p1;
56 	register struct wordent *p2;
57 {
58 	register struct wordent *p;
59 	register int l = 0;
60 
61 	for (p = p1; p != p2; p = p->next)
62 		switch (p->word[0]) {
63 
64 		case '(':
65 			l++;
66 			continue;
67 
68 		case ')':
69 			l--;
70 			if (l < 0)
71 				error("Too many )'s");
72 			continue;
73 
74 		case '>':
75 			if (p->next != p2 && eq(p->next->word, "&"))
76 				p = p->next;
77 			continue;
78 
79 		case '&':
80 		case '|':
81 		case ';':
82 		case '\n':
83 			if (l != 0)
84 				continue;
85 			asyn3(p1, p);
86 			asyntax(p->next, p2);
87 			return;
88 		}
89 	if (l == 0)
90 		asyn3(p1, p2);
91 }
92 
93 asyn3(p1, p2)
94 	struct wordent *p1;
95 	register struct wordent *p2;
96 {
97 	register struct varent *ap;
98 	struct wordent alout;
99 	register bool redid;
100 
101 	if (p1 == p2)
102 		return;
103 	if (p1->word[0] == '(') {
104 		for (p2 = p2->prev; p2->word[0] != ')'; p2 = p2->prev)
105 			if (p2 == p1)
106 				return;
107 		if (p2 == p1->next)
108 			return;
109 		asyn0(p1->next, p2);
110 		return;
111 	}
112 	ap = adrof1(p1->word, &aliases);
113 	if (ap == 0)
114 		return;
115 	alhistp = p1->prev;
116 	alhistt = p2;
117 	alvec = ap->vec;
118 	redid = lex(&alout);
119 	alhistp = alhistt = 0;
120 	alvec = 0;
121 	if (err) {
122 		freelex(&alout);
123 		error(err);
124 	}
125 	if (p1->word[0] && eq(p1->word, alout.next->word)) {
126 		char *cp = alout.next->word;
127 
128 		alout.next->word = strspl("\200", cp);
129 		XFREE(cp)
130 	}
131 	p1 = freenod(p1, redid ? p2 : p1->next);
132 	if (alout.next != &alout) {
133 		p1->next->prev = alout.prev->prev;
134 		alout.prev->prev->next = p1->next;
135 		alout.next->prev = p1;
136 		p1->next = alout.next;
137 		XFREE(alout.prev->word)
138 		XFREE((char *)alout.prev)
139 	}
140 	reset();		/* throw! */
141 }
142 
143 struct wordent *
144 freenod(p1, p2)
145 	register struct wordent *p1, *p2;
146 {
147 	register struct wordent *retp = p1->prev;
148 
149 	while (p1 != p2) {
150 		XFREE(p1->word)
151 		p1 = p1->next;
152 		XFREE((char *)p1->prev)
153 	}
154 	retp->next = p2;
155 	p2->prev = retp;
156 	return (retp);
157 }
158 
159 #define	PHERE	1
160 #define	PIN	2
161 #define	POUT	4
162 #define	PDIAG	8
163 
164 /*
165  * syntax
166  *	empty
167  *	syn0
168  */
169 struct command *
170 syntax(p1, p2, flags)
171 	register struct wordent *p1, *p2;
172 	int flags;
173 {
174 
175 	while (p1 != p2)
176 		if (any(p1->word[0], ";&\n"))
177 			p1 = p1->next;
178 		else
179 			return (syn0(p1, p2, flags));
180 	return (0);
181 }
182 
183 /*
184  * syn0
185  *	syn1
186  *	syn1 & syntax
187  */
188 struct command *
189 syn0(p1, p2, flags)
190 	struct wordent *p1, *p2;
191 	int flags;
192 {
193 	register struct wordent *p;
194 	register struct command *t, *t1;
195 	int l;
196 
197 	l = 0;
198 	for (p = p1; p != p2; p = p->next)
199 		switch (p->word[0]) {
200 
201 		case '(':
202 			l++;
203 			continue;
204 
205 		case ')':
206 			l--;
207 			if (l < 0)
208 				seterr("Too many )'s");
209 			continue;
210 
211 		case '|':
212 			if (p->word[1] == '|')
213 				continue;
214 			/* fall into ... */
215 
216 		case '>':
217 			if (p->next != p2 && eq(p->next->word, "&"))
218 				p = p->next;
219 			continue;
220 
221 		case '&':
222 			if (l != 0)
223 				break;
224 			if (p->word[1] == '&')
225 				continue;
226 			t1 = syn1(p1, p, flags);
227 			if (t1->t_dtyp == TLST) {
228 				t = (struct command *) calloc(1, sizeof (*t));
229 				t->t_dtyp = TPAR;
230 				t->t_dflg = FAND|FINT;
231 				t->t_dspr = t1;
232 				t1 = t;
233 			} else
234 				t1->t_dflg |= FAND|FINT;
235 			t = (struct command *) calloc(1, sizeof (*t));
236 			t->t_dtyp = TLST;
237 			t->t_dflg = 0;
238 			t->t_dcar = t1;
239 			t->t_dcdr = syntax(p, p2, flags);
240 			return(t);
241 		}
242 	if (l == 0)
243 		return (syn1(p1, p2, flags));
244 	seterr("Too many ('s");
245 	return (0);
246 }
247 
248 /*
249  * syn1
250  *	syn1a
251  *	syn1a ; syntax
252  */
253 struct command *
254 syn1(p1, p2, flags)
255 	struct wordent *p1, *p2;
256 	int flags;
257 {
258 	register struct wordent *p;
259 	register struct command *t;
260 	int l;
261 
262 	l = 0;
263 	for (p = p1; p != p2; p = p->next)
264 		switch (p->word[0]) {
265 
266 		case '(':
267 			l++;
268 			continue;
269 
270 		case ')':
271 			l--;
272 			continue;
273 
274 		case ';':
275 		case '\n':
276 			if (l != 0)
277 				break;
278 			t = (struct command *) calloc(1, sizeof (*t));
279 			t->t_dtyp = TLST;
280 			t->t_dcar = syn1a(p1, p, flags);
281 			t->t_dcdr = syntax(p->next, p2, flags);
282 			if (t->t_dcdr == 0)
283 				t->t_dcdr = t->t_dcar, t->t_dcar = 0;
284 			return (t);
285 		}
286 	return (syn1a(p1, p2, flags));
287 }
288 
289 /*
290  * syn1a
291  *	syn1b
292  *	syn1b || syn1a
293  */
294 struct command *
295 syn1a(p1, p2, flags)
296 	struct wordent *p1, *p2;
297 	int flags;
298 {
299 	register struct wordent *p;
300 	register struct command *t;
301 	register int l = 0;
302 
303 	for (p = p1; p != p2; p = p->next)
304 		switch (p->word[0]) {
305 
306 		case '(':
307 			l++;
308 			continue;
309 
310 		case ')':
311 			l--;
312 			continue;
313 
314 		case '|':
315 			if (p->word[1] != '|')
316 				continue;
317 			if (l == 0) {
318 				t = (struct command *) calloc(1, sizeof (*t));
319 				t->t_dtyp = TOR;
320 				t->t_dcar = syn1b(p1, p, flags);
321 				t->t_dcdr = syn1a(p->next, p2, flags);
322 				t->t_dflg = 0;
323 				return (t);
324 			}
325 			continue;
326 		}
327 	return (syn1b(p1, p2, flags));
328 }
329 
330 /*
331  * syn1b
332  *	syn2
333  *	syn2 && syn1b
334  */
335 struct command *
336 syn1b(p1, p2, flags)
337 	struct wordent *p1, *p2;
338 	int flags;
339 {
340 	register struct wordent *p;
341 	register struct command *t;
342 	register int l = 0;
343 
344 	l = 0;
345 	for (p = p1; p != p2; p = p->next)
346 		switch (p->word[0]) {
347 
348 		case '(':
349 			l++;
350 			continue;
351 
352 		case ')':
353 			l--;
354 			continue;
355 
356 		case '&':
357 			if (p->word[1] == '&' && l == 0) {
358 				t = (struct command *) calloc(1, sizeof (*t));
359 				t->t_dtyp = TAND;
360 				t->t_dcar = syn2(p1, p, flags);
361 				t->t_dcdr = syn1b(p->next, p2, flags);
362 				t->t_dflg = 0;
363 				return (t);
364 			}
365 			continue;
366 		}
367 	return (syn2(p1, p2, flags));
368 }
369 
370 /*
371  * syn2
372  *	syn3
373  *	syn3 | syn2
374  *	syn3 |& syn2
375  */
376 struct command *
377 syn2(p1, p2, flags)
378 	struct wordent *p1, *p2;
379 	int flags;
380 {
381 	register struct wordent *p, *pn;
382 	register struct command *t;
383 	register int l = 0;
384 	int f;
385 
386 	for (p = p1; p != p2; p = p->next)
387 		switch (p->word[0]) {
388 
389 		case '(':
390 			l++;
391 			continue;
392 
393 		case ')':
394 			l--;
395 			continue;
396 
397 		case '|':
398 			if (l != 0)
399 				continue;
400 			t = (struct command *) calloc(1, sizeof (*t));
401 			f = flags | POUT;
402 			pn = p->next;
403 			if (pn != p2 && pn->word[0] == '&') {
404 				f |= PDIAG;
405 				t->t_dflg |= FDIAG;
406 			}
407 			t->t_dtyp = TFIL;
408 			t->t_dcar = syn3(p1, p, f);
409 			if (pn != p2 && pn->word[0] == '&')
410 				p = pn;
411 			t->t_dcdr = syn2(p->next, p2, flags | PIN);
412 			return (t);
413 		}
414 	return (syn3(p1, p2, flags));
415 }
416 
417 char	*RELPAR =	"<>()";
418 
419 /*
420  * syn3
421  *	( syn0 ) [ < in  ] [ > out ]
422  *	word word* [ < in ] [ > out ]
423  *	KEYWORD ( word* ) word* [ < in ] [ > out ]
424  *
425  *	KEYWORD = (@ exit foreach if set switch test while)
426  */
427 struct command *
428 syn3(p1, p2, flags)
429 	struct wordent *p1, *p2;
430 	int flags;
431 {
432 	register struct wordent *p;
433 	struct wordent *lp, *rp;
434 	register struct command *t;
435 	register int l;
436 	char **av;
437 	int n, c;
438 	bool specp = 0;
439 
440 	if (p1 != p2) {
441 		p = p1;
442 again:
443 		switch (srchx(p->word)) {
444 
445 		case ZELSE:
446 			p = p->next;
447 			if (p != p2)
448 				goto again;
449 			break;
450 
451 		case ZEXIT:
452 		case ZFOREACH:
453 		case ZIF:
454 		case ZLET:
455 		case ZSET:
456 		case ZSWITCH:
457 		case ZWHILE:
458 			specp = 1;
459 			break;
460 		}
461 	}
462 	n = 0;
463 	l = 0;
464 	for (p = p1; p != p2; p = p->next)
465 		switch (p->word[0]) {
466 
467 		case '(':
468 			if (specp)
469 				n++;
470 			l++;
471 			continue;
472 
473 		case ')':
474 			if (specp)
475 				n++;
476 			l--;
477 			continue;
478 
479 		case '>':
480 		case '<':
481 			if (l != 0) {
482 				if (specp)
483 					n++;
484 				continue;
485 			}
486 			if (p->next == p2)
487 				continue;
488 			if (any(p->next->word[0], RELPAR))
489 				continue;
490 			n--;
491 			continue;
492 
493 		default:
494 			if (!specp && l != 0)
495 				continue;
496 			n++;
497 			continue;
498 		}
499 	if (n < 0)
500 		n = 0;
501 	t = (struct command *) calloc(1, sizeof (*t));
502 	av = (char **) calloc((unsigned) (n + 1), sizeof (char **));
503 	t->t_dcom = av;
504 	n = 0;
505 	if (p2->word[0] == ')')
506 		t->t_dflg = FPAR;
507 	lp = 0;
508 	rp = 0;
509 	l = 0;
510 	for (p = p1; p != p2; p = p->next) {
511 		c = p->word[0];
512 		switch (c) {
513 
514 		case '(':
515 			if (l == 0) {
516 				if (lp != 0 && !specp)
517 					seterr("Badly placed (");
518 				lp = p->next;
519 			}
520 			l++;
521 			goto savep;
522 
523 		case ')':
524 			l--;
525 			if (l == 0)
526 				rp = p;
527 			goto savep;
528 
529 		case '>':
530 			if (l != 0)
531 				goto savep;
532 			if (p->word[1] == '>')
533 				t->t_dflg |= FCAT;
534 			if (p->next != p2 && eq(p->next->word, "&")) {
535 				t->t_dflg |= FDIAG, p = p->next;
536 				if (flags & (POUT|PDIAG))
537 					goto badout;
538 			}
539 			if (p->next != p2 && eq(p->next->word, "!"))
540 				t->t_dflg |= FANY, p = p->next;
541 			if (p->next == p2) {
542 missfile:
543 				seterr("Missing name for redirect");
544 				continue;
545 			}
546 			p = p->next;
547 			if (any(p->word[0], RELPAR))
548 				goto missfile;
549 			if ((flags & POUT) && (flags & PDIAG) == 0 || t->t_drit)
550 badout:
551 				seterr("Ambiguous output redirect");
552 			else
553 				t->t_drit = savestr(p->word);
554 			continue;
555 
556 		case '<':
557 			if (l != 0)
558 				goto savep;
559 			if (p->word[1] == '<')
560 				t->t_dflg |= FHERE;
561 			if (p->next == p2)
562 				goto missfile;
563 			p = p->next;
564 			if (any(p->word[0], RELPAR))
565 				goto missfile;
566 			if ((flags & PHERE) && (t->t_dflg & FHERE))
567 				seterr("Can't << within ()'s");
568 			else if ((flags & PIN) || t->t_dlef)
569 				seterr("Ambiguous input redirect");
570 			else
571 				t->t_dlef = savestr(p->word);
572 			continue;
573 
574 savep:
575 			if (!specp)
576 				continue;
577 		default:
578 			if (l != 0 && !specp)
579 				continue;
580 			if (err == 0)
581 				av[n] = savestr(p->word);
582 			n++;
583 			continue;
584 		}
585 	}
586 	if (lp != 0 && !specp) {
587 		if (n != 0)
588 			seterr("Badly placed ()'s");
589 		t->t_dtyp = TPAR;
590 		t->t_dspr = syn0(lp, rp, PHERE);
591 	} else {
592 		if (n == 0)
593 			seterr("Invalid null command");
594 		t->t_dtyp = TCOM;
595 	}
596 	return (t);
597 }
598 
599 freesyn(t)
600 	register struct command *t;
601 {
602 	register char **v;
603 
604 	if (t == 0)
605 		return;
606 	switch (t->t_dtyp) {
607 
608 	case TCOM:
609 		for (v = t->t_dcom; *v; v++)
610 			XFREE(*v)
611 		XFREE((char *)t->t_dcom)
612 		goto lr;
613 
614 	case TPAR:
615 		freesyn(t->t_dspr);
616 		/* fall into ... */
617 
618 lr:
619 		XFREE(t->t_dlef)
620 		XFREE(t->t_drit)
621 		break;
622 
623 	case TAND:
624 	case TOR:
625 	case TFIL:
626 	case TLST:
627 		freesyn(t->t_dcar), freesyn(t->t_dcdr);
628 		break;
629 	}
630 	XFREE((char *)t)
631 }
632