xref: /plan9/sys/src/cmd/rc/tree.c (revision 276e7d6d7cdb63857b1620e0d4a2158cfb236504)
13e12c5d1SDavid du Colombier #include "rc.h"
23e12c5d1SDavid du Colombier #include "exec.h"
33e12c5d1SDavid du Colombier #include "io.h"
43e12c5d1SDavid du Colombier #include "fns.h"
53e12c5d1SDavid du Colombier tree *treenodes;
63e12c5d1SDavid du Colombier /*
73e12c5d1SDavid du Colombier  * create and clear a new tree node, and add it
83e12c5d1SDavid du Colombier  * to the node list.
93e12c5d1SDavid du Colombier  */
10dc5a79c1SDavid du Colombier 
11dc5a79c1SDavid du Colombier tree*
newtree(void)12dc5a79c1SDavid du Colombier newtree(void)
13dc5a79c1SDavid du Colombier {
143e12c5d1SDavid du Colombier 	tree *t = new(tree);
153e12c5d1SDavid du Colombier 	t->iskw = 0;
163e12c5d1SDavid du Colombier 	t->str = 0;
173e12c5d1SDavid du Colombier 	t->child[0] = t->child[1] = t->child[2] = 0;
183e12c5d1SDavid du Colombier 	t->next = treenodes;
193e12c5d1SDavid du Colombier 	treenodes = t;
203e12c5d1SDavid du Colombier 	return t;
213e12c5d1SDavid du Colombier }
22dc5a79c1SDavid du Colombier 
23dc5a79c1SDavid du Colombier void
freenodes(void)24dc5a79c1SDavid du Colombier freenodes(void)
25dc5a79c1SDavid du Colombier {
263e12c5d1SDavid du Colombier 	tree *t, *u;
273e12c5d1SDavid du Colombier 	for(t = treenodes;t;t = u){
283e12c5d1SDavid du Colombier 		u = t->next;
29dc5a79c1SDavid du Colombier 		if(t->str)
30dc5a79c1SDavid du Colombier 			efree(t->str);
313e12c5d1SDavid du Colombier 		efree((char *)t);
323e12c5d1SDavid du Colombier 	}
333e12c5d1SDavid du Colombier 	treenodes = 0;
343e12c5d1SDavid du Colombier }
35dc5a79c1SDavid du Colombier 
36dc5a79c1SDavid du Colombier tree*
tree1(int type,tree * c0)37dc5a79c1SDavid du Colombier tree1(int type, tree *c0)
383e12c5d1SDavid du Colombier {
393e12c5d1SDavid du Colombier 	return tree3(type, c0, (tree *)0, (tree *)0);
403e12c5d1SDavid du Colombier }
41dc5a79c1SDavid du Colombier 
42dc5a79c1SDavid du Colombier tree*
tree2(int type,tree * c0,tree * c1)43dc5a79c1SDavid du Colombier tree2(int type, tree *c0, tree *c1)
443e12c5d1SDavid du Colombier {
453e12c5d1SDavid du Colombier 	return tree3(type, c0, c1, (tree *)0);
463e12c5d1SDavid du Colombier }
47dc5a79c1SDavid du Colombier 
48dc5a79c1SDavid du Colombier tree*
tree3(int type,tree * c0,tree * c1,tree * c2)49dc5a79c1SDavid du Colombier tree3(int type, tree *c0, tree *c1, tree *c2)
503e12c5d1SDavid du Colombier {
513e12c5d1SDavid du Colombier 	tree *t;
523e12c5d1SDavid du Colombier 	if(type==';'){
53dc5a79c1SDavid du Colombier 		if(c0==0)
54dc5a79c1SDavid du Colombier 			return c1;
55dc5a79c1SDavid du Colombier 		if(c1==0)
56dc5a79c1SDavid du Colombier 			return c0;
573e12c5d1SDavid du Colombier 	}
583e12c5d1SDavid du Colombier 	t = newtree();
593e12c5d1SDavid du Colombier 	t->type = type;
603e12c5d1SDavid du Colombier 	t->child[0] = c0;
613e12c5d1SDavid du Colombier 	t->child[1] = c1;
623e12c5d1SDavid du Colombier 	t->child[2] = c2;
633e12c5d1SDavid du Colombier 	return t;
643e12c5d1SDavid du Colombier }
65dc5a79c1SDavid du Colombier 
66dc5a79c1SDavid du Colombier tree*
mung1(tree * t,tree * c0)67dc5a79c1SDavid du Colombier mung1(tree *t, tree *c0)
683e12c5d1SDavid du Colombier {
693e12c5d1SDavid du Colombier 	t->child[0] = c0;
703e12c5d1SDavid du Colombier 	return t;
713e12c5d1SDavid du Colombier }
72dc5a79c1SDavid du Colombier 
73dc5a79c1SDavid du Colombier tree*
mung2(tree * t,tree * c0,tree * c1)74dc5a79c1SDavid du Colombier mung2(tree *t, tree *c0, tree *c1)
753e12c5d1SDavid du Colombier {
763e12c5d1SDavid du Colombier 	t->child[0] = c0;
773e12c5d1SDavid du Colombier 	t->child[1] = c1;
783e12c5d1SDavid du Colombier 	return t;
793e12c5d1SDavid du Colombier }
80dc5a79c1SDavid du Colombier 
81dc5a79c1SDavid du Colombier tree*
mung3(tree * t,tree * c0,tree * c1,tree * c2)82dc5a79c1SDavid du Colombier mung3(tree *t, tree *c0, tree *c1, tree *c2)
833e12c5d1SDavid du Colombier {
843e12c5d1SDavid du Colombier 	t->child[0] = c0;
853e12c5d1SDavid du Colombier 	t->child[1] = c1;
863e12c5d1SDavid du Colombier 	t->child[2] = c2;
873e12c5d1SDavid du Colombier 	return t;
883e12c5d1SDavid du Colombier }
89dc5a79c1SDavid du Colombier 
90dc5a79c1SDavid du Colombier tree*
epimung(tree * comp,tree * epi)91dc5a79c1SDavid du Colombier epimung(tree *comp, tree *epi)
923e12c5d1SDavid du Colombier {
933e12c5d1SDavid du Colombier 	tree *p;
94dc5a79c1SDavid du Colombier 	if(epi==0)
95dc5a79c1SDavid du Colombier 		return comp;
963e12c5d1SDavid du Colombier 	for(p = epi;p->child[1];p = p->child[1]);
973e12c5d1SDavid du Colombier 	p->child[1] = comp;
983e12c5d1SDavid du Colombier 	return epi;
993e12c5d1SDavid du Colombier }
1003e12c5d1SDavid du Colombier /*
1013e12c5d1SDavid du Colombier  * Add a SIMPLE node at the root of t and percolate all the redirections
1023e12c5d1SDavid du Colombier  * up to the root.
1033e12c5d1SDavid du Colombier  */
104dc5a79c1SDavid du Colombier 
105dc5a79c1SDavid du Colombier tree*
simplemung(tree * t)106dc5a79c1SDavid du Colombier simplemung(tree *t)
1073e12c5d1SDavid du Colombier {
1083e12c5d1SDavid du Colombier 	tree *u;
1093e12c5d1SDavid du Colombier 	struct io *s;
110*276e7d6dSDavid du Colombier 
1113e12c5d1SDavid du Colombier 	t = tree1(SIMPLE, t);
1123e12c5d1SDavid du Colombier 	s = openstr();
1133e12c5d1SDavid du Colombier 	pfmt(s, "%t", t);
114*276e7d6dSDavid du Colombier 	t->str = strdup((char *)s->strp);
1153e12c5d1SDavid du Colombier 	closeio(s);
1163e12c5d1SDavid du Colombier 	for(u = t->child[0];u->type==ARGLIST;u = u->child[0]){
1173e12c5d1SDavid du Colombier 		if(u->child[1]->type==DUP
1183e12c5d1SDavid du Colombier 		|| u->child[1]->type==REDIR){
1193e12c5d1SDavid du Colombier 			u->child[1]->child[1] = t;
1203e12c5d1SDavid du Colombier 			t = u->child[1];
1213e12c5d1SDavid du Colombier 			u->child[1] = 0;
1223e12c5d1SDavid du Colombier 		}
1233e12c5d1SDavid du Colombier 	}
1243e12c5d1SDavid du Colombier 	return t;
1253e12c5d1SDavid du Colombier }
126dc5a79c1SDavid du Colombier 
127dc5a79c1SDavid du Colombier tree*
token(char * str,int type)128dc5a79c1SDavid du Colombier token(char *str, int type)
1293e12c5d1SDavid du Colombier {
1303e12c5d1SDavid du Colombier 	tree *t = newtree();
131*276e7d6dSDavid du Colombier 
1323e12c5d1SDavid du Colombier 	t->type = type;
1333e12c5d1SDavid du Colombier 	t->str = strdup(str);
1343e12c5d1SDavid du Colombier 	return t;
1353e12c5d1SDavid du Colombier }
136dc5a79c1SDavid du Colombier 
137dc5a79c1SDavid du Colombier void
freetree(tree * p)138dc5a79c1SDavid du Colombier freetree(tree *p)
1393e12c5d1SDavid du Colombier {
140dc5a79c1SDavid du Colombier 	if(p==0)
141dc5a79c1SDavid du Colombier 		return;
1423e12c5d1SDavid du Colombier 	freetree(p->child[0]);
1433e12c5d1SDavid du Colombier 	freetree(p->child[1]);
1443e12c5d1SDavid du Colombier 	freetree(p->child[2]);
145dc5a79c1SDavid du Colombier 	if(p->str)
146dc5a79c1SDavid du Colombier 		efree(p->str);
1473e12c5d1SDavid du Colombier 	efree((char *)p);
1483e12c5d1SDavid du Colombier }
149