#include #include "hash.h" #define HASHSIZE 101 static struct nlist *hashtab[HASHSIZE]; /* pointer table */ /* hash: form hash value from string */ unsigned hash(char *s) { unsigned hashval; for (hashval = 0; *s != '\0'; s++) hashval = *s + 31 * hashval; return hashval % HASHSIZE; } /* lookup: look for s in hashtab */ struct nlist *lookup(char *s) { struct nlist *np; for (np = hashtab[hash(s)]; np != NULL; np = np->next) if (strcmp(s, np->name) == 0) return np; return NULL; } /* strdup: make a duplicate of s */ char *strdup(char *s) { char *p; p = (char *) malloc(strlen(s)+1); if (p != NULL) strcpy(p, s); return p; } /* install: put (name, defn) in hashtab */ struct nlist *install(char *name, char *defn) { struct nlist *np; unsigned hashval; if ((np = lookup(name)) == NULL) { /* not found */ np = (struct nlist *) malloc(sizeof(struct nlist)); if (np == NULL || (np->name = strdup(name)) == NULL) return NULL; hashval = hash(name); np->next = hashtab[hashval]; hashtab[hashval] = np; } else free((void *) np->defn); if ((np->defn = strdup(defn)) == NULL) return NULL; return np; } /* undef: remove name and its defn from hashtab */ int undef(char *name) { struct nlist *np, *fp; unsigned hashval; if ((np = lookup(name)) == NULL) return -1; hashval = hash(name); fp = hashtab[hashval]; if (fp == np) /* name to remove is at beginning of list */ hashtab[hashval] = fp->next; else { while (fp->next != np) fp = fp->next; fp->next = np->next; /* skip out this mofo */ } free((void *) np->name); free((void *) np->defn); free((void *) np); return 0; }