1 /* $NetBSD: map.c,v 1.3 2014/12/10 04:38:03 christos Exp $ */
4 * Automated Testing Framework (atf)
6 * Copyright (c) 2008 The NetBSD Foundation, Inc.
9 * Redistribution and use in source and binary forms, with or without
10 * modification, are permitted provided that the following conditions
12 * 1. Redistributions of source code must retain the above copyright
13 * notice, this list of conditions and the following disclaimer.
14 * 2. Redistributions in binary form must reproduce the above copyright
15 * notice, this list of conditions and the following disclaimer in the
16 * documentation and/or other materials provided with the distribution.
18 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND
19 * CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
20 * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
21 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
22 * IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS BE LIABLE FOR ANY
23 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
25 * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
27 * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
28 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
29 * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
36 #include "atf-c/error.h"
37 #include "atf-c/utils.h"
42 /* ---------------------------------------------------------------------
43 * Auxiliary functions.
44 * --------------------------------------------------------------------- */
54 new_entry(const char *key
, void *value
, bool managed
)
58 me
= (struct map_entry
*)malloc(sizeof(*me
));
60 me
->m_key
= strdup(key
);
61 if (me
->m_key
== NULL
) {
66 me
->m_managed
= managed
;
73 /* ---------------------------------------------------------------------
74 * The "atf_map_citer" type.
75 * --------------------------------------------------------------------- */
82 atf_map_citer_key(const atf_map_citer_t citer
)
84 const struct map_entry
*me
= citer
.m_entry
;
90 atf_map_citer_data(const atf_map_citer_t citer
)
92 const struct map_entry
*me
= citer
.m_entry
;
98 atf_map_citer_next(const atf_map_citer_t citer
)
100 atf_map_citer_t newciter
;
103 newciter
.m_listiter
= atf_list_citer_next(citer
.m_listiter
);
104 newciter
.m_entry
= ((const struct map_entry
*)
105 atf_list_citer_data(newciter
.m_listiter
));
111 atf_equal_map_citer_map_citer(const atf_map_citer_t i1
,
112 const atf_map_citer_t i2
)
114 return i1
.m_map
== i2
.m_map
&& i1
.m_entry
== i2
.m_entry
;
117 /* ---------------------------------------------------------------------
118 * The "atf_map_iter" type.
119 * --------------------------------------------------------------------- */
126 atf_map_iter_key(const atf_map_iter_t iter
)
128 const struct map_entry
*me
= iter
.m_entry
;
134 atf_map_iter_data(const atf_map_iter_t iter
)
136 const struct map_entry
*me
= iter
.m_entry
;
142 atf_map_iter_next(const atf_map_iter_t iter
)
144 atf_map_iter_t newiter
;
147 newiter
.m_listiter
= atf_list_iter_next(iter
.m_listiter
);
148 newiter
.m_entry
= ((struct map_entry
*)
149 atf_list_iter_data(newiter
.m_listiter
));
155 atf_equal_map_iter_map_iter(const atf_map_iter_t i1
,
156 const atf_map_iter_t i2
)
158 return i1
.m_map
== i2
.m_map
&& i1
.m_entry
== i2
.m_entry
;
161 /* ---------------------------------------------------------------------
162 * The "atf_map" type.
163 * --------------------------------------------------------------------- */
166 * Constructors and destructors.
170 atf_map_init(atf_map_t
*m
)
172 return atf_list_init(&m
->m_list
);
176 atf_map_init_charpp(atf_map_t
*m
, const char *const *array
)
179 const char *const *ptr
= array
;
181 err
= atf_map_init(m
);
183 while (!atf_is_error(err
) && *ptr
!= NULL
) {
184 const char *key
, *value
;
190 if ((value
= *ptr
) == NULL
) {
191 err
= atf_libc_error(EINVAL
, "List too short; no value for "
192 "key '%s' provided", key
); /* XXX: Not really libc_error */
197 err
= atf_map_insert(m
, key
, strdup(value
), true);
201 if (atf_is_error(err
))
208 atf_map_fini(atf_map_t
*m
)
210 atf_list_iter_t iter
;
212 atf_list_for_each(iter
, &m
->m_list
) {
213 struct map_entry
*me
= atf_list_iter_data(iter
);
220 atf_list_fini(&m
->m_list
);
228 atf_map_begin(atf_map_t
*m
)
232 iter
.m_listiter
= atf_list_begin(&m
->m_list
);
233 iter
.m_entry
= atf_list_iter_data(iter
.m_listiter
);
238 atf_map_begin_c(const atf_map_t
*m
)
240 atf_map_citer_t citer
;
242 citer
.m_listiter
= atf_list_begin_c(&m
->m_list
);
243 citer
.m_entry
= atf_list_citer_data(citer
.m_listiter
);
248 atf_map_end(atf_map_t
*m
)
253 iter
.m_listiter
= atf_list_end(&m
->m_list
);
258 atf_map_end_c(const atf_map_t
*m
)
260 atf_map_citer_t iter
;
263 iter
.m_listiter
= atf_list_end_c(&m
->m_list
);
268 atf_map_find(atf_map_t
*m
, const char *key
)
270 atf_list_iter_t iter
;
272 atf_list_for_each(iter
, &m
->m_list
) {
273 struct map_entry
*me
= atf_list_iter_data(iter
);
275 if (strcmp(me
->m_key
, key
) == 0) {
284 return atf_map_end(m
);
288 atf_map_find_c(const atf_map_t
*m
, const char *key
)
290 atf_list_citer_t iter
;
292 atf_list_for_each_c(iter
, &m
->m_list
) {
293 const struct map_entry
*me
= atf_list_citer_data(iter
);
295 if (strcmp(me
->m_key
, key
) == 0) {
304 return atf_map_end_c(m
);
308 atf_map_size(const atf_map_t
*m
)
310 return atf_list_size(&m
->m_list
);
314 atf_map_to_charpp(const atf_map_t
*l
)
317 atf_map_citer_t iter
;
320 array
= malloc(sizeof(char *) * (atf_map_size(l
) * 2 + 1));
325 atf_map_for_each_c(iter
, l
) {
326 array
[i
] = strdup(atf_map_citer_key(iter
));
327 if (array
[i
] == NULL
) {
328 atf_utils_free_charpp(array
);
333 array
[i
+ 1] = strdup((const char *)atf_map_citer_data(iter
));
334 if (array
[i
+ 1] == NULL
) {
335 atf_utils_free_charpp(array
);
353 atf_map_insert(atf_map_t
*m
, const char *key
, void *value
, bool managed
)
355 struct map_entry
*me
;
359 iter
= atf_map_find(m
, key
);
360 if (atf_equal_map_iter_map_iter(iter
, atf_map_end(m
))) {
361 me
= new_entry(key
, value
, managed
);
363 err
= atf_no_memory_error();
365 err
= atf_list_append(&m
->m_list
, me
, false);
366 if (atf_is_error(err
)) {
377 INV(strcmp(me
->m_key
, key
) == 0);
379 me
->m_managed
= managed
;
381 err
= atf_no_error();