6 static inline struct dlist_entry
*dlist_mkentry(void *data
) {
7 struct dlist_entry
*le
;
9 if ((le
= calloc(1, sizeof(*le
))))
15 struct dlist_entry
*dlist_create_entry(void *data
) {
16 return dlist_mkentry(data
);
19 struct dlist_entry
*dlist_insert(struct dlist_entry
*list
, void *data
)
21 struct dlist_entry
*le
;
23 if (!(le
= dlist_mkentry(data
)))
28 list
->dlist_prev
->dlist_next
= le
;
29 le
->dlist_prev
= list
->dlist_prev
;
30 le
->dlist_next
= list
;
31 list
->dlist_prev
= le
;
37 struct dlist_entry
*dlist_append(struct dlist_entry
*list
, void *data
)
39 struct dlist_entry
*le
;
42 return dlist_insert(list
, data
);
44 if (!(le
= dlist_mkentry(data
)))
49 list
->dlist_next
->dlist_prev
= le
;
50 le
->dlist_next
= list
->dlist_next
;
51 le
->dlist_prev
= list
;
52 list
->dlist_next
= le
;
58 void *dlist_remove(struct dlist_entry
**head
, struct dlist_entry
*entry
)
64 if (head
&& *head
== entry
) {
65 *head
= entry
->dlist_prev
? entry
->dlist_prev
: entry
->dlist_next
;
68 if (entry
->dlist_prev
)
69 entry
->dlist_prev
->dlist_next
= entry
->dlist_next
;
70 if (entry
->dlist_next
)
71 entry
->dlist_next
->dlist_prev
= entry
->dlist_prev
;
79 struct dlist_entry
*dlist_find(struct dlist_entry
*entry
, void *data
, int (*cmp
)(void *, void *, size_t), size_t size
) {
80 struct dlist_entry
*it
;
85 /* search forwards... */
86 dlist_foreach(entry
, it
) {
89 if (it
->data
&& data
&& !cmp(it
->data
, data
, size
))
93 /* ... and backwards */
94 dlist_foreach(entry
->dlist_prev
, it
) {
97 if (it
->data
&& data
&& !cmp(it
->data
, data
, size
))
104 struct dlist_entry
*dlist_insert_unique(struct dlist_entry
*list
, void *data
, int (*cmp
)(void *, void *, size_t), size_t size
)
106 if (dlist_find(list
, data
, cmp
, size
))
108 return dlist_insert(list
, data
);
111 struct dlist_entry
*dlist_append_unique(struct dlist_entry
*list
, void *data
, int (*cmp
)(void *, void *, size_t), size_t size
)
113 if (dlist_find(list
, data
, cmp
, size
))
115 return dlist_append(list
, data
);
118 void dlist_destroy_entry(struct dlist_entry
**head
, struct dlist_entry
*entry
, void (*destructor
)(void *))
125 data
= dlist_remove(head
, entry
);
126 if (data
&& destructor
)
130 void dlist_destroy_list(struct dlist_entry
**list
, void (*destructor
)(void *))
132 struct dlist_entry
*cur
, *next
;
138 * Hoisting the if makes this more efficient. I guess gcc
139 * optimizes poorly in the first pass due to conditionals
140 * in the _safe macros :-/
143 dlist_foreach_safe((*list
)->dlist_next
, cur
, next
)
145 dlist_foreach_safe_reverse(*list
, cur
, next
)
150 dlist_foreach_safe((*list
)->dlist_next
, cur
, next
) {
151 destructor(cur
->data
);
154 dlist_foreach_safe_reverse(*list
, cur
, next
) {
155 destructor(cur
->data
);