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