gitout

A static git page generator
git clone https://git.bracken.jp/gitout.git
Log | Files | Refs | README | LICENSE

utest.h (77635B)


      1 /*
      2    The latest version of this library is available on GitHub;
      3    https://github.com/sheredom/utest.h
      4 */
      5 
      6 /*
      7    This is free and unencumbered software released into the public domain.
      8 
      9    Anyone is free to copy, modify, publish, use, compile, sell, or
     10    distribute this software, either in source code form or as a compiled
     11    binary, for any purpose, commercial or non-commercial, and by any
     12    means.
     13 
     14    In jurisdictions that recognize copyright laws, the author or authors
     15    of this software dedicate any and all copyright interest in the
     16    software to the public domain. We make this dedication for the benefit
     17    of the public at large and to the detriment of our heirs and
     18    successors. We intend this dedication to be an overt act of
     19    relinquishment in perpetuity of all present and future rights to this
     20    software under copyright law.
     21 
     22    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
     23    EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
     24    MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
     25    IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR
     26    OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
     27    ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
     28    OTHER DEALINGS IN THE SOFTWARE.
     29 
     30    For more information, please refer to <http://unlicense.org/>
     31 */
     32 
     33 #ifndef SHEREDOM_UTEST_H_INCLUDED
     34 #define SHEREDOM_UTEST_H_INCLUDED
     35 
     36 #ifdef _MSC_VER
     37 /*
     38    Disable warning about not inlining 'inline' functions.
     39 */
     40 #pragma warning(disable : 4710)
     41 
     42 /*
     43    Disable warning about inlining functions that are not marked 'inline'.
     44 */
     45 #pragma warning(disable : 4711)
     46 
     47 /*
     48    Disable warning for alignment padding added
     49 */
     50 #pragma warning(disable : 4820)
     51 
     52 #if _MSC_VER > 1900
     53 /*
     54   Disable warning about preprocessor macros not being defined in MSVC headers.
     55 */
     56 #pragma warning(disable : 4668)
     57 
     58 /*
     59   Disable warning about no function prototype given in MSVC headers.
     60 */
     61 #pragma warning(disable : 4255)
     62 
     63 /*
     64   Disable warning about pointer or reference to potentially throwing function.
     65 */
     66 #pragma warning(disable : 5039)
     67 
     68 /*
     69   Disable warning about macro expansion producing 'defined' has undefined
     70   behavior.
     71 */
     72 #pragma warning(disable : 5105)
     73 #endif
     74 
     75 #if _MSC_VER > 1930
     76 /*
     77   Disable warning about 'const' variable is not used.
     78 */
     79 #pragma warning(disable : 5264)
     80 #endif
     81 
     82 #pragma warning(push, 1)
     83 #endif
     84 
     85 #if defined(_MSC_VER) && (_MSC_VER < 1920)
     86 typedef __int64 utest_int64_t;
     87 typedef unsigned __int64 utest_uint64_t;
     88 typedef unsigned __int32 utest_uint32_t;
     89 #else
     90 #include <stdint.h>
     91 typedef int64_t utest_int64_t;
     92 typedef uint64_t utest_uint64_t;
     93 typedef uint32_t utest_uint32_t;
     94 #endif
     95 
     96 #include <stddef.h>
     97 #include <stdio.h>
     98 #include <stdlib.h>
     99 #include <string.h>
    100 #include <errno.h>
    101 
    102 #if defined(__cplusplus)
    103 #if defined(_MSC_VER) && !defined(_CPPUNWIND)
    104 /* We're on MSVC and the compiler is compiling without exception support! */
    105 #elif !defined(_MSC_VER) && !defined(__EXCEPTIONS)
    106 /* We're on a GCC/Clang compiler that doesn't have exception support! */
    107 #else
    108 #define UTEST_HAS_EXCEPTIONS 1
    109 #endif
    110 #endif
    111 
    112 #if defined(UTEST_HAS_EXCEPTIONS)
    113 #include <stdexcept>
    114 #endif
    115 
    116 #if defined(_MSC_VER)
    117 #pragma warning(pop)
    118 #endif
    119 
    120 #if defined(__cplusplus)
    121 #define UTEST_C_FUNC extern "C"
    122 #else
    123 #define UTEST_C_FUNC
    124 #endif
    125 
    126 #define UTEST_TEST_PASSED (0)
    127 #define UTEST_TEST_FAILURE (1)
    128 #define UTEST_TEST_SKIPPED (2)
    129 
    130 #if defined(__TINYC__)
    131 #define UTEST_ATTRIBUTE(a) __attribute((a))
    132 #else
    133 #define UTEST_ATTRIBUTE(a) __attribute__((a))
    134 #endif
    135 
    136 #if defined(_MSC_VER) || defined(__MINGW64__) || defined(__MINGW32__)
    137 
    138 #if defined(__MINGW64__) || defined(__MINGW32__)
    139 #pragma GCC diagnostic push
    140 #pragma GCC diagnostic ignored "-Wpragmas"
    141 #pragma GCC diagnostic ignored "-Wunknown-pragmas"
    142 #endif
    143 
    144 #if defined(_WINDOWS_) || defined(_WINDOWS_H)
    145 typedef LARGE_INTEGER utest_large_integer;
    146 #else
    147 // use old QueryPerformanceCounter definitions (not sure is this needed in some
    148 // edge cases or not) on Win7 with VS2015 these extern declaration cause "second
    149 // C linkage of overloaded function not allowed" error
    150 typedef union {
    151   struct {
    152     unsigned long LowPart;
    153     long HighPart;
    154   } DUMMYSTRUCTNAME;
    155   struct {
    156     unsigned long LowPart;
    157     long HighPart;
    158   } u;
    159   utest_int64_t QuadPart;
    160 } utest_large_integer;
    161 
    162 UTEST_C_FUNC __declspec(dllimport) int __stdcall QueryPerformanceCounter(
    163     utest_large_integer *);
    164 UTEST_C_FUNC __declspec(dllimport) int __stdcall QueryPerformanceFrequency(
    165     utest_large_integer *);
    166 
    167 #if defined(__MINGW64__) || defined(__MINGW32__)
    168 #pragma GCC diagnostic pop
    169 #endif
    170 #endif
    171 
    172 #elif defined(__linux__) || defined(__FreeBSD__) || defined(__OpenBSD__) ||    \
    173     defined(__NetBSD__) || defined(__DragonFly__) || defined(__sun__) ||       \
    174     defined(__HAIKU__)
    175 /*
    176    slightly obscure include here - we need to include glibc's features.h, but
    177    we don't want to just include a header that might not be defined for other
    178    c libraries like musl. Instead we include limits.h, which we know on all
    179    glibc distributions includes features.h
    180 */
    181 #include <limits.h>
    182 
    183 #if defined(__GLIBC__) && defined(__GLIBC_MINOR__)
    184 #include <time.h>
    185 
    186 #if ((2 < __GLIBC__) || ((2 == __GLIBC__) && (17 <= __GLIBC_MINOR__)))
    187 /* glibc is version 2.17 or above, so we can just use clock_gettime */
    188 #define UTEST_USE_CLOCKGETTIME
    189 #else
    190 #include <sys/syscall.h>
    191 #include <unistd.h>
    192 #endif
    193 #else // Other libc implementations
    194 #include <time.h>
    195 #define UTEST_USE_CLOCKGETTIME
    196 #endif
    197 
    198 #elif defined(__APPLE__)
    199 #include <time.h>
    200 #endif
    201 
    202 #if defined(_MSC_VER) && (_MSC_VER < 1920)
    203 #define UTEST_PRId64 "I64d"
    204 #define UTEST_PRIu64 "I64u"
    205 #else
    206 #include <inttypes.h>
    207 
    208 #define UTEST_PRId64 PRId64
    209 #define UTEST_PRIu64 PRIu64
    210 #endif
    211 
    212 #if defined(__cplusplus)
    213 #define UTEST_INLINE inline
    214 
    215 #if defined(__clang__)
    216 #define UTEST_INITIALIZER_BEGIN_DISABLE_WARNINGS                               \
    217   _Pragma("clang diagnostic push")                                             \
    218       _Pragma("clang diagnostic ignored \"-Wglobal-constructors\"")
    219 
    220 #define UTEST_INITIALIZER_END_DISABLE_WARNINGS _Pragma("clang diagnostic pop")
    221 #else
    222 #define UTEST_INITIALIZER_BEGIN_DISABLE_WARNINGS
    223 #define UTEST_INITIALIZER_END_DISABLE_WARNINGS
    224 #endif
    225 
    226 #define UTEST_INITIALIZER(f)                                                   \
    227   struct f##_cpp_struct {                                                      \
    228     f##_cpp_struct();                                                          \
    229   };                                                                           \
    230   UTEST_INITIALIZER_BEGIN_DISABLE_WARNINGS static f##_cpp_struct               \
    231       f##_cpp_global UTEST_INITIALIZER_END_DISABLE_WARNINGS;                   \
    232   f##_cpp_struct::f##_cpp_struct()
    233 #elif defined(_MSC_VER)
    234 #define UTEST_INLINE __forceinline
    235 
    236 #if defined(_WIN64)
    237 #define UTEST_SYMBOL_PREFIX
    238 #else
    239 #define UTEST_SYMBOL_PREFIX "_"
    240 #endif
    241 
    242 #if defined(__clang__)
    243 #define UTEST_INITIALIZER_BEGIN_DISABLE_WARNINGS                               \
    244   _Pragma("clang diagnostic push")                                             \
    245       _Pragma("clang diagnostic ignored \"-Wmissing-variable-declarations\"")
    246 
    247 #define UTEST_INITIALIZER_END_DISABLE_WARNINGS _Pragma("clang diagnostic pop")
    248 #else
    249 #define UTEST_INITIALIZER_BEGIN_DISABLE_WARNINGS
    250 #define UTEST_INITIALIZER_END_DISABLE_WARNINGS
    251 #endif
    252 
    253 #pragma section(".CRT$XCU", read)
    254 #define UTEST_INITIALIZER(f)                                                   \
    255   static void __cdecl f(void);                                                 \
    256   UTEST_INITIALIZER_BEGIN_DISABLE_WARNINGS                                     \
    257   __pragma(comment(linker, "/include:" UTEST_SYMBOL_PREFIX #f "_"))            \
    258       UTEST_C_FUNC                                                             \
    259       __declspec(allocate(".CRT$XCU")) void(__cdecl * f##_)(void) = f;         \
    260   UTEST_INITIALIZER_END_DISABLE_WARNINGS                                       \
    261   static void __cdecl f(void)
    262 #else
    263 #if defined(__linux__)
    264 #if defined(__clang__)
    265 #if __has_warning("-Wreserved-id-macro")
    266 #pragma clang diagnostic push
    267 #pragma clang diagnostic ignored "-Wreserved-id-macro"
    268 #endif
    269 #endif
    270 
    271 #define __STDC_FORMAT_MACROS 1
    272 
    273 #if defined(__clang__)
    274 #if __has_warning("-Wreserved-id-macro")
    275 #pragma clang diagnostic pop
    276 #endif
    277 #endif
    278 #endif
    279 
    280 #define UTEST_INLINE inline
    281 
    282 #define UTEST_INITIALIZER(f)                                                   \
    283   static void f(void) UTEST_ATTRIBUTE(constructor);                            \
    284   static void f(void)
    285 #endif
    286 
    287 #if defined(__cplusplus)
    288 #define UTEST_CAST(type, x) static_cast<type>(x)
    289 #define UTEST_PTR_CAST(type, x) reinterpret_cast<type>(x)
    290 #define UTEST_EXTERN extern "C"
    291 #define UTEST_NULL NULL
    292 #else
    293 #define UTEST_CAST(type, x) ((type)(x))
    294 #define UTEST_PTR_CAST(type, x) ((type)(x))
    295 #define UTEST_EXTERN extern
    296 #define UTEST_NULL 0
    297 #endif
    298 
    299 #ifdef _MSC_VER
    300 /*
    301     io.h contains definitions for some structures with natural padding. This is
    302     uninteresting, but for some reason MSVC's behaviour is to warn about
    303     including this system header. That *is* interesting
    304 */
    305 #pragma warning(disable : 4820)
    306 #pragma warning(push, 1)
    307 #include <io.h>
    308 #pragma warning(pop)
    309 #define UTEST_COLOUR_OUTPUT() (_isatty(_fileno(stdout)))
    310 #else
    311 #if defined(__EMSCRIPTEN__)
    312 #include <emscripten/html5.h>
    313 #define UTEST_COLOUR_OUTPUT() false
    314 #else
    315 #include <unistd.h>
    316 #define UTEST_COLOUR_OUTPUT() (isatty(STDOUT_FILENO))
    317 #endif
    318 #endif
    319 
    320 static UTEST_INLINE void *utest_realloc(void *const pointer, size_t new_size) {
    321   void *const new_pointer = realloc(pointer, new_size);
    322 
    323   if (UTEST_NULL == new_pointer) {
    324     free(pointer);
    325   }
    326 
    327   return new_pointer;
    328 }
    329 
    330 // Prevent 64-bit integer overflow when computing a timestamp by using a trick
    331 // from Sokol:
    332 // https://github.com/floooh/sokol/blob/189843bf4f86969ca4cc4b6d94e793a37c5128a7/sokol_time.h#L204
    333 static UTEST_INLINE utest_int64_t utest_mul_div(const utest_int64_t value,
    334                                                 const utest_int64_t numer,
    335                                                 const utest_int64_t denom) {
    336   const utest_int64_t q = value / denom;
    337   const utest_int64_t r = value % denom;
    338   return q * numer + r * numer / denom;
    339 }
    340 
    341 static UTEST_INLINE utest_int64_t utest_ns(void) {
    342 #if defined(_MSC_VER) || defined(__MINGW64__) || defined(__MINGW32__)
    343   utest_large_integer counter;
    344   utest_large_integer frequency;
    345   QueryPerformanceCounter(&counter);
    346   QueryPerformanceFrequency(&frequency);
    347   return utest_mul_div(counter.QuadPart, 1000000000, frequency.QuadPart);
    348 #elif defined(__linux__) && defined(__STRICT_ANSI__)
    349   return utest_mul_div(clock(), 1000000000, CLOCKS_PER_SEC);
    350 #elif defined(__linux__) || defined(__FreeBSD__) || defined(__OpenBSD__) ||    \
    351     defined(__NetBSD__) || defined(__DragonFly__) || defined(__sun__) ||       \
    352     defined(__HAIKU__)
    353   struct timespec ts;
    354 #if defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 201112L) &&              \
    355     !defined(__HAIKU__)
    356   timespec_get(&ts, TIME_UTC);
    357 #else
    358   const clockid_t cid = CLOCK_REALTIME;
    359 #if defined(UTEST_USE_CLOCKGETTIME)
    360   clock_gettime(cid, &ts);
    361 #else
    362   syscall(SYS_clock_gettime, cid, &ts);
    363 #endif
    364 #endif
    365   return UTEST_CAST(utest_int64_t, ts.tv_sec) * 1000 * 1000 * 1000 + ts.tv_nsec;
    366 #elif __APPLE__
    367   return UTEST_CAST(utest_int64_t, clock_gettime_nsec_np(CLOCK_UPTIME_RAW));
    368 #elif __EMSCRIPTEN__
    369   return emscripten_performance_now() * 1000000.0;
    370 #else
    371 #error Unsupported platform!
    372 #endif
    373 }
    374 
    375 typedef void (*utest_testcase_t)(int *, size_t);
    376 
    377 struct utest_test_state_s {
    378   utest_testcase_t func;
    379   size_t index;
    380   char *name;
    381 };
    382 
    383 struct utest_state_s {
    384   struct utest_test_state_s *tests;
    385   size_t tests_length;
    386   FILE *output;
    387 };
    388 
    389 /* extern to the global state utest needs to execute */
    390 UTEST_EXTERN struct utest_state_s utest_state;
    391 
    392 #if defined(_MSC_VER)
    393 #define UTEST_WEAK __forceinline
    394 #elif defined(__MINGW32__) || defined(__MINGW64__)
    395 #define UTEST_WEAK static UTEST_ATTRIBUTE(used)
    396 #elif defined(__clang__) || defined(__GNUC__) || defined(__TINYC__)
    397 #define UTEST_WEAK UTEST_ATTRIBUTE(weak)
    398 #else
    399 #error Non clang, non gcc, non MSVC, non tcc compiler found!
    400 #endif
    401 
    402 #if defined(_MSC_VER)
    403 #define UTEST_UNUSED
    404 #else
    405 #define UTEST_UNUSED UTEST_ATTRIBUTE(unused)
    406 #endif
    407 
    408 #ifdef __clang__
    409 #pragma clang diagnostic push
    410 #pragma clang diagnostic ignored "-Wvariadic-macros"
    411 #pragma clang diagnostic ignored "-Wc++98-compat-pedantic"
    412 #endif
    413 #define UTEST_PRINTF(...)                                                      \
    414   if (utest_state.output) {                                                    \
    415     fprintf(utest_state.output, __VA_ARGS__);                                  \
    416   }                                                                            \
    417   printf(__VA_ARGS__)
    418 #ifdef __clang__
    419 #pragma clang diagnostic pop
    420 #endif
    421 
    422 #ifdef __clang__
    423 #pragma clang diagnostic push
    424 #pragma clang diagnostic ignored "-Wvariadic-macros"
    425 #pragma clang diagnostic ignored "-Wc++98-compat-pedantic"
    426 #endif
    427 
    428 #ifdef _MSC_VER
    429 #define UTEST_SNPRINTF(BUFFER, N, ...) _snprintf_s(BUFFER, N, N, __VA_ARGS__)
    430 #else
    431 #define UTEST_SNPRINTF(...) snprintf(__VA_ARGS__)
    432 #endif
    433 
    434 #ifdef __clang__
    435 #pragma clang diagnostic pop
    436 #endif
    437 
    438 #if defined(__cplusplus)
    439 /* if we are using c++ we can use overloaded methods (its in the language) */
    440 #define UTEST_OVERLOADABLE
    441 #elif defined(__clang__)
    442 /* otherwise, if we are using clang with c - use the overloadable attribute */
    443 #define UTEST_OVERLOADABLE UTEST_ATTRIBUTE(overloadable)
    444 #endif
    445 
    446 #if defined(__cplusplus) && (__cplusplus >= 201103L)
    447 
    448 #ifdef __clang__
    449 #pragma clang diagnostic push
    450 #pragma clang diagnostic ignored "-Wc++98-compat-pedantic"
    451 #endif
    452 
    453 #include <type_traits>
    454 
    455 template <typename T, bool is_enum = std::is_enum<T>::value>
    456 struct utest_type_deducer final {
    457   static void _(const T t);
    458 };
    459 
    460 template <> struct utest_type_deducer<char, false> {
    461   static void _(const char c) {
    462     if (std::is_signed<decltype(c)>::value) {
    463       UTEST_PRINTF("%d", static_cast<int>(c));
    464     } else {
    465       UTEST_PRINTF("%u", static_cast<unsigned int>(c));
    466     }
    467   }
    468 };
    469 template <> struct utest_type_deducer<signed char, false> {
    470   static void _(const signed char c) {
    471     UTEST_PRINTF("%d", static_cast<int>(c));
    472   }
    473 };
    474 
    475 template <> struct utest_type_deducer<unsigned char, false> {
    476   static void _(const unsigned char c) {
    477     UTEST_PRINTF("%u", static_cast<unsigned int>(c));
    478   }
    479 };
    480 
    481 template <> struct utest_type_deducer<short, false> {
    482   static void _(const short s) { UTEST_PRINTF("%d", static_cast<int>(s)); }
    483 };
    484 
    485 template <> struct utest_type_deducer<unsigned short, false> {
    486   static void _(const unsigned short s) {
    487     UTEST_PRINTF("%u", static_cast<unsigned>(s));
    488   }
    489 };
    490 
    491 template <> struct utest_type_deducer<float, false> {
    492   static void _(const float f) { UTEST_PRINTF("%f", static_cast<double>(f)); }
    493 };
    494 
    495 template <> struct utest_type_deducer<double, false> {
    496   static void _(const double d) { UTEST_PRINTF("%f", d); }
    497 };
    498 
    499 template <> struct utest_type_deducer<long double, false> {
    500   static void _(const long double d) {
    501 #if defined(__MINGW32__) || defined(__MINGW64__)
    502     /* MINGW is weird - doesn't like LF at all?! */
    503     UTEST_PRINTF("%f", (double)d);
    504 #else
    505     UTEST_PRINTF("%Lf", d);
    506 #endif
    507   }
    508 };
    509 
    510 template <> struct utest_type_deducer<int, false> {
    511   static void _(const int i) { UTEST_PRINTF("%d", i); }
    512 };
    513 
    514 template <> struct utest_type_deducer<unsigned int, false> {
    515   static void _(const unsigned int i) { UTEST_PRINTF("%u", i); }
    516 };
    517 
    518 template <> struct utest_type_deducer<long, false> {
    519   static void _(const long i) { UTEST_PRINTF("%ld", i); }
    520 };
    521 
    522 template <> struct utest_type_deducer<unsigned long, false> {
    523   static void _(const unsigned long i) { UTEST_PRINTF("%lu", i); }
    524 };
    525 
    526 template <> struct utest_type_deducer<long long, false> {
    527   static void _(const long long i) { UTEST_PRINTF("%lld", i); }
    528 };
    529 
    530 template <> struct utest_type_deducer<unsigned long long, false> {
    531   static void _(const unsigned long long i) { UTEST_PRINTF("%llu", i); }
    532 };
    533 
    534 template <> struct utest_type_deducer<bool, false> {
    535   static void _(const bool i) { UTEST_PRINTF(i ? "true" : "false"); }
    536 };
    537 
    538 template <typename T> struct utest_type_deducer<const T *, false> {
    539   static void _(const T *t) {
    540     UTEST_PRINTF("%p", static_cast<void *>(const_cast<T *>(t)));
    541   }
    542 };
    543 
    544 template <typename T> struct utest_type_deducer<T *, false> {
    545   static void _(T *t) { UTEST_PRINTF("%p", static_cast<void *>(t)); }
    546 };
    547 
    548 template <typename T> struct utest_type_deducer<T, true> {
    549   static void _(const T t) {
    550     UTEST_PRINTF("%llu", static_cast<unsigned long long>(t));
    551   }
    552 };
    553 
    554 template <> struct utest_type_deducer<std::nullptr_t, false> {
    555   static void _(std::nullptr_t t) {
    556     UTEST_PRINTF("%p", static_cast<void *>(t));
    557   }
    558 };
    559 
    560 template <typename T>
    561 UTEST_WEAK UTEST_OVERLOADABLE void utest_type_printer(const T t) {
    562   utest_type_deducer<T>::_(t);
    563 }
    564 
    565 #ifdef __clang__
    566 #pragma clang diagnostic pop
    567 #endif
    568 
    569 #elif defined(UTEST_OVERLOADABLE)
    570 
    571 UTEST_WEAK UTEST_OVERLOADABLE void utest_type_printer(signed char c);
    572 UTEST_WEAK UTEST_OVERLOADABLE void utest_type_printer(signed char c) {
    573   UTEST_PRINTF("%d", UTEST_CAST(int, c));
    574 }
    575 
    576 UTEST_WEAK UTEST_OVERLOADABLE void utest_type_printer(unsigned char c);
    577 UTEST_WEAK UTEST_OVERLOADABLE void utest_type_printer(unsigned char c) {
    578   UTEST_PRINTF("%u", UTEST_CAST(unsigned int, c));
    579 }
    580 
    581 UTEST_WEAK UTEST_OVERLOADABLE void utest_type_printer(float f);
    582 UTEST_WEAK UTEST_OVERLOADABLE void utest_type_printer(float f) {
    583   UTEST_PRINTF("%f", UTEST_CAST(double, f));
    584 }
    585 
    586 UTEST_WEAK UTEST_OVERLOADABLE void utest_type_printer(double d);
    587 UTEST_WEAK UTEST_OVERLOADABLE void utest_type_printer(double d) {
    588   UTEST_PRINTF("%f", d);
    589 }
    590 
    591 UTEST_WEAK UTEST_OVERLOADABLE void utest_type_printer(long double d);
    592 UTEST_WEAK UTEST_OVERLOADABLE void utest_type_printer(long double d) {
    593 #if defined(__MINGW32__) || defined(__MINGW64__)
    594   /* MINGW is weird - doesn't like LF at all?! */
    595   UTEST_PRINTF("%f", (double)d);
    596 #else
    597   UTEST_PRINTF("%Lf", d);
    598 #endif
    599 }
    600 
    601 UTEST_WEAK UTEST_OVERLOADABLE void utest_type_printer(int i);
    602 UTEST_WEAK UTEST_OVERLOADABLE void utest_type_printer(int i) {
    603   UTEST_PRINTF("%d", i);
    604 }
    605 
    606 UTEST_WEAK UTEST_OVERLOADABLE void utest_type_printer(unsigned int i);
    607 UTEST_WEAK UTEST_OVERLOADABLE void utest_type_printer(unsigned int i) {
    608   UTEST_PRINTF("%u", i);
    609 }
    610 
    611 UTEST_WEAK UTEST_OVERLOADABLE void utest_type_printer(long int i);
    612 UTEST_WEAK UTEST_OVERLOADABLE void utest_type_printer(long int i) {
    613   UTEST_PRINTF("%ld", i);
    614 }
    615 
    616 UTEST_WEAK UTEST_OVERLOADABLE void utest_type_printer(long unsigned int i);
    617 UTEST_WEAK UTEST_OVERLOADABLE void utest_type_printer(long unsigned int i) {
    618   UTEST_PRINTF("%lu", i);
    619 }
    620 
    621 UTEST_WEAK UTEST_OVERLOADABLE void utest_type_printer(const void *p);
    622 UTEST_WEAK UTEST_OVERLOADABLE void utest_type_printer(const void *p) {
    623   UTEST_PRINTF("%p", p);
    624 }
    625 
    626 /*
    627    long long is a c++11 extension
    628 */
    629 #if defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) ||              \
    630     defined(__cplusplus) && (__cplusplus >= 201103L) ||                        \
    631     (defined(__MINGW32__) || defined(__MINGW64__))
    632 
    633 #ifdef __clang__
    634 #pragma clang diagnostic push
    635 #pragma clang diagnostic ignored "-Wc++98-compat-pedantic"
    636 #endif
    637 
    638 UTEST_WEAK UTEST_OVERLOADABLE void utest_type_printer(long long int i);
    639 UTEST_WEAK UTEST_OVERLOADABLE void utest_type_printer(long long int i) {
    640   UTEST_PRINTF("%lld", i);
    641 }
    642 
    643 UTEST_WEAK UTEST_OVERLOADABLE void utest_type_printer(long long unsigned int i);
    644 UTEST_WEAK UTEST_OVERLOADABLE void
    645 utest_type_printer(long long unsigned int i) {
    646   UTEST_PRINTF("%llu", i);
    647 }
    648 
    649 #ifdef __clang__
    650 #pragma clang diagnostic pop
    651 #endif
    652 
    653 #endif
    654 #elif defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 201112L) &&            \
    655         !(defined(__MINGW32__) || defined(__MINGW64__)) ||                     \
    656     defined(__TINYC__)
    657 #define utest_type_printer(val)                                                \
    658   UTEST_PRINTF(                                                                \
    659       _Generic((val),                                                          \
    660       signed char: "%d",                                                       \
    661       unsigned char: "%u",                                                     \
    662       short: "%d",                                                             \
    663       unsigned short: "%u",                                                    \
    664       int: "%d",                                                               \
    665       long: "%ld",                                                             \
    666       long long: "%lld",                                                       \
    667       unsigned: "%u",                                                          \
    668       unsigned long: "%lu",                                                    \
    669       unsigned long long: "%llu",                                              \
    670       float: "%f",                                                             \
    671       double: "%f",                                                            \
    672       long double: "%Lf",                                                      \
    673       default: _Generic((val - val), ptrdiff_t: "%p", default: "undef")),      \
    674       (val))
    675 #else
    676 /*
    677    we don't have the ability to print the values we got, so we create a macro
    678    to tell our users we can't do anything fancy
    679 */
    680 #define utest_type_printer(...) UTEST_PRINTF("undef")
    681 #endif
    682 
    683 #if defined(_MSC_VER)
    684 #define UTEST_SURPRESS_WARNING_BEGIN                                           \
    685   __pragma(warning(push)) __pragma(warning(disable : 4127))                    \
    686       __pragma(warning(disable : 4571)) __pragma(warning(disable : 4130))
    687 #define UTEST_SURPRESS_WARNING_END __pragma(warning(pop))
    688 #else
    689 #define UTEST_SURPRESS_WARNING_BEGIN
    690 #define UTEST_SURPRESS_WARNING_END
    691 #endif
    692 
    693 #if defined(__cplusplus) && (__cplusplus >= 201103L)
    694 #define UTEST_AUTO(x) auto
    695 #elif !defined(__cplusplus)
    696 
    697 #if defined(__clang__)
    698 /* clang-format off */
    699 /* had to disable clang-format here because it malforms the pragmas */
    700 #define UTEST_AUTO(x)                                                          \
    701   _Pragma("clang diagnostic push")                                             \
    702       _Pragma("clang diagnostic ignored \"-Wgnu-auto-type\"") __auto_type      \
    703           _Pragma("clang diagnostic pop")
    704 /* clang-format on */
    705 #else
    706 #define UTEST_AUTO(x) __typeof__(x + 0)
    707 #endif
    708 
    709 #else
    710 #define UTEST_AUTO(x) typeof(x + 0)
    711 #endif
    712 
    713 #if defined(__clang__)
    714 #define UTEST_STRNCMP(x, y, size)                                              \
    715   _Pragma("clang diagnostic push")                                             \
    716       _Pragma("clang diagnostic ignored \"-Wdisabled-macro-expansion\"")       \
    717           strncmp(x, y, size) _Pragma("clang diagnostic pop")
    718 #else
    719 #define UTEST_STRNCMP(x, y, size) strncmp(x, y, size)
    720 #endif
    721 
    722 #if defined(_MSC_VER)
    723 #define UTEST_STRNCPY(x, y, size) strcpy_s(x, size, y)
    724 #elif !defined(__clang__) && defined(__GNUC__)
    725 static UTEST_INLINE char *
    726 utest_strncpy_gcc(char *const dst, const char *const src, const size_t size) {
    727 #pragma GCC diagnostic push
    728 #pragma GCC diagnostic ignored "-Wstringop-overflow"
    729   return strncpy(dst, src, size);
    730 #pragma GCC diagnostic pop
    731 }
    732 
    733 #define UTEST_STRNCPY(x, y, size) utest_strncpy_gcc(x, y, size)
    734 #else
    735 #define UTEST_STRNCPY(x, y, size) strncpy(x, y, size)
    736 #endif
    737 
    738 #define UTEST_SKIP(msg)                                                        \
    739   do {                                                                         \
    740     UTEST_PRINTF("   Skipped : '%s'\n", (msg));                                \
    741     *utest_result = UTEST_TEST_SKIPPED;                                        \
    742     return;                                                                    \
    743   } while (0)
    744 
    745 #if defined(__clang__)
    746 #define UTEST_COND(x, y, cond, msg, is_assert)                                 \
    747   UTEST_SURPRESS_WARNING_BEGIN do {                                            \
    748     _Pragma("clang diagnostic push")                                           \
    749         _Pragma("clang diagnostic ignored \"-Wlanguage-extension-token\"")     \
    750             _Pragma("clang diagnostic ignored \"-Wc++98-compat-pedantic\"")    \
    751                 _Pragma("clang diagnostic ignored \"-Wfloat-equal\"")          \
    752                     UTEST_AUTO(x) xEval = (x);                                 \
    753     UTEST_AUTO(y) yEval = (y);                                                 \
    754     if (!((xEval)cond(yEval))) {                                               \
    755       const char *const xAsString = #x;                                        \
    756       const char *const yAsString = #y;                                        \
    757       _Pragma("clang diagnostic pop")                                          \
    758           UTEST_PRINTF("%s:%i: Failure\n", __FILE__, __LINE__);                \
    759       UTEST_PRINTF("  Expected : (");                                          \
    760       UTEST_PRINTF("%s) " #cond " (%s", xAsString, yAsString);                 \
    761       UTEST_PRINTF(")\n");                                                     \
    762       UTEST_PRINTF("    Actual : ");                                           \
    763       utest_type_printer(xEval);                                               \
    764       UTEST_PRINTF(" vs ");                                                    \
    765       utest_type_printer(yEval);                                               \
    766       UTEST_PRINTF("\n");                                                      \
    767       if (strlen(msg) > 0) {                                                   \
    768         UTEST_PRINTF("   Message : %s\n", msg);                                \
    769       }                                                                        \
    770       *utest_result = UTEST_TEST_FAILURE;                                      \
    771       if (is_assert) {                                                         \
    772         return;                                                                \
    773       }                                                                        \
    774     }                                                                          \
    775   }                                                                            \
    776   while (0)                                                                    \
    777   UTEST_SURPRESS_WARNING_END
    778 #elif defined(__GNUC__) || defined(__TINYC__)
    779 #define UTEST_COND(x, y, cond, msg, is_assert)                                 \
    780   UTEST_SURPRESS_WARNING_BEGIN do {                                            \
    781     UTEST_AUTO(x) xEval = (x);                                                 \
    782     UTEST_AUTO(y) yEval = (y);                                                 \
    783     if (!((xEval)cond(yEval))) {                                               \
    784       const char *const xAsString = #x;                                        \
    785       const char *const yAsString = #y;                                        \
    786       UTEST_PRINTF("%s:%i: Failure\n", __FILE__, __LINE__);                    \
    787       UTEST_PRINTF("  Expected : (");                                          \
    788       UTEST_PRINTF("%s) " #cond " (%s", xAsString, yAsString);                 \
    789       UTEST_PRINTF(")\n");                                                     \
    790       UTEST_PRINTF("    Actual : ");                                           \
    791       utest_type_printer(xEval);                                               \
    792       UTEST_PRINTF(" vs ");                                                    \
    793       utest_type_printer(yEval);                                               \
    794       UTEST_PRINTF("\n");                                                      \
    795       if (strlen(msg) > 0) {                                                   \
    796         UTEST_PRINTF("   Message : %s\n", msg);                                \
    797       }                                                                        \
    798       *utest_result = UTEST_TEST_FAILURE;                                      \
    799       if (is_assert) {                                                         \
    800         return;                                                                \
    801       }                                                                        \
    802     }                                                                          \
    803   }                                                                            \
    804   while (0)                                                                    \
    805   UTEST_SURPRESS_WARNING_END
    806 #else
    807 #define UTEST_COND(x, y, cond, msg, is_assert)                                 \
    808   UTEST_SURPRESS_WARNING_BEGIN do {                                            \
    809     if (!((x)cond(y))) {                                                       \
    810       UTEST_PRINTF("%s:%i: Failure (Expected " #cond " Actual)", __FILE__,     \
    811                    __LINE__);                                                  \
    812       if (strlen(msg) > 0) {                                                   \
    813         UTEST_PRINTF(" Message : %s", msg);                                    \
    814       }                                                                        \
    815       UTEST_PRINTF("\n");                                                      \
    816       *utest_result = UTEST_TEST_FAILURE;                                      \
    817       if (is_assert) {                                                         \
    818         return;                                                                \
    819       }                                                                        \
    820     }                                                                          \
    821   }                                                                            \
    822   while (0)                                                                    \
    823   UTEST_SURPRESS_WARNING_END
    824 #endif
    825 
    826 #define EXPECT_EQ(x, y) UTEST_COND(x, y, ==, "", 0)
    827 #define EXPECT_EQ_MSG(x, y, msg) UTEST_COND(x, y, ==, msg, 0)
    828 #define ASSERT_EQ(x, y) UTEST_COND(x, y, ==, "", 1)
    829 #define ASSERT_EQ_MSG(x, y, msg) UTEST_COND(x, y, ==, msg, 1)
    830 
    831 #define EXPECT_NE(x, y) UTEST_COND(x, y, !=, "", 0)
    832 #define EXPECT_NE_MSG(x, y, msg) UTEST_COND(x, y, !=, msg, 0)
    833 #define ASSERT_NE(x, y) UTEST_COND(x, y, !=, "", 1)
    834 #define ASSERT_NE_MSG(x, y, msg) UTEST_COND(x, y, !=, msg, 1)
    835 
    836 #define EXPECT_LT(x, y) UTEST_COND(x, y, <, "", 0)
    837 #define EXPECT_LT_MSG(x, y, msg) UTEST_COND(x, y, <, msg, 0)
    838 #define ASSERT_LT(x, y) UTEST_COND(x, y, <, "", 1)
    839 #define ASSERT_LT_MSG(x, y, msg) UTEST_COND(x, y, <, msg, 1)
    840 
    841 #define EXPECT_LE(x, y) UTEST_COND(x, y, <=, "", 0)
    842 #define EXPECT_LE_MSG(x, y, msg) UTEST_COND(x, y, <=, msg, 0)
    843 #define ASSERT_LE(x, y) UTEST_COND(x, y, <=, "", 1)
    844 #define ASSERT_LE_MSG(x, y, msg) UTEST_COND(x, y, <=, msg, 1)
    845 
    846 #define EXPECT_GT(x, y) UTEST_COND(x, y, >, "", 0)
    847 #define EXPECT_GT_MSG(x, y, msg) UTEST_COND(x, y, >, msg, 0)
    848 #define ASSERT_GT(x, y) UTEST_COND(x, y, >, "", 1)
    849 #define ASSERT_GT_MSG(x, y, msg) UTEST_COND(x, y, >, msg, 1)
    850 
    851 #define EXPECT_GE(x, y) UTEST_COND(x, y, >=, "", 0)
    852 #define EXPECT_GE_MSG(x, y, msg) UTEST_COND(x, y, >=, msg, 0)
    853 #define ASSERT_GE(x, y) UTEST_COND(x, y, >=, "", 1)
    854 #define ASSERT_GE_MSG(x, y, msg) UTEST_COND(x, y, >=, msg, 1)
    855 
    856 #define UTEST_TRUE(x, msg, is_assert)                                          \
    857   UTEST_SURPRESS_WARNING_BEGIN do {                                            \
    858     const int xEval = !!(x);                                                   \
    859     if (!(xEval)) {                                                            \
    860       UTEST_PRINTF("%s:%i: Failure\n", __FILE__, __LINE__);                    \
    861       UTEST_PRINTF("  Expected : true\n");                                     \
    862       UTEST_PRINTF("    Actual : %s\n", (xEval) ? "true" : "false");           \
    863       if (strlen(msg) > 0) {                                                   \
    864         UTEST_PRINTF("   Message : %s\n", msg);                                \
    865       }                                                                        \
    866       *utest_result = UTEST_TEST_FAILURE;                                      \
    867       if (is_assert) {                                                         \
    868         return;                                                                \
    869       }                                                                        \
    870     }                                                                          \
    871   }                                                                            \
    872   while (0)                                                                    \
    873   UTEST_SURPRESS_WARNING_END
    874 
    875 #define EXPECT_TRUE(x) UTEST_TRUE(x, "", 0)
    876 #define EXPECT_TRUE_MSG(x, msg) UTEST_TRUE(x, msg, 0)
    877 #define ASSERT_TRUE(x) UTEST_TRUE(x, "", 1)
    878 #define ASSERT_TRUE_MSG(x, msg) UTEST_TRUE(x, msg, 1)
    879 
    880 #define UTEST_FALSE(x, msg, is_assert)                                         \
    881   UTEST_SURPRESS_WARNING_BEGIN do {                                            \
    882     const int xEval = !!(x);                                                   \
    883     if (xEval) {                                                               \
    884       UTEST_PRINTF("%s:%i: Failure\n", __FILE__, __LINE__);                    \
    885       UTEST_PRINTF("  Expected : false\n");                                    \
    886       UTEST_PRINTF("    Actual : %s\n", (xEval) ? "true" : "false");           \
    887       if (strlen(msg) > 0) {                                                   \
    888         UTEST_PRINTF("   Message : %s\n", msg);                                \
    889       }                                                                        \
    890       *utest_result = UTEST_TEST_FAILURE;                                      \
    891       if (is_assert) {                                                         \
    892         return;                                                                \
    893       }                                                                        \
    894     }                                                                          \
    895   }                                                                            \
    896   while (0)                                                                    \
    897   UTEST_SURPRESS_WARNING_END
    898 
    899 #define EXPECT_FALSE(x) UTEST_FALSE(x, "", 0)
    900 #define EXPECT_FALSE_MSG(x, msg) UTEST_FALSE(x, msg, 0)
    901 #define ASSERT_FALSE(x) UTEST_FALSE(x, "", 1)
    902 #define ASSERT_FALSE_MSG(x, msg) UTEST_FALSE(x, msg, 1)
    903 
    904 #define UTEST_STREQ(x, y, msg, is_assert)                                      \
    905   UTEST_SURPRESS_WARNING_BEGIN do {                                            \
    906     const char *xEval = (x);                                                   \
    907     const char *yEval = (y);                                                   \
    908     if (UTEST_NULL == xEval || UTEST_NULL == yEval ||                          \
    909         0 != strcmp(xEval, yEval)) {                                           \
    910       UTEST_PRINTF("%s:%i: Failure\n", __FILE__, __LINE__);                    \
    911       UTEST_PRINTF("  Expected : \"%s\"\n", xEval);                            \
    912       UTEST_PRINTF("    Actual : \"%s\"\n", yEval);                            \
    913       if (strlen(msg) > 0) {                                                   \
    914         UTEST_PRINTF("   Message : %s\n", msg);                                \
    915       }                                                                        \
    916       *utest_result = UTEST_TEST_FAILURE;                                      \
    917       if (is_assert) {                                                         \
    918         return;                                                                \
    919       }                                                                        \
    920     }                                                                          \
    921   }                                                                            \
    922   while (0)                                                                    \
    923   UTEST_SURPRESS_WARNING_END
    924 
    925 #define EXPECT_STREQ(x, y) UTEST_STREQ(x, y, "", 0)
    926 #define EXPECT_STREQ_MSG(x, y, msg) UTEST_STREQ(x, y, msg, 0)
    927 #define ASSERT_STREQ(x, y) UTEST_STREQ(x, y, "", 1)
    928 #define ASSERT_STREQ_MSG(x, y, msg) UTEST_STREQ(x, y, msg, 1)
    929 
    930 #define UTEST_STRNE(x, y, msg, is_assert)                                      \
    931   UTEST_SURPRESS_WARNING_BEGIN do {                                            \
    932     const char *xEval = (x);                                                   \
    933     const char *yEval = (y);                                                   \
    934     if (UTEST_NULL == xEval || UTEST_NULL == yEval ||                          \
    935         0 == strcmp(xEval, yEval)) {                                           \
    936       UTEST_PRINTF("%s:%i: Failure\n", __FILE__, __LINE__);                    \
    937       UTEST_PRINTF("  Expected : \"%s\"\n", xEval);                            \
    938       UTEST_PRINTF("    Actual : \"%s\"\n", yEval);                            \
    939       if (strlen(msg) > 0) {                                                   \
    940         UTEST_PRINTF("   Message : %s\n", msg);                                \
    941       }                                                                        \
    942       *utest_result = UTEST_TEST_FAILURE;                                      \
    943       if (is_assert) {                                                         \
    944         return;                                                                \
    945       }                                                                        \
    946     }                                                                          \
    947   }                                                                            \
    948   while (0)                                                                    \
    949   UTEST_SURPRESS_WARNING_END
    950 
    951 #define EXPECT_STRNE(x, y) UTEST_STRNE(x, y, "", 0)
    952 #define EXPECT_STRNE_MSG(x, y, msg) UTEST_STRNE(x, y, msg, 0)
    953 #define ASSERT_STRNE(x, y) UTEST_STRNE(x, y, "", 1)
    954 #define ASSERT_STRNE_MSG(x, y, msg) UTEST_STRNE(x, y, msg, 1)
    955 
    956 #define UTEST_STRNEQ(x, y, n, msg, is_assert)                                  \
    957   UTEST_SURPRESS_WARNING_BEGIN do {                                            \
    958     const char *xEval = (x);                                                   \
    959     const char *yEval = (y);                                                   \
    960     const size_t nEval = UTEST_CAST(size_t, n);                                \
    961     if (UTEST_NULL == xEval || UTEST_NULL == yEval ||                          \
    962         0 != UTEST_STRNCMP(xEval, yEval, nEval)) {                             \
    963       UTEST_PRINTF("%s:%i: Failure\n", __FILE__, __LINE__);                    \
    964       UTEST_PRINTF("  Expected : \"%.*s\"\n", UTEST_CAST(int, nEval), xEval);  \
    965       UTEST_PRINTF("    Actual : \"%.*s\"\n", UTEST_CAST(int, nEval), yEval);  \
    966       if (strlen(msg) > 0) {                                                   \
    967         UTEST_PRINTF("   Message : %s\n", msg);                                \
    968       }                                                                        \
    969       *utest_result = UTEST_TEST_FAILURE;                                      \
    970       if (is_assert) {                                                         \
    971         return;                                                                \
    972       }                                                                        \
    973     }                                                                          \
    974   }                                                                            \
    975   while (0)                                                                    \
    976   UTEST_SURPRESS_WARNING_END
    977 
    978 #define EXPECT_STRNEQ(x, y, n) UTEST_STRNEQ(x, y, n, "", 0)
    979 #define EXPECT_STRNEQ_MSG(x, y, n, msg) UTEST_STRNEQ(x, y, n, msg, 0)
    980 #define ASSERT_STRNEQ(x, y, n) UTEST_STRNEQ(x, y, n, "", 1)
    981 #define ASSERT_STRNEQ_MSG(x, y, n, msg) UTEST_STRNEQ(x, y, n, msg, 1)
    982 
    983 #define UTEST_STRNNE(x, y, n, msg, is_assert)                                  \
    984   UTEST_SURPRESS_WARNING_BEGIN do {                                            \
    985     const char *xEval = (x);                                                   \
    986     const char *yEval = (y);                                                   \
    987     const size_t nEval = UTEST_CAST(size_t, n);                                \
    988     if (UTEST_NULL == xEval || UTEST_NULL == yEval ||                          \
    989         0 == UTEST_STRNCMP(xEval, yEval, nEval)) {                             \
    990       UTEST_PRINTF("%s:%i: Failure\n", __FILE__, __LINE__);                    \
    991       UTEST_PRINTF("  Expected : \"%.*s\"\n", UTEST_CAST(int, nEval), xEval);  \
    992       UTEST_PRINTF("    Actual : \"%.*s\"\n", UTEST_CAST(int, nEval), yEval);  \
    993       if (strlen(msg) > 0) {                                                   \
    994         UTEST_PRINTF("   Message : %s\n", msg);                                \
    995       }                                                                        \
    996       *utest_result = UTEST_TEST_FAILURE;                                      \
    997       if (is_assert) {                                                         \
    998         return;                                                                \
    999       }                                                                        \
   1000     }                                                                          \
   1001   }                                                                            \
   1002   while (0)                                                                    \
   1003   UTEST_SURPRESS_WARNING_END
   1004 
   1005 #define EXPECT_STRNNE(x, y, n) UTEST_STRNNE(x, y, n, "", 0)
   1006 #define EXPECT_STRNNE_MSG(x, y, n, msg) UTEST_STRNNE(x, y, n, msg, 0)
   1007 #define ASSERT_STRNNE(x, y, n) UTEST_STRNNE(x, y, n, "", 1)
   1008 #define ASSERT_STRNNE_MSG(x, y, n, msg) UTEST_STRNNE(x, y, n, msg, 1)
   1009 
   1010 #define UTEST_NEAR(x, y, epsilon, msg, is_assert)                              \
   1011   UTEST_SURPRESS_WARNING_BEGIN do {                                            \
   1012     const double diff =                                                        \
   1013         utest_fabs(UTEST_CAST(double, x) - UTEST_CAST(double, y));             \
   1014     if (diff > UTEST_CAST(double, epsilon) || utest_isnan(diff)) {             \
   1015       UTEST_PRINTF("%s:%i: Failure\n", __FILE__, __LINE__);                    \
   1016       UTEST_PRINTF("  Expected : %f\n", UTEST_CAST(double, x));                \
   1017       UTEST_PRINTF("    Actual : %f\n", UTEST_CAST(double, y));                \
   1018       if (strlen(msg) > 0) {                                                   \
   1019         UTEST_PRINTF("   Message : %s\n", msg);                                \
   1020       }                                                                        \
   1021       *utest_result = UTEST_TEST_FAILURE;                                      \
   1022       if (is_assert) {                                                         \
   1023         return;                                                                \
   1024       }                                                                        \
   1025     }                                                                          \
   1026   }                                                                            \
   1027   while (0)                                                                    \
   1028   UTEST_SURPRESS_WARNING_END
   1029 
   1030 #define EXPECT_NEAR(x, y, epsilon) UTEST_NEAR(x, y, epsilon, "", 0)
   1031 #define EXPECT_NEAR_MSG(x, y, epsilon, msg) UTEST_NEAR(x, y, epsilon, msg, 0)
   1032 #define ASSERT_NEAR(x, y, epsilon) UTEST_NEAR(x, y, epsilon, "", 1)
   1033 #define ASSERT_NEAR_MSG(x, y, epsilon, msg) UTEST_NEAR(x, y, epsilon, msg, 1)
   1034 
   1035 #if defined(UTEST_HAS_EXCEPTIONS)
   1036 #define UTEST_EXCEPTION(x, exception_type, msg, is_assert)                     \
   1037   UTEST_SURPRESS_WARNING_BEGIN do {                                            \
   1038     int exception_caught = 0;                                                  \
   1039     try {                                                                      \
   1040       x;                                                                       \
   1041     } catch (const exception_type &) {                                         \
   1042       exception_caught = 1;                                                    \
   1043     } catch (...) {                                                            \
   1044       exception_caught = 2;                                                    \
   1045     }                                                                          \
   1046     if (1 != exception_caught) {                                               \
   1047       UTEST_PRINTF("%s:%i: Failure\n", __FILE__, __LINE__);                    \
   1048       UTEST_PRINTF("  Expected : %s exception\n", #exception_type);            \
   1049       UTEST_PRINTF("    Actual : %s\n", (2 == exception_caught)                \
   1050                                             ? "Unexpected exception"           \
   1051                                             : "No exception");                 \
   1052       if (strlen(msg) > 0) {                                                   \
   1053         UTEST_PRINTF("   Message : %s\n", msg);                                \
   1054       }                                                                        \
   1055       *utest_result = UTEST_TEST_FAILURE;                                      \
   1056       if (is_assert) {                                                         \
   1057         return;                                                                \
   1058       }                                                                        \
   1059     }                                                                          \
   1060   }                                                                            \
   1061   while (0)                                                                    \
   1062   UTEST_SURPRESS_WARNING_END
   1063 
   1064 #define EXPECT_EXCEPTION(x, exception_type)                                    \
   1065   UTEST_EXCEPTION(x, exception_type, "", 0)
   1066 #define EXPECT_EXCEPTION_MSG(x, exception_type, msg)                           \
   1067   UTEST_EXCEPTION(x, exception_type, msg, 0)
   1068 #define ASSERT_EXCEPTION(x, exception_type)                                    \
   1069   UTEST_EXCEPTION(x, exception_type, "", 1)
   1070 #define ASSERT_EXCEPTION_MSG(x, exception_type, msg)                           \
   1071   UTEST_EXCEPTION(x, exception_type, msg, 1)
   1072 
   1073 #define UTEST_EXCEPTION_WITH_MESSAGE(x, exception_type, exception_message,     \
   1074                                      msg, is_assert)                           \
   1075   UTEST_SURPRESS_WARNING_BEGIN do {                                            \
   1076     int exception_caught = 0;                                                  \
   1077     char *message_caught = UTEST_NULL;                                         \
   1078     try {                                                                      \
   1079       x;                                                                       \
   1080     } catch (const exception_type &e) {                                        \
   1081       const char *const what = e.what();                                       \
   1082       exception_caught = 1;                                                    \
   1083       if (0 !=                                                                 \
   1084           UTEST_STRNCMP(what, exception_message, strlen(exception_message))) { \
   1085         const size_t message_size = strlen(what) + 1;                          \
   1086         message_caught = UTEST_PTR_CAST(char *, malloc(message_size));         \
   1087         UTEST_STRNCPY(message_caught, what, message_size);                     \
   1088       }                                                                        \
   1089     } catch (...) {                                                            \
   1090       exception_caught = 2;                                                    \
   1091     }                                                                          \
   1092     if (1 != exception_caught) {                                               \
   1093       UTEST_PRINTF("%s:%i: Failure\n", __FILE__, __LINE__);                    \
   1094       UTEST_PRINTF("  Expected : %s exception\n", #exception_type);            \
   1095       UTEST_PRINTF("    Actual : %s\n", (2 == exception_caught)                \
   1096                                             ? "Unexpected exception"           \
   1097                                             : "No exception");                 \
   1098       if (strlen(msg) > 0) {                                                   \
   1099         UTEST_PRINTF("   Message : %s\n", msg);                                \
   1100       }                                                                        \
   1101       *utest_result = UTEST_TEST_FAILURE;                                      \
   1102       if (is_assert) {                                                         \
   1103         return;                                                                \
   1104       }                                                                        \
   1105     } else if (UTEST_NULL != message_caught) {                                 \
   1106       UTEST_PRINTF("%s:%i: Failure\n", __FILE__, __LINE__);                    \
   1107       UTEST_PRINTF("  Expected : %s exception with message %s\n",              \
   1108                    #exception_type, exception_message);                        \
   1109       UTEST_PRINTF("    Actual message : %s\n", message_caught);               \
   1110       if (strlen(msg) > 0) {                                                   \
   1111         UTEST_PRINTF("   Message : %s\n", msg);                                \
   1112       }                                                                        \
   1113       *utest_result = UTEST_TEST_FAILURE;                                      \
   1114       free(message_caught);                                                    \
   1115       if (is_assert) {                                                         \
   1116         return;                                                                \
   1117       }                                                                        \
   1118     }                                                                          \
   1119   }                                                                            \
   1120   while (0)                                                                    \
   1121   UTEST_SURPRESS_WARNING_END
   1122 
   1123 #define EXPECT_EXCEPTION_WITH_MESSAGE(x, exception_type, exception_message)    \
   1124   UTEST_EXCEPTION_WITH_MESSAGE(x, exception_type, exception_message, "", 0)
   1125 #define EXPECT_EXCEPTION_WITH_MESSAGE_MSG(x, exception_type,                   \
   1126                                           exception_message, msg)              \
   1127   UTEST_EXCEPTION_WITH_MESSAGE(x, exception_type, exception_message, msg, 0)
   1128 #define ASSERT_EXCEPTION_WITH_MESSAGE(x, exception_type, exception_message)    \
   1129   UTEST_EXCEPTION_WITH_MESSAGE(x, exception_type, exception_message, "", 1)
   1130 #define ASSERT_EXCEPTION_WITH_MESSAGE_MSG(x, exception_type,                   \
   1131                                           exception_message, msg)              \
   1132   UTEST_EXCEPTION_WITH_MESSAGE(x, exception_type, exception_message, msg, 1)
   1133 #endif
   1134 
   1135 #if defined(__clang__)
   1136 #if __has_warning("-Wunsafe-buffer-usage")
   1137 #define UTEST_SURPRESS_WARNINGS_BEGIN                                          \
   1138   _Pragma("clang diagnostic push")                                             \
   1139       _Pragma("clang diagnostic ignored \"-Wunsafe-buffer-usage\"")
   1140 #define UTEST_SURPRESS_WARNINGS_END _Pragma("clang diagnostic pop")
   1141 #else
   1142 #define UTEST_SURPRESS_WARNINGS_BEGIN
   1143 #define UTEST_SURPRESS_WARNINGS_END
   1144 #endif
   1145 #elif defined(__GNUC__) && __GNUC__ >= 8 && defined(__cplusplus)
   1146 #define UTEST_SURPRESS_WARNINGS_BEGIN                                          \
   1147   _Pragma("GCC diagnostic push")                                               \
   1148       _Pragma("GCC diagnostic ignored \"-Wclass-memaccess\"")
   1149 #define UTEST_SURPRESS_WARNINGS_END _Pragma("GCC diagnostic pop")
   1150 #else
   1151 #define UTEST_SURPRESS_WARNINGS_BEGIN
   1152 #define UTEST_SURPRESS_WARNINGS_END
   1153 #endif
   1154 
   1155 #define UTEST(SET, NAME)                                                       \
   1156   UTEST_SURPRESS_WARNINGS_BEGIN                                                \
   1157   UTEST_EXTERN struct utest_state_s utest_state;                               \
   1158   static void utest_run_##SET##_##NAME(int *utest_result);                     \
   1159   static void utest_##SET##_##NAME(int *utest_result, size_t utest_index) {    \
   1160     (void)utest_index;                                                         \
   1161     utest_run_##SET##_##NAME(utest_result);                                    \
   1162   }                                                                            \
   1163   UTEST_INITIALIZER(utest_register_##SET##_##NAME) {                           \
   1164     const size_t index = utest_state.tests_length++;                           \
   1165     const char name_part[] = #SET "." #NAME;                                   \
   1166     const size_t name_size = strlen(name_part) + 1;                            \
   1167     char *name = UTEST_PTR_CAST(char *, malloc(name_size));                    \
   1168     utest_state.tests = UTEST_PTR_CAST(                                        \
   1169         struct utest_test_state_s *,                                           \
   1170         utest_realloc(UTEST_PTR_CAST(void *, utest_state.tests),               \
   1171                       sizeof(struct utest_test_state_s) *                      \
   1172                           utest_state.tests_length));                          \
   1173     if (utest_state.tests && name) {                                           \
   1174       utest_state.tests[index].func = &utest_##SET##_##NAME;                   \
   1175       utest_state.tests[index].name = name;                                    \
   1176       utest_state.tests[index].index = 0;                                      \
   1177       UTEST_SNPRINTF(name, name_size, "%s", name_part);                        \
   1178     } else {                                                                   \
   1179       if (utest_state.tests) {                                                 \
   1180         free(utest_state.tests);                                               \
   1181         utest_state.tests = NULL;                                              \
   1182       }                                                                        \
   1183       if (name) {                                                              \
   1184         free(name);                                                            \
   1185       }                                                                        \
   1186     }                                                                          \
   1187   }                                                                            \
   1188   UTEST_SURPRESS_WARNINGS_END                                                  \
   1189   void utest_run_##SET##_##NAME(int *utest_result)
   1190 
   1191 #define UTEST_F_SETUP(FIXTURE)                                                 \
   1192   static void utest_f_setup_##FIXTURE(int *utest_result,                       \
   1193                                       struct FIXTURE *utest_fixture)
   1194 
   1195 #define UTEST_F_TEARDOWN(FIXTURE)                                              \
   1196   static void utest_f_teardown_##FIXTURE(int *utest_result,                    \
   1197                                          struct FIXTURE *utest_fixture)
   1198 
   1199 #define UTEST_F(FIXTURE, NAME)                                                 \
   1200   UTEST_SURPRESS_WARNINGS_BEGIN                                                \
   1201   UTEST_EXTERN struct utest_state_s utest_state;                               \
   1202   static void utest_f_setup_##FIXTURE(int *, struct FIXTURE *);                \
   1203   static void utest_f_teardown_##FIXTURE(int *, struct FIXTURE *);             \
   1204   static void utest_run_##FIXTURE##_##NAME(int *, struct FIXTURE *);           \
   1205   static void utest_f_##FIXTURE##_##NAME(int *utest_result,                    \
   1206                                          size_t utest_index) {                 \
   1207     struct FIXTURE fixture;                                                    \
   1208     (void)utest_index;                                                         \
   1209     memset(&fixture, 0, sizeof(fixture));                                      \
   1210     utest_f_setup_##FIXTURE(utest_result, &fixture);                           \
   1211     if (UTEST_TEST_PASSED != *utest_result) {                                  \
   1212       return;                                                                  \
   1213     }                                                                          \
   1214     utest_run_##FIXTURE##_##NAME(utest_result, &fixture);                      \
   1215     utest_f_teardown_##FIXTURE(utest_result, &fixture);                        \
   1216   }                                                                            \
   1217   UTEST_INITIALIZER(utest_register_##FIXTURE##_##NAME) {                       \
   1218     const size_t index = utest_state.tests_length++;                           \
   1219     const char name_part[] = #FIXTURE "." #NAME;                               \
   1220     const size_t name_size = strlen(name_part) + 1;                            \
   1221     char *name = UTEST_PTR_CAST(char *, malloc(name_size));                    \
   1222     utest_state.tests = UTEST_PTR_CAST(                                        \
   1223         struct utest_test_state_s *,                                           \
   1224         utest_realloc(UTEST_PTR_CAST(void *, utest_state.tests),               \
   1225                       sizeof(struct utest_test_state_s) *                      \
   1226                           utest_state.tests_length));                          \
   1227     if (utest_state.tests && name) {                                           \
   1228       utest_state.tests[index].func = &utest_f_##FIXTURE##_##NAME;             \
   1229       utest_state.tests[index].name = name;                                    \
   1230       utest_state.tests[index].index = 0;                                      \
   1231       UTEST_SNPRINTF(name, name_size, "%s", name_part);                        \
   1232     } else {                                                                   \
   1233       if (utest_state.tests) {                                                 \
   1234         free(utest_state.tests);                                               \
   1235         utest_state.tests = NULL;                                              \
   1236       }                                                                        \
   1237       if (name) {                                                              \
   1238         free(name);                                                            \
   1239       }                                                                        \
   1240     }                                                                          \
   1241   }                                                                            \
   1242   UTEST_SURPRESS_WARNINGS_END                                                  \
   1243   void utest_run_##FIXTURE##_##NAME(int *utest_result,                         \
   1244                                     struct FIXTURE *utest_fixture)
   1245 
   1246 #define UTEST_I_SETUP(FIXTURE)                                                 \
   1247   static void utest_i_setup_##FIXTURE(                                         \
   1248       int *utest_result, struct FIXTURE *utest_fixture, size_t utest_index)
   1249 
   1250 #define UTEST_I_TEARDOWN(FIXTURE)                                              \
   1251   static void utest_i_teardown_##FIXTURE(                                      \
   1252       int *utest_result, struct FIXTURE *utest_fixture, size_t utest_index)
   1253 
   1254 #define UTEST_I(FIXTURE, NAME, INDEX)                                          \
   1255   UTEST_SURPRESS_WARNINGS_BEGIN                                                \
   1256   UTEST_EXTERN struct utest_state_s utest_state;                               \
   1257   static void utest_run_##FIXTURE##_##NAME##_##INDEX(int *, struct FIXTURE *); \
   1258   static void utest_i_##FIXTURE##_##NAME##_##INDEX(int *utest_result,          \
   1259                                                    size_t index) {             \
   1260     struct FIXTURE fixture;                                                    \
   1261     memset(&fixture, 0, sizeof(fixture));                                      \
   1262     utest_i_setup_##FIXTURE(utest_result, &fixture, index);                    \
   1263     if (UTEST_TEST_PASSED != *utest_result) {                                  \
   1264       return;                                                                  \
   1265     }                                                                          \
   1266     utest_run_##FIXTURE##_##NAME##_##INDEX(utest_result, &fixture);            \
   1267     utest_i_teardown_##FIXTURE(utest_result, &fixture, index);                 \
   1268   }                                                                            \
   1269   UTEST_INITIALIZER(utest_register_##FIXTURE##_##NAME##_##INDEX) {             \
   1270     size_t i;                                                                  \
   1271     utest_uint64_t iUp;                                                        \
   1272     for (i = 0; i < (INDEX); i++) {                                            \
   1273       const size_t index = utest_state.tests_length++;                         \
   1274       const char name_part[] = #FIXTURE "." #NAME;                             \
   1275       const size_t name_size = strlen(name_part) + 32;                         \
   1276       char *name = UTEST_PTR_CAST(char *, malloc(name_size));                  \
   1277       utest_state.tests = UTEST_PTR_CAST(                                      \
   1278           struct utest_test_state_s *,                                         \
   1279           utest_realloc(UTEST_PTR_CAST(void *, utest_state.tests),             \
   1280                         sizeof(struct utest_test_state_s) *                    \
   1281                             utest_state.tests_length));                        \
   1282       if (utest_state.tests && name) {                                         \
   1283         utest_state.tests[index].func = &utest_i_##FIXTURE##_##NAME##_##INDEX; \
   1284         utest_state.tests[index].index = i;                                    \
   1285         utest_state.tests[index].name = name;                                  \
   1286         iUp = UTEST_CAST(utest_uint64_t, i);                                   \
   1287         UTEST_SNPRINTF(name, name_size, "%s/%" UTEST_PRIu64, name_part, iUp);  \
   1288       } else {                                                                 \
   1289         if (utest_state.tests) {                                               \
   1290           free(utest_state.tests);                                             \
   1291           utest_state.tests = NULL;                                            \
   1292         }                                                                      \
   1293         if (name) {                                                            \
   1294           free(name);                                                          \
   1295         }                                                                      \
   1296       }                                                                        \
   1297     }                                                                          \
   1298   }                                                                            \
   1299   UTEST_SURPRESS_WARNINGS_END                                                  \
   1300   void utest_run_##FIXTURE##_##NAME##_##INDEX(int *utest_result,               \
   1301                                               struct FIXTURE *utest_fixture)
   1302 
   1303 #ifdef __clang__
   1304 #pragma clang diagnostic push
   1305 #pragma clang diagnostic ignored "-Wc++98-compat-pedantic"
   1306 #endif
   1307 
   1308 UTEST_WEAK
   1309 double utest_fabs(double d);
   1310 UTEST_WEAK
   1311 double utest_fabs(double d) {
   1312   union {
   1313     double d;
   1314     utest_uint64_t u;
   1315   } both;
   1316   both.d = d;
   1317   both.u &= 0x7fffffffffffffffu;
   1318   return both.d;
   1319 }
   1320 
   1321 UTEST_WEAK
   1322 int utest_isnan(double d);
   1323 UTEST_WEAK
   1324 int utest_isnan(double d) {
   1325   union {
   1326     double d;
   1327     utest_uint64_t u;
   1328   } both;
   1329   both.d = d;
   1330   both.u &= 0x7fffffffffffffffu;
   1331   return both.u > 0x7ff0000000000000u;
   1332 }
   1333 
   1334 #ifdef __clang__
   1335 #pragma clang diagnostic pop
   1336 #endif
   1337 
   1338 #if defined(__clang__)
   1339 #if __has_warning("-Wunsafe-buffer-usage")
   1340 #pragma clang diagnostic push
   1341 #pragma clang diagnostic ignored "-Wunsafe-buffer-usage"
   1342 #endif
   1343 #endif
   1344 
   1345 UTEST_WEAK
   1346 int utest_should_filter_test(const char *filter, const char *testcase);
   1347 UTEST_WEAK int utest_should_filter_test(const char *filter,
   1348                                         const char *testcase) {
   1349   if (filter) {
   1350     const char *filter_cur = filter;
   1351     const char *testcase_cur = testcase;
   1352     const char *filter_wildcard = UTEST_NULL;
   1353 
   1354     while (('\0' != *filter_cur) && ('\0' != *testcase_cur)) {
   1355       if ('*' == *filter_cur) {
   1356         /* store the position of the wildcard */
   1357         filter_wildcard = filter_cur;
   1358 
   1359         /* skip the wildcard character */
   1360         filter_cur++;
   1361 
   1362         while (('\0' != *filter_cur) && ('\0' != *testcase_cur)) {
   1363           if ('*' == *filter_cur) {
   1364             /*
   1365                we found another wildcard (filter is something like *foo*) so we
   1366                exit the current loop, and return to the parent loop to handle
   1367                the wildcard case
   1368             */
   1369             break;
   1370           } else if (*filter_cur != *testcase_cur) {
   1371             /* otherwise our filter didn't match, so reset it */
   1372             filter_cur = filter_wildcard;
   1373           }
   1374 
   1375           /* move testcase along */
   1376           testcase_cur++;
   1377 
   1378           /* move filter along */
   1379           filter_cur++;
   1380         }
   1381 
   1382         if (('\0' == *filter_cur) && ('\0' == *testcase_cur)) {
   1383           return 0;
   1384         }
   1385 
   1386         /* if the testcase has been exhausted, we don't have a match! */
   1387         if ('\0' == *testcase_cur) {
   1388           return 1;
   1389         }
   1390       } else {
   1391         if (*testcase_cur != *filter_cur) {
   1392           /* test case doesn't match filter */
   1393           return 1;
   1394         } else {
   1395           /* move our filter and testcase forward */
   1396           testcase_cur++;
   1397           filter_cur++;
   1398         }
   1399       }
   1400     }
   1401 
   1402     if (('\0' != *filter_cur) ||
   1403         (('\0' != *testcase_cur) &&
   1404          ((filter == filter_cur) || ('*' != filter_cur[-1])))) {
   1405       /* we have a mismatch! */
   1406       return 1;
   1407     }
   1408   }
   1409 
   1410   return 0;
   1411 }
   1412 
   1413 static UTEST_INLINE FILE *utest_fopen(const char *filename, const char *mode) {
   1414 #ifdef _MSC_VER
   1415   FILE *file;
   1416   if (0 == fopen_s(&file, filename, mode)) {
   1417     return file;
   1418   } else {
   1419     return UTEST_NULL;
   1420   }
   1421 #else
   1422   return fopen(filename, mode);
   1423 #endif
   1424 }
   1425 
   1426 static UTEST_INLINE int utest_main(int argc, const char *const argv[]);
   1427 int utest_main(int argc, const char *const argv[]) {
   1428   utest_uint64_t failed = 0;
   1429   utest_uint64_t skipped = 0;
   1430   size_t index = 0;
   1431   size_t *failed_testcases = UTEST_NULL;
   1432   size_t failed_testcases_length = 0;
   1433   size_t *skipped_testcases = UTEST_NULL;
   1434   size_t skipped_testcases_length = 0;
   1435   const char *filter = UTEST_NULL;
   1436   utest_uint64_t ran_tests = 0;
   1437   int enable_mixed_units = 0;
   1438   int random_order = 0;
   1439   utest_uint32_t seed = 0;
   1440 
   1441   enum colours { RESET, GREEN, RED, YELLOW };
   1442 
   1443   const int use_colours = UTEST_COLOUR_OUTPUT();
   1444   const char *colours[] = {"\033[0m", "\033[32m", "\033[31m", "\033[33m"};
   1445 
   1446   if (!use_colours) {
   1447     for (index = 0; index < sizeof colours / sizeof colours[0]; index++) {
   1448       colours[index] = "";
   1449     }
   1450   }
   1451   /* loop through all arguments looking for our options */
   1452   for (index = 1; index < UTEST_CAST(size_t, argc); index++) {
   1453     /* Informational switches */
   1454     const char help_str[] = "--help";
   1455     const char list_str[] = "--list-tests";
   1456     /* Test config switches */
   1457     const char filter_str[] = "--filter=";
   1458     const char output_str[] = "--output=";
   1459     const char enable_mixed_units_str[] = "--enable-mixed-units";
   1460     const char random_order_str[] = "--random-order";
   1461     const char random_order_with_seed_str[] = "--random-order=";
   1462 
   1463     if (0 == UTEST_STRNCMP(argv[index], help_str, strlen(help_str))) {
   1464       printf("utest.h - the single file unit testing solution for C/C++!\n"
   1465              "Command line Options:\n"
   1466              "  --help                  Show this message and exit.\n"
   1467              "  --filter=<filter>       Filter the test cases to run (EG. "
   1468              "MyTest*.a would run MyTestCase.a but not MyTestCase.b).\n"
   1469              "  --list-tests            List testnames, one per line. Output "
   1470              "names can be passed to --filter.\n");
   1471       printf("  --output=<output>       Output an xunit XML file to the file "
   1472              "specified in <output>.\n"
   1473              "  --enable-mixed-units    Enable the per-test output to contain "
   1474              "mixed units (s/ms/us/ns).\n"
   1475              "  --random-order[=<seed>] Randomize the order that the tests are "
   1476              "ran in. If the optional <seed> argument is not provided, then a "
   1477              "random starting seed is used.\n");
   1478       goto cleanup;
   1479     } else if (0 ==
   1480                UTEST_STRNCMP(argv[index], filter_str, strlen(filter_str))) {
   1481       /* user wants to filter what test cases run! */
   1482       filter = argv[index] + strlen(filter_str);
   1483     } else if (0 ==
   1484                UTEST_STRNCMP(argv[index], output_str, strlen(output_str))) {
   1485       utest_state.output = utest_fopen(argv[index] + strlen(output_str), "w+");
   1486     } else if (0 == UTEST_STRNCMP(argv[index], list_str, strlen(list_str))) {
   1487       for (index = 0; index < utest_state.tests_length; index++) {
   1488         UTEST_PRINTF("%s\n", utest_state.tests[index].name);
   1489       }
   1490       /* when printing the test list, don't actually run the tests */
   1491       return 0;
   1492     } else if (0 == UTEST_STRNCMP(argv[index], enable_mixed_units_str,
   1493                                   strlen(enable_mixed_units_str))) {
   1494       enable_mixed_units = 1;
   1495     } else if (0 == UTEST_STRNCMP(argv[index], random_order_with_seed_str,
   1496                                   strlen(random_order_with_seed_str))) {
   1497       seed =
   1498           UTEST_CAST(utest_uint32_t,
   1499                      strtoul(argv[index] + strlen(random_order_with_seed_str),
   1500                              UTEST_NULL, 10));
   1501       random_order = 1;
   1502     } else if (0 == UTEST_STRNCMP(argv[index], random_order_str,
   1503                                   strlen(random_order_str))) {
   1504       const utest_int64_t ns = utest_ns();
   1505 
   1506       // Some really poor pseudo-random using the current time. I do this
   1507       // because I really want to avoid using C's rand() because that'd mean our
   1508       // random would be affected by any srand() usage by the user (which I
   1509       // don't want).
   1510       seed = UTEST_CAST(utest_uint32_t, ns >> 32) * 31 +
   1511              UTEST_CAST(utest_uint32_t, ns & 0xffffffff);
   1512       random_order = 1;
   1513     }
   1514   }
   1515 
   1516   if (random_order) {
   1517     // Use Fisher-Yates with the Durstenfield's version to randomly re-order the
   1518     // tests.
   1519     for (index = utest_state.tests_length; index > 1; index--) {
   1520       // For the random order we'll use PCG.
   1521       const utest_uint32_t state = seed;
   1522       const utest_uint32_t word =
   1523           ((state >> ((state >> 28u) + 4u)) ^ state) * 277803737u;
   1524       const utest_uint32_t next =
   1525           ((word >> 22u) ^ word) % UTEST_CAST(utest_uint32_t, index);
   1526 
   1527       // Swap the randomly chosen element into the last location.
   1528       const struct utest_test_state_s copy = utest_state.tests[index - 1];
   1529       utest_state.tests[index - 1] = utest_state.tests[next];
   1530       utest_state.tests[next] = copy;
   1531 
   1532       // Move the seed onwards.
   1533       seed = seed * 747796405u + 2891336453u;
   1534     }
   1535   }
   1536 
   1537   for (index = 0; index < utest_state.tests_length; index++) {
   1538     if (utest_should_filter_test(filter, utest_state.tests[index].name)) {
   1539       continue;
   1540     }
   1541 
   1542     ran_tests++;
   1543   }
   1544 
   1545   printf("%s[==========]%s Running %" UTEST_PRIu64 " test cases.\n",
   1546          colours[GREEN], colours[RESET], UTEST_CAST(utest_uint64_t, ran_tests));
   1547 
   1548   if (utest_state.output) {
   1549     fprintf(utest_state.output, "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n");
   1550     fprintf(utest_state.output,
   1551             "<testsuites tests=\"%" UTEST_PRIu64 "\" name=\"All\">\n",
   1552             UTEST_CAST(utest_uint64_t, ran_tests));
   1553     fprintf(utest_state.output,
   1554             "<testsuite name=\"Tests\" tests=\"%" UTEST_PRIu64 "\">\n",
   1555             UTEST_CAST(utest_uint64_t, ran_tests));
   1556   }
   1557 
   1558   for (index = 0; index < utest_state.tests_length; index++) {
   1559     int result = UTEST_TEST_PASSED;
   1560     utest_int64_t ns = 0;
   1561 
   1562     if (utest_should_filter_test(filter, utest_state.tests[index].name)) {
   1563       continue;
   1564     }
   1565 
   1566     printf("%s[ RUN      ]%s %s\n", colours[GREEN], colours[RESET],
   1567            utest_state.tests[index].name);
   1568 
   1569     if (utest_state.output) {
   1570       fprintf(utest_state.output, "<testcase name=\"%s\">",
   1571               utest_state.tests[index].name);
   1572     }
   1573 
   1574     ns = utest_ns();
   1575     errno = 0;
   1576 #if defined(UTEST_HAS_EXCEPTIONS)
   1577     UTEST_SURPRESS_WARNING_BEGIN
   1578     try {
   1579       utest_state.tests[index].func(&result, utest_state.tests[index].index);
   1580     } catch (const std::exception &err) {
   1581       printf(" Exception : %s\n", err.what());
   1582       result = UTEST_TEST_FAILURE;
   1583     } catch (...) {
   1584       printf(" Exception : Unknown\n");
   1585       result = UTEST_TEST_FAILURE;
   1586     }
   1587     UTEST_SURPRESS_WARNING_END
   1588 #else
   1589     utest_state.tests[index].func(&result, utest_state.tests[index].index);
   1590 #endif
   1591     ns = utest_ns() - ns;
   1592 
   1593     if (utest_state.output) {
   1594       fprintf(utest_state.output, "</testcase>\n");
   1595     }
   1596 
   1597     // Record the failing test.
   1598     if (UTEST_TEST_FAILURE == result) {
   1599       const size_t failed_testcase_index = failed_testcases_length++;
   1600       failed_testcases = UTEST_PTR_CAST(
   1601           size_t *, utest_realloc(UTEST_PTR_CAST(void *, failed_testcases),
   1602                                   sizeof(size_t) * failed_testcases_length));
   1603       if (UTEST_NULL != failed_testcases) {
   1604         failed_testcases[failed_testcase_index] = index;
   1605       }
   1606       failed++;
   1607     } else if (UTEST_TEST_SKIPPED == result) {
   1608       const size_t skipped_testcase_index = skipped_testcases_length++;
   1609       skipped_testcases = UTEST_PTR_CAST(
   1610           size_t *, utest_realloc(UTEST_PTR_CAST(void *, skipped_testcases),
   1611                                   sizeof(size_t) * skipped_testcases_length));
   1612       if (UTEST_NULL != skipped_testcases) {
   1613         skipped_testcases[skipped_testcase_index] = index;
   1614       }
   1615       skipped++;
   1616     }
   1617 
   1618     {
   1619       const char *const units[] = {"ns", "us", "ms", "s", UTEST_NULL};
   1620       unsigned int unit_index = 0;
   1621       utest_int64_t time = ns;
   1622 
   1623       if (enable_mixed_units) {
   1624         for (unit_index = 0; UTEST_NULL != units[unit_index]; unit_index++) {
   1625           if (10000 > time) {
   1626             break;
   1627           }
   1628 
   1629           time /= 1000;
   1630         }
   1631       }
   1632 
   1633       if (UTEST_TEST_FAILURE == result) {
   1634         printf("%s[  FAILED  ]%s %s (%" UTEST_PRId64 "%s)\n", colours[RED],
   1635                colours[RESET], utest_state.tests[index].name, time,
   1636                units[unit_index]);
   1637       } else if (UTEST_TEST_SKIPPED == result) {
   1638         printf("%s[  SKIPPED ]%s %s (%" UTEST_PRId64 "%s)\n", colours[YELLOW],
   1639                colours[RESET], utest_state.tests[index].name, time,
   1640                units[unit_index]);
   1641       } else {
   1642         printf("%s[       OK ]%s %s (%" UTEST_PRId64 "%s)\n", colours[GREEN],
   1643                colours[RESET], utest_state.tests[index].name, time,
   1644                units[unit_index]);
   1645       }
   1646     }
   1647   }
   1648 
   1649   printf("%s[==========]%s %" UTEST_PRIu64 " test cases ran.\n", colours[GREEN],
   1650          colours[RESET], ran_tests);
   1651   printf("%s[  PASSED  ]%s %" UTEST_PRIu64 " tests.\n", colours[GREEN],
   1652          colours[RESET], ran_tests - failed - skipped);
   1653 
   1654   if (0 != skipped) {
   1655     printf("%s[  SKIPPED ]%s %" UTEST_PRIu64 " tests, listed below:\n",
   1656            colours[YELLOW], colours[RESET], skipped);
   1657     for (index = 0; index < skipped_testcases_length; index++) {
   1658       printf("%s[  SKIPPED ]%s %s\n", colours[YELLOW], colours[RESET],
   1659              utest_state.tests[skipped_testcases[index]].name);
   1660     }
   1661   }
   1662 
   1663   if (0 != failed) {
   1664     printf("%s[  FAILED  ]%s %" UTEST_PRIu64 " tests, listed below:\n",
   1665            colours[RED], colours[RESET], failed);
   1666     for (index = 0; index < failed_testcases_length; index++) {
   1667       printf("%s[  FAILED  ]%s %s\n", colours[RED], colours[RESET],
   1668              utest_state.tests[failed_testcases[index]].name);
   1669     }
   1670   }
   1671 
   1672   if (utest_state.output) {
   1673     fprintf(utest_state.output, "</testsuite>\n</testsuites>\n");
   1674   }
   1675 
   1676 cleanup:
   1677   for (index = 0; index < utest_state.tests_length; index++) {
   1678     free(UTEST_PTR_CAST(void *, utest_state.tests[index].name));
   1679   }
   1680 
   1681   free(UTEST_PTR_CAST(void *, skipped_testcases));
   1682   free(UTEST_PTR_CAST(void *, failed_testcases));
   1683   free(UTEST_PTR_CAST(void *, utest_state.tests));
   1684 
   1685   if (utest_state.output) {
   1686     fclose(utest_state.output);
   1687   }
   1688 
   1689   return UTEST_CAST(int, failed);
   1690 }
   1691 
   1692 #if defined(__clang__)
   1693 #if __has_warning("-Wunsafe-buffer-usage")
   1694 #pragma clang diagnostic pop
   1695 #endif
   1696 #endif
   1697 
   1698 /*
   1699    we need, in exactly one source file, define the global struct that will hold
   1700    the data we need to run utest. This macro allows the user to declare the
   1701    data without having to use the UTEST_MAIN macro, thus allowing them to write
   1702    their own main() function.
   1703 */
   1704 #define UTEST_STATE() struct utest_state_s utest_state = {0, 0, 0}
   1705 
   1706 /*
   1707    define a main() function to call into utest.h and start executing tests! A
   1708    user can optionally not use this macro, and instead define their own main()
   1709    function and manually call utest_main. The user must, in exactly one source
   1710    file, use the UTEST_STATE macro to declare a global struct variable that
   1711    utest requires.
   1712 */
   1713 #define UTEST_MAIN()                                                           \
   1714   UTEST_STATE();                                                               \
   1715   int main(int argc, const char *const argv[]) {                               \
   1716     return utest_main(argc, argv);                                             \
   1717   }
   1718 
   1719 #endif /* SHEREDOM_UTEST_H_INCLUDED */