1 /*
2 * Copyright (C) 2004 Dizzy
3 *
4 * This program is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU General Public License
6 * as published by the Free Software Foundation; either version 2
7 * of the License, or (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
17 */
18 #ifndef INCLUDED_ELIST_TYPES
19 #define INCLUDED_ELIST_TYPES
20
21 typedef struct elist_struct {
22 struct elist_struct *next, *prev;
23 } t_elist;
24
25 /* hlist are single linked elists */
26 typedef struct hlist_struct {
27 struct hlist_struct *next;
28 } t_hlist;
29
30 #endif /* INCLUDED_ELIST_TYPES */
31
32 #ifndef INCLUDED_ELIST_PROTOS
33 #define INCLUDED_ELIST_PROTOS
34
35 #ifdef HAVE_STDDEF_H
36 # include <stddef.h>
37 #endif
38
39 /* access to it's members */
40 #define elist_next(ptr) ((ptr)->next)
41 #define elist_prev(ptr) ((ptr)->prev)
42
43 #define __elist_init(elist,val) { (elist)->next = (elist)->prev = (val); }
44 #define elist_init(elist) __elist_init(elist,elist)
45 #define DECLARE_ELIST_INIT(var) \
46 t_elist var = { &var, &var };
47
48 /* link an new node just after "where" */
elist_add(t_elist * where,t_elist * what)49 static inline void elist_add(t_elist *where, t_elist *what)
50 {
51 what->next = where->next;
52 where->next->prev = what;
53 what->prev = where;
54 where->next = what;
55 }
56
57 /* link a new node just before "where" (usefull in creating queues) */
elist_add_tail(t_elist * where,t_elist * what)58 static inline void elist_add_tail(t_elist *where, t_elist *what)
59 {
60 what->prev = where->prev;
61 where->prev->next = what;
62 what->next = where;
63 where->prev = what;
64 }
65
66 /* unlink "what" from it's list */
elist_del(t_elist * what)67 static inline void elist_del(t_elist *what)
68 {
69 what->next->prev = what->prev;
70 what->prev->next = what->next;
71 }
72
73 /* finds out the container address by computing it from the list node
74 * address substracting the offset inside the container of the list node
75 * member */
76 #define elist_entry(ptr,type,member) ((type*)(((char*)ptr)-offsetof(type,member)))
77
78 /* DONT remove while traversing with this ! */
79 #define elist_for_each(pos,head) \
80 for (pos = (head)->next; pos != (head); pos = pos->next)
81
82 #define elist_for_each_rev(pos,head) \
83 for (pos = (head)->prev; pos != (head); pos = pos->prev)
84
85 /* safe for removals while traversing */
86 #define elist_for_each_safe(pos,head,save) \
87 for (pos = (head)->next, save = pos->next; pos != (head); \
88 pos = save, save = pos->next)
89
90 #define elist_for_each_safe_rev(pos,head,save) \
91 for (pos = (head)->prev, save = pos->prev; pos != (head); \
92 pos = save, save = pos->prev)
93
94 #define elist_empty(ptr) ((ptr)->next == (ptr))
95
96 #define hlist_next(ptr) elist_next(ptr)
97
98 #define __hlist_init(hlist,val) { (hlist)->next = (val); }
99 #define hlist_init(hlist) __hlist_init(hlist,hlist)
100 #define DECLARE_HLIST_INIT(var) \
101 t_hlist var = { &var };
102
103 /* link an new node just after "where" */
hlist_add(t_hlist * where,t_hlist * what)104 static inline void hlist_add(t_hlist *where, t_hlist *what)
105 {
106 what->next = where->next;
107 where->next = what;
108 }
109
110 /* unlink "what" from it's list, prev->next = what */
hlist_del(t_hlist * what,t_hlist * prev)111 static inline void hlist_del(t_hlist *what, t_hlist *prev)
112 {
113 prev->next = what->next;
114 }
115
116 /* move "what" back in the list with one position, never NULL
117 * prev: the previous element in the list, never NULL
118 * prev2: the previous element of "prev", if NULL means "what" is first
119 */
hlist_promote(t_hlist * what,t_hlist * prev,t_hlist * prev2)120 static inline void hlist_promote(t_hlist *what, t_hlist *prev, t_hlist *prev2)
121 {
122 if (prev2) {
123 prev->next = what->next;
124 prev2->next = what;
125 what->next = prev;
126 }
127 }
128
129 /* finds out the container address by computing it from the list node
130 * address substracting the offset inside the container of the list node
131 * member */
132 #define hlist_entry(ptr,type,member) elist_entry(ptr,type,member)
133
134 /* DONT remove while traversing with this ! */
135 #define hlist_for_each(pos,head) elist_for_each(pos,head)
136
137 /* safe for removals while traversing */
138 #define hlist_for_each_safe(pos,head,save) elist_for_each_safe(pos,head,save)
139
140 #define hlist_empty(ptr) elist_empty(ptr)
141
142 #endif /* INCLUDED_ELIST_PROTOS */
143