* 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.
// 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.
// 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.
// 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);
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(
// 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.
#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.
// 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;
}
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;
}
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);
}
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;
}
*/
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
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);
}
* 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);
}
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);
}
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));
}
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));
}
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);
}
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;
}
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;
}
* 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.
* #include <stdarg.h>
* #include <stddef.h>
* #include <setjmp.h>
- *
- * 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.
*/
#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__)
* 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
* 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__)
#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.
// 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);
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().
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,
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);