#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 *np, *prev; uint32_t h; prev = NULL; h = hash(name, hashsize); for (np = hashtab[h]; np != NULL; prev = np, np = np->next) if (!strcmp(name, np->name)) break; if (np != NULL) { if (prev == NULL) hashtab[h] = np->next; else prev->next = np->next; np->next = NULL; nlfree(np); 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]); }