symtab.c (1587B)
1 #include "mk.h" 2 3 #define NHASH 4099 4 #define HASHMUL 79UL /* 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 unsigned long h; 25 char *p; 26 Symtab *s; 27 28 for(p = sym, h = space; *p; h += *p++) 29 h *= HASHMUL; 30 h %= NHASH; 31 for(s = hash[h]; s; s = s->next) 32 if((s->space == space) && (strcmp(s->name, sym) == 0)) 33 return(s); 34 if(install == 0) 35 return(0); 36 s = (Symtab *)Malloc(sizeof(Symtab)); 37 s->space = space; 38 s->name = sym; 39 s->u.ptr = install; 40 s->next = hash[h]; 41 hash[h] = s; 42 return(s); 43 } 44 45 void 46 symdel(char *sym, int space) 47 { 48 unsigned long h; 49 char *p; 50 Symtab *s, *ls; 51 52 /* multiple memory leaks */ 53 54 for(p = sym, h = space; *p; h += *p++) 55 h *= HASHMUL; 56 h %= NHASH; 57 for(s = hash[h], ls = 0; s; ls = s, s = s->next) 58 if((s->space == space) && (strcmp(s->name, sym) == 0)){ 59 if(ls) 60 ls->next = s->next; 61 else 62 hash[h] = s->next; 63 free((char *)s); 64 } 65 } 66 67 void 68 symtraverse(int space, void (*fn)(Symtab*)) 69 { 70 Symtab **s, *ss; 71 72 for(s = hash; s < &hash[NHASH]; s++) 73 for(ss = *s; ss; ss = ss->next) 74 if(ss->space == space) 75 (*fn)(ss); 76 } 77 78 void 79 symstat(void) 80 { 81 Symtab **s, *ss; 82 int n; 83 int l[1000]; 84 85 memset((char *)l, 0, sizeof(l)); 86 for(s = hash; s < &hash[NHASH]; s++){ 87 for(ss = *s, n = 0; ss; ss = ss->next) 88 n++; 89 l[n]++; 90 } 91 for(n = 0; n < 1000; n++) 92 if(l[n]) Bprint(&bout, "%ld of length %d\n", l[n], n); 93 }