From ce05175372a9ddca1a225db0765ace1127a39293 Mon Sep 17 00:00:00 2001 From: Nicholas Date: Fri, 12 Nov 2021 09:22:01 -0800 Subject: chore: simplified organizational structure --- sys/cmd/rc/var.c | 336 ------------------------------------------------------- 1 file changed, 336 deletions(-) delete mode 100644 sys/cmd/rc/var.c (limited to 'sys/cmd/rc/var.c') diff --git a/sys/cmd/rc/var.c b/sys/cmd/rc/var.c deleted file mode 100644 index 3e9635f..0000000 --- a/sys/cmd/rc/var.c +++ /dev/null @@ -1,336 +0,0 @@ -#include "rc.h" -#include "parse.h" - -// TODO: string interning - -// ----------------------------------------------------------------------- -// globals - -struct Keyword -{ - char *name; - int type; -}; - -static Var *globals[512]; -static struct Keyword keywords[100]; // sparse map means less hits - -// ----------------------------------------------------------------------- -// internals - -static -int -hash(char *s, int len) -{ - int h =0, i = 1; - while(*s) - h += *s++*i++; - - h %= len; - return h < 0 ? h+len : h; -} - -static -void -·setvar(char *name, Word *val, int call) -{ - Var *v = var(name); - freeword(v->val); - - v->val = val; - v->new = 1; // this never turns off? - - if(call && v->update) - v->update(v); -} - -static -char* -list2strcolon(Word *words) -{ - char *value, *s, *t; - int len = 0; - Word *ap; - for(ap = words;ap;ap = ap->link) - len+=1+strlen(ap->str); - - value = emalloc(len+1); - - s = value; - for(ap = words; ap; ap = ap->link){ - for(t = ap->str;*t;) *s++=*t++; - *s++=':'; - } - - if(s==value) - *s='\0'; - else - s[-1]='\0'; - - return value; -} - -static -void -littlepath(Var *v) -{ - /* convert $path to $PATH */ - char *p; - Word *w; - - p = list2strcolon(v->val); - w = emalloc(sizeof(*w)); - w->str = p; - w->link = nil; - - ·setvar("PATH", w, 1); -} - -static -void -bigpath(Var *v) -{ - /* convert $PATH to $path */ - char *p, *q; - Word **l, *w; - - if(v->val == nil){ - ·setvar("path", nil, 0); - return; - } - - p = v->val->str; - w = nil; - l = &w; - - /* Doesn't handle escaped colon nonsense. */ - if(p[0] == 0) - p = nil; - - while(p){ - q = strchr(p, ':'); - if(q) - *q = 0; - - *l = makeword(p[0] ? p : ".", nil); - l = &(*l)->link; - - if(q){ - *q = ':'; - p = q+1; - }else - p = nil; - } - ·setvar("path", w, 0); -} - -// ----------------------------------------------------------------------- -// exports - -Var* -makevar(char *name, Var *link) -{ - Var *v = emalloc(sizeof(*v)); - - v->name = name; - v->val = 0; - v->new = 0; - v->newfunc = 0; - v->link = link; - v->func = nil; - v->update = nil; - - return v; -} - -void -setvar(char *name, Word *val) -{ - ·setvar(name, val, 1); -} - -Var* -definevar(char *name, Var *link) -{ - Var *v = emalloc(sizeof(*v)); - - v->name = name; - v->val = 0; - v->link = link; - - return v; -} - -Var* -globalvar(char *name) -{ - int h; - Var *v; - - h = hash(name, arrlen(globals)); - - if(strcmp(name,"PATH")==0){ - flush(shell.err); - } - - for(v = globals[h]; v; v = v->link){ - if(strcmp(v->name, name) == 0){ - return v; - } - } - - return globals[h] = definevar(strdup(name), globals[h]); -} - -Var* -var(char *name) -{ - Var *v; - if(runner){ - for(v = runner->local; v; v=v->link) - if(strcmp(v->name, name) == 0) - return v; - } - return globalvar(name); -} - -static -int -cmpenv(const void *a, const void *b) -{ - return strcmp(*(char**)a, *(char**)b); -} - -char** -mkenv(void) -{ - char **env, **ep, *p, *q; - Var **h, *v; - Word *a; - int nvar=0, nchr=0, sep; - -#define BODY \ - if((v==var(v->name)) && v->val){ \ - nvar++; \ - nchr+=strlen(v->name)+1; \ - for(a=v->val;a;a=a->link) \ - nchr+=strlen(a->str)+1; \ - } - - for(v= runner->local; v; v=v->link){ - BODY - } - for(h=globals; h!=arrend(globals); h++){ - for(v = *h; v; v=v->link){ - BODY - } - } - -#undef BODY - - env=emalloc((nvar+1)*sizeof(*env)+nchr); - ep=env; - p=(char *)&env[nvar+1]; - -#define BODY \ - if((v==var(v->name)) && v->val){ \ - *ep++=p; \ - q=v->name; \ - while(*q) \ - *p++=*q++; \ - sep='='; \ - for(a=v->val;a;a=a->link){ \ - *p++=sep; \ - sep='\1'; \ - q=a->str; \ - while(*q) \ - *p++=*q++; \ - } \ - *p++='\0'; \ - } - - for(v=runner->local; v; v=v->link){ - BODY - } - for(h=globals; h!=arrend(globals); h++){ - for(v = *h; v; v=v->link){ - BODY - } - } -#undef BODY - - *ep=0; - - qsort((char *)env, nvar, sizeof ep[0], cmpenv); - return env; -} - -void -initpath(void) -{ - Var *v; - - v = globalvar("path"); - v->update = littlepath; - - v = globalvar("PATH"); - v->update = bigpath; - - flush(shell.err); - bigpath(v); -} - -#define KEYWORDS \ - KEYWORD("for", Tfor) \ - KEYWORD("in", Tin) \ - KEYWORD("while", Twhile) \ - KEYWORD("if", Tif) \ - KEYWORD("else", Telse) \ - KEYWORD("switch", Tswitch) \ - KEYWORD("case", Tcase) \ - KEYWORD("!", Tbang) \ - KEYWORD("@", Tsubshell) \ - KEYWORD("func", Tfunc) - -void -initkeywords(void) -{ - int i, s, j, h; -#define KEYWORD(a, b) a, - static char *name[] = { KEYWORDS }; -#undef KEYWORD -#define KEYWORD(a, b) b, - static int type[] = { KEYWORDS }; -#undef KEYWORD - - for(i = 0; i < arrlen(type); i++){ - h = hash(name[i], arrlen(keywords)); - for(s=0; s < arrlen(keywords); s++){ - j = (h + s) % arrlen(keywords); - if(!keywords[j].type || strcmp(keywords[j].name, name[i]) == 0){ - keywords[j].name = name[i]; - keywords[j].type = type[i]; - goto nextkeyword; - } - } - nextkeyword:; - } -} - -int -iskeyword(char *word) -{ - int i, s, h; - - h = hash(word, arrlen(keywords)); - for(s = 0; s < arrlen(keywords); s++){ - i = (h + s) % arrlen(keywords); - if(!keywords[i].type) - return 0; - if(strcmp(keywords[i].name, word) == 0) - return keywords[i].type; - } - return 0; -} - -#undef KEYWORDS -- cgit v1.2.1