#include <stdio.h>
#include <stdlib.h>
#include <string.h>


struct nlist {
        struct nlist *next;
        char *name;
        char *defn;
};

#define HASHSIZE 101
static struct nlist *hashtab[HASHSIZE];

unsigned hash (char *s)
{
        unsigned hashval;

        for (hashval = 0; *s != '\0'; s++)
                hashval += *s + 31 * hashval;
        return hashval % HASHSIZE;
}

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;
}

struct nlist * install (char *name, char *defn)
{
        struct nlist *np;
        unsigned hashval;

        if ((np = lookup(name)) == NULL)
        {
                np = (struct nlist *) malloc(sizeof(*np));
                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;
}

void undef (char *name)
{
        struct nlist *curr, *last;
        unsigned hashval;

        last = curr = hashtab[hash(name)];
        while (curr != NULL && strcmp(name, curr->name)!= 0)
        {
                printf("while loop\n");
                last = curr;
                curr = curr->next;
                printf("last = %x, curr = %x\n", last, curr);
        }

        printf("after loop\n");
        if (curr)
        {
                last->next = curr->next;
                // !!!!!!!!
                free (curr);
				free ((void *) curr->name);
				free ((void *) curr->defn);
        }
}


int main (int argc, char *argv[])
{
        printf ("%u\n", hash("abcdef"));
        install ("H", "127");
        printf ("%s\n", lookup("H")->defn);

        undef ("H");
      if (lookup("H") != NULL)
              printf ("%s\n", lookup("H")->defn);
}