Purpose: Hash table for M4
* hash - get a hash value for string s
register unsigned long h
= 0;
h
= (h
<< 5) + h
+ *name
++;
* lookup(name) - find name in the hash table
for (p
= hashtab
[hash(name
)]; p
!= nil
; p
= p
->nxtptr
)
if (strcmp(name
, p
->name
) == 0)
* addent(name) - hash and create an entry in the hash table.
* The new entry is added at the front of a hash bucket.
* BEWARE: the type and defn fields are UNDEFINED.
p
= (ndptr
)malloc(sizeof *p
);
if (p
== NULL
) error("m4: no more memory.");
h
= &hashtab
[hash(name
)];
* addkywd(name, type) - stores a keyword in the hash table.
register ndptr p
= addent(name
);
* remove one entry (all==0) or all entries (all!=0) for a given name
* from the hash table. All hash table entries must have been obtained
* from malloc(), so it is safe to free the records themselves.
* However, the ->name and ->defn fields might point to storage which
* was obtained from strsave() -- in which case they may be freed -- or
* to static storage -- in which case they must not be freed. If the
* STATIC bit is set, the fields are not to be freed.
/* h always points to the pointer to p */
h
= &hashtab
[hash(name
)];
while ((p
= *h
) != nil
) {
if (strcmp(p
->name
, name
) == 0) {
*h
= p
->nxtptr
; /* delink this record */
if (!(p
->type
& STATIC
)) { /* free the name and defn */
free(p
->name
); /* if they came from strsave */
if (p
->defn
!= null
) free(p
->defn
);
} /* otherwise leave them */
free(p
); /* free the record itself */
if (!all
) return; /* first occurrence has gone */