Commit | Line | Data |
---|---|---|
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 | 10 | ndptr hashtab[HASHSIZE]; |
11 | ||
12 | ||
15637ed4 | 13 | /* |
78ed81a3 | 14 | * hash - get a hash value for string s |
15637ed4 | 15 | */ |
78ed81a3 | 16 | int |
17 | hash(name) | |
18 | char *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 | */ |
31 | ndptr 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 | */ |
47 | ndptr 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 | 66 | void 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 | 85 | void 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 |