diff options
| author | katherine <shmibs@shmibbles.me> | 2018-03-20 21:50:25 -0700 | 
|---|---|---|
| committer | katherine <shmibs@shmibbles.me> | 2018-03-20 21:50:25 -0700 | 
| commit | 742aeab8b2044281b4ed831e54006613737ef9e4 (patch) | |
| tree | 0ac6131002e914d0adba62588fc1ead492632242 | |
| parent | 24b2890940571a3eebbf111be2cc8b380c2a4e40 (diff) | |
| download | simple-test-742aeab8b2044281b4ed831e54006613737ef9e4.tar.gz | |
clean rewrite new version
properly implement _Generics for greatest possible ease of use
| -rw-r--r-- | src/simple-test.h | 1681 | 
1 files 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 <inttypes.h> -#include <locale.h> -#include <stdlib.h> -#include <stdint.h>  #include <stdio.h> +#include <stdlib.h>  #include <stdbool.h> +#include <stdint.h> +#include <inttypes.h> +#include <stdarg.h>  #include <string.h> -#include <wchar.h>  /****************************   *  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 | 
