URI: 
       tvar.c - plan9port - [fork] Plan 9 from user space
  HTML git clone git://src.adamsgaard.dk/plan9port
   DIR Log
   DIR Files
   DIR Refs
   DIR README
   DIR LICENSE
       ---
       tvar.c (2561B)
       ---
            1 #include "rc.h"
            2 #include "exec.h"
            3 #include "fns.h"
            4 
            5 int
            6 hash(char *s, int n)
            7 {
            8         int h = 0, i = 1;
            9         while(*s) h+=*s++*i++;
           10         h%=n;
           11         return h<0?h+n:h;
           12 }
           13 #define        NKW        30
           14 struct kw{
           15         char *name;
           16         int type;
           17         struct kw *next;
           18 }*kw[NKW];
           19 
           20 void
           21 kenter(int type, char *name)
           22 {
           23         int h = hash(name, NKW);
           24         struct kw *p = new(struct kw);
           25         p->type = type;
           26         p->name = name;
           27         p->next = kw[h];
           28         kw[h] = p;
           29 }
           30 
           31 void
           32 kinit(void)
           33 {
           34         kenter(FOR, "for");
           35         kenter(IN, "in");
           36         kenter(WHILE, "while");
           37         kenter(IF, "if");
           38         kenter(NOT, "not");
           39         kenter(TWIDDLE, "~");
           40         kenter(BANG, "!");
           41         kenter(SUBSHELL, "@");
           42         kenter(SWITCH, "switch");
           43         kenter(FN, "fn");
           44 }
           45 
           46 tree*
           47 klook(char *name)
           48 {
           49         struct kw *p;
           50         tree *t = token(name, WORD);
           51         for(p = kw[hash(name, NKW)];p;p = p->next)
           52                 if(strcmp(p->name, name)==0){
           53                         t->type = p->type;
           54                         t->iskw = 1;
           55                         break;
           56                 }
           57         return t;
           58 }
           59 
           60 var*
           61 gvlook(char *name)
           62 {
           63         int h = hash(name, NVAR);
           64         var *v;
           65         for(v = gvar[h];v;v = v->next) if(strcmp(v->name, name)==0) return v;
           66         return gvar[h] = newvar(strdup(name), gvar[h]);
           67 }
           68 
           69 var*
           70 vlook(char *name)
           71 {
           72         var *v;
           73         if(runq)
           74                 for(v = runq->local;v;v = v->next)
           75                         if(strcmp(v->name, name)==0) return v;
           76         return gvlook(name);
           77 }
           78 
           79 void
           80 _setvar(char *name, word *val, int callfn)
           81 {
           82         struct var *v = vlook(name);
           83         freewords(v->val);
           84         v->val=val;
           85         v->changed=1;
           86         if(callfn && v->changefn)
           87                 v->changefn(v);
           88 }
           89 
           90 void
           91 setvar(char *name, word *val)
           92 {
           93         _setvar(name, val, 1);
           94 }
           95 
           96 void
           97 bigpath(var *v)
           98 {
           99         /* convert $PATH to $path */
          100         char *p, *q;
          101         word **l, *w;
          102 
          103         if(v->val == nil){
          104                 _setvar("path", nil, 0);
          105                 return;
          106         }
          107         p = v->val->word;
          108         w = nil;
          109         l = &w;
          110         /*
          111          * Doesn't handle escaped colon nonsense.
          112          */
          113         if(p[0] == 0)
          114                 p = nil;
          115         while(p){
          116                 q = strchr(p, ':');
          117                 if(q)
          118                         *q = 0;
          119                 *l = newword(p[0] ? p : ".", nil);
          120                 l = &(*l)->next;
          121                 if(q){
          122                         *q = ':';
          123                         p = q+1;
          124                 }else
          125                         p = nil;
          126         }
          127         _setvar("path", w, 0);
          128 }
          129 
          130 char*
          131 list2strcolon(word *words)
          132 {
          133         char *value, *s, *t;
          134         int len = 0;
          135         word *ap;
          136         for(ap = words;ap;ap = ap->next)
          137                 len+=1+strlen(ap->word);
          138         value = emalloc(len+1);
          139         s = value;
          140         for(ap = words;ap;ap = ap->next){
          141                 for(t = ap->word;*t;) *s++=*t++;
          142                 *s++=':';
          143         }
          144         if(s==value)
          145                 *s='\0';
          146         else s[-1]='\0';
          147         return value;
          148 }
          149 void
          150 littlepath(var *v)
          151 {
          152         /* convert $path to $PATH */
          153         char *p;
          154         word *w;
          155 
          156         p = list2strcolon(v->val);
          157         w = new(word);
          158         w->word = p;
          159         w->next = nil;
          160         _setvar("PATH", w, 1);        /* 1: recompute $path to expose colon problems */
          161 }
          162 
          163 void
          164 pathinit(void)
          165 {
          166         var *v;
          167 
          168         v = gvlook("path");
          169         v->changefn = littlepath;
          170         v = gvlook("PATH");
          171         v->changefn = bigpath;
          172         bigpath(v);
          173 }