]> git.proxmox.com Git - mirror_frr.git/blob - lib/linklist.h
Merge pull request #2367 from qlyoung/docuser
[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 listhead(X) ((X) ? ((X)->head) : NULL)
56 #define listtail(X) ((X) ? ((X)->tail) : NULL)
57 #define listcount(X) ((X)->count)
58 #define list_isempty(X) ((X)->head == NULL && (X)->tail == NULL)
59 /* return X->data only if X and X->data are not NULL */
60 #define listgetdata(X) (assert(X), assert((X)->data != NULL), (X)->data)
61
62 /*
63 * Create a new linked list.
64 *
65 * Returns:
66 * the created linked list
67 */
68 extern struct list *list_new(void);
69
70 /*
71 * Add a new element to the tail of a list.
72 *
73 * Runtime is O(1).
74 *
75 * list
76 * list to operate on
77 *
78 * data
79 * element to add
80 */
81 extern void listnode_add(struct list *list, void *data);
82
83 /*
84 * Insert a new element into a list with insertion sort.
85 *
86 * If list->cmp is set, this function is used to determine the position to
87 * insert the new element. If it is not set, this function is equivalent to
88 * listnode_add.
89 *
90 * Runtime is O(N).
91 *
92 * list
93 * list to operate on
94 *
95 * val
96 * element to add
97 */
98 extern void listnode_add_sort(struct list *list, void *val);
99
100 /*
101 * Insert a new element into a list after another element.
102 *
103 * Runtime is O(1).
104 *
105 * list
106 * list to operate on
107 *
108 * pp
109 * listnode to insert after
110 *
111 * data
112 * data to insert
113 *
114 * Returns:
115 * pointer to newly created listnode that contains the inserted data
116 */
117 extern struct listnode *listnode_add_after(struct list *list,
118 struct listnode *pp, void *data);
119
120 /*
121 * Insert a new element into a list before another element.
122 *
123 * Runtime is O(1).
124 *
125 * list
126 * list to operate on
127 *
128 * pp
129 * listnode to insert before
130 *
131 * data
132 * data to insert
133 *
134 * Returns:
135 * pointer to newly created listnode that contains the inserted data
136 */
137 extern struct listnode *listnode_add_before(struct list *list,
138 struct listnode *pp, void *data);
139
140 /*
141 * Move a node to the tail of a list.
142 *
143 * Runtime is O(1).
144 *
145 * list
146 * list to operate on
147 *
148 * node
149 * node to move to tail
150 */
151 extern void listnode_move_to_tail(struct list *list, struct listnode *node);
152
153 /*
154 * Delete an element from a list.
155 *
156 * Runtime is O(N).
157 *
158 * list
159 * list to operate on
160 *
161 * data
162 * data to insert into list
163 */
164 extern void listnode_delete(struct list *list, void *data);
165
166 /*
167 * Find the listnode corresponding to an element in a list.
168 *
169 * list
170 * list to operate on
171 *
172 * data
173 * data to search for
174 *
175 * Returns:
176 * pointer to listnode storing the given data if found, NULL otherwise
177 */
178 extern struct listnode *listnode_lookup(struct list *list, void *data);
179
180 /*
181 * Retrieve the element at the head of a list.
182 *
183 * list
184 * list to operate on
185 *
186 * Returns:
187 * data at head of list, or NULL if list is empty
188 */
189 extern void *listnode_head(struct list *list);
190
191 /*
192 * Duplicate a list.
193 *
194 * list
195 * list to duplicate
196 *
197 * Returns:
198 * copy of the list
199 */
200 extern struct list *list_dup(struct list *l);
201
202 /*
203 * Sort a list in place.
204 *
205 * The sorting algorithm used is quicksort. Runtimes are equivalent to those of
206 * quicksort plus N. The sort is not stable.
207 *
208 * For portability reasons, the comparison function takes a pointer to pointer
209 * to void. This pointer should be dereferenced to get the actual data pointer.
210 * It is always safe to do this.
211 *
212 * list
213 * list to sort
214 *
215 * cmp
216 * comparison function for quicksort. Should return less than, equal to or
217 * greater than zero if the first argument is less than, equal to or greater
218 * than the second argument.
219 */
220 extern void list_sort(struct list *list,
221 int (*cmp)(const void **, const void **));
222
223 /*
224 * The usage of list_delete is being transitioned to pass in
225 * the double pointer to remove use after free's.
226 * list_free usage is deprecated, it leads to memory leaks
227 * of the linklist nodes. Please use list_delete_and_null
228 *
229 * In Oct of 2018, rename list_delete_and_null to list_delete
230 * and remove list_delete_original and the list_delete #define
231 * Additionally remove list_free entirely
232 */
233 #if defined(VERSION_TYPE_DEV) && CONFDATE > 20181001
234 CPP_NOTICE("list_delete without double pointer is deprecated, please fixup")
235 #endif
236
237 /*
238 * Delete a list and NULL its pointer.
239 *
240 * If non-null, list->del is called with each data element.
241 *
242 * plist
243 * pointer to list pointer; this will be set to NULL after the list has been
244 * deleted
245 */
246 extern void list_delete_and_null(struct list **plist);
247
248 /*
249 * Delete a list.
250 *
251 * If non-null, list->del is called with each data element.
252 *
253 * plist
254 * pointer to list pointer
255 */
256 extern void list_delete_original(struct list *list);
257 #define list_delete(X) \
258 list_delete_original((X)) \
259 CPP_WARN("Please transition to using list_delete_and_null")
260 #define list_free(X) \
261 list_delete_original((X)) \
262 CPP_WARN("Please transition tousing list_delete_and_null")
263
264 /*
265 * Delete all nodes from a list without deleting the list itself.
266 *
267 * If non-null, list->del is called with each data element.
268 *
269 * list
270 * list to operate on
271 */
272 extern void list_delete_all_node(struct list *list);
273
274 /*
275 * Delete a node from a list.
276 *
277 * list->del is not called with the data associated with the node.
278 *
279 * Runtime is O(1).
280 *
281 * list
282 * list to operate on
283 *
284 * node
285 * the node to delete
286 */
287 extern void list_delete_node(struct list *list, struct listnode *node);
288
289 /*
290 * Append a list to an existing list.
291 *
292 * Runtime is O(N) where N = listcount(add).
293 *
294 * list
295 * list to append to
296 *
297 * add
298 * list to append
299 */
300 extern void list_add_list(struct list *list, struct list *add);
301
302 /* List iteration macro.
303 * Usage: for (ALL_LIST_ELEMENTS (...) { ... }
304 * It is safe to delete the listnode using this macro.
305 */
306 #define ALL_LIST_ELEMENTS(list, node, nextnode, data) \
307 (node) = listhead(list), ((data) = NULL); \
308 (node) != NULL \
309 && ((data) = listgetdata(node), (nextnode) = node->next, 1); \
310 (node) = (nextnode), ((data) = NULL)
311
312 /* read-only list iteration macro.
313 * Usage: as per ALL_LIST_ELEMENTS, but not safe to delete the listnode Only
314 * use this macro when it is *immediately obvious* the listnode is not
315 * deleted in the body of the loop. Does not have forward-reference overhead
316 * of previous macro.
317 */
318 #define ALL_LIST_ELEMENTS_RO(list, node, data) \
319 (node) = listhead(list), ((data) = NULL); \
320 (node) != NULL && ((data) = listgetdata(node), 1); \
321 (node) = listnextnode(node), ((data) = NULL)
322
323 /* these *do not* cleanup list nodes and referenced data, as the functions
324 * do - these macros simply {de,at}tach a listnode from/to a list.
325 */
326
327 /* List node attach macro. */
328 #define LISTNODE_ATTACH(L, N) \
329 do { \
330 (N)->prev = (L)->tail; \
331 (N)->next = NULL; \
332 if ((L)->head == NULL) \
333 (L)->head = (N); \
334 else \
335 (L)->tail->next = (N); \
336 (L)->tail = (N); \
337 (L)->count++; \
338 } while (0)
339
340 /* List node detach macro. */
341 #define LISTNODE_DETACH(L, N) \
342 do { \
343 if ((N)->prev) \
344 (N)->prev->next = (N)->next; \
345 else \
346 (L)->head = (N)->next; \
347 if ((N)->next) \
348 (N)->next->prev = (N)->prev; \
349 else \
350 (L)->tail = (N)->prev; \
351 (L)->count--; \
352 } while (0)
353
354 #endif /* _ZEBRA_LINKLIST_H */