lib: import ccan modules for tdb2
[samba.git] / lib / 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(typesafe_cb_cast(void *, unsigned long, (expr)))
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, void *, (cb), (arg)), (arg))
34
35 #define callback_preargs(cb, arg)                                       \
36         _callback_preargs(typesafe_cb_preargs(void, void *, (cb), (arg), int, int), (arg))
37
38 #define callback_postargs(cb, arg)                                      \
39         _callback_postargs(typesafe_cb_postargs(void, 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_preargs(int a, int b, char *p)
47 {
48         ok1(a == 1);
49         ok1(b == 2);
50         ok1(strcmp(p, "hello world") == 0);
51 }
52
53 static void my_callback_postargs(char *p, int a, int b)
54 {
55         ok1(a == 1);
56         ok1(b == 2);
57         ok1(strcmp(p, "hello world") == 0);
58 }
59
60 /* This is simply a compile test; we promised typesafe_cb_cast can be in a
61  * static initializer. */
62 struct callback_onearg
63 {
64         void (*fn)(void *arg);
65         const void *arg;
66 };
67
68 struct callback_onearg cb_onearg
69 = { typesafe_cb(void, void *, my_callback_onearg, (char *)(intptr_t)"hello world"),
70     "hello world" };
71
72 struct callback_preargs
73 {
74         void (*fn)(int a, int b, void *arg);
75         const void *arg;
76 };
77
78 struct callback_preargs cb_preargs
79 = { typesafe_cb_preargs(void, void *, my_callback_preargs,
80                         (char *)(intptr_t)"hi", int, int), "hi" };
81
82 struct callback_postargs
83 {
84         void (*fn)(void *arg, int a, int b);
85         const void *arg;
86 };
87
88 struct callback_postargs cb_postargs
89 = { typesafe_cb_postargs(void, void *, my_callback_postargs,
90                          (char *)(intptr_t)"hi", int, int), "hi" };
91
92 int main(int argc, char *argv[])
93 {
94         void *p = &dummy;
95         unsigned long l = (unsigned long)p;
96         char str[] = "hello world";
97
98         plan_tests(2 + 1 + 3 + 3);
99         set_some_value(p);
100         set_some_value(l);
101
102         callback_onearg(my_callback_onearg, str);
103
104         callback_preargs(my_callback_preargs, str);
105
106         callback_postargs(my_callback_postargs, str);
107
108         return exit_status();
109 }