Fix potential undefined references to FILE, for libopkg users.
[oweals/opkg-lede.git] / libopkg / void_list.c
1 /* void_list.c - the opkg package management system
2
3    Carl D. Worth
4
5    Copyright (C) 2001 University of Southern California
6
7    This program is free software; you can redistribute it and/or
8    modify it under the terms of the GNU General Public License as
9    published by the Free Software Foundation; either version 2, or (at
10    your option) any later version.
11
12    This program is distributed in the hope that it will be useful, but
13    WITHOUT ANY WARRANTY; without even the implied warranty of
14    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15    General Public License for more details.
16 */
17
18 #include "void_list.h"
19 #include "libbb/libbb.h"
20
21 void void_list_elt_init(void_list_elt_t *elt, void *data)
22 {
23     INIT_LIST_HEAD(&elt->node);
24     elt->data = data;
25 }
26
27 static void_list_elt_t * void_list_elt_new (void *data) {
28     void_list_elt_t *elt;
29     /* freed in void_list_elt_deinit */
30     elt = xcalloc(1, sizeof(void_list_elt_t));
31     void_list_elt_init(elt, data);
32     return elt;
33 }
34
35 void void_list_elt_deinit(void_list_elt_t *elt)
36 {
37     list_del_init(&elt->node);
38     void_list_elt_init(elt, NULL);
39     free(elt);
40 }
41
42 void void_list_init(void_list_t *list)
43 {
44     INIT_LIST_HEAD(&list->head);
45 }
46
47 void void_list_deinit(void_list_t *list)
48 {
49     void_list_elt_t *elt;
50
51     while (!void_list_empty(list)) {
52         elt = void_list_pop(list);
53         void_list_elt_deinit(elt);
54     }
55     INIT_LIST_HEAD(&list->head);
56 }
57
58 void void_list_append(void_list_t *list, void *data)
59 {
60     void_list_elt_t *elt = void_list_elt_new(data);
61     list_add_tail(&elt->node, &list->head);
62 }
63
64 void void_list_push(void_list_t *list, void *data)
65 {
66     void_list_elt_t *elt = void_list_elt_new(data);
67     list_add(&elt->node, &list->head);
68 }
69
70 void_list_elt_t *void_list_pop(void_list_t *list)
71 {
72     struct list_head *node;
73
74     if (void_list_empty(list))
75         return NULL;
76     node = list->head.next;
77     list_del_init(node);
78     return list_entry(node, void_list_elt_t, node);
79 }
80
81 void *void_list_remove(void_list_t *list, void_list_elt_t **iter)
82 {
83     void_list_elt_t *pos, *n;
84     void_list_elt_t *old_elt;
85     void *old_data = NULL;
86
87     old_elt = *iter;
88     if (!old_elt)
89         return old_data;
90     old_data = old_elt->data;
91
92     list_for_each_entry_safe(pos, n, &list->head, node) {
93         if (pos == old_elt)
94             break;
95     }
96     if ( pos != old_elt) {
97         opkg_msg(ERROR, "Internal error: element not found in list.\n");
98         return NULL;
99     }
100
101     *iter = list_entry(pos->node.prev, void_list_elt_t, node);
102     void_list_elt_deinit(pos);
103
104     return old_data;
105 }
106
107 /* remove element containing elt data, using cmp(elt->data, target_data) == 0. */
108 void *void_list_remove_elt(void_list_t *list, const void *target_data, void_list_cmp_t cmp)
109 {
110     void_list_elt_t *pos, *n;
111     void *old_data = NULL;
112     list_for_each_entry_safe(pos, n, &list->head, node) {
113         if ( pos->data && cmp(pos->data, target_data)==0 ){
114             old_data = pos->data;
115             void_list_elt_deinit(pos);
116             break;
117         }
118     }
119     return old_data;
120 }
121
122 void_list_elt_t *void_list_first(void_list_t *list) {
123     struct list_head *elt;
124     if (!list)
125         return NULL;
126     elt = list->head.next;
127     if (elt == &list->head ) {
128         return NULL;
129     }
130     return list_entry(elt, void_list_elt_t, node);
131 }
132
133 void_list_elt_t *void_list_prev(void_list_t *list, void_list_elt_t *node) {
134     struct list_head *elt;
135     if (!list || !node)
136         return NULL;
137     elt = node->node.prev;
138     if (elt == &list->head ) {
139         return NULL;
140     }
141     return list_entry(elt, void_list_elt_t, node);
142 }
143
144 void_list_elt_t *void_list_next(void_list_t *list, void_list_elt_t *node) {
145     struct list_head *elt;
146     if (!list || !node)
147         return NULL;
148     elt = node->node.next;
149     if (elt == &list->head ) {
150         return NULL;
151     }
152     return list_entry(elt, void_list_elt_t, node);
153 }
154
155 void_list_elt_t *void_list_last(void_list_t *list) {
156     struct list_head *elt;
157     if (!list)
158         return NULL;
159     elt = list->head.prev;
160     if (elt == &list->head ) {
161         return NULL;
162     }
163     return list_entry(elt, void_list_elt_t, node);
164 }
165