LCOV - code coverage report
Current view: top level - unit_test/cmockalib/cmocka/src - cmocka.c (source / functions) Coverage Total Hit
Test: coverage.info Lines: 21.1 % 1461 308
Test Date: 2025-06-29 08:09:00 Functions: 32.8 % 134 44

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

Generated by: LCOV version 2.0-1