2 * Copyright 2008 Google Inc.
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
34 #define vsnprintf _vsnprintf
37 * Backwards compatibility with headers shipped with Visual Studio 2005 and
40 WINBASEAPI BOOL WINAPI IsDebuggerPresent(VOID);
55 #include <cmocka_private.h>
58 /* Size of guard bytes around dynamically allocated blocks. */
59 #define MALLOC_GUARD_SIZE 16
60 /* Pattern used to initialize guard blocks. */
61 #define MALLOC_GUARD_PATTERN 0xEF
62 /* Pattern used to initialize memory allocated with test_malloc(). */
63 #define MALLOC_ALLOC_PATTERN 0xBA
64 #define MALLOC_FREE_PATTERN 0xCD
65 /* Alignment of allocated blocks. NOTE: This must be base2. */
66 #define MALLOC_ALIGNMENT sizeof(size_t)
68 /* Printf formatting for source code locations. */
69 #define SOURCE_LOCATION_FORMAT "%s:%u"
71 /* Calculates the number of elements in an array. */
72 #define ARRAY_LENGTH(x) (sizeof(x) / sizeof((x)[0]))
75 * Declare and initialize the pointer member of ValuePointer variable name
78 #define declare_initialize_value_pointer_pointer(name, ptr) \
81 name.x.pointer = (void*)(ptr)
84 * Declare and initialize the value member of ValuePointer variable name
87 #define declare_initialize_value_pointer_value(name, val) \
91 /* Cast a LargestIntegralType to pointer_type via a ValuePointer. */
92 #define cast_largest_integral_type_to_pointer( \
93 pointer_type, largest_integral_type) \
94 ((pointer_type)((ValuePointer*)&(largest_integral_type))->x.pointer)
96 /* Used to cast LargetIntegralType to void* and vice versa. */
97 typedef union ValuePointer {
98 LargestIntegralType value;
100 #if defined(WORDS_BIGENDIAN) && (WORDS_SIZEOF_VOID_P == 4)
101 unsigned int padding;
107 /* Doubly linked list node. */
108 typedef struct ListNode {
111 struct ListNode *next;
112 struct ListNode *prev;
115 /* Debug information for malloc(). */
116 typedef struct MallocBlockInfo {
117 void* block; /* Address of the block returned by malloc(). */
118 size_t allocated_size; /* Total size of the allocated block. */
119 size_t size; /* Request block size. */
120 SourceLocation location; /* Where the block was allocated. */
121 ListNode node; /* Node within list of all allocated blocks. */
124 /* State of each test. */
125 typedef struct TestState {
126 const ListNode *check_point; /* Check point of the test if there's a */
127 /* setup function. */
128 void *state; /* State associated with the test. */
131 /* Determines whether two values are the same. */
132 typedef int (*EqualityFunction)(const void *left, const void *right);
134 /* Value of a symbol and the place it was declared. */
135 typedef struct SymbolValue {
136 SourceLocation location;
137 LargestIntegralType value;
141 * Contains a list of values for a symbol.
142 * NOTE: Each structure referenced by symbol_values_list_head must have a
143 * SourceLocation as its' first member.
145 typedef struct SymbolMapValue {
146 const char *symbol_name;
147 ListNode symbol_values_list_head;
150 /* Used by list_free() to deallocate values referenced by list nodes. */
151 typedef void (*CleanupListValue)(const void *value, void *cleanup_value_data);
153 /* Structure used to check the range of integer types.a */
154 typedef struct CheckIntegerRange {
155 CheckParameterEvent event;
156 LargestIntegralType minimum;
157 LargestIntegralType maximum;
160 /* Structure used to check whether an integer value is in a set. */
161 typedef struct CheckIntegerSet {
162 CheckParameterEvent event;
163 const LargestIntegralType *set;
167 /* Used to check whether a parameter matches the area of memory referenced by
169 typedef struct CheckMemoryData {
170 CheckParameterEvent event;
175 static ListNode* list_initialize(ListNode * const node);
176 static ListNode* list_add(ListNode * const head, ListNode *new_node);
177 static ListNode* list_add_value(ListNode * const head, const void *value,
179 static ListNode* list_remove(
180 ListNode * const node, const CleanupListValue cleanup_value,
181 void * const cleanup_value_data);
182 static void list_remove_free(
183 ListNode * const node, const CleanupListValue cleanup_value,
184 void * const cleanup_value_data);
185 static int list_empty(const ListNode * const head);
186 static int list_find(
187 ListNode * const head, const void *value,
188 const EqualityFunction equal_func, ListNode **output);
189 static int list_first(ListNode * const head, ListNode **output);
190 static ListNode* list_free(
191 ListNode * const head, const CleanupListValue cleanup_value,
192 void * const cleanup_value_data);
194 static void add_symbol_value(
195 ListNode * const symbol_map_head, const char * const symbol_names[],
196 const size_t number_of_symbol_names, const void* value, const int count);
197 static int get_symbol_value(
198 ListNode * const symbol_map_head, const char * const symbol_names[],
199 const size_t number_of_symbol_names, void **output);
200 static void free_value(const void *value, void *cleanup_value_data);
201 static void free_symbol_map_value(
202 const void *value, void *cleanup_value_data);
203 static void remove_always_return_values(ListNode * const map_head,
204 const size_t number_of_symbol_names);
205 static int check_for_leftover_values(
206 const ListNode * const map_head, const char * const error_message,
207 const size_t number_of_symbol_names);
209 * This must be called at the beginning of a test to initialize some data
212 static void initialize_testing(const char *test_name);
214 /* This must be called at the end of a test to free() allocated structures. */
215 static void teardown_testing(const char *test_name);
219 * Keeps track of the calling context returned by setenv() so that the fail()
220 * method can jump out of a test.
222 static jmp_buf global_run_test_env;
223 static int global_running_test = 0;
225 /* Keeps track of the calling context returned by setenv() so that */
226 /* mock_assert() can optionally jump back to expect_assert_failure(). */
227 jmp_buf global_expect_assert_env;
228 int global_expecting_assert = 0;
229 const char *global_last_failed_assert = NULL;
231 /* Keeps a map of the values that functions will have to return to provide */
232 /* mocked interfaces. */
233 static ListNode global_function_result_map_head;
234 /* Location of the last mock value returned was declared. */
235 static SourceLocation global_last_mock_value_location;
237 /* Keeps a map of the values that functions expect as parameters to their
238 * mocked interfaces. */
239 static ListNode global_function_parameter_map_head;
240 /* Location of last parameter value checked was declared. */
241 static SourceLocation global_last_parameter_location;
243 /* List of all currently allocated blocks. */
244 static ListNode global_allocated_blocks;
247 /* Signals caught by exception_handler(). */
248 static const int exception_signals[] = {
256 /* Default signal functions that should be restored after a test is complete. */
257 typedef void (*SignalFunction)(int signal);
258 static SignalFunction default_signal_functions[
259 ARRAY_LENGTH(exception_signals)];
263 /* The default exception filter. */
264 static LPTOP_LEVEL_EXCEPTION_FILTER previous_exception_filter;
266 /* Fatal exceptions. */
267 typedef struct ExceptionCodeInfo {
269 const char* description;
272 #define EXCEPTION_CODE_INFO(exception_code) {exception_code, #exception_code}
274 static const ExceptionCodeInfo exception_codes[] = {
275 EXCEPTION_CODE_INFO(EXCEPTION_ACCESS_VIOLATION),
276 EXCEPTION_CODE_INFO(EXCEPTION_ARRAY_BOUNDS_EXCEEDED),
277 EXCEPTION_CODE_INFO(EXCEPTION_DATATYPE_MISALIGNMENT),
278 EXCEPTION_CODE_INFO(EXCEPTION_FLT_DENORMAL_OPERAND),
279 EXCEPTION_CODE_INFO(EXCEPTION_FLT_DIVIDE_BY_ZERO),
280 EXCEPTION_CODE_INFO(EXCEPTION_FLT_INEXACT_RESULT),
281 EXCEPTION_CODE_INFO(EXCEPTION_FLT_INVALID_OPERATION),
282 EXCEPTION_CODE_INFO(EXCEPTION_FLT_OVERFLOW),
283 EXCEPTION_CODE_INFO(EXCEPTION_FLT_STACK_CHECK),
284 EXCEPTION_CODE_INFO(EXCEPTION_FLT_UNDERFLOW),
285 EXCEPTION_CODE_INFO(EXCEPTION_GUARD_PAGE),
286 EXCEPTION_CODE_INFO(EXCEPTION_ILLEGAL_INSTRUCTION),
287 EXCEPTION_CODE_INFO(EXCEPTION_INT_DIVIDE_BY_ZERO),
288 EXCEPTION_CODE_INFO(EXCEPTION_INT_OVERFLOW),
289 EXCEPTION_CODE_INFO(EXCEPTION_INVALID_DISPOSITION),
290 EXCEPTION_CODE_INFO(EXCEPTION_INVALID_HANDLE),
291 EXCEPTION_CODE_INFO(EXCEPTION_IN_PAGE_ERROR),
292 EXCEPTION_CODE_INFO(EXCEPTION_NONCONTINUABLE_EXCEPTION),
293 EXCEPTION_CODE_INFO(EXCEPTION_PRIV_INSTRUCTION),
294 EXCEPTION_CODE_INFO(EXCEPTION_STACK_OVERFLOW),
299 /* Exit the currently executing test. */
300 static void exit_test(const int quit_application) {
301 if (global_running_test) {
302 longjmp(global_run_test_env, 1);
303 } else if (quit_application) {
309 /* Initialize a SourceLocation structure. */
310 static void initialize_source_location(SourceLocation * const location) {
311 assert_non_null(location);
312 location->file = NULL;
317 /* Determine whether a source location is currently set. */
318 static int source_location_is_set(const SourceLocation * const location) {
319 assert_non_null(location);
320 return location->file && location->line;
324 /* Set a source location. */
325 static void set_source_location(
326 SourceLocation * const location, const char * const file,
328 assert_non_null(location);
329 location->file = file;
330 location->line = line;
334 /* Create function results and expected parameter lists. */
335 void initialize_testing(const char *test_name) {
337 list_initialize(&global_function_result_map_head);
338 initialize_source_location(&global_last_mock_value_location);
339 list_initialize(&global_function_parameter_map_head);
340 initialize_source_location(&global_last_parameter_location);
344 static void fail_if_leftover_values(const char *test_name) {
345 int error_occurred = 0;
347 remove_always_return_values(&global_function_result_map_head, 1);
348 if (check_for_leftover_values(
349 &global_function_result_map_head,
350 "%s() has remaining non-returned values.\n", 1)) {
354 remove_always_return_values(&global_function_parameter_map_head, 2);
355 if (check_for_leftover_values(
356 &global_function_parameter_map_head,
357 "%s parameter still has values that haven't been checked.\n", 2)) {
360 if (error_occurred) {
366 static void teardown_testing(const char *test_name) {
368 list_free(&global_function_result_map_head, free_symbol_map_value,
370 initialize_source_location(&global_last_mock_value_location);
371 list_free(&global_function_parameter_map_head, free_symbol_map_value,
373 initialize_source_location(&global_last_parameter_location);
376 /* Initialize a list node. */
377 static ListNode* list_initialize(ListNode * const node) {
387 * Adds a value at the tail of a given list.
388 * The node referencing the value is allocated from the heap.
390 static ListNode* list_add_value(ListNode * const head, const void *value,
391 const int refcount) {
392 ListNode * const new_node = (ListNode*)malloc(sizeof(ListNode));
393 assert_non_null(head);
394 assert_non_null(value);
395 new_node->value = value;
396 new_node->refcount = refcount;
397 return list_add(head, new_node);
401 /* Add new_node to the end of the list. */
402 static ListNode* list_add(ListNode * const head, ListNode *new_node) {
403 assert_non_null(head);
404 assert_non_null(new_node);
405 new_node->next = head;
406 new_node->prev = head->prev;
407 head->prev->next = new_node;
408 head->prev = new_node;
413 /* Remove a node from a list. */
414 static ListNode* list_remove(
415 ListNode * const node, const CleanupListValue cleanup_value,
416 void * const cleanup_value_data) {
417 assert_non_null(node);
418 node->prev->next = node->next;
419 node->next->prev = node->prev;
421 cleanup_value(node->value, cleanup_value_data);
427 /* Remove a list node from a list and free the node. */
428 static void list_remove_free(
429 ListNode * const node, const CleanupListValue cleanup_value,
430 void * const cleanup_value_data) {
431 assert_non_null(node);
432 free(list_remove(node, cleanup_value, cleanup_value_data));
437 * Frees memory kept by a linked list The cleanup_value function is called for
438 * every "value" field of nodes in the list, except for the head. In addition
439 * to each list value, cleanup_value_data is passed to each call to
440 * cleanup_value. The head of the list is not deallocated.
442 static ListNode* list_free(
443 ListNode * const head, const CleanupListValue cleanup_value,
444 void * const cleanup_value_data) {
445 assert_non_null(head);
446 while (!list_empty(head)) {
447 list_remove_free(head->next, cleanup_value, cleanup_value_data);
453 /* Determine whether a list is empty. */
454 static int list_empty(const ListNode * const head) {
455 assert_non_null(head);
456 return head->next == head;
461 * Find a value in the list using the equal_func to compare each node with the
464 static int list_find(ListNode * const head, const void *value,
465 const EqualityFunction equal_func, ListNode **output) {
467 assert_non_null(head);
468 for (current = head->next; current != head; current = current->next) {
469 if (equal_func(current->value, value)) {
477 /* Returns the first node of a list */
478 static int list_first(ListNode * const head, ListNode **output) {
479 ListNode *target_node;
480 assert_non_null(head);
481 if (list_empty(head)) {
484 target_node = head->next;
485 *output = target_node;
490 /* Deallocate a value referenced by a list. */
491 static void free_value(const void *value, void *cleanup_value_data) {
492 (void)cleanup_value_data;
493 assert_non_null(value);
498 /* Releases memory associated to a symbol_map_value. */
499 static void free_symbol_map_value(const void *value,
500 void *cleanup_value_data) {
501 SymbolMapValue * const map_value = (SymbolMapValue*)value;
502 const LargestIntegralType children = cast_ptr_to_largest_integral_type(cleanup_value_data);
503 assert_non_null(value);
504 list_free(&map_value->symbol_values_list_head,
505 children ? free_symbol_map_value : free_value,
506 (void *) ((uintptr_t)children - 1));
512 * Determine whether a symbol name referenced by a symbol_map_value matches the
513 * specified function name.
515 static int symbol_names_match(const void *map_value, const void *symbol) {
516 return !strcmp(((SymbolMapValue*)map_value)->symbol_name,
517 (const char*)symbol);
522 * Adds a value to the queue of values associated with the given hierarchy of
523 * symbols. It's assumed value is allocated from the heap.
525 static void add_symbol_value(ListNode * const symbol_map_head,
526 const char * const symbol_names[],
527 const size_t number_of_symbol_names,
528 const void* value, const int refcount) {
529 const char* symbol_name;
530 ListNode *target_node;
531 SymbolMapValue *target_map_value;
532 assert_non_null(symbol_map_head);
533 assert_non_null(symbol_names);
534 assert_true(number_of_symbol_names);
535 symbol_name = symbol_names[0];
537 if (!list_find(symbol_map_head, symbol_name, symbol_names_match,
539 SymbolMapValue * const new_symbol_map_value =
540 (SymbolMapValue*)malloc(sizeof(*new_symbol_map_value));
541 new_symbol_map_value->symbol_name = symbol_name;
542 list_initialize(&new_symbol_map_value->symbol_values_list_head);
543 target_node = list_add_value(symbol_map_head, new_symbol_map_value,
547 target_map_value = (SymbolMapValue*)target_node->value;
548 if (number_of_symbol_names == 1) {
549 list_add_value(&target_map_value->symbol_values_list_head,
552 add_symbol_value(&target_map_value->symbol_values_list_head,
553 &symbol_names[1], number_of_symbol_names - 1, value,
560 * Gets the next value associated with the given hierarchy of symbols.
561 * The value is returned as an output parameter with the function returning the
562 * node's old refcount value if a value is found, 0 otherwise. This means that
563 * a return value of 1 indicates the node was just removed from the list.
565 static int get_symbol_value(
566 ListNode * const head, const char * const symbol_names[],
567 const size_t number_of_symbol_names, void **output) {
568 const char* symbol_name;
569 ListNode *target_node;
570 assert_non_null(head);
571 assert_non_null(symbol_names);
572 assert_true(number_of_symbol_names);
573 assert_non_null(output);
574 symbol_name = symbol_names[0];
576 if (list_find(head, symbol_name, symbol_names_match, &target_node)) {
577 SymbolMapValue *map_value;
578 ListNode *child_list;
579 int return_value = 0;
580 assert_non_null(target_node);
581 assert_non_null(target_node->value);
583 map_value = (SymbolMapValue*)target_node->value;
584 child_list = &map_value->symbol_values_list_head;
586 if (number_of_symbol_names == 1) {
587 ListNode *value_node = NULL;
588 return_value = list_first(child_list, &value_node);
589 assert_true(return_value);
590 *output = (void*) value_node->value;
591 return_value = value_node->refcount;
592 if (--value_node->refcount == 0) {
593 list_remove_free(value_node, NULL, NULL);
596 return_value = get_symbol_value(
597 child_list, &symbol_names[1], number_of_symbol_names - 1,
600 if (list_empty(child_list)) {
601 list_remove_free(target_node, free_symbol_map_value, (void*)0);
605 print_error("No entries for symbol %s.\n", symbol_name);
612 * Traverse down a tree of symbol values and remove the first symbol value
613 * in each branch that has a refcount < -1 (i.e should always be returned
614 * and has been returned at least once).
616 static void remove_always_return_values(ListNode * const map_head,
617 const size_t number_of_symbol_names) {
619 assert_non_null(map_head);
620 assert_true(number_of_symbol_names);
621 current = map_head->next;
622 while (current != map_head) {
623 SymbolMapValue * const value = (SymbolMapValue*)current->value;
624 ListNode * const next = current->next;
625 ListNode *child_list;
626 assert_non_null(value);
627 child_list = &value->symbol_values_list_head;
629 if (!list_empty(child_list)) {
630 if (number_of_symbol_names == 1) {
631 ListNode * const child_node = child_list->next;
632 /* If this item has been returned more than once, free it. */
633 if (child_node->refcount < -1) {
634 list_remove_free(child_node, free_value, NULL);
637 remove_always_return_values(child_list,
638 number_of_symbol_names - 1);
642 if (list_empty(child_list)) {
643 list_remove_free(current, free_value, NULL);
650 * Checks if there are any leftover values set up by the test that were never
651 * retrieved through execution, and fail the test if that is the case.
653 static int check_for_leftover_values(
654 const ListNode * const map_head, const char * const error_message,
655 const size_t number_of_symbol_names) {
656 const ListNode *current;
657 int symbols_with_leftover_values = 0;
658 assert_non_null(map_head);
659 assert_true(number_of_symbol_names);
661 for (current = map_head->next; current != map_head;
662 current = current->next) {
663 const SymbolMapValue * const value =
664 (SymbolMapValue*)current->value;
665 const ListNode *child_list;
666 assert_non_null(value);
667 child_list = &value->symbol_values_list_head;
669 if (!list_empty(child_list)) {
670 if (number_of_symbol_names == 1) {
671 const ListNode *child_node;
672 print_error(error_message, value->symbol_name);
674 for (child_node = child_list->next; child_node != child_list;
675 child_node = child_node->next) {
676 const SourceLocation * const location =
677 (const SourceLocation*)child_node->value;
678 print_error(SOURCE_LOCATION_FORMAT
679 ": note: remaining item was declared here\n",
680 location->file, location->line);
683 print_error("%s.", value->symbol_name);
684 check_for_leftover_values(child_list, error_message,
685 number_of_symbol_names - 1);
687 symbols_with_leftover_values ++;
690 return symbols_with_leftover_values;
694 /* Get the next return value for the specified mock function. */
695 LargestIntegralType _mock(const char * const function, const char* const file,
698 const int rc = get_symbol_value(&global_function_result_map_head,
699 &function, 1, &result);
701 SymbolValue * const symbol = (SymbolValue*)result;
702 const LargestIntegralType value = symbol->value;
703 global_last_mock_value_location = symbol->location;
709 print_error(SOURCE_LOCATION_FORMAT ": error: Could not get value "
710 "to mock function %s\n", file, line, function);
711 if (source_location_is_set(&global_last_mock_value_location)) {
712 print_error(SOURCE_LOCATION_FORMAT
713 ": note: Previously returned mock value was declared here\n",
714 global_last_mock_value_location.file,
715 global_last_mock_value_location.line);
717 print_error("There were no previously returned mock values for "
726 /* Add a return value for the specified mock function name. */
727 void _will_return(const char * const function_name, const char * const file,
728 const int line, const LargestIntegralType value,
730 SymbolValue * const return_value =
731 (SymbolValue*)malloc(sizeof(*return_value));
732 assert_true(count > 0 || count == -1);
733 return_value->value = value;
734 set_source_location(&return_value->location, file, line);
735 add_symbol_value(&global_function_result_map_head, &function_name, 1,
736 return_value, count);
741 * Add a custom parameter checking function. If the event parameter is NULL
742 * the event structure is allocated internally by this function. If event
743 * parameter is provided it must be allocated on the heap and doesn't need to
744 * be deallocated by the caller.
747 const char* const function, const char* const parameter,
748 const char* const file, const int line,
749 const CheckParameterValue check_function,
750 const LargestIntegralType check_data,
751 CheckParameterEvent * const event, const int count) {
752 CheckParameterEvent * const check =
753 event ? event : (CheckParameterEvent*)malloc(sizeof(*check));
754 const char* symbols[] = {function, parameter};
755 check->parameter_name = parameter;
756 check->check_value = check_function;
757 check->check_value_data = check_data;
758 set_source_location(&check->location, file, line);
759 add_symbol_value(&global_function_parameter_map_head, symbols, 2, check,
764 /* Returns 1 if the specified values are equal. If the values are not equal
765 * an error is displayed and 0 is returned. */
766 static int values_equal_display_error(const LargestIntegralType left,
767 const LargestIntegralType right) {
768 const int equal = left == right;
770 print_error(LargestIntegralTypePrintfFormat " != "
771 LargestIntegralTypePrintfFormat "\n", left, right);
777 * Returns 1 if the specified values are not equal. If the values are equal
778 * an error is displayed and 0 is returned. */
779 static int values_not_equal_display_error(const LargestIntegralType left,
780 const LargestIntegralType right) {
781 const int not_equal = left != right;
783 print_error(LargestIntegralTypePrintfFormat " == "
784 LargestIntegralTypePrintfFormat "\n", left, right);
791 * Determine whether value is contained within check_integer_set.
792 * If invert is 0 and the value is in the set 1 is returned, otherwise 0 is
793 * returned and an error is displayed. If invert is 1 and the value is not
794 * in the set 1 is returned, otherwise 0 is returned and an error is
797 static int value_in_set_display_error(
798 const LargestIntegralType value,
799 const CheckIntegerSet * const check_integer_set, const int invert) {
800 int succeeded = invert;
801 assert_non_null(check_integer_set);
803 const LargestIntegralType * const set = check_integer_set->set;
804 const size_t size_of_set = check_integer_set->size_of_set;
806 for (i = 0; i < size_of_set; i++) {
807 if (set[i] == value) {
808 /* If invert = 0 and item is found, succeeded = 1. */
809 /* If invert = 1 and item is found, succeeded = 0. */
810 succeeded = !succeeded;
817 print_error("%llu is %sin the set (", value, invert ? "" : "not ");
818 for (i = 0; i < size_of_set; i++) {
819 print_error("%llu, ", set[i]);
828 * Determine whether a value is within the specified range. If the value is
829 * within the specified range 1 is returned. If the value isn't within the
830 * specified range an error is displayed and 0 is returned.
832 static int integer_in_range_display_error(
833 const LargestIntegralType value, const LargestIntegralType range_min,
834 const LargestIntegralType range_max) {
835 if (value >= range_min && value <= range_max) {
838 print_error("%llu is not within the range %llu-%llu\n", value, range_min,
845 * Determine whether a value is within the specified range. If the value
846 * is not within the range 1 is returned. If the value is within the
847 * specified range an error is displayed and zero is returned.
849 static int integer_not_in_range_display_error(
850 const LargestIntegralType value, const LargestIntegralType range_min,
851 const LargestIntegralType range_max) {
852 if (value < range_min || value > range_max) {
855 print_error("%llu is within the range %llu-%llu\n", value, range_min,
862 * Determine whether the specified strings are equal. If the strings are equal
863 * 1 is returned. If they're not equal an error is displayed and 0 is
866 static int string_equal_display_error(
867 const char * const left, const char * const right) {
868 if (strcmp(left, right) == 0) {
871 print_error("\"%s\" != \"%s\"\n", left, right);
877 * Determine whether the specified strings are equal. If the strings are not
878 * equal 1 is returned. If they're not equal an error is displayed and 0 is
881 static int string_not_equal_display_error(
882 const char * const left, const char * const right) {
883 if (strcmp(left, right) != 0) {
886 print_error("\"%s\" == \"%s\"\n", left, right);
892 * Determine whether the specified areas of memory are equal. If they're equal
893 * 1 is returned otherwise an error is displayed and 0 is returned.
895 static int memory_equal_display_error(const char* const a, const char* const b,
899 for (i = 0; i < size; i++) {
903 print_error("difference at offset %" PRIdS " 0x%02x 0x%02x\n",
909 print_error("%d bytes of %p and %p differ\n", differences,
918 * Determine whether the specified areas of memory are not equal. If they're
919 * not equal 1 is returned otherwise an error is displayed and 0 is
922 static int memory_not_equal_display_error(
923 const char* const a, const char* const b, const size_t size) {
926 for (i = 0; i < size; i++) {
934 print_error("%"PRIdS "bytes of %p and %p the same\n", same,
942 /* CheckParameterValue callback to check whether a value is within a set. */
943 static int check_in_set(const LargestIntegralType value,
944 const LargestIntegralType check_value_data) {
945 return value_in_set_display_error(value,
946 cast_largest_integral_type_to_pointer(CheckIntegerSet*,
947 check_value_data), 0);
951 /* CheckParameterValue callback to check whether a value isn't within a set. */
952 static int check_not_in_set(const LargestIntegralType value,
953 const LargestIntegralType check_value_data) {
954 return value_in_set_display_error(value,
955 cast_largest_integral_type_to_pointer(CheckIntegerSet*,
956 check_value_data), 1);
960 /* Create the callback data for check_in_set() or check_not_in_set() and
961 * register a check event. */
962 static void expect_set(
963 const char* const function, const char* const parameter,
964 const char* const file, const int line,
965 const LargestIntegralType values[], const size_t number_of_values,
966 const CheckParameterValue check_function, const int count) {
967 CheckIntegerSet * const check_integer_set =
968 (CheckIntegerSet*)malloc(sizeof(*check_integer_set) +
969 (sizeof(values[0]) * number_of_values));
970 LargestIntegralType * const set = (LargestIntegralType*)(
971 check_integer_set + 1);
972 declare_initialize_value_pointer_pointer(check_data, check_integer_set);
973 assert_non_null(values);
974 assert_true(number_of_values);
975 memcpy(set, values, number_of_values * sizeof(values[0]));
976 check_integer_set->set = set;
978 function, parameter, file, line, check_function,
979 check_data.value, &check_integer_set->event, count);
983 /* Add an event to check whether a value is in a set. */
985 const char* const function, const char* const parameter,
986 const char* const file, const int line,
987 const LargestIntegralType values[], const size_t number_of_values,
989 expect_set(function, parameter, file, line, values, number_of_values,
990 check_in_set, count);
994 /* Add an event to check whether a value isn't in a set. */
995 void _expect_not_in_set(
996 const char* const function, const char* const parameter,
997 const char* const file, const int line,
998 const LargestIntegralType values[], const size_t number_of_values,
1000 expect_set(function, parameter, file, line, values, number_of_values,
1001 check_not_in_set, count);
1005 /* CheckParameterValue callback to check whether a value is within a range. */
1006 static int check_in_range(const LargestIntegralType value,
1007 const LargestIntegralType check_value_data) {
1008 CheckIntegerRange * const check_integer_range =
1009 cast_largest_integral_type_to_pointer(CheckIntegerRange*,
1011 assert_non_null(check_integer_range);
1012 return integer_in_range_display_error(value, check_integer_range->minimum,
1013 check_integer_range->maximum);
1017 /* CheckParameterValue callback to check whether a value is not within a range. */
1018 static int check_not_in_range(const LargestIntegralType value,
1019 const LargestIntegralType check_value_data) {
1020 CheckIntegerRange * const check_integer_range =
1021 cast_largest_integral_type_to_pointer(CheckIntegerRange*,
1023 assert_non_null(check_integer_range);
1024 return integer_not_in_range_display_error(
1025 value, check_integer_range->minimum, check_integer_range->maximum);
1029 /* Create the callback data for check_in_range() or check_not_in_range() and
1030 * register a check event. */
1031 static void expect_range(
1032 const char* const function, const char* const parameter,
1033 const char* const file, const int line,
1034 const LargestIntegralType minimum, const LargestIntegralType maximum,
1035 const CheckParameterValue check_function, const int count) {
1036 CheckIntegerRange * const check_integer_range =
1037 (CheckIntegerRange*)malloc(sizeof(*check_integer_range));
1038 declare_initialize_value_pointer_pointer(check_data, check_integer_range);
1039 check_integer_range->minimum = minimum;
1040 check_integer_range->maximum = maximum;
1041 _expect_check(function, parameter, file, line, check_function,
1042 check_data.value, &check_integer_range->event, count);
1046 /* Add an event to determine whether a parameter is within a range. */
1047 void _expect_in_range(
1048 const char* const function, const char* const parameter,
1049 const char* const file, const int line,
1050 const LargestIntegralType minimum, const LargestIntegralType maximum,
1052 expect_range(function, parameter, file, line, minimum, maximum,
1053 check_in_range, count);
1057 /* Add an event to determine whether a parameter is not within a range. */
1058 void _expect_not_in_range(
1059 const char* const function, const char* const parameter,
1060 const char* const file, const int line,
1061 const LargestIntegralType minimum, const LargestIntegralType maximum,
1063 expect_range(function, parameter, file, line, minimum, maximum,
1064 check_not_in_range, count);
1068 /* CheckParameterValue callback to check whether a value is equal to an
1069 * expected value. */
1070 static int check_value(const LargestIntegralType value,
1071 const LargestIntegralType check_value_data) {
1072 return values_equal_display_error(value, check_value_data);
1076 /* Add an event to check a parameter equals an expected value. */
1078 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,
1086 /* CheckParameterValue callback to check whether a value is not equal to an
1087 * expected value. */
1088 static int check_not_value(const LargestIntegralType value,
1089 const LargestIntegralType check_value_data) {
1090 return values_not_equal_display_error(value, check_value_data);
1094 /* Add an event to check a parameter is not equal to an expected value. */
1095 void _expect_not_value(
1096 const char* const function, const char* const parameter,
1097 const char* const file, const int line,
1098 const LargestIntegralType value, const int count) {
1099 _expect_check(function, parameter, file, line, check_not_value, value,
1104 /* CheckParameterValue callback to check whether a parameter equals a string. */
1105 static int check_string(const LargestIntegralType value,
1106 const LargestIntegralType check_value_data) {
1107 return string_equal_display_error(
1108 cast_largest_integral_type_to_pointer(char*, value),
1109 cast_largest_integral_type_to_pointer(char*, check_value_data));
1113 /* Add an event to check whether a parameter is equal to a string. */
1114 void _expect_string(
1115 const char* const function, const char* const parameter,
1116 const char* const file, const int line, const char* string,
1118 declare_initialize_value_pointer_pointer(string_pointer,
1119 discard_const(string));
1120 _expect_check(function, parameter, file, line, check_string,
1121 string_pointer.value, NULL, count);
1125 /* CheckParameterValue callback to check whether a parameter is not equals to
1127 static int check_not_string(const LargestIntegralType value,
1128 const LargestIntegralType check_value_data) {
1129 return string_not_equal_display_error(
1130 cast_largest_integral_type_to_pointer(char*, value),
1131 cast_largest_integral_type_to_pointer(char*, check_value_data));
1135 /* Add an event to check whether a parameter is not equal to a string. */
1136 void _expect_not_string(
1137 const char* const function, const char* const parameter,
1138 const char* const file, const int line, const char* string,
1140 declare_initialize_value_pointer_pointer(string_pointer,
1141 discard_const(string));
1142 _expect_check(function, parameter, file, line, check_not_string,
1143 string_pointer.value, NULL, count);
1146 /* CheckParameterValue callback to check whether a parameter equals an area of
1148 static int check_memory(const LargestIntegralType value,
1149 const LargestIntegralType check_value_data) {
1150 CheckMemoryData * const check = cast_largest_integral_type_to_pointer(
1151 CheckMemoryData*, check_value_data);
1152 assert_non_null(check);
1153 return memory_equal_display_error(
1154 cast_largest_integral_type_to_pointer(const char*, value),
1155 (const char*)check->memory, check->size);
1159 /* Create the callback data for check_memory() or check_not_memory() and
1160 * register a check event. */
1161 static void expect_memory_setup(
1162 const char* const function, const char* const parameter,
1163 const char* const file, const int line,
1164 const void * const memory, const size_t size,
1165 const CheckParameterValue check_function, const int count) {
1166 CheckMemoryData * const check_data =
1167 (CheckMemoryData*)malloc(sizeof(*check_data) + size);
1168 void * const mem = (void*)(check_data + 1);
1169 declare_initialize_value_pointer_pointer(check_data_pointer, check_data);
1170 assert_non_null(memory);
1172 memcpy(mem, memory, size);
1173 check_data->memory = mem;
1174 check_data->size = size;
1175 _expect_check(function, parameter, file, line, check_function,
1176 check_data_pointer.value, &check_data->event, count);
1180 /* Add an event to check whether a parameter matches an area of memory. */
1181 void _expect_memory(
1182 const char* const function, const char* const parameter,
1183 const char* const file, const int line, const void* const memory,
1184 const size_t size, const int count) {
1185 expect_memory_setup(function, parameter, file, line, memory, size,
1186 check_memory, count);
1190 /* CheckParameterValue callback to check whether a parameter is not equal to
1191 * an area of memory. */
1192 static int check_not_memory(const LargestIntegralType value,
1193 const LargestIntegralType check_value_data) {
1194 CheckMemoryData * const check = cast_largest_integral_type_to_pointer(
1195 CheckMemoryData*, check_value_data);
1196 assert_non_null(check);
1197 return memory_not_equal_display_error(
1198 cast_largest_integral_type_to_pointer(const char*, value),
1199 (const char*)check->memory,
1204 /* Add an event to check whether a parameter doesn't match an area of memory. */
1205 void _expect_not_memory(
1206 const char* const function, const char* const parameter,
1207 const char* const file, const int line, const void* const memory,
1208 const size_t size, const int count) {
1209 expect_memory_setup(function, parameter, file, line, memory, size,
1210 check_not_memory, count);
1214 /* CheckParameterValue callback that always returns 1. */
1215 static int check_any(const LargestIntegralType value,
1216 const LargestIntegralType check_value_data) {
1218 (void)check_value_data;
1223 /* Add an event to allow any value for a parameter. */
1225 const char* const function, const char* const parameter,
1226 const char* const file, const int line, const int count) {
1227 _expect_check(function, parameter, file, line, check_any, 0, NULL,
1232 void _check_expected(
1233 const char * const function_name, const char * const parameter_name,
1234 const char* file, const int line, const LargestIntegralType value) {
1236 const char* symbols[] = {function_name, parameter_name};
1237 const int rc = get_symbol_value(&global_function_parameter_map_head,
1238 symbols, 2, &result);
1240 CheckParameterEvent * const check = (CheckParameterEvent*)result;
1241 int check_succeeded;
1242 global_last_parameter_location = check->location;
1243 check_succeeded = check->check_value(value, check->check_value_data);
1247 if (!check_succeeded) {
1248 print_error(SOURCE_LOCATION_FORMAT
1249 ": error: Check of parameter %s, function %s failed\n"
1250 SOURCE_LOCATION_FORMAT
1251 ": note: Expected parameter declared here\n",
1253 parameter_name, function_name,
1254 global_last_parameter_location.file,
1255 global_last_parameter_location.line);
1259 print_error(SOURCE_LOCATION_FORMAT ": error: Could not get value "
1260 "to check parameter %s of function %s\n", file, line,
1261 parameter_name, function_name);
1262 if (source_location_is_set(&global_last_parameter_location)) {
1263 print_error(SOURCE_LOCATION_FORMAT
1264 ": note: Previously declared parameter value was declared here\n",
1265 global_last_parameter_location.file,
1266 global_last_parameter_location.line);
1268 print_error("There were no previously declared parameter values "
1269 "for this test.\n");
1276 /* Replacement for assert. */
1277 void mock_assert(const int result, const char* const expression,
1278 const char* const file, const int line) {
1280 if (global_expecting_assert) {
1281 global_last_failed_assert = expression;
1282 longjmp(global_expect_assert_env, result);
1284 print_error("ASSERT: %s\n", expression);
1291 void _assert_true(const LargestIntegralType result,
1292 const char * const expression,
1293 const char * const file, const int line) {
1295 print_error("%s\n", expression);
1300 void _assert_return_code(const LargestIntegralType result,
1302 const LargestIntegralType error,
1303 const char * const expression,
1304 const char * const file,
1307 LargestIntegralType valmax;
1318 valmax = 2147483647;
1322 if (rlen > sizeof(valmax)) {
1323 valmax = 2147483647;
1325 valmax = 9223372036854775807L;
1330 if (result > valmax - 1) {
1332 print_error("%s < 0, errno(%llu): %s\n",
1333 expression, error, strerror(error));
1335 print_error("%s < 0\n", expression);
1341 void _assert_int_equal(
1342 const LargestIntegralType a, const LargestIntegralType b,
1343 const char * const file, const int line) {
1344 if (!values_equal_display_error(a, b)) {
1350 void _assert_int_not_equal(
1351 const LargestIntegralType a, const LargestIntegralType b,
1352 const char * const file, const int line) {
1353 if (!values_not_equal_display_error(a, b)) {
1359 void _assert_string_equal(const char * const a, const char * const b,
1360 const char * const file, const int line) {
1361 if (!string_equal_display_error(a, b)) {
1367 void _assert_string_not_equal(const char * const a, const char * const b,
1368 const char *file, const int line) {
1369 if (!string_not_equal_display_error(a, b)) {
1375 void _assert_memory_equal(const void * const a, const void * const b,
1376 const size_t size, const char* const file,
1378 if (!memory_equal_display_error((const char*)a, (const char*)b, size)) {
1384 void _assert_memory_not_equal(const void * const a, const void * const b,
1385 const size_t size, const char* const file,
1387 if (!memory_not_equal_display_error((const char*)a, (const char*)b,
1394 void _assert_in_range(
1395 const LargestIntegralType value, const LargestIntegralType minimum,
1396 const LargestIntegralType maximum, const char* const file,
1398 if (!integer_in_range_display_error(value, minimum, maximum)) {
1403 void _assert_not_in_range(
1404 const LargestIntegralType value, const LargestIntegralType minimum,
1405 const LargestIntegralType maximum, const char* const file,
1407 if (!integer_not_in_range_display_error(value, minimum, maximum)) {
1412 void _assert_in_set(const LargestIntegralType value,
1413 const LargestIntegralType values[],
1414 const size_t number_of_values, const char* const file,
1416 CheckIntegerSet check_integer_set;
1417 check_integer_set.set = values;
1418 check_integer_set.size_of_set = number_of_values;
1419 if (!value_in_set_display_error(value, &check_integer_set, 0)) {
1424 void _assert_not_in_set(const LargestIntegralType value,
1425 const LargestIntegralType values[],
1426 const size_t number_of_values, const char* const file,
1428 CheckIntegerSet check_integer_set;
1429 check_integer_set.set = values;
1430 check_integer_set.size_of_set = number_of_values;
1431 if (!value_in_set_display_error(value, &check_integer_set, 1)) {
1437 /* Get the list of allocated blocks. */
1438 static ListNode* get_allocated_blocks_list() {
1439 /* If it initialized, initialize the list of allocated blocks. */
1440 if (!global_allocated_blocks.value) {
1441 list_initialize(&global_allocated_blocks);
1442 global_allocated_blocks.value = (void*)1;
1444 return &global_allocated_blocks;
1447 /* Use the real malloc in this function. */
1449 void* _test_malloc(const size_t size, const char* file, const int line) {
1451 MallocBlockInfo *block_info;
1452 ListNode * const block_list = get_allocated_blocks_list();
1453 const size_t allocate_size = size + (MALLOC_GUARD_SIZE * 2) +
1454 sizeof(*block_info) + MALLOC_ALIGNMENT;
1455 char* const block = (char*)malloc(allocate_size);
1456 assert_non_null(block);
1458 /* Calculate the returned address. */
1459 ptr = (char*)(((size_t)block + MALLOC_GUARD_SIZE + sizeof(*block_info) +
1460 MALLOC_ALIGNMENT) & ~(MALLOC_ALIGNMENT - 1));
1462 /* Initialize the guard blocks. */
1463 memset(ptr - MALLOC_GUARD_SIZE, MALLOC_GUARD_PATTERN, MALLOC_GUARD_SIZE);
1464 memset(ptr + size, MALLOC_GUARD_PATTERN, MALLOC_GUARD_SIZE);
1465 memset(ptr, MALLOC_ALLOC_PATTERN, size);
1467 block_info = (MallocBlockInfo*)(ptr - (MALLOC_GUARD_SIZE +
1468 sizeof(*block_info)));
1469 set_source_location(&block_info->location, file, line);
1470 block_info->allocated_size = allocate_size;
1471 block_info->size = size;
1472 block_info->block = block;
1473 block_info->node.value = block_info;
1474 list_add(block_list, &block_info->node);
1477 #define malloc test_malloc
1480 void* _test_calloc(const size_t number_of_elements, const size_t size,
1481 const char* file, const int line) {
1482 void* const ptr = _test_malloc(number_of_elements * size, file, line);
1484 memset(ptr, 0, number_of_elements * size);
1490 /* Use the real free in this function. */
1492 void _test_free(void* const ptr, const char* file, const int line) {
1494 char *block = discard_const_p(char, ptr);
1496 MallocBlockInfo *block_info;
1497 _assert_true(cast_ptr_to_largest_integral_type(ptr), "ptr", file, line);
1498 block_info = (MallocBlockInfo*)(block - (MALLOC_GUARD_SIZE +
1499 sizeof(*block_info)));
1500 /* Check the guard blocks. */
1502 char *guards[2] = {block - MALLOC_GUARD_SIZE,
1503 block + block_info->size};
1504 for (i = 0; i < ARRAY_LENGTH(guards); i++) {
1506 char * const guard = guards[i];
1507 for (j = 0; j < MALLOC_GUARD_SIZE; j++) {
1508 const char diff = guard[j] - MALLOC_GUARD_PATTERN;
1510 print_error(SOURCE_LOCATION_FORMAT
1511 ": error: Guard block of %p size=%lu is corrupt\n"
1512 SOURCE_LOCATION_FORMAT ": note: allocated here at %p\n",
1514 ptr, (unsigned long)block_info->size,
1515 block_info->location.file, block_info->location.line,
1522 list_remove(&block_info->node, NULL, NULL);
1524 block = discard_const_p(char, block_info->block);
1525 memset(block, MALLOC_FREE_PATTERN, block_info->allocated_size);
1528 #define free test_free
1531 /* Crudely checkpoint the current heap state. */
1532 static const ListNode* check_point_allocated_blocks() {
1533 return get_allocated_blocks_list()->prev;
1537 /* Display the blocks allocated after the specified check point. This
1538 * function returns the number of blocks displayed. */
1539 static int display_allocated_blocks(const ListNode * const check_point) {
1540 const ListNode * const head = get_allocated_blocks_list();
1541 const ListNode *node;
1542 int allocated_blocks = 0;
1543 assert_non_null(check_point);
1544 assert_non_null(check_point->next);
1546 for (node = check_point->next; node != head; node = node->next) {
1547 const MallocBlockInfo * const block_info =
1548 (const MallocBlockInfo*)node->value;
1549 assert_non_null(block_info);
1551 if (!allocated_blocks) {
1552 print_error("Blocks allocated...\n");
1554 print_error(SOURCE_LOCATION_FORMAT ": note: block %p allocated here\n",
1555 block_info->location.file,
1556 block_info->location.line,
1558 allocated_blocks ++;
1560 return allocated_blocks;
1564 /* Free all blocks allocated after the specified check point. */
1565 static void free_allocated_blocks(const ListNode * const check_point) {
1566 const ListNode * const head = get_allocated_blocks_list();
1567 const ListNode *node;
1568 assert_non_null(check_point);
1570 node = check_point->next;
1571 assert_non_null(node);
1573 while (node != head) {
1574 MallocBlockInfo * const block_info = (MallocBlockInfo*)node->value;
1576 free(discard_const_p(char, block_info) + sizeof(*block_info) + MALLOC_GUARD_SIZE);
1581 /* Fail if any any blocks are allocated after the specified check point. */
1582 static void fail_if_blocks_allocated(const ListNode * const check_point,
1583 const char * const test_name) {
1584 const int allocated_blocks = display_allocated_blocks(check_point);
1585 if (allocated_blocks) {
1586 free_allocated_blocks(check_point);
1587 print_error("ERROR: %s leaked %d block(s)\n", test_name,
1594 void _fail(const char * const file, const int line) {
1595 print_error(SOURCE_LOCATION_FORMAT ": error: Failure!\n", file, line);
1601 static void exception_handler(int sig) {
1602 #ifdef HAVE_STRSIGNAL
1603 print_error("Test failed with exception: %s\n", strsignal(sig));
1605 print_error("Test failed with exception: %d\n", sig);
1612 static LONG WINAPI exception_filter(EXCEPTION_POINTERS *exception_pointers) {
1613 EXCEPTION_RECORD * const exception_record =
1614 exception_pointers->ExceptionRecord;
1615 const DWORD code = exception_record->ExceptionCode;
1617 for (i = 0; i < ARRAY_LENGTH(exception_codes); i++) {
1618 const ExceptionCodeInfo * const code_info = &exception_codes[i];
1619 if (code == code_info->code) {
1620 static int shown_debug_message = 0;
1622 print_error("%s occurred at 0x%08x.\n", code_info->description,
1623 exception_record->ExceptionAddress);
1624 if (!shown_debug_message) {
1627 "To debug in Visual Studio...\n"
1628 "1. Select menu item File->Open Project\n"
1629 "2. Change 'Files of type' to 'Executable Files'\n"
1630 "3. Open this executable.\n"
1631 "4. Select menu item Debug->Start\n"
1633 "Alternatively, set the environment variable \n"
1634 "UNIT_TESTING_DEBUG to 1 and rebuild this executable, \n"
1635 "then click 'Debug' in the popup dialog box.\n"
1637 shown_debug_message = 1;
1640 return EXCEPTION_EXECUTE_HANDLER;
1643 return EXCEPTION_CONTINUE_SEARCH;
1645 #endif /* !_WIN32 */
1648 /* Standard output and error print methods. */
1649 void vprint_message(const char* const format, va_list args) {
1651 vsnprintf(buffer, sizeof(buffer), format, args);
1652 printf("%s", buffer);
1655 OutputDebugString(buffer);
1660 void vprint_error(const char* const format, va_list args) {
1662 vsnprintf(buffer, sizeof(buffer), format, args);
1663 fprintf(stderr, "%s", buffer);
1666 OutputDebugString(buffer);
1671 void print_message(const char* const format, ...) {
1673 va_start(args, format);
1674 vprint_message(format, args);
1679 void print_error(const char* const format, ...) {
1681 va_start(args, format);
1682 vprint_error(format, args);
1688 const char * const function_name, const UnitTestFunction Function,
1689 void ** const volatile state, const UnitTestFunctionType function_type,
1690 const void* const heap_check_point) {
1691 const ListNode * const volatile check_point = (const ListNode*)
1693 heap_check_point : check_point_allocated_blocks());
1694 void *current_state = NULL;
1695 volatile int rc = 1;
1696 int handle_exceptions = 1;
1698 handle_exceptions = !IsDebuggerPresent();
1700 #ifdef UNIT_TESTING_DEBUG
1701 handle_exceptions = 0;
1702 #endif /* UNIT_TESTING_DEBUG */
1704 if (handle_exceptions) {
1707 for (i = 0; i < ARRAY_LENGTH(exception_signals); i++) {
1708 default_signal_functions[i] = signal(
1709 exception_signals[i], exception_handler);
1712 previous_exception_filter = SetUnhandledExceptionFilter(
1714 #endif /* !_WIN32 */
1717 if (function_type == UNIT_TEST_FUNCTION_TYPE_TEST) {
1718 print_message("[ RUN ] %s\n", function_name);
1720 initialize_testing(function_name);
1721 global_running_test = 1;
1722 if (setjmp(global_run_test_env) == 0) {
1723 Function(state ? state : ¤t_state);
1724 fail_if_leftover_values(function_name);
1726 /* If this is a setup function then ignore any allocated blocks
1727 * only ensure they're deallocated on tear down. */
1728 if (function_type != UNIT_TEST_FUNCTION_TYPE_SETUP) {
1729 fail_if_blocks_allocated(check_point, function_name);
1732 global_running_test = 0;
1734 if (function_type == UNIT_TEST_FUNCTION_TYPE_TEST) {
1735 print_message("[ OK ] %s\n", function_name);
1739 global_running_test = 0;
1740 print_message("[ FAILED ] %s\n", function_name);
1742 teardown_testing(function_name);
1744 if (handle_exceptions) {
1747 for (i = 0; i < ARRAY_LENGTH(exception_signals); i++) {
1748 signal(exception_signals[i], default_signal_functions[i]);
1751 if (previous_exception_filter) {
1752 SetUnhandledExceptionFilter(previous_exception_filter);
1753 previous_exception_filter = NULL;
1755 #endif /* !_WIN32 */
1762 int _run_tests(const UnitTest * const tests, const size_t number_of_tests) {
1763 /* Whether to execute the next test. */
1764 int run_next_test = 1;
1765 /* Whether the previous test failed. */
1766 int previous_test_failed = 0;
1767 /* Whether the previous setup failed. */
1768 int previous_setup_failed = 0;
1769 /* Check point of the heap state. */
1770 const ListNode * const check_point = check_point_allocated_blocks();
1771 /* Current test being executed. */
1772 size_t current_test = 0;
1773 /* Number of tests executed. */
1774 size_t tests_executed = 0;
1775 /* Number of failed tests. */
1776 size_t total_failed = 0;
1777 /* Number of setup functions. */
1779 /* Number of teardown functions. */
1780 size_t teardowns = 0;
1782 * A stack of test states. A state is pushed on the stack
1783 * when a test setup occurs and popped on tear down.
1785 TestState* test_states =
1786 (TestState*)malloc(number_of_tests * sizeof(*test_states));
1787 size_t number_of_test_states = 0;
1788 /* Names of the tests that failed. */
1789 const char** failed_names = (const char**)malloc(number_of_tests *
1790 sizeof(*failed_names));
1791 void **current_state = NULL;
1793 print_message("[==========] Running %"PRIdS " test(s).\n", number_of_tests);
1795 /* Make sure LargestIntegralType is at least the size of a pointer. */
1796 assert_true(sizeof(LargestIntegralType) >= sizeof(void*));
1798 while (current_test < number_of_tests) {
1799 const ListNode *test_check_point = NULL;
1800 TestState *current_TestState;
1801 const UnitTest * const test = &tests[current_test++];
1802 if (!test->function) {
1806 switch (test->function_type) {
1807 case UNIT_TEST_FUNCTION_TYPE_TEST:
1808 if (! previous_setup_failed) {
1812 case UNIT_TEST_FUNCTION_TYPE_SETUP: {
1813 /* Checkpoint the heap before the setup. */
1814 current_TestState = &test_states[number_of_test_states++];
1815 current_TestState->check_point = check_point_allocated_blocks();
1816 test_check_point = current_TestState->check_point;
1817 current_state = ¤t_TestState->state;
1818 *current_state = NULL;
1823 case UNIT_TEST_FUNCTION_TYPE_TEARDOWN:
1824 /* Check the heap based on the last setup checkpoint. */
1825 assert_true(number_of_test_states);
1826 current_TestState = &test_states[--number_of_test_states];
1827 test_check_point = current_TestState->check_point;
1828 current_state = ¤t_TestState->state;
1832 print_error("Invalid unit test function type %d\n",
1833 test->function_type);
1838 if (run_next_test) {
1839 int failed = _run_test(test->name, test->function, current_state,
1840 test->function_type, test_check_point);
1842 failed_names[total_failed] = test->name;
1845 switch (test->function_type) {
1846 case UNIT_TEST_FUNCTION_TYPE_TEST:
1847 previous_test_failed = failed;
1848 total_failed += failed;
1852 case UNIT_TEST_FUNCTION_TYPE_SETUP:
1856 /* Skip forward until the next test or setup function. */
1858 previous_setup_failed = 1;
1860 previous_test_failed = 0;
1863 case UNIT_TEST_FUNCTION_TYPE_TEARDOWN:
1864 /* If this test failed. */
1865 if (failed && !previous_test_failed) {
1871 assert_null("BUG: shouldn't be here!");
1878 print_message("[==========] %"PRIdS " test(s) run.\n", tests_executed);
1879 print_error("[ PASSED ] %"PRIdS " test(s).\n", tests_executed - total_failed);
1883 print_error("[ FAILED ] %"PRIdS " test(s), listed below:\n", total_failed);
1884 for (i = 0; i < total_failed; i++) {
1885 print_error("[ FAILED ] %s\n", failed_names[i]);
1888 print_error("\n %"PRIdS " FAILED TEST(S)\n", total_failed);
1891 if (number_of_test_states) {
1892 print_error("[ ERROR ] Mismatched number of setup %"PRIdS " and "
1893 "teardown %"PRIdS " functions\n", setups, teardowns);
1894 total_failed = (size_t)-1;
1898 free((void*)failed_names);
1900 fail_if_blocks_allocated(check_point, "run_tests");
1901 return (int)total_failed;