#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=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); } }