xref: /titanic_52/usr/src/tools/ctf/cvt/alist.c (revision c2580b931007758eab8cb5ae8726ebe1588e259b)
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 
37 #include "alist.h"
38 #include "memory.h"
39 #include "hash.h"
40 
41 #define	ALIST_HASH_SIZE	997
42 
43 struct alist {
44 	hash_t *al_elements;
45 	void (*al_namefree)(void *);
46 	void (*al_valfree)(void *);
47 };
48 
49 typedef struct alist_el {
50 	void *ale_name;
51 	void *ale_value;
52 } alist_el_t;
53 
54 static int
55 alist_hash(int nbuckets, alist_el_t *el)
56 {
57 	uintptr_t num = (uintptr_t)el->ale_name;
58 
59 	return (num % nbuckets);
60 }
61 
62 static int
63 alist_cmp(alist_el_t *el1, alist_el_t *el2)
64 {
65 	return ((uintptr_t)el1->ale_name != (uintptr_t)el2->ale_name);
66 }
67 
68 alist_t *
69 alist_xnew(int nbuckets, void (*namefree)(void *),
70     void (*valfree)(void *), int (*hashfn)(int, void *),
71     int (*cmpfn)(void *, void *))
72 {
73 	alist_t *alist;
74 
75 	alist = xcalloc(sizeof (alist_t));
76 	alist->al_elements = hash_new(nbuckets, hashfn, cmpfn);
77 	alist->al_namefree = namefree;
78 	alist->al_valfree = valfree;
79 
80 	return (alist);
81 }
82 
83 alist_t *
84 alist_new(void (*namefree)(void *), void (*valfree)(void *))
85 {
86 	return (alist_xnew(ALIST_HASH_SIZE, namefree, valfree,
87 	    (int (*)())alist_hash, (int (*)())alist_cmp));
88 }
89 
90 static void
91 alist_free_cb(alist_el_t *el, alist_t *alist)
92 {
93 	if (alist->al_namefree)
94 		alist->al_namefree(el->ale_name);
95 	if (alist->al_valfree)
96 		alist->al_valfree(el->ale_name);
97 	free(el);
98 }
99 
100 void
101 alist_free(alist_t *alist)
102 {
103 	hash_free(alist->al_elements, (void (*)())alist_free_cb, alist);
104 	free(alist);
105 }
106 
107 void
108 alist_add(alist_t *alist, void *name, void *value)
109 {
110 	alist_el_t *el;
111 
112 	el = xmalloc(sizeof (alist_el_t));
113 	el->ale_name = name;
114 	el->ale_value = value;
115 	hash_add(alist->al_elements, el);
116 }
117 
118 int
119 alist_find(alist_t *alist, void *name, void **value)
120 {
121 	alist_el_t template, *ret;
122 
123 	template.ale_name = name;
124 	if (!hash_find(alist->al_elements, &template, (void **)&ret))
125 		return (0);
126 
127 	if (value)
128 		*value = ret->ale_value;
129 
130 	return (1);
131 }
132 
133 typedef struct alist_iter_data {
134 	int (*aid_func)(void *, void *, void *);
135 	void *aid_priv;
136 } alist_iter_data_t;
137 
138 static int
139 alist_iter_cb(alist_el_t *el, alist_iter_data_t *aid)
140 {
141 	return (aid->aid_func(el->ale_name, el->ale_value, aid->aid_priv));
142 }
143 
144 int
145 alist_iter(alist_t *alist, int (*func)(void *, void *, void *), void *private)
146 {
147 	alist_iter_data_t aid;
148 
149 	aid.aid_func = func;
150 	aid.aid_priv = private;
151 
152 	return (hash_iter(alist->al_elements, (int (*)())alist_iter_cb, &aid));
153 }
154 
155 /*
156  * Debugging support.  Used to print the contents of an alist.
157  */
158 
159 void
160 alist_stats(alist_t *alist, int verbose)
161 {
162 	printf("Alist statistics\n");
163 	hash_stats(alist->al_elements, verbose);
164 }
165 
166 static int alist_def_print_cb_key_int = 1;
167 static int alist_def_print_cb_value_int = 1;
168 
169 static int
170 alist_def_print_cb(void *key, void *value)
171 {
172 	printf("Key: ");
173 	if (alist_def_print_cb_key_int == 1)
174 		printf("%5d ", (int)key);
175 	else
176 		printf("%s\n", (char *)key);
177 
178 	printf("Value: ");
179 	if (alist_def_print_cb_value_int == 1)
180 		printf("%5d\n", (int)value);
181 	else
182 		printf("%s\n", (char *)key);
183 
184 	return (1);
185 }
186 
187 static int
188 alist_dump_cb(void *node, void *private)
189 {
190 	int (*printer)(void *, void *) = (int (*)())private;
191 	alist_el_t *el = node;
192 
193 	printer(el->ale_name, el->ale_value);
194 
195 	return (1);
196 }
197 
198 int
199 alist_dump(alist_t *alist, int (*printer)(void *, void *))
200 {
201 	if (!printer)
202 		printer = alist_def_print_cb;
203 
204 	return (hash_iter(alist->al_elements, alist_dump_cb, (void *)printer));
205 }
206