Fix for "Issue 7: value_in_set_display_error() falsely reports errors." reported...
[platform/upstream/cmocka.git] / src / cmockery.c
1 /*
2  * Copyright 2008 Google Inc.
3  *
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
7  * 
8  * http://www.apache.org/licenses/LICENSE-2.0
9  * 
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.
15  */
16 #include <malloc.h>
17 #include <setjmp.h>
18 #ifndef _WIN32
19 #include <signal.h>
20 #endif // !_WIN32
21 #include <stdarg.h>
22 #include <stddef.h>
23 #include <stdio.h>
24 #include <stdlib.h>
25 #include <string.h>
26 #ifdef _WIN32
27 #include <windows.h>
28 #endif // _WIN32
29 #include <cmockery.h>
30
31 #ifdef _WIN32
32 #define vsnprintf _vsnprintf
33 #endif // _WIN32
34
35 /* Backwards compatibility with headers shipped with Visual Studio 2005 and
36  * earlier. */
37 #ifdef _WIN32
38 WINBASEAPI BOOL WINAPI IsDebuggerPresent(VOID);
39 #endif // _WIN32
40
41 // Size of guard bytes around dynamically allocated blocks.
42 #define MALLOC_GUARD_SIZE 16
43 // Pattern used to initialize guard blocks.
44 #define MALLOC_GUARD_PATTERN 0xEF
45 // Pattern used to initialize memory allocated with test_malloc().
46 #define MALLOC_ALLOC_PATTERN 0xBA
47 #define MALLOC_FREE_PATTERN 0xCD
48 // Alignment of allocated blocks.  NOTE: This must be base2.
49 #define MALLOC_ALIGNMENT sizeof(size_t)
50
51 // Printf formatting for source code locations.
52 #define SOURCE_LOCATION_FORMAT "%s:%d"
53
54 // Calculates the number of elements in an array.
55 #define ARRAY_LENGTH(x) (sizeof(x) / sizeof((x)[0]))
56
57 // Doubly linked list node.
58 typedef struct ListNode {
59         const void *value;
60         int refcount;
61         struct ListNode *next;
62         struct ListNode *prev;
63 } ListNode;
64
65 // Debug information for malloc().
66 typedef struct MallocBlockInfo {
67         void* block;              // Address of the block returned by malloc().
68         size_t allocated_size;    // Total size of the allocated block.
69         size_t size;              // Request block size.
70         SourceLocation location;  // Where the block was allocated.
71         ListNode node;            // Node within list of all allocated blocks.
72 } MallocBlockInfo;
73
74 // State of each test.
75 typedef struct TestState {
76         const ListNode *check_point; // Check point of the test if there's a 
77                                      // setup function.
78         void *state;                 // State associated with the test.
79 } TestState;
80
81 // Determines whether two values are the same.
82 typedef int (*EqualityFunction)(const void *left, const void *right);
83
84 // Value of a symbol and the place it was declared.
85 typedef struct SymbolValue {
86         SourceLocation location;
87         const void* value;
88 } SymbolValue;
89
90 /* Contains a list of values for a symbol.
91  * NOTE: Each structure referenced by symbol_values_list_head must have a 
92  * SourceLocation as its' first member.
93  */
94 typedef struct SymbolMapValue {
95         const char *symbol_name;
96         ListNode symbol_values_list_head;
97 } SymbolMapValue;
98
99 // Used by list_free() to deallocate values referenced by list nodes.
100 typedef void (*CleanupListValue)(const void *value, void *cleanup_value_data);
101
102 // Structure used to check the range of integer types.
103 typedef struct CheckIntegerRange {
104         CheckParameterEvent event;
105         int minimum;
106         int maximum;
107 } CheckIntegerRange;
108
109 // Structure used to check whether an integer value is in a set.
110 typedef struct CheckIntegerSet {
111         CheckParameterEvent event;
112         const void **set;
113         size_t size_of_set;
114 } CheckIntegerSet;
115
116 /* Used to check whether a parameter matches the area of memory referenced by 
117  * this structure.  */
118 typedef struct CheckMemoryData {
119         CheckParameterEvent event;
120         const void *memory;
121         size_t size;
122 } CheckMemoryData;
123
124 static ListNode* list_initialize(ListNode * const node);
125 static ListNode* list_add(ListNode * const head, ListNode *new_node);
126 static ListNode* list_add_value(ListNode * const head, const void *value,
127                                      const int count);
128 static ListNode* list_remove(
129     ListNode * const node, const CleanupListValue cleanup_value,
130     void * const cleanup_value_data);
131 static void list_remove_free(
132     ListNode * const node, const CleanupListValue cleanup_value,
133     void * const cleanup_value_data);
134 static int list_empty(const ListNode * const head);
135 static int list_find(
136     ListNode * const head, const void *value,
137     const EqualityFunction equal_func, ListNode **output);
138 static int list_first(ListNode * const head, ListNode **output);
139 static ListNode* list_free(
140     ListNode * const head, const CleanupListValue cleanup_value, 
141     void * const cleanup_value_data);
142
143 static void add_symbol_value(
144     ListNode * const symbol_map_head, const char * const symbol_names[], 
145     const size_t number_of_symbol_names, const void* value, const int count);
146 static int get_symbol_value(
147     ListNode * const symbol_map_head, const char * const symbol_names[], 
148     const size_t number_of_symbol_names, void **output);
149 static void free_value(const void *value, void *cleanup_value_data);
150 static void free_symbol_map_value(
151     const void *value, void *cleanup_value_data);
152 static void remove_always_return_values(ListNode * const map_head,
153                                         const size_t number_of_symbol_names);
154 static int check_for_leftover_values(
155     const ListNode * const map_head, const char * const error_message,
156     const size_t number_of_symbol_names);
157 // This must be called at the beginning of a test to initialize some data
158 // structures.
159 static void initialize_testing(const char *test_name);
160 // This must be called at the end of a test to free() allocated structures.
161 static void teardown_testing(const char *test_name);
162
163
164 // Keeps track of the calling context returned by setenv() so that the fail()
165 // method can jump out of a test.
166 static jmp_buf global_run_test_env;
167 static int global_running_test = 0;
168
169 // Keeps track of the calling context returned by setenv() so that
170 // mock_assert() can optionally jump back to expect_assert_failure().
171 jmp_buf global_expect_assert_env;
172 int global_expecting_assert = 0;
173
174 // Keeps a map of the values that functions will have to return to provide
175 // mocked interfaces.
176 static ListNode global_function_result_map_head;
177 // Location of the last mock value returned was declared.
178 static SourceLocation global_last_mock_value_location;
179
180 /* Keeps a map of the values that functions expect as parameters to their 
181  * mocked interfaces. */
182 static ListNode global_function_parameter_map_head;
183 // Location of last parameter value checked was declared.
184 static SourceLocation global_last_parameter_location;
185
186 // List of all currently allocated blocks.
187 static ListNode global_allocated_blocks;
188
189 #ifndef _WIN32
190 // Signals caught by exception_handler().
191 static const int exception_signals[] = {
192         SIGFPE,
193         SIGILL,
194         SIGSEGV,
195         SIGBUS,
196         SIGSYS,
197 };
198
199 // Default signal functions that should be restored after a test is complete.
200 typedef void (*SignalFunction)(int signal);
201 static SignalFunction default_signal_functions[
202     ARRAY_LENGTH(exception_signals)];
203
204 #else // _WIN32
205
206 // The default exception filter.
207 static LPTOP_LEVEL_EXCEPTION_FILTER previous_exception_filter;
208
209 // Fatal exceptions.
210 typedef struct ExceptionCodeInfo {
211         DWORD code;
212         const char* description;
213 } ExceptionCodeInfo;
214
215 #define EXCEPTION_CODE_INFO(exception_code) {exception_code, #exception_code}
216
217 static const ExceptionCodeInfo exception_codes[] = {
218         EXCEPTION_CODE_INFO(EXCEPTION_ACCESS_VIOLATION),
219         EXCEPTION_CODE_INFO(EXCEPTION_ARRAY_BOUNDS_EXCEEDED),
220         EXCEPTION_CODE_INFO(EXCEPTION_DATATYPE_MISALIGNMENT),
221         EXCEPTION_CODE_INFO(EXCEPTION_FLT_DENORMAL_OPERAND),
222         EXCEPTION_CODE_INFO(EXCEPTION_FLT_DIVIDE_BY_ZERO),
223         EXCEPTION_CODE_INFO(EXCEPTION_FLT_INEXACT_RESULT),
224         EXCEPTION_CODE_INFO(EXCEPTION_FLT_INVALID_OPERATION),
225         EXCEPTION_CODE_INFO(EXCEPTION_FLT_OVERFLOW),
226         EXCEPTION_CODE_INFO(EXCEPTION_FLT_STACK_CHECK),
227         EXCEPTION_CODE_INFO(EXCEPTION_FLT_UNDERFLOW),
228         EXCEPTION_CODE_INFO(EXCEPTION_GUARD_PAGE),
229         EXCEPTION_CODE_INFO(EXCEPTION_ILLEGAL_INSTRUCTION),
230         EXCEPTION_CODE_INFO(EXCEPTION_INT_DIVIDE_BY_ZERO),
231         EXCEPTION_CODE_INFO(EXCEPTION_INT_OVERFLOW),
232         EXCEPTION_CODE_INFO(EXCEPTION_INVALID_DISPOSITION),
233         EXCEPTION_CODE_INFO(EXCEPTION_INVALID_HANDLE),
234         EXCEPTION_CODE_INFO(EXCEPTION_IN_PAGE_ERROR),
235         EXCEPTION_CODE_INFO(EXCEPTION_NONCONTINUABLE_EXCEPTION),
236         EXCEPTION_CODE_INFO(EXCEPTION_PRIV_INSTRUCTION),
237         EXCEPTION_CODE_INFO(EXCEPTION_STACK_OVERFLOW),
238 };
239 #endif // !_WIN32
240
241
242 // Exit the currently executing test.
243 static void exit_test(const int quit_application) {
244         if (global_running_test) {
245                 longjmp(global_run_test_env, 1);
246         } else if (quit_application) {
247                 exit(-1);
248         }
249 }
250
251
252 // Initialize a SourceLocation structure.
253 static void initialize_source_location(SourceLocation * const location) {
254         assert_true(location);
255         location->file = NULL;
256         location->line = 0;
257 }
258
259
260 // Determine whether a source location is currently set.
261 static int source_location_is_set(const SourceLocation * const location) {
262         assert_true(location);
263         return location->file && location->line;
264 }
265
266
267 // Set a source location.
268 static void set_source_location(
269     SourceLocation * const location, const char * const file, 
270     const int line) {
271         assert_true(location);
272         location->file = file;
273         location->line = line;
274 }
275
276
277 // Create function results and expected parameter lists.
278 void initialize_testing(const char *test_name) {
279         list_initialize(&global_function_result_map_head);
280         initialize_source_location(&global_last_mock_value_location);
281         list_initialize(&global_function_parameter_map_head);
282         initialize_source_location(&global_last_parameter_location);
283 }
284
285
286 void fail_if_leftover_values(const char *test_name) {
287         int error_occurred = 0;
288         remove_always_return_values(&global_function_result_map_head, 1);
289         if (check_for_leftover_values(
290                 &global_function_result_map_head,
291                 "%s() has remaining non-returned values.\n", 1)) {
292                 error_occurred = 1;
293         }
294
295         remove_always_return_values(&global_function_parameter_map_head, 2);
296         if (check_for_leftover_values(
297                 &global_function_parameter_map_head,
298                 "%s parameter still has values that haven't been checked.\n", 2)) {
299                 error_occurred = 1;
300         }
301         if (error_occurred) {
302                 exit_test(1);
303         }
304 }
305
306
307 void teardown_testing(const char *test_name) {
308         list_free(&global_function_result_map_head, free_symbol_map_value, 
309                   (void*)0);
310         initialize_source_location(&global_last_mock_value_location);
311         list_free(&global_function_parameter_map_head, free_symbol_map_value,
312                   (void*)1);
313         initialize_source_location(&global_last_parameter_location);
314 }
315
316 // Initialize a list node.
317 static ListNode* list_initialize(ListNode * const node) {
318         node->value = NULL;
319         node->next = node;
320         node->prev = node;
321         node->refcount = 1;
322         return node;
323 }
324
325
326 /* Adds a value at the tail of a given list. 
327  * The node referencing the value is allocated from the heap. */
328 static ListNode* list_add_value(ListNode * const head, const void *value,
329                                      const int refcount) {
330         ListNode * const new_node = (ListNode*)malloc(sizeof(ListNode));
331         assert_true(head);
332         assert_true(value);
333         new_node->value = value;
334         new_node->refcount = refcount;
335         return list_add(head, new_node);
336 }
337
338
339 // Add new_node to the end of the list.
340 static ListNode* list_add(ListNode * const head, ListNode *new_node) {
341         assert_true(head);
342         assert_true(new_node);
343         new_node->next = head;
344         new_node->prev = head->prev;
345         head->prev->next = new_node;
346         head->prev = new_node;
347         return new_node;
348 }
349
350
351 // Remove a node from a list.
352 static ListNode* list_remove(
353         ListNode * const node, const CleanupListValue cleanup_value,
354         void * const cleanup_value_data) {
355         assert_true(node);
356         node->prev->next = node->next;
357         node->next->prev = node->prev;
358         if (cleanup_value) {
359                 cleanup_value(node->value, cleanup_value_data);
360         }
361         return node;
362 }
363
364
365 /* Remove a list node from a list and free the node. */
366 static void list_remove_free(
367         ListNode * const node, const CleanupListValue cleanup_value,
368         void * const cleanup_value_data) {
369         assert_true(node);
370         free(list_remove(node, cleanup_value, cleanup_value_data));
371 }
372
373
374 /* Frees memory kept by a linked list
375  * The cleanup_value function is called for every "value" field of nodes in the
376  * list, except for the head.  In addition to each list value, 
377  * cleanup_value_data is passed to each call to cleanup_value.  The head
378  * of the list is not deallocated.
379  */
380 static ListNode* list_free(
381         ListNode * const head, const CleanupListValue cleanup_value, 
382         void * const cleanup_value_data) {
383         assert_true(head);
384         while (!list_empty(head)) {
385                 list_remove_free(head->next, cleanup_value, cleanup_value_data);
386         }
387         return head;
388 }
389
390
391 // Determine whether a list is empty.
392 static int list_empty(const ListNode * const head) {
393         assert_true(head);
394         return head->next == head;
395 }
396
397
398 /* Find a value in the list using the equal_func to compare each node with the
399  * value. 
400  */
401 static int list_find(ListNode * const head, const void *value, 
402                      const EqualityFunction equal_func, ListNode **output) {
403         ListNode *current;
404         assert_true(head);
405         for (current = head->next; current != head; current = current->next) {
406                 if (equal_func(current->value, value)) {
407                         *output = current;
408                         return 1;
409                 }
410         }
411         return 0;
412 }
413
414 // Returns the first node of a list
415 static int list_first(ListNode * const head, ListNode **output) {
416         ListNode *target_node;
417         assert_true(head);
418         if (list_empty(head)) {
419                 return 0;
420         }
421         target_node = head->next;
422         *output = target_node;
423         return 1;
424 }
425
426
427 // Deallocate a value referenced by a list.
428 static void free_value(const void *value, void *cleanup_value_data) {
429         assert_true(value);
430         free((void*)value);
431 }
432
433
434 // Releases memory associated to a symbol_map_value.
435 static void free_symbol_map_value(const void *value, 
436                                   void *cleanup_value_data) {
437         SymbolMapValue * const map_value = (SymbolMapValue*)value;
438         const unsigned int children = (unsigned int)cleanup_value_data;
439         assert_true(value);
440         list_free(&map_value->symbol_values_list_head, 
441                   children ? free_symbol_map_value : free_value, 
442                   (void*)(children - 1));
443         free(map_value);
444 }
445
446
447 /* Determine whether a symbol name referenced by a symbol_map_value
448  * matches the specified function name. */
449 static int symbol_names_match(const void *map_value, const void *symbol) {
450         return !strcmp(((SymbolMapValue*)map_value)->symbol_name, 
451                    (const char*)symbol);
452 }
453
454
455 /* Adds a value to the queue of values associated with the given
456  * hierarchy of symbols.  It's assumed value is allocated from the heap.
457  */
458 static void add_symbol_value(ListNode * const symbol_map_head,
459                              const char * const symbol_names[],
460                              const size_t number_of_symbol_names,
461                              const void* value, const int refcount) {
462         const char* symbol_name;
463         ListNode *target_node;
464         SymbolMapValue *target_map_value;
465         assert_true(symbol_map_head);
466         assert_true(symbol_names);
467         assert_true(number_of_symbol_names);
468         symbol_name = symbol_names[0];
469
470         if (!list_find(symbol_map_head, symbol_name, symbol_names_match, 
471                        &target_node)) {
472                 SymbolMapValue * const new_symbol_map_value =
473                     malloc(sizeof(*new_symbol_map_value));
474                 new_symbol_map_value->symbol_name = symbol_name;
475                 list_initialize(&new_symbol_map_value->symbol_values_list_head);
476                 target_node = list_add_value(symbol_map_head, new_symbol_map_value,
477                                                   1);
478         }
479
480         target_map_value = (SymbolMapValue*)target_node->value;
481         if (number_of_symbol_names == 1) {
482                         list_add_value(&target_map_value->symbol_values_list_head,
483                                             value, refcount);
484         } else {
485                 add_symbol_value(&target_map_value->symbol_values_list_head,
486                                  &symbol_names[1], number_of_symbol_names - 1, value,
487                                  refcount);
488         }
489 }
490
491
492 /* Gets the next value associated with the given hierarchy of symbols. 
493  * The value is returned as an output parameter with the function returning the
494  * node's old refcount value if a value is found, 0 otherwise.
495  * This means that a return value of 1 indicates the node was just removed from
496  * the list.
497  */
498 static int get_symbol_value(
499         ListNode * const head, const char * const symbol_names[], 
500         const size_t number_of_symbol_names, void **output) {
501         const char* symbol_name;
502         ListNode *target_node;
503         assert_true(head);
504         assert_true(symbol_names);
505         assert_true(number_of_symbol_names);
506         assert_true(output);
507         symbol_name = symbol_names[0];
508
509         if (list_find(head, symbol_name, symbol_names_match, &target_node)) {
510                 SymbolMapValue *map_value;
511                 ListNode *child_list;
512                 int return_value = 0;
513                 assert_true(target_node);
514                 assert_true(target_node->value);
515
516                 map_value = (SymbolMapValue*)target_node->value;
517                 child_list = &map_value->symbol_values_list_head;
518
519                 if (number_of_symbol_names == 1) {
520                         ListNode *value_node = NULL;
521                         return_value = list_first(child_list, &value_node);
522                         assert_true(return_value);
523                         *output = (void*) value_node->value;
524                         return_value = value_node->refcount;
525                         if (--value_node->refcount == 0) {
526                                 list_remove_free(value_node, NULL, NULL);
527                         }
528                 } else {
529                         return_value = get_symbol_value(
530                             child_list, &symbol_names[1], number_of_symbol_names - 1, 
531                             output);
532                 }
533                 if (list_empty(child_list)) {
534                         list_remove_free(target_node, free_symbol_map_value, (void*)0);
535                 }
536                 return return_value;
537         } else {
538                 print_error("No entries for symbol %s.\n", symbol_name);
539         }
540         return 0;
541 }
542
543
544 /* Traverse down a tree of symbol values and remove the first symbol value
545  * in each branch that has a refcount < -1 (i.e should always be returned
546  * and has been returned at least once).
547  */
548 static void remove_always_return_values(ListNode * const map_head,
549                                         const size_t number_of_symbol_names) {
550         ListNode *current;
551         assert_true(map_head);
552         assert_true(number_of_symbol_names);
553         current = map_head->next;
554         while (current != map_head) {
555                 SymbolMapValue * const value = (SymbolMapValue*)current->value;
556                 ListNode * const next = current->next;
557                 ListNode *child_list;
558                 assert_true(value);
559                 child_list = &value->symbol_values_list_head;
560
561                 if (!list_empty(child_list)) {
562                         if (number_of_symbol_names == 1) {
563                                 ListNode * const child_node = child_list->next;
564                                 // If this item has been returned more than once, free it.
565                                 if (child_node->refcount < -1) {
566                                         list_remove_free(child_node, free_value, NULL);
567                                 }
568                         } else {
569                                 remove_always_return_values(child_list,
570                                                             number_of_symbol_names - 1);
571                         }
572                 }
573
574                 if (list_empty(child_list)) {
575                         list_remove_free(current, free_value, NULL);
576                 }
577                 current = next;
578         }
579 }
580
581 /* Checks if there are any leftover values set up by the test that were never
582  * retrieved through execution, and fail the test if that is the case.
583  */
584 static int check_for_leftover_values(
585         const ListNode * const map_head, const char * const error_message,
586         const size_t number_of_symbol_names) {
587         const ListNode *current;
588         int symbols_with_leftover_values = 0;
589         assert_true(map_head);
590         assert_true(number_of_symbol_names);
591
592         for (current = map_head->next; current != map_head; 
593              current = current->next) {
594                 const SymbolMapValue * const value = 
595                     (SymbolMapValue*)current->value;
596                 const ListNode *child_list;
597                 assert_true(value);
598                 child_list = &value->symbol_values_list_head;
599
600                 if (!list_empty(child_list)) {
601                         if (number_of_symbol_names == 1) {
602                                 const ListNode *child_node;
603                                 print_error(error_message, value->symbol_name);
604                                 print_error("  Remaining item(s) declared at...\n");
605
606                                 for (child_node = child_list->next; child_node != child_list;
607                                      child_node = child_node->next) {
608                                         const SourceLocation * const location = child_node->value;
609                                         print_error("    " SOURCE_LOCATION_FORMAT "\n",
610                                                     location->file, location->line);
611                                 }
612                         } else {
613                                 print_error("%s.", value->symbol_name);
614                                 check_for_leftover_values(child_list, error_message,
615                                                           number_of_symbol_names - 1);
616                         }
617                         symbols_with_leftover_values ++;
618                 }
619         }
620         return symbols_with_leftover_values;
621 }
622
623
624 // Get the next return value for the specified mock function.
625 void* _mock(const char * const function, const char* const file, 
626             const int line) {
627         void *result;
628         const int rc = get_symbol_value(&global_function_result_map_head, 
629                                         &function, 1, &result);
630         if (rc) {
631                 SymbolValue * const symbol = result;
632                 void * const value = (void*)symbol->value;
633                 global_last_mock_value_location = symbol->location;
634                 if (rc == 1) {
635                         free(symbol);
636                 }
637                 return value;
638         } else {
639                 print_error("ERROR: " SOURCE_LOCATION_FORMAT " - Could not get value "
640                             "to mock function %s\n", file, line, function);
641                 if (source_location_is_set(&global_last_mock_value_location)) {
642                         print_error("Previously returned mock value was declared at "
643                                     SOURCE_LOCATION_FORMAT "\n", 
644                                     global_last_mock_value_location.file, 
645                                     global_last_mock_value_location.line);
646                 } else {
647                         print_error("There were no previously returned mock values for "
648                                     "this test.\n");
649                 }
650                 exit_test(1);
651         }
652         return NULL;
653 }
654
655
656 // Add a return value for the specified mock function name.
657 void _will_return(const char * const function_name, const char * const file, 
658                   const int line, const void* const value, const int count) {
659         SymbolValue * const return_value = malloc(sizeof(*return_value));
660         assert_true(count > 0 || count == -1);
661         return_value->value = value;
662         set_source_location(&return_value->location, file, line);
663         add_symbol_value(&global_function_result_map_head, &function_name, 1,
664                          return_value, count);
665 }
666
667
668 /* Add a custom parameter checking function.  If the event parameter is NULL
669  * the event structure is allocated internally by this function.  If event
670  * parameter is provided it must be allocated on the heap and doesn't need to
671  * be deallocated by the caller.
672  */
673 void _expect_check(
674         const char* const function, const char* const parameter, 
675         const char* const file, const int line,
676         const CheckParameterValue check_function, void * const check_data,
677         CheckParameterEvent * const event, const int count) {
678         CheckParameterEvent * const check = 
679             event ? event : malloc(sizeof(*check));
680         const char* symbols[] = {function, parameter};
681         check->parameter_name = parameter;
682         check->check_value = check_function;
683         check->check_value_data = check_data;
684         set_source_location(&check->location, file, line); 
685         add_symbol_value(&global_function_parameter_map_head, symbols, 2, check,
686                          count);
687 }
688
689
690 /* Returns 1 if the specified values are equal.  If the values are not equal
691  * an error is displayed and 0 is returned. */
692 static int values_equal_display_error(const void* const left,
693                                       const void* const right) {
694         const int equal = left == right;
695         if (!equal) {
696                 print_error("0x%x != 0x%x\n", left, right);
697         }
698         return equal;
699 }
700
701 /* Returns 1 if the specified values are not equal.  If the values are equal
702  * an error is displayed and 0 is returned. */
703 static int values_not_equal_display_error(const void* const left,
704                                           const void* const right) {
705         const int not_equal = left != right;
706         if (!not_equal) {
707                 print_error("0x%x == 0x%x\n", left, right);
708         }
709         return not_equal;
710 }
711
712
713 /* Determine whether value is contained within check_integer_set.
714  * If invert is 0 and the value is in the set 1 is returned, otherwise 0 is
715  * returned and an error is displayed.  If invert is 1 and the value is not 
716  * in the set 1 is returned, otherwise 0 is returned and an error is 
717  * displayed. */
718 static int value_in_set_display_error(
719         const void *value, const CheckIntegerSet * const check_integer_set,
720         const int invert) {
721         int succeeded = invert;
722         assert_true(check_integer_set);
723         {
724                 const void ** const set = check_integer_set->set;
725                 const size_t size_of_set = check_integer_set->size_of_set; 
726                 size_t i;
727                 for (i = 0; i < size_of_set; i++) {
728                         if (set[i] == value) {
729                                 // If invert = 0 and item is found, succeeded = 1.
730                                 // If invert = 1 and item is found, succeeded = 0.
731                                 succeeded = !succeeded;
732                                 break;
733                         }
734                 }
735                 if (succeeded) {
736                         return 1;
737                 }
738                 print_error("%d is %sin the set (", value, invert ? "" : "not ");
739                 for (i = 0; i < size_of_set; i++) {
740                         print_error("%d, ", set[i]);
741                 }
742                 print_error(")\n");
743         }
744         return 0;
745 }
746
747
748 /* Determine whether a value is within the specified range.  If the value is
749  * within the specified range 1 is returned.  If the value isn't within the 
750  * specified range an error is displayed and 0 is returned. */
751 static int integer_in_range_display_error(
752         const int value, const int range_min, const int range_max) {
753         if (value >= range_min && value <= range_max) {
754                 return 1;
755         }
756         print_error("%d is not within the range %d-%d\n", value, range_min, 
757                     range_max);
758         return 0;
759 }
760
761
762 /* Determine whether a value is within the specified range.  If the value
763  * is not within the range 1 is returned.  If the value is within the 
764  * specified range an error is displayed and zero is returned. */
765 static int integer_not_in_range_display_error(
766         const int value, const int range_min, const int range_max) {
767         if (value < range_min || value > range_max) {
768                 return 1;
769         }
770         print_error("%d is within the range %d-%d\n", value, range_min,
771                     range_max);
772         return 0;
773 }
774
775
776 /* Determine whether the specified strings are equal.  If the strings are equal
777  * 1 is returned.  If they're not equal an error is displayed and 0 is 
778  * returned. */
779 static int string_equal_display_error(
780         const char * const left, const char * const right) {
781         if (strcmp(left, right) == 0) {
782                 return 1;
783         }
784         print_error("\"%s\" != \"%s\"\n", left, right);
785         return 0;
786 }
787
788
789 /* Determine whether the specified strings are equal.  If the strings are not 
790  * equal 1 is returned.  If they're not equal an error is displayed and 0 is 
791  * returned */
792 static int string_not_equal_display_error(
793         const char * const left, const char * const right) {
794         if (strcmp(left, right) != 0) {
795                 return 1;
796         }
797         print_error("\"%s\" == \"%s\"\n", left, right);
798         return 0;
799 }
800
801
802 /* Determine whether the specified areas of memory are equal.  If they're equal
803  * 1 is returned otherwise an error is displayed and 0 is returned. */
804 static int memory_equal_display_error(const char* a, const char* b,
805                                       const size_t size) {
806         int differences = 0;
807         size_t i;
808         for (i = 0; i < size; i++) {
809                 const char l = a[i];
810                 const char r = b[i];
811                 if (l != r) {
812                         print_error("difference at offset %d 0x%02x 0x%02x\n", i, l, r);
813                         differences ++;
814                 }
815         }
816         if (differences) {
817                 print_error("%d bytes of 0x%08x and 0x%08x differ\n", differences,
818                             a, b);
819                 return 0;
820         }
821         return 1;
822 }
823
824
825 /* Determine whether the specified areas of memory are not equal.  If they're 
826  * not equal 1 is returned otherwise an error is displayed and 0 is 
827  * returned. */
828 static int memory_not_equal_display_error(const char* a, const char* b,
829                                           const size_t size) {
830         int same = 0;
831         size_t i;
832         for (i = 0; i < size; i++) {
833                 const char l = a[i];
834                 const char r = b[i];
835                 if (l == r) {
836                         print_error("equal at offset %d 0x%02x 0x%02x\n", i, l, r);
837                         same ++;
838                 }
839         }
840         if (same) {
841                 print_error("%d bytes of 0x%08x and 0x%08x the same\n", same,
842                             a, b);
843                 return 0;
844         }
845         return 1;
846 }
847
848
849 // CheckParameterValue callback to check whether a value is within a set.
850 static int check_in_set(const void *value, void *check_value_data) {
851         return value_in_set_display_error(value, 
852             (CheckIntegerSet*)check_value_data, 0);
853 }
854
855
856 // CheckParameterValue callback to check whether a value isn't within a set.
857 static int check_not_in_set(const void *value, void *check_value_data) {
858         return value_in_set_display_error(value, 
859             (CheckIntegerSet*)check_value_data, 1);
860 }
861
862
863 /* Create the callback data for check_in_set() or check_not_in_set() and 
864  * register a check event. */
865 static void expect_set(
866         const char* const function, const char* const parameter,
867         const char* const file, const int line, const void *values[],
868         const size_t number_of_values, 
869         const CheckParameterValue check_function, const int count) {
870         CheckIntegerSet * const check_integer_set =
871             malloc(sizeof(*check_integer_set) + 
872                    (sizeof(values[0]) * number_of_values));
873         void ** const set = (void**)(check_integer_set + 1);
874         assert_true(values);
875         assert_true(number_of_values);
876         memcpy(set, values, number_of_values * sizeof(values[0]));
877         check_integer_set->set = (const void**)set;
878         _expect_check(function, parameter, file, line, check_function,
879                       check_integer_set, &check_integer_set->event, count);
880 }
881
882
883 // Add an event to check whether a value is in a set.
884 void _expect_in_set(
885         const char* const function, const char* const parameter, 
886         const char* const file, const int line, const void *values[], 
887         const size_t number_of_values, const int count) {
888         expect_set(function, parameter, file, line, values, number_of_values,
889                    check_in_set, count);
890 }
891
892
893 // Add an event to check whether a value isn't in a set.
894 void _expect_not_in_set(
895         const char* const function, const char* const parameter, 
896         const char* const file, const int line, const void *values[], 
897         const size_t number_of_values, const int count) {
898         expect_set(function, parameter, file, line, values, number_of_values,
899                    check_not_in_set, count);
900 }
901
902
903 // CheckParameterValue callback to check whether a value is within a range.
904 static int check_in_range(const void *value, void *check_value_data) {
905         CheckIntegerRange * const check_integer_range = check_value_data;
906         assert_true(check_value_data);
907         return integer_in_range_display_error(
908             (int)value, check_integer_range->minimum,
909             check_integer_range->maximum);
910 }
911
912
913 // CheckParameterValue callback to check whether a value is not within a range.
914 static int check_not_in_range(const void *value, void *check_value_data) {
915         CheckIntegerRange * const check_integer_range = check_value_data;
916         assert_true(check_value_data);
917         return integer_not_in_range_display_error(
918             (int)value, check_integer_range->minimum,
919             check_integer_range->maximum);
920 }
921
922
923 /* Create the callback data for check_in_range() or check_not_in_range() and 
924  * register a check event. */
925 static void expect_range(
926         const char* const function, const char* const parameter,
927         const char* const file, const int line,
928         const int minimum, const int maximum,
929         const CheckParameterValue check_function, const int count) {
930         CheckIntegerRange * const check_integer_range =
931             malloc(sizeof(*check_integer_range));
932         check_integer_range->minimum = minimum;
933         check_integer_range->maximum = maximum;
934         _expect_check(function, parameter, file, line, check_function,
935                       check_integer_range, &check_integer_range->event, count);
936 }
937
938
939 // Add an event to determine whether a parameter is within a range.
940 void _expect_in_range(
941         const char* const function, const char* const parameter,
942         const char* const file, const int line,
943         const int minimum, const int maximum, const int count) {
944         expect_range(function, parameter, file, line, minimum, maximum,
945                      check_in_range, count);
946 }
947
948
949 // Add an event to determine whether a parameter is not within a range.
950 void _expect_not_in_range(
951         const char* const function, const char* const parameter,
952         const char* const file, const int line,
953         const int minimum, const int maximum, const int count) {
954         expect_range(function, parameter, file, line, minimum, maximum,
955                      check_not_in_range, count);
956 }
957
958
959 /* CheckParameterValue callback to check whether a value is equal to an 
960  * expected value. */
961 static int check_value(const void *value, void *check_value_data) {
962         return values_equal_display_error(value, check_value_data);
963 }
964
965
966 // Add an event to check a parameter equals an expected value.
967 void _expect_value(
968         const char* const function, const char* const parameter,
969         const char* const file, const int line, const void* const value,
970         const int count) {
971         _expect_check(function, parameter, file, line, check_value, 
972                       (void*)value, NULL, count);
973 }
974
975
976 /* CheckParameterValue callback to check whether a value is not equal to an 
977  * expected value. */
978 static int check_not_value(const void *value, void *check_value_data) {
979         return values_not_equal_display_error(value, check_value_data);
980 }
981
982
983 // Add an event to check a parameter is not equal to an expected value.
984 void _expect_not_value(
985         const char* const function, const char* const parameter, 
986         const char* const file, const int line, const void* const value,
987         const int count) {
988         _expect_check(function, parameter, file, line, check_not_value,
989                       (void*)value, NULL, count);
990 }
991
992
993 // CheckParameterValue callback to check whether a parameter equals a string.
994 static int check_string(const void * value, void *check_value_data) {
995         return string_equal_display_error(value, check_value_data);
996 }
997
998
999 // Add an event to check whether a parameter is equal to a string.
1000 void _expect_string(
1001         const char* const function, const char* const parameter,
1002         const char* const file, const int line, const char* string,
1003         const int count) {
1004         _expect_check(function, parameter, file, line, check_string, (void*)string,
1005                       NULL, count);
1006 }
1007
1008
1009 /* CheckParameterValue callback to check whether a parameter is not equals to 
1010  * a string. */
1011 static int check_not_string(const void * value, void *check_value_data) {
1012         return string_not_equal_display_error(value, check_value_data);
1013 }
1014
1015
1016 // Add an event to check whether a parameter is not equal to a string.
1017 void _expect_not_string(
1018         const char* const function, const char* const parameter,
1019         const char* const file, const int line, const char* string,
1020         const int count) {
1021         _expect_check(function, parameter, file, line, check_not_string,
1022                       (void*)string, NULL, count);
1023 }
1024
1025 /* CheckParameterValue callback to check whether a parameter equals an area of
1026  * memory. */
1027 static int check_memory(const void* value, void *check_value_data) {
1028         CheckMemoryData * const check = (CheckMemoryData*)check_value_data;
1029         assert_true(check);
1030         return memory_equal_display_error(value, check->memory, check->size);
1031 }
1032
1033
1034 /* Create the callback data for check_memory() or check_not_memory() and 
1035  * register a check event. */
1036 static void expect_memory_setup(
1037         const char* const function, const char* const parameter,
1038         const char* const file, const int line,
1039         const void * const memory, const size_t size,
1040         const CheckParameterValue check_function, const int count) {
1041         CheckMemoryData * const check_data = malloc(sizeof(*check_data) + size);
1042         void * const mem = (void*)(check_data + 1);
1043         assert_true(memory);
1044         assert_true(size);
1045         memcpy(mem, memory, size);
1046         check_data->memory = mem;
1047         check_data->size = size;
1048         _expect_check(function, parameter, file, line, check_function,
1049                       check_data, &check_data->event, count);
1050 }
1051
1052
1053 // Add an event to check whether a parameter matches an area of memory.
1054 void _expect_memory(
1055         const char* const function, const char* const parameter,
1056         const char* const file, const int line, const void* const memory,
1057         const size_t size, const int count) {
1058         expect_memory_setup(function, parameter, file, line, memory, size,
1059                             check_memory, count);
1060 }
1061
1062
1063 /* CheckParameterValue callback to check whether a parameter is not equal to
1064  * an area of memory. */
1065 static int check_not_memory(const void* value, void *check_value_data) {
1066         CheckMemoryData * const check = (CheckMemoryData*)check_value_data;
1067         assert_true(check);
1068         return memory_not_equal_display_error(value, check->memory, check->size);
1069 }
1070
1071
1072 // Add an event to check whether a parameter doesn't match an area of memory.
1073 void _expect_not_memory(
1074         const char* const function, const char* const parameter,
1075         const char* const file, const int line, const void* const memory, 
1076         const size_t size, const int count) {
1077         expect_memory_setup(function, parameter, file, line, memory, size,
1078                             check_not_memory, count);
1079 }
1080
1081
1082 // CheckParameterValue callback that always returns 1.
1083 static int check_any(const void *value, void *check_value_data) {
1084         return 1;
1085 }
1086
1087
1088 // Add an event to allow any value for a parameter.
1089 void _expect_any(
1090         const char* const function, const char* const parameter,
1091         const char* const file, const int line, const int count) {
1092         _expect_check(function, parameter, file, line, check_any, NULL, NULL, 
1093                       count);
1094 }
1095
1096
1097 void _check_expected(
1098         const char * const function_name, const char * const parameter_name,
1099         const char* file, const int line, const void* value) {
1100         void *result;
1101         const char* symbols[] = {function_name, parameter_name};
1102         const int rc = get_symbol_value(&global_function_parameter_map_head, 
1103                                         symbols, 2, &result);
1104         if (rc) {
1105                 CheckParameterEvent * const check = (CheckParameterEvent*)result;
1106                 int check_succeeded;
1107                 global_last_parameter_location = check->location;
1108                 check_succeeded = check->check_value(value, check->check_value_data);
1109                 if (rc == 1) {
1110                         free(check);
1111                 }
1112                 if (!check_succeeded) {
1113                         print_error("ERROR: Check of parameter %s, function %s failed\n"
1114                                     "Expected parameter declared at " 
1115                                     SOURCE_LOCATION_FORMAT "\n",
1116                                     parameter_name, function_name,
1117                                     global_last_parameter_location.file, 
1118                                     global_last_parameter_location.line);
1119                         _fail(file, line); 
1120                 }
1121         } else {
1122                 print_error("ERROR: " SOURCE_LOCATION_FORMAT " - Could not get value "
1123                             "to check parameter %s of function %s\n", file, line, 
1124                             parameter_name, function_name);
1125                 if (source_location_is_set(&global_last_parameter_location)) {
1126                         print_error("Previously declared parameter value was declared at "
1127                                     SOURCE_LOCATION_FORMAT "\n", 
1128                                     global_last_parameter_location.file, 
1129                                     global_last_parameter_location.line);
1130                 } else {
1131                         print_error("There were no previously declared parameter values "
1132                                     "for this test.\n");
1133                 }
1134                 exit_test(1);
1135         }
1136 }
1137
1138
1139 // Replacement for assert.
1140 void mock_assert(const int result, const char* const expression, 
1141                  const char* const file, const int line) {
1142         if (!result) {
1143                 if (global_expecting_assert) {
1144                         longjmp(global_expect_assert_env, (int)expression);
1145                 } else {
1146                         print_error("ASSERT: %s\n", expression);
1147                         _fail(file, line);
1148                 }
1149         }
1150 }
1151
1152
1153 void _assert_true(const int result, const char * const expression, 
1154                   const char * const file, const int line) {
1155         if (!result) {
1156                 print_error("%s\n", expression);
1157                 _fail(file, line);
1158         }
1159 }
1160
1161 void _assert_int_equal(const int a, const int b, const char * const file, 
1162                        const int line) {
1163         if (!values_equal_display_error((void*)a, (void*)b)) {
1164                 _fail(file, line);
1165         }
1166 }
1167
1168
1169 void _assert_int_not_equal(const int a, const int b, const char * const file, 
1170                            const int line) {
1171         if (!values_not_equal_display_error((void*)a, (void*)b)) {
1172                 _fail(file, line);
1173         }
1174 }
1175
1176
1177 void _assert_string_equal(const char * const a, const char * const b, 
1178                           const char * const file, const int line) {
1179         if (!string_equal_display_error(a, b)) {
1180                 _fail(file, line);
1181         }
1182 }
1183
1184
1185 void _assert_string_not_equal(const char * const a, const char * const b, 
1186                               const char *file, const int line) {
1187         if (!string_not_equal_display_error(a, b)) {
1188                 _fail(file, line);
1189         }
1190 }
1191
1192
1193 void _assert_memory_equal(const void * const a, const void * const b, 
1194                           const size_t size, const char* const file, 
1195                           const int line) {
1196         if (!memory_equal_display_error((const char*)a, (const char*)b, size)) {
1197                 _fail(file, line);
1198         }
1199 }
1200
1201
1202 void _assert_memory_not_equal(const void * const a, const void * const b,
1203                               const size_t size, const char* const file, 
1204                               const int line) {
1205         if (!memory_not_equal_display_error((const char*)a, (const char*)b, 
1206                                             size)) {
1207                 _fail(file, line);
1208         }
1209 }
1210
1211
1212 void _assert_in_range(const int value, const int minimum, const int maximum,
1213                       const char* const file, const int line) {
1214         if (!integer_in_range_display_error(value, minimum, maximum)) {
1215                 _fail(file, line);
1216         }
1217 }
1218
1219 void _assert_not_in_range(const int value, const int minimum,
1220                           const int maximum, const char* const file, 
1221                           const int line) {
1222         if (!integer_not_in_range_display_error(value, minimum, maximum)) {
1223                 _fail(file, line);
1224         }
1225 }
1226
1227 void _assert_in_set(const void* const value, const void *values[],
1228                     const size_t number_of_values, const char* const file,
1229                     const int line) {
1230         CheckIntegerSet check_integer_set;
1231         check_integer_set.set = values;
1232         check_integer_set.size_of_set = number_of_values;
1233         if (!value_in_set_display_error(value, &check_integer_set, 0)) {
1234                 _fail(file, line);
1235         }
1236 }
1237
1238 void _assert_not_in_set(const void* const value, const void *values[],
1239                         const size_t number_of_values, const char* const file,
1240                         const int line) {
1241         CheckIntegerSet check_integer_set;
1242         check_integer_set.set = values;
1243         check_integer_set.size_of_set = number_of_values;
1244         if (!value_in_set_display_error(value, &check_integer_set, 1)) {
1245                 _fail(file, line);
1246         }
1247 }
1248
1249
1250 // Get the list of allocated blocks.
1251 static ListNode* get_allocated_blocks_list() {
1252         // If it initialized, initialize the list of allocated blocks.
1253         if (!global_allocated_blocks.value) {
1254                 list_initialize(&global_allocated_blocks);
1255                 global_allocated_blocks.value = (void*)1;
1256         }
1257         return &global_allocated_blocks;
1258 }
1259
1260 // Use the real malloc in this function.
1261 #undef malloc
1262 void* _test_malloc(const size_t size, const char* file, const int line) {
1263         char* ptr;
1264         MallocBlockInfo *block_info;
1265         ListNode * const block_list = get_allocated_blocks_list();
1266         const size_t allocate_size = size + (MALLOC_GUARD_SIZE * 2) + 
1267             sizeof(*block_info) + MALLOC_ALIGNMENT;
1268         char* const block = (char*)malloc(allocate_size);
1269         assert_true(block);
1270
1271         // Calculate the returned address.
1272         ptr = (char*)(((size_t)block + MALLOC_GUARD_SIZE + sizeof(*block_info) +
1273                       MALLOC_ALIGNMENT) & ~(MALLOC_ALIGNMENT - 1));
1274
1275         // Initialize the guard blocks.
1276         memset(ptr - MALLOC_GUARD_SIZE, MALLOC_GUARD_PATTERN, MALLOC_GUARD_SIZE);
1277         memset(ptr + size, MALLOC_GUARD_PATTERN, MALLOC_GUARD_SIZE);
1278         memset(ptr, MALLOC_ALLOC_PATTERN, size);
1279
1280         block_info = (MallocBlockInfo*)(ptr - (MALLOC_GUARD_SIZE +
1281                                                  sizeof(*block_info)));
1282         set_source_location(&block_info->location, file, line);
1283         block_info->allocated_size = allocate_size;
1284         block_info->size = size;
1285         block_info->block = block;
1286         block_info->node.value = block_info;
1287         list_add(block_list, &block_info->node);
1288         return ptr;
1289 }
1290 #define malloc test_malloc
1291
1292
1293 void* _test_calloc(const size_t number_of_elements, const size_t size, 
1294                    const char* file, const int line) {
1295         void* const ptr = _test_malloc(number_of_elements * size, file, line);
1296         if (ptr) {
1297                 memset(ptr, 0, number_of_elements * size);
1298         }
1299         return ptr;
1300 }
1301
1302
1303 // Use the real free in this function.
1304 #undef free
1305 void _test_free(void* const ptr, const char* file, const int line) {
1306         unsigned int i;
1307         char *block = (char*)ptr;
1308         MallocBlockInfo *block_info;
1309         _assert_true((int)ptr, "ptr", file, line);
1310         block_info = (MallocBlockInfo*)(block - (MALLOC_GUARD_SIZE +
1311                                                    sizeof(*block_info)));
1312         // Check the guard blocks.
1313         {
1314                 char *guards[2] = {block - MALLOC_GUARD_SIZE,
1315                                    block + block_info->size};
1316                 for (i = 0; i < ARRAY_LENGTH(guards); i++) {
1317                         unsigned int j;
1318                         char * const guard = guards[i];
1319                         for (j = 0; j < MALLOC_GUARD_SIZE; j++) {
1320                                 const char diff = guard[j] - MALLOC_GUARD_PATTERN;
1321                                 if (diff) {
1322                                         print_error(
1323                                             "Guard block of 0x%08x size=%d allocated by "
1324                                             SOURCE_LOCATION_FORMAT " at 0x%08x is corrupt\n", 
1325                                             (size_t)ptr, block_info->size,
1326                                             block_info->location.file, block_info->location.line, 
1327                                             (size_t)&guard[j]);
1328                                         _fail(file, line);
1329                                 }
1330                         }
1331                 }
1332         }
1333         list_remove(&block_info->node, NULL, NULL);
1334
1335         block = block_info->block;
1336         memset(block, MALLOC_FREE_PATTERN, block_info->allocated_size);
1337         free(block);
1338 }
1339 #define free test_free
1340
1341
1342 // Crudely checkpoint the current heap state.
1343 static const ListNode* check_point_allocated_blocks() {
1344         return get_allocated_blocks_list()->prev;
1345 }
1346
1347
1348 /* Display the blocks allocated after the specified check point.  This
1349  * function returns the number of blocks displayed. */
1350 static int display_allocated_blocks(const ListNode * const check_point) {
1351         const ListNode * const head = get_allocated_blocks_list();
1352         const ListNode *node;
1353         int allocated_blocks = 0;
1354         assert_true(check_point);
1355         assert_true(check_point->next);
1356
1357         for (node = check_point->next; node != head; node = node->next) {
1358                 const MallocBlockInfo * const block_info = node->value;
1359                 assert_true(block_info);
1360
1361                 if (!allocated_blocks) {
1362                         print_error("Blocks allocated...\n");
1363                 }
1364                 print_error("  0x%08x : " SOURCE_LOCATION_FORMAT "\n",
1365                             block_info->block, block_info->location.file,
1366                             block_info->location.line);
1367                 allocated_blocks ++;
1368         }
1369         return allocated_blocks;
1370 }
1371
1372
1373 // Free all blocks allocated after the specified check point.
1374 static void free_allocated_blocks(const ListNode * const check_point) {
1375         const ListNode * const head = get_allocated_blocks_list();
1376         const ListNode *node;
1377         assert_true(check_point);
1378
1379         node = check_point->next;
1380         assert_true(node);
1381
1382         while (node != head) {
1383                 MallocBlockInfo * const block_info = (MallocBlockInfo*)node->value;
1384                 node = node->next;
1385                 free((char*)block_info + sizeof(*block_info) + MALLOC_GUARD_SIZE);
1386         }
1387 }
1388
1389
1390 // Fail if any any blocks are allocated after the specified check point.
1391 static void fail_if_blocks_allocated(const ListNode * const check_point,
1392                                      const char * const test_name) {
1393         const int allocated_blocks = display_allocated_blocks(check_point);
1394         if (allocated_blocks) {
1395                 free_allocated_blocks(check_point);
1396                 print_error("ERROR: %s leaked %d block(s)\n", test_name, 
1397                             allocated_blocks);
1398                 exit_test(1);
1399         }
1400 }
1401
1402
1403 void _fail(const char * const file, const int line) {
1404         print_error("ERROR: " SOURCE_LOCATION_FORMAT " Failure!\n", file, line);
1405         exit_test(1);
1406 }
1407
1408
1409 #ifndef _WIN32
1410 static void exception_handler(int sig) {
1411         print_error("%s\n", strsignal(sig));
1412         exit_test(1);
1413 }
1414
1415 #else // _WIN32
1416
1417 static LONG WINAPI exception_filter(EXCEPTION_POINTERS *exception_pointers) {
1418         EXCEPTION_RECORD * const exception_record =
1419             exception_pointers->ExceptionRecord;
1420         const DWORD code = exception_record->ExceptionCode;
1421         unsigned int i;
1422         for (i = 0; i < ARRAY_LENGTH(exception_codes); i++) {
1423                 const ExceptionCodeInfo * const code_info = &exception_codes[i];
1424                 if (code == code_info->code) {
1425                         static int shown_debug_message = 0;
1426                         fflush(stdout);
1427                         print_error("%s occurred at 0x%08x.\n", code_info->description,
1428                                     exception_record->ExceptionAddress);
1429                         if (!shown_debug_message) {
1430                                 print_error(
1431                                     "\n"
1432                                     "To debug in Visual Studio...\n"
1433                                     "1. Select menu item File->Open Project\n"
1434                                     "2. Change 'Files of type' to 'Executable Files'\n"
1435                                     "3. Open this executable.\n"
1436                                     "4. Select menu item Debug->Start\n"
1437                                     "\n"
1438                                     "Alternatively, set the environment variable \n"
1439                                     "UNIT_TESTING_DEBUG to 1 and rebuild this executable, \n"
1440                                     "then click 'Debug' in the popup dialog box.\n"
1441                                     "\n");
1442                                 shown_debug_message = 1;
1443                         }
1444                         exit_test(0);
1445                         return EXCEPTION_EXECUTE_HANDLER;
1446                 }
1447         }
1448         return EXCEPTION_CONTINUE_SEARCH;
1449 }
1450 #endif // !_WIN32
1451
1452
1453 // Standard output and error print methods.
1454 void vprint_message(const char* const format, va_list args) {
1455         char buffer[1024];
1456         vsnprintf(buffer, sizeof(buffer), format, args);
1457         printf(buffer);
1458 #ifdef _WIN32
1459         OutputDebugString(buffer);
1460 #endif // _WIN32
1461 }
1462
1463
1464 void vprint_error(const char* const format, va_list args) {
1465         char buffer[1024];
1466         vsnprintf(buffer, sizeof(buffer), format, args);
1467         fprintf(stderr, buffer);
1468 #ifdef _WIN32
1469         OutputDebugString(buffer);
1470 #endif // _WIN32
1471 }
1472
1473
1474 void print_message(const char* const format, ...) {
1475         va_list args;
1476         va_start(args, format);
1477         vprint_message(format, args);
1478         va_end(args);
1479 }
1480
1481
1482 void print_error(const char* const format, ...) {
1483         va_list args;
1484         va_start(args, format);
1485         vprint_error(format, args);
1486         va_end(args);
1487 }
1488
1489
1490 int _run_test(
1491         const char * const function_name,  const UnitTestFunction Function, 
1492         void ** const state, const UnitTestFunctionType function_type,
1493         const void* const heap_check_point) {
1494         const ListNode * const check_point = heap_check_point ? 
1495             heap_check_point : check_point_allocated_blocks();
1496         void *current_state = NULL;
1497         int rc = 1;
1498         int handle_exceptions = 1;
1499 #ifdef _WIN32
1500         handle_exceptions = !IsDebuggerPresent();
1501 #endif // _WIN32
1502 #if UNIT_TESTING_DEBUG
1503         handle_exceptions = 0;
1504 #endif // UNIT_TESTING_DEBUG
1505
1506         if (handle_exceptions) {
1507 #ifndef _WIN32
1508                 unsigned int i;
1509                 for (i = 0; i < ARRAY_LENGTH(exception_signals); i++) {
1510                         default_signal_functions[i] = signal(
1511                             exception_signals[i], exception_handler);
1512                 }
1513 #else // _WIN32
1514                 previous_exception_filter = SetUnhandledExceptionFilter(
1515                     exception_filter);
1516 #endif // !_WIN32
1517         }
1518
1519         if (function_type == UNIT_TEST_FUNCTION_TYPE_TEST) {
1520                 print_message("%s: Starting test\n", function_name);
1521         }
1522         initialize_testing(function_name);
1523         global_running_test = 1;
1524         if (setjmp(global_run_test_env) == 0) {
1525                 Function(state ? state : &current_state);
1526                 fail_if_leftover_values(function_name);
1527
1528                 /* If this is a setup function then ignore any allocated blocks
1529                  * only ensure they're deallocated on tear down. */
1530                 if (function_type != UNIT_TEST_FUNCTION_TYPE_SETUP) {
1531                         fail_if_blocks_allocated(check_point, function_name);
1532                 }
1533
1534                 global_running_test = 0;
1535
1536                 if (function_type == UNIT_TEST_FUNCTION_TYPE_TEST) {
1537                         print_message("%s: Test completed successfully.\n", function_name);
1538                 }
1539                 rc = 0;
1540         } else {
1541                 global_running_test = 0;
1542                 print_message("%s: Test failed.\n", function_name);
1543         }
1544         teardown_testing(function_name);
1545
1546         if (handle_exceptions) {
1547 #ifndef _WIN32
1548                 unsigned int i;
1549                 for (i = 0; i < ARRAY_LENGTH(exception_signals); i++) {
1550                         signal(exception_signals[i], default_signal_functions[i]);
1551                 }
1552 #else // _WIN32
1553                 if (previous_exception_filter) {
1554                         SetUnhandledExceptionFilter(previous_exception_filter);
1555                         previous_exception_filter = NULL;
1556                 }
1557 #endif // !_WIN32
1558         }
1559
1560         return rc;
1561 }
1562
1563
1564 int _run_tests(const UnitTest * const tests, const size_t number_of_tests) {
1565         // Whether to execute the next test.
1566         int run_next_test = 1;
1567         // Whether the previous test failed.
1568         int previous_test_failed = 0;
1569         // Check point of the heap state.
1570         const ListNode * const check_point = check_point_allocated_blocks();
1571         // Current test being executed.
1572         size_t current_test = 0;
1573         // Number of tests executed.
1574         size_t tests_executed = 0;
1575         // Number of failed tests.
1576         size_t total_failed = 0;
1577         // Number of setup functions.
1578         size_t setups = 0;
1579         // Number of teardown functions.
1580         size_t teardowns = 0;
1581         /* A stack of test states.  A state is pushed on the stack
1582          * when a test setup occurs and popped on tear down. */
1583         TestState* test_states = malloc(number_of_tests * sizeof(*test_states));
1584         size_t number_of_test_states = 0;
1585         // Names of the tests that failed.
1586         const char** failed_names = malloc(number_of_tests * 
1587                                            sizeof(*failed_names));
1588         void **current_state = NULL;
1589
1590         while (current_test < number_of_tests) {
1591                 const ListNode *test_check_point = NULL;
1592                 TestState *current_TestState;
1593                 const UnitTest * const test = &tests[current_test++];
1594                 if (!test->function) {
1595                         continue;
1596                 }
1597
1598                 switch (test->function_type) {
1599                 case UNIT_TEST_FUNCTION_TYPE_TEST:
1600                         run_next_test = 1;
1601                         break;
1602                 case UNIT_TEST_FUNCTION_TYPE_SETUP: {
1603                         // Checkpoint the heap before the setup.
1604                         current_TestState = &test_states[number_of_test_states++];
1605                         current_TestState->check_point = check_point_allocated_blocks();
1606                         test_check_point = current_TestState->check_point;
1607                         current_state = &current_TestState->state;
1608                         *current_state = NULL;
1609                         run_next_test = 1;
1610                         setups ++;
1611                         break;
1612                 }
1613                 case UNIT_TEST_FUNCTION_TYPE_TEARDOWN:
1614                         // Check the heap based on the last setup checkpoint.
1615                         assert_true(number_of_test_states);
1616                         current_TestState = &test_states[--number_of_test_states];
1617                         test_check_point = current_TestState->check_point;
1618                         current_state = &current_TestState->state;
1619                         teardowns ++;
1620                         break;
1621                 default:
1622                         print_error("Invalid unit test function type %d\n",
1623                                     test->function_type);
1624                         exit_test(1);
1625                         break;
1626                 }
1627
1628                 if (run_next_test) {
1629                         int failed = _run_test(test->name, test->function, current_state,
1630                                                test->function_type, test_check_point);
1631                         if (failed) {
1632                                 failed_names[total_failed] = test->name;
1633                         }
1634
1635                         switch (test->function_type) {
1636                         case UNIT_TEST_FUNCTION_TYPE_TEST:
1637                                 previous_test_failed = failed;
1638                                 total_failed += failed;
1639                                 tests_executed ++;
1640                                 break;
1641
1642                         case UNIT_TEST_FUNCTION_TYPE_SETUP:
1643                                 if (failed) {
1644                                         total_failed ++;
1645                                         tests_executed ++;
1646                                         // Skip forward until the next test or setup function.
1647                                         run_next_test = 0;
1648                                 }
1649                                 previous_test_failed = 0;
1650                                 break;
1651
1652                         case UNIT_TEST_FUNCTION_TYPE_TEARDOWN:
1653                                 // If this test failed.
1654                                 if (failed && !previous_test_failed) {
1655                                         total_failed ++;
1656                                 }
1657                                 break;
1658                         default:
1659                                 assert_false("BUG: shouldn't be here!");
1660                                 break;
1661                         }
1662                 }
1663         }
1664
1665         if (total_failed) {
1666                 size_t i;
1667                 print_error("%d out of %d tests failed!\n", total_failed, 
1668                             tests_executed);
1669                 for (i = 0; i < total_failed; i++) {
1670                         print_error("    %s\n", failed_names[i]);
1671                 }
1672         } else {
1673                 print_message("All %d tests passed\n", tests_executed);
1674         }
1675
1676         if (number_of_test_states) {
1677                 print_error("Mismatched number of setup %d and teardown %d "
1678                             "functions\n", setups, teardowns);
1679                 total_failed = -1;
1680         }
1681
1682         free(test_states);
1683         free((void*)failed_names);
1684
1685         fail_if_blocks_allocated(check_point, "run_tests");
1686         return (int)total_failed;
1687 }