xref: /original-bsd/bin/csh/parse.c (revision 2301fdfb)
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.3 (Berkeley) 05/13/86";
9 #endif
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     			    t1->t_dtyp == TAND ||
229     			    t1->t_dtyp == TOR) {
230 				t = (struct command *) calloc(1, sizeof (*t));
231 				t->t_dtyp = TPAR;
232 				t->t_dflg = FAND|FINT;
233 				t->t_dspr = t1;
234 				t1 = t;
235 			} else
236 				t1->t_dflg |= FAND|FINT;
237 			t = (struct command *) calloc(1, sizeof (*t));
238 			t->t_dtyp = TLST;
239 			t->t_dflg = 0;
240 			t->t_dcar = t1;
241 			t->t_dcdr = syntax(p, p2, flags);
242 			return(t);
243 		}
244 	if (l == 0)
245 		return (syn1(p1, p2, flags));
246 	seterr("Too many ('s");
247 	return (0);
248 }
249 
250 /*
251  * syn1
252  *	syn1a
253  *	syn1a ; syntax
254  */
255 struct command *
256 syn1(p1, p2, flags)
257 	struct wordent *p1, *p2;
258 	int flags;
259 {
260 	register struct wordent *p;
261 	register struct command *t;
262 	int l;
263 
264 	l = 0;
265 	for (p = p1; p != p2; p = p->next)
266 		switch (p->word[0]) {
267 
268 		case '(':
269 			l++;
270 			continue;
271 
272 		case ')':
273 			l--;
274 			continue;
275 
276 		case ';':
277 		case '\n':
278 			if (l != 0)
279 				break;
280 			t = (struct command *) calloc(1, sizeof (*t));
281 			t->t_dtyp = TLST;
282 			t->t_dcar = syn1a(p1, p, flags);
283 			t->t_dcdr = syntax(p->next, p2, flags);
284 			if (t->t_dcdr == 0)
285 				t->t_dcdr = t->t_dcar, t->t_dcar = 0;
286 			return (t);
287 		}
288 	return (syn1a(p1, p2, flags));
289 }
290 
291 /*
292  * syn1a
293  *	syn1b
294  *	syn1b || syn1a
295  */
296 struct command *
297 syn1a(p1, p2, flags)
298 	struct wordent *p1, *p2;
299 	int flags;
300 {
301 	register struct wordent *p;
302 	register struct command *t;
303 	register int l = 0;
304 
305 	for (p = p1; p != p2; p = p->next)
306 		switch (p->word[0]) {
307 
308 		case '(':
309 			l++;
310 			continue;
311 
312 		case ')':
313 			l--;
314 			continue;
315 
316 		case '|':
317 			if (p->word[1] != '|')
318 				continue;
319 			if (l == 0) {
320 				t = (struct command *) calloc(1, sizeof (*t));
321 				t->t_dtyp = TOR;
322 				t->t_dcar = syn1b(p1, p, flags);
323 				t->t_dcdr = syn1a(p->next, p2, flags);
324 				t->t_dflg = 0;
325 				return (t);
326 			}
327 			continue;
328 		}
329 	return (syn1b(p1, p2, flags));
330 }
331 
332 /*
333  * syn1b
334  *	syn2
335  *	syn2 && syn1b
336  */
337 struct command *
338 syn1b(p1, p2, flags)
339 	struct wordent *p1, *p2;
340 	int flags;
341 {
342 	register struct wordent *p;
343 	register struct command *t;
344 	register int l = 0;
345 
346 	l = 0;
347 	for (p = p1; p != p2; p = p->next)
348 		switch (p->word[0]) {
349 
350 		case '(':
351 			l++;
352 			continue;
353 
354 		case ')':
355 			l--;
356 			continue;
357 
358 		case '&':
359 			if (p->word[1] == '&' && l == 0) {
360 				t = (struct command *) calloc(1, sizeof (*t));
361 				t->t_dtyp = TAND;
362 				t->t_dcar = syn2(p1, p, flags);
363 				t->t_dcdr = syn1b(p->next, p2, flags);
364 				t->t_dflg = 0;
365 				return (t);
366 			}
367 			continue;
368 		}
369 	return (syn2(p1, p2, flags));
370 }
371 
372 /*
373  * syn2
374  *	syn3
375  *	syn3 | syn2
376  *	syn3 |& syn2
377  */
378 struct command *
379 syn2(p1, p2, flags)
380 	struct wordent *p1, *p2;
381 	int flags;
382 {
383 	register struct wordent *p, *pn;
384 	register struct command *t;
385 	register int l = 0;
386 	int f;
387 
388 	for (p = p1; p != p2; p = p->next)
389 		switch (p->word[0]) {
390 
391 		case '(':
392 			l++;
393 			continue;
394 
395 		case ')':
396 			l--;
397 			continue;
398 
399 		case '|':
400 			if (l != 0)
401 				continue;
402 			t = (struct command *) calloc(1, sizeof (*t));
403 			f = flags | POUT;
404 			pn = p->next;
405 			if (pn != p2 && pn->word[0] == '&') {
406 				f |= PDIAG;
407 				t->t_dflg |= FDIAG;
408 			}
409 			t->t_dtyp = TFIL;
410 			t->t_dcar = syn3(p1, p, f);
411 			if (pn != p2 && pn->word[0] == '&')
412 				p = pn;
413 			t->t_dcdr = syn2(p->next, p2, flags | PIN);
414 			return (t);
415 		}
416 	return (syn3(p1, p2, flags));
417 }
418 
419 char	*RELPAR =	"<>()";
420 
421 /*
422  * syn3
423  *	( syn0 ) [ < in  ] [ > out ]
424  *	word word* [ < in ] [ > out ]
425  *	KEYWORD ( word* ) word* [ < in ] [ > out ]
426  *
427  *	KEYWORD = (@ exit foreach if set switch test while)
428  */
429 struct command *
430 syn3(p1, p2, flags)
431 	struct wordent *p1, *p2;
432 	int flags;
433 {
434 	register struct wordent *p;
435 	struct wordent *lp, *rp;
436 	register struct command *t;
437 	register int l;
438 	char **av;
439 	int n, c;
440 	bool specp = 0;
441 
442 	if (p1 != p2) {
443 		p = p1;
444 again:
445 		switch (srchx(p->word)) {
446 
447 		case ZELSE:
448 			p = p->next;
449 			if (p != p2)
450 				goto again;
451 			break;
452 
453 		case ZEXIT:
454 		case ZFOREACH:
455 		case ZIF:
456 		case ZLET:
457 		case ZSET:
458 		case ZSWITCH:
459 		case ZWHILE:
460 			specp = 1;
461 			break;
462 		}
463 	}
464 	n = 0;
465 	l = 0;
466 	for (p = p1; p != p2; p = p->next)
467 		switch (p->word[0]) {
468 
469 		case '(':
470 			if (specp)
471 				n++;
472 			l++;
473 			continue;
474 
475 		case ')':
476 			if (specp)
477 				n++;
478 			l--;
479 			continue;
480 
481 		case '>':
482 		case '<':
483 			if (l != 0) {
484 				if (specp)
485 					n++;
486 				continue;
487 			}
488 			if (p->next == p2)
489 				continue;
490 			if (any(p->next->word[0], RELPAR))
491 				continue;
492 			n--;
493 			continue;
494 
495 		default:
496 			if (!specp && l != 0)
497 				continue;
498 			n++;
499 			continue;
500 		}
501 	if (n < 0)
502 		n = 0;
503 	t = (struct command *) calloc(1, sizeof (*t));
504 	av = (char **) calloc((unsigned) (n + 1), sizeof (char **));
505 	t->t_dcom = av;
506 	n = 0;
507 	if (p2->word[0] == ')')
508 		t->t_dflg = FPAR;
509 	lp = 0;
510 	rp = 0;
511 	l = 0;
512 	for (p = p1; p != p2; p = p->next) {
513 		c = p->word[0];
514 		switch (c) {
515 
516 		case '(':
517 			if (l == 0) {
518 				if (lp != 0 && !specp)
519 					seterr("Badly placed (");
520 				lp = p->next;
521 			}
522 			l++;
523 			goto savep;
524 
525 		case ')':
526 			l--;
527 			if (l == 0)
528 				rp = p;
529 			goto savep;
530 
531 		case '>':
532 			if (l != 0)
533 				goto savep;
534 			if (p->word[1] == '>')
535 				t->t_dflg |= FCAT;
536 			if (p->next != p2 && eq(p->next->word, "&")) {
537 				t->t_dflg |= FDIAG, p = p->next;
538 				if (flags & (POUT|PDIAG))
539 					goto badout;
540 			}
541 			if (p->next != p2 && eq(p->next->word, "!"))
542 				t->t_dflg |= FANY, p = p->next;
543 			if (p->next == p2) {
544 missfile:
545 				seterr("Missing name for redirect");
546 				continue;
547 			}
548 			p = p->next;
549 			if (any(p->word[0], RELPAR))
550 				goto missfile;
551 			if ((flags & POUT) && (flags & PDIAG) == 0 || t->t_drit)
552 badout:
553 				seterr("Ambiguous output redirect");
554 			else
555 				t->t_drit = savestr(p->word);
556 			continue;
557 
558 		case '<':
559 			if (l != 0)
560 				goto savep;
561 			if (p->word[1] == '<')
562 				t->t_dflg |= FHERE;
563 			if (p->next == p2)
564 				goto missfile;
565 			p = p->next;
566 			if (any(p->word[0], RELPAR))
567 				goto missfile;
568 			if ((flags & PHERE) && (t->t_dflg & FHERE))
569 				seterr("Can't << within ()'s");
570 			else if ((flags & PIN) || t->t_dlef)
571 				seterr("Ambiguous input redirect");
572 			else
573 				t->t_dlef = savestr(p->word);
574 			continue;
575 
576 savep:
577 			if (!specp)
578 				continue;
579 		default:
580 			if (l != 0 && !specp)
581 				continue;
582 			if (err == 0)
583 				av[n] = savestr(p->word);
584 			n++;
585 			continue;
586 		}
587 	}
588 	if (lp != 0 && !specp) {
589 		if (n != 0)
590 			seterr("Badly placed ()'s");
591 		t->t_dtyp = TPAR;
592 		t->t_dspr = syn0(lp, rp, PHERE);
593 	} else {
594 		if (n == 0)
595 			seterr("Invalid null command");
596 		t->t_dtyp = TCOM;
597 	}
598 	return (t);
599 }
600 
601 freesyn(t)
602 	register struct command *t;
603 {
604 	register char **v;
605 
606 	if (t == 0)
607 		return;
608 	switch (t->t_dtyp) {
609 
610 	case TCOM:
611 		for (v = t->t_dcom; *v; v++)
612 			XFREE(*v)
613 		XFREE((char *)t->t_dcom)
614 		goto lr;
615 
616 	case TPAR:
617 		freesyn(t->t_dspr);
618 		/* fall into ... */
619 
620 lr:
621 		XFREE(t->t_dlef)
622 		XFREE(t->t_drit)
623 		break;
624 
625 	case TAND:
626 	case TOR:
627 	case TFIL:
628 	case TLST:
629 		freesyn(t->t_dcar), freesyn(t->t_dcdr);
630 		break;
631 	}
632 	XFREE((char *)t)
633 }
634