chiark / gitweb /
add api for choose the id name for a service
[elogind.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