diff options
Diffstat (limited to 'lily-test.h')
-rw-r--r-- | lily-test.h | 104 |
1 files changed, 104 insertions, 0 deletions
diff --git a/lily-test.h b/lily-test.h index 8f8b61c..c3f6f8c 100644 --- a/lily-test.h +++ b/lily-test.h @@ -53,6 +53,8 @@ #include <stddef.h> #include <stdint.h> #include <setjmp.h> +#include <stdio.h> +#include <stdarg.h> #define STR_IMP(x) #x #define STR(x) STR_IMP(x) @@ -106,6 +108,108 @@ static void f() #define LILY_TEST(description) LILY_TEST_(LILY_ANON_FUNC, LILY_ANON_DESC, description) +/* assertions */ +typedef struct lily_test_msg_t { + struct lily_test_msg_t *next; + char *msg; + const char *location; +} lily_test_msg_t; +void lily_msg_destroy(lily_test_msg_t *m); + +void lily_check(int x, const char *location, const char *fmt, ...); +#define LILY_CHECK_(str, x, location) \ + lily_check(x, location, "%s", str) +#define LILY_CHECK(x) LILY_CHECK_(STR(x), x, LILY_LOCATION) +#define CHECK(x) LILY_CHECK(x) + + +void lily_require(int x, const char *location, const char *fmt, ...); +#define LILY_REQUIRE_(str, x, location) \ + lily_require(x, location, "%s", str) +#define LILY_REQUIRE(x) LILY_REQUIRE_(STR(x), x, LILY_LOCATION) +#define REQUIRE(x) LILY_REQUIRE(x) + + +struct lily_global_t { + int failed; + jmp_buf env; + lily_test_msg_t HEAD; + lily_test_msg_t *TAIL; +} extern lily_g; + +#ifdef LILY_IMPLEMENTATION +struct lily_global_t lily_g; + +lily_test_msg_t *lily_msg_create(const char *location, const char *fmt, va_list args) +{ + lily_test_msg_t *m = malloc(sizeof(lily_test_msg_t)); + if (m == NULL) { + return NULL; + } + m->next = NULL; + m->location = location; + + va_list args_len; + va_copy(args_len, args); + size_t len = vsnprintf(NULL, 0, fmt, args_len) + 1; + va_end(args_len); + + m->msg = malloc(len * sizeof(char)); + if (m->msg == NULL) { + free(m); + return NULL; + } + vsnprintf(m->msg, len, fmt, args); + + return m; +} + +void lily_msg_destroy(lily_test_msg_t *m) +{ + if (m->next != NULL) { + // destroy the whole chain + lily_msg_destroy(m->next); + } + + free(m->msg); + free(m); +} + +void lily_check(int x, const char *location, const char *fmt, ...) +{ + if (!x) { + // assertion failed + va_list args; + va_start(args, fmt); + lily_test_msg_t *m = lily_msg_create(location, fmt, args); + va_end(args); + + lily_g.TAIL->next = m; + lily_g.TAIL = m; + lily_g.failed = 1; + } +} + + +void lily_require(int x, const char *location, const char *fmt, ...) +{ + if (!x) { + // assertion failed + va_list args; + va_start(args, fmt); + lily_test_msg_t *m = lily_msg_create(location, fmt, args); + va_end(args); + + lily_g.TAIL->next = m; + lily_g.TAIL = m; + lily_g.failed = 1; + + /* longjump out of test */ + longjmp(lily_g.env, 1); + } +} +#endif + /* ifdef LILY_TEST_H */ #else |