xref: /inferno-os/utils/mk/symtab.c (revision 9dc22068e29604f4b484e746112a9a4efe6fd57f)
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->value = 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 }
98