xref: /plan9-contrib/sys/src/cmd/rc/tree.c (revision 7dd7cddf99dd7472612f1413b4da293630e6b1bc)
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 tree *newtree(void){
11 	tree *t=new(tree);
12 	t->iskw=0;
13 	t->str=0;
14 	t->child[0]=t->child[1]=t->child[2]=0;
15 	t->next=treenodes;
16 	treenodes=t;
17 	return t;
18 }
19 void freenodes(void){
20 	tree *t, *u;
21 	for(t=treenodes;t;t=u){
22 		u=t->next;
23 		if(t->str) efree(t->str);
24 		efree((char *)t);
25 	}
26 	treenodes=0;
27 }
28 tree *tree1(int type, tree *c0)
29 {
30 	return tree3(type, c0, (tree *)0, (tree *)0);
31 }
32 tree *tree2(int type, tree *c0, tree *c1)
33 {
34 	return tree3(type, c0, c1, (tree *)0);
35 }
36 tree *tree3(int type, tree *c0, tree *c1, tree *c2)
37 {
38 	tree *t;
39 	if(type==';'){
40 		if(c0==0) return c1;
41 		if(c1==0) return c0;
42 	}
43 	t=newtree();
44 	t->type=type;
45 	t->child[0]=c0;
46 	t->child[1]=c1;
47 	t->child[2]=c2;
48 	return t;
49 }
50 tree *mung1(tree *t, tree *c0)
51 {
52 	t->child[0]=c0;
53 	return t;
54 }
55 tree *mung2(tree *t, tree *c0, tree *c1)
56 {
57 	t->child[0]=c0;
58 	t->child[1]=c1;
59 	return t;
60 }
61 tree *mung3(tree *t, tree *c0, tree *c1, tree *c2)
62 {
63 	t->child[0]=c0;
64 	t->child[1]=c1;
65 	t->child[2]=c2;
66 	return t;
67 }
68 tree *epimung(tree *comp, tree *epi)
69 {
70 	tree *p;
71 	if(epi==0) return comp;
72 	for(p=epi;p->child[1];p=p->child[1]);
73 	p->child[1]=comp;
74 	return epi;
75 }
76 /*
77  * Add a SIMPLE node at the root of t and percolate all the redirections
78  * up to the root.
79  */
80 tree *simplemung(tree *t)
81 {
82 	tree *u;
83 	struct io *s;
84 	t=tree1(SIMPLE, t);
85 	s=openstr();
86 	pfmt(s, "%t", t);
87 	t->str=strdup(s->strp);
88 	closeio(s);
89 	for(u=t->child[0];u->type==ARGLIST;u=u->child[0]){
90 		if(u->child[1]->type==DUP
91 		|| u->child[1]->type==REDIR){
92 			u->child[1]->child[1]=t;
93 			t=u->child[1];
94 			u->child[1]=0;
95 		}
96 	}
97 	return t;
98 }
99 tree *token(char *str, int type)
100 {
101 	tree *t=newtree();
102 	t->type=type;
103 	t->str=strdup(str);
104 	return t;
105 }
106 void freetree(tree *p)
107 {
108 	if(p==0) return;
109 	freetree(p->child[0]);
110 	freetree(p->child[1]);
111 	freetree(p->child[2]);
112 	if(p->str) efree(p->str);
113 	efree((char *)p);
114 }
115