xref: /minix3/external/bsd/bind/dist/lib/isccc/symtab.c (revision 00b67f09dd46474d133c95011a48590a8e8f94c7)
1*00b67f09SDavid van Moolenbroek /*	$NetBSD: symtab.c,v 1.4 2014/12/10 04:38:01 christos Exp $	*/
2*00b67f09SDavid van Moolenbroek 
3*00b67f09SDavid van Moolenbroek /*
4*00b67f09SDavid van Moolenbroek  * Portions Copyright (C) 2004, 2005, 2007  Internet Systems Consortium, Inc. ("ISC")
5*00b67f09SDavid van Moolenbroek  * Portions Copyright (C) 2001  Internet Software Consortium.
6*00b67f09SDavid van Moolenbroek  *
7*00b67f09SDavid van Moolenbroek  * Permission to use, copy, modify, and/or distribute this software for any
8*00b67f09SDavid van Moolenbroek  * purpose with or without fee is hereby granted, provided that the above
9*00b67f09SDavid van Moolenbroek  * copyright notice and this permission notice appear in all copies.
10*00b67f09SDavid van Moolenbroek  *
11*00b67f09SDavid van Moolenbroek  * THE SOFTWARE IS PROVIDED "AS IS" AND ISC AND NOMINUM DISCLAIMS ALL
12*00b67f09SDavid van Moolenbroek  * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES
13*00b67f09SDavid van Moolenbroek  * OF MERCHANTABILITY AND FITNESS.  IN NO EVENT SHALL ISC BE LIABLE FOR ANY
14*00b67f09SDavid van Moolenbroek  * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
15*00b67f09SDavid van Moolenbroek  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
16*00b67f09SDavid van Moolenbroek  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
17*00b67f09SDavid van Moolenbroek  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
18*00b67f09SDavid van Moolenbroek  *
19*00b67f09SDavid van Moolenbroek  * Portions Copyright (C) 2001  Nominum, Inc.
20*00b67f09SDavid van Moolenbroek  *
21*00b67f09SDavid van Moolenbroek  * Permission to use, copy, modify, and/or distribute this software for any
22*00b67f09SDavid van Moolenbroek  * purpose with or without fee is hereby granted, provided that the above
23*00b67f09SDavid van Moolenbroek  * copyright notice and this permission notice appear in all copies.
24*00b67f09SDavid van Moolenbroek  *
25*00b67f09SDavid van Moolenbroek  * THE SOFTWARE IS PROVIDED "AS IS" AND ISC AND NOMINUM DISCLAIMS ALL
26*00b67f09SDavid van Moolenbroek  * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES
27*00b67f09SDavid van Moolenbroek  * OF MERCHANTABILITY AND FITNESS.  IN NO EVENT SHALL ISC BE LIABLE FOR ANY
28*00b67f09SDavid van Moolenbroek  * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
29*00b67f09SDavid van Moolenbroek  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
30*00b67f09SDavid van Moolenbroek  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
31*00b67f09SDavid van Moolenbroek  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
32*00b67f09SDavid van Moolenbroek  */
33*00b67f09SDavid van Moolenbroek 
34*00b67f09SDavid van Moolenbroek /* Id: symtab.c,v 1.11 2007/09/13 04:45:18 each Exp  */
35*00b67f09SDavid van Moolenbroek 
36*00b67f09SDavid van Moolenbroek /*! \file */
37*00b67f09SDavid van Moolenbroek 
38*00b67f09SDavid van Moolenbroek #include <config.h>
39*00b67f09SDavid van Moolenbroek 
40*00b67f09SDavid van Moolenbroek #include <ctype.h>
41*00b67f09SDavid van Moolenbroek #include <stdlib.h>
42*00b67f09SDavid van Moolenbroek 
43*00b67f09SDavid van Moolenbroek #include <isc/assertions.h>
44*00b67f09SDavid van Moolenbroek #include <isc/magic.h>
45*00b67f09SDavid van Moolenbroek #include <isc/string.h>
46*00b67f09SDavid van Moolenbroek 
47*00b67f09SDavid van Moolenbroek #include <isccc/result.h>
48*00b67f09SDavid van Moolenbroek #include <isccc/symtab.h>
49*00b67f09SDavid van Moolenbroek #include <isccc/util.h>
50*00b67f09SDavid van Moolenbroek 
51*00b67f09SDavid van Moolenbroek typedef struct elt {
52*00b67f09SDavid van Moolenbroek 	char *				key;
53*00b67f09SDavid van Moolenbroek 	unsigned int			type;
54*00b67f09SDavid van Moolenbroek 	isccc_symvalue_t			value;
55*00b67f09SDavid van Moolenbroek 	ISC_LINK(struct elt)		link;
56*00b67f09SDavid van Moolenbroek } elt_t;
57*00b67f09SDavid van Moolenbroek 
58*00b67f09SDavid van Moolenbroek typedef ISC_LIST(elt_t)			eltlist_t;
59*00b67f09SDavid van Moolenbroek 
60*00b67f09SDavid van Moolenbroek #define SYMTAB_MAGIC			ISC_MAGIC('S', 'y', 'm', 'T')
61*00b67f09SDavid van Moolenbroek #define VALID_SYMTAB(st)		ISC_MAGIC_VALID(st, SYMTAB_MAGIC)
62*00b67f09SDavid van Moolenbroek 
63*00b67f09SDavid van Moolenbroek struct isccc_symtab {
64*00b67f09SDavid van Moolenbroek 	unsigned int			magic;
65*00b67f09SDavid van Moolenbroek 	unsigned int			size;
66*00b67f09SDavid van Moolenbroek 	eltlist_t *			table;
67*00b67f09SDavid van Moolenbroek 	isccc_symtabundefaction_t		undefine_action;
68*00b67f09SDavid van Moolenbroek 	void *				undefine_arg;
69*00b67f09SDavid van Moolenbroek 	isc_boolean_t			case_sensitive;
70*00b67f09SDavid van Moolenbroek };
71*00b67f09SDavid van Moolenbroek 
72*00b67f09SDavid van Moolenbroek isc_result_t
isccc_symtab_create(unsigned int size,isccc_symtabundefaction_t undefine_action,void * undefine_arg,isc_boolean_t case_sensitive,isccc_symtab_t ** symtabp)73*00b67f09SDavid van Moolenbroek isccc_symtab_create(unsigned int size,
74*00b67f09SDavid van Moolenbroek 		  isccc_symtabundefaction_t undefine_action,
75*00b67f09SDavid van Moolenbroek 		  void *undefine_arg,
76*00b67f09SDavid van Moolenbroek 		  isc_boolean_t case_sensitive,
77*00b67f09SDavid van Moolenbroek 		  isccc_symtab_t **symtabp)
78*00b67f09SDavid van Moolenbroek {
79*00b67f09SDavid van Moolenbroek 	isccc_symtab_t *symtab;
80*00b67f09SDavid van Moolenbroek 	unsigned int i;
81*00b67f09SDavid van Moolenbroek 
82*00b67f09SDavid van Moolenbroek 	REQUIRE(symtabp != NULL && *symtabp == NULL);
83*00b67f09SDavid van Moolenbroek 	REQUIRE(size > 0);	/* Should be prime. */
84*00b67f09SDavid van Moolenbroek 
85*00b67f09SDavid van Moolenbroek 	symtab = malloc(sizeof(*symtab));
86*00b67f09SDavid van Moolenbroek 	if (symtab == NULL)
87*00b67f09SDavid van Moolenbroek 		return (ISC_R_NOMEMORY);
88*00b67f09SDavid van Moolenbroek 	symtab->table = malloc(size * sizeof(eltlist_t));
89*00b67f09SDavid van Moolenbroek 	if (symtab->table == NULL) {
90*00b67f09SDavid van Moolenbroek 		free(symtab);
91*00b67f09SDavid van Moolenbroek 		return (ISC_R_NOMEMORY);
92*00b67f09SDavid van Moolenbroek 	}
93*00b67f09SDavid van Moolenbroek 	for (i = 0; i < size; i++)
94*00b67f09SDavid van Moolenbroek 		ISC_LIST_INIT(symtab->table[i]);
95*00b67f09SDavid van Moolenbroek 	symtab->size = size;
96*00b67f09SDavid van Moolenbroek 	symtab->undefine_action = undefine_action;
97*00b67f09SDavid van Moolenbroek 	symtab->undefine_arg = undefine_arg;
98*00b67f09SDavid van Moolenbroek 	symtab->case_sensitive = case_sensitive;
99*00b67f09SDavid van Moolenbroek 	symtab->magic = SYMTAB_MAGIC;
100*00b67f09SDavid van Moolenbroek 
101*00b67f09SDavid van Moolenbroek 	*symtabp = symtab;
102*00b67f09SDavid van Moolenbroek 
103*00b67f09SDavid van Moolenbroek 	return (ISC_R_SUCCESS);
104*00b67f09SDavid van Moolenbroek }
105*00b67f09SDavid van Moolenbroek 
106*00b67f09SDavid van Moolenbroek static inline void
free_elt(isccc_symtab_t * symtab,unsigned int bucket,elt_t * elt)107*00b67f09SDavid van Moolenbroek free_elt(isccc_symtab_t *symtab, unsigned int bucket, elt_t *elt) {
108*00b67f09SDavid van Moolenbroek 	ISC_LIST_UNLINK(symtab->table[bucket], elt, link);
109*00b67f09SDavid van Moolenbroek 	if (symtab->undefine_action != NULL)
110*00b67f09SDavid van Moolenbroek 		(symtab->undefine_action)(elt->key, elt->type, elt->value,
111*00b67f09SDavid van Moolenbroek 					  symtab->undefine_arg);
112*00b67f09SDavid van Moolenbroek 	free(elt);
113*00b67f09SDavid van Moolenbroek }
114*00b67f09SDavid van Moolenbroek 
115*00b67f09SDavid van Moolenbroek void
isccc_symtab_destroy(isccc_symtab_t ** symtabp)116*00b67f09SDavid van Moolenbroek isccc_symtab_destroy(isccc_symtab_t **symtabp) {
117*00b67f09SDavid van Moolenbroek 	isccc_symtab_t *symtab;
118*00b67f09SDavid van Moolenbroek 	unsigned int i;
119*00b67f09SDavid van Moolenbroek 	elt_t *elt, *nelt;
120*00b67f09SDavid van Moolenbroek 
121*00b67f09SDavid van Moolenbroek 	REQUIRE(symtabp != NULL);
122*00b67f09SDavid van Moolenbroek 	symtab = *symtabp;
123*00b67f09SDavid van Moolenbroek 	REQUIRE(VALID_SYMTAB(symtab));
124*00b67f09SDavid van Moolenbroek 
125*00b67f09SDavid van Moolenbroek 	for (i = 0; i < symtab->size; i++) {
126*00b67f09SDavid van Moolenbroek 		for (elt = ISC_LIST_HEAD(symtab->table[i]);
127*00b67f09SDavid van Moolenbroek 		     elt != NULL;
128*00b67f09SDavid van Moolenbroek 		     elt = nelt) {
129*00b67f09SDavid van Moolenbroek 			nelt = ISC_LIST_NEXT(elt, link);
130*00b67f09SDavid van Moolenbroek 			free_elt(symtab, i, elt);
131*00b67f09SDavid van Moolenbroek 		}
132*00b67f09SDavid van Moolenbroek 	}
133*00b67f09SDavid van Moolenbroek 	free(symtab->table);
134*00b67f09SDavid van Moolenbroek 	symtab->magic = 0;
135*00b67f09SDavid van Moolenbroek 	free(symtab);
136*00b67f09SDavid van Moolenbroek 
137*00b67f09SDavid van Moolenbroek 	*symtabp = NULL;
138*00b67f09SDavid van Moolenbroek }
139*00b67f09SDavid van Moolenbroek 
140*00b67f09SDavid van Moolenbroek static inline unsigned int
hash(const char * key,isc_boolean_t case_sensitive)141*00b67f09SDavid van Moolenbroek hash(const char *key, isc_boolean_t case_sensitive) {
142*00b67f09SDavid van Moolenbroek 	const char *s;
143*00b67f09SDavid van Moolenbroek 	unsigned int h = 0;
144*00b67f09SDavid van Moolenbroek 	unsigned int g;
145*00b67f09SDavid van Moolenbroek 	int c;
146*00b67f09SDavid van Moolenbroek 
147*00b67f09SDavid van Moolenbroek 	/*
148*00b67f09SDavid van Moolenbroek 	 * P. J. Weinberger's hash function, adapted from p. 436 of
149*00b67f09SDavid van Moolenbroek 	 * _Compilers: Principles, Techniques, and Tools_, Aho, Sethi
150*00b67f09SDavid van Moolenbroek 	 * and Ullman, Addison-Wesley, 1986, ISBN 0-201-10088-6.
151*00b67f09SDavid van Moolenbroek 	 */
152*00b67f09SDavid van Moolenbroek 
153*00b67f09SDavid van Moolenbroek 	if (case_sensitive) {
154*00b67f09SDavid van Moolenbroek 		for (s = key; *s != '\0'; s++) {
155*00b67f09SDavid van Moolenbroek 			h = ( h << 4 ) + *s;
156*00b67f09SDavid van Moolenbroek 			if ((g = ( h & 0xf0000000 )) != 0) {
157*00b67f09SDavid van Moolenbroek 				h = h ^ (g >> 24);
158*00b67f09SDavid van Moolenbroek 				h = h ^ g;
159*00b67f09SDavid van Moolenbroek 			}
160*00b67f09SDavid van Moolenbroek 		}
161*00b67f09SDavid van Moolenbroek 	} else {
162*00b67f09SDavid van Moolenbroek 		for (s = key; *s != '\0'; s++) {
163*00b67f09SDavid van Moolenbroek 			c = *s;
164*00b67f09SDavid van Moolenbroek 			c = tolower((unsigned char)c);
165*00b67f09SDavid van Moolenbroek 			h = ( h << 4 ) + c;
166*00b67f09SDavid van Moolenbroek 			if ((g = ( h & 0xf0000000 )) != 0) {
167*00b67f09SDavid van Moolenbroek 				h = h ^ (g >> 24);
168*00b67f09SDavid van Moolenbroek 				h = h ^ g;
169*00b67f09SDavid van Moolenbroek 			}
170*00b67f09SDavid van Moolenbroek 		}
171*00b67f09SDavid van Moolenbroek 	}
172*00b67f09SDavid van Moolenbroek 
173*00b67f09SDavid van Moolenbroek 	return (h);
174*00b67f09SDavid van Moolenbroek }
175*00b67f09SDavid van Moolenbroek 
176*00b67f09SDavid van Moolenbroek #define FIND(s, k, t, b, e) \
177*00b67f09SDavid van Moolenbroek 	b = hash((k), (s)->case_sensitive) % (s)->size; \
178*00b67f09SDavid van Moolenbroek 	if ((s)->case_sensitive) { \
179*00b67f09SDavid van Moolenbroek 		for (e = ISC_LIST_HEAD((s)->table[b]); \
180*00b67f09SDavid van Moolenbroek 		     e != NULL; \
181*00b67f09SDavid van Moolenbroek 		     e = ISC_LIST_NEXT(e, link)) { \
182*00b67f09SDavid van Moolenbroek 			if (((t) == 0 || e->type == (t)) && \
183*00b67f09SDavid van Moolenbroek 			    strcmp(e->key, (k)) == 0) \
184*00b67f09SDavid van Moolenbroek 				break; \
185*00b67f09SDavid van Moolenbroek 		} \
186*00b67f09SDavid van Moolenbroek 	} else { \
187*00b67f09SDavid van Moolenbroek 		for (e = ISC_LIST_HEAD((s)->table[b]); \
188*00b67f09SDavid van Moolenbroek 		     e != NULL; \
189*00b67f09SDavid van Moolenbroek 		     e = ISC_LIST_NEXT(e, link)) { \
190*00b67f09SDavid van Moolenbroek 			if (((t) == 0 || e->type == (t)) && \
191*00b67f09SDavid van Moolenbroek 			    strcasecmp(e->key, (k)) == 0) \
192*00b67f09SDavid van Moolenbroek 				break; \
193*00b67f09SDavid van Moolenbroek 		} \
194*00b67f09SDavid van Moolenbroek 	}
195*00b67f09SDavid van Moolenbroek 
196*00b67f09SDavid van Moolenbroek isc_result_t
isccc_symtab_lookup(isccc_symtab_t * symtab,const char * key,unsigned int type,isccc_symvalue_t * value)197*00b67f09SDavid van Moolenbroek isccc_symtab_lookup(isccc_symtab_t *symtab, const char *key, unsigned int type,
198*00b67f09SDavid van Moolenbroek 		  isccc_symvalue_t *value)
199*00b67f09SDavid van Moolenbroek {
200*00b67f09SDavid van Moolenbroek 	unsigned int bucket;
201*00b67f09SDavid van Moolenbroek 	elt_t *elt;
202*00b67f09SDavid van Moolenbroek 
203*00b67f09SDavid van Moolenbroek 	REQUIRE(VALID_SYMTAB(symtab));
204*00b67f09SDavid van Moolenbroek 	REQUIRE(key != NULL);
205*00b67f09SDavid van Moolenbroek 
206*00b67f09SDavid van Moolenbroek 	FIND(symtab, key, type, bucket, elt);
207*00b67f09SDavid van Moolenbroek 
208*00b67f09SDavid van Moolenbroek 	if (elt == NULL)
209*00b67f09SDavid van Moolenbroek 		return (ISC_R_NOTFOUND);
210*00b67f09SDavid van Moolenbroek 
211*00b67f09SDavid van Moolenbroek 	if (value != NULL)
212*00b67f09SDavid van Moolenbroek 		*value = elt->value;
213*00b67f09SDavid van Moolenbroek 
214*00b67f09SDavid van Moolenbroek 	return (ISC_R_SUCCESS);
215*00b67f09SDavid van Moolenbroek }
216*00b67f09SDavid van Moolenbroek 
217*00b67f09SDavid van Moolenbroek isc_result_t
isccc_symtab_define(isccc_symtab_t * symtab,char * key,unsigned int type,isccc_symvalue_t value,isccc_symexists_t exists_policy)218*00b67f09SDavid van Moolenbroek isccc_symtab_define(isccc_symtab_t *symtab, char *key, unsigned int type,
219*00b67f09SDavid van Moolenbroek 		  isccc_symvalue_t value, isccc_symexists_t exists_policy)
220*00b67f09SDavid van Moolenbroek {
221*00b67f09SDavid van Moolenbroek 	unsigned int bucket;
222*00b67f09SDavid van Moolenbroek 	elt_t *elt;
223*00b67f09SDavid van Moolenbroek 
224*00b67f09SDavid van Moolenbroek 	REQUIRE(VALID_SYMTAB(symtab));
225*00b67f09SDavid van Moolenbroek 	REQUIRE(key != NULL);
226*00b67f09SDavid van Moolenbroek 	REQUIRE(type != 0);
227*00b67f09SDavid van Moolenbroek 
228*00b67f09SDavid van Moolenbroek 	FIND(symtab, key, type, bucket, elt);
229*00b67f09SDavid van Moolenbroek 
230*00b67f09SDavid van Moolenbroek 	if (exists_policy != isccc_symexists_add && elt != NULL) {
231*00b67f09SDavid van Moolenbroek 		if (exists_policy == isccc_symexists_reject)
232*00b67f09SDavid van Moolenbroek 			return (ISC_R_EXISTS);
233*00b67f09SDavid van Moolenbroek 		INSIST(exists_policy == isccc_symexists_replace);
234*00b67f09SDavid van Moolenbroek 		ISC_LIST_UNLINK(symtab->table[bucket], elt, link);
235*00b67f09SDavid van Moolenbroek 		if (symtab->undefine_action != NULL)
236*00b67f09SDavid van Moolenbroek 			(symtab->undefine_action)(elt->key, elt->type,
237*00b67f09SDavid van Moolenbroek 						  elt->value,
238*00b67f09SDavid van Moolenbroek 						  symtab->undefine_arg);
239*00b67f09SDavid van Moolenbroek 	} else {
240*00b67f09SDavid van Moolenbroek 		elt = malloc(sizeof(*elt));
241*00b67f09SDavid van Moolenbroek 		if (elt == NULL)
242*00b67f09SDavid van Moolenbroek 			return (ISC_R_NOMEMORY);
243*00b67f09SDavid van Moolenbroek 		ISC_LINK_INIT(elt, link);
244*00b67f09SDavid van Moolenbroek 	}
245*00b67f09SDavid van Moolenbroek 
246*00b67f09SDavid van Moolenbroek 	elt->key = key;
247*00b67f09SDavid van Moolenbroek 	elt->type = type;
248*00b67f09SDavid van Moolenbroek 	elt->value = value;
249*00b67f09SDavid van Moolenbroek 
250*00b67f09SDavid van Moolenbroek 	/*
251*00b67f09SDavid van Moolenbroek 	 * We prepend so that the most recent definition will be found.
252*00b67f09SDavid van Moolenbroek 	 */
253*00b67f09SDavid van Moolenbroek 	ISC_LIST_PREPEND(symtab->table[bucket], elt, link);
254*00b67f09SDavid van Moolenbroek 
255*00b67f09SDavid van Moolenbroek 	return (ISC_R_SUCCESS);
256*00b67f09SDavid van Moolenbroek }
257*00b67f09SDavid van Moolenbroek 
258*00b67f09SDavid van Moolenbroek isc_result_t
isccc_symtab_undefine(isccc_symtab_t * symtab,const char * key,unsigned int type)259*00b67f09SDavid van Moolenbroek isccc_symtab_undefine(isccc_symtab_t *symtab, const char *key, unsigned int type) {
260*00b67f09SDavid van Moolenbroek 	unsigned int bucket;
261*00b67f09SDavid van Moolenbroek 	elt_t *elt;
262*00b67f09SDavid van Moolenbroek 
263*00b67f09SDavid van Moolenbroek 	REQUIRE(VALID_SYMTAB(symtab));
264*00b67f09SDavid van Moolenbroek 	REQUIRE(key != NULL);
265*00b67f09SDavid van Moolenbroek 
266*00b67f09SDavid van Moolenbroek 	FIND(symtab, key, type, bucket, elt);
267*00b67f09SDavid van Moolenbroek 
268*00b67f09SDavid van Moolenbroek 	if (elt == NULL)
269*00b67f09SDavid van Moolenbroek 		return (ISC_R_NOTFOUND);
270*00b67f09SDavid van Moolenbroek 
271*00b67f09SDavid van Moolenbroek 	free_elt(symtab, bucket, elt);
272*00b67f09SDavid van Moolenbroek 
273*00b67f09SDavid van Moolenbroek 	return (ISC_R_SUCCESS);
274*00b67f09SDavid van Moolenbroek }
275*00b67f09SDavid van Moolenbroek 
276*00b67f09SDavid van Moolenbroek void
isccc_symtab_foreach(isccc_symtab_t * symtab,isccc_symtabforeachaction_t action,void * arg)277*00b67f09SDavid van Moolenbroek isccc_symtab_foreach(isccc_symtab_t *symtab, isccc_symtabforeachaction_t action,
278*00b67f09SDavid van Moolenbroek 		   void *arg)
279*00b67f09SDavid van Moolenbroek {
280*00b67f09SDavid van Moolenbroek 	unsigned int i;
281*00b67f09SDavid van Moolenbroek 	elt_t *elt, *nelt;
282*00b67f09SDavid van Moolenbroek 
283*00b67f09SDavid van Moolenbroek 	REQUIRE(VALID_SYMTAB(symtab));
284*00b67f09SDavid van Moolenbroek 	REQUIRE(action != NULL);
285*00b67f09SDavid van Moolenbroek 
286*00b67f09SDavid van Moolenbroek 	for (i = 0; i < symtab->size; i++) {
287*00b67f09SDavid van Moolenbroek 		for (elt = ISC_LIST_HEAD(symtab->table[i]);
288*00b67f09SDavid van Moolenbroek 		     elt != NULL;
289*00b67f09SDavid van Moolenbroek 		     elt = nelt) {
290*00b67f09SDavid van Moolenbroek 			nelt = ISC_LIST_NEXT(elt, link);
291*00b67f09SDavid van Moolenbroek 			if ((action)(elt->key, elt->type, elt->value, arg))
292*00b67f09SDavid van Moolenbroek 				free_elt(symtab, i, elt);
293*00b67f09SDavid van Moolenbroek 		}
294*00b67f09SDavid van Moolenbroek 	}
295*00b67f09SDavid van Moolenbroek }
296