diff options
author | Nicholas Noll <nbnoll@eml.cc> | 2021-10-09 10:30:50 -0700 |
---|---|---|
committer | Nicholas Noll <nbnoll@eml.cc> | 2021-10-09 10:30:50 -0700 |
commit | 6f2cac23a7e759c464ef52103fac929e1eeb6b10 (patch) | |
tree | d2412c7f82fc47bdb6dc47d82b685982e63cefe7 /sys/cmd/rc/tree.c | |
parent | 80f92a7109c0bce2f4220ff1ce04ec8fd6fb9f8c (diff) |
feat(rc): added shell
Diffstat (limited to 'sys/cmd/rc/tree.c')
-rw-r--r-- | sys/cmd/rc/tree.c | 144 |
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; +} |