From 63d81237fb2ab01cec453d48d4c2d6403f172a5d Mon Sep 17 00:00:00 2001 From: jakeg00dwin Date: Thu, 22 Feb 2024 23:16:50 -0800 Subject: [PATCH] A copy of the newest cmocka release 1.1.7 --- cmake/cmocka-1.1.7/.clang_complete | 2 + cmake/cmocka-1.1.7/.ycm_extra_conf.py | 109 + cmake/cmocka-1.1.7/49.patch | 1628 ++++++++ cmake/cmocka-1.1.7/AUTHORS | 3 + cmake/cmocka-1.1.7/CMakeLists.txt | 93 + cmake/cmocka-1.1.7/COPYING | 202 + cmake/cmocka-1.1.7/CPackConfig.cmake | 54 + cmake/cmocka-1.1.7/CTestConfig.cmake | 9 + cmake/cmocka-1.1.7/ChangeLog | 137 + cmake/cmocka-1.1.7/CompilerChecks.cmake | 109 + cmake/cmocka-1.1.7/ConfigureChecks.cmake | 152 + cmake/cmocka-1.1.7/DefineOptions.cmake | 5 + cmake/cmocka-1.1.7/INSTALL.md | 120 + cmake/cmocka-1.1.7/NEWS | 0 cmake/cmocka-1.1.7/README.md | 22 + .../cmake/Modules/AddCCompilerFlag.cmake | 21 + .../cmake/Modules/AddCMockaTest.cmake | 143 + .../cmake/Modules/COPYING-CMAKE-SCRIPTS | 22 + .../cmake/Modules/CheckCCompilerFlagSSP.cmake | 48 + .../cmake/Modules/DefineCMakeDefaults.cmake | 25 + .../cmake/Modules/DefineCompilerFlags.cmake | 49 + .../Modules/DefinePlatformDefaults.cmake | 21 + .../cmocka-1.1.7/cmake/Modules/FindNSIS.cmake | 54 + .../Modules/MacroEnsureOutOfSourceBuild.cmake | 17 + .../cmake/Toolchain-Debian-mips.cmake | 21 + .../cmake/Toolchain-cross-m32.cmake | 23 + .../cmocka-build-tree-settings.cmake.in | 3 + cmake/cmocka-1.1.7/cmocka.pc.cmake | 11 + cmake/cmocka-1.1.7/config.h.cmake | 173 + cmake/cmocka-1.1.7/coverity/README | 9 + .../coverity/coverity_assert_model.c | 156 + .../coverity/coverity_internal_model.c | 5 + cmake/cmocka-1.1.7/doc/CMakeLists.txt | 45 + cmake/cmocka-1.1.7/doc/mainpage.dox | 134 + cmake/cmocka-1.1.7/doc/that_style/LICENSE | 21 + cmake/cmocka-1.1.7/doc/that_style/README.md | 22 + cmake/cmocka-1.1.7/doc/that_style/header.html | 56 + cmake/cmocka-1.1.7/doc/that_style/img/doc.svg | 97 + .../doc/that_style/img/folderclosed.svg | 77 + .../doc/that_style/img/folderopen.svg | 83 + .../doc/that_style/img/mag_glass.svg | 73 + .../doc/that_style/img/nav_edge_inter.svg | 73 + .../doc/that_style/img/nav_edge_left.svg | 73 + .../doc/that_style/img/nav_edge_right.svg | 73 + .../doc/that_style/img/splitbar_handle.svg | 120 + .../doc/that_style/img/sync_off.png | Bin 0 -> 483 bytes .../doc/that_style/img/sync_on.png | Bin 0 -> 488 bytes .../doc/that_style/js/striped_bg.js | 32 + .../doc/that_style/that_style.css | 1431 +++++++ cmake/cmocka-1.1.7/example/CMakeLists.txt | 57 + cmake/cmocka-1.1.7/example/allocate_module.c | 55 + .../example/allocate_module_test.c | 53 + cmake/cmocka-1.1.7/example/assert_macro.c | 39 + cmake/cmocka-1.1.7/example/assert_macro.h | 2 + .../cmocka-1.1.7/example/assert_macro_test.c | 46 + cmake/cmocka-1.1.7/example/assert_module.c | 38 + cmake/cmocka-1.1.7/example/assert_module.h | 18 + .../cmocka-1.1.7/example/assert_module_test.c | 56 + cmake/cmocka-1.1.7/example/calculator.c | 286 ++ cmake/cmocka-1.1.7/example/calculator_test.c | 482 +++ cmake/cmocka-1.1.7/example/database.h | 37 + .../cmocka-1.1.7/example/mock/CMakeLists.txt | 5 + .../example/mock/chef_wrap/CMakeLists.txt | 20 + .../example/mock/chef_wrap/chef.c | 54 + .../example/mock/chef_wrap/chef.h | 19 + .../example/mock/chef_wrap/waiter_test_wrap.c | 176 + .../example/mock/chef_wrap/waiter_test_wrap.h | 2 + .../example/mock/uptime/CMakeLists.txt | 20 + .../example/mock/uptime/README.md | 56 + .../example/mock/uptime/proc_uptime.c | 78 + .../example/mock/uptime/proc_uptime.h | 22 + .../example/mock/uptime/test_uptime.c | 185 + .../cmocka-1.1.7/example/mock/uptime/uptime.c | 115 + cmake/cmocka-1.1.7/example/simple_test.c | 18 + cmake/cmocka-1.1.7/include/CMakeLists.txt | 19 + cmake/cmocka-1.1.7/include/cmocka.h | 2455 +++++++++++ cmake/cmocka-1.1.7/include/cmocka_pbc.h | 62 + cmake/cmocka-1.1.7/include/cmocka_private.h | 165 + .../cmocka-1.1.7/include/cmockery/cmockery.h | 1 + cmake/cmocka-1.1.7/include/cmockery/pbc.h | 1 + cmake/cmocka-1.1.7/meson.build | 60 + cmake/cmocka-1.1.7/meson_options.txt | 1 + cmake/cmocka-1.1.7/src/CMakeLists.txt | 106 + cmake/cmocka-1.1.7/src/cmocka.c | 3632 +++++++++++++++++ cmake/cmocka-1.1.7/src/cmocka.def | 56 + cmake/cmocka-1.1.7/tests/CMakeLists.txt | 267 ++ cmake/cmocka-1.1.7/tests/cmocka_test.cmake | 229 ++ cmake/cmocka-1.1.7/tests/ctest-default.cmake | 74 + cmake/cmocka-1.1.7/tests/meson.build | 30 + cmake/cmocka-1.1.7/tests/test_alloc.c | 91 + cmake/cmocka-1.1.7/tests/test_assert_macros.c | 41 + .../tests/test_assert_macros_fail.c | 43 + cmake/cmocka-1.1.7/tests/test_basics.c | 62 + cmake/cmocka-1.1.7/tests/test_cmockery.c | 32 + cmake/cmocka-1.1.7/tests/test_double_macros.c | 40 + .../tests/test_exception_handler.c | 39 + cmake/cmocka-1.1.7/tests/test_fixtures.c | 82 + cmake/cmocka-1.1.7/tests/test_float_macros.c | 40 + .../cmocka-1.1.7/tests/test_group_fixtures.c | 50 + .../tests/test_group_setup_assert.c | 37 + .../tests/test_group_setup_fail.c | 34 + cmake/cmocka-1.1.7/tests/test_groups.c | 69 + cmake/cmocka-1.1.7/tests/test_ordering.c | 112 + cmake/cmocka-1.1.7/tests/test_ordering_fail.c | 95 + cmake/cmocka-1.1.7/tests/test_returns.c | 69 + cmake/cmocka-1.1.7/tests/test_returns_fail.c | 77 + cmake/cmocka-1.1.7/tests/test_setup_fail.c | 54 + cmake/cmocka-1.1.7/tests/test_skip.c | 39 + cmake/cmocka-1.1.7/tests/test_skip_filter.c | 57 + cmake/cmocka-1.1.7/tests/test_string.c | 40 + cmake/cmocka-1.1.7/tests/test_strmatch.c | 99 + cmake/cmocka-1.1.7/tests/test_wildcard.c | 53 + 112 files changed, 16308 insertions(+) create mode 100644 cmake/cmocka-1.1.7/.clang_complete create mode 100644 cmake/cmocka-1.1.7/.ycm_extra_conf.py create mode 100644 cmake/cmocka-1.1.7/49.patch create mode 100644 cmake/cmocka-1.1.7/AUTHORS create mode 100644 cmake/cmocka-1.1.7/CMakeLists.txt create mode 100644 cmake/cmocka-1.1.7/COPYING create mode 100644 cmake/cmocka-1.1.7/CPackConfig.cmake create mode 100644 cmake/cmocka-1.1.7/CTestConfig.cmake create mode 100644 cmake/cmocka-1.1.7/ChangeLog create mode 100644 cmake/cmocka-1.1.7/CompilerChecks.cmake create mode 100644 cmake/cmocka-1.1.7/ConfigureChecks.cmake create mode 100644 cmake/cmocka-1.1.7/DefineOptions.cmake create mode 100644 cmake/cmocka-1.1.7/INSTALL.md create mode 100644 cmake/cmocka-1.1.7/NEWS create mode 100644 cmake/cmocka-1.1.7/README.md create mode 100644 cmake/cmocka-1.1.7/cmake/Modules/AddCCompilerFlag.cmake create mode 100644 cmake/cmocka-1.1.7/cmake/Modules/AddCMockaTest.cmake create mode 100644 cmake/cmocka-1.1.7/cmake/Modules/COPYING-CMAKE-SCRIPTS create mode 100644 cmake/cmocka-1.1.7/cmake/Modules/CheckCCompilerFlagSSP.cmake create mode 100644 cmake/cmocka-1.1.7/cmake/Modules/DefineCMakeDefaults.cmake create mode 100644 cmake/cmocka-1.1.7/cmake/Modules/DefineCompilerFlags.cmake create mode 100644 cmake/cmocka-1.1.7/cmake/Modules/DefinePlatformDefaults.cmake create mode 100644 cmake/cmocka-1.1.7/cmake/Modules/FindNSIS.cmake create mode 100644 cmake/cmocka-1.1.7/cmake/Modules/MacroEnsureOutOfSourceBuild.cmake create mode 100644 cmake/cmocka-1.1.7/cmake/Toolchain-Debian-mips.cmake create mode 100644 cmake/cmocka-1.1.7/cmake/Toolchain-cross-m32.cmake create mode 100644 cmake/cmocka-1.1.7/cmocka-build-tree-settings.cmake.in create mode 100644 cmake/cmocka-1.1.7/cmocka.pc.cmake create mode 100644 cmake/cmocka-1.1.7/config.h.cmake create mode 100644 cmake/cmocka-1.1.7/coverity/README create mode 100644 cmake/cmocka-1.1.7/coverity/coverity_assert_model.c create mode 100644 cmake/cmocka-1.1.7/coverity/coverity_internal_model.c create mode 100644 cmake/cmocka-1.1.7/doc/CMakeLists.txt create mode 100644 cmake/cmocka-1.1.7/doc/mainpage.dox create mode 100644 cmake/cmocka-1.1.7/doc/that_style/LICENSE create mode 100644 cmake/cmocka-1.1.7/doc/that_style/README.md create mode 100644 cmake/cmocka-1.1.7/doc/that_style/header.html create mode 100644 cmake/cmocka-1.1.7/doc/that_style/img/doc.svg create mode 100644 cmake/cmocka-1.1.7/doc/that_style/img/folderclosed.svg create mode 100644 cmake/cmocka-1.1.7/doc/that_style/img/folderopen.svg create mode 100644 cmake/cmocka-1.1.7/doc/that_style/img/mag_glass.svg create mode 100644 cmake/cmocka-1.1.7/doc/that_style/img/nav_edge_inter.svg create mode 100644 cmake/cmocka-1.1.7/doc/that_style/img/nav_edge_left.svg create mode 100644 cmake/cmocka-1.1.7/doc/that_style/img/nav_edge_right.svg create mode 100644 cmake/cmocka-1.1.7/doc/that_style/img/splitbar_handle.svg create mode 100644 cmake/cmocka-1.1.7/doc/that_style/img/sync_off.png create mode 100644 cmake/cmocka-1.1.7/doc/that_style/img/sync_on.png create mode 100644 cmake/cmocka-1.1.7/doc/that_style/js/striped_bg.js create mode 100644 cmake/cmocka-1.1.7/doc/that_style/that_style.css create mode 100644 cmake/cmocka-1.1.7/example/CMakeLists.txt create mode 100644 cmake/cmocka-1.1.7/example/allocate_module.c create mode 100644 cmake/cmocka-1.1.7/example/allocate_module_test.c create mode 100644 cmake/cmocka-1.1.7/example/assert_macro.c create mode 100644 cmake/cmocka-1.1.7/example/assert_macro.h create mode 100644 cmake/cmocka-1.1.7/example/assert_macro_test.c create mode 100644 cmake/cmocka-1.1.7/example/assert_module.c create mode 100644 cmake/cmocka-1.1.7/example/assert_module.h create mode 100644 cmake/cmocka-1.1.7/example/assert_module_test.c create mode 100644 cmake/cmocka-1.1.7/example/calculator.c create mode 100644 cmake/cmocka-1.1.7/example/calculator_test.c create mode 100644 cmake/cmocka-1.1.7/example/database.h create mode 100644 cmake/cmocka-1.1.7/example/mock/CMakeLists.txt create mode 100644 cmake/cmocka-1.1.7/example/mock/chef_wrap/CMakeLists.txt create mode 100644 cmake/cmocka-1.1.7/example/mock/chef_wrap/chef.c create mode 100644 cmake/cmocka-1.1.7/example/mock/chef_wrap/chef.h create mode 100644 cmake/cmocka-1.1.7/example/mock/chef_wrap/waiter_test_wrap.c create mode 100644 cmake/cmocka-1.1.7/example/mock/chef_wrap/waiter_test_wrap.h create mode 100644 cmake/cmocka-1.1.7/example/mock/uptime/CMakeLists.txt create mode 100644 cmake/cmocka-1.1.7/example/mock/uptime/README.md create mode 100644 cmake/cmocka-1.1.7/example/mock/uptime/proc_uptime.c create mode 100644 cmake/cmocka-1.1.7/example/mock/uptime/proc_uptime.h create mode 100644 cmake/cmocka-1.1.7/example/mock/uptime/test_uptime.c create mode 100644 cmake/cmocka-1.1.7/example/mock/uptime/uptime.c create mode 100644 cmake/cmocka-1.1.7/example/simple_test.c create mode 100644 cmake/cmocka-1.1.7/include/CMakeLists.txt create mode 100644 cmake/cmocka-1.1.7/include/cmocka.h create mode 100644 cmake/cmocka-1.1.7/include/cmocka_pbc.h create mode 100644 cmake/cmocka-1.1.7/include/cmocka_private.h create mode 100644 cmake/cmocka-1.1.7/include/cmockery/cmockery.h create mode 100644 cmake/cmocka-1.1.7/include/cmockery/pbc.h create mode 100644 cmake/cmocka-1.1.7/meson.build create mode 100644 cmake/cmocka-1.1.7/meson_options.txt create mode 100644 cmake/cmocka-1.1.7/src/CMakeLists.txt create mode 100644 cmake/cmocka-1.1.7/src/cmocka.c create mode 100644 cmake/cmocka-1.1.7/src/cmocka.def create mode 100644 cmake/cmocka-1.1.7/tests/CMakeLists.txt create mode 100644 cmake/cmocka-1.1.7/tests/cmocka_test.cmake create mode 100644 cmake/cmocka-1.1.7/tests/ctest-default.cmake create mode 100644 cmake/cmocka-1.1.7/tests/meson.build create mode 100644 cmake/cmocka-1.1.7/tests/test_alloc.c create mode 100644 cmake/cmocka-1.1.7/tests/test_assert_macros.c create mode 100644 cmake/cmocka-1.1.7/tests/test_assert_macros_fail.c create mode 100644 cmake/cmocka-1.1.7/tests/test_basics.c create mode 100644 cmake/cmocka-1.1.7/tests/test_cmockery.c create mode 100644 cmake/cmocka-1.1.7/tests/test_double_macros.c create mode 100644 cmake/cmocka-1.1.7/tests/test_exception_handler.c create mode 100644 cmake/cmocka-1.1.7/tests/test_fixtures.c create mode 100644 cmake/cmocka-1.1.7/tests/test_float_macros.c create mode 100644 cmake/cmocka-1.1.7/tests/test_group_fixtures.c create mode 100644 cmake/cmocka-1.1.7/tests/test_group_setup_assert.c create mode 100644 cmake/cmocka-1.1.7/tests/test_group_setup_fail.c create mode 100644 cmake/cmocka-1.1.7/tests/test_groups.c create mode 100644 cmake/cmocka-1.1.7/tests/test_ordering.c create mode 100644 cmake/cmocka-1.1.7/tests/test_ordering_fail.c create mode 100644 cmake/cmocka-1.1.7/tests/test_returns.c create mode 100644 cmake/cmocka-1.1.7/tests/test_returns_fail.c create mode 100644 cmake/cmocka-1.1.7/tests/test_setup_fail.c create mode 100644 cmake/cmocka-1.1.7/tests/test_skip.c create mode 100644 cmake/cmocka-1.1.7/tests/test_skip_filter.c create mode 100644 cmake/cmocka-1.1.7/tests/test_string.c create mode 100644 cmake/cmocka-1.1.7/tests/test_strmatch.c create mode 100644 cmake/cmocka-1.1.7/tests/test_wildcard.c diff --git a/cmake/cmocka-1.1.7/.clang_complete b/cmake/cmocka-1.1.7/.clang_complete new file mode 100644 index 0000000..6177904 --- /dev/null +++ b/cmake/cmocka-1.1.7/.clang_complete @@ -0,0 +1,2 @@ +-Iinclude +-Iobj diff --git a/cmake/cmocka-1.1.7/.ycm_extra_conf.py b/cmake/cmocka-1.1.7/.ycm_extra_conf.py new file mode 100644 index 0000000..8305a8b --- /dev/null +++ b/cmake/cmocka-1.1.7/.ycm_extra_conf.py @@ -0,0 +1,109 @@ +import os +import ycm_core + +flags = [ +'-Wall', +'-Wextra', +'-Werror', +'-x', 'c', +'-Iinclude', +] + +# Set this to the absolute path to the folder (NOT the file!) containing the +# compile_commands.json file to use that instead of 'flags'. See here for +# more details: http://clang.llvm.org/docs/JSONCompilationDatabase.html +# +# Most projects will NOT need to set this to anything; you can just change the +# 'flags' list of compilation flags. Notice that YCM itself uses that approach. +compilation_database_folder = 'obj' + +if os.path.exists( compilation_database_folder ): + database = ycm_core.CompilationDatabase( compilation_database_folder ) +else: + database = None + +SOURCE_EXTENSIONS = [ '.cpp', '.cxx', '.cc', '.c', '.m', '.mm' ] + +def DirectoryOfThisScript(): + return os.path.dirname( os.path.abspath( __file__ ) ) + + +def MakeRelativePathsInFlagsAbsolute( flags, working_directory ): + if not working_directory: + return list( flags ) + new_flags = [] + make_next_absolute = False + path_flags = [ '-isystem', '-I', '-iquote', '--sysroot=' ] + for flag in flags: + new_flag = flag + + if make_next_absolute: + make_next_absolute = False + if not flag.startswith( '/' ): + new_flag = os.path.join( working_directory, flag ) + + for path_flag in path_flags: + if flag == path_flag: + make_next_absolute = True + break + + if flag.startswith( path_flag ): + path = flag[ len( path_flag ): ] + new_flag = path_flag + os.path.join( working_directory, path ) + break + + if new_flag: + new_flags.append( new_flag ) + return new_flags + + +def IsHeaderFile( filename ): + extension = os.path.splitext( filename )[ 1 ] + return extension in [ '.h', '.hxx', '.hpp', '.hh' ] + + +def GetCompilationInfoForFile( filename ): + # The compilation_commands.json file generated by CMake does not have entries + # for header files. So we do our best by asking the db for flags for a + # corresponding source file, if any. If one exists, the flags for that file + # should be good enough. + if IsHeaderFile( filename ): + basename = os.path.splitext( filename )[ 0 ] + for extension in SOURCE_EXTENSIONS: + replacement_file = basename + extension + if os.path.exists( replacement_file ): + compilation_info = database.GetCompilationInfoForFile( + replacement_file ) + if compilation_info.compiler_flags_: + return compilation_info + return None + return database.GetCompilationInfoForFile( filename ) + + +def FlagsForFile( filename, **kwargs ): + if database: + # Bear in mind that compilation_info.compiler_flags_ does NOT return a + # python list, but a "list-like" StringVec object + compilation_info = GetCompilationInfoForFile( filename ) + if not compilation_info: + return None + + final_flags = MakeRelativePathsInFlagsAbsolute( + compilation_info.compiler_flags_, + compilation_info.compiler_working_dir_ ) + + # NOTE: This is just for YouCompleteMe; it's highly likely that your project + # does NOT need to remove the stdlib flag. DO NOT USE THIS IN YOUR + # ycm_extra_conf IF YOU'RE NOT 100% SURE YOU NEED IT. + try: + final_flags.remove( '-stdlib=libc++' ) + except ValueError: + pass + else: + relative_to = DirectoryOfThisScript() + final_flags = MakeRelativePathsInFlagsAbsolute( flags, relative_to ) + + return { + 'flags': final_flags, + 'do_cache': True + } diff --git a/cmake/cmocka-1.1.7/49.patch b/cmake/cmocka-1.1.7/49.patch new file mode 100644 index 0000000..4b83fc4 --- /dev/null +++ b/cmake/cmocka-1.1.7/49.patch @@ -0,0 +1,1628 @@ +From 6a99bd773e986a615272ed0611d4fc7636b01a03 Mon Sep 17 00:00:00 2001 +From: maxime +Date: Tue, 9 Aug 2022 16:37:34 +0900 +Subject: [PATCH 1/8] Fixed warning when compiling on Windows: warning C4996: + 'strdup': The POSIX name for this item is deprecated. Instead, use the ISO + C++ conformant name: _strdup. See online help for details. + +--- + include/cmocka_private.h | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/include/cmocka_private.h b/include/cmocka_private.h +index 4d3ff30..7ee4a76 100644 +--- a/include/cmocka_private.h ++++ b/include/cmocka_private.h +@@ -40,6 +40,7 @@ + # define strcasecmp _stricmp + # define strncasecmp _strnicmp + # define strtok_r strtok_s ++# define strdup _strdup + + # if defined(HAVE__SNPRINTF_S) + # undef snprintf +-- +GitLab + + +From 7f2705e48bcde685189764303246601c13d66718 Mon Sep 17 00:00:00 2001 +From: maxime +Date: Tue, 9 Aug 2022 16:40:08 +0900 +Subject: [PATCH 2/8] Improve the implementation of the TAP output by printing + the message, severity, data, etc. in a YAML diagnostics section, as specified + by the TAP14 specification. + +--- + src/cmocka.c | 66 +++++++++++++++++++++++++++++----------------------- + 1 file changed, 37 insertions(+), 29 deletions(-) + +diff --git a/src/cmocka.c b/src/cmocka.c +index 2518590..1ab88fe 100644 +--- a/src/cmocka.c ++++ b/src/cmocka.c +@@ -2725,7 +2725,7 @@ static void cmprintf_group_start_tap(const size_t num_tests) + { + static bool version_printed = false; + if (!version_printed) { +- print_message("TAP version 13\n"); ++ print_message("TAP version 14\n"); + version_printed = true; + } + +@@ -2749,6 +2749,8 @@ static void cmprintf_tap(enum cm_printf_type type, + const char *test_name, + const char *error_message) + { ++ int print_error_message = 0; ++ + switch (type) { + case PRINTF_TEST_START: + break; +@@ -2756,42 +2758,48 @@ static void cmprintf_tap(enum cm_printf_type type, + print_message("ok %u - %s\n", (unsigned)test_number, test_name); + break; + case PRINTF_TEST_FAILURE: ++ case PRINTF_TEST_ERROR: + print_message("not ok %u - %s\n", (unsigned)test_number, test_name); +- if (error_message != NULL) { +- char *msg; +- char *p; ++ print_error_message = 1; ++ break; ++ case PRINTF_TEST_SKIPPED: ++ print_message("ok %u - %s # SKIP\n", (unsigned)test_number, test_name); ++ break; ++ } + +- msg = strdup(error_message); +- if (msg == NULL) { +- return; +- } +- p = msg; ++ if ((print_error_message == 1) && (error_message != NULL)) { ++ char *msg; ++ char *p; ++ const char *indent = ""; + +- while (p[0] != '\0') { +- char *q = p; ++ msg = strdup(error_message); ++ if (msg == NULL) { ++ return; ++ } ++ p = msg; + +- p = strchr(q, '\n'); +- if (p != NULL) { +- p[0] = '\0'; +- } ++ print_message(" ---\n"); + +- print_message("# %s\n", q); ++ print_message(" message: \""); ++ while (p[0] != '\0') { ++ char *q = p; + +- if (p == NULL) { +- break; +- } +- p++; ++ p = strchr(q, '\n'); ++ if (p != NULL) { ++ p[0] = '\0'; ++ print_message("%s%s\\n\\\n", indent, q); ++ } else { ++ print_message("%s%s\"\n", indent, q); ++ break; + } +- libc_free(msg); ++ p++; ++ indent = " "; + } +- break; +- case PRINTF_TEST_SKIPPED: +- print_message("ok %u # SKIP %s\n", (unsigned)test_number, test_name); +- break; +- case PRINTF_TEST_ERROR: +- print_message("not ok %u - %s %s\n", +- (unsigned)test_number, test_name, error_message); +- break; ++ libc_free(msg); ++ ++ print_message(" severity: %s\n", (type == PRINTF_TEST_FAILURE) ? "fail" : "error"); ++ ++ print_message(" ...\n"); + } + } + +-- +GitLab + + +From 9874464dc7858475ace081dc748b0f399213b473 Mon Sep 17 00:00:00 2001 +From: maxime +Date: Tue, 9 Aug 2022 16:44:18 +0900 +Subject: [PATCH 3/8] Added functions so that custom data can be attached to + the current test. I'm open to a different implementation, but I basically + needed a mechanism that is flexible enough to print any kind of data whether + a test passes or fails. For example, on the app using cmocka, I wanted to be + able to redefine the assert_* macros to automatically include data such as + 'expected', 'got' when a test fails. Currently the data are only used by the + TAP output. + +--- + include/cmocka.h | 51 +++++++++++++ + src/cmocka.c | 185 ++++++++++++++++++++++++++++++++++++++++++++--- + src/cmocka.def | 6 ++ + 3 files changed, 231 insertions(+), 11 deletions(-) + +diff --git a/include/cmocka.h b/include/cmocka.h +index 1897240..18f0da3 100644 +--- a/include/cmocka.h ++++ b/include/cmocka.h +@@ -1742,6 +1742,45 @@ void stop(void); + #define stop() _stop() + #endif + ++#ifdef DOXYGEN ++/** ++ * @brief Initialize a list of data for the current test. ++ */ ++int attach_test_data(size_t size); ++ ++/** ++ * @brief Expand the list of data for the current test. ++ */ ++int extend_test_data(size_t size); ++ ++/** ++ * @brief Append Boolean data for the current test. ++ */ ++void append_test_data_boolean(const char * const name, int value); ++ ++/** ++ * @brief Append Integer data for the current test. ++ */ ++void append_test_data_integer(const char * const name, uintmax_t value); ++ ++/** ++ * @brief Append Pointer data for the current test. ++ */ ++void append_test_data_pointer(const char * const name, void * const value); ++ ++/** ++ * @brief Append String data for the current test. ++ */ ++void append_test_data_string(const char * const name, const char * value); ++#else ++#define attach_test_data(s) _attach_test_data(s, __FILE__, __LINE__) ++#define extend_test_data(s) _extend_test_data(s, __FILE__, __LINE__) ++#define append_test_data_boolean(n, v) _append_test_data_boolean(n, v, __FILE__, __LINE__) ++#define append_test_data_integer(n, v) _append_test_data_integer(n, v, __FILE__, __LINE__) ++#define append_test_data_pointer(n, v) _append_test_data_pointer(n, v, __FILE__, __LINE__) ++#define append_test_data_string(n, v) _append_test_data_string(n, v, __FILE__, __LINE__) ++#endif ++ + #ifdef DOXYGEN + /** + * @brief Forces the test to fail immediately and quit, printing the reason. +@@ -2436,6 +2475,18 @@ CMOCKA_NORETURN void _skip(const char * const file, const int line); + + CMOCKA_NORETURN void _stop(void); + ++int _attach_test_data(size_t size, const char * const file, const int line); ++ ++int _extend_test_data(size_t size, const char * const file, const int line); ++ ++void _append_test_data_boolean(const char * const name, int value, const char * const file, const int line); ++ ++void _append_test_data_integer(const char * const name, uintmax_t value, const char * const file, const int line); ++ ++void _append_test_data_pointer(const char * const name, void * const value, const char * const file, const int line); ++ ++void _append_test_data_string(const char * const name, const char * value, const char * const file, const int line); ++ + /* Test runner */ + int _cmocka_run_group_tests(const char *group_name, + const struct CMUnitTest * const tests, +diff --git a/src/cmocka.c b/src/cmocka.c +index 1ab88fe..8bc13d8 100644 +--- a/src/cmocka.c ++++ b/src/cmocka.c +@@ -201,6 +201,19 @@ typedef struct CheckMemoryData { + size_t size; + } CheckMemoryData; + ++typedef enum CMDataType { ++ DATA_TYPE_BOOLEAN, ++ DATA_TYPE_INTEGER, ++ DATA_TYPE_POINTER, ++ DATA_TYPE_STRING, ++} CMDataType; ++ ++typedef struct CMData { ++ char *name; ++ void *value; ++ CMDataType type; ++} CMData; ++ + static ListNode* list_initialize(ListNode * const node); + static ListNode* list_add(ListNode * const head, ListNode *new_node); + static ListNode* list_add_value(ListNode * const head, const void *value, +@@ -270,6 +283,11 @@ const char *global_last_failed_assert = NULL; + static int global_skip_test; + static int global_stop_test; + ++/* Keeps an array of CMData to be printed for TAP output. */ ++static CMOCKA_THREAD CMData** global_test_data = NULL; ++static CMOCKA_THREAD size_t global_test_data_max_size; ++static CMOCKA_THREAD size_t global_test_data_len; ++ + /* Keeps a map of the values that functions will have to return to provide */ + /* mocked interfaces. */ + static CMOCKA_THREAD ListNode global_function_result_map_head; +@@ -410,6 +428,107 @@ void _stop(void) + exit(EXIT_FAILURE); + } + ++static void free_test_data(void) { ++ if (global_test_data) { ++ CMData* d; ++ size_t i; ++ for (i = 0; i < global_test_data_len; i++) { ++ d = global_test_data[i]; ++ if (d) { ++ free(d->name); ++ switch (d->type) { ++ case DATA_TYPE_STRING: ++ free(d->value); ++ default: ++ break; ++ } ++ free(d); ++ } ++ } ++ free(global_test_data); ++ ++ global_test_data = NULL; ++ global_test_data_max_size = 0; ++ global_test_data_len = 0; ++ } ++} ++ ++int _attach_test_data(size_t size, const char * const file, const int line) { ++ if (size > 0) { ++ free_test_data(); ++ global_test_data = (CMData**)malloc(size * sizeof(CMData*)); ++ if (!global_test_data) { ++ cmocka_print_error(SOURCE_LOCATION_FORMAT ": error: Failed to initialize data list.\n", file, line); ++ return 1; ++ } else { ++ global_test_data_max_size = size; ++ global_test_data_len = 0; ++ } ++ } ++ return 0; ++} ++ ++int _extend_test_data(size_t size, const char * const file, const int line) { ++ if (size > 0) { ++ CMData** tmp; ++ size_t tmp_size = global_test_data_max_size + size; ++ ++ tmp = (CMData**)realloc(global_test_data, tmp_size * sizeof(CMData*)); ++ if (!tmp) { ++ cmocka_print_error(SOURCE_LOCATION_FORMAT ": error: Failed to expand data list.\n", file, line); ++ return 1; ++ } else { ++ global_test_data = tmp; ++ global_test_data_max_size = tmp_size; ++ } ++ } ++ return 0; ++} ++ ++static void _append_test_data(const char * const name, void * const value, CMDataType type, const char * const file, const int line) { ++ CMData* d; ++ ++ if (!global_test_data) { ++ if (_attach_test_data(10, file, line) == 1) { ++ return; ++ } ++ } else if (global_test_data_len + 1 > global_test_data_max_size) { ++ if (_extend_test_data(10, file, line) == 1) { ++ return; ++ } ++ } ++ ++ d = (CMData*)malloc(sizeof(CMData)); ++ if (d) { ++ d->name = strdup(name); ++ switch (type) { ++ case DATA_TYPE_STRING: ++ d->value = strdup(value); ++ break; ++ default: ++ d->value = value; ++ } ++ d->type = type; ++ global_test_data[global_test_data_len++] = d; ++ } ++} ++ ++void _append_test_data_boolean(const char * const name, int value, const char * const file, const int line) { ++ _append_test_data(name, cast_uintmax_type_to_pointer(void * const, value), DATA_TYPE_BOOLEAN, file, line); ++} ++ ++void _append_test_data_integer(const char * const name, uintmax_t value, const char * const file, const int line) { ++ _append_test_data(name, cast_uintmax_type_to_pointer(void * const, value), DATA_TYPE_INTEGER, file, line); ++} ++ ++void _append_test_data_pointer(const char * const name, void * const value, const char * const file, const int line) { ++ _append_test_data(name, value, DATA_TYPE_POINTER, file, line); ++} ++ ++void _append_test_data_string(const char * const name, const char * value, const char * const file, const int line) { ++ _append_test_data(name, (void * const)value, DATA_TYPE_STRING, file, line); ++} ++ + /* Initialize a SourceLocation structure. */ + static void initialize_source_location(SourceLocation * const location) { + assert_non_null(location); +@@ -2747,8 +2866,12 @@ static void cmprintf_group_finish_tap(const char *group_name, + static void cmprintf_tap(enum cm_printf_type type, + size_t test_number, + const char *test_name, +- const char *error_message) ++ const char *error_message, ++ CMData** test_data) + { ++ CMData* d; ++ size_t i; ++ int diagnostics_opened = 0; + int print_error_message = 0; + + switch (type) { +@@ -2779,6 +2902,7 @@ static void cmprintf_tap(enum cm_printf_type type, + p = msg; + + print_message(" ---\n"); ++ diagnostics_opened = 1; + + print_message(" message: \""); + while (p[0] != '\0') { +@@ -2798,7 +2922,39 @@ static void cmprintf_tap(enum cm_printf_type type, + libc_free(msg); + + print_message(" severity: %s\n", (type == PRINTF_TEST_FAILURE) ? "fail" : "error"); ++ } ++ ++ if (test_data) { ++ if (diagnostics_opened == 0) { ++ print_message(" ---\n"); ++ diagnostics_opened = 1; ++ } ++ print_message(" data:\n"); ++ ++ for (i = 0; i < global_test_data_len; i++) { ++ d = test_data[i]; ++ switch (d->type) { ++ case DATA_TYPE_BOOLEAN: ++ print_message(" %s: %s\n", ++ d->name, (int)cast_ptr_to_uintmax_type(d->value) != (int)0 ? "true" : "false"); ++ break; ++ case DATA_TYPE_INTEGER: ++ print_message(" %s: %#jx\n", ++ d->name, cast_ptr_to_uintmax_type(d->value)); ++ break; ++ case DATA_TYPE_POINTER: ++ print_message(" %s: %p\n", ++ d->name, d->value); ++ break; ++ case DATA_TYPE_STRING: ++ print_message(" %s: '%s'\n", ++ d->name, (const char *)(d->value)); ++ break; ++ } ++ } ++ } + ++ if (diagnostics_opened == 1) { + print_message(" ...\n"); + } + } +@@ -2886,7 +3042,8 @@ static void cmprintf_group_finish(const char *group_name, + static void cmprintf(enum cm_printf_type type, + size_t test_number, + const char *test_name, +- const char *error_message) ++ const char *error_message, ++ CMData** test_data) + { + uint32_t output; + +@@ -2899,7 +3056,7 @@ static void cmprintf(enum cm_printf_type type, + cmprintf_subunit(type, test_name, error_message); + } + if (output & CM_OUTPUT_TAP) { +- cmprintf_tap(type, test_number, test_name, error_message); ++ cmprintf_tap(type, test_number, test_name, error_message, test_data); + } + } + +@@ -3253,7 +3410,7 @@ int _cmocka_run_group_tests(const char *group_name, + struct CMUnitTestState *cmtest = &cm_tests[i]; + size_t test_number = i + 1; + +- cmprintf(PRINTF_TEST_START, test_number, cmtest->test->name, NULL); ++ cmprintf(PRINTF_TEST_START, test_number, cmtest->test->name, NULL, NULL); + + if (group_state != NULL) { + cmtest->state = group_state; +@@ -3270,28 +3427,32 @@ int _cmocka_run_group_tests(const char *group_name, + cmprintf(PRINTF_TEST_SUCCESS, + test_number, + cmtest->test->name, +- cmtest->error_message); ++ cmtest->error_message, ++ global_test_data); + total_passed++; + break; + case CM_TEST_SKIPPED: + cmprintf(PRINTF_TEST_SKIPPED, + test_number, + cmtest->test->name, +- cmtest->error_message); ++ cmtest->error_message, ++ global_test_data); + total_skipped++; + break; + case CM_TEST_FAILED: + cmprintf(PRINTF_TEST_FAILURE, + test_number, + cmtest->test->name, +- cmtest->error_message); ++ cmtest->error_message, ++ global_test_data); + total_failed++; + break; + default: + cmprintf(PRINTF_TEST_ERROR, + test_number, + cmtest->test->name, +- "Internal cmocka error"); ++ "Internal cmocka error", ++ NULL); + total_errors++; + break; + } +@@ -3305,9 +3466,11 @@ int _cmocka_run_group_tests(const char *group_name, + cmprintf(PRINTF_TEST_ERROR, + test_number, + cmtest->test->name, +- err_msg); ++ err_msg, ++ NULL); + total_errors++; + } ++ free_test_data(); + } + } else { + if (cm_error_message != NULL) { +@@ -3316,7 +3479,7 @@ int _cmocka_run_group_tests(const char *group_name, + cm_error_message = NULL; + } + cmprintf(PRINTF_TEST_ERROR, 0, +- group_name, "[ FAILED ] GROUP SETUP"); ++ group_name, "[ FAILED ] GROUP SETUP", NULL); + total_errors++; + } + +@@ -3334,7 +3497,7 @@ int _cmocka_run_group_tests(const char *group_name, + cm_error_message = NULL; + } + cmprintf(PRINTF_TEST_ERROR, 0, +- group_name, "[ FAILED ] GROUP TEARDOWN"); ++ group_name, "[ FAILED ] GROUP TEARDOWN", NULL); + } + } + +diff --git a/src/cmocka.def b/src/cmocka.def +index f56b9a5..edeeffa 100644 +--- a/src/cmocka.def ++++ b/src/cmocka.def +@@ -1,5 +1,9 @@ + LIBRARY cmocka + EXPORTS ++ _append_test_data_boolean ++ _append_test_data_integer ++ _append_test_data_pointer ++ _append_test_data_string + _assert_double_equal + _assert_double_not_equal + _assert_float_equal +@@ -20,6 +24,7 @@ EXPORTS + _assert_uint_equal + _assert_uint_in_range + _assert_uint_not_equal ++ _attach_test_data + _check_expected + _cmocka_run_group_tests + _expect_any +@@ -35,6 +40,7 @@ EXPORTS + _expect_not_value + _expect_string + _expect_value ++ _extend_test_data + _fail + _function_called + _mock +-- +GitLab + + +From 3565734f7029a8a0c1600b292e641ec90e63ae17 Mon Sep 17 00:00:00 2001 +From: maxime +Date: Tue, 9 Aug 2022 16:47:28 +0900 +Subject: [PATCH 4/8] Added skip_with_note() function to provide an explanation + about why the test is to be skipped. + +--- + include/cmocka.h | 13 ++++++++++++ + src/cmocka.c | 55 ++++++++++++++++++++++++++++++++++++++++-------- + src/cmocka.def | 1 + + 3 files changed, 60 insertions(+), 9 deletions(-) + +diff --git a/include/cmocka.h b/include/cmocka.h +index 18f0da3..827e7a0 100644 +--- a/include/cmocka.h ++++ b/include/cmocka.h +@@ -1728,6 +1728,17 @@ void skip(void); + #define skip() _skip(__FILE__, __LINE__) + #endif + ++#ifdef DOXYGEN ++/** ++ * @brief Forces the test to not be executed, but marked as skipped. ++ * ++ * @param[in] note Explanation about why the test is skipped. ++ */ ++void skip_with_note(const char * const note, void); ++#else ++#define skip_with_note(note) _skip_with_note(note, __FILE__, __LINE__) ++#endif ++ + #ifdef DOXYGEN + /** + * @brief Forces the test to be stopped immediately. +@@ -2473,6 +2484,8 @@ 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 _skip_with_note(const char * const note, const char * const file, const int line); ++ + CMOCKA_NORETURN void _stop(void); + + int _attach_test_data(size_t size, const char * const file, const int line); +diff --git a/src/cmocka.c b/src/cmocka.c +index 8bc13d8..9c8c340 100644 +--- a/src/cmocka.c ++++ b/src/cmocka.c +@@ -281,6 +281,7 @@ jmp_buf global_expect_assert_env; + int global_expecting_assert = 0; + const char *global_last_failed_assert = NULL; + static int global_skip_test; ++static const char * global_skip_test_note = NULL; + static int global_stop_test; + + /* Keeps an array of CMData to be printed for TAP output. */ +@@ -385,6 +386,7 @@ struct CMUnitTestState { + const char *error_message; /* The error messages by the test */ + enum CMUnitTestStatus status; /* PASSED, FAILED, ABORT ... */ + double runtime; /* Time calculations */ ++ const char *skip_note; /* Explanation when the test is skipped */ + }; + + /* Exit the currently executing test. */ +@@ -419,6 +421,17 @@ void _skip(const char * const file, const int line) + exit(EXIT_FAILURE); + } + ++void _skip_with_note(const char * const note, const char * const file, const int line) ++{ ++ cmocka_print_error(SOURCE_LOCATION_FORMAT ": Skipped (%s)!\n", file, line, note); ++ global_skip_test = 1; ++ global_skip_test_note = note; ++ exit_test(true); ++ ++ /* Unreachable */ ++ exit(EXIT_FAILURE); ++} ++ + void _stop(void) + { + global_stop_test = 1; +@@ -2738,7 +2751,12 @@ static void cmprintf_group_finish_xml(const char *group_name, + } + break; + case CM_TEST_SKIPPED: +- fprintf(fp, " \n"); ++ if (cmtest->skip_note) { ++ fprintf(fp, " \n", ++ cmtest->skip_note); ++ } else { ++ fprintf(fp, " \n"); ++ } + break; + + case CM_TEST_PASSED: +@@ -2813,7 +2831,8 @@ static void cmprintf_group_finish_standard(const char *group_name, + + static void cmprintf_standard(enum cm_printf_type type, + const char *test_name, +- const char *error_message) ++ const char *error_message, ++ const char *skip_note) + { + switch (type) { + case PRINTF_TEST_START: +@@ -2829,7 +2848,11 @@ static void cmprintf_standard(enum cm_printf_type type, + print_message("[ FAILED ] %s\n", test_name); + break; + case PRINTF_TEST_SKIPPED: +- print_message("[ SKIPPED ] %s\n", test_name); ++ if (skip_note) { ++ print_message("[ SKIPPED ] %s - %s\n", test_name, skip_note); ++ } else { ++ print_message("[ SKIPPED ] %s\n", test_name); ++ } + break; + case PRINTF_TEST_ERROR: + if (error_message != NULL) { +@@ -2867,6 +2890,7 @@ static void cmprintf_tap(enum cm_printf_type type, + size_t test_number, + const char *test_name, + const char *error_message, ++ const char *skip_note, + CMData** test_data) + { + CMData* d; +@@ -2886,7 +2910,11 @@ static void cmprintf_tap(enum cm_printf_type type, + print_error_message = 1; + break; + case PRINTF_TEST_SKIPPED: +- print_message("ok %u - %s # SKIP\n", (unsigned)test_number, test_name); ++ if (skip_note) { ++ print_message("ok %u - %s # SKIP %s\n", (unsigned)test_number, test_name, skip_note); ++ } else { ++ print_message("ok %u - %s # SKIP\n", (unsigned)test_number, test_name); ++ } + break; + } + +@@ -2977,6 +3005,7 @@ static void cmprintf_subunit(enum cm_printf_type type, + } + break; + case PRINTF_TEST_SKIPPED: ++ /* TODO: should we print the explanation in DETAILS region as explained here: https://github.com/testing-cabal/subunit */ + print_message("skip: %s\n", test_name); + break; + case PRINTF_TEST_ERROR: +@@ -3043,6 +3072,7 @@ static void cmprintf(enum cm_printf_type type, + size_t test_number, + const char *test_name, + const char *error_message, ++ const char *skip_note, + CMData** test_data) + { + uint32_t output; +@@ -3050,13 +3080,13 @@ static void cmprintf(enum cm_printf_type type, + output = cm_get_output(); + + if (output & CM_OUTPUT_STANDARD) { +- cmprintf_standard(type, test_name, error_message); ++ cmprintf_standard(type, test_name, error_message, skip_note); + } + if (output & CM_OUTPUT_SUBUNIT) { + cmprintf_subunit(type, test_name, error_message); + } + if (output & CM_OUTPUT_TAP) { +- cmprintf_tap(type, test_number, test_name, error_message, test_data); ++ cmprintf_tap(type, test_number, test_name, error_message, skip_note, test_data); + } + } + +@@ -3298,7 +3328,9 @@ static int cmocka_run_one_tests(struct CMUnitTestState *test_state) + } else { + if (global_skip_test) { + test_state->status = CM_TEST_SKIPPED; ++ test_state->skip_note = global_skip_test_note; + global_skip_test = 0; /* Do not skip the next test */ ++ global_skip_test_note = NULL; + } else { + test_state->status = CM_TEST_FAILED; + } +@@ -3410,7 +3442,7 @@ int _cmocka_run_group_tests(const char *group_name, + struct CMUnitTestState *cmtest = &cm_tests[i]; + size_t test_number = i + 1; + +- cmprintf(PRINTF_TEST_START, test_number, cmtest->test->name, NULL, NULL); ++ cmprintf(PRINTF_TEST_START, test_number, cmtest->test->name, NULL, NULL, NULL); + + if (group_state != NULL) { + cmtest->state = group_state; +@@ -3428,6 +3460,7 @@ int _cmocka_run_group_tests(const char *group_name, + test_number, + cmtest->test->name, + cmtest->error_message, ++ cmtest->skip_note, + global_test_data); + total_passed++; + break; +@@ -3436,6 +3469,7 @@ int _cmocka_run_group_tests(const char *group_name, + test_number, + cmtest->test->name, + cmtest->error_message, ++ cmtest->skip_note, + global_test_data); + total_skipped++; + break; +@@ -3444,6 +3478,7 @@ int _cmocka_run_group_tests(const char *group_name, + test_number, + cmtest->test->name, + cmtest->error_message, ++ cmtest->skip_note, + global_test_data); + total_failed++; + break; +@@ -3452,6 +3487,7 @@ int _cmocka_run_group_tests(const char *group_name, + test_number, + cmtest->test->name, + "Internal cmocka error", ++ NULL, + NULL); + total_errors++; + break; +@@ -3467,6 +3503,7 @@ int _cmocka_run_group_tests(const char *group_name, + test_number, + cmtest->test->name, + err_msg, ++ NULL, + NULL); + total_errors++; + } +@@ -3479,7 +3516,7 @@ int _cmocka_run_group_tests(const char *group_name, + cm_error_message = NULL; + } + cmprintf(PRINTF_TEST_ERROR, 0, +- group_name, "[ FAILED ] GROUP SETUP", NULL); ++ group_name, "[ FAILED ] GROUP SETUP", NULL, NULL); + total_errors++; + } + +@@ -3497,7 +3534,7 @@ int _cmocka_run_group_tests(const char *group_name, + cm_error_message = NULL; + } + cmprintf(PRINTF_TEST_ERROR, 0, +- group_name, "[ FAILED ] GROUP TEARDOWN", NULL); ++ group_name, "[ FAILED ] GROUP TEARDOWN", NULL, NULL); + } + } + +diff --git a/src/cmocka.def b/src/cmocka.def +index edeeffa..3b29014 100644 +--- a/src/cmocka.def ++++ b/src/cmocka.def +@@ -45,6 +45,7 @@ EXPORTS + _function_called + _mock + _skip ++ _skip_with_note + _stop + _test_calloc + _test_free +-- +GitLab + + +From e28858ac8ddab8237497db6330b51d0e0500a6ef Mon Sep 17 00:00:00 2001 +From: maxime +Date: Tue, 9 Aug 2022 16:50:06 +0900 +Subject: [PATCH 5/8] Added support for TODO tests, which represent features to + be implemented. According to the TAP specification, these tests must not be + treated as a test failure if they fail (see + https://testanything.org/tap-version-14-specification.html). + +--- + include/cmocka.h | 24 +++++++ + src/cmocka.c | 175 +++++++++++++++++++++++++++++++++++++++++++---- + src/cmocka.def | 2 + + 3 files changed, 189 insertions(+), 12 deletions(-) + +diff --git a/include/cmocka.h b/include/cmocka.h +index 827e7a0..10138d7 100644 +--- a/include/cmocka.h ++++ b/include/cmocka.h +@@ -1753,6 +1753,26 @@ void stop(void); + #define stop() _stop() + #endif + ++#ifdef DOXYGEN ++/** ++ * @brief Mark the test as TODO, for a feature that is not fully implemented yet. ++ */ ++void todo(void); ++#else ++#define todo() _todo(__FILE__, __LINE__) ++#endif ++ ++#ifdef DOXYGEN ++/** ++ * @brief Mark the test as TODO, for a feature that is not fully implemented yet. ++ * ++ * @param[in] note Explanation about why the test is marked as TODO. ++ */ ++void todo_with_note(const char * const note, void); ++#else ++#define todo_with_note(note) _todo_with_note(note, __FILE__, __LINE__) ++#endif ++ + #ifdef DOXYGEN + /** + * @brief Initialize a list of data for the current test. +@@ -2488,6 +2508,10 @@ CMOCKA_NORETURN void _skip_with_note(const char * const note, const char * const + + CMOCKA_NORETURN void _stop(void); + ++void _todo(const char * const file, const int line); ++ ++void _todo_with_note(const char * const note, const char * const file, const int line); ++ + int _attach_test_data(size_t size, const char * const file, const int line); + + int _extend_test_data(size_t size, const char * const file, const int line); +diff --git a/src/cmocka.c b/src/cmocka.c +index 9c8c340..978a477 100644 +--- a/src/cmocka.c ++++ b/src/cmocka.c +@@ -283,6 +283,8 @@ const char *global_last_failed_assert = NULL; + static int global_skip_test; + static const char * global_skip_test_note = NULL; + static int global_stop_test; ++static int global_todo_test; ++static const char * global_todo_test_note = NULL; + + /* Keeps an array of CMData to be printed for TAP output. */ + static CMOCKA_THREAD CMData** global_test_data = NULL; +@@ -377,6 +379,8 @@ enum CMUnitTestStatus { + CM_TEST_FAILED, + CM_TEST_ERROR, + CM_TEST_SKIPPED, ++ CM_TEST_TODO_OK, ++ CM_TEST_TODO, + }; + + struct CMUnitTestState { +@@ -387,6 +391,7 @@ struct CMUnitTestState { + enum CMUnitTestStatus status; /* PASSED, FAILED, ABORT ... */ + double runtime; /* Time calculations */ + const char *skip_note; /* Explanation when the test is skipped */ ++ const char *todo_note; /* Explanation when the test is marked as TODO */ + }; + + /* Exit the currently executing test. */ +@@ -441,6 +446,17 @@ void _stop(void) + exit(EXIT_FAILURE); + } + ++void _todo(const char * const file, const int line) ++{ ++ global_todo_test = 1; ++} ++ ++void _todo_with_note(const char * const note, const char * const file, const int line) ++{ ++ global_todo_test = 1; ++ global_todo_test_note = note; ++} ++ + static void free_test_data(void) { + if (global_test_data) { + CMData* d; +@@ -2661,6 +2677,8 @@ enum cm_printf_type { + PRINTF_TEST_FAILURE, + PRINTF_TEST_ERROR, + PRINTF_TEST_SKIPPED, ++ PRINTF_TEST_TODO_OK, ++ PRINTF_TEST_TODO, + }; + + static int xml_printed; +@@ -2671,6 +2689,8 @@ static void cmprintf_group_finish_xml(const char *group_name, + size_t total_failed, + size_t total_errors, + size_t total_skipped, ++ size_t total_todo_ok, ++ size_t total_todo, + double total_runtime, + struct CMUnitTestState *cm_tests) + { +@@ -2726,13 +2746,15 @@ static void cmprintf_group_finish_xml(const char *group_name, + + fprintf(fp, "\n"); + fprintf(fp, " \n", ++ "tests=\"%u\" failures=\"%u\" errors=\"%u\" skipped=\"%u\" todo_ok=\"%u\" todo=\"%u\" >\n", + group_name, + total_runtime, /* seconds */ + (unsigned)total_executed, + (unsigned)total_failed, + (unsigned)total_errors, +- (unsigned)total_skipped); ++ (unsigned)total_skipped, ++ (unsigned)total_todo_ok, ++ (unsigned)total_todo); + + for (i = 0; i < total_executed; i++) { + struct CMUnitTestState *cmtest = &cm_tests[i]; +@@ -2741,6 +2763,18 @@ static void cmprintf_group_finish_xml(const char *group_name, + cmtest->test->name, cmtest->runtime); + + switch (cmtest->status) { ++ case CM_TEST_TODO_OK: ++ case CM_TEST_TODO: ++ if (cmtest->todo_note) { ++ fprintf(fp, " \n", ++ cmtest->todo_note); ++ } else { ++ fprintf(fp, " \n"); ++ } ++ if (cmtest->status == CM_TEST_TODO_OK) { ++ break; ++ } ++ // fall through + case CM_TEST_ERROR: + case CM_TEST_FAILED: + if (cmtest->error_message != NULL) { +@@ -2789,6 +2823,8 @@ static void cmprintf_group_finish_standard(const char *group_name, + size_t total_failed, + size_t total_errors, + size_t total_skipped, ++ size_t total_todo_ok, ++ size_t total_todo, + struct CMUnitTestState *cm_tests) + { + size_t i; +@@ -2799,6 +2835,34 @@ static void cmprintf_group_finish_standard(const char *group_name, + print_error("[ PASSED ] %u test(s).\n", + (unsigned)(total_passed)); + ++ if (total_todo_ok) { ++ print_message("[ TODO OK ] %s: %zu test(s), listed below:\n", ++ group_name, ++ total_todo_ok); ++ for (i = 0; i < total_executed; i++) { ++ struct CMUnitTestState *cmtest = &cm_tests[i]; ++ ++ if (cmtest->status == CM_TEST_TODO_OK) { ++ print_message("[ TODO OK ] %s\n", cmtest->test->name); ++ } ++ } ++ print_message("\n %u TODO TEST(S) PASSED - Consider promoting to normal test(s).\n", (unsigned)(total_todo_ok)); ++ } ++ ++ if (total_todo) { ++ print_message("[ TODO ] %s: %zu test(s), listed below:\n", ++ group_name, ++ total_todo); ++ for (i = 0; i < total_executed; i++) { ++ struct CMUnitTestState *cmtest = &cm_tests[i]; ++ ++ if (cmtest->status == CM_TEST_TODO) { ++ print_message("[ TODO ] %s\n", cmtest->test->name); ++ } ++ } ++ print_message("\n %u TODO TEST(S)\n", (unsigned)(total_todo)); ++ } ++ + if (total_skipped) { + print_error("[ SKIPPED ] %s: %zu test(s), listed below:\n", + group_name, +@@ -2832,7 +2896,8 @@ static void cmprintf_group_finish_standard(const char *group_name, + static void cmprintf_standard(enum cm_printf_type type, + const char *test_name, + const char *error_message, +- const char *skip_note) ++ const char *skip_note, ++ const char *todo_note) + { + switch (type) { + case PRINTF_TEST_START: +@@ -2854,6 +2919,23 @@ static void cmprintf_standard(enum cm_printf_type type, + print_message("[ SKIPPED ] %s\n", test_name); + } + break; ++ case PRINTF_TEST_TODO_OK: ++ if (todo_note) { ++ print_message("[ TODO OK ] %s - %s\n", test_name, todo_note); ++ } else { ++ print_message("[ TODO OK ] %s\n", test_name); ++ } ++ break; ++ case PRINTF_TEST_TODO: ++ if (todo_note) { ++ print_message("[ TODO ] %s - %s\n", test_name, todo_note); ++ } else { ++ print_message("[ TODO ] %s\n", test_name); ++ } ++ if (error_message != NULL) { ++ print_error("[ ERROR ] --- %s\n", error_message); ++ } ++ break; + case PRINTF_TEST_ERROR: + if (error_message != NULL) { + print_error("%s\n", error_message); +@@ -2877,10 +2959,12 @@ static void cmprintf_group_start_tap(const size_t num_tests) + static void cmprintf_group_finish_tap(const char *group_name, + size_t total_executed, + size_t total_passed, +- size_t total_skipped) ++ size_t total_skipped, ++ size_t total_todo_ok, ++ size_t total_todo) + { + const char *status = "not ok"; +- if (total_passed + total_skipped == total_executed) { ++ if (total_passed + total_skipped + total_todo_ok + total_todo == total_executed) { + status = "ok"; + } + print_message("# %s - %s\n", status, group_name); +@@ -2891,6 +2975,7 @@ static void cmprintf_tap(enum cm_printf_type type, + const char *test_name, + const char *error_message, + const char *skip_note, ++ const char *todo_note, + CMData** test_data) + { + CMData* d; +@@ -2916,6 +3001,21 @@ static void cmprintf_tap(enum cm_printf_type type, + print_message("ok %u - %s # SKIP\n", (unsigned)test_number, test_name); + } + break; ++ case PRINTF_TEST_TODO_OK: ++ if (todo_note) { ++ print_message("ok %u - %s # TODO %s\n", (unsigned)test_number, test_name, todo_note); ++ } else { ++ print_message("ok %u - %s # TODO\n", (unsigned)test_number, test_name); ++ } ++ break; ++ case PRINTF_TEST_TODO: ++ if (todo_note) { ++ print_message("not ok %u - %s # TODO %s\n", (unsigned)test_number, test_name, todo_note); ++ } else { ++ print_message("not ok %u - %s # TODO\n", (unsigned)test_number, test_name); ++ } ++ print_error_message = 1; ++ break; + } + + if ((print_error_message == 1) && (error_message != NULL)) { +@@ -3004,6 +3104,9 @@ static void cmprintf_subunit(enum cm_printf_type type, + print_message(" [\n%s\n]\n", error_message); + } + break; ++ case PRINTF_TEST_TODO_OK: ++ case PRINTF_TEST_TODO: ++ /* TODO: not sure about the subunit specification for TODO tests. Looks like they consider them as skipped. */ + case PRINTF_TEST_SKIPPED: + /* TODO: should we print the explanation in DETAILS region as explained here: https://github.com/testing-cabal/subunit */ + print_message("skip: %s\n", test_name); +@@ -3035,6 +3138,8 @@ static void cmprintf_group_finish(const char *group_name, + size_t total_failed, + size_t total_errors, + size_t total_skipped, ++ size_t total_todo_ok, ++ size_t total_todo, + double total_runtime, + struct CMUnitTestState *cm_tests) + { +@@ -3049,13 +3154,17 @@ static void cmprintf_group_finish(const char *group_name, + total_failed, + total_errors, + total_skipped, ++ total_todo_ok, ++ total_todo, + cm_tests); + } + if (output & CM_OUTPUT_TAP) { + cmprintf_group_finish_tap(group_name, + total_executed, + total_passed, +- total_skipped); ++ total_skipped, ++ total_todo_ok, ++ total_todo); + } + if (output & CM_OUTPUT_XML) { + cmprintf_group_finish_xml(group_name, +@@ -3063,6 +3172,8 @@ static void cmprintf_group_finish(const char *group_name, + total_failed, + total_errors, + total_skipped, ++ total_todo_ok, ++ total_todo, + total_runtime, + cm_tests); + } +@@ -3073,6 +3184,7 @@ static void cmprintf(enum cm_printf_type type, + const char *test_name, + const char *error_message, + const char *skip_note, ++ const char *todo_note, + CMData** test_data) + { + uint32_t output; +@@ -3080,13 +3192,13 @@ static void cmprintf(enum cm_printf_type type, + output = cm_get_output(); + + if (output & CM_OUTPUT_STANDARD) { +- cmprintf_standard(type, test_name, error_message, skip_note); ++ cmprintf_standard(type, test_name, error_message, skip_note, todo_note); + } + if (output & CM_OUTPUT_SUBUNIT) { + cmprintf_subunit(type, test_name, error_message); + } + if (output & CM_OUTPUT_TAP) { +- cmprintf_tap(type, test_number, test_name, error_message, skip_note, test_data); ++ cmprintf_tap(type, test_number, test_name, error_message, skip_note, todo_note, test_data); + } + } + +@@ -3324,17 +3436,27 @@ static int cmocka_run_one_tests(struct CMUnitTestState *test_state) + &test_state->state, + NULL); + if (rc == 0) { +- test_state->status = CM_TEST_PASSED; ++ if (global_todo_test) { ++ test_state->status = CM_TEST_TODO_OK; ++ test_state->todo_note = global_todo_test_note; ++ } else { ++ test_state->status = CM_TEST_PASSED; ++ } + } else { + if (global_skip_test) { + test_state->status = CM_TEST_SKIPPED; + test_state->skip_note = global_skip_test_note; + global_skip_test = 0; /* Do not skip the next test */ + global_skip_test_note = NULL; ++ } else if (global_todo_test) { ++ test_state->status = CM_TEST_TODO; ++ test_state->todo_note = global_todo_test_note; + } else { + test_state->status = CM_TEST_FAILED; + } + } ++ global_todo_test = 0; ++ global_todo_test_note = NULL; + rc = 0; + } + +@@ -3380,6 +3502,8 @@ int _cmocka_run_group_tests(const char *group_name, + size_t total_executed = 0; + size_t total_errors = 0; + size_t total_skipped = 0; ++ size_t total_todo_ok = 0; ++ size_t total_todo = 0; + double total_runtime = 0; + size_t i; + int rc; +@@ -3442,7 +3566,7 @@ int _cmocka_run_group_tests(const char *group_name, + struct CMUnitTestState *cmtest = &cm_tests[i]; + size_t test_number = i + 1; + +- cmprintf(PRINTF_TEST_START, test_number, cmtest->test->name, NULL, NULL, NULL); ++ cmprintf(PRINTF_TEST_START, test_number, cmtest->test->name, NULL, NULL, NULL, NULL); + + if (group_state != NULL) { + cmtest->state = group_state; +@@ -3461,6 +3585,7 @@ int _cmocka_run_group_tests(const char *group_name, + cmtest->test->name, + cmtest->error_message, + cmtest->skip_note, ++ cmtest->todo_note, + global_test_data); + total_passed++; + break; +@@ -3470,6 +3595,7 @@ int _cmocka_run_group_tests(const char *group_name, + cmtest->test->name, + cmtest->error_message, + cmtest->skip_note, ++ cmtest->todo_note, + global_test_data); + total_skipped++; + break; +@@ -3479,15 +3605,37 @@ int _cmocka_run_group_tests(const char *group_name, + cmtest->test->name, + cmtest->error_message, + cmtest->skip_note, ++ cmtest->todo_note, + global_test_data); + total_failed++; + break; ++ case CM_TEST_TODO_OK: ++ cmprintf(PRINTF_TEST_TODO_OK, ++ test_number, ++ cmtest->test->name, ++ cmtest->error_message, ++ cmtest->skip_note, ++ cmtest->todo_note, ++ global_test_data); ++ total_todo_ok++; ++ break; ++ case CM_TEST_TODO: ++ cmprintf(PRINTF_TEST_TODO, ++ test_number, ++ cmtest->test->name, ++ cmtest->error_message, ++ cmtest->skip_note, ++ cmtest->todo_note, ++ global_test_data); ++ total_todo++; ++ break; + default: + cmprintf(PRINTF_TEST_ERROR, + test_number, + cmtest->test->name, + "Internal cmocka error", + NULL, ++ NULL, + NULL); + total_errors++; + break; +@@ -3504,6 +3652,7 @@ int _cmocka_run_group_tests(const char *group_name, + cmtest->test->name, + err_msg, + NULL, ++ NULL, + NULL); + total_errors++; + } +@@ -3516,7 +3665,7 @@ int _cmocka_run_group_tests(const char *group_name, + cm_error_message = NULL; + } + cmprintf(PRINTF_TEST_ERROR, 0, +- group_name, "[ FAILED ] GROUP SETUP", NULL, NULL); ++ group_name, "[ FAILED ] GROUP SETUP", NULL, NULL, NULL); + total_errors++; + } + +@@ -3534,7 +3683,7 @@ int _cmocka_run_group_tests(const char *group_name, + cm_error_message = NULL; + } + cmprintf(PRINTF_TEST_ERROR, 0, +- group_name, "[ FAILED ] GROUP TEARDOWN", NULL, NULL); ++ group_name, "[ FAILED ] GROUP TEARDOWN", NULL, NULL, NULL); + } + } + +@@ -3544,6 +3693,8 @@ int _cmocka_run_group_tests(const char *group_name, + total_failed, + total_errors, + total_skipped, ++ total_todo_ok, ++ total_todo, + total_runtime, + cm_tests); + +diff --git a/src/cmocka.def b/src/cmocka.def +index 3b29014..19e09e8 100644 +--- a/src/cmocka.def ++++ b/src/cmocka.def +@@ -51,6 +51,8 @@ EXPORTS + _test_free + _test_malloc + _test_realloc ++ _todo ++ _todo_with_note + _will_return + cmocka_print_error + cmocka_set_message_output +-- +GitLab + + +From a671237d6719c5c9b244ba4c589b8ca7bfc5d2bd Mon Sep 17 00:00:00 2001 +From: maxime +Date: Tue, 9 Aug 2022 16:51:00 +0900 +Subject: [PATCH 6/8] Quick fix on cmprintf_group_finish_standard() because the + line breaks for messages such as "\n %u SKIPPED TEST(S)\n" made them appear + closer to the next list of tests than the lists they are related to. + +--- + src/cmocka.c | 16 ++++++++-------- + 1 file changed, 8 insertions(+), 8 deletions(-) + +diff --git a/src/cmocka.c b/src/cmocka.c +index 978a477..54fb01a 100644 +--- a/src/cmocka.c ++++ b/src/cmocka.c +@@ -2836,7 +2836,7 @@ static void cmprintf_group_finish_standard(const char *group_name, + (unsigned)(total_passed)); + + if (total_todo_ok) { +- print_message("[ TODO OK ] %s: %zu test(s), listed below:\n", ++ print_message("\n[ TODO OK ] %s: %zu test(s), listed below:\n", + group_name, + total_todo_ok); + for (i = 0; i < total_executed; i++) { +@@ -2846,11 +2846,11 @@ static void cmprintf_group_finish_standard(const char *group_name, + print_message("[ TODO OK ] %s\n", cmtest->test->name); + } + } +- print_message("\n %u TODO TEST(S) PASSED - Consider promoting to normal test(s).\n", (unsigned)(total_todo_ok)); ++ print_message(" %u TODO TEST(S) PASSED - Consider promoting to normal test(s).\n", (unsigned)(total_todo_ok)); + } + + if (total_todo) { +- print_message("[ TODO ] %s: %zu test(s), listed below:\n", ++ print_message("\n[ TODO ] %s: %zu test(s), listed below:\n", + group_name, + total_todo); + for (i = 0; i < total_executed; i++) { +@@ -2860,11 +2860,11 @@ static void cmprintf_group_finish_standard(const char *group_name, + print_message("[ TODO ] %s\n", cmtest->test->name); + } + } +- print_message("\n %u TODO TEST(S)\n", (unsigned)(total_todo)); ++ print_message(" %u TODO TEST(S)\n", (unsigned)(total_todo)); + } + + if (total_skipped) { +- print_error("[ SKIPPED ] %s: %zu test(s), listed below:\n", ++ print_error("\n[ SKIPPED ] %s: %zu test(s), listed below:\n", + group_name, + total_skipped); + for (i = 0; i < total_executed; i++) { +@@ -2874,11 +2874,11 @@ static void cmprintf_group_finish_standard(const char *group_name, + print_error("[ SKIPPED ] %s\n", cmtest->test->name); + } + } +- print_error("\n %zu SKIPPED TEST(S)\n", total_skipped); ++ print_error(" %zu SKIPPED TEST(S)\n", total_skipped); + } + + if (total_failed) { +- print_error("[ FAILED ] %s: %zu test(s), listed below:\n", ++ print_error("\n[ FAILED ] %s: %zu test(s), listed below:\n", + group_name, + total_failed); + for (i = 0; i < total_executed; i++) { +@@ -2888,7 +2888,7 @@ static void cmprintf_group_finish_standard(const char *group_name, + print_error("[ FAILED ] %s\n", cmtest->test->name); + } + } +- print_error("\n %zu FAILED TEST(S)\n", ++ print_error(" %zu FAILED TEST(S)\n", + (total_failed + total_errors)); + } + } +-- +GitLab + + +From 6c99594f6fb42128565a7bd9108fdf7efeb09ad5 Mon Sep 17 00:00:00 2001 +From: maxime +Date: Sun, 28 Aug 2022 00:58:11 +0900 +Subject: [PATCH 7/8] fixed compilation warnings + +--- + src/cmocka.c | 15 ++++++++------- + 1 file changed, 8 insertions(+), 7 deletions(-) + +diff --git a/src/cmocka.c b/src/cmocka.c +index 54fb01a..cdb8d50 100644 +--- a/src/cmocka.c ++++ b/src/cmocka.c +@@ -468,6 +468,7 @@ static void free_test_data(void) { + switch (d->type) { + case DATA_TYPE_STRING: + free(d->value); ++ break; + default: + break; + } +@@ -2762,21 +2763,19 @@ static void cmprintf_group_finish_xml(const char *group_name, + fprintf(fp, " \n", + cmtest->test->name, cmtest->runtime); + +- switch (cmtest->status) { +- case CM_TEST_TODO_OK: +- case CM_TEST_TODO: ++ if ((cmtest->status == CM_TEST_TODO) || (cmtest->status == CM_TEST_TODO_OK)) { + if (cmtest->todo_note) { + fprintf(fp, " \n", + cmtest->todo_note); + } else { + fprintf(fp, " \n"); + } +- if (cmtest->status == CM_TEST_TODO_OK) { +- break; +- } +- // fall through ++ } ++ ++ switch (cmtest->status) { + case CM_TEST_ERROR: + case CM_TEST_FAILED: ++ case CM_TEST_TODO: + if (cmtest->error_message != NULL) { + fprintf(fp, " \n", + cmtest->error_message); +@@ -2784,6 +2783,7 @@ static void cmprintf_group_finish_xml(const char *group_name, + fprintf(fp, " \n"); + } + break; ++ + case CM_TEST_SKIPPED: + if (cmtest->skip_note) { + fprintf(fp, " \n", +@@ -2795,6 +2795,7 @@ static void cmprintf_group_finish_xml(const char *group_name, + + case CM_TEST_PASSED: + case CM_TEST_NOT_STARTED: ++ case CM_TEST_TODO_OK: + break; + } + +-- +GitLab + + +From 7e3088264336fafb43bc4dbf842c657320a4c749 Mon Sep 17 00:00:00 2001 +From: maxime +Date: Sun, 28 Aug 2022 01:06:58 +0900 +Subject: [PATCH 8/8] Fixed YAML syntax errors that occurred when messages or + string data printed to the TAP output contained quotes or ended with a + newline. + +--- + src/cmocka.c | 77 ++++++++++++++++++++++++++++++++++++++++++++++++---- + 1 file changed, 72 insertions(+), 5 deletions(-) + +diff --git a/src/cmocka.c b/src/cmocka.c +index cdb8d50..78288d9 100644 +--- a/src/cmocka.c ++++ b/src/cmocka.c +@@ -2971,6 +2971,43 @@ static void cmprintf_group_finish_tap(const char *group_name, + print_message("# %s - %s\n", status, group_name); + } + ++static char* escape_quotes(const char* str) { ++ size_t len = strlen(str); ++ const char *p1 = str; ++ const char *p2 = NULL; ++ char *result; ++ ++ while ((p1 = strchr(p1, '"'))) { ++ len++; ++ p1++; ++ } ++ ++ result = (char*)malloc(sizeof(char) * (len + 1)); ++ if (!result) { ++ return NULL; ++ } ++ result[0] = 0; ++ ++ p1 = str; ++ while ((p2 = strchr(p1, '"'))) { ++#ifdef _WIN32 ++ strncat_s(result, len + 1, p1, p2 - p1); ++ strcat_s(result, len + 1, "\\\""); ++#else ++ strncat(result, p1, p2 - p1); ++ strcat(result, "\\\""); ++#endif ++ p1 = p2 + 1; ++ } ++#ifdef _WIN32 ++ strcat_s(result, len + 1, p1); ++#else ++ strcat(result, p1); ++#endif ++ ++ return result; ++} ++ + static void cmprintf_tap(enum cm_printf_type type, + size_t test_number, + const char *test_name, +@@ -2980,6 +3017,7 @@ static void cmprintf_tap(enum cm_printf_type type, + CMData** test_data) + { + CMData* d; ++ const char *valueStr; + size_t i; + int diagnostics_opened = 0; + int print_error_message = 0; +@@ -3021,19 +3059,33 @@ static void cmprintf_tap(enum cm_printf_type type, + + if ((print_error_message == 1) && (error_message != NULL)) { + char *msg; ++ char *tmp; + char *p; ++ char quoteChar; + const char *indent = ""; + + msg = strdup(error_message); + if (msg == NULL) { + return; + } +- p = msg; ++ ++ // Use double quotes if the message contains single quotes, then escape double quotes if needed. ++ quoteChar = strchr(msg, '\'') ? '"' : '\''; ++ if ((quoteChar == '"') && strchr(msg, '"')) { ++ tmp = escape_quotes(msg); ++ libc_free(msg); ++ if (tmp == NULL) { ++ return; ++ } ++ msg = tmp; ++ } + + print_message(" ---\n"); + diagnostics_opened = 1; + +- print_message(" message: \""); ++ print_message(" message: %c", quoteChar); ++ ++ p = msg; + while (p[0] != '\0') { + char *q = p; + +@@ -3042,7 +3094,7 @@ static void cmprintf_tap(enum cm_printf_type type, + p[0] = '\0'; + print_message("%s%s\\n\\\n", indent, q); + } else { +- print_message("%s%s\"\n", indent, q); ++ print_message("%s%s", indent, q); + break; + } + p++; +@@ -3050,6 +3102,8 @@ static void cmprintf_tap(enum cm_printf_type type, + } + libc_free(msg); + ++ print_message("%c\n", quoteChar); ++ + print_message(" severity: %s\n", (type == PRINTF_TEST_FAILURE) ? "fail" : "error"); + } + +@@ -3076,8 +3130,21 @@ static void cmprintf_tap(enum cm_printf_type type, + d->name, d->value); + break; + case DATA_TYPE_STRING: +- print_message(" %s: '%s'\n", +- d->name, (const char *)(d->value)); ++ valueStr = (const char *)(d->value); ++ if (strchr(valueStr, '\'')) { ++ if (strchr(valueStr, '"')) { ++ char *escapedVal = escape_quotes(valueStr); ++ print_message(" %s: \"%s\"\n", ++ d->name, escapedVal ? escapedVal : ""); ++ free(escapedVal); ++ } else { ++ print_message(" %s: \"%s\"\n", ++ d->name, valueStr); ++ } ++ } else { ++ print_message(" %s: '%s'\n", ++ d->name, valueStr); ++ } + break; + } + } +-- +GitLab + diff --git a/cmake/cmocka-1.1.7/AUTHORS b/cmake/cmocka-1.1.7/AUTHORS new file mode 100644 index 0000000..1fe0d34 --- /dev/null +++ b/cmake/cmocka-1.1.7/AUTHORS @@ -0,0 +1,3 @@ +opensource@google.com +Andreas Schneider +Jakub Hrozek diff --git a/cmake/cmocka-1.1.7/CMakeLists.txt b/cmake/cmocka-1.1.7/CMakeLists.txt new file mode 100644 index 0000000..7664bcc --- /dev/null +++ b/cmake/cmocka-1.1.7/CMakeLists.txt @@ -0,0 +1,93 @@ +# Required cmake version +cmake_minimum_required(VERSION 3.5.0) +cmake_policy(SET CMP0048 NEW) + +# Specify search path for CMake modules to be loaded by include() +# and find_package() +list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake/Modules") + +### Add defaults for cmake +# These defaults need to be included before the project() call. +include(DefineCMakeDefaults) + +# This will provide -DCMAKE_BUILD_TYPE=Profiling +# and -DCMAKE_BUILD_TYPE=AddressSanitizer +include(DefineCompilerFlags) +include(DefinePlatformDefaults) + +project(cmocka VERSION 1.1.7 LANGUAGES C) + +# global needed variables +set(APPLICATION_NAME ${PROJECT_NAME}) + +# SOVERSION scheme: CURRENT.AGE.REVISION +# If there was an incompatible interface change: +# Increment CURRENT. Set AGE and REVISION to 0 +# If there was a compatible interface change: +# Increment AGE. Set REVISION to 0 +# If the source code was changed, but there were no interface changes: +# Increment REVISION. +set(LIBRARY_VERSION "0.8.0") +set(LIBRARY_SOVERSION "0") + +# include cmake files +include(GNUInstallDirs) +include(CMakePackageConfigHelpers) +include(DefineOptions.cmake) +include(CPackConfig.cmake) +include(CompilerChecks.cmake) + +# disallow in-source build +include(MacroEnsureOutOfSourceBuild) +macro_ensure_out_of_source_build("${PROJECT_NAME} requires an out of source build. Please create a separate build directory and run 'cmake /path/to/${PROJECT_NAME} [options]' there.") + +# config.h checks +include(ConfigureChecks.cmake) +configure_file(config.h.cmake ${CMAKE_CURRENT_BINARY_DIR}/config.h) + +# MinGW DLL Naming Workaround +if (MINGW) + set(CMAKE_SHARED_LIBRARY_PREFIX "") +endif (MINGW) + +# check subdirectories +add_subdirectory(include) +add_subdirectory(src) +add_subdirectory(doc) + +include(AddCMockaTest) +if (UNIT_TESTING) + add_subdirectory(tests) +endif (UNIT_TESTING) + +if (WITH_EXAMPLES) + add_subdirectory(example) +endif () + +# pkg-config file +configure_file(cmocka.pc.cmake ${CMAKE_CURRENT_BINARY_DIR}/cmocka.pc @ONLY) +install( + FILES + ${CMAKE_CURRENT_BINARY_DIR}/cmocka.pc + DESTINATION + ${CMAKE_INSTALL_LIBDIR}/pkgconfig + COMPONENT + pkgconfig +) + +write_basic_package_version_file(${PROJECT_NAME}-config-version.cmake + COMPATIBILITY + AnyNewerVersion) + +install(FILES ${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}-config-version.cmake + DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/${PROJECT_NAME} + COMPONENT devel) + +# Add 'make dist' target which makes sure to invoke cmake before +add_custom_target(dist + COMMAND ${CMAKE_MAKE_PROGRAM} package_source) + +# Link combile database for clangd +execute_process(COMMAND cmake -E create_symlink + "${cmocka_BINARY_DIR}/compile_commands.json" + "${cmocka_SOURCE_DIR}/compile_commands.json") diff --git a/cmake/cmocka-1.1.7/COPYING b/cmake/cmocka-1.1.7/COPYING new file mode 100644 index 0000000..d645695 --- /dev/null +++ b/cmake/cmocka-1.1.7/COPYING @@ -0,0 +1,202 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + 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. diff --git a/cmake/cmocka-1.1.7/CPackConfig.cmake b/cmake/cmocka-1.1.7/CPackConfig.cmake new file mode 100644 index 0000000..da730fd --- /dev/null +++ b/cmake/cmocka-1.1.7/CPackConfig.cmake @@ -0,0 +1,54 @@ +# For help take a look at: +# http://www.cmake.org/Wiki/CMake:CPackConfiguration + +### general settings +set(CPACK_PACKAGE_NAME ${PROJECT_NAME}) +set(CPACK_PACKAGE_DESCRIPTION_SUMMARY "Unit testing framework for C with mock objects") +set(CPACK_PACKAGE_DESCRIPTION_FILE "${CMAKE_CURRENT_SOURCE_DIR}/README.md") +set(CPACK_PACKAGE_VENDOR "Andreas Schneider") +set(CPACK_PACKAGE_INSTALL_DIRECTORY ${CPACK_PACKAGE_NAME}) +set(CPACK_RESOURCE_FILE_LICENSE "${CMAKE_CURRENT_SOURCE_DIR}/COPYING") + + +### versions +set(CPACK_PACKAGE_VERSION ${PROJECT_VERSION}) + + +### source generator +set(CPACK_SOURCE_GENERATOR "TXZ") +set(CPACK_SOURCE_IGNORE_FILES "~$;[.]swp$;/[.]git;/[.]gitignore") +string(APPEND CPACK_SOURCE_IGNORE_FILES ";/build*;/obj*") +string(APPEND CPACK_SOURCE_IGNORE_FILES ";/tags;/cscope\.*") +string(APPEND CPACK_SOURCE_IGNORE_FILES ";/[.]ycm_extra_conf.pyc;") +string(APPEND CPACK_SOURCE_IGNORE_FILES ";/[.]clangd;/[.]cache;/compile_commands.json") +set(CPACK_SOURCE_PACKAGE_FILE_NAME "${CPACK_PACKAGE_NAME}-${CPACK_PACKAGE_VERSION}") + +if (WIN32) + set(CPACK_GENERATOR "ZIP") + + ### nsis generator + find_package(NSIS) + if (NSIS_MAKE) + set(CPACK_GENERATOR "${CPACK_GENERATOR};NSIS") + set(CPACK_NSIS_DISPLAY_NAME "CMocka") + set(CPACK_NSIS_COMPRESSOR "/SOLID zlib") + set(CPACK_NSIS_MENU_LINKS "http://cmocka.org/" "cmocka homepage") + endif (NSIS_MAKE) +endif (WIN32) + +set(CPACK_PACKAGE_INSTALL_DIRECTORY "cmocka") + +set(CPACK_PACKAGE_FILE_NAME ${PROJECT_NAME}-${CPACK_PACKAGE_VERSION}) + +set(CPACK_COMPONENT_LIBRARIES_DISPLAY_NAME "Libraries") +set(CPACK_COMPONENT_HEADERS_DISPLAY_NAME "C/C++ Headers") +set(CPACK_COMPONENT_LIBRARIES_DESCRIPTION + "Libraries used to build programs which use cmocka") +set(CPACK_COMPONENT_HEADERS_DESCRIPTION + "C/C++ header files for use with cmocka") +set(CPACK_COMPONENT_HEADERS_DEPENDS libraries) +#set(CPACK_COMPONENT_APPLICATIONS_GROUP "Runtime") +set(CPACK_COMPONENT_LIBRARIES_GROUP "Development") +set(CPACK_COMPONENT_HEADERS_GROUP "Development") + +include(CPack) diff --git a/cmake/cmocka-1.1.7/CTestConfig.cmake b/cmake/cmocka-1.1.7/CTestConfig.cmake new file mode 100644 index 0000000..8645258 --- /dev/null +++ b/cmake/cmocka-1.1.7/CTestConfig.cmake @@ -0,0 +1,9 @@ +set(UPDATE_TYPE "true") + +set(CTEST_PROJECT_NAME "cmocka") +set(CTEST_NIGHTLY_START_TIME "01:00:00 UTC") + +set(CTEST_DROP_METHOD "https") +set(CTEST_DROP_SITE "test.cmocka.org") +set(CTEST_DROP_LOCATION "/submit.php?project=${CTEST_PROJECT_NAME}") +set(CTEST_DROP_SITE_CDASH TRUE) diff --git a/cmake/cmocka-1.1.7/ChangeLog b/cmake/cmocka-1.1.7/ChangeLog new file mode 100644 index 0000000..31da4b7 --- /dev/null +++ b/cmake/cmocka-1.1.7/ChangeLog @@ -0,0 +1,137 @@ +Thu Feb 23 2023 Andreas Schneider + * cmocka version 1.1.7 + * Update ignore list for source tarball generation + +Fri Feb 16 2023 Andreas Schneider + * cmocka version 1.1.6 + * Added new assert macros to compare 2 double given an epsilon + * Added meson build system + * Added header with version to TAP13 output + * Fixed issues with MSVC + * Fixed TAP output for skipped tests + * Fixed issue with fail_msg + * CMake generated configs for find_package(cmocka) + * Documentation improvements + +Thu Mar 28 2019 Andreas Schneider + * cmocka version 1.1.5 + * Added cmocka_set_skip_filter() + +Thu Mar 28 2019 Andreas Schneider + * cmocka version 1.1.4 + * Added assert_float(_not)_equal() + * Added expect_any_always() + * Small bug fixes + +Wed Sep 26 2018 Andreas Schneider + * cmocka version 1.1.3 + * Fixed subunit output on failures + * Do not abort if a test is skipped + * Switched to Modern CMake + +Wed Aug 29 2018 Andreas Schneider + * cmocka version 1.1.2 + * Added function to filter tests (cmocka_set_test_filter) + * Added new mocking example (uptime) + * Fixed fixture error reporting + * Fixed compiler flags detection + * Some improvement for API documentation + +Fri Apr 07 2016 Andreas Schneider + * cmocka: version 1.1.1 + * Fixed TAP output + * Fixed cmocka on Windows x64 + * Fixed xUnit output durations + +Wed Sep 21 2016 Andreas Schneider + * cmocka: version 1.1.0 + * Added support to catch multiple exceptions + * Added support to verify call ordering + * Added support to pass initial data to test cases + * Added will_return_maybe() for ignoring mock returns + * Added subtests for groups using TAP output + * Added support to write multiple XML files for groups + * Improved documentation + * Fixed XML output generataion + * Fixed Windows builds with VS2015 + +Thu Mar 12 2015 Andreas Schneider + * cmocka: version 1.0.1 + * Added a macro for assert_ptr_equal(). + * Fixed test_realloc() if 0 size is passed. + * Fixed objects packaging bug. + * Fixed building with newer gcc versions. + +Sun Feb 16 2015 Andreas Schneider + * cmocka: version 1.0.0 + * Added new test runner with group fixtures. The old runner is deprecated + * Added an extensible message output formatter + * Added jUnit XML message output + * Added subunit message output + * Added Test Anything Protocol message output + * Added skip() command + * Added test_realloc() + * Added a cmockery compat header + * Fixed a lot of bugs on Windows + +Thu May 22 2014 Andreas Schneider + * cmocka: version 0.4.1 + * Added CMOCKA_TEST_ABORT env variable to leave threading apps. + * Fixed count parameter of expect_check() macro. + * Fixed reporting the number of tests. + * Fixed cmake config files. + +Fri Apr 11 2014 Andreas Schneider + * cmocka: version 0.4.0 + * Added support for group testing. + * Added assert_return_code(). + * Added better messages for errors. + * Added cmake config mode support. + * Fixed bug with unit_test_setup and unit_test_teardown. + * Fixed a lot of small bugs. + +Wed Nov 06 2013 Andreas Schneider + * cmocka: version 0.3.2 + * Fixed FindNSIS detection. + * Fixed unit_test_setup() and unit_test_teardown(). + * Fixed GTest and GCC message style conformance + * Fixed stringification in will_return_always(). + +Wed Jul 10 15:24 2013 Andreas Schneider + * cmocka: version 0.3.1 + * Fixed pointer conversion on s390 and ppc (32bit big endian). + * Fixed the customer_database test on big endian. + +Wed Jun 05 08:14 2013 Andreas Schneider + * cmocka: version 0.3.0 + * Added a better mock object example. + * Added pkgconfig file. + * Added new macros mock_type() and mock_ptr_type(). + * Added more documentation. + * Fixed installation problems on some platforms. + +Mon Jan 14 11:16 2013 Andreas Schneider + * cmocka: version 0.2.0 + * Added doxygen api documentation. + * Added new cmake build system. + * Added support to create windows NSIS installer. + * Fixed examples which didn't work. + * Fixed a huge amount of bugs. + +Mon Sep 15 17:21:22 2008 Google Inc. + * cmockery: version 0.12 + * Made it possible to specify additional compiler, lib tool and link + flags on Windows. + * Added Windows makefile to the tar ball. + +Fri Aug 29 10:50:46 2008 Google Inc. + + * cmockery: version 0.11 + * Made it possible to specify executable, library and object output + directories. + +Tue Aug 26 10:18:02 2008 Google Inc. + + * cmockery: initial release: + A lightweight library to simplify and generalize the process of + writing unit tests for C applications. diff --git a/cmake/cmocka-1.1.7/CompilerChecks.cmake b/cmake/cmocka-1.1.7/CompilerChecks.cmake new file mode 100644 index 0000000..b326807 --- /dev/null +++ b/cmake/cmocka-1.1.7/CompilerChecks.cmake @@ -0,0 +1,109 @@ +include(AddCCompilerFlag) +include(CheckCCompilerFlagSSP) + +if (UNIX) + # + # Check for -Werror turned on if possible + # + # This will prevent that compiler flags are detected incorrectly. + # + check_c_compiler_flag("-Werror" REQUIRED_FLAGS_WERROR) + if (REQUIRED_FLAGS_WERROR) + set(CMAKE_REQUIRED_FLAGS "-Werror") + + if (PICKY_DEVELOPER) + list(APPEND SUPPORTED_COMPILER_FLAGS "-Werror") + endif() + endif() + + add_c_compiler_flag("-std=gnu99" SUPPORTED_COMPILER_FLAGS) + add_c_compiler_flag("-Wpedantic" SUPPORTED_COMPILER_FLAGS) + add_c_compiler_flag("-Wall" SUPPORTED_COMPILER_FLAGS) + add_c_compiler_flag("-Wshadow" SUPPORTED_COMPILER_FLAGS) + add_c_compiler_flag("-Wmissing-prototypes" SUPPORTED_COMPILER_FLAGS) + add_c_compiler_flag("-Wcast-align" SUPPORTED_COMPILER_FLAGS) + #add_c_compiler_flag("-Wcast-qual" SUPPORTED_COMPILER_FLAGS) + add_c_compiler_flag("-Werror=address" SUPPORTED_COMPILER_FLAGS) + add_c_compiler_flag("-Wstrict-prototypes" SUPPORTED_COMPILER_FLAGS) + add_c_compiler_flag("-Werror=strict-prototypes" SUPPORTED_COMPILER_FLAGS) + add_c_compiler_flag("-Wwrite-strings" SUPPORTED_COMPILER_FLAGS) + add_c_compiler_flag("-Werror=write-strings" SUPPORTED_COMPILER_FLAGS) + add_c_compiler_flag("-Werror-implicit-function-declaration" SUPPORTED_COMPILER_FLAGS) + add_c_compiler_flag("-Wpointer-arith" SUPPORTED_COMPILER_FLAGS) + add_c_compiler_flag("-Werror=pointer-arith" SUPPORTED_COMPILER_FLAGS) + add_c_compiler_flag("-Wdeclaration-after-statement" SUPPORTED_COMPILER_FLAGS) + add_c_compiler_flag("-Werror=declaration-after-statement" SUPPORTED_COMPILER_FLAGS) + add_c_compiler_flag("-Wreturn-type" SUPPORTED_COMPILER_FLAGS) + add_c_compiler_flag("-Werror=return-type" SUPPORTED_COMPILER_FLAGS) + add_c_compiler_flag("-Wuninitialized" SUPPORTED_COMPILER_FLAGS) + add_c_compiler_flag("-Werror=uninitialized" SUPPORTED_COMPILER_FLAGS) + add_c_compiler_flag("-Wimplicit-fallthrough" SUPPORTED_COMPILER_FLAGS) + add_c_compiler_flag("-Werror=strict-overflow" SUPPORTED_COMPILER_FLAGS) + add_c_compiler_flag("-Wstrict-overflow=2" SUPPORTED_COMPILER_FLAGS) + add_c_compiler_flag("-Wno-format-zero-length" SUPPORTED_COMPILER_FLAGS) + add_c_compiler_flag("-Wmissing-field-initializers" SUPPORTED_COMPILER_FLAGS) + + check_c_compiler_flag("-Wformat" REQUIRED_FLAGS_WFORMAT) + if (REQUIRED_FLAGS_WFORMAT) + list(APPEND SUPPORTED_COMPILER_FLAGS "-Wformat") + set(CMAKE_REQUIRED_FLAGS "${CMAKE_REQUIRED_FLAGS} -Wformat") + endif() + add_c_compiler_flag("-Wformat-security" SUPPORTED_COMPILER_FLAGS) + add_c_compiler_flag("-Werror=format-security" SUPPORTED_COMPILER_FLAGS) + + # Allow zero for a variadic macro argument + string(TOLOWER "${CMAKE_C_COMPILER_ID}" _C_COMPILER_ID) + if ("${_C_COMPILER_ID}" STREQUAL "clang") + add_c_compiler_flag("-Wno-gnu-zero-variadic-macro-arguments" SUPPORTED_COMPILER_FLAGS) + endif() + + add_c_compiler_flag("-fno-common" SUPPORTED_COMPILER_FLAGS) + + if (CMAKE_BUILD_TYPE) + string(TOLOWER "${CMAKE_BUILD_TYPE}" CMAKE_BUILD_TYPE_LOWER) + if (CMAKE_BUILD_TYPE_LOWER MATCHES (release|relwithdebinfo|minsizerel)) + add_c_compiler_flag("-Wp,-D_FORTIFY_SOURCE=2" SUPPORTED_COMPILER_FLAGS) + endif() + endif() + + check_c_compiler_flag_ssp("-fstack-protector-strong" WITH_STACK_PROTECTOR_STRONG) + if (WITH_STACK_PROTECTOR_STRONG) + list(APPEND SUPPORTED_COMPILER_FLAGS "-fstack-protector-strong") + # This is needed as Solaris has a seperate libssp + if (SOLARIS) + list(APPEND SUPPORTED_LINKER_FLAGS "-fstack-protector-strong") + endif() + else (WITH_STACK_PROTECTOR_STRONG) + check_c_compiler_flag_ssp("-fstack-protector" WITH_STACK_PROTECTOR) + if (WITH_STACK_PROTECTOR) + list(APPEND SUPPORTED_COMPILER_FLAGS "-fstack-protector") + # This is needed as Solaris has a seperate libssp + if (SOLARIS) + list(APPEND SUPPORTED_LINKER_FLAGS "-fstack-protector") + endif() + endif() + endif (WITH_STACK_PROTECTOR_STRONG) + + check_c_compiler_flag_ssp("-fstack-clash-protection" WITH_STACK_CLASH_PROTECTION) + if (WITH_STACK_CLASH_PROTECTION) + list(APPEND SUPPORTED_COMPILER_FLAGS "-fstack-clash-protection") + endif() + + if (PICKY_DEVELOPER) + add_c_compiler_flag("-Wno-error=deprecated-declarations" SUPPORTED_COMPILER_FLAGS) + add_c_compiler_flag("-Wno-error=tautological-compare" SUPPORTED_COMPILER_FLAGS) + endif() + + # Unset CMAKE_REQUIRED_FLAGS + unset(CMAKE_REQUIRED_FLAGS) +endif() + +if (MSVC) + add_c_compiler_flag("/D _CRT_SECURE_CPP_OVERLOAD_STANDARD_NAMES=1" SUPPORTED_COMPILER_FLAGS) + add_c_compiler_flag("/D _CRT_SECURE_CPP_OVERLOAD_STANDARD_NAMES_COUNT=1" SUPPORTED_COMPILER_FLAGS) + add_c_compiler_flag("/D _CRT_NONSTDC_NO_WARNINGS=1" SUPPORTED_COMPILER_FLAGS) + add_c_compiler_flag("/D _CRT_SECURE_NO_WARNINGS=1" SUPPORTED_COMPILER_FLAGS) +endif() + +set(DEFAULT_C_COMPILE_FLAGS ${SUPPORTED_COMPILER_FLAGS} CACHE INTERNAL "Default C Compiler Flags" FORCE) +set(DEFAULT_LINK_FLAGS ${SUPPORTED_LINKER_FLAGS} CACHE INTERNAL "Default C Linker Flags" FORCE) diff --git a/cmake/cmocka-1.1.7/ConfigureChecks.cmake b/cmake/cmocka-1.1.7/ConfigureChecks.cmake new file mode 100644 index 0000000..028774f --- /dev/null +++ b/cmake/cmocka-1.1.7/ConfigureChecks.cmake @@ -0,0 +1,152 @@ +include(CheckIncludeFile) +include(CheckSymbolExists) +include(CheckFunctionExists) +include(CheckLibraryExists) +include(CheckTypeSize) +include(CheckCXXSourceCompiles) +include(CheckStructHasMember) +include(TestBigEndian) + +set(PACKAGE ${PROJECT_NAME}) +set(VERSION ${PROJECT_VERSION}) +set(DATADIR ${DATA_INSTALL_DIR}) +set(LIBDIR ${CMAKE_INSTALL_LIBDIR}) +set(PLUGINDIR "${PLUGIN_INSTALL_DIR}-${LIBRARY_SOVERSION}") +set(SYSCONFDIR ${SYSCONF_INSTALL_DIR}) + +set(BINARYDIR ${CMAKE_BINARY_DIR}) +set(SOURCEDIR ${CMAKE_SOURCE_DIR}) + +function(COMPILER_DUMPVERSION _OUTPUT_VERSION) + # Remove whitespaces from the argument. + # This is needed for CC="ccache gcc" cmake .. + string(REPLACE " " "" _C_COMPILER_ARG "${CMAKE_C_COMPILER_ARG1}") + + execute_process( + COMMAND + ${CMAKE_C_COMPILER} ${_C_COMPILER_ARG} -dumpversion + OUTPUT_VARIABLE _COMPILER_VERSION + ) + + string(REGEX REPLACE "([0-9])\\.([0-9])(\\.[0-9])?" "\\1\\2" + _COMPILER_VERSION ${_COMPILER_VERSION}) + + set(${_OUTPUT_VERSION} ${_COMPILER_VERSION} PARENT_SCOPE) +endfunction() + +if(CMAKE_COMPILER_IS_GNUCC AND NOT MINGW) + compiler_dumpversion(GNUCC_VERSION) + if (NOT GNUCC_VERSION EQUAL 34) + check_c_compiler_flag("-fvisibility=hidden" WITH_VISIBILITY_HIDDEN) + endif (NOT GNUCC_VERSION EQUAL 34) +endif(CMAKE_COMPILER_IS_GNUCC AND NOT MINGW) + +# DEFINITIONS +if (SOLARIS) + add_definitions(-D__EXTENSIONS__) +endif (SOLARIS) + +# HEADER FILES +check_include_file(assert.h HAVE_ASSERT_H) +check_include_file(inttypes.h HAVE_INTTYPES_H) +check_include_file(io.h HAVE_IO_H) +check_include_file(malloc.h HAVE_MALLOC_H) +check_include_file(memory.h HAVE_MEMORY_H) +check_include_file(setjmp.h HAVE_SETJMP_H) +check_include_file(signal.h HAVE_SIGNAL_H) +check_include_file(stdarg.h HAVE_STDARG_H) +check_include_file(stddef.h HAVE_STDDEF_H) +check_include_file(stdint.h HAVE_STDINT_H) +check_include_file(stdio.h HAVE_STDIO_H) +check_include_file(stdlib.h HAVE_STDLIB_H) +check_include_file(string.h HAVE_STRING_H) +check_include_file(strings.h HAVE_STRINGS_H) +check_include_file(sys/stat.h HAVE_SYS_STAT_H) +check_include_file(sys/types.h HAVE_SYS_TYPES_H) +check_include_file(time.h HAVE_TIME_H) +check_include_file(unistd.h HAVE_UNISTD_H) + +if (HAVE_TIME_H) + check_struct_has_member("struct timespec" tv_sec "time.h" HAVE_STRUCT_TIMESPEC) +endif (HAVE_TIME_H) + +# TYPES +check_type_size(uintptr_t UINTPTR_T) + +# FUNCTIONS +check_function_exists(calloc HAVE_CALLOC) +check_function_exists(exit HAVE_EXIT) +check_function_exists(fprintf HAVE_FPRINTF) +check_function_exists(free HAVE_FREE) +check_function_exists(longjmp HAVE_LONGJMP) +check_function_exists(siglongjmp HAVE_SIGLONGJMP) +check_function_exists(malloc HAVE_MALLOC) +check_function_exists(memcpy HAVE_MEMCPY) +check_function_exists(memset HAVE_MEMSET) +check_function_exists(printf HAVE_PRINTF) +check_function_exists(setjmp HAVE_SETJMP) +check_function_exists(signal HAVE_SIGNAL) +check_function_exists(strsignal HAVE_STRSIGNAL) +check_function_exists(strcmp HAVE_STRCMP) +check_function_exists(clock_gettime HAVE_CLOCK_GETTIME) + +if (WIN32) + check_function_exists(_vsnprintf_s HAVE__VSNPRINTF_S) + check_function_exists(_vsnprintf HAVE__VSNPRINTF) + check_function_exists(_snprintf HAVE__SNPRINTF) + check_function_exists(_snprintf_s HAVE__SNPRINTF_S) + check_symbol_exists(snprintf stdio.h HAVE_SNPRINTF) + check_symbol_exists(vsnprintf stdio.h HAVE_VSNPRINTF) +else (WIN32) + check_function_exists(sprintf HAVE_SNPRINTF) + check_function_exists(vsnprintf HAVE_VSNPRINTF) +endif (WIN32) + +find_library(RT_LIBRARY rt) +if (RT_LIBRARY AND NOT LINUX AND NOT ANDROID) + set(CMOCKA_REQUIRED_LIBRARIES ${RT_LIBRARY} CACHE INTERNAL "cmocka required system libraries") +endif () + +# OPTIONS +check_c_source_compiles(" +__thread int tls; + +int main(void) { + return 0; +}" HAVE_GCC_THREAD_LOCAL_STORAGE) + +if (WIN32) +check_c_source_compiles(" +__declspec(thread) int tls; + +int main(void) { + return 0; +}" HAVE_MSVC_THREAD_LOCAL_STORAGE) +endif(WIN32) + +if (HAVE_TIME_H AND HAVE_STRUCT_TIMESPEC AND HAVE_CLOCK_GETTIME) + if (RT_LIBRARY) + set(CMAKE_REQUIRED_LIBRARIES ${RT_LIBRARY}) + endif() + + check_c_source_compiles(" +#include + +int main(void) { + struct timespec ts; + + clock_gettime(CLOCK_REALTIME, &ts); + + return 0; +}" HAVE_CLOCK_REALTIME) + + # reset cmake requirements + set(CMAKE_REQUIRED_INCLUDES) + set(CMAKE_REQUIRED_LIBRARIES) +endif () + +# ENDIAN +if (NOT WIN32) + set(WORDS_SIZEOF_VOID_P ${CMAKE_SIZEOF_VOID_P}) + test_big_endian(WORDS_BIGENDIAN) +endif (NOT WIN32) diff --git a/cmake/cmocka-1.1.7/DefineOptions.cmake b/cmake/cmocka-1.1.7/DefineOptions.cmake new file mode 100644 index 0000000..986fe47 --- /dev/null +++ b/cmake/cmocka-1.1.7/DefineOptions.cmake @@ -0,0 +1,5 @@ +option(BUILD_SHARED_LIBS "Build shared libraries" ON) +option(WITH_CMOCKERY_SUPPORT "Install a cmockery header" OFF) +option(WITH_EXAMPLES "Build examples" ON) +option(UNIT_TESTING "Build with unit testing" OFF) +option(PICKY_DEVELOPER "Build with picky developer flags" OFF) diff --git a/cmake/cmocka-1.1.7/INSTALL.md b/cmake/cmocka-1.1.7/INSTALL.md new file mode 100644 index 0000000..0f8718b --- /dev/null +++ b/cmake/cmocka-1.1.7/INSTALL.md @@ -0,0 +1,120 @@ +# Installing cmocka + +## Use a package manger (also on Windows) + +If you're using a BSD or Linux distribution, cmocka is already packaged and +you should find it in your package manager. + + install cmocka-devel + or + install libcmocka-devel + +For Windows it is recommended to use: https://vcpkg.io/ + + vcpkg install cmocka + +## Building from source + +### Requirements + +#### Common requirements + +In order to build cmocka, you need to install several components: + +- A C compiler +- [CMake](http://www.cmake.org) >= 3.5.0. + +Note that these version numbers are version we know works correctly. If you +build and run cmocka successfully with an older version, please let us know. + +### Building +First, you need to configure the compilation, using CMake. Go inside the +`build` dir. Create it if it doesn't exist. + +GNU/Linux, MacOS X, MSYS/MinGW: + + cmake -DCMAKE_INSTALL_PREFIX=/usr -DCMAKE_BUILD_TYPE=Debug .. + make + +On Windows you should choose a makefile gernerator with -G, for example: + + cmake -G "Visual Studio 12 2013" -DCMAKE_BUILD_TYPE=Debug /path/to/source + +You can also use the CMake GUI which is shipped with CMake. It will list all +available generators for MSVC on Windows. We only support Visual Studio 2013 +or newer which supports C99. + +#### CMake standard options +Here is a list of the most interesting options provided out of the box by +CMake. + +- CMAKE_BUILD_TYPE: The type of build (can be Debug Release MinSizeRel + RelWithDebInfo) +- CMAKE_INSTALL_PREFIX: The prefix to use when running make install (Default + to /usr/local on GNU/Linux and MacOS X) +- CMAKE_C_COMPILER: The path to the C compiler +- CMAKE_CXX_COMPILER: The path to the C++ compiler + +#### CMake options defined for cmocka + +Options are defined in the following files: + +- DefineOptions.cmake + +They can be changed with the -D option: + +`cmake -DCMAKE_INSTALL_PREFIX=/usr -DCMAKE_BUILD_TYPE=Debug -DUNIT_TESTING=ON ..` + +#### Browsing/editing CMake options + +In addition to passing options on the command line, you can browse and edit +CMake options using `cmake-gui.exe` (Windows) or `ccmake` (GNU/Linux +and MacOS X). + +- Go to the build dir +- On Windows: run `cmakesetup` +- On GNU/Linux and MacOS X: run `ccmake ..` + +More at https://cmake.org/runningcmake/ + +### Installing + +If you want to install cmocka after compilation run: + + make install + +### Running + +The cmocka library can be found in the `build/src` directory. +You can run the binaries in `build/examples/*` which is a +are example tests. + +### Testing + +As mention above you can turn on the unit tests and make it possible to easily +execute them: + +`cmake -DCMAKE_BUILD_TYPE=Debug -DUNIT_TESTING=ON ..` + +After that you can simply call `make test` in the build directory or if you +want more output simply call `ctest -V`. + +If you want to enable the generation of coverage files you can do this by +using the following options: + +`cmake -DCMAKE_BUILD_TYPE=Profiling -DUNIT_TESTING=ON ..` + +After building it you will see that you have several coverage options in + +`make help` + +You should have `make ExperimentalCoverage` and running it will create +coverage files. The result is stored in Testing directory. + +## About this document + +This document is written using [Markdown][] syntax, making it possible to +provide usable information in both plain text and HTML format. Whenever +modifying this document please use [Markdown][] syntax. + +[markdown]: http://www.daringfireball.net/projects/markdown diff --git a/cmake/cmocka-1.1.7/NEWS b/cmake/cmocka-1.1.7/NEWS new file mode 100644 index 0000000..e69de29 diff --git a/cmake/cmocka-1.1.7/README.md b/cmake/cmocka-1.1.7/README.md new file mode 100644 index 0000000..7558b13 --- /dev/null +++ b/cmake/cmocka-1.1.7/README.md @@ -0,0 +1,22 @@ +cmocka +====== + +cmocka is an elegant unit testing framework for C with support for mock +objects. It only requires the standard C library, works on a range of computing +platforms (including embedded) and with different compilers. + +For information about how to use the cmocka unit testing framework see +doc/index.html or https://api.cmocka.org/. + +Compiling +--------- + +To compile the cmocka library and example applications run, create a build dir, +and in the build dir call 'cmake /path/to/cmocka' followed by 'make'. On +Windows you can use the cmake gui. More details can be found in the INSTALL.md +file. + +Website +------- + +https://cmocka.org diff --git a/cmake/cmocka-1.1.7/cmake/Modules/AddCCompilerFlag.cmake b/cmake/cmocka-1.1.7/cmake/Modules/AddCCompilerFlag.cmake new file mode 100644 index 0000000..c24c215 --- /dev/null +++ b/cmake/cmocka-1.1.7/cmake/Modules/AddCCompilerFlag.cmake @@ -0,0 +1,21 @@ +# +# add_c_compiler_flag("-Werror" SUPPORTED_CFLAGS) +# +# Copyright (c) 2018 Andreas Schneider +# +# Redistribution and use is allowed according to the terms of the BSD license. +# For details see the accompanying COPYING-CMAKE-SCRIPTS file. + +include(CheckCCompilerFlag) + +macro(add_c_compiler_flag _COMPILER_FLAG _OUTPUT_VARIABLE) + string(TOUPPER ${_COMPILER_FLAG} _COMPILER_FLAG_NAME) + string(REGEX REPLACE "^-" "" _COMPILER_FLAG_NAME "${_COMPILER_FLAG_NAME}") + string(REGEX REPLACE "(-|=|\ )" "_" _COMPILER_FLAG_NAME "${_COMPILER_FLAG_NAME}") + + check_c_compiler_flag("${_COMPILER_FLAG}" WITH_${_COMPILER_FLAG_NAME}_FLAG) + if (WITH_${_COMPILER_FLAG_NAME}_FLAG) + #string(APPEND ${_OUTPUT_VARIABLE} "${_COMPILER_FLAG} ") + list(APPEND ${_OUTPUT_VARIABLE} ${_COMPILER_FLAG}) + endif() +endmacro() diff --git a/cmake/cmocka-1.1.7/cmake/Modules/AddCMockaTest.cmake b/cmake/cmocka-1.1.7/cmake/Modules/AddCMockaTest.cmake new file mode 100644 index 0000000..12fbd79 --- /dev/null +++ b/cmake/cmocka-1.1.7/cmake/Modules/AddCMockaTest.cmake @@ -0,0 +1,143 @@ +# +# Copyright (c) 2007 Daniel Gollub +# Copyright (c) 2007-2018 Andreas Schneider +# Copyright (c) 2018 Anderson Toshiyuki Sasaki +# +# Redistribution and use is allowed according to the terms of the BSD license. +# For details see the accompanying COPYING-CMAKE-SCRIPTS file. + +#.rst: +# AddCMockaTest +# ------------- +# +# This file provides a function to add a test +# +# Functions provided +# ------------------ +# +# :: +# +# add_cmocka_test(target_name +# SOURCES src1 src2 ... srcN +# [COMPILE_OPTIONS opt1 opt2 ... optN] +# [LINK_LIBRARIES lib1 lib2 ... libN] +# [LINK_OPTIONS lopt1 lop2 .. loptN] +# ) +# +# ``target_name``: +# Required, expects the name of the test which will be used to define a target +# +# ``SOURCES``: +# Required, expects one or more source files names +# +# ``COMPILE_OPTIONS``: +# Optional, expects one or more options to be passed to the compiler +# +# ``LINK_LIBRARIES``: +# Optional, expects one or more libraries to be linked with the test +# executable. +# +# ``LINK_OPTIONS``: +# Optional, expects one or more options to be passed to the linker +# +# +# Example: +# +# .. code-block:: cmake +# +# add_cmocka_test(my_test +# SOURCES my_test.c other_source.c +# COMPILE_OPTIONS -g -Wall +# LINK_LIBRARIES mylib +# LINK_OPTIONS -Wl,--enable-syscall-fixup +# ) +# +# Where ``my_test`` is the name of the test, ``my_test.c`` and +# ``other_source.c`` are sources for the binary, ``-g -Wall`` are compiler +# options to be used, ``mylib`` is a target of a library to be linked, and +# ``-Wl,--enable-syscall-fixup`` is an option passed to the linker. +# + +enable_testing() +include(CTest) + +if (CMAKE_CROSSCOMPILING) + if (WIN32) + find_program(WINE_EXECUTABLE + NAMES wine) + set(TARGET_SYSTEM_EMULATOR ${WINE_EXECUTABLE} CACHE INTERNAL "") + endif() +endif() + +function(ADD_CMOCKA_TEST _TARGET_NAME) + + set(one_value_arguments + ) + + set(multi_value_arguments + SOURCES + COMPILE_OPTIONS + LINK_LIBRARIES + LINK_OPTIONS + ) + + cmake_parse_arguments(_add_cmocka_test + "" + "${one_value_arguments}" + "${multi_value_arguments}" + ${ARGN} + ) + + if (NOT DEFINED _add_cmocka_test_SOURCES) + message(FATAL_ERROR "No sources provided for target ${_TARGET_NAME}") + endif() + + add_executable(${_TARGET_NAME} ${_add_cmocka_test_SOURCES}) + + if (DEFINED _add_cmocka_test_COMPILE_OPTIONS) + target_compile_options(${_TARGET_NAME} + PRIVATE ${_add_cmocka_test_COMPILE_OPTIONS} + ) + endif() + + if (DEFINED _add_cmocka_test_LINK_LIBRARIES) + target_link_libraries(${_TARGET_NAME} + PRIVATE ${_add_cmocka_test_LINK_LIBRARIES} + ) + endif() + + if (DEFINED _add_cmocka_test_LINK_OPTIONS) + set_target_properties(${_TARGET_NAME} + PROPERTIES LINK_FLAGS + ${_add_cmocka_test_LINK_OPTIONS} + ) + endif() + + add_test(${_TARGET_NAME} + ${TARGET_SYSTEM_EMULATOR} ${_TARGET_NAME} + ) + +endfunction (ADD_CMOCKA_TEST) + +function(ADD_CMOCKA_TEST_ENVIRONMENT _TARGET_NAME) + if (WIN32 OR CYGWIN OR MINGW OR MSVC) + file(TO_NATIVE_PATH "${cmocka-library_BINARY_DIR}" CMOCKA_DLL_PATH) + + if (TARGET_SYSTEM_EMULATOR) + set(DLL_PATH_ENV "WINEPATH=${CMOCKA_DLL_PATH};$ENV{WINEPATH}") + else() + set(DLL_PATH_ENV "PATH=${CMOCKA_DLL_PATH}\\${CMAKE_BUILD_TYPE};$ENV{PATH}") + endif() + # + # IMPORTANT NOTE: The set_tests_properties(), below, internally + # stores its name/value pairs with a semicolon delimiter. + # because of this we must protect the semicolons in the path + # + string(REPLACE ";" "\\;" DLL_PATH_ENV "${DLL_PATH_ENV}") + + set_tests_properties(${_TARGET_NAME} + PROPERTIES + ENVIRONMENT + "${DLL_PATH_ENV}") + endif() +endfunction() diff --git a/cmake/cmocka-1.1.7/cmake/Modules/COPYING-CMAKE-SCRIPTS b/cmake/cmocka-1.1.7/cmake/Modules/COPYING-CMAKE-SCRIPTS new file mode 100644 index 0000000..4b41776 --- /dev/null +++ b/cmake/cmocka-1.1.7/cmake/Modules/COPYING-CMAKE-SCRIPTS @@ -0,0 +1,22 @@ +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions +are met: + +1. Redistributions of source code must retain the copyright + notice, this list of conditions and the following disclaimer. +2. Redistributions in binary form must reproduce the copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. +3. The name of the author may not be used to endorse or promote products + derived from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR +IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, +INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF +THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/cmake/cmocka-1.1.7/cmake/Modules/CheckCCompilerFlagSSP.cmake b/cmake/cmocka-1.1.7/cmake/Modules/CheckCCompilerFlagSSP.cmake new file mode 100644 index 0000000..eeaf4fc --- /dev/null +++ b/cmake/cmocka-1.1.7/cmake/Modules/CheckCCompilerFlagSSP.cmake @@ -0,0 +1,48 @@ +# - Check whether the C compiler supports a given flag in the +# context of a stack checking compiler option. + +# CHECK_C_COMPILER_FLAG_SSP(FLAG VARIABLE) +# +# FLAG - the compiler flag +# VARIABLE - variable to store the result +# +# This actually calls check_c_source_compiles. +# See help for CheckCSourceCompiles for a listing of variables +# that can modify the build. + +# Copyright (c) 2006, Alexander Neundorf, +# +# Redistribution and use is allowed according to the terms of the BSD license. +# For details see the accompanying COPYING-CMAKE-SCRIPTS file. + +# Requires cmake 3.10 +#include_guard(GLOBAL) +include(CheckCSourceCompiles) +include(CMakeCheckCompilerFlagCommonPatterns) + +macro(CHECK_C_COMPILER_FLAG_SSP _FLAG _RESULT) + set(SAFE_CMAKE_REQUIRED_FLAGS "${CMAKE_REQUIRED_FLAGS}") + set(CMAKE_REQUIRED_FLAGS "${_FLAG}") + + # Normalize locale during test compilation. + set(_CheckCCompilerFlag_LOCALE_VARS LC_ALL LC_MESSAGES LANG) + foreach(v ${_CheckCCompilerFlag_LOCALE_VARS}) + set(_CheckCCompilerFlag_SAVED_${v} "$ENV{${v}}") + set(ENV{${v}} C) + endforeach() + + CHECK_COMPILER_FLAG_COMMON_PATTERNS(_CheckCCompilerFlag_COMMON_PATTERNS) + check_c_source_compiles("int main(int argc, char **argv) { char buffer[256]; return buffer[argc]=0;}" + ${_RESULT} + # Some compilers do not fail with a bad flag + FAIL_REGEX "command line option .* is valid for .* but not for C" # GNU + ${_CheckCCompilerFlag_COMMON_PATTERNS}) + foreach(v ${_CheckCCompilerFlag_LOCALE_VARS}) + set(ENV{${v}} ${_CheckCCompilerFlag_SAVED_${v}}) + unset(_CheckCCompilerFlag_SAVED_${v}) + endforeach() + unset(_CheckCCompilerFlag_LOCALE_VARS) + unset(_CheckCCompilerFlag_COMMON_PATTERNS) + + set(CMAKE_REQUIRED_FLAGS "${SAFE_CMAKE_REQUIRED_FLAGS}") +endmacro(CHECK_C_COMPILER_FLAG_SSP) diff --git a/cmake/cmocka-1.1.7/cmake/Modules/DefineCMakeDefaults.cmake b/cmake/cmocka-1.1.7/cmake/Modules/DefineCMakeDefaults.cmake new file mode 100644 index 0000000..9fb034f --- /dev/null +++ b/cmake/cmocka-1.1.7/cmake/Modules/DefineCMakeDefaults.cmake @@ -0,0 +1,25 @@ +# Always include srcdir and builddir in include path +# This saves typing ${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_BINARY} in +# about every subdir +# since cmake 2.4.0 +set(CMAKE_INCLUDE_CURRENT_DIR ON) + +# Put the include dirs which are in the source or build tree +# before all other include dirs, so the headers in the sources +# are prefered over the already installed ones +# since cmake 2.4.1 +set(CMAKE_INCLUDE_DIRECTORIES_PROJECT_BEFORE ON) + +# Use colored output +# since cmake 2.4.0 +set(CMAKE_COLOR_MAKEFILE ON) + +# Create the compile command database for clang by default +set(CMAKE_EXPORT_COMPILE_COMMANDS ON) + +# Always build with -fPIC +set(CMAKE_POSITION_INDEPENDENT_CODE ON) + +# Avoid source tree pollution +set(CMAKE_DISABLE_SOURCE_CHANGES ON) +set(CMAKE_DISABLE_IN_SOURCE_BUILD ON) diff --git a/cmake/cmocka-1.1.7/cmake/Modules/DefineCompilerFlags.cmake b/cmake/cmocka-1.1.7/cmake/Modules/DefineCompilerFlags.cmake new file mode 100644 index 0000000..c9aea58 --- /dev/null +++ b/cmake/cmocka-1.1.7/cmake/Modules/DefineCompilerFlags.cmake @@ -0,0 +1,49 @@ +if (UNIX AND NOT WIN32) + # Activate with: -DCMAKE_BUILD_TYPE=Profiling + set(CMAKE_C_FLAGS_PROFILING "-O0 -g -fprofile-arcs -ftest-coverage" + CACHE STRING "Flags used by the C compiler during PROFILING builds.") + set(CMAKE_CXX_FLAGS_PROFILING "-O0 -g -fprofile-arcs -ftest-coverage" + CACHE STRING "Flags used by the CXX compiler during PROFILING builds.") + set(CMAKE_SHARED_LINKER_FLAGS_PROFILING "-fprofile-arcs -ftest-coverage" + CACHE STRING "Flags used by the linker during the creation of shared libraries during PROFILING builds.") + set(CMAKE_MODULE_LINKER_FLAGS_PROFILING "-fprofile-arcs -ftest-coverage" + CACHE STRING "Flags used by the linker during the creation of shared libraries during PROFILING builds.") + set(CMAKE_EXEC_LINKER_FLAGS_PROFILING "-fprofile-arcs -ftest-coverage" + CACHE STRING "Flags used by the linker during PROFILING builds.") + + # Activate with: -DCMAKE_BUILD_TYPE=AddressSanitizer + set(CMAKE_C_FLAGS_ADDRESSSANITIZER "-g -O1 -fsanitize=address -fno-omit-frame-pointer" + CACHE STRING "Flags used by the C compiler during ADDRESSSANITIZER builds.") + set(CMAKE_CXX_FLAGS_ADDRESSSANITIZER "-g -O1 -fsanitize=address -fno-omit-frame-pointer" + CACHE STRING "Flags used by the CXX compiler during ADDRESSSANITIZER builds.") + set(CMAKE_SHARED_LINKER_FLAGS_ADDRESSSANITIZER "-fsanitize=address" + CACHE STRING "Flags used by the linker during the creation of shared libraries during ADDRESSSANITIZER builds.") + set(CMAKE_MODULE_LINKER_FLAGS_ADDRESSSANITIZER "-fsanitize=address" + CACHE STRING "Flags used by the linker during the creation of shared libraries during ADDRESSSANITIZER builds.") + set(CMAKE_EXEC_LINKER_FLAGS_ADDRESSSANITIZER "-fsanitize=address" + CACHE STRING "Flags used by the linker during ADDRESSSANITIZER builds.") + + # Activate with: -DCMAKE_BUILD_TYPE=MemorySanitizer + set(CMAKE_C_FLAGS_MEMORYSANITIZER "-g -O2 -fsanitize=memory -fsanitize-memory-track-origins=2 -fno-omit-frame-pointer" + CACHE STRING "Flags used by the C compiler during MEMORYSANITIZER builds.") + set(CMAKE_CXX_FLAGS_MEMORYSANITIZER "-g -O2 -fsanitize=memory -fsanitize-memory-track-origins=2 -fno-omit-frame-pointer" + CACHE STRING "Flags used by the CXX compiler during MEMORYSANITIZER builds.") + set(CMAKE_SHARED_LINKER_FLAGS_MEMORYSANITIZER "-fsanitize=memory" + CACHE STRING "Flags used by the linker during the creation of shared libraries during MEMORYSANITIZER builds.") + set(CMAKE_MODULE_LINKER_FLAGS_MEMORYSANITIZER "-fsanitize=memory" + CACHE STRING "Flags used by the linker during the creation of shared libraries during MEMORYSANITIZER builds.") + set(CMAKE_EXEC_LINKER_FLAGS_MEMORYSANITIZER "-fsanitize=memory" + CACHE STRING "Flags used by the linker during MEMORYSANITIZER builds.") + + # Activate with: -DCMAKE_BUILD_TYPE=UndefinedSanitizer + set(CMAKE_C_FLAGS_UNDEFINEDSANITIZER "-g -O1 -fsanitize=undefined -fsanitize=null -fsanitize=alignment -fno-sanitize-recover" + CACHE STRING "Flags used by the C compiler during UNDEFINEDSANITIZER builds.") + set(CMAKE_CXX_FLAGS_UNDEFINEDSANITIZER "-g -O1 -fsanitize=undefined -fsanitize=null -fsanitize=alignment -fno-sanitize-recover" + CACHE STRING "Flags used by the CXX compiler during UNDEFINEDSANITIZER builds.") + set(CMAKE_SHARED_LINKER_FLAGS_UNDEFINEDSANITIZER "-fsanitize=undefined" + CACHE STRING "Flags used by the linker during the creation of shared libraries during UNDEFINEDSANITIZER builds.") + set(CMAKE_MODULE_LINKER_FLAGS_UNDEFINEDSANITIZER "-fsanitize=undefined" + CACHE STRING "Flags used by the linker during the creation of shared libraries during UNDEFINEDSANITIZER builds.") + set(CMAKE_EXEC_LINKER_FLAGS_UNDEFINEDSANITIZER "-fsanitize=undefined" + CACHE STRING "Flags used by the linker during UNDEFINEDSANITIZER builds.") +endif() diff --git a/cmake/cmocka-1.1.7/cmake/Modules/DefinePlatformDefaults.cmake b/cmake/cmocka-1.1.7/cmake/Modules/DefinePlatformDefaults.cmake new file mode 100644 index 0000000..46c3185 --- /dev/null +++ b/cmake/cmocka-1.1.7/cmake/Modules/DefinePlatformDefaults.cmake @@ -0,0 +1,21 @@ +# Set system vars + +if (CMAKE_SYSTEM_NAME MATCHES "Linux") + set(LINUX TRUE) +endif(CMAKE_SYSTEM_NAME MATCHES "Linux") + +if (CMAKE_SYSTEM_NAME MATCHES "FreeBSD") + set(FREEBSD TRUE) +endif (CMAKE_SYSTEM_NAME MATCHES "FreeBSD") + +if (CMAKE_SYSTEM_NAME MATCHES "OpenBSD") + set(OPENBSD TRUE) +endif (CMAKE_SYSTEM_NAME MATCHES "OpenBSD") + +if (CMAKE_SYSTEM_NAME MATCHES "NetBSD") + set(NETBSD TRUE) +endif (CMAKE_SYSTEM_NAME MATCHES "NetBSD") + +if (CMAKE_SYSTEM_NAME MATCHES "(Solaris|SunOS)") + set(SOLARIS TRUE) +endif (CMAKE_SYSTEM_NAME MATCHES "(Solaris|SunOS)") diff --git a/cmake/cmocka-1.1.7/cmake/Modules/FindNSIS.cmake b/cmake/cmocka-1.1.7/cmake/Modules/FindNSIS.cmake new file mode 100644 index 0000000..9f1ab17 --- /dev/null +++ b/cmake/cmocka-1.1.7/cmake/Modules/FindNSIS.cmake @@ -0,0 +1,54 @@ +# - Try to find NSIS +# Once done this will define +# +# NSIS_ROOT_PATH - Set this variable to the root installation of NSIS +# +# Read-Only variables: +# +# NSIS_FOUND - system has NSIS +# NSIS_MAKE - NSIS creator executable +# +#============================================================================= +# Copyright (c) 2010-2013 Andreas Schneider +# +# Distributed under the OSI-approved BSD License (the "License"); +# see accompanying file Copyright.txt for details. +# +# This software is distributed WITHOUT ANY WARRANTY; without even the +# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +# See the License for more information. +#============================================================================= +# + +if (WIN32) + set(_x86 "(x86)") + + set(_NSIS_ROOT_PATHS + "$ENV{ProgramFiles}/NSIS" + "$ENV{ProgramFiles${_x86}}/NSIS" + "[HKEY_LOCAL_MACHINE\\SOFTWARE\\Wow6432Node\\NSIS;Default]") + + find_path(NSIS_ROOT_PATH + NAMES + Include/Library.nsh + PATHS + ${_NSIS_ROOT_PATHS} + ) + mark_as_advanced(NSIS_ROOT_PATH) +endif (WIN32) + +find_program(NSIS_MAKE + NAMES + makensis + PATHS + ${NSIS_ROOT_PATH} +) + +include(FindPackageHandleStandardArgs) +find_package_handle_standard_args(NSIS DEFAULT_MSG NSIS_MAKE) + +if (NSIS_MAKE) + set(NSIS_FOUND TRUE) +endif (NSIS_MAKE) + +mark_as_advanced(NSIS_MAKE) diff --git a/cmake/cmocka-1.1.7/cmake/Modules/MacroEnsureOutOfSourceBuild.cmake b/cmake/cmocka-1.1.7/cmake/Modules/MacroEnsureOutOfSourceBuild.cmake new file mode 100644 index 0000000..a2e9480 --- /dev/null +++ b/cmake/cmocka-1.1.7/cmake/Modules/MacroEnsureOutOfSourceBuild.cmake @@ -0,0 +1,17 @@ +# - MACRO_ENSURE_OUT_OF_SOURCE_BUILD() +# MACRO_ENSURE_OUT_OF_SOURCE_BUILD() + +# Copyright (c) 2006, Alexander Neundorf, +# +# Redistribution and use is allowed according to the terms of the BSD license. +# For details see the accompanying COPYING-CMAKE-SCRIPTS file. + +macro (MACRO_ENSURE_OUT_OF_SOURCE_BUILD _errorMessage) + + string(COMPARE EQUAL "${CMAKE_SOURCE_DIR}" "${CMAKE_BINARY_DIR}" _insource) + if (_insource) + message(SEND_ERROR "${_errorMessage}") + message(FATAL_ERROR "Remove the file CMakeCache.txt in ${CMAKE_SOURCE_DIR} first.") + endif (_insource) + +endmacro (MACRO_ENSURE_OUT_OF_SOURCE_BUILD) diff --git a/cmake/cmocka-1.1.7/cmake/Toolchain-Debian-mips.cmake b/cmake/cmocka-1.1.7/cmake/Toolchain-Debian-mips.cmake new file mode 100644 index 0000000..d9c9d9f --- /dev/null +++ b/cmake/cmocka-1.1.7/cmake/Toolchain-Debian-mips.cmake @@ -0,0 +1,21 @@ +include(CMakeForceCompiler) + +set(TOOLCHAIN_PREFIX mips-linux-gnu) + +set(CMAKE_SYSTEM_NAME Linux) +set(CMAKE_SYSTEM_VERSION 1) +set(CMAKE_SYSTEM_PROCESSOR mips) + +# This is the location of the mips toolchain +set(CMAKE_C_COMPILER ${TOOLCHAIN_PREFIX}-gcc) +set(CMAKE_CXX_COMPILER ${TOOLCHAIN_PREFIX}-g++) + +# This is the file system root of the target +set(CMAKE_FIND_ROOT_PATH /usr/${TOOLCHAIN_PREFIX}) + +# Search for programs in the build host directories +set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER) + +# For libraries and headers in the target directories +set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY) +set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY) diff --git a/cmake/cmocka-1.1.7/cmake/Toolchain-cross-m32.cmake b/cmake/cmocka-1.1.7/cmake/Toolchain-cross-m32.cmake new file mode 100644 index 0000000..7918c60 --- /dev/null +++ b/cmake/cmocka-1.1.7/cmake/Toolchain-cross-m32.cmake @@ -0,0 +1,23 @@ +set(CMAKE_C_FLAGS "-m32" CACHE STRING "C compiler flags" FORCE) +set(CMAKE_CXX_FLAGS "-m32" CACHE STRING "C++ compiler flags" FORCE) + +set(LIB32 /usr/lib) # Fedora + +if(EXISTS /usr/lib32) + set(LIB32 /usr/lib32) # Arch, Solus +endif() + +set(CMAKE_SYSTEM_LIBRARY_PATH ${LIB32} CACHE STRING "system library search path" FORCE) +set(CMAKE_LIBRARY_PATH ${LIB32} CACHE STRING "library search path" FORCE) + +# this is probably unlikely to be needed, but just in case +set(CMAKE_EXE_LINKER_FLAGS "-m32 -L${LIB32}" CACHE STRING "executable linker flags" FORCE) +set(CMAKE_SHARED_LINKER_FLAGS "-m32 -L${LIB32}" CACHE STRING "shared library linker flags" FORCE) +set(CMAKE_MODULE_LINKER_FLAGS "-m32 -L${LIB32}" CACHE STRING "module linker flags" FORCE) + +# on Fedora and Arch and similar, point pkgconfig at 32 bit .pc files. We have +# to include the regular system .pc files as well (at the end), because some +# are not always present in the 32 bit directory +if(EXISTS ${LIB32}/pkgconfig) + set(ENV{PKG_CONFIG_LIBDIR} ${LIB32}/pkgconfig:/usr/share/pkgconfig:/usr/lib/pkgconfig:/usr/lib64/pkgconfig) +endiF() diff --git a/cmake/cmocka-1.1.7/cmocka-build-tree-settings.cmake.in b/cmake/cmocka-1.1.7/cmocka-build-tree-settings.cmake.in new file mode 100644 index 0000000..d0883b1 --- /dev/null +++ b/cmake/cmocka-1.1.7/cmocka-build-tree-settings.cmake.in @@ -0,0 +1,3 @@ +set_and_check(CMOCKA_INLUDE_DIR @PROJECT_SOURCE_DIR@/include) +set_and_check(CMOCKA_LIBRARY @PROJECT_BINARY_DIR@/src/@CMOCKA_LIBRARY_NAME@) +set_and_check(CMOCKA_LIBRARIES @PROJECT_BINARY_DIR@/src/@CMOCKA_LIBRARY_NAME@) diff --git a/cmake/cmocka-1.1.7/cmocka.pc.cmake b/cmake/cmocka-1.1.7/cmocka.pc.cmake new file mode 100644 index 0000000..ee189c6 --- /dev/null +++ b/cmake/cmocka-1.1.7/cmocka.pc.cmake @@ -0,0 +1,11 @@ +# cmocka pkg-config source file + +prefix=@CMAKE_INSTALL_PREFIX@ +libdir=@CMAKE_INSTALL_FULL_LIBDIR@ +includedir=@CMAKE_INSTALL_FULL_INCLUDEDIR@ + +Name: @PROJECT_NAME@ +Description: The cmocka unit testing library +Version: @PROJECT_VERSION@ +Libs: -L${libdir} -lcmocka +Cflags: -I${includedir} diff --git a/cmake/cmocka-1.1.7/config.h.cmake b/cmake/cmocka-1.1.7/config.h.cmake new file mode 100644 index 0000000..55fc69f --- /dev/null +++ b/cmake/cmocka-1.1.7/config.h.cmake @@ -0,0 +1,173 @@ +/* Name of package */ +#cmakedefine PACKAGE "${PROJECT_NAME}" + +/* Version number of package */ +#cmakedefine VERSION "${PROJECT_VERSION}" + +#cmakedefine LOCALEDIR "${LOCALE_INSTALL_DIR}" +#cmakedefine DATADIR "${DATADIR}" +#cmakedefine LIBDIR "${LIBDIR}" +#cmakedefine PLUGINDIR "${PLUGINDIR}" +#cmakedefine SYSCONFDIR "${SYSCONFDIR}" +#cmakedefine BINARYDIR "${BINARYDIR}" +#cmakedefine SOURCEDIR "${SOURCEDIR}" + +/************************** HEADER FILES *************************/ + +/* Define to 1 if you have the header file. */ +#cmakedefine HAVE_ASSERT_H 1 + +/* Define to 1 if you have the header file. */ +#cmakedefine HAVE_DLFCN_H 1 + +/* Define to 1 if you have the header file. */ +#cmakedefine HAVE_INTTYPES_H 1 + +/* Define to 1 if you have the header file. */ +#cmakedefine HAVE_IO_H 1 + +/* Define to 1 if you have the header file. */ +#cmakedefine HAVE_MALLOC_H 1 + +/* Define to 1 if you have the header file. */ +#cmakedefine HAVE_MEMORY_H 1 + +/* Define to 1 if you have the header file. */ +#cmakedefine HAVE_SETJMP_H 1 + +/* Define to 1 if you have the header file. */ +#cmakedefine HAVE_SIGNAL_H 1 + +/* Define to 1 if you have the header file. */ +#cmakedefine HAVE_STDARG_H 1 + +/* Define to 1 if you have the header file. */ +#cmakedefine HAVE_STDDEF_H 1 + +/* Define to 1 if you have the header file. */ +#cmakedefine HAVE_STDINT_H 1 + +/* Define to 1 if you have the header file. */ +#cmakedefine HAVE_STDIO_H 1 + +/* Define to 1 if you have the header file. */ +#cmakedefine HAVE_STDLIB_H 1 + +/* Define to 1 if you have the header file. */ +#cmakedefine HAVE_STRINGS_H 1 + +/* Define to 1 if you have the header file. */ +#cmakedefine HAVE_STRING_H 1 + +/* Define to 1 if you have the header file. */ +#cmakedefine HAVE_SYS_STAT_H 1 + +/* Define to 1 if you have the header file. */ +#cmakedefine HAVE_SYS_TYPES_H 1 + +/* Define to 1 if you have the header file. */ +#cmakedefine HAVE_TIME_H 1 + +/* Define to 1 if you have the header file. */ +#cmakedefine HAVE_UNISTD_H 1 + +/**************************** STRUCTS ****************************/ + +#cmakedefine HAVE_STRUCT_TIMESPEC 1 + +/***************************** TYPES *****************************/ + +#cmakedefine HAVE_UINTPTR_T 1 + +/*************************** FUNCTIONS ***************************/ + +/* Define to 1 if you have the `calloc' function. */ +#cmakedefine HAVE_CALLOC 1 + +/* Define to 1 if you have the `exit' function. */ +#cmakedefine HAVE_EXIT 1 + +/* Define to 1 if you have the `fprintf' function. */ +#cmakedefine HAVE_FPRINTF 1 + +/* Define to 1 if you have the `snprintf' function. */ +#cmakedefine HAVE_SNPRINTF 1 + +/* Define to 1 if you have the `_snprintf' function. */ +#cmakedefine HAVE__SNPRINTF 1 + +/* Define to 1 if you have the `_snprintf_s' function. */ +#cmakedefine HAVE__SNPRINTF_S 1 + +/* Define to 1 if you have the `vsnprintf' function. */ +#cmakedefine HAVE_VSNPRINTF 1 + +/* Define to 1 if you have the `_vsnprintf' function. */ +#cmakedefine HAVE__VSNPRINTF 1 + +/* Define to 1 if you have the `_vsnprintf_s' function. */ +#cmakedefine HAVE__VSNPRINTF_S 1 + +/* Define to 1 if you have the `free' function. */ +#cmakedefine HAVE_FREE 1 + +/* Define to 1 if you have the `longjmp' function. */ +#cmakedefine HAVE_LONGJMP 1 + +/* Define to 1 if you have the `siglongjmp' function. */ +#cmakedefine HAVE_SIGLONGJMP 1 + +/* Define to 1 if you have the `malloc' function. */ +#cmakedefine HAVE_MALLOC 1 + +/* Define to 1 if you have the `memcpy' function. */ +#cmakedefine HAVE_MEMCPY 1 + +/* Define to 1 if you have the `memset' function. */ +#cmakedefine HAVE_MEMSET 1 + +/* Define to 1 if you have the `printf' function. */ +#cmakedefine HAVE_PRINTF 1 + +/* Define to 1 if you have the `setjmp' function. */ +#cmakedefine HAVE_SETJMP 1 + +/* Define to 1 if you have the `signal' function. */ +#cmakedefine HAVE_SIGNAL 1 + +/* Define to 1 if you have the `snprintf' function. */ +#cmakedefine HAVE_SNPRINTF 1 + +/* Define to 1 if you have the `strcmp' function. */ +#cmakedefine HAVE_STRCMP 1 + +/* Define to 1 if you have the `strcpy' function. */ +#cmakedefine HAVE_STRCPY 1 + +/* Define to 1 if you have the `vsnprintf' function. */ +#cmakedefine HAVE_VSNPRINTF 1 + +/* Define to 1 if you have the `strsignal' function. */ +#cmakedefine HAVE_STRSIGNAL 1 + +/* Define to 1 if you have the `clock_gettime' function. */ +#cmakedefine HAVE_CLOCK_GETTIME 1 + +/**************************** OPTIONS ****************************/ + +/* Check if we have TLS support with GCC */ +#cmakedefine HAVE_GCC_THREAD_LOCAL_STORAGE 1 + +/* Check if we have TLS support with MSVC */ +#cmakedefine HAVE_MSVC_THREAD_LOCAL_STORAGE 1 + +/* Check if we have CLOCK_REALTIME for clock_gettime() */ +#cmakedefine HAVE_CLOCK_REALTIME 1 + +/*************************** ENDIAN *****************************/ + +#cmakedefine WORDS_SIZEOF_VOID_P ${WORDS_SIZEOF_VOID_P} + +/* Define WORDS_BIGENDIAN to 1 if your processor stores words with the most + significant byte first (like Motorola and SPARC, unlike Intel). */ +#cmakedefine WORDS_BIGENDIAN 1 diff --git a/cmake/cmocka-1.1.7/coverity/README b/cmake/cmocka-1.1.7/coverity/README new file mode 100644 index 0000000..7756137 --- /dev/null +++ b/cmake/cmocka-1.1.7/coverity/README @@ -0,0 +1,9 @@ +coverity_assert_model.c: + +This file is a Coverity Modeling file for projects using CMocka for unit +testing. The assert functiions could create false positives, to avoid that you +can load this modeling file in the Coverity web interface. + +coverity_internal_model.c: + +This file is for the CMocka source code itself. diff --git a/cmake/cmocka-1.1.7/coverity/coverity_assert_model.c b/cmake/cmocka-1.1.7/coverity/coverity_assert_model.c new file mode 100644 index 0000000..7ff64d8 --- /dev/null +++ b/cmake/cmocka-1.1.7/coverity/coverity_assert_model.c @@ -0,0 +1,156 @@ +#define LargestIntegralType unsigned long long + + +void _assert_true(const LargestIntegralType result, + const char* const expression, + const char * const file, const int line) +{ + if (!result) { + __coverity_panic__(); + } +} + +void _assert_int_equal( + const LargestIntegralType a, const LargestIntegralType b, + const char * const file, const int line) +{ + if (a != b) { + __coverity_panic__(); + } +} + +void _assert_int_not_equal( + const LargestIntegralType a, const LargestIntegralType b, + const char * const file, const int line) +{ + if (a == b) { + __coverity_panic__(); + } +} + +void _assert_return_code(const LargestIntegralType result, + size_t rlen, + const LargestIntegralType error, + const char * const expression, + const char * const file, + const int line) +{ + if (result != 0) { + __coverity_panic__(); + } +} + +void _assert_string_equal(const char * const a, const char * const b, + const char * const file, const int line) +{ + char ch; + int cmp; + + __coverity_weak_guard_sink__(a, b); + __coverity_weak_guard_sink__(b, a); + + ch = *((char *)a); + ch = *((char *)b); + + if (cmp != 0) { + __coverity_panic__(); + } +} + +void _assert_string_not_equal(const char * const a, const char * const b, + const char *file, const int line) +{ + char ch; + int cmp; + + __coverity_weak_guard_sink__(a, b); + __coverity_weak_guard_sink__(b, a); + + ch = *((char *)a); + ch = *((char *)b); + + if (cmp == 0) { + __coverity_panic__(); + } +} + +void _assert_memory_equal(const void * const a, const void * const b, + const size_t size, const char* const file, + const int line) +{ + unsigned char ch; + int cmp; + + __coverity_weak_guard_sink__(a, b); + __coverity_weak_guard_sink__(b, a); + + ch = *((unsigned char *)a); + ch = *((unsigned char *)b); + + if (cmp != 0) { + __coverity_panic__(); + } +} + +void _assert_memory_not_equal(const void * const a, const void * const b, + const size_t size, const char* const file, + const int line) +{ + unsigned char ch; + int cmp; + + __coverity_weak_guard_sink__(a, b); + __coverity_weak_guard_sink__(b, a); + + ch = *((unsigned char *)a); + ch = *((unsigned char *)b); + + if (cmp == 0) { + __coverity_panic__(); + } +} + +void _assert_in_range( + const LargestIntegralType value, const LargestIntegralType minimum, + const LargestIntegralType maximum, const char* const file, const int line) +{ + if (value < minimum || value > maximum) { + __coverity_panic__(); + } +} + +void _assert_not_in_range( + const LargestIntegralType value, const LargestIntegralType minimum, + const LargestIntegralType maximum, const char* const file, const int line) +{ + if (value > minimum && value < maximum) { + __coverity_panic__(); + } +} + +void _assert_in_set( + const LargestIntegralType value, const LargestIntegralType values[], + const size_t number_of_values, const char* const file, const int line) +{ + size_t i; + + for (i = 0; i < number_of_values; i++) { + if (value == values[i]) { + return; + } + } + __coverity_panic__(); +} + +void _assert_not_in_set( + const LargestIntegralType value, const LargestIntegralType values[], + const size_t number_of_values, const char* const file, const int line) +{ + size_t i; + + for (i = 0; i < number_of_values; i++) { + if (value == values[i]) { + __coverity_panic__(); + } + } +} diff --git a/cmake/cmocka-1.1.7/coverity/coverity_internal_model.c b/cmake/cmocka-1.1.7/coverity/coverity_internal_model.c new file mode 100644 index 0000000..fd1416d --- /dev/null +++ b/cmake/cmocka-1.1.7/coverity/coverity_internal_model.c @@ -0,0 +1,5 @@ +/* Functions to help coverity do static analysis on cmocka */ +void exit_test(const int quit_application) +{ + __coverity_panic__(); +} diff --git a/cmake/cmocka-1.1.7/doc/CMakeLists.txt b/cmake/cmocka-1.1.7/doc/CMakeLists.txt new file mode 100644 index 0000000..6ac7494 --- /dev/null +++ b/cmake/cmocka-1.1.7/doc/CMakeLists.txt @@ -0,0 +1,45 @@ +# +# Build the documentation +# +if (${CMAKE_VERSION} VERSION_GREATER "3.8.99") + +find_package(Doxygen) + +if (DOXYGEN_FOUND) + set(DOXYGEN_PROJECT_NAME ${PROJECT_NAME}) + set(DOXYGEN_PROJECT_NUMBER ${PROJECT_VERSION}) + set(DOXYGEN_PROJECT_BRIEF "Unit testing library with mock support") + + set(DOXYGEN_TAB_SIZE 4) + set(DOXYGEN_OPTIMIZE_OUTPUT_FOR_C YES) + set(DOXYGEN_MARKDOWN_SUPPORT YES) + + set(DOXYGEN_PREDEFINED DOXYGEN + CMOCKA_PRINTF_ATTRIBUTE(x,y)) + + set(DOXYGEN_EXCLUDE ${CMAKE_CURRENT_SOURCE_DIR}/that_style) + set(DOXYGEN_HTML_HEADER ${CMAKE_CURRENT_SOURCE_DIR}/that_style/header.html) + set(DOXYGEN_HTML_EXTRA_STYLESHEET ${CMAKE_CURRENT_SOURCE_DIR}/that_style/that_style.css) + set(DOXYGEN_HTML_EXTRA_FILES ${CMAKE_CURRENT_SOURCE_DIR}/that_style/img/nav_edge_left.svg + ${CMAKE_CURRENT_SOURCE_DIR}/that_style/img/nav_edge_right.svg + ${CMAKE_CURRENT_SOURCE_DIR}/that_style/img/nav_edge_inter.svg + ${CMAKE_CURRENT_SOURCE_DIR}/that_style/img/sync_off.png + ${CMAKE_CURRENT_SOURCE_DIR}/that_style/img/sync_on.png + ${CMAKE_CURRENT_SOURCE_DIR}/that_style/img/splitbar_handle.svg + ${CMAKE_CURRENT_SOURCE_DIR}/that_style/img/doc.svg + ${CMAKE_CURRENT_SOURCE_DIR}/that_style/img/mag_glass.svg + ${CMAKE_CURRENT_SOURCE_DIR}/that_style/img/folderclosed.svg + ${CMAKE_CURRENT_SOURCE_DIR}/that_style/img/folderopen.svg + ${CMAKE_CURRENT_SOURCE_DIR}/that_style/js/striped_bg.js) + + set(_doxyfile_template "${CMAKE_BINARY_DIR}/CMakeDoxyfile.in") + set(_target_doxyfile "${CMAKE_CURRENT_BINARY_DIR}/Doxyfile.docs") + configure_file("${_doxyfile_template}" "${_target_doxyfile}") + + doxygen_add_docs(docs + ${cmocka-library_SOURCE_DIR} + ${cmocka-header_SOURCE_DIR} + ${CMAKE_CURRENT_SOURCE_DIR}) +endif(DOXYGEN_FOUND) + +endif() # CMAKE_VERSION diff --git a/cmake/cmocka-1.1.7/doc/mainpage.dox b/cmake/cmocka-1.1.7/doc/mainpage.dox new file mode 100644 index 0000000..144971d --- /dev/null +++ b/cmake/cmocka-1.1.7/doc/mainpage.dox @@ -0,0 +1,134 @@ +/** + +@mainpage + +This is the online reference for developing with the cmocka library. It +documents the cmocka C API. + +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. + +http://cmocka.org/ + +@section main-features Features + +Tests written with cmocka are compiled into stand-alone executables and linked with the +CMock library, the standard C library and module being tested. Any symbols +external to the module being tested should be mocked - replaced with functions +that return values determined by the test - within the test application. Even +though significant differences may exist between the target execution +environment of a code module and the environment used to test the code the unit +testing is still valid since its goal is to test the logic of a code modules at +a functional level and not necessarily all of its interactions with the target +execution environment. + +The CMocka library provides: + + - Support for mock objects. + - Test fixtures. + - Only requires a C library + - Exception handling for signals (SIGSEGV, SIGILL, ...) + - No use of fork() + - Very well tested + - Testing of memory leaks, buffer overflows and underflows. + - A set of assert macros. + - Several supported output formats (stdout, TAP, JUnit XML, Subunit) + - License: Apache License 2.0 + +@section main-test A cmocka test + +Test cases are functions with the signature void function(void **state). Test +applications initialize a table with test case function pointers using +unit_test() macros. This table is then passed to the run_tests() macro to +execute the tests. run_tests() sets up the appropriate exception / signal +handlers and other data structures prior to running each test function. When a +unit test is complete run_tests() performs various checks to determine whether +the test succeeded. + +@code +#include +#include +#include +#include +#include + +/* A test case that does nothing and succeeds. */ +static void null_test_success(void **state) { + (void) state; /* unused */ +} + +int main(void) { + const struct CMUnitTest tests[] = { + cmocka_unit_test(null_test_success), + }; + + return cmocka_run_group_tests(tests, NULL, NULL); +} +@endcode + +@section main-mock Mock objects + +You may already have heard the term "Mock Object". It describes a special case +of an object that mimics a real instance of an interface in order to provide +enough of that interface for testing. While there are several unit testing +frameworks that already provide some easy to use interface for creating +different kinds of "fake" objects for testing, there may be some confusion in +terms of how these test objects are programmed and what the behavioral +differences are between them. + +Mock objects include some logic and the test driver is able to modify the +behaviour and state. The object can call some functions or act on different +input (abort a test if it is wrong). The test driver injects what it expects +the mock object to return. CMocka provides an API to easily mock code. + +Check out the examples here. + +@section main-embedded Embedded platforms + +It is possible that some embedded platforms do not provide definitions for +required types or that the guards to protect them are not defined. To address +this issue you can create a header file name 'cmocka_platform.h' with the +required types and definitions. After that point cmake to the include directory +using: + +
+    cmake -DCMOCKA_PLATFORM_INCLUDE=/home/compiler/my/include_directory ..
+
+ +@section main-threads Threading + +cmocka is not fully thread safe and it is not the goal of it to be it. We have +several global variables to track test states. They are marked as thread local +but it is possible that you still run into issues. However if you use cmocka +for writing tests in an application which uses threads, you can set the +following envionment variable: + +
+    CMOCKA_TEST_ABORT='1' ./my_threading_test
+
+ +With this environment variable set to '1', cmocka will call abort() if +a test fails. + +@section main-output Output formats + +By default, cmocka prints human-readable test output to stderr. It is +possible to configure several other output formats. The configuration is +done using the CMOCKA_MESSAGE_OUTPUT environment variable. The +supported values are: + - STDOUT for the default standard output printer + - SUBUNIT for subunit output + - TAP for Test Anything Protocol (TAP) output + - XML for JUnit XML format +The case doesn't matter. + +The XML output goes to stderr by default. If the environment variable +CMOCKA_XML_FILE exists and the file specified by this variable +doesn't exist yet, then cmocka will put the output to this file. Note +that if you are have several groups you should set CMOCKA_XML_FILE +to CMOCKA_XML_FILE=cm_%%g.xml. In this %g will be replaced by +the group_name of the test and a file will be created for each group, +othwerwise all groups will be printed into the same file. + +*/ diff --git a/cmake/cmocka-1.1.7/doc/that_style/LICENSE b/cmake/cmocka-1.1.7/doc/that_style/LICENSE new file mode 100644 index 0000000..eac42e7 --- /dev/null +++ b/cmake/cmocka-1.1.7/doc/that_style/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2017 Jan-Lukas Wynen + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/cmake/cmocka-1.1.7/doc/that_style/README.md b/cmake/cmocka-1.1.7/doc/that_style/README.md new file mode 100644 index 0000000..7572720 --- /dev/null +++ b/cmake/cmocka-1.1.7/doc/that_style/README.md @@ -0,0 +1,22 @@ +# that style +A plain, more modern HTML style for Doxygen + +## Requirements +- Doxygen (tested with version 1.8.13) +- *optional*: a sass/scss compiler if you want to modify the style + +## Simple usage +Tell Doxygen about the files for that style as shown in [doxyfile.conf](doxyfile.conf). You might need to adjust the +paths depending on where you installed that style. +When you run Doxygen, all files are copied into to generated HTML folder. So you don't need to keep the originals around +unless you want to re-generate the documentation. + +## Advanced +that style uses a custom javascript to hack some nice stripes into some tables. It has to be loaded from HTML. Hence you need +to use the provided custom header. Since its default content may change when Doxygen is updated, there might be syntax error in +the generated HTML. If this is the case, you can remove the custom header (adjust your doxyfile.conf). This has no +disadvantages other than removing the stripes. + +[that_style.css](that_style.css) was generated from the scss files in the folder [sass](sass). If you want to change the style, +use those files in order to have better control. For instance, you can easily change most colors by modifying the variables +in the beginning of [that_style.scss](sass/that_style.scss). diff --git a/cmake/cmocka-1.1.7/doc/that_style/header.html b/cmake/cmocka-1.1.7/doc/that_style/header.html new file mode 100644 index 0000000..3da4639 --- /dev/null +++ b/cmake/cmocka-1.1.7/doc/that_style/header.html @@ -0,0 +1,56 @@ + + + + + + + +$projectname: $title +$title + + + +$treeview +$search +$mathjax + + +$extrastylesheet + + +
+ + +
+ + + + + + + + + + + + + + + + + + + + + +
+
$projectname +  $projectnumber +
+
$projectbrief
+
+
$projectbrief
+
$searchbox
+
+ + diff --git a/cmake/cmocka-1.1.7/doc/that_style/img/doc.svg b/cmake/cmocka-1.1.7/doc/that_style/img/doc.svg new file mode 100644 index 0000000..68e1ba0 --- /dev/null +++ b/cmake/cmocka-1.1.7/doc/that_style/img/doc.svg @@ -0,0 +1,97 @@ + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + diff --git a/cmake/cmocka-1.1.7/doc/that_style/img/folderclosed.svg b/cmake/cmocka-1.1.7/doc/that_style/img/folderclosed.svg new file mode 100644 index 0000000..e53ec90 --- /dev/null +++ b/cmake/cmocka-1.1.7/doc/that_style/img/folderclosed.svg @@ -0,0 +1,77 @@ + + + + + + + + + + image/svg+xml + + + + + + + + + + diff --git a/cmake/cmocka-1.1.7/doc/that_style/img/folderopen.svg b/cmake/cmocka-1.1.7/doc/that_style/img/folderopen.svg new file mode 100644 index 0000000..1ab7b78 --- /dev/null +++ b/cmake/cmocka-1.1.7/doc/that_style/img/folderopen.svg @@ -0,0 +1,83 @@ + + + + + + + + + + image/svg+xml + + + + + + + + + + + diff --git a/cmake/cmocka-1.1.7/doc/that_style/img/mag_glass.svg b/cmake/cmocka-1.1.7/doc/that_style/img/mag_glass.svg new file mode 100644 index 0000000..e21a004 --- /dev/null +++ b/cmake/cmocka-1.1.7/doc/that_style/img/mag_glass.svg @@ -0,0 +1,73 @@ + + + + + + + + + + image/svg+xml + + + + + + + + + + diff --git a/cmake/cmocka-1.1.7/doc/that_style/img/nav_edge_inter.svg b/cmake/cmocka-1.1.7/doc/that_style/img/nav_edge_inter.svg new file mode 100644 index 0000000..f04f10f --- /dev/null +++ b/cmake/cmocka-1.1.7/doc/that_style/img/nav_edge_inter.svg @@ -0,0 +1,73 @@ + + + + + + + + + + image/svg+xml + + + + + + + + + + diff --git a/cmake/cmocka-1.1.7/doc/that_style/img/nav_edge_left.svg b/cmake/cmocka-1.1.7/doc/that_style/img/nav_edge_left.svg new file mode 100644 index 0000000..ca1adf4 --- /dev/null +++ b/cmake/cmocka-1.1.7/doc/that_style/img/nav_edge_left.svg @@ -0,0 +1,73 @@ + + + + + + + + + + image/svg+xml + + + + + + + + + + diff --git a/cmake/cmocka-1.1.7/doc/that_style/img/nav_edge_right.svg b/cmake/cmocka-1.1.7/doc/that_style/img/nav_edge_right.svg new file mode 100644 index 0000000..bb33815 --- /dev/null +++ b/cmake/cmocka-1.1.7/doc/that_style/img/nav_edge_right.svg @@ -0,0 +1,73 @@ + + + + + + + + + + image/svg+xml + + + + + + + + + + diff --git a/cmake/cmocka-1.1.7/doc/that_style/img/splitbar_handle.svg b/cmake/cmocka-1.1.7/doc/that_style/img/splitbar_handle.svg new file mode 100644 index 0000000..e0dc90d --- /dev/null +++ b/cmake/cmocka-1.1.7/doc/that_style/img/splitbar_handle.svg @@ -0,0 +1,120 @@ + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + diff --git a/cmake/cmocka-1.1.7/doc/that_style/img/sync_off.png b/cmake/cmocka-1.1.7/doc/that_style/img/sync_off.png new file mode 100644 index 0000000000000000000000000000000000000000..9d286d9c4a0f0794a1513a66940fa3806e1edfa4 GIT binary patch literal 483 zcmV<90UZ8`P)P000>X1^@s6#OZ}&00004b3#c}2nYxW zdJDl(R&6zpOuXTLI5Ph^8 zs5zlG_>EB^9&pqYU|0D25$@2#O?zc znSk9Yz#2|5z=iTAC$(@E^Uret&#Kg0VJ!#3+LrB#g?Q}Jq z?xOWfz_RhENRb7AZyA83E-rcoqoPa)_!|rT!ghTBz5uwzyZ;3w9h!91(~yH{6&P)P000>X1^@s6#OZ}&00004b3#c}2nYxW zdb59GQHz)^?hKh+O=l*#f4GpDxtuTGoO_1pvx=YSql;#O znj_i74F-kvgfFQ84dLGpaE}hIvg^NSO$#U*JmPb9{~i8FU=$ndM$bPOHQK2QSP+`~ zJO=O@s9P5@TPU(!vbU2#`c;d+H#E3JyJY{aU^) always start with even + if ($(this).is(".heading")) { + counter = 0; + } + + // add extra classes + if (counter % 2 == 1) { + $(this).addClass("odd"); + } + else { + $(this).addClass("even"); + } + + // advance counter at every separator + // this is the only way to reliably detect which table rows belong together + if ($(this).is('[class^="separator"]')) { + counter++; + } + }); + } +} + +// execute the function +$(document).ready(new MemberDeclsStriper().stripe); diff --git a/cmake/cmocka-1.1.7/doc/that_style/that_style.css b/cmake/cmocka-1.1.7/doc/that_style/that_style.css new file mode 100644 index 0000000..846353c --- /dev/null +++ b/cmake/cmocka-1.1.7/doc/that_style/that_style.css @@ -0,0 +1,1431 @@ +@charset "UTF-8"; +/* + * My own little style + */ +body, table, div, p, dl { + font: 400 14px/22px Roboto,sans-serif; } + +h1.groupheader { + font-size: 150%; } + +.title { + font: 400 14px/28px Roboto,sans-serif; + font-size: 150%; + font-weight: bold; + margin: 10px 2px; } + +h2.groupheader { + border-bottom: 1px solid #555555; + color: black; + font-size: 200%; + font-weight: bold; + margin-top: 1.75em; + padding-top: 1em; + padding-bottom: 4px; + width: 100%; } + +tr.heading h2 { + border-bottom: 1px solid #a5a5a5; + font-size: 150%; + margin-top: 6px; + margin-bottom: 6px; + padding-top: 3px; + padding-bottom: 7px; } + +h2.groupheader a { + margin-left: 1%; } + +h3.groupheader { + font-size: 100%; } + +h1, h2, h3, h4, h5, h6 { + -webkit-transition: none; + -moz-transition: none; + -o-transition: none; + transition: none; + margin-right: 15px; } + h1.glow, h2.glow, h3.glow, h4.glow, h5.glow, h6.glow { + text-shadow: none; + color: #5f082b; } + +dt { + font-weight: bold; } + +div.multicol { + -moz-column-gap: 1em; + -webkit-column-gap: 1em; + -moz-column-count: 3; + -webkit-column-count: 3; } + +p.startli, p.startdd { + margin-top: 2px; } + +p.starttd { + margin-top: 0px; } + +p.endli { + margin-bottom: 0px; } + +p.enddd { + margin-bottom: 4px; } + +p.endtd { + margin-bottom: 2px; } + +#top { + border: none; + position: relative; + z-index: 100; + -moz-box-shadow: 0 0 4px rgba(0, 0, 0, 0.4), 0 0 8px rgba(0, 0, 0, 0.3); + -webkit-box-shadow: 0 0 4px rgba(0, 0, 0, 0.4), 0 0 8px rgba(0, 0, 0, 0.3); + -o-box-shadow: 0 0 4px rgba(0, 0, 0, 0.4), 0 0 8px rgba(0, 0, 0, 0.3); + box-shadow: 0 0 4px rgba(0, 0, 0, 0.4), 0 0 8px rgba(0, 0, 0, 0.3); } + +caption { + font-weight: bold; } + +span.legend { + font-size: 70%; + text-align: center; } + +h3.version { + font-size: 90%; + text-align: center; } + +div.qindex, div.navtab { + background-color: #ffffff; + border: none; + text-align: center; } + +div.qindex, div.navpath { + width: 100%; + line-height: 140%; } + +div.navtab { + margin-right: 15px; } + +a, a:visited { + color: #00549f; + font-weight: normal; + text-decoration: none; } + +.contents a:visited { + color: #4665A2; } + +a:hover { + text-decoration: underline; } + +a.qindex { + font-weight: bold; + text-transform: uppercase; } + +a.qindexHL { + font-weight: bold; + background-color: #9CAFD4; + color: #ffffff; + border: 1px double #869DCA; } + +.contents a.qindexHL:visited { + color: #ffffff; } + +a.el, a.el:visited { + font-weight: normal; + color: #00549f; } + +a.elRef, a.elRef:visited { + font-family: monospace; + color: #006bc8; } + +/* + * The main menu at the top + */ +#main-menu { + background-image: none; + background: #414141; + padding: 0; } + +.sm-dox > li:not(:last-child) > a { + background-image: none; + text-shadow: none; + color: white; + font-weight: normal; + letter-spacing: 1px; + font-size: 11pt; + text-transform: uppercase; } + +.sm-dox > li:not(:last-child) > a:hover, +.sm-dox > li:not(:last-child) > a.highlighted { + background-color: #5f082b; } + +.sm-dox a span.sub-arrow { + border-color: white transparent transparent; } + +.sm-dox ul { + border: none; + -moz-border-radius: 0 !important; + -webkit-border-radius: 0 !important; + border-radius: 0 !important; + padding: 0; + background: #414141; + -moz-box-shadow: 0 0 4px rgba(0, 0, 0, 0.35), 0 0 8px rgba(0, 0, 0, 0.2); + -webkit-box-shadow: 0 0 4px rgba(0, 0, 0, 0.35), 0 0 8px rgba(0, 0, 0, 0.2); + -o-box-shadow: 0 0 4px rgba(0, 0, 0, 0.35), 0 0 8px rgba(0, 0, 0, 0.2); + box-shadow: 0 0 4px rgba(0, 0, 0, 0.35), 0 0 8px rgba(0, 0, 0, 0.2); } + .sm-dox ul a { + background: inherit; + color: white; + font-weight: normal; + letter-spacing: 1px; + font-size: 11pt; } + .sm-dox ul a:hover { + background: #5f082b; + color: white; + font-weight: normal; + letter-spacing: 1px; + font-size: 11pt; } + .sm-dox ul a.highlighted { + background: #5f082b; + color: white; + font-weight: normal; + letter-spacing: 1px; + font-size: 11pt; } + .sm-dox ul a span.sub-arrow { + /* this sets the color of the arrow */ + border-color: white transparent transparent; } + +dl.el { + margin-left: -1cm; } + +div.ah, span.ah { + background: none; + color: black; + margin-bottom: 3px; + margin-top: 3px; + padding: 0.2em; + border: none; + -moz-border-radius: 0; + -webkit-border-radius: 0; + border-radius: 0; + -moz-box-shadow: none; + -webkit-box-shadow: none; + -o-box-shadow: none; + box-shadow: none; + font: 14pt monospace; + font-weight: bold; + text-transform: uppercase; } + +div.classindex ul { + list-style: none; + padding-left: 0; } + +div.classindex span.ai { + display: inline-block; } + +div.groupHeader { + margin-left: 16px; + margin-top: 12px; + font-weight: bold; } + +div.groupText { + margin-left: 16px; + font-style: italic; } + +body { + background-color: #ffffff; + color: black; + margin: 0; } + +#doc-content { + background-color: #111; + color: #ffffff; } + +div.contents { + color: black; + background-color: #ffffff; + padding: 0; + margin: 5pt; } + div.contents hr { + display: none; + visibility: hidden; } + +div.header + div.contents { + padding: 1ex; + margin: 0 5pt 5pt 5pt; } + +div.textblock { + padding: 1ex 1ex 0 1ex; } + +div.textblock + ul { + padding-bottom: 1%; } + +img.footer { + border: 0px; + vertical-align: middle; } + +/* + Basic styling for fragments shared by all themes. +*/ +div.fragment { + padding: 4px; + margin: 4px 8px 4px 2px; + color: #bebebe; + background-color: #323232; + border: 3px solid #e8e8e8; + border-radius: 2px; + overflow-y: hidden; + overflow-x: auto; + position: relative; } + +div.line { + font-family: monospace, fixed; + font-size: 13px; + min-height: 13px; + line-height: 1.0; + text-indent: -53px; + margin: 0px; + padding: 1px 0 1px 53px; + white-space: pre; + -webkit-transition: background-color; + -moz-transition: background-color; + -o-transition: background-color; + transition: background-color; + -webkit-duration: 0s; + -moz-duration: 0s; + -o-duration: 0s; + duration: 0s; } + div.line:hover { + background-color: #1a1a1a; } + div.line::after { + content: "\000A"; + white-space: pre; } + +span.lineno { + padding-right: 4px; + text-align: right; + color: black; + height: 100px; + white-space: pre; + border-right: 3px solid #1d7567; + background-color: #323232; } + +span.lineno a, span.lineno a:visited { + background-color: inherit; + color: #1e595a; } + +span.lineno a:hover { + background-color: #C8C8C8; + text-decoration: none; } + +.lineno { + -webkit-touch-callout: none; + -webkit-user-select: none; + -khtml-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; } + +div.fragment { + color: #bebebe; + background-color: #323232; } + +div.fragment::before { + background-color: #1a1a1a; + border-right: 1px solid #3e3e3e; } + +div.line:hover { + background-color: #1a1a1a; } + +span.lineno { + color: #969696; + background-color: #323232; + border-right: 1px solid #3e3e3e; } + +span.lineno a, span.lineno a:visited { + background-color: inherit; + color: #dcdcdc; } + +span.lineno a:hover { + background-color: #323232; } + +a.code, a.code:visited { + color: #6cc7eb; } + +a.codeRef, a.codeRef:visited { + color: #3d95e6; } + +span.keyword { + color: #98f77a; + font-weight: bold; } + +span.keywordtype { + color: #ffa0a0; } + +span.keywordflow { + color: #98f77a; + font-weight: bold; } + +span.comment { + color: #999; + font-style: oblique; } + +span.preprocessor { + color: #cd5c57; } + +span.stringliteral { + color: #64b041; } + +span.charliteral { + color: #64b041; } + +blockquote { + background-color: #F7F8FB; + border-left: 2px solid #9CAFD4; + margin: 0 24px 0 4px; + padding: 0 12px 0 16px; } + +/* + * The search box + */ +.sm-dox > li:last-child { + margin-right: 10pt; } + +#MSearchBox { + border: 2px inset black; + display: table; + width: 350px; + height: 26px; + background: white; + margin-top: 5px; } + #MSearchBox .left { + background-image: none; + display: table-cell; + width: 100%; + height: inherit; + left: 0; } + #MSearchBox .right { + background-image: none; + width: 0; + display: none; + visibility: hidden; } + +nav > #MSearchBox { + border: 2px solid #666666; + margin: 5px 10pt 0 0; + height: 22px; } + +#MSearchSelect, .left #MSearchSelect { + left: 0; + background-image: url("mag_glass.svg"); + width: 22px; + height: 22px; + padding: 22px 22px 0 0; + margin: 0 4px 0 4px; + box-sizing: border-box; } + +#MSearchField { + background-image: none; + display: table-cell; + margin: 0; + margin-left: 30px; + width: calc(100% - 34px); + height: 22px; + font: 11pt sans-serif; } + +#MSearchSelectWindow { + background-color: #414141; + padding: 0; + border: solid 1px black; + -moz-border-radius: 0; + -webkit-border-radius: 0; + border-radius: 0; + -moz-box-shadow: 0 0 4px rgba(0, 0, 0, 0.35), 0 0 8px rgba(0, 0, 0, 0.2); + -webkit-box-shadow: 0 0 4px rgba(0, 0, 0, 0.35), 0 0 8px rgba(0, 0, 0, 0.2); + -o-box-shadow: 0 0 4px rgba(0, 0, 0, 0.35), 0 0 8px rgba(0, 0, 0, 0.2); + box-shadow: 0 0 4px rgba(0, 0, 0, 0.35), 0 0 8px rgba(0, 0, 0, 0.2); } + +a.SelectItem { + color: white; + padding: 3px 4px; + font: 10pt sans-serif; + letter-spacing: 1px; } + a.SelectItem:hover { + background-color: #5f082b; + color: white; } + a.SelectItem:focus, a.SelectItem:active { + color: white; } + +#MSearchResultsWindow { + background-color: white; + -moz-box-shadow: 0 0 4px rgba(0, 0, 0, 0.35), 0 0 8px rgba(0, 0, 0, 0.2); + -webkit-box-shadow: 0 0 4px rgba(0, 0, 0, 0.35), 0 0 8px rgba(0, 0, 0, 0.2); + -o-box-shadow: 0 0 4px rgba(0, 0, 0, 0.35), 0 0 8px rgba(0, 0, 0, 0.2); + box-shadow: 0 0 4px rgba(0, 0, 0, 0.35), 0 0 8px rgba(0, 0, 0, 0.2); } + +table.memberdecls { + width: 100%; + border-spacing: 0px; + padding: 0px; + margin-top: 7px; + background-color: #ffffff; + -moz-box-shadow: 0 0 4px rgba(0, 0, 0, 0.35), 0 0 8px rgba(0, 0, 0, 0.2); + -webkit-box-shadow: 0 0 4px rgba(0, 0, 0, 0.35), 0 0 8px rgba(0, 0, 0, 0.2); + -o-box-shadow: 0 0 4px rgba(0, 0, 0, 0.35), 0 0 8px rgba(0, 0, 0, 0.2); + box-shadow: 0 0 4px rgba(0, 0, 0, 0.35), 0 0 8px rgba(0, 0, 0, 0.2); } + +.memberdecls tbody { + background-color: #ffffff; } + +.memberdecls .odd { + background: #f6f6f6; } + +/* all but last separator show a line */ +.memberdecls tr[class^="separator"]:not(:last-child) .memSeparator { + border-bottom: 1px solid #c5c5c5; + line-height: 1px; + margin: 0; + padding: 0; } + +.memberdecls tr[class^="separator"]:last-child .memSeparator { + border-bottom: none; + line-height: 0; + margin: 0; + padding: 0; } + +table.fieldtable { + -moz-border-radius: 0; + -webkit-border-radius: 0; + border-radius: 0; + -moz-box-shadow: none; + -webkit-box-shadow: none; + -o-box-shadow: none; + box-shadow: none; } + +.memberdecls td, .fieldtable tr { + background-color: inherit; } + +.fieldtable th { + display: none; + height: 0; + visibility: hidden; } + +td.fieldname { + color: #820a32; + font-family: monospace; + font-weight: bold; } + +th.markdownTableHeadLeft, th.markdownTableHeadRight, +th.markdownTableHeadCenter, th.markdownTableHeadNone { + background-color: #414141; + color: white; } + +.memItemLeft, .memItemRight, +.memTemplItemLeft, .memTemplItemRight, .memTemplParams { + font-family: monospace; + background-color: #ffffff; + border: none; + margin: 4px; + padding: 1px 0 0 8px; } + +.mdescLeft, .mdescRight { + background-color: #ffffff; + border: none; + margin: 4px; + padding: 1px 0 0 8px; } + +.mdescLeft, .mdescRight { + padding: 0px 8px 4px 8px; + color: #555; } + +.memItemLeft, .memTemplItemLeft { + white-space: nowrap; } + +.memItemRight { + width: 100%; } + +.memTemplParams { + color: black; + white-space: nowrap; + font-size: 100%; } + +/* Styles for detailed member documentation */ +.memtitle { + padding: 8px; + border: none; + margin-bottom: -1px; + background-image: none; + background-color: #f6f6f6; + line-height: 1.25; + font-weight: bold; + color: black; + float: left; + z-index: 0; + position: relative; + -moz-box-shadow: 0 0 4px rgba(0, 0, 0, 0.35), 0 0 8px rgba(0, 0, 0, 0.2); + -webkit-box-shadow: 0 0 4px rgba(0, 0, 0, 0.35), 0 0 8px rgba(0, 0, 0, 0.2); + -o-box-shadow: 0 0 4px rgba(0, 0, 0, 0.35), 0 0 8px rgba(0, 0, 0, 0.2); + box-shadow: 0 0 4px rgba(0, 0, 0, 0.35), 0 0 8px rgba(0, 0, 0, 0.2); } + +.permalink { + font-size: 100%; + display: inline-block; + vertical-align: middle; } + +/* replace content of permalinks */ +.permalink a { + visibility: hidden; } + +.permalink a:after { + content: "§"; + visibility: visible; + display: block; + position: absolute; + color: black; + top: 20%; } + +.permalink a:visited { + color: black; } + +.memtemplate { + font-size: 100%; + color: black; + font-family: monospace; + font-weight: normal; + margin-left: 9px; } + +.memnav { + background-color: #EBEFF6; + border: 1px solid #A3B4D7; + text-align: center; + margin: 2px; + margin-right: 15px; + padding: 2px; } + +.mempage { + width: 100%; } + +.memitem { + font-family: monospace; + padding: 0; + margin-bottom: 10px; + margin-right: 5px; + -webkit-transition: none; + -moz-transition: none; + -ms-transition: none; + -o-transition: none; + transition: none; + display: table !important; + width: 100%; + background-color: #f6f6f6; + -moz-box-shadow: 0 0 4px rgba(0, 0, 0, 0.35), 0 0 8px rgba(0, 0, 0, 0.2); + -webkit-box-shadow: 0 0 4px rgba(0, 0, 0, 0.35), 0 0 8px rgba(0, 0, 0, 0.2); + -o-box-shadow: 0 0 4px rgba(0, 0, 0, 0.35), 0 0 8px rgba(0, 0, 0, 0.2); + box-shadow: 0 0 4px rgba(0, 0, 0, 0.35), 0 0 8px rgba(0, 0, 0, 0.2); } + +.memitem.glow { + -moz-box-shadow: none; + -webkit-box-shadow: none; + -o-box-shadow: none; + box-shadow: none; } + +.memname { + font-family: monospace; + font-weight: 400; + margin-left: 6px; } + +.memname td { + vertical-align: bottom; } + +.memproto, dl.reflist dt { + border: none; + padding: 6px 0px 6px 0px; + color: black; + font-weight: bold; + text-shadow: none; + background-color: #f6f6f6; + position: relative; + z-index: 1; + -moz-box-shadow: none; + -webkit-box-shadow: none; + -o-box-shadow: none; + box-shadow: none; } + +.overload { + font-family: "courier new",courier,monospace; + font-size: 65%; } + +.memdoc, dl.reflist dd { + border: none; + border-left: 4px solid #5f082b; + border-bottom-left-radius: 0px; + border-bottom-right-radius: 0px; + -webkit-border-bottom-left-radius: 0px; + -webkit-border-bottom-right-radius: 0px; + -moz-border-bottom-left-radius: 0px; + -moz-border-bottom-right-radius: 0px; + padding: 2px 1% 2px 1%; + margin: 1%; + background-color: #ffffff; + background-image: none; + -moz-box-shadow: none; + -webkit-box-shadow: none; + -o-box-shadow: none; + box-shadow: none; + /* allow movement of elements inside */ + display: flex; + flex-direction: column; } + +/* overrides for docs on individual pages */ +.memtitle:nth-child(2) { + width: 0; + height: 0; + display: none; + visibility: hidden; } + +.memitem:nth-child(3) { + margin: 0; + margin-top: 0.5%; + background-color: #ffffff; + -moz-box-shadow: none; + -webkit-box-shadow: none; + -o-box-shadow: none; + box-shadow: none; } + +.memitem:nth-child(3) .memproto { + padding: 10px; + background-color: #ffffff; + margin-bottom: 10px; } + +.memitem:nth-child(3) .memproto::after { + content: ""; + width: 99%; + height: 1px; + position: absolute; + bottom: -10px; + left: 0.5%; + background: #666; } + +.memitem:nth-child(3) .memdoc { + border: none; + padding: 0; } + +.memitem:nth-child(3) table.memname { + background-color: #f6f6f6; + border-collapse: collapse; + border-spacing: initial; + border: 1px solid #aaa; } + +.memitem:nth-child(3) table.memname tr:not(:last-child) { + border-bottom: 1px dashed #aaa; } + +dl.reflist dt { + padding: 5px; + z-index: 0; + /* cover the top shadow of dd */ + position: relative; + -moz-box-shadow: 0 0 4px rgba(0, 0, 0, 0.35), 0 0 8px rgba(0, 0, 0, 0.2); + -webkit-box-shadow: 0 0 4px rgba(0, 0, 0, 0.35), 0 0 8px rgba(0, 0, 0, 0.2); + -o-box-shadow: 0 0 4px rgba(0, 0, 0, 0.35), 0 0 8px rgba(0, 0, 0, 0.2); + box-shadow: 0 0 4px rgba(0, 0, 0, 0.35), 0 0 8px rgba(0, 0, 0, 0.2); } + +/* cover up the shadow at the bottom */ +dl.reflist dt::after { + content: " "; + width: 100%; + display: block; + height: 8px; + position: absolute; + background-color: #f6f6f6; + left: 0; + bottom: -8px; } + +dl.reflist dd { + border-left: 4px solid #5f082b; + padding: 2px 1% 2px 1%; + margin: 8px 8px 24px 8px; + outline: 8px solid #f6f6f6; + -moz-box-shadow: 0 0 4px 8px rgba(0, 0, 0, 0.35), 0 0 8px 8px rgba(0, 0, 0, 0.2); + -webkit-box-shadow: 0 0 4px 8px rgba(0, 0, 0, 0.35), 0 0 8px 8px rgba(0, 0, 0, 0.2); + -o-box-shadow: 0 0 4px 8px rgba(0, 0, 0, 0.35), 0 0 8px 8px rgba(0, 0, 0, 0.2); + box-shadow: 0 0 4px 8px rgba(0, 0, 0, 0.35), 0 0 8px 8px rgba(0, 0, 0, 0.2); } + +dl.reflist dd p::before { + font-size: 85%; + content: "\25B6\00A0\00A0"; + display: inline-block; + width: 12pt; } + +dl.reflist dd p { + margin-top: 4px; + margin-bottom: 4px; } + +.paramkey { + text-align: right; } + +.paramtype { + font-family: monospace; + white-space: nowrap; + color: #002546; } + +.paramname { + color: black; + font-family: monospace; + white-space: nowrap; } + +.paramname em { + color: #820a32; + font-style: normal; } + +.paramname code { + color: #404040; + line-height: 14px; } + +.params, .retval, .exception, .tparams { + margin-left: 0; + padding-left: 0; + margin-bottom: -0.25em; } + +.params dt, .tparams dt { + margin-bottom: 0.5em; } + +.params .paramname, .tparams .paramname, .retval .paramname, .exception .paramname { + color: #820a32; + font-family: monospace; + font-weight: bold; + vertical-align: top; } + +.params .paramtype, .tparams .paramtype { + font-family: monospace; + font-style: italic; + vertical-align: top; } + +.params .paramdir, .tparams .paramdir { + font-family: "courier new",courier,monospace; + vertical-align: top; } + +/* line over parameters docs */ +.params, .tparams { + border-collapse: collapse; } + +.params tr, .tparams tr { + -moz-box-shadow: 0 -2px 0 -1px #606060; + -webkit-box-shadow: 0 -2px 0 -1px #606060; + -o-box-shadow: 0 -2px 0 -1px #606060; + box-shadow: 0 -2px 0 -1px #606060; } + +.params .paramname, .tparams .paramname { + border-top: 2px solid #5f082b; + padding-right: 5pt; } + +.params td, .tparams td { + padding-bottom: 1em; } + +table.mlabels { + border-spacing: 0px; } + +td.mlabels-left { + width: 100%; + padding: 0px; } + +td.mlabels-right { + vertical-align: bottom; + padding: 0px; + white-space: nowrap; } + +span.mlabels { + margin-left: 8px; } + +span.mlabel { + background-color: #444444; + border: none; + border-radius: 3px; + text-shadow: none; + color: white; + margin-right: 4px; + padding: 3px 5px; + font-size: 8pt; + white-space: nowrap; + vertical-align: middle; } + +.memdoc .definition { + position: relative; + padding-top: 0.5em; + /* move definition line to bottom of memdoc */ + order: 3; } + .memdoc .definition::before { + content: ""; + width: 33%; + height: 1px; + border-top: 1px solid black; + position: absolute; + top: 0; } + +table.directory { + border-top: 1px solid #c5c5c5; + border-bottom: 1px solid #c5c5c5; + border-collapse: collapse; + width: 100%; + font: 400 14px Roboto,sans-serif; } + table.directory tr { + background-color: white !important; } + table.directory tr.even { + background-color: #f6f6f6 !important; } + table.directory tr:hover { + background-color: #e6e6e6 !important; } + table.directory td.entry { + padding: 1.5pt 3pt 1.5pt 3pt; + white-space: normal; } + +div.directory { + border: none; } + div.directory table.directory tr { + line-height: 17pt; } + div.directory table.directory td { + margin: 0; + padding: 0.5pt 6pt 0.5pt 0; + vertical-align: middle; } + div.directory table.directory td.entry { + white-space: nowrap; } + div.directory table.directory td.desc { + width: 100%; + padding-left: 6pt; + border-left: 1px solid rgba(0, 0, 0, 0.05); } + +.directory .levels { + white-space: nowrap; + width: 100%; + text-align: right; + font-size: 9pt; } + .directory .levels span { + cursor: pointer; + padding-left: 2px; + padding-right: 2px; + color: #00549f; } + .directory .levels span:hover { + text-decoration: underline; } + +/* + * The tree view on the left + */ +.arrow { + color: black; + cursor: pointer; + font-size: 80%; + display: inline-block; + width: 16px; + height: 22px; + margin-left: 4px; + -webkit-user-select: none; + -khtml-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; } + .arrow:hover { + color: black; } + +#selected .arrow { + color: white; } + #selected .arrow:hover { + color: #d2d2d2; } + +#nav-tree { + background-image: none; + background-color: white; } + #nav-tree .item { + margin: 0; } + #nav-tree .item:hover { + background-color: #d2d2d2; } + #nav-tree .selected { + background-image: none; + background-color: #5f082b; + color: white; + text-shadow: none; } + #nav-tree .selected:hover { + background-image: none; + background-color: #5f082b; + color: white; + text-shadow: none; } + #nav-tree a { + color: black; } + +.ui-resizable-e { + background: #808080 url("splitbar_handle.svg") no-repeat center; + border-right: solid 1px #c0c0c0; + border-left: solid 1px black; } + .ui-resizable-e:hover { + background-color: #606060; } + +.icon { + font-family: monospace; + font-weight: bold; + font-size: 12px; + height: 15px; + width: 15px; + display: inline-block; + background-color: #444444; + color: white; + text-align: center; + border-radius: 3px; + margin: 0; + padding-top: 1px; + text-indent: -1px; } + +.icona { + width: 0; + height: 0; + display: none; + visibility: hidden; } + +.iconfopen { + width: 24px; + height: 18px; + margin-bottom: 4px; + background-image: url("folderopen.svg"); + background-position: 0; + background-repeat: no-repeat; + vertical-align: top; + display: inline-block; } + +.iconfclosed { + width: 24px; + height: 18px; + margin-bottom: 4px; + background-image: url("folderclosed.svg"); + background-position: 0; + background-repeat: no-repeat; + vertical-align: top; + display: inline-block; } + +.icondoc { + width: 24px; + height: 18px; + margin-bottom: 4px; + background-image: url("doc.svg"); + background-position: 0; + background-repeat: no-repeat; + vertical-align: top; + display: inline-block; } + +div.dynheader { + margin-top: 8px; + -webkit-touch-callout: none; + -webkit-user-select: none; + -khtml-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; } + +address { + font-style: normal; + color: #2A3D61; } + +table.doxtable caption { + caption-side: top; } + +table.doxtable { + border-collapse: collapse; + margin-top: 4px; + margin-bottom: 4px; } + +table.doxtable td, table.doxtable th { + border: 1px solid #444444; + padding: 3px 7px 2px; } + +table.doxtable th { + background-color: #444444; + color: #FFFFFF; + font-size: 110%; + padding-bottom: 4px; + padding-top: 5px; } + +/* + * The line at the bottom + */ +.navpath { + /* intermediate navelems */ + /* first navelem */ + /* last navelem */ } + .navpath ul { + font-size: 11px; + background-image: none; + height: 30px; + line-height: 30px; + color: black; + border: none; + border-top: 1px solid #808080; + overflow: hidden; + margin: 0px; + padding: 0px; } + .navpath li:not(:first-child) { + list-style-type: none; + float: left; + padding-left: 18px; + padding-right: 10px; + color: black; + background-color: white; + background-image: url("nav_edge_inter.svg"); + background-repeat: no-repeat; + background-position: left -1px; + background-size: auto 100%; } + .navpath li:first-child { + list-style-type: none; + float: left; + padding-left: 15px; + padding-right: 10px; + color: black; + background-color: white; + background-image: none; } + .navpath li:nth-last-child(2) { + list-style-type: none; + float: left; + padding-left: 10px; + padding-right: 15px; + color: white; + background-color: #5f082b; + background-image: url("nav_edge_right.svg"); + background-repeat: no-repeat; + background-position: right -1px; + background-size: auto 100%; } + .navpath li:nth-last-child(2):not(:first-child) { + list-style-type: none; + float: left; + padding-left: 15px; + padding-right: 15px; + color: white; + background-color: #5f082b; + background-image: url("nav_edge_left.svg"), url("nav_edge_right.svg"); + background-repeat: no-repeat; + background-position: -1px -1px, right -1px; + background-size: auto 100%; } + .navpath li.navelem a, .navpath .navpath li.navelem b { + height: 32px; + display: block; + text-decoration: none; + outline: none; + color: inherit; + font-family: Roboto,sans-serif; + text-shadow: none; + text-decoration: none; + font-weight: normal; } + .navpath li.navelem a:hover { + color: inherit; + text-decoration: underline; } + .navpath li.footer { + list-style-type: none; + float: right; + padding-left: 0; + padding-right: 10px; + background-color: #d5d5d5; + background-image: none; + color: black; + font-size: 8pt; } + .navpath li.footer:before { + content: ""; + width: 13px; + height: 30px; + display: inline-block; + float: left; + background-image: url("nav_edge_right.svg"); + background-repeat: no-repeat; + background-position: right 0; + background-size: auto 100%; + /* flip the element horizontally */ + -moz-transform: scaleX(-1); + -o-transform: scaleX(-1); + -webkit-transform: scaleX(-1); + transform: scaleX(-1); + filter: FlipH; + -ms-filter: "FlipH"; } + +div.summary { + -webkit-order: 2; + order: 2; + float: right; + font-size: 8pt; + padding-right: 5px; + width: 50%; + text-align: right; + margin-right: 0.5%; } + +div.summary a { + white-space: nowrap; } + +table.classindex { + margin: 10px; + white-space: nowrap; + margin-left: 1%; + margin-right: 1%; + width: 98%; + border: none; + border-top: 1px solid black; + border-bottom: 1px solid black; + border-spacing: 0.5em; + padding: 0; } + +div.ingroups { + font-size: 8pt; + width: 50%; + text-align: left; } + +div.ingroups a { + white-space: nowrap; } + +div.header { + display: -webkit-flex; + display: flex; + justify-content: space-between; + background-image: none; + background-color: #ffffff; + color: black; + margin: 5pt 5pt 0 5pt; + padding: 0 1ex 0 1ex; + align-items: center; + justify-content: center; + border-bottom: none; + position: relative; } + +div.header::after { + content: ""; + height: 2px; + width: 99%; + position: absolute; + bottom: -5px; + left: 0.5%; + background: #666; } + +div.headertitle { + -webkit-order: 1; + order: 1; + margin-right: auto; + text-align: center; } + +dl { + padding: 0; } + +dl.section { + margin-left: 0px; + padding-left: 0px; } + +dl.section > dt { + font-weight: bold; + font-family: sans-serif; } + +dl.note, dl.warning, dl.attention, dl.pre, dl.post, dl.invariant, +dl.deprecated, dl.todo, dl.test, dl.bug { + margin-left: -7px; + padding-left: 3px; } + +dl.note { + padding-left: 7px; + border: none; } + +dl.warning { + background-color: #ffe6ea; + border: 1px solid #ff0728; + border-left: 4px solid #ff0728; + padding-top: 4px; + padding-bottom: 3px; } + +dl.attention { + border-left: 4px solid #ff0728; } + +dl.pre, dl.post, dl.invariant { + background-color: #f0ffe6; + border: 1px solid #5eb82a; + border-left: 4px solid #5eb82a; } + +dl.deprecated { + background-color: #f6f6f6; + border: 1px solid black; } + +dl.todo { + border-left: 4px solid #e8d500; } + +dl.test { + border-left: 4px solid #00549f; } + +dl.bug { + background-color: #f6f6f6; + border: 1px solid #cc071e; + border-left: 4px solid #cc071e; } + +dl.section dd { + margin-bottom: 6px; } + +.memdoc dl dt a.el { + font-weight: bold; + color: black; } + +#projectlogo { + text-align: center; + vertical-align: bottom; + border-collapse: separate; } + +#projectlogo img { + border: 0px none; } + +#projectalign { + vertical-align: middle; } + +#projectname { + font: 300% Tahoma, Arial,sans-serif; + margin: 0px; + padding: 2px 0px; } + +#projectbrief { + font: 120% Tahoma, Arial,sans-serif; + margin: 0px; + padding: 0px; } + +#projectnumber { + font: 50% Roboto,sans-serif; + margin: 0px; + padding: 0px; } + +#titlearea { + padding: 0px; + margin: 0px; + width: 100%; + border-bottom: none; } + #titlearea:nth-last-child(2) { + border-bottom: 2px solid #444444; } + +.image { + text-align: center; } + +.dotgraph, .mscgraph, .diagraph { + text-align: center; } + +.caption { + font-weight: bold; } + +div.zoom { + border: 1px solid #90A5CE; } + +dl.citelist { + margin-bottom: 5ex; } + dl.citelist dt { + color: black; + float: left; + font-weight: bold; + padding: 5px 0; + margin: 2px 10pt 2px 0; } + dl.citelist dd { + margin: 2px 0; + padding: 5px 0; } + dl.citelist .startdd { + margin-top: 0; } + +div.toc { + background-color: transparent; + border: 1px solid #414141; + -moz-border-radius: 0; + -webkit-border-radius: 0; + border-radius: 0; + float: right; + height: auto; + margin: 0 8px 10px 10px; + padding: 10px 15px 5px 25px; + width: auto; } + div.toc li { + background: transparent; + font: 10pt Roboto,DejaVu Sans,sans-serif; + padding-left: 0; + padding-top: 0.5ex; } + div.toc li .level1 { + margin-left: 10pt; } + div.toc li .level2 { + margin-left: 10pt; } + div.toc li .level3 { + margin-left: 10pt; } + div.toc li .level4 { + margin-left: 10pt; } + div.toc h3 { + font: bold 12px/1.2 Roboto,DejaVu Sans,sans-serif; + color: black; + border-bottom: none; + margin: 0; + letter-spacing: 1px; } + div.toc ul { + list-style: disc; + border: none; + padding: 0; } + +.inherit_header { + font-weight: bold; + color: gray; + cursor: pointer; + -webkit-touch-callout: none; + -webkit-user-select: none; + -khtml-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; } + +.inherit_header td { + padding: 6px 0px 2px 5px; } + +.inherit { + display: none; } + +/* tooltip related style info */ +.ttc { + position: absolute; + display: none; } + +#powerTip { + cursor: default; + white-space: nowrap; + background-color: #ffffff; + border: 1px solid #323232; + border-radius: 0; + -moz-box-shadow: none; + -webkit-box-shadow: none; + -o-box-shadow: none; + box-shadow: none; + display: none; + font-size: smaller; + max-width: 80%; + opacity: 0.9; + padding: 1ex 1em 1em 1em; + position: absolute; + z-index: 2147483647; } + #powerTip div.ttdoc { + color: grey; + font-style: italic; } + #powerTip div.ttname a { + font-weight: bold; } + #powerTip div.ttname { + font-weight: bold; } + #powerTip div.ttdeci { + color: #006318; } + #powerTip div { + margin: 0px; + padding: 0px; + font: 12px/16px Roboto,sans-serif; } + #powerTip:before, #powerTip:after { + content: ""; + position: absolute; + margin: 0px; } + +@media print { + #top { + display: none; } + #side-nav { + display: none; } + #nav-path { + display: none; } + body { + overflow: visible; } + h1, h2, h3, h4, h5, h6 { + page-break-after: avoid; } + .summary { + display: none; } + .memitem { + page-break-inside: avoid; } + #doc-content { + margin-left: 0 !important; + height: auto !important; + width: auto !important; + overflow: inherit; + display: inline; + background-color: white; } } diff --git a/cmake/cmocka-1.1.7/example/CMakeLists.txt b/cmake/cmocka-1.1.7/example/CMakeLists.txt new file mode 100644 index 0000000..126a2e9 --- /dev/null +++ b/cmake/cmocka-1.1.7/example/CMakeLists.txt @@ -0,0 +1,57 @@ +project(cmocka-examples C) + +set_source_files_properties(calculator.c + allocate_module.c + assert_module.c + PROPERTIES + COMPILE_DEFINITIONS + UNIT_TESTING=1) + + +### The most simple test +add_cmocka_test(simple_test + SOURCES simple_test.c + COMPILE_OPTIONS ${DEFAULT_C_COMPILE_FLAGS} + LINK_OPTIONS ${DEFAULT_LINK_FLAGS} + LINK_LIBRARIES cmocka::cmocka) +add_cmocka_test_environment(simple_test) + +### Allocate module test +add_cmocka_test(allocate_module_test + SOURCES allocate_module.c allocate_module_test.c + COMPILE_OPTIONS ${DEFAULT_C_COMPILE_FLAGS} + LINK_OPTIONS ${DEFAULT_LINK_FLAGS} + LINK_LIBRARIES cmocka::cmocka) +add_cmocka_test_environment(allocate_module_test) + +set_tests_properties(allocate_module_test + PROPERTIES + WILL_FAIL 1) + +### Assert macro test +add_cmocka_test(assert_macro_test + SOURCES assert_macro.c assert_macro_test.c + COMPILE_OPTIONS ${DEFAULT_C_COMPILE_FLAGS} + LINK_OPTIONS ${DEFAULT_LINK_FLAGS} + LINK_LIBRARIES cmocka::cmocka) +add_cmocka_test_environment(assert_macro_test) + +set_tests_properties(assert_macro_test + PROPERTIES + WILL_FAIL 1) + +### Assert module test +add_cmocka_test(assert_module_test + SOURCES assert_module.c assert_module_test.c + COMPILE_OPTIONS ${DEFAULT_C_COMPILE_FLAGS} + LINK_OPTIONS ${DEFAULT_LINK_FLAGS} + LINK_LIBRARIES cmocka::cmocka) +add_cmocka_test_environment(assert_module_test) + +set_tests_properties(assert_module_test + PROPERTIES + WILL_FAIL 1) + +if (NOT WIN32) + add_subdirectory(mock) +endif() diff --git a/cmake/cmocka-1.1.7/example/allocate_module.c b/cmake/cmocka-1.1.7/example/allocate_module.c new file mode 100644 index 0000000..3c4fb49 --- /dev/null +++ b/cmake/cmocka-1.1.7/example/allocate_module.c @@ -0,0 +1,55 @@ +/* + * Copyright 2008 Google Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif +#ifdef HAVE_MALLOC_H +#include +#endif +#include +#include + +#ifdef UNIT_TESTING +extern void* _test_malloc(const size_t size, const char* file, const int line); +extern void* _test_calloc(const size_t number_of_elements, const size_t size, + const char* file, const int line); +extern void _test_free(void* const ptr, const char* file, const int line); + +#define malloc(size) _test_malloc(size, __FILE__, __LINE__) +#define calloc(num, size) _test_calloc(num, size, __FILE__, __LINE__) +#define free(ptr) _test_free(ptr, __FILE__, __LINE__) +#endif // UNIT_TESTING + +void leak_memory(void); +void buffer_overflow(void); +void buffer_underflow(void); + +void leak_memory(void) { + int * const temporary = (int*)malloc(sizeof(int)); + *temporary = 0; +} + +void buffer_overflow(void) { + char * const memory = (char*)malloc(sizeof(int)); + memory[sizeof(int)] = '!'; + free(memory); +} + +void buffer_underflow(void) { + char * const memory = (char*)malloc(sizeof(int)); + memory[-1] = '!'; + free(memory); +} diff --git a/cmake/cmocka-1.1.7/example/allocate_module_test.c b/cmake/cmocka-1.1.7/example/allocate_module_test.c new file mode 100644 index 0000000..562aea2 --- /dev/null +++ b/cmake/cmocka-1.1.7/example/allocate_module_test.c @@ -0,0 +1,53 @@ +/* + * Copyright 2008 Google Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#include +#include +#include +#include + +extern void leak_memory(void); +extern void buffer_overflow(void); +extern void buffer_underflow(void); + +/* Test case that fails as leak_memory() leaks a dynamically allocated block. */ +static void leak_memory_test(void **state) { + (void) state; /* unused */ + + leak_memory(); +} + +/* Test case that fails as buffer_overflow() corrupts an allocated block. */ +static void buffer_overflow_test(void **state) { + (void) state; /* unused */ + + buffer_overflow(); +} + +/* Test case that fails as buffer_underflow() corrupts an allocated block. */ +static void buffer_underflow_test(void **state) { + (void) state; /* unused */ + + buffer_underflow(); +} + +int main(void) { + const struct CMUnitTest tests[] = { + cmocka_unit_test(leak_memory_test), + cmocka_unit_test(buffer_overflow_test), + cmocka_unit_test(buffer_underflow_test), + }; + return cmocka_run_group_tests(tests, NULL, NULL); +} diff --git a/cmake/cmocka-1.1.7/example/assert_macro.c b/cmake/cmocka-1.1.7/example/assert_macro.c new file mode 100644 index 0000000..9590590 --- /dev/null +++ b/cmake/cmocka-1.1.7/example/assert_macro.c @@ -0,0 +1,39 @@ +/* + * Copyright 2008 Google Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include "assert_macro.h" + +static const char* status_code_strings[] = { + "Address not found", + "Connection dropped", + "Connection timed out", +}; + +const char* get_status_code_string(const unsigned int status_code) { + return status_code_strings[status_code]; +} + +unsigned int string_to_status_code(const char* const status_code_string) { + unsigned int i; + for (i = 0; i < sizeof(status_code_strings) / + sizeof(status_code_strings[0]); i++) { + if (strcmp(status_code_strings[i], status_code_string) == 0) { + return i; + } + } + return ~0U; +} diff --git a/cmake/cmocka-1.1.7/example/assert_macro.h b/cmake/cmocka-1.1.7/example/assert_macro.h new file mode 100644 index 0000000..789380c --- /dev/null +++ b/cmake/cmocka-1.1.7/example/assert_macro.h @@ -0,0 +1,2 @@ +const char* get_status_code_string(const unsigned int status_code); +unsigned int string_to_status_code(const char* const status_code_string); diff --git a/cmake/cmocka-1.1.7/example/assert_macro_test.c b/cmake/cmocka-1.1.7/example/assert_macro_test.c new file mode 100644 index 0000000..2cd355c --- /dev/null +++ b/cmake/cmocka-1.1.7/example/assert_macro_test.c @@ -0,0 +1,46 @@ +/* + * Copyright 2008 Google Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#include +#include +#include +#include + +#include "assert_macro.h" + +/* This test will fail since the string returned by get_status_code_string(0) + * doesn't match "Connection timed out". */ +static void get_status_code_string_test(void **state) { + (void) state; /* unused */ + + assert_string_equal(get_status_code_string(0), "Address not found"); + assert_string_equal(get_status_code_string(1), "Connection timed out"); +} + +/* This test will fail since the status code of "Connection timed out" isn't 1 */ +static void string_to_status_code_test(void **state) { + (void) state; /* unused */ + + assert_int_equal(string_to_status_code("Address not found"), 0); + assert_int_equal(string_to_status_code("Connection timed out"), 1); +} + +int main(void) { + const struct CMUnitTest tests[] = { + cmocka_unit_test(get_status_code_string_test), + cmocka_unit_test(string_to_status_code_test), + }; + return cmocka_run_group_tests(tests, NULL, NULL); +} diff --git a/cmake/cmocka-1.1.7/example/assert_module.c b/cmake/cmocka-1.1.7/example/assert_module.c new file mode 100644 index 0000000..381069b --- /dev/null +++ b/cmake/cmocka-1.1.7/example/assert_module.c @@ -0,0 +1,38 @@ +/* + * Copyright 2008 Google Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#include + +#include "assert_module.h" + +/* If unit testing is enabled override assert with mock_assert(). */ +#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(((expression) ? 1 : 0), #expression, __FILE__, __LINE__); +#endif /* UNIT_TESTING */ + +void increment_value(int * const value) { + assert(value); + (*value) ++; +} + +void decrement_value(int * const value) { + if (value) { + (*value) --; + } +} diff --git a/cmake/cmocka-1.1.7/example/assert_module.h b/cmake/cmocka-1.1.7/example/assert_module.h new file mode 100644 index 0000000..b68b4d9 --- /dev/null +++ b/cmake/cmocka-1.1.7/example/assert_module.h @@ -0,0 +1,18 @@ +/* + * Copyright 2008 Google Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +void increment_value(int * const value); +void decrement_value(int * const value); diff --git a/cmake/cmocka-1.1.7/example/assert_module_test.c b/cmake/cmocka-1.1.7/example/assert_module_test.c new file mode 100644 index 0000000..f387754 --- /dev/null +++ b/cmake/cmocka-1.1.7/example/assert_module_test.c @@ -0,0 +1,56 @@ +/* + * Copyright 2008 Google Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#include +#include +#include +#include + +#include "assert_module.h" + +extern void increment_value(int * const value); + +/* This test case will fail but the assert is caught by run_tests() and the + * next test is executed. */ +static void increment_value_fail(void **state) { + (void) state; + + increment_value(NULL); +} + +/* This test case succeeds since increment_value() asserts on the NULL + * pointer. */ +static void increment_value_assert(void **state) { + (void) state; + + expect_assert_failure(increment_value(NULL)); +} + +/* This test case fails since decrement_value() doesn't assert on a NULL + * pointer. */ +static void decrement_value_fail(void **state) { + (void) state; + + expect_assert_failure(decrement_value(NULL)); +} + +int main(void) { + const struct CMUnitTest tests[] = { + cmocka_unit_test(increment_value_fail), + cmocka_unit_test(increment_value_assert), + cmocka_unit_test(decrement_value_fail), + }; + return cmocka_run_group_tests(tests, NULL, NULL); +} diff --git a/cmake/cmocka-1.1.7/example/calculator.c b/cmake/cmocka-1.1.7/example/calculator.c new file mode 100644 index 0000000..307b551 --- /dev/null +++ b/cmake/cmocka-1.1.7/example/calculator.c @@ -0,0 +1,286 @@ +/* + * Copyright 2008 Google Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* A calculator example used to demonstrate the cmocka testing library. */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif +#include +#ifdef HAVE_MALLOC_H +#include +#endif +#include +#include +#include + +/* If this is being built for a unit test. */ +#ifdef UNIT_TESTING + +/* Redirect printf to a function in the test application so it's possible to + * test the standard output. */ +#ifdef printf +#undef printf +#endif /* printf */ +extern int example_test_printf(const char *format, ...); +#define printf example_test_printf + +extern void print_message(const char *format, ...); + +/* Redirect fprintf to a function in the test application so it's possible to + * test error messages. */ +#ifdef fprintf +#undef fprintf +#endif /* fprintf */ +#define fprintf example_test_fprintf + +extern int example_test_fprintf(FILE * const file, const char *format, ...); + +/* Redirect assert to mock_assert() so assertions can be caught by cmocka. */ +#ifdef assert +#undef assert +#endif /* assert */ +#define assert(expression) \ + mock_assert((int)(expression), #expression, __FILE__, __LINE__) +void mock_assert(const int result, const char* expression, const char *file, + const int line); + +/* Redirect calloc and free to test_calloc() and test_free() so cmocka can + * check for memory leaks. */ +#ifdef calloc +#undef calloc +#endif /* calloc */ +#define calloc(num, size) _test_calloc(num, size, __FILE__, __LINE__) +#ifdef free +#undef free +#endif /* free */ +#define free(ptr) _test_free(ptr, __FILE__, __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); + +int example_main(int argc, char *argv[]); +/* main is defined in the unit test so redefine name of the the main function + * here. */ +#define main example_main + +/* All functions in this object need to be exposed to the test application, + * so redefine static to nothing. */ +#define static + +#endif /* UNIT_TESTING */ + + +/* A binary arithmetic integer operation (add, subtract etc.) */ +typedef int (*BinaryOperator)(int a, int b); + +/* Structure which maps operator strings to functions. */ +typedef struct OperatorFunction { + const char* operator; + BinaryOperator function; +} OperatorFunction; + + +BinaryOperator find_operator_function_by_string( + const size_t number_of_operator_functions, + const OperatorFunction * const operator_functions, + const char* const operator_string); + +int perform_operation( + int number_of_arguments, char *arguments[], + const size_t number_of_operator_functions, + const OperatorFunction * const operator_functions, + int * const number_of_intermediate_values, + int ** const intermediate_values, int * const error_occurred); + +static int add(int a, int b); +static int subtract(int a, int b); +static int multiply(int a, int b); +static int divide(int a, int b); + +/* Associate operator strings to functions. */ +static OperatorFunction operator_function_map[] = { + {"+", add}, + {"-", subtract}, + {"*", multiply}, + {"/", divide}, +}; + +static int add(int a, int b) { + return a + b; +} + +static int subtract(int a, int b) { + return a - b; +} + +static int multiply(int a, int b) { + return a * b; +} + +static int divide(int a, int b) { + assert(b); /* Check for divide by zero. */ + return a / b; +} + +/* Searches the specified array of operator_functions for the function + * associated with the specified operator_string. This function returns the + * function associated with operator_string if successful, NULL otherwise. + */ +BinaryOperator find_operator_function_by_string( + const size_t number_of_operator_functions, + const OperatorFunction * const operator_functions, + const char* const operator_string) { + size_t i; + assert(!number_of_operator_functions || operator_functions); + assert(operator_string != NULL); + + for (i = 0; i < number_of_operator_functions; i++) { + const OperatorFunction *const operator_function = + &operator_functions[i]; + if (strcmp(operator_function->operator, operator_string) == 0) { + return operator_function->function; + } + } + return NULL; +} + +/* Perform a series of binary arithmetic integer operations with no operator + * precedence. + * + * The input expression is specified by arguments which is an array of + * containing number_of_arguments strings. Operators invoked by the expression + * are specified by the array operator_functions containing + * number_of_operator_functions, OperatorFunction structures. The value of + * each binary operation is stored in a pointer returned to intermediate_values + * which is allocated by malloc(). + * + * If successful, this function returns the integer result of the operations. + * If an error occurs while performing the operation error_occurred is set to + * 1, the operation is aborted and 0 is returned. + */ +int perform_operation( + int number_of_arguments, char *arguments[], + const size_t number_of_operator_functions, + const OperatorFunction * const operator_functions, + int * const number_of_intermediate_values, + int ** const intermediate_values, int * const error_occurred) { + char *end_of_integer; + int value; + int i; + assert(!number_of_arguments || arguments); + assert(!number_of_operator_functions || operator_functions); + assert(error_occurred != NULL); + assert(number_of_intermediate_values != NULL); + assert(intermediate_values != NULL); + + *error_occurred = 0; + *number_of_intermediate_values = 0; + *intermediate_values = NULL; + if (!number_of_arguments) + return 0; + + /* Parse the first value. */ + value = (int)strtol(arguments[0], &end_of_integer, 10); + if (end_of_integer == arguments[0]) { + /* If an error occurred while parsing the integer. */ + fprintf(stderr, "Unable to parse integer from argument %s\n", + arguments[0]); + *error_occurred = 1; + return 0; + } + + /* Allocate an array for the output values. */ + *intermediate_values = calloc(((number_of_arguments - 1) / 2), + sizeof(**intermediate_values)); + + i = 1; + while (i < number_of_arguments) { + int other_value; + const char* const operator_string = arguments[i]; + const BinaryOperator function = find_operator_function_by_string( + number_of_operator_functions, operator_functions, operator_string); + int * const intermediate_value = + &((*intermediate_values)[*number_of_intermediate_values]); + (*number_of_intermediate_values) ++; + + if (!function) { + fprintf(stderr, "Unknown operator %s, argument %d\n", + operator_string, i); + *error_occurred = 1; + break; + } + i ++; + + if (i == number_of_arguments) { + fprintf(stderr, "Binary operator %s missing argument\n", + operator_string); + *error_occurred = 1; + break; + } + + other_value = (int)strtol(arguments[i], &end_of_integer, 10); + if (end_of_integer == arguments[i]) { + /* If an error occurred while parsing the integer. */ + fprintf(stderr, "Unable to parse integer %s of argument %d\n", + arguments[i], i); + *error_occurred = 1; + break; + } + i ++; + + /* Perform the operation and store the intermediate value. */ + *intermediate_value = function(value, other_value); + value = *intermediate_value; + } + if (*error_occurred) { + free(*intermediate_values); + *intermediate_values = NULL; + *number_of_intermediate_values = 0; + return 0; + } + return value; +} + +int main(int argc, char *argv[]) { + int return_value; + int number_of_intermediate_values; + int *intermediate_values; + /* Peform the operation. */ + const int result = perform_operation( + argc - 1, &argv[1], + sizeof(operator_function_map) / sizeof(operator_function_map[0]), + operator_function_map, &number_of_intermediate_values, + &intermediate_values, &return_value); + + /* If no errors occurred display the result. */ + if (!return_value && argc > 1) { + int i; + int intermediate_value_index = 0; + printf("%s\n", argv[1]); + for (i = 2; i < argc; i += 2) { + assert(intermediate_value_index < number_of_intermediate_values); + printf(" %s %s = %d\n", argv[i], argv[i + 1], + intermediate_values[intermediate_value_index++]); + } + printf("= %d\n", result); + } + if (intermediate_values) { + free(intermediate_values); + } + + return return_value; +} diff --git a/cmake/cmocka-1.1.7/example/calculator_test.c b/cmake/cmocka-1.1.7/example/calculator_test.c new file mode 100644 index 0000000..ab8cad8 --- /dev/null +++ b/cmake/cmocka-1.1.7/example/calculator_test.c @@ -0,0 +1,482 @@ +/* + * Copyright 2008 Google Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#include +#include +#include +#include "cmocka.h" +#include + +#ifdef _WIN32 +/* Compatibility with the Windows standard C library. */ +#define vsnprintf _vsnprintf +#endif /* _WIN32 */ + +#define array_length(x) (sizeof(x) / sizeof((x)[0])) + +/* To simplify this code, these functions and data structures could have been + * separated out from the application example.c into a header shared with + * test application. However, this example illustrates how it's possible to + * test existing code with little modification. */ + +typedef int (*BinaryOperator)(int a, int b); + +typedef struct OperatorFunction { + const char* operator; + BinaryOperator function; +} OperatorFunction; + +extern int add(int a, int b); +extern int subtract(int a, int b); +extern int multiply(int a, int b); +extern int divide(int a, int b); +extern BinaryOperator find_operator_function_by_string( + const size_t number_of_operator_functions, + const OperatorFunction * const operator_functions, + const char* const operator_string); +extern int perform_operation( + int number_of_arguments, char *arguments[], + const size_t number_of_operator_functions, + const OperatorFunction * const operator_functions, + int * const number_of_intermediate_values, + int ** const intermediate_values, int * const error_occurred); +extern int example_main(int argc, char *argv[]); + +int example_test_fprintf(FILE* const file, const char *format, ...) CMOCKA_PRINTF_ATTRIBUTE(2, 3); +int example_test_printf(const char *format, ...) CMOCKA_PRINTF_ATTRIBUTE(1, 2); + +static char temporary_buffer[256]; + +/* A mock fprintf function that checks the value of strings printed to the + * standard error stream. */ +int example_test_fprintf(FILE* const file, const char *format, ...) { + int return_value; + va_list args; + assert_true(file == stderr); + va_start(args, format); + return_value = vsnprintf(temporary_buffer, sizeof(temporary_buffer), + format, args); + check_expected_ptr(temporary_buffer); + va_end(args); + return return_value; +} + +/* A mock printf function that checks the value of strings printed to the + * standard output stream. */ +int example_test_printf(const char *format, ...) { + int return_value; + va_list args; + va_start(args, format); + return_value = vsnprintf(temporary_buffer, sizeof(temporary_buffer), + format, args); + check_expected_ptr(temporary_buffer); + va_end(args); + return return_value; +} + +/* A mock binary operator function. */ +static int binary_operator(int a, int b) { + check_expected(a); + check_expected(b); + return (int)mock(); +} + + +/* Ensure add() adds two integers correctly. */ +static void test_add(void **state) { + (void) state; /* unused */ + + assert_int_equal(add(3, 3), 6); + assert_int_equal(add(3, -3), 0); +} + +/* Ensure subtract() subtracts two integers correctly. */ +static void test_subtract(void **state) { + (void) state; /* unused */ + + assert_int_equal(subtract(3, 3), 0); + assert_int_equal(subtract(3, -3), 6); +} + +/* Ensure multiple() mulitplies two integers correctly. */ +static void test_multiply(void **state) { + (void) state; /* unused */ + + assert_int_equal(multiply(3, 3), 9); + assert_int_equal(multiply(3, 0), 0); +} + +/* Ensure divide() divides one integer by another correctly. */ +static void test_divide(void **state) { + (void) state; /* unused */ + + assert_int_equal(divide(10, 2), 5); + assert_int_equal(divide(2, 10), 0); +} + +/* Ensure divide() asserts when trying to divide by zero. */ +static void test_divide_by_zero(void **state) { + (void) state; /* unused */ + + expect_assert_failure(divide(100, 0)); +} + +/* Ensure find_operator_function_by_string() asserts when a NULL pointer is + * specified as the table to search. */ +static void test_find_operator_function_by_string_null_functions(void **state) { + (void) state; /* unused */ + + expect_assert_failure(find_operator_function_by_string(1, NULL, "test")); +} + +/* Ensure find_operator_function_by_string() asserts when a NULL pointer is + * specified as the string to search for. */ +static void test_find_operator_function_by_string_null_string(void **state) { + const OperatorFunction operator_functions[] = { + {"+", binary_operator}, + }; + + (void) state; /* unused */ + + expect_assert_failure(find_operator_function_by_string( + array_length(operator_functions), operator_functions, NULL)); +} + +/* Ensure find_operator_function_by_string() returns NULL when a NULL pointer + * is specified as the table to search when the table size is 0. */ +static void test_find_operator_function_by_string_valid_null_functions(void **state) { + (void) state; /* unused */ + + assert_null(find_operator_function_by_string(0, NULL, "test")); +} + +/* Ensure find_operator_function_by_string() returns NULL when searching for + * an operator string that isn't in the specified table. */ +static void test_find_operator_function_by_string_not_found(void **state) { + const OperatorFunction operator_functions[] = { + {"+", binary_operator}, + {"-", binary_operator}, + {"/", binary_operator}, + }; + + (void) state; /* unused */ + + assert_null(find_operator_function_by_string( + array_length(operator_functions), operator_functions, "test")); +} + +/* Ensure find_operator_function_by_string() returns the correct function when + * searching for an operator string that is in the specified table. */ +static void test_find_operator_function_by_string_found(void **state) { + const OperatorFunction operator_functions[] = { + {"+", (BinaryOperator)0x12345678}, + {"-", (BinaryOperator)0xDEADBEEF}, + {"/", (BinaryOperator)0xABADCAFE}, + }; + + (void) state; /* unused */ + + assert_int_equal( + cast_ptr_to_largest_integral_type( + find_operator_function_by_string(array_length(operator_functions), + operator_functions, + "-")), + 0xDEADBEEF); +} + +/* Ensure perform_operation() asserts when a NULL arguments array is specified. */ +static void test_perform_operation_null_args(void **state) { + const OperatorFunction operator_functions[] = { + {"+", binary_operator}, + }; + int number_of_intermediate_values; + int *intermediate_values; + int error_occurred; + + (void) state; /* unused */ + + expect_assert_failure(perform_operation( + 1, NULL, array_length(operator_functions), operator_functions, + &number_of_intermediate_values, &intermediate_values, + &error_occurred)); +} + +/* Ensure perform_operation() asserts when a NULL operator_functions array is + * specified. */ +static void test_perform_operation_null_operator_functions(void **state) { + const char *args[] = { + "1", "+", "2", "*", "4" + }; + int number_of_intermediate_values; + int *intermediate_values; + int error_occurred; + + (void) state; /* unused */ + + expect_assert_failure(perform_operation( + array_length(args), (char **) args, 1, NULL, &number_of_intermediate_values, + &intermediate_values, &error_occurred)); +} + +/* Ensure perform_operation() asserts when a NULL pointer is specified for + * number_of_intermediate_values. */ +static void test_perform_operation_null_number_of_intermediate_values(void **state) { + const OperatorFunction operator_functions[] = { + {"+", binary_operator}, + }; + const char *args[] = { + "1", "+", "2", "*", "4" + }; + int *intermediate_values; + int error_occurred; + + (void) state; /* unused */ + + expect_assert_failure(perform_operation( + array_length(args), (char **) args, 1, operator_functions, NULL, + &intermediate_values, &error_occurred)); +} + +/* Ensure perform_operation() asserts when a NULL pointer is specified for + * intermediate_values. */ +static void test_perform_operation_null_intermediate_values(void **state) { + const OperatorFunction operator_functions[] = { + {"+", binary_operator}, + }; + const char *args[] = { + "1", "+", "2", "*", "4" + }; + int number_of_intermediate_values; + int error_occurred; + + (void) state; /* unused */ + + expect_assert_failure(perform_operation( + array_length(args), (char **) args, array_length(operator_functions), + operator_functions, &number_of_intermediate_values, NULL, + &error_occurred)); +} + +/* Ensure perform_operation() returns 0 when no arguments are specified. */ +static void test_perform_operation_no_arguments(void **state) { + int number_of_intermediate_values; + int *intermediate_values; + int error_occurred; + + (void) state; /* unused */ + + assert_int_equal(perform_operation( + 0, NULL, 0, NULL, &number_of_intermediate_values, &intermediate_values, + &error_occurred), 0); + assert_int_equal(error_occurred, 0); +} + +/* Ensure perform_operation() returns an error if the first argument isn't + * an integer string. */ +static void test_perform_operation_first_arg_not_integer(void **state) { + const OperatorFunction operator_functions[] = { + {"+", binary_operator}, + }; + const char *args[] = { + "test", "+", "2", "*", "4" + }; + int number_of_intermediate_values; + int *intermediate_values; + int error_occurred; + + (void) state; /* unused */ + + expect_string(example_test_fprintf, temporary_buffer, + "Unable to parse integer from argument test\n"); + + assert_int_equal(perform_operation( + array_length(args), (char **) args, array_length(operator_functions), + operator_functions, &number_of_intermediate_values, + &intermediate_values, &error_occurred), 0); + assert_int_equal(error_occurred, 1); +} + +/* Ensure perform_operation() returns an error when parsing an unknown + * operator. */ +static void test_perform_operation_unknown_operator(void **state) { + const OperatorFunction operator_functions[] = { + {"+", binary_operator}, + }; + const char *args[] = { + "1", "*", "2", "*", "4" + }; + int number_of_intermediate_values; + int *intermediate_values; + int error_occurred; + + (void) state; /* unused */ + + expect_string(example_test_fprintf, temporary_buffer, + "Unknown operator *, argument 1\n"); + + assert_int_equal(perform_operation( + array_length(args), (char **) args, array_length(operator_functions), + operator_functions, &number_of_intermediate_values, + &intermediate_values, &error_occurred), 0); + assert_int_equal(error_occurred, 1); +} + +/* Ensure perform_operation() returns an error when nothing follows an + * operator. */ +static void test_perform_operation_missing_argument(void **state) { + const OperatorFunction operator_functions[] = { + {"+", binary_operator}, + }; + const char *args[] = { + "1", "+", + }; + int number_of_intermediate_values; + int *intermediate_values; + int error_occurred; + + (void) state; /* unused */ + + expect_string(example_test_fprintf, temporary_buffer, + "Binary operator + missing argument\n"); + + assert_int_equal(perform_operation( + array_length(args), (char **) args, array_length(operator_functions), + operator_functions, &number_of_intermediate_values, + &intermediate_values, &error_occurred), 0); + assert_int_equal(error_occurred, 1); +} + +/* Ensure perform_operation() returns an error when an integer doesn't follow + * an operator. */ +static void test_perform_operation_no_integer_after_operator(void **state) { + const OperatorFunction operator_functions[] = { + {"+", binary_operator}, + }; + const char *args[] = { + "1", "+", "test", + }; + int number_of_intermediate_values; + int *intermediate_values; + int error_occurred; + + (void) state; /* unused */ + + expect_string(example_test_fprintf, temporary_buffer, + "Unable to parse integer test of argument 2\n"); + + assert_int_equal(perform_operation( + array_length(args), (char **) args, array_length(operator_functions), + operator_functions, &number_of_intermediate_values, + &intermediate_values, &error_occurred), 0); + assert_int_equal(error_occurred, 1); +} + + +/* Ensure perform_operation() succeeds given valid input parameters. */ +static void test_perform_operation(void **state) { + const OperatorFunction operator_functions[] = { + {"+", binary_operator}, + {"*", binary_operator}, + }; + const char *args[] = { + "1", "+", "3", "*", "10", + }; + int number_of_intermediate_values; + int *intermediate_values = NULL; + int error_occurred; + + (void) state; /* unused */ + + /* Setup return values of mock operator functions. */ + /* Addition. */ + expect_value(binary_operator, a, 1); + expect_value(binary_operator, b, 3); + will_return(binary_operator, 4); + + /* Multiplication. */ + expect_value(binary_operator, a, 4); + expect_value(binary_operator, b, 10); + will_return(binary_operator, 40); + + assert_int_equal(perform_operation( + array_length(args), (char **) args, array_length(operator_functions), + operator_functions, &number_of_intermediate_values, + &intermediate_values, &error_occurred), 40); + assert_int_equal(error_occurred, 0); + + assert_non_null(intermediate_values); + assert_int_equal(intermediate_values[0], 4); + assert_int_equal(intermediate_values[1], 40); + test_free(intermediate_values); +} + + +/* Ensure main() in example.c succeeds given no arguments. */ +static void test_example_main_no_args(void **state) { + const char *args[] = { + "example", + }; + + (void) state; /* unused */ + + assert_int_equal(example_main(array_length(args), (char **) args), 0); +} + + + +/* Ensure main() in example.c succeeds given valid input arguments. */ +static void test_example_main(void **state) { + const char *args[] = { + "example", "1", "+", "3", "*", "10", + }; + + (void) state; /* unused */ + + expect_string(example_test_printf, temporary_buffer, "1\n"); + expect_string(example_test_printf, temporary_buffer, " + 3 = 4\n"); + expect_string(example_test_printf, temporary_buffer, " * 10 = 40\n"); + expect_string(example_test_printf, temporary_buffer, "= 40\n"); + + assert_int_equal(example_main(array_length(args), (char **) args), 0); +} + + +int main(void) { + const struct CMUnitTest tests[] = { + cmocka_unit_test(test_add), + cmocka_unit_test(test_subtract), + cmocka_unit_test(test_multiply), + cmocka_unit_test(test_divide), + cmocka_unit_test(test_divide_by_zero), + cmocka_unit_test(test_find_operator_function_by_string_null_functions), + cmocka_unit_test(test_find_operator_function_by_string_null_string), + cmocka_unit_test(test_find_operator_function_by_string_valid_null_functions), + cmocka_unit_test(test_find_operator_function_by_string_not_found), + cmocka_unit_test(test_find_operator_function_by_string_found), + cmocka_unit_test(test_perform_operation_null_args), + cmocka_unit_test(test_perform_operation_null_operator_functions), + cmocka_unit_test(test_perform_operation_null_number_of_intermediate_values), + cmocka_unit_test(test_perform_operation_null_intermediate_values), + cmocka_unit_test(test_perform_operation_no_arguments), + cmocka_unit_test(test_perform_operation_first_arg_not_integer), + cmocka_unit_test(test_perform_operation_unknown_operator), + cmocka_unit_test(test_perform_operation_missing_argument), + cmocka_unit_test(test_perform_operation_no_integer_after_operator), + cmocka_unit_test(test_perform_operation), + cmocka_unit_test(test_example_main_no_args), + cmocka_unit_test(test_example_main), + }; + return cmocka_run_group_tests(tests, NULL, NULL); +} diff --git a/cmake/cmocka-1.1.7/example/database.h b/cmake/cmocka-1.1.7/example/database.h new file mode 100644 index 0000000..880db3c --- /dev/null +++ b/cmake/cmocka-1.1.7/example/database.h @@ -0,0 +1,37 @@ +/* + * Copyright 2008 Google Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +typedef struct DatabaseConnection DatabaseConnection; + +/* Function that takes an SQL query string and sets results to an array of + * pointers with the result of the query. The value returned specifies the + * number of items in the returned array of results. The returned array of + * results are statically allocated and should not be deallocated using free() + */ +typedef unsigned int (*QueryDatabase)( + DatabaseConnection* const connection, const char * const query_string, + void *** const results); + +/* Connection to a database. */ +struct DatabaseConnection { + const char *url; + unsigned int port; + QueryDatabase query_database; +}; + +/* Connect to a database. */ +DatabaseConnection* connect_to_database(const char * const url, + const unsigned int port); + diff --git a/cmake/cmocka-1.1.7/example/mock/CMakeLists.txt b/cmake/cmocka-1.1.7/example/mock/CMakeLists.txt new file mode 100644 index 0000000..04bbb1f --- /dev/null +++ b/cmake/cmocka-1.1.7/example/mock/CMakeLists.txt @@ -0,0 +1,5 @@ +# TODO Execute "$CMAKE_LINKER --help" and check for --wrap +if (${CMAKE_C_COMPILER_ID} MATCHES "(GNU|Clang)" AND NOT APPLE) + add_subdirectory(chef_wrap) + add_subdirectory(uptime) +endif() diff --git a/cmake/cmocka-1.1.7/example/mock/chef_wrap/CMakeLists.txt b/cmake/cmocka-1.1.7/example/mock/chef_wrap/CMakeLists.txt new file mode 100644 index 0000000..205ccd4 --- /dev/null +++ b/cmake/cmocka-1.1.7/example/mock/chef_wrap/CMakeLists.txt @@ -0,0 +1,20 @@ +project(cmocka-wrap-examples C) + +include_directories( + ${CMAKE_BINARY_DIR} + ${CMAKE_CURRENT_SOURCE_DIR} + ${CMOCKA_PUBLIC_INCLUDE_DIRS} +) + +add_executable(waiter_test_wrap waiter_test_wrap.c chef.c) +target_link_libraries(waiter_test_wrap cmocka::cmocka) + +add_test(waiter_test_wrap ${CMAKE_CURRENT_BINARY_DIR}/waiter_test_wrap) + +set_target_properties(waiter_test_wrap + PROPERTIES + LINK_FLAGS "-Wl,--wrap=chef_cook" +) +if (WIN32 OR MINGW OR CYGWIN) + set_tests_properties(waiter_test_wrap PROPERTIES ENVIRONMENT "PATH=${DLL_PATH_ENV}") +endif (WIN32 OR MINGW OR CYGWIN) diff --git a/cmake/cmocka-1.1.7/example/mock/chef_wrap/chef.c b/cmake/cmocka-1.1.7/example/mock/chef_wrap/chef.c new file mode 100644 index 0000000..1429cde --- /dev/null +++ b/cmake/cmocka-1.1.7/example/mock/chef_wrap/chef.c @@ -0,0 +1,54 @@ +/* + * Copyright 2013 (c) Andreas Schneider + * Jakub Hrozek + * + * 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. + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "chef.h" + + +/* This is the real chef, just not implemented yet, currently it always + * returns ENOSYS + */ +int chef_cook(const char *order, char **dish_out) +{ + if (order == NULL || dish_out == NULL) return EINVAL; + + return -ENOSYS; +} + +/* Print chef return codes as string */ +const char *chef_strerror(int error) +{ + switch (error) { + case 0: + return "Success"; + case -1: + return "Unknown dish"; + case -2: + return "Not enough ingredients for the dish"; + } + + return "Unknown error!"; +} + diff --git a/cmake/cmocka-1.1.7/example/mock/chef_wrap/chef.h b/cmake/cmocka-1.1.7/example/mock/chef_wrap/chef.h new file mode 100644 index 0000000..c1a01c7 --- /dev/null +++ b/cmake/cmocka-1.1.7/example/mock/chef_wrap/chef.h @@ -0,0 +1,19 @@ +/* + * Copyright 2013 (c) Andreas Schneider + * Jakub Hrozek + * + * 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. + */ + +int chef_cook(const char *order, char **dish_out); +const char *chef_strerror(int error); diff --git a/cmake/cmocka-1.1.7/example/mock/chef_wrap/waiter_test_wrap.c b/cmake/cmocka-1.1.7/example/mock/chef_wrap/waiter_test_wrap.c new file mode 100644 index 0000000..4146818 --- /dev/null +++ b/cmake/cmocka-1.1.7/example/mock/chef_wrap/waiter_test_wrap.c @@ -0,0 +1,176 @@ +/* + * Copyright 2013 (c) Andreas Schneider + * Jakub Hrozek + * + * 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. + */ + +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include "waiter_test_wrap.h" +#include "chef.h" + +/* + * This is a mocked Chef object. A real Chef would look if he knows + * the dish in some kind of internal database and check his storage for + * ingredients. This chef simply retrieves this information from the test + * that is calling him. + * + * This object is also wrapped - if any code links with this file and is + * compiled with linker option --wrap chef_cook, any calls of that code to + * chef_cook will end up calling __wrap_chef_cook. + * + * If for any reason the wrapped function wanted to call the real chef_cook() + * function, it could do so by calling the special symbol __real_chef_cook(). + * + * Please note that when setting return codes for the chef_cook function, we + * use this wrapper as a parameter for the will_return() macro, not the + * real function. + * + * A chef object would return: + * 0 - cooking dish went fine + * -1 - unknown dish + * -2 - ran out of ingredients for the dish + * any other error code -- unexpected error while cooking + * + * The return codes should be consistent between the real and mocked objects. + */ +int __wrap_chef_cook(const char *order, char **dish_out) +{ + bool has_ingredients; + bool knows_dish; + char *dish; + + check_expected_ptr(order); + + knows_dish = mock_type(bool); + if (knows_dish == false) { + return -1; + } + + has_ingredients = mock_type(bool); + if (has_ingredients == false) { + return -2; + } + + dish = mock_ptr_type(char *); + *dish_out = strdup(dish); + if (*dish_out == NULL) return ENOMEM; + + return mock_type(int); +} + +/* Waiter return codes: + * 0 - success + * -1 - kitchen failed + * -2 - kitchen succeeded, but cooked a different food + */ +static int waiter_process(const char *order, char **dish) +{ + int rv; + + rv = chef_cook(order, dish); + if (rv != 0) { + fprintf(stderr, "Chef couldn't cook %s: %s\n", + order, chef_strerror(rv)); + return -1; + } + + /* Check if we received the dish we wanted from the kitchen */ + if (strcmp(order, *dish) != 0) { + free(*dish); + *dish = NULL; + return -2; + } + + return 0; +} + +static void test_order_hotdog(void **state) +{ + int rv; + char *dish; + + (void) state; /* unused */ + + /* We expect the chef to receive an order for a hotdog */ + expect_string(__wrap_chef_cook, order, "hotdog"); + /* And we tell the test chef that ke knows how to cook a hotdog + * and has the ingredients + */ + will_return(__wrap_chef_cook, true); + will_return(__wrap_chef_cook, true); + /* The result will be a hotdog and the cooking process will succeed */ + will_return(__wrap_chef_cook, cast_ptr_to_largest_integral_type("hotdog")); + will_return(__wrap_chef_cook, 0); + + /* Test the waiter */ + rv = waiter_process("hotdog", &dish); + + /* We expect the cook to succeed cooking the hotdog */ + assert_int_equal(rv, 0); + /* And actually receive one */ + assert_string_equal(dish, "hotdog"); + if (dish != NULL) { + free(dish); + } +} + +static void test_bad_dish(void **state) +{ + int rv; + char *dish; + + (void) state; /* unused */ + + /* We expect the chef to receive an order for a hotdog */ + expect_string(__wrap_chef_cook, order, "hotdog"); + /* And we tell the test chef that ke knows how to cook a hotdog + * and has the ingredients + */ + will_return(__wrap_chef_cook, true); + will_return(__wrap_chef_cook, true); + /* The result will be a burger and the cooking process will succeed. + * We expect the waiter to handle the bad dish and return an error + * code + */ + will_return(__wrap_chef_cook, cast_ptr_to_largest_integral_type("burger")); + will_return(__wrap_chef_cook, 0); + + /* Test the waiter */ + rv = waiter_process("hotdog", &dish); + + /* According to the documentation the waiter should return -2 now */ + assert_int_equal(rv, -2); + /* And do not give the bad dish to the customer */ + assert_null(dish); +} + +int main(void) +{ + const struct CMUnitTest tests[] = { + cmocka_unit_test(test_order_hotdog), + cmocka_unit_test(test_bad_dish), + }; + + return cmocka_run_group_tests(tests, NULL, NULL); +} diff --git a/cmake/cmocka-1.1.7/example/mock/chef_wrap/waiter_test_wrap.h b/cmake/cmocka-1.1.7/example/mock/chef_wrap/waiter_test_wrap.h new file mode 100644 index 0000000..9178ca2 --- /dev/null +++ b/cmake/cmocka-1.1.7/example/mock/chef_wrap/waiter_test_wrap.h @@ -0,0 +1,2 @@ + +int __wrap_chef_cook(const char *order, char **dish_out); diff --git a/cmake/cmocka-1.1.7/example/mock/uptime/CMakeLists.txt b/cmake/cmocka-1.1.7/example/mock/uptime/CMakeLists.txt new file mode 100644 index 0000000..967185f --- /dev/null +++ b/cmake/cmocka-1.1.7/example/mock/uptime/CMakeLists.txt @@ -0,0 +1,20 @@ +add_library(proc_uptime proc_uptime.c) + +add_executable(uptime uptime.c) +target_compile_options(uptime PRIVATE ${DEFAULT_C_COMPILE_FLAGS}) +target_link_libraries(uptime proc_uptime) +set_property(TARGET + uptime + PROPERTY + LINK_FLAGS + "${DEFAULT_LINK_FLAGS}") + +add_cmocka_test(test_uptime + SOURCES test_uptime.c + COMPILE_OPTIONS ${DEFAULT_C_COMPILE_FLAGS} + LINK_LIBRARIES cmocka::cmocka) +set_property(TARGET + test_uptime + PROPERTY + LINK_FLAGS + "${DEFAULT_LINK_FLAGS} -Wl,--wrap=uptime") diff --git a/cmake/cmocka-1.1.7/example/mock/uptime/README.md b/cmake/cmocka-1.1.7/example/mock/uptime/README.md new file mode 100644 index 0000000..081ae51 --- /dev/null +++ b/cmake/cmocka-1.1.7/example/mock/uptime/README.md @@ -0,0 +1,56 @@ +The uptime mock example +======================= + +This is a very simple example to explain the mocking feature of cmocka. It +implement the 'uptime' unix command in a very simple way to demonstrate how to +test the time calculation. + +The problem with testing the uptime command is that /proc/uptime constantly +ticks. The result is random whenever you call the test. To actually test it +we need to make sure that we work with fixed values. The mocking features +of cmocka allows us to test it anyway! + +Source files +------------ + +* *proc_uptime.c*: This implements the `uptime()` function reading and parsing + the /proc/uptime file. +* *uptime.c*: This is the actual uptime implementation, it calls + `calc_uptime()` to get a human readable string representation of the uptime. + This function calls `uptime()` from proc_uptime.c. +* *test_uptime.c*: This is the test with the mocking function for uptime(). + +Linking magic +------------- + +The test is linked using: + + ld --wrap=uptime + +This replaces the orginal `uptime()` function which reads from `/proc/uptime` +with the mock function we implemented for testing `calc_uptime()`. + +The mock function we implemented has a special name. It is called +`__wrap_uptime()`. All the symbols you want to mock (or replace) need to start +with the prefix `__wrap_`. So `ld --wrap=uptime` will rename the orignal +`uptime()` function to `__real_uptime()`. This means you can still reach the +original function using that name and call it e.g. from the wrap function. +The symbol `uptime` will be bound to `__wrap_uptime`. + +You can find more details in the manpage: `man ld` + +The uptime test +--------------- + +The code should be easy to understand. If you have a hard time following, there +are two ways to understand how things work. + +You can find out details about symbol binding using: + + LD_DEBUG=symbols ./example/uptime/uptime + LD_DEBUG=symbols ./example/uptime/test_uptime + +You can also use a debugger to step through the code! + + +Have fun! diff --git a/cmake/cmocka-1.1.7/example/mock/uptime/proc_uptime.c b/cmake/cmocka-1.1.7/example/mock/uptime/proc_uptime.c new file mode 100644 index 0000000..a92c2ab --- /dev/null +++ b/cmake/cmocka-1.1.7/example/mock/uptime/proc_uptime.c @@ -0,0 +1,78 @@ +/* + * Copyright 2018 Andreas Scheider + * + * 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. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "proc_uptime.h" + +#define UPTIME_FILE "/proc/uptime" + +int uptime(const char *uptime_path, double *uptime_secs, double *idle_secs) +{ + double up = 0; + double idle = 0; + char *savelocale = NULL; + char buf[1024] = {0}; + ssize_t nread; + int fd = -1; + int rc; + + if (uptime_path == NULL) { + uptime_path = UPTIME_FILE; + } + + fd = open(uptime_path, O_RDONLY); + if (fd < 0) { + return 0; + } + + nread = read(fd, buf, sizeof(buf)); + close(fd); + if (nread < 0) { + return 0; + } + + savelocale = strdup(setlocale(LC_NUMERIC, NULL)); + if (savelocale == NULL) { + return 0; + } + + setlocale(LC_NUMERIC, "C"); + rc = sscanf(buf, "%lf %lf", &up, &idle); + setlocale(LC_NUMERIC, savelocale); + free(savelocale); + if (rc < 2) { + errno = EFAULT; + return 0; + } + + if (uptime_secs != NULL) { + *uptime_secs = up; + } + if (idle_secs != NULL) { + *idle_secs = idle; + } + + return (int)up; +} diff --git a/cmake/cmocka-1.1.7/example/mock/uptime/proc_uptime.h b/cmake/cmocka-1.1.7/example/mock/uptime/proc_uptime.h new file mode 100644 index 0000000..222ece5 --- /dev/null +++ b/cmake/cmocka-1.1.7/example/mock/uptime/proc_uptime.h @@ -0,0 +1,22 @@ +/* + * Copyright 2018 Andreas Scheider + * + * 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 _PROC_UPTIME_H +#define _PROC_UPTIME_H + +int uptime(const char *uptime_path, double *uptime_secs, double *idle_secs); + +#endif /* _PROC_UPTIME_H */ diff --git a/cmake/cmocka-1.1.7/example/mock/uptime/test_uptime.c b/cmake/cmocka-1.1.7/example/mock/uptime/test_uptime.c new file mode 100644 index 0000000..c724f95 --- /dev/null +++ b/cmake/cmocka-1.1.7/example/mock/uptime/test_uptime.c @@ -0,0 +1,185 @@ +/* + * Copyright 2018 Andreas Scheider + * + * 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. + */ + +#include +#include +#include +#include +#include + +#define UNIT_TESTING 1 +#include "uptime.c" + +#define UNUSED(x) (void)(x) + +/* + * This is a mocked object! + * + * It is a reimplementation of the uptime() function you can find in + * proc_uptime.c. + * + * This function can be instrumeted by the test. We can tell it what + * we expect or should return. + */ +int __wrap_uptime(const char *uptime_path, + double *uptime_secs, + double *idle_secs); +int __wrap_uptime(const char *uptime_path, + double *uptime_secs, + double *idle_secs) +{ + double up; + double idle; + + /* Verify the passed value of the argument is correct */ + check_expected_ptr(uptime_path); + + /* Assign the return values */ + up = mock_type(double); + idle = mock_type(double); + + if (uptime_secs != NULL) { + *uptime_secs = up; + } + if (idle_secs != NULL) { + *idle_secs = idle; + } + + return (int)up; +} + +static void test_calc_uptime_minutes(void **state) +{ + char *uptime_str = NULL; + + UNUSED(state); + + /* Make sure the passed 'in' argument is correct */ + expect_string(__wrap_uptime, uptime_path, "/proc/uptime"); + + /* We tell the uptime function what values it should return */ + will_return(__wrap_uptime, 508.16); + will_return(__wrap_uptime, 72.23); + + /* We call the function like we would do it normally */ + uptime_str = calc_uptime(); + + /* Now lets check if the result is what we expect it to be */ + assert_non_null(uptime_str); + assert_string_equal(uptime_str, "up 8 minutes"); + + free(uptime_str); +} + +static void test_calc_uptime_hour_minute(void **state) +{ + char *uptime_str = NULL; + + UNUSED(state); + + /* Make sure the passed 'in' argument is correct */ + expect_string(__wrap_uptime, uptime_path, "/proc/uptime"); + + /* We tell the uptime function what values it should return */ + will_return(__wrap_uptime, 3699.16); + will_return(__wrap_uptime, 4069.23); + + /* We call the function like we would do it normally */ + uptime_str = calc_uptime(); + + /* Now lets check if the result is what we expect it to be */ + assert_non_null(uptime_str); + assert_string_equal(uptime_str, "up 1 hour, 1 minute"); + + free(uptime_str); +} + +static void test_calc_uptime_days_minutes(void **state) +{ + char *uptime_str = NULL; + + UNUSED(state); + + /* Make sure the passed 'in' argument is correct */ + expect_string(__wrap_uptime, uptime_path, "/proc/uptime"); + + /* We tell the uptime function what values it should return */ + will_return(__wrap_uptime, 259415.14); + will_return(__wrap_uptime, 262446.29); + + /* We call the function like we would do it normally */ + uptime_str = calc_uptime(); + + /* Now lets check if the result is what we expect it to be */ + assert_non_null(uptime_str); + assert_string_equal(uptime_str, "up 3 days, 3 minutes"); + + free(uptime_str); +} + +static void test_calc_uptime_days_hours_minutes(void **state) +{ + char *uptime_str = NULL; + + UNUSED(state); + + /* Make sure the passed 'in' argument is correct */ + expect_string(__wrap_uptime, uptime_path, "/proc/uptime"); + + /* We tell the uptime function what values it should return */ + will_return(__wrap_uptime, 359415.14); + will_return(__wrap_uptime, 362446.29); + + /* We call the function like we would do it normally */ + uptime_str = calc_uptime(); + + /* Now lets check if the result is what we expect it to be */ + assert_non_null(uptime_str); + assert_string_equal(uptime_str, "up 4 days, 3 hours, 50 minutes"); + + free(uptime_str); +} + +static void test_calc_uptime_null(void **state) +{ + char *uptime_str = NULL; + + UNUSED(state); + + /* Make sure the passed 'in' argument is correct */ + expect_string(__wrap_uptime, uptime_path, "/proc/uptime"); + + will_return(__wrap_uptime, -0.0); + will_return(__wrap_uptime, 0.1); + + uptime_str = calc_uptime(); + assert_null(uptime_str); + + free(uptime_str); +} + +int main(void) +{ + const struct CMUnitTest tests[] = { + cmocka_unit_test(test_calc_uptime_minutes), + cmocka_unit_test(test_calc_uptime_hour_minute), + cmocka_unit_test(test_calc_uptime_days_minutes), + cmocka_unit_test(test_calc_uptime_days_hours_minutes), + cmocka_unit_test(test_calc_uptime_null), + }; + + return cmocka_run_group_tests(tests, NULL, NULL); +} diff --git a/cmake/cmocka-1.1.7/example/mock/uptime/uptime.c b/cmake/cmocka-1.1.7/example/mock/uptime/uptime.c new file mode 100644 index 0000000..77776a7 --- /dev/null +++ b/cmake/cmocka-1.1.7/example/mock/uptime/uptime.c @@ -0,0 +1,115 @@ +/* + * Copyright 2018 Andreas Scheider + * + * 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. + */ + +#include +#include +#include +#include +#include +#include + +#include "proc_uptime.h" + +static char *calc_uptime(void) +{ + uint32_t up_minutes, up_hours, up_days, up_weeks, up_years; + ssize_t pos = 0; + size_t comma = 0; + double uptime_secs, idle_secs; + char buf[1024] = {0}; + int up; + + up = uptime("/proc/uptime", &uptime_secs, &idle_secs); + if (up == 0) { + return NULL; + } + + up_years = ((uint32_t)uptime_secs / (60 * 60 * 24 * 365)) % 10; + up_weeks = ((uint32_t)uptime_secs / (60 * 60 * 24 * 7)) % 52; + up_days = ((uint32_t)uptime_secs / (60 * 60 * 24)) % 7; + + pos += snprintf(buf + pos, sizeof(buf) - pos, "up "); + + up_minutes = (uint32_t)uptime_secs / 60; + up_hours = up_minutes / 60; + up_hours = up_hours % 24; + up_minutes = up_minutes % 60; + + if (up_years > 0) { + pos += snprintf(buf + pos, sizeof(buf) - pos, + "%u %s", + up_years, + up_years > 1 ? "years" : "year"); + comma++; + } + + if (up_weeks > 0) { + pos += snprintf(buf + pos, sizeof(buf) - pos, + "%s%u %s", + comma > 0 ? ", " : "", + up_weeks, + up_weeks > 1 ? "weeks" : "week"); + comma++; + } + + if (up_days > 0) { + pos += snprintf(buf + pos, sizeof(buf) - pos, + "%s%u %s", + comma > 0 ? ", " : "", + up_days, + up_days > 1 ? "days" : "day"); + comma++; + } + + if (up_hours > 0) { + pos += snprintf(buf + pos, sizeof(buf) - pos, + "%s%u %s", + comma > 0 ? ", " : "", + up_hours, + up_hours > 1 ? "hours" : "hour"); + comma++; + } + + if (up_minutes > 0 || (up_minutes == 0 && uptime_secs < 60)) { + pos += snprintf(buf + pos, sizeof(buf) - pos, + "%s%u %s", + comma > 0 ? ", " : "", + up_minutes, + up_minutes != 1 ? "minutes" : "minute"); + comma++; + } + + return strdup(buf); +} + +#ifndef UNIT_TESTING +int main(void) +{ + char *uptime_str = NULL; + + uptime_str = calc_uptime(); + if (uptime_str == NULL) { + fprintf(stderr, "Failed to read uptime\n"); + return 1; + } + + printf("%s\n", uptime_str); + + free(uptime_str); + + return 0; +} +#endif /* UNIT_TESTING */ diff --git a/cmake/cmocka-1.1.7/example/simple_test.c b/cmake/cmocka-1.1.7/example/simple_test.c new file mode 100644 index 0000000..cfb446c --- /dev/null +++ b/cmake/cmocka-1.1.7/example/simple_test.c @@ -0,0 +1,18 @@ +#include +#include +#include +#include +#include + +/* A test case that does nothing and succeeds. */ +static void null_test_success(void **state) { + (void) state; /* unused */ +} + +int main(void) { + const struct CMUnitTest tests[] = { + cmocka_unit_test(null_test_success), + }; + + return cmocka_run_group_tests(tests, NULL, NULL); +} diff --git a/cmake/cmocka-1.1.7/include/CMakeLists.txt b/cmake/cmocka-1.1.7/include/CMakeLists.txt new file mode 100644 index 0000000..4e38547 --- /dev/null +++ b/cmake/cmocka-1.1.7/include/CMakeLists.txt @@ -0,0 +1,19 @@ +project(cmocka-header C) + +install(FILES + cmocka.h + cmocka_pbc.h + DESTINATION + ${CMAKE_INSTALL_INCLUDEDIR} + COMPONENT + ${PROJECT_NAME}) + +if (WITH_CMOCKERY_SUPPORT) + install(FILES + cmockery/cmockery.h + cmockery/pbc.h + DESTINATION + ${CMAKE_INSTALL_INCLUDEDIR}/cmockery + COMPONENT + ${PROJECT_NAME}) +endif() diff --git a/cmake/cmocka-1.1.7/include/cmocka.h b/cmake/cmocka-1.1.7/include/cmocka.h new file mode 100644 index 0000000..a21d965 --- /dev/null +++ b/cmake/cmocka-1.1.7/include/cmocka.h @@ -0,0 +1,2455 @@ +/* + * 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 + +#define __func__ __FUNCTION__ + +# ifndef inline +#define inline __inline +# endif /* inline */ + +# if _MSC_VER < 1500 +# ifdef __cplusplus +extern "C" { +# endif /* __cplusplus */ +int __stdcall IsDebuggerPresent(); +# ifdef __cplusplus +} /* extern "C" */ +# endif /* __cplusplus */ +# endif /* _MSC_VER < 1500 */ +# endif /* _MSC_VER */ +#endif /* _WIN32 */ + +/** + * @defgroup cmocka The CMocka API + * + * These headers or their equivalents MUST be included prior to including + * this header file. + * @code + * #include + * #include + * #include + * #include + * #include + * @endcode + * + * This allows test applications to use custom definitions of C standard + * library functions and types. + * + * @{ + */ + +/* If __WORDSIZE is not set, try to figure it out and default to 32 bit. */ +#ifndef __WORDSIZE +# if (defined(__x86_64__) && !defined(__ILP32__)) || defined(__sparc_v9__) || defined(__sparcv9) +# define __WORDSIZE 64 +# else +# define __WORDSIZE 32 +# endif +#endif + +#ifdef DOXYGEN +/** + * Largest integral type. This type should be large enough to hold any + * pointer or integer supported by the compiler. + */ +typedef uintmax_t LargestIntegralType; +#else /* DOXGEN */ +#ifndef LargestIntegralType +# if __WORDSIZE == 64 && !defined(_WIN64) +# define LargestIntegralType unsigned long int +# else +# define LargestIntegralType unsigned long long int +# endif +#endif /* LargestIntegralType */ +#endif /* DOXYGEN */ + +/* Printf format used to display LargestIntegralType as a hexidecimal. */ +#ifndef LargestIntegralTypePrintfFormat +# ifdef _WIN32 +# define LargestIntegralTypePrintfFormat "0x%I64x" +# else +# if __WORDSIZE == 64 +# define LargestIntegralTypePrintfFormat "%#lx" +# else +# define LargestIntegralTypePrintfFormat "%#llx" +# endif +# endif /* _WIN32 */ +#endif /* LargestIntegralTypePrintfFormat */ + +/* Printf format used to display LargestIntegralType as a decimal. */ +#ifndef LargestIntegralTypePrintfFormatDecimal +# ifdef _WIN32 +# define LargestIntegralTypePrintfFormatDecimal "%I64u" +# else +# if __WORDSIZE == 64 +# define LargestIntegralTypePrintfFormatDecimal "%lu" +# else +# define LargestIntegralTypePrintfFormatDecimal "%llu" +# endif +# endif /* _WIN32 */ +#endif /* LargestIntegralTypePrintfFormat */ + +#ifndef FloatPrintfFormat +# define FloatPrintfFormat "%f" +#endif /* FloatPrintfFormat */ + +#ifndef DoublePrintfFormat +# define DoublePrintfFormat "%f" +#endif /* DoublePrintfFormat */ + +/* Perform an unsigned cast to LargestIntegralType. */ +#define cast_to_largest_integral_type(value) \ + ((LargestIntegralType)(value)) + +/* Smallest integral type capable of holding a pointer. */ +#if !defined(_UINTPTR_T) && !defined(_UINTPTR_T_DEFINED) && !defined(HAVE_UINTPTR_T) +# if defined(_WIN32) + /* WIN32 is an ILP32 platform */ + typedef unsigned int uintptr_t; +# elif defined(_WIN64) + typedef unsigned long int uintptr_t; +# else /* _WIN32 */ + +/* ILP32 and LP64 platforms */ +# ifdef __WORDSIZE /* glibc */ +# if __WORDSIZE == 64 + typedef unsigned long int uintptr_t; +# else + typedef unsigned int uintptr_t; +# endif /* __WORDSIZE == 64 */ +# else /* __WORDSIZE */ +# if defined(_LP64) || defined(_I32LPx) + typedef unsigned long int uintptr_t; +# else + typedef unsigned int uintptr_t; +# endif +# endif /* __WORDSIZE */ +# endif /* _WIN32 */ + +# define _UINTPTR_T +# define _UINTPTR_T_DEFINED +#endif /* !defined(_UINTPTR_T) || !defined(_UINTPTR_T_DEFINED) */ + +/* Perform an unsigned cast to uintptr_t. */ +#define cast_to_pointer_integral_type(value) \ + ((uintptr_t)((size_t)(value))) + +/* Perform a cast of a pointer to LargestIntegralType */ +#define cast_ptr_to_largest_integral_type(value) \ +cast_to_largest_integral_type(cast_to_pointer_integral_type(value)) + +/* GCC have printf type attribute check. */ +#ifdef __GNUC__ +#define CMOCKA_PRINTF_ATTRIBUTE(a,b) \ + __attribute__ ((__format__ (__printf__, a, b))) +#else +#define CMOCKA_PRINTF_ATTRIBUTE(a,b) +#endif /* __GNUC__ */ + +#if defined(__GNUC__) +#define CMOCKA_DEPRECATED __attribute__ ((deprecated)) +#elif defined(_MSC_VER) +#define CMOCKA_DEPRECATED __declspec(deprecated) +#else +#define CMOCKA_DEPRECATED +#endif + +#if defined(__GNUC__) +#define CMOCKA_NORETURN __attribute__ ((noreturn)) +#elif defined(_MSC_VER) +#define CMOCKA_NORETURN __declspec(noreturn) +#else +#define CMOCKA_NORETURN +#endif + +#define WILL_RETURN_ALWAYS -1 +#define WILL_RETURN_ONCE -2 + +/** + * @defgroup cmocka_mock Mock Objects + * @ingroup cmocka + * + * 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 stack 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 stack 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 + * stack using will_return() than consumed with mock() and vice-versa. + * + * The following unit test stub illustrates how would a unit test instruct the + * mock object to return a particular value: + * + * @code + * will_return(chef_cook, "hotdog"); + * will_return(chef_cook, 0); + * @endcode + * + * Now the mock object can check if the parameter it received is the parameter + * which is expected by the test driver. This can be done the following way: + * + * @code + * int chef_cook(const char *order, char **dish_out) + * { + * check_expected(order); + * } + * @endcode + * + * For a complete example please take a look + * here. + * + * @{ + */ + +#ifdef DOXYGEN +/** + * @brief Retrieve a return value of the current function. + * + * @return The value which was stored to return by this function. + * + * @see will_return() + */ +LargestIntegralType mock(void); +#else +#define mock() _mock(__func__, __FILE__, __LINE__) +#endif + +#ifdef DOXYGEN +/** + * @brief Retrieve a typed return value of the current function. + * + * The value would be casted to type internally to avoid having the + * caller to do the cast manually. + * + * @param[in] #type The expected type of the return value + * + * @return The value which was stored to return by this function. + * + * @code + * int param; + * + * param = mock_type(int); + * @endcode + * + * @see will_return() + * @see mock() + * @see mock_ptr_type() + */ +#type mock_type(#type); +#else +#define mock_type(type) ((type) mock()) +#endif + +#ifdef DOXYGEN +/** + * @brief Retrieve a typed return value of the current function. + * + * The value would be casted to type internally to avoid having the + * caller to do the cast manually but also casted to uintptr_t to make + * sure the result has a valid size to be used as a pointer. + * + * @param[in] #type The expected type of the return value + * + * @return The value which was stored to return by this function. + * + * @code + * char *param; + * + * param = mock_ptr_type(char *); + * @endcode + * + * @see will_return() + * @see mock() + * @see mock_type() + */ +type mock_ptr_type(#type); +#else +#define mock_ptr_type(type) ((type) (uintptr_t) mock()) +#endif + + +#ifdef DOXYGEN +/** + * @brief Store a value to be returned by mock() later. + * + * @param[in] #function The function which should return the given value. + * + * @param[in] value The value to be returned by mock(). + * + * @code + * int return_integer(void) + * { + * return (int)mock(); + * } + * + * static void test_integer_return(void **state) + * { + * will_return(return_integer, 42); + * + * assert_int_equal(my_function_calling_return_integer(), 42); + * } + * @endcode + * + * @see mock() + * @see will_return_count() + */ +void will_return(#function, LargestIntegralType value); +#else +#define will_return(function, value) \ + _will_return(#function, __FILE__, __LINE__, \ + cast_to_largest_integral_type(value), 1) +#endif + +#ifdef DOXYGEN +/** + * @brief Store a value to be returned by mock() later. + * + * @param[in] #function The function which should return the given value. + * + * @param[in] value The value to be returned by mock(). + * + * @param[in] count The parameter indicates the number of times the value should + * be returned by mock(). If count is set to -1, the value + * will always be returned but must be returned at least once. + * If count is set to -2, the value will always be returned + * by mock(), but is not required to be returned. + * + * @see mock() + */ +void will_return_count(#function, LargestIntegralType value, int count); +#else +#define will_return_count(function, value, count) \ + _will_return(#function, __FILE__, __LINE__, \ + cast_to_largest_integral_type(value), count) +#endif + +#ifdef DOXYGEN +/** + * @brief Store a value that will be always returned by mock(). + * + * @param[in] #function The function which should return the given value. + * + * @param[in] #value The value to be returned by mock(). + * + * This is equivalent to: + * @code + * will_return_count(function, value, -1); + * @endcode + * + * @see will_return_count() + * @see mock() + */ +void will_return_always(#function, LargestIntegralType value); +#else +#define will_return_always(function, value) \ + will_return_count(function, (value), WILL_RETURN_ALWAYS) +#endif + +#ifdef DOXYGEN +/** + * @brief Store a value that may be always returned by mock(). + * + * This stores a value which will always be returned by mock() but is not + * required to be returned by at least one call to mock(). Therefore, + * in contrast to will_return_always() which causes a test failure if it + * is not returned at least once, will_return_maybe() will never cause a test + * to fail if its value is not returned. + * + * @param[in] #function The function which should return the given value. + * + * @param[in] #value The value to be returned by mock(). + * + * This is equivalent to: + * @code + * will_return_count(function, value, -2); + * @endcode + * + * @see will_return_count() + * @see mock() + */ +void will_return_maybe(#function, LargestIntegralType value); +#else +#define will_return_maybe(function, value) \ + will_return_count(function, (value), WILL_RETURN_ONCE) +#endif +/** @} */ + +/** + * @defgroup cmocka_param Checking Parameters + * @ingroup cmocka + * + * Functionality to store expected values for mock function parameters. + * + * In addition to storing the return values of mock functions, cmocka provides + * functionality to store expected values for mock function parameters using + * the expect_*() functions provided. A mock function parameter can then be + * validated using the check_expected() macro. + * + * Successive calls to expect_*() macros for a parameter queues values to check + * the specified parameter. check_expected() checks a function parameter + * against the next value queued using expect_*(), if the parameter check fails + * a test failure is signalled. In addition if check_expected() is called and + * no more parameter values are queued a test failure occurs. + * + * The following test stub illustrates how to do this. First is the the function + * we call in the test driver: + * + * @code + * static void test_driver(void **state) + * { + * expect_string(chef_cook, order, "hotdog"); + * } + * @endcode + * + * Now the chef_cook function can check if the parameter we got passed is the + * parameter which is expected by the test driver. This can be done the + * following way: + * + * @code + * int chef_cook(const char *order, char **dish_out) + * { + * check_expected(order); + * } + * @endcode + * + * For a complete example please take a look + * here + * + * @{ + */ + +/* + * Add a custom parameter checking function. If the event parameter is NULL + * the event structure is allocated internally by this function. If event + * parameter is provided it must be allocated on the heap and doesn't need to + * be deallocated by the caller. + */ +#ifdef DOXYGEN +/** + * @brief Add a custom parameter checking function. + * + * If the event parameter is NULL the event structure is allocated internally + * by this function. If the parameter is provided it must be allocated on the + * heap and doesn't need to be deallocated by the caller. + * + * @param[in] #function The function to add a custom parameter checking + * function for. + * + * @param[in] #parameter The parameters passed to the function. + * + * @param[in] #check_function The check function to call. + * + * @param[in] check_data The data to pass to the check function. + */ +void expect_check(#function, #parameter, #check_function, const void *check_data); +#else +#define expect_check(function, parameter, check_function, check_data) \ + _expect_check(#function, #parameter, __FILE__, __LINE__, check_function, \ + cast_to_largest_integral_type(check_data), NULL, 1) +#endif + +#ifdef DOXYGEN +/** + * @brief Add an event to check if the parameter value is part of the provided + * array. + * + * The event is triggered by calling check_expected() in the mocked function. + * + * @param[in] #function The function to add the check for. + * + * @param[in] #parameter The name of the parameter passed to the function. + * + * @param[in] value_array[] The array to check for the value. + * + * @see check_expected(). + */ +void expect_in_set(#function, #parameter, LargestIntegralType value_array[]); +#else +#define expect_in_set(function, parameter, value_array) \ + expect_in_set_count(function, parameter, value_array, 1) +#endif + +#ifdef DOXYGEN +/** + * @brief Add an event to check if the parameter value is part of the provided + * array. + * + * The event is triggered by calling check_expected() in the mocked function. + * + * @param[in] #function The function to add the check for. + * + * @param[in] #parameter The name of the parameter passed to the function. + * + * @param[in] value_array[] The array to check for the value. + * + * @param[in] count The count parameter returns the number of times the value + * should be returned by check_expected(). If count is set + * to -1 the value will always be returned. + * + * @see check_expected(). + */ +void expect_in_set_count(#function, #parameter, LargestIntegralType value_array[], size_t count); +#else +#define expect_in_set_count(function, parameter, value_array, count) \ + _expect_in_set(#function, #parameter, __FILE__, __LINE__, value_array, \ + sizeof(value_array) / sizeof((value_array)[0]), count) +#endif + +#ifdef DOXYGEN +/** + * @brief Add an event to check if the parameter value is not part of the + * provided array. + * + * The event is triggered by calling check_expected() in the mocked function. + * + * @param[in] #function The function to add the check for. + * + * @param[in] #parameter The name of the parameter passed to the function. + * + * @param[in] value_array[] The array to check for the value. + * + * @see check_expected(). + */ +void expect_not_in_set(#function, #parameter, LargestIntegralType value_array[]); +#else +#define expect_not_in_set(function, parameter, value_array) \ + expect_not_in_set_count(function, parameter, value_array, 1) +#endif + +#ifdef DOXYGEN +/** + * @brief Add an event to check if the parameter value is not part of the + * provided array. + * + * The event is triggered by calling check_expected() in the mocked function. + * + * @param[in] #function The function to add the check for. + * + * @param[in] #parameter The name of the parameter passed to the function. + * + * @param[in] value_array[] The array to check for the value. + * + * @param[in] count The count parameter returns the number of times the value + * should be returned by check_expected(). If count is set + * to -1 the value will always be returned. + * + * @see check_expected(). + */ +void expect_not_in_set_count(#function, #parameter, LargestIntegralType value_array[], size_t count); +#else +#define expect_not_in_set_count(function, parameter, value_array, count) \ + _expect_not_in_set( \ + #function, #parameter, __FILE__, __LINE__, value_array, \ + sizeof(value_array) / sizeof((value_array)[0]), count) +#endif + + +#ifdef DOXYGEN +/** + * @brief Add an event to check a parameter is inside a numerical range. + * The check would succeed if minimum <= value <= maximum. + * + * The event is triggered by calling check_expected() in the mocked function. + * + * @param[in] #function The function to add the check for. + * + * @param[in] #parameter The name of the parameter passed to the function. + * + * @param[in] minimum The lower boundary of the interval to check against. + * + * @param[in] maximum The upper boundary of the interval to check against. + * + * @see check_expected(). + */ +void expect_in_range(#function, #parameter, LargestIntegralType minimum, LargestIntegralType maximum); +#else +#define expect_in_range(function, parameter, minimum, maximum) \ + expect_in_range_count(function, parameter, minimum, maximum, 1) +#endif + +#ifdef DOXYGEN +/** + * @brief Add an event to repeatedly check a parameter is inside a + * numerical range. The check would succeed if minimum <= value <= maximum. + * + * The event is triggered by calling check_expected() in the mocked function. + * + * @param[in] #function The function to add the check for. + * + * @param[in] #parameter The name of the parameter passed to the function. + * + * @param[in] minimum The lower boundary of the interval to check against. + * + * @param[in] maximum The upper boundary of the interval to check against. + * + * @param[in] count The count parameter returns the number of times the value + * should be returned by check_expected(). If count is set + * to -1 the value will always be returned. + * + * @see check_expected(). + */ +void expect_in_range_count(#function, #parameter, LargestIntegralType minimum, LargestIntegralType maximum, size_t count); +#else +#define expect_in_range_count(function, parameter, minimum, maximum, count) \ + _expect_in_range(#function, #parameter, __FILE__, __LINE__, minimum, \ + maximum, count) +#endif + +#ifdef DOXYGEN +/** + * @brief Add an event to check a parameter is outside a numerical range. + * The check would succeed if minimum > value > maximum. + * + * The event is triggered by calling check_expected() in the mocked function. + * + * @param[in] #function The function to add the check for. + * + * @param[in] #parameter The name of the parameter passed to the function. + * + * @param[in] minimum The lower boundary of the interval to check against. + * + * @param[in] maximum The upper boundary of the interval to check against. + * + * @see check_expected(). + */ +void expect_not_in_range(#function, #parameter, LargestIntegralType minimum, LargestIntegralType maximum); +#else +#define expect_not_in_range(function, parameter, minimum, maximum) \ + expect_not_in_range_count(function, parameter, minimum, maximum, 1) +#endif + +#ifdef DOXYGEN +/** + * @brief Add an event to repeatedly check a parameter is outside a + * numerical range. The check would succeed if minimum > value > maximum. + * + * The event is triggered by calling check_expected() in the mocked function. + * + * @param[in] #function The function to add the check for. + * + * @param[in] #parameter The name of the parameter passed to the function. + * + * @param[in] minimum The lower boundary of the interval to check against. + * + * @param[in] maximum The upper boundary of the interval to check against. + * + * @param[in] count The count parameter returns the number of times the value + * should be returned by check_expected(). If count is set + * to -1 the value will always be returned. + * + * @see check_expected(). + */ +void expect_not_in_range_count(#function, #parameter, LargestIntegralType minimum, LargestIntegralType maximum, size_t count); +#else +#define expect_not_in_range_count(function, parameter, minimum, maximum, \ + count) \ + _expect_not_in_range(#function, #parameter, __FILE__, __LINE__, \ + minimum, maximum, count) +#endif + +#ifdef DOXYGEN +/** + * @brief Add an event to check if a parameter is the given integer based 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() + * @see expect_string() + * @see expect_memory() + * @see expect_any() + */ +void expect_value(#function, #parameter, LargestIntegralType value); +#else +#define expect_value(function, parameter, value) \ + expect_value_count(function, parameter, value, 1) +#endif + +#ifdef DOXYGEN +/** + * @brief Add an event to repeatedly check if a parameter is the given integer + * based 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(). + * @see expect_not_string() + * @see expect_not_memory() + */ +void expect_value_count(#function, #parameter, LargestIntegralType value, size_t count); +#else +#define expect_value_count(function, parameter, value, count) \ + _expect_value(#function, #parameter, __FILE__, __LINE__, \ + cast_to_largest_integral_type(value), count) +#endif + +#ifdef DOXYGEN +/** + * @brief Add an event to check if a parameter isn't the given value. + * + * The event is triggered by calling check_expected() in the mocked function. + * + * @param[in] #function The function to add the check for. + * + * @param[in] #parameter The name of the parameter passed to the function. + * + * @param[in] value The value to check. + * + * @see check_expected(). + */ +void expect_not_value(#function, #parameter, LargestIntegralType value); +#else +#define expect_not_value(function, parameter, value) \ + expect_not_value_count(function, parameter, value, 1) +#endif + +#ifdef DOXYGEN +/** + * @brief Add an event to repeatedly check if a parameter isn't the given value. + * + * The event is triggered by calling check_expected() in the mocked function. + * + * @param[in] #function The function to add the check for. + * + * @param[in] #parameter The name of the parameter passed to the function. + * + * @param[in] value The value to check. + * + * @param[in] count The count parameter returns the number of times the value + * should be returned by check_expected(). If count is set + * to -1 the value will always be returned. + * + * @see check_expected(). + */ +void expect_not_value_count(#function, #parameter, LargestIntegralType value, size_t count); +#else +#define expect_not_value_count(function, parameter, value, count) \ + _expect_not_value(#function, #parameter, __FILE__, __LINE__, \ + cast_to_largest_integral_type(value), count) +#endif + +#ifdef DOXYGEN +/** + * @brief Add an event to check if the parameter value is equal to the + * provided string. + * + * The event is triggered by calling check_expected() in the mocked function. + * + * @param[in] #function The function to add the check for. + * + * @param[in] #parameter The name of the parameter passed to the function. + * + * @param[in] string The string value to compare. + * + * @see check_expected(). + */ +void expect_string(#function, #parameter, const char *string); +#else +#define expect_string(function, parameter, string) \ + expect_string_count(function, parameter, string, 1) +#endif + +#ifdef DOXYGEN +/** + * @brief Add an event to check if the parameter value is equal to the + * provided string. + * + * The event is triggered by calling check_expected() in the mocked function. + * + * @param[in] #function The function to add the check for. + * + * @param[in] #parameter The name of the parameter passed to the function. + * + * @param[in] string The string value to compare. + * + * @param[in] count The count parameter returns the number of times the value + * should be returned by check_expected(). If count is set + * to -1 the value will always be returned. + * + * @see check_expected(). + */ +void expect_string_count(#function, #parameter, const char *string, size_t count); +#else +#define expect_string_count(function, parameter, string, count) \ + _expect_string(#function, #parameter, __FILE__, __LINE__, \ + (const char*)(string), count) +#endif + +#ifdef DOXYGEN +/** + * @brief Add an event to check if the parameter value isn't equal to the + * provided string. + * + * The event is triggered by calling check_expected() in the mocked function. + * + * @param[in] #function The function to add the check for. + * + * @param[in] #parameter The name of the parameter passed to the function. + * + * @param[in] string The string value to compare. + * + * @see check_expected(). + */ +void expect_not_string(#function, #parameter, const char *string); +#else +#define expect_not_string(function, parameter, string) \ + expect_not_string_count(function, parameter, string, 1) +#endif + +#ifdef DOXYGEN +/** + * @brief Add an event to check if the parameter value isn't equal to the + * provided string. + * + * The event is triggered by calling check_expected() in the mocked function. + * + * @param[in] #function The function to add the check for. + * + * @param[in] #parameter The name of the parameter passed to the function. + * + * @param[in] string The string value to compare. + * + * @param[in] count The count parameter returns the number of times the value + * should be returned by check_expected(). If count is set + * to -1 the value will always be returned. + * + * @see check_expected(). + */ +void expect_not_string_count(#function, #parameter, const char *string, size_t count); +#else +#define expect_not_string_count(function, parameter, string, count) \ + _expect_not_string(#function, #parameter, __FILE__, __LINE__, \ + (const char*)(string), count) +#endif + +#ifdef DOXYGEN +/** + * @brief Add an event to check if the parameter does match an area of memory. + * + * The event is triggered by calling check_expected() in the mocked function. + * + * @param[in] #function The function to add the check for. + * + * @param[in] #parameter The name of the parameter passed to the function. + * + * @param[in] memory The memory to compare. + * + * @param[in] size The size of the memory to compare. + * + * @see check_expected(). + */ +void expect_memory(#function, #parameter, void *memory, size_t size); +#else +#define expect_memory(function, parameter, memory, size) \ + expect_memory_count(function, parameter, memory, size, 1) +#endif + +#ifdef DOXYGEN +/** + * @brief Add an event to repeatedly check if the parameter does match an area + * of memory. + * + * The event is triggered by calling check_expected() in the mocked function. + * + * @param[in] #function The function to add the check for. + * + * @param[in] #parameter The name of the parameter passed to the function. + * + * @param[in] memory The memory to compare. + * + * @param[in] size The size of the memory to compare. + * + * @param[in] count The count parameter returns the number of times the value + * should be returned by check_expected(). If count is set + * to -1 the value will always be returned. + * + * @see check_expected(). + */ +void expect_memory_count(#function, #parameter, void *memory, size_t size, size_t count); +#else +#define expect_memory_count(function, parameter, memory, size, count) \ + _expect_memory(#function, #parameter, __FILE__, __LINE__, \ + (const void*)(memory), size, count) +#endif + +#ifdef DOXYGEN +/** + * @brief Add an event to check if the parameter doesn't match an area of + * memory. + * + * The event is triggered by calling check_expected() in the mocked function. + * + * @param[in] #function The function to add the check for. + * + * @param[in] #parameter The name of the parameter passed to the function. + * + * @param[in] memory The memory to compare. + * + * @param[in] size The size of the memory to compare. + * + * @see check_expected(). + */ +void expect_not_memory(#function, #parameter, void *memory, size_t size); +#else +#define expect_not_memory(function, parameter, memory, size) \ + expect_not_memory_count(function, parameter, memory, size, 1) +#endif + +#ifdef DOXYGEN +/** + * @brief Add an event to repeatedly check if the parameter doesn't match an + * area of memory. + * + * The event is triggered by calling check_expected() in the mocked function. + * + * @param[in] #function The function to add the check for. + * + * @param[in] #parameter The name of the parameter passed to the function. + * + * @param[in] memory The memory to compare. + * + * @param[in] size The size of the memory to compare. + * + * @param[in] count The count parameter returns the number of times the value + * should be returned by check_expected(). If count is set + * to -1 the value will always be returned. + * + * @see check_expected(). + */ +void expect_not_memory_count(#function, #parameter, void *memory, size_t size, size_t count); +#else +#define expect_not_memory_count(function, parameter, memory, size, count) \ + _expect_not_memory(#function, #parameter, __FILE__, __LINE__, \ + (const void*)(memory), size, count) +#endif + + +#ifdef DOXYGEN +/** + * @brief Add an event to check if a parameter (of any value) has been passed. + * + * The event is triggered by calling check_expected() in the mocked function. + * + * @param[in] #function The function to add the check for. + * + * @param[in] #parameter The name of the parameter passed to the function. + * + * @see check_expected(). + */ +void expect_any(#function, #parameter); +#else +#define expect_any(function, parameter) \ + expect_any_count(function, parameter, 1) +#endif + +#ifdef DOXYGEN +/** + * @brief Add an event to 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(#function, #parameter, __FILE__, __LINE__, count) +#endif + +#ifdef DOXYGEN +/** + * @brief Determine whether a function parameter is correct. + * + * This ensures the next value queued by one of the expect_*() macros matches + * the specified variable. + * + * This function needs to be called in the mock object. + * + * @param[in] #parameter The parameter to check. + */ +void check_expected(#parameter); +#else +#define check_expected(parameter) \ + _check_expected(__func__, #parameter, __FILE__, __LINE__, \ + cast_to_largest_integral_type(parameter)) +#endif + +#ifdef DOXYGEN +/** + * @brief Determine whether a function parameter is correct. + * + * This ensures the next value queued by one of the expect_*() macros matches + * the specified variable. + * + * This function needs to be called in the mock object. + * + * @param[in] #parameter The pointer to check. + */ +void check_expected_ptr(#parameter); +#else +#define check_expected_ptr(parameter) \ + _check_expected(__func__, #parameter, __FILE__, __LINE__, \ + cast_ptr_to_largest_integral_type(parameter)) +#endif + +/** @} */ + +/** + * @defgroup cmocka_asserts Assert Macros + * @ingroup cmocka + * + * This is a set of useful assert macros like the standard C libary's + * assert(3) macro. + * + * On an assertion failure a cmocka assert macro will write the failure to the + * standard error stream and signal a test failure. Due to limitations of the C + * language the general C standard library assert() and cmocka's assert_true() + * and assert_false() macros can only display the expression that caused the + * assert failure. cmocka's type specific assert macros, assert_{type}_equal() + * and assert_{type}_not_equal(), display the data that caused the assertion + * failure which increases data visibility aiding debugging of failing test + * cases. + * + * @{ + */ + +#ifdef DOXYGEN +/** + * @brief Assert that the given expression is true. + * + * The function prints an error message to standard error and terminates the + * test by calling fail() if expression is false (i.e., compares equal to + * zero). + * + * @param[in] expression The expression to evaluate. + * + * @see assert_int_equal() + * @see assert_string_equal() + */ +void assert_true(scalar expression); +#else +#define assert_true(c) _assert_true(cast_to_largest_integral_type(c), #c, \ + __FILE__, __LINE__) +#endif + +#ifdef DOXYGEN +/** + * @brief Assert that the given expression is false. + * + * The function prints an error message to standard error and terminates the + * test by calling fail() if expression is true. + * + * @param[in] expression The expression to evaluate. + * + * @see assert_int_equal() + * @see assert_string_equal() + */ +void assert_false(scalar expression); +#else +#define assert_false(c) _assert_true(!(cast_to_largest_integral_type(c)), #c, \ + __FILE__, __LINE__) +#endif + +#ifdef DOXYGEN +/** + * @brief Assert that the return_code is greater than or equal to 0. + * + * The function prints an error message to standard error and terminates the + * test by calling fail() if the return code is smaller than 0. If the function + * you check sets an errno if it fails you can pass it to the function and + * it will be printed as part of the error message. + * + * @param[in] rc The return code to evaluate. + * + * @param[in] error Pass errno here or 0. + */ +void assert_return_code(int rc, int error); +#else +#define assert_return_code(rc, error) \ + _assert_return_code(cast_to_largest_integral_type(rc), \ + sizeof(rc), \ + cast_to_largest_integral_type(error), \ + #rc, __FILE__, __LINE__) +#endif + +#ifdef DOXYGEN +/** + * @brief Assert that the given pointer is non-NULL. + * + * The function prints an error message to standard error and terminates the + * test by calling fail() if the pointer is NULL. + * + * @param[in] pointer The pointer to evaluate. + * + * @see assert_null() + */ +void assert_non_null(void *pointer); +#else +#define assert_non_null(c) _assert_true(cast_ptr_to_largest_integral_type(c), #c, \ + __FILE__, __LINE__) +#endif + +#ifdef DOXYGEN +/** + * @brief Assert that the given pointer is NULL. + * + * The function prints an error message to standard error and terminates the + * test by calling fail() if the pointer is non-NULL. + * + * @param[in] pointer The pointer to evaluate. + * + * @see assert_non_null() + */ +void assert_null(void *pointer); +#else +#define assert_null(c) _assert_true(!(cast_ptr_to_largest_integral_type(c)), #c, \ +__FILE__, __LINE__) +#endif + +#ifdef DOXYGEN +/** + * @brief Assert that the two given pointers are equal. + * + * The function prints an error message and terminates the test by calling + * fail() if the pointers are not equal. + * + * @param[in] a The first pointer to compare. + * + * @param[in] b The pointer to compare against the first one. + */ +void assert_ptr_equal(void *a, void *b); +#else +#define assert_ptr_equal(a, b) \ + _assert_int_equal(cast_ptr_to_largest_integral_type(a), \ + cast_ptr_to_largest_integral_type(b), \ + __FILE__, __LINE__) +#endif + +#ifdef DOXYGEN +/** + * @brief Assert that the two given pointers are not equal. + * + * The function prints an error message and terminates the test by calling + * fail() if the pointers are equal. + * + * @param[in] a The first pointer to compare. + * + * @param[in] b The pointer to compare against the first one. + */ +void assert_ptr_not_equal(void *a, void *b); +#else +#define assert_ptr_not_equal(a, b) \ + _assert_int_not_equal(cast_ptr_to_largest_integral_type(a), \ + cast_ptr_to_largest_integral_type(b), \ + __FILE__, __LINE__) +#endif + +#ifdef DOXYGEN +/** + * @brief Assert that the two given integers are equal. + * + * The function prints an error message to standard error and terminates the + * test by calling fail() if the integers are not equal. + * + * @param[in] a The first integer to compare. + * + * @param[in] b The integer to compare against the first one. + */ +void assert_int_equal(int a, int b); +#else +#define assert_int_equal(a, b) \ + _assert_int_equal(cast_to_largest_integral_type(a), \ + cast_to_largest_integral_type(b), \ + __FILE__, __LINE__) +#endif + +#ifdef DOXYGEN +/** + * @brief Assert that the two given integers are not equal. + * + * The function prints an error message to standard error and terminates the + * test by calling fail() if the integers are equal. + * + * @param[in] a The first integer to compare. + * + * @param[in] b The integer to compare against the first one. + * + * @see assert_int_equal() + */ +void assert_int_not_equal(int a, int b); +#else +#define assert_int_not_equal(a, b) \ + _assert_int_not_equal(cast_to_largest_integral_type(a), \ + cast_to_largest_integral_type(b), \ + __FILE__, __LINE__) +#endif + +#ifdef DOXYGEN +/** + * @brief Assert that the two given 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((float)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 value is not smaller than the minimum + * and and not greater than the maximum. + * + * The function prints an error message to standard error and terminates the + * test by calling fail() if value is not in range. + * + * @param[in] value The value to check. + * + * @param[in] minimum The minimum value allowed. + * + * @param[in] maximum The maximum value allowed. + */ +void assert_in_range(LargestIntegralType value, LargestIntegralType minimum, LargestIntegralType maximum); +#else +#define assert_in_range(value, minimum, maximum) \ + _assert_in_range( \ + cast_to_largest_integral_type(value), \ + cast_to_largest_integral_type(minimum), \ + cast_to_largest_integral_type(maximum), __FILE__, __LINE__) +#endif + +#ifdef DOXYGEN +/** + * @brief Assert that the specified value is smaller than the minimum or + * greater than the maximum. + * + * The function prints an error message to standard error and terminates the + * test by calling fail() if value is in range. + * + * @param[in] value The value to check. + * + * @param[in] minimum The minimum value to compare. + * + * @param[in] maximum The maximum value to compare. + */ +void assert_not_in_range(LargestIntegralType value, LargestIntegralType minimum, LargestIntegralType maximum); +#else +#define assert_not_in_range(value, minimum, maximum) \ + _assert_not_in_range( \ + cast_to_largest_integral_type(value), \ + cast_to_largest_integral_type(minimum), \ + cast_to_largest_integral_type(maximum), __FILE__, __LINE__) +#endif + +#ifdef DOXYGEN +/** + * @brief Assert that the specified value is within a set. + * + * The function prints an error message to standard error and terminates the + * test by calling fail() if value is not within a set. + * + * @param[in] value The value to look up + * + * @param[in] values[] The array to check for the value. + * + * @param[in] count The size of the values array. + */ +void assert_in_set(LargestIntegralType value, LargestIntegralType values[], size_t count); +#else +#define assert_in_set(value, values, number_of_values) \ + _assert_in_set(value, values, number_of_values, __FILE__, __LINE__) +#endif + +#ifdef DOXYGEN +/** + * @brief Assert that the specified value is not within a set. + * + * The function prints an error message to standard error and terminates the + * test by calling fail() if value is within a set. + * + * @param[in] value The value to look up + * + * @param[in] values[] The array to check for the value. + * + * @param[in] count The size of the values array. + */ +void assert_not_in_set(LargestIntegralType value, LargestIntegralType values[], size_t count); +#else +#define assert_not_in_set(value, values, number_of_values) \ + _assert_not_in_set(value, values, number_of_values, __FILE__, __LINE__) +#endif + +/** @} */ + +/** + * @defgroup cmocka_call_order Call Ordering + * @ingroup cmocka + * + * It is often beneficial to make sure that functions are called in an + * order. This is independent of mock returns and parameter checking as both + * of the aforementioned do not check the order in which they are called from + * different functions. + * + *
    + *
  • 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(#function, __FILE__, __LINE__, times) +#endif + +#ifdef DOXYGEN +/** + * @brief Store expected single call to a mock to be checked by + * function_called() later. + * + * @param[in] #function The function which should should be called + * + * @see function_called() + */ +void expect_function_call(#function); +#else +#define expect_function_call(function) \ + _expect_function_call(#function, __FILE__, __LINE__, 1) +#endif + +#ifdef DOXYGEN +/** + * @brief Expects function_called() from given mock at least once + * + * @param[in] #function The function which should should be called + * + * @see function_called() + */ +void expect_function_call_any(#function); +#else +#define expect_function_call_any(function) \ + _expect_function_call(#function, __FILE__, __LINE__, -1) +#endif + +#ifdef DOXYGEN +/** + * @brief Ignores function_called() invocations from given mock function. + * + * @param[in] #function The function which should should be called + * + * @see function_called() + */ +void ignore_function_calls(#function); +#else +#define ignore_function_calls(function) \ + _expect_function_call(#function, __FILE__, __LINE__, -2) +#endif + +/** @} */ + +/** + * @defgroup cmocka_exec Running Tests + * @ingroup cmocka + * + * This is the way tests are executed with CMocka. + * + * The following example illustrates this macro's use with the unit_test macro. + * + * @code + * void Test0(void **state); + * void Test1(void **state); + * + * int main(void) + * { + * const struct CMUnitTest tests[] = { + * cmocka_unit_test(Test0), + * cmocka_unit_test(Test1), + * }; + * + * return cmocka_run_group_tests(tests, NULL, NULL); + * } + * @endcode + * + * @{ + */ + +#ifdef DOXYGEN +/** + * @brief Forces the test to fail immediately and quit. + */ +void fail(void); +#else +#define fail() _fail(__FILE__, __LINE__) +#endif + +#ifdef DOXYGEN +/** + * @brief Forces the test to not be executed, but marked as skipped + */ +void skip(void); +#else +#define skip() _skip(__FILE__, __LINE__) +#endif + +#ifdef DOXYGEN +/** + * @brief Forces the test to fail immediately and quit, printing the reason. + * + * @code + * fail_msg("This is some error message for test"); + * @endcode + * + * or + * + * @code + * char *error_msg = "This is some error message for test"; + * fail_msg("%s", error_msg); + * @endcode + */ +void fail_msg(const char *msg, ...); +#else +#define fail_msg(msg, ...) do { \ + cm_print_error("ERROR: " msg "\n", ##__VA_ARGS__); \ + fail(); \ +} while (0) +#endif + +#ifdef DOXYGEN +/** + * @brief Generic method to run a single test. + * + * @deprecated This function was deprecated in favor of cmocka_run_group_tests + * + * @param[in] #function The function to test. + * + * @return 0 on success, 1 if an error occured. + * + * @code + * // A test case that does nothing and succeeds. + * void null_test_success(void **state) { + * } + * + * int main(void) { + * return run_test(null_test_success); + * } + * @endcode + */ +int run_test(#function); +#else +#define run_test(f) _run_test(#f, f, NULL, UNIT_TEST_FUNCTION_TYPE_TEST, NULL) +#endif + +static inline void _unit_test_dummy(void **state) { + (void)state; +} + +/** Initializes a UnitTest structure. + * + * @deprecated This function was deprecated in favor of cmocka_unit_test + */ +#define unit_test(f) { #f, f, UNIT_TEST_FUNCTION_TYPE_TEST } + +#define _unit_test_setup(test, setup) \ + { #test "_" #setup, setup, UNIT_TEST_FUNCTION_TYPE_SETUP } + +/** Initializes a UnitTest structure with a setup function. + * + * @deprecated This function was deprecated in favor of cmocka_unit_test_setup + */ +#define unit_test_setup(test, setup) \ + _unit_test_setup(test, setup), \ + unit_test(test), \ + _unit_test_teardown(test, _unit_test_dummy) + +#define _unit_test_teardown(test, teardown) \ + { #test "_" #teardown, teardown, UNIT_TEST_FUNCTION_TYPE_TEARDOWN } + +/** Initializes a UnitTest structure with a teardown function. + * + * @deprecated This function was deprecated in favor of cmocka_unit_test_teardown + */ +#define unit_test_teardown(test, teardown) \ + _unit_test_setup(test, _unit_test_dummy), \ + unit_test(test), \ + _unit_test_teardown(test, teardown) + +/** Initializes a UnitTest structure for a group setup function. + * + * @deprecated This function was deprecated in favor of cmocka_run_group_tests + */ +#define group_test_setup(setup) \ + { "group_" #setup, setup, UNIT_TEST_FUNCTION_TYPE_GROUP_SETUP } + +/** Initializes a UnitTest structure for a group teardown function. + * + * @deprecated This function was deprecated in favor of cmocka_run_group_tests + */ +#define group_test_teardown(teardown) \ + { "group_" #teardown, teardown, UNIT_TEST_FUNCTION_TYPE_GROUP_TEARDOWN } + +/** + * Initialize an array of UnitTest structures with a setup function for a test + * and a teardown function. Either setup or teardown can be NULL. + * + * @deprecated This function was deprecated in favor of + * cmocka_unit_test_setup_teardown + */ +#define unit_test_setup_teardown(test, setup, teardown) \ + _unit_test_setup(test, setup), \ + unit_test(test), \ + _unit_test_teardown(test, teardown) + + +/** Initializes a CMUnitTest structure. */ +#define cmocka_unit_test(f) { #f, f, NULL, NULL, NULL } + +/** Initializes a CMUnitTest structure with a setup function. */ +#define cmocka_unit_test_setup(f, setup) { #f, f, setup, NULL, NULL } + +/** Initializes a CMUnitTest structure with a teardown function. */ +#define cmocka_unit_test_teardown(f, teardown) { #f, f, NULL, teardown, NULL } + +/** + * Initialize an array of CMUnitTest structures with a setup function for a test + * and a teardown function. Either setup or teardown can be NULL. + */ +#define cmocka_unit_test_setup_teardown(f, setup, teardown) { #f, f, setup, teardown, NULL } + +/** + * Initialize a CMUnitTest structure with given initial state. It will be passed + * to test function as an argument later. It can be used when test state does + * not need special initialization or was initialized already. + * @note If the group setup function initialized the state already, it won't be + * overridden by the initial state defined here. + */ +#define cmocka_unit_test_prestate(f, state) { #f, f, NULL, NULL, state } + +/** + * Initialize a CMUnitTest structure with given initial state, setup and + * teardown function. Any of these values can be NULL. Initial state is passed + * later to setup function, or directly to test if none was given. + * @note If the group setup function initialized the state already, it won't be + * overridden by the initial state defined here. + */ +#define cmocka_unit_test_prestate_setup_teardown(f, setup, teardown, state) { #f, f, setup, teardown, state } + +#define run_tests(tests) _run_tests(tests, sizeof(tests) / sizeof((tests)[0])) +#define run_group_tests(tests) _run_group_tests(tests, sizeof(tests) / sizeof((tests)[0])) + +#ifdef DOXYGEN +/** + * @brief Run tests specified by an array of CMUnitTest structures. + * + * @param[in] group_tests[] The array of unit tests to execute. + * + * @param[in] group_setup The setup function which should be called before + * all unit tests are executed. + * + * @param[in] group_teardown The teardown function to be called after all + * tests have finished. + * + * @return 0 on success, or the number of failed tests. + * + * @code + * static int setup(void **state) { + * int *answer = malloc(sizeof(int)); + * if (answer == NULL) { + * return -1; + * } + * *answer = 42; + * + * *state = answer; + * + * return 0; + * } + * + * static int teardown(void **state) { + * free(*state); + * + * return 0; + * } + * + * static void null_test_success(void **state) { + * (void) state; + * } + * + * static void int_test_success(void **state) { + * int *answer = *state; + * assert_int_equal(*answer, 42); + * } + * + * int main(void) { + * const struct CMUnitTest tests[] = { + * cmocka_unit_test(null_test_success), + * cmocka_unit_test_setup_teardown(int_test_success, setup, teardown), + * }; + * + * return cmocka_run_group_tests(tests, NULL, NULL); + * } + * @endcode + * + * @see cmocka_unit_test + * @see cmocka_unit_test_setup + * @see cmocka_unit_test_teardown + * @see cmocka_unit_test_setup_teardown + */ +int cmocka_run_group_tests(const struct CMUnitTest group_tests[], + CMFixtureFunction group_setup, + CMFixtureFunction group_teardown); +#else +# define cmocka_run_group_tests(group_tests, group_setup, group_teardown) \ + _cmocka_run_group_tests(#group_tests, group_tests, sizeof(group_tests) / sizeof((group_tests)[0]), group_setup, group_teardown) +#endif + +#ifdef DOXYGEN +/** + * @brief Run tests specified by an array of CMUnitTest structures and specify + * a name. + * + * @param[in] group_name The name of the group test. + * + * @param[in] group_tests[] The array of unit tests to execute. + * + * @param[in] group_setup The setup function which should be called before + * all unit tests are executed. + * + * @param[in] group_teardown The teardown function to be called after all + * tests have finished. + * + * @return 0 on success, or the number of failed tests. + * + * @code + * static int setup(void **state) { + * int *answer = malloc(sizeof(int)); + * if (answer == NULL) { + * return -1; + * } + * *answer = 42; + * + * *state = answer; + * + * return 0; + * } + * + * static int teardown(void **state) { + * free(*state); + * + * return 0; + * } + * + * static void null_test_success(void **state) { + * (void) state; + * } + * + * static void int_test_success(void **state) { + * int *answer = *state; + * assert_int_equal(*answer, 42); + * } + * + * int main(void) { + * const struct CMUnitTest tests[] = { + * cmocka_unit_test(null_test_success), + * cmocka_unit_test_setup_teardown(int_test_success, setup, teardown), + * }; + * + * return cmocka_run_group_tests_name("success_test", tests, NULL, NULL); + * } + * @endcode + * + * @see cmocka_unit_test + * @see cmocka_unit_test_setup + * @see cmocka_unit_test_teardown + * @see cmocka_unit_test_setup_teardown + */ +int cmocka_run_group_tests_name(const char *group_name, + const struct CMUnitTest group_tests[], + CMFixtureFunction group_setup, + CMFixtureFunction group_teardown); +#else +# define cmocka_run_group_tests_name(group_name, group_tests, group_setup, group_teardown) \ + _cmocka_run_group_tests(group_name, group_tests, sizeof(group_tests) / sizeof((group_tests)[0]), group_setup, group_teardown) +#endif + +/** @} */ + +/** + * @defgroup cmocka_alloc Dynamic Memory Allocation + * @ingroup cmocka + * + * Memory leaks, buffer overflows and underflows can be checked using cmocka. + * + * To test for memory leaks, buffer overflows and underflows a module being + * tested by cmocka should replace calls to malloc(), calloc() and free() to + * test_malloc(), test_calloc() and test_free() respectively. Each time a block + * is deallocated using test_free() it is checked for corruption, if a corrupt + * block is found a test failure is signalled. All blocks allocated using the + * test_*() allocation functions are tracked by the cmocka library. When a test + * completes if any allocated blocks (memory leaks) remain they are reported + * and a test failure is signalled. + * + * For simplicity cmocka currently executes all tests in one process. Therefore + * all test cases in a test application share a single address space which + * means memory corruption from a single test case could potentially cause the + * test application to exit prematurely. + * + * @{ + */ + +#ifdef DOXYGEN +/** + * @brief Test function overriding malloc. + * + * @param[in] size The bytes which should be allocated. + * + * @return A pointer to the allocated memory or NULL on error. + * + * @code + * #ifdef UNIT_TESTING + * extern void* _test_malloc(const size_t size, const char* file, const int line); + * + * #define malloc(size) _test_malloc(size, __FILE__, __LINE__) + * #endif + * + * void leak_memory() { + * int * const temporary = (int*)malloc(sizeof(int)); + * *temporary = 0; + * } + * @endcode + * + * @see malloc(3) + */ +void *test_malloc(size_t size); +#else +#define test_malloc(size) _test_malloc(size, __FILE__, __LINE__) +#endif + +#ifdef DOXYGEN +/** + * @brief Test function overriding calloc. + * + * The memory is set to zero. + * + * @param[in] nmemb The number of elements for an array to be allocated. + * + * @param[in] size The size in bytes of each array element to allocate. + * + * @return A pointer to the allocated memory, NULL on error. + * + * @see calloc(3) + */ +void *test_calloc(size_t nmemb, size_t size); +#else +#define test_calloc(num, size) _test_calloc(num, size, __FILE__, __LINE__) +#endif + +#ifdef DOXYGEN +/** + * @brief Test function overriding realloc which detects buffer overruns + * and memoery leaks. + * + * @param[in] ptr The memory block which should be changed. + * + * @param[in] size The bytes which should be allocated. + * + * @return The newly allocated memory block, NULL on error. + */ +void *test_realloc(void *ptr, size_t size); +#else +#define test_realloc(ptr, size) _test_realloc(ptr, size, __FILE__, __LINE__) +#endif + +#ifdef DOXYGEN +/** + * @brief Test function overriding free(3). + * + * @param[in] ptr The pointer to the memory space to free. + * + * @see free(3). + */ +void test_free(void *ptr); +#else +#define test_free(ptr) _test_free(ptr, __FILE__, __LINE__) +#endif + +/* Redirect malloc, calloc and free to the unit test allocators. */ +#ifdef UNIT_TESTING +#define malloc test_malloc +#define realloc test_realloc +#define calloc test_calloc +#define free test_free +#endif /* UNIT_TESTING */ + +/** @} */ + + +/** + * @defgroup cmocka_mock_assert Standard Assertions + * @ingroup cmocka + * + * How to handle assert(3) of the standard C library. + * + * Runtime assert macros like the standard C library's assert() should be + * redefined in modules being tested to use cmocka's mock_assert() function. + * Normally mock_assert() signals a test failure. If a function is called using + * the expect_assert_failure() macro, any calls to mock_assert() within the + * function will result in the execution of the test. If no calls to + * mock_assert() occur during the function called via expect_assert_failure() a + * test failure is signalled. + * + * @{ + */ + +/** + * @brief Function to replace assert(3) in tested code. + * + * In conjuction with check_assert() it's possible to determine whether an + * assert condition has failed without stopping a test. + * + * @param[in] result The expression to assert. + * + * @param[in] expression The expression as string. + * + * @param[in] file The file mock_assert() is called. + * + * @param[in] line The line mock_assert() is called. + * + * @code + * #ifdef UNIT_TESTING + * extern void mock_assert(const int result, const char* const expression, + * const char * const file, const int line); + * + * #undef assert + * #define assert(expression) \ + * mock_assert((int)(expression), #expression, __FILE__, __LINE__); + * #endif + * + * void increment_value(int * const value) { + * assert(value); + * (*value) ++; + * } + * @endcode + * + * @see assert(3) + * @see expect_assert_failure + */ +void mock_assert(const int result, const char* const expression, + const char * const file, const int line); + +#ifdef DOXYGEN +/** + * @brief Ensure that mock_assert() is called. + * + * If mock_assert() is called the assert expression string is returned. + * + * @param[in] fn_call The function will will call mock_assert(). + * + * @code + * #define assert mock_assert + * + * void showmessage(const char *message) { + * assert(message); + * } + * + * int main(int argc, const char* argv[]) { + * expect_assert_failure(show_message(NULL)); + * printf("succeeded\n"); + * return 0; + * } + * @endcode + * + */ +void expect_assert_failure(function fn_call); +#else +#define expect_assert_failure(function_call) \ + { \ + const int result = setjmp(global_expect_assert_env); \ + global_expecting_assert = 1; \ + if (result) { \ + print_message("Expected assertion %s occurred\n", \ + global_last_failed_assert); \ + global_expecting_assert = 0; \ + } else { \ + function_call ; \ + global_expecting_assert = 0; \ + print_error("Expected assert in %s\n", #function_call); \ + _fail(__FILE__, __LINE__); \ + } \ + } +#endif + +/** @} */ + +/* Function prototype for setup, test and teardown functions. */ +typedef void (*UnitTestFunction)(void **state); + +/* Function that determines whether a function parameter value is correct. */ +typedef int (*CheckParameterValue)(const LargestIntegralType value, + const LargestIntegralType check_value_data); + +/* Type of the unit test function. */ +typedef enum UnitTestFunctionType { + UNIT_TEST_FUNCTION_TYPE_TEST = 0, + UNIT_TEST_FUNCTION_TYPE_SETUP, + UNIT_TEST_FUNCTION_TYPE_TEARDOWN, + UNIT_TEST_FUNCTION_TYPE_GROUP_SETUP, + UNIT_TEST_FUNCTION_TYPE_GROUP_TEARDOWN, +} UnitTestFunctionType; + +/* + * Stores a unit test function with its name and type. + * NOTE: Every setup function must be paired with a teardown function. It's + * possible to specify NULL function pointers. + */ +typedef struct UnitTest { + const char* name; + UnitTestFunction function; + UnitTestFunctionType function_type; +} UnitTest; + +typedef struct GroupTest { + UnitTestFunction setup; + UnitTestFunction teardown; + const UnitTest *tests; + const size_t number_of_tests; +} GroupTest; + +/* Function prototype for test functions. */ +typedef void (*CMUnitTestFunction)(void **state); + +/* Function prototype for setup and teardown functions. */ +typedef int (*CMFixtureFunction)(void **state); + +struct CMUnitTest { + const char *name; + CMUnitTestFunction test_func; + CMFixtureFunction setup_func; + CMFixtureFunction teardown_func; + void *initial_state; +}; + +/* Location within some source code. */ +typedef struct SourceLocation { + const char* file; + int line; +} SourceLocation; + +/* Event that's called to check a parameter value. */ +typedef struct CheckParameterEvent { + SourceLocation location; + const char *parameter_name; + CheckParameterValue check_value; + LargestIntegralType check_value_data; +} CheckParameterEvent; + +/* Used by expect_assert_failure() and mock_assert(). */ +extern int global_expecting_assert; +extern jmp_buf global_expect_assert_env; +extern const char * global_last_failed_assert; + +/* Retrieves a value for the given function, as set by "will_return". */ +LargestIntegralType _mock(const char * const function, const char* const file, + const int line); + +void _expect_function_call( + const char * const function_name, + const char * const file, + const int line, + const int count); + +void _function_called(const char * const function, const char* const file, + const int line); + +void _expect_check( + const char* const function, const char* const parameter, + const char* const file, const int line, + const CheckParameterValue check_function, + const LargestIntegralType check_data, CheckParameterEvent * const event, + const int count); + +void _expect_in_set( + const char* const function, const char* const parameter, + const char* const file, const int line, const LargestIntegralType values[], + const size_t number_of_values, const int count); +void _expect_not_in_set( + const char* const function, const char* const parameter, + const char* const file, const int line, const LargestIntegralType values[], + const size_t number_of_values, const int count); + +void _expect_in_range( + const char* const function, const char* const parameter, + const char* const file, const int line, + const LargestIntegralType minimum, + const LargestIntegralType maximum, const int count); +void _expect_not_in_range( + const char* const function, const char* const parameter, + const char* const file, const int line, + const LargestIntegralType minimum, + const LargestIntegralType maximum, const int count); + +void _expect_value( + const char* const function, const char* const parameter, + const char* const file, const int line, const LargestIntegralType value, + const int count); +void _expect_not_value( + const char* const function, const char* const parameter, + const char* const file, const int line, const LargestIntegralType value, + const int count); + +void _expect_string( + const char* const function, const char* const parameter, + const char* const file, const int line, const char* string, + const int count); +void _expect_not_string( + const char* const function, const char* const parameter, + const char* const file, const int line, const char* string, + const int count); + +void _expect_memory( + const char* const function, const char* const parameter, + const char* const file, const int line, const void* const memory, + const size_t size, const int count); +void _expect_not_memory( + const char* const function, const char* const parameter, + const char* const file, const int line, const void* const memory, + const size_t size, const int count); + +void _expect_any( + const char* const function, const char* const parameter, + const char* const file, const int line, const int count); + +void _check_expected( + const char * const function_name, const char * const parameter_name, + const char* file, const int line, const LargestIntegralType value); + +void _will_return(const char * const function_name, const char * const file, + const int line, const LargestIntegralType value, + const int count); +void _assert_true(const LargestIntegralType result, + const char* const expression, + const char * const file, const int line); +void _assert_return_code(const LargestIntegralType result, + size_t rlen, + const LargestIntegralType error, + const char * const expression, + const char * const file, + const int line); +void _assert_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 LargestIntegralType a, const LargestIntegralType b, + const char * const file, const int line); +void _assert_int_not_equal( + const LargestIntegralType a, const LargestIntegralType b, + const char * const file, const int line); +void _assert_string_equal(const char * const a, const char * const b, + const char * const file, const int line); +void _assert_string_not_equal(const char * const a, const char * const b, + const char *file, const int line); +void _assert_memory_equal(const void * const a, const void * const b, + const size_t size, const char* const file, + const int line); +void _assert_memory_not_equal(const void * const a, const void * const b, + const size_t size, const char* const file, + const int line); +void _assert_in_range( + const LargestIntegralType value, const LargestIntegralType minimum, + const LargestIntegralType maximum, const char* const file, const int line); +void _assert_not_in_range( + const LargestIntegralType value, const LargestIntegralType minimum, + const LargestIntegralType maximum, const char* const file, const int line); +void _assert_in_set( + const LargestIntegralType value, const LargestIntegralType values[], + const size_t number_of_values, const char* const file, const int line); +void _assert_not_in_set( + const LargestIntegralType value, const LargestIntegralType values[], + const size_t number_of_values, const char* const file, const int line); + +void* _test_malloc(const size_t size, const char* file, const int line); +void* _test_realloc(void *ptr, const size_t size, const char* file, const int line); +void* _test_calloc(const size_t number_of_elements, const size_t size, + const char* file, const int line); +void _test_free(void* const ptr, const char* file, const int line); + +CMOCKA_NORETURN void _fail(const char * const file, const int line); + +CMOCKA_NORETURN void _skip(const char * const file, const int line); + +int _run_test( + const char * const function_name, const UnitTestFunction Function, + void ** const volatile state, const UnitTestFunctionType function_type, + const void* const heap_check_point); +CMOCKA_DEPRECATED int _run_tests(const UnitTest * const tests, + const size_t number_of_tests); +CMOCKA_DEPRECATED int _run_group_tests(const UnitTest * const tests, + const size_t number_of_tests); + +/* Test runner */ +int _cmocka_run_group_tests(const char *group_name, + const struct CMUnitTest * const tests, + const size_t num_tests, + CMFixtureFunction group_setup, + CMFixtureFunction group_teardown); + +/* Standard output and error print methods. */ +void print_message(const char* const format, ...) CMOCKA_PRINTF_ATTRIBUTE(1, 2); +void print_error(const char* const format, ...) CMOCKA_PRINTF_ATTRIBUTE(1, 2); +void vprint_message(const char* const format, va_list args) CMOCKA_PRINTF_ATTRIBUTE(1, 0); +void vprint_error(const char* const format, va_list args) CMOCKA_PRINTF_ATTRIBUTE(1, 0); +void cm_print_error(const char* const format, ...) CMOCKA_PRINTF_ATTRIBUTE(1, 2); + +enum cm_message_output { + CM_OUTPUT_STDOUT, + CM_OUTPUT_SUBUNIT, + CM_OUTPUT_TAP, + CM_OUTPUT_XML, +}; + +/** + * @brief Function to set the output format for a test. + * + * The ouput format for the test can either be set globally using this + * function or overriden with environment variable CMOCKA_MESSAGE_OUTPUT. + * + * The environment variable can be set to either STDOUT, SUBUNIT, TAP or XML. + * + * @param[in] output The output format to use for the test. + * + */ +void cmocka_set_message_output(enum cm_message_output output); + + +/** + * @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 wildards. The first is '*', a wildcard that matches + * zero or more characters, or ‘?’, a wildcard that matches exactly one + * character. + * + * @param[in] pattern The pattern to match, e.g. "test_wurst*" + */ +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 wildards. The first is '*', a wildcard that matches + * zero or more characters, or ‘?’, a wildcard that matches exactly one + * character. + * + * @param[in] pattern The pattern to match, e.g. "test_wurst*" + */ +void cmocka_set_skip_filter(const char *pattern); + +/** @} */ + +#endif /* CMOCKA_H_ */ diff --git a/cmake/cmocka-1.1.7/include/cmocka_pbc.h b/cmake/cmocka-1.1.7/include/cmocka_pbc.h new file mode 100644 index 0000000..a2a1bc1 --- /dev/null +++ b/cmake/cmocka-1.1.7/include/cmocka_pbc.h @@ -0,0 +1,62 @@ +/* + * Copyright 2014 Luis Pabon, Jr. + * + * 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. + */ + +/* + * Programming by Contract is a programming methodology + * which binds the caller and the function called to a + * contract. The contract is represented using Hoare Triple: + * {P} C {Q} + * where {P} is the precondition before executing command C, + * and {Q} is the postcondition. + * + * See also: + * http://en.wikipedia.org/wiki/Design_by_contract + * http://en.wikipedia.org/wiki/Hoare_logic + * http://dlang.org/dbc.html + */ +#ifndef CMOCKA_PBC_H_ +#define CMOCKA_PBC_H_ + +#if defined(UNIT_TESTING) || defined (DEBUG) + +#include + +/* + * Checks caller responsibility against contract + */ +#define REQUIRE(cond) assert(cond) + +/* + * Checks function reponsability against contract. + */ +#define ENSURE(cond) assert(cond) + +/* + * While REQUIRE and ENSURE apply to functions, INVARIANT + * applies to classes/structs. It ensures that intances + * of the class/struct are consistent. In other words, + * that the instance has not been corrupted. + */ +#define INVARIANT(invariant_fnc) do{ (invariant_fnc) } while (0); + +#else +#define REQUIRE(cond) do { } while (0); +#define ENSURE(cond) do { } while (0); +#define INVARIANT(invariant_fnc) do{ } while (0); + +#endif /* defined(UNIT_TESTING) || defined (DEBUG) */ +#endif /* CMOCKA_PBC_H_ */ + diff --git a/cmake/cmocka-1.1.7/include/cmocka_private.h b/cmake/cmocka-1.1.7/include/cmocka_private.h new file mode 100644 index 0000000..4d3ff30 --- /dev/null +++ b/cmake/cmocka-1.1.7/include/cmocka_private.h @@ -0,0 +1,165 @@ +/* + * Copyright 2008 Google Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef CMOCKA_PRIVATE_H_ +#define CMOCKA_PRIVATE_H_ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include + +#ifdef _WIN32 +#include + +# ifdef _MSC_VER +# include /* _snprintf */ +# include /* strtok_s */ + +# undef inline +# define inline __inline + +# ifndef va_copy +# define va_copy(dest, src) (dest = src) +# endif + +# define strcasecmp _stricmp +# define strncasecmp _strnicmp +# define strtok_r strtok_s + +# if defined(HAVE__SNPRINTF_S) +# undef snprintf +# define snprintf(d, n, ...) _snprintf_s((d), (n), _TRUNCATE, __VA_ARGS__) +# else /* HAVE__SNPRINTF_S */ +# if defined(HAVE__SNPRINTF) +# undef snprintf +# define snprintf _snprintf +# else /* HAVE__SNPRINTF */ +# if !defined(HAVE_SNPRINTF) +# error "no snprintf compatible function found" +# endif /* HAVE_SNPRINTF */ +# endif /* HAVE__SNPRINTF */ +# endif /* HAVE__SNPRINTF_S */ + +# if defined(HAVE__VSNPRINTF_S) +# undef vsnprintf +# define vsnprintf(s, n, f, v) _vsnprintf_s((s), (n), _TRUNCATE, (f), (v)) +# else /* HAVE__VSNPRINTF_S */ +# if defined(HAVE__VSNPRINTF) +# undef vsnprintf +# define vsnprintf _vsnprintf +# else +# if !defined(HAVE_VSNPRINTF) +# error "No vsnprintf compatible function found" +# endif /* HAVE_VSNPRINTF */ +# endif /* HAVE__VSNPRINTF */ +# endif /* HAVE__VSNPRINTF_S */ +# endif /* _MSC_VER */ + +/* + * Backwards compatibility with headers shipped with Visual Studio 2005 and + * earlier. + */ +WINBASEAPI BOOL WINAPI IsDebuggerPresent(VOID); + +#ifndef PRIdS +# define PRIdS "Id" +#endif + +#ifndef PRIu64 +# define PRIu64 "I64u" +#endif + +#ifndef PRIuMAX +# define PRIuMAX PRIu64 +#endif + +#ifndef PRIxMAX +#define PRIxMAX "I64x" +#endif + +#ifndef PRIXMAX +#define PRIXMAX "I64X" +#endif + +#else /* _WIN32 */ + +#ifndef __PRI64_PREFIX +# if __WORDSIZE == 64 +# define __PRI64_PREFIX "l" +# else +# define __PRI64_PREFIX "ll" +# endif +#endif + +#ifndef PRIdS +# define PRIdS "zd" +#endif + +#ifndef PRIu64 +# define PRIu64 __PRI64_PREFIX "u" +#endif + +#ifndef PRIuMAX +# define PRIuMAX __PRI64_PREFIX "u" +#endif + +#ifndef PRIxMAX +#define PRIxMAX __PRI64_PREFIX "x" +#endif + +#ifndef PRIXMAX +#define PRIXMAX __PRI64_PREFIX "X" +#endif + +#endif /* _WIN32 */ + +/** Free memory space */ +#define SAFE_FREE(x) do { if ((x) != NULL) {free(x); x=NULL;} } while(0) + +/** Zero a structure */ +#define ZERO_STRUCT(x) memset((char *)&(x), 0, sizeof(x)) + +/** Zero a structure given a pointer to the structure */ +#define ZERO_STRUCTP(x) do { if ((x) != NULL) memset((char *)(x), 0, sizeof(*(x))); } while(0) + +/** Get the size of an array */ +#define ARRAY_SIZE(a) (sizeof(a)/sizeof(a[0])) + +/** Overwrite the complete string with 'X' */ +#define BURN_STRING(x) do { if ((x) != NULL) memset((x), 'X', strlen((x))); } while(0) + +/** + * This is a hack to fix warnings. The idea is to use this everywhere that we + * get the "discarding const" warning by the compiler. That doesn't actually + * fix the real issue, but marks the place and you can search the code for + * discard_const. + * + * Please use this macro only when there is no other way to fix the warning. + * We should use this function in only in a very few places. + * + * Also, please call this via the discard_const_p() macro interface, as that + * makes the return type safe. + */ +#define discard_const(ptr) ((void *)((uintptr_t)(ptr))) + +/** + * Type-safe version of discard_const + */ +#define discard_const_p(type, ptr) ((type *)discard_const(ptr)) + +#endif /* CMOCKA_PRIVATE_H_ */ diff --git a/cmake/cmocka-1.1.7/include/cmockery/cmockery.h b/cmake/cmocka-1.1.7/include/cmockery/cmockery.h new file mode 100644 index 0000000..a252a5f --- /dev/null +++ b/cmake/cmocka-1.1.7/include/cmockery/cmockery.h @@ -0,0 +1 @@ +#include diff --git a/cmake/cmocka-1.1.7/include/cmockery/pbc.h b/cmake/cmocka-1.1.7/include/cmockery/pbc.h new file mode 100644 index 0000000..50bac87 --- /dev/null +++ b/cmake/cmocka-1.1.7/include/cmockery/pbc.h @@ -0,0 +1 @@ +#include diff --git a/cmake/cmocka-1.1.7/meson.build b/cmake/cmocka-1.1.7/meson.build new file mode 100644 index 0000000..8eae406 --- /dev/null +++ b/cmake/cmocka-1.1.7/meson.build @@ -0,0 +1,60 @@ +project('cmocka', 'c', + version : '1.1.5', + license : 'Apache-2.0') + +cc = meson.get_compiler('c') + +conf = configuration_data() + +foreach hdr : ['assert.h', 'inttypes.h', 'io.h', 'malloc.h', 'memory.h', + 'setjmp.h', 'signal.h', 'stdarg.h', 'stddef.h', 'stdint.h', + 'stdio.h', 'stdlib.h', 'string.h', 'strings.h', 'sys/stat.h', + 'sys/types.h', 'time.h', 'unistd.h'] + conf.set('HAVE_@0@'.format(hdr.underscorify().to_upper()), cc.has_header(hdr)) +endforeach + +code = '''#include +int a = sizeof(struct timespec); +''' +conf.set('HAVE_STRUCT_TIMESPEC', cc.compiles(code, name : 'struct timepec')) + +foreach func: ['calloc', 'exit', 'fprintf', 'free', 'longjmp', 'siglongjmp', + 'malloc', 'memcpy', 'memset', 'printf', 'setjmp', 'signal', + 'strsignal', 'strcmp', 'clock_gettime'] + conf.set('HAVE_@0@'.format(func.to_upper()), cc.has_function(func)) +endforeach + +code = '__thread int tls;' +conf.set('HAVE_GCC_THREAD_LOCAL_STORAGE', cc.compiles(code, name : '__thread')) + +code = '''#include +clockid_t t = CLOCK_REALTIME;''' +conf.set('HAVE_CLOCK_REALTIME', cc.compiles(code, name : 'CLOCK_REALTIME')) + +configure_file(output : 'config.h', configuration : conf) + +cmocka_includes = [include_directories('.'), include_directories('include')] +libcmocka = library('cmocka', 'src/cmocka.c', + c_args : ['-DHAVE_CONFIG_H'], + include_directories : cmocka_includes, + install : meson.is_subproject(), + override_options : ['c_std=gnu99'], + dependencies : [cc.find_library('rt', required : false)]) + +if meson.is_subproject() + cmocka_dep = declare_dependency(include_directories : cmocka_includes, + link_with : libcmocka) +else + install_headers('include/cmocka.h') + + pkgconfig = import('pkgconfig') + pkgconfig.generate(libraries : [libcmocka], + version : meson.project_version(), + name : 'cmocka', + filebase : 'cmocka', + description : 'The cmocka unit testing library') +endif + +if get_option('unit_testing') + subdir('tests') +endif diff --git a/cmake/cmocka-1.1.7/meson_options.txt b/cmake/cmocka-1.1.7/meson_options.txt new file mode 100644 index 0000000..0477fb5 --- /dev/null +++ b/cmake/cmocka-1.1.7/meson_options.txt @@ -0,0 +1 @@ +option('unit_testing', type: 'boolean', value: false) diff --git a/cmake/cmocka-1.1.7/src/CMakeLists.txt b/cmake/cmocka-1.1.7/src/CMakeLists.txt new file mode 100644 index 0000000..155c347 --- /dev/null +++ b/cmake/cmocka-1.1.7/src/CMakeLists.txt @@ -0,0 +1,106 @@ +project(cmocka-library C) + +set(CMOCKA_PLATFORM_INCLUDE CACHE PATH "Path to include directory for cmocka_platform.h") +mark_as_advanced(CMOCKA_PLATFORM_INCLUDE) + +set(CMOCKA_LINK_LIBRARIES + ${CMOCKA_REQUIRED_LIBRARIES} + CACHE INTERNAL "cmocka link libraries" +) + +set(cmocka_SRCS + cmocka.c +) + +if (WIN32) + set(cmocka_SRCS + ${cmocka_SRCS} + cmocka.def + ) +endif (WIN32) + +add_library(cmocka ${cmocka_SRCS}) + +target_include_directories(cmocka + PRIVATE + ${CMOCKA_PLATFORM_INCLUDE} + ${cmocka_BINARY_DIR} + PUBLIC + $ + $) + +target_compile_options(cmocka + PRIVATE + ${DEFAULT_C_COMPILE_FLAGS} + -DHAVE_CONFIG_H) +if (CMOCKA_PLATFORM_INCLUDE) + target_compile_options(cmocka + PRIVATE + -DCMOCKA_PLATFORM_INCLUDE) +endif() + +target_link_libraries(cmocka PRIVATE ${CMOCKA_LINK_LIBRARIES}) +set_property(TARGET + cmocka + PROPERTY + DEFINE_SYMBOL + CMOCKA_EXPORTS +) + +set_property(TARGET + cmocka + PROPERTY + VERSION + ${LIBRARY_VERSION} +) +set_property(TARGET + cmocka + PROPERTY + SOVERSION + ${LIBRARY_SOVERSION}) + +set_property(TARGET + cmocka + PROPERTY + LINK_FLAGS + "${DEFAULT_LINK_FLAGS}") + +add_library(cmocka::cmocka ALIAS cmocka) + +install(TARGETS cmocka + EXPORT cmocka-config + ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR} + LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} + RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} + COMPONENT ${PROJECT_NAME}) + +install(EXPORT cmocka-config + NAMESPACE cmocka:: + DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/cmocka) + +if (UNIT_TESTING) + # Internal library + add_library(cmocka-static STATIC ${cmocka_SRCS}) + + target_include_directories(cmocka-static + PRIVATE + ${CMOCKA_PLATFORM_INCLUDE} + ${cmocka_BINARY_DIR} + PUBLIC + ${cmocka-header_SOURCE_DIR}) + + + target_compile_options(cmocka-static + PRIVATE + ${DEFAULT_C_COMPILE_FLAGS} + -DHAVE_CONFIG_H) + if (CMOCKA_PLATFORM_INCLUDE) + target_compile_options(cmocka-static + PRIVATE + -DCMOCKA_PLATFORM_INCLUDE) + endif() + + target_link_libraries(cmocka-static PRIVATE ${CMOCKA_LINK_LIBRARIES}) + + add_library(cmocka::static ALIAS cmocka-static) +endif() diff --git a/cmake/cmocka-1.1.7/src/cmocka.c b/cmake/cmocka-1.1.7/src/cmocka.c new file mode 100644 index 0000000..52897e1 --- /dev/null +++ b/cmake/cmocka-1.1.7/src/cmocka.c @@ -0,0 +1,3632 @@ +/* + * Copyright 2008 Google Inc. + * Copyright 2014-2018 Andreas Schneider + * Copyright 2015 Jakub Hrozek + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#ifdef HAVE_MALLOC_H +#include +#endif + +#ifdef HAVE_INTTYPES_H +#include +#endif + +#ifdef HAVE_SIGNAL_H +#include +#endif + +#ifdef HAVE_STRINGS_H +#include +#endif + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/* + * This allows to add a platform specific header file. Some embedded platforms + * sometimes miss certain types and definitions. + * + * Example: + * + * typedef unsigned long int uintptr_t + * #define _UINTPTR_T 1 + * #define _UINTPTR_T_DEFINED 1 + */ +#ifdef CMOCKA_PLATFORM_INCLUDE +# include "cmocka_platform.h" +#endif /* CMOCKA_PLATFORM_INCLUDE */ + +#include +#include + +/* Size of guard bytes around dynamically allocated blocks. */ +#define MALLOC_GUARD_SIZE 16 +/* Pattern used to initialize guard blocks. */ +#define MALLOC_GUARD_PATTERN 0xEF +/* Pattern used to initialize memory allocated with test_malloc(). */ +#define MALLOC_ALLOC_PATTERN 0xBA +#define MALLOC_FREE_PATTERN 0xCD +/* Alignment of allocated blocks. NOTE: This must be base2. */ +#ifndef MALLOC_ALIGNMENT +#define MALLOC_ALIGNMENT sizeof(size_t) +#endif + +/* Printf formatting for source code locations. */ +#define SOURCE_LOCATION_FORMAT "%s:%u" + +#if defined(HAVE_GCC_THREAD_LOCAL_STORAGE) +# define CMOCKA_THREAD __thread +#elif defined(HAVE_MSVC_THREAD_LOCAL_STORAGE) +# define CMOCKA_THREAD __declspec(thread) +#else +# define CMOCKA_THREAD +#endif + +#ifdef HAVE_CLOCK_REALTIME +#define CMOCKA_CLOCK_GETTIME(clock_id, ts) clock_gettime((clock_id), (ts)) +#else +#define CMOCKA_CLOCK_GETTIME(clock_id, ts) +#endif + +#ifndef MAX +#define MAX(a,b) ((a) < (b) ? (b) : (a)) +#endif + +/** + * POSIX has sigsetjmp/siglongjmp, while Windows only has setjmp/longjmp. + */ +#ifdef HAVE_SIGLONGJMP +# define cm_jmp_buf sigjmp_buf +# define cm_setjmp(env) sigsetjmp(env, 1) +# define cm_longjmp(env, val) siglongjmp(env, val) +#else +# define cm_jmp_buf jmp_buf +# define cm_setjmp(env) setjmp(env) +# define cm_longjmp(env, val) longjmp(env, val) +#endif + + +/* + * Declare and initialize a LargestIntegralType variable name + * with value the conversion of ptr. + */ +#define declare_initialize_value_pointer_pointer(name, ptr) \ + LargestIntegralType name ; \ + name = (LargestIntegralType) (uintptr_t) ptr + +/* Cast a LargestIntegralType to pointer_type. */ +#define cast_largest_integral_type_to_pointer( \ + pointer_type, largest_integral_type) \ + ((pointer_type)(uintptr_t)(largest_integral_type)) + +/* Doubly linked list node. */ +typedef struct ListNode { + const void *value; + int refcount; + struct ListNode *next; + struct ListNode *prev; +} ListNode; + +/* Debug information for malloc(). */ +struct MallocBlockInfoData { + void* block; /* Address of the block returned by malloc(). */ + size_t allocated_size; /* Total size of the allocated block. */ + size_t size; /* Request block size. */ + SourceLocation location; /* Where the block was allocated. */ + ListNode node; /* Node within list of all allocated blocks. */ +}; + +typedef union { + struct MallocBlockInfoData *data; + char *ptr; +} MallocBlockInfo; + +/* State of each test. */ +typedef struct TestState { + const ListNode *check_point; /* Check point of the test if there's a */ + /* setup function. */ + void *state; /* State associated with the test. */ +} TestState; + +/* Determines whether two values are the same. */ +typedef int (*EqualityFunction)(const void *left, const void *right); + +/* Value of a symbol and the place it was declared. */ +typedef struct SymbolValue { + SourceLocation location; + LargestIntegralType value; +} SymbolValue; + +/* + * Contains a list of values for a symbol. + * NOTE: Each structure referenced by symbol_values_list_head must have a + * SourceLocation as its' first member. + */ +typedef struct SymbolMapValue { + const char *symbol_name; + ListNode symbol_values_list_head; +} SymbolMapValue; + +/* Where a particular ordering was located and its symbol name */ +typedef struct FuncOrderingValue { + SourceLocation location; + const char * function; +} FuncOrderingValue; + +/* Used by list_free() to deallocate values referenced by list nodes. */ +typedef void (*CleanupListValue)(const void *value, void *cleanup_value_data); + +/* Structure used to check the range of integer types.a */ +typedef struct CheckIntegerRange { + CheckParameterEvent event; + LargestIntegralType minimum; + LargestIntegralType maximum; +} CheckIntegerRange; + +/* Structure used to check whether an integer value is in a set. */ +typedef struct CheckIntegerSet { + CheckParameterEvent event; + const LargestIntegralType *set; + size_t size_of_set; +} CheckIntegerSet; + +/* Used to check whether a parameter matches the area of memory referenced by + * this structure. */ +typedef struct CheckMemoryData { + CheckParameterEvent event; + const void *memory; + size_t size; +} CheckMemoryData; + +static ListNode* list_initialize(ListNode * const node); +static ListNode* list_add(ListNode * const head, ListNode *new_node); +static ListNode* list_add_value(ListNode * const head, const void *value, + const int count); +static ListNode* list_remove( + ListNode * const node, const CleanupListValue cleanup_value, + void * const cleanup_value_data); +static void list_remove_free( + ListNode * const node, const CleanupListValue cleanup_value, + void * const cleanup_value_data); +static int list_empty(const ListNode * const head); +static int list_find( + ListNode * const head, const void *value, + const EqualityFunction equal_func, ListNode **output); +static int list_first(ListNode * const head, ListNode **output); +static ListNode* list_free( + ListNode * const head, const CleanupListValue cleanup_value, + void * const cleanup_value_data); + +static void add_symbol_value( + ListNode * const symbol_map_head, const char * const symbol_names[], + const size_t number_of_symbol_names, const void* value, const int count); +static int get_symbol_value( + ListNode * const symbol_map_head, const char * const symbol_names[], + const size_t number_of_symbol_names, void **output); +static void free_value(const void *value, void *cleanup_value_data); +static void free_symbol_map_value( + const void *value, void *cleanup_value_data); +static void remove_always_return_values(ListNode * const map_head, + const size_t number_of_symbol_names); + +static size_t check_for_leftover_values_list(const ListNode * head, + const char * const error_message); + +static size_t check_for_leftover_values( + const ListNode * const map_head, const char * const error_message, + const size_t number_of_symbol_names); + +static void remove_always_return_values_from_list(ListNode * const map_head); + +/* + * This must be called at the beginning of a test to initialize some data + * structures. + */ +static void initialize_testing(const char *test_name); + +/* This must be called at the end of a test to free() allocated structures. */ +static void teardown_testing(const char *test_name); + +static enum cm_message_output cm_get_output(void); + +static int cm_error_message_enabled = 1; +static CMOCKA_THREAD char *cm_error_message; + +/* + * Keeps track of the calling context returned by setenv() so that the fail() + * method can jump out of a test. + */ +static CMOCKA_THREAD cm_jmp_buf global_run_test_env; +static CMOCKA_THREAD int global_running_test = 0; + +/* Keeps track of the calling context returned by setenv() so that */ +/* mock_assert() can optionally jump back to expect_assert_failure(). */ +jmp_buf global_expect_assert_env; +int global_expecting_assert = 0; +const char *global_last_failed_assert = NULL; +static int global_skip_test; + +/* Keeps a map of the values that functions will have to return to provide */ +/* mocked interfaces. */ +static CMOCKA_THREAD ListNode global_function_result_map_head; +/* Location of the last mock value returned was declared. */ +static CMOCKA_THREAD SourceLocation global_last_mock_value_location; + +/* Keeps a map of the values that functions expect as parameters to their + * mocked interfaces. */ +static CMOCKA_THREAD ListNode global_function_parameter_map_head; +/* Location of last parameter value checked was declared. */ +static CMOCKA_THREAD SourceLocation global_last_parameter_location; + +/* List (acting as FIFO) of call ordering. */ +static CMOCKA_THREAD ListNode global_call_ordering_head; +/* Location of last call ordering that was declared. */ +static CMOCKA_THREAD SourceLocation global_last_call_ordering_location; + +/* List of all currently allocated blocks. */ +static CMOCKA_THREAD ListNode global_allocated_blocks; + +static enum cm_message_output global_msg_output = CM_OUTPUT_STDOUT; + +static const char *global_test_filter_pattern; + +static const char *global_skip_filter_pattern; + +#ifndef _WIN32 +/* Signals caught by exception_handler(). */ +static const int exception_signals[] = { + SIGFPE, + SIGILL, + SIGSEGV, +#ifdef SIGBUS + SIGBUS, +#endif +#ifdef SIGSYS + SIGSYS, +#endif +}; + +/* Default signal functions that should be restored after a test is complete. */ +typedef void (*SignalFunction)(int signal); +static SignalFunction default_signal_functions[ + ARRAY_SIZE(exception_signals)]; + +#else /* _WIN32 */ + +/* The default exception filter. */ +static LPTOP_LEVEL_EXCEPTION_FILTER previous_exception_filter; + +/* Fatal exceptions. */ +typedef struct ExceptionCodeInfo { + DWORD code; + const char* description; +} ExceptionCodeInfo; + +#define EXCEPTION_CODE_INFO(exception_code) {exception_code, #exception_code} + +static const ExceptionCodeInfo exception_codes[] = { + EXCEPTION_CODE_INFO(EXCEPTION_ACCESS_VIOLATION), + EXCEPTION_CODE_INFO(EXCEPTION_ARRAY_BOUNDS_EXCEEDED), + EXCEPTION_CODE_INFO(EXCEPTION_DATATYPE_MISALIGNMENT), + EXCEPTION_CODE_INFO(EXCEPTION_FLT_DENORMAL_OPERAND), + EXCEPTION_CODE_INFO(EXCEPTION_FLT_DIVIDE_BY_ZERO), + EXCEPTION_CODE_INFO(EXCEPTION_FLT_INEXACT_RESULT), + EXCEPTION_CODE_INFO(EXCEPTION_FLT_INVALID_OPERATION), + EXCEPTION_CODE_INFO(EXCEPTION_FLT_OVERFLOW), + EXCEPTION_CODE_INFO(EXCEPTION_FLT_STACK_CHECK), + EXCEPTION_CODE_INFO(EXCEPTION_FLT_UNDERFLOW), + EXCEPTION_CODE_INFO(EXCEPTION_GUARD_PAGE), + EXCEPTION_CODE_INFO(EXCEPTION_ILLEGAL_INSTRUCTION), + EXCEPTION_CODE_INFO(EXCEPTION_INT_DIVIDE_BY_ZERO), + EXCEPTION_CODE_INFO(EXCEPTION_INT_OVERFLOW), + EXCEPTION_CODE_INFO(EXCEPTION_INVALID_DISPOSITION), + EXCEPTION_CODE_INFO(EXCEPTION_INVALID_HANDLE), + EXCEPTION_CODE_INFO(EXCEPTION_IN_PAGE_ERROR), + EXCEPTION_CODE_INFO(EXCEPTION_NONCONTINUABLE_EXCEPTION), + EXCEPTION_CODE_INFO(EXCEPTION_PRIV_INSTRUCTION), + EXCEPTION_CODE_INFO(EXCEPTION_STACK_OVERFLOW), +}; +#endif /* !_WIN32 */ + +enum CMUnitTestStatus { + CM_TEST_NOT_STARTED, + CM_TEST_PASSED, + CM_TEST_FAILED, + CM_TEST_ERROR, + CM_TEST_SKIPPED, +}; + +struct CMUnitTestState { + const ListNode *check_point; /* Check point of the test if there's a setup function. */ + const struct CMUnitTest *test; /* Point to array element in the tests we get passed */ + void *state; /* State associated with the test */ + const char *error_message; /* The error messages by the test */ + enum CMUnitTestStatus status; /* PASSED, FAILED, ABORT ... */ + double runtime; /* Time calculations */ +}; + +/* Exit the currently executing test. */ +static void exit_test(const int quit_application) +{ + const char *env = getenv("CMOCKA_TEST_ABORT"); + int abort_test = 0; + + if (env != NULL && strlen(env) == 1) { + abort_test = (env[0] == '1'); + } + + if (global_skip_test == 0 && + abort_test == 1) { + print_error("%s", cm_error_message); + abort(); + } else if (global_running_test) { + cm_longjmp(global_run_test_env, 1); + } else if (quit_application) { + exit(-1); + } +} + +void _skip(const char * const file, const int line) +{ + cm_print_error(SOURCE_LOCATION_FORMAT ": Skipped!\n", file, line); + global_skip_test = 1; + exit_test(1); + + /* Unreachable */ + exit(-1); +} + +/* Initialize a SourceLocation structure. */ +static void initialize_source_location(SourceLocation * const location) { + assert_non_null(location); + location->file = NULL; + location->line = 0; +} + + +/* Determine whether a source location is currently set. */ +static int source_location_is_set(const SourceLocation * const location) { + assert_non_null(location); + return location->file && location->line; +} + + +/* Set a source location. */ +static void set_source_location( + SourceLocation * const location, const char * const file, + const int line) { + assert_non_null(location); + location->file = file; + location->line = line; +} + + +static int c_strreplace(char *src, + size_t src_len, + const char *pattern, + const char *repl, + int *str_replaced) +{ + char *p = NULL; + + p = strstr(src, pattern); + if (p == NULL) { + return -1; + } + + do { + size_t of = p - src; + size_t l = strlen(src); + size_t pl = strlen(pattern); + size_t rl = strlen(repl); + + /* overflow check */ + if (src_len <= l + MAX(pl, rl) + 1) { + return -1; + } + + if (rl != pl) { + memmove(src + of + rl, src + of + pl, l - of - pl + 1); + } + + memcpy(src + of, repl, rl); + + if (str_replaced != NULL) { + *str_replaced = 1; + } + p = strstr(src, pattern); + } while (p != NULL); + + return 0; +} + +static int c_strmatch(const char *str, const char *pattern) +{ + int ok; + + if (str == NULL || pattern == NULL) { + return 0; + } + + for (;;) { + /* Check if pattern is done */ + if (*pattern == '\0') { + /* If string is at the end, we're good */ + if (*str == '\0') { + return 1; + } + + return 0; + } + + if (*pattern == '*') { + /* Move on */ + pattern++; + + /* If we are at the end, everything is fine */ + if (*pattern == '\0') { + return 1; + } + + /* Try to match each position */ + for (; *str != '\0'; str++) { + ok = c_strmatch(str, pattern); + if (ok) { + return 1; + } + } + + /* No match */ + return 0; + } + + /* If we are at the end, leave */ + if (*str == '\0') { + return 0; + } + + /* Check if we have a single wildcard or matching char */ + if (*pattern != '?' && *str != *pattern) { + return 0; + } + + /* Move string and pattern */ + str++; + pattern++; + } + + return 0; +} + +/* Create function results and expected parameter lists. */ +void initialize_testing(const char *test_name) { + (void)test_name; + list_initialize(&global_function_result_map_head); + initialize_source_location(&global_last_mock_value_location); + list_initialize(&global_function_parameter_map_head); + initialize_source_location(&global_last_parameter_location); + list_initialize(&global_call_ordering_head); + initialize_source_location(&global_last_parameter_location); +} + + +static void fail_if_leftover_values(const char *test_name) { + int error_occurred = 0; + (void)test_name; + remove_always_return_values(&global_function_result_map_head, 1); + if (check_for_leftover_values( + &global_function_result_map_head, + "%s() has remaining non-returned values.\n", 1)) { + error_occurred = 1; + } + + remove_always_return_values(&global_function_parameter_map_head, 2); + if (check_for_leftover_values( + &global_function_parameter_map_head, + "'%s' parameter still has values that haven't been checked.\n", + 2)) { + error_occurred = 1; + } + + remove_always_return_values_from_list(&global_call_ordering_head); + if (check_for_leftover_values_list(&global_call_ordering_head, + "%s function was expected to be called but was not.\n")) { + error_occurred = 1; + } + if (error_occurred) { + exit_test(1); + } +} + + +static void teardown_testing(const char *test_name) { + (void)test_name; + list_free(&global_function_result_map_head, free_symbol_map_value, + (void*)0); + initialize_source_location(&global_last_mock_value_location); + list_free(&global_function_parameter_map_head, free_symbol_map_value, + (void*)1); + initialize_source_location(&global_last_parameter_location); + list_free(&global_call_ordering_head, free_value, + (void*)0); + initialize_source_location(&global_last_call_ordering_location); +} + +/* Initialize a list node. */ +static ListNode* list_initialize(ListNode * const node) { + node->value = NULL; + node->next = node; + node->prev = node; + node->refcount = 1; + return node; +} + + +/* + * Adds a value at the tail of a given list. + * The node referencing the value is allocated from the heap. + */ +static ListNode* list_add_value(ListNode * const head, const void *value, + const int refcount) { + ListNode * const new_node = (ListNode*)malloc(sizeof(ListNode)); + assert_non_null(head); + assert_non_null(value); + new_node->value = value; + new_node->refcount = refcount; + return list_add(head, new_node); +} + + +/* Add new_node to the end of the list. */ +static ListNode* list_add(ListNode * const head, ListNode *new_node) { + assert_non_null(head); + assert_non_null(new_node); + new_node->next = head; + new_node->prev = head->prev; + head->prev->next = new_node; + head->prev = new_node; + return new_node; +} + + +/* Remove a node from a list. */ +static ListNode* list_remove( + ListNode * const node, const CleanupListValue cleanup_value, + void * const cleanup_value_data) { + assert_non_null(node); + node->prev->next = node->next; + node->next->prev = node->prev; + if (cleanup_value) { + cleanup_value(node->value, cleanup_value_data); + } + return node; +} + + +/* Remove a list node from a list and free the node. */ +static void list_remove_free( + ListNode * const node, const CleanupListValue cleanup_value, + void * const cleanup_value_data) { + assert_non_null(node); + free(list_remove(node, cleanup_value, cleanup_value_data)); +} + + +/* + * Frees memory kept by a linked list The cleanup_value function is called for + * every "value" field of nodes in the list, except for the head. In addition + * to each list value, cleanup_value_data is passed to each call to + * cleanup_value. The head of the list is not deallocated. + */ +static ListNode* list_free( + ListNode * const head, const CleanupListValue cleanup_value, + void * const cleanup_value_data) { + assert_non_null(head); + while (!list_empty(head)) { + list_remove_free(head->next, cleanup_value, cleanup_value_data); + } + return head; +} + + +/* Determine whether a list is empty. */ +static int list_empty(const ListNode * const head) { + assert_non_null(head); + return head->next == head; +} + + +/* + * Find a value in the list using the equal_func to compare each node with the + * value. + */ +static int list_find(ListNode * const head, const void *value, + const EqualityFunction equal_func, ListNode **output) { + ListNode *current; + assert_non_null(head); + for (current = head->next; current != head; current = current->next) { + if (equal_func(current->value, value)) { + *output = current; + return 1; + } + } + return 0; +} + +/* Returns the first node of a list */ +static int list_first(ListNode * const head, ListNode **output) { + ListNode *target_node = NULL; + assert_non_null(head); + if (list_empty(head)) { + return 0; + } + target_node = head->next; + *output = target_node; + return 1; +} + + +/* Deallocate a value referenced by a list. */ +static void free_value(const void *value, void *cleanup_value_data) { + (void)cleanup_value_data; + assert_non_null(value); + free((void*)value); +} + + +/* Releases memory associated to a symbol_map_value. */ +static void free_symbol_map_value(const void *value, + void *cleanup_value_data) { + SymbolMapValue * const map_value = (SymbolMapValue*)value; + const LargestIntegralType children = cast_ptr_to_largest_integral_type(cleanup_value_data); + assert_non_null(value); + if (children == 0) { + list_free(&map_value->symbol_values_list_head, + free_value, + NULL); + } else { + list_free(&map_value->symbol_values_list_head, + free_symbol_map_value, + (void *)((uintptr_t)children - 1)); + } + + free(map_value); +} + + +/* + * Determine whether a symbol name referenced by a symbol_map_value matches the + * specified function name. + */ +static int symbol_names_match(const void *map_value, const void *symbol) { + return !strcmp(((SymbolMapValue*)map_value)->symbol_name, + (const char*)symbol); +} + +/* + * Adds a value to the queue of values associated with the given hierarchy of + * symbols. It's assumed value is allocated from the heap. + */ +static void add_symbol_value(ListNode * const symbol_map_head, + const char * const symbol_names[], + const size_t number_of_symbol_names, + const void* value, const int refcount) { + const char* symbol_name; + ListNode *target_node; + SymbolMapValue *target_map_value; + assert_non_null(symbol_map_head); + assert_non_null(symbol_names); + assert_true(number_of_symbol_names); + symbol_name = symbol_names[0]; + + if (!list_find(symbol_map_head, symbol_name, symbol_names_match, + &target_node)) { + SymbolMapValue * const new_symbol_map_value = + (SymbolMapValue*)malloc(sizeof(*new_symbol_map_value)); + new_symbol_map_value->symbol_name = symbol_name; + list_initialize(&new_symbol_map_value->symbol_values_list_head); + target_node = list_add_value(symbol_map_head, new_symbol_map_value, + 1); + } + + target_map_value = (SymbolMapValue*)target_node->value; + if (number_of_symbol_names == 1) { + list_add_value(&target_map_value->symbol_values_list_head, + value, refcount); + } else { + add_symbol_value(&target_map_value->symbol_values_list_head, + &symbol_names[1], number_of_symbol_names - 1, value, + refcount); + } +} + + +/* + * Gets the next value associated with the given hierarchy of symbols. + * The value is returned as an output parameter with the function returning the + * node's old refcount value if a value is found, 0 otherwise. This means that + * a return value of 1 indicates the node was just removed from the list. + */ +static int get_symbol_value( + ListNode * const head, const char * const symbol_names[], + const size_t number_of_symbol_names, void **output) { + const char* symbol_name = NULL; + ListNode *target_node = NULL; + assert_non_null(head); + assert_non_null(symbol_names); + assert_true(number_of_symbol_names); + assert_non_null(output); + symbol_name = symbol_names[0]; + + if (list_find(head, symbol_name, symbol_names_match, &target_node)) { + SymbolMapValue *map_value = NULL; + ListNode *child_list = NULL; + int return_value = 0; + assert_non_null(target_node); + assert_non_null(target_node->value); + + map_value = (SymbolMapValue*)target_node->value; + child_list = &map_value->symbol_values_list_head; + + if (number_of_symbol_names == 1) { + ListNode *value_node = NULL; + return_value = list_first(child_list, &value_node); + assert_true(return_value); + /* Add a check to silence clang analyzer */ + if (return_value == 0) { + goto out; + } + *output = (void*) value_node->value; + return_value = value_node->refcount; + if (value_node->refcount - 1 == 0) { + list_remove_free(value_node, NULL, NULL); + } else if (value_node->refcount > WILL_RETURN_ONCE) { + --value_node->refcount; + } + } else { + return_value = get_symbol_value( + child_list, &symbol_names[1], number_of_symbol_names - 1, + output); + } + if (list_empty(child_list)) { + list_remove_free(target_node, free_symbol_map_value, (void*)0); + } + return return_value; + } +out: + cm_print_error("No entries for symbol %s.\n", symbol_name); + return 0; +} + +/** + * Taverse a list of nodes and remove first symbol value in list that has a + * refcount < -1 (i.e. should always be returned and has been returned at + * least once). + */ + +static void remove_always_return_values_from_list(ListNode * const map_head) +{ + ListNode * current = NULL; + ListNode * next = NULL; + assert_non_null(map_head); + + for (current = map_head->next, next = current->next; + current != map_head; + current = next, next = current->next) { + if (current->refcount < -1) { + list_remove_free(current, free_value, NULL); + } + } +} + +/* + * Traverse down a tree of symbol values and remove the first symbol value + * in each branch that has a refcount < -1 (i.e should always be returned + * and has been returned at least once). + */ +static void remove_always_return_values(ListNode * const map_head, + const size_t number_of_symbol_names) { + ListNode *current; + assert_non_null(map_head); + assert_true(number_of_symbol_names); + current = map_head->next; + while (current != map_head) { + SymbolMapValue * const value = (SymbolMapValue*)current->value; + ListNode * const next = current->next; + ListNode *child_list; + assert_non_null(value); + child_list = &value->symbol_values_list_head; + + if (!list_empty(child_list)) { + if (number_of_symbol_names == 1) { + ListNode * const child_node = child_list->next; + /* If this item has been returned more than once, free it. */ + if (child_node->refcount < -1) { + list_remove_free(child_node, free_value, NULL); + } + } else { + remove_always_return_values(child_list, + number_of_symbol_names - 1); + } + } + + if (list_empty(child_list)) { + list_remove_free(current, free_value, NULL); + } + current = next; + } +} + +static size_t check_for_leftover_values_list(const ListNode * head, + const char * const error_message) +{ + ListNode *child_node; + size_t leftover_count = 0; + if (!list_empty(head)) + { + for (child_node = head->next; child_node != head; + child_node = child_node->next, ++leftover_count) { + const FuncOrderingValue *const o = + (const FuncOrderingValue*) child_node->value; + cm_print_error("%s: %s", error_message, o->function); + cm_print_error(SOURCE_LOCATION_FORMAT + ": note: remaining item was declared here\n", + o->location.file, o->location.line); + } + } + return leftover_count; +} + +/* + * Checks if there are any leftover values set up by the test that were never + * retrieved through execution, and fail the test if that is the case. + */ +static size_t check_for_leftover_values( + const ListNode * const map_head, const char * const error_message, + const size_t number_of_symbol_names) { + const ListNode *current; + size_t symbols_with_leftover_values = 0; + assert_non_null(map_head); + assert_true(number_of_symbol_names); + + for (current = map_head->next; current != map_head; + current = current->next) { + const SymbolMapValue * const value = + (SymbolMapValue*)current->value; + const ListNode *child_list; + assert_non_null(value); + child_list = &value->symbol_values_list_head; + + if (!list_empty(child_list)) { + if (number_of_symbol_names == 1) { + const ListNode *child_node; + cm_print_error("%s: %s", error_message, value->symbol_name); + + for (child_node = child_list->next; child_node != child_list; + child_node = child_node->next) { + const SourceLocation * const location = + (const SourceLocation*)child_node->value; + cm_print_error(SOURCE_LOCATION_FORMAT + ": note: remaining item was declared here\n", + location->file, location->line); + } + } else { + cm_print_error("%s: ", value->symbol_name); + check_for_leftover_values(child_list, error_message, + number_of_symbol_names - 1); + } + symbols_with_leftover_values ++; + } + } + return symbols_with_leftover_values; +} + + +/* Get the next return value for the specified mock function. */ +LargestIntegralType _mock(const char * const function, const char* const file, + const int line) { + void *result; + const int rc = get_symbol_value(&global_function_result_map_head, + &function, 1, &result); + if (rc) { + SymbolValue * const symbol = (SymbolValue*)result; + const LargestIntegralType value = symbol->value; + global_last_mock_value_location = symbol->location; + if (rc == 1) { + free(symbol); + } + return value; + } else { + cm_print_error(SOURCE_LOCATION_FORMAT ": error: Could not get value " + "to mock function %s\n", file, line, function); + if (source_location_is_set(&global_last_mock_value_location)) { + cm_print_error(SOURCE_LOCATION_FORMAT + ": note: Previously returned mock value was declared here\n", + global_last_mock_value_location.file, + global_last_mock_value_location.line); + } else { + cm_print_error("There were no previously returned mock values for " + "this test.\n"); + } + exit_test(1); + } + return 0; +} + +/* Ensure that function is being called in proper order */ +void _function_called(const char *const function, + const char *const file, + const int line) +{ + ListNode *first_value_node = NULL; + ListNode *value_node = NULL; + int rc; + + rc = list_first(&global_call_ordering_head, &value_node); + first_value_node = value_node; + if (rc) { + FuncOrderingValue *expected_call; + int cmp; + + expected_call = (FuncOrderingValue *)value_node->value; + + cmp = strcmp(expected_call->function, function); + if (value_node->refcount < -1) { + /* + * Search through value nodes until either function is found or + * encounter a non-zero refcount greater than -2 + */ + if (cmp != 0) { + value_node = value_node->next; + expected_call = (FuncOrderingValue *)value_node->value; + + cmp = strcmp(expected_call->function, function); + while (value_node->refcount < -1 && + cmp != 0 && + value_node != first_value_node->prev) { + value_node = value_node->next; + if (value_node == NULL) { + break; + } + expected_call = (FuncOrderingValue *)value_node->value; + if (expected_call == NULL) { + continue; + } + cmp = strcmp(expected_call->function, function); + } + + if (expected_call == NULL || value_node == first_value_node->prev) { + cm_print_error(SOURCE_LOCATION_FORMAT + ": error: No expected mock calls matching " + "called() invocation in %s", + file, line, + function); + exit_test(1); + } + } + } + + if (cmp == 0) { + if (value_node->refcount > -2 && --value_node->refcount == 0) { + list_remove_free(value_node, free_value, NULL); + } + } else { + cm_print_error(SOURCE_LOCATION_FORMAT + ": error: Expected call to %s but received called() " + "in %s\n", + file, line, + expected_call->function, + function); + exit_test(1); + } + } else { + cm_print_error(SOURCE_LOCATION_FORMAT + ": error: No mock calls expected but called() was " + "invoked in %s\n", + file, line, + function); + exit_test(1); + } +} + +/* Add a return value for the specified mock function name. */ +void _will_return(const char * const function_name, const char * const file, + const int line, const LargestIntegralType value, + const int count) { + SymbolValue * const return_value = + (SymbolValue*)malloc(sizeof(*return_value)); + assert_true(count != 0); + return_value->value = value; + set_source_location(&return_value->location, file, line); + add_symbol_value(&global_function_result_map_head, &function_name, 1, + return_value, count); +} + + +/* + * Add a custom parameter checking function. If the event parameter is NULL + * the event structure is allocated internally by this function. If event + * parameter is provided it must be allocated on the heap and doesn't need to + * be deallocated by the caller. + */ +void _expect_check( + const char* const function, const char* const parameter, + const char* const file, const int line, + const CheckParameterValue check_function, + const LargestIntegralType check_data, + CheckParameterEvent * const event, const int count) { + CheckParameterEvent * const check = + event ? event : (CheckParameterEvent*)malloc(sizeof(*check)); + const char* symbols[] = {function, parameter}; + check->parameter_name = parameter; + check->check_value = check_function; + check->check_value_data = check_data; + set_source_location(&check->location, file, line); + add_symbol_value(&global_function_parameter_map_head, symbols, 2, check, + count); +} + +/* + * Add an call expectations that a particular function is called correctly. + * This is used for code under test that makes calls to several functions + * in depended upon components (mocks). + */ + +void _expect_function_call( + const char * const function_name, + const char * const file, + const int line, + const int count) +{ + FuncOrderingValue *ordering; + + assert_non_null(function_name); + assert_non_null(file); + assert_true(count != 0); + + ordering = (FuncOrderingValue *)malloc(sizeof(*ordering)); + + set_source_location(&ordering->location, file, line); + ordering->function = function_name; + + list_add_value(&global_call_ordering_head, ordering, count); +} + +/* Returns 1 if the specified float values are equal, else returns 0. */ +static int float_compare(const float left, + const float right, + const float epsilon) { + float absLeft; + float absRight; + float largest; + float relDiff; + + float diff = left - right; + diff = (diff >= 0.f) ? diff : -diff; + + // Check if the numbers are really close -- needed + // when comparing numbers near zero. + if (diff <= epsilon) { + return 1; + } + + absLeft = (left >= 0.f) ? left : -left; + absRight = (right >= 0.f) ? right : -right; + + largest = (absRight > absLeft) ? absRight : absLeft; + relDiff = largest * FLT_EPSILON; + + if (diff > relDiff) { + return 0; + } + return 1; +} + +/* Returns 1 if the specified float values are equal. If the values are not equal + * an error is displayed and 0 is returned. */ +static int float_values_equal_display_error(const float left, + const float right, + const float epsilon) { + const int equal = float_compare(left, right, epsilon); + if (!equal) { + cm_print_error(FloatPrintfFormat " != " + FloatPrintfFormat "\n", left, right); + } + return equal; +} + +/* Returns 1 if the specified float values are different. If the values are equal + * an error is displayed and 0 is returned. */ +static int float_values_not_equal_display_error(const float left, + const float right, + const float epsilon) { + const int not_equal = (float_compare(left, right, epsilon) == 0); + if (!not_equal) { + cm_print_error(FloatPrintfFormat " == " + FloatPrintfFormat "\n", left, right); + } + return not_equal; +} + +/* Returns 1 if the specified double values are equal, else returns 0. */ +static int double_compare(const double left, + const double right, + const double epsilon) { + double absLeft; + double absRight; + double largest; + double relDiff; + + double diff = left - right; + diff = (diff >= 0.f) ? diff : -diff; + + /* + * Check if the numbers are really close -- needed + * when comparing numbers near zero. + */ + if (diff <= epsilon) { + return 1; + } + + absLeft = (left >= 0.f) ? left : -left; + absRight = (right >= 0.f) ? right : -right; + + largest = (absRight > absLeft) ? absRight : absLeft; + relDiff = largest * FLT_EPSILON; + + if (diff > relDiff) { + return 0; + } + + return 1; +} + +/* + * Returns 1 if the specified double values are equal. If the values are not + * equal an error is displayed and 0 is returned. + */ +static int double_values_equal_display_error(const double left, + const double right, + const double epsilon) { + const int equal = double_compare(left, right, epsilon); + + if (!equal) { + cm_print_error(DoublePrintfFormat " != " + DoublePrintfFormat "\n", left, right); + } + + return equal; +} + +/* + * Returns 1 if the specified double values are different. If the values are + * equal an error is displayed and 0 is returned. + */ +static int double_values_not_equal_display_error(const double left, + const double right, + const double epsilon) { + const int not_equal = (double_compare(left, right, epsilon) == 0); + + if (!not_equal) { + cm_print_error(DoublePrintfFormat " == " + DoublePrintfFormat "\n", left, right); + } + + return not_equal; +} + +/* Returns 1 if the specified values are equal. If the values are not equal + * an error is displayed and 0 is returned. */ +static int values_equal_display_error(const LargestIntegralType left, + const LargestIntegralType right) { + const int equal = left == right; + if (!equal) { + cm_print_error(LargestIntegralTypePrintfFormat " != " + LargestIntegralTypePrintfFormat "\n", left, right); + } + return equal; +} + +/* + * Returns 1 if the specified values are not equal. If the values are equal + * an error is displayed and 0 is returned. */ +static int values_not_equal_display_error(const LargestIntegralType left, + const LargestIntegralType right) { + const int not_equal = left != right; + if (!not_equal) { + cm_print_error(LargestIntegralTypePrintfFormat " == " + LargestIntegralTypePrintfFormat "\n", left, right); + } + return not_equal; +} + + +/* + * Determine whether value is contained within check_integer_set. + * If invert is 0 and the value is in the set 1 is returned, otherwise 0 is + * returned and an error is displayed. If invert is 1 and the value is not + * in the set 1 is returned, otherwise 0 is returned and an error is + * displayed. + */ +static int value_in_set_display_error( + const LargestIntegralType value, + const CheckIntegerSet * const check_integer_set, const int invert) { + int succeeded = invert; + assert_non_null(check_integer_set); + { + const LargestIntegralType * const set = check_integer_set->set; + const size_t size_of_set = check_integer_set->size_of_set; + size_t i; + for (i = 0; i < size_of_set; i++) { + if (set[i] == value) { + /* If invert = 0 and item is found, succeeded = 1. */ + /* If invert = 1 and item is found, succeeded = 0. */ + succeeded = !succeeded; + break; + } + } + if (succeeded) { + return 1; + } + cm_print_error(LargestIntegralTypePrintfFormatDecimal + " is %sin the set (", + value, invert ? "" : "not "); + for (i = 0; i < size_of_set; i++) { + cm_print_error(LargestIntegralTypePrintfFormat ", ", set[i]); + } + cm_print_error(")\n"); + } + return 0; +} + + +/* + * Determine whether a value is within the specified range. If the value is + * within the specified range 1 is returned. If the value isn't within the + * specified range an error is displayed and 0 is returned. + */ +static int integer_in_range_display_error( + const LargestIntegralType value, const LargestIntegralType range_min, + const LargestIntegralType range_max) { + if (value >= range_min && value <= range_max) { + return 1; + } + cm_print_error(LargestIntegralTypePrintfFormatDecimal + " is not within the range " + LargestIntegralTypePrintfFormatDecimal "-" + LargestIntegralTypePrintfFormatDecimal "\n", + value, range_min, range_max); + return 0; +} + + +/* + * Determine whether a value is within the specified range. If the value + * is not within the range 1 is returned. If the value is within the + * specified range an error is displayed and zero is returned. + */ +static int integer_not_in_range_display_error( + const LargestIntegralType value, const LargestIntegralType range_min, + const LargestIntegralType range_max) { + if (value < range_min || value > range_max) { + return 1; + } + cm_print_error(LargestIntegralTypePrintfFormatDecimal + " is within the range " + LargestIntegralTypePrintfFormatDecimal "-" + LargestIntegralTypePrintfFormatDecimal "\n", + value, range_min, range_max); + return 0; +} + + +/* + * Determine whether the specified strings are equal. If the strings are equal + * 1 is returned. If they're not equal an error is displayed and 0 is + * returned. + */ +static int string_equal_display_error( + const char * const left, const char * const right) { + if (strcmp(left, right) == 0) { + return 1; + } + cm_print_error("\"%s\" != \"%s\"\n", left, right); + return 0; +} + + +/* + * Determine whether the specified strings are equal. If the strings are not + * equal 1 is returned. If they're not equal an error is displayed and 0 is + * returned + */ +static int string_not_equal_display_error( + const char * const left, const char * const right) { + if (strcmp(left, right) != 0) { + return 1; + } + cm_print_error("\"%s\" == \"%s\"\n", left, right); + return 0; +} + + +/* + * Determine whether the specified areas of memory are equal. If they're equal + * 1 is returned otherwise an error is displayed and 0 is returned. + */ +static int memory_equal_display_error(const char* const a, const char* const b, + const size_t size) { + size_t differences = 0; + size_t i; + for (i = 0; i < size; i++) { + const char l = a[i]; + const char r = b[i]; + if (l != r) { + if (differences < 16) { + cm_print_error("difference at offset %" PRIdS " 0x%02x 0x%02x\n", + i, l, r); + } + differences ++; + } + } + if (differences > 0) { + if (differences >= 16) { + cm_print_error("...\n"); + } + cm_print_error("%"PRIdS " bytes of %p and %p differ\n", + differences, (void *)a, (void *)b); + return 0; + } + return 1; +} + + +/* + * Determine whether the specified areas of memory are not equal. If they're + * not equal 1 is returned otherwise an error is displayed and 0 is + * returned. + */ +static int memory_not_equal_display_error( + const char* const a, const char* const b, const size_t size) { + size_t same = 0; + size_t i; + for (i = 0; i < size; i++) { + const char l = a[i]; + const char r = b[i]; + if (l == r) { + same ++; + } + } + if (same == size) { + cm_print_error("%"PRIdS "bytes of %p and %p the same\n", + same, (void *)a, (void *)b); + return 0; + } + return 1; +} + + +/* CheckParameterValue callback to check whether a value is within a set. */ +static int check_in_set(const LargestIntegralType value, + const LargestIntegralType check_value_data) { + return value_in_set_display_error(value, + cast_largest_integral_type_to_pointer(CheckIntegerSet*, + check_value_data), 0); +} + + +/* CheckParameterValue callback to check whether a value isn't within a set. */ +static int check_not_in_set(const LargestIntegralType value, + const LargestIntegralType check_value_data) { + return value_in_set_display_error(value, + cast_largest_integral_type_to_pointer(CheckIntegerSet*, + check_value_data), 1); +} + + +/* Create the callback data for check_in_set() or check_not_in_set() and + * register a check event. */ +static void expect_set( + const char* const function, const char* const parameter, + const char* const file, const int line, + const LargestIntegralType values[], const size_t number_of_values, + const CheckParameterValue check_function, const int count) { + CheckIntegerSet * const check_integer_set = + (CheckIntegerSet*)malloc(sizeof(*check_integer_set) + + (sizeof(values[0]) * number_of_values)); + LargestIntegralType * const set = (LargestIntegralType*)( + check_integer_set + 1); + declare_initialize_value_pointer_pointer(check_data, check_integer_set); + assert_non_null(values); + assert_true(number_of_values); + memcpy(set, values, number_of_values * sizeof(values[0])); + check_integer_set->set = set; + check_integer_set->size_of_set = number_of_values; + _expect_check( + function, parameter, file, line, check_function, + check_data, &check_integer_set->event, count); +} + + +/* Add an event to check whether a value is in a set. */ +void _expect_in_set( + const char* const function, const char* const parameter, + const char* const file, const int line, + const LargestIntegralType values[], const size_t number_of_values, + const int count) { + expect_set(function, parameter, file, line, values, number_of_values, + check_in_set, count); +} + + +/* Add an event to check whether a value isn't in a set. */ +void _expect_not_in_set( + const char* const function, const char* const parameter, + const char* const file, const int line, + const LargestIntegralType values[], const size_t number_of_values, + const int count) { + expect_set(function, parameter, file, line, values, number_of_values, + check_not_in_set, count); +} + + +/* CheckParameterValue callback to check whether a value is within a range. */ +static int check_in_range(const LargestIntegralType value, + const LargestIntegralType check_value_data) { + CheckIntegerRange * const check_integer_range = + cast_largest_integral_type_to_pointer(CheckIntegerRange*, + check_value_data); + assert_non_null(check_integer_range); + return integer_in_range_display_error(value, check_integer_range->minimum, + check_integer_range->maximum); +} + + +/* CheckParameterValue callback to check whether a value is not within a range. */ +static int check_not_in_range(const LargestIntegralType value, + const LargestIntegralType check_value_data) { + CheckIntegerRange * const check_integer_range = + cast_largest_integral_type_to_pointer(CheckIntegerRange*, + check_value_data); + assert_non_null(check_integer_range); + return integer_not_in_range_display_error( + value, check_integer_range->minimum, check_integer_range->maximum); +} + + +/* Create the callback data for check_in_range() or check_not_in_range() and + * register a check event. */ +static void expect_range( + const char* const function, const char* const parameter, + const char* const file, const int line, + const LargestIntegralType minimum, const LargestIntegralType maximum, + const CheckParameterValue check_function, const int count) { + CheckIntegerRange * const check_integer_range = + (CheckIntegerRange*)malloc(sizeof(*check_integer_range)); + declare_initialize_value_pointer_pointer(check_data, check_integer_range); + check_integer_range->minimum = minimum; + check_integer_range->maximum = maximum; + _expect_check(function, parameter, file, line, check_function, + check_data, &check_integer_range->event, count); +} + + +/* Add an event to determine whether a parameter is within a range. */ +void _expect_in_range( + const char* const function, const char* const parameter, + const char* const file, const int line, + const LargestIntegralType minimum, const LargestIntegralType maximum, + const int count) { + expect_range(function, parameter, file, line, minimum, maximum, + check_in_range, count); +} + + +/* Add an event to determine whether a parameter is not within a range. */ +void _expect_not_in_range( + const char* const function, const char* const parameter, + const char* const file, const int line, + const LargestIntegralType minimum, const LargestIntegralType maximum, + const int count) { + expect_range(function, parameter, file, line, minimum, maximum, + check_not_in_range, count); +} + + +/* CheckParameterValue callback to check whether a value is equal to an + * expected value. */ +static int check_value(const LargestIntegralType value, + const LargestIntegralType check_value_data) { + return values_equal_display_error(value, check_value_data); +} + + +/* Add an event to check a parameter equals an expected value. */ +void _expect_value( + const char* const function, const char* const parameter, + const char* const file, const int line, + const LargestIntegralType value, const int count) { + _expect_check(function, parameter, file, line, check_value, value, NULL, + count); +} + + +/* CheckParameterValue callback to check whether a value is not equal to an + * expected value. */ +static int check_not_value(const LargestIntegralType value, + const LargestIntegralType check_value_data) { + return values_not_equal_display_error(value, check_value_data); +} + + +/* Add an event to check a parameter is not equal to an expected value. */ +void _expect_not_value( + const char* const function, const char* const parameter, + const char* const file, const int line, + const LargestIntegralType value, const int count) { + _expect_check(function, parameter, file, line, check_not_value, value, + NULL, count); +} + + +/* CheckParameterValue callback to check whether a parameter equals a string. */ +static int check_string(const LargestIntegralType value, + const LargestIntegralType check_value_data) { + return string_equal_display_error( + cast_largest_integral_type_to_pointer(char*, value), + cast_largest_integral_type_to_pointer(char*, check_value_data)); +} + + +/* Add an event to check whether a parameter is equal to a string. */ +void _expect_string( + const char* const function, const char* const parameter, + const char* const file, const int line, const char* string, + const int count) { + declare_initialize_value_pointer_pointer(string_pointer, + discard_const(string)); + _expect_check(function, parameter, file, line, check_string, + string_pointer, NULL, count); +} + + +/* CheckParameterValue callback to check whether a parameter is not equals to + * a string. */ +static int check_not_string(const LargestIntegralType value, + const LargestIntegralType check_value_data) { + return string_not_equal_display_error( + cast_largest_integral_type_to_pointer(char*, value), + cast_largest_integral_type_to_pointer(char*, check_value_data)); +} + + +/* Add an event to check whether a parameter is not equal to a string. */ +void _expect_not_string( + const char* const function, const char* const parameter, + const char* const file, const int line, const char* string, + const int count) { + declare_initialize_value_pointer_pointer(string_pointer, + discard_const(string)); + _expect_check(function, parameter, file, line, check_not_string, + string_pointer, NULL, count); +} + +/* CheckParameterValue callback to check whether a parameter equals an area of + * memory. */ +static int check_memory(const LargestIntegralType value, + const LargestIntegralType check_value_data) { + CheckMemoryData * const check = cast_largest_integral_type_to_pointer( + CheckMemoryData*, check_value_data); + assert_non_null(check); + return memory_equal_display_error( + cast_largest_integral_type_to_pointer(const char*, value), + (const char*)check->memory, check->size); +} + + +/* Create the callback data for check_memory() or check_not_memory() and + * register a check event. */ +static void expect_memory_setup( + const char* const function, const char* const parameter, + const char* const file, const int line, + const void * const memory, const size_t size, + const CheckParameterValue check_function, const int count) { + CheckMemoryData * const check_data = + (CheckMemoryData*)malloc(sizeof(*check_data) + size); + void * const mem = (void*)(check_data + 1); + declare_initialize_value_pointer_pointer(check_data_pointer, check_data); + assert_non_null(memory); + assert_true(size); + memcpy(mem, memory, size); + check_data->memory = mem; + check_data->size = size; + _expect_check(function, parameter, file, line, check_function, + check_data_pointer, &check_data->event, count); +} + + +/* Add an event to check whether a parameter matches an area of memory. */ +void _expect_memory( + const char* const function, const char* const parameter, + const char* const file, const int line, const void* const memory, + const size_t size, const int count) { + expect_memory_setup(function, parameter, file, line, memory, size, + check_memory, count); +} + + +/* CheckParameterValue callback to check whether a parameter is not equal to + * an area of memory. */ +static int check_not_memory(const LargestIntegralType value, + const LargestIntegralType check_value_data) { + CheckMemoryData * const check = cast_largest_integral_type_to_pointer( + CheckMemoryData*, check_value_data); + assert_non_null(check); + return memory_not_equal_display_error( + cast_largest_integral_type_to_pointer(const char*, value), + (const char*)check->memory, + check->size); +} + + +/* Add an event to check whether a parameter doesn't match an area of memory. */ +void _expect_not_memory( + const char* const function, const char* const parameter, + const char* const file, const int line, const void* const memory, + const size_t size, const int count) { + expect_memory_setup(function, parameter, file, line, memory, size, + check_not_memory, count); +} + + +/* CheckParameterValue callback that always returns 1. */ +static int check_any(const LargestIntegralType value, + const LargestIntegralType check_value_data) { + (void)value; + (void)check_value_data; + return 1; +} + + +/* Add an event to allow any value for a parameter. */ +void _expect_any( + const char* const function, const char* const parameter, + const char* const file, const int line, const int count) { + _expect_check(function, parameter, file, line, check_any, 0, NULL, + count); +} + + +void _check_expected( + const char * const function_name, const char * const parameter_name, + const char* file, const int line, const LargestIntegralType value) { + void *result = NULL; + const char* symbols[] = {function_name, parameter_name}; + const int rc = get_symbol_value(&global_function_parameter_map_head, + symbols, 2, &result); + if (rc) { + CheckParameterEvent * const check = (CheckParameterEvent*)result; + int check_succeeded; + global_last_parameter_location = check->location; + check_succeeded = check->check_value(value, check->check_value_data); + if (rc == 1) { + free(check); + } + if (!check_succeeded) { + cm_print_error(SOURCE_LOCATION_FORMAT + ": error: Check of parameter %s, function %s failed\n" + SOURCE_LOCATION_FORMAT + ": note: Expected parameter declared here\n", + file, line, + parameter_name, function_name, + global_last_parameter_location.file, + global_last_parameter_location.line); + _fail(file, line); + } + } else { + cm_print_error(SOURCE_LOCATION_FORMAT ": error: Could not get value " + "to check parameter %s of function %s\n", file, line, + parameter_name, function_name); + if (source_location_is_set(&global_last_parameter_location)) { + cm_print_error(SOURCE_LOCATION_FORMAT + ": note: Previously declared parameter value was declared here\n", + global_last_parameter_location.file, + global_last_parameter_location.line); + } else { + cm_print_error("There were no previously declared parameter values " + "for this test.\n"); + } + exit_test(1); + } +} + + +/* Replacement for assert. */ +void mock_assert(const int result, const char* const expression, + const char* const file, const int line) { + if (!result) { + if (global_expecting_assert) { + global_last_failed_assert = expression; + longjmp(global_expect_assert_env, result); + } else { + cm_print_error("ASSERT: %s\n", expression); + _fail(file, line); + } + } +} + + +void _assert_true(const LargestIntegralType result, + const char * const expression, + const char * const file, const int line) { + if (!result) { + cm_print_error("%s\n", expression); + _fail(file, line); + } +} + +void _assert_return_code(const LargestIntegralType result, + size_t rlen, + const LargestIntegralType error, + const char * const expression, + const char * const file, + const int line) +{ + LargestIntegralType valmax; + + + switch (rlen) { + case 1: + valmax = 255; + break; + case 2: + valmax = 32767; + break; + case 4: + valmax = 2147483647; + break; + case 8: + default: + if (rlen > sizeof(valmax)) { + valmax = 2147483647; + } else { + valmax = 9223372036854775807L; + } + break; + } + + if (result > valmax - 1) { + if (error > 0) { + cm_print_error("%s < 0, errno(" + LargestIntegralTypePrintfFormatDecimal "): %s\n", + expression, error, strerror((int)error)); + } else { + cm_print_error("%s < 0\n", expression); + } + _fail(file, line); + } +} + +void _assert_float_equal(const float a, + const float b, + const float epsilon, + const char * const file, + const int line) { + if (!float_values_equal_display_error(a, b, epsilon)) { + _fail(file, line); + } +} + +void _assert_float_not_equal(const float a, + const float b, + const float epsilon, + const char * const file, + const int line) { + if (!float_values_not_equal_display_error(a, b, epsilon)) { + _fail(file, line); + } +} + +void _assert_double_equal(const double a, + const double b, + const double epsilon, + const char * const file, + const int line) { + if (!double_values_equal_display_error(a, b, epsilon)) { + _fail(file, line); + } +} + +void _assert_double_not_equal(const double a, + const double b, + const double epsilon, + const char * const file, + const int line) { + if (!double_values_not_equal_display_error(a, b, epsilon)) { + _fail(file, line); + } +} + +void _assert_int_equal( + const LargestIntegralType a, const LargestIntegralType b, + const char * const file, const int line) { + if (!values_equal_display_error(a, b)) { + _fail(file, line); + } +} + + +void _assert_int_not_equal( + const LargestIntegralType a, const LargestIntegralType b, + const char * const file, const int line) { + if (!values_not_equal_display_error(a, b)) { + _fail(file, line); + } +} + + +void _assert_string_equal(const char * const a, const char * const b, + const char * const file, const int line) { + if (!string_equal_display_error(a, b)) { + _fail(file, line); + } +} + + +void _assert_string_not_equal(const char * const a, const char * const b, + const char *file, const int line) { + if (!string_not_equal_display_error(a, b)) { + _fail(file, line); + } +} + + +void _assert_memory_equal(const void * const a, const void * const b, + const size_t size, const char* const file, + const int line) { + if (!memory_equal_display_error((const char*)a, (const char*)b, size)) { + _fail(file, line); + } +} + + +void _assert_memory_not_equal(const void * const a, const void * const b, + const size_t size, const char* const file, + const int line) { + if (!memory_not_equal_display_error((const char*)a, (const char*)b, + size)) { + _fail(file, line); + } +} + + +void _assert_in_range( + const LargestIntegralType value, const LargestIntegralType minimum, + const LargestIntegralType maximum, const char* const file, + const int line) { + if (!integer_in_range_display_error(value, minimum, maximum)) { + _fail(file, line); + } +} + +void _assert_not_in_range( + const LargestIntegralType value, const LargestIntegralType minimum, + const LargestIntegralType maximum, const char* const file, + const int line) { + if (!integer_not_in_range_display_error(value, minimum, maximum)) { + _fail(file, line); + } +} + +void _assert_in_set(const LargestIntegralType value, + const LargestIntegralType values[], + const size_t number_of_values, const char* const file, + const int line) { + CheckIntegerSet check_integer_set; + check_integer_set.set = values; + check_integer_set.size_of_set = number_of_values; + if (!value_in_set_display_error(value, &check_integer_set, 0)) { + _fail(file, line); + } +} + +void _assert_not_in_set(const LargestIntegralType value, + const LargestIntegralType values[], + const size_t number_of_values, const char* const file, + const int line) { + CheckIntegerSet check_integer_set; + check_integer_set.set = values; + check_integer_set.size_of_set = number_of_values; + if (!value_in_set_display_error(value, &check_integer_set, 1)) { + _fail(file, line); + } +} + + +/* Get the list of allocated blocks. */ +static ListNode* get_allocated_blocks_list(void) { + /* If it initialized, initialize the list of allocated blocks. */ + if (!global_allocated_blocks.value) { + list_initialize(&global_allocated_blocks); + global_allocated_blocks.value = (void*)1; + } + return &global_allocated_blocks; +} + +static void *libc_calloc(size_t nmemb, size_t size) +{ +#undef calloc + return calloc(nmemb, size); +#define calloc test_calloc +} + +static void libc_free(void *ptr) +{ +#undef free + free(ptr); +#define free test_free +} + +static void *libc_realloc(void *ptr, size_t size) +{ +#undef realloc + return realloc(ptr, size); +#define realloc test_realloc +} + +static void vcm_print_error(const char* const format, + va_list args) CMOCKA_PRINTF_ATTRIBUTE(1, 0); + +/* It's important to use the libc malloc and free here otherwise + * the automatic free of leaked blocks can reap the error messages + */ +static void vcm_print_error(const char* const format, va_list args) +{ + char buffer[1024]; + size_t msg_len = 0; + va_list ap; + int len; + va_copy(ap, args); + + len = vsnprintf(buffer, sizeof(buffer), format, args); + if (len < 0) { + /* TODO */ + goto end; + } + + if (cm_error_message == NULL) { + /* CREATE MESSAGE */ + + cm_error_message = libc_calloc(1, len + 1); + if (cm_error_message == NULL) { + /* TODO */ + goto end; + } + } else { + /* APPEND MESSAGE */ + char *tmp; + + msg_len = strlen(cm_error_message); + tmp = libc_realloc(cm_error_message, msg_len + len + 1); + if (tmp == NULL) { + goto end; + } + cm_error_message = tmp; + } + + if (((size_t)len) < sizeof(buffer)) { + /* Use len + 1 to also copy '\0' */ + memcpy(cm_error_message + msg_len, buffer, len + 1); + } else { + vsnprintf(cm_error_message + msg_len, len, format, ap); + } +end: + va_end(ap); + +} + +static void vcm_free_error(char *err_msg) +{ + libc_free(err_msg); +} + +/* Use the real malloc in this function. */ +#undef malloc +void* _test_malloc(const size_t size, const char* file, const int line) { + char *ptr = NULL; + MallocBlockInfo block_info; + ListNode * const block_list = get_allocated_blocks_list(); + size_t allocate_size; + char *block = NULL; + + allocate_size = size + (MALLOC_GUARD_SIZE * 2) + + sizeof(struct MallocBlockInfoData) + MALLOC_ALIGNMENT; + assert_true(allocate_size > size); + + block = (char *)malloc(allocate_size); + assert_non_null(block); + + /* Calculate the returned address. */ + ptr = (char*)(((size_t)block + MALLOC_GUARD_SIZE + + sizeof(struct MallocBlockInfoData) + + MALLOC_ALIGNMENT) & ~(MALLOC_ALIGNMENT - 1)); + + /* Initialize the guard blocks. */ + memset(ptr - MALLOC_GUARD_SIZE, MALLOC_GUARD_PATTERN, MALLOC_GUARD_SIZE); + memset(ptr + size, MALLOC_GUARD_PATTERN, MALLOC_GUARD_SIZE); + memset(ptr, MALLOC_ALLOC_PATTERN, size); + + block_info.ptr = ptr - (MALLOC_GUARD_SIZE + + sizeof(struct MallocBlockInfoData)); + set_source_location(&block_info.data->location, file, line); + block_info.data->allocated_size = allocate_size; + block_info.data->size = size; + block_info.data->block = block; + block_info.data->node.value = block_info.ptr; + list_add(block_list, &block_info.data->node); + return ptr; +} +#define malloc test_malloc + + +void* _test_calloc(const size_t number_of_elements, const size_t size, + const char* file, const int line) { + void* const ptr = _test_malloc(number_of_elements * size, file, line); + if (ptr) { + memset(ptr, 0, number_of_elements * size); + } + return ptr; +} +#define calloc test_calloc + + +/* Use the real free in this function. */ +#undef free +void _test_free(void* const ptr, const char* file, const int line) { + unsigned int i; + char *block = discard_const_p(char, ptr); + MallocBlockInfo block_info; + + if (ptr == NULL) { + return; + } + + _assert_true(cast_ptr_to_largest_integral_type(ptr), "ptr", file, line); + block_info.ptr = block - (MALLOC_GUARD_SIZE + + sizeof(struct MallocBlockInfoData)); + /* Check the guard blocks. */ + { + char *guards[2] = {block - MALLOC_GUARD_SIZE, + block + block_info.data->size}; + for (i = 0; i < ARRAY_SIZE(guards); i++) { + unsigned int j; + char * const guard = guards[i]; + for (j = 0; j < MALLOC_GUARD_SIZE; j++) { + const char diff = guard[j] - MALLOC_GUARD_PATTERN; + if (diff) { + cm_print_error(SOURCE_LOCATION_FORMAT + ": error: Guard block of %p size=%lu is corrupt\n" + SOURCE_LOCATION_FORMAT ": note: allocated here at %p\n", + file, + line, + ptr, + (unsigned long)block_info.data->size, + block_info.data->location.file, + block_info.data->location.line, + (void *)&guard[j]); + _fail(file, line); + } + } + } + } + list_remove(&block_info.data->node, NULL, NULL); + + block = discard_const_p(char, block_info.data->block); + memset(block, MALLOC_FREE_PATTERN, block_info.data->allocated_size); + free(block); +} +#define free test_free + +#undef realloc +void *_test_realloc(void *ptr, + const size_t size, + const char *file, + const int line) +{ + MallocBlockInfo block_info; + char *block = ptr; + size_t block_size = size; + void *new_block; + + if (ptr == NULL) { + return _test_malloc(size, file, line); + } + + if (size == 0) { + _test_free(ptr, file, line); + return NULL; + } + + block_info.ptr = block - (MALLOC_GUARD_SIZE + + sizeof(struct MallocBlockInfoData)); + + new_block = _test_malloc(size, file, line); + if (new_block == NULL) { + return NULL; + } + + if (block_info.data->size < size) { + block_size = block_info.data->size; + } + + memcpy(new_block, ptr, block_size); + + /* Free previous memory */ + _test_free(ptr, file, line); + + return new_block; +} +#define realloc test_realloc + +/* Crudely checkpoint the current heap state. */ +static const ListNode* check_point_allocated_blocks(void) { + return get_allocated_blocks_list()->prev; +} + + +/* Display the blocks allocated after the specified check point. This + * function returns the number of blocks displayed. */ +static size_t display_allocated_blocks(const ListNode * const check_point) { + const ListNode * const head = get_allocated_blocks_list(); + const ListNode *node; + size_t allocated_blocks = 0; + assert_non_null(check_point); + assert_non_null(check_point->next); + + for (node = check_point->next; node != head; node = node->next) { + const MallocBlockInfo block_info = { + .ptr = discard_const(node->value), + }; + assert_non_null(block_info.ptr); + + if (allocated_blocks == 0) { + cm_print_error("Blocks allocated...\n"); + } + cm_print_error(SOURCE_LOCATION_FORMAT ": note: block %p allocated here\n", + block_info.data->location.file, + block_info.data->location.line, + block_info.data->block); + allocated_blocks++; + } + return allocated_blocks; +} + + +/* Free all blocks allocated after the specified check point. */ +static void free_allocated_blocks(const ListNode * const check_point) { + const ListNode * const head = get_allocated_blocks_list(); + const ListNode *node; + assert_non_null(check_point); + + node = check_point->next; + assert_non_null(node); + + while (node != head) { + const MallocBlockInfo block_info = { + .ptr = discard_const(node->value), + }; + node = node->next; + free(discard_const_p(char, block_info.data) + + sizeof(struct MallocBlockInfoData) + + MALLOC_GUARD_SIZE); + } +} + + +/* Fail if any any blocks are allocated after the specified check point. */ +static void fail_if_blocks_allocated(const ListNode * const check_point, + const char * const test_name) { + const size_t allocated_blocks = display_allocated_blocks(check_point); + if (allocated_blocks > 0) { + free_allocated_blocks(check_point); + cm_print_error("ERROR: %s leaked %zu block(s)\n", test_name, + allocated_blocks); + exit_test(1); + } +} + + +void _fail(const char * const file, const int line) { + enum cm_message_output output = cm_get_output(); + + switch(output) { + case CM_OUTPUT_STDOUT: + cm_print_error("[ LINE ] --- " SOURCE_LOCATION_FORMAT ": error: Failure!", file, line); + break; + default: + cm_print_error(SOURCE_LOCATION_FORMAT ": error: Failure!", file, line); + break; + } + exit_test(1); + + /* Unreachable */ + exit(-1); +} + + +#ifndef _WIN32 +CMOCKA_NORETURN static void exception_handler(int sig) { + const char *sig_strerror = ""; + +#ifdef HAVE_STRSIGNAL + sig_strerror = strsignal(sig); +#endif + + cm_print_error("Test failed with exception: %s(%d)", + sig_strerror, sig); + exit_test(1); + + /* Unreachable */ + exit(-1); +} + +#else /* _WIN32 */ + +static LONG WINAPI exception_filter(EXCEPTION_POINTERS *exception_pointers) { + EXCEPTION_RECORD * const exception_record = + exception_pointers->ExceptionRecord; + const DWORD code = exception_record->ExceptionCode; + unsigned int i; + for (i = 0; i < ARRAY_SIZE(exception_codes); i++) { + const ExceptionCodeInfo * const code_info = &exception_codes[i]; + if (code == code_info->code) { + static int shown_debug_message = 0; + fflush(stdout); + cm_print_error("%s occurred at %p.\n", code_info->description, + exception_record->ExceptionAddress); + if (!shown_debug_message) { + cm_print_error( + "\n" + "To debug in Visual Studio...\n" + "1. Select menu item File->Open Project\n" + "2. Change 'Files of type' to 'Executable Files'\n" + "3. Open this executable.\n" + "4. Select menu item Debug->Start\n" + "\n" + "Alternatively, set the environment variable \n" + "UNIT_TESTING_DEBUG to 1 and rebuild this executable, \n" + "then click 'Debug' in the popup dialog box.\n" + "\n"); + shown_debug_message = 1; + } + exit_test(0); + return EXCEPTION_EXECUTE_HANDLER; + } + } + return EXCEPTION_CONTINUE_SEARCH; +} +#endif /* !_WIN32 */ + +void cm_print_error(const char * const format, ...) +{ + va_list args; + va_start(args, format); + if (cm_error_message_enabled) { + vcm_print_error(format, args); + } else { + vprint_error(format, args); + } + va_end(args); +} + +/* Standard output and error print methods. */ +void vprint_message(const char* const format, va_list args) +{ + char buffer[4096]; + + vsnprintf(buffer, sizeof(buffer), format, args); + printf("%s", buffer); + fflush(stdout); +#ifdef _WIN32 + OutputDebugString(buffer); +#endif /* _WIN32 */ +} + + +void vprint_error(const char* const format, va_list args) +{ + char buffer[4096]; + + vsnprintf(buffer, sizeof(buffer), format, args); + fprintf(stderr, "%s", buffer); + fflush(stderr); +#ifdef _WIN32 + OutputDebugString(buffer); +#endif /* _WIN32 */ +} + + +void print_message(const char* const format, ...) { + va_list args; + va_start(args, format); + vprint_message(format, args); + va_end(args); +} + + +void print_error(const char* const format, ...) { + va_list args; + va_start(args, format); + vprint_error(format, args); + va_end(args); +} + +/* New formatter */ +static enum cm_message_output cm_get_output(void) +{ + enum cm_message_output output = global_msg_output; + char *env; + + env = getenv("CMOCKA_MESSAGE_OUTPUT"); + if (env != NULL) { + if (strcasecmp(env, "STDOUT") == 0) { + output = CM_OUTPUT_STDOUT; + } else if (strcasecmp(env, "SUBUNIT") == 0) { + output = CM_OUTPUT_SUBUNIT; + } else if (strcasecmp(env, "TAP") == 0) { + output = CM_OUTPUT_TAP; + } else if (strcasecmp(env, "XML") == 0) { + output = CM_OUTPUT_XML; + } + } + + return output; +} + +enum cm_printf_type { + PRINTF_TEST_START, + PRINTF_TEST_SUCCESS, + PRINTF_TEST_FAILURE, + PRINTF_TEST_ERROR, + PRINTF_TEST_SKIPPED, +}; + +static int xml_printed; +static int file_append; + +static void cmprintf_group_finish_xml(const char *group_name, + size_t total_executed, + size_t total_failed, + size_t total_errors, + size_t total_skipped, + double total_runtime, + struct CMUnitTestState *cm_tests) +{ + FILE *fp = stdout; + int file_opened = 0; + int multiple_files = 0; + char *env; + size_t i; + + env = getenv("CMOCKA_XML_FILE"); + if (env != NULL) { + char buf[1024]; + int rc; + + snprintf(buf, sizeof(buf), "%s", env); + + rc = c_strreplace(buf, sizeof(buf), "%g", group_name, &multiple_files); + if (rc < 0) { + snprintf(buf, sizeof(buf), "%s", env); + } + + fp = fopen(buf, "r"); + if (fp == NULL) { + fp = fopen(buf, "w"); + if (fp != NULL) { + file_append = 1; + file_opened = 1; + } else { + fp = stderr; + } + } else { + fclose(fp); + if (file_append) { + fp = fopen(buf, "a"); + if (fp != NULL) { + file_opened = 1; + xml_printed = 1; + } else { + fp = stderr; + } + } else { + fp = stderr; + } + } + } + + if (!xml_printed || (file_opened && !file_append)) { + fprintf(fp, "\n"); + if (!file_opened) { + xml_printed = 1; + } + } + + fprintf(fp, "\n"); + fprintf(fp, " \n", + group_name, + total_runtime, /* seconds */ + (unsigned)total_executed, + (unsigned)total_failed, + (unsigned)total_errors, + (unsigned)total_skipped); + + for (i = 0; i < total_executed; i++) { + struct CMUnitTestState *cmtest = &cm_tests[i]; + + fprintf(fp, " \n", + cmtest->test->name, cmtest->runtime); + + switch (cmtest->status) { + case CM_TEST_ERROR: + case CM_TEST_FAILED: + if (cmtest->error_message != NULL) { + fprintf(fp, " \n", + cmtest->error_message); + } else { + fprintf(fp, " \n"); + } + break; + case CM_TEST_SKIPPED: + fprintf(fp, " \n"); + break; + + case CM_TEST_PASSED: + case CM_TEST_NOT_STARTED: + break; + } + + fprintf(fp, " \n"); + } + + fprintf(fp, " \n"); + fprintf(fp, "\n"); + + if (file_opened) { + fclose(fp); + } +} + +static void cmprintf_group_start_standard(const char *group_name, + const size_t num_tests) +{ + print_message("[==========] %s: Running %zu test(s).\n", + group_name, + num_tests); +} + +static void cmprintf_group_finish_standard(const char *group_name, + size_t total_executed, + size_t total_passed, + size_t total_failed, + size_t total_errors, + size_t total_skipped, + struct CMUnitTestState *cm_tests) +{ + size_t i; + + print_message("[==========] %s: %zu test(s) run.\n", + group_name, + total_executed); + print_error("[ PASSED ] %u test(s).\n", + (unsigned)(total_passed)); + + if (total_skipped) { + print_error("[ SKIPPED ] %s: %zu test(s), listed below:\n", + group_name, + total_skipped); + for (i = 0; i < total_executed; i++) { + struct CMUnitTestState *cmtest = &cm_tests[i]; + + if (cmtest->status == CM_TEST_SKIPPED) { + print_error("[ SKIPPED ] %s\n", cmtest->test->name); + } + } + print_error("\n %zu SKIPPED TEST(S)\n", total_skipped); + } + + if (total_failed) { + print_error("[ FAILED ] %s: %zu test(s), listed below:\n", + group_name, + total_failed); + for (i = 0; i < total_executed; i++) { + struct CMUnitTestState *cmtest = &cm_tests[i]; + + if (cmtest->status == CM_TEST_FAILED) { + print_error("[ FAILED ] %s\n", cmtest->test->name); + } + } + print_error("\n %zu FAILED TEST(S)\n", + (total_failed + total_errors)); + } +} + +static void cmprintf_standard(enum cm_printf_type type, + const char *test_name, + const char *error_message) +{ + switch (type) { + case PRINTF_TEST_START: + print_message("[ RUN ] %s\n", test_name); + break; + case PRINTF_TEST_SUCCESS: + print_message("[ OK ] %s\n", test_name); + break; + case PRINTF_TEST_FAILURE: + if (error_message != NULL) { + print_error("[ ERROR ] --- %s\n", error_message); + } + print_message("[ FAILED ] %s\n", test_name); + break; + case PRINTF_TEST_SKIPPED: + print_message("[ SKIPPED ] %s\n", test_name); + break; + case PRINTF_TEST_ERROR: + if (error_message != NULL) { + print_error("%s\n", error_message); + } + print_error("[ ERROR ] %s\n", test_name); + break; + } +} + +static void cmprintf_group_start_tap(const size_t num_tests) +{ + static bool version_printed = false; + if (!version_printed) { + print_message("TAP version 13\n"); + version_printed = true; + } + + print_message("1..%u\n", (unsigned)num_tests); +} + +static void cmprintf_group_finish_tap(const char *group_name, + size_t total_executed, + size_t total_passed, + size_t total_skipped) +{ + const char *status = "not ok"; + if (total_passed + total_skipped == total_executed) { + status = "ok"; + } + print_message("# %s - %s\n", status, group_name); +} + +static void cmprintf_tap(enum cm_printf_type type, + size_t test_number, + const char *test_name, + const char *error_message) +{ + switch (type) { + case PRINTF_TEST_START: + break; + case PRINTF_TEST_SUCCESS: + print_message("ok %u - %s\n", (unsigned)test_number, test_name); + break; + case PRINTF_TEST_FAILURE: + print_message("not ok %u - %s\n", (unsigned)test_number, test_name); + if (error_message != NULL) { + char *msg; + char *p; + + msg = strdup(error_message); + if (msg == NULL) { + return; + } + p = msg; + + while (p[0] != '\0') { + char *q = p; + + p = strchr(q, '\n'); + if (p != NULL) { + p[0] = '\0'; + } + + print_message("# %s\n", q); + + if (p == NULL) { + break; + } + p++; + } + libc_free(msg); + } + break; + case PRINTF_TEST_SKIPPED: + print_message("ok %u # SKIP %s\n", (unsigned)test_number, test_name); + break; + case PRINTF_TEST_ERROR: + print_message("not ok %u - %s %s\n", + (unsigned)test_number, test_name, error_message); + break; + } +} + +static void cmprintf_subunit(enum cm_printf_type type, + const char *test_name, + const char *error_message) +{ + switch (type) { + case PRINTF_TEST_START: + print_message("test: %s\n", test_name); + break; + case PRINTF_TEST_SUCCESS: + print_message("success: %s\n", test_name); + break; + case PRINTF_TEST_FAILURE: + print_message("failure: %s", test_name); + if (error_message != NULL) { + print_message(" [\n%s\n]\n", error_message); + } + break; + case PRINTF_TEST_SKIPPED: + print_message("skip: %s\n", test_name); + break; + case PRINTF_TEST_ERROR: + print_message("error: %s [ %s ]\n", test_name, error_message); + break; + } +} + +static void cmprintf_group_start(const char *group_name, + const size_t num_tests) +{ + enum cm_message_output output; + + output = cm_get_output(); + + switch (output) { + case CM_OUTPUT_STDOUT: + cmprintf_group_start_standard(group_name, num_tests); + break; + case CM_OUTPUT_SUBUNIT: + break; + case CM_OUTPUT_TAP: + cmprintf_group_start_tap(num_tests); + break; + case CM_OUTPUT_XML: + break; + } +} + +static void cmprintf_group_finish(const char *group_name, + size_t total_executed, + size_t total_passed, + size_t total_failed, + size_t total_errors, + size_t total_skipped, + double total_runtime, + struct CMUnitTestState *cm_tests) +{ + enum cm_message_output output; + + output = cm_get_output(); + + switch (output) { + case CM_OUTPUT_STDOUT: + cmprintf_group_finish_standard(group_name, + total_executed, + total_passed, + total_failed, + total_errors, + total_skipped, + cm_tests); + break; + case CM_OUTPUT_SUBUNIT: + break; + case CM_OUTPUT_TAP: + cmprintf_group_finish_tap(group_name, + total_executed, + total_passed, + total_skipped); + break; + case CM_OUTPUT_XML: + cmprintf_group_finish_xml(group_name, + total_executed, + total_failed, + total_errors, + total_skipped, + total_runtime, + cm_tests); + break; + } +} + +static void cmprintf(enum cm_printf_type type, + size_t test_number, + const char *test_name, + const char *error_message) +{ + enum cm_message_output output; + + output = cm_get_output(); + + switch (output) { + case CM_OUTPUT_STDOUT: + cmprintf_standard(type, test_name, error_message); + break; + case CM_OUTPUT_SUBUNIT: + cmprintf_subunit(type, test_name, error_message); + break; + case CM_OUTPUT_TAP: + cmprintf_tap(type, test_number, test_name, error_message); + break; + case CM_OUTPUT_XML: + break; + } +} + +void cmocka_set_message_output(enum cm_message_output output) +{ + global_msg_output = output; +} + +void cmocka_set_test_filter(const char *pattern) +{ + global_test_filter_pattern = pattern; +} + +void cmocka_set_skip_filter(const char *pattern) +{ + global_skip_filter_pattern = pattern; +} + +/**************************************************************************** + * TIME CALCULATIONS + ****************************************************************************/ + +#ifdef HAVE_STRUCT_TIMESPEC +static struct timespec cm_tspecdiff(struct timespec time1, + struct timespec time0) +{ + struct timespec ret; + int xsec = 0; + int sign = 1; + + if (time0.tv_nsec > time1.tv_nsec) { + xsec = (int) ((time0.tv_nsec - time1.tv_nsec) / (1E9 + 1)); + time0.tv_nsec -= (long int) (1E9 * xsec); + time0.tv_sec += xsec; + } + + if ((time1.tv_nsec - time0.tv_nsec) > 1E9) { + xsec = (int) ((time1.tv_nsec - time0.tv_nsec) / 1E9); + time0.tv_nsec += (long int) (1E9 * xsec); + time0.tv_sec -= xsec; + } + + ret.tv_sec = time1.tv_sec - time0.tv_sec; + ret.tv_nsec = time1.tv_nsec - time0.tv_nsec; + + if (time1.tv_sec < time0.tv_sec) { + sign = -1; + } + + ret.tv_sec = ret.tv_sec * sign; + + return ret; +} + +static double cm_secdiff(struct timespec clock1, struct timespec clock0) +{ + double ret; + struct timespec diff; + + diff = cm_tspecdiff(clock1, clock0); + + ret = (double) diff.tv_sec; + ret += (double) diff.tv_nsec / (double) 1E9; + + return ret; +} +#endif /* HAVE_STRUCT_TIMESPEC */ + +/**************************************************************************** + * CMOCKA TEST RUNNER + ****************************************************************************/ +static int cmocka_run_one_test_or_fixture(const char *function_name, + CMUnitTestFunction test_func, + CMFixtureFunction setup_func, + CMFixtureFunction teardown_func, + void ** const volatile state, + const void *const heap_check_point) +{ + const ListNode * const volatile check_point = (const ListNode*) + (heap_check_point != NULL ? + heap_check_point : check_point_allocated_blocks()); + int handle_exceptions = 1; + void *current_state = NULL; + int rc = 0; + + /* FIXME check only one test or fixture is set */ + + /* Detect if we should handle exceptions */ +#ifdef _WIN32 + handle_exceptions = !IsDebuggerPresent(); +#endif /* _WIN32 */ +#ifdef UNIT_TESTING_DEBUG + handle_exceptions = 0; +#endif /* UNIT_TESTING_DEBUG */ + + + if (handle_exceptions) { +#ifndef _WIN32 + unsigned int i; + for (i = 0; i < ARRAY_SIZE(exception_signals); i++) { + default_signal_functions[i] = signal( + exception_signals[i], exception_handler); + } +#else /* _WIN32 */ + previous_exception_filter = SetUnhandledExceptionFilter( + exception_filter); +#endif /* !_WIN32 */ + } + + /* Init the test structure */ + initialize_testing(function_name); + + global_running_test = 1; + + if (cm_setjmp(global_run_test_env) == 0) { + if (test_func != NULL) { + test_func(state != NULL ? state : ¤t_state); + + fail_if_blocks_allocated(check_point, function_name); + rc = 0; + } else if (setup_func != NULL) { + rc = setup_func(state != NULL ? state : ¤t_state); + + /* + * For setup we can ignore any allocated blocks. We just need to + * ensure they're deallocated on tear down. + */ + } else if (teardown_func != NULL) { + rc = teardown_func(state != NULL ? state : ¤t_state); + + fail_if_blocks_allocated(check_point, function_name); + } else { + /* ERROR */ + } + fail_if_leftover_values(function_name); + global_running_test = 0; + } else { + /* TEST FAILED */ + global_running_test = 0; + rc = -1; + } + teardown_testing(function_name); + + if (handle_exceptions) { +#ifndef _WIN32 + unsigned int i; + for (i = 0; i < ARRAY_SIZE(exception_signals); i++) { + signal(exception_signals[i], default_signal_functions[i]); + } +#else /* _WIN32 */ + if (previous_exception_filter) { + SetUnhandledExceptionFilter(previous_exception_filter); + previous_exception_filter = NULL; + } +#endif /* !_WIN32 */ + } + + return rc; +} + +static int cmocka_run_group_fixture(const char *function_name, + CMFixtureFunction setup_func, + CMFixtureFunction teardown_func, + void **state, + const void *const heap_check_point) +{ + int rc; + + if (setup_func != NULL) { + rc = cmocka_run_one_test_or_fixture(function_name, + NULL, + setup_func, + NULL, + state, + heap_check_point); + } else { + rc = cmocka_run_one_test_or_fixture(function_name, + NULL, + NULL, + teardown_func, + state, + heap_check_point); + } + + return rc; +} + +static int cmocka_run_one_tests(struct CMUnitTestState *test_state) +{ +#ifdef HAVE_STRUCT_TIMESPEC + struct timespec start = { + .tv_sec = 0, + .tv_nsec = 0, + }; + struct timespec finish = { + .tv_sec = 0, + .tv_nsec = 0, + }; +#endif + int rc = 0; + + /* Run setup */ + if (test_state->test->setup_func != NULL) { + /* Setup the memory check point, it will be evaluated on teardown */ + test_state->check_point = check_point_allocated_blocks(); + + rc = cmocka_run_one_test_or_fixture(test_state->test->name, + NULL, + test_state->test->setup_func, + NULL, + &test_state->state, + test_state->check_point); + if (rc != 0) { + test_state->status = CM_TEST_ERROR; + cm_print_error("Test setup failed"); + } + } + + /* Run test */ +#ifdef HAVE_STRUCT_TIMESPEC + CMOCKA_CLOCK_GETTIME(CLOCK_REALTIME, &start); +#endif + + if (rc == 0) { + rc = cmocka_run_one_test_or_fixture(test_state->test->name, + test_state->test->test_func, + NULL, + NULL, + &test_state->state, + NULL); + if (rc == 0) { + test_state->status = CM_TEST_PASSED; + } else { + if (global_skip_test) { + test_state->status = CM_TEST_SKIPPED; + global_skip_test = 0; /* Do not skip the next test */ + } else { + test_state->status = CM_TEST_FAILED; + } + } + rc = 0; + } + + test_state->runtime = 0.0; + +#ifdef HAVE_STRUCT_TIMESPEC + CMOCKA_CLOCK_GETTIME(CLOCK_REALTIME, &finish); + test_state->runtime = cm_secdiff(finish, start); +#endif + + /* Run teardown */ + if (rc == 0 && test_state->test->teardown_func != NULL) { + rc = cmocka_run_one_test_or_fixture(test_state->test->name, + NULL, + NULL, + test_state->test->teardown_func, + &test_state->state, + test_state->check_point); + if (rc != 0) { + test_state->status = CM_TEST_ERROR; + cm_print_error("Test teardown failed"); + } + } + + test_state->error_message = cm_error_message; + cm_error_message = NULL; + + return rc; +} + +int _cmocka_run_group_tests(const char *group_name, + const struct CMUnitTest * const tests, + const size_t num_tests, + CMFixtureFunction group_setup, + CMFixtureFunction group_teardown) +{ + struct CMUnitTestState *cm_tests; + const ListNode *group_check_point = check_point_allocated_blocks(); + void *group_state = NULL; + size_t total_tests = 0; + size_t total_failed = 0; + size_t total_passed = 0; + size_t total_executed = 0; + size_t total_errors = 0; + size_t total_skipped = 0; + double total_runtime = 0; + size_t i; + int rc; + + /* Make sure LargestIntegralType is at least the size of a pointer. */ + assert_true(sizeof(LargestIntegralType) >= sizeof(void*)); + + cm_tests = libc_calloc(1, sizeof(struct CMUnitTestState) * num_tests); + if (cm_tests == NULL) { + return -1; + } + + /* Setup cmocka test array */ + for (i = 0; i < num_tests; i++) { + if (tests[i].name != NULL && + (tests[i].test_func != NULL + || tests[i].setup_func != NULL + || tests[i].teardown_func != NULL)) { + if (global_test_filter_pattern != NULL) { + int match; + + match = c_strmatch(tests[i].name, global_test_filter_pattern); + if (!match) { + continue; + } + } + if (global_skip_filter_pattern != NULL) { + int match; + + match = c_strmatch(tests[i].name, global_skip_filter_pattern); + if (match) { + continue; + } + } + cm_tests[total_tests] = (struct CMUnitTestState) { + .test = &tests[i], + .status = CM_TEST_NOT_STARTED, + .state = NULL, + }; + total_tests++; + } + } + + cmprintf_group_start(group_name, total_tests); + + rc = 0; + + /* Run group setup */ + if (group_setup != NULL) { + rc = cmocka_run_group_fixture("cmocka_group_setup", + group_setup, + NULL, + &group_state, + group_check_point); + } + + if (rc == 0) { + /* Execute tests */ + for (i = 0; i < total_tests; i++) { + struct CMUnitTestState *cmtest = &cm_tests[i]; + size_t test_number = i + 1; + + cmprintf(PRINTF_TEST_START, test_number, cmtest->test->name, NULL); + + if (group_state != NULL) { + cmtest->state = group_state; + } else if (cmtest->test->initial_state != NULL) { + cmtest->state = cmtest->test->initial_state; + } + + rc = cmocka_run_one_tests(cmtest); + total_executed++; + total_runtime += cmtest->runtime; + if (rc == 0) { + switch (cmtest->status) { + case CM_TEST_PASSED: + cmprintf(PRINTF_TEST_SUCCESS, + test_number, + cmtest->test->name, + cmtest->error_message); + total_passed++; + break; + case CM_TEST_SKIPPED: + cmprintf(PRINTF_TEST_SKIPPED, + test_number, + cmtest->test->name, + cmtest->error_message); + total_skipped++; + break; + case CM_TEST_FAILED: + cmprintf(PRINTF_TEST_FAILURE, + test_number, + cmtest->test->name, + cmtest->error_message); + total_failed++; + break; + default: + cmprintf(PRINTF_TEST_ERROR, + test_number, + cmtest->test->name, + "Internal cmocka error"); + total_errors++; + break; + } + } else { + char err_msg[2048] = {0}; + + snprintf(err_msg, sizeof(err_msg), + "Could not run test: %s", + cmtest->error_message); + + cmprintf(PRINTF_TEST_ERROR, + test_number, + cmtest->test->name, + err_msg); + total_errors++; + } + } + } else { + if (cm_error_message != NULL) { + print_error("[ ERROR ] --- %s\n", cm_error_message); + vcm_free_error(cm_error_message); + cm_error_message = NULL; + } + cmprintf(PRINTF_TEST_ERROR, 0, + group_name, "[ FAILED ] GROUP SETUP"); + total_errors++; + } + + /* Run group teardown */ + if (group_teardown != NULL) { + rc = cmocka_run_group_fixture("cmocka_group_teardown", + NULL, + group_teardown, + &group_state, + group_check_point); + if (rc != 0) { + if (cm_error_message != NULL) { + print_error("[ ERROR ] --- %s\n", cm_error_message); + vcm_free_error(cm_error_message); + cm_error_message = NULL; + } + cmprintf(PRINTF_TEST_ERROR, 0, + group_name, "[ FAILED ] GROUP TEARDOWN"); + } + } + + cmprintf_group_finish(group_name, + total_executed, + total_passed, + total_failed, + total_errors, + total_skipped, + total_runtime, + cm_tests); + + for (i = 0; i < total_tests; i++) { + vcm_free_error(discard_const_p(char, cm_tests[i].error_message)); + } + libc_free(cm_tests); + fail_if_blocks_allocated(group_check_point, "cmocka_group_tests"); + + return (int)(total_failed + total_errors); +} + +/**************************************************************************** + * DEPRECATED TEST RUNNER + ****************************************************************************/ + +int _run_test( + const char * const function_name, const UnitTestFunction Function, + void ** const volatile state, const UnitTestFunctionType function_type, + const void* const heap_check_point) { + const ListNode * const volatile check_point = (const ListNode*) + (heap_check_point ? + heap_check_point : check_point_allocated_blocks()); + void *current_state = NULL; + volatile int rc = 1; + int handle_exceptions = 1; +#ifdef _WIN32 + handle_exceptions = !IsDebuggerPresent(); +#endif /* _WIN32 */ +#ifdef UNIT_TESTING_DEBUG + handle_exceptions = 0; +#endif /* UNIT_TESTING_DEBUG */ + + cm_error_message_enabled = 0; + + if (handle_exceptions) { +#ifndef _WIN32 + unsigned int i; + for (i = 0; i < ARRAY_SIZE(exception_signals); i++) { + default_signal_functions[i] = signal( + exception_signals[i], exception_handler); + } +#else /* _WIN32 */ + previous_exception_filter = SetUnhandledExceptionFilter( + exception_filter); +#endif /* !_WIN32 */ + } + + if (function_type == UNIT_TEST_FUNCTION_TYPE_TEST) { + print_message("[ RUN ] %s\n", function_name); + } + initialize_testing(function_name); + global_running_test = 1; + if (cm_setjmp(global_run_test_env) == 0) { + Function(state ? state : ¤t_state); + fail_if_leftover_values(function_name); + + /* If this is a setup function then ignore any allocated blocks + * only ensure they're deallocated on tear down. */ + if (function_type != UNIT_TEST_FUNCTION_TYPE_SETUP) { + fail_if_blocks_allocated(check_point, function_name); + } + + global_running_test = 0; + + if (function_type == UNIT_TEST_FUNCTION_TYPE_TEST) { + print_message("[ OK ] %s\n", function_name); + } + rc = 0; + } else { + global_running_test = 0; + print_message("[ FAILED ] %s\n", function_name); + } + teardown_testing(function_name); + + if (handle_exceptions) { +#ifndef _WIN32 + unsigned int i; + for (i = 0; i < ARRAY_SIZE(exception_signals); i++) { + signal(exception_signals[i], default_signal_functions[i]); + } +#else /* _WIN32 */ + if (previous_exception_filter) { + SetUnhandledExceptionFilter(previous_exception_filter); + previous_exception_filter = NULL; + } +#endif /* !_WIN32 */ + } + + return rc; +} + + +int _run_tests(const UnitTest * const tests, const size_t number_of_tests) { + /* Whether to execute the next test. */ + int run_next_test = 1; + /* Whether the previous test failed. */ + int previous_test_failed = 0; + /* Whether the previous setup failed. */ + int previous_setup_failed = 0; + /* Check point of the heap state. */ + const ListNode * const check_point = check_point_allocated_blocks(); + /* Current test being executed. */ + size_t current_test = 0; + /* Number of tests executed. */ + size_t tests_executed = 0; + /* Number of failed tests. */ + size_t total_failed = 0; + /* Number of setup functions. */ + size_t setups = 0; + /* Number of teardown functions. */ + size_t teardowns = 0; + size_t i; + /* + * A stack of test states. A state is pushed on the stack + * when a test setup occurs and popped on tear down. + */ + TestState* test_states = + (TestState*)malloc(number_of_tests * sizeof(*test_states)); + /* The number of test states which should be 0 at the end */ + long number_of_test_states = 0; + /* Names of the tests that failed. */ + const char** failed_names = (const char**)malloc(number_of_tests * + sizeof(*failed_names)); + void **current_state = NULL; + + /* Count setup and teardown functions */ + for (i = 0; i < number_of_tests; i++) { + const UnitTest * const test = &tests[i]; + + if (test->function_type == UNIT_TEST_FUNCTION_TYPE_SETUP) { + setups++; + } + + if (test->function_type == UNIT_TEST_FUNCTION_TYPE_TEARDOWN) { + teardowns++; + } + } + + print_message("[==========] Running %"PRIdS " test(s).\n", + number_of_tests - setups - teardowns); + + /* Make sure LargestIntegralType is at least the size of a pointer. */ + assert_true(sizeof(LargestIntegralType) >= sizeof(void*)); + + while (current_test < number_of_tests) { + const ListNode *test_check_point = NULL; + TestState *current_TestState; + const UnitTest * const test = &tests[current_test++]; + if (!test->function) { + continue; + } + + switch (test->function_type) { + case UNIT_TEST_FUNCTION_TYPE_TEST: + if (! previous_setup_failed) { + run_next_test = 1; + } + break; + case UNIT_TEST_FUNCTION_TYPE_SETUP: { + /* Checkpoint the heap before the setup. */ + current_TestState = &test_states[number_of_test_states++]; + current_TestState->check_point = check_point_allocated_blocks(); + test_check_point = current_TestState->check_point; + current_state = ¤t_TestState->state; + *current_state = NULL; + run_next_test = 1; + break; + } + case UNIT_TEST_FUNCTION_TYPE_TEARDOWN: + /* Check the heap based on the last setup checkpoint. */ + assert_true(number_of_test_states); + current_TestState = &test_states[--number_of_test_states]; + test_check_point = current_TestState->check_point; + current_state = ¤t_TestState->state; + break; + default: + print_error("Invalid unit test function type %d\n", + test->function_type); + exit_test(1); + break; + } + + if (run_next_test) { + int failed = _run_test(test->name, test->function, current_state, + test->function_type, test_check_point); + if (failed) { + failed_names[total_failed] = test->name; + } + + switch (test->function_type) { + case UNIT_TEST_FUNCTION_TYPE_TEST: + previous_test_failed = failed; + total_failed += failed; + tests_executed ++; + break; + + case UNIT_TEST_FUNCTION_TYPE_SETUP: + if (failed) { + total_failed ++; + tests_executed ++; + /* Skip forward until the next test or setup function. */ + run_next_test = 0; + previous_setup_failed = 1; + } + previous_test_failed = 0; + break; + + case UNIT_TEST_FUNCTION_TYPE_TEARDOWN: + /* If this test failed. */ + if (failed && !previous_test_failed) { + total_failed ++; + } + break; + default: +#ifndef _HPUX + assert_null("BUG: shouldn't be here!"); +#endif + break; + } + } + } + + print_message("[==========] %"PRIdS " test(s) run.\n", tests_executed); + print_error("[ PASSED ] %"PRIdS " test(s).\n", tests_executed - total_failed); + + if (total_failed > 0) { + print_error("[ FAILED ] %"PRIdS " test(s), listed below:\n", total_failed); + for (i = 0; i < total_failed; i++) { + print_error("[ FAILED ] %s\n", failed_names[i]); + } + } else { + print_error("\n %"PRIdS " FAILED TEST(S)\n", total_failed); + } + + if (number_of_test_states != 0) { + print_error("[ ERROR ] Mismatched number of setup %"PRIdS " and " + "teardown %"PRIdS " functions\n", setups, teardowns); + total_failed = (size_t)-1; + } + + free(test_states); + free((void*)failed_names); + + fail_if_blocks_allocated(check_point, "run_tests"); + return (int)total_failed; +} + +int _run_group_tests(const UnitTest * const tests, const size_t number_of_tests) +{ + UnitTestFunction setup = NULL; + const char *setup_name = NULL; + size_t num_setups = 0; + UnitTestFunction teardown = NULL; + const char *teardown_name = NULL; + size_t num_teardowns = 0; + size_t current_test = 0; + size_t i; + + /* Number of tests executed. */ + size_t tests_executed = 0; + /* Number of failed tests. */ + size_t total_failed = 0; + /* Check point of the heap state. */ + const ListNode * const check_point = check_point_allocated_blocks(); + const char **failed_names = NULL; + void **current_state = NULL; + TestState group_state = { + .check_point = NULL, + }; + + if (number_of_tests == 0) { + return -1; + } + + failed_names = (const char **)malloc(number_of_tests * + sizeof(*failed_names)); + if (failed_names == NULL) { + return -2; + } + + /* Find setup and teardown function */ + for (i = 0; i < number_of_tests; i++) { + const UnitTest * const test = &tests[i]; + + if (test->function_type == UNIT_TEST_FUNCTION_TYPE_GROUP_SETUP) { + if (setup == NULL) { + setup = test->function; + setup_name = test->name; + num_setups = 1; + } else { + print_error("[ ERROR ] More than one group setup function detected\n"); + exit_test(1); + } + } + + if (test->function_type == UNIT_TEST_FUNCTION_TYPE_GROUP_TEARDOWN) { + if (teardown == NULL) { + teardown = test->function; + teardown_name = test->name; + num_teardowns = 1; + } else { + print_error("[ ERROR ] More than one group teardown function detected\n"); + exit_test(1); + } + } + } + + print_message("[==========] Running %"PRIdS " test(s).\n", + number_of_tests - num_setups - num_teardowns); + + if (setup != NULL) { + int failed; + + group_state.check_point = check_point_allocated_blocks(); + current_state = &group_state.state; + *current_state = NULL; + failed = _run_test(setup_name, + setup, + current_state, + UNIT_TEST_FUNCTION_TYPE_SETUP, + group_state.check_point); + if (failed) { + failed_names[total_failed] = setup_name; + } + + total_failed += failed; + tests_executed++; + } + + while (current_test < number_of_tests) { + int run_test = 0; + const UnitTest * const test = &tests[current_test++]; + if (test->function == NULL) { + continue; + } + + switch (test->function_type) { + case UNIT_TEST_FUNCTION_TYPE_TEST: + run_test = 1; + break; + case UNIT_TEST_FUNCTION_TYPE_SETUP: + case UNIT_TEST_FUNCTION_TYPE_TEARDOWN: + case UNIT_TEST_FUNCTION_TYPE_GROUP_SETUP: + case UNIT_TEST_FUNCTION_TYPE_GROUP_TEARDOWN: + break; + default: + print_error("Invalid unit test function type %d\n", + test->function_type); + break; + } + + if (run_test) { + int failed; + + failed = _run_test(test->name, + test->function, + current_state, + test->function_type, + NULL); + if (failed) { + failed_names[total_failed] = test->name; + } + + total_failed += failed; + tests_executed++; + } + } + + if (teardown != NULL) { + int failed; + + failed = _run_test(teardown_name, + teardown, + current_state, + UNIT_TEST_FUNCTION_TYPE_GROUP_TEARDOWN, + group_state.check_point); + if (failed) { + failed_names[total_failed] = teardown_name; + } + + total_failed += failed; + tests_executed++; + } + + print_message("[==========] %"PRIdS " test(s) run.\n", tests_executed); + print_error("[ PASSED ] %"PRIdS " test(s).\n", tests_executed - total_failed); + + if (total_failed) { + print_error("[ FAILED ] %"PRIdS " test(s), listed below:\n", total_failed); + for (i = 0; i < total_failed; i++) { + print_error("[ FAILED ] %s\n", failed_names[i]); + } + } else { + print_error("\n %"PRIdS " FAILED TEST(S)\n", total_failed); + } + + free((void*)failed_names); + fail_if_blocks_allocated(check_point, "run_group_tests"); + + return (int)total_failed; +} diff --git a/cmake/cmocka-1.1.7/src/cmocka.def b/cmake/cmocka-1.1.7/src/cmocka.def new file mode 100644 index 0000000..1c2c653 --- /dev/null +++ b/cmake/cmocka-1.1.7/src/cmocka.def @@ -0,0 +1,56 @@ +LIBRARY cmocka +EXPORTS + _assert_double_equal + _assert_double_not_equal + _assert_float_equal + _assert_float_not_equal + _assert_in_range + _assert_in_set + _assert_int_equal + _assert_int_not_equal + _assert_memory_equal + _assert_memory_not_equal + _assert_not_in_range + _assert_not_in_set + _assert_return_code + _assert_string_equal + _assert_string_not_equal + _assert_true + _check_expected + _cmocka_run_group_tests + _expect_any + _expect_check + _expect_function_call + _expect_in_range + _expect_in_set + _expect_memory + _expect_not_in_range + _expect_not_in_set + _expect_not_memory + _expect_not_string + _expect_not_value + _expect_string + _expect_value + _fail + _function_called + _mock + _run_test + _run_tests + _skip + _test_calloc + _test_free + _test_malloc + _test_realloc + _will_return + cm_print_error + cmocka_set_message_output + cmocka_set_test_filter + cmocka_set_skip_filter + global_expect_assert_env + global_expecting_assert + global_last_failed_assert + mock_assert + print_error + print_message + vprint_error + vprint_message diff --git a/cmake/cmocka-1.1.7/tests/CMakeLists.txt b/cmake/cmocka-1.1.7/tests/CMakeLists.txt new file mode 100644 index 0000000..1ce287a --- /dev/null +++ b/cmake/cmocka-1.1.7/tests/CMakeLists.txt @@ -0,0 +1,267 @@ +project(tests C) + +set(TEST_EXCEPTION_HANDLER TRUE) +if (WIN32) + # FIXME: The exception handler doesn't work on Windows + set(TEST_EXCEPTION_HANDLER FALSE) +endif() +if (CMAKE_BUILD_TYPE) + string(TOLOWER "${CMAKE_BUILD_TYPE}" CMAKE_BUILD_TYPE_LOWER) + if (CMAKE_BUILD_TYPE_LOWER STREQUAL "undefinedsanitizer") + set(TEST_EXCEPTION_HANDLER FALSE) + endif() +endif() + +set(CMOCKA_TESTS + test_alloc + test_group_setup_assert + test_group_setup_fail + test_fixtures + test_group_fixtures + test_groups + test_float_macros + test_double_macros + test_assert_macros + test_assert_macros_fail + test_basics + test_skip + test_strmatch + test_setup_fail + test_ordering + test_ordering_fail + test_returns + test_returns_fail + test_string + test_wildcard + test_skip_filter + test_cmockery + ) + +if (TEST_EXCEPTION_HANDLER) + list(APPEND CMOCKA_TESTS test_exception_handler) +endif() + +foreach(_CMOCKA_TEST ${CMOCKA_TESTS}) + add_cmocka_test(${_CMOCKA_TEST} + SOURCES ${_CMOCKA_TEST}.c + COMPILE_OPTIONS ${DEFAULT_C_COMPILE_FLAGS} + LINK_LIBRARIES cmocka::static + LINK_OPTIONS ${DEFAULT_LINK_FLAGS}) + target_include_directories(${_CMOCKA_TEST} PRIVATE ${cmocka_BINARY_DIR}) + + add_cmocka_test_environment(${_CMOCKA_TEST}) +endforeach() + +### Special Cases +if (${CMAKE_C_COMPILER_ID} MATCHES "(GNU|Clang)") + set_source_files_properties(test_cmockery.c PROPERTIES COMPILE_FLAGS "-Wno-deprecated-declarations") +endif() + +### Exceptions + +# test_skip +set_tests_properties( + test_skip + PROPERTIES + PASS_REGULAR_EXPRESSION + "\\[ SKIPPED \\] test_check_skip" +) + +# test_assert_macros_fail +set_tests_properties( + test_assert_macros_fail + PROPERTIES + PASS_REGULAR_EXPRESSION + "\\[ FAILED \\] tests: 1 test" +) + +# test_ordering ensure proper failures +set_tests_properties( + test_ordering_fail + PROPERTIES + PASS_REGULAR_EXPRESSION + "\\[ FAILED \\] tests: 7 test" +) + +# test_returns_fail ensure proper failures +set_tests_properties( + test_returns_fail + PROPERTIES + PASS_REGULAR_EXPRESSION + "\\[ FAILED \\] alloc_tests: 3 test" +) + +# test_exception_handler +if (TEST_EXCEPTION_HANDLER) + set_tests_properties(test_exception_handler + PROPERTIES + PASS_REGULAR_EXPRESSION + "Test failed with exception") +endif (TEST_EXCEPTION_HANDLER) + +set_tests_properties( + test_setup_fail + PROPERTIES + WILL_FAIL + 1 +) + +set_tests_properties( + test_group_setup_assert + PROPERTIES + WILL_FAIL + 1 +) + +set_tests_properties( + test_group_setup_fail + PROPERTIES + WILL_FAIL + 1 +) + +add_test(test_setup_fail_1_failed ${TARGET_SYSTEM_EMULATOR} test_setup_fail) +add_cmocka_test_environment(test_setup_fail_1_failed) +set_tests_properties( + test_setup_fail_1_failed + PROPERTIES + PASS_REGULAR_EXPRESSION + "\\[ ERROR \\] int_test_ignored" +) + +add_test (test_setup_fail_1_passed ${TARGET_SYSTEM_EMULATOR} test_setup_fail) +add_cmocka_test_environment(test_setup_fail_1_passed) +set_tests_properties( + test_setup_fail_1_passed + PROPERTIES + PASS_REGULAR_EXPRESSION + "\\[ PASSED \\] 1 test\\(s\\)." +) + +add_test (test_setup_fail_match_failed ${TARGET_SYSTEM_EMULATOR} test_setup_fail) +add_cmocka_test_environment(test_setup_fail_match_failed) +set_tests_properties( + test_setup_fail_match_failed + PROPERTIES + PASS_REGULAR_EXPRESSION + "\\[ ERROR \\] int_test_ignored" +) + +add_test (test_setup_fail_match_passed ${TARGET_SYSTEM_EMULATOR} test_setup_fail) +add_cmocka_test_environment(test_setup_fail_match_passed) +set_tests_properties( + test_setup_fail_match_passed + PROPERTIES + PASS_REGULAR_EXPRESSION + "\\[ OK \\] int_test_success" +) + +### Output formats + +# test output of success, failure, skip, fixture failure +set(OUTPUT_TESTS + test_basics + test_assert_macros_fail + test_groups + test_skip + test_setup_fail) + +set(TEST_OUTPUT_FMTS + tap + subunit + xml) + +set(test_basics_tap_out + "^TAP version 13" + "1\\.\\.2" + "ok 1 - null_test_success" + "ok 2 - int_test_success" + "# ok - tests") +set(test_assert_macros_fail_tap_out + "^TAP version 13" + "1\\.\\.1" + "not ok 1 - test_assert_return_code_fail" + "#[^\n\r]+[\n\r]#[^\n\r]+[\n\r]# not ok - tests") +set(test_groups_tap_out + "^TAP version 13" + "1\\.\\.1" + "ok 1 - null_test_success" + "# ok - test_group1" + "1\\.\\.1" + "ok 1 - int_test_success" + "# ok - test_group2") +set(test_skip_tap_out + "ok 1 # SKIP") +set(test_setup_fail_tap_out + "not ok 1 - int_test_ignored Could not run test: Test setup failed") + +set(test_basics_subunit_out + "^test: null_test_success" + "success: null_test_success") +set(test_assert_macros_fail_subunit_out + "failure: test_assert_return_code_fail \\[") +set(test_groups_subunit_out + "^test: null_test_success" + "success: null_test_success") +set(test_skip_subunit_out + "^test: test_check_skip" + "skip: test_check_skip") +set(test_setup_fail_subunit_out + "error: int_test_ignored \\[ Could not run test: Test setup failed \\]") + +set(test_basics_xml_out + "" + ".*") +set(test_assert_macros_fail_xml_out + "" + "") +set(test_groups_xml_out + "^<\\?xml version=\"1.0\" encoding=\"UTF-8\" \\?>" + "" + "" + "" + "" + "" + ".*" + "" + "" + "" + "") +set(test_skip_xml_out + "" + "") +set(test_setup_fail_xml_out + "" + "") + +foreach(_TEST_OUTPUT_FMT ${TEST_OUTPUT_FMTS}) + foreach(_OUTPUT_TEST ${OUTPUT_TESTS}) + set(TEST_NAME ${_OUTPUT_TEST}_${_TEST_OUTPUT_FMT}) + add_test(${TEST_NAME} ${TARGET_SYSTEM_EMULATOR} ${_OUTPUT_TEST}) + add_cmocka_test_environment(${TEST_NAME}) + + set_property( + TEST + ${TEST_NAME} + APPEND + PROPERTY + ENVIRONMENT CMOCKA_MESSAGE_OUTPUT=${_TEST_OUTPUT_FMT} + ) + + list(LENGTH ${TEST_NAME}_out len) + list(GET ${TEST_NAME}_out 0 output) + if(len GREATER 1) + list(REMOVE_AT ${TEST_NAME}_out 0) + foreach(line ${${TEST_NAME}_out}) + set(output "${output}[ \n\r]+${line}") + endforeach() + endif() + + set_tests_properties( + ${TEST_NAME} + PROPERTIES + PASS_REGULAR_EXPRESSION + ${output} + ) + endforeach() +endforeach() diff --git a/cmake/cmocka-1.1.7/tests/cmocka_test.cmake b/cmake/cmocka-1.1.7/tests/cmocka_test.cmake new file mode 100644 index 0000000..53ffcca --- /dev/null +++ b/cmake/cmocka-1.1.7/tests/cmocka_test.cmake @@ -0,0 +1,229 @@ +# +# CTEST SCRIPT FOR CMOCKA TESTING +# + +# +# Running this script: +# +# ctest -S tests/cmocka_test.cmake \ +# -DCTEST_MODEL="Nightly" +# -DCTEST_SITE="host.cmocka.org" \ +# -DCTEST_TARGET_SYSTEM="Linux-openSUSE_Tumbleweed-x86_64" +# +# The Target system describes the target OS, version, architecture, etc. This +# parameter allows the testing script to choose appropriate configuration for +# CMake and build tools. +# +# The set of supported targets is defined by the project. +# +# The generic format for the Target system is [-][-], where +# +# is one of Linux, Windows, MacOS, Android. +# is an optional OS name and version, for example Fedora-28, Win10. +# is an optional architecture description, for example x86_64, ARM, ARM-Tegra5. +# +# To enable coverage, set: +# -DCTEST_WITH_COVERAGE=TRUE +# +# To enable dynamic analysis, set: +# -DCTEST_WITH_DYNAMIC_ANALYSIS=TRUE +# + +# +# 0. Set defaults +# +set(PROJECT_NAME "cmocka") +set(PROJECT_GIT_URL "https://git.cryptomilk.org/projects/cmocka.git") + +# +# 1. Include CText Ext module +# +if(NOT CTEST_EXT_INCLUDED) + function(download_ctest_ext) + message("Download latest version of CTest Extension module") + + find_package(Git QUIET) + + set(repo_url "https://github.com/jet47/ctest-ext.git") + set(repo_dir "${CMAKE_CURRENT_LIST_DIR}/ctest-ext") + set(tmp_dir "${CMAKE_CURRENT_LIST_DIR}/ctest-ext-tmp") + + if(NOT EXISTS "${repo_dir}") + set(CTEST_CHECKOUT_COMMAND "${GIT_EXECUTABLE} clone ${repo_url} ${repo_dir}") + endif() + set(CTEST_UPDATE_COMMAND "${GIT_EXECUTABLE}") + + ctest_start("CTestExt" "${repo_dir}" "${tmp_dir}") + ctest_update(SOURCE "${repo_dir}") + + file(REMOVE_RECURSE "${tmp_dir}") + + set(CTEST_EXT_MODULE_PATH "${repo_dir}" PARENT_SCOPE) + endfunction() + + if(NOT DEFINED CTEST_EXT_MODULE_PATH) + if(DEFINED ENV{CTEST_EXT_MODULE_PATH} AND EXISTS "$ENV{CTEST_EXT_MODULE_PATH}/ctest_ext.cmake") + set(CTEST_EXT_MODULE_PATH "$ENV{CTEST_EXT_MODULE_PATH}") + elseif(EXISTS "${CMAKE_CURRENT_LIST_DIR}/ctest-ext/ctest_ext.cmake") + set(CTEST_EXT_MODULE_PATH "${CMAKE_CURRENT_LIST_DIR}/ctest-ext") + else() + download_ctest_ext() + endif() + endif() + + include("${CTEST_EXT_MODULE_PATH}/ctest_ext.cmake") +endif() + +# +# 2. Initialize CTest Ext module +# +set_ifndef(CTEST_PROJECT_NAME ${PROJECT_NAME}) + +set_ifndef(CTEST_PROJECT_GIT_URL ${PROJECT_GIT_URL}) +set_ifndef(CTEST_WITH_UPDATE TRUE) + +ctest_ext_init() + +# +# 3. Configure project for testing +# + +# Check supported targets and models +check_if_matches(CTEST_TARGET_SYSTEM "^Linux" "^Windows") +check_if_matches(CTEST_MODEL "^Experimental$" "^Nightly$" "^Continuous$" "^Release$" "^Documentation$") + +# Checks for Continuous model +set(IS_CONTINUOUS FALSE) +if(CTEST_MODEL MATCHES "Continuous") + set(IS_CONTINUOUS TRUE) +endif() + +set(IS_BINARY_EMPTY FALSE) +if(NOT EXISTS "${CTEST_BINARY_DIRECTORY}/CMakeCache.txt") + set(IS_BINARY_EMPTY TRUE) +endif() + +if(IS_CONTINUOUS AND NOT IS_BINARY_EMPTY AND NOT HAVE_UPDATES) + ctest_ext_info("Continuous model : no updates") + return() +endif() + +# Configure the testing model +set_ifndef(CTEST_WITH_SUBMIT TRUE) + +if(CTEST_MODEL MATCHES "Documentation") + set_ifndef(CTEST_WITH_TESTS FALSE) +else() + set_ifndef(CTEST_WITH_TESTS TRUE) +endif() + + +set_ifndef(CTEST_WITH_COVERAGE FALSE) +if (CTEST_WITH_COVERAGE) + set_ifndef(CTEST_COVERAGE_TOOL "CDASH") +endif() + +set_ifndef(CTEST_WITH_DYNAMIC_ANALYSIS FALSE) +if (CTEST_WITH_DYNAMIC_ANALYSIS) + set_ifndef(CTEST_DYNAMIC_ANALYSIS_TOOL "CDASH") +endif() + + +if(CTEST_MODEL MATCHES "Continuous") + set_ifndef(CTEST_EMPTY_BINARY_DIRECTORY FALSE) +else() + set_ifndef(CTEST_EMPTY_BINARY_DIRECTORY TRUE) +endif() + +# Set CMake options +if(CTEST_TARGET_SYSTEM MATCHES "Windows") + if(CTEST_TARGET_SYSTEM MATCHES "64") + set_ifndef(CTEST_CMAKE_GENERATOR "Visual Studio 13 Win64") + else() + set_ifndef(CTEST_CMAKE_GENERATOR "Visual Studio 13") + endif() +else() + set_ifndef(CTEST_CMAKE_GENERATOR "Unix Makefiles") +endif() + +if(CTEST_MODEL MATCHES "(Release|Continuous)") + set_ifndef(CTEST_CONFIGURATION_TYPE "Release") +else() + set_ifndef(CTEST_CONFIGURATION_TYPE "Debug") +endif() + +### Add project default build options here !!! + +add_cmake_cache_entry(UNIT_TESTING ON) +add_cmake_cache_entry(WITH_CMOCKERY_SUPPORT ON) + +### Add project default build options here ^^^ + +add_cmake_cache_entry("ENABLE_CTEST" TYPE "BOOL" "ON") + +if(CTEST_WITH_COVERAGE) + add_cmake_cache_entry("ENABLE_COVERAGE" TYPE "BOOL" "ON") +else() + add_cmake_cache_entry("ENABLE_COVERAGE" TYPE "BOOL" "OFF") +endif() + +if(CTEST_MODEL MATCHES "Documentation") + add_cmake_cache_entry("BUILD_DOCS" TYPE "BOOL" "ON") +endif() + +if(CTEST_MODEL MATCHES "Release") + if(CTEST_TARGET_SYSTEM MATCHES "Windows") + add_cmake_cache_entry("CPACK_GENERATOR" TYPE "STRING" "ZIP") + else() + add_cmake_cache_entry("CPACK_GENERATOR" TYPE "STRING" "TGZ") + endif() +endif() + +# +# 4. Start testing, configure and build project +# +ctest_ext_start() + +ctest_ext_configure() + +if(CTEST_MODEL MATCHES "Release") + ctest_ext_build(TARGETS "ALL" "package") +elseif(CTEST_MODEL MATCHES "Documentation") + ctest_ext_build(TARGET "docs") +else() + ctest_ext_build() +endif() + +# +# 5. Run tests +# +if(CTEST_MODEL MATCHES "Nightly") + ctest_ext_test(INCLUDE_LABEL "Full") +else() + ctest_ext_test(EXCLUDE_LABEL "Light") +endif() + +ctest_ext_coverage( + CDASH + LABELS "Module" +) + +ctest_ext_dynamic_analysis( + CDASH + INCLUDE_LABEL "Light" +) + +# +# 6. Submit results to remote server +# +if(CTEST_MODEL MATCHES "Release") + if(CTEST_TARGET_SYSTEM MATCHES "Windows") + file(GLOB packages "${CTEST_BINARY_DIRECTORY}/*.zip") + else() + file(GLOB packages "${CTEST_BINARY_DIRECTORY}/*.tar.gz") + endif() + + list(APPEND CTEST_UPLOAD_FILES ${packages}) +endif() + +ctest_ext_submit() diff --git a/cmake/cmocka-1.1.7/tests/ctest-default.cmake b/cmake/cmocka-1.1.7/tests/ctest-default.cmake new file mode 100644 index 0000000..e21e93c --- /dev/null +++ b/cmake/cmocka-1.1.7/tests/ctest-default.cmake @@ -0,0 +1,74 @@ +## The directory to run ctest in. +set(CTEST_DIRECTORY "$ENV{HOME}/workspace/tmp/dashboards/cmocka") + +## The hostname of the machine +set(CTEST_SITE "host.cmocka.org") +## The buildname +set(CTEST_BUILD_NAME "Linux_GCC_x86_64_default") + +## The Makefile generator to use +set(CTEST_CMAKE_GENERATOR "Unix Makefiles") + +## The Build configuration to use. +set(CTEST_BUILD_CONFIGURATION "Debug") + +## The build options for the project +set(CTEST_BUILD_OPTIONS "-DUNIT_TESTING=ON -DWITH_CMOCKERY_SUPPORT=ON") + +#set(CTEST_CUSTOM_MEMCHECK_IGNORE torture_rand) + +## The Model to set: Nightly, Continous, Experimental +set(CTEST_MODEL "Experimental") + +## The URL to the git repository +set(CTEST_GIT_REPOSITORY "git://git.cryptomilk.org/projects/cmocka.git") + +## The branch +#set(CTEST_GIT_BRANCH "--branch v0-5") + +## Wether to enable memory checking. +set(WITH_MEMCHECK FALSE) + +## Wether to enable code coverage. +set(WITH_COVERAGE FALSE) + +####################################################################### + +if (WITH_COVERAGE AND NOT WIN32) + set(CTEST_BUILD_CONFIGURATION "Profiling") +endif (WITH_COVERAGE AND NOT WIN32) + +set(CTEST_SOURCE_DIRECTORY "${CTEST_DIRECTORY}/${CTEST_BUILD_NAME}/source") +set(CTEST_BINARY_DIRECTORY "${CTEST_DIRECTORY}/${CTEST_BUILD_NAME}/build") + +set(CTEST_MEMORYCHECK_SUPPRESSIONS_FILE ${CMAKE_SOURCE_DIR}/tests/valgrind.supp) + +find_program(CTEST_GIT_COMMAND NAMES git) +find_program(CTEST_COVERAGE_COMMAND NAMES gcov) +find_program(CTEST_MEMORYCHECK_COMMAND NAMES valgrind) + +if(NOT EXISTS "${CTEST_SOURCE_DIRECTORY}") + set(CTEST_CHECKOUT_COMMAND "${CTEST_GIT_COMMAND} clone ${CTEST_GIT_BRANCH} ${CTEST_GIT_REPOSITORY} ${CTEST_SOURCE_DIRECTORY}") +endif() + +set(CTEST_UPDATE_COMMAND "${CTEST_GIT_COMMAND}") + +set(CTEST_CONFIGURE_COMMAND "${CMAKE_COMMAND} -DCMAKE_BUILD_TYPE:STRING=${CTEST_BUILD_CONFIGURATION}") +set(CTEST_CONFIGURE_COMMAND "${CTEST_CONFIGURE_COMMAND} ${CTEST_BUILD_OPTIONS}") +set(CTEST_CONFIGURE_COMMAND "${CTEST_CONFIGURE_COMMAND} \"-G${CTEST_CMAKE_GENERATOR}\"") +set(CTEST_CONFIGURE_COMMAND "${CTEST_CONFIGURE_COMMAND} \"${CTEST_SOURCE_DIRECTORY}\"") + +ctest_empty_binary_directory(${CTEST_BINARY_DIRECTORY}) + +ctest_start(${CTEST_MODEL} TRACK ${CTEST_MODEL}) +ctest_update(SOURCE ${CTEST_SOURCE_DIRECTORY}) +ctest_configure(BUILD ${CTEST_BINARY_DIRECTORY}) +ctest_build(BUILD ${CTEST_BINARY_DIRECTORY}) +ctest_test(BUILD ${CTEST_BINARY_DIRECTORY}) +if (WITH_MEMCHECK AND CTEST_COVERAGE_COMMAND) + ctest_coverage(BUILD ${CTEST_BINARY_DIRECTORY}) +endif (WITH_MEMCHECK AND CTEST_COVERAGE_COMMAND) +if (WITH_MEMCHECK AND CTEST_MEMORYCHECK_COMMAND) + ctest_memcheck(BUILD ${CTEST_BINARY_DIRECTORY}) +endif (WITH_MEMCHECK AND CTEST_MEMORYCHECK_COMMAND) +ctest_submit() diff --git a/cmake/cmocka-1.1.7/tests/meson.build b/cmake/cmocka-1.1.7/tests/meson.build new file mode 100644 index 0000000..b49066b --- /dev/null +++ b/cmake/cmocka-1.1.7/tests/meson.build @@ -0,0 +1,30 @@ +tests = { + 'alloc': false, + 'group_setup_assert': true, + 'group_setup_fail': true, + 'fixtures': false, + 'group_fixtures': false, + 'groups': false, + 'float_macros': false, + 'assert_macros': false, + 'assert_macros_fail': true, + 'basics': false, + 'skip': false, + 'strmatch': false, + 'setup_fail': true, + 'ordering': false, + 'ordering_fail': true, + 'returns': false, + 'returns_fail': true, + 'wildcard': false, + 'skip_filter': false, + 'cmockery': false +} + +foreach name, should_fail: tests + exe = executable(name, + 'test_@0@.c'.format(name), + include_directories: [cmocka_includes], + link_with: [libcmocka]) + test(name, exe, should_fail: should_fail) +endforeach diff --git a/cmake/cmocka-1.1.7/tests/test_alloc.c b/cmake/cmocka-1.1.7/tests/test_alloc.c new file mode 100644 index 0000000..966814a --- /dev/null +++ b/cmake/cmocka-1.1.7/tests/test_alloc.c @@ -0,0 +1,91 @@ +#include "config.h" + +#include +#include +#include +#include +#include + +#include +#include +#include + +static void torture_test_malloc(void **state) +{ + char *str; + size_t str_len; + size_t len; + + (void)state; /* unsused */ + + str_len = 12; + str = (char *)test_malloc(str_len); + assert_non_null(str); + + len = snprintf(str, str_len, "test string"); + assert_int_equal(len, 11); + + len = strlen(str); + assert_int_equal(len, 11); + + test_free(str); +} + +static void torture_test_realloc(void **state) +{ + char *str; + char *tmp; + size_t str_len; + size_t len; + + (void)state; /* unsused */ + + str_len = 16; + str = (char *)test_malloc(str_len); + assert_non_null(str); + + len = snprintf(str, str_len, "test string 123"); + assert_int_equal(len, 15); + + len = strlen(str); + assert_int_equal(len, 15); + + str_len = 20; + tmp = test_realloc(str, str_len); + assert_non_null(tmp); + + str = tmp; + len = strlen(str); + assert_string_equal(tmp, "test string 123"); + + snprintf(str + len, str_len - len, "4567"); + assert_string_equal(tmp, "test string 1234567"); + + test_free(str); +} + +static void torture_test_realloc_set0(void **state) +{ + char *str; + size_t str_len; + + (void)state; /* unsused */ + + str_len = 16; + str = (char *)test_malloc(str_len); + assert_non_null(str); + + /* realloc(ptr, 0) is like a free() */ + str = (char *)test_realloc(str, 0); + assert_null(str); +} + +int main(void) { + const struct CMUnitTest alloc_tests[] = { + cmocka_unit_test(torture_test_malloc), + cmocka_unit_test(torture_test_realloc), + cmocka_unit_test(torture_test_realloc_set0), + }; + + return cmocka_run_group_tests(alloc_tests, NULL, NULL); +} diff --git a/cmake/cmocka-1.1.7/tests/test_assert_macros.c b/cmake/cmocka-1.1.7/tests/test_assert_macros.c new file mode 100644 index 0000000..1a00880 --- /dev/null +++ b/cmake/cmocka-1.1.7/tests/test_assert_macros.c @@ -0,0 +1,41 @@ +#include "config.h" + +#include +#include +#include +#include +#include + +#include +#include +#include +#ifdef HAVE_UNISTD_H +#include +#endif +#include + +/************************************** + *** assert_return_code + **************************************/ +static void test_assert_return_code(void **state) +{ + struct stat sb = {0}; + int rc; + + (void)state; /* unused */ + + rc = stat(".", &sb); + assert_return_code(rc, 0); + +#ifndef _MSC_VER + assert_true(S_ISDIR(sb.st_mode)); +#endif +} + +int main(void) { + const struct CMUnitTest tests[] = { + cmocka_unit_test(test_assert_return_code), + }; + + return cmocka_run_group_tests(tests, NULL, NULL); +} diff --git a/cmake/cmocka-1.1.7/tests/test_assert_macros_fail.c b/cmake/cmocka-1.1.7/tests/test_assert_macros_fail.c new file mode 100644 index 0000000..aea919a --- /dev/null +++ b/cmake/cmocka-1.1.7/tests/test_assert_macros_fail.c @@ -0,0 +1,43 @@ +#include "config.h" + +#include +#include +#include +#include +#include + +#include +#include +#include +#ifdef HAVE_UNISTD_H +#include +#endif +#ifdef HAVE_IO_H +#include +#endif +#include + +/************************************** + *** assert_return_code + **************************************/ +static void test_assert_return_code_fail(void **state) +{ + int fd; + + (void)state; /* unused */ + + fd = open("this_file_doesnt_exist.cmocka", 0); + assert_return_code(fd, errno); + + if (fd >= 0) { + close(fd); + } +} + +int main(void) { + const struct CMUnitTest tests[] = { + cmocka_unit_test(test_assert_return_code_fail), + }; + + return cmocka_run_group_tests(tests, NULL, NULL); +} diff --git a/cmake/cmocka-1.1.7/tests/test_basics.c b/cmake/cmocka-1.1.7/tests/test_basics.c new file mode 100644 index 0000000..1bb493f --- /dev/null +++ b/cmake/cmocka-1.1.7/tests/test_basics.c @@ -0,0 +1,62 @@ +/* + * Copyright 2008 Google Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* Use the unit test allocators */ +#define UNIT_TESTING 1 + +#include +#include +#include +#include + +static int setup(void **state) { + int *answer = malloc(sizeof(int)); + + assert_non_null(answer); + *answer = 42; + + *state = answer; + + return 0; +} + +static int teardown(void **state) { + free(*state); + + return 0; +} + +/* A test case that does nothing and succeeds. */ +static void null_test_success(void **state) { + (void) state; +} + +/* A test case that does check if an int is equal. */ +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); +} diff --git a/cmake/cmocka-1.1.7/tests/test_cmockery.c b/cmake/cmocka-1.1.7/tests/test_cmockery.c new file mode 100644 index 0000000..83a7451 --- /dev/null +++ b/cmake/cmocka-1.1.7/tests/test_cmockery.c @@ -0,0 +1,32 @@ +/* + * Copyright 2008 Google Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include +#include +#include + +/* A test case that does nothing and succeeds. */ +static void null_test_success(void **state) { + (void) state; /* unused */ +} + +int main(void) { + const UnitTest tests[] = { + unit_test(null_test_success), + }; + return run_tests(tests); +} diff --git a/cmake/cmocka-1.1.7/tests/test_double_macros.c b/cmake/cmocka-1.1.7/tests/test_double_macros.c new file mode 100644 index 0000000..138c579 --- /dev/null +++ b/cmake/cmocka-1.1.7/tests/test_double_macros.c @@ -0,0 +1,40 @@ +/* + * Copyright 2019 Arnaud Gelas + * + * 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. + */ + +/* Use the unit test allocators */ +#define UNIT_TESTING 1 + +#include +#include +#include +#include + +/* A test case that does check if double is equal. */ +static void double_test_success(void **state) +{ + (void)state; /* unused */ + + assert_double_equal(0.5, 1. / 2., 0.000001); + assert_double_not_equal(0.5, 0.499, 0.000001); +} + +int main(void) { + const struct CMUnitTest tests[] = { + cmocka_unit_test(double_test_success), + }; + + return cmocka_run_group_tests(tests, NULL, NULL); +} diff --git a/cmake/cmocka-1.1.7/tests/test_exception_handler.c b/cmake/cmocka-1.1.7/tests/test_exception_handler.c new file mode 100644 index 0000000..23c19cd --- /dev/null +++ b/cmake/cmocka-1.1.7/tests/test_exception_handler.c @@ -0,0 +1,39 @@ +#include +#include +#include +#include + +#include + +static void test_segfault_recovery(void **state) +{ + (void)state; /* unused */ + + /* Raise segmentation fault */ + raise(SIGSEGV); +} + +static void test_segfault_recovery1(void **state) +{ + test_segfault_recovery(state); +} + +static void test_segfault_recovery2(void **state) +{ + test_segfault_recovery(state); +} + +static void test_segfault_recovery3(void **state) +{ + test_segfault_recovery(state); +} + +int main(void) { + const struct CMUnitTest exception_tests[] = { + cmocka_unit_test(test_segfault_recovery1), + cmocka_unit_test(test_segfault_recovery2), + cmocka_unit_test(test_segfault_recovery3), + }; + + return cmocka_run_group_tests(exception_tests, NULL, NULL); +} diff --git a/cmake/cmocka-1.1.7/tests/test_fixtures.c b/cmake/cmocka-1.1.7/tests/test_fixtures.c new file mode 100644 index 0000000..6d39487 --- /dev/null +++ b/cmake/cmocka-1.1.7/tests/test_fixtures.c @@ -0,0 +1,82 @@ +#include +#include +#include +#include + +#include + +static int setup_only(void **state) +{ + *state = malloc(1); + + return 0; +} + +static int teardown_only(void **state) +{ + free(*state); + + return 0; +} + +static void malloc_setup_test(void **state) +{ + assert_non_null(*state); + free(*state); +} + +static void malloc_teardown_test(void **state) +{ + *state = malloc(1); + assert_non_null(*state); +} + +static int prestate_setup(void **state) +{ + int *val = (int *)*state, *a; + + a = malloc(sizeof(int)); + *a = *val + 1; + *state = a; + + return 0; +} + +static int prestate_teardown(void **state) +{ + free(*state); + + return 0; +} + +static void prestate_setup_test(void **state) +{ + int *a = (int *)*state; + + assert_non_null(a); + assert_int_equal(*a, 43); +} + +static void prestate_test(void **state) +{ + int *a = (int *)*state; + + assert_non_null(a); + assert_int_equal(*a, 42); +} + +int main(void) { + int prestate = 42; + const struct CMUnitTest tests[] = { + cmocka_unit_test_setup(malloc_setup_test, setup_only), + cmocka_unit_test_setup(malloc_setup_test, setup_only), + cmocka_unit_test_teardown(malloc_teardown_test, teardown_only), + cmocka_unit_test_teardown(malloc_teardown_test, teardown_only), + cmocka_unit_test_teardown(malloc_teardown_test, teardown_only), + cmocka_unit_test_teardown(malloc_teardown_test, teardown_only), + cmocka_unit_test_prestate(prestate_test, &prestate), + cmocka_unit_test_prestate_setup_teardown(prestate_setup_test, prestate_setup, prestate_teardown, &prestate), + }; + + return cmocka_run_group_tests(tests, NULL, NULL); +} diff --git a/cmake/cmocka-1.1.7/tests/test_float_macros.c b/cmake/cmocka-1.1.7/tests/test_float_macros.c new file mode 100644 index 0000000..a9c7251 --- /dev/null +++ b/cmake/cmocka-1.1.7/tests/test_float_macros.c @@ -0,0 +1,40 @@ +/* + * Copyright 2019 Arnaud Gelas + * + * 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. + */ + +/* Use the unit test allocators */ +#define UNIT_TESTING 1 + +#include +#include +#include +#include + +/* A test case that does check if float is equal. */ +static void float_test_success(void **state) +{ + (void)state; /* unused */ + + assert_float_equal(0.5f, 1.f / 2.f, 0.000001f); + assert_float_not_equal(0.5, 0.499f, 0.000001f); +} + +int main(void) { + const struct CMUnitTest tests[] = { + cmocka_unit_test(float_test_success), + }; + + return cmocka_run_group_tests(tests, NULL, NULL); +} diff --git a/cmake/cmocka-1.1.7/tests/test_group_fixtures.c b/cmake/cmocka-1.1.7/tests/test_group_fixtures.c new file mode 100644 index 0000000..64f0ab7 --- /dev/null +++ b/cmake/cmocka-1.1.7/tests/test_group_fixtures.c @@ -0,0 +1,50 @@ +/* Use the unit test allocators */ +#define UNIT_TESTING 1 + +#include +#include +#include +#include + +static int group_setup(void **state) +{ + int *answer = malloc(sizeof(int)); + assert_non_null(answer); + *answer = 42; + + *state = answer; + return 0; +} + +static int group_teardown(void **state) +{ + int *answer = (int *)*state; + + free(answer); + return 0; +} + +static void test_value_equal(void **state) +{ + int a = *((int *)*state); + + assert_int_equal(a, 42); +} + +static void test_value_range(void **state) +{ + int a = *((int *)*state); + + assert_in_range(a, 0, 100); +} + +int main(void) { + int prestate = 1337; + const struct CMUnitTest tests[] = { + cmocka_unit_test(test_value_equal), + cmocka_unit_test(test_value_range), + cmocka_unit_test_prestate(test_value_equal, &prestate), + }; + + return cmocka_run_group_tests(tests, group_setup, group_teardown); +} diff --git a/cmake/cmocka-1.1.7/tests/test_group_setup_assert.c b/cmake/cmocka-1.1.7/tests/test_group_setup_assert.c new file mode 100644 index 0000000..eef61f8 --- /dev/null +++ b/cmake/cmocka-1.1.7/tests/test_group_setup_assert.c @@ -0,0 +1,37 @@ +/* Use the unit test allocators */ +#define UNIT_TESTING 1 + +#include +#include +#include +#include + +static int group_setup_failing(void **state) +{ + (void) state; /* unused */ + + assert_int_equal(0, 1); + + return 0; +} + +static void test_true(void **state) +{ + (void) state; /* unused */ + assert_true(1); +} + +static void test_false(void **state) +{ + (void) state; /* unused */ + assert_false(0); +} + +int main(void) { + const struct CMUnitTest tests[] = { + cmocka_unit_test(test_true), + cmocka_unit_test(test_false), + }; + + return cmocka_run_group_tests(tests, group_setup_failing, NULL); +} diff --git a/cmake/cmocka-1.1.7/tests/test_group_setup_fail.c b/cmake/cmocka-1.1.7/tests/test_group_setup_fail.c new file mode 100644 index 0000000..7815c03 --- /dev/null +++ b/cmake/cmocka-1.1.7/tests/test_group_setup_fail.c @@ -0,0 +1,34 @@ +/* Use the unit test allocators */ +#define UNIT_TESTING 1 + +#include +#include +#include +#include + +static int group_setup_failing(void **state) +{ + (void) state; /* unused */ + return 1; /* To indicate the failure */ +} + +static void test_true(void **state) +{ + (void) state; /* unused */ + assert_true(1); +} + +static void test_false(void **state) +{ + (void) state; /* unused */ + assert_false(0); +} + +int main(void) { + const struct CMUnitTest tests[] = { + cmocka_unit_test(test_true), + cmocka_unit_test(test_false), + }; + + return cmocka_run_group_tests(tests, group_setup_failing, NULL); +} diff --git a/cmake/cmocka-1.1.7/tests/test_groups.c b/cmake/cmocka-1.1.7/tests/test_groups.c new file mode 100644 index 0000000..af9e2b8 --- /dev/null +++ b/cmake/cmocka-1.1.7/tests/test_groups.c @@ -0,0 +1,69 @@ +/* + * Copyright 2016 David 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. + */ + +/* Use the unit test allocators */ +#define UNIT_TESTING 1 + +#include +#include +#include +#include + +static int setup(void **state) { + int *answer = malloc(sizeof(int)); + + assert_non_null(answer); + *answer = 42; + + *state = answer; + + return 0; +} + +static int teardown(void **state) { + free(*state); + + return 0; +} + +/* A test case that does nothing and succeeds. */ +static void null_test_success(void **state) { + (void) state; +} + +/* A test case that does check if an int is equal. */ +static void int_test_success(void **state) { + int *answer = *state; + + assert_int_equal(*answer, 42); +} + + +int main(void) { + const struct CMUnitTest test_group1[] = { + cmocka_unit_test(null_test_success), + }; + + const struct CMUnitTest test_group2[] = { + cmocka_unit_test_setup_teardown(int_test_success, setup, teardown), + }; + + int result = 0; + result += cmocka_run_group_tests(test_group1, NULL, NULL); + result += cmocka_run_group_tests(test_group2, NULL, NULL); + + return result; +} diff --git a/cmake/cmocka-1.1.7/tests/test_ordering.c b/cmake/cmocka-1.1.7/tests/test_ordering.c new file mode 100644 index 0000000..817c0ba --- /dev/null +++ b/cmake/cmocka-1.1.7/tests/test_ordering.c @@ -0,0 +1,112 @@ +#include "config.h" + +#include +#include +#include +#include +#include + +static void mock_test_a_called(void) +{ + function_called(); +} + +static void mock_test_b_called(void) +{ + function_called(); +} + +static void mock_test_c_called(void) +{ + function_called(); +} + + +static void test_does_succeed_for_expected(void **state) +{ + (void)state; + expect_function_call(mock_test_a_called); + expect_function_call(mock_test_a_called); + + mock_test_a_called(); + mock_test_a_called(); +} + +static void test_does_succeed_for_multiple_calls(void **state) +{ + (void)state; + expect_function_call(mock_test_a_called); + expect_function_calls(mock_test_a_called, 2); + expect_function_call(mock_test_a_called); + + mock_test_a_called(); + mock_test_a_called(); + mock_test_a_called(); + mock_test_a_called(); +} + +static void test_ordering_does_ignore_calls(void **state) +{ + (void)state; + + ignore_function_calls(mock_test_a_called); + + mock_test_a_called(); + mock_test_a_called(); + mock_test_a_called(); +} + +static void test_ordering_does_ignore_no_calls(void **state) +{ + (void)state; + ignore_function_calls(mock_test_a_called); +} + +static void test_ordering_does_expect_at_least_one_call(void **state) +{ + (void)state; + expect_function_call_any(mock_test_a_called); + + mock_test_a_called(); + mock_test_a_called(); + mock_test_a_called(); +} + +static void test_ordering_does_work_across_different_functions(void **state) +{ + (void)state; + expect_function_call(mock_test_a_called); + expect_function_call(mock_test_b_called); + expect_function_call(mock_test_a_called); + + mock_test_a_called(); + mock_test_b_called(); + mock_test_a_called(); +} + +static void test_ordering_ignores_out_of_order_properly(void **state) +{ + (void)state; + ignore_function_calls(mock_test_a_called); + ignore_function_calls(mock_test_b_called); + expect_function_calls(mock_test_c_called, 2); + + + mock_test_c_called(); + mock_test_b_called(); + mock_test_c_called(); +} + +int main(void) { + const struct CMUnitTest tests[] = { + cmocka_unit_test(test_does_succeed_for_expected) + ,cmocka_unit_test(test_does_succeed_for_multiple_calls) + ,cmocka_unit_test(test_ordering_does_ignore_no_calls) + ,cmocka_unit_test(test_ordering_does_ignore_calls) + ,cmocka_unit_test(test_ordering_does_expect_at_least_one_call) + ,cmocka_unit_test(test_ordering_does_work_across_different_functions) + ,cmocka_unit_test(test_ordering_ignores_out_of_order_properly) + }; + + return cmocka_run_group_tests(tests, NULL, NULL); +} diff --git a/cmake/cmocka-1.1.7/tests/test_ordering_fail.c b/cmake/cmocka-1.1.7/tests/test_ordering_fail.c new file mode 100644 index 0000000..652f5ad --- /dev/null +++ b/cmake/cmocka-1.1.7/tests/test_ordering_fail.c @@ -0,0 +1,95 @@ +#include "config.h" + +#include +#include +#include +#include +#include + +static void mock_test_a_called(void) +{ + function_called(); +} + +static void mock_test_b_called(void) +{ + function_called(); +} + +static void mock_test_c_called(void) +{ + function_called(); +} + +static void test_does_fail_for_unexpected_call(void **state) +{ + (void)state; + expect_function_call(mock_test_a_called); + expect_function_call(mock_test_a_called); + + mock_test_a_called(); + mock_test_a_called(); + mock_test_a_called(); +} + +static void test_does_fail_for_unmade_expected_call(void **state) +{ + (void)state; + expect_function_call(mock_test_a_called); + expect_function_call(mock_test_a_called); + + mock_test_a_called(); +} + +static void test_ordering_fails_out_of_order(void **state) +{ + (void)state; + expect_function_call(mock_test_a_called); + expect_function_call(mock_test_b_called); + expect_function_call(mock_test_a_called); + + mock_test_b_called(); +} + +static void test_ordering_fails_out_of_order_for_at_least_once_calls(void **state) +{ + (void)state; + expect_function_call_any(mock_test_a_called); + ignore_function_calls(mock_test_b_called); + + mock_test_b_called(); + mock_test_c_called(); +} + +/* Primarily used to test error message */ +static void test_fails_out_of_order_if_no_calls_found_on_any(void **state) +{ + (void)state; + expect_function_call_any(mock_test_a_called); + ignore_function_calls(mock_test_b_called); + + mock_test_a_called(); + mock_test_c_called(); +} + +static void test_fails_if_zero_count_used(void **state) +{ + (void)state; + expect_function_calls(mock_test_a_called, 0); + + mock_test_a_called(); +} + +int main(void) { + const struct CMUnitTest tests[] = { + cmocka_unit_test(test_does_fail_for_unexpected_call) + ,cmocka_unit_test(test_does_fail_for_unmade_expected_call) + ,cmocka_unit_test(test_does_fail_for_unmade_expected_call) + ,cmocka_unit_test(test_ordering_fails_out_of_order) + ,cmocka_unit_test(test_ordering_fails_out_of_order_for_at_least_once_calls) + ,cmocka_unit_test(test_fails_out_of_order_if_no_calls_found_on_any) + ,cmocka_unit_test(test_fails_if_zero_count_used) + }; + + return cmocka_run_group_tests(tests, NULL, NULL); +} diff --git a/cmake/cmocka-1.1.7/tests/test_returns.c b/cmake/cmocka-1.1.7/tests/test_returns.c new file mode 100644 index 0000000..b9370c9 --- /dev/null +++ b/cmake/cmocka-1.1.7/tests/test_returns.c @@ -0,0 +1,69 @@ +#include "config.h" + +#include +#include +#include +#include +#include + +#include + +int mock_function(void); +void mock_function_call_times(size_t times, int expectedValue); + +int mock_function(void) +{ + return (int) mock(); +} + +void mock_function_call_times(size_t times, int expectedValue) +{ + size_t i; + for (i = 0u; i < times; ++i) + { + assert_int_equal(expectedValue, mock_function()); + } +} + +static void test_will_return_maybe_for_no_calls(void **state) +{ + (void) state; + + will_return_maybe(mock_function, 32); +} + +static void test_will_return_maybe_for_one_mock_call(void **state) +{ + int value; + + (void) state; + + value = rand(); + will_return_maybe(mock_function, value); + mock_function_call_times(1u, value); +} + +static void test_will_return_maybe_for_more_than_one_call(void **state) +{ + int value; + size_t numberOfCalls; + (void)state; + + value = rand(); + numberOfCalls = (size_t) ((rand()) % 20 + 2); + will_return_maybe(mock_function, value); + mock_function_call_times(numberOfCalls, value); +} + +int main(int argc, char **argv) { + const struct CMUnitTest alloc_tests[] = { + cmocka_unit_test(test_will_return_maybe_for_no_calls) + ,cmocka_unit_test(test_will_return_maybe_for_one_mock_call) + ,cmocka_unit_test(test_will_return_maybe_for_more_than_one_call) + }; + + (void)argc; + (void)argv; + + return cmocka_run_group_tests(alloc_tests, NULL, NULL); +} diff --git a/cmake/cmocka-1.1.7/tests/test_returns_fail.c b/cmake/cmocka-1.1.7/tests/test_returns_fail.c new file mode 100644 index 0000000..81197d3 --- /dev/null +++ b/cmake/cmocka-1.1.7/tests/test_returns_fail.c @@ -0,0 +1,77 @@ +#include "config.h" + +#include +#include +#include +#include +#include + +#include + +int mock_function(void); +void mock_function_call_times(size_t times, int expectedValue); + +int mock_function(void) +{ + return (int) mock(); +} + +void mock_function_call_times(size_t times, int expectedValue) +{ + size_t i; + for (i = 0u; i < times; ++i) + { + assert_int_equal(expectedValue, mock_function()); + } +} + +static void test_will_return_fails_for_no_calls(void **state) +{ + (void) state; + + will_return(mock_function, 32); +} + +static void test_will_return_count_fails_for_unreturned_items(void **state) +{ + int value; + size_t numberOfCalls; + + (void) state; + + value = rand(); + numberOfCalls = (size_t) ((rand()) % 20 + 2); + + will_return_count(mock_function, value, numberOfCalls); + mock_function_call_times(numberOfCalls - 1u, value); +} + +static void test_will_return_always_fails_for_no_calls(void **state) +{ + int value; + + (void) state; + + value = rand(); + + will_return_always(mock_function, value); +} + +static int teardown(void **state) { + free(*state); + + return 0; +} + +int main(int argc, char **argv) { + const struct CMUnitTest alloc_tests[] = { + cmocka_unit_test_teardown(test_will_return_fails_for_no_calls, teardown) + ,cmocka_unit_test_teardown(test_will_return_count_fails_for_unreturned_items, teardown) + ,cmocka_unit_test_teardown(test_will_return_always_fails_for_no_calls, teardown) + }; + + (void)argc; + (void)argv; + + return cmocka_run_group_tests(alloc_tests, NULL, NULL); +} diff --git a/cmake/cmocka-1.1.7/tests/test_setup_fail.c b/cmake/cmocka-1.1.7/tests/test_setup_fail.c new file mode 100644 index 0000000..e3f8df8 --- /dev/null +++ b/cmake/cmocka-1.1.7/tests/test_setup_fail.c @@ -0,0 +1,54 @@ +#define UNIT_TESTING 1 + +#include +#include +#include +#include + +static int setup_fail(void **state) { + *state = NULL; + + /* We need to fail in setup */ + return -1; +} + +static void int_test_ignored(void **state) { + /* should not be called */ + assert_non_null(*state); +} + +static int setup_ok(void **state) { + int *answer; + + answer = malloc(sizeof(int)); + if (answer == NULL) { + return -1; + } + *answer = 42; + + *state = answer; + + return 0; +} + +/* A test case that does check if an int is equal. */ +static void int_test_success(void **state) { + int *answer = *state; + + assert_int_equal(*answer, 42); +} + +static int teardown(void **state) { + free(*state); + + return 0; +} + +int main(void) { + const struct CMUnitTest tests[] = { + cmocka_unit_test_setup_teardown(int_test_ignored, setup_fail, teardown), + cmocka_unit_test_setup_teardown(int_test_success, setup_ok, teardown), + }; + + return cmocka_run_group_tests(tests, NULL, NULL); +} diff --git a/cmake/cmocka-1.1.7/tests/test_skip.c b/cmake/cmocka-1.1.7/tests/test_skip.c new file mode 100644 index 0000000..127161a --- /dev/null +++ b/cmake/cmocka-1.1.7/tests/test_skip.c @@ -0,0 +1,39 @@ +/* + * Copyright 2008 Google Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include +#include +#include + +/* A test case that does check if an int is equal. */ +static void test_check_skip(void **state) { + (void)state; /* unused */ + + skip(); + + assert_true(0); +} + + +int main(void) { + const struct CMUnitTest tests[] = { + cmocka_unit_test(test_check_skip), + }; + + return cmocka_run_group_tests(tests, NULL, NULL); +} + diff --git a/cmake/cmocka-1.1.7/tests/test_skip_filter.c b/cmake/cmocka-1.1.7/tests/test_skip_filter.c new file mode 100644 index 0000000..e40209e --- /dev/null +++ b/cmake/cmocka-1.1.7/tests/test_skip_filter.c @@ -0,0 +1,57 @@ +/* + * Copyright (c) 2019 by Red Hat, Inc. + * + * Author: Anderson Toshiyuki Sasaki + * + * 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. + */ + +#include +#include +#include +#include + +static void test_skip1(void **state) +{ + (void)state; + + assert_true(1); +} + +static void test_skip2(void **state) +{ + (void)state; + + assert_false(1); +} + +static void test_fail(void **state) +{ + (void)state; + + assert_false(1); +} + +int main(void) { + const struct CMUnitTest tests[] = { + cmocka_unit_test(test_skip1), + cmocka_unit_test(test_skip2), + cmocka_unit_test(test_fail), + }; + + cmocka_set_test_filter("test_skip*"); + + cmocka_set_skip_filter("test_skip2"); + + return cmocka_run_group_tests(tests, NULL, NULL); +} diff --git a/cmake/cmocka-1.1.7/tests/test_string.c b/cmake/cmocka-1.1.7/tests/test_string.c new file mode 100644 index 0000000..f1c9b7a --- /dev/null +++ b/cmake/cmocka-1.1.7/tests/test_string.c @@ -0,0 +1,40 @@ +/* + * Copyright 2020 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. + */ + +#include +#include +#include +#include +#include + +static void torture_string_equal(void **state) +{ + assert_string_equal("wurst", "wurst"); +} + +static void torture_string_not_equal(void **state) +{ + assert_string_not_equal("wurst", "brot"); +} + +int main(void) { + const struct CMUnitTest tests[] = { + cmocka_unit_test(torture_string_equal), + cmocka_unit_test(torture_string_not_equal), + }; + + return cmocka_run_group_tests(tests, NULL, NULL); +} diff --git a/cmake/cmocka-1.1.7/tests/test_strmatch.c b/cmake/cmocka-1.1.7/tests/test_strmatch.c new file mode 100644 index 0000000..f2d966b --- /dev/null +++ b/cmake/cmocka-1.1.7/tests/test_strmatch.c @@ -0,0 +1,99 @@ +/* + * Copyright 2018 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. + */ + +#include "config.h" + +#include +#include +#include +#include + +#include "../src/cmocka.c" + +static void test_strmatch_null(void **state) +{ + int rc; + + (void)state; + + rc = c_strmatch(NULL, NULL); + assert_int_equal(rc, 0); + + rc = c_strmatch("", NULL); + assert_int_equal(rc, 0); + + rc = c_strmatch(NULL, ""); + assert_int_equal(rc, 0); +} + +static void test_strmatch_empty(void **state) +{ + int rc; + + (void)state; + + rc = c_strmatch("", ""); + assert_int_equal(rc, 1); + + rc = c_strmatch("wurst", ""); + assert_int_equal(rc, 0); + + rc = c_strmatch("", "wurst"); + assert_int_equal(rc, 0); +} + +static void test_strmatch_single(void **state) +{ + int rc; + + (void)state; + + rc = c_strmatch("wurst", "wurs?"); + assert_int_equal(rc, 1); + + rc = c_strmatch("wurst", "w?rs?"); + assert_int_equal(rc, 1); + + rc = c_strmatch("wurst", "wur?"); + assert_int_equal(rc, 0); +} + +static void test_strmatch_wildcard(void **state) +{ + int rc; + + (void)state; + + rc = c_strmatch("wurst", "wurst*"); + assert_int_equal(rc, 1); + + rc = c_strmatch("wurstbrot", "wurst*"); + assert_int_equal(rc, 1); + + rc = c_strmatch("wurstbrot", "w*t"); + assert_int_equal(rc, 1); +} + +int main(void) { + const struct CMUnitTest tests[] = { + cmocka_unit_test(test_strmatch_null), + cmocka_unit_test(test_strmatch_empty), + cmocka_unit_test(test_strmatch_single), + cmocka_unit_test(test_strmatch_wildcard), + }; + + return cmocka_run_group_tests(tests, NULL, NULL); +} diff --git a/cmake/cmocka-1.1.7/tests/test_wildcard.c b/cmake/cmocka-1.1.7/tests/test_wildcard.c new file mode 100644 index 0000000..10ee195 --- /dev/null +++ b/cmake/cmocka-1.1.7/tests/test_wildcard.c @@ -0,0 +1,53 @@ +/* + * Copyright 2018 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. + */ + +#include +#include +#include +#include + +static void test_ok1(void **state) +{ + (void)state; + + assert_true(1); +} + +static void test_ok2(void **state) +{ + (void)state; + + assert_true(1); +} + +static void test_fail(void **state) +{ + (void)state; + + assert_false(1); +} + +int main(void) { + const struct CMUnitTest tests[] = { + cmocka_unit_test(test_ok1), + cmocka_unit_test(test_ok2), + cmocka_unit_test(test_fail), + }; + + cmocka_set_test_filter("test_ok*"); + + return cmocka_run_group_tests(tests, NULL, NULL); +}