#include #include #include #include "lily-test.h" struct lily_globals_t _lily_globals; void lily_init() { _lily_globals.error_msg = NULL; _lily_globals.error_location = ""; } static void _lily_assert_msg(bool statement, const char *location, const char *format_string, va_list args) { if (statement) { va_end(args); return; // no error, return } _lily_globals.error_location = location; va_list args_len; va_copy(args_len, args); size_t length = vsnprintf(NULL, 0, format_string, args_len); va_end(args_len); char *msg = realloc(_lily_globals.error_msg, (length+1) * sizeof(char)); if (msg == NULL) { fprintf(stderr, "WARNING: failed to allocate memory for failed test message!\n"); if (_lily_globals.error_msg != NULL) { free(_lily_globals.error_msg); _lily_globals.error_msg = NULL; } } else { vsnprintf(msg, length+1, format_string, args); _lily_globals.error_msg = msg; } va_end(args); longjmp(_lily_globals.env, 1); } void lily_assert_msg(bool statement, const char *location, const char *format_string, ...) { va_list args; va_start(args, format_string); // _lily_assert_msg may long jump, so it takes calls va_end(args) for you _lily_assert_msg(statement, location, format_string, args); } void _lily_assert_true(const char *statement, bool value, const char *location) { lily_assert_msg(value, location, "%s is not true", statement); } void _lily_assert_false(const char *statement, bool value, const char *location) { lily_assert_msg(value, location, "%s is not false", statement); } void _lily_assert_not_null(const char *name, void *ptr, const char *location) { lily_assert_msg(ptr != NULL, location, "%s is NULL", name); } void _lily_assert_null(const char *name, void *ptr, const char *location) { lily_assert_msg(ptr == NULL, location, "%s (%p) is not NULL", name, ptr); } void _lily_assert_ptr_equal(const char *name_a, const char *name_b, void *a, void *b, const char *location) { lily_assert_msg(a == b, location, "%s (%p) is not equal to %s (%p)", name_a, a, name_b, b); } void _lily_assert_ptr_not_equal(const char *name_a, const char *name_b, void *a, void *b, const char *location) { lily_assert_msg(a != b, location, "%s (%p) is equal to %s", name_a, a, name_b); } void _lily_assert_int_equal(const char *name_a, const char *name_b, intmax_t a, intmax_t b, const char *location) { lily_assert_msg(a == b, location, "%s (%d) is not equal to %s (%d)", name_a, a, name_b, b); } void _lily_assert_int_not_equal(const char *name_a, const char *name_b, intmax_t a, intmax_t b, const char *location) { lily_assert_msg(a != b, location, "%s (%d) is equal to %s", name_a, a, name_b); } void _lily_assert_float_equal(const char *name_a, const char *name_b, double a, double b, double epsilon, const char *location) { lily_assert_msg(abs(a - b) <= epsilon, "%s (%f) is not equal to %s (%f) (epsilon: %f)", name_a, a, name_b, b, epsilon); } void _lily_assert_float_not_equal(const char *name_a, const char *name_b, double a, double b, double epsilon, const char *location) { lily_assert_msg(abs(a - b) > epsilon, "%s (%f) is equal to %s (%f) (epsilon: %f)", name_a, a, name_b, b, epsilon); } void _lily_assert_string_equal(const char *name_a, const char *name_b, char *a, char *b, const char *location) { lily_assert_msg(strcmp(a, b) == 0, "%s ('%s') is not equal to %s ('%s')", name_a, a, name_b, b); } void _lily_assert_string_not_equal(const char *name_a, const char *name_b, char *a, char *b, const char *location) { lily_assert_msg(strcmp(a, b) != 0, "%s ('%s') is equal to %s", name_a, a, name_b); } void _lily_assert_memory_equal(const char *name_a, const char *name_b, void *a, void *b, size_t size, const char *location) { lily_assert_msg(memcmp(a, b, size) == 0, "%s and %s contain different data", name_a, name_b); } void _lily_assert_memory_not_equal(const char *name_a, const char *name_b, void *a, void *b, size_t size, const char *location) { lily_assert_msg(memcmp(a, b, size) == 0, "%s contains the same data s %s", name_a, name_b); }