]> git.ipfire.org Git - thirdparty/systemd.git/blob - list.h
when shortcutting states do not skip state transitions
[thirdparty/systemd.git] / list.h
1 /*-*- Mode: C; c-basic-offset: 8 -*-*/
2
3 #ifndef foolisthfoo
4 #define foolisthfoo
5
6 /* The head of the linked list. Use this in the structure that shall
7 * contain the head of the linked list */
8 #define LIST_HEAD(t,name) \
9 t *name
10
11 /* The pointers in the linked list's items. Use this in the item structure */
12 #define LIST_FIELDS(t,name) \
13 t *name##_next, *name##_prev
14
15 /* Initialize the list's head */
16 #define LIST_HEAD_INIT(t,head) \
17 do { \
18 (head) = NULL; } \
19 while(false)
20
21 /* Initialize a list item */
22 #define LIST_INIT(t,name,item) \
23 do { \
24 t *_item = (item); \
25 assert(_item); \
26 _item->name##_prev = _item->name##_next = NULL; \
27 } while(false)
28
29 /* Prepend an item to the list */
30 #define LIST_PREPEND(t,name,head,item) \
31 do { \
32 t **_head = &(head), *_item = (item); \
33 assert(_item); \
34 if ((_item->name##_next = *_head)) \
35 _item->name##_next->name##_prev = _item; \
36 _item->name##_prev = NULL; \
37 *_head = _item; \
38 } while(false)
39
40 /* Remove an item from the list */
41 #define LIST_REMOVE(t,name,head,item) \
42 do { \
43 t **_head = &(head), *_item = (item); \
44 assert(_item); \
45 if (_item->name##_next) \
46 _item->name##_next->name##_prev = _item->name##_prev; \
47 if (_item->name##_prev) \
48 _item->name##_prev->name##_next = _item->name##_next; \
49 else { \
50 assert(*_head == _item); \
51 *_head = _item->name##_next; \
52 } \
53 _item->name##_next = _item->name##_prev = NULL; \
54 } while(false)
55
56 /* Find the head of the list */
57 #define LIST_FIND_HEAD(t,name,item,head) \
58 do { \
59 t *_item = (item); \
60 assert(_item); \
61 while ((_item->name##_prev) \
62 _item = _item->name##_prev; \
63 (head) = _item; \
64 } while (false)
65
66 /* Find the head of the list */
67 #define LIST_FIND_TAIL(t,name,item,tail) \
68 do { \
69 t *_item = (item); \
70 assert(_item); \
71 while (_item->name##_next) \
72 _item = _item->name##_next; \
73 (tail) = _item; \
74 } while (false)
75
76 /* Insert an item after another one (a = where, b = what) */
77 #define LIST_INSERT_AFTER(t,name,head,a,b) \
78 do { \
79 t **_head = &(head), *_a = (a), *_b = (b); \
80 assert(_b); \
81 if (!_a) { \
82 if ((_b->name##_next = *_head)) \
83 _b->name##_next->name##_prev = _b; \
84 _b->name##_prev = NULL; \
85 *_head = _b; \
86 } else { \
87 if ((_b->name##_next = _a->name##_next)) \
88 _b->name##_next->name##_prev = _b; \
89 _b->name##_prev = _a; \
90 _a->name##_next = _b; \
91 } \
92 } while(false)
93
94 #define LIST_FOREACH(name,i,head) \
95 for ((i) = (head); (i); (i) = (i)->name##_next)
96
97 #define LIST_FOREACH_SAFE(name,i,n,head) \
98 for ((i) = (head); (i) && (((n) = (i)->name##_next), 1); (i) = (n))
99
100 #endif