]> git.saurik.com Git - wxWidgets.git/blame - src/xpm/hashtab.c
usleep() prototype added for solaris
[wxWidgets.git] / src / xpm / hashtab.c
CommitLineData
cfbe03c9
JS
1/*
2 * Copyright (C) 1989-94 GROUPE BULL
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a copy
5 * of this software and associated documentation files (the "Software"), to
6 * deal in the Software without restriction, including without limitation the
7 * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
8 * sell copies of the Software, and to permit persons to whom the Software is
9 * furnished to do so, subject to the following conditions:
10 *
11 * The above copyright notice and this permission notice shall be included in
12 * all copies or substantial portions of the Software.
13 *
14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
17 * GROUPE BULL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
18 * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
19 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
20 *
21 * Except as contained in this notice, the name of GROUPE BULL shall not be
22 * used in advertising or otherwise to promote the sale, use or other dealings
23 * in this Software without prior written authorization from GROUPE BULL.
24 */
25
26/*****************************************************************************\
27* hashtable.c: *
28* *
29* XPM library *
30* *
31* Developed by Arnaud Le Hors *
32* this originaly comes from Colas Nahaboo as a part of Wool *
33* *
34\*****************************************************************************/
35
36#include "xpm34p.h"
37
38LFUNC(AtomMake, xpmHashAtom, (char *name, void *data));
39LFUNC(HashTableGrows, int, (xpmHashTable * table));
40
41static xpmHashAtom
42AtomMake(char *name, void *data) /* makes an atom */
43/* char *name; */ /* WARNING: is just pointed to */
44/* void *data; */
45{
46 xpmHashAtom object = (xpmHashAtom) XpmMalloc(sizeof(struct _xpmHashAtom));
47
48 if (object) {
49 object->name = name;
50 object->data = data;
51 }
52 return object;
53}
54
55/************************\
56* *
57* hash table routines *
58* *
59\************************/
60
61/*
62 * Hash function definition:
63 * HASH_FUNCTION: hash function, hash = hashcode, hp = pointer on char,
64 * hash2 = temporary for hashcode.
65 * INITIAL_TABLE_SIZE in slots
66 * HASH_TABLE_GROWS how hash table grows.
67 */
68
69/* Mock lisp function */
70#define HASH_FUNCTION hash = (hash << 5) - hash + *hp++;
71/* #define INITIAL_HASH_SIZE 2017 */
72#define INITIAL_HASH_SIZE 256 /* should be enough for colors */
73#define HASH_TABLE_GROWS size = size * 2;
74
75/* aho-sethi-ullman's HPJ (sizes should be primes)*/
76#ifdef notdef
77#define HASH_FUNCTION hash <<= 4; hash += *hp++; \
78 if(hash2 = hash & 0xf0000000) hash ^= (hash2 >> 24) ^ hash2;
79#define INITIAL_HASH_SIZE 4095 /* should be 2^n - 1 */
80#define HASH_TABLE_GROWS size = size << 1 + 1;
81#endif
82
83/* GNU emacs function */
84/*
85#define HASH_FUNCTION hash = (hash << 3) + (hash >> 28) + *hp++;
86#define INITIAL_HASH_SIZE 2017
87#define HASH_TABLE_GROWS size = size * 2;
88*/
89
90/* end of hash functions */
91
92/*
93 * The hash table is used to store atoms via their NAME:
94 *
95 * NAME --hash--> ATOM |--name--> "foo"
96 * |--data--> any value which has to be stored
97 *
98 */
99
100/*
101 * xpmHashSlot gives the slot (pointer to xpmHashAtom) of a name
102 * (slot points to NULL if it is not defined)
103 *
104 */
105
106xpmHashAtom *
107xpmHashSlot(xpmHashTable *table, char *s)
108{
109 xpmHashAtom *atomTable = table->atomTable;
110 unsigned int hash;
111 xpmHashAtom *p;
112 char *hp = s;
113 char *ns;
114
115 hash = 0;
116 while (*hp) { /* computes hash function */
117 HASH_FUNCTION
118 }
119 p = atomTable + hash % table->size;
120 while (*p) {
121 ns = (*p)->name;
122 if (ns[0] == s[0] && strcmp(ns, s) == 0)
123 break;
124 p--;
125 if (p < atomTable)
126 p = atomTable + table->size - 1;
127 }
128 return p;
129}
130
131static int
132HashTableGrows(xpmHashTable *table)
133{
134 xpmHashAtom *atomTable = table->atomTable;
135 int size = table->size;
136 xpmHashAtom *t, *p;
137 int i;
138 int oldSize = size;
139
140 t = atomTable;
141 HASH_TABLE_GROWS
142 table->size = size;
143 table->limit = size / 3;
144 atomTable = (xpmHashAtom *) XpmMalloc(size * sizeof(*atomTable));
145 if (!atomTable)
146 return (XpmNoMemory);
147 table->atomTable = atomTable;
148 for (p = atomTable + size; p > atomTable;)
149 *--p = NULL;
150 for (i = 0, p = t; i < oldSize; i++, p++)
151 if (*p) {
152 xpmHashAtom *ps = xpmHashSlot(table, (*p)->name);
153
154 *ps = *p;
155 }
156 XpmFree(t);
157 return (XpmSuccess);
158}
159
160/*
161 * xpmHashIntern(table, name, data)
162 * an xpmHashAtom is created if name doesn't exist, with the given data.
163 */
164
165int
166xpmHashIntern(xpmHashTable *table, char *tag, void *data)
167{
168 xpmHashAtom *slot;
169
170 if (!*(slot = xpmHashSlot(table, tag))) {
171 /* undefined, make a new atom with the given data */
172 if (!(*slot = AtomMake(tag, data)))
173 return (XpmNoMemory);
174 if (table->used >= table->limit) {
175 int ErrorStatus;
176
177 if ((ErrorStatus = HashTableGrows(table)) != XpmSuccess)
178 return (ErrorStatus);
179 table->used++;
180 return (XpmSuccess);
181 }
182 table->used++;
183 }
184 return (XpmSuccess);
185}
186
187/*
188 * must be called before allocating any atom
189 */
190
191int
192xpmHashTableInit(xpmHashTable *table)
193{
194 xpmHashAtom *p;
195 xpmHashAtom *atomTable;
196
197 table->size = INITIAL_HASH_SIZE;
198 table->limit = table->size / 3;
199 table->used = 0;
200 atomTable = (xpmHashAtom *) XpmMalloc(table->size * sizeof(*atomTable));
201 if (!atomTable)
202 return (XpmNoMemory);
203 for (p = atomTable + table->size; p > atomTable;)
204 *--p = NULL;
205 table->atomTable = atomTable;
206 return (XpmSuccess);
207}
208
209/*
210 * frees a hashtable and all the stored atoms
211 */
212
213void
214xpmHashTableFree(xpmHashTable *table)
215{
216 xpmHashAtom *p;
217 xpmHashAtom *atomTable = table->atomTable;
218
219 for (p = atomTable + table->size; p > atomTable;)
220 if (*--p)
221 XpmFree(*p);
222 XpmFree(atomTable);
223 table->atomTable = NULL;
224}