1 /* Copyright (c) 2008 The NetBSD Foundation, Inc.
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
7 * 1. Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * 2. Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
13 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND
14 * CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
15 * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
16 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
17 * IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS BE LIABLE FOR ANY
18 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
20 * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
21 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
22 * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
23 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
24 * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */
26 #include "atf-c/detail/map.h"
32 #include "atf-c/detail/sanity.h"
33 #include "atf-c/error.h"
34 #include "atf-c/utils.h"
36 /* ---------------------------------------------------------------------
37 * Auxiliary functions.
38 * --------------------------------------------------------------------- */
48 new_entry(const char *key, void *value, bool managed)
52 me = (struct map_entry *)malloc(sizeof(*me));
54 me->m_key = strdup(key);
55 if (me->m_key == NULL) {
60 me->m_managed = managed;
67 /* ---------------------------------------------------------------------
68 * The "atf_map_citer" type.
69 * --------------------------------------------------------------------- */
76 atf_map_citer_key(const atf_map_citer_t citer)
78 const struct map_entry *me = citer.m_entry;
84 atf_map_citer_data(const atf_map_citer_t citer)
86 const struct map_entry *me = citer.m_entry;
92 atf_map_citer_next(const atf_map_citer_t citer)
94 atf_map_citer_t newciter;
97 newciter.m_listiter = atf_list_citer_next(citer.m_listiter);
98 newciter.m_entry = ((const struct map_entry *)
99 atf_list_citer_data(newciter.m_listiter));
105 atf_equal_map_citer_map_citer(const atf_map_citer_t i1,
106 const atf_map_citer_t i2)
108 return i1.m_map == i2.m_map && i1.m_entry == i2.m_entry;
111 /* ---------------------------------------------------------------------
112 * The "atf_map_iter" type.
113 * --------------------------------------------------------------------- */
120 atf_map_iter_key(const atf_map_iter_t iter)
122 const struct map_entry *me = iter.m_entry;
128 atf_map_iter_data(const atf_map_iter_t iter)
130 const struct map_entry *me = iter.m_entry;
136 atf_map_iter_next(const atf_map_iter_t iter)
138 atf_map_iter_t newiter;
141 newiter.m_listiter = atf_list_iter_next(iter.m_listiter);
142 newiter.m_entry = ((struct map_entry *)
143 atf_list_iter_data(newiter.m_listiter));
149 atf_equal_map_iter_map_iter(const atf_map_iter_t i1,
150 const atf_map_iter_t i2)
152 return i1.m_map == i2.m_map && i1.m_entry == i2.m_entry;
155 /* ---------------------------------------------------------------------
156 * The "atf_map" type.
157 * --------------------------------------------------------------------- */
160 * Constructors and destructors.
164 atf_map_init(atf_map_t *m)
166 return atf_list_init(&m->m_list);
170 atf_map_init_charpp(atf_map_t *m, const char *const *array)
173 const char *const *ptr = array;
175 err = atf_map_init(m);
177 while (!atf_is_error(err) && *ptr != NULL) {
178 const char *key, *value;
184 if ((value = *ptr) == NULL) {
185 err = atf_libc_error(EINVAL, "List too short; no value for "
186 "key '%s' provided", key); /* XXX: Not really libc_error */
191 err = atf_map_insert(m, key, strdup(value), true);
195 if (atf_is_error(err))
202 atf_map_fini(atf_map_t *m)
204 atf_list_iter_t iter;
206 atf_list_for_each(iter, &m->m_list) {
207 struct map_entry *me = atf_list_iter_data(iter);
214 atf_list_fini(&m->m_list);
222 atf_map_begin(atf_map_t *m)
226 iter.m_listiter = atf_list_begin(&m->m_list);
227 iter.m_entry = atf_list_iter_data(iter.m_listiter);
232 atf_map_begin_c(const atf_map_t *m)
234 atf_map_citer_t citer;
236 citer.m_listiter = atf_list_begin_c(&m->m_list);
237 citer.m_entry = atf_list_citer_data(citer.m_listiter);
242 atf_map_end(atf_map_t *m)
247 iter.m_listiter = atf_list_end(&m->m_list);
252 atf_map_end_c(const atf_map_t *m)
254 atf_map_citer_t iter;
257 iter.m_listiter = atf_list_end_c(&m->m_list);
262 atf_map_find(atf_map_t *m, const char *key)
264 atf_list_iter_t iter;
266 atf_list_for_each(iter, &m->m_list) {
267 struct map_entry *me = atf_list_iter_data(iter);
269 if (strcmp(me->m_key, key) == 0) {
278 return atf_map_end(m);
282 atf_map_find_c(const atf_map_t *m, const char *key)
284 atf_list_citer_t iter;
286 atf_list_for_each_c(iter, &m->m_list) {
287 const struct map_entry *me = atf_list_citer_data(iter);
289 if (strcmp(me->m_key, key) == 0) {
298 return atf_map_end_c(m);
302 atf_map_size(const atf_map_t *m)
304 return atf_list_size(&m->m_list);
308 atf_map_to_charpp(const atf_map_t *l)
311 atf_map_citer_t iter;
314 array = malloc(sizeof(char *) * (atf_map_size(l) * 2 + 1));
319 atf_map_for_each_c(iter, l) {
320 array[i] = strdup(atf_map_citer_key(iter));
321 if (array[i] == NULL) {
322 atf_utils_free_charpp(array);
327 array[i + 1] = strdup((const char *)atf_map_citer_data(iter));
328 if (array[i + 1] == NULL) {
329 atf_utils_free_charpp(array);
347 atf_map_insert(atf_map_t *m, const char *key, void *value, bool managed)
349 struct map_entry *me;
353 iter = atf_map_find(m, key);
354 if (atf_equal_map_iter_map_iter(iter, atf_map_end(m))) {
355 me = new_entry(key, value, managed);
357 err = atf_no_memory_error();
359 err = atf_list_append(&m->m_list, me, false);
360 if (atf_is_error(err)) {
370 INV(strcmp(me->m_key, key) == 0);
372 me->m_managed = managed;
374 err = atf_no_error();