xref: /netbsd-src/external/cddl/osnet/dist/tools/ctf/cvt/alist.c (revision bdc22b2e01993381dcefeff2bc9b56ca75a4235c)
1 /*
2  * CDDL HEADER START
3  *
4  * The contents of this file are subject to the terms of the
5  * Common Development and Distribution License, Version 1.0 only
6  * (the "License").  You may not use this file except in compliance
7  * with the License.
8  *
9  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10  * or http://www.opensolaris.org/os/licensing.
11  * See the License for the specific language governing permissions
12  * and limitations under the License.
13  *
14  * When distributing Covered Code, include this CDDL HEADER in each
15  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16  * If applicable, add the following below this CDDL HEADER, with the
17  * fields enclosed by brackets "[]" replaced with your own identifying
18  * information: Portions Copyright [yyyy] [name of copyright owner]
19  *
20  * CDDL HEADER END
21  */
22 /*
23  * Copyright 2001-2003 Sun Microsystems, Inc.  All rights reserved.
24  * Use is subject to license terms.
25  */
26 
27 #pragma ident	"%Z%%M%	%I%	%E% SMI"
28 
29 /*
30  * Create, manage, and destroy association lists.  alists are arrays with
31  * arbitrary index types, and are also commonly known as associative arrays.
32  */
33 
34 #include <stdio.h>
35 #include <stdlib.h>
36 #include <stdint.h>
37 
38 #include "alist.h"
39 #include "memory.h"
40 #include "hash.h"
41 
42 #define	ALIST_HASH_SIZE	997
43 
44 struct alist {
45 	hash_t *al_elements;
46 	void (*al_namefree)(void *);
47 	void (*al_valfree)(void *);
48 };
49 
50 typedef struct alist_el {
51 	void *ale_name;
52 	void *ale_value;
53 } alist_el_t;
54 
55 static int
56 alist_hash(int nbuckets, void *arg)
57 {
58 	alist_el_t *el = arg;
59 	uintptr_t num = (uintptr_t)el->ale_name;
60 
61 	return (num % nbuckets);
62 }
63 
64 static int
65 alist_cmp(void *arg1, void *arg2)
66 {
67 	alist_el_t *el1 = arg1;
68 	alist_el_t *el2 = arg2;
69 	return ((uintptr_t)el1->ale_name != (uintptr_t)el2->ale_name);
70 }
71 
72 alist_t *
73 alist_xnew(int nbuckets, void (*namefree)(void *),
74     void (*valfree)(void *), int (*hashfn)(int, void *),
75     int (*cmpfn)(void *, void *))
76 {
77 	alist_t *alist;
78 
79 	alist = xcalloc(sizeof (alist_t));
80 	alist->al_elements = hash_new(nbuckets, hashfn, cmpfn);
81 	alist->al_namefree = namefree;
82 	alist->al_valfree = valfree;
83 
84 	return (alist);
85 }
86 
87 alist_t *
88 alist_new(void (*namefree)(void *), void (*valfree)(void *))
89 {
90 	return (alist_xnew(ALIST_HASH_SIZE, namefree, valfree,
91 	    alist_hash, alist_cmp));
92 }
93 
94 static void
95 alist_free_cb(void *arg1, void *arg2)
96 {
97 	alist_el_t *el = arg1;
98 	alist_t *alist = arg2;
99 	if (alist->al_namefree)
100 		alist->al_namefree(el->ale_name);
101 	if (alist->al_valfree)
102 		alist->al_valfree(el->ale_name);
103 	free(el);
104 }
105 
106 void
107 alist_free(alist_t *alist)
108 {
109 	hash_free(alist->al_elements, alist_free_cb, alist);
110 	free(alist);
111 }
112 
113 void
114 alist_add(alist_t *alist, void *name, void *value)
115 {
116 	alist_el_t *el;
117 
118 	el = xmalloc(sizeof (alist_el_t));
119 	el->ale_name = name;
120 	el->ale_value = value;
121 	hash_add(alist->al_elements, el);
122 }
123 
124 int
125 alist_find(alist_t *alist, void *name, void **value)
126 {
127 	alist_el_t template, *retx;
128 	void *ret;
129 
130 	template.ale_name = name;
131 	if (!hash_find(alist->al_elements, &template, &ret))
132 		return (0);
133 
134 	if (value) {
135 		retx = ret;
136 		*value = retx->ale_value;
137 	}
138 
139 	return (1);
140 }
141 
142 typedef struct alist_iter_data {
143 	int (*aid_func)(void *, void *, void *);
144 	void *aid_priv;
145 } alist_iter_data_t;
146 
147 static int
148 alist_iter_cb(void *arg1, void *arg2)
149 {
150 	alist_el_t *el = arg1;
151 	alist_iter_data_t *aid = arg2;
152 	return (aid->aid_func(el->ale_name, el->ale_value, aid->aid_priv));
153 }
154 
155 int
156 alist_iter(alist_t *alist, int (*func)(void *, void *, void *), void *private)
157 {
158 	alist_iter_data_t aid;
159 
160 	aid.aid_func = func;
161 	aid.aid_priv = private;
162 
163 	return (hash_iter(alist->al_elements, alist_iter_cb, &aid));
164 }
165 
166 /*
167  * Debugging support.  Used to print the contents of an alist.
168  */
169 
170 void
171 alist_stats(alist_t *alist, int verbose)
172 {
173 	printf("Alist statistics\n");
174 	hash_stats(alist->al_elements, verbose);
175 }
176 
177 static int alist_def_print_cb_key_int = 1;
178 static int alist_def_print_cb_value_int = 1;
179 
180 static int
181 alist_def_print_cb(void *key, void *value)
182 {
183 	printf("Key: ");
184 	if (alist_def_print_cb_key_int == 1)
185 		printf("%5lu ", (ulong_t)key);
186 	else
187 		printf("%s\n", (char *)key);
188 
189 	printf("Value: ");
190 	if (alist_def_print_cb_value_int == 1)
191 		printf("%5lu\n", (ulong_t)value);
192 	else
193 		printf("%s\n", (char *)key);
194 
195 	return (1);
196 }
197 
198 static int
199 alist_dump_cb(void *node, void *private)
200 {
201 	int (*printer)(void *, void *) = private;
202 	alist_el_t *el = node;
203 
204 	printer(el->ale_name, el->ale_value);
205 
206 	return (1);
207 }
208 
209 int
210 alist_dump(alist_t *alist, int (*printer)(void *, void *))
211 {
212 	if (!printer)
213 		printer = alist_def_print_cb;
214 
215 	return (hash_iter(alist->al_elements, alist_dump_cb, (void *)printer));
216 }
217