summaryrefslogtreecommitdiff
path: root/sys/src/cmd/mk/symtab.c
diff options
context:
space:
mode:
authorTaru Karttunen <taruti@taruti.net>2011-03-30 15:46:40 +0300
committerTaru Karttunen <taruti@taruti.net>2011-03-30 15:46:40 +0300
commite5888a1ffdae813d7575f5fb02275c6bb07e5199 (patch)
treed8d51eac403f07814b9e936eed0c9a79195e2450 /sys/src/cmd/mk/symtab.c
Import sources from 2011-03-30 iso image
Diffstat (limited to 'sys/src/cmd/mk/symtab.c')
-rwxr-xr-xsys/src/cmd/mk/symtab.c95
1 files changed, 95 insertions, 0 deletions
diff --git a/sys/src/cmd/mk/symtab.c b/sys/src/cmd/mk/symtab.c
new file mode 100755
index 000000000..57129ae67
--- /dev/null
+++ b/sys/src/cmd/mk/symtab.c
@@ -0,0 +1,95 @@
+#include "mk.h"
+
+#define NHASH 4099
+#define HASHMUL 79L /* this is a good value */
+static Symtab *hash[NHASH];
+
+void
+syminit(void)
+{
+ Symtab **s, *ss;
+
+ for(s = hash; s < &hash[NHASH]; s++){
+ for(ss = *s; ss; ss = ss->next)
+ free((char *)ss);
+ *s = 0;
+ }
+}
+
+Symtab *
+symlook(char *sym, int space, void *install)
+{
+ long h;
+ char *p;
+ Symtab *s;
+
+ for(p = sym, h = space; *p; h += *p++)
+ h *= HASHMUL;
+ if(h < 0)
+ h = ~h;
+ h %= NHASH;
+ for(s = hash[h]; s; s = s->next)
+ if((s->space == space) && (strcmp(s->name, sym) == 0))
+ return(s);
+ if(install == 0)
+ return(0);
+ s = (Symtab *)Malloc(sizeof(Symtab));
+ s->space = space;
+ s->name = sym;
+ s->u.ptr = install;
+ s->next = hash[h];
+ hash[h] = s;
+ return(s);
+}
+
+void
+symdel(char *sym, int space)
+{
+ long h;
+ char *p;
+ Symtab *s, *ls;
+
+ /* multiple memory leaks */
+
+ for(p = sym, h = space; *p; h += *p++)
+ h *= HASHMUL;
+ if(h < 0)
+ h = ~h;
+ h %= NHASH;
+ for(s = hash[h], ls = 0; s; ls = s, s = s->next)
+ if((s->space == space) && (strcmp(s->name, sym) == 0)){
+ if(ls)
+ ls->next = s->next;
+ else
+ hash[h] = s->next;
+ free((char *)s);
+ }
+}
+
+void
+symtraverse(int space, void (*fn)(Symtab*))
+{
+ Symtab **s, *ss;
+
+ for(s = hash; s < &hash[NHASH]; s++)
+ for(ss = *s; ss; ss = ss->next)
+ if(ss->space == space)
+ (*fn)(ss);
+}
+
+void
+symstat(void)
+{
+ Symtab **s, *ss;
+ int n;
+ int l[1000];
+
+ memset((char *)l, 0, sizeof(l));
+ for(s = hash; s < &hash[NHASH]; s++){
+ for(ss = *s, n = 0; ss; ss = ss->next)
+ n++;
+ l[n]++;
+ }
+ for(n = 0; n < 1000; n++)
+ if(l[n]) Bprint(&bout, "%d of length %d\n", l[n], n);
+}