add BUILD_BUG_ON from the kernel
[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 list_add(&node->list, &tree->list);
97 }
98
99 #define vlist_simple_for_each_element(tree, element, node_member) \
100 list_for_each_entry(element, &(tree)->list, node_member.list)
101
102 #define vlist_simple_empty(tree) \
103 list_empty(&(tree)->list)
104
105
106 #ifdef __linux__
107 static inline int fls(int x)
108 {
109 int r = 32;
110
111 if (!x)
112 return 0;
113 if (!(x & 0xffff0000u)) {
114 x <<= 16;
115 r -= 16;
116 }
117 if (!(x & 0xff000000u)) {
118 x <<= 8;
119 r -= 8;
120 }
121 if (!(x & 0xf0000000u)) {
122 x <<= 4;
123 r -= 4;
124 }
125 if (!(x & 0xc0000000u)) {
126 x <<= 2;
127 r -= 2;
128 }
129 if (!(x & 0x80000000u)) {
130 x <<= 1;
131 r -= 1;
132 }
133 return r;
134 }
135 #endif
136
137 int avl_strcmp(const void *k1, const void *k2, void *ptr);
138
139 #endif