[netdrvr gianfar] use new phy layer
[linux-2.6/libata-dev.git] / include / linux / netfilter_ipv4 / listhelp.h
blob360429f4873755e758018a6915a591aaa6338e84
1 #ifndef _LISTHELP_H
2 #define _LISTHELP_H
3 #include <linux/config.h>
4 #include <linux/list.h>
6 /* Header to do more comprehensive job than linux/list.h; assume list
7 is first entry in structure. */
9 /* Return pointer to first true entry, if any, or NULL. A macro
10 required to allow inlining of cmpfn. */
11 #define LIST_FIND(head, cmpfn, type, args...) \
12 ({ \
13 const struct list_head *__i, *__j = NULL; \
15 ASSERT_READ_LOCK(head); \
16 list_for_each(__i, (head)) \
17 if (cmpfn((const type)__i , ## args)) { \
18 __j = __i; \
19 break; \
20 } \
21 (type)__j; \
24 #define LIST_FIND_W(head, cmpfn, type, args...) \
25 ({ \
26 const struct list_head *__i, *__j = NULL; \
28 ASSERT_WRITE_LOCK(head); \
29 list_for_each(__i, (head)) \
30 if (cmpfn((type)__i , ## args)) { \
31 __j = __i; \
32 break; \
33 } \
34 (type)__j; \
37 /* Just like LIST_FIND but we search backwards */
38 #define LIST_FIND_B(head, cmpfn, type, args...) \
39 ({ \
40 const struct list_head *__i, *__j = NULL; \
42 ASSERT_READ_LOCK(head); \
43 list_for_each_prev(__i, (head)) \
44 if (cmpfn((const type)__i , ## args)) { \
45 __j = __i; \
46 break; \
47 } \
48 (type)__j; \
51 static inline int
52 __list_cmp_same(const void *p1, const void *p2) { return p1 == p2; }
54 /* Is this entry in the list? */
55 static inline int
56 list_inlist(struct list_head *head, const void *entry)
58 return LIST_FIND(head, __list_cmp_same, void *, entry) != NULL;
61 /* Delete from list. */
62 #ifdef CONFIG_NETFILTER_DEBUG
63 #define LIST_DELETE(head, oldentry) \
64 do { \
65 ASSERT_WRITE_LOCK(head); \
66 if (!list_inlist(head, oldentry)) \
67 printk("LIST_DELETE: %s:%u `%s'(%p) not in %s.\n", \
68 __FILE__, __LINE__, #oldentry, oldentry, #head); \
69 else list_del((struct list_head *)oldentry); \
70 } while(0)
71 #else
72 #define LIST_DELETE(head, oldentry) list_del((struct list_head *)oldentry)
73 #endif
75 /* Append. */
76 static inline void
77 list_append(struct list_head *head, void *new)
79 ASSERT_WRITE_LOCK(head);
80 list_add((new), (head)->prev);
83 /* Prepend. */
84 static inline void
85 list_prepend(struct list_head *head, void *new)
87 ASSERT_WRITE_LOCK(head);
88 list_add(new, head);
91 /* Insert according to ordering function; insert before first true. */
92 #define LIST_INSERT(head, new, cmpfn) \
93 do { \
94 struct list_head *__i; \
95 ASSERT_WRITE_LOCK(head); \
96 list_for_each(__i, (head)) \
97 if ((new), (typeof (new))__i) \
98 break; \
99 list_add((struct list_head *)(new), __i->prev); \
100 } while(0)
102 /* If the field after the list_head is a nul-terminated string, you
103 can use these functions. */
104 static inline int __list_cmp_name(const void *i, const char *name)
106 return strcmp(name, i+sizeof(struct list_head)) == 0;
109 /* Returns false if same name already in list, otherwise does insert. */
110 static inline int
111 list_named_insert(struct list_head *head, void *new)
113 if (LIST_FIND(head, __list_cmp_name, void *,
114 new + sizeof(struct list_head)))
115 return 0;
116 list_prepend(head, new);
117 return 1;
120 /* Find this named element in the list. */
121 #define list_named_find(head, name) \
122 LIST_FIND(head, __list_cmp_name, void *, name)
124 #endif /*_LISTHELP_H*/