proto_80211_mac_hdr.c: complete tclas element
[netsniff-ng.git] / src / list.h
blobbda62b4b67d214f5291537ad0d4122b74e0e119f
1 /*
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.
6 */
8 #ifndef LIST_H
9 #define LIST_H
11 #include <stdbool.h>
13 struct list_item {
14 struct list_item *prev;
15 struct list_item *next;
18 static inline void list_init(struct list_item *head)
20 head->prev = head;
21 head->next = 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))
59 return;
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;
64 list_init(src_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)
71 return NULL;
72 return node->next;
75 #define list_for_each_node(node, head) \
76 for (node = list_get_next_node(head, head); \
77 node; \
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) \
84 ((struct_type *) ( \
85 ((size_t) ptr) - \
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), \
93 struct_member); \
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); \
111 entry = tmp, \
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), \
118 struct_member);})
120 #endif /* LIST_H */