tree.c - 9base - revived minimalist port of Plan 9 userland to Unix | |
git clone git://git.suckless.org/9base | |
Log | |
Files | |
Refs | |
README | |
LICENSE | |
--- | |
tree.c (2071B) | |
--- | |
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* | |
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 | |
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* | |
37 tree1(int type, tree *c0) | |
38 { | |
39 return tree3(type, c0, (tree *)0, (tree *)0); | |
40 } | |
41 | |
42 tree* | |
43 tree2(int type, tree *c0, tree *c1) | |
44 { | |
45 return tree3(type, c0, c1, (tree *)0); | |
46 } | |
47 | |
48 tree* | |
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* | |
67 mung1(tree *t, tree *c0) | |
68 { | |
69 t->child[0] = c0; | |
70 return t; | |
71 } | |
72 | |
73 tree* | |
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* | |
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* | |
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* | |
106 simplemung(tree *t) | |
107 { | |
108 tree *u; | |
109 struct io *s; | |
110 t = tree1(SIMPLE, t); | |
111 s = openstr(); | |
112 pfmt(s, "%t", t); | |
113 t->str = strdup(s->strp); | |
114 closeio(s); | |
115 for(u = t->child[0];u->type==ARGLIST;u = u->child[0]){ | |
116 if(u->child[1]->type==DUP | |
117 || u->child[1]->type==REDIR){ | |
118 u->child[1]->child[1] = t; | |
119 t = u->child[1]; | |
120 u->child[1] = 0; | |
121 } | |
122 } | |
123 return t; | |
124 } | |
125 | |
126 tree* | |
127 token(char *str, int type) | |
128 { | |
129 tree *t = newtree(); | |
130 t->type = type; | |
131 t->str = strdup(str); | |
132 return t; | |
133 } | |
134 | |
135 void | |
136 freetree(tree *p) | |
137 { | |
138 if(p==0) | |
139 return; | |
140 freetree(p->child[0]); | |
141 freetree(p->child[1]); | |
142 freetree(p->child[2]); | |
143 if(p->str) | |
144 efree(p->str); | |
145 efree((char *)p); | |
146 } |