add a new event for interface free
[project/netifd.git] / utils.h
1 #ifndef __NETIFD_UTILS_H
2 #define __NETIFD_UTILS_H
3
4 #include <libubox/list.h>
5 #include <libubox/avl.h>
6 #include <libubox/blobmsg.h>
7
8 #ifndef __OPTIMIZE__
9 #define BUILD_BUG_ON(condition) ((void)sizeof(char[1 - 2*!!(condition)]))
10 #else
11 extern int __build_bug_on_failed;
12 #define BUILD_BUG_ON(condition)                          \
13         do {                                                    \
14                 ((void)sizeof(char[1 - 2*!!(condition)]));  \
15                 if (condition) __build_bug_on_failed = 1;   \
16         } while(0)
17 #endif
18
19 static inline bool blobmsg_get_bool_default(struct blob_attr *attr, bool val)
20 {
21         if (!attr)
22                 return val;
23
24         return blobmsg_get_bool(attr);
25 }
26
27 #define __init __attribute__((constructor))
28
29 struct vlist_tree;
30 struct vlist_node;
31
32 typedef void (*vlist_update_cb)(struct vlist_tree *tree,
33                                 struct vlist_node *node_new,
34                                 struct vlist_node *node_old);
35
36 struct vlist_tree {
37         struct avl_tree avl;
38
39         vlist_update_cb update;
40         bool keep_old;
41         bool no_delete;
42
43         int version;
44 };
45
46 struct vlist_node {
47         struct avl_node avl;
48         int version;
49 };
50
51 void vlist_init(struct vlist_tree *tree, avl_tree_comp cmp, vlist_update_cb update);
52
53 #define vlist_find(tree, name, element, node_member) \
54         avl_find_element(&(tree)->avl, name, element, node_member.avl)
55
56 static inline void vlist_update(struct vlist_tree *tree)
57 {
58         tree->version++;
59 }
60
61 void vlist_add(struct vlist_tree *tree, struct vlist_node *node, void *key);
62 void vlist_delete(struct vlist_tree *tree, struct vlist_node *node);
63 void vlist_flush(struct vlist_tree *tree);
64 void vlist_flush_all(struct vlist_tree *tree);
65
66 #define vlist_for_each_element(tree, element, node_member) \
67         avl_for_each_element(&(tree)->avl, element, node_member.avl)
68
69
70 struct vlist_simple_tree {
71         struct list_head list;
72         int head_offset;
73         int version;
74 };
75
76 struct vlist_simple_node {
77         struct list_head list;
78         int version;
79 };
80
81 #define vlist_simple_init(tree, node, member) \
82         __vlist_simple_init(tree, offsetof(node, member))
83
84 void __vlist_simple_init(struct vlist_simple_tree *tree, int offset);
85 void vlist_simple_delete(struct vlist_simple_tree *tree, struct vlist_simple_node *node);
86 void vlist_simple_flush(struct vlist_simple_tree *tree);
87 void vlist_simple_flush_all(struct vlist_simple_tree *tree);
88
89 static inline void vlist_simple_update(struct vlist_simple_tree *tree)
90 {
91         tree->version++;
92 }
93
94 static inline void vlist_simple_add(struct vlist_simple_tree *tree, struct vlist_simple_node *node)
95 {
96         node->version = tree->version;
97         list_add(&node->list, &tree->list);
98 }
99
100 #define vlist_simple_for_each_element(tree, element, node_member) \
101         list_for_each_entry(element, &(tree)->list, node_member.list)
102
103 #define vlist_simple_empty(tree) \
104         list_empty(&(tree)->list)
105
106
107 #ifdef __linux__
108 static inline int fls(int x)
109 {
110     int r = 32;
111
112     if (!x)
113         return 0;
114     if (!(x & 0xffff0000u)) {
115         x <<= 16;
116         r -= 16;
117     }
118     if (!(x & 0xff000000u)) {
119         x <<= 8;
120         r -= 8;
121     }
122     if (!(x & 0xf0000000u)) {
123         x <<= 4;
124         r -= 4;
125     }
126     if (!(x & 0xc0000000u)) {
127         x <<= 2;
128         r -= 2;
129     }
130     if (!(x & 0x80000000u)) {
131         x <<= 1;
132         r -= 1;
133     }
134     return r;
135 }
136 #endif
137
138 int avl_strcmp(const void *k1, const void *k2, void *ptr);
139
140 #endif