[PATCH] Update cmocka to version 1.1.3

Jeremy Allison jra at samba.org
Tue Oct 2 17:20:29 UTC 2018


On Tue, Oct 02, 2018 at 10:04:53AM +0200, Andreas Schneider via samba-technical wrote:
> Hello,
> 
> the attached patch updates cmocka to version 1.1.3. A gitlab merge request is 
> here:
> 
> https://gitlab.com/samba-team/samba/merge_requests/78
> 
> 
> Please review and push if OK.

LGTM. RB+ and pushed.

Jeremy.

> Thanks,
> 
> 
> 	Andreas
> 
> -- 
> Andreas Schneider                      asn at samba.org
> Samba Team                             www.samba.org
> GPG-ID:     8DFF53E18F2ABC8D8F3C92237EE0FC4DCC014E3D

> From 0b3b749e50274fda16b6640dd1562b14181b469f Mon Sep 17 00:00:00 2001
> From: Andreas Schneider <asn at samba.org>
> Date: Tue, 4 Sep 2018 17:50:15 +0200
> Subject: [PATCH] third_party: Update cmocka to version 1.1.3
> 
> * Added function to filter tests (cmocka_set_test_filter)
> * Fixed fixture error reporting
> * Some improvement for API documentation -> https://api.cmocka.org/
> * Fixed subunit output on failures
> * Do not abort if a test is skipped
> 
> Signed-off-by: Andreas Schneider <asn at samba.org>
> ---
>  buildtools/wafsamba/samba_third_party.py |   2 +-
>  third_party/cmocka/cmocka.c              | 261 +++++++++++++++++------
>  third_party/cmocka/cmocka.h              |  28 ++-
>  3 files changed, 215 insertions(+), 76 deletions(-)
> 
> diff --git a/buildtools/wafsamba/samba_third_party.py b/buildtools/wafsamba/samba_third_party.py
> index f86d38710c4..a529ae981d0 100644
> --- a/buildtools/wafsamba/samba_third_party.py
> +++ b/buildtools/wafsamba/samba_third_party.py
> @@ -36,7 +36,7 @@ Build.BuildContext.CHECK_POPT = CHECK_POPT
>  
>  @conf
>  def CHECK_CMOCKA(conf):
> -    return conf.CHECK_BUNDLED_SYSTEM_PKG('cmocka', minversion='1.1.1')
> +    return conf.CHECK_BUNDLED_SYSTEM_PKG('cmocka', minversion='1.1.3')
>  
>  Build.BuildContext.CHECK_CMOCKA = CHECK_CMOCKA
>  
> diff --git a/third_party/cmocka/cmocka.c b/third_party/cmocka/cmocka.c
> index 0861c2cbcd6..b21fe15536c 100644
> --- a/third_party/cmocka/cmocka.c
> +++ b/third_party/cmocka/cmocka.c
> @@ -1,6 +1,6 @@
>  /*
>   * Copyright 2008 Google Inc.
> - * Copyright 2014-2015 Andreas Schneider <asn at cryptomilk.org>
> + * Copyright 2014-2018 Andreas Schneider <asn at cryptomilk.org>
>   * Copyright 2015      Jakub Hrozek <jakub.hrozek at posteo.se>
>   *
>   * Licensed under the Apache License, Version 2.0 (the "License");
> @@ -45,7 +45,7 @@
>  #include <time.h>
>  
>  /*
> - * This allows one to add a platform specific header file. Some embedded platforms
> + * This allows to add a platform specific header file. Some embedded platforms
>   * sometimes miss certain types and definitions.
>   *
>   * Example:
> @@ -148,12 +148,17 @@ typedef struct ListNode {
>  } ListNode;
>  
>  /* Debug information for malloc(). */
> -typedef struct MallocBlockInfo {
> +struct MallocBlockInfoData {
>      void* block;              /* Address of the block returned by malloc(). */
>      size_t allocated_size;    /* Total size of the allocated block. */
>      size_t size;              /* Request block size. */
>      SourceLocation location;  /* Where the block was allocated. */
>      ListNode node;            /* Node within list of all allocated blocks. */
> +};
> +
> +typedef union {
> +    struct MallocBlockInfoData *data;
> +    char *ptr;
>  } MallocBlockInfo;
>  
>  /* State of each test. */
> @@ -247,7 +252,7 @@ static void remove_always_return_values(ListNode * const map_head,
>  static size_t check_for_leftover_values_list(const ListNode * head,
>                                               const char * const error_message);
>  
> -static int check_for_leftover_values(
> +static size_t check_for_leftover_values(
>      const ListNode * const map_head, const char * const error_message,
>      const size_t number_of_symbol_names);
>  
> @@ -305,6 +310,8 @@ static CMOCKA_THREAD ListNode global_allocated_blocks;
>  
>  static enum cm_message_output global_msg_output = CM_OUTPUT_STDOUT;
>  
> +static const char *global_test_filter_pattern;
> +
>  #ifndef _WIN32
>  /* Signals caught by exception_handler(). */
>  static const int exception_signals[] = {
> @@ -381,9 +388,15 @@ struct CMUnitTestState {
>  /* Exit the currently executing test. */
>  static void exit_test(const int quit_application)
>  {
> -    const char *abort_test = getenv("CMOCKA_TEST_ABORT");
> +    const char *env = getenv("CMOCKA_TEST_ABORT");
> +    int abort_test = 0;
> +
> +    if (env != NULL && strlen(env) == 1) {
> +        abort_test = (env[0] == '1');
> +    }
>  
> -    if (abort_test != NULL && abort_test[0] == '1') {
> +    if (global_skip_test == 0 &&
> +        abort_test == 1) {
>          print_error("%s", cm_error_message);
>          abort();
>      } else if (global_running_test) {
> @@ -453,7 +466,7 @@ static int c_strreplace(char *src,
>              memmove(src + of + rl, src + of + pl, l - of - pl + 1);
>          }
>  
> -        strncpy(src + of, repl, rl);
> +        memcpy(src + of, repl, rl);
>  
>          if (str_replaced != NULL) {
>              *str_replaced = 1;
> @@ -464,6 +477,64 @@ static int c_strreplace(char *src,
>      return 0;
>  }
>  
> +static int c_strmatch(const char *str, const char *pattern)
> +{
> +    int ok;
> +
> +    if (str == NULL || pattern == NULL) {
> +        return 0;
> +    }
> +
> +    for (;;) {
> +        /* Check if pattern is done */
> +        if (*pattern == '\0') {
> +            /* If string is at the end, we're good */
> +            if (*str == '\0') {
> +                return 1;
> +            }
> +
> +            return 0;
> +        }
> +
> +        if (*pattern == '*') {
> +            /* Move on */
> +            pattern++;
> +
> +            /* If we are at the end, everything is fine */
> +            if (*pattern == '\0') {
> +                return 1;
> +            }
> +
> +            /* Try to match each position */
> +            for (; *str != '\0'; str++) {
> +                ok = c_strmatch(str, pattern);
> +                if (ok) {
> +                    return 1;
> +                }
> +            }
> +
> +            /* No match */
> +            return 0;
> +        }
> +
> +        /* If we are at the end, leave */
> +        if (*str == '\0') {
> +            return 0;
> +        }
> +
> +        /* Check if we have a single wildcard or matching char */
> +        if (*pattern != '?' && *str != *pattern) {
> +            return 0;
> +        }
> +
> +        /* Move string and pattern */
> +        str++;
> +        pattern++;
> +    }
> +
> +    return 0;
> +}
> +
>  /* Create function results and expected parameter lists. */
>  void initialize_testing(const char *test_name) {
>      (void)test_name;
> @@ -489,7 +560,8 @@ static void fail_if_leftover_values(const char *test_name) {
>      remove_always_return_values(&global_function_parameter_map_head, 2);
>      if (check_for_leftover_values(
>              &global_function_parameter_map_head,
> -            "%s parameter still has values that haven't been checked.\n", 2)) {
> +            "'%s' parameter still has values that haven't been checked.\n",
> +            2)) {
>          error_occurred = 1;
>      }
>  
> @@ -620,7 +692,7 @@ static int list_find(ListNode * const head, const void *value,
>  
>  /* Returns the first node of a list */
>  static int list_first(ListNode * const head, ListNode **output) {
> -    ListNode *target_node;
> +    ListNode *target_node = NULL;
>      assert_non_null(head);
>      if (list_empty(head)) {
>          return 0;
> @@ -708,8 +780,8 @@ static void add_symbol_value(ListNode * const symbol_map_head,
>  static int get_symbol_value(
>          ListNode * const head, const char * const symbol_names[],
>          const size_t number_of_symbol_names, void **output) {
> -    const char* symbol_name;
> -    ListNode *target_node;
> +    const char* symbol_name = NULL;
> +    ListNode *target_node = NULL;
>      assert_non_null(head);
>      assert_non_null(symbol_names);
>      assert_true(number_of_symbol_names);
> @@ -717,8 +789,8 @@ static int get_symbol_value(
>      symbol_name = symbol_names[0];
>  
>      if (list_find(head, symbol_name, symbol_names_match, &target_node)) {
> -        SymbolMapValue *map_value;
> -        ListNode *child_list;
> +        SymbolMapValue *map_value = NULL;
> +        ListNode *child_list = NULL;
>          int return_value = 0;
>          assert_non_null(target_node);
>          assert_non_null(target_node->value);
> @@ -730,6 +802,10 @@ static int get_symbol_value(
>              ListNode *value_node = NULL;
>              return_value = list_first(child_list, &value_node);
>              assert_true(return_value);
> +            /* Add a check to silence clang analyzer */
> +            if (return_value == 0) {
> +                goto out;
> +            }
>              *output = (void*) value_node->value;
>              return_value = value_node->refcount;
>              if (value_node->refcount - 1 == 0) {
> @@ -746,9 +822,9 @@ static int get_symbol_value(
>              list_remove_free(target_node, free_symbol_map_value, (void*)0);
>          }
>          return return_value;
> -    } else {
> -        cm_print_error("No entries for symbol %s.\n", symbol_name);
>      }
> +out:
> +    cm_print_error("No entries for symbol %s.\n", symbol_name);
>      return 0;
>  }
>  
> @@ -835,11 +911,11 @@ static size_t check_for_leftover_values_list(const ListNode * head,
>   * Checks if there are any leftover values set up by the test that were never
>   * retrieved through execution, and fail the test if that is the case.
>   */
> -static int check_for_leftover_values(
> +static size_t check_for_leftover_values(
>          const ListNode * const map_head, const char * const error_message,
>          const size_t number_of_symbol_names) {
>      const ListNode *current;
> -    int symbols_with_leftover_values = 0;
> +    size_t symbols_with_leftover_values = 0;
>      assert_non_null(map_head);
>      assert_true(number_of_symbol_names);
>  
> @@ -865,7 +941,7 @@ static int check_for_leftover_values(
>                                     location->file, location->line);
>                  }
>              } else {
> -                cm_print_error("%s.", value->symbol_name);
> +                cm_print_error("%s: ", value->symbol_name);
>                  check_for_leftover_values(child_list, error_message,
>                                            number_of_symbol_names - 1);
>              }
> @@ -1187,19 +1263,24 @@ static int string_not_equal_display_error(
>   */
>  static int memory_equal_display_error(const char* const a, const char* const b,
>                                        const size_t size) {
> -    int differences = 0;
> +    size_t differences = 0;
>      size_t i;
>      for (i = 0; i < size; i++) {
>          const char l = a[i];
>          const char r = b[i];
>          if (l != r) {
> -            cm_print_error("difference at offset %" PRIdS " 0x%02x 0x%02x\n",
> -                           i, l, r);
> +            if (differences < 16) {
> +                cm_print_error("difference at offset %" PRIdS " 0x%02x 0x%02x\n",
> +                               i, l, r);
> +            }
>              differences ++;
>          }
>      }
> -    if (differences) {
> -        cm_print_error("%d bytes of %p and %p differ\n",
> +    if (differences > 0) {
> +        if (differences >= 16) {
> +            cm_print_error("...\n");
> +        }
> +        cm_print_error("%"PRIdS " bytes of %p and %p differ\n",
>                         differences, (void *)a, (void *)b);
>          return 0;
>      }
> @@ -1526,7 +1607,7 @@ void _expect_any(
>  void _check_expected(
>          const char * const function_name, const char * const parameter_name,
>          const char* file, const int line, const LargestIntegralType value) {
> -    void *result;
> +    void *result = NULL;
>      const char* symbols[] = {function_name, parameter_name};
>      const int rc = get_symbol_value(&global_function_parameter_map_head,
>                                      symbols, 2, &result);
> @@ -1819,16 +1900,22 @@ static void vcm_free_error(char *err_msg)
>  /* Use the real malloc in this function. */
>  #undef malloc
>  void* _test_malloc(const size_t size, const char* file, const int line) {
> -    char* ptr;
> -    MallocBlockInfo *block_info;
> +    char *ptr = NULL;
> +    MallocBlockInfo block_info;
>      ListNode * const block_list = get_allocated_blocks_list();
> -    const size_t allocate_size = size + (MALLOC_GUARD_SIZE * 2) +
> -        sizeof(*block_info) + MALLOC_ALIGNMENT;
> -    char* const block = (char*)malloc(allocate_size);
> +    size_t allocate_size;
> +    char *block = NULL;
> +
> +    allocate_size = size + (MALLOC_GUARD_SIZE * 2) +
> +                    sizeof(struct MallocBlockInfoData) + MALLOC_ALIGNMENT;
> +    assert_true(allocate_size > size);
> +
> +    block = (char *)malloc(allocate_size);
>      assert_non_null(block);
>  
>      /* Calculate the returned address. */
> -    ptr = (char*)(((size_t)block + MALLOC_GUARD_SIZE + sizeof(*block_info) +
> +    ptr = (char*)(((size_t)block + MALLOC_GUARD_SIZE +
> +                  sizeof(struct MallocBlockInfoData) +
>                    MALLOC_ALIGNMENT) & ~(MALLOC_ALIGNMENT - 1));
>  
>      /* Initialize the guard blocks. */
> @@ -1836,14 +1923,14 @@ void* _test_malloc(const size_t size, const char* file, const int line) {
>      memset(ptr + size, MALLOC_GUARD_PATTERN, MALLOC_GUARD_SIZE);
>      memset(ptr, MALLOC_ALLOC_PATTERN, size);
>  
> -    block_info = (MallocBlockInfo*)(ptr - (MALLOC_GUARD_SIZE +
> -                                             sizeof(*block_info)));
> -    set_source_location(&block_info->location, file, line);
> -    block_info->allocated_size = allocate_size;
> -    block_info->size = size;
> -    block_info->block = block;
> -    block_info->node.value = block_info;
> -    list_add(block_list, &block_info->node);
> +    block_info.ptr = ptr - (MALLOC_GUARD_SIZE +
> +                            sizeof(struct MallocBlockInfoData));
> +    set_source_location(&block_info.data->location, file, line);
> +    block_info.data->allocated_size = allocate_size;
> +    block_info.data->size = size;
> +    block_info.data->block = block;
> +    block_info.data->node.value = block_info.ptr;
> +    list_add(block_list, &block_info.data->node);
>      return ptr;
>  }
>  #define malloc test_malloc
> @@ -1864,19 +1951,19 @@ void* _test_calloc(const size_t number_of_elements, const size_t size,
>  void _test_free(void* const ptr, const char* file, const int line) {
>      unsigned int i;
>      char *block = discard_const_p(char, ptr);
> -    MallocBlockInfo *block_info;
> +    MallocBlockInfo block_info;
>  
>      if (ptr == NULL) {
>          return;
>      }
>  
>      _assert_true(cast_ptr_to_largest_integral_type(ptr), "ptr", file, line);
> -    block_info = (MallocBlockInfo*)(block - (MALLOC_GUARD_SIZE +
> -                                               sizeof(*block_info)));
> +    block_info.ptr = block - (MALLOC_GUARD_SIZE +
> +                              sizeof(struct MallocBlockInfoData));
>      /* Check the guard blocks. */
>      {
>          char *guards[2] = {block - MALLOC_GUARD_SIZE,
> -                           block + block_info->size};
> +                           block + block_info.data->size};
>          for (i = 0; i < ARRAY_SIZE(guards); i++) {
>              unsigned int j;
>              char * const guard = guards[i];
> @@ -1886,19 +1973,22 @@ void _test_free(void* const ptr, const char* file, const int line) {
>                      cm_print_error(SOURCE_LOCATION_FORMAT
>                                     ": error: Guard block of %p size=%lu is corrupt\n"
>                                     SOURCE_LOCATION_FORMAT ": note: allocated here at %p\n",
> -                                   file, line,
> -                                   ptr, (unsigned long)block_info->size,
> -                                   block_info->location.file, block_info->location.line,
> +                                   file,
> +                                   line,
> +                                   ptr,
> +                                   (unsigned long)block_info.data->size,
> +                                   block_info.data->location.file,
> +                                   block_info.data->location.line,
>                                     (void *)&guard[j]);
>                      _fail(file, line);
>                  }
>              }
>          }
>      }
> -    list_remove(&block_info->node, NULL, NULL);
> +    list_remove(&block_info.data->node, NULL, NULL);
>  
> -    block = discard_const_p(char, block_info->block);
> -    memset(block, MALLOC_FREE_PATTERN, block_info->allocated_size);
> +    block = discard_const_p(char, block_info.data->block);
> +    memset(block, MALLOC_FREE_PATTERN, block_info.data->allocated_size);
>      free(block);
>  }
>  #define free test_free
> @@ -1909,7 +1999,7 @@ void *_test_realloc(void *ptr,
>                     const char *file,
>                     const int line)
>  {
> -    MallocBlockInfo *block_info;
> +    MallocBlockInfo block_info;
>      char *block = ptr;
>      size_t block_size = size;
>      void *new_block;
> @@ -1923,16 +2013,16 @@ void *_test_realloc(void *ptr,
>          return NULL;
>      }
>  
> -    block_info = (MallocBlockInfo*)(block - (MALLOC_GUARD_SIZE +
> -                                             sizeof(*block_info)));
> +    block_info.ptr = block - (MALLOC_GUARD_SIZE +
> +                              sizeof(struct MallocBlockInfoData));
>  
>      new_block = _test_malloc(size, file, line);
>      if (new_block == NULL) {
>          return NULL;
>      }
>  
> -    if (block_info->size < size) {
> -        block_size = block_info->size;
> +    if (block_info.data->size < size) {
> +        block_size = block_info.data->size;
>      }
>  
>      memcpy(new_block, ptr, block_size);
> @@ -1960,17 +2050,18 @@ static size_t display_allocated_blocks(const ListNode * const check_point) {
>      assert_non_null(check_point->next);
>  
>      for (node = check_point->next; node != head; node = node->next) {
> -        const MallocBlockInfo * const block_info =
> -            (const MallocBlockInfo*)node->value;
> -        assert_non_null(block_info);
> +        const MallocBlockInfo block_info = {
> +            .ptr = discard_const(node->value),
> +        };
> +        assert_non_null(block_info.ptr);
>  
>          if (allocated_blocks == 0) {
>              cm_print_error("Blocks allocated...\n");
>          }
>          cm_print_error(SOURCE_LOCATION_FORMAT ": note: block %p allocated here\n",
> -                       block_info->location.file,
> -                       block_info->location.line,
> -                       block_info->block);
> +                       block_info.data->location.file,
> +                       block_info.data->location.line,
> +                       block_info.data->block);
>          allocated_blocks++;
>      }
>      return allocated_blocks;
> @@ -1987,9 +2078,13 @@ static void free_allocated_blocks(const ListNode * const check_point) {
>      assert_non_null(node);
>  
>      while (node != head) {
> -        MallocBlockInfo * const block_info = (MallocBlockInfo*)node->value;
> +        const MallocBlockInfo block_info = {
> +            .ptr = discard_const(node->value),
> +        };
>          node = node->next;
> -        free(discard_const_p(char, block_info) + sizeof(*block_info) + MALLOC_GUARD_SIZE);
> +        free(discard_const_p(char, block_info.data) +
> +             sizeof(struct MallocBlockInfoData) +
> +             MALLOC_GUARD_SIZE);
>      }
>  }
>  
> @@ -2415,7 +2510,7 @@ static void cmprintf_subunit(enum cm_printf_type type,
>      case PRINTF_TEST_FAILURE:
>          print_message("failure: %s", test_name);
>          if (error_message != NULL) {
> -            print_message(" [\n%s]\n", error_message);
> +            print_message(" [\n%s\n]\n", error_message);
>          }
>          break;
>      case PRINTF_TEST_SKIPPED:
> @@ -2515,6 +2610,11 @@ void cmocka_set_message_output(enum cm_message_output output)
>      global_msg_output = output;
>  }
>  
> +void cmocka_set_test_filter(const char *pattern)
> +{
> +    global_test_filter_pattern = pattern;
> +}
> +
>  /****************************************************************************
>   * TIME CALCULATIONS
>   ****************************************************************************/
> @@ -2800,7 +2900,15 @@ int _cmocka_run_group_tests(const char *group_name,
>              (tests[i].test_func != NULL
>               || tests[i].setup_func != NULL
>               || tests[i].teardown_func != NULL)) {
> -            cm_tests[i] = (struct CMUnitTestState) {
> +            if (global_test_filter_pattern != NULL) {
> +                int ok;
> +
> +                ok = c_strmatch(tests[i].name, global_test_filter_pattern);
> +                if (!ok) {
> +                    continue;
> +                }
> +            }
> +            cm_tests[total_tests] = (struct CMUnitTestState) {
>                  .test = &tests[i],
>                  .status = CM_TEST_NOT_STARTED,
>                  .state = NULL,
> @@ -2871,10 +2979,16 @@ int _cmocka_run_group_tests(const char *group_name,
>                          break;
>                  }
>              } else {
> +                char err_msg[2048] = {0};
> +
> +                snprintf(err_msg, sizeof(err_msg),
> +                         "Could not run test: %s",
> +                         cmtest->error_message);
> +
>                  cmprintf(PRINTF_TEST_ERROR,
>                           test_number,
>                           cmtest->test->name,
> -                         "Could not run the test - check test fixtures");
> +                         err_msg);
>                  total_errors++;
>              }
>          }
> @@ -3167,7 +3281,7 @@ int _run_group_tests(const UnitTest * const tests, const size_t number_of_tests)
>      const char *setup_name;
>      size_t num_setups = 0;
>      UnitTestFunction teardown = NULL;
> -    const char *teardown_name;
> +    const char *teardown_name = NULL;
>      size_t num_teardowns = 0;
>      size_t current_test = 0;
>      size_t i;
> @@ -3178,10 +3292,21 @@ int _run_group_tests(const UnitTest * const tests, const size_t number_of_tests)
>      size_t total_failed = 0;
>      /* Check point of the heap state. */
>      const ListNode * const check_point = check_point_allocated_blocks();
> -    const char** failed_names = (const char**)malloc(number_of_tests *
> -                                       sizeof(*failed_names));
> +    const char **failed_names = NULL;
>      void **current_state = NULL;
> -    TestState group_state;
> +    TestState group_state = {
> +        .check_point = NULL,
> +    };
> +
> +    if (number_of_tests == 0) {
> +        return -1;
> +    }
> +
> +    failed_names = (const char **)malloc(number_of_tests *
> +                                         sizeof(*failed_names));
> +    if (failed_names == NULL) {
> +        return -2;
> +    }
>  
>      /* Find setup and teardown function */
>      for (i = 0; i < number_of_tests; i++) {
> diff --git a/third_party/cmocka/cmocka.h b/third_party/cmocka/cmocka.h
> index 4fd82a98b30..e6861c83d27 100644
> --- a/third_party/cmocka/cmocka.h
> +++ b/third_party/cmocka/cmocka.h
> @@ -1,5 +1,6 @@
>  /*
>   * Copyright 2008 Google Inc.
> + * Copyright 2014-2018 Andreas Schneider <asn at cryptomilk.org>
>   *
>   * Licensed under the Apache License, Version 2.0 (the "License");
>   * you may not use this file except in compliance with the License.
> @@ -56,7 +57,7 @@ int __stdcall IsDebuggerPresent();
>  
>  /* If __WORDSIZE is not set, try to figure it out and default to 32 bit. */
>  #ifndef __WORDSIZE
> -# if defined(__x86_64__) && !defined(__ILP32__)
> +# if (defined(__x86_64__) && !defined(__ILP32__)) || defined(__sparc_v9__) || defined(__sparcv9)
>  #  define __WORDSIZE 64
>  # else
>  #  define __WORDSIZE 32
> @@ -1107,7 +1108,7 @@ void assert_return_code(int rc, int error);
>   * @brief Assert that the given pointer is non-NULL.
>   *
>   * The function prints an error message to standard error and terminates the
> - * test by calling fail() if the pointer is non-NULL.
> + * test by calling fail() if the pointer is NULL.
>   *
>   * @param[in]  pointer  The pointer to evaluate.
>   *
> @@ -1698,8 +1699,8 @@ static inline void _unit_test_dummy(void **state) {
>   */
>  #define cmocka_unit_test_prestate_setup_teardown(f, setup, teardown, state) { #f, f, setup, teardown, state }
>  
> -#define run_tests(tests) _run_tests(tests, sizeof(tests) / sizeof(tests)[0])
> -#define run_group_tests(tests) _run_group_tests(tests, sizeof(tests) / sizeof(tests)[0])
> +#define run_tests(tests) _run_tests(tests, sizeof(tests) / sizeof((tests)[0]))
> +#define run_group_tests(tests) _run_group_tests(tests, sizeof(tests) / sizeof((tests)[0]))
>  
>  #ifdef DOXYGEN
>  /**
> @@ -1763,7 +1764,7 @@ int cmocka_run_group_tests(const struct CMUnitTest group_tests[],
>                             CMFixtureFunction group_teardown);
>  #else
>  # define cmocka_run_group_tests(group_tests, group_setup, group_teardown) \
> -        _cmocka_run_group_tests(#group_tests, group_tests, sizeof(group_tests) / sizeof(group_tests)[0], group_setup, group_teardown)
> +        _cmocka_run_group_tests(#group_tests, group_tests, sizeof(group_tests) / sizeof((group_tests)[0]), group_setup, group_teardown)
>  #endif
>  
>  #ifdef DOXYGEN
> @@ -1832,7 +1833,7 @@ int cmocka_run_group_tests_name(const char *group_name,
>                                  CMFixtureFunction group_teardown);
>  #else
>  # define cmocka_run_group_tests_name(group_name, group_tests, group_setup, group_teardown) \
> -        _cmocka_run_group_tests(group_name, group_tests, sizeof(group_tests) / sizeof(group_tests)[0], group_setup, group_teardown)
> +        _cmocka_run_group_tests(group_name, group_tests, sizeof(group_tests) / sizeof((group_tests)[0]), group_setup, group_teardown)
>  #endif
>  
>  /** @} */
> @@ -2269,7 +2270,7 @@ enum cm_message_output {
>  /**
>   * @brief Function to set the output format for a test.
>   *
> - * The output format for the test can either be set globally using this
> + * The ouput format for the test can either be set globally using this
>   * function or overriden with environment variable CMOCKA_MESSAGE_OUTPUT.
>   *
>   * The environment variable can be set to either STDOUT, SUBUNIT, TAP or XML.
> @@ -2279,6 +2280,19 @@ enum cm_message_output {
>   */
>  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
> + * 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_test_filter(const char *pattern);
> +
>  /** @} */
>  
>  #endif /* CMOCKA_H_ */
> -- 
> 2.19.0
> 




More information about the samba-technical mailing list