1 /*
2 
3  Package: dyncall
4  Library: test
5  File: test/suite/main.c
6  Description:
7  License:
8 
9    Copyright (c) 2007-2021 Daniel Adler <dadler@uni-goettingen.de>,
10                            Tassilo Philipp <tphilipp@potion-studios.com>
11 
12    Permission to use, copy, modify, and distribute this software for any
13    purpose with or without fee is hereby granted, provided that the above
14    copyright notice and this permission notice appear in all copies.
15 
16    THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
17    WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
18    MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
19    ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
20    WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
21    ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
22    OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
23 
24 */
25 
26 
27 
28 #include "../../dyncall/dyncall.h"
29 #include "config.h"
30 #include "../../dyncall/dyncall_value.h"
31 #include <math.h>
32 #include <stdlib.h>
33 #include "../common/platformInit.h"
34 #include "../common/platformInit.c" /* Impl. for functions only used in this translation unit */
35 
36 
37 int       getId();
38 DCpointer getFunc(int x);
39 DCValue*  getArg(int pos);
40 
41 
42 typedef double precise;
43 
44 
45 DCbool     valueBool    [NARGS];
46 DCshort    valueShort   [NARGS];
47 DCchar     valueChar    [NARGS];
48 DCint      valueInt     [NARGS];
49 DClonglong valueLongLong[NARGS];
50 DCdouble   valueDouble  [NARGS];
51 DCpointer  valuePointer [NARGS];
52 DCfloat    valueFloat   [NARGS];
53 
54 enum {
55   ID_DOUBLE = 0,
56   ID_LONGLONG,
57   ID_INT,
58   ID_POINTER,
59   ID_BOOL,
60   ID_FLOAT
61 };
62 
equals(int select,int pos,void * data)63 DCbool equals(int select, int pos, void* data)
64 {
65   switch(select)
66   {
67     case ID_BOOL:     return ( getArg(pos)->B == valueBool    [pos] ); break;
68     case ID_INT:      return ( getArg(pos)->i == valueInt     [pos] ); break;
69     case ID_LONGLONG: return ( getArg(pos)->l == valueLongLong[pos] ); break;
70     case ID_DOUBLE:   return ( getArg(pos)->d == valueDouble  [pos] ); break;
71     case ID_POINTER:  return ( getArg(pos)->p == valuePointer [pos] ); break;
72     case ID_FLOAT:    return ( getArg(pos)->f == valueFloat   [pos] ); break;
73   }
74   return DC_FALSE;
75 }
76 
77 
78 void clearValues();
79 
80 
init()81 void init()
82 {
83   int i;
84   for(i=0; i<NARGS; ++i)
85   {
86     valueBool[i]     = (DCbool)((i % 1) ? DC_TRUE : DC_FALSE);
87     valueInt[i]      = (DCint)     (i);
88     valueLongLong[i] = (DClonglong)(i);
89     valueDouble[i]   = (DCdouble)  (i);
90     valuePointer[i]  = (DCpointer) (ptrdiff_t) (i);
91     valueFloat[i]    = (DCfloat)   (i);
92   }
93 }
94 
95 
push(DCCallVM * pCall,int select,int pos)96 void push(DCCallVM* pCall, int select, int pos)
97 {
98   switch(select)
99   {
100     case ID_BOOL: dcArgBool    ( pCall, valueBool    [pos] ); break;
101     case ID_INT: dcArgInt     ( pCall, valueInt     [pos] ); break;
102     case ID_LONGLONG: dcArgLongLong( pCall, valueLongLong[pos] ); break;
103     case ID_DOUBLE: dcArgDouble  ( pCall, valueDouble  [pos] ); break;
104     case ID_POINTER: dcArgPointer ( pCall, valuePointer [pos] ); break;
105     case ID_FLOAT: dcArgFloat   ( pCall, valueFloat   [pos] ); break;
106   }
107 }
108 
109 
110 #define test(x) if (!(x)) return DC_FALSE
111 
112 
test_case(int x)113 DCbool test_case(int x)
114 {
115   int y = x;
116   int selects[NARGS] = { 0, };
117   int pos, i;
118 
119   DCCallVM* pCall = dcNewCallVM(4096);
120   dcReset(pCall);
121   clearValues();
122 
123   for(pos = 0; y>0; ++pos)
124   {
125     int select = (y-1) % NTYPES;
126     selects[pos] = select;
127     push(pCall,select,pos);
128     y = (y-1) / NTYPES;
129   }
130   dcCallVoid(pCall,getFunc(x));
131 
132   test( getId() == x );
133 
134   for(i = 0;i<pos;++i) {
135     test( equals( selects[i], i, getArg(i) ) );
136   }
137 
138   dcFree(pCall);
139   return DC_TRUE;
140 }
141 
142 
powerfact(int x,int n)143 int powerfact(int x, int n)
144 {
145   if(n==0) return 0;
146   return (int)(pow((double)x,n)+powerfact(x,n-1));
147 }
148 
149 
run_range(int from,int to)150 DCbool run_range(int from, int to)
151 {
152   DCbool tr = DC_TRUE, r;
153   int i;
154   for(i=from; i<to; ++i) {
155     printf("%d:",i);
156     r = test_case(i);
157     printf("%d\n", r);
158     tr &= r;
159   }
160   return tr;
161 }
162 
163 
main(int argc,char * argv[])164 int main(int argc, char* argv[])
165 {
166   DCbool success = DC_FALSE;
167 
168   dcTest_initPlatform();
169 
170   init();
171   if (argc == 2) {
172     int index = atoi(argv[1]);
173     success = run_range( index, index+1 );
174   } else if (argc == 3) {
175     int from = atoi(argv[1]);
176     int to   = atoi(argv[2])+1;
177     success = run_range(from,to);
178   } else {
179     int ncalls = powerfact(NTYPES,NARGS)+1;
180     success = run_range(0,ncalls);
181   }
182 
183   printf("result: suite: %d\n", success);
184 
185   dcTest_deInitPlatform();
186 
187   return !success;
188 }
189 
190