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/list.h"
31 #include "atf-c/detail/sanity.h"
32 #include "atf-c/error.h"
33 #include "atf-c/utils.h"
35 /* ---------------------------------------------------------------------
36 * Auxiliary functions.
37 * --------------------------------------------------------------------- */
40 struct list_entry *m_prev;
41 struct list_entry *m_next;
48 entry_to_citer(const atf_list_t *l, const struct list_entry *le)
50 atf_list_citer_t iter;
58 entry_to_iter(atf_list_t *l, struct list_entry *le)
68 new_entry(void *object, bool managed)
70 struct list_entry *le;
72 le = (struct list_entry *)malloc(sizeof(*le));
74 le->m_prev = le->m_next = NULL;
75 le->m_object = object;
76 le->m_managed = managed;
85 delete_entry(struct list_entry *le)
95 new_entry_and_link(void *object, bool managed, struct list_entry *prev,
96 struct list_entry *next)
98 struct list_entry *le;
100 le = new_entry(object, managed);
112 /* ---------------------------------------------------------------------
113 * The "atf_list_citer" type.
114 * --------------------------------------------------------------------- */
121 atf_list_citer_data(const atf_list_citer_t citer)
123 const struct list_entry *le = citer.m_entry;
129 atf_list_citer_next(const atf_list_citer_t citer)
131 const struct list_entry *le = citer.m_entry;
132 atf_list_citer_t newciter;
137 newciter.m_entry = le->m_next;
143 atf_equal_list_citer_list_citer(const atf_list_citer_t i1,
144 const atf_list_citer_t i2)
146 return i1.m_list == i2.m_list && i1.m_entry == i2.m_entry;
149 /* ---------------------------------------------------------------------
150 * The "atf_list_iter" type.
151 * --------------------------------------------------------------------- */
158 atf_list_iter_data(const atf_list_iter_t iter)
160 const struct list_entry *le = iter.m_entry;
166 atf_list_iter_next(const atf_list_iter_t iter)
168 const struct list_entry *le = iter.m_entry;
169 atf_list_iter_t newiter;
174 newiter.m_entry = le->m_next;
180 atf_equal_list_iter_list_iter(const atf_list_iter_t i1,
181 const atf_list_iter_t i2)
183 return i1.m_list == i2.m_list && i1.m_entry == i2.m_entry;
186 /* ---------------------------------------------------------------------
187 * The "atf_list" type.
188 * --------------------------------------------------------------------- */
191 * Constructors and destructors.
195 atf_list_init(atf_list_t *l)
197 struct list_entry *lebeg, *leend;
199 lebeg = new_entry(NULL, false);
201 return atf_no_memory_error();
204 leend = new_entry(NULL, false);
207 return atf_no_memory_error();
210 lebeg->m_next = leend;
211 lebeg->m_prev = NULL;
213 leend->m_next = NULL;
214 leend->m_prev = lebeg;
220 return atf_no_error();
224 atf_list_fini(atf_list_t *l)
226 struct list_entry *le;
229 le = (struct list_entry *)l->m_begin;
232 struct list_entry *lenext;
240 INV(freed == l->m_size + 2);
248 atf_list_begin(atf_list_t *l)
250 struct list_entry *le = l->m_begin;
251 return entry_to_iter(l, le->m_next);
255 atf_list_begin_c(const atf_list_t *l)
257 const struct list_entry *le = l->m_begin;
258 return entry_to_citer(l, le->m_next);
262 atf_list_end(atf_list_t *l)
264 return entry_to_iter(l, l->m_end);
268 atf_list_end_c(const atf_list_t *l)
270 return entry_to_citer(l, l->m_end);
274 atf_list_index(atf_list_t *list, const size_t idx)
276 atf_list_iter_t iter;
278 PRE(idx < atf_list_size(list));
280 iter = atf_list_begin(list);
284 !atf_equal_list_iter_list_iter((iter), atf_list_end(list))) {
285 iter = atf_list_iter_next(iter);
289 return atf_list_iter_data(iter);
293 atf_list_index_c(const atf_list_t *list, const size_t idx)
295 atf_list_citer_t iter;
297 PRE(idx < atf_list_size(list));
299 iter = atf_list_begin_c(list);
303 !atf_equal_list_citer_list_citer((iter),
304 atf_list_end_c(list))) {
305 iter = atf_list_citer_next(iter);
309 return atf_list_citer_data(iter);
313 atf_list_size(const atf_list_t *l)
319 atf_list_to_charpp(const atf_list_t *l)
322 atf_list_citer_t iter;
325 array = malloc(sizeof(char *) * (atf_list_size(l) + 1));
330 atf_list_for_each_c(iter, l) {
331 array[i] = strdup((const char *)atf_list_citer_data(iter));
332 if (array[i] == NULL) {
333 atf_utils_free_charpp(array);
351 atf_list_append(atf_list_t *l, void *data, bool managed)
353 struct list_entry *le, *next, *prev;
356 next = (struct list_entry *)l->m_end;
358 le = new_entry_and_link(data, managed, prev, next);
360 err = atf_no_memory_error();
363 err = atf_no_error();
370 atf_list_append_list(atf_list_t *l, atf_list_t *src)
372 struct list_entry *e1, *e2, *ghost1, *ghost2;
374 ghost1 = (struct list_entry *)l->m_end;
375 ghost2 = (struct list_entry *)src->m_begin;
380 delete_entry(ghost1);
381 delete_entry(ghost2);
386 l->m_end = src->m_end;
387 l->m_size += src->m_size;