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