(mu_assoc_create): Take 3 arguments
(mu_assoc_clear, mu_assoc_destroy): New functions
Showing
1 changed file
with
56 additions
and
8 deletions
... | @@ -44,12 +44,13 @@ static unsigned int max_rehash = sizeof (hash_size) / sizeof (hash_size[0]); | ... | @@ -44,12 +44,13 @@ static unsigned int max_rehash = sizeof (hash_size) / sizeof (hash_size[0]); |
44 | 44 | ||
45 | struct _mu_assoc_elem | 45 | struct _mu_assoc_elem |
46 | { | 46 | { |
47 | char *name; | 47 | const char *name; |
48 | char data[1]; | 48 | char data[1]; |
49 | }; | 49 | }; |
50 | 50 | ||
51 | struct _mu_assoc | 51 | struct _mu_assoc |
52 | { | 52 | { |
53 | int flags; | ||
53 | unsigned int hash_num; /* Index to hash_size table */ | 54 | unsigned int hash_num; /* Index to hash_size table */ |
54 | size_t elsize; /* Size of an element */ | 55 | size_t elsize; /* Size of an element */ |
55 | void *tab; | 56 | void *tab; |
... | @@ -121,6 +122,15 @@ assoc_rehash (mu_assoc_t assoc) | ... | @@ -121,6 +122,15 @@ assoc_rehash (mu_assoc_t assoc) |
121 | return 0; | 122 | return 0; |
122 | } | 123 | } |
123 | 124 | ||
125 | static void | ||
126 | assoc_free_elem (mu_assoc_t assoc, struct _mu_assoc_elem *elem) | ||
127 | { | ||
128 | if (assoc->free) | ||
129 | assoc->free (elem->data); | ||
130 | if (!(assoc->flags & MU_ASSOC_COPY_KEY)) | ||
131 | free (elem->name); | ||
132 | } | ||
133 | |||
124 | static int | 134 | static int |
125 | assoc_remove (mu_assoc_t assoc, struct _mu_assoc_elem *elem) | 135 | assoc_remove (mu_assoc_t assoc, struct _mu_assoc_elem *elem) |
126 | { | 136 | { |
... | @@ -130,11 +140,7 @@ assoc_remove (mu_assoc_t assoc, struct _mu_assoc_elem *elem) | ... | @@ -130,11 +140,7 @@ assoc_remove (mu_assoc_t assoc, struct _mu_assoc_elem *elem) |
130 | && elem < ASSOC_ELEM (assoc, hash_size[assoc->hash_num]))) | 140 | && elem < ASSOC_ELEM (assoc, hash_size[assoc->hash_num]))) |
131 | return EINVAL; | 141 | return EINVAL; |
132 | 142 | ||
133 | if (assoc->free) | 143 | assoc_free_elem (assoc, elem); |
134 | { | ||
135 | assoc->free (elem->data); | ||
136 | free (elem->name); | ||
137 | } | ||
138 | 144 | ||
139 | for (i = ASSOC_ELEM_INDEX (assoc, elem);;) | 145 | for (i = ASSOC_ELEM_INDEX (assoc, elem);;) |
140 | { | 146 | { |
... | @@ -158,6 +164,9 @@ assoc_remove (mu_assoc_t assoc, struct _mu_assoc_elem *elem) | ... | @@ -158,6 +164,9 @@ assoc_remove (mu_assoc_t assoc, struct _mu_assoc_elem *elem) |
158 | return 0; | 164 | return 0; |
159 | } | 165 | } |
160 | 166 | ||
167 | #define name_cmp(assoc,a,b) (((assoc)->flags & MU_ASSOC_ICASE) ? \ | ||
168 | strcasecmp(a,b) : strcmp(a,b)) | ||
169 | |||
161 | static int | 170 | static int |
162 | assoc_lookup_or_install (struct _mu_assoc_elem **elp, | 171 | assoc_lookup_or_install (struct _mu_assoc_elem **elp, |
163 | mu_assoc_t assoc, const char *name, int *install) | 172 | mu_assoc_t assoc, const char *name, int *install) |
... | @@ -182,7 +191,7 @@ assoc_lookup_or_install (struct _mu_assoc_elem **elp, | ... | @@ -182,7 +191,7 @@ assoc_lookup_or_install (struct _mu_assoc_elem **elp, |
182 | 191 | ||
183 | for (i = pos; (elem = ASSOC_ELEM (assoc, i))->name;) | 192 | for (i = pos; (elem = ASSOC_ELEM (assoc, i))->name;) |
184 | { | 193 | { |
185 | if (strcmp (elem->name, name) == 0) | 194 | if (name_cmp (assoc, elem->name, name) == 0) |
186 | { | 195 | { |
187 | if (install) | 196 | if (install) |
188 | *install = 0; | 197 | *install = 0; |
... | @@ -202,9 +211,14 @@ assoc_lookup_or_install (struct _mu_assoc_elem **elp, | ... | @@ -202,9 +211,14 @@ assoc_lookup_or_install (struct _mu_assoc_elem **elp, |
202 | if (elem->name == NULL) | 211 | if (elem->name == NULL) |
203 | { | 212 | { |
204 | *install = 1; | 213 | *install = 1; |
214 | if (assoc->flags & MU_ASSOC_COPY_KEY) | ||
215 | elem->name = name; | ||
216 | else | ||
217 | { | ||
205 | elem->name = strdup (name); | 218 | elem->name = strdup (name); |
206 | if (!elem->name) | 219 | if (!elem->name) |
207 | return ENOMEM; | 220 | return ENOMEM; |
221 | } | ||
208 | *elp = elem; | 222 | *elp = elem; |
209 | return 0; | 223 | return 0; |
210 | } | 224 | } |
... | @@ -216,16 +230,50 @@ assoc_lookup_or_install (struct _mu_assoc_elem **elp, | ... | @@ -216,16 +230,50 @@ assoc_lookup_or_install (struct _mu_assoc_elem **elp, |
216 | } | 230 | } |
217 | 231 | ||
218 | int | 232 | int |
219 | mu_assoc_create (mu_assoc_t *passoc, size_t elsize) | 233 | mu_assoc_create (mu_assoc_t *passoc, size_t elsize, int flags) |
220 | { | 234 | { |
221 | mu_assoc_t assoc = calloc (1, sizeof (*assoc)); | 235 | mu_assoc_t assoc = calloc (1, sizeof (*assoc)); |
222 | if (!assoc) | 236 | if (!assoc) |
223 | return ENOMEM; | 237 | return ENOMEM; |
238 | assoc->flags = flags; | ||
224 | assoc->elsize = elsize; | 239 | assoc->elsize = elsize; |
225 | *passoc = assoc; | 240 | *passoc = assoc; |
226 | return 0; | 241 | return 0; |
227 | } | 242 | } |
228 | 243 | ||
244 | void | ||
245 | mu_assoc_clear (mu_assoc_t assoc) | ||
246 | { | ||
247 | unsigned i, hs; | ||
248 | |||
249 | if (!assoc) | ||
250 | return; | ||
251 | |||
252 | hs = hash_size[assoc->hash_num]; | ||
253 | for (i = 0; i < hs; i++) | ||
254 | { | ||
255 | struct _mu_assoc_elem *elem = ASSOC_ELEM (assoc, i); | ||
256 | if (elem->name) | ||
257 | { | ||
258 | assoc_free_elem (assoc, elem); | ||
259 | elem->name = NULL; | ||
260 | } | ||
261 | } | ||
262 | } | ||
263 | |||
264 | void | ||
265 | mu_assoc_destroy (mu_assoc_t *passoc) | ||
266 | { | ||
267 | mu_assoc_t assoc; | ||
268 | if (passoc && (assoc = *passoc) != NULL) | ||
269 | { | ||
270 | mu_assoc_clear (assoc); | ||
271 | free (assoc->tab); | ||
272 | free (assoc); | ||
273 | *passoc = NULL; | ||
274 | } | ||
275 | } | ||
276 | |||
229 | int | 277 | int |
230 | mu_assoc_set_free (mu_assoc_t assoc, mu_assoc_free_fn fn) | 278 | mu_assoc_set_free (mu_assoc_t assoc, mu_assoc_free_fn fn) |
231 | { | 279 | { | ... | ... |
-
Please register or sign in to post a comment