2 * Automated Testing Framework (atf)
4 * Copyright (c) 2008 The NetBSD Foundation, Inc.
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
16 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND
17 * CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
18 * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
19 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
20 * IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS BE LIABLE FOR ANY
21 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
23 * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
24 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
25 * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
26 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
27 * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
34 #include "atf-c/error.h"
35 #include "atf-c/utils.h"
40 /* ---------------------------------------------------------------------
41 * Auxiliary functions.
42 * --------------------------------------------------------------------- */
52 new_entry(const char *key
, void *value
, bool managed
)
56 me
= (struct map_entry
*)malloc(sizeof(*me
));
58 me
->m_key
= strdup(key
);
59 if (me
->m_key
== NULL
) {
64 me
->m_managed
= managed
;
71 /* ---------------------------------------------------------------------
72 * The "atf_map_citer" type.
73 * --------------------------------------------------------------------- */
80 atf_map_citer_key(const atf_map_citer_t citer
)
82 const struct map_entry
*me
= citer
.m_entry
;
88 atf_map_citer_data(const atf_map_citer_t citer
)
90 const struct map_entry
*me
= citer
.m_entry
;
96 atf_map_citer_next(const atf_map_citer_t citer
)
98 atf_map_citer_t newciter
;
101 newciter
.m_listiter
= atf_list_citer_next(citer
.m_listiter
);
102 newciter
.m_entry
= ((const struct map_entry
*)
103 atf_list_citer_data(newciter
.m_listiter
));
109 atf_equal_map_citer_map_citer(const atf_map_citer_t i1
,
110 const atf_map_citer_t i2
)
112 return i1
.m_map
== i2
.m_map
&& i1
.m_entry
== i2
.m_entry
;
115 /* ---------------------------------------------------------------------
116 * The "atf_map_iter" type.
117 * --------------------------------------------------------------------- */
124 atf_map_iter_key(const atf_map_iter_t iter
)
126 const struct map_entry
*me
= iter
.m_entry
;
132 atf_map_iter_data(const atf_map_iter_t iter
)
134 const struct map_entry
*me
= iter
.m_entry
;
140 atf_map_iter_next(const atf_map_iter_t iter
)
142 atf_map_iter_t newiter
;
145 newiter
.m_listiter
= atf_list_iter_next(iter
.m_listiter
);
146 newiter
.m_entry
= ((struct map_entry
*)
147 atf_list_iter_data(newiter
.m_listiter
));
153 atf_equal_map_iter_map_iter(const atf_map_iter_t i1
,
154 const atf_map_iter_t i2
)
156 return i1
.m_map
== i2
.m_map
&& i1
.m_entry
== i2
.m_entry
;
159 /* ---------------------------------------------------------------------
160 * The "atf_map" type.
161 * --------------------------------------------------------------------- */
164 * Constructors and destructors.
168 atf_map_init(atf_map_t
*m
)
170 return atf_list_init(&m
->m_list
);
174 atf_map_init_charpp(atf_map_t
*m
, const char *const *array
)
177 const char *const *ptr
= array
;
179 err
= atf_map_init(m
);
181 while (!atf_is_error(err
) && *ptr
!= NULL
) {
182 const char *key
, *value
;
188 if ((value
= *ptr
) == NULL
) {
189 err
= atf_libc_error(EINVAL
, "List too short; no value for "
190 "key '%s' provided", key
); /* XXX: Not really libc_error */
195 err
= atf_map_insert(m
, key
, strdup(value
), true);
199 if (atf_is_error(err
))
206 atf_map_fini(atf_map_t
*m
)
208 atf_list_iter_t iter
;
210 atf_list_for_each(iter
, &m
->m_list
) {
211 struct map_entry
*me
= atf_list_iter_data(iter
);
218 atf_list_fini(&m
->m_list
);
226 atf_map_begin(atf_map_t
*m
)
230 iter
.m_listiter
= atf_list_begin(&m
->m_list
);
231 iter
.m_entry
= atf_list_iter_data(iter
.m_listiter
);
236 atf_map_begin_c(const atf_map_t
*m
)
238 atf_map_citer_t citer
;
240 citer
.m_listiter
= atf_list_begin_c(&m
->m_list
);
241 citer
.m_entry
= atf_list_citer_data(citer
.m_listiter
);
246 atf_map_end(atf_map_t
*m
)
251 iter
.m_listiter
= atf_list_end(&m
->m_list
);
256 atf_map_end_c(const atf_map_t
*m
)
258 atf_map_citer_t iter
;
261 iter
.m_listiter
= atf_list_end_c(&m
->m_list
);
266 atf_map_find(atf_map_t
*m
, const char *key
)
268 atf_list_iter_t iter
;
270 atf_list_for_each(iter
, &m
->m_list
) {
271 struct map_entry
*me
= atf_list_iter_data(iter
);
273 if (strcmp(me
->m_key
, key
) == 0) {
282 return atf_map_end(m
);
286 atf_map_find_c(const atf_map_t
*m
, const char *key
)
288 atf_list_citer_t iter
;
290 atf_list_for_each_c(iter
, &m
->m_list
) {
291 const struct map_entry
*me
= atf_list_citer_data(iter
);
293 if (strcmp(me
->m_key
, key
) == 0) {
302 return atf_map_end_c(m
);
306 atf_map_size(const atf_map_t
*m
)
308 return atf_list_size(&m
->m_list
);
312 atf_map_to_charpp(const atf_map_t
*l
)
315 atf_map_citer_t iter
;
318 array
= malloc(sizeof(char *) * (atf_map_size(l
) * 2 + 1));
323 atf_map_for_each_c(iter
, l
) {
324 array
[i
] = strdup(atf_map_citer_key(iter
));
325 if (array
[i
] == NULL
) {
326 atf_utils_free_charpp(array
);
331 array
[i
+ 1] = strdup((const char *)atf_map_citer_data(iter
));
332 if (array
[i
+ 1] == NULL
) {
333 atf_utils_free_charpp(array
);
351 atf_map_insert(atf_map_t
*m
, const char *key
, void *value
, bool managed
)
353 struct map_entry
*me
;
357 iter
= atf_map_find(m
, key
);
358 if (atf_equal_map_iter_map_iter(iter
, atf_map_end(m
))) {
359 me
= new_entry(key
, value
, managed
);
361 err
= atf_no_memory_error();
363 err
= atf_list_append(&m
->m_list
, me
, false);
364 if (atf_is_error(err
)) {
375 INV(strcmp(me
->m_key
, key
) == 0);
377 me
->m_managed
= managed
;
379 err
= atf_no_error();