a2f7d03d4e
Xqdol() used to take quadratic time because of strcat(), the code isnt really needed as list2str() aready does the same thing in linear time without the strcat(). add estrdup() which uses emalloc() so allocation error are catched. move strdups() of name from callers into newvar(). avoid recursion of conclist(), and avoid copying of word strings by providing Newword() function which doesnt copy the word string.
149 lines
2 KiB
C
149 lines
2 KiB
C
#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 = estrdup((char *)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);
|
|
}
|