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