typesafe: fix warnings with gcc's -Wcast-qual
[ccan] / ccan / typesafe_cb / test / run.c
1 #include <ccan/typesafe_cb/typesafe_cb.h>
2 #include <string.h>
3 #include <stdint.h>
4 #include <ccan/tap/tap.h>
5
6 static char dummy = 0;
7
8 /* The example usage. */
9 static void _set_some_value(void *val)
10 {
11         ok1(val == &dummy);
12 }
13
14 #define set_some_value(expr)                                            \
15         _set_some_value(cast_if_type(void *, (expr), (expr), unsigned long))
16
17 static void _callback_onearg(void (*fn)(void *arg), void *arg)
18 {
19         fn(arg);
20 }
21
22 static void _callback_preargs(void (*fn)(int a, int b, void *arg), void *arg)
23 {
24         fn(1, 2, arg);
25 }
26
27 static void _callback_postargs(void (*fn)(void *arg, int a, int b), void *arg)
28 {
29         fn(arg, 1, 2);
30 }
31
32 #define callback_onearg(cb, arg)                                        \
33         _callback_onearg(typesafe_cb(void, (cb), (arg)), (arg))
34
35 #define callback_preargs(cb, arg)                                       \
36         _callback_preargs(typesafe_cb_preargs(void, (cb), (arg), int, int), (arg))
37
38 #define callback_postargs(cb, arg)                                      \
39         _callback_postargs(typesafe_cb_postargs(void, (cb), (arg), int, int), (arg))
40
41 static void my_callback_onearg(char *p)
42 {
43         ok1(strcmp(p, "hello world") == 0);
44 }
45
46 static void my_callback_onearg_const(const char *p)
47 {
48         ok1(strcmp(p, "hello world") == 0);
49 }
50
51 static void my_callback_onearg_volatile(volatile char *p)
52 {
53         /* Double cast avoids warning on gcc's -Wcast-qual */
54         ok1(strcmp((char *)(intptr_t)p, "hello world") == 0);
55 }
56
57 static void my_callback_preargs(int a, int b, char *p)
58 {
59         ok1(a == 1);
60         ok1(b == 2);
61         ok1(strcmp(p, "hello world") == 0);
62 }
63
64 #if 0 /* FIXME */
65 static void my_callback_preargs_const(int a, int b, const char *p)
66 {
67         ok1(a == 1);
68         ok1(b == 2);
69         ok1(strcmp(p, "hello world") == 0);
70 }
71
72 static void my_callback_preargs_volatile(int a, int b, volatile char *p)
73 {
74         ok1(a == 1);
75         ok1(b == 2);
76         ok1(strcmp((char *)p, "hello world") == 0);
77 }
78 #endif
79
80 static void my_callback_postargs(char *p, int a, int b)
81 {
82         ok1(a == 1);
83         ok1(b == 2);
84         ok1(strcmp(p, "hello world") == 0);
85 }
86
87 #if 0 /* FIXME */
88 static void my_callback_postargs_const(const char *p, int a, int b)
89 {
90         ok1(a == 1);
91         ok1(b == 2);
92         ok1(strcmp(p, "hello world") == 0);
93 }
94
95 static void my_callback_postargs_volatile(volatile char *p, int a, int b)
96 {
97         ok1(a == 1);
98         ok1(b == 2);
99         ok1(strcmp((char *)p, "hello world") == 0);
100 }
101 #endif
102
103 /* This is simply a compile test; we promised cast_if_type can be in a
104  * static initializer. */
105 struct callback_onearg
106 {
107         void (*fn)(void *arg);
108         const void *arg;
109 };
110
111 struct callback_onearg cb_onearg
112 = { typesafe_cb(void, my_callback_onearg, (char *)(intptr_t)"hello world"),
113     "hello world" };
114
115 struct callback_preargs
116 {
117         void (*fn)(int a, int b, void *arg);
118         const void *arg;
119 };
120
121 struct callback_preargs cb_preargs
122 = { typesafe_cb_preargs(void, my_callback_preargs,
123                         (char *)(intptr_t)"hi", int, int), "hi" };
124
125 struct callback_postargs
126 {
127         void (*fn)(void *arg, int a, int b);
128         const void *arg;
129 };
130
131 struct callback_postargs cb_postargs
132 = { typesafe_cb_postargs(void, my_callback_postargs, 
133                          (char *)(intptr_t)"hi", int, int), "hi" };
134
135 int main(int argc, char *argv[])
136 {
137         void *p = &dummy;
138         unsigned long l = (unsigned long)p;
139         char str[] = "hello world";
140
141         plan_tests(2 + 3 + 3 + 3);
142         set_some_value(p);
143         set_some_value(l);
144
145         callback_onearg(my_callback_onearg, str);
146         callback_onearg(my_callback_onearg_const, str);
147         callback_onearg(my_callback_onearg_volatile, str);
148
149         callback_preargs(my_callback_preargs, str);
150 #if 0 /* FIXME */
151         callback_preargs(my_callback_preargs_const, str);
152         callback_preargs(my_callback_preargs_volatile, str);
153 #endif
154
155         callback_postargs(my_callback_postargs, str);
156 #if 0 /* FIXME */
157         callback_postargs(my_callback_postargs_const, str);
158         callback_postargs(my_callback_postargs_volatile, str);
159 #endif
160
161         return exit_status();
162 }