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