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 }