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