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