#include "rc.h"
#include "y.tab.h"
typedef struct Kw Kw;
#define NKW 30
#define NVAR 521
struct Kw{
char *name;
int type;
Kw *next;
};
void updenvlocal(Var *v);
void addenv(Var *v);
Kw *kw[NKW];
Var *gvar[NVAR];
int
hash(char *s, int n)
{
int h=0, i=1;
while(*s)
h+=*s++*i++;
h%=n;
return h<0?h+n:h;
}
void
kenter(int type, char *name)
{
int h=hash(name, NKW);
Kw *p=new(Kw);
p->type=type;
p->name=name;
p->next=kw[h];
kw[h]=p;
}
void
vinit(void)
{
char *buf, **env, envname[256], *name, *p, *s;
Dir *ent;
int i, fd, dir, len, n, nent;
Word *w, *val;
int f;
dir = open("/env", 0);
if(dir < 0){
pfmt(err, "rc: can't open /env: %r\n");
return;
}
ent = nil;
for(;;){
nent = dirread(dir, &ent);
if(nent <= 0)
break;
for(i=0; i<nent; i++){
len = ent[i].length;
if(len && strncmp(ent[i].name, "fn#", 3)!=0){
snprint(envname, sizeof envname, "/env/%s", ent[i].name);
if((f=open(envname, 0))>=0){
buf=malloc((int)len+1);
read(f, buf, (long)len);
val=0;
/* Charitably add a 0 at the end if need be */
if(buf[len-1]) buf[len++]='\0';
s=buf+len-1;
for(;;){
while(s!=buf && s[-1]!='\0') --s;
val=newword(s, val);
if(s==buf) break;
--s;
}
setvar(ent[i].name, val);
vlook(ent[i].name)->changed=0;
close(f);
free(buf);
}
}
}
free(ent);
}
close(dir);
}
Tree *
klook(char *name)
{
Kw *p;
Tree *t=token(name, WORD);
for(p=kw[hash(name, NKW)];p;p=p->next) {
if(strcmp(p->name, name)==0){
t->type=p->type;
t->iskw=1;
break;
}
}
return t;
}
Var *
gvlook(char *name)
{
int h=hash(name, NVAR);
Var *v;
for(v=gvar[h]; v; v=v->next)
if(strcmp(v->name, name)==0)
return v;
return gvar[h]=newvar(strdup(name), gvar[h]);
}
Var *
vlook(char *name)
{
Var *v;
if(runq)
for(v=runq->local; v; v=v->next)
if(strcmp(v->name, name)==0)
return v;
return gvlook(name);
}
void
setvar(char *name, Word *val)
{
Var *v=vlook(name);
freewords(v->val);
v->val=val;
v->changed=1;
}
Var *
newvar(char *name, Var *next)
{
Var *v=new(Var);
v->name=name;
v->val=0;
v->fn=0;
v->changed=0;
v->fnchanged=0;
v->next=next;
return v;
}
void
execfinit(void)
{
}
void
updenv(void)
{
Var *v, **h;
for(h=gvar;h!=&gvar[NVAR];h++)
for(v=*h;v;v=v->next)
addenv(v);
if(runq)
updenvlocal(runq->local);
}
void
addenv(Var *v)
{
char buf[100], *p;
Io *f;
Word *w;
int i, n;
if(v->changed){
v->changed=0;
p = 0;
n = 0;
if(v->val) {
for(w=v->val; w; w=w->next) {
i = strlen(w->word);
p = realloc(p, n+i+1);
memmove(p+n, w->word, i);
n+=i;
p[n++] = IWS;
}
p[n-1] = 0;
putenv(v->name, p);
} else
putenv(v->name, "");
free(p);
}
if(v->fnchanged){
v->fnchanged=0;
snprint(buf, sizeof(buf), "fn#%s", v->name);
f = openstr();
pfmt(f, "fn %s %s\n", v->name, v->fn[v->pc-1].s);
putenv(buf, f->strp);
closeio(f);
}
}
void
updenvlocal(Var *v)
{
if(v){
updenvlocal(v->next);
addenv(v);
}
}
syntax highlighted by Code2HTML, v. 0.9.1