This commit was manufactured by cvs2svn to create tag 'FreeBSD-release/1.0'.
[unix-history] / usr.bin / m4 / look.c
CommitLineData
78ed81a3 1/* File : look.c
2 Author : Ozan Yigit
3 Updated: 4 May 1992
4 Purpose: Hash table for M4
5*/
15637ed4 6
15637ed4
RG
7#include "mdef.h"
8#include "extr.h"
9
78ed81a3 10ndptr hashtab[HASHSIZE];
11
12
15637ed4 13/*
78ed81a3 14 * hash - get a hash value for string s
15637ed4 15 */
78ed81a3 16int
17hash(name)
18char *name;
15637ed4 19{
78ed81a3 20 register unsigned long h = 0;
21
22 while (*name)
23 h = (h << 5) + h + *name++;
24
25 return h % HASHSIZE;
15637ed4
RG
26}
27
78ed81a3 28/*
29 * lookup(name) - find name in the hash table
15637ed4
RG
30 */
31ndptr lookup(name)
78ed81a3 32 char *name;
33 {
15637ed4
RG
34 register ndptr p;
35
36 for (p = hashtab[hash(name)]; p != nil; p = p->nxtptr)
78ed81a3 37 if (strcmp(name, p->name) == 0)
38 break;
39 return p;
40 }
15637ed4 41
78ed81a3 42/*
43 * addent(name) - hash and create an entry in the hash table.
44 * The new entry is added at the front of a hash bucket.
45 * BEWARE: the type and defn fields are UNDEFINED.
15637ed4
RG
46 */
47ndptr addent(name)
78ed81a3 48 char *name;
49 {
50 register ndptr p, *h;
51
52 p = (ndptr)malloc(sizeof *p);
53 if (p == NULL) error("m4: no more memory.");
54 h = &hashtab[hash(name)];
55 p->name = strsave(name);
56 p->defn = null;
57 p->nxtptr = *h;
58 *h = p;
15637ed4 59 return p;
78ed81a3 60 }
15637ed4 61
78ed81a3 62
63/*
64 * addkywd(name, type) - stores a keyword in the hash table.
15637ed4 65 */
78ed81a3 66void addkywd(name, type)
67 char *name;
68 int type;
69 {
70 register ndptr p = addent(name);
71 p->type = type | STATIC;
72 }
15637ed4 73
78ed81a3 74
75/*
76 * remhash(name, all)
77 * remove one entry (all==0) or all entries (all!=0) for a given name
78 * from the hash table. All hash table entries must have been obtained
79 * from malloc(), so it is safe to free the records themselves.
80 * However, the ->name and ->defn fields might point to storage which
81 * was obtained from strsave() -- in which case they may be freed -- or
82 * to static storage -- in which case they must not be freed. If the
83 * STATIC bit is set, the fields are not to be freed.
15637ed4 84 */
78ed81a3 85void remhash(name, all)
86 char *name;
87 int all;
88 {
89 register ndptr p, *h;
90 /* h always points to the pointer to p */
91
92 h = &hashtab[hash(name)];
93 while ((p = *h) != nil) {
94 if (strcmp(p->name, name) == 0) {
95 *h = p->nxtptr; /* delink this record */
96 if (!(p->type & STATIC)) { /* free the name and defn */
97 free(p->name); /* if they came from strsave */
98 if (p->defn != null) free(p->defn);
99 } /* otherwise leave them */
100 free(p); /* free the record itself */
101 if (!all) return; /* first occurrence has gone */
102 } else {
103 h = &(p->nxtptr);
104 }
15637ed4 105 }
78ed81a3 106 }
15637ed4 107