This commit was manufactured by cvs2svn to create branch
[iptables.git] / libiptc2 / linux_listhelp.h
1 #ifndef _LINUX_LISTHELP_H
2 #define _LINUX_LISTHELP_H
3 #include <stdlib.h>
4 #include <string.h>
5 #include "linux_list.h"
6
7 /* Header to do more comprehensive job than linux/list.h; assume list
8    is first entry in structure. */
9
10 /* Return pointer to first true entry, if any, or NULL.  A macro
11    required to allow inlining of cmpfn. */
12 #define LIST_FIND(head, cmpfn, type, args...)           \
13 ({                                                      \
14         const struct list_head *__i = (head);           \
15                                                         \
16         do {                                            \
17                 __i = __i->next;                        \
18                 if (__i == (head)) {                    \
19                         __i = NULL;                     \
20                         break;                          \
21                 }                                       \
22         } while (!cmpfn((const type)__i , ## args));    \
23         (type)__i;                                      \
24 })
25
26 #define LIST_FIND_W(head, cmpfn, type, args...) \
27 ({                                              \
28         const struct list_head *__i = (head);   \
29                                                 \
30         do {                                    \
31                 __i = __i->next;                \
32                 if (__i == (head)) {            \
33                         __i = NULL;             \
34                         break;                  \
35                 }                               \
36         } while (!cmpfn((type)__i , ## args));  \
37         (type)__i;                              \
38 })
39
40 static inline int
41 __list_cmp_same(const void *p1, const void *p2) { return p1 == p2; }
42
43 /* Is this entry in the list? */
44 static inline int
45 list_inlist(struct list_head *head, const void *entry)
46 {
47         return LIST_FIND(head, __list_cmp_same, void *, entry) != NULL;
48 }
49
50 /* Delete from list. */
51 #define LIST_DELETE(head, oldentry) list_del((struct list_head *)oldentry)
52
53 /* Append. */
54 static inline void
55 list_append(struct list_head *head, void *new)
56 {
57         list_add((new), (head)->prev);
58 }
59
60 /* Prepend. */
61 static inline void
62 list_prepend(struct list_head *head, void *new)
63 {
64         list_add(new, head);
65 }
66
67 /* Insert according to ordering function; insert before first true. */
68 #define LIST_INSERT(head, new, cmpfn)                           \
69 do {                                                            \
70         struct list_head *__i;                                  \
71         for (__i = (head)->next;                                \
72              !cmpfn((new), (typeof (new))__i) && __i != (head); \
73              __i = __i->next);                                  \
74         list_add((struct list_head *)(new), __i->prev);         \
75 } while(0)
76
77 /* If the field after the list_head is a nul-terminated string, you
78    can use these functions. */
79 static inline int __list_cmp_name(const void *i, const char *name)
80 {
81         return strcmp(name, i+sizeof(struct list_head)) == 0;
82 }
83
84 /* Returns false if same name already in list, otherwise does insert. */
85 static inline int
86 list_named_insert(struct list_head *head, void *new)
87 {
88         if (LIST_FIND(head, __list_cmp_name, void *,
89                       new + sizeof(struct list_head)))
90                 return 0;
91         list_prepend(head, new);
92         return 1;
93 }
94
95 /* Find this named element in the list. */
96 #define list_named_find(head, name)                     \
97 LIST_FIND(head, __list_cmp_name, void *, name)
98
99 #endif /*_LISTHELP_H*/