xref: /csrg-svn/bin/csh/parse.c (revision 17511)
1*17511Sedward #ifndef lint
2*17511Sedward static	char *sccsid = "@(#)parse.c	4.2 (Berkeley) 12/13/84";
3*17511Sedward #endif
41301Sbill 
51301Sbill #include "sh.h"
61301Sbill 
71301Sbill /*
81301Sbill  * C shell
91301Sbill  */
101301Sbill 
111301Sbill /*
121301Sbill  * Perform aliasing on the word list lex
131301Sbill  * Do a (very rudimentary) parse to separate into commands.
141301Sbill  * If word 0 of a command has an alias, do it.
151301Sbill  * Repeat a maximum of 20 times.
161301Sbill  */
171301Sbill alias(lex)
181301Sbill 	register struct wordent *lex;
191301Sbill {
201301Sbill 	int aleft = 21;
211301Sbill 	jmp_buf osetexit;
221301Sbill 
231301Sbill 	getexit(osetexit);
241301Sbill 	setexit();
251301Sbill 	if (haderr) {
261301Sbill 		resexit(osetexit);
271301Sbill 		reset();
281301Sbill 	}
291301Sbill 	if (--aleft == 0)
301301Sbill 		error("Alias loop");
311301Sbill 	asyntax(lex->next, lex);
321301Sbill 	resexit(osetexit);
331301Sbill }
341301Sbill 
351301Sbill asyntax(p1, p2)
361301Sbill 	register struct wordent *p1, *p2;
371301Sbill {
381301Sbill 
391301Sbill 	while (p1 != p2)
401301Sbill 		if (any(p1->word[0], ";&\n"))
411301Sbill 			p1 = p1->next;
421301Sbill 		else {
431301Sbill 			asyn0(p1, p2);
441301Sbill 			return;
451301Sbill 		}
461301Sbill }
471301Sbill 
481301Sbill asyn0(p1, p2)
491301Sbill 	struct wordent *p1;
501301Sbill 	register struct wordent *p2;
511301Sbill {
521301Sbill 	register struct wordent *p;
531301Sbill 	register int l = 0;
541301Sbill 
551301Sbill 	for (p = p1; p != p2; p = p->next)
561301Sbill 		switch (p->word[0]) {
571301Sbill 
581301Sbill 		case '(':
591301Sbill 			l++;
601301Sbill 			continue;
611301Sbill 
621301Sbill 		case ')':
631301Sbill 			l--;
641301Sbill 			if (l < 0)
651301Sbill 				error("Too many )'s");
661301Sbill 			continue;
671301Sbill 
681301Sbill 		case '>':
691301Sbill 			if (p->next != p2 && eq(p->next->word, "&"))
701301Sbill 				p = p->next;
711301Sbill 			continue;
721301Sbill 
731301Sbill 		case '&':
741301Sbill 		case '|':
751301Sbill 		case ';':
761301Sbill 		case '\n':
771301Sbill 			if (l != 0)
781301Sbill 				continue;
791301Sbill 			asyn3(p1, p);
801301Sbill 			asyntax(p->next, p2);
811301Sbill 			return;
821301Sbill 		}
831301Sbill 	if (l == 0)
841301Sbill 		asyn3(p1, p2);
851301Sbill }
861301Sbill 
871301Sbill asyn3(p1, p2)
881301Sbill 	struct wordent *p1;
891301Sbill 	register struct wordent *p2;
901301Sbill {
911301Sbill 	register struct varent *ap;
921301Sbill 	struct wordent alout;
931301Sbill 	register bool redid;
941301Sbill 
951301Sbill 	if (p1 == p2)
961301Sbill 		return;
971301Sbill 	if (p1->word[0] == '(') {
981301Sbill 		for (p2 = p2->prev; p2->word[0] != ')'; p2 = p2->prev)
991301Sbill 			if (p2 == p1)
1001301Sbill 				return;
1011301Sbill 		if (p2 == p1->next)
1021301Sbill 			return;
1031301Sbill 		asyn0(p1->next, p2);
1041301Sbill 		return;
1051301Sbill 	}
1061301Sbill 	ap = adrof1(p1->word, &aliases);
1071301Sbill 	if (ap == 0)
1081301Sbill 		return;
1091301Sbill 	alhistp = p1->prev;
1101301Sbill 	alhistt = p2;
1111301Sbill 	alvec = ap->vec;
1121301Sbill 	redid = lex(&alout);
1131301Sbill 	alhistp = alhistt = 0;
1141301Sbill 	alvec = 0;
1151301Sbill 	if (err) {
1161301Sbill 		freelex(&alout);
1171301Sbill 		error(err);
1181301Sbill 	}
1191301Sbill 	if (p1->word[0] && eq(p1->word, alout.next->word)) {
1201301Sbill 		char *cp = alout.next->word;
1211301Sbill 
1221301Sbill 		alout.next->word = strspl("\200", cp);
123*17511Sedward 		XFREE(cp)
1241301Sbill 	}
1251301Sbill 	p1 = freenod(p1, redid ? p2 : p1->next);
1261301Sbill 	if (alout.next != &alout) {
1271301Sbill 		p1->next->prev = alout.prev->prev;
1281301Sbill 		alout.prev->prev->next = p1->next;
1291301Sbill 		alout.next->prev = p1;
1301301Sbill 		p1->next = alout.next;
131*17511Sedward 		XFREE(alout.prev->word)
132*17511Sedward 		XFREE((char *)alout.prev)
1331301Sbill 	}
1341301Sbill 	reset();		/* throw! */
1351301Sbill }
1361301Sbill 
1371301Sbill struct wordent *
1381301Sbill freenod(p1, p2)
1391301Sbill 	register struct wordent *p1, *p2;
1401301Sbill {
1411301Sbill 	register struct wordent *retp = p1->prev;
1421301Sbill 
1431301Sbill 	while (p1 != p2) {
144*17511Sedward 		XFREE(p1->word)
1451301Sbill 		p1 = p1->next;
146*17511Sedward 		XFREE((char *)p1->prev)
1471301Sbill 	}
1481301Sbill 	retp->next = p2;
1491301Sbill 	p2->prev = retp;
1501301Sbill 	return (retp);
1511301Sbill }
1521301Sbill 
1531301Sbill #define	PHERE	1
1541301Sbill #define	PIN	2
1551301Sbill #define	POUT	4
1561301Sbill #define	PDIAG	8
1571301Sbill 
1581301Sbill /*
1591301Sbill  * syntax
1601301Sbill  *	empty
1611301Sbill  *	syn0
1621301Sbill  */
1631301Sbill struct command *
1641301Sbill syntax(p1, p2, flags)
1651301Sbill 	register struct wordent *p1, *p2;
1661301Sbill 	int flags;
1671301Sbill {
1681301Sbill 
1691301Sbill 	while (p1 != p2)
1701301Sbill 		if (any(p1->word[0], ";&\n"))
1711301Sbill 			p1 = p1->next;
1721301Sbill 		else
1731301Sbill 			return (syn0(p1, p2, flags));
1741301Sbill 	return (0);
1751301Sbill }
1761301Sbill 
1771301Sbill /*
1781301Sbill  * syn0
1791301Sbill  *	syn1
1801301Sbill  *	syn1 & syntax
1811301Sbill  */
1821301Sbill struct command *
1831301Sbill syn0(p1, p2, flags)
1841301Sbill 	struct wordent *p1, *p2;
1851301Sbill 	int flags;
1861301Sbill {
1871301Sbill 	register struct wordent *p;
1881301Sbill 	register struct command *t, *t1;
1891301Sbill 	int l;
1901301Sbill 
1911301Sbill 	l = 0;
1921301Sbill 	for (p = p1; p != p2; p = p->next)
1931301Sbill 		switch (p->word[0]) {
1941301Sbill 
1951301Sbill 		case '(':
1961301Sbill 			l++;
1971301Sbill 			continue;
1981301Sbill 
1991301Sbill 		case ')':
2001301Sbill 			l--;
2011301Sbill 			if (l < 0)
2021301Sbill 				seterr("Too many )'s");
2031301Sbill 			continue;
2041301Sbill 
2051301Sbill 		case '|':
2061301Sbill 			if (p->word[1] == '|')
2071301Sbill 				continue;
2081301Sbill 			/* fall into ... */
2091301Sbill 
2101301Sbill 		case '>':
2111301Sbill 			if (p->next != p2 && eq(p->next->word, "&"))
2121301Sbill 				p = p->next;
2131301Sbill 			continue;
2141301Sbill 
2151301Sbill 		case '&':
2161301Sbill 			if (l != 0)
2171301Sbill 				break;
2181301Sbill 			if (p->word[1] == '&')
2191301Sbill 				continue;
2201301Sbill 			t1 = syn1(p1, p, flags);
2211301Sbill 			if (t1->t_dtyp == TLST) {
2221301Sbill 				t = (struct command *) calloc(1, sizeof (*t));
2231301Sbill 				t->t_dtyp = TPAR;
2241301Sbill 				t->t_dflg = FAND|FINT;
2251301Sbill 				t->t_dspr = t1;
2261301Sbill 				t1 = t;
2271301Sbill 			} else
2281301Sbill 				t1->t_dflg |= FAND|FINT;
2291301Sbill 			t = (struct command *) calloc(1, sizeof (*t));
2301301Sbill 			t->t_dtyp = TLST;
2311301Sbill 			t->t_dflg = 0;
2321301Sbill 			t->t_dcar = t1;
2331301Sbill 			t->t_dcdr = syntax(p, p2, flags);
2341301Sbill 			return(t);
2351301Sbill 		}
2361301Sbill 	if (l == 0)
2371301Sbill 		return (syn1(p1, p2, flags));
2381301Sbill 	seterr("Too many ('s");
2391301Sbill 	return (0);
2401301Sbill }
2411301Sbill 
2421301Sbill /*
2431301Sbill  * syn1
2441301Sbill  *	syn1a
2451301Sbill  *	syn1a ; syntax
2461301Sbill  */
2471301Sbill struct command *
2481301Sbill syn1(p1, p2, flags)
2491301Sbill 	struct wordent *p1, *p2;
2501301Sbill 	int flags;
2511301Sbill {
2521301Sbill 	register struct wordent *p;
2531301Sbill 	register struct command *t;
2541301Sbill 	int l;
2551301Sbill 
2561301Sbill 	l = 0;
2571301Sbill 	for (p = p1; p != p2; p = p->next)
2581301Sbill 		switch (p->word[0]) {
2591301Sbill 
2601301Sbill 		case '(':
2611301Sbill 			l++;
2621301Sbill 			continue;
2631301Sbill 
2641301Sbill 		case ')':
2651301Sbill 			l--;
2661301Sbill 			continue;
2671301Sbill 
2681301Sbill 		case ';':
2691301Sbill 		case '\n':
2701301Sbill 			if (l != 0)
2711301Sbill 				break;
2721301Sbill 			t = (struct command *) calloc(1, sizeof (*t));
2731301Sbill 			t->t_dtyp = TLST;
2741301Sbill 			t->t_dcar = syn1a(p1, p, flags);
2751301Sbill 			t->t_dcdr = syntax(p->next, p2, flags);
2761301Sbill 			if (t->t_dcdr == 0)
2771301Sbill 				t->t_dcdr = t->t_dcar, t->t_dcar = 0;
2781301Sbill 			return (t);
2791301Sbill 		}
2801301Sbill 	return (syn1a(p1, p2, flags));
2811301Sbill }
2821301Sbill 
2831301Sbill /*
2841301Sbill  * syn1a
2851301Sbill  *	syn1b
2861301Sbill  *	syn1b || syn1a
2871301Sbill  */
2881301Sbill struct command *
2891301Sbill syn1a(p1, p2, flags)
2901301Sbill 	struct wordent *p1, *p2;
2911301Sbill 	int flags;
2921301Sbill {
2931301Sbill 	register struct wordent *p;
2941301Sbill 	register struct command *t;
2951301Sbill 	register int l = 0;
2961301Sbill 
2971301Sbill 	for (p = p1; p != p2; p = p->next)
2981301Sbill 		switch (p->word[0]) {
2991301Sbill 
3001301Sbill 		case '(':
3011301Sbill 			l++;
3021301Sbill 			continue;
3031301Sbill 
3041301Sbill 		case ')':
3051301Sbill 			l--;
3061301Sbill 			continue;
3071301Sbill 
3081301Sbill 		case '|':
3091301Sbill 			if (p->word[1] != '|')
3101301Sbill 				continue;
3111301Sbill 			if (l == 0) {
3121301Sbill 				t = (struct command *) calloc(1, sizeof (*t));
3131301Sbill 				t->t_dtyp = TOR;
3141301Sbill 				t->t_dcar = syn1b(p1, p, flags);
3151301Sbill 				t->t_dcdr = syn1a(p->next, p2, flags);
3161301Sbill 				t->t_dflg = 0;
3171301Sbill 				return (t);
3181301Sbill 			}
3191301Sbill 			continue;
3201301Sbill 		}
3211301Sbill 	return (syn1b(p1, p2, flags));
3221301Sbill }
3231301Sbill 
3241301Sbill /*
3251301Sbill  * syn1b
3261301Sbill  *	syn2
3271301Sbill  *	syn2 && syn1b
3281301Sbill  */
3291301Sbill struct command *
3301301Sbill syn1b(p1, p2, flags)
3311301Sbill 	struct wordent *p1, *p2;
3321301Sbill 	int flags;
3331301Sbill {
3341301Sbill 	register struct wordent *p;
3351301Sbill 	register struct command *t;
3361301Sbill 	register int l = 0;
3371301Sbill 
3381301Sbill 	l = 0;
3391301Sbill 	for (p = p1; p != p2; p = p->next)
3401301Sbill 		switch (p->word[0]) {
3411301Sbill 
3421301Sbill 		case '(':
3431301Sbill 			l++;
3441301Sbill 			continue;
3451301Sbill 
3461301Sbill 		case ')':
3471301Sbill 			l--;
3481301Sbill 			continue;
3491301Sbill 
3501301Sbill 		case '&':
3511301Sbill 			if (p->word[1] == '&' && l == 0) {
3521301Sbill 				t = (struct command *) calloc(1, sizeof (*t));
3531301Sbill 				t->t_dtyp = TAND;
3541301Sbill 				t->t_dcar = syn2(p1, p, flags);
3551301Sbill 				t->t_dcdr = syn1b(p->next, p2, flags);
3561301Sbill 				t->t_dflg = 0;
3571301Sbill 				return (t);
3581301Sbill 			}
3591301Sbill 			continue;
3601301Sbill 		}
3611301Sbill 	return (syn2(p1, p2, flags));
3621301Sbill }
3631301Sbill 
3641301Sbill /*
3651301Sbill  * syn2
3661301Sbill  *	syn3
3671301Sbill  *	syn3 | syn2
3681301Sbill  *	syn3 |& syn2
3691301Sbill  */
3701301Sbill struct command *
3711301Sbill syn2(p1, p2, flags)
3721301Sbill 	struct wordent *p1, *p2;
3731301Sbill 	int flags;
3741301Sbill {
3751301Sbill 	register struct wordent *p, *pn;
3761301Sbill 	register struct command *t;
3771301Sbill 	register int l = 0;
3781301Sbill 	int f;
3791301Sbill 
3801301Sbill 	for (p = p1; p != p2; p = p->next)
3811301Sbill 		switch (p->word[0]) {
3821301Sbill 
3831301Sbill 		case '(':
3841301Sbill 			l++;
3851301Sbill 			continue;
3861301Sbill 
3871301Sbill 		case ')':
3881301Sbill 			l--;
3891301Sbill 			continue;
3901301Sbill 
3911301Sbill 		case '|':
3921301Sbill 			if (l != 0)
3931301Sbill 				continue;
3941301Sbill 			t = (struct command *) calloc(1, sizeof (*t));
3951301Sbill 			f = flags | POUT;
3961301Sbill 			pn = p->next;
3971301Sbill 			if (pn != p2 && pn->word[0] == '&') {
3981301Sbill 				f |= PDIAG;
3991301Sbill 				t->t_dflg |= FDIAG;
4001301Sbill 			}
4011301Sbill 			t->t_dtyp = TFIL;
4021301Sbill 			t->t_dcar = syn3(p1, p, f);
4031301Sbill 			if (pn != p2 && pn->word[0] == '&')
4041301Sbill 				p = pn;
4051301Sbill 			t->t_dcdr = syn2(p->next, p2, flags | PIN);
4061301Sbill 			return (t);
4071301Sbill 		}
4081301Sbill 	return (syn3(p1, p2, flags));
4091301Sbill }
4101301Sbill 
4111301Sbill char	*RELPAR =	"<>()";
4121301Sbill 
4131301Sbill /*
4141301Sbill  * syn3
4151301Sbill  *	( syn0 ) [ < in  ] [ > out ]
4161301Sbill  *	word word* [ < in ] [ > out ]
4171301Sbill  *	KEYWORD ( word* ) word* [ < in ] [ > out ]
4181301Sbill  *
4191301Sbill  *	KEYWORD = (@ exit foreach if set switch test while)
4201301Sbill  */
4211301Sbill struct command *
4221301Sbill syn3(p1, p2, flags)
4231301Sbill 	struct wordent *p1, *p2;
4241301Sbill 	int flags;
4251301Sbill {
4261301Sbill 	register struct wordent *p;
4271301Sbill 	struct wordent *lp, *rp;
4281301Sbill 	register struct command *t;
4291301Sbill 	register int l;
4301301Sbill 	char **av;
4311301Sbill 	int n, c;
4321301Sbill 	bool specp = 0;
4331301Sbill 
4341301Sbill 	if (p1 != p2) {
4351301Sbill 		p = p1;
4361301Sbill again:
4371301Sbill 		switch (srchx(p->word)) {
4381301Sbill 
4391301Sbill 		case ZELSE:
4401301Sbill 			p = p->next;
4411301Sbill 			if (p != p2)
4421301Sbill 				goto again;
4431301Sbill 			break;
4441301Sbill 
4451301Sbill 		case ZEXIT:
4461301Sbill 		case ZFOREACH:
4471301Sbill 		case ZIF:
4481301Sbill 		case ZLET:
4491301Sbill 		case ZSET:
4501301Sbill 		case ZSWITCH:
4511301Sbill 		case ZWHILE:
4521301Sbill 			specp = 1;
4531301Sbill 			break;
4541301Sbill 		}
4551301Sbill 	}
4561301Sbill 	n = 0;
4571301Sbill 	l = 0;
4581301Sbill 	for (p = p1; p != p2; p = p->next)
4591301Sbill 		switch (p->word[0]) {
4601301Sbill 
4611301Sbill 		case '(':
4621301Sbill 			if (specp)
4631301Sbill 				n++;
4641301Sbill 			l++;
4651301Sbill 			continue;
4661301Sbill 
4671301Sbill 		case ')':
4681301Sbill 			if (specp)
4691301Sbill 				n++;
4701301Sbill 			l--;
4711301Sbill 			continue;
4721301Sbill 
4731301Sbill 		case '>':
4741301Sbill 		case '<':
4751301Sbill 			if (l != 0) {
4761301Sbill 				if (specp)
4771301Sbill 					n++;
4781301Sbill 				continue;
4791301Sbill 			}
4801301Sbill 			if (p->next == p2)
4811301Sbill 				continue;
4821301Sbill 			if (any(p->next->word[0], RELPAR))
4831301Sbill 				continue;
4841301Sbill 			n--;
4851301Sbill 			continue;
4861301Sbill 
4871301Sbill 		default:
4881301Sbill 			if (!specp && l != 0)
4891301Sbill 				continue;
4901301Sbill 			n++;
4911301Sbill 			continue;
4921301Sbill 		}
4931301Sbill 	if (n < 0)
4941301Sbill 		n = 0;
4951301Sbill 	t = (struct command *) calloc(1, sizeof (*t));
496*17511Sedward 	av = (char **) calloc((unsigned) (n + 1), sizeof (char **));
4971301Sbill 	t->t_dcom = av;
4981301Sbill 	n = 0;
4991301Sbill 	if (p2->word[0] == ')')
5001301Sbill 		t->t_dflg = FPAR;
5011301Sbill 	lp = 0;
5021301Sbill 	rp = 0;
5031301Sbill 	l = 0;
5041301Sbill 	for (p = p1; p != p2; p = p->next) {
5051301Sbill 		c = p->word[0];
5061301Sbill 		switch (c) {
5071301Sbill 
5081301Sbill 		case '(':
5091301Sbill 			if (l == 0) {
5101301Sbill 				if (lp != 0 && !specp)
5111301Sbill 					seterr("Badly placed (");
5121301Sbill 				lp = p->next;
5131301Sbill 			}
5141301Sbill 			l++;
5151301Sbill 			goto savep;
5161301Sbill 
5171301Sbill 		case ')':
5181301Sbill 			l--;
5191301Sbill 			if (l == 0)
5201301Sbill 				rp = p;
5211301Sbill 			goto savep;
5221301Sbill 
5231301Sbill 		case '>':
5241301Sbill 			if (l != 0)
5251301Sbill 				goto savep;
5261301Sbill 			if (p->word[1] == '>')
5271301Sbill 				t->t_dflg |= FCAT;
5281301Sbill 			if (p->next != p2 && eq(p->next->word, "&")) {
5291301Sbill 				t->t_dflg |= FDIAG, p = p->next;
5301301Sbill 				if (flags & (POUT|PDIAG))
5311301Sbill 					goto badout;
5321301Sbill 			}
5331301Sbill 			if (p->next != p2 && eq(p->next->word, "!"))
5341301Sbill 				t->t_dflg |= FANY, p = p->next;
5351301Sbill 			if (p->next == p2) {
5361301Sbill missfile:
5371301Sbill 				seterr("Missing name for redirect");
5381301Sbill 				continue;
5391301Sbill 			}
5401301Sbill 			p = p->next;
5411301Sbill 			if (any(p->word[0], RELPAR))
5421301Sbill 				goto missfile;
5431301Sbill 			if ((flags & POUT) && (flags & PDIAG) == 0 || t->t_drit)
5441301Sbill badout:
5451301Sbill 				seterr("Ambiguous output redirect");
5461301Sbill 			else
5471301Sbill 				t->t_drit = savestr(p->word);
5481301Sbill 			continue;
5491301Sbill 
5501301Sbill 		case '<':
5511301Sbill 			if (l != 0)
5521301Sbill 				goto savep;
5531301Sbill 			if (p->word[1] == '<')
5541301Sbill 				t->t_dflg |= FHERE;
5551301Sbill 			if (p->next == p2)
5561301Sbill 				goto missfile;
5571301Sbill 			p = p->next;
5581301Sbill 			if (any(p->word[0], RELPAR))
5591301Sbill 				goto missfile;
5601301Sbill 			if ((flags & PHERE) && (t->t_dflg & FHERE))
5611301Sbill 				seterr("Can't << within ()'s");
5621301Sbill 			else if ((flags & PIN) || t->t_dlef)
5631301Sbill 				seterr("Ambiguous input redirect");
5641301Sbill 			else
5651301Sbill 				t->t_dlef = savestr(p->word);
5661301Sbill 			continue;
5671301Sbill 
5681301Sbill savep:
5691301Sbill 			if (!specp)
5701301Sbill 				continue;
5711301Sbill 		default:
5721301Sbill 			if (l != 0 && !specp)
5731301Sbill 				continue;
5741301Sbill 			if (err == 0)
5751301Sbill 				av[n] = savestr(p->word);
5761301Sbill 			n++;
5771301Sbill 			continue;
5781301Sbill 		}
5791301Sbill 	}
5801301Sbill 	if (lp != 0 && !specp) {
5811301Sbill 		if (n != 0)
5821301Sbill 			seterr("Badly placed ()'s");
5831301Sbill 		t->t_dtyp = TPAR;
5841301Sbill 		t->t_dspr = syn0(lp, rp, PHERE);
5851301Sbill 	} else {
5861301Sbill 		if (n == 0)
5871301Sbill 			seterr("Invalid null command");
5881301Sbill 		t->t_dtyp = TCOM;
5891301Sbill 	}
5901301Sbill 	return (t);
5911301Sbill }
5921301Sbill 
5931301Sbill freesyn(t)
5941301Sbill 	register struct command *t;
5951301Sbill {
5961301Sbill 	register char **v;
5971301Sbill 
5981301Sbill 	if (t == 0)
5991301Sbill 		return;
6001301Sbill 	switch (t->t_dtyp) {
6011301Sbill 
6021301Sbill 	case TCOM:
6031301Sbill 		for (v = t->t_dcom; *v; v++)
604*17511Sedward 			XFREE(*v)
605*17511Sedward 		XFREE((char *)t->t_dcom)
6061301Sbill 		goto lr;
6071301Sbill 
6081301Sbill 	case TPAR:
6091301Sbill 		freesyn(t->t_dspr);
6101301Sbill 		/* fall into ... */
6111301Sbill 
6121301Sbill lr:
613*17511Sedward 		XFREE(t->t_dlef)
614*17511Sedward 		XFREE(t->t_drit)
6151301Sbill 		break;
6161301Sbill 
6171301Sbill 	case TAND:
6181301Sbill 	case TOR:
6191301Sbill 	case TFIL:
6201301Sbill 	case TLST:
6211301Sbill 		freesyn(t->t_dcar), freesyn(t->t_dcdr);
6221301Sbill 		break;
6231301Sbill 	}
624*17511Sedward 	XFREE((char *)t)
6251301Sbill }
626