Skip to content

Commit 48f37dd

Browse files
committed
Import list.h from systemd
The file is taken from systemd[1]. Note: The inclusion of the macro header is removed. [1]: https://raw.githubusercontent.com/systemd/systemd/0d7f7c2fde377d9bf618d16aa230757f956f8191/src/basic/list.h
1 parent e9901db commit 48f37dd

File tree

1 file changed

+169
-0
lines changed

1 file changed

+169
-0
lines changed

src/list.h

Lines changed: 169 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,169 @@
1+
/* SPDX-License-Identifier: LGPL-2.1+ */
2+
#pragma once
3+
4+
/* The head of the linked list. Use this in the structure that shall
5+
* contain the head of the linked list */
6+
#define LIST_HEAD(t,name) \
7+
t *name
8+
9+
/* The pointers in the linked list's items. Use this in the item structure */
10+
#define LIST_FIELDS(t,name) \
11+
t *name##_next, *name##_prev
12+
13+
/* Initialize the list's head */
14+
#define LIST_HEAD_INIT(head) \
15+
do { \
16+
(head) = NULL; \
17+
} while (false)
18+
19+
/* Initialize a list item */
20+
#define LIST_INIT(name,item) \
21+
do { \
22+
typeof(*(item)) *_item = (item); \
23+
assert(_item); \
24+
_item->name##_prev = _item->name##_next = NULL; \
25+
} while (false)
26+
27+
/* Prepend an item to the list */
28+
#define LIST_PREPEND(name,head,item) \
29+
do { \
30+
typeof(*(head)) **_head = &(head), *_item = (item); \
31+
assert(_item); \
32+
if ((_item->name##_next = *_head)) \
33+
_item->name##_next->name##_prev = _item; \
34+
_item->name##_prev = NULL; \
35+
*_head = _item; \
36+
} while (false)
37+
38+
/* Append an item to the list */
39+
#define LIST_APPEND(name,head,item) \
40+
do { \
41+
typeof(*(head)) **_hhead = &(head), *_tail; \
42+
LIST_FIND_TAIL(name, *_hhead, _tail); \
43+
LIST_INSERT_AFTER(name, *_hhead, _tail, item); \
44+
} while (false)
45+
46+
/* Remove an item from the list */
47+
#define LIST_REMOVE(name,head,item) \
48+
do { \
49+
typeof(*(head)) **_head = &(head), *_item = (item); \
50+
assert(_item); \
51+
if (_item->name##_next) \
52+
_item->name##_next->name##_prev = _item->name##_prev; \
53+
if (_item->name##_prev) \
54+
_item->name##_prev->name##_next = _item->name##_next; \
55+
else { \
56+
assert(*_head == _item); \
57+
*_head = _item->name##_next; \
58+
} \
59+
_item->name##_next = _item->name##_prev = NULL; \
60+
} while (false)
61+
62+
/* Find the head of the list */
63+
#define LIST_FIND_HEAD(name,item,head) \
64+
do { \
65+
typeof(*(item)) *_item = (item); \
66+
if (!_item) \
67+
(head) = NULL; \
68+
else { \
69+
while (_item->name##_prev) \
70+
_item = _item->name##_prev; \
71+
(head) = _item; \
72+
} \
73+
} while (false)
74+
75+
/* Find the tail of the list */
76+
#define LIST_FIND_TAIL(name,item,tail) \
77+
do { \
78+
typeof(*(item)) *_item = (item); \
79+
if (!_item) \
80+
(tail) = NULL; \
81+
else { \
82+
while (_item->name##_next) \
83+
_item = _item->name##_next; \
84+
(tail) = _item; \
85+
} \
86+
} while (false)
87+
88+
/* Insert an item after another one (a = where, b = what) */
89+
#define LIST_INSERT_AFTER(name,head,a,b) \
90+
do { \
91+
typeof(*(head)) **_head = &(head), *_a = (a), *_b = (b); \
92+
assert(_b); \
93+
if (!_a) { \
94+
if ((_b->name##_next = *_head)) \
95+
_b->name##_next->name##_prev = _b; \
96+
_b->name##_prev = NULL; \
97+
*_head = _b; \
98+
} else { \
99+
if ((_b->name##_next = _a->name##_next)) \
100+
_b->name##_next->name##_prev = _b; \
101+
_b->name##_prev = _a; \
102+
_a->name##_next = _b; \
103+
} \
104+
} while (false)
105+
106+
/* Insert an item before another one (a = where, b = what) */
107+
#define LIST_INSERT_BEFORE(name,head,a,b) \
108+
do { \
109+
typeof(*(head)) **_head = &(head), *_a = (a), *_b = (b); \
110+
assert(_b); \
111+
if (!_a) { \
112+
if (!*_head) { \
113+
_b->name##_next = NULL; \
114+
_b->name##_prev = NULL; \
115+
*_head = _b; \
116+
} else { \
117+
typeof(*(head)) *_tail = (head); \
118+
while (_tail->name##_next) \
119+
_tail = _tail->name##_next; \
120+
_b->name##_next = NULL; \
121+
_b->name##_prev = _tail; \
122+
_tail->name##_next = _b; \
123+
} \
124+
} else { \
125+
if ((_b->name##_prev = _a->name##_prev)) \
126+
_b->name##_prev->name##_next = _b; \
127+
else \
128+
*_head = _b; \
129+
_b->name##_next = _a; \
130+
_a->name##_prev = _b; \
131+
} \
132+
} while (false)
133+
134+
#define LIST_JUST_US(name,item) \
135+
(!(item)->name##_prev && !(item)->name##_next) \
136+
137+
#define LIST_FOREACH(name,i,head) \
138+
for ((i) = (head); (i); (i) = (i)->name##_next)
139+
140+
#define LIST_FOREACH_SAFE(name,i,n,head) \
141+
for ((i) = (head); (i) && (((n) = (i)->name##_next), 1); (i) = (n))
142+
143+
#define LIST_FOREACH_BEFORE(name,i,p) \
144+
for ((i) = (p)->name##_prev; (i); (i) = (i)->name##_prev)
145+
146+
#define LIST_FOREACH_AFTER(name,i,p) \
147+
for ((i) = (p)->name##_next; (i); (i) = (i)->name##_next)
148+
149+
/* Iterate through all the members of the list p is included in, but skip over p */
150+
#define LIST_FOREACH_OTHERS(name,i,p) \
151+
for (({ \
152+
(i) = (p); \
153+
while ((i) && (i)->name##_prev) \
154+
(i) = (i)->name##_prev; \
155+
if ((i) == (p)) \
156+
(i) = (p)->name##_next; \
157+
}); \
158+
(i); \
159+
(i) = (i)->name##_next == (p) ? (p)->name##_next : (i)->name##_next)
160+
161+
/* Loop starting from p->next until p->prev.
162+
p can be adjusted meanwhile. */
163+
#define LIST_LOOP_BUT_ONE(name,i,head,p) \
164+
for ((i) = (p)->name##_next ? (p)->name##_next : (head); \
165+
(i) != (p); \
166+
(i) = (i)->name##_next ? (i)->name##_next : (head))
167+
168+
#define LIST_IS_EMPTY(head) \
169+
(!(head))

0 commit comments

Comments
 (0)