bullet3/test/Bullet2/Source/main.cpp
erwincoumans ab8f16961e Code-style consistency improvement:
Apply clang-format-all.sh using the _clang-format file through all the cpp/.h files.
make sure not to apply it to certain serialization structures, since some parser expects the * as part of the name, instead of type.
This commit contains no other changes aside from adding and applying clang-format-all.sh
2018-09-23 14:17:31 -07:00

321 lines
6.7 KiB
C++

//
// main.c
// BulletTest
//
// Copyright (c) 2011 Apple Inc.
//
#include <stdio.h>
#ifdef __APPLE__
#include <libgen.h>
#endif //__APPLE__
#include <string.h>
#include <stdlib.h>
#include <limits.h>
#include "main.h"
#include "Utils.h"
#include "TestList.h"
#include "LinearMath/btScalar.h"
#if defined(BT_USE_NEON) || defined(BT_USE_SSE_IN_API)
#ifdef _WIN32
#define strcasecmp _stricmp
#define basename(A) A
#endif
#define EXIT_NO_ERROR INT_MIN
//int gReportNanoseconds = 0; // in Utils.c
int gReportAverageTimes = 0;
int gExitOnError = 0;
char *gFullPath = NULL;
const char *gAppName = NULL;
int gArgc;
const char **gArgv;
typedef struct TestNode
{
struct TestNode *next;
const char *name;
} TestNode;
TestNode *gNodeList = NULL;
static int ParseArgs(int argc, const char *argv[]);
static void PrintUsage(void);
static int Init(void);
static void ListTests(void);
const char *gArch =
#ifdef __i386__
"i386";
#elif defined __x86_64__
"x86_64";
#elif defined __arm__
"arm";
#elif defined _WIN64
"win64";
#elif defined _WIN32
"win32";
#else
#error unknown arch
#endif
#include <stdio.h>
int main(int argc, const char *argv[])
{
// Enable just one test programatically (instead of command-line param)
// TestNode *node = (TestNode*) malloc( sizeof( TestNode ) );
// node->name = "btDbvt";
// node->next = 0;
// gNodeList = node;
srand(0.f);
int numPassedTests = 0;
int numFailedTests = 0;
int err;
// Parse arguments. Build gNodeList.
if ((err = ParseArgs(argc, argv)))
{
if (EXIT_NO_ERROR == err)
return 0;
PrintUsage();
return err;
}
printf("Arch: %s\n", gArch);
if (gReportAverageTimes)
printf("Reporting average times.\n");
else
printf("Reporting best times.\n");
// Set a few things up
if ((err = Init()))
{
printf("Init failed.\n");
return err;
}
if (NULL == gNodeList)
{ // test everything
printf("No function list found. Testing everything...\n");
size_t i;
for (i = 0; NULL != gTestList[i].test_func; i++)
{
printf("\n----------------------------------------------\n");
printf("Testing %s:\n", gTestList[i].name);
printf("----------------------------------------------\n");
uint64_t startTime = ReadTicks();
int local_error = gTestList[i].test_func();
uint64_t currentTime = ReadTicks() - startTime;
if (local_error)
{
numFailedTests++;
printf("*** %s test failed with error: %d\n", gTestList[i].name, local_error);
if (gExitOnError)
return local_error;
if (0 == err)
err = local_error;
}
else
{
numPassedTests++;
printf("%s Passed.\t\t\t(%2.2gs)\n", gTestList[i].name, TicksToSeconds(currentTime));
}
}
}
else
{ // test just the list
while (NULL != gNodeList)
{
TestNode *currentNode = gNodeList;
gNodeList = gNodeList->next;
// Find the test with that name
size_t i;
for (i = 0; NULL != gTestList[i].test_func; i++)
if (0 == strcasecmp(currentNode->name, gTestList[i].name))
break;
if (NULL != gTestList[i].test_func)
{
printf("\n----------------------------------------------\n");
printf("Testing %s:\n", gTestList[i].name);
printf("----------------------------------------------\n");
uint64_t startTime = ReadTicks();
int local_error = gTestList[i].test_func();
uint64_t currentTime = ReadTicks() - startTime;
if (local_error)
{
numFailedTests++;
printf("*** %s test failed with error: %d\n", gTestList[i].name, local_error);
if (gExitOnError)
return local_error;
if (0 == err)
err = local_error;
}
else
{
numPassedTests++;
printf("%s Passed.\t\t\t(%2.2gs)\n", gTestList[i].name, TicksToSeconds(currentTime));
}
}
else
{
printf("\n***Error: Test name \"%s\" not found! Skipping.\n", currentNode->name);
err = -1;
if (gExitOnError)
return -1;
}
free(currentNode);
}
}
printf("\n----------------------------------------------\n");
printf("numPassedTests = %d, numFailedTests = %d\n", numPassedTests, numFailedTests);
free(gFullPath);
return err;
}
static int Init(void)
{
// init the timer
TicksToCycles(0);
return 0;
}
static int ParseArgs(int argc, const char *argv[])
{
int listTests = 0;
TestNode *list = NULL;
gArgc = argc;
gArgv = argv;
gFullPath = (char *)malloc(strlen(argv[0]) + 1);
strcpy(gFullPath, argv[0]);
gAppName = basename(gFullPath);
if (NULL == gAppName)
gAppName = "<unknown app name>";
printf("%s ", gAppName);
int skipremaining = 0;
size_t i;
for (i = 1; i < argc; i++)
{
const char *arg = argv[i];
printf("\t%s", arg);
if (arg[0] == '-')
{
arg++;
while (arg[0] != '\0')
{
int stop = 0;
switch (arg[0])
{
case 'a':
gReportAverageTimes ^= 1;
break;
case 'e':
gExitOnError ^= 1;
break;
case 'h':
PrintUsage();
return EXIT_NO_ERROR;
case 'l':
listTests ^= 1;
return EXIT_NO_ERROR;
case 's':
gReportNanoseconds ^= 1;
break;
case ' ':
stop = 1;
break;
case 'N': //ignore the -NSDocumentRevisionsDebugMode argument from XCode 4.3.2
skipremaining = 1;
stop = 1;
break;
default:
printf("\nError: Unknown flag \'%c\'\n", arg[0]);
return -1;
}
if (stop)
break;
arg++;
}
}
else
{ // add function name to the list
TestNode *node = (TestNode *)malloc(sizeof(TestNode));
node->name = arg;
node->next = list;
list = node;
}
if (skipremaining)
break;
}
// reverse the list of test names, and stick on gNodeList
while (list)
{
TestNode *node = list;
TestNode *next = node->next;
node->next = gNodeList;
gNodeList = node;
list = next;
}
printf("\n");
if (listTests)
ListTests();
return 0;
}
static void PrintUsage(void)
{
printf("\nUsage:\n");
printf("%s: <-aehls> <test names>", gAppName);
printf("Options:\n");
printf("\t-a\tToggle report average times vs. best times. (Default: best times)\n");
printf("\t-e\tToggle exit immediately on error behavior. (Default: off)\n");
printf("\t-h\tPrint this message.\n");
printf("\t-l\tToggle list available test names. (Default: off)\n");
printf("\t-s\tToggle report times in cycles or nanoseconds. (Default: cycles)\n\n");
printf("\tOptions may be followed by one or more test names. If no test names \n");
printf("\tare provided, then all tests are run.\n\n");
}
static void ListTests(void)
{
size_t i;
printf("\nTests:\n");
for (i = 0; NULL != gTestList[i].test_func; i++)
{
printf("%19s", gTestList[i].name);
if (NULL != gTestList[i].test_func)
printf(",");
if (3 == (i & 3))
printf("\n");
}
}
#else
#include <stdio.h>
int main(int argc, char* argv[])
{
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");
return 0;
}
#endif