home *** CD-ROM | disk | FTP | other *** search
- /* $Header: hash.c,v 1.1 85/03/14 15:38:16 nicklin Exp $ */
-
- /*
- * Author: Peter J. Nicklin
- */
- #include "null.h"
- #include "hash.h"
- #include "macro.h"
-
- /*
- * hthash() returns a hash value for string, s.
- */
- hthash(s, hash)
- register char *s; /* string */
- HASH *hash; /* hash table */
- {
- register int hashval; /* hash value for string */
-
- for (hashval = 0; *s != '\0'; s++)
- hashval += *s;
- return(hashval % hash->hashsiz);
- }
-
-
-
- /*
- * htinit() returns a pointer to a new hash table, or a null pointer if
- * out of memory.
- */
- HASH *
- htinit(hashsiz)
- unsigned int hashsiz; /* hash table size */
- {
- char *malloc(); /* allocate memory */
- char *calloc(); /* allocate and zero memory */
- HASH *ht; /* pointer to hash table struct */
- HASHBLK **pt; /* pointer to hash pointer table */
-
- if ((ht = (HASH *) malloc(sizeof(HASH))) == NULL ||
- (pt = (HASHBLK **) calloc(hashsiz, sizeof(HASHBLK *))) == NULL)
- {
- warn("out of memory");
- return(NULL);
- }
- ht->hashtab = pt;
- ht->hashsiz = hashsiz;
- return(ht);
- }
-
-
-
- /*
- * htinstall() installs a new entry in a hash table if it doesn't already
- * exist. If it does, the old definition and value is superseded. Returns
- * a pointer to the entry, or null if out of memory.
- */
- HASHBLK *
- htinstall(key, def, val, hash)
- char *key; /* key for hash table entry */
- char *def; /* definition string */
- int val; /* integer value */
- HASH *hash; /* hash table */
- {
- char *malloc(); /* memory allocator */
- char *strsav(); /* save string somewhere */
- HASHBLK *htb; /* hash table entry block */
- HASHBLK *htlookup(); /* find hash table entry */
- int hashval; /* hash value for key */
- int hthash(); /* calculate hash value */
-
- if ((htb = htlookup(key, hash)) == NULL)
- { /* not found */
- if ((htb = (HASHBLK *) malloc(sizeof(HASHBLK))) == NULL)
- return(NULL);
- if ((htb->h_key = strsav(key)) == NULL)
- return(NULL);
- hashval = hthash(key, hash);
- htb->h_next = (hash->hashtab)[hashval];
- (hash->hashtab)[hashval] = htb;
- htb->h_sub = NULL;
- htb->h_tag = NULL;
- }
- else { /* found */
- free(htb->h_def); /* free previous definition */
- }
- if ((htb->h_def = strsav(def)) == NULL)
- return(NULL);
- htb->h_val = val;
- return(htb);
- }
-
-
-
- /*
- * htlookup() returns a pointer to a hash table entry if found, otherwise null.
- */
- HASHBLK *
- htlookup(key, hash)
- char *key; /* key for hash table entry */
- HASH *hash; /* hash table */
- {
- HASHBLK *htb; /* hash table entry block */
- int hthash(); /* calculate hash value */
-
- for (htb = (hash->hashtab)[hthash(key, hash)]; htb != NULL; htb = htb->h_next)
- if (EQUAL(htb->h_key, key))
- return(htb); /* found */
- return(NULL); /* not found */
- }
-
-
-
- /*
- * htrm() removes a hash table entry. If key is null, the entire hash
- * table is removed.
- */
- void
- htrm(key, hash)
- char *key; /* key for hash table entry */
- HASH *hash; /* hash table */
- {
- HASHBLK *htbrm(); /* remove hash table block */
- HASHBLK *htc; /* first hash table block in chain */
- int hashval; /* hash value for key */
- int hthash(); /* compute hash value */
- int i; /* hash table index */
-
- if (key == NULL)
- {
- for (i = 0; i < hash->hashsiz; i++)
- if ((htc = (hash->hashtab)[i]) != NULL)
- htc = htbrm(key, htc);
- free((char *) hash);
- }
- else {
- hashval = hthash(key, hash);
- if ((htc = (hash->hashtab)[hashval]) != NULL)
- (hash->hashtab)[hashval] = htbrm(key, htc);
- }
- }
-
-
-
- /*
- * htbrm() removes a hash table block identified by key. If key is null, the
- * entire chain is removed. Returns a pointer to the first block in the chain.
- */
- HASHBLK *
- htbrm(key, htc)
- char *key; /* key string */
- HASHBLK *htc; /* hash table block chain */
- {
- HASHBLK *curblk; /* current list block */
- HASHBLK *nxtblk; /* next list block */
- HASHBLK *prvblk; /* previous list block */
-
- if (key == NULL)
- while (htc != NULL)
- {
- nxtblk = htc->h_next;
- free(htc->h_key);
- free(htc->h_def);
- free((char *) htc);
- htc = nxtblk;
- }
- else {
- /* first block is a special case */
- if (EQUAL(htc->h_key, key))
- {
- nxtblk = htc->h_next;
- free(htc->h_key);
- free(htc->h_def);
- free((char *) htc);
- htc = nxtblk;
- }
- else {
- /* remainder of list */
- prvblk = htc;
- curblk = htc->h_next;
- while (curblk != NULL)
- if (EQUAL(curblk->h_key, key))
- {
- prvblk->h_next = curblk->h_next;
- free(curblk->h_key);
- free(curblk->h_def);
- free((char *) curblk);
- curblk = prvblk->h_next;
- break;
- }
- else {
- prvblk = curblk;
- curblk = curblk->h_next;
- }
- }
- }
- return(htc);
- }
-