xref: /plan9/sys/src/cmd/rc/tree.c (revision 276e7d6d7cdb63857b1620e0d4a2158cfb236504)
1 #include "rc.h"
2 #include "exec.h"
3 #include "io.h"
4 #include "fns.h"
5 tree *treenodes;
6 /*
7  * create and clear a new tree node, and add it
8  * to the node list.
9  */
10 
11 tree*
newtree(void)12 newtree(void)
13 {
14 	tree *t = new(tree);
15 	t->iskw = 0;
16 	t->str = 0;
17 	t->child[0] = t->child[1] = t->child[2] = 0;
18 	t->next = treenodes;
19 	treenodes = t;
20 	return t;
21 }
22 
23 void
freenodes(void)24 freenodes(void)
25 {
26 	tree *t, *u;
27 	for(t = treenodes;t;t = u){
28 		u = t->next;
29 		if(t->str)
30 			efree(t->str);
31 		efree((char *)t);
32 	}
33 	treenodes = 0;
34 }
35 
36 tree*
tree1(int type,tree * c0)37 tree1(int type, tree *c0)
38 {
39 	return tree3(type, c0, (tree *)0, (tree *)0);
40 }
41 
42 tree*
tree2(int type,tree * c0,tree * c1)43 tree2(int type, tree *c0, tree *c1)
44 {
45 	return tree3(type, c0, c1, (tree *)0);
46 }
47 
48 tree*
tree3(int type,tree * c0,tree * c1,tree * c2)49 tree3(int type, tree *c0, tree *c1, tree *c2)
50 {
51 	tree *t;
52 	if(type==';'){
53 		if(c0==0)
54 			return c1;
55 		if(c1==0)
56 			return c0;
57 	}
58 	t = newtree();
59 	t->type = type;
60 	t->child[0] = c0;
61 	t->child[1] = c1;
62 	t->child[2] = c2;
63 	return t;
64 }
65 
66 tree*
mung1(tree * t,tree * c0)67 mung1(tree *t, tree *c0)
68 {
69 	t->child[0] = c0;
70 	return t;
71 }
72 
73 tree*
mung2(tree * t,tree * c0,tree * c1)74 mung2(tree *t, tree *c0, tree *c1)
75 {
76 	t->child[0] = c0;
77 	t->child[1] = c1;
78 	return t;
79 }
80 
81 tree*
mung3(tree * t,tree * c0,tree * c1,tree * c2)82 mung3(tree *t, tree *c0, tree *c1, tree *c2)
83 {
84 	t->child[0] = c0;
85 	t->child[1] = c1;
86 	t->child[2] = c2;
87 	return t;
88 }
89 
90 tree*
epimung(tree * comp,tree * epi)91 epimung(tree *comp, tree *epi)
92 {
93 	tree *p;
94 	if(epi==0)
95 		return comp;
96 	for(p = epi;p->child[1];p = p->child[1]);
97 	p->child[1] = comp;
98 	return epi;
99 }
100 /*
101  * Add a SIMPLE node at the root of t and percolate all the redirections
102  * up to the root.
103  */
104 
105 tree*
simplemung(tree * t)106 simplemung(tree *t)
107 {
108 	tree *u;
109 	struct io *s;
110 
111 	t = tree1(SIMPLE, t);
112 	s = openstr();
113 	pfmt(s, "%t", t);
114 	t->str = strdup((char *)s->strp);
115 	closeio(s);
116 	for(u = t->child[0];u->type==ARGLIST;u = u->child[0]){
117 		if(u->child[1]->type==DUP
118 		|| u->child[1]->type==REDIR){
119 			u->child[1]->child[1] = t;
120 			t = u->child[1];
121 			u->child[1] = 0;
122 		}
123 	}
124 	return t;
125 }
126 
127 tree*
token(char * str,int type)128 token(char *str, int type)
129 {
130 	tree *t = newtree();
131 
132 	t->type = type;
133 	t->str = strdup(str);
134 	return t;
135 }
136 
137 void
freetree(tree * p)138 freetree(tree *p)
139 {
140 	if(p==0)
141 		return;
142 	freetree(p->child[0]);
143 	freetree(p->child[1]);
144 	freetree(p->child[2]);
145 	if(p->str)
146 		efree(p->str);
147 	efree((char *)p);
148 }
149