From 34779155d5b69b51aa301e7c111f95ea9c840589 Mon Sep 17 00:00:00 2001
From: flu0r1ne <flu0r1ne@flu0r1ne.net>
Date: Thu, 17 Aug 2023 15:56:11 -0500
Subject: init commit

---
 test/utest.h        | 1623 +++++++++++++++++++++++++++++++++++++++++++++++++++
 test/wg2sd_test.cpp |  219 +++++++
 2 files changed, 1842 insertions(+)
 create mode 100644 test/utest.h
 create mode 100644 test/wg2sd_test.cpp

(limited to 'test')

diff --git a/test/utest.h b/test/utest.h
new file mode 100644
index 0000000..ca996ea
--- /dev/null
+++ b/test/utest.h
@@ -0,0 +1,1623 @@
+/*
+   The latest version of this library is available on GitHub;
+   https://github.com/sheredom/utest.h
+*/
+
+/*
+   This is free and unencumbered software released into the public domain.
+
+   Anyone is free to copy, modify, publish, use, compile, sell, or
+   distribute this software, either in source code form or as a compiled
+   binary, for any purpose, commercial or non-commercial, and by any
+   means.
+
+   In jurisdictions that recognize copyright laws, the author or authors
+   of this software dedicate any and all copyright interest in the
+   software to the public domain. We make this dedication for the benefit
+   of the public at large and to the detriment of our heirs and
+   successors. We intend this dedication to be an overt act of
+   relinquishment in perpetuity of all present and future rights to this
+   software under copyright law.
+
+   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+   EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+   IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR
+   OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+   ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+   OTHER DEALINGS IN THE SOFTWARE.
+
+   For more information, please refer to <http://unlicense.org/>
+*/
+
+#ifndef SHEREDOM_UTEST_H_INCLUDED
+#define SHEREDOM_UTEST_H_INCLUDED
+
+#ifdef _MSC_VER
+/*
+   Disable warning about not inlining 'inline' functions.
+*/
+#pragma warning(disable : 4710)
+
+/*
+   Disable warning about inlining functions that are not marked 'inline'.
+*/
+#pragma warning(disable : 4711)
+
+/*
+   Disable warning for alignment padding added
+*/
+#pragma warning(disable : 4820)
+
+#if _MSC_VER > 1900
+/*
+  Disable warning about preprocessor macros not being defined in MSVC headers.
+*/
+#pragma warning(disable : 4668)
+
+/*
+  Disable warning about no function prototype given in MSVC headers.
+*/
+#pragma warning(disable : 4255)
+
+/*
+  Disable warning about pointer or reference to potentially throwing function.
+*/
+#pragma warning(disable : 5039)
+
+/*
+  Disable warning about macro expansion producing 'defined' has undefined
+  behavior.
+*/
+#pragma warning(disable : 5105)
+#endif
+
+#if _MSC_VER > 1930
+/*
+  Disable warning about 'const' variable is not used.
+*/
+#pragma warning(disable : 5264)
+#endif
+
+#pragma warning(push, 1)
+#endif
+
+#if defined(_MSC_VER) && (_MSC_VER < 1920)
+typedef __int64 utest_int64_t;
+typedef unsigned __int64 utest_uint64_t;
+typedef unsigned __int32 utest_uint32_t;
+#else
+#include <stdint.h>
+typedef int64_t utest_int64_t;
+typedef uint64_t utest_uint64_t;
+typedef uint32_t utest_uint32_t;
+#endif
+
+#include <stddef.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+
+#if defined(__cplusplus)
+#if defined(_MSC_VER) && !defined(_CPPUNWIND)
+/* We're on MSVC and the compiler is compiling without exception support! */
+#elif !defined(_MSC_VER) && !defined(__EXCEPTIONS)
+/* We're on a GCC/Clang compiler that doesn't have exception support! */
+#else
+#define UTEST_HAS_EXCEPTIONS 1
+#endif
+#endif
+
+#if defined(UTEST_HAS_EXCEPTIONS)
+#include <stdexcept>
+#endif
+
+#if defined(_MSC_VER)
+#pragma warning(pop)
+#endif
+
+#if defined(__cplusplus)
+#define UTEST_C_FUNC extern "C"
+#else
+#define UTEST_C_FUNC
+#endif
+
+#define UTEST_TEST_PASSED (0)
+#define UTEST_TEST_FAILURE (1)
+#define UTEST_TEST_SKIPPED (2)
+
+#if defined(__TINYC__)
+#define UTEST_ATTRIBUTE(a) __attribute((a))
+#else
+#define UTEST_ATTRIBUTE(a) __attribute__((a))
+#endif
+
+#if defined(_MSC_VER) || defined(__MINGW64__) || defined(__MINGW32__)
+
+#if defined(__MINGW64__) || defined(__MINGW32__)
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wpragmas"
+#pragma GCC diagnostic ignored "-Wunknown-pragmas"
+#endif
+
+#if defined(_WINDOWS_) || defined(_WINDOWS_H)
+typedef LARGE_INTEGER utest_large_integer;
+#else
+// use old QueryPerformanceCounter definitions (not sure is this needed in some
+// edge cases or not) on Win7 with VS2015 these extern declaration cause "second
+// C linkage of overloaded function not allowed" error
+typedef union {
+  struct {
+    unsigned long LowPart;
+    long HighPart;
+  } DUMMYSTRUCTNAME;
+  struct {
+    unsigned long LowPart;
+    long HighPart;
+  } u;
+  utest_int64_t QuadPart;
+} utest_large_integer;
+
+UTEST_C_FUNC __declspec(dllimport) int __stdcall QueryPerformanceCounter(
+    utest_large_integer *);
+UTEST_C_FUNC __declspec(dllimport) int __stdcall QueryPerformanceFrequency(
+    utest_large_integer *);
+
+#if defined(__MINGW64__) || defined(__MINGW32__)
+#pragma GCC diagnostic pop
+#endif
+#endif
+
+#elif defined(__linux__) || defined(__FreeBSD__) || defined(__OpenBSD__) ||    \
+    defined(__NetBSD__) || defined(__DragonFly__) || defined(__sun__) ||       \
+    defined(__HAIKU__)
+/*
+   slightly obscure include here - we need to include glibc's features.h, but
+   we don't want to just include a header that might not be defined for other
+   c libraries like musl. Instead we include limits.h, which we know on all
+   glibc distributions includes features.h
+*/
+#include <limits.h>
+
+#if defined(__GLIBC__) && defined(__GLIBC_MINOR__)
+#include <time.h>
+
+#if ((2 < __GLIBC__) || ((2 == __GLIBC__) && (17 <= __GLIBC_MINOR__)))
+/* glibc is version 2.17 or above, so we can just use clock_gettime */
+#define UTEST_USE_CLOCKGETTIME
+#else
+#include <sys/syscall.h>
+#include <unistd.h>
+#endif
+#else // Other libc implementations
+#include <time.h>
+#define UTEST_USE_CLOCKGETTIME
+#endif
+
+#elif defined(__APPLE__)
+#include <time.h>
+#endif
+
+#if defined(_MSC_VER) && (_MSC_VER < 1920)
+#define UTEST_PRId64 "I64d"
+#define UTEST_PRIu64 "I64u"
+#else
+#include <inttypes.h>
+
+#define UTEST_PRId64 PRId64
+#define UTEST_PRIu64 PRIu64
+#endif
+
+#if defined(__cplusplus)
+#define UTEST_INLINE inline
+
+#if defined(__clang__)
+#define UTEST_INITIALIZER_BEGIN_DISABLE_WARNINGS                               \
+  _Pragma("clang diagnostic push")                                             \
+      _Pragma("clang diagnostic ignored \"-Wglobal-constructors\"")
+
+#define UTEST_INITIALIZER_END_DISABLE_WARNINGS _Pragma("clang diagnostic pop")
+#else
+#define UTEST_INITIALIZER_BEGIN_DISABLE_WARNINGS
+#define UTEST_INITIALIZER_END_DISABLE_WARNINGS
+#endif
+
+#define UTEST_INITIALIZER(f)                                                   \
+  struct f##_cpp_struct {                                                      \
+    f##_cpp_struct();                                                          \
+  };                                                                           \
+  UTEST_INITIALIZER_BEGIN_DISABLE_WARNINGS static f##_cpp_struct               \
+      f##_cpp_global UTEST_INITIALIZER_END_DISABLE_WARNINGS;                   \
+  f##_cpp_struct::f##_cpp_struct()
+#elif defined(_MSC_VER)
+#define UTEST_INLINE __forceinline
+
+#if defined(_WIN64)
+#define UTEST_SYMBOL_PREFIX
+#else
+#define UTEST_SYMBOL_PREFIX "_"
+#endif
+
+#if defined(__clang__)
+#define UTEST_INITIALIZER_BEGIN_DISABLE_WARNINGS                               \
+  _Pragma("clang diagnostic push")                                             \
+      _Pragma("clang diagnostic ignored \"-Wmissing-variable-declarations\"")
+
+#define UTEST_INITIALIZER_END_DISABLE_WARNINGS _Pragma("clang diagnostic pop")
+#else
+#define UTEST_INITIALIZER_BEGIN_DISABLE_WARNINGS
+#define UTEST_INITIALIZER_END_DISABLE_WARNINGS
+#endif
+
+#pragma section(".CRT$XCU", read)
+#define UTEST_INITIALIZER(f)                                                   \
+  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_INITIALIZER_END_DISABLE_WARNINGS                                       \
+  static void __cdecl f(void)
+#else
+#if defined(__linux__)
+#if defined(__clang__)
+#if __has_warning("-Wreserved-id-macro")
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wreserved-id-macro"
+#endif
+#endif
+
+#define __STDC_FORMAT_MACROS 1
+
+#if defined(__clang__)
+#if __has_warning("-Wreserved-id-macro")
+#pragma clang diagnostic pop
+#endif
+#endif
+#endif
+
+#define UTEST_INLINE inline
+
+#define UTEST_INITIALIZER(f)                                                   \
+  static void f(void) UTEST_ATTRIBUTE(constructor);                            \
+  static void f(void)
+#endif
+
+#if defined(__cplusplus)
+#define UTEST_CAST(type, x) static_cast<type>(x)
+#define UTEST_PTR_CAST(type, x) reinterpret_cast<type>(x)
+#define UTEST_EXTERN extern "C"
+#define UTEST_NULL NULL
+#else
+#define UTEST_CAST(type, x) ((type)(x))
+#define UTEST_PTR_CAST(type, x) ((type)(x))
+#define UTEST_EXTERN extern
+#define UTEST_NULL 0
+#endif
+
+#ifdef _MSC_VER
+/*
+    io.h contains definitions for some structures with natural padding. This is
+    uninteresting, but for some reason MSVC's behaviour is to warn about
+    including this system header. That *is* interesting
+*/
+#pragma warning(disable : 4820)
+#pragma warning(push, 1)
+#include <io.h>
+#pragma warning(pop)
+#define UTEST_COLOUR_OUTPUT() (_isatty(_fileno(stdout)))
+#else
+#if defined(__EMSCRIPTEN__)
+#include <emscripten/html5.h>
+#define UTEST_COLOUR_OUTPUT() false
+#else
+#include <unistd.h>
+#define UTEST_COLOUR_OUTPUT() (isatty(STDOUT_FILENO))
+#endif
+#endif
+
+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);
+  }
+
+  return new_pointer;
+}
+
+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);
+#elif defined(__linux__) && defined(__STRICT_ANSI__)
+  return UTEST_CAST(utest_int64_t, clock()) * 1000000000 / CLOCKS_PER_SEC;
+#elif defined(__linux__) || defined(__FreeBSD__) || defined(__OpenBSD__) ||    \
+    defined(__NetBSD__) || defined(__DragonFly__) || defined(__sun__) ||       \
+    defined(__HAIKU__)
+  struct timespec ts;
+#if defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 201112L) &&              \
+    !defined(__HAIKU__)
+  timespec_get(&ts, TIME_UTC);
+#else
+  const clockid_t cid = CLOCK_REALTIME;
+#if defined(UTEST_USE_CLOCKGETTIME)
+  clock_gettime(cid, &ts);
+#else
+  syscall(SYS_clock_gettime, cid, &ts);
+#endif
+#endif
+  return UTEST_CAST(utest_int64_t, ts.tv_sec) * 1000 * 1000 * 1000 + ts.tv_nsec;
+#elif __APPLE__
+  return UTEST_CAST(utest_int64_t, clock_gettime_nsec_np(CLOCK_UPTIME_RAW));
+#elif __EMSCRIPTEN__
+  return emscripten_performance_now() * 1000000.0;
+#else
+#error Unsupported platform!
+#endif
+}
+
+typedef void (*utest_testcase_t)(int *, size_t);
+
+struct utest_test_state_s {
+  utest_testcase_t func;
+  size_t index;
+  char *name;
+};
+
+struct utest_state_s {
+  struct utest_test_state_s *tests;
+  size_t tests_length;
+  FILE *output;
+};
+
+/* extern to the global state utest needs to execute */
+UTEST_EXTERN struct utest_state_s utest_state;
+
+#if defined(_MSC_VER)
+#define UTEST_WEAK __forceinline
+#elif defined(__MINGW32__) || defined(__MINGW64__)
+#define UTEST_WEAK static UTEST_ATTRIBUTE(used)
+#elif defined(__clang__) || defined(__GNUC__) || defined(__TINYC__)
+#define UTEST_WEAK UTEST_ATTRIBUTE(weak)
+#else
+#error Non clang, non gcc, non MSVC, non tcc compiler found!
+#endif
+
+#if defined(_MSC_VER)
+#define UTEST_UNUSED
+#else
+#define UTEST_UNUSED UTEST_ATTRIBUTE(unused)
+#endif
+
+#ifdef __clang__
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wvariadic-macros"
+#pragma clang diagnostic ignored "-Wc++98-compat-pedantic"
+#endif
+#define UTEST_PRINTF(...)                                                      \
+  if (utest_state.output) {                                                    \
+    fprintf(utest_state.output, __VA_ARGS__);                                  \
+  }                                                                            \
+  printf(__VA_ARGS__)
+#ifdef __clang__
+#pragma clang diagnostic pop
+#endif
+
+#ifdef __clang__
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wvariadic-macros"
+#pragma clang diagnostic ignored "-Wc++98-compat-pedantic"
+#endif
+
+#ifdef _MSC_VER
+#define UTEST_SNPRINTF(BUFFER, N, ...) _snprintf_s(BUFFER, N, N, __VA_ARGS__)
+#else
+#define UTEST_SNPRINTF(...) snprintf(__VA_ARGS__)
+#endif
+
+#ifdef __clang__
+#pragma clang diagnostic pop
+#endif
+
+#if defined(__cplusplus)
+/* if we are using c++ we can use overloaded methods (its in the language) */
+#define UTEST_OVERLOADABLE
+#elif defined(__clang__)
+/* otherwise, if we are using clang with c - use the overloadable attribute */
+#define UTEST_OVERLOADABLE UTEST_ATTRIBUTE(overloadable)
+#endif
+
+#if defined(__cplusplus) && (__cplusplus >= 201103L)
+
+#ifdef __clang__
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wc++98-compat-pedantic"
+#endif
+
+#include <type_traits>
+
+template <typename T, bool is_enum = std::is_enum<T>::value>
+struct utest_type_deducer final {
+  static void _(const T t);
+};
+
+template <> struct utest_type_deducer<signed char, false> {
+  static void _(const signed char c) {
+    UTEST_PRINTF("%d", static_cast<int>(c));
+  }
+};
+
+template <> struct utest_type_deducer<unsigned char, false> {
+  static void _(const unsigned char c) {
+    UTEST_PRINTF("%u", static_cast<unsigned int>(c));
+  }
+};
+
+template <> struct utest_type_deducer<short, false> {
+  static void _(const short s) { UTEST_PRINTF("%d", static_cast<int>(s)); }
+};
+
+template <> struct utest_type_deducer<unsigned short, false> {
+  static void _(const unsigned short s) {
+    UTEST_PRINTF("%u", static_cast<int>(s));
+  }
+};
+
+template <> struct utest_type_deducer<float, false> {
+  static void _(const float f) { UTEST_PRINTF("%f", static_cast<double>(f)); }
+};
+
+template <> struct utest_type_deducer<double, false> {
+  static void _(const double d) { UTEST_PRINTF("%f", d); }
+};
+
+template <> struct utest_type_deducer<long double, false> {
+  static void _(const long double d) {
+#if defined(__MINGW32__) || defined(__MINGW64__)
+    /* MINGW is weird - doesn't like LF at all?! */
+    UTEST_PRINTF("%f", (double)d);
+#else
+    UTEST_PRINTF("%Lf", d);
+#endif
+  }
+};
+
+template <> struct utest_type_deducer<int, false> {
+  static void _(const int i) { UTEST_PRINTF("%d", i); }
+};
+
+template <> struct utest_type_deducer<unsigned int, false> {
+  static void _(const unsigned int i) { UTEST_PRINTF("%u", i); }
+};
+
+template <> struct utest_type_deducer<long, false> {
+  static void _(const long i) { UTEST_PRINTF("%ld", i); }
+};
+
+template <> struct utest_type_deducer<unsigned long, false> {
+  static void _(const unsigned long i) { UTEST_PRINTF("%lu", i); }
+};
+
+template <> struct utest_type_deducer<long long, false> {
+  static void _(const long long i) { UTEST_PRINTF("%lld", i); }
+};
+
+template <> struct utest_type_deducer<unsigned long long, false> {
+  static void _(const unsigned long long i) { UTEST_PRINTF("%llu", i); }
+};
+
+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)));
+  }
+};
+
+template <typename T> struct utest_type_deducer<T *, false> {
+  static void _(T *t) { UTEST_PRINTF("%p", static_cast<void *>(t)); }
+};
+
+template <typename T> struct utest_type_deducer<T, true> {
+  static void _(const T t) {
+    UTEST_PRINTF("%llu", static_cast<unsigned long long>(t));
+  }
+};
+
+template <typename T>
+UTEST_WEAK UTEST_OVERLOADABLE void utest_type_printer(const T t) {
+  utest_type_deducer<T>::_(t);
+}
+
+#ifdef __clang__
+#pragma clang diagnostic pop
+#endif
+
+#elif defined(UTEST_OVERLOADABLE)
+
+UTEST_WEAK UTEST_OVERLOADABLE void utest_type_printer(signed char c);
+UTEST_WEAK UTEST_OVERLOADABLE void utest_type_printer(signed char c) {
+  UTEST_PRINTF("%d", UTEST_CAST(int, c));
+}
+
+UTEST_WEAK UTEST_OVERLOADABLE void utest_type_printer(unsigned char c);
+UTEST_WEAK UTEST_OVERLOADABLE void utest_type_printer(unsigned char c) {
+  UTEST_PRINTF("%u", UTEST_CAST(unsigned int, c));
+}
+
+UTEST_WEAK UTEST_OVERLOADABLE void utest_type_printer(float f);
+UTEST_WEAK UTEST_OVERLOADABLE void utest_type_printer(float f) {
+  UTEST_PRINTF("%f", UTEST_CAST(double, f));
+}
+
+UTEST_WEAK UTEST_OVERLOADABLE void utest_type_printer(double d);
+UTEST_WEAK UTEST_OVERLOADABLE void utest_type_printer(double d) {
+  UTEST_PRINTF("%f", d);
+}
+
+UTEST_WEAK UTEST_OVERLOADABLE void utest_type_printer(long double d);
+UTEST_WEAK UTEST_OVERLOADABLE void utest_type_printer(long double d) {
+#if defined(__MINGW32__) || defined(__MINGW64__)
+  /* MINGW is weird - doesn't like LF at all?! */
+  UTEST_PRINTF("%f", (double)d);
+#else
+  UTEST_PRINTF("%Lf", d);
+#endif
+}
+
+UTEST_WEAK UTEST_OVERLOADABLE void utest_type_printer(int i);
+UTEST_WEAK UTEST_OVERLOADABLE void utest_type_printer(int i) {
+  UTEST_PRINTF("%d", i);
+}
+
+UTEST_WEAK UTEST_OVERLOADABLE void utest_type_printer(unsigned int i);
+UTEST_WEAK UTEST_OVERLOADABLE void utest_type_printer(unsigned int i) {
+  UTEST_PRINTF("%u", i);
+}
+
+UTEST_WEAK UTEST_OVERLOADABLE void utest_type_printer(long int i);
+UTEST_WEAK UTEST_OVERLOADABLE void utest_type_printer(long int i) {
+  UTEST_PRINTF("%ld", i);
+}
+
+UTEST_WEAK UTEST_OVERLOADABLE void utest_type_printer(long unsigned int i);
+UTEST_WEAK UTEST_OVERLOADABLE void utest_type_printer(long unsigned int i) {
+  UTEST_PRINTF("%lu", i);
+}
+
+UTEST_WEAK UTEST_OVERLOADABLE void utest_type_printer(const void *p);
+UTEST_WEAK UTEST_OVERLOADABLE void utest_type_printer(const void *p) {
+  UTEST_PRINTF("%p", p);
+}
+
+/*
+   long long is a c++11 extension
+*/
+#if defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) ||              \
+    defined(__cplusplus) && (__cplusplus >= 201103L) ||                        \
+    (defined(__MINGW32__) || defined(__MINGW64__))
+
+#ifdef __clang__
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wc++98-compat-pedantic"
+#endif
+
+UTEST_WEAK UTEST_OVERLOADABLE void utest_type_printer(long long int i);
+UTEST_WEAK UTEST_OVERLOADABLE void utest_type_printer(long long int i) {
+  UTEST_PRINTF("%lld", i);
+}
+
+UTEST_WEAK UTEST_OVERLOADABLE void utest_type_printer(long long unsigned int i);
+UTEST_WEAK UTEST_OVERLOADABLE void
+utest_type_printer(long long unsigned int i) {
+  UTEST_PRINTF("%llu", i);
+}
+
+#ifdef __clang__
+#pragma clang diagnostic pop
+#endif
+
+#endif
+#elif defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 201112L) &&            \
+        !(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))
+#else
+/*
+   we don't have the ability to print the values we got, so we create a macro
+   to tell our users we can't do anything fancy
+*/
+#define utest_type_printer(...) UTEST_PRINTF("undef")
+#endif
+
+#ifdef _MSC_VER
+#define UTEST_SURPRESS_WARNING_BEGIN                                           \
+  __pragma(warning(push)) __pragma(warning(disable : 4127))                    \
+      __pragma(warning(disable : 4571)) __pragma(warning(disable : 4130))
+#define UTEST_SURPRESS_WARNING_END __pragma(warning(pop))
+#else
+#define UTEST_SURPRESS_WARNING_BEGIN
+#define UTEST_SURPRESS_WARNING_END
+#endif
+
+#if defined(__cplusplus) && (__cplusplus >= 201103L)
+#define UTEST_AUTO(x) auto
+#elif !defined(__cplusplus)
+
+#if defined(__clang__)
+/* clang-format off */
+/* had to disable clang-format here because it malforms the pragmas */
+#define UTEST_AUTO(x)                                                          \
+  _Pragma("clang diagnostic push")                                             \
+      _Pragma("clang diagnostic ignored \"-Wgnu-auto-type\"") __auto_type      \
+          _Pragma("clang diagnostic pop")
+/* clang-format on */
+#else
+#define UTEST_AUTO(x) __typeof__(x + 0)
+#endif
+
+#else
+#define UTEST_AUTO(x) typeof(x + 0)
+#endif
+
+#if defined(__clang__)
+#define UTEST_STRNCMP(x, y, size)                                              \
+  _Pragma("clang diagnostic push")                                             \
+      _Pragma("clang diagnostic ignored \"-Wdisabled-macro-expansion\"")       \
+          strncmp(x, y, size) _Pragma("clang diagnostic pop")
+#else
+#define UTEST_STRNCMP(x, y, size) strncmp(x, y, size)
+#endif
+
+#define UTEST_SKIP(msg)                                                        \
+  do {                                                                         \
+    UTEST_PRINTF("   Skipped : '%s'\n", (msg));                                \
+    *utest_result = UTEST_TEST_SKIPPED;                                        \
+    return;                                                                    \
+  } while (0)
+
+#if defined(__clang__)
+#define UTEST_EXPECT(x, y, cond)                                               \
+  UTEST_SURPRESS_WARNING_BEGIN do {                                            \
+    _Pragma("clang diagnostic push")                                           \
+        _Pragma("clang diagnostic ignored \"-Wlanguage-extension-token\"")     \
+            _Pragma("clang diagnostic ignored \"-Wc++98-compat-pedantic\"")    \
+                _Pragma("clang diagnostic ignored \"-Wfloat-equal\"")          \
+                    UTEST_AUTO(x) xEval = (x);                                 \
+    UTEST_AUTO(y) yEval = (y);                                                 \
+    if (!((xEval)cond(yEval))) {                                               \
+      _Pragma("clang diagnostic pop")                                          \
+          UTEST_PRINTF("%s:%i: Failure\n", __FILE__, __LINE__);                \
+      UTEST_PRINTF("  Expected : (");                                          \
+      UTEST_PRINTF(#x ") " #cond " (" #y);                                     \
+      UTEST_PRINTF(")\n");                                                     \
+      UTEST_PRINTF("    Actual : ");                                           \
+      utest_type_printer(xEval);                                               \
+      UTEST_PRINTF(" vs ");                                                    \
+      utest_type_printer(yEval);                                               \
+      UTEST_PRINTF("\n");                                                      \
+      *utest_result = UTEST_TEST_FAILURE;                                      \
+    }                                                                          \
+  }                                                                            \
+  while (0)                                                                    \
+  UTEST_SURPRESS_WARNING_END
+#elif defined(__GNUC__) || defined(__TINYC__)
+#define UTEST_EXPECT(x, y, cond)                                               \
+  UTEST_SURPRESS_WARNING_BEGIN do {                                            \
+    UTEST_AUTO(x) xEval = (x);                                                 \
+    UTEST_AUTO(y) yEval = (y);                                                 \
+    if (!((xEval)cond(yEval))) {                                               \
+      UTEST_PRINTF("%s:%i: Failure\n", __FILE__, __LINE__);                    \
+      UTEST_PRINTF("  Expected : (");                                          \
+      UTEST_PRINTF(#x ") " #cond " (" #y);                                     \
+      UTEST_PRINTF(")\n");                                                     \
+      UTEST_PRINTF("    Actual : ");                                           \
+      utest_type_printer(xEval);                                               \
+      UTEST_PRINTF(" vs ");                                                    \
+      utest_type_printer(yEval);                                               \
+      UTEST_PRINTF("\n");                                                      \
+      *utest_result = UTEST_TEST_FAILURE;                                      \
+    }                                                                          \
+  }                                                                            \
+  while (0)                                                                    \
+  UTEST_SURPRESS_WARNING_END
+#else
+#define UTEST_EXPECT(x, y, cond)                                               \
+  UTEST_SURPRESS_WARNING_BEGIN do {                                            \
+    if (!((x)cond(y))) {                                                       \
+      UTEST_PRINTF("%s:%i: Failure (Expected " #cond " Actual)\n", __FILE__,   \
+                   __LINE__);                                                  \
+      *utest_result = UTEST_TEST_FAILURE;                                      \
+    }                                                                          \
+  }                                                                            \
+  while (0)                                                                    \
+  UTEST_SURPRESS_WARNING_END
+#endif
+
+#define EXPECT_TRUE(x)                                                         \
+  UTEST_SURPRESS_WARNING_BEGIN do {                                            \
+    const int xEval = !!(x);                                                   \
+    if (!(xEval)) {                                                            \
+      UTEST_PRINTF("%s:%i: Failure\n", __FILE__, __LINE__);                    \
+      UTEST_PRINTF("  Expected : true\n");                                     \
+      UTEST_PRINTF("    Actual : %s\n", (xEval) ? "true" : "false");           \
+      *utest_result = UTEST_TEST_FAILURE;                                      \
+    }                                                                          \
+  }                                                                            \
+  while (0)                                                                    \
+  UTEST_SURPRESS_WARNING_END
+
+#define EXPECT_FALSE(x)                                                        \
+  UTEST_SURPRESS_WARNING_BEGIN do {                                            \
+    const int xEval = !!(x);                                                   \
+    if (xEval) {                                                               \
+      UTEST_PRINTF("%s:%i: Failure\n", __FILE__, __LINE__);                    \
+      UTEST_PRINTF("  Expected : false\n");                                    \
+      UTEST_PRINTF("    Actual : %s\n", (xEval) ? "true" : "false");           \
+      *utest_result = UTEST_TEST_FAILURE;                                      \
+    }                                                                          \
+  }                                                                            \
+  while (0)                                                                    \
+  UTEST_SURPRESS_WARNING_END
+
+#define EXPECT_EQ(x, y) UTEST_EXPECT(x, y, ==)
+#define EXPECT_NE(x, y) UTEST_EXPECT(x, y, !=)
+#define EXPECT_LT(x, y) UTEST_EXPECT(x, y, <)
+#define EXPECT_LE(x, y) UTEST_EXPECT(x, y, <=)
+#define EXPECT_GT(x, y) UTEST_EXPECT(x, y, >)
+#define EXPECT_GE(x, y) UTEST_EXPECT(x, y, >=)
+
+#define EXPECT_STREQ(x, y)                                                     \
+  UTEST_SURPRESS_WARNING_BEGIN do {                                            \
+    const char *xEval = (x);                                                   \
+    const char *yEval = (y);                                                   \
+    if (UTEST_NULL == xEval || UTEST_NULL == yEval ||                          \
+        0 != strcmp(xEval, yEval)) {                                           \
+      UTEST_PRINTF("%s:%i: Failure\n", __FILE__, __LINE__);                    \
+      UTEST_PRINTF("  Expected : \"%s\"\n", xEval);                            \
+      UTEST_PRINTF("    Actual : \"%s\"\n", yEval);                            \
+      *utest_result = UTEST_TEST_FAILURE;                                      \
+    }                                                                          \
+  }                                                                            \
+  while (0)                                                                    \
+  UTEST_SURPRESS_WARNING_END
+
+#define EXPECT_STRNE(x, y)                                                     \
+  UTEST_SURPRESS_WARNING_BEGIN do {                                            \
+    const char *xEval = (x);                                                   \
+    const char *yEval = (y);                                                   \
+    if (UTEST_NULL == xEval || UTEST_NULL == yEval ||                          \
+        0 == strcmp(xEval, yEval)) {                                           \
+      UTEST_PRINTF("%s:%i: Failure\n", __FILE__, __LINE__);                    \
+      UTEST_PRINTF("  Expected : \"%s\"\n", xEval);                            \
+      UTEST_PRINTF("    Actual : \"%s\"\n", yEval);                            \
+      *utest_result = UTEST_TEST_FAILURE;                                      \
+    }                                                                          \
+  }                                                                            \
+  while (0)                                                                    \
+  UTEST_SURPRESS_WARNING_END
+
+#define EXPECT_STRNEQ(x, y, n)                                                 \
+  UTEST_SURPRESS_WARNING_BEGIN do {                                            \
+    const char *xEval = (x);                                                   \
+    const char *yEval = (y);                                                   \
+    const size_t nEval = UTEST_CAST(size_t, n);                                \
+    if (UTEST_NULL == xEval || UTEST_NULL == yEval ||                          \
+        0 != UTEST_STRNCMP(xEval, yEval, nEval)) {                             \
+      UTEST_PRINTF("%s:%i: Failure\n", __FILE__, __LINE__);                    \
+      UTEST_PRINTF("  Expected : \"%.*s\"\n", UTEST_CAST(int, nEval), xEval);  \
+      UTEST_PRINTF("    Actual : \"%.*s\"\n", UTEST_CAST(int, nEval), yEval);  \
+      *utest_result = UTEST_TEST_FAILURE;                                      \
+    }                                                                          \
+  }                                                                            \
+  while (0)                                                                    \
+  UTEST_SURPRESS_WARNING_END
+
+#define EXPECT_STRNNE(x, y, n)                                                 \
+  UTEST_SURPRESS_WARNING_BEGIN do {                                            \
+    const char *xEval = (x);                                                   \
+    const char *yEval = (y);                                                   \
+    const size_t nEval = UTEST_CAST(size_t, n);                                \
+    if (UTEST_NULL == xEval || UTEST_NULL == yEval ||                          \
+        0 == UTEST_STRNCMP(xEval, yEval, nEval)) {                             \
+      UTEST_PRINTF("%s:%i: Failure\n", __FILE__, __LINE__);                    \
+      UTEST_PRINTF("  Expected : \"%.*s\"\n", UTEST_CAST(int, nEval), xEval);  \
+      UTEST_PRINTF("    Actual : \"%.*s\"\n", UTEST_CAST(int, nEval), yEval);  \
+      *utest_result = UTEST_TEST_FAILURE;                                      \
+    }                                                                          \
+  }                                                                            \
+  while (0)                                                                    \
+  UTEST_SURPRESS_WARNING_END
+
+#define EXPECT_NEAR(x, y, epsilon)                                             \
+  UTEST_SURPRESS_WARNING_BEGIN do {                                            \
+    const double diff =                                                        \
+        utest_fabs(UTEST_CAST(double, x) - UTEST_CAST(double, y));             \
+    if (diff > UTEST_CAST(double, epsilon) || utest_isnan(diff)) {             \
+      UTEST_PRINTF("%s:%i: Failure\n", __FILE__, __LINE__);                    \
+      UTEST_PRINTF("  Expected : %f\n", UTEST_CAST(double, x));                \
+      UTEST_PRINTF("    Actual : %f\n", UTEST_CAST(double, y));                \
+      *utest_result = UTEST_TEST_FAILURE;                                      \
+    }                                                                          \
+  }                                                                            \
+  while (0)                                                                    \
+  UTEST_SURPRESS_WARNING_END
+
+#if defined(UTEST_HAS_EXCEPTIONS)
+#define EXPECT_EXCEPTION(x, exception_type)                                    \
+  UTEST_SURPRESS_WARNING_BEGIN do {                                            \
+    int exception_caught = 0;                                                  \
+    try {                                                                      \
+      x;                                                                       \
+    } catch (const exception_type &) {                                         \
+      exception_caught = 1;                                                    \
+    } catch (...) {                                                            \
+      exception_caught = 2;                                                    \
+    }                                                                          \
+    if (exception_caught != 1) {                                               \
+      UTEST_PRINTF("%s:%i: Failure\n", __FILE__, __LINE__);                    \
+      UTEST_PRINTF("  Expected : %s exception\n", #exception_type);            \
+      UTEST_PRINTF("    Actual : %s\n", (exception_caught == 2)                \
+                                            ? "Unexpected exception"           \
+                                            : "No exception");                 \
+      *utest_result = UTEST_TEST_FAILURE;                                      \
+    }                                                                          \
+  }                                                                            \
+  while (0)                                                                    \
+  UTEST_SURPRESS_WARNING_END
+#endif
+
+#if defined(__clang__)
+#define UTEST_ASSERT(x, y, cond)                                               \
+  UTEST_SURPRESS_WARNING_BEGIN do {                                            \
+    _Pragma("clang diagnostic push")                                           \
+        _Pragma("clang diagnostic ignored \"-Wlanguage-extension-token\"")     \
+            _Pragma("clang diagnostic ignored \"-Wc++98-compat-pedantic\"")    \
+                _Pragma("clang diagnostic ignored \"-Wfloat-equal\"")          \
+                    UTEST_AUTO(x) xEval = (x);                                 \
+    UTEST_AUTO(y) yEval = (y);                                                 \
+    if (!((xEval)cond(yEval))) {                                               \
+      _Pragma("clang diagnostic pop")                                          \
+          UTEST_PRINTF("%s:%i: Failure\n", __FILE__, __LINE__);                \
+      UTEST_PRINTF("  Expected : (");                                          \
+      UTEST_PRINTF(#x ") " #cond " (" #y);                                     \
+      UTEST_PRINTF(")\n");                                                     \
+      UTEST_PRINTF("    Actual : ");                                           \
+      utest_type_printer(xEval);                                               \
+      UTEST_PRINTF(" vs ");                                                    \
+      utest_type_printer(yEval);                                               \
+      UTEST_PRINTF("\n");                                                      \
+      *utest_result = UTEST_TEST_FAILURE;                                      \
+      return;                                                                  \
+    }                                                                          \
+  }                                                                            \
+  while (0)                                                                    \
+  UTEST_SURPRESS_WARNING_END
+#elif defined(__GNUC__) || defined(__TINYC__)
+#define UTEST_ASSERT(x, y, cond)                                               \
+  UTEST_SURPRESS_WARNING_BEGIN do {                                            \
+    UTEST_AUTO(x) xEval = (x);                                                 \
+    UTEST_AUTO(y) yEval = (y);                                                 \
+    if (!((xEval)cond(yEval))) {                                               \
+      UTEST_PRINTF("%s:%i: Failure\n", __FILE__, __LINE__);                    \
+      UTEST_PRINTF("  Expected : (");                                          \
+      UTEST_PRINTF(#x ") " #cond " (" #y);                                     \
+      UTEST_PRINTF(")\n");                                                     \
+      UTEST_PRINTF("    Actual : ");                                           \
+      utest_type_printer(xEval);                                               \
+      UTEST_PRINTF(" vs ");                                                    \
+      utest_type_printer(yEval);                                               \
+      UTEST_PRINTF("\n");                                                      \
+      *utest_result = UTEST_TEST_FAILURE;                                      \
+      return;                                                                  \
+    }                                                                          \
+  }                                                                            \
+  while (0)                                                                    \
+  UTEST_SURPRESS_WARNING_END
+#else
+#define UTEST_ASSERT(x, y, cond)                                               \
+  UTEST_SURPRESS_WARNING_BEGIN do {                                            \
+    if (!((x)cond(y))) {                                                       \
+      UTEST_PRINTF("%s:%i: Failure (Expected " #cond " Actual)\n", __FILE__,   \
+                   __LINE__);                                                  \
+      *utest_result = UTEST_TEST_FAILURE;                                      \
+      return;                                                                  \
+    }                                                                          \
+  }                                                                            \
+  while (0)                                                                    \
+  UTEST_SURPRESS_WARNING_END
+#endif
+
+#define ASSERT_TRUE(x)                                                         \
+  UTEST_SURPRESS_WARNING_BEGIN do {                                            \
+    const int xEval = !!(x);                                                   \
+    if (!(xEval)) {                                                            \
+      UTEST_PRINTF("%s:%i: Failure\n", __FILE__, __LINE__);                    \
+      UTEST_PRINTF("  Expected : true\n");                                     \
+      UTEST_PRINTF("    Actual : %s\n", (xEval) ? "true" : "false");           \
+      *utest_result = UTEST_TEST_FAILURE;                                      \
+      return;                                                                  \
+    }                                                                          \
+  }                                                                            \
+  while (0)                                                                    \
+  UTEST_SURPRESS_WARNING_END
+
+#define ASSERT_FALSE(x)                                                        \
+  UTEST_SURPRESS_WARNING_BEGIN do {                                            \
+    const int xEval = !!(x);                                                   \
+    if (xEval) {                                                               \
+      UTEST_PRINTF("%s:%i: Failure\n", __FILE__, __LINE__);                    \
+      UTEST_PRINTF("  Expected : false\n");                                    \
+      UTEST_PRINTF("    Actual : %s\n", (xEval) ? "true" : "false");           \
+      *utest_result = UTEST_TEST_FAILURE;                                      \
+      return;                                                                  \
+    }                                                                          \
+  }                                                                            \
+  while (0)                                                                    \
+  UTEST_SURPRESS_WARNING_END
+
+#define ASSERT_EQ(x, y) UTEST_ASSERT(x, y, ==)
+#define ASSERT_NE(x, y) UTEST_ASSERT(x, y, !=)
+#define ASSERT_LT(x, y) UTEST_ASSERT(x, y, <)
+#define ASSERT_LE(x, y) UTEST_ASSERT(x, y, <=)
+#define ASSERT_GT(x, y) UTEST_ASSERT(x, y, >)
+#define ASSERT_GE(x, y) UTEST_ASSERT(x, y, >=)
+
+#define ASSERT_STREQ(x, y)                                                     \
+  UTEST_SURPRESS_WARNING_BEGIN do {                                            \
+    const char *xEval = (x);                                                   \
+    const char *yEval = (y);                                                   \
+    if (UTEST_NULL == xEval || UTEST_NULL == yEval ||                          \
+        0 != strcmp(xEval, yEval)) {                                           \
+      UTEST_PRINTF("%s:%i: Failure\n", __FILE__, __LINE__);                    \
+      UTEST_PRINTF("  Expected : \"%s\"\n", xEval);                            \
+      UTEST_PRINTF("    Actual : \"%s\"\n", yEval);                            \
+      *utest_result = UTEST_TEST_FAILURE;                                      \
+      return;                                                                  \
+    }                                                                          \
+  }                                                                            \
+  while (0)                                                                    \
+  UTEST_SURPRESS_WARNING_END
+
+#define ASSERT_STRNE(x, y)                                                     \
+  UTEST_SURPRESS_WARNING_BEGIN do {                                            \
+    const char *xEval = (x);                                                   \
+    const char *yEval = (y);                                                   \
+    if (UTEST_NULL == xEval || UTEST_NULL == yEval ||                          \
+        0 == strcmp(xEval, yEval)) {                                           \
+      UTEST_PRINTF("%s:%i: Failure\n", __FILE__, __LINE__);                    \
+      UTEST_PRINTF("  Expected : \"%s\"\n", xEval);                            \
+      UTEST_PRINTF("    Actual : \"%s\"\n", yEval);                            \
+      *utest_result = UTEST_TEST_FAILURE;                                      \
+      return;                                                                  \
+    }                                                                          \
+  }                                                                            \
+  while (0)                                                                    \
+  UTEST_SURPRESS_WARNING_END
+
+#define ASSERT_STRNEQ(x, y, n)                                                 \
+  UTEST_SURPRESS_WARNING_BEGIN do {                                            \
+    const char *xEval = (x);                                                   \
+    const char *yEval = (y);                                                   \
+    const size_t nEval = UTEST_CAST(size_t, n);                                \
+    if (UTEST_NULL == xEval || UTEST_NULL == yEval ||                          \
+        0 != UTEST_STRNCMP(xEval, yEval, nEval)) {                             \
+      UTEST_PRINTF("%s:%i: Failure\n", __FILE__, __LINE__);                    \
+      UTEST_PRINTF("  Expected : \"%.*s\"\n", UTEST_CAST(int, nEval), xEval);  \
+      UTEST_PRINTF("    Actual : \"%.*s\"\n", UTEST_CAST(int, nEval), yEval);  \
+      *utest_result = UTEST_TEST_FAILURE;                                      \
+      return;                                                                  \
+    }                                                                          \
+  }                                                                            \
+  while (0)                                                                    \
+  UTEST_SURPRESS_WARNING_END
+
+#define ASSERT_STRNNE(x, y, n)                                                 \
+  UTEST_SURPRESS_WARNING_BEGIN do {                                            \
+    const char *xEval = (x);                                                   \
+    const char *yEval = (y);                                                   \
+    const size_t nEval = UTEST_CAST(size_t, n);                                \
+    if (UTEST_NULL == xEval || UTEST_NULL == yEval ||                          \
+        0 == UTEST_STRNCMP(xEval, yEval, nEval)) {                             \
+      UTEST_PRINTF("%s:%i: Failure\n", __FILE__, __LINE__);                    \
+      UTEST_PRINTF("  Expected : \"%.*s\"\n", UTEST_CAST(int, nEval), xEval);  \
+      UTEST_PRINTF("    Actual : \"%.*s\"\n", UTEST_CAST(int, nEval), yEval);  \
+      *utest_result = UTEST_TEST_FAILURE;                                      \
+      return;                                                                  \
+    }                                                                          \
+  }                                                                            \
+  while (0)                                                                    \
+  UTEST_SURPRESS_WARNING_END
+
+#define ASSERT_NEAR(x, y, epsilon)                                             \
+  UTEST_SURPRESS_WARNING_BEGIN do {                                            \
+    const double diff =                                                        \
+        utest_fabs(UTEST_CAST(double, x) - UTEST_CAST(double, y));             \
+    if (diff > UTEST_CAST(double, epsilon) || utest_isnan(diff)) {             \
+      UTEST_PRINTF("%s:%i: Failure\n", __FILE__, __LINE__);                    \
+      UTEST_PRINTF("  Expected : %f\n", UTEST_CAST(double, x));                \
+      UTEST_PRINTF("    Actual : %f\n", UTEST_CAST(double, y));                \
+      *utest_result = UTEST_TEST_FAILURE;                                      \
+      return;                                                                  \
+    }                                                                          \
+  }                                                                            \
+  while (0)                                                                    \
+  UTEST_SURPRESS_WARNING_END
+
+#if defined(UTEST_HAS_EXCEPTIONS)
+#define ASSERT_EXCEPTION(x, exception_type)                                    \
+  UTEST_SURPRESS_WARNING_BEGIN do {                                            \
+    int exception_caught = 0;                                                  \
+    try {                                                                      \
+      x;                                                                       \
+    } catch (const exception_type &) {                                         \
+      exception_caught = 1;                                                    \
+    } catch (...) {                                                            \
+      exception_caught = 2;                                                    \
+    }                                                                          \
+    if (exception_caught != 1) {                                               \
+      UTEST_PRINTF("%s:%i: Failure\n", __FILE__, __LINE__);                    \
+      UTEST_PRINTF("  Expected : %s exception\n", #exception_type);            \
+      UTEST_PRINTF("    Actual : %s\n", (exception_caught == 2)                \
+                                            ? "Unexpected exception"           \
+                                            : "No exception");                 \
+      *utest_result = UTEST_TEST_FAILURE;                                      \
+      return;                                                                  \
+    }                                                                          \
+  }                                                                            \
+  while (0)                                                                    \
+  UTEST_SURPRESS_WARNING_END
+#endif
+
+#define UTEST(SET, NAME)                                                       \
+  UTEST_EXTERN struct utest_state_s utest_state;                               \
+  static void utest_run_##SET##_##NAME(int *utest_result);                     \
+  static void utest_##SET##_##NAME(int *utest_result, size_t utest_index) {    \
+    (void)utest_index;                                                         \
+    utest_run_##SET##_##NAME(utest_result);                                    \
+  }                                                                            \
+  UTEST_INITIALIZER(utest_register_##SET##_##NAME) {                           \
+    const size_t index = utest_state.tests_length++;                           \
+    const char *name_part = #SET "." #NAME;                                    \
+    const size_t name_size = strlen(name_part) + 1;                            \
+    char *name = UTEST_PTR_CAST(char *, malloc(name_size));                    \
+    utest_state.tests = UTEST_PTR_CAST(                                        \
+        struct utest_test_state_s *,                                           \
+        utest_realloc(UTEST_PTR_CAST(void *, utest_state.tests),               \
+                      sizeof(struct utest_test_state_s) *                      \
+                          utest_state.tests_length));                          \
+    if (utest_state.tests) {                                                   \
+      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);                                                              \
+    }                                                                          \
+  }                                                                            \
+  void utest_run_##SET##_##NAME(int *utest_result)
+
+#define UTEST_F_SETUP(FIXTURE)                                                 \
+  static void utest_f_setup_##FIXTURE(int *utest_result,                       \
+                                      struct FIXTURE *utest_fixture)
+
+#define UTEST_F_TEARDOWN(FIXTURE)                                              \
+  static void utest_f_teardown_##FIXTURE(int *utest_result,                    \
+                                         struct FIXTURE *utest_fixture)
+
+#if defined(__GNUC__) && __GNUC__ >= 8 && defined(__cplusplus)
+#define UTEST_FIXTURE_SURPRESS_WARNINGS_BEGIN                                  \
+  _Pragma("GCC diagnostic push")                                               \
+      _Pragma("GCC diagnostic ignored \"-Wclass-memaccess\"")
+#define UTEST_FIXTURE_SURPRESS_WARNINGS_END _Pragma("GCC diagnostic pop")
+#else
+#define UTEST_FIXTURE_SURPRESS_WARNINGS_BEGIN
+#define UTEST_FIXTURE_SURPRESS_WARNINGS_END
+#endif
+
+#define UTEST_F(FIXTURE, NAME)                                                 \
+  UTEST_FIXTURE_SURPRESS_WARNINGS_BEGIN                                        \
+  UTEST_EXTERN struct utest_state_s utest_state;                               \
+  static void utest_f_setup_##FIXTURE(int *, struct FIXTURE *);                \
+  static void utest_f_teardown_##FIXTURE(int *, struct FIXTURE *);             \
+  static void utest_run_##FIXTURE##_##NAME(int *, struct FIXTURE *);           \
+  static void utest_f_##FIXTURE##_##NAME(int *utest_result,                    \
+                                         size_t utest_index) {                 \
+    struct FIXTURE fixture;                                                    \
+    (void)utest_index;                                                         \
+    memset(&fixture, 0, sizeof(fixture));                                      \
+    utest_f_setup_##FIXTURE(utest_result, &fixture);                           \
+    if (UTEST_TEST_PASSED != *utest_result) {                                  \
+      return;                                                                  \
+    }                                                                          \
+    utest_run_##FIXTURE##_##NAME(utest_result, &fixture);                      \
+    utest_f_teardown_##FIXTURE(utest_result, &fixture);                        \
+  }                                                                            \
+  UTEST_INITIALIZER(utest_register_##FIXTURE##_##NAME) {                       \
+    const size_t index = utest_state.tests_length++;                           \
+    const char *name_part = #FIXTURE "." #NAME;                                \
+    const size_t name_size = strlen(name_part) + 1;                            \
+    char *name = UTEST_PTR_CAST(char *, malloc(name_size));                    \
+    utest_state.tests = UTEST_PTR_CAST(                                        \
+        struct utest_test_state_s *,                                           \
+        utest_realloc(UTEST_PTR_CAST(void *, utest_state.tests),               \
+                      sizeof(struct utest_test_state_s) *                      \
+                          utest_state.tests_length));                          \
+    if (utest_state.tests) {                                                   \
+      utest_state.tests[index].func = &utest_f_##FIXTURE##_##NAME;             \
+      utest_state.tests[index].name = name;                                    \
+      UTEST_SNPRINTF(name, name_size, "%s", name_part);                        \
+    } else if (name) {                                                         \
+      free(name);                                                              \
+    }                                                                          \
+  }                                                                            \
+  UTEST_FIXTURE_SURPRESS_WARNINGS_END                                          \
+  void utest_run_##FIXTURE##_##NAME(int *utest_result,                         \
+                                    struct FIXTURE *utest_fixture)
+
+#define UTEST_I_SETUP(FIXTURE)                                                 \
+  static void utest_i_setup_##FIXTURE(                                         \
+      int *utest_result, struct FIXTURE *utest_fixture, size_t utest_index)
+
+#define UTEST_I_TEARDOWN(FIXTURE)                                              \
+  static void utest_i_teardown_##FIXTURE(                                      \
+      int *utest_result, struct FIXTURE *utest_fixture, size_t utest_index)
+
+#define UTEST_I(FIXTURE, NAME, INDEX)                                          \
+  UTEST_EXTERN struct utest_state_s utest_state;                               \
+  static void utest_run_##FIXTURE##_##NAME##_##INDEX(int *, struct FIXTURE *); \
+  static void utest_i_##FIXTURE##_##NAME##_##INDEX(int *utest_result,          \
+                                                   size_t index) {             \
+    struct FIXTURE fixture;                                                    \
+    memset(&fixture, 0, sizeof(fixture));                                      \
+    utest_i_setup_##FIXTURE(utest_result, &fixture, index);                    \
+    if (UTEST_TEST_PASSED != *utest_result) {                                  \
+      return;                                                                  \
+    }                                                                          \
+    utest_run_##FIXTURE##_##NAME##_##INDEX(utest_result, &fixture);            \
+    utest_i_teardown_##FIXTURE(utest_result, &fixture, index);                 \
+  }                                                                            \
+  UTEST_INITIALIZER(utest_register_##FIXTURE##_##NAME##_##INDEX) {             \
+    size_t i;                                                                  \
+    utest_uint64_t iUp;                                                        \
+    for (i = 0; i < (INDEX); i++) {                                            \
+      const size_t index = utest_state.tests_length++;                         \
+      const char *name_part = #FIXTURE "." #NAME;                              \
+      const size_t name_size = strlen(name_part) + 32;                         \
+      char *name = UTEST_PTR_CAST(char *, malloc(name_size));                  \
+      utest_state.tests = UTEST_PTR_CAST(                                      \
+          struct utest_test_state_s *,                                         \
+          utest_realloc(UTEST_PTR_CAST(void *, utest_state.tests),             \
+                        sizeof(struct utest_test_state_s) *                    \
+                            utest_state.tests_length));                        \
+      if (utest_state.tests) {                                                 \
+        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);                                                            \
+      }                                                                        \
+    }                                                                          \
+  }                                                                            \
+  void utest_run_##FIXTURE##_##NAME##_##INDEX(int *utest_result,               \
+                                              struct FIXTURE *utest_fixture)
+
+UTEST_WEAK
+double utest_fabs(double d);
+UTEST_WEAK
+double utest_fabs(double d) {
+  union {
+    double d;
+    utest_uint64_t u;
+  } both;
+  both.d = d;
+  both.u &= 0x7fffffffffffffffu;
+  return both.d;
+}
+
+UTEST_WEAK
+int utest_isnan(double d);
+UTEST_WEAK
+int utest_isnan(double d) {
+  union {
+    double d;
+    utest_uint64_t u;
+  } both;
+  both.d = d;
+  both.u &= 0x7fffffffffffffffu;
+  return both.u > 0x7ff0000000000000u;
+}
+
+UTEST_WEAK
+int utest_should_filter_test(const char *filter, const char *testcase);
+UTEST_WEAK int utest_should_filter_test(const char *filter,
+                                        const char *testcase) {
+  if (filter) {
+    const char *filter_cur = filter;
+    const char *testcase_cur = testcase;
+    const char *filter_wildcard = UTEST_NULL;
+
+    while (('\0' != *filter_cur) && ('\0' != *testcase_cur)) {
+      if ('*' == *filter_cur) {
+        /* store the position of the wildcard */
+        filter_wildcard = filter_cur;
+
+        /* skip the wildcard character */
+        filter_cur++;
+
+        while (('\0' != *filter_cur) && ('\0' != *testcase_cur)) {
+          if ('*' == *filter_cur) {
+            /*
+               we found another wildcard (filter is something like *foo*) so we
+               exit the current loop, and return to the parent loop to handle
+               the wildcard case
+            */
+            break;
+          } else if (*filter_cur != *testcase_cur) {
+            /* otherwise our filter didn't match, so reset it */
+            filter_cur = filter_wildcard;
+          }
+
+          /* move testcase along */
+          testcase_cur++;
+
+          /* move filter along */
+          filter_cur++;
+        }
+
+        if (('\0' == *filter_cur) && ('\0' == *testcase_cur)) {
+          return 0;
+        }
+
+        /* if the testcase has been exhausted, we don't have a match! */
+        if ('\0' == *testcase_cur) {
+          return 1;
+        }
+      } else {
+        if (*testcase_cur != *filter_cur) {
+          /* test case doesn't match filter */
+          return 1;
+        } else {
+          /* move our filter and testcase forward */
+          testcase_cur++;
+          filter_cur++;
+        }
+      }
+    }
+
+    if (('\0' != *filter_cur) ||
+        (('\0' != *testcase_cur) &&
+         ((filter == filter_cur) || ('*' != filter_cur[-1])))) {
+      /* we have a mismatch! */
+      return 1;
+    }
+  }
+
+  return 0;
+}
+
+static UTEST_INLINE FILE *utest_fopen(const char *filename, const char *mode) {
+#ifdef _MSC_VER
+  FILE *file;
+  if (0 == fopen_s(&file, filename, mode)) {
+    return file;
+  } else {
+    return UTEST_NULL;
+  }
+#else
+  return fopen(filename, mode);
+#endif
+}
+
+static UTEST_INLINE int utest_main(int argc, const char *const argv[]);
+int utest_main(int argc, const char *const argv[]) {
+  utest_uint64_t failed = 0;
+  utest_uint64_t skipped = 0;
+  size_t index = 0;
+  size_t *failed_testcases = UTEST_NULL;
+  size_t failed_testcases_length = 0;
+  size_t *skipped_testcases = UTEST_NULL;
+  size_t skipped_testcases_length = 0;
+  const char *filter = UTEST_NULL;
+  utest_uint64_t ran_tests = 0;
+  int enable_mixed_units = 0;
+  int random_order = 0;
+  utest_uint32_t seed = 0;
+
+  enum colours { RESET, GREEN, RED, YELLOW };
+
+  const int use_colours = UTEST_COLOUR_OUTPUT();
+  const char *colours[] = {"\033[0m", "\033[32m", "\033[31m", "\033[33m"};
+
+  if (!use_colours) {
+    for (index = 0; index < sizeof colours / sizeof colours[0]; index++) {
+      colours[index] = "";
+    }
+  }
+  /* loop through all arguments looking for our options */
+  for (index = 1; index < UTEST_CAST(size_t, argc); index++) {
+    /* Informational switches */
+    const char help_str[] = "--help";
+    const char list_str[] = "--list-tests";
+    /* Test config switches */
+    const char filter_str[] = "--filter=";
+    const char output_str[] = "--output=";
+    const char enable_mixed_units_str[] = "--enable-mixed-units";
+    const char random_order_str[] = "--random-order";
+    const char random_order_with_seed_str[] = "--random-order=";
+
+    if (0 == UTEST_STRNCMP(argv[index], help_str, strlen(help_str))) {
+      printf("utest.h - the single file unit testing solution for C/C++!\n"
+             "Command line Options:\n"
+             "  --help                  Show this message and exit.\n"
+             "  --filter=<filter>       Filter the test cases to run (EG. "
+             "MyTest*.a would run MyTestCase.a but not MyTestCase.b).\n"
+             "  --list-tests            List testnames, one per line. Output "
+             "names can be passed to --filter.\n");
+      printf("  --output=<output>       Output an xunit XML file to the file "
+             "specified in <output>.\n"
+             "  --enable-mixed-units    Enable the per-test output to contain "
+             "mixed units (s/ms/us/ns).\n"
+             "  --random-order[=<seed>] Randomize the order that the tests are "
+             "ran in. If the optional <seed> argument is not provided, then a "
+             "random starting seed is used.\n");
+      goto cleanup;
+    } else if (0 ==
+               UTEST_STRNCMP(argv[index], filter_str, strlen(filter_str))) {
+      /* user wants to filter what test cases run! */
+      filter = argv[index] + strlen(filter_str);
+    } else if (0 ==
+               UTEST_STRNCMP(argv[index], output_str, strlen(output_str))) {
+      utest_state.output = utest_fopen(argv[index] + strlen(output_str), "w+");
+    } else if (0 == UTEST_STRNCMP(argv[index], list_str, strlen(list_str))) {
+      for (index = 0; index < utest_state.tests_length; index++) {
+        UTEST_PRINTF("%s\n", utest_state.tests[index].name);
+      }
+      /* when printing the test list, don't actually run the tests */
+      return 0;
+    } else if (0 == UTEST_STRNCMP(argv[index], enable_mixed_units_str,
+                                  strlen(enable_mixed_units_str))) {
+      enable_mixed_units = 1;
+    } else if (0 == UTEST_STRNCMP(argv[index], random_order_with_seed_str,
+                                  strlen(random_order_with_seed_str))) {
+      seed =
+          UTEST_CAST(utest_uint32_t,
+                     strtoul(argv[index] + strlen(random_order_with_seed_str),
+                             UTEST_NULL, 10));
+      random_order = 1;
+    } else if (0 == UTEST_STRNCMP(argv[index], random_order_str,
+                                  strlen(random_order_str))) {
+      const utest_int64_t ns = utest_ns();
+
+      // Some really poor pseudo-random using the current time. I do this
+      // because I really want to avoid using C's rand() because that'd mean our
+      // random would be affected by any srand() usage by the user (which I
+      // don't want).
+      seed = UTEST_CAST(utest_uint32_t, ns >> 32) * 31 +
+             UTEST_CAST(utest_uint32_t, ns & 0xffffffff);
+      random_order = 1;
+    }
+  }
+
+  if (random_order) {
+    // Use Fisher-Yates with the Durstenfield's version to randomly re-order the
+    // tests.
+    for (index = utest_state.tests_length; index > 1; index--) {
+      // For the random order we'll use PCG.
+      const utest_uint32_t state = seed;
+      const utest_uint32_t word =
+          ((state >> ((state >> 28u) + 4u)) ^ state) * 277803737u;
+      const utest_uint32_t next =
+          ((word >> 22u) ^ word) % UTEST_CAST(utest_uint32_t, index);
+
+      // Swap the randomly chosen element into the last location.
+      const struct utest_test_state_s copy = utest_state.tests[index - 1];
+      utest_state.tests[index - 1] = utest_state.tests[next];
+      utest_state.tests[next] = copy;
+
+      // Move the seed onwards.
+      seed = seed * 747796405u + 2891336453u;
+    }
+  }
+
+  for (index = 0; index < utest_state.tests_length; index++) {
+    if (utest_should_filter_test(filter, utest_state.tests[index].name)) {
+      continue;
+    }
+
+    ran_tests++;
+  }
+
+  printf("%s[==========]%s Running %" UTEST_PRIu64 " test cases.\n",
+         colours[GREEN], colours[RESET], UTEST_CAST(utest_uint64_t, ran_tests));
+
+  if (utest_state.output) {
+    fprintf(utest_state.output, "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n");
+    fprintf(utest_state.output,
+            "<testsuites tests=\"%" UTEST_PRIu64 "\" name=\"All\">\n",
+            UTEST_CAST(utest_uint64_t, ran_tests));
+    fprintf(utest_state.output,
+            "<testsuite name=\"Tests\" tests=\"%" UTEST_PRIu64 "\">\n",
+            UTEST_CAST(utest_uint64_t, ran_tests));
+  }
+
+  for (index = 0; index < utest_state.tests_length; index++) {
+    int result = UTEST_TEST_PASSED;
+    utest_int64_t ns = 0;
+
+    if (utest_should_filter_test(filter, utest_state.tests[index].name)) {
+      continue;
+    }
+
+    printf("%s[ RUN      ]%s %s\n", colours[GREEN], colours[RESET],
+           utest_state.tests[index].name);
+
+    if (utest_state.output) {
+      fprintf(utest_state.output, "<testcase name=\"%s\">",
+              utest_state.tests[index].name);
+    }
+
+    ns = utest_ns();
+    errno = 0;
+#if defined(UTEST_HAS_EXCEPTIONS)
+    UTEST_SURPRESS_WARNING_BEGIN
+    try {
+      utest_state.tests[index].func(&result, utest_state.tests[index].index);
+    } catch (const std::exception &err) {
+      printf(" Exception : %s\n", err.what());
+      result = UTEST_TEST_FAILURE;
+    } catch (...) {
+      printf(" Exception : Unknown\n");
+      result = UTEST_TEST_FAILURE;
+    }
+    UTEST_SURPRESS_WARNING_END
+#else
+    utest_state.tests[index].func(&result, utest_state.tests[index].index);
+#endif
+    ns = utest_ns() - ns;
+
+    if (utest_state.output) {
+      fprintf(utest_state.output, "</testcase>\n");
+    }
+
+    // Record the failing test.
+    if (UTEST_TEST_FAILURE == result) {
+      const size_t failed_testcase_index = failed_testcases_length++;
+      failed_testcases = UTEST_PTR_CAST(
+          size_t *, utest_realloc(UTEST_PTR_CAST(void *, failed_testcases),
+                                  sizeof(size_t) * failed_testcases_length));
+      if (UTEST_NULL != failed_testcases) {
+        failed_testcases[failed_testcase_index] = index;
+      }
+      failed++;
+    } else if (UTEST_TEST_SKIPPED == result) {
+      const size_t skipped_testcase_index = skipped_testcases_length++;
+      skipped_testcases = UTEST_PTR_CAST(
+          size_t *, utest_realloc(UTEST_PTR_CAST(void *, skipped_testcases),
+                                  sizeof(size_t) * skipped_testcases_length));
+      if (UTEST_NULL != skipped_testcases) {
+        skipped_testcases[skipped_testcase_index] = index;
+      }
+      skipped++;
+    }
+
+    {
+      const char *const units[] = {"ns", "us", "ms", "s", UTEST_NULL};
+      unsigned int unit_index = 0;
+      utest_int64_t time = ns;
+
+      if (enable_mixed_units) {
+        for (unit_index = 0; UTEST_NULL != units[unit_index]; unit_index++) {
+          if (10000 > time) {
+            break;
+          }
+
+          time /= 1000;
+        }
+      }
+
+      if (UTEST_TEST_FAILURE == result) {
+        printf("%s[  FAILED  ]%s %s (%" UTEST_PRId64 "%s)\n", colours[RED],
+               colours[RESET], utest_state.tests[index].name, time,
+               units[unit_index]);
+      } else if (UTEST_TEST_SKIPPED == result) {
+        printf("%s[  SKIPPED ]%s %s (%" UTEST_PRId64 "%s)\n", colours[YELLOW],
+               colours[RESET], utest_state.tests[index].name, time,
+               units[unit_index]);
+      } else {
+        printf("%s[       OK ]%s %s (%" UTEST_PRId64 "%s)\n", colours[GREEN],
+               colours[RESET], utest_state.tests[index].name, time,
+               units[unit_index]);
+      }
+    }
+  }
+
+  printf("%s[==========]%s %" UTEST_PRIu64 " test cases ran.\n", colours[GREEN],
+         colours[RESET], ran_tests);
+  printf("%s[  PASSED  ]%s %" UTEST_PRIu64 " tests.\n", colours[GREEN],
+         colours[RESET], ran_tests - failed - skipped);
+
+  if (0 != skipped) {
+    printf("%s[  SKIPPED ]%s %" UTEST_PRIu64 " tests, listed below:\n",
+           colours[YELLOW], colours[RESET], skipped);
+    for (index = 0; index < skipped_testcases_length; index++) {
+      printf("%s[  SKIPPED ]%s %s\n", colours[YELLOW], colours[RESET],
+             utest_state.tests[skipped_testcases[index]].name);
+    }
+  }
+
+  if (0 != failed) {
+    printf("%s[  FAILED  ]%s %" UTEST_PRIu64 " tests, listed below:\n",
+           colours[RED], colours[RESET], failed);
+    for (index = 0; index < failed_testcases_length; index++) {
+      printf("%s[  FAILED  ]%s %s\n", colours[RED], colours[RESET],
+             utest_state.tests[failed_testcases[index]].name);
+    }
+  }
+
+  if (utest_state.output) {
+    fprintf(utest_state.output, "</testsuite>\n</testsuites>\n");
+  }
+
+cleanup:
+  for (index = 0; index < utest_state.tests_length; index++) {
+    free(UTEST_PTR_CAST(void *, utest_state.tests[index].name));
+  }
+
+  free(UTEST_PTR_CAST(void *, skipped_testcases));
+  free(UTEST_PTR_CAST(void *, failed_testcases));
+  free(UTEST_PTR_CAST(void *, utest_state.tests));
+
+  if (utest_state.output) {
+    fclose(utest_state.output);
+  }
+
+  return UTEST_CAST(int, failed);
+}
+
+/*
+   we need, in exactly one source file, define the global struct that will hold
+   the data we need to run utest. This macro allows the user to declare the
+   data without having to use the UTEST_MAIN macro, thus allowing them to write
+   their own main() function.
+*/
+#define UTEST_STATE() struct utest_state_s utest_state = {0, 0, 0}
+
+/*
+   define a main() function to call into utest.h and start executing tests! A
+   user can optionally not use this macro, and instead define their own main()
+   function and manually call utest_main. The user must, in exactly one source
+   file, use the UTEST_STATE macro to declare a global struct variable that
+   utest requires.
+*/
+#define UTEST_MAIN()                                                           \
+  UTEST_STATE();                                                               \
+  int main(int argc, const char *const argv[]) {                               \
+    return utest_main(argc, argv);                                             \
+  }
+
+#endif /* SHEREDOM_UTEST_H_INCLUDED */
diff --git a/test/wg2sd_test.cpp b/test/wg2sd_test.cpp
new file mode 100644
index 0000000..5d57ac9
--- /dev/null
+++ b/test/wg2sd_test.cpp
@@ -0,0 +1,219 @@
+#include "utest.h"
+
+#include "wg2sd.hpp"
+#include <sstream>
+#include <array>
+
+namespace wg2sd {
+	extern bool _is_default_route(std::string const & cidr);
+	extern bool _is_ipv4_route(std::string const & cidr);
+};
+
+using namespace wg2sd;
+
+UTEST(wg2sd, ip_helpers) {
+
+	std::array<std::string, 8> default_routes = {
+		"0/0",
+		"0.0/0",
+		"0.0.0/0",
+		"0.0.0.0/0",
+		"::/0",
+		"::0/0",
+		"::0/0",
+		"0000:0000:0000:0000::/0",
+	};
+
+	for(std::string const & s : default_routes) {
+		ASSERT_TRUE(_is_default_route(s));
+	}
+
+	std::array<std::string, 8> non_default_routes = {
+		"192.168.0.1/24",
+		"0.0.0.1/0",
+		"0.0.0.0/32",
+		"1/1",
+		"2001:db8::1/64",
+		"fe80::1/128",
+		"::1/128",
+		"2001:0db8:0000:0000::/64",
+	};
+
+	for(std::string const & s : non_default_routes) {
+		ASSERT_FALSE(_is_default_route(s));
+	}
+
+	std::array<std::string, 4> ipv4_route = {
+		"192.168.1.1",
+		"0.0.0.0/0",
+		"255.255.255.255/32",
+		"1.2.3.4/0"
+	};
+
+	for(std::string const & s : ipv4_route) {
+		ASSERT_TRUE(_is_ipv4_route(s));
+	}
+
+	std::array<std::string, 4> ipv6_route = {
+		"2001:db8::1/64",
+		"fe80::1/128",
+		"::1/128",
+		"2001:0db8:0000:0000::/64",
+	};
+
+	for(std::string const & s : ipv6_route) {
+		ASSERT_FALSE(_is_ipv4_route(s));
+	}
+}
+
+// Typical configuration, similar to that provided by mullvad.net
+char const * CONFIG1 = (
+	"[Interface]\n"
+	"  # Device: Fast Mink\n"
+	" PrivateKey = APmSX97Yww7WyHrQGG3u7oUJAKRazSyXVu9lD+A3aW8=\n"
+	"Address = 10.14.123.142/32,fc00:aaaa:aaaa:aa01::6:ad78/128\n"
+	"DNS =10.0.0.2\n"
+	"[Peer]\n"
+	"PublicKey = kMIIVxitU3/1AnAGwdL5KazDQ97MnkuEVz2sWihALnQ= \n"
+	"AllowedIPs = 0.0.0.0/0,::0/0 # comment\n"
+	"Endpoint = 194.36.25.33:51820\n"
+);
+
+// Configuration with multiple peers, interface peer tables are reversed
+const char * CONFIG2 = (
+	"[Peer]\n"
+	"PublicKey = sMYYPASxJslAuszh5PgUPysrzZHHBOzawJ8PFbRQrHI=\n"
+	"AllowedIPs = 192.168.1.2/32\n"
+	"Endpoint = 203.0.113.1:51820\n"
+	"\n"
+	"[Peer]\n"
+	"PublicKey = kB9CSPsPS5irR0ZpVAHZKPNHLQKjIFjmgc6MSCAiWUs=\n"
+	"AllowedIPs = 192.168.1.3/32\n"
+	"Endpoint = 203.0.113.2:51820\n"
+	"\n"
+	"[Interface]\n"
+	"PrivateKey = ED3TF8deMhmXHa7Jrp024uv5T7jKl7611vFV3C1P+EY=\n"
+	"Address = 192.168.1.1/24\n"
+);
+
+// Configuration with persistant keepalive, psk, and multiple DNS entries
+const char * CONFIG3 = (
+	"[Interface]\n"
+	"PrivateKey = cJgeEfHUay0aKpV+k1lFK9nq9JJcqzKm8+Wh3EGtg1c=\n"
+	"  Table=5\n"
+	"\t\tAddress = 192.168.1.1/24\n"
+	"DNS = 8.8.8.8,\t 8.8.4.4\n"
+	"ListenPort = 4444\n"
+	"Table = 42\n"
+	"\n"
+	"[Peer]\n"
+	"   PublicKey = kB9CSPsPS5irR0ZpVAHZKPNHLQKjIFjmgc6MSCAiWUs=\n"
+	"  AllowedIPs = 192.168.1.2/32\n"
+	"Endpoint = 203.0.113.1:51820\n"
+	"PersistentKeepalive = 25\n"
+	"    PresharedKey = KIst3pK+YVHmM5k7NbNULKd2px9vaRsFi/y4E7NDWDQ=\n"
+);
+
+const char * INVALID_CONFIG = (
+	"PrivateKey = kPvfTBQxgHpaXI9wVj6JrtYKIJLVXrf0zg6ON7qUxl8=\n"
+	"Address = 192.168.1.1/24\n"
+	"[Interface]\n"
+);
+
+
+UTEST(wg2sd, parses_config) {
+
+	// CONFIG1
+	std::istringstream ss { CONFIG1 };
+
+	Config cfg = parse_config("wg", ss);
+
+	ASSERT_STREQ(cfg.intf.name.c_str(), "wg");
+	ASSERT_STREQ(cfg.intf.private_key.c_str(), "APmSX97Yww7WyHrQGG3u7oUJAKRazSyXVu9lD+A3aW8=");
+	ASSERT_EQ(cfg.intf.table, 0ul);
+	ASSERT_FALSE(cfg.intf.listen_port.has_value());
+	ASSERT_EQ(cfg.intf.DNS.size(), 1ull);
+	ASSERT_STREQ(cfg.intf.DNS.back().c_str(), "10.0.0.2");
+	ASSERT_EQ(cfg.peers.size(), 1ull);
+
+	const Peer & peer = cfg.peers[0];
+
+	ASSERT_STREQ(peer.endpoint.c_str(), "194.36.25.33:51820");
+	ASSERT_STREQ(peer.allowed_ips[0].route.c_str(), "0.0.0.0/0");
+	ASSERT_TRUE(peer.allowed_ips[0].is_ipv4);
+	ASSERT_TRUE(peer.allowed_ips[0].is_default_route);
+	ASSERT_STREQ(peer.allowed_ips[1].route.c_str(), "::0/0");
+	ASSERT_FALSE(peer.allowed_ips[1].is_ipv4);
+	ASSERT_TRUE(peer.allowed_ips[1].is_default_route);
+
+	ASSERT_STREQ(peer.public_key.c_str(), "kMIIVxitU3/1AnAGwdL5KazDQ97MnkuEVz2sWihALnQ=");
+	ASSERT_STREQ(peer.preshared_key.c_str(), "");
+	ASSERT_STREQ(peer.persistent_keepalive.c_str(), "");
+
+	// CONFIG2
+	std::istringstream ss2 { CONFIG2 };
+
+	Config cfg2 = parse_config("wg", ss2);
+
+	ASSERT_STREQ(cfg2.intf.name.c_str(), "wg");
+	ASSERT_FALSE(cfg2.intf.listen_port.has_value());
+	ASSERT_STREQ(cfg2.intf.private_key.c_str(), "ED3TF8deMhmXHa7Jrp024uv5T7jKl7611vFV3C1P+EY=");
+	ASSERT_EQ(cfg2.intf.table, 0ul);
+	ASSERT_EQ(cfg2.intf.DNS.size(), 0ull);
+	
+	ASSERT_EQ(cfg2.peers.size(), 2ull);
+
+	const Peer &peer2_1 = cfg2.peers[0];
+
+	ASSERT_STREQ(peer2_1.endpoint.c_str(), "203.0.113.1:51820");
+	ASSERT_STREQ(peer2_1.allowed_ips[0].route.c_str(), "192.168.1.2/32");
+	ASSERT_TRUE(peer2_1.allowed_ips[0].is_ipv4);
+	ASSERT_FALSE(peer2_1.allowed_ips[0].is_default_route);
+	ASSERT_STREQ(peer2_1.public_key.c_str(), "sMYYPASxJslAuszh5PgUPysrzZHHBOzawJ8PFbRQrHI=");
+	ASSERT_STREQ(peer2_1.preshared_key.c_str(), "");
+	ASSERT_STREQ(peer2_1.persistent_keepalive.c_str(), "");
+
+	const Peer &peer2_2 = cfg2.peers[1];
+
+	ASSERT_STREQ(peer2_2.endpoint.c_str(), "203.0.113.2:51820");
+	ASSERT_STREQ(peer2_2.allowed_ips[0].route.c_str(), "192.168.1.3/32");
+	ASSERT_TRUE(peer2_2.allowed_ips[0].is_ipv4);
+	ASSERT_FALSE(peer2_2.allowed_ips[0].is_default_route);
+	ASSERT_STREQ(peer2_2.public_key.c_str(), "kB9CSPsPS5irR0ZpVAHZKPNHLQKjIFjmgc6MSCAiWUs=");
+	ASSERT_STREQ(peer2_2.preshared_key.c_str(), "");
+	ASSERT_STREQ(peer2_2.persistent_keepalive.c_str(), "");
+
+	// CONFIG3
+	std::istringstream ss3 { CONFIG3 };
+
+	Config cfg3 = parse_config("wg", ss3);
+
+	ASSERT_STREQ(cfg3.intf.name.c_str(), "wg");
+	ASSERT_STREQ(cfg3.intf.private_key.c_str(), "cJgeEfHUay0aKpV+k1lFK9nq9JJcqzKm8+Wh3EGtg1c=");
+	ASSERT_EQ(cfg3.intf.table, 42ul);
+	uint16_t port = cfg3.intf.listen_port.value();
+	ASSERT_EQ(port, 4444);
+	ASSERT_EQ(cfg3.intf.DNS.size(), 2ull);
+	ASSERT_STREQ(cfg3.intf.DNS[0].c_str(), "8.8.8.8");
+	ASSERT_STREQ(cfg3.intf.DNS[1].c_str(), "8.8.4.4");
+	
+	ASSERT_EQ(cfg3.peers.size(), 1ull);
+
+	const Peer &peer3 = cfg3.peers[0];
+
+	ASSERT_STREQ(peer3.endpoint.c_str(), "203.0.113.1:51820");
+	ASSERT_STREQ(peer3.allowed_ips[0].route.c_str(), "192.168.1.2/32");
+	ASSERT_TRUE(peer3.allowed_ips[0].is_ipv4);
+	ASSERT_FALSE(peer3.allowed_ips[0].is_default_route);
+	ASSERT_STREQ(peer3.public_key.c_str(), "kB9CSPsPS5irR0ZpVAHZKPNHLQKjIFjmgc6MSCAiWUs=");
+	ASSERT_STREQ(peer3.preshared_key.c_str(), "KIst3pK+YVHmM5k7NbNULKd2px9vaRsFi/y4E7NDWDQ=");
+	ASSERT_STREQ(peer3.persistent_keepalive.c_str(), "25");
+
+
+	// INVALID_CONFIG
+	std::istringstream ss4 { INVALID_CONFIG };
+
+	ASSERT_EXCEPTION(parse_config("wg", ss4), ParsingException);
+}
+
+UTEST_MAIN()
-- 
cgit v1.2.3