| #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); | 
 | } |