16 /*----- Preliminary definitions -------------------------------------------*/
18 /* Confuse the fragment scanner... */
22 static const char *test_name;
25 static void prepare(const char *name) { test_name = name; test_seq = 0; }
27 static void step(int q, const char *where)
30 fprintf(stderr, "test %s (%s): step %d instead of %d\n",
31 test_name, where, q, test_seq);
37 static void done(int q, const char *where) { step(q, where); }
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)
48 [user (tests head) tests (tests tail) main (user end)]
50 /*----- Test machinery ----------------------------------------------------*/
52 static void tests(void)
55 code c : (tests tail) {
61 /*----- Main program ------------------------------------------------------*/
71 /*----- Various kinds of method combinations ------------------------------*/
82 static void *xmalloc(size_t n)
85 if (!p) { perror("malloc"); exit(EXIT_FAILURE); }
89 static struct item *make_item(const char *p)
90 { struct item *q = xmalloc(sizeof(*q)); q->p = p; return (q); }
92 static void free_list(struct item *i)
93 { struct item *ii; while (i) { ii = i->next; free(i); i = ii; } }
95 static int check_list(struct item *i, ...)
103 p = va_arg(ap, const char *);
105 if (!i || strcmp(i->p, p) != 0) break;
113 struct vec { int *v; size_t n; };
115 static void free_vec(struct vec *v) { free(v->v); }
117 static int check_vec(struct vec *v, ...)
128 if (i == v->n || j != v->v[i]) break;
131 if (i == v->n) rc = 0;
138 [link = SodObject, nick = t1base]
139 class T1Base : SodObject {
140 [combination = progn] void aprogn() { STEP(1); }
141 [combination = sum] int asum() { return 1; }
142 [combination = and] int aand() { return 8; }
143 [combination = max] int amax() { return 12; }
145 [combination = custom,
146 decls = { struct item **head = &sod_ret; },
147 each = { *head = sod_val; head = &sod_val->next; },
148 after = { *head = 0; }]
149 struct item *alist() { return make_item("base"); }
151 [combination = custom,
152 decls = { int *v; size_t i = 0; }, methty = <int>, count = n,
153 before = { v = xmalloc(n*sizeof(int)); },
154 each = { v[i++] = sod_val; },
155 after = { sod_ret.v = v; sod_ret.n = n; }]
157 int t1base.avec() { return 19; }
160 [link = T1Base, nick = t1sub]
161 class T1Sub : T1Base {
162 void t1base.aprogn() { STEP(0); }
163 int t1base.asum() { return 2; }
164 int t1base.aand() { return 6; }
165 int t1base.amax() { return 17; }
166 struct item *t1base.alist() { return make_item("sub"); }
167 int t1base.avec() { return 4; }
171 prepare("aggregate, base");
172 { SOD_DECL(T1Base, t1, NO_KWARGS);
175 STEP(0); T1Base_aprogn(t1); /* 1 */
176 if (T1Base_asum(t1) == 1) STEP(2);
177 if (T1Base_aand(t1) == 8) STEP(3);
178 if (T1Base_amax(t1) == 12) STEP(4);
179 l = T1Base_alist(t1);
180 if (!check_list(l, "base", (const char *)0)) STEP(5);
183 if (!check_vec(&v, 19, -1)) STEP(6);
187 prepare("aggregate, sub");
188 { SOD_DECL(T1Sub, t1, NO_KWARGS);
191 T1Base_aprogn(t1); /* 0, 1 */
192 if (T1Base_asum(t1) == 3) STEP(2);
193 if (T1Base_aand(t1) == 8) STEP(3);
194 if (T1Base_amax(t1) == 17) STEP(4);
195 l = T1Base_alist(t1);
196 if (!check_list(l, "sub", "base", (const char *)0)) STEP(5);
199 if (!check_vec(&v, 4, 19, -1)) STEP(6);
205 /*----- Slot and user initargs --------------------------------------------*/
207 [link = SodObject, nick = t2]
208 class T2 : SodObject {
209 [initarg = x] int x = 0;
212 init { if (!y) STEP(0); }
216 prepare("initargs, defaults");
217 { SOD_DECL(T2, t, NO_KWARGS);
218 if (t->t2.x == 0) STEP(0);
221 prepare("initargs, explicit");
222 { SOD_DECL(T2, t, KWARGS(K(x, 42) K(y, 0)));
223 if (t->t2.x == 42) STEP(1);
228 /*----- Keyword argument propagation --------------------------------------*/
230 [link = SodObject, nick = base]
231 class T3Base : SodObject {
232 void m0(?int x) { STEP(x); }
236 [link = T3Base, nick = mid]
237 class T3Mid : T3Base {
238 void base.m0(?int y) { STEP(y); CALL_NEXT_METHOD; }
239 void base.m1(?) { STEP(4); CALL_NEXT_METHOD; }
242 [link = T3Mid, nick = sub]
243 class T3Sub : T3Mid {
244 void base.m0(?int z) { STEP(z); CALL_NEXT_METHOD; }
245 void base.m1(?int z) { STEP(z); CALL_NEXT_METHOD; }
250 { SOD_DECL(T3Sub, t, NO_KWARGS);
251 T3Base_m0(t, KWARGS(K(z, 0) K(y, 1) K(x, 2)));
252 T3Base_m1(t, KWARGS(K(z, 3)));
257 /*----- That's all, folks -------------------------------------------------*/