]>
git.ipfire.org Git - thirdparty/kmod.git/blob - libkmod/libkmod-list.c
2 * libkmod - interface to kernel module operations
4 * Copyright (C) 2011 ProFUSION embedded systems
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation version 2.1.
10 * This library is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * Lesser General Public License for more details.
15 * You should have received a copy of the GNU Lesser General Public
16 * License along with this library; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
23 #include "libkmod-private.h"
25 static inline struct list_node
*list_node_init(struct list_node
*node
)
33 static inline struct list_node
*list_node_next(const struct list_node
*node
)
41 static inline struct list_node
*list_node_prev(const struct list_node
*node
)
49 static inline void list_node_append(struct list_node
*list
,
50 struct list_node
*node
)
57 node
->prev
= list
->prev
;
58 list
->prev
->next
= node
;
63 static inline struct list_node
*list_node_remove(struct list_node
*node
)
65 if (node
->prev
== node
|| node
->next
== node
)
68 node
->prev
->next
= node
->next
;
69 node
->next
->prev
= node
->prev
;
74 static inline void list_node_insert_after(struct list_node
*list
,
75 struct list_node
*node
)
83 node
->next
= list
->next
;
84 list
->next
->prev
= node
;
88 static inline void list_node_insert_before(struct list_node
*list
,
89 struct list_node
*node
)
97 node
->prev
= list
->prev
;
98 list
->prev
->next
= node
;
102 static inline void list_node_append_list(struct list_node
*list1
,
103 struct list_node
*list2
)
105 struct list_node
*list1_last
;
108 list_node_init(list2
);
112 list1
->prev
->next
= list2
;
113 list2
->prev
->next
= list1
;
115 /* cache the last, because we will lose the pointer */
116 list1_last
= list1
->prev
;
118 list1
->prev
= list2
->prev
;
119 list2
->prev
= list1_last
;
122 struct kmod_list
*kmod_list_append(struct kmod_list
*list
, const void *data
)
124 struct kmod_list
*new;
126 new = malloc(sizeof(*new));
130 new->data
= (void *)data
;
131 list_node_append(list
? &list
->node
: NULL
, &new->node
);
133 return list
? list
: new;
136 struct kmod_list
*kmod_list_insert_after(struct kmod_list
*list
,
139 struct kmod_list
*new;
142 return kmod_list_append(list
, data
);
144 new = malloc(sizeof(*new));
148 new->data
= (void *)data
;
149 list_node_insert_after(&list
->node
, &new->node
);
154 struct kmod_list
*kmod_list_insert_before(struct kmod_list
*list
,
157 struct kmod_list
*new;
160 return kmod_list_append(list
, data
);
162 new = malloc(sizeof(*new));
166 new->data
= (void *)data
;
167 list_node_insert_before(&list
->node
, &new->node
);
172 struct kmod_list
*kmod_list_append_list(struct kmod_list
*list1
,
173 struct kmod_list
*list2
)
178 list_node_append_list(&list1
->node
, &list2
->node
);
183 struct kmod_list
*kmod_list_prepend(struct kmod_list
*list
, const void *data
)
185 struct kmod_list
*new;
187 new = malloc(sizeof(*new));
191 new->data
= (void *)data
;
192 list_node_append(list
? &list
->node
: NULL
, &new->node
);
197 struct kmod_list
*kmod_list_remove(struct kmod_list
*list
)
199 struct list_node
*node
;
204 node
= list_node_remove(&list
->node
);
210 return container_of(node
, struct kmod_list
, node
);
213 struct kmod_list
*kmod_list_remove_data(struct kmod_list
*list
,
216 struct kmod_list
*itr
;
217 struct list_node
*node
;
219 for (itr
= list
; itr
!= NULL
; itr
= kmod_list_next(list
, itr
)) {
220 if (itr
->data
== data
)
227 node
= list_node_remove(&itr
->node
);
233 return container_of(node
, struct kmod_list
, node
);
237 * n must be greater to or equal the number of elements (we don't check the
240 struct kmod_list
*kmod_list_remove_n_latest(struct kmod_list
*list
,
247 * Get last element, remove all appended elments and if list became
248 * empty, set return pointer to NULL
250 l
= kmod_list_prev(list
, list
);
254 for (i
= 0; i
< n
; i
++)
255 l
= kmod_list_remove(l
);
257 /* If list became empty, save it*/
265 * @list: the head of the list
266 * @curr: the current node in the list
268 * Get the previous node in @list relative to @curr as if @list was not a
269 * circular list. I.e.: the previous of the head is NULL. It can be used to
270 * iterate a list by checking for NULL return to know when all elements were
273 * Returns: node previous to @curr or NULL if either this node is the head of
274 * the list or the list is empty.
276 KMOD_EXPORT
struct kmod_list
*kmod_list_prev(const struct kmod_list
*list
,
277 const struct kmod_list
*curr
)
279 if (list
== NULL
|| curr
== NULL
)
282 if (curr
->node
.prev
== &list
->node
)
285 return container_of(curr
->node
.prev
, struct kmod_list
, node
);
290 * @list: the head of the list
291 * @curr: the current node in the list
293 * Get the next node in @list relative to @curr as if @list was not a circular
294 * list. I.e. calling this function in the last node of the list returns
295 * NULL.. It can be used to iterate a list by checking for NULL return to know
296 * when all elements were iterated.
298 * Returns: node next to @curr or NULL if either this node is the last of or
301 KMOD_EXPORT
struct kmod_list
*kmod_list_next(const struct kmod_list
*list
,
302 const struct kmod_list
*curr
)
304 if (list
== NULL
|| curr
== NULL
)
307 if (curr
->node
.next
== &list
->node
)
310 return container_of(curr
->node
.next
, struct kmod_list
, node
);