]> git.ipfire.org Git - thirdparty/samba.git/commitdiff
third_party: Update cmocka to version 1.1.8
authorAndreas Schneider <asn@samba.org>
Wed, 15 Oct 2025 09:39:42 +0000 (11:39 +0200)
committerAnoop C S <anoopcs@samba.org>
Fri, 17 Oct 2025 12:16:23 +0000 (12:16 +0000)
Signed-off-by: Andreas Schneider <asn@samba.org>
Reviewed-by: Anoop C S <anoopcs@samba.org>
Autobuild-User(master): Anoop C S <anoopcs@samba.org>
Autobuild-Date(master): Fri Oct 17 12:16:23 UTC 2025 on atb-devel-224

buildtools/wafsamba/samba_third_party.py
third_party/cmocka/cmocka.c
third_party/cmocka/cmocka.h
third_party/cmocka/cmocka_private.h
third_party/cmocka/wscript

index 8f0c56dec797d1e5b6a8c72ee0a3cf57b1bb1a54..425c45457098ad765d20de7e15a6d358be795075 100644 (file)
@@ -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
 
index b21fe15536c9d9e5bd51c2bd78ced96a992fbd69..1ea32ebc6bf2046f693890eccfb9dd7431429fb8 100644 (file)
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
+#include <stdbool.h>
 #include <time.h>
+#include <float.h>
+#include <errno.h>
+#include <limits.h>
 
 /*
  * 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"
 
 
 /*
- * 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, "&", "&amp;", NULL);
+    c_strreplace(buf, buf_len, "\"", "&quot;", NULL);
+    c_strreplace(buf, buf_len, "\'", "&apos;", NULL);
+    c_strreplace(buf, buf_len, "<", "&lt;", NULL);
+    c_strreplace(buf, buf_len, ">", "&gt;", 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, "<testsuites>\n");
     fprintf(fp, "  <testsuite name=\"%s\" time=\"%.3f\" "
                 "tests=\"%u\" failures=\"%u\" errors=\"%u\" skipped=\"%u\" >\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, "    <testcase name=\"%s\" time=\"%.3f\" >\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;
index e6861c83d2754b2cd9c9e7c0ec2676b5c10105bc..c5872fe34370184b4fa4af56bfa4bfba8670be4d 100644 (file)
@@ -1,6 +1,6 @@
 /*
  * Copyright 2008 Google Inc.
- * Copyright 2014-2018 Andreas Schneider <asn@cryptomilk.org>
+ * Copyright 2014-2022 Andreas Schneider <asn@cryptomilk.org>
  *
  * 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 <stdarg.h>
+ * #include <stdbool.h>
  * #include <stddef.h>
+ * #include <stdint.h>
  * #include <setjmp.h>
  * @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
- * <a href="http://git.cryptomilk.org/projects/cmocka.git/tree/example/chef_wrap/waiter_test_wrap.c">here</a>.
+ * For a complete example please take a look
+ * <a href="https://git.cryptomilk.org/projects/cmocka.git/tree/example/mock">here</a>.
  *
  * @{
  */
@@ -425,8 +443,8 @@ void will_return_maybe(#function, LargestIntegralType value);
  * }
  * @endcode
  *
- * For a complete example please at a look at
- * <a href="http://git.cryptomilk.org/projects/cmocka.git/tree/example/chef_wrap/waiter_test_wrap.c">here</a>
+ * For a complete example please take a look
+ * <a href="https://git.cryptomilk.org/projects/cmocka.git/tree/example/mock">here</a>
  *
  * @{
  */
@@ -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_ */
index d20d841aed564f774ec441867a838709d4e1ba0f..4d3ff30228c41dbd6ccf7b1570776941673add37 100644 (file)
@@ -28,6 +28,7 @@
 
 # ifdef _MSC_VER
 # include <stdio.h> /* _snprintf */
+# include <string.h> /* 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
index ebac963b0e1c9e703cf4941b79169631f7c67816..ba82d459bd92fdb114738ba36c5c7b8f20df9046 100644 (file)
@@ -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)