1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
|
#ifndef _LIST_H
# define _LIST_H
/**
Simple list handlig macros.
Needs rewrite or inclusion of /usr/include/linux/list.h as a replacement.
*/
/* Must be first if structure is going to use it. */
struct list_entry {
struct list_entry *le_next, *le_prev;
};
# define list_head() struct list_entry _list_head
# define le(p) (&((*p)._list_head))
# define list_insert(list, newnode) \
do { \
if (!(*list)) { \
le(newnode)->le_next = \
le(newnode)->le_prev = le(newnode); \
*list = (void *)le(newnode); \
} else { \
le(*list)->le_prev->le_next = le(newnode); \
le(newnode)->le_next = le(*list); \
le(newnode)->le_prev = le(*list)->le_prev; \
le(*list)->le_prev = le(newnode); \
} \
} while (0)
# define list_prepend(list, newnode) \
do { \
list_insert(list, newnode); \
*list = newnode; \
} while (0)
# define list_remove(list, oldnode) \
do { \
if (le(oldnode) == le(*list)) { \
*list = (void *)le(*list)->le_next; \
} \
if (le(oldnode) == le(*list)) { \
le(oldnode)->le_next = NULL; \
le(oldnode)->le_prev = NULL; \
*list = NULL; \
} else { \
le(oldnode)->le_next->le_prev = le(oldnode)->le_prev; \
le(oldnode)->le_prev->le_next = le(oldnode)->le_next; \
le(oldnode)->le_prev = NULL; \
le(oldnode)->le_next = NULL; \
} \
} while (0)
/*
list_do(list, node) {
stuff; // redefining "node" (as well as "list) unsafe!
// NOTE: running list_remove(list, node) possible, but you have to call
// "if (list && (node = (void *)le(*list)->le_next)) continue;"
// afterwards (after node-related resources cleanup if needed)
} while (!list_done(list, node));
*/
# define list_do(list, curr) \
if ((curr = *list)) do
# define list_done(list, curr) \
((curr = (void *)le(curr)->le_next) == *list)
/*
* list_for(list, tmp, counter) {
* stuff;
* }
*
* counter = # of items in list when done.
* * sets cnt to 0 before even checking list;
* * checks for valid list
* * traverses list, incrementing counter. If we get to the for loop,
* there must be at least one item in the list
*/
# define list_for(list, curr, cnt) \
if (!(cnt=0) && (list != NULL) && (*list != NULL)) \
for (curr = *list; \
(cnt == 0) || (curr != *list); \
curr = (void*)le(curr)->le_next, \
cnt++)
# define list_for_rev(list, curr, cnt) \
if (!(cnt=0) && list && *list) \
for (curr = (void *)(le(*list)->le_prev); \
(cnt == 0) || ((void *)curr != le(*list)->le_prev); \
curr = (void*)(le(curr)->le_prev), \
cnt++)
#endif
|