1 | |
2 | |
3 | |
4 | |
5 | |
6 | |
7 | |
8 | |
9 | |
10 | |
11 | |
12 | |
13 | |
14 | |
15 | |
16 | |
17 | |
18 | |
19 | |
20 | |
21 | |
22 | |
23 | |
24 | |
25 | |
26 | |
27 | |
28 | |
29 | |
30 | |
31 | |
32 | |
33 | |
34 | |
35 | |
36 | #ifdef HAVE_CONFIG_H1 |
37 | #include <config.h> |
38 | #endif |
39 | #include "XpmI.h" |
40 | |
41 | LFUNC(AtomMake, xpmHashAtom, (char *name, void *data))static xpmHashAtom AtomMake (char *name, void *data); |
42 | LFUNC(HashTableGrows, int, (xpmHashTable * table))static int HashTableGrows (xpmHashTable * table); |
43 | |
44 | static xpmHashAtom |
45 | AtomMake( |
46 | char *name, |
47 | void *data) |
48 | { |
49 | xpmHashAtom object = (xpmHashAtom) XpmMalloc(sizeof(struct _xpmHashAtom))malloc((sizeof(struct _xpmHashAtom))); |
50 | |
51 | if (object) { |
52 | object->name = name; |
53 | object->data = data; |
54 | } |
55 | return object; |
56 | } |
57 | |
58 | |
59 | |
60 | |
61 | |
62 | |
63 | |
64 | |
65 | |
66 | |
67 | |
68 | |
69 | |
70 | |
71 | |
72 | |
73 | #define HASH_FUNCTIONhash = (hash << 5) - hash + *hp++; hash = (hash << 5) - hash + *hp++; |
74 | |
75 | #define INITIAL_HASH_SIZE256 256 /* should be enough for colors */ |
76 | #define HASH_TABLE_GROWSsize = size * 2; size = size * 2; |
77 | |
78 | |
79 | #ifdef notdef |
80 | #define HASH_FUNCTIONhash = (hash << 5) - hash + *hp++; hash <<= 4; hash += *hp++; \ |
81 | if(hash2 = hash & 0xf0000000) hash ^= (hash2 >> 24) ^ hash2; |
82 | #define INITIAL_HASH_SIZE256 4095 /* should be 2^n - 1 */ |
83 | #define HASH_TABLE_GROWSsize = size * 2; size = size << 1 + 1; |
84 | #endif |
85 | |
86 | |
87 | |
88 | |
89 | |
90 | |
91 | |
92 | |
93 | |
94 | |
95 | |
96 | |
97 | |
98 | |
99 | |
100 | |
101 | |
102 | |
103 | |
104 | |
105 | |
106 | |
107 | |
108 | |
109 | xpmHashAtom * |
110 | xpmHashSlot( |
111 | xpmHashTable *table, |
112 | char *s) |
113 | { |
114 | xpmHashAtom *atomTable = table->atomTable; |
115 | unsigned int hash; |
116 | xpmHashAtom *p; |
117 | char *hp = s; |
118 | char *ns; |
119 | |
120 | hash = 0; |
121 | while (*hp) { |
| 23 | | Loop condition is false. Execution continues on line 124 | |
|
122 | HASH_FUNCTIONhash = (hash << 5) - hash + *hp++; |
123 | } |
124 | p = atomTable + hash % table->size; |
| |
125 | while (*p) { |
126 | ns = (*p)->name; |
127 | if (ns[0] == s[0] && strcmp(ns, s) == 0) |
128 | break; |
129 | p--; |
130 | if (p < atomTable) |
131 | p = atomTable + table->size - 1; |
132 | } |
133 | return p; |
134 | } |
135 | |
136 | static int |
137 | HashTableGrows(xpmHashTable *table) |
138 | { |
139 | xpmHashAtom *atomTable = table->atomTable; |
140 | unsigned int size = table->size; |
141 | xpmHashAtom *t, *p; |
142 | int i; |
143 | unsigned int oldSize = size; |
144 | |
145 | t = atomTable; |
146 | HASH_TABLE_GROWSsize = size * 2; |
147 | table->size = size; |
| 5 | | Value assigned to field 'size' | |
|
148 | table->limit = size / 3; |
149 | if (size >= UINT_MAX(2147483647 *2U +1U) / sizeof(*atomTable)) |
| |
150 | return (XpmNoMemory-3); |
151 | atomTable = (xpmHashAtom *) XpmMalloc(size * sizeof(*atomTable))malloc((size * sizeof(*atomTable))); |
152 | if (!atomTable) |
| 7 | | Assuming 'atomTable' is non-null | |
|
| |
153 | return (XpmNoMemory-3); |
154 | table->atomTable = atomTable; |
155 | for (p = atomTable + size; p > atomTable;) |
| 9 | | Assuming 'p' is <= 'atomTable' | |
|
| 10 | | Loop condition is false. Execution continues on line 157 | |
|
156 | *--p = NULL((void*)0); |
157 | for (i = 0, p = t; i < oldSize; i++, p++) |
| 11 | | Loop condition is true. Entering loop body | |
|
| 13 | | Assuming 'i' is < 'oldSize' | |
|
| 14 | | Loop condition is true. Entering loop body | |
|
| 16 | | Assuming 'i' is < 'oldSize' | |
|
| 17 | | Loop condition is true. Entering loop body | |
|
| 19 | | Assuming 'i' is < 'oldSize' | |
|
| 20 | | Loop condition is true. Entering loop body | |
|
158 | if (*p) { |
| |
| |
| |
| |
159 | xpmHashAtom *ps = xpmHashSlot(table, (*p)->name); |
| |
160 | |
161 | *ps = *p; |
162 | } |
163 | XpmFree(t)free(t); |
164 | return (XpmSuccess0); |
165 | } |
166 | |
167 | |
168 | |
169 | |
170 | |
171 | |
172 | int |
173 | xpmHashIntern( |
174 | xpmHashTable *table, |
175 | char *tag, |
176 | void *data) |
177 | { |
178 | xpmHashAtom *slot; |
179 | |
180 | if (!*(slot = xpmHashSlot(table, tag))) { |
| |
181 | |
182 | if (!(*slot = AtomMake(tag, data))) |
| |
183 | return (XpmNoMemory-3); |
184 | if (table->used >= table->limit) { |
| |
185 | int ErrorStatus; |
186 | |
187 | if ((ErrorStatus = HashTableGrows(table)) != XpmSuccess0) |
| 4 | | Calling 'HashTableGrows' | |
|
188 | return (ErrorStatus); |
189 | table->used++; |
190 | return (XpmSuccess0); |
191 | } |
192 | table->used++; |
193 | } |
194 | return (XpmSuccess0); |
195 | } |
196 | |
197 | |
198 | |
199 | |
200 | |
201 | int |
202 | xpmHashTableInit(xpmHashTable *table) |
203 | { |
204 | xpmHashAtom *p; |
205 | xpmHashAtom *atomTable; |
206 | |
207 | table->size = INITIAL_HASH_SIZE256; |
208 | table->limit = table->size / 3; |
209 | table->used = 0; |
210 | table->atomTable = NULL((void*)0); |
211 | if (table->size >= UINT_MAX(2147483647 *2U +1U) / sizeof(*atomTable)) |
212 | return (XpmNoMemory-3); |
213 | atomTable = (xpmHashAtom *) XpmMalloc(table->size * sizeof(*atomTable))malloc((table->size * sizeof(*atomTable))); |
214 | if (!atomTable) |
215 | return (XpmNoMemory-3); |
216 | for (p = atomTable + table->size; p > atomTable;) |
217 | *--p = NULL((void*)0); |
218 | table->atomTable = atomTable; |
219 | return (XpmSuccess0); |
220 | } |
221 | |
222 | |
223 | |
224 | |
225 | |
226 | void |
227 | xpmHashTableFree(xpmHashTable *table) |
228 | { |
229 | xpmHashAtom *p; |
230 | xpmHashAtom *atomTable = table->atomTable; |
231 | |
232 | if (!atomTable) |
233 | return; |
234 | for (p = atomTable + table->size; p > atomTable;) |
235 | if (*--p) |
236 | XpmFree(*p)free(*p); |
237 | XpmFree(atomTable)free(atomTable); |
238 | table->atomTable = NULL((void*)0); |
239 | } |