]> git.proxmox.com Git - mirror_frr.git/blob - lib/linklist.h
Merge pull request #2559 from pacovn/Coverity_1302503_Logically_dead_code
[mirror_frr.git] / lib / linklist.h
1 /* Generic linked list
2 * Copyright (C) 1997, 2000 Kunihiro Ishiguro
3 *
4 * This file is part of GNU Zebra.
5 *
6 * GNU Zebra is free software; you can redistribute it and/or modify it
7 * under the terms of the GNU General Public License as published by the
8 * Free Software Foundation; either version 2, or (at your option) any
9 * later version.
10 *
11 * GNU Zebra is distributed in the hope that it will be useful, but
12 * WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License along
17 * with this program; see the file COPYING; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
19 */
20
21 #ifndef _ZEBRA_LINKLIST_H
22 #define _ZEBRA_LINKLIST_H
23
24 /* listnodes must always contain data to be valid. Adding an empty node
25 * to a list is invalid
26 */
27 struct listnode {
28 struct listnode *next;
29 struct listnode *prev;
30
31 /* private member, use getdata() to retrieve, do not access directly */
32 void *data;
33 };
34
35 struct list {
36 struct listnode *head;
37 struct listnode *tail;
38
39 /* invariant: count is the number of listnodes in the list */
40 unsigned int count;
41
42 /*
43 * Returns -1 if val1 < val2, 0 if equal?, 1 if val1 > val2.
44 * Used as definition of sorted for listnode_add_sort
45 */
46 int (*cmp)(void *val1, void *val2);
47
48 /* callback to free user-owned data when listnode is deleted. supplying
49 * this callback is very much encouraged!
50 */
51 void (*del)(void *val);
52 };
53
54 #define listnextnode(X) ((X) ? ((X)->next) : NULL)
55 #define listnextnode_unchecked(X) ((X)->next)
56 #define listhead(X) ((X) ? ((X)->head) : NULL)
57 #define listtail(X) ((X) ? ((X)->tail) : NULL)
58 #define listcount(X) ((X)->count)
59 #define list_isempty(X) ((X)->head == NULL && (X)->tail == NULL)
60 /* return X->data only if X and X->data are not NULL */
61 #define listgetdata(X) (assert(X), assert((X)->data != NULL), (X)->data)
62
63 /*
64 * Create a new linked list.
65 *
66 * Returns:
67 * the created linked list
68 */
69 extern struct list *list_new(void);
70
71 /*
72 * Add a new element to the tail of a list.
73 *
74 * Runtime is O(1).
75 *
76 * list
77 * list to operate on
78 *
79 * data
80 * element to add
81 */
82 extern void listnode_add(struct list *list, void *data);
83
84 /*
85 * Insert a new element into a list with insertion sort.
86 *
87 * If list->cmp is set, this function is used to determine the position to
88 * insert the new element. If it is not set, this function is equivalent to
89 * listnode_add.
90 *
91 * Runtime is O(N).
92 *
93 * list
94 * list to operate on
95 *
96 * val
97 * element to add
98 */
99 extern void listnode_add_sort(struct list *list, void *val);
100
101 /*
102 * Insert a new element into a list after another element.
103 *
104 * Runtime is O(1).
105 *
106 * list
107 * list to operate on
108 *
109 * pp
110 * listnode to insert after
111 *
112 * data
113 * data to insert
114 *
115 * Returns:
116 * pointer to newly created listnode that contains the inserted data
117 */
118 extern struct listnode *listnode_add_after(struct list *list,
119 struct listnode *pp, void *data);
120
121 /*
122 * Insert a new element into a list before another element.
123 *
124 * Runtime is O(1).
125 *
126 * list
127 * list to operate on
128 *
129 * pp
130 * listnode to insert before
131 *
132 * data
133 * data to insert
134 *
135 * Returns:
136 * pointer to newly created listnode that contains the inserted data
137 */
138 extern struct listnode *listnode_add_before(struct list *list,
139 struct listnode *pp, void *data);
140
141 /*
142 * Move a node to the tail of a list.
143 *
144 * Runtime is O(1).
145 *
146 * list
147 * list to operate on
148 *
149 * node
150 * node to move to tail
151 */
152 extern void listnode_move_to_tail(struct list *list, struct listnode *node);
153
154 /*
155 * Delete an element from a list.
156 *
157 * Runtime is O(N).
158 *
159 * list
160 * list to operate on
161 *
162 * data
163 * data to insert into list
164 */
165 extern void listnode_delete(struct list *list, void *data);
166
167 /*
168 * Find the listnode corresponding to an element in a list.
169 *
170 * list
171 * list to operate on
172 *
173 * data
174 * data to search for
175 *
176 * Returns:
177 * pointer to listnode storing the given data if found, NULL otherwise
178 */
179 extern struct listnode *listnode_lookup(struct list *list, void *data);
180
181 /*
182 * Retrieve the element at the head of a list.
183 *
184 * list
185 * list to operate on
186 *
187 * Returns:
188 * data at head of list, or NULL if list is empty
189 */
190 extern void *listnode_head(struct list *list);
191
192 /*
193 * Duplicate a list.
194 *
195 * list
196 * list to duplicate
197 *
198 * Returns:
199 * copy of the list
200 */
201 extern struct list *list_dup(struct list *l);
202
203 /*
204 * Sort a list in place.
205 *
206 * The sorting algorithm used is quicksort. Runtimes are equivalent to those of
207 * quicksort plus N. The sort is not stable.
208 *
209 * For portability reasons, the comparison function takes a pointer to pointer
210 * to void. This pointer should be dereferenced to get the actual data pointer.
211 * It is always safe to do this.
212 *
213 * list
214 * list to sort
215 *
216 * cmp
217 * comparison function for quicksort. Should return less than, equal to or
218 * greater than zero if the first argument is less than, equal to or greater
219 * than the second argument.
220 */
221 extern void list_sort(struct list *list,
222 int (*cmp)(const void **, const void **));
223
224 /*
225 * The usage of list_delete is being transitioned to pass in
226 * the double pointer to remove use after free's.
227 * list_free usage is deprecated, it leads to memory leaks
228 * of the linklist nodes. Please use list_delete_and_null
229 *
230 * In Oct of 2018, rename list_delete_and_null to list_delete
231 * and remove list_delete_original and the list_delete #define
232 * Additionally remove list_free entirely
233 */
234 #if defined(VERSION_TYPE_DEV) && CONFDATE > 20181001
235 CPP_NOTICE("list_delete without double pointer is deprecated, please fixup")
236 #endif
237
238 /*
239 * Delete a list and NULL its pointer.
240 *
241 * If non-null, list->del is called with each data element.
242 *
243 * plist
244 * pointer to list pointer; this will be set to NULL after the list has been
245 * deleted
246 */
247 extern void list_delete_and_null(struct list **plist);
248
249 /*
250 * Delete a list.
251 *
252 * If non-null, list->del is called with each data element.
253 *
254 * plist
255 * pointer to list pointer
256 */
257 extern void list_delete_original(struct list *list);
258 #define list_delete(X) \
259 list_delete_original((X)) \
260 CPP_WARN("Please transition to using list_delete_and_null")
261 #define list_free(X) \
262 list_delete_original((X)) \
263 CPP_WARN("Please transition tousing list_delete_and_null")
264
265 /*
266 * Delete all nodes from a list without deleting the list itself.
267 *
268 * If non-null, list->del is called with each data element.
269 *
270 * list
271 * list to operate on
272 */
273 extern void list_delete_all_node(struct list *list);
274
275 /*
276 * Delete a node from a list.
277 *
278 * list->del is not called with the data associated with the node.
279 *
280 * Runtime is O(1).
281 *
282 * list
283 * list to operate on
284 *
285 * node
286 * the node to delete
287 */
288 extern void list_delete_node(struct list *list, struct listnode *node);
289
290 /*
291 * Append a list to an existing list.
292 *
293 * Runtime is O(N) where N = listcount(add).
294 *
295 * list
296 * list to append to
297 *
298 * add
299 * list to append
300 */
301 extern void list_add_list(struct list *list, struct list *add);
302
303 /* List iteration macro.
304 * Usage: for (ALL_LIST_ELEMENTS (...) { ... }
305 * It is safe to delete the listnode using this macro.
306 */
307 #define ALL_LIST_ELEMENTS(list, node, nextnode, data) \
308 (node) = listhead(list), ((data) = NULL); \
309 (node) != NULL \
310 && ((data) = listgetdata(node), (nextnode) = node->next, 1); \
311 (node) = (nextnode), ((data) = NULL)
312
313 /* read-only list iteration macro.
314 * Usage: as per ALL_LIST_ELEMENTS, but not safe to delete the listnode Only
315 * use this macro when it is *immediately obvious* the listnode is not
316 * deleted in the body of the loop. Does not have forward-reference overhead
317 * of previous macro.
318 */
319 #define ALL_LIST_ELEMENTS_RO(list, node, data) \
320 (node) = listhead(list), ((data) = NULL); \
321 (node) != NULL && ((data) = listgetdata(node), 1); \
322 (node) = listnextnode(node), ((data) = NULL)
323
324 /* these *do not* cleanup list nodes and referenced data, as the functions
325 * do - these macros simply {de,at}tach a listnode from/to a list.
326 */
327
328 /* List node attach macro. */
329 #define LISTNODE_ATTACH(L, N) \
330 do { \
331 (N)->prev = (L)->tail; \
332 (N)->next = NULL; \
333 if ((L)->head == NULL) \
334 (L)->head = (N); \
335 else \
336 (L)->tail->next = (N); \
337 (L)->tail = (N); \
338 (L)->count++; \
339 } while (0)
340
341 /* List node detach macro. */
342 #define LISTNODE_DETACH(L, N) \
343 do { \
344 if ((N)->prev) \
345 (N)->prev->next = (N)->next; \
346 else \
347 (L)->head = (N)->next; \
348 if ((N)->next) \
349 (N)->next->prev = (N)->prev; \
350 else \
351 (L)->tail = (N)->prev; \
352 (L)->count--; \
353 } while (0)
354
355 #endif /* _ZEBRA_LINKLIST_H */