]>
Commit | Line | Data |
---|---|---|
60918275 LP |
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) \ | |
034c6ed7 | 9 | t *name |
60918275 LP |
10 | |
11 | /* The pointers in the linked list's items. Use this in the item structure */ | |
034c6ed7 LP |
12 | #define LIST_FIELDS(t,name) \ |
13 | t *name##_next, *name##_prev | |
60918275 LP |
14 | |
15 | /* Initialize the list's head */ | |
034c6ed7 | 16 | #define LIST_HEAD_INIT(t,head) \ |
60918275 | 17 | do { \ |
034c6ed7 | 18 | (head) = NULL; } \ |
60918275 LP |
19 | while(false) |
20 | ||
21 | /* Initialize a list item */ | |
034c6ed7 | 22 | #define LIST_INIT(t,name,item) \ |
60918275 LP |
23 | do { \ |
24 | t *_item = (item); \ | |
25 | assert(_item); \ | |
034c6ed7 | 26 | _item->name##_prev = _item->name##_next = NULL; \ |
60918275 LP |
27 | } while(false) |
28 | ||
29 | /* Prepend an item to the list */ | |
034c6ed7 | 30 | #define LIST_PREPEND(t,name,head,item) \ |
60918275 LP |
31 | do { \ |
32 | t **_head = &(head), *_item = (item); \ | |
33 | assert(_item); \ | |
034c6ed7 LP |
34 | if ((_item->name##_next = *_head)) \ |
35 | _item->name##_next->name##_prev = _item; \ | |
36 | _item->name##_prev = NULL; \ | |
60918275 LP |
37 | *_head = _item; \ |
38 | } while(false) | |
39 | ||
40 | /* Remove an item from the list */ | |
034c6ed7 | 41 | #define LIST_REMOVE(t,name,head,item) \ |
60918275 LP |
42 | do { \ |
43 | t **_head = &(head), *_item = (item); \ | |
44 | assert(_item); \ | |
034c6ed7 LP |
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; \ | |
60918275 LP |
49 | else { \ |
50 | assert(*_head == _item); \ | |
034c6ed7 | 51 | *_head = _item->name##_next; \ |
60918275 | 52 | } \ |
034c6ed7 | 53 | _item->name##_next = _item->name##_prev = NULL; \ |
60918275 LP |
54 | } while(false) |
55 | ||
56 | /* Find the head of the list */ | |
034c6ed7 | 57 | #define LIST_FIND_HEAD(t,name,item,head) \ |
60918275 | 58 | do { \ |
034c6ed7 LP |
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; \ | |
60918275 LP |
74 | } while (false) |
75 | ||
76 | /* Insert an item after another one (a = where, b = what) */ | |
034c6ed7 | 77 | #define LIST_INSERT_AFTER(t,name,head,a,b) \ |
60918275 LP |
78 | do { \ |
79 | t **_head = &(head), *_a = (a), *_b = (b); \ | |
80 | assert(_b); \ | |
81 | if (!_a) { \ | |
034c6ed7 LP |
82 | if ((_b->name##_next = *_head)) \ |
83 | _b->name##_next->name##_prev = _b; \ | |
84 | _b->name##_prev = NULL; \ | |
60918275 LP |
85 | *_head = _b; \ |
86 | } else { \ | |
034c6ed7 LP |
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; \ | |
60918275 LP |
91 | } \ |
92 | } while(false) | |
93 | ||
034c6ed7 LP |
94 | #define LIST_FOREACH(name,i,head) \ |
95 | for ((i) = (head); (i); (i) = (i)->name##_next) | |
60918275 | 96 | |
034c6ed7 LP |
97 | #define LIST_FOREACH_SAFE(name,i,n,head) \ |
98 | for ((i) = (head); (i) && (((n) = (i)->name##_next), 1); (i) = (n)) | |
60918275 LP |
99 | |
100 | #endif |