#include #include #include #include #include "hash.h" void nlfree(struct nlist *p); uint32_t hash(char *s, uint32_t hashsize); struct nlist *lookup(struct nlist *hashtab[], uint32_t hashsize, char *s); void pnl(struct nlist *np); uint32_t hash(char *s, uint32_t hashsize) { uint32_t hashval; for (hashval = 0; *s != '\0'; ++s) hashval = *s + 31*hashval; return hashval % hashsize; } struct nlist *lookup(struct nlist *hashtab[], uint32_t hashsize, char *s) { struct nlist *np; for (np = hashtab[hash(s, hashsize)]; np != NULL; np = np->next) if (!strcmp(s, np->name)) return np; return NULL; } struct nlist *install(struct nlist *hashtab[], uint32_t hashsize, char *name, char *defn) { struct nlist *np; uint32_t hashval; if ((np = lookup(hashtab, hashsize, name)) == NULL) { np = (struct nlist *) malloc(sizeof(*np)); if (np == NULL || (np->name = strdup(name)) == NULL) { nlfree(np); return NULL; } hashval = hash(name, hashsize); np->next = hashtab[hashval]; hashtab[hashval] = np; } else { free(np->defn); } if ((np->defn = strdup(defn)) == NULL) { undef(hashtab, hashsize, name); return NULL; } return np; } void undef(struct nlist *hashtab[], uint32_t hashsize, char *name) { struct nlist *cur, *last; uint32_t hashval = hash(name, hashsize); for (cur = hashtab[hashval], last = NULL; cur !=NULL; last = cur, cur = cur->next) { if (!strcmp(cur->name, name)) { if (last == NULL) hashtab[hashval] = cur->next; else last->next = cur->next; cur->next = NULL; nlfree(cur); return; } } } void pnl(struct nlist *np) { if (np != NULL) { pnl(np->next); printf("%10s %s\n", np->name, np->defn); } } void phashtab(struct nlist *hashtab[], int lim) { int i; for (i = 0; i < lim; ++i) pnl(hashtab[i]); } void nlfree(struct nlist *p) { if (p != NULL ) { nlfree(p->next); if (p->defn != NULL) free(p->defn); if (p->name != NULL) free(p->name); free(p); } } void hashfree(struct nlist *hashtab[], int lim) { int i; for (i = 0; i < lim; ++i) nlfree(hashtab[i]); }