]>
git.ipfire.org Git - thirdparty/kmod.git/blob - libkmod/libkmod-list.c
2 * libkmod - interface to kernel module operations
4 * Copyright (C) 2011-2013 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; either
9 * version 2.1 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
24 #include "libkmod-internal.h"
27 * SECTION:libkmod-list
28 * @short_description: general purpose list
31 static inline struct list_node
*list_node_init(struct list_node
*node
)
39 static inline struct list_node
*list_node_next(const struct list_node
*node
)
47 static inline struct list_node
*list_node_prev(const struct list_node
*node
)
55 static inline void list_node_append(struct list_node
*list
,
56 struct list_node
*node
)
63 node
->prev
= list
->prev
;
64 list
->prev
->next
= node
;
69 static inline struct list_node
*list_node_remove(struct list_node
*node
)
71 if (node
->prev
== node
|| node
->next
== node
)
74 node
->prev
->next
= node
->next
;
75 node
->next
->prev
= node
->prev
;
80 static inline void list_node_insert_after(struct list_node
*list
,
81 struct list_node
*node
)
89 node
->next
= list
->next
;
90 list
->next
->prev
= node
;
94 static inline void list_node_insert_before(struct list_node
*list
,
95 struct list_node
*node
)
103 node
->prev
= list
->prev
;
104 list
->prev
->next
= node
;
108 static inline void list_node_append_list(struct list_node
*list1
,
109 struct list_node
*list2
)
111 struct list_node
*list1_last
;
114 list_node_init(list2
);
118 list1
->prev
->next
= list2
;
119 list2
->prev
->next
= list1
;
121 /* cache the last, because we will lose the pointer */
122 list1_last
= list1
->prev
;
124 list1
->prev
= list2
->prev
;
125 list2
->prev
= list1_last
;
128 struct kmod_list
*kmod_list_append(struct kmod_list
*list
, const void *data
)
130 struct kmod_list
*new;
132 new = malloc(sizeof(*new));
136 new->data
= (void *)data
;
137 list_node_append(list
? &list
->node
: NULL
, &new->node
);
139 return list
? list
: new;
142 struct kmod_list
*kmod_list_insert_after(struct kmod_list
*list
,
145 struct kmod_list
*new;
148 return kmod_list_append(list
, data
);
150 new = malloc(sizeof(*new));
154 new->data
= (void *)data
;
155 list_node_insert_after(&list
->node
, &new->node
);
160 struct kmod_list
*kmod_list_insert_before(struct kmod_list
*list
,
163 struct kmod_list
*new;
166 return kmod_list_append(list
, data
);
168 new = malloc(sizeof(*new));
172 new->data
= (void *)data
;
173 list_node_insert_before(&list
->node
, &new->node
);
178 struct kmod_list
*kmod_list_append_list(struct kmod_list
*list1
,
179 struct kmod_list
*list2
)
187 list_node_append_list(&list1
->node
, &list2
->node
);
192 struct kmod_list
*kmod_list_prepend(struct kmod_list
*list
, const void *data
)
194 struct kmod_list
*new;
196 new = malloc(sizeof(*new));
200 new->data
= (void *)data
;
201 list_node_append(list
? &list
->node
: NULL
, &new->node
);
206 struct kmod_list
*kmod_list_remove(struct kmod_list
*list
)
208 struct list_node
*node
;
213 node
= list_node_remove(&list
->node
);
219 return container_of(node
, struct kmod_list
, node
);
222 struct kmod_list
*kmod_list_remove_data(struct kmod_list
*list
,
225 struct kmod_list
*itr
;
226 struct list_node
*node
;
228 for (itr
= list
; itr
!= NULL
; itr
= kmod_list_next(list
, itr
)) {
229 if (itr
->data
== data
)
236 node
= list_node_remove(&itr
->node
);
242 return container_of(node
, struct kmod_list
, node
);
246 * n must be greater to or equal the number of elements (we don't check the
249 struct kmod_list
*kmod_list_remove_n_latest(struct kmod_list
*list
,
252 struct kmod_list
*l
= list
;
255 for (i
= 0; i
< n
; i
++) {
256 l
= kmod_list_last(l
);
257 l
= kmod_list_remove(l
);
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
)
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
);
315 * @list: the head of the list
317 * Get the last element of the @list. As @list is a circular list,
318 * this is a cheap operation O(1) with the last element being the
321 * If the list has a single element it will return the list itself (as
322 * expected, and this is what differentiates from kmod_list_prev()).
324 * Returns: last node at @list or NULL if the list is empty.
326 KMOD_EXPORT
struct kmod_list
*kmod_list_last(const struct kmod_list
*list
)
330 return container_of(list
->node
.prev
, struct kmod_list
, node
);