rsc | 76193d7 | 2003-09-30 17:47:42 +0000 | [diff] [blame] | 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; |
| 11 | |
| 12 | for(s = hash; s < &hash[NHASH]; s++){ |
| 13 | for(ss = *s; ss; ss = ss->next) |
| 14 | free((char *)ss); |
| 15 | *s = 0; |
| 16 | } |
| 17 | } |
| 18 | |
| 19 | Symtab * |
| 20 | symlook(char *sym, int space, void *install) |
| 21 | { |
| 22 | long h; |
| 23 | char *p; |
| 24 | Symtab *s; |
| 25 | |
| 26 | for(p = sym, h = space; *p; h += *p++) |
| 27 | h *= HASHMUL; |
| 28 | if(h < 0) |
| 29 | h = ~h; |
| 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->value = 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 | 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 | if(h < 0) |
| 57 | h = ~h; |
| 58 | h %= NHASH; |
| 59 | for(s = hash[h], ls = 0; s; ls = s, s = s->next) |
| 60 | if((s->space == space) && (strcmp(s->name, sym) == 0)){ |
| 61 | if(ls) |
| 62 | ls->next = s->next; |
| 63 | else |
| 64 | hash[h] = s->next; |
| 65 | free((char *)s); |
| 66 | } |
| 67 | } |
| 68 | |
| 69 | void |
| 70 | symtraverse(int space, void (*fn)(Symtab*)) |
| 71 | { |
| 72 | Symtab **s, *ss; |
| 73 | |
| 74 | for(s = hash; s < &hash[NHASH]; s++) |
| 75 | for(ss = *s; ss; ss = ss->next) |
| 76 | if(ss->space == space) |
| 77 | (*fn)(ss); |
| 78 | } |
| 79 | |
| 80 | void |
| 81 | symstat(void) |
| 82 | { |
| 83 | Symtab **s, *ss; |
| 84 | int n; |
| 85 | int l[1000]; |
| 86 | |
| 87 | memset((char *)l, 0, sizeof(l)); |
| 88 | for(s = hash; s < &hash[NHASH]; s++){ |
| 89 | for(ss = *s, n = 0; ss; ss = ss->next) |
| 90 | n++; |
| 91 | l[n]++; |
| 92 | } |
| 93 | for(n = 0; n < 1000; n++) |
| 94 | if(l[n]) Bprint(&bout, "%ld of length %d\n", l[n], n); |
| 95 | } |