Mercurial > pub > dyncall > dyncall
comparison test/suite_aggrs/main.c @ 432:167faab0c0be
first usable version of test suite for aggregates, handling only non-nested struct params, at the moment;
still missing:
- unions
- arrays
- aggregates as return values
author | Tassilo Philipp |
---|---|
date | Fri, 21 Jan 2022 15:42:29 +0100 |
parents | |
children | 45662241d9cd |
comparison
equal
deleted
inserted
replaced
431:1cb8a65ea27f | 432:167faab0c0be |
---|---|
1 /* | |
2 | |
3 Package: dyncall | |
4 Library: test | |
5 File: test/call_aggrs/main.c | |
6 Description: | |
7 License: | |
8 | |
9 Copyright (c) 2022 Tassilo Philipp <tphilipp@potion-studios.com> | |
10 | |
11 Permission to use, copy, modify, and distribute this software for any | |
12 purpose with or without fee is hereby granted, provided that the above | |
13 copyright notice and this permission notice appear in all copies. | |
14 | |
15 THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES | |
16 WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF | |
17 MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR | |
18 ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES | |
19 WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN | |
20 ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF | |
21 OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. | |
22 | |
23 */ | |
24 | |
25 #include "dyncall.h" | |
26 #include "dyncall_struct.h" | |
27 #include "globals.h" | |
28 #include <string.h> | |
29 #include "../common/platformInit.h" | |
30 #include "../common/platformInit.c" /* Impl. for functions only used in this translation unit */ | |
31 | |
32 | |
33 void* G_callvm; | |
34 | |
35 | |
36 static int find_agg_idx(int* len, const char* sig) | |
37 { | |
38 for(int i=0; i<G_naggs; ++i) { | |
39 const char* agg_sig = G_agg_sigs[i]; | |
40 *len = strlen(agg_sig); | |
41 if(strncmp(agg_sig, sig, *len) == 0) | |
42 return i; | |
43 } | |
44 return -1; | |
45 } | |
46 | |
47 int invoke(char const* signature, void* t) | |
48 { | |
49 DCCallVM * p = (DCCallVM*) G_callvm; | |
50 char const * sig = signature; | |
51 char rtype; | |
52 char atype; | |
53 int pos = 0; | |
54 int s = 0; | |
55 | |
56 clear_V(); | |
57 | |
58 rtype = *sig++; | |
59 dcReset(p); | |
60 | |
61 while ( (atype = *sig) != '\0') { | |
62 pos++; | |
63 switch(atype) { | |
64 case 'c': dcArgChar (p,K_c[pos]); break; | |
65 case 's': dcArgShort (p,K_s[pos]); break; | |
66 case 'i': dcArgInt (p,K_i[pos]); break; | |
67 case 'j': dcArgLong (p,K_j[pos]); break; | |
68 case 'l': dcArgLongLong(p,K_l[pos]); break; | |
69 case 'p': dcArgPointer (p,K_p[pos]); break; | |
70 case 'f': dcArgFloat (p,K_f[pos]); break; | |
71 case 'd': dcArgDouble (p,K_d[pos]); break; | |
72 case '{': { | |
73 /* find struct sig */ | |
74 int len; | |
75 int i = find_agg_idx(&len, sig); | |
76 if(i == -1) { | |
77 printf("unknown sig at '%s' ;", sig); | |
78 return 0; | |
79 } | |
80 DCstruct *st = ((DCstruct*(*)())G_agg_newdcstfuncs[i])(); | |
81 dcArgStruct(p, st, K_a[pos]); | |
82 sig += len-1; /* advance to next arg char */ | |
83 break; | |
84 } | |
85 default: printf("unknown atype '%c' (1) ;", atype); return 0; | |
86 } | |
87 ++sig; | |
88 } | |
89 | |
90 switch(rtype) | |
91 { | |
92 case 'v': dcCallVoid(p,t); s=1; /*TODO:check that no return-arg was touched.*/ break; | |
93 case 'c': s = (dcCallChar (p,t) == K_c[pos]) ; break; | |
94 case 's': s = (dcCallShort (p,t) == K_s[pos]) ; break; | |
95 case 'i': s = (dcCallInt (p,t) == K_i[pos]) ; break; | |
96 case 'j': s = (dcCallLong (p,t) == K_j[pos]) ; break; | |
97 case 'l': s = (dcCallLongLong(p,t) == K_l[pos]) ; break; | |
98 case 'p': s = (dcCallPointer (p,t) == K_p[pos]) ; break; | |
99 case 'f': s = (dcCallFloat (p,t) == K_f[pos]) ; break; | |
100 case 'd': s = (dcCallDouble (p,t) == K_d[pos]) ; break; | |
101 //@@@ handle return types case '{': @@@ ; break; | |
102 default: printf("unknown rtype '%c'", rtype); return 0; | |
103 } | |
104 | |
105 if (!s) { printf("rval wrong;"); return 0; } | |
106 /* test: */ | |
107 sig = signature+1; | |
108 pos = 1; | |
109 while ( (atype = *sig) != '\0') { | |
110 switch(atype) { | |
111 case 'c': s = ( V_c[pos] == K_c[pos] ); if (!s) printf("'c':%d: %d != %d ; ", pos, V_c[pos], K_c[pos]); break; | |
112 case 's': s = ( V_s[pos] == K_s[pos] ); if (!s) printf("'s':%d: %d != %d ; ", pos, V_s[pos], K_s[pos]); break; | |
113 case 'i': s = ( V_i[pos] == K_i[pos] ); if (!s) printf("'i':%d: %d != %d ; ", pos, V_i[pos], K_i[pos]); break; | |
114 case 'j': s = ( V_j[pos] == K_j[pos] ); if (!s) printf("'j':%d: %ld != %ld ; ", pos, V_j[pos], K_j[pos]); break; | |
115 case 'l': s = ( V_l[pos] == K_l[pos] ); if (!s) printf("'l':%d: %lld != %lld ; ", pos, V_l[pos], K_l[pos]); break; | |
116 case 'p': s = ( V_p[pos] == K_p[pos] ); if (!s) printf("'p':%d: %lld != %lld ; ", pos, (long long) V_p[pos], (long long) K_p[pos]); break; | |
117 case 'f': s = ( V_f[pos] == K_f[pos] ); if (!s) printf("'f':%d: %f != %f ; ", pos, V_f[pos], K_f[pos]); break; | |
118 case 'd': s = ( V_d[pos] == K_d[pos] ); if (!s) printf("'d':%d: %f != %f ; ", pos, V_d[pos], K_d[pos]); break; | |
119 case '{': { | |
120 /* no check: guaranteed to exist, or invoke func would've exited when passing args, above */ | |
121 int len; | |
122 int i = find_agg_idx(&len, sig); | |
123 s = ((int(*)())G_agg_cmpfuncs[i])(V_a[pos], K_a[pos]); | |
124 if (!s) printf("'{':%d: %lld != %lld ; ", pos, (long long) V_a[pos], (long long) K_a[pos]); | |
125 sig += len-1; /* advance to next arg char */ | |
126 break; | |
127 } | |
128 default: printf("unknown atype '%c' ; ", atype); return 0; | |
129 } | |
130 if (!s) { | |
131 printf("arg mismatch at %d ; ", pos); | |
132 return 0; | |
133 } | |
134 ++sig; | |
135 ++pos; | |
136 } | |
137 return 1; | |
138 } | |
139 | |
140 int run_test(int i) | |
141 { | |
142 char const * sig; | |
143 void * target; | |
144 int success; | |
145 sig = G_sigtab[i]; | |
146 target = (void*) G_funtab[i]; | |
147 printf("%d:%s:",i,sig); | |
148 success = invoke(sig,target); | |
149 printf("%d\n",success); | |
150 return success; | |
151 } | |
152 | |
153 int run_all() | |
154 { | |
155 int i; | |
156 int failure = 0; | |
157 for(i=0;i<G_ncases;++i) | |
158 failure |= !( run_test(i) ); | |
159 | |
160 return !failure; | |
161 } | |
162 | |
163 int main(int argc, char* argv[]) | |
164 { | |
165 int total; | |
166 | |
167 dcTest_initPlatform(); | |
168 | |
169 init_K(G_maxargs); | |
170 G_callvm = (DCCallVM*) dcNewCallVM(32768); | |
171 dcReset(G_callvm); | |
172 total = run_all(); | |
173 printf("result: call_aggrs: %d\n", total); | |
174 | |
175 dcTest_deInitPlatform(); | |
176 | |
177 return !total; | |
178 } | |
179 |