chiark / gitweb /
add minimal logging framework
[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)                                                  \
13     t *next, *prev
14
15 /* Initialize the list's head */
16 #define LIST_HEAD_INIT(t,item)                                          \
17         do {                                                            \
18                 (item) = (t*) NULL; }                                   \
19         while(false)
20
21 /* Initialize a list item */
22 #define LIST_INIT(t,item)                                               \
23         do {                                                            \
24                 t *_item = (item);                                      \
25                 assert(_item);                                          \
26                 _item->prev = _item->next = NULL;                       \
27         } while(false)
28
29 /* Prepend an item to the list */
30 #define LIST_PREPEND(t,head,item)                                       \
31         do {                                                            \
32                 t **_head = &(head), *_item = (item);                   \
33                 assert(_item);                                          \
34                 if ((_item->next = *_head))                             \
35                         _item->next->prev = _item;                      \
36                 _item->prev = NULL;                                     \
37                 *_head = _item;                                         \
38         } while(false)
39
40 /* Remove an item from the list */
41 #define LIST_REMOVE(t,head,item)                                        \
42         do {                                                            \
43                 t **_head = &(head), *_item = (item);                   \
44                 assert(_item);                                          \
45                 if (_item->next)                                        \
46                         _item->next->prev = _item->prev;                \
47                 if (_item->prev)                                        \
48                         _item->prev->next = _item->next;                \
49                 else {                                                  \
50                         assert(*_head == _item);                        \
51                         *_head = _item->next;                           \
52                 }                                                       \
53                 _item->next = _item->prev = NULL;                       \
54         } while(false)
55
56 /* Find the head of the list */
57 #define LIST_FIND_HEAD(t,item,head)                                     \
58         do {                                                            \
59                 t **_head = (head), *_item = (item);                    \
60                 *_head = _item;                                         \
61                 assert(_head);                                          \
62                 while ((*_head)->prev)                                  \
63                         *_head = (*_head)->prev;                        \
64         } while (false)
65
66 /* Insert an item after another one (a = where, b = what) */
67 #define LIST_INSERT_AFTER(t,head,a,b)                                   \
68         do {                                                            \
69                 t **_head = &(head), *_a = (a), *_b = (b);              \
70                 assert(_b);                                             \
71                 if (!_a) {                                              \
72                         if ((_b->next = *_head))                        \
73                                 _b->next->prev = _b;                    \
74                         _b->prev = NULL;                                \
75                         *_head = _b;                                    \
76                 } else {                                                \
77                         if ((_b->next = _a->next))                      \
78                                 _b->next->prev = _b;                    \
79                         _b->prev = _a;                                  \
80                         _a->next = _b;                                  \
81                 }                                                       \
82         } while(false)
83
84 #define LIST_FOREACH(i,head)                                            \
85         for (i = (head); i; i = i->next)
86
87 #define LIST_FOREACH_SAFE(i,n,head)                                     \
88         for (i = (head); i && ((n = i->next), 1); i = n)
89
90 #endif