1 #ifndef LLIST_H
2 #define LLIST_H
3 
4 /* Doubly linked list */
5 #define DLLIST_PREPEND_FULL(list, item, prev, next) STMT_START { \
6 	(item)->prev = NULL; \
7 	(item)->next = *(list); \
8 	if (*(list) != NULL) (*(list))->prev = (item); \
9 	*(list) = (item); \
10 	} STMT_END
11 
12 #define DLLIST_PREPEND(list, item) \
13 	DLLIST_PREPEND_FULL(list, item, prev, next)
14 
15 #define DLLIST_REMOVE_FULL(list, item, prev, next) STMT_START { \
16 	if ((item)->prev != NULL) \
17 		(item)->prev->next = (item)->next; \
18 	else if ((*list) == item) \
19 		*(list) = (item)->next; \
20 	if ((item)->next != NULL) { \
21 		(item)->next->prev = (item)->prev; \
22 		(item)->next = NULL; \
23 	} \
24 	(item)->prev = NULL; \
25 	} STMT_END
26 
27 #define DLLIST_REMOVE(list, item) \
28 	DLLIST_REMOVE_FULL(list, item, prev, next)
29 
30 /* Doubly linked list with head and tail */
31 #define DLLIST2_PREPEND_FULL(head, tail, item, prev, next) STMT_START { \
32 	(item)->prev = NULL; \
33 	(item)->next = *(head); \
34 	if (*(head) != NULL) (*(head))->prev = (item); else (*tail) = (item); \
35 	*(head) = (item); \
36 	} STMT_END
37 
38 #define DLLIST2_PREPEND(head, tail, item) \
39 	DLLIST2_PREPEND_FULL(head, tail, item, prev, next)
40 
41 #define DLLIST2_APPEND_FULL(head, tail, item, prev, next) STMT_START { \
42 	(item)->prev = *(tail); \
43 	(item)->next = NULL; \
44 	if (*(tail) != NULL) (*(tail))->next = (item); else (*head) = (item); \
45 	*(tail) = (item); \
46 	} STMT_END
47 
48 #define DLLIST2_APPEND(head, tail, item) \
49 	DLLIST2_APPEND_FULL(head, tail, item, prev, next)
50 
51 #define DLLIST2_INSERT_AFTER_FULL(head, tail, after, item, prev, next) \
52 	STMT_START { \
53 	(item)->prev = (after); \
54 	(item)->next = (after)->next; \
55 	if ((after)->next != NULL) \
56 		(after)->next->prev = (item); \
57 	(after)->next = (item); \
58 	if (*(tail) == (after)) \
59 		*(tail) = (item); \
60 	} STMT_END
61 
62 #define DLLIST2_INSERT_AFTER(head, tail, after, item) \
63 	DLLIST2_INSERT_AFTER_FULL(head, tail, after, item, prev, next)
64 
65 #define DLLIST2_REMOVE_FULL(head, tail, item, prev, next) STMT_START { \
66 	if ((item)->prev != NULL) \
67 		(item)->prev->next = (item)->next; \
68 	else if (*(head) == item) \
69 		*(head) = (item)->next; \
70 	if ((item)->next != NULL) { \
71 		(item)->next->prev = (item)->prev; \
72 		(item)->next = NULL; \
73 	} else if ((*tail) == item) \
74 		*(tail) = (item)->prev; \
75 	(item)->prev = NULL; \
76 	} STMT_END
77 
78 #define DLLIST2_REMOVE(head, tail, item) \
79 	DLLIST2_REMOVE_FULL(head, tail, item, prev, next)
80 
81 #endif
82