~ubuntu-branches/ubuntu/feisty/elinks/feisty-updates

« back to all changes in this revision

Viewing changes to src/util/lists.h

  • Committer: Bazaar Package Importer
  • Author(s): Peter Gervai
  • Date: 2004-01-21 22:13:45 UTC
  • Revision ID: james.westby@ubuntu.com-20040121221345-ju33hai1yhhqt6kn
Tags: upstream-0.9.1
ImportĀ upstreamĀ versionĀ 0.9.1

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* $Id: lists.h,v 1.37 2003/12/21 14:56:56 zas Exp $ */
 
2
 
 
3
#ifndef EL__UTIL_LISTS_H
 
4
#define EL__UTIL_LISTS_H
 
5
 
 
6
#include "util/error.h" /* do_not_optimize_here() */
 
7
 
 
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). */
 
11
 
 
12
/* Lists debugging
 
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. */
 
16
#ifdef DEBUG
 
17
#define LISTDEBUG
 
18
#endif
 
19
 
 
20
 
 
21
/* Fix namespace clash with system headers (like FreeBSD's, all hail BSD!). */
 
22
#undef LIST_HEAD
 
23
#undef list_head
 
24
#define list_head list_head_elinks
 
25
 
 
26
 
 
27
#ifndef LISTDEBUG
 
28
 
 
29
#define list_del_enforce(x) /* better don't */
 
30
 
 
31
#define list_magic_error(where, what) /* no magic */
 
32
 
 
33
#define list_magic_set(x) /* no magic */
 
34
 
 
35
#define list_magic_correct(x) (1)
 
36
#define list_magic_check(x, where) /* no magic */
 
37
#define list_magic_chkbool(x, where) (1)
 
38
 
 
39
struct list_head {
 
40
        void *next;
 
41
        void *prev;
 
42
};
 
43
 
 
44
struct xlist_head {
 
45
        struct xlist_head *next;
 
46
        struct xlist_head *prev;
 
47
};
 
48
 
 
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))
 
54
 
 
55
 
 
56
#else /* LISTDEBUG */
 
57
 
 
58
#define LISTMAGIC1 ((void *) 0xdadababa)
 
59
#define LISTMAGIC2 ((void *) 0xd0d0b0b0)
 
60
#define LISTMAGIC3 ((void *) 0x25254545)
 
61
 
 
62
#define list_del_enforce(x) \
 
63
do { \
 
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__); \
 
68
} while (0)
 
69
 
 
70
 
 
71
#define list_magic_error(where,what) INTERNAL("[%s] %s - bad list magic", where, #what)
 
72
 
 
73
 
 
74
#define list_magic_set(x) \
 
75
do { \
 
76
        (x).magic1 = LISTMAGIC1; \
 
77
        (x).magic2 = LISTMAGIC2; \
 
78
} while (0)
 
79
 
 
80
 
 
81
/* Backend for list_magic_check() and list_magic_chkbool(). */
 
82
#define list_magic_correct(x) ((x).magic1 == LISTMAGIC1 && (x).magic2 == LISTMAGIC2)
 
83
 
 
84
#define list_magic_check(x, where) \
 
85
do { \
 
86
        if (!list_magic_correct(*(x))) \
 
87
                list_magic_error(where, x); \
 
88
} while (0)
 
89
 
 
90
#define list_magic_chkbool(x, where) (list_magic_correct(x) || (list_magic_error(where, x), 1))
 
91
 
 
92
 
 
93
struct list_head {
 
94
        void *magic1;
 
95
        void *next;
 
96
        void *prev;
 
97
        void *magic2;
 
98
};
 
99
 
 
100
struct xlist_head {
 
101
        void *magic1;
 
102
        struct xlist_head *next;
 
103
        struct xlist_head *prev;
 
104
        void *magic2;
 
105
};
 
106
 
 
107
 
 
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))
 
113
 
 
114
#endif /* LISTDEBUG */
 
115
 
 
116
 
 
117
#define init_list(x) \
 
118
do { \
 
119
        list_magic_set(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)); \
 
123
} while (0)
 
124
 
 
125
 
 
126
#define list_empty(x) (list_magic_chkbool(x, "list_empty") && (x).next == &(x))
 
127
 
 
128
#define del_from_list(x) \
 
129
do { \
 
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); \
 
136
} while (0)
 
137
 
 
138
#define add_at_pos(p,x) \
 
139
do { \
 
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; \
 
144
        (x)->prev = (p); \
 
145
        (p)->next = (x); \
 
146
        (x)->next->prev = (x); \
 
147
        do_not_optimize_here_gcc_2_7(p); \
 
148
} while (0)
 
149
 
 
150
 
 
151
#ifdef HAVE_TYPEOF
 
152
 
 
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))
 
155
 
 
156
#define foreach(e,l) \
 
157
        for ((e) = (l).next; \
 
158
             (e) != (typeof(e)) &(l); \
 
159
             (e) = (e)->next)
 
160
 
 
161
#define foreachback(e,l) \
 
162
        for ((e) = (l).prev; \
 
163
             (e) != (typeof(e)) &(l); \
 
164
             (e) = (e)->prev)
 
165
 
 
166
#else
 
167
 
 
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))
 
172
 
 
173
#define foreach(e,l) \
 
174
        for ((e) = (l).next;\
 
175
             (e) != (void *) &(l);\
 
176
             (e) = (e)->next)
 
177
 
 
178
#define foreachback(e,l) \
 
179
        for ((e) = (l).prev; \
 
180
             (e) != (void *) &(l); \
 
181
             (e) = (e)->prev)
 
182
 
 
183
#endif /* HAVE_TYPEOF */
 
184
 
 
185
 
 
186
#define free_list(l) \
 
187
do { \
 
188
        struct xlist_head *head; \
 
189
\
 
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)) { \
 
195
                head = (l).next; \
 
196
                del_from_list(head); \
 
197
                mem_free(head); \
 
198
        } \
 
199
        do_not_optimize_here_gcc_2_7(&l); \
 
200
} while (0)
 
201
 
 
202
 
 
203
#endif /* EL__UTIL_LISTS_H */