1 #include "rc.h" 2 #include "y.tab.h" 3 4 extern char **_environ; 5 6 typedef struct Kw Kw; 7 8 #define NKW 30 9 #define NVAR 521 10 11 struct Kw{ 12 char *name; 13 int type; 14 Kw *next; 15 }; 16 17 void updenvlocal(Var *v); 18 void addenv(Var *v); 19 20 Kw *kw[NKW]; 21 Var *gvar[NVAR]; 22 23 int 24 hash(char *s, int n) 25 { 26 int h=0, i=1; 27 28 while(*s) 29 h+=*s++*i++; 30 h%=n; 31 return h<0?h+n:h; 32 } 33 34 void 35 kenter(int type, char *name) 36 { 37 int h=hash(name, NKW); 38 Kw *p=new(Kw); 39 p->type=type; 40 p->name=name; 41 p->next=kw[h]; 42 kw[h]=p; 43 } 44 45 void 46 vinit(void) 47 { 48 char **env, *name, *val, *p; 49 int i; 50 Word *w; 51 Io *f; 52 int n; 53 Var *v; 54 55 env = _environ; 56 for(i=0; env[i]; free(name), i++) { 57 name = strdup(env[i]); 58 p = strchr(name, '='); 59 if(p == 0 || p == name) 60 continue; 61 *p = 0; 62 val = p+1; 63 n = strlen(val); 64 if(n == 0) 65 continue; 66 67 if(strncmp(name, "fn#", 3)!=0) { 68 /* variable */ 69 w = 0; 70 p = val+n-1; 71 while(*p) { 72 if(*p == IWS) 73 *p-- = 0; 74 for(; *p && *p != IWS; p--) 75 ; 76 w=newword(p+1, w); 77 } 78 setvar(name, w); 79 vlook(name)->changed=0; 80 } else { 81 /* function */ 82 f = opencore(val, n); 83 execcmds(f); 84 } 85 } 86 v = vlook("path"); 87 p = getenv("path"); 88 if(v->val == 0 && p) 89 v->val = newword(p, 0); 90 } 91 92 93 Tree * 94 klook(char *name) 95 { 96 Kw *p; 97 Tree *t=token(name, WORD); 98 for(p=kw[hash(name, NKW)];p;p=p->next) { 99 if(strcmp(p->name, name)==0){ 100 t->type=p->type; 101 t->iskw=1; 102 break; 103 } 104 } 105 return t; 106 } 107 108 Var * 109 gvlook(char *name) 110 { 111 int h=hash(name, NVAR); 112 Var *v; 113 for(v=gvar[h]; v; v=v->next) 114 if(strcmp(v->name, name)==0) 115 return v; 116 117 return gvar[h]=newvar(strdup(name), gvar[h]); 118 } 119 120 Var * 121 vlook(char *name) 122 { 123 Var *v; 124 if(runq) 125 for(v=runq->local; v; v=v->next) 126 if(strcmp(v->name, name)==0) 127 return v; 128 return gvlook(name); 129 } 130 131 void 132 setvar(char *name, Word *val) 133 { 134 Var *v=vlook(name); 135 freewords(v->val); 136 v->val=val; 137 v->changed=1; 138 } 139 140 Var * 141 newvar(char *name, Var *next) 142 { 143 Var *v=new(Var); 144 v->name=name; 145 v->val=0; 146 v->fn=0; 147 v->changed=0; 148 v->fnchanged=0; 149 v->next=next; 150 return v; 151 } 152 153 154 void 155 execfinit(void) 156 { 157 } 158 159 void 160 updenv(void) 161 { 162 Var *v, **h; 163 164 for(h=gvar;h!=&gvar[NVAR];h++) 165 for(v=*h;v;v=v->next) 166 addenv(v); 167 168 if(runq) 169 updenvlocal(runq->local); 170 } 171 172 static void 173 envput(char *var, char *val) 174 { 175 int i, n; 176 char *e; 177 char buf[256]; 178 179 snprint(buf, sizeof(buf), "%s=%s", var, val); 180 n = strlen(var); 181 for(i = 0;;i++){ 182 e = environ[i]; 183 if(e == 0) 184 break; 185 if(strncmp(e, var, n) == 0){ 186 free(e); 187 environ[i] = strdup(buf); 188 return; 189 } 190 } 191 environ = realloc(environ, (i+2)*sizeof(char*)); 192 environ[i++] = strdup(buf); 193 environ[i] = 0; 194 } 195 196 void 197 addenv(Var *v) 198 { 199 char buf[100], *p; 200 Io *f; 201 Word *w; 202 int i, n; 203 204 if(v->changed){ 205 v->changed=0; 206 p = 0; 207 n = 0; 208 if(v->val) { 209 for(w=v->val; w; w=w->next) { 210 i = strlen(w->word); 211 p = realloc(p, n+i+1); 212 memmove(p+n, w->word, i); 213 n+=i; 214 p[n++] = IWS; 215 } 216 p[n-1] = 0; 217 envput(v->name, p); 218 } else 219 envput(v->name, ""); 220 free(p); 221 } 222 223 if(v->fnchanged){ 224 v->fnchanged=0; 225 snprint(buf, sizeof(buf), "fn#%s", v->name); 226 f = openstr(); 227 pfmt(f, "fn %s %s\n", v->name, v->fn[v->pc-1].s); 228 envput(buf, f->strp); 229 closeio(f); 230 } 231 } 232 233 void 234 updenvlocal(Var *v) 235 { 236 if(v){ 237 updenvlocal(v->next); 238 addenv(v); 239 } 240 } 241