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