commit bcd12b6b429c57a93bee3881ce2725e9e7578a51
Author: Henry Case
Date: Sat May 25 00:39:46 2019 +0100
Merges multiple repositories into one
diff --git a/emCmocka/.clang_complete b/emCmocka/.clang_complete
new file mode 100644
index 0000000..6177904
--- /dev/null
+++ b/emCmocka/.clang_complete
@@ -0,0 +1,2 @@
+-Iinclude
+-Iobj
diff --git a/emCmocka/.gitignore b/emCmocka/.gitignore
new file mode 100644
index 0000000..3944fce
--- /dev/null
+++ b/emCmocka/.gitignore
@@ -0,0 +1,7 @@
+*.swp
+*~$
+tags
+cscope.*
+.ycm_extra_conf.pyc
+/build
+/obj*
diff --git a/emCmocka/.ycm_extra_conf.py b/emCmocka/.ycm_extra_conf.py
new file mode 100644
index 0000000..8305a8b
--- /dev/null
+++ b/emCmocka/.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/emCmocka/AUTHORS b/emCmocka/AUTHORS
new file mode 100644
index 0000000..1fe0d34
--- /dev/null
+++ b/emCmocka/AUTHORS
@@ -0,0 +1,3 @@
+opensource@google.com
+Andreas Schneider
+Jakub Hrozek
diff --git a/emCmocka/CMakeLists.txt b/emCmocka/CMakeLists.txt
new file mode 100644
index 0000000..39b9ec8
--- /dev/null
+++ b/emCmocka/CMakeLists.txt
@@ -0,0 +1,88 @@
+project(cmocka C)
+
+# Required cmake version
+cmake_minimum_required(VERSION 2.6.0)
+
+# global needed variables
+set(APPLICATION_NAME ${PROJECT_NAME})
+
+set(APPLICATION_VERSION_MAJOR "1")
+set(APPLICATION_VERSION_MINOR "1")
+set(APPLICATION_VERSION_PATCH "1")
+
+set(APPLICATION_VERSION "${APPLICATION_VERSION_MAJOR}.${APPLICATION_VERSION_MINOR}.${APPLICATION_VERSION_PATCH}")
+
+# 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.4.1")
+set(LIBRARY_SOVERSION "0")
+
+# where to look first for cmake modules, before ${CMAKE_ROOT}/Modules/ is checked
+set(CMAKE_MODULE_PATH
+ ${CMAKE_CURRENT_SOURCE_DIR}/cmake/Modules
+)
+
+# add definitions
+include(DefineCMakeDefaults)
+include(DefinePlatformDefaults)
+include(DefineCompilerFlags)
+include(DefineInstallationPaths)
+include(DefineOptions.cmake)
+include(CPackConfig.cmake)
+include(CheckSymbolExists)
+
+# 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(doc)
+add_subdirectory(include)
+add_subdirectory(src)
+
+if (UNIT_TESTING)
+ include(AddCMockaTest)
+ add_subdirectory(tests)
+endif (UNIT_TESTING)
+
+add_subdirectory(example)
+
+# pkg-config file
+configure_file(cmocka.pc.cmake ${CMAKE_CURRENT_BINARY_DIR}/cmocka.pc)
+install(
+ FILES
+ ${CMAKE_CURRENT_BINARY_DIR}/cmocka.pc
+ DESTINATION
+ ${LIB_INSTALL_DIR}/pkgconfig
+ COMPONENT
+ pkgconfig
+)
+
+# cmake config files
+set(CMOCKA_LIBRARY_NAME ${CMAKE_SHARED_LIBRARY_PREFIX}${PROJECT_NAME}${CMAKE_SHARED_LIBRARY_SUFFIX})
+
+configure_file(${PROJECT_NAME}-config.cmake.in ${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}-config.cmake @ONLY)
+configure_file(${PROJECT_NAME}-config-version.cmake.in ${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}-config-version.cmake @ONLY)
+install(
+ FILES
+ ${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}-config.cmake
+ ${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}-config-version.cmake
+ DESTINATION
+ ${CMAKE_INSTALL_DIR}/${PROJECT_NAME}
+ COMPONENT
+ devel
+)
diff --git a/emCmocka/COPYING b/emCmocka/COPYING
new file mode 100644
index 0000000..d645695
--- /dev/null
+++ b/emCmocka/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/emCmocka/CPackConfig.cmake b/emCmocka/CPackConfig.cmake
new file mode 100644
index 0000000..a110c97
--- /dev/null
+++ b/emCmocka/CPackConfig.cmake
@@ -0,0 +1,53 @@
+# For help take a look at:
+# http://www.cmake.org/Wiki/CMake:CPackConfiguration
+
+### general settings
+set(CPACK_PACKAGE_NAME ${APPLICATION_NAME})
+set(CPACK_PACKAGE_DESCRIPTION_SUMMARY "Unit testing framework for C with mock objects")
+set(CPACK_PACKAGE_DESCRIPTION_FILE "${CMAKE_CURRENT_SOURCE_DIR}/README")
+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_MAJOR "${APPLICATION_VERSION_MAJOR}")
+set(CPACK_PACKAGE_VERSION_MINOR "${APPLICATION_VERSION_MINOR}")
+set(CPACK_PACKAGE_VERSION_PATCH "${APPLICATION_VERSION_PATCH}")
+set(CPACK_PACKAGE_VERSION "${CPACK_PACKAGE_VERSION_MAJOR}.${CPACK_PACKAGE_VERSION_MINOR}.${CPACK_PACKAGE_VERSION_PATCH}")
+
+
+### source generator
+set(CPACK_SOURCE_GENERATOR "TGZ")
+set(CPACK_SOURCE_IGNORE_FILES "~$;[.]swp$;/[.]svn/;/[.]git/;.gitignore;/obj*;tags;cscope.*;.ycm_extra_conf.pyc")
+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 ${APPLICATION_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/emCmocka/CTestConfig.cmake b/emCmocka/CTestConfig.cmake
new file mode 100644
index 0000000..f93a981
--- /dev/null
+++ b/emCmocka/CTestConfig.cmake
@@ -0,0 +1,10 @@
+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 "mock.cryptomilk.org")
+set(CTEST_DROP_LOCATION "/submit.php?project=${CTEST_PROJECT_NAME}")
+set(CTEST_DROP_SITE_CDASH TRUE)
+
diff --git a/emCmocka/ChangeLog b/emCmocka/ChangeLog
new file mode 100644
index 0000000..aa5835a
--- /dev/null
+++ b/emCmocka/ChangeLog
@@ -0,0 +1,98 @@
+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/emCmocka/ConfigureChecks.cmake b/emCmocka/ConfigureChecks.cmake
new file mode 100644
index 0000000..9bdc6f8
--- /dev/null
+++ b/emCmocka/ConfigureChecks.cmake
@@ -0,0 +1,149 @@
+include(CheckIncludeFile)
+include(CheckSymbolExists)
+include(CheckFunctionExists)
+include(CheckLibraryExists)
+include(CheckTypeSize)
+include(CheckCXXSourceCompiles)
+include(CheckStructHasMember)
+include(TestBigEndian)
+
+set(PACKAGE ${APPLICATION_NAME})
+set(VERSION ${APPLICATION_VERSION})
+set(DATADIR ${DATA_INSTALL_DIR})
+set(LIBDIR ${LIB_INSTALL_DIR})
+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)
+
+# 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)
+ 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/emCmocka/DefineOptions.cmake b/emCmocka/DefineOptions.cmake
new file mode 100644
index 0000000..7564a22
--- /dev/null
+++ b/emCmocka/DefineOptions.cmake
@@ -0,0 +1,7 @@
+option(WITH_STATIC_LIB "Build with a static library" OFF)
+option(WITH_CMOCKERY_SUPPORT "Install a cmockery header" OFF)
+option(UNIT_TESTING "Build with unit testing" OFF)
+
+if (UNIT_TESTING)
+ set(WITH_STATIC_LIB ON)
+endif()
diff --git a/emCmocka/INSTALL b/emCmocka/INSTALL
new file mode 100644
index 0000000..8b438d5
--- /dev/null
+++ b/emCmocka/INSTALL
@@ -0,0 +1,102 @@
+# How to build from source
+
+## Requirements
+
+### Common requirements
+
+In order to build cmocka, you need to install several components:
+
+- A C compiler
+- [CMake](http://www.cmake.org) >= 2.8.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.
+
+### 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 `cmakesetup` (Windows), `cmake-gui` or `ccmake` (GNU/Linux
+and MacOS X).
+
+- Go to the build dir
+- On Windows: run `cmakesetup`
+- On GNU/Linux and MacOS X: run `ccmake ..`
+
+## 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 exsample 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/emCmocka/NEWS b/emCmocka/NEWS
new file mode 100644
index 0000000..e69de29
diff --git a/emCmocka/README b/emCmocka/README
new file mode 100644
index 0000000..b432e8e
--- /dev/null
+++ b/emCmocka/README
@@ -0,0 +1,15 @@
+CMOCKA
+=======
+
+cmocka is a fork for Google's cmockery unit testing framework to fix bugs and
+support it in future.
+See https://code.google.com/p/cmockery/
+
+For information about how to use the cmocka unit testing framework see
+doc/index.html.
+
+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 file.
diff --git a/emCmocka/cmake/Modules/AddCMockaTest.cmake b/emCmocka/cmake/Modules/AddCMockaTest.cmake
new file mode 100644
index 0000000..19de66e
--- /dev/null
+++ b/emCmocka/cmake/Modules/AddCMockaTest.cmake
@@ -0,0 +1,23 @@
+# - ADD_CMOCKA_TEST(test_name test_source linklib1 ... linklibN)
+
+# Copyright (c) 2007 Daniel Gollub
+# Copyright (c) 2007-2010 Andreas Schneider
+#
+# Redistribution and use is allowed according to the terms of the BSD license.
+# For details see the accompanying COPYING-CMAKE-SCRIPTS file.
+
+enable_testing()
+include(CTest)
+
+if(CMAKE_COMPILER_IS_GNUCC AND NOT MINGW)
+ set(CMAKE_C_FLAGS_PROFILING "-g -O0 -Wall -W -Wshadow -Wunused-variable -Wunused-parameter -Wunused-function -Wunused -Wno-system-headers -Wwrite-strings -fprofile-arcs -ftest-coverage" CACHE STRING "Profiling Compiler Flags")
+ set(CMAKE_SHARED_LINKER_FLAGS_PROFILING " -fprofile-arcs -ftest-coverage" CACHE STRING "Profiling Linker Flags")
+ set(CMAKE_MODULE_LINKER_FLAGS_PROFILING " -fprofile-arcs -ftest-coverage" CACHE STRING "Profiling Linker Flags")
+ set(CMAKE_EXEC_LINKER_FLAGS_PROFILING " -fprofile-arcs -ftest-coverage" CACHE STRING "Profiling Linker Flags")
+endif(CMAKE_COMPILER_IS_GNUCC AND NOT MINGW)
+
+function (ADD_CMOCKA_TEST _testName _testSource)
+ add_executable(${_testName} ${_testSource})
+ target_link_libraries(${_testName} ${ARGN})
+ add_test(${_testName} ${CMAKE_CURRENT_BINARY_DIR}/${_testName})
+endfunction (ADD_CMOCKA_TEST)
diff --git a/emCmocka/cmake/Modules/COPYING-CMAKE-SCRIPTS b/emCmocka/cmake/Modules/COPYING-CMAKE-SCRIPTS
new file mode 100644
index 0000000..4b41776
--- /dev/null
+++ b/emCmocka/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/emCmocka/cmake/Modules/CheckCCompilerFlagSSP.cmake b/emCmocka/cmake/Modules/CheckCCompilerFlagSSP.cmake
new file mode 100644
index 0000000..2fe4395
--- /dev/null
+++ b/emCmocka/cmake/Modules/CheckCCompilerFlagSSP.cmake
@@ -0,0 +1,26 @@
+# - 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.
+
+
+include(CheckCSourceCompiles)
+
+function(CHECK_C_COMPILER_FLAG_SSP _FLAG _RESULT)
+ set(SAFE_CMAKE_REQUIRED_DEFINITIONS "${CMAKE_REQUIRED_DEFINITIONS}")
+ set(CMAKE_REQUIRED_DEFINITIONS "${_FLAG}")
+ check_c_source_compiles("int main(int argc, char **argv) { char buffer[256]; return buffer[argc]=0;}" ${_RESULT})
+ set(CMAKE_REQUIRED_DEFINITIONS "${SAFE_CMAKE_REQUIRED_DEFINITIONS}")
+endfunction(CHECK_C_COMPILER_FLAG_SSP)
diff --git a/emCmocka/cmake/Modules/DefineCMakeDefaults.cmake b/emCmocka/cmake/Modules/DefineCMakeDefaults.cmake
new file mode 100644
index 0000000..a08eca1
--- /dev/null
+++ b/emCmocka/cmake/Modules/DefineCMakeDefaults.cmake
@@ -0,0 +1,36 @@
+# 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)
+
+# Define the generic version of the libraries here
+set(GENERIC_LIB_VERSION "0.1.0")
+set(GENERIC_LIB_SOVERSION "0")
+
+# Set the default build type to release with debug info
+if (NOT CMAKE_BUILD_TYPE)
+ set(CMAKE_BUILD_TYPE RelWithDebInfo
+ CACHE STRING
+ "Choose the type of build, options are: None Debug Release RelWithDebInfo MinSizeRel."
+ )
+endif (NOT CMAKE_BUILD_TYPE)
+
+# Create the compile command database for clang by default
+set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
+
+if (APPLE)
+ set(CMAKE_MACOSX_RPATH ON)
+ set(CMAKE_SKIP_BUILD_RPATH FALSE)
+ set(CMAKE_BUILD_WITH_INSTALL_RPATH FALSE)
+endif(APPLE)
diff --git a/emCmocka/cmake/Modules/DefineCompilerFlags.cmake b/emCmocka/cmake/Modules/DefineCompilerFlags.cmake
new file mode 100644
index 0000000..cef5dc1
--- /dev/null
+++ b/emCmocka/cmake/Modules/DefineCompilerFlags.cmake
@@ -0,0 +1,79 @@
+# define system dependent compiler flags
+
+include(CheckCCompilerFlag)
+include(CheckCCompilerFlagSSP)
+
+if (UNIX AND NOT WIN32)
+ #
+ # Define GNUCC compiler flags
+ #
+ if (${CMAKE_C_COMPILER_ID} MATCHES "(GNU|Clang)")
+
+ # add -Wconversion ?
+ set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -std=gnu99 -pedantic -pedantic-errors")
+ set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall -Wextra -Wshadow -Wmissing-prototypes -Wdeclaration-after-statement")
+ set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wunused -Wfloat-equal -Wpointer-arith -Wwrite-strings -Wformat-security")
+ set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wmissing-format-attribute -Wundef -Wstrict-prototypes")
+
+ # with -fPIC
+ check_c_compiler_flag("-fPIC" WITH_FPIC)
+ if (WITH_FPIC)
+ set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fPIC")
+ endif (WITH_FPIC)
+
+ check_c_compiler_flag_ssp("-fstack-protector" WITH_STACK_PROTECTOR)
+ if (WITH_STACK_PROTECTOR)
+ set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fstack-protector")
+ endif (WITH_STACK_PROTECTOR)
+
+ if (CMAKE_BUILD_TYPE)
+ string(TOLOWER "${CMAKE_BUILD_TYPE}" CMAKE_BUILD_TYPE_LOWER)
+ if (CMAKE_BUILD_TYPE_LOWER MATCHES (release|relwithdebinfo|minsizerel))
+ check_c_compiler_flag("-Wp,-D_FORTIFY_SOURCE=2" WITH_FORTIFY_SOURCE)
+ if (WITH_FORTIFY_SOURCE)
+ set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wp,-D_FORTIFY_SOURCE=2")
+ endif (WITH_FORTIFY_SOURCE)
+ endif()
+ endif()
+
+ set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -D_GNU_SOURCE")
+ endif (${CMAKE_C_COMPILER_ID} MATCHES "(GNU|Clang)")
+
+ #
+ # Check for large filesystem support
+ #
+ if (CMAKE_SIZEOF_VOID_P MATCHES "8")
+ # with large file support
+ execute_process(
+ COMMAND
+ getconf LFS64_CFLAGS
+ OUTPUT_VARIABLE
+ _lfs_CFLAGS
+ ERROR_QUIET
+ OUTPUT_STRIP_TRAILING_WHITESPACE
+ )
+ else (CMAKE_SIZEOF_VOID_P MATCHES "8")
+ # with large file support
+ execute_process(
+ COMMAND
+ getconf LFS_CFLAGS
+ OUTPUT_VARIABLE
+ _lfs_CFLAGS
+ ERROR_QUIET
+ OUTPUT_STRIP_TRAILING_WHITESPACE
+ )
+ endif (CMAKE_SIZEOF_VOID_P MATCHES "8")
+ if (_lfs_CFLAGS)
+ string(REGEX REPLACE "[\r\n]" " " "${_lfs_CFLAGS}" "${${_lfs_CFLAGS}}")
+ set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${_lfs_CFLAGS}")
+ endif (_lfs_CFLAGS)
+
+endif (UNIX AND NOT WIN32)
+
+if (MSVC)
+ # Use secure functions by defaualt and suppress warnings about
+ #"deprecated" functions
+ set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} /D _CRT_SECURE_CPP_OVERLOAD_STANDARD_NAMES=1")
+ set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} /D _CRT_SECURE_CPP_OVERLOAD_STANDARD_NAMES_COUNT=1")
+ set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} /D _CRT_NONSTDC_NO_WARNINGS=1 /D _CRT_SECURE_NO_WARNINGS=1")
+endif (MSVC)
diff --git a/emCmocka/cmake/Modules/DefineInstallationPaths.cmake b/emCmocka/cmake/Modules/DefineInstallationPaths.cmake
new file mode 100644
index 0000000..88e08ca
--- /dev/null
+++ b/emCmocka/cmake/Modules/DefineInstallationPaths.cmake
@@ -0,0 +1,109 @@
+if (UNIX OR OS2)
+ IF (NOT APPLICATION_NAME)
+ MESSAGE(STATUS "${PROJECT_NAME} is used as APPLICATION_NAME")
+ SET(APPLICATION_NAME ${PROJECT_NAME})
+ ENDIF (NOT APPLICATION_NAME)
+
+ # Suffix for Linux
+ SET(LIB_SUFFIX
+ CACHE STRING "Define suffix of directory name (32/64)"
+ )
+
+ SET(EXEC_INSTALL_PREFIX
+ "${CMAKE_INSTALL_PREFIX}"
+ CACHE PATH "Base directory for executables and libraries"
+ )
+ SET(SHARE_INSTALL_PREFIX
+ "${CMAKE_INSTALL_PREFIX}/share"
+ CACHE PATH "Base directory for files which go to share/"
+ )
+ SET(DATA_INSTALL_PREFIX
+ "${SHARE_INSTALL_PREFIX}/${APPLICATION_NAME}"
+ CACHE PATH "The parent directory where applications can install their data")
+
+ # The following are directories where stuff will be installed to
+ SET(BIN_INSTALL_DIR
+ "${EXEC_INSTALL_PREFIX}/bin"
+ CACHE PATH "The ${APPLICATION_NAME} binary install dir (default prefix/bin)"
+ )
+ SET(SBIN_INSTALL_DIR
+ "${EXEC_INSTALL_PREFIX}/sbin"
+ CACHE PATH "The ${APPLICATION_NAME} sbin install dir (default prefix/sbin)"
+ )
+ SET(LIB_INSTALL_DIR
+ "${EXEC_INSTALL_PREFIX}/lib${LIB_SUFFIX}"
+ CACHE PATH "The subdirectory relative to the install prefix where libraries will be installed (default is prefix/lib)"
+ )
+ SET(LIBEXEC_INSTALL_DIR
+ "${EXEC_INSTALL_PREFIX}/libexec"
+ CACHE PATH "The subdirectory relative to the install prefix where libraries will be installed (default is prefix/libexec)"
+ )
+ SET(PLUGIN_INSTALL_DIR
+ "${LIB_INSTALL_DIR}/${APPLICATION_NAME}"
+ CACHE PATH "The subdirectory relative to the install prefix where plugins will be installed (default is prefix/lib/${APPLICATION_NAME})"
+ )
+ SET(INCLUDE_INSTALL_DIR
+ "${CMAKE_INSTALL_PREFIX}/include"
+ CACHE PATH "The subdirectory to the header prefix (default prefix/include)"
+ )
+
+ set(CMAKE_INSTALL_DIR
+ "${LIB_INSTALL_DIR}/cmake"
+ CACHE PATH "The subdirectory to install cmake config files")
+
+ SET(DATA_INSTALL_DIR
+ "${DATA_INSTALL_PREFIX}"
+ CACHE PATH "The parent directory where applications can install their data (default prefix/share/${APPLICATION_NAME})"
+ )
+ SET(HTML_INSTALL_DIR
+ "${DATA_INSTALL_PREFIX}/doc/HTML"
+ CACHE PATH "The HTML install dir for documentation (default data/doc/html)"
+ )
+ SET(ICON_INSTALL_DIR
+ "${DATA_INSTALL_PREFIX}/icons"
+ CACHE PATH "The icon install dir (default data/icons/)"
+ )
+ SET(SOUND_INSTALL_DIR
+ "${DATA_INSTALL_PREFIX}/sounds"
+ CACHE PATH "The install dir for sound files (default data/sounds)"
+ )
+
+ SET(LOCALE_INSTALL_DIR
+ "${SHARE_INSTALL_PREFIX}/locale"
+ CACHE PATH "The install dir for translations (default prefix/share/locale)"
+ )
+
+ SET(XDG_APPS_DIR
+ "${SHARE_INSTALL_PREFIX}/applications/"
+ CACHE PATH "The XDG apps dir"
+ )
+ SET(XDG_DIRECTORY_DIR
+ "${SHARE_INSTALL_PREFIX}/desktop-directories"
+ CACHE PATH "The XDG directory"
+ )
+
+ SET(SYSCONF_INSTALL_DIR
+ "${EXEC_INSTALL_PREFIX}/etc"
+ CACHE PATH "The ${APPLICATION_NAME} sysconfig install dir (default prefix/etc)"
+ )
+ SET(MAN_INSTALL_DIR
+ "${SHARE_INSTALL_PREFIX}/man"
+ CACHE PATH "The ${APPLICATION_NAME} man install dir (default prefix/man)"
+ )
+ SET(INFO_INSTALL_DIR
+ "${SHARE_INSTALL_PREFIX}/info"
+ CACHE PATH "The ${APPLICATION_NAME} info install dir (default prefix/info)"
+ )
+else()
+ # Same same
+ set(BIN_INSTALL_DIR "bin" CACHE PATH "-")
+ set(SBIN_INSTALL_DIR "sbin" CACHE PATH "-")
+ set(LIB_INSTALL_DIR "lib${LIB_SUFFIX}" CACHE PATH "-")
+ set(INCLUDE_INSTALL_DIR "include" CACHE PATH "-")
+ set(CMAKE_INSTALL_DIR "CMake" CACHE PATH "-")
+ set(PLUGIN_INSTALL_DIR "plugins" CACHE PATH "-")
+ set(HTML_INSTALL_DIR "doc/HTML" CACHE PATH "-")
+ set(ICON_INSTALL_DIR "icons" CACHE PATH "-")
+ set(SOUND_INSTALL_DIR "soudns" CACHE PATH "-")
+ set(LOCALE_INSTALL_DIR "lang" CACHE PATH "-")
+endif ()
diff --git a/emCmocka/cmake/Modules/DefinePlatformDefaults.cmake b/emCmocka/cmake/Modules/DefinePlatformDefaults.cmake
new file mode 100644
index 0000000..46c3185
--- /dev/null
+++ b/emCmocka/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/emCmocka/cmake/Modules/FindNSIS.cmake b/emCmocka/cmake/Modules/FindNSIS.cmake
new file mode 100644
index 0000000..08d839b
--- /dev/null
+++ b/emCmocka/cmake/Modules/FindNSIS.cmake
@@ -0,0 +1,51 @@
+# - Try to find NSIS
+# Once done this will define
+#
+# 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(_NSIS_ROOT_HINTS
+ "[HKEY_LOCAL_MACHINE\\SOFTWARE\\Wow6432Node\\NSIS;Default]")
+
+ set(_NSIS_ROOT_PATHS
+ $ENV{PROGRAMFILES}/NSIS)
+
+ find_path(NSIS_ROOT_PATH
+ NAMES
+ Include/Library.nsh
+ HINTS
+ ${_NSIS_ROOT_HINTS}
+ 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/emCmocka/cmake/Modules/MacroEnsureOutOfSourceBuild.cmake b/emCmocka/cmake/Modules/MacroEnsureOutOfSourceBuild.cmake
new file mode 100644
index 0000000..a2e9480
--- /dev/null
+++ b/emCmocka/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/emCmocka/cmake/Modules/UseDoxygen.cmake b/emCmocka/cmake/Modules/UseDoxygen.cmake
new file mode 100644
index 0000000..72c384d
--- /dev/null
+++ b/emCmocka/cmake/Modules/UseDoxygen.cmake
@@ -0,0 +1,140 @@
+# - Run Doxygen
+#
+# Adds a doxygen target that runs doxygen to generate the html
+# and optionally the LaTeX API documentation.
+# The doxygen target is added to the doc target as a dependency.
+# i.e.: the API documentation is built with:
+# make doc
+#
+# USAGE: GLOBAL INSTALL
+#
+# Install it with:
+# cmake ./ && sudo make install
+# Add the following to the CMakeLists.txt of your project:
+# include(UseDoxygen OPTIONAL)
+# Optionally copy Doxyfile.in in the directory of CMakeLists.txt and edit it.
+#
+# USAGE: INCLUDE IN PROJECT
+#
+# set(CMAKE_MODULE_PATH ${CMAKE_CURRENT_SOURCE_DIR})
+# include(UseDoxygen)
+# Add the Doxyfile.in and UseDoxygen.cmake files to the projects source directory.
+#
+#
+# CONFIGURATION
+#
+# To configure Doxygen you can edit Doxyfile.in and set some variables in cmake.
+# Variables you may define are:
+# DOXYFILE_SOURCE_DIR - Path where the Doxygen input files are.
+# Defaults to the current source directory.
+# DOXYFILE_EXTRA_SOURCES - Additional source diretories/files for Doxygen to scan.
+# The Paths should be in double quotes and separated by space. e.g.:
+# "${CMAKE_CURRENT_BINARY_DIR}/foo.c" "${CMAKE_CURRENT_BINARY_DIR}/bar/"
+#
+# DOXYFILE_OUTPUT_DIR - Path where the Doxygen output is stored.
+# Defaults to "${CMAKE_CURRENT_BINARY_DIR}/doc".
+#
+# DOXYFILE_LATEX - ON/OFF; Set to "ON" if you want the LaTeX documentation
+# to be built.
+# DOXYFILE_LATEX_DIR - Directory relative to DOXYFILE_OUTPUT_DIR where
+# the Doxygen LaTeX output is stored. Defaults to "latex".
+#
+# DOXYFILE_HTML_DIR - Directory relative to DOXYFILE_OUTPUT_DIR where
+# the Doxygen html output is stored. Defaults to "html".
+#
+
+#
+# Copyright (c) 2009, 2010, 2011 Tobias Rautenkranz
+#
+# Redistribution and use is allowed according to the terms of the New
+# BSD license.
+# For details see the accompanying COPYING-CMAKE-SCRIPTS file.
+#
+
+macro(usedoxygen_set_default name value type docstring)
+ if(NOT DEFINED "${name}")
+ set("${name}" "${value}" CACHE "${type}" "${docstring}")
+ endif()
+endmacro()
+
+find_package(Doxygen)
+
+if(DOXYGEN_FOUND)
+ find_file(DOXYFILE_IN "Doxyfile.in"
+ PATHS "${CMAKE_CURRENT_SOURCE_DIR}" "${CMAKE_ROOT}/Modules/"
+ NO_DEFAULT_PATH
+ DOC "Path to the doxygen configuration template file")
+ set(DOXYFILE "${CMAKE_CURRENT_BINARY_DIR}/Doxyfile")
+ include(FindPackageHandleStandardArgs)
+ find_package_handle_standard_args(DOXYFILE_IN DEFAULT_MSG "DOXYFILE_IN")
+endif()
+
+if(DOXYGEN_FOUND AND DOXYFILE_IN_FOUND)
+ usedoxygen_set_default(DOXYFILE_OUTPUT_DIR "${CMAKE_CURRENT_BINARY_DIR}/doc"
+ PATH "Doxygen output directory")
+ usedoxygen_set_default(DOXYFILE_HTML_DIR "html"
+ STRING "Doxygen HTML output directory")
+ usedoxygen_set_default(DOXYFILE_SOURCE_DIR "${CMAKE_CURRENT_SOURCE_DIR}"
+ PATH "Input files source directory")
+ usedoxygen_set_default(DOXYFILE_EXTRA_SOURCE_DIRS ""
+ STRING "Additional source files/directories separated by space")
+ set(DOXYFILE_SOURCE_DIRS "\"${DOXYFILE_SOURCE_DIR}\" ${DOXYFILE_EXTRA_SOURCES}")
+
+ usedoxygen_set_default(DOXYFILE_LATEX YES BOOL "Generate LaTeX API documentation" OFF)
+ usedoxygen_set_default(DOXYFILE_LATEX_DIR "latex" STRING "LaTex output directory")
+
+ mark_as_advanced(DOXYFILE_OUTPUT_DIR DOXYFILE_HTML_DIR DOXYFILE_LATEX_DIR
+ DOXYFILE_SOURCE_DIR DOXYFILE_EXTRA_SOURCE_DIRS DOXYFILE_IN)
+
+
+ set_property(DIRECTORY
+ APPEND PROPERTY
+ ADDITIONAL_MAKE_CLEAN_FILES
+ "${DOXYFILE_OUTPUT_DIR}/${DOXYFILE_HTML_DIR}")
+
+ add_custom_target(doxygen
+ COMMAND "${DOXYGEN_EXECUTABLE}"
+ "${DOXYFILE}"
+ COMMENT "Writing documentation to ${DOXYFILE_OUTPUT_DIR}..."
+ WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}")
+
+ set(DOXYFILE_DOT "NO")
+ if(DOXYGEN_DOT_EXECUTABLE)
+ set(DOXYFILE_DOT "YES")
+ endif()
+
+ ## LaTeX
+ set(DOXYFILE_PDFLATEX "NO")
+
+ set_property(DIRECTORY APPEND PROPERTY
+ ADDITIONAL_MAKE_CLEAN_FILES
+ "${DOXYFILE_OUTPUT_DIR}/${DOXYFILE_LATEX_DIR}")
+
+ if(DOXYFILE_LATEX STREQUAL "ON")
+ set(DOXYFILE_GENERATE_LATEX "YES")
+ find_package(LATEX)
+ find_program(DOXYFILE_MAKE make)
+ mark_as_advanced(DOXYFILE_MAKE)
+ if(LATEX_COMPILER AND MAKEINDEX_COMPILER AND DOXYFILE_MAKE)
+ if(PDFLATEX_COMPILER)
+ set(DOXYFILE_PDFLATEX "YES")
+ endif()
+
+ add_custom_command(TARGET doxygen
+ POST_BUILD
+ COMMAND "${DOXYFILE_MAKE}"
+ COMMENT "Running LaTeX for Doxygen documentation in ${DOXYFILE_OUTPUT_DIR}/${DOXYFILE_LATEX_DIR}..."
+ WORKING_DIRECTORY "${DOXYFILE_OUTPUT_DIR}/${DOXYFILE_LATEX_DIR}")
+ else()
+ set(DOXYGEN_LATEX "NO")
+ endif()
+ else()
+ set(DOXYFILE_GENERATE_LATEX "NO")
+ endif()
+
+
+ configure_file("${DOXYFILE_IN}" "${DOXYFILE}" @ONLY)
+
+ add_custom_target(doc)
+ add_dependencies(doc doxygen)
+endif()
diff --git a/emCmocka/cmocka-build-tree-settings.cmake.in b/emCmocka/cmocka-build-tree-settings.cmake.in
new file mode 100644
index 0000000..eb1f29e
--- /dev/null
+++ b/emCmocka/cmocka-build-tree-settings.cmake.in
@@ -0,0 +1 @@
+set(CMOCKA_INLUDE_DIR @PROJECT_SOURCE_DIR@/include)
diff --git a/emCmocka/cmocka-config-version.cmake.in b/emCmocka/cmocka-config-version.cmake.in
new file mode 100644
index 0000000..98f292c
--- /dev/null
+++ b/emCmocka/cmocka-config-version.cmake.in
@@ -0,0 +1,11 @@
+set(PACKAGE_VERSION @APPLICATION_VERSION@)
+
+# Check whether the requested PACKAGE_FIND_VERSION is compatible
+if("${PACKAGE_VERSION}" VERSION_LESS "${PACKAGE_FIND_VERSION}")
+ set(PACKAGE_VERSION_COMPATIBLE FALSE)
+else()
+ set(PACKAGE_VERSION_COMPATIBLE TRUE)
+ if ("${PACKAGE_VERSION}" VERSION_EQUAL "${PACKAGE_FIND_VERSION}")
+ set(PACKAGE_VERSION_EXACT TRUE)
+ endif()
+endif()
diff --git a/emCmocka/cmocka-config.cmake.in b/emCmocka/cmocka-config.cmake.in
new file mode 100644
index 0000000..317f0a2
--- /dev/null
+++ b/emCmocka/cmocka-config.cmake.in
@@ -0,0 +1,11 @@
+get_filename_component(CMOCKA_CMAKE_DIR "${CMAKE_CURRENT_LIST_FILE}" PATH)
+
+if (EXISTS "${CMOCKA_CMAKE_DIR}/CMakeCache.txt")
+ # In build tree
+ include(${CMOCKA_CMAKE_DIR}/cmocka-build-tree-settings.cmake)
+else()
+ set(CMOCKA_INCLUDE_DIR @INCLUDE_INSTALL_DIR@)
+endif()
+
+set(CMOCKA_LIBRARY @LIB_INSTALL_DIR@/@CMOCKA_LIBRARY_NAME@)
+set(CMOCKA_LIBRARIES @LIB_INSTALL_DIR@/@CMOCKA_LIBRARY_NAME@)
diff --git a/emCmocka/cmocka.pc.cmake b/emCmocka/cmocka.pc.cmake
new file mode 100644
index 0000000..c6f7433
--- /dev/null
+++ b/emCmocka/cmocka.pc.cmake
@@ -0,0 +1,6 @@
+Name: ${APPLICATION_NAME}
+Description: The cmocka unit testing library
+Version: ${APPLICATION_VERSION}
+Libs: -L${LIB_INSTALL_DIR} -lcmocka
+Cflags: -I${INCLUDE_INSTALL_DIR}
+
diff --git a/emCmocka/config.h.cmake b/emCmocka/config.h.cmake
new file mode 100644
index 0000000..1aaabb5
--- /dev/null
+++ b/emCmocka/config.h.cmake
@@ -0,0 +1,169 @@
+/* Name of package */
+#cmakedefine PACKAGE "${APPLICATION_NAME}"
+
+/* Version number of package */
+#cmakedefine VERSION "${APPLICATION_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
+
+/*************************** 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/emCmocka/coverity/README b/emCmocka/coverity/README
new file mode 100644
index 0000000..7756137
--- /dev/null
+++ b/emCmocka/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/emCmocka/coverity/coverity_assert_model.c b/emCmocka/coverity/coverity_assert_model.c
new file mode 100644
index 0000000..9bbb9f7
--- /dev/null
+++ b/emCmocka/coverity/coverity_assert_model.c
@@ -0,0 +1,87 @@
+#define LargestIntegralType unsigned long long
+
+void _assert_true(const LargestIntegralType result,
+ const char* const expression,
+ const char * const file, const int line)
+{
+ __coverity_panic__();
+}
+
+void _assert_int_equal(
+ const LargestIntegralType a, const LargestIntegralType b,
+ const char * const file, const int line)
+{
+ __coverity_panic__();
+}
+
+void _assert_int_not_equal(
+ const LargestIntegralType a, const LargestIntegralType b,
+ const char * const file, const int line)
+{
+ __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)
+{
+ __coverity_panic__();
+}
+
+void _assert_string_equal(const char * const a, const char * const b,
+ const char * const file, const int line)
+{
+ __coverity_panic__();
+}
+
+void _assert_string_not_equal(const char * const a, const char * const b,
+ const char *file, const int line)
+{
+ __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)
+{
+ __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)
+{
+ __coverity_panic__();
+}
+
+void _assert_in_range(
+ const LargestIntegralType value, const LargestIntegralType minimum,
+ const LargestIntegralType maximum, const char* const file, const int line)
+{
+ __coverity_panic__();
+}
+
+void _assert_not_in_range(
+ const LargestIntegralType value, const LargestIntegralType minimum,
+ const LargestIntegralType maximum, const char* const file, const int line)
+{
+ __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)
+{
+ __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)
+{
+ __coverity_panic__();
+}
+
diff --git a/emCmocka/coverity/coverity_internal_model.c b/emCmocka/coverity/coverity_internal_model.c
new file mode 100644
index 0000000..fd1416d
--- /dev/null
+++ b/emCmocka/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/emCmocka/doc/CMakeLists.txt b/emCmocka/doc/CMakeLists.txt
new file mode 100644
index 0000000..3124281
--- /dev/null
+++ b/emCmocka/doc/CMakeLists.txt
@@ -0,0 +1,5 @@
+#
+# Build the documentation
+#
+include(UseDoxygen OPTIONAL)
+
diff --git a/emCmocka/doc/Doxyfile.in b/emCmocka/doc/Doxyfile.in
new file mode 100644
index 0000000..221beba
--- /dev/null
+++ b/emCmocka/doc/Doxyfile.in
@@ -0,0 +1,2442 @@
+# Doxyfile 1.8.12
+
+# This file describes the settings to be used by the documentation system
+# doxygen (www.doxygen.org) for a project.
+#
+# All text after a double hash (##) is considered a comment and is placed in
+# front of the TAG it is preceding.
+#
+# All text after a single hash (#) is considered a comment and will be ignored.
+# The format is:
+# TAG = value [value, ...]
+# For lists, items can also be appended using:
+# TAG += value [value, ...]
+# Values that contain spaces should be placed between quotes (\" \").
+
+#---------------------------------------------------------------------------
+# Project related configuration options
+#---------------------------------------------------------------------------
+
+# This tag specifies the encoding used for all characters in the config file
+# that follow. The default is UTF-8 which is also the encoding used for all text
+# before the first occurrence of this tag. Doxygen uses libiconv (or the iconv
+# built into libc) for the transcoding. See http://www.gnu.org/software/libiconv
+# for the list of possible encodings.
+# The default value is: UTF-8.
+
+DOXYFILE_ENCODING = UTF-8
+
+# The PROJECT_NAME tag is a single word (or a sequence of words surrounded by
+# double-quotes, unless you are using Doxywizard) that should identify the
+# project for which the documentation is generated. This name is used in the
+# title of most generated pages and in a few other places.
+# The default value is: My Project.
+
+PROJECT_NAME = @APPLICATION_NAME@
+
+# The PROJECT_NUMBER tag can be used to enter a project or revision number. This
+# could be handy for archiving the generated documentation or if some version
+# control system is used.
+
+PROJECT_NUMBER = @APPLICATION_VERSION@
+
+# Using the PROJECT_BRIEF tag one can provide an optional one line description
+# for a project that appears at the top of each page and should give viewer a
+# quick idea about the purpose of the project. Keep the description short.
+
+PROJECT_BRIEF =
+
+# With the PROJECT_LOGO tag one can specify a logo or an icon that is included
+# in the documentation. The maximum height of the logo should not exceed 55
+# pixels and the maximum width should not exceed 200 pixels. Doxygen will copy
+# the logo to the output directory.
+
+PROJECT_LOGO =
+
+# The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute) path
+# into which the generated documentation will be written. If a relative path is
+# entered, it will be relative to the location where doxygen was started. If
+# left blank the current directory will be used.
+
+OUTPUT_DIRECTORY = "@CMAKE_CURRENT_BINARY_DIR@"
+
+# If the CREATE_SUBDIRS tag is set to YES then doxygen will create 4096 sub-
+# directories (in 2 levels) under the output directory of each output format and
+# will distribute the generated files over these directories. Enabling this
+# option can be useful when feeding doxygen a huge amount of source files, where
+# putting all generated files in the same directory would otherwise causes
+# performance problems for the file system.
+# The default value is: NO.
+
+CREATE_SUBDIRS = NO
+
+# If the ALLOW_UNICODE_NAMES tag is set to YES, doxygen will allow non-ASCII
+# characters to appear in the names of generated files. If set to NO, non-ASCII
+# characters will be escaped, for example _xE3_x81_x84 will be used for Unicode
+# U+3044.
+# The default value is: NO.
+
+ALLOW_UNICODE_NAMES = NO
+
+# The OUTPUT_LANGUAGE tag is used to specify the language in which all
+# documentation generated by doxygen is written. Doxygen will use this
+# information to generate all constant output in the proper language.
+# Possible values are: Afrikaans, Arabic, Armenian, Brazilian, Catalan, Chinese,
+# Chinese-Traditional, Croatian, Czech, Danish, Dutch, English (United States),
+# Esperanto, Farsi (Persian), Finnish, French, German, Greek, Hungarian,
+# Indonesian, Italian, Japanese, Japanese-en (Japanese with English messages),
+# Korean, Korean-en (Korean with English messages), Latvian, Lithuanian,
+# Macedonian, Norwegian, Persian (Farsi), Polish, Portuguese, Romanian, Russian,
+# Serbian, Serbian-Cyrillic, Slovak, Slovene, Spanish, Swedish, Turkish,
+# Ukrainian and Vietnamese.
+# The default value is: English.
+
+OUTPUT_LANGUAGE = English
+
+# If the BRIEF_MEMBER_DESC tag is set to YES, doxygen will include brief member
+# descriptions after the members that are listed in the file and class
+# documentation (similar to Javadoc). Set to NO to disable this.
+# The default value is: YES.
+
+BRIEF_MEMBER_DESC = YES
+
+# If the REPEAT_BRIEF tag is set to YES, doxygen will prepend the brief
+# description of a member or function before the detailed description
+#
+# Note: If both HIDE_UNDOC_MEMBERS and BRIEF_MEMBER_DESC are set to NO, the
+# brief descriptions will be completely suppressed.
+# The default value is: YES.
+
+REPEAT_BRIEF = YES
+
+# This tag implements a quasi-intelligent brief description abbreviator that is
+# used to form the text in various listings. Each string in this list, if found
+# as the leading text of the brief description, will be stripped from the text
+# and the result, after processing the whole list, is used as the annotated
+# text. Otherwise, the brief description is used as-is. If left blank, the
+# following values are used ($name is automatically replaced with the name of
+# the entity):The $name class, The $name widget, The $name file, is, provides,
+# specifies, contains, represents, a, an and the.
+
+ABBREVIATE_BRIEF = "The $name class" \
+ "The $name widget" \
+ "The $name file" \
+ is \
+ provides \
+ specifies \
+ contains \
+ represents \
+ a \
+ an \
+ the
+
+# If the ALWAYS_DETAILED_SEC and REPEAT_BRIEF tags are both set to YES then
+# doxygen will generate a detailed section even if there is only a brief
+# description.
+# The default value is: NO.
+
+ALWAYS_DETAILED_SEC = NO
+
+# If the INLINE_INHERITED_MEMB tag is set to YES, doxygen will show all
+# inherited members of a class in the documentation of that class as if those
+# members were ordinary class members. Constructors, destructors and assignment
+# operators of the base classes will not be shown.
+# The default value is: NO.
+
+INLINE_INHERITED_MEMB = NO
+
+# If the FULL_PATH_NAMES tag is set to YES, doxygen will prepend the full path
+# before files name in the file list and in the header files. If set to NO the
+# shortest path that makes the file name unique will be used
+# The default value is: YES.
+
+FULL_PATH_NAMES = YES
+
+# The STRIP_FROM_PATH tag can be used to strip a user-defined part of the path.
+# Stripping is only done if one of the specified strings matches the left-hand
+# part of the path. The tag can be used to show relative paths in the file list.
+# If left blank the directory from which doxygen is run is used as the path to
+# strip.
+#
+# Note that you can specify absolute paths here, but also relative paths, which
+# will be relative from the directory where doxygen is started.
+# This tag requires that the tag FULL_PATH_NAMES is set to YES.
+
+STRIP_FROM_PATH = "@CMAKE_SOURCE_DIR@"
+
+# The STRIP_FROM_INC_PATH tag can be used to strip a user-defined part of the
+# path mentioned in the documentation of a class, which tells the reader which
+# header file to include in order to use a class. If left blank only the name of
+# the header file containing the class definition is used. Otherwise one should
+# specify the list of include paths that are normally passed to the compiler
+# using the -I flag.
+
+STRIP_FROM_INC_PATH = "@CMAKE_SOURCE_DIR@"
+
+# If the SHORT_NAMES tag is set to YES, doxygen will generate much shorter (but
+# less readable) file names. This can be useful is your file systems doesn't
+# support long names like on DOS, Mac, or CD-ROM.
+# The default value is: NO.
+
+SHORT_NAMES = NO
+
+# If the JAVADOC_AUTOBRIEF tag is set to YES then doxygen will interpret the
+# first line (until the first dot) of a Javadoc-style comment as the brief
+# description. If set to NO, the Javadoc-style will behave just like regular Qt-
+# style comments (thus requiring an explicit @brief command for a brief
+# description.)
+# The default value is: NO.
+
+JAVADOC_AUTOBRIEF = YES
+
+# If the QT_AUTOBRIEF tag is set to YES then doxygen will interpret the first
+# line (until the first dot) of a Qt-style comment as the brief description. If
+# set to NO, the Qt-style will behave just like regular Qt-style comments (thus
+# requiring an explicit \brief command for a brief description.)
+# The default value is: NO.
+
+QT_AUTOBRIEF = NO
+
+# The MULTILINE_CPP_IS_BRIEF tag can be set to YES to make doxygen treat a
+# multi-line C++ special comment block (i.e. a block of //! or /// comments) as
+# a brief description. This used to be the default behavior. The new default is
+# to treat a multi-line C++ comment block as a detailed description. Set this
+# tag to YES if you prefer the old behavior instead.
+#
+# Note that setting this tag to YES also means that rational rose comments are
+# not recognized any more.
+# The default value is: NO.
+
+MULTILINE_CPP_IS_BRIEF = NO
+
+# If the INHERIT_DOCS tag is set to YES then an undocumented member inherits the
+# documentation from any documented member that it re-implements.
+# The default value is: YES.
+
+INHERIT_DOCS = YES
+
+# If the SEPARATE_MEMBER_PAGES tag is set to YES then doxygen will produce a new
+# page for each member. If set to NO, the documentation of a member will be part
+# of the file/class/namespace that contains it.
+# The default value is: NO.
+
+SEPARATE_MEMBER_PAGES = NO
+
+# The TAB_SIZE tag can be used to set the number of spaces in a tab. Doxygen
+# uses this value to replace tabs by spaces in code fragments.
+# Minimum value: 1, maximum value: 16, default value: 4.
+
+TAB_SIZE = 2
+
+# This tag can be used to specify a number of aliases that act as commands in
+# the documentation. An alias has the form:
+# name=value
+# For example adding
+# "sideeffect=@par Side Effects:\n"
+# will allow you to put the command \sideeffect (or @sideeffect) in the
+# documentation, which will result in a user-defined paragraph with heading
+# "Side Effects:". You can put \n's in the value part of an alias to insert
+# newlines.
+
+ALIASES =
+
+# This tag can be used to specify a number of word-keyword mappings (TCL only).
+# A mapping has the form "name=value". For example adding "class=itcl::class"
+# will allow you to use the command class in the itcl::class meaning.
+
+TCL_SUBST =
+
+# Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C sources
+# only. Doxygen will then generate output that is more tailored for C. For
+# instance, some of the names that are used will be different. The list of all
+# members will be omitted, etc.
+# The default value is: NO.
+
+OPTIMIZE_OUTPUT_FOR_C = YES
+
+# Set the OPTIMIZE_OUTPUT_JAVA tag to YES if your project consists of Java or
+# Python sources only. Doxygen will then generate output that is more tailored
+# for that language. For instance, namespaces will be presented as packages,
+# qualified scopes will look different, etc.
+# The default value is: NO.
+
+OPTIMIZE_OUTPUT_JAVA = NO
+
+# Set the OPTIMIZE_FOR_FORTRAN tag to YES if your project consists of Fortran
+# sources. Doxygen will then generate output that is tailored for Fortran.
+# The default value is: NO.
+
+OPTIMIZE_FOR_FORTRAN = NO
+
+# Set the OPTIMIZE_OUTPUT_VHDL tag to YES if your project consists of VHDL
+# sources. Doxygen will then generate output that is tailored for VHDL.
+# The default value is: NO.
+
+OPTIMIZE_OUTPUT_VHDL = NO
+
+# Doxygen selects the parser to use depending on the extension of the files it
+# parses. With this tag you can assign which parser to use for a given
+# extension. Doxygen has a built-in mapping, but you can override or extend it
+# using this tag. The format is ext=language, where ext is a file extension, and
+# language is one of the parsers supported by doxygen: IDL, Java, Javascript,
+# C#, C, C++, D, PHP, Objective-C, Python, Fortran (fixed format Fortran:
+# FortranFixed, free formatted Fortran: FortranFree, unknown formatted Fortran:
+# Fortran. In the later case the parser tries to guess whether the code is fixed
+# or free formatted code, this is the default for Fortran type files), VHDL. For
+# instance to make doxygen treat .inc files as Fortran files (default is PHP),
+# and .f files as C (default is Fortran), use: inc=Fortran f=C.
+#
+# Note: For files without extension you can use no_extension as a placeholder.
+#
+# Note that for custom extensions you also need to set FILE_PATTERNS otherwise
+# the files are not read by doxygen.
+
+EXTENSION_MAPPING =
+
+# If the MARKDOWN_SUPPORT tag is enabled then doxygen pre-processes all comments
+# according to the Markdown format, which allows for more readable
+# documentation. See http://daringfireball.net/projects/markdown/ for details.
+# The output of markdown processing is further processed by doxygen, so you can
+# mix doxygen, HTML, and XML commands with Markdown formatting. Disable only in
+# case of backward compatibilities issues.
+# The default value is: YES.
+
+MARKDOWN_SUPPORT = YES
+
+# When the TOC_INCLUDE_HEADINGS tag is set to a non-zero value, all headings up
+# to that level are automatically included in the table of contents, even if
+# they do not have an id attribute.
+# Note: This feature currently applies only to Markdown headings.
+# Minimum value: 0, maximum value: 99, default value: 0.
+# This tag requires that the tag MARKDOWN_SUPPORT is set to YES.
+
+TOC_INCLUDE_HEADINGS = 0
+
+# When enabled doxygen tries to link words that correspond to documented
+# classes, or namespaces to their corresponding documentation. Such a link can
+# be prevented in individual cases by putting a % sign in front of the word or
+# globally by setting AUTOLINK_SUPPORT to NO.
+# The default value is: YES.
+
+AUTOLINK_SUPPORT = YES
+
+# If you use STL classes (i.e. std::string, std::vector, etc.) but do not want
+# to include (a tag file for) the STL sources as input, then you should set this
+# tag to YES in order to let doxygen match functions declarations and
+# definitions whose arguments contain STL classes (e.g. func(std::string);
+# versus func(std::string) {}). This also make the inheritance and collaboration
+# diagrams that involve STL classes more complete and accurate.
+# The default value is: NO.
+
+BUILTIN_STL_SUPPORT = NO
+
+# If you use Microsoft's C++/CLI language, you should set this option to YES to
+# enable parsing support.
+# The default value is: NO.
+
+CPP_CLI_SUPPORT = NO
+
+# Set the SIP_SUPPORT tag to YES if your project consists of sip (see:
+# http://www.riverbankcomputing.co.uk/software/sip/intro) sources only. Doxygen
+# will parse them like normal C++ but will assume all classes use public instead
+# of private inheritance when no explicit protection keyword is present.
+# The default value is: NO.
+
+SIP_SUPPORT = NO
+
+# For Microsoft's IDL there are propget and propput attributes to indicate
+# getter and setter methods for a property. Setting this option to YES will make
+# doxygen to replace the get and set methods by a property in the documentation.
+# This will only work if the methods are indeed getting or setting a simple
+# type. If this is not the case, or you want to show the methods anyway, you
+# should set this option to NO.
+# The default value is: YES.
+
+IDL_PROPERTY_SUPPORT = YES
+
+# If member grouping is used in the documentation and the DISTRIBUTE_GROUP_DOC
+# tag is set to YES then doxygen will reuse the documentation of the first
+# member in the group (if any) for the other members of the group. By default
+# all members of a group must be documented explicitly.
+# The default value is: NO.
+
+DISTRIBUTE_GROUP_DOC = NO
+
+# If one adds a struct or class to a group and this option is enabled, then also
+# any nested class or struct is added to the same group. By default this option
+# is disabled and one has to add nested compounds explicitly via \ingroup.
+# The default value is: NO.
+
+GROUP_NESTED_COMPOUNDS = NO
+
+# Set the SUBGROUPING tag to YES to allow class member groups of the same type
+# (for instance a group of public functions) to be put as a subgroup of that
+# type (e.g. under the Public Functions section). Set it to NO to prevent
+# subgrouping. Alternatively, this can be done per class using the
+# \nosubgrouping command.
+# The default value is: YES.
+
+SUBGROUPING = YES
+
+# When the INLINE_GROUPED_CLASSES tag is set to YES, classes, structs and unions
+# are shown inside the group in which they are included (e.g. using \ingroup)
+# instead of on a separate page (for HTML and Man pages) or section (for LaTeX
+# and RTF).
+#
+# Note that this feature does not work in combination with
+# SEPARATE_MEMBER_PAGES.
+# The default value is: NO.
+
+INLINE_GROUPED_CLASSES = NO
+
+# When the INLINE_SIMPLE_STRUCTS tag is set to YES, structs, classes, and unions
+# with only public data fields or simple typedef fields will be shown inline in
+# the documentation of the scope in which they are defined (i.e. file,
+# namespace, or group documentation), provided this scope is documented. If set
+# to NO, structs, classes, and unions are shown on a separate page (for HTML and
+# Man pages) or section (for LaTeX and RTF).
+# The default value is: NO.
+
+INLINE_SIMPLE_STRUCTS = NO
+
+# When TYPEDEF_HIDES_STRUCT tag is enabled, a typedef of a struct, union, or
+# enum is documented as struct, union, or enum with the name of the typedef. So
+# typedef struct TypeS {} TypeT, will appear in the documentation as a struct
+# with name TypeT. When disabled the typedef will appear as a member of a file,
+# namespace, or class. And the struct will be named TypeS. This can typically be
+# useful for C code in case the coding convention dictates that all compound
+# types are typedef'ed and only the typedef is referenced, never the tag name.
+# The default value is: NO.
+
+TYPEDEF_HIDES_STRUCT = YES
+
+# The size of the symbol lookup cache can be set using LOOKUP_CACHE_SIZE. This
+# cache is used to resolve symbols given their name and scope. Since this can be
+# an expensive process and often the same symbol appears multiple times in the
+# code, doxygen keeps a cache of pre-resolved symbols. If the cache is too small
+# doxygen will become slower. If the cache is too large, memory is wasted. The
+# cache size is given by this formula: 2^(16+LOOKUP_CACHE_SIZE). The valid range
+# is 0..9, the default is 0, corresponding to a cache size of 2^16=65536
+# symbols. At the end of a run doxygen will report the cache usage and suggest
+# the optimal cache size from a speed point of view.
+# Minimum value: 0, maximum value: 9, default value: 0.
+
+LOOKUP_CACHE_SIZE = 0
+
+#---------------------------------------------------------------------------
+# Build related configuration options
+#---------------------------------------------------------------------------
+
+# If the EXTRACT_ALL tag is set to YES, doxygen will assume all entities in
+# documentation are documented, even if no documentation was available. Private
+# class members and static file members will be hidden unless the
+# EXTRACT_PRIVATE respectively EXTRACT_STATIC tags are set to YES.
+# Note: This will also disable the warnings about undocumented members that are
+# normally produced when WARNINGS is set to YES.
+# The default value is: NO.
+
+EXTRACT_ALL = NO
+
+# If the EXTRACT_PRIVATE tag is set to YES, all private members of a class will
+# be included in the documentation.
+# The default value is: NO.
+
+EXTRACT_PRIVATE = NO
+
+# If the EXTRACT_PACKAGE tag is set to YES, all members with package or internal
+# scope will be included in the documentation.
+# The default value is: NO.
+
+EXTRACT_PACKAGE = NO
+
+# If the EXTRACT_STATIC tag is set to YES, all static members of a file will be
+# included in the documentation.
+# The default value is: NO.
+
+EXTRACT_STATIC = NO
+
+# If the EXTRACT_LOCAL_CLASSES tag is set to YES, classes (and structs) defined
+# locally in source files will be included in the documentation. If set to NO,
+# only classes defined in header files are included. Does not have any effect
+# for Java sources.
+# The default value is: YES.
+
+EXTRACT_LOCAL_CLASSES = NO
+
+# This flag is only useful for Objective-C code. If set to YES, local methods,
+# which are defined in the implementation section but not in the interface are
+# included in the documentation. If set to NO, only methods in the interface are
+# included.
+# The default value is: NO.
+
+EXTRACT_LOCAL_METHODS = NO
+
+# If this flag is set to YES, the members of anonymous namespaces will be
+# extracted and appear in the documentation as a namespace called
+# 'anonymous_namespace{file}', where file will be replaced with the base name of
+# the file that contains the anonymous namespace. By default anonymous namespace
+# are hidden.
+# The default value is: NO.
+
+EXTRACT_ANON_NSPACES = NO
+
+# If the HIDE_UNDOC_MEMBERS tag is set to YES, doxygen will hide all
+# undocumented members inside documented classes or files. If set to NO these
+# members will be included in the various overviews, but no documentation
+# section is generated. This option has no effect if EXTRACT_ALL is enabled.
+# The default value is: NO.
+
+HIDE_UNDOC_MEMBERS = YES
+
+# If the HIDE_UNDOC_CLASSES tag is set to YES, doxygen will hide all
+# undocumented classes that are normally visible in the class hierarchy. If set
+# to NO, these classes will be included in the various overviews. This option
+# has no effect if EXTRACT_ALL is enabled.
+# The default value is: NO.
+
+HIDE_UNDOC_CLASSES = YES
+
+# If the HIDE_FRIEND_COMPOUNDS tag is set to YES, doxygen will hide all friend
+# (class|struct|union) declarations. If set to NO, these declarations will be
+# included in the documentation.
+# The default value is: NO.
+
+HIDE_FRIEND_COMPOUNDS = NO
+
+# If the HIDE_IN_BODY_DOCS tag is set to YES, doxygen will hide any
+# documentation blocks found inside the body of a function. If set to NO, these
+# blocks will be appended to the function's detailed documentation block.
+# The default value is: NO.
+
+HIDE_IN_BODY_DOCS = NO
+
+# The INTERNAL_DOCS tag determines if documentation that is typed after a
+# \internal command is included. If the tag is set to NO then the documentation
+# will be excluded. Set it to YES to include the internal documentation.
+# The default value is: NO.
+
+INTERNAL_DOCS = @CMAKE_INTERNAL_DOC@
+
+# If the CASE_SENSE_NAMES tag is set to NO then doxygen will only generate file
+# names in lower-case letters. If set to YES, upper-case letters are also
+# allowed. This is useful if you have classes or files whose names only differ
+# in case and if your file system supports case sensitive file names. Windows
+# and Mac users are advised to set this option to NO.
+# The default value is: system dependent.
+
+CASE_SENSE_NAMES = YES
+
+# If the HIDE_SCOPE_NAMES tag is set to NO then doxygen will show members with
+# their full class and namespace scopes in the documentation. If set to YES, the
+# scope will be hidden.
+# The default value is: NO.
+
+HIDE_SCOPE_NAMES = NO
+
+# If the HIDE_COMPOUND_REFERENCE tag is set to NO (default) then doxygen will
+# append additional text to a page's title, such as Class Reference. If set to
+# YES the compound reference will be hidden.
+# The default value is: NO.
+
+HIDE_COMPOUND_REFERENCE= NO
+
+# If the SHOW_INCLUDE_FILES tag is set to YES then doxygen will put a list of
+# the files that are included by a file in the documentation of that file.
+# The default value is: YES.
+
+SHOW_INCLUDE_FILES = YES
+
+# If the SHOW_GROUPED_MEMB_INC tag is set to YES then Doxygen will add for each
+# grouped member an include statement to the documentation, telling the reader
+# which file to include in order to use the member.
+# The default value is: NO.
+
+SHOW_GROUPED_MEMB_INC = NO
+
+# If the FORCE_LOCAL_INCLUDES tag is set to YES then doxygen will list include
+# files with double quotes in the documentation rather than with sharp brackets.
+# The default value is: NO.
+
+FORCE_LOCAL_INCLUDES = NO
+
+# If the INLINE_INFO tag is set to YES then a tag [inline] is inserted in the
+# documentation for inline members.
+# The default value is: YES.
+
+INLINE_INFO = YES
+
+# If the SORT_MEMBER_DOCS tag is set to YES then doxygen will sort the
+# (detailed) documentation of file and class members alphabetically by member
+# name. If set to NO, the members will appear in declaration order.
+# The default value is: YES.
+
+SORT_MEMBER_DOCS = YES
+
+# If the SORT_BRIEF_DOCS tag is set to YES then doxygen will sort the brief
+# descriptions of file, namespace and class members alphabetically by member
+# name. If set to NO, the members will appear in declaration order. Note that
+# this will also influence the order of the classes in the class list.
+# The default value is: NO.
+
+SORT_BRIEF_DOCS = YES
+
+# If the SORT_MEMBERS_CTORS_1ST tag is set to YES then doxygen will sort the
+# (brief and detailed) documentation of class members so that constructors and
+# destructors are listed first. If set to NO the constructors will appear in the
+# respective orders defined by SORT_BRIEF_DOCS and SORT_MEMBER_DOCS.
+# Note: If SORT_BRIEF_DOCS is set to NO this option is ignored for sorting brief
+# member documentation.
+# Note: If SORT_MEMBER_DOCS is set to NO this option is ignored for sorting
+# detailed member documentation.
+# The default value is: NO.
+
+SORT_MEMBERS_CTORS_1ST = NO
+
+# If the SORT_GROUP_NAMES tag is set to YES then doxygen will sort the hierarchy
+# of group names into alphabetical order. If set to NO the group names will
+# appear in their defined order.
+# The default value is: NO.
+
+SORT_GROUP_NAMES = NO
+
+# If the SORT_BY_SCOPE_NAME tag is set to YES, the class list will be sorted by
+# fully-qualified names, including namespaces. If set to NO, the class list will
+# be sorted only by class name, not including the namespace part.
+# Note: This option is not very useful if HIDE_SCOPE_NAMES is set to YES.
+# Note: This option applies only to the class list, not to the alphabetical
+# list.
+# The default value is: NO.
+
+SORT_BY_SCOPE_NAME = NO
+
+# If the STRICT_PROTO_MATCHING option is enabled and doxygen fails to do proper
+# type resolution of all parameters of a function it will reject a match between
+# the prototype and the implementation of a member function even if there is
+# only one candidate or it is obvious which candidate to choose by doing a
+# simple string match. By disabling STRICT_PROTO_MATCHING doxygen will still
+# accept a match between prototype and implementation in such cases.
+# The default value is: NO.
+
+STRICT_PROTO_MATCHING = NO
+
+# The GENERATE_TODOLIST tag can be used to enable (YES) or disable (NO) the todo
+# list. This list is created by putting \todo commands in the documentation.
+# The default value is: YES.
+
+GENERATE_TODOLIST = YES
+
+# The GENERATE_TESTLIST tag can be used to enable (YES) or disable (NO) the test
+# list. This list is created by putting \test commands in the documentation.
+# The default value is: YES.
+
+GENERATE_TESTLIST = YES
+
+# The GENERATE_BUGLIST tag can be used to enable (YES) or disable (NO) the bug
+# list. This list is created by putting \bug commands in the documentation.
+# The default value is: YES.
+
+GENERATE_BUGLIST = YES
+
+# The GENERATE_DEPRECATEDLIST tag can be used to enable (YES) or disable (NO)
+# the deprecated list. This list is created by putting \deprecated commands in
+# the documentation.
+# The default value is: YES.
+
+GENERATE_DEPRECATEDLIST= YES
+
+# The ENABLED_SECTIONS tag can be used to enable conditional documentation
+# sections, marked by \if ... \endif and \cond
+# ... \endcond blocks.
+
+ENABLED_SECTIONS =
+
+# The MAX_INITIALIZER_LINES tag determines the maximum number of lines that the
+# initial value of a variable or macro / define can have for it to appear in the
+# documentation. If the initializer consists of more lines than specified here
+# it will be hidden. Use a value of 0 to hide initializers completely. The
+# appearance of the value of individual variables and macros / defines can be
+# controlled using \showinitializer or \hideinitializer command in the
+# documentation regardless of this setting.
+# Minimum value: 0, maximum value: 10000, default value: 30.
+
+MAX_INITIALIZER_LINES = 30
+
+# Set the SHOW_USED_FILES tag to NO to disable the list of files generated at
+# the bottom of the documentation of classes and structs. If set to YES, the
+# list will mention the files that were used to generate the documentation.
+# The default value is: YES.
+
+SHOW_USED_FILES = YES
+
+# Set the SHOW_FILES tag to NO to disable the generation of the Files page. This
+# will remove the Files entry from the Quick Index and from the Folder Tree View
+# (if specified).
+# The default value is: YES.
+
+SHOW_FILES = YES
+
+# Set the SHOW_NAMESPACES tag to NO to disable the generation of the Namespaces
+# page. This will remove the Namespaces entry from the Quick Index and from the
+# Folder Tree View (if specified).
+# The default value is: YES.
+
+SHOW_NAMESPACES = YES
+
+# The FILE_VERSION_FILTER tag can be used to specify a program or script that
+# doxygen should invoke to get the current version for each file (typically from
+# the version control system). Doxygen will invoke the program by executing (via
+# popen()) the command command input-file, where command is the value of the
+# FILE_VERSION_FILTER tag, and input-file is the name of an input file provided
+# by doxygen. Whatever the program writes to standard output is used as the file
+# version. For an example see the documentation.
+
+FILE_VERSION_FILTER =
+
+# The LAYOUT_FILE tag can be used to specify a layout file which will be parsed
+# by doxygen. The layout file controls the global structure of the generated
+# output files in an output format independent way. To create the layout file
+# that represents doxygen's defaults, run doxygen with the -l option. You can
+# optionally specify a file name after the option, if omitted DoxygenLayout.xml
+# will be used as the name of the layout file.
+#
+# Note that if you run doxygen from a directory containing a file called
+# DoxygenLayout.xml, doxygen will parse it automatically even if the LAYOUT_FILE
+# tag is left empty.
+
+LAYOUT_FILE =
+
+# The CITE_BIB_FILES tag can be used to specify one or more bib files containing
+# the reference definitions. This must be a list of .bib files. The .bib
+# extension is automatically appended if omitted. This requires the bibtex tool
+# to be installed. See also http://en.wikipedia.org/wiki/BibTeX for more info.
+# For LaTeX the style of the bibliography can be controlled using
+# LATEX_BIB_STYLE. To use this feature you need bibtex and perl available in the
+# search path. See also \cite for info how to create references.
+
+CITE_BIB_FILES =
+
+#---------------------------------------------------------------------------
+# Configuration options related to warning and progress messages
+#---------------------------------------------------------------------------
+
+# The QUIET tag can be used to turn on/off the messages that are generated to
+# standard output by doxygen. If QUIET is set to YES this implies that the
+# messages are off.
+# The default value is: NO.
+
+QUIET = YES
+
+# The WARNINGS tag can be used to turn on/off the warning messages that are
+# generated to standard error (stderr) by doxygen. If WARNINGS is set to YES
+# this implies that the warnings are on.
+#
+# Tip: Turn warnings on while writing the documentation.
+# The default value is: YES.
+
+WARNINGS = YES
+
+# If the WARN_IF_UNDOCUMENTED tag is set to YES then doxygen will generate
+# warnings for undocumented members. If EXTRACT_ALL is set to YES then this flag
+# will automatically be disabled.
+# The default value is: YES.
+
+WARN_IF_UNDOCUMENTED = YES
+
+# If the WARN_IF_DOC_ERROR tag is set to YES, doxygen will generate warnings for
+# potential errors in the documentation, such as not documenting some parameters
+# in a documented function, or documenting parameters that don't exist or using
+# markup commands wrongly.
+# The default value is: YES.
+
+WARN_IF_DOC_ERROR = YES
+
+# This WARN_NO_PARAMDOC option can be enabled to get warnings for functions that
+# are documented, but have no documentation for their parameters or return
+# value. If set to NO, doxygen will only warn about wrong or incomplete
+# parameter documentation, but not about the absence of documentation.
+# The default value is: NO.
+
+WARN_NO_PARAMDOC = NO
+
+# If the WARN_AS_ERROR tag is set to YES then doxygen will immediately stop when
+# a warning is encountered.
+# The default value is: NO.
+
+WARN_AS_ERROR = NO
+
+# The WARN_FORMAT tag determines the format of the warning messages that doxygen
+# can produce. The string should contain the $file, $line, and $text tags, which
+# will be replaced by the file and line number from which the warning originated
+# and the warning text. Optionally the format may contain $version, which will
+# be replaced by the version of the file (if it could be obtained via
+# FILE_VERSION_FILTER)
+# The default value is: $file:$line: $text.
+
+WARN_FORMAT = "$file:$line: $text"
+
+# The WARN_LOGFILE tag can be used to specify a file to which warning and error
+# messages should be written. If left blank the output is written to standard
+# error (stderr).
+
+WARN_LOGFILE =
+
+#---------------------------------------------------------------------------
+# Configuration options related to the input files
+#---------------------------------------------------------------------------
+
+# The INPUT tag is used to specify the files and/or directories that contain
+# documented source files. You may enter file names like myfile.cpp or
+# directories like /usr/src/myproject. Separate the files or directories with
+# spaces. See also FILE_PATTERNS and EXTENSION_MAPPING
+# Note: If this tag is empty the current directory is searched.
+
+INPUT = "@CMAKE_SOURCE_DIR@/include" \
+ "@CMAKE_SOURCE_DIR@/src" \
+ "@CMAKE_SOURCE_DIR@/doc"
+
+# This tag can be used to specify the character encoding of the source files
+# that doxygen parses. Internally doxygen uses the UTF-8 encoding. Doxygen uses
+# libiconv (or the iconv built into libc) for the transcoding. See the libiconv
+# documentation (see: http://www.gnu.org/software/libiconv) for the list of
+# possible encodings.
+# The default value is: UTF-8.
+
+INPUT_ENCODING = UTF-8
+
+# If the value of the INPUT tag contains directories, you can use the
+# FILE_PATTERNS tag to specify one or more wildcard patterns (like *.cpp and
+# *.h) to filter out the source-files in the directories.
+#
+# Note that for custom extensions or not directly supported extensions you also
+# need to set EXTENSION_MAPPING for the extension otherwise the files are not
+# read by doxygen.
+#
+# If left blank the following patterns are tested:*.c, *.cc, *.cxx, *.cpp,
+# *.c++, *.java, *.ii, *.ixx, *.ipp, *.i++, *.inl, *.idl, *.ddl, *.odl, *.h,
+# *.hh, *.hxx, *.hpp, *.h++, *.cs, *.d, *.php, *.php4, *.php5, *.phtml, *.inc,
+# *.m, *.markdown, *.md, *.mm, *.dox, *.py, *.pyw, *.f90, *.f95, *.f03, *.f08,
+# *.f, *.for, *.tcl, *.vhd, *.vhdl, *.ucf and *.qsf.
+
+FILE_PATTERNS = *.cpp \
+ *.cc \
+ *.c \
+ *.h \
+ *.hh \
+ *.hpp \
+ *.dox
+
+# The RECURSIVE tag can be used to specify whether or not subdirectories should
+# be searched for input files as well.
+# The default value is: NO.
+
+RECURSIVE = YES
+
+# The EXCLUDE tag can be used to specify files and/or directories that should be
+# excluded from the INPUT source files. This way you can easily exclude a
+# subdirectory from a directory tree whose root is specified with the INPUT tag.
+#
+# Note that relative paths are relative to the directory from which doxygen is
+# run.
+
+EXCLUDE =
+
+# The EXCLUDE_SYMLINKS tag can be used to select whether or not files or
+# directories that are symbolic links (a Unix file system feature) are excluded
+# from the input.
+# The default value is: NO.
+
+EXCLUDE_SYMLINKS = NO
+
+# If the value of the INPUT tag contains directories, you can use the
+# EXCLUDE_PATTERNS tag to specify one or more wildcard patterns to exclude
+# certain files from those directories.
+#
+# Note that the wildcards are matched against the file with absolute path, so to
+# exclude all test directories for example use the pattern */test/*
+
+EXCLUDE_PATTERNS = */.git/* \
+ */.svn/* \
+ */cmake/*
+
+# The EXCLUDE_SYMBOLS tag can be used to specify one or more symbol names
+# (namespaces, classes, functions, etc.) that should be excluded from the
+# output. The symbol name can be a fully qualified name, a word, or if the
+# wildcard * is used, a substring. Examples: ANamespace, AClass,
+# AClass::ANamespace, ANamespace::*Test
+#
+# Note that the wildcards are matched against the file with absolute path, so to
+# exclude all test directories use the pattern */test/*
+
+EXCLUDE_SYMBOLS =
+
+# The EXAMPLE_PATH tag can be used to specify one or more files or directories
+# that contain example code fragments that are included (see the \include
+# command).
+
+EXAMPLE_PATH = "@CMAKE_SOURCE_DIR@/example"
+
+# If the value of the EXAMPLE_PATH tag contains directories, you can use the
+# EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp and
+# *.h) to filter out the source-files in the directories. If left blank all
+# files are included.
+
+EXAMPLE_PATTERNS = *.c \
+ *.h \
+ INSTALL \
+ DEPENDENCIES \
+ CHANGELOG \
+ LICENSE \
+ LGPL
+
+# If the EXAMPLE_RECURSIVE tag is set to YES then subdirectories will be
+# searched for input files to be used with the \include or \dontinclude commands
+# irrespective of the value of the RECURSIVE tag.
+# The default value is: NO.
+
+EXAMPLE_RECURSIVE = YES
+
+# The IMAGE_PATH tag can be used to specify one or more files or directories
+# that contain images that are to be included in the documentation (see the
+# \image command).
+
+IMAGE_PATH =
+
+# The INPUT_FILTER tag can be used to specify a program that doxygen should
+# invoke to filter for each input file. Doxygen will invoke the filter program
+# by executing (via popen()) the command:
+#
+#
+#
+# where is the value of the INPUT_FILTER tag, and is the
+# name of an input file. Doxygen will then use the output that the filter
+# program writes to standard output. If FILTER_PATTERNS is specified, this tag
+# will be ignored.
+#
+# Note that the filter must not add or remove lines; it is applied before the
+# code is scanned, but not when the output code is generated. If lines are added
+# or removed, the anchors will not be placed correctly.
+#
+# Note that for custom extensions or not directly supported extensions you also
+# need to set EXTENSION_MAPPING for the extension otherwise the files are not
+# properly processed by doxygen.
+
+INPUT_FILTER =
+
+# The FILTER_PATTERNS tag can be used to specify filters on a per file pattern
+# basis. Doxygen will compare the file name with each pattern and apply the
+# filter if there is a match. The filters are a list of the form: pattern=filter
+# (like *.cpp=my_cpp_filter). See INPUT_FILTER for further information on how
+# filters are used. If the FILTER_PATTERNS tag is empty or if none of the
+# patterns match the file name, INPUT_FILTER is applied.
+#
+# Note that for custom extensions or not directly supported extensions you also
+# need to set EXTENSION_MAPPING for the extension otherwise the files are not
+# properly processed by doxygen.
+
+FILTER_PATTERNS =
+
+# If the FILTER_SOURCE_FILES tag is set to YES, the input filter (if set using
+# INPUT_FILTER) will also be used to filter the input files that are used for
+# producing the source files to browse (i.e. when SOURCE_BROWSER is set to YES).
+# The default value is: NO.
+
+FILTER_SOURCE_FILES = NO
+
+# The FILTER_SOURCE_PATTERNS tag can be used to specify source filters per file
+# pattern. A pattern will override the setting for FILTER_PATTERN (if any) and
+# it is also possible to disable source filtering for a specific pattern using
+# *.ext= (so without naming a filter).
+# This tag requires that the tag FILTER_SOURCE_FILES is set to YES.
+
+FILTER_SOURCE_PATTERNS =
+
+# If the USE_MDFILE_AS_MAINPAGE tag refers to the name of a markdown file that
+# is part of the input, its contents will be placed on the main page
+# (index.html). This can be useful if you have a project on for instance GitHub
+# and want to reuse the introduction page also for the doxygen output.
+
+USE_MDFILE_AS_MAINPAGE =
+
+#---------------------------------------------------------------------------
+# Configuration options related to source browsing
+#---------------------------------------------------------------------------
+
+# If the SOURCE_BROWSER tag is set to YES then a list of source files will be
+# generated. Documented entities will be cross-referenced with these sources.
+#
+# Note: To get rid of all source code in the generated output, make sure that
+# also VERBATIM_HEADERS is set to NO.
+# The default value is: NO.
+
+SOURCE_BROWSER = NO
+
+# Setting the INLINE_SOURCES tag to YES will include the body of functions,
+# classes and enums directly into the documentation.
+# The default value is: NO.
+
+INLINE_SOURCES = NO
+
+# Setting the STRIP_CODE_COMMENTS tag to YES will instruct doxygen to hide any
+# special comment blocks from generated source code fragments. Normal C, C++ and
+# Fortran comments will always remain visible.
+# The default value is: YES.
+
+STRIP_CODE_COMMENTS = YES
+
+# If the REFERENCED_BY_RELATION tag is set to YES then for each documented
+# function all documented functions referencing it will be listed.
+# The default value is: NO.
+
+REFERENCED_BY_RELATION = YES
+
+# If the REFERENCES_RELATION tag is set to YES then for each documented function
+# all documented entities called/used by that function will be listed.
+# The default value is: NO.
+
+REFERENCES_RELATION = YES
+
+# If the REFERENCES_LINK_SOURCE tag is set to YES and SOURCE_BROWSER tag is set
+# to YES then the hyperlinks from functions in REFERENCES_RELATION and
+# REFERENCED_BY_RELATION lists will link to the source code. Otherwise they will
+# link to the documentation.
+# The default value is: YES.
+
+REFERENCES_LINK_SOURCE = YES
+
+# If SOURCE_TOOLTIPS is enabled (the default) then hovering a hyperlink in the
+# source code will show a tooltip with additional information such as prototype,
+# brief description and links to the definition and documentation. Since this
+# will make the HTML file larger and loading of large files a bit slower, you
+# can opt to disable this feature.
+# The default value is: YES.
+# This tag requires that the tag SOURCE_BROWSER is set to YES.
+
+SOURCE_TOOLTIPS = YES
+
+# If the USE_HTAGS tag is set to YES then the references to source code will
+# point to the HTML generated by the htags(1) tool instead of doxygen built-in
+# source browser. The htags tool is part of GNU's global source tagging system
+# (see http://www.gnu.org/software/global/global.html). You will need version
+# 4.8.6 or higher.
+#
+# To use it do the following:
+# - Install the latest version of global
+# - Enable SOURCE_BROWSER and USE_HTAGS in the config file
+# - Make sure the INPUT points to the root of the source tree
+# - Run doxygen as normal
+#
+# Doxygen will invoke htags (and that will in turn invoke gtags), so these
+# tools must be available from the command line (i.e. in the search path).
+#
+# The result: instead of the source browser generated by doxygen, the links to
+# source code will now point to the output of htags.
+# The default value is: NO.
+# This tag requires that the tag SOURCE_BROWSER is set to YES.
+
+USE_HTAGS = NO
+
+# If the VERBATIM_HEADERS tag is set the YES then doxygen will generate a
+# verbatim copy of the header file for each class for which an include is
+# specified. Set to NO to disable this.
+# See also: Section \class.
+# The default value is: YES.
+
+VERBATIM_HEADERS = YES
+
+#---------------------------------------------------------------------------
+# Configuration options related to the alphabetical class index
+#---------------------------------------------------------------------------
+
+# If the ALPHABETICAL_INDEX tag is set to YES, an alphabetical index of all
+# compounds will be generated. Enable this if the project contains a lot of
+# classes, structs, unions or interfaces.
+# The default value is: YES.
+
+ALPHABETICAL_INDEX = YES
+
+# The COLS_IN_ALPHA_INDEX tag can be used to specify the number of columns in
+# which the alphabetical index list will be split.
+# Minimum value: 1, maximum value: 20, default value: 5.
+# This tag requires that the tag ALPHABETICAL_INDEX is set to YES.
+
+COLS_IN_ALPHA_INDEX = 2
+
+# In case all classes in a project start with a common prefix, all classes will
+# be put under the same header in the alphabetical index. The IGNORE_PREFIX tag
+# can be used to specify a prefix (or a list of prefixes) that should be ignored
+# while generating the index headers.
+# This tag requires that the tag ALPHABETICAL_INDEX is set to YES.
+
+IGNORE_PREFIX =
+
+#---------------------------------------------------------------------------
+# Configuration options related to the HTML output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_HTML tag is set to YES, doxygen will generate HTML output
+# The default value is: YES.
+
+GENERATE_HTML = YES
+
+# The HTML_OUTPUT tag is used to specify where the HTML docs will be put. If a
+# relative path is entered the value of OUTPUT_DIRECTORY will be put in front of
+# it.
+# The default directory is: html.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+HTML_OUTPUT = html
+
+# The HTML_FILE_EXTENSION tag can be used to specify the file extension for each
+# generated HTML page (for example: .htm, .php, .asp).
+# The default value is: .html.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+HTML_FILE_EXTENSION = .html
+
+# The HTML_HEADER tag can be used to specify a user-defined HTML header file for
+# each generated HTML page. If the tag is left blank doxygen will generate a
+# standard header.
+#
+# To get valid HTML the header file that includes any scripts and style sheets
+# that doxygen needs, which is dependent on the configuration options used (e.g.
+# the setting GENERATE_TREEVIEW). It is highly recommended to start with a
+# default header using
+# doxygen -w html new_header.html new_footer.html new_stylesheet.css
+# YourConfigFile
+# and then modify the file new_header.html. See also section "Doxygen usage"
+# for information on how to generate the default header that doxygen normally
+# uses.
+# Note: The header is subject to change so you typically have to regenerate the
+# default header when upgrading to a newer version of doxygen. For a description
+# of the possible markers and block names see the documentation.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+HTML_HEADER =
+
+# The HTML_FOOTER tag can be used to specify a user-defined HTML footer for each
+# generated HTML page. If the tag is left blank doxygen will generate a standard
+# footer. See HTML_HEADER for more information on how to generate a default
+# footer and what special commands can be used inside the footer. See also
+# section "Doxygen usage" for information on how to generate the default footer
+# that doxygen normally uses.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+HTML_FOOTER =
+
+# The HTML_STYLESHEET tag can be used to specify a user-defined cascading style
+# sheet that is used by each HTML page. It can be used to fine-tune the look of
+# the HTML output. If left blank doxygen will generate a default style sheet.
+# See also section "Doxygen usage" for information on how to generate the style
+# sheet that doxygen normally uses.
+# Note: It is recommended to use HTML_EXTRA_STYLESHEET instead of this tag, as
+# it is more robust and this tag (HTML_STYLESHEET) will in the future become
+# obsolete.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+HTML_STYLESHEET =
+
+# The HTML_EXTRA_STYLESHEET tag can be used to specify additional user-defined
+# cascading style sheets that are included after the standard style sheets
+# created by doxygen. Using this option one can overrule certain style aspects.
+# This is preferred over using HTML_STYLESHEET since it does not replace the
+# standard style sheet and is therefore more robust against future updates.
+# Doxygen will copy the style sheet files to the output directory.
+# Note: The order of the extra style sheet files is of importance (e.g. the last
+# style sheet in the list overrules the setting of the previous ones in the
+# list). For an example see the documentation.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+HTML_EXTRA_STYLESHEET =
+
+# The HTML_EXTRA_FILES tag can be used to specify one or more extra images or
+# other source files which should be copied to the HTML output directory. Note
+# that these files will be copied to the base HTML output directory. Use the
+# $relpath^ marker in the HTML_HEADER and/or HTML_FOOTER files to load these
+# files. In the HTML_STYLESHEET file, use the file name only. Also note that the
+# files will be copied as-is; there are no commands or markers available.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+HTML_EXTRA_FILES =
+
+# The HTML_COLORSTYLE_HUE tag controls the color of the HTML output. Doxygen
+# will adjust the colors in the style sheet and background images according to
+# this color. Hue is specified as an angle on a colorwheel, see
+# http://en.wikipedia.org/wiki/Hue for more information. For instance the value
+# 0 represents red, 60 is yellow, 120 is green, 180 is cyan, 240 is blue, 300
+# purple, and 360 is red again.
+# Minimum value: 0, maximum value: 359, default value: 220.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+HTML_COLORSTYLE_HUE = 220
+
+# The HTML_COLORSTYLE_SAT tag controls the purity (or saturation) of the colors
+# in the HTML output. For a value of 0 the output will use grayscales only. A
+# value of 255 will produce the most vivid colors.
+# Minimum value: 0, maximum value: 255, default value: 100.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+HTML_COLORSTYLE_SAT = 100
+
+# The HTML_COLORSTYLE_GAMMA tag controls the gamma correction applied to the
+# luminance component of the colors in the HTML output. Values below 100
+# gradually make the output lighter, whereas values above 100 make the output
+# darker. The value divided by 100 is the actual gamma applied, so 80 represents
+# a gamma of 0.8, The value 220 represents a gamma of 2.2, and 100 does not
+# change the gamma.
+# Minimum value: 40, maximum value: 240, default value: 80.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+HTML_COLORSTYLE_GAMMA = 80
+
+# If the HTML_TIMESTAMP tag is set to YES then the footer of each generated HTML
+# page will contain the date and time when the page was generated. Setting this
+# to YES can help to show when doxygen was last run and thus if the
+# documentation is up to date.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+HTML_TIMESTAMP = NO
+
+# If the HTML_DYNAMIC_SECTIONS tag is set to YES then the generated HTML
+# documentation will contain sections that can be hidden and shown after the
+# page has loaded.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+HTML_DYNAMIC_SECTIONS = NO
+
+# With HTML_INDEX_NUM_ENTRIES one can control the preferred number of entries
+# shown in the various tree structured indices initially; the user can expand
+# and collapse entries dynamically later on. Doxygen will expand the tree to
+# such a level that at most the specified number of entries are visible (unless
+# a fully collapsed tree already exceeds this amount). So setting the number of
+# entries 1 will produce a full collapsed tree by default. 0 is a special value
+# representing an infinite number of entries and will result in a full expanded
+# tree by default.
+# Minimum value: 0, maximum value: 9999, default value: 100.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+HTML_INDEX_NUM_ENTRIES = 100
+
+# If the GENERATE_DOCSET tag is set to YES, additional index files will be
+# generated that can be used as input for Apple's Xcode 3 integrated development
+# environment (see: http://developer.apple.com/tools/xcode/), introduced with
+# OSX 10.5 (Leopard). To create a documentation set, doxygen will generate a
+# Makefile in the HTML output directory. Running make will produce the docset in
+# that directory and running make install will install the docset in
+# ~/Library/Developer/Shared/Documentation/DocSets so that Xcode will find it at
+# startup. See http://developer.apple.com/tools/creatingdocsetswithdoxygen.html
+# for more information.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+GENERATE_DOCSET = NO
+
+# This tag determines the name of the docset feed. A documentation feed provides
+# an umbrella under which multiple documentation sets from a single provider
+# (such as a company or product suite) can be grouped.
+# The default value is: Doxygen generated docs.
+# This tag requires that the tag GENERATE_DOCSET is set to YES.
+
+DOCSET_FEEDNAME = "Doxygen generated docs"
+
+# This tag specifies a string that should uniquely identify the documentation
+# set bundle. This should be a reverse domain-name style string, e.g.
+# com.mycompany.MyDocSet. Doxygen will append .docset to the name.
+# The default value is: org.doxygen.Project.
+# This tag requires that the tag GENERATE_DOCSET is set to YES.
+
+DOCSET_BUNDLE_ID = org.doxygen.Project
+
+# The DOCSET_PUBLISHER_ID tag specifies a string that should uniquely identify
+# the documentation publisher. This should be a reverse domain-name style
+# string, e.g. com.mycompany.MyDocSet.documentation.
+# The default value is: org.doxygen.Publisher.
+# This tag requires that the tag GENERATE_DOCSET is set to YES.
+
+DOCSET_PUBLISHER_ID = org.doxygen.Publisher
+
+# The DOCSET_PUBLISHER_NAME tag identifies the documentation publisher.
+# The default value is: Publisher.
+# This tag requires that the tag GENERATE_DOCSET is set to YES.
+
+DOCSET_PUBLISHER_NAME = Publisher
+
+# If the GENERATE_HTMLHELP tag is set to YES then doxygen generates three
+# additional HTML index files: index.hhp, index.hhc, and index.hhk. The
+# index.hhp is a project file that can be read by Microsoft's HTML Help Workshop
+# (see: http://www.microsoft.com/en-us/download/details.aspx?id=21138) on
+# Windows.
+#
+# The HTML Help Workshop contains a compiler that can convert all HTML output
+# generated by doxygen into a single compiled HTML file (.chm). Compiled HTML
+# files are now used as the Windows 98 help format, and will replace the old
+# Windows help format (.hlp) on all Windows platforms in the future. Compressed
+# HTML files also contain an index, a table of contents, and you can search for
+# words in the documentation. The HTML workshop also contains a viewer for
+# compressed HTML files.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+GENERATE_HTMLHELP = NO
+
+# The CHM_FILE tag can be used to specify the file name of the resulting .chm
+# file. You can add a path in front of the file if the result should not be
+# written to the html output directory.
+# This tag requires that the tag GENERATE_HTMLHELP is set to YES.
+
+CHM_FILE =
+
+# The HHC_LOCATION tag can be used to specify the location (absolute path
+# including file name) of the HTML help compiler (hhc.exe). If non-empty,
+# doxygen will try to run the HTML help compiler on the generated index.hhp.
+# The file has to be specified with full path.
+# This tag requires that the tag GENERATE_HTMLHELP is set to YES.
+
+HHC_LOCATION =
+
+# The GENERATE_CHI flag controls if a separate .chi index file is generated
+# (YES) or that it should be included in the master .chm file (NO).
+# The default value is: NO.
+# This tag requires that the tag GENERATE_HTMLHELP is set to YES.
+
+GENERATE_CHI = NO
+
+# The CHM_INDEX_ENCODING is used to encode HtmlHelp index (hhk), content (hhc)
+# and project file content.
+# This tag requires that the tag GENERATE_HTMLHELP is set to YES.
+
+CHM_INDEX_ENCODING =
+
+# The BINARY_TOC flag controls whether a binary table of contents is generated
+# (YES) or a normal table of contents (NO) in the .chm file. Furthermore it
+# enables the Previous and Next buttons.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_HTMLHELP is set to YES.
+
+BINARY_TOC = NO
+
+# The TOC_EXPAND flag can be set to YES to add extra items for group members to
+# the table of contents of the HTML help documentation and to the tree view.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_HTMLHELP is set to YES.
+
+TOC_EXPAND = NO
+
+# If the GENERATE_QHP tag is set to YES and both QHP_NAMESPACE and
+# QHP_VIRTUAL_FOLDER are set, an additional index file will be generated that
+# can be used as input for Qt's qhelpgenerator to generate a Qt Compressed Help
+# (.qch) of the generated HTML documentation.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+GENERATE_QHP = NO
+
+# If the QHG_LOCATION tag is specified, the QCH_FILE tag can be used to specify
+# the file name of the resulting .qch file. The path specified is relative to
+# the HTML output folder.
+# This tag requires that the tag GENERATE_QHP is set to YES.
+
+QCH_FILE =
+
+# The QHP_NAMESPACE tag specifies the namespace to use when generating Qt Help
+# Project output. For more information please see Qt Help Project / Namespace
+# (see: http://qt-project.org/doc/qt-4.8/qthelpproject.html#namespace).
+# The default value is: org.doxygen.Project.
+# This tag requires that the tag GENERATE_QHP is set to YES.
+
+QHP_NAMESPACE =
+
+# The QHP_VIRTUAL_FOLDER tag specifies the namespace to use when generating Qt
+# Help Project output. For more information please see Qt Help Project / Virtual
+# Folders (see: http://qt-project.org/doc/qt-4.8/qthelpproject.html#virtual-
+# folders).
+# The default value is: doc.
+# This tag requires that the tag GENERATE_QHP is set to YES.
+
+QHP_VIRTUAL_FOLDER = doc
+
+# If the QHP_CUST_FILTER_NAME tag is set, it specifies the name of a custom
+# filter to add. For more information please see Qt Help Project / Custom
+# Filters (see: http://qt-project.org/doc/qt-4.8/qthelpproject.html#custom-
+# filters).
+# This tag requires that the tag GENERATE_QHP is set to YES.
+
+QHP_CUST_FILTER_NAME =
+
+# The QHP_CUST_FILTER_ATTRS tag specifies the list of the attributes of the
+# custom filter to add. For more information please see Qt Help Project / Custom
+# Filters (see: http://qt-project.org/doc/qt-4.8/qthelpproject.html#custom-
+# filters).
+# This tag requires that the tag GENERATE_QHP is set to YES.
+
+QHP_CUST_FILTER_ATTRS =
+
+# The QHP_SECT_FILTER_ATTRS tag specifies the list of the attributes this
+# project's filter section matches. Qt Help Project / Filter Attributes (see:
+# http://qt-project.org/doc/qt-4.8/qthelpproject.html#filter-attributes).
+# This tag requires that the tag GENERATE_QHP is set to YES.
+
+QHP_SECT_FILTER_ATTRS =
+
+# The QHG_LOCATION tag can be used to specify the location of Qt's
+# qhelpgenerator. If non-empty doxygen will try to run qhelpgenerator on the
+# generated .qhp file.
+# This tag requires that the tag GENERATE_QHP is set to YES.
+
+QHG_LOCATION =
+
+# If the GENERATE_ECLIPSEHELP tag is set to YES, additional index files will be
+# generated, together with the HTML files, they form an Eclipse help plugin. To
+# install this plugin and make it available under the help contents menu in
+# Eclipse, the contents of the directory containing the HTML and XML files needs
+# to be copied into the plugins directory of eclipse. The name of the directory
+# within the plugins directory should be the same as the ECLIPSE_DOC_ID value.
+# After copying Eclipse needs to be restarted before the help appears.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+GENERATE_ECLIPSEHELP = NO
+
+# A unique identifier for the Eclipse help plugin. When installing the plugin
+# the directory name containing the HTML and XML files should also have this
+# name. Each documentation set should have its own identifier.
+# The default value is: org.doxygen.Project.
+# This tag requires that the tag GENERATE_ECLIPSEHELP is set to YES.
+
+ECLIPSE_DOC_ID = org.doxygen.Project
+
+# If you want full control over the layout of the generated HTML pages it might
+# be necessary to disable the index and replace it with your own. The
+# DISABLE_INDEX tag can be used to turn on/off the condensed index (tabs) at top
+# of each HTML page. A value of NO enables the index and the value YES disables
+# it. Since the tabs in the index contain the same information as the navigation
+# tree, you can set this option to YES if you also set GENERATE_TREEVIEW to YES.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+DISABLE_INDEX = NO
+
+# The GENERATE_TREEVIEW tag is used to specify whether a tree-like index
+# structure should be generated to display hierarchical information. If the tag
+# value is set to YES, a side panel will be generated containing a tree-like
+# index structure (just like the one that is generated for HTML Help). For this
+# to work a browser that supports JavaScript, DHTML, CSS and frames is required
+# (i.e. any modern browser). Windows users are probably better off using the
+# HTML help feature. Via custom style sheets (see HTML_EXTRA_STYLESHEET) one can
+# further fine-tune the look of the index. As an example, the default style
+# sheet generated by doxygen has an example that shows how to put an image at
+# the root of the tree instead of the PROJECT_NAME. Since the tree basically has
+# the same information as the tab index, you could consider setting
+# DISABLE_INDEX to YES when enabling this option.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+GENERATE_TREEVIEW = NO
+
+# The ENUM_VALUES_PER_LINE tag can be used to set the number of enum values that
+# doxygen will group on one line in the generated HTML documentation.
+#
+# Note that a value of 0 will completely suppress the enum values from appearing
+# in the overview section.
+# Minimum value: 0, maximum value: 20, default value: 4.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+ENUM_VALUES_PER_LINE = 4
+
+# If the treeview is enabled (see GENERATE_TREEVIEW) then this tag can be used
+# to set the initial width (in pixels) of the frame in which the tree is shown.
+# Minimum value: 0, maximum value: 1500, default value: 250.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+TREEVIEW_WIDTH = 250
+
+# If the EXT_LINKS_IN_WINDOW option is set to YES, doxygen will open links to
+# external symbols imported via tag files in a separate window.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+EXT_LINKS_IN_WINDOW = NO
+
+# Use this tag to change the font size of LaTeX formulas included as images in
+# the HTML documentation. When you change the font size after a successful
+# doxygen run you need to manually remove any form_*.png images from the HTML
+# output directory to force them to be regenerated.
+# Minimum value: 8, maximum value: 50, default value: 10.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+FORMULA_FONTSIZE = 10
+
+# Use the FORMULA_TRANPARENT tag to determine whether or not the images
+# generated for formulas are transparent PNGs. Transparent PNGs are not
+# supported properly for IE 6.0, but are supported on all modern browsers.
+#
+# Note that when changing this option you need to delete any form_*.png files in
+# the HTML output directory before the changes have effect.
+# The default value is: YES.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+FORMULA_TRANSPARENT = YES
+
+# Enable the USE_MATHJAX option to render LaTeX formulas using MathJax (see
+# http://www.mathjax.org) which uses client side Javascript for the rendering
+# instead of using pre-rendered bitmaps. Use this if you do not have LaTeX
+# installed or if you want to formulas look prettier in the HTML output. When
+# enabled you may also need to install MathJax separately and configure the path
+# to it using the MATHJAX_RELPATH option.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+USE_MATHJAX = NO
+
+# When MathJax is enabled you can set the default output format to be used for
+# the MathJax output. See the MathJax site (see:
+# http://docs.mathjax.org/en/latest/output.html) for more details.
+# Possible values are: HTML-CSS (which is slower, but has the best
+# compatibility), NativeMML (i.e. MathML) and SVG.
+# The default value is: HTML-CSS.
+# This tag requires that the tag USE_MATHJAX is set to YES.
+
+MATHJAX_FORMAT = HTML-CSS
+
+# When MathJax is enabled you need to specify the location relative to the HTML
+# output directory using the MATHJAX_RELPATH option. The destination directory
+# should contain the MathJax.js script. For instance, if the mathjax directory
+# is located at the same level as the HTML output directory, then
+# MATHJAX_RELPATH should be ../mathjax. The default value points to the MathJax
+# Content Delivery Network so you can quickly see the result without installing
+# MathJax. However, it is strongly recommended to install a local copy of
+# MathJax from http://www.mathjax.org before deployment.
+# The default value is: http://cdn.mathjax.org/mathjax/latest.
+# This tag requires that the tag USE_MATHJAX is set to YES.
+
+MATHJAX_RELPATH = http://cdn.mathjax.org/mathjax/latest
+
+# The MATHJAX_EXTENSIONS tag can be used to specify one or more MathJax
+# extension names that should be enabled during MathJax rendering. For example
+# MATHJAX_EXTENSIONS = TeX/AMSmath TeX/AMSsymbols
+# This tag requires that the tag USE_MATHJAX is set to YES.
+
+MATHJAX_EXTENSIONS =
+
+# The MATHJAX_CODEFILE tag can be used to specify a file with javascript pieces
+# of code that will be used on startup of the MathJax code. See the MathJax site
+# (see: http://docs.mathjax.org/en/latest/output.html) for more details. For an
+# example see the documentation.
+# This tag requires that the tag USE_MATHJAX is set to YES.
+
+MATHJAX_CODEFILE =
+
+# When the SEARCHENGINE tag is enabled doxygen will generate a search box for
+# the HTML output. The underlying search engine uses javascript and DHTML and
+# should work on any modern browser. Note that when using HTML help
+# (GENERATE_HTMLHELP), Qt help (GENERATE_QHP), or docsets (GENERATE_DOCSET)
+# there is already a search function so this one should typically be disabled.
+# For large projects the javascript based search engine can be slow, then
+# enabling SERVER_BASED_SEARCH may provide a better solution. It is possible to
+# search using the keyboard; to jump to the search box use + S
+# (what the is depends on the OS and browser, but it is typically
+# , /
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.
+
+
Using mock_assert()
+assert_module.c
+
+#include <assert.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((int)(expression), #expression, __FILE__, __LINE__);
+#endif // UNIT_TESTING
+
+void increment_value(int * const value) {
+ assert(value);
+ (*value) ++;
+}
+
+void decrement_value(int * const value) {
+ if (value) {
+ *value --;
+ }
+}
+
+assert_module_test.c
+
+#include <stdarg.h>
+#include <stddef.h>
+#include <setjmp.h>
+#include <cmocka.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. */
+void increment_value_fail(void **state) {
+ increment_value(NULL);
+}
+
+// This test case succeeds since increment_value() asserts on the NULL pointer.
+void increment_value_assert(void **state) {
+ expect_assert_failure(increment_value(NULL));
+}
+
+/* This test case fails since decrement_value() doesn't assert on a NULL
+ * pointer. */
+void decrement_value_fail(void **state) {
+ expect_assert_failure(decrement_value(NULL));
+}
+
+int main(int argc, char *argv[]) {
+ const UnitTest tests[] = {
+ unit_test(increment_value_fail),
+ unit_test(increment_value_assert),
+ unit_test(decrement_value_fail),
+ };
+ return run_tests(tests);
+}
+
+
+
cmocka provides an assortment of assert macros that tests applications
+should use use in preference to the C standard library's assert 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.
+
+
Using assert_{type}_equal() macros
+assert_macro.c
+
+#include <string.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;
+}
+
+assert_macro_test.c
+
+#include <stdarg.h>
+#include <stddef.h>
+#include <setjmp.h>
+#include <cmocka.h>
+
+extern const char* get_status_code_string(const unsigned int status_code);
+extern unsigned int string_to_status_code(
+ const char* const status_code_string);
+
+/* This test will fail since the string returned by get_status_code_string(0)
+ * doesn't match "Connection timed out". */
+void get_status_code_string_test(void **state) {
+ 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
+void string_to_status_code_test(void **state) {
+ assert_int_equal(string_to_status_code("Address not found"), 0);
+ assert_int_equal(string_to_status_code("Connection timed out"), 1);
+}
+
+int main(int argc, char *argv[]) {
+ const UnitTest tests[] = {
+ unit_test(get_status_code_string_test),
+ unit_test(string_to_status_code_test),
+ };
+ return run_tests(tests);
+}
+
+
+
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.
A unit test should ideally isolate the function or module being tested
+from any external dependencies. This can be performed using mock functions
+that are either statically or dynamically linked with the module being tested.
+Mock functions must be statically linked when the code being tested directly
+references external functions. Dynamic linking is simply the process of
+setting a function pointer in a table used by the tested module to reference
+a mock function defined in the unit test.
In order to simplify the implementation of mock functions cmocka provides
+functionality which stores return values for mock functions in each test
+case using will_return(). These values are then returned by each mock
+function using calls to mock().
+
+Values passed to will_return() are added to a queue for each function
+specified. Each successive call to mock() from a function removes a
+return value from the queue. This makes it possible for a mock function to use
+multiple calls to mock() to return output parameters in addition to a
+return value. In addition this allows the specification of return values for
+multiple calls to a mock function.
+
+
Using will_return()
+database.h
+
+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);
+
+customer_database.c
+
+#include <stddef.h>
+#include <stdio.h>
+#include <database.h>
+#ifdef _WIN32
+#define snprintf _snprintf
+#endif // _WIN32
+
+// Connect to the database containing customer information.
+DatabaseConnection* connect_to_customer_database() {
+ return connect_to_database("customers.abcd.org", 321);
+}
+
+/* Find the ID of a customer by his/her name returning a value > 0 if
+ * successful, 0 otherwise. */
+unsigned int get_customer_id_by_name(
+ DatabaseConnection * const connection,
+ const char * const customer_name) {
+ char query_string[256];
+ int number_of_results;
+ void **results;
+ snprintf(query_string, sizeof(query_string),
+ "SELECT ID FROM CUSTOMERS WHERE NAME = %s", customer_name);
+ number_of_results = connection->query_database(connection, query_string,
+ &results);
+ if (number_of_results != 1) {
+ return -1;
+ }
+ return (unsigned int)results[0];
+}
+
+customer_database_test.c
+
+#include <stdarg.h>
+#include <stddef.h>
+#include <setjmp.h>
+#include <cmocka.h>
+#include <database.h>
+
+
+extern DatabaseConnection* connect_to_customer_database();
+extern unsigned int get_customer_id_by_name(
+ DatabaseConnection * const connection, const char * const customer_name);
+
+// Mock query database function.
+unsigned int mock_query_database(
+ DatabaseConnection* const connection, const char * const query_string,
+ void *** const results) {
+ *results = (void**)mock();
+ return (unsigned int)mock();
+}
+
+// Mock of the connect to database function.
+DatabaseConnection* connect_to_database(const char * const database_url,
+ const unsigned int port) {
+ return (DatabaseConnection*)mock();
+}
+
+void test_connect_to_customer_database(void **state) {
+ will_return(connect_to_database, 0x0DA7ABA53);
+ assert_true(connect_to_customer_database() ==
+ (DatabaseConnection*)0x0DA7ABA53);
+}
+
+/* This test fails as the mock function connect_to_database() will have no
+ * value to return. */
+void fail_connect_to_customer_database(void **state) {
+ will_return(connect_to_database, 0x0DA7ABA53);
+ assert_true(connect_to_customer_database() ==
+ (DatabaseConnection*)0x0DA7ABA53);
+}
+
+void test_get_customer_id_by_name(void **state) {
+ DatabaseConnection connection = {
+ "somedatabase.somewhere.com", 12345678, mock_query_database
+ };
+ // Return a single customer ID when mock_query_database() is called.
+ int customer_ids = 543;
+ will_return(mock_query_database, &customer_ids);
+ will_return(mock_query_database, 1);
+ assert_int_equal(get_customer_id_by_name(&connection, "john doe"), 543);
+}
+
+int main(int argc, char* argv[]) {
+ const UnitTest tests[] = {
+ unit_test(test_connect_to_customer_database),
+ unit_test(fail_connect_to_customer_database),
+ unit_test(test_get_customer_id_by_name),
+ };
+ return run_tests(tests);
+}
+
+
+
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.
+
+
Using expect_*()
+product_database.c
+
+#include <database.h>
+
+// Connect to the database containing customer information.
+DatabaseConnection* connect_to_product_database() {
+ return connect_to_database("products.abcd.org", 322);
+}
+
+product_database_test.c
+
+#include <stdarg.h>
+#include <stddef.h>
+#include <setjmp.h>
+#include <cmocka.h>
+#include <database.h>
+
+extern DatabaseConnection* connect_to_product_database();
+
+/* Mock connect to database function.
+ * NOTE: This mock function is very general could be shared between tests
+ * that use the imaginary database.h module. */
+DatabaseConnection* connect_to_database(const char * const url,
+ const unsigned int port) {
+ check_expected(url);
+ check_expected(port);
+ return (DatabaseConnection*)mock();
+}
+
+void test_connect_to_product_database(void **state) {
+ expect_string(connect_to_database, url, "products.abcd.org");
+ expect_value(connect_to_database, port, 322);
+ will_return(connect_to_database, 0xDA7ABA53);
+ assert_int_equal(connect_to_product_database(), 0xDA7ABA53);
+}
+
+/* This test will fail since the expected URL is different to the URL that is
+ * passed to connect_to_database() by connect_to_product_database(). */
+void test_connect_to_product_database_bad_url(void **state) {
+ expect_string(connect_to_database, url, "products.abcd.com");
+ expect_value(connect_to_database, port, 322);
+ will_return(connect_to_database, 0xDA7ABA53);
+ assert_int_equal((int)connect_to_product_database(), 0xDA7ABA53);
+}
+
+/* This test will fail since the mock connect_to_database() will attempt to
+ * retrieve a value for the parameter port which isn't specified by this
+ * test function. */
+void test_connect_to_product_database_missing_parameter(void **state) {
+ expect_string(connect_to_database, url, "products.abcd.org");
+ will_return(connect_to_database, 0xDA7ABA53);
+ assert_int_equal((int)connect_to_product_database(), 0xDA7ABA53);
+}
+
+int main(int argc, char* argv[]) {
+ const UnitTest tests[] = {
+ unit_test(test_connect_to_product_database),
+ unit_test(test_connect_to_product_database_bad_url),
+ unit_test(test_connect_to_product_database_missing_parameter),
+ };
+ return run_tests(tests);
+}
+
+
+
cmocka allows the specification of multiple setup and tear down functions
+for each test case. Setup functions, specified by the unit_test_setup()
+or unit_test_setup_teardown() macros allow common initialization to be
+shared between multiple test cases. In addition, tear down functions,
+specified by the unit_test_teardown() or
+unit_test_setup_teardown() macros provide a code path that is always
+executed for a test case even when it fails.
+
+
Using unit_test_setup_teardown()
+key_value.c
+
+#include <stddef.h>
+#include <stdlib.h>
+#include <string.h>
+
+typedef struct KeyValue {
+ unsigned int key;
+ const char* value;
+} KeyValue;
+
+static KeyValue *key_values = NULL;
+static unsigned int number_of_key_values = 0;
+
+void set_key_values(KeyValue * const new_key_values,
+ const unsigned int new_number_of_key_values) {
+ key_values = new_key_values;
+ number_of_key_values = new_number_of_key_values;
+}
+
+// Compare two key members of KeyValue structures.
+int key_value_compare_keys(const void *a, const void *b) {
+ return (int)((KeyValue*)a)->key - (int)((KeyValue*)b)->key;
+}
+
+// Search an array of key value pairs for the item with the specified value.
+KeyValue* find_item_by_value(const char * const value) {
+ unsigned int i;
+ for (i = 0; i < number_of_key_values; i++) {
+ if (strcmp(key_values[i].value, value) == 0) {
+ return &key_values[i];
+ }
+ }
+ return NULL;
+}
+
+// Sort an array of key value pairs by key.
+void sort_items_by_key() {
+ qsort(key_values, number_of_key_values, sizeof(*key_values),
+ key_value_compare_keys);
+}
+
+key_value_test.c
+
+#include <stdarg.h>
+#include <stddef.h>
+#include <setjmp.h>
+#include <string.h>
+#include <cmocka.h>
+
+/* This is duplicated here from the module setup_teardown.c to reduce the
+ * number of files used in this test. */
+typedef struct KeyValue {
+ unsigned int key;
+ const char* value;
+} KeyValue;
+
+void set_key_values(KeyValue * const new_key_values,
+ const unsigned int new_number_of_key_values);
+extern KeyValue* find_item_by_value(const char * const value);
+extern void sort_items_by_key();
+
+static KeyValue key_values[] = {
+ { 10, "this" },
+ { 52, "test" },
+ { 20, "a" },
+ { 13, "is" },
+};
+
+void create_key_values(void **state) {
+ KeyValue * const items = (KeyValue*)test_malloc(sizeof(key_values));
+ memcpy(items, key_values, sizeof(key_values));
+ *state = (void*)items;
+ set_key_values(items, sizeof(key_values) / sizeof(key_values[0]));
+}
+
+void destroy_key_values(void **state) {
+ test_free(*state);
+ set_key_values(NULL, 0);
+}
+
+void test_find_item_by_value(void **state) {
+ unsigned int i;
+ for (i = 0; i < sizeof(key_values) / sizeof(key_values[0]); i++) {
+ KeyValue * const found = find_item_by_value(key_values[i].value);
+ assert_true(found);
+ assert_int_equal(found->key, key_values[i].key);
+ assert_string_equal(found->value, key_values[i].value);
+ }
+}
+
+void test_sort_items_by_key(void **state) {
+ unsigned int i;
+ KeyValue * const kv = *state;
+ sort_items_by_key();
+ for (i = 1; i < sizeof(key_values) / sizeof(key_values[0]); i++) {
+ assert_true(kv[i - 1].key < kv[i].key);
+ }
+}
+
+int main(int argc, char* argv[]) {
+ const UnitTest tests[] = {
+ unit_test_setup_teardown(test_find_item_by_value, create_key_values,
+ destroy_key_values),
+ unit_test_setup_teardown(test_sort_items_by_key, create_key_values,
+ destroy_key_values),
+ };
+ return run_tests(tests);
+}
+
+
+
A small command line calculator
+calculator.c application
+and test application that full exercises the calculator application
+calculator_test.c
+are provided as an example of cmocka's features discussed in this document.
+
+
+
+
+ Last modified: Wed Jul 22 12:11:43 PDT 2009
+
diff --git a/emCmocka/doc/mainpage.dox b/emCmocka/doc/mainpage.dox
new file mode 100644
index 0000000..4c26d96
--- /dev/null
+++ b/emCmocka/doc/mainpage.dox
@@ -0,0 +1,133 @@
+/**
+
+@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, xUnit 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
+
+/* 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 and API to easily mock code.
+
+Learn more ...
+
+@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:
+
+
+
+@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 xUnit 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/emCmocka/example/CMakeLists.txt b/emCmocka/example/CMakeLists.txt
new file mode 100644
index 0000000..4951733
--- /dev/null
+++ b/emCmocka/example/CMakeLists.txt
@@ -0,0 +1,140 @@
+project(cmocka-examples C)
+
+include_directories(
+ ${CMAKE_BINARY_DIR}
+ ${CMAKE_CURRENT_SOURCE_DIR}
+ ${CMOCKA_PUBLIC_INCLUDE_DIRS}
+)
+
+set_source_files_properties(
+ calculator.c
+ allocate_module.c
+ assert_module.c
+ PROPERTIES
+ COMPILE_DEFINITIONS UNIT_TESTING=1)
+
+
+if (WIN32 OR CYGWIN OR MINGW)
+ set(CMOCKA_DLL_LIB ${CMAKE_BINARY_DIR}/src)
+ file(TO_NATIVE_PATH "${CMOCKA_DLL_PATH}" CMOCKA_DLL_PATH)
+ set(DLL_PATH_ENV "${CMOCKA_DLL_PATH};$ENV{PATH}")
+
+ #
+ # 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}")
+endif (WIN32 OR CYGWIN OR MINGW)
+
+
+### The most simple test
+add_executable(simple_test simple_test.c)
+target_link_libraries(simple_test ${CMOCKA_SHARED_LIBRARY})
+
+add_test(simple_test ${CMAKE_CURRENT_BINARY_DIR}/simple_test)
+if (WIN32 OR CYGWIN OR MINGW)
+ set_tests_properties(simple_test PROPERTIES ENVIRONMENT "PATH=${DLL_PATH_ENV}")
+endif (WIN32 OR CYGWIN OR MINGW)
+
+### Calulator test
+#TODO investigate dll jmp issue on MinGW
+if (NOT MINGW OR WITH_STATIC_LIB)
+ add_executable(calculator_test calculator.c calculator_test.c)
+ add_test(calculator_test ${CMAKE_CURRENT_BINARY_DIR}/calculator_test)
+ if (WIN32 OR CYGWIN)
+ set_tests_properties(calculator_test PROPERTIES ENVIRONMENT "PATH=${DLL_PATH_ENV}")
+ endif (WIN32 OR CYGWIN)
+
+ if (MINGW)
+ target_link_libraries(calculator_test ${CMOCKA_STATIC_LIBRARY})
+ else (MINGW)
+ target_link_libraries(calculator_test ${CMOCKA_SHARED_LIBRARY})
+ endif (MINGW)
+
+ if (WIN32 OR CYGWIN OR MINGW)
+ set_tests_properties(calculator_test PROPERTIES ENVIRONMENT "PATH=${DLL_PATH_ENV}")
+ endif (WIN32 OR CYGWIN OR MINGW)
+endif (NOT MINGW OR WITH_STATIC_LIB)
+
+### Allocate module test
+add_executable(allocate_module_test allocate_module.c allocate_module_test.c)
+target_link_libraries(allocate_module_test ${CMOCKA_SHARED_LIBRARY})
+
+# This is a test that should detect leaks and overflows and will fail for that
+add_test(allocate_module_test ${CMAKE_CURRENT_BINARY_DIR}/allocate_module_test)
+if (WIN32 OR CYGWIN OR MINGW)
+ set_tests_properties(allocate_module_test PROPERTIES ENVIRONMENT "PATH=${DLL_PATH_ENV}")
+endif (WIN32 OR CYGWIN OR MINGW)
+
+set_tests_properties(
+ allocate_module_test
+ PROPERTIES
+ WILL_FAIL 1
+)
+
+### Assert macro test
+add_executable(assert_macro_test assert_macro.c assert_macro_test.c)
+target_link_libraries(assert_macro_test ${CMOCKA_SHARED_LIBRARY})
+
+add_test(assert_macro_test ${CMAKE_CURRENT_BINARY_DIR}/assert_macro_test)
+set_tests_properties(
+ assert_macro_test
+ PROPERTIES
+ WILL_FAIL 1
+)
+if (WIN32 OR CYGWIN OR MINGW)
+ set_tests_properties(assert_macro_test PROPERTIES ENVIRONMENT "PATH=${DLL_PATH_ENV}")
+endif (WIN32 OR CYGWIN OR MINGW)
+
+### Assert module test
+add_executable(assert_module_test assert_module.c assert_module_test.c)
+target_link_libraries(assert_module_test ${CMOCKA_SHARED_LIBRARY})
+
+add_test(assert_module_test ${CMAKE_CURRENT_BINARY_DIR}/assert_module_test)
+set_tests_properties(
+ assert_module_test
+ PROPERTIES
+ WILL_FAIL 1
+)
+if (WIN32 OR CYGWIN OR MINGW)
+ set_tests_properties(assert_module_test PROPERTIES ENVIRONMENT "PATH=${DLL_PATH_ENV}")
+endif (WIN32 OR CYGWIN OR MINGW)
+
+### Customer database test
+add_executable(customer_database_test customer_database.c customer_database_test.c)
+target_link_libraries(customer_database_test ${CMOCKA_SHARED_LIBRARY})
+
+add_test(customer_database_test ${CMAKE_CURRENT_BINARY_DIR}/customer_database_test)
+if (WIN32 OR CYGWIN OR MINGW)
+ set_tests_properties(customer_database_test PROPERTIES ENVIRONMENT "PATH=${DLL_PATH_ENV}")
+endif (WIN32 OR CYGWIN OR MINGW)
+
+### Key Value Test
+add_executable(key_value_test key_value.c key_value_test.c)
+target_link_libraries(key_value_test ${CMOCKA_SHARED_LIBRARY})
+
+add_test(key_value_test ${CMAKE_CURRENT_BINARY_DIR}/key_value_test)
+if (WIN32 OR CYGWIN OR MINGW)
+ set_tests_properties(key_value_test PROPERTIES ENVIRONMENT "PATH=${DLL_PATH_ENV}")
+endif (WIN32 OR CYGWIN OR MINGW)
+
+### Product database test
+add_executable(product_database_test product_database.c product_database_test.c)
+target_link_libraries(product_database_test ${CMOCKA_SHARED_LIBRARY})
+
+add_test(product_database_test ${CMAKE_CURRENT_BINARY_DIR}/product_database_test)
+set_tests_properties(
+ product_database_test
+ PROPERTIES
+ PASS_REGULAR_EXPRESSION
+ "\\[ FAILED \\] 2 test"
+)
+if (WIN32 OR CYGWIN OR MINGW)
+ set_tests_properties(product_database_test PROPERTIES ENVIRONMENT "PATH=${DLL_PATH_ENV}")
+endif (WIN32 OR CYGWIN OR MINGW)
+
+# TODO Execute "$CMAKE_LINKER --help" and check for --wrap
+if (${CMAKE_C_COMPILER_ID} MATCHES "(GNU|Clang)" AND NOT APPLE)
+ add_subdirectory(chef_wrap)
+endif()
diff --git a/emCmocka/example/allocate_module.c b/emCmocka/example/allocate_module.c
new file mode 100644
index 0000000..3c4fb49
--- /dev/null
+++ b/emCmocka/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/emCmocka/example/allocate_module_test.c b/emCmocka/example/allocate_module_test.c
new file mode 100644
index 0000000..562aea2
--- /dev/null
+++ b/emCmocka/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/emCmocka/example/assert_macro.c b/emCmocka/example/assert_macro.c
new file mode 100644
index 0000000..9590590
--- /dev/null
+++ b/emCmocka/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/emCmocka/example/assert_macro.h b/emCmocka/example/assert_macro.h
new file mode 100644
index 0000000..789380c
--- /dev/null
+++ b/emCmocka/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/emCmocka/example/assert_macro_test.c b/emCmocka/example/assert_macro_test.c
new file mode 100644
index 0000000..2cd355c
--- /dev/null
+++ b/emCmocka/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/emCmocka/example/assert_module.c b/emCmocka/example/assert_module.c
new file mode 100644
index 0000000..381069b
--- /dev/null
+++ b/emCmocka/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/emCmocka/example/assert_module.h b/emCmocka/example/assert_module.h
new file mode 100644
index 0000000..b68b4d9
--- /dev/null
+++ b/emCmocka/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/emCmocka/example/assert_module_test.c b/emCmocka/example/assert_module_test.c
new file mode 100644
index 0000000..f387754
--- /dev/null
+++ b/emCmocka/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/emCmocka/example/calculator.c b/emCmocka/example/calculator.c
new file mode 100644
index 0000000..307b551
--- /dev/null
+++ b/emCmocka/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/emCmocka/example/calculator_test.c b/emCmocka/example/calculator_test.c
new file mode 100644
index 0000000..ab8cad8
--- /dev/null
+++ b/emCmocka/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/emCmocka/example/chef_wrap/CMakeLists.txt b/emCmocka/example/chef_wrap/CMakeLists.txt
new file mode 100644
index 0000000..68afec0
--- /dev/null
+++ b/emCmocka/example/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_SHARED_LIBRARY})
+
+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/emCmocka/example/chef_wrap/chef.c b/emCmocka/example/chef_wrap/chef.c
new file mode 100644
index 0000000..1429cde
--- /dev/null
+++ b/emCmocka/example/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/emCmocka/example/chef_wrap/chef.h b/emCmocka/example/chef_wrap/chef.h
new file mode 100644
index 0000000..c1a01c7
--- /dev/null
+++ b/emCmocka/example/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/emCmocka/example/chef_wrap/waiter_test_wrap.c b/emCmocka/example/chef_wrap/waiter_test_wrap.c
new file mode 100644
index 0000000..4146818
--- /dev/null
+++ b/emCmocka/example/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/emCmocka/example/chef_wrap/waiter_test_wrap.h b/emCmocka/example/chef_wrap/waiter_test_wrap.h
new file mode 100644
index 0000000..9178ca2
--- /dev/null
+++ b/emCmocka/example/chef_wrap/waiter_test_wrap.h
@@ -0,0 +1,2 @@
+
+int __wrap_chef_cook(const char *order, char **dish_out);
diff --git a/emCmocka/example/customer_database.c b/emCmocka/example/customer_database.c
new file mode 100644
index 0000000..2d49e19
--- /dev/null
+++ b/emCmocka/example/customer_database.c
@@ -0,0 +1,51 @@
+/*
+ * 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
+#ifdef _WIN32
+#define snprintf _snprintf
+#endif /* _WIN32 */
+
+DatabaseConnection* connect_to_customer_database(void);
+unsigned int get_customer_id_by_name(
+ DatabaseConnection * const connection,
+ const char * const customer_name);
+
+/* Connect to the database containing customer information. */
+DatabaseConnection* connect_to_customer_database(void) {
+ return connect_to_database("customers.abcd.org", 321);
+}
+
+/* Find the ID of a customer by his/her name returning a value > 0 if
+ * successful, 0 otherwise. */
+unsigned int get_customer_id_by_name(
+ DatabaseConnection * const connection,
+ const char * const customer_name) {
+ char query_string[256];
+ int number_of_results;
+ void **results;
+ snprintf(query_string, sizeof(query_string),
+ "SELECT ID FROM CUSTOMERS WHERE NAME = %s", customer_name);
+ number_of_results = connection->query_database(connection, query_string,
+ &results);
+
+ if (number_of_results != 1) {
+ return -1;
+ }
+
+ return (unsigned int)*((int *)results);
+}
diff --git a/emCmocka/example/customer_database_test.c b/emCmocka/example/customer_database_test.c
new file mode 100644
index 0000000..45ec782
--- /dev/null
+++ b/emCmocka/example/customer_database_test.c
@@ -0,0 +1,89 @@
+/*
+ * 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
+
+extern DatabaseConnection* connect_to_customer_database(void);
+extern unsigned int get_customer_id_by_name(
+ DatabaseConnection * const connection, const char * const customer_name);
+
+/* Mock query database function. */
+static unsigned int mock_query_database(DatabaseConnection* const connection,
+ const char * const query_string,
+ void *** const results) {
+ (void) connection; /* unused */
+ (void) query_string; /* unused */
+
+ *results = (void **)mock_ptr_type(int *);
+ return mock_ptr_type(int);
+}
+
+/* Mock of the connect to database function. */
+DatabaseConnection* connect_to_database(const char * const database_url,
+ const unsigned int port) {
+ (void) database_url; /* unused */
+ (void) port; /* unused */
+
+ return (DatabaseConnection*)((size_t)mock());
+}
+
+static void test_connect_to_customer_database(void **state) {
+ (void) state; /* unused */
+
+ will_return(connect_to_database, 0x0DA7ABA53);
+
+ assert_int_equal((size_t)connect_to_customer_database(), 0x0DA7ABA53);
+}
+
+/* This test fails as the mock function connect_to_database() will have no
+ * value to return. */
+#if 0
+static void fail_connect_to_customer_database(void **state) {
+ (void) state; /* unused */
+
+ assert_true(connect_to_customer_database() ==
+ (DatabaseConnection*)0x0DA7ABA53);
+}
+#endif
+
+static void test_get_customer_id_by_name(void **state) {
+ DatabaseConnection connection = {
+ "somedatabase.somewhere.com", 12345678, mock_query_database
+ };
+ /* Return a single customer ID when mock_query_database() is called. */
+ int customer_ids = 543;
+ int rc;
+
+ (void) state; /* unused */
+
+ will_return(mock_query_database,
+ cast_ptr_to_largest_integral_type(&customer_ids));
+ will_return(mock_query_database, 1);
+
+ rc = get_customer_id_by_name(&connection, "john doe");
+ assert_int_equal(rc, 543);
+}
+
+int main(void) {
+ const struct CMUnitTest tests[] = {
+ cmocka_unit_test(test_connect_to_customer_database),
+ cmocka_unit_test(test_get_customer_id_by_name),
+ };
+ return cmocka_run_group_tests(tests, NULL, NULL);
+}
diff --git a/emCmocka/example/database.h b/emCmocka/example/database.h
new file mode 100644
index 0000000..880db3c
--- /dev/null
+++ b/emCmocka/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/emCmocka/example/key_value.c b/emCmocka/example/key_value.c
new file mode 100644
index 0000000..057274a
--- /dev/null
+++ b/emCmocka/example/key_value.c
@@ -0,0 +1,51 @@
+/*
+ * 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 "key_value.h"
+
+static KeyValue *key_values = NULL;
+static unsigned int number_of_key_values = 0;
+
+void set_key_values(KeyValue * const new_key_values,
+ const unsigned int new_number_of_key_values) {
+ key_values = new_key_values;
+ number_of_key_values = new_number_of_key_values;
+}
+
+/* Compare two key members of KeyValue structures. */
+static int key_value_compare_keys(const void *a, const void *b) {
+ return (int)((KeyValue*)a)->key - (int)((KeyValue*)b)->key;
+}
+
+/* Search an array of key value pairs for the item with the specified value. */
+KeyValue* find_item_by_value(const char * const value) {
+ unsigned int i;
+ for (i = 0; i < number_of_key_values; i++) {
+ if (strcmp(key_values[i].value, value) == 0) {
+ return &key_values[i];
+ }
+ }
+ return NULL;
+}
+
+/* Sort an array of key value pairs by key. */
+void sort_items_by_key(void) {
+ qsort(key_values, number_of_key_values, sizeof(*key_values),
+ key_value_compare_keys);
+}
diff --git a/emCmocka/example/key_value.h b/emCmocka/example/key_value.h
new file mode 100644
index 0000000..736faf2
--- /dev/null
+++ b/emCmocka/example/key_value.h
@@ -0,0 +1,27 @@
+/*
+ * 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 KeyValue {
+ unsigned int key;
+ const char* value;
+} KeyValue;
+
+void set_key_values(KeyValue * const new_key_values,
+ const unsigned int new_number_of_key_values);
+
+KeyValue* find_item_by_value(const char * const value);
+
+void sort_items_by_key(void);
diff --git a/emCmocka/example/key_value_test.c b/emCmocka/example/key_value_test.c
new file mode 100644
index 0000000..102a2be
--- /dev/null
+++ b/emCmocka/example/key_value_test.c
@@ -0,0 +1,77 @@
+/*
+ * 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
+
+#include "key_value.h"
+
+static KeyValue key_values[] = {
+ { 10, "this" },
+ { 52, "test" },
+ { 20, "a" },
+ { 13, "is" },
+};
+
+static int create_key_values(void **state) {
+ KeyValue * const items = (KeyValue*)test_malloc(sizeof(key_values));
+ memcpy(items, key_values, sizeof(key_values));
+ *state = (void*)items;
+ set_key_values(items, sizeof(key_values) / sizeof(key_values[0]));
+
+ return 0;
+}
+
+static int destroy_key_values(void **state) {
+ test_free(*state);
+ set_key_values(NULL, 0);
+
+ return 0;
+}
+
+static void test_find_item_by_value(void **state) {
+ unsigned int i;
+
+ (void) state; /* unused */
+
+ for (i = 0; i < sizeof(key_values) / sizeof(key_values[0]); i++) {
+ KeyValue * const found = find_item_by_value(key_values[i].value);
+ assert_true(found != NULL);
+ assert_int_equal(found->key, key_values[i].key);
+ assert_string_equal(found->value, key_values[i].value);
+ }
+}
+
+static void test_sort_items_by_key(void **state) {
+ unsigned int i;
+ KeyValue * const kv = *state;
+ sort_items_by_key();
+ for (i = 1; i < sizeof(key_values) / sizeof(key_values[0]); i++) {
+ assert_true(kv[i - 1].key < kv[i].key);
+ }
+}
+
+int main(void) {
+ const struct CMUnitTest tests[] = {
+ cmocka_unit_test_setup_teardown(test_find_item_by_value,
+ create_key_values, destroy_key_values),
+ cmocka_unit_test_setup_teardown(test_sort_items_by_key,
+ create_key_values, destroy_key_values),
+ };
+ return cmocka_run_group_tests(tests, NULL, NULL);
+}
diff --git a/emCmocka/example/product_database.c b/emCmocka/example/product_database.c
new file mode 100644
index 0000000..980b7e5
--- /dev/null
+++ b/emCmocka/example/product_database.c
@@ -0,0 +1,24 @@
+/*
+ * 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
+
+DatabaseConnection* connect_to_product_database(void);
+
+/* Connect to the database containing customer information. */
+DatabaseConnection* connect_to_product_database(void) {
+ return connect_to_database("products.abcd.org", 322);
+}
+
diff --git a/emCmocka/example/product_database_test.c b/emCmocka/example/product_database_test.c
new file mode 100644
index 0000000..e09eeab
--- /dev/null
+++ b/emCmocka/example/product_database_test.c
@@ -0,0 +1,72 @@
+/*
+ * 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
+
+extern DatabaseConnection* connect_to_product_database(void);
+
+/* Mock connect to database function.
+ * NOTE: This mock function is very general could be shared between tests
+ * that use the imaginary database.h module. */
+DatabaseConnection* connect_to_database(const char * const url,
+ const unsigned int port) {
+ check_expected_ptr(url);
+ check_expected(port);
+ return (DatabaseConnection*)((size_t)mock());
+}
+
+static void test_connect_to_product_database(void **state) {
+ (void) state; /* unused */
+
+ expect_string(connect_to_database, url, "products.abcd.org");
+ expect_value(connect_to_database, port, 322);
+ will_return(connect_to_database, 0xDA7ABA53);
+ assert_int_equal((size_t)connect_to_product_database(), 0xDA7ABA53);
+}
+
+/* This test will fail since the expected URL is different to the URL that is
+ * passed to connect_to_database() by connect_to_product_database(). */
+static void test_connect_to_product_database_bad_url(void **state) {
+ (void) state; /* unused */
+
+ expect_string(connect_to_database, url, "products.abcd.com");
+ expect_value(connect_to_database, port, 322);
+ will_return(connect_to_database, 0xDA7ABA53);
+ assert_int_equal((size_t)connect_to_product_database(), 0xDA7ABA53);
+}
+
+/* This test will fail since the mock connect_to_database() will attempt to
+ * retrieve a value for the parameter port which isn't specified by this
+ * test function. */
+static void test_connect_to_product_database_missing_parameter(void **state) {
+ (void) state; /* unused */
+
+ expect_string(connect_to_database, url, "products.abcd.org");
+ will_return(connect_to_database, 0xDA7ABA53);
+ assert_int_equal((size_t)connect_to_product_database(), 0xDA7ABA53);
+}
+
+int main(void) {
+ const struct CMUnitTest tests[] = {
+ cmocka_unit_test(test_connect_to_product_database),
+ cmocka_unit_test(test_connect_to_product_database_bad_url),
+ cmocka_unit_test(test_connect_to_product_database_missing_parameter),
+ };
+ return cmocka_run_group_tests(tests, NULL, NULL);
+}
diff --git a/emCmocka/example/simple_test.c b/emCmocka/example/simple_test.c
new file mode 100644
index 0000000..c6eee9c
--- /dev/null
+++ b/emCmocka/example/simple_test.c
@@ -0,0 +1,17 @@
+#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/emCmocka/example/src_example/Makefile b/emCmocka/example/src_example/Makefile
new file mode 100644
index 0000000..1856aba
--- /dev/null
+++ b/emCmocka/example/src_example/Makefile
@@ -0,0 +1,10 @@
+DEFS_TO_REMOVE=-DHAVE_SETJMP_H -DHAVE_STDIO_H
+
+all:
+ gcc -I../../include $(DEFS_TO_REMOVE) -o cmocka.o -c ../../src/cmocka.c
+ gcc -I../../include -o simple_test.o -c simple_test.c
+ gcc -o a.out cmocka.o simple_test.o
+
+clean:
+ rm -rf *.o
+ rm -rf a.out
\ No newline at end of file
diff --git a/emCmocka/example/src_example/simple_test.c b/emCmocka/example/src_example/simple_test.c
new file mode 100644
index 0000000..c6eee9c
--- /dev/null
+++ b/emCmocka/example/src_example/simple_test.c
@@ -0,0 +1,17 @@
+#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/emCmocka/include/CMakeLists.txt b/emCmocka/include/CMakeLists.txt
new file mode 100644
index 0000000..4cca031
--- /dev/null
+++ b/emCmocka/include/CMakeLists.txt
@@ -0,0 +1,27 @@
+project(cmocka-headers C)
+
+set(cmocka_HDRS
+ cmocka.h
+ cmocka_pbc.h
+)
+
+install(
+ FILES
+ ${cmocka_HDRS}
+ DESTINATION
+ ${INCLUDE_INSTALL_DIR}
+ COMPONENT
+ headers
+)
+
+if (WITH_CMOCKERY_SUPPORT)
+ install(
+ FILES
+ cmockery/cmockery.h
+ cmockery/pbc.h
+ DESTINATION
+ ${INCLUDE_INSTALL_DIR}/cmockery
+ COMPONENT
+ headers
+ )
+endif()
diff --git a/emCmocka/include/cmocka.h b/emCmocka/include/cmocka.h
new file mode 100644
index 0000000..b49dbf8
--- /dev/null
+++ b/emCmocka/include/cmocka.h
@@ -0,0 +1,2284 @@
+/*
+ * Copyright 2008 Google Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#ifndef CMOCKA_H_
+#define CMOCKA_H_
+
+#ifdef _WIN32
+# ifdef _MSC_VER
+
+#define __func__ __FUNCTION__
+
+# ifndef inline
+#define inline __inline
+# endif /* inline */
+
+# if _MSC_VER < 1500
+# ifdef __cplusplus
+extern "C" {
+# endif /* __cplusplus */
+int __stdcall IsDebuggerPresent();
+# ifdef __cplusplus
+} /* extern "C" */
+# endif /* __cplusplus */
+# endif /* _MSC_VER < 1500 */
+# endif /* _MSC_VER */
+#endif /* _WIN32 */
+
+/**
+ * @defgroup cmocka The CMocka API
+ *
+ * These headers or their equivalents should be included prior to including
+ * this header file.
+ * @code
+ * #include
+ * #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__)
+# define __WORDSIZE 64
+# else
+# define __WORDSIZE 32
+# endif
+#endif
+
+#ifdef DOXYGEN
+/**
+ * Largest integral type. This type should be large enough to hold any
+ * pointer or integer supported by the compiler.
+ */
+typedef uintmax_t LargestIntegralType;
+#else /* DOXGEN */
+#ifndef LargestIntegralType
+# if __WORDSIZE == 64 && !defined(_WIN64)
+# define LargestIntegralType unsigned long int
+# else
+# define LargestIntegralType unsigned long long int
+# endif
+#endif /* LargestIntegralType */
+#endif /* DOXYGEN */
+
+/* Printf format used to display LargestIntegralType as a hexidecimal. */
+#ifndef LargestIntegralTypePrintfFormat
+# ifdef _WIN32
+# define LargestIntegralTypePrintfFormat "0x%I64x"
+# else
+# if __WORDSIZE == 64
+# define LargestIntegralTypePrintfFormat "%#lx"
+# else
+# define LargestIntegralTypePrintfFormat "%#llx"
+# endif
+# endif /* _WIN32 */
+#endif /* LargestIntegralTypePrintfFormat */
+
+/* Printf format used to display LargestIntegralType as a decimal. */
+#ifndef LargestIntegralTypePrintfFormatDecimal
+# ifdef _WIN32
+# define LargestIntegralTypePrintfFormatDecimal "%I64u"
+# else
+# if __WORDSIZE == 64
+# define LargestIntegralTypePrintfFormatDecimal "%lu"
+# else
+# define LargestIntegralTypePrintfFormatDecimal "%llu"
+# endif
+# endif /* _WIN32 */
+#endif /* LargestIntegralTypePrintfFormat */
+
+/* Perform an unsigned cast to LargestIntegralType. */
+#define cast_to_largest_integral_type(value) \
+ ((LargestIntegralType)(value))
+
+/* Smallest integral type capable of holding a pointer. */
+#if !defined(_UINTPTR_T) && !defined(_UINTPTR_T_DEFINED)
+# if defined(_WIN32)
+ /* WIN32 is an ILP32 platform */
+ typedef unsigned int uintptr_t;
+# elif defined(_WIN64)
+ typedef unsigned long int uintptr_t
+# else /* _WIN32 */
+
+/* ILP32 and LP64 platforms */
+# ifdef __WORDSIZE /* glibc */
+# if __WORDSIZE == 64
+ typedef unsigned long int uintptr_t;
+# else
+ typedef unsigned int uintptr_t;
+# endif /* __WORDSIZE == 64 */
+# else /* __WORDSIZE */
+# if defined(_LP64) || defined(_I32LPx)
+ typedef unsigned long int uintptr_t;
+# else
+ typedef unsigned int uintptr_t;
+# endif
+# endif /* __WORDSIZE */
+# endif /* _WIN32 */
+
+# define _UINTPTR_T
+# define _UINTPTR_T_DEFINED
+#endif /* !defined(_UINTPTR_T) || !defined(_UINTPTR_T_DEFINED) */
+
+/* Perform an unsigned cast to uintptr_t. */
+#define cast_to_pointer_integral_type(value) \
+ ((uintptr_t)((size_t)(value)))
+
+/* Perform a cast of a pointer to LargestIntegralType */
+#define cast_ptr_to_largest_integral_type(value) \
+cast_to_largest_integral_type(cast_to_pointer_integral_type(value))
+
+/* GCC have printf type attribute check. */
+#ifdef __GNUC__
+#define CMOCKA_PRINTF_ATTRIBUTE(a,b) \
+ __attribute__ ((__format__ (__printf__, a, b)))
+#else
+#define CMOCKA_PRINTF_ATTRIBUTE(a,b)
+#endif /* __GNUC__ */
+
+#if defined(__GNUC__)
+#define CMOCKA_DEPRECATED __attribute__ ((deprecated))
+#elif defined(_MSC_VER)
+#define CMOCKA_DEPRECATED __declspec(deprecated)
+#else
+#define CMOCKA_DEPRECATED
+#endif
+
+#define WILL_RETURN_ALWAYS -1
+#define WILL_RETURN_ONCE -2
+
+/**
+ * @defgroup cmocka_mock Mock Objects
+ * @ingroup cmocka
+ *
+ * Mock objects mock objects are simulated objects that mimic the behavior of
+ * real objects. Instead of calling the real objects, the tested object calls a
+ * mock object that merely asserts that the correct methods were called, with
+ * the expected parameters, in the correct order.
+ *
+ *
+ *
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 at 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 at a look at
+ * 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 value.
+ *
+ * The event is triggered by calling check_expected() in the mocked function.
+ *
+ * @param[in] #function The function to add the check for.
+ *
+ * @param[in] #parameter The name of the parameter passed to the function.
+ *
+ * @param[in] value The value to check.
+ *
+ * @see check_expected().
+ */
+void expect_value(#function, #parameter, LargestIntegralType value);
+#else
+#define expect_value(function, parameter, value) \
+ expect_value_count(function, parameter, value, 1)
+#endif
+
+#ifdef DOXYGEN
+/**
+ * @brief Add an event to repeatedly check if a parameter is the given value.
+ *
+ * The event is triggered by calling check_expected() in the mocked function.
+ *
+ * @param[in] #function The function to add the check for.
+ *
+ * @param[in] #parameter The name of the parameter passed to the function.
+ *
+ * @param[in] value The value to check.
+ *
+ * @param[in] count The count parameter returns the number of times the value
+ * should be returned by check_expected(). If count is set
+ * to -1 the value will always be returned.
+ *
+ * @see check_expected().
+ */
+void expect_value_count(#function, #parameter, LargestIntegralType value, size_t count);
+#else
+#define expect_value_count(function, parameter, value, count) \
+ _expect_value(#function, #parameter, __FILE__, __LINE__, \
+ cast_to_largest_integral_type(value), count)
+#endif
+
+#ifdef DOXYGEN
+/**
+ * @brief Add an event to check if a parameter isn't the given value.
+ *
+ * The event is triggered by calling check_expected() in the mocked function.
+ *
+ * @param[in] #function The function to add the check for.
+ *
+ * @param[in] #parameter The name of the parameter passed to the function.
+ *
+ * @param[in] value The value to check.
+ *
+ * @see check_expected().
+ */
+void expect_not_value(#function, #parameter, LargestIntegralType value);
+#else
+#define expect_not_value(function, parameter, value) \
+ expect_not_value_count(function, parameter, value, 1)
+#endif
+
+#ifdef DOXYGEN
+/**
+ * @brief Add an event to repeatedly check if a parameter isn't the given value.
+ *
+ * The event is triggered by calling check_expected() in the mocked function.
+ *
+ * @param[in] #function The function to add the check for.
+ *
+ * @param[in] #parameter The name of the parameter passed to the function.
+ *
+ * @param[in] value The value to check.
+ *
+ * @param[in] count The count parameter returns the number of times the value
+ * should be returned by check_expected(). If count is set
+ * to -1 the value will always be returned.
+ *
+ * @see check_expected().
+ */
+void expect_not_value_count(#function, #parameter, LargestIntegralType value, size_t count);
+#else
+#define expect_not_value_count(function, parameter, value, count) \
+ _expect_not_value(#function, #parameter, __FILE__, __LINE__, \
+ cast_to_largest_integral_type(value), count)
+#endif
+
+#ifdef DOXYGEN
+/**
+ * @brief Add an event to check if the parameter value is equal to the
+ * provided string.
+ *
+ * The event is triggered by calling check_expected() in the mocked function.
+ *
+ * @param[in] #function The function to add the check for.
+ *
+ * @param[in] #parameter The name of the parameter passed to the function.
+ *
+ * @param[in] string The string value to compare.
+ *
+ * @see check_expected().
+ */
+void expect_string(#function, #parameter, const char *string);
+#else
+#define expect_string(function, parameter, string) \
+ expect_string_count(function, parameter, string, 1)
+#endif
+
+#ifdef DOXYGEN
+/**
+ * @brief Add an event to check if the parameter value is equal to the
+ * provided string.
+ *
+ * The event is triggered by calling check_expected() in the mocked function.
+ *
+ * @param[in] #function The function to add the check for.
+ *
+ * @param[in] #parameter The name of the parameter passed to the function.
+ *
+ * @param[in] string The string value to compare.
+ *
+ * @param[in] count The count parameter returns the number of times the value
+ * should be returned by check_expected(). If count is set
+ * to -1 the value will always be returned.
+ *
+ * @see check_expected().
+ */
+void expect_string_count(#function, #parameter, const char *string, size_t count);
+#else
+#define expect_string_count(function, parameter, string, count) \
+ _expect_string(#function, #parameter, __FILE__, __LINE__, \
+ (const char*)(string), count)
+#endif
+
+#ifdef DOXYGEN
+/**
+ * @brief Add an event to check if the parameter value isn't equal to the
+ * provided string.
+ *
+ * The event is triggered by calling check_expected() in the mocked function.
+ *
+ * @param[in] #function The function to add the check for.
+ *
+ * @param[in] #parameter The name of the parameter passed to the function.
+ *
+ * @param[in] string The string value to compare.
+ *
+ * @see check_expected().
+ */
+void expect_not_string(#function, #parameter, const char *string);
+#else
+#define expect_not_string(function, parameter, string) \
+ expect_not_string_count(function, parameter, string, 1)
+#endif
+
+#ifdef DOXYGEN
+/**
+ * @brief Add an event to check if the parameter value isn't equal to the
+ * provided string.
+ *
+ * The event is triggered by calling check_expected() in the mocked function.
+ *
+ * @param[in] #function The function to add the check for.
+ *
+ * @param[in] #parameter The name of the parameter passed to the function.
+ *
+ * @param[in] string The string value to compare.
+ *
+ * @param[in] count The count parameter returns the number of times the value
+ * should be returned by check_expected(). If count is set
+ * to -1 the value will always be returned.
+ *
+ * @see check_expected().
+ */
+void expect_not_string_count(#function, #parameter, const char *string, size_t count);
+#else
+#define expect_not_string_count(function, parameter, string, count) \
+ _expect_not_string(#function, #parameter, __FILE__, __LINE__, \
+ (const char*)(string), count)
+#endif
+
+#ifdef DOXYGEN
+/**
+ * @brief Add an event to check if the parameter does match an area of memory.
+ *
+ * The event is triggered by calling check_expected() in the mocked function.
+ *
+ * @param[in] #function The function to add the check for.
+ *
+ * @param[in] #parameter The name of the parameter passed to the function.
+ *
+ * @param[in] memory The memory to compare.
+ *
+ * @param[in] size The size of the memory to compare.
+ *
+ * @see check_expected().
+ */
+void expect_memory(#function, #parameter, void *memory, size_t size);
+#else
+#define expect_memory(function, parameter, memory, size) \
+ expect_memory_count(function, parameter, memory, size, 1)
+#endif
+
+#ifdef DOXYGEN
+/**
+ * @brief Add an event to repeatedly check if the parameter does match an area
+ * of memory.
+ *
+ * The event is triggered by calling check_expected() in the mocked function.
+ *
+ * @param[in] #function The function to add the check for.
+ *
+ * @param[in] #parameter The name of the parameter passed to the function.
+ *
+ * @param[in] memory The memory to compare.
+ *
+ * @param[in] size The size of the memory to compare.
+ *
+ * @param[in] count The count parameter returns the number of times the value
+ * should be returned by check_expected(). If count is set
+ * to -1 the value will always be returned.
+ *
+ * @see check_expected().
+ */
+void expect_memory_count(#function, #parameter, void *memory, size_t size, size_t count);
+#else
+#define expect_memory_count(function, parameter, memory, size, count) \
+ _expect_memory(#function, #parameter, __FILE__, __LINE__, \
+ (const void*)(memory), size, count)
+#endif
+
+#ifdef DOXYGEN
+/**
+ * @brief Add an event to check if the parameter doesn't match an area of
+ * memory.
+ *
+ * The event is triggered by calling check_expected() in the mocked function.
+ *
+ * @param[in] #function The function to add the check for.
+ *
+ * @param[in] #parameter The name of the parameter passed to the function.
+ *
+ * @param[in] memory The memory to compare.
+ *
+ * @param[in] size The size of the memory to compare.
+ *
+ * @see check_expected().
+ */
+void expect_not_memory(#function, #parameter, void *memory, size_t size);
+#else
+#define expect_not_memory(function, parameter, memory, size) \
+ expect_not_memory_count(function, parameter, memory, size, 1)
+#endif
+
+#ifdef DOXYGEN
+/**
+ * @brief Add an event to repeatedly check if the parameter doesn't match an
+ * area of memory.
+ *
+ * The event is triggered by calling check_expected() in the mocked function.
+ *
+ * @param[in] #function The function to add the check for.
+ *
+ * @param[in] #parameter The name of the parameter passed to the function.
+ *
+ * @param[in] memory The memory to compare.
+ *
+ * @param[in] size The size of the memory to compare.
+ *
+ * @param[in] count The count parameter returns the number of times the value
+ * should be returned by check_expected(). If count is set
+ * to -1 the value will always be returned.
+ *
+ * @see check_expected().
+ */
+void expect_not_memory_count(#function, #parameter, void *memory, size_t size, size_t count);
+#else
+#define expect_not_memory_count(function, parameter, memory, size, count) \
+ _expect_not_memory(#function, #parameter, __FILE__, __LINE__, \
+ (const void*)(memory), size, count)
+#endif
+
+
+#ifdef DOXYGEN
+/**
+ * @brief Add an event to check if a parameter (of any value) has been passed.
+ *
+ * The event is triggered by calling check_expected() in the mocked function.
+ *
+ * @param[in] #function The function to add the check for.
+ *
+ * @param[in] #parameter The name of the parameter passed to the function.
+ *
+ * @see check_expected().
+ */
+void expect_any(#function, #parameter);
+#else
+#define expect_any(function, parameter) \
+ expect_any_count(function, parameter, 1)
+#endif
+
+#ifdef DOXYGEN
+/**
+ * @brief Add an event to repeatedly check if a parameter (of any value) has
+ * been passed.
+ *
+ * The event is triggered by calling check_expected() in the mocked function.
+ *
+ * @param[in] #function The function to add the check for.
+ *
+ * @param[in] #parameter The name of the parameter passed to the function.
+ *
+ * @param[in] count The count parameter returns the number of times the value
+ * should be returned by check_expected(). If count is set
+ * to -1 the value will always be returned.
+ *
+ * @see check_expected().
+ */
+void expect_any_count(#function, #parameter, size_t count);
+#else
+#define expect_any_count(function, parameter, count) \
+ _expect_any(#function, #parameter, __FILE__, __LINE__, count)
+#endif
+
+#ifdef DOXYGEN
+/**
+ * @brief Determine whether a function parameter is correct.
+ *
+ * This ensures the next value queued by one of the expect_*() macros matches
+ * the specified variable.
+ *
+ * This function needs to be called in the mock object.
+ *
+ * @param[in] #parameter The parameter to check.
+ */
+void check_expected(#parameter);
+#else
+#define check_expected(parameter) \
+ _check_expected(__func__, #parameter, __FILE__, __LINE__, \
+ cast_to_largest_integral_type(parameter))
+#endif
+
+#ifdef DOXYGEN
+/**
+ * @brief Determine whether a function parameter is correct.
+ *
+ * This ensures the next value queued by one of the expect_*() macros matches
+ * the specified variable.
+ *
+ * This function needs to be called in the mock object.
+ *
+ * @param[in] #parameter The pointer to check.
+ */
+void check_expected_ptr(#parameter);
+#else
+#define check_expected_ptr(parameter) \
+ _check_expected(__func__, #parameter, __FILE__, __LINE__, \
+ cast_ptr_to_largest_integral_type(parameter))
+#endif
+
+/** @} */
+
+/**
+ * @defgroup cmocka_asserts Assert Macros
+ * @ingroup cmocka
+ *
+ * This is a set of useful assert macros like the standard C libary's
+ * assert(3) macro.
+ *
+ * On an assertion failure a cmocka assert macro will write the failure to the
+ * standard error stream and signal a test failure. Due to limitations of the C
+ * language the general C standard library assert() and cmocka's assert_true()
+ * and assert_false() macros can only display the expression that caused the
+ * assert failure. cmocka's type specific assert macros, assert_{type}_equal()
+ * and assert_{type}_not_equal(), display the data that caused the assertion
+ * failure which increases data visibility aiding debugging of failing test
+ * cases.
+ *
+ * @{
+ */
+
+#ifdef DOXYGEN
+/**
+ * @brief Assert that the given expression is true.
+ *
+ * The function prints an error message to standard error and terminates the
+ * test by calling fail() if expression is false (i.e., compares equal to
+ * zero).
+ *
+ * @param[in] expression The expression to evaluate.
+ *
+ * @see assert_int_equal()
+ * @see assert_string_equal()
+ */
+void assert_true(scalar expression);
+#else
+#define assert_true(c) _assert_true(cast_to_largest_integral_type(c), #c, \
+ __FILE__, __LINE__)
+#endif
+
+#ifdef DOXYGEN
+/**
+ * @brief Assert that the given expression is false.
+ *
+ * The function prints an error message to standard error and terminates the
+ * test by calling fail() if expression is true.
+ *
+ * @param[in] expression The expression to evaluate.
+ *
+ * @see assert_int_equal()
+ * @see assert_string_equal()
+ */
+void assert_false(scalar expression);
+#else
+#define assert_false(c) _assert_true(!(cast_to_largest_integral_type(c)), #c, \
+ __FILE__, __LINE__)
+#endif
+
+#ifdef DOXYGEN
+/**
+ * @brief Assert that the return_code is greater than or equal to 0.
+ *
+ * The function prints an error message to standard error and terminates the
+ * test by calling fail() if the return code is smaller than 0. If the function
+ * you check sets an errno if it fails you can pass it to the function and
+ * it will be printed as part of the error message.
+ *
+ * @param[in] rc The return code to evaluate.
+ *
+ * @param[in] error Pass errno here or 0.
+ */
+void assert_return_code(int rc, int error);
+#else
+#define assert_return_code(rc, error) \
+ _assert_return_code(cast_to_largest_integral_type(rc), \
+ sizeof(rc), \
+ cast_to_largest_integral_type(error), \
+ #rc, __FILE__, __LINE__)
+#endif
+
+#ifdef DOXYGEN
+/**
+ * @brief Assert that the given pointer is non-NULL.
+ *
+ * The function prints an error message to standard error and terminates the
+ * test by calling fail() if the pointer is non-NULL.
+ *
+ * @param[in] pointer The pointer to evaluate.
+ *
+ * @see assert_null()
+ */
+void assert_non_null(void *pointer);
+#else
+#define assert_non_null(c) _assert_true(cast_ptr_to_largest_integral_type(c), #c, \
+ __FILE__, __LINE__)
+#endif
+
+#ifdef DOXYGEN
+/**
+ * @brief Assert that the given pointer is NULL.
+ *
+ * The function prints an error message to standard error and terminates the
+ * test by calling fail() if the pointer is non-NULL.
+ *
+ * @param[in] pointer The pointer to evaluate.
+ *
+ * @see assert_non_null()
+ */
+void assert_null(void *pointer);
+#else
+#define assert_null(c) _assert_true(!(cast_ptr_to_largest_integral_type(c)), #c, \
+__FILE__, __LINE__)
+#endif
+
+#ifdef DOXYGEN
+/**
+ * @brief Assert that the two given pointers are equal.
+ *
+ * The function prints an error message and terminates the test by calling
+ * fail() if the pointers are not equal.
+ *
+ * @param[in] a The first pointer to compare.
+ *
+ * @param[in] b The pointer to compare against the first one.
+ */
+void assert_ptr_equal(void *a, void *b);
+#else
+#define assert_ptr_equal(a, b) \
+ _assert_int_equal(cast_ptr_to_largest_integral_type(a), \
+ cast_ptr_to_largest_integral_type(b), \
+ __FILE__, __LINE__)
+#endif
+
+#ifdef DOXYGEN
+/**
+ * @brief Assert that the two given pointers are not equal.
+ *
+ * The function prints an error message and terminates the test by calling
+ * fail() if the pointers are equal.
+ *
+ * @param[in] a The first pointer to compare.
+ *
+ * @param[in] b The pointer to compare against the first one.
+ */
+void assert_ptr_not_equal(void *a, void *b);
+#else
+#define assert_ptr_not_equal(a, b) \
+ _assert_int_not_equal(cast_ptr_to_largest_integral_type(a), \
+ cast_ptr_to_largest_integral_type(b), \
+ __FILE__, __LINE__)
+#endif
+
+#ifdef DOXYGEN
+/**
+ * @brief Assert that the two given integers are equal.
+ *
+ * The function prints an error message to standard error and terminates the
+ * test by calling fail() if the integers are not equal.
+ *
+ * @param[in] a The first integer to compare.
+ *
+ * @param[in] b The integer to compare against the first one.
+ */
+void assert_int_equal(int a, int b);
+#else
+#define assert_int_equal(a, b) \
+ _assert_int_equal(cast_to_largest_integral_type(a), \
+ cast_to_largest_integral_type(b), \
+ __FILE__, __LINE__)
+#endif
+
+#ifdef DOXYGEN
+/**
+ * @brief Assert that the two given integers are not equal.
+ *
+ * The function prints an error message to standard error and terminates the
+ * test by calling fail() if the integers are equal.
+ *
+ * @param[in] a The first integer to compare.
+ *
+ * @param[in] b The integer to compare against the first one.
+ *
+ * @see assert_int_equal()
+ */
+void assert_int_not_equal(int a, int b);
+#else
+#define assert_int_not_equal(a, b) \
+ _assert_int_not_equal(cast_to_largest_integral_type(a), \
+ cast_to_largest_integral_type(b), \
+ __FILE__, __LINE__)
+#endif
+
+#ifdef DOXYGEN
+/**
+ * @brief Assert that the two given strings are equal.
+ *
+ * The function prints an error message to standard error and terminates the
+ * test by calling fail() if the strings are not equal.
+ *
+ * @param[in] a The string to check.
+ *
+ * @param[in] b The other string to compare.
+ */
+void assert_string_equal(const char *a, const char *b);
+#else
+#define assert_string_equal(a, b) \
+ _assert_string_equal((const char*)(a), (const char*)(b), __FILE__, \
+ __LINE__)
+#endif
+
+#ifdef DOXYGEN
+/**
+ * @brief Assert that the two given strings are not equal.
+ *
+ * The function prints an error message to standard error and terminates the
+ * test by calling fail() if the strings are equal.
+ *
+ * @param[in] a The string to check.
+ *
+ * @param[in] b The other string to compare.
+ */
+void assert_string_not_equal(const char *a, const char *b);
+#else
+#define assert_string_not_equal(a, b) \
+ _assert_string_not_equal((const char*)(a), (const char*)(b), __FILE__, \
+ __LINE__)
+#endif
+
+#ifdef DOXYGEN
+/**
+ * @brief Assert that the two given areas of memory are equal, otherwise fail.
+ *
+ * The function prints an error message to standard error and terminates the
+ * test by calling fail() if the memory is not equal.
+ *
+ * @param[in] a The first memory area to compare
+ * (interpreted as unsigned char).
+ *
+ * @param[in] b The second memory area to compare
+ * (interpreted as unsigned char).
+ *
+ * @param[in] size The first n bytes of the memory areas to compare.
+ */
+void assert_memory_equal(const void *a, const void *b, size_t size);
+#else
+#define assert_memory_equal(a, b, size) \
+ _assert_memory_equal((const void*)(a), (const void*)(b), size, __FILE__, \
+ __LINE__)
+#endif
+
+#ifdef DOXYGEN
+/**
+ * @brief Assert that the two given areas of memory are not equal.
+ *
+ * The function prints an error message to standard error and terminates the
+ * test by calling fail() if the memory is equal.
+ *
+ * @param[in] a The first memory area to compare
+ * (interpreted as unsigned char).
+ *
+ * @param[in] b The second memory area to compare
+ * (interpreted as unsigned char).
+ *
+ * @param[in] size The first n bytes of the memory areas to compare.
+ */
+void assert_memory_not_equal(const void *a, const void *b, size_t size);
+#else
+#define assert_memory_not_equal(a, b, size) \
+ _assert_memory_not_equal((const void*)(a), (const void*)(b), size, \
+ __FILE__, __LINE__)
+#endif
+
+#ifdef DOXYGEN
+/**
+ * @brief Assert that the specified value is not smaller than the minimum
+ * and and not greater than the maximum.
+ *
+ * The function prints an error message to standard error and terminates the
+ * test by calling fail() if value is not in range.
+ *
+ * @param[in] value The value to check.
+ *
+ * @param[in] minimum The minimum value allowed.
+ *
+ * @param[in] maximum The maximum value allowed.
+ */
+void assert_in_range(LargestIntegralType value, LargestIntegralType minimum, LargestIntegralType maximum);
+#else
+#define assert_in_range(value, minimum, maximum) \
+ _assert_in_range( \
+ cast_to_largest_integral_type(value), \
+ cast_to_largest_integral_type(minimum), \
+ cast_to_largest_integral_type(maximum), __FILE__, __LINE__)
+#endif
+
+#ifdef DOXYGEN
+/**
+ * @brief Assert that the specified value is smaller than the minimum or
+ * greater than the maximum.
+ *
+ * The function prints an error message to standard error and terminates the
+ * test by calling fail() if value is in range.
+ *
+ * @param[in] value The value to check.
+ *
+ * @param[in] minimum The minimum value to compare.
+ *
+ * @param[in] maximum The maximum value to compare.
+ */
+void assert_not_in_range(LargestIntegralType value, LargestIntegralType minimum, LargestIntegralType maximum);
+#else
+#define assert_not_in_range(value, minimum, maximum) \
+ _assert_not_in_range( \
+ cast_to_largest_integral_type(value), \
+ cast_to_largest_integral_type(minimum), \
+ cast_to_largest_integral_type(maximum), __FILE__, __LINE__)
+#endif
+
+#ifdef DOXYGEN
+/**
+ * @brief Assert that the specified value is within a set.
+ *
+ * The function prints an error message to standard error and terminates the
+ * test by calling fail() if value is not within a set.
+ *
+ * @param[in] value The value to look up
+ *
+ * @param[in] values[] The array to check for the value.
+ *
+ * @param[in] count The size of the values array.
+ */
+void assert_in_set(LargestIntegralType value, LargestIntegralType values[], size_t count);
+#else
+#define assert_in_set(value, values, number_of_values) \
+ _assert_in_set(value, values, number_of_values, __FILE__, __LINE__)
+#endif
+
+#ifdef DOXYGEN
+/**
+ * @brief Assert that the specified value is not within a set.
+ *
+ * The function prints an error message to standard error and terminates the
+ * test by calling fail() if value is within a set.
+ *
+ * @param[in] value The value to look up
+ *
+ * @param[in] values[] The array to check for the value.
+ *
+ * @param[in] count The size of the values array.
+ */
+void assert_not_in_set(LargestIntegralType value, LargestIntegralType values[], size_t count);
+#else
+#define assert_not_in_set(value, values, number_of_values) \
+ _assert_not_in_set(value, values, number_of_values, __FILE__, __LINE__)
+#endif
+
+/** @} */
+
+/**
+ * @defgroup cmocka_call_order Call Ordering
+ * @ingroup cmocka
+ *
+ * It is often beneficial to make sure that functions are called in an
+ * order. This is independent of mock returns and parameter checking as both
+ * of the aforementioned do not check the order in which they are called from
+ * different functions.
+ *
+ *
+ *
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.
+ *
+ * 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 { \
+ print_error("ERROR: " msg "\n", ##__VA_ARGS__); \
+ fail(); \
+} while (0)
+#endif
+
+#ifdef DOXYGEN
+/**
+ * @brief Generic method to run a single test.
+ *
+ * @deprecated This function was deprecated in favor of cmocka_run_group_tests
+ *
+ * @param[in] #function The function to test.
+ *
+ * @return 0 on success, 1 if an error occured.
+ *
+ * @code
+ * // A test case that does nothing and succeeds.
+ * void null_test_success(void **state) {
+ * }
+ *
+ * int main(void) {
+ * return run_test(null_test_success);
+ * }
+ * @endcode
+ */
+int run_test(#function);
+#else
+#define run_test(f) _run_test(#f, f, NULL, UNIT_TEST_FUNCTION_TYPE_TEST, NULL)
+#endif
+
+static inline void _unit_test_dummy(void **state) {
+ (void)state;
+}
+
+/** Initializes a UnitTest structure.
+ *
+ * @deprecated This function was deprecated in favor of cmocka_unit_test
+ */
+#define unit_test(f) { #f, f, UNIT_TEST_FUNCTION_TYPE_TEST }
+
+#define _unit_test_setup(test, setup) \
+ { #test "_" #setup, setup, UNIT_TEST_FUNCTION_TYPE_SETUP }
+
+/** Initializes a UnitTest structure with a setup function.
+ *
+ * @deprecated This function was deprecated in favor of cmocka_unit_test_setup
+ */
+#define unit_test_setup(test, setup) \
+ _unit_test_setup(test, setup), \
+ unit_test(test), \
+ _unit_test_teardown(test, _unit_test_dummy)
+
+#define _unit_test_teardown(test, teardown) \
+ { #test "_" #teardown, teardown, UNIT_TEST_FUNCTION_TYPE_TEARDOWN }
+
+/** Initializes a UnitTest structure with a teardown function.
+ *
+ * @deprecated This function was deprecated in favor of cmocka_unit_test_teardown
+ */
+#define unit_test_teardown(test, teardown) \
+ _unit_test_setup(test, _unit_test_dummy), \
+ unit_test(test), \
+ _unit_test_teardown(test, teardown)
+
+/** Initializes a UnitTest structure for a group setup function.
+ *
+ * @deprecated This function was deprecated in favor of cmocka_run_group_tests
+ */
+#define group_test_setup(setup) \
+ { "group_" #setup, setup, UNIT_TEST_FUNCTION_TYPE_GROUP_SETUP }
+
+/** Initializes a UnitTest structure for a group teardown function.
+ *
+ * @deprecated This function was deprecated in favor of cmocka_run_group_tests
+ */
+#define group_test_teardown(teardown) \
+ { "group_" #teardown, teardown, UNIT_TEST_FUNCTION_TYPE_GROUP_TEARDOWN }
+
+/**
+ * Initialize an array of UnitTest structures with a setup function for a test
+ * and a teardown function. Either setup or teardown can be NULL.
+ *
+ * @deprecated This function was deprecated in favor of
+ * cmocka_unit_test_setup_teardown
+ */
+#define unit_test_setup_teardown(test, setup, teardown) \
+ _unit_test_setup(test, setup), \
+ unit_test(test), \
+ _unit_test_teardown(test, teardown)
+
+
+/** Initializes a CMUnitTest structure. */
+#define cmocka_unit_test(f) { #f, f, NULL, NULL, NULL }
+
+/** Initializes a CMUnitTest structure with a setup function. */
+#define cmocka_unit_test_setup(f, setup) { #f, f, setup, NULL, NULL }
+
+/** Initializes a CMUnitTest structure with a teardown function. */
+#define cmocka_unit_test_teardown(f, teardown) { #f, f, NULL, teardown, NULL }
+
+/**
+ * Initialize an array of CMUnitTest structures with a setup function for a test
+ * and a teardown function. Either setup or teardown can be NULL.
+ */
+#define cmocka_unit_test_setup_teardown(f, setup, teardown) { #f, f, setup, teardown, NULL }
+
+/**
+ * Initialize a CMUnitTest structure with given initial state. It will be passed
+ * to test function as an argument later. It can be used when test state does
+ * not need special initialization or was initialized already.
+ * @note If the group setup function initialized the state already, it won't be
+ * overridden by the initial state defined here.
+ */
+#define cmocka_unit_test_prestate(f, state) { #f, f, NULL, NULL, state }
+
+/**
+ * Initialize a CMUnitTest structure with given initial state, setup and
+ * teardown function. Any of these values can be NULL. Initial state is passed
+ * later to setup function, or directly to test if none was given.
+ * @note If the group setup function initialized the state already, it won't be
+ * overridden by the initial state defined here.
+ */
+#define cmocka_unit_test_prestate_setup_teardown(f, setup, teardown, state) { #f, f, setup, teardown, state }
+
+#define run_tests(tests) _run_tests(tests, sizeof(tests) / sizeof((tests)[0]))
+#define run_group_tests(tests) _run_group_tests(tests, sizeof(tests) / sizeof((tests)[0]))
+
+#ifdef DOXYGEN
+/**
+ * @brief Run tests specified by an array of CMUnitTest structures.
+ *
+ * @param[in] group_tests[] The array of unit tests to execute.
+ *
+ * @param[in] group_setup The setup function which should be called before
+ * all unit tests are executed.
+ *
+ * @param[in] group_teardown The teardown function to be called after all
+ * tests have finished.
+ *
+ * @return 0 on success, or the number of failed tests.
+ *
+ * @code
+ * static int setup(void **state) {
+ * int *answer = malloc(sizeof(int));
+ * if (*answer == NULL) {
+ * return -1;
+ * }
+ * *answer = 42;
+ *
+ * *state = answer;
+ *
+ * return 0;
+ * }
+ *
+ * static int teardown(void **state) {
+ * free(*state);
+ *
+ * return 0;
+ * }
+ *
+ * static void null_test_success(void **state) {
+ * (void) state;
+ * }
+ *
+ * static void int_test_success(void **state) {
+ * int *answer = *state;
+ * assert_int_equal(*answer, 42);
+ * }
+ *
+ * int main(void) {
+ * const struct CMUnitTest tests[] = {
+ * cmocka_unit_test(null_test_success),
+ * cmocka_unit_test_setup_teardown(int_test_success, setup, teardown),
+ * };
+ *
+ * return cmocka_run_group_tests(tests, NULL, NULL);
+ * }
+ * @endcode
+ *
+ * @see cmocka_unit_test
+ * @see cmocka_unit_test_setup
+ * @see cmocka_unit_test_teardown
+ * @see cmocka_unit_test_setup_teardown
+ */
+int cmocka_run_group_tests(const struct CMUnitTest group_tests[],
+ CMFixtureFunction group_setup,
+ CMFixtureFunction group_teardown);
+#else
+# define cmocka_run_group_tests(group_tests, group_setup, group_teardown) \
+ _cmocka_run_group_tests(#group_tests, group_tests, sizeof(group_tests) / sizeof((group_tests)[0]), group_setup, group_teardown)
+#endif
+
+#ifdef DOXYGEN
+/**
+ * @brief Run tests specified by an array of CMUnitTest structures and specify
+ * a name.
+ *
+ * @param[in] group_name The name of the group test.
+ *
+ * @param[in] group_tests[] The array of unit tests to execute.
+ *
+ * @param[in] group_setup The setup function which should be called before
+ * all unit tests are executed.
+ *
+ * @param[in] group_teardown The teardown function to be called after all
+ * tests have finished.
+ *
+ * @return 0 on success, or the number of failed tests.
+ *
+ * @code
+ * static int setup(void **state) {
+ * int *answer = malloc(sizeof(int));
+ * if (*answer == NULL) {
+ * return -1;
+ * }
+ * *answer = 42;
+ *
+ * *state = answer;
+ *
+ * return 0;
+ * }
+ *
+ * static int teardown(void **state) {
+ * free(*state);
+ *
+ * return 0;
+ * }
+ *
+ * static void null_test_success(void **state) {
+ * (void) state;
+ * }
+ *
+ * static void int_test_success(void **state) {
+ * int *answer = *state;
+ * assert_int_equal(*answer, 42);
+ * }
+ *
+ * int main(void) {
+ * const struct CMUnitTest tests[] = {
+ * cmocka_unit_test(null_test_success),
+ * cmocka_unit_test_setup_teardown(int_test_success, setup, teardown),
+ * };
+ *
+ * return cmocka_run_group_tests_name("success_test", tests, NULL, NULL);
+ * }
+ * @endcode
+ *
+ * @see cmocka_unit_test
+ * @see cmocka_unit_test_setup
+ * @see cmocka_unit_test_teardown
+ * @see cmocka_unit_test_setup_teardown
+ */
+int cmocka_run_group_tests_name(const char *group_name,
+ const struct CMUnitTest group_tests[],
+ CMFixtureFunction group_setup,
+ CMFixtureFunction group_teardown);
+#else
+# define cmocka_run_group_tests_name(group_name, group_tests, group_setup, group_teardown) \
+ _cmocka_run_group_tests(group_name, group_tests, sizeof(group_tests) / sizeof((group_tests)[0]), group_setup, group_teardown)
+#endif
+
+/** @} */
+
+/**
+ * @defgroup cmocka_alloc Dynamic Memory Allocation
+ * @ingroup cmocka
+ *
+ * Memory leaks, buffer overflows and underflows can be checked using cmocka.
+ *
+ * To test for memory leaks, buffer overflows and underflows a module being
+ * tested by cmocka should replace calls to malloc(), calloc() and free() to
+ * test_malloc(), test_calloc() and test_free() respectively. Each time a block
+ * is deallocated using test_free() it is checked for corruption, if a corrupt
+ * block is found a test failure is signalled. All blocks allocated using the
+ * test_*() allocation functions are tracked by the cmocka library. When a test
+ * completes if any allocated blocks (memory leaks) remain they are reported
+ * and a test failure is signalled.
+ *
+ * For simplicity cmocka currently executes all tests in one process. Therefore
+ * all test cases in a test application share a single address space which
+ * means memory corruption from a single test case could potentially cause the
+ * test application to exit prematurely.
+ *
+ * @{
+ */
+
+#ifdef DOXYGEN
+/**
+ * @brief Test function overriding malloc.
+ *
+ * @param[in] size The bytes which should be allocated.
+ *
+ * @return A pointer to the allocated memory or NULL on error.
+ *
+ * @code
+ * #ifdef UNIT_TESTING
+ * extern void* _test_malloc(const size_t size, const char* file, const int line);
+ *
+ * #define malloc(size) _test_malloc(size, __FILE__, __LINE__)
+ * #endif
+ *
+ * void leak_memory() {
+ * int * const temporary = (int*)malloc(sizeof(int));
+ * *temporary = 0;
+ * }
+ * @endcode
+ *
+ * @see malloc(3)
+ */
+void *test_malloc(size_t size);
+#else
+#define test_malloc(size) _test_malloc(size, __FILE__, __LINE__)
+#endif
+
+#ifdef DOXYGEN
+/**
+ * @brief Test function overriding calloc.
+ *
+ * The memory is set to zero.
+ *
+ * @param[in] nmemb The number of elements for an array to be allocated.
+ *
+ * @param[in] size The size in bytes of each array element to allocate.
+ *
+ * @return A pointer to the allocated memory, NULL on error.
+ *
+ * @see calloc(3)
+ */
+void *test_calloc(size_t nmemb, size_t size);
+#else
+#define test_calloc(num, size) _test_calloc(num, size, __FILE__, __LINE__)
+#endif
+
+#ifdef DOXYGEN
+/**
+ * @brief Test function overriding realloc which detects buffer overruns
+ * and memoery leaks.
+ *
+ * @param[in] ptr The memory block which should be changed.
+ *
+ * @param[in] size The bytes which should be allocated.
+ *
+ * @return The newly allocated memory block, NULL on error.
+ */
+void *test_realloc(void *ptr, size_t size);
+#else
+#define test_realloc(ptr, size) _test_realloc(ptr, size, __FILE__, __LINE__)
+#endif
+
+#ifdef DOXYGEN
+/**
+ * @brief Test function overriding free(3).
+ *
+ * @param[in] ptr The pointer to the memory space to free.
+ *
+ * @see free(3).
+ */
+void test_free(void *ptr);
+#else
+#define test_free(ptr) _test_free(ptr, __FILE__, __LINE__)
+#endif
+
+/* Redirect malloc, calloc and free to the unit test allocators. */
+#ifdef UNIT_TESTING
+#define malloc test_malloc
+#define realloc test_realloc
+#define calloc test_calloc
+#define free test_free
+#endif /* UNIT_TESTING */
+
+/** @} */
+
+
+/**
+ * @defgroup cmocka_mock_assert Standard Assertions
+ * @ingroup cmocka
+ *
+ * How to handle assert(3) of the standard C library.
+ *
+ * Runtime assert macros like the standard C library's assert() should be
+ * redefined in modules being tested to use cmocka's mock_assert() function.
+ * Normally mock_assert() signals a test failure. If a function is called using
+ * the expect_assert_failure() macro, any calls to mock_assert() within the
+ * function will result in the execution of the test. If no calls to
+ * mock_assert() occur during the function called via expect_assert_failure() a
+ * test failure is signalled.
+ *
+ * @{
+ */
+
+/**
+ * @brief Function to replace assert(3) in tested code.
+ *
+ * In conjuction with check_assert() it's possible to determine whether an
+ * assert condition has failed without stopping a test.
+ *
+ * @param[in] result The expression to assert.
+ *
+ * @param[in] expression The expression as string.
+ *
+ * @param[in] file The file mock_assert() is called.
+ *
+ * @param[in] line The line mock_assert() is called.
+ *
+ * @code
+ * #ifdef UNIT_TESTING
+ * extern void mock_assert(const int result, const char* const expression,
+ * const char * const file, const int line);
+ *
+ * #undef assert
+ * #define assert(expression) \
+ * mock_assert((int)(expression), #expression, __FILE__, __LINE__);
+ * #endif
+ *
+ * void increment_value(int * const value) {
+ * assert(value);
+ * (*value) ++;
+ * }
+ * @endcode
+ *
+ * @see assert(3)
+ * @see expect_assert_failure
+ */
+void mock_assert(const int result, const char* const expression,
+ const char * const file, const int line);
+
+#ifdef DOXYGEN
+/**
+ * @brief Ensure that mock_assert() is called.
+ *
+ * If mock_assert() is called the assert expression string is returned.
+ *
+ * @param[in] fn_call The function will will call mock_assert().
+ *
+ * @code
+ * #define assert mock_assert
+ *
+ * void showmessage(const char *message) {
+ * assert(message);
+ * }
+ *
+ * int main(int argc, const char* argv[]) {
+ * expect_assert_failure(show_message(NULL));
+ * printf("succeeded\n");
+ * return 0;
+ * }
+ * @endcode
+ *
+ */
+void expect_assert_failure(function fn_call);
+#else
+#define expect_assert_failure(function_call) \
+ { \
+ const int result = setjmp(global_expect_assert_env); \
+ global_expecting_assert = 1; \
+ if (result) { \
+ print_message("Expected assertion %s occurred\n", \
+ global_last_failed_assert); \
+ global_expecting_assert = 0; \
+ } else { \
+ function_call ; \
+ global_expecting_assert = 0; \
+ print_error("Expected assert in %s\n", #function_call); \
+ _fail(__FILE__, __LINE__); \
+ } \
+ }
+#endif
+
+/** @} */
+
+/* Function prototype for setup, test and teardown functions. */
+typedef void (*UnitTestFunction)(void **state);
+
+/* Function that determines whether a function parameter value is correct. */
+typedef int (*CheckParameterValue)(const LargestIntegralType value,
+ const LargestIntegralType check_value_data);
+
+/* Type of the unit test function. */
+typedef enum UnitTestFunctionType {
+ UNIT_TEST_FUNCTION_TYPE_TEST = 0,
+ UNIT_TEST_FUNCTION_TYPE_SETUP,
+ UNIT_TEST_FUNCTION_TYPE_TEARDOWN,
+ UNIT_TEST_FUNCTION_TYPE_GROUP_SETUP,
+ UNIT_TEST_FUNCTION_TYPE_GROUP_TEARDOWN,
+} UnitTestFunctionType;
+
+/*
+ * Stores a unit test function with its name and type.
+ * NOTE: Every setup function must be paired with a teardown function. It's
+ * possible to specify NULL function pointers.
+ */
+typedef struct UnitTest {
+ const char* name;
+ UnitTestFunction function;
+ UnitTestFunctionType function_type;
+} UnitTest;
+
+typedef struct GroupTest {
+ UnitTestFunction setup;
+ UnitTestFunction teardown;
+ const UnitTest *tests;
+ const size_t number_of_tests;
+} GroupTest;
+
+/* Function prototype for test functions. */
+typedef void (*CMUnitTestFunction)(void **state);
+
+/* Function prototype for setup and teardown functions. */
+typedef int (*CMFixtureFunction)(void **state);
+
+struct CMUnitTest {
+ const char *name;
+ CMUnitTestFunction test_func;
+ CMFixtureFunction setup_func;
+ CMFixtureFunction teardown_func;
+ void *initial_state;
+};
+
+/* Location within some source code. */
+typedef struct SourceLocation {
+ const char* file;
+ int line;
+} SourceLocation;
+
+/* Event that's called to check a parameter value. */
+typedef struct CheckParameterEvent {
+ SourceLocation location;
+ const char *parameter_name;
+ CheckParameterValue check_value;
+ LargestIntegralType check_value_data;
+} CheckParameterEvent;
+
+/* Used by expect_assert_failure() and mock_assert(). */
+extern int global_expecting_assert;
+extern jmp_buf global_expect_assert_env;
+extern const char * global_last_failed_assert;
+
+/* Retrieves a value for the given function, as set by "will_return". */
+LargestIntegralType _mock(const char * const function, const char* const file,
+ const int line);
+
+void _expect_function_call(
+ const char * const function_name,
+ const char * const file,
+ const int line,
+ const int count);
+
+void _function_called(const char * const function, const char* const file,
+ const int line);
+
+void _expect_check(
+ const char* const function, const char* const parameter,
+ const char* const file, const int line,
+ const CheckParameterValue check_function,
+ const LargestIntegralType check_data, CheckParameterEvent * const event,
+ const int count);
+
+void _expect_in_set(
+ const char* const function, const char* const parameter,
+ const char* const file, const int line, const LargestIntegralType values[],
+ const size_t number_of_values, const int count);
+void _expect_not_in_set(
+ const char* const function, const char* const parameter,
+ const char* const file, const int line, const LargestIntegralType values[],
+ const size_t number_of_values, const int count);
+
+void _expect_in_range(
+ const char* const function, const char* const parameter,
+ const char* const file, const int line,
+ const LargestIntegralType minimum,
+ const LargestIntegralType maximum, const int count);
+void _expect_not_in_range(
+ const char* const function, const char* const parameter,
+ const char* const file, const int line,
+ const LargestIntegralType minimum,
+ const LargestIntegralType maximum, const int count);
+
+void _expect_value(
+ const char* const function, const char* const parameter,
+ const char* const file, const int line, const LargestIntegralType value,
+ const int count);
+void _expect_not_value(
+ const char* const function, const char* const parameter,
+ const char* const file, const int line, const LargestIntegralType value,
+ const int count);
+
+void _expect_string(
+ const char* const function, const char* const parameter,
+ const char* const file, const int line, const char* string,
+ const int count);
+void _expect_not_string(
+ const char* const function, const char* const parameter,
+ const char* const file, const int line, const char* string,
+ const int count);
+
+void _expect_memory(
+ const char* const function, const char* const parameter,
+ const char* const file, const int line, const void* const memory,
+ const size_t size, const int count);
+void _expect_not_memory(
+ const char* const function, const char* const parameter,
+ const char* const file, const int line, const void* const memory,
+ const size_t size, const int count);
+
+void _expect_any(
+ const char* const function, const char* const parameter,
+ const char* const file, const int line, const int count);
+
+void _check_expected(
+ const char * const function_name, const char * const parameter_name,
+ const char* file, const int line, const LargestIntegralType value);
+
+void _will_return(const char * const function_name, const char * const file,
+ const int line, const LargestIntegralType value,
+ const int count);
+void _assert_true(const LargestIntegralType result,
+ const char* const expression,
+ const char * const file, const int line);
+void _assert_return_code(const LargestIntegralType result,
+ size_t rlen,
+ const LargestIntegralType error,
+ const char * const expression,
+ const char * const file,
+ const int line);
+void _assert_int_equal(
+ const LargestIntegralType a, const LargestIntegralType b,
+ const char * const file, const int line);
+void _assert_int_not_equal(
+ const LargestIntegralType a, const LargestIntegralType b,
+ const char * const file, const int line);
+void _assert_string_equal(const char * const a, const char * const b,
+ const char * const file, const int line);
+void _assert_string_not_equal(const char * const a, const char * const b,
+ const char *file, const int line);
+void _assert_memory_equal(const void * const a, const void * const b,
+ const size_t size, const char* const file,
+ const int line);
+void _assert_memory_not_equal(const void * const a, const void * const b,
+ const size_t size, const char* const file,
+ const int line);
+void _assert_in_range(
+ const LargestIntegralType value, const LargestIntegralType minimum,
+ const LargestIntegralType maximum, const char* const file, const int line);
+void _assert_not_in_range(
+ const LargestIntegralType value, const LargestIntegralType minimum,
+ const LargestIntegralType maximum, const char* const file, const int line);
+void _assert_in_set(
+ const LargestIntegralType value, const LargestIntegralType values[],
+ const size_t number_of_values, const char* const file, const int line);
+void _assert_not_in_set(
+ const LargestIntegralType value, const LargestIntegralType values[],
+ const size_t number_of_values, const char* const file, const int line);
+
+void* _test_malloc(const size_t size, const char* file, const int line);
+void* _test_realloc(void *ptr, const size_t size, const char* file, const int line);
+void* _test_calloc(const size_t number_of_elements, const size_t size,
+ const char* file, const int line);
+void _test_free(void* const ptr, const char* file, const int line);
+
+void _fail(const char * const file, const int line);
+
+void _skip(const char * const file, const int line);
+
+int _run_test(
+ const char * const function_name, const UnitTestFunction Function,
+ void ** const volatile state, const UnitTestFunctionType function_type,
+ const void* const heap_check_point);
+CMOCKA_DEPRECATED int _run_tests(const UnitTest * const tests,
+ const size_t number_of_tests);
+CMOCKA_DEPRECATED int _run_group_tests(const UnitTest * const tests,
+ const size_t number_of_tests);
+
+/* Test runner */
+int _cmocka_run_group_tests(const char *group_name,
+ const struct CMUnitTest * const tests,
+ const size_t num_tests,
+ CMFixtureFunction group_setup,
+ CMFixtureFunction group_teardown);
+
+/* Standard output and error print methods. */
+void print_message(const char* const format, ...) CMOCKA_PRINTF_ATTRIBUTE(1, 2);
+void print_error(const char* const format, ...) CMOCKA_PRINTF_ATTRIBUTE(1, 2);
+void vprint_message(const char* const format, va_list args) CMOCKA_PRINTF_ATTRIBUTE(1, 0);
+void vprint_error(const char* const format, va_list args) CMOCKA_PRINTF_ATTRIBUTE(1, 0);
+
+enum cm_message_output {
+ CM_OUTPUT_STDOUT,
+ CM_OUTPUT_SUBUNIT,
+ CM_OUTPUT_TAP,
+ CM_OUTPUT_XML,
+};
+
+/**
+ * @brief Function to set the output format for a test.
+ *
+ * The ouput format for the test can either be set globally using this
+ * function or overriden with environment variable CMOCKA_MESSAGE_OUTPUT.
+ *
+ * The environment variable can be set to either STDOUT, SUBUNIT, TAP or XML.
+ *
+ * @param[in] output The output format to use for the test.
+ *
+ */
+void cmocka_set_message_output(enum cm_message_output output);
+
+/** @} */
+
+#endif /* CMOCKA_H_ */
diff --git a/emCmocka/include/cmocka_pbc.h b/emCmocka/include/cmocka_pbc.h
new file mode 100644
index 0000000..a2a1bc1
--- /dev/null
+++ b/emCmocka/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/emCmocka/include/cmocka_private.h b/emCmocka/include/cmocka_private.h
new file mode 100644
index 0000000..d20d841
--- /dev/null
+++ b/emCmocka/include/cmocka_private.h
@@ -0,0 +1,163 @@
+/*
+ * Copyright 2008 Google Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef CMOCKA_PRIVATE_H_
+#define CMOCKA_PRIVATE_H_
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include
+
+#ifdef _WIN32
+#include
+
+# ifdef _MSC_VER
+# include /* _snprintf */
+
+# undef inline
+# define inline __inline
+
+# ifndef va_copy
+# define va_copy(dest, src) (dest = src)
+# endif
+
+# define strcasecmp _stricmp
+# define strncasecmp _strnicmp
+
+# if defined(HAVE__SNPRINTF_S)
+# undef snprintf
+# define snprintf(d, n, ...) _snprintf_s((d), (n), _TRUNCATE, __VA_ARGS__)
+# else /* HAVE__SNPRINTF_S */
+# if defined(HAVE__SNPRINTF)
+# undef snprintf
+# define snprintf _snprintf
+# else /* HAVE__SNPRINTF */
+# if !defined(HAVE_SNPRINTF)
+# error "no snprintf compatible function found"
+# endif /* HAVE_SNPRINTF */
+# endif /* HAVE__SNPRINTF */
+# endif /* HAVE__SNPRINTF_S */
+
+# if defined(HAVE__VSNPRINTF_S)
+# undef vsnprintf
+# define vsnprintf(s, n, f, v) _vsnprintf_s((s), (n), _TRUNCATE, (f), (v))
+# else /* HAVE__VSNPRINTF_S */
+# if defined(HAVE__VSNPRINTF)
+# undef vsnprintf
+# define vsnprintf _vsnprintf
+# else
+# if !defined(HAVE_VSNPRINTF)
+# error "No vsnprintf compatible function found"
+# endif /* HAVE_VSNPRINTF */
+# endif /* HAVE__VSNPRINTF */
+# endif /* HAVE__VSNPRINTF_S */
+# endif /* _MSC_VER */
+
+/*
+ * Backwards compatibility with headers shipped with Visual Studio 2005 and
+ * earlier.
+ */
+WINBASEAPI BOOL WINAPI IsDebuggerPresent(VOID);
+
+#ifndef PRIdS
+# define PRIdS "Id"
+#endif
+
+#ifndef PRIu64
+# define PRIu64 "I64u"
+#endif
+
+#ifndef PRIuMAX
+# define PRIuMAX PRIu64
+#endif
+
+#ifndef PRIxMAX
+#define PRIxMAX "I64x"
+#endif
+
+#ifndef PRIXMAX
+#define PRIXMAX "I64X"
+#endif
+
+#else /* _WIN32 */
+
+#ifndef __PRI64_PREFIX
+# if __WORDSIZE == 64
+# define __PRI64_PREFIX "l"
+# else
+# define __PRI64_PREFIX "ll"
+# endif
+#endif
+
+#ifndef PRIdS
+# define PRIdS "zd"
+#endif
+
+#ifndef PRIu64
+# define PRIu64 __PRI64_PREFIX "u"
+#endif
+
+#ifndef PRIuMAX
+# define PRIuMAX __PRI64_PREFIX "u"
+#endif
+
+#ifndef PRIxMAX
+#define PRIxMAX __PRI64_PREFIX "x"
+#endif
+
+#ifndef PRIXMAX
+#define PRIXMAX __PRI64_PREFIX "X"
+#endif
+
+#endif /* _WIN32 */
+
+/** Free memory space */
+#define SAFE_FREE(x) do { if ((x) != NULL) {free(x); x=NULL;} } while(0)
+
+/** Zero a structure */
+#define ZERO_STRUCT(x) memset((char *)&(x), 0, sizeof(x))
+
+/** Zero a structure given a pointer to the structure */
+#define ZERO_STRUCTP(x) do { if ((x) != NULL) memset((char *)(x), 0, sizeof(*(x))); } while(0)
+
+/** Get the size of an array */
+#define ARRAY_SIZE(a) (sizeof(a)/sizeof(a[0]))
+
+/** Overwrite the complete string with 'X' */
+#define BURN_STRING(x) do { if ((x) != NULL) memset((x), 'X', strlen((x))); } while(0)
+
+/**
+ * This is a hack to fix warnings. The idea is to use this everywhere that we
+ * get the "discarding const" warning by the compiler. That doesn't actually
+ * fix the real issue, but marks the place and you can search the code for
+ * discard_const.
+ *
+ * Please use this macro only when there is no other way to fix the warning.
+ * We should use this function in only in a very few places.
+ *
+ * Also, please call this via the discard_const_p() macro interface, as that
+ * makes the return type safe.
+ */
+#define discard_const(ptr) ((void *)((uintptr_t)(ptr)))
+
+/**
+ * Type-safe version of discard_const
+ */
+#define discard_const_p(type, ptr) ((type *)discard_const(ptr))
+
+#endif /* CMOCKA_PRIVATE_H_ */
diff --git a/emCmocka/include/cmockery/cmockery.h b/emCmocka/include/cmockery/cmockery.h
new file mode 100644
index 0000000..a252a5f
--- /dev/null
+++ b/emCmocka/include/cmockery/cmockery.h
@@ -0,0 +1 @@
+#include
diff --git a/emCmocka/include/cmockery/pbc.h b/emCmocka/include/cmockery/pbc.h
new file mode 100644
index 0000000..50bac87
--- /dev/null
+++ b/emCmocka/include/cmockery/pbc.h
@@ -0,0 +1 @@
+#include
diff --git a/emCmocka/src/CMakeLists.txt b/emCmocka/src/CMakeLists.txt
new file mode 100644
index 0000000..67c9bc2
--- /dev/null
+++ b/emCmocka/src/CMakeLists.txt
@@ -0,0 +1,118 @@
+project(cmocka-library C)
+
+set(CMOCKA_PLATFORM_INCLUDE CACHE PATH "Path to include directory for cmocka_platform.h")
+
+set(CMOCKA_PUBLIC_INCLUDE_DIRS
+ ${cmocka_SOURCE_DIR}/include
+ ${CMOCKA_PLATFORM_INCLUDE}
+ CACHE INTERNAL "cmocka public include directories"
+)
+
+set(CMOCKA_PRIVATE_INCLUDE_DIRS
+ ${cmocka_BINARY_DIR}
+)
+
+set(CMOCKA_SHARED_LIBRARY
+ cmocka_shared
+ CACHE INTERNAL "cmocka shared library"
+)
+
+if (WITH_STATIC_LIB)
+ set(CMOCKA_STATIC_LIBRARY
+ cmocka_static
+ CACHE INTERNAL "cmocka static library"
+ )
+endif (WITH_STATIC_LIB)
+
+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)
+
+include_directories(
+ ${CMOCKA_PUBLIC_INCLUDE_DIRS}
+ ${CMOCKA_PRIVATE_INCLUDE_DIRS}
+)
+
+add_definitions(-DHAVE_CONFIG_H=1)
+if (CMOCKA_PLATFORM_INCLUDE)
+ add_definitions(-DCMOCKA_PLATFORM_INCLUDE=1)
+endif()
+
+add_library(${CMOCKA_SHARED_LIBRARY} SHARED ${cmocka_SRCS})
+
+target_link_libraries(${CMOCKA_SHARED_LIBRARY} ${CMOCKA_LINK_LIBRARIES})
+set_target_properties(
+ ${CMOCKA_SHARED_LIBRARY}
+ PROPERTIES
+ OUTPUT_NAME
+ cmocka
+ DEFINE_SYMBOL
+ CMOCKA_EXPORTS
+)
+
+if (NOT WIN32)
+ set_target_properties(
+ ${CMOCKA_SHARED_LIBRARY}
+ PROPERTIES
+ VERSION
+ ${LIBRARY_VERSION}
+ SOVERSION
+ ${LIBRARY_SOVERSION}
+ )
+endif (NOT WIN32)
+
+install(
+ TARGETS ${CMOCKA_SHARED_LIBRARY}
+ RUNTIME DESTINATION ${BIN_INSTALL_DIR}
+ LIBRARY DESTINATION ${LIB_INSTALL_DIR}
+ ARCHIVE DESTINATION ${LIB_INSTALL_DIR}
+ COMPONENT libraries
+)
+
+if (WITH_STATIC_LIB)
+ add_library(${CMOCKA_STATIC_LIBRARY} STATIC ${cmocka_SRCS})
+
+ set_target_properties(
+ ${CMOCKA_STATIC_LIBRARY}
+ PROPERTIES
+ VERSION
+ ${LIBRARY_VERSION}
+ SOVERSION
+ ${LIBRARY_SOVERSION}
+ OUTPUT_NAME
+ cmocka
+ )
+
+ install(
+ TARGETS ${CMOCKA_STATIC_LIBRARY}
+ DESTINATION ${LIB_INSTALL_DIR}
+ COMPONENT libraries
+ )
+endif (WITH_STATIC_LIB)
+
+if (POLICY CMP0026)
+ cmake_policy(SET CMP0026 OLD)
+endif()
+
+#
+# In order to run tests we will need to set the approriate environment
+# variable so that the test program can locate its dependent DLL's. First
+# we want to know what directory our dependent DLL was installed into:
+#
+get_target_property(_cmocka_dir cmocka_shared LOCATION_${CMOCKA_BUILD_TYPE})
+get_filename_component(_cmocka_path "${_cmocka_dir}" PATH)
+file(TO_NATIVE_PATH "${_cmocka_path}" _cmocka_path_native)
+
+set(CMOCKA_DLL_PATH "${_cmocka_path_native}" PARENT_SCOPE)
diff --git a/emCmocka/src/cmocka.c b/emCmocka/src/cmocka.c
new file mode 100644
index 0000000..32f65c6
--- /dev/null
+++ b/emCmocka/src/cmocka.c
@@ -0,0 +1,3327 @@
+/*
+ * Copyright 2008 Google Inc.
+ * Copyright 2014-2015 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
+
+#ifdef HAVE_SETJMP_H
+#include
+#endif
+
+#ifdef HAVE_STDIO_H
+#include
+#endif
+
+#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. */
+#define MALLOC_ALIGNMENT sizeof(size_t)
+
+/* Printf formatting for source code locations. */
+#define SOURCE_LOCATION_FORMAT "%s:%u"
+
+#if defined(HAVE_GCC_THREAD_LOCAL_STORAGE)
+# define CMOCKA_THREAD __thread
+#elif defined(HAVE_MSVC_THREAD_LOCAL_STORAGE)
+# define CMOCKA_THREAD __declspec(thread)
+#else
+# define CMOCKA_THREAD
+#endif
+
+#ifdef HAVE_CLOCK_REALTIME
+#define CMOCKA_CLOCK_GETTIME(clock_id, ts) clock_gettime((clock_id), (ts))
+#else
+#define CMOCKA_CLOCK_GETTIME(clock_id, ts)
+#endif
+
+#ifndef MAX
+#define MAX(a,b) ((a) < (b) ? (b) : (a))
+#endif
+
+/**
+ * POSIX has sigsetjmp/siglongjmp, while Windows only has setjmp/longjmp.
+ */
+#ifdef HAVE_SIGLONGJMP
+# define cm_jmp_buf sigjmp_buf
+# define cm_setjmp(env) sigsetjmp(env, 1)
+# define cm_longjmp(env, val) siglongjmp(env, val)
+#else
+# define cm_jmp_buf jmp_buf
+# define cm_setjmp(env) setjmp(env)
+# define cm_longjmp(env, val) longjmp(env, val)
+#endif
+
+
+/*
+ * Declare and initialize the pointer member of ValuePointer variable name
+ * with ptr.
+ */
+#define declare_initialize_value_pointer_pointer(name, ptr) \
+ ValuePointer name ; \
+ name.value = 0; \
+ name.x.pointer = (void*)(ptr)
+
+/*
+ * Declare and initialize the value member of ValuePointer variable name
+ * with val.
+ */
+#define declare_initialize_value_pointer_value(name, val) \
+ ValuePointer name ; \
+ name.value = val
+
+/* Cast a LargestIntegralType to pointer_type via a ValuePointer. */
+#define cast_largest_integral_type_to_pointer( \
+ pointer_type, largest_integral_type) \
+ ((pointer_type)((ValuePointer*)&(largest_integral_type))->x.pointer)
+
+/* Used to cast LargetIntegralType to void* and vice versa. */
+typedef union ValuePointer {
+ LargestIntegralType value;
+ struct {
+#if defined(WORDS_BIGENDIAN) && (WORDS_SIZEOF_VOID_P == 4)
+ unsigned int padding;
+#endif
+ void *pointer;
+ } x;
+} ValuePointer;
+
+/* Doubly linked list node. */
+typedef struct ListNode {
+ const void *value;
+ int refcount;
+ struct ListNode *next;
+ struct ListNode *prev;
+} ListNode;
+
+/* Debug information for malloc(). */
+typedef struct MallocBlockInfo {
+ void* block; /* Address of the block returned by malloc(). */
+ size_t allocated_size; /* Total size of the allocated block. */
+ size_t size; /* Request block size. */
+ SourceLocation location; /* Where the block was allocated. */
+ ListNode node; /* Node within list of all allocated blocks. */
+} MallocBlockInfo;
+
+/* State of each test. */
+typedef struct TestState {
+ const ListNode *check_point; /* Check point of the test if there's a */
+ /* setup function. */
+ void *state; /* State associated with the test. */
+} TestState;
+
+/* Determines whether two values are the same. */
+typedef int (*EqualityFunction)(const void *left, const void *right);
+
+/* Value of a symbol and the place it was declared. */
+typedef struct SymbolValue {
+ SourceLocation location;
+ LargestIntegralType value;
+} SymbolValue;
+
+/*
+ * Contains a list of values for a symbol.
+ * NOTE: Each structure referenced by symbol_values_list_head must have a
+ * SourceLocation as its' first member.
+ */
+typedef struct SymbolMapValue {
+ const char *symbol_name;
+ ListNode symbol_values_list_head;
+} SymbolMapValue;
+
+/* Where a particular ordering was located and its symbol name */
+typedef struct FuncOrderingValue {
+ SourceLocation location;
+ const char * function;
+} FuncOrderingValue;
+
+/* Used by list_free() to deallocate values referenced by list nodes. */
+typedef void (*CleanupListValue)(const void *value, void *cleanup_value_data);
+
+/* Structure used to check the range of integer types.a */
+typedef struct CheckIntegerRange {
+ CheckParameterEvent event;
+ LargestIntegralType minimum;
+ LargestIntegralType maximum;
+} CheckIntegerRange;
+
+/* Structure used to check whether an integer value is in a set. */
+typedef struct CheckIntegerSet {
+ CheckParameterEvent event;
+ const LargestIntegralType *set;
+ size_t size_of_set;
+} CheckIntegerSet;
+
+/* Used to check whether a parameter matches the area of memory referenced by
+ * this structure. */
+typedef struct CheckMemoryData {
+ CheckParameterEvent event;
+ const void *memory;
+ size_t size;
+} CheckMemoryData;
+
+static ListNode* list_initialize(ListNode * const node);
+static ListNode* list_add(ListNode * const head, ListNode *new_node);
+static ListNode* list_add_value(ListNode * const head, const void *value,
+ const int count);
+static ListNode* list_remove(
+ ListNode * const node, const CleanupListValue cleanup_value,
+ void * const cleanup_value_data);
+static void list_remove_free(
+ ListNode * const node, const CleanupListValue cleanup_value,
+ void * const cleanup_value_data);
+static int list_empty(const ListNode * const head);
+static int list_find(
+ ListNode * const head, const void *value,
+ const EqualityFunction equal_func, ListNode **output);
+static int list_first(ListNode * const head, ListNode **output);
+static ListNode* list_free(
+ ListNode * const head, const CleanupListValue cleanup_value,
+ void * const cleanup_value_data);
+
+static void add_symbol_value(
+ ListNode * const symbol_map_head, const char * const symbol_names[],
+ const size_t number_of_symbol_names, const void* value, const int count);
+static int get_symbol_value(
+ ListNode * const symbol_map_head, const char * const symbol_names[],
+ const size_t number_of_symbol_names, void **output);
+static void free_value(const void *value, void *cleanup_value_data);
+static void free_symbol_map_value(
+ const void *value, void *cleanup_value_data);
+static void remove_always_return_values(ListNode * const map_head,
+ const size_t number_of_symbol_names);
+
+static int check_for_leftover_values_list(const ListNode * head,
+ const char * const error_message);
+
+static int check_for_leftover_values(
+ const ListNode * const map_head, const char * const error_message,
+ const size_t number_of_symbol_names);
+
+static void remove_always_return_values_from_list(ListNode * const map_head);
+
+/*
+ * This must be called at the beginning of a test to initialize some data
+ * structures.
+ */
+static void initialize_testing(const char *test_name);
+
+/* This must be called at the end of a test to free() allocated structures. */
+static void teardown_testing(const char *test_name);
+
+static enum cm_message_output cm_get_output(void);
+
+static int cm_error_message_enabled = 1;
+static CMOCKA_THREAD char *cm_error_message;
+
+void cm_print_error(const char * const format, ...) CMOCKA_PRINTF_ATTRIBUTE(1, 2);
+
+/*
+ * Keeps track of the calling context returned by setenv() so that the fail()
+ * method can jump out of a test.
+ */
+static CMOCKA_THREAD cm_jmp_buf global_run_test_env;
+static CMOCKA_THREAD int global_running_test = 0;
+
+/* Keeps track of the calling context returned by setenv() so that */
+/* mock_assert() can optionally jump back to expect_assert_failure(). */
+jmp_buf global_expect_assert_env;
+int global_expecting_assert = 0;
+const char *global_last_failed_assert = NULL;
+static int global_skip_test;
+
+/* Keeps a map of the values that functions will have to return to provide */
+/* mocked interfaces. */
+static CMOCKA_THREAD ListNode global_function_result_map_head;
+/* Location of the last mock value returned was declared. */
+static CMOCKA_THREAD SourceLocation global_last_mock_value_location;
+
+/* Keeps a map of the values that functions expect as parameters to their
+ * mocked interfaces. */
+static CMOCKA_THREAD ListNode global_function_parameter_map_head;
+/* Location of last parameter value checked was declared. */
+static CMOCKA_THREAD SourceLocation global_last_parameter_location;
+
+/* List (acting as FIFO) of call ordering. */
+static CMOCKA_THREAD ListNode global_call_ordering_head;
+/* Location of last call ordering that was declared. */
+static CMOCKA_THREAD SourceLocation global_last_call_ordering_location;
+
+/* List of all currently allocated blocks. */
+static CMOCKA_THREAD ListNode global_allocated_blocks;
+
+static enum cm_message_output global_msg_output = CM_OUTPUT_STDOUT;
+
+#ifdef HAVE_SIGNAL_H
+#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;
+
+#endif // HAVE_SIGNAL_H
+
+/* Fatal exceptions. */
+typedef struct ExceptionCodeInfo {
+ DWORD code;
+ const char* description;
+} ExceptionCodeInfo;
+
+#define EXCEPTION_CODE_INFO(exception_code) {exception_code, #exception_code}
+
+static const ExceptionCodeInfo exception_codes[] = {
+ EXCEPTION_CODE_INFO(EXCEPTION_ACCESS_VIOLATION),
+ EXCEPTION_CODE_INFO(EXCEPTION_ARRAY_BOUNDS_EXCEEDED),
+ EXCEPTION_CODE_INFO(EXCEPTION_DATATYPE_MISALIGNMENT),
+ EXCEPTION_CODE_INFO(EXCEPTION_FLT_DENORMAL_OPERAND),
+ EXCEPTION_CODE_INFO(EXCEPTION_FLT_DIVIDE_BY_ZERO),
+ EXCEPTION_CODE_INFO(EXCEPTION_FLT_INEXACT_RESULT),
+ EXCEPTION_CODE_INFO(EXCEPTION_FLT_INVALID_OPERATION),
+ EXCEPTION_CODE_INFO(EXCEPTION_FLT_OVERFLOW),
+ EXCEPTION_CODE_INFO(EXCEPTION_FLT_STACK_CHECK),
+ EXCEPTION_CODE_INFO(EXCEPTION_FLT_UNDERFLOW),
+ EXCEPTION_CODE_INFO(EXCEPTION_GUARD_PAGE),
+ EXCEPTION_CODE_INFO(EXCEPTION_ILLEGAL_INSTRUCTION),
+ EXCEPTION_CODE_INFO(EXCEPTION_INT_DIVIDE_BY_ZERO),
+ EXCEPTION_CODE_INFO(EXCEPTION_INT_OVERFLOW),
+ EXCEPTION_CODE_INFO(EXCEPTION_INVALID_DISPOSITION),
+ EXCEPTION_CODE_INFO(EXCEPTION_INVALID_HANDLE),
+ EXCEPTION_CODE_INFO(EXCEPTION_IN_PAGE_ERROR),
+ EXCEPTION_CODE_INFO(EXCEPTION_NONCONTINUABLE_EXCEPTION),
+ EXCEPTION_CODE_INFO(EXCEPTION_PRIV_INSTRUCTION),
+ EXCEPTION_CODE_INFO(EXCEPTION_STACK_OVERFLOW),
+};
+#endif /* !_WIN32 */
+
+enum CMUnitTestStatus {
+ CM_TEST_NOT_STARTED,
+ CM_TEST_PASSED,
+ CM_TEST_FAILED,
+ CM_TEST_ERROR,
+ CM_TEST_SKIPPED,
+};
+
+struct CMUnitTestState {
+ const ListNode *check_point; /* Check point of the test if there's a setup function. */
+ const struct CMUnitTest *test; /* Point to array element in the tests we get passed */
+ void *state; /* State associated with the test */
+ const char *error_message; /* The error messages by the test */
+ enum CMUnitTestStatus status; /* PASSED, FAILED, ABORT ... */
+ double runtime; /* Time calculations */
+};
+
+/* Exit the currently executing test. */
+static void exit_test(const int quit_application)
+{
+ const char *abort_test = getenv("CMOCKA_TEST_ABORT");
+
+ if (abort_test != NULL && abort_test[0] == '1') {
+ print_error("%s", cm_error_message);
+ abort();
+ } else if (global_running_test) {
+ cm_longjmp(global_run_test_env, 1);
+ } else if (quit_application) {
+ exit(-1);
+ }
+}
+
+void _skip(const char * const file, const int line)
+{
+ cm_print_error(SOURCE_LOCATION_FORMAT ": Skipped!\n", file, line);
+ global_skip_test = 1;
+ exit_test(1);
+}
+
+/* Initialize a SourceLocation structure. */
+static void initialize_source_location(SourceLocation * const location) {
+ assert_non_null(location);
+ location->file = NULL;
+ location->line = 0;
+}
+
+
+/* Determine whether a source location is currently set. */
+static int source_location_is_set(const SourceLocation * const location) {
+ assert_non_null(location);
+ return location->file && location->line;
+}
+
+
+/* Set a source location. */
+static void set_source_location(
+ SourceLocation * const location, const char * const file,
+ const int line) {
+ assert_non_null(location);
+ location->file = file;
+ location->line = line;
+}
+
+
+static int c_strreplace(char *src,
+ size_t src_len,
+ const char *pattern,
+ const char *repl,
+ int *str_replaced)
+{
+ char *p = NULL;
+
+ p = strstr(src, pattern);
+ if (p == NULL) {
+ return -1;
+ }
+
+ do {
+ size_t of = p - src;
+ size_t l = strlen(src);
+ size_t pl = strlen(pattern);
+ size_t rl = strlen(repl);
+
+ /* overflow check */
+ if (src_len <= l + MAX(pl, rl) + 1) {
+ return -1;
+ }
+
+ if (rl != pl) {
+ memmove(src + of + rl, src + of + pl, l - of - pl + 1);
+ }
+
+ strncpy(src + of, repl, rl);
+
+ if (str_replaced != NULL) {
+ *str_replaced = 1;
+ }
+ p = strstr(src, pattern);
+ } while (p != NULL);
+
+ return 0;
+}
+
+/* Create function results and expected parameter lists. */
+void initialize_testing(const char *test_name) {
+ (void)test_name;
+ list_initialize(&global_function_result_map_head);
+ initialize_source_location(&global_last_mock_value_location);
+ list_initialize(&global_function_parameter_map_head);
+ initialize_source_location(&global_last_parameter_location);
+ list_initialize(&global_call_ordering_head);
+ initialize_source_location(&global_last_parameter_location);
+}
+
+
+static void fail_if_leftover_values(const char *test_name) {
+ int error_occurred = 0;
+ (void)test_name;
+ remove_always_return_values(&global_function_result_map_head, 1);
+ if (check_for_leftover_values(
+ &global_function_result_map_head,
+ "%s() has remaining non-returned values.\n", 1)) {
+ error_occurred = 1;
+ }
+
+ remove_always_return_values(&global_function_parameter_map_head, 2);
+ if (check_for_leftover_values(
+ &global_function_parameter_map_head,
+ "%s parameter still has values that haven't been checked.\n", 2)) {
+ error_occurred = 1;
+ }
+
+ remove_always_return_values_from_list(&global_call_ordering_head);
+ if (check_for_leftover_values_list(&global_call_ordering_head,
+ "%s function was expected to be called but was not not.\n")) {
+ error_occurred = 1;
+ }
+ if (error_occurred) {
+ exit_test(1);
+ }
+}
+
+
+static void teardown_testing(const char *test_name) {
+ (void)test_name;
+ list_free(&global_function_result_map_head, free_symbol_map_value,
+ (void*)0);
+ initialize_source_location(&global_last_mock_value_location);
+ list_free(&global_function_parameter_map_head, free_symbol_map_value,
+ (void*)1);
+ initialize_source_location(&global_last_parameter_location);
+ list_free(&global_call_ordering_head, free_value,
+ (void*)0);
+ initialize_source_location(&global_last_call_ordering_location);
+}
+
+/* Initialize a list node. */
+static ListNode* list_initialize(ListNode * const node) {
+ node->value = NULL;
+ node->next = node;
+ node->prev = node;
+ node->refcount = 1;
+ return node;
+}
+
+
+/*
+ * Adds a value at the tail of a given list.
+ * The node referencing the value is allocated from the heap.
+ */
+static ListNode* list_add_value(ListNode * const head, const void *value,
+ const int refcount) {
+ ListNode * const new_node = (ListNode*)malloc(sizeof(ListNode));
+ assert_non_null(head);
+ assert_non_null(value);
+ new_node->value = value;
+ new_node->refcount = refcount;
+ return list_add(head, new_node);
+}
+
+
+/* Add new_node to the end of the list. */
+static ListNode* list_add(ListNode * const head, ListNode *new_node) {
+ assert_non_null(head);
+ assert_non_null(new_node);
+ new_node->next = head;
+ new_node->prev = head->prev;
+ head->prev->next = new_node;
+ head->prev = new_node;
+ return new_node;
+}
+
+
+/* Remove a node from a list. */
+static ListNode* list_remove(
+ ListNode * const node, const CleanupListValue cleanup_value,
+ void * const cleanup_value_data) {
+ assert_non_null(node);
+ node->prev->next = node->next;
+ node->next->prev = node->prev;
+ if (cleanup_value) {
+ cleanup_value(node->value, cleanup_value_data);
+ }
+ return node;
+}
+
+
+/* Remove a list node from a list and free the node. */
+static void list_remove_free(
+ ListNode * const node, const CleanupListValue cleanup_value,
+ void * const cleanup_value_data) {
+ assert_non_null(node);
+ free(list_remove(node, cleanup_value, cleanup_value_data));
+}
+
+
+/*
+ * Frees memory kept by a linked list The cleanup_value function is called for
+ * every "value" field of nodes in the list, except for the head. In addition
+ * to each list value, cleanup_value_data is passed to each call to
+ * cleanup_value. The head of the list is not deallocated.
+ */
+static ListNode* list_free(
+ ListNode * const head, const CleanupListValue cleanup_value,
+ void * const cleanup_value_data) {
+ assert_non_null(head);
+ while (!list_empty(head)) {
+ list_remove_free(head->next, cleanup_value, cleanup_value_data);
+ }
+ return head;
+}
+
+
+/* Determine whether a list is empty. */
+static int list_empty(const ListNode * const head) {
+ assert_non_null(head);
+ return head->next == head;
+}
+
+
+/*
+ * Find a value in the list using the equal_func to compare each node with the
+ * value.
+ */
+static int list_find(ListNode * const head, const void *value,
+ const EqualityFunction equal_func, ListNode **output) {
+ ListNode *current;
+ assert_non_null(head);
+ for (current = head->next; current != head; current = current->next) {
+ if (equal_func(current->value, value)) {
+ *output = current;
+ return 1;
+ }
+ }
+ return 0;
+}
+
+/* Returns the first node of a list */
+static int list_first(ListNode * const head, ListNode **output) {
+ ListNode *target_node;
+ assert_non_null(head);
+ if (list_empty(head)) {
+ return 0;
+ }
+ target_node = head->next;
+ *output = target_node;
+ return 1;
+}
+
+
+/* Deallocate a value referenced by a list. */
+static void free_value(const void *value, void *cleanup_value_data) {
+ (void)cleanup_value_data;
+ assert_non_null(value);
+ free((void*)value);
+}
+
+
+/* Releases memory associated to a symbol_map_value. */
+static void free_symbol_map_value(const void *value,
+ void *cleanup_value_data) {
+ SymbolMapValue * const map_value = (SymbolMapValue*)value;
+ const LargestIntegralType children = cast_ptr_to_largest_integral_type(cleanup_value_data);
+ assert_non_null(value);
+ list_free(&map_value->symbol_values_list_head,
+ children ? free_symbol_map_value : free_value,
+ (void *) ((uintptr_t)children - 1));
+ free(map_value);
+}
+
+
+/*
+ * Determine whether a symbol name referenced by a symbol_map_value matches the
+ * specified function name.
+ */
+static int symbol_names_match(const void *map_value, const void *symbol) {
+ return !strcmp(((SymbolMapValue*)map_value)->symbol_name,
+ (const char*)symbol);
+}
+
+/*
+ * Adds a value to the queue of values associated with the given hierarchy of
+ * symbols. It's assumed value is allocated from the heap.
+ */
+static void add_symbol_value(ListNode * const symbol_map_head,
+ const char * const symbol_names[],
+ const size_t number_of_symbol_names,
+ const void* value, const int refcount) {
+ const char* symbol_name;
+ ListNode *target_node;
+ SymbolMapValue *target_map_value;
+ assert_non_null(symbol_map_head);
+ assert_non_null(symbol_names);
+ assert_true(number_of_symbol_names);
+ symbol_name = symbol_names[0];
+
+ if (!list_find(symbol_map_head, symbol_name, symbol_names_match,
+ &target_node)) {
+ SymbolMapValue * const new_symbol_map_value =
+ (SymbolMapValue*)malloc(sizeof(*new_symbol_map_value));
+ new_symbol_map_value->symbol_name = symbol_name;
+ list_initialize(&new_symbol_map_value->symbol_values_list_head);
+ target_node = list_add_value(symbol_map_head, new_symbol_map_value,
+ 1);
+ }
+
+ target_map_value = (SymbolMapValue*)target_node->value;
+ if (number_of_symbol_names == 1) {
+ list_add_value(&target_map_value->symbol_values_list_head,
+ value, refcount);
+ } else {
+ add_symbol_value(&target_map_value->symbol_values_list_head,
+ &symbol_names[1], number_of_symbol_names - 1, value,
+ refcount);
+ }
+}
+
+
+/*
+ * Gets the next value associated with the given hierarchy of symbols.
+ * The value is returned as an output parameter with the function returning the
+ * node's old refcount value if a value is found, 0 otherwise. This means that
+ * a return value of 1 indicates the node was just removed from the list.
+ */
+static int get_symbol_value(
+ ListNode * const head, const char * const symbol_names[],
+ const size_t number_of_symbol_names, void **output) {
+ const char* symbol_name;
+ ListNode *target_node;
+ assert_non_null(head);
+ assert_non_null(symbol_names);
+ assert_true(number_of_symbol_names);
+ assert_non_null(output);
+ symbol_name = symbol_names[0];
+
+ if (list_find(head, symbol_name, symbol_names_match, &target_node)) {
+ SymbolMapValue *map_value;
+ ListNode *child_list;
+ int return_value = 0;
+ assert_non_null(target_node);
+ assert_non_null(target_node->value);
+
+ map_value = (SymbolMapValue*)target_node->value;
+ child_list = &map_value->symbol_values_list_head;
+
+ if (number_of_symbol_names == 1) {
+ ListNode *value_node = NULL;
+ return_value = list_first(child_list, &value_node);
+ assert_true(return_value);
+ *output = (void*) value_node->value;
+ return_value = value_node->refcount;
+ if (value_node->refcount - 1 == 0) {
+ list_remove_free(value_node, NULL, NULL);
+ } else if (value_node->refcount > WILL_RETURN_ONCE) {
+ --value_node->refcount;
+ }
+ } else {
+ return_value = get_symbol_value(
+ child_list, &symbol_names[1], number_of_symbol_names - 1,
+ output);
+ }
+ if (list_empty(child_list)) {
+ list_remove_free(target_node, free_symbol_map_value, (void*)0);
+ }
+ return return_value;
+ } else {
+ cm_print_error("No entries for symbol %s.\n", symbol_name);
+ }
+ return 0;
+}
+
+/**
+ * Taverse a list of nodes and remove first symbol value in list that has a
+ * refcount < -1 (i.e. should always be returned and has been returned at
+ * least once).
+ */
+
+static void remove_always_return_values_from_list(ListNode * const map_head)
+{
+ ListNode * current = NULL;
+ ListNode * next = NULL;
+ assert_non_null(map_head);
+
+ for (current = map_head->next, next = current->next;
+ current != map_head;
+ current = next, next = current->next) {
+ if (current->refcount < -1) {
+ list_remove_free(current, free_value, NULL);
+ }
+ }
+}
+
+/*
+ * Traverse down a tree of symbol values and remove the first symbol value
+ * in each branch that has a refcount < -1 (i.e should always be returned
+ * and has been returned at least once).
+ */
+static void remove_always_return_values(ListNode * const map_head,
+ const size_t number_of_symbol_names) {
+ ListNode *current;
+ assert_non_null(map_head);
+ assert_true(number_of_symbol_names);
+ current = map_head->next;
+ while (current != map_head) {
+ SymbolMapValue * const value = (SymbolMapValue*)current->value;
+ ListNode * const next = current->next;
+ ListNode *child_list;
+ assert_non_null(value);
+ child_list = &value->symbol_values_list_head;
+
+ if (!list_empty(child_list)) {
+ if (number_of_symbol_names == 1) {
+ ListNode * const child_node = child_list->next;
+ /* If this item has been returned more than once, free it. */
+ if (child_node->refcount < -1) {
+ list_remove_free(child_node, free_value, NULL);
+ }
+ } else {
+ remove_always_return_values(child_list,
+ number_of_symbol_names - 1);
+ }
+ }
+
+ if (list_empty(child_list)) {
+ list_remove_free(current, free_value, NULL);
+ }
+ current = next;
+ }
+}
+
+static int check_for_leftover_values_list(const ListNode * head,
+ const char * const error_message)
+{
+ ListNode *child_node;
+ int leftover_count = 0;
+ if (!list_empty(head))
+ {
+ for (child_node = head->next; child_node != head;
+ child_node = child_node->next, ++leftover_count) {
+ const FuncOrderingValue *const o =
+ (const FuncOrderingValue*) child_node->value;
+ cm_print_error(error_message, o->function);
+ cm_print_error(SOURCE_LOCATION_FORMAT
+ ": note: remaining item was declared here\n",
+ o->location.file, o->location.line);
+ }
+ }
+ return leftover_count;
+}
+
+/*
+ * Checks if there are any leftover values set up by the test that were never
+ * retrieved through execution, and fail the test if that is the case.
+ */
+static int check_for_leftover_values(
+ const ListNode * const map_head, const char * const error_message,
+ const size_t number_of_symbol_names) {
+ const ListNode *current;
+ int symbols_with_leftover_values = 0;
+ assert_non_null(map_head);
+ assert_true(number_of_symbol_names);
+
+ for (current = map_head->next; current != map_head;
+ current = current->next) {
+ const SymbolMapValue * const value =
+ (SymbolMapValue*)current->value;
+ const ListNode *child_list;
+ assert_non_null(value);
+ child_list = &value->symbol_values_list_head;
+
+ if (!list_empty(child_list)) {
+ if (number_of_symbol_names == 1) {
+ const ListNode *child_node;
+ cm_print_error(error_message, value->symbol_name);
+
+ for (child_node = child_list->next; child_node != child_list;
+ child_node = child_node->next) {
+ const SourceLocation * const location =
+ (const SourceLocation*)child_node->value;
+ cm_print_error(SOURCE_LOCATION_FORMAT
+ ": note: remaining item was declared here\n",
+ location->file, location->line);
+ }
+ } else {
+ cm_print_error("%s.", value->symbol_name);
+ check_for_leftover_values(child_list, error_message,
+ number_of_symbol_names - 1);
+ }
+ symbols_with_leftover_values ++;
+ }
+ }
+ return symbols_with_leftover_values;
+}
+
+
+/* Get the next return value for the specified mock function. */
+LargestIntegralType _mock(const char * const function, const char* const file,
+ const int line) {
+ void *result;
+ const int rc = get_symbol_value(&global_function_result_map_head,
+ &function, 1, &result);
+ if (rc) {
+ SymbolValue * const symbol = (SymbolValue*)result;
+ const LargestIntegralType value = symbol->value;
+ global_last_mock_value_location = symbol->location;
+ if (rc == 1) {
+ free(symbol);
+ }
+ return value;
+ } else {
+ cm_print_error(SOURCE_LOCATION_FORMAT ": error: Could not get value "
+ "to mock function %s\n", file, line, function);
+ if (source_location_is_set(&global_last_mock_value_location)) {
+ cm_print_error(SOURCE_LOCATION_FORMAT
+ ": note: Previously returned mock value was declared here\n",
+ global_last_mock_value_location.file,
+ global_last_mock_value_location.line);
+ } else {
+ cm_print_error("There were no previously returned mock values for "
+ "this test.\n");
+ }
+ exit_test(1);
+ }
+ return 0;
+}
+
+/* Ensure that function is being called in proper order */
+void _function_called(const char *const function,
+ const char *const file,
+ const int line)
+{
+ ListNode *first_value_node = NULL;
+ ListNode *value_node = NULL;
+ int rc;
+
+ rc = list_first(&global_call_ordering_head, &value_node);
+ first_value_node = value_node;
+ if (rc) {
+ FuncOrderingValue *expected_call;
+ int cmp;
+
+ expected_call = (FuncOrderingValue *)value_node->value;
+
+ cmp = strcmp(expected_call->function, function);
+ if (value_node->refcount < -1) {
+ /*
+ * Search through value nodes until either function is found or
+ * encounter a non-zero refcount greater than -2
+ */
+ if (cmp != 0) {
+ value_node = value_node->next;
+ expected_call = (FuncOrderingValue *)value_node->value;
+
+ cmp = strcmp(expected_call->function, function);
+ while (value_node->refcount < -1 &&
+ cmp != 0 &&
+ value_node != first_value_node->prev) {
+ value_node = value_node->next;
+ if (value_node == NULL) {
+ break;
+ }
+ expected_call = (FuncOrderingValue *)value_node->value;
+ if (expected_call == NULL) {
+ continue;
+ }
+ cmp = strcmp(expected_call->function, function);
+ }
+
+ if (expected_call == NULL || value_node == first_value_node->prev) {
+ cm_print_error(SOURCE_LOCATION_FORMAT
+ ": error: No expected mock calls matching "
+ "called() invocation in %s",
+ file, line,
+ function);
+ exit_test(1);
+ }
+ }
+ }
+
+ if (cmp == 0) {
+ if (value_node->refcount > -2 && --value_node->refcount == 0) {
+ list_remove_free(value_node, free_value, NULL);
+ }
+ } else {
+ cm_print_error(SOURCE_LOCATION_FORMAT
+ ": error: Expected call to %s but received called() "
+ "in %s\n",
+ file, line,
+ expected_call->function,
+ function);
+ exit_test(1);
+ }
+ } else {
+ cm_print_error(SOURCE_LOCATION_FORMAT
+ ": error: No mock calls expected but called() was "
+ "invoked in %s\n",
+ file, line,
+ function);
+ exit_test(1);
+ }
+}
+
+/* Add a return value for the specified mock function name. */
+void _will_return(const char * const function_name, const char * const file,
+ const int line, const LargestIntegralType value,
+ const int count) {
+ SymbolValue * const return_value =
+ (SymbolValue*)malloc(sizeof(*return_value));
+ assert_true(count != 0);
+ return_value->value = value;
+ set_source_location(&return_value->location, file, line);
+ add_symbol_value(&global_function_result_map_head, &function_name, 1,
+ return_value, count);
+}
+
+
+/*
+ * Add a custom parameter checking function. If the event parameter is NULL
+ * the event structure is allocated internally by this function. If event
+ * parameter is provided it must be allocated on the heap and doesn't need to
+ * be deallocated by the caller.
+ */
+void _expect_check(
+ const char* const function, const char* const parameter,
+ const char* const file, const int line,
+ const CheckParameterValue check_function,
+ const LargestIntegralType check_data,
+ CheckParameterEvent * const event, const int count) {
+ CheckParameterEvent * const check =
+ event ? event : (CheckParameterEvent*)malloc(sizeof(*check));
+ const char* symbols[] = {function, parameter};
+ check->parameter_name = parameter;
+ check->check_value = check_function;
+ check->check_value_data = check_data;
+ set_source_location(&check->location, file, line);
+ add_symbol_value(&global_function_parameter_map_head, symbols, 2, check,
+ count);
+}
+
+/*
+ * Add an call expectations that a particular function is called correctly.
+ * This is used for code under test that makes calls to several functions
+ * in depended upon components (mocks).
+ */
+
+void _expect_function_call(
+ const char * const function_name,
+ const char * const file,
+ const int line,
+ const int count)
+{
+ FuncOrderingValue *ordering;
+
+ assert_non_null(function_name);
+ assert_non_null(file);
+ assert_true(count != 0);
+
+ ordering = (FuncOrderingValue *)malloc(sizeof(*ordering));
+
+ set_source_location(&ordering->location, file, line);
+ ordering->function = function_name;
+
+ list_add_value(&global_call_ordering_head, ordering, count);
+}
+
+/* Returns 1 if the specified values are equal. If the values are not equal
+ * an error is displayed and 0 is returned. */
+static int values_equal_display_error(const LargestIntegralType left,
+ const LargestIntegralType right) {
+ const int equal = left == right;
+ if (!equal) {
+ cm_print_error(LargestIntegralTypePrintfFormat " != "
+ LargestIntegralTypePrintfFormat "\n", left, right);
+ }
+ return equal;
+}
+
+/*
+ * Returns 1 if the specified values are not equal. If the values are equal
+ * an error is displayed and 0 is returned. */
+static int values_not_equal_display_error(const LargestIntegralType left,
+ const LargestIntegralType right) {
+ const int not_equal = left != right;
+ if (!not_equal) {
+ cm_print_error(LargestIntegralTypePrintfFormat " == "
+ LargestIntegralTypePrintfFormat "\n", left, right);
+ }
+ return not_equal;
+}
+
+
+/*
+ * Determine whether value is contained within check_integer_set.
+ * If invert is 0 and the value is in the set 1 is returned, otherwise 0 is
+ * returned and an error is displayed. If invert is 1 and the value is not
+ * in the set 1 is returned, otherwise 0 is returned and an error is
+ * displayed.
+ */
+static int value_in_set_display_error(
+ const LargestIntegralType value,
+ const CheckIntegerSet * const check_integer_set, const int invert) {
+ int succeeded = invert;
+ assert_non_null(check_integer_set);
+ {
+ const LargestIntegralType * const set = check_integer_set->set;
+ const size_t size_of_set = check_integer_set->size_of_set;
+ size_t i;
+ for (i = 0; i < size_of_set; i++) {
+ if (set[i] == value) {
+ /* If invert = 0 and item is found, succeeded = 1. */
+ /* If invert = 1 and item is found, succeeded = 0. */
+ succeeded = !succeeded;
+ break;
+ }
+ }
+ if (succeeded) {
+ return 1;
+ }
+ cm_print_error(LargestIntegralTypePrintfFormatDecimal
+ " is %sin the set (",
+ value, invert ? "" : "not ");
+ for (i = 0; i < size_of_set; i++) {
+ cm_print_error(LargestIntegralTypePrintfFormat ", ", set[i]);
+ }
+ cm_print_error(")\n");
+ }
+ return 0;
+}
+
+
+/*
+ * Determine whether a value is within the specified range. If the value is
+ * within the specified range 1 is returned. If the value isn't within the
+ * specified range an error is displayed and 0 is returned.
+ */
+static int integer_in_range_display_error(
+ const LargestIntegralType value, const LargestIntegralType range_min,
+ const LargestIntegralType range_max) {
+ if (value >= range_min && value <= range_max) {
+ return 1;
+ }
+ cm_print_error(LargestIntegralTypePrintfFormatDecimal
+ " is not within the range "
+ LargestIntegralTypePrintfFormatDecimal "-"
+ LargestIntegralTypePrintfFormatDecimal "\n",
+ value, range_min, range_max);
+ return 0;
+}
+
+
+/*
+ * Determine whether a value is within the specified range. If the value
+ * is not within the range 1 is returned. If the value is within the
+ * specified range an error is displayed and zero is returned.
+ */
+static int integer_not_in_range_display_error(
+ const LargestIntegralType value, const LargestIntegralType range_min,
+ const LargestIntegralType range_max) {
+ if (value < range_min || value > range_max) {
+ return 1;
+ }
+ cm_print_error(LargestIntegralTypePrintfFormatDecimal
+ " is within the range "
+ LargestIntegralTypePrintfFormatDecimal "-"
+ LargestIntegralTypePrintfFormatDecimal "\n",
+ value, range_min, range_max);
+ return 0;
+}
+
+
+/*
+ * Determine whether the specified strings are equal. If the strings are equal
+ * 1 is returned. If they're not equal an error is displayed and 0 is
+ * returned.
+ */
+static int string_equal_display_error(
+ const char * const left, const char * const right) {
+ if (strcmp(left, right) == 0) {
+ return 1;
+ }
+ cm_print_error("\"%s\" != \"%s\"\n", left, right);
+ return 0;
+}
+
+
+/*
+ * Determine whether the specified strings are equal. If the strings are not
+ * equal 1 is returned. If they're not equal an error is displayed and 0 is
+ * returned
+ */
+static int string_not_equal_display_error(
+ const char * const left, const char * const right) {
+ if (strcmp(left, right) != 0) {
+ return 1;
+ }
+ cm_print_error("\"%s\" == \"%s\"\n", left, right);
+ return 0;
+}
+
+
+/*
+ * Determine whether the specified areas of memory are equal. If they're equal
+ * 1 is returned otherwise an error is displayed and 0 is returned.
+ */
+static int memory_equal_display_error(const char* const a, const char* const b,
+ const size_t size) {
+ int differences = 0;
+ size_t i;
+ for (i = 0; i < size; i++) {
+ const char l = a[i];
+ const char r = b[i];
+ if (l != r) {
+ cm_print_error("difference at offset %" PRIdS " 0x%02x 0x%02x\n",
+ i, l, r);
+ differences ++;
+ }
+ }
+ if (differences) {
+ cm_print_error("%d bytes of %p and %p differ\n",
+ differences, (void *)a, (void *)b);
+ return 0;
+ }
+ return 1;
+}
+
+
+/*
+ * Determine whether the specified areas of memory are not equal. If they're
+ * not equal 1 is returned otherwise an error is displayed and 0 is
+ * returned.
+ */
+static int memory_not_equal_display_error(
+ const char* const a, const char* const b, const size_t size) {
+ size_t same = 0;
+ size_t i;
+ for (i = 0; i < size; i++) {
+ const char l = a[i];
+ const char r = b[i];
+ if (l == r) {
+ same ++;
+ }
+ }
+ if (same == size) {
+ cm_print_error("%"PRIdS "bytes of %p and %p the same\n",
+ same, (void *)a, (void *)b);
+ return 0;
+ }
+ return 1;
+}
+
+
+/* CheckParameterValue callback to check whether a value is within a set. */
+static int check_in_set(const LargestIntegralType value,
+ const LargestIntegralType check_value_data) {
+ return value_in_set_display_error(value,
+ cast_largest_integral_type_to_pointer(CheckIntegerSet*,
+ check_value_data), 0);
+}
+
+
+/* CheckParameterValue callback to check whether a value isn't within a set. */
+static int check_not_in_set(const LargestIntegralType value,
+ const LargestIntegralType check_value_data) {
+ return value_in_set_display_error(value,
+ cast_largest_integral_type_to_pointer(CheckIntegerSet*,
+ check_value_data), 1);
+}
+
+
+/* Create the callback data for check_in_set() or check_not_in_set() and
+ * register a check event. */
+static void expect_set(
+ const char* const function, const char* const parameter,
+ const char* const file, const int line,
+ const LargestIntegralType values[], const size_t number_of_values,
+ const CheckParameterValue check_function, const int count) {
+ CheckIntegerSet * const check_integer_set =
+ (CheckIntegerSet*)malloc(sizeof(*check_integer_set) +
+ (sizeof(values[0]) * number_of_values));
+ LargestIntegralType * const set = (LargestIntegralType*)(
+ check_integer_set + 1);
+ declare_initialize_value_pointer_pointer(check_data, check_integer_set);
+ assert_non_null(values);
+ assert_true(number_of_values);
+ memcpy(set, values, number_of_values * sizeof(values[0]));
+ check_integer_set->set = set;
+ check_integer_set->size_of_set = number_of_values;
+ _expect_check(
+ function, parameter, file, line, check_function,
+ check_data.value, &check_integer_set->event, count);
+}
+
+
+/* Add an event to check whether a value is in a set. */
+void _expect_in_set(
+ const char* const function, const char* const parameter,
+ const char* const file, const int line,
+ const LargestIntegralType values[], const size_t number_of_values,
+ const int count) {
+ expect_set(function, parameter, file, line, values, number_of_values,
+ check_in_set, count);
+}
+
+
+/* Add an event to check whether a value isn't in a set. */
+void _expect_not_in_set(
+ const char* const function, const char* const parameter,
+ const char* const file, const int line,
+ const LargestIntegralType values[], const size_t number_of_values,
+ const int count) {
+ expect_set(function, parameter, file, line, values, number_of_values,
+ check_not_in_set, count);
+}
+
+
+/* CheckParameterValue callback to check whether a value is within a range. */
+static int check_in_range(const LargestIntegralType value,
+ const LargestIntegralType check_value_data) {
+ CheckIntegerRange * const check_integer_range =
+ cast_largest_integral_type_to_pointer(CheckIntegerRange*,
+ check_value_data);
+ assert_non_null(check_integer_range);
+ return integer_in_range_display_error(value, check_integer_range->minimum,
+ check_integer_range->maximum);
+}
+
+
+/* CheckParameterValue callback to check whether a value is not within a range. */
+static int check_not_in_range(const LargestIntegralType value,
+ const LargestIntegralType check_value_data) {
+ CheckIntegerRange * const check_integer_range =
+ cast_largest_integral_type_to_pointer(CheckIntegerRange*,
+ check_value_data);
+ assert_non_null(check_integer_range);
+ return integer_not_in_range_display_error(
+ value, check_integer_range->minimum, check_integer_range->maximum);
+}
+
+
+/* Create the callback data for check_in_range() or check_not_in_range() and
+ * register a check event. */
+static void expect_range(
+ const char* const function, const char* const parameter,
+ const char* const file, const int line,
+ const LargestIntegralType minimum, const LargestIntegralType maximum,
+ const CheckParameterValue check_function, const int count) {
+ CheckIntegerRange * const check_integer_range =
+ (CheckIntegerRange*)malloc(sizeof(*check_integer_range));
+ declare_initialize_value_pointer_pointer(check_data, check_integer_range);
+ check_integer_range->minimum = minimum;
+ check_integer_range->maximum = maximum;
+ _expect_check(function, parameter, file, line, check_function,
+ check_data.value, &check_integer_range->event, count);
+}
+
+
+/* Add an event to determine whether a parameter is within a range. */
+void _expect_in_range(
+ const char* const function, const char* const parameter,
+ const char* const file, const int line,
+ const LargestIntegralType minimum, const LargestIntegralType maximum,
+ const int count) {
+ expect_range(function, parameter, file, line, minimum, maximum,
+ check_in_range, count);
+}
+
+
+/* Add an event to determine whether a parameter is not within a range. */
+void _expect_not_in_range(
+ const char* const function, const char* const parameter,
+ const char* const file, const int line,
+ const LargestIntegralType minimum, const LargestIntegralType maximum,
+ const int count) {
+ expect_range(function, parameter, file, line, minimum, maximum,
+ check_not_in_range, count);
+}
+
+
+/* CheckParameterValue callback to check whether a value is equal to an
+ * expected value. */
+static int check_value(const LargestIntegralType value,
+ const LargestIntegralType check_value_data) {
+ return values_equal_display_error(value, check_value_data);
+}
+
+
+/* Add an event to check a parameter equals an expected value. */
+void _expect_value(
+ const char* const function, const char* const parameter,
+ const char* const file, const int line,
+ const LargestIntegralType value, const int count) {
+ _expect_check(function, parameter, file, line, check_value, value, NULL,
+ count);
+}
+
+
+/* CheckParameterValue callback to check whether a value is not equal to an
+ * expected value. */
+static int check_not_value(const LargestIntegralType value,
+ const LargestIntegralType check_value_data) {
+ return values_not_equal_display_error(value, check_value_data);
+}
+
+
+/* Add an event to check a parameter is not equal to an expected value. */
+void _expect_not_value(
+ const char* const function, const char* const parameter,
+ const char* const file, const int line,
+ const LargestIntegralType value, const int count) {
+ _expect_check(function, parameter, file, line, check_not_value, value,
+ NULL, count);
+}
+
+
+/* CheckParameterValue callback to check whether a parameter equals a string. */
+static int check_string(const LargestIntegralType value,
+ const LargestIntegralType check_value_data) {
+ return string_equal_display_error(
+ cast_largest_integral_type_to_pointer(char*, value),
+ cast_largest_integral_type_to_pointer(char*, check_value_data));
+}
+
+
+/* Add an event to check whether a parameter is equal to a string. */
+void _expect_string(
+ const char* const function, const char* const parameter,
+ const char* const file, const int line, const char* string,
+ const int count) {
+ declare_initialize_value_pointer_pointer(string_pointer,
+ discard_const(string));
+ _expect_check(function, parameter, file, line, check_string,
+ string_pointer.value, NULL, count);
+}
+
+
+/* CheckParameterValue callback to check whether a parameter is not equals to
+ * a string. */
+static int check_not_string(const LargestIntegralType value,
+ const LargestIntegralType check_value_data) {
+ return string_not_equal_display_error(
+ cast_largest_integral_type_to_pointer(char*, value),
+ cast_largest_integral_type_to_pointer(char*, check_value_data));
+}
+
+
+/* Add an event to check whether a parameter is not equal to a string. */
+void _expect_not_string(
+ const char* const function, const char* const parameter,
+ const char* const file, const int line, const char* string,
+ const int count) {
+ declare_initialize_value_pointer_pointer(string_pointer,
+ discard_const(string));
+ _expect_check(function, parameter, file, line, check_not_string,
+ string_pointer.value, NULL, count);
+}
+
+/* CheckParameterValue callback to check whether a parameter equals an area of
+ * memory. */
+static int check_memory(const LargestIntegralType value,
+ const LargestIntegralType check_value_data) {
+ CheckMemoryData * const check = cast_largest_integral_type_to_pointer(
+ CheckMemoryData*, check_value_data);
+ assert_non_null(check);
+ return memory_equal_display_error(
+ cast_largest_integral_type_to_pointer(const char*, value),
+ (const char*)check->memory, check->size);
+}
+
+
+/* Create the callback data for check_memory() or check_not_memory() and
+ * register a check event. */
+static void expect_memory_setup(
+ const char* const function, const char* const parameter,
+ const char* const file, const int line,
+ const void * const memory, const size_t size,
+ const CheckParameterValue check_function, const int count) {
+ CheckMemoryData * const check_data =
+ (CheckMemoryData*)malloc(sizeof(*check_data) + size);
+ void * const mem = (void*)(check_data + 1);
+ declare_initialize_value_pointer_pointer(check_data_pointer, check_data);
+ assert_non_null(memory);
+ assert_true(size);
+ memcpy(mem, memory, size);
+ check_data->memory = mem;
+ check_data->size = size;
+ _expect_check(function, parameter, file, line, check_function,
+ check_data_pointer.value, &check_data->event, count);
+}
+
+
+/* Add an event to check whether a parameter matches an area of memory. */
+void _expect_memory(
+ const char* const function, const char* const parameter,
+ const char* const file, const int line, const void* const memory,
+ const size_t size, const int count) {
+ expect_memory_setup(function, parameter, file, line, memory, size,
+ check_memory, count);
+}
+
+
+/* CheckParameterValue callback to check whether a parameter is not equal to
+ * an area of memory. */
+static int check_not_memory(const LargestIntegralType value,
+ const LargestIntegralType check_value_data) {
+ CheckMemoryData * const check = cast_largest_integral_type_to_pointer(
+ CheckMemoryData*, check_value_data);
+ assert_non_null(check);
+ return memory_not_equal_display_error(
+ cast_largest_integral_type_to_pointer(const char*, value),
+ (const char*)check->memory,
+ check->size);
+}
+
+
+/* Add an event to check whether a parameter doesn't match an area of memory. */
+void _expect_not_memory(
+ const char* const function, const char* const parameter,
+ const char* const file, const int line, const void* const memory,
+ const size_t size, const int count) {
+ expect_memory_setup(function, parameter, file, line, memory, size,
+ check_not_memory, count);
+}
+
+
+/* CheckParameterValue callback that always returns 1. */
+static int check_any(const LargestIntegralType value,
+ const LargestIntegralType check_value_data) {
+ (void)value;
+ (void)check_value_data;
+ return 1;
+}
+
+
+/* Add an event to allow any value for a parameter. */
+void _expect_any(
+ const char* const function, const char* const parameter,
+ const char* const file, const int line, const int count) {
+ _expect_check(function, parameter, file, line, check_any, 0, NULL,
+ count);
+}
+
+
+void _check_expected(
+ const char * const function_name, const char * const parameter_name,
+ const char* file, const int line, const LargestIntegralType value) {
+ void *result;
+ const char* symbols[] = {function_name, parameter_name};
+ const int rc = get_symbol_value(&global_function_parameter_map_head,
+ symbols, 2, &result);
+ if (rc) {
+ CheckParameterEvent * const check = (CheckParameterEvent*)result;
+ int check_succeeded;
+ global_last_parameter_location = check->location;
+ check_succeeded = check->check_value(value, check->check_value_data);
+ if (rc == 1) {
+ free(check);
+ }
+ if (!check_succeeded) {
+ cm_print_error(SOURCE_LOCATION_FORMAT
+ ": error: Check of parameter %s, function %s failed\n"
+ SOURCE_LOCATION_FORMAT
+ ": note: Expected parameter declared here\n",
+ file, line,
+ parameter_name, function_name,
+ global_last_parameter_location.file,
+ global_last_parameter_location.line);
+ _fail(file, line);
+ }
+ } else {
+ cm_print_error(SOURCE_LOCATION_FORMAT ": error: Could not get value "
+ "to check parameter %s of function %s\n", file, line,
+ parameter_name, function_name);
+ if (source_location_is_set(&global_last_parameter_location)) {
+ cm_print_error(SOURCE_LOCATION_FORMAT
+ ": note: Previously declared parameter value was declared here\n",
+ global_last_parameter_location.file,
+ global_last_parameter_location.line);
+ } else {
+ cm_print_error("There were no previously declared parameter values "
+ "for this test.\n");
+ }
+ exit_test(1);
+ }
+}
+
+
+/* Replacement for assert. */
+void mock_assert(const int result, const char* const expression,
+ const char* const file, const int line) {
+ if (!result) {
+ if (global_expecting_assert) {
+ global_last_failed_assert = expression;
+ longjmp(global_expect_assert_env, result);
+ } else {
+ cm_print_error("ASSERT: %s\n", expression);
+ _fail(file, line);
+ }
+ }
+}
+
+
+void _assert_true(const LargestIntegralType result,
+ const char * const expression,
+ const char * const file, const int line) {
+ if (!result) {
+ cm_print_error("%s\n", expression);
+ _fail(file, line);
+ }
+}
+
+void _assert_return_code(const LargestIntegralType result,
+ size_t rlen,
+ const LargestIntegralType error,
+ const char * const expression,
+ const char * const file,
+ const int line)
+{
+ LargestIntegralType valmax;
+
+
+ switch (rlen) {
+ case 1:
+ valmax = 255;
+ break;
+ case 2:
+ valmax = 32767;
+ break;
+ case 4:
+ valmax = 2147483647;
+ break;
+ case 8:
+ default:
+ if (rlen > sizeof(valmax)) {
+ valmax = 2147483647;
+ } else {
+ valmax = 9223372036854775807L;
+ }
+ break;
+ }
+
+ if (result > valmax - 1) {
+ if (error > 0) {
+ cm_print_error("%s < 0, errno("
+ LargestIntegralTypePrintfFormatDecimal "): %s\n",
+ expression, error, strerror((int)error));
+ } else {
+ cm_print_error("%s < 0\n", expression);
+ }
+ _fail(file, line);
+ }
+}
+
+void _assert_int_equal(
+ const LargestIntegralType a, const LargestIntegralType b,
+ const char * const file, const int line) {
+ if (!values_equal_display_error(a, b)) {
+ _fail(file, line);
+ }
+}
+
+
+void _assert_int_not_equal(
+ const LargestIntegralType a, const LargestIntegralType b,
+ const char * const file, const int line) {
+ if (!values_not_equal_display_error(a, b)) {
+ _fail(file, line);
+ }
+}
+
+
+void _assert_string_equal(const char * const a, const char * const b,
+ const char * const file, const int line) {
+ if (!string_equal_display_error(a, b)) {
+ _fail(file, line);
+ }
+}
+
+
+void _assert_string_not_equal(const char * const a, const char * const b,
+ const char *file, const int line) {
+ if (!string_not_equal_display_error(a, b)) {
+ _fail(file, line);
+ }
+}
+
+
+void _assert_memory_equal(const void * const a, const void * const b,
+ const size_t size, const char* const file,
+ const int line) {
+ if (!memory_equal_display_error((const char*)a, (const char*)b, size)) {
+ _fail(file, line);
+ }
+}
+
+
+void _assert_memory_not_equal(const void * const a, const void * const b,
+ const size_t size, const char* const file,
+ const int line) {
+ if (!memory_not_equal_display_error((const char*)a, (const char*)b,
+ size)) {
+ _fail(file, line);
+ }
+}
+
+
+void _assert_in_range(
+ const LargestIntegralType value, const LargestIntegralType minimum,
+ const LargestIntegralType maximum, const char* const file,
+ const int line) {
+ if (!integer_in_range_display_error(value, minimum, maximum)) {
+ _fail(file, line);
+ }
+}
+
+void _assert_not_in_range(
+ const LargestIntegralType value, const LargestIntegralType minimum,
+ const LargestIntegralType maximum, const char* const file,
+ const int line) {
+ if (!integer_not_in_range_display_error(value, minimum, maximum)) {
+ _fail(file, line);
+ }
+}
+
+void _assert_in_set(const LargestIntegralType value,
+ const LargestIntegralType values[],
+ const size_t number_of_values, const char* const file,
+ const int line) {
+ CheckIntegerSet check_integer_set;
+ check_integer_set.set = values;
+ check_integer_set.size_of_set = number_of_values;
+ if (!value_in_set_display_error(value, &check_integer_set, 0)) {
+ _fail(file, line);
+ }
+}
+
+void _assert_not_in_set(const LargestIntegralType value,
+ const LargestIntegralType values[],
+ const size_t number_of_values, const char* const file,
+ const int line) {
+ CheckIntegerSet check_integer_set;
+ check_integer_set.set = values;
+ check_integer_set.size_of_set = number_of_values;
+ if (!value_in_set_display_error(value, &check_integer_set, 1)) {
+ _fail(file, line);
+ }
+}
+
+
+/* Get the list of allocated blocks. */
+static ListNode* get_allocated_blocks_list(void) {
+ /* If it initialized, initialize the list of allocated blocks. */
+ if (!global_allocated_blocks.value) {
+ list_initialize(&global_allocated_blocks);
+ global_allocated_blocks.value = (void*)1;
+ }
+ return &global_allocated_blocks;
+}
+
+static void *libc_malloc(size_t size)
+{
+#undef malloc
+ return malloc(size);
+#define malloc test_malloc
+}
+
+static void libc_free(void *ptr)
+{
+#undef free
+ free(ptr);
+#define free test_free
+}
+
+static void *libc_realloc(void *ptr, size_t size)
+{
+#undef realloc
+ return realloc(ptr, size);
+#define realloc test_realloc
+}
+
+static void vcm_print_error(const char* const format,
+ va_list args) CMOCKA_PRINTF_ATTRIBUTE(1, 0);
+
+/* It's important to use the libc malloc and free here otherwise
+ * the automatic free of leaked blocks can reap the error messages
+ */
+static void vcm_print_error(const char* const format, va_list args)
+{
+ char buffer[1024];
+ size_t msg_len = 0;
+ va_list ap;
+ int len;
+ va_copy(ap, args);
+
+ len = vsnprintf(buffer, sizeof(buffer), format, args);
+ if (len < 0) {
+ /* TODO */
+ goto end;
+ }
+
+ if (cm_error_message == NULL) {
+ /* CREATE MESSAGE */
+
+ cm_error_message = libc_malloc(len + 1);
+ if (cm_error_message == NULL) {
+ /* TODO */
+ goto end;
+ }
+ } else {
+ /* APPEND MESSAGE */
+ char *tmp;
+
+ msg_len = strlen(cm_error_message);
+ tmp = libc_realloc(cm_error_message, msg_len + len + 1);
+ if (tmp == NULL) {
+ goto end;
+ }
+ cm_error_message = tmp;
+ }
+
+ if (((size_t)len) < sizeof(buffer)) {
+ /* Use len + 1 to also copy '\0' */
+ memcpy(cm_error_message + msg_len, buffer, len + 1);
+ } else {
+ vsnprintf(cm_error_message + msg_len, len, format, ap);
+ }
+end:
+ va_end(ap);
+
+}
+
+static void vcm_free_error(char *err_msg)
+{
+ libc_free(err_msg);
+}
+
+/* Use the real malloc in this function. */
+#undef malloc
+void* _test_malloc(const size_t size, const char* file, const int line) {
+ char* ptr;
+ MallocBlockInfo *block_info;
+ ListNode * const block_list = get_allocated_blocks_list();
+ const size_t allocate_size = size + (MALLOC_GUARD_SIZE * 2) +
+ sizeof(*block_info) + MALLOC_ALIGNMENT;
+ char* const block = (char*)malloc(allocate_size);
+ assert_non_null(block);
+
+ /* Calculate the returned address. */
+ ptr = (char*)(((size_t)block + MALLOC_GUARD_SIZE + sizeof(*block_info) +
+ MALLOC_ALIGNMENT) & ~(MALLOC_ALIGNMENT - 1));
+
+ /* Initialize the guard blocks. */
+ memset(ptr - MALLOC_GUARD_SIZE, MALLOC_GUARD_PATTERN, MALLOC_GUARD_SIZE);
+ memset(ptr + size, MALLOC_GUARD_PATTERN, MALLOC_GUARD_SIZE);
+ memset(ptr, MALLOC_ALLOC_PATTERN, size);
+
+ block_info = (MallocBlockInfo*)(ptr - (MALLOC_GUARD_SIZE +
+ sizeof(*block_info)));
+ set_source_location(&block_info->location, file, line);
+ block_info->allocated_size = allocate_size;
+ block_info->size = size;
+ block_info->block = block;
+ block_info->node.value = block_info;
+ list_add(block_list, &block_info->node);
+ return ptr;
+}
+#define malloc test_malloc
+
+
+void* _test_calloc(const size_t number_of_elements, const size_t size,
+ const char* file, const int line) {
+ void* const ptr = _test_malloc(number_of_elements * size, file, line);
+ if (ptr) {
+ memset(ptr, 0, number_of_elements * size);
+ }
+ return ptr;
+}
+
+
+/* Use the real free in this function. */
+#undef free
+void _test_free(void* const ptr, const char* file, const int line) {
+ unsigned int i;
+ char *block = discard_const_p(char, ptr);
+ MallocBlockInfo *block_info;
+
+ if (ptr == NULL) {
+ return;
+ }
+
+ _assert_true(cast_ptr_to_largest_integral_type(ptr), "ptr", file, line);
+ block_info = (MallocBlockInfo*)(block - (MALLOC_GUARD_SIZE +
+ sizeof(*block_info)));
+ /* Check the guard blocks. */
+ {
+ char *guards[2] = {block - MALLOC_GUARD_SIZE,
+ block + block_info->size};
+ for (i = 0; i < ARRAY_SIZE(guards); i++) {
+ unsigned int j;
+ char * const guard = guards[i];
+ for (j = 0; j < MALLOC_GUARD_SIZE; j++) {
+ const char diff = guard[j] - MALLOC_GUARD_PATTERN;
+ if (diff) {
+ cm_print_error(SOURCE_LOCATION_FORMAT
+ ": error: Guard block of %p size=%lu is corrupt\n"
+ SOURCE_LOCATION_FORMAT ": note: allocated here at %p\n",
+ file, line,
+ ptr, (unsigned long)block_info->size,
+ block_info->location.file, block_info->location.line,
+ (void *)&guard[j]);
+ _fail(file, line);
+ }
+ }
+ }
+ }
+ list_remove(&block_info->node, NULL, NULL);
+
+ block = discard_const_p(char, block_info->block);
+ memset(block, MALLOC_FREE_PATTERN, block_info->allocated_size);
+ free(block);
+}
+#define free test_free
+
+#undef realloc
+void *_test_realloc(void *ptr,
+ const size_t size,
+ const char *file,
+ const int line)
+{
+ MallocBlockInfo *block_info;
+ char *block = ptr;
+ size_t block_size = size;
+ void *new_block;
+
+ if (ptr == NULL) {
+ return _test_malloc(size, file, line);
+ }
+
+ if (size == 0) {
+ _test_free(ptr, file, line);
+ return NULL;
+ }
+
+ block_info = (MallocBlockInfo*)(block - (MALLOC_GUARD_SIZE +
+ sizeof(*block_info)));
+
+ new_block = _test_malloc(size, file, line);
+ if (new_block == NULL) {
+ return NULL;
+ }
+
+ if (block_info->size < size) {
+ block_size = block_info->size;
+ }
+
+ memcpy(new_block, ptr, block_size);
+
+ /* Free previous memory */
+ _test_free(ptr, file, line);
+
+ return new_block;
+}
+#define realloc test_realloc
+
+/* Crudely checkpoint the current heap state. */
+static const ListNode* check_point_allocated_blocks(void) {
+ return get_allocated_blocks_list()->prev;
+}
+
+
+/* Display the blocks allocated after the specified check point. This
+ * function returns the number of blocks displayed. */
+static int display_allocated_blocks(const ListNode * const check_point) {
+ const ListNode * const head = get_allocated_blocks_list();
+ const ListNode *node;
+ int allocated_blocks = 0;
+ assert_non_null(check_point);
+ assert_non_null(check_point->next);
+
+ for (node = check_point->next; node != head; node = node->next) {
+ const MallocBlockInfo * const block_info =
+ (const MallocBlockInfo*)node->value;
+ assert_non_null(block_info);
+
+ if (!allocated_blocks) {
+ cm_print_error("Blocks allocated...\n");
+ }
+ cm_print_error(SOURCE_LOCATION_FORMAT ": note: block %p allocated here\n",
+ block_info->location.file,
+ block_info->location.line,
+ block_info->block);
+ allocated_blocks ++;
+ }
+ return allocated_blocks;
+}
+
+
+/* Free all blocks allocated after the specified check point. */
+static void free_allocated_blocks(const ListNode * const check_point) {
+ const ListNode * const head = get_allocated_blocks_list();
+ const ListNode *node;
+ assert_non_null(check_point);
+
+ node = check_point->next;
+ assert_non_null(node);
+
+ while (node != head) {
+ MallocBlockInfo * const block_info = (MallocBlockInfo*)node->value;
+ node = node->next;
+ free(discard_const_p(char, block_info) + sizeof(*block_info) + MALLOC_GUARD_SIZE);
+ }
+}
+
+
+/* Fail if any any blocks are allocated after the specified check point. */
+static void fail_if_blocks_allocated(const ListNode * const check_point,
+ const char * const test_name) {
+ const int allocated_blocks = display_allocated_blocks(check_point);
+ if (allocated_blocks) {
+ free_allocated_blocks(check_point);
+ cm_print_error("ERROR: %s leaked %d block(s)\n", test_name,
+ allocated_blocks);
+ exit_test(1);
+ }
+}
+
+
+void _fail(const char * const file, const int line) {
+ enum cm_message_output output = cm_get_output();
+
+ switch(output) {
+ case CM_OUTPUT_STDOUT:
+ cm_print_error("[ LINE ] --- " SOURCE_LOCATION_FORMAT ": error: Failure!", file, line);
+ break;
+ default:
+ cm_print_error(SOURCE_LOCATION_FORMAT ": error: Failure!", file, line);
+ break;
+ }
+ exit_test(1);
+}
+
+
+#ifndef _WIN32
+static void exception_handler(int sig) {
+ const char *sig_strerror = "";
+
+#ifdef HAVE_STRSIGNAL
+ sig_strerror = strsignal(sig);
+#endif
+
+ cm_print_error("Test failed with exception: %s(%d)",
+ sig_strerror, sig);
+ exit_test(1);
+}
+
+#else /* _WIN32 */
+
+static LONG WINAPI exception_filter(EXCEPTION_POINTERS *exception_pointers) {
+ EXCEPTION_RECORD * const exception_record =
+ exception_pointers->ExceptionRecord;
+ const DWORD code = exception_record->ExceptionCode;
+ unsigned int i;
+ for (i = 0; i < ARRAY_SIZE(exception_codes); i++) {
+ const ExceptionCodeInfo * const code_info = &exception_codes[i];
+ if (code == code_info->code) {
+ static int shown_debug_message = 0;
+ fflush(stdout);
+ cm_print_error("%s occurred at %p.\n", code_info->description,
+ exception_record->ExceptionAddress);
+ if (!shown_debug_message) {
+ cm_print_error(
+ "\n"
+ "To debug in Visual Studio...\n"
+ "1. Select menu item File->Open Project\n"
+ "2. Change 'Files of type' to 'Executable Files'\n"
+ "3. Open this executable.\n"
+ "4. Select menu item Debug->Start\n"
+ "\n"
+ "Alternatively, set the environment variable \n"
+ "UNIT_TESTING_DEBUG to 1 and rebuild this executable, \n"
+ "then click 'Debug' in the popup dialog box.\n"
+ "\n");
+ shown_debug_message = 1;
+ }
+ exit_test(0);
+ return EXCEPTION_EXECUTE_HANDLER;
+ }
+ }
+ return EXCEPTION_CONTINUE_SEARCH;
+}
+#endif /* !_WIN32 */
+
+void cm_print_error(const char * const format, ...)
+{
+ va_list args;
+ va_start(args, format);
+ if (cm_error_message_enabled) {
+ vcm_print_error(format, args);
+ } else {
+ vprint_error(format, args);
+ }
+ va_end(args);
+}
+
+/* Standard output and error print methods. */
+void vprint_message(const char* const format, va_list args) {
+ char buffer[1024];
+ vsnprintf(buffer, sizeof(buffer), format, args);
+ printf("%s", buffer);
+ fflush(stdout);
+#ifdef _WIN32
+ OutputDebugString(buffer);
+#endif /* _WIN32 */
+}
+
+
+void vprint_error(const char* const format, va_list args) {
+ char buffer[1024];
+ vsnprintf(buffer, sizeof(buffer), format, args);
+ fprintf(stderr, "%s", buffer);
+ fflush(stderr);
+#ifdef _WIN32
+ OutputDebugString(buffer);
+#endif /* _WIN32 */
+}
+
+
+void print_message(const char* const format, ...) {
+ va_list args;
+ va_start(args, format);
+ vprint_message(format, args);
+ va_end(args);
+}
+
+
+void print_error(const char* const format, ...) {
+ va_list args;
+ va_start(args, format);
+ vprint_error(format, args);
+ va_end(args);
+}
+
+/* New formatter */
+static enum cm_message_output cm_get_output(void)
+{
+ enum cm_message_output output = global_msg_output;
+ char *env;
+
+ env = getenv("CMOCKA_MESSAGE_OUTPUT");
+ if (env != NULL) {
+ if (strcasecmp(env, "STDOUT") == 0) {
+ output = CM_OUTPUT_STDOUT;
+ } else if (strcasecmp(env, "SUBUNIT") == 0) {
+ output = CM_OUTPUT_SUBUNIT;
+ } else if (strcasecmp(env, "TAP") == 0) {
+ output = CM_OUTPUT_TAP;
+ } else if (strcasecmp(env, "XML") == 0) {
+ output = CM_OUTPUT_XML;
+ }
+ }
+
+ return output;
+}
+
+enum cm_printf_type {
+ PRINTF_TEST_START,
+ PRINTF_TEST_SUCCESS,
+ PRINTF_TEST_FAILURE,
+ PRINTF_TEST_ERROR,
+ PRINTF_TEST_SKIPPED,
+};
+
+static int xml_printed;
+static int file_append;
+
+static void cmprintf_group_finish_xml(const char *group_name,
+ size_t total_executed,
+ size_t total_failed,
+ size_t total_errors,
+ size_t total_skipped,
+ double total_runtime,
+ struct CMUnitTestState *cm_tests)
+{
+ FILE *fp = stdout;
+ int file_opened = 0;
+ int multiple_files = 0;
+ char *env;
+ size_t i;
+
+ env = getenv("CMOCKA_XML_FILE");
+ if (env != NULL) {
+ char buf[1024];
+ int rc;
+
+ snprintf(buf, sizeof(buf), "%s", env);
+
+ rc = c_strreplace(buf, sizeof(buf), "%g", group_name, &multiple_files);
+ if (rc < 0) {
+ snprintf(buf, sizeof(buf), "%s", env);
+ }
+
+ fp = fopen(buf, "r");
+ if (fp == NULL) {
+ fp = fopen(buf, "w");
+ if (fp != NULL) {
+ file_append = 1;
+ file_opened = 1;
+ } else {
+ fp = stderr;
+ }
+ } else {
+ fclose(fp);
+ if (file_append) {
+ fp = fopen(buf, "a");
+ if (fp != NULL) {
+ file_opened = 1;
+ xml_printed = 1;
+ } else {
+ fp = stderr;
+ }
+ } else {
+ fp = stderr;
+ }
+ }
+ }
+
+ if (!xml_printed || (file_opened && !file_append)) {
+ fprintf(fp, "\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 size_t num_tests)
+{
+ print_message("[==========] Running %u test(s).\n",
+ (unsigned)num_tests);
+}
+
+static void cmprintf_group_finish_standard(size_t total_executed,
+ size_t total_passed,
+ size_t total_failed,
+ size_t total_errors,
+ size_t total_skipped,
+ struct CMUnitTestState *cm_tests)
+{
+ size_t i;
+
+ print_message("[==========] %u test(s) run.\n", (unsigned)total_executed);
+ print_error("[ PASSED ] %u test(s).\n",
+ (unsigned)(total_passed));
+
+ if (total_skipped) {
+ print_error("[ SKIPPED ] %"PRIdS " test(s), listed below:\n", total_skipped);
+ for (i = 0; i < total_executed; i++) {
+ struct CMUnitTestState *cmtest = &cm_tests[i];
+
+ if (cmtest->status == CM_TEST_SKIPPED) {
+ print_error("[ SKIPPED ] %s\n", cmtest->test->name);
+ }
+ }
+ print_error("\n %u SKIPPED TEST(S)\n", (unsigned)(total_skipped));
+ }
+
+ if (total_failed) {
+ print_error("[ FAILED ] %"PRIdS " test(s), listed below:\n", total_failed);
+ for (i = 0; i < total_executed; i++) {
+ struct CMUnitTestState *cmtest = &cm_tests[i];
+
+ if (cmtest->status == CM_TEST_FAILED) {
+ print_error("[ FAILED ] %s\n", cmtest->test->name);
+ }
+ }
+ print_error("\n %u FAILED TEST(S)\n",
+ (unsigned)(total_failed + total_errors));
+ }
+}
+
+static void cmprintf_standard(enum cm_printf_type type,
+ const char *test_name,
+ const char *error_message)
+{
+ switch (type) {
+ case PRINTF_TEST_START:
+ print_message("[ RUN ] %s\n", test_name);
+ break;
+ case PRINTF_TEST_SUCCESS:
+ print_message("[ OK ] %s\n", test_name);
+ break;
+ case PRINTF_TEST_FAILURE:
+ if (error_message != NULL) {
+ print_error("[ ERROR ] --- %s\n", error_message);
+ }
+ print_message("[ FAILED ] %s\n", test_name);
+ break;
+ case PRINTF_TEST_SKIPPED:
+ print_message("[ SKIPPED ] %s\n", test_name);
+ break;
+ case PRINTF_TEST_ERROR:
+ if (error_message != NULL) {
+ print_error("%s\n", error_message);
+ }
+ print_error("[ ERROR ] %s\n", test_name);
+ break;
+ }
+}
+
+static void cmprintf_group_start_tap(const size_t num_tests)
+{
+ print_message("1..%u\n", (unsigned)num_tests);
+}
+
+static void cmprintf_group_finish_tap(const char *group_name,
+ size_t total_executed,
+ size_t total_passed,
+ size_t total_skipped)
+{
+ const char *status = "not ok";
+ if (total_passed + total_skipped == total_executed) {
+ status = "ok";
+ }
+ print_message("# %s - %s\n", status, group_name);
+}
+
+static void cmprintf_tap(enum cm_printf_type type,
+ uint32_t test_number,
+ const char *test_name,
+ const char *error_message)
+{
+ switch (type) {
+ case PRINTF_TEST_START:
+ break;
+ case PRINTF_TEST_SUCCESS:
+ print_message("ok %u - %s\n", (unsigned)test_number, test_name);
+ break;
+ case PRINTF_TEST_FAILURE:
+ print_message("not ok %u - %s\n", (unsigned)test_number, test_name);
+ if (error_message != NULL) {
+ char *msg;
+ char *p;
+
+ msg = strdup(error_message);
+ if (msg == NULL) {
+ return;
+ }
+ p = msg;
+
+ while (p[0] != '\0') {
+ char *q = p;
+
+ p = strchr(q, '\n');
+ if (p != NULL) {
+ p[0] = '\0';
+ }
+
+ print_message("# %s\n", q);
+
+ if (p == NULL) {
+ break;
+ }
+ p++;
+ }
+ libc_free(msg);
+ }
+ break;
+ case PRINTF_TEST_SKIPPED:
+ print_message("not ok %u # SKIP %s\n", (unsigned)test_number, test_name);
+ break;
+ case PRINTF_TEST_ERROR:
+ print_message("not ok %u - %s %s\n",
+ (unsigned)test_number, test_name, error_message);
+ break;
+ }
+}
+
+static void cmprintf_subunit(enum cm_printf_type type,
+ const char *test_name,
+ const char *error_message)
+{
+ switch (type) {
+ case PRINTF_TEST_START:
+ print_message("test: %s\n", test_name);
+ break;
+ case PRINTF_TEST_SUCCESS:
+ print_message("success: %s\n", test_name);
+ break;
+ case PRINTF_TEST_FAILURE:
+ print_message("failure: %s", test_name);
+ if (error_message != NULL) {
+ print_message(" [\n%s]\n", error_message);
+ }
+ break;
+ case PRINTF_TEST_SKIPPED:
+ print_message("skip: %s\n", test_name);
+ break;
+ case PRINTF_TEST_ERROR:
+ print_message("error: %s [ %s ]\n", test_name, error_message);
+ break;
+ }
+}
+
+static void cmprintf_group_start(const size_t num_tests)
+{
+ enum cm_message_output output;
+
+ output = cm_get_output();
+
+ switch (output) {
+ case CM_OUTPUT_STDOUT:
+ cmprintf_group_start_standard(num_tests);
+ break;
+ case CM_OUTPUT_SUBUNIT:
+ break;
+ case CM_OUTPUT_TAP:
+ cmprintf_group_start_tap(num_tests);
+ break;
+ case CM_OUTPUT_XML:
+ break;
+ }
+}
+
+static void cmprintf_group_finish(const char *group_name,
+ size_t total_executed,
+ size_t total_passed,
+ size_t total_failed,
+ size_t total_errors,
+ size_t total_skipped,
+ double total_runtime,
+ struct CMUnitTestState *cm_tests)
+{
+ enum cm_message_output output;
+
+ output = cm_get_output();
+
+ switch (output) {
+ case CM_OUTPUT_STDOUT:
+ cmprintf_group_finish_standard(total_executed,
+ total_passed,
+ total_failed,
+ total_errors,
+ total_skipped,
+ cm_tests);
+ break;
+ case CM_OUTPUT_SUBUNIT:
+ break;
+ case CM_OUTPUT_TAP:
+ cmprintf_group_finish_tap(group_name, total_executed, total_passed, total_skipped);
+ break;
+ case CM_OUTPUT_XML:
+ cmprintf_group_finish_xml(group_name,
+ total_executed,
+ total_failed,
+ total_errors,
+ total_skipped,
+ total_runtime,
+ cm_tests);
+ break;
+ }
+}
+
+static void cmprintf(enum cm_printf_type type,
+ size_t test_number,
+ const char *test_name,
+ const char *error_message)
+{
+ enum cm_message_output output;
+
+ output = cm_get_output();
+
+ switch (output) {
+ case CM_OUTPUT_STDOUT:
+ cmprintf_standard(type, test_name, error_message);
+ break;
+ case CM_OUTPUT_SUBUNIT:
+ cmprintf_subunit(type, test_name, error_message);
+ break;
+ case CM_OUTPUT_TAP:
+ cmprintf_tap(type, test_number, test_name, error_message);
+ break;
+ case CM_OUTPUT_XML:
+ break;
+ }
+}
+
+void cmocka_set_message_output(enum cm_message_output output)
+{
+ global_msg_output = output;
+}
+
+/****************************************************************************
+ * TIME CALCULATIONS
+ ****************************************************************************/
+
+#ifdef HAVE_STRUCT_TIMESPEC
+static struct timespec cm_tspecdiff(struct timespec time1,
+ struct timespec time0)
+{
+ struct timespec ret;
+ int xsec = 0;
+ int sign = 1;
+
+ if (time0.tv_nsec > time1.tv_nsec) {
+ xsec = (int) ((time0.tv_nsec - time1.tv_nsec) / (1E9 + 1));
+ time0.tv_nsec -= (long int) (1E9 * xsec);
+ time0.tv_sec += xsec;
+ }
+
+ if ((time1.tv_nsec - time0.tv_nsec) > 1E9) {
+ xsec = (int) ((time1.tv_nsec - time0.tv_nsec) / 1E9);
+ time0.tv_nsec += (long int) (1E9 * xsec);
+ time0.tv_sec -= xsec;
+ }
+
+ ret.tv_sec = time1.tv_sec - time0.tv_sec;
+ ret.tv_nsec = time1.tv_nsec - time0.tv_nsec;
+
+ if (time1.tv_sec < time0.tv_sec) {
+ sign = -1;
+ }
+
+ ret.tv_sec = ret.tv_sec * sign;
+
+ return ret;
+}
+
+static double cm_secdiff(struct timespec clock1, struct timespec clock0)
+{
+ double ret;
+ struct timespec diff;
+
+ diff = cm_tspecdiff(clock1, clock0);
+
+ ret = diff.tv_sec;
+ ret += (double) diff.tv_nsec / (double) 1E9;
+
+ return ret;
+}
+#endif /* HAVE_STRUCT_TIMESPEC */
+
+/****************************************************************************
+ * CMOCKA TEST RUNNER
+ ****************************************************************************/
+static int cmocka_run_one_test_or_fixture(const char *function_name,
+ CMUnitTestFunction test_func,
+ CMFixtureFunction setup_func,
+ CMFixtureFunction teardown_func,
+ void ** const volatile state,
+ const void *const heap_check_point)
+{
+ const ListNode * const volatile check_point = (const ListNode*)
+ (heap_check_point != NULL ?
+ heap_check_point : check_point_allocated_blocks());
+ int handle_exceptions = 1;
+ void *current_state = NULL;
+ int rc = 0;
+
+ /* FIXME check only one test or fixture is set */
+
+ /* Detect if we should handle exceptions */
+#ifdef _WIN32
+ handle_exceptions = !IsDebuggerPresent();
+#endif /* _WIN32 */
+#ifdef UNIT_TESTING_DEBUG
+ handle_exceptions = 0;
+#endif /* UNIT_TESTING_DEBUG */
+
+#ifdef HAVE_SIGNAL_H
+ 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 */
+ }
+#endif
+ /* 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);
+
+#ifdef HAVE_SIGNAL_H
+ 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 */
+ }
+#endif
+
+ return rc;
+}
+
+static int cmocka_run_group_fixture(const char *function_name,
+ CMFixtureFunction setup_func,
+ CMFixtureFunction teardown_func,
+ void **state,
+ const void *const heap_check_point)
+{
+ int rc;
+
+ if (setup_func != NULL) {
+ rc = cmocka_run_one_test_or_fixture(function_name,
+ NULL,
+ setup_func,
+ NULL,
+ state,
+ heap_check_point);
+ } else {
+ rc = cmocka_run_one_test_or_fixture(function_name,
+ NULL,
+ NULL,
+ teardown_func,
+ state,
+ heap_check_point);
+ }
+
+ return rc;
+}
+
+static int cmocka_run_one_tests(struct CMUnitTestState *test_state)
+{
+#ifdef HAVE_STRUCT_TIMESPEC
+ struct timespec start = {
+ .tv_sec = 0,
+ .tv_nsec = 0,
+ };
+ struct timespec finish = {
+ .tv_sec = 0,
+ .tv_nsec = 0,
+ };
+#endif
+ int rc = 0;
+
+ /* Run setup */
+ if (test_state->test->setup_func != NULL) {
+ /* Setup the memory check point, it will be evaluated on teardown */
+ test_state->check_point = check_point_allocated_blocks();
+
+ rc = cmocka_run_one_test_or_fixture(test_state->test->name,
+ NULL,
+ test_state->test->setup_func,
+ NULL,
+ &test_state->state,
+ test_state->check_point);
+ if (rc != 0) {
+ test_state->status = CM_TEST_ERROR;
+ cm_print_error("Test setup failed");
+ }
+ }
+
+ /* Run test */
+#ifdef HAVE_STRUCT_TIMESPEC
+ CMOCKA_CLOCK_GETTIME(CLOCK_REALTIME, &start);
+#endif
+
+ if (rc == 0) {
+ rc = cmocka_run_one_test_or_fixture(test_state->test->name,
+ test_state->test->test_func,
+ NULL,
+ NULL,
+ &test_state->state,
+ NULL);
+ if (rc == 0) {
+ test_state->status = CM_TEST_PASSED;
+ } else {
+ if (global_skip_test) {
+ test_state->status = CM_TEST_SKIPPED;
+ global_skip_test = 0; /* Do not skip the next test */
+ } else {
+ test_state->status = CM_TEST_FAILED;
+ }
+ }
+ rc = 0;
+ }
+
+ test_state->runtime = 0.0;
+
+#ifdef HAVE_STRUCT_TIMESPEC
+ CMOCKA_CLOCK_GETTIME(CLOCK_REALTIME, &finish);
+ test_state->runtime = cm_secdiff(finish, start);
+#endif
+
+ /* Run teardown */
+ if (rc == 0 && test_state->test->teardown_func != NULL) {
+ rc = cmocka_run_one_test_or_fixture(test_state->test->name,
+ NULL,
+ NULL,
+ test_state->test->teardown_func,
+ &test_state->state,
+ test_state->check_point);
+ if (rc != 0) {
+ test_state->status = CM_TEST_ERROR;
+ cm_print_error("Test teardown failed");
+ }
+ }
+
+ test_state->error_message = cm_error_message;
+ cm_error_message = NULL;
+
+ return rc;
+}
+
+int _cmocka_run_group_tests(const char *group_name,
+ const struct CMUnitTest * const tests,
+ const size_t num_tests,
+ CMFixtureFunction group_setup,
+ CMFixtureFunction group_teardown)
+{
+ struct CMUnitTestState *cm_tests;
+ const ListNode *group_check_point = check_point_allocated_blocks();
+ void *group_state = NULL;
+ size_t total_tests = 0;
+ size_t total_failed = 0;
+ size_t total_passed = 0;
+ size_t total_executed = 0;
+ size_t total_errors = 0;
+ size_t total_skipped = 0;
+ double total_runtime = 0;
+ size_t i;
+ int rc;
+
+ /* Make sure LargestIntegralType is at least the size of a pointer. */
+ assert_true(sizeof(LargestIntegralType) >= sizeof(void*));
+
+ cm_tests = (struct CMUnitTestState *)libc_malloc(sizeof(struct CMUnitTestState) * num_tests);
+ if (cm_tests == NULL) {
+ return -1;
+ }
+
+ /* Setup cmocka test array */
+ for (i = 0; i < num_tests; i++) {
+ if (tests[i].name != NULL &&
+ (tests[i].test_func != NULL
+ || tests[i].setup_func != NULL
+ || tests[i].teardown_func != NULL)) {
+ cm_tests[i] = (struct CMUnitTestState) {
+ .test = &tests[i],
+ .status = CM_TEST_NOT_STARTED,
+ .state = NULL,
+ };
+ total_tests++;
+ }
+ }
+
+ cmprintf_group_start(total_tests);
+
+ rc = 0;
+
+ /* Run group setup */
+ if (group_setup != NULL) {
+ rc = cmocka_run_group_fixture("cmocka_group_setup",
+ group_setup,
+ NULL,
+ &group_state,
+ group_check_point);
+ }
+
+ if (rc == 0) {
+ /* Execute tests */
+ for (i = 0; i < total_tests; i++) {
+ struct CMUnitTestState *cmtest = &cm_tests[i];
+ size_t test_number = i + 1;
+
+ cmprintf(PRINTF_TEST_START, test_number, cmtest->test->name, NULL);
+
+ if (group_state != NULL) {
+ cmtest->state = group_state;
+ } else if (cmtest->test->initial_state != NULL) {
+ cmtest->state = cmtest->test->initial_state;
+ }
+
+ rc = cmocka_run_one_tests(cmtest);
+ total_executed++;
+ total_runtime += cmtest->runtime;
+ if (rc == 0) {
+ switch (cmtest->status) {
+ case CM_TEST_PASSED:
+ cmprintf(PRINTF_TEST_SUCCESS,
+ test_number,
+ cmtest->test->name,
+ cmtest->error_message);
+ total_passed++;
+ break;
+ case CM_TEST_SKIPPED:
+ cmprintf(PRINTF_TEST_SKIPPED,
+ test_number,
+ cmtest->test->name,
+ cmtest->error_message);
+ total_skipped++;
+ break;
+ case CM_TEST_FAILED:
+ cmprintf(PRINTF_TEST_FAILURE,
+ test_number,
+ cmtest->test->name,
+ cmtest->error_message);
+ total_failed++;
+ break;
+ default:
+ cmprintf(PRINTF_TEST_ERROR,
+ test_number,
+ cmtest->test->name,
+ "Internal cmocka error");
+ total_errors++;
+ break;
+ }
+ } else {
+ 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 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;
+
+#ifdef HAVE_SIGNAL_H
+ 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 */
+ }
+#endif
+
+ 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);
+
+#ifdef HAVE_SIGNAL_H
+ 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 */
+ }
+#endif
+
+ 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;
+ 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 = (const char**)malloc(number_of_tests *
+ sizeof(*failed_names));
+ void **current_state = NULL;
+ TestState group_state;
+
+ /* Find setup and teardown function */
+ for (i = 0; i < number_of_tests; i++) {
+ const UnitTest * const test = &tests[i];
+
+ if (test->function_type == UNIT_TEST_FUNCTION_TYPE_GROUP_SETUP) {
+ if (setup == NULL) {
+ setup = test->function;
+ setup_name = test->name;
+ num_setups = 1;
+ } else {
+ print_error("[ ERROR ] More than one group setup function detected\n");
+ exit_test(1);
+ }
+ }
+
+ if (test->function_type == UNIT_TEST_FUNCTION_TYPE_GROUP_TEARDOWN) {
+ if (teardown == NULL) {
+ teardown = test->function;
+ teardown_name = test->name;
+ num_teardowns = 1;
+ } else {
+ print_error("[ ERROR ] More than one group teardown function detected\n");
+ exit_test(1);
+ }
+ }
+ }
+
+ print_message("[==========] Running %"PRIdS " test(s).\n",
+ number_of_tests - num_setups - num_teardowns);
+
+ if (setup != NULL) {
+ int failed;
+
+ group_state.check_point = check_point_allocated_blocks();
+ current_state = &group_state.state;
+ *current_state = NULL;
+ failed = _run_test(setup_name,
+ setup,
+ current_state,
+ UNIT_TEST_FUNCTION_TYPE_SETUP,
+ group_state.check_point);
+ if (failed) {
+ failed_names[total_failed] = setup_name;
+ }
+
+ total_failed += failed;
+ tests_executed++;
+ }
+
+ while (current_test < number_of_tests) {
+ int run_test = 0;
+ const UnitTest * const test = &tests[current_test++];
+ if (test->function == NULL) {
+ continue;
+ }
+
+ switch (test->function_type) {
+ case UNIT_TEST_FUNCTION_TYPE_TEST:
+ run_test = 1;
+ break;
+ case UNIT_TEST_FUNCTION_TYPE_SETUP:
+ case UNIT_TEST_FUNCTION_TYPE_TEARDOWN:
+ case UNIT_TEST_FUNCTION_TYPE_GROUP_SETUP:
+ case UNIT_TEST_FUNCTION_TYPE_GROUP_TEARDOWN:
+ break;
+ default:
+ print_error("Invalid unit test function type %d\n",
+ test->function_type);
+ break;
+ }
+
+ if (run_test) {
+ int failed;
+
+ failed = _run_test(test->name,
+ test->function,
+ current_state,
+ test->function_type,
+ NULL);
+ if (failed) {
+ failed_names[total_failed] = test->name;
+ }
+
+ total_failed += failed;
+ tests_executed++;
+ }
+ }
+
+ if (teardown != NULL) {
+ int failed;
+
+ failed = _run_test(teardown_name,
+ teardown,
+ current_state,
+ UNIT_TEST_FUNCTION_TYPE_GROUP_TEARDOWN,
+ group_state.check_point);
+ if (failed) {
+ failed_names[total_failed] = teardown_name;
+ }
+
+ total_failed += failed;
+ tests_executed++;
+ }
+
+ print_message("[==========] %"PRIdS " test(s) run.\n", tests_executed);
+ print_error("[ PASSED ] %"PRIdS " test(s).\n", tests_executed - total_failed);
+
+ if (total_failed) {
+ print_error("[ FAILED ] %"PRIdS " test(s), listed below:\n", total_failed);
+ for (i = 0; i < total_failed; i++) {
+ print_error("[ FAILED ] %s\n", failed_names[i]);
+ }
+ } else {
+ print_error("\n %"PRIdS " FAILED TEST(S)\n", total_failed);
+ }
+
+ free((void*)failed_names);
+ fail_if_blocks_allocated(check_point, "run_group_tests");
+
+ return (int)total_failed;
+}
diff --git a/emCmocka/src/cmocka.def b/emCmocka/src/cmocka.def
new file mode 100644
index 0000000..43228c4
--- /dev/null
+++ b/emCmocka/src/cmocka.def
@@ -0,0 +1,49 @@
+LIBRARY cmocka
+EXPORTS
+ _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
+ cmocka_set_message_output
+ global_expect_assert_env
+ global_expecting_assert
+ global_last_failed_assert
+ mock_assert
+ print_error
+ print_message
+ vprint_error
+ vprint_message
diff --git a/emCmocka/tests/CMakeLists.txt b/emCmocka/tests/CMakeLists.txt
new file mode 100644
index 0000000..f17124a
--- /dev/null
+++ b/emCmocka/tests/CMakeLists.txt
@@ -0,0 +1,243 @@
+project(tests C)
+
+include_directories(
+ ${CMAKE_BINARY_DIR}
+ ${CMAKE_CURRENT_SOURCE_DIR}
+ ${CMAKE_SOURCE_DIR}/include
+)
+
+set(CMOCKA_TESTS
+ test_alloc
+ test_group_setup_assert
+ test_group_setup_fail
+ test_fixtures
+ test_group_fixtures
+ test_groups
+ test_assert_macros
+ test_assert_macros_fail
+ test_exception_handler
+ test_basics
+ test_skip
+ test_setup_fail
+ test_ordering
+ test_ordering_fail
+ test_returns
+ test_returns_fail)
+
+foreach(_CMOCKA_TEST ${CMOCKA_TESTS})
+ add_cmocka_test(${_CMOCKA_TEST} ${_CMOCKA_TEST}.c ${CMOCKA_STATIC_LIBRARY})
+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()
+add_cmocka_test(test_cmockery test_cmockery.c ${CMOCKA_STATIC_LIBRARY})
+
+### 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 \\] 1 test"
+)
+
+# test_ordering ensure proper failures
+set_tests_properties(
+ test_ordering_fail
+ PROPERTIES
+ PASS_REGULAR_EXPRESSION
+ "\\[ FAILED \\] 7 test"
+)
+
+# test_returns_fail ensure proper failures
+set_tests_properties(
+ test_returns_fail
+ PROPERTIES
+ PASS_REGULAR_EXPRESSION
+ "\\[ FAILED \\] 3 test"
+)
+
+# test_exception_handler
+if (WIN32)
+ set_tests_properties(
+ test_exception_handler
+ PROPERTIES
+ PASS_REGULAR_EXPRESSION
+ "EXCEPTION_ACCESS_VIOLATION occurred at")
+else()
+ set_tests_properties(
+ test_exception_handler
+ PROPERTIES
+ PASS_REGULAR_EXPRESSION
+ "Test failed with exception: (Segmentation fault|Segmentation Fault|11)"
+ )
+endif (WIN32)
+
+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 test_setup_fail)
+set_tests_properties(
+ test_setup_fail_1_failed
+ PROPERTIES
+ PASS_REGULAR_EXPRESSION
+ "\\[ ERROR \\] int_test_ignored"
+)
+
+add_test (test_setup_fail_1_passed test_setup_fail)
+set_tests_properties(
+ test_setup_fail_1_passed
+ PROPERTIES
+ PASS_REGULAR_EXPRESSION
+ "\\[ PASSED \\] 1 test\\(s\\)."
+)
+
+add_test (test_setup_fail_match_failed test_setup_fail)
+set_tests_properties(
+ test_setup_fail_match_failed
+ PROPERTIES
+ PASS_REGULAR_EXPRESSION
+ "\\[ ERROR \\] int_test_ignored"
+)
+
+add_test (test_setup_fail_match_passed test_setup_fail)
+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
+ "^1\\.\\.2"
+ "ok 1 - null_test_success"
+ "ok 2 - int_test_success"
+ "# ok - tests")
+set(test_assert_macros_fail_tap_out
+ "^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
+ "^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
+ "not 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} ${_OUTPUT_TEST})
+
+ set_property(
+ TEST
+ ${TEST_NAME}
+ 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/emCmocka/tests/ctest-default.cmake b/emCmocka/tests/ctest-default.cmake
new file mode 100644
index 0000000..e21e93c
--- /dev/null
+++ b/emCmocka/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/emCmocka/tests/simple_test/Makefile b/emCmocka/tests/simple_test/Makefile
new file mode 100644
index 0000000..c0ab632
--- /dev/null
+++ b/emCmocka/tests/simple_test/Makefile
@@ -0,0 +1,6 @@
+DEFS=-I../../include -DHAVE_STDIO_H -DHAVE_SETJMP_H
+
+all:
+ gcc $(DEFS) -o cmocka.o -c ../../src/cmocka.c
+ gcc $(DEFS) -o test_basics.o -c ../test_basics.c
+ gcc $(DEFS) -o a.out test_basics.o cmocka.o
diff --git a/emCmocka/tests/test_alloc.c b/emCmocka/tests/test_alloc.c
new file mode 100644
index 0000000..966814a
--- /dev/null
+++ b/emCmocka/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/emCmocka/tests/test_assert_macros.c b/emCmocka/tests/test_assert_macros.c
new file mode 100644
index 0000000..85b0a38
--- /dev/null
+++ b/emCmocka/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;
+ 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/emCmocka/tests/test_assert_macros_fail.c b/emCmocka/tests/test_assert_macros_fail.c
new file mode 100644
index 0000000..aea919a
--- /dev/null
+++ b/emCmocka/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/emCmocka/tests/test_basics.c b/emCmocka/tests/test_basics.c
new file mode 100644
index 0000000..1bb493f
--- /dev/null
+++ b/emCmocka/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/emCmocka/tests/test_cmockery.c b/emCmocka/tests/test_cmockery.c
new file mode 100644
index 0000000..83a7451
--- /dev/null
+++ b/emCmocka/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/emCmocka/tests/test_exception_handler.c b/emCmocka/tests/test_exception_handler.c
new file mode 100644
index 0000000..3f7c181
--- /dev/null
+++ b/emCmocka/tests/test_exception_handler.c
@@ -0,0 +1,30 @@
+#include
+#include
+#include
+#include
+
+#include
+
+struct test_segv {
+ int x;
+ int y;
+};
+
+static void test_segfault_recovery(void **state)
+{
+ struct test_segv *s = NULL;
+
+ (void) state; /* unused */
+
+ s->x = 1;
+}
+
+int main(void) {
+ const struct CMUnitTest tests[] = {
+ cmocka_unit_test(test_segfault_recovery),
+ cmocka_unit_test(test_segfault_recovery),
+ cmocka_unit_test(test_segfault_recovery),
+ };
+
+ return cmocka_run_group_tests(tests, NULL, NULL);
+}
diff --git a/emCmocka/tests/test_fixtures.c b/emCmocka/tests/test_fixtures.c
new file mode 100644
index 0000000..6d39487
--- /dev/null
+++ b/emCmocka/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/emCmocka/tests/test_group_fixtures.c b/emCmocka/tests/test_group_fixtures.c
new file mode 100644
index 0000000..64f0ab7
--- /dev/null
+++ b/emCmocka/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/emCmocka/tests/test_group_setup_assert.c b/emCmocka/tests/test_group_setup_assert.c
new file mode 100644
index 0000000..eef61f8
--- /dev/null
+++ b/emCmocka/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/emCmocka/tests/test_group_setup_fail.c b/emCmocka/tests/test_group_setup_fail.c
new file mode 100644
index 0000000..7815c03
--- /dev/null
+++ b/emCmocka/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/emCmocka/tests/test_groups.c b/emCmocka/tests/test_groups.c
new file mode 100644
index 0000000..af9e2b8
--- /dev/null
+++ b/emCmocka/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/emCmocka/tests/test_ordering.c b/emCmocka/tests/test_ordering.c
new file mode 100644
index 0000000..817c0ba
--- /dev/null
+++ b/emCmocka/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/emCmocka/tests/test_ordering_fail.c b/emCmocka/tests/test_ordering_fail.c
new file mode 100644
index 0000000..652f5ad
--- /dev/null
+++ b/emCmocka/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/emCmocka/tests/test_returns.c b/emCmocka/tests/test_returns.c
new file mode 100644
index 0000000..b9370c9
--- /dev/null
+++ b/emCmocka/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/emCmocka/tests/test_returns_fail.c b/emCmocka/tests/test_returns_fail.c
new file mode 100644
index 0000000..81197d3
--- /dev/null
+++ b/emCmocka/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/emCmocka/tests/test_setup_fail.c b/emCmocka/tests/test_setup_fail.c
new file mode 100644
index 0000000..e3f8df8
--- /dev/null
+++ b/emCmocka/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/emCmocka/tests/test_skip.c b/emCmocka/tests/test_skip.c
new file mode 100644
index 0000000..127161a
--- /dev/null
+++ b/emCmocka/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/mbedtls_vs_boringssl/.gitmodules b/mbedtls_vs_boringssl/.gitmodules
new file mode 100644
index 0000000..ec44b13
--- /dev/null
+++ b/mbedtls_vs_boringssl/.gitmodules
@@ -0,0 +1,6 @@
+[submodule "bssl/src"]
+ path = bssl/src
+ url = https://github.com/google/boringssl.git
+[submodule "mbedtls/src"]
+ path = mbedtls/src
+ url = https://github.com/ARMmbed/mbedtls.git
diff --git a/mbedtls_vs_boringssl/APPENDIX.md b/mbedtls_vs_boringssl/APPENDIX.md
new file mode 100644
index 0000000..70b2e7c
--- /dev/null
+++ b/mbedtls_vs_boringssl/APPENDIX.md
@@ -0,0 +1,278 @@
+# Additional information
+
+A lot of, mostly useless, details
+
+## Appendix A
+
+Default NDK flags
+
+* CC:
+```
+ --target=aarch64-none-linux-android
+ -DBORINGSSL_IMPLEMENTATION
+ -g
+ -DANDROID
+ -ffunction-sections
+ -funwind-tables
+ -fstack-protector-strong
+ -no-canonical-prefixes
+ -Wa,--noexecstack
+ -Wformat
+ -Werror=format-security
+ -Werror
+ -Wformat=2
+ -Wsign-compare
+ -Wmissing-field-initializers
+ -Wwrite-strings
+ -Wall
+ -ggdb
+ -fvisibility=hidden
+ -fno-common
+ -Wnewline-eof
+ -fcolor-diagnostics
+ -Wimplicit-fallthrough
+ -Wmissing-prototypes
+ -Wold-style-definition
+ -Wstrict-prototypes
+ -Wshadow
+ -D_XOPEN_SOURCE=700
+ -O2
+ -DNDEBUG
+ -fPIC
+```
+
+* CPP:
+```
+ -cc1
+ -triple aarch64-none-linux-android
+ -emit-obj
+ -mnoexecstack
+ -disable-free
+ -disable-llvm-verifier
+ -discard-value-names
+ -mrelocation-model pic
+ -pic-level 2
+ -pic-is-pie
+ -mthread-model posix
+ -mdisable-fp-elim
+ -fmath-errno
+ -masm-verbose
+ -mconstructor-aliases
+ -munwind-tables
+ -fuse-init-array
+ -target-cpu generic
+ -target-feature +neon
+ -target-abi aapcs
+ -dwarf-column-info
+ -debug-info-kind=limited
+ -dwarf-version=4
+ -debugger-tuning=gdb
+ -ffunction-sections
+ -D BORINGSSL_IMPLEMENTATION
+ -D ANDROID
+ -D NDEBUG
+ -O2
+ -Wformat
+ -Werror=format-security
+ -Werror
+ -Wformat=2
+ -Wsign-compare
+ -Wmissing-field-initializers
+ -Wwrite-strings
+ -Wall
+ -Wnewline-eof
+ -Wimplicit-fallthrough
+ -Wmissing-declarations
+ -Wmissing-prototypes
+ -Wshadow
+ -std=c++11
+ -fdeprecated-macro
+ -fdebug-compilation-dir /home/hdc/repos/mbedtls_vs_boringssl/bssl/src/build/crypto
+ -ferror-limit 19
+ -fmessage-length 238
+ -fvisibility hidden
+ -femulated-tls
+ -stack-protector 2
+ -fallow-half-arguments-and-returns
+ -fno-rtti
+ -fno-signed-char
+ -fobjc-runtime=gcc
+ -fno-common
+ -fdiagnostics-show-option
+ -fcolor-diagnostics
+ -vectorize-loops
+ -vectorize-slp
+```
+
+## Appendix B
+
+Test platform settings
+
+```
+[ro.build.id]: [OPR6.170623.013]
+[ro.bootimage.build.date]: [Wed Oct 11 15:46:15 BST 2017]
+[ro.bootimage.build.fingerprint]: [Android/hikey/hikey:8.0.0/OPR6.170623.013/110:userdebug/test-keys]
+[ro.product.cpu.abi]: [arm64-v8a]
+[ro.product.cpu.abilist]: [arm64-v8a,armeabi-v7a,armeabi]
+[ro.product.cpu.abilist32]: [armeabi-v7a,armeabi]
+[ro.product.cpu.abilist64]: [arm64-v8a]
+[ro.build.version.sdk]: [26]
+[ro.build.version.security_patch]: [2017-08-05]
+```
+
+## Appendix C
+
+Performance measures provied by ``bssl speed``:
+
+| Operation | Small | Default |
+|-----------|------|---------|
+|RSA 2048 signing | (59.5 ops/sec) | (108.1 ops/sec) |
+|RSA 2048 verify | (2377.5 ops/sec) | (4078.3 ops/sec) |
+|RSA 4096 signing | (8.3 ops/sec) | (14.9 ops/sec) |
+|RSA 4096 verify | (668.0 ops/sec) | (1088.4 ops/sec) |
+|AES-128-GCM (16 bytes) | (497832.2 ops/sec): 8.0 MB/s | (1690241.1 ops/sec): 27.0 MB/s |
+|AES-128-GCM (1350 bytes) | (17675.4 ops/sec): 23.9 MB/s | (291430.3 ops/sec): 393.4 MB/s |
+|AES-128-GCM (8192 bytes) | (2991.6 ops/sec): 24.5 MB/s | (57088.8 ops/sec): 467.7 MB/s |
+|AES-256-GCM (16 bytes) | (444847.4 ops/sec): 7.1 MB/s | (1615148.8 ops/sec): 25.8 MB/s |
+|AES-256-GCM (1350 bytes) | (14792.6 ops/sec): 20.0 MB/s | (254718.5 ops/sec): 343.9 MB/s |
+|AES-256-GCM (8192 bytes) | (2525.7 ops/sec): 20.7 MB/s | (49056.6 ops/sec): 401.9 MB/s |
+|ChaCha20-Poly1305 (16 bytes) | (385043.6 ops/sec): 6.2 MB/s | (460788.5 ops/sec): 7.4 MB/s |
+|ChaCha20-Poly1305 (1350 bytes) | (33108.8 ops/sec): 44.7 MB/s | (67622.8 ops/sec): 91.3 MB/s |
+|ChaCha20-Poly1305 (8192 bytes) | (5905.1 ops/sec): 48.4 MB/s | (13219.5 ops/sec): 108.3 MB/s |
+|DES-EDE3-CBC-SHA1 (16 bytes) | (100311.5 ops/sec): 1.6 MB/s | (110073.3 ops/sec): 1.8 MB/s |
+|DES-EDE3-CBC-SHA1 (1350 bytes) | (3787.2 ops/sec): 5.1 MB/s | (3926.7 ops/sec): 5.3 MB/s |
+|DES-EDE3-CBC-SHA1 (8192 bytes) | (638.4 ops/sec): 5.2 MB/s | (661.2 ops/sec): 5.4 MB/s |
+|AES-128-CBC-SHA1 (16 bytes) | (268159.9 ops/sec): 4.3 MB/s | (540844.8 ops/sec): 8.7 MB/s |
+|AES-128-CBC-SHA1 (1350 bytes) | (22535.6 ops/sec): 30.4 MB/s | (162597.6 ops/sec): 219.5 MB/s |
+|AES-128-CBC-SHA1 (8192 bytes) | (3959.9 ops/sec): 32.4 MB/s | (37787.3 ops/sec): 309.6 MB/s |
+|AES-256-CBC-SHA1 (16 bytes) | (244904.2 ops/sec): 3.9 MB/s | (524976.9 ops/sec): 8.4 MB/s |
+|AES-256-CBC-SHA1 (1350 bytes) | (18272.3 ops/sec): 24.7 MB/s | (141626.7 ops/sec): 191.2 MB/s |
+|AES-256-CBC-SHA1 (8192 bytes) | (3181.3 ops/sec): 26.1 MB/s | (31195.9 ops/sec): 255.6 MB/s |
+|AES-128-GCM-SIV (16 bytes) | (244929.5 ops/sec): 3.9 MB/s | (776750.7 ops/sec): 12.4 MB/s |
+|AES-128-GCM-SIV (1350 bytes) | (14640.5 ops/sec): 19.8 MB/s | (66627.7 ops/sec): 89.9 MB/s |
+|AES-128-GCM-SIV (8192 bytes) | (2531.6 ops/sec): 20.7 MB/s | (11850.0 ops/sec): 97.1 MB/s |
+|AES-256-GCM-SIV (16 bytes) | (171899.3 ops/sec): 2.8 MB/s | (660748.9 ops/sec): 10.6 MB/s |
+|AES-256-GCM-SIV (1350 bytes) | (12489.6 ops/sec): 16.9 MB/s | (61124.5 ops/sec): 82.5 MB/s |
+|AES-256-GCM-SIV (8192 bytes) | (2182.7 ops/sec): 17.9 MB/s | (10936.1 ops/sec): 89.6 MB/s |
+|AES-128-GCM-SIV (16 bytes) | (239698.0 ops/sec): 3.8 MB/s | (733661.0 ops/sec): 11.7 MB/s |
+|AES-128-GCM-SIV (1350 bytes) | (14616.0 ops/sec): 19.7 MB/s | (65984.0 ops/sec): 89.1 MB/s |
+|AES-128-GCM-SIV (8192 bytes) | (2529.8 ops/sec): 20.7 MB/s | (11745.7 ops/sec): 96.2 MB/s |
+|AES-256-GCM-SIV (16 bytes) | (170826.1 ops/sec): 2.7 MB/s | (626465.6 ops/sec): 10.0 MB/s |
+|AES-256-GCM-SIV (1350 bytes) | (12474.8 ops/sec): 16.8 MB/s | (60595.5 ops/sec): 81.8 MB/s |
+|AES-256-GCM-SIV (8192 bytes) | (2182.1 ops/sec): 17.9 MB/s | (10841.9 ops/sec): 88.8 MB/s |
+|AES-128-CCM-Bluetooth (16 bytes) | (438558.8 ops/sec): 7.0 MB/s | (1405567.1 ops/sec): 22.5 MB/s |
+|AES-128-CCM-Bluetooth (1350 bytes) | (14776.5 ops/sec): 19.9 MB/s | (140168.4 ops/sec): 189.2 MB/s |
+|AES-128-CCM-Bluetooth (8192 bytes) | (2498.7 ops/sec): 20.5 MB/s | (25890.2 ops/sec): 212.1 MB/s |
+|SHA-1 (16 bytes) | (1244563.2 ops/sec): 19.9 MB/s | (2567122.0 ops/sec): 41.1 MB/s |
+|SHA-1 (256 bytes) | (341934.0 ops/sec): 87.5 MB/s | (1162590.8 ops/sec): 297.6 MB/s |
+|SHA-1 (8192 bytes) | (14574.3 ops/sec): 119.4 MB/s | (66844.3 ops/sec): 547.6 MB/s |
+|SHA-256 (16 bytes) | (691326.6 ops/sec): 11.1 MB/s | (2431927.0 ops/sec): 38.9 MB/s |
+|SHA-256 (256 bytes) | (166138.9 ops/sec): 42.5 MB/s | (1120621.2 ops/sec): 286.9 MB/s |
+|SHA-256 (8192 bytes) | (6824.7 ops/sec): 55.9 MB/s | (63214.7 ops/sec): 517.9 MB/s |
+|SHA-512 (16 bytes) | (688007.9 ops/sec): 11.0 MB/s | (729988.3 ops/sec): 11.7 MB/s |
+|SHA-512 (256 bytes) | (272146.5 ops/sec): 69.7 MB/s | (289178.7 ops/sec): 74.0 MB/s |
+|SHA-512 (8192 bytes) | (14014.7 ops/sec): 114.8 MB/s | (14759.6 ops/sec): 120.9 MB/s |
+|RNG (16 bytes) | (137217.4 ops/sec): 2.2 MB/s | (249239.3 ops/sec): 4.0 MB/s |
+|RNG (256 bytes) | (69898.9 ops/sec): 17.9 MB/s | (224698.5 ops/sec): 57.5 MB/s |
+|RNG (8192 bytes) | (4058.7 ops/sec): 33.2 MB/s | (55705.4 ops/sec): 456.3 MB/s |
+|ECDH P-224 operations | (151.0 ops/sec) | (1602.4 ops/sec) |
+|ECDH P-256 operations | (594.7 ops/sec) | (642.8 ops/sec) |
+|ECDH P-384 operations | (59.0 ops/sec) | (97.4 ops/sec) |
+|ECDH P-521 operations | (27.1 ops/sec) | (43.4 ops/sec) |
+|ECDSA P-224 signing | (277.8 ops/sec) | (3312.7 ops/sec) |
+|ECDSA P-224 verify | (241.2 ops/sec) | (1451.7 ops/sec) |
+|ECDSA P-256 signing | (1396.6 ops/sec) | (1738.5 ops/sec) |
+|ECDSA P-256 verify | (672.1 ops/sec) | (704.2 ops/sec) |
+|ECDSA P-384 signing | (107.0 ops/sec) | (177.6 ops/sec) |
+|ECDSA P-384 verify | (94.4 ops/sec) | (156.9 ops/sec) |
+|ECDSA P-521 signing | (49.0 ops/sec) | (78.2 ops/sec) |
+|ECDSA P-521 verify | (43.8 ops/sec) | (70.8 ops/sec) |
+
+Performance measures provided by ``benchmark``:
+
+| Algo | Small | Normal |
+|-------------------------------|----------------------|----------------------|
+|MD5 | 131223 KiB/s | 131761 KiB/s |
+|RIPEMD160 | 81451 KiB/s | 89899 KiB/s |
+|SHA-1 | 104117 KiB/s | 104375 KiB/s |
+|SHA-256 | 46809 KiB/s | 52044 KiB/s |
+|SHA-512 | 56760 KiB/s | 57648 KiB/s |
+|ARC4 | 65014 KiB/s | 65023 KiB/s |
+|3DES | 7785 KiB/s | 7885 KiB/s |
+|DES | 19071 KiB/s | 19512 KiB/s |
+|AES-CBC-128 | 32460 KiB/s | 35995 KiB/s |
+|AES-CBC-192 | 28392 KiB/s | 31044 KiB/s |
+|AES-CBC-256 | 25213 KiB/s | 27296 KiB/s |
+|AES-GCM-128 | 16399 KiB/s | 16398 KiB/s |
+|AES-GCM-192 | 15272 KiB/s | 15271 KiB/s |
+|AES-GCM-256 | 14287 KiB/s | 14286 KiB/s |
+|AES-CCM-128 | 15824 KiB/s | 15887 KiB/s |
+|AES-CCM-192 | 13853 KiB/s | 13899 KiB/s |
+|AES-CCM-256 | 12315 KiB/s | 12356 KiB/s |
+|CAMELLIA-CBC-128 | 19735 KiB/s | 26762 KiB/s |
+|CAMELLIA-CBC-192 | 15458 KiB/s | 20839 KiB/s |
+|CAMELLIA-CBC-256 | 15459 KiB/s | 20839 KiB/s |
+|BLOWFISH-CBC-128 | 25188 KiB/s | 28955 KiB/s |
+|BLOWFISH-CBC-192 | 25189 KiB/s | 28954 KiB/s |
+|BLOWFISH-CBC-256 | 25183 KiB/s | 28955 KiB/s |
+|CTR_DRBG (NOPR) | 27122 KiB/s | 27050 KiB/s |
+|CTR_DRBG (PR) | 18397 KiB/s | 19111 KiB/s |
+|HMAC_DRBG SHA-1 (NOPR) | 6746 KiB/s | 6968 KiB/s |
+|HMAC_DRBG SHA-1 (PR) | 6208 KiB/s | 6426 KiB/s |
+|HMAC_DRBG SHA-256 (NOPR) | 5321 KiB/s | 5795 KiB/s |
+|HMAC_DRBG SHA-256 (PR) | 4657 KiB/s | 5083 KiB/s |
+|RSA-2048 | 652 public/s | 653 public/s |
+|RSA-2048 | 17 private/s | 17 private/s |
+|RSA-4096 | 168 public/s | 168 public/s |
+|RSA-4096 | 3 private/s | 3 private/s |
+|DHE-2048 | 3 handshake/s | 3 handshake/s |
+|DH-2048 | 5 handshake/s | 6 handshake/s |
+|DHE-3072 | 1 handshake/s | 1 handshake/s |
+|DH-3072 | 2 handshake/s | 2 handshake/s |
+|ECDSA-secp521r1 | 70 sign/s | 74 sign/s |
+|ECDSA-brainpoolP512r1 | 8 sign/s | 9 sign/s |
+|ECDSA-secp384r1 | 126 sign/s | 133 sign/s |
+|ECDSA-brainpoolP384r1 | 16 sign/s | 18 sign/s |
+|ECDSA-secp256r1 | 189 sign/s | 195 sign/s |
+|ECDSA-secp256k1 | 176 sign/s | 189 sign/s |
+|ECDSA-brainpoolP256r1 | 27 sign/s | 31 sign/s |
+|ECDSA-secp224r1 | 277 sign/s | 291 sign/s |
+|ECDSA-secp224k1 | 216 sign/s | 230 sign/s |
+|ECDSA-secp192r1 | 329 sign/s | 352 sign/s |
+|ECDSA-secp192k1 | 264 sign/s | 277 sign/s |
+|ECDSA-secp521r1 | 19 verify/s | 21 verify/s |
+|ECDSA-brainpoolP512r1 | 2 verify/s | 2 verify/s |
+|ECDSA-secp384r1 | 35 verify/s | 36 verify/s |
+|ECDSA-brainpoolP384r1 | 4 verify/s | 4 verify/s |
+|ECDSA-secp256r1 | 54 verify/s | 57 verify/s |
+|ECDSA-secp256k1 | 53 verify/s | 57 verify/s |
+|ECDSA-brainpoolP256r1 | 7 verify/s | 8 verify/s |
+|ECDSA-secp224r1 | 82 verify/s | 86 verify/s |
+|ECDSA-secp224k1 | 63 verify/s | 67 verify/s |
+|ECDSA-secp192r1 | 102 verify/s | 110 verify/s |
+|ECDSA-secp192k1 | 77 verify/s | 82 verify/s |
+|ECDHE-secp521r1 | 20 handshake/s | 21 handshake/s |
+|ECDHE-brainpoolP512r1 | 2 handshake/s | 2 handshake/s |
+|ECDHE-secp384r1 | 37 handshake/s | 39 handshake/s |
+|ECDHE-brainpoolP384r1 | 4 handshake/s | 4 handshake/s |
+|ECDHE-secp256r1 | 57 handshake/s | 60 handshake/s |
+|ECDHE-secp256k1 | 56 handshake/s | 60 handshake/s |
+|ECDHE-brainpoolP256r1 | 7 handshake/s | 8 handshake/s |
+|ECDHE-secp224r1 | 89 handshake/s | 92 handshake/s |
+|ECDHE-secp224k1 | 67 handshake/s | 71 handshake/s |
+|ECDHE-secp192r1 | 111 handshake/s | 118 handshake/s |
+|ECDHE-secp192k1 | 83 handshake/s | 87 handshake/s |
+|ECDHE-Curve25519 | 41 handshake/s | 41 handshake/s |
+|ECDH-secp521r1 | 27 handshake/s | 28 handshake/s |
+|ECDH-brainpoolP512r1 | 3 handshake/s | 3 handshake/s |
+|ECDH-secp384r1 | 49 handshake/s | 51 handshake/s |
+|ECDH-brainpoolP384r1 | 5 handshake/s | 5 handshake/s |
+|ECDH-secp256r1 | 77 handshake/s | 81 handshake/s |
+|ECDH-secp256k1 | 78 handshake/s | 82 handshake/s |
+|ECDH-brainpoolP256r1 | 9 handshake/s | 11 handshake/s |
+|ECDH-secp224r1 | 121 handshake/s | 126 handshake/s |
+|ECDH-secp224k1 | 91 handshake/s | 97 handshake/s |
+|ECDH-secp192r1 | 150 handshake/s | 159 handshake/s |
+|ECDH-secp192k1 | 113 handshake/s | 120 handshake/s |
+|ECDH-Curve25519 | 80 handshake/s | 82 handshake/s |
+
diff --git a/mbedtls_vs_boringssl/README.md b/mbedtls_vs_boringssl/README.md
new file mode 100644
index 0000000..dcf89fc
--- /dev/null
+++ b/mbedtls_vs_boringssl/README.md
@@ -0,0 +1,3 @@
+# BoringSSL and mbedTLS comparison
+
+See here: http://hdc.amongbytes.com/post/201804-comparing-mbedtls-to-boringssl/
diff --git a/mbedtls_vs_boringssl/bssl/Makefile.aarch64 b/mbedtls_vs_boringssl/bssl/Makefile.aarch64
new file mode 100644
index 0000000..e48c800
--- /dev/null
+++ b/mbedtls_vs_boringssl/bssl/Makefile.aarch64
@@ -0,0 +1,29 @@
+include ../common.mk
+
+BUILD_DIR = src/build
+MAKE = cmake --build .
+
+all: prepare build
+
+clean:
+ rm -rf $(BUILD_DIR)
+
+prepare: clean
+ rm -rf $(BUILD_DIR)
+ mkdir -p $(BUILD_DIR)
+ cd $(BUILD_DIR); \
+ cmake \
+ -DANDROID_TOOLCHAIN_NAME=aarch64-linux-android-clang5.0 \
+ -DCMAKE_TOOLCHAIN_FILE=${ANDROID_NDK}/build/cmake/android.toolchain.cmake \
+ -DANDROID_NATIVE_API_LEVEL=$(NDK_TARGETVER) \
+ -DCMAKE_BUILD_TYPE=Release \
+ -DANDROID_ABI=arm64-v8a \
+ -DOPENSSL_SMALL=1 \
+ -DCMAKE_C_FLAGS_RELEASE="-Os -fdata-sections -Wno-error=unused-command-line-argument" \
+ -DCMAKE_CXX_FLAGS_RELEASE="-Os -fdata-sections -Wno-error=unused-command-line-argument" \
+ -DCMAKE_EXE_LINKER_FLAGS="-Wl,--gc-sections -Wno-error=unused-command-line-argument" \
+ ..
+build:
+ cd $(BUILD_DIR); \
+ $(MAKE)
+ python ../print_bssl_size.py " -fdata-sections (+)"
diff --git a/mbedtls_vs_boringssl/bssl/Makefile.native b/mbedtls_vs_boringssl/bssl/Makefile.native
new file mode 100644
index 0000000..8598c52
--- /dev/null
+++ b/mbedtls_vs_boringssl/bssl/Makefile.native
@@ -0,0 +1,22 @@
+include ../common.mk
+
+BUILD_DIR = src/build
+MAKE = cmake --build .
+
+all: prepare build
+
+prepare:
+ rm -rf $(BUILD_DIR)
+ mkdir -p $(BUILD_DIR)
+ cd $(BUILD_DIR); \
+ cmake -DCMAKE_BUILD_TYPE=Release \
+ -DCMAKE_BUILD_TYPE=Release \
+ -DOPENSSL_SMALL=1 \
+ -DCMAKE_C_FLAGS_RELEASE="-Os -fdata-sections" \
+ -DCMAKE_CXX_FLAGS_RELEASE="-Os -fdata-sections" \
+ -DCMAKE_EXE_LINKER_FLAGS="-Wl,--gc-sections" \
+ ..
+
+build:
+ cd $(BUILD_DIR); \
+ $(MAKE)
diff --git a/mbedtls_vs_boringssl/common.mk b/mbedtls_vs_boringssl/common.mk
new file mode 100644
index 0000000..95412d5
--- /dev/null
+++ b/mbedtls_vs_boringssl/common.mk
@@ -0,0 +1,5 @@
+# Constants and makefile shit used in build
+mkfile_path = $(abspath $(lastword $(MAKEFILE_LIST)))
+current_dir = $(notdir $(patsubst %/,%,$(dir $(mkfile_path))))
+ANDROID_NDK = /opt/android-ndk
+NDK_TARGETVER = 27
diff --git a/mbedtls_vs_boringssl/mbedtls/Makefile.aarch64 b/mbedtls_vs_boringssl/mbedtls/Makefile.aarch64
new file mode 100644
index 0000000..5c63884
--- /dev/null
+++ b/mbedtls_vs_boringssl/mbedtls/Makefile.aarch64
@@ -0,0 +1,48 @@
+include ../common.mk
+
+## NDK configuration.
+NDK = $(ANDROID_NDK)
+NDK_TARGETARCH = aarch64-linux-android
+NDK_TARGETSHORTARCH = arm64
+NDK_TOOLVER = 4.9
+NDK_HOSTARCH = linux-x86_64
+NDK_TOOLS = $(NDK)/toolchains/llvm/prebuilt/$(NDK_HOSTARCH)/bin
+NDK_SYSROOT = $(NDK)/sysroot
+NDK_TOOL = $(NDK_TOOLS)/clang
+NDK_LIBS = $(NDK)/toolchains/$(NDK_TARGETARCH)-$(NDK_TOOLVER)/prebuilt/linux-x86_64/lib/gcc/$(NDK_TARGETARCH)/4.9.x
+NDK_INCLUDES = -I$(NDK)/sysroot/usr/include -I$(NDK)/sysroot/usr/include/$(NDK_TARGETARCH)
+NDK_SYSROOT = $(NDK)/platforms/android-$(NDK_TARGETVER)/arch-$(NDK_TARGETSHORTARCH)
+
+OPT = -std=c99 -Os \
+ -fdata-sections \
+ -ffunction-sections \
+ -fPIE \
+ -Wall \
+ -target $(NDK_TARGETARCH)
+
+CFLAGS = $(OPT) \
+ $(NDK_INCLUDES) \
+ -D__ANDROID_API__=$(NDK_TARGETVER) \
+ -D_SOCKLEN_T_DECLARED
+
+LDFLAGS = $(OPT) \
+ -pie \
+ -Wl,--gc-sections \
+ --sysroot=$(NDK_SYSROOT) \
+ -B $(ANDROID_NDK)/toolchains/$(NDK_TARGETARCH)-$(NDK_TOOLVER)/prebuilt/linux-x86_64/$(NDK_TARGETARCH)/bin \
+ -L$(NDK_LIBS)
+
+all:
+ CC=$(NDK_TOOL) CFLAGS="$(CFLAGS)" LDFLAGS="$(LDFLAGS)" make -C src
+
+clean:
+ make -C src clean
+
+push:
+ adb root
+ adb remount
+ adb shell "rm -rf /data/app/mbedtls/*"
+ adb shell "mkdir -p /data/app/mbedtls"
+ adb push src/programs/ssl/ssl_client1 /data/app/mbedtls/
+ adb push src/programs/ssl/ssl_server /data/app/mbedtls/
+ adb push src/programs/test/benchmark /data/app/mbedtls/
\ No newline at end of file
diff --git a/mbedtls_vs_boringssl/mbedtls/Makefile.native b/mbedtls_vs_boringssl/mbedtls/Makefile.native
new file mode 100644
index 0000000..567afa0
--- /dev/null
+++ b/mbedtls_vs_boringssl/mbedtls/Makefile.native
@@ -0,0 +1,13 @@
+include ../common.mk
+
+OPT = -D_SOCKLEN_T_DECLARED -Os -fdata-sections
+
+CFLAGS = $(OPT)
+LDFLAGS =
+
+all:
+ CC=gcc CFLAGS="$(CFLAGS)" LDFLAGS="$(LDFLAGS)" make -C src
+
+clean:
+ make -C src clean
+
diff --git a/mbedtls_vs_boringssl/mbedtls/config_mbedTLS_minimal.h b/mbedtls_vs_boringssl/mbedtls/config_mbedTLS_minimal.h
new file mode 100644
index 0000000..12f62d8
--- /dev/null
+++ b/mbedtls_vs_boringssl/mbedtls/config_mbedTLS_minimal.h
@@ -0,0 +1,2879 @@
+/**
+ * \file config.h
+ *
+ * \brief Configuration options (set of defines)
+ *
+ * This set of compile-time options may be used to enable
+ * or disable features selectively, and reduce the global
+ * memory footprint.
+ */
+/*
+ * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * 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.
+ *
+ * This file is part of mbed TLS (https://tls.mbed.org)
+ */
+
+#ifndef MBEDTLS_CONFIG_H
+#define MBEDTLS_CONFIG_H
+
+#if defined(_MSC_VER) && !defined(_CRT_SECURE_NO_DEPRECATE)
+#define _CRT_SECURE_NO_DEPRECATE 1
+#endif
+
+/**
+ * \name SECTION: System support
+ *
+ * This section sets system specific settings.
+ * \{
+ */
+
+/**
+ * \def MBEDTLS_HAVE_ASM
+ *
+ * The compiler has support for asm().
+ *
+ * Requires support for asm() in compiler.
+ *
+ * Used in:
+ * library/timing.c
+ * library/padlock.c
+ * include/mbedtls/bn_mul.h
+ *
+ * Comment to disable the use of assembly code.
+ */
+#define MBEDTLS_HAVE_ASM
+
+/**
+ * \def MBEDTLS_NO_UDBL_DIVISION
+ *
+ * The platform lacks support for double-width integer division (64-bit
+ * division on a 32-bit platform, 128-bit division on a 64-bit platform).
+ *
+ * Used in:
+ * include/mbedtls/bignum.h
+ * library/bignum.c
+ *
+ * The bignum code uses double-width division to speed up some operations.
+ * Double-width division is often implemented in software that needs to
+ * be linked with the program. The presence of a double-width integer
+ * type is usually detected automatically through preprocessor macros,
+ * but the automatic detection cannot know whether the code needs to
+ * and can be linked with an implementation of division for that type.
+ * By default division is assumed to be usable if the type is present.
+ * Uncomment this option to prevent the use of double-width division.
+ *
+ * Note that division for the native integer type is always required.
+ * Furthermore, a 64-bit type is always required even on a 32-bit
+ * platform, but it need not support multiplication or division. In some
+ * cases it is also desirable to disable some double-width operations. For
+ * example, if double-width division is implemented in software, disabling
+ * it can reduce code size in some embedded targets.
+ */
+//#define MBEDTLS_NO_UDBL_DIVISION
+
+/**
+ * \def MBEDTLS_HAVE_SSE2
+ *
+ * CPU supports SSE2 instruction set.
+ *
+ * Uncomment if the CPU supports SSE2 (IA-32 specific).
+ */
+//#define MBEDTLS_HAVE_SSE2
+
+/**
+ * \def MBEDTLS_HAVE_TIME
+ *
+ * System has time.h and time().
+ * The time does not need to be correct, only time differences are used,
+ * by contrast with MBEDTLS_HAVE_TIME_DATE
+ *
+ * Defining MBEDTLS_HAVE_TIME allows you to specify MBEDTLS_PLATFORM_TIME_ALT,
+ * MBEDTLS_PLATFORM_TIME_MACRO, MBEDTLS_PLATFORM_TIME_TYPE_MACRO and
+ * MBEDTLS_PLATFORM_STD_TIME.
+ *
+ * Comment if your system does not support time functions
+ */
+#define MBEDTLS_HAVE_TIME
+
+/**
+ * \def MBEDTLS_HAVE_TIME_DATE
+ *
+ * System has time.h and time(), gmtime() and the clock is correct.
+ * The time needs to be correct (not necesarily very accurate, but at least
+ * the date should be correct). This is used to verify the validity period of
+ * X.509 certificates.
+ *
+ * Comment if your system does not have a correct clock.
+ */
+#define MBEDTLS_HAVE_TIME_DATE
+
+/**
+ * \def MBEDTLS_PLATFORM_MEMORY
+ *
+ * Enable the memory allocation layer.
+ *
+ * By default mbed TLS uses the system-provided calloc() and free().
+ * This allows different allocators (self-implemented or provided) to be
+ * provided to the platform abstraction layer.
+ *
+ * Enabling MBEDTLS_PLATFORM_MEMORY without the
+ * MBEDTLS_PLATFORM_{FREE,CALLOC}_MACROs will provide
+ * "mbedtls_platform_set_calloc_free()" allowing you to set an alternative calloc() and
+ * free() function pointer at runtime.
+ *
+ * Enabling MBEDTLS_PLATFORM_MEMORY and specifying
+ * MBEDTLS_PLATFORM_{CALLOC,FREE}_MACROs will allow you to specify the
+ * alternate function at compile time.
+ *
+ * Requires: MBEDTLS_PLATFORM_C
+ *
+ * Enable this layer to allow use of alternative memory allocators.
+ */
+//#define MBEDTLS_PLATFORM_MEMORY
+
+/**
+ * \def MBEDTLS_PLATFORM_NO_STD_FUNCTIONS
+ *
+ * Do not assign standard functions in the platform layer (e.g. calloc() to
+ * MBEDTLS_PLATFORM_STD_CALLOC and printf() to MBEDTLS_PLATFORM_STD_PRINTF)
+ *
+ * This makes sure there are no linking errors on platforms that do not support
+ * these functions. You will HAVE to provide alternatives, either at runtime
+ * via the platform_set_xxx() functions or at compile time by setting
+ * the MBEDTLS_PLATFORM_STD_XXX defines, or enabling a
+ * MBEDTLS_PLATFORM_XXX_MACRO.
+ *
+ * Requires: MBEDTLS_PLATFORM_C
+ *
+ * Uncomment to prevent default assignment of standard functions in the
+ * platform layer.
+ */
+//#define MBEDTLS_PLATFORM_NO_STD_FUNCTIONS
+
+/**
+ * \def MBEDTLS_PLATFORM_EXIT_ALT
+ *
+ * MBEDTLS_PLATFORM_XXX_ALT: Uncomment a macro to let mbed TLS support the
+ * function in the platform abstraction layer.
+ *
+ * Example: In case you uncomment MBEDTLS_PLATFORM_PRINTF_ALT, mbed TLS will
+ * provide a function "mbedtls_platform_set_printf()" that allows you to set an
+ * alternative printf function pointer.
+ *
+ * All these define require MBEDTLS_PLATFORM_C to be defined!
+ *
+ * \note MBEDTLS_PLATFORM_SNPRINTF_ALT is required on Windows;
+ * it will be enabled automatically by check_config.h
+ *
+ * \warning MBEDTLS_PLATFORM_XXX_ALT cannot be defined at the same time as
+ * MBEDTLS_PLATFORM_XXX_MACRO!
+ *
+ * Requires: MBEDTLS_PLATFORM_TIME_ALT requires MBEDTLS_HAVE_TIME
+ *
+ * Uncomment a macro to enable alternate implementation of specific base
+ * platform function
+ */
+//#define MBEDTLS_PLATFORM_EXIT_ALT
+//#define MBEDTLS_PLATFORM_TIME_ALT
+//#define MBEDTLS_PLATFORM_FPRINTF_ALT
+//#define MBEDTLS_PLATFORM_PRINTF_ALT
+//#define MBEDTLS_PLATFORM_SNPRINTF_ALT
+//#define MBEDTLS_PLATFORM_NV_SEED_ALT
+//#define MBEDTLS_PLATFORM_SETUP_TEARDOWN_ALT
+
+/**
+ * \def MBEDTLS_DEPRECATED_WARNING
+ *
+ * Mark deprecated functions so that they generate a warning if used.
+ * Functions deprecated in one version will usually be removed in the next
+ * version. You can enable this to help you prepare the transition to a new
+ * major version by making sure your code is not using these functions.
+ *
+ * This only works with GCC and Clang. With other compilers, you may want to
+ * use MBEDTLS_DEPRECATED_REMOVED
+ *
+ * Uncomment to get warnings on using deprecated functions.
+ */
+//#define MBEDTLS_DEPRECATED_WARNING
+
+/**
+ * \def MBEDTLS_DEPRECATED_REMOVED
+ *
+ * Remove deprecated functions so that they generate an error if used.
+ * Functions deprecated in one version will usually be removed in the next
+ * version. You can enable this to help you prepare the transition to a new
+ * major version by making sure your code is not using these functions.
+ *
+ * Uncomment to get errors on using deprecated functions.
+ */
+#define MBEDTLS_DEPRECATED_REMOVED
+
+/* \} name SECTION: System support */
+
+/**
+ * \name SECTION: mbed TLS feature support
+ *
+ * This section sets support for features that are or are not needed
+ * within the modules that are enabled.
+ * \{
+ */
+
+/**
+ * \def MBEDTLS_TIMING_ALT
+ *
+ * Uncomment to provide your own alternate implementation for mbedtls_timing_hardclock(),
+ * mbedtls_timing_get_timer(), mbedtls_set_alarm(), mbedtls_set/get_delay()
+ *
+ * Only works if you have MBEDTLS_TIMING_C enabled.
+ *
+ * You will need to provide a header "timing_alt.h" and an implementation at
+ * compile time.
+ */
+//#define MBEDTLS_TIMING_ALT
+
+/**
+ * \def MBEDTLS_AES_ALT
+ *
+ * MBEDTLS__MODULE_NAME__ALT: Uncomment a macro to let mbed TLS use your
+ * alternate core implementation of a symmetric crypto, an arithmetic or hash
+ * module (e.g. platform specific assembly optimized implementations). Keep
+ * in mind that the function prototypes should remain the same.
+ *
+ * This replaces the whole module. If you only want to replace one of the
+ * functions, use one of the MBEDTLS__FUNCTION_NAME__ALT flags.
+ *
+ * Example: In case you uncomment MBEDTLS_AES_ALT, mbed TLS will no longer
+ * provide the "struct mbedtls_aes_context" definition and omit the base
+ * function declarations and implementations. "aes_alt.h" will be included from
+ * "aes.h" to include the new function definitions.
+ *
+ * Uncomment a macro to enable alternate implementation of the corresponding
+ * module.
+ *
+ * \warning MD2, MD4, MD5, ARC4, DES and SHA-1 are considered weak and their
+ * use constitutes a security risk. If possible, we recommend
+ * avoiding dependencies on them, and considering stronger message
+ * digests and ciphers instead.
+ *
+ */
+//#define MBEDTLS_AES_ALT
+//#define MBEDTLS_ARC4_ALT
+//#define MBEDTLS_BLOWFISH_ALT
+//#define MBEDTLS_CAMELLIA_ALT
+//#define MBEDTLS_CCM_ALT
+//#define MBEDTLS_CMAC_ALT
+//#define MBEDTLS_DES_ALT
+//#define MBEDTLS_DHM_ALT
+//#define MBEDTLS_ECJPAKE_ALT
+//#define MBEDTLS_GCM_ALT
+//#define MBEDTLS_MD2_ALT
+//#define MBEDTLS_MD4_ALT
+//#define MBEDTLS_MD5_ALT
+//#define MBEDTLS_RIPEMD160_ALT
+//#define MBEDTLS_RSA_ALT
+//#define MBEDTLS_SHA1_ALT
+//#define MBEDTLS_SHA256_ALT
+//#define MBEDTLS_SHA512_ALT
+//#define MBEDTLS_XTEA_ALT
+/*
+ * When replacing the elliptic curve module, pleace consider, that it is
+ * implemented with two .c files:
+ * - ecp.c
+ * - ecp_curves.c
+ * You can replace them very much like all the other MBEDTLS__MODULE_NAME__ALT
+ * macros as described above. The only difference is that you have to make sure
+ * that you provide functionality for both .c files.
+ */
+//#define MBEDTLS_ECP_ALT
+
+/**
+ * \def MBEDTLS_MD2_PROCESS_ALT
+ *
+ * MBEDTLS__FUNCTION_NAME__ALT: Uncomment a macro to let mbed TLS use you
+ * alternate core implementation of symmetric crypto or hash function. Keep in
+ * mind that function prototypes should remain the same.
+ *
+ * This replaces only one function. The header file from mbed TLS is still
+ * used, in contrast to the MBEDTLS__MODULE_NAME__ALT flags.
+ *
+ * Example: In case you uncomment MBEDTLS_SHA256_PROCESS_ALT, mbed TLS will
+ * no longer provide the mbedtls_sha1_process() function, but it will still provide
+ * the other function (using your mbedtls_sha1_process() function) and the definition
+ * of mbedtls_sha1_context, so your implementation of mbedtls_sha1_process must be compatible
+ * with this definition.
+ *
+ * \note Because of a signature change, the core AES encryption and decryption routines are
+ * currently named mbedtls_aes_internal_encrypt and mbedtls_aes_internal_decrypt,
+ * respectively. When setting up alternative implementations, these functions should
+ * be overriden, but the wrapper functions mbedtls_aes_decrypt and mbedtls_aes_encrypt
+ * must stay untouched.
+ *
+ * \note If you use the AES_xxx_ALT macros, then is is recommended to also set
+ * MBEDTLS_AES_ROM_TABLES in order to help the linker garbage-collect the AES
+ * tables.
+ *
+ * Uncomment a macro to enable alternate implementation of the corresponding
+ * function.
+ *
+ * \warning MD2, MD4, MD5, DES and SHA-1 are considered weak and their use
+ * constitutes a security risk. If possible, we recommend avoiding
+ * dependencies on them, and considering stronger message digests
+ * and ciphers instead.
+ *
+ */
+//#define MBEDTLS_MD2_PROCESS_ALT
+//#define MBEDTLS_MD4_PROCESS_ALT
+//#define MBEDTLS_MD5_PROCESS_ALT
+//#define MBEDTLS_RIPEMD160_PROCESS_ALT
+//#define MBEDTLS_SHA1_PROCESS_ALT
+//#define MBEDTLS_SHA256_PROCESS_ALT
+//#define MBEDTLS_SHA512_PROCESS_ALT
+//#define MBEDTLS_DES_SETKEY_ALT
+//#define MBEDTLS_DES_CRYPT_ECB_ALT
+//#define MBEDTLS_DES3_CRYPT_ECB_ALT
+//#define MBEDTLS_AES_SETKEY_ENC_ALT
+//#define MBEDTLS_AES_SETKEY_DEC_ALT
+//#define MBEDTLS_AES_ENCRYPT_ALT
+//#define MBEDTLS_AES_DECRYPT_ALT
+//#define MBEDTLS_ECDH_GEN_PUBLIC_ALT
+//#define MBEDTLS_ECDH_COMPUTE_SHARED_ALT
+//#define MBEDTLS_ECDSA_VERIFY_ALT
+//#define MBEDTLS_ECDSA_SIGN_ALT
+//#define MBEDTLS_ECDSA_GENKEY_ALT
+
+/**
+ * \def MBEDTLS_ECP_INTERNAL_ALT
+ *
+ * Expose a part of the internal interface of the Elliptic Curve Point module.
+ *
+ * MBEDTLS_ECP__FUNCTION_NAME__ALT: Uncomment a macro to let mbed TLS use your
+ * alternative core implementation of elliptic curve arithmetic. Keep in mind
+ * that function prototypes should remain the same.
+ *
+ * This partially replaces one function. The header file from mbed TLS is still
+ * used, in contrast to the MBEDTLS_ECP_ALT flag. The original implementation
+ * is still present and it is used for group structures not supported by the
+ * alternative.
+ *
+ * Any of these options become available by defining MBEDTLS_ECP_INTERNAL_ALT
+ * and implementing the following functions:
+ * unsigned char mbedtls_internal_ecp_grp_capable(
+ * const mbedtls_ecp_group *grp )
+ * int mbedtls_internal_ecp_init( const mbedtls_ecp_group *grp )
+ * void mbedtls_internal_ecp_deinit( const mbedtls_ecp_group *grp )
+ * The mbedtls_internal_ecp_grp_capable function should return 1 if the
+ * replacement functions implement arithmetic for the given group and 0
+ * otherwise.
+ * The functions mbedtls_internal_ecp_init and mbedtls_internal_ecp_deinit are
+ * called before and after each point operation and provide an opportunity to
+ * implement optimized set up and tear down instructions.
+ *
+ * Example: In case you uncomment MBEDTLS_ECP_INTERNAL_ALT and
+ * MBEDTLS_ECP_DOUBLE_JAC_ALT, mbed TLS will still provide the ecp_double_jac
+ * function, but will use your mbedtls_internal_ecp_double_jac if the group is
+ * supported (your mbedtls_internal_ecp_grp_capable function returns 1 when
+ * receives it as an argument). If the group is not supported then the original
+ * implementation is used. The other functions and the definition of
+ * mbedtls_ecp_group and mbedtls_ecp_point will not change, so your
+ * implementation of mbedtls_internal_ecp_double_jac and
+ * mbedtls_internal_ecp_grp_capable must be compatible with this definition.
+ *
+ * Uncomment a macro to enable alternate implementation of the corresponding
+ * function.
+ */
+/* Required for all the functions in this section */
+//#define MBEDTLS_ECP_INTERNAL_ALT
+/* Support for Weierstrass curves with Jacobi representation */
+//#define MBEDTLS_ECP_RANDOMIZE_JAC_ALT
+//#define MBEDTLS_ECP_ADD_MIXED_ALT
+//#define MBEDTLS_ECP_DOUBLE_JAC_ALT
+//#define MBEDTLS_ECP_NORMALIZE_JAC_MANY_ALT
+//#define MBEDTLS_ECP_NORMALIZE_JAC_ALT
+/* Support for curves with Montgomery arithmetic */
+//#define MBEDTLS_ECP_DOUBLE_ADD_MXZ_ALT
+//#define MBEDTLS_ECP_RANDOMIZE_MXZ_ALT
+//#define MBEDTLS_ECP_NORMALIZE_MXZ_ALT
+
+/**
+ * \def MBEDTLS_TEST_NULL_ENTROPY
+ *
+ * Enables testing and use of mbed TLS without any configured entropy sources.
+ * This permits use of the library on platforms before an entropy source has
+ * been integrated (see for example the MBEDTLS_ENTROPY_HARDWARE_ALT or the
+ * MBEDTLS_ENTROPY_NV_SEED switches).
+ *
+ * WARNING! This switch MUST be disabled in production builds, and is suitable
+ * only for development.
+ * Enabling the switch negates any security provided by the library.
+ *
+ * Requires MBEDTLS_ENTROPY_C, MBEDTLS_NO_DEFAULT_ENTROPY_SOURCES
+ *
+ */
+//#define MBEDTLS_TEST_NULL_ENTROPY
+
+/**
+ * \def MBEDTLS_ENTROPY_HARDWARE_ALT
+ *
+ * Uncomment this macro to let mbed TLS use your own implementation of a
+ * hardware entropy collector.
+ *
+ * Your function must be called \c mbedtls_hardware_poll(), have the same
+ * prototype as declared in entropy_poll.h, and accept NULL as first argument.
+ *
+ * Uncomment to use your own hardware entropy collector.
+ */
+//#define MBEDTLS_ENTROPY_HARDWARE_ALT
+
+/**
+ * \def MBEDTLS_AES_ROM_TABLES
+ *
+ * Use precomputed AES tables stored in ROM.
+ *
+ * Uncomment this macro to use precomputed AES tables stored in ROM.
+ * Comment this macro to generate AES tables in RAM at runtime.
+ *
+ * Tradeoff: Using precomputed ROM tables reduces RAM usage by ~8kb
+ * (or ~2kb if \c MBEDTLS_AES_FEWER_TABLES is used) and reduces the
+ * initialization time before the first AES operation can be performed.
+ * It comes at the cost of additional ~8kb ROM use (resp. ~2kb if \c
+ * MBEDTLS_AES_FEWER_TABLES below is used), and potentially degraded
+ * performance if ROM access is slower than RAM access.
+ *
+ * This option is independent of \c MBEDTLS_AES_FEWER_TABLES.
+ *
+ */
+//#define MBEDTLS_AES_ROM_TABLES
+
+/**
+ * \def MBEDTLS_AES_FEWER_TABLES
+ *
+ * Use less ROM/RAM for AES tables.
+ *
+ * Uncommenting this macro omits 75% of the AES tables from
+ * ROM / RAM (depending on the value of \c MBEDTLS_AES_ROM_TABLES)
+ * by computing their values on the fly during operations
+ * (the tables are entry-wise rotations of one another).
+ *
+ * Tradeoff: Uncommenting this reduces the RAM / ROM footprint
+ * by ~6kb but at the cost of more arithmetic operations during
+ * runtime. Specifically, one has to compare 4 accesses within
+ * different tables to 4 accesses with additional arithmetic
+ * operations within the same table. The performance gain/loss
+ * depends on the system and memory details.
+ *
+ * This option is independent of \c MBEDTLS_AES_ROM_TABLES.
+ *
+ */
+//#define MBEDTLS_AES_FEWER_TABLES
+
+/**
+ * \def MBEDTLS_CAMELLIA_SMALL_MEMORY
+ *
+ * Use less ROM for the Camellia implementation (saves about 768 bytes).
+ *
+ * Uncomment this macro to use less memory for Camellia.
+ */
+//#define MBEDTLS_CAMELLIA_SMALL_MEMORY
+
+/**
+ * \def MBEDTLS_CIPHER_MODE_CBC
+ *
+ * Enable Cipher Block Chaining mode (CBC) for symmetric ciphers.
+ */
+//#define MBEDTLS_CIPHER_MODE_CBC
+
+/**
+ * \def MBEDTLS_CIPHER_MODE_CFB
+ *
+ * Enable Cipher Feedback mode (CFB) for symmetric ciphers.
+ */
+//#define MBEDTLS_CIPHER_MODE_CFB
+
+/**
+ * \def MBEDTLS_CIPHER_MODE_CTR
+ *
+ * Enable Counter Block Cipher mode (CTR) for symmetric ciphers.
+ */
+//#define MBEDTLS_CIPHER_MODE_CTR
+
+/**
+ * \def MBEDTLS_CIPHER_NULL_CIPHER
+ *
+ * Enable NULL cipher.
+ * Warning: Only do so when you know what you are doing. This allows for
+ * encryption or channels without any security!
+ *
+ * Requires MBEDTLS_ENABLE_WEAK_CIPHERSUITES as well to enable
+ * the following ciphersuites:
+ * MBEDTLS_TLS_ECDH_ECDSA_WITH_NULL_SHA
+ * MBEDTLS_TLS_ECDH_RSA_WITH_NULL_SHA
+ * MBEDTLS_TLS_ECDHE_ECDSA_WITH_NULL_SHA
+ * MBEDTLS_TLS_ECDHE_RSA_WITH_NULL_SHA
+ * MBEDTLS_TLS_ECDHE_PSK_WITH_NULL_SHA384
+ * MBEDTLS_TLS_ECDHE_PSK_WITH_NULL_SHA256
+ * MBEDTLS_TLS_ECDHE_PSK_WITH_NULL_SHA
+ * MBEDTLS_TLS_DHE_PSK_WITH_NULL_SHA384
+ * MBEDTLS_TLS_DHE_PSK_WITH_NULL_SHA256
+ * MBEDTLS_TLS_DHE_PSK_WITH_NULL_SHA
+ * MBEDTLS_TLS_RSA_WITH_NULL_SHA256
+ * MBEDTLS_TLS_RSA_WITH_NULL_SHA
+ * MBEDTLS_TLS_RSA_WITH_NULL_MD5
+ * MBEDTLS_TLS_RSA_PSK_WITH_NULL_SHA384
+ * MBEDTLS_TLS_RSA_PSK_WITH_NULL_SHA256
+ * MBEDTLS_TLS_RSA_PSK_WITH_NULL_SHA
+ * MBEDTLS_TLS_PSK_WITH_NULL_SHA384
+ * MBEDTLS_TLS_PSK_WITH_NULL_SHA256
+ * MBEDTLS_TLS_PSK_WITH_NULL_SHA
+ *
+ * Uncomment this macro to enable the NULL cipher and ciphersuites
+ */
+//#define MBEDTLS_CIPHER_NULL_CIPHER
+
+/**
+ * \def MBEDTLS_CIPHER_PADDING_PKCS7
+ *
+ * MBEDTLS_CIPHER_PADDING_XXX: Uncomment or comment macros to add support for
+ * specific padding modes in the cipher layer with cipher modes that support
+ * padding (e.g. CBC)
+ *
+ * If you disable all padding modes, only full blocks can be used with CBC.
+ *
+ * Enable padding modes in the cipher layer.
+ */
+#define MBEDTLS_CIPHER_PADDING_PKCS7
+//#define MBEDTLS_CIPHER_PADDING_ONE_AND_ZEROS
+//#define MBEDTLS_CIPHER_PADDING_ZEROS_AND_LEN
+//#define MBEDTLS_CIPHER_PADDING_ZEROS
+
+/**
+ * \def MBEDTLS_ENABLE_WEAK_CIPHERSUITES
+ *
+ * Enable weak ciphersuites in SSL / TLS.
+ * Warning: Only do so when you know what you are doing. This allows for
+ * channels with virtually no security at all!
+ *
+ * This enables the following ciphersuites:
+ * MBEDTLS_TLS_RSA_WITH_DES_CBC_SHA
+ * MBEDTLS_TLS_DHE_RSA_WITH_DES_CBC_SHA
+ *
+ * Uncomment this macro to enable weak ciphersuites
+ *
+ * \warning DES is considered a weak cipher and its use constitutes a
+ * security risk. We recommend considering stronger ciphers instead.
+ */
+//#define MBEDTLS_ENABLE_WEAK_CIPHERSUITES
+
+/**
+ * \def MBEDTLS_REMOVE_ARC4_CIPHERSUITES
+ *
+ * Remove RC4 ciphersuites by default in SSL / TLS.
+ * This flag removes the ciphersuites based on RC4 from the default list as
+ * returned by mbedtls_ssl_list_ciphersuites(). However, it is still possible to
+ * enable (some of) them with mbedtls_ssl_conf_ciphersuites() by including them
+ * explicitly.
+ *
+ * Uncomment this macro to remove RC4 ciphersuites by default.
+ */
+#define MBEDTLS_REMOVE_ARC4_CIPHERSUITES
+
+/**
+ * \def MBEDTLS_ECP_DP_SECP192R1_ENABLED
+ *
+ * MBEDTLS_ECP_XXXX_ENABLED: Enables specific curves within the Elliptic Curve
+ * module. By default all supported curves are enabled.
+ *
+ * Comment macros to disable the curve and functions for it
+ */
+//#define MBEDTLS_ECP_DP_SECP192R1_ENABLED
+//#define MBEDTLS_ECP_DP_SECP224R1_ENABLED
+#define MBEDTLS_ECP_DP_SECP256R1_ENABLED
+//#define MBEDTLS_ECP_DP_SECP384R1_ENABLED
+//#define MBEDTLS_ECP_DP_SECP521R1_ENABLED
+//#define MBEDTLS_ECP_DP_SECP192K1_ENABLED
+//#define MBEDTLS_ECP_DP_SECP224K1_ENABLED
+//#define MBEDTLS_ECP_DP_SECP256K1_ENABLED
+//#define MBEDTLS_ECP_DP_BP256R1_ENABLED
+//#define MBEDTLS_ECP_DP_BP384R1_ENABLED
+//#define MBEDTLS_ECP_DP_BP512R1_ENABLED
+#define MBEDTLS_ECP_DP_CURVE25519_ENABLED
+#define MBEDTLS_ECP_DP_CURVE448_ENABLED
+
+/**
+ * \def MBEDTLS_ECP_NIST_OPTIM
+ *
+ * Enable specific 'modulo p' routines for each NIST prime.
+ * Depending on the prime and architecture, makes operations 4 to 8 times
+ * faster on the corresponding curve.
+ *
+ * Comment this macro to disable NIST curves optimisation.
+ */
+#define MBEDTLS_ECP_NIST_OPTIM
+
+/**
+ * \def MBEDTLS_ECDSA_DETERMINISTIC
+ *
+ * Enable deterministic ECDSA (RFC 6979).
+ * Standard ECDSA is "fragile" in the sense that lack of entropy when signing
+ * may result in a compromise of the long-term signing key. This is avoided by
+ * the deterministic variant.
+ *
+ * Requires: MBEDTLS_HMAC_DRBG_C
+ *
+ * Comment this macro to disable deterministic ECDSA.
+ */
+#define MBEDTLS_ECDSA_DETERMINISTIC
+
+/**
+ * \def MBEDTLS_KEY_EXCHANGE_PSK_ENABLED
+ *
+ * Enable the PSK based ciphersuite modes in SSL / TLS.
+ *
+ * This enables the following ciphersuites (if other requisites are
+ * enabled as well):
+ * MBEDTLS_TLS_PSK_WITH_AES_256_GCM_SHA384
+ * MBEDTLS_TLS_PSK_WITH_AES_256_CBC_SHA384
+ * MBEDTLS_TLS_PSK_WITH_AES_256_CBC_SHA
+ * MBEDTLS_TLS_PSK_WITH_CAMELLIA_256_GCM_SHA384
+ * MBEDTLS_TLS_PSK_WITH_CAMELLIA_256_CBC_SHA384
+ * MBEDTLS_TLS_PSK_WITH_AES_128_GCM_SHA256
+ * MBEDTLS_TLS_PSK_WITH_AES_128_CBC_SHA256
+ * MBEDTLS_TLS_PSK_WITH_AES_128_CBC_SHA
+ * MBEDTLS_TLS_PSK_WITH_CAMELLIA_128_GCM_SHA256
+ * MBEDTLS_TLS_PSK_WITH_CAMELLIA_128_CBC_SHA256
+ * MBEDTLS_TLS_PSK_WITH_3DES_EDE_CBC_SHA
+ * MBEDTLS_TLS_PSK_WITH_RC4_128_SHA
+ */
+//#define MBEDTLS_KEY_EXCHANGE_PSK_ENABLED
+
+/**
+ * \def MBEDTLS_KEY_EXCHANGE_DHE_PSK_ENABLED
+ *
+ * Enable the DHE-PSK based ciphersuite modes in SSL / TLS.
+ *
+ * Requires: MBEDTLS_DHM_C
+ *
+ * This enables the following ciphersuites (if other requisites are
+ * enabled as well):
+ * MBEDTLS_TLS_DHE_PSK_WITH_AES_256_GCM_SHA384
+ * MBEDTLS_TLS_DHE_PSK_WITH_AES_256_CBC_SHA384
+ * MBEDTLS_TLS_DHE_PSK_WITH_AES_256_CBC_SHA
+ * MBEDTLS_TLS_DHE_PSK_WITH_CAMELLIA_256_GCM_SHA384
+ * MBEDTLS_TLS_DHE_PSK_WITH_CAMELLIA_256_CBC_SHA384
+ * MBEDTLS_TLS_DHE_PSK_WITH_AES_128_GCM_SHA256
+ * MBEDTLS_TLS_DHE_PSK_WITH_AES_128_CBC_SHA256
+ * MBEDTLS_TLS_DHE_PSK_WITH_AES_128_CBC_SHA
+ * MBEDTLS_TLS_DHE_PSK_WITH_CAMELLIA_128_GCM_SHA256
+ * MBEDTLS_TLS_DHE_PSK_WITH_CAMELLIA_128_CBC_SHA256
+ * MBEDTLS_TLS_DHE_PSK_WITH_3DES_EDE_CBC_SHA
+ * MBEDTLS_TLS_DHE_PSK_WITH_RC4_128_SHA
+ *
+ * \warning Using DHE constitutes a security risk as it
+ * is not possible to validate custom DH parameters.
+ * If possible, it is recommended users should consider
+ * preferring other methods of key exchange.
+ * See dhm.h for more details.
+ *
+ */
+//#define MBEDTLS_KEY_EXCHANGE_DHE_PSK_ENABLED
+
+/**
+ * \def MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED
+ *
+ * Enable the ECDHE-PSK based ciphersuite modes in SSL / TLS.
+ *
+ * Requires: MBEDTLS_ECDH_C
+ *
+ * This enables the following ciphersuites (if other requisites are
+ * enabled as well):
+ * MBEDTLS_TLS_ECDHE_PSK_WITH_AES_256_CBC_SHA384
+ * MBEDTLS_TLS_ECDHE_PSK_WITH_AES_256_CBC_SHA
+ * MBEDTLS_TLS_ECDHE_PSK_WITH_CAMELLIA_256_CBC_SHA384
+ * MBEDTLS_TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA256
+ * MBEDTLS_TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA
+ * MBEDTLS_TLS_ECDHE_PSK_WITH_CAMELLIA_128_CBC_SHA256
+ * MBEDTLS_TLS_ECDHE_PSK_WITH_3DES_EDE_CBC_SHA
+ * MBEDTLS_TLS_ECDHE_PSK_WITH_RC4_128_SHA
+ */
+//#define MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED
+
+/**
+ * \def MBEDTLS_KEY_EXCHANGE_RSA_PSK_ENABLED
+ *
+ * Enable the RSA-PSK based ciphersuite modes in SSL / TLS.
+ *
+ * Requires: MBEDTLS_RSA_C, MBEDTLS_PKCS1_V15,
+ * MBEDTLS_X509_CRT_PARSE_C
+ *
+ * This enables the following ciphersuites (if other requisites are
+ * enabled as well):
+ * MBEDTLS_TLS_RSA_PSK_WITH_AES_256_GCM_SHA384
+ * MBEDTLS_TLS_RSA_PSK_WITH_AES_256_CBC_SHA384
+ * MBEDTLS_TLS_RSA_PSK_WITH_AES_256_CBC_SHA
+ * MBEDTLS_TLS_RSA_PSK_WITH_CAMELLIA_256_GCM_SHA384
+ * MBEDTLS_TLS_RSA_PSK_WITH_CAMELLIA_256_CBC_SHA384
+ * MBEDTLS_TLS_RSA_PSK_WITH_AES_128_GCM_SHA256
+ * MBEDTLS_TLS_RSA_PSK_WITH_AES_128_CBC_SHA256
+ * MBEDTLS_TLS_RSA_PSK_WITH_AES_128_CBC_SHA
+ * MBEDTLS_TLS_RSA_PSK_WITH_CAMELLIA_128_GCM_SHA256
+ * MBEDTLS_TLS_RSA_PSK_WITH_CAMELLIA_128_CBC_SHA256
+ * MBEDTLS_TLS_RSA_PSK_WITH_3DES_EDE_CBC_SHA
+ * MBEDTLS_TLS_RSA_PSK_WITH_RC4_128_SHA
+ */
+//#define MBEDTLS_KEY_EXCHANGE_RSA_PSK_ENABLED
+
+/**
+ * \def MBEDTLS_KEY_EXCHANGE_RSA_ENABLED
+ *
+ * Enable the RSA-only based ciphersuite modes in SSL / TLS.
+ *
+ * Requires: MBEDTLS_RSA_C, MBEDTLS_PKCS1_V15,
+ * MBEDTLS_X509_CRT_PARSE_C
+ *
+ * This enables the following ciphersuites (if other requisites are
+ * enabled as well):
+ * MBEDTLS_TLS_RSA_WITH_AES_256_GCM_SHA384
+ * MBEDTLS_TLS_RSA_WITH_AES_256_CBC_SHA256
+ * MBEDTLS_TLS_RSA_WITH_AES_256_CBC_SHA
+ * MBEDTLS_TLS_RSA_WITH_CAMELLIA_256_GCM_SHA384
+ * MBEDTLS_TLS_RSA_WITH_CAMELLIA_256_CBC_SHA256
+ * MBEDTLS_TLS_RSA_WITH_CAMELLIA_256_CBC_SHA
+ * MBEDTLS_TLS_RSA_WITH_AES_128_GCM_SHA256
+ * MBEDTLS_TLS_RSA_WITH_AES_128_CBC_SHA256
+ * MBEDTLS_TLS_RSA_WITH_AES_128_CBC_SHA
+ * MBEDTLS_TLS_RSA_WITH_CAMELLIA_128_GCM_SHA256
+ * MBEDTLS_TLS_RSA_WITH_CAMELLIA_128_CBC_SHA256
+ * MBEDTLS_TLS_RSA_WITH_CAMELLIA_128_CBC_SHA
+ * MBEDTLS_TLS_RSA_WITH_3DES_EDE_CBC_SHA
+ * MBEDTLS_TLS_RSA_WITH_RC4_128_SHA
+ * MBEDTLS_TLS_RSA_WITH_RC4_128_MD5
+ */
+//#define MBEDTLS_KEY_EXCHANGE_RSA_ENABLED
+
+/**
+ * \def MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED
+ *
+ * Enable the DHE-RSA based ciphersuite modes in SSL / TLS.
+ *
+ * Requires: MBEDTLS_DHM_C, MBEDTLS_RSA_C, MBEDTLS_PKCS1_V15,
+ * MBEDTLS_X509_CRT_PARSE_C
+ *
+ * This enables the following ciphersuites (if other requisites are
+ * enabled as well):
+ * MBEDTLS_TLS_DHE_RSA_WITH_AES_256_GCM_SHA384
+ * MBEDTLS_TLS_DHE_RSA_WITH_AES_256_CBC_SHA256
+ * MBEDTLS_TLS_DHE_RSA_WITH_AES_256_CBC_SHA
+ * MBEDTLS_TLS_DHE_RSA_WITH_CAMELLIA_256_GCM_SHA384
+ * MBEDTLS_TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA256
+ * MBEDTLS_TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA
+ * MBEDTLS_TLS_DHE_RSA_WITH_AES_128_GCM_SHA256
+ * MBEDTLS_TLS_DHE_RSA_WITH_AES_128_CBC_SHA256
+ * MBEDTLS_TLS_DHE_RSA_WITH_AES_128_CBC_SHA
+ * MBEDTLS_TLS_DHE_RSA_WITH_CAMELLIA_128_GCM_SHA256
+ * MBEDTLS_TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA256
+ * MBEDTLS_TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA
+ * MBEDTLS_TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA
+ *
+ * \warning Using DHE constitutes a security risk as it
+ * is not possible to validate custom DH parameters.
+ * If possible, it is recommended users should consider
+ * preferring other methods of key exchange.
+ * See dhm.h for more details.
+ *
+ */
+//#define MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED
+
+/**
+ * \def MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED
+ *
+ * Enable the ECDHE-RSA based ciphersuite modes in SSL / TLS.
+ *
+ * Requires: MBEDTLS_ECDH_C, MBEDTLS_RSA_C, MBEDTLS_PKCS1_V15,
+ * MBEDTLS_X509_CRT_PARSE_C
+ *
+ * This enables the following ciphersuites (if other requisites are
+ * enabled as well):
+ * MBEDTLS_TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384
+ * MBEDTLS_TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384
+ * MBEDTLS_TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA
+ * MBEDTLS_TLS_ECDHE_RSA_WITH_CAMELLIA_256_GCM_SHA384
+ * MBEDTLS_TLS_ECDHE_RSA_WITH_CAMELLIA_256_CBC_SHA384
+ * MBEDTLS_TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256
+ * MBEDTLS_TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256
+ * MBEDTLS_TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA
+ * MBEDTLS_TLS_ECDHE_RSA_WITH_CAMELLIA_128_GCM_SHA256
+ * MBEDTLS_TLS_ECDHE_RSA_WITH_CAMELLIA_128_CBC_SHA256
+ * MBEDTLS_TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA
+ * MBEDTLS_TLS_ECDHE_RSA_WITH_RC4_128_SHA
+ */
+// #define MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED
+
+/**
+ * \def MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED
+ *
+ * Enable the ECDHE-ECDSA based ciphersuite modes in SSL / TLS.
+ *
+ * Requires: MBEDTLS_ECDH_C, MBEDTLS_ECDSA_C, MBEDTLS_X509_CRT_PARSE_C,
+ *
+ * This enables the following ciphersuites (if other requisites are
+ * enabled as well):
+ * MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384
+ * MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384
+ * MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA
+ * MBEDTLS_TLS_ECDHE_ECDSA_WITH_CAMELLIA_256_GCM_SHA384
+ * MBEDTLS_TLS_ECDHE_ECDSA_WITH_CAMELLIA_256_CBC_SHA384
+ * MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256
+ * MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256
+ * MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA
+ * MBEDTLS_TLS_ECDHE_ECDSA_WITH_CAMELLIA_128_GCM_SHA256
+ * MBEDTLS_TLS_ECDHE_ECDSA_WITH_CAMELLIA_128_CBC_SHA256
+ * MBEDTLS_TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA
+ * MBEDTLS_TLS_ECDHE_ECDSA_WITH_RC4_128_SHA
+ */
+#define MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED
+
+/**
+ * \def MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED
+ *
+ * Enable the ECDH-ECDSA based ciphersuite modes in SSL / TLS.
+ *
+ * Requires: MBEDTLS_ECDH_C, MBEDTLS_X509_CRT_PARSE_C
+ *
+ * This enables the following ciphersuites (if other requisites are
+ * enabled as well):
+ * MBEDTLS_TLS_ECDH_ECDSA_WITH_RC4_128_SHA
+ * MBEDTLS_TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA
+ * MBEDTLS_TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA
+ * MBEDTLS_TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA
+ * MBEDTLS_TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256
+ * MBEDTLS_TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384
+ * MBEDTLS_TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256
+ * MBEDTLS_TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384
+ * MBEDTLS_TLS_ECDH_ECDSA_WITH_CAMELLIA_128_CBC_SHA256
+ * MBEDTLS_TLS_ECDH_ECDSA_WITH_CAMELLIA_256_CBC_SHA384
+ * MBEDTLS_TLS_ECDH_ECDSA_WITH_CAMELLIA_128_GCM_SHA256
+ * MBEDTLS_TLS_ECDH_ECDSA_WITH_CAMELLIA_256_GCM_SHA384
+ */
+#define MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED
+
+/**
+ * \def MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED
+ *
+ * Enable the ECDH-RSA based ciphersuite modes in SSL / TLS.
+ *
+ * Requires: MBEDTLS_ECDH_C, MBEDTLS_X509_CRT_PARSE_C
+ *
+ * This enables the following ciphersuites (if other requisites are
+ * enabled as well):
+ * MBEDTLS_TLS_ECDH_RSA_WITH_RC4_128_SHA
+ * MBEDTLS_TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA
+ * MBEDTLS_TLS_ECDH_RSA_WITH_AES_128_CBC_SHA
+ * MBEDTLS_TLS_ECDH_RSA_WITH_AES_256_CBC_SHA
+ * MBEDTLS_TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256
+ * MBEDTLS_TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384
+ * MBEDTLS_TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256
+ * MBEDTLS_TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384
+ * MBEDTLS_TLS_ECDH_RSA_WITH_CAMELLIA_128_CBC_SHA256
+ * MBEDTLS_TLS_ECDH_RSA_WITH_CAMELLIA_256_CBC_SHA384
+ * MBEDTLS_TLS_ECDH_RSA_WITH_CAMELLIA_128_GCM_SHA256
+ * MBEDTLS_TLS_ECDH_RSA_WITH_CAMELLIA_256_GCM_SHA384
+ */
+//#define MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED
+
+/**
+ * \def MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED
+ *
+ * Enable the ECJPAKE based ciphersuite modes in SSL / TLS.
+ *
+ * \warning This is currently experimental. EC J-PAKE support is based on the
+ * Thread v1.0.0 specification; incompatible changes to the specification
+ * might still happen. For this reason, this is disabled by default.
+ *
+ * Requires: MBEDTLS_ECJPAKE_C
+ * MBEDTLS_SHA256_C
+ * MBEDTLS_ECP_DP_SECP256R1_ENABLED
+ *
+ * This enables the following ciphersuites (if other requisites are
+ * enabled as well):
+ * MBEDTLS_TLS_ECJPAKE_WITH_AES_128_CCM_8
+ */
+//#define MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED
+
+/**
+ * \def MBEDTLS_PK_PARSE_EC_EXTENDED
+ *
+ * Enhance support for reading EC keys using variants of SEC1 not allowed by
+ * RFC 5915 and RFC 5480.
+ *
+ * Currently this means parsing the SpecifiedECDomain choice of EC
+ * parameters (only known groups are supported, not arbitrary domains, to
+ * avoid validation issues).
+ *
+ * Disable if you only need to support RFC 5915 + 5480 key formats.
+ */
+#define MBEDTLS_PK_PARSE_EC_EXTENDED
+
+/**
+ * \def MBEDTLS_ERROR_STRERROR_DUMMY
+ *
+ * Enable a dummy error function to make use of mbedtls_strerror() in
+ * third party libraries easier when MBEDTLS_ERROR_C is disabled
+ * (no effect when MBEDTLS_ERROR_C is enabled).
+ *
+ * You can safely disable this if MBEDTLS_ERROR_C is enabled, or if you're
+ * not using mbedtls_strerror() or error_strerror() in your application.
+ *
+ * Disable if you run into name conflicts and want to really remove the
+ * mbedtls_strerror()
+ */
+//#define MBEDTLS_ERROR_STRERROR_DUMMY
+
+/**
+ * \def MBEDTLS_GENPRIME
+ *
+ * Enable the prime-number generation code.
+ *
+ * Requires: MBEDTLS_BIGNUM_C
+ */
+#define MBEDTLS_GENPRIME
+
+/**
+ * \def MBEDTLS_FS_IO
+ *
+ * Enable functions that use the filesystem.
+ */
+#define MBEDTLS_FS_IO
+
+/**
+ * \def MBEDTLS_NO_DEFAULT_ENTROPY_SOURCES
+ *
+ * Do not add default entropy sources. These are the platform specific,
+ * mbedtls_timing_hardclock and HAVEGE based poll functions.
+ *
+ * This is useful to have more control over the added entropy sources in an
+ * application.
+ *
+ * Uncomment this macro to prevent loading of default entropy functions.
+ */
+//#define MBEDTLS_NO_DEFAULT_ENTROPY_SOURCES
+
+/**
+ * \def MBEDTLS_NO_PLATFORM_ENTROPY
+ *
+ * Do not use built-in platform entropy functions.
+ * This is useful if your platform does not support
+ * standards like the /dev/urandom or Windows CryptoAPI.
+ *
+ * Uncomment this macro to disable the built-in platform entropy functions.
+ */
+//#define MBEDTLS_NO_PLATFORM_ENTROPY
+
+/**
+ * \def MBEDTLS_ENTROPY_FORCE_SHA256
+ *
+ * Force the entropy accumulator to use a SHA-256 accumulator instead of the
+ * default SHA-512 based one (if both are available).
+ *
+ * Requires: MBEDTLS_SHA256_C
+ *
+ * On 32-bit systems SHA-256 can be much faster than SHA-512. Use this option
+ * if you have performance concerns.
+ *
+ * This option is only useful if both MBEDTLS_SHA256_C and
+ * MBEDTLS_SHA512_C are defined. Otherwise the available hash module is used.
+ */
+//#define MBEDTLS_ENTROPY_FORCE_SHA256
+
+/**
+ * \def MBEDTLS_ENTROPY_NV_SEED
+ *
+ * Enable the non-volatile (NV) seed file-based entropy source.
+ * (Also enables the NV seed read/write functions in the platform layer)
+ *
+ * This is crucial (if not required) on systems that do not have a
+ * cryptographic entropy source (in hardware or kernel) available.
+ *
+ * Requires: MBEDTLS_ENTROPY_C, MBEDTLS_PLATFORM_C
+ *
+ * \note The read/write functions that are used by the entropy source are
+ * determined in the platform layer, and can be modified at runtime and/or
+ * compile-time depending on the flags (MBEDTLS_PLATFORM_NV_SEED_*) used.
+ *
+ * \note If you use the default implementation functions that read a seedfile
+ * with regular fopen(), please make sure you make a seedfile with the
+ * proper name (defined in MBEDTLS_PLATFORM_STD_NV_SEED_FILE) and at
+ * least MBEDTLS_ENTROPY_BLOCK_SIZE bytes in size that can be read from
+ * and written to or you will get an entropy source error! The default
+ * implementation will only use the first MBEDTLS_ENTROPY_BLOCK_SIZE
+ * bytes from the file.
+ *
+ * \note The entropy collector will write to the seed file before entropy is
+ * given to an external source, to update it.
+ */
+//#define MBEDTLS_ENTROPY_NV_SEED
+
+/**
+ * \def MBEDTLS_MEMORY_DEBUG
+ *
+ * Enable debugging of buffer allocator memory issues. Automatically prints
+ * (to stderr) all (fatal) messages on memory allocation issues. Enables
+ * function for 'debug output' of allocated memory.
+ *
+ * Requires: MBEDTLS_MEMORY_BUFFER_ALLOC_C
+ *
+ * Uncomment this macro to let the buffer allocator print out error messages.
+ */
+//#define MBEDTLS_MEMORY_DEBUG
+
+/**
+ * \def MBEDTLS_MEMORY_BACKTRACE
+ *
+ * Include backtrace information with each allocated block.
+ *
+ * Requires: MBEDTLS_MEMORY_BUFFER_ALLOC_C
+ * GLIBC-compatible backtrace() an backtrace_symbols() support
+ *
+ * Uncomment this macro to include backtrace information
+ */
+//#define MBEDTLS_MEMORY_BACKTRACE
+
+/**
+ * \def MBEDTLS_PK_RSA_ALT_SUPPORT
+ *
+ * Support external private RSA keys (eg from a HSM) in the PK layer.
+ *
+ * Comment this macro to disable support for external private RSA keys.
+ */
+//#define MBEDTLS_PK_RSA_ALT_SUPPORT
+
+/**
+ * \def MBEDTLS_PKCS1_V15
+ *
+ * Enable support for PKCS#1 v1.5 encoding.
+ *
+ * Requires: MBEDTLS_RSA_C
+ *
+ * This enables support for PKCS#1 v1.5 operations.
+ */
+#define MBEDTLS_PKCS1_V15
+
+/**
+ * \def MBEDTLS_PKCS1_V21
+ *
+ * Enable support for PKCS#1 v2.1 encoding.
+ *
+ * Requires: MBEDTLS_MD_C, MBEDTLS_RSA_C
+ *
+ * This enables support for RSAES-OAEP and RSASSA-PSS operations.
+ */
+#define MBEDTLS_PKCS1_V21
+
+/**
+ * \def MBEDTLS_RSA_NO_CRT
+ *
+ * Do not use the Chinese Remainder Theorem
+ * for the RSA private operation.
+ *
+ * Uncomment this macro to disable the use of CRT in RSA.
+ *
+ */
+//#define MBEDTLS_RSA_NO_CRT
+
+/**
+ * \def MBEDTLS_SELF_TEST
+ *
+ * Enable the checkup functions (*_self_test).
+ */
+//#define MBEDTLS_SELF_TEST
+
+/**
+ * \def MBEDTLS_SHA256_SMALLER
+ *
+ * Enable an implementation of SHA-256 that has lower ROM footprint but also
+ * lower performance.
+ *
+ * The default implementation is meant to be a reasonnable compromise between
+ * performance and size. This version optimizes more aggressively for size at
+ * the expense of performance. Eg on Cortex-M4 it reduces the size of
+ * mbedtls_sha256_process() from ~2KB to ~0.5KB for a performance hit of about
+ * 30%.
+ *
+ * Uncomment to enable the smaller implementation of SHA256.
+ */
+//#define MBEDTLS_SHA256_SMALLER
+
+/**
+ * \def MBEDTLS_SSL_ALL_ALERT_MESSAGES
+ *
+ * Enable sending of alert messages in case of encountered errors as per RFC.
+ * If you choose not to send the alert messages, mbed TLS can still communicate
+ * with other servers, only debugging of failures is harder.
+ *
+ * The advantage of not sending alert messages, is that no information is given
+ * about reasons for failures thus preventing adversaries of gaining intel.
+ *
+ * Enable sending of all alert messages
+ */
+#define MBEDTLS_SSL_ALL_ALERT_MESSAGES
+
+/**
+ * \def MBEDTLS_SSL_DEBUG_ALL
+ *
+ * Enable the debug messages in SSL module for all issues.
+ * Debug messages have been disabled in some places to prevent timing
+ * attacks due to (unbalanced) debugging function calls.
+ *
+ * If you need all error reporting you should enable this during debugging,
+ * but remove this for production servers that should log as well.
+ *
+ * Uncomment this macro to report all debug messages on errors introducing
+ * a timing side-channel.
+ *
+ */
+//#define MBEDTLS_SSL_DEBUG_ALL
+
+/** \def MBEDTLS_SSL_ENCRYPT_THEN_MAC
+ *
+ * Enable support for Encrypt-then-MAC, RFC 7366.
+ *
+ * This allows peers that both support it to use a more robust protection for
+ * ciphersuites using CBC, providing deep resistance against timing attacks
+ * on the padding or underlying cipher.
+ *
+ * This only affects CBC ciphersuites, and is useless if none is defined.
+ *
+ * Requires: MBEDTLS_SSL_PROTO_TLS1 or
+ * MBEDTLS_SSL_PROTO_TLS1_1 or
+ * MBEDTLS_SSL_PROTO_TLS1_2
+ *
+ * Comment this macro to disable support for Encrypt-then-MAC
+ */
+#define MBEDTLS_SSL_ENCRYPT_THEN_MAC
+
+/** \def MBEDTLS_SSL_EXTENDED_MASTER_SECRET
+ *
+ * Enable support for Extended Master Secret, aka Session Hash
+ * (draft-ietf-tls-session-hash-02).
+ *
+ * This was introduced as "the proper fix" to the Triple Handshake familiy of
+ * attacks, but it is recommended to always use it (even if you disable
+ * renegotiation), since it actually fixes a more fundamental issue in the
+ * original SSL/TLS design, and has implications beyond Triple Handshake.
+ *
+ * Requires: MBEDTLS_SSL_PROTO_TLS1 or
+ * MBEDTLS_SSL_PROTO_TLS1_1 or
+ * MBEDTLS_SSL_PROTO_TLS1_2
+ *
+ * Comment this macro to disable support for Extended Master Secret.
+ */
+#define MBEDTLS_SSL_EXTENDED_MASTER_SECRET
+
+/**
+ * \def MBEDTLS_SSL_FALLBACK_SCSV
+ *
+ * Enable support for FALLBACK_SCSV (draft-ietf-tls-downgrade-scsv-00).
+ *
+ * For servers, it is recommended to always enable this, unless you support
+ * only one version of TLS, or know for sure that none of your clients
+ * implements a fallback strategy.
+ *
+ * For clients, you only need this if you're using a fallback strategy, which
+ * is not recommended in the first place, unless you absolutely need it to
+ * interoperate with buggy (version-intolerant) servers.
+ *
+ * Comment this macro to disable support for FALLBACK_SCSV
+ */
+#define MBEDTLS_SSL_FALLBACK_SCSV
+
+/**
+ * \def MBEDTLS_SSL_HW_RECORD_ACCEL
+ *
+ * Enable hooking functions in SSL module for hardware acceleration of
+ * individual records.
+ *
+ * Uncomment this macro to enable hooking functions.
+ */
+//#define MBEDTLS_SSL_HW_RECORD_ACCEL
+
+/**
+ * \def MBEDTLS_SSL_CBC_RECORD_SPLITTING
+ *
+ * Enable 1/n-1 record splitting for CBC mode in SSLv3 and TLS 1.0.
+ *
+ * This is a countermeasure to the BEAST attack, which also minimizes the risk
+ * of interoperability issues compared to sending 0-length records.
+ *
+ * Comment this macro to disable 1/n-1 record splitting.
+ */
+//#define MBEDTLS_SSL_CBC_RECORD_SPLITTING
+
+/**
+ * \def MBEDTLS_SSL_RENEGOTIATION
+ *
+ * Disable support for TLS renegotiation.
+ *
+ * The two main uses of renegotiation are (1) refresh keys on long-lived
+ * connections and (2) client authentication after the initial handshake.
+ * If you don't need renegotiation, it's probably better to disable it, since
+ * it has been associated with security issues in the past and is easy to
+ * misuse/misunderstand.
+ *
+ * Comment this to disable support for renegotiation.
+ *
+ * \note Even if this option is disabled, both client and server are aware
+ * of the Renegotiation Indication Extension (RFC 5746) used to
+ * prevent the SSL renegotiation attack (see RFC 5746 Sect. 1).
+ * (See \c mbedtls_ssl_conf_legacy_renegotiation for the
+ * configuration of this extension).
+ *
+ */
+#define MBEDTLS_SSL_RENEGOTIATION
+
+/**
+ * \def MBEDTLS_SSL_SRV_SUPPORT_SSLV2_CLIENT_HELLO
+ *
+ * Enable support for receiving and parsing SSLv2 Client Hello messages for the
+ * SSL Server module (MBEDTLS_SSL_SRV_C).
+ *
+ * Uncomment this macro to enable support for SSLv2 Client Hello messages.
+ */
+//#define MBEDTLS_SSL_SRV_SUPPORT_SSLV2_CLIENT_HELLO
+
+/**
+ * \def MBEDTLS_SSL_SRV_RESPECT_CLIENT_PREFERENCE
+ *
+ * Pick the ciphersuite according to the client's preferences rather than ours
+ * in the SSL Server module (MBEDTLS_SSL_SRV_C).
+ *
+ * Uncomment this macro to respect client's ciphersuite order
+ */
+//#define MBEDTLS_SSL_SRV_RESPECT_CLIENT_PREFERENCE
+
+/**
+ * \def MBEDTLS_SSL_MAX_FRAGMENT_LENGTH
+ *
+ * Enable support for RFC 6066 max_fragment_length extension in SSL.
+ *
+ * Comment this macro to disable support for the max_fragment_length extension
+ */
+#define MBEDTLS_SSL_MAX_FRAGMENT_LENGTH
+
+/**
+ * \def MBEDTLS_SSL_PROTO_SSL3
+ *
+ * Enable support for SSL 3.0.
+ *
+ * Requires: MBEDTLS_MD5_C
+ * MBEDTLS_SHA1_C
+ *
+ * Comment this macro to disable support for SSL 3.0
+ */
+//#define MBEDTLS_SSL_PROTO_SSL3
+
+/**
+ * \def MBEDTLS_SSL_PROTO_TLS1
+ *
+ * Enable support for TLS 1.0.
+ *
+ * Requires: MBEDTLS_MD5_C
+ * MBEDTLS_SHA1_C
+ *
+ * Comment this macro to disable support for TLS 1.0
+ */
+//#define MBEDTLS_SSL_PROTO_TLS1
+
+/**
+ * \def MBEDTLS_SSL_PROTO_TLS1_1
+ *
+ * Enable support for TLS 1.1 (and DTLS 1.0 if DTLS is enabled).
+ *
+ * Requires: MBEDTLS_MD5_C
+ * MBEDTLS_SHA1_C
+ *
+ * Comment this macro to disable support for TLS 1.1 / DTLS 1.0
+ */
+//#define MBEDTLS_SSL_PROTO_TLS1_1
+
+/**
+ * \def MBEDTLS_SSL_PROTO_TLS1_2
+ *
+ * Enable support for TLS 1.2 (and DTLS 1.2 if DTLS is enabled).
+ *
+ * Requires: MBEDTLS_SHA1_C or MBEDTLS_SHA256_C or MBEDTLS_SHA512_C
+ * (Depends on ciphersuites)
+ *
+ * Comment this macro to disable support for TLS 1.2 / DTLS 1.2
+ */
+#define MBEDTLS_SSL_PROTO_TLS1_2
+
+/**
+ * \def MBEDTLS_SSL_PROTO_DTLS
+ *
+ * Enable support for DTLS (all available versions).
+ *
+ * Enable this and MBEDTLS_SSL_PROTO_TLS1_1 to enable DTLS 1.0,
+ * and/or this and MBEDTLS_SSL_PROTO_TLS1_2 to enable DTLS 1.2.
+ *
+ * Requires: MBEDTLS_SSL_PROTO_TLS1_1
+ * or MBEDTLS_SSL_PROTO_TLS1_2
+ *
+ * Comment this macro to disable support for DTLS
+ */
+//#define MBEDTLS_SSL_PROTO_DTLS
+
+/**
+ * \def MBEDTLS_SSL_ALPN
+ *
+ * Enable support for RFC 7301 Application Layer Protocol Negotiation.
+ *
+ * Comment this macro to disable support for ALPN.
+ */
+#define MBEDTLS_SSL_ALPN
+
+/**
+ * \def MBEDTLS_SSL_DTLS_ANTI_REPLAY
+ *
+ * Enable support for the anti-replay mechanism in DTLS.
+ *
+ * Requires: MBEDTLS_SSL_TLS_C
+ * MBEDTLS_SSL_PROTO_DTLS
+ *
+ * \warning Disabling this is often a security risk!
+ * See mbedtls_ssl_conf_dtls_anti_replay() for details.
+ *
+ * Comment this to disable anti-replay in DTLS.
+ */
+//#define MBEDTLS_SSL_DTLS_ANTI_REPLAY
+
+/**
+ * \def MBEDTLS_SSL_DTLS_HELLO_VERIFY
+ *
+ * Enable support for HelloVerifyRequest on DTLS servers.
+ *
+ * This feature is highly recommended to prevent DTLS servers being used as
+ * amplifiers in DoS attacks against other hosts. It should always be enabled
+ * unless you know for sure amplification cannot be a problem in the
+ * environment in which your server operates.
+ *
+ * \warning Disabling this can ba a security risk! (see above)
+ *
+ * Requires: MBEDTLS_SSL_PROTO_DTLS
+ *
+ * Comment this to disable support for HelloVerifyRequest.
+ */
+//#define MBEDTLS_SSL_DTLS_HELLO_VERIFY
+
+/**
+ * \def MBEDTLS_SSL_DTLS_CLIENT_PORT_REUSE
+ *
+ * Enable server-side support for clients that reconnect from the same port.
+ *
+ * Some clients unexpectedly close the connection and try to reconnect using the
+ * same source port. This needs special support from the server to handle the
+ * new connection securely, as described in section 4.2.8 of RFC 6347. This
+ * flag enables that support.
+ *
+ * Requires: MBEDTLS_SSL_DTLS_HELLO_VERIFY
+ *
+ * Comment this to disable support for clients reusing the source port.
+ */
+//#define MBEDTLS_SSL_DTLS_CLIENT_PORT_REUSE
+
+/**
+ * \def MBEDTLS_SSL_DTLS_BADMAC_LIMIT
+ *
+ * Enable support for a limit of records with bad MAC.
+ *
+ * See mbedtls_ssl_conf_dtls_badmac_limit().
+ *
+ * Requires: MBEDTLS_SSL_PROTO_DTLS
+ */
+//#define MBEDTLS_SSL_DTLS_BADMAC_LIMIT
+
+/**
+ * \def MBEDTLS_SSL_SESSION_TICKETS
+ *
+ * Enable support for RFC 5077 session tickets in SSL.
+ * Client-side, provides full support for session tickets (maintainance of a
+ * session store remains the responsibility of the application, though).
+ * Server-side, you also need to provide callbacks for writing and parsing
+ * tickets, including authenticated encryption and key management. Example
+ * callbacks are provided by MBEDTLS_SSL_TICKET_C.
+ *
+ * Comment this macro to disable support for SSL session tickets
+ */
+#define MBEDTLS_SSL_SESSION_TICKETS
+
+/**
+ * \def MBEDTLS_SSL_EXPORT_KEYS
+ *
+ * Enable support for exporting key block and master secret.
+ * This is required for certain users of TLS, e.g. EAP-TLS.
+ *
+ * Comment this macro to disable support for key export
+ */
+#define MBEDTLS_SSL_EXPORT_KEYS
+
+/**
+ * \def MBEDTLS_SSL_SERVER_NAME_INDICATION
+ *
+ * Enable support for RFC 6066 server name indication (SNI) in SSL.
+ *
+ * Requires: MBEDTLS_X509_CRT_PARSE_C
+ *
+ * Comment this macro to disable support for server name indication in SSL
+ */
+#define MBEDTLS_SSL_SERVER_NAME_INDICATION
+
+/**
+ * \def MBEDTLS_SSL_TRUNCATED_HMAC
+ *
+ * Enable support for RFC 6066 truncated HMAC in SSL.
+ *
+ * Comment this macro to disable support for truncated HMAC in SSL
+ */
+#define MBEDTLS_SSL_TRUNCATED_HMAC
+
+/**
+ * \def MBEDTLS_SSL_TRUNCATED_HMAC_COMPAT
+ *
+ * Fallback to old (pre-2.7), non-conforming implementation of the truncated
+ * HMAC extension which also truncates the HMAC key. Note that this option is
+ * only meant for a transitory upgrade period and is likely to be removed in
+ * a future version of the library.
+ *
+ * \warning The old implementation is non-compliant and has a security weakness
+ * (2^80 brute force attack on the HMAC key used for a single,
+ * uninterrupted connection). This should only be enabled temporarily
+ * when (1) the use of truncated HMAC is essential in order to save
+ * bandwidth, and (2) the peer is an Mbed TLS stack that doesn't use
+ * the fixed implementation yet (pre-2.7).
+ *
+ * \deprecated This option is deprecated and will likely be removed in a
+ * future version of Mbed TLS.
+ *
+ * Uncomment to fallback to old, non-compliant truncated HMAC implementation.
+ *
+ * Requires: MBEDTLS_SSL_TRUNCATED_HMAC
+ */
+//#define MBEDTLS_SSL_TRUNCATED_HMAC_COMPAT
+
+/**
+ * \def MBEDTLS_THREADING_ALT
+ *
+ * Provide your own alternate threading implementation.
+ *
+ * Requires: MBEDTLS_THREADING_C
+ *
+ * Uncomment this to allow your own alternate threading implementation.
+ */
+//#define MBEDTLS_THREADING_ALT
+
+/**
+ * \def MBEDTLS_THREADING_PTHREAD
+ *
+ * Enable the pthread wrapper layer for the threading layer.
+ *
+ * Requires: MBEDTLS_THREADING_C
+ *
+ * Uncomment this to enable pthread mutexes.
+ */
+//#define MBEDTLS_THREADING_PTHREAD
+
+/**
+ * \def MBEDTLS_VERSION_FEATURES
+ *
+ * Allow run-time checking of compile-time enabled features. Thus allowing users
+ * to check at run-time if the library is for instance compiled with threading
+ * support via mbedtls_version_check_feature().
+ *
+ * Requires: MBEDTLS_VERSION_C
+ *
+ * Comment this to disable run-time checking and save ROM space
+ */
+#define MBEDTLS_VERSION_FEATURES
+
+/**
+ * \def MBEDTLS_X509_ALLOW_EXTENSIONS_NON_V3
+ *
+ * If set, the X509 parser will not break-off when parsing an X509 certificate
+ * and encountering an extension in a v1 or v2 certificate.
+ *
+ * Uncomment to prevent an error.
+ */
+//#define MBEDTLS_X509_ALLOW_EXTENSIONS_NON_V3
+
+/**
+ * \def MBEDTLS_X509_ALLOW_UNSUPPORTED_CRITICAL_EXTENSION
+ *
+ * If set, the X509 parser will not break-off when parsing an X509 certificate
+ * and encountering an unknown critical extension.
+ *
+ * \warning Depending on your PKI use, enabling this can be a security risk!
+ *
+ * Uncomment to prevent an error.
+ */
+//#define MBEDTLS_X509_ALLOW_UNSUPPORTED_CRITICAL_EXTENSION
+
+/**
+ * \def MBEDTLS_X509_CHECK_KEY_USAGE
+ *
+ * Enable verification of the keyUsage extension (CA and leaf certificates).
+ *
+ * Disabling this avoids problems with mis-issued and/or misused
+ * (intermediate) CA and leaf certificates.
+ *
+ * \warning Depending on your PKI use, disabling this can be a security risk!
+ *
+ * Comment to skip keyUsage checking for both CA and leaf certificates.
+ */
+#define MBEDTLS_X509_CHECK_KEY_USAGE
+
+/**
+ * \def MBEDTLS_X509_CHECK_EXTENDED_KEY_USAGE
+ *
+ * Enable verification of the extendedKeyUsage extension (leaf certificates).
+ *
+ * Disabling this avoids problems with mis-issued and/or misused certificates.
+ *
+ * \warning Depending on your PKI use, disabling this can be a security risk!
+ *
+ * Comment to skip extendedKeyUsage checking for certificates.
+ */
+#define MBEDTLS_X509_CHECK_EXTENDED_KEY_USAGE
+
+/**
+ * \def MBEDTLS_X509_RSASSA_PSS_SUPPORT
+ *
+ * Enable parsing and verification of X.509 certificates, CRLs and CSRS
+ * signed with RSASSA-PSS (aka PKCS#1 v2.1).
+ *
+ * Comment this macro to disallow using RSASSA-PSS in certificates.
+ */
+// #define MBEDTLS_X509_RSASSA_PSS_SUPPORT
+
+/**
+ * \def MBEDTLS_ZLIB_SUPPORT
+ *
+ * If set, the SSL/TLS module uses ZLIB to support compression and
+ * decompression of packet data.
+ *
+ * \warning TLS-level compression MAY REDUCE SECURITY! See for example the
+ * CRIME attack. Before enabling this option, you should examine with care if
+ * CRIME or similar exploits may be a applicable to your use case.
+ *
+ * \note Currently compression can't be used with DTLS.
+ *
+ * \deprecated This feature is deprecated and will be removed
+ * in the next major revision of the library.
+ *
+ * Used in: library/ssl_tls.c
+ * library/ssl_cli.c
+ * library/ssl_srv.c
+ *
+ * This feature requires zlib library and headers to be present.
+ *
+ * Uncomment to enable use of ZLIB
+ */
+//#define MBEDTLS_ZLIB_SUPPORT
+/* \} name SECTION: mbed TLS feature support */
+
+/**
+ * \name SECTION: mbed TLS modules
+ *
+ * This section enables or disables entire modules in mbed TLS
+ * \{
+ */
+
+/**
+ * \def MBEDTLS_AESNI_C
+ *
+ * Enable AES-NI support on x86-64.
+ *
+ * Module: library/aesni.c
+ * Caller: library/aes.c
+ *
+ * Requires: MBEDTLS_HAVE_ASM
+ *
+ * This modules adds support for the AES-NI instructions on x86-64
+ */
+//#define MBEDTLS_AESNI_C
+
+/**
+ * \def MBEDTLS_AES_C
+ *
+ * Enable the AES block cipher.
+ *
+ * Module: library/aes.c
+ * Caller: library/ssl_tls.c
+ * library/pem.c
+ * library/ctr_drbg.c
+ *
+ * This module enables the following ciphersuites (if other requisites are
+ * enabled as well):
+ * MBEDTLS_TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA
+ * MBEDTLS_TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA
+ * MBEDTLS_TLS_ECDH_RSA_WITH_AES_128_CBC_SHA
+ * MBEDTLS_TLS_ECDH_RSA_WITH_AES_256_CBC_SHA
+ * MBEDTLS_TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256
+ * MBEDTLS_TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384
+ * MBEDTLS_TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256
+ * MBEDTLS_TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384
+ * MBEDTLS_TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256
+ * MBEDTLS_TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384
+ * MBEDTLS_TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256
+ * MBEDTLS_TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384
+ * MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384
+ * MBEDTLS_TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384
+ * MBEDTLS_TLS_DHE_RSA_WITH_AES_256_GCM_SHA384
+ * MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384
+ * MBEDTLS_TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384
+ * MBEDTLS_TLS_DHE_RSA_WITH_AES_256_CBC_SHA256
+ * MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA
+ * MBEDTLS_TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA
+ * MBEDTLS_TLS_DHE_RSA_WITH_AES_256_CBC_SHA
+ * MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256
+ * MBEDTLS_TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256
+ * MBEDTLS_TLS_DHE_RSA_WITH_AES_128_GCM_SHA256
+ * MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256
+ * MBEDTLS_TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256
+ * MBEDTLS_TLS_DHE_RSA_WITH_AES_128_CBC_SHA256
+ * MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA
+ * MBEDTLS_TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA
+ * MBEDTLS_TLS_DHE_RSA_WITH_AES_128_CBC_SHA
+ * MBEDTLS_TLS_DHE_PSK_WITH_AES_256_GCM_SHA384
+ * MBEDTLS_TLS_ECDHE_PSK_WITH_AES_256_CBC_SHA384
+ * MBEDTLS_TLS_DHE_PSK_WITH_AES_256_CBC_SHA384
+ * MBEDTLS_TLS_ECDHE_PSK_WITH_AES_256_CBC_SHA
+ * MBEDTLS_TLS_DHE_PSK_WITH_AES_256_CBC_SHA
+ * MBEDTLS_TLS_DHE_PSK_WITH_AES_128_GCM_SHA256
+ * MBEDTLS_TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA256
+ * MBEDTLS_TLS_DHE_PSK_WITH_AES_128_CBC_SHA256
+ * MBEDTLS_TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA
+ * MBEDTLS_TLS_DHE_PSK_WITH_AES_128_CBC_SHA
+ * MBEDTLS_TLS_RSA_WITH_AES_256_GCM_SHA384
+ * MBEDTLS_TLS_RSA_WITH_AES_256_CBC_SHA256
+ * MBEDTLS_TLS_RSA_WITH_AES_256_CBC_SHA
+ * MBEDTLS_TLS_RSA_WITH_AES_128_GCM_SHA256
+ * MBEDTLS_TLS_RSA_WITH_AES_128_CBC_SHA256
+ * MBEDTLS_TLS_RSA_WITH_AES_128_CBC_SHA
+ * MBEDTLS_TLS_RSA_PSK_WITH_AES_256_GCM_SHA384
+ * MBEDTLS_TLS_RSA_PSK_WITH_AES_256_CBC_SHA384
+ * MBEDTLS_TLS_RSA_PSK_WITH_AES_256_CBC_SHA
+ * MBEDTLS_TLS_RSA_PSK_WITH_AES_128_GCM_SHA256
+ * MBEDTLS_TLS_RSA_PSK_WITH_AES_128_CBC_SHA256
+ * MBEDTLS_TLS_RSA_PSK_WITH_AES_128_CBC_SHA
+ * MBEDTLS_TLS_PSK_WITH_AES_256_GCM_SHA384
+ * MBEDTLS_TLS_PSK_WITH_AES_256_CBC_SHA384
+ * MBEDTLS_TLS_PSK_WITH_AES_256_CBC_SHA
+ * MBEDTLS_TLS_PSK_WITH_AES_128_GCM_SHA256
+ * MBEDTLS_TLS_PSK_WITH_AES_128_CBC_SHA256
+ * MBEDTLS_TLS_PSK_WITH_AES_128_CBC_SHA
+ *
+ * PEM_PARSE uses AES for decrypting encrypted keys.
+ */
+#define MBEDTLS_AES_C
+
+/**
+ * \def MBEDTLS_ARC4_C
+ *
+ * Enable the ARCFOUR stream cipher.
+ *
+ * Module: library/arc4.c
+ * Caller: library/ssl_tls.c
+ *
+ * This module enables the following ciphersuites (if other requisites are
+ * enabled as well):
+ * MBEDTLS_TLS_ECDH_ECDSA_WITH_RC4_128_SHA
+ * MBEDTLS_TLS_ECDH_RSA_WITH_RC4_128_SHA
+ * MBEDTLS_TLS_ECDHE_ECDSA_WITH_RC4_128_SHA
+ * MBEDTLS_TLS_ECDHE_RSA_WITH_RC4_128_SHA
+ * MBEDTLS_TLS_ECDHE_PSK_WITH_RC4_128_SHA
+ * MBEDTLS_TLS_DHE_PSK_WITH_RC4_128_SHA
+ * MBEDTLS_TLS_RSA_WITH_RC4_128_SHA
+ * MBEDTLS_TLS_RSA_WITH_RC4_128_MD5
+ * MBEDTLS_TLS_RSA_PSK_WITH_RC4_128_SHA
+ * MBEDTLS_TLS_PSK_WITH_RC4_128_SHA
+ *
+ * \warning ARC4 is considered a weak cipher and its use constitutes a
+ * security risk. If possible, we recommend avoidng dependencies on
+ * it, and considering stronger ciphers instead.
+ *
+ */
+//#define MBEDTLS_ARC4_C
+
+/**
+ * \def MBEDTLS_ASN1_PARSE_C
+ *
+ * Enable the generic ASN1 parser.
+ *
+ * Module: library/asn1.c
+ * Caller: library/x509.c
+ * library/dhm.c
+ * library/pkcs12.c
+ * library/pkcs5.c
+ * library/pkparse.c
+ */
+#define MBEDTLS_ASN1_PARSE_C
+
+/**
+ * \def MBEDTLS_ASN1_WRITE_C
+ *
+ * Enable the generic ASN1 writer.
+ *
+ * Module: library/asn1write.c
+ * Caller: library/ecdsa.c
+ * library/pkwrite.c
+ * library/x509_create.c
+ * library/x509write_crt.c
+ * library/x509write_csr.c
+ */
+#define MBEDTLS_ASN1_WRITE_C
+
+/**
+ * \def MBEDTLS_BASE64_C
+ *
+ * Enable the Base64 module.
+ *
+ * Module: library/base64.c
+ * Caller: library/pem.c
+ *
+ * This module is required for PEM support (required by X.509).
+ */
+#define MBEDTLS_BASE64_C
+
+/**
+ * \def MBEDTLS_BIGNUM_C
+ *
+ * Enable the multi-precision integer library.
+ *
+ * Module: library/bignum.c
+ * Caller: library/dhm.c
+ * library/ecp.c
+ * library/ecdsa.c
+ * library/rsa.c
+ * library/rsa_internal.c
+ * library/ssl_tls.c
+ *
+ * This module is required for RSA, DHM and ECC (ECDH, ECDSA) support.
+ */
+#define MBEDTLS_BIGNUM_C
+
+/**
+ * \def MBEDTLS_BLOWFISH_C
+ *
+ * Enable the Blowfish block cipher.
+ *
+ * Module: library/blowfish.c
+ */
+//#define MBEDTLS_BLOWFISH_C
+
+/**
+ * \def MBEDTLS_CAMELLIA_C
+ *
+ * Enable the Camellia block cipher.
+ *
+ * Module: library/camellia.c
+ * Caller: library/ssl_tls.c
+ *
+ * This module enables the following ciphersuites (if other requisites are
+ * enabled as well):
+ * MBEDTLS_TLS_ECDH_ECDSA_WITH_CAMELLIA_128_CBC_SHA256
+ * MBEDTLS_TLS_ECDH_ECDSA_WITH_CAMELLIA_256_CBC_SHA384
+ * MBEDTLS_TLS_ECDH_RSA_WITH_CAMELLIA_128_CBC_SHA256
+ * MBEDTLS_TLS_ECDH_RSA_WITH_CAMELLIA_256_CBC_SHA384
+ * MBEDTLS_TLS_ECDH_ECDSA_WITH_CAMELLIA_128_GCM_SHA256
+ * MBEDTLS_TLS_ECDH_ECDSA_WITH_CAMELLIA_256_GCM_SHA384
+ * MBEDTLS_TLS_ECDH_RSA_WITH_CAMELLIA_128_GCM_SHA256
+ * MBEDTLS_TLS_ECDH_RSA_WITH_CAMELLIA_256_GCM_SHA384
+ * MBEDTLS_TLS_ECDHE_ECDSA_WITH_CAMELLIA_256_GCM_SHA384
+ * MBEDTLS_TLS_ECDHE_RSA_WITH_CAMELLIA_256_GCM_SHA384
+ * MBEDTLS_TLS_DHE_RSA_WITH_CAMELLIA_256_GCM_SHA384
+ * MBEDTLS_TLS_ECDHE_ECDSA_WITH_CAMELLIA_256_CBC_SHA384
+ * MBEDTLS_TLS_ECDHE_RSA_WITH_CAMELLIA_256_CBC_SHA384
+ * MBEDTLS_TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA256
+ * MBEDTLS_TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA
+ * MBEDTLS_TLS_ECDHE_ECDSA_WITH_CAMELLIA_128_GCM_SHA256
+ * MBEDTLS_TLS_ECDHE_RSA_WITH_CAMELLIA_128_GCM_SHA256
+ * MBEDTLS_TLS_DHE_RSA_WITH_CAMELLIA_128_GCM_SHA256
+ * MBEDTLS_TLS_ECDHE_ECDSA_WITH_CAMELLIA_128_CBC_SHA256
+ * MBEDTLS_TLS_ECDHE_RSA_WITH_CAMELLIA_128_CBC_SHA256
+ * MBEDTLS_TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA256
+ * MBEDTLS_TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA
+ * MBEDTLS_TLS_DHE_PSK_WITH_CAMELLIA_256_GCM_SHA384
+ * MBEDTLS_TLS_ECDHE_PSK_WITH_CAMELLIA_256_CBC_SHA384
+ * MBEDTLS_TLS_DHE_PSK_WITH_CAMELLIA_256_CBC_SHA384
+ * MBEDTLS_TLS_DHE_PSK_WITH_CAMELLIA_128_GCM_SHA256
+ * MBEDTLS_TLS_DHE_PSK_WITH_CAMELLIA_128_CBC_SHA256
+ * MBEDTLS_TLS_ECDHE_PSK_WITH_CAMELLIA_128_CBC_SHA256
+ * MBEDTLS_TLS_RSA_WITH_CAMELLIA_256_GCM_SHA384
+ * MBEDTLS_TLS_RSA_WITH_CAMELLIA_256_CBC_SHA256
+ * MBEDTLS_TLS_RSA_WITH_CAMELLIA_256_CBC_SHA
+ * MBEDTLS_TLS_RSA_WITH_CAMELLIA_128_GCM_SHA256
+ * MBEDTLS_TLS_RSA_WITH_CAMELLIA_128_CBC_SHA256
+ * MBEDTLS_TLS_RSA_WITH_CAMELLIA_128_CBC_SHA
+ * MBEDTLS_TLS_RSA_PSK_WITH_CAMELLIA_256_GCM_SHA384
+ * MBEDTLS_TLS_RSA_PSK_WITH_CAMELLIA_256_CBC_SHA384
+ * MBEDTLS_TLS_RSA_PSK_WITH_CAMELLIA_128_GCM_SHA256
+ * MBEDTLS_TLS_RSA_PSK_WITH_CAMELLIA_128_CBC_SHA256
+ * MBEDTLS_TLS_PSK_WITH_CAMELLIA_256_GCM_SHA384
+ * MBEDTLS_TLS_PSK_WITH_CAMELLIA_256_CBC_SHA384
+ * MBEDTLS_TLS_PSK_WITH_CAMELLIA_128_GCM_SHA256
+ * MBEDTLS_TLS_PSK_WITH_CAMELLIA_128_CBC_SHA256
+ */
+//#define MBEDTLS_CAMELLIA_C
+
+/**
+ * \def MBEDTLS_CCM_C
+ *
+ * Enable the Counter with CBC-MAC (CCM) mode for 128-bit block cipher.
+ *
+ * Module: library/ccm.c
+ *
+ * Requires: MBEDTLS_AES_C or MBEDTLS_CAMELLIA_C
+ *
+ * This module enables the AES-CCM ciphersuites, if other requisites are
+ * enabled as well.
+ */
+//#define MBEDTLS_CCM_C
+
+/**
+ * \def MBEDTLS_CERTS_C
+ *
+ * Enable the test certificates.
+ *
+ * Module: library/certs.c
+ * Caller:
+ *
+ * This module is used for testing (ssl_client/server).
+ */
+#define MBEDTLS_CERTS_C
+
+/**
+ * \def MBEDTLS_CIPHER_C
+ *
+ * Enable the generic cipher layer.
+ *
+ * Module: library/cipher.c
+ * Caller: library/ssl_tls.c
+ *
+ * Uncomment to enable generic cipher wrappers.
+ */
+#define MBEDTLS_CIPHER_C
+
+/**
+ * \def MBEDTLS_CMAC_C
+ *
+ * Enable the CMAC (Cipher-based Message Authentication Code) mode for block
+ * ciphers.
+ *
+ * Module: library/cmac.c
+ *
+ * Requires: MBEDTLS_AES_C or MBEDTLS_DES_C
+ *
+ */
+//#define MBEDTLS_CMAC_C
+
+/**
+ * \def MBEDTLS_CTR_DRBG_C
+ *
+ * Enable the CTR_DRBG AES-256-based random generator.
+ *
+ * Module: library/ctr_drbg.c
+ * Caller:
+ *
+ * Requires: MBEDTLS_AES_C
+ *
+ * This module provides the CTR_DRBG AES-256 random number generator.
+ */
+#define MBEDTLS_CTR_DRBG_C
+
+/**
+ * \def MBEDTLS_DEBUG_C
+ *
+ * Enable the debug functions.
+ *
+ * Module: library/debug.c
+ * Caller: library/ssl_cli.c
+ * library/ssl_srv.c
+ * library/ssl_tls.c
+ *
+ * This module provides debugging functions.
+ */
+//#define MBEDTLS_DEBUG_C
+
+/**
+ * \def MBEDTLS_DES_C
+ *
+ * Enable the DES block cipher.
+ *
+ * Module: library/des.c
+ * Caller: library/pem.c
+ * library/ssl_tls.c
+ *
+ * This module enables the following ciphersuites (if other requisites are
+ * enabled as well):
+ * MBEDTLS_TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA
+ * MBEDTLS_TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA
+ * MBEDTLS_TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA
+ * MBEDTLS_TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA
+ * MBEDTLS_TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA
+ * MBEDTLS_TLS_ECDHE_PSK_WITH_3DES_EDE_CBC_SHA
+ * MBEDTLS_TLS_DHE_PSK_WITH_3DES_EDE_CBC_SHA
+ * MBEDTLS_TLS_RSA_WITH_3DES_EDE_CBC_SHA
+ * MBEDTLS_TLS_RSA_PSK_WITH_3DES_EDE_CBC_SHA
+ * MBEDTLS_TLS_PSK_WITH_3DES_EDE_CBC_SHA
+ *
+ * PEM_PARSE uses DES/3DES for decrypting encrypted keys.
+ *
+ * \warning DES is considered a weak cipher and its use constitutes a
+ * security risk. We recommend considering stronger ciphers instead.
+ */
+//#define MBEDTLS_DES_C
+
+/**
+ * \def MBEDTLS_DHM_C
+ *
+ * Enable the Diffie-Hellman-Merkle module.
+ *
+ * Module: library/dhm.c
+ * Caller: library/ssl_cli.c
+ * library/ssl_srv.c
+ *
+ * This module is used by the following key exchanges:
+ * DHE-RSA, DHE-PSK
+ *
+ * \warning Using DHE constitutes a security risk as it
+ * is not possible to validate custom DH parameters.
+ * If possible, it is recommended users should consider
+ * preferring other methods of key exchange.
+ * See dhm.h for more details.
+ *
+ */
+// #define MBEDTLS_DHM_C
+
+/**
+ * \def MBEDTLS_ECDH_C
+ *
+ * Enable the elliptic curve Diffie-Hellman library.
+ *
+ * Module: library/ecdh.c
+ * Caller: library/ssl_cli.c
+ * library/ssl_srv.c
+ *
+ * This module is used by the following key exchanges:
+ * ECDHE-ECDSA, ECDHE-RSA, DHE-PSK
+ *
+ * Requires: MBEDTLS_ECP_C
+ */
+#define MBEDTLS_ECDH_C
+
+/**
+ * \def MBEDTLS_ECDSA_C
+ *
+ * Enable the elliptic curve DSA library.
+ *
+ * Module: library/ecdsa.c
+ * Caller:
+ *
+ * This module is used by the following key exchanges:
+ * ECDHE-ECDSA
+ *
+ * Requires: MBEDTLS_ECP_C, MBEDTLS_ASN1_WRITE_C, MBEDTLS_ASN1_PARSE_C
+ */
+#define MBEDTLS_ECDSA_C
+
+/**
+ * \def MBEDTLS_ECJPAKE_C
+ *
+ * Enable the elliptic curve J-PAKE library.
+ *
+ * \warning This is currently experimental. EC J-PAKE support is based on the
+ * Thread v1.0.0 specification; incompatible changes to the specification
+ * might still happen. For this reason, this is disabled by default.
+ *
+ * Module: library/ecjpake.c
+ * Caller:
+ *
+ * This module is used by the following key exchanges:
+ * ECJPAKE
+ *
+ * Requires: MBEDTLS_ECP_C, MBEDTLS_MD_C
+ */
+//#define MBEDTLS_ECJPAKE_C
+
+/**
+ * \def MBEDTLS_ECP_C
+ *
+ * Enable the elliptic curve over GF(p) library.
+ *
+ * Module: library/ecp.c
+ * Caller: library/ecdh.c
+ * library/ecdsa.c
+ * library/ecjpake.c
+ *
+ * Requires: MBEDTLS_BIGNUM_C and at least one MBEDTLS_ECP_DP_XXX_ENABLED
+ */
+#define MBEDTLS_ECP_C
+
+/**
+ * \def MBEDTLS_ENTROPY_C
+ *
+ * Enable the platform-specific entropy code.
+ *
+ * Module: library/entropy.c
+ * Caller:
+ *
+ * Requires: MBEDTLS_SHA512_C or MBEDTLS_SHA256_C
+ *
+ * This module provides a generic entropy pool
+ */
+#define MBEDTLS_ENTROPY_C
+
+/**
+ * \def MBEDTLS_ERROR_C
+ *
+ * Enable error code to error string conversion.
+ *
+ * Module: library/error.c
+ * Caller:
+ *
+ * This module enables mbedtls_strerror().
+ */
+#define MBEDTLS_ERROR_C
+
+/**
+ * \def MBEDTLS_GCM_C
+ *
+ * Enable the Galois/Counter Mode (GCM) for AES.
+ *
+ * Module: library/gcm.c
+ *
+ * Requires: MBEDTLS_AES_C or MBEDTLS_CAMELLIA_C
+ *
+ * This module enables the AES-GCM and CAMELLIA-GCM ciphersuites, if other
+ * requisites are enabled as well.
+ */
+#define MBEDTLS_GCM_C
+
+/**
+ * \def MBEDTLS_HAVEGE_C
+ *
+ * Enable the HAVEGE random generator.
+ *
+ * Warning: the HAVEGE random generator is not suitable for virtualized
+ * environments
+ *
+ * Warning: the HAVEGE random generator is dependent on timing and specific
+ * processor traits. It is therefore not advised to use HAVEGE as
+ * your applications primary random generator or primary entropy pool
+ * input. As a secondary input to your entropy pool, it IS able add
+ * the (limited) extra entropy it provides.
+ *
+ * Module: library/havege.c
+ * Caller:
+ *
+ * Requires: MBEDTLS_TIMING_C
+ *
+ * Uncomment to enable the HAVEGE random generator.
+ */
+//#define MBEDTLS_HAVEGE_C
+
+/**
+ * \def MBEDTLS_HMAC_DRBG_C
+ *
+ * Enable the HMAC_DRBG random generator.
+ *
+ * Module: library/hmac_drbg.c
+ * Caller:
+ *
+ * Requires: MBEDTLS_MD_C
+ *
+ * Uncomment to enable the HMAC_DRBG random number geerator.
+ */
+#define MBEDTLS_HMAC_DRBG_C
+
+/**
+ * \def MBEDTLS_MD_C
+ *
+ * Enable the generic message digest layer.
+ *
+ * Module: library/md.c
+ * Caller:
+ *
+ * Uncomment to enable generic message digest wrappers.
+ */
+#define MBEDTLS_MD_C
+
+/**
+ * \def MBEDTLS_MD2_C
+ *
+ * Enable the MD2 hash algorithm.
+ *
+ * Module: library/md2.c
+ * Caller:
+ *
+ * Uncomment to enable support for (rare) MD2-signed X.509 certs.
+ *
+ * \warning MD2 is considered a weak message digest and its use constitutes a
+ * security risk. If possible, we recommend avoiding dependencies on
+ * it, and considering stronger message digests instead.
+ *
+ */
+//#define MBEDTLS_MD2_C
+
+/**
+ * \def MBEDTLS_MD4_C
+ *
+ * Enable the MD4 hash algorithm.
+ *
+ * Module: library/md4.c
+ * Caller:
+ *
+ * Uncomment to enable support for (rare) MD4-signed X.509 certs.
+ *
+ * \warning MD4 is considered a weak message digest and its use constitutes a
+ * security risk. If possible, we recommend avoiding dependencies on
+ * it, and considering stronger message digests instead.
+ *
+ */
+//#define MBEDTLS_MD4_C
+
+/**
+ * \def MBEDTLS_MD5_C
+ *
+ * Enable the MD5 hash algorithm.
+ *
+ * Module: library/md5.c
+ * Caller: library/md.c
+ * library/pem.c
+ * library/ssl_tls.c
+ *
+ * This module is required for SSL/TLS up to version 1.1, and for TLS 1.2
+ * depending on the handshake parameters. Further, it is used for checking
+ * MD5-signed certificates, and for PBKDF1 when decrypting PEM-encoded
+ * encrypted keys.
+ *
+ * \warning MD5 is considered a weak message digest and its use constitutes a
+ * security risk. If possible, we recommend avoiding dependencies on
+ * it, and considering stronger message digests instead.
+ *
+ */
+//#define MBEDTLS_MD5_C
+
+/**
+ * \def MBEDTLS_MEMORY_BUFFER_ALLOC_C
+ *
+ * Enable the buffer allocator implementation that makes use of a (stack)
+ * based buffer to 'allocate' dynamic memory. (replaces calloc() and free()
+ * calls)
+ *
+ * Module: library/memory_buffer_alloc.c
+ *
+ * Requires: MBEDTLS_PLATFORM_C
+ * MBEDTLS_PLATFORM_MEMORY (to use it within mbed TLS)
+ *
+ * Enable this module to enable the buffer memory allocator.
+ */
+//#define MBEDTLS_MEMORY_BUFFER_ALLOC_C
+
+/**
+ * \def MBEDTLS_NET_C
+ *
+ * Enable the TCP and UDP over IPv6/IPv4 networking routines.
+ *
+ * \note This module only works on POSIX/Unix (including Linux, BSD and OS X)
+ * and Windows. For other platforms, you'll want to disable it, and write your
+ * own networking callbacks to be passed to \c mbedtls_ssl_set_bio().
+ *
+ * \note See also our Knowledge Base article about porting to a new
+ * environment:
+ * https://tls.mbed.org/kb/how-to/how-do-i-port-mbed-tls-to-a-new-environment-OS
+ *
+ * Module: library/net_sockets.c
+ *
+ * This module provides networking routines.
+ */
+#define MBEDTLS_NET_C
+
+/**
+ * \def MBEDTLS_OID_C
+ *
+ * Enable the OID database.
+ *
+ * Module: library/oid.c
+ * Caller: library/asn1write.c
+ * library/pkcs5.c
+ * library/pkparse.c
+ * library/pkwrite.c
+ * library/rsa.c
+ * library/x509.c
+ * library/x509_create.c
+ * library/x509_crl.c
+ * library/x509_crt.c
+ * library/x509_csr.c
+ * library/x509write_crt.c
+ * library/x509write_csr.c
+ *
+ * This modules translates between OIDs and internal values.
+ */
+#define MBEDTLS_OID_C
+
+/**
+ * \def MBEDTLS_PADLOCK_C
+ *
+ * Enable VIA Padlock support on x86.
+ *
+ * Module: library/padlock.c
+ * Caller: library/aes.c
+ *
+ * Requires: MBEDTLS_HAVE_ASM
+ *
+ * This modules adds support for the VIA PadLock on x86.
+ */
+//#define MBEDTLS_PADLOCK_C
+
+/**
+ * \def MBEDTLS_PEM_PARSE_C
+ *
+ * Enable PEM decoding / parsing.
+ *
+ * Module: library/pem.c
+ * Caller: library/dhm.c
+ * library/pkparse.c
+ * library/x509_crl.c
+ * library/x509_crt.c
+ * library/x509_csr.c
+ *
+ * Requires: MBEDTLS_BASE64_C
+ *
+ * This modules adds support for decoding / parsing PEM files.
+ */
+#define MBEDTLS_PEM_PARSE_C
+
+/**
+ * \def MBEDTLS_PEM_WRITE_C
+ *
+ * Enable PEM encoding / writing.
+ *
+ * Module: library/pem.c
+ * Caller: library/pkwrite.c
+ * library/x509write_crt.c
+ * library/x509write_csr.c
+ *
+ * Requires: MBEDTLS_BASE64_C
+ *
+ * This modules adds support for encoding / writing PEM files.
+ */
+#define MBEDTLS_PEM_WRITE_C
+
+/**
+ * \def MBEDTLS_PK_C
+ *
+ * Enable the generic public (asymetric) key layer.
+ *
+ * Module: library/pk.c
+ * Caller: library/ssl_tls.c
+ * library/ssl_cli.c
+ * library/ssl_srv.c
+ *
+ * Requires: MBEDTLS_RSA_C or MBEDTLS_ECP_C
+ *
+ * Uncomment to enable generic public key wrappers.
+ */
+#define MBEDTLS_PK_C
+
+/**
+ * \def MBEDTLS_PK_PARSE_C
+ *
+ * Enable the generic public (asymetric) key parser.
+ *
+ * Module: library/pkparse.c
+ * Caller: library/x509_crt.c
+ * library/x509_csr.c
+ *
+ * Requires: MBEDTLS_PK_C
+ *
+ * Uncomment to enable generic public key parse functions.
+ */
+#define MBEDTLS_PK_PARSE_C
+
+/**
+ * \def MBEDTLS_PK_WRITE_C
+ *
+ * Enable the generic public (asymetric) key writer.
+ *
+ * Module: library/pkwrite.c
+ * Caller: library/x509write.c
+ *
+ * Requires: MBEDTLS_PK_C
+ *
+ * Uncomment to enable generic public key write functions.
+ */
+#define MBEDTLS_PK_WRITE_C
+
+/**
+ * \def MBEDTLS_PKCS5_C
+ *
+ * Enable PKCS#5 functions.
+ *
+ * Module: library/pkcs5.c
+ *
+ * Requires: MBEDTLS_MD_C
+ *
+ * This module adds support for the PKCS#5 functions.
+ */
+#define MBEDTLS_PKCS5_C
+
+/**
+ * \def MBEDTLS_PKCS11_C
+ *
+ * Enable wrapper for PKCS#11 smartcard support.
+ *
+ * Module: library/pkcs11.c
+ * Caller: library/pk.c
+ *
+ * Requires: MBEDTLS_PK_C
+ *
+ * This module enables SSL/TLS PKCS #11 smartcard support.
+ * Requires the presence of the PKCS#11 helper library (libpkcs11-helper)
+ */
+//#define MBEDTLS_PKCS11_C
+
+/**
+ * \def MBEDTLS_PKCS12_C
+ *
+ * Enable PKCS#12 PBE functions.
+ * Adds algorithms for parsing PKCS#8 encrypted private keys
+ *
+ * Module: library/pkcs12.c
+ * Caller: library/pkparse.c
+ *
+ * Requires: MBEDTLS_ASN1_PARSE_C, MBEDTLS_CIPHER_C, MBEDTLS_MD_C
+ * Can use: MBEDTLS_ARC4_C
+ *
+ * This module enables PKCS#12 functions.
+ */
+#define MBEDTLS_PKCS12_C
+
+/**
+ * \def MBEDTLS_PLATFORM_C
+ *
+ * Enable the platform abstraction layer that allows you to re-assign
+ * functions like calloc(), free(), snprintf(), printf(), fprintf(), exit().
+ *
+ * Enabling MBEDTLS_PLATFORM_C enables to use of MBEDTLS_PLATFORM_XXX_ALT
+ * or MBEDTLS_PLATFORM_XXX_MACRO directives, allowing the functions mentioned
+ * above to be specified at runtime or compile time respectively.
+ *
+ * \note This abstraction layer must be enabled on Windows (including MSYS2)
+ * as other module rely on it for a fixed snprintf implementation.
+ *
+ * Module: library/platform.c
+ * Caller: Most other .c files
+ *
+ * This module enables abstraction of common (libc) functions.
+ */
+#define MBEDTLS_PLATFORM_C
+
+/**
+ * \def MBEDTLS_RIPEMD160_C
+ *
+ * Enable the RIPEMD-160 hash algorithm.
+ *
+ * Module: library/ripemd160.c
+ * Caller: library/md.c
+ *
+ */
+//#define MBEDTLS_RIPEMD160_C
+
+/**
+ * \def MBEDTLS_RSA_C
+ *
+ * Enable the RSA public-key cryptosystem.
+ *
+ * Module: library/rsa.c
+ * library/rsa_internal.c
+ * Caller: library/ssl_cli.c
+ * library/ssl_srv.c
+ * library/ssl_tls.c
+ * library/x509.c
+ *
+ * This module is used by the following key exchanges:
+ * RSA, DHE-RSA, ECDHE-RSA, RSA-PSK
+ *
+ * Requires: MBEDTLS_BIGNUM_C, MBEDTLS_OID_C
+ */
+//#define MBEDTLS_RSA_C
+
+/**
+ * \def MBEDTLS_SHA1_C
+ *
+ * Enable the SHA1 cryptographic hash algorithm.
+ *
+ * Module: library/sha1.c
+ * Caller: library/md.c
+ * library/ssl_cli.c
+ * library/ssl_srv.c
+ * library/ssl_tls.c
+ * library/x509write_crt.c
+ *
+ * This module is required for SSL/TLS up to version 1.1, for TLS 1.2
+ * depending on the handshake parameters, and for SHA1-signed certificates.
+ *
+ * \warning SHA-1 is considered a weak message digest and its use constitutes
+ * a security risk. If possible, we recommend avoiding dependencies
+ * on it, and considering stronger message digests instead.
+ *
+ */
+//#define MBEDTLS_SHA1_C
+
+/**
+ * \def MBEDTLS_SHA256_C
+ *
+ * Enable the SHA-224 and SHA-256 cryptographic hash algorithms.
+ *
+ * Module: library/sha256.c
+ * Caller: library/entropy.c
+ * library/md.c
+ * library/ssl_cli.c
+ * library/ssl_srv.c
+ * library/ssl_tls.c
+ *
+ * This module adds support for SHA-224 and SHA-256.
+ * This module is required for the SSL/TLS 1.2 PRF function.
+ */
+#define MBEDTLS_SHA256_C
+
+/**
+ * \def MBEDTLS_SHA512_C
+ *
+ * Enable the SHA-384 and SHA-512 cryptographic hash algorithms.
+ *
+ * Module: library/sha512.c
+ * Caller: library/entropy.c
+ * library/md.c
+ * library/ssl_cli.c
+ * library/ssl_srv.c
+ *
+ * This module adds support for SHA-384 and SHA-512.
+ */
+#define MBEDTLS_SHA512_C
+
+/**
+ * \def MBEDTLS_SSL_CACHE_C
+ *
+ * Enable simple SSL cache implementation.
+ *
+ * Module: library/ssl_cache.c
+ * Caller:
+ *
+ * Requires: MBEDTLS_SSL_CACHE_C
+ */
+#define MBEDTLS_SSL_CACHE_C
+
+/**
+ * \def MBEDTLS_SSL_COOKIE_C
+ *
+ * Enable basic implementation of DTLS cookies for hello verification.
+ *
+ * Module: library/ssl_cookie.c
+ * Caller:
+ */
+#define MBEDTLS_SSL_COOKIE_C
+
+/**
+ * \def MBEDTLS_SSL_TICKET_C
+ *
+ * Enable an implementation of TLS server-side callbacks for session tickets.
+ *
+ * Module: library/ssl_ticket.c
+ * Caller:
+ *
+ * Requires: MBEDTLS_CIPHER_C
+ */
+#define MBEDTLS_SSL_TICKET_C
+
+/**
+ * \def MBEDTLS_SSL_CLI_C
+ *
+ * Enable the SSL/TLS client code.
+ *
+ * Module: library/ssl_cli.c
+ * Caller:
+ *
+ * Requires: MBEDTLS_SSL_TLS_C
+ *
+ * This module is required for SSL/TLS client support.
+ */
+#define MBEDTLS_SSL_CLI_C
+
+/**
+ * \def MBEDTLS_SSL_SRV_C
+ *
+ * Enable the SSL/TLS server code.
+ *
+ * Module: library/ssl_srv.c
+ * Caller:
+ *
+ * Requires: MBEDTLS_SSL_TLS_C
+ *
+ * This module is required for SSL/TLS server support.
+ */
+//#define MBEDTLS_SSL_SRV_C
+
+/**
+ * \def MBEDTLS_SSL_TLS_C
+ *
+ * Enable the generic SSL/TLS code.
+ *
+ * Module: library/ssl_tls.c
+ * Caller: library/ssl_cli.c
+ * library/ssl_srv.c
+ *
+ * Requires: MBEDTLS_CIPHER_C, MBEDTLS_MD_C
+ * and at least one of the MBEDTLS_SSL_PROTO_XXX defines
+ *
+ * This module is required for SSL/TLS.
+ */
+#define MBEDTLS_SSL_TLS_C
+
+/**
+ * \def MBEDTLS_THREADING_C
+ *
+ * Enable the threading abstraction layer.
+ * By default mbed TLS assumes it is used in a non-threaded environment or that
+ * contexts are not shared between threads. If you do intend to use contexts
+ * between threads, you will need to enable this layer to prevent race
+ * conditions. See also our Knowledge Base article about threading:
+ * https://tls.mbed.org/kb/development/thread-safety-and-multi-threading
+ *
+ * Module: library/threading.c
+ *
+ * This allows different threading implementations (self-implemented or
+ * provided).
+ *
+ * You will have to enable either MBEDTLS_THREADING_ALT or
+ * MBEDTLS_THREADING_PTHREAD.
+ *
+ * Enable this layer to allow use of mutexes within mbed TLS
+ */
+//#define MBEDTLS_THREADING_C
+
+/**
+ * \def MBEDTLS_TIMING_C
+ *
+ * Enable the semi-portable timing interface.
+ *
+ * \note The provided implementation only works on POSIX/Unix (including Linux,
+ * BSD and OS X) and Windows. On other platforms, you can either disable that
+ * module and provide your own implementations of the callbacks needed by
+ * \c mbedtls_ssl_set_timer_cb() for DTLS, or leave it enabled and provide
+ * your own implementation of the whole module by setting
+ * \c MBEDTLS_TIMING_ALT in the current file.
+ *
+ * \note See also our Knowledge Base article about porting to a new
+ * environment:
+ * https://tls.mbed.org/kb/how-to/how-do-i-port-mbed-tls-to-a-new-environment-OS
+ *
+ * Module: library/timing.c
+ * Caller: library/havege.c
+ *
+ * This module is used by the HAVEGE random number generator.
+ */
+#define MBEDTLS_TIMING_C
+
+/**
+ * \def MBEDTLS_VERSION_C
+ *
+ * Enable run-time version information.
+ *
+ * Module: library/version.c
+ *
+ * This module provides run-time version information.
+ */
+#define MBEDTLS_VERSION_C
+
+/**
+ * \def MBEDTLS_X509_USE_C
+ *
+ * Enable X.509 core for using certificates.
+ *
+ * Module: library/x509.c
+ * Caller: library/x509_crl.c
+ * library/x509_crt.c
+ * library/x509_csr.c
+ *
+ * Requires: MBEDTLS_ASN1_PARSE_C, MBEDTLS_BIGNUM_C, MBEDTLS_OID_C,
+ * MBEDTLS_PK_PARSE_C
+ *
+ * This module is required for the X.509 parsing modules.
+ */
+#define MBEDTLS_X509_USE_C
+
+/**
+ * \def MBEDTLS_X509_CRT_PARSE_C
+ *
+ * Enable X.509 certificate parsing.
+ *
+ * Module: library/x509_crt.c
+ * Caller: library/ssl_cli.c
+ * library/ssl_srv.c
+ * library/ssl_tls.c
+ *
+ * Requires: MBEDTLS_X509_USE_C
+ *
+ * This module is required for X.509 certificate parsing.
+ */
+#define MBEDTLS_X509_CRT_PARSE_C
+
+/**
+ * \def MBEDTLS_X509_CRL_PARSE_C
+ *
+ * Enable X.509 CRL parsing.
+ *
+ * Module: library/x509_crl.c
+ * Caller: library/x509_crt.c
+ *
+ * Requires: MBEDTLS_X509_USE_C
+ *
+ * This module is required for X.509 CRL parsing.
+ */
+#define MBEDTLS_X509_CRL_PARSE_C
+
+/**
+ * \def MBEDTLS_X509_CSR_PARSE_C
+ *
+ * Enable X.509 Certificate Signing Request (CSR) parsing.
+ *
+ * Module: library/x509_csr.c
+ * Caller: library/x509_crt_write.c
+ *
+ * Requires: MBEDTLS_X509_USE_C
+ *
+ * This module is used for reading X.509 certificate request.
+ */
+#define MBEDTLS_X509_CSR_PARSE_C
+
+/**
+ * \def MBEDTLS_X509_CREATE_C
+ *
+ * Enable X.509 core for creating certificates.
+ *
+ * Module: library/x509_create.c
+ *
+ * Requires: MBEDTLS_BIGNUM_C, MBEDTLS_OID_C, MBEDTLS_PK_WRITE_C
+ *
+ * This module is the basis for creating X.509 certificates and CSRs.
+ */
+//#define MBEDTLS_X509_CREATE_C
+
+/**
+ * \def MBEDTLS_X509_CRT_WRITE_C
+ *
+ * Enable creating X.509 certificates.
+ *
+ * Module: library/x509_crt_write.c
+ *
+ * Requires: MBEDTLS_X509_CREATE_C
+ *
+ * This module is required for X.509 certificate creation.
+ */
+//#define MBEDTLS_X509_CRT_WRITE_C
+
+/**
+ * \def MBEDTLS_X509_CSR_WRITE_C
+ *
+ * Enable creating X.509 Certificate Signing Requests (CSR).
+ *
+ * Module: library/x509_csr_write.c
+ *
+ * Requires: MBEDTLS_X509_CREATE_C
+ *
+ * This module is required for X.509 certificate request writing.
+ */
+//#define MBEDTLS_X509_CSR_WRITE_C
+
+/**
+ * \def MBEDTLS_XTEA_C
+ *
+ * Enable the XTEA block cipher.
+ *
+ * Module: library/xtea.c
+ * Caller:
+ */
+//#define MBEDTLS_XTEA_C
+
+/* \} name SECTION: mbed TLS modules */
+
+/**
+ * \name SECTION: Module configuration options
+ *
+ * This section allows for the setting of module specific sizes and
+ * configuration options. The default values are already present in the
+ * relevant header files and should suffice for the regular use cases.
+ *
+ * Our advice is to enable options and change their values here
+ * only if you have a good reason and know the consequences.
+ *
+ * Please check the respective header file for documentation on these
+ * parameters (to prevent duplicate documentation).
+ * \{
+ */
+
+/* MPI / BIGNUM options */
+//#define MBEDTLS_MPI_WINDOW_SIZE 6 /**< Maximum windows size used. */
+//#define MBEDTLS_MPI_MAX_SIZE 1024 /**< Maximum number of bytes for usable MPIs. */
+
+/* CTR_DRBG options */
+//#define MBEDTLS_CTR_DRBG_ENTROPY_LEN 48 /**< Amount of entropy used per seed by default (48 with SHA-512, 32 with SHA-256) */
+//#define MBEDTLS_CTR_DRBG_RESEED_INTERVAL 10000 /**< Interval before reseed is performed by default */
+//#define MBEDTLS_CTR_DRBG_MAX_INPUT 256 /**< Maximum number of additional input bytes */
+//#define MBEDTLS_CTR_DRBG_MAX_REQUEST 1024 /**< Maximum number of requested bytes per call */
+//#define MBEDTLS_CTR_DRBG_MAX_SEED_INPUT 384 /**< Maximum size of (re)seed buffer */
+
+/* HMAC_DRBG options */
+//#define MBEDTLS_HMAC_DRBG_RESEED_INTERVAL 10000 /**< Interval before reseed is performed by default */
+//#define MBEDTLS_HMAC_DRBG_MAX_INPUT 256 /**< Maximum number of additional input bytes */
+//#define MBEDTLS_HMAC_DRBG_MAX_REQUEST 1024 /**< Maximum number of requested bytes per call */
+//#define MBEDTLS_HMAC_DRBG_MAX_SEED_INPUT 384 /**< Maximum size of (re)seed buffer */
+
+/* ECP options */
+//#define MBEDTLS_ECP_MAX_BITS 521 /**< Maximum bit size of groups */
+//#define MBEDTLS_ECP_WINDOW_SIZE 6 /**< Maximum window size used */
+//#define MBEDTLS_ECP_FIXED_POINT_OPTIM 1 /**< Enable fixed-point speed-up */
+
+/* Entropy options */
+//#define MBEDTLS_ENTROPY_MAX_SOURCES 20 /**< Maximum number of sources supported */
+//#define MBEDTLS_ENTROPY_MAX_GATHER 128 /**< Maximum amount requested from entropy sources */
+//#define MBEDTLS_ENTROPY_MIN_HARDWARE 32 /**< Default minimum number of bytes required for the hardware entropy source mbedtls_hardware_poll() before entropy is released */
+
+/* Memory buffer allocator options */
+//#define MBEDTLS_MEMORY_ALIGN_MULTIPLE 4 /**< Align on multiples of this value */
+
+/* Platform options */
+//#define MBEDTLS_PLATFORM_STD_MEM_HDR /**< Header to include if MBEDTLS_PLATFORM_NO_STD_FUNCTIONS is defined. Don't define if no header is needed. */
+//#define MBEDTLS_PLATFORM_STD_CALLOC calloc /**< Default allocator to use, can be undefined */
+//#define MBEDTLS_PLATFORM_STD_FREE free /**< Default free to use, can be undefined */
+//#define MBEDTLS_PLATFORM_STD_EXIT exit /**< Default exit to use, can be undefined */
+//#define MBEDTLS_PLATFORM_STD_TIME time /**< Default time to use, can be undefined. MBEDTLS_HAVE_TIME must be enabled */
+//#define MBEDTLS_PLATFORM_STD_FPRINTF fprintf /**< Default fprintf to use, can be undefined */
+//#define MBEDTLS_PLATFORM_STD_PRINTF printf /**< Default printf to use, can be undefined */
+/* Note: your snprintf must correclty zero-terminate the buffer! */
+//#define MBEDTLS_PLATFORM_STD_SNPRINTF snprintf /**< Default snprintf to use, can be undefined */
+//#define MBEDTLS_PLATFORM_STD_EXIT_SUCCESS 0 /**< Default exit value to use, can be undefined */
+//#define MBEDTLS_PLATFORM_STD_EXIT_FAILURE 1 /**< Default exit value to use, can be undefined */
+//#define MBEDTLS_PLATFORM_STD_NV_SEED_READ mbedtls_platform_std_nv_seed_read /**< Default nv_seed_read function to use, can be undefined */
+//#define MBEDTLS_PLATFORM_STD_NV_SEED_WRITE mbedtls_platform_std_nv_seed_write /**< Default nv_seed_write function to use, can be undefined */
+//#define MBEDTLS_PLATFORM_STD_NV_SEED_FILE "seedfile" /**< Seed file to read/write with default implementation */
+
+/* To Use Function Macros MBEDTLS_PLATFORM_C must be enabled */
+/* MBEDTLS_PLATFORM_XXX_MACRO and MBEDTLS_PLATFORM_XXX_ALT cannot both be defined */
+//#define MBEDTLS_PLATFORM_CALLOC_MACRO calloc /**< Default allocator macro to use, can be undefined */
+//#define MBEDTLS_PLATFORM_FREE_MACRO free /**< Default free macro to use, can be undefined */
+//#define MBEDTLS_PLATFORM_EXIT_MACRO exit /**< Default exit macro to use, can be undefined */
+//#define MBEDTLS_PLATFORM_TIME_MACRO time /**< Default time macro to use, can be undefined. MBEDTLS_HAVE_TIME must be enabled */
+//#define MBEDTLS_PLATFORM_TIME_TYPE_MACRO time_t /**< Default time macro to use, can be undefined. MBEDTLS_HAVE_TIME must be enabled */
+//#define MBEDTLS_PLATFORM_FPRINTF_MACRO fprintf /**< Default fprintf macro to use, can be undefined */
+//#define MBEDTLS_PLATFORM_PRINTF_MACRO printf /**< Default printf macro to use, can be undefined */
+/* Note: your snprintf must correclty zero-terminate the buffer! */
+//#define MBEDTLS_PLATFORM_SNPRINTF_MACRO snprintf /**< Default snprintf macro to use, can be undefined */
+//#define MBEDTLS_PLATFORM_NV_SEED_READ_MACRO mbedtls_platform_std_nv_seed_read /**< Default nv_seed_read function to use, can be undefined */
+//#define MBEDTLS_PLATFORM_NV_SEED_WRITE_MACRO mbedtls_platform_std_nv_seed_write /**< Default nv_seed_write function to use, can be undefined */
+
+/* SSL Cache options */
+//#define MBEDTLS_SSL_CACHE_DEFAULT_TIMEOUT 86400 /**< 1 day */
+//#define MBEDTLS_SSL_CACHE_DEFAULT_MAX_ENTRIES 50 /**< Maximum entries in cache */
+
+/* SSL options */
+//#define MBEDTLS_SSL_MAX_CONTENT_LEN 16384 /**< Maxium fragment length in bytes, determines the size of each of the two internal I/O buffers */
+//#define MBEDTLS_SSL_DEFAULT_TICKET_LIFETIME 86400 /**< Lifetime of session tickets (if enabled) */
+//#define MBEDTLS_PSK_MAX_LEN 32 /**< Max size of TLS pre-shared keys, in bytes (default 256 bits) */
+//#define MBEDTLS_SSL_COOKIE_TIMEOUT 60 /**< Default expiration delay of DTLS cookies, in seconds if HAVE_TIME, or in number of cookies issued */
+
+/**
+ * Complete list of ciphersuites to use, in order of preference.
+ *
+ * \warning No dependency checking is done on that field! This option can only
+ * be used to restrict the set of available ciphersuites. It is your
+ * responsibility to make sure the needed modules are active.
+ *
+ * Use this to save a few hundred bytes of ROM (default ordering of all
+ * available ciphersuites) and a few to a few hundred bytes of RAM.
+ *
+ * The value below is only an example, not the default.
+ */
+//#define MBEDTLS_SSL_CIPHERSUITES MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256
+
+/* X509 options */
+//#define MBEDTLS_X509_MAX_INTERMEDIATE_CA 8 /**< Maximum number of intermediate CAs in a verification chain. */
+//#define MBEDTLS_X509_MAX_FILE_PATH_LEN 512 /**< Maximum length of a path/filename string in bytes including the null terminator character ('\0'). */
+
+/**
+ * Allow SHA-1 in the default TLS configuration for certificate signing.
+ * Without this build-time option, SHA-1 support must be activated explicitly
+ * through mbedtls_ssl_conf_cert_profile. Turning on this option is not
+ * recommended because of it is possible to generate SHA-1 collisions, however
+ * this may be safe for legacy infrastructure where additional controls apply.
+ *
+ * \warning SHA-1 is considered a weak message digest and its use constitutes
+ * a security risk. If possible, we recommend avoiding dependencies
+ * on it, and considering stronger message digests instead.
+ *
+ */
+// #define MBEDTLS_TLS_DEFAULT_ALLOW_SHA1_IN_CERTIFICATES
+
+/**
+ * Allow SHA-1 in the default TLS configuration for TLS 1.2 handshake
+ * signature and ciphersuite selection. Without this build-time option, SHA-1
+ * support must be activated explicitly through mbedtls_ssl_conf_sig_hashes.
+ * The use of SHA-1 in TLS <= 1.1 and in HMAC-SHA-1 is always allowed by
+ * default. At the time of writing, there is no practical attack on the use
+ * of SHA-1 in handshake signatures, hence this option is turned on by default
+ * to preserve compatibility with existing peers, but the general
+ * warning applies nonetheless:
+ *
+ * \warning SHA-1 is considered a weak message digest and its use constitutes
+ * a security risk. If possible, we recommend avoiding dependencies
+ * on it, and considering stronger message digests instead.
+ *
+ */
+//#define MBEDTLS_TLS_DEFAULT_ALLOW_SHA1_IN_KEY_EXCHANGE
+
+/* \} name SECTION: Customisation configuration options */
+
+/* Target and application specific configurations */
+//#define YOTTA_CFG_MBEDTLS_TARGET_CONFIG_FILE "mbedtls/target_config.h"
+
+#if defined(TARGET_LIKE_MBED) && defined(YOTTA_CFG_MBEDTLS_TARGET_CONFIG_FILE)
+#include YOTTA_CFG_MBEDTLS_TARGET_CONFIG_FILE
+#endif
+
+/*
+ * Allow user to override any previous default.
+ *
+ * Use two macro names for that, as:
+ * - with yotta the prefix YOTTA_CFG_ is forced
+ * - without yotta is looks weird to have a YOTTA prefix.
+ */
+#if defined(YOTTA_CFG_MBEDTLS_USER_CONFIG_FILE)
+#include YOTTA_CFG_MBEDTLS_USER_CONFIG_FILE
+#elif defined(MBEDTLS_USER_CONFIG_FILE)
+#include MBEDTLS_USER_CONFIG_FILE
+#endif
+
+#include "check_config.h"
+
+#endif /* MBEDTLS_CONFIG_H */
diff --git a/mbedtls_vs_boringssl/testapp/Makefile.aarch64 b/mbedtls_vs_boringssl/testapp/Makefile.aarch64
new file mode 100644
index 0000000..7f02f68
--- /dev/null
+++ b/mbedtls_vs_boringssl/testapp/Makefile.aarch64
@@ -0,0 +1,107 @@
+include ../common.mk
+
+DBG ?= 0
+SRCDIR = src
+OBJDIR = obj
+BORINGSSL_DIR = ../bssl/src
+MBEDTLS_DIR = ../mbedtls/src
+
+## Debug/Release configuration
+ifeq ($(DBG),1)
+DEBUG = -DDEBUG -g -O0
+RELEASE =
+STRIP = true
+else
+DEBUG =
+RELEASE = -Os -fdata-sections -ffunction-sections
+STRIP = $(NDK)/toolchains/aarch64-linux-android-4.9/prebuilt/linux-x86_64/aarch64-linux-android/bin/strip
+endif
+
+## NDK configuration.
+NDK = $(ANDROID_NDK)
+NDK_TARGETARCH = aarch64-linux-android
+NDK_TARGETSHORTARCH = arm64
+NDK_TOOLVER = 4.9
+NDK_HOSTARCH = linux-x86_64
+NDK_TOOLS = $(NDK)/toolchains/llvm/prebuilt/$(NDK_HOSTARCH)/bin
+NDK_SYSROOT = $(NDK)/sysroot
+NDK_TOOL = $(NDK_TOOLS)/clang
+NDK_LIBS = $(NDK)/toolchains/$(NDK_TARGETARCH)-$(NDK_TOOLVER)/prebuilt/linux-x86_64/lib/gcc/$(NDK_TARGETARCH)/4.9.x
+NDK_INCLUDES = -I$(NDK)/sysroot/usr/include \
+ -I$(NDK)/sysroot/usr/include/$(NDK_TARGETARCH)
+NDK_SYSROOT = $(NDK)/platforms/android-$(NDK_TARGETVER)/arch-$(NDK_TARGETSHORTARCH)
+
+OPT = $(DEBUG) \
+ $(RELEASE) \
+ -std=c99 \
+ -fPIE \
+ -Wall \
+ -target $(NDK_TARGETARCH)
+CFLAGS = $(OPT) \
+ $(NDK_INCLUDES)
+CFLAGS_BORINGSSL = $(CFLAGS) \
+ -I$(BORINGSSL_DIR) -I$(BORINGSSL_DIR)/include
+CFLAGS_MBEDTLS = $(CFLAGS) \
+ -I$(MBEDTLS_DIR)/include
+LDFLAGS = $(OPT) \
+ $(DEBUG) $(RELEASE) \
+ -pie \
+ --sysroot=$(NDK_SYSROOT) \
+ -B $(ANDROID_NDK)/toolchains/$(NDK_TARGETARCH)-$(NDK_TOOLVER)/prebuilt/linux-x86_64/$(NDK_TARGETARCH)/bin \
+ -L$(NDK_LIBS) \
+ -Wl,--gc-sections
+
+LDFLAGS_BORINGSSL = $(LDFLAGS) \
+ -L$(BORINGSSL_DIR)/build/crypto -L$(BORINGSSL_DIR)/build/ssl \
+ -lssl -lcrypto
+
+LDFLAGS_MBEDTLS = $(LDFLAGS) \
+ -L$(MBEDTLS_DIR)/library -lmbedx509 -lmbedtls -lmbedcrypto
+
+.PHONY: print_boring_ld print_mbed_ld
+
+all: init b_client m_client server
+
+init:
+ mkdir -p $(OBJDIR)
+ # Create 1MB file with random data
+ dd if=/dev/urandom of=etc/random_data bs=1024 count=1024
+
+clean:
+ rm -rf $(OBJDIR)
+ rm -rf b_client
+ rm -rf m_client
+ rm -rf server
+
+b_client: common
+ $(NDK_TOOL) -c $(SRCDIR)/b_client.c -o $(OBJDIR)/b_client.o $(CFLAGS_BORINGSSL)
+ $(NDK_TOOL) -o b_client $(OBJDIR)/b_client.o $(OBJDIR)/common.o $(OBJDIR)/common_boring.o $(LDFLAGS_BORINGSSL)
+ $(STRIP) -s b_client
+
+m_client: common
+ $(NDK_TOOL) -c $(SRCDIR)/m_client.c -o $(OBJDIR)/m_client.o $(CFLAGS_MBEDTLS)
+ $(NDK_TOOL) -o m_client $(OBJDIR)/m_client.o $(OBJDIR)/common.o $(LDFLAGS_MBEDTLS)
+ $(STRIP) -s m_client
+
+server: common
+ $(NDK_TOOL) -c $(SRCDIR)/server.c -o $(OBJDIR)/server.o $(CFLAGS_BORINGSSL)
+ $(NDK_TOOL) -o server $(OBJDIR)/server.o $(OBJDIR)/common.o $(OBJDIR)/common_boring.o $(LDFLAGS_BORINGSSL)
+ $(STRIP) -s server
+
+common:
+ $(NDK_TOOL) -c $(SRCDIR)/common.c -o $(OBJDIR)/common.o $(CFLAGS)
+ $(NDK_TOOL) -c $(SRCDIR)/common_boring.c -o $(OBJDIR)/common_boring.o $(CFLAGS_BORINGSSL)
+
+adb-prepare:
+ adb root
+ adb remount
+ adb shell rm -rf /data/app/test_space/*
+ adb shell mkdir -p /data/app/test_space/etc
+ # Need to reset date to 10th of April this year, otherwise, cert verification fails
+ adb shell "toybox date 041910002018"
+
+push: adb-prepare
+ adb push b_client /data/app/test_space/
+ adb push m_client /data/app/test_space/
+ adb push server /data/app/test_space/
+ adb push etc/* /data/app/test_space/etc/
diff --git a/mbedtls_vs_boringssl/testapp/Makefile.native b/mbedtls_vs_boringssl/testapp/Makefile.native
new file mode 100644
index 0000000..52283f5
--- /dev/null
+++ b/mbedtls_vs_boringssl/testapp/Makefile.native
@@ -0,0 +1,64 @@
+BORINGSSL_DIR=/home/hdc/repos/mbedtls_vs_boringssl/bssl/src
+BORINGSSL_LIB=$(BORINGSSL_DIR)/build
+MBEDTLS_DIR=/home/hdc/repos/mbedtls_vs_boringssl/mbedtls/src
+MBEDTLS_LIB=$(MBEDTLS_DIR)/build
+
+DBG?=0
+
+ifeq ($(DBG),1)
+DEBUG=-DDEBUG -g -O0
+STRIP=true
+else
+DEBUG=-Os -fdata-sections -ffunction-sections
+STRIP=strip
+endif
+
+CC=clang
+
+CFLAGS_COMMON=-std=c99 $(DEBUG)
+BORINGSSL_CFLAGS=$(CFLAGS_COMMON) -I$(BORINGSSL_DIR)/ -I$(BORINGSSL_DIR)/include
+BORINGSSL_LDFLAGS=-L$(BORINGSSL_LIB)/crypto -L$(BORINGSSL_LIB)/ssl -lssl -lcrypto -lpthread -Wl,--gc-sections
+MBEDTLS_CFLAGS=$(CFLAGS_COMMON) -I$(MBEDTLS_DIR)/include
+MBEDTLS_LDFLAGS=-L$(MBEDTLS_DIR)/library -lmbedx509 -lmbedtls -lmbedcrypto
+SRCDIR=src
+OBJDIR=obj
+
+.PHONY: print_boring_ld print_mbed_ld
+
+all: init server b_client m_client
+
+init:
+ mkdir -p obj
+ # Create 1MB file with random data
+ dd if=/dev/urandom of=etc/random_data bs=1024 count=1024
+
+clean:
+ rm -rf $(OBJDIR)
+ rm b_client
+ rm m_client
+ rm server
+
+b_client: common
+ $(CC) -c $(SRCDIR)/b_client.c -o $(OBJDIR)/b_client.o $(BORINGSSL_CFLAGS)
+ $(CC) -o b_client $(OBJDIR)/b_client.o $(OBJDIR)/common.o $(OBJDIR)/common_boring.o $(BORINGSSL_LDFLAGS)
+ $(STRIP) b_client
+
+m_client: common
+ $(CC) -c $(SRCDIR)/m_client.c -o $(OBJDIR)/m_client.o $(MBEDTLS_CFLAGS)
+ $(CC) -o m_client $(OBJDIR)/m_client.o $(OBJDIR)/common.o $(MBEDTLS_LDFLAGS)
+ $(STRIP) m_client
+
+server: common
+ $(CC) -c $(SRCDIR)/server.c -o $(OBJDIR)/server.o $(BORINGSSL_CFLAGS)
+ $(CC) -o server $(OBJDIR)/server.o $(OBJDIR)/common.o $(OBJDIR)/common_boring.o $(BORINGSSL_LDFLAGS)
+ $(STRIP) server
+
+common:
+ $(CC) -c $(SRCDIR)/common.c -o $(OBJDIR)/common.o
+ $(CC) -c $(SRCDIR)/common_boring.c -o $(OBJDIR)/common_boring.o $(BORINGSSL_CFLAGS)
+
+print_boring_ld:
+ @echo $(BORINGSSL_LIB)/crypto:$(BORINGSSL_LIB)/ssl
+print_mbed_ld:
+ @echo $(MBEDTLS_LIB)/crypto:$(MBEDTLS_LIB)/ssl
+
diff --git a/mbedtls_vs_boringssl/testapp/etc/ca/ca.cert.pem b/mbedtls_vs_boringssl/testapp/etc/ca/ca.cert.pem
new file mode 100644
index 0000000..0ddba83
--- /dev/null
+++ b/mbedtls_vs_boringssl/testapp/etc/ca/ca.cert.pem
@@ -0,0 +1,24 @@
+-----BEGIN CERTIFICATE-----
+MIID8jCCAtqgAwIBAgIJALuIdyUDX1d+MA0GCSqGSIb3DQEBCwUAMIGFMQswCQYD
+VQQGEwJGUjENMAsGA1UECAwEUEFDQTEXMBUGA1UEBwwOQ2FnbmVzIHN1ciBNZXIx
+JjAkBgNVBAsMHURvbWFpbiBDb250cm9sIFZhbGlkYXRlZCBTQVJMMSYwJAYDVQQD
+DB1Eb21haW4gQ29udHJvbCBWYWxpZGF0ZWQgU0FSTDAeFw0xODA0MDkxNjMxMDVa
+Fw00NTA4MjUxNjMxMDVaMIGFMQswCQYDVQQGEwJGUjENMAsGA1UECAwEUEFDQTEX
+MBUGA1UEBwwOQ2FnbmVzIHN1ciBNZXIxJjAkBgNVBAsMHURvbWFpbiBDb250cm9s
+IFZhbGlkYXRlZCBTQVJMMSYwJAYDVQQDDB1Eb21haW4gQ29udHJvbCBWYWxpZGF0
+ZWQgU0FSTDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALBjh23Spt4I
+AvaFLNL9LXDngLy6OyJbqPYNOEfn9vdvzcCJZbBDhD1HNoIuJux340wcio5TZajX
+sJCIUl/n+e+8BGwxzZvp3qM2e/Rs94roZjlUWHMaX/a8Q7MvrR9XWM1SaEp2fHa9
+nBgdfSo+BvvILq8lZU7vO+xw7Yjtx0YNk1v3IAMoQyrfaeZcb9uE1tuAj0oPwmEp
+CWqGVkQEIJ6MJBbA+6SW6yi/5h3s0mbc7hdcmLr+vSv5Bkg8qOaPwh0ffuTCMuGq
+8q9en4WSW/mnbDZpPdGZwp4Ub7po4Zp9dVQoD7Skf9chz26+pivmIfUB1Xwr48b2
+gFfbZcwDsFsCAwEAAaNjMGEwHQYDVR0OBBYEFPSjEiJgM3NjauAc0lzUrgExAgvg
+MB8GA1UdIwQYMBaAFPSjEiJgM3NjauAc0lzUrgExAgvgMA8GA1UdEwEB/wQFMAMB
+Af8wDgYDVR0PAQH/BAQDAgGGMA0GCSqGSIb3DQEBCwUAA4IBAQAQALRSOq1IwOMG
+qZeXvNmd+jGomDH4IDV+s+agGWWneVzRJzP1qSxvrG5BgyP+STzvxEJBgGfCZKHw
+qW2HH2bt3vU0KhF90zthmLlZSphuF3XTBUyWfhmUgxuSWxgScBLHrk2vwQv55Mxn
+N88DPwYfRLjJUfEIDhzgNRsrVP1mbP0tmXjfmuQzE9Ht8L3fqJ+Tfk/eHdJIOkeM
+YRYSOT6oa7g49Vi6ONE7m+BqCDS7D+2p6t6Zb/1lEI82TvmbUq7gd9xHCROFmhis
+gBKsJxp0aVI5pB9mLqnluB21c4sVqt6si8sWcJjtTCmojp192aSxB3A6hVI0P8qY
+7iJBFwa1
+-----END CERTIFICATE-----
diff --git a/mbedtls_vs_boringssl/testapp/etc/ecdsa_256.key b/mbedtls_vs_boringssl/testapp/etc/ecdsa_256.key
new file mode 100644
index 0000000..22cef15
--- /dev/null
+++ b/mbedtls_vs_boringssl/testapp/etc/ecdsa_256.key
@@ -0,0 +1,8 @@
+-----BEGIN EC PARAMETERS-----
+BggqhkjOPQMBBw==
+-----END EC PARAMETERS-----
+-----BEGIN EC PRIVATE KEY-----
+MHcCAQEEIF8KXjVrcF0u+J3dDxrOPHr3/xQlxwpZowwdDxiM72iUoAoGCCqGSM49
+AwEHoUQDQgAE7HJPLOV22gIiLMIR1btCTDQMbtwwWqhuErrk2r4+p3Oino2fSDBm
+9T76CNfnLjmUue1qoLj144aK86GB0rGy4A==
+-----END EC PRIVATE KEY-----
diff --git a/mbedtls_vs_boringssl/testapp/etc/ecdsa_256.pem b/mbedtls_vs_boringssl/testapp/etc/ecdsa_256.pem
new file mode 100644
index 0000000..dc21c6a
--- /dev/null
+++ b/mbedtls_vs_boringssl/testapp/etc/ecdsa_256.pem
@@ -0,0 +1,15 @@
+-----BEGIN CERTIFICATE-----
+MIICTTCCATUCCQD7FNAespFtBDANBgkqhkiG9w0BAQsFADCBhTELMAkGA1UEBhMC
+RlIxDTALBgNVBAgMBFBBQ0ExFzAVBgNVBAcMDkNhZ25lcyBzdXIgTWVyMSYwJAYD
+VQQLDB1Eb21haW4gQ29udHJvbCBWYWxpZGF0ZWQgU0FSTDEmMCQGA1UEAwwdRG9t
+YWluIENvbnRyb2wgVmFsaWRhdGVkIFNBUkwwHhcNMTgwNDA5MjAxMTEwWhcNNDUw
+ODI0MjAxMTEwWjAWMRQwEgYDVQQDDAt3d3cuZG12LmNvbTBZMBMGByqGSM49AgEG
+CCqGSM49AwEHA0IABOxyTyzldtoCIizCEdW7Qkw0DG7cMFqobhK65Nq+Pqdzop6N
+n0gwZvU++gjX5y45lLntaqC49eOGivOhgdKxsuAwDQYJKoZIhvcNAQELBQADggEB
+ADEx+x0XXiTyBjEi5wVFEx/36tD4TMck5GLzyWFBPMgY5rVk0/scyYslqikF7j/M
+OY/Z+3WG/Wx0OqH+inA+aYb2xg6qLd4JR9eIRU7luSKyFDRCK3BYcpPYa9DQKVim
+Q4jA17rLRKqLLSDWUr0VO+YaXk9EqpkjjEeo3Dn1xIKtwwqvEocFUWlc1MPUrfgX
+OpPP4fSyqPcE0I75vWsznGyrYax9k7fAFV/UdC2p/jQPs+lVVesml2DJA9IjEdpJ
+1HOKpzjPXrPkCixoXqjM0HZRLuCNUb1sl8bWvpCQ6xTtDH0mkt8yHO6HeqKLpgpZ
+2O99VHKVMmEzsFOyE+4khVM=
+-----END CERTIFICATE-----
diff --git a/mbedtls_vs_boringssl/testapp/etc/rsa_2048.key b/mbedtls_vs_boringssl/testapp/etc/rsa_2048.key
new file mode 100644
index 0000000..b4f3de4
--- /dev/null
+++ b/mbedtls_vs_boringssl/testapp/etc/rsa_2048.key
@@ -0,0 +1,30 @@
+-----BEGIN RSA PRIVATE KEY-----
+Proc-Type: 4,ENCRYPTED
+DEK-Info: AES-256-CBC,298AA9B5B7606E863BB9183F689D9346
+
+VvURRUrBBi/AlUA4AlFUKm+aVzvnG4TQrhHKTV3nFGOHeqB+Sua+3R+e6svyiY+p
+d0VaZtlpS2mE7lxPqy0+VOarCYYkJOF2juGVMwFzEG8lkoEUyC8qyOobaRj4OCcb
+PgIk9b3i5Lv2PBLTpC4lxo6FrUykKXqLKeg0Lp4EEfFRGOKQB5CQBDeGOA1oBeqt
+cwRxXP8k3KPiIs+P+Lswk5qLD4gTtlf8ycQmJuCDFUQ3ARgRvngqFvu/44fm5Ztv
+6fBvAQvoHXJ9I+HuJAJcT1wGn9itZYFRMXyA2pf1Q2WHpxm1ZS7AiZrn5nyqPpnV
+aoBlwR7D0OxyoRumSHA3Y4YheN+uId27Gg12AWUalDcFes3DD2DZOkSQrzsIT0X3
+EifJSSnuOTLe8w+SSvUVIMxkW5CRE0uOi/wuZHTpRN0ZxsvmeL+EHQmqtAOcjS5g
+RPMidMdSGfCnqC0N2EAalUU2BsIGRgG5yvmG5ZIqu0Bm6WIIX1T34HS8HUhDqgRX
+jOi8Ch7J/6xMZcxSeqRvdss96s6SzehqpG3kW7EsualJqWwmAGF0oJOxX6LupIRd
+0GacwZv+NcWPYKL9oDNINPrU8hvobhaSeLvK8Gum8DK4TTd0evng6LYvkgejIcRF
+pzfC+ONTiHZO4ayxleJVFAdph2LY3itO/TKD6KBLq0vnd+HvOKPWq0s0zDtQ/mSF
+PMEwZ0DvYq5mtko5MOIqlIJKXS+p+jmzAhIZzqPt57HoyZjuRKTKkvlTeOoY7cax
+UDGJffDrnagbP3R12i+bm7Bmz7aQQktuwhV7/SrEnJDM2PLDOYuWnGV5v/Cb+L/7
+gGMFs9PTro8p4OkCLcpyGS/FoA7J5B1JixhUJ4tSEzEkTBSYz5WCi7NqrRZ9nnDf
+drYBNpMHlK4DNRe9qhusdRPrbd9srDH8g74QQgzWorYx0TqBUS45NLyyUZPydFxJ
+vAT1lmdWo7DhhnqSkPAcrwKdakDIravzvw0Ex+iEzAPSaflDvVybu6Gf8r6FrFIR
+SrR2pT4EztvPViaS9KZHZ0PQYKporwsWM1ZLyGX2qi3d5+YFijE3IT67rSLuEBMO
+/RFY0OCHbmKNrOiCaXk51+04hXg8ptjAxD8YCFpOzaDlSW2LX9D2QAfghoArZVTb
+OHThemZ4zIvamGkZLQB44nuvduIRGBA2LiQ0YiH4FhuJCP7zTCtCqQu4Wnn6J4tb
+YCEtm9ntFSGGCipErqqENPTBhxz6exO8emd2/y0INY4d9xJYjfhqCrKShpeF+/Lf
+6pJ3Pj9qA3D8wWcizER5N4R1fzmhTOSCxinC6OVJOzdk76M6gi+bD5RV8HD60TyG
+VEmTusA8lrLlKSYiE+4VFYBJjBSCopybJAaNsKXaYM3hwaPTPJwsgPWxwQ5m/vPT
+7dvkPOnhqwQ7DEvr2y3AgEUJxXxtsNwQEiKgMuRxNIQNE5mp68dJ5hMFnbJUPvvo
+80IsUH11LLDQJV60aLLF8M37BFvNPUayaS+oP78UwRMbnpC92nuHNgvGfdXFKhV3
+/8z6lNYPlMGgBwdCD6NBXpXHkp7rxOAGvHx5eUocjgXfF2b8zSXyN/9egK9sfMZZ
+-----END RSA PRIVATE KEY-----
diff --git a/mbedtls_vs_boringssl/testapp/etc/rsa_2048.pem b/mbedtls_vs_boringssl/testapp/etc/rsa_2048.pem
new file mode 100644
index 0000000..97abd96
--- /dev/null
+++ b/mbedtls_vs_boringssl/testapp/etc/rsa_2048.pem
@@ -0,0 +1,19 @@
+-----BEGIN CERTIFICATE-----
+MIIDGDCCAgACCQD7FNAespFtAjANBgkqhkiG9w0BAQsFADCBhTELMAkGA1UEBhMC
+RlIxDTALBgNVBAgMBFBBQ0ExFzAVBgNVBAcMDkNhZ25lcyBzdXIgTWVyMSYwJAYD
+VQQLDB1Eb21haW4gQ29udHJvbCBWYWxpZGF0ZWQgU0FSTDEmMCQGA1UEAwwdRG9t
+YWluIENvbnRyb2wgVmFsaWRhdGVkIFNBUkwwHhcNMTgwNDA5MTYzMjEwWhcNNDUw
+ODI0MTYzMjEwWjAWMRQwEgYDVQQDDAt3d3cuZG12LmNvbTCCASIwDQYJKoZIhvcN
+AQEBBQADggEPADCCAQoCggEBANDw1tIr4IHqfivyIBMn4MPRaPQFxOZPIRaIOo85
+4gaeHD11tLbxIh++lzfxk//ubC5a5K/PUDsVhLupTQVNKklcg4eRymZROkXoqgRg
++ibEH5IYRu64aVlhQe4lGiK/Z8njUtq31zeyn2RaYWW/4uq/wmOKB/qVinARISKf
+lvTjtSN5cBg55tyDV5Cb7GgpSBXVGc8J4WKU6BAn43FTqgj8XkVvGYR3C/X5ZR/+
+3xXVqe/VwLHyYNe61ySYRmymdoXJnJE7l0+MJhcpvepzEZ1pCULomNbHcxGfSZnc
+XsajvNKp/Y+cjC/IYmzkpTHgHhUEVs1rAdotNr0j5vRS/iECAwEAATANBgkqhkiG
+9w0BAQsFAAOCAQEAXjyhGLvT1waoYofYhkN3xmrkDxtM8HmG/xGad1vhkx6Qi2M/
+kdX/UlEMwlkh1Of20iJVcMmTPleiOcIO2cE8F0BQ4wIGN3PGw8guxa11ToyyMarg
+cWNUWdA4gwYvMQv6tceUtsJUjNp0O6JW563jejVaiqBHhG50riJ2wfzqgMItjZY0
+/TLVRQbEJ+NGeYZJ9/jL5xmHxoL8ROQ3RXtZjxU6Jr0pe3Y7XKT27QE3007EkCYb
+XG7K1U/rbixqfphXys677gjJ8xXChunjNqCijNk2xjHmu2MakspSqIB86oB50oLj
+Pu+AVI/SGD1qlJBC9qlgDoUkm9VI9mTIKJzALg==
+-----END CERTIFICATE-----
diff --git a/mbedtls_vs_boringssl/testapp/etc/rsa_3072.key b/mbedtls_vs_boringssl/testapp/etc/rsa_3072.key
new file mode 100644
index 0000000..6c52235
--- /dev/null
+++ b/mbedtls_vs_boringssl/testapp/etc/rsa_3072.key
@@ -0,0 +1,40 @@
+-----BEGIN PRIVATE KEY-----
+MIIG/QIBADANBgkqhkiG9w0BAQEFAASCBucwggbjAgEAAoIBgQDChoUsywwSGecu
+aHGGNMY8PrvM7nPjXpFXD0MK1OG0Yf3eV/QqRC3ahS7SICUvhRTiDzClez45NOKx
+YpH1C0u/M/DvojFgrGJlKVvO0vdckxlWCyK6DVKiwBP7ySkXjy+TuRuIZ4kxHzWC
+AEldbgPHlIGPxvhU4dAHXHcdHGdAgHL+7AhZh32acIDq3pkla3PQAawKcl/72l7v
+PXju594jWZkzrqPjXKpJ2GRX8q5XFoMNUe3hDR1Fk4aij7Y2k5aWmkD3WVGHti9K
+Zdjua2CYIp1+BUZ205wxOiWHlshpXzs73Exj2uv9OM/fcVliy5T+uR87a6KoIq+7
+vrU642yWCWOx3pzhvfgBANCnJRWXCq4CPAyImNUaapgnrM9TIWRyBmtD7/qsfQ0b
+DKJItf+p4Zzx1QatLKFG8qaaoP+6liQQaYFRP/v+cXM7c9LaU7elKI3yyClLSUoV
+rg6vp/xUsIcaYjUP2j+3VMv54Dy18eWt2FkmRB1ompSp+g6XoI8CAQMCggGBAIGv
+A3MyCAwRRMma9ll4hCgp0oie9+zptjoKLLHjQSLr/pQ6osbYHpGuHzbAGMpYuJa0
+yxj81CYjQcuXC/iyMn939fUWy5XIQZjGPTSMpOhiEOQHbHwI4cHVYqfbcLpfdQ0m
+ElrvsMtqI6wAMOj0AoUNq7UvUDiWiq+S+hNoRNWq91SdWuZaU7xLAJyUZhjyTTVW
+crGhlVKRlJ9+UJ9FPsI7u3fJwpeTHDE67Y/3HuS5rLOL8+teE4O3rxcKeXm3uI/h
+4O6rL2hwJDWSZ0LDnCCRpPQQwjlh6/xg57+R7Fgn8UW9u6dtyuNTHHpR+iiouE+Y
+7unzF5SC/ipQDFUYHmNiygGZL6KMy1H5NlosQiQZ/BY7A6UsNnySa6XwZu1/HTMt
+6pEtFbiXs3XaR6aA9Ervjt6OEHTldQ5/mBc2A6cvtvLB/wa74fkX5vhA2ruapTWr
+T501rYPTKhUKxmyaSe0U7qZ4rLcgOpxKbr/Rh6fkoXfgBOov5supefCRPeCsuwKB
+wQDpmuped2B80mnSchyL3KG/x5GFxSfALgnWGYovzHLHPxJQGLrSa841N4j+Qggb
+4n/r4e93+L1Ps++9Zl4A9HFQ+F0oKE+j18mB6LEkvFCqhIRC29mJcQyfNbchFqhl
+Ph+6XE/Ul8p5UdF2gZfNyQoJ5TGnWPEusxwD8T3IY5helGd6i8SY6FztIzlsNv/p
+hZ/9YjHjP9ngmGruXjgQBb1NFKuELbGE2gMw60faiKbPmJVHtotVwauS8OA+67jH
+w30CgcEA1SyFMuEp7juPJ5ghfmlUp4CUiib7YJKwYI8/uG9zHeQ/Ayb4FkptcwSc
+KbRaCewAm3HJZIZB+apCvuBEukrNr/zXh1CFyhL9hCJN+yZhtl8vngeth2V2wFk/
+ja2MiaSY6uU7lZSPnkeuc8OfASuHL5UU/Kb8zyFVrUIEr2xh4ToqKbq+Lj3MG6pf
+WtuK12Yf10Vko7fLJPQgB7+s/LrQI/x1nH+AeE/km/nd/51KaoJeMlHGcTqXpCt9
+gjR4/tn7AoHBAJu8nD76QFM28Tb2vbKTFn/aYQPYxSrJW+QRBsqITITUtuAQfIxH
+3s4lBf7WsBKW//KWn6VQfjUin9OZlACi9jX66MVwNRflMQFFy23S4HGtrYHn5lug
+sxTOehYPGu4panw9io26hvuL4PmruokwsVvuIRo7S3R3aAKg09rtED8NmlGygxCa
+6J4Xe515//EDv/5Bdpd/5pW68fQ+0AqufjNjHQLJIQM8AiCc2pGwbzUQY4UkXOPW
+cmH16tSdJdqCUwKBwQCOHa4h63FJfQoaZWupm43FAGMGxKeVtyBAX3/QSky+mCoC
+Gfq5hvOiAxLGeDwGnVW89oZDBCv7xtcp6th8Md51UzpaNa6Gt1OtbDP8xEEkP3UU
+BR5aQ6SAO3+zyQhbwxCcmNJjuF++2nRNLRSrclofuLiob1M0wOPI1q3KSEFA0XFx
+Jyl0KTK9HD+R57Hk7r/k2O3Ceodt+BVaf8iofIrCqE5oVQBQNUMSppP/vjGcVul2
+4S72Jw/Cx6kBeFCp5qcCgcBF+fb8F59HYjZJAjV4Qv2obehNvcb7swHMOYTLBkBq
+j9cnVysTQ9lc6vwB5Vh4rzwOSmJRKPvv6+1oinImwtzZFLuggunkXxmrPLiRcF82
+Gj7RL62D6msMbNo0vMXmXa20D/M3lATSuWuOsBz1BAfFrkO/kwAz02s9dleOidX3
+YkuSiPhm3bQD3qezO3OQmZ2s1OfzZMQpXE8+4ymTWW5H9KtKxrDs7/05goy1/OPk
+u5evFUiLOWw7CJ9Sy1/Jaws=
+-----END PRIVATE KEY-----
diff --git a/mbedtls_vs_boringssl/testapp/etc/rsa_3072.pem b/mbedtls_vs_boringssl/testapp/etc/rsa_3072.pem
new file mode 100644
index 0000000..7d75777
--- /dev/null
+++ b/mbedtls_vs_boringssl/testapp/etc/rsa_3072.pem
@@ -0,0 +1,18 @@
+-----BEGIN CERTIFICATE-----
+MIIC1DCCAnsCCQCY04gkucQIkzAKBggqhkjOPQQDAjB9MQswCQYDVQQGEwJGUjEN
+MAsGA1UECAwEUEFDQTEXMBUGA1UEBwwOQ2FnbmVzIHN1ciBNZXIxIjAgBgNVBAsM
+GUNlcnQgVGVzdGluZyBPcmdhbml6YXRpb24xIjAgBgNVBAMMGUNlcnQgVGVzdGlu
+ZyBPcmdhbml6YXRpb24wHhcNMTgwNDE3MTMyNzA4WhcNMTgwNTE3MTMyNzA4WjAf
+MR0wGwYDVQQDDBR3d3cuY2VydF90ZXN0aW5nLmNvbTCCAaAwDQYJKoZIhvcNAQEB
+BQADggGNADCCAYgCggGBAMKGhSzLDBIZ5y5ocYY0xjw+u8zuc+NekVcPQwrU4bRh
+/d5X9CpELdqFLtIgJS+FFOIPMKV7Pjk04rFikfULS78z8O+iMWCsYmUpW87S91yT
+GVYLIroNUqLAE/vJKRePL5O5G4hniTEfNYIASV1uA8eUgY/G+FTh0Adcdx0cZ0CA
+cv7sCFmHfZpwgOremSVrc9ABrApyX/vaXu89eO7n3iNZmTOuo+NcqknYZFfyrlcW
+gw1R7eENHUWThqKPtjaTlpaaQPdZUYe2L0pl2O5rYJginX4FRnbTnDE6JYeWyGlf
+OzvcTGPa6/04z99xWWLLlP65Hztroqgir7u+tTrjbJYJY7HenOG9+AEA0KclFZcK
+rgI8DIiY1RpqmCesz1MhZHIGa0Pv+qx9DRsMoki1/6nhnPHVBq0soUbyppqg/7qW
+JBBpgVE/+/5xcztz0tpTt6UojfLIKUtJShWuDq+n/FSwhxpiNQ/aP7dUy/ngPLXx
+5a3YWSZEHWialKn6DpegjwIBAzAKBggqhkjOPQQDAgNHADBEAiBiXGvdsqXGxDtR
+09lV6d2w2rYVteso/RVCQVxUWo5BuQIgRXF5XrvhRbpTOaRgLgnOpyLZv7nEwWNG
+cRb2Q37V4VM=
+-----END CERTIFICATE-----
diff --git a/mbedtls_vs_boringssl/testapp/src/b_client.c b/mbedtls_vs_boringssl/testapp/src/b_client.c
new file mode 100644
index 0000000..e589716
--- /dev/null
+++ b/mbedtls_vs_boringssl/testapp/src/b_client.c
@@ -0,0 +1,205 @@
+#include
+#include "common.h"
+
+// include/ path is here for a reason - to make sure we compile against boringssl (temporary solution)
+#include
+#include
+
+// Buffer used for read/write tests
+unsigned char rw_buf[BUFFER_SIZE];
+
+SSL_CTX *setup_client_ctx(void)
+{
+ SSL_CTX* ctx;
+
+ ctx = SSL_CTX_new(TLS_with_buffers_method());
+ SSL_CTX_set_verify(ctx, SSL_VERIFY_PEER, NULL);
+ if( SSL_CTX_load_verify_locations(ctx, CACERT, NULL) != 1) {
+ ERR("Error loading CA DIR");
+ }
+ return ctx;
+}
+
+int do_client_loop(SSL* ssl)
+{
+ int err, nwritten;
+ char buf[80];
+
+ for(;;)
+ {
+ if( !fgets(buf, sizeof(buf), stdin) )
+ break;
+ for(nwritten = 0; nwritten < strlen(buf); nwritten += err)
+ {
+ err = SSL_write(ssl, buf + nwritten, strlen(buf) - nwritten);
+ if(err<=0)
+ return 0;
+ }
+ }
+ return 1;
+}
+
+void test_Handshake(size_t handshake_nb) {
+
+ SSL* ssl;
+ SSL_CTX* ctx;
+ int err;
+
+ init();
+ ctx = setup_client_ctx();
+
+ DBG("Trying to connect");
+ int fd = connect_once();
+
+ for (size_t i=0; i0);
+
+ if (0==(SSL_get_shutdown(ssl) & SSL_RECEIVED_SHUTDOWN)) {
+ ERR("SSL_Read");
+ }
+
+ DBG("Shutdown");
+ SSL_set_read_ahead(ssl, 0);
+ assert(SSL_shutdown(ssl) == 1);
+
+ SSL_free(ssl);
+ SSL_CTX_free(ctx);
+ close(fd);
+}
+
+void test_Write() {
+ SSL* ssl;
+ SSL_CTX* ctx;
+ int err,nread=0;
+
+ init();
+ ctx = setup_client_ctx();
+
+ DBG("Trying to connect");
+ int fd = connect_once();
+
+ DBG("SSL ctx setup");
+ if (!(ssl = SSL_new(ctx))) {
+ ERR("Error creating an SSL context");
+ }
+ SSL_set_fd(ssl, fd);
+
+ DBG("SSL handshake");
+ err = SSL_connect(ssl);
+ if (err<=0) {
+ ERR("Error connecting SSL err=%d", err);
+ }
+
+ DBG("Writing");
+
+ fill_buffer_from_file(rw_buf, sizeof(rw_buf));
+ for (size_t i=0; i
+#include
+#include
+
+#include
+#include
+#include
+#include
+
+/* -----------------------------------------------------------------------------
+ * @brief Performs TCP 3-way handshake with IP:PORT
+ * -------------------------------------------------------------------------------- */
+int connect_once(void) {
+
+ struct sockaddr_in a;
+
+ int fd = socket(AF_INET, SOCK_STREAM, 0);
+ memset(&a, 0, sizeof(a));
+ a.sin_family = AF_INET;
+ a.sin_addr.s_addr = inet_addr(IP);
+ a.sin_port = htons(PORT);
+
+ // Set socket to blocking, in order to make things simplere
+ if (fcntl(fd, F_SETFL, fcntl(fd, F_GETFL) & ~O_NONBLOCK )<0) {
+ ERR("fcntl");
+ }
+
+ if (connect(fd, (struct sockaddr *) &a, sizeof(a))<0) {
+ ERR("Econnect");
+ }
+ DBG("Connected");
+ return fd;
+}
+
+/* -----------------------------------------------------------------------------
+ * @brief Fills the buffer with random data.
+ *------------------------------------------------------------------------------ */
+void fill_buffer_from_file(unsigned char *b, size_t sz) {
+ FILE * fd = fopen(RANDOM_DATA_FILE, "r");
+ if (!fd) {
+ ERR("fopen");
+ }
+
+ if (fread(b, 1, sz, fd) < sz) {
+ // Random data file smaller than a buffer
+ ERR("fread");
+ }
+
+ if (fclose(fd)) {
+ ERR("fclose");
+ }
+}
diff --git a/mbedtls_vs_boringssl/testapp/src/common.h b/mbedtls_vs_boringssl/testapp/src/common.h
new file mode 100644
index 0000000..a7dd17c
--- /dev/null
+++ b/mbedtls_vs_boringssl/testapp/src/common.h
@@ -0,0 +1,64 @@
+#ifndef __COMMON_H__
+#define __COMMON_H__
+
+#include
+#include
+#include
+
+#ifdef DEBUG
+#include
+#endif
+
+#define PORT 1443
+#define IP "127.0.0.1"
+#define SERVER "localhost"
+#define CLIENT "localhost"
+#define CACERT "etc/ca/ca.cert.pem"
+//#define CERT_HOSTNAME "www.cert_testing.com"
+#define CERT_HOSTNAME "www.dmv.com"
+#define KEYFILE_PASS "test123"
+#define READ_REQUEST "ReadRequest"
+#define HANDHAKE_REPS 200
+// Keep random data file must at least same size as a buffer size
+#define RANDOM_DATA_FILE "etc/random_data"
+#define BUFFER_SIZE 1024
+// Amount bytes of plaintext data exchanged in read-write stets is BUFFER_SIZE*RW_ITERATOIONS
+#ifdef DEBUG
+#define RW_ITERATIONS (1024*10) // 10 MB
+#else
+#define RW_ITERATIONS (1024*200) // 1GB
+#endif
+// Utils
+#define LOG_I(...) \
+ do { \
+ (void) fprintf(stdout, "[%s() %s:%d] ", __func__, __FILE__, __LINE__); \
+ (void) fprintf(stdout, __VA_ARGS__); \
+ (void) fprintf(stdout, "\n"); \
+ } while (0)
+#define ERR(...) \
+ do { \
+ LOG_I(__VA_ARGS__); \
+ exit(-1); \
+ } while (0)
+
+#define LOG(...) LOG_I(__VA_ARGS__)
+
+#ifdef DEBUG
+#define DBG(...) LOG_I(__VA_ARGS__)
+#else
+#define DBG(...)
+#endif
+
+#define ARRAY_SIZE(x) (sizeof(x)/sizeof(x[0]))
+
+int connect_once(void);
+void init(void);
+void cleanup(void);
+void fill_buffer_from_file(unsigned char *b, size_t sz);
+
+// Available tests
+void test_Write(void);
+void test_Read(void);
+void test_Handshake(size_t);
+
+#endif // __COMMON_H__
\ No newline at end of file
diff --git a/mbedtls_vs_boringssl/testapp/src/common_boring.c b/mbedtls_vs_boringssl/testapp/src/common_boring.c
new file mode 100644
index 0000000..83f1922
--- /dev/null
+++ b/mbedtls_vs_boringssl/testapp/src/common_boring.c
@@ -0,0 +1,30 @@
+#include "common.h"
+
+// include/ path is here for a reason - to make sure we compile against boringssl (temporary solution)
+#include
+#include
+#include
+#include
+
+void init(void) {
+ OpenSSL_add_all_algorithms();
+ SSL_load_error_strings();
+ SSL_library_init();
+ CRYPTO_library_init();
+
+ if(!SSL_library_init())
+ {
+ fprintf(stderr, "** OpenSSL initialization failed!\n");
+ exit(-1);
+ }
+}
+
+void cleanup(void) {
+
+ ERR_free_strings();
+ ERR_clear_error();
+ CRYPTO_set_locking_callback(NULL);
+ CRYPTO_set_id_callback(NULL);
+ EVP_cleanup();
+ CRYPTO_cleanup_all_ex_data();
+}
\ No newline at end of file
diff --git a/mbedtls_vs_boringssl/testapp/src/m_client.c b/mbedtls_vs_boringssl/testapp/src/m_client.c
new file mode 100644
index 0000000..e46d951
--- /dev/null
+++ b/mbedtls_vs_boringssl/testapp/src/m_client.c
@@ -0,0 +1,244 @@
+#include
+
+#include "mbedtls/net.h"
+#include "mbedtls/ssl.h"
+#include "mbedtls/entropy.h"
+#include "mbedtls/ctr_drbg.h"
+#ifdef DEBUG
+#include "mbedtls/debug.h"
+#endif
+
+#include "common.h"
+
+mbedtls_net_context server_fd;
+mbedtls_entropy_context entropy;
+mbedtls_ctr_drbg_context ctr_drbg;
+mbedtls_ssl_context ctx;
+mbedtls_ssl_config conf;
+mbedtls_x509_crt cacert;
+
+// Buffer used for read/write tests
+unsigned char rw_buf[BUFFER_SIZE];
+
+// Function calls 'mbedtls_ssl_handshake' and 'mbedtls_ssl_close_notify'
+#define HANDLE_OP_RW_NEEDS(op, ctx) \
+do { \
+ while ((ret = (op)((ctx)))) { \
+ if( ret != MBEDTLS_ERR_SSL_WANT_READ && ret != MBEDTLS_ERR_SSL_WANT_WRITE ) { \
+ ERR("Critical error when performing " #op); \
+ } \
+ } \
+} while (0);
+
+
+#ifdef DEBUG
+static void my_debug( void *ctx, int level,
+ const char *file, int line, const char *str ) {
+ ((void) level);
+ fprintf( (FILE *) ctx, "%s:%04d: %s", file, line, str );
+ fflush( (FILE *) ctx );
+}
+#endif
+
+void init() {
+ int ret;
+
+ mbedtls_net_init( &server_fd );
+ mbedtls_ssl_init( &ctx );
+ mbedtls_ssl_config_init( &conf );
+ mbedtls_x509_crt_init( &cacert );
+ mbedtls_ctr_drbg_init( &ctr_drbg );
+ mbedtls_entropy_init( &entropy );
+
+ mbedtls_ssl_conf_rng( &conf, mbedtls_ctr_drbg_random, &ctr_drbg );
+ ret = mbedtls_ctr_drbg_seed( &ctr_drbg, mbedtls_entropy_func, &entropy,
+ (const unsigned char *) CLIENT,
+ strlen( CLIENT ) );
+ if (ret) {
+ ERR( "mbedtls_ctr_drbg_seed");
+ }
+
+ ret = mbedtls_ssl_config_defaults(&conf,
+ MBEDTLS_SSL_IS_CLIENT,
+ MBEDTLS_SSL_TRANSPORT_STREAM, // TLS not DTLS
+ MBEDTLS_SSL_PRESET_DEFAULT );
+ if (ret) {
+ ERR("mbedtls_ssl_config_defaults");
+ }
+
+ mbedtls_ssl_conf_authmode( &conf, MBEDTLS_SSL_VERIFY_REQUIRED );
+ if (ret) {
+ ERR( "mbedtls_ssl_conf_authmode");
+ }
+
+ ret = mbedtls_x509_crt_parse_file(&cacert, CACERT);
+ if (ret) {
+ ERR("mbedtls_x509_crt_parse");
+ }
+
+ mbedtls_ssl_conf_ca_chain( &conf, &cacert, NULL );
+ //mbedtls_ssl_conf_ciphersuites( &conf, AllowedCiphers);
+#ifdef DEBUG
+ mbedtls_ssl_conf_dbg( &conf, my_debug, stdout );
+ mbedtls_debug_set_threshold(4);
+#endif
+ // end of 'conf' object setup
+
+ ret = mbedtls_ssl_setup(&ctx, &conf);
+ if (ret) {
+ ERR("mbedtls_ssl_setup");
+ }
+}
+
+void cleanup(void) {
+ mbedtls_x509_crt_free(&cacert);
+ mbedtls_net_free( &server_fd );
+ mbedtls_ssl_free( &ctx );
+ mbedtls_ssl_config_free( &conf );
+ mbedtls_ctr_drbg_free( &ctr_drbg );
+ mbedtls_entropy_free( &entropy );
+}
+
+static void setup_client_ctx(void)
+{
+
+ if (mbedtls_ssl_set_hostname(&ctx, CERT_HOSTNAME) ) {
+ ERR("mbedtls_ssl_set_hostname");
+ }
+ mbedtls_ssl_set_bio(&ctx, &server_fd, mbedtls_net_send, mbedtls_net_recv, NULL );
+}
+
+void test_Handshake(size_t handshake_nb) {
+ int ret;
+ init();
+
+ DBG("Trying to connect");
+ server_fd.fd = connect_once();
+ setup_client_ctx();
+
+ for (int i=0; i0);
+
+ if (err != MBEDTLS_ERR_SSL_PEER_CLOSE_NOTIFY) {
+ ERR("mbedtls_ssl_read");
+ }
+
+ DBG("Send 'close notify'");
+ HANDLE_OP_RW_NEEDS(mbedtls_ssl_close_notify, &ctx);
+
+ close(server_fd.fd);
+ cleanup();
+}
+
+int main(int argc, char* argv[]) {
+
+ if (argc < 2) {
+ goto usage;
+ }
+
+ if (!strncmp("test_Handshake", argv[1], strlen("test_Handshake"))) {
+ test_Handshake(HANDHAKE_REPS);
+ } else if (!strncmp("test_Read", argv[1], strlen("test_Read"))) {
+ test_Read();
+ } else if (!strncmp("test_Write", argv[1], strlen("test_Write"))) {
+ test_Write();
+ } else {
+ printf("Unknown test");
+ goto usage;
+ }
+
+exit:
+ return 0;
+
+usage:
+ ERR("\n\nUsage: %s test_name \nOptions for 'test_name':\n\t"
+ "test_Handshake\n\ttest_Write\n\ttest_Read\n", argv[0]);
+ goto exit;
+}
\ No newline at end of file
diff --git a/mbedtls_vs_boringssl/testapp/src/server.c b/mbedtls_vs_boringssl/testapp/src/server.c
new file mode 100644
index 0000000..efdadcc
--- /dev/null
+++ b/mbedtls_vs_boringssl/testapp/src/server.c
@@ -0,0 +1,264 @@
+#include
+#include
+#include
+
+// include/ path is here for a reason - to make sure we compile against boringssl (temporary solution)
+#include
+#include
+#include
+#include
+
+#include "common.h"
+
+// Enforce this protocol version
+#define TLS_PROT_VERSION TLS1_2_VERSION
+#define ENFORCED_CURVE NID_X9_62_prime256v1
+// Not supported by mbedTLS
+//#define ENFORCED_CURVE NID_X25519
+
+static const int Curves[1] = {ENFORCED_CURVE};
+
+static const struct CertDesc_t {
+ const char* arg;
+ const char* cert;
+ const char* key;
+ const char* cipher;
+ const int* curves;
+} Certs[] = {
+ {
+ .arg = "RSA_2048",
+ .key = "etc/rsa_2048.key",
+ .cert = "etc/rsa_2048.pem",
+ .cipher = "TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384",
+ .curves = Curves,
+ },
+ {
+ .arg = "RSA_3072",
+ .key = "etc/rsa_3072.key",
+ .cert = "etc/rsa_3072.pem",
+ .cipher = "TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384",
+ .curves = Curves,
+ },
+ {
+ .arg = "ECDSA_256",
+ .key = "etc/ecdsa_256.key",
+ .cert = "etc/ecdsa_256.pem",
+ .cipher = "TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384",
+ .curves = Curves,
+ }
+};
+
+const struct CertDesc_t* get_cert_desc(const char* c) {
+ for(size_t i=0; icert, SSL_FILETYPE_PEM) != 1)
+ ERR("Error loading certificate from file");
+ if(SSL_CTX_use_PrivateKey_file(ctx, c->key, SSL_FILETYPE_PEM) != 1)
+ ERR("Error loading private key from file");
+
+ if (SSL_CTX_set_strict_cipher_list(ctx, c->cipher) != 1) {
+ ERR("Error setting cipher list");
+ }
+
+ if (!SSL_CTX_set1_curves(ctx, c->curves, 1)) {
+ ERR("Enforcing curve");
+ }
+
+ if (SSL_CTX_set_min_proto_version(ctx, TLS_PROT_VERSION) != 1 ||
+ SSL_CTX_set_max_proto_version(ctx, TLS_PROT_VERSION) != 1) {
+ ERR("Enforcing protocol to TLSv1.2");
+
+ }
+ return ctx;
+}
+
+static void start_writing(SSL *ssl) {
+ int nread,err;
+
+ DBG("Start writing");
+
+ fill_buffer_from_file(rw_buf, sizeof(rw_buf));
+ for (size_t i=0; i0);
+ return (SSL_get_shutdown(ssl) & SSL_RECEIVED_SHUTDOWN) ? 1 : 0;
+}
+
+#ifdef DEBUG
+static const char* DBG_get_curve(SSL* ssl) {
+ const int id = SSL_get_curve_id(ssl);
+ if (!id) return "N/A";
+ return SSL_get_curve_name(id);
+}
+#endif
+
+// Interface for accepting
+int main(int argc, char *argv[])
+{
+ SSL *ssl;
+ SSL_CTX *ctx;
+ int fd, ret;
+
+ if (argc < 2) {
+ goto usage;
+ }
+
+ // Start server
+ init();
+
+ ctx = setup_server_ctx(argv[1]);
+ fd = accept_once();
+
+ for(;;) {
+
+ DBG("SSL Accepting");
+ if(!(ssl = SSL_new(ctx))) {
+ DBG("Error creating SSL context");
+ }
+
+
+ SSL_set_fd(ssl, fd);
+ ret = SSL_accept(ssl);
+ //printf("%s\n", SSL_get_curve_name(SSL_get_curve_id(ssl)));
+ if (ret<=0) {
+ ret = SSL_get_error(ssl, ret);
+
+ if (ret == SSL_ERROR_SYSCALL) {
+ DBG("Connection closed");
+ goto end;
+ } else {
+ ERR("Critical error occured %d", ret);
+ }
+ }
+
+ DBG("Protocol: %s Cipher %s Curve %s", SSL_get_version(ssl), SSL_get_cipher_name(ssl), DBG_get_curve(ssl));
+
+ DBG("server loop");
+ ret = do_server_loop(ssl);
+ if(ret) {
+
+ DBG("Shutdown");
+ SSL_set_read_ahead(ssl, 0);
+ if (ret==2) {
+ // Server is closing
+ SSL_shutdown(ssl);
+ }
+ assert(SSL_shutdown(ssl)==1);
+ }
+ else {
+ DBG("Shutdown - error case");
+ goto end;
+ }
+ SSL_clear(ssl);
+ }
+ SSL_CTX_free(ctx);
+
+end:
+ cleanup();
+ return 0;
+usage:
+ ERR("\n\nUsage: %s server certificate \nOptions for 'server certificate':\n\t"
+ "RSA_2048\n\t"
+ "RSA_3072\n\t"
+ "ECDSA_256\n\t",
+ argv[0]);
+ goto end;
+}
\ No newline at end of file
diff --git a/ndk-hello_world/README.md b/ndk-hello_world/README.md
new file mode 100644
index 0000000..4304445
--- /dev/null
+++ b/ndk-hello_world/README.md
@@ -0,0 +1,49 @@
+# How to compile C++ hello world with Android NDK
+
+1. Create following directory structure:
+
+ ```
+ hello_world/
+ jni/
+ libs/
+ ```
+
+2. In the `jni` directory create two files
+ 1. Android.mk:
+
+ ```
+ LOCAL_PATH := $(call my-dir)
+ include $(CLEAR_VARS)
+
+ # give module name
+ LOCAL_MODULE := hello_world
+
+ # list your C files to compile
+ LOCAL_SRC_FILES := test.c
+
+ # This seems to be needed for Android M on ARMv8
+ LOCAL_CFLAGS = -fPIE
+ LOCAL_LDFLAGS = -fPIE -pie
+
+ include $(BUILD_EXECUTABLE)
+ ```
+
+ 2. test.c
+
+ ```
+ #include
+ #include
+ int main()
+ {
+ printf("Hello World\n");
+ return 0;
+ }
+ ```
+
+4. Export PATH to NDK
+ ```
+ export PATH=/usr/local/softs/android-ndk-r10e:$PATH
+ ```
+3. Go to `jni` directory
+5. Call ``ndk-build``
+6. Result should be in `hello_world/libs/armeabi/hello_world`
diff --git a/ndk-hello_world/hello_world/jni/Android.mk b/ndk-hello_world/hello_world/jni/Android.mk
new file mode 100644
index 0000000..95e2b09
--- /dev/null
+++ b/ndk-hello_world/hello_world/jni/Android.mk
@@ -0,0 +1,12 @@
+LOCAL_PATH := $(call my-dir)
+include $(CLEAR_VARS)
+# give module name
+LOCAL_MODULE := hello_world
+# # list your C files to compile
+LOCAL_SRC_FILES := test.c
+
+LOCAL_CFLAGS = -fPIE
+LOCAL_LDFLAGS = -fPIE -pie
+
+# this option will build executables instead of building library for android application.
+include $(BUILD_EXECUTABLE)
diff --git a/ndk-hello_world/hello_world/jni/test.c b/ndk-hello_world/hello_world/jni/test.c
new file mode 100644
index 0000000..2889f7b
--- /dev/null
+++ b/ndk-hello_world/hello_world/jni/test.c
@@ -0,0 +1,8 @@
+#include
+#include
+int main()
+{
+ printf("Hello World\n");
+ return 0;
+}
+
diff --git a/ndk-hello_world/hello_world/libs/.keep b/ndk-hello_world/hello_world/libs/.keep
new file mode 100644
index 0000000..e69de29
diff --git a/radamsa-comp-android/Makefile b/radamsa-comp-android/Makefile
new file mode 100644
index 0000000..a8b6330
--- /dev/null
+++ b/radamsa-comp-android/Makefile
@@ -0,0 +1,52 @@
+# Must be configured by the user
+ANDROID_NDK := /opt/android-ndk
+
+# Constants and makefile shit used in build
+mkfile_path = $(abspath $(lastword $(MAKEFILE_LIST)))
+current_dir = $(notdir $(patsubst %/,%,$(dir $(mkfile_path))))
+
+## NDK configuration.
+PLATFORM_VERSION = 19
+NDK_ARCH = arm
+NDK_ABI = linux-androideabi
+NDK = $(ANDROID_NDK)
+NDK_COMP_VER = 4.9
+NDK_HOSTARCH = linux-x86_64
+NDK_TOOLS = $(NDK)/toolchains/$(NDK_ARCH)-$(NDK_ABI)-$(NDK_COMP_VER)/prebuilt/$(NDK_HOSTARCH)/bin
+NDK_SYSROOT = $(NDK)/platforms/android-$(PLATFORM_VERSION)/arch-$(NDK_ARCH)
+NDK_INC = $(NDK)/platforms/android-$(PLATFORM_VERSION)/arch-$(NDK_ARCH)/usr/include
+NDK_LIB = $(NDK)/platforms/android-$(PLATFORM_VERSION)/arch-$(NDK_ARCH)/usr/lib
+
+## Compiler and compilation flags
+CC = $(NDK_TOOLS)/$(NDK_ARCH)-$(NDK_ABI)-gcc
+CFLAGS = --sysroot=$(NDK_SYSROOT) -fPIE -pie -mthumb -O3 -DNO_SECCOMP -I$(NDK_INC) \
+ -std=gnu99 -Wall -Werror
+LDFLAGS = --sysroot=$(NDK_SYSROOT) -fPIE -pie
+
+# Exploit
+OUT = $(current_dir)/Out/Bin
+RADAMSA_SRC = src
+
+all: clone bin
+.PHONY: all radamsa.c
+
+clone:
+ git clone https://github.com/aoh/radamsa.git $(RADAMSA_SRC)
+ #Checkout revision to make sure whole solution compiles
+ cd src && git checkout 1a9cc03fda47dd3706ef69f4ad971f66b273a324
+
+radamsa.c:
+ $(MAKE) -C $(RADAMSA_SRC) radamsa.c
+ patch -p1 < android.patch
+
+bin: radamsa.c
+ mkdir -p $(OUT)
+ $(CC) $(CFLAGS) -o $(OUT)/radamsa.o -c $(RADAMSA_SRC)/radamsa.c
+ $(CC) $(LDFLAGS) -o $(OUT)/radamsa $(OUT)/radamsa.o -ldl
+
+clean:
+ rm -rf $(OUT)
+ rm -rf $(RADAMSA_SRC)
+
+push:
+ adb push $(OUT)/radamsa /data/app/
diff --git a/radamsa-comp-android/README b/radamsa-comp-android/README
new file mode 100644
index 0000000..f7b49f9
--- /dev/null
+++ b/radamsa-comp-android/README
@@ -0,0 +1,9 @@
+# Android build of radamsa fuzzer/mutator
+
+Project is basically a makefile that clones radamsa and then uses NDK to compile it for Android
+
+# Usage
+Edit makefile and set ``ANDROID_NDK`` variable to absolute path to Android NDK. Then just ``make``
+
+# To do
+In order to compile make needs to apply patch called ``android.patch``. The patch just adds one one line which is required for android build. Would be good to get rid of that sht somehow.
diff --git a/radamsa-comp-android/android.patch b/radamsa-comp-android/android.patch
new file mode 100644
index 0000000..56db30a
--- /dev/null
+++ b/radamsa-comp-android/android.patch
@@ -0,0 +1,12 @@
+diff --git a/radamsa.c b/radamsa.c
+index 5e5735d..d93ef42 100644
+--- a/src/radamsa.c
++++ b/src/radamsa.c
+@@ -2547,6 +2547,7 @@ unsigned char heap[] = {2,3,9,114,101,99,117,114,115,105,118,101,2,3,1,43,2,
+ #include
+ #include
+ #include
++#include
+ #ifndef O_BINARY
+ #define O_BINARY 0
+ #endif
diff --git a/reset_android_gatekeeper_password/README.md b/reset_android_gatekeeper_password/README.md
new file mode 100644
index 0000000..360475a
--- /dev/null
+++ b/reset_android_gatekeeper_password/README.md
@@ -0,0 +1,15 @@
+# Reset Android M Lockscreen Password
+
+Script cleans lockscreen pattern/password/PIN (not fingerprint) from rooted Android M.
+
+To use:
+
+1. Connect device via USB
+2. Make sure ``adb devices`` detects the device
+3. Run:
+
+```
+./clean_lock_password.sh
+```
+
+Script will remove password and pattern from android filesystem and replace locksettings database.
diff --git a/reset_android_gatekeeper_password/clean_lock_passwd.sh b/reset_android_gatekeeper_password/clean_lock_passwd.sh
new file mode 100644
index 0000000..20dea65
--- /dev/null
+++ b/reset_android_gatekeeper_password/clean_lock_passwd.sh
@@ -0,0 +1,16 @@
+#!/bin/bash
+
+adb root
+adb remount
+
+# Remove old passwords
+adb shell rm /data/system/gatekeeper.password.key
+adb shell touch /data/system/gatekeeper.password.key
+adb shell rm /data/system/gatekeeper.pattern.key
+adb shell touch /data/system/gatekeeper.password.key
+
+# Copy virgin version of locksettings DB
+adb push locksettings.db-shm /data/system/
+adb push locksettings.db-wal /data/system/
+
+adb reboot
diff --git a/reset_android_gatekeeper_password/locksettings.db-shm b/reset_android_gatekeeper_password/locksettings.db-shm
new file mode 100644
index 0000000..d2d9660
Binary files /dev/null and b/reset_android_gatekeeper_password/locksettings.db-shm differ
diff --git a/reset_android_gatekeeper_password/locksettings.db-wal b/reset_android_gatekeeper_password/locksettings.db-wal
new file mode 100644
index 0000000..88e689f
Binary files /dev/null and b/reset_android_gatekeeper_password/locksettings.db-wal differ