Skip to content

Commit

Permalink
asserts: Implemented new composable assertion API.
Browse files Browse the repository at this point in the history
This proposal implements assertions as composable sub-functions
for the `cr_assert` and `cr_expect` macros.

For instance, instead of having `cr_assert_eq(1, 2)`, the user can either
use `cr_assert(eq(1, 2))` or `cr_assert(eq(i32, 1, 2))`. This has the
advantage of simplifying the implementation of the assert macro, but
also brings to the table an improved correctness by letting the user enforce
the type of operands with a type tag, and the possibility to
pretty-print and natively compare user types without c11 or compiler-specific
constructs like _Generic or __builtin_types_compatible_p.

This also lets us handle properly special comparison cases like
ulp-based equality for IEEE floats.

Fixes #165, #182.
  • Loading branch information
Snaipe committed Jul 1, 2017
1 parent 710d930 commit d258a8b
Show file tree
Hide file tree
Showing 73 changed files with 5,523 additions and 739 deletions.
19 changes: 14 additions & 5 deletions .cmake/Modules/Capabilities.cmake
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -29,16 +29,25 @@ if (I18N AND GETTEXT_FOUND AND LIBINTL_LIB_FOUND)
set (ENABLE_NLS 1) set (ENABLE_NLS 1)
endif () endif ()


list (APPEND CMAKE_REQUIRED_DEFINITIONS
-D_GNU_SOURCE
-D_CRT_RAND_S
-DVC_EXTRALEAN
-DWIN32_LEAN_AND_MEAN)

# Check for functions # Check for functions


check_function_exists(strtok_s HAVE_STRTOK_S) check_symbol_exists(strtok_s "string.h" HAVE_STRTOK_S)
check_function_exists(strtok_r HAVE_STRTOK_R) check_symbol_exists(strtok_r "string.h" HAVE_STRTOK_R)


check_library_exists (anl getaddrinfo_a "" HAVE_GETADDRINFO_A) check_library_exists (anl getaddrinfo_a "" HAVE_GETADDRINFO_A)


check_function_exists(funopen HAVE_FUNOPEN) check_symbol_exists(funopen "stdio.h" HAVE_FUNOPEN)
check_function_exists(fopencookie HAVE_FOPENCOOKIE) check_symbol_exists(fopencookie "stdio.h" HAVE_FOPENCOOKIE)
check_function_exists(open_memstream HAVE_OPEN_MEMSTREAM) check_symbol_exists(open_memstream "stdio.h" HAVE_OPEN_MEMSTREAM)

check_symbol_exists(getcwd "unistd.h" HAVE_GETCWD)
check_symbol_exists(GetCurrentDirectory "windows.h" HAVE_GETCURRENTDIRECTORY)


check_library_exists(rt clock_gettime "time.h" HAVE_CLOCK_GETTIME_RT) check_library_exists(rt clock_gettime "time.h" HAVE_CLOCK_GETTIME_RT)
if (HAVE_CLOCK_GETTIME_RT AND NOT HAVE_LIBRT) if (HAVE_CLOCK_GETTIME_RT AND NOT HAVE_LIBRT)
Expand Down
33 changes: 33 additions & 0 deletions .cmake/Modules/FindLibgit2.cmake
Original file line number Original file line Diff line number Diff line change
@@ -0,0 +1,33 @@
# - Try to find the libgit2 library
# Once done this will define
#
# LIBGIT2_FOUND - System has libgit2
# LIBGIT2_INCLUDE_DIR - The libgit2 include directory
# LIBGIT2_LIBRARIES - The libraries needed to use libgit2
# LIBGIT2_DEFINITIONS - Compiler switches required for using libgit2


# use pkg-config to get the directories and then use these values
# in the FIND_PATH() and FIND_LIBRARY() calls
#FIND_PACKAGE(PkgConfig)
#PKG_SEARCH_MODULE(PC_LIBGIT2 libgit2)

SET(LIBGIT2_DEFINITIONS ${PC_LIBGIT2_CFLAGS_OTHER})

FIND_PATH(LIBGIT2_INCLUDE_DIR NAMES git2.h
HINTS
${PC_LIBGIT2_INCLUDEDIR}
${PC_LIBGIT2_INCLUDE_DIRS}
)

FIND_LIBRARY(LIBGIT2_LIBRARIES NAMES git2
HINTS
${PC_LIBGIT2_LIBDIR}
${PC_LIBGIT2_LIBRARY_DIRS}
)


INCLUDE(FindPackageHandleStandardArgs)
FIND_PACKAGE_HANDLE_STANDARD_ARGS(libgit2 DEFAULT_MSG LIBGIT2_LIBRARIES LIBGIT2_INCLUDE_DIR)

MARK_AS_ADVANCED(LIBGIT2_INCLUDE_DIR LIBGIT2_LIBRARIES)
26 changes: 13 additions & 13 deletions .cmake/Modules/Submodules.cmake
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -12,18 +12,18 @@ set(GIT_SUBMODULES libcsptr dyncall)
### (leave empty if you want master) ### (leave empty if you want master)


### First, get all submodules in ### First, get all submodules in
if(${GIT_SUBMODULES_CHECKOUT_QUIET}) #if(${GIT_SUBMODULES_CHECKOUT_QUIET})
execute_process( # execute_process(
COMMAND git submodule update --init --recursive # COMMAND git submodule update --init --recursive
WORKING_DIRECTORY ${PROJECT_SOURCE_DIR} # WORKING_DIRECTORY ${PROJECT_SOURCE_DIR}
OUTPUT_QUIET # OUTPUT_QUIET
ERROR_QUIET # ERROR_QUIET
) # )
else() #else()
execute_process( # execute_process(
COMMAND git submodule update --init --recursive # COMMAND git submodule update --init --recursive
WORKING_DIRECTORY ${PROJECT_SOURCE_DIR} # WORKING_DIRECTORY ${PROJECT_SOURCE_DIR}
) # )
endif() #endif()


endif() endif()
6 changes: 3 additions & 3 deletions .githooks/pre-commit
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -44,8 +44,6 @@ PARSE_EXTS=true
# FILE_EXTS=".c .h .cpp .hpp" # FILE_EXTS=".c .h .cpp .hpp"
FILE_EXTS=".c .h .cc .hh .cpp .hpp .hxx" FILE_EXTS=".c .h .cc .hh .cpp .hpp .hxx"


EXCLUDE_PATTERN="src/protocol/*.pb.*"

################################################################## ##################################################################
# There should be no need to change anything below this line. # There should be no need to change anything below this line.


Expand Down Expand Up @@ -109,7 +107,9 @@ do
fi fi


case "$file" in case "$file" in
$EXCLUDE_PATTERN) continue; src/protocol/*.pb.*) continue;;
include/*) continue;;
samples/*) continue;;
esac esac


# escape special characters in the source filename: # escape special characters in the source filename:
Expand Down
64 changes: 52 additions & 12 deletions CMakeLists.txt
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -22,19 +22,34 @@ include (Submodules)
include (Capabilities) include (Capabilities)
include (Subprojects) include (Subprojects)
include (PackageUtils) include (PackageUtils)
include (CheckCCompilerFlag)


if (NOT WIN32) check_c_compiler_flag("-fPIC" CC_HAVE_FPIC)
check_c_compiler_flag("-fvisibility=hidden" CC_HAVE_VISIBILITY)

# Linker flags are ignored by check_c_compiler_flag, so we have
# to use this workaround
set (CMAKE_REQUIRED_FLAGS "-Wl,--exclude-libs=ALL")
check_c_compiler_flag("" LINKER_HAS_EXCLUDE_LIBS)
unset (CMAKE_REQUIRED_FLAGS)

if (LINKER_HAS_EXCLUDE_LIBS)
set (CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wl,--exclude-libs=ALL")
endif ()

if (CC_HAVE_FPIC)
set (PIC_C_FLAGS "-fPIC") set (PIC_C_FLAGS "-fPIC")
endif ()

if (CC_HAVE_VISIBILITY)
set (VISI_C_FLAGS "-fvisibility=hidden") set (VISI_C_FLAGS "-fvisibility=hidden")
else ()
set (PIC_C_FLAGS "")
set (VISI_C_FLAGS "")
endif () endif ()


find_package(Libcsptr) find_package(Libcsptr)
find_package(Dyncall) find_package(Dyncall)
find_package(Nanomsg) find_package(Nanomsg)
find_package(BoxFort) find_package(BoxFort)
find_package(Libgit2)


cr_add_subproject (csptr cr_add_subproject (csptr
GIT "https://github.com/Snaipe/libcsptr#0d52904" GIT "https://github.com/Snaipe/libcsptr#0d52904"
Expand Down Expand Up @@ -82,6 +97,26 @@ cr_add_subproject (boxfort PATH dependencies/boxfort
CMAKE CMAKE
IF NOT BOXFORT_FOUND) IF NOT BOXFORT_FOUND)


cr_add_subproject (git2
GIT "git://github.com/libgit2/libgit2#v0.25.1"
OPTS
-DBUILD_SHARED_LIBS=OFF
-DBUILD_CLAR=OFF
-DUSE_ICONV=OFF
-DUSE_SSH=OFF
-DUSE_GSSAPI=OFF
-DUSE_OPENSSL=OFF
-DVALGRIND=OFF
-DCURL=OFF
-DWINHTTP=OFF
-DCMAKE_DISABLE_FIND_PACKAGE_HTTP_Parser=TRUE
-DCMAKE_DISABLE_FIND_PACKAGE_ZLIB=TRUE
-DCMAKE_DISABLE_FIND_PACKAGE_Iconv=TRUE
-DCMAKE_DISABLE_FIND_PACKAGE_Security=TRUE
"-DCMAKE_C_FLAGS=${PIC_C_FLAGS} ${VISI_C_FLAGS}"
CMAKE
IF NOT LIBGIT2_FOUND)

add_definitions(-DBXF_STATIC_LIB -DNN_STATIC_LIB) add_definitions(-DBXF_STATIC_LIB -DNN_STATIC_LIB)


cr_add_subproject (wingetopt cr_add_subproject (wingetopt
Expand Down Expand Up @@ -137,23 +172,28 @@ cr_link_subproject(criterion csptr STATIC IF NOT CSPTR_FOUND)
cr_link_subproject(criterion nanomsg STATIC IF NOT NANOMSG_FOUND) cr_link_subproject(criterion nanomsg STATIC IF NOT NANOMSG_FOUND)
cr_link_subproject(criterion dyncall_s STATIC IF NOT DYNCALL_FOUND) cr_link_subproject(criterion dyncall_s STATIC IF NOT DYNCALL_FOUND)
cr_link_subproject(criterion boxfort STATIC IF NOT BOXFORT_FOUND) cr_link_subproject(criterion boxfort STATIC IF NOT BOXFORT_FOUND)
cr_link_subproject(criterion git2 STATIC IF NOT LIBGIT2_FOUND)
cr_link_subproject(criterion wingetopt STATIC) cr_link_subproject(criterion wingetopt STATIC)


if (CSPTR_FOUND) if (CSPTR_FOUND)
include_directories("${CSPTR_INCLUDE_DIRS}") include_directories(${CSPTR_INCLUDE_DIRS})
cr_link_libraries(criterion "${CSPTR_LIBRARIES}") cr_link_libraries(criterion ${CSPTR_LIBRARIES})
endif () endif ()
if (NANOMSG_FOUND) if (NANOMSG_FOUND)
include_directories("${NANOMSG_INCLUDE_DIRS}") include_directories(${NANOMSG_INCLUDE_DIRS})
cr_link_libraries(criterion "${NANOMSG_LIBRARIES}" IF NANOMSG_FOUND) cr_link_libraries(criterion ${NANOMSG_LIBRARIES})
endif () endif ()
if (DYNCALL_FOUND) if (DYNCALL_FOUND)
include_directories("${DYNCALL_INCLUDE_DIRS}") include_directories(${DYNCALL_INCLUDE_DIRS})
cr_link_libraries(criterion "${DYNCALL_LIBRARIES}" IF DYNCALL_FOUND) cr_link_libraries(criterion ${DYNCALL_LIBRARIES})
endif () endif ()
if (BOXFORT_FOUND) if (BOXFORT_FOUND)
include_directories("${BOXFORT_INCLUDE_DIRS}") include_directories(${BOXFORT_INCLUDE_DIRS})
cr_link_libraries(criterion "${BOXFORT_LIBRARIES}" IF BOXFORT_FOUND) cr_link_libraries(criterion ${BOXFORT_LIBRARIES})
endif ()
if (LIBGIT2_FOUND)
include_directories(${LIBGIT2_INCLUDE_DIRS})
cr_link_libraries(criterion ${LIBGIT2_LIBRARIES})
endif () endif ()


cr_link_libraries(criterion pthread IF NOT WIN32) cr_link_libraries(criterion pthread IF NOT WIN32)
Expand Down
1 change: 1 addition & 0 deletions appveyor.yml
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ environment:
- COMPILER: mingw - COMPILER: mingw
GENERATOR: "MSYS Makefiles" GENERATOR: "MSYS Makefiles"
BUILD_FLAGS: -j2 BUILD_FLAGS: -j2
CPPFLAGS: -D__USE_MINGW_ANSI_STDIO
- COMPILER: msvc - COMPILER: msvc
GENERATOR: "Visual Studio 14 2015 Win64" GENERATOR: "Visual Studio 14 2015 Win64"
CFLAGS: /MP CFLAGS: /MP
Expand Down
2 changes: 1 addition & 1 deletion dependencies/nanopb
Submodule nanopb updated 115 files
2 changes: 1 addition & 1 deletion doc/Doxyfile
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -2018,7 +2018,7 @@ INCLUDE_FILE_PATTERNS =
# recursively expanded use the := operator instead of the = operator. # recursively expanded use the := operator instead of the = operator.
# This tag requires that the tag ENABLE_PREPROCESSING is set to YES. # This tag requires that the tag ENABLE_PREPROCESSING is set to YES.


PREDEFINED = __GNUC__ __cplusplus PREDEFINED = __GNUC__ __cplusplus CRITERION_DOCGEN


# If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then this # If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then this
# tag can be used to specify a list of macro names that should be expanded. The # tag can be used to specify a list of macro names that should be expanded. The
Expand Down
29 changes: 29 additions & 0 deletions doc/_static/style.css
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -23,3 +23,32 @@
.container > dl { .container > dl {
margin-bottom: 0 !important; /* Dirty hack */ margin-bottom: 0 !important; /* Dirty hack */
} }

/* Don't indent group contents */
.group dd {
margin-left: 0;
}

/* Hide ugly group title block & group rubrics */
.group > dt,
p.breathe-sectiondef-title {
display: none;
}

/* Slightly indent content for doxygen entries */
dl.macro > dd {
margin-left: 30px;
}

/* Format parameters better */
.breatheparameterlist {
padding-left: 0;
list-style-type: none;
}

.breatheparameterlist > li > code,
.breatheparameterlist > li > code > .pre {
background: transparent;
font-family: inherit;
font-weight: bold;
}
42 changes: 10 additions & 32 deletions doc/assert.rst
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -12,40 +12,18 @@ macros to this list. Hence only ``assert`` macros are represented here.
All ``assert`` macros may take an optional ``printf`` format string and All ``assert`` macros may take an optional ``printf`` format string and
parameters. parameters.


Base Assertions Assertion API
----------------- -------------


.. doxygengroup:: BaseAsserts .. doxygengroup:: AssertAPI


Common Assertions Assertion Criteria
----------------- ------------------


.. doxygengroup:: CommonBinAsserts .. doxygengroup:: Criteria
.. doxygengroup:: CommonUnaryAsserts .. doxygengroup:: TaggedCriteria
.. doxygengroup:: FloatAsserts


String Assertions Tags
----------------- ----


.. doxygengroup:: StringAsserts .. doxygengroup:: Tags

Wide String Assertions
----------------------

.. doxygengroup:: WideStringAsserts

Array Assertions
-----------------

.. doxygengroup:: ArrayAsserts
.. doxygengroup:: SafeArrCmpAsserts

Exception Assertions
--------------------

.. doxygengroup:: ExceptionAsserts

File Assertions
---------------

.. doxygengroup:: FileAsserts
14 changes: 8 additions & 6 deletions doc/conf.py
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -14,12 +14,10 @@
# If your documentation needs a minimal Sphinx version, state it here. # If your documentation needs a minimal Sphinx version, state it here.
#needs_sphinx = '1.0' #needs_sphinx = '1.0'


# hack for readthedocs to cause it to run doxygen first def generate_doxygen_xml(app):
# https://github.com/rtfd/readthedocs.org/issues/388 from subprocess import call
on_rtd = os.environ.get('READTHEDOCS', None) == 'True' doxdir = os.path.abspath(os.path.dirname(__file__))
if on_rtd: call('cd %s; doxygen' % doxdir, shell=True)
from subprocess import call
call('doxygen')


# Add any Sphinx extension module names here, as strings. They can be # Add any Sphinx extension module names here, as strings. They can be
# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom # extensions coming with Sphinx (named 'sphinx.ext.*') or your custom
Expand Down Expand Up @@ -306,3 +304,7 @@
from pygments.lexers.c_cpp import CLexer from pygments.lexers.c_cpp import CLexer


lexers['c'] = CLexer(startinline=True) lexers['c'] = CLexer(startinline=True)

def setup(app):
# Add hook for building doxygen xml when needed
app.connect("builder-inited", generate_doxygen_xml)
7 changes: 7 additions & 0 deletions include/criterion/internal/asprintf-compat.h
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -30,6 +30,8 @@
# include <stdarg.h> # include <stdarg.h>
#endif #endif


#include <stddef.h>

#include "common.h" #include "common.h"


CR_BEGIN_C_API CR_BEGIN_C_API
Expand All @@ -39,6 +41,11 @@ CR_API int cr_asprintf(char **strp, const char *fmt, ...);
CR_API int cr_vasprintf(char **strp, const char *fmt, va_list ap); CR_API int cr_vasprintf(char **strp, const char *fmt, va_list ap);
CR_API void cr_asprintf_free(char *buf); CR_API void cr_asprintf_free(char *buf);


CR_API int cri_fmt_bprintf(char **buf, size_t *offset, size_t *sz,
const char *fmt, ...);

CR_API char *cri_strtok_r(char *str, const char *delim, char **saveptr);

CR_END_C_API CR_END_C_API


#endif /* !CRITERION_ASPRINTF_COMPAT_H_ */ #endif /* !CRITERION_ASPRINTF_COMPAT_H_ */
Loading

0 comments on commit d258a8b

Please sign in to comment.