aboutsummaryrefslogtreecommitdiff
path: root/sys/cmd/rc/var.c
diff options
context:
space:
mode:
Diffstat (limited to 'sys/cmd/rc/var.c')
-rw-r--r--sys/cmd/rc/var.c336
1 files changed, 0 insertions, 336 deletions
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