diff options
author | Luke T. Shumaker <lukeshu@lukeshu.com> | 2024-11-15 15:12:08 -0700 |
---|---|---|
committer | Luke T. Shumaker <lukeshu@lukeshu.com> | 2024-11-15 21:40:37 -0700 |
commit | 5704de985cff1d40359ecd15211cece0fbe79067 (patch) | |
tree | 5c172a6ea91716f4f8023e58d580e4b08fbd7fc1 /libmisc/tests/test_vcall.c | |
parent | f753128b22b61d4f85a74ba2694b8f9a576fc238 (diff) |
Add tests to libmisc
Diffstat (limited to 'libmisc/tests/test_vcall.c')
-rw-r--r-- | libmisc/tests/test_vcall.c | 74 |
1 files changed, 74 insertions, 0 deletions
diff --git a/libmisc/tests/test_vcall.c b/libmisc/tests/test_vcall.c new file mode 100644 index 0000000..f36fc4b --- /dev/null +++ b/libmisc/tests/test_vcall.c @@ -0,0 +1,74 @@ +/* libmisc/tests/test_vcall.c - Tests for <libmisc/vcall.h> + * + * Copyright (C) 2024 Luke T. Shumaker <lukeshu@lukeshu.com> + * SPDX-License-Identifier: AGPL-3.0-or-later + */ + +#include <libmisc/assert.h> +#include <libmisc/vcall.h> + +#include "test.h" + +/******************************************************************************/ + +struct frobber_vtable; + +typedef struct { + struct frobber_vtable *vtable; +} implements_frobber; + +struct frobber_vtable { + int (*frob)(implements_frobber *); + int (*frob1)(implements_frobber *, int); + void (*frob0)(implements_frobber *); +}; + +/******************************************************************************/ + +struct myclass { + int a; + implements_frobber; +}; +static_assert(offsetof(struct myclass, implements_frobber) != 0); + +static int myclass_frob(implements_frobber *_self) { + struct myclass *self = VCALL_SELF(struct myclass, implements_frobber, _self); + test_assert(self); + test_assert((void*)self != (void*)_self); + return self->a; +} + +static int myclass_frob1(implements_frobber *_self, int arg) { + struct myclass *self = VCALL_SELF(struct myclass, implements_frobber, _self); + test_assert(self); + test_assert((void*)self != (void*)_self); + return arg; +} + +static void myclass_frob0(implements_frobber *_self) { + struct myclass *self = VCALL_SELF(struct myclass, implements_frobber, _self); + test_assert(self); + test_assert((void*)self != (void*)_self); +} + +struct frobber_vtable myclass_vtable = { + .frob = myclass_frob, + .frob1 = myclass_frob1, + .frob0 = myclass_frob0, +}; + +/******************************************************************************/ + +#define MAGIC1 909837 +#define MAGIC2 657441 + +int main() { + struct myclass obj = { + .implements_frobber = { .vtable = &myclass_vtable }, + .a = MAGIC1, + }; + test_assert(VCALL(&obj, frob) == MAGIC1); + test_assert(VCALL(&obj, frob1, MAGIC2) == MAGIC2); + VCALL(&obj, frob0); + return 0; +} |