diff options
Diffstat (limited to 'lib/ccan/typesafe_cb/test')
19 files changed, 759 insertions, 0 deletions
diff --git a/lib/ccan/typesafe_cb/test/compile_fail-cast_if_any.c b/lib/ccan/typesafe_cb/test/compile_fail-cast_if_any.c new file mode 100644 index 0000000000..dfb51167ff --- /dev/null +++ b/lib/ccan/typesafe_cb/test/compile_fail-cast_if_any.c @@ -0,0 +1,42 @@ +#include <ccan/typesafe_cb/typesafe_cb.h> +#include <stdlib.h> + +struct foo { + int x; +}; + +struct bar { + int x; +}; + +struct baz { + int x; +}; + +struct any { + int x; +}; + +struct other { + int x; +}; + +static void take_any(struct any *any) +{ +} + +int main(int argc, char *argv[]) +{ +#ifdef FAIL + struct other +#if !HAVE_TYPEOF||!HAVE_BUILTIN_CHOOSE_EXPR||!HAVE_BUILTIN_TYPES_COMPATIBLE_P +#error "Unfortunately we don't fail if cast_if_type is a noop." +#endif +#else + struct foo +#endif + *arg = NULL; + take_any(cast_if_any(struct any *, arg, arg, + struct foo *, struct bar *, struct baz *)); + return 0; +} diff --git a/lib/ccan/typesafe_cb/test/compile_fail-cast_if_type-promotable.c b/lib/ccan/typesafe_cb/test/compile_fail-cast_if_type-promotable.c new file mode 100644 index 0000000000..11d42f4c6b --- /dev/null +++ b/lib/ccan/typesafe_cb/test/compile_fail-cast_if_type-promotable.c @@ -0,0 +1,23 @@ +#include <ccan/typesafe_cb/typesafe_cb.h> +#include <stdbool.h> + +static void _set_some_value(void *val) +{ +} + +#define set_some_value(expr) \ + _set_some_value(typesafe_cb_cast(void *, long, (expr))) + +int main(int argc, char *argv[]) +{ +#ifdef FAIL + bool x = 0; +#if !HAVE_TYPEOF||!HAVE_BUILTIN_CHOOSE_EXPR||!HAVE_BUILTIN_TYPES_COMPATIBLE_P +#error "Unfortunately we don't fail if typesafe_cb_cast is a noop." +#endif +#else + long x = 0; +#endif + set_some_value(x); + return 0; +} diff --git a/lib/ccan/typesafe_cb/test/compile_fail-cast_if_type.c b/lib/ccan/typesafe_cb/test/compile_fail-cast_if_type.c new file mode 100644 index 0000000000..610793514f --- /dev/null +++ b/lib/ccan/typesafe_cb/test/compile_fail-cast_if_type.c @@ -0,0 +1,25 @@ +#include <ccan/typesafe_cb/typesafe_cb.h> + +void _set_some_value(void *val); + +void _set_some_value(void *val) +{ +} + +#define set_some_value(expr) \ + _set_some_value(cast_if_type(void *, (expr), (expr), unsigned long)) + +int main(int argc, char *argv[]) +{ +#ifdef FAIL + int x = 0; + set_some_value(x); +#if !HAVE_TYPEOF||!HAVE_BUILTIN_CHOOSE_EXPR||!HAVE_BUILTIN_TYPES_COMPATIBLE_P +#error "Unfortunately we don't fail if cast_if_type is a noop." +#endif +#else + void *p = 0; + set_some_value(p); +#endif + return 0; +} diff --git a/lib/ccan/typesafe_cb/test/compile_fail-typesafe_cb-int.c b/lib/ccan/typesafe_cb/test/compile_fail-typesafe_cb-int.c new file mode 100644 index 0000000000..c4033364d4 --- /dev/null +++ b/lib/ccan/typesafe_cb/test/compile_fail-typesafe_cb-int.c @@ -0,0 +1,27 @@ +#include <ccan/typesafe_cb/typesafe_cb.h> +#include <stdlib.h> + +void _callback(void (*fn)(void *arg), void *arg); +void _callback(void (*fn)(void *arg), void *arg) +{ + fn(arg); +} + +/* Callback is set up to warn if arg isn't a pointer (since it won't + * pass cleanly to _callback's second arg. */ +#define callback(fn, arg) \ + _callback(typesafe_cb(void, (fn), (arg)), (arg)) + +void my_callback(int something); +void my_callback(int something) +{ +} + +int main(int argc, char *argv[]) +{ +#ifdef FAIL + /* This fails due to arg, not due to cast. */ + callback(my_callback, 100); +#endif + return 0; +} diff --git a/lib/ccan/typesafe_cb/test/compile_fail-typesafe_cb.c b/lib/ccan/typesafe_cb/test/compile_fail-typesafe_cb.c new file mode 100644 index 0000000000..81e36d7b87 --- /dev/null +++ b/lib/ccan/typesafe_cb/test/compile_fail-typesafe_cb.c @@ -0,0 +1,34 @@ +#include <ccan/typesafe_cb/typesafe_cb.h> +#include <stdlib.h> + +static void _register_callback(void (*cb)(void *arg), void *arg) +{ +} + +#define register_callback(cb, arg) \ + _register_callback(typesafe_cb(void, void *, (cb), (arg)), (arg)) + +static void my_callback(char *p) +{ +} + +int main(int argc, char *argv[]) +{ + char str[] = "hello world"; +#ifdef FAIL + int *p; +#if !HAVE_TYPEOF||!HAVE_BUILTIN_CHOOSE_EXPR||!HAVE_BUILTIN_TYPES_COMPATIBLE_P +#error "Unfortunately we don't fail if typesafe_cb_cast is a noop." +#endif +#else + char *p; +#endif + p = NULL; + + /* This should work always. */ + register_callback(my_callback, str); + + /* This will fail with FAIL defined */ + register_callback(my_callback, p); + return 0; +} diff --git a/lib/ccan/typesafe_cb/test/compile_fail-typesafe_cb_cast-multi.c b/lib/ccan/typesafe_cb/test/compile_fail-typesafe_cb_cast-multi.c new file mode 100644 index 0000000000..62b5f91e18 --- /dev/null +++ b/lib/ccan/typesafe_cb/test/compile_fail-typesafe_cb_cast-multi.c @@ -0,0 +1,43 @@ +#include <ccan/typesafe_cb/typesafe_cb.h> +#include <stdlib.h> + +struct foo { + int x; +}; + +struct bar { + int x; +}; + +struct baz { + int x; +}; + +struct any { + int x; +}; + +struct other { + int x; +}; + +static void take_any(struct any *any) +{ +} + +int main(int argc, char *argv[]) +{ +#ifdef FAIL + struct other +#if !HAVE_TYPEOF||!HAVE_BUILTIN_CHOOSE_EXPR||!HAVE_BUILTIN_TYPES_COMPATIBLE_P +#error "Unfortunately we don't fail if typesafe_cb_cast is a noop." +#endif +#else + struct foo +#endif + *arg = NULL; + take_any(typesafe_cb_cast3(struct any *, + struct foo *, struct bar *, struct baz *, + arg)); + return 0; +} diff --git a/lib/ccan/typesafe_cb/test/compile_fail-typesafe_cb_cast.c b/lib/ccan/typesafe_cb/test/compile_fail-typesafe_cb_cast.c new file mode 100644 index 0000000000..d2e6f2ab40 --- /dev/null +++ b/lib/ccan/typesafe_cb/test/compile_fail-typesafe_cb_cast.c @@ -0,0 +1,25 @@ +#include <ccan/typesafe_cb/typesafe_cb.h> + +void _set_some_value(void *val); + +void _set_some_value(void *val) +{ +} + +#define set_some_value(expr) \ + _set_some_value(typesafe_cb_cast(void *, unsigned long, (expr))) + +int main(int argc, char *argv[]) +{ +#ifdef FAIL + int x = 0; + set_some_value(x); +#if !HAVE_TYPEOF||!HAVE_BUILTIN_CHOOSE_EXPR||!HAVE_BUILTIN_TYPES_COMPATIBLE_P +#error "Unfortunately we don't fail if typesafe_cb_cast is a noop." +#endif +#else + void *p = 0; + set_some_value(p); +#endif + return 0; +} diff --git a/lib/ccan/typesafe_cb/test/compile_fail-typesafe_cb_exact.c b/lib/ccan/typesafe_cb/test/compile_fail-typesafe_cb_exact.c new file mode 100644 index 0000000000..0f61d5decd --- /dev/null +++ b/lib/ccan/typesafe_cb/test/compile_fail-typesafe_cb_exact.c @@ -0,0 +1,33 @@ +#include <ccan/typesafe_cb/typesafe_cb.h> +#include <stdlib.h> + +static void _register_callback(void (*cb)(void *arg), const void *arg) +{ +} + +#define register_callback(cb, arg) \ + _register_callback(typesafe_cb_exact(void, (cb), (arg)), (arg)) + +static void my_callback(const char *p) +{ +} + +int main(int argc, char *argv[]) +{ +#ifdef FAIL + char *p; +#if !HAVE_TYPEOF||!HAVE_BUILTIN_CHOOSE_EXPR||!HAVE_BUILTIN_TYPES_COMPATIBLE_P +#error "Unfortunately we don't fail if cast_if_type is a noop." +#endif +#else + const char *p; +#endif + p = NULL; + + /* This should work always. */ + register_callback(my_callback, (const char *)"hello world"); + + /* This will fail with FAIL defined */ + register_callback(my_callback, p); + return 0; +} diff --git a/lib/ccan/typesafe_cb/test/compile_fail-typesafe_cb_postargs.c b/lib/ccan/typesafe_cb/test/compile_fail-typesafe_cb_postargs.c new file mode 100644 index 0000000000..7d3530851d --- /dev/null +++ b/lib/ccan/typesafe_cb/test/compile_fail-typesafe_cb_postargs.c @@ -0,0 +1,27 @@ +#include <ccan/typesafe_cb/typesafe_cb.h> +#include <stdlib.h> + +static void _register_callback(void (*cb)(void *arg, int x), void *arg) +{ +} +#define register_callback(cb, arg) \ + _register_callback(typesafe_cb_postargs(void, void *, (cb), (arg), int), (arg)) + +static void my_callback(char *p, int x) +{ +} + +int main(int argc, char *argv[]) +{ +#ifdef FAIL + int *p; +#if !HAVE_TYPEOF||!HAVE_BUILTIN_CHOOSE_EXPR||!HAVE_BUILTIN_TYPES_COMPATIBLE_P +#error "Unfortunately we don't fail if typesafe_cb_cast is a noop." +#endif +#else + char *p; +#endif + p = NULL; + register_callback(my_callback, p); + return 0; +} diff --git a/lib/ccan/typesafe_cb/test/compile_fail-typesafe_cb_preargs.c b/lib/ccan/typesafe_cb/test/compile_fail-typesafe_cb_preargs.c new file mode 100644 index 0000000000..bd55c6722c --- /dev/null +++ b/lib/ccan/typesafe_cb/test/compile_fail-typesafe_cb_preargs.c @@ -0,0 +1,28 @@ +#include <ccan/typesafe_cb/typesafe_cb.h> +#include <stdlib.h> + +static void _register_callback(void (*cb)(int x, void *arg), void *arg) +{ +} + +#define register_callback(cb, arg) \ + _register_callback(typesafe_cb_preargs(void, void *, (cb), (arg), int), (arg)) + +static void my_callback(int x, char *p) +{ +} + +int main(int argc, char *argv[]) +{ +#ifdef FAIL + int *p; +#if !HAVE_TYPEOF||!HAVE_BUILTIN_CHOOSE_EXPR||!HAVE_BUILTIN_TYPES_COMPATIBLE_P +#error "Unfortunately we don't fail if typesafe_cb_cast is a noop." +#endif +#else + char *p; +#endif + p = NULL; + register_callback(my_callback, p); + return 0; +} diff --git a/lib/ccan/typesafe_cb/test/compile_ok-cast_if_any.c b/lib/ccan/typesafe_cb/test/compile_ok-cast_if_any.c new file mode 100644 index 0000000000..e8f3c49406 --- /dev/null +++ b/lib/ccan/typesafe_cb/test/compile_ok-cast_if_any.c @@ -0,0 +1,41 @@ +#include <ccan/typesafe_cb/typesafe_cb.h> +#include <stdlib.h> + +struct foo { + int x; +}; + +struct bar { + int x; +}; + +struct baz { + int x; +}; + +struct any { + int x; +}; + +static void take_any(struct any *any) +{ +} + +int main(int argc, char *argv[]) +{ +#if HAVE_TYPEOF + /* Otherwise we get unused warnings for these. */ + struct foo *foo = NULL; + struct bar *bar = NULL; + struct baz *baz = NULL; +#endif + struct other *arg = NULL; + + take_any(cast_if_any(struct any *, arg, foo, + struct foo *, struct bar *, struct baz *)); + take_any(cast_if_any(struct any *, arg, bar, + struct foo *, struct bar *, struct baz *)); + take_any(cast_if_any(struct any *, arg, baz, + struct foo *, struct bar *, struct baz *)); + return 0; +} diff --git a/lib/ccan/typesafe_cb/test/compile_ok-typesafe_cb-NULL.c b/lib/ccan/typesafe_cb/test/compile_ok-typesafe_cb-NULL.c new file mode 100644 index 0000000000..265de8b14e --- /dev/null +++ b/lib/ccan/typesafe_cb/test/compile_ok-typesafe_cb-NULL.c @@ -0,0 +1,17 @@ +#include <ccan/typesafe_cb/typesafe_cb.h> +#include <stdlib.h> + +/* NULL args for callback function should be OK for normal and _def. */ + +static void _register_callback(void (*cb)(const void *arg), const void *arg) +{ +} + +#define register_callback(cb, arg) \ + _register_callback(typesafe_cb(void, const void *, (cb), (arg)), (arg)) + +int main(int argc, char *argv[]) +{ + register_callback(NULL, "hello world"); + return 0; +} diff --git a/lib/ccan/typesafe_cb/test/compile_ok-typesafe_cb-const.c b/lib/ccan/typesafe_cb/test/compile_ok-typesafe_cb-const.c new file mode 100644 index 0000000000..7c2d62ef23 --- /dev/null +++ b/lib/ccan/typesafe_cb/test/compile_ok-typesafe_cb-const.c @@ -0,0 +1,50 @@ +#include <ccan/typesafe_cb/typesafe_cb.h> +#include <stdlib.h> + +/* const args in callbacks should be OK. */ + +static void _register_callback(void (*cb)(void *arg), void *arg) +{ +} + +#define register_callback(cb, arg) \ + _register_callback(typesafe_cb(void, (cb), (arg)), (arg)) + +#define register_callback_def(cb, arg) \ + _register_callback(typesafe_cb_def(void, (cb), (arg)), (arg)) + +static void _register_callback_pre(void (*cb)(int x, void *arg), void *arg) +{ +} + +#define register_callback_pre(cb, arg) \ + _register_callback_pre(typesafe_cb_preargs(void, (cb), (arg), int), (arg)) + +static void _register_callback_post(void (*cb)(void *arg, int x), void *arg) +{ +} + +#define register_callback_post(cb, arg) \ + _register_callback_post(typesafe_cb_postargs(void, (cb), (arg), int), (arg)) + +static void my_callback(const char *p) +{ +} + +static void my_callback_pre(int x, /*const*/ char *p) +{ +} + +static void my_callback_post(/*const*/ char *p, int x) +{ +} + +int main(int argc, char *argv[]) +{ + char p[] = "hello world"; + register_callback(my_callback, p); + register_callback_def(my_callback, p); + register_callback_pre(my_callback_pre, p); + register_callback_post(my_callback_post, p); + return 0; +} diff --git a/lib/ccan/typesafe_cb/test/compile_ok-typesafe_cb-undefined.c b/lib/ccan/typesafe_cb/test/compile_ok-typesafe_cb-undefined.c new file mode 100644 index 0000000000..aa50bad6a9 --- /dev/null +++ b/lib/ccan/typesafe_cb/test/compile_ok-typesafe_cb-undefined.c @@ -0,0 +1,49 @@ +#include <ccan/typesafe_cb/typesafe_cb.h> +#include <stdlib.h> + +/* const args in callbacks should be OK. */ + +static void _register_callback(void (*cb)(void *arg), void *arg) +{ +} + +#define register_callback(cb, arg) \ + _register_callback(typesafe_cb(void, void *, (cb), (arg)), (arg)) + +static void _register_callback_pre(void (*cb)(int x, void *arg), void *arg) +{ +} + +#define register_callback_pre(cb, arg) \ + _register_callback_pre(typesafe_cb_preargs(void, void *, (cb), (arg), int), (arg)) + +static void _register_callback_post(void (*cb)(void *arg, int x), void *arg) +{ +} + +#define register_callback_post(cb, arg) \ + _register_callback_post(typesafe_cb_postargs(void, void *, (cb), (arg), int), (arg)) + +struct undefined; + +static void my_callback(struct undefined *undef) +{ +} + +static void my_callback_pre(int x, struct undefined *undef) +{ +} + +static void my_callback_post(struct undefined *undef, int x) +{ +} + +int main(int argc, char *argv[]) +{ + struct undefined *handle = NULL; + + register_callback(my_callback, handle); + register_callback_pre(my_callback_pre, handle); + register_callback_post(my_callback_post, handle); + return 0; +} diff --git a/lib/ccan/typesafe_cb/test/compile_ok-typesafe_cb-vars.c b/lib/ccan/typesafe_cb/test/compile_ok-typesafe_cb-vars.c new file mode 100644 index 0000000000..f6a2bfecbc --- /dev/null +++ b/lib/ccan/typesafe_cb/test/compile_ok-typesafe_cb-vars.c @@ -0,0 +1,52 @@ +#include <ccan/typesafe_cb/typesafe_cb.h> +#include <stdlib.h> + +/* const args in callbacks should be OK. */ + +static void _register_callback(void (*cb)(void *arg), void *arg) +{ +} + +#define register_callback(cb, arg) \ + _register_callback(typesafe_cb(void, void *, (cb), (arg)), (arg)) + +static void _register_callback_pre(void (*cb)(int x, void *arg), void *arg) +{ +} + +#define register_callback_pre(cb, arg) \ + _register_callback_pre(typesafe_cb_preargs(void, void *, (cb), (arg), int), (arg)) + +static void _register_callback_post(void (*cb)(void *arg, int x), void *arg) +{ +} + +#define register_callback_post(cb, arg) \ + _register_callback_post(typesafe_cb_postargs(void, void *, (cb), (arg), int), (arg)) + +struct undefined; + +static void my_callback(struct undefined *undef) +{ +} + +static void my_callback_pre(int x, struct undefined *undef) +{ +} + +static void my_callback_post(struct undefined *undef, int x) +{ +} + +int main(int argc, char *argv[]) +{ + struct undefined *handle = NULL; + void (*cb)(struct undefined *undef) = my_callback; + void (*pre)(int x, struct undefined *undef) = my_callback_pre; + void (*post)(struct undefined *undef, int x) = my_callback_post; + + register_callback(cb, handle); + register_callback_pre(pre, handle); + register_callback_post(post, handle); + return 0; +} diff --git a/lib/ccan/typesafe_cb/test/compile_ok-typesafe_cb-volatile.c b/lib/ccan/typesafe_cb/test/compile_ok-typesafe_cb-volatile.c new file mode 100644 index 0000000000..3fcb1ff656 --- /dev/null +++ b/lib/ccan/typesafe_cb/test/compile_ok-typesafe_cb-volatile.c @@ -0,0 +1,47 @@ +#include <ccan/typesafe_cb/typesafe_cb.h> +#include <stdlib.h> + +/* volatile args in callbacks should be OK. */ + +static void _register_callback(void (*cb)(void *arg), void *arg) +{ +} + +#define register_callback(cb, arg) \ + _register_callback(typesafe_cb(void, (cb), (arg)), (arg)) + +static void _register_callback_pre(void (*cb)(int x, void *arg), void *arg) +{ +} + +#define register_callback_pre(cb, arg) \ + _register_callback_pre(typesafe_cb_preargs(void, (cb), (arg), int), (arg)) + +static void _register_callback_post(void (*cb)(void *arg, int x), void *arg) +{ +} + +#define register_callback_post(cb, arg) \ + _register_callback_post(typesafe_cb_postargs(void, (cb), (arg), int), (arg)) + +static void my_callback(volatile char *p) +{ +} + +/* FIXME: Can't handle volatile for these */ +static void my_callback_pre(int x, /* volatile */ char *p) +{ +} + +static void my_callback_post(/* volatile */ char *p, int x) +{ +} + +int main(int argc, char *argv[]) +{ + char p[] = "hello world"; + register_callback(my_callback, p); + register_callback_pre(my_callback_pre, p); + register_callback_post(my_callback_post, p); + return 0; +} diff --git a/lib/ccan/typesafe_cb/test/compile_ok-typesafe_cb_cast.c b/lib/ccan/typesafe_cb/test/compile_ok-typesafe_cb_cast.c new file mode 100644 index 0000000000..b7f21dc094 --- /dev/null +++ b/lib/ccan/typesafe_cb/test/compile_ok-typesafe_cb_cast.c @@ -0,0 +1,41 @@ +#include <ccan/typesafe_cb/typesafe_cb.h> +#include <stdlib.h> + +struct foo { + int x; +}; + +struct bar { + int x; +}; + +struct baz { + int x; +}; + +struct any { + int x; +}; + +static void take_any(struct any *any) +{ +} + +int main(int argc, char *argv[]) +{ + /* Otherwise we get unused warnings for these. */ + struct foo *foo = NULL; + struct bar *bar = NULL; + struct baz *baz = NULL; + + take_any(typesafe_cb_cast3(struct any *, + struct foo *, struct bar *, struct baz *, + foo)); + take_any(typesafe_cb_cast3(struct any *, + struct foo *, struct bar *, struct baz *, + bar)); + take_any(typesafe_cb_cast3(struct any *, + struct foo *, struct bar *, struct baz *, + baz)); + return 0; +} diff --git a/lib/ccan/typesafe_cb/test/compile_ok-typesafe_cb_def-const.c b/lib/ccan/typesafe_cb/test/compile_ok-typesafe_cb_def-const.c new file mode 100644 index 0000000000..01e090f1dc --- /dev/null +++ b/lib/ccan/typesafe_cb/test/compile_ok-typesafe_cb_def-const.c @@ -0,0 +1,46 @@ +#include <ccan/typesafe_cb/typesafe_cb.h> +#include <stdlib.h> + +/* const args in callbacks should be OK. */ + +static void _register_callback(void (*cb)(void *arg), void *arg) +{ +} + +#define register_callback(cb, arg) \ + _register_callback(typesafe_cb(void, (cb), (arg)), (arg)) + +static void _register_callback_pre(void (*cb)(int x, void *arg), void *arg) +{ +} + +#define register_callback_pre(cb, arg) \ + _register_callback_pre(typesafe_cb_preargs(void, (cb), (arg), int), (arg)) + +static void _register_callback_post(void (*cb)(void *arg, int x), void *arg) +{ +} + +#define register_callback_post(cb, arg) \ + _register_callback_post(typesafe_cb_postargs(void, (cb), (arg), int), (arg)) + +static void my_callback(const char *p) +{ +} + +static void my_callback_pre(int x, /*const*/ char *p) +{ +} + +static void my_callback_post(/*const*/ char *p, int x) +{ +} + +int main(int argc, char *argv[]) +{ + char p[] = "hello world"; + register_callback(my_callback, p); + register_callback_pre(my_callback_pre, p); + register_callback_post(my_callback_post, p); + return 0; +} diff --git a/lib/ccan/typesafe_cb/test/run.c b/lib/ccan/typesafe_cb/test/run.c new file mode 100644 index 0000000000..116e7d1946 --- /dev/null +++ b/lib/ccan/typesafe_cb/test/run.c @@ -0,0 +1,109 @@ +#include <ccan/typesafe_cb/typesafe_cb.h> +#include <string.h> +#include <stdint.h> +#include <ccan/tap/tap.h> + +static char dummy = 0; + +/* The example usage. */ +static void _set_some_value(void *val) +{ + ok1(val == &dummy); +} + +#define set_some_value(expr) \ + _set_some_value(typesafe_cb_cast(void *, unsigned long, (expr))) + +static void _callback_onearg(void (*fn)(void *arg), void *arg) +{ + fn(arg); +} + +static void _callback_preargs(void (*fn)(int a, int b, void *arg), void *arg) +{ + fn(1, 2, arg); +} + +static void _callback_postargs(void (*fn)(void *arg, int a, int b), void *arg) +{ + fn(arg, 1, 2); +} + +#define callback_onearg(cb, arg) \ + _callback_onearg(typesafe_cb(void, void *, (cb), (arg)), (arg)) + +#define callback_preargs(cb, arg) \ + _callback_preargs(typesafe_cb_preargs(void, void *, (cb), (arg), int, int), (arg)) + +#define callback_postargs(cb, arg) \ + _callback_postargs(typesafe_cb_postargs(void, void *, (cb), (arg), int, int), (arg)) + +static void my_callback_onearg(char *p) +{ + ok1(strcmp(p, "hello world") == 0); +} + +static void my_callback_preargs(int a, int b, char *p) +{ + ok1(a == 1); + ok1(b == 2); + ok1(strcmp(p, "hello world") == 0); +} + +static void my_callback_postargs(char *p, int a, int b) +{ + ok1(a == 1); + ok1(b == 2); + ok1(strcmp(p, "hello world") == 0); +} + +/* This is simply a compile test; we promised typesafe_cb_cast can be in a + * static initializer. */ +struct callback_onearg +{ + void (*fn)(void *arg); + const void *arg; +}; + +struct callback_onearg cb_onearg += { typesafe_cb(void, void *, my_callback_onearg, (char *)(intptr_t)"hello world"), + "hello world" }; + +struct callback_preargs +{ + void (*fn)(int a, int b, void *arg); + const void *arg; +}; + +struct callback_preargs cb_preargs += { typesafe_cb_preargs(void, void *, my_callback_preargs, + (char *)(intptr_t)"hi", int, int), "hi" }; + +struct callback_postargs +{ + void (*fn)(void *arg, int a, int b); + const void *arg; +}; + +struct callback_postargs cb_postargs += { typesafe_cb_postargs(void, void *, my_callback_postargs, + (char *)(intptr_t)"hi", int, int), "hi" }; + +int main(int argc, char *argv[]) +{ + void *p = &dummy; + unsigned long l = (unsigned long)p; + char str[] = "hello world"; + + plan_tests(2 + 1 + 3 + 3); + set_some_value(p); + set_some_value(l); + + callback_onearg(my_callback_onearg, str); + + callback_preargs(my_callback_preargs, str); + + callback_postargs(my_callback_postargs, str); + + return exit_status(); +} |