1 /* $Header: /src/pub/tcsh/sh.parse.c,v 3.11 2002/03/08 17:36:46 christos Exp $ */
3 * sh.parse.c: Interpret a list of tokens
6 * Copyright (c) 1980, 1991 The Regents of the University of California.
9 * Redistribution and use in source and binary forms, with or without
10 * modification, are permitted provided that the following conditions
12 * 1. Redistributions of source code must retain the above copyright
13 * notice, this list of conditions and the following disclaimer.
14 * 2. Redistributions in binary form must reproduce the above copyright
15 * notice, this list of conditions and the following disclaimer in the
16 * documentation and/or other materials provided with the distribution.
17 * 3. Neither the name of the University nor the names of its contributors
18 * may be used to endorse or promote products derived from this software
19 * without specific prior written permission.
21 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
22 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
25 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
35 RCSID("$Id: sh.parse.c,v 3.11 2002/03/08 17:36:46 christos Exp $")
40 static void asyntax __P((struct wordent *, struct wordent *));
41 static void asyn0 __P((struct wordent *, struct wordent *));
42 static void asyn3 __P((struct wordent *, struct wordent *));
43 static struct wordent *freenod __P((struct wordent *, struct wordent *));
44 static struct command *syn0 __P((struct wordent *, struct wordent *, int));
45 static struct command *syn1 __P((struct wordent *, struct wordent *, int));
46 static struct command *syn1a __P((struct wordent *, struct wordent *, int));
47 static struct command *syn1b __P((struct wordent *, struct wordent *, int));
48 static struct command *syn2 __P((struct wordent *, struct wordent *, int));
49 static struct command *syn3 __P((struct wordent *, struct wordent *, int));
51 #define ALEFT 51 /* max of 50 alias expansions */
52 #define HLEFT 11 /* max of 10 history expansions */
54 * Perform aliasing on the word list lexp
55 * Do a (very rudimentary) parse to separate into commands.
56 * If word 0 of a command has an alias, do it.
57 * Repeat a maximum of 50 times.
63 register struct wordent *lexp;
76 stderror(ERR_ALIASLOOP);
77 asyntax(lexp->next, lexp);
83 register struct wordent *p1, *p2;
86 if (any(";&\n", p1->word[0]))
97 register struct wordent *p2;
99 register struct wordent *p;
102 for (p = p1; p != p2; p = p->next)
103 switch (p->word[0]) {
112 stderror(ERR_TOOMANYRP);
116 if (p->next != p2 && eq(p->next->word, STRand))
127 asyntax(p->next, p2);
140 register struct wordent *p2;
142 register struct varent *ap;
143 struct wordent alout;
148 if (p1->word[0] == '(') {
149 for (p2 = p2->prev; p2->word[0] != ')'; p2 = p2->prev)
157 ap = adrof1(p1->word, &aliases);
164 alhistp = alhistt = 0;
170 if (p1->word[0] && eq(p1->word, alout.next->word)) {
171 Char *cp = alout.next->word;
173 alout.next->word = Strspl(STRQNULL, cp);
176 p1 = freenod(p1, redid ? p2 : p1->next);
177 if (alout.next != &alout) {
178 p1->next->prev = alout.prev->prev;
179 alout.prev->prev->next = p1->next;
180 alout.next->prev = p1;
181 p1->next = alout.next;
182 xfree((ptr_t) alout.prev->word);
183 xfree((ptr_t) (alout.prev));
185 reset(); /* throw! */
188 static struct wordent *
190 register struct wordent *p1, *p2;
192 register struct wordent *retp = p1->prev;
195 xfree((ptr_t) p1->word);
197 xfree((ptr_t) (p1->prev));
215 syntax(p1, p2, flags)
216 register struct wordent *p1, *p2;
221 if (any(";&\n", p1->word[0]))
224 return (syn0(p1, p2, flags));
233 static struct command *
235 struct wordent *p1, *p2;
238 register struct wordent *p;
239 register struct command *t, *t1;
243 for (p = p1; p != p2; p = p->next)
244 switch (p->word[0]) {
253 seterror(ERR_TOOMANYRP);
257 if (p->word[1] == '|')
262 if (p->next != p2 && eq(p->next->word, STRand))
269 if (p->word[1] == '&')
271 t1 = syn1(p1, p, flags);
272 if (t1->t_dtyp == NODE_LIST ||
273 t1->t_dtyp == NODE_AND ||
274 t1->t_dtyp == NODE_OR) {
275 t = (struct command *) xcalloc(1, sizeof(*t));
276 t->t_dtyp = NODE_PAREN;
277 t->t_dflg = F_AMPERSAND | F_NOINTERRUPT;
282 t1->t_dflg |= F_AMPERSAND | F_NOINTERRUPT;
283 t = (struct command *) xcalloc(1, sizeof(*t));
284 t->t_dtyp = NODE_LIST;
287 t->t_dcdr = syntax(p, p2, flags);
293 return (syn1(p1, p2, flags));
294 seterror(ERR_TOOMANYLP);
303 static struct command *
305 struct wordent *p1, *p2;
308 register struct wordent *p;
309 register struct command *t;
313 for (p = p1; p != p2; p = p->next)
314 switch (p->word[0]) {
328 t = (struct command *) xcalloc(1, sizeof(*t));
329 t->t_dtyp = NODE_LIST;
330 t->t_dcar = syn1a(p1, p, flags);
331 t->t_dcdr = syntax(p->next, p2, flags);
333 t->t_dcdr = t->t_dcar, t->t_dcar = 0;
339 return (syn1a(p1, p2, flags));
347 static struct command *
349 struct wordent *p1, *p2;
352 register struct wordent *p;
353 register struct command *t;
356 for (p = p1; p != p2; p = p->next)
357 switch (p->word[0]) {
368 if (p->word[1] != '|')
371 t = (struct command *) xcalloc(1, sizeof(*t));
373 t->t_dcar = syn1b(p1, p, flags);
374 t->t_dcdr = syn1a(p->next, p2, flags);
383 return (syn1b(p1, p2, flags));
391 static struct command *
393 struct wordent *p1, *p2;
396 register struct wordent *p;
397 register struct command *t;
400 for (p = p1; p != p2; p = p->next)
401 switch (p->word[0]) {
412 if (p->word[1] == '&' && l == 0) {
413 t = (struct command *) xcalloc(1, sizeof(*t));
414 t->t_dtyp = NODE_AND;
415 t->t_dcar = syn2(p1, p, flags);
416 t->t_dcdr = syn1b(p->next, p2, flags);
425 return (syn2(p1, p2, flags));
434 static struct command *
436 struct wordent *p1, *p2;
439 register struct wordent *p, *pn;
440 register struct command *t;
444 for (p = p1; p != p2; p = p->next)
445 switch (p->word[0]) {
458 t = (struct command *) xcalloc(1, sizeof(*t));
461 if (pn != p2 && pn->word[0] == '&') {
463 t->t_dflg |= F_STDERR;
465 t->t_dtyp = NODE_PIPE;
466 t->t_dcar = syn3(p1, p, f);
467 if (pn != p2 && pn->word[0] == '&')
469 t->t_dcdr = syn2(p->next, p2, flags | P_IN);
475 return (syn3(p1, p2, flags));
478 static char RELPAR[] = {'<', '>', '(', ')', '\0'};
482 * ( syn0 ) [ < in ] [ > out ]
483 * word word* [ < in ] [ > out ]
484 * KEYWORD ( word* ) word* [ < in ] [ > out ]
486 * KEYWORD = (@ exit foreach if set switch test while)
488 static struct command *
490 struct wordent *p1, *p2;
493 register struct wordent *p;
494 struct wordent *lp, *rp;
495 register struct command *t;
504 switch (srchx(p->word)) {
527 for (p = p1; p != p2; p = p->next)
528 switch (p->word[0]) {
551 if (any(RELPAR, p->next->word[0]))
557 if (!specp && l != 0)
564 t = (struct command *) xcalloc(1, sizeof(*t));
565 av = (Char **) xcalloc((size_t) (n + 1), sizeof(Char **));
568 if (p2->word[0] == ')')
569 t->t_dflg = F_NOFORK;
573 for (p = p1; p != p2; p = p->next) {
579 if (lp != 0 && !specp)
580 seterror(ERR_BADPLP);
595 if (p->word[1] == '>')
596 t->t_dflg |= F_APPEND;
597 if (p->next != p2 && eq(p->next->word, STRand)) {
598 t->t_dflg |= F_STDERR, p = p->next;
599 if (flags & (P_OUT | P_DIAG)) {
600 seterror(ERR_OUTRED);
604 if (p->next != p2 && eq(p->next->word, STRbang))
605 t->t_dflg |= F_OVERWRITE, p = p->next;
607 seterror(ERR_MISRED);
611 if (any(RELPAR, p->word[0])) {
612 seterror(ERR_MISRED);
615 if (((flags & P_OUT) && (flags & P_DIAG) == 0) || t->t_drit)
616 seterror(ERR_OUTRED);
618 t->t_drit = Strsave(p->word);
624 if (p->word[1] == '<')
627 seterror(ERR_MISRED);
631 if (any(RELPAR, p->word[0])) {
632 seterror(ERR_MISRED);
635 if ((flags & P_HERE) && (t->t_dflg & F_READ))
636 seterror(ERR_REDPAR);
637 else if ((flags & P_IN) || t->t_dlef)
640 t->t_dlef = Strsave(p->word);
647 if (l != 0 && !specp)
650 av[n] = Strsave(p->word);
655 if (lp != 0 && !specp) {
657 seterror(ERR_BADPLPS);
658 t->t_dtyp = NODE_PAREN;
659 t->t_dspr = syn0(lp, rp, P_HERE);
663 seterror(ERR_NULLCOM);
664 t->t_dtyp = NODE_COMMAND;
671 register struct command *t;
680 for (v = t->t_dcom; *v; v++)
682 xfree((ptr_t) (t->t_dcom));
683 xfree((ptr_t) t->t_dlef);
684 xfree((ptr_t) t->t_drit);
688 xfree((ptr_t) t->t_dlef);
689 xfree((ptr_t) t->t_drit);
696 freesyn(t->t_dcar), freesyn(t->t_dcdr);