]> git.ipfire.org Git - thirdparty/kmod.git/blame - libkmod/libkmod-list.c
ci: move compression variants further down
[thirdparty/kmod.git] / libkmod / libkmod-list.c
CommitLineData
b5a2cd07 1// SPDX-License-Identifier: LGPL-2.1-or-later
6924e47a 2/*
e6b0e49b 3 * Copyright (C) 2011-2013 ProFUSION embedded systems
6924e47a
LDM
4 */
5
6#include <stdlib.h>
7
8#include "libkmod.h"
83b855a6 9#include "libkmod-internal.h"
6924e47a
LDM
10
11static inline struct list_node *list_node_init(struct list_node *node)
12{
13 node->next = node;
14 node->prev = node;
15
16 return node;
17}
18
115bcd52 19static inline void list_node_append(struct list_node *list, struct list_node *node)
6924e47a
LDM
20{
21 if (list == NULL) {
22 list_node_init(node);
23 return;
24 }
25
26 node->prev = list->prev;
27 list->prev->next = node;
28 list->prev = node;
29 node->next = list;
30}
31
32static inline struct list_node *list_node_remove(struct list_node *node)
33{
34 if (node->prev == node || node->next == node)
35 return NULL;
36
37 node->prev->next = node->next;
38 node->next->prev = node->prev;
39
e16e27f4 40 return node->next;
6924e47a
LDM
41}
42
115bcd52 43static inline void list_node_insert_after(struct list_node *list, struct list_node *node)
86e87885
LDM
44{
45 if (list == NULL) {
46 list_node_init(node);
47 return;
48 }
49
50 node->prev = list;
51 node->next = list->next;
52 list->next->prev = node;
53 list->next = node;
54}
55
115bcd52 56static inline void list_node_insert_before(struct list_node *list, struct list_node *node)
b91a1c6d
LDM
57{
58 if (list == NULL) {
59 list_node_init(node);
60 return;
61 }
62
63 node->next = list;
64 node->prev = list->prev;
65 list->prev->next = node;
66 list->prev = node;
67}
68
115bcd52 69static inline void list_node_append_list(struct list_node *list1, struct list_node *list2)
1965029c
LDM
70{
71 struct list_node *list1_last;
72
73 if (list1 == NULL) {
74 list_node_init(list2);
75 return;
76 }
77
78 list1->prev->next = list2;
79 list2->prev->next = list1;
80
81 /* cache the last, because we will lose the pointer */
82 list1_last = list1->prev;
83
84 list1->prev = list2->prev;
85 list2->prev = list1_last;
86}
87
1ce08a56 88struct kmod_list *kmod_list_append(struct kmod_list *list, const void *data)
6924e47a
LDM
89{
90 struct kmod_list *new;
91
92 new = malloc(sizeof(*new));
93 if (new == NULL)
94 return NULL;
95
1ce08a56 96 new->data = (void *)data;
6924e47a
LDM
97 list_node_append(list ? &list->node : NULL, &new->node);
98
99 return list ? list : new;
100}
101
115bcd52 102struct kmod_list *kmod_list_insert_after(struct kmod_list *list, const void *data)
86e87885
LDM
103{
104 struct kmod_list *new;
105
106 if (list == NULL)
107 return kmod_list_append(list, data);
108
109 new = malloc(sizeof(*new));
110 if (new == NULL)
111 return NULL;
112
113 new->data = (void *)data;
114 list_node_insert_after(&list->node, &new->node);
115
116 return list;
117}
118
115bcd52 119struct kmod_list *kmod_list_insert_before(struct kmod_list *list, const void *data)
b91a1c6d
LDM
120{
121 struct kmod_list *new;
122
123 if (list == NULL)
124 return kmod_list_append(list, data);
125
126 new = malloc(sizeof(*new));
127 if (new == NULL)
128 return NULL;
129
130 new->data = (void *)data;
131 list_node_insert_before(&list->node, &new->node);
132
133 return new;
134}
135
115bcd52 136struct kmod_list *kmod_list_append_list(struct kmod_list *list1, struct kmod_list *list2)
1965029c
LDM
137{
138 if (list1 == NULL)
139 return list2;
140
434f32ca
LDM
141 if (list2 == NULL)
142 return list1;
143
1965029c
LDM
144 list_node_append_list(&list1->node, &list2->node);
145
146 return list1;
147}
148
1ce08a56 149struct kmod_list *kmod_list_prepend(struct kmod_list *list, const void *data)
6924e47a
LDM
150{
151 struct kmod_list *new;
152
153 new = malloc(sizeof(*new));
154 if (new == NULL)
155 return NULL;
156
1ce08a56 157 new->data = (void *)data;
6924e47a
LDM
158 list_node_append(list ? &list->node : NULL, &new->node);
159
160 return new;
161}
162
163struct kmod_list *kmod_list_remove(struct kmod_list *list)
164{
165 struct list_node *node;
166
167 if (list == NULL)
168 return NULL;
169
170 node = list_node_remove(&list->node);
171 free(list);
172
173 if (node == NULL)
174 return NULL;
175
176 return container_of(node, struct kmod_list, node);
177}
178
115bcd52 179struct kmod_list *kmod_list_remove_data(struct kmod_list *list, const void *data)
6924e47a
LDM
180{
181 struct kmod_list *itr;
182 struct list_node *node;
183
184 for (itr = list; itr != NULL; itr = kmod_list_next(list, itr)) {
185 if (itr->data == data)
186 break;
187 }
188
189 if (itr == NULL)
190 return list;
191
192 node = list_node_remove(&itr->node);
193 free(itr);
194
195 if (node == NULL)
196 return NULL;
197
198 return container_of(node, struct kmod_list, node);
199}
200
1ce08a56 201KMOD_EXPORT struct kmod_list *kmod_list_prev(const struct kmod_list *list,
115bcd52 202 const struct kmod_list *curr)
79d77111
LDM
203{
204 if (list == NULL || curr == NULL)
205 return NULL;
206
2a70a5d4 207 if (list == curr)
79d77111
LDM
208 return NULL;
209
210 return container_of(curr->node.prev, struct kmod_list, node);
211}
212
1ce08a56 213KMOD_EXPORT struct kmod_list *kmod_list_next(const struct kmod_list *list,
115bcd52 214 const struct kmod_list *curr)
6924e47a
LDM
215{
216 if (list == NULL || curr == NULL)
217 return NULL;
218
219 if (curr->node.next == &list->node)
220 return NULL;
221
222 return container_of(curr->node.next, struct kmod_list, node);
223}
d5ec60bc 224
d5ec60bc
GSB
225KMOD_EXPORT struct kmod_list *kmod_list_last(const struct kmod_list *list)
226{
227 if (list == NULL)
228 return NULL;
229 return container_of(list->node.prev, struct kmod_list, node);
230}