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