From d1a19f0d477a6249d8af9322317b8434b86260ea Mon Sep 17 00:00:00 2001 From: Nicholas Noll Date: Wed, 13 Oct 2021 08:27:37 -0700 Subject: fix(email): bytes error. updated vendoring --- sys/cmd/rc/var.c | 230 +++++++++++++++++++++++++++++++++---------------------- 1 file changed, 138 insertions(+), 92 deletions(-) (limited to 'sys/cmd/rc/var.c') diff --git a/sys/cmd/rc/var.c b/sys/cmd/rc/var.c index d442369..d48dc66 100644 --- a/sys/cmd/rc/var.c +++ b/sys/cmd/rc/var.c @@ -1,129 +1,175 @@ #include "rc.h" +#include "exec.h" +#include "fns.h" -Var *globals[1021] = { 0 }; +var *gvar[NVAR] = { 0 }; /* hash for globals */ -struct Keyword { - ushort type; - char *name; - struct Keyword *link; -} *keywords[41]; - -// ----------------------------------------------------------------------- -// utility - -static int hash(char *s, int n) { - int i = 1, h = 0; - while (*s) - h += *s++*i++; - h %= n; - return (h<0)?h+n:h; + int h = 0, i = 1; + while(*s) h+=*s++*i++; + h%=n; + return h<0?h+n:h; } +#define NKW 30 +struct kw{ + char *name; + int type; + struct kw *next; +}*kw[NKW]; -// ----------------------------------------------------------------------- -// keywords - -static void -putkw(int type, char *name) +kenter(int type, char *name) { - struct Keyword *kw; - int h = hash(name, arrlen(keywords)); - - alloc(kw); - kw->type = type; - kw->name = name; - kw->link = keywords[h]; - - keywords[h] = kw; + int h = hash(name, NKW); + struct kw *p = new(struct kw); + p->type = type; + p->name = name; + p->next = kw[h]; + kw[h] = p; } void -initkw(void) +kinit(void) { - putkw(Tfor, "for"); - putkw(Tin, "in"); - putkw(Twhile, "while"); - putkw(Tif, "if"); - putkw(Telse, "else"); - putkw(Tswitch, "switch"); - putkw(Tcase, "case"); - putkw(Tfunc, "func"); + kenter(FOR, "for"); + kenter(IN, "in"); + kenter(WHILE, "while"); + kenter(IF, "if"); + kenter(NOT, "not"); + kenter(TWIDDLE, "~"); + kenter(BANG, "!"); + kenter(SUBSHELL, "@"); + kenter(SWITCH, "switch"); + kenter(FN, "fn"); } -int -kwlookup(char *name) +tree* +klook(char *name) { - int t; - struct Keyword *it; - for(t=-1,it = keywords[hash(name, arrlen(keywords))];it;it = it->link) - if(!strcmp(it->name, name)) - t = it->type; - return t; + struct 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; } -// ----------------------------------------------------------------------- -// variables - -Var * -newvar(char *name, Var *link) +var* +gvlook(char *name) { - Var *v; - - alloc(v); - v->name = name; - v->val = 0; - v->func = nil; - v->funcnew = 0; - v->new = 0; - v->update = nil; - v->link = link; - - return v; + 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]); } -/* only global lookup */ +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); +} -Var * -gvlookup(char *name) +void +_setvar(char *name, word *val, int callfn) { - Var *v; - int h = hash(name, arrlen(globals)); - for (v = globals[h]; v; v = v->link) - if (!strcmp(v->name, name)) - return v; + struct var *v = vlook(name); + freewords(v->val); + v->val=val; + v->changed=1; + if(callfn && v->changefn) + v->changefn(v); +} - return globals[h] = newvar(strdup(name), globals[h]); +void +setvar(char *name, word *val) +{ + _setvar(name, val, 1); } -/* local + global lookup */ -Var * -vlookup(char *name) +void +bigpath(var *v) { - Var *v; - if (shell) - for (v = shell->local; v; v = v->link) - if (!strcmp(v->name, name)) - return v; - return gvlookup(name); + /* convert $PATH to $path */ + char *p, *q; + word **l, *w; + + if(v->val == nil){ + _setvar("path", nil, 0); + return; + } + p = v->val->word; + 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 = newword(p[0] ? p : ".", nil); + l = &(*l)->next; + if(q){ + *q = ':'; + p = q+1; + }else + p = nil; + } + _setvar("path", w, 0); } -static +char* +list2strcolon(word *words) +{ + char *value, *s, *t; + int len = 0; + word *ap; + for(ap = words;ap;ap = ap->next) + len+=1+strlen(ap->word); + value = emalloc(len+1); + s = value; + for(ap = words;ap;ap = ap->next){ + for(t = ap->word;*t;) *s++=*t++; + *s++=':'; + } + if(s==value) + *s='\0'; + else s[-1]='\0'; + return value; +} void -set(char *name, Word *val, int call) +littlepath(var *v) { - Var *v = vlookup(name); - freelist(v->val); - v->val = val; - v->new = 1; - if (call && v->update) - v->update(v); + /* convert $path to $PATH */ + char *p; + word *w; + + p = list2strcolon(v->val); + w = new(word); + w->word = p; + w->next = nil; + _setvar("PATH", w, 1); /* 1: recompute $path to expose colon problems */ } void -setvar(char *name, Word *val) +pathinit(void) { - set(name, val, 1); + var *v; + + v = gvlook("path"); + v->changefn = littlepath; + v = gvlook("PATH"); + v->changefn = bigpath; + bigpath(v); } -- cgit v1.2.1