From c62dbc8faad8ebcdade41deaf744c2fe3cc72e13 Mon Sep 17 00:00:00 2001 From: Patrick Steinhardt Date: Thu, 4 Dec 2025 13:09:50 +0100 Subject: [PATCH 1/4] clar: fix variadic macros in integer comparison functions Variadic macros always expect at least one argument. Consequently, when one wants to declare a macro that takes a formatting string and an optional list of varibles then one cannot declare the formatting string itself as a separate argument to the function. In the newly introduced integer comparison functions we do exactly that though. Consequently, all callers must pass at least one variable to the formatting string, even if they don't want to use any formatting in the first place. Fix this by dropping the explicit formatting string parameter. Add tests to catch this issue going forward. --- clar.h | 24 ++++++++++++------------ test/expected/quiet | 10 ++++++++++ test/expected/summary_with_filename | 12 +++++++++++- test/expected/summary_without_filename | 12 +++++++++++- test/expected/tap | 24 ++++++++++++++++++++++-- test/expected/without_arguments | 12 +++++++++++- test/selftest.c | 10 +++++----- test/suites/combined.c | 22 ++++++++++++++++++++++ 8 files changed, 104 insertions(+), 22 deletions(-) diff --git a/clar.h b/clar.h index 35dda80..eb6f1df 100644 --- a/clar.h +++ b/clar.h @@ -175,28 +175,28 @@ const char *cl_fixture_basename(const char *fixture_name); #define cl_assert_equal_i_(i1,i2,note) cl_assert_compare_i(i1,i2,CLAR_COMPARISON_EQ,#i1 " != " #i2 " (" #note ")","%"PRIdMAX " != %"PRIdMAX,(intmax_t)(i1),(intmax_t)(i2)) #define cl_assert_equal_i_fmt(i1,i2,fmt) cl_assert_compare_i(i1,i2,CLAR_COMPARISON_EQ,#i1 " != " #i2, fmt " != " fmt, (int)(i1), (int)(i2)) -#define cl_assert_compare_i(i1,i2,cmp,error,description,...) clar__assert_compare_i(CLAR_CURRENT_FILE,CLAR_CURRENT_FUNC,CLAR_CURRENT_LINE,1,cmp,(i1),(i2),error,description,__VA_ARGS__) -#define cl_assert_eq_i_(i1,i2,description,...) cl_assert_compare_i(i1,i2,CLAR_COMPARISON_EQ,"Expected comparison to hold: " #i1 " == " #i2,description,__VA_ARGS__) +#define cl_assert_compare_i(i1,i2,cmp,error,...) clar__assert_compare_i(CLAR_CURRENT_FILE,CLAR_CURRENT_FUNC,CLAR_CURRENT_LINE,1,cmp,(i1),(i2),error,__VA_ARGS__) +#define cl_assert_eq_i_(i1,i2,...) cl_assert_compare_i(i1,i2,CLAR_COMPARISON_EQ,"Expected comparison to hold: " #i1 " == " #i2,__VA_ARGS__) #define cl_assert_eq_i(i1,i2) cl_assert_eq_i_(i1,i2,"%"PRIdMAX " != %"PRIdMAX,(intmax_t)(i1),(intmax_t)(i2)) -#define cl_assert_lt_i_(i1,i2,description,...) cl_assert_compare_i(i1,i2,CLAR_COMPARISON_LT,"Expected comparison to hold: " #i1 " < " #i2,description,__VA_ARGS__) +#define cl_assert_lt_i_(i1,i2,...) cl_assert_compare_i(i1,i2,CLAR_COMPARISON_LT,"Expected comparison to hold: " #i1 " < " #i2,__VA_ARGS__) #define cl_assert_lt_i(i1,i2) cl_assert_lt_i_(i1,i2,"%"PRIdMAX " >= %"PRIdMAX,(intmax_t)(i1),(intmax_t)(i2)) -#define cl_assert_le_i_(i1,i2,description,...) cl_assert_compare_i(i1,i2,CLAR_COMPARISON_LE,"Expected comparison to hold: " #i1 " <= " #i2,description,__VA_ARGS__) +#define cl_assert_le_i_(i1,i2,...) cl_assert_compare_i(i1,i2,CLAR_COMPARISON_LE,"Expected comparison to hold: " #i1 " <= " #i2,__VA_ARGS__) #define cl_assert_le_i(i1,i2) cl_assert_le_i_(i1,i2,"%"PRIdMAX " > %"PRIdMAX,(intmax_t)(i1),(intmax_t)(i2)) -#define cl_assert_gt_i_(i1,i2,description,...) cl_assert_compare_i(i1,i2,CLAR_COMPARISON_GT,"Expected comparison to hold: " #i1 " > " #i2,description,__VA_ARGS__) +#define cl_assert_gt_i_(i1,i2,...) cl_assert_compare_i(i1,i2,CLAR_COMPARISON_GT,"Expected comparison to hold: " #i1 " > " #i2,__VA_ARGS__) #define cl_assert_gt_i(i1,i2) cl_assert_gt_i_(i1,i2,"%"PRIdMAX " <= %"PRIdMAX,(intmax_t)(i1),(intmax_t)(i2)) -#define cl_assert_ge_i_(i1,i2,description,...) cl_assert_compare_i(i1,i2,CLAR_COMPARISON_GE,"Expected comparison to hold: " #i1 " >= " #i2,description,__VA_ARGS__) +#define cl_assert_ge_i_(i1,i2,...) cl_assert_compare_i(i1,i2,CLAR_COMPARISON_GE,"Expected comparison to hold: " #i1 " >= " #i2,__VA_ARGS__) #define cl_assert_ge_i(i1,i2) cl_assert_ge_i_(i1,i2,"%"PRIdMAX " < %"PRIdMAX,(intmax_t)(i1),(intmax_t)(i2)) -#define cl_assert_compare_u(u1,u2,cmp,error,description,...) clar__assert_compare_u(CLAR_CURRENT_FILE,CLAR_CURRENT_FUNC,CLAR_CURRENT_LINE,1,cmp,(u1),(u2),error,description,__VA_ARGS__) -#define cl_assert_eq_u_(u1,u2,description,...) cl_assert_compare_u(u1,u2,CLAR_COMPARISON_EQ,"Expected comparison to hold: " #u1 " == " #u2,description,__VA_ARGS__) +#define cl_assert_compare_u(u1,u2,cmp,error,...) clar__assert_compare_u(CLAR_CURRENT_FILE,CLAR_CURRENT_FUNC,CLAR_CURRENT_LINE,1,cmp,(u1),(u2),error,__VA_ARGS__) +#define cl_assert_eq_u_(u1,u2,...) cl_assert_compare_u(u1,u2,CLAR_COMPARISON_EQ,"Expected comparison to hold: " #u1 " == " #u2,__VA_ARGS__) #define cl_assert_eq_u(u1,u2) cl_assert_eq_u_(u1,u2,"%"PRIuMAX " != %"PRIuMAX,(uintmax_t)(u1),(uintmax_t)(u2)) -#define cl_assert_lt_u_(u1,u2,description,...) cl_assert_compare_u(u1,u2,CLAR_COMPARISON_LT,"Expected comparison to hold: " #u1 " < " #u2,description,__VA_ARGS__) +#define cl_assert_lt_u_(u1,u2,...) cl_assert_compare_u(u1,u2,CLAR_COMPARISON_LT,"Expected comparison to hold: " #u1 " < " #u2,__VA_ARGS__) #define cl_assert_lt_u(u1,u2) cl_assert_lt_u_(u1,u2,"%"PRIuMAX " >= %"PRIuMAX,(uintmax_t)(u1),(uintmax_t)(u2)) -#define cl_assert_le_u_(u1,u2,description,...) cl_assert_compare_u(u1,u2,CLAR_COMPARISON_LE,"Expected comparison to hold: " #u1 " <= " #u2,description,__VA_ARGS__) +#define cl_assert_le_u_(u1,u2,...) cl_assert_compare_u(u1,u2,CLAR_COMPARISON_LE,"Expected comparison to hold: " #u1 " <= " #u2,__VA_ARGS__) #define cl_assert_le_u(u1,u2) cl_assert_le_u_(u1,u2,"%"PRIuMAX " > %"PRIuMAX,(uintmax_t)(u1),(uintmax_t)(u2)) -#define cl_assert_gt_u_(u1,u2,description,...) cl_assert_compare_u(u1,u2,CLAR_COMPARISON_GT,"Expected comparison to hold: " #u1 " > " #u2,description,__VA_ARGS__) +#define cl_assert_gt_u_(u1,u2,...) cl_assert_compare_u(u1,u2,CLAR_COMPARISON_GT,"Expected comparison to hold: " #u1 " > " #u2,__VA_ARGS__) #define cl_assert_gt_u(u1,u2) cl_assert_gt_u_(u1,u2,"%"PRIuMAX " <= %"PRIuMAX,(uintmax_t)(u1),(uintmax_t)(u2)) -#define cl_assert_ge_u_(u1,u2,description,...) cl_assert_compare_u(u1,u2,CLAR_COMPARISON_GE,"Expected comparison to hold: " #u1 " >= " #u2,description,__VA_ARGS__) +#define cl_assert_ge_u_(u1,u2,...) cl_assert_compare_u(u1,u2,CLAR_COMPARISON_GE,"Expected comparison to hold: " #u1 " >= " #u2,__VA_ARGS__) #define cl_assert_ge_u(u1,u2) cl_assert_ge_u_(u1,u2,"%"PRIuMAX " < %"PRIuMAX,(uintmax_t)(u1),(uintmax_t)(u2)) #define cl_assert_equal_b(b1,b2) clar__assert_equal(CLAR_CURRENT_FILE,CLAR_CURRENT_FUNC,CLAR_CURRENT_LINE,#b1 " != " #b2, 1, "%d", (int)((b1) != 0),(int)((b2) != 0)) diff --git a/test/expected/quiet b/test/expected/quiet index d1cafcb..80745c5 100644 --- a/test/expected/quiet +++ b/test/expected/quiet @@ -53,7 +53,17 @@ combined::compare_i [file:42] 2 >= 1 12) Failure: +combined::compare_i_with_format [file:42] + Expected comparison to hold: two < 1 + foo: bar + + 13) Failure: combined::compare_u [file:42] Expected comparison to hold: two < 1 2 >= 1 + 14) Failure: +combined::compare_u_with_format [file:42] + Expected comparison to hold: two < 1 + foo: bar + diff --git a/test/expected/summary_with_filename b/test/expected/summary_with_filename index 0b9e0cf..6240713 100644 --- a/test/expected/summary_with_filename +++ b/test/expected/summary_with_filename @@ -1,6 +1,6 @@ Loaded 1 suites: Started (test status codes: OK='.' FAILURE='F' SKIPPED='S') -FFFFFFFFFFFF +FFFFFFFFFFFFFF 1) Failure: combined::1 [file:42] @@ -57,8 +57,18 @@ combined::compare_i [file:42] 2 >= 1 12) Failure: +combined::compare_i_with_format [file:42] + Expected comparison to hold: two < 1 + foo: bar + + 13) Failure: combined::compare_u [file:42] Expected comparison to hold: two < 1 2 >= 1 + 14) Failure: +combined::compare_u_with_format [file:42] + Expected comparison to hold: two < 1 + foo: bar + written summary file to different.xml diff --git a/test/expected/summary_without_filename b/test/expected/summary_without_filename index 0b6222d..f423da8 100644 --- a/test/expected/summary_without_filename +++ b/test/expected/summary_without_filename @@ -1,6 +1,6 @@ Loaded 1 suites: Started (test status codes: OK='.' FAILURE='F' SKIPPED='S') -FFFFFFFFFFFF +FFFFFFFFFFFFFF 1) Failure: combined::1 [file:42] @@ -57,8 +57,18 @@ combined::compare_i [file:42] 2 >= 1 12) Failure: +combined::compare_i_with_format [file:42] + Expected comparison to hold: two < 1 + foo: bar + + 13) Failure: combined::compare_u [file:42] Expected comparison to hold: two < 1 2 >= 1 + 14) Failure: +combined::compare_u_with_format [file:42] + Expected comparison to hold: two < 1 + foo: bar + written summary file to summary.xml diff --git a/test/expected/tap b/test/expected/tap index 03f3aa6..297e02d 100644 --- a/test/expected/tap +++ b/test/expected/tap @@ -109,7 +109,17 @@ not ok 11 - combined::compare_i line: 42 function: 'func' ... -not ok 12 - combined::compare_u +not ok 12 - combined::compare_i_with_format + --- + reason: | + Expected comparison to hold: two < 1 + foo: bar + at: + file: 'file' + line: 42 + function: 'func' + ... +not ok 13 - combined::compare_u --- reason: | Expected comparison to hold: two < 1 @@ -119,4 +129,14 @@ not ok 12 - combined::compare_u line: 42 function: 'func' ... -1..12 +not ok 14 - combined::compare_u_with_format + --- + reason: | + Expected comparison to hold: two < 1 + foo: bar + at: + file: 'file' + line: 42 + function: 'func' + ... +1..14 diff --git a/test/expected/without_arguments b/test/expected/without_arguments index d1189e8..4ad7299 100644 --- a/test/expected/without_arguments +++ b/test/expected/without_arguments @@ -1,6 +1,6 @@ Loaded 1 suites: Started (test status codes: OK='.' FAILURE='F' SKIPPED='S') -FFFFFFFFFFFF +FFFFFFFFFFFFFF 1) Failure: combined::1 [file:42] @@ -57,7 +57,17 @@ combined::compare_i [file:42] 2 >= 1 12) Failure: +combined::compare_i_with_format [file:42] + Expected comparison to hold: two < 1 + foo: bar + + 13) Failure: combined::compare_u [file:42] Expected comparison to hold: two < 1 2 >= 1 + 14) Failure: +combined::compare_u_with_format [file:42] + Expected comparison to hold: two < 1 + foo: bar + diff --git a/test/selftest.c b/test/selftest.c index 717af92..a703711 100644 --- a/test/selftest.c +++ b/test/selftest.c @@ -298,7 +298,7 @@ void test_selftest__help(void) void test_selftest__without_arguments(void) { - cl_invoke(assert_output("combined", "without_arguments", 12, NULL)); + cl_invoke(assert_output("combined", "without_arguments", 14, NULL)); } void test_selftest__specific_test(void) @@ -313,12 +313,12 @@ void test_selftest__stop_on_failure(void) void test_selftest__quiet(void) { - cl_invoke(assert_output("combined", "quiet", 12, "-q", NULL)); + cl_invoke(assert_output("combined", "quiet", 14, "-q", NULL)); } void test_selftest__tap(void) { - cl_invoke(assert_output("combined", "tap", 12, "-t", NULL)); + cl_invoke(assert_output("combined", "tap", 14, "-t", NULL)); } void test_selftest__suite_names(void) @@ -329,7 +329,7 @@ void test_selftest__suite_names(void) void test_selftest__summary_without_filename(void) { struct stat st; - cl_invoke(assert_output("combined", "summary_without_filename", 12, "-r", NULL)); + cl_invoke(assert_output("combined", "summary_without_filename", 14, "-r", NULL)); /* The summary contains timestamps, so we cannot verify its contents. */ cl_must_pass(stat("summary.xml", &st)); } @@ -337,7 +337,7 @@ void test_selftest__summary_without_filename(void) void test_selftest__summary_with_filename(void) { struct stat st; - cl_invoke(assert_output("combined", "summary_with_filename", 12, "-rdifferent.xml", NULL)); + cl_invoke(assert_output("combined", "summary_with_filename", 14, "-rdifferent.xml", NULL)); /* The summary contains timestamps, so we cannot verify its contents. */ cl_must_pass(stat("different.xml", &st)); } diff --git a/test/suites/combined.c b/test/suites/combined.c index 49ff2a2..68fcc67 100644 --- a/test/suites/combined.c +++ b/test/suites/combined.c @@ -95,27 +95,49 @@ void test_combined__compare_i(void) cl_assert_equal_i(one, 1); cl_assert_eq_i(one, 1); + cl_assert_eq_i_(one, 1, "format"); cl_assert_lt_i(one, 2); + cl_assert_lt_i_(one, 2, "format"); cl_assert_le_i(one, 2); cl_assert_le_i(two, 2); + cl_assert_le_i_(two, 2, "format"); cl_assert_gt_i(two, 1); + cl_assert_gt_i_(two, 1, "format"); cl_assert_ge_i(two, 2); cl_assert_ge_i(3, two); + cl_assert_ge_i_(3, two, "format"); cl_assert_lt_i(two, 1); /* this one fails */ } +void test_combined__compare_i_with_format(void) +{ + int two = 2; + cl_assert_lt_i_(two, 1, "foo: %s", "bar"); +} + void test_combined__compare_u(void) { unsigned one = 1, two = 2; cl_assert_eq_u(one, 1); + cl_assert_eq_u_(one, 1, "format"); cl_assert_lt_u(one, 2); + cl_assert_lt_u_(one, 2, "format"); cl_assert_le_u(one, 2); cl_assert_le_u(two, 2); + cl_assert_le_u_(two, 2, "format"); cl_assert_gt_u(two, 1); + cl_assert_gt_u_(two, 1, "format"); cl_assert_ge_u(two, 2); cl_assert_ge_u(3, two); + cl_assert_ge_u_(3, two, "format"); cl_assert_lt_u(two, 1); /* this one fails */ } + +void test_combined__compare_u_with_format(void) +{ + unsigned two = 2; + cl_assert_lt_u_(two, 1, "foo: %s", "bar"); +} From f4e19b86f515c11dac000cca59dd2164208683e4 Mon Sep 17 00:00:00 2001 From: Patrick Steinhardt Date: Thu, 4 Dec 2025 13:19:51 +0100 Subject: [PATCH 2/4] clar: merge `cl_assert_eq_i()` and `cl_assert_equal_i()` again The `cl_assert_eq_i()` function has been newly introduced with the typesafe integer comparison functions. This function and its cousin `cl_assert_eq_i_()` are so similar to the preexisting functions `cl_assert_equal_i()` and `cl_assert_equal_i_()` to cause some confusion. The only difference is the exact output format. So let's merge those two and drop the newly introduced functions again. Also rename equivalent functions for unsigned integers to match. --- clar.h | 14 ++++------- test/expected/quiet | 23 ++++++++++-------- test/expected/summary_with_filename | 25 ++++++++++++-------- test/expected/summary_without_filename | 25 ++++++++++++-------- test/expected/tap | 32 +++++++++++++++++--------- test/expected/without_arguments | 25 ++++++++++++-------- test/selftest.c | 10 ++++---- test/suites/combined.c | 15 ++++++++---- 8 files changed, 100 insertions(+), 69 deletions(-) diff --git a/clar.h b/clar.h index eb6f1df..d0811dc 100644 --- a/clar.h +++ b/clar.h @@ -170,14 +170,10 @@ const char *cl_fixture_basename(const char *fixture_name); #define cl_assert_equal_wcsn(wcs1,wcs2,len) clar__assert_equal(CLAR_CURRENT_FILE,CLAR_CURRENT_FUNC,CLAR_CURRENT_LINE,"String mismatch: " #wcs1 " != " #wcs2, 1, "%.*ls", (wcs1), (wcs2), (int)(len)) #define cl_assert_equal_wcsn_(wcs1,wcs2,len,note) clar__assert_equal(CLAR_CURRENT_FILE,CLAR_CURRENT_FUNC,CLAR_CURRENT_LINE,"String mismatch: " #wcs1 " != " #wcs2 " (" #note ")", 1, "%.*ls", (wcs1), (wcs2), (int)(len)) -/* The following three macros are essentially deprecated now in favor of the macros in subsequent blocks. */ -#define cl_assert_equal_i(i1,i2) cl_assert_compare_i(i1,i2,CLAR_COMPARISON_EQ,#i1 " != " #i2,"%"PRIdMAX " != %"PRIdMAX,(intmax_t)(i1),(intmax_t)(i2)) -#define cl_assert_equal_i_(i1,i2,note) cl_assert_compare_i(i1,i2,CLAR_COMPARISON_EQ,#i1 " != " #i2 " (" #note ")","%"PRIdMAX " != %"PRIdMAX,(intmax_t)(i1),(intmax_t)(i2)) -#define cl_assert_equal_i_fmt(i1,i2,fmt) cl_assert_compare_i(i1,i2,CLAR_COMPARISON_EQ,#i1 " != " #i2, fmt " != " fmt, (int)(i1), (int)(i2)) - #define cl_assert_compare_i(i1,i2,cmp,error,...) clar__assert_compare_i(CLAR_CURRENT_FILE,CLAR_CURRENT_FUNC,CLAR_CURRENT_LINE,1,cmp,(i1),(i2),error,__VA_ARGS__) -#define cl_assert_eq_i_(i1,i2,...) cl_assert_compare_i(i1,i2,CLAR_COMPARISON_EQ,"Expected comparison to hold: " #i1 " == " #i2,__VA_ARGS__) -#define cl_assert_eq_i(i1,i2) cl_assert_eq_i_(i1,i2,"%"PRIdMAX " != %"PRIdMAX,(intmax_t)(i1),(intmax_t)(i2)) +#define cl_assert_equal_i_(i1,i2,...) cl_assert_compare_i(i1,i2,CLAR_COMPARISON_EQ,"Expected comparison to hold: " #i1 " == " #i2,__VA_ARGS__) +#define cl_assert_equal_i(i1,i2) cl_assert_equal_i_(i1,i2,"%"PRIdMAX " != %"PRIdMAX,(intmax_t)(i1),(intmax_t)(i2)) +#define cl_assert_equal_i_fmt(i1,i2,fmt) cl_assert_compare_i(i1,i2,CLAR_COMPARISON_EQ,#i1 " != " #i2, fmt " != " fmt, (int)(i1), (int)(i2)) #define cl_assert_lt_i_(i1,i2,...) cl_assert_compare_i(i1,i2,CLAR_COMPARISON_LT,"Expected comparison to hold: " #i1 " < " #i2,__VA_ARGS__) #define cl_assert_lt_i(i1,i2) cl_assert_lt_i_(i1,i2,"%"PRIdMAX " >= %"PRIdMAX,(intmax_t)(i1),(intmax_t)(i2)) #define cl_assert_le_i_(i1,i2,...) cl_assert_compare_i(i1,i2,CLAR_COMPARISON_LE,"Expected comparison to hold: " #i1 " <= " #i2,__VA_ARGS__) @@ -188,8 +184,8 @@ const char *cl_fixture_basename(const char *fixture_name); #define cl_assert_ge_i(i1,i2) cl_assert_ge_i_(i1,i2,"%"PRIdMAX " < %"PRIdMAX,(intmax_t)(i1),(intmax_t)(i2)) #define cl_assert_compare_u(u1,u2,cmp,error,...) clar__assert_compare_u(CLAR_CURRENT_FILE,CLAR_CURRENT_FUNC,CLAR_CURRENT_LINE,1,cmp,(u1),(u2),error,__VA_ARGS__) -#define cl_assert_eq_u_(u1,u2,...) cl_assert_compare_u(u1,u2,CLAR_COMPARISON_EQ,"Expected comparison to hold: " #u1 " == " #u2,__VA_ARGS__) -#define cl_assert_eq_u(u1,u2) cl_assert_eq_u_(u1,u2,"%"PRIuMAX " != %"PRIuMAX,(uintmax_t)(u1),(uintmax_t)(u2)) +#define cl_assert_equal_u_(u1,u2,...) cl_assert_compare_u(u1,u2,CLAR_COMPARISON_EQ,"Expected comparison to hold: " #u1 " == " #u2,__VA_ARGS__) +#define cl_assert_equal_u(u1,u2) cl_assert_equal_u_(u1,u2,"%"PRIuMAX " != %"PRIuMAX,(uintmax_t)(u1),(uintmax_t)(u2)) #define cl_assert_lt_u_(u1,u2,...) cl_assert_compare_u(u1,u2,CLAR_COMPARISON_LT,"Expected comparison to hold: " #u1 " < " #u2,__VA_ARGS__) #define cl_assert_lt_u(u1,u2) cl_assert_lt_u_(u1,u2,"%"PRIuMAX " >= %"PRIuMAX,(uintmax_t)(u1),(uintmax_t)(u2)) #define cl_assert_le_u_(u1,u2,...) cl_assert_compare_u(u1,u2,CLAR_COMPARISON_LE,"Expected comparison to hold: " #u1 " <= " #u2,__VA_ARGS__) diff --git a/test/expected/quiet b/test/expected/quiet index 80745c5..8a90246 100644 --- a/test/expected/quiet +++ b/test/expected/quiet @@ -18,51 +18,56 @@ combined::strings_with_length [file:42] 5) Failure: combined::int [file:42] - 101 != value ("extra note on failing test") + Expected comparison to hold: 101 == value 101 != 100 6) Failure: +combined::int_note [file:42] + Expected comparison to hold: 101 == value + extra note on failing test + + 7) Failure: combined::int_fmt [file:42] 022 != value 0022 != 0144 - 7) Failure: + 8) Failure: combined::bool [file:42] 0 != value 0 != 1 - 8) Failure: + 9) Failure: combined::multiline_description [file:42] Function call failed: -1 description line 1 description line 2 - 9) Failure: + 10) Failure: combined::null_string [file:42] String mismatch: "expected" != actual ("this one fails") 'expected' != NULL - 10) Failure: + 11) Failure: combined::failf [file:42] Test failed. some reason: foo - 11) Failure: + 12) Failure: combined::compare_i [file:42] Expected comparison to hold: two < 1 2 >= 1 - 12) Failure: + 13) Failure: combined::compare_i_with_format [file:42] Expected comparison to hold: two < 1 foo: bar - 13) Failure: + 14) Failure: combined::compare_u [file:42] Expected comparison to hold: two < 1 2 >= 1 - 14) Failure: + 15) Failure: combined::compare_u_with_format [file:42] Expected comparison to hold: two < 1 foo: bar diff --git a/test/expected/summary_with_filename b/test/expected/summary_with_filename index 6240713..1b17faf 100644 --- a/test/expected/summary_with_filename +++ b/test/expected/summary_with_filename @@ -1,6 +1,6 @@ Loaded 1 suites: Started (test status codes: OK='.' FAILURE='F' SKIPPED='S') -FFFFFFFFFFFFFF +FFFFFFFFFFFFFFF 1) Failure: combined::1 [file:42] @@ -22,51 +22,56 @@ combined::strings_with_length [file:42] 5) Failure: combined::int [file:42] - 101 != value ("extra note on failing test") + Expected comparison to hold: 101 == value 101 != 100 6) Failure: +combined::int_note [file:42] + Expected comparison to hold: 101 == value + extra note on failing test + + 7) Failure: combined::int_fmt [file:42] 022 != value 0022 != 0144 - 7) Failure: + 8) Failure: combined::bool [file:42] 0 != value 0 != 1 - 8) Failure: + 9) Failure: combined::multiline_description [file:42] Function call failed: -1 description line 1 description line 2 - 9) Failure: + 10) Failure: combined::null_string [file:42] String mismatch: "expected" != actual ("this one fails") 'expected' != NULL - 10) Failure: + 11) Failure: combined::failf [file:42] Test failed. some reason: foo - 11) Failure: + 12) Failure: combined::compare_i [file:42] Expected comparison to hold: two < 1 2 >= 1 - 12) Failure: + 13) Failure: combined::compare_i_with_format [file:42] Expected comparison to hold: two < 1 foo: bar - 13) Failure: + 14) Failure: combined::compare_u [file:42] Expected comparison to hold: two < 1 2 >= 1 - 14) Failure: + 15) Failure: combined::compare_u_with_format [file:42] Expected comparison to hold: two < 1 foo: bar diff --git a/test/expected/summary_without_filename b/test/expected/summary_without_filename index f423da8..fe46b0f 100644 --- a/test/expected/summary_without_filename +++ b/test/expected/summary_without_filename @@ -1,6 +1,6 @@ Loaded 1 suites: Started (test status codes: OK='.' FAILURE='F' SKIPPED='S') -FFFFFFFFFFFFFF +FFFFFFFFFFFFFFF 1) Failure: combined::1 [file:42] @@ -22,51 +22,56 @@ combined::strings_with_length [file:42] 5) Failure: combined::int [file:42] - 101 != value ("extra note on failing test") + Expected comparison to hold: 101 == value 101 != 100 6) Failure: +combined::int_note [file:42] + Expected comparison to hold: 101 == value + extra note on failing test + + 7) Failure: combined::int_fmt [file:42] 022 != value 0022 != 0144 - 7) Failure: + 8) Failure: combined::bool [file:42] 0 != value 0 != 1 - 8) Failure: + 9) Failure: combined::multiline_description [file:42] Function call failed: -1 description line 1 description line 2 - 9) Failure: + 10) Failure: combined::null_string [file:42] String mismatch: "expected" != actual ("this one fails") 'expected' != NULL - 10) Failure: + 11) Failure: combined::failf [file:42] Test failed. some reason: foo - 11) Failure: + 12) Failure: combined::compare_i [file:42] Expected comparison to hold: two < 1 2 >= 1 - 12) Failure: + 13) Failure: combined::compare_i_with_format [file:42] Expected comparison to hold: two < 1 foo: bar - 13) Failure: + 14) Failure: combined::compare_u [file:42] Expected comparison to hold: two < 1 2 >= 1 - 14) Failure: + 15) Failure: combined::compare_u_with_format [file:42] Expected comparison to hold: two < 1 foo: bar diff --git a/test/expected/tap b/test/expected/tap index 297e02d..e1956c8 100644 --- a/test/expected/tap +++ b/test/expected/tap @@ -41,14 +41,24 @@ not ok 4 - combined::strings_with_length not ok 5 - combined::int --- reason: | - 101 != value ("extra note on failing test") + Expected comparison to hold: 101 == value 101 != 100 at: file: 'file' line: 42 function: 'func' ... -not ok 6 - combined::int_fmt +not ok 6 - combined::int_note + --- + reason: | + Expected comparison to hold: 101 == value + extra note on failing test + at: + file: 'file' + line: 42 + function: 'func' + ... +not ok 7 - combined::int_fmt --- reason: | 022 != value @@ -58,7 +68,7 @@ not ok 6 - combined::int_fmt line: 42 function: 'func' ... -not ok 7 - combined::bool +not ok 8 - combined::bool --- reason: | 0 != value @@ -68,7 +78,7 @@ not ok 7 - combined::bool line: 42 function: 'func' ... -not ok 8 - combined::multiline_description +not ok 9 - combined::multiline_description --- reason: | Function call failed: -1 @@ -79,7 +89,7 @@ not ok 8 - combined::multiline_description line: 42 function: 'func' ... -not ok 9 - combined::null_string +not ok 10 - combined::null_string --- reason: | String mismatch: "expected" != actual ("this one fails") @@ -89,7 +99,7 @@ not ok 9 - combined::null_string line: 42 function: 'func' ... -not ok 10 - combined::failf +not ok 11 - combined::failf --- reason: | Test failed. @@ -99,7 +109,7 @@ not ok 10 - combined::failf line: 42 function: 'func' ... -not ok 11 - combined::compare_i +not ok 12 - combined::compare_i --- reason: | Expected comparison to hold: two < 1 @@ -109,7 +119,7 @@ not ok 11 - combined::compare_i line: 42 function: 'func' ... -not ok 12 - combined::compare_i_with_format +not ok 13 - combined::compare_i_with_format --- reason: | Expected comparison to hold: two < 1 @@ -119,7 +129,7 @@ not ok 12 - combined::compare_i_with_format line: 42 function: 'func' ... -not ok 13 - combined::compare_u +not ok 14 - combined::compare_u --- reason: | Expected comparison to hold: two < 1 @@ -129,7 +139,7 @@ not ok 13 - combined::compare_u line: 42 function: 'func' ... -not ok 14 - combined::compare_u_with_format +not ok 15 - combined::compare_u_with_format --- reason: | Expected comparison to hold: two < 1 @@ -139,4 +149,4 @@ not ok 14 - combined::compare_u_with_format line: 42 function: 'func' ... -1..14 +1..15 diff --git a/test/expected/without_arguments b/test/expected/without_arguments index 4ad7299..4a583b7 100644 --- a/test/expected/without_arguments +++ b/test/expected/without_arguments @@ -1,6 +1,6 @@ Loaded 1 suites: Started (test status codes: OK='.' FAILURE='F' SKIPPED='S') -FFFFFFFFFFFFFF +FFFFFFFFFFFFFFF 1) Failure: combined::1 [file:42] @@ -22,51 +22,56 @@ combined::strings_with_length [file:42] 5) Failure: combined::int [file:42] - 101 != value ("extra note on failing test") + Expected comparison to hold: 101 == value 101 != 100 6) Failure: +combined::int_note [file:42] + Expected comparison to hold: 101 == value + extra note on failing test + + 7) Failure: combined::int_fmt [file:42] 022 != value 0022 != 0144 - 7) Failure: + 8) Failure: combined::bool [file:42] 0 != value 0 != 1 - 8) Failure: + 9) Failure: combined::multiline_description [file:42] Function call failed: -1 description line 1 description line 2 - 9) Failure: + 10) Failure: combined::null_string [file:42] String mismatch: "expected" != actual ("this one fails") 'expected' != NULL - 10) Failure: + 11) Failure: combined::failf [file:42] Test failed. some reason: foo - 11) Failure: + 12) Failure: combined::compare_i [file:42] Expected comparison to hold: two < 1 2 >= 1 - 12) Failure: + 13) Failure: combined::compare_i_with_format [file:42] Expected comparison to hold: two < 1 foo: bar - 13) Failure: + 14) Failure: combined::compare_u [file:42] Expected comparison to hold: two < 1 2 >= 1 - 14) Failure: + 15) Failure: combined::compare_u_with_format [file:42] Expected comparison to hold: two < 1 foo: bar diff --git a/test/selftest.c b/test/selftest.c index a703711..6eadc64 100644 --- a/test/selftest.c +++ b/test/selftest.c @@ -298,7 +298,7 @@ void test_selftest__help(void) void test_selftest__without_arguments(void) { - cl_invoke(assert_output("combined", "without_arguments", 14, NULL)); + cl_invoke(assert_output("combined", "without_arguments", 15, NULL)); } void test_selftest__specific_test(void) @@ -313,12 +313,12 @@ void test_selftest__stop_on_failure(void) void test_selftest__quiet(void) { - cl_invoke(assert_output("combined", "quiet", 14, "-q", NULL)); + cl_invoke(assert_output("combined", "quiet", 15, "-q", NULL)); } void test_selftest__tap(void) { - cl_invoke(assert_output("combined", "tap", 14, "-t", NULL)); + cl_invoke(assert_output("combined", "tap", 15, "-t", NULL)); } void test_selftest__suite_names(void) @@ -329,7 +329,7 @@ void test_selftest__suite_names(void) void test_selftest__summary_without_filename(void) { struct stat st; - cl_invoke(assert_output("combined", "summary_without_filename", 14, "-r", NULL)); + cl_invoke(assert_output("combined", "summary_without_filename", 15, "-r", NULL)); /* The summary contains timestamps, so we cannot verify its contents. */ cl_must_pass(stat("summary.xml", &st)); } @@ -337,7 +337,7 @@ void test_selftest__summary_without_filename(void) void test_selftest__summary_with_filename(void) { struct stat st; - cl_invoke(assert_output("combined", "summary_with_filename", 14, "-rdifferent.xml", NULL)); + cl_invoke(assert_output("combined", "summary_with_filename", 15, "-rdifferent.xml", NULL)); /* The summary contains timestamps, so we cannot verify its contents. */ cl_must_pass(stat("different.xml", &st)); } diff --git a/test/suites/combined.c b/test/suites/combined.c index 68fcc67..9e9dbc2 100644 --- a/test/suites/combined.c +++ b/test/suites/combined.c @@ -55,7 +55,12 @@ void test_combined__strings_with_length(void) void test_combined__int(void) { int value = 100; - cl_assert_equal_i(100, value); + cl_assert_equal_i(101, value); +} + +void test_combined__int_note(void) +{ + int value = 100; cl_assert_equal_i_(101, value, "extra note on failing test"); } @@ -94,8 +99,8 @@ void test_combined__compare_i(void) int one = 1, two = 2; cl_assert_equal_i(one, 1); - cl_assert_eq_i(one, 1); - cl_assert_eq_i_(one, 1, "format"); + cl_assert_equal_i(one, 1); + cl_assert_equal_i_(one, 1, "format"); cl_assert_lt_i(one, 2); cl_assert_lt_i_(one, 2, "format"); cl_assert_le_i(one, 2); @@ -120,8 +125,8 @@ void test_combined__compare_u(void) { unsigned one = 1, two = 2; - cl_assert_eq_u(one, 1); - cl_assert_eq_u_(one, 1, "format"); + cl_assert_equal_u(one, 1); + cl_assert_equal_u_(one, 1, "format"); cl_assert_lt_u(one, 2); cl_assert_lt_u_(one, 2, "format"); cl_assert_le_u(one, 2); From 815978122ea44c5c9a3b1aac036f7ef65dac64ac Mon Sep 17 00:00:00 2001 From: Patrick Steinhardt Date: Fri, 5 Dec 2025 11:07:25 +0100 Subject: [PATCH 3/4] clar: avoid repetition in integer comparison functions The error message that we use for all the integer comparison functions is repeated for every macro. This was done because we reused the same infra for both deprecated comparison functions (`cl_assert_equal_i()`) and the new replacements (`cl_assert_eq_i()`), and the resulting error messages are expected to be different there. That has changed in the preceding commit though, where we started to open-code the deprecated functions. Consequently, we can now deduplicate the error message for the new comparison functions. Do so. --- clar.h | 28 ++++++++++++++------------ test/expected/quiet | 2 +- test/expected/summary_with_filename | 2 +- test/expected/summary_without_filename | 2 +- test/expected/tap | 2 +- test/expected/without_arguments | 2 +- 6 files changed, 20 insertions(+), 18 deletions(-) diff --git a/clar.h b/clar.h index d0811dc..ae8f7b8 100644 --- a/clar.h +++ b/clar.h @@ -170,29 +170,31 @@ const char *cl_fixture_basename(const char *fixture_name); #define cl_assert_equal_wcsn(wcs1,wcs2,len) clar__assert_equal(CLAR_CURRENT_FILE,CLAR_CURRENT_FUNC,CLAR_CURRENT_LINE,"String mismatch: " #wcs1 " != " #wcs2, 1, "%.*ls", (wcs1), (wcs2), (int)(len)) #define cl_assert_equal_wcsn_(wcs1,wcs2,len,note) clar__assert_equal(CLAR_CURRENT_FILE,CLAR_CURRENT_FUNC,CLAR_CURRENT_LINE,"String mismatch: " #wcs1 " != " #wcs2 " (" #note ")", 1, "%.*ls", (wcs1), (wcs2), (int)(len)) -#define cl_assert_compare_i(i1,i2,cmp,error,...) clar__assert_compare_i(CLAR_CURRENT_FILE,CLAR_CURRENT_FUNC,CLAR_CURRENT_LINE,1,cmp,(i1),(i2),error,__VA_ARGS__) -#define cl_assert_equal_i_(i1,i2,...) cl_assert_compare_i(i1,i2,CLAR_COMPARISON_EQ,"Expected comparison to hold: " #i1 " == " #i2,__VA_ARGS__) +#define cl_assert_compare_i_(i1, i2, cmp, error, ...) clar__assert_compare_i(CLAR_CURRENT_FILE, CLAR_CURRENT_FUNC, CLAR_CURRENT_LINE, 1, cmp, \ + (i1), (i2), "Expected comparison to hold: " error, __VA_ARGS__) +#define cl_assert_equal_i_(i1, i2, ...) cl_assert_compare_i_(i1, i2, CLAR_COMPARISON_EQ, #i1 " == " #i2, __VA_ARGS__) #define cl_assert_equal_i(i1,i2) cl_assert_equal_i_(i1,i2,"%"PRIdMAX " != %"PRIdMAX,(intmax_t)(i1),(intmax_t)(i2)) -#define cl_assert_equal_i_fmt(i1,i2,fmt) cl_assert_compare_i(i1,i2,CLAR_COMPARISON_EQ,#i1 " != " #i2, fmt " != " fmt, (int)(i1), (int)(i2)) -#define cl_assert_lt_i_(i1,i2,...) cl_assert_compare_i(i1,i2,CLAR_COMPARISON_LT,"Expected comparison to hold: " #i1 " < " #i2,__VA_ARGS__) +#define cl_assert_equal_i_fmt(i1, i2, fmt) cl_assert_compare_i_(i1, i2, CLAR_COMPARISON_EQ, #i1 " == " #i2, fmt " != " fmt, (int)(i1), (int)(i2)) +#define cl_assert_lt_i_(i1, i2, ...) cl_assert_compare_i_(i1, i2, CLAR_COMPARISON_LT, #i1 " < " #i2, __VA_ARGS__) #define cl_assert_lt_i(i1,i2) cl_assert_lt_i_(i1,i2,"%"PRIdMAX " >= %"PRIdMAX,(intmax_t)(i1),(intmax_t)(i2)) -#define cl_assert_le_i_(i1,i2,...) cl_assert_compare_i(i1,i2,CLAR_COMPARISON_LE,"Expected comparison to hold: " #i1 " <= " #i2,__VA_ARGS__) +#define cl_assert_le_i_(i1, i2, ...) cl_assert_compare_i_(i1, i2, CLAR_COMPARISON_LE, #i1 " <= " #i2, __VA_ARGS__) #define cl_assert_le_i(i1,i2) cl_assert_le_i_(i1,i2,"%"PRIdMAX " > %"PRIdMAX,(intmax_t)(i1),(intmax_t)(i2)) -#define cl_assert_gt_i_(i1,i2,...) cl_assert_compare_i(i1,i2,CLAR_COMPARISON_GT,"Expected comparison to hold: " #i1 " > " #i2,__VA_ARGS__) +#define cl_assert_gt_i_(i1, i2, ...) cl_assert_compare_i_(i1, i2, CLAR_COMPARISON_GT, #i1 " > " #i2, __VA_ARGS__) #define cl_assert_gt_i(i1,i2) cl_assert_gt_i_(i1,i2,"%"PRIdMAX " <= %"PRIdMAX,(intmax_t)(i1),(intmax_t)(i2)) -#define cl_assert_ge_i_(i1,i2,...) cl_assert_compare_i(i1,i2,CLAR_COMPARISON_GE,"Expected comparison to hold: " #i1 " >= " #i2,__VA_ARGS__) +#define cl_assert_ge_i_(i1, i2, ...) cl_assert_compare_i_(i1, i2, CLAR_COMPARISON_GE, #i1 " >= " #i2, __VA_ARGS__) #define cl_assert_ge_i(i1,i2) cl_assert_ge_i_(i1,i2,"%"PRIdMAX " < %"PRIdMAX,(intmax_t)(i1),(intmax_t)(i2)) -#define cl_assert_compare_u(u1,u2,cmp,error,...) clar__assert_compare_u(CLAR_CURRENT_FILE,CLAR_CURRENT_FUNC,CLAR_CURRENT_LINE,1,cmp,(u1),(u2),error,__VA_ARGS__) -#define cl_assert_equal_u_(u1,u2,...) cl_assert_compare_u(u1,u2,CLAR_COMPARISON_EQ,"Expected comparison to hold: " #u1 " == " #u2,__VA_ARGS__) +#define cl_assert_compare_u_(u1, u2, cmp, error, ...) clar__assert_compare_u(CLAR_CURRENT_FILE, CLAR_CURRENT_FUNC, CLAR_CURRENT_LINE, 1, cmp, \ + (u1), (u2), "Expected comparison to hold: " error, __VA_ARGS__) +#define cl_assert_equal_u_(u1, u2, ...) cl_assert_compare_u_(u1, u2, CLAR_COMPARISON_EQ, #u1 " == " #u2, __VA_ARGS__) #define cl_assert_equal_u(u1,u2) cl_assert_equal_u_(u1,u2,"%"PRIuMAX " != %"PRIuMAX,(uintmax_t)(u1),(uintmax_t)(u2)) -#define cl_assert_lt_u_(u1,u2,...) cl_assert_compare_u(u1,u2,CLAR_COMPARISON_LT,"Expected comparison to hold: " #u1 " < " #u2,__VA_ARGS__) +#define cl_assert_lt_u_(u1, u2, ...) cl_assert_compare_u_(u1, u2, CLAR_COMPARISON_LT, #u1 " < " #u2, __VA_ARGS__) #define cl_assert_lt_u(u1,u2) cl_assert_lt_u_(u1,u2,"%"PRIuMAX " >= %"PRIuMAX,(uintmax_t)(u1),(uintmax_t)(u2)) -#define cl_assert_le_u_(u1,u2,...) cl_assert_compare_u(u1,u2,CLAR_COMPARISON_LE,"Expected comparison to hold: " #u1 " <= " #u2,__VA_ARGS__) +#define cl_assert_le_u_(u1, u2, ...) cl_assert_compare_u_(u1, u2, CLAR_COMPARISON_LE, #u1 " <= " #u2, __VA_ARGS__) #define cl_assert_le_u(u1,u2) cl_assert_le_u_(u1,u2,"%"PRIuMAX " > %"PRIuMAX,(uintmax_t)(u1),(uintmax_t)(u2)) -#define cl_assert_gt_u_(u1,u2,...) cl_assert_compare_u(u1,u2,CLAR_COMPARISON_GT,"Expected comparison to hold: " #u1 " > " #u2,__VA_ARGS__) +#define cl_assert_gt_u_(u1, u2, ...) cl_assert_compare_u_(u1, u2, CLAR_COMPARISON_GT, #u1 " > " #u2, __VA_ARGS__) #define cl_assert_gt_u(u1,u2) cl_assert_gt_u_(u1,u2,"%"PRIuMAX " <= %"PRIuMAX,(uintmax_t)(u1),(uintmax_t)(u2)) -#define cl_assert_ge_u_(u1,u2,...) cl_assert_compare_u(u1,u2,CLAR_COMPARISON_GE,"Expected comparison to hold: " #u1 " >= " #u2,__VA_ARGS__) +#define cl_assert_ge_u_(u1, u2, ...) cl_assert_compare_u_(u1, u2, CLAR_COMPARISON_GE, #u1 " >= " #u2, __VA_ARGS__) #define cl_assert_ge_u(u1,u2) cl_assert_ge_u_(u1,u2,"%"PRIuMAX " < %"PRIuMAX,(uintmax_t)(u1),(uintmax_t)(u2)) #define cl_assert_equal_b(b1,b2) clar__assert_equal(CLAR_CURRENT_FILE,CLAR_CURRENT_FUNC,CLAR_CURRENT_LINE,#b1 " != " #b2, 1, "%d", (int)((b1) != 0),(int)((b2) != 0)) diff --git a/test/expected/quiet b/test/expected/quiet index 8a90246..a93273b 100644 --- a/test/expected/quiet +++ b/test/expected/quiet @@ -28,7 +28,7 @@ combined::int_note [file:42] 7) Failure: combined::int_fmt [file:42] - 022 != value + Expected comparison to hold: 022 == value 0022 != 0144 8) Failure: diff --git a/test/expected/summary_with_filename b/test/expected/summary_with_filename index 1b17faf..a9471cc 100644 --- a/test/expected/summary_with_filename +++ b/test/expected/summary_with_filename @@ -32,7 +32,7 @@ combined::int_note [file:42] 7) Failure: combined::int_fmt [file:42] - 022 != value + Expected comparison to hold: 022 == value 0022 != 0144 8) Failure: diff --git a/test/expected/summary_without_filename b/test/expected/summary_without_filename index fe46b0f..83ba770 100644 --- a/test/expected/summary_without_filename +++ b/test/expected/summary_without_filename @@ -32,7 +32,7 @@ combined::int_note [file:42] 7) Failure: combined::int_fmt [file:42] - 022 != value + Expected comparison to hold: 022 == value 0022 != 0144 8) Failure: diff --git a/test/expected/tap b/test/expected/tap index e1956c8..e67118d 100644 --- a/test/expected/tap +++ b/test/expected/tap @@ -61,7 +61,7 @@ not ok 6 - combined::int_note not ok 7 - combined::int_fmt --- reason: | - 022 != value + Expected comparison to hold: 022 == value 0022 != 0144 at: file: 'file' diff --git a/test/expected/without_arguments b/test/expected/without_arguments index 4a583b7..9891f45 100644 --- a/test/expected/without_arguments +++ b/test/expected/without_arguments @@ -32,7 +32,7 @@ combined::int_note [file:42] 7) Failure: combined::int_fmt [file:42] - 022 != value + Expected comparison to hold: 022 == value 0022 != 0144 8) Failure: From db09c8511c01bc4bafe11ddd823d44a0fef1f747 Mon Sep 17 00:00:00 2001 From: Patrick Steinhardt Date: Fri, 5 Dec 2025 11:07:45 +0100 Subject: [PATCH 4/4] clar: fix double evaluation for integer comparison macros Same as with a preceding comimt we also have double evaluation of arguments in the newly introduced integer comparison macros. Fix this issue by storing the values in a local variable first. --- clar.h | 30 ++++++++++++++++++++---------- 1 file changed, 20 insertions(+), 10 deletions(-) diff --git a/clar.h b/clar.h index ae8f7b8..f7e4363 100644 --- a/clar.h +++ b/clar.h @@ -172,30 +172,40 @@ const char *cl_fixture_basename(const char *fixture_name); #define cl_assert_compare_i_(i1, i2, cmp, error, ...) clar__assert_compare_i(CLAR_CURRENT_FILE, CLAR_CURRENT_FUNC, CLAR_CURRENT_LINE, 1, cmp, \ (i1), (i2), "Expected comparison to hold: " error, __VA_ARGS__) +#define cl_assert_compare_i(i1, i2, cmp, error, fmt) do { \ + intmax_t v1 = (i1), v2 = (i2); \ + clar__assert_compare_i(CLAR_CURRENT_FILE, CLAR_CURRENT_FUNC, CLAR_CURRENT_LINE, 1, cmp, \ + v1, v2, "Expected comparison to hold: " error, fmt, v1, v2); \ +} while (0) #define cl_assert_equal_i_(i1, i2, ...) cl_assert_compare_i_(i1, i2, CLAR_COMPARISON_EQ, #i1 " == " #i2, __VA_ARGS__) -#define cl_assert_equal_i(i1,i2) cl_assert_equal_i_(i1,i2,"%"PRIdMAX " != %"PRIdMAX,(intmax_t)(i1),(intmax_t)(i2)) +#define cl_assert_equal_i(i1, i2) cl_assert_compare_i (i1, i2, CLAR_COMPARISON_EQ, #i1 " == " #i2, "%"PRIdMAX " != %"PRIdMAX) #define cl_assert_equal_i_fmt(i1, i2, fmt) cl_assert_compare_i_(i1, i2, CLAR_COMPARISON_EQ, #i1 " == " #i2, fmt " != " fmt, (int)(i1), (int)(i2)) #define cl_assert_lt_i_(i1, i2, ...) cl_assert_compare_i_(i1, i2, CLAR_COMPARISON_LT, #i1 " < " #i2, __VA_ARGS__) -#define cl_assert_lt_i(i1,i2) cl_assert_lt_i_(i1,i2,"%"PRIdMAX " >= %"PRIdMAX,(intmax_t)(i1),(intmax_t)(i2)) +#define cl_assert_lt_i(i1, i2) cl_assert_compare_i (i1, i2, CLAR_COMPARISON_LT, #i1 " < " #i2, "%"PRIdMAX " >= %"PRIdMAX) #define cl_assert_le_i_(i1, i2, ...) cl_assert_compare_i_(i1, i2, CLAR_COMPARISON_LE, #i1 " <= " #i2, __VA_ARGS__) -#define cl_assert_le_i(i1,i2) cl_assert_le_i_(i1,i2,"%"PRIdMAX " > %"PRIdMAX,(intmax_t)(i1),(intmax_t)(i2)) +#define cl_assert_le_i(i1, i2) cl_assert_compare_i (i1, i2, CLAR_COMPARISON_LE, #i1 " <= " #i2, "%"PRIdMAX " > %"PRIdMAX) #define cl_assert_gt_i_(i1, i2, ...) cl_assert_compare_i_(i1, i2, CLAR_COMPARISON_GT, #i1 " > " #i2, __VA_ARGS__) -#define cl_assert_gt_i(i1,i2) cl_assert_gt_i_(i1,i2,"%"PRIdMAX " <= %"PRIdMAX,(intmax_t)(i1),(intmax_t)(i2)) +#define cl_assert_gt_i(i1, i2) cl_assert_compare_i (i1, i2, CLAR_COMPARISON_GT, #i1 " > " #i2, "%"PRIdMAX " <= %"PRIdMAX) #define cl_assert_ge_i_(i1, i2, ...) cl_assert_compare_i_(i1, i2, CLAR_COMPARISON_GE, #i1 " >= " #i2, __VA_ARGS__) -#define cl_assert_ge_i(i1,i2) cl_assert_ge_i_(i1,i2,"%"PRIdMAX " < %"PRIdMAX,(intmax_t)(i1),(intmax_t)(i2)) +#define cl_assert_ge_i(i1, i2) cl_assert_compare_i (i1, i2, CLAR_COMPARISON_GE, #i1 " >= " #i2, "%"PRIdMAX " < %"PRIdMAX) #define cl_assert_compare_u_(u1, u2, cmp, error, ...) clar__assert_compare_u(CLAR_CURRENT_FILE, CLAR_CURRENT_FUNC, CLAR_CURRENT_LINE, 1, cmp, \ (u1), (u2), "Expected comparison to hold: " error, __VA_ARGS__) +#define cl_assert_compare_u(u1, u2, cmp, error, fmt) do { \ + uintmax_t v1 = (u1), v2 = (u2); \ + clar__assert_compare_u(CLAR_CURRENT_FILE, CLAR_CURRENT_FUNC, CLAR_CURRENT_LINE, 1, cmp, \ + v1, v2, "Expected comparison to hold: " error, fmt, v1, v2); \ +} while (0) #define cl_assert_equal_u_(u1, u2, ...) cl_assert_compare_u_(u1, u2, CLAR_COMPARISON_EQ, #u1 " == " #u2, __VA_ARGS__) -#define cl_assert_equal_u(u1,u2) cl_assert_equal_u_(u1,u2,"%"PRIuMAX " != %"PRIuMAX,(uintmax_t)(u1),(uintmax_t)(u2)) +#define cl_assert_equal_u(u1, u2) cl_assert_compare_u (u1, u2, CLAR_COMPARISON_EQ, #u1 " == " #u2, "%"PRIuMAX " != %"PRIuMAX) #define cl_assert_lt_u_(u1, u2, ...) cl_assert_compare_u_(u1, u2, CLAR_COMPARISON_LT, #u1 " < " #u2, __VA_ARGS__) -#define cl_assert_lt_u(u1,u2) cl_assert_lt_u_(u1,u2,"%"PRIuMAX " >= %"PRIuMAX,(uintmax_t)(u1),(uintmax_t)(u2)) +#define cl_assert_lt_u(u1, u2) cl_assert_compare_u (u1, u2, CLAR_COMPARISON_LT, #u1 " < " #u2, "%"PRIuMAX " >= %"PRIuMAX) #define cl_assert_le_u_(u1, u2, ...) cl_assert_compare_u_(u1, u2, CLAR_COMPARISON_LE, #u1 " <= " #u2, __VA_ARGS__) -#define cl_assert_le_u(u1,u2) cl_assert_le_u_(u1,u2,"%"PRIuMAX " > %"PRIuMAX,(uintmax_t)(u1),(uintmax_t)(u2)) +#define cl_assert_le_u(u1, u2) cl_assert_compare_u (u1, u2, CLAR_COMPARISON_LE, #u1 " <= " #u2, "%"PRIuMAX " > %"PRIuMAX) #define cl_assert_gt_u_(u1, u2, ...) cl_assert_compare_u_(u1, u2, CLAR_COMPARISON_GT, #u1 " > " #u2, __VA_ARGS__) -#define cl_assert_gt_u(u1,u2) cl_assert_gt_u_(u1,u2,"%"PRIuMAX " <= %"PRIuMAX,(uintmax_t)(u1),(uintmax_t)(u2)) +#define cl_assert_gt_u(u1, u2) cl_assert_compare_u (u1, u2, CLAR_COMPARISON_GT, #u1 " > " #u2, "%"PRIuMAX " <= %"PRIuMAX) #define cl_assert_ge_u_(u1, u2, ...) cl_assert_compare_u_(u1, u2, CLAR_COMPARISON_GE, #u1 " >= " #u2, __VA_ARGS__) -#define cl_assert_ge_u(u1,u2) cl_assert_ge_u_(u1,u2,"%"PRIuMAX " < %"PRIuMAX,(uintmax_t)(u1),(uintmax_t)(u2)) +#define cl_assert_ge_u(u1, u2) cl_assert_compare_u (u1, u2, CLAR_COMPARISON_GE, #u1 " >= " #u2, "%"PRIuMAX " < %"PRIuMAX) #define cl_assert_equal_b(b1,b2) clar__assert_equal(CLAR_CURRENT_FILE,CLAR_CURRENT_FUNC,CLAR_CURRENT_LINE,#b1 " != " #b2, 1, "%d", (int)((b1) != 0),(int)((b2) != 0))