From 1c668ffa031529a49fa8fad83e9ee30c333f19ba Mon Sep 17 00:00:00 2001 From: stewartamiles Date: Thu, 23 Jul 2009 16:36:49 +0000 Subject: [PATCH] * Support for mocking long long (>= 64-bit) parameters. * Changed tabs to spaces in cmockery.c/.h to be consistent with the other source files. * Deleted all trailing whitespace. * Fixed warnings introduced in tests after adding support for 64-bit mocks. git-svn-id: http://cmockery.googlecode.com/svn/trunk@37 40f4469a-5155-0410-be90-2de3f0bae501 --- src/cmockery.c | 2085 ++++++++++++++++++---------------- src/example/calculator_test.c | 61 +- src/example/customer_database_test.c | 8 +- src/example/product_database_test.c | 6 +- src/google/cmockery.h | 319 +++--- 5 files changed, 1297 insertions(+), 1182 deletions(-) diff --git a/src/cmockery.c b/src/cmockery.c index badcd6e..ed6ab76 100755 --- a/src/cmockery.c +++ b/src/cmockery.c @@ -4,9 +4,9 @@ * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at - * + * * http://www.apache.org/licenses/LICENSE-2.0 - * + * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. @@ -59,28 +59,52 @@ WINBASEAPI BOOL WINAPI IsDebuggerPresent(VOID); // Calculates the number of elements in an array. #define ARRAY_LENGTH(x) (sizeof(x) / sizeof((x)[0])) +// Declare and initialize the pointer member of ValuePointer variable name +// with ptr. +#define declare_initialize_value_pointer_pointer(name, ptr) \ + ValuePointer name ; \ + name.value = 0; \ + name.pointer = (void*)(ptr) + +// Declare and initialize the value member of ValuePointer variable name +// with val. +#define declare_initialize_value_pointer_value(name, val) \ + ValuePointer name ; \ + name.value = val + +// Cast a LargestIntegralType to pointer_type via a ValuePointer. +#define cast_largest_integral_type_to_pointer( \ + pointer_type, largest_integral_type) \ + ((pointer_type)((ValuePointer*)&(largest_integral_type))->pointer) + +// Used to cast LargetIntegralType to void* and vice versa. +typedef union ValuePointer { + LargestIntegralType value; + void *pointer; +} ValuePointer; + // Doubly linked list node. typedef struct ListNode { - const void *value; - int refcount; - struct ListNode *next; - struct ListNode *prev; + const void *value; + int refcount; + struct ListNode *next; + struct ListNode *prev; } ListNode; // Debug information for malloc(). typedef struct MallocBlockInfo { - void* block; // Address of the block returned by malloc(). - size_t allocated_size; // Total size of the allocated block. - size_t size; // Request block size. - SourceLocation location; // Where the block was allocated. - ListNode node; // Node within list of all allocated blocks. + void* block; // Address of the block returned by malloc(). + size_t allocated_size; // Total size of the allocated block. + size_t size; // Request block size. + SourceLocation location; // Where the block was allocated. + ListNode node; // Node within list of all allocated blocks. } MallocBlockInfo; // State of each test. typedef struct TestState { - const ListNode *check_point; // Check point of the test if there's a - // setup function. - void *state; // State associated with the test. + const ListNode *check_point; // Check point of the test if there's a + // setup function. + void *state; // State associated with the test. } TestState; // Determines whether two values are the same. @@ -88,17 +112,17 @@ typedef int (*EqualityFunction)(const void *left, const void *right); // Value of a symbol and the place it was declared. typedef struct SymbolValue { - SourceLocation location; - const void* value; + SourceLocation location; + LargestIntegralType value; } SymbolValue; /* Contains a list of values for a symbol. - * NOTE: Each structure referenced by symbol_values_list_head must have a + * NOTE: Each structure referenced by symbol_values_list_head must have a * SourceLocation as its' first member. */ typedef struct SymbolMapValue { - const char *symbol_name; - ListNode symbol_values_list_head; + const char *symbol_name; + ListNode symbol_values_list_head; } SymbolMapValue; // Used by list_free() to deallocate values referenced by list nodes. @@ -106,24 +130,24 @@ typedef void (*CleanupListValue)(const void *value, void *cleanup_value_data); // Structure used to check the range of integer types. typedef struct CheckIntegerRange { - CheckParameterEvent event; - int minimum; - int maximum; + CheckParameterEvent event; + int minimum; + int maximum; } CheckIntegerRange; // Structure used to check whether an integer value is in a set. typedef struct CheckIntegerSet { - CheckParameterEvent event; - const void **set; - size_t size_of_set; + CheckParameterEvent event; + const LargestIntegralType *set; + size_t size_of_set; } CheckIntegerSet; -/* Used to check whether a parameter matches the area of memory referenced by +/* Used to check whether a parameter matches the area of memory referenced by * this structure. */ typedef struct CheckMemoryData { - CheckParameterEvent event; - const void *memory; - size_t size; + CheckParameterEvent event; + const void *memory; + size_t size; } CheckMemoryData; static ListNode* list_initialize(ListNode * const node); @@ -142,14 +166,14 @@ static int list_find( const EqualityFunction equal_func, ListNode **output); static int list_first(ListNode * const head, ListNode **output); static ListNode* list_free( - ListNode * const head, const CleanupListValue cleanup_value, + ListNode * const head, const CleanupListValue cleanup_value, void * const cleanup_value_data); static void add_symbol_value( - ListNode * const symbol_map_head, const char * const symbol_names[], + ListNode * const symbol_map_head, const char * const symbol_names[], const size_t number_of_symbol_names, const void* value, const int count); static int get_symbol_value( - ListNode * const symbol_map_head, const char * const symbol_names[], + ListNode * const symbol_map_head, const char * const symbol_names[], const size_t number_of_symbol_names, void **output); static void free_value(const void *value, void *cleanup_value_data); static void free_symbol_map_value( @@ -182,7 +206,7 @@ static ListNode global_function_result_map_head; // Location of the last mock value returned was declared. static SourceLocation global_last_mock_value_location; -/* Keeps a map of the values that functions expect as parameters to their +/* Keeps a map of the values that functions expect as parameters to their * mocked interfaces. */ static ListNode global_function_parameter_map_head; // Location of last parameter value checked was declared. @@ -194,11 +218,11 @@ static ListNode global_allocated_blocks; #ifndef _WIN32 // Signals caught by exception_handler(). static const int exception_signals[] = { - SIGFPE, - SIGILL, - SIGSEGV, - SIGBUS, - SIGSYS, + SIGFPE, + SIGILL, + SIGSEGV, + SIGBUS, + SIGSYS, }; // Default signal functions that should be restored after a test is complete. @@ -213,143 +237,143 @@ static LPTOP_LEVEL_EXCEPTION_FILTER previous_exception_filter; // Fatal exceptions. typedef struct ExceptionCodeInfo { - DWORD code; - const char* description; + DWORD code; + const char* description; } ExceptionCodeInfo; #define EXCEPTION_CODE_INFO(exception_code) {exception_code, #exception_code} static const ExceptionCodeInfo exception_codes[] = { - EXCEPTION_CODE_INFO(EXCEPTION_ACCESS_VIOLATION), - EXCEPTION_CODE_INFO(EXCEPTION_ARRAY_BOUNDS_EXCEEDED), - EXCEPTION_CODE_INFO(EXCEPTION_DATATYPE_MISALIGNMENT), - EXCEPTION_CODE_INFO(EXCEPTION_FLT_DENORMAL_OPERAND), - EXCEPTION_CODE_INFO(EXCEPTION_FLT_DIVIDE_BY_ZERO), - EXCEPTION_CODE_INFO(EXCEPTION_FLT_INEXACT_RESULT), - EXCEPTION_CODE_INFO(EXCEPTION_FLT_INVALID_OPERATION), - EXCEPTION_CODE_INFO(EXCEPTION_FLT_OVERFLOW), - EXCEPTION_CODE_INFO(EXCEPTION_FLT_STACK_CHECK), - EXCEPTION_CODE_INFO(EXCEPTION_FLT_UNDERFLOW), - EXCEPTION_CODE_INFO(EXCEPTION_GUARD_PAGE), - EXCEPTION_CODE_INFO(EXCEPTION_ILLEGAL_INSTRUCTION), - EXCEPTION_CODE_INFO(EXCEPTION_INT_DIVIDE_BY_ZERO), - EXCEPTION_CODE_INFO(EXCEPTION_INT_OVERFLOW), - EXCEPTION_CODE_INFO(EXCEPTION_INVALID_DISPOSITION), - EXCEPTION_CODE_INFO(EXCEPTION_INVALID_HANDLE), - EXCEPTION_CODE_INFO(EXCEPTION_IN_PAGE_ERROR), - EXCEPTION_CODE_INFO(EXCEPTION_NONCONTINUABLE_EXCEPTION), - EXCEPTION_CODE_INFO(EXCEPTION_PRIV_INSTRUCTION), - EXCEPTION_CODE_INFO(EXCEPTION_STACK_OVERFLOW), + EXCEPTION_CODE_INFO(EXCEPTION_ACCESS_VIOLATION), + EXCEPTION_CODE_INFO(EXCEPTION_ARRAY_BOUNDS_EXCEEDED), + EXCEPTION_CODE_INFO(EXCEPTION_DATATYPE_MISALIGNMENT), + EXCEPTION_CODE_INFO(EXCEPTION_FLT_DENORMAL_OPERAND), + EXCEPTION_CODE_INFO(EXCEPTION_FLT_DIVIDE_BY_ZERO), + EXCEPTION_CODE_INFO(EXCEPTION_FLT_INEXACT_RESULT), + EXCEPTION_CODE_INFO(EXCEPTION_FLT_INVALID_OPERATION), + EXCEPTION_CODE_INFO(EXCEPTION_FLT_OVERFLOW), + EXCEPTION_CODE_INFO(EXCEPTION_FLT_STACK_CHECK), + EXCEPTION_CODE_INFO(EXCEPTION_FLT_UNDERFLOW), + EXCEPTION_CODE_INFO(EXCEPTION_GUARD_PAGE), + EXCEPTION_CODE_INFO(EXCEPTION_ILLEGAL_INSTRUCTION), + EXCEPTION_CODE_INFO(EXCEPTION_INT_DIVIDE_BY_ZERO), + EXCEPTION_CODE_INFO(EXCEPTION_INT_OVERFLOW), + EXCEPTION_CODE_INFO(EXCEPTION_INVALID_DISPOSITION), + EXCEPTION_CODE_INFO(EXCEPTION_INVALID_HANDLE), + EXCEPTION_CODE_INFO(EXCEPTION_IN_PAGE_ERROR), + EXCEPTION_CODE_INFO(EXCEPTION_NONCONTINUABLE_EXCEPTION), + EXCEPTION_CODE_INFO(EXCEPTION_PRIV_INSTRUCTION), + EXCEPTION_CODE_INFO(EXCEPTION_STACK_OVERFLOW), }; #endif // !_WIN32 // Exit the currently executing test. static void exit_test(const int quit_application) { - if (global_running_test) { - longjmp(global_run_test_env, 1); - } else if (quit_application) { - exit(-1); - } + if (global_running_test) { + longjmp(global_run_test_env, 1); + } else if (quit_application) { + exit(-1); + } } // Initialize a SourceLocation structure. static void initialize_source_location(SourceLocation * const location) { - assert_true(location); - location->file = NULL; - location->line = 0; + assert_true(location); + location->file = NULL; + location->line = 0; } // Determine whether a source location is currently set. static int source_location_is_set(const SourceLocation * const location) { - assert_true(location); - return location->file && location->line; + assert_true(location); + return location->file && location->line; } // Set a source location. static void set_source_location( - SourceLocation * const location, const char * const file, + SourceLocation * const location, const char * const file, const int line) { - assert_true(location); - location->file = file; - location->line = line; + assert_true(location); + location->file = file; + location->line = line; } // Create function results and expected parameter lists. void initialize_testing(const char *test_name) { - list_initialize(&global_function_result_map_head); - initialize_source_location(&global_last_mock_value_location); - list_initialize(&global_function_parameter_map_head); - initialize_source_location(&global_last_parameter_location); + list_initialize(&global_function_result_map_head); + initialize_source_location(&global_last_mock_value_location); + list_initialize(&global_function_parameter_map_head); + initialize_source_location(&global_last_parameter_location); } void fail_if_leftover_values(const char *test_name) { - int error_occurred = 0; - remove_always_return_values(&global_function_result_map_head, 1); - if (check_for_leftover_values( - &global_function_result_map_head, - "%s() has remaining non-returned values.\n", 1)) { - error_occurred = 1; - } - - remove_always_return_values(&global_function_parameter_map_head, 2); - if (check_for_leftover_values( - &global_function_parameter_map_head, - "%s parameter still has values that haven't been checked.\n", 2)) { - error_occurred = 1; - } - if (error_occurred) { - exit_test(1); - } + int error_occurred = 0; + remove_always_return_values(&global_function_result_map_head, 1); + if (check_for_leftover_values( + &global_function_result_map_head, + "%s() has remaining non-returned values.\n", 1)) { + error_occurred = 1; + } + + remove_always_return_values(&global_function_parameter_map_head, 2); + if (check_for_leftover_values( + &global_function_parameter_map_head, + "%s parameter still has values that haven't been checked.\n", 2)) { + error_occurred = 1; + } + if (error_occurred) { + exit_test(1); + } } void teardown_testing(const char *test_name) { - list_free(&global_function_result_map_head, free_symbol_map_value, - (void*)0); - initialize_source_location(&global_last_mock_value_location); - list_free(&global_function_parameter_map_head, free_symbol_map_value, - (void*)1); - initialize_source_location(&global_last_parameter_location); + list_free(&global_function_result_map_head, free_symbol_map_value, + (void*)0); + initialize_source_location(&global_last_mock_value_location); + list_free(&global_function_parameter_map_head, free_symbol_map_value, + (void*)1); + initialize_source_location(&global_last_parameter_location); } // Initialize a list node. static ListNode* list_initialize(ListNode * const node) { - node->value = NULL; - node->next = node; - node->prev = node; - node->refcount = 1; - return node; + node->value = NULL; + node->next = node; + node->prev = node; + node->refcount = 1; + return node; } -/* Adds a value at the tail of a given list. +/* Adds a value at the tail of a given list. * The node referencing the value is allocated from the heap. */ static ListNode* list_add_value(ListNode * const head, const void *value, const int refcount) { - ListNode * const new_node = (ListNode*)malloc(sizeof(ListNode)); - assert_true(head); - assert_true(value); - new_node->value = value; - new_node->refcount = refcount; - return list_add(head, new_node); + ListNode * const new_node = (ListNode*)malloc(sizeof(ListNode)); + assert_true(head); + assert_true(value); + new_node->value = value; + new_node->refcount = refcount; + return list_add(head, new_node); } // Add new_node to the end of the list. static ListNode* list_add(ListNode * const head, ListNode *new_node) { - assert_true(head); - assert_true(new_node); - new_node->next = head; - new_node->prev = head->prev; - head->prev->next = new_node; - head->prev = new_node; - return new_node; + assert_true(head); + assert_true(new_node); + new_node->next = head; + new_node->prev = head->prev; + head->prev->next = new_node; + head->prev = new_node; + return new_node; } @@ -357,13 +381,13 @@ static ListNode* list_add(ListNode * const head, ListNode *new_node) { static ListNode* list_remove( ListNode * const node, const CleanupListValue cleanup_value, void * const cleanup_value_data) { - assert_true(node); - node->prev->next = node->next; - node->next->prev = node->prev; - if (cleanup_value) { - cleanup_value(node->value, cleanup_value_data); - } - return node; + assert_true(node); + node->prev->next = node->next; + node->next->prev = node->prev; + if (cleanup_value) { + cleanup_value(node->value, cleanup_value_data); + } + return node; } @@ -371,88 +395,88 @@ static ListNode* list_remove( static void list_remove_free( ListNode * const node, const CleanupListValue cleanup_value, void * const cleanup_value_data) { - assert_true(node); - free(list_remove(node, cleanup_value, cleanup_value_data)); + assert_true(node); + free(list_remove(node, cleanup_value, cleanup_value_data)); } /* Frees memory kept by a linked list * The cleanup_value function is called for every "value" field of nodes in the - * list, except for the head. In addition to each list value, + * list, except for the head. In addition to each list value, * cleanup_value_data is passed to each call to cleanup_value. The head * of the list is not deallocated. */ static ListNode* list_free( - ListNode * const head, const CleanupListValue cleanup_value, + ListNode * const head, const CleanupListValue cleanup_value, void * const cleanup_value_data) { - assert_true(head); - while (!list_empty(head)) { - list_remove_free(head->next, cleanup_value, cleanup_value_data); - } - return head; + assert_true(head); + while (!list_empty(head)) { + list_remove_free(head->next, cleanup_value, cleanup_value_data); + } + return head; } // Determine whether a list is empty. static int list_empty(const ListNode * const head) { - assert_true(head); - return head->next == head; + assert_true(head); + return head->next == head; } /* Find a value in the list using the equal_func to compare each node with the - * value. + * value. */ -static int list_find(ListNode * const head, const void *value, +static int list_find(ListNode * const head, const void *value, const EqualityFunction equal_func, ListNode **output) { - ListNode *current; - assert_true(head); - for (current = head->next; current != head; current = current->next) { - if (equal_func(current->value, value)) { - *output = current; - return 1; - } - } - return 0; + ListNode *current; + assert_true(head); + for (current = head->next; current != head; current = current->next) { + if (equal_func(current->value, value)) { + *output = current; + return 1; + } + } + return 0; } // Returns the first node of a list static int list_first(ListNode * const head, ListNode **output) { - ListNode *target_node; - assert_true(head); - if (list_empty(head)) { - return 0; - } - target_node = head->next; - *output = target_node; - return 1; + ListNode *target_node; + assert_true(head); + if (list_empty(head)) { + return 0; + } + target_node = head->next; + *output = target_node; + return 1; } // Deallocate a value referenced by a list. static void free_value(const void *value, void *cleanup_value_data) { - assert_true(value); - free((void*)value); + assert_true(value); + free((void*)value); } // Releases memory associated to a symbol_map_value. -static void free_symbol_map_value(const void *value, +static void free_symbol_map_value(const void *value, void *cleanup_value_data) { - SymbolMapValue * const map_value = (SymbolMapValue*)value; - const unsigned int children = (unsigned int)cleanup_value_data; - assert_true(value); - list_free(&map_value->symbol_values_list_head, - children ? free_symbol_map_value : free_value, - (void*)(children - 1)); - free(map_value); + SymbolMapValue * const map_value = (SymbolMapValue*)value; + const unsigned int children = (unsigned int)cleanup_value_data; + assert_true(value); + list_free(&map_value->symbol_values_list_head, + children ? free_symbol_map_value : free_value, + (void*)(children - 1)); + free(map_value); } /* Determine whether a symbol name referenced by a symbol_map_value * matches the specified function name. */ static int symbol_names_match(const void *map_value, const void *symbol) { - return !strcmp(((SymbolMapValue*)map_value)->symbol_name, + return !strcmp(((SymbolMapValue*)map_value)->symbol_name, (const char*)symbol); } @@ -464,85 +488,85 @@ static void add_symbol_value(ListNode * const symbol_map_head, const char * const symbol_names[], const size_t number_of_symbol_names, const void* value, const int refcount) { - const char* symbol_name; - ListNode *target_node; - SymbolMapValue *target_map_value; - assert_true(symbol_map_head); - assert_true(symbol_names); - assert_true(number_of_symbol_names); - symbol_name = symbol_names[0]; - - if (!list_find(symbol_map_head, symbol_name, symbol_names_match, - &target_node)) { - SymbolMapValue * const new_symbol_map_value = - malloc(sizeof(*new_symbol_map_value)); - new_symbol_map_value->symbol_name = symbol_name; - list_initialize(&new_symbol_map_value->symbol_values_list_head); - target_node = list_add_value(symbol_map_head, new_symbol_map_value, - 1); - } - - target_map_value = (SymbolMapValue*)target_node->value; - if (number_of_symbol_names == 1) { - list_add_value(&target_map_value->symbol_values_list_head, - value, refcount); - } else { - add_symbol_value(&target_map_value->symbol_values_list_head, - &symbol_names[1], number_of_symbol_names - 1, value, - refcount); - } -} - - -/* Gets the next value associated with the given hierarchy of symbols. + const char* symbol_name; + ListNode *target_node; + SymbolMapValue *target_map_value; + assert_true(symbol_map_head); + assert_true(symbol_names); + assert_true(number_of_symbol_names); + symbol_name = symbol_names[0]; + + if (!list_find(symbol_map_head, symbol_name, symbol_names_match, + &target_node)) { + SymbolMapValue * const new_symbol_map_value = + malloc(sizeof(*new_symbol_map_value)); + new_symbol_map_value->symbol_name = symbol_name; + list_initialize(&new_symbol_map_value->symbol_values_list_head); + target_node = list_add_value(symbol_map_head, new_symbol_map_value, + 1); + } + + target_map_value = (SymbolMapValue*)target_node->value; + if (number_of_symbol_names == 1) { + list_add_value(&target_map_value->symbol_values_list_head, + value, refcount); + } else { + add_symbol_value(&target_map_value->symbol_values_list_head, + &symbol_names[1], number_of_symbol_names - 1, value, + refcount); + } +} + + +/* Gets the next value associated with the given hierarchy of symbols. * The value is returned as an output parameter with the function returning the * node's old refcount value if a value is found, 0 otherwise. * This means that a return value of 1 indicates the node was just removed from * the list. */ static int get_symbol_value( - ListNode * const head, const char * const symbol_names[], + ListNode * const head, const char * const symbol_names[], const size_t number_of_symbol_names, void **output) { - const char* symbol_name; - ListNode *target_node; - assert_true(head); - assert_true(symbol_names); - assert_true(number_of_symbol_names); - assert_true(output); - symbol_name = symbol_names[0]; - - if (list_find(head, symbol_name, symbol_names_match, &target_node)) { - SymbolMapValue *map_value; - ListNode *child_list; - int return_value = 0; - assert_true(target_node); - assert_true(target_node->value); - - map_value = (SymbolMapValue*)target_node->value; - child_list = &map_value->symbol_values_list_head; - - if (number_of_symbol_names == 1) { - ListNode *value_node = NULL; - return_value = list_first(child_list, &value_node); - assert_true(return_value); - *output = (void*) value_node->value; - return_value = value_node->refcount; - if (--value_node->refcount == 0) { - list_remove_free(value_node, NULL, NULL); - } - } else { - return_value = get_symbol_value( - child_list, &symbol_names[1], number_of_symbol_names - 1, - output); - } - if (list_empty(child_list)) { - list_remove_free(target_node, free_symbol_map_value, (void*)0); - } - return return_value; - } else { - print_error("No entries for symbol %s.\n", symbol_name); - } - return 0; + const char* symbol_name; + ListNode *target_node; + assert_true(head); + assert_true(symbol_names); + assert_true(number_of_symbol_names); + assert_true(output); + symbol_name = symbol_names[0]; + + if (list_find(head, symbol_name, symbol_names_match, &target_node)) { + SymbolMapValue *map_value; + ListNode *child_list; + int return_value = 0; + assert_true(target_node); + assert_true(target_node->value); + + map_value = (SymbolMapValue*)target_node->value; + child_list = &map_value->symbol_values_list_head; + + if (number_of_symbol_names == 1) { + ListNode *value_node = NULL; + return_value = list_first(child_list, &value_node); + assert_true(return_value); + *output = (void*) value_node->value; + return_value = value_node->refcount; + if (--value_node->refcount == 0) { + list_remove_free(value_node, NULL, NULL); + } + } else { + return_value = get_symbol_value( + child_list, &symbol_names[1], number_of_symbol_names - 1, + output); + } + if (list_empty(child_list)) { + list_remove_free(target_node, free_symbol_map_value, (void*)0); + } + return return_value; + } else { + print_error("No entries for symbol %s.\n", symbol_name); + } + return 0; } @@ -552,35 +576,35 @@ static int get_symbol_value( */ static void remove_always_return_values(ListNode * const map_head, const size_t number_of_symbol_names) { - ListNode *current; - assert_true(map_head); - assert_true(number_of_symbol_names); - current = map_head->next; - while (current != map_head) { - SymbolMapValue * const value = (SymbolMapValue*)current->value; - ListNode * const next = current->next; - ListNode *child_list; - assert_true(value); - child_list = &value->symbol_values_list_head; - - if (!list_empty(child_list)) { - if (number_of_symbol_names == 1) { - ListNode * const child_node = child_list->next; - // If this item has been returned more than once, free it. - if (child_node->refcount < -1) { - list_remove_free(child_node, free_value, NULL); - } - } else { - remove_always_return_values(child_list, - number_of_symbol_names - 1); - } - } - - if (list_empty(child_list)) { - list_remove_free(current, free_value, NULL); - } - current = next; - } + ListNode *current; + assert_true(map_head); + assert_true(number_of_symbol_names); + current = map_head->next; + while (current != map_head) { + SymbolMapValue * const value = (SymbolMapValue*)current->value; + ListNode * const next = current->next; + ListNode *child_list; + assert_true(value); + child_list = &value->symbol_values_list_head; + + if (!list_empty(child_list)) { + if (number_of_symbol_names == 1) { + ListNode * const child_node = child_list->next; + // If this item has been returned more than once, free it. + if (child_node->refcount < -1) { + list_remove_free(child_node, free_value, NULL); + } + } else { + remove_always_return_values(child_list, + number_of_symbol_names - 1); + } + } + + if (list_empty(child_list)) { + list_remove_free(current, free_value, NULL); + } + current = next; + } } /* Checks if there are any leftover values set up by the test that were never @@ -589,84 +613,85 @@ static void remove_always_return_values(ListNode * const map_head, static int check_for_leftover_values( const ListNode * const map_head, const char * const error_message, const size_t number_of_symbol_names) { - const ListNode *current; - int symbols_with_leftover_values = 0; - assert_true(map_head); - assert_true(number_of_symbol_names); - - for (current = map_head->next; current != map_head; - current = current->next) { - const SymbolMapValue * const value = - (SymbolMapValue*)current->value; - const ListNode *child_list; - assert_true(value); - child_list = &value->symbol_values_list_head; - - if (!list_empty(child_list)) { - if (number_of_symbol_names == 1) { - const ListNode *child_node; - print_error(error_message, value->symbol_name); - print_error(" Remaining item(s) declared at...\n"); - - for (child_node = child_list->next; child_node != child_list; - child_node = child_node->next) { - const SourceLocation * const location = child_node->value; - print_error(" " SOURCE_LOCATION_FORMAT "\n", - location->file, location->line); - } - } else { - print_error("%s.", value->symbol_name); - check_for_leftover_values(child_list, error_message, - number_of_symbol_names - 1); - } - symbols_with_leftover_values ++; - } - } - return symbols_with_leftover_values; + const ListNode *current; + int symbols_with_leftover_values = 0; + assert_true(map_head); + assert_true(number_of_symbol_names); + + for (current = map_head->next; current != map_head; + current = current->next) { + const SymbolMapValue * const value = + (SymbolMapValue*)current->value; + const ListNode *child_list; + assert_true(value); + child_list = &value->symbol_values_list_head; + + if (!list_empty(child_list)) { + if (number_of_symbol_names == 1) { + const ListNode *child_node; + print_error(error_message, value->symbol_name); + print_error(" Remaining item(s) declared at...\n"); + + for (child_node = child_list->next; child_node != child_list; + child_node = child_node->next) { + const SourceLocation * const location = child_node->value; + print_error(" " SOURCE_LOCATION_FORMAT "\n", + location->file, location->line); + } + } else { + print_error("%s.", value->symbol_name); + check_for_leftover_values(child_list, error_message, + number_of_symbol_names - 1); + } + symbols_with_leftover_values ++; + } + } + return symbols_with_leftover_values; } // Get the next return value for the specified mock function. -void* _mock(const char * const function, const char* const file, - const int line) { - void *result; - const int rc = get_symbol_value(&global_function_result_map_head, - &function, 1, &result); - if (rc) { - SymbolValue * const symbol = result; - void * const value = (void*)symbol->value; - global_last_mock_value_location = symbol->location; - if (rc == 1) { - free(symbol); - } - return value; - } else { - print_error("ERROR: " SOURCE_LOCATION_FORMAT " - Could not get value " - "to mock function %s\n", file, line, function); - if (source_location_is_set(&global_last_mock_value_location)) { - print_error("Previously returned mock value was declared at " - SOURCE_LOCATION_FORMAT "\n", - global_last_mock_value_location.file, - global_last_mock_value_location.line); - } else { - print_error("There were no previously returned mock values for " - "this test.\n"); - } - exit_test(1); - } - return NULL; +LargestIntegralType _mock(const char * const function, const char* const file, + const int line) { + void *result; + const int rc = get_symbol_value(&global_function_result_map_head, + &function, 1, &result); + if (rc) { + SymbolValue * const symbol = (SymbolValue*)result; + const LargestIntegralType value = symbol->value; + global_last_mock_value_location = symbol->location; + if (rc == 1) { + free(symbol); + } + return value; + } else { + print_error("ERROR: " SOURCE_LOCATION_FORMAT " - Could not get value " + "to mock function %s\n", file, line, function); + if (source_location_is_set(&global_last_mock_value_location)) { + print_error("Previously returned mock value was declared at " + SOURCE_LOCATION_FORMAT "\n", + global_last_mock_value_location.file, + global_last_mock_value_location.line); + } else { + print_error("There were no previously returned mock values for " + "this test.\n"); + } + exit_test(1); + } + return 0; } // Add a return value for the specified mock function name. -void _will_return(const char * const function_name, const char * const file, - const int line, const void* const value, const int count) { - SymbolValue * const return_value = malloc(sizeof(*return_value)); - assert_true(count > 0 || count == -1); - return_value->value = value; - set_source_location(&return_value->location, file, line); - add_symbol_value(&global_function_result_map_head, &function_name, 1, - return_value, count); +void _will_return(const char * const function_name, const char * const file, + const int line, const LargestIntegralType value, + const int count) { + SymbolValue * const return_value = malloc(sizeof(*return_value)); + assert_true(count > 0 || count == -1); + return_value->value = value; + set_source_location(&return_value->location, file, line); + add_symbol_value(&global_function_result_map_head, &function_name, 1, + return_value, count); } @@ -676,268 +701,287 @@ void _will_return(const char * const function_name, const char * const file, * be deallocated by the caller. */ void _expect_check( - const char* const function, const char* const parameter, + const char* const function, const char* const parameter, const char* const file, const int line, - const CheckParameterValue check_function, void * const check_data, + const CheckParameterValue check_function, + const LargestIntegralType check_data, CheckParameterEvent * const event, const int count) { - CheckParameterEvent * const check = - event ? event : malloc(sizeof(*check)); - const char* symbols[] = {function, parameter}; - check->parameter_name = parameter; - check->check_value = check_function; - check->check_value_data = check_data; - set_source_location(&check->location, file, line); - add_symbol_value(&global_function_parameter_map_head, symbols, 2, check, - count); + CheckParameterEvent * const check = + event ? event : malloc(sizeof(*check)); + const char* symbols[] = {function, parameter}; + check->parameter_name = parameter; + check->check_value = check_function; + check->check_value_data = check_data; + set_source_location(&check->location, file, line); + add_symbol_value(&global_function_parameter_map_head, symbols, 2, check, + count); } /* Returns 1 if the specified values are equal. If the values are not equal * an error is displayed and 0 is returned. */ -static int values_equal_display_error(const void* const left, - const void* const right) { - const int equal = left == right; - if (!equal) { - print_error("0x%x != 0x%x\n", left, right); - } - return equal; +static int values_equal_display_error(const LargestIntegralType left, + const LargestIntegralType right) { + const int equal = left == right; + if (!equal) { + print_error(LargestIntegralTypePrintfFormat " != " + LargestIntegralTypePrintfFormat "\n", left, right); + } + return equal; } /* Returns 1 if the specified values are not equal. If the values are equal * an error is displayed and 0 is returned. */ -static int values_not_equal_display_error(const void* const left, - const void* const right) { - const int not_equal = left != right; - if (!not_equal) { - print_error("0x%x == 0x%x\n", left, right); - } - return not_equal; +static int values_not_equal_display_error(const LargestIntegralType left, + const LargestIntegralType right) { + const int not_equal = left != right; + if (!not_equal) { + print_error(LargestIntegralTypePrintfFormat " == " + LargestIntegralTypePrintfFormat "\n", left, right); + } + return not_equal; } /* Determine whether value is contained within check_integer_set. * If invert is 0 and the value is in the set 1 is returned, otherwise 0 is - * returned and an error is displayed. If invert is 1 and the value is not - * in the set 1 is returned, otherwise 0 is returned and an error is + * returned and an error is displayed. If invert is 1 and the value is not + * in the set 1 is returned, otherwise 0 is returned and an error is * displayed. */ static int value_in_set_display_error( - const void *value, const CheckIntegerSet * const check_integer_set, - const int invert) { - int succeeded = invert; - assert_true(check_integer_set); - { - const void ** const set = check_integer_set->set; - const size_t size_of_set = check_integer_set->size_of_set; - size_t i; - for (i = 0; i < size_of_set; i++) { - if (set[i] == value) { - // If invert = 0 and item is found, succeeded = 1. - // If invert = 1 and item is found, succeeded = 0. - succeeded = !succeeded; - break; - } - } - if (succeeded) { - return 1; - } - print_error("%d is %sin the set (", value, invert ? "" : "not "); - for (i = 0; i < size_of_set; i++) { - print_error("%d, ", set[i]); - } - print_error(")\n"); - } - return 0; + const LargestIntegralType value, + const CheckIntegerSet * const check_integer_set, const int invert) { + int succeeded = invert; + assert_true(check_integer_set); + { + const LargestIntegralType * const set = check_integer_set->set; + const size_t size_of_set = check_integer_set->size_of_set; + size_t i; + for (i = 0; i < size_of_set; i++) { + if (set[i] == value) { + // If invert = 0 and item is found, succeeded = 1. + // If invert = 1 and item is found, succeeded = 0. + succeeded = !succeeded; + break; + } + } + if (succeeded) { + return 1; + } + print_error("%d is %sin the set (", value, invert ? "" : "not "); + for (i = 0; i < size_of_set; i++) { + print_error("%d, ", set[i]); + } + print_error(")\n"); + } + return 0; } /* Determine whether a value is within the specified range. If the value is - * within the specified range 1 is returned. If the value isn't within the + * within the specified range 1 is returned. If the value isn't within the * specified range an error is displayed and 0 is returned. */ static int integer_in_range_display_error( - const int value, const int range_min, const int range_max) { - if (value >= range_min && value <= range_max) { - return 1; - } - print_error("%d is not within the range %d-%d\n", value, range_min, - range_max); - return 0; + const LargestIntegralType value, const LargestIntegralType range_min, + const LargestIntegralType range_max) { + if (value >= range_min && value <= range_max) { + return 1; + } + print_error("%d is not within the range %d-%d\n", value, range_min, + range_max); + return 0; } /* Determine whether a value is within the specified range. If the value - * is not within the range 1 is returned. If the value is within the + * is not within the range 1 is returned. If the value is within the * specified range an error is displayed and zero is returned. */ static int integer_not_in_range_display_error( - const int value, const int range_min, const int range_max) { - if (value < range_min || value > range_max) { - return 1; - } - print_error("%d is within the range %d-%d\n", value, range_min, - range_max); - return 0; + const LargestIntegralType value, const LargestIntegralType range_min, + const LargestIntegralType range_max) { + if (value < range_min || value > range_max) { + return 1; + } + print_error("%d is within the range %d-%d\n", value, range_min, + range_max); + return 0; } /* Determine whether the specified strings are equal. If the strings are equal - * 1 is returned. If they're not equal an error is displayed and 0 is + * 1 is returned. If they're not equal an error is displayed and 0 is * returned. */ static int string_equal_display_error( const char * const left, const char * const right) { - if (strcmp(left, right) == 0) { - return 1; - } - print_error("\"%s\" != \"%s\"\n", left, right); - return 0; + if (strcmp(left, right) == 0) { + return 1; + } + print_error("\"%s\" != \"%s\"\n", left, right); + return 0; } -/* Determine whether the specified strings are equal. If the strings are not - * equal 1 is returned. If they're not equal an error is displayed and 0 is +/* Determine whether the specified strings are equal. If the strings are not + * equal 1 is returned. If they're not equal an error is displayed and 0 is * returned */ static int string_not_equal_display_error( const char * const left, const char * const right) { - if (strcmp(left, right) != 0) { - return 1; - } - print_error("\"%s\" == \"%s\"\n", left, right); - return 0; + if (strcmp(left, right) != 0) { + return 1; + } + print_error("\"%s\" == \"%s\"\n", left, right); + return 0; } /* Determine whether the specified areas of memory are equal. If they're equal * 1 is returned otherwise an error is displayed and 0 is returned. */ -static int memory_equal_display_error(const char* a, const char* b, +static int memory_equal_display_error(const char* const a, const char* const b, const size_t size) { - int differences = 0; - size_t i; - for (i = 0; i < size; i++) { - const char l = a[i]; - const char r = b[i]; - if (l != r) { - print_error("difference at offset %d 0x%02x 0x%02x\n", i, l, r); - differences ++; - } - } - if (differences) { - print_error("%d bytes of 0x%08x and 0x%08x differ\n", differences, - a, b); - return 0; - } - return 1; -} - - -/* Determine whether the specified areas of memory are not equal. If they're - * not equal 1 is returned otherwise an error is displayed and 0 is + int differences = 0; + size_t i; + for (i = 0; i < size; i++) { + const char l = a[i]; + const char r = b[i]; + if (l != r) { + print_error("difference at offset %d 0x%02x 0x%02x\n", i, l, r); + differences ++; + } + } + if (differences) { + print_error("%d bytes of 0x%08x and 0x%08x differ\n", differences, + a, b); + return 0; + } + return 1; +} + + +/* Determine whether the specified areas of memory are not equal. If they're + * not equal 1 is returned otherwise an error is displayed and 0 is * returned. */ -static int memory_not_equal_display_error(const char* a, const char* b, - const size_t size) { - int same = 0; - size_t i; - for (i = 0; i < size; i++) { - const char l = a[i]; - const char r = b[i]; - if (l == r) { - print_error("equal at offset %d 0x%02x 0x%02x\n", i, l, r); - same ++; - } - } - if (same) { - print_error("%d bytes of 0x%08x and 0x%08x the same\n", same, - a, b); - return 0; - } - return 1; +static int memory_not_equal_display_error( + const char* const a, const char* const b, const size_t size) { + int same = 0; + size_t i; + for (i = 0; i < size; i++) { + const char l = a[i]; + const char r = b[i]; + if (l == r) { + print_error("equal at offset %d 0x%02x 0x%02x\n", i, l, r); + same ++; + } + } + if (same) { + print_error("%d bytes of 0x%08x and 0x%08x the same\n", same, + a, b); + return 0; + } + return 1; } // CheckParameterValue callback to check whether a value is within a set. -static int check_in_set(const void *value, void *check_value_data) { - return value_in_set_display_error(value, - (CheckIntegerSet*)check_value_data, 0); +static int check_in_set(const LargestIntegralType value, + const LargestIntegralType check_value_data) { + return value_in_set_display_error(value, + cast_largest_integral_type_to_pointer(CheckIntegerSet*, + check_value_data), 0); } // CheckParameterValue callback to check whether a value isn't within a set. -static int check_not_in_set(const void *value, void *check_value_data) { - return value_in_set_display_error(value, - (CheckIntegerSet*)check_value_data, 1); +static int check_not_in_set(const LargestIntegralType value, + const LargestIntegralType check_value_data) { + return value_in_set_display_error(value, + cast_largest_integral_type_to_pointer(CheckIntegerSet*, + check_value_data), 1); } -/* Create the callback data for check_in_set() or check_not_in_set() and +/* Create the callback data for check_in_set() or check_not_in_set() and * register a check event. */ static void expect_set( const char* const function, const char* const parameter, - const char* const file, const int line, const void *values[], - const size_t number_of_values, + const char* const file, const int line, + const LargestIntegralType values[], const size_t number_of_values, const CheckParameterValue check_function, const int count) { - CheckIntegerSet * const check_integer_set = - malloc(sizeof(*check_integer_set) + - (sizeof(values[0]) * number_of_values)); - void ** const set = (void**)(check_integer_set + 1); - assert_true(values); - assert_true(number_of_values); - memcpy(set, values, number_of_values * sizeof(values[0])); - check_integer_set->set = (const void**)set; - _expect_check(function, parameter, file, line, check_function, - check_integer_set, &check_integer_set->event, count); + CheckIntegerSet * const check_integer_set = + malloc(sizeof(*check_integer_set) + + (sizeof(values[0]) * number_of_values)); + LargestIntegralType * const set = (LargestIntegralType*)( + check_integer_set + 1); + declare_initialize_value_pointer_pointer(check_data, check_integer_set); + assert_true(values); + assert_true(number_of_values); + memcpy(set, values, number_of_values * sizeof(values[0])); + check_integer_set->set = set; + _expect_check( + function, parameter, file, line, check_function, + check_data.value, &check_integer_set->event, count); } // Add an event to check whether a value is in a set. void _expect_in_set( - const char* const function, const char* const parameter, - const char* const file, const int line, const void *values[], - const size_t number_of_values, const int count) { - expect_set(function, parameter, file, line, values, number_of_values, - check_in_set, count); + const char* const function, const char* const parameter, + const char* const file, const int line, + const LargestIntegralType values[], const size_t number_of_values, + const int count) { + expect_set(function, parameter, file, line, values, number_of_values, + check_in_set, count); } // Add an event to check whether a value isn't in a set. void _expect_not_in_set( - const char* const function, const char* const parameter, - const char* const file, const int line, const void *values[], - const size_t number_of_values, const int count) { - expect_set(function, parameter, file, line, values, number_of_values, - check_not_in_set, count); + const char* const function, const char* const parameter, + const char* const file, const int line, + const LargestIntegralType values[], const size_t number_of_values, + const int count) { + expect_set(function, parameter, file, line, values, number_of_values, + check_not_in_set, count); } // CheckParameterValue callback to check whether a value is within a range. -static int check_in_range(const void *value, void *check_value_data) { - CheckIntegerRange * const check_integer_range = check_value_data; - assert_true(check_value_data); - return integer_in_range_display_error( - (int)value, check_integer_range->minimum, - check_integer_range->maximum); +static int check_in_range(const LargestIntegralType value, + const LargestIntegralType check_value_data) { + CheckIntegerRange * const check_integer_range = + cast_largest_integral_type_to_pointer(CheckIntegerRange*, + check_value_data); + assert_true(check_integer_range); + return integer_in_range_display_error(value, check_integer_range->minimum, + check_integer_range->maximum); } // CheckParameterValue callback to check whether a value is not within a range. -static int check_not_in_range(const void *value, void *check_value_data) { - CheckIntegerRange * const check_integer_range = check_value_data; - assert_true(check_value_data); - return integer_not_in_range_display_error( - (int)value, check_integer_range->minimum, - check_integer_range->maximum); +static int check_not_in_range(const LargestIntegralType value, + const LargestIntegralType check_value_data) { + CheckIntegerRange * const check_integer_range = + cast_largest_integral_type_to_pointer(CheckIntegerRange*, + check_value_data); + assert_true(check_integer_range); + return integer_not_in_range_display_error( + value, check_integer_range->minimum, check_integer_range->maximum); } -/* Create the callback data for check_in_range() or check_not_in_range() and +/* Create the callback data for check_in_range() or check_not_in_range() and * register a check event. */ static void expect_range( const char* const function, const char* const parameter, const char* const file, const int line, - const int minimum, const int maximum, + const LargestIntegralType minimum, const LargestIntegralType maximum, const CheckParameterValue check_function, const int count) { - CheckIntegerRange * const check_integer_range = - malloc(sizeof(*check_integer_range)); - check_integer_range->minimum = minimum; - check_integer_range->maximum = maximum; - _expect_check(function, parameter, file, line, check_function, - check_integer_range, &check_integer_range->event, count); + CheckIntegerRange * const check_integer_range = + malloc(sizeof(*check_integer_range)); + declare_initialize_value_pointer_pointer(check_data, check_integer_range); + check_integer_range->minimum = minimum; + check_integer_range->maximum = maximum; + _expect_check(function, parameter, file, line, check_function, + check_data.value, &check_integer_range->event, count); } @@ -945,9 +989,10 @@ static void expect_range( void _expect_in_range( const char* const function, const char* const parameter, const char* const file, const int line, - const int minimum, const int maximum, const int count) { - expect_range(function, parameter, file, line, minimum, maximum, - check_in_range, count); + const LargestIntegralType minimum, const LargestIntegralType maximum, + const int count) { + expect_range(function, parameter, file, line, minimum, maximum, + check_in_range, count); } @@ -955,49 +1000,55 @@ void _expect_in_range( void _expect_not_in_range( const char* const function, const char* const parameter, const char* const file, const int line, - const int minimum, const int maximum, const int count) { - expect_range(function, parameter, file, line, minimum, maximum, - check_not_in_range, count); + const LargestIntegralType minimum, const LargestIntegralType maximum, + const int count) { + expect_range(function, parameter, file, line, minimum, maximum, + check_not_in_range, count); } -/* CheckParameterValue callback to check whether a value is equal to an +/* CheckParameterValue callback to check whether a value is equal to an * expected value. */ -static int check_value(const void *value, void *check_value_data) { - return values_equal_display_error(value, check_value_data); +static int check_value(const LargestIntegralType value, + const LargestIntegralType check_value_data) { + return values_equal_display_error(value, check_value_data); } // Add an event to check a parameter equals an expected value. void _expect_value( const char* const function, const char* const parameter, - const char* const file, const int line, const void* const value, - const int count) { - _expect_check(function, parameter, file, line, check_value, - (void*)value, NULL, count); + const char* const file, const int line, + const LargestIntegralType value, const int count) { + _expect_check(function, parameter, file, line, check_value, value, NULL, + count); } -/* CheckParameterValue callback to check whether a value is not equal to an +/* CheckParameterValue callback to check whether a value is not equal to an * expected value. */ -static int check_not_value(const void *value, void *check_value_data) { - return values_not_equal_display_error(value, check_value_data); +static int check_not_value(const LargestIntegralType value, + const LargestIntegralType check_value_data) { + return values_not_equal_display_error(value, check_value_data); } // Add an event to check a parameter is not equal to an expected value. void _expect_not_value( - const char* const function, const char* const parameter, - const char* const file, const int line, const void* const value, - const int count) { - _expect_check(function, parameter, file, line, check_not_value, - (void*)value, NULL, count); + const char* const function, const char* const parameter, + const char* const file, const int line, + const LargestIntegralType value, const int count) { + _expect_check(function, parameter, file, line, check_not_value, value, + NULL, count); } // CheckParameterValue callback to check whether a parameter equals a string. -static int check_string(const void * value, void *check_value_data) { - return string_equal_display_error(value, check_value_data); +static int check_string(const LargestIntegralType value, + const LargestIntegralType check_value_data) { + return string_equal_display_error( + cast_largest_integral_type_to_pointer(char*, value), + cast_largest_integral_type_to_pointer(char*, check_value_data)); } @@ -1006,15 +1057,19 @@ void _expect_string( const char* const function, const char* const parameter, const char* const file, const int line, const char* string, const int count) { - _expect_check(function, parameter, file, line, check_string, (void*)string, - NULL, count); + declare_initialize_value_pointer_pointer(string_pointer, (char*)string); + _expect_check(function, parameter, file, line, check_string, + string_pointer.value, NULL, count); } -/* CheckParameterValue callback to check whether a parameter is not equals to +/* CheckParameterValue callback to check whether a parameter is not equals to * a string. */ -static int check_not_string(const void * value, void *check_value_data) { - return string_not_equal_display_error(value, check_value_data); +static int check_not_string(const LargestIntegralType value, + const LargestIntegralType check_value_data) { + return string_not_equal_display_error( + cast_largest_integral_type_to_pointer(char*, value), + cast_largest_integral_type_to_pointer(char*, check_value_data)); } @@ -1023,35 +1078,41 @@ void _expect_not_string( const char* const function, const char* const parameter, const char* const file, const int line, const char* string, const int count) { - _expect_check(function, parameter, file, line, check_not_string, - (void*)string, NULL, count); + declare_initialize_value_pointer_pointer(string_pointer, (char*)string); + _expect_check(function, parameter, file, line, check_not_string, + string_pointer.value, NULL, count); } /* CheckParameterValue callback to check whether a parameter equals an area of * memory. */ -static int check_memory(const void* value, void *check_value_data) { - CheckMemoryData * const check = (CheckMemoryData*)check_value_data; - assert_true(check); - return memory_equal_display_error(value, check->memory, check->size); +static int check_memory(const LargestIntegralType value, + const LargestIntegralType check_value_data) { + CheckMemoryData * const check = cast_largest_integral_type_to_pointer( + CheckMemoryData*, check_value_data); + assert_true(check); + return memory_equal_display_error( + cast_largest_integral_type_to_pointer(void*, value), + check->memory, check->size); } -/* Create the callback data for check_memory() or check_not_memory() and +/* Create the callback data for check_memory() or check_not_memory() and * register a check event. */ static void expect_memory_setup( const char* const function, const char* const parameter, const char* const file, const int line, const void * const memory, const size_t size, const CheckParameterValue check_function, const int count) { - CheckMemoryData * const check_data = malloc(sizeof(*check_data) + size); - void * const mem = (void*)(check_data + 1); - assert_true(memory); - assert_true(size); - memcpy(mem, memory, size); - check_data->memory = mem; - check_data->size = size; - _expect_check(function, parameter, file, line, check_function, - check_data, &check_data->event, count); + CheckMemoryData * const check_data = malloc(sizeof(*check_data) + size); + void * const mem = (void*)(check_data + 1); + declare_initialize_value_pointer_pointer(check_data_pointer, check_data); + assert_true(memory); + assert_true(size); + memcpy(mem, memory, size); + check_data->memory = mem; + check_data->size = size; + _expect_check(function, parameter, file, line, check_function, + check_data_pointer.value, &check_data->event, count); } @@ -1060,33 +1121,38 @@ void _expect_memory( const char* const function, const char* const parameter, const char* const file, const int line, const void* const memory, const size_t size, const int count) { - expect_memory_setup(function, parameter, file, line, memory, size, - check_memory, count); + expect_memory_setup(function, parameter, file, line, memory, size, + check_memory, count); } /* CheckParameterValue callback to check whether a parameter is not equal to * an area of memory. */ -static int check_not_memory(const void* value, void *check_value_data) { - CheckMemoryData * const check = (CheckMemoryData*)check_value_data; - assert_true(check); - return memory_not_equal_display_error(value, check->memory, check->size); +static int check_not_memory(const LargestIntegralType value, + const LargestIntegralType check_value_data) { + CheckMemoryData * const check = cast_largest_integral_type_to_pointer( + CheckMemoryData*, check_value_data); + assert_true(check); + return memory_not_equal_display_error( + cast_largest_integral_type_to_pointer(void*, value), check->memory, + check->size); } // Add an event to check whether a parameter doesn't match an area of memory. void _expect_not_memory( const char* const function, const char* const parameter, - const char* const file, const int line, const void* const memory, + const char* const file, const int line, const void* const memory, const size_t size, const int count) { - expect_memory_setup(function, parameter, file, line, memory, size, - check_not_memory, count); + expect_memory_setup(function, parameter, file, line, memory, size, + check_not_memory, count); } // CheckParameterValue callback that always returns 1. -static int check_any(const void *value, void *check_value_data) { - return 1; +static int check_any(const LargestIntegralType value, + const LargestIntegralType check_value_data) { + return 1; } @@ -1094,599 +1160,608 @@ static int check_any(const void *value, void *check_value_data) { void _expect_any( const char* const function, const char* const parameter, const char* const file, const int line, const int count) { - _expect_check(function, parameter, file, line, check_any, NULL, NULL, - count); + _expect_check(function, parameter, file, line, check_any, 0, NULL, + count); } void _check_expected( const char * const function_name, const char * const parameter_name, - const char* file, const int line, const void* value) { - void *result; - const char* symbols[] = {function_name, parameter_name}; - const int rc = get_symbol_value(&global_function_parameter_map_head, - symbols, 2, &result); - if (rc) { - CheckParameterEvent * const check = (CheckParameterEvent*)result; - int check_succeeded; - global_last_parameter_location = check->location; - check_succeeded = check->check_value(value, check->check_value_data); - if (rc == 1) { - free(check); - } - if (!check_succeeded) { - print_error("ERROR: Check of parameter %s, function %s failed\n" - "Expected parameter declared at " - SOURCE_LOCATION_FORMAT "\n", - parameter_name, function_name, - global_last_parameter_location.file, - global_last_parameter_location.line); - _fail(file, line); - } - } else { - print_error("ERROR: " SOURCE_LOCATION_FORMAT " - Could not get value " - "to check parameter %s of function %s\n", file, line, - parameter_name, function_name); - if (source_location_is_set(&global_last_parameter_location)) { - print_error("Previously declared parameter value was declared at " - SOURCE_LOCATION_FORMAT "\n", - global_last_parameter_location.file, - global_last_parameter_location.line); - } else { - print_error("There were no previously declared parameter values " - "for this test.\n"); - } - exit_test(1); - } + const char* file, const int line, const LargestIntegralType value) { + void *result; + const char* symbols[] = {function_name, parameter_name}; + const int rc = get_symbol_value(&global_function_parameter_map_head, + symbols, 2, &result); + if (rc) { + CheckParameterEvent * const check = (CheckParameterEvent*)result; + int check_succeeded; + global_last_parameter_location = check->location; + check_succeeded = check->check_value(value, check->check_value_data); + if (rc == 1) { + free(check); + } + if (!check_succeeded) { + print_error("ERROR: Check of parameter %s, function %s failed\n" + "Expected parameter declared at " + SOURCE_LOCATION_FORMAT "\n", + parameter_name, function_name, + global_last_parameter_location.file, + global_last_parameter_location.line); + _fail(file, line); + } + } else { + print_error("ERROR: " SOURCE_LOCATION_FORMAT " - Could not get value " + "to check parameter %s of function %s\n", file, line, + parameter_name, function_name); + if (source_location_is_set(&global_last_parameter_location)) { + print_error("Previously declared parameter value was declared at " + SOURCE_LOCATION_FORMAT "\n", + global_last_parameter_location.file, + global_last_parameter_location.line); + } else { + print_error("There were no previously declared parameter values " + "for this test.\n"); + } + exit_test(1); + } } // Replacement for assert. -void mock_assert(const int result, const char* const expression, +void mock_assert(const int result, const char* const expression, const char* const file, const int line) { - if (!result) { - if (global_expecting_assert) { - longjmp(global_expect_assert_env, (int)expression); - } else { - print_error("ASSERT: %s\n", expression); - _fail(file, line); - } - } + if (!result) { + if (global_expecting_assert) { + longjmp(global_expect_assert_env, (int)expression); + } else { + print_error("ASSERT: %s\n", expression); + _fail(file, line); + } + } } -void _assert_true(const int result, const char * const expression, +void _assert_true(const int result, const char * const expression, const char * const file, const int line) { - if (!result) { - print_error("%s\n", expression); - _fail(file, line); - } + if (!result) { + print_error("%s\n", expression); + _fail(file, line); + } } -void _assert_int_equal(const int a, const int b, const char * const file, - const int line) { - if (!values_equal_display_error((void*)a, (void*)b)) { - _fail(file, line); - } +void _assert_int_equal( + const LargestIntegralType a, const LargestIntegralType b, + const char * const file, const int line) { + if (!values_equal_display_error(a, b)) { + _fail(file, line); + } } -void _assert_int_not_equal(const int a, const int b, const char * const file, - const int line) { - if (!values_not_equal_display_error((void*)a, (void*)b)) { - _fail(file, line); - } +void _assert_int_not_equal( + const LargestIntegralType a, const LargestIntegralType b, + const char * const file, const int line) { + if (!values_not_equal_display_error(a, b)) { + _fail(file, line); + } } -void _assert_string_equal(const char * const a, const char * const b, +void _assert_string_equal(const char * const a, const char * const b, const char * const file, const int line) { - if (!string_equal_display_error(a, b)) { - _fail(file, line); - } + if (!string_equal_display_error(a, b)) { + _fail(file, line); + } } -void _assert_string_not_equal(const char * const a, const char * const b, +void _assert_string_not_equal(const char * const a, const char * const b, const char *file, const int line) { - if (!string_not_equal_display_error(a, b)) { - _fail(file, line); - } + if (!string_not_equal_display_error(a, b)) { + _fail(file, line); + } } -void _assert_memory_equal(const void * const a, const void * const b, - const size_t size, const char* const file, +void _assert_memory_equal(const void * const a, const void * const b, + const size_t size, const char* const file, const int line) { - if (!memory_equal_display_error((const char*)a, (const char*)b, size)) { - _fail(file, line); - } + if (!memory_equal_display_error((const char*)a, (const char*)b, size)) { + _fail(file, line); + } } void _assert_memory_not_equal(const void * const a, const void * const b, - const size_t size, const char* const file, + const size_t size, const char* const file, const int line) { - if (!memory_not_equal_display_error((const char*)a, (const char*)b, - size)) { - _fail(file, line); - } + if (!memory_not_equal_display_error((const char*)a, (const char*)b, + size)) { + _fail(file, line); + } } -void _assert_in_range(const int value, const int minimum, const int maximum, - const char* const file, const int line) { - if (!integer_in_range_display_error(value, minimum, maximum)) { - _fail(file, line); - } +void _assert_in_range( + const LargestIntegralType value, const LargestIntegralType minimum, + const LargestIntegralType maximum, const char* const file, + const int line) { + if (!integer_in_range_display_error(value, minimum, maximum)) { + _fail(file, line); + } } -void _assert_not_in_range(const int value, const int minimum, - const int maximum, const char* const file, - const int line) { - if (!integer_not_in_range_display_error(value, minimum, maximum)) { - _fail(file, line); - } +void _assert_not_in_range( + const LargestIntegralType value, const LargestIntegralType minimum, + const LargestIntegralType maximum, const char* const file, + const int line) { + if (!integer_not_in_range_display_error(value, minimum, maximum)) { + _fail(file, line); + } } -void _assert_in_set(const void* const value, const void *values[], +void _assert_in_set(const LargestIntegralType value, + const LargestIntegralType values[], const size_t number_of_values, const char* const file, const int line) { - CheckIntegerSet check_integer_set; - check_integer_set.set = values; - check_integer_set.size_of_set = number_of_values; - if (!value_in_set_display_error(value, &check_integer_set, 0)) { - _fail(file, line); - } + CheckIntegerSet check_integer_set; + check_integer_set.set = values; + check_integer_set.size_of_set = number_of_values; + if (!value_in_set_display_error(value, &check_integer_set, 0)) { + _fail(file, line); + } } -void _assert_not_in_set(const void* const value, const void *values[], +void _assert_not_in_set(const LargestIntegralType value, + const LargestIntegralType values[], const size_t number_of_values, const char* const file, const int line) { - CheckIntegerSet check_integer_set; - check_integer_set.set = values; - check_integer_set.size_of_set = number_of_values; - if (!value_in_set_display_error(value, &check_integer_set, 1)) { - _fail(file, line); - } + CheckIntegerSet check_integer_set; + check_integer_set.set = values; + check_integer_set.size_of_set = number_of_values; + if (!value_in_set_display_error(value, &check_integer_set, 1)) { + _fail(file, line); + } } // Get the list of allocated blocks. static ListNode* get_allocated_blocks_list() { - // If it initialized, initialize the list of allocated blocks. - if (!global_allocated_blocks.value) { - list_initialize(&global_allocated_blocks); - global_allocated_blocks.value = (void*)1; - } - return &global_allocated_blocks; + // If it initialized, initialize the list of allocated blocks. + if (!global_allocated_blocks.value) { + list_initialize(&global_allocated_blocks); + global_allocated_blocks.value = (void*)1; + } + return &global_allocated_blocks; } // Use the real malloc in this function. #undef malloc void* _test_malloc(const size_t size, const char* file, const int line) { - char* ptr; - MallocBlockInfo *block_info; - ListNode * const block_list = get_allocated_blocks_list(); - const size_t allocate_size = size + (MALLOC_GUARD_SIZE * 2) + - sizeof(*block_info) + MALLOC_ALIGNMENT; - char* const block = (char*)malloc(allocate_size); - assert_true(block); - - // Calculate the returned address. - ptr = (char*)(((size_t)block + MALLOC_GUARD_SIZE + sizeof(*block_info) + - MALLOC_ALIGNMENT) & ~(MALLOC_ALIGNMENT - 1)); - - // Initialize the guard blocks. - memset(ptr - MALLOC_GUARD_SIZE, MALLOC_GUARD_PATTERN, MALLOC_GUARD_SIZE); - memset(ptr + size, MALLOC_GUARD_PATTERN, MALLOC_GUARD_SIZE); - memset(ptr, MALLOC_ALLOC_PATTERN, size); - - block_info = (MallocBlockInfo*)(ptr - (MALLOC_GUARD_SIZE + - sizeof(*block_info))); - set_source_location(&block_info->location, file, line); - block_info->allocated_size = allocate_size; - block_info->size = size; - block_info->block = block; - block_info->node.value = block_info; - list_add(block_list, &block_info->node); - return ptr; + char* ptr; + MallocBlockInfo *block_info; + ListNode * const block_list = get_allocated_blocks_list(); + const size_t allocate_size = size + (MALLOC_GUARD_SIZE * 2) + + sizeof(*block_info) + MALLOC_ALIGNMENT; + char* const block = (char*)malloc(allocate_size); + assert_true(block); + + // Calculate the returned address. + ptr = (char*)(((size_t)block + MALLOC_GUARD_SIZE + sizeof(*block_info) + + MALLOC_ALIGNMENT) & ~(MALLOC_ALIGNMENT - 1)); + + // Initialize the guard blocks. + memset(ptr - MALLOC_GUARD_SIZE, MALLOC_GUARD_PATTERN, MALLOC_GUARD_SIZE); + memset(ptr + size, MALLOC_GUARD_PATTERN, MALLOC_GUARD_SIZE); + memset(ptr, MALLOC_ALLOC_PATTERN, size); + + block_info = (MallocBlockInfo*)(ptr - (MALLOC_GUARD_SIZE + + sizeof(*block_info))); + set_source_location(&block_info->location, file, line); + block_info->allocated_size = allocate_size; + block_info->size = size; + block_info->block = block; + block_info->node.value = block_info; + list_add(block_list, &block_info->node); + return ptr; } #define malloc test_malloc -void* _test_calloc(const size_t number_of_elements, const size_t size, +void* _test_calloc(const size_t number_of_elements, const size_t size, const char* file, const int line) { - void* const ptr = _test_malloc(number_of_elements * size, file, line); - if (ptr) { - memset(ptr, 0, number_of_elements * size); - } - return ptr; + void* const ptr = _test_malloc(number_of_elements * size, file, line); + if (ptr) { + memset(ptr, 0, number_of_elements * size); + } + return ptr; } // Use the real free in this function. #undef free void _test_free(void* const ptr, const char* file, const int line) { - unsigned int i; - char *block = (char*)ptr; - MallocBlockInfo *block_info; - _assert_true((int)ptr, "ptr", file, line); - block_info = (MallocBlockInfo*)(block - (MALLOC_GUARD_SIZE + - sizeof(*block_info))); - // Check the guard blocks. - { - char *guards[2] = {block - MALLOC_GUARD_SIZE, - block + block_info->size}; - for (i = 0; i < ARRAY_LENGTH(guards); i++) { - unsigned int j; - char * const guard = guards[i]; - for (j = 0; j < MALLOC_GUARD_SIZE; j++) { - const char diff = guard[j] - MALLOC_GUARD_PATTERN; - if (diff) { - print_error( - "Guard block of 0x%08x size=%d allocated by " - SOURCE_LOCATION_FORMAT " at 0x%08x is corrupt\n", - (size_t)ptr, block_info->size, - block_info->location.file, block_info->location.line, - (size_t)&guard[j]); - _fail(file, line); - } - } - } - } - list_remove(&block_info->node, NULL, NULL); - - block = block_info->block; - memset(block, MALLOC_FREE_PATTERN, block_info->allocated_size); - free(block); + unsigned int i; + char *block = (char*)ptr; + MallocBlockInfo *block_info; + _assert_true((int)ptr, "ptr", file, line); + block_info = (MallocBlockInfo*)(block - (MALLOC_GUARD_SIZE + + sizeof(*block_info))); + // Check the guard blocks. + { + char *guards[2] = {block - MALLOC_GUARD_SIZE, + block + block_info->size}; + for (i = 0; i < ARRAY_LENGTH(guards); i++) { + unsigned int j; + char * const guard = guards[i]; + for (j = 0; j < MALLOC_GUARD_SIZE; j++) { + const char diff = guard[j] - MALLOC_GUARD_PATTERN; + if (diff) { + print_error( + "Guard block of 0x%08x size=%d allocated by " + SOURCE_LOCATION_FORMAT " at 0x%08x is corrupt\n", + (size_t)ptr, block_info->size, + block_info->location.file, block_info->location.line, + (size_t)&guard[j]); + _fail(file, line); + } + } + } + } + list_remove(&block_info->node, NULL, NULL); + + block = block_info->block; + memset(block, MALLOC_FREE_PATTERN, block_info->allocated_size); + free(block); } #define free test_free // Crudely checkpoint the current heap state. static const ListNode* check_point_allocated_blocks() { - return get_allocated_blocks_list()->prev; + return get_allocated_blocks_list()->prev; } /* Display the blocks allocated after the specified check point. This * function returns the number of blocks displayed. */ static int display_allocated_blocks(const ListNode * const check_point) { - const ListNode * const head = get_allocated_blocks_list(); - const ListNode *node; - int allocated_blocks = 0; - assert_true(check_point); - assert_true(check_point->next); + const ListNode * const head = get_allocated_blocks_list(); + const ListNode *node; + int allocated_blocks = 0; + assert_true(check_point); + assert_true(check_point->next); - for (node = check_point->next; node != head; node = node->next) { - const MallocBlockInfo * const block_info = node->value; - assert_true(block_info); + for (node = check_point->next; node != head; node = node->next) { + const MallocBlockInfo * const block_info = node->value; + assert_true(block_info); - if (!allocated_blocks) { - print_error("Blocks allocated...\n"); - } - print_error(" 0x%08x : " SOURCE_LOCATION_FORMAT "\n", - block_info->block, block_info->location.file, - block_info->location.line); - allocated_blocks ++; - } - return allocated_blocks; + if (!allocated_blocks) { + print_error("Blocks allocated...\n"); + } + print_error(" 0x%08x : " SOURCE_LOCATION_FORMAT "\n", + block_info->block, block_info->location.file, + block_info->location.line); + allocated_blocks ++; + } + return allocated_blocks; } // Free all blocks allocated after the specified check point. static void free_allocated_blocks(const ListNode * const check_point) { - const ListNode * const head = get_allocated_blocks_list(); - const ListNode *node; - assert_true(check_point); + const ListNode * const head = get_allocated_blocks_list(); + const ListNode *node; + assert_true(check_point); - node = check_point->next; - assert_true(node); + node = check_point->next; + assert_true(node); - while (node != head) { - MallocBlockInfo * const block_info = (MallocBlockInfo*)node->value; - node = node->next; - free((char*)block_info + sizeof(*block_info) + MALLOC_GUARD_SIZE); - } + while (node != head) { + MallocBlockInfo * const block_info = (MallocBlockInfo*)node->value; + node = node->next; + free((char*)block_info + sizeof(*block_info) + MALLOC_GUARD_SIZE); + } } // Fail if any any blocks are allocated after the specified check point. static void fail_if_blocks_allocated(const ListNode * const check_point, const char * const test_name) { - const int allocated_blocks = display_allocated_blocks(check_point); - if (allocated_blocks) { - free_allocated_blocks(check_point); - print_error("ERROR: %s leaked %d block(s)\n", test_name, - allocated_blocks); - exit_test(1); - } + const int allocated_blocks = display_allocated_blocks(check_point); + if (allocated_blocks) { + free_allocated_blocks(check_point); + print_error("ERROR: %s leaked %d block(s)\n", test_name, + allocated_blocks); + exit_test(1); + } } void _fail(const char * const file, const int line) { - print_error("ERROR: " SOURCE_LOCATION_FORMAT " Failure!\n", file, line); - exit_test(1); + print_error("ERROR: " SOURCE_LOCATION_FORMAT " Failure!\n", file, line); + exit_test(1); } #ifndef _WIN32 static void exception_handler(int sig) { - print_error("%s\n", strsignal(sig)); - exit_test(1); + print_error("%s\n", strsignal(sig)); + exit_test(1); } #else // _WIN32 static LONG WINAPI exception_filter(EXCEPTION_POINTERS *exception_pointers) { - EXCEPTION_RECORD * const exception_record = - exception_pointers->ExceptionRecord; - const DWORD code = exception_record->ExceptionCode; - unsigned int i; - for (i = 0; i < ARRAY_LENGTH(exception_codes); i++) { - const ExceptionCodeInfo * const code_info = &exception_codes[i]; - if (code == code_info->code) { - static int shown_debug_message = 0; - fflush(stdout); - print_error("%s occurred at 0x%08x.\n", code_info->description, - exception_record->ExceptionAddress); - if (!shown_debug_message) { - print_error( - "\n" - "To debug in Visual Studio...\n" - "1. Select menu item File->Open Project\n" - "2. Change 'Files of type' to 'Executable Files'\n" - "3. Open this executable.\n" - "4. Select menu item Debug->Start\n" - "\n" - "Alternatively, set the environment variable \n" - "UNIT_TESTING_DEBUG to 1 and rebuild this executable, \n" - "then click 'Debug' in the popup dialog box.\n" - "\n"); - shown_debug_message = 1; - } - exit_test(0); - return EXCEPTION_EXECUTE_HANDLER; - } - } - return EXCEPTION_CONTINUE_SEARCH; + EXCEPTION_RECORD * const exception_record = + exception_pointers->ExceptionRecord; + const DWORD code = exception_record->ExceptionCode; + unsigned int i; + for (i = 0; i < ARRAY_LENGTH(exception_codes); i++) { + const ExceptionCodeInfo * const code_info = &exception_codes[i]; + if (code == code_info->code) { + static int shown_debug_message = 0; + fflush(stdout); + print_error("%s occurred at 0x%08x.\n", code_info->description, + exception_record->ExceptionAddress); + if (!shown_debug_message) { + print_error( + "\n" + "To debug in Visual Studio...\n" + "1. Select menu item File->Open Project\n" + "2. Change 'Files of type' to 'Executable Files'\n" + "3. Open this executable.\n" + "4. Select menu item Debug->Start\n" + "\n" + "Alternatively, set the environment variable \n" + "UNIT_TESTING_DEBUG to 1 and rebuild this executable, \n" + "then click 'Debug' in the popup dialog box.\n" + "\n"); + shown_debug_message = 1; + } + exit_test(0); + return EXCEPTION_EXECUTE_HANDLER; + } + } + return EXCEPTION_CONTINUE_SEARCH; } #endif // !_WIN32 // Standard output and error print methods. void vprint_message(const char* const format, va_list args) { - char buffer[1024]; - vsnprintf(buffer, sizeof(buffer), format, args); - printf(buffer); + char buffer[1024]; + vsnprintf(buffer, sizeof(buffer), format, args); + printf(buffer); #ifdef _WIN32 - OutputDebugString(buffer); + OutputDebugString(buffer); #endif // _WIN32 } void vprint_error(const char* const format, va_list args) { - char buffer[1024]; - vsnprintf(buffer, sizeof(buffer), format, args); - fprintf(stderr, buffer); + char buffer[1024]; + vsnprintf(buffer, sizeof(buffer), format, args); + fprintf(stderr, buffer); #ifdef _WIN32 - OutputDebugString(buffer); + OutputDebugString(buffer); #endif // _WIN32 } void print_message(const char* const format, ...) { - va_list args; - va_start(args, format); - vprint_message(format, args); - va_end(args); + va_list args; + va_start(args, format); + vprint_message(format, args); + va_end(args); } void print_error(const char* const format, ...) { - va_list args; - va_start(args, format); - vprint_error(format, args); - va_end(args); + va_list args; + va_start(args, format); + vprint_error(format, args); + va_end(args); } int _run_test( - const char * const function_name, const UnitTestFunction Function, + const char * const function_name, const UnitTestFunction Function, void ** const state, const UnitTestFunctionType function_type, const void* const heap_check_point) { - const ListNode * const check_point = heap_check_point ? - heap_check_point : check_point_allocated_blocks(); - void *current_state = NULL; - int rc = 1; - int handle_exceptions = 1; + const ListNode * const check_point = heap_check_point ? + heap_check_point : check_point_allocated_blocks(); + void *current_state = NULL; + int rc = 1; + int handle_exceptions = 1; #ifdef _WIN32 - handle_exceptions = !IsDebuggerPresent(); + handle_exceptions = !IsDebuggerPresent(); #endif // _WIN32 #if UNIT_TESTING_DEBUG - handle_exceptions = 0; + handle_exceptions = 0; #endif // UNIT_TESTING_DEBUG - if (handle_exceptions) { + if (handle_exceptions) { #ifndef _WIN32 - unsigned int i; - for (i = 0; i < ARRAY_LENGTH(exception_signals); i++) { - default_signal_functions[i] = signal( - exception_signals[i], exception_handler); - } + unsigned int i; + for (i = 0; i < ARRAY_LENGTH(exception_signals); i++) { + default_signal_functions[i] = signal( + exception_signals[i], exception_handler); + } #else // _WIN32 - previous_exception_filter = SetUnhandledExceptionFilter( - exception_filter); + previous_exception_filter = SetUnhandledExceptionFilter( + exception_filter); #endif // !_WIN32 - } - - if (function_type == UNIT_TEST_FUNCTION_TYPE_TEST) { - print_message("%s: Starting test\n", function_name); - } - initialize_testing(function_name); - global_running_test = 1; - if (setjmp(global_run_test_env) == 0) { - Function(state ? state : ¤t_state); - fail_if_leftover_values(function_name); - - /* If this is a setup function then ignore any allocated blocks - * only ensure they're deallocated on tear down. */ - if (function_type != UNIT_TEST_FUNCTION_TYPE_SETUP) { - fail_if_blocks_allocated(check_point, function_name); - } - - global_running_test = 0; - - if (function_type == UNIT_TEST_FUNCTION_TYPE_TEST) { - print_message("%s: Test completed successfully.\n", function_name); - } - rc = 0; - } else { - global_running_test = 0; - print_message("%s: Test failed.\n", function_name); - } - teardown_testing(function_name); - - if (handle_exceptions) { + } + + if (function_type == UNIT_TEST_FUNCTION_TYPE_TEST) { + print_message("%s: Starting test\n", function_name); + } + initialize_testing(function_name); + global_running_test = 1; + if (setjmp(global_run_test_env) == 0) { + Function(state ? state : ¤t_state); + fail_if_leftover_values(function_name); + + /* If this is a setup function then ignore any allocated blocks + * only ensure they're deallocated on tear down. */ + if (function_type != UNIT_TEST_FUNCTION_TYPE_SETUP) { + fail_if_blocks_allocated(check_point, function_name); + } + + global_running_test = 0; + + if (function_type == UNIT_TEST_FUNCTION_TYPE_TEST) { + print_message("%s: Test completed successfully.\n", function_name); + } + rc = 0; + } else { + global_running_test = 0; + print_message("%s: Test failed.\n", function_name); + } + teardown_testing(function_name); + + if (handle_exceptions) { #ifndef _WIN32 - unsigned int i; - for (i = 0; i < ARRAY_LENGTH(exception_signals); i++) { - signal(exception_signals[i], default_signal_functions[i]); - } + unsigned int i; + for (i = 0; i < ARRAY_LENGTH(exception_signals); i++) { + signal(exception_signals[i], default_signal_functions[i]); + } #else // _WIN32 - if (previous_exception_filter) { - SetUnhandledExceptionFilter(previous_exception_filter); - previous_exception_filter = NULL; - } + if (previous_exception_filter) { + SetUnhandledExceptionFilter(previous_exception_filter); + previous_exception_filter = NULL; + } #endif // !_WIN32 - } + } - return rc; + return rc; } int _run_tests(const UnitTest * const tests, const size_t number_of_tests) { - // Whether to execute the next test. - int run_next_test = 1; - // Whether the previous test failed. - int previous_test_failed = 0; - // Check point of the heap state. - const ListNode * const check_point = check_point_allocated_blocks(); - // Current test being executed. - size_t current_test = 0; - // Number of tests executed. - size_t tests_executed = 0; - // Number of failed tests. - size_t total_failed = 0; - // Number of setup functions. - size_t setups = 0; - // Number of teardown functions. - size_t teardowns = 0; - /* A stack of test states. A state is pushed on the stack - * when a test setup occurs and popped on tear down. */ - TestState* test_states = malloc(number_of_tests * sizeof(*test_states)); - size_t number_of_test_states = 0; - // Names of the tests that failed. - const char** failed_names = malloc(number_of_tests * - sizeof(*failed_names)); - void **current_state = NULL; - - while (current_test < number_of_tests) { - const ListNode *test_check_point = NULL; - TestState *current_TestState; - const UnitTest * const test = &tests[current_test++]; - if (!test->function) { - continue; - } - - switch (test->function_type) { - case UNIT_TEST_FUNCTION_TYPE_TEST: - run_next_test = 1; - break; - case UNIT_TEST_FUNCTION_TYPE_SETUP: { - // Checkpoint the heap before the setup. - current_TestState = &test_states[number_of_test_states++]; - current_TestState->check_point = check_point_allocated_blocks(); - test_check_point = current_TestState->check_point; - current_state = ¤t_TestState->state; - *current_state = NULL; - run_next_test = 1; - setups ++; - break; - } - case UNIT_TEST_FUNCTION_TYPE_TEARDOWN: - // Check the heap based on the last setup checkpoint. - assert_true(number_of_test_states); - current_TestState = &test_states[--number_of_test_states]; - test_check_point = current_TestState->check_point; - current_state = ¤t_TestState->state; - teardowns ++; - break; - default: - print_error("Invalid unit test function type %d\n", - test->function_type); - exit_test(1); - break; - } - - if (run_next_test) { - int failed = _run_test(test->name, test->function, current_state, - test->function_type, test_check_point); - if (failed) { - failed_names[total_failed] = test->name; - } - - switch (test->function_type) { - case UNIT_TEST_FUNCTION_TYPE_TEST: - previous_test_failed = failed; - total_failed += failed; - tests_executed ++; - break; - - case UNIT_TEST_FUNCTION_TYPE_SETUP: - if (failed) { - total_failed ++; - tests_executed ++; - // Skip forward until the next test or setup function. - run_next_test = 0; - } - previous_test_failed = 0; - break; - - case UNIT_TEST_FUNCTION_TYPE_TEARDOWN: - // If this test failed. - if (failed && !previous_test_failed) { - total_failed ++; - } - break; - default: - assert_false("BUG: shouldn't be here!"); - break; - } - } - } - - if (total_failed) { - size_t i; - print_error("%d out of %d tests failed!\n", total_failed, - tests_executed); - for (i = 0; i < total_failed; i++) { - print_error(" %s\n", failed_names[i]); - } - } else { - print_message("All %d tests passed\n", tests_executed); - } - - if (number_of_test_states) { - print_error("Mismatched number of setup %d and teardown %d " - "functions\n", setups, teardowns); - total_failed = -1; - } - - free(test_states); - free((void*)failed_names); - - fail_if_blocks_allocated(check_point, "run_tests"); - return (int)total_failed; + // Whether to execute the next test. + int run_next_test = 1; + // Whether the previous test failed. + int previous_test_failed = 0; + // Check point of the heap state. + const ListNode * const check_point = check_point_allocated_blocks(); + // Current test being executed. + size_t current_test = 0; + // Number of tests executed. + size_t tests_executed = 0; + // Number of failed tests. + size_t total_failed = 0; + // Number of setup functions. + size_t setups = 0; + // Number of teardown functions. + size_t teardowns = 0; + /* A stack of test states. A state is pushed on the stack + * when a test setup occurs and popped on tear down. */ + TestState* test_states = malloc(number_of_tests * sizeof(*test_states)); + size_t number_of_test_states = 0; + // Names of the tests that failed. + const char** failed_names = malloc(number_of_tests * + sizeof(*failed_names)); + void **current_state = NULL; + // Make sure LargestIntegralType is at least the size of a pointer. + assert_true(sizeof(LargestIntegralType) >= sizeof(void*)); + + while (current_test < number_of_tests) { + const ListNode *test_check_point = NULL; + TestState *current_TestState; + const UnitTest * const test = &tests[current_test++]; + if (!test->function) { + continue; + } + + switch (test->function_type) { + case UNIT_TEST_FUNCTION_TYPE_TEST: + run_next_test = 1; + break; + case UNIT_TEST_FUNCTION_TYPE_SETUP: { + // Checkpoint the heap before the setup. + current_TestState = &test_states[number_of_test_states++]; + current_TestState->check_point = check_point_allocated_blocks(); + test_check_point = current_TestState->check_point; + current_state = ¤t_TestState->state; + *current_state = NULL; + run_next_test = 1; + setups ++; + break; + } + case UNIT_TEST_FUNCTION_TYPE_TEARDOWN: + // Check the heap based on the last setup checkpoint. + assert_true(number_of_test_states); + current_TestState = &test_states[--number_of_test_states]; + test_check_point = current_TestState->check_point; + current_state = ¤t_TestState->state; + teardowns ++; + break; + default: + print_error("Invalid unit test function type %d\n", + test->function_type); + exit_test(1); + break; + } + + if (run_next_test) { + int failed = _run_test(test->name, test->function, current_state, + test->function_type, test_check_point); + if (failed) { + failed_names[total_failed] = test->name; + } + + switch (test->function_type) { + case UNIT_TEST_FUNCTION_TYPE_TEST: + previous_test_failed = failed; + total_failed += failed; + tests_executed ++; + break; + + case UNIT_TEST_FUNCTION_TYPE_SETUP: + if (failed) { + total_failed ++; + tests_executed ++; + // Skip forward until the next test or setup function. + run_next_test = 0; + } + previous_test_failed = 0; + break; + + case UNIT_TEST_FUNCTION_TYPE_TEARDOWN: + // If this test failed. + if (failed && !previous_test_failed) { + total_failed ++; + } + break; + default: + assert_false("BUG: shouldn't be here!"); + break; + } + } + } + + if (total_failed) { + size_t i; + print_error("%d out of %d tests failed!\n", total_failed, + tests_executed); + for (i = 0; i < total_failed; i++) { + print_error(" %s\n", failed_names[i]); + } + } else { + print_message("All %d tests passed\n", tests_executed); + } + + if (number_of_test_states) { + print_error("Mismatched number of setup %d and teardown %d " + "functions\n", setups, teardowns); + total_failed = -1; + } + + free(test_states); + free((void*)failed_names); + + fail_if_blocks_allocated(check_point, "run_tests"); + return (int)total_failed; } diff --git a/src/example/calculator_test.c b/src/example/calculator_test.c index 6feaf41..7f68732 100644 --- a/src/example/calculator_test.c +++ b/src/example/calculator_test.c @@ -4,9 +4,9 @@ * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at - * + * * http://www.apache.org/licenses/LICENSE-2.0 - * + * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. @@ -26,8 +26,8 @@ #define array_length(x) (sizeof(x) / sizeof((x)[0])) -/* To simplify this code, these functions and data structures could have been - * separated out from the application example.c into a header shared with +/* To simplify this code, these functions and data structures could have been + * separated out from the application example.c into a header shared with * test application. However, this example illustrates how it's possible to * test existing code with little modification. */ @@ -48,13 +48,13 @@ extern BinaryOperator find_operator_function_by_string( const char* const operator_string); extern int perform_operation( int number_of_arguments, char *arguments[], - const size_t number_of_operator_functions, + const size_t number_of_operator_functions, const OperatorFunction * const operator_functions, int * const number_of_intermediate_values, int ** const intermediate_values, int * const error_occurred); extern int example_main(int argc, char *argv[]); -/* A mock fprintf function that checks the value of strings printed to the +/* A mock fprintf function that checks the value of strings printed to the * standard error stream. */ int example_test_fprintf(FILE* const file, const char *format, ...) { int return_value; @@ -69,7 +69,7 @@ int example_test_fprintf(FILE* const file, const char *format, ...) { return return_value; } -/* A mock printf function that checks the value of strings printed to the +/* A mock printf function that checks the value of strings printed to the * standard output stream. */ int example_test_printf(const char *format, ...) { int return_value; @@ -120,13 +120,13 @@ void test_divide_by_zero(void **state) { expect_assert_failure(divide(100, 0)); } -/* Ensure find_operator_function_by_string() asserts when a NULL pointer is +/* Ensure find_operator_function_by_string() asserts when a NULL pointer is * specified as the table to search. */ void test_find_operator_function_by_string_null_functions(void **state) { expect_assert_failure(find_operator_function_by_string(1, NULL, "test")); } -/* Ensure find_operator_function_by_string() asserts when a NULL pointer is +/* Ensure find_operator_function_by_string() asserts when a NULL pointer is * specified as the string to search for. */ void test_find_operator_function_by_string_null_string(void **state) { const OperatorFunction operator_functions[] = { @@ -136,11 +136,10 @@ void test_find_operator_function_by_string_null_string(void **state) { array_length(operator_functions), operator_functions, NULL)); } -/* Ensure find_operator_function_by_string() returns NULL when a NULL pointer +/* Ensure find_operator_function_by_string() returns NULL when a NULL pointer * is specified as the table to search when the table size is 0. */ void test_find_operator_function_by_string_valid_null_functions(void **state) { - assert_int_equal((int)find_operator_function_by_string(0, NULL, "test"), - (int)NULL); + assert_int_equal(find_operator_function_by_string(0, NULL, "test"), NULL); } /* Ensure find_operator_function_by_string() returns NULL when searching for @@ -151,9 +150,9 @@ void test_find_operator_function_by_string_not_found(void **state) { {"-", binary_operator}, {"/", binary_operator}, }; - assert_int_equal((int)find_operator_function_by_string( + assert_int_equal(find_operator_function_by_string( array_length(operator_functions), operator_functions, "test"), - (int)NULL); + NULL); } /* Ensure find_operator_function_by_string() returns the correct function when @@ -164,7 +163,7 @@ void test_find_operator_function_by_string_found(void **state) { {"-", (BinaryOperator)0xDEADBEEF}, {"/", (BinaryOperator)0xABADCAFE}, }; - assert_int_equal((int)find_operator_function_by_string( + assert_int_equal(find_operator_function_by_string( array_length(operator_functions), operator_functions, "-"), 0xDEADBEEF); } @@ -179,11 +178,11 @@ void test_perform_operation_null_args(void **state) { int error_occurred; expect_assert_failure(perform_operation( 1, NULL, array_length(operator_functions), operator_functions, - &number_of_intermediate_values, &intermediate_values, + &number_of_intermediate_values, &intermediate_values, &error_occurred)); } -/* Ensure perform_operation() asserts when a NULL operator_functions array is +/* Ensure perform_operation() asserts when a NULL operator_functions array is * specified. */ void test_perform_operation_null_operator_functions(void **state) { char *args[] = { @@ -193,11 +192,11 @@ void test_perform_operation_null_operator_functions(void **state) { int *intermediate_values; int error_occurred; expect_assert_failure(perform_operation( - array_length(args), args, 1, NULL, &number_of_intermediate_values, + array_length(args), args, 1, NULL, &number_of_intermediate_values, &intermediate_values, &error_occurred)); } -/* Ensure perform_operation() asserts when a NULL pointer is specified for +/* Ensure perform_operation() asserts when a NULL pointer is specified for * number_of_intermediate_values. */ void test_perform_operation_null_number_of_intermediate_values(void **state) { const OperatorFunction operator_functions[] = { @@ -207,13 +206,13 @@ void test_perform_operation_null_number_of_intermediate_values(void **state) { "1", "+", "2", "*", "4" }; int *intermediate_values; - int error_occurred; + int error_occurred; expect_assert_failure(perform_operation( - array_length(args), args, 1, operator_functions, NULL, + array_length(args), args, 1, operator_functions, NULL, &intermediate_values, &error_occurred)); } -/* Ensure perform_operation() asserts when a NULL pointer is specified for +/* Ensure perform_operation() asserts when a NULL pointer is specified for * intermediate_values. */ void test_perform_operation_null_intermediate_values(void **state) { const OperatorFunction operator_functions[] = { @@ -223,7 +222,7 @@ void test_perform_operation_null_intermediate_values(void **state) { "1", "+", "2", "*", "4" }; int number_of_intermediate_values; - int error_occurred; + int error_occurred; expect_assert_failure(perform_operation( array_length(args), args, array_length(operator_functions), operator_functions, &number_of_intermediate_values, NULL, @@ -254,7 +253,7 @@ void test_perform_operation_first_arg_not_integer(void **state) { int *intermediate_values; int error_occurred; - expect_string(example_test_fprintf, temporary_buffer, + expect_string(example_test_fprintf, temporary_buffer, "Unable to parse integer from argument test\n"); assert_int_equal(perform_operation( @@ -264,7 +263,7 @@ void test_perform_operation_first_arg_not_integer(void **state) { assert_int_equal(error_occurred, 1); } -/* Ensure perform_operation() returns an error when parsing an unknown +/* Ensure perform_operation() returns an error when parsing an unknown * operator. */ void test_perform_operation_unknown_operator(void **state) { const OperatorFunction operator_functions[] = { @@ -277,7 +276,7 @@ void test_perform_operation_unknown_operator(void **state) { int *intermediate_values; int error_occurred; - expect_string(example_test_fprintf, temporary_buffer, + expect_string(example_test_fprintf, temporary_buffer, "Unknown operator *, argument 1\n"); assert_int_equal(perform_operation( @@ -287,20 +286,20 @@ void test_perform_operation_unknown_operator(void **state) { assert_int_equal(error_occurred, 1); } -/* Ensure perform_operation() returns an error when nothing follows an +/* Ensure perform_operation() returns an error when nothing follows an * operator. */ void test_perform_operation_missing_argument(void **state) { const OperatorFunction operator_functions[] = { {"+", binary_operator}, }; char *args[] = { - "1", "+", + "1", "+", }; int number_of_intermediate_values; int *intermediate_values; int error_occurred; - expect_string(example_test_fprintf, temporary_buffer, + expect_string(example_test_fprintf, temporary_buffer, "Binary operator + missing argument\n"); assert_int_equal(perform_operation( @@ -323,14 +322,14 @@ void test_perform_operation_no_integer_after_operator(void **state) { int *intermediate_values; int error_occurred; - expect_string(example_test_fprintf, temporary_buffer, + expect_string(example_test_fprintf, temporary_buffer, "Unable to parse integer test of argument 2\n"); assert_int_equal(perform_operation( array_length(args), args, array_length(operator_functions), operator_functions, &number_of_intermediate_values, &intermediate_values, &error_occurred), 0); - assert_int_equal(error_occurred, 1); + assert_int_equal(error_occurred, 1); } diff --git a/src/example/customer_database_test.c b/src/example/customer_database_test.c index b059007..202037e 100644 --- a/src/example/customer_database_test.c +++ b/src/example/customer_database_test.c @@ -4,9 +4,9 @@ * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at - * + * * http://www.apache.org/licenses/LICENSE-2.0 - * + * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. @@ -27,14 +27,14 @@ extern unsigned int get_customer_id_by_name( unsigned int mock_query_database( DatabaseConnection* const connection, const char * const query_string, void *** const results) { - *results = (void**)mock(); + *results = (void**)((unsigned)mock()); return (unsigned int)mock(); } // Mock of the connect to database function. DatabaseConnection* connect_to_database(const char * const database_url, const unsigned int port) { - return (DatabaseConnection*)mock(); + return (DatabaseConnection*)((unsigned)mock()); } void test_connect_to_customer_database(void **state) { diff --git a/src/example/product_database_test.c b/src/example/product_database_test.c index d3c5109..e198516 100644 --- a/src/example/product_database_test.c +++ b/src/example/product_database_test.c @@ -4,9 +4,9 @@ * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at - * + * * http://www.apache.org/licenses/LICENSE-2.0 - * + * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. @@ -28,7 +28,7 @@ DatabaseConnection* connect_to_database(const char * const url, const unsigned int port) { check_expected(url); check_expected(port); - return (DatabaseConnection*)mock(); + return (DatabaseConnection*)((unsigned)mock()); } void test_connect_to_product_database(void **state) { diff --git a/src/google/cmockery.h b/src/google/cmockery.h index 827d3c4..ec47e58 100755 --- a/src/google/cmockery.h +++ b/src/google/cmockery.h @@ -4,9 +4,9 @@ * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at - * + * * http://www.apache.org/licenses/LICENSE-2.0 - * + * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. @@ -22,8 +22,8 @@ * #include * #include * #include - * - * This allows test applications to use custom definitions of C standard + * + * This allows test applications to use custom definitions of C standard * library functions and types. */ @@ -32,6 +32,21 @@ #define __func__ __FUNCTION__ #endif +/* Largest integral type. This type should be large enough to hold any + * pointer or integer supported by the compiler. */ +#ifndef LargestIntegralType +#define LargestIntegralType unsigned long long +#endif // LargestIntegralType + +// Printf format used to display LargestIntegralType. +#ifndef LargestIntegralTypePrintfFormat +#define LargestIntegralTypePrintfFormat "%lx" +#endif // LargestIntegralTypePrintfFormat + +// Perform an unsigned cast to LargestIntegralType. +#define cast_to_largest_integral_type(value) \ + ((LargestIntegralType)((unsigned)(value))) + // Retrieves a return value for the current function. #define mock() _mock(__func__, __FILE__, __LINE__) @@ -40,9 +55,11 @@ * by mock(). If count is set to -1 the value will always be returned. */ #define will_return(function, value) \ - _will_return(#function, __FILE__, __LINE__, (void*)value, 1) + _will_return(#function, __FILE__, __LINE__, \ + cast_to_largest_integral_type(value), 1) #define will_return_count(function, value, count) \ - _will_return(#function, __FILE__, __LINE__, (void*)value, count) + _will_return(#function, __FILE__, __LINE__, \ + cast_to_largest_integral_type(value), count) /* Add a custom parameter checking function. If the event parameter is NULL * the event structure is allocated internally by this function. If event @@ -50,105 +67,106 @@ * be deallocated by the caller. */ #define expect_check(function, parameter, check_function, check_data) \ - _expect_check(#function, #parameter, __FILE__, __LINE__, check_function, \ - check_data) + _expect_check(#function, #parameter, __FILE__, __LINE__, check_function, \ + cast_to_largest_integral_type(check_data), NULL, 0) -/* Add an event to check a parameter, using check_expected(), against a set of +/* Add an event to check a parameter, using check_expected(), against a set of * values. See will_return() for a description of the count parameter. */ #define expect_in_set(function, parameter, value_array) \ - expect_in_set_count(function, parameter, value_array, 1) + expect_in_set_count(function, parameter, value_array, 1) #define expect_in_set_count(function, parameter, value_array, count) \ - _expect_in_set(#function, #parameter, __FILE__, __LINE__, value_array, \ - sizeof(value_array) / sizeof(value_array[0]), count) + _expect_in_set(#function, #parameter, __FILE__, __LINE__, value_array, \ + sizeof(value_array) / sizeof((value_array)[0]), count) #define expect_not_in_set(function, parameter, value_array) \ - expect_not_in_set_count(function, parameter, value_array, 1) + expect_not_in_set_count(function, parameter, value_array, 1) #define expect_not_in_set_count(function, parameter, value_array, count) \ - _expect_not_in_set( \ - #function, #parameter, __FILE__, __LINE__, value_array, \ - sizeof(value_array) / sizeof(value_array[0]), count) + _expect_not_in_set( \ + #function, #parameter, __FILE__, __LINE__, value_array, \ + sizeof(value_array) / sizeof((value_array)[0]), count) -/* Add an event to check a parameter, using check_expected(), against a - * signed range. Where range is minimum <= value <= maximum. - * See will_return() for a description of the count parameter. +/* Add an event to check a parameter, using check_expected(), against a + * signed range. Where range is minimum <= value <= maximum. + * See will_return() for a description of the count parameter. */ #define expect_in_range(function, parameter, minimum, maximum) \ - expect_in_range_count(function, parameter, minimum, maximum, 1) + expect_in_range_count(function, parameter, minimum, maximum, 1) #define expect_in_range_count(function, parameter, minimum, maximum, count) \ - _expect_in_range(#function, #parameter, __FILE__, __LINE__, minimum, \ - maximum, count) + _expect_in_range(#function, #parameter, __FILE__, __LINE__, minimum, \ + maximum, count) -/* Add an event to check a parameter, using check_expected(), against a - * signed range. Where range is value < minimum or value > maximum. - * See will_return() for a description of the count parameter. +/* Add an event to check a parameter, using check_expected(), against a + * signed range. Where range is value < minimum or value > maximum. + * See will_return() for a description of the count parameter. */ #define expect_not_in_range(function, parameter, minimum, maximum) \ - expect_not_in_range_count(function, parameter, minimum, maximum, 1) + expect_not_in_range_count(function, parameter, minimum, maximum, 1) #define expect_not_in_range_count(function, parameter, minimum, maximum, \ count) \ - _expect_not_in_range(#function, #parameter, __FILE__, __LINE__, \ - minimum, maximum, count) + _expect_not_in_range(#function, #parameter, __FILE__, __LINE__, \ + minimum, maximum, count) -/* Add an event to check whether a parameter, using check_expected(), is or - * isn't a value. See will_return() for a description of the count parameter. +/* Add an event to check whether a parameter, using check_expected(), is or + * isn't a value. See will_return() for a description of the count parameter. */ #define expect_value(function, parameter, value) \ - expect_value_count(function, parameter, value, 1) + expect_value_count(function, parameter, value, 1) #define expect_value_count(function, parameter, value, count) \ - _expect_value(#function, #parameter, __FILE__, __LINE__, (void*)value, \ - count) + _expect_value(#function, #parameter, __FILE__, __LINE__, \ + cast_to_largest_integral_type(value), count) #define expect_not_value(function, parameter, value) \ - expect_not_value_count(function, parameter, value, 1) + expect_not_value_count(function, parameter, value, 1) #define expect_not_value_count(function, parameter, value, count) \ - _expect_not_value(#function, #parameter, __FILE__, __LINE__, \ - (void*)value, count) + _expect_not_value(#function, #parameter, __FILE__, __LINE__, \ + cast_to_largest_integral_type(value), count) -/* Add an event to check whether a parameter, using check_expected(), - * is or isn't a string. See will_return() for a description of the count - * parameter. +/* Add an event to check whether a parameter, using check_expected(), + * is or isn't a string. See will_return() for a description of the count + * parameter. */ #define expect_string(function, parameter, string) \ - expect_string_count(function, parameter, string, 1) + expect_string_count(function, parameter, string, 1) #define expect_string_count(function, parameter, string, count) \ - _expect_string(#function, #parameter, __FILE__, __LINE__, (void*)string, \ - count) + _expect_string(#function, #parameter, __FILE__, __LINE__, \ + (const char*)(string), count) #define expect_not_string(function, parameter, string) \ - expect_not_string_count(function, parameter, string, 1) + expect_not_string_count(function, parameter, string, 1) #define expect_not_string_count(function, parameter, string, count) \ - _expect_not_string(#function, #parameter, __FILE__, __LINE__, \ - (void*)string, count) + _expect_not_string(#function, #parameter, __FILE__, __LINE__, \ + (const char*)(string), count) -/* Add an event to check whether a parameter, using check_expected() does or - * doesn't match an area of memory. See will_return() for a description of - * the count parameter. +/* Add an event to check whether a parameter, using check_expected() does or + * doesn't match an area of memory. See will_return() for a description of + * the count parameter. */ #define expect_memory(function, parameter, memory, size) \ - expect_memory_count(function, parameter, memory, size, 1) -#define expect_memory_count(function, parameter, memory, size, count) \ - _expect_memory(#function, #parameter, __FILE__, __LINE__, (void*)memory, \ - size, count) + expect_memory_count(function, parameter, memory, size, 1) +#define expect_memory_count(function, parameter, memory, size, count) \ + _expect_memory(#function, #parameter, __FILE__, __LINE__, \ + (const void*)(memory), size, count) #define expect_not_memory(function, parameter, memory, size) \ - expect_not_memory_count(function, parameter, memory, size, 1) + expect_not_memory_count(function, parameter, memory, size, 1) #define expect_not_memory_count(function, parameter, memory, size, count) \ - _expect_not_memory(#function, #parameter, __FILE__, __LINE__, \ - (void*)memory, size, count) + _expect_not_memory(#function, #parameter, __FILE__, __LINE__, \ + (const void*)(memory), size, count) -/* Add an event to allow any value for a parameter checked using - * check_expected(). See will_return() for a description of the count - * parameter. +/* Add an event to allow any value for a parameter checked using + * check_expected(). See will_return() for a description of the count + * parameter. */ #define expect_any(function, parameter) \ - expect_any_count(function, parameter, 1) + expect_any_count(function, parameter, 1) #define expect_any_count(function, parameter, count) \ - _expect_any(#function, #parameter, __FILE__, __LINE__, count) + _expect_any(#function, #parameter, __FILE__, __LINE__, count) /* Determine whether a function parameter is correct. This ensures the next * value queued by one of the expect_*() macros matches the specified variable. */ #define check_expected(parameter) \ - _check_expected(__func__, #parameter, __FILE__, __LINE__, (void*)parameter) + _check_expected(__func__, #parameter, __FILE__, __LINE__, \ + cast_to_largest_integral_type(parameter)) // Assert that the given expression is true. #define assert_true(c) _assert_true((int)(c), #c, __FILE__, __LINE__) @@ -156,43 +174,54 @@ #define assert_false(c) _assert_true(!((int)(c)), #c, __FILE__, __LINE__) // Assert that the two given integers are equal, otherwise fail. -#define assert_int_equal(a, b) _assert_int_equal(a, b, __FILE__, __LINE__) +#define assert_int_equal(a, b) \ + _assert_int_equal(cast_to_largest_integral_type(a), \ + cast_to_largest_integral_type(b), \ + __FILE__, __LINE__) // Assert that the two given integers are not equal, otherwise fail. #define assert_int_not_equal(a, b) \ - _assert_int_not_equal(a, b, __FILE__, __LINE__) + _assert_int_not_equal(cast_to_largest_integral_type(a), \ + cast_to_largest_integral_type(b), \ + __FILE__, __LINE__) // Assert that the two given strings are equal, otherwise fail. #define assert_string_equal(a, b) \ - _assert_string_equal((const char*)a, (const char*)b, __FILE__, __LINE__) + _assert_string_equal((const char*)(a), (const char*)(b), __FILE__, \ + __LINE__) // Assert that the two given strings are not equal, otherwise fail. #define assert_string_not_equal(a, b) \ - _assert_string_not_equal((const char*)a, (const char*)b, __FILE__, \ - __LINE__) + _assert_string_not_equal((const char*)(a), (const char*)(b), __FILE__, \ + __LINE__) // Assert that the two given areas of memory are equal, otherwise fail. #define assert_memory_equal(a, b, size) \ - _assert_memory_equal((const char*)a, (const char*)b, size, __FILE__, \ - __LINE__) + _assert_memory_equal((const char*)(a), (const char*)(b), size, __FILE__, \ + __LINE__) // Assert that the two given areas of memory are not equal, otherwise fail. #define assert_memory_not_equal(a, b, size) \ - _assert_memory_not_equal((const char*)a, (const char*)b, size, __FILE__, \ - __LINE__) + _assert_memory_not_equal((const char*)(a), (const char*)(b), size, \ + __FILE__, __LINE__) // Assert that the specified value is >= minimum and <= maximum. #define assert_in_range(value, minimum, maximum) \ - _assert_in_range((int)value, (int)minimum, (int)maximum, __FILE__, \ - __LINE__) + _assert_in_range( \ + cast_to_largest_integral_type(value), \ + cast_to_largest_integral_type(minimum), \ + cast_to_largest_integral_type(maximum), __FILE__, __LINE__) + // Assert that the specified value is < minumum or > maximum #define assert_not_in_range(value, minimum, maximum) \ - _assert_not_in_range((int)value, (int)minimum, (int)maximum, __FILE__, \ - __LINE__) + _assert_not_in_range( \ + cast_to_largest_integral_type(value), \ + cast_to_largest_integral_type(minimum), \ + cast_to_largest_integral_type(maximum), __FILE__, __LINE__) // Assert that the specified value is within a set. #define assert_in_set(value, values, number_of_values) \ - _assert_in_set(value, values, number_of_values, __FILE__, __LINE__) + _assert_in_set(value, values, number_of_values, __FILE__, __LINE__) // Assert that the specified value is not within a set. #define assert_not_in_set(value, values, number_of_values) \ - _assert_not_in_set(value, values, number_of_values, __FILE__, __LINE__) + _assert_not_in_set(value, values, number_of_values, __FILE__, __LINE__) // Forces the test to fail immediately and quit. @@ -204,25 +233,25 @@ // Initializes a UnitTest structure. #define unit_test(f) { #f, f, UNIT_TEST_FUNCTION_TYPE_TEST } #define unit_test_setup(test, setup) \ - { #test "_" #setup, setup, UNIT_TEST_FUNCTION_TYPE_SETUP } + { #test "_" #setup, setup, UNIT_TEST_FUNCTION_TYPE_SETUP } #define unit_test_teardown(test, teardown) \ - { #test "_" #teardown, teardown, UNIT_TEST_FUNCTION_TYPE_TEARDOWN } + { #test "_" #teardown, teardown, UNIT_TEST_FUNCTION_TYPE_TEARDOWN } /* Initialize an array of UnitTest structures with a setup function for a test * and a teardown function. Either setup or teardown can be NULL. */ -#define unit_test_setup_teardown(test, setup, teardown) \ - unit_test_setup(test, setup), \ - unit_test(test), \ - unit_test_teardown(test, teardown) +#define unit_test_setup_teardown(test, setup, teardown) \ + unit_test_setup(test, setup), \ + unit_test(test), \ + unit_test_teardown(test, teardown) /* * Run tests specified by an array of UnitTest structures. The following * example illustrates this macro's use with the unit_test macro. - * + * * void Test0(); * void Test1(); - * + * * int main(int argc, char* argv[]) { * const UnitTest tests[] = { * unit_test(Test0); @@ -281,38 +310,39 @@ typedef void (*UnitTestFunction)(void **state); // Function that determines whether a function parameter value is correct. -typedef int (*CheckParameterValue)(const void *value, void *check_value_data); +typedef int (*CheckParameterValue)(const LargestIntegralType value, + const LargestIntegralType check_value_data); // Type of the unit test function. typedef enum UnitTestFunctionType { - UNIT_TEST_FUNCTION_TYPE_TEST = 0, - UNIT_TEST_FUNCTION_TYPE_SETUP, - UNIT_TEST_FUNCTION_TYPE_TEARDOWN, + UNIT_TEST_FUNCTION_TYPE_TEST = 0, + UNIT_TEST_FUNCTION_TYPE_SETUP, + UNIT_TEST_FUNCTION_TYPE_TEARDOWN, } UnitTestFunctionType; /* Stores a unit test function with its name and type. * NOTE: Every setup function must be paired with a teardown function. It's - * possible to specify NULL function pointers. + * possible to specify NULL function pointers. */ typedef struct UnitTest { - const char* name; - UnitTestFunction function; - UnitTestFunctionType function_type; + const char* name; + UnitTestFunction function; + UnitTestFunctionType function_type; } UnitTest; // Location within some source code. typedef struct SourceLocation { - const char* file; - int line; + const char* file; + int line; } SourceLocation; -// Event that's called to check a parameter value. +// Event that's called to check a parameter value. typedef struct CheckParameterEvent { - SourceLocation location; - const char *parameter_name; - CheckParameterValue check_value; - void *check_value_data; + SourceLocation location; + const char *parameter_name; + CheckParameterValue check_value; + LargestIntegralType check_value_data; } CheckParameterEvent; // Used by expect_assert_failure() and mock_assert(). @@ -320,40 +350,45 @@ extern int global_expecting_assert; extern jmp_buf global_expect_assert_env; // Retrieves a value for the given function, as set by "will_return". -void* _mock(const char * const function, const char* const file, - const int line); +LargestIntegralType _mock(const char * const function, const char* const file, + const int line); void _expect_check( - const char* const function, const char* const parameter, + const char* const function, const char* const parameter, const char* const file, const int line, - const CheckParameterValue check_function, void * const check_data, - CheckParameterEvent * const event, const int count); + const CheckParameterValue check_function, + const LargestIntegralType check_data, CheckParameterEvent * const event, + const int count); void _expect_in_set( const char* const function, const char* const parameter, - const char* const file, const int line, const void *values[], + const char* const file, const int line, const LargestIntegralType values[], const size_t number_of_values, const int count); void _expect_not_in_set( const char* const function, const char* const parameter, - const char* const file, const int line, const void *values[], + const char* const file, const int line, const LargestIntegralType values[], const size_t number_of_values, const int count); void _expect_in_range( const char* const function, const char* const parameter, const char* const file, const int line, - const int minimum, const int maximum, const int count); + const LargestIntegralType minimum, + const LargestIntegralType maximum, const int count); void _expect_not_in_range( const char* const function, const char* const parameter, const char* const file, const int line, - const int minimum, const int maximum, const int count); + const LargestIntegralType minimum, + const LargestIntegralType maximum, const int count); + void _expect_value( const char* const function, const char* const parameter, - const char* const file, const int line, const void* const value, + const char* const file, const int line, const LargestIntegralType value, const int count); void _expect_not_value( const char* const function, const char* const parameter, - const char* const file, const int line, const void* const value, + const char* const file, const int line, const LargestIntegralType value, const int count); + void _expect_string( const char* const function, const char* const parameter, const char* const file, const int line, const char* string, @@ -362,67 +397,73 @@ void _expect_not_string( const char* const function, const char* const parameter, const char* const file, const int line, const char* string, const int count); + void _expect_memory( const char* const function, const char* const parameter, const char* const file, const int line, const void* const memory, const size_t size, const int count); void _expect_not_memory( const char* const function, const char* const parameter, - const char* const file, const int line, const void* const memory, + const char* const file, const int line, const void* const memory, const size_t size, const int count); + void _expect_any( const char* const function, const char* const parameter, const char* const file, const int line, const int count); void _check_expected( const char * const function_name, const char * const parameter_name, - const char* file, const int line, const void* value); + const char* file, const int line, const LargestIntegralType value); // Can be used to replace assert in tested code so that in conjuction with -// check_assert() it's possible to determine whether an assert condition has +// check_assert() it's possible to determine whether an assert condition has // failed without stopping a test. -void mock_assert(const int result, const char* const expression, +void mock_assert(const int result, const char* const expression, const char * const file, const int line); void _will_return(const char * const function_name, const char * const file, - const int line, const void* const value, const int count); -void _assert_true(const int result, const char* const expression, + const int line, const LargestIntegralType value, + const int count); +void _assert_true(const int result, const char* const expression, const char * const file, const int line); -void _assert_int_equal(const int a, const int b, const char * const file, - const int line); -void _assert_int_not_equal(const int a, const int b, const char * const file, - const int line); -void _assert_string_equal(const char * const a, const char * const b, +void _assert_int_equal( + const LargestIntegralType a, const LargestIntegralType b, + const char * const file, const int line); +void _assert_int_not_equal( + const LargestIntegralType a, const LargestIntegralType b, + const char * const file, const int line); +void _assert_string_equal(const char * const a, const char * const b, const char * const file, const int line); -void _assert_string_not_equal(const char * const a, const char * const b, +void _assert_string_not_equal(const char * const a, const char * const b, const char *file, const int line); -void _assert_memory_equal(const void * const a, const void * const b, - const size_t size, const char* const file, +void _assert_memory_equal(const void * const a, const void * const b, + const size_t size, const char* const file, const int line); void _assert_memory_not_equal(const void * const a, const void * const b, - const size_t size, const char* const file, + const size_t size, const char* const file, const int line); -void _assert_in_range(const int value, const int minimum, const int maximum, - const char* const file, const int line); -void _assert_not_in_range(const int value, const int minimum, - const int maximum, const char* const file, - const int line); -void _assert_in_set(const void * const value, const void *values[], - const size_t number_of_values, const char* const file, - const int line); -void _assert_not_in_set(const void * const value, const void *values[], - const size_t number_of_values, const char* const file, - const int line); +void _assert_in_range( + const LargestIntegralType value, const LargestIntegralType minimum, + const LargestIntegralType maximum, const char* const file, const int line); +void _assert_not_in_range( + const LargestIntegralType value, const LargestIntegralType minimum, + const LargestIntegralType maximum, const char* const file, const int line); +void _assert_in_set( + const LargestIntegralType value, const LargestIntegralType values[], + const size_t number_of_values, const char* const file, const int line); +void _assert_not_in_set( + const LargestIntegralType value, const LargestIntegralType values[], + const size_t number_of_values, const char* const file, const int line); void* _test_malloc(const size_t size, const char* file, const int line); -void* _test_calloc(const size_t number_of_elements, const size_t size, +void* _test_calloc(const size_t number_of_elements, const size_t size, const char* file, const int line); void _test_free(void* const ptr, const char* file, const int line); void _fail(const char * const file, const int line); int _run_test( - const char * const function_name, const UnitTestFunction Function, - void ** const state, const UnitTestFunctionType function_type, + const char * const function_name, const UnitTestFunction Function, + void ** const state, const UnitTestFunctionType function_type, const void* const heap_check_point); int _run_tests(const UnitTest * const tests, const size_t number_of_tests); -- 2.7.4