From 742aeab8b2044281b4ed831e54006613737ef9e4 Mon Sep 17 00:00:00 2001 From: katherine Date: Tue, 20 Mar 2018 21:50:25 -0700 Subject: clean rewrite new version properly implement _Generics for greatest possible ease of use --- src/simple-test.h | 1681 ++++++++++++++--------------------------------------- 1 file changed, 423 insertions(+), 1258 deletions(-) diff --git a/src/simple-test.h b/src/simple-test.h index 6650720..b1dbfdf 100644 --- a/src/simple-test.h +++ b/src/simple-test.h @@ -1,1329 +1,494 @@ #ifndef SIMPLE_TEST_H #define SIMPLE_TEST_H -#define _XOPEN_SOURCE - -#include -#include -#include -#include #include +#include #include +#include +#include +#include #include -#include /**************************** * INTERNAL FUNCTIONALITY * ****************************/ -typedef enum { + + +enum simple_test_type { SIMPLE_TEST_BOOL, SIMPLE_TEST_INT, - SIMPLE_TEST_UINT, - SIMPLE_TEST_FLOAT, - SIMPLE_TEST_PTR, + SIMPLE_TEST_UNSIGNED, SIMPLE_TEST_CHAR, - SIMPLE_TEST_STR, - SIMPLE_TEST_WCHAR, - SIMPLE_TEST_WSTR, - SIMPLE_TEST_DEFAULT, -} simple_test_type_t; + SIMPLE_TEST_STRING, + SIMPLE_TEST_POINTER, + SIMPLE_TEST_UNKNOWN, + SIMPLE_TEST_MISMATCH, +}; -typedef enum { +enum simple_test_cond { SIMPLE_TEST_TRUE, + SIMPLE_TEST_FALSE, SIMPLE_TEST_EQ, SIMPLE_TEST_NEQ, - SIMPLE_TEST_G, + SIMPLE_TEST_GT, + SIMPLE_TEST_LT, SIMPLE_TEST_GEQ, - SIMPLE_TEST_L, SIMPLE_TEST_LEQ -} simple_test_cond_t; +}; + +#define SIMPLE_TEST_TYPE(a) \ + _Generic((a), \ + bool: SIMPLE_TEST_BOOL, \ + char: SIMPLE_TEST_CHAR, \ + int8_t: SIMPLE_TEST_INT, \ + int16_t: SIMPLE_TEST_INT, \ + int32_t: SIMPLE_TEST_INT, \ + int64_t: SIMPLE_TEST_INT, \ + uint8_t: SIMPLE_TEST_UNSIGNED, \ + uint16_t: SIMPLE_TEST_UNSIGNED, \ + uint32_t: SIMPLE_TEST_UNSIGNED, \ + uint64_t: SIMPLE_TEST_UNSIGNED, \ + char *: SIMPLE_TEST_STRING, \ + void *: SIMPLE_TEST_POINTER, \ + default: SIMPLE_TEST_UNKNOWN) + +#define SIMPLE_TEST_PASTE_ACTUAL(a, b) \ + a##b + +#define SIMPLE_TEST_PASTE(a, b) \ + SIMPLE_TEST_PASTE_ACTUAL(a, b) + +#define SIMPLE_TEST_FAIL1(...) \ + do { \ + printf("\e[1m% *c :: at line %d, \e[m\e[1;31mfail: \e[m", \ + simple_test_pad_width, ' ', __LINE__); \ + printf(__VA_ARGS__); \ + printf("\n"); \ + } while (0) + +// #define SIMPLE_TEST_PRINT_VAL(a, type) \ +// do { \ +// printf("\e[1m% *c :: ", simple_test_pad_width, ' '); \ +// printf("`%s` \e[m== \e[1m", #a); \ +// switch (type) { \ +// case SIMPLE_TEST_BOOL: \ +// printf("%s", (a) ? "true" : "false"); \ +// break; \ +// case SIMPLE_TEST_CHAR: \ +// printf("%c", (a)); \ +// break; \ +// case SIMPLE_TEST_INT: \ +// printf("%" PRIdMAX, (a)); \ +// break; \ +// case SIMPLE_TEST_UNSIGNED: \ +// printf("%" PRIuMAX, (a)); \ +// break; \ +// case SIMPLE_TEST_STRING: \ +// printf(((a) ? "\"%s\"" : "%s"), (a)); \ +// break; \ +// case SIMPLE_TEST_POINTER: \ +// printf("%p", (a)); \ +// break; \ +// default: \ +// break; \ +// } \ +// printf("\e[m\n"); \ +// } while (0) + +#define SIMPLE_TEST_PRINT_VAL(w, s, t) \ + do { \ + printf("\e[1m% *c :: ", simple_test_pad_width, ' '); \ + printf("`%s` \e[m== \e[1m", s); \ + switch (t) { \ + case SIMPLE_TEST_BOOL: \ + printf("%s", (w ? simple_test_il : simple_test_ir) \ + ? "true" : "false"); \ + break; \ + case SIMPLE_TEST_CHAR: \ + printf("%c", w ? simple_test_il : simple_test_ir); \ + break; \ + case SIMPLE_TEST_INT: \ + printf("%" PRIdMAX, w ? simple_test_il : simple_test_ir); \ + break; \ + case SIMPLE_TEST_UNSIGNED: \ + printf("%" PRIuMAX, w ? simple_test_ul : simple_test_ur); \ + break; \ + case SIMPLE_TEST_STRING: \ + printf(((w ? simple_test_sl : simple_test_sr) \ + ? "\"%s\"" : "%s"), w \ + ? simple_test_sl : simple_test_sr); \ + break; \ + case SIMPLE_TEST_POINTER: \ + printf("%p", w ? simple_test_pl : simple_test_pr); \ + break; \ + default: \ + break; \ + } \ + printf("\e[m\n"); \ + } while (0) + +#define SIMPLE_TEST_FAIL2 \ + do { \ + simple_test_fail_count++; \ + goto simple_test_loop_end; \ + } while (0) + +#define SIMPLE_TEST_ERR(...) \ + do { \ + printf("\e[1m% *c :: at line %d, \e[m\e[1;31merr: \e[m", \ + simple_test_pad_width, ' ', __LINE__); \ + printf(__VA_ARGS__); \ + printf("\n"); \ + exit(1); \ + } while (0) -int simple_test_mbslen(char *arg) -{ - int blen = strlen(arg), clen = 0, i = 0; - wchar_t wc; - setlocale(LC_ALL, ""); - while(i < blen) { - i += mbtowc(&wc, arg + i, blen - i); - clen += wcwidth(wc); - } - return clen; -} +#define SIMPLE_TEST_PRINT_BUF_WIDTH 512 -void simple_test_get_escape(char c, char *buf) -{ - buf[0] = '\\'; - buf[2] = '\0'; - switch(c) { - case '\a': - buf[1] = 'a'; - break; - case '\b': - buf[1] = 'b'; - break; - case '\t': - buf[1] = 't'; - break; - case '\n': - buf[1] = 'n'; - break; - case '\v': - buf[1] = 'v'; - break; - case '\f': - buf[1] = 'f'; - break; - case '\r': - buf[1] = 'r'; - break; - default: - buf[0] = c; - buf[1] = '\0'; - } -} +/****************** + * BASIC MACROS * + ******************/ -void simple_test_get_escape_wide(wchar_t c, wchar_t *buf) -{ - buf[0] = L'\\'; - buf[2] = L'\0'; +#define REGISTER_TEARDOWN(f) \ + do { \ + if (simple_test_teardown != NULL) \ + SIMPLE_TEST_ERR("teardown function already defined"); \ + simple_test_teardown = _Generic((f), \ + void(*)(void): (f), default: NULL); \ + if (simple_test_teardown == NULL) { \ + SIMPLE_TEST_ERR( \ + "wrongly-typed function passed to REGISTER_TEARDOWN"); \ + } \ + } while (0) - switch(c) { - case L'\a': - buf[1] = L'a'; - break; - case L'\b': - buf[1] = L'b'; - break; - case L'\t': - buf[1] = L't'; - break; - case L'\n': - buf[1] = L'n'; - break; - case L'\v': - buf[1] = L'v'; - break; - case L'\f': - buf[1] = L'f'; - break; - case L'\r': - buf[1] = L'r'; - break; - default: - buf[0] = c; - buf[1] = L'\0'; - } -} -/* extra levels of abstraction are necessary - * to get __LINE__ to evaluate first */ -#define SIMPLE_TEST_STRINGIFY(x) SIMPLE_TEST_STRINGIFY_EVAL(x) +#define USE_TEARDOWN \ + do { \ + if (simple_test_teardown == NULL) \ + SIMPLE_TEST_ERR("teardown function undefined"); \ + simple_test_do_teardown = true; \ + } while (0) -#define SIMPLE_TEST_STRINGIFY_EVAL(x) \ -#x -#define SIMPLE_TEST_LEN_DIFF(arg1, arg2) \ - ( simple_test_mbslen(arg1) - simple_test_mbslen(arg2) ) -#define SIMPLE_TEST_FAIL_ONE(summary, file, line, fmt, sarg, arg) \ -do { \ - { \ - printf("\e[1m :: "); \ - printf("%s", file); \ - printf(":%i: \e[31;1mfail:\e[m ", line); \ - printf(summary); \ - printf("\e[m\n"); \ - printf("\e[1m :: "); \ - printf("%s == \e[m" fmt "\n", sarg, arg); \ - exit(1); \ - } \ -} while(0) -#define SIMPLE_TEST_FAIL(summary, file, line, fmt1, fmt2, sarg1, sarg2, arg1, arg2) \ -do { \ +/* must appear before all tests */ +#define BEGIN_TEST \ + int main(int argc, char **argv) \ { \ - int simple_test_i, simple_test_diff = SIMPLE_TEST_LEN_DIFF(sarg1, sarg2); \ - printf("\e[1m :: "); \ - printf("%s", file); \ - printf(":%i: \e[31;1mfail:\e[m ", line); \ - printf(summary); \ - printf("\e[m\n"); \ - printf("\e[1m :: "); \ - for(simple_test_i = 0; simple_test_i < -simple_test_diff; simple_test_i++) \ - printf(" "); \ - printf("%s == \e[m", sarg1); \ - printf(fmt1, arg1); \ - printf("\n\e[1m :: "); \ - for(simple_test_i = 0; simple_test_i < simple_test_diff; simple_test_i++) \ - printf(" "); \ - printf("%s == \e[m", sarg2); \ - printf(fmt2, arg2); \ - printf("\n"); \ - exit(1); \ - } \ -} while(0) + int simple_test_iterator; \ + int simple_test_pad_width = 0; \ + int simple_test_fail_count = 0; \ + char simple_test_print_buf[SIMPLE_TEST_PRINT_BUF_WIDTH]; \ + int simple_test_test_count = 0; \ + int simple_test_test_current = 1; \ + int simple_test_pass_number = 0; \ + bool simple_test_do_teardown = false; \ + void (*simple_test_teardown)(void) = NULL; \ + do { \ + if (simple_test_pass_number == 0) { \ + printf("\e[1mstarting tests in " __FILE__ "...\n"); \ + } else { \ + simple_test_pad_width = sprintf(simple_test_print_buf, \ + "%d", simple_test_test_count) + 1; \ + } \ + for (simple_test_iterator = 0; simple_test_pass_number == 0 && \ + simple_test_iterator < 1; simple_test_iterator++) { \ + (void)0; \ -#define SIMPLE_TEST_INTERN_ERR(file, line) \ -do { \ - printf("\e[1m :: "); \ - printf("%s:%i: \e[31;1merr:\e[m ", file, line); \ - printf("bad call to internal func\n"); \ - exit(1); \ -} while(0) -void simple_test_assert_bool(char *sarg1, char *sarg2, - bool arg1, bool arg2, - const char *file, const int line, simple_test_cond_t cond) -{ - switch(cond) { - case SIMPLE_TEST_TRUE: - if(!(arg2)) - SIMPLE_TEST_FAIL_ONE("unexpected false value", file, line, - "%s", sarg2, arg2 ? "true" : "false"); - break; - case SIMPLE_TEST_EQ: - if(arg1 != arg2) - SIMPLE_TEST_FAIL("bool values do not match", file, line, - "%s", "%s", sarg1, sarg2, - arg1 ? "true" : "false", arg2 ? "true" : "false"); - break; - case SIMPLE_TEST_NEQ: - if(arg1 == arg2) - SIMPLE_TEST_FAIL("bool values match", file, line, - "%s", "%s", sarg1, sarg2, - arg1 ? "true" : "false", arg2 ? "true" : "false"); - break; - default: - SIMPLE_TEST_INTERN_ERR(file, line); +#define TEST(description) \ + } \ + if (simple_test_do_teardown) { \ + simple_test_do_teardown = false; \ + simple_test_teardown(); \ + } \ + int SIMPLE_TEST_PASTE(simple_test_test_slot_, __LINE__); \ + if (simple_test_pass_number == 0) { \ + SIMPLE_TEST_PASTE(simple_test_test_slot_, __LINE__) \ + = ++simple_test_test_count; \ + } else if (simple_test_pass_number \ + == SIMPLE_TEST_PASTE(simple_test_test_slot_, __LINE__)) { \ + printf("\e[m% *d \e[1m:: \e[m\e[33m%s\e[m\n", simple_test_pad_width, \ + simple_test_test_current++, description); \ + +/* must appear after all tests */ +#define END_TEST \ + } \ + if (simple_test_do_teardown) { \ + simple_test_do_teardown = false; \ + simple_test_teardown(); \ + } \ + if (simple_test_test_count == 0) { \ + SIMPLE_TEST_ERR("no tests defined"); \ + } \ +simple_test_loop_end: \ + (void)0; \ + } while (simple_test_pass_number++ < simple_test_test_count); \ + if (simple_test_fail_count) { \ + printf("\e[1;31m%d of %d tests failed\e[m\n", \ + simple_test_fail_count, simple_test_test_count); \ + return 1; \ + } else { \ + printf("\e[1;32mall tests passed!\e[m\n"); \ + return 0; \ + } \ } -} -void simple_test_assert_int(char *sarg1, char *sarg2, - intmax_t arg1, intmax_t arg2, - const char *file, const int line, simple_test_cond_t cond) -{ - switch(cond) { - case SIMPLE_TEST_TRUE: - if(!(arg2)) - SIMPLE_TEST_FAIL_ONE("unexpected 0 value", file, line, - "%" PRIiMAX, sarg2, arg2); - break; - case SIMPLE_TEST_EQ: - if(arg1 != arg2) - SIMPLE_TEST_FAIL("int values do not match", file, line, - "%" PRIiMAX, "%" PRIiMAX, sarg1, sarg2, arg1, arg2); - break; - case SIMPLE_TEST_NEQ: - if(arg1 == arg2) - SIMPLE_TEST_FAIL("int values match", file, line, - "%" PRIiMAX, "%" PRIiMAX, sarg1, sarg2, arg1, arg2); - break; - case SIMPLE_TEST_G: - if(arg1 <= arg2) - SIMPLE_TEST_FAIL("arg1 <= arg2", file, line, - "%" PRIiMAX, "%" PRIiMAX, sarg1, sarg2, arg1, arg2); - break; - case SIMPLE_TEST_GEQ: - if(arg1 < arg2) - SIMPLE_TEST_FAIL("arg1 < arg2", file, line, - "%" PRIiMAX, "%" PRIiMAX, sarg1, sarg2, arg1, arg2); - break; - case SIMPLE_TEST_L: - if(arg1 >= arg2) - SIMPLE_TEST_FAIL("arg1 >= arg2", file, line, - "%" PRIiMAX, "%" PRIiMAX, sarg1, sarg2, arg1, arg2); - break; - case SIMPLE_TEST_LEQ: - if(arg1 > arg2) - SIMPLE_TEST_FAIL("arg1 > arg2", file, line, - "%" PRIiMAX, "%" PRIiMAX, sarg1, sarg2, arg1, arg2); - break; - default: - SIMPLE_TEST_INTERN_ERR(file, line); - } -} +#define ECHO(...) \ + do { \ + printf("\e[1m% *c :: \e[m\e[34m", simple_test_pad_width, ' '); \ + printf(__VA_ARGS__); \ + printf("...\e[m\n"); \ + } while (0) -void simple_test_assert_uint(char *sarg1, char *sarg2, - uintmax_t arg1, uintmax_t arg2, - const char *file, const int line, simple_test_cond_t cond) -{ - switch(cond) { - case SIMPLE_TEST_TRUE: - if(!(arg2)) - SIMPLE_TEST_FAIL_ONE("unexpected 0 value", file, line, - "%" PRIuMAX, sarg2, arg2); - break; - case SIMPLE_TEST_EQ: - if(arg1 != arg2) - SIMPLE_TEST_FAIL("uint values do not match", file, line, - "%" PRIuMAX, "%" PRIuMAX, sarg1, sarg2, arg1, arg2); - break; - case SIMPLE_TEST_NEQ: - if(arg1 == arg2) - SIMPLE_TEST_FAIL("uint values match", file, line, - "%" PRIuMAX, "%" PRIuMAX, sarg1, sarg2, arg1, arg2); - break; - case SIMPLE_TEST_G: - if(arg1 <= arg2) - SIMPLE_TEST_FAIL("arg1 <= arg2", file, line, - "%" PRIuMAX, "%" PRIuMAX, sarg1, sarg2, arg1, arg2); - break; - case SIMPLE_TEST_GEQ: - if(arg1 < arg2) - SIMPLE_TEST_FAIL("arg1 < arg2", file, line, - "%" PRIuMAX, "%" PRIuMAX, sarg1, sarg2, arg1, arg2); - break; - case SIMPLE_TEST_L: - if(arg1 >= arg2) - SIMPLE_TEST_FAIL("arg1 >= arg2", file, line, - "%" PRIuMAX, "%" PRIuMAX, sarg1, sarg2, arg1, arg2); - break; - case SIMPLE_TEST_LEQ: - if(arg1 > arg2) - SIMPLE_TEST_FAIL("arg1 > arg2", file, line, - "%" PRIuMAX, "%" PRIuMAX, sarg1, sarg2, arg1, arg2); - break; - default: - SIMPLE_TEST_INTERN_ERR(file, line); - } -} -void simple_test_assert_hex(char *sarg1, char *sarg2, - uintmax_t arg1, uintmax_t arg2, - const char *file, const int line, simple_test_cond_t cond) -{ - switch(cond) { - case SIMPLE_TEST_TRUE: - if(!(arg2)) - SIMPLE_TEST_FAIL_ONE("unexpected 0 value", file, line, - "%" PRIxMAX, sarg2, arg2); - break; - case SIMPLE_TEST_EQ: - if(arg1 != arg2) - SIMPLE_TEST_FAIL("uint values do not match", file, line, - "%" PRIxMAX, "%" PRIxMAX, sarg1, sarg2, arg1, arg2); - break; - case SIMPLE_TEST_NEQ: - if(arg1 == arg2) - SIMPLE_TEST_FAIL("uint values match", file, line, - "%" PRIxMAX, "%" PRIxMAX, sarg1, sarg2, arg1, arg2); - break; - case SIMPLE_TEST_G: - if(arg1 <= arg2) - SIMPLE_TEST_FAIL("arg1 <= arg2", file, line, - "%" PRIxMAX, "%" PRIxMAX, sarg1, sarg2, arg1, arg2); - break; - case SIMPLE_TEST_GEQ: - if(arg1 < arg2) - SIMPLE_TEST_FAIL("arg1 < arg2", file, line, - "%" PRIxMAX, "%" PRIxMAX, sarg1, sarg2, arg1, arg2); - break; - case SIMPLE_TEST_L: - if(arg1 >= arg2) - SIMPLE_TEST_FAIL("arg1 >= arg2", file, line, - "%" PRIxMAX, "%" PRIxMAX, sarg1, sarg2, arg1, arg2); - break; - case SIMPLE_TEST_LEQ: - if(arg1 > arg2) - SIMPLE_TEST_FAIL("arg1 > arg2", file, line, - "%" PRIxMAX, "%" PRIxMAX, sarg1, sarg2, arg1, arg2); - break; - default: - SIMPLE_TEST_INTERN_ERR(file, line); - } -} +/********************** + * ASSERTION MACROS * + **********************/ -void simple_test_assert_float(char *sarg1, char *sarg2, - long double arg1, long double arg2, - const char *file, const int line, simple_test_cond_t cond) -{ - switch(cond) { - case SIMPLE_TEST_TRUE: - if(!(arg2)) - SIMPLE_TEST_FAIL_ONE("unexpected 0 value", file, line, - "%Lg", sarg2, arg2); - break; - case SIMPLE_TEST_EQ: - if(arg1 != arg2) - SIMPLE_TEST_FAIL("float values do not match", file, line, - "%Lg", "%Lg", sarg1, sarg2, arg1, arg2); - break; - case SIMPLE_TEST_NEQ: - if(arg1 == arg2) - SIMPLE_TEST_FAIL("float values match", file, line, - "%Lg", "%Lg", sarg1, sarg2, arg1, arg2); - break; - case SIMPLE_TEST_G: - if(arg1 <= arg2) - SIMPLE_TEST_FAIL("arg1 <= arg2", file, line, - "%Lg", "%Lg", sarg1, sarg2, arg1, arg2); - break; - case SIMPLE_TEST_GEQ: - if(arg1 < arg2) - SIMPLE_TEST_FAIL("arg1 < arg2", file, line, - "%Lg", "%Lg", sarg1, sarg2, arg1, arg2); - break; - case SIMPLE_TEST_L: - if(arg1 >= arg2) - SIMPLE_TEST_FAIL("arg1 >= arg2", file, line, - "%Lg", "%Lg", sarg1, sarg2, arg1, arg2); - break; - case SIMPLE_TEST_LEQ: - if(arg1 > arg2) - SIMPLE_TEST_FAIL("arg1 > arg2", file, line, - "%Lg", "%Lg", sarg1, sarg2, arg1, arg2); - break; - default: - SIMPLE_TEST_INTERN_ERR(file, line); - } -} +static intmax_t simple_test_il, simple_test_ir; +static uintmax_t simple_test_ul, simple_test_ur; +static char simple_test_cl, simple_test_cr; +static char *simple_test_sl, *simple_test_sr; +static void *simple_test_pl, *simple_test_pr; -void simple_test_assert_ptr(char *sarg1, char *sarg2, - void *arg1, void *arg2, - const char *file, const int line, simple_test_cond_t cond) +static int simple_test_assert(enum simple_test_type t, + enum simple_test_cond c, ...) { - switch(cond) { + va_list ap; + bool two = !(c == SIMPLE_TEST_TRUE || c == SIMPLE_TEST_FALSE); + + int r; + + va_start(ap, c); + + switch (t) { + case SIMPLE_TEST_MISMATCH: + return -2; + case SIMPLE_TEST_BOOL: + case SIMPLE_TEST_INT: + case SIMPLE_TEST_CHAR: + simple_test_il = va_arg(ap, intmax_t); + if (two) simple_test_ir = va_arg(ap, intmax_t); + switch (c) { case SIMPLE_TEST_TRUE: - if(arg2 == NULL) - SIMPLE_TEST_FAIL_ONE("unexpected NULL value", file, line, - "%p", sarg2, arg2); - break; + r = simple_test_il; + goto end; + case SIMPLE_TEST_FALSE: + r = !simple_test_il; + goto end; case SIMPLE_TEST_EQ: - if(arg1 != arg2) - SIMPLE_TEST_FAIL("pointer values do not match", file, line, - "%p", "%p", sarg1, sarg2, arg1, arg2); - break; + r = simple_test_il == simple_test_ir; + goto end; case SIMPLE_TEST_NEQ: - if(arg1 == arg2) - SIMPLE_TEST_FAIL("pointer values match", file, line, - "%p", "%p", sarg1, sarg2, arg1, arg2); - break; - case SIMPLE_TEST_G: - if(arg1 <= arg2) - SIMPLE_TEST_FAIL("arg1 <= arg2", file, line, - "%p", "%p", sarg1, sarg2, arg1, arg2); - break; + r = simple_test_il != simple_test_ir; + goto end; + case SIMPLE_TEST_GT: + r = simple_test_il > simple_test_ir; + goto end; + case SIMPLE_TEST_LT: + r = simple_test_il < simple_test_ir; + goto end; case SIMPLE_TEST_GEQ: - if(arg1 < arg2) - SIMPLE_TEST_FAIL("arg1 < arg2", file, line, - "%p", "%p", sarg1, sarg2, arg1, arg2); - break; - case SIMPLE_TEST_L: - if(arg1 >= arg2) - SIMPLE_TEST_FAIL("arg1 >= arg2", file, line, - "%p", "%p", sarg1, sarg2, arg1, arg2); - break; + r = simple_test_il >= simple_test_ir; + goto end; case SIMPLE_TEST_LEQ: - if(arg1 > arg2) - SIMPLE_TEST_FAIL("arg1 > arg2", file, line, - "%p", "%p", sarg1, sarg2, arg1, arg2); - break; - default: - SIMPLE_TEST_INTERN_ERR(file, line); - } -} - -void simple_test_assert_char(char *sarg1, char *sarg2, - char arg1, char arg2, - const char *file, const int line, simple_test_cond_t cond) -{ - char buf1[3]; - char buf2[3]; - simple_test_get_escape(arg1, buf1); - simple_test_get_escape(arg2, buf2); - switch(cond) { + r = simple_test_il <= simple_test_ir; + goto end; + } + + case SIMPLE_TEST_UNSIGNED: + simple_test_ul = va_arg(ap, uintmax_t); + if (two) simple_test_ur = va_arg(ap, uintmax_t); + switch (c) { case SIMPLE_TEST_TRUE: - if(arg2 == '\0') - SIMPLE_TEST_FAIL_ONE("unexpected '\\0' value", file, line, - "‘%s’", sarg2, buf2); - break; + r = simple_test_ul; + goto end; + case SIMPLE_TEST_FALSE: + r = !simple_test_ul; + goto end; case SIMPLE_TEST_EQ: - if(arg1 != arg2) - SIMPLE_TEST_FAIL("char values do not match", file, line, - "‘%s’", "‘%s’", sarg1, sarg2, buf1, buf2); - break; + r = simple_test_ul == simple_test_ur; + goto end; case SIMPLE_TEST_NEQ: - if(arg1 == arg2) - SIMPLE_TEST_FAIL("char values match", file, line, - "‘%s’", "‘%s’", sarg1, sarg2, buf1, buf2); - break; - case SIMPLE_TEST_G: - if(arg1 <= arg2) - SIMPLE_TEST_FAIL("arg1 <= arg2", file, line, - "‘%s’", "‘%s’", sarg1, sarg2, buf1, buf2); - break; + r = simple_test_ul != simple_test_ur; + goto end; + case SIMPLE_TEST_GT: + r = simple_test_ul > simple_test_ur; + goto end; + case SIMPLE_TEST_LT: + r = simple_test_ul < simple_test_ur; + goto end; case SIMPLE_TEST_GEQ: - if(arg1 < arg2) - SIMPLE_TEST_FAIL("arg1 < arg2", file, line, - "‘%s’", "‘%s’", sarg1, sarg2, buf1, buf2); - break; - case SIMPLE_TEST_L: - if(arg1 >= arg2) - SIMPLE_TEST_FAIL("arg1 >= arg2", file, line, - "‘%s’", "‘%s’", sarg1, sarg2, buf1, buf2); - break; + r = simple_test_ul >= simple_test_ur; + goto end; case SIMPLE_TEST_LEQ: - if(arg1 > arg2) - SIMPLE_TEST_FAIL("arg1 > arg2", file, line, - "‘%s’", "‘%s’", sarg1, sarg2, buf1, buf2); - break; - default: - SIMPLE_TEST_INTERN_ERR(file, line); - } -} - -void simple_test_assert_str(char *sarg1, char *sarg2, - char *arg1, char *arg2, - const char *file, const int line, simple_test_cond_t cond) -{ - bool barg1 = (arg1 == NULL ? true : false); - bool barg2 = (arg2 == NULL ? true : false); - arg1 = (arg1 == NULL ? "(nil)" : arg1); - arg2 = (arg2 == NULL ? "(nil)" : arg2); - - switch(cond) { + r = simple_test_ul <= simple_test_ur; + goto end; + } + + case SIMPLE_TEST_STRING: + simple_test_sl = va_arg(ap, char *); + if (two) simple_test_sr = va_arg(ap, char *); + switch (c) { case SIMPLE_TEST_TRUE: - if(!strcmp(arg2, "(nil)")) - SIMPLE_TEST_FAIL_ONE("unexpected NULL string", file, line, - "%s", sarg2, arg2); - break; + r = simple_test_sl != NULL; + goto end; + case SIMPLE_TEST_FALSE: + r = simple_test_sl == NULL; + goto end; case SIMPLE_TEST_EQ: - if( strcmp(arg1, arg2) ) - SIMPLE_TEST_FAIL("strings do not match", file, line, - (barg1 ? "%s" : "‘%s’"), - (barg2 ? "%s" : "‘%s’"), - sarg1, sarg2, arg1, arg2); - break; + r = strcmp(simple_test_sl, simple_test_sr) ? 0 : 1; + goto end; case SIMPLE_TEST_NEQ: - if( !strcmp(arg1, arg2) ) - SIMPLE_TEST_FAIL("strings match", file, line, - (barg1 ? "%s" : "‘%s’"), - (barg2 ? "%s" : "‘%s’"), - sarg1, sarg2, arg1, arg2); - break; - case SIMPLE_TEST_G: - if( strcmp(arg1, arg2) <= 0) - SIMPLE_TEST_FAIL("arg1 <= arg2", file, line, - (barg1 ? "%s" : "‘%s’"), - (barg2 ? "%s" : "‘%s’"), - sarg1, sarg2, arg1, arg2); - break; + r = strcmp(simple_test_sl, simple_test_sr) ? 1 : 0; + goto end; + case SIMPLE_TEST_GT: + r = strcmp(simple_test_sl, simple_test_sr) > 0 ? 1 : 0; + goto end; + case SIMPLE_TEST_LT: + r = strcmp(simple_test_sl, simple_test_sr) < 0 ? 1 : 0; + goto end; case SIMPLE_TEST_GEQ: - if( strcmp(arg1, arg2) < 0) - SIMPLE_TEST_FAIL("arg1 < arg2", file, line, - (barg1 ? "%s" : "‘%s’"), - (barg2 ? "%s" : "‘%s’"), - sarg1, sarg2, arg1, arg2); - break; - case SIMPLE_TEST_L: - if( strcmp(arg1, arg2) >= 0) - SIMPLE_TEST_FAIL("arg1 >= arg2", file, line, - (barg1 ? "%s" : "‘%s’"), - (barg2 ? "%s" : "‘%s’"), - sarg1, sarg2, arg1, arg2); - break; + r = strcmp(simple_test_sl, simple_test_sr) >= 0 ? 1 : 0; + goto end; case SIMPLE_TEST_LEQ: - if( strcmp(arg1, arg2) > 0) - SIMPLE_TEST_FAIL("arg1 > arg2", file, line, - (barg1 ? "%s" : "‘%s’"), - (barg2 ? "%s" : "‘%s’"), - sarg1, sarg2, arg1, arg2); - break; - default: - SIMPLE_TEST_INTERN_ERR(file, line); - } -} - -void simple_test_assert_wchar(char *sarg1, char *sarg2, - wchar_t arg1, wchar_t arg2, - const char *file, const int line, simple_test_cond_t cond) -{ - wchar_t buf1[3]; - wchar_t buf2[3]; - simple_test_get_escape_wide(arg1, buf1); - simple_test_get_escape_wide(arg2, buf2); - switch(cond) { + r = strcmp(simple_test_sl, simple_test_sr) <= 0 ? 1 : 0; + goto end; + } + + case SIMPLE_TEST_POINTER: + simple_test_pl = va_arg(ap, void *); + if (two) simple_test_pr = va_arg(ap, void *); + switch (c) { case SIMPLE_TEST_TRUE: - if(arg2 == L'\0') - SIMPLE_TEST_FAIL_ONE("unexpected '\\0' value", file, line, - "‘%ls’", sarg2, buf2); - break; + r = simple_test_pl != NULL; + goto end; + case SIMPLE_TEST_FALSE: + r = simple_test_pl == NULL; + goto end; case SIMPLE_TEST_EQ: - if(arg1 != arg2) - SIMPLE_TEST_FAIL("char values do not match", file, line, - "‘%ls’", "‘%ls’", sarg1, sarg2, buf1, buf2); - break; + r = simple_test_pl == simple_test_pr; + goto end; case SIMPLE_TEST_NEQ: - if(arg1 == arg2) - SIMPLE_TEST_FAIL("char values match", file, line, - "‘%ls’", "‘%ls’", sarg1, sarg2, buf1, buf2); - break; - case SIMPLE_TEST_G: - if(arg1 <= arg2) - SIMPLE_TEST_FAIL("arg1 <= arg2", file, line, - "‘%ls’", "‘%ls’", sarg1, sarg2, buf1, buf2); - break; + r = simple_test_pl != simple_test_pr; + goto end; + case SIMPLE_TEST_GT: + r = simple_test_pl > simple_test_pr; + goto end; + case SIMPLE_TEST_LT: + r = simple_test_pl < simple_test_pr; + goto end; case SIMPLE_TEST_GEQ: - if(arg1 < arg2) - SIMPLE_TEST_FAIL("arg1 < arg2", file, line, - "‘%ls’", "‘%ls’", sarg1, sarg2, buf1, buf2); - break; - case SIMPLE_TEST_L: - if(arg1 >= arg2) - SIMPLE_TEST_FAIL("arg1 >= arg2", file, line, - "‘%ls’", "‘%ls’", sarg1, sarg2, buf1, buf2); - break; + r = simple_test_pl >= simple_test_pr; + goto end; case SIMPLE_TEST_LEQ: - if(arg1 > arg2) - SIMPLE_TEST_FAIL("arg1 > arg2", file, line, - "‘%ls’", "‘%ls’", sarg1, sarg2, buf1, buf2); - break; - default: - SIMPLE_TEST_INTERN_ERR(file, line); + r = simple_test_pl <= simple_test_pr; + goto end; + } + + default: + r = -1; } + +end: + va_end(ap); + return r; } -void simple_test_assert_wstr(char *sarg1, char *sarg2, - wchar_t *arg1, wchar_t *arg2, - const char *file, const int line, simple_test_cond_t cond) +static enum simple_test_type simple_test_type_resolve(enum simple_test_type t1, + enum simple_test_type t2) { - bool barg1 = (arg1 == NULL ? true : false); - bool barg2 = (arg2 == NULL ? true : false); - arg1 = (arg1 == NULL ? L"(nil)" : arg1); - arg2 = (arg2 == NULL ? L"(nil)" : arg2); - - switch(cond) { - case SIMPLE_TEST_TRUE: - if(!wcscmp(arg2, L"(nil)")) - SIMPLE_TEST_FAIL_ONE("unexpected NULL string", file, line, - "%ls", sarg2, arg2); - break; - case SIMPLE_TEST_EQ: - if( wcscmp(arg1, arg2) ) - SIMPLE_TEST_FAIL("strings do not match", file, line, - (barg1 ? "%ls" : "‘%ls’"), - (barg2 ? "%ls" : "‘%ls’"), - sarg1, sarg2, arg1, arg2); - break; - case SIMPLE_TEST_NEQ: - if( !wcscmp(arg1, arg2) ) - SIMPLE_TEST_FAIL("strings match", file, line, - (barg1 ? "%ls" : "‘%ls’"), - (barg2 ? "%ls" : "‘%ls’"), - sarg1, sarg2, arg1, arg2); - break; - case SIMPLE_TEST_G: - if( wcscmp(arg1, arg2) <= 0) - SIMPLE_TEST_FAIL("arg1 <= arg2", file, line, - (barg1 ? "%ls" : "‘%ls’"), - (barg2 ? "%ls" : "‘%ls’"), - sarg1, sarg2, arg1, arg2); - break; - case SIMPLE_TEST_GEQ: - if( wcscmp(arg1, arg2) < 0) - SIMPLE_TEST_FAIL("arg1 < arg2", file, line, - (barg1 ? "%ls" : "‘%ls’"), - (barg2 ? "%ls" : "‘%ls’"), - sarg1, sarg2, arg1, arg2); - break; - case SIMPLE_TEST_L: - if( wcscmp(arg1, arg2) >= 0) - SIMPLE_TEST_FAIL("arg1 >= arg2", file, line, - (barg1 ? "%ls" : "‘%ls’"), - (barg2 ? "%ls" : "‘%ls’"), - sarg1, sarg2, arg1, arg2); - break; - case SIMPLE_TEST_LEQ: - if( wcscmp(arg1, arg2) > 0) - SIMPLE_TEST_FAIL("arg1 > arg2", file, line, - (barg1 ? "%ls" : "‘%ls’"), - (barg2 ? "%ls" : "‘%ls’"), - sarg1, sarg2, arg1, arg2); - break; - default: - SIMPLE_TEST_INTERN_ERR(file, line); + if (t1 != t2) { + if (t1 == SIMPLE_TEST_INT && t2 == SIMPLE_TEST_UNSIGNED + || t1 == SIMPLE_TEST_UNSIGNED && t2 == SIMPLE_TEST_INT + || t1 == SIMPLE_TEST_BOOL && t2 == SIMPLE_TEST_UNSIGNED + || t1 == SIMPLE_TEST_UNSIGNED && t2 == SIMPLE_TEST_BOOL) { + return SIMPLE_TEST_UNSIGNED; + } else if (t1 == SIMPLE_TEST_BOOL && t2 == SIMPLE_TEST_INT + || t1 == SIMPLE_TEST_INT && t2 == SIMPLE_TEST_BOOL) { + return SIMPLE_TEST_INT; + } else if (t1 == SIMPLE_TEST_INT && t2 == SIMPLE_TEST_CHAR + || t1 == SIMPLE_TEST_CHAR && t2 == SIMPLE_TEST_INT) { + return SIMPLE_TEST_CHAR; + } else if (t1 == SIMPLE_TEST_CHAR && t2 == SIMPLE_TEST_UNSIGNED + || t1 == SIMPLE_TEST_UNSIGNED && t2 == SIMPLE_TEST_CHAR){ + return SIMPLE_TEST_UNSIGNED; + } else if (t1 == SIMPLE_TEST_POINTER && t2 == SIMPLE_TEST_STRING + || t1 == SIMPLE_TEST_STRING && t2 == SIMPLE_TEST_POINTER){ + return SIMPLE_TEST_POINTER; + } else { + return SIMPLE_TEST_MISMATCH; + } } -} - -/* reporting bool as SIMPLE_TEST_INT because that's how the compiler - * sees true / false constants */ -#define SIMPLE_TEST_TYPE_ENUM_VAL(arg) \ - _Generic((arg), \ - bool: SIMPLE_TEST_INT, \ - int8_t: SIMPLE_TEST_INT, int16_t: SIMPLE_TEST_INT, \ - int32_t: SIMPLE_TEST_INT, int64_t: SIMPLE_TEST_INT, \ - uint8_t: SIMPLE_TEST_UINT, uint16_t: SIMPLE_TEST_UINT, \ - uint32_t: SIMPLE_TEST_UINT, uint64_t: SIMPLE_TEST_UINT, \ - float: SIMPLE_TEST_FLOAT, double: SIMPLE_TEST_FLOAT, \ - long double: SIMPLE_TEST_FLOAT, \ - default: SIMPLE_TEST_DEFAULT \ - ) - -#define SIMPLE_TEST_TYPE_CHECK(arg1, arg2) \ -do { \ - if(SIMPLE_TEST_TYPE_ENUM_VAL(arg1) != SIMPLE_TEST_TYPE_ENUM_VAL(arg2)) { \ - printf("\e[1m :: "); \ - printf("%s:%i: \e[31;1merr:\e[m ", __FILE__, __LINE__); \ - printf("type mismatch\n"); \ - exit(1); \ - } \ -} while(0) - -#define SIMPLE_TEST_GENERIC_CAST(arg) \ - _Generic((arg), \ - int8_t: (intmax_t)(arg), int16_t: (intmax_t)(arg), int32_t: (intmax_t)(arg), \ - int64_t: (intmax_t)(arg), \ - uint8_t: (uintmax_t)(arg), uint16_t: (uintmax_t)(arg), uint32_t: (uintmax_t)(arg), \ - uint64_t: (uintmax_t)(arg), \ - float: (long double)(arg), double: (long double)(arg), \ - long double: (long double)(arg) \ - ) - -#define SIMPLE_TEST_GENERIC_NOT(arg) \ - _Generic((arg), \ - int8_t: 0, int16_t: 0, int32_t: 0, int64_t: 0, \ - uint8_t: 0, uint16_t: 0, uint32_t: 0, uint64_t: 0, \ - float: 0.0, double: 0.0, \ - long double: 0.0 \ - ) - -#define SIMPLE_TEST_GENERIC_NOT_STR(arg) \ - _Generic((arg), \ - int8_t: "0", int16_t: "0", int32_t: "0", int64_t: "0", \ - uint8_t: "0", uint16_t: "0", uint32_t: "0", uint64_t: "0", \ - float: "0.0", double: "0.0", \ - long double: "0.0" \ - ) - -#define SIMPLE_TEST_GENERIC_FUNCCALL(sarg1, sarg2, arg1, arg2, cond) \ - _Generic((arg2), \ - int8_t: simple_test_assert_int, int16_t: simple_test_assert_int, \ - int32_t: simple_test_assert_int, int64_t: simple_test_assert_int, \ - uint8_t: simple_test_assert_uint, uint16_t: simple_test_assert_uint, \ - uint32_t: simple_test_assert_uint, uint64_t: simple_test_assert_uint, \ - float: simple_test_assert_float, double: simple_test_assert_float, \ - long double: simple_test_assert_float \ - )(sarg1, sarg2, SIMPLE_TEST_GENERIC_CAST(arg1), \ - SIMPLE_TEST_GENERIC_CAST(arg2), __FILE__, __LINE__, cond) - - - -/********************** - * TOP-LEVEL MACROS * - **********************/ - -/* the whole thing is inside one - * big function. yay! */ -#define BEGIN_TEST \ -int simple_test_count_current=1; \ -int main(int argc, char *argv[]) \ -{ \ - printf("\e[1m" __FILE__ "\n"); -/* yaaaay! */ -#define END_TEST \ - printf("\e[1m :: \e[m\e[32msuccess!\e[m\n"); \ - return 0; \ + return t1; } -#define TEST(description) \ -printf("\e[1m%3i :: \e[m\e[33m%s\e[m\n", simple_test_count_current++, description); - -/* pretty printing for the current state within - * a test */ -#define ECHO(...) \ -do { \ - printf("\e[1m :: \e[m\e[34m"); \ - printf(__VA_ARGS__); \ - printf("...\e[m\n"); \ -} while(0) - - -/************************ - * TYPE-GENERIC TESTS * - ************************/ - -#define ASSERT(arg) \ -do { \ - SIMPLE_TEST_GENERIC_FUNCCALL(SIMPLE_TEST_GENERIC_NOT_STR(arg), #arg, \ - SIMPLE_TEST_GENERIC_NOT(arg), arg, SIMPLE_TEST_TRUE); \ -} while(0) - -#define ASSERT_EQ(arg1, arg2) \ -do { \ - SIMPLE_TEST_TYPE_CHECK(arg1, arg2); \ - SIMPLE_TEST_GENERIC_FUNCCALL(#arg1, #arg2, \ - arg1, arg2, SIMPLE_TEST_EQ); \ -} while(0) - -#define ASSERT_NEQ(arg1, arg2) \ -do { \ - SIMPLE_TEST_TYPE_CHECK(arg1, arg2); \ - SIMPLE_TEST_GENERIC_FUNCCALL(#arg1, #arg2, \ - arg1, arg2, SIMPLE_TEST_NEQ); \ -} while(0) - -#define ASSERT_G(arg1, arg2) \ -do { \ - SIMPLE_TEST_TYPE_CHECK(arg1, arg2); \ - SIMPLE_TEST_GENERIC_FUNCCALL(#arg1, #arg2, \ - arg1, arg2, SIMPLE_TEST_G); \ -} while(0) - -#define ASSERT_GEQ(arg1, arg2) \ -do { \ - SIMPLE_TEST_TYPE_CHECK(arg1, arg2); \ - SIMPLE_TEST_GENERIC_FUNCCALL(#arg1, #arg2, \ - arg1, arg2, SIMPLE_TEST_GEQ); \ -} while(0) - -#define ASSERT_L(arg1, arg2) \ -do { \ - SIMPLE_TEST_TYPE_CHECK(arg1, arg2); \ - SIMPLE_TEST_GENERIC_FUNCCALL(#arg1, #arg2, \ - arg1, arg2, SIMPLE_TEST_L); \ -} while(0) - -#define ASSERT_LEQ(arg1, arg2) \ -do { \ - SIMPLE_TEST_TYPE_CHECK(arg1, arg2); \ - SIMPLE_TEST_GENERIC_FUNCCALL(#arg1, #arg2, \ - arg1, arg2, SIMPLE_TEST_LEQ); \ -} while(0) - -/************************* - * TYPE-SPECIFIC TESTS * - *************************/ - -#define ASSERT_BOOL(arg) \ -do { \ - SIMPLE_TEST_TYPE_CHECK(false, arg); \ - simple_test_assert_bool("false", #arg, \ - false, (bool)(arg), \ - __FILE__, __LINE__, SIMPLE_TEST_TRUE); \ -} while(0) - -#define ASSERT_BOOL_EQ(arg1, arg2) \ -do { \ - SIMPLE_TEST_TYPE_CHECK(arg1, arg2); \ - simple_test_assert_bool(#arg1, #arg2, \ - (bool)(arg1), (bool)(arg2), \ - __FILE__, __LINE__, SIMPLE_TEST_EQ); \ -} while(0) - -#define ASSERT_BOOL_NEQ(arg1, arg2) \ -do { \ - SIMPLE_TEST_TYPE_CHECK(arg1, arg2); \ - simple_test_assert_bool(#arg1, #arg2, \ - (bool)(arg1), (bool)(arg2), \ - __FILE__, __LINE__, SIMPLE_TEST_NEQ); \ -} while(0) - -#define ASSERT_INT(arg) \ -do { \ - SIMPLE_TEST_TYPE_CHECK(0, arg); \ - simple_test_assert_int("0", #arg, \ - (intmax_t)0, (intmax_t)(arg), \ - __FILE__, __LINE__, SIMPLE_TEST_TRUE); \ -} while(0) - -#define ASSERT_INT_EQ(arg1, arg2) \ -do { \ - SIMPLE_TEST_TYPE_CHECK(arg1, arg2); \ - simple_test_assert_int(#arg1, #arg2, \ - (intmax_t)(arg1), (intmax_t)(arg2), \ - __FILE__, __LINE__, SIMPLE_TEST_EQ); \ -} while(0) - -#define ASSERT_INT_NEQ(arg1, arg2) \ -do { \ - SIMPLE_TEST_TYPE_CHECK(arg1, arg2); \ - simple_test_assert_int(#arg1, #arg2, \ - (intmax_t)(arg1), (intmax_t)(arg2), \ - __FILE__, __LINE__, SIMPLE_TEST_NEQ); \ -} while(0) - -#define ASSERT_INT_G(arg1, arg2) \ -do { \ - SIMPLE_TEST_TYPE_CHECK(arg1, arg2); \ - simple_test_assert_int(#arg1, #arg2, \ - (intmax_t)(arg1), (intmax_t)(arg2), \ - __FILE__, __LINE__, SIMPLE_TEST_G); \ -} while(0) - -#define ASSERT_INT_GEQ(arg1, arg2) \ -do { \ - SIMPLE_TEST_TYPE_CHECK(arg1, arg2); \ - simple_test_assert_int(#arg1, #arg2, \ - (intmax_t)(arg1), (intmax_t)(arg2), \ - __FILE__, __LINE__, SIMPLE_TEST_GEQ); \ -} while(0) - -#define ASSERT_INT_L(arg1, arg2) \ -do { \ - SIMPLE_TEST_TYPE_CHECK(arg1, arg2); \ - simple_test_assert_int(#arg1, #arg2, \ - (intmax_t)(arg1), (intmax_t)(arg2), \ - __FILE__, __LINE__, SIMPLE_TEST_L); \ -} while(0) - -#define ASSERT_INT_LEQ(arg1, arg2) \ -do { \ - SIMPLE_TEST_TYPE_CHECK(arg1, arg2); \ - simple_test_assert_int(#arg1, #arg2, \ - (intmax_t)(arg1), (intmax_t)(arg2), \ - __FILE__, __LINE__, SIMPLE_TEST_LEQ); \ -} while(0) - -#define ASSERT_UINT(arg) \ -do { \ - SIMPLE_TEST_TYPE_CHECK(0, arg); \ - simple_test_assert_uint("0", #arg, \ - (uintmax_t)0, (uintmax_t)(arg), \ - __FILE__, __LINE__, SIMPLE_TEST_TRUE); \ -} while(0) - -#define ASSERT_UINT_EQ(arg1, arg2) \ -do { \ - SIMPLE_TEST_TYPE_CHECK(arg1, arg2); \ - simple_test_assert_uint(#arg1, #arg2, \ - (uintmax_t)(arg1), (uintmax_t)(arg2), \ - __FILE__, __LINE__, SIMPLE_TEST_EQ); \ -} while(0) - -#define ASSERT_UINT_NEQ(arg1, arg2) \ -do { \ - SIMPLE_TEST_TYPE_CHECK(arg1, arg2); \ - simple_test_assert_uint(#arg1, #arg2, \ - (uintmax_t)(arg1), (uintmax_t)(arg2), \ - __FILE__, __LINE__, SIMPLE_TEST_NEQ); \ -} while(0) - -#define ASSERT_UINT_G(arg1, arg2) \ -do { \ - SIMPLE_TEST_TYPE_CHECK(arg1, arg2); \ - simple_test_assert_uint(#arg1, #arg2, \ - (uintmax_t)(arg1), (uintmax_t)(arg2), \ - __FILE__, __LINE__, SIMPLE_TEST_G); \ -} while(0) - -#define ASSERT_UINT_GEQ(arg1, arg2) \ -do { \ - SIMPLE_TEST_TYPE_CHECK(arg1, arg2); \ - simple_test_assert_uint(#arg1, #arg2, \ - (uintmax_t)(arg1), (uintmax_t)(arg2), \ - __FILE__, __LINE__, SIMPLE_TEST_GEQ); \ -} while(0) - -#define ASSERT_UINT_L(arg1, arg2) \ -do { \ - SIMPLE_TEST_TYPE_CHECK(arg1, arg2); \ - simple_test_assert_uint(#arg1, #arg2, \ - (uintmax_t)(arg1), (uintmax_t)(arg2), \ - __FILE__, __LINE__, SIMPLE_TEST_L); \ -} while(0) - -#define ASSERT_UINT_LEQ(arg1, arg2) \ -do { \ - SIMPLE_TEST_TYPE_CHECK(arg1, arg2); \ - simple_test_assert_uint(#arg1, #arg2, \ - (uintmax_t)(arg1), (uintmax_t)(arg2), \ - __FILE__, __LINE__, SIMPLE_TEST_LEQ); \ -} while(0) - -#define ASSERT_HEX(arg) \ -do { \ - SIMPLE_TEST_TYPE_CHECK(0, arg2); \ - simple_test_assert_uint("0", #arg, \ - (uintmax_t)0, (uintmax_t)(arg), \ - __FILE__, __LINE__, SIMPLE_TEST_TRUE); \ -} while(0) - -#define ASSERT_HEX_EQ(arg1, arg2) \ -do { \ - SIMPLE_TEST_TYPE_CHECK(arg1, arg2); \ - simple_test_assert_uint(#arg1, #arg2, \ - (uintmax_t)(arg1), (uintmax_t)(arg2), \ - __FILE__, __LINE__, SIMPLE_TEST_EQ); \ -} while(0) - -#define ASSERT_HEX_NEQ(arg1, arg2) \ -do { \ - SIMPLE_TEST_TYPE_CHECK(arg1, arg2); \ - simple_test_assert_hex(#arg1, #arg2, \ - (uintmax_t)(arg1), (uintmax_t)(arg2), \ - __FILE__, __LINE__, SIMPLE_TEST_NEQ); \ -} while(0) - -#define ASSERT_HEX_G(arg1, arg2) \ -do { \ - SIMPLE_TEST_TYPE_CHECK(arg1, arg2); \ - simple_test_assert_hex(#arg1, #arg2, \ - (uintmax_t)(arg1), (uintmax_t)(arg2), \ - __FILE__, __LINE__, SIMPLE_TEST_G); \ -} while(0) - -#define ASSERT_HEX_GEQ(arg1, arg2) \ -do { \ - SIMPLE_TEST_TYPE_CHECK(arg1, arg2); \ - simple_test_assert_hex(#arg1, #arg2, \ - (uintmax_t)(arg1), (uintmax_t)(arg2), \ - __FILE__, __LINE__, SIMPLE_TEST_GEQ); \ -} while(0) - -#define ASSERT_HEX_L(arg1, arg2) \ -do { \ - SIMPLE_TEST_TYPE_CHECK(arg1, arg2); \ - simple_test_assert_hex(#arg1, #arg2, \ - (uintmax_t)(arg1), (uintmax_t)(arg2), \ - __FILE__, __LINE__, SIMPLE_TEST_L); \ -} while(0) - -#define ASSERT_HEX_LEQ(arg1, arg2) \ -do { \ - SIMPLE_TEST_TYPE_CHECK(arg1, arg2); \ - simple_test_assert_hex(#arg1, #arg2, \ - (uintmax_t)(arg1), (uintmax_t)(arg2), \ - __FILE__, __LINE__, SIMPLE_TEST_LEQ); \ -} while(0) - -#define ASSERT_FLOAT(arg) \ -do { \ - SIMPLE_TEST_TYPE_CHECK(0.0, arg); \ - simple_test_assert_float("0", #arg, \ - (long double)0, (long double)(arg), \ - __FILE__, __LINE__, SIMPLE_TEST_TRUE); \ -} while(0) - -#define ASSERT_FLOAT_EQ(arg1, arg2) \ -do { \ - SIMPLE_TEST_TYPE_CHECK(arg1, arg2); \ - simple_test_assert_float(#arg1, #arg2, \ - (long double)(arg1), (long double)(arg2), \ - __FILE__, __LINE__, SIMPLE_TEST_EQ); \ -} while(0) - -#define ASSERT_FLOAT_NEQ(arg1, arg2) \ -do { \ - SIMPLE_TEST_TYPE_CHECK(arg1, arg2); \ - simple_test_assert_float(#arg1, #arg2, \ - (long double)(arg1), (long double)(arg2), \ - __FILE__, __LINE__, SIMPLE_TEST_NEQ); \ -} while(0) - -#define ASSERT_FLOAT_G(arg1, arg2) \ -do { \ - SIMPLE_TEST_TYPE_CHECK(arg1, arg2); \ - simple_test_assert_float(#arg1, #arg2, \ - (long double)(arg1), (long double)(arg2), \ - __FILE__, __LINE__, SIMPLE_TEST_G); \ -} while(0) - -#define ASSERT_FLOAT_GEQ(arg1, arg2) \ -do { \ - SIMPLE_TEST_TYPE_CHECK(arg1, arg2); \ - simple_test_assert_float(#arg1, #arg2, \ - (long double)(arg1), (long double)(arg2), \ - __FILE__, __LINE__, SIMPLE_TEST_GEQ); \ -} while(0) - -#define ASSERT_FLOAT_L(arg1, arg2) \ -do { \ - SIMPLE_TEST_TYPE_CHECK(arg1, arg2); \ - simple_test_assert_float(#arg1, #arg2, \ - (long double)(arg1), (long double)(arg2), \ - __FILE__, __LINE__, SIMPLE_TEST_L); \ -} while(0) - -#define ASSERT_FLOAT_LEQ(arg1, arg2) \ -do { \ - SIMPLE_TEST_TYPE_CHECK(arg1, arg2); \ - simple_test_assert_float(#arg1, #arg2, \ - (long double)(arg1), (long double)(arg2), \ - __FILE__, __LINE__, SIMPLE_TEST_LEQ); \ -} while(0) - -#define ASSERT_PTR(arg) \ -do { \ - SIMPLE_TEST_TYPE_CHECK(NULL, arg); \ - simple_test_assert_ptr("NULL", #arg, \ - NULL, (void *)(arg), \ - __FILE__, __LINE__, SIMPLE_TEST_TRUE); \ -} while(0) - -#define ASSERT_PTR_EQ(arg1, arg2) \ -do { \ - SIMPLE_TEST_TYPE_CHECK(arg1, arg2); \ - simple_test_assert_ptr(#arg1, #arg2, \ - (void *)(arg1), (void *)(arg2), \ - __FILE__, __LINE__, SIMPLE_TEST_EQ); \ -} while(0) - -#define ASSERT_PTR_NEQ(arg1, arg2) \ -do { \ - SIMPLE_TEST_TYPE_CHECK(arg1, arg2); \ - simple_test_assert_ptr(#arg1, #arg2, \ - (void *)(arg1), (void *)(arg2), \ - __FILE__, __LINE__, SIMPLE_TEST_NEQ); \ -} while(0) - -#define ASSERT_PTR_G(arg1, arg2) \ -do { \ - SIMPLE_TEST_TYPE_CHECK(arg1, arg2); \ - simple_test_assert_ptr(#arg1, #arg2, \ - (void *)(arg1), (void *)(arg2), \ - __FILE__, __LINE__, SIMPLE_TEST_G); \ -} while(0) - -#define ASSERT_PTR_GEQ(arg1, arg2) \ -do { \ - SIMPLE_TEST_TYPE_CHECK(arg1, arg2); \ - simple_test_assert_ptr(#arg1, #arg2, \ - (void *)(arg1), (void *)(arg2), \ - __FILE__, __LINE__, SIMPLE_TEST_GEQ); \ -} while(0) - -#define ASSERT_PTR_L(arg1, arg2) \ -do { \ - SIMPLE_TEST_TYPE_CHECK(arg1, arg2); \ - simple_test_assert_ptr(#arg1, #arg2, \ - (void *)(arg1), (void *)(arg2), \ - __FILE__, __LINE__, SIMPLE_TEST_L); \ -} while(0) - -#define ASSERT_PTR_LEQ(arg1, arg2) \ -do { \ - SIMPLE_TEST_TYPE_CHECK(arg1, arg2); \ - simple_test_assert_ptr(#arg1, #arg2, \ - (void *)(arg1), (void *)(arg2), \ - __FILE__, __LINE__, SIMPLE_TEST_LEQ); \ -} while(0) - -#define ASSERT_CHAR(arg) \ -do { \ - SIMPLE_TEST_TYPE_CHECK('\0', arg); \ - simple_test_assert_char("\\0", #arg, \ - '\0', arg, \ - __FILE__, __LINE__, SIMPLE_TEST_TRUE); \ -} while(0) - -#define ASSERT_CHAR_EQ(arg1, arg2) \ -do { \ - SIMPLE_TEST_TYPE_CHECK(arg1, arg2); \ - simple_test_assert_char(#arg1, #arg2, \ - arg1, arg2, \ - __FILE__, __LINE__, SIMPLE_TEST_EQ); \ -} while(0) - -#define ASSERT_CHAR_NEQ(arg1, arg2) \ -do { \ - SIMPLE_TEST_TYPE_CHECK(arg1, arg2); \ - simple_test_assert_char(#arg1, #arg2, \ - arg1, arg2, \ - __FILE__, __LINE__, SIMPLE_TEST_NEQ); \ -} while(0) - -#define ASSERT_CHAR_G(arg1, arg2) \ -do { \ - SIMPLE_TEST_TYPE_CHECK(arg1, arg2); \ - simple_test_assert_char(#arg1, #arg2, \ - arg1, arg2, \ - __FILE__, __LINE__, SIMPLE_TEST_G); \ -} while(0) - -#define ASSERT_CHAR_GEQ(arg1, arg2) \ -do { \ - SIMPLE_TEST_TYPE_CHECK(arg1, arg2); \ - simple_test_assert_char(#arg1, #arg2, \ - arg1, arg2, \ - __FILE__, __LINE__, SIMPLE_TEST_GEQ); \ -} while(0) - -#define ASSERT_CHAR_L(arg1, arg2) \ -do { \ - SIMPLE_TEST_TYPE_CHECK(arg1, arg2); \ - simple_test_assert_char(#arg1, #arg2, \ - arg1, arg2, \ - __FILE__, __LINE__, SIMPLE_TEST_L); \ -} while(0) - -#define ASSERT_CHAR_LEQ(arg1, arg2) \ -do { \ - SIMPLE_TEST_TYPE_CHECK(arg1, arg2); \ - simple_test_assert_char(#arg1, #arg2, \ - arg1, arg2, \ - __FILE__, __LINE__, SIMPLE_TEST_LEQ); \ -} while(0) - -#define ASSERT_STR(arg) \ -do { \ - SIMPLE_TEST_TYPE_CHECK("0", arg); \ - simple_test_assert_str("0", #arg, \ - 0, (arg), \ - __FILE__, __LINE__, SIMPLE_TEST_TRUE); \ -} while(0) - -#define ASSERT_STR_EQ(arg1, arg2) \ -do { \ - SIMPLE_TEST_TYPE_CHECK(arg1, arg2); \ - simple_test_assert_str(#arg1, #arg2, \ - arg1, arg2, \ - __FILE__, __LINE__, SIMPLE_TEST_EQ); \ -} while(0) - -#define ASSERT_STR_NEQ(arg1, arg2) \ -do { \ - SIMPLE_TEST_TYPE_CHECK(arg1, arg2); \ - simple_test_assert_str(#arg1, #arg2, \ - arg1, arg2, \ - __FILE__, __LINE__, SIMPLE_TEST_NEQ); \ -} while(0) - -#define ASSERT_STR_G(arg1, arg2) \ -do { \ - SIMPLE_TEST_TYPE_CHECK(arg1, arg2); \ - simple_test_assert_str(#arg1, #arg2, \ - arg1, arg2, \ - __FILE__, __LINE__, SIMPLE_TEST_G); \ -} while(0) - -#define ASSERT_STR_GEQ(arg1, arg2) \ -do { \ - SIMPLE_TEST_TYPE_CHECK(arg1, arg2); \ - simple_test_assert_str(#arg1, #arg2, \ - arg1, arg2, \ - __FILE__, __LINE__, SIMPLE_TEST_GEQ); \ -} while(0) - -#define ASSERT_STR_L(arg1, arg2) \ -do { \ - SIMPLE_TEST_TYPE_CHECK(arg1, arg2); \ - simple_test_assert_str(#arg1, #arg2, \ - arg1, arg2, \ - __FILE__, __LINE__, SIMPLE_TEST_L); \ -} while(0) - -#define ASSERT_STR_LEQ(arg1, arg2) \ -do { \ - SIMPLE_TEST_TYPE_CHECK(arg1, arg2); \ - simple_test_assert_str(#arg1, #arg2, \ - arg1, arg2, \ - __FILE__, __LINE__, SIMPLE_TEST_LEQ); \ -} while(0) - -#define ASSERT_WCHAR(arg) \ -do { \ - SIMPLE_TEST_TYPE_CHECK(L'\0', arg2); \ - simple_test_assert_wchar("\\0", #arg, \ - L'\0', arg, \ - __FILE__, __LINE__, SIMPLE_TEST_TRUE); \ -} while(0) - -#define ASSERT_WCHAR_EQ(arg1, arg2) \ -do { \ - SIMPLE_TEST_TYPE_CHECK(arg1, arg2); \ - simple_test_assert_wchar(#arg1, #arg2, \ - arg1, arg2, \ - __FILE__, __LINE__, SIMPLE_TEST_EQ); \ -} while(0) - -#define ASSERT_WCHAR_NEQ(arg1, arg2) \ -do { \ - SIMPLE_TEST_TYPE_CHECK(arg1, arg2); \ - simple_test_assert_wchar(#arg1, #arg2, \ - arg1, arg2, \ - __FILE__, __LINE__, SIMPLE_TEST_NEQ); \ -} while(0) - -#define ASSERT_WCHAR_G(arg1, arg2) \ -do { \ - SIMPLE_TEST_TYPE_CHECK(arg1, arg2); \ - simple_test_assert_wchar(#arg1, #arg2, \ - arg1, arg2, \ - __FILE__, __LINE__, SIMPLE_TEST_G); \ -} while(0) - -#define ASSERT_WCHAR_GEQ(arg1, arg2) \ -do { \ - SIMPLE_TEST_TYPE_CHECK(arg1, arg2); \ - simple_test_assert_wchar(#arg1, #arg2, \ - arg1, arg2, \ - __FILE__, __LINE__, SIMPLE_TEST_GEQ); \ -} while(0) - -#define ASSERT_WCHAR_L(arg1, arg2) \ -do { \ - SIMPLE_TEST_TYPE_CHECK(arg1, arg2); \ - simple_test_assert_wchar(#arg1, #arg2, \ - arg1, arg2, \ - __FILE__, __LINE__, SIMPLE_TEST_L); \ -} while(0) - -#define ASSERT_WCHAR_LEQ(arg1, arg2) \ -do { \ - SIMPLE_TEST_TYPE_CHECK(arg1, arg2); \ - simple_test_assert_wchar(#arg1, #arg2, \ - arg1, arg2, \ - __FILE__, __LINE__, SIMPLE_TEST_LEQ); \ -} while(0) - -#define ASSERT_WSTR(arg) \ -do { \ - SIMPLE_TEST_TYPE_CHECK(L"0", arg); \ - simple_test_assert_wstr("0", #arg, \ - 0, (arg), \ - __FILE__, __LINE__, SIMPLE_TEST_TRUE); \ -} while(0) - -#define ASSERT_WSTR_EQ(arg1, arg2) \ -do { \ - SIMPLE_TEST_TYPE_CHECK(arg1, arg2); \ - simple_test_assert_wstr(#arg1, #arg2, \ - arg1, arg2, \ - __FILE__, __LINE__, SIMPLE_TEST_EQ); \ -} while(0) - -#define ASSERT_WSTR_NEQ(arg1, arg2) \ -do { \ - SIMPLE_TEST_TYPE_CHECK(arg1, arg2); \ - simple_test_assert_wstr(#arg1, #arg2, \ - arg1, arg2, \ - __FILE__, __LINE__, SIMPLE_TEST_NEQ); \ -} while(0) - -#define ASSERT_WSTR_G(arg1, arg2) \ -do { \ - SIMPLE_TEST_TYPE_CHECK(arg1, arg2); \ - simple_test_assert_wstr(#arg1, #arg2, \ - arg1, arg2, \ - __FILE__, __LINE__, SIMPLE_TEST_G); \ -} while(0) - -#define ASSERT_WSTR_GEQ(arg1, arg2) \ -do { \ - SIMPLE_TEST_TYPE_CHECK(arg1, arg2); \ - simple_test_assert_wstr(#arg1, #arg2, \ - arg1, arg2, \ - __FILE__, __LINE__, SIMPLE_TEST_GEQ); \ -} while(0) - -#define ASSERT_WSTR_L(arg1, arg2) \ -do { \ - SIMPLE_TEST_TYPE_CHECK(arg1, arg2); \ - simple_test_assert_wstr(#arg1, #arg2, \ - arg1, arg2, \ - __FILE__, __LINE__, SIMPLE_TEST_L); \ -} while(0) - -#define ASSERT_WSTR_LEQ(arg1, arg2) \ -do { \ - SIMPLE_TEST_TYPE_CHECK(arg1, arg2); \ - simple_test_assert_wstr(#arg1, #arg2, \ - arg1, arg2, \ - __FILE__, __LINE__, SIMPLE_TEST_LEQ); \ -} while(0) +#define SIMPLE_TEST_ASSERT1(t, c, s, a) \ + do { \ + switch ( simple_test_assert(t, c, (a)) ) { \ + case 1: break; \ + case 0: \ + SIMPLE_TEST_FAIL1(s " failed"); \ + SIMPLE_TEST_PRINT_VAL(0, #a, t); \ + SIMPLE_TEST_FAIL2; \ + break; \ + default: \ + SIMPLE_TEST_ERR("unrecognised type in assertion"); \ + } \ + } while (0) + +#define SIMPLE_TEST_ASSERT2(t1, t2, c, s, a, b) \ + do { \ + switch ( simple_test_assert(simple_test_type_resolve(t1, t2), \ + c, (a), (b)) ) { \ + case 1: break; \ + case 0: \ + SIMPLE_TEST_FAIL1(s " failed"); \ + SIMPLE_TEST_PRINT_VAL(0, #a, simple_test_type_resolve(t1, t2)); \ + SIMPLE_TEST_PRINT_VAL(1, #b, simple_test_type_resolve(t1, t2)); \ + SIMPLE_TEST_FAIL2; \ + break; \ + case -2: \ + SIMPLE_TEST_ERR("type mismatch in assertion"); \ + default: \ + SIMPLE_TEST_ERR("unrecognised type in assertion"); \ + } \ + } while (0) + +#define ASSERT(a) \ + SIMPLE_TEST_ASSERT1(SIMPLE_TEST_TYPE((a)), SIMPLE_TEST_TRUE, "ASSERT", a) + +#define ASSERT_NOT(a) \ + SIMPLE_TEST_ASSERT1(SIMPLE_TEST_TYPE((a)), SIMPLE_TEST_FALSE, \ + "ASSERT_NOT", a) + +#define ASSERT_EQ(a, b) \ + SIMPLE_TEST_ASSERT2(SIMPLE_TEST_TYPE((a)), SIMPLE_TEST_TYPE((b)), \ + SIMPLE_TEST_EQ, "ASSERT_EQ", a, b) + +#define ASSERT_NEQ(a, b) \ + SIMPLE_TEST_ASSERT2(SIMPLE_TEST_TYPE((a)), SIMPLE_TEST_TYPE((b)), \ + SIMPLE_TEST_NEQ, "ASSERT_NEQ", a, b) + +#define ASSERT_GT(a, b) \ + SIMPLE_TEST_ASSERT2(SIMPLE_TEST_TYPE((a)), SIMPLE_TEST_TYPE((b)), \ + SIMPLE_TEST_GT, "ASSERT_GT", a, b) + +#define ASSERT_LT(a, b) \ + SIMPLE_TEST_ASSERT2(SIMPLE_TEST_TYPE((a)), SIMPLE_TEST_TYPE((b)), \ + SIMPLE_TEST_LT, "ASSERT_LT", a, b) + +#define ASSERT_GEQ(a, b) \ + SIMPLE_TEST_ASSERT2(SIMPLE_TEST_TYPE((a)), SIMPLE_TEST_TYPE((b)), \ + SIMPLE_TEST_GEQ, "ASSERT_GEQ", a, b) + +#define ASSERT_LEQ(a, b) \ + SIMPLE_TEST_ASSERT2(SIMPLE_TEST_TYPE((a)), SIMPLE_TEST_TYPE((b)), \ + SIMPLE_TEST_LEQ, "ASSERT_LEQ", a, b) #endif -- cgit v1.2.3