2 * netsniff-ng - the packet sniffing beast
3 * list.c - Doubly linked list implementation
4 * Copyright (C) 2011 Jiri Pirko <jpirko@redhat.com>
5 * Subject to the GPL, version 2.
14 struct list_item
*prev
;
15 struct list_item
*next
;
18 static inline void list_init(struct list_item
*head
)
24 static inline bool list_empty(struct list_item
*head
)
26 return head
->next
== head
;
29 static inline void __list_add(struct list_item
*new_node
,
30 struct list_item
*prev_node
,
31 struct list_item
*next_node
)
33 new_node
->prev
= prev_node
;
34 new_node
->next
= next_node
;
35 prev_node
->next
= new_node
;
36 next_node
->prev
= new_node
;
39 static inline void list_add(struct list_item
*head
, struct list_item
*node
)
41 __list_add(node
, head
, head
->next
);
44 static inline void list_add_tail(struct list_item
*head
, struct list_item
*node
)
46 __list_add(node
, head
->prev
, head
);
49 static inline void list_del(struct list_item
*node
)
51 node
->prev
->next
= node
->next
;
52 node
->next
->prev
= node
->prev
;
55 static inline void list_move_nodes(struct list_item
*dst_head
,
56 struct list_item
*src_head
)
58 if (list_empty(src_head
))
60 dst_head
->prev
->next
= src_head
->next
;
61 src_head
->next
->prev
= dst_head
->prev
;
62 dst_head
->prev
= src_head
->prev
;
63 src_head
->prev
->next
= dst_head
;
67 static inline struct list_item
*list_get_next_node(struct list_item
*head
,
68 struct list_item
*node
)
70 if (node
->next
== head
)
75 #define list_for_each_node(node, head) \
76 for (node = list_get_next_node(head, head); \
78 node = list_get_next_node(head, node))
80 #define in_struct_offset(struct_type, struct_member) \
81 ((size_t) (&((struct_type *) 0)->struct_member))
83 #define get_container(ptr, struct_type, struct_member) \
86 in_struct_offset(struct_type, struct_member)))
88 #define list_get_node_entry(node, struct_type, struct_member) \
89 get_container(node, struct_type, struct_member)
91 #define list_for_each_node_entry(entry, head, struct_member) \
92 for (entry = list_get_node_entry((head)->next, typeof(*entry), \
94 &entry->struct_member != (head); \
95 entry = list_get_node_entry(entry->struct_member.next, \
96 typeof(*entry), struct_member))
98 #define list_for_each_node_entry_continue_reverse(entry, head, struct_member) \
99 for (entry = list_get_node_entry(entry->struct_member.prev, \
100 typeof(*entry), struct_member); \
101 &entry->struct_member != (head); \
102 entry = list_get_node_entry(entry->struct_member.prev, \
103 typeof(*entry), struct_member))
105 #define list_for_each_node_entry_safe(entry, tmp, head, struct_member) \
106 for (entry = list_get_node_entry((head)->next, \
107 typeof(*entry), struct_member), \
108 tmp = list_get_node_entry(entry->struct_member.next, \
109 typeof(*entry), struct_member); \
110 &entry->struct_member != (head); \
112 tmp = list_get_node_entry(entry->struct_member.next, \
113 typeof(*entry), struct_member))
115 #define list_get_next_node_entry(head, entry, struct_member) ({ \
116 struct list_item *next = (entry ? &entry->struct_member : (head))->next;\
117 (next == (head)) ? NULL : list_get_node_entry(next, typeof(*entry), \