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