main.cpp 8.5 KB

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