chiark / gitweb /
list: Fixing typo in LIST_FIND_HEAD
[elogind.git] / src / list.h
1 /*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
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