chiark / gitweb /
test/test.sod: Abbreviate the T1 class nicknames.
[sod] / test / test.sod
CommitLineData
4a83289a
MW
1/* -*-sod-*- */
2
fd040f06 3code h: includes {
4a83289a
MW
4#include "sod.h"
5}
6
fd040f06 7code c: includes {
4a83289a
MW
8#include <stdio.h>
9#include <stdlib.h>
10#include <string.h>
11
12#include "test.h"
13}
14
fd040f06 15code c: early_user {
4a83289a
MW
16/*----- Preliminary definitions -------------------------------------------*/
17
18/* Confuse the fragment scanner... */
19#define LBRACE {
20#define RBRACE }
21
22static const char *test_name;
23static int test_seq;
24
25static void prepare(const char *name) { test_name = name; test_seq = 0; }
26
27static void step(int q, const char *where)
28{
29 if (test_seq != q) {
30 fprintf(stderr, "test %s (%s): step %d instead of %d\n",
31 test_name, where, q, test_seq);
32 abort();
33 }
34 test_seq++;
35}
36
37static void done(int q, const char *where) { step(q, where); }
38
39#define STRINGIFY_(x) #x
40#define STRINGIFY(x) STRINGIFY_(x)
41#define WHERE __FILE__ ":" STRINGIFY(__LINE__)
42#define STEP(q) step((q), WHERE)
43#define DONE(q) done((q), WHERE)
44
45}
46
fd040f06 47code c: (tests head)
4a83289a
MW
48 [user (tests head) tests (tests tail) main (user end)]
49{
50/*----- Test machinery ----------------------------------------------------*/
51
52static void tests(void)
53LBRACE
54}
fd040f06 55code c: (tests tail) {
4a83289a
MW
56RBRACE
57
58}
59
fd040f06 60code c: main {
4a83289a
MW
61/*----- Main program ------------------------------------------------------*/
62
63int main(void)
64{
65 tests();
66 return (0);
67}
68
69}
70
71/*----- Various kinds of method combinations ------------------------------*/
72
fd040f06 73code h: early_user {
4a83289a
MW
74struct item {
75 struct item *next;
76 const char *p;
77};
78
79}
80
fd040f06 81code c: early_user {
4a83289a
MW
82static void *xmalloc(size_t n)
83{
84 void *p = malloc(n);
85 if (!p) { perror("malloc"); exit(EXIT_FAILURE); }
86 return (p);
87}
88
89static struct item *make_item(const char *p)
90 { struct item *q = xmalloc(sizeof(*q)); q->p = p; return (q); }
91
92static void free_list(struct item *i)
93 { struct item *ii; while (i) { ii = i->next; free(i); i = ii; } }
94
95static int check_list(struct item *i, ...)
96{
97 va_list ap;
98 const char *p;
99 int rc = -1;
100
101 va_start(ap, i);
102 for (;;) {
103 p = va_arg(ap, const char *);
104 if (!p) break;
105 if (!i || strcmp(i->p, p) != 0) break;
106 i = i->next;
107 }
108 if (!i) rc = 0;
109 va_end(ap);
110 return (rc);
111}
112
113struct vec { int *v; size_t n; };
114
115static void free_vec(struct vec *v) { free(v->v); }
116
117static int check_vec(struct vec *v, ...)
118{
119 va_list ap;
120 int j;
121 size_t i = 0;
122 int rc = -1;
123
124 va_start(ap, v);
125 for (;;) {
126 j = va_arg(ap, int);
127 if (j < 0) break;
128 if (i == v->n || j != v->v[i]) break;
129 i++;
130 }
131 if (i == v->n) rc = 0;
132 va_end(ap);
133 return (rc);
134}
135
136}
137
1e99dff0 138[link = SodObject, nick = base]
fd040f06 139class T1Base: SodObject {
b07535d8
MW
140 [combination = progn] void aprogn();
141 [combination = sum] int asum();
142 [combination = and] int aand();
143 [combination = max] int amax();
4a83289a
MW
144
145 [combination = custom,
b07535d8 146 empty = { sod_ret = 0; },
4a83289a
MW
147 decls = { struct item **head = &sod_ret; },
148 each = { *head = sod_val; head = &sod_val->next; },
149 after = { *head = 0; }]
b07535d8 150 struct item *alist();
4a83289a
MW
151
152 [combination = custom,
153 decls = { int *v; size_t i = 0; }, methty = <int>, count = n,
b07535d8 154 empty = { sod_ret.v = 0; sod_ret.n = 0; },
4a83289a
MW
155 before = { v = xmalloc(n*sizeof(int)); },
156 each = { v[i++] = sod_val; },
157 after = { sod_ret.v = v; sod_ret.n = n; }]
158 struct vec avec();
b07535d8
MW
159}
160
1e99dff0 161[link = T1Base, nick = mid]
b07535d8 162class T1Mid: T1Base {
1e99dff0
MW
163 void base.aprogn() { STEP(1); }
164 int base.asum() { return 1; }
165 int base.aand() { return 8; }
166 int base.amax() { return 12; }
167 struct item *base.alist() { return make_item("mid"); }
168 int base.avec() { return 19; }
4a83289a
MW
169}
170
1e99dff0 171[link = T1Mid, nick = sub]
b07535d8 172class T1Sub: T1Mid {
1e99dff0
MW
173 void base.aprogn() { STEP(0); }
174 int base.asum() { return 2; }
175 int base.aand() { return 6; }
176 int base.amax() { return 17; }
177 struct item *base.alist() { return make_item("sub"); }
178 int base.avec() { return 4; }
4a83289a
MW
179}
180
fd040f06 181code c: tests {
4a83289a 182 prepare("aggregate, base");
a142609c 183 { SOD_DECL(T1Base, t1, NO_KWARGS);
b07535d8
MW
184 struct item *l;
185 struct vec v;
186 STEP(0); T1Base_aprogn(t1); STEP(1);
187 if (T1Base_asum(t1) == 0) STEP(2);
188 if (T1Base_aand(t1) == 1) STEP(3);
1e99dff0 189 if (!t1->_vt->base.amax) STEP(4);
b07535d8
MW
190 l = T1Base_alist(t1);
191 if (!l) STEP(5);
192 v = T1Base_avec(t1);
193 if (!v.n) STEP(6);
194 DONE(7);
195 }
196 prepare("aggregate, mid");
197 { SOD_DECL(T1Mid, t1, NO_KWARGS);
4a83289a
MW
198 struct item *l;
199 struct vec v;
200 STEP(0); T1Base_aprogn(t1); /* 1 */
201 if (T1Base_asum(t1) == 1) STEP(2);
202 if (T1Base_aand(t1) == 8) STEP(3);
203 if (T1Base_amax(t1) == 12) STEP(4);
204 l = T1Base_alist(t1);
b07535d8 205 if (!check_list(l, "mid", (const char *)0)) STEP(5);
4a83289a
MW
206 free_list(l);
207 v = T1Base_avec(t1);
208 if (!check_vec(&v, 19, -1)) STEP(6);
209 free_vec(&v);
210 DONE(7);
211 }
212 prepare("aggregate, sub");
a142609c 213 { SOD_DECL(T1Sub, t1, NO_KWARGS);
4a83289a
MW
214 struct item *l;
215 struct vec v;
216 T1Base_aprogn(t1); /* 0, 1 */
217 if (T1Base_asum(t1) == 3) STEP(2);
218 if (T1Base_aand(t1) == 8) STEP(3);
219 if (T1Base_amax(t1) == 17) STEP(4);
220 l = T1Base_alist(t1);
b07535d8 221 if (!check_list(l, "sub", "mid", (const char *)0)) STEP(5);
4a83289a
MW
222 free_list(l);
223 v = T1Base_avec(t1);
224 if (!check_vec(&v, 4, 19, -1)) STEP(6);
225 free_vec(&v);
226 DONE(7);
227 }
228}
229
b2983f35
MW
230/*----- Slot and user initargs --------------------------------------------*/
231
232[link = SodObject, nick = t2]
fd040f06 233class T2: SodObject {
b2983f35
MW
234 [initarg = x] int x = 0;
235
236 initarg int y = 1;
237 init { if (!y) STEP(0); }
238}
239
fd040f06 240code c: tests {
b2983f35
MW
241 prepare("initargs, defaults");
242 { SOD_DECL(T2, t, NO_KWARGS);
243 if (t->t2.x == 0) STEP(0);
244 DONE(1);
245 }
246 prepare("initargs, explicit");
247 { SOD_DECL(T2, t, KWARGS(K(x, 42) K(y, 0)));
248 if (t->t2.x == 42) STEP(1);
249 DONE(2);
250 }
251}
252
bce58d37
MW
253/*----- Keyword argument propagation --------------------------------------*/
254
255[link = SodObject, nick = base]
fd040f06 256class T3Base: SodObject {
bce58d37
MW
257 void m0(?int x) { STEP(x); }
258 void m1(?) { }
259}
260
12386a26 261[link = T3Base, nick = mid]
fd040f06 262class T3Mid: T3Base {
12386a26
MW
263 void base.m0(?int y) { STEP(y); CALL_NEXT_METHOD; }
264 void base.m1(?) { STEP(4); CALL_NEXT_METHOD; }
265}
266
267[link = T3Mid, nick = sub]
fd040f06 268class T3Sub: T3Mid {
bce58d37
MW
269 void base.m0(?int z) { STEP(z); CALL_NEXT_METHOD; }
270 void base.m1(?int z) { STEP(z); CALL_NEXT_METHOD; }
271}
272
fd040f06 273code c: tests {
bce58d37
MW
274 prepare("kwargs");
275 { SOD_DECL(T3Sub, t, NO_KWARGS);
12386a26
MW
276 T3Base_m0(t, KWARGS(K(z, 0) K(y, 1) K(x, 2)));
277 T3Base_m1(t, KWARGS(K(z, 3)));
278 DONE(5);
bce58d37
MW
279 }
280}
281
4a83289a 282/*----- That's all, folks -------------------------------------------------*/