From: Andreas Schneider Date: Wed, 15 Oct 2025 09:39:42 +0000 (+0200) Subject: third_party: Update cmocka to version 1.1.8 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=93d21dc7e961f1eaa8aa0075c53b2b1134955780;p=thirdparty%2Fsamba.git third_party: Update cmocka to version 1.1.8 Signed-off-by: Andreas Schneider Reviewed-by: Anoop C S Autobuild-User(master): Anoop C S Autobuild-Date(master): Fri Oct 17 12:16:23 UTC 2025 on atb-devel-224 --- diff --git a/buildtools/wafsamba/samba_third_party.py b/buildtools/wafsamba/samba_third_party.py index 8f0c56dec79..425c4545709 100644 --- a/buildtools/wafsamba/samba_third_party.py +++ b/buildtools/wafsamba/samba_third_party.py @@ -18,7 +18,7 @@ Build.BuildContext.CHECK_POPT = CHECK_POPT @conf def CHECK_CMOCKA(conf): - return conf.CHECK_BUNDLED_SYSTEM_PKG('cmocka', minversion='1.1.3') + return conf.CHECK_BUNDLED_SYSTEM_PKG('cmocka', minversion='1.1.8') Build.BuildContext.CHECK_CMOCKA = CHECK_CMOCKA diff --git a/third_party/cmocka/cmocka.c b/third_party/cmocka/cmocka.c index b21fe15536c..1ea32ebc6bf 100644 --- a/third_party/cmocka/cmocka.c +++ b/third_party/cmocka/cmocka.c @@ -42,7 +42,11 @@ #include #include #include +#include #include +#include +#include +#include /* * This allows to add a platform specific header file. Some embedded platforms @@ -69,7 +73,9 @@ #define MALLOC_ALLOC_PATTERN 0xBA #define MALLOC_FREE_PATTERN 0xCD /* Alignment of allocated blocks. NOTE: This must be base2. */ +#ifndef MALLOC_ALIGNMENT #define MALLOC_ALIGNMENT sizeof(size_t) +#endif /* Printf formatting for source code locations. */ #define SOURCE_LOCATION_FORMAT "%s:%u" @@ -107,37 +113,17 @@ /* - * Declare and initialize the pointer member of ValuePointer variable name - * with ptr. + * Declare and initialize a LargestIntegralType variable name + * with value the conversion of ptr. */ #define declare_initialize_value_pointer_pointer(name, ptr) \ - ValuePointer name ; \ - name.value = 0; \ - name.x.pointer = (void*)(ptr) - -/* - * Declare and initialize the value member of ValuePointer variable name - * with val. - */ -#define declare_initialize_value_pointer_value(name, val) \ - ValuePointer name ; \ - name.value = val + LargestIntegralType name ; \ + name = (LargestIntegralType) (uintptr_t) ptr -/* Cast a LargestIntegralType to pointer_type via a ValuePointer. */ +/* Cast a LargestIntegralType to pointer_type. */ #define cast_largest_integral_type_to_pointer( \ pointer_type, largest_integral_type) \ - ((pointer_type)((ValuePointer*)&(largest_integral_type))->x.pointer) - -/* Used to cast LargetIntegralType to void* and vice versa. */ -typedef union ValuePointer { - LargestIntegralType value; - struct { -#if defined(WORDS_BIGENDIAN) && (WORDS_SIZEOF_VOID_P == 4) - unsigned int padding; -#endif - void *pointer; - } x; -} ValuePointer; + ((pointer_type)(uintptr_t)(largest_integral_type)) /* Doubly linked list node. */ typedef struct ListNode { @@ -272,8 +258,6 @@ static enum cm_message_output cm_get_output(void); static int cm_error_message_enabled = 1; static CMOCKA_THREAD char *cm_error_message; -void cm_print_error(const char * const format, ...) CMOCKA_PRINTF_ATTRIBUTE(1, 2); - /* * Keeps track of the calling context returned by setenv() so that the fail() * method can jump out of a test. @@ -312,6 +296,8 @@ static enum cm_message_output global_msg_output = CM_OUTPUT_STDOUT; static const char *global_test_filter_pattern; +static const char *global_skip_filter_pattern; + #ifndef _WIN32 /* Signals caught by exception_handler(). */ static const int exception_signals[] = { @@ -411,6 +397,9 @@ void _skip(const char * const file, const int line) cm_print_error(SOURCE_LOCATION_FORMAT ": Skipped!\n", file, line); global_skip_test = 1; exit_test(1); + + /* Unreachable */ + exit(-1); } /* Initialize a SourceLocation structure. */ @@ -446,32 +435,41 @@ static int c_strreplace(char *src, { char *p = NULL; + // Terminate if there is no valid data + if (src == NULL || src_len == 0 || pattern == NULL || repl == NULL) { + errno = EINVAL; + return -1; + } + p = strstr(src, pattern); + /* There is nothing to replace */ if (p == NULL) { - return -1; + return 0; } + const size_t pattern_len = strlen(pattern); + const size_t repl_len = strlen(repl); do { - size_t of = p - src; + size_t offset = p - src; size_t l = strlen(src); - size_t pl = strlen(pattern); - size_t rl = strlen(repl); /* overflow check */ - if (src_len <= l + MAX(pl, rl) + 1) { + if (src_len <= l + MAX(pattern_len, repl_len) + 1) { return -1; } - if (rl != pl) { - memmove(src + of + rl, src + of + pl, l - of - pl + 1); + if (repl_len != pattern_len) { + memmove(src + offset + repl_len, + src + offset + pattern_len, + l - offset - pattern_len + 1); } - memcpy(src + of, repl, rl); + memcpy(src + offset, repl, repl_len); if (str_replaced != NULL) { *str_replaced = 1; } - p = strstr(src, pattern); + p = strstr(src + offset + repl_len, pattern); } while (p != NULL); return 0; @@ -567,7 +565,7 @@ static void fail_if_leftover_values(const char *test_name) { remove_always_return_values_from_list(&global_call_ordering_head); if (check_for_leftover_values_list(&global_call_ordering_head, - "%s function was expected to be called but was not not.\n")) { + "%s function was expected to be called but was not.\n")) { error_occurred = 1; } if (error_occurred) { @@ -717,9 +715,16 @@ static void free_symbol_map_value(const void *value, SymbolMapValue * const map_value = (SymbolMapValue*)value; const LargestIntegralType children = cast_ptr_to_largest_integral_type(cleanup_value_data); assert_non_null(value); - list_free(&map_value->symbol_values_list_head, - children ? free_symbol_map_value : free_value, - (void *) ((uintptr_t)children - 1)); + if (children == 0) { + list_free(&map_value->symbol_values_list_head, + free_value, + NULL); + } else { + list_free(&map_value->symbol_values_list_head, + free_symbol_map_value, + (void *)((uintptr_t)children - 1)); + } + free(map_value); } @@ -898,7 +903,7 @@ static size_t check_for_leftover_values_list(const ListNode * head, child_node = child_node->next, ++leftover_count) { const FuncOrderingValue *const o = (const FuncOrderingValue*) child_node->value; - cm_print_error(error_message, o->function); + cm_print_error("%s: %s", error_message, o->function); cm_print_error(SOURCE_LOCATION_FORMAT ": note: remaining item was declared here\n", o->location.file, o->location.line); @@ -930,7 +935,7 @@ static size_t check_for_leftover_values( if (!list_empty(child_list)) { if (number_of_symbol_names == 1) { const ListNode *child_node; - cm_print_error(error_message, value->symbol_name); + cm_print_error("%s: %s", error_message, value->symbol_name); for (child_node = child_list->next; child_node != child_list; child_node = child_node->next) { @@ -1122,6 +1127,129 @@ void _expect_function_call( list_add_value(&global_call_ordering_head, ordering, count); } +/* Returns 1 if the specified float values are equal, else returns 0. */ +static int float_compare(const float left, + const float right, + const float epsilon) { + float absLeft; + float absRight; + float largest; + float relDiff; + + float diff = left - right; + diff = (diff >= 0.f) ? diff : -diff; + + // Check if the numbers are really close -- needed + // when comparing numbers near zero. + if (diff <= epsilon) { + return 1; + } + + absLeft = (left >= 0.f) ? left : -left; + absRight = (right >= 0.f) ? right : -right; + + largest = (absRight > absLeft) ? absRight : absLeft; + relDiff = largest * FLT_EPSILON; + + if (diff > relDiff) { + return 0; + } + return 1; +} + +/* Returns 1 if the specified float values are equal. If the values are not equal + * an error is displayed and 0 is returned. */ +static int float_values_equal_display_error(const float left, + const float right, + const float epsilon) { + const int equal = float_compare(left, right, epsilon); + if (!equal) { + cm_print_error(FloatPrintfFormat " != " + FloatPrintfFormat "\n", left, right); + } + return equal; +} + +/* Returns 1 if the specified float values are different. If the values are equal + * an error is displayed and 0 is returned. */ +static int float_values_not_equal_display_error(const float left, + const float right, + const float epsilon) { + const int not_equal = (float_compare(left, right, epsilon) == 0); + if (!not_equal) { + cm_print_error(FloatPrintfFormat " == " + FloatPrintfFormat "\n", left, right); + } + return not_equal; +} + +/* Returns 1 if the specified double values are equal, else returns 0. */ +static int double_compare(const double left, + const double right, + const double epsilon) { + double absLeft; + double absRight; + double largest; + double relDiff; + + double diff = left - right; + diff = (diff >= 0.f) ? diff : -diff; + + /* + * Check if the numbers are really close -- needed + * when comparing numbers near zero. + */ + if (diff <= epsilon) { + return 1; + } + + absLeft = (left >= 0.f) ? left : -left; + absRight = (right >= 0.f) ? right : -right; + + largest = (absRight > absLeft) ? absRight : absLeft; + relDiff = largest * FLT_EPSILON; + + if (diff > relDiff) { + return 0; + } + + return 1; +} + +/* + * Returns 1 if the specified double values are equal. If the values are not + * equal an error is displayed and 0 is returned. + */ +static int double_values_equal_display_error(const double left, + const double right, + const double epsilon) { + const int equal = double_compare(left, right, epsilon); + + if (!equal) { + cm_print_error(DoublePrintfFormat " != " + DoublePrintfFormat "\n", left, right); + } + + return equal; +} + +/* + * Returns 1 if the specified double values are different. If the values are + * equal an error is displayed and 0 is returned. + */ +static int double_values_not_equal_display_error(const double left, + const double right, + const double epsilon) { + const int not_equal = (double_compare(left, right, epsilon) == 0); + + if (!not_equal) { + cm_print_error(DoublePrintfFormat " == " + DoublePrintfFormat "\n", left, right); + } + + return not_equal; +} + /* Returns 1 if the specified values are equal. If the values are not equal * an error is displayed and 0 is returned. */ static int values_equal_display_error(const LargestIntegralType left, @@ -1266,11 +1394,11 @@ static int memory_equal_display_error(const char* const a, const char* const b, size_t differences = 0; size_t i; for (i = 0; i < size; i++) { - const char l = a[i]; - const char r = b[i]; + const unsigned char l = a[i]; + const unsigned char r = b[i]; if (l != r) { if (differences < 16) { - cm_print_error("difference at offset %" PRIdS " 0x%02x 0x%02x\n", + cm_print_error("difference at offset %" PRIdS " 0x%02hhx 0x%02hhx\n", i, l, r); } differences ++; @@ -1351,7 +1479,7 @@ static void expect_set( check_integer_set->size_of_set = number_of_values; _expect_check( function, parameter, file, line, check_function, - check_data.value, &check_integer_set->event, count); + check_data, &check_integer_set->event, count); } @@ -1414,7 +1542,7 @@ static void expect_range( check_integer_range->minimum = minimum; check_integer_range->maximum = maximum; _expect_check(function, parameter, file, line, check_function, - check_data.value, &check_integer_range->event, count); + check_data, &check_integer_range->event, count); } @@ -1493,7 +1621,7 @@ void _expect_string( declare_initialize_value_pointer_pointer(string_pointer, discard_const(string)); _expect_check(function, parameter, file, line, check_string, - string_pointer.value, NULL, count); + string_pointer, NULL, count); } @@ -1515,7 +1643,7 @@ void _expect_not_string( declare_initialize_value_pointer_pointer(string_pointer, discard_const(string)); _expect_check(function, parameter, file, line, check_not_string, - string_pointer.value, NULL, count); + string_pointer, NULL, count); } /* CheckParameterValue callback to check whether a parameter equals an area of @@ -1548,7 +1676,7 @@ static void expect_memory_setup( check_data->memory = mem; check_data->size = size; _expect_check(function, parameter, file, line, check_function, - check_data_pointer.value, &check_data->event, count); + check_data_pointer, &check_data->event, count); } @@ -1714,6 +1842,46 @@ void _assert_return_code(const LargestIntegralType result, } } +void _assert_float_equal(const float a, + const float b, + const float epsilon, + const char * const file, + const int line) { + if (!float_values_equal_display_error(a, b, epsilon)) { + _fail(file, line); + } +} + +void _assert_float_not_equal(const float a, + const float b, + const float epsilon, + const char * const file, + const int line) { + if (!float_values_not_equal_display_error(a, b, epsilon)) { + _fail(file, line); + } +} + +void _assert_double_equal(const double a, + const double b, + const double epsilon, + const char * const file, + const int line) { + if (!double_values_equal_display_error(a, b, epsilon)) { + _fail(file, line); + } +} + +void _assert_double_not_equal(const double a, + const double b, + const double epsilon, + const char * const file, + const int line) { + if (!double_values_not_equal_display_error(a, b, epsilon)) { + _fail(file, line); + } +} + void _assert_int_equal( const LargestIntegralType a, const LargestIntegralType b, const char * const file, const int line) { @@ -1820,11 +1988,11 @@ static ListNode* get_allocated_blocks_list(void) { return &global_allocated_blocks; } -static void *libc_malloc(size_t size) +static void *libc_calloc(size_t nmemb, size_t size) { -#undef malloc - return malloc(size); -#define malloc test_malloc +#undef calloc + return calloc(nmemb, size); +#define calloc test_calloc } static void libc_free(void *ptr) @@ -1864,7 +2032,7 @@ static void vcm_print_error(const char* const format, va_list args) if (cm_error_message == NULL) { /* CREATE MESSAGE */ - cm_error_message = libc_malloc(len + 1); + cm_error_message = libc_calloc(1, len + 1); if (cm_error_message == NULL) { /* TODO */ goto end; @@ -1938,12 +2106,20 @@ void* _test_malloc(const size_t size, const char* file, const int line) { void* _test_calloc(const size_t number_of_elements, const size_t size, const char* file, const int line) { - void* const ptr = _test_malloc(number_of_elements * size, file, line); + void *ptr = NULL; + + if (size > 0 && number_of_elements > SIZE_MAX / size) { + errno = ENOMEM; + return NULL; + } + + ptr = _test_malloc(number_of_elements * size, file, line); if (ptr) { memset(ptr, 0, number_of_elements * size); } return ptr; } +#define calloc test_calloc /* Use the real free in this function. */ @@ -2114,11 +2290,14 @@ void _fail(const char * const file, const int line) { break; } exit_test(1); + + /* Unreachable */ + exit(-1); } #ifndef _WIN32 -static void exception_handler(int sig) { +CMOCKA_NORETURN static void exception_handler(int sig) { const char *sig_strerror = ""; #ifdef HAVE_STRSIGNAL @@ -2128,6 +2307,9 @@ static void exception_handler(int sig) { cm_print_error("Test failed with exception: %s(%d)", sig_strerror, sig); exit_test(1); + + /* Unreachable */ + exit(-1); } #else /* _WIN32 */ @@ -2180,8 +2362,10 @@ void cm_print_error(const char * const format, ...) } /* Standard output and error print methods. */ -void vprint_message(const char* const format, va_list args) { - char buffer[1024]; +void vprint_message(const char* const format, va_list args) +{ + char buffer[4096]; + vsnprintf(buffer, sizeof(buffer), format, args); printf("%s", buffer); fflush(stdout); @@ -2191,8 +2375,10 @@ void vprint_message(const char* const format, va_list args) { } -void vprint_error(const char* const format, va_list args) { - char buffer[1024]; +void vprint_error(const char* const format, va_list args) +{ + char buffer[4096]; + vsnprintf(buffer, sizeof(buffer), format, args); fprintf(stderr, "%s", buffer); fflush(stderr); @@ -2250,6 +2436,16 @@ enum cm_printf_type { static int xml_printed; static int file_append; +static void cmprepare_xml_attribute_string(char *buf, size_t buf_len, const char *src) +{ + snprintf(buf, buf_len, "%s", src); + c_strreplace(buf, buf_len, "&", "&", NULL); + c_strreplace(buf, buf_len, "\"", """, NULL); + c_strreplace(buf, buf_len, "\'", "'", NULL); + c_strreplace(buf, buf_len, "<", "<", NULL); + c_strreplace(buf, buf_len, ">", ">", NULL); +} + static void cmprintf_group_finish_xml(const char *group_name, size_t total_executed, size_t total_failed, @@ -2308,10 +2504,15 @@ static void cmprintf_group_finish_xml(const char *group_name, } } + char group_name_escaped[1024]; + cmprepare_xml_attribute_string(group_name_escaped, + sizeof(group_name_escaped), + group_name); + fprintf(fp, "\n"); fprintf(fp, " \n", - group_name, + group_name_escaped, total_runtime, /* seconds */ (unsigned)total_executed, (unsigned)total_failed, @@ -2321,8 +2522,14 @@ static void cmprintf_group_finish_xml(const char *group_name, for (i = 0; i < total_executed; i++) { struct CMUnitTestState *cmtest = &cm_tests[i]; + /* Escape double quotes and remove spaces in test name */ + char test_name_escaped[1024]; + cmprepare_xml_attribute_string(test_name_escaped, + sizeof(test_name_escaped), + cmtest->test->name); + fprintf(fp, " \n", - cmtest->test->name, cmtest->runtime); + test_name_escaped, cmtest->runtime); switch (cmtest->status) { case CM_TEST_ERROR: @@ -2354,13 +2561,16 @@ static void cmprintf_group_finish_xml(const char *group_name, } } -static void cmprintf_group_start_standard(const size_t num_tests) +static void cmprintf_group_start_standard(const char *group_name, + const size_t num_tests) { - print_message("[==========] Running %u test(s).\n", - (unsigned)num_tests); + print_message("[==========] %s: Running %zu test(s).\n", + group_name, + num_tests); } -static void cmprintf_group_finish_standard(size_t total_executed, +static void cmprintf_group_finish_standard(const char *group_name, + size_t total_executed, size_t total_passed, size_t total_failed, size_t total_errors, @@ -2369,12 +2579,16 @@ static void cmprintf_group_finish_standard(size_t total_executed, { size_t i; - print_message("[==========] %u test(s) run.\n", (unsigned)total_executed); + print_message("[==========] %s: %zu test(s) run.\n", + group_name, + total_executed); print_error("[ PASSED ] %u test(s).\n", (unsigned)(total_passed)); if (total_skipped) { - print_error("[ SKIPPED ] %"PRIdS " test(s), listed below:\n", total_skipped); + print_error("[ SKIPPED ] %s: %zu test(s), listed below:\n", + group_name, + total_skipped); for (i = 0; i < total_executed; i++) { struct CMUnitTestState *cmtest = &cm_tests[i]; @@ -2382,11 +2596,13 @@ static void cmprintf_group_finish_standard(size_t total_executed, print_error("[ SKIPPED ] %s\n", cmtest->test->name); } } - print_error("\n %u SKIPPED TEST(S)\n", (unsigned)(total_skipped)); + print_error("\n %zu SKIPPED TEST(S)\n", total_skipped); } if (total_failed) { - print_error("[ FAILED ] %"PRIdS " test(s), listed below:\n", total_failed); + print_error("[ FAILED ] %s: %zu test(s), listed below:\n", + group_name, + total_failed); for (i = 0; i < total_executed; i++) { struct CMUnitTestState *cmtest = &cm_tests[i]; @@ -2394,8 +2610,8 @@ static void cmprintf_group_finish_standard(size_t total_executed, print_error("[ FAILED ] %s\n", cmtest->test->name); } } - print_error("\n %u FAILED TEST(S)\n", - (unsigned)(total_failed + total_errors)); + print_error("\n %zu FAILED TEST(S)\n", + (total_failed + total_errors)); } } @@ -2430,6 +2646,12 @@ static void cmprintf_standard(enum cm_printf_type type, static void cmprintf_group_start_tap(const size_t num_tests) { + static bool version_printed = false; + if (!version_printed) { + print_message("TAP version 13\n"); + version_printed = true; + } + print_message("1..%u\n", (unsigned)num_tests); } @@ -2446,7 +2668,7 @@ static void cmprintf_group_finish_tap(const char *group_name, } static void cmprintf_tap(enum cm_printf_type type, - uint32_t test_number, + size_t test_number, const char *test_name, const char *error_message) { @@ -2487,7 +2709,7 @@ static void cmprintf_tap(enum cm_printf_type type, } break; case PRINTF_TEST_SKIPPED: - print_message("not ok %u # SKIP %s\n", (unsigned)test_number, test_name); + print_message("ok %u # SKIP %s\n", (unsigned)test_number, test_name); break; case PRINTF_TEST_ERROR: print_message("not ok %u - %s %s\n", @@ -2522,7 +2744,8 @@ static void cmprintf_subunit(enum cm_printf_type type, } } -static void cmprintf_group_start(const size_t num_tests) +static void cmprintf_group_start(const char *group_name, + const size_t num_tests) { enum cm_message_output output; @@ -2530,7 +2753,7 @@ static void cmprintf_group_start(const size_t num_tests) switch (output) { case CM_OUTPUT_STDOUT: - cmprintf_group_start_standard(num_tests); + cmprintf_group_start_standard(group_name, num_tests); break; case CM_OUTPUT_SUBUNIT: break; @@ -2557,17 +2780,21 @@ static void cmprintf_group_finish(const char *group_name, switch (output) { case CM_OUTPUT_STDOUT: - cmprintf_group_finish_standard(total_executed, - total_passed, - total_failed, - total_errors, - total_skipped, - cm_tests); + cmprintf_group_finish_standard(group_name, + total_executed, + total_passed, + total_failed, + total_errors, + total_skipped, + cm_tests); break; case CM_OUTPUT_SUBUNIT: break; case CM_OUTPUT_TAP: - cmprintf_group_finish_tap(group_name, total_executed, total_passed, total_skipped); + cmprintf_group_finish_tap(group_name, + total_executed, + total_passed, + total_skipped); break; case CM_OUTPUT_XML: cmprintf_group_finish_xml(group_name, @@ -2615,6 +2842,11 @@ void cmocka_set_test_filter(const char *pattern) global_test_filter_pattern = pattern; } +void cmocka_set_skip_filter(const char *pattern) +{ + global_skip_filter_pattern = pattern; +} + /**************************************************************************** * TIME CALCULATIONS ****************************************************************************/ @@ -2658,7 +2890,7 @@ static double cm_secdiff(struct timespec clock1, struct timespec clock0) diff = cm_tspecdiff(clock1, clock0); - ret = diff.tv_sec; + ret = (double) diff.tv_sec; ret += (double) diff.tv_nsec / (double) 1E9; return ret; @@ -2889,7 +3121,7 @@ int _cmocka_run_group_tests(const char *group_name, /* Make sure LargestIntegralType is at least the size of a pointer. */ assert_true(sizeof(LargestIntegralType) >= sizeof(void*)); - cm_tests = (struct CMUnitTestState *)libc_malloc(sizeof(struct CMUnitTestState) * num_tests); + cm_tests = libc_calloc(1, sizeof(struct CMUnitTestState) * num_tests); if (cm_tests == NULL) { return -1; } @@ -2901,10 +3133,18 @@ int _cmocka_run_group_tests(const char *group_name, || tests[i].setup_func != NULL || tests[i].teardown_func != NULL)) { if (global_test_filter_pattern != NULL) { - int ok; + int match; + + match = c_strmatch(tests[i].name, global_test_filter_pattern); + if (!match) { + continue; + } + } + if (global_skip_filter_pattern != NULL) { + int match; - ok = c_strmatch(tests[i].name, global_test_filter_pattern); - if (!ok) { + match = c_strmatch(tests[i].name, global_skip_filter_pattern); + if (match) { continue; } } @@ -2917,7 +3157,7 @@ int _cmocka_run_group_tests(const char *group_name, } } - cmprintf_group_start(total_tests); + cmprintf_group_start(group_name, total_tests); rc = 0; @@ -3036,7 +3276,7 @@ int _cmocka_run_group_tests(const char *group_name, libc_free(cm_tests); fail_if_blocks_allocated(group_check_point, "cmocka_group_tests"); - return total_failed + total_errors; + return (int)(total_failed + total_errors); } /**************************************************************************** @@ -3278,7 +3518,7 @@ int _run_tests(const UnitTest * const tests, const size_t number_of_tests) { int _run_group_tests(const UnitTest * const tests, const size_t number_of_tests) { UnitTestFunction setup = NULL; - const char *setup_name; + const char *setup_name = NULL; size_t num_setups = 0; UnitTestFunction teardown = NULL; const char *teardown_name = NULL; diff --git a/third_party/cmocka/cmocka.h b/third_party/cmocka/cmocka.h index e6861c83d27..c5872fe3437 100644 --- a/third_party/cmocka/cmocka.h +++ b/third_party/cmocka/cmocka.h @@ -1,6 +1,6 @@ /* * Copyright 2008 Google Inc. - * Copyright 2014-2018 Andreas Schneider + * Copyright 2014-2022 Andreas Schneider * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -41,11 +41,13 @@ int __stdcall IsDebuggerPresent(); /** * @defgroup cmocka The CMocka API * - * These headers or their equivalents should be included prior to including + * These headers or their equivalents MUST be included prior to including * this header file. * @code * #include + * #include * #include + * #include * #include * @endcode * @@ -106,17 +108,25 @@ typedef uintmax_t LargestIntegralType; # endif /* _WIN32 */ #endif /* LargestIntegralTypePrintfFormat */ +#ifndef FloatPrintfFormat +# define FloatPrintfFormat "%f" +#endif /* FloatPrintfFormat */ + +#ifndef DoublePrintfFormat +# define DoublePrintfFormat "%f" +#endif /* DoublePrintfFormat */ + /* Perform an unsigned cast to LargestIntegralType. */ #define cast_to_largest_integral_type(value) \ ((LargestIntegralType)(value)) /* Smallest integral type capable of holding a pointer. */ -#if !defined(_UINTPTR_T) && !defined(_UINTPTR_T_DEFINED) +#if !defined(_UINTPTR_T) && !defined(_UINTPTR_T_DEFINED) && !defined(HAVE_UINTPTR_T) && !defined(__UINTPTR_TYPE__) # if defined(_WIN32) /* WIN32 is an ILP32 platform */ typedef unsigned int uintptr_t; # elif defined(_WIN64) - typedef unsigned long int uintptr_t + typedef unsigned long int uintptr_t; # else /* _WIN32 */ /* ILP32 and LP64 platforms */ @@ -163,6 +173,14 @@ cast_to_largest_integral_type(cast_to_pointer_integral_type(value)) #define CMOCKA_DEPRECATED #endif +#if defined(__GNUC__) +#define CMOCKA_NORETURN __attribute__ ((noreturn)) +#elif defined(_MSC_VER) +#define CMOCKA_NORETURN __declspec(noreturn) +#else +#define CMOCKA_NORETURN +#endif + #define WILL_RETURN_ALWAYS -1 #define WILL_RETURN_ONCE -2 @@ -170,7 +188,7 @@ cast_to_largest_integral_type(cast_to_pointer_integral_type(value)) * @defgroup cmocka_mock Mock Objects * @ingroup cmocka * - * Mock objects mock objects are simulated objects that mimic the behavior of + * Mock objects are simulated objects that mimic the behavior of * real objects. Instead of calling the real objects, the tested object calls a * mock object that merely asserts that the correct methods were called, with * the expected parameters, in the correct order. @@ -208,8 +226,8 @@ cast_to_largest_integral_type(cast_to_pointer_integral_type(value)) * } * @endcode * - * For a complete example please at a look - * here. + * For a complete example please take a look + * here. * * @{ */ @@ -425,8 +443,8 @@ void will_return_maybe(#function, LargestIntegralType value); * } * @endcode * - * For a complete example please at a look at - * here + * For a complete example please take a look + * here * * @{ */ @@ -662,7 +680,7 @@ void expect_not_in_range_count(#function, #parameter, LargestIntegralType minimu #ifdef DOXYGEN /** - * @brief Add an event to check if a parameter is the given value. + * @brief Add an event to check if a parameter is the given integer based value. * * The event is triggered by calling check_expected() in the mocked function. * @@ -672,7 +690,10 @@ void expect_not_in_range_count(#function, #parameter, LargestIntegralType minimu * * @param[in] value The value to check. * - * @see check_expected(). + * @see check_expected() + * @see expect_string() + * @see expect_memory() + * @see expect_any() */ void expect_value(#function, #parameter, LargestIntegralType value); #else @@ -682,7 +703,8 @@ void expect_value(#function, #parameter, LargestIntegralType value); #ifdef DOXYGEN /** - * @brief Add an event to repeatedly check if a parameter is the given value. + * @brief Add an event to repeatedly check if a parameter is the given integer + * based value. * * The event is triggered by calling check_expected() in the mocked function. * @@ -697,6 +719,8 @@ void expect_value(#function, #parameter, LargestIntegralType value); * to -1 the value will always be returned. * * @see check_expected(). + * @see expect_not_string() + * @see expect_not_memory() */ void expect_value_count(#function, #parameter, LargestIntegralType value, size_t count); #else @@ -964,6 +988,24 @@ void expect_any(#function, #parameter); expect_any_count(function, parameter, 1) #endif +#ifdef DOXYGEN +/** + * @brief Add an event to always check if a parameter (of any value) has been passed. + * + * The event is triggered by calling check_expected() in the mocked function. + * + * @param[in] #function The function to add the check for. + * + * @param[in] #parameter The name of the parameter passed to the function. + * + * @see check_expected(). + */ +void expect_any_always(#function, #parameter); +#else +#define expect_any_always(function, parameter) \ + expect_any_count(function, parameter, WILL_RETURN_ALWAYS) +#endif + #ifdef DOXYGEN /** * @brief Add an event to repeatedly check if a parameter (of any value) has @@ -1215,6 +1257,95 @@ void assert_int_not_equal(int a, int b); __FILE__, __LINE__) #endif +#ifdef DOXYGEN +/** + * @brief Assert that the two given float are equal given an epsilon. + * + * The function prints an error message to standard error and terminates the + * test by calling fail() if the float are not equal (given an epsilon). + * + * @param[in] a The first float to compare. + * + * @param[in] b The float to compare against the first one. + * + * @param[in] epsilon The epsilon used as margin for float comparison. + */ +void assert_float_equal(float a, float b, float epsilon); +#else +#define assert_float_equal(a, b, epsilon) \ + _assert_float_equal((float)a, \ + (float)b, \ + (float)epsilon, \ + __FILE__, __LINE__) +#endif + +#ifdef DOXYGEN +/** + * @brief Assert that the two given float are not equal given an epsilon. + * + * The function prints an error message to standard error and terminates the + * test by calling fail() if the float are not equal (given an epsilon). + * + * @param[in] a The first float to compare. + * + * @param[in] b The float to compare against the first one. + * + * @param[in] epsilon The epsilon used as margin for float comparison. + */ +void assert_float_not_equal(float a, float b, float epsilon); +#else +#define assert_float_not_equal(a, b, epsilon) \ + _assert_float_not_equal((float)a, \ + (float)b, \ + (float)epsilon, \ + __FILE__, __LINE__) +#endif + +#ifdef DOXYGEN +/** + * @brief Assert that the two given double are equal given an epsilon. + * + * The function prints an error message to standard error and terminates the + * test by calling fail() if the double are not equal (given an epsilon). + * + * @param[in] a The first double to compare. + * + * @param[in] b The double to compare against the first one. + * + * @param[in] epsilon The epsilon used as margin for double comparison. + */ +void assert_double_equal(double a, double b, double epsilon); +#else +#define assert_double_equal(a, b, epsilon) \ + _assert_double_equal((double)a, \ + (double)b, \ + (double)epsilon, \ + __FILE__, __LINE__) +#endif + +#ifdef DOXYGEN +/** + * @brief Assert that the two given double are not equal given an epsilon. + * + * The function prints an error message to standard error and terminates the + * test by calling fail() if the double are not equal (given an epsilon). + * + * @param[in] a The first double to compare. + * + * @param[in] b The double to compare against the first one. + * + * @param[in] epsilon The epsilon used as margin for double comparison. + */ +void assert_double_not_equal(double a, double b, double epsilon); +#else +#define assert_double_not_equal(a, b, epsilon) \ + _assert_double_not_equal((float)a, \ + (double)b, \ + (double)epsilon, \ + __FILE__, __LINE__) +#endif + + #ifdef DOXYGEN /** * @brief Assert that the two given strings are equal. @@ -1229,8 +1360,7 @@ void assert_int_not_equal(int a, int b); void assert_string_equal(const char *a, const char *b); #else #define assert_string_equal(a, b) \ - _assert_string_equal((const char*)(a), (const char*)(b), __FILE__, \ - __LINE__) + _assert_string_equal((a), (b), __FILE__, __LINE__) #endif #ifdef DOXYGEN @@ -1247,8 +1377,7 @@ void assert_string_equal(const char *a, const char *b); void assert_string_not_equal(const char *a, const char *b); #else #define assert_string_not_equal(a, b) \ - _assert_string_not_equal((const char*)(a), (const char*)(b), __FILE__, \ - __LINE__) + _assert_string_not_equal((a), (b), __FILE__, __LINE__) #endif #ifdef DOXYGEN @@ -1405,7 +1534,10 @@ void assert_not_in_set(LargestIntegralType value, LargestIntegralType values[], * created (e.g. expect_function_call()) than consumed with function_called(). * There are provisions such as ignore_function_calls() which allow this * restriction to be circumvented in tests where mock calls for the code under - * test are not the focus of the test. + * test are not the focus of the test. function_called() must be called from + * the same thread as expect_function_call(), and that thread must have been + * initialized for use by cmocka (see also the [Threading section of the main + * documentation page](index.html#main-threads)). * * The following example illustrates how a unit test instructs cmocka * to expect a function_called() from a particular mock, @@ -1575,7 +1707,7 @@ void skip(void); void fail_msg(const char *msg, ...); #else #define fail_msg(msg, ...) do { \ - print_error("ERROR: " msg "\n", ##__VA_ARGS__); \ + cm_print_error("ERROR: " msg "\n", ##__VA_ARGS__); \ fail(); \ } while (0) #endif @@ -1719,7 +1851,7 @@ static inline void _unit_test_dummy(void **state) { * @code * static int setup(void **state) { * int *answer = malloc(sizeof(int)); - * if (*answer == NULL) { + * if (answer == NULL) { * return -1; * } * *answer = 42; @@ -1787,7 +1919,7 @@ int cmocka_run_group_tests(const struct CMUnitTest group_tests[], * @code * static int setup(void **state) { * int *answer = malloc(sizeof(int)); - * if (*answer == NULL) { + * if (answer == NULL) { * return -1; * } * *answer = 42; @@ -2199,6 +2331,18 @@ void _assert_return_code(const LargestIntegralType result, const char * const expression, const char * const file, const int line); +void _assert_float_equal(const float a, const float n, + const float epsilon, const char* const file, + const int line); +void _assert_float_not_equal(const float a, const float n, + const float epsilon, const char* const file, + const int line); +void _assert_double_equal(const double a, const double n, + const double epsilon, const char* const file, + const int line); +void _assert_double_not_equal(const double a, const double n, + const double epsilon, const char* const file, + const int line); void _assert_int_equal( const LargestIntegralType a, const LargestIntegralType b, const char * const file, const int line); @@ -2234,9 +2378,9 @@ void* _test_calloc(const size_t number_of_elements, const size_t size, const char* file, const int line); void _test_free(void* const ptr, const char* file, const int line); -void _fail(const char * const file, const int line); +CMOCKA_NORETURN void _fail(const char * const file, const int line); -void _skip(const char * const file, const int line); +CMOCKA_NORETURN void _skip(const char * const file, const int line); int _run_test( const char * const function_name, const UnitTestFunction Function, @@ -2259,6 +2403,7 @@ void print_message(const char* const format, ...) CMOCKA_PRINTF_ATTRIBUTE(1, 2); void print_error(const char* const format, ...) CMOCKA_PRINTF_ATTRIBUTE(1, 2); void vprint_message(const char* const format, va_list args) CMOCKA_PRINTF_ATTRIBUTE(1, 0); void vprint_error(const char* const format, va_list args) CMOCKA_PRINTF_ATTRIBUTE(1, 0); +void cm_print_error(const char* const format, ...) CMOCKA_PRINTF_ATTRIBUTE(1, 2); enum cm_message_output { CM_OUTPUT_STDOUT, @@ -2284,7 +2429,7 @@ void cmocka_set_message_output(enum cm_message_output output); /** * @brief Set a pattern to only run the test matching the pattern. * - * This allows to filter tests and only run the ones matching the pattern. Thep + * This allows to filter tests and only run the ones matching the pattern. The * pattern can include two wildards. The first is '*', a wildcard that matches * zero or more characters, or ‘?’, a wildcard that matches exactly one * character. @@ -2293,6 +2438,18 @@ void cmocka_set_message_output(enum cm_message_output output); */ void cmocka_set_test_filter(const char *pattern); +/** + * @brief Set a pattern to skip tests matching the pattern. + * + * This allows to filter tests and skip the ones matching the pattern. The + * pattern can include two wildards. The first is '*', a wildcard that matches + * zero or more characters, or ‘?’, a wildcard that matches exactly one + * character. + * + * @param[in] pattern The pattern to match, e.g. "test_wurst*" + */ +void cmocka_set_skip_filter(const char *pattern); + /** @} */ #endif /* CMOCKA_H_ */ diff --git a/third_party/cmocka/cmocka_private.h b/third_party/cmocka/cmocka_private.h index d20d841aed5..4d3ff30228c 100644 --- a/third_party/cmocka/cmocka_private.h +++ b/third_party/cmocka/cmocka_private.h @@ -28,6 +28,7 @@ # ifdef _MSC_VER # include /* _snprintf */ +# include /* strtok_s */ # undef inline # define inline __inline @@ -38,6 +39,7 @@ # define strcasecmp _stricmp # define strncasecmp _strnicmp +# define strtok_r strtok_s # if defined(HAVE__SNPRINTF_S) # undef snprintf diff --git a/third_party/cmocka/wscript b/third_party/cmocka/wscript index ebac963b0e1..ba82d459bd9 100644 --- a/third_party/cmocka/wscript +++ b/third_party/cmocka/wscript @@ -18,9 +18,13 @@ def build(bld): # Link to librt if needed for clock_gettime() if bld.CONFIG_SET('HAVE_LIBRT'): extra_libs += ' rt' + cmocka_cflags = '-DHAVE_CONFIG_H=1' + if bld.CONFIG_SET('HAVE_WNO_ERROR_DECLARATION_AFTER_STATEMENT'): + cmocka_cflags += ' -Wno-error=declaration-after-statement' + bld.SAMBA_LIBRARY('cmocka', source='cmocka.c', - cflags='-DHAVE_CONFIG_H=1', + cflags_end=cmocka_cflags, deps=extra_libs, allow_warnings=True, private_library=True)