[PATCH] Add cmocka 1.1.1 to third_party

Andreas Schneider asn at samba.org
Fri Apr 7 14:51:46 UTC 2017


Hi,

I've released cmocka-1.1.1 and this patchset adds it to third_party. I 
recommend to install it in the system!

If wonder how to use it:

https://api.cmocka.org/ is where you should start.


Review and push appreciated!


Cheers,


	Andreas

-- 
Andreas Schneider                   GPG-ID: CC014E3D
Samba Team                             asn at samba.org
www.samba.org
-------------- next part --------------
>From 9a3695a82d9190ff228d92dd6ab938ad025490b8 Mon Sep 17 00:00:00 2001
From: Andreas Schneider <asn at samba.org>
Date: Fri, 7 Apr 2017 15:44:22 +0200
Subject: [PATCH 1/2] wafsamba: Add CHECK_CMOCKA function

---
 buildtools/wafsamba/samba_third_party.py | 6 ++++++
 1 file changed, 6 insertions(+)

diff --git a/buildtools/wafsamba/samba_third_party.py b/buildtools/wafsamba/samba_third_party.py
index 8cfa4df7214..ac77be74f5a 100644
--- a/buildtools/wafsamba/samba_third_party.py
+++ b/buildtools/wafsamba/samba_third_party.py
@@ -33,3 +33,9 @@ def CHECK_POPT(conf):
     return conf.CHECK_BUNDLED_SYSTEM('popt', checkfunctions='poptGetContext', headers='popt.h')
 
 Build.BuildContext.CHECK_POPT = CHECK_POPT
+
+ at conf
+def CHECK_CMOCKA(conf):
+    return conf.CHECK_BUNDLED_SYSTEM_PKG('cmocka', minversion='1.1.1')
+
+Build.BuildContext.CHECK_CMOCKA = CHECK_CMOCKA
-- 
2.12.2


>From a4d2d5ad9819234574f6af6a6b39f30a8e85bb6d Mon Sep 17 00:00:00 2001
From: Andreas Schneider <asn at samba.org>
Date: Fri, 7 Apr 2017 15:44:05 +0200
Subject: [PATCH 2/2] third_party: Add cmocka 1.1.1

---
 testsuite/unittests/wscript         |   14 +-
 third_party/cmocka/cmocka.c         | 3306 +++++++++++++++++++++++++++++++++++
 third_party/cmocka/cmocka.h         | 2284 ++++++++++++++++++++++++
 third_party/cmocka/cmocka_private.h |  163 ++
 third_party/cmocka/wscript          |   19 +
 third_party/wscript                 |    2 +
 wscript                             |    6 +
 7 files changed, 5785 insertions(+), 9 deletions(-)
 create mode 100644 third_party/cmocka/cmocka.c
 create mode 100644 third_party/cmocka/cmocka.h
 create mode 100644 third_party/cmocka/cmocka_private.h
 create mode 100644 third_party/cmocka/wscript

diff --git a/testsuite/unittests/wscript b/testsuite/unittests/wscript
index e2569513d49..355ab0cc10a 100644
--- a/testsuite/unittests/wscript
+++ b/testsuite/unittests/wscript
@@ -3,14 +3,10 @@
 import os
 
 def configure(conf):
-    pkg_name = 'cmocka'
-    pkg_minversion = '1.0'
-
-    conf.CHECK_BUNDLED_SYSTEM_PKG(pkg_name, minversion=pkg_minversion)
+    return
 
 def build(bld):
-    if bld.CONFIG_SET('HAVE_CMOCKA'):
-        bld.SAMBA_BINARY('test_krb5samba',
-                         source='test_krb5_samba.c',
-                         deps='krb5samba cmocka',
-                         install=False)
+    bld.SAMBA_BINARY('test_krb5samba',
+                     source='test_krb5_samba.c',
+                     deps='krb5samba cmocka',
+                     install=False)
diff --git a/third_party/cmocka/cmocka.c b/third_party/cmocka/cmocka.c
new file mode 100644
index 00000000000..14b2765b781
--- /dev/null
+++ b/third_party/cmocka/cmocka.c
@@ -0,0 +1,3306 @@
+/*
+ * Copyright 2008 Google Inc.
+ * Copyright 2014-2015 Andreas Schneider <asn at cryptomilk.org>
+ * Copyright 2015      Jakub Hrozek <jakub.hrozek at posteo.se>
+ *
+ * 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.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#ifdef HAVE_MALLOC_H
+#include <malloc.h>
+#endif
+
+#ifdef HAVE_INTTYPES_H
+#include <inttypes.h>
+#endif
+
+#ifdef HAVE_SIGNAL_H
+#include <signal.h>
+#endif
+
+#ifdef HAVE_STRINGS_H
+#include <strings.h>
+#endif
+
+#include <stdint.h>
+#include <setjmp.h>
+#include <stdarg.h>
+#include <stddef.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <time.h>
+
+/*
+ * This allows to add a platform specific header file. Some embedded platforms
+ * sometimes miss certain types and definitions.
+ *
+ * Example:
+ *
+ * typedef unsigned long int uintptr_t
+ * #define _UINTPTR_T 1
+ * #define _UINTPTR_T_DEFINED 1
+ */
+#ifdef CMOCKA_PLATFORM_INCLUDE
+# include "cmocka_platform.h"
+#endif /* CMOCKA_PLATFORM_INCLUDE */
+
+#include <cmocka.h>
+#include <cmocka_private.h>
+
+/* Size of guard bytes around dynamically allocated blocks. */
+#define MALLOC_GUARD_SIZE 16
+/* Pattern used to initialize guard blocks. */
+#define MALLOC_GUARD_PATTERN 0xEF
+/* Pattern used to initialize memory allocated with test_malloc(). */
+#define MALLOC_ALLOC_PATTERN 0xBA
+#define MALLOC_FREE_PATTERN 0xCD
+/* Alignment of allocated blocks.  NOTE: This must be base2. */
+#define MALLOC_ALIGNMENT sizeof(size_t)
+
+/* Printf formatting for source code locations. */
+#define SOURCE_LOCATION_FORMAT "%s:%u"
+
+#if defined(HAVE_GCC_THREAD_LOCAL_STORAGE)
+# define CMOCKA_THREAD __thread
+#elif defined(HAVE_MSVC_THREAD_LOCAL_STORAGE)
+# define CMOCKA_THREAD __declspec(thread)
+#else
+# define CMOCKA_THREAD
+#endif
+
+#ifdef HAVE_CLOCK_REALTIME
+#define CMOCKA_CLOCK_GETTIME(clock_id, ts) clock_gettime((clock_id), (ts))
+#else
+#define CMOCKA_CLOCK_GETTIME(clock_id, ts)
+#endif
+
+#ifndef MAX
+#define MAX(a,b) ((a) < (b) ? (b) : (a))
+#endif
+
+/**
+ * POSIX has sigsetjmp/siglongjmp, while Windows only has setjmp/longjmp.
+ */
+#ifdef HAVE_SIGLONGJMP
+# define cm_jmp_buf             sigjmp_buf
+# define cm_setjmp(env)         sigsetjmp(env, 1)
+# define cm_longjmp(env, val)   siglongjmp(env, val)
+#else
+# define cm_jmp_buf             jmp_buf
+# define cm_setjmp(env)         setjmp(env)
+# define cm_longjmp(env, val)   longjmp(env, val)
+#endif
+
+
+/*
+ * 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.x.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))->x.pointer)
+
+/* Used to cast LargetIntegralType to void* and vice versa. */
+typedef union ValuePointer {
+    LargestIntegralType value;
+    struct {
+#if defined(WORDS_BIGENDIAN) && (WORDS_SIZEOF_VOID_P == 4)
+        unsigned int padding;
+#endif
+        void *pointer;
+    } x;
+} ValuePointer;
+
+/* Doubly linked list node. */
+typedef struct ListNode {
+    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. */
+} 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. */
+} TestState;
+
+/* Determines whether two values are the same. */
+typedef int (*EqualityFunction)(const void *left, const void *right);
+
+/* Value of a symbol and the place it was declared. */
+typedef struct SymbolValue {
+    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
+ * SourceLocation as its' first member.
+ */
+typedef struct SymbolMapValue {
+    const char *symbol_name;
+    ListNode symbol_values_list_head;
+} SymbolMapValue;
+
+/* Where a particular ordering was located and its symbol name */
+typedef struct FuncOrderingValue {
+    SourceLocation location;
+    const char * function;
+} FuncOrderingValue;
+
+/* Used by list_free() to deallocate values referenced by list nodes. */
+typedef void (*CleanupListValue)(const void *value, void *cleanup_value_data);
+
+/* Structure used to check the range of integer types.a */
+typedef struct CheckIntegerRange {
+    CheckParameterEvent event;
+    LargestIntegralType minimum;
+    LargestIntegralType maximum;
+} CheckIntegerRange;
+
+/* Structure used to check whether an integer value is in a set. */
+typedef struct CheckIntegerSet {
+    CheckParameterEvent event;
+    const LargestIntegralType *set;
+    size_t size_of_set;
+} CheckIntegerSet;
+
+/* 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;
+} CheckMemoryData;
+
+static ListNode* list_initialize(ListNode * const node);
+static ListNode* list_add(ListNode * const head, ListNode *new_node);
+static ListNode* list_add_value(ListNode * const head, const void *value,
+                                     const int count);
+static ListNode* list_remove(
+    ListNode * const node, const CleanupListValue cleanup_value,
+    void * const cleanup_value_data);
+static void list_remove_free(
+    ListNode * const node, const CleanupListValue cleanup_value,
+    void * const cleanup_value_data);
+static int list_empty(const ListNode * const head);
+static int list_find(
+    ListNode * const head, const void *value,
+    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,
+    void * const cleanup_value_data);
+
+static void add_symbol_value(
+    ListNode * const symbol_map_head, const char * const symbol_names[],
+    const size_t number_of_symbol_names, const void* value, const int count);
+static int get_symbol_value(
+    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(
+    const void *value, void *cleanup_value_data);
+static void remove_always_return_values(ListNode * const map_head,
+                                        const size_t number_of_symbol_names);
+
+static int check_for_leftover_values_list(const ListNode * head,
+    const char * const error_message);
+
+static int check_for_leftover_values(
+    const ListNode * const map_head, const char * const error_message,
+    const size_t number_of_symbol_names);
+
+static void remove_always_return_values_from_list(ListNode * const map_head);
+
+/*
+ * This must be called at the beginning of a test to initialize some data
+ * structures.
+ */
+static void initialize_testing(const char *test_name);
+
+/* This must be called at the end of a test to free() allocated structures. */
+static void teardown_testing(const char *test_name);
+
+static enum cm_message_output cm_get_output(void);
+
+static int cm_error_message_enabled = 1;
+static CMOCKA_THREAD char *cm_error_message;
+
+void cm_print_error(const char * const format, ...) CMOCKA_PRINTF_ATTRIBUTE(1, 2);
+
+/*
+ * Keeps track of the calling context returned by setenv() so that the fail()
+ * method can jump out of a test.
+ */
+static CMOCKA_THREAD cm_jmp_buf global_run_test_env;
+static CMOCKA_THREAD int global_running_test = 0;
+
+/* Keeps track of the calling context returned by setenv() so that */
+/* mock_assert() can optionally jump back to expect_assert_failure(). */
+jmp_buf global_expect_assert_env;
+int global_expecting_assert = 0;
+const char *global_last_failed_assert = NULL;
+static int global_skip_test;
+
+/* Keeps a map of the values that functions will have to return to provide */
+/* mocked interfaces. */
+static CMOCKA_THREAD ListNode global_function_result_map_head;
+/* Location of the last mock value returned was declared. */
+static CMOCKA_THREAD SourceLocation global_last_mock_value_location;
+
+/* Keeps a map of the values that functions expect as parameters to their
+ * mocked interfaces. */
+static CMOCKA_THREAD ListNode global_function_parameter_map_head;
+/* Location of last parameter value checked was declared. */
+static CMOCKA_THREAD SourceLocation global_last_parameter_location;
+
+/* List (acting as FIFO) of call ordering. */
+static CMOCKA_THREAD ListNode global_call_ordering_head;
+/* Location of last call ordering that was declared. */
+static CMOCKA_THREAD SourceLocation global_last_call_ordering_location;
+
+/* List of all currently allocated blocks. */
+static CMOCKA_THREAD ListNode global_allocated_blocks;
+
+static enum cm_message_output global_msg_output = CM_OUTPUT_STDOUT;
+
+#ifndef _WIN32
+/* Signals caught by exception_handler(). */
+static const int exception_signals[] = {
+    SIGFPE,
+    SIGILL,
+    SIGSEGV,
+#ifdef SIGBUS
+    SIGBUS,
+#endif
+#ifdef SIGSYS
+    SIGSYS,
+#endif
+};
+
+/* Default signal functions that should be restored after a test is complete. */
+typedef void (*SignalFunction)(int signal);
+static SignalFunction default_signal_functions[
+    ARRAY_SIZE(exception_signals)];
+
+#else /* _WIN32 */
+
+/* The default exception filter. */
+static LPTOP_LEVEL_EXCEPTION_FILTER previous_exception_filter;
+
+/* Fatal exceptions. */
+typedef struct ExceptionCodeInfo {
+    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),
+};
+#endif /* !_WIN32 */
+
+enum CMUnitTestStatus {
+    CM_TEST_NOT_STARTED,
+    CM_TEST_PASSED,
+    CM_TEST_FAILED,
+    CM_TEST_ERROR,
+    CM_TEST_SKIPPED,
+};
+
+struct CMUnitTestState {
+    const ListNode *check_point; /* Check point of the test if there's a setup function. */
+    const struct CMUnitTest *test; /* Point to array element in the tests we get passed */
+    void *state; /* State associated with the test */
+    const char *error_message; /* The error messages by the test */
+    enum CMUnitTestStatus status; /* PASSED, FAILED, ABORT ... */
+    double runtime; /* Time calculations */
+};
+
+/* Exit the currently executing test. */
+static void exit_test(const int quit_application)
+{
+    const char *abort_test = getenv("CMOCKA_TEST_ABORT");
+
+    if (abort_test != NULL && abort_test[0] == '1') {
+        print_error("%s", cm_error_message);
+        abort();
+    } else if (global_running_test) {
+        cm_longjmp(global_run_test_env, 1);
+    } else if (quit_application) {
+        exit(-1);
+    }
+}
+
+void _skip(const char * const file, const int line)
+{
+    cm_print_error(SOURCE_LOCATION_FORMAT ": Skipped!\n", file, line);
+    global_skip_test = 1;
+    exit_test(1);
+}
+
+/* Initialize a SourceLocation structure. */
+static void initialize_source_location(SourceLocation * const location) {
+    assert_non_null(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_non_null(location);
+    return location->file && location->line;
+}
+
+
+/* Set a source location. */
+static void set_source_location(
+    SourceLocation * const location, const char * const file,
+    const int line) {
+    assert_non_null(location);
+    location->file = file;
+    location->line = line;
+}
+
+
+static int c_strreplace(char *src,
+                        size_t src_len,
+                        const char *pattern,
+                        const char *repl,
+                        int *str_replaced)
+{
+    char *p = NULL;
+
+    p = strstr(src, pattern);
+    if (p == NULL) {
+        return -1;
+    }
+
+    do {
+        size_t of = p - src;
+        size_t l  = strlen(src);
+        size_t pl = strlen(pattern);
+        size_t rl = strlen(repl);
+
+        /* overflow check */
+        if (src_len <= l + MAX(pl, rl) + 1) {
+            return -1;
+        }
+
+        if (rl != pl) {
+            memmove(src + of + rl, src + of + pl, l - of - pl + 1);
+        }
+
+        strncpy(src + of, repl, rl);
+
+        if (str_replaced != NULL) {
+            *str_replaced = 1;
+        }
+        p = strstr(src, pattern);
+    } while (p != NULL);
+
+    return 0;
+}
+
+/* Create function results and expected parameter lists. */
+void initialize_testing(const char *test_name) {
+    (void)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_call_ordering_head);
+    initialize_source_location(&global_last_parameter_location);
+}
+
+
+static void fail_if_leftover_values(const char *test_name) {
+    int error_occurred = 0;
+    (void)test_name;
+    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;
+    }
+
+    remove_always_return_values_from_list(&global_call_ordering_head);
+    if (check_for_leftover_values_list(&global_call_ordering_head,
+        "%s function was expected to be called but was not not.\n")) {
+        error_occurred = 1;
+    }
+    if (error_occurred) {
+        exit_test(1);
+    }
+}
+
+
+static void teardown_testing(const char *test_name) {
+    (void)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_call_ordering_head, free_value,
+              (void*)0);
+    initialize_source_location(&global_last_call_ordering_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;
+}
+
+
+/*
+ * 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_non_null(head);
+    assert_non_null(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_non_null(head);
+    assert_non_null(new_node);
+    new_node->next = head;
+    new_node->prev = head->prev;
+    head->prev->next = new_node;
+    head->prev = new_node;
+    return new_node;
+}
+
+
+/* Remove a node from a list. */
+static ListNode* list_remove(
+        ListNode * const node, const CleanupListValue cleanup_value,
+        void * const cleanup_value_data) {
+    assert_non_null(node);
+    node->prev->next = node->next;
+    node->next->prev = node->prev;
+    if (cleanup_value) {
+        cleanup_value(node->value, cleanup_value_data);
+    }
+    return node;
+}
+
+
+/* Remove a list node from a list and free the node. */
+static void list_remove_free(
+        ListNode * const node, const CleanupListValue cleanup_value,
+        void * const cleanup_value_data) {
+    assert_non_null(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, 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,
+        void * const cleanup_value_data) {
+    assert_non_null(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_non_null(head);
+    return head->next == head;
+}
+
+
+/*
+ * Find a value in the list using the equal_func to compare each node with the
+ * value.
+ */
+static int list_find(ListNode * const head, const void *value,
+                     const EqualityFunction equal_func, ListNode **output) {
+    ListNode *current;
+    assert_non_null(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_non_null(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) {
+    (void)cleanup_value_data;
+    assert_non_null(value);
+    free((void*)value);
+}
+
+
+/* Releases memory associated to a symbol_map_value. */
+static void free_symbol_map_value(const void *value,
+                                  void *cleanup_value_data) {
+    SymbolMapValue * const map_value = (SymbolMapValue*)value;
+    const LargestIntegralType children = cast_ptr_to_largest_integral_type(cleanup_value_data);
+    assert_non_null(value);
+    list_free(&map_value->symbol_values_list_head,
+              children ? free_symbol_map_value : free_value,
+              (void *) ((uintptr_t)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,
+                   (const char*)symbol);
+}
+
+/*
+ * Adds a value to the queue of values associated with the given hierarchy of
+ * symbols.  It's assumed value is allocated from the heap.
+ */
+static void add_symbol_value(ListNode * const symbol_map_head,
+                             const char * const symbol_names[],
+                             const size_t number_of_symbol_names,
+                             const void* value, const int refcount) {
+    const char* symbol_name;
+    ListNode *target_node;
+    SymbolMapValue *target_map_value;
+    assert_non_null(symbol_map_head);
+    assert_non_null(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 =
+            (SymbolMapValue*)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[],
+        const size_t number_of_symbol_names, void **output) {
+    const char* symbol_name;
+    ListNode *target_node;
+    assert_non_null(head);
+    assert_non_null(symbol_names);
+    assert_true(number_of_symbol_names);
+    assert_non_null(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_non_null(target_node);
+        assert_non_null(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 - 1 == 0) {
+                list_remove_free(value_node, NULL, NULL);
+            } else if (value_node->refcount > WILL_RETURN_ONCE) {
+                --value_node->refcount;
+            }
+        } 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 {
+        cm_print_error("No entries for symbol %s.\n", symbol_name);
+    }
+    return 0;
+}
+
+/**
+ * Taverse a list of nodes and remove first symbol value in list that has a
+ * refcount < -1 (i.e. should always be returned and has been returned at
+ * least once).
+ */
+
+static void remove_always_return_values_from_list(ListNode * const map_head)
+{
+    ListNode * current = NULL;
+    ListNode * next = NULL;
+    assert_non_null(map_head);
+
+    for (current = map_head->next, next = current->next;
+            current != map_head;
+            current = next, next = current->next) {
+        if (current->refcount < -1) {
+            list_remove_free(current, free_value, NULL);
+        }
+    }
+}
+
+/*
+ * Traverse down a tree of symbol values and remove the first symbol value
+ * in each branch that has a refcount < -1 (i.e should always be returned
+ * and has been returned at least once).
+ */
+static void remove_always_return_values(ListNode * const map_head,
+                                        const size_t number_of_symbol_names) {
+    ListNode *current;
+    assert_non_null(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_non_null(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;
+    }
+}
+
+static int check_for_leftover_values_list(const ListNode * head,
+                                          const char * const error_message)
+{
+    ListNode *child_node;
+    int leftover_count = 0;
+    if (!list_empty(head))
+    {
+        for (child_node = head->next; child_node != head;
+                 child_node = child_node->next, ++leftover_count) {
+            const FuncOrderingValue *const o =
+                    (const FuncOrderingValue*) child_node->value;
+            cm_print_error(error_message, o->function);
+            cm_print_error(SOURCE_LOCATION_FORMAT
+                    ": note: remaining item was declared here\n",
+                    o->location.file, o->location.line);
+        }
+    }
+    return leftover_count;
+}
+
+/*
+ * Checks if there are any leftover values set up by the test that were never
+ * retrieved through execution, and fail the test if that is the case.
+ */
+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_non_null(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_non_null(value);
+        child_list = &value->symbol_values_list_head;
+
+        if (!list_empty(child_list)) {
+            if (number_of_symbol_names == 1) {
+                const ListNode *child_node;
+                cm_print_error(error_message, value->symbol_name);
+
+                for (child_node = child_list->next; child_node != child_list;
+                     child_node = child_node->next) {
+                    const SourceLocation * const location =
+                        (const SourceLocation*)child_node->value;
+                    cm_print_error(SOURCE_LOCATION_FORMAT
+                                   ": note: remaining item was declared here\n",
+                                   location->file, location->line);
+                }
+            } else {
+                cm_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. */
+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 {
+        cm_print_error(SOURCE_LOCATION_FORMAT ": error: Could not get value "
+                       "to mock function %s\n", file, line, function);
+        if (source_location_is_set(&global_last_mock_value_location)) {
+            cm_print_error(SOURCE_LOCATION_FORMAT
+                           ": note: Previously returned mock value was declared here\n",
+                           global_last_mock_value_location.file,
+                           global_last_mock_value_location.line);
+        } else {
+            cm_print_error("There were no previously returned mock values for "
+                           "this test.\n");
+        }
+        exit_test(1);
+    }
+    return 0;
+}
+
+/* Ensure that function is being called in proper order */
+void _function_called(const char *const function,
+                      const char *const file,
+                      const int line)
+{
+    ListNode *first_value_node = NULL;
+    ListNode *value_node = NULL;
+    int rc;
+
+    rc = list_first(&global_call_ordering_head, &value_node);
+    first_value_node = value_node;
+    if (rc) {
+        FuncOrderingValue *expected_call;
+        int cmp;
+
+        expected_call = (FuncOrderingValue *)value_node->value;
+
+        cmp = strcmp(expected_call->function, function);
+        if (value_node->refcount < -1) {
+            /*
+             * Search through value nodes until either function is found or
+             * encounter a non-zero refcount greater than -2
+             */
+            if (cmp != 0) {
+                value_node = value_node->next;
+                expected_call = (FuncOrderingValue *)value_node->value;
+
+                cmp = strcmp(expected_call->function, function);
+                while (value_node->refcount < -1 &&
+                       cmp != 0 &&
+                       value_node != first_value_node->prev) {
+                    value_node = value_node->next;
+                    if (value_node == NULL) {
+                        break;
+                    }
+                    expected_call = (FuncOrderingValue *)value_node->value;
+                    if (expected_call == NULL) {
+                        continue;
+                    }
+                    cmp = strcmp(expected_call->function, function);
+                }
+
+                if (expected_call == NULL || value_node == first_value_node->prev) {
+                    cm_print_error(SOURCE_LOCATION_FORMAT
+                                   ": error: No expected mock calls matching "
+                                   "called() invocation in %s",
+                                   file, line,
+                                   function);
+                    exit_test(1);
+                }
+            }
+        }
+
+        if (cmp == 0) {
+            if (value_node->refcount > -2 && --value_node->refcount == 0) {
+                list_remove_free(value_node, free_value, NULL);
+            }
+        } else {
+            cm_print_error(SOURCE_LOCATION_FORMAT
+                           ": error: Expected call to %s but received called() "
+                           "in %s\n",
+                           file, line,
+                           expected_call->function,
+                           function);
+            exit_test(1);
+        }
+    } else {
+        cm_print_error(SOURCE_LOCATION_FORMAT
+                       ": error: No mock calls expected but called() was "
+                       "invoked in %s\n",
+                       file, line,
+                       function);
+        exit_test(1);
+    }
+}
+
+/* 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 LargestIntegralType value,
+                  const int count) {
+    SymbolValue * const return_value =
+        (SymbolValue*)malloc(sizeof(*return_value));
+    assert_true(count != 0);
+    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);
+}
+
+
+/*
+ * Add a custom parameter checking function.  If the event parameter is NULL
+ * the event structure is allocated internally by this function.  If event
+ * parameter is provided it must be allocated on the heap and doesn't need to
+ * be deallocated by the caller.
+ */
+void _expect_check(
+        const char* const function, const char* const parameter,
+        const char* const file, const int line,
+        const CheckParameterValue check_function,
+        const LargestIntegralType check_data,
+        CheckParameterEvent * const event, const int count) {
+    CheckParameterEvent * const check =
+        event ? event : (CheckParameterEvent*)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);
+}
+
+/*
+ * Add an call expectations that a particular function is called correctly.
+ * This is used for code under test that makes calls to several functions
+ * in depended upon components (mocks).
+ */
+
+void _expect_function_call(
+    const char * const function_name,
+    const char * const file,
+    const int line,
+    const int count)
+{
+    FuncOrderingValue *ordering;
+
+    assert_non_null(function_name);
+    assert_non_null(file);
+    assert_true(count != 0);
+
+    ordering = (FuncOrderingValue *)malloc(sizeof(*ordering));
+
+    set_source_location(&ordering->location, file, line);
+    ordering->function = function_name;
+
+    list_add_value(&global_call_ordering_head, ordering, 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 LargestIntegralType left,
+                                      const LargestIntegralType right) {
+    const int equal = left == right;
+    if (!equal) {
+        cm_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 LargestIntegralType left,
+                                          const LargestIntegralType right) {
+    const int not_equal = left != right;
+    if (!not_equal) {
+        cm_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
+ * displayed.
+ */
+static int value_in_set_display_error(
+        const LargestIntegralType value,
+        const CheckIntegerSet * const check_integer_set, const int invert) {
+    int succeeded = invert;
+    assert_non_null(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;
+        }
+        cm_print_error(LargestIntegralTypePrintfFormatDecimal
+                       " is %sin the set (",
+                       value, invert ? "" : "not ");
+        for (i = 0; i < size_of_set; i++) {
+            cm_print_error(LargestIntegralTypePrintfFormat ", ", set[i]);
+        }
+        cm_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
+ * specified range an error is displayed and 0 is returned.
+ */
+static int integer_in_range_display_error(
+        const LargestIntegralType value, const LargestIntegralType range_min,
+        const LargestIntegralType range_max) {
+    if (value >= range_min && value <= range_max) {
+        return 1;
+    }
+    cm_print_error(LargestIntegralTypePrintfFormatDecimal
+                   " is not within the range "
+                   LargestIntegralTypePrintfFormatDecimal "-"
+                   LargestIntegralTypePrintfFormatDecimal "\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
+ * specified range an error is displayed and zero is returned.
+ */
+static int integer_not_in_range_display_error(
+        const LargestIntegralType value, const LargestIntegralType range_min,
+        const LargestIntegralType range_max) {
+    if (value < range_min || value > range_max) {
+        return 1;
+    }
+    cm_print_error(LargestIntegralTypePrintfFormatDecimal
+                   " is within the range "
+                   LargestIntegralTypePrintfFormatDecimal "-"
+                   LargestIntegralTypePrintfFormatDecimal "\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
+ * returned.
+ */
+static int string_equal_display_error(
+        const char * const left, const char * const right) {
+    if (strcmp(left, right) == 0) {
+        return 1;
+    }
+    cm_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
+ * returned
+ */
+static int string_not_equal_display_error(
+        const char * const left, const char * const right) {
+    if (strcmp(left, right) != 0) {
+        return 1;
+    }
+    cm_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* 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) {
+            cm_print_error("difference at offset %" PRIdS " 0x%02x 0x%02x\n",
+                           i, l, r);
+            differences ++;
+        }
+    }
+    if (differences) {
+        cm_print_error("%d bytes of %p and %p differ\n",
+                       differences, (void *)a, (void *)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* const a, const char* const b, const size_t size) {
+    size_t same = 0;
+    size_t i;
+    for (i = 0; i < size; i++) {
+        const char l = a[i];
+        const char r = b[i];
+        if (l == r) {
+            same ++;
+        }
+    }
+    if (same == size) {
+        cm_print_error("%"PRIdS "bytes of %p and %p the same\n",
+                       same, (void *)a, (void *)b);
+        return 0;
+    }
+    return 1;
+}
+
+
+/* CheckParameterValue callback to check whether a value is within a set. */
+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 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
+ * register a check event. */
+static void expect_set(
+        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 CheckParameterValue check_function, const int count) {
+    CheckIntegerSet * const check_integer_set =
+        (CheckIntegerSet*)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_non_null(values);
+    assert_true(number_of_values);
+    memcpy(set, values, number_of_values * sizeof(values[0]));
+    check_integer_set->set = set;
+    check_integer_set->size_of_set = number_of_values;
+    _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 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 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 LargestIntegralType value,
+                          const LargestIntegralType check_value_data) {
+    CheckIntegerRange * const check_integer_range =
+        cast_largest_integral_type_to_pointer(CheckIntegerRange*,
+                                              check_value_data);
+    assert_non_null(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 LargestIntegralType value,
+                              const LargestIntegralType check_value_data) {
+    CheckIntegerRange * const check_integer_range =
+        cast_largest_integral_type_to_pointer(CheckIntegerRange*,
+                                              check_value_data);
+    assert_non_null(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
+ * register a check event. */
+static void expect_range(
+        const char* const function, const char* const parameter,
+        const char* const file, const int line,
+        const LargestIntegralType minimum, const LargestIntegralType maximum,
+        const CheckParameterValue check_function, const int count) {
+    CheckIntegerRange * const check_integer_range =
+        (CheckIntegerRange*)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);
+}
+
+
+/* Add an event to determine whether a parameter is within a range. */
+void _expect_in_range(
+        const char* const function, const char* const parameter,
+        const char* const file, const int line,
+        const LargestIntegralType minimum, const LargestIntegralType maximum,
+        const int count) {
+    expect_range(function, parameter, file, line, minimum, maximum,
+                 check_in_range, count);
+}
+
+
+/* Add an event to determine whether a parameter is not within a range. */
+void _expect_not_in_range(
+        const char* const function, const char* const parameter,
+        const char* const file, const int line,
+        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
+ * expected value. */
+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 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
+ * expected value. */
+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 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 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));
+}
+
+
+/* Add an event to check whether a parameter is equal to a string. */
+void _expect_string(
+        const char* const function, const char* const parameter,
+        const char* const file, const int line, const char* string,
+        const int count) {
+    declare_initialize_value_pointer_pointer(string_pointer,
+                                             discard_const(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
+ * a string. */
+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));
+}
+
+
+/* Add an event to check whether a parameter is not equal to a string. */
+void _expect_not_string(
+        const char* const function, const char* const parameter,
+        const char* const file, const int line, const char* string,
+        const int count) {
+    declare_initialize_value_pointer_pointer(string_pointer,
+                                             discard_const(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 LargestIntegralType value,
+                        const LargestIntegralType check_value_data) {
+    CheckMemoryData * const check = cast_largest_integral_type_to_pointer(
+        CheckMemoryData*, check_value_data);
+    assert_non_null(check);
+    return memory_equal_display_error(
+        cast_largest_integral_type_to_pointer(const char*, value),
+        (const char*)check->memory, check->size);
+}
+
+
+/* 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 =
+        (CheckMemoryData*)malloc(sizeof(*check_data) + size);
+    void * const mem = (void*)(check_data + 1);
+    declare_initialize_value_pointer_pointer(check_data_pointer, check_data);
+    assert_non_null(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);
+}
+
+
+/* Add an event to check whether a parameter matches an area of memory. */
+void _expect_memory(
+        const char* const function, const char* const parameter,
+        const char* const file, const int line, const void* const memory,
+        const size_t size, const int count) {
+    expect_memory_setup(function, parameter, file, line, memory, size,
+                        check_memory, count);
+}
+
+
+/* CheckParameterValue callback to check whether a parameter is not equal to
+ * an area of memory. */
+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_non_null(check);
+    return memory_not_equal_display_error(
+        cast_largest_integral_type_to_pointer(const char*, value),
+        (const char*)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 size_t size, const int 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 LargestIntegralType value,
+                     const LargestIntegralType check_value_data) {
+    (void)value;
+    (void)check_value_data;
+    return 1;
+}
+
+
+/* Add an event to allow any value for a parameter. */
+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, 0, NULL,
+                  count);
+}
+
+
+void _check_expected(
+        const char * const function_name, const char * const parameter_name,
+        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) {
+            cm_print_error(SOURCE_LOCATION_FORMAT
+                           ": error: Check of parameter %s, function %s failed\n"
+                           SOURCE_LOCATION_FORMAT
+                           ": note: Expected parameter declared here\n",
+                           file, line,
+                           parameter_name, function_name,
+                           global_last_parameter_location.file,
+                           global_last_parameter_location.line);
+            _fail(file, line);
+        }
+    } else {
+        cm_print_error(SOURCE_LOCATION_FORMAT ": error: 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)) {
+            cm_print_error(SOURCE_LOCATION_FORMAT
+                        ": note: Previously declared parameter value was declared here\n",
+                        global_last_parameter_location.file,
+                        global_last_parameter_location.line);
+        } else {
+            cm_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,
+                 const char* const file, const int line) {
+    if (!result) {
+        if (global_expecting_assert) {
+            global_last_failed_assert = expression;
+            longjmp(global_expect_assert_env, result);
+        } else {
+            cm_print_error("ASSERT: %s\n", expression);
+            _fail(file, line);
+        }
+    }
+}
+
+
+void _assert_true(const LargestIntegralType result,
+                  const char * const expression,
+                  const char * const file, const int line) {
+    if (!result) {
+        cm_print_error("%s\n", expression);
+        _fail(file, line);
+    }
+}
+
+void _assert_return_code(const LargestIntegralType result,
+                         size_t rlen,
+                         const LargestIntegralType error,
+                         const char * const expression,
+                         const char * const file,
+                         const int line)
+{
+    LargestIntegralType valmax;
+
+
+    switch (rlen) {
+    case 1:
+        valmax = 255;
+        break;
+    case 2:
+        valmax = 32767;
+        break;
+    case 4:
+        valmax = 2147483647;
+        break;
+    case 8:
+    default:
+        if (rlen > sizeof(valmax)) {
+            valmax = 2147483647;
+        } else {
+            valmax = 9223372036854775807L;
+        }
+        break;
+    }
+
+    if (result > valmax - 1) {
+        if (error > 0) {
+            cm_print_error("%s < 0, errno("
+                           LargestIntegralTypePrintfFormatDecimal "): %s\n",
+                           expression, error, strerror((int)error));
+        } else {
+            cm_print_error("%s < 0\n", expression);
+        }
+        _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 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,
+                          const char * const file, const int line) {
+    if (!string_equal_display_error(a, b)) {
+        _fail(file, line);
+    }
+}
+
+
+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);
+    }
+}
+
+
+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);
+    }
+}
+
+
+void _assert_memory_not_equal(const void * const a, const void * const b,
+                              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);
+    }
+}
+
+
+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 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 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);
+    }
+}
+
+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);
+    }
+}
+
+
+/* Get the list of allocated blocks. */
+static ListNode* get_allocated_blocks_list(void) {
+    /* 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;
+}
+
+static void *libc_malloc(size_t size)
+{
+#undef malloc
+    return malloc(size);
+#define malloc test_malloc
+}
+
+static void libc_free(void *ptr)
+{
+#undef free
+    free(ptr);
+#define free test_free
+}
+
+static void *libc_realloc(void *ptr, size_t size)
+{
+#undef realloc
+    return realloc(ptr, size);
+#define realloc test_realloc
+}
+
+static void vcm_print_error(const char* const format,
+                            va_list args) CMOCKA_PRINTF_ATTRIBUTE(1, 0);
+
+/* It's important to use the libc malloc and free here otherwise
+ * the automatic free of leaked blocks can reap the error messages
+ */
+static void vcm_print_error(const char* const format, va_list args)
+{
+    char buffer[1024];
+    size_t msg_len = 0;
+    va_list ap;
+    int len;
+    va_copy(ap, args);
+
+    len = vsnprintf(buffer, sizeof(buffer), format, args);
+    if (len < 0) {
+        /* TODO */
+        goto end;
+    }
+
+    if (cm_error_message == NULL) {
+        /* CREATE MESSAGE */
+
+        cm_error_message = libc_malloc(len + 1);
+        if (cm_error_message == NULL) {
+            /* TODO */
+            goto end;
+        }
+    } else {
+        /* APPEND MESSAGE */
+        char *tmp;
+
+        msg_len = strlen(cm_error_message);
+        tmp = libc_realloc(cm_error_message, msg_len + len + 1);
+        if (tmp == NULL) {
+            goto end;
+        }
+        cm_error_message = tmp;
+    }
+
+    if (((size_t)len) < sizeof(buffer)) {
+        /* Use len + 1 to also copy '\0' */
+        memcpy(cm_error_message + msg_len, buffer, len + 1);
+    } else {
+        vsnprintf(cm_error_message + msg_len, len, format, ap);
+    }
+end:
+    va_end(ap);
+
+}
+
+static void vcm_free_error(char *err_msg)
+{
+    libc_free(err_msg);
+}
+
+/* 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_non_null(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,
+                   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;
+}
+
+
+/* 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 = discard_const_p(char, ptr);
+    MallocBlockInfo *block_info;
+
+    if (ptr == NULL) {
+        return;
+    }
+
+    _assert_true(cast_ptr_to_largest_integral_type(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_SIZE(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) {
+                    cm_print_error(SOURCE_LOCATION_FORMAT
+                                   ": error: Guard block of %p size=%lu is corrupt\n"
+                                   SOURCE_LOCATION_FORMAT ": note: allocated here at %p\n",
+                                   file, line,
+                                   ptr, (unsigned long)block_info->size,
+                                   block_info->location.file, block_info->location.line,
+                                   (void *)&guard[j]);
+                    _fail(file, line);
+                }
+            }
+        }
+    }
+    list_remove(&block_info->node, NULL, NULL);
+
+    block = discard_const_p(char, block_info->block);
+    memset(block, MALLOC_FREE_PATTERN, block_info->allocated_size);
+    free(block);
+}
+#define free test_free
+
+#undef realloc
+void *_test_realloc(void *ptr,
+                   const size_t size,
+                   const char *file,
+                   const int line)
+{
+    MallocBlockInfo *block_info;
+    char *block = ptr;
+    size_t block_size = size;
+    void *new_block;
+
+    if (ptr == NULL) {
+        return _test_malloc(size, file, line);
+    }
+
+    if (size == 0) {
+        _test_free(ptr, file, line);
+        return NULL;
+    }
+
+    block_info = (MallocBlockInfo*)(block - (MALLOC_GUARD_SIZE +
+                                             sizeof(*block_info)));
+
+    new_block = _test_malloc(size, file, line);
+    if (new_block == NULL) {
+        return NULL;
+    }
+
+    if (block_info->size < size) {
+        block_size = block_info->size;
+    }
+
+    memcpy(new_block, ptr, block_size);
+
+    /* Free previous memory */
+    _test_free(ptr, file, line);
+
+    return new_block;
+}
+#define realloc test_realloc
+
+/* Crudely checkpoint the current heap state. */
+static const ListNode* check_point_allocated_blocks(void) {
+    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_non_null(check_point);
+    assert_non_null(check_point->next);
+
+    for (node = check_point->next; node != head; node = node->next) {
+        const MallocBlockInfo * const block_info =
+            (const MallocBlockInfo*)node->value;
+        assert_non_null(block_info);
+
+        if (!allocated_blocks) {
+            cm_print_error("Blocks allocated...\n");
+        }
+        cm_print_error(SOURCE_LOCATION_FORMAT ": note: block %p allocated here\n",
+                       block_info->location.file,
+                       block_info->location.line,
+                       block_info->block);
+        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_non_null(check_point);
+
+    node = check_point->next;
+    assert_non_null(node);
+
+    while (node != head) {
+        MallocBlockInfo * const block_info = (MallocBlockInfo*)node->value;
+        node = node->next;
+        free(discard_const_p(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);
+        cm_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) {
+    enum cm_message_output output = cm_get_output();
+
+    switch(output) {
+        case CM_OUTPUT_STDOUT:
+            cm_print_error("[   LINE   ] --- " SOURCE_LOCATION_FORMAT ": error: Failure!", file, line);
+            break;
+        default:
+            cm_print_error(SOURCE_LOCATION_FORMAT ": error: Failure!", file, line);
+            break;
+    }
+    exit_test(1);
+}
+
+
+#ifndef _WIN32
+static void exception_handler(int sig) {
+    const char *sig_strerror = "";
+
+#ifdef HAVE_STRSIGNAL
+    sig_strerror = strsignal(sig);
+#endif
+
+    cm_print_error("Test failed with exception: %s(%d)",
+                   sig_strerror, 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_SIZE(exception_codes); i++) {
+        const ExceptionCodeInfo * const code_info = &exception_codes[i];
+        if (code == code_info->code) {
+            static int shown_debug_message = 0;
+            fflush(stdout);
+            cm_print_error("%s occurred at %p.\n", code_info->description,
+                        exception_record->ExceptionAddress);
+            if (!shown_debug_message) {
+                cm_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 */
+
+void cm_print_error(const char * const format, ...)
+{
+    va_list args;
+    va_start(args, format);
+    if (cm_error_message_enabled) {
+        vcm_print_error(format, args);
+    } else {
+        vprint_error(format, args);
+    }
+    va_end(args);
+}
+
+/* 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("%s", buffer);
+    fflush(stdout);
+#ifdef _WIN32
+    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, "%s", buffer);
+    fflush(stderr);
+#ifdef _WIN32
+    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);
+}
+
+
+void print_error(const char* const format, ...) {
+    va_list args;
+    va_start(args, format);
+    vprint_error(format, args);
+    va_end(args);
+}
+
+/* New formatter */
+static enum cm_message_output cm_get_output(void)
+{
+    enum cm_message_output output = global_msg_output;
+    char *env;
+
+    env = getenv("CMOCKA_MESSAGE_OUTPUT");
+    if (env != NULL) {
+        if (strcasecmp(env, "STDOUT") == 0) {
+            output = CM_OUTPUT_STDOUT;
+        } else if (strcasecmp(env, "SUBUNIT") == 0) {
+            output = CM_OUTPUT_SUBUNIT;
+        } else if (strcasecmp(env, "TAP") == 0) {
+            output = CM_OUTPUT_TAP;
+        } else if (strcasecmp(env, "XML") == 0) {
+            output = CM_OUTPUT_XML;
+        }
+    }
+
+    return output;
+}
+
+enum cm_printf_type {
+    PRINTF_TEST_START,
+    PRINTF_TEST_SUCCESS,
+    PRINTF_TEST_FAILURE,
+    PRINTF_TEST_ERROR,
+    PRINTF_TEST_SKIPPED,
+};
+
+static int xml_printed;
+static int file_append;
+
+static void cmprintf_group_finish_xml(const char *group_name,
+                                      size_t total_executed,
+                                      size_t total_failed,
+                                      size_t total_errors,
+                                      size_t total_skipped,
+                                      double total_runtime,
+                                      struct CMUnitTestState *cm_tests)
+{
+    FILE *fp = stdout;
+    int file_opened = 0;
+    int multiple_files = 0;
+    char *env;
+    size_t i;
+
+    env = getenv("CMOCKA_XML_FILE");
+    if (env != NULL) {
+        char buf[1024];
+        int rc;
+
+        snprintf(buf, sizeof(buf), "%s", env);
+
+        rc = c_strreplace(buf, sizeof(buf), "%g", group_name, &multiple_files);
+        if (rc < 0) {
+            snprintf(buf, sizeof(buf), "%s", env);
+        }
+
+        fp = fopen(buf, "r");
+        if (fp == NULL) {
+            fp = fopen(buf, "w");
+            if (fp != NULL) {
+                file_append = 1;
+                file_opened = 1;
+            } else {
+                fp = stderr;
+            }
+        } else {
+            fclose(fp);
+            if (file_append) {
+                fp = fopen(buf, "a");
+                if (fp != NULL) {
+                    file_opened = 1;
+                    xml_printed = 1;
+                } else {
+                    fp = stderr;
+                }
+            } else {
+                fp = stderr;
+            }
+        }
+    }
+
+    if (!xml_printed || (file_opened && !file_append)) {
+        fprintf(fp, "<?xml version=\"1.0\" encoding=\"UTF-8\" ?>\n");
+        if (!file_opened) {
+            xml_printed = 1;
+        }
+    }
+
+    fprintf(fp, "<testsuites>\n");
+    fprintf(fp, "  <testsuite name=\"%s\" time=\"%.3f\" "
+                "tests=\"%u\" failures=\"%u\" errors=\"%u\" skipped=\"%u\" >\n",
+                group_name,
+                total_runtime, /* seconds */
+                (unsigned)total_executed,
+                (unsigned)total_failed,
+                (unsigned)total_errors,
+                (unsigned)total_skipped);
+
+    for (i = 0; i < total_executed; i++) {
+        struct CMUnitTestState *cmtest = &cm_tests[i];
+
+        fprintf(fp, "    <testcase name=\"%s\" time=\"%.3f\" >\n",
+                cmtest->test->name, cmtest->runtime);
+
+        switch (cmtest->status) {
+        case CM_TEST_ERROR:
+        case CM_TEST_FAILED:
+            if (cmtest->error_message != NULL) {
+                fprintf(fp, "      <failure><![CDATA[%s]]></failure>\n",
+                        cmtest->error_message);
+            } else {
+                fprintf(fp, "      <failure message=\"Unknown error\" />\n");
+            }
+            break;
+        case CM_TEST_SKIPPED:
+            fprintf(fp, "      <skipped/>\n");
+            break;
+
+        case CM_TEST_PASSED:
+        case CM_TEST_NOT_STARTED:
+            break;
+        }
+
+        fprintf(fp, "    </testcase>\n");
+    }
+
+    fprintf(fp, "  </testsuite>\n");
+    fprintf(fp, "</testsuites>\n");
+
+    if (file_opened) {
+        fclose(fp);
+    }
+}
+
+static void cmprintf_group_start_standard(const size_t num_tests)
+{
+    print_message("[==========] Running %u test(s).\n",
+                  (unsigned)num_tests);
+}
+
+static void cmprintf_group_finish_standard(size_t total_executed,
+                                           size_t total_passed,
+                                           size_t total_failed,
+                                           size_t total_errors,
+                                           size_t total_skipped,
+                                           struct CMUnitTestState *cm_tests)
+{
+    size_t i;
+
+    print_message("[==========] %u test(s) run.\n", (unsigned)total_executed);
+    print_error("[  PASSED  ] %u test(s).\n",
+                (unsigned)(total_passed));
+
+    if (total_skipped) {
+        print_error("[  SKIPPED ] %"PRIdS " test(s), listed below:\n", total_skipped);
+        for (i = 0; i < total_executed; i++) {
+            struct CMUnitTestState *cmtest = &cm_tests[i];
+
+            if (cmtest->status == CM_TEST_SKIPPED) {
+                print_error("[  SKIPPED ] %s\n", cmtest->test->name);
+            }
+        }
+        print_error("\n %u SKIPPED TEST(S)\n", (unsigned)(total_skipped));
+    }
+
+    if (total_failed) {
+        print_error("[  FAILED  ] %"PRIdS " test(s), listed below:\n", total_failed);
+        for (i = 0; i < total_executed; i++) {
+            struct CMUnitTestState *cmtest = &cm_tests[i];
+
+            if (cmtest->status == CM_TEST_FAILED) {
+                print_error("[  FAILED  ] %s\n", cmtest->test->name);
+            }
+        }
+        print_error("\n %u FAILED TEST(S)\n",
+                    (unsigned)(total_failed + total_errors));
+    }
+}
+
+static void cmprintf_standard(enum cm_printf_type type,
+                              const char *test_name,
+                              const char *error_message)
+{
+    switch (type) {
+    case PRINTF_TEST_START:
+        print_message("[ RUN      ] %s\n", test_name);
+        break;
+    case PRINTF_TEST_SUCCESS:
+        print_message("[       OK ] %s\n", test_name);
+        break;
+    case PRINTF_TEST_FAILURE:
+        if (error_message != NULL) {
+            print_error("[  ERROR   ] --- %s\n", error_message);
+        }
+        print_message("[  FAILED  ] %s\n", test_name);
+        break;
+    case PRINTF_TEST_SKIPPED:
+        print_message("[  SKIPPED ] %s\n", test_name);
+        break;
+    case PRINTF_TEST_ERROR:
+        if (error_message != NULL) {
+            print_error("%s\n", error_message);
+        }
+        print_error("[  ERROR   ] %s\n", test_name);
+        break;
+    }
+}
+
+static void cmprintf_group_start_tap(const size_t num_tests)
+{
+    print_message("1..%u\n", (unsigned)num_tests);
+}
+
+static void cmprintf_group_finish_tap(const char *group_name,
+                                      size_t total_executed,
+                                      size_t total_passed,
+                                      size_t total_skipped)
+{
+    const char *status = "not ok";
+    if (total_passed + total_skipped == total_executed) {
+        status = "ok";
+    }
+    print_message("# %s - %s\n", status, group_name);
+}
+
+static void cmprintf_tap(enum cm_printf_type type,
+                         uint32_t test_number,
+                         const char *test_name,
+                         const char *error_message)
+{
+    switch (type) {
+    case PRINTF_TEST_START:
+        break;
+    case PRINTF_TEST_SUCCESS:
+        print_message("ok %u - %s\n", (unsigned)test_number, test_name);
+        break;
+    case PRINTF_TEST_FAILURE:
+        print_message("not ok %u - %s\n", (unsigned)test_number, test_name);
+        if (error_message != NULL) {
+            char *msg;
+            char *p;
+
+            msg = strdup(error_message);
+            if (msg == NULL) {
+                return;
+            }
+            p = msg;
+
+            while (p[0] != '\0') {
+                char *q = p;
+
+                p = strchr(q, '\n');
+                if (p != NULL) {
+                    p[0] = '\0';
+                }
+
+                print_message("# %s\n", q);
+
+                if (p == NULL) {
+                    break;
+                }
+                p++;
+            }
+            libc_free(msg);
+        }
+        break;
+    case PRINTF_TEST_SKIPPED:
+        print_message("not ok %u # SKIP %s\n", (unsigned)test_number, test_name);
+        break;
+    case PRINTF_TEST_ERROR:
+        print_message("not ok %u - %s %s\n",
+                      (unsigned)test_number, test_name, error_message);
+        break;
+    }
+}
+
+static void cmprintf_subunit(enum cm_printf_type type,
+                             const char *test_name,
+                             const char *error_message)
+{
+    switch (type) {
+    case PRINTF_TEST_START:
+        print_message("test: %s\n", test_name);
+        break;
+    case PRINTF_TEST_SUCCESS:
+        print_message("success: %s\n", test_name);
+        break;
+    case PRINTF_TEST_FAILURE:
+        print_message("failure: %s", test_name);
+        if (error_message != NULL) {
+            print_message(" [\n%s]\n", error_message);
+        }
+        break;
+    case PRINTF_TEST_SKIPPED:
+        print_message("skip: %s\n", test_name);
+        break;
+    case PRINTF_TEST_ERROR:
+        print_message("error: %s [ %s ]\n", test_name, error_message);
+        break;
+    }
+}
+
+static void cmprintf_group_start(const size_t num_tests)
+{
+    enum cm_message_output output;
+
+    output = cm_get_output();
+
+    switch (output) {
+    case CM_OUTPUT_STDOUT:
+        cmprintf_group_start_standard(num_tests);
+        break;
+    case CM_OUTPUT_SUBUNIT:
+        break;
+    case CM_OUTPUT_TAP:
+        cmprintf_group_start_tap(num_tests);
+        break;
+    case CM_OUTPUT_XML:
+        break;
+    }
+}
+
+static void cmprintf_group_finish(const char *group_name,
+                                  size_t total_executed,
+                                  size_t total_passed,
+                                  size_t total_failed,
+                                  size_t total_errors,
+                                  size_t total_skipped,
+                                  double total_runtime,
+                                  struct CMUnitTestState *cm_tests)
+{
+    enum cm_message_output output;
+
+    output = cm_get_output();
+
+    switch (output) {
+    case CM_OUTPUT_STDOUT:
+        cmprintf_group_finish_standard(total_executed,
+                                    total_passed,
+                                    total_failed,
+                                    total_errors,
+                                    total_skipped,
+                                    cm_tests);
+        break;
+    case CM_OUTPUT_SUBUNIT:
+        break;
+    case CM_OUTPUT_TAP:
+        cmprintf_group_finish_tap(group_name, total_executed, total_passed, total_skipped);
+        break;
+    case CM_OUTPUT_XML:
+        cmprintf_group_finish_xml(group_name,
+                                  total_executed,
+                                  total_failed,
+                                  total_errors,
+                                  total_skipped,
+                                  total_runtime,
+                                  cm_tests);
+        break;
+    }
+}
+
+static void cmprintf(enum cm_printf_type type,
+                     size_t test_number,
+                     const char *test_name,
+                     const char *error_message)
+{
+    enum cm_message_output output;
+
+    output = cm_get_output();
+
+    switch (output) {
+    case CM_OUTPUT_STDOUT:
+        cmprintf_standard(type, test_name, error_message);
+        break;
+    case CM_OUTPUT_SUBUNIT:
+        cmprintf_subunit(type, test_name, error_message);
+        break;
+    case CM_OUTPUT_TAP:
+        cmprintf_tap(type, test_number, test_name, error_message);
+        break;
+    case CM_OUTPUT_XML:
+        break;
+    }
+}
+
+void cmocka_set_message_output(enum cm_message_output output)
+{
+    global_msg_output = output;
+}
+
+/****************************************************************************
+ * TIME CALCULATIONS
+ ****************************************************************************/
+
+#ifdef HAVE_STRUCT_TIMESPEC
+static struct timespec cm_tspecdiff(struct timespec time1,
+                                    struct timespec time0)
+{
+    struct timespec ret;
+    int xsec = 0;
+    int sign = 1;
+
+    if (time0.tv_nsec > time1.tv_nsec) {
+        xsec = (int) ((time0.tv_nsec - time1.tv_nsec) / (1E9 + 1));
+        time0.tv_nsec -= (long int) (1E9 * xsec);
+        time0.tv_sec += xsec;
+    }
+
+    if ((time1.tv_nsec - time0.tv_nsec) > 1E9) {
+        xsec = (int) ((time1.tv_nsec - time0.tv_nsec) / 1E9);
+        time0.tv_nsec += (long int) (1E9 * xsec);
+        time0.tv_sec -= xsec;
+    }
+
+    ret.tv_sec = time1.tv_sec - time0.tv_sec;
+    ret.tv_nsec = time1.tv_nsec - time0.tv_nsec;
+
+    if (time1.tv_sec < time0.tv_sec) {
+        sign = -1;
+    }
+
+    ret.tv_sec = ret.tv_sec * sign;
+
+    return ret;
+}
+
+static double cm_secdiff(struct timespec clock1, struct timespec clock0)
+{
+    double ret;
+    struct timespec diff;
+
+    diff = cm_tspecdiff(clock1, clock0);
+
+    ret = diff.tv_sec;
+    ret += (double) diff.tv_nsec / (double) 1E9;
+
+    return ret;
+}
+#endif /* HAVE_STRUCT_TIMESPEC */
+
+/****************************************************************************
+ * CMOCKA TEST RUNNER
+ ****************************************************************************/
+static int cmocka_run_one_test_or_fixture(const char *function_name,
+                                          CMUnitTestFunction test_func,
+                                          CMFixtureFunction setup_func,
+                                          CMFixtureFunction teardown_func,
+                                          void ** const volatile state,
+                                          const void *const heap_check_point)
+{
+    const ListNode * const volatile check_point = (const ListNode*)
+        (heap_check_point != NULL ?
+         heap_check_point : check_point_allocated_blocks());
+    int handle_exceptions = 1;
+    void *current_state = NULL;
+    int rc = 0;
+
+    /* FIXME check only one test or fixture is set */
+
+    /* Detect if we should handle exceptions */
+#ifdef _WIN32
+    handle_exceptions = !IsDebuggerPresent();
+#endif /* _WIN32 */
+#ifdef UNIT_TESTING_DEBUG
+    handle_exceptions = 0;
+#endif /* UNIT_TESTING_DEBUG */
+
+
+    if (handle_exceptions) {
+#ifndef _WIN32
+        unsigned int i;
+        for (i = 0; i < ARRAY_SIZE(exception_signals); i++) {
+            default_signal_functions[i] = signal(
+                    exception_signals[i], exception_handler);
+        }
+#else /* _WIN32 */
+        previous_exception_filter = SetUnhandledExceptionFilter(
+                exception_filter);
+#endif /* !_WIN32 */
+    }
+
+    /* Init the test structure */
+    initialize_testing(function_name);
+
+    global_running_test = 1;
+
+    if (cm_setjmp(global_run_test_env) == 0) {
+        if (test_func != NULL) {
+            test_func(state != NULL ? state : &current_state);
+
+            fail_if_blocks_allocated(check_point, function_name);
+            rc = 0;
+        } else if (setup_func != NULL) {
+            rc = setup_func(state != NULL ? state : &current_state);
+
+            /*
+             * For setup we can ignore any allocated blocks. We just need to
+             * ensure they're deallocated on tear down.
+             */
+        } else if (teardown_func != NULL) {
+            rc = teardown_func(state != NULL ? state : &current_state);
+
+            fail_if_blocks_allocated(check_point, function_name);
+        } else {
+            /* ERROR */
+        }
+        fail_if_leftover_values(function_name);
+        global_running_test = 0;
+    } else {
+        /* TEST FAILED */
+        global_running_test = 0;
+        rc = -1;
+    }
+    teardown_testing(function_name);
+
+    if (handle_exceptions) {
+#ifndef _WIN32
+        unsigned int i;
+        for (i = 0; i < ARRAY_SIZE(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;
+        }
+#endif /* !_WIN32 */
+    }
+
+    return rc;
+}
+
+static int cmocka_run_group_fixture(const char *function_name,
+                                    CMFixtureFunction setup_func,
+                                    CMFixtureFunction teardown_func,
+                                    void **state,
+                                    const void *const heap_check_point)
+{
+    int rc;
+
+    if (setup_func != NULL) {
+        rc = cmocka_run_one_test_or_fixture(function_name,
+                                        NULL,
+                                        setup_func,
+                                        NULL,
+                                        state,
+                                        heap_check_point);
+    } else {
+        rc = cmocka_run_one_test_or_fixture(function_name,
+                                        NULL,
+                                        NULL,
+                                        teardown_func,
+                                        state,
+                                        heap_check_point);
+    }
+
+    return rc;
+}
+
+static int cmocka_run_one_tests(struct CMUnitTestState *test_state)
+{
+#ifdef HAVE_STRUCT_TIMESPEC
+    struct timespec start = {
+        .tv_sec = 0,
+        .tv_nsec = 0,
+    };
+    struct timespec finish = {
+        .tv_sec = 0,
+        .tv_nsec = 0,
+    };
+#endif
+    int rc = 0;
+
+    /* Run setup */
+    if (test_state->test->setup_func != NULL) {
+        /* Setup the memory check point, it will be evaluated on teardown */
+        test_state->check_point = check_point_allocated_blocks();
+
+        rc = cmocka_run_one_test_or_fixture(test_state->test->name,
+                                            NULL,
+                                            test_state->test->setup_func,
+                                            NULL,
+                                            &test_state->state,
+                                            test_state->check_point);
+        if (rc != 0) {
+            test_state->status = CM_TEST_ERROR;
+            cm_print_error("Test setup failed");
+        }
+    }
+
+    /* Run test */
+#ifdef HAVE_STRUCT_TIMESPEC
+    CMOCKA_CLOCK_GETTIME(CLOCK_REALTIME, &start);
+#endif
+
+    if (rc == 0) {
+        rc = cmocka_run_one_test_or_fixture(test_state->test->name,
+                                            test_state->test->test_func,
+                                            NULL,
+                                            NULL,
+                                            &test_state->state,
+                                            NULL);
+        if (rc == 0) {
+            test_state->status = CM_TEST_PASSED;
+        } else {
+            if (global_skip_test) {
+                test_state->status = CM_TEST_SKIPPED;
+                global_skip_test = 0; /* Do not skip the next test */
+            } else {
+                test_state->status = CM_TEST_FAILED;
+            }
+        }
+        rc = 0;
+    }
+
+    test_state->runtime = 0.0;
+
+#ifdef HAVE_STRUCT_TIMESPEC
+    CMOCKA_CLOCK_GETTIME(CLOCK_REALTIME, &finish);
+    test_state->runtime = cm_secdiff(finish, start);
+#endif
+
+    /* Run teardown */
+    if (rc == 0 && test_state->test->teardown_func != NULL) {
+        rc = cmocka_run_one_test_or_fixture(test_state->test->name,
+                                            NULL,
+                                            NULL,
+                                            test_state->test->teardown_func,
+                                            &test_state->state,
+                                            test_state->check_point);
+        if (rc != 0) {
+            test_state->status = CM_TEST_ERROR;
+            cm_print_error("Test teardown failed");
+        }
+    }
+
+    test_state->error_message = cm_error_message;
+    cm_error_message = NULL;
+
+    return rc;
+}
+
+int _cmocka_run_group_tests(const char *group_name,
+                            const struct CMUnitTest * const tests,
+                            const size_t num_tests,
+                            CMFixtureFunction group_setup,
+                            CMFixtureFunction group_teardown)
+{
+    struct CMUnitTestState *cm_tests;
+    const ListNode *group_check_point = check_point_allocated_blocks();
+    void *group_state = NULL;
+    size_t total_tests = 0;
+    size_t total_failed = 0;
+    size_t total_passed = 0;
+    size_t total_executed = 0;
+    size_t total_errors = 0;
+    size_t total_skipped = 0;
+    double total_runtime = 0;
+    size_t i;
+    int rc;
+
+    /* Make sure LargestIntegralType is at least the size of a pointer. */
+    assert_true(sizeof(LargestIntegralType) >= sizeof(void*));
+
+    cm_tests = (struct CMUnitTestState *)libc_malloc(sizeof(struct CMUnitTestState) * num_tests);
+    if (cm_tests == NULL) {
+        return -1;
+    }
+
+    /* Setup cmocka test array */
+    for (i = 0; i < num_tests; i++) {
+        if (tests[i].name != NULL &&
+            (tests[i].test_func != NULL
+             || tests[i].setup_func != NULL
+             || tests[i].teardown_func != NULL)) {
+            cm_tests[i] = (struct CMUnitTestState) {
+                .test = &tests[i],
+                .status = CM_TEST_NOT_STARTED,
+                .state = NULL,
+            };
+            total_tests++;
+        }
+    }
+
+    cmprintf_group_start(total_tests);
+
+    rc = 0;
+
+    /* Run group setup */
+    if (group_setup != NULL) {
+        rc = cmocka_run_group_fixture("cmocka_group_setup",
+                                      group_setup,
+                                      NULL,
+                                      &group_state,
+                                      group_check_point);
+    }
+
+    if (rc == 0) {
+        /* Execute tests */
+        for (i = 0; i < total_tests; i++) {
+            struct CMUnitTestState *cmtest = &cm_tests[i];
+            size_t test_number = i + 1;
+
+            cmprintf(PRINTF_TEST_START, test_number, cmtest->test->name, NULL);
+
+            if (group_state != NULL) {
+                cmtest->state = group_state;
+            } else if (cmtest->test->initial_state  != NULL) {
+                cmtest->state = cmtest->test->initial_state;
+            }
+
+            rc = cmocka_run_one_tests(cmtest);
+            total_executed++;
+            total_runtime += cmtest->runtime;
+            if (rc == 0) {
+                switch (cmtest->status) {
+                    case CM_TEST_PASSED:
+                        cmprintf(PRINTF_TEST_SUCCESS,
+                                 test_number,
+                                 cmtest->test->name,
+                                 cmtest->error_message);
+                        total_passed++;
+                        break;
+                    case CM_TEST_SKIPPED:
+                        cmprintf(PRINTF_TEST_SKIPPED,
+                                 test_number,
+                                 cmtest->test->name,
+                                 cmtest->error_message);
+                        total_skipped++;
+                        break;
+                    case CM_TEST_FAILED:
+                        cmprintf(PRINTF_TEST_FAILURE,
+                                 test_number,
+                                 cmtest->test->name,
+                                 cmtest->error_message);
+                        total_failed++;
+                        break;
+                    default:
+                        cmprintf(PRINTF_TEST_ERROR,
+                                 test_number,
+                                 cmtest->test->name,
+                                 "Internal cmocka error");
+                        total_errors++;
+                        break;
+                }
+            } else {
+                cmprintf(PRINTF_TEST_ERROR,
+                         test_number,
+                         cmtest->test->name,
+                         "Could not run the test - check test fixtures");
+                total_errors++;
+            }
+        }
+    } else {
+        if (cm_error_message != NULL) {
+            print_error("[  ERROR   ] --- %s\n", cm_error_message);
+            vcm_free_error(cm_error_message);
+            cm_error_message = NULL;
+        }
+        cmprintf(PRINTF_TEST_ERROR, 0,
+                 group_name, "[  FAILED  ] GROUP SETUP");
+        total_errors++;
+    }
+
+    /* Run group teardown */
+    if (group_teardown != NULL) {
+        rc = cmocka_run_group_fixture("cmocka_group_teardown",
+                                      NULL,
+                                      group_teardown,
+                                      &group_state,
+                                      group_check_point);
+        if (rc != 0) {
+            if (cm_error_message != NULL) {
+                print_error("[  ERROR   ] --- %s\n", cm_error_message);
+                vcm_free_error(cm_error_message);
+                cm_error_message = NULL;
+            }
+            cmprintf(PRINTF_TEST_ERROR, 0,
+                     group_name, "[  FAILED  ] GROUP TEARDOWN");
+        }
+    }
+
+    cmprintf_group_finish(group_name,
+                          total_executed,
+                          total_passed,
+                          total_failed,
+                          total_errors,
+                          total_skipped,
+                          total_runtime,
+                          cm_tests);
+
+    for (i = 0; i < total_tests; i++) {
+        vcm_free_error(discard_const_p(char, cm_tests[i].error_message));
+    }
+    libc_free(cm_tests);
+    fail_if_blocks_allocated(group_check_point, "cmocka_group_tests");
+
+    return total_failed + total_errors;
+}
+
+/****************************************************************************
+ * DEPRECATED TEST RUNNER
+ ****************************************************************************/
+
+int _run_test(
+        const char * const function_name,  const UnitTestFunction Function,
+        void ** const volatile state, const UnitTestFunctionType function_type,
+        const void* const heap_check_point) {
+    const ListNode * const volatile check_point = (const ListNode*)
+        (heap_check_point ?
+         heap_check_point : check_point_allocated_blocks());
+    void *current_state = NULL;
+    volatile int rc = 1;
+    int handle_exceptions = 1;
+#ifdef _WIN32
+    handle_exceptions = !IsDebuggerPresent();
+#endif /* _WIN32 */
+#ifdef UNIT_TESTING_DEBUG
+    handle_exceptions = 0;
+#endif /* UNIT_TESTING_DEBUG */
+
+    cm_error_message_enabled = 0;
+
+    if (handle_exceptions) {
+#ifndef _WIN32
+        unsigned int i;
+        for (i = 0; i < ARRAY_SIZE(exception_signals); i++) {
+            default_signal_functions[i] = signal(
+                exception_signals[i], exception_handler);
+        }
+#else /* _WIN32 */
+        previous_exception_filter = SetUnhandledExceptionFilter(
+            exception_filter);
+#endif /* !_WIN32 */
+    }
+
+    if (function_type == UNIT_TEST_FUNCTION_TYPE_TEST) {
+        print_message("[ RUN      ] %s\n", function_name);
+    }
+    initialize_testing(function_name);
+    global_running_test = 1;
+    if (cm_setjmp(global_run_test_env) == 0) {
+        Function(state ? state : &current_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("[       OK ] %s\n", function_name);
+        }
+        rc = 0;
+    } else {
+        global_running_test = 0;
+        print_message("[  FAILED  ] %s\n", function_name);
+    }
+    teardown_testing(function_name);
+
+    if (handle_exceptions) {
+#ifndef _WIN32
+        unsigned int i;
+        for (i = 0; i < ARRAY_SIZE(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;
+        }
+#endif /* !_WIN32 */
+    }
+
+    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;
+    /* Whether the previous setup failed. */
+    int previous_setup_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;
+    size_t i;
+    /*
+     * 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 =
+       (TestState*)malloc(number_of_tests * sizeof(*test_states));
+    /* The number of test states which should be 0 at the end */
+    long number_of_test_states = 0;
+    /* Names of the tests that failed. */
+    const char** failed_names = (const char**)malloc(number_of_tests *
+                                       sizeof(*failed_names));
+    void **current_state = NULL;
+
+    /* Count setup and teardown functions */
+    for (i = 0; i < number_of_tests; i++) {
+        const UnitTest * const test = &tests[i];
+
+        if (test->function_type == UNIT_TEST_FUNCTION_TYPE_SETUP) {
+            setups++;
+        }
+
+        if (test->function_type == UNIT_TEST_FUNCTION_TYPE_TEARDOWN) {
+            teardowns++;
+        }
+    }
+
+    print_message("[==========] Running %"PRIdS " test(s).\n",
+                  number_of_tests - setups - teardowns);
+
+    /* 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:
+            if (! previous_setup_failed) {
+                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 = &current_TestState->state;
+            *current_state = NULL;
+            run_next_test = 1;
+            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 = &current_TestState->state;
+            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_setup_failed = 1;
+                }
+                previous_test_failed = 0;
+                break;
+
+            case UNIT_TEST_FUNCTION_TYPE_TEARDOWN:
+                /* If this test failed. */
+                if (failed && !previous_test_failed) {
+                    total_failed ++;
+                }
+                break;
+            default:
+#ifndef _HPUX
+                assert_null("BUG: shouldn't be here!");
+#endif
+                break;
+            }
+        }
+    }
+
+    print_message("[==========] %"PRIdS " test(s) run.\n", tests_executed);
+    print_error("[  PASSED  ] %"PRIdS " test(s).\n", tests_executed - total_failed);
+
+    if (total_failed > 0) {
+        print_error("[  FAILED  ] %"PRIdS " test(s), listed below:\n", total_failed);
+        for (i = 0; i < total_failed; i++) {
+            print_error("[  FAILED  ] %s\n", failed_names[i]);
+        }
+    } else {
+        print_error("\n %"PRIdS " FAILED TEST(S)\n", total_failed);
+    }
+
+    if (number_of_test_states != 0) {
+        print_error("[  ERROR   ] Mismatched number of setup %"PRIdS " and "
+                    "teardown %"PRIdS " functions\n", setups, teardowns);
+        total_failed = (size_t)-1;
+    }
+
+    free(test_states);
+    free((void*)failed_names);
+
+    fail_if_blocks_allocated(check_point, "run_tests");
+    return (int)total_failed;
+}
+
+int _run_group_tests(const UnitTest * const tests, const size_t number_of_tests)
+{
+    UnitTestFunction setup = NULL;
+    const char *setup_name;
+    size_t num_setups = 0;
+    UnitTestFunction teardown = NULL;
+    const char *teardown_name;
+    size_t num_teardowns = 0;
+    size_t current_test = 0;
+    size_t i;
+
+    /* Number of tests executed. */
+    size_t tests_executed = 0;
+    /* Number of failed tests. */
+    size_t total_failed = 0;
+    /* Check point of the heap state. */
+    const ListNode * const check_point = check_point_allocated_blocks();
+    const char** failed_names = (const char**)malloc(number_of_tests *
+                                       sizeof(*failed_names));
+    void **current_state = NULL;
+    TestState group_state;
+
+    /* Find setup and teardown function */
+    for (i = 0; i < number_of_tests; i++) {
+        const UnitTest * const test = &tests[i];
+
+        if (test->function_type == UNIT_TEST_FUNCTION_TYPE_GROUP_SETUP) {
+            if (setup == NULL) {
+                setup = test->function;
+                setup_name = test->name;
+                num_setups = 1;
+            } else {
+                print_error("[  ERROR   ] More than one group setup function detected\n");
+                exit_test(1);
+            }
+        }
+
+        if (test->function_type == UNIT_TEST_FUNCTION_TYPE_GROUP_TEARDOWN) {
+            if (teardown == NULL) {
+                teardown = test->function;
+                teardown_name = test->name;
+                num_teardowns = 1;
+            } else {
+                print_error("[  ERROR   ] More than one group teardown function detected\n");
+                exit_test(1);
+            }
+        }
+    }
+
+    print_message("[==========] Running %"PRIdS " test(s).\n",
+                  number_of_tests - num_setups - num_teardowns);
+
+    if (setup != NULL) {
+        int failed;
+
+        group_state.check_point = check_point_allocated_blocks();
+        current_state = &group_state.state;
+        *current_state = NULL;
+        failed = _run_test(setup_name,
+                           setup,
+                           current_state,
+                           UNIT_TEST_FUNCTION_TYPE_SETUP,
+                           group_state.check_point);
+        if (failed) {
+            failed_names[total_failed] = setup_name;
+        }
+
+        total_failed += failed;
+        tests_executed++;
+    }
+
+    while (current_test < number_of_tests) {
+        int run_test = 0;
+        const UnitTest * const test = &tests[current_test++];
+        if (test->function == NULL) {
+            continue;
+        }
+
+        switch (test->function_type) {
+        case UNIT_TEST_FUNCTION_TYPE_TEST:
+            run_test = 1;
+            break;
+        case UNIT_TEST_FUNCTION_TYPE_SETUP:
+        case UNIT_TEST_FUNCTION_TYPE_TEARDOWN:
+        case UNIT_TEST_FUNCTION_TYPE_GROUP_SETUP:
+        case UNIT_TEST_FUNCTION_TYPE_GROUP_TEARDOWN:
+            break;
+        default:
+            print_error("Invalid unit test function type %d\n",
+                        test->function_type);
+            break;
+        }
+
+        if (run_test) {
+            int failed;
+
+            failed = _run_test(test->name,
+                               test->function,
+                               current_state,
+                               test->function_type,
+                               NULL);
+            if (failed) {
+                failed_names[total_failed] = test->name;
+            }
+
+            total_failed += failed;
+            tests_executed++;
+        }
+    }
+
+    if (teardown != NULL) {
+        int failed;
+
+        failed = _run_test(teardown_name,
+                           teardown,
+                           current_state,
+                           UNIT_TEST_FUNCTION_TYPE_GROUP_TEARDOWN,
+                           group_state.check_point);
+        if (failed) {
+            failed_names[total_failed] = teardown_name;
+        }
+
+        total_failed += failed;
+        tests_executed++;
+    }
+
+    print_message("[==========] %"PRIdS " test(s) run.\n", tests_executed);
+    print_error("[  PASSED  ] %"PRIdS " test(s).\n", tests_executed - total_failed);
+
+    if (total_failed) {
+        print_error("[  FAILED  ] %"PRIdS " test(s), listed below:\n", total_failed);
+        for (i = 0; i < total_failed; i++) {
+            print_error("[  FAILED  ] %s\n", failed_names[i]);
+        }
+    } else {
+        print_error("\n %"PRIdS " FAILED TEST(S)\n", total_failed);
+    }
+
+    free((void*)failed_names);
+    fail_if_blocks_allocated(check_point, "run_group_tests");
+
+    return (int)total_failed;
+}
diff --git a/third_party/cmocka/cmocka.h b/third_party/cmocka/cmocka.h
new file mode 100644
index 00000000000..72d6ae21c90
--- /dev/null
+++ b/third_party/cmocka/cmocka.h
@@ -0,0 +1,2284 @@
+/*
+ * Copyright 2008 Google Inc.
+ *
+ * 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.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#ifndef CMOCKA_H_
+#define CMOCKA_H_
+
+#ifdef _WIN32
+# ifdef _MSC_VER
+
+#define __func__ __FUNCTION__
+
+# ifndef inline
+#define inline __inline
+# endif /* inline */
+
+#  if _MSC_VER < 1500
+#   ifdef __cplusplus
+extern "C" {
+#   endif   /* __cplusplus */
+int __stdcall IsDebuggerPresent();
+#   ifdef __cplusplus
+} /* extern "C" */
+#   endif   /* __cplusplus */
+#  endif  /* _MSC_VER < 1500 */
+# endif /* _MSC_VER */
+#endif  /* _WIN32 */
+
+/**
+ * @defgroup cmocka The CMocka API
+ *
+ * These headers or their equivalents should be included prior to including
+ * this header file.
+ * @code
+ * #include <stdarg.h>
+ * #include <stddef.h>
+ * #include <setjmp.h>
+ * @endcode
+ *
+ * This allows test applications to use custom definitions of C standard
+ * library functions and types.
+ *
+ * @{
+ */
+
+/* If __WORDSIZE is not set, try to figure it out and default to 32 bit. */
+#ifndef __WORDSIZE
+# if defined(__x86_64__) && !defined(__ILP32__)
+#  define __WORDSIZE 64
+# else
+#  define __WORDSIZE 32
+# endif
+#endif
+
+#ifdef DOXYGEN
+/**
+ * Largest integral type.  This type should be large enough to hold any
+ * pointer or integer supported by the compiler.
+ */
+typedef uintmax_t LargestIntegralType;
+#else /* DOXGEN */
+#ifndef LargestIntegralType
+# if __WORDSIZE == 64 && !defined(_WIN64)
+#  define LargestIntegralType unsigned long int
+# else
+#  define LargestIntegralType unsigned long long int
+# endif
+#endif /* LargestIntegralType */
+#endif /* DOXYGEN */
+
+/* Printf format used to display LargestIntegralType as a hexidecimal. */
+#ifndef LargestIntegralTypePrintfFormat
+# ifdef _WIN32
+#  define LargestIntegralTypePrintfFormat "0x%I64x"
+# else
+#  if __WORDSIZE == 64
+#   define LargestIntegralTypePrintfFormat "%#lx"
+#  else
+#   define LargestIntegralTypePrintfFormat "%#llx"
+#  endif
+# endif /* _WIN32 */
+#endif /* LargestIntegralTypePrintfFormat */
+
+/* Printf format used to display LargestIntegralType as a decimal. */
+#ifndef LargestIntegralTypePrintfFormatDecimal
+# ifdef _WIN32
+#  define LargestIntegralTypePrintfFormatDecimal "%I64u"
+# else
+#  if __WORDSIZE == 64
+#   define LargestIntegralTypePrintfFormatDecimal "%lu"
+#  else
+#   define LargestIntegralTypePrintfFormatDecimal "%llu"
+#  endif
+# endif /* _WIN32 */
+#endif /* LargestIntegralTypePrintfFormat */
+
+/* Perform an unsigned cast to LargestIntegralType. */
+#define cast_to_largest_integral_type(value) \
+    ((LargestIntegralType)(value))
+
+/* Smallest integral type capable of holding a pointer. */
+#if !defined(_UINTPTR_T) && !defined(_UINTPTR_T_DEFINED)
+# if defined(_WIN32)
+    /* WIN32 is an ILP32 platform */
+    typedef unsigned int uintptr_t;
+# elif defined(_WIN64)
+    typedef unsigned long int uintptr_t
+# else /* _WIN32 */
+
+/* ILP32 and LP64 platforms */
+#  ifdef __WORDSIZE /* glibc */
+#   if __WORDSIZE == 64
+      typedef unsigned long int uintptr_t;
+#   else
+      typedef unsigned int uintptr_t;
+#   endif /* __WORDSIZE == 64 */
+#  else /* __WORDSIZE */
+#   if defined(_LP64) || defined(_I32LPx)
+      typedef unsigned long int uintptr_t;
+#   else
+      typedef unsigned int uintptr_t;
+#   endif
+#  endif /* __WORDSIZE */
+# endif /* _WIN32 */
+
+# define _UINTPTR_T
+# define _UINTPTR_T_DEFINED
+#endif /* !defined(_UINTPTR_T) || !defined(_UINTPTR_T_DEFINED) */
+
+/* Perform an unsigned cast to uintptr_t. */
+#define cast_to_pointer_integral_type(value) \
+    ((uintptr_t)((size_t)(value)))
+
+/* Perform a cast of a pointer to LargestIntegralType */
+#define cast_ptr_to_largest_integral_type(value) \
+cast_to_largest_integral_type(cast_to_pointer_integral_type(value))
+
+/* GCC have printf type attribute check.  */
+#ifdef __GNUC__
+#define CMOCKA_PRINTF_ATTRIBUTE(a,b) \
+    __attribute__ ((__format__ (__printf__, a, b)))
+#else
+#define CMOCKA_PRINTF_ATTRIBUTE(a,b)
+#endif /* __GNUC__ */
+
+#if defined(__GNUC__)
+#define CMOCKA_DEPRECATED __attribute__ ((deprecated))
+#elif defined(_MSC_VER)
+#define CMOCKA_DEPRECATED __declspec(deprecated)
+#else
+#define CMOCKA_DEPRECATED
+#endif
+
+#define WILL_RETURN_ALWAYS -1
+#define WILL_RETURN_ONCE -2
+
+/**
+ * @defgroup cmocka_mock Mock Objects
+ * @ingroup cmocka
+ *
+ * Mock objects mock objects are simulated objects that mimic the behavior of
+ * real objects. Instead of calling the real objects, the tested object calls a
+ * mock object that merely asserts that the correct methods were called, with
+ * the expected parameters, in the correct order.
+ *
+ * <ul>
+ * <li><strong>will_return(function, value)</strong> - The will_return() macro
+ * pushes a value onto a stack of mock values. This macro is intended to be
+ * used by the unit test itself, while programming the behaviour of the mocked
+ * object.</li>
+ *
+ * <li><strong>mock()</strong> - the mock macro pops a value from a stack of
+ * test values. The user of the mock() macro is the mocked object that uses it
+ * to learn how it should behave.</li>
+ * </ul>
+ *
+ * Because the will_return() and mock() are intended to be used in pairs, the
+ * cmocka library would fail the test if there are more values pushed onto the
+ * stack using will_return() than consumed with mock() and vice-versa.
+ *
+ * The following unit test stub illustrates how would a unit test instruct the
+ * mock object to return a particular value:
+ *
+ * @code
+ * will_return(chef_cook, "hotdog");
+ * will_return(chef_cook, 0);
+ * @endcode
+ *
+ * Now the mock object can check if the parameter it received is the parameter
+ * which is expected by the test driver. This can be done the following way:
+ *
+ * @code
+ * int chef_cook(const char *order, char **dish_out)
+ * {
+ *     check_expected(order);
+ * }
+ * @endcode
+ *
+ * For a complete example please at a look
+ * <a href="http://git.cryptomilk.org/projects/cmocka.git/tree/example/chef_wrap/waiter_test_wrap.c">here</a>.
+ *
+ * @{
+ */
+
+#ifdef DOXYGEN
+/**
+ * @brief Retrieve a return value of the current function.
+ *
+ * @return The value which was stored to return by this function.
+ *
+ * @see will_return()
+ */
+LargestIntegralType mock(void);
+#else
+#define mock() _mock(__func__, __FILE__, __LINE__)
+#endif
+
+#ifdef DOXYGEN
+/**
+ * @brief Retrieve a typed return value of the current function.
+ *
+ * The value would be casted to type internally to avoid having the
+ * caller to do the cast manually.
+ *
+ * @param[in]  #type  The expected type of the return value
+ *
+ * @return The value which was stored to return by this function.
+ *
+ * @code
+ * int param;
+ *
+ * param = mock_type(int);
+ * @endcode
+ *
+ * @see will_return()
+ * @see mock()
+ * @see mock_ptr_type()
+ */
+#type mock_type(#type);
+#else
+#define mock_type(type) ((type) mock())
+#endif
+
+#ifdef DOXYGEN
+/**
+ * @brief Retrieve a typed return value of the current function.
+ *
+ * The value would be casted to type internally to avoid having the
+ * caller to do the cast manually but also casted to uintptr_t to make
+ * sure the result has a valid size to be used as a pointer.
+ *
+ * @param[in]  #type  The expected type of the return value
+ *
+ * @return The value which was stored to return by this function.
+ *
+ * @code
+ * char *param;
+ *
+ * param = mock_ptr_type(char *);
+ * @endcode
+ *
+ * @see will_return()
+ * @see mock()
+ * @see mock_type()
+ */
+type mock_ptr_type(#type);
+#else
+#define mock_ptr_type(type) ((type) (uintptr_t) mock())
+#endif
+
+
+#ifdef DOXYGEN
+/**
+ * @brief Store a value to be returned by mock() later.
+ *
+ * @param[in]  #function  The function which should return the given value.
+ *
+ * @param[in]  value The value to be returned by mock().
+ *
+ * @code
+ * int return_integer(void)
+ * {
+ *      return (int)mock();
+ * }
+ *
+ * static void test_integer_return(void **state)
+ * {
+ *      will_return(return_integer, 42);
+ *
+ *      assert_int_equal(my_function_calling_return_integer(), 42);
+ * }
+ * @endcode
+ *
+ * @see mock()
+ * @see will_return_count()
+ */
+void will_return(#function, LargestIntegralType value);
+#else
+#define will_return(function, value) \
+    _will_return(#function, __FILE__, __LINE__, \
+                 cast_to_largest_integral_type(value), 1)
+#endif
+
+#ifdef DOXYGEN
+/**
+ * @brief Store a value to be returned by mock() later.
+ *
+ * @param[in]  #function  The function which should return the given value.
+ *
+ * @param[in]  value The value to be returned by mock().
+ *
+ * @param[in]  count The parameter indicates the number of times the value should
+ *                   be returned by mock(). If count is set to -1, the value
+ *                   will always be returned but must be returned at least once.
+ *                   If count is set to -2, the value will always be returned
+ *                   by mock(), but is not required to be returned.
+ *
+ * @see mock()
+ */
+void will_return_count(#function, LargestIntegralType value, int count);
+#else
+#define will_return_count(function, value, count) \
+    _will_return(#function, __FILE__, __LINE__, \
+                 cast_to_largest_integral_type(value), count)
+#endif
+
+#ifdef DOXYGEN
+/**
+ * @brief Store a value that will be always returned by mock().
+ *
+ * @param[in]  #function  The function which should return the given value.
+ *
+ * @param[in]  #value The value to be returned by mock().
+ *
+ * This is equivalent to:
+ * @code
+ * will_return_count(function, value, -1);
+ * @endcode
+ *
+ * @see will_return_count()
+ * @see mock()
+ */
+void will_return_always(#function, LargestIntegralType value);
+#else
+#define will_return_always(function, value) \
+    will_return_count(function, (value), WILL_RETURN_ALWAYS)
+#endif
+
+#ifdef DOXYGEN
+/**
+ * @brief Store a value that may be always returned by mock().
+ *
+ * This stores a value which will always be returned by mock() but is not
+ * required to be returned by at least one call to mock(). Therefore,
+ * in contrast to will_return_always() which causes a test failure if it
+ * is not returned at least once, will_return_maybe() will never cause a test
+ * to fail if its value is not returned.
+ *
+ * @param[in]  #function  The function which should return the given value.
+ *
+ * @param[in]  #value The value to be returned by mock().
+ *
+ * This is equivalent to:
+ * @code
+ * will_return_count(function, value, -2);
+ * @endcode
+ *
+ * @see will_return_count()
+ * @see mock()
+ */
+void will_return_maybe(#function, LargestIntegralType value);
+#else
+#define will_return_maybe(function, value) \
+    will_return_count(function, (value), WILL_RETURN_ONCE)
+#endif
+/** @} */
+
+/**
+ * @defgroup cmocka_param Checking Parameters
+ * @ingroup cmocka
+ *
+ * Functionality to store expected values for mock function parameters.
+ *
+ * In addition to storing the return values of mock functions, cmocka provides
+ * functionality to store expected values for mock function parameters using
+ * the expect_*() functions provided. A mock function parameter can then be
+ * validated using the check_expected() macro.
+ *
+ * Successive calls to expect_*() macros for a parameter queues values to check
+ * the specified parameter. check_expected() checks a function parameter
+ * against the next value queued using expect_*(), if the parameter check fails
+ * a test failure is signalled. In addition if check_expected() is called and
+ * no more parameter values are queued a test failure occurs.
+ *
+ * The following test stub illustrates how to do this. First is the the function
+ * we call in the test driver:
+ *
+ * @code
+ * static void test_driver(void **state)
+ * {
+ *     expect_string(chef_cook, order, "hotdog");
+ * }
+ * @endcode
+ *
+ * Now the chef_cook function can check if the parameter we got passed is the
+ * parameter which is expected by the test driver. This can be done the
+ * following way:
+ *
+ * @code
+ * int chef_cook(const char *order, char **dish_out)
+ * {
+ *     check_expected(order);
+ * }
+ * @endcode
+ *
+ * For a complete example please at a look at
+ * <a href="http://git.cryptomilk.org/projects/cmocka.git/tree/example/chef_wrap/waiter_test_wrap.c">here</a>
+ *
+ * @{
+ */
+
+/*
+ * Add a custom parameter checking function.  If the event parameter is NULL
+ * the event structure is allocated internally by this function.  If event
+ * parameter is provided it must be allocated on the heap and doesn't need to
+ * be deallocated by the caller.
+ */
+#ifdef DOXYGEN
+/**
+ * @brief Add a custom parameter checking function.
+ *
+ * If the event parameter is NULL the event structure is allocated internally
+ * by this function. If the parameter is provided it must be allocated on the
+ * heap and doesn't need to be deallocated by the caller.
+ *
+ * @param[in]  #function  The function to add a custom parameter checking
+ *                        function for.
+ *
+ * @param[in]  #parameter The parameters passed to the function.
+ *
+ * @param[in]  #check_function  The check function to call.
+ *
+ * @param[in]  check_data       The data to pass to the check function.
+ */
+void expect_check(#function, #parameter, #check_function, const void *check_data);
+#else
+#define expect_check(function, parameter, check_function, check_data) \
+    _expect_check(#function, #parameter, __FILE__, __LINE__, check_function, \
+                  cast_to_largest_integral_type(check_data), NULL, 1)
+#endif
+
+#ifdef DOXYGEN
+/**
+ * @brief Add an event to check if the parameter value is part of the provided
+ *        array.
+ *
+ * The event is triggered by calling check_expected() in the mocked function.
+ *
+ * @param[in]  #function  The function to add the check for.
+ *
+ * @param[in]  #parameter The name of the parameter passed to the function.
+ *
+ * @param[in]  value_array[] The array to check for the value.
+ *
+ * @see check_expected().
+ */
+void expect_in_set(#function, #parameter, LargestIntegralType value_array[]);
+#else
+#define expect_in_set(function, parameter, value_array) \
+    expect_in_set_count(function, parameter, value_array, 1)
+#endif
+
+#ifdef DOXYGEN
+/**
+ * @brief Add an event to check if the parameter value is part of the provided
+ *        array.
+ *
+ * The event is triggered by calling check_expected() in the mocked function.
+ *
+ * @param[in]  #function  The function to add the check for.
+ *
+ * @param[in]  #parameter The name of the parameter passed to the function.
+ *
+ * @param[in]  value_array[] The array to check for the value.
+ *
+ * @param[in]  count  The count parameter returns the number of times the value
+ *                    should be returned by check_expected(). If count is set
+ *                    to -1 the value will always be returned.
+ *
+ * @see check_expected().
+ */
+void expect_in_set_count(#function, #parameter, LargestIntegralType value_array[], size_t count);
+#else
+#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)
+#endif
+
+#ifdef DOXYGEN
+/**
+ * @brief Add an event to check if the parameter value is not part of the
+ *        provided array.
+ *
+ * The event is triggered by calling check_expected() in the mocked function.
+ *
+ * @param[in]  #function  The function to add the check for.
+ *
+ * @param[in]  #parameter The name of the parameter passed to the function.
+ *
+ * @param[in]  value_array[] The array to check for the value.
+ *
+ * @see check_expected().
+ */
+void expect_not_in_set(#function, #parameter, LargestIntegralType value_array[]);
+#else
+#define expect_not_in_set(function, parameter, value_array) \
+    expect_not_in_set_count(function, parameter, value_array, 1)
+#endif
+
+#ifdef DOXYGEN
+/**
+ * @brief Add an event to check if the parameter value is not part of the
+ *        provided array.
+ *
+ * The event is triggered by calling check_expected() in the mocked function.
+ *
+ * @param[in]  #function  The function to add the check for.
+ *
+ * @param[in]  #parameter The name of the parameter passed to the function.
+ *
+ * @param[in]  value_array[] The array to check for the value.
+ *
+ * @param[in]  count  The count parameter returns the number of times the value
+ *                    should be returned by check_expected(). If count is set
+ *                    to -1 the value will always be returned.
+ *
+ * @see check_expected().
+ */
+void expect_not_in_set_count(#function, #parameter, LargestIntegralType value_array[], size_t count);
+#else
+#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)
+#endif
+
+
+#ifdef DOXYGEN
+/**
+ * @brief Add an event to check a parameter is inside a numerical range.
+ * The check would succeed if minimum <= value <= maximum.
+ *
+ * The event is triggered by calling check_expected() in the mocked function.
+ *
+ * @param[in]  #function  The function to add the check for.
+ *
+ * @param[in]  #parameter The name of the parameter passed to the function.
+ *
+ * @param[in]  minimum  The lower boundary of the interval to check against.
+ *
+ * @param[in]  maximum  The upper boundary of the interval to check against.
+ *
+ * @see check_expected().
+ */
+void expect_in_range(#function, #parameter, LargestIntegralType minimum, LargestIntegralType maximum);
+#else
+#define expect_in_range(function, parameter, minimum, maximum) \
+    expect_in_range_count(function, parameter, minimum, maximum, 1)
+#endif
+
+#ifdef DOXYGEN
+/**
+ * @brief Add an event to repeatedly check a parameter is inside a
+ * numerical range. The check would succeed if minimum <= value <= maximum.
+ *
+ * The event is triggered by calling check_expected() in the mocked function.
+ *
+ * @param[in]  #function  The function to add the check for.
+ *
+ * @param[in]  #parameter The name of the parameter passed to the function.
+ *
+ * @param[in]  minimum  The lower boundary of the interval to check against.
+ *
+ * @param[in]  maximum  The upper boundary of the interval to check against.
+ *
+ * @param[in]  count  The count parameter returns the number of times the value
+ *                    should be returned by check_expected(). If count is set
+ *                    to -1 the value will always be returned.
+ *
+ * @see check_expected().
+ */
+void expect_in_range_count(#function, #parameter, LargestIntegralType minimum, LargestIntegralType maximum, size_t count);
+#else
+#define expect_in_range_count(function, parameter, minimum, maximum, count) \
+    _expect_in_range(#function, #parameter, __FILE__, __LINE__, minimum, \
+                     maximum, count)
+#endif
+
+#ifdef DOXYGEN
+/**
+ * @brief Add an event to check a parameter is outside a numerical range.
+ * The check would succeed if minimum > value > maximum.
+ *
+ * The event is triggered by calling check_expected() in the mocked function.
+ *
+ * @param[in]  #function  The function to add the check for.
+ *
+ * @param[in]  #parameter The name of the parameter passed to the function.
+ *
+ * @param[in]  minimum  The lower boundary of the interval to check against.
+ *
+ * @param[in]  maximum  The upper boundary of the interval to check against.
+ *
+ * @see check_expected().
+ */
+void expect_not_in_range(#function, #parameter, LargestIntegralType minimum, LargestIntegralType maximum);
+#else
+#define expect_not_in_range(function, parameter, minimum, maximum) \
+    expect_not_in_range_count(function, parameter, minimum, maximum, 1)
+#endif
+
+#ifdef DOXYGEN
+/**
+ * @brief Add an event to repeatedly check a parameter is outside a
+ * numerical range. The check would succeed if minimum > value > maximum.
+ *
+ * The event is triggered by calling check_expected() in the mocked function.
+ *
+ * @param[in]  #function  The function to add the check for.
+ *
+ * @param[in]  #parameter The name of the parameter passed to the function.
+ *
+ * @param[in]  minimum  The lower boundary of the interval to check against.
+ *
+ * @param[in]  maximum  The upper boundary of the interval to check against.
+ *
+ * @param[in]  count  The count parameter returns the number of times the value
+ *                    should be returned by check_expected(). If count is set
+ *                    to -1 the value will always be returned.
+ *
+ * @see check_expected().
+ */
+void expect_not_in_range_count(#function, #parameter, LargestIntegralType minimum, LargestIntegralType maximum, size_t count);
+#else
+#define expect_not_in_range_count(function, parameter, minimum, maximum, \
+                                  count) \
+    _expect_not_in_range(#function, #parameter, __FILE__, __LINE__, \
+                         minimum, maximum, count)
+#endif
+
+#ifdef DOXYGEN
+/**
+ * @brief Add an event to check if a parameter is the given value.
+ *
+ * The event is triggered by calling check_expected() in the mocked function.
+ *
+ * @param[in]  #function  The function to add the check for.
+ *
+ * @param[in]  #parameter The name of the parameter passed to the function.
+ *
+ * @param[in]  value  The value to check.
+ *
+ * @see check_expected().
+ */
+void expect_value(#function, #parameter, LargestIntegralType value);
+#else
+#define expect_value(function, parameter, value) \
+    expect_value_count(function, parameter, value, 1)
+#endif
+
+#ifdef DOXYGEN
+/**
+ * @brief Add an event to repeatedly check if a parameter is the given value.
+ *
+ * The event is triggered by calling check_expected() in the mocked function.
+ *
+ * @param[in]  #function  The function to add the check for.
+ *
+ * @param[in]  #parameter The name of the parameter passed to the function.
+ *
+ * @param[in]  value  The value to check.
+ *
+ * @param[in]  count  The count parameter returns the number of times the value
+ *                    should be returned by check_expected(). If count is set
+ *                    to -1 the value will always be returned.
+ *
+ * @see check_expected().
+ */
+void expect_value_count(#function, #parameter, LargestIntegralType value, size_t count);
+#else
+#define expect_value_count(function, parameter, value, count) \
+    _expect_value(#function, #parameter, __FILE__, __LINE__, \
+                  cast_to_largest_integral_type(value), count)
+#endif
+
+#ifdef DOXYGEN
+/**
+ * @brief Add an event to check if a parameter isn't the given value.
+ *
+ * The event is triggered by calling check_expected() in the mocked function.
+ *
+ * @param[in]  #function  The function to add the check for.
+ *
+ * @param[in]  #parameter The name of the parameter passed to the function.
+ *
+ * @param[in]  value  The value to check.
+ *
+ * @see check_expected().
+ */
+void expect_not_value(#function, #parameter, LargestIntegralType value);
+#else
+#define expect_not_value(function, parameter, value) \
+    expect_not_value_count(function, parameter, value, 1)
+#endif
+
+#ifdef DOXYGEN
+/**
+ * @brief Add an event to repeatedly check if a parameter isn't the given value.
+ *
+ * The event is triggered by calling check_expected() in the mocked function.
+ *
+ * @param[in]  #function  The function to add the check for.
+ *
+ * @param[in]  #parameter The name of the parameter passed to the function.
+ *
+ * @param[in]  value  The value to check.
+ *
+ * @param[in]  count  The count parameter returns the number of times the value
+ *                    should be returned by check_expected(). If count is set
+ *                    to -1 the value will always be returned.
+ *
+ * @see check_expected().
+ */
+void expect_not_value_count(#function, #parameter, LargestIntegralType value, size_t count);
+#else
+#define expect_not_value_count(function, parameter, value, count) \
+    _expect_not_value(#function, #parameter, __FILE__, __LINE__, \
+                      cast_to_largest_integral_type(value), count)
+#endif
+
+#ifdef DOXYGEN
+/**
+ * @brief Add an event to check if the parameter value is equal to the
+ *        provided string.
+ *
+ * The event is triggered by calling check_expected() in the mocked function.
+ *
+ * @param[in]  #function  The function to add the check for.
+ *
+ * @param[in]  #parameter The name of the parameter passed to the function.
+ *
+ * @param[in]  string   The string value to compare.
+ *
+ * @see check_expected().
+ */
+void expect_string(#function, #parameter, const char *string);
+#else
+#define expect_string(function, parameter, string) \
+    expect_string_count(function, parameter, string, 1)
+#endif
+
+#ifdef DOXYGEN
+/**
+ * @brief Add an event to check if the parameter value is equal to the
+ *        provided string.
+ *
+ * The event is triggered by calling check_expected() in the mocked function.
+ *
+ * @param[in]  #function  The function to add the check for.
+ *
+ * @param[in]  #parameter The name of the parameter passed to the function.
+ *
+ * @param[in]  string   The string value to compare.
+ *
+ * @param[in]  count  The count parameter returns the number of times the value
+ *                    should be returned by check_expected(). If count is set
+ *                    to -1 the value will always be returned.
+ *
+ * @see check_expected().
+ */
+void expect_string_count(#function, #parameter, const char *string, size_t count);
+#else
+#define expect_string_count(function, parameter, string, count) \
+    _expect_string(#function, #parameter, __FILE__, __LINE__, \
+                   (const char*)(string), count)
+#endif
+
+#ifdef DOXYGEN
+/**
+ * @brief Add an event to check if the parameter value isn't equal to the
+ *        provided string.
+ *
+ * The event is triggered by calling check_expected() in the mocked function.
+ *
+ * @param[in]  #function  The function to add the check for.
+ *
+ * @param[in]  #parameter The name of the parameter passed to the function.
+ *
+ * @param[in]  string   The string value to compare.
+ *
+ * @see check_expected().
+ */
+void expect_not_string(#function, #parameter, const char *string);
+#else
+#define expect_not_string(function, parameter, string) \
+    expect_not_string_count(function, parameter, string, 1)
+#endif
+
+#ifdef DOXYGEN
+/**
+ * @brief Add an event to check if the parameter value isn't equal to the
+ *        provided string.
+ *
+ * The event is triggered by calling check_expected() in the mocked function.
+ *
+ * @param[in]  #function  The function to add the check for.
+ *
+ * @param[in]  #parameter The name of the parameter passed to the function.
+ *
+ * @param[in]  string   The string value to compare.
+ *
+ * @param[in]  count  The count parameter returns the number of times the value
+ *                    should be returned by check_expected(). If count is set
+ *                    to -1 the value will always be returned.
+ *
+ * @see check_expected().
+ */
+void expect_not_string_count(#function, #parameter, const char *string, size_t count);
+#else
+#define expect_not_string_count(function, parameter, string, count) \
+    _expect_not_string(#function, #parameter, __FILE__, __LINE__, \
+                       (const char*)(string), count)
+#endif
+
+#ifdef DOXYGEN
+/**
+ * @brief Add an event to check if the parameter does match an area of memory.
+ *
+ * The event is triggered by calling check_expected() in the mocked function.
+ *
+ * @param[in]  #function  The function to add the check for.
+ *
+ * @param[in]  #parameter The name of the parameter passed to the function.
+ *
+ * @param[in]  memory  The memory to compare.
+ *
+ * @param[in]  size  The size of the memory to compare.
+ *
+ * @see check_expected().
+ */
+void expect_memory(#function, #parameter, void *memory, size_t size);
+#else
+#define expect_memory(function, parameter, memory, size) \
+    expect_memory_count(function, parameter, memory, size, 1)
+#endif
+
+#ifdef DOXYGEN
+/**
+ * @brief Add an event to repeatedly check if the parameter does match an area
+ *        of memory.
+ *
+ * The event is triggered by calling check_expected() in the mocked function.
+ *
+ * @param[in]  #function  The function to add the check for.
+ *
+ * @param[in]  #parameter The name of the parameter passed to the function.
+ *
+ * @param[in]  memory  The memory to compare.
+ *
+ * @param[in]  size  The size of the memory to compare.
+ *
+ * @param[in]  count  The count parameter returns the number of times the value
+ *                    should be returned by check_expected(). If count is set
+ *                    to -1 the value will always be returned.
+ *
+ * @see check_expected().
+ */
+void expect_memory_count(#function, #parameter, void *memory, size_t size, size_t count);
+#else
+#define expect_memory_count(function, parameter, memory, size, count) \
+    _expect_memory(#function, #parameter, __FILE__, __LINE__, \
+                   (const void*)(memory), size, count)
+#endif
+
+#ifdef DOXYGEN
+/**
+ * @brief Add an event to check if the parameter doesn't match an area of
+ *        memory.
+ *
+ * The event is triggered by calling check_expected() in the mocked function.
+ *
+ * @param[in]  #function  The function to add the check for.
+ *
+ * @param[in]  #parameter The name of the parameter passed to the function.
+ *
+ * @param[in]  memory  The memory to compare.
+ *
+ * @param[in]  size  The size of the memory to compare.
+ *
+ * @see check_expected().
+ */
+void expect_not_memory(#function, #parameter, void *memory, size_t size);
+#else
+#define expect_not_memory(function, parameter, memory, size) \
+    expect_not_memory_count(function, parameter, memory, size, 1)
+#endif
+
+#ifdef DOXYGEN
+/**
+ * @brief Add an event to repeatedly check if the parameter doesn't match an
+ *        area of memory.
+ *
+ * The event is triggered by calling check_expected() in the mocked function.
+ *
+ * @param[in]  #function  The function to add the check for.
+ *
+ * @param[in]  #parameter The name of the parameter passed to the function.
+ *
+ * @param[in]  memory  The memory to compare.
+ *
+ * @param[in]  size  The size of the memory to compare.
+ *
+ * @param[in]  count  The count parameter returns the number of times the value
+ *                    should be returned by check_expected(). If count is set
+ *                    to -1 the value will always be returned.
+ *
+ * @see check_expected().
+ */
+void expect_not_memory_count(#function, #parameter, void *memory, size_t size, size_t count);
+#else
+#define expect_not_memory_count(function, parameter, memory, size, count) \
+    _expect_not_memory(#function, #parameter, __FILE__, __LINE__, \
+                       (const void*)(memory), size, count)
+#endif
+
+
+#ifdef DOXYGEN
+/**
+ * @brief Add an event to check if a parameter (of any value) has been passed.
+ *
+ * The event is triggered by calling check_expected() in the mocked function.
+ *
+ * @param[in]  #function  The function to add the check for.
+ *
+ * @param[in]  #parameter The name of the parameter passed to the function.
+ *
+ * @see check_expected().
+ */
+void expect_any(#function, #parameter);
+#else
+#define expect_any(function, parameter) \
+    expect_any_count(function, parameter, 1)
+#endif
+
+#ifdef DOXYGEN
+/**
+ * @brief Add an event to repeatedly check if a parameter (of any value) has
+ *        been passed.
+ *
+ * The event is triggered by calling check_expected() in the mocked function.
+ *
+ * @param[in]  #function  The function to add the check for.
+ *
+ * @param[in]  #parameter The name of the parameter passed to the function.
+ *
+ * @param[in]  count  The count parameter returns the number of times the value
+ *                    should be returned by check_expected(). If count is set
+ *                    to -1 the value will always be returned.
+ *
+ * @see check_expected().
+ */
+void expect_any_count(#function, #parameter, size_t count);
+#else
+#define expect_any_count(function, parameter, count) \
+    _expect_any(#function, #parameter, __FILE__, __LINE__, count)
+#endif
+
+#ifdef DOXYGEN
+/**
+ * @brief Determine whether a function parameter is correct.
+ *
+ * This ensures the next value queued by one of the expect_*() macros matches
+ * the specified variable.
+ *
+ * This function needs to be called in the mock object.
+ *
+ * @param[in]  #parameter  The parameter to check.
+ */
+void check_expected(#parameter);
+#else
+#define check_expected(parameter) \
+    _check_expected(__func__, #parameter, __FILE__, __LINE__, \
+                    cast_to_largest_integral_type(parameter))
+#endif
+
+#ifdef DOXYGEN
+/**
+ * @brief Determine whether a function parameter is correct.
+ *
+ * This ensures the next value queued by one of the expect_*() macros matches
+ * the specified variable.
+ *
+ * This function needs to be called in the mock object.
+ *
+ * @param[in]  #parameter  The pointer to check.
+ */
+void check_expected_ptr(#parameter);
+#else
+#define check_expected_ptr(parameter) \
+    _check_expected(__func__, #parameter, __FILE__, __LINE__, \
+                    cast_ptr_to_largest_integral_type(parameter))
+#endif
+
+/** @} */
+
+/**
+ * @defgroup cmocka_asserts Assert Macros
+ * @ingroup cmocka
+ *
+ * This is a set of useful assert macros like the standard C libary's
+ * assert(3) macro.
+ *
+ * On an assertion failure a cmocka assert macro will write the failure to the
+ * standard error stream and signal a test failure. Due to limitations of the C
+ * language the general C standard library assert() and cmocka's assert_true()
+ * and assert_false() macros can only display the expression that caused the
+ * assert failure. cmocka's type specific assert macros, assert_{type}_equal()
+ * and assert_{type}_not_equal(), display the data that caused the assertion
+ * failure which increases data visibility aiding debugging of failing test
+ * cases.
+ *
+ * @{
+ */
+
+#ifdef DOXYGEN
+/**
+ * @brief Assert that the given expression is true.
+ *
+ * The function prints an error message to standard error and terminates the
+ * test by calling fail() if expression is false (i.e., compares equal to
+ * zero).
+ *
+ * @param[in]  expression  The expression to evaluate.
+ *
+ * @see assert_int_equal()
+ * @see assert_string_equal()
+ */
+void assert_true(scalar expression);
+#else
+#define assert_true(c) _assert_true(cast_to_largest_integral_type(c), #c, \
+                                    __FILE__, __LINE__)
+#endif
+
+#ifdef DOXYGEN
+/**
+ * @brief Assert that the given expression is false.
+ *
+ * The function prints an error message to standard error and terminates the
+ * test by calling fail() if expression is true.
+ *
+ * @param[in]  expression  The expression to evaluate.
+ *
+ * @see assert_int_equal()
+ * @see assert_string_equal()
+ */
+void assert_false(scalar expression);
+#else
+#define assert_false(c) _assert_true(!(cast_to_largest_integral_type(c)), #c, \
+                                     __FILE__, __LINE__)
+#endif
+
+#ifdef DOXYGEN
+/**
+ * @brief Assert that the return_code is greater than or equal to 0.
+ *
+ * The function prints an error message to standard error and terminates the
+ * test by calling fail() if the return code is smaller than 0. If the function
+ * you check sets an errno if it fails you can pass it to the function and
+ * it will be printed as part of the error message.
+ *
+ * @param[in]  rc       The return code to evaluate.
+ *
+ * @param[in]  error    Pass errno here or 0.
+ */
+void assert_return_code(int rc, int error);
+#else
+#define assert_return_code(rc, error) \
+    _assert_return_code(cast_to_largest_integral_type(rc), \
+                        sizeof(rc), \
+                        cast_to_largest_integral_type(error), \
+                        #rc, __FILE__, __LINE__)
+#endif
+
+#ifdef DOXYGEN
+/**
+ * @brief Assert that the given pointer is non-NULL.
+ *
+ * The function prints an error message to standard error and terminates the
+ * test by calling fail() if the pointer is non-NULL.
+ *
+ * @param[in]  pointer  The pointer to evaluate.
+ *
+ * @see assert_null()
+ */
+void assert_non_null(void *pointer);
+#else
+#define assert_non_null(c) _assert_true(cast_ptr_to_largest_integral_type(c), #c, \
+                                        __FILE__, __LINE__)
+#endif
+
+#ifdef DOXYGEN
+/**
+ * @brief Assert that the given pointer is NULL.
+ *
+ * The function prints an error message to standard error and terminates the
+ * test by calling fail() if the pointer is non-NULL.
+ *
+ * @param[in]  pointer  The pointer to evaluate.
+ *
+ * @see assert_non_null()
+ */
+void assert_null(void *pointer);
+#else
+#define assert_null(c) _assert_true(!(cast_ptr_to_largest_integral_type(c)), #c, \
+__FILE__, __LINE__)
+#endif
+
+#ifdef DOXYGEN
+/**
+ * @brief Assert that the two given pointers are equal.
+ *
+ * The function prints an error message and terminates the test by calling
+ * fail() if the pointers are not equal.
+ *
+ * @param[in]  a        The first pointer to compare.
+ *
+ * @param[in]  b        The pointer to compare against the first one.
+ */
+void assert_ptr_equal(void *a, void *b);
+#else
+#define assert_ptr_equal(a, b) \
+    _assert_int_equal(cast_ptr_to_largest_integral_type(a), \
+                      cast_ptr_to_largest_integral_type(b), \
+                      __FILE__, __LINE__)
+#endif
+
+#ifdef DOXYGEN
+/**
+ * @brief Assert that the two given pointers are not equal.
+ *
+ * The function prints an error message and terminates the test by calling
+ * fail() if the pointers are equal.
+ *
+ * @param[in]  a        The first pointer to compare.
+ *
+ * @param[in]  b        The pointer to compare against the first one.
+ */
+void assert_ptr_not_equal(void *a, void *b);
+#else
+#define assert_ptr_not_equal(a, b) \
+    _assert_int_not_equal(cast_ptr_to_largest_integral_type(a), \
+                          cast_ptr_to_largest_integral_type(b), \
+                          __FILE__, __LINE__)
+#endif
+
+#ifdef DOXYGEN
+/**
+ * @brief Assert that the two given integers are equal.
+ *
+ * The function prints an error message to standard error and terminates the
+ * test by calling fail() if the integers are not equal.
+ *
+ * @param[in]  a  The first integer to compare.
+ *
+ * @param[in]  b  The integer to compare against the first one.
+ */
+void assert_int_equal(int a, int b);
+#else
+#define assert_int_equal(a, b) \
+    _assert_int_equal(cast_to_largest_integral_type(a), \
+                      cast_to_largest_integral_type(b), \
+                      __FILE__, __LINE__)
+#endif
+
+#ifdef DOXYGEN
+/**
+ * @brief Assert that the two given integers are not equal.
+ *
+ * The function prints an error message to standard error and terminates the
+ * test by calling fail() if the integers are equal.
+ *
+ * @param[in]  a  The first integer to compare.
+ *
+ * @param[in]  b  The integer to compare against the first one.
+ *
+ * @see assert_int_equal()
+ */
+void assert_int_not_equal(int a, int b);
+#else
+#define assert_int_not_equal(a, b) \
+    _assert_int_not_equal(cast_to_largest_integral_type(a), \
+                          cast_to_largest_integral_type(b), \
+                          __FILE__, __LINE__)
+#endif
+
+#ifdef DOXYGEN
+/**
+ * @brief Assert that the two given strings are equal.
+ *
+ * The function prints an error message to standard error and terminates the
+ * test by calling fail() if the strings are not equal.
+ *
+ * @param[in]  a  The string to check.
+ *
+ * @param[in]  b  The other string to compare.
+ */
+void assert_string_equal(const char *a, const char *b);
+#else
+#define assert_string_equal(a, b) \
+    _assert_string_equal((const char*)(a), (const char*)(b), __FILE__, \
+                         __LINE__)
+#endif
+
+#ifdef DOXYGEN
+/**
+ * @brief Assert that the two given strings are not equal.
+ *
+ * The function prints an error message to standard error and terminates the
+ * test by calling fail() if the strings are equal.
+ *
+ * @param[in]  a  The string to check.
+ *
+ * @param[in]  b  The other string to compare.
+ */
+void assert_string_not_equal(const char *a, const char *b);
+#else
+#define assert_string_not_equal(a, b) \
+    _assert_string_not_equal((const char*)(a), (const char*)(b), __FILE__, \
+                             __LINE__)
+#endif
+
+#ifdef DOXYGEN
+/**
+ * @brief Assert that the two given areas of memory are equal, otherwise fail.
+ *
+ * The function prints an error message to standard error and terminates the
+ * test by calling fail() if the memory is not equal.
+ *
+ * @param[in]  a  The first memory area to compare
+ *                (interpreted as unsigned char).
+ *
+ * @param[in]  b  The second memory area to compare
+ *                (interpreted as unsigned char).
+ *
+ * @param[in]  size  The first n bytes of the memory areas to compare.
+ */
+void assert_memory_equal(const void *a, const void *b, size_t size);
+#else
+#define assert_memory_equal(a, b, size) \
+    _assert_memory_equal((const void*)(a), (const void*)(b), size, __FILE__, \
+                         __LINE__)
+#endif
+
+#ifdef DOXYGEN
+/**
+ * @brief Assert that the two given areas of memory are not equal.
+ *
+ * The function prints an error message to standard error and terminates the
+ * test by calling fail() if the memory is equal.
+ *
+ * @param[in]  a  The first memory area to compare
+ *                (interpreted as unsigned char).
+ *
+ * @param[in]  b  The second memory area to compare
+ *                (interpreted as unsigned char).
+ *
+ * @param[in]  size  The first n bytes of the memory areas to compare.
+ */
+void assert_memory_not_equal(const void *a, const void *b, size_t size);
+#else
+#define assert_memory_not_equal(a, b, size) \
+    _assert_memory_not_equal((const void*)(a), (const void*)(b), size, \
+                             __FILE__, __LINE__)
+#endif
+
+#ifdef DOXYGEN
+/**
+ * @brief Assert that the specified value is not smaller than the minimum
+ * and and not greater than the maximum.
+ *
+ * The function prints an error message to standard error and terminates the
+ * test by calling fail() if value is not in range.
+ *
+ * @param[in]  value  The value to check.
+ *
+ * @param[in]  minimum  The minimum value allowed.
+ *
+ * @param[in]  maximum  The maximum value allowed.
+ */
+void assert_in_range(LargestIntegralType value, LargestIntegralType minimum, LargestIntegralType maximum);
+#else
+#define assert_in_range(value, minimum, maximum) \
+    _assert_in_range( \
+        cast_to_largest_integral_type(value), \
+        cast_to_largest_integral_type(minimum), \
+        cast_to_largest_integral_type(maximum), __FILE__, __LINE__)
+#endif
+
+#ifdef DOXYGEN
+/**
+ * @brief Assert that the specified value is smaller than the minimum or
+ * greater than the maximum.
+ *
+ * The function prints an error message to standard error and terminates the
+ * test by calling fail() if value is in range.
+ *
+ * @param[in]  value  The value to check.
+ *
+ * @param[in]  minimum  The minimum value to compare.
+ *
+ * @param[in]  maximum  The maximum value to compare.
+ */
+void assert_not_in_range(LargestIntegralType value, LargestIntegralType minimum, LargestIntegralType maximum);
+#else
+#define assert_not_in_range(value, minimum, maximum) \
+    _assert_not_in_range( \
+        cast_to_largest_integral_type(value), \
+        cast_to_largest_integral_type(minimum), \
+        cast_to_largest_integral_type(maximum), __FILE__, __LINE__)
+#endif
+
+#ifdef DOXYGEN
+/**
+ * @brief Assert that the specified value is within a set.
+ *
+ * The function prints an error message to standard error and terminates the
+ * test by calling fail() if value is not within a set.
+ *
+ * @param[in]  value  The value to look up
+ *
+ * @param[in]  values[]  The array to check for the value.
+ *
+ * @param[in]  count  The size of the values array.
+ */
+void assert_in_set(LargestIntegralType value, LargestIntegralType values[], size_t count);
+#else
+#define assert_in_set(value, values, number_of_values) \
+    _assert_in_set(value, values, number_of_values, __FILE__, __LINE__)
+#endif
+
+#ifdef DOXYGEN
+/**
+ * @brief Assert that the specified value is not within a set.
+ *
+ * The function prints an error message to standard error and terminates the
+ * test by calling fail() if value is within a set.
+ *
+ * @param[in]  value  The value to look up
+ *
+ * @param[in]  values[]  The array to check for the value.
+ *
+ * @param[in]  count  The size of the values array.
+ */
+void assert_not_in_set(LargestIntegralType value, LargestIntegralType values[], size_t count);
+#else
+#define assert_not_in_set(value, values, number_of_values) \
+    _assert_not_in_set(value, values, number_of_values, __FILE__, __LINE__)
+#endif
+
+/** @} */
+
+/**
+ * @defgroup cmocka_call_order Call Ordering
+ * @ingroup cmocka
+ *
+ * It is often beneficial to  make sure that functions are called in an
+ * order. This is independent of mock returns and parameter checking as both
+ * of the aforementioned do not check the order in which they are called from
+ * different functions.
+ *
+ * <ul>
+ * <li><strong>expect_function_call(function)</strong> - The
+ * expect_function_call() macro pushes an expectation onto the stack of
+ * expected calls.</li>
+ *
+ * <li><strong>function_called()</strong> - pops a value from the stack of
+ * expected calls. function_called() is invoked within the mock object
+ * that uses it.
+ * </ul>
+ *
+ * expect_function_call() and function_called() are intended to be used in
+ * pairs. Cmocka will fail a test if there are more or less expected calls
+ * created (e.g. expect_function_call()) than consumed with function_called().
+ * There are provisions such as ignore_function_calls() which allow this
+ * restriction to be circumvented in tests where mock calls for the code under
+ * test are not the focus of the test.
+ *
+ * The following example illustrates how a unit test instructs cmocka
+ * to expect a function_called() from a particular mock,
+ * <strong>chef_sing()</strong>:
+ *
+ * @code
+ * void chef_sing(void);
+ *
+ * void code_under_test()
+ * {
+ *   chef_sing();
+ * }
+ *
+ * void some_test(void **state)
+ * {
+ *     expect_function_call(chef_sing);
+ *     code_under_test();
+ * }
+ * @endcode
+ *
+ * The implementation of the mock then must check whether it was meant to
+ * be called by invoking <strong>function_called()</strong>:
+ *
+ * @code
+ * void chef_sing()
+ * {
+ *     function_called();
+ * }
+ * @endcode
+ *
+ * @{
+ */
+
+#ifdef DOXYGEN
+/**
+ * @brief Check that current mocked function is being called in the expected
+ *        order
+ *
+ * @see expect_function_call()
+ */
+void function_called(void);
+#else
+#define function_called() _function_called(__func__, __FILE__, __LINE__)
+#endif
+
+#ifdef DOXYGEN
+/**
+ * @brief Store expected call(s) to a mock to be checked by function_called()
+ *        later.
+ *
+ * @param[in]  #function  The function which should should be called
+ *
+ * @param[in]  times number of times this mock must be called
+ *
+ * @see function_called()
+ */
+void expect_function_calls(#function, const int times);
+#else
+#define expect_function_calls(function, times) \
+    _expect_function_call(#function, __FILE__, __LINE__, times)
+#endif
+
+#ifdef DOXYGEN
+/**
+ * @brief Store expected single call to a mock to be checked by
+ *        function_called() later.
+ *
+ * @param[in]  #function  The function which should should be called
+ *
+ * @see function_called()
+ */
+void expect_function_call(#function);
+#else
+#define expect_function_call(function) \
+    _expect_function_call(#function, __FILE__, __LINE__, 1)
+#endif
+
+#ifdef DOXYGEN
+/**
+ * @brief Expects function_called() from given mock at least once
+ *
+ * @param[in]  #function  The function which should should be called
+ *
+ * @see function_called()
+ */
+void expect_function_call_any(#function);
+#else
+#define expect_function_call_any(function) \
+    _expect_function_call(#function, __FILE__, __LINE__, -1)
+#endif
+
+#ifdef DOXYGEN
+/**
+ * @brief Ignores function_called() invocations from given mock function.
+ *
+ * @param[in]  #function  The function which should should be called
+ *
+ * @see function_called()
+ */
+void ignore_function_calls(#function);
+#else
+#define ignore_function_calls(function) \
+    _expect_function_call(#function, __FILE__, __LINE__, -2)
+#endif
+
+/** @} */
+
+/**
+ * @defgroup cmocka_exec Running Tests
+ * @ingroup cmocka
+ *
+ * This is the way tests are executed with CMocka.
+ *
+ * The following example illustrates this macro's use with the unit_test macro.
+ *
+ * @code
+ * void Test0(void **state);
+ * void Test1(void **state);
+ *
+ * int main(void)
+ * {
+ *     const struct CMUnitTest tests[] = {
+ *         cmocka_unit_test(Test0),
+ *         cmocka_unit_test(Test1),
+ *     };
+ *
+ *     return cmocka_run_group_tests(tests, NULL, NULL);
+ * }
+ * @endcode
+ *
+ * @{
+ */
+
+#ifdef DOXYGEN
+/**
+ * @brief Forces the test to fail immediately and quit.
+ */
+void fail(void);
+#else
+#define fail() _fail(__FILE__, __LINE__)
+#endif
+
+#ifdef DOXYGEN
+/**
+ * @brief Forces the test to not be executed, but marked as skipped
+ */
+void skip(void);
+#else
+#define skip() _skip(__FILE__, __LINE__)
+#endif
+
+#ifdef DOXYGEN
+/**
+ * @brief Forces the test to fail immediately and quit, printing the reason.
+ *
+ * @code
+ * fail_msg("This is some error message for test");
+ * @endcode
+ *
+ * or
+ *
+ * @code
+ * char *error_msg = "This is some error message for test";
+ * fail_msg("%s", error_msg);
+ * @endcode
+ */
+void fail_msg(const char *msg, ...);
+#else
+#define fail_msg(msg, ...) do { \
+    print_error("ERROR: " msg "\n", ##__VA_ARGS__); \
+    fail(); \
+} while (0)
+#endif
+
+#ifdef DOXYGEN
+/**
+ * @brief Generic method to run a single test.
+ *
+ * @deprecated This function was deprecated in favor of cmocka_run_group_tests
+ *
+ * @param[in]  #function The function to test.
+ *
+ * @return 0 on success, 1 if an error occured.
+ *
+ * @code
+ * // A test case that does nothing and succeeds.
+ * void null_test_success(void **state) {
+ * }
+ *
+ * int main(void) {
+ *      return run_test(null_test_success);
+ * }
+ * @endcode
+ */
+int run_test(#function);
+#else
+#define run_test(f) _run_test(#f, f, NULL, UNIT_TEST_FUNCTION_TYPE_TEST, NULL)
+#endif
+
+static inline void _unit_test_dummy(void **state) {
+    (void)state;
+}
+
+/** Initializes a UnitTest structure.
+ *
+ * @deprecated This function was deprecated in favor of cmocka_unit_test
+ */
+#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 }
+
+/** Initializes a UnitTest structure with a setup function.
+ *
+ * @deprecated This function was deprecated in favor of cmocka_unit_test_setup
+ */
+#define unit_test_setup(test, setup) \
+    _unit_test_setup(test, setup), \
+    unit_test(test), \
+    _unit_test_teardown(test, _unit_test_dummy)
+
+#define _unit_test_teardown(test, teardown) \
+    { #test "_" #teardown, teardown, UNIT_TEST_FUNCTION_TYPE_TEARDOWN }
+
+/** Initializes a UnitTest structure with a teardown function.
+ *
+ * @deprecated This function was deprecated in favor of cmocka_unit_test_teardown
+ */
+#define unit_test_teardown(test, teardown) \
+    _unit_test_setup(test, _unit_test_dummy), \
+    unit_test(test), \
+    _unit_test_teardown(test, teardown)
+
+/** Initializes a UnitTest structure for a group setup function.
+ *
+ * @deprecated This function was deprecated in favor of cmocka_run_group_tests
+ */
+#define group_test_setup(setup) \
+    { "group_" #setup, setup, UNIT_TEST_FUNCTION_TYPE_GROUP_SETUP }
+
+/** Initializes a UnitTest structure for a group teardown function.
+ *
+ * @deprecated This function was deprecated in favor of cmocka_run_group_tests
+ */
+#define group_test_teardown(teardown) \
+    { "group_" #teardown, teardown, UNIT_TEST_FUNCTION_TYPE_GROUP_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.
+ *
+ * @deprecated This function was deprecated in favor of
+ * cmocka_unit_test_setup_teardown
+ */
+#define unit_test_setup_teardown(test, setup, teardown) \
+    _unit_test_setup(test, setup), \
+    unit_test(test), \
+    _unit_test_teardown(test, teardown)
+
+
+/** Initializes a CMUnitTest structure. */
+#define cmocka_unit_test(f) { #f, f, NULL, NULL, NULL }
+
+/** Initializes a CMUnitTest structure with a setup function. */
+#define cmocka_unit_test_setup(f, setup) { #f, f, setup, NULL, NULL }
+
+/** Initializes a CMUnitTest structure with a teardown function. */
+#define cmocka_unit_test_teardown(f, teardown) { #f, f, NULL, teardown, NULL }
+
+/**
+ * Initialize an array of CMUnitTest structures with a setup function for a test
+ * and a teardown function. Either setup or teardown can be NULL.
+ */
+#define cmocka_unit_test_setup_teardown(f, setup, teardown) { #f, f, setup, teardown, NULL }
+
+/**
+ * Initialize a CMUnitTest structure with given initial state. It will be passed
+ * to test function as an argument later. It can be used when test state does
+ * not need special initialization or was initialized already.
+ * @note If the group setup function initialized the state already, it won't be
+ * overridden by the initial state defined here.
+ */
+#define cmocka_unit_test_prestate(f, state) { #f, f, NULL, NULL, state }
+
+/**
+ * Initialize a CMUnitTest structure with given initial state, setup and
+ * teardown function. Any of these values can be NULL. Initial state is passed
+ * later to setup function, or directly to test if none was given.
+ * @note If the group setup function initialized the state already, it won't be
+ * overridden by the initial state defined here.
+ */
+#define cmocka_unit_test_prestate_setup_teardown(f, setup, teardown, state) { #f, f, setup, teardown, state }
+
+#define run_tests(tests) _run_tests(tests, sizeof(tests) / sizeof(tests)[0])
+#define run_group_tests(tests) _run_group_tests(tests, sizeof(tests) / sizeof(tests)[0])
+
+#ifdef DOXYGEN
+/**
+ * @brief Run tests specified by an array of CMUnitTest structures.
+ *
+ * @param[in]  group_tests[]  The array of unit tests to execute.
+ *
+ * @param[in]  group_setup    The setup function which should be called before
+ *                            all unit tests are executed.
+ *
+ * @param[in]  group_teardown The teardown function to be called after all
+ *                            tests have finished.
+ *
+ * @return 0 on success, or the number of failed tests.
+ *
+ * @code
+ * static int setup(void **state) {
+ *      int *answer = malloc(sizeof(int));
+ *      if (*answer == NULL) {
+ *          return -1;
+ *      }
+ *      *answer = 42;
+ *
+ *      *state = answer;
+ *
+ *      return 0;
+ * }
+ *
+ * static int teardown(void **state) {
+ *      free(*state);
+ *
+ *      return 0;
+ * }
+ *
+ * static void null_test_success(void **state) {
+ *     (void) state;
+ * }
+ *
+ * static void int_test_success(void **state) {
+ *      int *answer = *state;
+ *      assert_int_equal(*answer, 42);
+ * }
+ *
+ * int main(void) {
+ *     const struct CMUnitTest tests[] = {
+ *         cmocka_unit_test(null_test_success),
+ *         cmocka_unit_test_setup_teardown(int_test_success, setup, teardown),
+ *     };
+ *
+ *     return cmocka_run_group_tests(tests, NULL, NULL);
+ * }
+ * @endcode
+ *
+ * @see cmocka_unit_test
+ * @see cmocka_unit_test_setup
+ * @see cmocka_unit_test_teardown
+ * @see cmocka_unit_test_setup_teardown
+ */
+int cmocka_run_group_tests(const struct CMUnitTest group_tests[],
+                           CMFixtureFunction group_setup,
+                           CMFixtureFunction group_teardown);
+#else
+# define cmocka_run_group_tests(group_tests, group_setup, group_teardown) \
+        _cmocka_run_group_tests(#group_tests, group_tests, sizeof(group_tests) / sizeof(group_tests)[0], group_setup, group_teardown)
+#endif
+
+#ifdef DOXYGEN
+/**
+ * @brief Run tests specified by an array of CMUnitTest structures and specify
+ *        a name.
+ *
+ * @param[in]  group_name     The name of the group test.
+ *
+ * @param[in]  group_tests[]  The array of unit tests to execute.
+ *
+ * @param[in]  group_setup    The setup function which should be called before
+ *                            all unit tests are executed.
+ *
+ * @param[in]  group_teardown The teardown function to be called after all
+ *                            tests have finished.
+ *
+ * @return 0 on success, or the number of failed tests.
+ *
+ * @code
+ * static int setup(void **state) {
+ *      int *answer = malloc(sizeof(int));
+ *      if (*answer == NULL) {
+ *          return -1;
+ *      }
+ *      *answer = 42;
+ *
+ *      *state = answer;
+ *
+ *      return 0;
+ * }
+ *
+ * static int teardown(void **state) {
+ *      free(*state);
+ *
+ *      return 0;
+ * }
+ *
+ * static void null_test_success(void **state) {
+ *     (void) state;
+ * }
+ *
+ * static void int_test_success(void **state) {
+ *      int *answer = *state;
+ *      assert_int_equal(*answer, 42);
+ * }
+ *
+ * int main(void) {
+ *     const struct CMUnitTest tests[] = {
+ *         cmocka_unit_test(null_test_success),
+ *         cmocka_unit_test_setup_teardown(int_test_success, setup, teardown),
+ *     };
+ *
+ *     return cmocka_run_group_tests_name("success_test", tests, NULL, NULL);
+ * }
+ * @endcode
+ *
+ * @see cmocka_unit_test
+ * @see cmocka_unit_test_setup
+ * @see cmocka_unit_test_teardown
+ * @see cmocka_unit_test_setup_teardown
+ */
+int cmocka_run_group_tests_name(const char *group_name,
+                                const struct CMUnitTest group_tests[],
+                                CMFixtureFunction group_setup,
+                                CMFixtureFunction group_teardown);
+#else
+# define cmocka_run_group_tests_name(group_name, group_tests, group_setup, group_teardown) \
+        _cmocka_run_group_tests(group_name, group_tests, sizeof(group_tests) / sizeof(group_tests)[0], group_setup, group_teardown)
+#endif
+
+/** @} */
+
+/**
+ * @defgroup cmocka_alloc Dynamic Memory Allocation
+ * @ingroup cmocka
+ *
+ * Memory leaks, buffer overflows and underflows can be checked using cmocka.
+ *
+ * To test for memory leaks, buffer overflows and underflows a module being
+ * tested by cmocka should replace calls to malloc(), calloc() and free() to
+ * test_malloc(), test_calloc() and test_free() respectively. Each time a block
+ * is deallocated using test_free() it is checked for corruption, if a corrupt
+ * block is found a test failure is signalled. All blocks allocated using the
+ * test_*() allocation functions are tracked by the cmocka library. When a test
+ * completes if any allocated blocks (memory leaks) remain they are reported
+ * and a test failure is signalled.
+ *
+ * For simplicity cmocka currently executes all tests in one process. Therefore
+ * all test cases in a test application share a single address space which
+ * means memory corruption from a single test case could potentially cause the
+ * test application to exit prematurely.
+ *
+ * @{
+ */
+
+#ifdef DOXYGEN
+/**
+ * @brief Test function overriding malloc.
+ *
+ * @param[in]  size  The bytes which should be allocated.
+ *
+ * @return A pointer to the allocated memory or NULL on error.
+ *
+ * @code
+ * #ifdef UNIT_TESTING
+ * extern void* _test_malloc(const size_t size, const char* file, const int line);
+ *
+ * #define malloc(size) _test_malloc(size, __FILE__, __LINE__)
+ * #endif
+ *
+ * void leak_memory() {
+ *     int * const temporary = (int*)malloc(sizeof(int));
+ *     *temporary = 0;
+ * }
+ * @endcode
+ *
+ * @see malloc(3)
+ */
+void *test_malloc(size_t size);
+#else
+#define test_malloc(size) _test_malloc(size, __FILE__, __LINE__)
+#endif
+
+#ifdef DOXYGEN
+/**
+ * @brief Test function overriding calloc.
+ *
+ * The memory is set to zero.
+ *
+ * @param[in]  nmemb  The number of elements for an array to be allocated.
+ *
+ * @param[in]  size   The size in bytes of each array element to allocate.
+ *
+ * @return A pointer to the allocated memory, NULL on error.
+ *
+ * @see calloc(3)
+ */
+void *test_calloc(size_t nmemb, size_t size);
+#else
+#define test_calloc(num, size) _test_calloc(num, size, __FILE__, __LINE__)
+#endif
+
+#ifdef DOXYGEN
+/**
+ * @brief Test function overriding realloc which detects buffer overruns
+ *        and memoery leaks.
+ *
+ * @param[in]  ptr   The memory block which should be changed.
+ *
+ * @param[in]  size  The bytes which should be allocated.
+ *
+ * @return           The newly allocated memory block, NULL on error.
+ */
+void *test_realloc(void *ptr, size_t size);
+#else
+#define test_realloc(ptr, size) _test_realloc(ptr, size, __FILE__, __LINE__)
+#endif
+
+#ifdef DOXYGEN
+/**
+ * @brief Test function overriding free(3).
+ *
+ * @param[in]  ptr  The pointer to the memory space to free.
+ *
+ * @see free(3).
+ */
+void test_free(void *ptr);
+#else
+#define test_free(ptr) _test_free(ptr, __FILE__, __LINE__)
+#endif
+
+/* Redirect malloc, calloc and free to the unit test allocators. */
+#ifdef UNIT_TESTING
+#define malloc test_malloc
+#define realloc test_realloc
+#define calloc test_calloc
+#define free test_free
+#endif /* UNIT_TESTING */
+
+/** @} */
+
+
+/**
+ * @defgroup cmocka_mock_assert Standard Assertions
+ * @ingroup cmocka
+ *
+ * How to handle assert(3) of the standard C library.
+ *
+ * Runtime assert macros like the standard C library's assert() should be
+ * redefined in modules being tested to use cmocka's mock_assert() function.
+ * Normally mock_assert() signals a test failure. If a function is called using
+ * the expect_assert_failure() macro, any calls to mock_assert() within the
+ * function will result in the execution of the test. If no calls to
+ * mock_assert() occur during the function called via expect_assert_failure() a
+ * test failure is signalled.
+ *
+ * @{
+ */
+
+/**
+ * @brief Function to replace assert(3) in tested code.
+ *
+ * In conjuction with check_assert() it's possible to determine whether an
+ * assert condition has failed without stopping a test.
+ *
+ * @param[in]  result  The expression to assert.
+ *
+ * @param[in]  expression  The expression as string.
+ *
+ * @param[in]  file  The file mock_assert() is called.
+ *
+ * @param[in]  line  The line mock_assert() is called.
+ *
+ * @code
+ * #ifdef UNIT_TESTING
+ * extern void mock_assert(const int result, const char* const expression,
+ *                         const char * const file, const int line);
+ *
+ * #undef assert
+ * #define assert(expression) \
+ *     mock_assert((int)(expression), #expression, __FILE__, __LINE__);
+ * #endif
+ *
+ * void increment_value(int * const value) {
+ *     assert(value);
+ *     (*value) ++;
+ * }
+ * @endcode
+ *
+ * @see assert(3)
+ * @see expect_assert_failure
+ */
+void mock_assert(const int result, const char* const expression,
+                 const char * const file, const int line);
+
+#ifdef DOXYGEN
+/**
+ * @brief Ensure that mock_assert() is called.
+ *
+ * If mock_assert() is called the assert expression string is returned.
+ *
+ * @param[in]  fn_call  The function will will call mock_assert().
+ *
+ * @code
+ * #define assert mock_assert
+ *
+ * void showmessage(const char *message) {
+ *   assert(message);
+ * }
+ *
+ * int main(int argc, const char* argv[]) {
+ *   expect_assert_failure(show_message(NULL));
+ *   printf("succeeded\n");
+ *   return 0;
+ * }
+ * @endcode
+ *
+ */
+void expect_assert_failure(function fn_call);
+#else
+#define expect_assert_failure(function_call) \
+  { \
+    const int result = setjmp(global_expect_assert_env); \
+    global_expecting_assert = 1; \
+    if (result) { \
+      print_message("Expected assertion %s occurred\n", \
+                    global_last_failed_assert); \
+      global_expecting_assert = 0; \
+    } else { \
+      function_call ; \
+      global_expecting_assert = 0; \
+      print_error("Expected assert in %s\n", #function_call); \
+      _fail(__FILE__, __LINE__); \
+    } \
+  }
+#endif
+
+/** @} */
+
+/* Function prototype for setup, test and teardown functions. */
+typedef void (*UnitTestFunction)(void **state);
+
+/* Function that determines whether a function parameter value is correct. */
+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_GROUP_SETUP,
+    UNIT_TEST_FUNCTION_TYPE_GROUP_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.
+ */
+typedef struct UnitTest {
+    const char* name;
+    UnitTestFunction function;
+    UnitTestFunctionType function_type;
+} UnitTest;
+
+typedef struct GroupTest {
+    UnitTestFunction setup;
+    UnitTestFunction teardown;
+    const UnitTest *tests;
+    const size_t number_of_tests;
+} GroupTest;
+
+/* Function prototype for test functions. */
+typedef void (*CMUnitTestFunction)(void **state);
+
+/* Function prototype for setup and teardown functions. */
+typedef int (*CMFixtureFunction)(void **state);
+
+struct CMUnitTest {
+    const char *name;
+    CMUnitTestFunction test_func;
+    CMFixtureFunction setup_func;
+    CMFixtureFunction teardown_func;
+    void *initial_state;
+};
+
+/* Location within some source code. */
+typedef struct SourceLocation {
+    const char* file;
+    int line;
+} SourceLocation;
+
+/* Event that's called to check a parameter value. */
+typedef struct CheckParameterEvent {
+    SourceLocation location;
+    const char *parameter_name;
+    CheckParameterValue check_value;
+    LargestIntegralType check_value_data;
+} CheckParameterEvent;
+
+/* Used by expect_assert_failure() and mock_assert(). */
+extern int global_expecting_assert;
+extern jmp_buf global_expect_assert_env;
+extern const char * global_last_failed_assert;
+
+/* Retrieves a value for the given function, as set by "will_return". */
+LargestIntegralType _mock(const char * const function, const char* const file,
+                          const int line);
+
+void _expect_function_call(
+    const char * const function_name,
+    const char * const file,
+    const int line,
+    const int count);
+
+void _function_called(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 file, const int line,
+    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 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 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 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 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 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 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 int count);
+void _expect_not_string(
+    const char* const function, const char* const parameter,
+    const char* const file, const int line, const char* string,
+    const int count);
+
+void _expect_memory(
+    const char* const function, const char* const parameter,
+    const char* const file, const int line, const void* const memory,
+    const size_t size, const int count);
+void _expect_not_memory(
+    const char* const function, const char* const parameter,
+    const char* const file, const int line, const void* const memory,
+    const 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 LargestIntegralType value);
+
+void _will_return(const char * const function_name, const char * const file,
+                  const int line, const LargestIntegralType value,
+                  const int count);
+void _assert_true(const LargestIntegralType result,
+                  const char* const expression,
+                  const char * const file, const int line);
+void _assert_return_code(const LargestIntegralType result,
+                         size_t rlen,
+                         const LargestIntegralType error,
+                         const char * const expression,
+                         const char * const file,
+                         const int line);
+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,
+                              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,
+                          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 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_realloc(void *ptr, const size_t size, const char* file, const int line);
+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);
+
+void _skip(const char * const file, const int line);
+
+int _run_test(
+    const char * const function_name, const UnitTestFunction Function,
+    void ** const volatile state, const UnitTestFunctionType function_type,
+    const void* const heap_check_point);
+CMOCKA_DEPRECATED int _run_tests(const UnitTest * const tests,
+                                 const size_t number_of_tests);
+CMOCKA_DEPRECATED int _run_group_tests(const UnitTest * const tests,
+                                       const size_t number_of_tests);
+
+/* Test runner */
+int _cmocka_run_group_tests(const char *group_name,
+                            const struct CMUnitTest * const tests,
+                            const size_t num_tests,
+                            CMFixtureFunction group_setup,
+                            CMFixtureFunction group_teardown);
+
+/* Standard output and error print methods. */
+void print_message(const char* const format, ...) CMOCKA_PRINTF_ATTRIBUTE(1, 2);
+void print_error(const char* const format, ...) CMOCKA_PRINTF_ATTRIBUTE(1, 2);
+void vprint_message(const char* const format, va_list args) CMOCKA_PRINTF_ATTRIBUTE(1, 0);
+void vprint_error(const char* const format, va_list args) CMOCKA_PRINTF_ATTRIBUTE(1, 0);
+
+enum cm_message_output {
+    CM_OUTPUT_STDOUT,
+    CM_OUTPUT_SUBUNIT,
+    CM_OUTPUT_TAP,
+    CM_OUTPUT_XML,
+};
+
+/**
+ * @brief Function to set the output format for a test.
+ *
+ * The ouput format for the test can either be set globally using this
+ * function or overriden with environment variable CMOCKA_MESSAGE_OUTPUT.
+ *
+ * The environment variable can be set to either STDOUT, SUBUNIT, TAP or XML.
+ *
+ * @param[in] output    The output format to use for the test.
+ *
+ */
+void cmocka_set_message_output(enum cm_message_output output);
+
+/** @} */
+
+#endif /* CMOCKA_H_ */
diff --git a/third_party/cmocka/cmocka_private.h b/third_party/cmocka/cmocka_private.h
new file mode 100644
index 00000000000..d20d841aed5
--- /dev/null
+++ b/third_party/cmocka/cmocka_private.h
@@ -0,0 +1,163 @@
+/*
+ * Copyright 2008 Google Inc.
+ *
+ * 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.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef CMOCKA_PRIVATE_H_
+#define CMOCKA_PRIVATE_H_
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <stdint.h>
+
+#ifdef _WIN32
+#include <windows.h>
+
+# ifdef _MSC_VER
+# include <stdio.h> /* _snprintf */
+
+#  undef inline
+#  define inline __inline
+
+#  ifndef va_copy
+#   define va_copy(dest, src) (dest = src)
+#  endif
+
+#  define strcasecmp _stricmp
+#  define strncasecmp _strnicmp
+
+#  if defined(HAVE__SNPRINTF_S)
+#   undef snprintf
+#   define snprintf(d, n, ...) _snprintf_s((d), (n), _TRUNCATE, __VA_ARGS__)
+#  else /* HAVE__SNPRINTF_S */
+#   if defined(HAVE__SNPRINTF)
+#     undef snprintf
+#     define snprintf _snprintf
+#   else /* HAVE__SNPRINTF */
+#    if !defined(HAVE_SNPRINTF)
+#     error "no snprintf compatible function found"
+#    endif /* HAVE_SNPRINTF */
+#   endif /* HAVE__SNPRINTF */
+#  endif /* HAVE__SNPRINTF_S */
+
+#  if defined(HAVE__VSNPRINTF_S)
+#   undef vsnprintf
+#   define vsnprintf(s, n, f, v) _vsnprintf_s((s), (n), _TRUNCATE, (f), (v))
+#  else /* HAVE__VSNPRINTF_S */
+#   if defined(HAVE__VSNPRINTF)
+#    undef vsnprintf
+#    define vsnprintf _vsnprintf
+#   else
+#    if !defined(HAVE_VSNPRINTF)
+#     error "No vsnprintf compatible function found"
+#    endif /* HAVE_VSNPRINTF */
+#   endif /* HAVE__VSNPRINTF */
+#  endif /* HAVE__VSNPRINTF_S */
+# endif /* _MSC_VER */
+
+/*
+ * Backwards compatibility with headers shipped with Visual Studio 2005 and
+ * earlier.
+ */
+WINBASEAPI BOOL WINAPI IsDebuggerPresent(VOID);
+
+#ifndef PRIdS
+# define PRIdS "Id"
+#endif
+
+#ifndef PRIu64
+# define PRIu64 "I64u"
+#endif
+
+#ifndef PRIuMAX
+# define PRIuMAX PRIu64
+#endif
+
+#ifndef PRIxMAX
+#define PRIxMAX "I64x"
+#endif
+
+#ifndef PRIXMAX
+#define PRIXMAX "I64X"
+#endif
+
+#else /* _WIN32 */
+
+#ifndef __PRI64_PREFIX
+# if __WORDSIZE == 64
+#  define __PRI64_PREFIX "l"
+# else
+#  define __PRI64_PREFIX "ll"
+# endif
+#endif
+
+#ifndef PRIdS
+# define PRIdS "zd"
+#endif
+
+#ifndef PRIu64
+# define PRIu64 __PRI64_PREFIX "u"
+#endif
+
+#ifndef PRIuMAX
+# define PRIuMAX __PRI64_PREFIX "u"
+#endif
+
+#ifndef PRIxMAX
+#define PRIxMAX __PRI64_PREFIX "x"
+#endif
+
+#ifndef PRIXMAX
+#define PRIXMAX __PRI64_PREFIX "X"
+#endif
+
+#endif /* _WIN32 */
+
+/** Free memory space */
+#define SAFE_FREE(x) do { if ((x) != NULL) {free(x); x=NULL;} } while(0)
+
+/** Zero a structure */
+#define ZERO_STRUCT(x) memset((char *)&(x), 0, sizeof(x))
+
+/** Zero a structure given a pointer to the structure */
+#define ZERO_STRUCTP(x) do { if ((x) != NULL) memset((char *)(x), 0, sizeof(*(x))); } while(0)
+
+/** Get the size of an array */
+#define ARRAY_SIZE(a) (sizeof(a)/sizeof(a[0]))
+
+/** Overwrite the complete string with 'X' */
+#define BURN_STRING(x) do { if ((x) != NULL) memset((x), 'X', strlen((x))); } while(0)
+
+/**
+ * This is a hack to fix warnings. The idea is to use this everywhere that we
+ * get the "discarding const" warning by the compiler. That doesn't actually
+ * fix the real issue, but marks the place and you can search the code for
+ * discard_const.
+ *
+ * Please use this macro only when there is no other way to fix the warning.
+ * We should use this function in only in a very few places.
+ *
+ * Also, please call this via the discard_const_p() macro interface, as that
+ * makes the return type safe.
+ */
+#define discard_const(ptr) ((void *)((uintptr_t)(ptr)))
+
+/**
+ * Type-safe version of discard_const
+ */
+#define discard_const_p(type, ptr) ((type *)discard_const(ptr))
+
+#endif /* CMOCKA_PRIVATE_H_ */
diff --git a/third_party/cmocka/wscript b/third_party/cmocka/wscript
new file mode 100644
index 00000000000..5ed56c9ceb0
--- /dev/null
+++ b/third_party/cmocka/wscript
@@ -0,0 +1,19 @@
+#!/usr/bin/env python
+
+import Options
+
+def configure(conf):
+    conf.CHECK_FUNCS('longjmp siglongjmp')
+
+    if conf.CHECK_CMOCKA():
+        conf.define('USING_SYSTEM_CMOCKA', 1)
+
+def build(bld):
+    if bld.CONFIG_SET('USING_SYSTEM_CMOCKA'):
+        return
+
+    bld.SAMBA_LIBRARY('cmocka',
+                      source='cmocka.c',
+                      deps='rt',
+                      allow_warnings=True,
+                      private_library=True)
diff --git a/third_party/wscript b/third_party/wscript
index d5b9df7bb96..ad4d6245bbd 100644
--- a/third_party/wscript
+++ b/third_party/wscript
@@ -47,6 +47,7 @@ Unable to find Python module '%s'. Please install the system package or place a
 def configure(conf):
     for module, package in external_pkgs.items():
         find_third_party_module(conf, module, package)
+    conf.RECURSE('cmocka')
     conf.RECURSE('popt')
     conf.RECURSE('zlib')
 
@@ -69,5 +70,6 @@ def build(bld):
                         target='empty_file')
 
     bld.INSTALL_FILES('${PYTHONARCHDIR}/samba/third_party', 'empty_file', destname='__init__.py')
+    bld.RECURSE('cmocka')
     bld.RECURSE('zlib')
     bld.RECURSE('popt')
diff --git a/wscript b/wscript
index 3e4a0cdb6d4..5a82c61472a 100644
--- a/wscript
+++ b/wscript
@@ -143,6 +143,12 @@ def configure(conf):
         else:
             conf.define('USING_SYSTEM_POPT', 1)
 
+        if not conf.CHECK_CMOCKA():
+            raise Utils.WafError('cmocka development packages has not been found.\nIf third_party is installed, check that it is in the proper place.')
+        else:
+            conf.define('USING_SYSTEM_CMOCKA', 1)
+
+
     conf.RECURSE('lib/ldb')
 
     if not (Options.options.without_ad_dc):
-- 
2.12.2



More information about the samba-technical mailing list