9base

revived minimalist port of Plan 9 userland to Unix
git clone git://git.suckless.org/9base
Log | Files | Refs | README | 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 }