]> git.ipfire.org Git - thirdparty/kmod.git/blob - libkmod/libkmod-list.c
improve "const" keyword usage.
[thirdparty/kmod.git] / libkmod / libkmod-list.c
1 /*
2 * libkmod - interface to kernel module operations
3 *
4 * Copyright (C) 2011 ProFUSION embedded systems
5 *
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.
9 *
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.
14 *
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
18 */
19
20 #include <stdlib.h>
21
22 #include "libkmod.h"
23 #include "libkmod-private.h"
24
25 static inline struct list_node *list_node_init(struct list_node *node)
26 {
27 node->next = node;
28 node->prev = node;
29
30 return node;
31 }
32
33 static inline struct list_node *list_node_next(const struct list_node *node)
34 {
35 if (node == NULL)
36 return NULL;
37
38 return node->next;
39 }
40
41 static inline struct list_node *list_node_prev(const struct list_node *node)
42 {
43 if (node == NULL)
44 return NULL;
45
46 return node->prev;
47 }
48
49 static inline void list_node_append(struct list_node *list,
50 struct list_node *node)
51 {
52 if (list == NULL) {
53 list_node_init(node);
54 return;
55 }
56
57 node->prev = list->prev;
58 list->prev->next = node;
59 list->prev = node;
60 node->next = list;
61 }
62
63 static inline struct list_node *list_node_remove(struct list_node *node)
64 {
65 if (node->prev == node || node->next == node)
66 return NULL;
67
68 node->prev->next = node->next;
69 node->next->prev = node->prev;
70
71 return node->prev;
72 }
73
74 struct kmod_list *kmod_list_append(struct kmod_list *list, const void *data)
75 {
76 struct kmod_list *new;
77
78 new = malloc(sizeof(*new));
79 if (new == NULL)
80 return NULL;
81
82 new->data = (void *)data;
83 list_node_append(list ? &list->node : NULL, &new->node);
84
85 return list ? list : new;
86 }
87
88 struct kmod_list *kmod_list_prepend(struct kmod_list *list, const void *data)
89 {
90 struct kmod_list *new;
91
92 new = malloc(sizeof(*new));
93 if (new == NULL)
94 return NULL;
95
96 new->data = (void *)data;
97 list_node_append(list ? &list->node : NULL, &new->node);
98
99 return new;
100 }
101
102 struct kmod_list *kmod_list_remove(struct kmod_list *list)
103 {
104 struct list_node *node;
105
106 if (list == NULL)
107 return NULL;
108
109 node = list_node_remove(&list->node);
110 free(list);
111
112 if (node == NULL)
113 return NULL;
114
115 return container_of(node, struct kmod_list, node);
116 }
117
118 struct kmod_list *kmod_list_remove_data(struct kmod_list *list,
119 const void *data)
120 {
121 struct kmod_list *itr;
122 struct list_node *node;
123
124 for (itr = list; itr != NULL; itr = kmod_list_next(list, itr)) {
125 if (itr->data == data)
126 break;
127 }
128
129 if (itr == NULL)
130 return list;
131
132 node = list_node_remove(&itr->node);
133 free(itr);
134
135 if (node == NULL)
136 return NULL;
137
138 return container_of(node, struct kmod_list, node);
139 }
140
141 /*
142 * n must be greater to or equal the number of elements (we don't check the
143 * condition
144 */
145 struct kmod_list *kmod_list_remove_n_latest(struct kmod_list *list,
146 unsigned int n)
147 {
148 struct kmod_list *l;
149 unsigned int i;
150
151 /*
152 * Get last element, remove all appended elments and if list became
153 * empty, set return pointer to NULL
154 */
155 l = kmod_list_prev(list, list);
156 if (l == NULL)
157 l = list;
158
159 for (i = 0; i < n; i++)
160 l = kmod_list_remove(l);
161
162 /* If list became empty, save it*/
163 if (l == NULL)
164 list = NULL;
165
166 return list;
167 }
168
169 KMOD_EXPORT struct kmod_list *kmod_list_prev(const struct kmod_list *list,
170 const struct kmod_list *curr)
171 {
172 if (list == NULL || curr == NULL)
173 return NULL;
174
175 if (curr->node.prev == &list->node)
176 return NULL;
177
178 return container_of(curr->node.prev, struct kmod_list, node);
179 }
180
181 KMOD_EXPORT struct kmod_list *kmod_list_next(const struct kmod_list *list,
182 const struct kmod_list *curr)
183 {
184 if (list == NULL || curr == NULL)
185 return NULL;
186
187 if (curr->node.next == &list->node)
188 return NULL;
189
190 return container_of(curr->node.next, struct kmod_list, node);
191 }