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