]> git.ipfire.org Git - people/ms/systemd.git/blob - list.h
manager: fix GC algorithm
[people/ms/systemd.git] / list.h
1 /*-*- Mode: C; c-basic-offset: 8 -*-*/
2
3 #ifndef foolisthfoo
4 #define foolisthfoo
5
6 /***
7 This file is part of systemd.
8
9 Copyright 2010 Lennart Poettering
10
11 systemd is free software; you can redistribute it and/or modify it
12 under the terms of the GNU General Public License as published by
13 the Free Software Foundation; either version 2 of the License, or
14 (at your option) any later version.
15
16 systemd is distributed in the hope that it will be useful, but
17 WITHOUT ANY WARRANTY; without even the implied warranty of
18 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
19 General Public License for more details.
20
21 You should have received a copy of the GNU General Public License
22 along with systemd; If not, see <http://www.gnu.org/licenses/>.
23 ***/
24
25 /* The head of the linked list. Use this in the structure that shall
26 * contain the head of the linked list */
27 #define LIST_HEAD(t,name) \
28 t *name
29
30 /* The pointers in the linked list's items. Use this in the item structure */
31 #define LIST_FIELDS(t,name) \
32 t *name##_next, *name##_prev
33
34 /* Initialize the list's head */
35 #define LIST_HEAD_INIT(t,head) \
36 do { \
37 (head) = NULL; } \
38 while(false)
39
40 /* Initialize a list item */
41 #define LIST_INIT(t,name,item) \
42 do { \
43 t *_item = (item); \
44 assert(_item); \
45 _item->name##_prev = _item->name##_next = NULL; \
46 } while(false)
47
48 /* Prepend an item to the list */
49 #define LIST_PREPEND(t,name,head,item) \
50 do { \
51 t **_head = &(head), *_item = (item); \
52 assert(_item); \
53 if ((_item->name##_next = *_head)) \
54 _item->name##_next->name##_prev = _item; \
55 _item->name##_prev = NULL; \
56 *_head = _item; \
57 } while(false)
58
59 /* Remove an item from the list */
60 #define LIST_REMOVE(t,name,head,item) \
61 do { \
62 t **_head = &(head), *_item = (item); \
63 assert(_item); \
64 if (_item->name##_next) \
65 _item->name##_next->name##_prev = _item->name##_prev; \
66 if (_item->name##_prev) \
67 _item->name##_prev->name##_next = _item->name##_next; \
68 else { \
69 assert(*_head == _item); \
70 *_head = _item->name##_next; \
71 } \
72 _item->name##_next = _item->name##_prev = NULL; \
73 } while(false)
74
75 /* Find the head of the list */
76 #define LIST_FIND_HEAD(t,name,item,head) \
77 do { \
78 t *_item = (item); \
79 assert(_item); \
80 while ((_item->name##_prev) \
81 _item = _item->name##_prev; \
82 (head) = _item; \
83 } while (false)
84
85 /* Find the head of the list */
86 #define LIST_FIND_TAIL(t,name,item,tail) \
87 do { \
88 t *_item = (item); \
89 assert(_item); \
90 while (_item->name##_next) \
91 _item = _item->name##_next; \
92 (tail) = _item; \
93 } while (false)
94
95 /* Insert an item after another one (a = where, b = what) */
96 #define LIST_INSERT_AFTER(t,name,head,a,b) \
97 do { \
98 t **_head = &(head), *_a = (a), *_b = (b); \
99 assert(_b); \
100 if (!_a) { \
101 if ((_b->name##_next = *_head)) \
102 _b->name##_next->name##_prev = _b; \
103 _b->name##_prev = NULL; \
104 *_head = _b; \
105 } else { \
106 if ((_b->name##_next = _a->name##_next)) \
107 _b->name##_next->name##_prev = _b; \
108 _b->name##_prev = _a; \
109 _a->name##_next = _b; \
110 } \
111 } while(false)
112
113 #define LIST_FOREACH(name,i,head) \
114 for ((i) = (head); (i); (i) = (i)->name##_next)
115
116 #define LIST_FOREACH_SAFE(name,i,n,head) \
117 for ((i) = (head); (i) && (((n) = (i)->name##_next), 1); (i) = (n))
118
119 #endif