Imported Upstream version 2.81
[platform/upstream/libbullet.git] / Test / Source / main.cpp
1 //\r
2 //  main.c\r
3 //  BulletTest\r
4 //\r
5 //  Copyright (c) 2011 Apple Inc.\r
6 //\r
7 #include <stdio.h>\r
8 #ifdef __APPLE__\r
9 #include <libgen.h>\r
10 #endif //__APPLE__\r
11 \r
12 #include <string.h>\r
13 #include <stdlib.h>\r
14 #include <limits.h>\r
15 #include "main.h"\r
16 #include "Utils.h"\r
17 #include "TestList.h"\r
18 #include "LinearMath/btScalar.h"\r
19 \r
20 #if defined (BT_USE_NEON) || defined (BT_USE_SSE_IN_API)\r
21 \r
22 #ifdef _WIN32\r
23 #define strcasecmp _stricmp\r
24 #define basename(A) A\r
25 #endif\r
26 \r
27 #define EXIT_NO_ERROR INT_MIN\r
28 \r
29 //int gReportNanoseconds = 0;    // in Utils.c\r
30 \r
31 int gReportAverageTimes = 0;\r
32 int gExitOnError = 0;\r
33 char *gFullPath = NULL;\r
34 const char *gAppName = NULL;\r
35 int gArgc;\r
36 const char **gArgv;\r
37 \r
38 typedef struct TestNode\r
39 {\r
40     struct TestNode *next;\r
41     const char      *name;\r
42 }TestNode;\r
43 \r
44 TestNode *gNodeList = NULL;\r
45 \r
46 static int ParseArgs( int argc, const char *argv[] );\r
47 static void PrintUsage( void );\r
48 static int Init( void );\r
49 static void ListTests(void );\r
50 \r
51 const char *gArch = \r
52 #ifdef __i386__ \r
53     "i386";\r
54 #elif defined __x86_64__\r
55     "x86_64";\r
56 #elif defined __arm__\r
57     "arm";\r
58 #elif defined _WIN64\r
59         "win64";\r
60 #elif defined _WIN32\r
61         "win32";\r
62 #else\r
63     #error unknown arch\r
64 #endif\r
65 \r
66 \r
67 \r
68 \r
69 \r
70 #include <stdio.h>\r
71 \r
72 int main (int argc, const char * argv[])\r
73 {\r
74 \r
75    // Enable just one test programatically (instead of command-line param)\r
76    // TestNode *node = (TestNode*) malloc( sizeof( TestNode ) );\r
77    // node->name = "btDbvt";\r
78    // node->next = 0;\r
79    // gNodeList = node;\r
80     \r
81         srand(0.f);\r
82 \r
83     int numPassedTests=0;\r
84         int numFailedTests= 0;\r
85 \r
86     int err;\r
87     \r
88     // Parse arguments. Build gNodeList.\r
89     if( (err = ParseArgs( argc, argv ) ) )\r
90     {\r
91         if( EXIT_NO_ERROR == err )\r
92             return 0;\r
93         \r
94         PrintUsage();        \r
95         return err;\r
96     }\r
97     \r
98     printf("Arch: %s\n", gArch );\r
99     \r
100     if( gReportAverageTimes )\r
101         printf( "Reporting average times.\n" );\r
102     else\r
103         printf( "Reporting best times.\n" );\r
104     \r
105     // Set a few things up\r
106     if( (err = Init() ))\r
107     {\r
108         printf( "Init failed.\n" );\r
109         return err;\r
110     }\r
111     \r
112     if( NULL == gNodeList )\r
113     { // test everything\r
114         printf( "No function list found. Testing everything...\n" );\r
115         size_t i;\r
116         for( i = 0; NULL != gTestList[i].test_func; i++ )\r
117         {\r
118             printf( "\n----------------------------------------------\n" );\r
119             printf( "Testing %s:\n", gTestList[i].name );\r
120             printf( "----------------------------------------------\n" );\r
121             uint64_t startTime = ReadTicks();\r
122             int local_error = gTestList[i].test_func();\r
123             uint64_t currentTime = ReadTicks() - startTime;\r
124             if( local_error )\r
125             {\r
126                                 numFailedTests++;\r
127                 printf( "*** %s test failed with error: %d\n", gTestList[i].name, local_error );\r
128                 if( gExitOnError )\r
129                     return local_error;\r
130                 if( 0 == err )\r
131                     err = local_error;\r
132             }\r
133             else\r
134                         {\r
135                                 numPassedTests++;\r
136                 printf("%s Passed.\t\t\t(%2.2gs)\n", gTestList[i].name, TicksToSeconds(currentTime));\r
137                         }\r
138         }\r
139     }\r
140     else\r
141     { // test just the list\r
142         while( NULL != gNodeList )\r
143         {\r
144             TestNode *currentNode = gNodeList;\r
145             gNodeList = gNodeList->next;\r
146             \r
147             // Find the test with that name\r
148             size_t i;\r
149             for( i = 0; NULL != gTestList[i].test_func; i++ )\r
150                 if( 0 == strcasecmp( currentNode->name, gTestList[i].name ) )\r
151                     break;\r
152             \r
153             if( NULL != gTestList[i].test_func )\r
154             {\r
155                 printf( "\n----------------------------------------------\n" );\r
156                 printf( "Testing %s:\n", gTestList[i].name );\r
157                 printf( "----------------------------------------------\n" );\r
158                 uint64_t startTime = ReadTicks();\r
159                 int local_error = gTestList[i].test_func();\r
160                 uint64_t currentTime = ReadTicks() - startTime;\r
161                 if( local_error )\r
162                 {\r
163                                         numFailedTests++;\r
164                     printf( "*** %s test failed with error: %d\n", gTestList[i].name, local_error );\r
165                     if( gExitOnError )\r
166                         return local_error;\r
167                     if( 0 == err )\r
168                         err = local_error;\r
169                 }\r
170                 else\r
171                                 {\r
172                                         numPassedTests++;\r
173                     printf("%s Passed.\t\t\t(%2.2gs)\n", gTestList[i].name, TicksToSeconds(currentTime));\r
174                                 }\r
175             }\r
176             else\r
177             {\r
178                 printf( "\n***Error: Test name \"%s\" not found! Skipping.\n", currentNode->name );\r
179                 err = -1;\r
180                 if( gExitOnError )\r
181                     return -1;\r
182             }\r
183             \r
184             free( currentNode );\r
185         }\r
186     }\r
187         printf( "\n----------------------------------------------\n" );\r
188         printf("numPassedTests = %d, numFailedTests = %d\n",numPassedTests,numFailedTests);\r
189     \r
190     free(gFullPath);\r
191     return err;\r
192 }\r
193 \r
194 static int Init( void )\r
195 {\r
196     // init the timer\r
197     TicksToCycles(0);\r
198     \r
199     return 0;\r
200 }\r
201 \r
202 static int ParseArgs( int argc, const char *argv[] )\r
203 {\r
204     int listTests = 0;\r
205     TestNode *list = NULL;\r
206     \r
207     gArgc = argc;\r
208     gArgv = argv;\r
209     gFullPath = (char*)malloc( strlen(argv[0]) + 1);\r
210     strcpy(gFullPath, argv[0]);\r
211     gAppName = basename( gFullPath );\r
212     if( NULL == gAppName )\r
213         gAppName = "<unknown app name>";\r
214     \r
215     printf( "%s ", gAppName );\r
216     int skipremaining=0;\r
217     \r
218     size_t i;\r
219     for( i = 1; i < argc; i++ )\r
220     {\r
221         const char *arg = argv[i];\r
222         printf( "\t%s", arg );\r
223         if( arg[0] == '-' )\r
224         {\r
225             arg++;\r
226             while( arg[0] != '\0' )\r
227             {\r
228                 int stop = 0;\r
229                 switch( arg[0] )\r
230                 {\r
231                     case 'a':\r
232                         gReportAverageTimes ^= 1;\r
233                         break;\r
234                     case 'e':\r
235                         gExitOnError ^= 1;\r
236                         break;\r
237                     case 'h':\r
238                         PrintUsage();\r
239                         return EXIT_NO_ERROR;\r
240                     case 'l':\r
241                         listTests ^= 1;\r
242                         return EXIT_NO_ERROR;\r
243                     case 's':\r
244                         gReportNanoseconds ^= 1;\r
245                         break;\r
246                     case ' ':\r
247                         stop = 1;\r
248                         break;\r
249                     case 'N'://ignore the -NSDocumentRevisionsDebugMode argument from XCode 4.3.2\r
250                         skipremaining = 1;\r
251                        stop = 1;\r
252                         break;\r
253                     default:\r
254                         printf( "\nError: Unknown flag \'%c\'\n", arg[0] );\r
255                         return -1;\r
256                 }\r
257                 if( stop )\r
258                     break;\r
259                 arg++;\r
260             }\r
261         }\r
262         else\r
263         { // add function name to the list\r
264             TestNode *node = (TestNode*) malloc( sizeof( TestNode ) );\r
265             node->name = arg;\r
266             node->next = list;\r
267             list = node;\r
268         }\r
269         if (skipremaining)\r
270             break;\r
271     }\r
272     \r
273     // reverse the list of test names, and stick on gNodeList\r
274     while( list )\r
275     {\r
276         TestNode *node = list;\r
277         TestNode *next = node->next;\r
278         node->next = gNodeList;\r
279         gNodeList = node;\r
280         list = next;\r
281     }\r
282     \r
283     printf( "\n" );\r
284     if( listTests )\r
285         ListTests();\r
286     \r
287     return 0;\r
288 }\r
289 \r
290 \r
291 static void PrintUsage( void )\r
292 {\r
293     printf("\nUsage:\n" );\r
294     printf("%s: <-aehls> <test names>", gAppName);\r
295     printf("Options:\n");\r
296     printf("\t-a\tToggle report average times vs. best times. (Default: best times)\n");\r
297     printf("\t-e\tToggle exit immediately on error behavior. (Default: off)\n");\r
298     printf("\t-h\tPrint this message.\n");\r
299     printf("\t-l\tToggle list available test names.  (Default: off)\n");\r
300     printf("\t-s\tToggle report times in cycles or nanoseconds. (Default: cycles)\n\n");\r
301     printf("\tOptions may be followed by one or more test names. If no test names \n" );\r
302     printf("\tare provided, then all tests are run.\n\n");\r
303 }\r
304 \r
305 static void ListTests(void )\r
306 {\r
307     size_t i;\r
308     \r
309     printf("\nTests:\n");\r
310     for( i = 0; NULL != gTestList[i].test_func; i++ )\r
311     {\r
312         printf( "%19s", gTestList[i].name );\r
313         if( NULL != gTestList[i].test_func )\r
314             printf( "," );\r
315         if( 3 == (i&3) )\r
316             printf( "\n" );\r
317     }\r
318 }\r
319 #else\r
320 #include <stdio.h>\r
321 int main(int argc, char* argv[])\r
322 {\r
323         printf("error: no SIMD enabled through BT_USE_NEON or BT_USE_SSE_IN_API \n(enable in LinearMath/btScalar.h or through build system)\n");\r
324         return 0;\r
325 }\r
326 #endif\r