LCOV - code coverage report
Current view: top level - third_party/cmocka - cmocka.c (source / functions) Hit Total Coverage
Test: coverage report for master 2b515b7d Lines: 608 1510 40.3 %
Date: 2024-02-28 12:06:22 Functions: 77 125 61.6 %

          Line data    Source code
       1             : /*
       2             :  * Copyright 2008 Google Inc.
       3             :  * Copyright 2014-2018 Andreas Schneider <asn@cryptomilk.org>
       4             :  * Copyright 2015      Jakub Hrozek <jakub.hrozek@posteo.se>
       5             :  *
       6             :  * Licensed under the Apache License, Version 2.0 (the "License");
       7             :  * you may not use this file except in compliance with the License.
       8             :  * You may obtain a copy of the License at
       9             :  *
      10             :  * http://www.apache.org/licenses/LICENSE-2.0
      11             :  *
      12             :  * Unless required by applicable law or agreed to in writing, software
      13             :  * distributed under the License is distributed on an "AS IS" BASIS,
      14             :  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
      15             :  * See the License for the specific language governing permissions and
      16             :  * limitations under the License.
      17             :  */
      18             : #ifdef HAVE_CONFIG_H
      19             : #include "config.h"
      20             : #endif
      21             : 
      22             : #ifdef HAVE_MALLOC_H
      23             : #include <malloc.h>
      24             : #endif
      25             : 
      26             : #ifdef HAVE_INTTYPES_H
      27             : #include <inttypes.h>
      28             : #endif
      29             : 
      30             : #ifdef HAVE_SIGNAL_H
      31             : #include <signal.h>
      32             : #endif
      33             : 
      34             : #ifdef HAVE_STRINGS_H
      35             : #include <strings.h>
      36             : #endif
      37             : 
      38             : #include <stdint.h>
      39             : #include <setjmp.h>
      40             : #include <stdarg.h>
      41             : #include <stddef.h>
      42             : #include <stdio.h>
      43             : #include <stdlib.h>
      44             : #include <string.h>
      45             : #include <time.h>
      46             : 
      47             : /*
      48             :  * This allows to add a platform specific header file. Some embedded platforms
      49             :  * sometimes miss certain types and definitions.
      50             :  *
      51             :  * Example:
      52             :  *
      53             :  * typedef unsigned long int uintptr_t
      54             :  * #define _UINTPTR_T 1
      55             :  * #define _UINTPTR_T_DEFINED 1
      56             :  */
      57             : #ifdef CMOCKA_PLATFORM_INCLUDE
      58             : # include "cmocka_platform.h"
      59             : #endif /* CMOCKA_PLATFORM_INCLUDE */
      60             : 
      61             : #include <cmocka.h>
      62             : #include <cmocka_private.h>
      63             : 
      64             : /* Size of guard bytes around dynamically allocated blocks. */
      65             : #define MALLOC_GUARD_SIZE 16
      66             : /* Pattern used to initialize guard blocks. */
      67             : #define MALLOC_GUARD_PATTERN 0xEF
      68             : /* Pattern used to initialize memory allocated with test_malloc(). */
      69             : #define MALLOC_ALLOC_PATTERN 0xBA
      70             : #define MALLOC_FREE_PATTERN 0xCD
      71             : /* Alignment of allocated blocks.  NOTE: This must be base2. */
      72             : #define MALLOC_ALIGNMENT sizeof(size_t)
      73             : 
      74             : /* Printf formatting for source code locations. */
      75             : #define SOURCE_LOCATION_FORMAT "%s:%u"
      76             : 
      77             : #if defined(HAVE_GCC_THREAD_LOCAL_STORAGE)
      78             : # define CMOCKA_THREAD __thread
      79             : #elif defined(HAVE_MSVC_THREAD_LOCAL_STORAGE)
      80             : # define CMOCKA_THREAD __declspec(thread)
      81             : #else
      82             : # define CMOCKA_THREAD
      83             : #endif
      84             : 
      85             : #ifdef HAVE_CLOCK_REALTIME
      86             : #define CMOCKA_CLOCK_GETTIME(clock_id, ts) clock_gettime((clock_id), (ts))
      87             : #else
      88             : #define CMOCKA_CLOCK_GETTIME(clock_id, ts)
      89             : #endif
      90             : 
      91             : #ifndef MAX
      92             : #define MAX(a,b) ((a) < (b) ? (b) : (a))
      93             : #endif
      94             : 
      95             : /**
      96             :  * POSIX has sigsetjmp/siglongjmp, while Windows only has setjmp/longjmp.
      97             :  */
      98             : #ifdef HAVE_SIGLONGJMP
      99             : # define cm_jmp_buf             sigjmp_buf
     100             : # define cm_setjmp(env)         sigsetjmp(env, 1)
     101             : # define cm_longjmp(env, val)   siglongjmp(env, val)
     102             : #else
     103             : # define cm_jmp_buf             jmp_buf
     104             : # define cm_setjmp(env)         setjmp(env)
     105             : # define cm_longjmp(env, val)   longjmp(env, val)
     106             : #endif
     107             : 
     108             : 
     109             : /*
     110             :  * Declare and initialize the pointer member of ValuePointer variable name
     111             :  * with ptr.
     112             :  */
     113             : #define declare_initialize_value_pointer_pointer(name, ptr) \
     114             :     ValuePointer name ; \
     115             :     name.value = 0; \
     116             :     name.x.pointer = (void*)(ptr)
     117             : 
     118             : /*
     119             :  * Declare and initialize the value member of ValuePointer variable name
     120             :  * with val.
     121             :  */
     122             : #define declare_initialize_value_pointer_value(name, val) \
     123             :     ValuePointer name ; \
     124             :     name.value = val
     125             : 
     126             : /* Cast a LargestIntegralType to pointer_type via a ValuePointer. */
     127             : #define cast_largest_integral_type_to_pointer( \
     128             :     pointer_type, largest_integral_type) \
     129             :     ((pointer_type)((ValuePointer*)&(largest_integral_type))->x.pointer)
     130             : 
     131             : /* Used to cast LargetIntegralType to void* and vice versa. */
     132             : typedef union ValuePointer {
     133             :     LargestIntegralType value;
     134             :     struct {
     135             : #if defined(WORDS_BIGENDIAN) && (WORDS_SIZEOF_VOID_P == 4)
     136             :         unsigned int padding;
     137             : #endif
     138             :         void *pointer;
     139             :     } x;
     140             : } ValuePointer;
     141             : 
     142             : /* Doubly linked list node. */
     143             : typedef struct ListNode {
     144             :     const void *value;
     145             :     int refcount;
     146             :     struct ListNode *next;
     147             :     struct ListNode *prev;
     148             : } ListNode;
     149             : 
     150             : /* Debug information for malloc(). */
     151             : struct MallocBlockInfoData {
     152             :     void* block;              /* Address of the block returned by malloc(). */
     153             :     size_t allocated_size;    /* Total size of the allocated block. */
     154             :     size_t size;              /* Request block size. */
     155             :     SourceLocation location;  /* Where the block was allocated. */
     156             :     ListNode node;            /* Node within list of all allocated blocks. */
     157             : };
     158             : 
     159             : typedef union {
     160             :     struct MallocBlockInfoData *data;
     161             :     char *ptr;
     162             : } MallocBlockInfo;
     163             : 
     164             : /* State of each test. */
     165             : typedef struct TestState {
     166             :     const ListNode *check_point; /* Check point of the test if there's a */
     167             :                                  /* setup function. */
     168             :     void *state;                 /* State associated with the test. */
     169             : } TestState;
     170             : 
     171             : /* Determines whether two values are the same. */
     172             : typedef int (*EqualityFunction)(const void *left, const void *right);
     173             : 
     174             : /* Value of a symbol and the place it was declared. */
     175             : typedef struct SymbolValue {
     176             :     SourceLocation location;
     177             :     LargestIntegralType value;
     178             : } SymbolValue;
     179             : 
     180             : /*
     181             :  * Contains a list of values for a symbol.
     182             :  * NOTE: Each structure referenced by symbol_values_list_head must have a
     183             :  * SourceLocation as its' first member.
     184             :  */
     185             : typedef struct SymbolMapValue {
     186             :     const char *symbol_name;
     187             :     ListNode symbol_values_list_head;
     188             : } SymbolMapValue;
     189             : 
     190             : /* Where a particular ordering was located and its symbol name */
     191             : typedef struct FuncOrderingValue {
     192             :     SourceLocation location;
     193             :     const char * function;
     194             : } FuncOrderingValue;
     195             : 
     196             : /* Used by list_free() to deallocate values referenced by list nodes. */
     197             : typedef void (*CleanupListValue)(const void *value, void *cleanup_value_data);
     198             : 
     199             : /* Structure used to check the range of integer types.a */
     200             : typedef struct CheckIntegerRange {
     201             :     CheckParameterEvent event;
     202             :     LargestIntegralType minimum;
     203             :     LargestIntegralType maximum;
     204             : } CheckIntegerRange;
     205             : 
     206             : /* Structure used to check whether an integer value is in a set. */
     207             : typedef struct CheckIntegerSet {
     208             :     CheckParameterEvent event;
     209             :     const LargestIntegralType *set;
     210             :     size_t size_of_set;
     211             : } CheckIntegerSet;
     212             : 
     213             : /* Used to check whether a parameter matches the area of memory referenced by
     214             :  * this structure.  */
     215             : typedef struct CheckMemoryData {
     216             :     CheckParameterEvent event;
     217             :     const void *memory;
     218             :     size_t size;
     219             : } CheckMemoryData;
     220             : 
     221             : static ListNode* list_initialize(ListNode * const node);
     222             : static ListNode* list_add(ListNode * const head, ListNode *new_node);
     223             : static ListNode* list_add_value(ListNode * const head, const void *value,
     224             :                                      const int count);
     225             : static ListNode* list_remove(
     226             :     ListNode * const node, const CleanupListValue cleanup_value,
     227             :     void * const cleanup_value_data);
     228             : static void list_remove_free(
     229             :     ListNode * const node, const CleanupListValue cleanup_value,
     230             :     void * const cleanup_value_data);
     231             : static int list_empty(const ListNode * const head);
     232             : static int list_find(
     233             :     ListNode * const head, const void *value,
     234             :     const EqualityFunction equal_func, ListNode **output);
     235             : static int list_first(ListNode * const head, ListNode **output);
     236             : static ListNode* list_free(
     237             :     ListNode * const head, const CleanupListValue cleanup_value,
     238             :     void * const cleanup_value_data);
     239             : 
     240             : static void add_symbol_value(
     241             :     ListNode * const symbol_map_head, const char * const symbol_names[],
     242             :     const size_t number_of_symbol_names, const void* value, const int count);
     243             : static int get_symbol_value(
     244             :     ListNode * const symbol_map_head, const char * const symbol_names[],
     245             :     const size_t number_of_symbol_names, void **output);
     246             : static void free_value(const void *value, void *cleanup_value_data);
     247             : static void free_symbol_map_value(
     248             :     const void *value, void *cleanup_value_data);
     249             : static void remove_always_return_values(ListNode * const map_head,
     250             :                                         const size_t number_of_symbol_names);
     251             : 
     252             : static size_t check_for_leftover_values_list(const ListNode * head,
     253             :                                              const char * const error_message);
     254             : 
     255             : static size_t check_for_leftover_values(
     256             :     const ListNode * const map_head, const char * const error_message,
     257             :     const size_t number_of_symbol_names);
     258             : 
     259             : static void remove_always_return_values_from_list(ListNode * const map_head);
     260             : 
     261             : /*
     262             :  * This must be called at the beginning of a test to initialize some data
     263             :  * structures.
     264             :  */
     265             : static void initialize_testing(const char *test_name);
     266             : 
     267             : /* This must be called at the end of a test to free() allocated structures. */
     268             : static void teardown_testing(const char *test_name);
     269             : 
     270             : static enum cm_message_output cm_get_output(void);
     271             : 
     272             : static int cm_error_message_enabled = 1;
     273             : static CMOCKA_THREAD char *cm_error_message;
     274             : 
     275             : void cm_print_error(const char * const format, ...) CMOCKA_PRINTF_ATTRIBUTE(1, 2);
     276             : 
     277             : /*
     278             :  * Keeps track of the calling context returned by setenv() so that the fail()
     279             :  * method can jump out of a test.
     280             :  */
     281             : static CMOCKA_THREAD cm_jmp_buf global_run_test_env;
     282             : static CMOCKA_THREAD int global_running_test = 0;
     283             : 
     284             : /* Keeps track of the calling context returned by setenv() so that */
     285             : /* mock_assert() can optionally jump back to expect_assert_failure(). */
     286             : jmp_buf global_expect_assert_env;
     287             : int global_expecting_assert = 0;
     288             : const char *global_last_failed_assert = NULL;
     289             : static int global_skip_test;
     290             : 
     291             : /* Keeps a map of the values that functions will have to return to provide */
     292             : /* mocked interfaces. */
     293             : static CMOCKA_THREAD ListNode global_function_result_map_head;
     294             : /* Location of the last mock value returned was declared. */
     295             : static CMOCKA_THREAD SourceLocation global_last_mock_value_location;
     296             : 
     297             : /* Keeps a map of the values that functions expect as parameters to their
     298             :  * mocked interfaces. */
     299             : static CMOCKA_THREAD ListNode global_function_parameter_map_head;
     300             : /* Location of last parameter value checked was declared. */
     301             : static CMOCKA_THREAD SourceLocation global_last_parameter_location;
     302             : 
     303             : /* List (acting as FIFO) of call ordering. */
     304             : static CMOCKA_THREAD ListNode global_call_ordering_head;
     305             : /* Location of last call ordering that was declared. */
     306             : static CMOCKA_THREAD SourceLocation global_last_call_ordering_location;
     307             : 
     308             : /* List of all currently allocated blocks. */
     309             : static CMOCKA_THREAD ListNode global_allocated_blocks;
     310             : 
     311             : static enum cm_message_output global_msg_output = CM_OUTPUT_STDOUT;
     312             : 
     313             : static const char *global_test_filter_pattern;
     314             : 
     315             : #ifndef _WIN32
     316             : /* Signals caught by exception_handler(). */
     317             : static const int exception_signals[] = {
     318             :     SIGFPE,
     319             :     SIGILL,
     320             :     SIGSEGV,
     321             : #ifdef SIGBUS
     322             :     SIGBUS,
     323             : #endif
     324             : #ifdef SIGSYS
     325             :     SIGSYS,
     326             : #endif
     327             : };
     328             : 
     329             : /* Default signal functions that should be restored after a test is complete. */
     330             : typedef void (*SignalFunction)(int signal);
     331             : static SignalFunction default_signal_functions[
     332             :     ARRAY_SIZE(exception_signals)];
     333             : 
     334             : #else /* _WIN32 */
     335             : 
     336             : /* The default exception filter. */
     337             : static LPTOP_LEVEL_EXCEPTION_FILTER previous_exception_filter;
     338             : 
     339             : /* Fatal exceptions. */
     340             : typedef struct ExceptionCodeInfo {
     341             :     DWORD code;
     342             :     const char* description;
     343             : } ExceptionCodeInfo;
     344             : 
     345             : #define EXCEPTION_CODE_INFO(exception_code) {exception_code, #exception_code}
     346             : 
     347             : static const ExceptionCodeInfo exception_codes[] = {
     348             :     EXCEPTION_CODE_INFO(EXCEPTION_ACCESS_VIOLATION),
     349             :     EXCEPTION_CODE_INFO(EXCEPTION_ARRAY_BOUNDS_EXCEEDED),
     350             :     EXCEPTION_CODE_INFO(EXCEPTION_DATATYPE_MISALIGNMENT),
     351             :     EXCEPTION_CODE_INFO(EXCEPTION_FLT_DENORMAL_OPERAND),
     352             :     EXCEPTION_CODE_INFO(EXCEPTION_FLT_DIVIDE_BY_ZERO),
     353             :     EXCEPTION_CODE_INFO(EXCEPTION_FLT_INEXACT_RESULT),
     354             :     EXCEPTION_CODE_INFO(EXCEPTION_FLT_INVALID_OPERATION),
     355             :     EXCEPTION_CODE_INFO(EXCEPTION_FLT_OVERFLOW),
     356             :     EXCEPTION_CODE_INFO(EXCEPTION_FLT_STACK_CHECK),
     357             :     EXCEPTION_CODE_INFO(EXCEPTION_FLT_UNDERFLOW),
     358             :     EXCEPTION_CODE_INFO(EXCEPTION_GUARD_PAGE),
     359             :     EXCEPTION_CODE_INFO(EXCEPTION_ILLEGAL_INSTRUCTION),
     360             :     EXCEPTION_CODE_INFO(EXCEPTION_INT_DIVIDE_BY_ZERO),
     361             :     EXCEPTION_CODE_INFO(EXCEPTION_INT_OVERFLOW),
     362             :     EXCEPTION_CODE_INFO(EXCEPTION_INVALID_DISPOSITION),
     363             :     EXCEPTION_CODE_INFO(EXCEPTION_INVALID_HANDLE),
     364             :     EXCEPTION_CODE_INFO(EXCEPTION_IN_PAGE_ERROR),
     365             :     EXCEPTION_CODE_INFO(EXCEPTION_NONCONTINUABLE_EXCEPTION),
     366             :     EXCEPTION_CODE_INFO(EXCEPTION_PRIV_INSTRUCTION),
     367             :     EXCEPTION_CODE_INFO(EXCEPTION_STACK_OVERFLOW),
     368             : };
     369             : #endif /* !_WIN32 */
     370             : 
     371             : enum CMUnitTestStatus {
     372             :     CM_TEST_NOT_STARTED,
     373             :     CM_TEST_PASSED,
     374             :     CM_TEST_FAILED,
     375             :     CM_TEST_ERROR,
     376             :     CM_TEST_SKIPPED,
     377             : };
     378             : 
     379             : struct CMUnitTestState {
     380             :     const ListNode *check_point; /* Check point of the test if there's a setup function. */
     381             :     const struct CMUnitTest *test; /* Point to array element in the tests we get passed */
     382             :     void *state; /* State associated with the test */
     383             :     const char *error_message; /* The error messages by the test */
     384             :     enum CMUnitTestStatus status; /* PASSED, FAILED, ABORT ... */
     385             :     double runtime; /* Time calculations */
     386             : };
     387             : 
     388             : /* Exit the currently executing test. */
     389           0 : static void exit_test(const int quit_application)
     390             : {
     391           0 :     const char *env = getenv("CMOCKA_TEST_ABORT");
     392           0 :     int abort_test = 0;
     393             : 
     394           0 :     if (env != NULL && strlen(env) == 1) {
     395           0 :         abort_test = (env[0] == '1');
     396             :     }
     397             : 
     398           0 :     if (global_skip_test == 0 &&
     399             :         abort_test == 1) {
     400           0 :         print_error("%s", cm_error_message);
     401           0 :         abort();
     402           0 :     } else if (global_running_test) {
     403           0 :         cm_longjmp(global_run_test_env, 1);
     404           0 :     } else if (quit_application) {
     405           0 :         exit(-1);
     406             :     }
     407           0 : }
     408             : 
     409           0 : void _skip(const char * const file, const int line)
     410             : {
     411           0 :     cm_print_error(SOURCE_LOCATION_FORMAT ": Skipped!\n", file, line);
     412           0 :     global_skip_test = 1;
     413           0 :     exit_test(1);
     414           0 : }
     415             : 
     416             : /* Initialize a SourceLocation structure. */
     417        8562 : static void initialize_source_location(SourceLocation * const location) {
     418        8562 :     assert_non_null(location);
     419        8562 :     location->file = NULL;
     420        8562 :     location->line = 0;
     421        3744 : }
     422             : 
     423             : 
     424             : /* Determine whether a source location is currently set. */
     425           0 : static int source_location_is_set(const SourceLocation * const location) {
     426           0 :     assert_non_null(location);
     427           0 :     return location->file && location->line;
     428             : }
     429             : 
     430             : 
     431             : /* Set a source location. */
     432         408 : static void set_source_location(
     433             :     SourceLocation * const location, const char * const file,
     434             :     const int line) {
     435         408 :     assert_non_null(location);
     436         408 :     location->file = file;
     437         408 :     location->line = line;
     438           0 : }
     439             : 
     440             : 
     441           0 : static int c_strreplace(char *src,
     442             :                         size_t src_len,
     443             :                         const char *pattern,
     444             :                         const char *repl,
     445             :                         int *str_replaced)
     446             : {
     447           0 :     char *p = NULL;
     448             : 
     449           0 :     p = strstr(src, pattern);
     450           0 :     if (p == NULL) {
     451           0 :         return -1;
     452             :     }
     453             : 
     454           0 :     do {
     455           0 :         size_t of = p - src;
     456           0 :         size_t l  = strlen(src);
     457           0 :         size_t pl = strlen(pattern);
     458           0 :         size_t rl = strlen(repl);
     459             : 
     460             :         /* overflow check */
     461           0 :         if (src_len <= l + MAX(pl, rl) + 1) {
     462           0 :             return -1;
     463             :         }
     464             : 
     465           0 :         if (rl != pl) {
     466           0 :             memmove(src + of + rl, src + of + pl, l - of - pl + 1);
     467             :         }
     468             : 
     469           0 :         memcpy(src + of, repl, rl);
     470             : 
     471           0 :         if (str_replaced != NULL) {
     472           0 :             *str_replaced = 1;
     473             :         }
     474           0 :         p = strstr(src, pattern);
     475           0 :     } while (p != NULL);
     476             : 
     477           0 :     return 0;
     478             : }
     479             : 
     480           0 : static int c_strmatch(const char *str, const char *pattern)
     481             : {
     482           0 :     int ok;
     483             : 
     484           0 :     if (str == NULL || pattern == NULL) {
     485           0 :         return 0;
     486             :     }
     487             : 
     488           0 :     for (;;) {
     489             :         /* Check if pattern is done */
     490           0 :         if (*pattern == '\0') {
     491             :             /* If string is at the end, we're good */
     492           0 :             if (*str == '\0') {
     493           0 :                 return 1;
     494             :             }
     495             : 
     496           0 :             return 0;
     497             :         }
     498             : 
     499           0 :         if (*pattern == '*') {
     500             :             /* Move on */
     501           0 :             pattern++;
     502             : 
     503             :             /* If we are at the end, everything is fine */
     504           0 :             if (*pattern == '\0') {
     505           0 :                 return 1;
     506             :             }
     507             : 
     508             :             /* Try to match each position */
     509           0 :             for (; *str != '\0'; str++) {
     510           0 :                 ok = c_strmatch(str, pattern);
     511           0 :                 if (ok) {
     512           0 :                     return 1;
     513             :                 }
     514             :             }
     515             : 
     516             :             /* No match */
     517           0 :             return 0;
     518             :         }
     519             : 
     520             :         /* If we are at the end, leave */
     521           0 :         if (*str == '\0') {
     522           0 :             return 0;
     523             :         }
     524             : 
     525             :         /* Check if we have a single wildcard or matching char */
     526           0 :         if (*pattern != '?' && *str != *pattern) {
     527           0 :             return 0;
     528             :         }
     529             : 
     530             :         /* Move string and pattern */
     531           0 :         str++;
     532           0 :         pattern++;
     533             :     }
     534             : 
     535             :     return 0;
     536             : }
     537             : 
     538             : /* Create function results and expected parameter lists. */
     539        1427 : void initialize_testing(const char *test_name) {
     540         803 :     (void)test_name;
     541        1427 :     list_initialize(&global_function_result_map_head);
     542        2230 :     initialize_source_location(&global_last_mock_value_location);
     543        1427 :     list_initialize(&global_function_parameter_map_head);
     544        2230 :     initialize_source_location(&global_last_parameter_location);
     545        1427 :     list_initialize(&global_call_ordering_head);
     546        2230 :     initialize_source_location(&global_last_parameter_location);
     547        1427 : }
     548             : 
     549             : 
     550        1427 : static void fail_if_leftover_values(const char *test_name) {
     551        1427 :     int error_occurred = 0;
     552         803 :     (void)test_name;
     553        1427 :     remove_always_return_values(&global_function_result_map_head, 1);
     554        1427 :     if (check_for_leftover_values(
     555             :             &global_function_result_map_head,
     556             :             "%s() has remaining non-returned values.\n", 1)) {
     557           0 :         error_occurred = 1;
     558             :     }
     559             : 
     560        1427 :     remove_always_return_values(&global_function_parameter_map_head, 2);
     561        1427 :     if (check_for_leftover_values(
     562             :             &global_function_parameter_map_head,
     563             :             "'%s' parameter still has values that haven't been checked.\n",
     564             :             2)) {
     565           0 :         error_occurred = 1;
     566             :     }
     567             : 
     568        1427 :     remove_always_return_values_from_list(&global_call_ordering_head);
     569        1427 :     if (check_for_leftover_values_list(&global_call_ordering_head,
     570             :         "%s function was expected to be called but was not not.\n")) {
     571           0 :         error_occurred = 1;
     572             :     }
     573        1427 :     if (error_occurred) {
     574           0 :         exit_test(1);
     575             :     }
     576        1427 : }
     577             : 
     578             : 
     579        1427 : static void teardown_testing(const char *test_name) {
     580         803 :     (void)test_name;
     581        1427 :     list_free(&global_function_result_map_head, free_symbol_map_value,
     582             :               (void*)0);
     583        1427 :     initialize_source_location(&global_last_mock_value_location);
     584        1427 :     list_free(&global_function_parameter_map_head, free_symbol_map_value,
     585             :               (void*)1);
     586        1427 :     initialize_source_location(&global_last_parameter_location);
     587        1427 :     list_free(&global_call_ordering_head, free_value,
     588             :               (void*)0);
     589        1427 :     initialize_source_location(&global_last_call_ordering_location);
     590        1427 : }
     591             : 
     592             : /* Initialize a list node. */
     593        4689 : static ListNode* list_initialize(ListNode * const node) {
     594        4689 :     node->value = NULL;
     595        4689 :     node->next = node;
     596        4689 :     node->prev = node;
     597        4689 :     node->refcount = 1;
     598        2691 :     return node;
     599             : }
     600             : 
     601             : 
     602             : /*
     603             :  * Adds a value at the tail of a given list.
     604             :  * The node referencing the value is allocated from the heap.
     605             :  */
     606         735 : static ListNode* list_add_value(ListNode * const head, const void *value,
     607             :                                      const int refcount) {
     608         735 :     ListNode * const new_node = (ListNode*)malloc(sizeof(ListNode));
     609         735 :     assert_non_null(head);
     610         735 :     assert_non_null(value);
     611         735 :     new_node->value = value;
     612         735 :     new_node->refcount = refcount;
     613         735 :     return list_add(head, new_node);
     614             : }
     615             : 
     616             : 
     617             : /* Add new_node to the end of the list. */
     618         735 : static ListNode* list_add(ListNode * const head, ListNode *new_node) {
     619         735 :     assert_non_null(head);
     620         735 :     assert_non_null(new_node);
     621         735 :     new_node->next = head;
     622         735 :     new_node->prev = head->prev;
     623         735 :     head->prev->next = new_node;
     624         735 :     head->prev = new_node;
     625         735 :     return new_node;
     626             : }
     627             : 
     628             : 
     629             : /* Remove a node from a list. */
     630         735 : static ListNode* list_remove(
     631             :         ListNode * const node, const CleanupListValue cleanup_value,
     632             :         void * const cleanup_value_data) {
     633         735 :     assert_non_null(node);
     634         735 :     node->prev->next = node->next;
     635         735 :     node->next->prev = node->prev;
     636         735 :     if (cleanup_value) {
     637         342 :         cleanup_value(node->value, cleanup_value_data);
     638             :     }
     639         735 :     return node;
     640             : }
     641             : 
     642             : 
     643             : /* Remove a list node from a list and free the node. */
     644         735 : static void list_remove_free(
     645             :         ListNode * const node, const CleanupListValue cleanup_value,
     646             :         void * const cleanup_value_data) {
     647         735 :     assert_non_null(node);
     648         735 :     free(list_remove(node, cleanup_value, cleanup_value_data));
     649         735 : }
     650             : 
     651             : 
     652             : /*
     653             :  * Frees memory kept by a linked list The cleanup_value function is called for
     654             :  * every "value" field of nodes in the list, except for the head.  In addition
     655             :  * to each list value, cleanup_value_data is passed to each call to
     656             :  * cleanup_value.  The head of the list is not deallocated.
     657             :  */
     658        4587 : static ListNode* list_free(
     659             :         ListNode * const head, const CleanupListValue cleanup_value,
     660             :         void * const cleanup_value_data) {
     661        4587 :     assert_non_null(head);
     662        4587 :     while (!list_empty(head)) {
     663           0 :         list_remove_free(head->next, cleanup_value, cleanup_value_data);
     664             :     }
     665        4587 :     return head;
     666             : }
     667             : 
     668             : 
     669             : /* Determine whether a list is empty. */
     670        6938 : static int list_empty(const ListNode * const head) {
     671        5211 :     assert_non_null(head);
     672        5211 :     return head->next == head;
     673             : }
     674             : 
     675             : 
     676             : /*
     677             :  * Find a value in the list using the equal_func to compare each node with the
     678             :  * value.
     679             :  */
     680        1005 : static int list_find(ListNode * const head, const void *value,
     681             :                      const EqualityFunction equal_func, ListNode **output) {
     682        1005 :     ListNode *current;
     683        1005 :     assert_non_null(head);
     684        1221 :     for (current = head->next; current != head; current = current->next) {
     685         894 :         if (equal_func(current->value, value)) {
     686         678 :             *output = current;
     687         678 :             return 1;
     688             :         }
     689             :     }
     690           0 :     return 0;
     691             : }
     692             : 
     693             : /* Returns the first node of a list */
     694         394 : static int list_first(ListNode * const head, ListNode **output) {
     695         394 :     ListNode *target_node = NULL;
     696         394 :     assert_non_null(head);
     697         394 :     if (list_empty(head)) {
     698           0 :         return 0;
     699             :     }
     700         394 :     target_node = head->next;
     701         394 :     *output = target_node;
     702         394 :     return 1;
     703             : }
     704             : 
     705             : 
     706             : /* Deallocate a value referenced by a list. */
     707          36 : static void free_value(const void *value, void *cleanup_value_data) {
     708          36 :     (void)cleanup_value_data;
     709          36 :     assert_non_null(value);
     710          36 :     free((void*)value);
     711          36 : }
     712             : 
     713             : 
     714             : /* Releases memory associated to a symbol_map_value. */
     715         306 : static void free_symbol_map_value(const void *value,
     716             :                                   void *cleanup_value_data) {
     717         306 :     SymbolMapValue * const map_value = (SymbolMapValue*)value;
     718         306 :     const LargestIntegralType children = cast_ptr_to_largest_integral_type(cleanup_value_data);
     719         306 :     assert_non_null(value);
     720         306 :     list_free(&map_value->symbol_values_list_head,
     721             :               children ? free_symbol_map_value : free_value,
     722         306 :               (void *) ((uintptr_t)children - 1));
     723         306 :     free(map_value);
     724         306 : }
     725             : 
     726             : 
     727             : /*
     728             :  * Determine whether a symbol name referenced by a symbol_map_value matches the
     729             :  * specified function name.
     730             :  */
     731         894 : static int symbol_names_match(const void *map_value, const void *symbol) {
     732         894 :     return !strcmp(((SymbolMapValue*)map_value)->symbol_name,
     733             :                    (const char*)symbol);
     734             : }
     735             : 
     736             : /*
     737             :  * Adds a value to the queue of values associated with the given hierarchy of
     738             :  * symbols.  It's assumed value is allocated from the heap.
     739             :  */
     740         408 : static void add_symbol_value(ListNode * const symbol_map_head,
     741             :                              const char * const symbol_names[],
     742             :                              const size_t number_of_symbol_names,
     743             :                              const void* value, const int refcount) {
     744         517 :     const char* symbol_name;
     745         517 :     ListNode *target_node;
     746         517 :     SymbolMapValue *target_map_value;
     747         517 :     assert_non_null(symbol_map_head);
     748         517 :     assert_non_null(symbol_names);
     749         517 :     assert_true(number_of_symbol_names);
     750         517 :     symbol_name = symbol_names[0];
     751             : 
     752         517 :     if (!list_find(symbol_map_head, symbol_name, symbol_names_match,
     753             :                    &target_node)) {
     754         327 :         SymbolMapValue * const new_symbol_map_value =
     755         327 :             (SymbolMapValue*)malloc(sizeof(*new_symbol_map_value));
     756         327 :         new_symbol_map_value->symbol_name = symbol_name;
     757         327 :         list_initialize(&new_symbol_map_value->symbol_values_list_head);
     758         327 :         target_node = list_add_value(symbol_map_head, new_symbol_map_value,
     759             :                                           1);
     760             :     }
     761             : 
     762         517 :     target_map_value = (SymbolMapValue*)target_node->value;
     763         517 :     if (number_of_symbol_names == 1) {
     764         408 :             list_add_value(&target_map_value->symbol_values_list_head,
     765             :                                 value, refcount);
     766             :     } else {
     767         109 :         add_symbol_value(&target_map_value->symbol_values_list_head,
     768             :                          &symbol_names[1], number_of_symbol_names - 1, value,
     769             :                          refcount);
     770             :     }
     771         408 : }
     772             : 
     773             : 
     774             : /*
     775             :  * Gets the next value associated with the given hierarchy of symbols.
     776             :  * The value is returned as an output parameter with the function returning the
     777             :  * node's old refcount value if a value is found, 0 otherwise.  This means that
     778             :  * a return value of 1 indicates the node was just removed from the list.
     779             :  */
     780         488 : static int get_symbol_value(
     781             :         ListNode * const head, const char * const symbol_names[],
     782             :         const size_t number_of_symbol_names, void **output) {
     783         488 :     const char* symbol_name = NULL;
     784         488 :     ListNode *target_node = NULL;
     785         488 :     assert_non_null(head);
     786         488 :     assert_non_null(symbol_names);
     787         488 :     assert_true(number_of_symbol_names);
     788         488 :     assert_non_null(output);
     789         488 :     symbol_name = symbol_names[0];
     790             : 
     791         488 :     if (list_find(head, symbol_name, symbol_names_match, &target_node)) {
     792         488 :         SymbolMapValue *map_value = NULL;
     793         488 :         ListNode *child_list = NULL;
     794         488 :         int return_value = 0;
     795         488 :         assert_non_null(target_node);
     796         488 :         assert_non_null(target_node->value);
     797             : 
     798         488 :         map_value = (SymbolMapValue*)target_node->value;
     799         488 :         child_list = &map_value->symbol_values_list_head;
     800             : 
     801         488 :         if (number_of_symbol_names == 1) {
     802         394 :             ListNode *value_node = NULL;
     803         394 :             return_value = list_first(child_list, &value_node);
     804         394 :             assert_true(return_value);
     805             :             /* Add a check to silence clang analyzer */
     806         394 :             if (return_value == 0) {
     807           0 :                 goto out;
     808             :             }
     809         394 :             *output = (void*) value_node->value;
     810         394 :             return_value = value_node->refcount;
     811         394 :             if (value_node->refcount - 1 == 0) {
     812         393 :                 list_remove_free(value_node, NULL, NULL);
     813           1 :             } else if (value_node->refcount > WILL_RETURN_ONCE) {
     814           1 :                 --value_node->refcount;
     815             :             }
     816             :         } else {
     817          94 :             return_value = get_symbol_value(
     818             :                 child_list, &symbol_names[1], number_of_symbol_names - 1,
     819             :                 output);
     820             :         }
     821         488 :         if (list_empty(child_list)) {
     822         306 :             list_remove_free(target_node, free_symbol_map_value, (void*)0);
     823             :         }
     824         488 :         return return_value;
     825             :     }
     826           0 : out:
     827           0 :     cm_print_error("No entries for symbol %s.\n", symbol_name);
     828           0 :     return 0;
     829             : }
     830             : 
     831             : /**
     832             :  * Taverse a list of nodes and remove first symbol value in list that has a
     833             :  * refcount < -1 (i.e. should always be returned and has been returned at
     834             :  * least once).
     835             :  */
     836             : 
     837        1427 : static void remove_always_return_values_from_list(ListNode * const map_head)
     838             : {
     839        1427 :     ListNode * current = NULL;
     840        1427 :     ListNode * next = NULL;
     841        1427 :     assert_non_null(map_head);
     842             : 
     843        1427 :     for (current = map_head->next, next = current->next;
     844        1427 :             current != map_head;
     845           0 :             current = next, next = current->next) {
     846           0 :         if (current->refcount < -1) {
     847           0 :             list_remove_free(current, free_value, NULL);
     848             :         }
     849             :     }
     850        1427 : }
     851             : 
     852             : /*
     853             :  * Traverse down a tree of symbol values and remove the first symbol value
     854             :  * in each branch that has a refcount < -1 (i.e should always be returned
     855             :  * and has been returned at least once).
     856             :  */
     857        2860 : static void remove_always_return_values(ListNode * const map_head,
     858             :                                         const size_t number_of_symbol_names) {
     859        1612 :     ListNode *current;
     860        2860 :     assert_non_null(map_head);
     861        2860 :     assert_true(number_of_symbol_names);
     862        2860 :     current = map_head->next;
     863        2881 :     while (current != map_head) {
     864          21 :         SymbolMapValue * const value = (SymbolMapValue*)current->value;
     865          21 :         ListNode * const next = current->next;
     866          21 :         ListNode *child_list;
     867          21 :         assert_non_null(value);
     868          21 :         child_list = &value->symbol_values_list_head;
     869             : 
     870          21 :         if (!list_empty(child_list)) {
     871          21 :             if (number_of_symbol_names == 1) {
     872          15 :                 ListNode * const child_node = child_list->next;
     873             :                 /* If this item has been returned more than once, free it. */
     874          15 :                 if (child_node->refcount < -1) {
     875          15 :                     list_remove_free(child_node, free_value, NULL);
     876             :                 }
     877             :             } else {
     878           6 :                 remove_always_return_values(child_list,
     879             :                                             number_of_symbol_names - 1);
     880             :             }
     881             :         }
     882             : 
     883          21 :         if (list_empty(child_list)) {
     884          21 :             list_remove_free(current, free_value, NULL);
     885             :         }
     886           0 :         current = next;
     887             :     }
     888        2860 : }
     889             : 
     890        1427 : static size_t check_for_leftover_values_list(const ListNode * head,
     891             :                                              const char * const error_message)
     892             : {
     893         803 :     ListNode *child_node;
     894        1427 :     size_t leftover_count = 0;
     895        1427 :     if (!list_empty(head))
     896             :     {
     897           0 :         for (child_node = head->next; child_node != head;
     898           0 :                  child_node = child_node->next, ++leftover_count) {
     899           0 :             const FuncOrderingValue *const o =
     900             :                     (const FuncOrderingValue*) child_node->value;
     901           0 :             cm_print_error(error_message, o->function);
     902           0 :             cm_print_error(SOURCE_LOCATION_FORMAT
     903             :                     ": note: remaining item was declared here\n",
     904           0 :                     o->location.file, o->location.line);
     905             :         }
     906             :     }
     907        1427 :     return leftover_count;
     908             : }
     909             : 
     910             : /*
     911             :  * Checks if there are any leftover values set up by the test that were never
     912             :  * retrieved through execution, and fail the test if that is the case.
     913             :  */
     914        2854 : static size_t check_for_leftover_values(
     915             :         const ListNode * const map_head, const char * const error_message,
     916             :         const size_t number_of_symbol_names) {
     917        1606 :     const ListNode *current;
     918        2854 :     size_t symbols_with_leftover_values = 0;
     919        2854 :     assert_non_null(map_head);
     920        2854 :     assert_true(number_of_symbol_names);
     921             : 
     922        2854 :     for (current = map_head->next; current != map_head;
     923           0 :          current = current->next) {
     924           0 :         const SymbolMapValue * const value =
     925             :             (SymbolMapValue*)current->value;
     926           0 :         const ListNode *child_list;
     927           0 :         assert_non_null(value);
     928           0 :         child_list = &value->symbol_values_list_head;
     929             : 
     930           0 :         if (!list_empty(child_list)) {
     931           0 :             if (number_of_symbol_names == 1) {
     932           0 :                 const ListNode *child_node;
     933           0 :                 cm_print_error(error_message, value->symbol_name);
     934             : 
     935           0 :                 for (child_node = child_list->next; child_node != child_list;
     936           0 :                      child_node = child_node->next) {
     937           0 :                     const SourceLocation * const location =
     938             :                         (const SourceLocation*)child_node->value;
     939           0 :                     cm_print_error(SOURCE_LOCATION_FORMAT
     940             :                                    ": note: remaining item was declared here\n",
     941           0 :                                    location->file, location->line);
     942             :                 }
     943             :             } else {
     944           0 :                 cm_print_error("%s: ", value->symbol_name);
     945           0 :                 check_for_leftover_values(child_list, error_message,
     946             :                                           number_of_symbol_names - 1);
     947             :             }
     948           0 :             symbols_with_leftover_values ++;
     949             :         }
     950             :     }
     951        2854 :     return symbols_with_leftover_values;
     952             : }
     953             : 
     954             : 
     955             : /* Get the next return value for the specified mock function. */
     956         300 : LargestIntegralType _mock(const char * const function, const char* const file,
     957             :                           const int line) {
     958         300 :     void *result;
     959         300 :     const int rc = get_symbol_value(&global_function_result_map_head,
     960             :                                     &function, 1, &result);
     961         300 :     if (rc) {
     962         300 :         SymbolValue * const symbol = (SymbolValue*)result;
     963         300 :         const LargestIntegralType value = symbol->value;
     964         300 :         global_last_mock_value_location = symbol->location;
     965         300 :         if (rc == 1) {
     966         299 :             free(symbol);
     967             :         }
     968         300 :         return value;
     969             :     } else {
     970           0 :         cm_print_error(SOURCE_LOCATION_FORMAT ": error: Could not get value "
     971             :                        "to mock function %s\n", file, line, function);
     972           0 :         if (source_location_is_set(&global_last_mock_value_location)) {
     973           0 :             cm_print_error(SOURCE_LOCATION_FORMAT
     974             :                            ": note: Previously returned mock value was declared here\n",
     975             :                            global_last_mock_value_location.file,
     976             :                            global_last_mock_value_location.line);
     977             :         } else {
     978           0 :             cm_print_error("There were no previously returned mock values for "
     979             :                            "this test.\n");
     980             :         }
     981           0 :         exit_test(1);
     982             :     }
     983           0 :     return 0;
     984             : }
     985             : 
     986             : /* Ensure that function is being called in proper order */
     987           0 : void _function_called(const char *const function,
     988             :                       const char *const file,
     989             :                       const int line)
     990             : {
     991           0 :     ListNode *first_value_node = NULL;
     992           0 :     ListNode *value_node = NULL;
     993           0 :     int rc;
     994             : 
     995           0 :     rc = list_first(&global_call_ordering_head, &value_node);
     996           0 :     first_value_node = value_node;
     997           0 :     if (rc) {
     998           0 :         FuncOrderingValue *expected_call;
     999           0 :         int cmp;
    1000             : 
    1001           0 :         expected_call = (FuncOrderingValue *)value_node->value;
    1002             : 
    1003           0 :         cmp = strcmp(expected_call->function, function);
    1004           0 :         if (value_node->refcount < -1) {
    1005             :             /*
    1006             :              * Search through value nodes until either function is found or
    1007             :              * encounter a non-zero refcount greater than -2
    1008             :              */
    1009           0 :             if (cmp != 0) {
    1010           0 :                 value_node = value_node->next;
    1011           0 :                 expected_call = (FuncOrderingValue *)value_node->value;
    1012             : 
    1013           0 :                 cmp = strcmp(expected_call->function, function);
    1014           0 :                 while (value_node->refcount < -1 &&
    1015           0 :                        cmp != 0 &&
    1016           0 :                        value_node != first_value_node->prev) {
    1017           0 :                     value_node = value_node->next;
    1018           0 :                     if (value_node == NULL) {
    1019           0 :                         break;
    1020             :                     }
    1021           0 :                     expected_call = (FuncOrderingValue *)value_node->value;
    1022           0 :                     if (expected_call == NULL) {
    1023           0 :                         continue;
    1024             :                     }
    1025           0 :                     cmp = strcmp(expected_call->function, function);
    1026             :                 }
    1027             : 
    1028           0 :                 if (expected_call == NULL || value_node == first_value_node->prev) {
    1029           0 :                     cm_print_error(SOURCE_LOCATION_FORMAT
    1030             :                                    ": error: No expected mock calls matching "
    1031             :                                    "called() invocation in %s",
    1032             :                                    file, line,
    1033             :                                    function);
    1034           0 :                     exit_test(1);
    1035             :                 }
    1036             :             }
    1037             :         }
    1038             : 
    1039           0 :         if (cmp == 0) {
    1040           0 :             if (value_node->refcount > -2 && --value_node->refcount == 0) {
    1041           0 :                 list_remove_free(value_node, free_value, NULL);
    1042             :             }
    1043             :         } else {
    1044           0 :             cm_print_error(SOURCE_LOCATION_FORMAT
    1045             :                            ": error: Expected call to %s but received called() "
    1046             :                            "in %s\n",
    1047             :                            file, line,
    1048             :                            expected_call->function,
    1049             :                            function);
    1050           0 :             exit_test(1);
    1051             :         }
    1052             :     } else {
    1053           0 :         cm_print_error(SOURCE_LOCATION_FORMAT
    1054             :                        ": error: No mock calls expected but called() was "
    1055             :                        "invoked in %s\n",
    1056             :                        file, line,
    1057             :                        function);
    1058           0 :         exit_test(1);
    1059             :     }
    1060           0 : }
    1061             : 
    1062             : /* Add a return value for the specified mock function name. */
    1063         299 : void _will_return(const char * const function_name, const char * const file,
    1064             :                   const int line, const LargestIntegralType value,
    1065             :                   const int count) {
    1066         299 :     SymbolValue * const return_value =
    1067         299 :         (SymbolValue*)malloc(sizeof(*return_value));
    1068         299 :     assert_true(count != 0);
    1069         299 :     return_value->value = value;
    1070         299 :     set_source_location(&return_value->location, file, line);
    1071         299 :     add_symbol_value(&global_function_result_map_head, &function_name, 1,
    1072             :                      return_value, count);
    1073         299 : }
    1074             : 
    1075             : 
    1076             : /*
    1077             :  * Add a custom parameter checking function.  If the event parameter is NULL
    1078             :  * the event structure is allocated internally by this function.  If event
    1079             :  * parameter is provided it must be allocated on the heap and doesn't need to
    1080             :  * be deallocated by the caller.
    1081             :  */
    1082         109 : void _expect_check(
    1083             :         const char* const function, const char* const parameter,
    1084             :         const char* const file, const int line,
    1085             :         const CheckParameterValue check_function,
    1086             :         const LargestIntegralType check_data,
    1087             :         CheckParameterEvent * const event, const int count) {
    1088         218 :     CheckParameterEvent * const check =
    1089         109 :         event ? event : (CheckParameterEvent*)malloc(sizeof(*check));
    1090         109 :     const char* symbols[] = {function, parameter};
    1091         109 :     check->parameter_name = parameter;
    1092         109 :     check->check_value = check_function;
    1093         109 :     check->check_value_data = check_data;
    1094         109 :     set_source_location(&check->location, file, line);
    1095         109 :     add_symbol_value(&global_function_parameter_map_head, symbols, 2, check,
    1096             :                      count);
    1097         109 : }
    1098             : 
    1099             : /*
    1100             :  * Add an call expectations that a particular function is called correctly.
    1101             :  * This is used for code under test that makes calls to several functions
    1102             :  * in depended upon components (mocks).
    1103             :  */
    1104             : 
    1105           0 : void _expect_function_call(
    1106             :     const char * const function_name,
    1107             :     const char * const file,
    1108             :     const int line,
    1109             :     const int count)
    1110             : {
    1111           0 :     FuncOrderingValue *ordering;
    1112             : 
    1113           0 :     assert_non_null(function_name);
    1114           0 :     assert_non_null(file);
    1115           0 :     assert_true(count != 0);
    1116             : 
    1117           0 :     ordering = (FuncOrderingValue *)malloc(sizeof(*ordering));
    1118             : 
    1119           0 :     set_source_location(&ordering->location, file, line);
    1120           0 :     ordering->function = function_name;
    1121             : 
    1122           0 :     list_add_value(&global_call_ordering_head, ordering, count);
    1123           0 : }
    1124             : 
    1125             : /* Returns 1 if the specified values are equal.  If the values are not equal
    1126             :  * an error is displayed and 0 is returned. */
    1127       11552 : static int values_equal_display_error(const LargestIntegralType left,
    1128             :                                       const LargestIntegralType right) {
    1129       11552 :     const int equal = left == right;
    1130       11552 :     if (!equal) {
    1131           0 :         cm_print_error(LargestIntegralTypePrintfFormat " != "
    1132             :                        LargestIntegralTypePrintfFormat "\n", left, right);
    1133             :     }
    1134       11552 :     return equal;
    1135             : }
    1136             : 
    1137             : /*
    1138             :  * Returns 1 if the specified values are not equal.  If the values are equal
    1139             :  * an error is displayed and 0 is returned. */
    1140          77 : static int values_not_equal_display_error(const LargestIntegralType left,
    1141             :                                           const LargestIntegralType right) {
    1142          77 :     const int not_equal = left != right;
    1143          77 :     if (!not_equal) {
    1144           0 :         cm_print_error(LargestIntegralTypePrintfFormat " == "
    1145             :                        LargestIntegralTypePrintfFormat "\n", left, right);
    1146             :     }
    1147          77 :     return not_equal;
    1148             : }
    1149             : 
    1150             : 
    1151             : /*
    1152             :  * Determine whether value is contained within check_integer_set.
    1153             :  * If invert is 0 and the value is in the set 1 is returned, otherwise 0 is
    1154             :  * returned and an error is displayed.  If invert is 1 and the value is not
    1155             :  * in the set 1 is returned, otherwise 0 is returned and an error is
    1156             :  * displayed.
    1157             :  */
    1158          15 : static int value_in_set_display_error(
    1159             :         const LargestIntegralType value,
    1160             :         const CheckIntegerSet * const check_integer_set, const int invert) {
    1161          15 :     int succeeded = invert;
    1162          15 :     assert_non_null(check_integer_set);
    1163             :     {
    1164          15 :         const LargestIntegralType * const set = check_integer_set->set;
    1165          15 :         const size_t size_of_set = check_integer_set->size_of_set;
    1166          15 :         size_t i;
    1167          21 :         for (i = 0; i < size_of_set; i++) {
    1168          21 :             if (set[i] == value) {
    1169             :                 /* If invert = 0 and item is found, succeeded = 1. */
    1170             :                 /* If invert = 1 and item is found, succeeded = 0. */
    1171          15 :                 succeeded = !succeeded;
    1172          15 :                 break;
    1173             :             }
    1174             :         }
    1175          15 :         if (succeeded) {
    1176           0 :             return 1;
    1177             :         }
    1178           0 :         cm_print_error(LargestIntegralTypePrintfFormatDecimal
    1179             :                        " is %sin the set (",
    1180             :                        value, invert ? "" : "not ");
    1181           0 :         for (i = 0; i < size_of_set; i++) {
    1182           0 :             cm_print_error(LargestIntegralTypePrintfFormat ", ", set[i]);
    1183             :         }
    1184           0 :         cm_print_error(")\n");
    1185             :     }
    1186           0 :     return 0;
    1187             : }
    1188             : 
    1189             : 
    1190             : /*
    1191             :  * Determine whether a value is within the specified range.  If the value is
    1192             :  * within the specified range 1 is returned.  If the value isn't within the
    1193             :  * specified range an error is displayed and 0 is returned.
    1194             :  */
    1195         433 : static int integer_in_range_display_error(
    1196             :         const LargestIntegralType value, const LargestIntegralType range_min,
    1197             :         const LargestIntegralType range_max) {
    1198         433 :     if (value >= range_min && value <= range_max) {
    1199           2 :         return 1;
    1200             :     }
    1201           0 :     cm_print_error(LargestIntegralTypePrintfFormatDecimal
    1202             :                    " is not within the range "
    1203             :                    LargestIntegralTypePrintfFormatDecimal "-"
    1204             :                    LargestIntegralTypePrintfFormatDecimal "\n",
    1205             :                    value, range_min, range_max);
    1206           0 :     return 0;
    1207             : }
    1208             : 
    1209             : 
    1210             : /*
    1211             :  * Determine whether a value is within the specified range.  If the value
    1212             :  * is not within the range 1 is returned.  If the value is within the
    1213             :  * specified range an error is displayed and zero is returned.
    1214             :  */
    1215           0 : static int integer_not_in_range_display_error(
    1216             :         const LargestIntegralType value, const LargestIntegralType range_min,
    1217             :         const LargestIntegralType range_max) {
    1218           0 :     if (value < range_min || value > range_max) {
    1219           0 :         return 1;
    1220             :     }
    1221           0 :     cm_print_error(LargestIntegralTypePrintfFormatDecimal
    1222             :                    " is within the range "
    1223             :                    LargestIntegralTypePrintfFormatDecimal "-"
    1224             :                    LargestIntegralTypePrintfFormatDecimal "\n",
    1225             :                    value, range_min, range_max);
    1226           0 :     return 0;
    1227             : }
    1228             : 
    1229             : 
    1230             : /*
    1231             :  * Determine whether the specified strings are equal.  If the strings are equal
    1232             :  * 1 is returned.  If they're not equal an error is displayed and 0 is
    1233             :  * returned.
    1234             :  */
    1235         617 : static int string_equal_display_error(
    1236             :         const char * const left, const char * const right) {
    1237         617 :     if (strcmp(left, right) == 0) {
    1238         254 :         return 1;
    1239             :     }
    1240           0 :     cm_print_error("\"%s\" != \"%s\"\n", left, right);
    1241           0 :     return 0;
    1242             : }
    1243             : 
    1244             : 
    1245             : /*
    1246             :  * Determine whether the specified strings are equal.  If the strings are not
    1247             :  * equal 1 is returned.  If they're not equal an error is displayed and 0 is
    1248             :  * returned
    1249             :  */
    1250           6 : static int string_not_equal_display_error(
    1251             :         const char * const left, const char * const right) {
    1252           6 :     if (strcmp(left, right) != 0) {
    1253           0 :         return 1;
    1254             :     }
    1255           0 :     cm_print_error("\"%s\" == \"%s\"\n", left, right);
    1256           0 :     return 0;
    1257             : }
    1258             : 
    1259             : 
    1260             : /*
    1261             :  * Determine whether the specified areas of memory are equal.  If they're equal
    1262             :  * 1 is returned otherwise an error is displayed and 0 is returned.
    1263             :  */
    1264         718 : static int memory_equal_display_error(const char* const a, const char* const b,
    1265             :                                       const size_t size) {
    1266         718 :     size_t differences = 0;
    1267         521 :     size_t i;
    1268     1019061 :     for (i = 0; i < size; i++) {
    1269     1018343 :         const char l = a[i];
    1270     1018343 :         const char r = b[i];
    1271     1018343 :         if (l != r) {
    1272           0 :             if (differences < 16) {
    1273           0 :                 cm_print_error("difference at offset %" PRIdS " 0x%02x 0x%02x\n",
    1274             :                                i, l, r);
    1275             :             }
    1276           0 :             differences ++;
    1277             :         }
    1278             :     }
    1279         718 :     if (differences > 0) {
    1280           0 :         if (differences >= 16) {
    1281           0 :             cm_print_error("...\n");
    1282             :         }
    1283           0 :         cm_print_error("%"PRIdS " bytes of %p and %p differ\n",
    1284             :                        differences, (void *)a, (void *)b);
    1285           0 :         return 0;
    1286             :     }
    1287         197 :     return 1;
    1288             : }
    1289             : 
    1290             : 
    1291             : /*
    1292             :  * Determine whether the specified areas of memory are not equal.  If they're
    1293             :  * not equal 1 is returned otherwise an error is displayed and 0 is
    1294             :  * returned.
    1295             :  */
    1296           7 : static int memory_not_equal_display_error(
    1297             :         const char* const a, const char* const b, const size_t size) {
    1298           7 :     size_t same = 0;
    1299           7 :     size_t i;
    1300         595 :     for (i = 0; i < size; i++) {
    1301         588 :         const char l = a[i];
    1302         588 :         const char r = b[i];
    1303         588 :         if (l == r) {
    1304           2 :             same ++;
    1305             :         }
    1306             :     }
    1307           7 :     if (same == size) {
    1308           0 :         cm_print_error("%"PRIdS "bytes of %p and %p the same\n",
    1309             :                        same, (void *)a, (void *)b);
    1310           0 :         return 0;
    1311             :     }
    1312           0 :     return 1;
    1313             : }
    1314             : 
    1315             : 
    1316             : /* CheckParameterValue callback to check whether a value is within a set. */
    1317           0 : static int check_in_set(const LargestIntegralType value,
    1318             :                         const LargestIntegralType check_value_data) {
    1319           0 :     return value_in_set_display_error(value,
    1320           0 :         cast_largest_integral_type_to_pointer(CheckIntegerSet*,
    1321             :                                               check_value_data), 0);
    1322             : }
    1323             : 
    1324             : 
    1325             : /* CheckParameterValue callback to check whether a value isn't within a set. */
    1326           0 : static int check_not_in_set(const LargestIntegralType value,
    1327             :                             const LargestIntegralType check_value_data) {
    1328           0 :     return value_in_set_display_error(value,
    1329           0 :         cast_largest_integral_type_to_pointer(CheckIntegerSet*,
    1330             :                                               check_value_data), 1);
    1331             : }
    1332             : 
    1333             : 
    1334             : /* Create the callback data for check_in_set() or check_not_in_set() and
    1335             :  * register a check event. */
    1336           0 : static void expect_set(
    1337             :         const char* const function, const char* const parameter,
    1338             :         const char* const file, const int line,
    1339             :         const LargestIntegralType values[], const size_t number_of_values,
    1340             :         const CheckParameterValue check_function, const int count) {
    1341           0 :     CheckIntegerSet * const check_integer_set =
    1342           0 :         (CheckIntegerSet*)malloc(sizeof(*check_integer_set) +
    1343             :                (sizeof(values[0]) * number_of_values));
    1344           0 :     LargestIntegralType * const set = (LargestIntegralType*)(
    1345             :         check_integer_set + 1);
    1346           0 :     declare_initialize_value_pointer_pointer(check_data, check_integer_set);
    1347           0 :     assert_non_null(values);
    1348           0 :     assert_true(number_of_values);
    1349           0 :     memcpy(set, values, number_of_values * sizeof(values[0]));
    1350           0 :     check_integer_set->set = set;
    1351           0 :     check_integer_set->size_of_set = number_of_values;
    1352           0 :     _expect_check(
    1353             :         function, parameter, file, line, check_function,
    1354             :         check_data.value, &check_integer_set->event, count);
    1355           0 : }
    1356             : 
    1357             : 
    1358             : /* Add an event to check whether a value is in a set. */
    1359           0 : void _expect_in_set(
    1360             :         const char* const function, const char* const parameter,
    1361             :         const char* const file, const int line,
    1362             :         const LargestIntegralType values[], const size_t number_of_values,
    1363             :         const int count) {
    1364           0 :     expect_set(function, parameter, file, line, values, number_of_values,
    1365             :                check_in_set, count);
    1366           0 : }
    1367             : 
    1368             : 
    1369             : /* Add an event to check whether a value isn't in a set. */
    1370           0 : void _expect_not_in_set(
    1371             :         const char* const function, const char* const parameter,
    1372             :         const char* const file, const int line,
    1373             :         const LargestIntegralType values[], const size_t number_of_values,
    1374             :         const int count) {
    1375           0 :     expect_set(function, parameter, file, line, values, number_of_values,
    1376             :                check_not_in_set, count);
    1377           0 : }
    1378             : 
    1379             : 
    1380             : /* CheckParameterValue callback to check whether a value is within a range. */
    1381           0 : static int check_in_range(const LargestIntegralType value,
    1382             :                           const LargestIntegralType check_value_data) {
    1383           0 :     CheckIntegerRange * const check_integer_range =
    1384           0 :         cast_largest_integral_type_to_pointer(CheckIntegerRange*,
    1385             :                                               check_value_data);
    1386           0 :     assert_non_null(check_integer_range);
    1387           0 :     return integer_in_range_display_error(value, check_integer_range->minimum,
    1388             :                                           check_integer_range->maximum);
    1389             : }
    1390             : 
    1391             : 
    1392             : /* CheckParameterValue callback to check whether a value is not within a range. */
    1393           0 : static int check_not_in_range(const LargestIntegralType value,
    1394             :                               const LargestIntegralType check_value_data) {
    1395           0 :     CheckIntegerRange * const check_integer_range =
    1396           0 :         cast_largest_integral_type_to_pointer(CheckIntegerRange*,
    1397             :                                               check_value_data);
    1398           0 :     assert_non_null(check_integer_range);
    1399           0 :     return integer_not_in_range_display_error(
    1400             :         value, check_integer_range->minimum, check_integer_range->maximum);
    1401             : }
    1402             : 
    1403             : 
    1404             : /* Create the callback data for check_in_range() or check_not_in_range() and
    1405             :  * register a check event. */
    1406           0 : static void expect_range(
    1407             :         const char* const function, const char* const parameter,
    1408             :         const char* const file, const int line,
    1409             :         const LargestIntegralType minimum, const LargestIntegralType maximum,
    1410             :         const CheckParameterValue check_function, const int count) {
    1411           0 :     CheckIntegerRange * const check_integer_range =
    1412           0 :         (CheckIntegerRange*)malloc(sizeof(*check_integer_range));
    1413           0 :     declare_initialize_value_pointer_pointer(check_data, check_integer_range);
    1414           0 :     check_integer_range->minimum = minimum;
    1415           0 :     check_integer_range->maximum = maximum;
    1416           0 :     _expect_check(function, parameter, file, line, check_function,
    1417             :                   check_data.value, &check_integer_range->event, count);
    1418           0 : }
    1419             : 
    1420             : 
    1421             : /* Add an event to determine whether a parameter is within a range. */
    1422           0 : void _expect_in_range(
    1423             :         const char* const function, const char* const parameter,
    1424             :         const char* const file, const int line,
    1425             :         const LargestIntegralType minimum, const LargestIntegralType maximum,
    1426             :         const int count) {
    1427           0 :     expect_range(function, parameter, file, line, minimum, maximum,
    1428             :                  check_in_range, count);
    1429           0 : }
    1430             : 
    1431             : 
    1432             : /* Add an event to determine whether a parameter is not within a range. */
    1433           0 : void _expect_not_in_range(
    1434             :         const char* const function, const char* const parameter,
    1435             :         const char* const file, const int line,
    1436             :         const LargestIntegralType minimum, const LargestIntegralType maximum,
    1437             :         const int count) {
    1438           0 :     expect_range(function, parameter, file, line, minimum, maximum,
    1439             :                  check_not_in_range, count);
    1440           0 : }
    1441             : 
    1442             : 
    1443             : /* CheckParameterValue callback to check whether a value is equal to an
    1444             :  * expected value. */
    1445          30 : static int check_value(const LargestIntegralType value,
    1446             :                        const LargestIntegralType check_value_data) {
    1447          30 :     return values_equal_display_error(value, check_value_data);
    1448             : }
    1449             : 
    1450             : 
    1451             : /* Add an event to check a parameter equals an expected value. */
    1452          39 : void _expect_value(
    1453             :         const char* const function, const char* const parameter,
    1454             :         const char* const file, const int line,
    1455             :         const LargestIntegralType value, const int count) {
    1456          39 :     _expect_check(function, parameter, file, line, check_value, value, NULL,
    1457             :                   count);
    1458          39 : }
    1459             : 
    1460             : 
    1461             : /* CheckParameterValue callback to check whether a value is not equal to an
    1462             :  * expected value. */
    1463           0 : static int check_not_value(const LargestIntegralType value,
    1464             :                            const LargestIntegralType check_value_data) {
    1465           0 :     return values_not_equal_display_error(value, check_value_data);
    1466             : }
    1467             : 
    1468             : 
    1469             : /* Add an event to check a parameter is not equal to an expected value. */
    1470           0 : void _expect_not_value(
    1471             :         const char* const function, const char* const parameter,
    1472             :         const char* const file, const int line,
    1473             :         const LargestIntegralType value, const int count) {
    1474           0 :     _expect_check(function, parameter, file, line, check_not_value, value,
    1475             :                   NULL, count);
    1476           0 : }
    1477             : 
    1478             : 
    1479             : /* CheckParameterValue callback to check whether a parameter equals a string. */
    1480           2 : static int check_string(const LargestIntegralType value,
    1481             :                         const LargestIntegralType check_value_data) {
    1482           4 :     return string_equal_display_error(
    1483           2 :         cast_largest_integral_type_to_pointer(char*, value),
    1484           2 :         cast_largest_integral_type_to_pointer(char*, check_value_data));
    1485             : }
    1486             : 
    1487             : 
    1488             : /* Add an event to check whether a parameter is equal to a string. */
    1489           2 : void _expect_string(
    1490             :         const char* const function, const char* const parameter,
    1491             :         const char* const file, const int line, const char* string,
    1492             :         const int count) {
    1493           2 :     declare_initialize_value_pointer_pointer(string_pointer,
    1494             :                                              discard_const(string));
    1495           2 :     _expect_check(function, parameter, file, line, check_string,
    1496             :                   string_pointer.value, NULL, count);
    1497           2 : }
    1498             : 
    1499             : 
    1500             : /* CheckParameterValue callback to check whether a parameter is not equals to
    1501             :  * a string. */
    1502           0 : static int check_not_string(const LargestIntegralType value,
    1503             :                             const LargestIntegralType check_value_data) {
    1504           0 :     return string_not_equal_display_error(
    1505           0 :         cast_largest_integral_type_to_pointer(char*, value),
    1506           0 :         cast_largest_integral_type_to_pointer(char*, check_value_data));
    1507             : }
    1508             : 
    1509             : 
    1510             : /* Add an event to check whether a parameter is not equal to a string. */
    1511           0 : void _expect_not_string(
    1512             :         const char* const function, const char* const parameter,
    1513             :         const char* const file, const int line, const char* string,
    1514             :         const int count) {
    1515           0 :     declare_initialize_value_pointer_pointer(string_pointer,
    1516             :                                              discard_const(string));
    1517           0 :     _expect_check(function, parameter, file, line, check_not_string,
    1518             :                   string_pointer.value, NULL, count);
    1519           0 : }
    1520             : 
    1521             : /* CheckParameterValue callback to check whether a parameter equals an area of
    1522             :  * memory. */
    1523          12 : static int check_memory(const LargestIntegralType value,
    1524             :                         const LargestIntegralType check_value_data) {
    1525          12 :     CheckMemoryData * const check = cast_largest_integral_type_to_pointer(
    1526             :         CheckMemoryData*, check_value_data);
    1527          12 :     assert_non_null(check);
    1528          24 :     return memory_equal_display_error(
    1529          12 :         cast_largest_integral_type_to_pointer(const char*, value),
    1530          12 :         (const char*)check->memory, check->size);
    1531             : }
    1532             : 
    1533             : 
    1534             : /* Create the callback data for check_memory() or check_not_memory() and
    1535             :  * register a check event. */
    1536          18 : static void expect_memory_setup(
    1537             :         const char* const function, const char* const parameter,
    1538             :         const char* const file, const int line,
    1539             :         const void * const memory, const size_t size,
    1540             :         const CheckParameterValue check_function, const int count) {
    1541          18 :     CheckMemoryData * const check_data =
    1542          18 :         (CheckMemoryData*)malloc(sizeof(*check_data) + size);
    1543          18 :     void * const mem = (void*)(check_data + 1);
    1544          18 :     declare_initialize_value_pointer_pointer(check_data_pointer, check_data);
    1545          18 :     assert_non_null(memory);
    1546          18 :     assert_true(size);
    1547          18 :     memcpy(mem, memory, size);
    1548          18 :     check_data->memory = mem;
    1549          18 :     check_data->size = size;
    1550          18 :     _expect_check(function, parameter, file, line, check_function,
    1551             :                   check_data_pointer.value, &check_data->event, count);
    1552          18 : }
    1553             : 
    1554             : 
    1555             : /* Add an event to check whether a parameter matches an area of memory. */
    1556          18 : void _expect_memory(
    1557             :         const char* const function, const char* const parameter,
    1558             :         const char* const file, const int line, const void* const memory,
    1559             :         const size_t size, const int count) {
    1560          18 :     expect_memory_setup(function, parameter, file, line, memory, size,
    1561             :                         check_memory, count);
    1562          18 : }
    1563             : 
    1564             : 
    1565             : /* CheckParameterValue callback to check whether a parameter is not equal to
    1566             :  * an area of memory. */
    1567           0 : static int check_not_memory(const LargestIntegralType value,
    1568             :                             const LargestIntegralType check_value_data) {
    1569           0 :     CheckMemoryData * const check = cast_largest_integral_type_to_pointer(
    1570             :         CheckMemoryData*, check_value_data);
    1571           0 :     assert_non_null(check);
    1572           0 :     return memory_not_equal_display_error(
    1573           0 :         cast_largest_integral_type_to_pointer(const char*, value),
    1574           0 :         (const char*)check->memory,
    1575             :         check->size);
    1576             : }
    1577             : 
    1578             : 
    1579             : /* Add an event to check whether a parameter doesn't match an area of memory. */
    1580           0 : void _expect_not_memory(
    1581             :         const char* const function, const char* const parameter,
    1582             :         const char* const file, const int line, const void* const memory,
    1583             :         const size_t size, const int count) {
    1584           0 :     expect_memory_setup(function, parameter, file, line, memory, size,
    1585             :                         check_not_memory, count);
    1586           0 : }
    1587             : 
    1588             : 
    1589             : /* CheckParameterValue callback that always returns 1. */
    1590           0 : static int check_any(const LargestIntegralType value,
    1591             :                      const LargestIntegralType check_value_data) {
    1592           0 :     (void)value;
    1593           0 :     (void)check_value_data;
    1594           0 :     return 1;
    1595             : }
    1596             : 
    1597             : 
    1598             : /* Add an event to allow any value for a parameter. */
    1599           0 : void _expect_any(
    1600             :         const char* const function, const char* const parameter,
    1601             :         const char* const file, const int line, const int count) {
    1602           0 :     _expect_check(function, parameter, file, line, check_any, 0, NULL,
    1603             :                   count);
    1604           0 : }
    1605             : 
    1606             : 
    1607          94 : void _check_expected(
    1608             :         const char * const function_name, const char * const parameter_name,
    1609             :         const char* file, const int line, const LargestIntegralType value) {
    1610          94 :     void *result = NULL;
    1611          94 :     const char* symbols[] = {function_name, parameter_name};
    1612          94 :     const int rc = get_symbol_value(&global_function_parameter_map_head,
    1613             :                                     symbols, 2, &result);
    1614          94 :     if (rc) {
    1615          94 :         CheckParameterEvent * const check = (CheckParameterEvent*)result;
    1616          94 :         int check_succeeded;
    1617          94 :         global_last_parameter_location = check->location;
    1618          94 :         check_succeeded = check->check_value(value, check->check_value_data);
    1619          94 :         if (rc == 1) {
    1620          94 :             free(check);
    1621             :         }
    1622          94 :         if (!check_succeeded) {
    1623           0 :             cm_print_error(SOURCE_LOCATION_FORMAT
    1624             :                            ": error: Check of parameter %s, function %s failed\n"
    1625             :                            SOURCE_LOCATION_FORMAT
    1626             :                            ": note: Expected parameter declared here\n",
    1627             :                            file, line,
    1628             :                            parameter_name, function_name,
    1629             :                            global_last_parameter_location.file,
    1630             :                            global_last_parameter_location.line);
    1631           0 :             _fail(file, line);
    1632             :         }
    1633             :     } else {
    1634           0 :         cm_print_error(SOURCE_LOCATION_FORMAT ": error: Could not get value "
    1635             :                     "to check parameter %s of function %s\n", file, line,
    1636             :                     parameter_name, function_name);
    1637           0 :         if (source_location_is_set(&global_last_parameter_location)) {
    1638           0 :             cm_print_error(SOURCE_LOCATION_FORMAT
    1639             :                         ": note: Previously declared parameter value was declared here\n",
    1640             :                         global_last_parameter_location.file,
    1641             :                         global_last_parameter_location.line);
    1642             :         } else {
    1643           0 :             cm_print_error("There were no previously declared parameter values "
    1644             :                         "for this test.\n");
    1645             :         }
    1646           0 :         exit_test(1);
    1647             :     }
    1648          94 : }
    1649             : 
    1650             : 
    1651             : /* Replacement for assert. */
    1652           0 : void mock_assert(const int result, const char* const expression,
    1653             :                  const char* const file, const int line) {
    1654           0 :     if (!result) {
    1655           0 :         if (global_expecting_assert) {
    1656           0 :             global_last_failed_assert = expression;
    1657           0 :             longjmp(global_expect_assert_env, result);
    1658             :         } else {
    1659           0 :             cm_print_error("ASSERT: %s\n", expression);
    1660           0 :             _fail(file, line);
    1661             :         }
    1662             :     }
    1663           0 : }
    1664             : 
    1665             : 
    1666     5597642 : void _assert_true(const LargestIntegralType result,
    1667             :                   const char * const expression,
    1668             :                   const char * const file, const int line) {
    1669     5597642 :     if (!result) {
    1670           0 :         cm_print_error("%s\n", expression);
    1671           0 :         _fail(file, line);
    1672             :     }
    1673     5597642 : }
    1674             : 
    1675         124 : void _assert_return_code(const LargestIntegralType result,
    1676             :                          size_t rlen,
    1677             :                          const LargestIntegralType error,
    1678             :                          const char * const expression,
    1679             :                          const char * const file,
    1680             :                          const int line)
    1681             : {
    1682         124 :     LargestIntegralType valmax;
    1683             : 
    1684             : 
    1685         124 :     switch (rlen) {
    1686           0 :     case 1:
    1687           0 :         valmax = 255;
    1688           0 :         break;
    1689           0 :     case 2:
    1690           0 :         valmax = 32767;
    1691           0 :         break;
    1692         124 :     case 4:
    1693         124 :         valmax = 2147483647;
    1694         124 :         break;
    1695           0 :     case 8:
    1696             :     default:
    1697           0 :         if (rlen > sizeof(valmax)) {
    1698           0 :             valmax = 2147483647;
    1699             :         } else {
    1700           0 :             valmax = 9223372036854775807L;
    1701             :         }
    1702           0 :         break;
    1703             :     }
    1704             : 
    1705         124 :     if (result > valmax - 1) {
    1706           0 :         if (error > 0) {
    1707           0 :             cm_print_error("%s < 0, errno("
    1708             :                            LargestIntegralTypePrintfFormatDecimal "): %s\n",
    1709             :                            expression, error, strerror((int)error));
    1710             :         } else {
    1711           0 :             cm_print_error("%s < 0\n", expression);
    1712             :         }
    1713           0 :         _fail(file, line);
    1714             :     }
    1715         124 : }
    1716             : 
    1717       11522 : void _assert_int_equal(
    1718             :         const LargestIntegralType a, const LargestIntegralType b,
    1719             :         const char * const file, const int line) {
    1720       11522 :     if (!values_equal_display_error(a, b)) {
    1721           0 :         _fail(file, line);
    1722             :     }
    1723       11522 : }
    1724             : 
    1725             : 
    1726          77 : void _assert_int_not_equal(
    1727             :         const LargestIntegralType a, const LargestIntegralType b,
    1728             :         const char * const file, const int line) {
    1729          77 :     if (!values_not_equal_display_error(a, b)) {
    1730           0 :         _fail(file, line);
    1731             :     }
    1732          77 : }
    1733             : 
    1734             : 
    1735         615 : void _assert_string_equal(const char * const a, const char * const b,
    1736             :                           const char * const file, const int line) {
    1737         615 :     if (!string_equal_display_error(a, b)) {
    1738           0 :         _fail(file, line);
    1739             :     }
    1740         615 : }
    1741             : 
    1742             : 
    1743           6 : void _assert_string_not_equal(const char * const a, const char * const b,
    1744             :                               const char *file, const int line) {
    1745           6 :     if (!string_not_equal_display_error(a, b)) {
    1746           0 :         _fail(file, line);
    1747             :     }
    1748           6 : }
    1749             : 
    1750             : 
    1751         706 : void _assert_memory_equal(const void * const a, const void * const b,
    1752             :                           const size_t size, const char* const file,
    1753             :                           const int line) {
    1754         706 :     if (!memory_equal_display_error((const char*)a, (const char*)b, size)) {
    1755           0 :         _fail(file, line);
    1756             :     }
    1757         706 : }
    1758             : 
    1759             : 
    1760           7 : void _assert_memory_not_equal(const void * const a, const void * const b,
    1761             :                               const size_t size, const char* const file,
    1762             :                               const int line) {
    1763           7 :     if (!memory_not_equal_display_error((const char*)a, (const char*)b,
    1764             :                                         size)) {
    1765           0 :         _fail(file, line);
    1766             :     }
    1767           7 : }
    1768             : 
    1769             : 
    1770         433 : void _assert_in_range(
    1771             :         const LargestIntegralType value, const LargestIntegralType minimum,
    1772             :         const LargestIntegralType maximum, const char* const file,
    1773             :         const int line) {
    1774         433 :     if (!integer_in_range_display_error(value, minimum, maximum)) {
    1775           0 :         _fail(file, line);
    1776             :     }
    1777         433 : }
    1778             : 
    1779           0 : void _assert_not_in_range(
    1780             :         const LargestIntegralType value, const LargestIntegralType minimum,
    1781             :         const LargestIntegralType maximum, const char* const file,
    1782             :         const int line) {
    1783           0 :     if (!integer_not_in_range_display_error(value, minimum, maximum)) {
    1784           0 :         _fail(file, line);
    1785             :     }
    1786           0 : }
    1787             : 
    1788          15 : void _assert_in_set(const LargestIntegralType value,
    1789             :                     const LargestIntegralType values[],
    1790             :                     const size_t number_of_values, const char* const file,
    1791             :                     const int line) {
    1792          15 :     CheckIntegerSet check_integer_set;
    1793          15 :     check_integer_set.set = values;
    1794          15 :     check_integer_set.size_of_set = number_of_values;
    1795          15 :     if (!value_in_set_display_error(value, &check_integer_set, 0)) {
    1796           0 :         _fail(file, line);
    1797             :     }
    1798          15 : }
    1799             : 
    1800           0 : void _assert_not_in_set(const LargestIntegralType value,
    1801             :                         const LargestIntegralType values[],
    1802             :                         const size_t number_of_values, const char* const file,
    1803             :                         const int line) {
    1804           0 :     CheckIntegerSet check_integer_set;
    1805           0 :     check_integer_set.set = values;
    1806           0 :     check_integer_set.size_of_set = number_of_values;
    1807           0 :     if (!value_in_set_display_error(value, &check_integer_set, 1)) {
    1808           0 :         _fail(file, line);
    1809             :     }
    1810           0 : }
    1811             : 
    1812             : 
    1813             : /* Get the list of allocated blocks. */
    1814        2319 : static ListNode* get_allocated_blocks_list(void) {
    1815             :     /* If it initialized, initialize the list of allocated blocks. */
    1816        2319 :     if (!global_allocated_blocks.value) {
    1817          81 :         list_initialize(&global_allocated_blocks);
    1818          81 :         global_allocated_blocks.value = (void*)1;
    1819             :     }
    1820        2319 :     return &global_allocated_blocks;
    1821             : }
    1822             : 
    1823          81 : static void *libc_malloc(size_t size)
    1824             : {
    1825             : #undef malloc
    1826          81 :     return malloc(size);
    1827             : #define malloc test_malloc
    1828             : }
    1829             : 
    1830         816 : static void libc_free(void *ptr)
    1831             : {
    1832             : #undef free
    1833         816 :     free(ptr);
    1834             : #define free test_free
    1835         228 : }
    1836             : 
    1837           0 : static void *libc_realloc(void *ptr, size_t size)
    1838             : {
    1839             : #undef realloc
    1840           0 :     return realloc(ptr, size);
    1841             : #define realloc test_realloc
    1842             : }
    1843             : 
    1844             : static void vcm_print_error(const char* const format,
    1845             :                             va_list args) CMOCKA_PRINTF_ATTRIBUTE(1, 0);
    1846             : 
    1847             : /* It's important to use the libc malloc and free here otherwise
    1848             :  * the automatic free of leaked blocks can reap the error messages
    1849             :  */
    1850           0 : static void vcm_print_error(const char* const format, va_list args)
    1851             : {
    1852           0 :     char buffer[1024];
    1853           0 :     size_t msg_len = 0;
    1854           0 :     va_list ap;
    1855           0 :     int len;
    1856           0 :     va_copy(ap, args);
    1857             : 
    1858           0 :     len = vsnprintf(buffer, sizeof(buffer), format, args);
    1859           0 :     if (len < 0) {
    1860             :         /* TODO */
    1861           0 :         goto end;
    1862             :     }
    1863             : 
    1864           0 :     if (cm_error_message == NULL) {
    1865             :         /* CREATE MESSAGE */
    1866             : 
    1867           0 :         cm_error_message = libc_malloc(len + 1);
    1868           0 :         if (cm_error_message == NULL) {
    1869             :             /* TODO */
    1870           0 :             goto end;
    1871             :         }
    1872             :     } else {
    1873             :         /* APPEND MESSAGE */
    1874           0 :         char *tmp;
    1875             : 
    1876           0 :         msg_len = strlen(cm_error_message);
    1877           0 :         tmp = libc_realloc(cm_error_message, msg_len + len + 1);
    1878           0 :         if (tmp == NULL) {
    1879           0 :             goto end;
    1880             :         }
    1881           0 :         cm_error_message = tmp;
    1882             :     }
    1883             : 
    1884           0 :     if (((size_t)len) < sizeof(buffer)) {
    1885             :         /* Use len + 1 to also copy '\0' */
    1886           0 :         memcpy(cm_error_message + msg_len, buffer, len + 1);
    1887             :     } else {
    1888           0 :         vsnprintf(cm_error_message + msg_len, len, format, ap);
    1889             :     }
    1890           0 : end:
    1891           0 :     va_end(ap);
    1892             : 
    1893           0 : }
    1894             : 
    1895         735 : static void vcm_free_error(char *err_msg)
    1896             : {
    1897         735 :     libc_free(err_msg);
    1898         212 : }
    1899             : 
    1900             : /* Use the real malloc in this function. */
    1901             : #undef malloc
    1902           0 : void* _test_malloc(const size_t size, const char* file, const int line) {
    1903           0 :     char *ptr = NULL;
    1904           0 :     MallocBlockInfo block_info;
    1905           0 :     ListNode * const block_list = get_allocated_blocks_list();
    1906           0 :     size_t allocate_size;
    1907           0 :     char *block = NULL;
    1908             : 
    1909           0 :     allocate_size = size + (MALLOC_GUARD_SIZE * 2) +
    1910             :                     sizeof(struct MallocBlockInfoData) + MALLOC_ALIGNMENT;
    1911           0 :     assert_true(allocate_size > size);
    1912             : 
    1913           0 :     block = (char *)malloc(allocate_size);
    1914           0 :     assert_non_null(block);
    1915             : 
    1916             :     /* Calculate the returned address. */
    1917           0 :     ptr = (char*)(((size_t)block + MALLOC_GUARD_SIZE +
    1918           0 :                   sizeof(struct MallocBlockInfoData) +
    1919           0 :                   MALLOC_ALIGNMENT) & ~(MALLOC_ALIGNMENT - 1));
    1920             : 
    1921             :     /* Initialize the guard blocks. */
    1922           0 :     memset(ptr - MALLOC_GUARD_SIZE, MALLOC_GUARD_PATTERN, MALLOC_GUARD_SIZE);
    1923           0 :     memset(ptr + size, MALLOC_GUARD_PATTERN, MALLOC_GUARD_SIZE);
    1924           0 :     memset(ptr, MALLOC_ALLOC_PATTERN, size);
    1925             : 
    1926           0 :     block_info.ptr = ptr - (MALLOC_GUARD_SIZE +
    1927             :                             sizeof(struct MallocBlockInfoData));
    1928           0 :     set_source_location(&block_info.data->location, file, line);
    1929           0 :     block_info.data->allocated_size = allocate_size;
    1930           0 :     block_info.data->size = size;
    1931           0 :     block_info.data->block = block;
    1932           0 :     block_info.data->node.value = block_info.ptr;
    1933           0 :     list_add(block_list, &block_info.data->node);
    1934           0 :     return ptr;
    1935             : }
    1936             : #define malloc test_malloc
    1937             : 
    1938             : 
    1939           0 : void* _test_calloc(const size_t number_of_elements, const size_t size,
    1940             :                    const char* file, const int line) {
    1941           0 :     void* const ptr = _test_malloc(number_of_elements * size, file, line);
    1942           0 :     if (ptr) {
    1943           0 :         memset(ptr, 0, number_of_elements * size);
    1944             :     }
    1945           0 :     return ptr;
    1946             : }
    1947             : 
    1948             : 
    1949             : /* Use the real free in this function. */
    1950             : #undef free
    1951           0 : void _test_free(void* const ptr, const char* file, const int line) {
    1952           0 :     unsigned int i;
    1953           0 :     char *block = discard_const_p(char, ptr);
    1954           0 :     MallocBlockInfo block_info;
    1955             : 
    1956           0 :     if (ptr == NULL) {
    1957           0 :         return;
    1958             :     }
    1959             : 
    1960           0 :     _assert_true(cast_ptr_to_largest_integral_type(ptr), "ptr", file, line);
    1961           0 :     block_info.ptr = block - (MALLOC_GUARD_SIZE +
    1962             :                               sizeof(struct MallocBlockInfoData));
    1963             :     /* Check the guard blocks. */
    1964             :     {
    1965           0 :         char *guards[2] = {block - MALLOC_GUARD_SIZE,
    1966           0 :                            block + block_info.data->size};
    1967           0 :         for (i = 0; i < ARRAY_SIZE(guards); i++) {
    1968           0 :             unsigned int j;
    1969           0 :             char * const guard = guards[i];
    1970           0 :             for (j = 0; j < MALLOC_GUARD_SIZE; j++) {
    1971           0 :                 const char diff = guard[j] - MALLOC_GUARD_PATTERN;
    1972           0 :                 if (diff) {
    1973           0 :                     cm_print_error(SOURCE_LOCATION_FORMAT
    1974             :                                    ": error: Guard block of %p size=%lu is corrupt\n"
    1975             :                                    SOURCE_LOCATION_FORMAT ": note: allocated here at %p\n",
    1976             :                                    file,
    1977             :                                    line,
    1978             :                                    ptr,
    1979           0 :                                    (unsigned long)block_info.data->size,
    1980           0 :                                    block_info.data->location.file,
    1981           0 :                                    block_info.data->location.line,
    1982           0 :                                    (void *)&guard[j]);
    1983           0 :                     _fail(file, line);
    1984             :                 }
    1985             :             }
    1986             :         }
    1987             :     }
    1988           0 :     list_remove(&block_info.data->node, NULL, NULL);
    1989             : 
    1990           0 :     block = discard_const_p(char, block_info.data->block);
    1991           0 :     memset(block, MALLOC_FREE_PATTERN, block_info.data->allocated_size);
    1992           0 :     free(block);
    1993             : }
    1994             : #define free test_free
    1995             : 
    1996             : #undef realloc
    1997           0 : void *_test_realloc(void *ptr,
    1998             :                    const size_t size,
    1999             :                    const char *file,
    2000             :                    const int line)
    2001             : {
    2002           0 :     MallocBlockInfo block_info;
    2003           0 :     char *block = ptr;
    2004           0 :     size_t block_size = size;
    2005           0 :     void *new_block;
    2006             : 
    2007           0 :     if (ptr == NULL) {
    2008           0 :         return _test_malloc(size, file, line);
    2009             :     }
    2010             : 
    2011           0 :     if (size == 0) {
    2012           0 :         _test_free(ptr, file, line);
    2013           0 :         return NULL;
    2014             :     }
    2015             : 
    2016           0 :     block_info.ptr = block - (MALLOC_GUARD_SIZE +
    2017             :                               sizeof(struct MallocBlockInfoData));
    2018             : 
    2019           0 :     new_block = _test_malloc(size, file, line);
    2020           0 :     if (new_block == NULL) {
    2021           0 :         return NULL;
    2022             :     }
    2023             : 
    2024           0 :     if (block_info.data->size < size) {
    2025           0 :         block_size = block_info.data->size;
    2026             :     }
    2027             : 
    2028           0 :     memcpy(new_block, ptr, block_size);
    2029             : 
    2030             :     /* Free previous memory */
    2031           0 :     _test_free(ptr, file, line);
    2032             : 
    2033           0 :     return new_block;
    2034             : }
    2035             : #define realloc test_realloc
    2036             : 
    2037             : /* Crudely checkpoint the current heap state. */
    2038        1156 : static const ListNode* check_point_allocated_blocks(void) {
    2039         960 :     return get_allocated_blocks_list()->prev;
    2040             : }
    2041             : 
    2042             : 
    2043             : /* Display the blocks allocated after the specified check point.  This
    2044             :  * function returns the number of blocks displayed. */
    2045        1163 : static size_t display_allocated_blocks(const ListNode * const check_point) {
    2046        1163 :     const ListNode * const head = get_allocated_blocks_list();
    2047         729 :     const ListNode *node;
    2048        1163 :     size_t allocated_blocks = 0;
    2049        1163 :     assert_non_null(check_point);
    2050        1163 :     assert_non_null(check_point->next);
    2051             : 
    2052        1163 :     for (node = check_point->next; node != head; node = node->next) {
    2053           0 :         const MallocBlockInfo block_info = {
    2054           0 :             .ptr = discard_const(node->value),
    2055             :         };
    2056           0 :         assert_non_null(block_info.ptr);
    2057             : 
    2058           0 :         if (allocated_blocks == 0) {
    2059           0 :             cm_print_error("Blocks allocated...\n");
    2060             :         }
    2061           0 :         cm_print_error(SOURCE_LOCATION_FORMAT ": note: block %p allocated here\n",
    2062           0 :                        block_info.data->location.file,
    2063           0 :                        block_info.data->location.line,
    2064           0 :                        block_info.data->block);
    2065           0 :         allocated_blocks++;
    2066             :     }
    2067        1163 :     return allocated_blocks;
    2068             : }
    2069             : 
    2070             : 
    2071             : /* Free all blocks allocated after the specified check point. */
    2072           0 : static void free_allocated_blocks(const ListNode * const check_point) {
    2073           0 :     const ListNode * const head = get_allocated_blocks_list();
    2074           0 :     const ListNode *node;
    2075           0 :     assert_non_null(check_point);
    2076             : 
    2077           0 :     node = check_point->next;
    2078           0 :     assert_non_null(node);
    2079             : 
    2080           0 :     while (node != head) {
    2081           0 :         const MallocBlockInfo block_info = {
    2082           0 :             .ptr = discard_const(node->value),
    2083             :         };
    2084           0 :         node = node->next;
    2085           0 :         free(discard_const_p(char, block_info.data) +
    2086             :              sizeof(struct MallocBlockInfoData) +
    2087             :              MALLOC_GUARD_SIZE);
    2088             :     }
    2089           0 : }
    2090             : 
    2091             : 
    2092             : /* Fail if any any blocks are allocated after the specified check point. */
    2093        1163 : static void fail_if_blocks_allocated(const ListNode * const check_point,
    2094             :                                      const char * const test_name) {
    2095        1163 :     const size_t allocated_blocks = display_allocated_blocks(check_point);
    2096        1163 :     if (allocated_blocks > 0) {
    2097           0 :         free_allocated_blocks(check_point);
    2098           0 :         cm_print_error("ERROR: %s leaked %zu block(s)\n", test_name,
    2099             :                        allocated_blocks);
    2100           0 :         exit_test(1);
    2101             :     }
    2102        1163 : }
    2103             : 
    2104             : 
    2105           0 : void _fail(const char * const file, const int line) {
    2106           0 :     enum cm_message_output output = cm_get_output();
    2107             : 
    2108           0 :     switch(output) {
    2109           0 :         case CM_OUTPUT_STDOUT:
    2110           0 :             cm_print_error("[   LINE   ] --- " SOURCE_LOCATION_FORMAT ": error: Failure!", file, line);
    2111           0 :             break;
    2112           0 :         default:
    2113           0 :             cm_print_error(SOURCE_LOCATION_FORMAT ": error: Failure!", file, line);
    2114           0 :             break;
    2115             :     }
    2116           0 :     exit_test(1);
    2117           0 : }
    2118             : 
    2119             : 
    2120             : #ifndef _WIN32
    2121           0 : static void exception_handler(int sig) {
    2122           0 :     const char *sig_strerror = "";
    2123             : 
    2124             : #ifdef HAVE_STRSIGNAL
    2125           0 :     sig_strerror = strsignal(sig);
    2126             : #endif
    2127             : 
    2128           0 :     cm_print_error("Test failed with exception: %s(%d)",
    2129             :                    sig_strerror, sig);
    2130           0 :     exit_test(1);
    2131           0 : }
    2132             : 
    2133             : #else /* _WIN32 */
    2134             : 
    2135             : static LONG WINAPI exception_filter(EXCEPTION_POINTERS *exception_pointers) {
    2136             :     EXCEPTION_RECORD * const exception_record =
    2137             :         exception_pointers->ExceptionRecord;
    2138             :     const DWORD code = exception_record->ExceptionCode;
    2139             :     unsigned int i;
    2140             :     for (i = 0; i < ARRAY_SIZE(exception_codes); i++) {
    2141             :         const ExceptionCodeInfo * const code_info = &exception_codes[i];
    2142             :         if (code == code_info->code) {
    2143             :             static int shown_debug_message = 0;
    2144             :             fflush(stdout);
    2145             :             cm_print_error("%s occurred at %p.\n", code_info->description,
    2146             :                         exception_record->ExceptionAddress);
    2147             :             if (!shown_debug_message) {
    2148             :                 cm_print_error(
    2149             :                     "\n"
    2150             :                     "To debug in Visual Studio...\n"
    2151             :                     "1. Select menu item File->Open Project\n"
    2152             :                     "2. Change 'Files of type' to 'Executable Files'\n"
    2153             :                     "3. Open this executable.\n"
    2154             :                     "4. Select menu item Debug->Start\n"
    2155             :                     "\n"
    2156             :                     "Alternatively, set the environment variable \n"
    2157             :                     "UNIT_TESTING_DEBUG to 1 and rebuild this executable, \n"
    2158             :                     "then click 'Debug' in the popup dialog box.\n"
    2159             :                     "\n");
    2160             :                 shown_debug_message = 1;
    2161             :             }
    2162             :             exit_test(0);
    2163             :             return EXCEPTION_EXECUTE_HANDLER;
    2164             :         }
    2165             :     }
    2166             :     return EXCEPTION_CONTINUE_SEARCH;
    2167             : }
    2168             : #endif /* !_WIN32 */
    2169             : 
    2170           0 : void cm_print_error(const char * const format, ...)
    2171             : {
    2172           0 :     va_list args;
    2173           0 :     va_start(args, format);
    2174           0 :     if (cm_error_message_enabled) {
    2175           0 :         vcm_print_error(format, args);
    2176             :     } else {
    2177           0 :         vprint_error(format, args);
    2178             :     }
    2179           0 :     va_end(args);
    2180           0 : }
    2181             : 
    2182             : /* Standard output and error print methods. */
    2183        1616 : void vprint_message(const char* const format, va_list args) {
    2184        1166 :     char buffer[1024];
    2185        1616 :     vsnprintf(buffer, sizeof(buffer), format, args);
    2186        1616 :     printf("%s", buffer);
    2187        1616 :     fflush(stdout);
    2188             : #ifdef _WIN32
    2189             :     OutputDebugString(buffer);
    2190             : #endif /* _WIN32 */
    2191        1616 : }
    2192             : 
    2193             : 
    2194          27 : void vprint_error(const char* const format, va_list args) {
    2195           0 :     char buffer[1024];
    2196          27 :     vsnprintf(buffer, sizeof(buffer), format, args);
    2197          27 :     fprintf(stderr, "%s", buffer);
    2198          27 :     fflush(stderr);
    2199             : #ifdef _WIN32
    2200             :     OutputDebugString(buffer);
    2201             : #endif /* _WIN32 */
    2202          27 : }
    2203             : 
    2204             : 
    2205        1616 : void print_message(const char* const format, ...) {
    2206        1166 :     va_list args;
    2207        1616 :     va_start(args, format);
    2208        1616 :     vprint_message(format, args);
    2209        1616 :     va_end(args);
    2210        1616 : }
    2211             : 
    2212             : 
    2213          27 : void print_error(const char* const format, ...) {
    2214           0 :     va_list args;
    2215          27 :     va_start(args, format);
    2216          27 :     vprint_error(format, args);
    2217          27 :     va_end(args);
    2218          27 : }
    2219             : 
    2220             : /* New formatter */
    2221        1632 : static enum cm_message_output cm_get_output(void)
    2222             : {
    2223        1632 :     enum cm_message_output output = global_msg_output;
    2224        1176 :     char *env;
    2225             : 
    2226        1632 :     env = getenv("CMOCKA_MESSAGE_OUTPUT");
    2227        1632 :     if (env != NULL) {
    2228           0 :         if (strcasecmp(env, "STDOUT") == 0) {
    2229           0 :             output = CM_OUTPUT_STDOUT;
    2230           0 :         } else if (strcasecmp(env, "SUBUNIT") == 0) {
    2231           0 :             output = CM_OUTPUT_SUBUNIT;
    2232           0 :         } else if (strcasecmp(env, "TAP") == 0) {
    2233           0 :             output = CM_OUTPUT_TAP;
    2234           0 :         } else if (strcasecmp(env, "XML") == 0) {
    2235           0 :             output = CM_OUTPUT_XML;
    2236             :         }
    2237             :     }
    2238             : 
    2239        1632 :     return output;
    2240             : }
    2241             : 
    2242             : enum cm_printf_type {
    2243             :     PRINTF_TEST_START,
    2244             :     PRINTF_TEST_SUCCESS,
    2245             :     PRINTF_TEST_FAILURE,
    2246             :     PRINTF_TEST_ERROR,
    2247             :     PRINTF_TEST_SKIPPED,
    2248             : };
    2249             : 
    2250             : static int xml_printed;
    2251             : static int file_append;
    2252             : 
    2253           0 : static void cmprintf_group_finish_xml(const char *group_name,
    2254             :                                       size_t total_executed,
    2255             :                                       size_t total_failed,
    2256             :                                       size_t total_errors,
    2257             :                                       size_t total_skipped,
    2258             :                                       double total_runtime,
    2259             :                                       struct CMUnitTestState *cm_tests)
    2260             : {
    2261           0 :     FILE *fp = stdout;
    2262           0 :     int file_opened = 0;
    2263           0 :     int multiple_files = 0;
    2264           0 :     char *env;
    2265           0 :     size_t i;
    2266             : 
    2267           0 :     env = getenv("CMOCKA_XML_FILE");
    2268           0 :     if (env != NULL) {
    2269           0 :         char buf[1024];
    2270           0 :         int rc;
    2271             : 
    2272           0 :         snprintf(buf, sizeof(buf), "%s", env);
    2273             : 
    2274           0 :         rc = c_strreplace(buf, sizeof(buf), "%g", group_name, &multiple_files);
    2275           0 :         if (rc < 0) {
    2276           0 :             snprintf(buf, sizeof(buf), "%s", env);
    2277             :         }
    2278             : 
    2279           0 :         fp = fopen(buf, "r");
    2280           0 :         if (fp == NULL) {
    2281           0 :             fp = fopen(buf, "w");
    2282           0 :             if (fp != NULL) {
    2283           0 :                 file_append = 1;
    2284           0 :                 file_opened = 1;
    2285             :             } else {
    2286           0 :                 fp = stderr;
    2287             :             }
    2288             :         } else {
    2289           0 :             fclose(fp);
    2290           0 :             if (file_append) {
    2291           0 :                 fp = fopen(buf, "a");
    2292           0 :                 if (fp != NULL) {
    2293           0 :                     file_opened = 1;
    2294           0 :                     xml_printed = 1;
    2295             :                 } else {
    2296           0 :                     fp = stderr;
    2297             :                 }
    2298             :             } else {
    2299           0 :                 fp = stderr;
    2300             :             }
    2301             :         }
    2302             :     }
    2303             : 
    2304           0 :     if (!xml_printed || (file_opened && !file_append)) {
    2305           0 :         fprintf(fp, "<?xml version=\"1.0\" encoding=\"UTF-8\" ?>\n");
    2306           0 :         if (!file_opened) {
    2307           0 :             xml_printed = 1;
    2308             :         }
    2309             :     }
    2310             : 
    2311           0 :     fprintf(fp, "<testsuites>\n");
    2312           0 :     fprintf(fp, "  <testsuite name=\"%s\" time=\"%.3f\" "
    2313             :                 "tests=\"%u\" failures=\"%u\" errors=\"%u\" skipped=\"%u\" >\n",
    2314             :                 group_name,
    2315             :                 total_runtime, /* seconds */
    2316             :                 (unsigned)total_executed,
    2317             :                 (unsigned)total_failed,
    2318             :                 (unsigned)total_errors,
    2319             :                 (unsigned)total_skipped);
    2320             : 
    2321           0 :     for (i = 0; i < total_executed; i++) {
    2322           0 :         struct CMUnitTestState *cmtest = &cm_tests[i];
    2323             : 
    2324           0 :         fprintf(fp, "    <testcase name=\"%s\" time=\"%.3f\" >\n",
    2325           0 :                 cmtest->test->name, cmtest->runtime);
    2326             : 
    2327           0 :         switch (cmtest->status) {
    2328           0 :         case CM_TEST_ERROR:
    2329             :         case CM_TEST_FAILED:
    2330           0 :             if (cmtest->error_message != NULL) {
    2331           0 :                 fprintf(fp, "      <failure><![CDATA[%s]]></failure>\n",
    2332             :                         cmtest->error_message);
    2333             :             } else {
    2334           0 :                 fprintf(fp, "      <failure message=\"Unknown error\" />\n");
    2335             :             }
    2336           0 :             break;
    2337           0 :         case CM_TEST_SKIPPED:
    2338           0 :             fprintf(fp, "      <skipped/>\n");
    2339           0 :             break;
    2340             : 
    2341           0 :         case CM_TEST_PASSED:
    2342             :         case CM_TEST_NOT_STARTED:
    2343           0 :             break;
    2344             :         }
    2345             : 
    2346           0 :         fprintf(fp, "    </testcase>\n");
    2347             :     }
    2348             : 
    2349           0 :     fprintf(fp, "  </testsuite>\n");
    2350           0 :     fprintf(fp, "</testsuites>\n");
    2351             : 
    2352           0 :     if (file_opened) {
    2353           0 :         fclose(fp);
    2354             :     }
    2355           0 : }
    2356             : 
    2357          13 : static void cmprintf_group_start_standard(const size_t num_tests)
    2358             : {
    2359          13 :     print_message("[==========] Running %u test(s).\n",
    2360             :                   (unsigned)num_tests);
    2361          13 : }
    2362             : 
    2363          13 : static void cmprintf_group_finish_standard(size_t total_executed,
    2364             :                                            size_t total_passed,
    2365             :                                            size_t total_failed,
    2366             :                                            size_t total_errors,
    2367             :                                            size_t total_skipped,
    2368             :                                            struct CMUnitTestState *cm_tests)
    2369             : {
    2370           0 :     size_t i;
    2371             : 
    2372          13 :     print_message("[==========] %u test(s) run.\n", (unsigned)total_executed);
    2373          13 :     print_error("[  PASSED  ] %u test(s).\n",
    2374             :                 (unsigned)(total_passed));
    2375             : 
    2376          13 :     if (total_skipped) {
    2377           0 :         print_error("[  SKIPPED ] %"PRIdS " test(s), listed below:\n", total_skipped);
    2378           0 :         for (i = 0; i < total_executed; i++) {
    2379           0 :             struct CMUnitTestState *cmtest = &cm_tests[i];
    2380             : 
    2381           0 :             if (cmtest->status == CM_TEST_SKIPPED) {
    2382           0 :                 print_error("[  SKIPPED ] %s\n", cmtest->test->name);
    2383             :             }
    2384             :         }
    2385           0 :         print_error("\n %u SKIPPED TEST(S)\n", (unsigned)(total_skipped));
    2386             :     }
    2387             : 
    2388          13 :     if (total_failed) {
    2389           0 :         print_error("[  FAILED  ] %"PRIdS " test(s), listed below:\n", total_failed);
    2390           0 :         for (i = 0; i < total_executed; i++) {
    2391           0 :             struct CMUnitTestState *cmtest = &cm_tests[i];
    2392             : 
    2393           0 :             if (cmtest->status == CM_TEST_FAILED) {
    2394           0 :                 print_error("[  FAILED  ] %s\n", cmtest->test->name);
    2395             :             }
    2396             :         }
    2397           0 :         print_error("\n %u FAILED TEST(S)\n",
    2398             :                     (unsigned)(total_failed + total_errors));
    2399             :     }
    2400          13 : }
    2401             : 
    2402         360 : static void cmprintf_standard(enum cm_printf_type type,
    2403             :                               const char *test_name,
    2404             :                               const char *error_message)
    2405             : {
    2406         360 :     switch (type) {
    2407         180 :     case PRINTF_TEST_START:
    2408         180 :         print_message("[ RUN      ] %s\n", test_name);
    2409         180 :         break;
    2410         180 :     case PRINTF_TEST_SUCCESS:
    2411         180 :         print_message("[       OK ] %s\n", test_name);
    2412         180 :         break;
    2413           0 :     case PRINTF_TEST_FAILURE:
    2414           0 :         if (error_message != NULL) {
    2415           0 :             print_error("[  ERROR   ] --- %s\n", error_message);
    2416             :         }
    2417           0 :         print_message("[  FAILED  ] %s\n", test_name);
    2418           0 :         break;
    2419           0 :     case PRINTF_TEST_SKIPPED:
    2420           0 :         print_message("[  SKIPPED ] %s\n", test_name);
    2421           0 :         break;
    2422           0 :     case PRINTF_TEST_ERROR:
    2423           0 :         if (error_message != NULL) {
    2424           0 :             print_error("%s\n", error_message);
    2425             :         }
    2426           0 :         print_error("[  ERROR   ] %s\n", test_name);
    2427           0 :         break;
    2428             :     }
    2429         360 : }
    2430             : 
    2431           0 : static void cmprintf_group_start_tap(const size_t num_tests)
    2432             : {
    2433           0 :     print_message("1..%u\n", (unsigned)num_tests);
    2434           0 : }
    2435             : 
    2436           0 : static void cmprintf_group_finish_tap(const char *group_name,
    2437             :                                       size_t total_executed,
    2438             :                                       size_t total_passed,
    2439             :                                       size_t total_skipped)
    2440             : {
    2441           0 :     const char *status = "not ok";
    2442           0 :     if (total_passed + total_skipped == total_executed) {
    2443           0 :         status = "ok";
    2444             :     }
    2445           0 :     print_message("# %s - %s\n", status, group_name);
    2446           0 : }
    2447             : 
    2448           0 : static void cmprintf_tap(enum cm_printf_type type,
    2449             :                          uint32_t test_number,
    2450             :                          const char *test_name,
    2451             :                          const char *error_message)
    2452             : {
    2453           0 :     switch (type) {
    2454           0 :     case PRINTF_TEST_START:
    2455           0 :         break;
    2456           0 :     case PRINTF_TEST_SUCCESS:
    2457           0 :         print_message("ok %u - %s\n", (unsigned)test_number, test_name);
    2458           0 :         break;
    2459           0 :     case PRINTF_TEST_FAILURE:
    2460           0 :         print_message("not ok %u - %s\n", (unsigned)test_number, test_name);
    2461           0 :         if (error_message != NULL) {
    2462           0 :             char *msg;
    2463           0 :             char *p;
    2464             : 
    2465           0 :             msg = strdup(error_message);
    2466           0 :             if (msg == NULL) {
    2467           0 :                 return;
    2468             :             }
    2469           0 :             p = msg;
    2470             : 
    2471           0 :             while (p[0] != '\0') {
    2472           0 :                 char *q = p;
    2473             : 
    2474           0 :                 p = strchr(q, '\n');
    2475           0 :                 if (p != NULL) {
    2476           0 :                     p[0] = '\0';
    2477             :                 }
    2478             : 
    2479           0 :                 print_message("# %s\n", q);
    2480             : 
    2481           0 :                 if (p == NULL) {
    2482           0 :                     break;
    2483             :                 }
    2484           0 :                 p++;
    2485             :             }
    2486           0 :             libc_free(msg);
    2487             :         }
    2488           0 :         break;
    2489           0 :     case PRINTF_TEST_SKIPPED:
    2490           0 :         print_message("not ok %u # SKIP %s\n", (unsigned)test_number, test_name);
    2491           0 :         break;
    2492           0 :     case PRINTF_TEST_ERROR:
    2493           0 :         print_message("not ok %u - %s %s\n",
    2494             :                       (unsigned)test_number, test_name, error_message);
    2495           0 :         break;
    2496             :     }
    2497             : }
    2498             : 
    2499        1110 : static void cmprintf_subunit(enum cm_printf_type type,
    2500             :                              const char *test_name,
    2501             :                              const char *error_message)
    2502             : {
    2503        1110 :     switch (type) {
    2504         555 :     case PRINTF_TEST_START:
    2505         555 :         print_message("test: %s\n", test_name);
    2506         555 :         break;
    2507         555 :     case PRINTF_TEST_SUCCESS:
    2508         555 :         print_message("success: %s\n", test_name);
    2509         555 :         break;
    2510           0 :     case PRINTF_TEST_FAILURE:
    2511           0 :         print_message("failure: %s", test_name);
    2512           0 :         if (error_message != NULL) {
    2513           0 :             print_message(" [\n%s\n]\n", error_message);
    2514             :         }
    2515           0 :         break;
    2516           0 :     case PRINTF_TEST_SKIPPED:
    2517           0 :         print_message("skip: %s\n", test_name);
    2518           0 :         break;
    2519           0 :     case PRINTF_TEST_ERROR:
    2520           0 :         print_message("error: %s [ %s ]\n", test_name, error_message);
    2521           0 :         break;
    2522             :     }
    2523        1110 : }
    2524             : 
    2525          81 : static void cmprintf_group_start(const size_t num_tests)
    2526             : {
    2527          65 :     enum cm_message_output output;
    2528             : 
    2529          81 :     output = cm_get_output();
    2530             : 
    2531          81 :     switch (output) {
    2532          13 :     case CM_OUTPUT_STDOUT:
    2533          13 :         cmprintf_group_start_standard(num_tests);
    2534          13 :         break;
    2535           3 :     case CM_OUTPUT_SUBUNIT:
    2536           3 :         break;
    2537           0 :     case CM_OUTPUT_TAP:
    2538           0 :         cmprintf_group_start_tap(num_tests);
    2539           0 :         break;
    2540           0 :     case CM_OUTPUT_XML:
    2541           0 :         break;
    2542             :     }
    2543          81 : }
    2544             : 
    2545          81 : static void cmprintf_group_finish(const char *group_name,
    2546             :                                   size_t total_executed,
    2547             :                                   size_t total_passed,
    2548             :                                   size_t total_failed,
    2549             :                                   size_t total_errors,
    2550             :                                   size_t total_skipped,
    2551             :                                   double total_runtime,
    2552             :                                   struct CMUnitTestState *cm_tests)
    2553             : {
    2554          65 :     enum cm_message_output output;
    2555             : 
    2556          81 :     output = cm_get_output();
    2557             : 
    2558          81 :     switch (output) {
    2559          13 :     case CM_OUTPUT_STDOUT:
    2560          13 :         cmprintf_group_finish_standard(total_executed,
    2561             :                                     total_passed,
    2562             :                                     total_failed,
    2563             :                                     total_errors,
    2564             :                                     total_skipped,
    2565             :                                     cm_tests);
    2566          13 :         break;
    2567           3 :     case CM_OUTPUT_SUBUNIT:
    2568           3 :         break;
    2569           0 :     case CM_OUTPUT_TAP:
    2570           0 :         cmprintf_group_finish_tap(group_name, total_executed, total_passed, total_skipped);
    2571           0 :         break;
    2572           0 :     case CM_OUTPUT_XML:
    2573           0 :         cmprintf_group_finish_xml(group_name,
    2574             :                                   total_executed,
    2575             :                                   total_failed,
    2576             :                                   total_errors,
    2577             :                                   total_skipped,
    2578             :                                   total_runtime,
    2579             :                                   cm_tests);
    2580           0 :         break;
    2581             :     }
    2582          81 : }
    2583             : 
    2584        1470 : static void cmprintf(enum cm_printf_type type,
    2585             :                      size_t test_number,
    2586             :                      const char *test_name,
    2587             :                      const char *error_message)
    2588             : {
    2589        1046 :     enum cm_message_output output;
    2590             : 
    2591        1470 :     output = cm_get_output();
    2592             : 
    2593        1470 :     switch (output) {
    2594         360 :     case CM_OUTPUT_STDOUT:
    2595         360 :         cmprintf_standard(type, test_name, error_message);
    2596         360 :         break;
    2597        1110 :     case CM_OUTPUT_SUBUNIT:
    2598        1110 :         cmprintf_subunit(type, test_name, error_message);
    2599        1110 :         break;
    2600           0 :     case CM_OUTPUT_TAP:
    2601           0 :         cmprintf_tap(type, test_number, test_name, error_message);
    2602           0 :         break;
    2603           0 :     case CM_OUTPUT_XML:
    2604           0 :         break;
    2605             :     }
    2606        1470 : }
    2607             : 
    2608          68 : void cmocka_set_message_output(enum cm_message_output output)
    2609             : {
    2610          68 :     global_msg_output = output;
    2611          68 : }
    2612             : 
    2613           0 : void cmocka_set_test_filter(const char *pattern)
    2614             : {
    2615           0 :     global_test_filter_pattern = pattern;
    2616           0 : }
    2617             : 
    2618             : /****************************************************************************
    2619             :  * TIME CALCULATIONS
    2620             :  ****************************************************************************/
    2621             : 
    2622             : #ifdef HAVE_STRUCT_TIMESPEC
    2623         735 : static struct timespec cm_tspecdiff(struct timespec time1,
    2624             :                                     struct timespec time0)
    2625             : {
    2626         523 :     struct timespec ret;
    2627         735 :     int xsec = 0;
    2628         735 :     int sign = 1;
    2629             : 
    2630         735 :     if (time0.tv_nsec > time1.tv_nsec) {
    2631           6 :         xsec = (int) ((time0.tv_nsec - time1.tv_nsec) / (1E9 + 1));
    2632           6 :         time0.tv_nsec -= (long int) (1E9 * xsec);
    2633           6 :         time0.tv_sec += xsec;
    2634             :     }
    2635             : 
    2636         735 :     if ((time1.tv_nsec - time0.tv_nsec) > 1E9) {
    2637           0 :         xsec = (int) ((time1.tv_nsec - time0.tv_nsec) / 1E9);
    2638           0 :         time0.tv_nsec += (long int) (1E9 * xsec);
    2639           0 :         time0.tv_sec -= xsec;
    2640             :     }
    2641             : 
    2642         735 :     ret.tv_sec = time1.tv_sec - time0.tv_sec;
    2643         735 :     ret.tv_nsec = time1.tv_nsec - time0.tv_nsec;
    2644             : 
    2645         735 :     if (time1.tv_sec < time0.tv_sec) {
    2646           0 :         sign = -1;
    2647             :     }
    2648             : 
    2649         735 :     ret.tv_sec = ret.tv_sec * sign;
    2650             : 
    2651         735 :     return ret;
    2652             : }
    2653             : 
    2654         735 : static double cm_secdiff(struct timespec clock1, struct timespec clock0)
    2655             : {
    2656         523 :     double ret;
    2657         523 :     struct timespec diff;
    2658             : 
    2659         735 :     diff = cm_tspecdiff(clock1, clock0);
    2660             : 
    2661         735 :     ret = diff.tv_sec;
    2662         735 :     ret += (double) diff.tv_nsec / (double) 1E9;
    2663             : 
    2664         735 :     return ret;
    2665             : }
    2666             : #endif /* HAVE_STRUCT_TIMESPEC */
    2667             : 
    2668             : /****************************************************************************
    2669             :  * CMOCKA TEST RUNNER
    2670             :  ****************************************************************************/
    2671        1427 : static int cmocka_run_one_test_or_fixture(const char *function_name,
    2672             :                                           CMUnitTestFunction test_func,
    2673             :                                           CMFixtureFunction setup_func,
    2674             :                                           CMFixtureFunction teardown_func,
    2675             :                                           void ** const volatile state,
    2676             :                                           const void *const heap_check_point)
    2677             : {
    2678        1427 :     const ListNode * const volatile check_point = (const ListNode*)
    2679             :         (heap_check_point != NULL ?
    2680         212 :          heap_check_point : check_point_allocated_blocks());
    2681        1427 :     int handle_exceptions = 1;
    2682        1427 :     void *current_state = NULL;
    2683        1427 :     int rc = 0;
    2684             : 
    2685             :     /* FIXME check only one test or fixture is set */
    2686             : 
    2687             :     /* Detect if we should handle exceptions */
    2688             : #ifdef _WIN32
    2689             :     handle_exceptions = !IsDebuggerPresent();
    2690             : #endif /* _WIN32 */
    2691             : #ifdef UNIT_TESTING_DEBUG
    2692             :     handle_exceptions = 0;
    2693             : #endif /* UNIT_TESTING_DEBUG */
    2694             : 
    2695             : 
    2696        1427 :     if (handle_exceptions) {
    2697             : #ifndef _WIN32
    2698         803 :         unsigned int i;
    2699        8562 :         for (i = 0; i < ARRAY_SIZE(exception_signals); i++) {
    2700        7135 :             default_signal_functions[i] = signal(
    2701        7135 :                     exception_signals[i], exception_handler);
    2702             :         }
    2703             : #else /* _WIN32 */
    2704             :         previous_exception_filter = SetUnhandledExceptionFilter(
    2705             :                 exception_filter);
    2706             : #endif /* !_WIN32 */
    2707             :     }
    2708             : 
    2709             :     /* Init the test structure */
    2710        1427 :     initialize_testing(function_name);
    2711             : 
    2712        1427 :     global_running_test = 1;
    2713             : 
    2714        1427 :     if (cm_setjmp(global_run_test_env) == 0) {
    2715        1427 :         if (test_func != NULL) {
    2716         735 :             test_func(state != NULL ? state : &current_state);
    2717             : 
    2718         735 :             fail_if_blocks_allocated(check_point, function_name);
    2719         212 :             rc = 0;
    2720         692 :         } else if (setup_func != NULL) {
    2721         345 :             rc = setup_func(state != NULL ? state : &current_state);
    2722             : 
    2723             :             /*
    2724             :              * For setup we can ignore any allocated blocks. We just need to
    2725             :              * ensure they're deallocated on tear down.
    2726             :              */
    2727         347 :         } else if (teardown_func != NULL) {
    2728         347 :             rc = teardown_func(state != NULL ? state : &current_state);
    2729             : 
    2730         347 :             fail_if_blocks_allocated(check_point, function_name);
    2731             :         } else {
    2732             :             /* ERROR */
    2733         803 :         }
    2734        1427 :         fail_if_leftover_values(function_name);
    2735        1427 :         global_running_test = 0;
    2736             :     } else {
    2737             :         /* TEST FAILED */
    2738           0 :         global_running_test = 0;
    2739           0 :         rc = -1;
    2740             :     }
    2741        1427 :     teardown_testing(function_name);
    2742             : 
    2743         624 :     if (handle_exceptions) {
    2744             : #ifndef _WIN32
    2745             :         unsigned int i;
    2746        8562 :         for (i = 0; i < ARRAY_SIZE(exception_signals); i++) {
    2747        7135 :             signal(exception_signals[i], default_signal_functions[i]);
    2748             :         }
    2749             : #else /* _WIN32 */
    2750             :         if (previous_exception_filter) {
    2751             :             SetUnhandledExceptionFilter(previous_exception_filter);
    2752             :             previous_exception_filter = NULL;
    2753             :         }
    2754             : #endif /* !_WIN32 */
    2755             :     }
    2756             : 
    2757        1427 :     return rc;
    2758             : }
    2759             : 
    2760          15 : static int cmocka_run_group_fixture(const char *function_name,
    2761             :                                     CMFixtureFunction setup_func,
    2762             :                                     CMFixtureFunction teardown_func,
    2763             :                                     void **state,
    2764             :                                     const void *const heap_check_point)
    2765             : {
    2766          15 :     int rc;
    2767             : 
    2768           8 :     if (setup_func != NULL) {
    2769           8 :         rc = cmocka_run_one_test_or_fixture(function_name,
    2770             :                                         NULL,
    2771             :                                         setup_func,
    2772             :                                         NULL,
    2773             :                                         state,
    2774             :                                         heap_check_point);
    2775             :     } else {
    2776           0 :         rc = cmocka_run_one_test_or_fixture(function_name,
    2777             :                                         NULL,
    2778             :                                         NULL,
    2779             :                                         teardown_func,
    2780             :                                         state,
    2781             :                                         heap_check_point);
    2782             :     }
    2783             : 
    2784          15 :     return rc;
    2785             : }
    2786             : 
    2787         735 : static int cmocka_run_one_tests(struct CMUnitTestState *test_state)
    2788             : {
    2789             : #ifdef HAVE_STRUCT_TIMESPEC
    2790         735 :     struct timespec start = {
    2791             :         .tv_sec = 0,
    2792             :         .tv_nsec = 0,
    2793             :     };
    2794         735 :     struct timespec finish = {
    2795             :         .tv_sec = 0,
    2796             :         .tv_nsec = 0,
    2797             :     };
    2798             : #endif
    2799         735 :     int rc = 0;
    2800             : 
    2801             :     /* Run setup */
    2802         735 :     if (test_state->test->setup_func != NULL) {
    2803             :         /* Setup the memory check point, it will be evaluated on teardown */
    2804         337 :         test_state->check_point = check_point_allocated_blocks();
    2805             : 
    2806         337 :         rc = cmocka_run_one_test_or_fixture(test_state->test->name,
    2807             :                                             NULL,
    2808         206 :                                             test_state->test->setup_func,
    2809             :                                             NULL,
    2810             :                                             &test_state->state,
    2811         206 :                                             test_state->check_point);
    2812         337 :         if (rc != 0) {
    2813           0 :             test_state->status = CM_TEST_ERROR;
    2814           0 :             cm_print_error("Test setup failed");
    2815             :         }
    2816             :     }
    2817             : 
    2818             :     /* Run test */
    2819             : #ifdef HAVE_STRUCT_TIMESPEC
    2820         735 :     CMOCKA_CLOCK_GETTIME(CLOCK_REALTIME, &start);
    2821             : #endif
    2822             : 
    2823         735 :     if (rc == 0) {
    2824        1258 :         rc = cmocka_run_one_test_or_fixture(test_state->test->name,
    2825         735 :                                             test_state->test->test_func,
    2826             :                                             NULL,
    2827             :                                             NULL,
    2828             :                                             &test_state->state,
    2829             :                                             NULL);
    2830         735 :         if (rc == 0) {
    2831         735 :             test_state->status = CM_TEST_PASSED;
    2832             :         } else {
    2833           0 :             if (global_skip_test) {
    2834           0 :                 test_state->status = CM_TEST_SKIPPED;
    2835           0 :                 global_skip_test = 0; /* Do not skip the next test */
    2836             :             } else {
    2837           0 :                 test_state->status = CM_TEST_FAILED;
    2838             :             }
    2839             :         }
    2840         212 :         rc = 0;
    2841             :     }
    2842             : 
    2843         735 :     test_state->runtime = 0.0;
    2844             : 
    2845             : #ifdef HAVE_STRUCT_TIMESPEC
    2846         735 :     CMOCKA_CLOCK_GETTIME(CLOCK_REALTIME, &finish);
    2847         735 :     test_state->runtime = cm_secdiff(finish, start);
    2848             : #endif
    2849             : 
    2850             :     /* Run teardown */
    2851         735 :     if (rc == 0 && test_state->test->teardown_func != NULL) {
    2852         474 :         rc = cmocka_run_one_test_or_fixture(test_state->test->name,
    2853             :                                             NULL,
    2854             :                                             NULL,
    2855         206 :                                             test_state->test->teardown_func,
    2856             :                                             &test_state->state,
    2857         340 :                                             test_state->check_point);
    2858         340 :         if (rc != 0) {
    2859           0 :             test_state->status = CM_TEST_ERROR;
    2860           0 :             cm_print_error("Test teardown failed");
    2861             :         }
    2862             :     }
    2863             : 
    2864         735 :     test_state->error_message = cm_error_message;
    2865         735 :     cm_error_message = NULL;
    2866             : 
    2867         735 :     return rc;
    2868             : }
    2869             : 
    2870          81 : int _cmocka_run_group_tests(const char *group_name,
    2871             :                             const struct CMUnitTest * const tests,
    2872             :                             const size_t num_tests,
    2873             :                             CMFixtureFunction group_setup,
    2874             :                             CMFixtureFunction group_teardown)
    2875             : {
    2876          65 :     struct CMUnitTestState *cm_tests;
    2877          81 :     const ListNode *group_check_point = check_point_allocated_blocks();
    2878          81 :     void *group_state = NULL;
    2879          81 :     size_t total_tests = 0;
    2880          81 :     size_t total_failed = 0;
    2881          81 :     size_t total_passed = 0;
    2882          81 :     size_t total_executed = 0;
    2883          81 :     size_t total_errors = 0;
    2884          81 :     size_t total_skipped = 0;
    2885          81 :     double total_runtime = 0;
    2886          65 :     size_t i;
    2887          65 :     int rc;
    2888             : 
    2889             :     /* Make sure LargestIntegralType is at least the size of a pointer. */
    2890          81 :     assert_true(sizeof(LargestIntegralType) >= sizeof(void*));
    2891             : 
    2892          81 :     cm_tests = (struct CMUnitTestState *)libc_malloc(sizeof(struct CMUnitTestState) * num_tests);
    2893          81 :     if (cm_tests == NULL) {
    2894           0 :         return -1;
    2895             :     }
    2896             : 
    2897             :     /* Setup cmocka test array */
    2898         816 :     for (i = 0; i < num_tests; i++) {
    2899         735 :         if (tests[i].name != NULL &&
    2900         735 :             (tests[i].test_func != NULL
    2901           0 :              || tests[i].setup_func != NULL
    2902           0 :              || tests[i].teardown_func != NULL)) {
    2903         735 :             if (global_test_filter_pattern != NULL) {
    2904           0 :                 int ok;
    2905             : 
    2906           0 :                 ok = c_strmatch(tests[i].name, global_test_filter_pattern);
    2907           0 :                 if (!ok) {
    2908           0 :                     continue;
    2909             :                 }
    2910             :             }
    2911         735 :             cm_tests[total_tests] = (struct CMUnitTestState) {
    2912         212 :                 .test = &tests[i],
    2913             :                 .status = CM_TEST_NOT_STARTED,
    2914             :                 .state = NULL,
    2915             :             };
    2916         735 :             total_tests++;
    2917             :         }
    2918             :     }
    2919             : 
    2920          81 :     cmprintf_group_start(total_tests);
    2921             : 
    2922          81 :     rc = 0;
    2923             : 
    2924             :     /* Run group setup */
    2925          81 :     if (group_setup != NULL) {
    2926           8 :         rc = cmocka_run_group_fixture("cmocka_group_setup",
    2927             :                                       group_setup,
    2928             :                                       NULL,
    2929             :                                       &group_state,
    2930             :                                       group_check_point);
    2931             :     }
    2932             : 
    2933          24 :     if (rc == 0) {
    2934             :         /* Execute tests */
    2935         816 :         for (i = 0; i < total_tests; i++) {
    2936         735 :             struct CMUnitTestState *cmtest = &cm_tests[i];
    2937         735 :             size_t test_number = i + 1;
    2938             : 
    2939         735 :             cmprintf(PRINTF_TEST_START, test_number, cmtest->test->name, NULL);
    2940             : 
    2941         735 :             if (group_state != NULL) {
    2942          50 :                 cmtest->state = group_state;
    2943         685 :             } else if (cmtest->test->initial_state  != NULL) {
    2944           0 :                 cmtest->state = cmtest->test->initial_state;
    2945             :             }
    2946             : 
    2947         735 :             rc = cmocka_run_one_tests(cmtest);
    2948         735 :             total_executed++;
    2949         735 :             total_runtime += cmtest->runtime;
    2950         735 :             if (rc == 0) {
    2951         735 :                 switch (cmtest->status) {
    2952         735 :                     case CM_TEST_PASSED:
    2953         735 :                         cmprintf(PRINTF_TEST_SUCCESS,
    2954             :                                  test_number,
    2955         735 :                                  cmtest->test->name,
    2956             :                                  cmtest->error_message);
    2957         735 :                         total_passed++;
    2958         735 :                         break;
    2959           0 :                     case CM_TEST_SKIPPED:
    2960           0 :                         cmprintf(PRINTF_TEST_SKIPPED,
    2961             :                                  test_number,
    2962           0 :                                  cmtest->test->name,
    2963             :                                  cmtest->error_message);
    2964           0 :                         total_skipped++;
    2965           0 :                         break;
    2966           0 :                     case CM_TEST_FAILED:
    2967           0 :                         cmprintf(PRINTF_TEST_FAILURE,
    2968             :                                  test_number,
    2969           0 :                                  cmtest->test->name,
    2970             :                                  cmtest->error_message);
    2971           0 :                         total_failed++;
    2972           0 :                         break;
    2973           0 :                     default:
    2974           0 :                         cmprintf(PRINTF_TEST_ERROR,
    2975             :                                  test_number,
    2976           0 :                                  cmtest->test->name,
    2977             :                                  "Internal cmocka error");
    2978           0 :                         total_errors++;
    2979           0 :                         break;
    2980             :                 }
    2981             :             } else {
    2982           0 :                 char err_msg[2048] = {0};
    2983             : 
    2984           0 :                 snprintf(err_msg, sizeof(err_msg),
    2985             :                          "Could not run test: %s",
    2986             :                          cmtest->error_message);
    2987             : 
    2988           0 :                 cmprintf(PRINTF_TEST_ERROR,
    2989             :                          test_number,
    2990           0 :                          cmtest->test->name,
    2991             :                          err_msg);
    2992           0 :                 total_errors++;
    2993             :             }
    2994             :         }
    2995             :     } else {
    2996           0 :         if (cm_error_message != NULL) {
    2997           0 :             print_error("[  ERROR   ] --- %s\n", cm_error_message);
    2998           0 :             vcm_free_error(cm_error_message);
    2999           0 :             cm_error_message = NULL;
    3000             :         }
    3001           0 :         cmprintf(PRINTF_TEST_ERROR, 0,
    3002             :                  group_name, "[  FAILED  ] GROUP SETUP");
    3003           0 :         total_errors++;
    3004             :     }
    3005             : 
    3006             :     /* Run group teardown */
    3007          81 :     if (group_teardown != NULL) {
    3008           7 :         rc = cmocka_run_group_fixture("cmocka_group_teardown",
    3009             :                                       NULL,
    3010             :                                       group_teardown,
    3011             :                                       &group_state,
    3012             :                                       group_check_point);
    3013           7 :         if (rc != 0) {
    3014           0 :             if (cm_error_message != NULL) {
    3015           0 :                 print_error("[  ERROR   ] --- %s\n", cm_error_message);
    3016           0 :                 vcm_free_error(cm_error_message);
    3017           0 :                 cm_error_message = NULL;
    3018             :             }
    3019           0 :             cmprintf(PRINTF_TEST_ERROR, 0,
    3020             :                      group_name, "[  FAILED  ] GROUP TEARDOWN");
    3021             :         }
    3022             :     }
    3023             : 
    3024          81 :     cmprintf_group_finish(group_name,
    3025             :                           total_executed,
    3026             :                           total_passed,
    3027             :                           total_failed,
    3028             :                           total_errors,
    3029             :                           total_skipped,
    3030             :                           total_runtime,
    3031             :                           cm_tests);
    3032             : 
    3033         881 :     for (i = 0; i < total_tests; i++) {
    3034         735 :         vcm_free_error(discard_const_p(char, cm_tests[i].error_message));
    3035             :     }
    3036          81 :     libc_free(cm_tests);
    3037          81 :     fail_if_blocks_allocated(group_check_point, "cmocka_group_tests");
    3038             : 
    3039          81 :     return total_failed + total_errors;
    3040             : }
    3041             : 
    3042             : /****************************************************************************
    3043             :  * DEPRECATED TEST RUNNER
    3044             :  ****************************************************************************/
    3045             : 
    3046           0 : int _run_test(
    3047             :         const char * const function_name,  const UnitTestFunction Function,
    3048             :         void ** const volatile state, const UnitTestFunctionType function_type,
    3049             :         const void* const heap_check_point) {
    3050           0 :     const ListNode * const volatile check_point = (const ListNode*)
    3051             :         (heap_check_point ?
    3052           0 :          heap_check_point : check_point_allocated_blocks());
    3053           0 :     void *current_state = NULL;
    3054           0 :     volatile int rc = 1;
    3055           0 :     int handle_exceptions = 1;
    3056             : #ifdef _WIN32
    3057             :     handle_exceptions = !IsDebuggerPresent();
    3058             : #endif /* _WIN32 */
    3059             : #ifdef UNIT_TESTING_DEBUG
    3060             :     handle_exceptions = 0;
    3061             : #endif /* UNIT_TESTING_DEBUG */
    3062             : 
    3063           0 :     cm_error_message_enabled = 0;
    3064             : 
    3065           0 :     if (handle_exceptions) {
    3066             : #ifndef _WIN32
    3067           0 :         unsigned int i;
    3068           0 :         for (i = 0; i < ARRAY_SIZE(exception_signals); i++) {
    3069           0 :             default_signal_functions[i] = signal(
    3070           0 :                 exception_signals[i], exception_handler);
    3071             :         }
    3072             : #else /* _WIN32 */
    3073             :         previous_exception_filter = SetUnhandledExceptionFilter(
    3074             :             exception_filter);
    3075             : #endif /* !_WIN32 */
    3076             :     }
    3077             : 
    3078           0 :     if (function_type == UNIT_TEST_FUNCTION_TYPE_TEST) {
    3079           0 :         print_message("[ RUN      ] %s\n", function_name);
    3080             :     }
    3081           0 :     initialize_testing(function_name);
    3082           0 :     global_running_test = 1;
    3083           0 :     if (cm_setjmp(global_run_test_env) == 0) {
    3084           0 :         Function(state ? state : &current_state);
    3085           0 :         fail_if_leftover_values(function_name);
    3086             : 
    3087             :         /* If this is a setup function then ignore any allocated blocks
    3088             :          * only ensure they're deallocated on tear down. */
    3089           0 :         if (function_type != UNIT_TEST_FUNCTION_TYPE_SETUP) {
    3090           0 :             fail_if_blocks_allocated(check_point, function_name);
    3091             :         }
    3092             : 
    3093           0 :         global_running_test = 0;
    3094             : 
    3095           0 :         if (function_type == UNIT_TEST_FUNCTION_TYPE_TEST) {
    3096           0 :             print_message("[       OK ] %s\n", function_name);
    3097             :         }
    3098           0 :         rc = 0;
    3099             :     } else {
    3100           0 :         global_running_test = 0;
    3101           0 :         print_message("[  FAILED  ] %s\n", function_name);
    3102             :     }
    3103           0 :     teardown_testing(function_name);
    3104             : 
    3105           0 :     if (handle_exceptions) {
    3106             : #ifndef _WIN32
    3107             :         unsigned int i;
    3108           0 :         for (i = 0; i < ARRAY_SIZE(exception_signals); i++) {
    3109           0 :             signal(exception_signals[i], default_signal_functions[i]);
    3110             :         }
    3111             : #else /* _WIN32 */
    3112             :         if (previous_exception_filter) {
    3113             :             SetUnhandledExceptionFilter(previous_exception_filter);
    3114             :             previous_exception_filter = NULL;
    3115             :         }
    3116             : #endif /* !_WIN32 */
    3117             :     }
    3118             : 
    3119           0 :     return rc;
    3120             : }
    3121             : 
    3122             : 
    3123           0 : int _run_tests(const UnitTest * const tests, const size_t number_of_tests) {
    3124             :     /* Whether to execute the next test. */
    3125           0 :     int run_next_test = 1;
    3126             :     /* Whether the previous test failed. */
    3127           0 :     int previous_test_failed = 0;
    3128             :     /* Whether the previous setup failed. */
    3129           0 :     int previous_setup_failed = 0;
    3130             :     /* Check point of the heap state. */
    3131           0 :     const ListNode * const check_point = check_point_allocated_blocks();
    3132             :     /* Current test being executed. */
    3133           0 :     size_t current_test = 0;
    3134             :     /* Number of tests executed. */
    3135           0 :     size_t tests_executed = 0;
    3136             :     /* Number of failed tests. */
    3137           0 :     size_t total_failed = 0;
    3138             :     /* Number of setup functions. */
    3139           0 :     size_t setups = 0;
    3140             :     /* Number of teardown functions. */
    3141           0 :     size_t teardowns = 0;
    3142           0 :     size_t i;
    3143             :     /*
    3144             :      * A stack of test states.  A state is pushed on the stack
    3145             :      * when a test setup occurs and popped on tear down.
    3146             :      */
    3147           0 :     TestState* test_states =
    3148           0 :        (TestState*)malloc(number_of_tests * sizeof(*test_states));
    3149             :     /* The number of test states which should be 0 at the end */
    3150           0 :     long number_of_test_states = 0;
    3151             :     /* Names of the tests that failed. */
    3152           0 :     const char** failed_names = (const char**)malloc(number_of_tests *
    3153             :                                        sizeof(*failed_names));
    3154           0 :     void **current_state = NULL;
    3155             : 
    3156             :     /* Count setup and teardown functions */
    3157           0 :     for (i = 0; i < number_of_tests; i++) {
    3158           0 :         const UnitTest * const test = &tests[i];
    3159             : 
    3160           0 :         if (test->function_type == UNIT_TEST_FUNCTION_TYPE_SETUP) {
    3161           0 :             setups++;
    3162             :         }
    3163             : 
    3164           0 :         if (test->function_type == UNIT_TEST_FUNCTION_TYPE_TEARDOWN) {
    3165           0 :             teardowns++;
    3166             :         }
    3167             :     }
    3168             : 
    3169           0 :     print_message("[==========] Running %"PRIdS " test(s).\n",
    3170           0 :                   number_of_tests - setups - teardowns);
    3171             : 
    3172             :     /* Make sure LargestIntegralType is at least the size of a pointer. */
    3173           0 :     assert_true(sizeof(LargestIntegralType) >= sizeof(void*));
    3174             : 
    3175           0 :     while (current_test < number_of_tests) {
    3176           0 :         const ListNode *test_check_point = NULL;
    3177           0 :         TestState *current_TestState;
    3178           0 :         const UnitTest * const test = &tests[current_test++];
    3179           0 :         if (!test->function) {
    3180           0 :             continue;
    3181             :         }
    3182             : 
    3183           0 :         switch (test->function_type) {
    3184           0 :         case UNIT_TEST_FUNCTION_TYPE_TEST:
    3185           0 :             if (! previous_setup_failed) {
    3186           0 :                 run_next_test = 1;
    3187             :             }
    3188           0 :             break;
    3189           0 :         case UNIT_TEST_FUNCTION_TYPE_SETUP: {
    3190             :             /* Checkpoint the heap before the setup. */
    3191           0 :             current_TestState = &test_states[number_of_test_states++];
    3192           0 :             current_TestState->check_point = check_point_allocated_blocks();
    3193           0 :             test_check_point = current_TestState->check_point;
    3194           0 :             current_state = &current_TestState->state;
    3195           0 :             *current_state = NULL;
    3196           0 :             run_next_test = 1;
    3197           0 :             break;
    3198             :         }
    3199           0 :         case UNIT_TEST_FUNCTION_TYPE_TEARDOWN:
    3200             :             /* Check the heap based on the last setup checkpoint. */
    3201           0 :             assert_true(number_of_test_states);
    3202           0 :             current_TestState = &test_states[--number_of_test_states];
    3203           0 :             test_check_point = current_TestState->check_point;
    3204           0 :             current_state = &current_TestState->state;
    3205           0 :             break;
    3206           0 :         default:
    3207           0 :             print_error("Invalid unit test function type %d\n",
    3208           0 :                         test->function_type);
    3209           0 :             exit_test(1);
    3210           0 :             break;
    3211             :         }
    3212             : 
    3213           0 :         if (run_next_test) {
    3214           0 :             int failed = _run_test(test->name, test->function, current_state,
    3215           0 :                                    test->function_type, test_check_point);
    3216           0 :             if (failed) {
    3217           0 :                 failed_names[total_failed] = test->name;
    3218             :             }
    3219             : 
    3220           0 :             switch (test->function_type) {
    3221           0 :             case UNIT_TEST_FUNCTION_TYPE_TEST:
    3222           0 :                 previous_test_failed = failed;
    3223           0 :                 total_failed += failed;
    3224           0 :                 tests_executed ++;
    3225           0 :                 break;
    3226             : 
    3227           0 :             case UNIT_TEST_FUNCTION_TYPE_SETUP:
    3228           0 :                 if (failed) {
    3229           0 :                     total_failed ++;
    3230           0 :                     tests_executed ++;
    3231             :                     /* Skip forward until the next test or setup function. */
    3232           0 :                     run_next_test = 0;
    3233           0 :                     previous_setup_failed = 1;
    3234             :                 }
    3235           0 :                 previous_test_failed = 0;
    3236           0 :                 break;
    3237             : 
    3238           0 :             case UNIT_TEST_FUNCTION_TYPE_TEARDOWN:
    3239             :                 /* If this test failed. */
    3240           0 :                 if (failed && !previous_test_failed) {
    3241           0 :                     total_failed ++;
    3242             :                 }
    3243           0 :                 break;
    3244           0 :             default:
    3245             : #ifndef _HPUX
    3246           0 :                 assert_null("BUG: shouldn't be here!");
    3247             : #endif
    3248           0 :                 break;
    3249             :             }
    3250             :         }
    3251             :     }
    3252             : 
    3253           0 :     print_message("[==========] %"PRIdS " test(s) run.\n", tests_executed);
    3254           0 :     print_error("[  PASSED  ] %"PRIdS " test(s).\n", tests_executed - total_failed);
    3255             : 
    3256           0 :     if (total_failed > 0) {
    3257           0 :         print_error("[  FAILED  ] %"PRIdS " test(s), listed below:\n", total_failed);
    3258           0 :         for (i = 0; i < total_failed; i++) {
    3259           0 :             print_error("[  FAILED  ] %s\n", failed_names[i]);
    3260             :         }
    3261             :     } else {
    3262           0 :         print_error("\n %"PRIdS " FAILED TEST(S)\n", total_failed);
    3263             :     }
    3264             : 
    3265           0 :     if (number_of_test_states != 0) {
    3266           0 :         print_error("[  ERROR   ] Mismatched number of setup %"PRIdS " and "
    3267             :                     "teardown %"PRIdS " functions\n", setups, teardowns);
    3268           0 :         total_failed = (size_t)-1;
    3269             :     }
    3270             : 
    3271           0 :     free(test_states);
    3272           0 :     free((void*)failed_names);
    3273             : 
    3274           0 :     fail_if_blocks_allocated(check_point, "run_tests");
    3275           0 :     return (int)total_failed;
    3276             : }
    3277             : 
    3278           0 : int _run_group_tests(const UnitTest * const tests, const size_t number_of_tests)
    3279             : {
    3280           0 :     UnitTestFunction setup = NULL;
    3281           0 :     const char *setup_name;
    3282           0 :     size_t num_setups = 0;
    3283           0 :     UnitTestFunction teardown = NULL;
    3284           0 :     const char *teardown_name = NULL;
    3285           0 :     size_t num_teardowns = 0;
    3286           0 :     size_t current_test = 0;
    3287           0 :     size_t i;
    3288             : 
    3289             :     /* Number of tests executed. */
    3290           0 :     size_t tests_executed = 0;
    3291             :     /* Number of failed tests. */
    3292           0 :     size_t total_failed = 0;
    3293             :     /* Check point of the heap state. */
    3294           0 :     const ListNode * const check_point = check_point_allocated_blocks();
    3295           0 :     const char **failed_names = NULL;
    3296           0 :     void **current_state = NULL;
    3297           0 :     TestState group_state = {
    3298             :         .check_point = NULL,
    3299             :     };
    3300             : 
    3301           0 :     if (number_of_tests == 0) {
    3302           0 :         return -1;
    3303             :     }
    3304             : 
    3305           0 :     failed_names = (const char **)malloc(number_of_tests *
    3306             :                                          sizeof(*failed_names));
    3307           0 :     if (failed_names == NULL) {
    3308           0 :         return -2;
    3309             :     }
    3310             : 
    3311             :     /* Find setup and teardown function */
    3312           0 :     for (i = 0; i < number_of_tests; i++) {
    3313           0 :         const UnitTest * const test = &tests[i];
    3314             : 
    3315           0 :         if (test->function_type == UNIT_TEST_FUNCTION_TYPE_GROUP_SETUP) {
    3316           0 :             if (setup == NULL) {
    3317           0 :                 setup = test->function;
    3318           0 :                 setup_name = test->name;
    3319           0 :                 num_setups = 1;
    3320             :             } else {
    3321           0 :                 print_error("[  ERROR   ] More than one group setup function detected\n");
    3322           0 :                 exit_test(1);
    3323             :             }
    3324             :         }
    3325             : 
    3326           0 :         if (test->function_type == UNIT_TEST_FUNCTION_TYPE_GROUP_TEARDOWN) {
    3327           0 :             if (teardown == NULL) {
    3328           0 :                 teardown = test->function;
    3329           0 :                 teardown_name = test->name;
    3330           0 :                 num_teardowns = 1;
    3331             :             } else {
    3332           0 :                 print_error("[  ERROR   ] More than one group teardown function detected\n");
    3333           0 :                 exit_test(1);
    3334             :             }
    3335             :         }
    3336             :     }
    3337             : 
    3338           0 :     print_message("[==========] Running %"PRIdS " test(s).\n",
    3339           0 :                   number_of_tests - num_setups - num_teardowns);
    3340             : 
    3341           0 :     if (setup != NULL) {
    3342           0 :         int failed;
    3343             : 
    3344           0 :         group_state.check_point = check_point_allocated_blocks();
    3345           0 :         current_state = &group_state.state;
    3346           0 :         *current_state = NULL;
    3347           0 :         failed = _run_test(setup_name,
    3348             :                            setup,
    3349             :                            current_state,
    3350             :                            UNIT_TEST_FUNCTION_TYPE_SETUP,
    3351           0 :                            group_state.check_point);
    3352           0 :         if (failed) {
    3353           0 :             failed_names[total_failed] = setup_name;
    3354             :         }
    3355             : 
    3356           0 :         total_failed += failed;
    3357           0 :         tests_executed++;
    3358             :     }
    3359             : 
    3360           0 :     while (current_test < number_of_tests) {
    3361           0 :         int run_test = 0;
    3362           0 :         const UnitTest * const test = &tests[current_test++];
    3363           0 :         if (test->function == NULL) {
    3364           0 :             continue;
    3365             :         }
    3366             : 
    3367           0 :         switch (test->function_type) {
    3368           0 :         case UNIT_TEST_FUNCTION_TYPE_TEST:
    3369           0 :             run_test = 1;
    3370           0 :             break;
    3371           0 :         case UNIT_TEST_FUNCTION_TYPE_SETUP:
    3372             :         case UNIT_TEST_FUNCTION_TYPE_TEARDOWN:
    3373             :         case UNIT_TEST_FUNCTION_TYPE_GROUP_SETUP:
    3374             :         case UNIT_TEST_FUNCTION_TYPE_GROUP_TEARDOWN:
    3375           0 :             break;
    3376           0 :         default:
    3377           0 :             print_error("Invalid unit test function type %d\n",
    3378           0 :                         test->function_type);
    3379           0 :             break;
    3380             :         }
    3381             : 
    3382           0 :         if (run_test) {
    3383           0 :             int failed;
    3384             : 
    3385           0 :             failed = _run_test(test->name,
    3386           0 :                                test->function,
    3387             :                                current_state,
    3388           0 :                                test->function_type,
    3389             :                                NULL);
    3390           0 :             if (failed) {
    3391           0 :                 failed_names[total_failed] = test->name;
    3392             :             }
    3393             : 
    3394           0 :             total_failed += failed;
    3395           0 :             tests_executed++;
    3396             :         }
    3397             :     }
    3398             : 
    3399           0 :     if (teardown != NULL) {
    3400           0 :         int failed;
    3401             : 
    3402           0 :         failed = _run_test(teardown_name,
    3403             :                            teardown,
    3404             :                            current_state,
    3405             :                            UNIT_TEST_FUNCTION_TYPE_GROUP_TEARDOWN,
    3406           0 :                            group_state.check_point);
    3407           0 :         if (failed) {
    3408           0 :             failed_names[total_failed] = teardown_name;
    3409             :         }
    3410             : 
    3411           0 :         total_failed += failed;
    3412           0 :         tests_executed++;
    3413             :     }
    3414             : 
    3415           0 :     print_message("[==========] %"PRIdS " test(s) run.\n", tests_executed);
    3416           0 :     print_error("[  PASSED  ] %"PRIdS " test(s).\n", tests_executed - total_failed);
    3417             : 
    3418           0 :     if (total_failed) {
    3419           0 :         print_error("[  FAILED  ] %"PRIdS " test(s), listed below:\n", total_failed);
    3420           0 :         for (i = 0; i < total_failed; i++) {
    3421           0 :             print_error("[  FAILED  ] %s\n", failed_names[i]);
    3422             :         }
    3423             :     } else {
    3424           0 :         print_error("\n %"PRIdS " FAILED TEST(S)\n", total_failed);
    3425             :     }
    3426             : 
    3427           0 :     free((void*)failed_names);
    3428           0 :     fail_if_blocks_allocated(check_point, "run_group_tests");
    3429             : 
    3430           0 :     return (int)total_failed;
    3431             : }

Generated by: LCOV version 1.14