Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
123 changes: 87 additions & 36 deletions test/utest.h
Original file line number Diff line number Diff line change
Expand Up @@ -255,8 +255,8 @@ UTEST_C_FUNC __declspec(dllimport) int __stdcall QueryPerformanceFrequency(
static void __cdecl f(void); \
UTEST_INITIALIZER_BEGIN_DISABLE_WARNINGS \
__pragma(comment(linker, "/include:" UTEST_SYMBOL_PREFIX #f "_")) \
UTEST_C_FUNC __declspec(allocate(".CRT$XCU")) void(__cdecl * \
f##_)(void) = f; \
UTEST_C_FUNC \
__declspec(allocate(".CRT$XCU")) void(__cdecl * f##_)(void) = f; \
UTEST_INITIALIZER_END_DISABLE_WARNINGS \
static void __cdecl f(void)
#else
Expand Down Expand Up @@ -321,22 +321,32 @@ static UTEST_INLINE void *utest_realloc(void *const pointer, size_t new_size) {
void *const new_pointer = realloc(pointer, new_size);

if (UTEST_NULL == new_pointer) {
free(new_pointer);
free(pointer);
}

return new_pointer;
}

// Prevent 64-bit integer overflow when computing a timestamp by using a trick
// from Sokol:
// https://github.com/floooh/sokol/blob/189843bf4f86969ca4cc4b6d94e793a37c5128a7/sokol_time.h#L204
static UTEST_INLINE utest_int64_t utest_mul_div(const utest_int64_t value,
const utest_int64_t numer,
const utest_int64_t denom) {
const utest_int64_t q = value / denom;
const utest_int64_t r = value % denom;
return q * numer + r * numer / denom;
}

static UTEST_INLINE utest_int64_t utest_ns(void) {
#if defined(_MSC_VER) || defined(__MINGW64__) || defined(__MINGW32__)
utest_large_integer counter;
utest_large_integer frequency;
QueryPerformanceCounter(&counter);
QueryPerformanceFrequency(&frequency);
return UTEST_CAST(utest_int64_t,
(counter.QuadPart * 1000000000) / frequency.QuadPart);
return utest_mul_div(counter.QuadPart, 1000000000, frequency.QuadPart);
#elif defined(__linux__) && defined(__STRICT_ANSI__)
return UTEST_CAST(utest_int64_t, clock()) * 1000000000 / CLOCKS_PER_SEC;
return utest_mul_div(clock(), 1000000000, CLOCKS_PER_SEC);
#elif defined(__linux__) || defined(__FreeBSD__) || defined(__OpenBSD__) || \
defined(__NetBSD__) || defined(__DragonFly__) || defined(__sun__) || \
defined(__HAIKU__)
Expand Down Expand Up @@ -447,6 +457,15 @@ struct utest_type_deducer final {
static void _(const T t);
};

template <> struct utest_type_deducer<char, false> {
static void _(const char c) {
if (std::is_signed<decltype(c)>::value) {
UTEST_PRINTF("%d", static_cast<int>(c));
} else {
UTEST_PRINTF("%u", static_cast<unsigned int>(c));
}
}
};
template <> struct utest_type_deducer<signed char, false> {
static void _(const signed char c) {
UTEST_PRINTF("%d", static_cast<int>(c));
Expand All @@ -465,7 +484,7 @@ template <> struct utest_type_deducer<short, false> {

template <> struct utest_type_deducer<unsigned short, false> {
static void _(const unsigned short s) {
UTEST_PRINTF("%u", static_cast<int>(s));
UTEST_PRINTF("%u", static_cast<unsigned>(s));
}
};

Expand Down Expand Up @@ -512,6 +531,10 @@ template <> struct utest_type_deducer<unsigned long long, false> {
static void _(const unsigned long long i) { UTEST_PRINTF("%llu", i); }
};

template <> struct utest_type_deducer<bool, false> {
static void _(const bool i) { UTEST_PRINTF(i ? "true" : "false"); }
};

template <typename T> struct utest_type_deducer<const T *, false> {
static void _(const T *t) {
UTEST_PRINTF("%p", static_cast<void *>(const_cast<T *>(t)));
Expand All @@ -528,6 +551,12 @@ template <typename T> struct utest_type_deducer<T, true> {
}
};

template <> struct utest_type_deducer<std::nullptr_t, false> {
static void _(std::nullptr_t t) {
UTEST_PRINTF("%p", static_cast<void *>(t));
}
};

template <typename T>
UTEST_WEAK UTEST_OVERLOADABLE void utest_type_printer(const T t) {
utest_type_deducer<T>::_(t);
Expand Down Expand Up @@ -626,24 +655,23 @@ utest_type_printer(long long unsigned int i) {
!(defined(__MINGW32__) || defined(__MINGW64__)) || \
defined(__TINYC__)
#define utest_type_printer(val) \
UTEST_PRINTF(_Generic((val), signed char \
: "%d", unsigned char \
: "%u", short \
: "%d", unsigned short \
: "%u", int \
: "%d", long \
: "%ld", long long \
: "%lld", unsigned \
: "%u", unsigned long \
: "%lu", unsigned long long \
: "%llu", float \
: "%f", double \
: "%f", long double \
: "%Lf", default \
: _Generic((val - val), ptrdiff_t \
: "%p", default \
: "undef")), \
(val))
UTEST_PRINTF( \
_Generic((val), \
signed char: "%d", \
unsigned char: "%u", \
short: "%d", \
unsigned short: "%u", \
int: "%d", \
long: "%ld", \
long long: "%lld", \
unsigned: "%u", \
unsigned long: "%lu", \
unsigned long long: "%llu", \
float: "%f", \
double: "%f", \
long double: "%Lf", \
default: _Generic((val - val), ptrdiff_t: "%p", default: "undef")), \
(val))
#else
/*
we don't have the ability to print the values we got, so we create a macro
Expand Down Expand Up @@ -724,10 +752,12 @@ utest_strncpy_gcc(char *const dst, const char *const src, const size_t size) {
UTEST_AUTO(x) xEval = (x); \
UTEST_AUTO(y) yEval = (y); \
if (!((xEval)cond(yEval))) { \
const char *const xAsString = #x; \
const char *const yAsString = #y; \
_Pragma("clang diagnostic pop") \
UTEST_PRINTF("%s:%i: Failure\n", __FILE__, __LINE__); \
UTEST_PRINTF(" Expected : ("); \
UTEST_PRINTF(#x ") " #cond " (" #y); \
UTEST_PRINTF("%s) " #cond " (%s", xAsString, yAsString); \
UTEST_PRINTF(")\n"); \
UTEST_PRINTF(" Actual : "); \
utest_type_printer(xEval); \
Expand All @@ -751,9 +781,11 @@ utest_strncpy_gcc(char *const dst, const char *const src, const size_t size) {
UTEST_AUTO(x) xEval = (x); \
UTEST_AUTO(y) yEval = (y); \
if (!((xEval)cond(yEval))) { \
const char *const xAsString = #x; \
const char *const yAsString = #y; \
UTEST_PRINTF("%s:%i: Failure\n", __FILE__, __LINE__); \
UTEST_PRINTF(" Expected : ("); \
UTEST_PRINTF(#x ") " #cond " (" #y); \
UTEST_PRINTF("%s) " #cond " (%s", xAsString, yAsString); \
UTEST_PRINTF(")\n"); \
UTEST_PRINTF(" Actual : "); \
utest_type_printer(xEval); \
Expand Down Expand Up @@ -1138,13 +1170,19 @@ utest_strncpy_gcc(char *const dst, const char *const src, const size_t size) {
utest_realloc(UTEST_PTR_CAST(void *, utest_state.tests), \
sizeof(struct utest_test_state_s) * \
utest_state.tests_length)); \
if (utest_state.tests) { \
if (utest_state.tests && name) { \
utest_state.tests[index].func = &utest_##SET##_##NAME; \
utest_state.tests[index].name = name; \
utest_state.tests[index].index = 0; \
UTEST_SNPRINTF(name, name_size, "%s", name_part); \
} else if (name) { \
free(name); \
} else { \
if (utest_state.tests) { \
free(utest_state.tests); \
utest_state.tests = NULL; \
} \
if (name) { \
free(name); \
} \
} \
} \
UTEST_SURPRESS_WARNINGS_END \
Expand Down Expand Up @@ -1186,12 +1224,19 @@ utest_strncpy_gcc(char *const dst, const char *const src, const size_t size) {
utest_realloc(UTEST_PTR_CAST(void *, utest_state.tests), \
sizeof(struct utest_test_state_s) * \
utest_state.tests_length)); \
if (utest_state.tests) { \
if (utest_state.tests && name) { \
utest_state.tests[index].func = &utest_f_##FIXTURE##_##NAME; \
utest_state.tests[index].name = name; \
utest_state.tests[index].index = 0; \
UTEST_SNPRINTF(name, name_size, "%s", name_part); \
} else if (name) { \
free(name); \
} else { \
if (utest_state.tests) { \
free(utest_state.tests); \
utest_state.tests = NULL; \
} \
if (name) { \
free(name); \
} \
} \
} \
UTEST_SURPRESS_WARNINGS_END \
Expand Down Expand Up @@ -1234,14 +1279,20 @@ utest_strncpy_gcc(char *const dst, const char *const src, const size_t size) {
utest_realloc(UTEST_PTR_CAST(void *, utest_state.tests), \
sizeof(struct utest_test_state_s) * \
utest_state.tests_length)); \
if (utest_state.tests) { \
if (utest_state.tests && name) { \
utest_state.tests[index].func = &utest_i_##FIXTURE##_##NAME##_##INDEX; \
utest_state.tests[index].index = i; \
utest_state.tests[index].name = name; \
iUp = UTEST_CAST(utest_uint64_t, i); \
UTEST_SNPRINTF(name, name_size, "%s/%" UTEST_PRIu64, name_part, iUp); \
} else if (name) { \
free(name); \
} else { \
if (utest_state.tests) { \
free(utest_state.tests); \
utest_state.tests = NULL; \
} \
if (name) { \
free(name); \
} \
} \
} \
} \
Expand Down
Loading