symtab.c - 9base - revived minimalist port of Plan 9 userland to Unix
 (HTM) git clone git://git.suckless.org/9base
 (DIR) Log
 (DIR) Files
 (DIR) Refs
 (DIR) README
 (DIR) LICENSE
       ---
       symtab.c (1610B)
       ---
            1 #include        "mk.h"
            2 
            3 #define        NHASH        4099
            4 #define        HASHMUL        79L        /* this is a good value */
            5 static Symtab *hash[NHASH];
            6 
            7 void
            8 syminit(void)
            9 {
           10         Symtab **s, *ss, *next;
           11 
           12         for(s = hash; s < &hash[NHASH]; s++){
           13                 for(ss = *s; ss; ss = next){
           14                         next = ss->next;
           15                         free((char *)ss);
           16                 }
           17                 *s = 0;
           18         }
           19 }
           20 
           21 Symtab *
           22 symlook(char *sym, int space, void *install)
           23 {
           24         long h;
           25         char *p;
           26         Symtab *s;
           27 
           28         for(p = sym, h = space; *p; h += *p++)
           29                 h *= HASHMUL;
           30         if(h < 0)
           31                 h = ~h;
           32         h %= NHASH;
           33         for(s = hash[h]; s; s = s->next)
           34                 if((s->space == space) && (strcmp(s->name, sym) == 0))
           35                         return(s);
           36         if(install == 0)
           37                 return(0);
           38         s = (Symtab *)Malloc(sizeof(Symtab));
           39         s->space = space;
           40         s->name = sym;
           41         s->u.ptr = install;
           42         s->next = hash[h];
           43         hash[h] = s;
           44         return(s);
           45 }
           46 
           47 void
           48 symdel(char *sym, int space)
           49 {
           50         long h;
           51         char *p;
           52         Symtab *s, *ls;
           53 
           54         /* multiple memory leaks */
           55 
           56         for(p = sym, h = space; *p; h += *p++)
           57                 h *= HASHMUL;
           58         if(h < 0)
           59                 h = ~h;
           60         h %= NHASH;
           61         for(s = hash[h], ls = 0; s; ls = s, s = s->next)
           62                 if((s->space == space) && (strcmp(s->name, sym) == 0)){
           63                         if(ls)
           64                                 ls->next = s->next;
           65                         else
           66                                 hash[h] = s->next;
           67                         free((char *)s);
           68                 }
           69 }
           70 
           71 void
           72 symtraverse(int space, void (*fn)(Symtab*))
           73 {
           74         Symtab **s, *ss;
           75 
           76         for(s = hash; s < &hash[NHASH]; s++)
           77                 for(ss = *s; ss; ss = ss->next)
           78                         if(ss->space == space)
           79                                 (*fn)(ss);
           80 }
           81 
           82 void
           83 symstat(void)
           84 {
           85         Symtab **s, *ss;
           86         int n;
           87         int l[1000];
           88 
           89         memset((char *)l, 0, sizeof(l));
           90         for(s = hash; s < &hash[NHASH]; s++){
           91                 for(ss = *s, n = 0; ss; ss = ss->next)
           92                         n++;
           93                 l[n]++;
           94         }
           95         for(n = 0; n < 1000; n++)
           96                 if(l[n]) Bprint(&bout, "%ld of length %d\n", l[n], n);
           97 }