X-Git-Url: https://git.distorted.org.uk/~mdw/sod/blobdiff_plain/e520bc2484f96c38991fb8d3b49cd9a3b2410842..9e91c8e7b5fcdeb6389ac7ccbcd9c77348c4493a:/test/kwtest.c diff --git a/test/kwtest.c b/test/kwtest.c new file mode 100644 index 0000000..b760ed4 --- /dev/null +++ b/test/kwtest.c @@ -0,0 +1,143 @@ +/* -*-c-*- + * + * Test program for the keyword-argument machinery + * + * (c) 2015 Straylight/Edgeware + */ + +/*----- Licensing notice --------------------------------------------------* + * + * This file is part of the Sensible Object Design, an object system for C. + * + * SOD is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * SOD is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with SOD; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#include +#include +#include +#include + +#include "keyword.h" + +static void show_kwval(const char *what, int f, const char *fmt, ...) +{ + va_list ap; + + printf(" %s = ", what); + if (!f) + puts(""); + else { + va_start(ap, fmt); + vprintf(fmt, ap); + va_end(ap); + putchar('\n'); + } +} + +#define SHOW(mem, fmt) show_kwval(#mem, kw.mem##_suppliedp, fmt, kw.mem) + +#define t1_KWSET(_) \ + _(int, x, 0) \ + _(double, y, 69.0) \ + _(const char *, z, "default") +KWSET_STRUCT(t1); +static KWSET_PARSEFN(t1) +static KWCALL void t1(const char *what, KWTAIL) +{ + KWPARSE(t1); + + printf("t1: %s\n", what); + SHOW(x, "%d"); + SHOW(y, "%g"); + SHOW(z, "`%s'"); +} + +static KWCALL void t2(const char *what, ...) +{ + va_list ap; + + printf("t2: %s\n", what); + va_start(ap, what); + t1("via t2", KWARGS(K_VALIST(ap))); + va_end(ap); +} + +#define t3_KWSET(_) \ + _(int, q, 0) \ + t1_KWSET(_) +KWSET_STRUCT(t3); +static KWSET_PARSEFN(t3) +static KWCALL void t3(const char *what, KWTAIL) +{ + struct kwval v[KW_COUNT(t1)]; + size_t n = 0; + KWPARSE(t3); + + printf("t3: %s\n", what); + SHOW(q, "%c"); + SHOW(z, "`%s'"); + + KW_COPY(t3, t1, kw, v, n); + t1("via t3", KWARGS(K_TAB(v, n) + K(x, kw.x_suppliedp ? kw.x + 1 : 42))); +} + +/* The @KW_TEST@ machinery from the manpage... */ +#define KWARGS_TEST(k, val) KWARGS(K(k, val) K(kw.unknown, 0)) + +static jmp_buf kw_test_jmp; + +static void kw_test_unknown(const char *set, const char *kw) +{ + if (strcmp(kw, "kw.unknown") == 0) longjmp(kw_test_jmp, 1); + else longjmp(kw_test_jmp, 2); +} + +#define KW_TEST(flag, set, call) do { \ + kw_unkhookfn *oldunk = kw_unkhook; \ + kw_unkhook = kw_test_unknown; \ + switch (setjmp(kw_test_jmp)) { \ + case 0: call; abort(); \ + case 1: flag = 1; break; \ + case 2: flag = 0; break; \ + default: abort(); \ + } \ + kw_unkhook = oldunk; \ +} while (0) +/* END */ + +int main(void) +{ + t1("no args", NO_KWARGS); + t1("some args", KWARGS(K(z, "set") K(x, 42))); + + t2("indirection", KWARGS(K(y, 6.283))); + + t3("no args", NO_KWARGS); + t3("x initially 19", KWARGS(K(q, 't') K(x, 19) K(z, "boing"))); + +#define TEST_KWTEST(kw, val) do { \ + int f_; \ + KW_TEST(f_, t3, t3(0, KWARGS_TEST(kw, val))); \ + printf("t3 arg `%s' %s\n", #kw, f_ ? "present" : "absent"); \ +} while (0) + TEST_KWTEST(q, '!'); + TEST_KWTEST(z, "splat"); + TEST_KWTEST(nope, 0); + + return (0); +} + +/*----- That's all, folks -------------------------------------------------*/