diff --git a/doc/check.texi b/doc/check.texi index 3af9ada5..9d0fa22a 100644 --- a/doc/check.texi +++ b/doc/check.texi @@ -1223,6 +1223,17 @@ used for comparison is different for each function and is indicated by the last two letters of the function name. The abbreviations @code{eq} and @code{ne} correspond to @code{==} and @code{!=} respectively. +@item ck_assert_ptr_null +@itemx ck_assert_ptr_nonnull + +Compares a pointers against null and displays predefined message with +condition and value of the input parameter on failure. +@code{ck_assert_ptr_null} checks that pointer is equal to NULL and +@code{ck_assert_ptr_nonnull} checks that pointer is not equal to NULL. +@code{ck_assert_ptr_nonnull} is highly recommended to use in situations +when a function call can return NULL as error indication (like functions +that use malloc, calloc, strdup, mmap, etc). + @item ck_assert_mem_eq @itemx ck_assert_mem_ne @itemx ck_assert_mem_lt diff --git a/src/check.h.in b/src/check.h.in index 81f1ad49..c1caecb3 100644 --- a/src/check.h.in +++ b/src/check.h.in @@ -1648,6 +1648,17 @@ do { \ ck_assert_msg(_ck_x OP _ck_y, "Assertion '%s' failed: %s == %#x, %s == %#x", #X" "#OP" "#Y, #X, _ck_x, #Y, _ck_y); \ } while (0) +/* Pointer against NULL comparison macros with improved output + * compared to ck_assert(). */ +/* OP may only be == or != */ +#define _ck_assert_ptr_null(X, OP) do { \ + const void* _ck_x = (X); \ + ck_assert_msg(_ck_x OP NULL, \ + "Assertion '%s' failed: %s == %#x", \ + #X" "#OP" NULL", \ + #X, _ck_x); \ +} while (0) + /** * Check if two pointers are equal. * @@ -1675,6 +1686,32 @@ do { \ */ #define ck_assert_ptr_ne(X, Y) _ck_assert_ptr(X, !=, Y) +/** + * Check if a pointer is equal to NULL. + * + * If X != NULL, the test fails. + * + * @param X pointer to compare against NULL + * + * @note If the check fails, the remaining of the test is aborted + * + * @since 0.11.0 + */ +#define ck_assert_ptr_null(X) _ck_assert_ptr_null(X, ==) + +/** + * Check if a pointer is not equal to NULL. + * + * If X == NULL, the test fails. + * + * @param X pointer to compare against NULL + * + * @note If the check fails, the remaining of the test is aborted + * + * @since 0.11.0 + */ +#define ck_assert_ptr_nonnull(X) _ck_assert_ptr_null(X, !=) + /** * Mark the last point reached in a unit test. * diff --git a/tests/check_check_master.c b/tests/check_check_master.c index 5ac5f8ce..e61361cb 100644 --- a/tests/check_check_master.c +++ b/tests/check_check_master.c @@ -230,6 +230,8 @@ static master_test_t master_tests[] = { { "Simple Tests", "test_ck_assert_pstr_ne_with_null", CK_FAILURE, "Assertion 't != s' failed: t == (null), s == (null)" }, { "Simple Tests", "test_ck_assert_ptr_eq", CK_FAILURE, "Assertion 'x == y' failed: x == 0x1, y == 0x2" }, { "Simple Tests", "test_ck_assert_ptr_ne", CK_FAILURE, "Assertion 'x != z' failed: x == 0x1, z == 0x1" }, + { "Simple Tests", "test_ck_assert_ptr_null", CK_FAILURE, "Assertion 'x == NULL' failed: x == 0x1" }, + { "Simple Tests", "test_ck_assert_ptr_nonnull", CK_FAILURE, "Assertion 'x != NULL' failed: x == 0" }, { "Simple Tests", "test_ck_assert_mem_eq", CK_FAILURE, "Assertion '\"\\x00\\x00\\x00\\x00\\x01\" == s' failed: \"\\x00\\x00\\x00\\x00\\x01\" == \"0000000001\", s == \"0000000002\"" }, { "Simple Tests", "test_ck_assert_mem_ne", CK_FAILURE, "Assertion 't != s' failed: t == \"0000000002\", s == \"0000000002\"" }, { "Simple Tests", "test_ck_assert_mem_lt", CK_FAILURE, "Assertion 's < s' failed: s == \"0000000001\", s == \"0000000001\"" }, diff --git a/tests/check_check_sub.c b/tests/check_check_sub.c index 77de05a7..b5aac1d2 100644 --- a/tests/check_check_sub.c +++ b/tests/check_check_sub.c @@ -2131,6 +2131,30 @@ START_TEST(test_ck_assert_ptr_ne) } END_TEST +START_TEST(test_ck_assert_ptr_null) +{ + record_test_name(tcase_name()); + + void* x = (void*)0x1; + void* y = NULL; + ck_assert_ptr_null(y); + record_failure_line_num(__LINE__); + ck_assert_ptr_null(x); +} +END_TEST + +START_TEST(test_ck_assert_ptr_nonnull) +{ + record_test_name(tcase_name()); + + void* x = NULL; + void* y = (void*)0x1; + ck_assert_ptr_nonnull(y); + record_failure_line_num(__LINE__); + ck_assert_ptr_nonnull(x); +} +END_TEST + START_TEST(test_ck_assert_mem_eq) { const char *s = "\x00\x00\x00\x00\x02"; @@ -2917,6 +2941,8 @@ Suite *make_sub_suite(void) tcase_add_test (tc_simple, test_ck_assert_pstr_ne_with_null); tcase_add_test (tc_simple, test_ck_assert_ptr_eq); tcase_add_test (tc_simple, test_ck_assert_ptr_ne); + tcase_add_test (tc_simple, test_ck_assert_ptr_null); + tcase_add_test (tc_simple, test_ck_assert_ptr_nonnull); tcase_add_test (tc_simple, test_ck_assert_mem_eq); tcase_add_test (tc_simple, test_ck_assert_mem_ne); tcase_add_test (tc_simple, test_ck_assert_mem_lt);