From 4a155d66eee4ab007de80df96ba6317f783f84f4 Mon Sep 17 00:00:00 2001 From: Aaro Saila Date: Thu, 2 Jul 2026 11:57:35 +0300 Subject: [PATCH] Testing framework. Shader creation function. More dynstring functions --- meson.build | 39 +- mingw32_x86_64.txt | 1 + src/DynString.c | 53 +- src/DynString.h | 13 + src/main.c | 70 +- src/shader.c | 88 + src/shader.h | 9 + src/shaders/shader.frag | 7 + src/shaders/shader.vert | 7 + tests/main.c | 80 + vendor/cmocka/cmocka.h | 7092 +++++++++++++++++++++++++++++++++++++ vendor/cmocka/libcmocka.a | Bin 0 -> 181760 bytes 12 files changed, 7388 insertions(+), 71 deletions(-) create mode 100644 src/shader.c create mode 100644 src/shader.h create mode 100644 src/shaders/shader.frag create mode 100644 src/shaders/shader.vert create mode 100644 tests/main.c create mode 100644 vendor/cmocka/cmocka.h create mode 100644 vendor/cmocka/libcmocka.a diff --git a/meson.build b/meson.build index 8b54dcc..896601a 100644 --- a/meson.build +++ b/meson.build @@ -1,20 +1,30 @@ project('scuffedcraft', 'c') +cc = meson.get_compiler('c') +vendor_dir_abs = meson.current_source_dir() + '/vendor/' + cargs = [ '-std=c99', '-Og', '-g', - '-DBOUNDS_CHECK' + '-DBOUNDS_CHECK', + '-DSHADERS_PATH="../src/shaders/"' ] -dependencies = [] +dependencies = [ +] link_args = [] +test_link_args = [] include_dirs = [ 'vendor/', 'src/' ] +test_include_dirs = [ + 'src/', + 'vendor/' +] if host_machine.system() == 'linux' dependencies += [ @@ -24,6 +34,9 @@ elif host_machine.system() == 'windows' link_args += [ '-lopengl32' ] + test_link_args += [ + '-lwinpthread' + ] cargs += [ '-DUNICODE', @@ -31,7 +44,7 @@ elif host_machine.system() == 'windows' '-municode' ] - if build_machine.system() == 'linux' + if meson.is_cross_build() and build_machine.system() == 'linux' link_args += [ '-Lvendor/wine/', ] @@ -46,8 +59,26 @@ executable( 'src/DynString.c', 'src/log.c', 'src/main.c', + 'src/shader.c', c_args: cargs, dependencies: dependencies, link_args: link_args, - include_directories: include_directories(include_dirs) + include_directories: include_directories(include_dirs), ) + + +executable( + 'tests', + 'tests/main.c', + 'src/DynString.c', + 'src/log.c', + c_args: cargs, + include_directories: include_directories(test_include_dirs), + link_args: test_link_args, + dependencies: [ + cc.find_library( + 'libcmocka', + dirs: [ vendor_dir_abs + 'cmocka/' ] + ) + ] +) diff --git a/mingw32_x86_64.txt b/mingw32_x86_64.txt index 1e8b61d..b1343fd 100644 --- a/mingw32_x86_64.txt +++ b/mingw32_x86_64.txt @@ -1,5 +1,6 @@ [binaries] c = 'x86_64-w64-mingw32-clang' +strip = 'x86_64-w64-mingw32-strip' exe_wrapper = 'wine' [host_machine] diff --git a/src/DynString.c b/src/DynString.c index 85f6f0c..30d3e96 100644 --- a/src/DynString.c +++ b/src/DynString.c @@ -1,19 +1,22 @@ +#include +#include #include #include -#include #include "DynString.h" #include "log.h" DynString DynString_alloc(const char* str, const size_t len) { DynString dstr = { - .data = (char*) malloc(sizeof(char) * len), - .len = len + .data = (char*) malloc(sizeof(char) * len + 1), + .len = len, + .capacity = len }; if (dstr.data == NULL) { LOG_FATAL("Ran out of memory"); } dstr.data = memcpy(dstr.data, str, len); + dstr.data[len] = '\0'; return dstr; } @@ -21,14 +24,20 @@ DynString DynString_alloc(const char* str, const size_t len) { void DynString_free(DynString* dstr) { if (dstr->data != NULL) { free(dstr->data); + dstr->data = NULL; } dstr->len = 0; + dstr->capacity = 0; } bool DynString_is_null(const DynString* dstr) { return dstr->data == NULL; } +const char* DynString_c_str(const DynString* dstr) { + return dstr->data; +} + bool DynString_equal(const DynString* s1, const DynString* s2) { if (s1->len != s2->len) { return false; @@ -47,3 +56,41 @@ bool DynString_equal(const DynString* s1, const DynString* s2) { return true; } +void DynString_reserve(DynString* dstr, const size_t new_capacity) { + if (dstr->capacity >= new_capacity) { + return; + } + + errno = 0; + dstr->data = realloc(dstr->data, new_capacity); + if (errno != 0) { + LOG_FATAL("Ran out of memory"); + } + dstr->capacity = new_capacity; +} + +void DynString_concat_c_str( + DynString* dstr, + const char* str, + const size_t str_len +) { + const size_t new_len = dstr->len + str_len; + if (new_len > dstr->capacity) { + DynString_reserve(dstr, new_len + 1); + } + + strncpy(dstr->data + dstr->len, str, str_len); + dstr->data[new_len] = '\0'; + dstr->len = new_len; +} + +DynString DynString_alloc_concat_c_strs( + const char* s1, + const size_t s1_len, + const char* s2, + const size_t s2_len +) { + DynString dstr = DynString_alloc(s1, s1_len); + DynString_concat_c_str(&dstr, s2, s2_len); + return dstr; +} diff --git a/src/DynString.h b/src/DynString.h index b31c2e5..cf20e73 100644 --- a/src/DynString.h +++ b/src/DynString.h @@ -9,11 +9,24 @@ typedef struct { char* data; size_t len; + size_t capacity; } DynString; DynString DynString_alloc(const char* str, const size_t len); void DynString_free(DynString* dstr); bool DynString_is_null(const DynString* dstr); +const char* DynString_c_str(const DynString* dstr); bool DynString_equal(const DynString* s1, const DynString* s2); +void DynString_concat_c_str( + DynString* dstr, + const char* str, + const size_t str_len +); +DynString DynString_alloc_concat_c_strs( + const char* s1, + const size_t s1_len, + const char* s2, + const size_t s2_len +); #endif // DYN_STRING_H_ diff --git a/src/main.c b/src/main.c index c967f5f..9955d54 100644 --- a/src/main.c +++ b/src/main.c @@ -15,6 +15,7 @@ #include "log.h" #include "pltf/gl_funcs.h" #include "pltf/pltf.h" +#include "shader.h" // int _main() { // return 0; @@ -396,69 +397,10 @@ int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR pCmdLine, glBindVertexArray(0); - // clang-format off - const char* vertex_shader_src = - "#version 460 core\n" - "layout (location = 0) in vec3 a_pos;\n" - "void main() {\n" - " gl_Position = vec4(a_pos, 1.0);\n" - "}\n" - ; - - const char* fragment_shader_src = - "#version 460 core\n" - "out vec4 frag_color;\n" - "void main() {\n" - " frag_color = vec4(0.0, 0.0, 0.0, 1.0);\n" - "}\n" - ; - // clang-format on - - const unsigned int vert_shader = glCreateShader(GL_VERTEX_SHADER); - { - const int len = strlen(vertex_shader_src); - glShaderSource(vert_shader, 1, &vertex_shader_src, &len); - glCompileShader(vert_shader); - int compile_status = 0; - glGetShaderiv(vert_shader, GL_COMPILE_STATUS, &compile_status); - if (compile_status != GL_TRUE) { - int info_log_len = 0; - glGetShaderiv(vert_shader, GL_INFO_LOG_LENGTH, &info_log_len); - char* err_str = (char*) malloc(sizeof(char) * info_log_len); - glGetShaderInfoLog(vert_shader, info_log_len - 1, NULL, err_str); - LOG_FATALF("Failed to compile vertex shader: %s", err_str); - } - } - const unsigned int frag_shader = glCreateShader(GL_FRAGMENT_SHADER); - { - const int len = strlen(fragment_shader_src); - glShaderSource(frag_shader, 1, &fragment_shader_src, &len); - glCompileShader(frag_shader); - int compile_status = 0; - glGetShaderiv(frag_shader, GL_COMPILE_STATUS, &compile_status); - if (compile_status != GL_TRUE) { - int info_log_len = 0; - glGetShaderiv(frag_shader, GL_INFO_LOG_LENGTH, &info_log_len); - char* err_str = (char*) malloc(sizeof(char) * info_log_len); - glGetShaderInfoLog(frag_shader, info_log_len - 1, NULL, err_str); - LOG_FATALF("Failed to compile fragment shader: %s", err_str); - } - } - - const unsigned int shader_program = glCreateProgram(); - { - - glAttachShader(shader_program, vert_shader); - glAttachShader(shader_program, frag_shader); - glLinkProgram(shader_program); - int compile_status = 0; - glGetProgramiv(shader_program, GL_LINK_STATUS, &compile_status); - if (compile_status != GL_TRUE) { - LOG_FATAL("Failed to link shader program."); - } - glDeleteShader(vert_shader); - glDeleteShader(frag_shader); - } + const unsigned int shader = shader_create( + "shader.vert", + "shader.frag" + ); MSG msg = { 0 }; while (true) { @@ -472,7 +414,7 @@ int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR pCmdLine, glClear(GL_COLOR_BUFFER_BIT); - glUseProgram(shader_program); + glUseProgram(shader); glBindVertexArray(triangle_vao); glDrawArrays(GL_TRIANGLE_STRIP, 0, triangle_vert_count); diff --git a/src/shader.c b/src/shader.c new file mode 100644 index 0000000..a705d6e --- /dev/null +++ b/src/shader.c @@ -0,0 +1,88 @@ +#include +#include +#include + +#include "DynString.h" +#include "pltf/gl_funcs.h" +#include "log.h" + +static char read_buf[512] = { 0 }; +static const size_t read_buf_len = sizeof(read_buf) / sizeof(read_buf[0]); + +static DynString read_shader_source(const char* path) { + const DynString full_path = DynString_alloc_concat_c_strs( + SHADERS_PATH, + strlen(SHADERS_PATH), + path, + strlen(path) + ); + + DynString source = DynString_alloc("", 0); + + FILE* shader_file = fopen(DynString_c_str(&full_path), "r"); + if (shader_file == NULL) { + LOG_ERRORF("Failed to open file %.*s. Errno: %d", DYN_STRING_FMT(full_path), errno); + return source; + } + + size_t bytes_read = 0; + do { + bytes_read = fread(read_buf, 1, read_buf_len - 1, shader_file); + read_buf[bytes_read] = '\0'; + DynString_concat_c_str(&source, read_buf, bytes_read); + } while (bytes_read == read_buf_len - 1); + + if (fclose(shader_file) == EOF) { + LOG_ERRORF("Failed to close file %s. Errno: %d", path, errno); + } + + return source; +} + +static unsigned int compile_shader(const DynString* shader_src, const GLenum shader_type) { + const unsigned int shader = glCreateShader(shader_type); + const char* shader_src_c_str = DynString_c_str(shader_src); + const int len = (int) shader_src->len; + glShaderSource(shader, 1, &shader_src_c_str, &len); + glCompileShader(shader); + int compile_status = 0; + glGetShaderiv(shader, GL_COMPILE_STATUS, &compile_status); + if (compile_status != GL_TRUE) { + int info_log_len = 0; + glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &info_log_len); + char* err_str = (char*) malloc(sizeof(char) * info_log_len); + glGetShaderInfoLog(shader, info_log_len - 1, NULL, err_str); + LOG_FATALF("Failed to compile vertex shader: %s", err_str); + } + + return shader; +} + +unsigned int shader_create( + const char* vertex_shader_path, + const char* fragment_shader_path +) { + DynString vert_source = read_shader_source(vertex_shader_path); + DynString frag_source = read_shader_source(fragment_shader_path); + + const unsigned int vert_shader = compile_shader(&vert_source, GL_VERTEX_SHADER); + const unsigned int frag_shader = compile_shader(&frag_source, GL_FRAGMENT_SHADER); + + DynString_free(&vert_source); + DynString_free(&frag_source); + + const unsigned int shader_program = glCreateProgram(); + glAttachShader(shader_program, vert_shader); + glAttachShader(shader_program, frag_shader); + glLinkProgram(shader_program); + int compile_status = 0; + glGetProgramiv(shader_program, GL_LINK_STATUS, &compile_status); + if (compile_status != GL_TRUE) { + LOG_FATAL("Failed to link shader program."); + } + + glDeleteShader(vert_shader); + glDeleteShader(frag_shader); + + return shader_program; +} diff --git a/src/shader.h b/src/shader.h new file mode 100644 index 0000000..a277c70 --- /dev/null +++ b/src/shader.h @@ -0,0 +1,9 @@ +#ifndef SHADER_H_ +#define SHADER_H_ + +unsigned int shader_create( + const char* vertex_shader_path, + const char* fragment_shader_path +); + +#endif // SHADER_H_ diff --git a/src/shaders/shader.frag b/src/shaders/shader.frag new file mode 100644 index 0000000..c8e8ca3 --- /dev/null +++ b/src/shaders/shader.frag @@ -0,0 +1,7 @@ +#version 460 core + +out vec4 frag_color; + +void main() { + frag_color = vec4(0.0, 0.0, 0.0, 1.0); +} diff --git a/src/shaders/shader.vert b/src/shaders/shader.vert new file mode 100644 index 0000000..93a796b --- /dev/null +++ b/src/shaders/shader.vert @@ -0,0 +1,7 @@ +#version 460 core + +layout (location = 0) in vec3 a_pos; + +void main() { + gl_Position = vec4(a_pos, 1.0); +} diff --git a/tests/main.c b/tests/main.c new file mode 100644 index 0000000..62648b5 --- /dev/null +++ b/tests/main.c @@ -0,0 +1,80 @@ +#include +#include + +#include "cmocka/cmocka.h" +#include "DynString.h" + +void test_DynString_alloc(void** state) { + const char* c_str = "Hello"; + const size_t c_str_len = strlen(c_str); + DynString dstr = DynString_alloc(c_str, c_str_len); + + assert_memory_equal(dstr.data, c_str, c_str_len + 1); + assert_true(dstr.len == c_str_len); + assert_true(dstr.capacity == c_str_len); + + free(dstr.data); +} + +void test_DynString_free(void** state) { + DynString dstr = DynString_alloc("Hello", strlen("Hello")); + + DynString_free(&dstr); + + assert_null(dstr.data); + assert_true(dstr.len == 0); + assert_true(dstr.capacity == 0); +} + +void test_DynString_equal(void** state) { + DynString s1 = DynString_alloc("Hello", strlen("Hello")); + DynString s2 = DynString_alloc("Hello", strlen("Hello")); + assert_true(DynString_equal(&s1, &s2)); + DynString_free(&s1); + DynString_free(&s2); + + s1 = DynString_alloc("Hello", strlen("Hello")); + s2 = DynString_alloc("Hello", strlen("Hello")); + assert_true(DynString_equal(&s1, &s2)); + DynString_free(&s1); + DynString_free(&s2); +} + +void test_DynString_concat_c_str(void** state) { + const char* dstr_c_str = "Hello"; + const char* c_str = " World"; + const size_t combined_length = strlen(dstr_c_str) + strlen(c_str); + + DynString dstr = DynString_alloc(dstr_c_str, strlen("Hello")); + DynString_concat_c_str(&dstr, c_str, strlen(c_str)); + + assert_memory_equal(dstr.data, "Hello World", strlen("Hello World")); + assert_true(dstr.len == combined_length); + assert_true(dstr.capacity == combined_length + 1); + + DynString_free(&dstr); +} + +void test_DynString_c_str(void** state) { + const char* c_str = "Hello"; + DynString dstr = DynString_alloc(c_str, strlen(c_str)); + + assert_string_equal(c_str, DynString_c_str(&dstr)); + + DynString_concat_c_str(&dstr, " World", strlen(" World")); + + assert_string_equal("Hello World", DynString_c_str(&dstr)); +} + +int main() { + const struct CMUnitTest tests[] = { + cmocka_unit_test(test_DynString_alloc), + cmocka_unit_test(test_DynString_free), + cmocka_unit_test(test_DynString_equal), + cmocka_unit_test(test_DynString_concat_c_str), + cmocka_unit_test(test_DynString_c_str), + }; + + return cmocka_run_group_tests(tests, NULL, NULL); +} + diff --git a/vendor/cmocka/cmocka.h b/vendor/cmocka/cmocka.h new file mode 100644 index 0000000..a63a807 --- /dev/null +++ b/vendor/cmocka/cmocka.h @@ -0,0 +1,7092 @@ +/* + * Copyright 2008 Google Inc. + * Copyright 2014-2022 Andreas Schneider + * + * 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 + +# ifndef CMOCKA_STATIC +# ifdef CMOCKA_EXPORTS +#define CMOCKA_DLLEXTERN __declspec(dllexport) +# else +#define CMOCKA_DLLEXTERN __declspec(dllimport) +# endif /* CMOCKA_EXPORTS */ +# endif /* ndef CMOCKA_STATIC */ + +#ifndef __func__ +#define __func__ __FUNCTION__ +#endif /* __func__ */ + +#ifndef inline +#define inline __inline +#endif /* inline */ + +# endif /* _MSC_VER */ +#endif /* _WIN32 */ + +/** + * @def CMOCKA_DLLEXTERN + * This attribute is needed when dynamically linking to a data object in a DLL. + * It's optional (but increases performance) for dynamically linking to + * functions in a DLL. + * @see + * https://github.com/MicrosoftDocs/cpp-docs/blob/bd5a4fbd8ea3dd47b5c7a228c266cdddcaca0e00/docs/cpp/dllexport-dllimport.md + */ +#ifndef CMOCKA_DLLEXTERN +#define CMOCKA_DLLEXTERN // only needed on MSVC compiler when using a DLL +#endif /* ndef CMOCKA_DLLEXTERN */ + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @defgroup cmocka 📚 The CMocka API + * @brief Unit testing framework for C with support for mock objects. + * + * cmocka is an elegant unit testing framework for C with support for mock + * objects. It only requires the standard C library, works on a lot of platforms + * (including embedded) and with different compilers. + * + * @section cmocka-includes Standard includes + * + * CMocka requires the include of the following list of standard headers or + * their equivalent. + * + * @code + * #include + * #include + * #include + * #include + * #include + * @endcode + * + * The header file 'cmocka.h' includes those headers already and in case your + * platform does not provide those header files, you must + * `#define CMOCKA_NO_STANDARD_INCLUDES` in order to prevent the include of + * those files. + * + * An example of how your code which uses CMocka could look like is given below. + * + * @code + * #include "path/to/cmocka_platform.h" + * #define CMOCKA_NO_STANDARD_INCLUDES + * #include + * // ... your test code goes here ... + * @endcode + */ + +#ifndef CMOCKA_NO_STANDARD_INCLUDES +#include +#include +#include +#include +#include +#endif + +/** + * @defgroup cmocka_util 🔨 Utility Macros and Types + * @ingroup cmocka + * @brief Type conversions, casting helpers, and common data structures. + * + * Internal utilities and data types used throughout the CMocka API. + * + * @{ + */ + +/* Perform an signed cast to intmax_t. */ +#define cast_to_intmax_type(value) \ + ((intmax_t)(value)) + +/* Perform an unsigned cast to uintmax_t. */ +#define cast_to_uintmax_type(value) \ + ((uintmax_t)(value)) + +/* Perform a safe cast from pointer to uintmax_t. */ +#define cast_ptr_to_uintmax_type(value) \ + ((uintmax_t)(uintptr_t)(value)) + +/* Perform cast to double. */ +#define cast_to_double_type(value) \ + ((double)(value)) + +/* Perform cast to float. */ +#define cast_to_float_type(value) \ + ((float)(value)) + +/** + * Perform cast to void pointer. + * + * ISO C forbids conversion between function pointers and void*. This macro + * provides a portable way to perform such conversions by casting through + * uintptr_t, which is allowed by POSIX and works on all practical platforms. + */ +#define cast_to_void_pointer(ptr) \ + ((void *)(uintptr_t)(ptr)) + +/** + * Perform a cast from an integer to CMockaValueData. + * + * For backwards compatibility reasons, this explicitly casts to `uintmax_t`. + * For most compilers, this will suppress warnings about passing float/intmax_t + * to this macro. + */ +#define cast_int_to_cmocka_value(value) \ + (CMockaValueData) \ + { \ + .uint_val = (uintmax_t)(value) \ + } + +/** Perform a cast from a pointer to CMockaValueData. */ +#define cast_ptr_to_cmocka_value(value) \ + (CMockaValueData) \ + { \ + .const_ptr = (value) \ + } + +/** Assign an integer value to CMockaValueData. */ +#define assign_int_to_cmocka_value(value) \ + (CMockaValueData) \ + { \ + .int_val = (value) \ + } + +/** Assign an unsigned integer value to CMockaValueData. */ +#define assign_uint_to_cmocka_value(value) \ + (CMockaValueData) \ + { \ + .uint_val = (value) \ + } + +/** Assign a floating point value to CMockaValueData. */ +#define assign_float_to_cmocka_value(value) \ + (CMockaValueData) \ + { \ + .float_val = ((float)(value)) \ + } + +/** Assign a double floating point value to CMockaValueData. */ +#define assign_double_to_cmocka_value(value) \ + (CMockaValueData) \ + { \ + .real_val = ((double)(value)) \ + } + +/* Nested macros are not expanded when they appear along with # or ## */ +#define cmocka_tostring(val) #val + +/** @cond INTERNAL */ +/* 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(CMOCKA_DISABLE_DEPRECATION_WARNINGS) || defined(CMOCKA_DISABLE_DEPRECTATION_WARNINGS) +#define CMOCKA_DEPRECATED +#define CMOCKA_DEPRECATION_WARNING(msg) +#else /* CMOCKA_DISABLE_DEPRECATION_WARNINGS */ + +/* Deprecation warnings for functions */ +#if defined(__GNUC__) +#define CMOCKA_DEPRECATED __attribute__ ((deprecated)) +#else +/* MSVC requires __declspec(deprecated) before the function declaration, + * not after it. Since we already use CMOCKA_DEPRECATION_WARNING() in + * the macro wrappers, we don't need function-level deprecation for MSVC. */ +#define CMOCKA_DEPRECATED +#endif + +/* Deprecation warnings for macros */ +#if defined(__GNUC__) || defined(__clang__) +/* Use a deprecated typedef in a statement expression to generate warnings + * that work even when the header is included as a system header (-isystem). + */ +#define CMOCKA_DEPRECATION_WARNING(msg) \ + __extension__({ \ + typedef int cmocka_macro __attribute__((deprecated(msg))); \ + cmocka_macro cmocka_deprecated_var __attribute__((unused)) = 0; \ + (void)sizeof(cmocka_deprecated_var); \ + }); +#elif defined(_MSC_VER) +#define CMOCKA_DEPRECATION_WARNING(msg) __pragma(message("warning: " msg)) +#else +#define CMOCKA_DEPRECATION_WARNING(msg) +#endif + +#endif /* CMOCKA_DISABLE_DEPRETATION_WARNINGS */ + +#if defined(__GNUC__) +#define CMOCKA_NORETURN __attribute__ ((noreturn)) +#elif defined(_MSC_VER) +#define CMOCKA_NORETURN __declspec(noreturn) +#else +#define CMOCKA_NORETURN +#endif + +/* Function attribute that tells the compiler that we never access the value + * of a/b, just the pointer address. + * + * Without this, newer compilers like GCC-12 will print + * `-Wmaybe-uninitialized` warnings. + * + * See: + * https://gcc.gnu.org/onlinedocs/gcc-12.2.0/gcc/Common-Function-Attributes.html#Common-Function-Attributes + */ +#ifdef __has_attribute +#if __has_attribute(access) +#define CMOCKA_NO_ACCESS_ATTRIBUTE \ + __attribute__((access(none, 1), access(none, 2))) +#endif +#endif +#ifndef CMOCKA_NO_ACCESS_ATTRIBUTE +#define CMOCKA_NO_ACCESS_ATTRIBUTE +#endif +/** @endcond */ + +/** @} */ /* cmocka_util */ + +/** + * @defgroup cmocka_mock 🎪 Mock Objects + * @ingroup cmocka + * @brief Simulate objects and control function return values in tests. + * + * 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. + * + *
    + *
  • will_return(function, value) - The will_return() macro + * pushes a value onto a queue of mock values. This macro is intended to be + * used by the unit test itself, while programming the behaviour of the mocked + * object.
  • + * + *
  • mock() - the mock macro pops a value from a queue of + * test values. The user of the mock() macro is the mocked object that uses it + * to learn how it should behave.
  • + *
+ * + * 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 + * queue 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_ptr_type(chef_cook, "hotdog", const char *); + * will_return_int(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) + * { + * *dish_out = mock_ptr_type(char *); // "hotdog" + * int return_code = mock_int(); // 0 + * return return_code; + * } + * @endcode + * + * For a complete example please take a look + * here. + * + * @{ + */ + +/** + * @brief Return a value indefinitely when used with will_return_count(). + * + * This constant can be passed as the count parameter to will_return_count() + * and related functions to indicate that the specified value should be + * returned every time the mocked function is called, without limit. + * + * @see will_return_count() + * @see will_return_int_count() + * @see will_return_uint_count() + * @see will_return_ptr_count() + */ +#define WILL_RETURN_ALWAYS -1 + +/** + * @brief Return a value once when used with will_return_count(). + * + * This constant can be passed as the count parameter to will_return_count() + * and related functions to indicate that the specified value should be + * returned only the next time the mocked function is called. This is the + * default behavior of will_return() and related macros. + * + * @see will_return_count() + * @see will_return() + */ +#define WILL_RETURN_ONCE -2 + +/** + * @brief Check a parameter every time when used with expect_check_data_count(). + * + * This constant can be passed as the count parameter to expect_check_data_count() + * to indicate that the parameter check should be performed every time the mocked + * function is called. The test will fail if the function is never called. + * + * @see expect_check_data_count() + */ +#define EXPECT_ALWAYS -1 + +/** + * @brief Optionally check a parameter when used with expect_check_data_count(). + * + * This constant can be passed as the count parameter to expect_check_data_count() + * to indicate that the parameter check is optional. The check will be performed + * if the function is called, but the test will not fail if it's never called. + * + * @see expect_check_data_count() + */ +#define EXPECT_MAYBE -2 + +#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() + */ +uintmax_t mock(void); +#else +#define mock() (_mock(__func__, __FILE__, __LINE__, NULL)).uint_val +#endif + + +#ifdef DOXYGEN +/** + * @brief Retrieve a value of the current function and cast it to given type. + * + * The value would be casted to type internally to avoid having the + * caller to do the cast manually. Type safety checks are disabled with that + * function. + * + * @param[in] #type The expected type of the return value + * + * @return The value which was stored to return by this function casted to the + * specified type. + * + * @code + * int param; + * + * param = mock_type(int); + * @endcode + * + * @see will_return() + */ +type mock_type(#type); +#else +#define mock_type(type) ((type) mock()) +#endif + +#ifdef DOXYGEN +/** + * @brief Check if data is available for the current mock function. + * + * This function checks if there is data available for the current mock function + * which calls has_mock() without consuming it. This is useful when you want to + * check if mock data has been set up before calling mock(). + * + * @return true if mock data is available, false otherwise. + * + * @code + * int example_mock_function(void) + * { + * if (has_mock()) { + * return mock_int(); + * } + * return default_value; + * } + * @endcode + * + * @see mock() + * @see mock_int() + * @see mock_uint() + * @see mock_float() + * @see will_return() + */ +bool has_mock(void); +#else +#define has_mock() _has_mock(__func__) +#endif + +#ifdef DOXYGEN +/** + * @brief Retrieve an integer return value of the current function. + * + * @return The value which was stored to return by this function. + * + * @code + * intmax_t param; + * + * param = mock_int(); + * @endcode + * + * @see will_return_int() + */ +intmax_t mock_int(); +#else +/* TODO: Enable type safety check by passing intmax_t instead of NULL */ +#define mock_int() (_mock(__func__, __FILE__, __LINE__, NULL)).int_val +#endif + + +#ifdef DOXYGEN +/** + * @brief Retrieve an unsigned integer return value of the current function. + * + * @return The value which was stored to return by this function. + * + * @code + * uintmax_t param; + * + * param = mock_uint(); + * @endcode + * + * @see will_return_uint() + */ +uintmax_t mock_uint(void); +#else +#define mock_uint() (_mock(__func__, __FILE__, __LINE__, "uintmax_t")).uint_val +#endif + + +#ifdef DOXYGEN +/** + * @brief Retrieve a float return value of the current function. + * + * @return The float value which was stored to return by this function. + * + * @see will_return_float() + */ +float mock_float(void); +#else +#define mock_float() (_mock(__func__, __FILE__, __LINE__, NULL)).float_val +#endif + +#ifdef DOXYGEN +/** + * @brief Retrieve a double precision floating point return value of the + * current function. + * + * @return The double value which was stored to return by this function. + * + * @see will_return_double() + */ +double mock_double(void); +#else +#define mock_double() (_mock(__func__, __FILE__, __LINE__, NULL)).real_val +#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. This macro does NOT perform type checking. + * For type-safe pointer retrieval, use mock_ptr_type_checked() instead. + * + * @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_ptr() + * @see mock_ptr_type_checked() + */ +type mock_ptr_type(#type); +#else +#define mock_ptr_type(type) \ + ((type)(_mock(__func__, __FILE__, __LINE__, NULL)).ptr) +#endif + +#ifdef DOXYGEN +/** + * @brief Retrieve a typed return value of the current function with type checking. + * + * The value would be casted to type internally to avoid having the + * caller to do the cast manually. This macro DOES perform type checking + * and will fail the test if the type used with will_return_ptr_type() + * does not match the type passed to this macro. + * + * @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_checked(char *); + * @endcode + * + * @see will_return_ptr_type() + * @see mock_ptr_type() + */ +type mock_ptr_type_checked(#type); +#else +#define mock_ptr_type_checked(type) \ + ((type)(_mock(__func__, __FILE__, __LINE__, #type)).ptr) +#endif + +#ifdef DOXYGEN +/** + * @brief Retrieve a named value for the current function. + * + * @param[in] #name The name under which to look for the value + * + * @return The value which was stored under the given name for this function. + * + * @code + * int param; + * param = (int)mock_parameter(number); + * @endcode + * + * @see mock() + * @see mock_parameter_type() + * @see mock_parameter_int() + * @see mock_parameter_uint() + * @see mock_parameter_float() + * @see mock_parameter_ptr() + * @see mock_parameter_ptr_type() + * @see will_return() + * @see will_set_parameter() + * @see will_set_parameter_int() + * @see will_set_parameter_uint() + * @see will_set_parameter_float() + * @see will_set_parameter_count() + * @see will_set_parameter_always() + * @see will_set_parameter_maybe() + * @see will_set_parameter_ptr() + * @see will_set_parameter_ptr_type() + * @see will_set_parameter_ptr_count() + * @see will_set_parameter_ptr_always() + * @see will_set_parameter_ptr_maybe() + */ +uintmax_t mock_parameter(#name); +#else +#define mock_parameter(name) \ + (_mock_parameter(__func__, #name, __FILE__, __LINE__, NULL)).uint_val +#endif + +#ifdef DOXYGEN +/** + * @brief Retrieve a named value for the current function and cast it to given type. + * + * The value would be casted to type internally to avoid having the + * caller to do the cast manually. Type safety checks are disabled with that + * function. + * + * @param[in] #name The name under which to look for the value + * + * @param[in] #type The expected type of the named value + * + * @return The value which was stored under name for this function. + * + * @code + * int param; + * + * param = mock_parameter_type(param, int); + * @endcode + * + * @see mock_parameter() + * @see will_set_parameter() + */ +#type mock_parameter_type(#name, #type); +#else +#define mock_parameter_type(name, type) ((type) mock_parameter(#name)) +#endif + +#ifdef DOXYGEN +/** + * @brief Retrieve a named integer value for the current function. + * + * @param[in] #name The name under which to look for the value + * + * @return The integer value which was stored under the given name for this function. + * + * @code + * intmax_t param; + * + * param = mock_parameter_int(param); + * @endcode + * + * @see mock_parameter() + * @see will_set_parameter() + * @see will_set_parameter_int() + */ +intmax_t mock_parameter_int(#name); +#else +#define mock_parameter_int(name) \ + (_mock_parameter(__func__, #name, __FILE__, __LINE__, "intmax_t")).int_val +#endif + +#ifdef DOXYGEN +/** + * @brief Retrieve an unsigned integer return value of the current function. + * + * @param[in] #name The name under which to look for the value + * + * @return The value which was stored to return by this function. + * + * @code + * uintmax_t param; + * + * param = mock_parameter_uint(param); + * @endcode + * + * @see mock_parameter() + * @see will_set_parameter() + * @see will_set_parameter_uint() + */ +uintmax_t mock_parameter_uint(#name); +#else +#define mock_parameter_uint(name) \ + (_mock_parameter(__func__, #name, __FILE__, __LINE__, "uintmax_t")).uint_val +#endif + +#ifdef DOXYGEN +/** + * @brief Retrieve a named float value for the current function. + * + * @param[in] #name The name under which to look for the value + * + * @return The float value which was stored to return by this function. + * + * @code + * float param; + * + * param = mock_parameter_float(param); + * @endcode + * + * @see mock_parameter() + * @see will_set_parameter() + * @see will_set_parameter_float() + */ +float mock_parameter_float(#name); +#else +#define mock_parameter_float(name) \ + (_mock_parameter(__func__, #name, __FILE__, __LINE__, "float")).float_val +#endif + +#ifdef DOXYGEN +/** + * @brief Retrieve a named double precision floating point value for the + * current function. + * + * @param[in] #name The name under which to look for the value + * + * @return The double value which was stored to return by this function. + * + * @code + * double param; + * + * param = mock_parameter_double(param); + * @endcode + * + * @see mock_parameter() + * @see will_set_parameter_double() + */ +double mock_parameter_double(#name); +#else +#define mock_parameter_double(name) \ + (_mock_parameter(__func__, #name, __FILE__, __LINE__, "double")).real_val +#endif + +#ifdef DOXYGEN +/** + * @brief Retrieve a named pointer for the current function. + * + * @param[in] #name The name under which to look for the pointer + * + * @return The pointer which was stored to return by this function. + * + * @code + * int *result + * result = (int*)mock_parameter_ptr(result); + * @endcode + * + * @see mock_parameter() + * @see will_set_parameter() + * @see will_set_parameter_ptr() + */ +void *mock_parameter_ptr(#name); +#else +#define mock_parameter_ptr(name) \ + ((_mock_parameter(__func__, #name, __FILE__, __LINE__, NULL)).ptr) +#endif + +#ifdef DOXYGEN +/** + * @brief Retrieve a named pointer for the current function. + * + * In addition it checks if if the type specified by the call to + * will_return_ptr_type() is the same. + * And casts it to that type. + * + * @param[in] #name The name under which to look for the pointer + * + * @return The pointer which was stored to return by this function. + * + * @code + * int *result + * result = mock_parameter_ptr_type(result, int*); + * @endcode + * + * @see mock_parameter() + * @see will_set_parameter() + * @see will_set_parameter_ptr_type() + */ +type mock_parameter_ptr_type(#name, #type); +#else +#define mock_parameter_ptr_type(name, type) \ + ((type)(_mock_parameter(__func__, #name, __FILE__, __LINE__, #type)).ptr) +#endif + +#ifdef DOXYGEN +/** + * @brief set errno for the current function. + * + * @code + * mock_errno(); + * @endcode + */ +void mock_errno(void); +#else +#define mock_errno() \ + do { \ + intmax_t err = (_mock_parameter( \ + __func__, \ + "/errno", \ + __FILE__, \ + __LINE__, \ + "errno")).int_val; \ + if (err != 0) { \ + errno = err; \ + } \ + } while (0) +#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 mock_int() + * @see mock_uint() + * @see mock_float() + * @see will_return_int() + * @see will_return_uint() + * @see will_return_float() + * @see will_return_ptr_type() + * @see will_return_count() + * @see will_return_always() + * @see will_return_ptr_always() + */ +void will_return(#function, uintmax_t value); +#else +#define will_return(function, value) \ + _will_return(cmocka_tostring(function), \ + __FILE__, \ + __LINE__, \ + NULL, \ + cast_int_to_cmocka_value(value), \ + 1) +#endif + +#ifdef DOXYGEN +/** + * @brief Store an integer 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 + * int32_t return_int32(void) + * { + * return (int32_t)mock_int(); + * } + * + * static void test_integer_return(void **state) + * { + * will_return_int(return_int32, -42); + * + * assert_int_equal(my_function_calling_return_int32(), -42); + * } + * @endcode + * + * @see mock_int() + */ +void will_return_int(#function, intmax_t value); +#else +#define will_return_int(function, value) \ + _will_return(#function, \ + __FILE__, \ + __LINE__, \ + "intmax_t", \ + assign_int_to_cmocka_value(value), \ + 1) +#endif + +#ifdef DOXYGEN +/** + * @brief Store an integer value to be returned a specified number of times 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_int(). 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_int(), but is not required to be + * returned. + * + * @code + * int32_t return_int32(void) + * { + * return (int32_t)mock_int(); + * } + * + * static void test_integer_return(void **state) + * { + * will_return_int_count(return_int32, -42, 3); + * + * assert_int_equal(my_function_calling_return_int32(), -42); + * assert_int_equal(my_function_calling_return_int32(), -42); + * assert_int_equal(my_function_calling_return_int32(), -42); + * } + * @endcode + * + * @see mock_int() + * @see will_return_int() + */ +void will_return_int_count(#function, intmax_t value, int count); +#else +#define will_return_int_count(function, value, count) \ + _will_return(#function, \ + __FILE__, \ + __LINE__, \ + "intmax_t", \ + assign_int_to_cmocka_value(value), \ + count) +#endif + +#ifdef DOXYGEN +/** + * @brief Store a unsigned integer 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 + * uint32_t return_uint32(void) + * { + * return (uint32_t)mock_uint(); + * } + * + * static void test_integer_return(void **state) + * { + * will_return_uint(return_uint32, 42); + * + * assert_uint_equal(my_function_calling_return_uint32(), 42); + * } + * @endcode + * + * @see mock_uint() + * @see will_return_count() + */ +void will_return_uint(#function, uintmax_t value); +#else +#define will_return_uint(function, value) \ + _will_return(#function, \ + __FILE__, \ + __LINE__, \ + "uintmax_t", \ + assign_uint_to_cmocka_value(value), \ + 1) +#endif + +#ifdef DOXYGEN +/** + * @brief Store an unsigned integer value to be returned a specified number of + * times 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_uint(). 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_uint(), but is not required to be + * returned. + * + * @code + * uint32_t return_uint32(void) + * { + * return (uint32_t)mock_uint(); + * } + * + * static void test_integer_return(void **state) + * { + * will_return_uint_count(return_uint32, 42, 3); + * + * assert_uint_equal(my_function_calling_return_uint32(), 42); + * assert_uint_equal(my_function_calling_return_uint32(), 42); + * assert_uint_equal(my_function_calling_return_uint32(), 42); + * } + * @endcode + * + * @see mock_uint() + * @see will_return_uint() + */ +void will_return_uint_count(#function, uintmax_t value, int count); +#else +#define will_return_uint_count(function, value, count) \ + _will_return(#function, \ + __FILE__, \ + __LINE__, \ + "uintmax_t", \ + assign_uint_to_cmocka_value(value), \ + count) +#endif + +#ifdef DOXYGEN +/** + * @brief Store a float value to be returned by mock() later. + * + * @param[in] #function The function which should return the given value. + * + * @param[in] value The float value to be returned by mock(). + * + * @code + * float return_float(void) + * { + * return mock_float(); + * } + * + * static void test_float_return(void **state) + * { + * will_return_float(return_float, 1.0f); + * + * assert_float_equal(my_function_calling_return_float(), 1.0f, 0.01f); + * } + * @endcode + * + * @see mock_float() + * @see mock_double() + */ +void will_return_float(#function, float value); +#else +#define will_return_float(function, value) \ + _will_return(#function, \ + __FILE__, \ + __LINE__, \ + "float", \ + assign_float_to_cmocka_value(value), \ + 1) +#endif + +#ifdef DOXYGEN +/** + * @brief Store a float value to be returned a specified number of times by + * mock() later. + * + * @param[in] #function The function which should return the given value. + * + * @param[in] value The float value to be returned by mock(). + * + * @param[in] count The parameter indicates the number of times the value + * should be returned by mock_float(). 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_float(), but is not required to be + * returned. + * + * @code + * float return_float(void) + * { + * return mock_float(); + * } + * + * static void test_float_return(void **state) + * { + * will_return_float_count(return_float, 1.0f, 3); + * + * assert_float_equal(my_function_calling_return_float(), 1.0f, 0.01f); + * assert_float_equal(my_function_calling_return_float(), 1.0f, 0.01f); + * assert_float_equal(my_function_calling_return_float(), 1.0f, 0.01f); + * } + * @endcode + * + * @see mock_float() + * @see will_return_float() + */ +void will_return_float_count(#function, float value, int count); +#else +#define will_return_float_count(function, value, count) \ + _will_return(#function, \ + __FILE__, \ + __LINE__, \ + "float", \ + assign_float_to_cmocka_value(value), \ + count) +#endif + +#ifdef DOXYGEN +/** + * @brief Store a double precision floating point value to be returned by + * mock() later. + * + * @param[in] #function The function which should return the given value. + * + * @param[in] value The double value to be returned by mock(). + * + * @code + * double return_double(void) + * { + * return mock_double(); + * } + * + * static void test_double_return(void **state) + * { + * will_return_double(return_double, 2.5); + * + * assert_double_equal(my_function_calling_return_double(), 2.5, 0.01); + * } + * @endcode + * + * @see mock_double() + */ +void will_return_double(#function, double value); +#else +#define will_return_double(function, value) \ + _will_return(#function, \ + __FILE__, \ + __LINE__, \ + "double", \ + assign_double_to_cmocka_value(value), \ + 1) +#endif + +#ifdef DOXYGEN +/** + * @brief Store a double precision floating point value to be returned a + * specified number of times by mock() later. + * + * @param[in] #function The function which should return the given value. + * + * @param[in] value The double value to be returned by mock(). + * + * @param[in] count The parameter indicates the number of times the value + * should be returned by mock_double(). 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_double(), but is not required to be + * returned. + * + * @code + * double return_double(void) + * { + * return mock_double(); + * } + * + * static void test_double_return(void **state) + * { + * will_return_double_count(return_double, 2.5, 3); + * + * assert_double_equal(my_function_calling_return_double(), 2.5, 0.01); + * assert_double_equal(my_function_calling_return_double(), 2.5, 0.01); + * assert_double_equal(my_function_calling_return_double(), 2.5, 0.01); + * } + * @endcode + * + * @see mock_double() + * @see will_return_double() + */ +void will_return_double_count(#function, double value, int count); +#else +#define will_return_double_count(function, value, count) \ + _will_return(#function, \ + __FILE__, \ + __LINE__, \ + "double", \ + assign_double_to_cmocka_value(value), \ + count) +#endif + +#ifdef DOXYGEN +/** + * @brief Store an integer value that will always be returned by mock_int(). + * + * @param[in] #function The function which should return the given value. + * + * @param[in] value The value to be returned by mock_int(). + * + * This is equivalent to: + * @code + * will_return_int_count(function, value, -1); + * @endcode + * + * @see will_return_int_count() + * @see mock_int() + */ +void will_return_int_always(#function, intmax_t value); +#else +#define will_return_int_always(function, value) \ + will_return_int_count(function, (value), WILL_RETURN_ALWAYS) +#endif + +#ifdef DOXYGEN +/** + * @brief Store an unsigned integer value that will always be returned by + * mock_uint(). + * + * @param[in] #function The function which should return the given value. + * + * @param[in] value The value to be returned by mock_uint(). + * + * This is equivalent to: + * @code + * will_return_uint_count(function, value, -1); + * @endcode + * + * @see will_return_uint_count() + * @see mock_uint() + */ +void will_return_uint_always(#function, uintmax_t value); +#else +#define will_return_uint_always(function, value) \ + will_return_uint_count(function, (value), WILL_RETURN_ALWAYS) +#endif + +#ifdef DOXYGEN +/** + * @brief Store a float value that will always be returned by mock_float(). + * + * @param[in] #function The function which should return the given value. + * + * @param[in] value The value to be returned by mock_float(). + * + * This is equivalent to: + * @code + * will_return_float_count(function, value, -1); + * @endcode + * + * @see will_return_float_count() + * @see mock_float() + */ +void will_return_float_always(#function, float value); +#else +#define will_return_float_always(function, value) \ + will_return_float_count(function, (value), WILL_RETURN_ALWAYS) +#endif + +#ifdef DOXYGEN +/** + * @brief Store a double value that will always be returned by mock_double(). + * + * @param[in] #function The function which should return the given value. + * + * @param[in] value The value to be returned by mock_double(). + * + * This is equivalent to: + * @code + * will_return_double_count(function, value, -1); + * @endcode + * + * @see will_return_double_count() + * @see mock_double() + */ +void will_return_double_always(#function, double value); +#else +#define will_return_double_always(function, value) \ + will_return_double_count(function, (value), WILL_RETURN_ALWAYS) +#endif + +#ifdef DOXYGEN +/** + * @deprecated Use will_return_int_count() or will_return_uint_count() + */ +void will_return_count(#function, uintmax_t value, int count); +#else +#define will_return_count(function, value, count) \ + do { \ + CMOCKA_DEPRECATION_WARNING( \ + "will_return_count: use will_return_int_count or " \ + "will_return_uint_count instead") \ + _will_return(cmocka_tostring(function), \ + __FILE__, \ + __LINE__, \ + NULL, \ + cast_int_to_cmocka_value(value), \ + count); \ + } while (0) +#endif + +#ifdef DOXYGEN +/** + * @deprecated Use will_return_int_always() or will_return_uint_always() + */ +void will_return_always(#function, uintmax_t value); +#else +#define will_return_always(function, value) \ + do { \ + CMOCKA_DEPRECATION_WARNING( \ + "will_return_always: use will_return_int_always or " \ + "will_return_uint_always instead") \ + will_return_count(function, (value), WILL_RETURN_ALWAYS); \ + } while (0) +#endif + +#ifdef DOXYGEN +/** + * @brief Store an integer value that may always be returned by mock_int(). + * + * This stores a value which will always be returned by mock_int() but is not + * required to be returned by at least one call to mock_int(). Therefore, + * in contrast to will_return_int_always() which causes a test failure if it + * is not returned at least once, will_return_int_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_int(). + * + * This is equivalent to: + * @code + * will_return_int_count(function, value, -2); + * @endcode + * + * @see will_return_int_count() + * @see mock_int() + */ +void will_return_int_maybe(#function, intmax_t value); +#else +#define will_return_int_maybe(function, value) \ + will_return_int_count(function, (value), WILL_RETURN_ONCE) +#endif + +#ifdef DOXYGEN +/** + * @brief Store an unsigned integer value that may always be returned by + * mock_uint(). + * + * This stores a value which will always be returned by mock_uint() but is not + * required to be returned by at least one call to mock_uint(). Therefore, + * in contrast to will_return_uint_always() which causes a test failure if it + * is not returned at least once, will_return_uint_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_uint(). + * + * This is equivalent to: + * @code + * will_return_uint_count(function, value, -2); + * @endcode + * + * @see will_return_uint_count() + * @see mock_uint() + */ +void will_return_uint_maybe(#function, uintmax_t value); +#else +#define will_return_uint_maybe(function, value) \ + will_return_uint_count(function, (value), WILL_RETURN_ONCE) +#endif + +#ifdef DOXYGEN +/** + * @brief Store a float value that may always be returned by mock_float(). + * + * This stores a value which will always be returned by mock_float() but is not + * required to be returned by at least one call to mock_float(). Therefore, + * in contrast to will_return_float_always() which causes a test failure if it + * is not returned at least once, will_return_float_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_float(). + * + * This is equivalent to: + * @code + * will_return_float_count(function, value, -2); + * @endcode + * + * @see will_return_float_count() + * @see mock_float() + */ +void will_return_float_maybe(#function, float value); +#else +#define will_return_float_maybe(function, value) \ + will_return_float_count(function, (value), WILL_RETURN_ONCE) +#endif + +#ifdef DOXYGEN +/** + * @brief Store a double value that may always be returned by mock_double(). + * + * This stores a value which will always be returned by mock_double() but is not + * required to be returned by at least one call to mock_double(). Therefore, + * in contrast to will_return_double_always() which causes a test failure if it + * is not returned at least once, will_return_double_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_double(). + * + * This is equivalent to: + * @code + * will_return_double_count(function, value, -2); + * @endcode + * + * @see will_return_double_count() + * @see mock_double() + */ +void will_return_double_maybe(#function, double value); +#else +#define will_return_double_maybe(function, value) \ + will_return_double_count(function, (value), WILL_RETURN_ONCE) +#endif + +#ifdef DOXYGEN +/** + * @deprecated Use will_return_int_maybe() or will_return_uint_maybe() + */ +void will_return_maybe(#function, uintmax_t value); +#else +#define will_return_maybe(function, value) \ + do { \ + CMOCKA_DEPRECATION_WARNING( \ + "will_return_maybe: use will_return_int_maybe or " \ + "will_return_uint_maybe instead") \ + will_return_count(function, (value), WILL_RETURN_ONCE); \ + } while (0) +#endif + +#ifdef DOXYGEN +/** + * @brief Store a pointer value to be returned by mock_ptr_type() later. + * + * @param[in] #function The function which should return the given value. + * + * @param[in] value The value to be returned by mock_ptr_type(). + * + * @code + * const char * return_pointer(void) + * { + * return mock_ptr_type(const char *); + * } + * + * static void test_pointer_return(void **state) + * { + * will_return_ptr_type(return_pointer, "hello world", const char *); + * + * assert_string_equal(my_func_calling_return_pointer(), "hello world"); + * } + * @endcode + * + * @see mock_ptr_type() + * @see will_return_ptr_count() + */ +void will_return_ptr(#function, void *value); +#else +#define will_return_ptr(function, value) \ + _will_return(#function, \ + __FILE__, \ + __LINE__, \ + NULL, \ + cast_ptr_to_cmocka_value(value), \ + 1) +#endif + +#ifdef DOXYGEN +/** + * @brief Store a pointer value to be returned by mock_ptr_type_checked() later. + * + * This will also check that the type matches and if not will fail(). The type + * checking only works when used in conjunction with mock_ptr_type_checked(). + * If you use mock_ptr_type() to retrieve the value, no type checking will occur. + * + * @param[in] #function The function which should return the given value. + * + * @param[in] value The value to be returned by mock_ptr_type_checked(). + * + * @param[in] #type The type of the pointer. + * @code + * const char *return_pointer(void) + * { + * return mock_ptr_type_checked(const char *); + * } + * + * static void test_pointer_return(void **state) + * { + * will_return_ptr_type(return_pointer, "hello world", const char *); + * + * assert_string_equal(my_func_calling_return_pointer(), "hello world"); + * } + * @endcode + * + * @see mock_ptr_type_checked() + */ +void will_return_ptr_type(#function, void *value, type); +#else +#define will_return_ptr_type(function, value, type) \ + _will_return(#function, \ + __FILE__, \ + __LINE__, \ + #type, \ + cast_ptr_to_cmocka_value(value), \ + 1) +#endif + +#ifdef DOXYGEN +/** + * @brief Store a pointer value to be returned by mock_ptr_type() later. + * + * @param[in] #function The function which should return the given value. + * + * @param[in] value The value to be returned by mock_ptr_type(). + * + * @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_ptr_type() + */ +void will_return_ptr_count(#function, void *value, int count); +#else +#define will_return_ptr_count(function, value, count) \ + _will_return(#function, \ + __FILE__, \ + __LINE__, \ + NULL, \ + cast_ptr_to_cmocka_value(value), \ + count) +#endif + +#ifdef DOXYGEN +/** + * @brief Store a value that will be always returned by mock_ptr_type(). + * + * @param[in] #function The function which should return the given value. + * + * @param[in] #value The value to be returned by mock_ptr_type(). + * + * This is equivalent to: + * @code + * will_return_ptr_count(function, value, -1); + * @endcode + * + * @see will_return_ptr_count() + * @see mock_ptr_type() + */ +void will_return_ptr_always(#function, void *value); +#else +#define will_return_ptr_always(function, value) \ + will_return_ptr_count(function, (value), WILL_RETURN_ALWAYS) +#endif + +#ifdef DOXYGEN +/** + * @brief Store a value that may be always returned by mock_ptr_type(). + * + * This stores a value which will always be returned by mock_ptr_type() but is + * not required to be returned by at least one call to mock_ptr_type(). + * Therefore, in contrast to will_return_ptr_always() which causes a test + * failure if it is not returned at least once, will_return_ptr_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_ptr_type(). + * + * This is equivalent to: + * @code + * will_return_ptr_count(function, value, -2); + * @endcode + * + * @see will_return_ptr_count() + * @see mock_ptr_type() + */ +void will_return_ptr_maybe(#function, void *value); +#else +#define will_return_ptr_maybe(function, value) \ + will_return_ptr_count(function, (value), WILL_RETURN_ONCE) +#endif + +#ifdef DOXYGEN +/** + * @brief Store a named value to be returned by mock_parameter() later. + * + * @param[in] #function The function in which the given value should be return. + * + * @param[in] #name The name under which the given value should be returned. + * + * @param[in] value The value to be returned by mock_parameter(). + * + * @code + * void return_integer(int *result) + * { + * *result = (int)mock_parameter(result); + * } + * + * static void test_integer_return(void **state) + * { + * will_set_parameter(return_integer, result, 42); + * + * int retVal = 0; + * my_function_calling_return_integer(&retVal); + * assert_int_equal(result, 42); + * } + * @endcode + * + * @see mock_parameter() + * @see mock_parameter() + * @see mock_parameter_int() + * @see mock_parameter_uint() + * @see mock_parameter_float() + * @see mock_parameter_ptr() + * @see mock_parameter_ptr_type() + * @see will_set_parameter_int() + * @see will_set_parameter_uint() + * @see will_set_parameter_float() + * @see will_set_parameter_ptr() + * @see will_set_parameter_ptr_type() + * @see will_set_parameter_count() + * @see will_set_parameter_always() + * @see will_set_parameter_maybe() + * @see will_set_parameter_ptr_count() + * @see will_set_parameter_ptr_always() + * @see will_set_parameter_ptr_maybe() + */ +void will_set_parameter(#function, #name, uintmax_t value); +#else +#define will_set_parameter(function, name, value) \ + _will_set_parameter(cmocka_tostring(function), \ + #name, \ + __FILE__, \ + __LINE__, \ + NULL, \ + cast_int_to_cmocka_value(value), \ + 1) +#endif + +#ifdef DOXYGEN +/** + * @brief Store a named integer value to be returned by mock_parameter() later. + * + * And adds some type checking information to be able to check + * with call to mock_parameter_int(). + * + * @param[in] #function The function in which the given value should be return. + * + * @param[in] #name The name under which the given value should be returned. + * + * @param[in] value The value to be returned by mock_parameter(). + * + * @code + * void return_int32(int32_t *result) + * { + * *result = (int32_t)mock_parameter_int(result); + * } + * + * static void test_integer_return(void **state) + * { + * will_set_parameter_int(return_int32, result, -42); + * int32_t result_param = 0; + * return_int32(&result_param); + * assert_int_equal(result_param, -42); + * } + * @endcode + * + * @see mock_parameter() + * @see mock_parameter_int() + * @see will_set_parameter() + */ +void will_set_parameter_int(#function, #name, intmax_t value); +#else +#define will_set_parameter_int(function, name, value) \ + _will_set_parameter(#function, \ + #name, \ + __FILE__, \ + __LINE__, \ + "intmax_t", \ + assign_int_to_cmocka_value(value), \ + 1) +#endif + +#ifdef DOXYGEN +/** + * @brief Store a named unsigned integer value to be returned by + * mock_parameter() later. + * + * And adds some type checking information to be able to check + * with call to mock_parameter_uint(). + * + * @param[in] #function The function in which the given value should be + * return. + * + * @param[in] #name The name under which the given value should be returned. + * + * @param[in] value The value to be returned by mock_parameter(). + * + * @code + * void return_uint32(uint32_t *result) + * { + * *result =(uint32_t)mock_parameter_uint(result); + * } + * + * static void test_integer_return(void **state) + * { + * will_set_parameter_uint(return_uint32, result, 42); + * uint32_t result_param = 0; + * return_uint32(&result_param); + * assert_uint_equal(result_param, 42); + * } + * @endcode + * + * @see mock_parameter() + * @see mock_parameter_uint() + * @see will_set_parameter() + */ +void will_set_parameter_uint(#function, #name, uintmax_t value); +#else +#define will_set_parameter_uint(function, name, value) \ + _will_set_parameter(#function, \ + #name, \ + __FILE__, \ + __LINE__, \ + "uintmax_t", \ + assign_uint_to_cmocka_value(value), \ + 1) +#endif + +#ifdef DOXYGEN +/** + * @brief Store a named float value to be returned by mock_parameter() later. + * + * And adds some type checking information to be able to check + * with call to mock_parameter_float(). + * + * @param[in] #function The function in which the given value should be + * return. + * + * @param[in] #name The name under which the given value should be returned. + * + * @param[in] value The float value to be returned by mock_parameter(). + * + * @code + * void return_float(float *result) + * { + * *result = mock_parameter_float(result); + * } + * + * static void test_float_return(void **state) + * { + * will_set_parameter_float(return_float, result, 34.7f); + * float result_param = NAN; + * return_float(&result_param); + * assert_float_equal(result_param, 34.7f, 0.01f); + * } + * @endcode + * + * @see mock_parameter() + * @see mock_parameter_float() + * @see will_set_parameter() + */ +void will_set_parameter_float(#function, #name, float value); +#else +#define will_set_parameter_float(function, name, value) \ + _will_set_parameter(#function, \ + #name, \ + __FILE__, \ + __LINE__, \ + "float", \ + assign_float_to_cmocka_value(value), \ + 1) +#endif + +#ifdef DOXYGEN +/** + * @brief Store a named double precision floating point value to be returned + * by mock_parameter() later. + * + * And adds some type checking information to be able to check + * with call to mock_parameter_double(). + * + * @param[in] #function The function in which the given value should be + * return. + * + * @param[in] #name The name under which the given value should be returned. + * + * @param[in] value The double value to be returned by mock_parameter(). + * + * @code + * void return_double(double *result) + * { + * *result = mock_parameter_double(result); + * } + * + * static void test_double_return(void **state) + * { + * will_set_parameter_double(return_double, result, 34.7); + * double result_param = NAN; + * return_double(&result_param); + * assert_double_equal(result_param, 34.7, 0.0); + * } + * @endcode + * + * @see mock_parameter() + * @see mock_parameter_double() + * @see will_set_parameter() + */ +void will_set_parameter_double(#function, #name, double value); +#else +#define will_set_parameter_double(function, name, value) \ + _will_set_parameter(#function, \ + #name, \ + __FILE__, \ + __LINE__, \ + "double", \ + assign_double_to_cmocka_value(value), \ + 1) +#endif + +#ifdef DOXYGEN +/** + * @brief Store a named integer value to be returned a specified number of times + * by mock_parameter_int() later. + * + * @param[in] #function The function in which the given value should be + * return. + * + * @param[in] #name The name under which the given value should be returned. + * + * @param[in] value The value to be returned by mock_parameter_int(). + * + * @param[in] count The parameter indicates the number of times the value + * should be returned. 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, but is not required to be returned. + * + * @see mock_parameter_int() + * @see will_set_parameter_int() + */ +void will_set_parameter_int_count(#function, #name, intmax_t value, int count); +#else +#define will_set_parameter_int_count(function, name, value, count) \ + _will_set_parameter(#function, \ + #name, \ + __FILE__, \ + __LINE__, \ + "intmax_t", \ + assign_int_to_cmocka_value(value), \ + count) +#endif + +#ifdef DOXYGEN +/** + * @brief Store a named unsigned integer value to be returned a specified + * number of times by mock_parameter_uint() later. + * + * @param[in] #function The function in which the given value should be + * return. + * + * @param[in] #name The name under which the given value should be returned. + * + * @param[in] value The value to be returned by mock_parameter_uint(). + * + * @param[in] count The parameter indicates the number of times the value + * should be returned. 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, but is not required to be returned. + * + * @see mock_parameter_uint() + * @see will_set_parameter_uint() + */ +void will_set_parameter_uint_count(#function, + #name, + uintmax_t value, + int count); +#else +#define will_set_parameter_uint_count(function, name, value, count) \ + _will_set_parameter(#function, \ + #name, \ + __FILE__, \ + __LINE__, \ + "uintmax_t", \ + assign_uint_to_cmocka_value(value), \ + count) +#endif + +#ifdef DOXYGEN +/** + * @brief Store a named float value to be returned a specified number of times + * by mock_parameter_float() later. + * + * @param[in] #function The function in which the given value should be + * return. + * + * @param[in] #name The name under which the given value should be returned. + * + * @param[in] value The value to be returned by mock_parameter_float(). + * + * @param[in] count The parameter indicates the number of times the value + * should be returned. 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, but is not required to be returned. + * + * @see mock_parameter_float() + * @see will_set_parameter_float() + */ +void will_set_parameter_float_count(#function, #name, float value, int count); +#else +#define will_set_parameter_float_count(function, name, value, count) \ + _will_set_parameter(#function, \ + #name, \ + __FILE__, \ + __LINE__, \ + "float", \ + assign_float_to_cmocka_value(value), \ + count) +#endif + +#ifdef DOXYGEN +/** + * @brief Store a named double value to be returned a specified number of times + * by mock_parameter_double() later. + * + * @param[in] #function The function in which the given value should be + * return. + * + * @param[in] #name The name under which the given value should be returned. + * + * @param[in] value The value to be returned by mock_parameter_double(). + * + * @param[in] count The parameter indicates the number of times the value + * should be returned. 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, but is not required to be returned. + * + * @see mock_parameter_double() + * @see will_set_parameter_double() + */ +void will_set_parameter_double_count(#function, #name, double value, int count); +#else +#define will_set_parameter_double_count(function, name, value, count) \ + _will_set_parameter(#function, \ + #name, \ + __FILE__, \ + __LINE__, \ + "double", \ + assign_double_to_cmocka_value(value), \ + count) +#endif + +#ifdef DOXYGEN +/** + * @deprecated Use will_set_parameter_int_count() or + * will_set_parameter_uint_count() + */ +void will_set_parameter_count(#function, #name, uintmax_t value, int count); +#else +#define will_set_parameter_count(function, name, value, count) \ + do { \ + CMOCKA_DEPRECATION_WARNING( \ + "will_set_parameter_count: use will_set_parameter_int_count or " \ + "will_set_parameter_uint_count instead") \ + _will_set_parameter(cmocka_tostring(function), \ + #name, \ + __FILE__, \ + __LINE__, \ + NULL, \ + cast_int_to_cmocka_value(value), \ + count); \ + } while (0) +#endif + +#ifdef DOXYGEN +/** + * @brief Store a named integer value that will always be returned by + * mock_parameter_int(). + * + * @param[in] #function The function in which the given value should be + * return. + * + * @param[in] #name The name under which the given value should be returned. + * + * @param[in] value The value to be returned by mock_parameter_int(). + * + * This is equivalent to: + * @code + * will_set_parameter_int_count(function, name, value, -1); + * @endcode + * + * @see mock_parameter_int() + * @see will_set_parameter_int_count() + */ +void will_set_parameter_int_always(#function, #name, intmax_t value); +#else +#define will_set_parameter_int_always(function, name, value) \ + will_set_parameter_int_count(function, name, (value), WILL_RETURN_ALWAYS) +#endif + +#ifdef DOXYGEN +/** + * @brief Store a named unsigned integer value that will always be returned by + * mock_parameter_uint(). + * + * @param[in] #function The function in which the given value should be + * return. + * + * @param[in] #name The name under which the given value should be returned. + * + * @param[in] value The value to be returned by mock_parameter_uint(). + * + * This is equivalent to: + * @code + * will_set_parameter_uint_count(function, name, value, -1); + * @endcode + * + * @see mock_parameter_uint() + * @see will_set_parameter_uint_count() + */ +void will_set_parameter_uint_always(#function, #name, uintmax_t value); +#else +#define will_set_parameter_uint_always(function, name, value) \ + will_set_parameter_uint_count(function, name, (value), WILL_RETURN_ALWAYS) +#endif + +#ifdef DOXYGEN +/** + * @brief Store a named float value that will always be returned by + * mock_parameter_float(). + * + * @param[in] #function The function in which the given value should be + * return. + * + * @param[in] #name The name under which the given value should be returned. + * + * @param[in] value The value to be returned by mock_parameter_float(). + * + * This is equivalent to: + * @code + * will_set_parameter_float_count(function, name, value, -1); + * @endcode + * + * @see mock_parameter_float() + * @see will_set_parameter_float_count() + */ +void will_set_parameter_float_always(#function, #name, float value); +#else +#define will_set_parameter_float_always(function, name, value) \ + will_set_parameter_float_count(function, name, (value), WILL_RETURN_ALWAYS) +#endif + +#ifdef DOXYGEN +/** + * @brief Store a named double value that will always be returned by + * mock_parameter_double(). + * + * @param[in] #function The function in which the given value should be + * return. + * + * @param[in] #name The name under which the given value should be returned. + * + * @param[in] value The value to be returned by mock_parameter_double(). + * + * This is equivalent to: + * @code + * will_set_parameter_double_count(function, name, value, -1); + * @endcode + * + * @see mock_parameter_double() + * @see will_set_parameter_double_count() + */ +void will_set_parameter_double_always(#function, #name, double value); +#else +#define will_set_parameter_double_always(function, name, value) \ + will_set_parameter_double_count(function, name, (value), WILL_RETURN_ALWAYS) +#endif + +#ifdef DOXYGEN +/** + * @deprecated Use will_set_parameter_int_always() or + * will_set_parameter_uint_always() + */ +void will_set_parameter_always(#function, #name, uintmax_t value); +#else +#define will_set_parameter_always(function, name, value) \ + do { \ + CMOCKA_DEPRECATION_WARNING( \ + "will_set_parameter_always: use will_set_parameter_int_always or " \ + "will_set_parameter_uint_always instead") \ + will_set_parameter_count(function, name, (value), WILL_RETURN_ALWAYS); \ + } while (0) +#endif + +#ifdef DOXYGEN +/** + * @brief Store a named integer value that may always be returned by mock_parameter_int(). + * + * This stores a value which will always be returned by mock_parameter_int() but is not + * required to be returned by at least one call to mock_parameter_int(). + * + * @param[in] #function The function in which the given value should be return. + * + * @param[in] #name The name under which the given value should be returned. + * + * @param[in] value The value to be returned by mock_parameter_int(). + * + * This is equivalent to: + * @code + * will_set_parameter_int_count(function, name, value, -2); + * @endcode + * + * @see mock_parameter_int() + * @see will_set_parameter_int_count() + */ +void will_set_parameter_int_maybe(#function, #name, intmax_t value); +#else +#define will_set_parameter_int_maybe(function, name, value) \ + will_set_parameter_int_count(function, name, (value), WILL_RETURN_ONCE) +#endif + +#ifdef DOXYGEN +/** + * @brief Store a named unsigned integer value that may always be returned by mock_parameter_uint(). + * + * This stores a value which will always be returned by mock_parameter_uint() but is not + * required to be returned by at least one call to mock_parameter_uint(). + * + * @param[in] #function The function in which the given value should be return. + * + * @param[in] #name The name under which the given value should be returned. + * + * @param[in] value The value to be returned by mock_parameter_uint(). + * + * This is equivalent to: + * @code + * will_set_parameter_uint_count(function, name, value, -2); + * @endcode + * + * @see mock_parameter_uint() + * @see will_set_parameter_uint_count() + */ +void will_set_parameter_uint_maybe(#function, #name, uintmax_t value); +#else +#define will_set_parameter_uint_maybe(function, name, value) \ + will_set_parameter_uint_count(function, name, (value), WILL_RETURN_ONCE) +#endif + +#ifdef DOXYGEN +/** + * @brief Store a named float value that may always be returned by mock_parameter_float(). + * + * This stores a value which will always be returned by mock_parameter_float() but is not + * required to be returned by at least one call to mock_parameter_float(). + * + * @param[in] #function The function in which the given value should be return. + * + * @param[in] #name The name under which the given value should be returned. + * + * @param[in] value The value to be returned by mock_parameter_float(). + * + * This is equivalent to: + * @code + * will_set_parameter_float_count(function, name, value, -2); + * @endcode + * + * @see mock_parameter_float() + * @see will_set_parameter_float_count() + */ +void will_set_parameter_float_maybe(#function, #name, float value); +#else +#define will_set_parameter_float_maybe(function, name, value) \ + will_set_parameter_float_count(function, name, (value), WILL_RETURN_ONCE) +#endif + +#ifdef DOXYGEN +/** + * @brief Store a named double value that may always be returned by mock_parameter_double(). + * + * This stores a value which will always be returned by mock_parameter_double() but is not + * required to be returned by at least one call to mock_parameter_double(). + * + * @param[in] #function The function in which the given value should be return. + * + * @param[in] #name The name under which the given value should be returned. + * + * @param[in] value The value to be returned by mock_parameter_double(). + * + * This is equivalent to: + * @code + * will_set_parameter_double_count(function, name, value, -2); + * @endcode + * + * @see mock_parameter_double() + * @see will_set_parameter_double_count() + */ +void will_set_parameter_double_maybe(#function, #name, double value); +#else +#define will_set_parameter_double_maybe(function, name, value) \ + will_set_parameter_double_count(function, name, (value), WILL_RETURN_ONCE) +#endif + +#ifdef DOXYGEN +/** + * @deprecated Use will_set_parameter_int_maybe() or + * will_set_parameter_uint_maybe() + */ +void will_set_parameter_maybe(#function, #name, uintmax_t value); +#else +#define will_set_parameter_maybe(function, name, value) \ + do { \ + CMOCKA_DEPRECATION_WARNING( \ + "will_set_parameter_maybe: use will_set_parameter_int_maybe or " \ + "will_set_parameter_uint_maybe instead") \ + will_set_parameter_count(function, name, (value), WILL_RETURN_ONCE); \ + } while (0) +#endif + +#ifdef DOXYGEN +/** + * @brief Store a named pointer value to be returned by mock_parameter() later. + * + * @param[in] #function The function in which the given value should be + * return. + * + * @param[in] #name The name under which the given value should be returned. + * + * @param[in] value The value to be returned by mock_parameter(). + * + * @code + * void return_pointer(const char **result) + * { + * *result = (const char *)mock_parameter_ptr(result); + * } + * static void test_pointer_return(void **state) + * { + * will_set_parameter_ptr(return_pointer, result, "hello world"); + * const char *returned = NULL; + * my_func_calling_return_pointer(&returned); + * assert_string_equal(returned, "hello world"); + * } + * @endcode + * + * @see mock_parameter() + * @see mock_parameter_ptr() + * @see will_set_parameter() + */ +void will_set_parameter_ptr(#function, #name, void *value); +#else +#define will_set_parameter_ptr(function, name, value) \ + _will_set_parameter(#function, \ + #name, \ + __FILE__, \ + __LINE__, \ + NULL, \ + cast_ptr_to_cmocka_value(value), \ + 1) +#endif + +#ifdef DOXYGEN +/** + * @brief Store a named pointer value to be returned by mock_parameter() later. + * + * This will also check that the type matches and if not will fail(). + * + * @param[in] #function The function in which the given value should be return. + * + * @param[in] #name The name under which the given value should be returned. + * + * @param[in] value The value to be returned by mock_parameter(). + * + * @param[in] type The type of the pointer. + * + * @code + * void return_pointer(const char **result) + * { + * *result = mock_parameter_ptr_typed(result, const char*); + * } + * static void test_pointer_return(void **state) + * { + * will_set_parameter_ptr_type(return_pointer, result, "hello world", const char*); + * const char *returned = NULL; + * my_func_calling_return_pointer(&returned); + * assert_string_equal(returned, "hello world"); + * } + * @endcode + * + * @see mock_parameter() + * @see mock_parameter_ptr() + * @see mock_parameter_ptr_type() + * @see will_set_parameter() + * @see will_set_parameter_ptr() + */ +void will_set_parameter_ptr_type(#function, #name, void *value, #type); +#else +#define will_set_parameter_ptr_type(function, name, value, type) \ + _will_set_parameter(#function, \ + #name, \ + __FILE__, \ + __LINE__, \ + #type, \ + cast_ptr_to_cmocka_value(value), \ + 1) +#endif + +#ifdef DOXYGEN +/** + * @brief Store a named pointer value to be returned a specified number of times + * by mock_parameter_ptr() later. + * + * @param[in] #function The function in which the given value should be return. + * + * @param[in] #name The name under which the given value should be returned. + * + * @param[in] value The value to be returned by mock_parameter_ptr(). + * + * @param[in] count The parameter indicates the number of times the value should + * be returned by mock_parameter_ptr(). 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_parameter_ptr(), but is not required to be returned. + * + * @code + * void return_pointer(const char **resultA, const char **resultB) + * { + * *resultA = (const char *)mock_parameter_ptr(result); + * *resultB = (const char *)mock_parameter_ptr(result); + * } + * static void test_pointer_return(void **state) + * { + * will_set_parameter_ptr_count(return_pointer, result, "hello world", const char*, 2); + * const char *returnedA = NULL; + * const char *returnedB = NULL; + * my_func_calling_return_pointer(&returnedA, &returnedB); + * assert_string_equal(returnedA, "hello world"); + * assert_string_equal(returnedB, "hello world"); + * } + * @endcode + * + * @see mock_parameter() + * @see mock_parameter_ptr() + * @see will_named_return() + * @see will_named_return_ptr() + */ +void will_set_parameter_ptr_count(#function, #name, void *value, int count); +#else +#define will_set_parameter_ptr_count(function, name, value, count) \ + _will_set_parameter(#function, \ + #name, \ + __FILE__, \ + __LINE__, \ + NULL, \ + cast_ptr_to_cmocka_value(value), \ + count) +#endif + +#ifdef DOXYGEN +/** + * @brief Store a named pointer value that will be always returned by + * mock_parameter_ptr(). + * + * This stores a value which will always be returned by mock_parameter_ptr() + * and is required to be returned by at least one call to mock_parameter_ptr(). + * If it is not returned at least once the test will fail. + * + * @param[in] #function The function in which the given value should be + * return. + * + * @param[in] #name The name under which the given value should be returned. + * + * @param[in] value The value to be returned by mock_parameter_ptr(). + * + * This is equivalent to: + * @code + * will_set_parameter_ptr_count(function, name, value, -1); + * @endcode + * + * @see mock_parameter() + * @see mock_parameter_ptr() + * @see will_set_parameter() + * @see will_set_parameter_ptr() + * @see will_set_parameter_ptr_count() + */ +void will_set_parameter_ptr_always(#function, #name, void *value); +#else +#define will_set_parameter_ptr_always(function, name, value) \ + will_set_parameter_ptr_count(function, name, (value), WILL_RETURN_ALWAYS) +#endif + +#ifdef DOXYGEN +/** + * @brief Store a named pointer value that may be always returned by + * mock_parameter_ptr(). + * + * This stores a value which will always be returned by mock_parameter_ptr() but + * is not required to be returned by at least one call to mock_parameter_ptr(). + * Therefore, in contrast to will_set_parameter_ptr_always() which causes a test + * failure if it is not returned at least once, will_set_parameter_ptr_maybe() + * will never cause a test to fail if its value is not returned. + * + * @param[in] #function The function in which the given value should be + * return. + * + * @param[in] #name The name under which the given value should be returned. + * + * @param[in] value The value to be returned by mock_parameter_ptr(). + * + * This is equivalent to: + * @code + * will_set_parameter_ptr_count(function, name, value, -2); + * @endcode + * + * @see mock_parameter() + * @see mock_parameter_ptr() + * @see will_set_parameter() + * @see will_set_parameter_ptr() + * @see will_set_parameter_ptr_count() + */ +void will_set_parameter_ptr_maybe(#function, #name, void *value); +#else +#define will_set_parameter_ptr_maybe(function, name, value) \ + will_set_parameter_ptr_count(function, name, (value), WILL_RETURN_ONCE) +#endif + +#ifdef DOXYGEN +/** + * @brief Store an integer value to set errno to by mock_errno() later. + * + * @param[in] #function The function in which errno + * should be set to the given value. + * + * @param[in] value The value to set errno to by the call to mock_errno(). + * + * @code + * void sets_errno(void) + * { + * mock_errno(); + * } + * + * static void test_sets_errno(void **state) + * { + * will_set_errno(sets_errno, -3); + * + * assert_int_equal(errno, -3); + * } + * @endcode + * + * @see mock_errno() + */ +void will_set_errno(#function, intmax_t value); +#else +#define will_set_errno(function, value) \ + _will_set_parameter(#function, \ + "/errno", \ + __FILE__, \ + __LINE__, \ + "errno", \ + assign_int_to_cmocka_value(value), \ + 1) +#endif + +#ifdef DOXYGEN +/** + * @brief Store an integer value to always set errno to by mock_errno(). + * + * + * + * @param[in] #function The function in which errno + * should be set to the given value. + * + * @param[in] value The value to set errno to by the call to mock_errno(). + * + * @param[in] count The count parameter gives the number of times the value + * should be validated by check_expected(). If count is set + * to @ref EXPECT_ALWAYS the value will always be returned, + * and cmocka expects check_expected() to be issued at least + * once. If count is set to @ref EXPECT_MAYBE, any number of + * calls to check_expected() is accepted, including zero. + * + * @code + * void sets_errno(void) + * { + * mock_errno(); + * } + * static void test_sets_errno(void **state) + * { + * will_set_errno_count(sets_errno, -3, 2); + * sets_errno(); + * assert_int_equal(errno, -3); + * errno = 0; + * sets_errno(); + * assert_int_equal(errno, -3); + * } + * @endcode + * + * @see mock_errno() + * @see will_set_errno() + * @see will_set_errno_always() + * @see will_set_errno_maybe() + */ +void will_set_errno_count(#function, intmax_t value, size_t count); +#else +#define will_set_errno_count(function, value, count) \ + _will_set_parameter(#function, \ + "/errno", \ + __FILE__, \ + __LINE__, \ + "errno", \ + assign_int_to_cmocka_value(value), \ + (count)) +#endif + +#ifdef DOXYGEN +/** + * @brief Store an integer value to set errno to by mock_errno() later, + * for a specified number of times. + * + * This stores a value which will errno will always be set to by mock_errno() + * but is required to be set least once by a call to mock_errno(). + * + * @param[in] #function The function in which errno + * should be set to the given value. + * + * @param[in] value The value to set errno to by the call to mock_errno(). + * + * This is equivalent to: + * @code + * will_set_parameter_count(function, name, value, -1); + * @endcode + * + * @see mock_errno() + * @see will_set_errno() + * @see will_set_errno_count() + * @see will_set_errno_maybe() + */ +void will_set_errno_always(#function, intmax_t value); +#else +#define will_set_errno_always(function, value) \ + will_set_errno_count(function, (value), WILL_RETURN_ALWAYS); +#endif + +#ifdef DOXYGEN +/** + * @brief Store an integer value to set errno to by mock_errno() later, + * for a specified number of times. + * + * This stores a value which will errno will always be set to by mock_errno() + * and won't fail if mock_errno() is never called. + * + * @param[in] #function The function in which errno + * should be set to the given value. + * + * @param[in] value The value to set errno to by the call to mock_errno(). + * + * This is equivalent to: + * @code + * will_set_parameter_count(function, name, value, -2); + * @endcode + * + * @see mock_errno() + * @see will_set_errno() + * @see will_set_errno_count() + * @see will_set_errno_always() + */ +void will_set_errno_maybe(#function, intmax_t value); +#else +#define will_set_errno_maybe(function, value) \ + will_set_errno_count(function, (value), WILL_RETURN_ONCE); +#endif + +/** @} */ /* cmocka_mock */ + +/** + * @defgroup cmocka_param ✅ Checking Parameters + * @ingroup cmocka + * @brief Validate function parameters match expected values. + * + * 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_*() macros. + * + * 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_ptr(order); + * } + * @endcode + * + * For a complete example please take a look + * here + * + * @{ + */ + + +#ifdef DOXYGEN +/** + * @deprecated Use expect_check_data() + */ +void expect_check(function, + parameter, + CheckParameterValue check_function, + const void *check_data); +#else +#define expect_check(function, parameter, check_function, check_data) \ + do { \ + CMOCKA_DEPRECATION_WARNING( \ + "expect_check: use expect_check_data instead") \ + _expect_check(cmocka_tostring(function), \ + cmocka_tostring(parameter), \ + __FILE__, \ + __LINE__, \ + check_function, \ + cast_to_uintmax_type(check_data), \ + NULL, \ + 1); \ + } while (0) +#endif + + +#ifdef DOXYGEN +/** + * @deprecated Use expect_check_data_count() + */ +void expect_check_count(function, + parameter, + CheckParameterValue check_function, + const void *check_data, + size_t count); +#else +#define expect_check_count( \ + function, parameter, check_function, check_data, count) \ + do { \ + CMOCKA_DEPRECATION_WARNING( \ + "expect_check_count: use expect_check_data_count instead") \ + _expect_check(cmocka_tostring(function), \ + cmocka_tostring(parameter), \ + __FILE__, \ + __LINE__, \ + check_function, \ + cast_to_uintmax_type(check_data), \ + NULL, \ + count); \ + } while (0) +#endif + +#ifdef DOXYGEN +/** + * @brief Add a custom parameter checking function using CMockaValueData (new API). + * + * This is the new API that uses CMockaValueData for type-safe parameter checking. + * It allows checking of integer, float, double, and pointer values. + * + * @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 (CheckParameterValueData). + * + * @param[in] check_data The data to pass to the check function (CMockaValueData). + * + * ## Checker Function Interface + * + * The checker function must have the following signature: + * @code + * int checker_function(CMockaValueData value, CMockaValueData check_data); + * @endcode + * + * ### Parameters + * - **value**: The actual parameter value passed to the mocked function. + * This is provided via check_expected(), check_expected_int(), + * check_expected_uint(), check_expected_float(), or check_expected_double() + * in the mocked function. + * - **check_data**: The expected data that was passed to expect_check_data(). + * This contains the value you want to compare against. + * + * ### Return Value + * The checker function should return: + * - **Non-zero** (typically 1 or true) if the check succeeds + * - **Zero** (0 or false) if the check fails + * + * When the checker returns zero, cmocka will fail the test with an appropriate + * error message. + * + * ### Accessing Values in CMockaValueData + * + * The CMockaValueData union contains the following fields: + * - **int_val**: For signed integer types (intmax_t) + * - **uint_val**: For unsigned integer types (uintmax_t) + * - **float_val**: For single-precision floating-point types (float) + * - **real_val**: For double-precision floating-point types (double) + * - **ptr**: For pointer types (const void *) + * + * ## Usage Notes + * + * 1. **Calling will_return() in the checker**: You can call will_return() or + * other cmocka setup functions within your checker function to set up return + * values dynamically based on the parameter being checked. This is useful + * when the return value depends on the input parameter. + * + * 2. **Checking multiple parameters**: To check all parameters of a function + * at once, you can pass a pointer to a struct containing all parameter + * values as the check_data. Your checker function can then validate all + * fields in a single call. See example below. + * + * 3. **Memory allocation for check_data**: If you allocate memory for the + * check_data parameter (e.g., for a struct), you are responsible for + * managing its lifetime. The checker function receives the data by value, + * so if you pass a pointer in check_data.ptr, ensure it remains valid + * until the checker is called. Note that cmocka does not free this memory + * automatically. + * + * @code + * // Example: Custom range checker + * typedef struct { + * int min; + * int max; + * } range_data; + * + * int check_in_custom_range(CMockaValueData value, CMockaValueData check_data) + * { + * range_data *range = (range_data *)check_data.ptr; + * int val = value.int_val; + * + * // Return 1 (true) if in range, 0 (false) otherwise + * return (val >= range->min && val <= range->max); + * } + * + * // In your test: + * void test_custom_check(void **state) + * { + * range_data range = {10, 20}; + * expect_check_data(my_function, param, + * check_in_custom_range, + * cast_ptr_to_cmocka_value(&range)); + * my_function(15); // This will pass + * } + * + * // The mocked function: + * void my_function(int param) + * { + * check_expected_int(param); // Triggers the checker + * } + * @endcode + * + * @code + * // Example: Checker that also sets return values + * int check_and_setup_return(CMockaValueData value, CMockaValueData check_data) + * { + * int expected = check_data.int_val; + * int actual = value.int_val; + * + * if (actual == expected) { + * // Set up return value dynamically based on the parameter + * will_return_int(some_other_function, actual * 2); + * return 1; // Success + * } + * return 0; // Failure + * } + * @endcode + * + * @code + * // Example: Checking multiple parameters at once + * typedef struct { + * int expected_a; + * int expected_b; + * const char *expected_str; + * } multi_param_check; + * + * int check_multiple_params(CMockaValueData value, CMockaValueData check_data) + * { + * multi_param_check *expected = (multi_param_check *)check_data.ptr; + * multi_param_check *actual = (multi_param_check *)value.ptr; + * + * return (actual->expected_a == expected->expected_a && + * actual->expected_b == expected->expected_b && + * strcmp(actual->expected_str, expected->expected_str) == 0); + * } + * + * // In your test: + * void test_multi_param(void **state) + * { + * multi_param_check expected = {42, 100, "test"}; + * multi_param_check actual = {42, 100, "test"}; + * + * expect_check_data(my_function, params, + * check_multiple_params, + * cast_ptr_to_cmocka_value(&expected)); + * + * // In the mocked function, you would pack all params into a struct + * // and call check_expected_ptr(params) + * } + * @endcode + * + * @see check_expected_int() + * @see check_expected_uint() + * @see check_expected_float() + * @see check_expected_double() + * @see check_expected_ptr() + * @see expect_check_data_count() + */ +void expect_check_data(function, + parameter, + CheckParameterValueData check_function, + CMockaValueData check_data); +#else +#define expect_check_data(function, parameter, check_function, check_data) \ + _expect_check_data(cmocka_tostring(function), \ + cmocka_tostring(parameter), \ + __FILE__, \ + __LINE__, \ + check_function, \ + check_data, \ + NULL, \ + 1) +#endif + +#ifdef DOXYGEN +/** + * @brief Add a custom parameter checking function using CMockaValueData with + * count (new API). + * + * This is the new API that uses CMockaValueData for type-safe parameter + * checking. This version allows you to specify how many times the check should + * be performed. + * + * @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 + * (CheckParameterValueData). + * + * @param[in] check_data The data to pass to the check function (CMockaValueData). + * + * @param[in] count The number of times this check should be called. + * - A specific positive number: The check will be performed + * exactly that many times. + * - **EXPECT_ALWAYS** (-1): The check will always be + * performed and must be called at least once. The test + * will fail if not called. + * - **EXPECT_MAYBE** (-2): The check will always be + * performed but is not required to be called. The test + * will not fail if the checker is never invoked. + * + * See expect_check_data() for detailed documentation on the checker function + * interface, usage notes, and examples. + * + * @code + * // Example: Check a parameter exactly 3 times + * expect_check_data_count(my_function, param, + * my_checker, + * assign_int_to_cmocka_value(42), + * 3); + * my_function(42); + * my_function(42); + * my_function(42); + * @endcode + * + * @code + * // Example: Always check (must be called at least once) + * expect_check_data_count(my_function, param, + * my_checker, + * assign_int_to_cmocka_value(42), + * EXPECT_ALWAYS); + * my_function(42); + * my_function(42); + * // Can call any number of times, but at least once + * @endcode + * + * @code + * // Example: Optional check (may or may not be called) + * expect_check_data_count(my_function, param, + * my_checker, + * assign_int_to_cmocka_value(42), + * EXPECT_MAYBE); + * // my_function may or may not be called - test won't fail either way + * @endcode + * + * @see expect_check_data() + */ +void expect_check_data_count(function, + parameter, + CheckParameterValueData check_function, + CMockaValueData check_data, + size_t count); +#else +#define expect_check_data_count(function, \ + parameter, \ + check_function, \ + check_data, \ + count) \ + _expect_check_data(cmocka_tostring(function), \ + cmocka_tostring(parameter), \ + __FILE__, \ + __LINE__, \ + check_function, \ + check_data, \ + NULL, \ + count) +#endif + +#ifdef DOXYGEN +/** + * @deprecated Use expect_int_in_set() or expect_uint_in_set() + */ +void expect_in_set(#function, #parameter, uintmax_t value_array[]); +#else +#define expect_in_set(function, parameter, value_array) \ + do { \ + CMOCKA_DEPRECATION_WARNING("expect_in_set: use expect_int_in_set or " \ + "expect_uint_in_set instead") \ + expect_in_set_count(function, parameter, value_array, 1); \ + } while (0) +#endif + +#ifdef DOXYGEN +/** + * @brief Add an event to check if the parameter value is part of the provided + * integer 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, intmax_t value_array[]); +#else +#define expect_int_in_set(function, parameter, value_array) \ + expect_int_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 + * unsigned integer 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, intmax_t value_array[]); +#else +#define expect_uint_in_set(function, parameter, value_array) \ + expect_uint_in_set_count(function, parameter, value_array, 1) +#endif + +#ifdef DOXYGEN +/** + * @deprecated Use expect_int_in_set_count() or expect_uint_in_set_count() + */ +void expect_in_set_count(#function, #parameter, uintmax_t value_array[], size_t count); +#else +#define expect_in_set_count(function, parameter, value_array, count) \ + do { \ + CMOCKA_DEPRECATION_WARNING( \ + "expect_in_set_count: use expect_int_in_set_count or " \ + "expect_uint_in_set_count instead") \ + _expect_uint_in_set(cmocka_tostring(function), \ + cmocka_tostring(parameter), \ + __FILE__, \ + __LINE__, \ + value_array, \ + sizeof(value_array) / sizeof((value_array)[0]), \ + count); \ + } while (0) +#endif + +#ifdef DOXYGEN +/** + * @brief Add an event to check if the parameter value is part of the provided + * integer 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_int_in_set_count(#function, #parameter, intmax_t value_array[], size_t count); +#else +#define expect_int_in_set_count(function, parameter, value_array, count) \ + _expect_int_in_set(cmocka_tostring(function), \ + cmocka_tostring(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 part of the provided + * unsigned integer 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_uint_in_set_count(#function, #parameter, uintmax_t value_array[], size_t count); +#else +#define expect_uint_in_set_count(function, parameter, value_array, count) \ + _expect_uint_in_set(cmocka_tostring(function), \ + cmocka_tostring(parameter), \ + __FILE__, \ + __LINE__, \ + value_array, \ + sizeof(value_array) / sizeof((value_array)[0]), \ + count) +#endif + +#ifdef DOXYGEN +/** + * @deprecated Use expect_int_not_in_set() or expect_uint_not_in_set() + */ +void expect_not_in_set(#function, #parameter, uintmax_t value_array[]); +#else +#define expect_not_in_set(function, parameter, value_array) \ + do { \ + CMOCKA_DEPRECATION_WARNING( \ + "expect_not_in_set: use expect_int_not_in_set or " \ + "expect_uint_not_in_set instead") \ + expect_not_in_set_count(function, parameter, value_array, 1); \ + } while (0) +#endif + +#ifdef DOXYGEN +/** + * @deprecated Use expect_int_not_in_set_count() or expect_uint_not_in_set_count() + */ +void expect_not_in_set_count(#function, #parameter, uintmax_t value_array[], size_t count); +#else +#define expect_not_in_set_count(function, parameter, value_array, count) \ + do { \ + CMOCKA_DEPRECATION_WARNING( \ + "expect_not_in_set_count: use expect_int_not_in_set_count or " \ + "expect_uint_not_in_set_count instead") \ + _expect_not_in_set(cmocka_tostring(function), \ + cmocka_tostring(parameter), \ + __FILE__, \ + __LINE__, \ + value_array, \ + sizeof(value_array) / sizeof((value_array)[0]), \ + count); \ + } while (0) +#endif + +#ifdef DOXYGEN +/** + * @brief Add an event to check if the integer parameter value is not part of + * the provided integer 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_int_not_in_set(#function, #parameter, intmax_t value_array[]); +#else +#define expect_int_not_in_set(function, parameter, value_array) \ + expect_int_not_in_set_count(function, parameter, value_array, 1) +#endif + +#ifdef DOXYGEN +/** + * @brief Add an event to check if the integer parameter value is not part of + * the provided integer 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_int_not_in_set_count(#function, + #parameter, + intmax_t value_array[], + size_t count); +#else +#define expect_int_not_in_set_count(function, parameter, value_array, count) \ + _expect_int_not_in_set(cmocka_tostring(function), \ + cmocka_tostring(parameter), \ + __FILE__, \ + __LINE__, \ + value_array, \ + sizeof(value_array) / sizeof((value_array)[0]), \ + count) +#endif + +#ifdef DOXYGEN +/** + * @brief Add an event to check if the unsigned integer parameter value is not + * part of the provided unsigned integer 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_uint_not_in_set(#function, #parameter, uintmax_t value_array[]); +#else +#define expect_uint_not_in_set(function, parameter, value_array) \ + expect_uint_not_in_set_count(function, parameter, value_array, 1) +#endif + +#ifdef DOXYGEN +/** + * @brief Add an event to check if the unsigned integer parameter value is not + * part of the provided unsigned integer 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_uint_not_in_set_count(#function, + #parameter, + uintmax_t value_array[], + size_t count); +#else +#define expect_uint_not_in_set_count(function, parameter, value_array, count) \ + _expect_uint_not_in_set(cmocka_tostring(function), \ + cmocka_tostring(parameter), \ + __FILE__, \ + __LINE__, \ + value_array, \ + sizeof(value_array) / sizeof((value_array)[0]), \ + count) +#endif + +#ifdef DOXYGEN +/** + * @brief Add an event to check if the float parameter value is part of the + * provided array. + * + * The event is triggered by calling check_expected_float() 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] epsilon The epsilon used as margin for float comparison. + * + * @param[in] value_array[] The array to check for the value. + * + * @see check_expected_float(). + */ +void expect_float_in_set(#function, #parameter, double value_array[], double epsilon); +#else +#define expect_float_in_set(function, parameter, value_array, epsilon) \ + expect_float_in_set_count(function, parameter, value_array, epsilon, 1) +#endif + +#ifdef DOXYGEN +/** + * @brief Add an event to check if the float parameter value is part of the + * provided integer array. + * + * The event is triggered by calling check_expected_float() 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] epsilon The epsilon used as margin for float comparison. + * + * @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_float(). + */ +void expect_float_in_set_count(#function, #parameter, double value_array[], double epsilon, size_t count); +#else +#define expect_float_in_set_count(function, parameter, value_array, epsilon, count) \ + _expect_float_in_set(cmocka_tostring(function), \ + cmocka_tostring(parameter), \ + __FILE__, \ + __LINE__, \ + value_array, \ + sizeof(value_array) / sizeof((value_array)[0]), \ + epsilon, \ + count) +#endif + +#ifdef DOXYGEN +/** + * @brief Add an event to check if the float parameter value is not part of the + * provided array. + * + * The event is triggered by calling check_expected_float() 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] epsilon The epsilon used as margin for float comparison. + * + * @param[in] value_array[] The array to check for the value. + * + * @see check_expected_float(). + */ +void expect_float_not_in_set(#function, #parameter, double value_array[], double epsilon); +#else +#define expect_float_not_in_set(function, parameter, value_array, epsilon) \ + expect_float_not_in_set_count(function, parameter, value_array, epsilon, 1) +#endif + +#ifdef DOXYGEN +/** + * @brief Add an event to check if the float parameter value is not part of the + * provided integer array. + * + * The event is triggered by calling check_expected_float() 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] epsilon The epsilon used as margin for float comparison. + * + * @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_float(). + */ +void expect_float_not_in_set_count(#function, #parameter, double value_array[], double epsilon, size_t count); +#else +#define expect_float_not_in_set_count(function, parameter, value_array, epsilon, count) \ + _expect_float_not_in_set(cmocka_tostring(function), \ + cmocka_tostring(parameter), \ + __FILE__, \ + __LINE__, \ + value_array, \ + sizeof(value_array) / sizeof((value_array)[0]), \ + epsilon, \ + count) +#endif + + +#ifdef DOXYGEN +/** + * @deprecated Use expect_int_in_range() + */ +void expect_in_range(#function, #parameter, uintmax_t minimum, uintmax_t maximum); +#else +#define expect_in_range(function, parameter, minimum, maximum) \ + do { \ + CMOCKA_DEPRECATION_WARNING( \ + "expect_in_range: use expect_int_in_range or " \ + "expect_uint_in_range instead") \ + expect_in_range_count(function, parameter, minimum, maximum, 1); \ + } while (0) +#endif + +#ifdef DOXYGEN +/** + * @deprecated Use expect_int_in_range_count() + */ +void expect_in_range_count(#function, #parameter, uintmax_t minimum, uintmax_t maximum, size_t count); +#else +#define expect_in_range_count(function, parameter, minimum, maximum, count) \ + do { \ + CMOCKA_DEPRECATION_WARNING( \ + "expect_in_range_count: use expect_int_in_range_count or " \ + "expect_uint_in_range_count instead") \ + _expect_in_range(cmocka_tostring(function), \ + cmocka_tostring(parameter), \ + __FILE__, \ + __LINE__, \ + minimum, \ + maximum, \ + count); \ + } while (0) +#endif + +#ifdef DOXYGEN +/** + * @brief Add an event to check an integer 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_int_in_range(#function, +#parameter, + intmax_t minimum, + intmax_t maximum); +#else +#define expect_int_in_range(function, parameter, minimum, maximum) \ + expect_int_in_range_count(function, parameter, minimum, maximum, 1) +#endif + +#ifdef DOXYGEN +/** + * @brief Add an event to repeatedly check an integer 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_int_in_range_count(#function, +#parameter, + intmax_t minimum, + intmax_t maximum, + size_t count); +#else +#define expect_int_in_range_count( \ + function, parameter, minimum, maximum, count) \ + _expect_int_in_range(cmocka_tostring(function), \ + cmocka_tostring(parameter), \ + __FILE__, \ + __LINE__, \ + minimum, \ + maximum, \ + count) +#endif + +#ifdef DOXYGEN +/** + * @brief Add an event to check an unsigned integer 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_uint_in_range(#function, +#parameter, + uintmax_t minimum, + uintmax_t maximum); +#else +#define expect_uint_in_range(function, parameter, minimum, maximum) \ + expect_uint_in_range_count(function, parameter, minimum, maximum, 1) +#endif + +#ifdef DOXYGEN +/** + * @brief Add an event to repeatedly check an unsigned integer 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_uint_in_range_count(#function, +#parameter, + uintmax_t minimum, + uintmax_t maximum, + size_t count); +#else +#define expect_uint_in_range_count( \ + function, parameter, minimum, maximum, count) \ + _expect_uint_in_range(cmocka_tostring(function), \ + cmocka_tostring(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, uintmax_t minimum, uintmax_t 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, uintmax_t minimum, uintmax_t maximum, size_t count); +#else +#define expect_not_in_range_count(function, parameter, minimum, maximum, \ + count) \ + _expect_not_in_range(cmocka_tostring(function), cmocka_tostring(parameter), __FILE__, __LINE__, \ + minimum, maximum, count) +#endif + +#ifdef DOXYGEN +/** + * @brief Add an event to check an integer 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_int_not_in_range(#function, + #parameter, + intmax_t minimum, + intmax_t maximum); +#else +#define expect_int_not_in_range(function, parameter, minimum, maximum) \ + expect_int_not_in_range_count(function, parameter, minimum, maximum, 1) +#endif + +#ifdef DOXYGEN +/** + * @brief Add an event to repeatedly check an integer 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_int_not_in_range_count(#function, + #parameter, + intmax_t minimum, + intmax_t maximum, + size_t count); +#else +#define expect_int_not_in_range_count( \ + function, parameter, minimum, maximum, count) \ + _expect_int_not_in_range(cmocka_tostring(function), \ + cmocka_tostring(parameter), \ + __FILE__, \ + __LINE__, \ + minimum, \ + maximum, \ + count) +#endif + +#ifdef DOXYGEN +/** + * @brief Add an event to check an unsigned integer 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_uint_not_in_range(#function, + #parameter, + uintmax_t minimum, + uintmax_t maximum); +#else +#define expect_uint_not_in_range(function, parameter, minimum, maximum) \ + expect_uint_not_in_range_count(function, parameter, minimum, maximum, 1) +#endif + +#ifdef DOXYGEN +/** + * @brief Add an event to repeatedly check an unsigned integer 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_uint_not_in_range_count(#function, + #parameter, + uintmax_t minimum, + uintmax_t maximum, + size_t count); +#else +#define expect_uint_not_in_range_count( \ + function, parameter, minimum, maximum, count) \ + _expect_uint_not_in_range(cmocka_tostring(function), \ + cmocka_tostring(parameter), \ + __FILE__, \ + __LINE__, \ + minimum, \ + maximum, \ + 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_float() 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] epsilon The epsilon used as margin for float comparison. + * + * @see check_expected_float(). + */ +void expect_float_in_range(#function, #parameter, double minimum, double maximum, double epsilon); +#else +#define expect_float_in_range(function, parameter, minimum, maximum, epsilon) \ + expect_float_in_range_count(function, parameter, minimum, maximum, epsilon, 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_float() 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] epsilon The epsilon used as margin for float comparison. + * + * @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_float() + */ +void expect_float_in_range_count(#function, #parameter, double minimum, double maximum, double epsilon, size_t count); +#else +#define expect_float_in_range_count(function, parameter, minimum, maximum, epsilon, count) \ + _expect_float_in_range(cmocka_tostring(function), \ + cmocka_tostring(parameter), \ + __FILE__, \ + __LINE__, \ + cast_to_double_type(minimum), \ + cast_to_double_type(maximum), \ + cast_to_double_type(epsilon), \ + 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. + * + * @param[in] epsilon The epsilon used as margin for float comparison. + * + * @see check_expected(). + */ +void expect_float_not_in_range(#function, #parameter, double minimum, double maximum, double epsilon); +#else +#define expect_float_not_in_range(function, parameter, minimum, maximum, epsilon) \ + expect_float_not_in_range_count(function, parameter, minimum, maximum, epsilon, 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] epsilon The epsilon used as margin for float comparison. + * + * @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_float_not_in_range_count(#function, #parameter, double minimum, double maximum, double epsilon, size_t count); +#else +#define expect_float_not_in_range_count(function, parameter, minimum, maximum, \ + epsilon, count) \ + _expect_float_not_in_range(cmocka_tostring(function), \ + cmocka_tostring(parameter), \ + __FILE__, \ + __LINE__, \ + cast_to_double_type(minimum), \ + cast_to_double_type(maximum), \ + cast_to_double_type(epsilon), \ + count) +#endif + +#ifdef DOXYGEN +/** + * @deprecated Use expect_int_value() or expect_uint_value() + */ +void expect_value(#function, #parameter, uintmax_t value); +#else +#define expect_value(function, parameter, value) \ + do { \ + CMOCKA_DEPRECATION_WARNING("expect_value: use expect_int_value or " \ + "expect_uint_value instead") \ + expect_value_count(function, parameter, value, 1); \ + } while (0) +#endif + +#ifdef DOXYGEN +/** + * @deprecated Use expect_int_value_count() or expect_uint_value_count() + */ +void expect_value_count(#function, #parameter, uintmax_t value, size_t count); +#else +#define expect_value_count(function, parameter, value, count) \ + do { \ + CMOCKA_DEPRECATION_WARNING( \ + "expect_value_count: use expect_int_value_count or " \ + "expect_uint_value_count instead") \ + _expect_value(cmocka_tostring(function), \ + cmocka_tostring(parameter), \ + __FILE__, \ + __LINE__, \ + cast_to_uintmax_type(value), \ + count); \ + } while (0) +#endif + +#ifdef DOXYGEN +/** + * @brief Add an event to check if an integer 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_int_value(#function, #parameter, intmax_t value); +#else +#define expect_int_value(function, parameter, value) \ + expect_int_value_count(function, parameter, value, 1) +#endif + +#ifdef DOXYGEN +/** + * @brief Add an event to repeatedly check if an integer 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_int_value_count(#function, +#parameter, + intmax_t value, + size_t count); +#else +#define expect_int_value_count(function, parameter, value, count) \ + _expect_int_value(cmocka_tostring(function), \ + cmocka_tostring(parameter), \ + __FILE__, \ + __LINE__, \ + value, \ + count) +#endif + +#ifdef DOXYGEN +/** + * @brief Add an event to check if an unsigned integer 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_uint_value(#function, #parameter, uintmax_t value); +#else +#define expect_uint_value(function, parameter, value) \ + expect_uint_value_count(function, parameter, value, 1) +#endif + +#ifdef DOXYGEN +/** + * @brief Add an event to repeatedly check if an unsigned integer 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_uint_value_count(#function, +#parameter, + uintmax_t value, + size_t count); +#else +#define expect_uint_value_count(function, parameter, value, count) \ + _expect_uint_value(cmocka_tostring(function), \ + cmocka_tostring(parameter), \ + __FILE__, \ + __LINE__, \ + value, \ + count) +#endif + +#ifdef DOXYGEN +/** + * @brief Add an event to check if a parameter (int) 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 (intmax_t) to check. + * + * @see check_expected(). + */ +void expect_int_not_value(#function, #parameter, intmax_t value); +#else +#define expect_int_not_value(function, parameter, value) \ + expect_int_not_value_count(function, parameter, value, 1) +#endif + +#ifdef DOXYGEN +/** + * @brief Add an event to repeatedly check if a parameter (int) 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 (intmax_t) 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_int_not_value_count(#function, + #parameter, + intmax_t value, + size_t count); +#else +#define expect_int_not_value_count(function, parameter, value, count) \ + _expect_int_not_value(cmocka_tostring(function), \ + cmocka_tostring(parameter), \ + __FILE__, \ + __LINE__, \ + value, \ + count) +#endif + +#ifdef DOXYGEN +/** + * @brief Add an event to check if a parameter (uint) 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 (uintmax_t) to check. + * + * @see check_expected(). + */ +void expect_uint_not_value(#function, #parameter, uintmax_t value); +#else +#define expect_uint_not_value(function, parameter, value) \ + expect_uint_not_value_count(function, parameter, value, 1) +#endif + +#ifdef DOXYGEN +/** + * @brief Add an event to repeatedly check if a parameter (uint) 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 (uintmax_t) 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_uint_not_value_count(#function, + #parameter, + uintmax_t value, + size_t count); +#else +#define expect_uint_not_value_count(function, parameter, value, count) \ + _expect_uint_not_value(cmocka_tostring(function), \ + cmocka_tostring(parameter), \ + __FILE__, \ + __LINE__, \ + value, \ + count) +#endif + +#ifdef DOXYGEN +/** + * @deprecated Use expect_int_not_value() or expect_uint_not_value() + */ +void expect_not_value(#function, #parameter, uintmax_t value); +#else +#define expect_not_value(function, parameter, value) \ + do { \ + CMOCKA_DEPRECATION_WARNING( \ + "expect_not_value: use expect_int_not_value or " \ + "expect_uint_not_value instead") \ + expect_not_value_count(function, parameter, value, 1); \ + } while (0) +#endif + +#ifdef DOXYGEN +/** + * @deprecated Use expect_int_not_value_count() or expect_uint_not_value_count() + */ +void expect_not_value_count(#function, #parameter, uintmax_t value, size_t count); +#else +#define expect_not_value_count(function, parameter, value, count) \ + do { \ + CMOCKA_DEPRECATION_WARNING( \ + "expect_not_value_count: use expect_int_not_value_count or " \ + "expect_uint_not_value_count instead") \ + _expect_not_value(cmocka_tostring(function), \ + cmocka_tostring(parameter), \ + __FILE__, \ + __LINE__, \ + cast_to_uintmax_type(value), \ + count); \ + } while (0) +#endif + +#ifdef DOXYGEN +/** + * @brief Add an event to check if a parameter is the given floating point value. + * + * The event is triggered by calling check_expected_float() 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] epsilon The epsilon used as margin for float comparison. + * + * @see check_expected_float() + * @see expect_string() + * @see expect_memory() + * @see expect_any() + */ +void expect_float(#function, #parameter, double value, double epsilon); +#else +#define expect_float(function, parameter, value, epsilon) \ + expect_float_count(function, parameter, cast_to_double_type(value), \ + cast_to_double_type(epsilon), 1) +#endif + +#ifdef DOXYGEN +/** + * @brief Add an event to repeatedly check if a parameter is the given floating + * point value. + * + * The event is triggered by calling check_expected_float() 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] epsilon The epsilon used as margin for float comparison. + * + * @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_float(). + * @see expect_not_string() + * @see expect_not_memory() + */ +void expect_float_count(#function, #parameter, double value, double epsilon, size_t count); +#else +#define expect_float_count(function, parameter, value, epsilon, count) \ + _expect_float(cmocka_tostring(function), cmocka_tostring(parameter), __FILE__, __LINE__, \ + cast_to_double_type(value), cast_to_double_type(epsilon), count) +#endif + +#ifdef DOXYGEN +/** + * @brief Add an event to check if a parameter isn't the given floating point + * value. + * + * The event is triggered by calling check_expected_float() 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] epsilon The epsilon used as margin for float comparison. + * + * @see check_expected_float() + * @see expect_string() + * @see expect_memory() + * @see expect_any() + */ +void expect_not_float(#function, #parameter, double value, double epsilon); +#else +#define expect_not_float(function, parameter, value, epsilon) \ + expect_not_float_count(function, \ + parameter, \ + cast_to_float_type(value), \ + cast_to_float_type(epsilon), \ + 1) +#endif + +#ifdef DOXYGEN +/** + * @brief Add an event to repeatedly check if a parameter isn't the floating + * point value. + * + * The event is triggered by calling check_expected_float() 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] epsilon The epsilon used as margin for float comparison. + * + * @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_float(). + * @see expect_not_string() + * @see expect_not_memory() + */ +void expect_not_float_count(#function, #parameter, double value, double epsilon, size_t count); +#else +#define expect_not_float_count(function, parameter, value, epsilon, count) \ + _expect_not_float(cmocka_tostring(function), \ + cmocka_tostring(parameter), \ + __FILE__, \ + __LINE__, \ + cast_to_float_type(value), \ + cast_to_float_type(epsilon), \ + count) +#endif + +#ifdef DOXYGEN +/** + * @brief Add an event to check if a parameter is the given double + * precision floating point value. + * + * The event is triggered by calling check_expected_double() 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] epsilon The epsilon used as margin for double comparison. + * + * @see check_expected_double() + */ +void expect_double(#function, #parameter, double value, double epsilon); +#else +#define expect_double(function, parameter, value, epsilon) \ + expect_double_count(function, \ + parameter, \ + cast_to_double_type(value), \ + cast_to_double_type(epsilon), \ + 1) +#endif + +#ifdef DOXYGEN +/** + * @brief Add an event to repeatedly check if a parameter is the given double + * precision floating point value. + * + * The event is triggered by calling check_expected_double() 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] epsilon The epsilon used as margin for double comparison. + * + * @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_double(). + */ +void expect_double_count(#function, + #parameter, + double value, + double epsilon, + size_t count); +#else +#define expect_double_count(function, parameter, value, epsilon, count) \ + _expect_double(cmocka_tostring(function), \ + cmocka_tostring(parameter), \ + __FILE__, \ + __LINE__, \ + cast_to_double_type(value), \ + cast_to_double_type(epsilon), \ + count) +#endif + +#ifdef DOXYGEN +/** + * @brief Add an event to check if a parameter isn't the given double precision + * floating point value. + * + * The event is triggered by calling check_expected_double() 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] epsilon The epsilon used as margin for double comparison. + * + * @see check_expected_double() + */ +void expect_not_double(#function, #parameter, double value, double epsilon); +#else +#define expect_not_double(function, parameter, value, epsilon) \ + expect_not_double_count(function, \ + parameter, \ + cast_to_double_type(value), \ + cast_to_double_type(epsilon), \ + 1) +#endif + +#ifdef DOXYGEN +/** + * @brief Add an event to repeatedly check if a parameter isn't the double + * precision floating point value. + * + * The event is triggered by calling check_expected_double() 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] epsilon The epsilon used as margin for double comparison. + * + * @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_double(). + */ +void expect_not_double_count(#function, + #parameter, + double value, + double epsilon, + size_t count); +#else +#define expect_not_double_count(function, parameter, value, epsilon, count) \ + _expect_not_double(cmocka_tostring(function), \ + cmocka_tostring(parameter), \ + __FILE__, \ + __LINE__, \ + cast_to_double_type(value), \ + cast_to_double_type(epsilon), \ + 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(cmocka_tostring(function), cmocka_tostring(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(cmocka_tostring(function), cmocka_tostring(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(cmocka_tostring(function), cmocka_tostring(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(cmocka_tostring(function), cmocka_tostring(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 always 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_always(#function, #parameter); +#else +#define expect_any_always(function, parameter) \ + expect_any_count(function, parameter, WILL_RETURN_ALWAYS) +#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(cmocka_tostring(function), cmocka_tostring(parameter), __FILE__, __LINE__, count) +#endif + +#ifdef DOXYGEN +/** + * @deprecated Use check_expected_int(), check_expected_uint(), + * check_expected_float or check_expetecd_double() instead. + */ +void check_expected(#parameter); +#else +#define check_expected(parameter) \ + do { \ + CMOCKA_DEPRECATION_WARNING( \ + "check_expected: use check_expected_int or " \ + "check_expected_uint instead") \ + _check_expected(__func__, \ + #parameter, \ + __FILE__, \ + __LINE__, \ + cast_int_to_cmocka_value(parameter)); \ + } while (0) +#endif + +#ifdef DOXYGEN +/** + * @brief Check that any parameter value matches the next value in the queue. + * + * This generic parameter checker works with any type including structs passed + * by value. It passes the address of the parameter, making it suitable for + * struct validation with custom checkers. + * + * Use this when: + * - Checking structs passed by value with expect_check_data() + * - Generic/template code where the type isn't known + * + * For scalar types, prefer the type-specific versions: + * - check_expected_int() for signed integers + * - check_expected_uint() for unsigned integers + * - check_expected_float() for float types + * - check_expected_double() for double types + * - check_expected_ptr() for pointers + * + * @param[in] #parameter The parameter to check. + * + * @see check_expected_int() + * @see check_expected_uint() + * @see check_expected_float() + * @see check_expected_double() + * @see check_expected_ptr() + * @see expect_check_data() + */ +void check_expected_any(#parameter); +#else +#define check_expected_any(parameter) \ + _check_expected(__func__, #parameter, __FILE__, __LINE__, \ + cast_ptr_to_cmocka_value(&(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_cmocka_value(parameter)) +#endif + +#ifdef DOXYGEN +/** + * @brief Determine whether a function parameter is correct. + * + * This ensures the next value queued by one of the expect_int*() 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_int(#parameter); +#else +#define check_expected_int(parameter) \ + _check_expected(__func__, \ + #parameter, \ + __FILE__, \ + __LINE__, \ + assign_int_to_cmocka_value(parameter)) +#endif + +#ifdef DOXYGEN +/** + * @brief Determine whether a function parameter is correct. + * + * This ensures the next value queued by one of the expect_uint*() 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_uint(#parameter); +#else +#define check_expected_uint(parameter) \ + _check_expected(__func__, \ + #parameter, \ + __FILE__, \ + __LINE__, \ + assign_uint_to_cmocka_value(parameter)) +#endif + +#ifdef DOXYGEN +/** + * @brief Determine whether a function parameter is correct. + * + * This ensures the next value queued by one of the expect*_float() macros matches + * the specified variable. + * + * This function needs to be called in the mock object. + * + * @param[in] #parameter The parameter to check. + * + * @see expect_float + * @see expect_not_float + * @see expect_float_count + * @see expect_not_float_count + */ +void check_expected_float(#parameter); +#else +#define check_expected_float(parameter) \ + _check_expected(__func__, \ + #parameter, \ + __FILE__, \ + __LINE__, \ + assign_float_to_cmocka_value(parameter)) +#endif + +#ifdef DOXYGEN +/** + * @brief Determine whether a function parameter is correct. + * + * This ensures the next value queued by one of the expect*_double() macros + * matches the specified variable. + * + * This function needs to be called in the mock object. + * + * @param[in] #parameter The parameter to check. + * + * @see expect_double + * @see expect_not_double + * @see expect_double_count + * @see expect_not_double_count + */ +void check_expected_double(#parameter); +#else +#define check_expected_double(parameter) \ + _check_expected(__func__, \ + #parameter, \ + __FILE__, \ + __LINE__, \ + assign_double_to_cmocka_value(parameter)) +#endif + +/** @} */ /* cmocka_param */ + +/** + * @defgroup cmocka_asserts 🛡️ Assert Macros + * @ingroup cmocka + * @brief Verify conditions and fail tests when assertions don't hold. + * + * Assertion macros for validating test conditions. + * + * CMocka provides type-specific assertion macros that display detailed + * information about failures, making debugging easier than the standard C + * library'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_uintmax_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_false(cast_to_uintmax_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(intmax_t rc, int32_t error); +#else +#define assert_return_code(rc, error) \ + _assert_return_code((rc), \ + (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 NULL. + * + * @param[in] pointer The pointer to evaluate. + * + * @see assert_null() + */ +void assert_non_null(void *pointer); +#else +#define assert_non_null(c) assert_ptr_not_equal((c), NULL) +#endif + +#ifdef DOXYGEN +/** + * @brief Assert that the given pointer is non-NULL. + * + * The function prints an error message extended by message to standard error + * and terminates the test by calling fail() if the pointer is NULL. + * + * @param[in] pointer The pointer to evaluate. + * + * @param[in] message The message to print when the pointer is NULL. + * + * @see assert_null_msg() + */ +void assert_non_null_msg(void *pointer, const char *const message); +#else +#define assert_non_null_msg(c, msg) assert_ptr_not_equal_msg((c), NULL, (msg)) +#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_ptr_equal((c), NULL) +#endif + +#ifdef DOXYGEN +/** + * @brief Assert that the given pointer is NULL. + * + * The function prints an error message extended by message to standard error + * and terminates the test by calling fail() if the pointer is non-NULL. + * + * @param[in] pointer The pointer to evaluate. + * + * @param[in] message The message to print when the pointer is not NULL. + * + * @see assert_non_null_msg() + */ +void assert_null_msg(void *pointer, const char *const message); +#else +#define assert_null_msg(c, msg) assert_ptr_equal_msg((c), NULL, (msg)) +#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_ptr_equal_msg((a), (b), NULL) +#endif + +#ifdef DOXYGEN +/** + * @brief Assert that the two given pointers are equal. + * + * The function prints the failing comparison and the error message given by the user + * and then 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. + * + * @param[in] msg The error message to print when a & b are not equal. + */ +void assert_ptr_equal_msg(void *a, void *b, const char *const msg); +#else +#define assert_ptr_equal_msg(a, b, msg) \ + _assert_ptr_equal_msg(cast_to_void_pointer(a), \ + cast_to_void_pointer(b), \ + __FILE__, __LINE__, (msg)) +#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_ptr_not_equal_msg((a), (b), NULL) +#endif + +#ifdef DOXYGEN +/** + * @brief Assert that the two given pointers are not equal. + * + * The function prints the failing comparison and the error message given by the user + * and then 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. + * + * @param[in] msg The error message to print when a & b are equal. + */ +void assert_ptr_not_equal_msg(void *a, void *b, const char *const msg); +#else /* DOXYGEN */ + +#if defined(__has_builtin) + +#if __has_builtin(__builtin_unreachable) +#define assert_ptr_not_equal_msg(a, b, msg) \ + do { \ + const void *cmocka_p1 = cast_to_void_pointer(a), \ + *cmocka_p2 = cast_to_void_pointer(b); \ + _assert_ptr_not_equal_msg( \ + cmocka_p1, cmocka_p2, __FILE__, __LINE__, (msg)); \ + if (cmocka_p1 == cmocka_p2) { \ + __builtin_unreachable(); \ + } \ + } while (0) +#else /* __has_builtin(__builtin_unreachable) */ +#define assert_ptr_not_equal_msg(a, b, msg) \ +_assert_ptr_not_equal_msg(cast_to_void_pointer(a), \ + cast_to_void_pointer(b), \ + __FILE__, \ + __LINE__, \ + (msg)) +#endif /* __has_builtin(__builtin_unreachable) */ + +#else /* defined(__has_builtin) */ +#define assert_ptr_not_equal_msg(a, b, msg) \ +_assert_ptr_not_equal_msg(cast_to_void_pointer(a), \ + cast_to_void_pointer(b), \ + __FILE__, \ + __LINE__, \ + (msg)) +#endif /* __has_builtin(__builtin_unreachable) */ + +#endif /* DOXYGEN */ + +#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(intmax_t a, intmax_t b); +#else +#define assert_int_equal(a, b) \ + _assert_int_equal(cast_to_intmax_type(a), \ + cast_to_intmax_type(b), \ + __FILE__, __LINE__) +#endif + +#ifdef DOXYGEN +/** + * @brief Assert that the two given unsigned 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 unsigned integer to compare. + * + * @param[in] b The unsigned integer to compare against the first one. + */ +void assert_uint_equal(uintmax_t a, uintmax_t b); +#else +#define assert_uint_equal(a, b) \ + _assert_uint_equal(cast_to_uintmax_type(a), \ + cast_to_uintmax_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(intmax_t a, intmax_t b); +#else +#define assert_int_not_equal(a, b) \ + _assert_int_not_equal(cast_to_intmax_type(a), \ + cast_to_intmax_type(b), \ + __FILE__, __LINE__) +#endif + +#ifdef DOXYGEN +/** + * @brief Assert that the two given unsigned integers are not 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 unsigned integer to compare. + * + * @param[in] b The unsigned integer to compare against the first one. + */ +void assert_uint_not_equal(uintmax_t a, uintmax_t b); +#else +#define assert_uint_not_equal(a, b) \ + _assert_uint_not_equal(cast_to_uintmax_type(a), \ + cast_to_uintmax_type(b), \ + __FILE__, __LINE__) +#endif + +#ifdef DOXYGEN +/** + * @brief Assert that the two given float are equal given an epsilon. + * + * The function prints an error message to standard error and terminates the + * test by calling fail() if the float are not equal (given an epsilon). + * + * @param[in] a The first float to compare. + * + * @param[in] b The float to compare against the first one. + * + * @param[in] epsilon The epsilon used as margin for float comparison. + */ +void assert_float_equal(float a, float b, float epsilon); +#else +#define assert_float_equal(a, b, epsilon) \ + _assert_float_equal((float)a, \ + (float)b, \ + (float)epsilon, \ + __FILE__, __LINE__) +#endif + +#ifdef DOXYGEN +/** + * @brief Assert that the two given float are not equal given an epsilon. + * + * The function prints an error message to standard error and terminates the + * test by calling fail() if the float are not equal (given an epsilon). + * + * @param[in] a The first float to compare. + * + * @param[in] b The float to compare against the first one. + * + * @param[in] epsilon The epsilon used as margin for float comparison. + */ +void assert_float_not_equal(float a, float b, float epsilon); +#else +#define assert_float_not_equal(a, b, epsilon) \ + _assert_float_not_equal((float)a, \ + (float)b, \ + (float)epsilon, \ + __FILE__, __LINE__) +#endif + +#ifdef DOXYGEN +/** + * @brief Assert that the two given double are equal given an epsilon. + * + * The function prints an error message to standard error and terminates the + * test by calling fail() if the double are not equal (given an epsilon). + * + * @param[in] a The first double to compare. + * + * @param[in] b The double to compare against the first one. + * + * @param[in] epsilon The epsilon used as margin for double comparison. + */ +void assert_double_equal(double a, double b, double epsilon); +#else +#define assert_double_equal(a, b, epsilon) \ + _assert_double_equal((double)a, \ + (double)b, \ + (double)epsilon, \ + __FILE__, __LINE__) +#endif + +#ifdef DOXYGEN +/** + * @brief Assert that the two given double are not equal given an epsilon. + * + * The function prints an error message to standard error and terminates the + * test by calling fail() if the double are not equal (given an epsilon). + * + * @param[in] a The first double to compare. + * + * @param[in] b The double to compare against the first one. + * + * @param[in] epsilon The epsilon used as margin for double comparison. + */ +void assert_double_not_equal(double a, double b, double epsilon); +#else +#define assert_double_not_equal(a, b, epsilon) \ + _assert_double_not_equal((double)a, \ + (double)b, \ + (double)epsilon, \ + __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((a), (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((a), (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 integer 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_int_in_range(intmax_t value, intmax_t minimum, intmax_t maximum); +#else +#define assert_int_in_range(value, minimum, maximum) \ + _assert_int_in_range( \ + cast_to_intmax_type(value), \ + cast_to_intmax_type(minimum), \ + cast_to_intmax_type(maximum), __FILE__, __LINE__) +#endif + +#ifdef DOXYGEN +/** + * @brief Assert that the specified unsigned integer 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_uint_in_range(uintmax_t value, uintmax_t minimum, uintmax_t maximum); +#else +#define assert_uint_in_range(value, minimum, maximum) \ + _assert_uint_in_range( \ + cast_to_intmax_type(value), \ + cast_to_intmax_type(minimum), \ + cast_to_intmax_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. + * + * 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_int_not_in_range(intmax_t value, + intmax_t minimum, + intmax_t maximum); +#else +#define assert_int_not_in_range(value, minimum, maximum) \ + _assert_int_not_in_range(cast_to_intmax_type(value), \ + cast_to_intmax_type(minimum), \ + cast_to_intmax_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. + * + * 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_uint_not_in_range(uintmax_t value, + uintmax_t minimum, + uintmax_t maximum); +#else +#define assert_uint_not_in_range(value, minimum, maximum) \ + _assert_uint_not_in_range(cast_to_uintmax_type(value), \ + cast_to_uintmax_type(minimum), \ + cast_to_uintmax_type(maximum), \ + __FILE__, \ + __LINE__) +#endif + +#ifdef DOXYGEN +/** + * @deprecated Use assert_int_in_range() and assert_uint_in_range() + */ +void assert_in_range(uintmax_t value, uintmax_t minimum, uintmax_t maximum); +#else +#define assert_in_range(value, minimum, maximum) \ + do { \ + CMOCKA_DEPRECATION_WARNING( \ + "assert_in_range: use assert_int_in_range or " \ + "assert_uint_in_range instead") \ + _assert_uint_in_range(cast_to_uintmax_type(value), \ + cast_to_uintmax_type(minimum), \ + cast_to_uintmax_type(maximum), \ + __FILE__, \ + __LINE__); \ + } while (0) +#endif + +#ifdef DOXYGEN +/** + * @deprecated Use assert_int_not_in_range() or assert_uint_not_in_range() + */ +void assert_not_in_range(uintmax_t value, uintmax_t minimum, uintmax_t maximum); +#else +#define assert_not_in_range(value, minimum, maximum) \ + do { \ + CMOCKA_DEPRECATION_WARNING( \ + "assert_not_in_range: use assert_int_not_in_range or " \ + "assert_uint_not_in_range instead") \ + _assert_uint_not_in_range(cast_to_uintmax_type(value), \ + cast_to_uintmax_type(minimum), \ + cast_to_uintmax_type(maximum), \ + __FILE__, \ + __LINE__); \ + } while (0) +#endif + +#ifdef DOXYGEN +/** + * @brief Assert that the specified float 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. + * + * 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. + * + * @param[in] epsilon The epsilon used as margin for float comparison. + */ +void assert_float_not_in_range(double value, double minimum, double maximum, double epsilon); +#else +#define assert_float_not_in_range(value, minimum, maximum, epsilon) \ + _assert_float_not_in_range(cast_to_double_type(value), \ + cast_to_double_type(minimum), \ + cast_to_double_type(maximum), \ + cast_to_double_type(epsilon), \ + __FILE__, \ + __LINE__) +#endif + +#ifdef DOXYGEN +/** + * @brief Assert that the specified float 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. + * + * @param[in] epsilon The epsilon used as margin for float comparison. + */ +void assert_float_in_range(double value, double minimum, double maximum, double epsilon); +#else +#define assert_float_in_range(value, minimum, maximum, epsilon) \ + _assert_float_in_range( \ + cast_to_double_type(value), \ + cast_to_double_type(minimum), \ + cast_to_double_type(maximum), \ + cast_to_double_type(epsilon), __FILE__, __LINE__) +#endif + +#ifdef DOXYGEN +/** + * @deprecated Use assert_int_in_set() or assert_uint_in_set() + */ +void assert_in_set(uintmax_t value, uintmax_t values[], size_t count); +#else +#define assert_in_set(value, values, number_of_values) \ + do { \ + CMOCKA_DEPRECATION_WARNING("assert_in_set: use assert_int_in_set or " \ + "assert_uint_in_set instead") \ + _assert_uint_in_set( \ + value, values, number_of_values, __FILE__, __LINE__); \ + } while (0) +#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(uintmax_t value, uintmax_t 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 + +#ifdef DOXYGEN +/** + * @brief Assert that the specified integer 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_int_in_set(intmax_t value, intmax_t values[], size_t count); +#else +#define assert_int_in_set(value, values, number_of_values) \ + if (number_of_values > 0) { \ + intmax_t _cmocka_set[number_of_values]; \ + for (size_t _i = 0; _i < number_of_values; _i++) { \ + _cmocka_set[_i] = values[_i]; \ + } \ + _assert_int_in_set(value, _cmocka_set, 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_int_not_in_set(intmax_t value, intmax_t values[], size_t count); +#else +#define assert_int_not_in_set(value, values, number_of_values) \ + if (number_of_values > 0) { \ + intmax_t _cmocka_set[number_of_values]; \ + for (size_t _i = 0; _i < number_of_values; _i++) { \ + _cmocka_set[_i] = values[_i]; \ + } \ + _assert_int_not_in_set(value, _cmocka_set, number_of_values, __FILE__, __LINE__); \ + } +#endif + +#ifdef DOXYGEN +/** + * @brief Assert that the specified unsigned integer 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_uint_in_set(uintmax_t value, uintmax_t values[], size_t count); +#else +#define assert_uint_in_set(value, values, number_of_values) \ + if (number_of_values > 0) { \ + uintmax_t _cmocka_set[number_of_values]; \ + for (size_t _i = 0; _i < number_of_values; _i++) { \ + _cmocka_set[_i] = values[_i]; \ + } \ + _assert_uint_in_set(value, _cmocka_set, number_of_values, __FILE__, __LINE__); \ + } +#endif + +#ifdef DOXYGEN +/** + * @brief Assert that the specified unsigned integer 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_uint_not_in_set(uintmax_t value, uintmax_t values[], size_t count); +#else +#define assert_uint_not_in_set(value, values, number_of_values) \ + if (number_of_values > 0) { \ + uintmax_t _cmocka_set[number_of_values]; \ + for (size_t _i = 0; _i < number_of_values; _i++) { \ + _cmocka_set[_i] = values[_i]; \ + } \ + _assert_uint_not_in_set(value, _cmocka_set, number_of_values, __FILE__, __LINE__); \ + } +#endif + +#ifdef DOXYGEN +/** + * @brief Assert that the specified float 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. + * + * @param[in] epsilon The epsilon used as margin for float comparison. + */ +void assert_float_in_set(double value, double values[], size_t count, double epsilon); +#else +#define assert_float_in_set(value, values, number_of_values, epsilon) \ + if (number_of_values > 0) { \ + double _cmocka_set[number_of_values]; \ + for (size_t _i = 0; _i < number_of_values; _i++) { \ + _cmocka_set[_i] = values[_i]; \ + } \ + _assert_float_in_set(value, _cmocka_set, number_of_values, epsilon, __FILE__, __LINE__); \ + } +#endif + +#ifdef DOXYGEN +/** + * @brief Assert that the specified float 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 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. + * + * @param[in] epsilon The epsilon used as margin for float comparison. + */ +void assert_float_not_in_set(double value, double values[], size_t count, double epsilon); +#else +#define assert_float_not_in_set(value, values, number_of_values, epsilon) \ + if (number_of_values > 0) { \ + double _cmocka_set[number_of_values]; \ + for (size_t _i = 0; _i < number_of_values; _i++) { \ + _cmocka_set[_i] = values[_i]; \ + } \ + _assert_float_not_in_set(value, _cmocka_set, number_of_values, epsilon, __FILE__, __LINE__); \ + } +#endif + +/** @} */ /* cmocka_asserts */ + +/** + * @defgroup cmocka_call_order 🔢 Call Ordering + * @ingroup cmocka + * @brief Ensure functions are called in the correct sequence. + * + * Verify that functions are called in the expected order. + * + * This module provides functionality to ensure functions are called in a + * specific sequence, independent of mock return values and parameter + * checking. Both of the aforementioned do not verify the order in which + * functions are called. + * + *
    + *
  • expect_function_call(function) - The + * expect_function_call() macro pushes an expectation onto the stack of + * expected calls.
  • + * + *
  • function_called() - pops a value from the stack of + * expected calls. function_called() is invoked within the mock object + * that uses it. + *
+ * + * 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. function_called() must be called from + * the same thread as expect_function_call(), and that thread must have been + * initialized for use by cmocka (see also the [Threading section of the main + * documentation page](index.html#main-threads)). + * + * The following example illustrates how a unit test instructs cmocka + * to expect a function_called() from a particular mock, + * chef_sing(): + * + * @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 function_called(): + * + * @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(cmocka_tostring(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(cmocka_tostring(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(cmocka_tostring(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(cmocka_tostring(function), __FILE__, __LINE__, -2) +#endif + +/** @} */ /* cmocka_call_order */ + +/** + * @defgroup cmocka_exec ▶️ Running Tests + * @ingroup cmocka + * @brief Execute test suites with setup and teardown functions. + * + * Test execution framework and test runners. + * + * This module provides the infrastructure for defining, organizing, and + * running tests, including support for setup/teardown functions (fixtures), + * test grouping, and multiple test runner macros. + * + * The following example illustrates how to define and run tests with + * CMocka. + * + * @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 be stopped immediately. + * + * Call stop() to stop a running test. + * The test is considered passed if there are no leftover values, otherwise a test failure + * is signaled. + * Calling stop() is especially useful in mocked functions that do not return, e.g reset the CPU. + */ +void stop(void); +#else +#define stop() _stop() +#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 { \ + cmocka_print_error("ERROR: " msg "\n", ##__VA_ARGS__); \ + fail(); \ +} while (0) +#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) \ + (CMOCKA_DEPRECATION_WARNING("unit_test: use cmocka_unit_test instead")( \ + UnitTest){#f, f, UNIT_TEST_FUNCTION_TYPE_TEST}) + +/** @cond INTERNAL */ +#define _unit_test_setup(test, setup) \ + { #test "_" #setup, setup, UNIT_TEST_FUNCTION_TYPE_SETUP } +/** @endcond */ + +/** 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) \ + CMOCKA_DEPRECATION_WARNING( \ + "unit_test_setup: use cmocka_unit_test_setup instead") \ + _unit_test_setup(test, setup), unit_test(test), \ + _unit_test_teardown(test, _unit_test_dummy) + +/** @cond INTERNAL */ +#define _unit_test_teardown(test, teardown) \ + { #test "_" #teardown, teardown, UNIT_TEST_FUNCTION_TYPE_TEARDOWN } +/** @endcond */ + +/** 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) \ + CMOCKA_DEPRECATION_WARNING( \ + "unit_test_teardown: use cmocka_unit_test_teardown instead") \ + _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) \ + (CMOCKA_DEPRECATION_WARNING( \ + "group_test_setup: use cmocka_run_group_tests instead")(UnitTest){ \ + "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) \ + (CMOCKA_DEPRECATION_WARNING( \ + "group_test_teardown: use cmocka_run_group_tests instead")(UnitTest){ \ + "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) \ + CMOCKA_DEPRECATION_WARNING("unit_test_setup_teardown: use " \ + "cmocka_unit_test_setup_teardown instead") \ + _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 } + +#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 + +/** @} */ /* cmocka_exec */ + +/** + * @defgroup cmocka_alloc 🧩 Dynamic Memory Allocation + * @ingroup cmocka + * @brief Detect memory leaks, buffer overflows, and allocation errors. + * + * @warning This shouldn't be used anymore, better use + * AddressSanitizer. + * + * 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. + * + * Automatic Allocation Redirection (Deprecated): + * + * When both UNIT_TESTING and ALLOCATION_TESTING are defined, the standard + * C library allocation functions (malloc, calloc, realloc, free) are + * automatically redirected to cmocka's test allocators. This enables + * automatic memory leak detection and helps ensure proper memory management + * in tested code. + * + * @note This feature is deprecated and should not be used in new code. + * Better use + * AddressSanitizer. + * + * To enable allocation testing, define both macros before including cmocka.h: + * + * @code + * #include + * + * #define UNIT_TESTING 1 + * #define ALLOCATION_TESTING 1 + * #include + * + * // This code will have malloc/free automatically redirected + * void* ptr = malloc(100); // Actually calls test_malloc() + * free(ptr); // Actually calls test_free() + * @endcode + * + * With ALLOCATION_TESTING enabled: + * - malloc() → test_malloc() + * - calloc() → test_calloc() + * - realloc() → test_realloc() + * - free() → test_free() + * + * @warning Mixing regular allocations with test allocations can lead to + * memory corruption. Ensure consistent usage throughout your + * test code. + * @{ + */ + +#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 memory 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 + +#if defined(UNIT_TESTING) && defined(ALLOCATION_TESTING) +#define malloc test_malloc +#define realloc test_realloc +#define calloc test_calloc +#define free test_free +#endif /* UNIT_TESTING && ALLOCATION_TESTING */ + +/** @} */ /* cmocka_alloc */ + +/** + * @defgroup cmocka_mock_assert 🎯 Standard Assertions + * @ingroup cmocka + * @brief Test code that uses assert(3) from the standard C library. + * + * 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 conjunction 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) \ + { \ + global_expecting_assert = 1; \ + if (setjmp(global_expect_assert_env) != 0) { \ + 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 + +/** @} */ /* cmocka_mock_assert */ + +/** + * @ingroup cmocka_util + * + * CMocka value data type. + * + * Allows storing multiple types of values in CMocka functions without using + * undefined behavior. + */ +typedef union { + /** Holds signed integral types */ + intmax_t int_val; + /** Holds integral types */ + uintmax_t uint_val; + /** Holds floating-point type */ + float float_val; + /** Holds double/real floating-pointing types*/ + double real_val; // TODO: Should we use `long double` instead + /** Holds pointer data */ + void *ptr; + /** Holds pointer data (const) */ + const void *const_ptr; + // The following aren't used by CMocka currently, but are added to avoid + // breaking ABI compatibility in the future + /** Holds function pointer data */ + void *(*func)(void); +} CMockaValueData; + +#ifndef DOXYGEN +/** + * @deprecated This type was replaced by uintmax_t for better type clarity. + * Use uintmax_t directly instead. + */ +#define LargestIntegralType uintmax_t + +/** + * @deprecated Use cast_ptr_to_uintmax_type instead + */ +#if defined(__GNUC__) +#define cast_ptr_to_largest_integral_type(value) \ + __extension__({ \ + CMOCKA_DEPRECATION_WARNING( \ + "cast_ptr_to_largest_integral_type: " \ + "use cast_ptr_to_uintmax_type instead"); \ + cast_ptr_to_uintmax_type(value); \ + }) +#else +#define cast_ptr_to_largest_integral_type(value) \ + cast_ptr_to_uintmax_type(value) +#endif +#endif + +/** + * @ingroup cmocka_exec + * + * Function prototype for setup, test and teardown functions. + */ +typedef void (*UnitTestFunction)(void **state); + +/** + * @ingroup cmocka_param + * + * Function that determines whether a function parameter value is correct (old API). + */ +typedef int (*CheckParameterValue)(const uintmax_t value, + const uintmax_t check_value_data); + +/** + * @ingroup cmocka_param + * + * Function that determines whether a function parameter value is correct (new API with CMockaValueData). + */ +typedef int (*CheckParameterValueData)(const CMockaValueData value, + const CMockaValueData check_value_data); + +/** + * @ingroup cmocka_param + * + * Function that determines whether a function parameter value is correct. + */ +typedef int (*CheckIntParameterValue)(const intmax_t value, + const intmax_t check_value_data); + +/** + * @ingroup cmocka_param + * + * Function that determines whether a function parameter value is correct. + */ +typedef int (*CheckUintParameterValue)(const uintmax_t value, + const uintmax_t check_value_data); + +/** + * @ingroup cmocka_exec + * + * 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; + +/** + * @ingroup cmocka_exec + * + * 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; + +/** + * @ingroup cmocka_exec + */ +typedef struct GroupTest { + UnitTestFunction setup; + UnitTestFunction teardown; + const UnitTest *tests; + const size_t number_of_tests; +} GroupTest; + +/** + * @ingroup cmocka_exec + * + * Function prototype for test functions. + */ +typedef void (*CMUnitTestFunction)(void **state); + +/** + * @ingroup cmocka_exec + * + * Function prototype for setup and teardown functions. + */ +typedef int (*CMFixtureFunction)(void **state); + +/** + * @ingroup cmocka_exec + */ +struct CMUnitTest { + const char *name; + CMUnitTestFunction test_func; + CMFixtureFunction setup_func; + CMFixtureFunction teardown_func; + void *initial_state; +}; + +/** + * @ingroup cmocka_param + * + * Location within some source code. + */ +typedef struct SourceLocation { + const char* file; + int line; +} SourceLocation; + +/** + * @ingroup cmocka_param + * + * Event that's called to check a parameter value (old API). + */ +typedef struct CheckParameterEvent { + SourceLocation location; + const char *parameter_name; + CheckParameterValue check_value; + uintmax_t check_value_data; +} CheckParameterEvent; + +/** + * @ingroup cmocka_param + * + * Event that's called to check a parameter value (new API with CMockaValueData). + */ +typedef struct CheckParameterEventData { + SourceLocation location; + const char *parameter_name; + CheckParameterValueData check_value; + CMockaValueData check_value_data; +} CheckParameterEventData; + +/** + * @defgroup cmocka_config 🔧 Configuration and Output + * @ingroup cmocka + * @brief Control test output formats and execution behavior. + * + * Configure test execution behavior and output formatting. + * + * This module provides functions to customize CMocka's behavior, including + * setting custom output callbacks, controlling output format (STANDARD, + * SUBUNIT, TAP, XML), and filtering which tests to run or skip. + * + * @{ + */ + +/* 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); + +/** + * Callbacks which can be set via cmocka_set_callbacks(). + * + * @ingroup cmocka_config + * @sa cmocka_set_callbacks() + */ +struct CMCallbacks { + /** A callback for printing out standard messages. + * The supplied callback function will be invoked by the standard output + * print methods. If no callback has been supplied, the default action + * is to print to `stdout`. + * + * The one exception at present is XML output, which is always written directly + * to a file handle, even if that is set to `stdout`. */ + void (*vprint_message)(const char * const format, va_list args); + + /** A callback for printing out error messages. + * The supplied callback function will be invoked by the standard output + * print methods. If no callback has been supplied, the default action + * is to print to `stdout`. + * + * The one exception at present is XML output, which is always written directly + * to a file handle, even if that is set to `stdout`. */ + void (*vprint_error)(const char * const format, va_list args); +}; + +/** + * @brief Set callback functions for CMocka. + * + * Input is a structure containing function pointers to one or more + * user-supplied callback functions. A NULL pointer for a particular + * callback will set that callback to the default implementation. + * + * See the CMCallbacks documentation for details of each callback. + * + * @param[in] f_callbacks A structure containing the user callbacks to use. + * + * @ingroup cmocka_config + * @sa CMCallbacks + */ +void cmocka_set_callbacks(const struct CMCallbacks *f_callbacks); + +/** + * @brief Output format options for test results. + * + * These are bitfield flags that can be combined using bitwise OR to enable + * multiple output formats simultaneously. + * + * @ingroup cmocka_config + */ +enum cm_message_output { + /** Standard CMocka output format (bit 0) */ + CM_OUTPUT_STANDARD = 0x00000001, + /** Alias for CM_OUTPUT_STANDARD (for API compatibility) */ + CM_OUTPUT_STDOUT = 0x00000001, + /** Subunit output format for test result aggregation (bit 1) */ + CM_OUTPUT_SUBUNIT = 0x00000002, + /** Test Anything Protocol (TAP) output format (bit 2) */ + CM_OUTPUT_TAP = 0x00000004, + /** JUnit-compatible XML output format (bit 3) */ + CM_OUTPUT_XML = 0x00000008, +}; + +#ifdef DOXYGEN +/** + * @deprecated Use cmocka_print_error() + */ +void cm_print_error(const char* const format, ...); +#else +#define cm_print_error(format, ...) \ + do { \ + CMOCKA_DEPRECATION_WARNING( \ + "cm_print_error: use cmocka_print_error instead") \ + cmocka_print_error(format, ##__VA_ARGS__); \ + } while (0) +#endif + +/** + * @brief Print error message using the cmocka output format. + * + * This prints an error message using the message output defined by the + * environment variable CMOCKA_MESSAGE_OUTPUT or + * cmocka_set_message_output(). + * + * @param format The format string fprintf(3) uses. + * @param ... The parameters used to fill format. + * + * @ingroup cmocka_config + */ +void cmocka_print_error(const char* const format, ...) CMOCKA_PRINTF_ATTRIBUTE(1, 2); + +/** + * @brief Function to set the output format for a test. + * + * The output format(s) for the test can either be set globally using this + * function or overwritten with environment variable CMOCKA_MESSAGE_OUTPUT. + * + * The environment variable can be set to STANDARD, SUBUNIT, TAP or XML. + * Multiple outputs separated with comma are permitted. + * (e.g. export CMOCKA_MESSAGE_OUTPUT=STANDARD,XML) + * + * @param[in] output The output format from cm_message_output to use + * for the test. For multiple outputs OR options + * together. + * + * @ingroup cmocka_config + */ +void cmocka_set_message_output(uint32_t output); + + +/** + * @brief Set a pattern to only run the test matching the pattern. + * + * This allows to filter tests and only run the ones matching the pattern. + * The pattern can include two wildcards. The first is '*', a wildcard that + * matches zero or more characters, or '?', a wildcard that matches exactly + * one character. + * + * The same can also be achieved by setting the environment variable + * CMOCKA_TEST_FILTER, without needing to recompile the application. + * + * @param[in] pattern The pattern to match, e.g. "test_wurst*" + * + * @ingroup cmocka_config + */ +void cmocka_set_test_filter(const char *pattern); + +/** + * @brief Set a pattern to skip tests matching the pattern. + * + * This allows to filter tests and skip the ones matching the pattern. The + * pattern can include two wildcards. The first is '*', a wildcard that + * matches zero or more characters, or '?', a wildcard that matches exactly + * one character. + * + * The same can also be achieved by setting the environment variable + * CMOCKA_SKIP_FILTER, without needing to recompile the application. + * + * @param[in] pattern The pattern to match, e.g. "test_wurst*" + * + * @ingroup cmocka_config + */ +void cmocka_set_skip_filter(const char *pattern); + +/** @} */ /* cmocka_config */ + +/** + * @cond INTERNAL + * + * Internal functions used by CMocka macros. + * + * These functions are implementation details and should not be called directly. + * Users should only use the documented macros that wrap these functions. + * These are excluded from the documentation to avoid confusion. + */ + +/* Used by expect_assert_failure() and mock_assert(). */ +CMOCKA_DLLEXTERN extern int global_expecting_assert; +CMOCKA_DLLEXTERN extern jmp_buf global_expect_assert_env; +CMOCKA_DLLEXTERN extern const char * global_last_failed_assert; + +/* Retrieves a value for the given function, as set by "will_return". */ +CMockaValueData _mock(const char *const function, + const char *const file, + const int line, + const char *name); + +CMockaValueData _mock_parameter(const char *const function, + const char *name, + const char *const file, + const int line, + const char *type); + +bool _has_mock(const char *const function); + +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); + +/* Old API function using uintmax_t */ +void _expect_check( + const char* const function, const char* const parameter, + const char* const file, const int line, + const CheckParameterValue check_function, + const uintmax_t check_data, CheckParameterEvent * const event, + const int count) CMOCKA_DEPRECATED; + +/* New API function using CMockaValueData */ +void _expect_check_data( + const char* const function, const char* const parameter, + const char* const file, const int line, + const CheckParameterValueData check_function, + const CMockaValueData check_data, CheckParameterEventData * const event, + const int count); + +void _expect_int_in_set(const char *const function, + const char *const parameter, + const char *const file, + const size_t line, + const intmax_t values[], + const size_t number_of_values, + const size_t count); +void _expect_uint_in_set(const char *const function, + const char *const parameter, + const char *const file, + const size_t line, + const uintmax_t values[], + const size_t number_of_values, + const size_t count); + +void _expect_float_in_set(const char *const function, + const char *const parameter, + const char *const file, + const size_t line, + const double values[], + const size_t number_of_values, + const double epsilon, + const size_t count); + +void _expect_not_in_set( + const char* const function, const char* const parameter, + const char* const file, const int line, const uintmax_t values[], + const size_t number_of_values, const int count); +void _expect_int_not_in_set(const char *const function, + const char *const parameter, + const char *const file, + const size_t line, + const intmax_t values[], + const size_t number_of_values, + const size_t count); +void _expect_uint_not_in_set(const char *const function, + const char *const parameter, + const char *const file, + const size_t line, + const uintmax_t values[], + const size_t number_of_values, + const size_t count); + +void _expect_float_not_in_set( + const char* const function, const char* const parameter, + const char* const file, const size_t line, const double values[], + const size_t number_of_values, const double epsilon, const size_t count); + +void _expect_in_range(const char *const function, + const char *const parameter, + const char *const file, + const int line, + const uintmax_t minimum, + const uintmax_t maximum, + const int count) CMOCKA_DEPRECATED; +void _expect_int_in_range(const char *const function, + const char *const parameter, + const char *const file, + const size_t line, + const intmax_t minimum, + const intmax_t maximum, + const size_t count); +void _expect_uint_in_range(const char *const function, + const char *const parameter, + const char *const file, + const size_t line, + const uintmax_t minimum, + const uintmax_t maximum, + const size_t count); +void _expect_not_in_range( + const char* const function, const char* const parameter, + const char* const file, const int line, + const uintmax_t minimum, + const uintmax_t maximum, const int count); +void _expect_int_not_in_range(const char *const function, + const char *const parameter, + const char *const file, + const size_t line, + const intmax_t minimum, + const intmax_t maximum, + const size_t count); +void _expect_uint_not_in_range(const char *const function, + const char *const parameter, + const char *const file, + const size_t line, + const uintmax_t minimum, + const uintmax_t maximum, + const size_t count); +void _expect_float_in_range( + const char* const function, const char* const parameter, + const char* const file, const int line, + const double minimum, const double maximum, const double epsilon, + const int count); +void _expect_float_not_in_range( + const char* const function, const char* const parameter, + const char* const file, const int line, + const double minimum, const double maximum, const double epsilon, + const int count); + +void _expect_value( + const char* const function, const char* const parameter, + const char* const file, const int line, const uintmax_t value, + const int count); +void _expect_int_value(const char *const function, + const char *const parameter, + const char *const file, + const size_t line, + const intmax_t value, + const size_t count); +void _expect_uint_value(const char *const function, + const char *const parameter, + const char *const file, + const size_t line, + const uintmax_t value, + const size_t count); +void _expect_int_not_value(const char *const function, + const char *const parameter, + const char *const file, + const size_t line, + const intmax_t value, + const size_t count); +void _expect_uint_not_value(const char *const function, + const char *const parameter, + const char *const file, + const size_t line, + const uintmax_t value, + const size_t count); +void _expect_not_value( + const char* const function, const char* const parameter, + const char* const file, const int line, const uintmax_t value, + const int count); + +void _expect_float( + const char* const function, const char* const parameter, + const char* const file, const int line, const double value, + const double epsilon, const int count); +void _expect_not_float( + const char* const function, const char* const parameter, + const char* const file, const int line, const double value, + const double epsilon, const int count); + +void _expect_double(const char *const function, + const char *const parameter, + const char *const file, + const int line, + const double value, + const double epsilon, + const int count); +void _expect_not_double(const char *const function, + const char *const parameter, + const char *const file, + const int line, + const double value, + const double epsilon, + 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 CMockaValueData value); + +void _will_return(const char *const function_name, + const char *const file, + const int line, + const char *name, + const CMockaValueData value, + const int count); +void _will_set_parameter(const char *const function_name, + const char *name, + const char *const file, + const int line, + const char *type, + const CMockaValueData value, + const int count); +void _assert_true(const uintmax_t result, + const char* const expression, + const char * const file, const int line); +void _assert_false(const uintmax_t result, + const char * const expression, + const char * const file, const int line); +void _assert_return_code(const intmax_t result, + const int32_t error, + const char * const expression, + const char * const file, + const int line); +void _assert_float_equal(const float a, const float n, + const float epsilon, const char* const file, + const int line); +void _assert_float_not_equal(const float a, const float n, + const float epsilon, const char* const file, + const int line); +void _assert_double_equal(const double a, const double n, + const double epsilon, const char* const file, + const int line); +void _assert_double_not_equal(const double a, const double n, + const double epsilon, const char* const file, + const int line); +void _assert_int_equal(const intmax_t a, + const intmax_t b, + const char * const file, + const int line); +void _assert_int_not_equal(const intmax_t a, + const intmax_t b, + const char * const file, + const int line); +void _assert_uint_equal(const uintmax_t a, + const uintmax_t b, + const char * const file, + const int line); +void _assert_uint_not_equal(const uintmax_t a, + const uintmax_t b, + const char * const file, + const int line); +CMOCKA_NO_ACCESS_ATTRIBUTE +void _assert_ptr_equal_msg(const void *a, + const void *b, + const char *const file, + const int line, + const char *const msg); +CMOCKA_NO_ACCESS_ATTRIBUTE +void _assert_ptr_not_equal_msg(const void *a, + const void *b, + const char *const file, + const int line, + const char *const msg); +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_int_in_range(const intmax_t value, + const intmax_t minimum, + const intmax_t maximum, + const char* const file, + const int line); +void _assert_int_not_in_range(const intmax_t value, + const intmax_t minimum, + const intmax_t maximum, + const char *const file, + const int line); +void _assert_uint_in_range(const uintmax_t value, + const uintmax_t minimum, + const uintmax_t maximum, + const char* const file, + const int line); +void _assert_uint_not_in_range(const uintmax_t value, + const uintmax_t minimum, + const uintmax_t maximum, + const char* const file, + const int line); +void _assert_float_in_range(const double value, + const double minimum, + const double maximum, + const double epsilon, + const char* const file, + const int line); +void _assert_float_not_in_range(const double value, + const double minimum, + const double maximum, + const double epsilon, + const char* const file, + const int line); +void _assert_not_in_set( + const uintmax_t value, const uintmax_t values[], + const size_t number_of_values, const char* const file, const int line); +void _assert_int_in_set(const intmax_t value, + const intmax_t values[], + const size_t number_of_values, + const char *const file, + const int line); +void _assert_int_not_in_set(const intmax_t value, + const intmax_t values[], + const size_t number_of_values, + const char *const file, + const int line); +void _assert_uint_in_set(const uintmax_t value, + const uintmax_t values[], + const size_t number_of_values, + const char *const file, + const int line); +void _assert_uint_not_in_set(const uintmax_t value, + const uintmax_t values[], + const size_t number_of_values, + const char *const file, + const int line); +void _assert_float_in_set(const double value, + const double values[], + const size_t number_of_values, + const double epsilon, + const char *const file, + const int line); +void _assert_float_not_in_set(const double value, + const double values[], + const size_t number_of_values, + const double epsilon, + 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); + +CMOCKA_NORETURN void _fail(const char * const file, const int line); + +CMOCKA_NORETURN void _skip(const char * const file, const int line); + +CMOCKA_NORETURN void _stop(void); + +/* 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); + +/** @endcond */ + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#endif /* CMOCKA_H_ */ diff --git a/vendor/cmocka/libcmocka.a b/vendor/cmocka/libcmocka.a new file mode 100644 index 0000000000000000000000000000000000000000..bd61423a7ee66867387f5b55b2e7ea55d2954143 GIT binary patch literal 181760 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
P_7Ov> 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 literal 0 HcmV?d00001