From 4a83289a1b4333dba449e7f71df1f7069d2ee0f7 Mon Sep 17 00:00:00 2001 Message-Id: <4a83289a1b4333dba449e7f71df1f7069d2ee0f7.1716791842.git.mdw@distorted.org.uk> From: Mark Wooding Date: Tue, 5 Jan 2016 17:20:55 +0000 Subject: [PATCH] test/test.sod: New file containing miscellaneous tests. Organization: Straylight/Edgeware From: Mark Wooding Currently there's just a tidied-up version of the aggregating method combination tests I was using during development. --- test/Makefile.am | 8 ++ test/test.sod | 205 +++++++++++++++++++++++++++++++++++++++++++++++ vars.am | 1 + 3 files changed, 214 insertions(+) create mode 100644 test/test.sod diff --git a/test/Makefile.am b/test/Makefile.am index abd524e..08d6625 100644 --- a/test/Makefile.am +++ b/test/Makefile.am @@ -40,4 +40,12 @@ check-local:: chimaera chimaera.ref ./chimaera >chimaera.out diff -u $(srcdir)/chimaera.ref chimaera.out +###-------------------------------------------------------------------------- +### Other tests. + +TESTS += test +check_PROGRAMS += test +nodist_test_SOURCES = test.c test.h +BUILT_SOURCES += $(nodist_test_SOURCES) + ###----- That's all, folks -------------------------------------------------- diff --git a/test/test.sod b/test/test.sod new file mode 100644 index 0000000..e5025b5 --- /dev/null +++ b/test/test.sod @@ -0,0 +1,205 @@ +/* -*-sod-*- */ + +code h : includes { +#include "sod.h" +} + +code c : includes { +#include +#include +#include + +#include "test.h" +} + +code c : early_user { +/*----- Preliminary definitions -------------------------------------------*/ + +/* Confuse the fragment scanner... */ +#define LBRACE { +#define RBRACE } + +static const char *test_name; +static int test_seq; + +static void prepare(const char *name) { test_name = name; test_seq = 0; } + +static void step(int q, const char *where) +{ + if (test_seq != q) { + fprintf(stderr, "test %s (%s): step %d instead of %d\n", + test_name, where, q, test_seq); + abort(); + } + test_seq++; +} + +static void done(int q, const char *where) { step(q, where); } + +#define STRINGIFY_(x) #x +#define STRINGIFY(x) STRINGIFY_(x) +#define WHERE __FILE__ ":" STRINGIFY(__LINE__) +#define STEP(q) step((q), WHERE) +#define DONE(q) done((q), WHERE) + +} + +code c : (tests head) + [user (tests head) tests (tests tail) main (user end)] +{ +/*----- Test machinery ----------------------------------------------------*/ + +static void tests(void) +LBRACE +} +code c : (tests tail) { +RBRACE + +} + +code c : main { +/*----- Main program ------------------------------------------------------*/ + +int main(void) +{ + tests(); + return (0); +} + +} + +/*----- Various kinds of method combinations ------------------------------*/ + +code h : early_user { +struct item { + struct item *next; + const char *p; +}; + +} + +code c : early_user { +static void *xmalloc(size_t n) +{ + void *p = malloc(n); + if (!p) { perror("malloc"); exit(EXIT_FAILURE); } + return (p); +} + +static struct item *make_item(const char *p) + { struct item *q = xmalloc(sizeof(*q)); q->p = p; return (q); } + +static void free_list(struct item *i) + { struct item *ii; while (i) { ii = i->next; free(i); i = ii; } } + +static int check_list(struct item *i, ...) +{ + va_list ap; + const char *p; + int rc = -1; + + va_start(ap, i); + for (;;) { + p = va_arg(ap, const char *); + if (!p) break; + if (!i || strcmp(i->p, p) != 0) break; + i = i->next; + } + if (!i) rc = 0; + va_end(ap); + return (rc); +} + +struct vec { int *v; size_t n; }; + +static void free_vec(struct vec *v) { free(v->v); } + +static int check_vec(struct vec *v, ...) +{ + va_list ap; + int j; + size_t i = 0; + int rc = -1; + + va_start(ap, v); + for (;;) { + j = va_arg(ap, int); + if (j < 0) break; + if (i == v->n || j != v->v[i]) break; + i++; + } + if (i == v->n) rc = 0; + va_end(ap); + return (rc); +} + +} + +[link = SodObject, nick = t1base] +class T1Base : SodObject { + [combination = progn] void aprogn() { STEP(1); } + [combination = sum] int asum() { return 1; } + [combination = and] int aand() { return 8; } + [combination = max] int amax() { return 12; } + + [combination = custom, + decls = { struct item **head = &sod_ret; }, + each = { *head = sod_val; head = &sod_val->next; }, + after = { *head = 0; }] + struct item *alist() { return make_item("base"); } + + [combination = custom, + decls = { int *v; size_t i = 0; }, methty = , count = n, + before = { v = xmalloc(n*sizeof(int)); }, + each = { v[i++] = sod_val; }, + after = { sod_ret.v = v; sod_ret.n = n; }] + struct vec avec(); + int t1base.avec() { return 19; } +} + +[link = T1Base, nick = t1sub] +class T1Sub : T1Base { + void t1base.aprogn() { STEP(0); } + int t1base.asum() { return 2; } + int t1base.aand() { return 6; } + int t1base.amax() { return 17; } + struct item *t1base.alist() { return make_item("sub"); } + int t1base.avec() { return 4; } +} + +code c : tests { + prepare("aggregate, base"); + { SOD_DECL(T1Base, t1); + struct item *l; + struct vec v; + STEP(0); T1Base_aprogn(t1); /* 1 */ + if (T1Base_asum(t1) == 1) STEP(2); + if (T1Base_aand(t1) == 8) STEP(3); + if (T1Base_amax(t1) == 12) STEP(4); + l = T1Base_alist(t1); + if (!check_list(l, "base", (const char *)0)) STEP(5); + free_list(l); + v = T1Base_avec(t1); + if (!check_vec(&v, 19, -1)) STEP(6); + free_vec(&v); + DONE(7); + } + prepare("aggregate, sub"); + { SOD_DECL(T1Sub, t1); + struct item *l; + struct vec v; + T1Base_aprogn(t1); /* 0, 1 */ + if (T1Base_asum(t1) == 3) STEP(2); + if (T1Base_aand(t1) == 8) STEP(3); + if (T1Base_amax(t1) == 17) STEP(4); + l = T1Base_alist(t1); + if (!check_list(l, "sub", "base", (const char *)0)) STEP(5); + free_list(l); + v = T1Base_avec(t1); + if (!check_vec(&v, 4, 19, -1)) STEP(6); + free_vec(&v); + DONE(7); + } +} + +/*----- That's all, folks -------------------------------------------------*/ diff --git a/vars.am b/vars.am index dd7b931..0c83837 100644 --- a/vars.am +++ b/vars.am @@ -42,6 +42,7 @@ BUILT_SOURCES = bin_PROGRAMS = check_PROGRAMS = pkginclude_HEADERS = +TESTS = dist_man_MANS = -- [mdw]