Compare commits

...

10 Commits

48 changed files with 4128 additions and 303 deletions

View File

@@ -1,6 +1,10 @@
#ifndef BH_BENCH_H #ifndef BH_BENCH_H
#define BH_BENCH_H #define BH_BENCH_H
#include <BH/Common.h>
typedef struct BH_Bench BH_Bench; typedef struct BH_Bench BH_Bench;
typedef void (*BH_BenchCallback)(BH_Bench *); typedef void (*BH_BenchCallback)(BH_Bench *);
@@ -20,6 +24,25 @@ void BH_BenchAdd(const char *name,
int BH_BenchIter(BH_Bench *state); int BH_BenchIter(BH_Bench *state);
void BH_BenchSubcount(BH_Bench *state,
size_t count);
int BH_BenchRun(void); int BH_BenchRun(void);
#if defined(__GNUC__) || defined(__clang__)
#define BH_BenchDoNotOptimize(arg) \
do { \
__asm__ __volatile__("" : : "r"(*((char volatile*) &arg)) : "memory"); \
} while (0)
#else
#define BH_BenchDoNotOptimize(arg) \
do { \
volatile void* _ptr = (void*)&(arg); \
(void)_ptr; \
} while (0)
#endif
#endif /* BH_BENCH_H */ #endif /* BH_BENCH_H */

View File

@@ -14,6 +14,7 @@ struct BH_Bench
BH_BenchCallback cb; BH_BenchCallback cb;
int started; int started;
size_t iterations; size_t iterations;
size_t subcount;
}; };
@@ -51,6 +52,7 @@ void BH_BenchAdd(const char *name,
bench->cb = cb; bench->cb = cb;
bench->started = 0; bench->started = 0;
bench->iterations = 0; bench->iterations = 0;
bench->subcount = 1;
/* Append benchmark entry */ /* Append benchmark entry */
current = root; current = root;
@@ -84,15 +86,22 @@ int BH_BenchIter(BH_Bench *state)
if (millis > 1000 || state->iterations > 1000000000) if (millis > 1000 || state->iterations > 1000000000)
{ {
float ips, ns; float ips, ns;
ips = state->iterations / (millis / 1000.0f); ips = state->iterations / (millis / 1000.0f) * state->subcount;
ns = (millis * 1000000.0) / state->iterations; ns = (millis * 1000000.0) / state->iterations / state->subcount;
printf("%s\t%.2f ips (%.2f ns)\n", state->name, ips, ns); printf("%-12s %.2f ips (%.2f ns)\n", state->name, ips, ns);
return 0; return 0;
} }
return 1; return 1;
} }
void BH_BenchSubcount(BH_Bench *state,
size_t count)
{
state->subcount = count;
}
int BH_BenchRun(void) int BH_BenchRun(void)
{ {
BH_Bench *current; BH_Bench *current;

169
bench/tests/BenchAlgo.c Normal file
View File

@@ -0,0 +1,169 @@
#include <BH/Bench.h>
#include <BH/Algo.h>
#define NUM_ENTRIES 1000
static int testArray[NUM_ENTRIES];
static int tempArray[NUM_ENTRIES];
static int pivotValue;
static int intEqual(const void *a, const void *b)
{
int ia, ib;
ia = *(const int*)a;
ib = *(const int*)b;
return (ia > ib) - (ia < ib);
}
static void algoSetup(void)
{
int i;
for (i = 0; i < NUM_ENTRIES; ++i)
{
testArray[i] = NUM_ENTRIES - i;
tempArray[i] = NUM_ENTRIES - i;
}
pivotValue = NUM_ENTRIES / 2;
}
BH_BENCH_TEST(Swap)
{
int a = 123;
int b = 456;
algoSetup();
while (BH_BenchIter(state))
{
BH_Swap(&a, &b, sizeof(int));
BH_BenchDoNotOptimize(a);
BH_BenchDoNotOptimize(b);
BH_Swap(&a, &b, sizeof(int));
}
}
BH_BENCH_TEST(Partition)
{
algoSetup();
while (BH_BenchIter(state))
{
void *pivot, *result;
for (int i = 0; i < NUM_ENTRIES; ++i)
testArray[i] = tempArray[i];
pivot = &pivotValue;
result = BH_Partition(pivot, testArray, NUM_ENTRIES, sizeof(int), intEqual);
BH_BenchDoNotOptimize(result);
BH_BenchDoNotOptimize(testArray);
}
}
BH_BENCH_TEST(Sort)
{
algoSetup();
while (BH_BenchIter(state))
{
int i;
for (i = 0; i < NUM_ENTRIES; ++i)
testArray[i] = tempArray[i];
BH_Sort(testArray, NUM_ENTRIES, sizeof(int), intEqual);
BH_BenchDoNotOptimize(testArray);
}
}
BH_BENCH_TEST(HeapMake)
{
algoSetup();
while (BH_BenchIter(state))
{
int i;
for (i = 0; i < NUM_ENTRIES; ++i)
testArray[i] = tempArray[i];
BH_HeapMake(testArray, NUM_ENTRIES, sizeof(int), intEqual);
BH_BenchDoNotOptimize(testArray);
}
}
BH_BENCH_TEST(HeapRemove)
{
algoSetup();
while (BH_BenchIter(state))
{
int i;
for (i = 0; i < NUM_ENTRIES; ++i)
testArray[i] = tempArray[i];
BH_HeapMake(testArray, NUM_ENTRIES, sizeof(int), intEqual);
BH_HeapRemove(testArray, NUM_ENTRIES, sizeof(int), intEqual);
BH_BenchDoNotOptimize(testArray);
}
}
BH_BENCH_TEST(HeapInsert)
{
algoSetup();
while (BH_BenchIter(state))
{
int i, value;
for (i = 0; i < NUM_ENTRIES - 1; ++i)
testArray[i] = tempArray[i];
testArray[NUM_ENTRIES - 1] = 0;
BH_HeapMake(testArray, NUM_ENTRIES - 1, sizeof(int), intEqual);
value = 250;
BH_HeapInsert(&value, testArray, NUM_ENTRIES - 1, sizeof(int), intEqual);
BH_BenchDoNotOptimize(testArray);
}
}
BH_BENCH_TEST(HeapReplace)
{
algoSetup();
while (BH_BenchIter(state))
{
int i, value;
for (i = 0; i < NUM_ENTRIES; ++i)
testArray[i] = tempArray[i];
BH_HeapMake(testArray, NUM_ENTRIES, sizeof(int), intEqual);
value = 100;
BH_HeapReplace(&value, testArray, NUM_ENTRIES, sizeof(int), intEqual);
BH_BenchDoNotOptimize(testArray);
}
}
int main(int argc, char **argv)
{
BH_UNUSED(argc);
BH_UNUSED(argv);
BH_BENCH_ADD(Swap);
BH_BENCH_ADD(Partition);
BH_BENCH_ADD(Sort);
BH_BENCH_ADD(HeapMake);
BH_BENCH_ADD(HeapRemove);
BH_BENCH_ADD(HeapInsert);
BH_BENCH_ADD(HeapReplace);
return BH_BenchRun();
}

80
bench/tests/BenchBox2f.c Normal file
View File

@@ -0,0 +1,80 @@
#include <BH/Bench.h>
#include <BH/Math/Box2f.h>
static float boxAMin[2] = {1.0f, 2.0f};
static float boxAMax[2] = {5.0f, 6.0f};
static float boxBMin[2] = {3.0f, 4.0f};
static float boxBMax[2] = {7.0f, 8.0f};
static float pointInside[2] = {3.0f, 4.0f};
static float pointList[] =
{
1.0f, 2.0f,
4.0f, 6.0f,
2.0f, 3.0f,
5.0f, 1.0f,
3.0f, 7.0f
};
static size_t pointCount = 5;
static float outMin[2];
static float outMax[2];
BH_BENCH_TEST(Union)
{
while (BH_BenchIter(state))
{
BH_Box2fUnion(boxAMin, boxAMax, boxBMin, boxBMax, outMin, outMax);
BH_BenchDoNotOptimize(outMin);
BH_BenchDoNotOptimize(outMax);
}
}
BH_BENCH_TEST(Intersect)
{
while (BH_BenchIter(state))
{
int result;
result = BH_Box2fIntersect(boxAMin, boxAMax, boxBMin, boxBMax, outMin, outMax);
BH_BenchDoNotOptimize(result);
BH_BenchDoNotOptimize(outMin);
BH_BenchDoNotOptimize(outMax);
}
}
BH_BENCH_TEST(Contains)
{
while (BH_BenchIter(state))
{
int result;
result = BH_Box2fContains(boxAMin, boxAMax, pointInside);
BH_BenchDoNotOptimize(result);
}
}
BH_BENCH_TEST(Enclose)
{
while (BH_BenchIter(state))
{
int result;
result = BH_Box2fEnclose(pointList, pointCount, outMin, outMax);
BH_BenchDoNotOptimize(result);
BH_BenchDoNotOptimize(outMin);
BH_BenchDoNotOptimize(outMax);
}
}
int main(void)
{
BH_BENCH_ADD(Union);
BH_BENCH_ADD(Intersect);
BH_BENCH_ADD(Contains);
BH_BENCH_ADD(Enclose);
return BH_BenchRun();
}

82
bench/tests/BenchBox3f.c Normal file
View File

@@ -0,0 +1,82 @@
#include <BH/Bench.h>
#include <BH/Math/Box3f.h>
static float boxAMin[3] = {1.0f, 2.0f, 3.0f};
static float boxAMax[3] = {6.0f, 7.0f, 8.0f};
static float boxBMin[3] = {4.0f, 5.0f, 2.0f};
static float boxBMax[3] = {9.0f, 10.0f, 6.0f};
static float pointInside[3] = {3.0f, 4.0f, 5.0f};
static float pointList[] =
{
1.0f, 2.0f, 3.0f,
5.0f, 1.0f, 7.0f,
2.0f, 6.0f, 4.0f,
8.0f, 3.0f, 5.0f,
4.0f, 4.0f, 1.0f
};
static size_t pointCount = 5;
static float outMin[3];
static float outMax[3];
BH_BENCH_TEST(Union)
{
while (BH_BenchIter(state))
{
BH_Box3fUnion(boxAMin, boxAMax, boxBMin, boxBMax, outMin, outMax);
BH_BenchDoNotOptimize(outMin);
BH_BenchDoNotOptimize(outMax);
}
}
BH_BENCH_TEST(Intersect)
{
while (BH_BenchIter(state))
{
int result;
result = BH_Box3fIntersect(boxAMin, boxAMax, boxBMin, boxBMax, outMin, outMax);
BH_BenchDoNotOptimize(result);
BH_BenchDoNotOptimize(outMin);
BH_BenchDoNotOptimize(outMax);
}
}
BH_BENCH_TEST(Contains)
{
while (BH_BenchIter(state))
{
int result;
result = BH_Box3fContains(boxAMin, boxAMax, pointInside);
BH_BenchDoNotOptimize(result);
}
}
BH_BENCH_TEST(Enclose)
{
while (BH_BenchIter(state))
{
int result;
result = BH_Box3fEnclose(pointList, pointCount, outMin, outMax);
BH_BenchDoNotOptimize(result);
BH_BenchDoNotOptimize(outMin);
BH_BenchDoNotOptimize(outMax);
}
}
int main(int argc, char **argv)
{
BH_UNUSED(argc);
BH_UNUSED(argv);
BH_BENCH_ADD(Union);
BH_BENCH_ADD(Intersect);
BH_BENCH_ADD(Contains);
BH_BENCH_ADD(Enclose);
return BH_BenchRun();
}

292
bench/tests/BenchColor.c Normal file
View File

@@ -0,0 +1,292 @@
#include <BH/Bench.h>
#include <BH/Color.h>
static BH_Color color, other, result;
static BH_Color foreground, background;
static uint8_t r8, g8, b8, a8;
static uint16_t r16, g16, b16, a16;
static float rf, gf, bf, af;
static float hf, sf, vf, lf, af_hsv, af_hsl;
static int blendMode = BH_COLOR_MODE_NORMAL;
BH_BENCH_TEST(SetRGBA8GetRGBA8)
{
while (BH_BenchIter(state))
{
BH_ColorSetRGBA8(&color, 100, 200, 150, 255);
BH_ColorRGBA8(&color, &r8, &g8, &b8, &a8);
BH_BenchDoNotOptimize(r8);
BH_BenchDoNotOptimize(g8);
BH_BenchDoNotOptimize(b8);
BH_BenchDoNotOptimize(a8);
}
}
BH_BENCH_TEST(SetRGBA16GetRGBA16)
{
while (BH_BenchIter(state))
{
BH_ColorSetRGBA16(&color, 32768, 40000, 50000, 65535);
BH_ColorRGBA16(&color, &r16, &g16, &b16, &a16);
BH_BenchDoNotOptimize(r16);
BH_BenchDoNotOptimize(g16);
BH_BenchDoNotOptimize(b16);
BH_BenchDoNotOptimize(a16);
}
}
BH_BENCH_TEST(SetRGBAfGetRGBAf)
{
while (BH_BenchIter(state))
{
BH_ColorSetRGBAf(&color, 0.392f, 0.784f, 0.588f, 1.0f);
BH_ColorRGBAf(&color, &rf, &gf, &bf, &af);
BH_BenchDoNotOptimize(rf);
BH_BenchDoNotOptimize(gf);
BH_BenchDoNotOptimize(bf);
BH_BenchDoNotOptimize(af);
}
}
BH_BENCH_TEST(SetHSVAfGetHSVAf)
{
while (BH_BenchIter(state))
{
BH_ColorSetHSVAf(&color, 0.333f, 0.6f, 0.8f, 1.0f);
BH_ColorHSVAf(&color, &hf, &sf, &vf, &af_hsv);
BH_BenchDoNotOptimize(hf);
BH_BenchDoNotOptimize(sf);
BH_BenchDoNotOptimize(vf);
BH_BenchDoNotOptimize(af_hsv);
}
}
BH_BENCH_TEST(SetHSLAfGetHSLAf)
{
while (BH_BenchIter(state))
{
BH_ColorSetHSLAf(&color, 0.333f, 0.6f, 0.5f, 1.0f);
BH_ColorHSLAf(&color, &hf, &sf, &lf, &af_hsl);
BH_BenchDoNotOptimize(hf);
BH_BenchDoNotOptimize(sf);
BH_BenchDoNotOptimize(lf);
BH_BenchDoNotOptimize(af_hsl);
}
}
BH_BENCH_TEST(ToRGBAFromHSVA)
{
while (BH_BenchIter(state))
{
BH_ColorSetHSVAf(&color, 0.4f, 0.7f, 0.9f, 1.0f);
BH_ColorToRGBA(&color, &result);
BH_BenchDoNotOptimize(result.data.rgba.r);
BH_BenchDoNotOptimize(result.data.rgba.g);
BH_BenchDoNotOptimize(result.data.rgba.b);
BH_BenchDoNotOptimize(result.data.rgba.a);
}
}
BH_BENCH_TEST(ToHSVAFromRGBA)
{
while (BH_BenchIter(state))
{
BH_ColorSetRGBAf(&color, 0.2f, 0.6f, 0.4f, 1.0f);
BH_ColorToHSVA(&color, &result);
BH_BenchDoNotOptimize(result.data.hsva.h);
BH_BenchDoNotOptimize(result.data.hsva.s);
BH_BenchDoNotOptimize(result.data.hsva.v);
BH_BenchDoNotOptimize(result.data.hsva.a);
}
}
BH_BENCH_TEST(ToHSLAFromRGBA)
{
while (BH_BenchIter(state))
{
BH_ColorSetRGBAf(&color, 0.2f, 0.6f, 0.4f, 1.0f);
BH_ColorToHSLA(&color, &result);
BH_BenchDoNotOptimize(result.data.hsla.h);
BH_BenchDoNotOptimize(result.data.hsla.s);
BH_BenchDoNotOptimize(result.data.hsla.l);
BH_BenchDoNotOptimize(result.data.hsla.a);
}
}
BH_BENCH_TEST(BlendNormal)
{
while (BH_BenchIter(state))
{
BH_ColorSetRGBAf(&foreground, 0.8f, 0.3f, 0.2f, 0.7f);
BH_ColorSetRGBAf(&background, 0.1f, 0.5f, 0.9f, 1.0f);
BH_ColorBlend(&foreground, &background, BH_COLOR_MODE_NORMAL, &result);
BH_BenchDoNotOptimize(result.data.rgba.r);
BH_BenchDoNotOptimize(result.data.rgba.g);
BH_BenchDoNotOptimize(result.data.rgba.b);
BH_BenchDoNotOptimize(result.data.rgba.a);
}
}
BH_BENCH_TEST(BlendMultiply)
{
while (BH_BenchIter(state))
{
BH_ColorSetRGBAf(&foreground, 0.6f, 0.4f, 0.3f, 0.8f);
BH_ColorSetRGBAf(&background, 0.5f, 0.7f, 0.9f, 1.0f);
BH_ColorBlend(&foreground, &background, BH_COLOR_MODE_MULTIPLY, &result);
BH_BenchDoNotOptimize(result);
}
}
BH_BENCH_TEST(BlendScreen)
{
while (BH_BenchIter(state))
{
BH_ColorSetRGBAf(&foreground, 0.7f, 0.2f, 0.1f, 0.6f);
BH_ColorSetRGBAf(&background, 0.3f, 0.8f, 0.6f, 1.0f);
BH_ColorBlend(&foreground, &background, BH_COLOR_MODE_SCREEN, &result);
BH_BenchDoNotOptimize(result);
}
}
BH_BENCH_TEST(BlendOverlay)
{
while (BH_BenchIter(state))
{
BH_ColorSetRGBAf(&foreground, 0.5f, 0.5f, 0.5f, 0.9f);
BH_ColorSetRGBAf(&background, 0.4f, 0.6f, 0.3f, 1.0f);
BH_ColorBlend(&foreground, &background, BH_COLOR_MODE_OVERLAY, &result);
BH_BenchDoNotOptimize(result);
}
}
BH_BENCH_TEST(BlendHardLight)
{
while (BH_BenchIter(state))
{
BH_ColorSetRGBAf(&foreground, 0.8f, 0.1f, 0.1f, 0.7f);
BH_ColorSetRGBAf(&background, 0.5f, 0.5f, 0.5f, 1.0f);
BH_ColorBlend(&foreground, &background, BH_COLOR_MODE_HARD_LIGHT, &result);
BH_BenchDoNotOptimize(result);
}
}
BH_BENCH_TEST(BlendDifference)
{
while (BH_BenchIter(state))
{
BH_ColorSetRGBAf(&foreground, 0.9f, 0.2f, 0.1f, 0.8f);
BH_ColorSetRGBAf(&background, 0.1f, 0.8f, 0.9f, 1.0f);
BH_ColorBlend(&foreground, &background, BH_COLOR_MODE_DIFFERENCE, &result);
BH_BenchDoNotOptimize(result);
}
}
BH_BENCH_TEST(BlendHue)
{
while (BH_BenchIter(state))
{
BH_ColorSetRGBAf(&foreground, 0.8f, 0.3f, 0.2f, 1.0f);
BH_ColorSetRGBAf(&background, 0.2f, 0.7f, 0.6f, 1.0f);
BH_ColorBlend(&foreground, &background, BH_COLOR_MODE_HUE, &result);
BH_BenchDoNotOptimize(result);
}
}
BH_BENCH_TEST(BlendSaturation)
{
while (BH_BenchIter(state))
{
BH_ColorSetRGBAf(&foreground, 0.3f, 0.9f, 0.4f, 1.0f);
BH_ColorSetRGBAf(&background, 0.6f, 0.2f, 0.7f, 1.0f);
BH_ColorBlend(&foreground, &background, BH_COLOR_MODE_SATURATION, &result);
BH_BenchDoNotOptimize(result);
}
}
BH_BENCH_TEST(BlendColor)
{
while (BH_BenchIter(state))
{
BH_ColorSetRGBAf(&foreground, 0.1f, 0.8f, 0.3f, 1.0f);
BH_ColorSetRGBAf(&background, 0.7f, 0.2f, 0.6f, 1.0f);
BH_ColorBlend(&foreground, &background, BH_COLOR_MODE_COLOR, &result);
BH_BenchDoNotOptimize(result);
}
}
BH_BENCH_TEST(BlendLuminosity)
{
while (BH_BenchIter(state))
{
BH_ColorSetRGBAf(&foreground, 0.2f, 0.8f, 0.4f, 1.0f);
BH_ColorSetRGBAf(&background, 0.6f, 0.3f, 0.7f, 1.0f);
BH_ColorBlend(&foreground, &background, BH_COLOR_MODE_LUMINOSITY, &result);
BH_BenchDoNotOptimize(result);
}
}
int main(int argc, char **argv)
{
BH_UNUSED(argc);
BH_UNUSED(argv);
BH_BENCH_ADD(SetRGBA8GetRGBA8);
BH_BENCH_ADD(SetRGBA16GetRGBA16);
BH_BENCH_ADD(SetRGBAfGetRGBAf);
BH_BENCH_ADD(SetHSVAfGetHSVAf);
BH_BENCH_ADD(SetHSLAfGetHSLAf);
BH_BENCH_ADD(ToRGBAFromHSVA);
BH_BENCH_ADD(ToHSVAFromRGBA);
BH_BENCH_ADD(ToHSLAFromRGBA);
BH_BENCH_ADD(BlendNormal);
BH_BENCH_ADD(BlendMultiply);
BH_BENCH_ADD(BlendScreen);
BH_BENCH_ADD(BlendOverlay);
BH_BENCH_ADD(BlendHardLight);
BH_BENCH_ADD(BlendDifference);
BH_BENCH_ADD(BlendHue);
BH_BENCH_ADD(BlendSaturation);
BH_BENCH_ADD(BlendColor);
BH_BENCH_ADD(BlendLuminosity);
return BH_BenchRun();
}

136
bench/tests/BenchHashmap.c Normal file
View File

@@ -0,0 +1,136 @@
#include <BH/Bench.h>
#include <BH/Hashmap.h>
#include <stdio.h>
#define NUM_ENTRIES 1000
static int keys[NUM_ENTRIES];
static char values[NUM_ENTRIES][16];
static BH_Hashmap *map;
static BH_Hashmap *warmMap;
int BH_IntEqual(const void *a, const void *b)
{
return (*(const int*)a == *(const int*)b) ? 0 : 1;
}
size_t BH_IntHash(const void *key)
{
int k = *(const int*)key;
return (size_t)((k * 2654435761U) >> 8);
}
static void setupData(void)
{
int i;
for (i = 0; i < NUM_ENTRIES; ++i)
{
keys[i] = i + 1;
sprintf(values[i], "value_%d", i + 1);
}
}
static void setupWarmMap(void)
{
int i;
warmMap = BH_HashmapNew(BH_IntEqual, BH_IntHash);
for (i = 0; i < NUM_ENTRIES; ++i)
{
BH_HashmapInsert(warmMap, &keys[i], values[i]);
}
}
BH_BENCH_TEST(NewFree)
{
while (BH_BenchIter(state))
{
map = BH_HashmapNew(BH_IntEqual, BH_IntHash);
BH_BenchDoNotOptimize(map);
BH_HashmapFree(map);
}
}
BH_BENCH_TEST(ReserveInsert)
{
BH_BenchSubcount(state, NUM_ENTRIES);
while (BH_BenchIter(state))
{
map = BH_HashmapNew(BH_IntEqual, BH_IntHash);
BH_HashmapReserve(map, NUM_ENTRIES);
for (int i = 0; i < NUM_ENTRIES; ++i)
{
BH_HashmapInsert(map, &keys[i], values[i]);
}
BH_HashmapClear(map);
BH_BenchDoNotOptimize(map);
BH_HashmapFree(map);
}
}
BH_BENCH_TEST(Lookup)
{
BH_BenchSubcount(state, NUM_ENTRIES);
while (BH_BenchIter(state))
{
int i;
void *value = NULL;
for (i = 0; i < NUM_ENTRIES; ++i)
{
BH_HashmapAt(warmMap, &keys[i], &value);
}
BH_BenchDoNotOptimize(value);
}
}
BH_BENCH_TEST(Remove)
{
BH_BenchSubcount(state, NUM_ENTRIES);
while (BH_BenchIter(state))
{
int i;
map = BH_HashmapNew(BH_IntEqual, BH_IntHash);
for (i = 0; i < NUM_ENTRIES; ++i)
{
BH_HashmapInsert(map, &keys[i], values[i]);
}
for (i = 0; i < NUM_ENTRIES; ++i)
{
BH_HashmapRemove(map, &keys[i]);
}
BH_BenchDoNotOptimize(map);
BH_HashmapFree(map);
}
}
int main(int argc, char **argv)
{
BH_UNUSED(argc);
BH_UNUSED(argv);
setupData();
setupWarmMap();
BH_BENCH_ADD(NewFree);
BH_BENCH_ADD(ReserveInsert);
BH_BENCH_ADD(Lookup);
BH_BENCH_ADD(Remove);
return BH_BenchRun();
}

55
bench/tests/BenchLine.c Normal file
View File

@@ -0,0 +1,55 @@
#include <BH/Bench.h>
#include <BH/Math/Line.h>
static float pointA[2] = {1.0f, 2.0f};
static float pointB[2] = {4.0f, 6.0f};
static float lineNormal[3] = {3.0f, -4.0f, 5.0f};
static float outLine[3];
static float outPoint[2];
BH_BENCH_TEST(FromPoints)
{
while (BH_BenchIter(state))
{
int result;
result = BH_LineFromPoints(pointA, pointB, outLine);
BH_BenchDoNotOptimize(result);
BH_BenchDoNotOptimize(outLine);
}
}
BH_BENCH_TEST(Distance)
{
while (BH_BenchIter(state))
{
float result;
result = BH_LineDistance(lineNormal, pointA);
BH_BenchDoNotOptimize(result);
}
}
BH_BENCH_TEST(ClosestPoint)
{
while (BH_BenchIter(state))
{
BH_LineClosestPoint(lineNormal, pointA, outPoint);
BH_BenchDoNotOptimize(outPoint);
}
}
int main(int argc, char **argv)
{
BH_UNUSED(argc);
BH_UNUSED(argv);
BH_BENCH_ADD(FromPoints);
BH_BENCH_ADD(Distance);
BH_BENCH_ADD(ClosestPoint);
return BH_BenchRun();
}

190
bench/tests/BenchMat3f.c Normal file
View File

@@ -0,0 +1,190 @@
#include <BH/Bench.h>
#include <BH/Math/Mat3f.h>
static float matA[9] =
{
1.0f, 0.5f, 0.0f,
0.2f, 2.0f, 0.3f,
0.0f, 0.1f, 1.5f
};
static float matB[9] =
{
0.8f, 0.0f, 0.2f,
0.1f, 1.2f, 0.4f,
0.3f, 0.0f, 0.9f
};
static float outMat[9];
static float outInv[9];
static float vec3[3] = {1.5f, 2.5f, 1.0f};
static float vec2[2] = {3.0f, 4.0f};
static float outVec3[3];
static float outVec2[2];
BH_BENCH_TEST(Identity)
{
while (BH_BenchIter(state))
{
BH_Mat3fIdentity(outMat);
BH_BenchDoNotOptimize(outMat);
}
}
BH_BENCH_TEST(Add)
{
while (BH_BenchIter(state))
{
BH_Mat3fAdd(matA, matB, outMat);
BH_BenchDoNotOptimize(outMat);
}
}
BH_BENCH_TEST(Sub)
{
while (BH_BenchIter(state))
{
BH_Mat3fSub(matA, matB, outMat);
BH_BenchDoNotOptimize(outMat);
}
}
BH_BENCH_TEST(Mul)
{
while (BH_BenchIter(state))
{
BH_Mat3fMul(matA, matB, outMat);
BH_BenchDoNotOptimize(outMat);
}
}
BH_BENCH_TEST(Scale)
{
while (BH_BenchIter(state))
{
BH_Mat3fScale(matA, 2.5f, outMat);
BH_BenchDoNotOptimize(outMat);
}
}
BH_BENCH_TEST(Transpose)
{
while (BH_BenchIter(state))
{
BH_Mat3fTranspose(matA, outMat);
BH_BenchDoNotOptimize(outMat);
}
}
BH_BENCH_TEST(Trace)
{
while (BH_BenchIter(state))
{
float trace;
trace = BH_Mat3fTrace(matA);
BH_BenchDoNotOptimize(trace);
}
}
BH_BENCH_TEST(Det)
{
while (BH_BenchIter(state))
{
float det;
det = BH_Mat3fDet(matA);
BH_BenchDoNotOptimize(det);
}
}
BH_BENCH_TEST(Inverse)
{
while (BH_BenchIter(state))
{
int result;
result = BH_Mat3fInverse(matA, outInv);
BH_BenchDoNotOptimize(result);
BH_BenchDoNotOptimize(outInv);
}
}
BH_BENCH_TEST(FromScale)
{
while (BH_BenchIter(state))
{
BH_Mat3fFromScale(2.0f, 3.0f, outMat);
BH_BenchDoNotOptimize(outMat);
}
}
BH_BENCH_TEST(FromTranslation)
{
while (BH_BenchIter(state))
{
BH_Mat3fFromTranslation(4.0f, -2.0f, outMat);
BH_BenchDoNotOptimize(outMat);
}
}
BH_BENCH_TEST(FromRotation)
{
while (BH_BenchIter(state))
{
BH_Mat3fFromRotation(0.7854f, outMat);
BH_BenchDoNotOptimize(outMat);
}
}
BH_BENCH_TEST(ApplyVec3f)
{
while (BH_BenchIter(state))
{
BH_Mat3fApplyVec3f(matA, vec3, outVec3);
BH_BenchDoNotOptimize(outVec3);
}
}
BH_BENCH_TEST(ApplyVec2f)
{
while (BH_BenchIter(state))
{
BH_Mat3fApplyVec2f(matA, vec2, outVec2);
BH_BenchDoNotOptimize(outVec2);
}
}
int main(int argc, char **argv)
{
BH_UNUSED(argc);
BH_UNUSED(argv);
BH_BENCH_ADD(Identity);
BH_BENCH_ADD(Add);
BH_BENCH_ADD(Sub);
BH_BENCH_ADD(Mul);
BH_BENCH_ADD(Scale);
BH_BENCH_ADD(Transpose);
BH_BENCH_ADD(Trace);
BH_BENCH_ADD(Det);
BH_BENCH_ADD(Inverse);
BH_BENCH_ADD(FromScale);
BH_BENCH_ADD(FromTranslation);
BH_BENCH_ADD(FromRotation);
BH_BENCH_ADD(ApplyVec3f);
BH_BENCH_ADD(ApplyVec2f);
return BH_BenchRun();
}

285
bench/tests/BenchMat4f.c Normal file
View File

@@ -0,0 +1,285 @@
#include <BH/Bench.h>
#include <BH/Math/Mat4f.h>
static float matA[16] =
{
1.0f, 0.2f, 0.0f, 0.0f,
0.1f, 1.5f, 0.3f, 0.0f,
0.0f, 0.0f, 2.0f, 0.0f,
1.0f, 2.0f, 3.0f, 1.0f
};
static float matB[16] =
{
0.9f, 0.0f, 0.1f, 0.0f,
0.0f, 1.1f, 0.0f, 0.0f,
0.2f, 0.3f, 0.8f, 0.0f,
0.5f, 1.0f, 1.5f, 1.0f
};
static float outMat[16];
static float outInv[16];
static float vec4[4] = {1.0f, 2.0f, 3.0f, 1.0f};
static float vec3[3] = {4.0f, 5.0f, 6.0f};
static float outVec4[4];
static float outVec3[3];
static float quat[4] = {0.707f, 0.0f, 0.0f, 0.707f};
static float axis[3] = {0.577f, 0.577f, 0.577f};
static float camPos[3] = {0.0f, 0.0f, 5.0f};
static float camAt[3] = {0.0f, 0.0f, 0.0f};
static float camUp[3] = {0.0f, 1.0f, 0.0f};
BH_BENCH_TEST(Identity)
{
while (BH_BenchIter(state))
{
BH_Mat4fIdentity(outMat);
BH_BenchDoNotOptimize(outMat);
}
}
BH_BENCH_TEST(Add)
{
while (BH_BenchIter(state))
{
BH_Mat4fAdd(matA, matB, outMat);
BH_BenchDoNotOptimize(outMat);
}
}
BH_BENCH_TEST(Sub)
{
while (BH_BenchIter(state))
{
BH_Mat4fSub(matA, matB, outMat);
BH_BenchDoNotOptimize(outMat);
}
}
BH_BENCH_TEST(Mul)
{
while (BH_BenchIter(state))
{
BH_Mat4fMul(matA, matB, outMat);
BH_BenchDoNotOptimize(outMat);
}
}
BH_BENCH_TEST(Scale)
{
while (BH_BenchIter(state))
{
BH_Mat4fScale(matA, 1.5f, outMat);
BH_BenchDoNotOptimize(outMat);
}
}
BH_BENCH_TEST(Transpose)
{
while (BH_BenchIter(state))
{
BH_Mat4fTranspose(matA, outMat);
BH_BenchDoNotOptimize(outMat);
}
}
BH_BENCH_TEST(Trace)
{
while (BH_BenchIter(state))
{
float trace;
trace = BH_Mat4fTrace(matA);
BH_BenchDoNotOptimize(trace);
}
}
BH_BENCH_TEST(Det)
{
while (BH_BenchIter(state))
{
float det;
det = BH_Mat4fDet(matA);
BH_BenchDoNotOptimize(det);
}
}
BH_BENCH_TEST(Inverse)
{
while (BH_BenchIter(state))
{
int result;
result = BH_Mat4fInverse(matA, outInv);
BH_BenchDoNotOptimize(result);
BH_BenchDoNotOptimize(outInv);
}
}
BH_BENCH_TEST(FromScale)
{
while (BH_BenchIter(state))
{
BH_Mat4fFromScale(2.0f, 3.0f, 4.0f, outMat);
BH_BenchDoNotOptimize(outMat);
}
}
BH_BENCH_TEST(FromTranslation)
{
while (BH_BenchIter(state))
{
BH_Mat4fFromTranslation(1.0f, -1.0f, 2.5f, outMat);
BH_BenchDoNotOptimize(outMat);
}
}
BH_BENCH_TEST(FromRotationX)
{
while (BH_BenchIter(state))
{
BH_Mat4fFromRotationX(0.7854f, outMat);
BH_BenchDoNotOptimize(outMat);
}
}
BH_BENCH_TEST(FromRotationY)
{
while (BH_BenchIter(state))
{
BH_Mat4fFromRotationY(0.7854f, outMat);
BH_BenchDoNotOptimize(outMat);
}
}
BH_BENCH_TEST(FromRotationZ)
{
while (BH_BenchIter(state))
{
BH_Mat4fFromRotationZ(0.7854f, outMat);
BH_BenchDoNotOptimize(outMat);
}
}
BH_BENCH_TEST(FromAxis)
{
while (BH_BenchIter(state))
{
BH_Mat4fFromAxis(axis, 1.0472f, outMat);
BH_BenchDoNotOptimize(outMat);
}
}
BH_BENCH_TEST(FromEuler)
{
while (BH_BenchIter(state))
{
BH_Mat4fFromEuler(0.3f, 0.4f, 0.5f, outMat);
BH_BenchDoNotOptimize(outMat);
}
}
BH_BENCH_TEST(FromQuat4f)
{
while (BH_BenchIter(state))
{
BH_Mat4fFromQuat4f(quat, outMat);
BH_BenchDoNotOptimize(outMat);
}
}
BH_BENCH_TEST(FromOrtho)
{
while (BH_BenchIter(state))
{
BH_Mat4fFromOrtho(-4.0f, 4.0f, -3.0f, 3.0f, 0.1f, 100.0f, outMat);
BH_BenchDoNotOptimize(outMat);
}
}
BH_BENCH_TEST(FromFrustum)
{
while (BH_BenchIter(state))
{
BH_Mat4fFromFrustum(60.0f, 1.77f, 0.1f, 100.0f, outMat);
BH_BenchDoNotOptimize(outMat);
}
}
BH_BENCH_TEST(FromLookAt)
{
while (BH_BenchIter(state))
{
BH_Mat4fFromLookAt(camPos, camAt, camUp, outMat);
BH_BenchDoNotOptimize(outMat);
}
}
BH_BENCH_TEST(ApplyVec4f)
{
while (BH_BenchIter(state))
{
BH_Mat4fApplyVec4f(matA, vec4, outVec4);
BH_BenchDoNotOptimize(outVec4);
}
}
BH_BENCH_TEST(ApplyVec3f)
{
while (BH_BenchIter(state))
{
BH_Mat4fApplyVec3f(matA, vec3, outVec3);
BH_BenchDoNotOptimize(outVec3);
}
}
int main(int argc, char **argv)
{
BH_UNUSED(argc);
BH_UNUSED(argv);
BH_BENCH_ADD(Identity);
BH_BENCH_ADD(Add);
BH_BENCH_ADD(Sub);
BH_BENCH_ADD(Mul);
BH_BENCH_ADD(Scale);
BH_BENCH_ADD(Transpose);
BH_BENCH_ADD(Trace);
BH_BENCH_ADD(Det);
BH_BENCH_ADD(Inverse);
BH_BENCH_ADD(FromScale);
BH_BENCH_ADD(FromTranslation);
BH_BENCH_ADD(FromRotationX);
BH_BENCH_ADD(FromRotationY);
BH_BENCH_ADD(FromRotationZ);
BH_BENCH_ADD(FromAxis);
BH_BENCH_ADD(FromEuler);
BH_BENCH_ADD(FromQuat4f);
BH_BENCH_ADD(FromOrtho);
BH_BENCH_ADD(FromFrustum);
BH_BENCH_ADD(FromLookAt);
BH_BENCH_ADD(ApplyVec4f);
BH_BENCH_ADD(ApplyVec3f);
return BH_BenchRun();
}

57
bench/tests/BenchPlane.c Normal file
View File

@@ -0,0 +1,57 @@
#include <BH/Bench.h>
#include <BH/Math/Plane.h>
static float pointA[3] = {1.0f, 2.0f, 3.0f};
static float pointB[3] = {4.0f, 6.0f, 2.0f};
static float pointC[3] = {2.0f, 1.0f, -1.0f};
static float testPoint[3] = {5.0f, -3.0f, 7.0f};
static float planeNormal[4] = {1.0f, -2.0f, 1.0f, 4.0f};
static float outPlane[4];
static float outPoint[3];
BH_BENCH_TEST(FromPoints)
{
while (BH_BenchIter(state))
{
int result;
result = BH_PlaneFromPoints(pointA, pointB, pointC, outPlane);
BH_BenchDoNotOptimize(result);
BH_BenchDoNotOptimize(outPlane);
}
}
BH_BENCH_TEST(Distance)
{
while (BH_BenchIter(state))
{
float result;
result = BH_PlaneDistance(planeNormal, testPoint);
BH_BenchDoNotOptimize(result);
}
}
BH_BENCH_TEST(ClosestPoint)
{
while (BH_BenchIter(state))
{
BH_PlaneClosestPoint(planeNormal, testPoint, outPoint);
BH_BenchDoNotOptimize(outPoint);
}
}
int main(int argc, char **argv)
{
BH_UNUSED(argc);
BH_UNUSED(argv);
BH_BENCH_ADD(FromPoints);
BH_BENCH_ADD(Distance);
BH_BENCH_ADD(ClosestPoint);
return BH_BenchRun();
}

117
bench/tests/BenchQueue.c Normal file
View File

@@ -0,0 +1,117 @@
#include <BH/Bench.h>
#include <BH/Queue.h>
#define NUM_ENTRIES 1000
static int values[NUM_ENTRIES];
static BH_Queue *queue;
static void *frontValue;
static void *iter;
static void *iterValue;
static void setupData()
{
int i;
queue = BH_QueueNew();
for (i = 0; i < NUM_ENTRIES; ++i)
{
values[i] = i + 1;
BH_QueueInsert(queue, &values[i]);
}
}
BH_BENCH_TEST(NewFree)
{
while (BH_BenchIter(state))
{
queue = BH_QueueNew();
BH_BenchDoNotOptimize(queue);
if (queue) BH_QueueFree(queue);
}
}
BH_BENCH_TEST(ReserveInsert)
{
BH_BenchSubcount(state, NUM_ENTRIES);
while (BH_BenchIter(state))
{
int i;
queue = BH_QueueNew();
BH_QueueReserve(queue, NUM_ENTRIES);
for (i = 0; i < NUM_ENTRIES; ++i)
{
values[i] = i + 1;
BH_QueueInsert(queue, &values[i]);
}
BH_BenchDoNotOptimize(queue);
BH_QueueFree(queue);
}
}
BH_BENCH_TEST(FrontRemove)
{
BH_BenchSubcount(state, NUM_ENTRIES);
while (BH_BenchIter(state))
{
int i;
queue = BH_QueueNew();
for (i = 0; i < NUM_ENTRIES; ++i)
{
values[i] = i + 1;
BH_QueueInsert(queue, &values[i]);
}
for (i = 0; i < NUM_ENTRIES; ++i)
{
if (BH_QueueFront(queue, &frontValue) == 0)
{
BH_QueueRemove(queue);
}
}
BH_BenchDoNotOptimize(frontValue);
BH_BenchDoNotOptimize(queue);
BH_QueueFree(queue);
}
}
BH_BENCH_TEST(Iterate)
{
setupData();
BH_BenchSubcount(state, NUM_ENTRIES);
while (BH_BenchIter(state))
{
iter = NULL;
iterValue = NULL;
while ((iter = BH_QueueIterNext(queue, iter)) != NULL)
{
iterValue = BH_QueueIterValue(iter);
}
BH_BenchDoNotOptimize(iterValue);
}
BH_QueueFree(queue);
}
int main(int argc, char **argv)
{
BH_UNUSED(argc);
BH_UNUSED(argv);
BH_BENCH_ADD(NewFree);
BH_BENCH_ADD(ReserveInsert);
BH_BENCH_ADD(FrontRemove);
BH_BENCH_ADD(Iterate);
return BH_BenchRun();
}

143
bench/tests/BenchRay2f.c Normal file
View File

@@ -0,0 +1,143 @@
#include <BH/Bench.h>
#include <BH/Math/Ray2f.h>
static float rayAStart[2] = {1.0f, 1.0f};
static float rayADir[2] = {1.0f, 0.5f};
static float rayBStart[2] = {3.0f, 0.0f};
static float rayBDir[2] = {-0.5f, 1.0f};
static float lineEq[3] = {1.0f, 1.0f, -4.0f};
static float segStart[2] = {0.0f, 3.0f};
static float segEnd[2] = {5.0f, 2.0f};
static float boxMin[2] = {2.0f, 2.0f};
static float boxMax[2] = {6.0f, 5.0f};
static float outPoint[2];
BH_BENCH_TEST(IntersectLine)
{
while (BH_BenchIter(state))
{
float t;
int result;
result = BH_Ray2fIntersectLine(rayAStart, rayADir, lineEq, &t, outPoint);
BH_BenchDoNotOptimize(result);
BH_BenchDoNotOptimize(t);
BH_BenchDoNotOptimize(outPoint);
}
}
BH_BENCH_TEST(IntersectTime)
{
while (BH_BenchIter(state))
{
float time1, time2;
int result;
result = BH_Ray2fIntersectTime(rayAStart, rayADir, rayBStart, rayBDir, &time1, &time2);
BH_BenchDoNotOptimize(result);
BH_BenchDoNotOptimize(time1);
BH_BenchDoNotOptimize(time2);
}
}
BH_BENCH_TEST(IntersectRay)
{
while (BH_BenchIter(state))
{
float t;
int result;
result = BH_Ray2fIntersectRay(rayAStart, rayADir, rayBStart, rayBDir, &t, outPoint);
BH_BenchDoNotOptimize(result);
BH_BenchDoNotOptimize(t);
BH_BenchDoNotOptimize(outPoint);
}
}
BH_BENCH_TEST(IntersectSegment)
{
while (BH_BenchIter(state))
{
float t;
int result;
result = BH_Ray2fIntersectSegment(rayAStart, rayADir, segStart, segEnd, &t, outPoint);
BH_BenchDoNotOptimize(result);
BH_BenchDoNotOptimize(t);
BH_BenchDoNotOptimize(outPoint);
}
}
BH_BENCH_TEST(SegmentIntersectLine)
{
while (BH_BenchIter(state))
{
float t;
int result;
result = BH_Segment2fIntersectLine(segStart, segEnd, lineEq, &t, outPoint);
BH_BenchDoNotOptimize(result);
BH_BenchDoNotOptimize(t);
BH_BenchDoNotOptimize(outPoint);
}
}
BH_BENCH_TEST(SegmentIntersectSegment)
{
while (BH_BenchIter(state))
{
float t;
int result;
result = BH_Segment2fIntersectSegment(segStart, segEnd, rayAStart, rayBStart, &t, outPoint);
BH_BenchDoNotOptimize(result);
BH_BenchDoNotOptimize(t);
BH_BenchDoNotOptimize(outPoint);
}
}
BH_BENCH_TEST(IntersectBox2f)
{
while (BH_BenchIter(state))
{
float t;
int result;
result = BH_Ray2fIntersectBox2f(rayAStart, rayADir, boxMin, boxMax, &t, outPoint);
BH_BenchDoNotOptimize(result);
BH_BenchDoNotOptimize(t);
BH_BenchDoNotOptimize(outPoint);
}
}
BH_BENCH_TEST(SegmentIntersectBox2f)
{
while (BH_BenchIter(state))
{
float t;
int result;
result = BH_Segment2fIntersectBox2f(segStart, segEnd, boxMin, boxMax, &t, outPoint);
BH_BenchDoNotOptimize(result);
BH_BenchDoNotOptimize(t);
BH_BenchDoNotOptimize(outPoint);
}
}
int main(int argc, char **argv)
{
BH_UNUSED(argc);
BH_UNUSED(argv);
BH_BENCH_ADD(IntersectLine);
BH_BENCH_ADD(IntersectTime);
BH_BENCH_ADD(IntersectRay);
BH_BENCH_ADD(IntersectSegment);
BH_BENCH_ADD(SegmentIntersectLine);
BH_BENCH_ADD(SegmentIntersectSegment);
BH_BENCH_ADD(IntersectBox2f);
BH_BENCH_ADD(SegmentIntersectBox2f);
return BH_BenchRun();
}

115
bench/tests/BenchRay3f.c Normal file
View File

@@ -0,0 +1,115 @@
#include <BH/Bench.h>
#include <BH/Math/Ray3f.h>
static float rayStart[3] = {0.0f, 0.0f, 0.0f};
static float rayDir[3] = {1.0f, 1.0f, 1.0f};
static float segStart[3] = {-2.0f, -2.0f, -2.0f};
static float segEnd[3] = {2.0f, 2.0f, 2.0f};
static float planeEq[4] = {1.0f, 1.0f, 1.0f, -3.0f};
static float triA[3] = {1.0f, 1.0f, 1.0f};
static float triB[3] = {2.0f, 1.0f, 0.0f};
static float triC[3] = {0.0f, 2.0f, 1.0f};
static float boxMin[3] = {1.0f, 1.0f, 1.0f};
static float boxMax[3] = {3.0f, 3.0f, 3.0f};
static float outPoint[3];
BH_BENCH_TEST(IntersectPlane)
{
while (BH_BenchIter(state))
{
float t;
int result;
result = BH_Ray3fIntersectPlane(rayStart, rayDir, planeEq, &t, outPoint);
BH_BenchDoNotOptimize(result);
BH_BenchDoNotOptimize(t);
BH_BenchDoNotOptimize(outPoint);
}
}
BH_BENCH_TEST(IntersectTriangle)
{
while (BH_BenchIter(state))
{
float t;
int result;
result = BH_Ray3fIntersectTriangle(rayStart, rayDir, triA, triB, triC, &t, outPoint);
BH_BenchDoNotOptimize(result);
BH_BenchDoNotOptimize(t);
BH_BenchDoNotOptimize(outPoint);
}
}
BH_BENCH_TEST(SegmentIntersectPlane)
{
while (BH_BenchIter(state))
{
float t;
int result;
result = BH_Segment3fIntersectPlane(segStart, segEnd, planeEq, &t, outPoint);
BH_BenchDoNotOptimize(result);
BH_BenchDoNotOptimize(t);
BH_BenchDoNotOptimize(outPoint);
}
}
BH_BENCH_TEST(SegmentIntersectTriangle)
{
while (BH_BenchIter(state))
{
float t;
int result;
result = BH_Segment3fIntersectTriangle(segStart, segEnd, triA, triB, triC, &t, outPoint);
BH_BenchDoNotOptimize(result);
BH_BenchDoNotOptimize(t);
BH_BenchDoNotOptimize(outPoint);
}
}
BH_BENCH_TEST(IntersectBox3f)
{
while (BH_BenchIter(state))
{
float t;
int result;
result = BH_Ray3fIntersectBox3f(rayStart, rayDir, boxMin, boxMax, &t, outPoint);
BH_BenchDoNotOptimize(result);
BH_BenchDoNotOptimize(t);
BH_BenchDoNotOptimize(outPoint);
}
}
BH_BENCH_TEST(SegmentIntersectBox3f)
{
while (BH_BenchIter(state))
{
float t;
int result;
result = BH_Segment3fIntersectBox3f(segStart, segEnd, boxMin, boxMax, &t, outPoint);
BH_BenchDoNotOptimize(result);
BH_BenchDoNotOptimize(t);
BH_BenchDoNotOptimize(outPoint);
}
}
int main(int argc, char **argv)
{
BH_UNUSED(argc);
BH_UNUSED(argv);
BH_BENCH_ADD(IntersectPlane);
BH_BENCH_ADD(IntersectTriangle);
BH_BENCH_ADD(SegmentIntersectPlane);
BH_BENCH_ADD(SegmentIntersectTriangle);
BH_BENCH_ADD(IntersectBox3f);
BH_BENCH_ADD(SegmentIntersectBox3f);
return BH_BenchRun();
}

286
bench/tests/BenchString.c Normal file
View File

@@ -0,0 +1,286 @@
#include <BH/Bench.h>
#include <BH/String.h>
#define BUF_SIZE 64
static char buffer[BUF_SIZE];
static size_t actual;
static double testDouble = 1234.5678;
static int8_t testInt8s = -128;
static int16_t testInt16s = -32768;
static int32_t testInt32s = -2147483647;
static int64_t testInt64s = -9223372036854775807LL;
static uint8_t testInt8u = 255;
static uint16_t testInt16u = 65535;
static uint32_t testInt32u = 4294967295U;
static uint64_t testInt64u = 18446744073709551615ULL;
static const char *strDouble = "1234.5678";
static const char *strInt8s = "-128";
static const char *strInt16s = "-32768";
static const char *strInt32s = "-2147483647";
static const char *strInt64s = "-9223372036854775807";
static const char *strInt8u = "255";
static const char *strInt16u = "65535";
static const char *strInt32u = "4294967295";
static const char *strInt64u = "18446744073709551615";
static size_t parsedSize;
BH_BENCH_TEST(StringFromDouble)
{
while (BH_BenchIter(state))
{
int result;
result = BH_StringFromDouble(buffer, BUF_SIZE, testDouble, 'f', 6, &actual);
BH_BenchDoNotOptimize(result);
BH_BenchDoNotOptimize(buffer);
BH_BenchDoNotOptimize(actual);
}
}
BH_BENCH_TEST(StringFromInt8s)
{
while (BH_BenchIter(state))
{
int result;
result = BH_StringFromInt8s(buffer, BUF_SIZE, testInt8s, 10, &actual);
BH_BenchDoNotOptimize(result);
BH_BenchDoNotOptimize(buffer);
BH_BenchDoNotOptimize(actual);
}
}
BH_BENCH_TEST(StringFromInt16s)
{
while (BH_BenchIter(state))
{
int result;
result = BH_StringFromInt16s(buffer, BUF_SIZE, testInt16s, 10, &actual);
BH_BenchDoNotOptimize(result);
BH_BenchDoNotOptimize(buffer);
BH_BenchDoNotOptimize(actual);
}
}
BH_BENCH_TEST(StringFromInt32s)
{
while (BH_BenchIter(state))
{
int result;
result = BH_StringFromInt32s(buffer, BUF_SIZE, testInt32s, 10, &actual);
BH_BenchDoNotOptimize(result);
BH_BenchDoNotOptimize(buffer);
BH_BenchDoNotOptimize(actual);
}
}
BH_BENCH_TEST(StringFromInt64s)
{
while (BH_BenchIter(state))
{
int result;
result = BH_StringFromInt64s(buffer, BUF_SIZE, testInt64s, 10, &actual);
BH_BenchDoNotOptimize(result);
BH_BenchDoNotOptimize(buffer);
BH_BenchDoNotOptimize(actual);
}
}
BH_BENCH_TEST(StringFromInt8u)
{
while (BH_BenchIter(state))
{
int result;
result = BH_StringFromInt8u(buffer, BUF_SIZE, testInt8u, 10, &actual);
BH_BenchDoNotOptimize(result);
BH_BenchDoNotOptimize(buffer);
BH_BenchDoNotOptimize(actual);
}
}
BH_BENCH_TEST(StringFromInt16u)
{
while (BH_BenchIter(state))
{
int result;
result = BH_StringFromInt16u(buffer, BUF_SIZE, testInt16u, 10, &actual);
BH_BenchDoNotOptimize(result);
BH_BenchDoNotOptimize(buffer);
BH_BenchDoNotOptimize(actual);
}
}
BH_BENCH_TEST(StringFromInt32u)
{
while (BH_BenchIter(state))
{
int result;
result = BH_StringFromInt32u(buffer, BUF_SIZE, testInt32u, 10, &actual);
BH_BenchDoNotOptimize(result);
BH_BenchDoNotOptimize(buffer);
BH_BenchDoNotOptimize(actual);
}
}
BH_BENCH_TEST(StringFromInt64u)
{
while (BH_BenchIter(state))
{
int result;
result = BH_StringFromInt64u(buffer, BUF_SIZE, testInt64u, 10, &actual);
BH_BenchDoNotOptimize(result);
BH_BenchDoNotOptimize(buffer);
BH_BenchDoNotOptimize(actual);
}
}
BH_BENCH_TEST(StringToDouble)
{
while (BH_BenchIter(state))
{
double result;
parsedSize = 0;
result = BH_StringToDouble(strDouble, &parsedSize);
BH_BenchDoNotOptimize(result);
BH_BenchDoNotOptimize(parsedSize);
}
}
BH_BENCH_TEST(StringToInt8s)
{
while (BH_BenchIter(state))
{
int8_t result;
parsedSize = 0;
result = BH_StringToInt8s(strInt8s, &parsedSize, 10);
BH_BenchDoNotOptimize(result);
BH_BenchDoNotOptimize(parsedSize);
}
}
BH_BENCH_TEST(StringToInt16s)
{
while (BH_BenchIter(state))
{
int16_t result;
parsedSize = 0;
result = BH_StringToInt16s(strInt16s, &parsedSize, 10);
BH_BenchDoNotOptimize(result);
BH_BenchDoNotOptimize(parsedSize);
}
}
BH_BENCH_TEST(StringToInt32s)
{
while (BH_BenchIter(state))
{
int32_t result;
parsedSize = 0;
result = BH_StringToInt32s(strInt32s, &parsedSize, 10);
BH_BenchDoNotOptimize(result);
BH_BenchDoNotOptimize(parsedSize);
}
}
BH_BENCH_TEST(StringToInt64s)
{
while (BH_BenchIter(state))
{
int64_t result;
parsedSize = 0;
result = BH_StringToInt64s(strInt64s, &parsedSize, 10);
BH_BenchDoNotOptimize(result);
BH_BenchDoNotOptimize(parsedSize);
}
}
BH_BENCH_TEST(StringToInt8u)
{
while (BH_BenchIter(state))
{
uint8_t result;
parsedSize = 0;
result = BH_StringToInt8u(strInt8u, &parsedSize, 10);
BH_BenchDoNotOptimize(result);
BH_BenchDoNotOptimize(parsedSize);
}
}
BH_BENCH_TEST(StringToInt16u)
{
while (BH_BenchIter(state))
{
uint16_t result;
parsedSize = 0;
result = BH_StringToInt16u(strInt16u, &parsedSize, 10);
BH_BenchDoNotOptimize(result);
BH_BenchDoNotOptimize(parsedSize);
}
}
BH_BENCH_TEST(StringToInt32u)
{
while (BH_BenchIter(state))
{
uint32_t result;
parsedSize = 0;
result = BH_StringToInt32u(strInt32u, &parsedSize, 10);
BH_BenchDoNotOptimize(result);
BH_BenchDoNotOptimize(parsedSize);
}
}
BH_BENCH_TEST(StringToInt64u)
{
while (BH_BenchIter(state))
{
uint64_t result;
parsedSize = 0;
result = BH_StringToInt64u(strInt64u, &parsedSize, 10);
BH_BenchDoNotOptimize(result);
BH_BenchDoNotOptimize(parsedSize);
}
}
int main(void)
{
BH_BENCH_ADD(StringFromDouble);
BH_BENCH_ADD(StringFromInt8s);
BH_BENCH_ADD(StringFromInt16s);
BH_BENCH_ADD(StringFromInt32s);
BH_BENCH_ADD(StringFromInt64s);
BH_BENCH_ADD(StringFromInt8u);
BH_BENCH_ADD(StringFromInt16u);
BH_BENCH_ADD(StringFromInt32u);
BH_BENCH_ADD(StringFromInt64u);
BH_BENCH_ADD(StringToDouble);
BH_BENCH_ADD(StringToInt8s);
BH_BENCH_ADD(StringToInt16s);
BH_BENCH_ADD(StringToInt32s);
BH_BENCH_ADD(StringToInt64s);
BH_BENCH_ADD(StringToInt8u);
BH_BENCH_ADD(StringToInt16u);
BH_BENCH_ADD(StringToInt32u);
BH_BENCH_ADD(StringToInt64u);
return BH_BenchRun();
}

381
bench/tests/BenchUnicode.c Normal file
View File

@@ -0,0 +1,381 @@
#include <BH/Bench.h>
#include <BH/Unicode.h>
#define BUF_SIZE 8
static char buffer[BUF_SIZE];
static size_t result;
static uint32_t testUnitLower = 'a';
static uint32_t testUnitUpper = 'A';
static uint32_t testUnitLatin1 = 0x00E9;
static uint32_t testUnitBMP = 0x2603;
static uint32_t testUnitSMP = 0x1F600;
static const char utf8_a[] = { 'a' };
static const char utf8_e_acute[] = { 0xC3, 0xA9 };
static const char utf8_snowman[] = { 0xE2, 0x98, 0x83 };
static const char utf8_grin[] = { 0xF0, 0x9F, 0x98, 0x80 };
static const char utf16_a_le[] = { 'a', 0x00 };
static const char utf16_e_acute_le[] = { 0xE9, 0x00 };
static const char utf16_snowman_le[] = { 0x03, 0x26 };
static const char utf16_grin_le[] = { 0xD8, 0x3D, 0xDE, 0x00 };
static const char utf16_a_be[] = { 0x00, 'a' };
static const char utf16_e_acute_be[] = { 0x00, 0xE9 };
static const char utf16_snowman_be[] = { 0x26, 0x03 };
static const char utf16_grin_be[] = { 0x3D, 0xD8, 0x00, 0xDE };
static const char utf32_a_le[] = { 'a', 0x00, 0x00, 0x00 };
static const char utf32_e_acute_le[] = { 0xE9, 0x00, 0x00, 0x00 };
static const char utf32_snowman_le[] = { 0x03, 0x26, 0x00, 0x00 };
static const char utf32_grin_le[] = { 0x00, 0xF0, 0x01, 0x00 };
static const char utf32_a_be[] = { 0x00, 0x00, 0x00, 'a' };
static const char utf32_e_acute_be[] = { 0x00, 0x00, 0x00, 0xE9 };
static const char utf32_snowman_be[] = { 0x00, 0x00, 0x26, 0x03 };
static const char utf32_grin_be[] = { 0x00, 0x01, 0xF0, 0x00 };
BH_BENCH_TEST(Lower)
{
while (BH_BenchIter(state))
{
uint32_t lower;
lower = BH_UnicodeLower(testUnitUpper);
BH_BenchDoNotOptimize(lower);
}
}
BH_BENCH_TEST(Upper)
{
while (BH_BenchIter(state))
{
uint32_t upper;
upper = BH_UnicodeUpper(testUnitLower);
BH_BenchDoNotOptimize(upper);
}
}
BH_BENCH_TEST(DecodeUtf8Ascii)
{
while (BH_BenchIter(state))
{
result = BH_UnicodeDecodeUtf8(utf8_a, 1, &testUnitLower);
BH_BenchDoNotOptimize(result);
BH_BenchDoNotOptimize(testUnitLower);
}
}
BH_BENCH_TEST(DecodeUtf8Latin1)
{
while (BH_BenchIter(state))
{
result = BH_UnicodeDecodeUtf8(utf8_e_acute, 2, &testUnitLatin1);
BH_BenchDoNotOptimize(result);
BH_BenchDoNotOptimize(testUnitLatin1);
}
}
BH_BENCH_TEST(DecodeUtf8BMP)
{
while (BH_BenchIter(state))
{
result = BH_UnicodeDecodeUtf8(utf8_snowman, 3, &testUnitBMP);
BH_BenchDoNotOptimize(result);
BH_BenchDoNotOptimize(testUnitBMP);
}
}
BH_BENCH_TEST(DecodeUtf8SMP)
{
while (BH_BenchIter(state))
{
result = BH_UnicodeDecodeUtf8(utf8_grin, 4, &testUnitSMP);
BH_BenchDoNotOptimize(result);
BH_BenchDoNotOptimize(testUnitSMP);
}
}
BH_BENCH_TEST(EncodeUtf8Ascii)
{
while (BH_BenchIter(state))
{
result = BH_UnicodeEncodeUtf8(testUnitLower, buffer);
BH_BenchDoNotOptimize(result);
BH_BenchDoNotOptimize(buffer);
}
}
BH_BENCH_TEST(EncodeUtf8Latin1)
{
while (BH_BenchIter(state))
{
result = BH_UnicodeEncodeUtf8(testUnitLatin1, buffer);
BH_BenchDoNotOptimize(result);
BH_BenchDoNotOptimize(buffer);
}
}
BH_BENCH_TEST(EncodeUtf8BMP)
{
while (BH_BenchIter(state))
{
result = BH_UnicodeEncodeUtf8(testUnitBMP, buffer);
BH_BenchDoNotOptimize(result);
BH_BenchDoNotOptimize(buffer);
}
}
BH_BENCH_TEST(EncodeUtf8SMP)
{
while (BH_BenchIter(state))
{
result = BH_UnicodeEncodeUtf8(testUnitSMP, buffer);
BH_BenchDoNotOptimize(result);
BH_BenchDoNotOptimize(buffer);
}
}
BH_BENCH_TEST(DecodeUtf16LEAscii)
{
while (BH_BenchIter(state))
{
result = BH_UnicodeDecodeUtf16LE(utf16_a_le, 2, &testUnitLower);
BH_BenchDoNotOptimize(result);
BH_BenchDoNotOptimize(testUnitLower);
}
}
BH_BENCH_TEST(DecodeUtf16LELatin1)
{
while (BH_BenchIter(state))
{
result = BH_UnicodeDecodeUtf16LE(utf16_e_acute_le, 2, &testUnitLatin1);
BH_BenchDoNotOptimize(result);
BH_BenchDoNotOptimize(testUnitLatin1);
}
}
BH_BENCH_TEST(DecodeUtf16LEBMP)
{
while (BH_BenchIter(state))
{
result = BH_UnicodeDecodeUtf16LE(utf16_snowman_le, 2, &testUnitBMP);
BH_BenchDoNotOptimize(result);
BH_BenchDoNotOptimize(testUnitBMP);
}
}
BH_BENCH_TEST(DecodeUtf16LESMP)
{
while (BH_BenchIter(state))
{
result = BH_UnicodeDecodeUtf16LE(utf16_grin_le, 4, &testUnitSMP);
BH_BenchDoNotOptimize(result);
BH_BenchDoNotOptimize(testUnitSMP);
}
}
BH_BENCH_TEST(DecodeUtf16BEAscii)
{
while (BH_BenchIter(state))
{
result = BH_UnicodeDecodeUtf16BE(utf16_a_be, 2, &testUnitLower);
BH_BenchDoNotOptimize(result);
BH_BenchDoNotOptimize(testUnitLower);
}
}
BH_BENCH_TEST(DecodeUtf16BESMP)
{
while (BH_BenchIter(state))
{
result = BH_UnicodeDecodeUtf16BE(utf16_grin_be, 4, &testUnitSMP);
BH_BenchDoNotOptimize(result);
BH_BenchDoNotOptimize(testUnitSMP);
}
}
BH_BENCH_TEST(EncodeUtf16LEAscii)
{
while (BH_BenchIter(state))
{
result = BH_UnicodeEncodeUtf16LE(testUnitLower, buffer);
BH_BenchDoNotOptimize(result);
BH_BenchDoNotOptimize(buffer);
}
}
BH_BENCH_TEST(EncodeUtf16LESMP)
{
while (BH_BenchIter(state))
{
result = BH_UnicodeEncodeUtf16LE(testUnitSMP, buffer);
BH_BenchDoNotOptimize(result);
BH_BenchDoNotOptimize(buffer);
}
}
BH_BENCH_TEST(EncodeUtf16BEAscii)
{
while (BH_BenchIter(state))
{
result = BH_UnicodeEncodeUtf16BE(testUnitLower, buffer);
BH_BenchDoNotOptimize(result);
BH_BenchDoNotOptimize(buffer);
}
}
BH_BENCH_TEST(EncodeUtf16BESMP)
{
while (BH_BenchIter(state))
{
result = BH_UnicodeEncodeUtf16BE(testUnitSMP, buffer);
BH_BenchDoNotOptimize(result);
BH_BenchDoNotOptimize(buffer);
}
}
BH_BENCH_TEST(DecodeUtf32LEAscii)
{
while (BH_BenchIter(state))
{
result = BH_UnicodeDecodeUtf32LE(utf32_a_le, 4, &testUnitLower);
BH_BenchDoNotOptimize(result);
BH_BenchDoNotOptimize(testUnitLower);
}
}
BH_BENCH_TEST(DecodeUtf32LESMP)
{
while (BH_BenchIter(state))
{
result = BH_UnicodeDecodeUtf32LE(utf32_grin_le, 4, &testUnitSMP);
BH_BenchDoNotOptimize(result);
BH_BenchDoNotOptimize(testUnitSMP);
}
}
BH_BENCH_TEST(DecodeUtf32BEAscii)
{
while (BH_BenchIter(state))
{
result = BH_UnicodeDecodeUtf32BE(utf32_a_be, 4, &testUnitLower);
BH_BenchDoNotOptimize(result);
BH_BenchDoNotOptimize(testUnitLower);
}
}
BH_BENCH_TEST(DecodeUtf32BESMP)
{
while (BH_BenchIter(state))
{
result = BH_UnicodeDecodeUtf32BE(utf32_grin_be, 4, &testUnitSMP);
BH_BenchDoNotOptimize(result);
BH_BenchDoNotOptimize(testUnitSMP);
}
}
BH_BENCH_TEST(EncodeUtf32LEAscii)
{
while (BH_BenchIter(state))
{
result = BH_UnicodeEncodeUtf32LE(testUnitLower, buffer);
BH_BenchDoNotOptimize(result);
BH_BenchDoNotOptimize(buffer);
}
}
BH_BENCH_TEST(EncodeUtf32LESMP)
{
while (BH_BenchIter(state))
{
result = BH_UnicodeEncodeUtf32LE(testUnitSMP, buffer);
BH_BenchDoNotOptimize(result);
BH_BenchDoNotOptimize(buffer);
}
}
BH_BENCH_TEST(EncodeUtf32BEAscii)
{
while (BH_BenchIter(state))
{
result = BH_UnicodeEncodeUtf32BE(testUnitLower, buffer);
BH_BenchDoNotOptimize(result);
BH_BenchDoNotOptimize(buffer);
}
}
BH_BENCH_TEST(EncodeUtf32BESMP)
{
while (BH_BenchIter(state))
{
result = BH_UnicodeEncodeUtf32BE(testUnitSMP, buffer);
BH_BenchDoNotOptimize(result);
BH_BenchDoNotOptimize(buffer);
}
}
int main(int argc, char **argv)
{
BH_UNUSED(argc);
BH_UNUSED(argv);
BH_BENCH_ADD(Lower);
BH_BENCH_ADD(Upper);
BH_BENCH_ADD(DecodeUtf8Ascii);
BH_BENCH_ADD(DecodeUtf8Latin1);
BH_BENCH_ADD(DecodeUtf8BMP);
BH_BENCH_ADD(DecodeUtf8SMP);
BH_BENCH_ADD(EncodeUtf8Ascii);
BH_BENCH_ADD(EncodeUtf8Latin1);
BH_BENCH_ADD(EncodeUtf8BMP);
BH_BENCH_ADD(EncodeUtf8SMP);
BH_BENCH_ADD(DecodeUtf16LEAscii);
BH_BENCH_ADD(DecodeUtf16LELatin1);
BH_BENCH_ADD(DecodeUtf16LEBMP);
BH_BENCH_ADD(DecodeUtf16LESMP);
BH_BENCH_ADD(DecodeUtf16BEAscii);
BH_BENCH_ADD(DecodeUtf16BESMP);
BH_BENCH_ADD(EncodeUtf16LEAscii);
BH_BENCH_ADD(EncodeUtf16LESMP);
BH_BENCH_ADD(EncodeUtf16BEAscii);
BH_BENCH_ADD(EncodeUtf16BESMP);
BH_BENCH_ADD(DecodeUtf32LEAscii);
BH_BENCH_ADD(DecodeUtf32LESMP);
BH_BENCH_ADD(DecodeUtf32BEAscii);
BH_BENCH_ADD(DecodeUtf32BESMP);
BH_BENCH_ADD(EncodeUtf32LEAscii);
BH_BENCH_ADD(EncodeUtf32LESMP);
BH_BENCH_ADD(EncodeUtf32BEAscii);
BH_BENCH_ADD(EncodeUtf32BESMP);
return BH_BenchRun();
}

View File

@@ -1,139 +0,0 @@
#include <BH/Bench.h>
#include <BH/Math/Vec2i.h>
#include <BH/Math/Vec3i.h>
#include <BH/Math/Vec4i.h>
#include <BH/Math/Vec2f.h>
#include <BH/Math/Vec3f.h>
#include <BH/Math/Vec4f.h>
#include <stdlib.h>
BH_BENCH_TEST(Vec2i)
{
int a[2], b[2];
a[0] = (rand() % 100);
a[1] = (rand() % 100);
b[0] = (rand() % 100);
b[1] = (rand() % 100);
while (BH_BenchIter(state))
{
BH_Vec2iAdd(a, b, a);
}
}
BH_BENCH_TEST(Vec3i)
{
int a[3], b[3];
a[0] = (rand() % 100);
a[1] = (rand() % 100);
a[2] = (rand() % 100);
b[0] = (rand() % 100);
b[1] = (rand() % 100);
b[2] = (rand() % 100);
while (BH_BenchIter(state))
{
BH_Vec3iAdd(a, b, a);
}
}
BH_BENCH_TEST(Vec4i)
{
int a[4], b[4];
a[0] = (rand() % 100);
a[1] = (rand() % 100);
a[2] = (rand() % 100);
a[3] = (rand() % 100);
b[0] = (rand() % 100);
b[1] = (rand() % 100);
b[2] = (rand() % 100);
b[3] = (rand() % 100);
while (BH_BenchIter(state))
{
BH_Vec4iAdd(a, b, a);
}
}
BH_BENCH_TEST(Vec2f)
{
float a[2], b[2];
a[0] = (rand() % 100) / 200.0;
a[1] = (rand() % 100) / 200.0;
b[0] = (rand() % 100) / 200.0;
b[1] = (rand() % 100) / 200.0;
while (BH_BenchIter(state))
{
BH_Vec2fAdd(a, b, a);
}
}
BH_BENCH_TEST(Vec3f)
{
float a[3], b[3];
a[0] = (rand() % 100) / 200.0;
a[1] = (rand() % 100) / 200.0;
a[2] = (rand() % 100) / 200.0;
b[0] = (rand() % 100) / 200.0;
b[1] = (rand() % 100) / 200.0;
b[2] = (rand() % 100) / 200.0;
while (BH_BenchIter(state))
{
BH_Vec3fAdd(a, b, a);
}
}
BH_BENCH_TEST(Vec4f)
{
float a[4], b[4];
a[0] = (rand() % 100) / 200.0;
a[1] = (rand() % 100) / 200.0;
a[2] = (rand() % 100) / 200.0;
a[3] = (rand() % 100) / 200.0;
b[0] = (rand() % 100) / 200.0;
b[1] = (rand() % 100) / 200.0;
b[2] = (rand() % 100) / 200.0;
b[3] = (rand() % 100) / 200.0;
while (BH_BenchIter(state))
{
BH_Vec4fAdd(a, b, a);
}
}
int main(int argc, char **argv)
{
BH_UNUSED(argc);
BH_UNUSED(argv);
BH_BENCH_ADD(Vec2i);
BH_BENCH_ADD(Vec3i);
BH_BENCH_ADD(Vec4i);
BH_BENCH_ADD(Vec2f);
BH_BENCH_ADD(Vec3f);
BH_BENCH_ADD(Vec4f);
return BH_BenchRun();
}

204
bench/tests/BenchVec2f.c Normal file
View File

@@ -0,0 +1,204 @@
#include <BH/Bench.h>
#include <BH/Math/Vec2f.h>
static float vecA[2] = {1.0f, 2.0f};
static float vecB[2] = {3.0f, -1.0f};
static float vecC[2] = {0.5f, 4.0f};
static float vecZero[2] = {0.0f, 0.0f};
static float vecLarge[2] = {1e6f, -1e6f};
static float vecOut[2];
BH_BENCH_TEST(Add)
{
while (BH_BenchIter(state))
{
BH_Vec2fAdd(vecA, vecB, vecOut);
BH_BenchDoNotOptimize(vecOut);
}
}
BH_BENCH_TEST(Sub)
{
while (BH_BenchIter(state))
{
BH_Vec2fSub(vecA, vecB, vecOut);
BH_BenchDoNotOptimize(vecOut);
}
}
BH_BENCH_TEST(Mul)
{
while (BH_BenchIter(state))
{
BH_Vec2fMul(vecA, vecB, vecOut);
BH_BenchDoNotOptimize(vecOut);
}
}
BH_BENCH_TEST(Scale)
{
const float scale = 2.5f;
while (BH_BenchIter(state))
{
BH_Vec2fScale(vecA, scale, vecOut);
BH_BenchDoNotOptimize(vecOut);
}
}
BH_BENCH_TEST(MulAdd)
{
while (BH_BenchIter(state))
{
BH_Vec2fMulAdd(vecA, vecB, vecC, vecOut);
BH_BenchDoNotOptimize(vecOut);
}
}
BH_BENCH_TEST(Negate)
{
while (BH_BenchIter(state))
{
BH_Vec2fNegate(vecA, vecOut);
BH_BenchDoNotOptimize(vecOut);
}
}
BH_BENCH_TEST(Dot)
{
float result;
while (BH_BenchIter(state))
{
result = BH_Vec2fDot(vecA, vecB);
BH_BenchDoNotOptimize(result);
}
}
BH_BENCH_TEST(Cross)
{
float result;
while (BH_BenchIter(state))
{
result = BH_Vec2fCross(vecA, vecB);
BH_BenchDoNotOptimize(result);
}
}
BH_BENCH_TEST(Length)
{
float result;
while (BH_BenchIter(state))
{
result = BH_Vec2fLength(vecA);
BH_BenchDoNotOptimize(result);
}
}
BH_BENCH_TEST(Normal)
{
while (BH_BenchIter(state))
{
BH_Vec2fNormal(vecA, vecOut);
BH_BenchDoNotOptimize(vecOut);
}
}
BH_BENCH_TEST(NormalEx)
{
float length;
while (BH_BenchIter(state))
{
length = BH_Vec2fNormalEx(vecA, vecOut);
BH_BenchDoNotOptimize(vecOut);
BH_BenchDoNotOptimize(length);
}
}
BH_BENCH_TEST(Min)
{
while (BH_BenchIter(state))
{
BH_Vec2fMin(vecA, vecB, vecOut);
BH_BenchDoNotOptimize(vecOut);
}
}
BH_BENCH_TEST(Max)
{
while (BH_BenchIter(state))
{
BH_Vec2fMax(vecA, vecB, vecOut);
BH_BenchDoNotOptimize(vecOut);
}
}
BH_BENCH_TEST(Lerp)
{
const float t = 0.3f;
while (BH_BenchIter(state))
{
BH_Vec2fLerp(vecA, vecB, t, vecOut);
BH_BenchDoNotOptimize(vecOut);
}
}
BH_BENCH_TEST(Project)
{
while (BH_BenchIter(state))
{
BH_Vec2fProject(vecA, vecB, vecOut);
BH_BenchDoNotOptimize(vecOut);
}
}
BH_BENCH_TEST(Barycentric)
{
const float v = 0.2f, w = 0.3f;
while (BH_BenchIter(state))
{
BH_Vec2fBarycentric(vecA, vecB, vecC, v, w, vecOut);
BH_BenchDoNotOptimize(vecOut);
}
}
int main(int argc, char **argv)
{
BH_UNUSED(argc);
BH_UNUSED(argv);
BH_BENCH_ADD(Add);
BH_BENCH_ADD(Sub);
BH_BENCH_ADD(Mul);
BH_BENCH_ADD(Scale);
BH_BENCH_ADD(MulAdd);
BH_BENCH_ADD(Negate);
BH_BENCH_ADD(Dot);
BH_BENCH_ADD(Cross);
BH_BENCH_ADD(Length);
BH_BENCH_ADD(Normal);
BH_BENCH_ADD(NormalEx);
BH_BENCH_ADD(Min);
BH_BENCH_ADD(Max);
BH_BENCH_ADD(Lerp);
BH_BENCH_ADD(Project);
BH_BENCH_ADD(Barycentric);
return BH_BenchRun();
}

107
bench/tests/BenchVec2i.c Normal file
View File

@@ -0,0 +1,107 @@
#include <BH/Bench.h>
#include <BH/Math/Vec2i.h>
static int vecA[2] = {5, -3};
static int vecB[2] = {2, 7};
static int vecC[2] = {4, 1};
static int vecOut[2];
BH_BENCH_TEST(Add)
{
while (BH_BenchIter(state))
{
BH_Vec2iAdd(vecA, vecB, vecOut);
BH_BenchDoNotOptimize(vecOut);
}
}
BH_BENCH_TEST(Sub)
{
while (BH_BenchIter(state))
{
BH_Vec2iSub(vecA, vecB, vecOut);
BH_BenchDoNotOptimize(vecOut);
}
}
BH_BENCH_TEST(Mul)
{
while (BH_BenchIter(state))
{
BH_Vec2iMul(vecA, vecB, vecOut);
BH_BenchDoNotOptimize(vecOut);
}
}
BH_BENCH_TEST(Scale)
{
const int s = 3;
while (BH_BenchIter(state))
{
BH_Vec2iScale(vecA, s, vecOut);
BH_BenchDoNotOptimize(vecOut);
}
}
BH_BENCH_TEST(MulAdd)
{
while (BH_BenchIter(state))
{
BH_Vec2iMulAdd(vecA, vecB, vecC, vecOut);
BH_BenchDoNotOptimize(vecOut);
}
}
BH_BENCH_TEST(Negate)
{
while (BH_BenchIter(state))
{
BH_Vec2iNegate(vecA, vecOut);
BH_BenchDoNotOptimize(vecOut);
}
}
BH_BENCH_TEST(Min)
{
while (BH_BenchIter(state))
{
BH_Vec2iMin(vecA, vecB, vecOut);
BH_BenchDoNotOptimize(vecOut);
}
}
BH_BENCH_TEST(Max)
{
while (BH_BenchIter(state))
{
BH_Vec2iMax(vecA, vecB, vecOut);
BH_BenchDoNotOptimize(vecOut);
}
}
int main(int argc, char **argv)
{
BH_UNUSED(argc);
BH_UNUSED(argv);
BH_BENCH_ADD(Add);
BH_BENCH_ADD(Sub);
BH_BENCH_ADD(Mul);
BH_BENCH_ADD(Scale);
BH_BENCH_ADD(MulAdd);
BH_BENCH_ADD(Negate);
BH_BENCH_ADD(Min);
BH_BENCH_ADD(Max);
return BH_BenchRun();
}

202
bench/tests/BenchVec3f.c Normal file
View File

@@ -0,0 +1,202 @@
#include <BH/Bench.h>
#include <BH/Math/Vec3f.h>
static float vecA[3] = {1.0f, 2.0f, 3.0f};
static float vecB[3] = {4.0f, -1.0f, 0.5f};
static float vecC[3] = {0.5f, 0.5f, 2.0f};
static float vecOut[3];
BH_BENCH_TEST(Add)
{
while (BH_BenchIter(state))
{
BH_Vec3fAdd(vecA, vecB, vecOut);
BH_BenchDoNotOptimize(vecOut);
}
}
BH_BENCH_TEST(Sub)
{
while (BH_BenchIter(state))
{
BH_Vec3fSub(vecA, vecB, vecOut);
BH_BenchDoNotOptimize(vecOut);
}
}
BH_BENCH_TEST(Mul)
{
while (BH_BenchIter(state))
{
BH_Vec3fMul(vecA, vecB, vecOut);
BH_BenchDoNotOptimize(vecOut);
}
}
BH_BENCH_TEST(Scale)
{
static float scalar = 2.5f;
while (BH_BenchIter(state))
{
BH_Vec3fScale(vecA, scalar, vecOut);
BH_BenchDoNotOptimize(vecOut);
}
}
BH_BENCH_TEST(MulAdd)
{
while (BH_BenchIter(state))
{
BH_Vec3fMulAdd(vecA, vecB, vecC, vecOut);
BH_BenchDoNotOptimize(vecOut);
}
}
BH_BENCH_TEST(Negate)
{
while (BH_BenchIter(state))
{
BH_Vec3fNegate(vecA, vecOut);
BH_BenchDoNotOptimize(vecOut);
}
}
BH_BENCH_TEST(Dot)
{
float result;
while (BH_BenchIter(state))
{
result = BH_Vec3fDot(vecA, vecB);
BH_BenchDoNotOptimize(result);
}
}
BH_BENCH_TEST(Cross)
{
while (BH_BenchIter(state))
{
BH_Vec3fCross(vecA, vecB, vecOut);
BH_BenchDoNotOptimize(vecOut);
}
}
BH_BENCH_TEST(Length)
{
float result;
while (BH_BenchIter(state))
{
result = BH_Vec3fLength(vecA);
BH_BenchDoNotOptimize(result);
}
}
BH_BENCH_TEST(Normal)
{
while (BH_BenchIter(state))
{
BH_Vec3fNormal(vecA, vecOut);
BH_BenchDoNotOptimize(vecOut);
}
}
BH_BENCH_TEST(NormalEx)
{
float result;
while (BH_BenchIter(state))
{
result = BH_Vec3fNormalEx(vecA, vecOut);
BH_BenchDoNotOptimize(result);
BH_BenchDoNotOptimize(vecOut);
}
}
BH_BENCH_TEST(Min)
{
while (BH_BenchIter(state))
{
BH_Vec3fMin(vecA, vecB, vecOut);
BH_BenchDoNotOptimize(vecOut);
}
}
BH_BENCH_TEST(Max)
{
while (BH_BenchIter(state))
{
BH_Vec3fMax(vecA, vecB, vecOut);
BH_BenchDoNotOptimize(vecOut);
}
}
BH_BENCH_TEST(Lerp)
{
static float t = 0.75f;
while (BH_BenchIter(state))
{
BH_Vec3fLerp(vecA, vecB, t, vecOut);
BH_BenchDoNotOptimize(vecOut);
}
}
BH_BENCH_TEST(Project)
{
while (BH_BenchIter(state))
{
BH_Vec3fProject(vecA, vecB, vecOut);
BH_BenchDoNotOptimize(vecOut);
}
}
BH_BENCH_TEST(Barycentric)
{
static float v = 0.3f;
static float w = 0.4f;
while (BH_BenchIter(state))
{
BH_Vec3fBarycentric(vecA, vecB, vecC, v, w, vecOut);
BH_BenchDoNotOptimize(vecOut);
}
}
int main(int argc, char **argv)
{
BH_UNUSED(argc);
BH_UNUSED(argv);
BH_BENCH_ADD(Add);
BH_BENCH_ADD(Sub);
BH_BENCH_ADD(Mul);
BH_BENCH_ADD(Scale);
BH_BENCH_ADD(MulAdd);
BH_BENCH_ADD(Negate);
BH_BENCH_ADD(Dot);
BH_BENCH_ADD(Cross);
BH_BENCH_ADD(Length);
BH_BENCH_ADD(Normal);
BH_BENCH_ADD(NormalEx);
BH_BENCH_ADD(Min);
BH_BENCH_ADD(Max);
BH_BENCH_ADD(Lerp);
BH_BENCH_ADD(Project);
BH_BENCH_ADD(Barycentric);
return BH_BenchRun();
}

108
bench/tests/BenchVec3i.c Normal file
View File

@@ -0,0 +1,108 @@
#include <BH/Bench.h>
#include <BH/Math/Vec3i.h>
static int vecA[3] = {1, 2, 3};
static int vecB[3] = {4, -1, 5};
static int vecC[3] = {2, 3, -1};
static int vecOut[3];
BH_BENCH_TEST(Add)
{
while (BH_BenchIter(state))
{
BH_Vec3iAdd(vecA, vecB, vecOut);
BH_BenchDoNotOptimize(vecOut);
}
}
BH_BENCH_TEST(Sub)
{
while (BH_BenchIter(state))
{
BH_Vec3iSub(vecA, vecB, vecOut);
BH_BenchDoNotOptimize(vecOut);
}
}
BH_BENCH_TEST(Mul)
{
while (BH_BenchIter(state))
{
BH_Vec3iMul(vecA, vecB, vecOut);
BH_BenchDoNotOptimize(vecOut);
}
}
BH_BENCH_TEST(Scale)
{
int scalar = 3;
while (BH_BenchIter(state))
{
BH_Vec3iScale(vecA, scalar, vecOut);
BH_BenchDoNotOptimize(vecOut);
}
}
BH_BENCH_TEST(MulAdd)
{
while (BH_BenchIter(state))
{
BH_Vec3iMulAdd(vecA, vecB, vecC, vecOut);
BH_BenchDoNotOptimize(vecOut);
}
}
BH_BENCH_TEST(Negate)
{
while (BH_BenchIter(state))
{
BH_Vec3iNegate(vecA, vecOut);
BH_BenchDoNotOptimize(vecOut);
}
}
BH_BENCH_TEST(Min)
{
while (BH_BenchIter(state))
{
BH_Vec3iMin(vecA, vecB, vecOut);
BH_BenchDoNotOptimize(vecOut);
}
}
BH_BENCH_TEST(Max)
{
while (BH_BenchIter(state))
{
BH_Vec3iMax(vecA, vecB, vecOut);
BH_BenchDoNotOptimize(vecOut);
}
}
int main(int argc, char **argv)
{
BH_UNUSED(argc);
BH_UNUSED(argv);
BH_BENCH_ADD(Add);
BH_BENCH_ADD(Sub);
BH_BENCH_ADD(Mul);
BH_BENCH_ADD(Scale);
BH_BENCH_ADD(MulAdd);
BH_BENCH_ADD(Negate);
BH_BENCH_ADD(Min);
BH_BENCH_ADD(Max);
return BH_BenchRun();
}

191
bench/tests/BenchVec4f.c Normal file
View File

@@ -0,0 +1,191 @@
#include <BH/Bench.h>
#include <BH/Math/Vec4f.h>
static float vecA[4] = {1.0f, 2.0f, 3.0f, 4.0f};
static float vecB[4] = {4.0f, -1.0f, 0.5f, 2.0f};
static float vecC[4] = {0.5f, 0.5f, 2.0f, 1.0f};
static float vecOut[4];
BH_BENCH_TEST(Add)
{
while (BH_BenchIter(state))
{
BH_Vec4fAdd(vecA, vecB, vecOut);
BH_BenchDoNotOptimize(vecOut);
}
}
BH_BENCH_TEST(Sub)
{
while (BH_BenchIter(state))
{
BH_Vec4fSub(vecA, vecB, vecOut);
BH_BenchDoNotOptimize(vecOut);
}
}
BH_BENCH_TEST(Mul)
{
while (BH_BenchIter(state))
{
BH_Vec4fMul(vecA, vecB, vecOut);
BH_BenchDoNotOptimize(vecOut);
}
}
BH_BENCH_TEST(Scale)
{
float scalar = 2.5f;
while (BH_BenchIter(state))
{
BH_Vec4fScale(vecA, scalar, vecOut);
BH_BenchDoNotOptimize(vecOut);
}
}
BH_BENCH_TEST(MulAdd)
{
while (BH_BenchIter(state))
{
BH_Vec4fMulAdd(vecA, vecB, vecC, vecOut);
BH_BenchDoNotOptimize(vecOut);
}
}
BH_BENCH_TEST(Negate)
{
while (BH_BenchIter(state))
{
BH_Vec4fNegate(vecA, vecOut);
BH_BenchDoNotOptimize(vecOut);
}
}
BH_BENCH_TEST(Dot)
{
while (BH_BenchIter(state))
{
float result = BH_Vec4fDot(vecA, vecB);
BH_BenchDoNotOptimize(result);
}
}
BH_BENCH_TEST(Length)
{
while (BH_BenchIter(state))
{
float result = BH_Vec4fLength(vecA);
BH_BenchDoNotOptimize(result);
}
}
BH_BENCH_TEST(Normal)
{
while (BH_BenchIter(state))
{
BH_Vec4fNormal(vecA, vecOut);
BH_BenchDoNotOptimize(vecOut);
}
}
BH_BENCH_TEST(NormalEx)
{
while (BH_BenchIter(state))
{
float result = BH_Vec4fNormalEx(vecA, vecOut);
BH_BenchDoNotOptimize(result);
BH_BenchDoNotOptimize(vecOut);
}
}
BH_BENCH_TEST(Min)
{
while (BH_BenchIter(state))
{
BH_Vec4fMin(vecA, vecB, vecOut);
BH_BenchDoNotOptimize(vecOut);
}
}
BH_BENCH_TEST(Max)
{
while (BH_BenchIter(state))
{
BH_Vec4fMax(vecA, vecB, vecOut);
BH_BenchDoNotOptimize(vecOut);
}
}
BH_BENCH_TEST(Lerp)
{
float t = 0.75f;
while (BH_BenchIter(state))
{
BH_Vec4fLerp(vecA, vecB, t, vecOut);
BH_BenchDoNotOptimize(vecOut);
}
}
BH_BENCH_TEST(Project)
{
while (BH_BenchIter(state))
{
BH_Vec4fProject(vecA, vecB, vecOut);
BH_BenchDoNotOptimize(vecOut);
}
}
BH_BENCH_TEST(Barycentric)
{
float v = 0.3f;
float w = 0.4f;
while (BH_BenchIter(state))
{
BH_Vec4fBarycentric(vecA, vecB, vecC, v, w, vecOut);
BH_BenchDoNotOptimize(vecOut);
}
}
int main(int argc, char **argv)
{
BH_UNUSED(argc);
BH_UNUSED(argv);
BH_BENCH_ADD(Add);
BH_BENCH_ADD(Sub);
BH_BENCH_ADD(Mul);
BH_BENCH_ADD(Scale);
BH_BENCH_ADD(MulAdd);
BH_BENCH_ADD(Negate);
BH_BENCH_ADD(Dot);
BH_BENCH_ADD(Length);
BH_BENCH_ADD(Normal);
BH_BENCH_ADD(NormalEx);
BH_BENCH_ADD(Min);
BH_BENCH_ADD(Max);
BH_BENCH_ADD(Lerp);
BH_BENCH_ADD(Project);
BH_BENCH_ADD(Barycentric);
return BH_BenchRun();
}

108
bench/tests/BenchVec4i.c Normal file
View File

@@ -0,0 +1,108 @@
#include <BH/Bench.h>
#include <BH/Math/Vec4i.h>
static int vecA[4] = {1, 2, 3, 4};
static int vecB[4] = {4, -1, 5, 2};
static int vecC[4] = {2, 3, -1, 1};
static int vecOut[4];
BH_BENCH_TEST(Add)
{
while (BH_BenchIter(state))
{
BH_Vec4iAdd(vecA, vecB, vecOut);
BH_BenchDoNotOptimize(vecOut);
}
}
BH_BENCH_TEST(Sub)
{
while (BH_BenchIter(state))
{
BH_Vec4iSub(vecA, vecB, vecOut);
BH_BenchDoNotOptimize(vecOut);
}
}
BH_BENCH_TEST(Mul)
{
while (BH_BenchIter(state))
{
BH_Vec4iMul(vecA, vecB, vecOut);
BH_BenchDoNotOptimize(vecOut);
}
}
BH_BENCH_TEST(Scale)
{
int scalar = 3;
while (BH_BenchIter(state))
{
BH_Vec4iScale(vecA, scalar, vecOut);
BH_BenchDoNotOptimize(vecOut);
}
}
BH_BENCH_TEST(MulAdd)
{
while (BH_BenchIter(state))
{
BH_Vec4iMulAdd(vecA, vecB, vecC, vecOut);
BH_BenchDoNotOptimize(vecOut);
}
}
BH_BENCH_TEST(Negate)
{
while (BH_BenchIter(state))
{
BH_Vec4iNegate(vecA, vecOut);
BH_BenchDoNotOptimize(vecOut);
}
}
BH_BENCH_TEST(Min)
{
while (BH_BenchIter(state))
{
BH_Vec4iMin(vecA, vecB, vecOut);
BH_BenchDoNotOptimize(vecOut);
}
}
BH_BENCH_TEST(Max)
{
while (BH_BenchIter(state))
{
BH_Vec4iMax(vecA, vecB, vecOut);
BH_BenchDoNotOptimize(vecOut);
}
}
int main(int argc, char **argv)
{
BH_UNUSED(argc);
BH_UNUSED(argv);
BH_BENCH_ADD(Add);
BH_BENCH_ADD(Sub);
BH_BENCH_ADD(Mul);
BH_BENCH_ADD(Scale);
BH_BENCH_ADD(MulAdd);
BH_BENCH_ADD(Negate);
BH_BENCH_ADD(Min);
BH_BENCH_ADD(Max);
return BH_BenchRun();
}

20
configure vendored
View File

@@ -13,6 +13,7 @@ enable_lfs="no"
enable_tests="yes" enable_tests="yes"
enable_benchmarks="no" enable_benchmarks="no"
enable_pic="yes" enable_pic="yes"
enable_lto="no"
use_clock_gettime="no" use_clock_gettime="no"
use_short_limbs="no" use_short_limbs="no"
arflags=${ARFLAGS:-cr} arflags=${ARFLAGS:-cr}
@@ -25,6 +26,7 @@ ldflagsmt=${LDFLAGSMT:--pthread}
ldlibsmt=${LDLIBSMT} ldlibsmt=${LDLIBSMT}
platform="" platform=""
display_help="no" display_help="no"
release="no"
# Parse arguments # Parse arguments
for option do for option do
@@ -57,9 +59,12 @@ for option do
--use-short-limbs|--use-short-limbs=yes) use_short_limbs="yes" ;; --use-short-limbs|--use-short-limbs=yes) use_short_limbs="yes" ;;
--use-short-limbs=no) use_short_limbs="no" ;; --use-short-limbs=no) use_short_limbs="no" ;;
--source=*) source_path="${option#--source=}" ;; --source=*) source_path="${option#--source=}" ;;
--enable-pic|--with-pic=yes) enable_pic="yes" ;; --enable-pic|--enable-pic=yes) enable_pic="yes" ;;
--enable-pic=no) enable_pic="no" ;; --enable-pic=no) enable_pic="no" ;;
--enable-lto|--enable-lto=yes) enable_lto="yes" ;;
--enable-lto=no) enable_lto="no" ;;
--help|-h) display_help="yes" ;; --help|-h) display_help="yes" ;;
--release) release="yes" ;;
*) echo "configure: WARNING unrecognized option $option" ;; *) echo "configure: WARNING unrecognized option $option" ;;
esac esac
done done
@@ -86,12 +91,14 @@ Options:
--prefix= Install prefix --prefix= Install prefix
--enable-shared[=yes|no] Make shared library --enable-shared[=yes|no] Make shared library
--enable-pic[=yes|no] Enable position independent code (PIC) --enable-pic[=yes|no] Enable position independent code (PIC)
--enable-lto[=yes|no] Enable link time optimizations
--enable-mt[=yes|no] Enable multithreading support --enable-mt[=yes|no] Enable multithreading support
--enable-lfs[=yes|no] Enable large file support --enable-lfs[=yes|no] Enable large file support
--enable-tests[=yes|no] Enable unit tests --enable-tests[=yes|no] Enable unit tests
--enable-benchmarks[=yes|no] Enable benchmarks --enable-benchmarks[=yes|no] Enable benchmarks
--use-clock_gettime[=yes|no] Use of clock_gettime regardless of the support --use-clock_gettime[=yes|no] Use of clock_gettime regardless of the support
--use-short-limbs[=yes|no] Use shorter limbs in big integers --use-short-limbs[=yes|no] Use shorter limbs in big integers
--release Build in release mode
EOF EOF
exit 1 exit 1
fi fi
@@ -132,10 +139,19 @@ fi
cflags="-I${source_path}include -I. $cflags" cflags="-I${source_path}include -I. $cflags"
ldlibs="-lm $ldlibs" ldlibs="-lm $ldlibs"
if [ "$release" = "yes" ]; then
cflags="$cflags -DNDEBUG"
fi
if [ "$enable_pic" = "yes" ]; then if [ "$enable_pic" = "yes" ]; then
cflags="$cflags -fPIC" cflags="$cflags -fPIC"
fi fi
if [ "$enable_lto" = "yes" ]; then
cflags="$cflags -flto"
ldflags="$ldflags -flto"
fi
if [ "$enable_pic" = "no" ] && [ "$enable_shared" = "yes" ]; then if [ "$enable_pic" = "no" ] && [ "$enable_shared" = "yes" ]; then
echo "configure: WARNING: requested shared library while PIC is disabled" echo "configure: WARNING: requested shared library while PIC is disabled"
echo "configure: WARNING: expect build failure" echo "configure: WARNING: expect build failure"
@@ -417,6 +433,7 @@ echo " --- General information --- "
echo "OS: $os" echo "OS: $os"
echo "Platform: $platform" echo "Platform: $platform"
echo "Source path: $source_path" echo "Source path: $source_path"
echo "Release: $release"
echo echo
echo " --- Makefile variables --- " echo " --- Makefile variables --- "
echo "CC: $cc" echo "CC: $cc"
@@ -435,6 +452,7 @@ echo "Enable long file support: $enable_lfs"
echo "Enable tests: $enable_tests" echo "Enable tests: $enable_tests"
echo "Enable benchmarks: $enable_benchmarks" echo "Enable benchmarks: $enable_benchmarks"
echo "Enable PIC: $enable_pic" echo "Enable PIC: $enable_pic"
echo "Enable LTO: $enable_lto"
echo "Build shared library: $enable_shared" echo "Build shared library: $enable_shared"
echo "Use clock_gettime: $use_clock_gettime" echo "Use clock_gettime: $use_clock_gettime"
echo "Use short limbs: $use_short_limbs" echo "Use short limbs: $use_short_limbs"

View File

@@ -177,6 +177,13 @@ The optional parameter I<result> returns 0 or an error code.
This function returns a pointer to a new BH_IO object or NULL. This function returns a pointer to a new BH_IO object or NULL.
=head2 BH_IOIsFile
int BH_IOIsFile(BH_IO *device);
Checks if I/O device is a file.
=head2 BH_BufferNew =head2 BH_BufferNew
BH_IO *BH_BufferNew(BH_IO *device, BH_IO *BH_BufferNew(BH_IO *device,
@@ -193,6 +200,13 @@ If successful, this function returns a pointer to the new BH_IO object or
NULL in case of an error. NULL in case of an error.
=head2 BH_IOIsBuffer
int BH_IOIsBuffer(BH_IO *device);
Checks if I/O device is a buffer.
=head2 BH_BytesNew =head2 BH_BytesNew
BH_IO *BH_BytesNew(char *data, BH_IO *BH_BytesNew(char *data,
@@ -207,6 +221,13 @@ If successful, this function returns a pointer to the new BH_IO object or
NULL in case of an error. NULL in case of an error.
=head2 BH_IOIsBytes
int BH_IOIsBytes(BH_IO *device);
Checks if I/O device is a memory region/bytes.
=head2 BH_IOFree =head2 BH_IOFree
void BH_IOFree(BH_IO *device); void BH_IOFree(BH_IO *device);
@@ -456,6 +477,35 @@ This function is equivalent to the following code:
(BH_IOFlags(device) & BH_IO_FLAG_EOF) (BH_IOFlags(device) & BH_IO_FLAG_EOF)
=head2 BH_IOReadLine
char *BH_IOReadLine(BH_IO *device,
char *str,
size_t size);
Reads a line from I<device> into I<str>, up to I<size-1> bytes.
Stops at I<\n> or EOF. The result is null-terminated. Partial lines may remain
in the stream if longer than buffer.
Returns I<str> on success, NULL on error.
=head2 BH_IOReadLineFull
char *BH_IOReadLineFull(BH_IO *device,
char *str,
size_t size);
Reads a line from I<device> into I<str>, up to I<size-1> bytes.
Stops at I<\n> or EOF. The result is null-terminated. Consumes the entire line
from the stream, discarding excess data if the line is too long. Ensures no
partial line remains.
Returns I<str> on success, NULL on error.
=head1 STRUCTURES =head1 STRUCTURES

View File

@@ -239,11 +239,11 @@ If successful, it returns 0 or an error code.
=head2 BH_StringToDouble =head2 BH_StringToDouble
double BH_StringToDouble(const char *string, double BH_StringToDouble(const char *string,
size_t *size); size_t *actual);
Converts the string I<string> to a real number. Converts the string I<string> to a real number.
The optional parameter I<size> returns the number of characters read from the The optional parameter I<actual> returns the number of characters read from the
string. string.
If successful, it returns the converted number or 0. If successful, it returns the converted number or 0.
@@ -252,131 +252,154 @@ If successful, it returns the converted number or 0.
=head2 BH_StringToInt8s =head2 BH_StringToInt8s
int8_t BH_StringToInt8s(const char *string, int8_t BH_StringToInt8s(const char *string,
size_t *size, int base,
int base); size_t *actual);
Converts the string I<string> to an 8-bit signed integer. Converts the string I<string> to an 8-bit signed integer.
The optional parameter I<size> returns the number of characters read from the
string.
The optional parameter I<base> specifies the base of the number. The optional parameter I<base> specifies the base of the number.
The optional parameter I<actual> returns the number of characters read from the
string.
If successful, it returns the converted number or 0. If successful, it returns the converted number or 0.
=head2 BH_StringToInt16s =head2 BH_StringToInt16s
int16_t BH_StringToInt16s(const char *string, int16_t BH_StringToInt16s(const char *string,
size_t *size, int base,
int base); size_t *actual);
Converts the string I<string> to a signed 16-bit integer. Converts the string I<string> to a signed 16-bit integer.
The optional parameter I<size> returns the number of characters read from the
string.
The optional parameter I<base> specifies the base of the number. The optional parameter I<base> specifies the base of the number.
The optional parameter I<actual> returns the number of characters read from the
string.
If successful, it returns the converted number or 0. If successful, it returns the converted number or 0.
=head2 BH_StringToInt32s =head2 BH_StringToInt32s
int32_t BH_StringToInt32s(const char *string, int32_t BH_StringToInt32s(const char *string,
size_t *size, int base,
int base); size_t *actual);
Converts the string I<string> to a signed 32-bit integer. Converts the string I<string> to a signed 32-bit integer.
The optional parameter I<size> returns the number of characters read from the
string.
The optional parameter I<base> specifies the base of the number. The optional parameter I<base> specifies the base of the number.
The optional parameter I<actual> returns the number of characters read from the
string.
If successful, it returns the converted number or 0. If successful, it returns the converted number or 0.
=head2 BH_StringToInt64s =head2 BH_StringToInt64s
int64_t BH_StringToInt64s(const char *string, int64_t BH_StringToInt64s(const char *string,
size_t *size, int base,
int base); size_t *actual);
Converts the string I<string> to a signed 64-bit integer. Converts the string I<string> to a signed 64-bit integer.
The optional parameter I<size> returns the number of characters read from the
string.
The optional parameter I<base> specifies the base of the number. The optional parameter I<base> specifies the base of the number.
The optional parameter I<actual> returns the number of characters read from the
string.
If successful, it returns the converted number or 0. If successful, it returns the converted number or 0.
=head2 BH_StringToInt8u =head2 BH_StringToInt8u
uint8_t BH_StringToInt8u(const char *string, uint8_t BH_StringToInt8u(const char *string,
size_t *size, int base,
int base); size_t *actual);
Converts the string I<string> to an unsigned 8-bit integer. Converts the string I<string> to an unsigned 8-bit integer.
The optional parameter I<size> returns the number of characters read from the
string.
The optional parameter I<base> specifies the base of the number. The optional parameter I<base> specifies the base of the number.
The optional parameter I<actual> returns the number of characters read from the
string.
If successful, it returns the converted number or 0. If successful, it returns the converted number or 0.
=head2 BH_StringToInt16u =head2 BH_StringToInt16u
uint16_t BH_StringToInt16u(const char *string, uint16_t BH_StringToInt16u(const char *string,
size_t *size, int base,
int base); size_t *actual);
Converts the string I<string> to an unsigned 16-bit integer. Converts the string I<string> to an unsigned 16-bit integer.
The optional parameter I<size> returns the number of characters read from the
string.
The optional parameter I<base> specifies the base of the number. The optional parameter I<base> specifies the base of the number.
The optional parameter I<actual> returns the number of characters read from the
string.
If successful, it returns the converted number or 0. If successful, it returns the converted number or 0.
=head2 BH_StringToInt32u =head2 BH_StringToInt32u
uint32_t BH_StringToInt32u(const char *string, uint32_t BH_StringToInt32u(const char *string,
size_t *size, int base,
int base); size_t *actual);
Converts the string I<string> to an unsigned 32-bit integer. Converts the string I<string> to an unsigned 32-bit integer.
The optional parameter I<size> returns the number of characters read from the
string.
The optional parameter I<base> specifies the base of the number. The optional parameter I<base> specifies the base of the number.
The optional parameter I<actual> returns the number of characters read from the
string.
If successful, it returns the converted number or 0. If successful, it returns the converted number or 0.
=head2 BH_StringToInt64u =head2 BH_StringToInt64u
uint64_t BH_StringToInt64u(const char *string, uint64_t BH_StringToInt64u(const char *string,
size_t *size, int base,
int base); size_t *actual);
Converts the string I<string> to an unsigned 64-bit integer. Converts the string I<string> to an unsigned 64-bit integer.
The optional parameter I<size> returns the number of characters read from the
string.
The optional parameter I<base> specifies the base of the number. The optional parameter I<base> specifies the base of the number.
The optional parameter I<actual> returns the number of characters read from the
string.
If successful, it returns the converted number or 0. If successful, it returns the converted number or 0.
=head2 BH_StringDup
char *BH_StringDup(const char *string);
Creates duplicate of the I<string> (simular to strdup).
=head2 BH_StringCompare
int BH_StringCompare(const char *s1,
const char *s2);
Compares two strings.
=head2 BH_StringCompareCaseless
int BH_StringCompareCaseless(const char *s1,
const char *s2);
Compares two case-insensitive strings.
=head1 SEE ALSO =head1 SEE ALSO
L<BH> L<BH>

View File

@@ -178,6 +178,13 @@ BH_IO предоставляет разработчику возможность
Данная функция возвращает указатель на новый BH_IO объект или NULL. Данная функция возвращает указатель на новый BH_IO объект или NULL.
=head2 BH_IOIsFile
int BH_IOIsFile(BH_IO *device);
Проверяет, является ли устройство ввода-вывода файлом.
=head2 BH_BufferNew =head2 BH_BufferNew
BH_IO *BH_BufferNew(BH_IO *device, BH_IO *BH_BufferNew(BH_IO *device,
@@ -195,6 +202,13 @@ I<device>.
NULL в случае ошибки. NULL в случае ошибки.
=head2 BH_IOIsBuffer
int BH_IOIsBuffer(BH_IO *device);
Проверяет, является ли устройство ввода-вывода буфером.
=head2 BH_BytesNew =head2 BH_BytesNew
BH_IO *BH_BytesNew(char *data, BH_IO *BH_BytesNew(char *data,
@@ -209,6 +223,13 @@ NULL в случае ошибки.
NULL в случае ошибки. NULL в случае ошибки.
=head2 BH_IOIsBytes
int BH_IOIsBytes(BH_IO *device);
Проверяет, является ли устройство ввода-вывода регионом памяти.
=head2 BH_IOFree =head2 BH_IOFree
void BH_IOFree(BH_IO *device); void BH_IOFree(BH_IO *device);
@@ -460,6 +481,36 @@ I<size>.
(BH_IOFlags(device) & BH_IO_FLAG_EOF) (BH_IOFlags(device) & BH_IO_FLAG_EOF)
=head2 BH_IOReadLine
char *BH_IOReadLine(BH_IO *device,
char *str,
size_t size);
Читает строку размером до I<size - 1> байт из устройства ввода-вывода и
записывает данные в I<str>. Результирующая строка нуль-терминированная.
Останавливается на символе I<\n> или конце потока (EOF). Если строка длиннее
буфера, её остаток остаётся в устройстве ввода-вывода для последующего чтения.
Данная функция возвращает указатель на новый I<str> или NULL.
=head2 BH_IOReadLineFull
char *BH_IOReadLineFull(BH_IO *device,
char *str,
size_t size);
Читает строку размером до I<size - 1> байт из устройства ввода-вывода и
записывает данные в I<str>. Результирующая строка нуль-терминированная.
Останавливается на символе I<\n> или конце потока (EOF). Полностью читает строку
из устройства ввода-вывода, отбрасывая избыточные данные.
Данная функция возвращает указатель на новый I<str> или NULL.
=head1 СТРУКТУРЫ ДАННЫХ =head1 СТРУКТУРЫ ДАННЫХ

View File

@@ -243,7 +243,7 @@ I<string> (с ограничением по длинне I<size>).
Преобразовывает строку I<string> в вещественное число. Преобразовывает строку I<string> в вещественное число.
Опциональный параметр I<size> возвращает число прочитанных символов из строки. Опциональный параметр I<actual> возвращает число прочитанных символов из строки.
В случае успеха, возвращает преобразованное число или 0. В случае успеха, возвращает преобразованное число или 0.
@@ -251,123 +251,146 @@ I<string> (с ограничением по длинне I<size>).
=head2 BH_StringToInt8s =head2 BH_StringToInt8s
int8_t BH_StringToInt8s(const char *string, int8_t BH_StringToInt8s(const char *string,
size_t *size, int base,
int base); size_t *actual);
Преобразовывает строку I<string> в целое знаковое 8-битное число. Преобразовывает строку I<string> в целое знаковое 8-битное число.
Опциональный параметр I<size> возвращает число прочитанных символов из строки.
Опциональный параметр I<base> задает основание числа. Опциональный параметр I<base> задает основание числа.
Опциональный параметр I<actual> возвращает число прочитанных символов из строки.
В случае успеха, возвращает преобразованное число или 0. В случае успеха, возвращает преобразованное число или 0.
=head2 BH_StringToInt16s =head2 BH_StringToInt16s
int16_t BH_StringToInt16s(const char *string, int16_t BH_StringToInt16s(const char *string,
size_t *size, int base,
int base); size_t *actual);
Преобразовывает строку I<string> в целое знаковое 16-битное число. Преобразовывает строку I<string> в целое знаковое 16-битное число.
Опциональный параметр I<size> возвращает число прочитанных символов из строки.
Опциональный параметр I<base> задает основание числа. Опциональный параметр I<base> задает основание числа.
Опциональный параметр I<actual> возвращает число прочитанных символов из строки.
В случае успеха, возвращает преобразованное число или 0. В случае успеха, возвращает преобразованное число или 0.
=head2 BH_StringToInt32s =head2 BH_StringToInt32s
int32_t BH_StringToInt32s(const char *string, int32_t BH_StringToInt32s(const char *string,
size_t *size, int base,
int base); size_t *actual);
Преобразовывает строку I<string> в целое знаковое 32-битное число. Преобразовывает строку I<string> в целое знаковое 32-битное число.
Опциональный параметр I<size> возвращает число прочитанных символов из строки.
Опциональный параметр I<base> задает основание числа. Опциональный параметр I<base> задает основание числа.
Опциональный параметр I<actual> возвращает число прочитанных символов из строки.
В случае успеха, возвращает преобразованное число или 0. В случае успеха, возвращает преобразованное число или 0.
=head2 BH_StringToInt64s =head2 BH_StringToInt64s
int64_t BH_StringToInt64s(const char *string, int64_t BH_StringToInt64s(const char *string,
size_t *size, int base,
int base); size_t *actual);
Преобразовывает строку I<string> в целое знаковое 64-битное число. Преобразовывает строку I<string> в целое знаковое 64-битное число.
Опциональный параметр I<size> возвращает число прочитанных символов из строки.
Опциональный параметр I<base> задает основание числа. Опциональный параметр I<base> задает основание числа.
Опциональный параметр I<actual> возвращает число прочитанных символов из строки.
В случае успеха, возвращает преобразованное число или 0. В случае успеха, возвращает преобразованное число или 0.
=head2 BH_StringToInt8u =head2 BH_StringToInt8u
uint8_t BH_StringToInt8u(const char *string, uint8_t BH_StringToInt8u(const char *string,
size_t *size, int base,
int base); size_t *actual);
Преобразовывает строку I<string> в целое беззнаковое 8-битное число. Преобразовывает строку I<string> в целое беззнаковое 8-битное число.
Опциональный параметр I<size> возвращает число прочитанных символов из строки.
Опциональный параметр I<base> задает основание числа. Опциональный параметр I<base> задает основание числа.
Опциональный параметр I<actual> возвращает число прочитанных символов из строки.
В случае успеха, возвращает преобразованное число или 0. В случае успеха, возвращает преобразованное число или 0.
=head2 BH_StringToInt16u =head2 BH_StringToInt16u
uint16_t BH_StringToInt16u(const char *string, uint16_t BH_StringToInt16u(const char *string,
size_t *size, int base,
int base); size_t *actual);
Преобразовывает строку I<string> в целое беззнаковое 16-битное число. Преобразовывает строку I<string> в целое беззнаковое 16-битное число.
Опциональный параметр I<size> возвращает число прочитанных символов из строки.
Опциональный параметр I<base> задает основание числа. Опциональный параметр I<base> задает основание числа.
Опциональный параметр I<actual> возвращает число прочитанных символов из строки.
В случае успеха, возвращает преобразованное число или 0. В случае успеха, возвращает преобразованное число или 0.
=head2 BH_StringToInt32u =head2 BH_StringToInt32u
uint32_t BH_StringToInt32u(const char *string, uint32_t BH_StringToInt32u(const char *string,
size_t *size, int base,
int base); size_t *actual);
Преобразовывает строку I<string> в целое беззнаковое 32-битное число. Преобразовывает строку I<string> в целое беззнаковое 32-битное число.
Опциональный параметр I<size> возвращает число прочитанных символов из строки.
Опциональный параметр I<base> задает основание числа. Опциональный параметр I<base> задает основание числа.
Опциональный параметр I<actual> возвращает число прочитанных символов из строки.
В случае успеха, возвращает преобразованное число или 0. В случае успеха, возвращает преобразованное число или 0.
=head2 BH_StringToInt64u =head2 BH_StringToInt64u
uint64_t BH_StringToInt64u(const char *string, uint64_t BH_StringToInt64u(const char *string,
size_t *size, int base,
int base); size_t *actual);
Преобразовывает строку I<string> в целое беззнаковое 64-битное число. Преобразовывает строку I<string> в целое беззнаковое 64-битное число.
Опциональный параметр I<size> возвращает число прочитанных символов из строки.
Опциональный параметр I<base> задает основание числа. Опциональный параметр I<base> задает основание числа.
Опциональный параметр I<actual> возвращает число прочитанных символов из строки.
В случае успеха, возвращает преобразованное число или 0. В случае успеха, возвращает преобразованное число или 0.
=head2 BH_StringDup
char *BH_StringDup(const char *string);
Создает копию строки I<string> (схоже с strdup).
=head2 BH_StringCompare
int BH_StringCompare(const char *s1,
const char *s2);
Сравнивает две строки.
=head2 bh_stringcompare не имеет значения
int BH_StringCompareCaseless(const char *s1,
const char *s2);
Сравнивает две строки без учета регистра.
=head1 СМ. ТАКЖЕ =head1 СМ. ТАКЖЕ
L<BH> L<BH>

View File

@@ -86,16 +86,25 @@ BH_IO *BH_FileNew(const char *path,
int *result); int *result);
int BH_IOIsFile(BH_IO *device);
BH_IO *BH_BufferNew(BH_IO *device, BH_IO *BH_BufferNew(BH_IO *device,
size_t size, size_t size,
int *result); int *result);
int BH_IOIsBuffer(BH_IO *device);
BH_IO *BH_BytesNew(char *data, BH_IO *BH_BytesNew(char *data,
size_t size, size_t size,
int *result); int *result);
int BH_IOIsBytes(BH_IO *device);
void BH_IOFree(BH_IO *device); void BH_IOFree(BH_IO *device);
@@ -155,4 +164,14 @@ int BH_IOEndOfFile(BH_IO *device);
int BH_IOClear(BH_IO *device); int BH_IOClear(BH_IO *device);
char *BH_IOReadLine(BH_IO *device,
char *str,
size_t size);
char *BH_IOReadLineFull(BH_IO *device,
char *str,
size_t size);
#endif /* BH_IO_H */ #endif /* BH_IO_H */

76
include/BH/Ini.h Normal file
View File

@@ -0,0 +1,76 @@
#ifndef BH_INI_H
#define BH_INI_H
#include "IO.h"
typedef struct BH_Ini BH_Ini;
BH_Ini *BH_IniNew(void);
void BH_IniFree(BH_Ini *ini);
int BH_IniLoad(BH_Ini *ini,
BH_IO *io);
int BH_IniSave(BH_Ini *ini,
BH_IO *io);
int BH_IniSetString(BH_Ini *ini,
const char *section,
const char *key,
const char *value);
const char *BH_IniString(BH_Ini *ini,
const char *section,
const char *key);
void BH_IniRemoveSection(BH_Ini *ini,
const char *section);
void BH_IniRemoveKey(BH_Ini *ini,
const char *section,
const char *key);
void *BH_IniSectionIterNext(BH_Ini *ini,
void *iter);
void *BH_IniSectionIterAt(BH_Ini *ini,
const char *section);
const char *BH_IniSectionIterName(void *iter);
void BH_IniSectionIterRemove(BH_Ini *ini,
void *iter);
void *BH_IniKVIterNext(void *section,
void *iter);
void *BH_IniKVIterAt(void *section,
const char *key);
const char *BH_IniKVIterKey(void *iter);
const char *BH_IniKVIterValue(void *iter);
void BH_IniKVIterRemove(void *section,
void *iter);
#endif /* BH_INI_H */

View File

@@ -70,47 +70,58 @@ int BH_StringFromInt64u(char *string,
double BH_StringToDouble(const char *string, double BH_StringToDouble(const char *string,
size_t *size); size_t *actual);
int8_t BH_StringToInt8s(const char *string, int8_t BH_StringToInt8s(const char *string,
size_t *size, int base,
int base); size_t *actual);
int16_t BH_StringToInt16s(const char *string, int16_t BH_StringToInt16s(const char *string,
size_t *size, int base,
int base); size_t *actual);
int32_t BH_StringToInt32s(const char *string, int32_t BH_StringToInt32s(const char *string,
size_t *size, int base,
int base); size_t *actual);
int64_t BH_StringToInt64s(const char *string, int64_t BH_StringToInt64s(const char *string,
size_t *size, int base,
int base); size_t *actual);
uint8_t BH_StringToInt8u(const char *string, uint8_t BH_StringToInt8u(const char *string,
size_t *size, int base,
int base); size_t *actual);
uint16_t BH_StringToInt16u(const char *string, uint16_t BH_StringToInt16u(const char *string,
size_t *size, int base,
int base); size_t *actual);
uint32_t BH_StringToInt32u(const char *string, uint32_t BH_StringToInt32u(const char *string,
size_t *size, int base,
int base); size_t *actual);
uint64_t BH_StringToInt64u(const char *string, uint64_t BH_StringToInt64u(const char *string,
size_t *size, int base,
int base); size_t *actual);
char *BH_StringDup(const char *string);
int BH_StringCompare(const char *s1,
const char *s2);
int BH_StringCompareCaseless(const char *s1,
const char *s2);
#endif /* BH_STRING_H */ #endif /* BH_STRING_H */

View File

@@ -302,3 +302,12 @@ BH_IO *BH_BufferNew(BH_IO *device,
return (BH_IO*)buffer; return (BH_IO*)buffer;
} }
int BH_IOIsBuffer(BH_IO *device)
{
if (!device)
return 0;
return device->callback == (BH_IOCallback)bufferCallback;
}

View File

@@ -215,3 +215,13 @@ BH_IO *BH_BytesNew(char *data,
return (BH_IO*)bytes; return (BH_IO*)bytes;
} }
int BH_IOIsBytes(BH_IO *device)
{
if (!device)
return 0;
return device->callback == (BH_IOCallback)bytesCallback;
}

View File

@@ -178,3 +178,53 @@ int BH_IOEndOfFile(BH_IO *device)
return flags & BH_IO_FLAG_EOF; return flags & BH_IO_FLAG_EOF;
} }
char *BH_IOReadLine(BH_IO *device,
char *str,
size_t size)
{
size_t i, actual;
if (size < 1)
return NULL;
i = 0;
while (i < size - 1)
{
if (BH_IORead(device, str + i, 1, &actual) || actual != 1)
break;
if (str[i++] == '\n')
break;
}
str[i] = 0;
return i ? str : NULL;
}
char *BH_IOReadLineFull(BH_IO *device,
char *str,
size_t size)
{
size_t i, actual;
char data;
if (size < 1)
return NULL;
i = 0;
while (1)
{
if (BH_IORead(device, &data, 1, &actual) || actual != 1)
break;
if (i < size - 1)
str[i++] = data;
if (data == '\n')
break;
}
str[i] = 0;
return i ? str : NULL;
}

View File

@@ -13,3 +13,9 @@ BH_IO *BH_FileNew(const char *path,
return NULL; return NULL;
} }
int BH_IOIsFile(BH_IO *device)
{
return 0;
}

View File

@@ -306,3 +306,12 @@ BH_IO *BH_FileNew(const char *path,
return (BH_IO*)file; return (BH_IO*)file;
} }
int BH_IOIsFile(BH_IO *device)
{
if (!device)
return 0;
return device->callback == (BH_IOCallback)fileCallback;
}

View File

@@ -315,3 +315,12 @@ BH_IO *BH_FileNew(const char *path,
return (BH_IO*)file; return (BH_IO*)file;
} }
int BH_IOIsFile(BH_IO *device)
{
if (!device)
return 0;
return device->callback == (BH_IOCallback)fileCallback;
}

View File

@@ -8,6 +8,7 @@
#include <string.h> #include <string.h>
#include <Config.h>
#include "Inline/Mpi.h" #include "Inline/Mpi.h"
@@ -514,11 +515,11 @@ static int caselessCompare(const char *src,
static int parseFormat(const char *string, static int parseFormat(const char *string,
size_t *size,
char *buffer, char *buffer,
int *sign, int *sign,
int *e, int *e,
int *type) int *type,
size_t *actual)
{ {
const char *current; const char *current;
int esign, dot, count; int esign, dot, count;
@@ -606,15 +607,15 @@ static int parseFormat(const char *string,
*e -= dot; *e -= dot;
done: done:
if (size) if (actual)
*size = current - string; *actual = current - string;
return count; return count;
} }
double BH_StringToDouble(const char *string, double BH_StringToDouble(const char *string,
size_t *size) size_t *actual)
{ {
int type, e, sign, i, count, shift; int type, e, sign, i, count, shift;
Mpi r, s, tmp[5]; Mpi r, s, tmp[5];
@@ -626,7 +627,7 @@ double BH_StringToDouble(const char *string,
assert(string != NULL); assert(string != NULL);
/* Parse from string format */ /* Parse from string format */
count = parseFormat(string, size, buffer, &sign, &e, &type); count = parseFormat(string, buffer, &sign, &e, &type, actual);
/* Handle special values */ /* Handle special values */
if (type == BH_FP_INFINITE) if (type == BH_FP_INFINITE)
@@ -640,8 +641,8 @@ double BH_StringToDouble(const char *string,
else if (type == BH_FP_ZERO) else if (type == BH_FP_ZERO)
{ {
/* Hacky solution to indicate we haven't seen any digit */ /* Hacky solution to indicate we haven't seen any digit */
if (size) if (actual)
*size = 0; *actual = 0;
return 0.0; return 0.0;
} }

View File

@@ -3,15 +3,15 @@ signed char sym;
/* Check for valid base and zero out read size */ /* Check for valid base and zero out read size */
result = 0; result = 0;
if (size) if (actual)
*size = 0; *actual = 0;
if (base != 0 && (base < 2 || base > 36)) if (base != 0 && (base < 2 || base > 36))
return 0; return 0;
/* Handle space, sign and base */ /* Handle space, sign and base */
skipSpace(&string, size); skipSpace(&string, actual);
handleSign(&string, size, &sign); handleSign(&string, actual, &sign);
guessBase(&string, size, &base); guessBase(&string, actual, &base);
/* Read digits */ /* Read digits */
while(*string) while(*string)
@@ -21,14 +21,14 @@ while(*string)
if (sym >= base || sym == -1) if (sym >= base || sym == -1)
break; break;
if (size) if (actual)
(*size)++; (*actual)++;
result = result * base + sym; result = result * base + sym;
flag = 1; flag = 1;
} }
/* Zero out size on error */ /* Zero out size on error */
if (!result && !flag && size) if (!result && !flag && actual)
*size = 0; *actual = 0;
return result * sign; return result * sign;

View File

@@ -1,7 +1,6 @@
#include <BH/String.h> #include <BH/String.h>
#include <ctype.h> #include <ctype.h>
#include <limits.h> #include <limits.h>
#include <stdlib.h>
#include <string.h> #include <string.h>
@@ -161,8 +160,8 @@ int BH_StringFromInt64u(char *string,
int8_t BH_StringToInt8s(const char *string, int8_t BH_StringToInt8s(const char *string,
size_t *size, int base,
int base) size_t *actual)
{ {
int8_t result; int8_t result;
#include "Inline/Int.h" #include "Inline/Int.h"
@@ -170,8 +169,8 @@ int8_t BH_StringToInt8s(const char *string,
int16_t BH_StringToInt16s(const char *string, int16_t BH_StringToInt16s(const char *string,
size_t *size, int base,
int base) size_t *actual)
{ {
int16_t result; int16_t result;
#include "Inline/Int.h" #include "Inline/Int.h"
@@ -179,8 +178,8 @@ int16_t BH_StringToInt16s(const char *string,
int32_t BH_StringToInt32s(const char *string, int32_t BH_StringToInt32s(const char *string,
size_t *size, int base,
int base) size_t *actual)
{ {
int32_t result; int32_t result;
#include "Inline/Int.h" #include "Inline/Int.h"
@@ -188,8 +187,8 @@ int32_t BH_StringToInt32s(const char *string,
int64_t BH_StringToInt64s(const char *string, int64_t BH_StringToInt64s(const char *string,
size_t *size, int base,
int base) size_t *actual)
{ {
int64_t result; int64_t result;
#include "Inline/Int.h" #include "Inline/Int.h"
@@ -197,8 +196,8 @@ int64_t BH_StringToInt64s(const char *string,
uint8_t BH_StringToInt8u(const char *string, uint8_t BH_StringToInt8u(const char *string,
size_t *size, int base,
int base) size_t *actual)
{ {
uint8_t result; uint8_t result;
#include "Inline/Int.h" #include "Inline/Int.h"
@@ -206,8 +205,8 @@ uint8_t BH_StringToInt8u(const char *string,
uint16_t BH_StringToInt16u(const char *string, uint16_t BH_StringToInt16u(const char *string,
size_t *size, int base,
int base) size_t *actual)
{ {
uint16_t result; uint16_t result;
#include "Inline/Int.h" #include "Inline/Int.h"
@@ -215,8 +214,8 @@ uint16_t BH_StringToInt16u(const char *string,
uint32_t BH_StringToInt32u(const char *string, uint32_t BH_StringToInt32u(const char *string,
size_t *size, int base,
int base) size_t *actual)
{ {
uint32_t result; uint32_t result;
#include "Inline/Int.h" #include "Inline/Int.h"
@@ -224,8 +223,8 @@ uint32_t BH_StringToInt32u(const char *string,
uint64_t BH_StringToInt64u(const char *string, uint64_t BH_StringToInt64u(const char *string,
size_t *size, int base,
int base) size_t *actual)
{ {
uint64_t result; uint64_t result;
#include "Inline/Int.h" #include "Inline/Int.h"

48
src/String/String.c Normal file
View File

@@ -0,0 +1,48 @@
#include <BH/String.h>
#include <BH/Unicode.h>
#include <string.h>
#include <stdlib.h>
char *BH_StringDup(const char *string)
{
size_t length;
char *result;
if (!string)
return NULL;
length = strlen(string) + 1;
result = malloc(length);
if (result)
memcpy(result, string, length);
return result;
}
int BH_StringCompare(const char *s1,
const char *s2)
{
return strcmp(s1, s2);
}
int BH_StringCompareCaseless(const char *s1,
const char *s2)
{
uint32_t c1, c2;
while (*s1 && *s2)
{
s1 += BH_UnicodeDecodeUtf8(s1, 4, &c1);
s2 += BH_UnicodeDecodeUtf8(s2, 4, &c2);
c1 = BH_UnicodeLower(c1);
c2 = BH_UnicodeLower(c2);
if (c1 != c2)
return (c1 < c2) ? -1 : 1;
}
return (!*s1) ? (!*s2 ? 0 : -1) : 1;
}

View File

@@ -2,10 +2,13 @@
#define BH_UNIT_H #define BH_UNIT_H
#include <stdio.h> #include <stdio.h>
#include <string.h>
#include <math.h> #include <math.h>
typedef int (*BH_UnitCallback)(void); typedef int (*BH_UnitCallback)(void);
#define BH_VERIFY(e) \ #define BH_VERIFY(e) \
do { \ do { \
if (!(e)) { \ if (!(e)) { \
@@ -35,6 +38,20 @@ typedef int (*BH_UnitCallback)(void);
} while(0) } while(0)
#define BH_VERIFY_STR_EQ(actual, expected) \
do { \
const char *a, *b; \
a = (actual); \
b = (expected); \
BH_VERIFY(a != NULL && b != NULL); \
if (strcmp(a, b) != 0) { \
printf("%s:%d\tExpected '%s', got '%s'\n", \
__FILE__, __LINE__, a, b); \
return -1; \
} \
} while(0)
#define BH_UNIT_TEST(name) \ #define BH_UNIT_TEST(name) \
static int unit##name(void) static int unit##name(void)

View File

@@ -7,6 +7,7 @@
BH_UNIT_TEST(Null) BH_UNIT_TEST(Null)
{ {
BH_VERIFY(BH_BufferNew(NULL, 0, NULL) == NULL); BH_VERIFY(BH_BufferNew(NULL, 0, NULL) == NULL);
BH_VERIFY(BH_IOIsBuffer(NULL) == 0);
return 0; return 0;
} }
@@ -21,6 +22,7 @@ BH_UNIT_TEST(Write)
memset(data, 0, 16); memset(data, 0, 16);
BH_VERIFY((io = BH_BytesNew(data, 16, NULL)) != NULL); BH_VERIFY((io = BH_BytesNew(data, 16, NULL)) != NULL);
BH_VERIFY((buffer = BH_BufferNew(io, 4, NULL)) != NULL); BH_VERIFY((buffer = BH_BufferNew(io, 4, NULL)) != NULL);
BH_VERIFY(BH_IOIsBuffer(buffer));
BH_VERIFY(BH_IOWrite(buffer, "1234567", 7, &size) == BH_OK); BH_VERIFY(BH_IOWrite(buffer, "1234567", 7, &size) == BH_OK);
BH_VERIFY(size == 7); BH_VERIFY(size == 7);

View File

@@ -10,6 +10,8 @@ BH_UNIT_TEST(Null)
BH_VERIFY(BH_BytesNew(NULL, 0, NULL) == NULL); BH_VERIFY(BH_BytesNew(NULL, 0, NULL) == NULL);
BH_VERIFY(BH_BytesNew(&data, 0, NULL) == NULL); BH_VERIFY(BH_BytesNew(&data, 0, NULL) == NULL);
BH_VERIFY(BH_BytesNew(NULL, 1234, NULL) == NULL); BH_VERIFY(BH_BytesNew(NULL, 1234, NULL) == NULL);
BH_VERIFY(BH_IOIsBytes(NULL) == 0);
return 0; return 0;
} }
@@ -22,6 +24,7 @@ BH_UNIT_TEST(Read)
size_t size; size_t size;
BH_VERIFY((io = BH_BytesNew(buffer1, 14, NULL)) != NULL); BH_VERIFY((io = BH_BytesNew(buffer1, 14, NULL)) != NULL);
BH_VERIFY(BH_IOIsBytes(io));
BH_VERIFY(BH_IORead(io, buffer2, 14, &size) == BH_OK); BH_VERIFY(BH_IORead(io, buffer2, 14, &size) == BH_OK);
BH_VERIFY(size == 14); BH_VERIFY(size == 14);
BH_VERIFY(memcmp(buffer1, buffer2, 14) == 0); BH_VERIFY(memcmp(buffer1, buffer2, 14) == 0);

View File

@@ -40,6 +40,7 @@ static int checkNull(void)
BH_VERIFY(BH_IOCap(NULL, 0) != BH_OK); BH_VERIFY(BH_IOCap(NULL, 0) != BH_OK);
BH_VERIFY(BH_IOEndOfFile(NULL) != BH_OK); BH_VERIFY(BH_IOEndOfFile(NULL) != BH_OK);
BH_VERIFY(BH_IOError(NULL) != BH_OK); BH_VERIFY(BH_IOError(NULL) != BH_OK);
BH_VERIFY(BH_IOIsFile(NULL) == 0);
BH_IOFree(NULL); BH_IOFree(NULL);
return 0; return 0;
@@ -58,6 +59,7 @@ static int checkNormal(void)
/* Check operations for write only access */ /* Check operations for write only access */
BH_VERIFY((io = BH_FileNew(FILENAME1, BH_FILE_WRITE, NULL)) != NULL); BH_VERIFY((io = BH_FileNew(FILENAME1, BH_FILE_WRITE, NULL)) != NULL);
BH_VERIFY(BH_IOIsFile(io));
BH_VERIFY(BH_IOWrite(io, "1234567890", 10, &actual) == BH_OK); BH_VERIFY(BH_IOWrite(io, "1234567890", 10, &actual) == BH_OK);
BH_VERIFY(actual == 10); BH_VERIFY(actual == 10);

View File

@@ -8,35 +8,35 @@ BH_UNIT_TEST(Int8)
size_t size; size_t size;
BH_VERIFY(BH_StringFromInt8s(str, 9, -13, 16, NULL) == BH_OK); BH_VERIFY(BH_StringFromInt8s(str, 9, -13, 16, NULL) == BH_OK);
BH_VERIFY(BH_StringToInt8s(str, &size, 16) == -13); BH_VERIFY(BH_StringToInt8s(str, 16, &size) == -13);
BH_VERIFY(size == 2); BH_VERIFY(size == 2);
BH_VERIFY(BH_StringFromInt8s(str, 9, -13, 10, NULL) == BH_OK); BH_VERIFY(BH_StringFromInt8s(str, 9, -13, 10, NULL) == BH_OK);
BH_VERIFY(BH_StringToInt8s(str, &size, 10) == -13); BH_VERIFY(BH_StringToInt8s(str, 10, &size) == -13);
BH_VERIFY(size == 3); BH_VERIFY(size == 3);
BH_VERIFY(BH_StringFromInt8s(str, 9, -13, 8, NULL) == BH_OK); BH_VERIFY(BH_StringFromInt8s(str, 9, -13, 8, NULL) == BH_OK);
BH_VERIFY(BH_StringToInt8s(str, &size, 8) == -13); BH_VERIFY(BH_StringToInt8s(str, 8, &size) == -13);
BH_VERIFY(size == 3); BH_VERIFY(size == 3);
BH_VERIFY(BH_StringFromInt8s(str, 9, -13, 2, NULL) == BH_OK); BH_VERIFY(BH_StringFromInt8s(str, 9, -13, 2, NULL) == BH_OK);
BH_VERIFY(BH_StringToInt8s(str, &size, 2) == -13); BH_VERIFY(BH_StringToInt8s(str, 2, &size) == -13);
BH_VERIFY(size == 5); BH_VERIFY(size == 5);
BH_VERIFY(BH_StringFromInt8u(str, 9, 200, 16, NULL) == BH_OK); BH_VERIFY(BH_StringFromInt8u(str, 9, 200, 16, NULL) == BH_OK);
BH_VERIFY(BH_StringToInt8u(str, &size, 16) == 200); BH_VERIFY(BH_StringToInt8u(str, 16, &size) == 200);
BH_VERIFY(size == 2); BH_VERIFY(size == 2);
BH_VERIFY(BH_StringFromInt8u(str, 9, 200, 10, NULL) == BH_OK); BH_VERIFY(BH_StringFromInt8u(str, 9, 200, 10, NULL) == BH_OK);
BH_VERIFY(BH_StringToInt8u(str, &size, 10) == 200); BH_VERIFY(BH_StringToInt8u(str, 10, &size) == 200);
BH_VERIFY(size == 3); BH_VERIFY(size == 3);
BH_VERIFY(BH_StringFromInt8u(str, 9, 200, 8, NULL) == BH_OK); BH_VERIFY(BH_StringFromInt8u(str, 9, 200, 8, NULL) == BH_OK);
BH_VERIFY(BH_StringToInt8u(str, &size, 8) == 200); BH_VERIFY(BH_StringToInt8u(str, 8, &size) == 200);
BH_VERIFY(size == 3); BH_VERIFY(size == 3);
BH_VERIFY(BH_StringFromInt8u(str, 9, 200, 2, NULL) == BH_OK); BH_VERIFY(BH_StringFromInt8u(str, 9, 200, 2, NULL) == BH_OK);
BH_VERIFY(BH_StringToInt8u(str, &size, 2) == 200); BH_VERIFY(BH_StringToInt8u(str, 2, &size) == 200);
BH_VERIFY(size == 8); BH_VERIFY(size == 8);
return 0; return 0;
@@ -49,35 +49,35 @@ BH_UNIT_TEST(Int16)
size_t size; size_t size;
BH_VERIFY(BH_StringFromInt16s(str, 17, -1234, 16, NULL) == BH_OK); BH_VERIFY(BH_StringFromInt16s(str, 17, -1234, 16, NULL) == BH_OK);
BH_VERIFY(BH_StringToInt16s(str, &size, 16) == -1234); BH_VERIFY(BH_StringToInt16s(str, 16, &size) == -1234);
BH_VERIFY(size == 4); BH_VERIFY(size == 4);
BH_VERIFY(BH_StringFromInt16s(str, 17, -1234, 10, NULL) == BH_OK); BH_VERIFY(BH_StringFromInt16s(str, 17, -1234, 10, NULL) == BH_OK);
BH_VERIFY(BH_StringToInt16s(str, &size, 10) == -1234); BH_VERIFY(BH_StringToInt16s(str, 10, &size) == -1234);
BH_VERIFY(size == 5); BH_VERIFY(size == 5);
BH_VERIFY(BH_StringFromInt16s(str, 17, -1234, 8, NULL) == BH_OK); BH_VERIFY(BH_StringFromInt16s(str, 17, -1234, 8, NULL) == BH_OK);
BH_VERIFY(BH_StringToInt16s(str, &size, 8) == -1234); BH_VERIFY(BH_StringToInt16s(str, 8, &size) == -1234);
BH_VERIFY(size == 5); BH_VERIFY(size == 5);
BH_VERIFY(BH_StringFromInt16s(str, 17, -1234, 2, NULL) == BH_OK); BH_VERIFY(BH_StringFromInt16s(str, 17, -1234, 2, NULL) == BH_OK);
BH_VERIFY(BH_StringToInt16s(str, &size, 2) == -1234); BH_VERIFY(BH_StringToInt16s(str, 2, &size) == -1234);
BH_VERIFY(size == 12); BH_VERIFY(size == 12);
BH_VERIFY(BH_StringFromInt16u(str, 17, 43210, 16, NULL) == BH_OK); BH_VERIFY(BH_StringFromInt16u(str, 17, 43210, 16, NULL) == BH_OK);
BH_VERIFY(BH_StringToInt16u(str, &size, 16) == 43210); BH_VERIFY(BH_StringToInt16u(str, 16, &size) == 43210);
BH_VERIFY(size == 4); BH_VERIFY(size == 4);
BH_VERIFY(BH_StringFromInt16u(str, 17, 43210, 10, NULL) == BH_OK); BH_VERIFY(BH_StringFromInt16u(str, 17, 43210, 10, NULL) == BH_OK);
BH_VERIFY(BH_StringToInt16u(str, &size, 10) == 43210); BH_VERIFY(BH_StringToInt16u(str, 10, &size) == 43210);
BH_VERIFY(size == 5); BH_VERIFY(size == 5);
BH_VERIFY(BH_StringFromInt16u(str, 17, 43210, 8, NULL) == BH_OK); BH_VERIFY(BH_StringFromInt16u(str, 17, 43210, 8, NULL) == BH_OK);
BH_VERIFY(BH_StringToInt16u(str, &size, 8) == 43210); BH_VERIFY(BH_StringToInt16u(str, 8, &size) == 43210);
BH_VERIFY(size == 6); BH_VERIFY(size == 6);
BH_VERIFY(BH_StringFromInt16u(str, 17, 43210, 2, NULL) == BH_OK); BH_VERIFY(BH_StringFromInt16u(str, 17, 43210, 2, NULL) == BH_OK);
BH_VERIFY(BH_StringToInt16u(str, &size, 2) == 43210); BH_VERIFY(BH_StringToInt16u(str, 2, &size) == 43210);
BH_VERIFY(size == 16); BH_VERIFY(size == 16);
return 0; return 0;
@@ -90,35 +90,35 @@ BH_UNIT_TEST(Int32)
size_t size; size_t size;
BH_VERIFY(BH_StringFromInt32s(str, 33, -1234567890l, 16, NULL) == BH_OK); BH_VERIFY(BH_StringFromInt32s(str, 33, -1234567890l, 16, NULL) == BH_OK);
BH_VERIFY(BH_StringToInt32s(str, &size, 16) == -1234567890l); BH_VERIFY(BH_StringToInt32s(str, 16, &size) == -1234567890l);
BH_VERIFY(size == 9); BH_VERIFY(size == 9);
BH_VERIFY(BH_StringFromInt32s(str, 33, -1234567890l, 10, NULL) == BH_OK); BH_VERIFY(BH_StringFromInt32s(str, 33, -1234567890l, 10, NULL) == BH_OK);
BH_VERIFY(BH_StringToInt32s(str, &size, 10) == -1234567890l); BH_VERIFY(BH_StringToInt32s(str, 10, &size) == -1234567890l);
BH_VERIFY(size == 11); BH_VERIFY(size == 11);
BH_VERIFY(BH_StringFromInt32s(str, 33, -1234567890l, 8, NULL) == BH_OK); BH_VERIFY(BH_StringFromInt32s(str, 33, -1234567890l, 8, NULL) == BH_OK);
BH_VERIFY(BH_StringToInt32s(str, &size, 8) == -1234567890l); BH_VERIFY(BH_StringToInt32s(str, 8, &size) == -1234567890l);
BH_VERIFY(size == 12); BH_VERIFY(size == 12);
BH_VERIFY(BH_StringFromInt32s(str, 33, -1234567890l, 2, NULL) == BH_OK); BH_VERIFY(BH_StringFromInt32s(str, 33, -1234567890l, 2, NULL) == BH_OK);
BH_VERIFY(BH_StringToInt32s(str, &size, 2) == -1234567890l); BH_VERIFY(BH_StringToInt32s(str, 2, &size) == -1234567890l);
BH_VERIFY(size == 32); BH_VERIFY(size == 32);
BH_VERIFY(BH_StringFromInt32u(str, 33, 3456789012ul, 16, NULL) == BH_OK); BH_VERIFY(BH_StringFromInt32u(str, 33, 3456789012ul, 16, NULL) == BH_OK);
BH_VERIFY(BH_StringToInt32u(str, &size, 16) == 3456789012ul); BH_VERIFY(BH_StringToInt32u(str, 16, &size) == 3456789012ul);
BH_VERIFY(size == 8); BH_VERIFY(size == 8);
BH_VERIFY(BH_StringFromInt32u(str, 33, 3456789012ul, 10, NULL) == BH_OK); BH_VERIFY(BH_StringFromInt32u(str, 33, 3456789012ul, 10, NULL) == BH_OK);
BH_VERIFY(BH_StringToInt32u(str, &size, 10) == 3456789012ul); BH_VERIFY(BH_StringToInt32u(str, 10, &size) == 3456789012ul);
BH_VERIFY(size == 10); BH_VERIFY(size == 10);
BH_VERIFY(BH_StringFromInt32u(str, 33, 3456789012ul, 8, NULL) == BH_OK); BH_VERIFY(BH_StringFromInt32u(str, 33, 3456789012ul, 8, NULL) == BH_OK);
BH_VERIFY(BH_StringToInt32u(str, &size, 8) == 3456789012ul); BH_VERIFY(BH_StringToInt32u(str, 8, &size) == 3456789012ul);
BH_VERIFY(size == 11); BH_VERIFY(size == 11);
BH_VERIFY(BH_StringFromInt32u(str, 33, 3456789012ul, 2, NULL) == BH_OK); BH_VERIFY(BH_StringFromInt32u(str, 33, 3456789012ul, 2, NULL) == BH_OK);
BH_VERIFY(BH_StringToInt32u(str, &size, 2) == 3456789012ul); BH_VERIFY(BH_StringToInt32u(str, 2, &size) == 3456789012ul);
BH_VERIFY(size == 32); BH_VERIFY(size == 32);
return 0; return 0;
@@ -129,34 +129,34 @@ BH_UNIT_TEST(Parsing)
{ {
size_t size; size_t size;
BH_VERIFY(BH_StringToInt32s(" 0x1234", &size, 16) == 0x1234); BH_VERIFY(BH_StringToInt32s(" 0x1234", 16, &size) == 0x1234);
BH_VERIFY(size == 9); BH_VERIFY(size == 9);
BH_VERIFY(BH_StringToInt32s(" 12345", &size, 10) == 12345); BH_VERIFY(BH_StringToInt32s(" 12345", 10, &size) == 12345);
BH_VERIFY(size == 8); BH_VERIFY(size == 8);
BH_VERIFY(BH_StringToInt32s(" 0123", &size, 8) == 0123); BH_VERIFY(BH_StringToInt32s(" 0123", 8, &size) == 0123);
BH_VERIFY(size == 7); BH_VERIFY(size == 7);
BH_VERIFY(BH_StringToInt32s(" 0b1111Hello", &size, 2) == 15); BH_VERIFY(BH_StringToInt32s(" 0b1111Hello", 2, &size) == 15);
BH_VERIFY(size == 9); BH_VERIFY(size == 9);
BH_VERIFY(BH_StringToInt32s(" 0x1234", &size, 0) == 0x1234); BH_VERIFY(BH_StringToInt32s(" 0x1234", 0, &size) == 0x1234);
BH_VERIFY(size == 9); BH_VERIFY(size == 9);
BH_VERIFY(BH_StringToInt32s(" 0123", &size, 0) == 0123); BH_VERIFY(BH_StringToInt32s(" 0123", 0, &size) == 0123);
BH_VERIFY(size == 7); BH_VERIFY(size == 7);
BH_VERIFY(BH_StringToInt32s(" 123", &size, 0) == 123); BH_VERIFY(BH_StringToInt32s(" 123", 0, &size) == 123);
BH_VERIFY(size == 6); BH_VERIFY(size == 6);
BH_VERIFY(BH_StringToInt32s(" 0b1111", &size, 0) == 15); BH_VERIFY(BH_StringToInt32s(" 0b1111", 0, &size) == 15);
BH_VERIFY(size == 9); BH_VERIFY(size == 9);
BH_VERIFY(BH_StringToInt32s(" 12345Hello", &size, 10) == 12345); BH_VERIFY(BH_StringToInt32s(" 12345Hello", 10, &size) == 12345);
BH_VERIFY(size == 8); BH_VERIFY(size == 8);
BH_VERIFY(BH_StringToInt32s(" Hello", &size, 10) == 0); BH_VERIFY(BH_StringToInt32s(" Hello", 10, &size) == 0);
BH_VERIFY(size == 0); BH_VERIFY(size == 0);
return 0; return 0;

76
test/tests/TestReadLine.c Normal file
View File

@@ -0,0 +1,76 @@
#include <BH/Unit.h>
#include <BH/IO.h>
#include <string.h>
static const char testInput[] =
"this is a very long line that exceeds the buffer\n"
"short\n"
"another line\n";
BH_UNIT_TEST(ReadLine)
{
char buffer[32], *result;
BH_IO *io;
BH_VERIFY((io = BH_BytesNew((char*)testInput, strlen(testInput), NULL)));
/* Check splited read */
BH_VERIFY((result = BH_IOReadLine(io, buffer, sizeof(buffer))));
BH_VERIFY_STR_EQ(buffer, "this is a very long line that e");
BH_VERIFY((result = BH_IOReadLine(io, buffer, sizeof(buffer))));
BH_VERIFY_STR_EQ(buffer, "xceeds the buffer\n");
/* Check smaller reads */
BH_VERIFY((result = BH_IOReadLine(io, buffer, sizeof(buffer))));
BH_VERIFY_STR_EQ(buffer, "short\n");
BH_VERIFY((result = BH_IOReadLine(io, buffer, sizeof(buffer))));
BH_VERIFY_STR_EQ(buffer, "another line\n");
/* Check EOF */
BH_VERIFY(!(result = BH_IOReadLine(io, buffer, sizeof(buffer))));
BH_IOFree(io);
return 0;
}
BH_UNIT_TEST(ReadLineFull)
{
char buffer[32], *result;
BH_IO *io;
BH_VERIFY((io = BH_BytesNew((char*)testInput, strlen(testInput), NULL)));
/* Check truncated read */
BH_VERIFY((result = BH_IOReadLineFull(io, buffer, sizeof(buffer))));
BH_VERIFY_STR_EQ(buffer, "this is a very long line that e");
/* Check smaller reads */
BH_VERIFY((result = BH_IOReadLineFull(io, buffer, sizeof(buffer))));
BH_VERIFY_STR_EQ(buffer, "short\n");
BH_VERIFY((result = BH_IOReadLineFull(io, buffer, sizeof(buffer))));
BH_VERIFY_STR_EQ(buffer, "another line\n");
/* Check EOF */
BH_VERIFY(!(result = BH_IOReadLineFull(io, buffer, sizeof(buffer))));
BH_IOFree(io);
return 0;
}
int main(int argc, char **argv)
{
BH_UNUSED(argc);
BH_UNUSED(argv);
BH_UNIT_ADD(ReadLine);
BH_UNIT_ADD(ReadLineFull);
return BH_UnitRun();
}

112
test/tests/TestString.c Normal file
View File

@@ -0,0 +1,112 @@
#include <BH/Unit.h>
#include <BH/String.h>
BH_UNIT_TEST(EqualStrings)
{
BH_VERIFY(BH_StringCompare("hello", "hello") == 0);
BH_VERIFY(BH_StringCompare("", "") == 0);
BH_VERIFY(BH_StringCompare("a", "a") == 0);
BH_VERIFY(BH_StringCompare("123", "123") == 0);
return 0;
}
BH_UNIT_TEST(LessThan)
{
BH_VERIFY(BH_StringCompare("apple", "banana") < 0);
BH_VERIFY(BH_StringCompare("aa", "ab") < 0);
BH_VERIFY(BH_StringCompare("a", "b") < 0);
BH_VERIFY(BH_StringCompare("", "a") < 0);
return 0;
}
BH_UNIT_TEST(GreaterThan)
{
BH_VERIFY(BH_StringCompare("zebra", "apple") > 0);
BH_VERIFY(BH_StringCompare("ab", "aa") > 0);
BH_VERIFY(BH_StringCompare("b", "a") > 0);
BH_VERIFY(BH_StringCompare("a", "") > 0);
return 0;
}
BH_UNIT_TEST(CaselessEqual)
{
BH_VERIFY(BH_StringCompareCaseless("hello", "HELLO") == 0);
BH_VERIFY(BH_StringCompareCaseless("Hello", "hELLO") == 0);
BH_VERIFY(BH_StringCompareCaseless("TEST", "test") == 0);
BH_VERIFY(BH_StringCompareCaseless("", "") == 0);
BH_VERIFY(BH_StringCompareCaseless("MiXeD", "mIxEd") == 0);
return 0;
}
BH_UNIT_TEST(CaselessLessThan)
{
BH_VERIFY(BH_StringCompareCaseless("apple", "BANANA") < 0);
BH_VERIFY(BH_StringCompareCaseless("alpha", "Beta") < 0);
BH_VERIFY(BH_StringCompareCaseless("a", "Z") < 0);
return 0;
}
BH_UNIT_TEST(CaselessGreaterThan)
{
BH_VERIFY(BH_StringCompareCaseless("zebra", "APPLE") > 0);
BH_VERIFY(BH_StringCompareCaseless("Zulu", "alpha") > 0);
BH_VERIFY(BH_StringCompareCaseless("Z", "a") > 0);
return 0;
}
BH_UNIT_TEST(EdgeCases)
{
BH_VERIFY(BH_StringCompare(
"this is a very long string for testing purposes",
"this is a very long string for testing purposes") == 0);
BH_VERIFY(BH_StringCompare("abc123", "abc124") < 0);
BH_VERIFY(BH_StringCompare("test", "testing") < 0);
BH_VERIFY(BH_StringCompare("testing", "test") > 0);
return 0;
}
BH_UNIT_TEST(CaselessEdgeCases)
{
BH_VERIFY(BH_StringCompareCaseless("TEST", "TESTING") < 0);
BH_VERIFY(BH_StringCompareCaseless("TESTING", "test") > 0);
BH_VERIFY(BH_StringCompareCaseless("file1.txt", "file10.txt") < 0);
BH_VERIFY(BH_StringCompareCaseless("AaAa", "AAAA") == 0);
return 0;
}
int main(int argc, char **argv)
{
(void)argc;
(void)argv;
BH_UNIT_ADD(EqualStrings);
BH_UNIT_ADD(LessThan);
BH_UNIT_ADD(GreaterThan);
BH_UNIT_ADD(EdgeCases);
BH_UNIT_ADD(CaselessEqual);
BH_UNIT_ADD(CaselessLessThan);
BH_UNIT_ADD(CaselessGreaterThan);
BH_UNIT_ADD(CaselessEdgeCases);
return BH_UnitRun();
}