diff --git a/NEWS b/NEWS index 4f3fc479..c704a45e 100644 --- a/NEWS +++ b/NEWS @@ -1,6 +1,11 @@ In Development: # Mentioning Check 0.14.0 for now, to fix distcheck target until next release +* Define CK_ATTRIBUTE_FORMAT for GCC >= 2.95.3, to make use of + ‘gnu_printf’ format attribute + +* Refactor tests to fix signed - unsigned conversions + Sun Jan 26, 2020: Released Check 0.14.0 based on hash 0076ec62f71d33b5b54530f8471b4c99f50638d7 diff --git a/TODO b/TODO index 7e53b95b..3045d3f6 100644 --- a/TODO +++ b/TODO @@ -59,6 +59,10 @@ Build issues: [ ] * Add option BUILD_DOCUMENTATION to CMake (Github #217). [ ] * Missing function check in CMake creates def HAVE_FOO=0. There should be no HAVE_FOO (Github #195). +[ ] * CMake and Autotools should check if compiler supports __attribute__ ((format (a, b, c))) + to decide if CK_ATTRIBUTE_FORMAT can be defined + https://www.gnu.org/software/autoconf-archive/ax_gcc_func_attribute.html + Check source code: ============ diff --git a/lib/libcompat.h b/lib/libcompat.h index 816c53bf..ea63a5e8 100644 --- a/lib/libcompat.h +++ b/lib/libcompat.h @@ -48,8 +48,10 @@ #if GCC_VERSION_AT_LEAST(2,95,3) #define CK_ATTRIBUTE_UNUSED __attribute__ ((unused)) +#define CK_ATTRIBUTE_FORMAT(a, b, c) __attribute__ ((format (a, b, c))) #else #define CK_ATTRIBUTE_UNUSED +#define CK_ATTRIBUTE_FORMAT(a, b, c) #endif /* GCC 2.95 */ #if GCC_VERSION_AT_LEAST(2,5,0) diff --git a/src/check.c b/src/check.c index 2d4ebb68..f74b3849 100644 --- a/src/check.c +++ b/src/check.c @@ -54,7 +54,7 @@ int check_micro_version = CHECK_MICRO_VERSION; const char* current_test_name = NULL; -static int non_pass(int val); +static int non_pass(enum test_result); static Fixture *fixture_create(SFun fun, int ischecked); static void tcase_add_fixture(TCase * tc, SFun setup, SFun teardown, int ischecked); @@ -512,7 +512,7 @@ TestResult **srunner_results(SRunner * sr) return trarray; } -static int non_pass(int val) +static int non_pass(enum test_result val) { return val != CK_PASS; } diff --git a/src/check.h.in b/src/check.h.in index 2e131d26..fdbc8b05 100644 --- a/src/check.h.in +++ b/src/check.h.in @@ -64,8 +64,10 @@ CK_CPPSTART #if GCC_VERSION_AT_LEAST(2,95,3) #define CK_ATTRIBUTE_UNUSED __attribute__ ((unused)) +#define CK_ATTRIBUTE_FORMAT(a, b, c) __attribute__ ((format (a, b, c))) #else #define CK_ATTRIBUTE_UNUSED +#define CK_ATTRIBUTE_FORMAT(a, b, c) #endif /* GCC 2.95 */ #if GCC_VERSION_AT_LEAST(2,5,0) @@ -499,10 +501,10 @@ static void __testname ## _fn (int _i CK_ATTRIBUTE_UNUSED) #if @HAVE_FORK@ CK_DLL_EXP void CK_EXPORT _ck_assert_failed(const char *file, int line, const char *expr, - ...) CK_ATTRIBUTE_NORETURN; + ...) CK_ATTRIBUTE_NORETURN CK_ATTRIBUTE_FORMAT(gnu_printf, 3, 4); #else CK_DLL_EXP void CK_EXPORT _ck_assert_failed(const char *file, int line, - const char *expr, ...); + const char *expr, ...) CK_ATTRIBUTE_FORMAT(gnu_printf, 3, 4); #endif /** diff --git a/src/check_error.h b/src/check_error.h index c2c8d34e..19580880 100644 --- a/src/check_error.h +++ b/src/check_error.h @@ -31,7 +31,7 @@ extern jmp_buf error_jmp_buffer; /* Print error message and die If fmt ends in colon, include system error information */ void eprintf(const char *fmt, const char *file, int line, - ...) CK_ATTRIBUTE_NORETURN; + ...) CK_ATTRIBUTE_NORETURN CK_ATTRIBUTE_FORMAT(gnu_printf, 1, 4); /* malloc or die */ void *emalloc(size_t n); void *erealloc(void *, size_t n); diff --git a/src/check_str.h b/src/check_str.h index b26eae2b..92697f28 100644 --- a/src/check_str.h +++ b/src/check_str.h @@ -21,6 +21,8 @@ #ifndef CHECK_STR_H #define CHECK_STR_H +#include "../lib/libcompat.h" + /* Return a string representation of the given TestResult. Return value has been malloc'd, and must be freed by the caller */ char *tr_str(TestResult * tr); @@ -37,6 +39,6 @@ char *tr_short_str(TestResult * tr); */ char *sr_stat_str(SRunner * sr); -char *ck_strdup_printf(const char *fmt, ...); +char *ck_strdup_printf(const char *fmt, ...) CK_ATTRIBUTE_FORMAT(gnu_printf, 1, 2); #endif /* CHECK_STR_H */ diff --git a/tests/check_check.h b/tests/check_check.h index 32e49bc6..d828ee01 100644 --- a/tests/check_check.h +++ b/tests/check_check.h @@ -96,6 +96,6 @@ void record_failure_line_num(const int line); * * If there are no more lines to read, -1 is returned. */ -int get_next_failure_line_num(FILE * file); +long get_next_failure_line_num(FILE * file); #endif /* CHECK_CHECK_H */ diff --git a/tests/check_check_master.c b/tests/check_check_master.c index a606708a..aaf45f3f 100644 --- a/tests/check_check_master.c +++ b/tests/check_check_master.c @@ -561,7 +561,7 @@ END_TEST START_TEST(test_check_failure_lnos) { int i; - int line_no; + long line_no; int passed = 0; int number_failed; TestResult *tr; @@ -652,10 +652,6 @@ END_TEST START_TEST(test_check_test_names) { int i; - int line_no; - int passed = 0; - int number_failed; - TestResult *tr; rewind(test_names_file); @@ -936,9 +932,9 @@ char* get_next_test_name(FILE * file) void record_failure_line_num(int linenum) { - int to_write; - ssize_t written; - int result; + size_t to_write; + size_t written; + int result, chars_printed; char string[16]; /* @@ -947,12 +943,13 @@ void record_failure_line_num(int linenum) */ linenum += 1; - to_write = snprintf(string, sizeof(string), "%d\n", linenum); - if(to_write <= 0) + chars_printed = snprintf(string, sizeof(string), "%d\n", linenum); + if(chars_printed <= 0 || (size_t) chars_printed >= sizeof(string)) { fprintf(stderr, "%s:%d: Error in call to snprintf:", __FILE__, __LINE__); exit(1); } + to_write = (size_t) chars_printed; if(line_num_failures == NULL) { @@ -969,7 +966,7 @@ void record_failure_line_num(int linenum) written = fwrite(string, 1, to_write, line_num_failures); if(written != to_write) { - fprintf(stderr, "%s:%d: Error in call to fwrite, wrote %zd instead of %d:", __FILE__, __LINE__, written, to_write); + fprintf(stderr, "%s:%d: Error in call to fwrite, wrote %zd instead of %zu:", __FILE__, __LINE__, written, to_write); exit(1); } @@ -981,13 +978,13 @@ void record_failure_line_num(int linenum) } } -int get_next_failure_line_num(FILE * file) +long get_next_failure_line_num(FILE * file) { char * line = NULL; char * end = NULL; size_t length; ssize_t written; - int value = -1; + long value = -1; written = getline(&line, &length, file); diff --git a/tests/check_check_sub.c b/tests/check_check_sub.c index ddfea1d2..184a3bf7 100644 --- a/tests/check_check_sub.c +++ b/tests/check_check_sub.c @@ -1092,7 +1092,7 @@ END_TEST START_TEST(test_ck_assert_double_eq_with_promotion) { - float x = 0.1; + float x = 0.1F; double y = x; record_test_name(tcase_name()); @@ -1103,7 +1103,7 @@ END_TEST START_TEST(test_ck_assert_double_eq_with_conv) { - float x = 0.1; + float x = 0.1F; record_test_name(tcase_name()); @@ -1608,7 +1608,7 @@ END_TEST START_TEST(test_ck_assert_ldouble_eq_with_promotion) { - float x = 1.1; + float x = 1.1F; long double y = x; record_test_name(tcase_name()); @@ -1619,7 +1619,7 @@ END_TEST START_TEST(test_ck_assert_ldouble_eq_with_conv) { - float x = 1.1; + float x = 1.1F; long double y = x; record_test_name(tcase_name()); diff --git a/tests/check_check_tags.c b/tests/check_check_tags.c index e4f485ab..7c77e302 100644 --- a/tests/check_check_tags.c +++ b/tests/check_check_tags.c @@ -658,7 +658,7 @@ START_TEST(include_w_spaces) Suite *make_tag_suite(void) { - TCase *set_get_tags, *no_filters; + TCase *no_filters; TCase *include_filters, *exclude_filters; #if HAVE_DECL_SETENV TCase *include_filters_env, *exclude_filters_env; diff --git a/tests/check_set_max_msg_size.c b/tests/check_set_max_msg_size.c index 92a3bab5..d7c91bd6 100644 --- a/tests/check_set_max_msg_size.c +++ b/tests/check_set_max_msg_size.c @@ -52,7 +52,6 @@ static Suite *make_set_max_msg_size_suite(void) int main (int argc, char *argv[]) { - int n; SRunner *sr; if (argc != 2) { @@ -64,8 +63,8 @@ int main (int argc, char *argv[]) * Run the test suite. This is intended to trigger the "Message is too long" error. * Actual success/failure is determined by examining the output. */ - check_set_max_msg_size(32); /* 1st call has no effect since */ - check_set_max_msg_size(atoi(argv[1])); /* the 2nd call will override it. */ + check_set_max_msg_size(32); /* 1st call has no effect since */ + check_set_max_msg_size(strtoul(argv[1], NULL, 10)); /* the 2nd call will override it. */ sr = srunner_create(make_set_max_msg_size_suite()); srunner_run_all(sr, CK_NORMAL); srunner_free(sr);