xref: /minix3/external/bsd/bind/dist/unit/atf-src/atf-c/detail/map.c (revision 00b67f09dd46474d133c95011a48590a8e8f94c7)
1*00b67f09SDavid van Moolenbroek /*	$NetBSD: map.c,v 1.3 2014/12/10 04:38:03 christos Exp $	*/
2*00b67f09SDavid van Moolenbroek 
3*00b67f09SDavid van Moolenbroek /*
4*00b67f09SDavid van Moolenbroek  * Automated Testing Framework (atf)
5*00b67f09SDavid van Moolenbroek  *
6*00b67f09SDavid van Moolenbroek  * Copyright (c) 2008 The NetBSD Foundation, Inc.
7*00b67f09SDavid van Moolenbroek  * All rights reserved.
8*00b67f09SDavid van Moolenbroek  *
9*00b67f09SDavid van Moolenbroek  * Redistribution and use in source and binary forms, with or without
10*00b67f09SDavid van Moolenbroek  * modification, are permitted provided that the following conditions
11*00b67f09SDavid van Moolenbroek  * are met:
12*00b67f09SDavid van Moolenbroek  * 1. Redistributions of source code must retain the above copyright
13*00b67f09SDavid van Moolenbroek  *    notice, this list of conditions and the following disclaimer.
14*00b67f09SDavid van Moolenbroek  * 2. Redistributions in binary form must reproduce the above copyright
15*00b67f09SDavid van Moolenbroek  *    notice, this list of conditions and the following disclaimer in the
16*00b67f09SDavid van Moolenbroek  *    documentation and/or other materials provided with the distribution.
17*00b67f09SDavid van Moolenbroek  *
18*00b67f09SDavid van Moolenbroek  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND
19*00b67f09SDavid van Moolenbroek  * CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
20*00b67f09SDavid van Moolenbroek  * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
21*00b67f09SDavid van Moolenbroek  * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
22*00b67f09SDavid van Moolenbroek  * IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS BE LIABLE FOR ANY
23*00b67f09SDavid van Moolenbroek  * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24*00b67f09SDavid van Moolenbroek  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
25*00b67f09SDavid van Moolenbroek  * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26*00b67f09SDavid van Moolenbroek  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
27*00b67f09SDavid van Moolenbroek  * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
28*00b67f09SDavid van Moolenbroek  * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
29*00b67f09SDavid van Moolenbroek  * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30*00b67f09SDavid van Moolenbroek  */
31*00b67f09SDavid van Moolenbroek 
32*00b67f09SDavid van Moolenbroek #include <errno.h>
33*00b67f09SDavid van Moolenbroek #include <stdlib.h>
34*00b67f09SDavid van Moolenbroek #include <string.h>
35*00b67f09SDavid van Moolenbroek 
36*00b67f09SDavid van Moolenbroek #include "atf-c/error.h"
37*00b67f09SDavid van Moolenbroek #include "atf-c/utils.h"
38*00b67f09SDavid van Moolenbroek 
39*00b67f09SDavid van Moolenbroek #include "map.h"
40*00b67f09SDavid van Moolenbroek #include "sanity.h"
41*00b67f09SDavid van Moolenbroek 
42*00b67f09SDavid van Moolenbroek /* ---------------------------------------------------------------------
43*00b67f09SDavid van Moolenbroek  * Auxiliary functions.
44*00b67f09SDavid van Moolenbroek  * --------------------------------------------------------------------- */
45*00b67f09SDavid van Moolenbroek 
46*00b67f09SDavid van Moolenbroek struct map_entry {
47*00b67f09SDavid van Moolenbroek     char *m_key;
48*00b67f09SDavid van Moolenbroek     void *m_value;
49*00b67f09SDavid van Moolenbroek     bool m_managed;
50*00b67f09SDavid van Moolenbroek };
51*00b67f09SDavid van Moolenbroek 
52*00b67f09SDavid van Moolenbroek static
53*00b67f09SDavid van Moolenbroek struct map_entry *
new_entry(const char * key,void * value,bool managed)54*00b67f09SDavid van Moolenbroek new_entry(const char *key, void *value, bool managed)
55*00b67f09SDavid van Moolenbroek {
56*00b67f09SDavid van Moolenbroek     struct map_entry *me;
57*00b67f09SDavid van Moolenbroek 
58*00b67f09SDavid van Moolenbroek     me = (struct map_entry *)malloc(sizeof(*me));
59*00b67f09SDavid van Moolenbroek     if (me != NULL) {
60*00b67f09SDavid van Moolenbroek         me->m_key = strdup(key);
61*00b67f09SDavid van Moolenbroek         if (me->m_key == NULL) {
62*00b67f09SDavid van Moolenbroek             free(me);
63*00b67f09SDavid van Moolenbroek             me = NULL;
64*00b67f09SDavid van Moolenbroek         } else {
65*00b67f09SDavid van Moolenbroek             me->m_value = value;
66*00b67f09SDavid van Moolenbroek             me->m_managed = managed;
67*00b67f09SDavid van Moolenbroek         }
68*00b67f09SDavid van Moolenbroek     }
69*00b67f09SDavid van Moolenbroek 
70*00b67f09SDavid van Moolenbroek     return me;
71*00b67f09SDavid van Moolenbroek }
72*00b67f09SDavid van Moolenbroek 
73*00b67f09SDavid van Moolenbroek /* ---------------------------------------------------------------------
74*00b67f09SDavid van Moolenbroek  * The "atf_map_citer" type.
75*00b67f09SDavid van Moolenbroek  * --------------------------------------------------------------------- */
76*00b67f09SDavid van Moolenbroek 
77*00b67f09SDavid van Moolenbroek /*
78*00b67f09SDavid van Moolenbroek  * Getters.
79*00b67f09SDavid van Moolenbroek  */
80*00b67f09SDavid van Moolenbroek 
81*00b67f09SDavid van Moolenbroek const char *
atf_map_citer_key(const atf_map_citer_t citer)82*00b67f09SDavid van Moolenbroek atf_map_citer_key(const atf_map_citer_t citer)
83*00b67f09SDavid van Moolenbroek {
84*00b67f09SDavid van Moolenbroek     const struct map_entry *me = citer.m_entry;
85*00b67f09SDavid van Moolenbroek     PRE(me != NULL);
86*00b67f09SDavid van Moolenbroek     return me->m_key;
87*00b67f09SDavid van Moolenbroek }
88*00b67f09SDavid van Moolenbroek 
89*00b67f09SDavid van Moolenbroek const void *
atf_map_citer_data(const atf_map_citer_t citer)90*00b67f09SDavid van Moolenbroek atf_map_citer_data(const atf_map_citer_t citer)
91*00b67f09SDavid van Moolenbroek {
92*00b67f09SDavid van Moolenbroek     const struct map_entry *me = citer.m_entry;
93*00b67f09SDavid van Moolenbroek     PRE(me != NULL);
94*00b67f09SDavid van Moolenbroek     return me->m_value;
95*00b67f09SDavid van Moolenbroek }
96*00b67f09SDavid van Moolenbroek 
97*00b67f09SDavid van Moolenbroek atf_map_citer_t
atf_map_citer_next(const atf_map_citer_t citer)98*00b67f09SDavid van Moolenbroek atf_map_citer_next(const atf_map_citer_t citer)
99*00b67f09SDavid van Moolenbroek {
100*00b67f09SDavid van Moolenbroek     atf_map_citer_t newciter;
101*00b67f09SDavid van Moolenbroek 
102*00b67f09SDavid van Moolenbroek     newciter = citer;
103*00b67f09SDavid van Moolenbroek     newciter.m_listiter = atf_list_citer_next(citer.m_listiter);
104*00b67f09SDavid van Moolenbroek     newciter.m_entry = ((const struct map_entry *)
105*00b67f09SDavid van Moolenbroek                         atf_list_citer_data(newciter.m_listiter));
106*00b67f09SDavid van Moolenbroek 
107*00b67f09SDavid van Moolenbroek     return newciter;
108*00b67f09SDavid van Moolenbroek }
109*00b67f09SDavid van Moolenbroek 
110*00b67f09SDavid van Moolenbroek bool
atf_equal_map_citer_map_citer(const atf_map_citer_t i1,const atf_map_citer_t i2)111*00b67f09SDavid van Moolenbroek atf_equal_map_citer_map_citer(const atf_map_citer_t i1,
112*00b67f09SDavid van Moolenbroek                               const atf_map_citer_t i2)
113*00b67f09SDavid van Moolenbroek {
114*00b67f09SDavid van Moolenbroek     return i1.m_map == i2.m_map && i1.m_entry == i2.m_entry;
115*00b67f09SDavid van Moolenbroek }
116*00b67f09SDavid van Moolenbroek 
117*00b67f09SDavid van Moolenbroek /* ---------------------------------------------------------------------
118*00b67f09SDavid van Moolenbroek  * The "atf_map_iter" type.
119*00b67f09SDavid van Moolenbroek  * --------------------------------------------------------------------- */
120*00b67f09SDavid van Moolenbroek 
121*00b67f09SDavid van Moolenbroek /*
122*00b67f09SDavid van Moolenbroek  * Getters.
123*00b67f09SDavid van Moolenbroek  */
124*00b67f09SDavid van Moolenbroek 
125*00b67f09SDavid van Moolenbroek const char *
atf_map_iter_key(const atf_map_iter_t iter)126*00b67f09SDavid van Moolenbroek atf_map_iter_key(const atf_map_iter_t iter)
127*00b67f09SDavid van Moolenbroek {
128*00b67f09SDavid van Moolenbroek     const struct map_entry *me = iter.m_entry;
129*00b67f09SDavid van Moolenbroek     PRE(me != NULL);
130*00b67f09SDavid van Moolenbroek     return me->m_key;
131*00b67f09SDavid van Moolenbroek }
132*00b67f09SDavid van Moolenbroek 
133*00b67f09SDavid van Moolenbroek void *
atf_map_iter_data(const atf_map_iter_t iter)134*00b67f09SDavid van Moolenbroek atf_map_iter_data(const atf_map_iter_t iter)
135*00b67f09SDavid van Moolenbroek {
136*00b67f09SDavid van Moolenbroek     const struct map_entry *me = iter.m_entry;
137*00b67f09SDavid van Moolenbroek     PRE(me != NULL);
138*00b67f09SDavid van Moolenbroek     return me->m_value;
139*00b67f09SDavid van Moolenbroek }
140*00b67f09SDavid van Moolenbroek 
141*00b67f09SDavid van Moolenbroek atf_map_iter_t
atf_map_iter_next(const atf_map_iter_t iter)142*00b67f09SDavid van Moolenbroek atf_map_iter_next(const atf_map_iter_t iter)
143*00b67f09SDavid van Moolenbroek {
144*00b67f09SDavid van Moolenbroek     atf_map_iter_t newiter;
145*00b67f09SDavid van Moolenbroek 
146*00b67f09SDavid van Moolenbroek     newiter = iter;
147*00b67f09SDavid van Moolenbroek     newiter.m_listiter = atf_list_iter_next(iter.m_listiter);
148*00b67f09SDavid van Moolenbroek     newiter.m_entry = ((struct map_entry *)
149*00b67f09SDavid van Moolenbroek                        atf_list_iter_data(newiter.m_listiter));
150*00b67f09SDavid van Moolenbroek 
151*00b67f09SDavid van Moolenbroek     return newiter;
152*00b67f09SDavid van Moolenbroek }
153*00b67f09SDavid van Moolenbroek 
154*00b67f09SDavid van Moolenbroek bool
atf_equal_map_iter_map_iter(const atf_map_iter_t i1,const atf_map_iter_t i2)155*00b67f09SDavid van Moolenbroek atf_equal_map_iter_map_iter(const atf_map_iter_t i1,
156*00b67f09SDavid van Moolenbroek                             const atf_map_iter_t i2)
157*00b67f09SDavid van Moolenbroek {
158*00b67f09SDavid van Moolenbroek     return i1.m_map == i2.m_map && i1.m_entry == i2.m_entry;
159*00b67f09SDavid van Moolenbroek }
160*00b67f09SDavid van Moolenbroek 
161*00b67f09SDavid van Moolenbroek /* ---------------------------------------------------------------------
162*00b67f09SDavid van Moolenbroek  * The "atf_map" type.
163*00b67f09SDavid van Moolenbroek  * --------------------------------------------------------------------- */
164*00b67f09SDavid van Moolenbroek 
165*00b67f09SDavid van Moolenbroek /*
166*00b67f09SDavid van Moolenbroek  * Constructors and destructors.
167*00b67f09SDavid van Moolenbroek  */
168*00b67f09SDavid van Moolenbroek 
169*00b67f09SDavid van Moolenbroek atf_error_t
atf_map_init(atf_map_t * m)170*00b67f09SDavid van Moolenbroek atf_map_init(atf_map_t *m)
171*00b67f09SDavid van Moolenbroek {
172*00b67f09SDavid van Moolenbroek     return atf_list_init(&m->m_list);
173*00b67f09SDavid van Moolenbroek }
174*00b67f09SDavid van Moolenbroek 
175*00b67f09SDavid van Moolenbroek atf_error_t
atf_map_init_charpp(atf_map_t * m,const char * const * array)176*00b67f09SDavid van Moolenbroek atf_map_init_charpp(atf_map_t *m, const char *const *array)
177*00b67f09SDavid van Moolenbroek {
178*00b67f09SDavid van Moolenbroek     atf_error_t err;
179*00b67f09SDavid van Moolenbroek     const char *const *ptr = array;
180*00b67f09SDavid van Moolenbroek 
181*00b67f09SDavid van Moolenbroek     err = atf_map_init(m);
182*00b67f09SDavid van Moolenbroek     if (array != NULL) {
183*00b67f09SDavid van Moolenbroek         while (!atf_is_error(err) && *ptr != NULL) {
184*00b67f09SDavid van Moolenbroek             const char *key, *value;
185*00b67f09SDavid van Moolenbroek 
186*00b67f09SDavid van Moolenbroek             key = *ptr;
187*00b67f09SDavid van Moolenbroek             INV(key != NULL);
188*00b67f09SDavid van Moolenbroek             ptr++;
189*00b67f09SDavid van Moolenbroek 
190*00b67f09SDavid van Moolenbroek             if ((value = *ptr) == NULL) {
191*00b67f09SDavid van Moolenbroek                 err = atf_libc_error(EINVAL, "List too short; no value for "
192*00b67f09SDavid van Moolenbroek                     "key '%s' provided", key);  /* XXX: Not really libc_error */
193*00b67f09SDavid van Moolenbroek                 break;
194*00b67f09SDavid van Moolenbroek             }
195*00b67f09SDavid van Moolenbroek             ptr++;
196*00b67f09SDavid van Moolenbroek 
197*00b67f09SDavid van Moolenbroek             err = atf_map_insert(m, key, strdup(value), true);
198*00b67f09SDavid van Moolenbroek         }
199*00b67f09SDavid van Moolenbroek     }
200*00b67f09SDavid van Moolenbroek 
201*00b67f09SDavid van Moolenbroek     if (atf_is_error(err))
202*00b67f09SDavid van Moolenbroek         atf_map_fini(m);
203*00b67f09SDavid van Moolenbroek 
204*00b67f09SDavid van Moolenbroek     return err;
205*00b67f09SDavid van Moolenbroek }
206*00b67f09SDavid van Moolenbroek 
207*00b67f09SDavid van Moolenbroek void
atf_map_fini(atf_map_t * m)208*00b67f09SDavid van Moolenbroek atf_map_fini(atf_map_t *m)
209*00b67f09SDavid van Moolenbroek {
210*00b67f09SDavid van Moolenbroek     atf_list_iter_t iter;
211*00b67f09SDavid van Moolenbroek 
212*00b67f09SDavid van Moolenbroek     atf_list_for_each(iter, &m->m_list) {
213*00b67f09SDavid van Moolenbroek         struct map_entry *me = atf_list_iter_data(iter);
214*00b67f09SDavid van Moolenbroek 
215*00b67f09SDavid van Moolenbroek         if (me->m_managed)
216*00b67f09SDavid van Moolenbroek             free(me->m_value);
217*00b67f09SDavid van Moolenbroek         free(me->m_key);
218*00b67f09SDavid van Moolenbroek         free(me);
219*00b67f09SDavid van Moolenbroek     }
220*00b67f09SDavid van Moolenbroek     atf_list_fini(&m->m_list);
221*00b67f09SDavid van Moolenbroek }
222*00b67f09SDavid van Moolenbroek 
223*00b67f09SDavid van Moolenbroek /*
224*00b67f09SDavid van Moolenbroek  * Getters.
225*00b67f09SDavid van Moolenbroek  */
226*00b67f09SDavid van Moolenbroek 
227*00b67f09SDavid van Moolenbroek atf_map_iter_t
atf_map_begin(atf_map_t * m)228*00b67f09SDavid van Moolenbroek atf_map_begin(atf_map_t *m)
229*00b67f09SDavid van Moolenbroek {
230*00b67f09SDavid van Moolenbroek     atf_map_iter_t iter;
231*00b67f09SDavid van Moolenbroek     iter.m_map = m;
232*00b67f09SDavid van Moolenbroek     iter.m_listiter = atf_list_begin(&m->m_list);
233*00b67f09SDavid van Moolenbroek     iter.m_entry = atf_list_iter_data(iter.m_listiter);
234*00b67f09SDavid van Moolenbroek     return iter;
235*00b67f09SDavid van Moolenbroek }
236*00b67f09SDavid van Moolenbroek 
237*00b67f09SDavid van Moolenbroek atf_map_citer_t
atf_map_begin_c(const atf_map_t * m)238*00b67f09SDavid van Moolenbroek atf_map_begin_c(const atf_map_t *m)
239*00b67f09SDavid van Moolenbroek {
240*00b67f09SDavid van Moolenbroek     atf_map_citer_t citer;
241*00b67f09SDavid van Moolenbroek     citer.m_map = m;
242*00b67f09SDavid van Moolenbroek     citer.m_listiter = atf_list_begin_c(&m->m_list);
243*00b67f09SDavid van Moolenbroek     citer.m_entry = atf_list_citer_data(citer.m_listiter);
244*00b67f09SDavid van Moolenbroek     return citer;
245*00b67f09SDavid van Moolenbroek }
246*00b67f09SDavid van Moolenbroek 
247*00b67f09SDavid van Moolenbroek atf_map_iter_t
atf_map_end(atf_map_t * m)248*00b67f09SDavid van Moolenbroek atf_map_end(atf_map_t *m)
249*00b67f09SDavid van Moolenbroek {
250*00b67f09SDavid van Moolenbroek     atf_map_iter_t iter;
251*00b67f09SDavid van Moolenbroek     iter.m_map = m;
252*00b67f09SDavid van Moolenbroek     iter.m_entry = NULL;
253*00b67f09SDavid van Moolenbroek     iter.m_listiter = atf_list_end(&m->m_list);
254*00b67f09SDavid van Moolenbroek     return iter;
255*00b67f09SDavid van Moolenbroek }
256*00b67f09SDavid van Moolenbroek 
257*00b67f09SDavid van Moolenbroek atf_map_citer_t
atf_map_end_c(const atf_map_t * m)258*00b67f09SDavid van Moolenbroek atf_map_end_c(const atf_map_t *m)
259*00b67f09SDavid van Moolenbroek {
260*00b67f09SDavid van Moolenbroek     atf_map_citer_t iter;
261*00b67f09SDavid van Moolenbroek     iter.m_map = m;
262*00b67f09SDavid van Moolenbroek     iter.m_entry = NULL;
263*00b67f09SDavid van Moolenbroek     iter.m_listiter = atf_list_end_c(&m->m_list);
264*00b67f09SDavid van Moolenbroek     return iter;
265*00b67f09SDavid van Moolenbroek }
266*00b67f09SDavid van Moolenbroek 
267*00b67f09SDavid van Moolenbroek atf_map_iter_t
atf_map_find(atf_map_t * m,const char * key)268*00b67f09SDavid van Moolenbroek atf_map_find(atf_map_t *m, const char *key)
269*00b67f09SDavid van Moolenbroek {
270*00b67f09SDavid van Moolenbroek     atf_list_iter_t iter;
271*00b67f09SDavid van Moolenbroek 
272*00b67f09SDavid van Moolenbroek     atf_list_for_each(iter, &m->m_list) {
273*00b67f09SDavid van Moolenbroek         struct map_entry *me = atf_list_iter_data(iter);
274*00b67f09SDavid van Moolenbroek 
275*00b67f09SDavid van Moolenbroek         if (strcmp(me->m_key, key) == 0) {
276*00b67f09SDavid van Moolenbroek             atf_map_iter_t i;
277*00b67f09SDavid van Moolenbroek             i.m_map = m;
278*00b67f09SDavid van Moolenbroek             i.m_entry = me;
279*00b67f09SDavid van Moolenbroek             i.m_listiter = iter;
280*00b67f09SDavid van Moolenbroek             return i;
281*00b67f09SDavid van Moolenbroek         }
282*00b67f09SDavid van Moolenbroek     }
283*00b67f09SDavid van Moolenbroek 
284*00b67f09SDavid van Moolenbroek     return atf_map_end(m);
285*00b67f09SDavid van Moolenbroek }
286*00b67f09SDavid van Moolenbroek 
287*00b67f09SDavid van Moolenbroek atf_map_citer_t
atf_map_find_c(const atf_map_t * m,const char * key)288*00b67f09SDavid van Moolenbroek atf_map_find_c(const atf_map_t *m, const char *key)
289*00b67f09SDavid van Moolenbroek {
290*00b67f09SDavid van Moolenbroek     atf_list_citer_t iter;
291*00b67f09SDavid van Moolenbroek 
292*00b67f09SDavid van Moolenbroek     atf_list_for_each_c(iter, &m->m_list) {
293*00b67f09SDavid van Moolenbroek         const struct map_entry *me = atf_list_citer_data(iter);
294*00b67f09SDavid van Moolenbroek 
295*00b67f09SDavid van Moolenbroek         if (strcmp(me->m_key, key) == 0) {
296*00b67f09SDavid van Moolenbroek             atf_map_citer_t i;
297*00b67f09SDavid van Moolenbroek             i.m_map = m;
298*00b67f09SDavid van Moolenbroek             i.m_entry = me;
299*00b67f09SDavid van Moolenbroek             i.m_listiter = iter;
300*00b67f09SDavid van Moolenbroek             return i;
301*00b67f09SDavid van Moolenbroek         }
302*00b67f09SDavid van Moolenbroek     }
303*00b67f09SDavid van Moolenbroek 
304*00b67f09SDavid van Moolenbroek     return atf_map_end_c(m);
305*00b67f09SDavid van Moolenbroek }
306*00b67f09SDavid van Moolenbroek 
307*00b67f09SDavid van Moolenbroek size_t
atf_map_size(const atf_map_t * m)308*00b67f09SDavid van Moolenbroek atf_map_size(const atf_map_t *m)
309*00b67f09SDavid van Moolenbroek {
310*00b67f09SDavid van Moolenbroek     return atf_list_size(&m->m_list);
311*00b67f09SDavid van Moolenbroek }
312*00b67f09SDavid van Moolenbroek 
313*00b67f09SDavid van Moolenbroek char **
atf_map_to_charpp(const atf_map_t * l)314*00b67f09SDavid van Moolenbroek atf_map_to_charpp(const atf_map_t *l)
315*00b67f09SDavid van Moolenbroek {
316*00b67f09SDavid van Moolenbroek     char **array;
317*00b67f09SDavid van Moolenbroek     atf_map_citer_t iter;
318*00b67f09SDavid van Moolenbroek     size_t i;
319*00b67f09SDavid van Moolenbroek 
320*00b67f09SDavid van Moolenbroek     array = malloc(sizeof(char *) * (atf_map_size(l) * 2 + 1));
321*00b67f09SDavid van Moolenbroek     if (array == NULL)
322*00b67f09SDavid van Moolenbroek         goto out;
323*00b67f09SDavid van Moolenbroek 
324*00b67f09SDavid van Moolenbroek     i = 0;
325*00b67f09SDavid van Moolenbroek     atf_map_for_each_c(iter, l) {
326*00b67f09SDavid van Moolenbroek         array[i] = strdup(atf_map_citer_key(iter));
327*00b67f09SDavid van Moolenbroek         if (array[i] == NULL) {
328*00b67f09SDavid van Moolenbroek             atf_utils_free_charpp(array);
329*00b67f09SDavid van Moolenbroek             array = NULL;
330*00b67f09SDavid van Moolenbroek             goto out;
331*00b67f09SDavid van Moolenbroek         }
332*00b67f09SDavid van Moolenbroek 
333*00b67f09SDavid van Moolenbroek         array[i + 1] = strdup((const char *)atf_map_citer_data(iter));
334*00b67f09SDavid van Moolenbroek         if (array[i + 1] == NULL) {
335*00b67f09SDavid van Moolenbroek             atf_utils_free_charpp(array);
336*00b67f09SDavid van Moolenbroek             array = NULL;
337*00b67f09SDavid van Moolenbroek             goto out;
338*00b67f09SDavid van Moolenbroek         }
339*00b67f09SDavid van Moolenbroek 
340*00b67f09SDavid van Moolenbroek         i += 2;
341*00b67f09SDavid van Moolenbroek     }
342*00b67f09SDavid van Moolenbroek     array[i] = NULL;
343*00b67f09SDavid van Moolenbroek 
344*00b67f09SDavid van Moolenbroek out:
345*00b67f09SDavid van Moolenbroek     return array;
346*00b67f09SDavid van Moolenbroek }
347*00b67f09SDavid van Moolenbroek 
348*00b67f09SDavid van Moolenbroek /*
349*00b67f09SDavid van Moolenbroek  * Modifiers.
350*00b67f09SDavid van Moolenbroek  */
351*00b67f09SDavid van Moolenbroek 
352*00b67f09SDavid van Moolenbroek atf_error_t
atf_map_insert(atf_map_t * m,const char * key,void * value,bool managed)353*00b67f09SDavid van Moolenbroek atf_map_insert(atf_map_t *m, const char *key, void *value, bool managed)
354*00b67f09SDavid van Moolenbroek {
355*00b67f09SDavid van Moolenbroek     struct map_entry *me;
356*00b67f09SDavid van Moolenbroek     atf_error_t err;
357*00b67f09SDavid van Moolenbroek     atf_map_iter_t iter;
358*00b67f09SDavid van Moolenbroek 
359*00b67f09SDavid van Moolenbroek     iter = atf_map_find(m, key);
360*00b67f09SDavid van Moolenbroek     if (atf_equal_map_iter_map_iter(iter, atf_map_end(m))) {
361*00b67f09SDavid van Moolenbroek         me = new_entry(key, value, managed);
362*00b67f09SDavid van Moolenbroek         if (me == NULL)
363*00b67f09SDavid van Moolenbroek             err = atf_no_memory_error();
364*00b67f09SDavid van Moolenbroek         else {
365*00b67f09SDavid van Moolenbroek             err = atf_list_append(&m->m_list, me, false);
366*00b67f09SDavid van Moolenbroek             if (atf_is_error(err)) {
367*00b67f09SDavid van Moolenbroek                 if (managed)
368*00b67f09SDavid van Moolenbroek                     free(value);
369*00b67f09SDavid van Moolenbroek                 free(me);
370*00b67f09SDavid van Moolenbroek             }
371*00b67f09SDavid van Moolenbroek         }
372*00b67f09SDavid van Moolenbroek     } else {
373*00b67f09SDavid van Moolenbroek         me = iter.m_entry;
374*00b67f09SDavid van Moolenbroek         if (me->m_managed)
375*00b67f09SDavid van Moolenbroek             free(me->m_value);
376*00b67f09SDavid van Moolenbroek 
377*00b67f09SDavid van Moolenbroek         INV(strcmp(me->m_key, key) == 0);
378*00b67f09SDavid van Moolenbroek         me->m_value = value;
379*00b67f09SDavid van Moolenbroek         me->m_managed = managed;
380*00b67f09SDavid van Moolenbroek 
381*00b67f09SDavid van Moolenbroek         err = atf_no_error();
382*00b67f09SDavid van Moolenbroek     }
383*00b67f09SDavid van Moolenbroek 
384*00b67f09SDavid van Moolenbroek     return err;
385*00b67f09SDavid van Moolenbroek }
386