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