| tree.c - 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 } |