1
/* $Id: lists.h,v 1.37 2003/12/21 14:56:56 zas Exp $ */
3
#ifndef EL__UTIL_LISTS_H
4
#define EL__UTIL_LISTS_H
6
#include "util/error.h" /* do_not_optimize_here() */
8
/* BEWARE! You MAY NOT use ternary operator as parameter to there functions,
9
* because they are likely to take & of the parameter. Worst of all, it will
10
* work with gcc. But nowhere else (at least not w/ tcc). */
13
* Two unsigned int magic number will be put before and after the next and
14
* prev pointers, these will be check on list operations.
15
* Some pointers are set to specific values after action. */
21
/* Fix namespace clash with system headers (like FreeBSD's, all hail BSD!). */
24
#define list_head list_head_elinks
29
#define list_del_enforce(x) /* better don't */
31
#define list_magic_error(where, what) /* no magic */
33
#define list_magic_set(x) /* no magic */
35
#define list_magic_correct(x) (1)
36
#define list_magic_check(x, where) /* no magic */
37
#define list_magic_chkbool(x, where) (1)
45
struct xlist_head *next;
46
struct xlist_head *prev;
49
#define NULL_LIST_HEAD NULL, NULL
50
#define D_LIST_HEAD(x) &x, &x
51
#define INIT_LIST_HEAD(x) struct list_head x = { D_LIST_HEAD(x) }
52
#define LIST_HEAD(x) x *next; x *prev
53
#define LIST_SET_MAGIC(x) list_magic_set(*(x))
58
#define LISTMAGIC1 ((void *) 0xdadababa)
59
#define LISTMAGIC2 ((void *) 0xd0d0b0b0)
60
#define LISTMAGIC3 ((void *) 0x25254545)
62
#define list_del_enforce(x) \
64
/* Little hack: we put LISTMAGIC3 in prev */ \
65
/* and the line number in next. Debugging purpose. */ \
66
(x)->prev = LISTMAGIC3; \
67
(x)->next = (void *) ((unsigned int) __LINE__); \
71
#define list_magic_error(where,what) INTERNAL("[%s] %s - bad list magic", where, #what)
74
#define list_magic_set(x) \
76
(x).magic1 = LISTMAGIC1; \
77
(x).magic2 = LISTMAGIC2; \
81
/* Backend for list_magic_check() and list_magic_chkbool(). */
82
#define list_magic_correct(x) ((x).magic1 == LISTMAGIC1 && (x).magic2 == LISTMAGIC2)
84
#define list_magic_check(x, where) \
86
if (!list_magic_correct(*(x))) \
87
list_magic_error(where, x); \
90
#define list_magic_chkbool(x, where) (list_magic_correct(x) || (list_magic_error(where, x), 1))
102
struct xlist_head *next;
103
struct xlist_head *prev;
108
#define NULL_LIST_HEAD LISTMAGIC1, NULL, NULL, LISTMAGIC2
109
#define D_LIST_HEAD(x) LISTMAGIC1, &x, &x, LISTMAGIC2
110
#define INIT_LIST_HEAD(x) struct list_head x = { D_LIST_HEAD(x) }
111
#define LIST_HEAD(x) void *magic1; x *next; x *prev; void *magic2;
112
#define LIST_SET_MAGIC(x) list_magic_set(*(x))
114
#endif /* LISTDEBUG */
117
#define init_list(x) \
120
do_not_optimize_here_gcc_3_x(&(x)); /* antialiasing ;) */ \
121
(x).next = (x).prev = &(x); \
122
do_not_optimize_here_gcc_3_x(&(x)); \
126
#define list_empty(x) (list_magic_chkbool(x, "list_empty") && (x).next == &(x))
128
#define del_from_list(x) \
130
list_magic_check(x, "del_from_list"); \
131
do_not_optimize_here_gcc_2_7(x); \
132
((struct list_head *) (x)->next)->prev = (x)->prev; \
133
((struct list_head *) (x)->prev)->next = (x)->next; \
134
list_del_enforce(x); \
135
do_not_optimize_here_gcc_2_7(x); \
138
#define add_at_pos(p,x) \
140
list_magic_check(p, "add_at_pos"); \
141
list_magic_set(*(x)); \
142
do_not_optimize_here_gcc_2_7(p); \
143
(x)->next = (p)->next; \
146
(x)->next->prev = (x); \
147
do_not_optimize_here_gcc_2_7(p); \
153
#define add_to_list(l,x) add_at_pos((typeof(x)) &(l), (x))
154
#define add_to_list_end(l,x) add_at_pos((typeof(x)) (l).prev, (x))
156
#define foreach(e,l) \
157
for ((e) = (l).next; \
158
(e) != (typeof(e)) &(l); \
161
#define foreachback(e,l) \
162
for ((e) = (l).prev; \
163
(e) != (typeof(e)) &(l); \
168
#define add_to_list(l,x) \
169
add_at_pos((struct xlist_head *) &(l), (struct xlist_head *) (x))
170
#define add_to_list_end(l,x) \
171
add_at_pos((struct xlist_head *) (l).prev, (struct xlist_head *) (x))
173
#define foreach(e,l) \
174
for ((e) = (l).next;\
175
(e) != (void *) &(l);\
178
#define foreachback(e,l) \
179
for ((e) = (l).prev; \
180
(e) != (void *) &(l); \
183
#endif /* HAVE_TYPEOF */
186
#define free_list(l) \
188
struct xlist_head *head; \
190
list_magic_check(&(l), "free_list"); \
191
do_not_optimize_here_gcc_2_7(&l); \
192
foreach (head, (l)) do_not_optimize_here_gcc_3_x(head); /* AA */ \
193
foreachback (head, (l)) do_not_optimize_here_gcc_3_x(head); /* AA */ \
194
while ((l).next != &(l)) { \
196
del_from_list(head); \
199
do_not_optimize_here_gcc_2_7(&l); \
203
#endif /* EL__UTIL_LISTS_H */