Commit e359804b e359804b7564824d7e4638de589469a70d4fb101 by Sergey Poznyakoff

(mu_assoc_create): Take 3 arguments

(mu_assoc_clear, mu_assoc_destroy): New functions
1 parent 718d0119
...@@ -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 {
......