aboutsummaryrefslogtreecommitdiff
path: root/sys/cmd/rc/tree.c
diff options
context:
space:
mode:
Diffstat (limited to 'sys/cmd/rc/tree.c')
-rw-r--r--sys/cmd/rc/tree.c144
1 files changed, 144 insertions, 0 deletions
diff --git a/sys/cmd/rc/tree.c b/sys/cmd/rc/tree.c
new file mode 100644
index 0000000..14049e5
--- /dev/null
+++ b/sys/cmd/rc/tree.c
@@ -0,0 +1,144 @@
+#include "rc.h"
+
+// -----------------------------------------------------------------------
+// globals
+
+static Tree *nodes;
+
+// -----------------------------------------------------------------------
+// exported funcs
+
+Tree*
+newtree(void)
+{
+ Tree *t;
+
+ alloc(t);
+ t->str = nil;
+ t->child[0] = t->child[1] = t->child[2] = nil;
+ t->redir.fd[0] = t->redir.fd[1] = t->redir.type = 0;
+
+ t->link = nodes, nodes = t;
+ return t;
+}
+
+void
+freetree(Tree *t)
+{
+ if (!t)
+ return;
+
+ freetree(t->child[0]);
+ freetree(t->child[1]);
+ freetree(t->child[2]);
+
+ if (t->str)
+ efree(t->str);
+ efree(t);
+}
+
+void
+freenodes(void)
+{
+ Tree *t, *u;
+
+ for (t = nodes;t;t = u) {
+ u = t->link;
+ if (t->str)
+ efree(t->str);
+ efree(t);
+ }
+ nodes = nil;
+}
+
+/* tree creation */
+Tree*
+tree3(int type, Tree *c0, Tree *c1, Tree *c2)
+{
+ Tree *t;
+
+ t = newtree();
+ t->type = type;
+ t->child[0] = c0;
+ t->child[1] = c1;
+ t->child[2] = c2;
+
+ return t;
+}
+
+Tree*
+tree2(int type, Tree *c0, Tree *c1)
+{
+ return tree3(type, c0, c1, nil);
+}
+
+Tree*
+tree1(int type, Tree *c0)
+{
+ return tree3(type, c0, nil, nil);
+}
+
+/* tree hang */
+Tree*
+hang1(Tree *p, Tree *c0)
+{
+ p->child[0] = c0;
+ return p;
+}
+
+Tree*
+hang2(Tree *p, Tree *c0, Tree *c1)
+{
+ p->child[0] = c0;
+ p->child[1] = c1;
+ return p;
+}
+
+Tree*
+hang3(Tree *p, Tree *c0, Tree *c1, Tree *c2)
+{
+ p->child[0] = c0;
+ p->child[1] = c1;
+ p->child[2] = c2;
+ return p;
+}
+
+/* hangs the cmd underneath the epilogue */
+Tree*
+epihang(Tree *c, Tree *epi)
+{
+ Tree *p;
+ if(!epi)
+ return c;
+ for(p=epi;p->child[1];p = p->child[1])
+ ;
+ p->child[1] = c;
+ return epi;
+}
+
+/* hangs tree t from a new simple node. percolates redirections to root */
+Tree*
+simplehang(Tree *t)
+{
+ Tree *u;
+ t = tree1(Tsimple, t);
+ for(u = t->child[0];u->type==Targs;u=u->child[0]) {
+ if (u->child[1]->type==Tdup
+ || u->child[1]->type==Tredir){
+ u->child[1]->child[1] = t;
+ t = u->child[1];
+ u->child[1] = nil;
+ }
+ }
+ return t;
+}
+
+Tree*
+wordnode(char *w)
+{
+ Tree *t = newtree();
+ t->type = Tword;
+ t->str = strdup(w);
+
+ return t;
+}