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