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 }