style: Added and enforce uncrustify config

This commit is contained in:
Snaipe 2016-09-05 21:32:57 +02:00
parent ec7cbe2a18
commit d2a4124b87
130 changed files with 4155 additions and 3342 deletions

View file

@ -0,0 +1,48 @@
#!/bin/sh
# Provide the canonicalize filename (physical filename with out any symlinks)
# like the GNU version readlink with the -f option regardless of the version of
# readlink (GNU or BSD).
# This file is part of a set of unofficial pre-commit hooks available
# at github.
# Link: https://github.com/githubbrowser/Pre-commit-hooks
# Contact: David Martin, david.martin.mailbox@googlemail.com
###########################################################
# There should be no need to change anything below this line.
# Canonicalize by recursively following every symlink in every component of the
# specified filename. This should reproduce the results of the GNU version of
# readlink with the -f option.
#
# Reference: http://stackoverflow.com/questions/1055671/how-can-i-get-the-behavior-of-gnus-readlink-f-on-a-mac
canonicalize_filename () {
local target_file="$1"
local physical_directory=""
local result=""
# Need to restore the working directory after work.
local working_dir="`pwd`"
cd -- "$(dirname -- "$target_file")"
target_file="$(basename -- "$target_file")"
# Iterate down a (possible) chain of symlinks
while [ -L "$target_file" ]
do
target_file="$(readlink -- "$target_file")"
cd -- "$(dirname -- "$target_file")"
target_file="$(basename -- "$target_file")"
done
# Compute the canonicalized name by finding the physical path
# for the directory we're in and appending the target file.
physical_directory="`pwd -P`"
result="$physical_directory/$target_file"
# restore the working directory after work.
cd -- "$working_dir"
echo "$result"
}

4
.githooks/install.sh Executable file
View file

@ -0,0 +1,4 @@
#!/bin/sh
rm -Rf .git/hooks
ln -s ../.githooks .git/hooks

165
.githooks/pre-commit Executable file
View file

@ -0,0 +1,165 @@
#!/bin/sh
# git pre-commit hook that runs an Uncrustify stylecheck.
# Features:
# - abort commit when commit does not comply with the style guidelines
# - create a patch of the proposed style changes
#
# More info on Uncrustify: http://uncrustify.sourceforge.net/
# This file is part of a set of unofficial pre-commit hooks available
# at github.
# Link: https://github.com/githubbrowser/Pre-commit-hooks
# Contact: David Martin, david.martin.mailbox@googlemail.com
##################################################################
# CONFIGURATION
# set uncrustify path or executable
# UNCRUSTIFY="/usr/bin/uncrustify"
UNCRUSTIFY="uncrustify"
# set uncrustify config location
# CONFIG="/home/user/.config/uncrustify.cfg"
CONFIG=".uncrustify.cfg"
# the source language: C, CPP, D, CS, JAVA, PAWN, VALA, OC, OC+
# use AUTO to let Uncrustify decide which language a given file uses.
# the detected language is printed to the console when Uncrustify is called.
# override if the automatic detection seems off.
# SOURCE_LANGUAGE="AUTO"
SOURCE_LANGUAGE="AUTO"
# remove any older patches from previous commits. Set to true or false.
# DELETE_OLD_PATCHES=false
DELETE_OLD_PATCHES=false
# only parse files with the extensions in FILE_EXTS. Set to true or false.
# if false every changed file in the commit will be parsed with Uncrustify.
# if true only files matching one of the extensions are parsed with Uncrustify.
# PARSE_EXTS=true
PARSE_EXTS=true
# file types to parse. Only effective when PARSE_EXTS is true.
# FILE_EXTS=".c .h .cpp .hpp"
FILE_EXTS=".c .h .cc .hh .cpp .hpp .hxx"
##################################################################
# There should be no need to change anything below this line.
. "$(dirname -- "$0")/canonicalize_filename.sh"
# exit on error
set -e
# check whether the given file matches any of the set extensions
matches_extension() {
local filename="$(basename -- "$1")"
local extension=".${filename##*.}"
local ext
for ext in $FILE_EXTS; do [ "$ext" = "$extension" ] && return 0; done
return 1
}
# necessary check for initial commit
if git rev-parse --verify HEAD >/dev/null 2>&1 ; then
against=HEAD
else
# Initial commit: diff against an empty tree object
against=4b825dc642cb6eb9a060e54bf8d69288fbee4904
fi
# make sure the config file and executable are correctly set
if [ ! -f "$CONFIG" ] ; then
printf "Error: uncrustify config file not found.\n"
printf "Set the correct path in $(canonicalize_filename "$0").\n"
exit 1
fi
if ! command -v "$UNCRUSTIFY" > /dev/null ; then
printf "Error: uncrustify executable not found.\n"
printf "Set the correct path in $(canonicalize_filename "$0").\n"
exit 1
fi
# create a filename to store our generated patch
prefix="pre-commit-uncrustify"
suffix="$(date +%C%y-%m-%d_%Hh%Mm%Ss)"
patch="/tmp/$prefix-$suffix.patch"
# clean up any older uncrustify patches
$DELETE_OLD_PATCHES && rm -f /tmp/$prefix*.patch
# create one patch containing all changes to the files
# sed to remove quotes around the filename, if inserted by the system
# (done sometimes, if the filename contains special characters, like the quote itself)
git diff-index --cached --diff-filter=ACMR --name-only $against -- | \
sed -e 's/^"\(.*\)"$/\1/' | \
while read file
do
# ignore file if we do check for file extensions and the file
# does not match any of the extensions specified in $FILE_EXTS
if $PARSE_EXTS && ! matches_extension "$file"; then
continue;
fi
# escape special characters in the source filename:
# - '\': backslash needs to be escaped
# - '*': used as matching string => '*' would mean expansion
# (curiously, '?' must not be escaped)
# - '[': used as matching string => '[' would mean start of set
# - '|': used as sed split char instead of '/', so it needs to be escaped
# in the filename
# printf %s particularly important if the filename contains the % character
file_escaped_source=$(printf "%s" "$file" | sed -e 's/[\*[|]/\\&/g')
# escape special characters in the target filename:
# phase 1 (characters escaped in the output diff):
# - '\': backslash needs to be escaped in the output diff
# - '"': quote needs to be escaped in the output diff if present inside
# of the filename, as it used to bracket the entire filename part
# phase 2 (characters escaped in the match replacement):
# - '\': backslash needs to be escaped again for sed itself
# (i.e. double escaping after phase 1)
# - '&': would expand to matched string
# - '|': used as sed split char instead of '/'
# printf %s particularly important if the filename contains the % character
file_escaped_target=$(printf "%s" "$file" | sed -e 's/[\"]/\\&/g' -e 's/[\&|]/\\&/g')
# Uncrustify detects the language automatically if it is not specified
language_option=""
if [ "$SOURCE_LANGUAGE" != "AUTO" ] ; then
language_option="-l $SOURCE_LANGUAGE"
fi
# uncrustify our sourcefile, create a patch with diff and append it to our $patch
# The sed call is necessary to transform the patch from
# --- $file timestamp
# +++ - timestamp
# to both lines working on the same file and having a a/ and b/ prefix.
# Else it can not be applied with 'git apply'.
"$UNCRUSTIFY" -c "$CONFIG" -f "$file" $language_option | \
git --no-pager diff --color=always --no-index -- "$file" - | \
sed -e "1s|--- $file_escaped_source|--- \"a/$file_escaped_target\"|" -e "2s|+++ -|+++ \"b/$file_escaped_target\"|" >> "$patch"
done
# if no patch has been generated all is ok, clean up the file stub and exit
if [ ! -s "$patch" ] ; then
printf "Files in this commit comply with the uncrustify rules.\n"
rm -f "$patch"
exit 0
fi
# a patch has been created, notify the user and exit
printf "\nThe following differences were found between the code to commit "
printf "and the uncrustify rules:\n\n"
cat "$patch"
printf "\nYou can apply these changes with:\n git apply $patch\n"
printf "(may need to be called from the root directory of your repository)\n"
printf "Aborting commit. Apply changes and commit again or skip checking with"
printf " --no-verify (not recommended).\n"
exit 1

238
.uncrustify.cfg Normal file
View file

@ -0,0 +1,238 @@
#
# uncrustify config file (initially based on the linux kernel coding style)
#
input_tab_size = 4 # original tab size
output_tab_size = 4 # new tab size
newlines = lf # \n
utf8_force = true
utf8_bom = remove
# Indent
indent_with_tabs = 0 # 1=indent to level only, 2=indent with tabs
indent_columns = 4 # indents are 4 cols
indent_continue = 8 # line continuations are indented by 8 columns
indent_label = -4 # pos: absolute col, neg: relative column
indent_xml_string = 2 # embedded XML indents are 2 cols
indent_ctor_init = 4 # indent c++ ctor initializer list
indent_switch_case = 4 # indent 'case' inside switch statements
indent_namespace = false
indent_extern = false
indent_class = false
indent_class_colon = true
indent_access_spec_body = true
# Newlines
nl_max = 2 # no duplicate blank lines
nl_func_paren = remove # "int foo()" vs "int foo\n()"
nl_func_decl_start = ignore
nl_func_decl_empty = remove
nl_func_decl_args = ignore
nl_func_decl_end = remove
nl_enum_brace = remove # "enum {" vs "enum \n {"
nl_union_brace = remove # "union {" vs "union \n {"
nl_struct_brace = remove # "struct {" vs "struct \n {"
nl_do_brace = remove # "do {" vs "do \n {"
nl_if_brace = remove # "if () {" vs "if () \n {"
nl_for_brace = remove # "for () {" vs "for () \n {"
nl_else_brace = remove # "else {" vs "else \n {"
nl_while_brace = remove # "while () {" vs "while () \n {"
nl_switch_brace = remove # "switch () {" vs "switch () \n {"
nl_brace_while = remove # "} while" vs "} \n while" - cuddle while
nl_brace_else = remove # "} else" vs "} \n else" - cuddle else
nl_namespace_brace = force # "namespace name {" vs "namespace name \n {"
nl_func_var_def_blk = 1
nl_fcall_brace = remove # "list_for_each() {" vs "list_for_each()\n{"
nl_fdef_brace = add # "int foo() {" vs "int foo()\n{"
nl_after_label_colon = false # "fail:\nfree(foo);" vs "fail: free(foo);"
nl_start_of_file = remove
nl_end_of_file = force
nl_end_of_file_min = 1
nl_comment_func_def = 1
nl_assign_leave_one_liners = true
nl_class_leave_one_liners = true
nl_enum_leave_one_liners = true
nl_getset_leave_one_liners = true
nl_func_leave_one_liners = true
nl_cpp_lambda_leave_one_liners = true
nl_while_leave_one_liners = false
nl_if_leave_one_liners = false
nl_multi_line_define = true
nl_func_call_start_multi_line = false
nl_func_call_end_multi_line = false
# Source code modifications
mod_paren_on_return = remove # "return 1;" vs "return (1);"
mod_full_brace_if = remove # "if (a) a--;" vs "if (a) { a--; }"
mod_full_brace_if_chain = true
mod_full_brace_for = remove # "for () a--;" vs "for () { a--; }"
mod_full_brace_do = force # "do a--; while ();" vs "do { a--; } while ();"
mod_full_brace_while = remove # "while (a) a--;" vs "while (a) { a--; }"
mod_full_brace_nl = 3 # don't remove if more than 3 newlines
# Spacing
sp_addr = remove
sp_after_angle = force
sp_after_byref = remove
sp_after_byref_func = remove
sp_after_cast = force # "(int) a" vs "(int)a"
sp_after_class_colon = force
sp_after_comma = force
sp_after_dc = remove
sp_after_new = force
sp_after_operator = remove
sp_after_operator_sym = remove
sp_after_ptr_star = remove # "int *foo" vs "int * foo"
sp_after_ptr_star_func = remove
sp_after_semi = force
sp_after_semi_for = force
sp_after_semi_for_empty = remove
sp_after_sparen = force # "if () {" vs "if (){"
sp_after_type = force
sp_angle_paren = remove
sp_angle_shift = ignore
sp_angle_word = force
sp_arith = force
sp_assign = add
sp_assign_default = force
sp_attribute_paren = remove
sp_balance_nested_parens = false
sp_before_angle = remove
sp_before_byref = force
sp_before_byref_func = force
sp_before_case_colon = remove
sp_before_class_colon = force
sp_before_comma = remove
sp_before_dc = remove
sp_before_ellipsis = remove
sp_before_nl_cont = force
sp_before_ptr_star = force # "int*" vs "int *"
sp_before_ptr_star_func = force
sp_before_semi = remove
sp_before_semi_for = remove
sp_before_semi_for_empty = remove
sp_before_sparen = force # "if (" vs "if("
sp_before_square = remove
sp_before_tr_emb_cmt = force
sp_before_unnamed_byref = force
sp_between_ptr_star = remove # "int **" vs "int * *"
sp_bool = force
sp_brace_catch = force
sp_brace_else = force # "}else" vs "} else"
sp_brace_finally = force
sp_brace_typedef = force
sp_case_label = force
sp_catch_brace = force
sp_catch_paren = force
sp_cmt_cpp_start = force
sp_compare = force
sp_cond_colon = add
sp_cond_question = add
sp_cpp_cast_paren = force
sp_defined_paren = force
sp_deref = remove
sp_else_brace = force # "else{" vs "else {"
sp_endif_cmt = force
sp_enum_assign = force
sp_finally_brace = force
sp_fparen_brace = force
sp_func_call_paren = remove # "foo (" vs "foo("
sp_func_call_user_paren = remove
sp_func_class_paren = remove
sp_func_def_paren = remove # "int foo (){" vs "int foo(){"
sp_func_proto_paren = remove # "int foo ();" vs "int foo();"
sp_getset_brace = force
sp_incdec = remove
sp_inside_angle = remove
sp_inside_braces = force # "{ 1 }" vs "{1}"
sp_inside_braces_empty = remove
sp_inside_braces_enum = force # "{ 1 }" vs "{1}"
sp_inside_braces_struct = force # "{ 1 }" vs "{1}"
sp_inside_fparen = remove
sp_inside_fparens = remove
sp_inside_paren = remove
sp_inside_paren_cast = remove
sp_inside_sparen = remove
sp_inside_square = remove
sp_inv = remove
sp_macro = force
sp_macro_func = force
sp_member = remove
sp_not = remove
sp_num_before_tr_emb_cmt = 1
sp_paren_brace = force
sp_paren_comma = ignore
sp_paren_paren = remove # "((" vs "( ("
sp_pp_concat = force
sp_pp_stringify = remove
sp_return_paren = force # "return (1);" vs "return(1);"
sp_sign = remove
sp_sizeof_paren = force # "sizeof (int)" vs "sizeof(int)"
sp_sparen_brace = force
sp_special_semi = remove
sp_square_fparen = remove
sp_template_angle = add
sp_throw_paren = force
sp_try_brace = force
cmt_sp_before_star_cont = 0
cmt_sp_after_star_cont = 1
# Positioning
pos_arith = lead
pos_assign = trail
pos_bool = lead
pos_compare = lead
pos_conditional = lead
pos_comma = trail
pos_class_comma = trail
pos_class_colon = lead
# Alignment
align_with_tabs = false # use tabs to align
align_on_tabstop = false # align on tabstops
align_enum_equ_span = 4 # '=' in enum definition
align_nl_cont = true
align_assign_span = 0
align_struct_init_span = 3 # align stuff in a structure init '= { }'
align_right_cmt_span = 3
align_pp_define_span = 8
align_pp_define_gap = 4
align_func_params = false
align_var_struct_span = 0
# Comment
cmt_indent_multi = true
cmt_c_group = false
cmt_c_nl_start = false
cmt_c_nl_end = false
cmt_cpp_group = true
cmt_cpp_nl_start = false
cmt_cpp_nl_end = false
cmt_cpp_to_c = true
cmt_star_cont = false
cmt_multi_check_last = true
eat_blanks_after_open_brace = true
eat_blanks_before_close_brace = true
# Preprocessor
pp_indent = remove
pp_space = force
pp_space_count = 1
# Misc
set cpp_cast nonstd # nonstd cast attributes
set func_call_user _ N_ # gettext macros
set attribute CR_FORMAT CR_API CR_PURE CR_INLINE

View file

@ -26,9 +26,9 @@
* @brief Functions to abort and continue tests
*****************************************************************************/
#ifndef CRITERION_ABORT_H_
# define CRITERION_ABORT_H_
#define CRITERION_ABORT_H_
# include "internal/common.h"
#include "internal/common.h"
CR_BEGIN_C_API

View file

@ -26,16 +26,16 @@
* @brief Test intern memory managment
*****************************************************************************/
#ifndef CRITERION_ALLOC_H_
# define CRITERION_ALLOC_H_
#define CRITERION_ALLOC_H_
# ifdef __cplusplus
# include <memory>
# include <cstddef>
#ifdef __cplusplus
# include <memory>
# include <cstddef>
using std::size_t;
# else
# include <stddef.h>
# endif
# include "internal/common.h"
#else
# include <stddef.h>
#endif
#include "internal/common.h"
CR_BEGIN_C_API
@ -92,177 +92,187 @@ CR_API void cr_free(void *ptr);
CR_END_C_API
# ifdef __cplusplus
# include <type_traits>
#ifdef __cplusplus
# include <type_traits>
namespace criterion {
namespace criterion
{
void *(*const malloc)(size_t) = cr_malloc;
void(*const free)(void *) = cr_free;
void *(*const calloc)(size_t, size_t) = cr_calloc;
void *(*const realloc)(void *, size_t) = cr_realloc;
void *(*const malloc)(size_t) = cr_malloc;
void (*const free)(void *) = cr_free;
void *(*const calloc)(size_t, size_t) = cr_calloc;
void *(*const realloc)(void *, size_t) = cr_realloc;
/**
* Allocates and construct a new object.
*
* It is undefined behaviour to access a pointer returned by the new
* operator inside a test or its setup and teardown functions;
* new_obj must be used in its place for this purpose.
*
* This function is semantically identical to the new operator.
*
* @tparam T The type of the object to construct
* @param[in] params The constructor parameters of T.
* @returns The pointer to the newly constructed object.
*/
template <typename T, typename... Params>
T *new_obj(Params... params)
{
T *obj = static_cast<T *>(cr_malloc(sizeof (T)));
/**
* Allocates and construct a new object.
*
* It is undefined behaviour to access a pointer returned by the new
* operator inside a test or its setup and teardown functions;
* new_obj must be used in its place for this purpose.
*
* This function is semantically identical to the new operator.
*
* @tparam T The type of the object to construct
* @param[in] params The constructor parameters of T.
* @returns The pointer to the newly constructed object.
*/
template<typename T, typename... Params>
T* new_obj(Params... params) {
T* obj = static_cast<T*>(cr_malloc(sizeof (T)));
new (obj) T(params...);
return obj;
}
new (obj) T(params...);
return obj;
}
/**
* Allocates and construct a new array of primitive types
*
* It is undefined behaviour to access a pointer returned by the new[]
* operator inside a test or its setup and teardown functions;
* new_arr must be used in its place for this purpose.
*
* This function is semantically identical to the new[] operator.
*
* @tparam T The compound type of the array to construct
* @param[in] len The length of the array.
* @returns The pointer to the newly constructed array.
*/
template<typename T>
typename std::enable_if<std::is_fundamental<T>::value>::type*
new_arr(size_t len) {
void *ptr = cr_malloc(sizeof (size_t) + sizeof (T) * len);
*(reinterpret_cast<size_t*>(ptr)) = len;
T* arr = reinterpret_cast<T*>(reinterpret_cast<size_t*>(ptr) + 1);
return arr;
}
/**
* Allocates and construct a new array of primitive types
*
* It is undefined behaviour to access a pointer returned by the new[]
* operator inside a test or its setup and teardown functions;
* new_arr must be used in its place for this purpose.
*
* This function is semantically identical to the new[] operator.
*
* @tparam T The compound type of the array to construct
* @param[in] len The length of the array.
* @returns The pointer to the newly constructed array.
*/
template <typename T>
typename std::enable_if<std::is_fundamental<T>::value>::type
* new_arr(size_t len) {
void *ptr = cr_malloc(sizeof (size_t) + sizeof (T) * len);
/**
* Allocates and construct a new array of object types
*
* It is undefined behaviour to access a pointer returned by the new[]
* operator inside a test or its setup and teardown functions;
* new_arr must be used in its place for this purpose.
*
* This function is semantically identical to the new[] operator.
*
* @tparam T The compound type of the array to construct
* @param[in] len The length of the array.
* @returns The pointer to the newly constructed array.
*/
template<typename T>
T* new_arr(size_t len) {
void *ptr = cr_malloc(sizeof (size_t) + sizeof (T) * len);
*(reinterpret_cast<size_t*>(ptr)) = len;
*(reinterpret_cast<size_t *>(ptr)) = len;
T *arr = reinterpret_cast<T *>(reinterpret_cast<size_t *>(ptr) + 1);
return arr;
}
T* arr = reinterpret_cast<T*>(reinterpret_cast<size_t*>(ptr) + 1);
for (size_t i = 0; i < len; ++i)
new (arr + i) T();
return arr;
}
/**
* Allocates and construct a new array of object types
*
* It is undefined behaviour to access a pointer returned by the new[]
* operator inside a test or its setup and teardown functions;
* new_arr must be used in its place for this purpose.
*
* This function is semantically identical to the new[] operator.
*
* @tparam T The compound type of the array to construct
* @param[in] len The length of the array.
* @returns The pointer to the newly constructed array.
*/
template <typename T>
T *new_arr(size_t len)
{
void *ptr = cr_malloc(sizeof (size_t) + sizeof (T) * len);
/**
* Destroys and frees an object allocated by new_obj.
*
* This function is semantically identical to the delete operator.
*
* @tparam T The type of the object to construct
* @param[in] ptr The object to destroy.
*/
template<typename T>
void delete_obj(T* ptr) {
ptr->~T();
cr_free(ptr);
}
*(reinterpret_cast<size_t *>(ptr)) = len;
/**
* Destroys and frees an array allocated by delete_arr.
*
* This function is semantically identical to the delete[] operator.
*
* @tparam T The type of the object to construct
* @param[in] ptr The object to destroy.
*/
template<typename T>
void delete_arr(typename std::enable_if<std::is_fundamental<T>::value>::type* ptr) {
cr_free(ptr);
}
T *arr = reinterpret_cast<T *>(reinterpret_cast<size_t *>(ptr) + 1);
for (size_t i = 0; i < len; ++i)
new (arr + i)T();
return arr;
}
/**
* Destroys and frees an array allocated by delete_arr.
*
* This function is semantically identical to the delete[] operator.
*
* @tparam T The type of the object to construct
* @param[in] ptr The object to destroy.
*/
template<typename T>
void delete_arr(T* ptr) {
size_t *ptr_ = reinterpret_cast<size_t*>(ptr);
size_t len = *(ptr_ - 1);
T* arr = reinterpret_cast<T*>(ptr_);
for (size_t i = 0; i < len; ++i)
arr[i].~T();
cr_free(ptr_ - 1);
}
/**
* Destroys and frees an object allocated by new_obj.
*
* This function is semantically identical to the delete operator.
*
* @tparam T The type of the object to construct
* @param[in] ptr The object to destroy.
*/
template <typename T>
void delete_obj(T *ptr)
{
ptr->~T();
cr_free(ptr);
}
/**
* Allocator for use in the STL.
*
* This internally uses calls to the cr_malloc function family, which
* means that STL collections can be safely used inside tests or
* setup/teardown functions if this allocator is used.
*/
template<typename T>
struct allocator {
typedef T value_type;
typedef value_type* pointer;
typedef const value_type* const_pointer;
typedef value_type& reference;
typedef const value_type& const_reference;
typedef std::size_t size_type;
typedef std::ptrdiff_t difference_type;
/**
* Destroys and frees an array allocated by delete_arr.
*
* This function is semantically identical to the delete[] operator.
*
* @tparam T The type of the object to construct
* @param[in] ptr The object to destroy.
*/
template <typename T>
void delete_arr(typename std::enable_if<std::is_fundamental<T>::value>::type *ptr)
{
cr_free(ptr);
}
template<typename U>
struct rebind {
typedef allocator<U> other;
};
/**
* Destroys and frees an array allocated by delete_arr.
*
* This function is semantically identical to the delete[] operator.
*
* @tparam T The type of the object to construct
* @param[in] ptr The object to destroy.
*/
template <typename T>
void delete_arr(T *ptr)
{
size_t *ptr_ = reinterpret_cast<size_t *>(ptr);
size_t len = *(ptr_ - 1);
T *arr = reinterpret_cast<T *>(ptr_);
inline explicit allocator() {}
inline ~allocator() {}
inline explicit allocator(allocator const&) {}
template<typename U>
inline explicit allocator(allocator<U> const&) {}
for (size_t i = 0; i < len; ++i)
arr[i].~T();
cr_free(ptr_ - 1);
}
inline pointer address(reference r) { return &r; }
inline const_pointer address(const_reference r) { return &r; }
/**
* Allocator for use in the STL.
*
* This internally uses calls to the cr_malloc function family, which
* means that STL collections can be safely used inside tests or
* setup/teardown functions if this allocator is used.
*/
template <typename T>
struct allocator {
typedef T value_type;
typedef value_type *pointer;
typedef const value_type *const_pointer;
typedef value_type &reference;
typedef const value_type &const_reference;
typedef std::size_t size_type;
typedef std::ptrdiff_t difference_type;
inline pointer allocate(size_type cnt, typename std::allocator<void>::const_pointer = 0) {
return reinterpret_cast<pointer>(cr_malloc(cnt * sizeof (T)));
}
inline void deallocate(pointer p, size_type) { cr_free(p); }
inline size_type max_size() const {
return size_type(-1) / sizeof(T);
}
inline void construct(pointer p, const T& t) { new(p) T(t); }
inline void construct(pointer p, T&& t) { new (p) T(std::move(t)); }
inline void destroy(pointer p) { p->~T(); }
inline bool operator==(allocator const&) { return true; }
inline bool operator!=(allocator const& a) { return !operator==(a); }
template <typename U>
struct rebind {
typedef allocator<U> other;
};
inline explicit allocator() {}
inline ~allocator() {}
inline explicit allocator(allocator const &) {}
template <typename U>
inline explicit allocator(allocator<U> const &) {}
inline pointer address(reference r) { return &r; }
inline const_pointer address(const_reference r) { return &r; }
inline pointer allocate(size_type cnt, typename std::allocator<void>::const_pointer = 0)
{
return reinterpret_cast<pointer>(cr_malloc(cnt * sizeof (T)));
}
inline void deallocate(pointer p, size_type) { cr_free(p); }
inline size_type max_size() const
{
return size_type(-1) / sizeof (T);
}
inline void construct(pointer p, const T &t) { new(p) T(t); }
inline void construct(pointer p, T &&t) { new (p) T(std::move(t)); }
inline void destroy(pointer p) { p->~T(); }
inline bool operator==(allocator const &) { return true; }
inline bool operator!=(allocator const &a) { return !operator==(a); }
};
}
# endif
#endif
#endif /* !CRITERION_ALLOC_H_ */

View file

@ -27,11 +27,11 @@
* @brief Assertion API
*****************************************************************************/
#ifndef CRITERION_ASSERT_H_
# define CRITERION_ASSERT_H_
#define CRITERION_ASSERT_H_
# ifdef __cplusplus
# include <algorithm>
# endif
#ifdef __cplusplus
# include <algorithm>
#endif
/**
* @defgroup BaseAsserts Base assertions
@ -49,14 +49,14 @@
* @param[in] ... (optional) format string parameters
*
*****************************************************************************/
# define cr_assert_fail(FormatString, ...) <internal>
/**
* Skips the test
*
* The test is marked as skipped and the execution of the function is aborted.
*
*****************************************************************************/
# define cr_skip_test(FormatString, ...) <internal>
#define cr_assert_fail(FormatString, ...) < internal
> /**
* Skips the test
*
* The test is marked as skipped and the execution of the function is aborted.
*
*****************************************************************************/
#define cr_skip_test(FormatString, ...) < internal >
/**
* Fails always.
@ -69,7 +69,7 @@
* @param[in] ... (optional) format string parameters
*
*****************************************************************************/
# define cr_expect_fail(FormatString, ...) <internal>
#define cr_expect_fail(FormatString, ...) < internal >
/**
* Passes if Condition is true
@ -85,7 +85,7 @@
* @param[in] ... (optional) format string parameters
*
*****************************************************************************/
# define cr_assert(Condition, FormatString, ...) <internal>
#define cr_assert(Condition, FormatString, ...) < internal >
/**
* Passes if Condition is true
@ -100,7 +100,7 @@
* @param[in] ... (optional) format string parameters
*
*****************************************************************************/
# define cr_expect(Condition, FormatString, ...) <internal>
#define cr_expect(Condition, FormatString, ...) < internal >
/**
* Passes if Condition is false
@ -116,7 +116,7 @@
* @param[in] ... (optional) format string parameters
*
*****************************************************************************/
# define cr_assert_not(Condition, FormatString, ...) <internal>
#define cr_assert_not(Condition, FormatString, ...) < internal >
/**
* Passes if Condition is false
@ -131,7 +131,7 @@
* @param[in] ... (optional) format string parameters
*
*****************************************************************************/
# define cr_expect_not(Condition, FormatString, ...) <internal>
#define cr_expect_not(Condition, FormatString, ...) < internal >
/**@}*/
@ -157,7 +157,7 @@
* @param[in] ... (optional) format string parameters
*
*****************************************************************************/
# define cr_assert_eq(Actual, Expected, FormatString, ...) <internal>
#define cr_assert_eq(Actual, Expected, FormatString, ...) < internal >
/**
* Passes if Actual is equal to Expected
@ -175,7 +175,7 @@
* @param[in] ... (optional) format string parameters
*
*****************************************************************************/
# define cr_expect_eq(Actual, Expected, FormatString, ...) <internal>
#define cr_expect_eq(Actual, Expected, FormatString, ...) < internal >
/**
* Passes if Actual is not equal to Unexpected
@ -194,7 +194,7 @@
* @param[in] ... (optional) format string parameters
*
*****************************************************************************/
# define cr_assert_neq(Actual, Unexpected, FormatString, ...) <internal>
#define cr_assert_neq(Actual, Unexpected, FormatString, ...) < internal >
/**
* Passes if Actual is not equal to Unexpected
@ -212,7 +212,7 @@
* @param[in] ... (optional) format string parameters
*
*****************************************************************************/
# define cr_expect_neq(Actual, Unexpected, FormatString, ...) <internal>
#define cr_expect_neq(Actual, Unexpected, FormatString, ...) < internal >
/**
* Passes if Actual is less than Reference
@ -231,7 +231,7 @@
* @param[in] ... (optional) format string parameters
*
*****************************************************************************/
# define cr_assert_lt(Actual, Reference, FormatString, ...) <internal>
#define cr_assert_lt(Actual, Reference, FormatString, ...) < internal >
/**
* Passes if Actual is less than Reference
@ -249,7 +249,7 @@
* @param[in] ... (optional) format string parameters
*
*****************************************************************************/
# define cr_expect_lt(Actual, Reference, FormatString, ...) <internal>
#define cr_expect_lt(Actual, Reference, FormatString, ...) < internal >
/**
* Passes if Actual is less or equal to Reference
@ -268,7 +268,7 @@
* @param[in] ... (optional) format string parameters
*
*****************************************************************************/
# define cr_assert_leq(Actual, Reference, FormatString, ...) <internal>
#define cr_assert_leq(Actual, Reference, FormatString, ...) < internal >
/**
* Passes if Actual is less or equal to Reference
@ -286,7 +286,7 @@
* @param[in] ... (optional) format string parameters
*
*****************************************************************************/
# define cr_expect_leq(Actual, Reference, FormatString, ...) <internal>
#define cr_expect_leq(Actual, Reference, FormatString, ...) < internal >
/**
* Passes if Actual is greater than Reference
@ -305,7 +305,7 @@
* @param[in] ... (optional) format string parameters
*
*****************************************************************************/
# define cr_assert_gt(Actual, Reference, FormatString, ...) <internal>
#define cr_assert_gt(Actual, Reference, FormatString, ...) < internal >
/**
* Passes if Actual is greater than Reference
@ -323,7 +323,7 @@
* @param[in] ... (optional) format string parameters
*
*****************************************************************************/
# define cr_expect_gt(Actual, Reference, FormatString, ...) <internal>
#define cr_expect_gt(Actual, Reference, FormatString, ...) < internal >
/**
* Passes if Actual is greater or equal to Reference
@ -342,7 +342,7 @@
* @param[in] ... (optional) format string parameters
*
*****************************************************************************/
# define cr_assert_geq(Actual, Reference, FormatString, ...) <internal>
#define cr_assert_geq(Actual, Reference, FormatString, ...) < internal >
/**
* Passes if Actual is greater or equal to Reference
@ -360,7 +360,7 @@
* @param[in] ... (optional) format string parameters
*
*****************************************************************************/
# define cr_expect_geq(Actual, Reference, FormatString, ...) <internal>
#define cr_expect_geq(Actual, Reference, FormatString, ...) < internal >
/**@}*/
@ -383,7 +383,7 @@
* @param[in] ... (optional) format string parameters
*
*****************************************************************************/
# define cr_assert_null(Value, FormatString, ...) <internal>
#define cr_assert_null(Value, FormatString, ...) < internal >
/**
* Passes if Value is NULL
@ -398,7 +398,7 @@
* @param[in] ... (optional) format string parameters
*
*****************************************************************************/
# define cr_expect_null(Value, FormatString, ...) <internal>
#define cr_expect_null(Value, FormatString, ...) < internal >
/**
* Passes if Value is not NULL
@ -414,7 +414,7 @@
* @param[in] ... (optional) format string parameters
*
*****************************************************************************/
# define cr_assert_not_null(Value, FormatString, ...) <internal>
#define cr_assert_not_null(Value, FormatString, ...) < internal >
/**
* Passes if Value is not NULL
@ -429,7 +429,7 @@
* @param[in] ... (optional) format string parameters
*
*****************************************************************************/
# define cr_expect_not_null(Value, FormatString, ...) <internal>
#define cr_expect_not_null(Value, FormatString, ...) < internal >
/**@}*/
@ -456,7 +456,7 @@
* @param[in] ... (optional) format string parameters
*
*****************************************************************************/
# define cr_assert_float_eq(Actual, Expected, Epsilon, FormatString, ...) <internal>
#define cr_assert_float_eq(Actual, Expected, Epsilon, FormatString, ...) < internal >
/**
* Passes if Actual is equal to Expected with a tolerance of Epsilon
@ -475,7 +475,7 @@
* @param[in] ... (optional) format string parameters
*
*****************************************************************************/
# define cr_expect_float_eq(Actual, Expected, Epsilon, FormatString, ...) <internal>
#define cr_expect_float_eq(Actual, Expected, Epsilon, FormatString, ...) < internal >
/**
* Passes if Actual is not equal to Unexpected with a tolerance of Epsilon
@ -495,7 +495,7 @@
* @param[in] ... (optional) format string parameters
*
*****************************************************************************/
# define cr_assert_float_neq(Actual, Unexpected, Epsilon, FormatString, ...) <internal>
#define cr_assert_float_neq(Actual, Unexpected, Epsilon, FormatString, ...) < internal >
/**
* Passes if Actual is not equal to Unexpected with a tolerance of Epsilon
@ -514,7 +514,7 @@
* @param[in] ... (optional) format string parameters
*
*****************************************************************************/
# define cr_expect_float_neq(Actual, Unexpected, Epsilon, FormatString, ...) <internal>
#define cr_expect_float_neq(Actual, Unexpected, Epsilon, FormatString, ...) < internal >
/**@}*/
@ -545,7 +545,7 @@
* @param[in] ... (optional) format string parameters
*
*****************************************************************************/
# define cr_assert_str_empty(Value, FormatString, ...) <internal>
#define cr_assert_str_empty(Value, FormatString, ...) < internal >
/**
* Passes if Value is an empty string
@ -562,7 +562,7 @@
* @param[in] ... (optional) format string parameters
*
*****************************************************************************/
# define cr_expect_str_empty(Value, FormatString, ...) <internal>
#define cr_expect_str_empty(Value, FormatString, ...) < internal >
/**
* Passes if Value is not an empty string
@ -580,7 +580,7 @@
* @param[in] ... (optional) format string parameters
*
*****************************************************************************/
# define cr_assert_str_not_empty(Value, FormatString, ...) <internal>
#define cr_assert_str_not_empty(Value, FormatString, ...) < internal >
/**
* Passes if Value is not an empty string
@ -597,7 +597,7 @@
* @param[in] ... (optional) format string parameters
*
*****************************************************************************/
# define cr_expect_str_not_empty(Value, FormatString, ...) <internal>
#define cr_expect_str_not_empty(Value, FormatString, ...) < internal >
/**
* Passes if Actual is lexicographically equal to Expected
@ -614,7 +614,7 @@
* @param[in] ... (optional) format string parameters
*
*****************************************************************************/
# define cr_assert_str_eq(Actual, Expected, FormatString, ...) <internal>
#define cr_assert_str_eq(Actual, Expected, FormatString, ...) < internal >
/**
* Passes if Actual is lexicographically equal to Expected
@ -630,7 +630,7 @@
* @param[in] ... (optional) format string parameters
*
*****************************************************************************/
# define cr_expect_str_eq(Actual, Expected, FormatString, ...) <internal>
#define cr_expect_str_eq(Actual, Expected, FormatString, ...) < internal >
/**
* Passes if Actual is not lexicographically equal to Unexpected
@ -647,7 +647,7 @@
* @param[in] ... (optional) format string parameters
*
*****************************************************************************/
# define cr_assert_str_neq(Actual, Unexpected, FormatString, ...) <internal>
#define cr_assert_str_neq(Actual, Unexpected, FormatString, ...) < internal >
/**
* Passes if Actual is not lexicographically equal to Unexpected
@ -663,7 +663,7 @@
* @param[in] ... (optional) format string parameters
*
*****************************************************************************/
# define cr_expect_str_neq(Actual, Unexpected, FormatString, ...) <internal>
#define cr_expect_str_neq(Actual, Unexpected, FormatString, ...) < internal >
/**
* Passes if Actual is lexicographically less than Reference
@ -680,7 +680,7 @@
* @param[in] ... (optional) format string parameters
*
*****************************************************************************/
# define cr_assert_str_lt(Actual, Reference, FormatString, ...) <internal>
#define cr_assert_str_lt(Actual, Reference, FormatString, ...) < internal >
/**
* Passes if Actual is lexicographically less than Reference
@ -696,7 +696,7 @@
* @param[in] ... (optional) format string parameters
*
*****************************************************************************/
# define cr_expect_str_lt(Actual, Reference, FormatString, ...) <internal>
#define cr_expect_str_lt(Actual, Reference, FormatString, ...) < internal >
/**
* Passes if Actual is lexicographically less or equal to Reference
@ -713,7 +713,7 @@
* @param[in] ... (optional) format string parameters
*
*****************************************************************************/
# define cr_assert_str_leq(Actual, Reference, FormatString, ...) <internal>
#define cr_assert_str_leq(Actual, Reference, FormatString, ...) < internal >
/**
* Passes if Actual is lexicographically less or equal to Reference
@ -729,7 +729,7 @@
* @param[in] ... (optional) format string parameters
*
*****************************************************************************/
# define cr_expect_str_leq(Actual, Reference, FormatString, ...) <internal>
#define cr_expect_str_leq(Actual, Reference, FormatString, ...) < internal >
/**
* Passes if Actual is lexicographically greater than Reference
@ -746,7 +746,7 @@
* @param[in] ... (optional) format string parameters
*
*****************************************************************************/
# define cr_assert_str_gt(Actual, Reference, FormatString, ...) <internal>
#define cr_assert_str_gt(Actual, Reference, FormatString, ...) < internal >
/**
* Passes if Actual is lexicographically greater than Reference
@ -762,7 +762,7 @@
* @param[in] ... (optional) format string parameters
*
*****************************************************************************/
# define cr_expect_str_gt(Actual, Reference, FormatString, ...) <internal>
#define cr_expect_str_gt(Actual, Reference, FormatString, ...) < internal >
/**
* Passes if Actual is lexicographically greater or equal to Reference
@ -779,7 +779,7 @@
* @param[in] ... (optional) format string parameters
*
*****************************************************************************/
# define cr_assert_str_geq(Actual, Reference, FormatString, ...) <internal>
#define cr_assert_str_geq(Actual, Reference, FormatString, ...) < internal >
/**
* Passes if Actual is lexicographically greater or equal to Reference
@ -795,7 +795,7 @@
* @param[in] ... (optional) format string parameters
*
*****************************************************************************/
# define cr_expect_str_geq(Actual, Reference, FormatString, ...) <internal>
#define cr_expect_str_geq(Actual, Reference, FormatString, ...) < internal >
/**@}*/
@ -822,7 +822,7 @@
* @param[in] ... (optional) format string parameters
*
*****************************************************************************/
# define cr_assert_arr_eq(Actual, Expected, FormatString, ...) <internal>
#define cr_assert_arr_eq(Actual, Expected, FormatString, ...) < internal >
/**
* Passes if Actual is byte-to-byte equal to Expected
@ -841,7 +841,7 @@
* @param[in] ... (optional) format string parameters
*
*****************************************************************************/
# define cr_expect_arr_eq(Actual, Expected, FormatString, ...) <internal>
#define cr_expect_arr_eq(Actual, Expected, FormatString, ...) < internal >
/**
* Passes if Actual is not byte-to-byte equal to Expected
@ -862,7 +862,7 @@
* @param[in] ... (optional) format string parameters
*
*****************************************************************************/
# define cr_assert_arr_neq(Actual, Unexpected, Size, FormatString, ...) <internal>
#define cr_assert_arr_neq(Actual, Unexpected, Size, FormatString, ...) < internal >
/**
* Passes if Actual is not byte-to-byte equal to Unexpected
@ -882,7 +882,7 @@
* @param[in] ... (optional) format string parameters
*
*****************************************************************************/
# define cr_expect_arr_neq(Actual, Unexpected, Size, FormatString, ...) <internal>
#define cr_expect_arr_neq(Actual, Unexpected, Size, FormatString, ...) < internal >
/**@}*/
@ -917,7 +917,7 @@
* @param[in] ... (optional) format string parameters
*
*****************************************************************************/
# define cr_assert_arr_eq_cmp(Actual, Expected, Size, Cmp, FormatString, ...) <internal>
#define cr_assert_arr_eq_cmp(Actual, Expected, Size, Cmp, FormatString, ...) < internal >
/**
* Passes if Actual is comparatively equal to Expected (C++ / GNU C99 only)
@ -941,7 +941,7 @@
* @param[in] ... (optional) format string parameters
*
*****************************************************************************/
# define cr_expect_arr_eq_cmp(Actual, Expected, Size, Cmp, FormatString, ...) <internal>
#define cr_expect_arr_eq_cmp(Actual, Expected, Size, Cmp, FormatString, ...) < internal >
/**
* Passes if Actual is not comparatively equal to Unexpected (C++ / GNU C99
@ -967,7 +967,7 @@
* @param[in] ... (optional) format string parameters
*
*****************************************************************************/
# define cr_assert_arr_neq_cmp(Actual, Unexpected, Size, Cmp, FormatString, ...) <internal>
#define cr_assert_arr_neq_cmp(Actual, Unexpected, Size, Cmp, FormatString, ...) < internal >
/**
* Passes if Actual is not comparatively equal to Unexpected (C++ / GNU C99
@ -992,7 +992,7 @@
* @param[in] ... (optional) format string parameters
*
*****************************************************************************/
# define cr_expect_arr_neq_cmp(Actual, Unexpected, Size, Cmp, FormatString, ...) <internal>
#define cr_expect_arr_neq_cmp(Actual, Unexpected, Size, Cmp, FormatString, ...) < internal >
/**
* Passes if Actual is comparatively less than Reference (C++ / GNU C99 only)
@ -1017,7 +1017,7 @@
* @param[in] ... (optional) format string parameters
*
*****************************************************************************/
# define cr_assert_arr_lt_cmp(Actual, Reference, Size, Cmp, FormatString, ...) <internal>
#define cr_assert_arr_lt_cmp(Actual, Reference, Size, Cmp, FormatString, ...) < internal >
/**
* Passes if Actual is comparatively less than Reference (C++ / GNU C99 only)
@ -1041,7 +1041,7 @@
* @param[in] ... (optional) format string parameters
*
*****************************************************************************/
# define cr_expect_arr_lt_cmp(Actual, Reference, Size, Cmp, FormatString, ...) <internal>
#define cr_expect_arr_lt_cmp(Actual, Reference, Size, Cmp, FormatString, ...) < internal >
/**
* Passes if Actual is comparatively less or equal to Reference (C++ / GNU C99
@ -1067,7 +1067,7 @@
* @param[in] ... (optional) format string parameters
*
*****************************************************************************/
# define cr_assert_arr_leq_cmp(Actual, Reference, Size, Cmp, FormatString, ...) <internal>
#define cr_assert_arr_leq_cmp(Actual, Reference, Size, Cmp, FormatString, ...) < internal >
/**
* Passes if Actual is comparatively less or equal to Reference (C++ / GNU C99
@ -1092,7 +1092,7 @@
* @param[in] ... (optional) format string parameters
*
*****************************************************************************/
# define cr_expect_arr_leq_cmp(Actual, Reference, Size, Cmp, FormatString, ...) <internal>
#define cr_expect_arr_leq_cmp(Actual, Reference, Size, Cmp, FormatString, ...) < internal >
/**
* Passes if Actual is comparatively greater than Reference (C++ / GNU C99 only)
@ -1117,7 +1117,7 @@
* @param[in] ... (optional) format string parameters
*
*****************************************************************************/
# define cr_assert_arr_gt_cmp(Actual, Reference, Size, Cmp, FormatString, ...) <internal>
#define cr_assert_arr_gt_cmp(Actual, Reference, Size, Cmp, FormatString, ...) < internal >
/**
* Passes if Actual is comparatively greater than Reference (C++ / GNU C99 only)
@ -1141,7 +1141,7 @@
* @param[in] ... (optional) format string parameters
*
*****************************************************************************/
# define cr_expect_arr_gt_cmp(Actual, Reference, Size, Cmp, FormatString, ...) <internal>
#define cr_expect_arr_gt_cmp(Actual, Reference, Size, Cmp, FormatString, ...) < internal >
/**
* Passes if Actual is comparatively greater or equal to Reference (C++ / GNU
@ -1167,7 +1167,7 @@
* @param[in] ... (optional) format string parameters
*
*****************************************************************************/
# define cr_assert_arr_geq_cmp(Actual, Reference, Size, Cmp, FormatString, ...) <internal>
#define cr_assert_arr_geq_cmp(Actual, Reference, Size, Cmp, FormatString, ...) < internal >
/**
* Passes if Actual is comparatively greater or equal to Reference (C++ / GNU
@ -1192,11 +1192,11 @@
* @param[in] ... (optional) format string parameters
*
*****************************************************************************/
# define cr_expect_arr_geq_cmp(Actual, Reference, Size, Cmp, FormatString, ...) <internal>
#define cr_expect_arr_geq_cmp(Actual, Reference, Size, Cmp, FormatString, ...) < internal >
/**@}*/
# ifdef __cplusplus
#ifdef __cplusplus
/**
* @defgroup ExceptionAsserts Exception asserts
@ -1223,7 +1223,7 @@
* @param[in] ... (optional) format string parameters
*
*****************************************************************************/
# define cr_assert_throw(Statement, Exception, FormatString, ...) <internal>
# define cr_assert_throw(Statement, Exception, FormatString, ...) < internal >
/**
* Passes if Statement throws an instance of Exception (C++ only)
@ -1241,7 +1241,7 @@
* @param[in] ... (optional) format string parameters
*
*****************************************************************************/
# define cr_expect_throw(Statement, Exception, FormatString, ...) <internal>
# define cr_expect_throw(Statement, Exception, FormatString, ...) < internal >
/**
* Passes if Statement does not throws an instance of Exception (C++ only)
@ -1260,7 +1260,7 @@
* @param[in] ... (optional) format string parameters
*
*****************************************************************************/
# define cr_assert_no_throw(Statement, Exception, FormatString, ...) <internal>
# define cr_assert_no_throw(Statement, Exception, FormatString, ...) < internal >
/**
* Passes if Statement does not throws an instance of Exception (C++ only)
@ -1278,7 +1278,7 @@
* @param[in] ... (optional) format string parameters
*
*****************************************************************************/
# define cr_expect_no_throw(Statement, Exception, FormatString, ...) <internal>
# define cr_expect_no_throw(Statement, Exception, FormatString, ...) < internal >
/**
* Passes if Statement throws any kind of exception (C++ only)
@ -1296,7 +1296,7 @@
* @param[in] ... (optional) format string parameters
*
*****************************************************************************/
# define cr_assert_any_throw(Statement, FormatString, ...) <internal>
# define cr_assert_any_throw(Statement, FormatString, ...) < internal >
/**
* Passes if Statement throws any kind of exception (C++ only)
@ -1313,7 +1313,7 @@
* @param[in] ... (optional) format string parameters
*
*****************************************************************************/
# define cr_expect_any_throw(Statement, FormatString, ...) <internal>
# define cr_expect_any_throw(Statement, FormatString, ...) < internal >
/**
* Passes if Statement does not throws any kind of exception (C++ only)
@ -1331,7 +1331,7 @@
* @param[in] ... (optional) format string parameters
*
*****************************************************************************/
# define cr_assert_none_throw(Statement, FormatString, ...) <internal>
# define cr_assert_none_throw(Statement, FormatString, ...) < internal >
/**
* Passes if Statement does not throws any kind of exception (C++ only)
@ -1348,23 +1348,23 @@
* @param[in] ... (optional) format string parameters
*
*****************************************************************************/
# define cr_expect_none_throw(Statement, FormatString, ...) <internal>
# define cr_expect_none_throw(Statement, FormatString, ...) < internal >
# endif
#endif
/**@}*/
/** @cond CRITERION_DOC_DEPRECATED */
// The section below is here for backward compatibility purposes.
// It shall be removed in the next major version of Criterion
# ifndef CRITERION_NO_COMPAT
/* The section below is here for backward compatibility purposes.
It shall be removed in the next major version of Criterion */
#ifndef CRITERION_NO_COMPAT
# define CRITERION_ASSERT_DEPRECATED_B(Name, Newname) \
CRITERION_ASSERT_DEPRECATED__( \
message \
("The `" #Name "` macro is deprecated, " \
"please use `" #Newname "` instead.") \
)
# define CRITERION_ASSERT_DEPRECATED_B(Name, Newname) \
CRITERION_ASSERT_DEPRECATED__( \
message \
("The `" #Name "` macro is deprecated, " \
"please use `" #Newname "` instead.") \
)
# ifdef _MSC_VER
# define CRITERION_ASSERT_DEPRECATED__(Msg) \
@ -1374,25 +1374,25 @@
_Pragma(#Msg)
# endif
// scheduled for removal after 2.0
# define cr_abort_test(Message) CRITERION_ASSERT_DEPRECATED_B(cr_abort_test, cr_assert_fail) cr_assert_fail(Message)
# define cr_assert_strings_eq(...) CRITERION_ASSERT_DEPRECATED_B(cr_assert_strings_eq, cr_assert_str_eq) cr_assert_str_eq(__VA_ARGS__)
# define cr_assert_strings_neq(...) CRITERION_ASSERT_DEPRECATED_B(cr_assert_strings_neq, cr_assert_str_neq) cr_assert_str_neq(__VA_ARGS__)
# define cr_assert_strings_lt(...) CRITERION_ASSERT_DEPRECATED_B(cr_assert_strings_lt, cr_assert_str_lt) cr_assert_str_lt(__VA_ARGS__)
# define cr_assert_strings_leq(...) CRITERION_ASSERT_DEPRECATED_B(cr_assert_strings_leq, cr_assert_str_leq) cr_assert_str_leq(__VA_ARGS__)
# define cr_assert_strings_gt(...) CRITERION_ASSERT_DEPRECATED_B(cr_assert_strings_gt, cr_assert_str_gt) cr_assert_str_gt(__VA_ARGS__)
# define cr_assert_strings_geq(...) CRITERION_ASSERT_DEPRECATED_B(cr_assert_strings_geq, cr_assert_str_geq) cr_assert_str_geq(__VA_ARGS__)
/* scheduled for removal after 2.0 */
# define cr_abort_test(Message) CRITERION_ASSERT_DEPRECATED_B(cr_abort_test, cr_assert_fail) cr_assert_fail(Message)
# define cr_assert_strings_eq(...) CRITERION_ASSERT_DEPRECATED_B(cr_assert_strings_eq, cr_assert_str_eq) cr_assert_str_eq(__VA_ARGS__)
# define cr_assert_strings_neq(...) CRITERION_ASSERT_DEPRECATED_B(cr_assert_strings_neq, cr_assert_str_neq) cr_assert_str_neq(__VA_ARGS__)
# define cr_assert_strings_lt(...) CRITERION_ASSERT_DEPRECATED_B(cr_assert_strings_lt, cr_assert_str_lt) cr_assert_str_lt(__VA_ARGS__)
# define cr_assert_strings_leq(...) CRITERION_ASSERT_DEPRECATED_B(cr_assert_strings_leq, cr_assert_str_leq) cr_assert_str_leq(__VA_ARGS__)
# define cr_assert_strings_gt(...) CRITERION_ASSERT_DEPRECATED_B(cr_assert_strings_gt, cr_assert_str_gt) cr_assert_str_gt(__VA_ARGS__)
# define cr_assert_strings_geq(...) CRITERION_ASSERT_DEPRECATED_B(cr_assert_strings_geq, cr_assert_str_geq) cr_assert_str_geq(__VA_ARGS__)
# define cr_assert_arrays_eq(...) CRITERION_ASSERT_DEPRECATED_B(cr_assert_arrays_eq, cr_assert_arr_eq) cr_assert_arr_eq(__VA_ARGS__)
# define cr_assert_arrays_neq(...) CRITERION_ASSERT_DEPRECATED_B(cr_assert_arrays_neq, cr_assert_arr_neq) cr_assert_arr_neq(__VA_ARGS__)
# define cr_assert_arrays_eq(...) CRITERION_ASSERT_DEPRECATED_B(cr_assert_arrays_eq, cr_assert_arr_eq) cr_assert_arr_eq(__VA_ARGS__)
# define cr_assert_arrays_neq(...) CRITERION_ASSERT_DEPRECATED_B(cr_assert_arrays_neq, cr_assert_arr_neq) cr_assert_arr_neq(__VA_ARGS__)
# define cr_assert_arrays_eq_cmp(...) CRITERION_ASSERT_DEPRECATED_B(cr_assert_arrays_eq_cmp, cr_assert_arr_eq_cmp) cr_assert_arr_eq_cmp(__VA_ARGS__)
# define cr_assert_arrays_neq_cmp(...) CRITERION_ASSERT_DEPRECATED_B(cr_assert_arrays_neq_cmp, cr_assert_arr_neq_cmp) cr_assert_arr_neq_cmp(__VA_ARGS__)
# define cr_assert_arrays_eq_cmp(...) CRITERION_ASSERT_DEPRECATED_B(cr_assert_arrays_eq_cmp, cr_assert_arr_eq_cmp) cr_assert_arr_eq_cmp(__VA_ARGS__)
# define cr_assert_arrays_neq_cmp(...) CRITERION_ASSERT_DEPRECATED_B(cr_assert_arrays_neq_cmp, cr_assert_arr_neq_cmp) cr_assert_arr_neq_cmp(__VA_ARGS__)
# endif
#endif
/** @endcond */
# include "internal/assert.h"
#include "internal/assert.h"
#endif /* !CRITERION_ASSERT_H_ */

View file

@ -26,11 +26,11 @@
* @brief Include this to use criterion
*****************************************************************************/
#ifndef CRITERION_H_
# define CRITERION_H_
#define CRITERION_H_
# include "types.h"
# include "assert.h"
# include "alloc.h"
#include "types.h"
#include "assert.h"
#include "alloc.h"
/**
* Defines a new test.
@ -42,7 +42,7 @@
* (see criterion/types.h).\n
* Example: .exit_code = 1
*/
# define Test(Suite, Name, ...) <internal>
#define Test(Suite, Name, ...) < internal >
/**
* Explicitely defines a test suite and its options.
@ -53,7 +53,7 @@
* (see criterion/types.h).
* These options will provide the defaults for each test.
*/
# define TestSuite(Name, ...) <internal>
#define TestSuite(Name, ...) < internal >
CR_BEGIN_C_API
@ -109,13 +109,13 @@ CR_API int criterion_handle_args(int argc, char *argv[], bool handle_unknown_arg
* @param[in] test The newly created test.
*/
CR_API void criterion_register_test(struct criterion_test_set *tests,
struct criterion_test *test);
struct criterion_test *test);
CR_API extern const struct criterion_test *const criterion_current_test;
CR_API extern const struct criterion_test *const criterion_current_test;
CR_API extern const struct criterion_suite *const criterion_current_suite;
CR_END_C_API
# include "internal/test.h"
#include "internal/test.h"
#endif /* !CRITERION_H_ */

View file

@ -22,15 +22,15 @@
* THE SOFTWARE.
*/
#ifndef CRITERION_EVENT_H_
# define CRITERION_EVENT_H_
#define CRITERION_EVENT_H_
# ifdef __cplusplus
# include <cstddef>
# else
# include <stddef.h>
# endif
# include "internal/common.h"
# include "stats.h"
#ifdef __cplusplus
# include <cstddef>
#else
# include <stddef.h>
#endif
#include "internal/common.h"
#include "stats.h"
CR_BEGIN_C_API

View file

@ -26,9 +26,9 @@
* @brief Report hooks
*****************************************************************************/
#ifndef CRITERION_HOOKS_H_
# define CRITERION_HOOKS_H_
#define CRITERION_HOOKS_H_
# include "internal/hooks.h"
#include "internal/hooks.h"
/**
* This enum lists all the phases of the runner lifecycle.
@ -67,6 +67,6 @@ typedef void (*f_report_hook)();
*
* @param Kind The report phase to hook the function onto.
*/
# define ReportHook(Kind) CR_REPORT_HOOK_IMPL(Kind)
#define ReportHook(Kind) CR_REPORT_HOOK_IMPL(Kind)
#endif /* !CRITERION_HOOKS_H_ */

View file

@ -22,15 +22,15 @@
* THE SOFTWARE.
*/
#ifndef CRITERION_ASPRINTF_COMPAT_H_
# define CRITERION_ASPRINTF_COMPAT_H_
#define CRITERION_ASPRINTF_COMPAT_H_
# ifdef __cplusplus
# include <cstdarg>
# else
# include <stdarg.h>
# endif
#ifdef __cplusplus
# include <cstdarg>
#else
# include <stdarg.h>
#endif
# include "common.h"
#include "common.h"
CR_BEGIN_C_API

File diff suppressed because it is too large Load diff

View file

@ -22,118 +22,118 @@
* THE SOFTWARE.
*/
#ifndef CRITERION_COMMON_H_
# define CRITERION_COMMON_H_
#define CRITERION_COMMON_H_
# if defined(_MSC_VER)
# if _MSC_VER < 1900
# error \
Your version of MSVC++ is too old, please compile your tests using \
a c99 compiler, like MinGW or MSVC 14.0+ (Included in visual studio \
2015)
# endif
#if defined (_MSC_VER)
# if _MSC_VER < 1900
# error \
Your version of MSVC++ is too old, please compile your tests using \
a c99 compiler, like MinGW or MSVC 14.0+ (Included in visual studio \
2015)
# endif
#endif
# ifndef CR_IS_MSVC
# ifdef _MSC_VER
# define CR_IS_MSVC _MSC_VER
# else
# define CR_IS_MSVC 0
# endif
# endif
# ifdef __cplusplus
# ifdef __GNUC__
# define CR_ATTRIBUTE(Arg) __attribute__((Arg))
# else
# define CR_ATTRIBUTE(Arg) [[gnu::Arg]]
# endif
# define CR_BEGIN_C_API extern "C" {
# define CR_END_C_API }
#ifndef CR_IS_MSVC
# ifdef _MSC_VER
# define CR_IS_MSVC _MSC_VER
# else
# define CR_ATTRIBUTE(Arg) __attribute__((Arg))
# define CR_BEGIN_C_API
# define CR_END_C_API
# define CR_IS_MSVC 0
# endif
#endif
# ifdef __APPLE__
# define CR_SECTION_START_SUFFIX(Name) __asm("section$start$__DATA$" Name)
# define CR_SECTION_END_SUFFIX(Name) __asm("section$end$__DATA$" Name)
# define CR_SECTION_(Name) CR_ATTRIBUTE(section("__DATA," Name))
# define CR_SECTION_SUFFIX_
# elif CR_IS_MSVC
# define CR_SECTION_START_SUFFIX(Name)
# define CR_SECTION_END_SUFFIX(Name)
# define CR_SECTION_(Name) \
__pragma(data_seg(push)) \
__pragma(section(Name, read)) \
#ifdef __cplusplus
# ifdef __GNUC__
# define CR_ATTRIBUTE(Arg) __attribute__((Arg))
# else
# define CR_ATTRIBUTE(Arg) [[gnu::Arg]]
# endif
# define CR_BEGIN_C_API extern "C" {
# define CR_END_C_API }
#else
# define CR_ATTRIBUTE(Arg) __attribute__((Arg))
# define CR_BEGIN_C_API
# define CR_END_C_API
#endif
#ifdef __APPLE__
# define CR_SECTION_START_SUFFIX(Name) __asm("section$start$__DATA$" Name)
# define CR_SECTION_END_SUFFIX(Name) __asm("section$end$__DATA$" Name)
# define CR_SECTION_(Name) CR_ATTRIBUTE(section("__DATA," Name))
# define CR_SECTION_SUFFIX_
#elif CR_IS_MSVC
# define CR_SECTION_START_SUFFIX(Name)
# define CR_SECTION_END_SUFFIX(Name)
# define CR_SECTION_(Name) \
__pragma(data_seg(push)) \
__pragma(section(Name, read)) \
__declspec(allocate(Name))
# define CR_SECTION_SUFFIX_ \
# define CR_SECTION_SUFFIX_ \
__pragma(data_seg(pop))
# else
# define CR_SECTION_START_SUFFIX(Name)
# define CR_SECTION_END_SUFFIX(Name)
# define CR_SECTION_(Name) CR_ATTRIBUTE(section(Name))
# define CR_SECTION_SUFFIX_
# endif
#else
# define CR_SECTION_START_SUFFIX(Name)
# define CR_SECTION_END_SUFFIX(Name)
# define CR_SECTION_(Name) CR_ATTRIBUTE(section(Name))
# define CR_SECTION_SUFFIX_
#endif
# define CR_MAKE_IDENTIFIER_(Prefix, Id) CR_MAKE_IDENTIFIER__(Prefix, Id)
# define CR_MAKE_IDENTIFIER__(Prefix, Id) Prefix ## _ ## Id
#define CR_MAKE_IDENTIFIER_(Prefix, Id) CR_MAKE_IDENTIFIER__(Prefix, Id)
#define CR_MAKE_IDENTIFIER__(Prefix, Id) Prefix ## _ ## Id
# ifdef __GNUC__
# define CR_UNUSED CR_ATTRIBUTE(unused)
# define CR_NORETURN CR_ATTRIBUTE(noreturn)
# define CR_INLINE CR_ATTRIBUTE(always_inline) inline
# elif CR_IS_MSVC
# define CR_UNUSED __pragma(warning(suppress:4100))
# define CR_NORETURN __declspec(noreturn)
# define CR_INLINE __forceinline
# else
# define CR_UNUSED
# define CR_NORETURN
# define CR_INLINE inline
# endif
#ifdef __GNUC__
# define CR_UNUSED CR_ATTRIBUTE(unused)
# define CR_NORETURN CR_ATTRIBUTE(noreturn)
# define CR_INLINE CR_ATTRIBUTE(always_inline) inline
#elif CR_IS_MSVC
# define CR_UNUSED __pragma(warning(suppress: 4100))
# define CR_NORETURN __declspec(noreturn)
# define CR_INLINE __forceinline
#else
# define CR_UNUSED
# define CR_NORETURN
# define CR_INLINE inline
#endif
# ifdef _WIN32
# define CR_SIZE_T_FORMAT "%Iu"
# else
# define CR_SIZE_T_FORMAT "%zu"
# endif
#ifdef _WIN32
# define CR_SIZE_T_FORMAT "%Iu"
#else
# define CR_SIZE_T_FORMAT "%zu"
#endif
# ifdef __GNUC__
# define CR_FORMAT(Archetype, Index, Ftc) CR_ATTRIBUTE(format(Archetype, Index, Ftc))
# else
# define CR_FORMAT(Archetype, Index, Ftc)
# endif
#ifdef __GNUC__
# define CR_FORMAT(Archetype, Index, Ftc) CR_ATTRIBUTE(format(Archetype, Index, Ftc))
#else
# define CR_FORMAT(Archetype, Index, Ftc)
#endif
# if defined _WIN32 || defined __CYGWIN__
# ifdef CRITERION_BUILDING_DLL
# ifdef __GNUC__
# define CR_API CR_ATTRIBUTE(dllexport)
# else
# define CR_API __declspec(dllexport)
# endif
#if defined _WIN32 || defined __CYGWIN__
# ifdef CRITERION_BUILDING_DLL
# ifdef __GNUC__
# define CR_API CR_ATTRIBUTE(dllexport)
# else
# ifdef __GNUC__
# define CR_API CR_ATTRIBUTE(dllimport)
# else
# define CR_API __declspec(dllimport)
# endif
# define CR_API __declspec(dllexport)
# endif
# else
# ifdef __GNUC__
# define CR_API CR_ATTRIBUTE(dllimport)
# else
# define CR_API __declspec(dllimport)
# endif
# endif
# define CR_LOCAL
#else
# if __GNUC__ >= 4
# define CR_API CR_ATTRIBUTE(visibility("default"))
# define CR_LOCAL CR_ATTRIBUTE(visibility("hidden"))
# else
# define CR_API
# define CR_LOCAL
# else
# if __GNUC__ >= 4
# define CR_API CR_ATTRIBUTE(visibility("default"))
# define CR_LOCAL CR_ATTRIBUTE(visibility("hidden"))
# else
# define CR_API
# define CR_LOCAL
# endif
# endif
#endif
# ifdef __cplusplus
# define CR_STDN std::
# else
# define CR_STDN
# endif
#ifdef __cplusplus
# define CR_STDN std::
#else
# define CR_STDN
#endif
#endif /* !CRITERION_COMMON_H_ */

View file

@ -22,20 +22,20 @@
* THE SOFTWARE.
*/
#ifndef CRITERION_INTERNAL_DEPRECATION_H_
# define CRITERION_INTERNAL_DEPRECATION_H_
#define CRITERION_INTERNAL_DEPRECATION_H_
# define CR_DEPRECATED(Msg) CR_DEPRECATED_(message (Msg))
#define CR_DEPRECATED(Msg) CR_DEPRECATED_(message(Msg))
# ifdef _MSC_VER
# define CR_DEPRECATED_(Msg) __pragma(Msg)
# else
# define CR_DEPRECATED_(Msg) _Pragma(#Msg)
# endif
#ifdef _MSC_VER
# define CR_DEPRECATED_(Msg) __pragma(Msg)
#else
# define CR_DEPRECATED_(Msg) _Pragma(#Msg)
#endif
# ifdef __GNUC__
# define CR_DEPRECATED_MEMBER(Member) Member __attribute__((deprecated))
# else
# define CR_DEPRECATED_MEMBER(Member) Member
# endif
#ifdef __GNUC__
# define CR_DEPRECATED_MEMBER(Member) Member __attribute__((deprecated))
#else
# define CR_DEPRECATED_MEMBER(Member) Member
#endif
#endif /* !CRITERION_INTERNAL_DEPRECATION_H_ */

View file

@ -22,104 +22,106 @@
* THE SOFTWARE.
*/
#ifndef CRITERION_DESIGNATED_INITIALIZER_COMPAT_HH_
# define CRITERION_DESIGNATED_INITIALIZER_COMPAT_HH_
#define CRITERION_DESIGNATED_INITIALIZER_COMPAT_HH_
# include "common.h"
#include "common.h"
# define CRITERION_ARG_LENGTH(...) CR_EXPAND(CRITERION_ARG_LENGTH_(__VA_ARGS__,\
63, 62, 61, 60, 59, 58, 57, 56, 55, 54, 53, 52, 51, 50, 49, 48, 47, 46, 45,\
44, 43, 42, 41, 40, 39, 38, 37, 36, 35, 34, 33, 32, 31, 30, 29, 28, 27, 26,\
25, 24, 23, 22, 21, 20, 19, 18, 17, 16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6,\
5, 4, 3, 2, 1, 0))
# define CRITERION_ARG_LENGTH_(_63, _62, _61, _60, _59, _58, _57, _56, _55, _54, _53, \
_52, _51, _50, _49, _48, _47, _46, _45, _44, _43, _42, _41, _40, _39, _38, \
_37, _36, _35, _34, _33, _32, _31, _30, _29, _28, _27, _26, _25, _24, _23, \
_22, _21, _20, _19, _18, _17, _16, _15, _14, _13, _12, _11, _10, _9, _8, \
_7, _6, _5, _4, _3, _2, _1, count, ...) count
#define CRITERION_ARG_LENGTH(...) \
CR_EXPAND(CRITERION_ARG_LENGTH_(__VA_ARGS__, \
63, 62, 61, 60, 59, 58, 57, 56, 55, 54, 53, 52, 51, 50, 49, 48, 47, 46, 45, \
44, 43, 42, 41, 40, 39, 38, 37, 36, 35, 34, 33, 32, 31, 30, 29, 28, 27, 26, \
25, 24, 23, 22, 21, 20, 19, 18, 17, 16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, \
5, 4, 3, 2, 1, 0))
#define CRITERION_ARG_LENGTH_(_63, _62, _61, _60, _59, _58, _57, _56, _55, _54, _53, \
_52, _51, _50, _49, _48, _47, _46, _45, _44, _43, _42, _41, _40, _39, _38, \
_37, _36, _35, _34, _33, _32, _31, _30, _29, _28, _27, _26, _25, _24, _23, \
_22, _21, _20, _19, _18, _17, _16, _15, _14, _13, _12, _11, _10, _9, _8, \
_7, _6, _5, _4, _3, _2, _1, count, ...) count
# define CRITERION_APPLY_1(Macro, ...)
# define CRITERION_APPLY_2(Macro, Prefix, Head, ...) Macro(Prefix, Head) CR_EXPAND(CRITERION_APPLY_1(Macro, Prefix, __VA_ARGS__))
# define CRITERION_APPLY_3(Macro, Prefix, Head, ...) Macro(Prefix, Head) CR_EXPAND(CRITERION_APPLY_2(Macro, Prefix, __VA_ARGS__))
# define CRITERION_APPLY_4(Macro, Prefix, Head, ...) Macro(Prefix, Head) CR_EXPAND(CRITERION_APPLY_3(Macro, Prefix, __VA_ARGS__))
# define CRITERION_APPLY_5(Macro, Prefix, Head, ...) Macro(Prefix, Head) CR_EXPAND(CRITERION_APPLY_4(Macro, Prefix, __VA_ARGS__))
# define CRITERION_APPLY_6(Macro, Prefix, Head, ...) Macro(Prefix, Head) CR_EXPAND(CRITERION_APPLY_5(Macro, Prefix, __VA_ARGS__))
# define CRITERION_APPLY_7(Macro, Prefix, Head, ...) Macro(Prefix, Head) CR_EXPAND(CRITERION_APPLY_6(Macro, Prefix, __VA_ARGS__))
# define CRITERION_APPLY_8(Macro, Prefix, Head, ...) Macro(Prefix, Head) CR_EXPAND(CRITERION_APPLY_7(Macro, Prefix, __VA_ARGS__))
# define CRITERION_APPLY_9(Macro, Prefix, Head, ...) Macro(Prefix, Head) CR_EXPAND(CRITERION_APPLY_8(Macro, Prefix, __VA_ARGS__))
# define CRITERION_APPLY_10(Macro, Prefix, Head, ...) Macro(Prefix, Head) CR_EXPAND(CRITERION_APPLY_9(Macro, Prefix, __VA_ARGS__))
# define CRITERION_APPLY_11(Macro, Prefix, Head, ...) Macro(Prefix, Head) CR_EXPAND(CRITERION_APPLY_10(Macro, Prefix, __VA_ARGS__))
# define CRITERION_APPLY_12(Macro, Prefix, Head, ...) Macro(Prefix, Head) CR_EXPAND(CRITERION_APPLY_11(Macro, Prefix, __VA_ARGS__))
# define CRITERION_APPLY_13(Macro, Prefix, Head, ...) Macro(Prefix, Head) CR_EXPAND(CRITERION_APPLY_12(Macro, Prefix, __VA_ARGS__))
# define CRITERION_APPLY_14(Macro, Prefix, Head, ...) Macro(Prefix, Head) CR_EXPAND(CRITERION_APPLY_13(Macro, Prefix, __VA_ARGS__))
# define CRITERION_APPLY_15(Macro, Prefix, Head, ...) Macro(Prefix, Head) CR_EXPAND(CRITERION_APPLY_14(Macro, Prefix, __VA_ARGS__))
# define CRITERION_APPLY_16(Macro, Prefix, Head, ...) Macro(Prefix, Head) CR_EXPAND(CRITERION_APPLY_15(Macro, Prefix, __VA_ARGS__))
# define CRITERION_APPLY_17(Macro, Prefix, Head, ...) Macro(Prefix, Head) CR_EXPAND(CRITERION_APPLY_16(Macro, Prefix, __VA_ARGS__))
# define CRITERION_APPLY_18(Macro, Prefix, Head, ...) Macro(Prefix, Head) CR_EXPAND(CRITERION_APPLY_17(Macro, Prefix, __VA_ARGS__))
# define CRITERION_APPLY_19(Macro, Prefix, Head, ...) Macro(Prefix, Head) CR_EXPAND(CRITERION_APPLY_18(Macro, Prefix, __VA_ARGS__))
# define CRITERION_APPLY_20(Macro, Prefix, Head, ...) Macro(Prefix, Head) CR_EXPAND(CRITERION_APPLY_19(Macro, Prefix, __VA_ARGS__))
# define CRITERION_APPLY_21(Macro, Prefix, Head, ...) Macro(Prefix, Head) CR_EXPAND(CRITERION_APPLY_20(Macro, Prefix, __VA_ARGS__))
# define CRITERION_APPLY_22(Macro, Prefix, Head, ...) Macro(Prefix, Head) CR_EXPAND(CRITERION_APPLY_21(Macro, Prefix, __VA_ARGS__))
# define CRITERION_APPLY_23(Macro, Prefix, Head, ...) Macro(Prefix, Head) CR_EXPAND(CRITERION_APPLY_22(Macro, Prefix, __VA_ARGS__))
# define CRITERION_APPLY_24(Macro, Prefix, Head, ...) Macro(Prefix, Head) CR_EXPAND(CRITERION_APPLY_23(Macro, Prefix, __VA_ARGS__))
# define CRITERION_APPLY_25(Macro, Prefix, Head, ...) Macro(Prefix, Head) CR_EXPAND(CRITERION_APPLY_24(Macro, Prefix, __VA_ARGS__))
# define CRITERION_APPLY_26(Macro, Prefix, Head, ...) Macro(Prefix, Head) CR_EXPAND(CRITERION_APPLY_25(Macro, Prefix, __VA_ARGS__))
# define CRITERION_APPLY_27(Macro, Prefix, Head, ...) Macro(Prefix, Head) CR_EXPAND(CRITERION_APPLY_26(Macro, Prefix, __VA_ARGS__))
# define CRITERION_APPLY_28(Macro, Prefix, Head, ...) Macro(Prefix, Head) CR_EXPAND(CRITERION_APPLY_27(Macro, Prefix, __VA_ARGS__))
# define CRITERION_APPLY_29(Macro, Prefix, Head, ...) Macro(Prefix, Head) CR_EXPAND(CRITERION_APPLY_28(Macro, Prefix, __VA_ARGS__))
# define CRITERION_APPLY_30(Macro, Prefix, Head, ...) Macro(Prefix, Head) CR_EXPAND(CRITERION_APPLY_29(Macro, Prefix, __VA_ARGS__))
# define CRITERION_APPLY_31(Macro, Prefix, Head, ...) Macro(Prefix, Head) CR_EXPAND(CRITERION_APPLY_30(Macro, Prefix, __VA_ARGS__))
# define CRITERION_APPLY_32(Macro, Prefix, Head, ...) Macro(Prefix, Head) CR_EXPAND(CRITERION_APPLY_31(Macro, Prefix, __VA_ARGS__))
# define CRITERION_APPLY_33(Macro, Prefix, Head, ...) Macro(Prefix, Head) CR_EXPAND(CRITERION_APPLY_32(Macro, Prefix, __VA_ARGS__))
# define CRITERION_APPLY_34(Macro, Prefix, Head, ...) Macro(Prefix, Head) CR_EXPAND(CRITERION_APPLY_33(Macro, Prefix, __VA_ARGS__))
# define CRITERION_APPLY_35(Macro, Prefix, Head, ...) Macro(Prefix, Head) CR_EXPAND(CRITERION_APPLY_34(Macro, Prefix, __VA_ARGS__))
# define CRITERION_APPLY_36(Macro, Prefix, Head, ...) Macro(Prefix, Head) CR_EXPAND(CRITERION_APPLY_35(Macro, Prefix, __VA_ARGS__))
# define CRITERION_APPLY_37(Macro, Prefix, Head, ...) Macro(Prefix, Head) CR_EXPAND(CRITERION_APPLY_36(Macro, Prefix, __VA_ARGS__))
# define CRITERION_APPLY_38(Macro, Prefix, Head, ...) Macro(Prefix, Head) CR_EXPAND(CRITERION_APPLY_37(Macro, Prefix, __VA_ARGS__))
# define CRITERION_APPLY_39(Macro, Prefix, Head, ...) Macro(Prefix, Head) CR_EXPAND(CRITERION_APPLY_38(Macro, Prefix, __VA_ARGS__))
# define CRITERION_APPLY_40(Macro, Prefix, Head, ...) Macro(Prefix, Head) CR_EXPAND(CRITERION_APPLY_39(Macro, Prefix, __VA_ARGS__))
# define CRITERION_APPLY_41(Macro, Prefix, Head, ...) Macro(Prefix, Head) CR_EXPAND(CRITERION_APPLY_40(Macro, Prefix, __VA_ARGS__))
# define CRITERION_APPLY_42(Macro, Prefix, Head, ...) Macro(Prefix, Head) CR_EXPAND(CRITERION_APPLY_41(Macro, Prefix, __VA_ARGS__))
# define CRITERION_APPLY_43(Macro, Prefix, Head, ...) Macro(Prefix, Head) CR_EXPAND(CRITERION_APPLY_42(Macro, Prefix, __VA_ARGS__))
# define CRITERION_APPLY_44(Macro, Prefix, Head, ...) Macro(Prefix, Head) CR_EXPAND(CRITERION_APPLY_43(Macro, Prefix, __VA_ARGS__))
# define CRITERION_APPLY_45(Macro, Prefix, Head, ...) Macro(Prefix, Head) CR_EXPAND(CRITERION_APPLY_44(Macro, Prefix, __VA_ARGS__))
# define CRITERION_APPLY_46(Macro, Prefix, Head, ...) Macro(Prefix, Head) CR_EXPAND(CRITERION_APPLY_45(Macro, Prefix, __VA_ARGS__))
# define CRITERION_APPLY_47(Macro, Prefix, Head, ...) Macro(Prefix, Head) CR_EXPAND(CRITERION_APPLY_46(Macro, Prefix, __VA_ARGS__))
# define CRITERION_APPLY_48(Macro, Prefix, Head, ...) Macro(Prefix, Head) CR_EXPAND(CRITERION_APPLY_47(Macro, Prefix, __VA_ARGS__))
# define CRITERION_APPLY_49(Macro, Prefix, Head, ...) Macro(Prefix, Head) CR_EXPAND(CRITERION_APPLY_48(Macro, Prefix, __VA_ARGS__))
# define CRITERION_APPLY_50(Macro, Prefix, Head, ...) Macro(Prefix, Head) CR_EXPAND(CRITERION_APPLY_49(Macro, Prefix, __VA_ARGS__))
# define CRITERION_APPLY_51(Macro, Prefix, Head, ...) Macro(Prefix, Head) CR_EXPAND(CRITERION_APPLY_50(Macro, Prefix, __VA_ARGS__))
# define CRITERION_APPLY_52(Macro, Prefix, Head, ...) Macro(Prefix, Head) CR_EXPAND(CRITERION_APPLY_51(Macro, Prefix, __VA_ARGS__))
# define CRITERION_APPLY_53(Macro, Prefix, Head, ...) Macro(Prefix, Head) CR_EXPAND(CRITERION_APPLY_52(Macro, Prefix, __VA_ARGS__))
# define CRITERION_APPLY_54(Macro, Prefix, Head, ...) Macro(Prefix, Head) CR_EXPAND(CRITERION_APPLY_53(Macro, Prefix, __VA_ARGS__))
# define CRITERION_APPLY_55(Macro, Prefix, Head, ...) Macro(Prefix, Head) CR_EXPAND(CRITERION_APPLY_54(Macro, Prefix, __VA_ARGS__))
# define CRITERION_APPLY_56(Macro, Prefix, Head, ...) Macro(Prefix, Head) CR_EXPAND(CRITERION_APPLY_55(Macro, Prefix, __VA_ARGS__))
# define CRITERION_APPLY_57(Macro, Prefix, Head, ...) Macro(Prefix, Head) CR_EXPAND(CRITERION_APPLY_56(Macro, Prefix, __VA_ARGS__))
# define CRITERION_APPLY_58(Macro, Prefix, Head, ...) Macro(Prefix, Head) CR_EXPAND(CRITERION_APPLY_57(Macro, Prefix, __VA_ARGS__))
# define CRITERION_APPLY_59(Macro, Prefix, Head, ...) Macro(Prefix, Head) CR_EXPAND(CRITERION_APPLY_58(Macro, Prefix, __VA_ARGS__))
# define CRITERION_APPLY_60(Macro, Prefix, Head, ...) Macro(Prefix, Head) CR_EXPAND(CRITERION_APPLY_59(Macro, Prefix, __VA_ARGS__))
# define CRITERION_APPLY_61(Macro, Prefix, Head, ...) Macro(Prefix, Head) CR_EXPAND(CRITERION_APPLY_60(Macro, Prefix, __VA_ARGS__))
# define CRITERION_APPLY_62(Macro, Prefix, Head, ...) Macro(Prefix, Head) CR_EXPAND(CRITERION_APPLY_61(Macro, Prefix, __VA_ARGS__))
# define CRITERION_APPLY_63(Macro, Prefix, Head, ...) Macro(Prefix, Head) CR_EXPAND(CRITERION_APPLY_62(Macro, Prefix, __VA_ARGS__))
# define CRITERION_APPLY_64(Macro, Prefix, Head, ...) Macro(Prefix, Head) CR_EXPAND(CRITERION_APPLY_63(Macro, Prefix, __VA_ARGS__))
# define CRITERION_APPLY_65(Macro, Prefix, Head, ...) Macro(Prefix, Head) CR_EXPAND(CRITERION_APPLY_64(Macro, Prefix, __VA_ARGS__))
#define CRITERION_APPLY_1(Macro, ...)
#define CRITERION_APPLY_2(Macro, Prefix, Head, ...) Macro(Prefix, Head) CR_EXPAND(CRITERION_APPLY_1(Macro, Prefix, __VA_ARGS__))
#define CRITERION_APPLY_3(Macro, Prefix, Head, ...) Macro(Prefix, Head) CR_EXPAND(CRITERION_APPLY_2(Macro, Prefix, __VA_ARGS__))
#define CRITERION_APPLY_4(Macro, Prefix, Head, ...) Macro(Prefix, Head) CR_EXPAND(CRITERION_APPLY_3(Macro, Prefix, __VA_ARGS__))
#define CRITERION_APPLY_5(Macro, Prefix, Head, ...) Macro(Prefix, Head) CR_EXPAND(CRITERION_APPLY_4(Macro, Prefix, __VA_ARGS__))
#define CRITERION_APPLY_6(Macro, Prefix, Head, ...) Macro(Prefix, Head) CR_EXPAND(CRITERION_APPLY_5(Macro, Prefix, __VA_ARGS__))
#define CRITERION_APPLY_7(Macro, Prefix, Head, ...) Macro(Prefix, Head) CR_EXPAND(CRITERION_APPLY_6(Macro, Prefix, __VA_ARGS__))
#define CRITERION_APPLY_8(Macro, Prefix, Head, ...) Macro(Prefix, Head) CR_EXPAND(CRITERION_APPLY_7(Macro, Prefix, __VA_ARGS__))
#define CRITERION_APPLY_9(Macro, Prefix, Head, ...) Macro(Prefix, Head) CR_EXPAND(CRITERION_APPLY_8(Macro, Prefix, __VA_ARGS__))
#define CRITERION_APPLY_10(Macro, Prefix, Head, ...) Macro(Prefix, Head) CR_EXPAND(CRITERION_APPLY_9(Macro, Prefix, __VA_ARGS__))
#define CRITERION_APPLY_11(Macro, Prefix, Head, ...) Macro(Prefix, Head) CR_EXPAND(CRITERION_APPLY_10(Macro, Prefix, __VA_ARGS__))
#define CRITERION_APPLY_12(Macro, Prefix, Head, ...) Macro(Prefix, Head) CR_EXPAND(CRITERION_APPLY_11(Macro, Prefix, __VA_ARGS__))
#define CRITERION_APPLY_13(Macro, Prefix, Head, ...) Macro(Prefix, Head) CR_EXPAND(CRITERION_APPLY_12(Macro, Prefix, __VA_ARGS__))
#define CRITERION_APPLY_14(Macro, Prefix, Head, ...) Macro(Prefix, Head) CR_EXPAND(CRITERION_APPLY_13(Macro, Prefix, __VA_ARGS__))
#define CRITERION_APPLY_15(Macro, Prefix, Head, ...) Macro(Prefix, Head) CR_EXPAND(CRITERION_APPLY_14(Macro, Prefix, __VA_ARGS__))
#define CRITERION_APPLY_16(Macro, Prefix, Head, ...) Macro(Prefix, Head) CR_EXPAND(CRITERION_APPLY_15(Macro, Prefix, __VA_ARGS__))
#define CRITERION_APPLY_17(Macro, Prefix, Head, ...) Macro(Prefix, Head) CR_EXPAND(CRITERION_APPLY_16(Macro, Prefix, __VA_ARGS__))
#define CRITERION_APPLY_18(Macro, Prefix, Head, ...) Macro(Prefix, Head) CR_EXPAND(CRITERION_APPLY_17(Macro, Prefix, __VA_ARGS__))
#define CRITERION_APPLY_19(Macro, Prefix, Head, ...) Macro(Prefix, Head) CR_EXPAND(CRITERION_APPLY_18(Macro, Prefix, __VA_ARGS__))
#define CRITERION_APPLY_20(Macro, Prefix, Head, ...) Macro(Prefix, Head) CR_EXPAND(CRITERION_APPLY_19(Macro, Prefix, __VA_ARGS__))
#define CRITERION_APPLY_21(Macro, Prefix, Head, ...) Macro(Prefix, Head) CR_EXPAND(CRITERION_APPLY_20(Macro, Prefix, __VA_ARGS__))
#define CRITERION_APPLY_22(Macro, Prefix, Head, ...) Macro(Prefix, Head) CR_EXPAND(CRITERION_APPLY_21(Macro, Prefix, __VA_ARGS__))
#define CRITERION_APPLY_23(Macro, Prefix, Head, ...) Macro(Prefix, Head) CR_EXPAND(CRITERION_APPLY_22(Macro, Prefix, __VA_ARGS__))
#define CRITERION_APPLY_24(Macro, Prefix, Head, ...) Macro(Prefix, Head) CR_EXPAND(CRITERION_APPLY_23(Macro, Prefix, __VA_ARGS__))
#define CRITERION_APPLY_25(Macro, Prefix, Head, ...) Macro(Prefix, Head) CR_EXPAND(CRITERION_APPLY_24(Macro, Prefix, __VA_ARGS__))
#define CRITERION_APPLY_26(Macro, Prefix, Head, ...) Macro(Prefix, Head) CR_EXPAND(CRITERION_APPLY_25(Macro, Prefix, __VA_ARGS__))
#define CRITERION_APPLY_27(Macro, Prefix, Head, ...) Macro(Prefix, Head) CR_EXPAND(CRITERION_APPLY_26(Macro, Prefix, __VA_ARGS__))
#define CRITERION_APPLY_28(Macro, Prefix, Head, ...) Macro(Prefix, Head) CR_EXPAND(CRITERION_APPLY_27(Macro, Prefix, __VA_ARGS__))
#define CRITERION_APPLY_29(Macro, Prefix, Head, ...) Macro(Prefix, Head) CR_EXPAND(CRITERION_APPLY_28(Macro, Prefix, __VA_ARGS__))
#define CRITERION_APPLY_30(Macro, Prefix, Head, ...) Macro(Prefix, Head) CR_EXPAND(CRITERION_APPLY_29(Macro, Prefix, __VA_ARGS__))
#define CRITERION_APPLY_31(Macro, Prefix, Head, ...) Macro(Prefix, Head) CR_EXPAND(CRITERION_APPLY_30(Macro, Prefix, __VA_ARGS__))
#define CRITERION_APPLY_32(Macro, Prefix, Head, ...) Macro(Prefix, Head) CR_EXPAND(CRITERION_APPLY_31(Macro, Prefix, __VA_ARGS__))
#define CRITERION_APPLY_33(Macro, Prefix, Head, ...) Macro(Prefix, Head) CR_EXPAND(CRITERION_APPLY_32(Macro, Prefix, __VA_ARGS__))
#define CRITERION_APPLY_34(Macro, Prefix, Head, ...) Macro(Prefix, Head) CR_EXPAND(CRITERION_APPLY_33(Macro, Prefix, __VA_ARGS__))
#define CRITERION_APPLY_35(Macro, Prefix, Head, ...) Macro(Prefix, Head) CR_EXPAND(CRITERION_APPLY_34(Macro, Prefix, __VA_ARGS__))
#define CRITERION_APPLY_36(Macro, Prefix, Head, ...) Macro(Prefix, Head) CR_EXPAND(CRITERION_APPLY_35(Macro, Prefix, __VA_ARGS__))
#define CRITERION_APPLY_37(Macro, Prefix, Head, ...) Macro(Prefix, Head) CR_EXPAND(CRITERION_APPLY_36(Macro, Prefix, __VA_ARGS__))
#define CRITERION_APPLY_38(Macro, Prefix, Head, ...) Macro(Prefix, Head) CR_EXPAND(CRITERION_APPLY_37(Macro, Prefix, __VA_ARGS__))
#define CRITERION_APPLY_39(Macro, Prefix, Head, ...) Macro(Prefix, Head) CR_EXPAND(CRITERION_APPLY_38(Macro, Prefix, __VA_ARGS__))
#define CRITERION_APPLY_40(Macro, Prefix, Head, ...) Macro(Prefix, Head) CR_EXPAND(CRITERION_APPLY_39(Macro, Prefix, __VA_ARGS__))
#define CRITERION_APPLY_41(Macro, Prefix, Head, ...) Macro(Prefix, Head) CR_EXPAND(CRITERION_APPLY_40(Macro, Prefix, __VA_ARGS__))
#define CRITERION_APPLY_42(Macro, Prefix, Head, ...) Macro(Prefix, Head) CR_EXPAND(CRITERION_APPLY_41(Macro, Prefix, __VA_ARGS__))
#define CRITERION_APPLY_43(Macro, Prefix, Head, ...) Macro(Prefix, Head) CR_EXPAND(CRITERION_APPLY_42(Macro, Prefix, __VA_ARGS__))
#define CRITERION_APPLY_44(Macro, Prefix, Head, ...) Macro(Prefix, Head) CR_EXPAND(CRITERION_APPLY_43(Macro, Prefix, __VA_ARGS__))
#define CRITERION_APPLY_45(Macro, Prefix, Head, ...) Macro(Prefix, Head) CR_EXPAND(CRITERION_APPLY_44(Macro, Prefix, __VA_ARGS__))
#define CRITERION_APPLY_46(Macro, Prefix, Head, ...) Macro(Prefix, Head) CR_EXPAND(CRITERION_APPLY_45(Macro, Prefix, __VA_ARGS__))
#define CRITERION_APPLY_47(Macro, Prefix, Head, ...) Macro(Prefix, Head) CR_EXPAND(CRITERION_APPLY_46(Macro, Prefix, __VA_ARGS__))
#define CRITERION_APPLY_48(Macro, Prefix, Head, ...) Macro(Prefix, Head) CR_EXPAND(CRITERION_APPLY_47(Macro, Prefix, __VA_ARGS__))
#define CRITERION_APPLY_49(Macro, Prefix, Head, ...) Macro(Prefix, Head) CR_EXPAND(CRITERION_APPLY_48(Macro, Prefix, __VA_ARGS__))
#define CRITERION_APPLY_50(Macro, Prefix, Head, ...) Macro(Prefix, Head) CR_EXPAND(CRITERION_APPLY_49(Macro, Prefix, __VA_ARGS__))
#define CRITERION_APPLY_51(Macro, Prefix, Head, ...) Macro(Prefix, Head) CR_EXPAND(CRITERION_APPLY_50(Macro, Prefix, __VA_ARGS__))
#define CRITERION_APPLY_52(Macro, Prefix, Head, ...) Macro(Prefix, Head) CR_EXPAND(CRITERION_APPLY_51(Macro, Prefix, __VA_ARGS__))
#define CRITERION_APPLY_53(Macro, Prefix, Head, ...) Macro(Prefix, Head) CR_EXPAND(CRITERION_APPLY_52(Macro, Prefix, __VA_ARGS__))
#define CRITERION_APPLY_54(Macro, Prefix, Head, ...) Macro(Prefix, Head) CR_EXPAND(CRITERION_APPLY_53(Macro, Prefix, __VA_ARGS__))
#define CRITERION_APPLY_55(Macro, Prefix, Head, ...) Macro(Prefix, Head) CR_EXPAND(CRITERION_APPLY_54(Macro, Prefix, __VA_ARGS__))
#define CRITERION_APPLY_56(Macro, Prefix, Head, ...) Macro(Prefix, Head) CR_EXPAND(CRITERION_APPLY_55(Macro, Prefix, __VA_ARGS__))
#define CRITERION_APPLY_57(Macro, Prefix, Head, ...) Macro(Prefix, Head) CR_EXPAND(CRITERION_APPLY_56(Macro, Prefix, __VA_ARGS__))
#define CRITERION_APPLY_58(Macro, Prefix, Head, ...) Macro(Prefix, Head) CR_EXPAND(CRITERION_APPLY_57(Macro, Prefix, __VA_ARGS__))
#define CRITERION_APPLY_59(Macro, Prefix, Head, ...) Macro(Prefix, Head) CR_EXPAND(CRITERION_APPLY_58(Macro, Prefix, __VA_ARGS__))
#define CRITERION_APPLY_60(Macro, Prefix, Head, ...) Macro(Prefix, Head) CR_EXPAND(CRITERION_APPLY_59(Macro, Prefix, __VA_ARGS__))
#define CRITERION_APPLY_61(Macro, Prefix, Head, ...) Macro(Prefix, Head) CR_EXPAND(CRITERION_APPLY_60(Macro, Prefix, __VA_ARGS__))
#define CRITERION_APPLY_62(Macro, Prefix, Head, ...) Macro(Prefix, Head) CR_EXPAND(CRITERION_APPLY_61(Macro, Prefix, __VA_ARGS__))
#define CRITERION_APPLY_63(Macro, Prefix, Head, ...) Macro(Prefix, Head) CR_EXPAND(CRITERION_APPLY_62(Macro, Prefix, __VA_ARGS__))
#define CRITERION_APPLY_64(Macro, Prefix, Head, ...) Macro(Prefix, Head) CR_EXPAND(CRITERION_APPLY_63(Macro, Prefix, __VA_ARGS__))
#define CRITERION_APPLY_65(Macro, Prefix, Head, ...) Macro(Prefix, Head) CR_EXPAND(CRITERION_APPLY_64(Macro, Prefix, __VA_ARGS__))
# define CRITERION_APPLY__(Macro, Prefix, n, ...) CR_EXPAND(CRITERION_APPLY_##n(Macro, Prefix, __VA_ARGS__,))
# define CRITERION_APPLY_(Macro, n, Prefix, ...) CR_EXPAND(CRITERION_APPLY__(Macro, Prefix, n, __VA_ARGS__))
# define CRITERION_APPLY(Macro, ...) CR_EXPAND(CRITERION_APPLY_(Macro, CRITERION_ARG_LENGTH(__VA_ARGS__), __VA_ARGS__))
#define CRITERION_APPLY__(Macro, Prefix, n, ...) CR_EXPAND(CRITERION_APPLY_ ## n(Macro, Prefix, __VA_ARGS__, ))
#define CRITERION_APPLY_(Macro, n, Prefix, ...) CR_EXPAND(CRITERION_APPLY__(Macro, Prefix, n, __VA_ARGS__))
#define CRITERION_APPLY(Macro, ...) CR_EXPAND(CRITERION_APPLY_(Macro, CRITERION_ARG_LENGTH(__VA_ARGS__), __VA_ARGS__))
# define CRITERION_ADD_PREFIX_ONCE(Prefix, Field) Prefix Field;
# define CRITERION_ADD_PREFIX(...) \
#define CRITERION_ADD_PREFIX_ONCE(Prefix, Field) Prefix Field;
#define CRITERION_ADD_PREFIX(...) \
CR_EXPAND(CRITERION_APPLY(CRITERION_ADD_PREFIX_ONCE, __VA_ARGS__))
# ifdef __cplusplus
# define CRITERION_MAKE_STRUCT(Type, ...) []() -> Type { \
Type t; \
std::memset(&t, 0, sizeof (t)); \
CR_EXPAND(CRITERION_ADD_PREFIX(t, __VA_ARGS__)) \
return t; \
}()
# else
# define CRITERION_MAKE_STRUCT(Type, ...) { __VA_ARGS__ }
# endif
#ifdef __cplusplus
# define CRITERION_MAKE_STRUCT(Type, ...) \
[]() -> Type { \
Type t; \
std::memset(&t, 0, sizeof (t)); \
CR_EXPAND(CRITERION_ADD_PREFIX(t, __VA_ARGS__)) \
return t; \
} ()
#else
# define CRITERION_MAKE_STRUCT(Type, ...) { __VA_ARGS__ }
#endif
#endif /* !CRITERION_DESIGNATED_INITIALIZER_COMPAT_HH_ */

View file

@ -22,63 +22,62 @@
* THE SOFTWARE.
*/
#ifndef CRITERION_INTERNAL_HOOKS_H_
# define CRITERION_INTERNAL_HOOKS_H_
#define CRITERION_INTERNAL_HOOKS_H_
# include "common.h"
# include "../types.h"
#include "common.h"
#include "../types.h"
# define CR_HOOK_IDENTIFIER_(Suffix) CR_HOOK_IDENTIFIER__(__LINE__, Suffix)
# define CR_HOOK_IDENTIFIER__(Line, Suffix) CR_HOOK_IDENTIFIER___(Line, Suffix)
# define CR_HOOK_IDENTIFIER___(Line, Suffix) hook_l ## Line ## _ ## Suffix
#define CR_HOOK_IDENTIFIER_(Suffix) CR_HOOK_IDENTIFIER__(__LINE__, Suffix)
#define CR_HOOK_IDENTIFIER__(Line, Suffix) CR_HOOK_IDENTIFIER___(Line, Suffix)
#define CR_HOOK_IDENTIFIER___(Line, Suffix) hook_l ## Line ## _ ## Suffix
# ifdef __cplusplus
# define CR_HOOK_PROTOTYPE_ \
#ifdef __cplusplus
# define CR_HOOK_PROTOTYPE_ \
extern "C" void CR_HOOK_IDENTIFIER_(impl)
# else
# define CR_HOOK_PROTOTYPE_ \
#else
# define CR_HOOK_PROTOTYPE_ \
void CR_HOOK_IDENTIFIER_(impl)
# endif
#endif
// Section abbreviations
# define CR_HOOK_SECTION_PRE_ALL cr_pra
# define CR_HOOK_SECTION_PRE_SUITE cr_prs
# define CR_HOOK_SECTION_PRE_INIT cr_pri
# define CR_HOOK_SECTION_PRE_TEST cr_prt
# define CR_HOOK_SECTION_ASSERT cr_ast
# define CR_HOOK_SECTION_THEORY_FAIL cr_thf
# define CR_HOOK_SECTION_TEST_CRASH cr_tsc
# define CR_HOOK_SECTION_POST_TEST cr_pot
# define CR_HOOK_SECTION_POST_FINI cr_pof
# define CR_HOOK_SECTION_POST_SUITE cr_pos
# define CR_HOOK_SECTION_POST_ALL cr_poa
/* Section abbreviations */
#define CR_HOOK_SECTION_PRE_ALL cr_pra
#define CR_HOOK_SECTION_PRE_SUITE cr_prs
#define CR_HOOK_SECTION_PRE_INIT cr_pri
#define CR_HOOK_SECTION_PRE_TEST cr_prt
#define CR_HOOK_SECTION_ASSERT cr_ast
#define CR_HOOK_SECTION_THEORY_FAIL cr_thf
#define CR_HOOK_SECTION_TEST_CRASH cr_tsc
#define CR_HOOK_SECTION_POST_TEST cr_pot
#define CR_HOOK_SECTION_POST_FINI cr_pof
#define CR_HOOK_SECTION_POST_SUITE cr_pos
#define CR_HOOK_SECTION_POST_ALL cr_poa
# define CR_HOOK_SECTION(Kind) CR_HOOK_SECTION_ ## Kind
#define CR_HOOK_SECTION(Kind) CR_HOOK_SECTION_ ## Kind
# define CR_HOOK_SECTION_STRINGIFY__(Sec) #Sec
# define CR_HOOK_SECTION_STRINGIFY_(Sec) CR_HOOK_SECTION_STRINGIFY__(Sec)
# define CR_HOOK_SECTION_STRINGIFY(Kind) CR_HOOK_SECTION_STRINGIFY_(CR_HOOK_SECTION(Kind))
#define CR_HOOK_SECTION_STRINGIFY__(Sec) #Sec
#define CR_HOOK_SECTION_STRINGIFY_(Sec) CR_HOOK_SECTION_STRINGIFY__(Sec)
#define CR_HOOK_SECTION_STRINGIFY(Kind) CR_HOOK_SECTION_STRINGIFY_(CR_HOOK_SECTION(Kind))
# define CR_HOOK_PARAM_TYPE_PRE_ALL struct criterion_test_set *
# define CR_HOOK_PARAM_TYPE_PRE_SUITE struct criterion_suite_set *
# define CR_HOOK_PARAM_TYPE_PRE_INIT struct criterion_test *
# define CR_HOOK_PARAM_TYPE_PRE_TEST struct criterion_test *
# define CR_HOOK_PARAM_TYPE_ASSERT struct criterion_assert_stats *
# define CR_HOOK_PARAM_TYPE_THEORY_FAIL struct criterion_theory_stats *
# define CR_HOOK_PARAM_TYPE_TEST_CRASH struct criterion_test_stats *
# define CR_HOOK_PARAM_TYPE_POST_TEST struct criterion_test_stats *
# define CR_HOOK_PARAM_TYPE_POST_FINI struct criterion_test_stats *
# define CR_HOOK_PARAM_TYPE_POST_SUITE struct criterion_suite_stats *
# define CR_HOOK_PARAM_TYPE_POST_ALL struct criterion_global_stats *
#define CR_HOOK_PARAM_TYPE_PRE_ALL struct criterion_test_set *
#define CR_HOOK_PARAM_TYPE_PRE_SUITE struct criterion_suite_set *
#define CR_HOOK_PARAM_TYPE_PRE_INIT struct criterion_test *
#define CR_HOOK_PARAM_TYPE_PRE_TEST struct criterion_test *
#define CR_HOOK_PARAM_TYPE_ASSERT struct criterion_assert_stats *
#define CR_HOOK_PARAM_TYPE_THEORY_FAIL struct criterion_theory_stats *
#define CR_HOOK_PARAM_TYPE_TEST_CRASH struct criterion_test_stats *
#define CR_HOOK_PARAM_TYPE_POST_TEST struct criterion_test_stats *
#define CR_HOOK_PARAM_TYPE_POST_FINI struct criterion_test_stats *
#define CR_HOOK_PARAM_TYPE_POST_SUITE struct criterion_suite_stats *
#define CR_HOOK_PARAM_TYPE_POST_ALL struct criterion_global_stats *
# define CR_HOOK_PARAM_TYPE(Kind) CR_HOOK_PARAM_TYPE_ ## Kind
#define CR_HOOK_PARAM_TYPE(Kind) CR_HOOK_PARAM_TYPE_ ## Kind
# define CR_REPORT_HOOK_IMPL(Kind) \
CR_HOOK_PROTOTYPE_(CR_HOOK_PARAM_TYPE(Kind)); \
CR_SECTION_(CR_HOOK_SECTION_STRINGIFY(Kind)) \
f_report_hook CR_HOOK_IDENTIFIER_(func) = \
(f_report_hook) CR_HOOK_IDENTIFIER_(impl) \
CR_SECTION_SUFFIX_; \
#define CR_REPORT_HOOK_IMPL(Kind) \
CR_HOOK_PROTOTYPE_(CR_HOOK_PARAM_TYPE(Kind)); \
CR_SECTION_(CR_HOOK_SECTION_STRINGIFY(Kind)) \
f_report_hook CR_HOOK_IDENTIFIER_(func) = \
(f_report_hook) CR_HOOK_IDENTIFIER_(impl) \
CR_SECTION_SUFFIX_; \
CR_HOOK_PROTOTYPE_
#endif /* !CRITERION_INTERNAL_HOOKS_H_ */

View file

@ -22,9 +22,9 @@
* THE SOFTWARE.
*/
#ifndef CRITERION_ORDERED_SET_H_
# define CRITERION_ORDERED_SET_H_
#define CRITERION_ORDERED_SET_H_
# include "../types.h"
#include "../types.h"
typedef int (*f_criterion_cmp)(void *, void *);
@ -32,7 +32,7 @@ struct criterion_ordered_set {
struct criterion_ordered_set_node *first;
size_t size;
f_criterion_cmp cmp;
void (*const dtor)(void *, void *);
void(*const dtor)(void *, void *);
};
struct criterion_ordered_set_node {
@ -42,17 +42,17 @@ struct criterion_ordered_set_node {
CR_BEGIN_C_API
CR_API struct criterion_ordered_set *new_ordered_set(f_criterion_cmp cmp,
void (*dtor)(void *, void *));
void (*dtor)(void *, void *));
CR_API void *insert_ordered_set(struct criterion_ordered_set *l,
void *ptr,
size_t size);
void *ptr,
size_t size);
CR_END_C_API
# define FOREACH_SET(Elt, Set) \
#define FOREACH_SET(Elt, Set) \
for (struct criterion_ordered_set_node *n = Set->first; n; n = n->next) \
for (int cond = 1; cond;) \
for (Elt = (void*) (n + 1); cond && (cond = 0, 1);)
for (Elt = (void *) (n + 1); cond && (cond = 0, 1);)
#endif /* !CRITERION_ORDERED_SET_H_ */

View file

@ -22,10 +22,10 @@
* THE SOFTWARE.
*/
#ifndef CRITERION_INTERNAL_PARAMETERIZED_H_
# define CRITERION_INTERNAL_PARAMETERIZED_H_
#define CRITERION_INTERNAL_PARAMETERIZED_H_
# include "test.h"
# include "../types.h"
#include "test.h"
#include "../types.h"
struct criterion_test_params {
size_t size;
@ -33,93 +33,93 @@ struct criterion_test_params {
size_t length;
void (*cleanup)(struct criterion_test_params *);
# ifdef __cplusplus
#ifdef __cplusplus
constexpr criterion_test_params(size_t size, void *params, size_t length)
: size(size)
, params(params)
, length(length)
, cleanup(nullptr)
: size(size),
params(params),
length(length),
cleanup(nullptr)
{}
constexpr criterion_test_params(size_t size, void *params, size_t length,
void (*cleanup)(struct criterion_test_params *))
: size(size)
, params(params)
, length(length)
, cleanup(cleanup)
void(*cleanup)(struct criterion_test_params *))
: size(size),
params(params),
length(length),
cleanup(cleanup)
{}
template <typename T>
constexpr criterion_test_params(std::vector<T, criterion::allocator<T>>& vec,
void (*cleanup)(criterion_test_params *) = nullptr)
: size(sizeof (T))
, params(&vec[0])
, length(vec.size())
, cleanup(cleanup)
constexpr criterion_test_params(std::vector<T, criterion::allocator<T> > &vec,
void(*cleanup)(criterion_test_params *) = nullptr)
: size(sizeof (T)),
params(&vec[0]),
length(vec.size()),
cleanup(cleanup)
{}
template <typename T, unsigned int N>
constexpr criterion_test_params(T (&arr)[N],
void (*cleanup)(criterion_test_params *) = nullptr)
: size(sizeof (arr[0]))
, params(static_cast<void*>(&arr))
, length(N)
, cleanup(cleanup)
void(*cleanup)(criterion_test_params *) = nullptr)
: size(sizeof (arr[0])),
params(static_cast<void *>(&arr)),
length(N),
cleanup(cleanup)
{}
# endif
#endif
};
# ifdef __cplusplus
# define CR_PARAM_TEST_PROTOTYPE_(Param, Category, Name) \
#ifdef __cplusplus
# define CR_PARAM_TEST_PROTOTYPE_(Param, Category, Name) \
extern "C" void CR_IDENTIFIER_(Category, Name, impl)(Param)
# else
# define CR_PARAM_TEST_PROTOTYPE_(Param, Category, Name) \
#else
# define CR_PARAM_TEST_PROTOTYPE_(Param, Category, Name) \
void CR_IDENTIFIER_(Category, Name, impl)(Param)
# endif
#endif
# define CR_PARAM_TEST_BASE(Param, Category, Name, ...) \
CR_PARAM_TEST_PROTOTYPE_(Param, Category, Name); \
CR_TEST_TRAMPOLINE_(Category, Name) \
struct criterion_test_extra_data CR_IDENTIFIER_(Category, Name, extra) = \
CR_EXPAND(CRITERION_MAKE_STRUCT(criterion_test_extra_data, \
.compiler_ = CR_COMPILER_, \
.lang_ = CR_LANG, \
.kind_ = CR_TEST_PARAMETERIZED, \
.param_ = CR_IDENTIFIER_(Category, Name, param), \
.identifier_ = #Category "/" #Name, \
.file_ = __FILE__, \
.line_ = __LINE__, \
__VA_ARGS__ \
)); \
struct criterion_test CR_IDENTIFIER_(Category, Name, meta) = { \
#Name, \
#Category, \
CR_IDENTIFIER_(Category, Name, jmp), \
&CR_IDENTIFIER_(Category, Name, extra) \
}; \
CR_SECTION_("cr_tst") \
struct criterion_test *CR_IDENTIFIER_(Category, Name, ptr) \
= &CR_IDENTIFIER_(Category, Name, meta) CR_SECTION_SUFFIX_; \
#define CR_PARAM_TEST_BASE(Param, Category, Name, ...) \
CR_PARAM_TEST_PROTOTYPE_(Param, Category, Name); \
CR_TEST_TRAMPOLINE_(Category, Name) \
struct criterion_test_extra_data CR_IDENTIFIER_(Category, Name, extra) = \
CR_EXPAND(CRITERION_MAKE_STRUCT(criterion_test_extra_data, \
.compiler_ = CR_COMPILER_, \
.lang_ = CR_LANG, \
.kind_ = CR_TEST_PARAMETERIZED, \
.param_ = CR_IDENTIFIER_(Category, Name, param), \
.identifier_ = #Category "/" #Name, \
.file_ = __FILE__, \
.line_ = __LINE__, \
__VA_ARGS__ \
)); \
struct criterion_test CR_IDENTIFIER_(Category, Name, meta) = { \
#Name, \
#Category, \
CR_IDENTIFIER_(Category, Name, jmp), \
&CR_IDENTIFIER_(Category, Name, extra) \
}; \
CR_SECTION_("cr_tst") \
struct criterion_test *CR_IDENTIFIER_(Category, Name, ptr) \
= &CR_IDENTIFIER_(Category, Name, meta) CR_SECTION_SUFFIX_; \
CR_PARAM_TEST_PROTOTYPE_(Param, Category, Name)
# define CR_PARAM_TEST_PARAMS(Category, Name) \
#define CR_PARAM_TEST_PARAMS(Category, Name) \
static struct criterion_test_params CR_IDENTIFIER_(Category, Name, param)(void)
# ifdef __cplusplus
# define cr_make_param_array_(Type, Array, ...) \
#ifdef __cplusplus
# define cr_make_param_array_(Type, Array, ...) \
criterion_test_params(sizeof (Type), (Array), __VA_ARGS__)
# else
# define cr_make_param_array_(Type, Array, ...) \
(struct criterion_test_params) { .size = sizeof (Type), (void*)(Array), __VA_ARGS__ }
# endif
#else
# define cr_make_param_array_(Type, Array, ...) \
(struct criterion_test_params) { .size = sizeof (Type), (void *) (Array), __VA_ARGS__ }
#endif
# undef ParameterizedTest
# define ParameterizedTest(...) CR_EXPAND(CR_PARAM_TEST_BASE(__VA_ARGS__, .sentinel_ = 0))
#undef ParameterizedTest
#define ParameterizedTest(...) CR_EXPAND(CR_PARAM_TEST_BASE(__VA_ARGS__, .sentinel_ = 0))
# undef ParameterizedTestParameters
# define ParameterizedTestParameters(Suite, Name) CR_PARAM_TEST_PARAMS(Suite, Name)
#undef ParameterizedTestParameters
#define ParameterizedTestParameters(Suite, Name) CR_PARAM_TEST_PARAMS(Suite, Name)
# undef cr_make_param_array
# define cr_make_param_array(...) CR_EXPAND(cr_make_param_array_(__VA_ARGS__))
#undef cr_make_param_array
#define cr_make_param_array(...) CR_EXPAND(cr_make_param_array_(__VA_ARGS__))
#endif /* !CRITERION_INTERNAL_PARAMETERIZED_H_ */

View file

@ -22,52 +22,53 @@
* THE SOFTWARE.
*/
#ifndef CRITERION_PREPROCESS_H_
# define CRITERION_PREPROCESS_H_
#define CRITERION_PREPROCESS_H_
# define CR_NOOP do {} while(0)
#define CR_NOOP do {} while (0)
# ifdef __cplusplus
# define CR_NOTHROW throw()
# else
# define CR_NOTHROW
# endif
#ifdef __cplusplus
# define CR_NOTHROW throw ()
#else
# define CR_NOTHROW
#endif
# define CR_EXPAND(x) x
# define CR_IDENTITY(...) __VA_ARGS__
#define CR_EXPAND(x) x
#define CR_IDENTITY(...) __VA_ARGS__
# define CR_STR(x) CR_EXPAND(CR_STR_(x))
# define CR_STR_(x) #x
#define CR_STR(x) CR_EXPAND(CR_STR_(x))
#define CR_STR_(x) #x
# define CR_VA_TAIL(...) CR_EXPAND(CR_VA_TAIL_HELPER(CR_VA_TAIL_SELECT(__VA_ARGS__), __VA_ARGS__))
#define CR_VA_TAIL(...) CR_EXPAND(CR_VA_TAIL_HELPER(CR_VA_TAIL_SELECT(__VA_ARGS__), __VA_ARGS__))
# define CR_VA_TAIL_HELPER(N, ...) CR_EXPAND(CR_VA_TAIL_HELPER_(N, __VA_ARGS__))
# define CR_VA_TAIL_HELPER_(N, ...) CR_EXPAND(CR_VA_TAIL_HELPER_##N(__VA_ARGS__))
# define CR_VA_TAIL_HELPER_1(Head)
# define CR_VA_TAIL_HELPER_2(Head, ...) __VA_ARGS__
#define CR_VA_TAIL_HELPER(N, ...) CR_EXPAND(CR_VA_TAIL_HELPER_(N, __VA_ARGS__))
#define CR_VA_TAIL_HELPER_(N, ...) CR_EXPAND(CR_VA_TAIL_HELPER_ ## N(__VA_ARGS__))
#define CR_VA_TAIL_HELPER_1(Head)
#define CR_VA_TAIL_HELPER_2(Head, ...) __VA_ARGS__
# define CR_VA_HEAD(...) CR_EXPAND(CR_VA_HEAD_HELPER(CR_VA_TAIL_SELECT(__VA_ARGS__), __VA_ARGS__))
#define CR_VA_HEAD(...) CR_EXPAND(CR_VA_HEAD_HELPER(CR_VA_TAIL_SELECT(__VA_ARGS__), __VA_ARGS__))
# define CR_VA_HEAD_HELPER(N, ...) CR_EXPAND(CR_VA_HEAD_HELPER_(N, __VA_ARGS__))
# define CR_VA_HEAD_HELPER_(N, ...) CR_EXPAND(CR_VA_HEAD_HELPER_##N(__VA_ARGS__))
# define CR_VA_HEAD_HELPER_1(Head) Head
# define CR_VA_HEAD_HELPER_2(Head, ...) Head
#define CR_VA_HEAD_HELPER(N, ...) CR_EXPAND(CR_VA_HEAD_HELPER_(N, __VA_ARGS__))
#define CR_VA_HEAD_HELPER_(N, ...) CR_EXPAND(CR_VA_HEAD_HELPER_ ## N(__VA_ARGS__))
#define CR_VA_HEAD_HELPER_1(Head) Head
#define CR_VA_HEAD_HELPER_2(Head, ...) Head
# define CR_VA_TAIL_SELECT(...) CR_EXPAND(CR_VA_TAIL_SELECT64(__VA_ARGS__, \
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, \
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, \
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, \
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, \
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, \
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, \
2, 2, 1, _))
#define CR_VA_TAIL_SELECT(...) \
CR_EXPAND(CR_VA_TAIL_SELECT64(__VA_ARGS__, \
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, \
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, \
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, \
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, \
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, \
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, \
2, 2, 1, _))
# define CR_VA_TAIL_SELECT64( \
#define CR_VA_TAIL_SELECT64( \
_01, _02, _03, _04, _05, _06, _07, _08, _09, _10, \
_11, _12, _13, _14, _15, _16, _17, _18, _19, _20, \
_21, _22, _23, _24, _25, _26, _27, _28, _29, _30, \
_31, _32, _33, _34, _35, _36, _37, _38, _39, _40, \
_41, _42, _43, _44, _45, _46, _47, _48, _49, _50, \
_51, _52, _53, _54, _55, _56, _57, _58, _59, _60, \
_61, _62, _63, X, ...) X
_61, _62, _63, X, ...) X
#endif /* !CRITERION_PREPROCESS_H_ */

View file

@ -22,148 +22,148 @@
* THE SOFTWARE.
*/
#ifndef CRITERION_INTERNAL_REDIRECT_H_
# define CRITERION_INTERNAL_REDIRECT_H_
#define CRITERION_INTERNAL_REDIRECT_H_
# include "common.h"
# include "assert.h"
#include "common.h"
#include "assert.h"
CR_BEGIN_C_API
CR_API int cr_stdout_match_file(CR_STDN FILE* ref);
CR_API int cr_stdout_match_str(const char* ref);
CR_API int cr_stderr_match_file(CR_STDN FILE* ref);
CR_API int cr_stderr_match_str(const char* ref);
CR_API int cr_stdout_match_file(CR_STDN FILE *ref);
CR_API int cr_stdout_match_str(const char *ref);
CR_API int cr_stderr_match_file(CR_STDN FILE *ref);
CR_API int cr_stderr_match_str(const char *ref);
CR_END_C_API
# define cr_assert_redir_op_(Fail, Fun, Op, File, Str, ...) \
CR_EXPAND(cr_assert_impl( \
Fail, \
!(Fun((File), (Str)) Op 0), \
dummy, \
CRITERION_ASSERT_MSG_FILE_STR_MATCH, \
(CR_STR(File), Str), \
__VA_ARGS__ \
))
#define cr_assert_redir_op_(Fail, Fun, Op, File, Str, ...) \
CR_EXPAND(cr_assert_impl( \
Fail, \
!(Fun((File), (Str)) Op 0), \
dummy, \
CRITERION_ASSERT_MSG_FILE_STR_MATCH, \
(CR_STR(File), Str), \
__VA_ARGS__ \
))
# define cr_assert_redir_op_va_(Fail, Fun, Op, ...) \
CR_EXPAND(cr_assert_redir_op_( \
Fail, \
Fun, \
Op, \
CR_VA_HEAD(__VA_ARGS__), \
CR_VA_HEAD(CR_VA_TAIL(__VA_ARGS__)), \
CR_VA_TAIL(CR_VA_TAIL(__VA_ARGS__)) \
))
#define cr_assert_redir_op_va_(Fail, Fun, Op, ...) \
CR_EXPAND(cr_assert_redir_op_( \
Fail, \
Fun, \
Op, \
CR_VA_HEAD(__VA_ARGS__), \
CR_VA_HEAD(CR_VA_TAIL(__VA_ARGS__)), \
CR_VA_TAIL(CR_VA_TAIL(__VA_ARGS__)) \
))
# define cr_assert_redir_f_op_(Fail, Fun, Op, File, Ref, ...) \
CR_EXPAND(cr_assert_impl( \
Fail, \
!(Fun((File), (Ref)) Op 0), \
dummy, \
CRITERION_ASSERT_MSG_FILE_MATCH, \
(CR_STR(File), CR_STR(Ref)), \
__VA_ARGS__ \
))
#define cr_assert_redir_f_op_(Fail, Fun, Op, File, Ref, ...) \
CR_EXPAND(cr_assert_impl( \
Fail, \
!(Fun((File), (Ref)) Op 0), \
dummy, \
CRITERION_ASSERT_MSG_FILE_MATCH, \
(CR_STR(File), CR_STR(Ref)), \
__VA_ARGS__ \
))
# define cr_assert_redir_f_op_va_(Fail, Fun, Op, ...) \
CR_EXPAND(cr_assert_redir_f_op_( \
Fail, \
Fun, \
Op, \
CR_VA_HEAD(__VA_ARGS__), \
CR_VA_HEAD(CR_VA_TAIL(__VA_ARGS__)), \
CR_VA_TAIL(CR_VA_TAIL(__VA_ARGS__)) \
))
#define cr_assert_redir_f_op_va_(Fail, Fun, Op, ...) \
CR_EXPAND(cr_assert_redir_f_op_( \
Fail, \
Fun, \
Op, \
CR_VA_HEAD(__VA_ARGS__), \
CR_VA_HEAD(CR_VA_TAIL(__VA_ARGS__)), \
CR_VA_TAIL(CR_VA_TAIL(__VA_ARGS__)) \
))
# undef cr_assert_file_contents_eq_str
# define cr_assert_file_contents_eq_str(...) CR_EXPAND(cr_assert_redir_op_va_(CR_FAIL_ABORT_, cr_file_match_str, ==, __VA_ARGS__))
# undef cr_expect_file_contents_eq_str
# define cr_expect_file_contents_eq_str(...) CR_EXPAND(cr_assert_redir_op_va_(CR_FAIL_CONTINUES_, cr_file_match_str, ==, __VA_ARGS__))
# undef cr_assert_file_contents_neq_str
# define cr_assert_file_contents_neq_str(...) CR_EXPAND(cr_assert_redir_op_va_(CR_FAIL_ABORT_, cr_file_match_str, !=, __VA_ARGS__))
# undef cr_expect_file_contents_neq_str
# define cr_expect_file_contents_neq_str(...) CR_EXPAND(cr_assert_redir_op_va_(CR_FAIL_CONTINUES_, cr_file_match_str, !=, __VA_ARGS__))
# undef cr_assert_file_contents_eq
# define cr_assert_file_contents_eq(...) CR_EXPAND(cr_assert_redir_f_op_va_(CR_FAIL_ABORT_, cr_file_match_file, ==, __VA_ARGS__))
# undef cr_expect_file_contents_eq
# define cr_expect_file_contents_eq(...) CR_EXPAND(cr_assert_redir_f_op_va_(CR_FAIL_CONTINUES_, cr_file_match_file, ==, __VA_ARGS__))
# undef cr_assert_file_contents_neq
# define cr_assert_file_contents_neq(...) CR_EXPAND(cr_assert_redir_f_op_va_(CR_FAIL_ABORT_, cr_file_match_file, !=, __VA_ARGS__))
# undef cr_expect_file_contents_neq
# define cr_expect_file_contents_neq(...) CR_EXPAND(cr_assert_redir_f_op_va_(CR_FAIL_CONTINUES_, cr_file_match_file, !=, __VA_ARGS__))
#undef cr_assert_file_contents_eq_str
#define cr_assert_file_contents_eq_str(...) CR_EXPAND(cr_assert_redir_op_va_(CR_FAIL_ABORT_, cr_file_match_str, ==, __VA_ARGS__))
#undef cr_expect_file_contents_eq_str
#define cr_expect_file_contents_eq_str(...) CR_EXPAND(cr_assert_redir_op_va_(CR_FAIL_CONTINUES_, cr_file_match_str, ==, __VA_ARGS__))
#undef cr_assert_file_contents_neq_str
#define cr_assert_file_contents_neq_str(...) CR_EXPAND(cr_assert_redir_op_va_(CR_FAIL_ABORT_, cr_file_match_str, !=, __VA_ARGS__))
#undef cr_expect_file_contents_neq_str
#define cr_expect_file_contents_neq_str(...) CR_EXPAND(cr_assert_redir_op_va_(CR_FAIL_CONTINUES_, cr_file_match_str, !=, __VA_ARGS__))
#undef cr_assert_file_contents_eq
#define cr_assert_file_contents_eq(...) CR_EXPAND(cr_assert_redir_f_op_va_(CR_FAIL_ABORT_, cr_file_match_file, ==, __VA_ARGS__))
#undef cr_expect_file_contents_eq
#define cr_expect_file_contents_eq(...) CR_EXPAND(cr_assert_redir_f_op_va_(CR_FAIL_CONTINUES_, cr_file_match_file, ==, __VA_ARGS__))
#undef cr_assert_file_contents_neq
#define cr_assert_file_contents_neq(...) CR_EXPAND(cr_assert_redir_f_op_va_(CR_FAIL_ABORT_, cr_file_match_file, !=, __VA_ARGS__))
#undef cr_expect_file_contents_neq
#define cr_expect_file_contents_neq(...) CR_EXPAND(cr_assert_redir_f_op_va_(CR_FAIL_CONTINUES_, cr_file_match_file, !=, __VA_ARGS__))
# undef cr_assert_stdout_eq_str
# define cr_assert_stdout_eq_str(...) CR_EXPAND(cr_assert_redir_unop_va_(CR_FAIL_ABORT_, cr_stdout_match_str, ==, stdout, __VA_ARGS__))
# undef cr_expect_stdout_eq_str
# define cr_expect_stdout_eq_str(...) CR_EXPAND(cr_assert_redir_unop_va_(CR_FAIL_CONTINUES_, cr_stdout_match_str, ==, stdout, __VA_ARGS__))
# undef cr_assert_stdout_neq_str
# define cr_assert_stdout_neq_str(...) CR_EXPAND(cr_assert_redir_unop_va_(CR_FAIL_ABORT_, cr_stdout_match_str, !=, stdout, __VA_ARGS__))
# undef cr_expect_stdout_neq_str
# define cr_expect_stdout_neq_str(...) CR_EXPAND(cr_assert_redir_unop_va_(CR_FAIL_CONTINUES_, cr_stdout_match_str, !=, stdout, __VA_ARGS__))
# undef cr_assert_stderr_eq_str
# define cr_assert_stderr_eq_str(...) CR_EXPAND(cr_assert_redir_unop_va_(CR_FAIL_ABORT_, cr_stderr_match_str, ==, stderr, __VA_ARGS__))
# undef cr_expect_stderr_eq_str
# define cr_expect_stderr_eq_str(...) CR_EXPAND(cr_assert_redir_unop_va_(CR_FAIL_CONTINUES_, cr_stderr_match_str, ==, stderr, __VA_ARGS__))
# undef cr_assert_stderr_neq_str
# define cr_assert_stderr_neq_str(...) CR_EXPAND(cr_assert_redir_unop_va_(CR_FAIL_ABORT_, cr_stderr_match_str, !=, stderr, __VA_ARGS__))
# undef cr_expect_stderr_neq_str
# define cr_expect_stderr_neq_str(...) CR_EXPAND(cr_assert_redir_unop_va_(CR_FAIL_CONTINUES_, cr_stderr_match_str, !=, stderr, __VA_ARGS__))
# undef cr_assert_stdout_eq
# define cr_assert_stdout_eq(...) CR_EXPAND(cr_assert_redir_f_unop_va_(CR_FAIL_ABORT_, cr_stdout_match_file, ==, stdout, __VA_ARGS__))
# undef cr_expect_stdout_eq
# define cr_expect_stdout_eq(...) CR_EXPAND(cr_assert_redir_f_unop_va_(CR_FAIL_CONTINUES_, cr_stdout_match_file, ==, stdout, __VA_ARGS__))
# undef cr_assert_stdout_neq
# define cr_assert_stdout_neq(...) CR_EXPAND(cr_assert_redir_f_unop_va_(CR_FAIL_ABORT_, cr_stdout_match_file, !=, stdout, __VA_ARGS__))
# undef cr_expect_stdout_neq
# define cr_expect_stdout_neq(...) CR_EXPAND(cr_assert_redir_f_unop_va_(CR_FAIL_CONTINUES_, cr_stdout_match_file, !=, stdout, __VA_ARGS__))
# undef cr_assert_stderr_eq
# define cr_assert_stderr_eq(...) CR_EXPAND(cr_assert_redir_f_unop_va_(CR_FAIL_ABORT_, cr_stderr_match_file, ==, stderr, __VA_ARGS__))
# undef cr_expect_stderr_eq
# define cr_expect_stderr_eq(...) CR_EXPAND(cr_assert_redir_f_unop_va_(CR_FAIL_CONTINUES_, cr_stderr_match_file, ==, stderr, __VA_ARGS__))
# undef cr_assert_stderr_neq
# define cr_assert_stderr_neq(...) CR_EXPAND(cr_assert_redir_f_unop_va_(CR_FAIL_ABORT_, cr_stderr_match_file, !=, stderr, __VA_ARGS__))
# undef cr_expect_stderr_neq
# define cr_expect_stderr_neq(...) CR_EXPAND(cr_assert_redir_f_unop_va_(CR_FAIL_CONTINUES_, cr_stderr_match_file, !=, stderr, __VA_ARGS__))
#undef cr_assert_stdout_eq_str
#define cr_assert_stdout_eq_str(...) CR_EXPAND(cr_assert_redir_unop_va_(CR_FAIL_ABORT_, cr_stdout_match_str, ==, stdout, __VA_ARGS__))
#undef cr_expect_stdout_eq_str
#define cr_expect_stdout_eq_str(...) CR_EXPAND(cr_assert_redir_unop_va_(CR_FAIL_CONTINUES_, cr_stdout_match_str, ==, stdout, __VA_ARGS__))
#undef cr_assert_stdout_neq_str
#define cr_assert_stdout_neq_str(...) CR_EXPAND(cr_assert_redir_unop_va_(CR_FAIL_ABORT_, cr_stdout_match_str, !=, stdout, __VA_ARGS__))
#undef cr_expect_stdout_neq_str
#define cr_expect_stdout_neq_str(...) CR_EXPAND(cr_assert_redir_unop_va_(CR_FAIL_CONTINUES_, cr_stdout_match_str, !=, stdout, __VA_ARGS__))
#undef cr_assert_stderr_eq_str
#define cr_assert_stderr_eq_str(...) CR_EXPAND(cr_assert_redir_unop_va_(CR_FAIL_ABORT_, cr_stderr_match_str, ==, stderr, __VA_ARGS__))
#undef cr_expect_stderr_eq_str
#define cr_expect_stderr_eq_str(...) CR_EXPAND(cr_assert_redir_unop_va_(CR_FAIL_CONTINUES_, cr_stderr_match_str, ==, stderr, __VA_ARGS__))
#undef cr_assert_stderr_neq_str
#define cr_assert_stderr_neq_str(...) CR_EXPAND(cr_assert_redir_unop_va_(CR_FAIL_ABORT_, cr_stderr_match_str, !=, stderr, __VA_ARGS__))
#undef cr_expect_stderr_neq_str
#define cr_expect_stderr_neq_str(...) CR_EXPAND(cr_assert_redir_unop_va_(CR_FAIL_CONTINUES_, cr_stderr_match_str, !=, stderr, __VA_ARGS__))
#undef cr_assert_stdout_eq
#define cr_assert_stdout_eq(...) CR_EXPAND(cr_assert_redir_f_unop_va_(CR_FAIL_ABORT_, cr_stdout_match_file, ==, stdout, __VA_ARGS__))
#undef cr_expect_stdout_eq
#define cr_expect_stdout_eq(...) CR_EXPAND(cr_assert_redir_f_unop_va_(CR_FAIL_CONTINUES_, cr_stdout_match_file, ==, stdout, __VA_ARGS__))
#undef cr_assert_stdout_neq
#define cr_assert_stdout_neq(...) CR_EXPAND(cr_assert_redir_f_unop_va_(CR_FAIL_ABORT_, cr_stdout_match_file, !=, stdout, __VA_ARGS__))
#undef cr_expect_stdout_neq
#define cr_expect_stdout_neq(...) CR_EXPAND(cr_assert_redir_f_unop_va_(CR_FAIL_CONTINUES_, cr_stdout_match_file, !=, stdout, __VA_ARGS__))
#undef cr_assert_stderr_eq
#define cr_assert_stderr_eq(...) CR_EXPAND(cr_assert_redir_f_unop_va_(CR_FAIL_ABORT_, cr_stderr_match_file, ==, stderr, __VA_ARGS__))
#undef cr_expect_stderr_eq
#define cr_expect_stderr_eq(...) CR_EXPAND(cr_assert_redir_f_unop_va_(CR_FAIL_CONTINUES_, cr_stderr_match_file, ==, stderr, __VA_ARGS__))
#undef cr_assert_stderr_neq
#define cr_assert_stderr_neq(...) CR_EXPAND(cr_assert_redir_f_unop_va_(CR_FAIL_ABORT_, cr_stderr_match_file, !=, stderr, __VA_ARGS__))
#undef cr_expect_stderr_neq
#define cr_expect_stderr_neq(...) CR_EXPAND(cr_assert_redir_f_unop_va_(CR_FAIL_CONTINUES_, cr_stderr_match_file, !=, stderr, __VA_ARGS__))
# define cr_assert_redir_unop_(Fail, Fun, Op, File, Str, ...) \
CR_EXPAND(cr_assert_impl( \
Fail, \
!(Fun((Str)) Op 0), \
dummy, \
CRITERION_ASSERT_MSG_FILE_STR_MATCH, \
(CR_STR(File), Str), \
__VA_ARGS__ \
))
#define cr_assert_redir_unop_(Fail, Fun, Op, File, Str, ...) \
CR_EXPAND(cr_assert_impl( \
Fail, \
!(Fun((Str)) Op 0), \
dummy, \
CRITERION_ASSERT_MSG_FILE_STR_MATCH, \
(CR_STR(File), Str), \
__VA_ARGS__ \
))
# define cr_assert_redir_unop_va_(Fail, Fun, Op, ...) \
CR_EXPAND(cr_assert_redir_unop_( \
Fail, \
Fun, \
Op, \
CR_VA_HEAD(__VA_ARGS__), \
CR_VA_HEAD(CR_VA_TAIL(__VA_ARGS__)), \
CR_VA_TAIL(CR_VA_TAIL(__VA_ARGS__)) \
))
#define cr_assert_redir_unop_va_(Fail, Fun, Op, ...) \
CR_EXPAND(cr_assert_redir_unop_( \
Fail, \
Fun, \
Op, \
CR_VA_HEAD(__VA_ARGS__), \
CR_VA_HEAD(CR_VA_TAIL(__VA_ARGS__)), \
CR_VA_TAIL(CR_VA_TAIL(__VA_ARGS__)) \
))
# define cr_assert_redir_f_unop_(Fail, Fun, Op, File, Ref, ...) \
CR_EXPAND(cr_assert_impl( \
Fail, \
!(Fun((Ref)) Op 0), \
dummy, \
CRITERION_ASSERT_MSG_FILE_MATCH, \
(CR_STR(File), CR_STR(Ref)), \
__VA_ARGS__ \
))
#define cr_assert_redir_f_unop_(Fail, Fun, Op, File, Ref, ...) \
CR_EXPAND(cr_assert_impl( \
Fail, \
!(Fun((Ref)) Op 0), \
dummy, \
CRITERION_ASSERT_MSG_FILE_MATCH, \
(CR_STR(File), CR_STR(Ref)), \
__VA_ARGS__ \
))
# define cr_assert_redir_f_unop_va_(Fail, Fun, Op, ...) \
CR_EXPAND(cr_assert_redir_f_unop_( \
Fail, \
Fun, \
Op, \
CR_VA_HEAD(__VA_ARGS__), \
CR_VA_HEAD(CR_VA_TAIL(__VA_ARGS__)), \
CR_VA_TAIL(CR_VA_TAIL(__VA_ARGS__)) \
))
#define cr_assert_redir_f_unop_va_(Fail, Fun, Op, ...) \
CR_EXPAND(cr_assert_redir_f_unop_( \
Fail, \
Fun, \
Op, \
CR_VA_HEAD(__VA_ARGS__), \
CR_VA_HEAD(CR_VA_TAIL(__VA_ARGS__)), \
CR_VA_TAIL(CR_VA_TAIL(__VA_ARGS__)) \
))
#endif /* !CRITERION_INTERNAL_REDIRECT_H_ */

View file

@ -22,141 +22,159 @@
* THE SOFTWARE.
*/
#ifndef CRITERION_INTERNAL_STDIO_FILEBUF_HXX_
# define CRITERION_INTERNAL_STDIO_FILEBUF_HXX_
#define CRITERION_INTERNAL_STDIO_FILEBUF_HXX_
# include <fstream>
#include <fstream>
/* *INDENT-OFF* */
namespace criterion { namespace internal {
/* *INDENT-ON* */
template <typename CharT, typename Traits = std::char_traits<CharT>>
class stdio_sync_filebuf : public std::basic_streambuf<CharT, Traits> {
public:
typedef Traits traits;
typedef std::basic_filebuf<CharT, Traits> super;
typedef typename Traits::int_type int_type;
typedef typename Traits::pos_type pos_type;
typedef typename Traits::off_type off_type;
template <typename CharT, typename Traits = std::char_traits<CharT> >
class stdio_sync_filebuf : public std::basic_streambuf<CharT, Traits> {
public:
typedef Traits traits;
typedef std::basic_filebuf<CharT, Traits> super;
typedef typename Traits::int_type int_type;
typedef typename Traits::pos_type pos_type;
typedef typename Traits::off_type off_type;
stdio_sync_filebuf(std::FILE *file)
: file(file)
, lastchar(Traits::eof())
{}
stdio_sync_filebuf(std::FILE *file)
: file(file),
lastchar(Traits::eof())
{}
stdio_sync_filebuf(stdio_sync_filebuf&& other) = default;
stdio_sync_filebuf& operator=(stdio_sync_filebuf&& other) = default;
stdio_sync_filebuf(stdio_sync_filebuf &&other) = default;
stdio_sync_filebuf &operator=(stdio_sync_filebuf &&other) = default;
void swap(stdio_sync_filebuf& other) {
super::swap(other);
std::swap(file, other.file);
std::swap(lastchar, other.lastchar);
}
void swap(stdio_sync_filebuf &other)
{
super::swap(other);
std::swap(file, other.file);
std::swap(lastchar, other.lastchar);
}
protected:
int_type syncgetc();
int_type syncungetc(int_type);
int_type syncputc(int_type);
protected:
int_type syncgetc();
int_type syncungetc(int_type);
int_type syncputc(int_type);
virtual std::streampos seekoff(std::streamoff off,
std::ios_base::seekdir dir,
std::ios_base::openmode = std::ios_base::in | std::ios_base::out) {
virtual std::streampos seekoff(std::streamoff off,
std::ios_base::seekdir dir,
std::ios_base::openmode = std::ios_base::in | std::ios_base::out)
{
int whence;
int whence;
if (dir == std::ios_base::beg)
whence = SEEK_SET;
else if (dir == std::ios_base::cur)
whence = SEEK_CUR;
if (dir == std::ios_base::beg)
whence = SEEK_SET;
else if (dir == std::ios_base::cur)
whence = SEEK_CUR;
else
whence = SEEK_END;
if (!fseek(file, off, whence))
return std::streampos(std::ftell(file));
return std::streamoff(-1);
}
virtual std::streampos seekpos(std::streampos pos,
std::ios_base::openmode mode = std::ios_base::in | std::ios_base::out)
{
return seekoff(std::streamoff(pos), std::ios_base::beg, mode);
}
virtual std::streamsize xsgetn(CharT *s, std::streamsize n);
virtual std::streamsize xsputn(const CharT *s, std::streamsize n);
virtual int sync()
{
return std::fflush(file);
}
virtual int_type underflow()
{
int_type c = syncgetc();
return syncungetc(c);
}
virtual int_type uflow()
{
return lastchar = syncgetc();
}
static inline bool is_eof(int_type c)
{
static const int_type eof = Traits::eof();
return Traits::eq_int_type(c, eof);
}
virtual int_type overflow(int_type c = Traits::eof())
{
int_type ret;
if (is_eof(c)) {
if (std::fflush(file))
ret = Traits::eof();
else
whence = SEEK_END;
if (!fseek(file, off, whence))
return std::streampos(std::ftell(file));
return std::streamoff(-1);
ret = Traits::not_eof(c);
} else {
ret = syncputc(c);
}
virtual std::streampos seekpos(std::streampos pos,
std::ios_base::openmode mode = std::ios_base::in | std::ios_base::out) {
return seekoff(std::streamoff(pos), std::ios_base::beg, mode);
}
virtual std::streamsize xsgetn(CharT* s, std::streamsize n);
virtual std::streamsize xsputn(const CharT* s, std::streamsize n);
virtual int sync() {
return std::fflush(file);
}
virtual int_type underflow() {
int_type c = syncgetc();
return syncungetc(c);
}
virtual int_type uflow() {
return lastchar = syncgetc();
}
static inline bool is_eof(int_type c) {
static const int_type eof = Traits::eof();
return Traits::eq_int_type(c, eof);
}
virtual int_type overflow(int_type c = Traits::eof()) {
int_type ret;
if (is_eof(c)) {
if (std::fflush(file))
ret = Traits::eof();
else
ret = Traits::not_eof(c);
} else {
ret = syncputc(c);
}
return ret;
}
virtual int_type pbackfail(int_type c = Traits::eof()) {
int_type ret = syncungetc(is_eof(c) && !is_eof(lastchar) ? lastchar : c);
lastchar = Traits::eof();
return ret;
}
private:
std::FILE *file;
bool file_open;
int_type lastchar;
};
template <>
inline stdio_sync_filebuf<char>::int_type
stdio_sync_filebuf<char>::syncgetc() {
return std::getc(file);
return ret;
}
template <>
inline stdio_sync_filebuf<char>::int_type
stdio_sync_filebuf<char>::syncungetc(stdio_sync_filebuf<char>::int_type c) {
return std::ungetc(c, file);
virtual int_type pbackfail(int_type c = Traits::eof())
{
int_type ret = syncungetc(is_eof(c) && !is_eof(lastchar) ? lastchar : c);
lastchar = Traits::eof();
return ret;
}
template <>
inline stdio_sync_filebuf<char>::int_type
stdio_sync_filebuf<char>::syncputc(stdio_sync_filebuf<char>::int_type c) {
return std::putc(c, file);
}
private:
std::FILE *file;
bool file_open;
int_type lastchar;
};
template <>
inline std::streamsize
stdio_sync_filebuf<char>::xsgetn(char *s, std::streamsize n) {
std::streamsize res = std::fread(s, 1, n, file);
lastchar = res > 0 ? traits::to_int_type(s[res - 1]) : traits::eof();
return res;
}
template <>
inline stdio_sync_filebuf<char>::int_type
stdio_sync_filebuf<char>::syncgetc()
{
return std::getc(file);
}
template <>
inline std::streamsize
stdio_sync_filebuf<char>::xsputn(const char *s, std::streamsize n) {
return std::fwrite(s, 1, n, file);
}
template <>
inline stdio_sync_filebuf<char>::int_type
stdio_sync_filebuf<char>::syncungetc(stdio_sync_filebuf<char>::int_type c)
{
return std::ungetc(c, file);
}
template <>
inline stdio_sync_filebuf<char>::int_type
stdio_sync_filebuf<char>::syncputc(stdio_sync_filebuf<char>::int_type c)
{
return std::putc(c, file);
}
template <>
inline std::streamsize
stdio_sync_filebuf<char>::xsgetn(char *s, std::streamsize n)
{
std::streamsize res = std::fread(s, 1, n, file);
lastchar = res > 0 ? traits::to_int_type(s[res - 1]) : traits::eof();
return res;
}
template <>
inline std::streamsize
stdio_sync_filebuf<char>::xsputn(const char *s, std::streamsize n)
{
return std::fwrite(s, 1, n, file);
}
/* *INDENT-OFF* */
}}

View file

@ -22,113 +22,117 @@
* THE SOFTWARE.
*/
#ifndef CRITERION_INTERNAL_STREAM_HXX_
# define CRITERION_INTERNAL_STREAM_HXX_
#define CRITERION_INTERNAL_STREAM_HXX_
# include <fstream>
# include <cstdio>
# include <memory>
#include <fstream>
#include <cstdio>
#include <memory>
# include "stdio_filebuf.hxx"
#include "stdio_filebuf.hxx"
/* *INDENT-OFF* */
namespace criterion { namespace internal {
/* *INDENT-ON* */
template <typename CharT, typename Super>
class stream_mixin : public Super {
template <typename CharT, typename Super>
class stream_mixin : public Super {
public:
stream_mixin(FILE* f)
: Super()
, fbuf(new stdio_sync_filebuf<CharT>(f))
, file(f)
{
std::ios::rdbuf(&*fbuf);
}
stream_mixin(FILE *f)
: Super(),
fbuf(new stdio_sync_filebuf<CharT>(f)),
file(f)
{
std::ios::rdbuf(&*fbuf);
}
# if __cplusplus > 199711L
stream_mixin(const stream_mixin& other) = delete;
stream_mixin& operator=(const stream_mixin& other) = delete;
# endif
#if __cplusplus > 199711L
stream_mixin(const stream_mixin &other) = delete;
stream_mixin &operator=(const stream_mixin &other) = delete;
#endif
stream_mixin(stream_mixin&& other) :
fbuf(std::move(other.fbuf)),
file(std::move(other.file))
{}
stream_mixin(stream_mixin &&other) :
fbuf(std::move(other.fbuf)),
file(std::move(other.file))
{}
stream_mixin& operator=(stream_mixin&& other) {
fbuf = std::move(other.fbuf);
file = std::move(other.file);
}
stream_mixin &operator=(stream_mixin &&other)
{
fbuf = std::move(other.fbuf);
file = std::move(other.file);
}
void close(void) {
Super::flush();
Super::close();
std::fclose(file);
}
void close(void)
{
Super::flush();
Super::close();
std::fclose(file);
}
private:
std::shared_ptr<stdio_sync_filebuf<CharT>> fbuf;
std::FILE* file;
};
private:
std::shared_ptr<stdio_sync_filebuf<CharT> > fbuf;
std::FILE *file;
};
template <typename CharT>
class basic_ofstream : public stream_mixin<CharT, std::basic_ofstream<CharT>> {
typedef stream_mixin<CharT, std::basic_ofstream<CharT>> super;
public:
basic_ofstream(FILE* f)
: super(f)
{}
template <typename CharT>
class basic_ofstream : public stream_mixin<CharT, std::basic_ofstream<CharT> > {
typedef stream_mixin<CharT, std::basic_ofstream<CharT> > super;
public:
basic_ofstream(FILE *f)
: super(f)
{}
basic_ofstream(basic_ofstream&& other)
: super(std::move(other))
{}
};
basic_ofstream(basic_ofstream &&other)
: super(std::move(other))
{}
};
template <typename CharT>
class basic_ifstream : public stream_mixin<CharT, std::basic_ifstream<CharT>> {
typedef stream_mixin<CharT, std::basic_ifstream<CharT>> super;
public:
basic_ifstream(FILE* f)
: super(f)
{}
template <typename CharT>
class basic_ifstream : public stream_mixin<CharT, std::basic_ifstream<CharT> > {
typedef stream_mixin<CharT, std::basic_ifstream<CharT> > super;
public:
basic_ifstream(FILE *f)
: super(f)
{}
basic_ifstream(basic_ifstream&& other)
: super(std::move(other))
{}
};
basic_ifstream(basic_ifstream &&other)
: super(std::move(other))
{}
};
template <typename CharT>
class basic_fstream : public stream_mixin<CharT, std::basic_fstream<CharT>> {
typedef stream_mixin<CharT, std::basic_fstream<CharT>> super;
public:
basic_fstream(FILE* f)
: super(f)
{}
template <typename CharT>
class basic_fstream : public stream_mixin<CharT, std::basic_fstream<CharT> > {
typedef stream_mixin<CharT, std::basic_fstream<CharT> > super;
public:
basic_fstream(FILE *f)
: super(f)
{}
basic_fstream(basic_fstream&& other)
: super(std::move(other))
{}
};
basic_fstream(basic_fstream &&other)
: super(std::move(other))
{}
};
struct get_redirected_out_stream_ {
static inline basic_ofstream<char>& call(std::FILE* f) {
static std::unique_ptr<basic_ofstream<char>> stream;
struct get_redirected_out_stream_ {
static inline basic_ofstream<char> &call(std::FILE *f)
{
static std::unique_ptr<basic_ofstream<char> > stream;
if (!stream)
stream.reset(new basic_ofstream<char>(f));
return *stream;
}
if (!stream)
stream.reset(new basic_ofstream<char>(f));
return *stream;
}
};
};
struct get_redirected_in_stream_ {
static inline basic_ifstream<char> &call(std::FILE *f)
{
static std::unique_ptr<basic_ifstream<char> > stream;
struct get_redirected_in_stream_ {
static inline basic_ifstream<char>& call(std::FILE* f) {
static std::unique_ptr<basic_ifstream<char>> stream;
if (!stream)
stream.reset(new basic_ifstream<char>(f));
return *stream;
}
};
if (!stream)
stream.reset(new basic_ifstream<char>(f));
return *stream;
}
};
/* *INDENT-OFF* */
}}

View file

@ -22,45 +22,45 @@
* THE SOFTWARE.
*/
#ifndef CRITERION_INTERNAL_TEST_H_
# define CRITERION_INTERNAL_TEST_H_
#define CRITERION_INTERNAL_TEST_H_
# include "designated-initializer-compat.h"
# include "common.h"
#include "designated-initializer-compat.h"
#include "common.h"
# ifdef __OBJC__
#import <Foundation/Foundation.h>
# endif
#ifdef __OBJC__
# import <Foundation/Foundation.h>
#endif
# ifdef __cplusplus
# include <exception>
# endif
#ifdef __cplusplus
# include <exception>
#endif
# define CR_IDENTIFIER_(Category, Name, Suffix) \
#define CR_IDENTIFIER_(Category, Name, Suffix) \
Category ## _ ## Name ## _ ## Suffix
# ifdef __cplusplus
# ifdef __OBJC__
# define CR_LANG CR_LANG_OBJCXX
# else
# define CR_LANG CR_LANG_CXX
# endif
#ifdef __cplusplus
# ifdef __OBJC__
# define CR_LANG CR_LANG_OBJCXX
# else
# ifdef __OBJC__
# define CR_LANG CR_LANG_OBJC
# else
# define CR_LANG CR_LANG_C
# endif
# define CR_LANG CR_LANG_CXX
# endif
#else
# ifdef __OBJC__
# define CR_LANG CR_LANG_OBJC
# else
# define CR_LANG CR_LANG_C
# endif
#endif
# ifdef __cplusplus
# define CR_TEST_PROTOTYPE_(Category, Name) \
#ifdef __cplusplus
# define CR_TEST_PROTOTYPE_(Category, Name) \
extern "C" void CR_IDENTIFIER_(Category, Name, impl)(void)
# else
# define CR_TEST_PROTOTYPE_(Category, Name) \
#else
# define CR_TEST_PROTOTYPE_(Category, Name) \
void CR_IDENTIFIER_(Category, Name, impl)(void)
# endif
#endif
# define CR_SUITE_IDENTIFIER_(Name, Suffix) \
#define CR_SUITE_IDENTIFIER_(Name, Suffix) \
suite_ ## Name ## _ ## Suffix
CR_BEGIN_C_API
@ -78,123 +78,123 @@ static const char *const cr_msg_test_main_other_exception = "Caught some unexpec
static const char *const cr_msg_test_fini_std_exception = "Caught an unexpected exception during the test finalization: %s.";
static const char *const cr_msg_test_fini_other_exception = "Caught some unexpected exception during the test finalization.";
# ifdef __cplusplus
# define CR_TEST_TRAMPOLINE_(Category, Name) \
static inline void CR_IDENTIFIER_(Category, Name, jmp)(void) { \
try { \
criterion_internal_test_setup(); \
} catch (const std::exception &e) { \
criterion_test_die(cr_msg_test_init_std_exception, e.what()); \
} catch (...) { \
criterion_test_die(cr_msg_test_init_other_exception); \
} \
try { \
criterion_internal_test_main((void(*)(void)) CR_IDENTIFIER_(Category, Name, impl)); \
} catch (const std::exception &e) { \
criterion_test_die(cr_msg_test_main_std_exception, e.what()); \
} catch (...) { \
criterion_test_die(cr_msg_test_main_other_exception); \
} \
try { \
criterion_internal_test_teardown(); \
} catch (const std::exception &e) { \
criterion_test_die(cr_msg_test_fini_std_exception, e.what()); \
} catch (...) { \
criterion_test_die(cr_msg_test_fini_other_exception); \
} \
#ifdef __cplusplus
# define CR_TEST_TRAMPOLINE_(Category, Name) \
static inline void CR_IDENTIFIER_(Category, Name, jmp)(void) { \
try { \
criterion_internal_test_setup(); \
} catch (const std::exception &e) { \
criterion_test_die(cr_msg_test_init_std_exception, e.what()); \
} catch (...) { \
criterion_test_die(cr_msg_test_init_other_exception); \
} \
try { \
criterion_internal_test_main((void (*)(void))CR_IDENTIFIER_(Category, Name, impl)); \
} catch (const std::exception &e) { \
criterion_test_die(cr_msg_test_main_std_exception, e.what()); \
} catch (...) { \
criterion_test_die(cr_msg_test_main_other_exception); \
} \
try { \
criterion_internal_test_teardown(); \
} catch (const std::exception &e) { \
criterion_test_die(cr_msg_test_fini_std_exception, e.what()); \
} catch (...) { \
criterion_test_die(cr_msg_test_fini_other_exception); \
} \
}
#else
# if defined (__OBJC__) && defined (__EXCEPTIONS)
# define CR_TEST_TRAMPOLINE_(Category, Name) \
static inline void CR_IDENTIFIER_(Category, Name, jmp)(void) { \
@try { \
criterion_internal_test_setup(); \
} @catch (NSException *e) { \
NSString *reason = [e reason]; \
criterion_test_die(cr_msg_test_init_std_exception, [reason UTF8String]); \
} @catch (...) { \
criterion_test_die(cr_msg_test_init_other_exception); \
} \
@try { \
criterion_internal_test_main((void (*)(void))CR_IDENTIFIER_(Category, Name, impl)); \
} @catch (NSException *e) { \
NSString *reason = [e reason]; \
criterion_test_die(cr_msg_test_main_std_exception, [reason UTF8String]); \
} @catch (...) { \
criterion_test_die(cr_msg_test_main_other_exception); \
} \
@try { \
criterion_internal_test_teardown(); \
} @catch (NSException *e) { \
NSString *reason = [e reason]; \
criterion_test_die(cr_msg_test_fini_std_exception, [reason UTF8String]); \
} @catch (...) { \
criterion_test_die(cr_msg_test_fini_other_exception); \
} \
}
# else
# if defined(__OBJC__) && defined(__EXCEPTIONS)
# define CR_TEST_TRAMPOLINE_(Category, Name) \
static inline void CR_IDENTIFIER_(Category, Name, jmp)(void) { \
@try { \
criterion_internal_test_setup(); \
} @catch (NSException *e) { \
NSString *reason = [e reason]; \
criterion_test_die(cr_msg_test_init_std_exception, [reason UTF8String]); \
} @catch (...) { \
criterion_test_die(cr_msg_test_init_other_exception); \
} \
@try { \
criterion_internal_test_main((void(*)(void)) CR_IDENTIFIER_(Category, Name, impl)); \
} @catch (NSException *e) { \
NSString *reason = [e reason]; \
criterion_test_die(cr_msg_test_main_std_exception, [reason UTF8String]); \
} @catch (...) { \
criterion_test_die(cr_msg_test_main_other_exception); \
} \
@try { \
criterion_internal_test_teardown(); \
} @catch (NSException *e) { \
NSString *reason = [e reason]; \
criterion_test_die(cr_msg_test_fini_std_exception, [reason UTF8String]); \
} @catch (...) { \
criterion_test_die(cr_msg_test_fini_other_exception); \
} \
# define CR_TEST_TRAMPOLINE_(Category, Name) \
static inline void CR_IDENTIFIER_(Category, Name, jmp)(void) { \
criterion_internal_test_setup(); \
criterion_internal_test_main((void (*)(void))CR_IDENTIFIER_(Category, Name, impl)); \
criterion_internal_test_teardown(); \
}
# else
# define CR_TEST_TRAMPOLINE_(Category, Name) \
static inline void CR_IDENTIFIER_(Category, Name, jmp)(void) { \
criterion_internal_test_setup(); \
criterion_internal_test_main((void(*)(void)) CR_IDENTIFIER_(Category, Name, impl)); \
criterion_internal_test_teardown(); \
}
# endif
# endif
#endif
# if defined(_MSC_VER)
# define CR_COMPILER_ CR_COMP_MSVC
# elif defined(__clang__)
# define CR_COMPILER_ CR_COMP_CLANG
# elif defined(__GNUC__)
# define CR_COMPILER_ CR_COMP_GCC
# else
# define CR_COMPILER_ CR_COMP_UNKNOWN
# endif
#if defined (_MSC_VER)
# define CR_COMPILER_ CR_COMP_MSVC
#elif defined (__clang__)
# define CR_COMPILER_ CR_COMP_CLANG
#elif defined (__GNUC__)
# define CR_COMPILER_ CR_COMP_GCC
#else
# define CR_COMPILER_ CR_COMP_UNKNOWN
#endif
# define CR_TEST_BASE(Category, Name, ...) \
CR_TEST_PROTOTYPE_(Category, Name); \
CR_TEST_TRAMPOLINE_(Category, Name) \
struct criterion_test_extra_data CR_IDENTIFIER_(Category, Name, extra) = \
CR_EXPAND(CRITERION_MAKE_STRUCT(criterion_test_extra_data, \
.compiler_ = CR_COMPILER_, \
.lang_ = CR_LANG, \
.kind_ = CR_TEST_NORMAL, \
.param_ = (struct criterion_test_params(*)(void)) NULL, \
.identifier_ = #Category "/" #Name, \
.file_ = __FILE__, \
.line_ = __LINE__, \
__VA_ARGS__ \
)); \
struct criterion_test CR_IDENTIFIER_(Category, Name, meta) = { \
#Name, \
#Category, \
CR_IDENTIFIER_(Category, Name, jmp), \
&CR_IDENTIFIER_(Category, Name, extra) \
}; \
CR_SECTION_("cr_tst") \
struct criterion_test *CR_IDENTIFIER_(Category, Name, ptr) \
= &CR_IDENTIFIER_(Category, Name, meta) CR_SECTION_SUFFIX_; \
#define CR_TEST_BASE(Category, Name, ...) \
CR_TEST_PROTOTYPE_(Category, Name); \
CR_TEST_TRAMPOLINE_(Category, Name) \
struct criterion_test_extra_data CR_IDENTIFIER_(Category, Name, extra) = \
CR_EXPAND(CRITERION_MAKE_STRUCT(criterion_test_extra_data, \
.compiler_ = CR_COMPILER_, \
.lang_ = CR_LANG, \
.kind_ = CR_TEST_NORMAL, \
.param_ = (struct criterion_test_params (*)(void))NULL, \
.identifier_ = #Category "/" #Name, \
.file_ = __FILE__, \
.line_ = __LINE__, \
__VA_ARGS__ \
)); \
struct criterion_test CR_IDENTIFIER_(Category, Name, meta) = { \
#Name, \
#Category, \
CR_IDENTIFIER_(Category, Name, jmp), \
&CR_IDENTIFIER_(Category, Name, extra) \
}; \
CR_SECTION_("cr_tst") \
struct criterion_test *CR_IDENTIFIER_(Category, Name, ptr) \
= &CR_IDENTIFIER_(Category, Name, meta) CR_SECTION_SUFFIX_; \
CR_TEST_PROTOTYPE_(Category, Name)
# define CR_SUITE_BASE(Name, ...) \
struct criterion_test_extra_data CR_SUITE_IDENTIFIER_(Name, extra) = \
CR_EXPAND(CRITERION_MAKE_STRUCT(criterion_test_extra_data, \
.file_ = __FILE__, \
.line_ = 0, \
__VA_ARGS__ \
)); \
struct criterion_suite CR_SUITE_IDENTIFIER_(Name, meta) = { \
#Name, \
&CR_SUITE_IDENTIFIER_(Name, extra), \
}; \
CR_SECTION_("cr_sts") \
struct criterion_suite *CR_SUITE_IDENTIFIER_(Name, ptr) \
= &CR_SUITE_IDENTIFIER_(Name, meta) CR_SECTION_SUFFIX_
#define CR_SUITE_BASE(Name, ...) \
struct criterion_test_extra_data CR_SUITE_IDENTIFIER_(Name, extra) = \
CR_EXPAND(CRITERION_MAKE_STRUCT(criterion_test_extra_data, \
.file_ = __FILE__, \
.line_ = 0, \
__VA_ARGS__ \
)); \
struct criterion_suite CR_SUITE_IDENTIFIER_(Name, meta) = { \
#Name, \
&CR_SUITE_IDENTIFIER_(Name, extra), \
}; \
CR_SECTION_("cr_sts") \
struct criterion_suite *CR_SUITE_IDENTIFIER_(Name, ptr) \
= &CR_SUITE_IDENTIFIER_(Name, meta) CR_SECTION_SUFFIX_
# undef Test
# define Test(...) CR_EXPAND(CR_TEST_BASE(__VA_ARGS__, .sentinel_ = 0))
# undef TestSuite
# define TestSuite(...) CR_EXPAND(CR_SUITE_BASE(__VA_ARGS__, .sentinel_ = 0))
#undef Test
#define Test(...) CR_EXPAND(CR_TEST_BASE(__VA_ARGS__, .sentinel_ = 0))
#undef TestSuite
#define TestSuite(...) CR_EXPAND(CR_SUITE_BASE(__VA_ARGS__, .sentinel_ = 0))
#endif /* !CRITERION_INTERNAL_TEST_H_ */

View file

@ -22,23 +22,24 @@
* THE SOFTWARE.
*/
#ifndef CRITERION_INTERNAL_THEORIES_H_
# define CRITERION_INTERNAL_THEORIES_H_
#define CRITERION_INTERNAL_THEORIES_H_
# include "test.h"
#include "test.h"
# ifdef __cplusplus
# include <cstddef>
#ifdef __cplusplus
# include <cstddef>
using std::size_t;
# else
# include <stddef.h>
# endif
#else
# include <stddef.h>
#endif
# ifdef __cplusplus
#ifdef __cplusplus
template <typename... T>
constexpr size_t criterion_va_num__(const T &...) {
return sizeof...(T);
constexpr size_t criterion_va_num__(const T & ...)
{
return sizeof ... (T);
}
# endif
#endif
struct criterion_datapoints {
size_t size;
@ -53,50 +54,51 @@ CR_API void cr_theory_main(struct criterion_datapoints *dps, size_t datapoints,
CR_END_C_API
# ifdef __cplusplus
# define CR_TH_VA_NUM(Type, ...) criterion_va_num__(__VA_ARGS__)
# define CR_TH_TEMP_ARRAY(Type, ...) []() -> Type* { static Type arr[] = { __VA_ARGS__ }; return reinterpret_cast<Type*>(&arr); }()
# else
# define CR_TH_VA_NUM(Type, ...) sizeof ((Type[]) { __VA_ARGS__ }) / sizeof (Type)
# define CR_TH_TEMP_ARRAY(Type, ...) &(Type[]) { __VA_ARGS__ }
# endif
#ifdef __cplusplus
# define CR_TH_VA_NUM(Type, ...) criterion_va_num__(__VA_ARGS__)
# define CR_TH_TEMP_ARRAY(Type, ...) []() -> Type * { static Type arr[] = { __VA_ARGS__ }; return reinterpret_cast<Type *>(&arr); } ()
#else
# define CR_TH_VA_NUM(Type, ...) sizeof ((Type[]) { __VA_ARGS__ }) / sizeof (Type)
# define CR_TH_TEMP_ARRAY(Type, ...) & (Type[]) { __VA_ARGS__ }
#endif
# define CR_TH_INTERNAL_TDPS(Category, Name) \
#define CR_TH_INTERNAL_TDPS(Category, Name) \
static struct criterion_datapoints CR_IDENTIFIER_(Category, Name, dps)[]
# define CR_TH_INTERNAL_TDP(Category, Name) \
#define CR_TH_INTERNAL_TDP(Category, Name) \
(CR_IDENTIFIER_(Category, Name, dps))
# define CR_TH_INTERNAL_DP(Type, ...) { \
sizeof (Type), \
CR_EXPAND(CR_TH_VA_NUM(Type, __VA_ARGS__)), \
#Type, \
#define CR_TH_INTERNAL_DP(Type, ...) \
{ \
sizeof (Type), \
CR_EXPAND(CR_TH_VA_NUM(Type, __VA_ARGS__)), \
#Type, \
CR_EXPAND(CR_TH_TEMP_ARRAY(Type, __VA_ARGS__)), \
}
# define CR_NB_DATAPOINTS(Var) \
#define CR_NB_DATAPOINTS(Var) \
(sizeof (Var) / sizeof (struct criterion_datapoints))
# define CR_VAARG_ID(Suffix, Category, Name, ...) \
#define CR_VAARG_ID(Suffix, Category, Name, ...) \
CR_IDENTIFIER_(Category, Name, Suffix)
# define CR_THEORY_BASE(Args, ...) \
void CR_EXPAND(CR_VAARG_ID(theory, __VA_ARGS__,))Args; \
CR_EXPAND(CR_TEST_BASE(__VA_ARGS__, .sentinel_ = 0)) { \
cr_theory_main( \
CR_EXPAND(CR_VAARG_ID(dps, __VA_ARGS__,)), \
CR_NB_DATAPOINTS(CR_EXPAND(CR_VAARG_ID(dps, __VA_ARGS__,))), \
(void(*)(void)) CR_EXPAND(CR_VAARG_ID(theory, __VA_ARGS__,)) \
); \
} \
void CR_EXPAND(CR_VAARG_ID(theory, __VA_ARGS__,))Args
#define CR_THEORY_BASE(Args, ...) \
void CR_EXPAND(CR_VAARG_ID(theory, __VA_ARGS__, )) Args; \
CR_EXPAND(CR_TEST_BASE(__VA_ARGS__, .sentinel_ = 0)) { \
cr_theory_main( \
CR_EXPAND(CR_VAARG_ID(dps, __VA_ARGS__, )), \
CR_NB_DATAPOINTS(CR_EXPAND(CR_VAARG_ID(dps, __VA_ARGS__, ))), \
(void (*)(void))CR_EXPAND(CR_VAARG_ID(theory, __VA_ARGS__, )) \
); \
} \
void CR_EXPAND(CR_VAARG_ID(theory, __VA_ARGS__, )) Args
# define cr_assume_op_(Op, Actual, Expected) cr_assume((Actual) Op (Expected))
#define cr_assume_op_(Op, Actual, Expected) cr_assume((Actual) Op(Expected))
# define cr_assume_str_op_(Op, Actual, Expected) \
#define cr_assume_str_op_(Op, Actual, Expected) \
cr_assume(strcmp((Actual), (Expected)) Op 0)
# undef Theory
# define Theory(Args, ...) CR_EXPAND(CR_THEORY_BASE(Args, __VA_ARGS__))
#undef Theory
#define Theory(Args, ...) CR_EXPAND(CR_THEORY_BASE(Args, __VA_ARGS__))
#endif /* !CRITERION_INTERNAL_THEORIES_H_ */

View file

@ -26,12 +26,12 @@
* @brief Logging functions
*****************************************************************************/
#ifndef CRITERION_LOGGING_H_
# define CRITERION_LOGGING_H_
#define CRITERION_LOGGING_H_
# include "internal/common.h"
# include "internal/ordered-set.h"
# include "internal/deprecation.h"
# include "stats.h"
#include "internal/common.h"
#include "internal/ordered-set.h"
#include "internal/deprecation.h"
#include "stats.h"
CR_BEGIN_C_API
@ -71,7 +71,7 @@ CR_API void cr_log(enum criterion_severity severity, const char *msg, ...);
* @param[in] ... Additional arguments depending on msg
*
*****************************************************************************/
# define cr_log_info(...) cr_log(CR_LOG_INFO, __VA_ARGS__)
#define cr_log_info(...) cr_log(CR_LOG_INFO, __VA_ARGS__)
/**
* Prints a warning message
@ -83,7 +83,7 @@ CR_API void cr_log(enum criterion_severity severity, const char *msg, ...);
* @param[in] ... Additional arguments depending on msg
*
*****************************************************************************/
# define cr_log_warn(...) cr_log(CR_LOG_WARNING, __VA_ARGS__)
#define cr_log_warn(...) cr_log(CR_LOG_WARNING, __VA_ARGS__)
/**
* Prints a error message
@ -95,7 +95,7 @@ CR_API void cr_log(enum criterion_severity severity, const char *msg, ...);
* @param[in] ... Additional arguments depending on msg
*
*****************************************************************************/
# define cr_log_error(...) cr_log(CR_LOG_ERROR, __VA_ARGS__)
#define cr_log_error(...) cr_log(CR_LOG_ERROR, __VA_ARGS__)
struct criterion_logger {
void (*log_pre_all )(struct criterion_test_set *set);
@ -120,56 +120,57 @@ extern struct criterion_logger normal_logging;
CR_END_C_API
# define CR_NORMAL_LOGGING (&normal_logging)
#define CR_NORMAL_LOGGING (&normal_logging)
# ifdef __cplusplus
# include <sstream>
#ifdef __cplusplus
# include <sstream>
namespace criterion { namespace logging {
namespace criterion
{ namespace logging
{
static void(*const log)(enum criterion_severity, const char *, ...) = cr_log;
static void (*const log)(enum criterion_severity, const char *, ...) = cr_log;
class streambuf : public std::stringbuf {
public:
streambuf(enum criterion_severity severity__)
: std::stringbuf(), severity__(severity__)
{}
class streambuf : public std::stringbuf {
public:
streambuf(enum criterion_severity severity__)
: std::stringbuf(), severity__(severity__)
{}
virtual int sync() override
{
criterion::logging::log(severity__, "%s", str().c_str());
str(std::string());
return 0;
}
private:
enum criterion_severity severity__;
};
virtual int sync() override {
criterion::logging::log(severity__, "%s", str().c_str());
str(std::string());
return 0;
}
private:
enum criterion_severity severity__;
};
class stream : public std::ostream {
public:
stream(enum criterion_severity severity__)
: std::ostream(&buf), buf(severity__)
{}
private:
streambuf buf;
};
class stream : public std::ostream {
public:
stream(enum criterion_severity severity__)
: std::ostream(&buf), buf(severity__)
{}
private:
streambuf buf;
};
stream info { CR_LOG_INFO };
stream warn { CR_LOG_WARNING };
stream error { CR_LOG_ERROR };
} }
#endif
stream info { CR_LOG_INFO };
stream warn { CR_LOG_WARNING };
stream error { CR_LOG_ERROR };
/* Deprecated old logging system, schedule removal for 3.0 */
#ifndef CRITERION_NO_COMPAT
}}
# endif
# define criterion_log(_, ...) CR_DEPRECATED("criterion_log is deprecated, please use cr_log instead.") cr_log_info(__VA_ARGS__)
# define criterion_info(...) CR_DEPRECATED("criterion_info is deprecated, please use cr_log_info instead.") cr_log_info(__VA_ARGS__)
# define criterion_pinfo(_, ...) CR_DEPRECATED("criterion_pinfo is deprecated, please use cr_log_info instead.") cr_log_info(__VA_ARGS__)
# define criterion_important(...) CR_DEPRECATED("criterion_important is deprecated, please use cr_log_info instead.") cr_log_info(__VA_ARGS__)
# define criterion_pimportant(_, ...) CR_DEPRECATED("criterion_pimportant is deprecated, please use cr_log_info instead.") cr_log_info(__VA_ARGS__)
# define criterion_perror(...) CR_DEPRECATED("criterion_perror is deprecated, please use cr_log_error instead.") cr_log_error(__VA_ARGS__)
// Deprecated old logging system, schedule removal for 3.0
# ifndef CRITERION_NO_COMPAT
# define criterion_log(_, ...) CR_DEPRECATED("criterion_log is deprecated, please use cr_log instead.") cr_log_info(__VA_ARGS__)
# define criterion_info(...) CR_DEPRECATED("criterion_info is deprecated, please use cr_log_info instead.") cr_log_info(__VA_ARGS__)
# define criterion_pinfo(_, ...) CR_DEPRECATED("criterion_pinfo is deprecated, please use cr_log_info instead.") cr_log_info(__VA_ARGS__)
# define criterion_important(...) CR_DEPRECATED("criterion_important is deprecated, please use cr_log_info instead.") cr_log_info(__VA_ARGS__)
# define criterion_pimportant(_, ...) CR_DEPRECATED("criterion_pimportant is deprecated, please use cr_log_info instead.") cr_log_info(__VA_ARGS__)
# define criterion_perror(...) CR_DEPRECATED("criterion_perror is deprecated, please use cr_log_error instead.") cr_log_error(__VA_ARGS__)
# endif /* !CRITERION_NO_COMPAT */
#endif /* !CRITERION_NO_COMPAT */
#endif /* !CRITERION_LOGGING_H_ */

View file

@ -26,11 +26,11 @@
* @brief criterion options
*****************************************************************************/
#ifndef CRITERION_OPTIONS_H_
# define CRITERION_OPTIONS_H_
#define CRITERION_OPTIONS_H_
# include <stdbool.h>
# include "logging.h"
# include "internal/common.h"
#include <stdbool.h>
#include "logging.h"
#include "internal/common.h"
enum criterion_debugger {
/**
@ -61,7 +61,6 @@ enum criterion_debugger {
};
struct criterion_options {
/**
* The current logging threshold.
*

View file

@ -26,11 +26,11 @@
* @brief Report functions
*****************************************************************************/
#ifndef CRITERION_OUTPUT_H_
# define CRITERION_OUTPUT_H_
#define CRITERION_OUTPUT_H_
# include "stats.h"
#include "stats.h"
typedef void criterion_reporter(FILE *stream, struct criterion_global_stats *);
typedef void criterion_reporter (FILE *stream, struct criterion_global_stats *);
/**
* Register an output provider.

View file

@ -26,10 +26,10 @@
* @brief Parameterized tests
*****************************************************************************/
#ifndef CRITERION_PARAMETERIZED_H_
# define CRITERION_PARAMETERIZED_H_
#define CRITERION_PARAMETERIZED_H_
# include "alloc.h"
# include "assert.h"
#include "alloc.h"
#include "assert.h"
/**
* @defgroup ParameterizedBase Parameterized test & generator macros
@ -52,7 +52,7 @@
* (see criterion/types.h).
* Example: `.exit_code = 1`
*/
# define ParameterizedTest(Type, Suite, Name, ...) <internal>
#define ParameterizedTest(Type, Suite, Name, ...) < internal >
/**
* Defines the parameter generator prototype for the associated parameterized
@ -63,7 +63,7 @@
* @returns A constructed instance of criterion::parameters, or the result of
* the cr_make_param_array macro.
*/
# define ParameterizedTestParameters(Suite, Name) <internal>
#define ParameterizedTestParameters(Suite, Name) < internal >
/**
* Constructs a parameter list used as a return value for a parameter generator.
@ -77,27 +77,27 @@
* @param Cleanup The optional cleanup function for the array.
* @returns The parameter list.
*/
# define cr_make_param_array(Type, Array, Len, Cleanup) <internal>
#define cr_make_param_array(Type, Array, Len, Cleanup) < internal >
/** @} */
# ifdef __cplusplus
# include <vector>
#ifdef __cplusplus
# include <vector>
namespace criterion {
/**
* Represents a C++ dynamic parameter list for a parameter generator.
*
* @ingroup ParameterizedBase
*
* @param T The type of the parameter.
*/
template <typename T>
using parameters = std::vector<T, criterion::allocator<T>>;
namespace criterion
{
/**
* Represents a C++ dynamic parameter list for a parameter generator.
*
* @ingroup ParameterizedBase
*
* @param T The type of the parameter.
*/
template <typename T>
using parameters = std::vector<T, criterion::allocator<T> >;
}
# endif
#endif
# include "internal/parameterized.h"
#include "internal/parameterized.h"
#endif /* !CRITERION_PARAMETERIZED_H_ */

View file

@ -26,15 +26,15 @@
* @brief Redirect functions and file asserts
*****************************************************************************/
#ifndef CRITERION_REDIRECT_H_
# define CRITERION_REDIRECT_H_
#define CRITERION_REDIRECT_H_
# include "internal/common.h"
#include "internal/common.h"
# ifdef __cplusplus
# include <cstdio>
# else
# include <stdio.h>
# endif
#ifdef __cplusplus
# include <cstdio>
#else
# include <stdio.h>
#endif
CR_BEGIN_C_API
@ -59,21 +59,21 @@ CR_API void cr_redirect_stdin(void);
*
* @returns the file handle.
*/
CR_API CR_STDN FILE* cr_get_redirected_stdout(void);
CR_API CR_STDN FILE *cr_get_redirected_stdout(void);
/**
* Get a file handle representing the read-end of the redirected stderr.
*
* @returns the file handle.
*/
CR_API CR_STDN FILE* cr_get_redirected_stderr(void);
CR_API CR_STDN FILE *cr_get_redirected_stderr(void);
/**
* Get a file handle representing the write-end of the redirected stdin.
*
* @returns the file handle.
*/
CR_API CR_STDN FILE* cr_get_redirected_stdin(void);
CR_API CR_STDN FILE *cr_get_redirected_stdin(void);
/**
* Compare the contents of a file with a string.
@ -82,7 +82,7 @@ CR_API CR_STDN FILE* cr_get_redirected_stdin(void);
* @param[in] str The string to compare the contents to.
* @returns 1 if the contents of the file is equal to the string, 0 otherwise.
*/
CR_API int cr_file_match_str(CR_STDN FILE* f, const char *str);
CR_API int cr_file_match_str(CR_STDN FILE *f, const char *str);
/**
* Compare the contents of a file with the contents of another file.
@ -91,7 +91,7 @@ CR_API int cr_file_match_str(CR_STDN FILE* f, const char *str);
* @param[in] ref The second file to compare the contents to.
* @returns 1 if the contents of the files are equal, 0 otherwise.
*/
CR_API int cr_file_match_file(CR_STDN FILE* f, CR_STDN FILE* ref);
CR_API int cr_file_match_file(CR_STDN FILE *f, CR_STDN FILE *ref);
/**
* Create a file mock.
@ -124,7 +124,7 @@ CR_END_C_API
* @param[in] ... (optional) format string parameters
*
*****************************************************************************/
# define cr_assert_file_contents_eq_str(File, ExpectedContents, FormatString, ...) <internal>
#define cr_assert_file_contents_eq_str(File, ExpectedContents, FormatString, ...) < internal >
/**
* Passes if the contents of \c File are equal to the string \c ExpectedContents
@ -141,7 +141,7 @@ CR_END_C_API
* @param[in] ... (optional) format string parameters
*
*****************************************************************************/
# define cr_expect_file_contents_eq_str(File, ExpectedContents, FormatString, ...) <internal>
#define cr_expect_file_contents_eq_str(File, ExpectedContents, FormatString, ...) < internal >
/**
* Passes if the contents of \c File are not equal to the string
@ -160,7 +160,7 @@ CR_END_C_API
* @param[in] ... (optional) format string parameters
*
*****************************************************************************/
# define cr_assert_file_contents_neq_str(File, UnexpectedContents, FormatString, ...) <internal>
#define cr_assert_file_contents_neq_str(File, UnexpectedContents, FormatString, ...) < internal >
/**
* Passes if the contents of \c File are not equal to the string
@ -178,7 +178,7 @@ CR_END_C_API
* @param[in] ... (optional) format string parameters
*
*****************************************************************************/
# define cr_expect_file_contents_neq_str(File, UnexpectedContents, FormatString, ...) <internal>
#define cr_expect_file_contents_neq_str(File, UnexpectedContents, FormatString, ...) < internal >
/**
* Passes if the contents of \c File are equal to the contents of \c RefFile
@ -195,7 +195,7 @@ CR_END_C_API
* @param[in] ... (optional) format string parameters
*
*****************************************************************************/
# define cr_assert_file_contents_eq(File, RefFile, FormatString, ...) <internal>
#define cr_assert_file_contents_eq(File, RefFile, FormatString, ...) < internal >
/**
* Passes if the contents of \c File are equal to the contents of \c RefFile
@ -211,7 +211,7 @@ CR_END_C_API
* @param[in] ... (optional) format string parameters
*
*****************************************************************************/
# define cr_expect_file_contents_eq(File, RefFile, FormatString, ...) <internal>
#define cr_expect_file_contents_eq(File, RefFile, FormatString, ...) < internal >
/**
* Passes if the contents of \c File are not equal to the contents of
@ -230,7 +230,7 @@ CR_END_C_API
* @param[in] ... (optional) format string parameters
*
*****************************************************************************/
# define cr_assert_file_contents_neq(File, RefFile, FormatString, ...) <internal>
#define cr_assert_file_contents_neq(File, RefFile, FormatString, ...) < internal >
/**
* Passes if the contents of \c File are not equal to the contents of
@ -248,7 +248,7 @@ CR_END_C_API
* @param[in] ... (optional) format string parameters
*
*****************************************************************************/
# define cr_expect_file_contents_neq(File, RefFile, FormatString, ...) <internal>
#define cr_expect_file_contents_neq(File, RefFile, FormatString, ...) < internal >
/**@}*/
@ -273,7 +273,7 @@ CR_END_C_API
* @param[in] ... (optional) format string parameters
*
*****************************************************************************/
# define cr_assert_stdout_eq_str(ExpectedContents, FormatString, ...) <internal>
#define cr_assert_stdout_eq_str(ExpectedContents, FormatString, ...) < internal >
/**
* Passes if the contents of \c stdout are equal to the contents of the string
@ -290,7 +290,7 @@ CR_END_C_API
* @param[in] ... (optional) format string parameters
*
*****************************************************************************/
# define cr_expect_stdout_eq_str(ExpectedContents, FormatString, ...) <internal>
#define cr_expect_stdout_eq_str(ExpectedContents, FormatString, ...) < internal >
/**
* Passes if the contents of \c stdout are not equal to the contents of the
@ -308,7 +308,7 @@ CR_END_C_API
* @param[in] ... (optional) format string parameters
*
*****************************************************************************/
# define cr_assert_stdout_neq_str(UnexpectedContents, FormatString, ...) <internal>
#define cr_assert_stdout_neq_str(UnexpectedContents, FormatString, ...) < internal >
/**
* Passes if the contents of \c stdout are not equal to the contents of the
@ -325,7 +325,7 @@ CR_END_C_API
* @param[in] ... (optional) format string parameters
*
*****************************************************************************/
# define cr_expect_stdout_neq_str(UnexpectedContents, FormatString, ...) <internal>
#define cr_expect_stdout_neq_str(UnexpectedContents, FormatString, ...) < internal >
/**
* Passes if the contents of \c stderr are equal to the contents of the string
@ -343,7 +343,7 @@ CR_END_C_API
* @param[in] ... (optional) format string parameters
*
*****************************************************************************/
# define cr_assert_stderr_eq_str(ExpectedContents, FormatString, ...) <internal>
#define cr_assert_stderr_eq_str(ExpectedContents, FormatString, ...) < internal >
/**
* Passes if the contents of \c stderr are equal to the contents of the string
@ -360,7 +360,7 @@ CR_END_C_API
* @param[in] ... (optional) format string parameters
*
*****************************************************************************/
# define cr_expect_stderr_eq_str(ExpectedContents, FormatString, ...) <internal>
#define cr_expect_stderr_eq_str(ExpectedContents, FormatString, ...) < internal >
/**
* Passes if the contents of \c stderr are not equal to the contents of the
@ -378,7 +378,7 @@ CR_END_C_API
* @param[in] ... (optional) format string parameters
*
*****************************************************************************/
# define cr_assert_stderr_neq_str(UnexpectedContents, FormatString, ...) <internal>
#define cr_assert_stderr_neq_str(UnexpectedContents, FormatString, ...) < internal >
/**
* Passes if the contents of \c stderr are not equal to the contents of the
@ -395,7 +395,7 @@ CR_END_C_API
* @param[in] ... (optional) format string parameters
*
*****************************************************************************/
# define cr_expect_stderr_neq_str(UnexpectedContents, FormatString, ...) <internal>
#define cr_expect_stderr_neq_str(UnexpectedContents, FormatString, ...) < internal >
/**
* Passes if the contents of \c stdout are equal to the contents of \c RefFile
@ -411,7 +411,7 @@ CR_END_C_API
* @param[in] ... (optional) format string parameters
*
*****************************************************************************/
# define cr_assert_stdout_eq(RefFile, FormatString, ...) <internal>
#define cr_assert_stdout_eq(RefFile, FormatString, ...) < internal >
/**
* Passes if the contents of \c stdout are equal to the contents of \c RefFile
@ -426,7 +426,7 @@ CR_END_C_API
* @param[in] ... (optional) format string parameters
*
*****************************************************************************/
# define cr_expect_stdout_eq(RefFile, FormatString, ...) <internal>
#define cr_expect_stdout_eq(RefFile, FormatString, ...) < internal >
/**
* Passes if the contents of \c stdout are not equal to the contents of \c
@ -444,7 +444,7 @@ CR_END_C_API
* @param[in] ... (optional) format string parameters
*
*****************************************************************************/
# define cr_assert_stdout_neq(RefFile, FormatString, ...) <internal>
#define cr_assert_stdout_neq(RefFile, FormatString, ...) < internal >
/**
* Passes if the contents of \c stdout are not equal to the contents of \c
@ -461,7 +461,7 @@ CR_END_C_API
* @param[in] ... (optional) format string parameters
*
*****************************************************************************/
# define cr_expect_stdout_neq(RefFile, FormatString, ...) <internal>
#define cr_expect_stdout_neq(RefFile, FormatString, ...) < internal >
/**
* Passes if the contents of \c stderr are equal to the contents of \c RefFile
@ -477,7 +477,7 @@ CR_END_C_API
* @param[in] ... (optional) format string parameters
*
*****************************************************************************/
# define cr_assert_stderr_eq(RefFile, FormatString, ...) <internal>
#define cr_assert_stderr_eq(RefFile, FormatString, ...) < internal >
/**
* Passes if the contents of \c stderr are equal to the contents of \c RefFile
@ -492,7 +492,7 @@ CR_END_C_API
* @param[in] ... (optional) format string parameters
*
*****************************************************************************/
# define cr_expect_stderr_eq(RefFile, FormatString, ...) <internal>
#define cr_expect_stderr_eq(RefFile, FormatString, ...) < internal >
/**
* Passes if the contents of \c stderr are not equal to the contents of \c
@ -510,7 +510,7 @@ CR_END_C_API
* @param[in] ... (optional) format string parameters
*
*****************************************************************************/
# define cr_assert_stderr_neq(RefFile, FormatString, ...) <internal>
#define cr_assert_stderr_neq(RefFile, FormatString, ...) < internal >
/**
* Passes if the contents of \c stderr are not equal to the contents of \c
@ -527,43 +527,48 @@ CR_END_C_API
* @param[in] ... (optional) format string parameters
*
*****************************************************************************/
# define cr_expect_stderr_neq(RefFile, FormatString, ...) <internal>
#define cr_expect_stderr_neq(RefFile, FormatString, ...) < internal >
/**@}*/
# ifdef __cplusplus
# include "internal/stream.hxx"
#ifdef __cplusplus
# include "internal/stream.hxx"
namespace criterion {
namespace criterion
{
typedef internal::basic_ofstream<char> ofstream;
typedef internal::basic_ifstream<char> ifstream;
typedef internal::basic_fstream<char> fstream;
typedef internal::basic_ofstream<char> ofstream;
typedef internal::basic_ifstream<char> ifstream;
typedef internal::basic_fstream<char> fstream;
static inline ofstream &get_redirected_cin(void)
{
return internal::get_redirected_out_stream_::call(cr_get_redirected_stdin());
}
static inline ofstream& get_redirected_cin(void) {
return internal::get_redirected_out_stream_::call(cr_get_redirected_stdin());
}
static inline ifstream &get_redirected_cout(void)
{
return internal::get_redirected_in_stream_::call(cr_get_redirected_stdout());
}
static inline ifstream& get_redirected_cout(void) {
return internal::get_redirected_in_stream_::call(cr_get_redirected_stdout());
}
static inline ifstream &get_redirected_cerr(void)
{
return internal::get_redirected_in_stream_::call(cr_get_redirected_stderr());
}
static inline ifstream& get_redirected_cerr(void) {
return internal::get_redirected_in_stream_::call(cr_get_redirected_stderr());
}
# if __GNUC__ >= 5
static inline fstream mock_file(size_t max_size)
{
return fstream(cr_mock_file_size(max_size));
}
# if __GNUC__ >= 5
static inline fstream mock_file(size_t max_size) {
return fstream(cr_mock_file_size(max_size));
}
static inline fstream mock_file(void) {
return mock_file(4096);
}
# endif
static inline fstream mock_file(void)
{
return mock_file(4096);
}
# endif
}
#endif
# include "internal/redirect.h"
#include "internal/redirect.h"
#endif /* !CRITERION_REDIRECT_H_ */

View file

@ -26,14 +26,14 @@
* @brief Test stats
*****************************************************************************/
#ifndef CRITERION_STATS_H_
# define CRITERION_STATS_H_
#define CRITERION_STATS_H_
# include "types.h"
# include "internal/deprecation.h"
#include "types.h"
#include "internal/deprecation.h"
enum criterion_test_status {
CR_STATUS_PASSED = 0,
CR_STATUS_FAILED = 1,
CR_STATUS_PASSED = 0,
CR_STATUS_FAILED = 1,
CR_STATUS_SKIPPED = 2,
};

View file

@ -26,9 +26,9 @@
* @brief Theory tests
*****************************************************************************/
#ifndef CRITERION_THEORIES_H_
# define CRITERION_THEORIES_H_
#define CRITERION_THEORIES_H_
# include "criterion.h"
#include "criterion.h"
CR_BEGIN_C_API
@ -66,7 +66,7 @@ CR_END_C_API
* (see criterion/types.h).
* Example: .exit_code = 1
*/
# define Theory(Params, Suite, Name, ...) <internal>
#define Theory(Params, Suite, Name, ...) < internal >
/**
* Defines an array of data points.
@ -87,7 +87,7 @@ CR_END_C_API
* @param Suite The name of the test suite containing this test.
* @param Name The name of the test.
*/
# define TheoryDataPoints(Suite, Name) CR_TH_INTERNAL_TDPS(Suite, Name)
#define TheoryDataPoints(Suite, Name) CR_TH_INTERNAL_TDPS(Suite, Name)
/**
* Defines a new set of data points.
@ -95,7 +95,7 @@ CR_END_C_API
* @param Type The type of each data point in the set.
* @param ... The data points in the set.
*/
# define DataPoints(Type, ...) CR_EXPAND(CR_TH_INTERNAL_DP(Type, __VA_ARGS__))
#define DataPoints(Type, ...) CR_EXPAND(CR_TH_INTERNAL_DP(Type, __VA_ARGS__))
/**@}*/
@ -114,10 +114,10 @@ CR_END_C_API
* @param[in] Condition Condition to test
*
*****************************************************************************/
# define cr_assume(Condition) \
do { \
if (!(Condition)) \
cr_theory_abort(); \
#define cr_assume(Condition) \
do { \
if (!(Condition)) \
cr_theory_abort(); \
} while (0)
/**
@ -130,7 +130,7 @@ CR_END_C_API
* @param[in] Condition Condition to test
*
*****************************************************************************/
# define cr_assume_not(Condition) cr_assume(!(Condition))
#define cr_assume_not(Condition) cr_assume(!(Condition))
/**
* Assumes `Actual` is equal to `Expected`
@ -143,7 +143,7 @@ CR_END_C_API
* @param[in] Expected Expected value
*
*****************************************************************************/
# define cr_assume_eq(Actual, Expected) cr_assume_op_(==, Actual, Expected)
#define cr_assume_eq(Actual, Expected) cr_assume_op_(==, Actual, Expected)
/**
* Assumes `Actual` is not equal to `Unexpected`
@ -156,7 +156,7 @@ CR_END_C_API
* @param[in] Unexpected Unexpected value
*
*****************************************************************************/
# define cr_assume_neq(Actual, Unexpected) cr_assume_op_(!=, Actual, Unexpected)
#define cr_assume_neq(Actual, Unexpected) cr_assume_op_(!=, Actual, Unexpected)
/**
* Assumes `Actual` is greater than `Reference`
@ -169,7 +169,7 @@ CR_END_C_API
* @param[in] Reference Reference value
*
*****************************************************************************/
# define cr_assume_gt(Actual, Reference) cr_assume_op_(>, Actual, Reference)
#define cr_assume_gt(Actual, Reference) cr_assume_op_(>, Actual, Reference)
/**
* Assumes `Actual` is greater or equal to `Reference`
@ -182,7 +182,7 @@ CR_END_C_API
* @param[in] Reference Reference value
*
*****************************************************************************/
# define cr_assume_geq(Actual, Reference) cr_assume_op_(>=, Actual, Reference)
#define cr_assume_geq(Actual, Reference) cr_assume_op_(>=, Actual, Reference)
/**
* Assumes `Actual` is less than `Reference`
@ -195,7 +195,7 @@ CR_END_C_API
* @param[in] Reference Reference value
*
*****************************************************************************/
# define cr_assume_lt(Actual, Reference) cr_assume_op_(<, Actual, Reference)
#define cr_assume_lt(Actual, Reference) cr_assume_op_(<, Actual, Reference)
/**
* Assumes `Actual` is less or equal to `Reference`
@ -208,7 +208,7 @@ CR_END_C_API
* @param[in] Reference Reference value
*
*****************************************************************************/
# define cr_assume_leq(Actual, Reference) cr_assume_op_(<=, Actual, Reference)
#define cr_assume_leq(Actual, Reference) cr_assume_op_(<=, Actual, Reference)
/**
* Assumes `Value` is NULL.
@ -220,7 +220,7 @@ CR_END_C_API
* @param[in] Value Value to test
*
*****************************************************************************/
# define cr_assume_null(Value) cr_assume_eq(Value, NULL)
#define cr_assume_null(Value) cr_assume_eq(Value, NULL)
/**
* Assumes `Value` is not NULL.
@ -232,7 +232,7 @@ CR_END_C_API
* @param[in] Value Value to test
*
*****************************************************************************/
# define cr_assume_not_null(Value) cr_assume_neq(Value, NULL)
#define cr_assume_not_null(Value) cr_assume_neq(Value, NULL)
/**
* Assumes `Actual` is equal to `Expected` with a tolerance of `Epsilon`
@ -248,9 +248,9 @@ CR_END_C_API
* @param[in] Epsilon Tolerance between Actual and Expected
*
*****************************************************************************/
# define cr_assume_float_eq(Actual, Expected, Epsilon) \
cr_assume((Expected) - (Actual) <= (Epsilon) \
&& (Actual) - (Expected) <= (Epsilon))
#define cr_assume_float_eq(Actual, Expected, Epsilon) \
cr_assume((Expected) - (Actual) <= (Epsilon) \
&& (Actual) - (Expected) <= (Epsilon))
/**
* Assumes `Actual` is not equal to `Expected` with a tolerance of `Epsilon`
@ -266,9 +266,9 @@ CR_END_C_API
* @param[in] Epsilon Tolerance between Actual and Expected
*
*****************************************************************************/
# define cr_assume_float_neq(Actual, Expected, Epsilon) \
cr_assume((Expected) - (Actual) > (Epsilon) \
|| (Actual) - (Expected) > (Epsilon))
#define cr_assume_float_neq(Actual, Expected, Epsilon) \
cr_assume((Expected) - (Actual) > (Epsilon) \
|| (Actual) - (Expected) > (Epsilon))
/**
* Assumes `Actual` is lexicographically equal to `Expected`
@ -281,7 +281,7 @@ CR_END_C_API
* @param[in] Expected Expected string
*
*****************************************************************************/
# define cr_assume_str_eq(Actual, Expected) cr_assume_str_op_(==, Actual, Expected)
#define cr_assume_str_eq(Actual, Expected) cr_assume_str_op_(==, Actual, Expected)
/**
* Assumes `Actual` is not lexicographically equal to `Unexpected`
@ -294,7 +294,7 @@ CR_END_C_API
* @param[in] Unexpected Unexpected string
*
*****************************************************************************/
# define cr_assume_str_neq(Actual, Unexpected) cr_assume_str_op_(!=, Actual, Unexpected)
#define cr_assume_str_neq(Actual, Unexpected) cr_assume_str_op_(!=, Actual, Unexpected)
/**
* Assumes `Actual` is lexicographically less than `Reference`
@ -307,7 +307,7 @@ CR_END_C_API
* @param[in] Reference Reference value
*
*****************************************************************************/
# define cr_assume_str_lt(Actual, Reference) cr_assume_str_op_(<, Actual, Reference)
#define cr_assume_str_lt(Actual, Reference) cr_assume_str_op_(<, Actual, Reference)
/**
* Assumes `Actual` is lexicographically less or equal to `Reference`
@ -320,7 +320,7 @@ CR_END_C_API
* @param[in] Reference Reference value
*
*****************************************************************************/
# define cr_assume_str_leq(Actual, Reference) cr_assume_str_op_(<=, Actual, Reference)
#define cr_assume_str_leq(Actual, Reference) cr_assume_str_op_(<=, Actual, Reference)
/**
* Assumes `Actual` is lexicographically greater than `Reference`
@ -333,7 +333,7 @@ CR_END_C_API
* @param[in] Reference Reference value
*
*****************************************************************************/
# define cr_assume_str_gt(Actual, Reference) cr_assume_str_op_(>, Actual, Reference)
#define cr_assume_str_gt(Actual, Reference) cr_assume_str_op_(>, Actual, Reference)
/**
* Assumes `Actual` is lexicographically greater or equal to `Reference`
@ -346,7 +346,7 @@ CR_END_C_API
* @param[in] Reference Reference value
*
*****************************************************************************/
# define cr_assume_str_geq(Actual, Reference) cr_assume_str_op_(>=, Actual, Reference)
#define cr_assume_str_geq(Actual, Reference) cr_assume_str_op_(>=, Actual, Reference)
/**
* Assumes `Actual` is byte-to-byte equal to `Expected`
@ -362,7 +362,7 @@ CR_END_C_API
* @param[in] Size The size of both arrays
*
*****************************************************************************/
# define cr_assume_arr_eq(Actual, Expected, Size) cr_assume(!memcmp((Actual), (Expected), (Size)))
#define cr_assume_arr_eq(Actual, Expected, Size) cr_assume(!memcmp((Actual), (Expected), (Size)))
/**
* Assumes `Actual` is not byte-to-byte equal to `Unexpected`
*
@ -377,24 +377,24 @@ CR_END_C_API
* @param[in] Size The size of both arrays
*
*****************************************************************************/
# define cr_assume_arr_neq(Actual, Unexpected, Size) cr_assume(memcmp((Actual), (Unexpected), (Size)))
#define cr_assume_arr_neq(Actual, Unexpected, Size) cr_assume(memcmp((Actual), (Unexpected), (Size)))
/**@}*/
// Deprecated
/* Deprecated */
# ifndef CRITERION_NO_COMPAT
# define cr_assume_strings_eq(...) CRITERION_ASSERT_DEPRECATED_B(cr_assume_strings_eq, cr_assume_str_eq) cr_assume_str_eq(__VA_ARGS__)
# define cr_assume_strings_neq(...) CRITERION_ASSERT_DEPRECATED_B(cr_assume_strings_neq, cr_assume_str_neq) cr_assume_str_neq(__VA_ARGS__)
# define cr_assume_strings_lt(...) CRITERION_ASSERT_DEPRECATED_B(cr_assume_strings_lt, cr_assume_str_lt) cr_assume_str_lt(__VA_ARGS__)
# define cr_assume_strings_leq(...) CRITERION_ASSERT_DEPRECATED_B(cr_assume_strings_leq, cr_assume_str_leq) cr_assume_str_leq(__VA_ARGS__)
# define cr_assume_strings_gt(...) CRITERION_ASSERT_DEPRECATED_B(cr_assume_strings_gt, cr_assume_str_gt) cr_assume_str_gt(__VA_ARGS__)
# define cr_assume_strings_geq(...) CRITERION_ASSERT_DEPRECATED_B(cr_assume_strings_geq, cr_assume_str_geq) cr_assume_str_geq(__VA_ARGS__)
#ifndef CRITERION_NO_COMPAT
# define cr_assume_strings_eq(...) CRITERION_ASSERT_DEPRECATED_B(cr_assume_strings_eq, cr_assume_str_eq) cr_assume_str_eq(__VA_ARGS__)
# define cr_assume_strings_neq(...) CRITERION_ASSERT_DEPRECATED_B(cr_assume_strings_neq, cr_assume_str_neq) cr_assume_str_neq(__VA_ARGS__)
# define cr_assume_strings_lt(...) CRITERION_ASSERT_DEPRECATED_B(cr_assume_strings_lt, cr_assume_str_lt) cr_assume_str_lt(__VA_ARGS__)
# define cr_assume_strings_leq(...) CRITERION_ASSERT_DEPRECATED_B(cr_assume_strings_leq, cr_assume_str_leq) cr_assume_str_leq(__VA_ARGS__)
# define cr_assume_strings_gt(...) CRITERION_ASSERT_DEPRECATED_B(cr_assume_strings_gt, cr_assume_str_gt) cr_assume_str_gt(__VA_ARGS__)
# define cr_assume_strings_geq(...) CRITERION_ASSERT_DEPRECATED_B(cr_assume_strings_geq, cr_assume_str_geq) cr_assume_str_geq(__VA_ARGS__)
# define cr_assume_arrays_eq(...) CRITERION_ASSERT_DEPRECATED_B(cr_assume_arrays_eq, cr_assume_arr_eq) cr_assume_arr_eq(__VA_ARGS__)
# define cr_assume_arrays_neq(...) CRITERION_ASSERT_DEPRECATED_B(cr_assume_arrays_neq, cr_assume_arr_neq) cr_assume_arr_neq(__VA_ARGS__)
# endif
# define cr_assume_arrays_eq(...) CRITERION_ASSERT_DEPRECATED_B(cr_assume_arrays_eq, cr_assume_arr_eq) cr_assume_arr_eq(__VA_ARGS__)
# define cr_assume_arrays_neq(...) CRITERION_ASSERT_DEPRECATED_B(cr_assume_arrays_neq, cr_assume_arr_neq) cr_assume_arr_neq(__VA_ARGS__)
#endif
# include "internal/theories.h"
#include "internal/theories.h"
#endif /* !CRITERION_THEORIES_H_ */

View file

@ -26,29 +26,29 @@
* @brief Types for tests
*****************************************************************************/
#ifndef CRITERION_TYPES_H_
# define CRITERION_TYPES_H_
#define CRITERION_TYPES_H_
# include "alloc.h"
# ifdef __cplusplus
# include <cstddef>
# include <vector>
#include "alloc.h"
#ifdef __cplusplus
# include <cstddef>
# include <vector>
using std::size_t;
# else
# include <stdbool.h>
# include <stddef.h>
# endif
# include "internal/common.h"
#else
# include <stdbool.h>
# include <stddef.h>
#endif
#include "internal/common.h"
/**
* Enumerates the supported languages for tests
*/
enum criterion_language {
CR_LANG_C, //!< C
CR_LANG_CXX, //!< C++
CR_LANG_OBJC, //!< Objective-C
CR_LANG_OBJCXX, //!< Objective-C++
CR_LANG_C, /* !< C */
CR_LANG_CXX, /* !< C++ */
CR_LANG_OBJC, /* !< Objective-C */
CR_LANG_OBJCXX, /* !< Objective-C++ */
CR_LANG_SIZE_ // leave this at the end
CR_LANG_SIZE_ /* leave this at the end */
};
/**
@ -76,8 +76,8 @@ struct criterion_test_params;
* the Test and TestSuite macros, or other means.
*/
struct criterion_test_extra_data {
/// @cond CRITERION_TEST_EXTRA_DATA_PRIVATE_API
// Start of private API
/* / @cond CRITERION_TEST_EXTRA_DATA_PRIVATE_API
Start of private API */
/*
* Warning: the fields below are not meant to be set manually.
* Setting them improperly *will* wreck havock in your tests.
@ -92,8 +92,8 @@ struct criterion_test_extra_data {
const char *identifier_;
const char *file_;
unsigned line_;
// Enf of private API
/// @endcond
/* Enf of private API
/ @endcond */
/**
* The setup test fixture.

View file

@ -15,7 +15,7 @@ Test(asserts, base) {
Test(asserts, old_school) {
cr_expect_fail("You can fail an assertion with a message from anywhere");
cr_assert_fail(); // or without a message
cr_assert_fail(); /* or without a message */
}
Test(asserts, string) {
@ -57,27 +57,28 @@ struct dummy_struct {
size_t b;
};
int eq_dummy(struct dummy_struct *a, struct dummy_struct *b) {
int eq_dummy(struct dummy_struct *a, struct dummy_struct *b)
{
return a->a != b->a || a->b != b->b;
}
Test(asserts, array) {
int arr1[] = {1, 2, 3, 4};
int arr2[] = {4, 3, 2, 1};
int arr1[] = { 1, 2, 3, 4 };
int arr2[] = { 4, 3, 2, 1 };
cr_assert_arr_eq(arr1, arr1, 4 * sizeof (int));
cr_assert_arr_neq(arr1, arr2, 4 * sizeof (int));
#ifdef __GNUC__
struct dummy_struct s1[] = {{4, 2}, {2, 4}};
struct dummy_struct s1[] = { { 4, 2 }, { 2, 4 } };
struct dummy_struct s2[2];
memset(s2, 0xFF, sizeof(s2));
memset(s2, 0xFF, sizeof (s2));
s2[0].a = 4;
s2[0].b = 2;
s2[1].a = 2;
s2[1].b = 4;
// cr_assert_arr_eq(s1, s2, 2); not guaranteed to work on structs.
/* cr_assert_arr_eq(s1, s2, 2); not guaranteed to work on structs. */
cr_assert_arr_eq_cmp(s1, s2, 2, eq_dummy);
#endif
}

View file

@ -18,7 +18,7 @@ Test(asserts, base) {
Test(asserts, old_school) {
cr_expect_fail("You can fail an assertion with a message from anywhere");
cr_assert_fail(); // or without a message
cr_assert_fail(); /* or without a message */
}
Test(asserts, string) {
@ -59,24 +59,27 @@ struct dummy_struct {
char a;
size_t b;
bool operator==(const struct dummy_struct& rhs) const {
bool operator==(const struct dummy_struct &rhs) const
{
return this->a == rhs.a && this->b == rhs.b;
}
bool operator<(const struct dummy_struct& rhs) const {
bool operator<(const struct dummy_struct &rhs) const
{
return this->a < rhs.a;
}
};
int eq_dummy(struct dummy_struct *a, struct dummy_struct *b) {
int eq_dummy(struct dummy_struct *a, struct dummy_struct *b)
{
return *a == *b ? 0 : (*a < *b ? -1 : 1);
}
Test(asserts, array) {
// 1. (recommended): use std::array and cr_assert_eq
std::array<dummy_struct, 2> cpparr1 = {{{4, 2}, {2, 4}}};
/* 1. (recommended): use std::array and cr_assert_eq */
std::array<dummy_struct, 2> cpparr1 = { { { 4, 2 }, { 2, 4 } } };
std::array<dummy_struct, 2> cpparr2;
memset(&cpparr2[0], 0xFF, 2 * sizeof(struct dummy_struct));
memset(&cpparr2[0], 0xFF, 2 * sizeof (struct dummy_struct));
cpparr2[0].a = 4;
cpparr2[0].b = 2;
cpparr2[1].a = 2;
@ -84,24 +87,24 @@ Test(asserts, array) {
cr_assert_eq(cpparr1, cpparr2);
// 2. Compare arrays byte-to-byte
int arr1[] = {1, 2, 3, 4};
int arr2[] = {4, 3, 2, 1};
/* 2. Compare arrays byte-to-byte */
int arr1[] = { 1, 2, 3, 4 };
int arr2[] = { 4, 3, 2, 1 };
cr_assert_arr_eq(arr1, arr1, 4 * sizeof (int));
cr_assert_arr_neq(arr1, arr2, 4 * sizeof (int));
// 3. Compare arrays with a comparison function
struct dummy_struct s1[] = {{4, 2}, {2, 4}};
/* 3. Compare arrays with a comparison function */
struct dummy_struct s1[] = { { 4, 2 }, { 2, 4 } };
struct dummy_struct s2[2];
memset(s2, 0xFF, sizeof(s2));
memset(s2, 0xFF, sizeof (s2));
s2[0].a = 4;
s2[0].b = 2;
s2[1].a = 2;
s2[1].b = 4;
// cr_assert_arr_eq(&s1, &s2, 2 * sizeof (struct dummy_struct));
// isn't guaranteed to work on structs.
/* cr_assert_arr_eq(&s1, &s2, 2 * sizeof (struct dummy_struct));
isn't guaranteed to work on structs. */
cr_assert_arr_eq_cmp(&s1, &s2, 2, eq_dummy);
}

View file

@ -1,11 +1,13 @@
#include <criterion/criterion.h>
#include <stdio.h>
void setup(void) {
void setup(void)
{
puts("Runs before the test");
}
void teardown(void) {
void teardown(void)
{
puts("Runs after the test");
}

View file

@ -1,11 +1,13 @@
#include <criterion/criterion.h>
#include <stdio.h>
void setup(void) {
void setup(void)
{
puts("Runs before the test");
}
void teardown(void) {
void teardown(void)
{
puts("Runs after the test");
}

View file

@ -7,12 +7,12 @@ using criterion::logging::error;
Test(logging, stream) {
info << "This is an informational message. They are not displayed "
"by default."
"by default."
<< std::endl;
warn << "This is a warning. They indicate some possible malfunction "
"or misconfiguration in the test."
"or misconfiguration in the test."
<< std::endl;
error << "This is an error. They indicate serious problems and "
"are usually shown before the test is aborted."
"are usually shown before the test is aborted."
<< std::endl;
}

View file

@ -1,9 +1,11 @@
#include <criterion/criterion.h>
void setup_suite(void) {
void setup_suite(void)
{
}
void teardown_suite(void) {
void teardown_suite(void)
{
}
TestSuite(suite1, .init = setup_suite, .fini = teardown_suite);
@ -18,4 +20,5 @@ Test(suite2, test) {
TestSuite(disabled, .disabled = true);
Test(disabled, test) {}
Test(disabled, test) {
}

View file

@ -1,9 +1,11 @@
#include <criterion/criterion.h>
void setup_suite(void) {
void setup_suite(void)
{
}
void teardown_suite(void) {
void teardown_suite(void)
{
}
TestSuite(suite1, .init = setup_suite, .fini = teardown_suite);
@ -18,4 +20,5 @@ Test(suite2, test) {
TestSuite(disabled, .disabled = true);
Test(disabled, test) {}
Test(disabled, test) {
}

View file

@ -1,7 +1,7 @@
#include <criterion/parameterized.h>
#include <stdio.h>
// Basic usage
/* Basic usage */
ParameterizedTestParameters(params, simple) {
static int vals[] = { 1, 2, 3 };
@ -13,7 +13,7 @@ ParameterizedTest(int *val, params, simple) {
cr_assert_fail("Parameter: %d", *val);
}
// Multiple parameters must be coalesced in a single parameter
/* Multiple parameters must be coalesced in a single parameter */
struct parameter_tuple {
int i;
@ -22,9 +22,9 @@ struct parameter_tuple {
ParameterizedTestParameters(params, multiple) {
static struct parameter_tuple params[] = {
{1, 2},
{3, 4},
{5, 6},
{ 1, 2 },
{ 3, 4 },
{ 5, 6 },
};
return cr_make_param_array(struct parameter_tuple, params, sizeof (params) / sizeof (struct parameter_tuple));
@ -34,27 +34,30 @@ ParameterizedTest(struct parameter_tuple *tup, params, multiple) {
cr_assert_fail("Parameters: (%d, %f)", tup->i, tup->d);
}
// Cleaning up dynamically generated parameters
/* Cleaning up dynamically generated parameters */
// you **MUST** use cr_malloc, cr_free, cr_realloc, and cr_calloc instead of their
// unprefixed counterparts to allocate dynamic memory in parameters, otherwise
// this will crash.
/* you **MUST** use cr_malloc, cr_free, cr_realloc, and cr_calloc instead of their
unprefixed counterparts to allocate dynamic memory in parameters, otherwise
this will crash. */
struct parameter_tuple_dyn {
int i;
double *d;
};
void free_params(struct criterion_test_params *crp) {
void free_params(struct criterion_test_params *crp)
{
for (size_t i = 0; i < crp->length; ++i) {
struct parameter_tuple_dyn *tup = (struct parameter_tuple_dyn*) crp->params + i;
struct parameter_tuple_dyn *tup = (struct parameter_tuple_dyn *) crp->params + i;
cr_free(tup->d);
}
cr_free(crp->params);
}
double *gen_double(double val) {
double *gen_double(double val)
{
double *ptr = cr_malloc(sizeof (double));
*ptr = val;
return ptr;
}
@ -63,6 +66,7 @@ ParameterizedTestParameters(params, cleanup) {
const size_t nb_tuples = 3;
struct parameter_tuple_dyn *params = cr_malloc(sizeof (struct parameter_tuple_dyn) * nb_tuples);
params[0] = (struct parameter_tuple_dyn) { 1, gen_double(2) };
params[1] = (struct parameter_tuple_dyn) { 3, gen_double(4) };
params[2] = (struct parameter_tuple_dyn) { 5, gen_double(6) };

View file

@ -1,6 +1,6 @@
#include <criterion/parameterized.h>
// Basic usage
/* Basic usage */
ParameterizedTestParameters(params, simple) {
static int vals[] = { 1, 2, 3 };
@ -12,7 +12,7 @@ ParameterizedTest(int *val, params, simple) {
cr_assert_fail("Parameter: %d", *val);
}
// Multiple parameters must be coalesced in a single parameter
/* Multiple parameters must be coalesced in a single parameter */
struct parameter_tuple {
int i;
@ -21,9 +21,9 @@ struct parameter_tuple {
ParameterizedTestParameters(params, multiple) {
static struct parameter_tuple params[] = {
{1, 2},
{3, 4},
{5, 6},
{ 1, 2 },
{ 3, 4 },
{ 5, 6 },
};
return criterion_test_params(params);
@ -33,14 +33,14 @@ ParameterizedTest(struct parameter_tuple *tup, params, multiple) {
cr_assert_fail("Parameters: (%d, %f)", tup->i, tup->d);
}
// Using dynamically generated parameters
/* Using dynamically generated parameters */
// you **MUST** use new_obj, new_arr, delete_obj, delete_arr instead of
// the new, new[], delete and delete[] operators (respectively) to allocate and
// deallocate dynamic memory in parameters, otherwise this will crash.
/* you **MUST** use new_obj, new_arr, delete_obj, delete_arr instead of
the new, new[], delete and delete[] operators (respectively) to allocate and
deallocate dynamic memory in parameters, otherwise this will crash. */
// the criterion::allocator<T> allocator may be used with STL containers to
// allocate objects with the functions described above.
/* the criterion::allocator<T> allocator may be used with STL containers to
allocate objects with the functions described above. */
using criterion::new_obj;
using criterion::new_arr;
@ -49,7 +49,7 @@ using criterion::delete_arr;
struct parameter_tuple_dyn {
int i;
std::unique_ptr<double, decltype(criterion::free)> d;
std::unique_ptr<double, decltype (criterion::free)> d;
parameter_tuple_dyn() : i(0), d(nullptr, criterion::free) {}
parameter_tuple_dyn(int i, double *d) : i(i), d(d, criterion::free) {}
@ -62,11 +62,11 @@ ParameterizedTestParameters(params, cleanup) {
params.push_back(parameter_tuple_dyn(3, new_obj<double>(4)));
params.push_back(parameter_tuple_dyn(5, new_obj<double>(6)));
// A criterion::parameters<T> can be returned in place of a
// criterion_test_params.
/* A criterion::parameters<T> can be returned in place of a
criterion_test_params. */
return params;
}
ParameterizedTest(parameter_tuple_dyn *tup, params, cleanup) {
ParameterizedTest(parameter_tuple_dyn * tup, params, cleanup) {
cr_assert_fail("Parameters: (%d, %f)", tup->i, *tup->d);
}

View file

@ -4,9 +4,10 @@
#include <stdio.h>
#include <ctype.h>
// Testing stdout/stderr
/* Testing stdout/stderr */
void redirect_all_std(void) {
void redirect_all_std(void)
{
cr_redirect_stdout();
cr_redirect_stderr();
}
@ -23,16 +24,19 @@ Test(redirect, test_outputs, .init = redirect_all_std) {
cr_assert_stderr_eq_str("bar");
}
// Testing general I/O with sample command-line rot13
/* Testing general I/O with sample command-line rot13 */
char rot13_char(char c) {
char rot13_char(char c)
{
return isalpha(c) ? (c - 'a' + 13) % 26 + 'a' : c;
}
void rot13_io(void) {
void rot13_io(void)
{
char buf[512];
size_t read;
while ((read = fread(buf, 1, sizeof (buf), stdin)) > 0) {
for (size_t i = 0; i < read; ++i)
buf[i] = rot13_char(buf[i]);
@ -42,7 +46,8 @@ void rot13_io(void) {
}
Test(redirect, rot13, .init = cr_redirect_stdout) {
FILE* f_stdin = cr_get_redirected_stdin();
FILE *f_stdin = cr_get_redirected_stdin();
fprintf(f_stdin, "the quick brown fox jumps over the lazy dog");
fclose(f_stdin);

View file

@ -5,9 +5,10 @@
#include <iostream>
#include <cctype>
// Testing stdout/stderr
/* Testing stdout/stderr */
void redirect_all_std(void) {
void redirect_all_std(void)
{
cr_redirect_stdout();
cr_redirect_stderr();
}
@ -20,13 +21,15 @@ Test(redirect, test_outputs, .init = redirect_all_std) {
cr_assert_stderr_eq_str("bar");
}
// Testing general I/O with sample command-line rot13
/* Testing general I/O with sample command-line rot13 */
char rot13_char(char c) {
char rot13_char(char c)
{
return std::isalpha(c) ? (c - 'a' + 13) % 26 + 'a' : c;
}
void rot13_io(void) {
void rot13_io(void)
{
std::string s;
std::cin >> s;
@ -36,7 +39,7 @@ void rot13_io(void) {
}
Test(redirect, rot13, .init = cr_redirect_stdout) {
auto& f_cin = criterion::get_redirected_cin();
auto &f_cin = criterion::get_redirected_cin();
f_cin << "the quick brown fox jumps over the lazy dog";
f_cin.close();

View file

@ -15,17 +15,17 @@ Test(simple, uncaught) {
crash();
}
// Cross platform segfault simulator ™
// a.k.a. "I can't believe I have to write this for a sample"
/* Cross platform segfault simulator ™
a.k.a. "I can't believe I have to write this for a sample" */
#ifdef _WIN32
# include <windows.h>
#endif
void crash(void) {
void crash(void)
{
#ifdef _WIN32
// This translates to a SIGSEGV
/* This translates to a SIGSEGV */
RaiseException(EXCEPTION_ACCESS_VIOLATION, EXCEPTION_NONCONTINUABLE, 0, NULL);
#else
raise(SIGSEGV);

View file

@ -15,16 +15,17 @@ Test(simple, uncaught) {
crash();
}
// Cross platform segfault simulator ™
// a.k.a. "I can't believe I have to write this for a sample"
/* Cross platform segfault simulator ™
a.k.a. "I can't believe I have to write this for a sample" */
#ifdef _WIN32
# include <windows.h>
#endif
void crash(void) {
void crash(void)
{
#ifdef _WIN32
// This translates to a SIGSEGV
/* This translates to a SIGSEGV */
RaiseException(EXCEPTION_ACCESS_VIOLATION, EXCEPTION_NONCONTINUABLE, 0, NULL);
#else
std::raise(SIGSEGV);

View file

@ -1,18 +1,28 @@
#include <criterion/criterion.h>
#include <stdexcept>
void raise_std(void) {
void raise_std(void)
{
throw std::invalid_argument("Some exception message");
}
void raise_any(void) {
void raise_any(void)
{
throw 1;
}
Test(exception, raise_std) { raise_std(); }
Test(exception, raise_any) { raise_any(); }
Test(exception, raise_std) {
raise_std();
}
Test(exception, raise_any) {
raise_any();
}
Test(exception, raise_std_init, .init = raise_std) {}
Test(exception, raise_any_init, .init = raise_any) {}
Test(exception, raise_std_fini, .fini = raise_std) {}
Test(exception, raise_any_fini, .fini = raise_any) {}
Test(exception, raise_std_init, .init = raise_std) {
}
Test(exception, raise_any_init, .init = raise_any) {
}
Test(exception, raise_std_fini, .fini = raise_std) {
}
Test(exception, raise_any_fini, .fini = raise_any) {
}

View file

@ -13,7 +13,8 @@ Test(exit, unexpected_exit) {
exit(127);
}
void do_exit (void) {
void do_exit(void)
{
exit(127);
}

View file

@ -13,7 +13,8 @@ Test(exit, unexpected_exit) {
exit(127);
}
void do_exit (void) {
void do_exit(void)
{
exit(127);
}

View file

@ -1,8 +1,8 @@
#include <criterion/criterion.h>
// Define NULL consistenly for the regression tests
# undef NULL
# define NULL ((void *)0)
/* Define NULL consistenly for the regression tests */
#undef NULL
#define NULL ((void *) 0)
Test(messages, default) {
cr_expect(0);

View file

@ -1,7 +1,9 @@
#include <criterion/criterion.h>
void crash(void) {
void crash(void)
{
int *i = NULL;
*i = 42;
}

View file

@ -1,7 +1,9 @@
#include <criterion/criterion.h>
void crash(void) {
void crash(void)
{
int *i = NULL;
*i = 42;
}

View file

@ -1,19 +1,19 @@
#ifdef _MSC_VER
#pragma warning(disable : 4090)
# pragma warning(disable : 4090)
#endif
#include <criterion/theories.h>
// Testing for various parameters
/* Testing for various parameters */
TheoryDataPoints(theory, misc) = {
DataPoints(char, 'a'),
DataPoints(bool, true),
DataPoints(short, 1),
DataPoints(int, 1),
DataPoints(float, 3.14f),
DataPoints(double, 3.14),
DataPoints(char *, "test"),
DataPoints(char, 'a'),
DataPoints(bool, true),
DataPoints(short, 1),
DataPoints(int, 1),
DataPoints(float, 3.14f),
DataPoints(double, 3.14),
DataPoints(char *, "test"),
DataPoints(const char *, "other test"),
};
@ -30,6 +30,6 @@ Theory((char c, bool b, short s, int i, float f, double d, char *str, const char
cr_assert_str_eq(str, "test");
cr_assert_str_eq(cstr, "other test");
// abort to see the formatted string of all parameters
/* abort to see the formatted string of all parameters */
cr_assert_fail();
}

View file

@ -1,21 +1,21 @@
#ifdef _MSC_VER
#pragma warning(disable : 4090)
# pragma warning(disable : 4090)
#endif
#include <criterion/theories.h>
// Testing for various parameters
/* Testing for various parameters */
char test_str[] = {'t', 'e', 's', 't', '\0'};
char test_str[] = { 't', 'e', 's', 't', '\0' };
TheoryDataPoints(theory, misc) = {
DataPoints(char, 'a'),
DataPoints(bool, true),
DataPoints(short, 1),
DataPoints(int, 1),
DataPoints(float, 3.14f),
DataPoints(double, 3.14),
DataPoints(char *, test_str),
DataPoints(char, 'a'),
DataPoints(bool, true),
DataPoints(short, 1),
DataPoints(int, 1),
DataPoints(float, 3.14f),
DataPoints(double, 3.14),
DataPoints(char *, test_str),
DataPoints(const char *, "other test"),
};
@ -32,6 +32,6 @@ Theory((char c, bool b, short s, int i, float f, double d, char *str, const char
cr_assert_str_eq(str, "test");
cr_assert_str_eq(cstr, "other test");
// abort to see the formatted string of all parameters
/* abort to see the formatted string of all parameters */
cr_assert_fail();
}

View file

@ -1,19 +1,21 @@
#ifdef _MSC_VER
#pragma warning(disable : 4090)
# pragma warning(disable : 4090)
#endif
#include <criterion/theories.h>
#include <limits.h>
# define INT_DATAPOINTS DataPoints(int, 0, 1, 2, -1, -2, INT_MAX, INT_MIN)
#define INT_DATAPOINTS DataPoints(int, 0, 1, 2, -1, -2, INT_MAX, INT_MIN)
// Let's test the multiplicative properties of 32-bit integers:
/* Let's test the multiplicative properties of 32-bit integers: */
int bad_mul(int a, int b) {
int bad_mul(int a, int b)
{
return a * b;
}
int bad_div(int a, int b) {
int bad_div(int a, int b)
{
return a / b;
}
@ -27,14 +29,15 @@ Theory((int a, int b), algebra, bad_divide_is_inverse_of_multiply) {
cr_assert_eq(a, bad_div(bad_mul(a, b), b));
}
// The above implementation of mul & div fails the test because of overflows,
// let's try again:
long long good_mul(long long a, long long b) {
/* The above implementation of mul & div fails the test because of overflows,
let's try again: */
long long good_mul(long long a, long long b)
{
return a * b;
}
long long good_div(long long a, long long b) {
long long good_div(long long a, long long b)
{
return a / b;
}
@ -48,13 +51,13 @@ Theory((int a, int b), algebra, good_divide_is_inverse_of_multiply) {
cr_assert_eq(a, good_div(good_mul(a, b), b));
}
// For triangulation
/* For triangulation */
Test(algebra, multiplication_by_integer) {
cr_assert_eq(10, good_mul(5, 2));
}
// Another property test
/* Another property test */
TheoryDataPoints(algebra, zero_is_absorbing) = {
INT_DATAPOINTS,
@ -66,24 +69,24 @@ Theory((int a, int b), algebra, zero_is_absorbing) {
cr_assert_eq(0, good_mul(a, b));
}
// Testing for various parameters
/* Testing for various parameters */
struct my_object {
int foo;
};
TheoryDataPoints(theory, misc) = {
DataPoints(char, 'a'),
DataPoints(bool, true),
DataPoints(short, 1),
DataPoints(int, 1),
DataPoints(long, 1),
DataPoints(long long, 1),
DataPoints(float, 3.14f),
DataPoints(double, 3.14),
DataPoints(char *, "test"),
DataPoints(const char *, "other test"),
DataPoints(struct my_object *, &(struct my_object) {42}),
DataPoints(char, 'a'),
DataPoints(bool, true),
DataPoints(short, 1),
DataPoints(int, 1),
DataPoints(long, 1),
DataPoints(long long, 1),
DataPoints(float, 3.14f),
DataPoints(double, 3.14),
DataPoints(char *, "test"),
DataPoints(const char *, "other test"),
DataPoints(struct my_object *, & (struct my_object) { 42 }),
};
Theory((char c, bool b, short s, int i, long l, long long ll, float f, double d, char *str, const char *cstr, struct my_object *obj), theory, misc) {
@ -102,6 +105,6 @@ Theory((char c, bool b, short s, int i, long l, long long ll, float f, double d,
cr_assert_str_eq(cstr, "other test");
cr_assert_eq(obj->foo, 42);
// abort to see the formatted string of all parameters
/* abort to see the formatted string of all parameters */
cr_assert_fail();
}

View file

@ -1,5 +1,5 @@
#ifdef _MSC_VER
#pragma warning(disable : 4090)
# pragma warning(disable : 4090)
#endif
#include <criterion/theories.h>
@ -9,15 +9,17 @@
# include <limits.h>
#endif
# define INT_DATAPOINTS DataPoints(int, 0, 1, 2, -1, -2, INT_MAX, INT_MIN)
#define INT_DATAPOINTS DataPoints(int, 0, 1, 2, -1, -2, INT_MAX, INT_MIN)
// Let's test the multiplicative properties of 32-bit integers:
/* Let's test the multiplicative properties of 32-bit integers: */
int bad_mul(int a, int b) {
int bad_mul(int a, int b)
{
return a * b;
}
int bad_div(int a, int b) {
int bad_div(int a, int b)
{
return a / b;
}
@ -31,14 +33,15 @@ Theory((int a, int b), algebra, bad_divide_is_inverse_of_multiply) {
cr_assert_eq(a, bad_div(bad_mul(a, b), b));
}
// The above implementation of mul & div fails the test because of overflows,
// let's try again:
long long good_mul(long long a, long long b) {
/* The above implementation of mul & div fails the test because of overflows,
let's try again: */
long long good_mul(long long a, long long b)
{
return a * b;
}
long long good_div(long long a, long long b) {
long long good_div(long long a, long long b)
{
return a / b;
}
@ -52,13 +55,13 @@ Theory((int a, int b), algebra, good_divide_is_inverse_of_multiply) {
cr_assert_eq(a, good_div(good_mul(a, b), b));
}
// For triangulation
/* For triangulation */
Test(algebra, multiplication_by_integer) {
cr_assert_eq(10, good_mul(5, 2));
}
// Another property test
/* Another property test */
TheoryDataPoints(algebra, zero_is_absorbing) = {
INT_DATAPOINTS,
@ -70,27 +73,27 @@ Theory((int a, int b), algebra, zero_is_absorbing) {
cr_assert_eq(0, good_mul(a, b));
}
// Testing for various parameters
/* Testing for various parameters */
struct my_object {
int foo;
};
struct my_object o = {42};
struct my_object o = { 42 };
char test_str[] = {'t', 'e', 's', 't', '\0'};
char test_str[] = { 't', 'e', 's', 't', '\0' };
TheoryDataPoints(theory, misc) = {
DataPoints(char, 'a'),
DataPoints(bool, true),
DataPoints(short, 1),
DataPoints(int, 1),
DataPoints(long, 1),
DataPoints(long long, 1),
DataPoints(float, 3.14f),
DataPoints(double, 3.14),
DataPoints(char *, test_str),
DataPoints(const char *, "other test"),
DataPoints(char, 'a'),
DataPoints(bool, true),
DataPoints(short, 1),
DataPoints(int, 1),
DataPoints(long, 1),
DataPoints(long long, 1),
DataPoints(float, 3.14f),
DataPoints(double, 3.14),
DataPoints(char *, test_str),
DataPoints(const char *, "other test"),
DataPoints(struct my_object *, &o),
};
@ -110,6 +113,6 @@ Theory((char c, bool b, short s, int i, long l, long long ll, float f, double d,
cr_assert_str_eq(cstr, "other test");
cr_assert_eq(obj->foo, 42);
// abort to see the formatted string of all parameters
/* abort to see the formatted string of all parameters */
cr_assert_fail();
}

View file

@ -2,7 +2,7 @@
#ifdef _WIN32
# include <windows.h>
# define sleep(x) Sleep(x * 1000)
# define sleep(x) Sleep(x * 1000)
#else
# include <unistd.h>
#endif

View file

@ -22,13 +22,13 @@
* THE SOFTWARE.
*/
#ifndef COMMON_H_
# define COMMON_H_
#define COMMON_H_
# include <stdio.h>
# include <stdlib.h>
#include <stdio.h>
#include <stdlib.h>
# include "criterion/internal/common.h"
#include "criterion/internal/common.h"
# define DEF(X, Y) ((X) ? (X) : (Y))
#define DEF(X, Y) ((X) ? (X) : (Y))
#endif /* !COMMON_H_ */

View file

@ -32,7 +32,7 @@ static bxf_arena inheritable_arena;
void cri_alloc_init(void)
{
int rc = bxf_arena_init(0, BXF_ARENA_RESIZE | BXF_ARENA_IDENTITY
| BXF_ARENA_KEEPMAPPED, &inheritable_arena);
| BXF_ARENA_KEEPMAPPED, &inheritable_arena);
if (rc < 0)
cr_panic("Could not initialize inheritable arena: %s", strerror(-rc));
@ -51,6 +51,7 @@ bxf_arena cri_alloc_getarena(void)
void *cr_malloc(size_t size)
{
bxf_ptr ptr = bxf_arena_alloc(&inheritable_arena, size);
if (ptr < 0) {
errno = -ptr;
return NULL;
@ -61,6 +62,7 @@ void *cr_malloc(size_t size)
void *cr_calloc(size_t nmemb, size_t size)
{
void *ptr = cr_malloc(size * nmemb);
if (ptr)
memset(ptr, 0, size * nmemb);
return ptr;
@ -68,8 +70,9 @@ void *cr_calloc(size_t nmemb, size_t size)
void *cr_realloc(void *ptr, size_t size)
{
bxf_ptr p = (intptr_t)ptr - (intptr_t)inheritable_arena;
bxf_ptr p = (intptr_t) ptr - (intptr_t) inheritable_arena;
bxf_ptr newptr = bxf_arena_realloc(&inheritable_arena, p, size);
if (newptr < 0) {
errno = -newptr;
return NULL;
@ -79,6 +82,7 @@ void *cr_realloc(void *ptr, size_t size)
void cr_free(void *ptr)
{
bxf_ptr p = (intptr_t)ptr - (intptr_t)inheritable_arena;
bxf_ptr p = (intptr_t) ptr - (intptr_t) inheritable_arena;
(void) bxf_arena_free(&inheritable_arena, p);
}

View file

@ -22,10 +22,10 @@
* THE SOFTWARE.
*/
#ifndef COMPAT_ALLOC_H_
# define COMPAT_ALLOC_H_
#define COMPAT_ALLOC_H_
# include <boxfort.h>
# include "criterion/alloc.h"
#include <boxfort.h>
#include "criterion/alloc.h"
void cri_alloc_init(void);
void cri_alloc_term(void);

View file

@ -23,8 +23,10 @@
*/
#include "basename.h"
const char *basename_compat(const char *str) {
const char *basename_compat(const char *str)
{
const char *start = str;
for (const char *c = str; *c; ++c)
if ((*c == '/' || *c == '\\') && c[1])
start = c + 1;

View file

@ -22,7 +22,7 @@
* THE SOFTWARE.
*/
#ifndef BASENAME_H_
# define BASENAME_H_
#define BASENAME_H_
const char *basename_compat(const char *str);

View file

@ -22,46 +22,46 @@
* THE SOFTWARE.
*/
#ifndef INTERNAL_H_
# define INTERNAL_H_
#define INTERNAL_H_
# if defined(_WIN32) && !defined(__CYGWIN__)
# include <windows.h>
#if defined (_WIN32) && !defined (__CYGWIN__)
# include <windows.h>
# if defined(MINGW_DEFINE_OFF_T) && (defined(__MINGW32__) || defined(__MINGW64__))
# include "off_t.h"
# if defined (MINGW_DEFINE_OFF_T) && (defined (__MINGW32__) || defined (__MINGW64__))
# include "off_t.h"
# if !defined(__MINGW64__)
# define off_t cr_off32
# else
# define off_t cr_off64
# endif
# define off64_t cr_off64
# if !defined (__MINGW64__)
# define off_t cr_off32
# else
# define off_t cr_off64
# endif
# include <io.h>
# if defined(MINGW_DEFINE_OFF_T) && (defined(__MINGW32__) || defined(__MINGW64__))
# undef off_t
# undef off64_t
# endif
# include <fcntl.h>
# include <winnt.h>
# include <stdint.h>
# include <signal.h>
# else
# include <fcntl.h>
# include <signal.h>
# include <sys/param.h>
# include <sys/wait.h>
# include <unistd.h>
# ifdef BSD
# include <sys/types.h>
# define off64_t cr_off64
# endif
# include <io.h>
# if defined (MINGW_DEFINE_OFF_T) && (defined (__MINGW32__) || defined (__MINGW64__))
# undef off_t
# undef off64_t
# endif
# include <fcntl.h>
# include <winnt.h>
# include <stdint.h>
# include <signal.h>
#else
# include <fcntl.h>
# include <signal.h>
# include <sys/param.h>
# include <sys/wait.h>
# include <unistd.h>
# ifdef BSD
# include <sys/types.h>
typedef unsigned long u_long;
typedef unsigned int u_int;
typedef unsigned short u_short;
typedef unsigned char u_char;
# include <sys/sysctl.h>
# endif
# include <sys/sysctl.h>
# endif
#endif
# include "posix.h"
#include "posix.h"
#endif /* !INTERNAL_H_ */

View file

@ -36,7 +36,8 @@
#ifdef VANILLA_WIN32
static HANDLE cr_job;
#else
static void handle_sigterm(CR_UNUSED int signum) {
static void handle_sigterm(CR_UNUSED int signum)
{
assert(signum == SIGTERM);
kill(-getpid(), SIGTERM);
@ -44,32 +45,34 @@ static void handle_sigterm(CR_UNUSED int signum) {
}
#endif
void setup_parent_job(void) {
void setup_parent_job(void)
{
#ifdef VANILLA_WIN32
// Put runner in its own job
/* Put runner in its own job */
cr_job = CreateJobObject(NULL, NULL);
if (!AssignProcessToJobObject(cr_job, GetCurrentProcess()))
abort();
#else
// Put runner in its own group
/* Put runner in its own group */
setpgid(0, 0);
// Setup termination handlers
/* Setup termination handlers */
sigset_t block_mask;
sigemptyset (&block_mask);
sigaddset (&block_mask, SIGINT);
sigaddset (&block_mask, SIGQUIT);
sigaddset (&block_mask, SIGTSTP);
sigemptyset(&block_mask);
sigaddset(&block_mask, SIGINT);
sigaddset(&block_mask, SIGQUIT);
sigaddset(&block_mask, SIGTSTP);
struct sigaction sa = {
.sa_handler = handle_sigterm,
.sa_mask = block_mask,
.sa_handler = handle_sigterm,
.sa_mask = block_mask,
};
sigaction(SIGTERM, &sa, NULL);
#endif
}
void cr_killall(void) {
void cr_killall(void)
{
fflush(NULL);
#ifdef VANILLA_WIN32
if (!TerminateJobObject(cr_job, 1))
@ -79,7 +82,8 @@ void cr_killall(void) {
#endif
}
void cr_terminate(struct criterion_global_stats *stats) {
void cr_terminate(struct criterion_global_stats *stats)
{
report(POST_ALL, stats);
process_all_output(stats);
log(post_all, stats);

View file

@ -22,10 +22,10 @@
* THE SOFTWARE.
*/
#ifndef COMPAT_KILL_H_
# define COMPAT_KILL_H_
#define COMPAT_KILL_H_
# include "posix.h"
# include "criterion/stats.h"
#include "posix.h"
#include "criterion/stats.h"
void setup_parent_job(void);
void cr_killall(void);

View file

@ -21,7 +21,7 @@
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
#define _GNU_SOURCE 1
#define _GNU_SOURCE 1
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
@ -31,7 +31,7 @@
#include "internal.h"
#include "criterion/redirect.h"
#if defined(HAVE_FUNOPEN) || defined(HAVE_FOPENCOOKIE)
#if defined (HAVE_FUNOPEN) || defined (HAVE_FOPENCOOKIE)
# ifdef HAVE_FUNOPEN
typedef int cr_count;
@ -51,12 +51,14 @@ struct memfile {
char *mem;
};
static inline size_t size_safe_add(size_t size, size_t cur, cr_off off) {
static inline size_t size_safe_add(size_t size, size_t cur, cr_off off)
{
cur = cur < SIZE_MAX - off ? cur + off : SIZE_MAX;
return cur < size ? cur : size;
}
static inline size_t off_safe_add(size_t size, size_t cur, cr_off off) {
static inline size_t off_safe_add(size_t size, size_t cur, cr_off off)
{
if (off >= 0)
cur = cur < SIZE_MAX - off ? cur + off : SIZE_MAX;
else
@ -64,17 +66,19 @@ static inline size_t off_safe_add(size_t size, size_t cur, cr_off off) {
return cur < size ? cur : size;
}
# define errno_return(Errno, Val) \
do { \
errno = (Errno); \
return (Val); \
# define errno_return(Errno, Val) \
do { \
errno = (Errno); \
return (Val); \
} while (0)
static cr_retcount mock_file_read(void *cookie, char *buf, cr_count count) {
static cr_retcount mock_file_read(void *cookie, char *buf, cr_count count)
{
struct memfile *mf = cookie;
# ifdef HAVE_FUNOPEN
if (count < 0)
errno_return(EINVAL, (cr_retcount) -1);
errno_return(EINVAL, (cr_retcount) - 1);
# endif
if (mf->cur >= mf->size || count == 0)
return 0;
@ -86,17 +90,19 @@ static cr_retcount mock_file_read(void *cookie, char *buf, cr_count count) {
return count;
}
static cr_retcount mock_file_write(void *cookie, const char *buf, cr_count count) {
static cr_retcount mock_file_write(void *cookie, const char *buf, cr_count count)
{
struct memfile *mf = cookie;
# ifdef HAVE_FUNOPEN
if (count < 0)
errno_return(EINVAL, (cr_retcount) -1);
errno_return(EINVAL, (cr_retcount) - 1);
# endif
if (count == 0)
return 0;
if (mf->cur >= mf->max_size)
errno_return(EIO, (cr_retcount) -1);
errno_return(EIO, (cr_retcount) - 1);
size_t end = size_safe_add(mf->max_size, mf->cur, count);
if (mf->size < end)
@ -108,7 +114,7 @@ static cr_retcount mock_file_write(void *cookie, const char *buf, cr_count count
mf->region_size = mf->region_size * 3 / 2;
char *newptr = realloc(mf->mem, mf->region_size);
if (!newptr)
errno_return(EIO, (cr_retcount) -1);
errno_return(EIO, (cr_retcount) - 1);
mf->mem = newptr;
}
memcpy(mf->mem + mf->cur, buf, count);
@ -117,20 +123,24 @@ static cr_retcount mock_file_write(void *cookie, const char *buf, cr_count count
}
# ifdef HAVE_FUNOPEN
static cr_off mock_file_seek(void *cookie, cr_off off, int whence) {
static cr_off mock_file_seek(void *cookie, cr_off off, int whence)
{
struct memfile *mf = cookie;
switch (whence) {
case SEEK_SET: return (mf->cur = off);
case SEEK_CUR: return (mf->cur = off_safe_add(mf->size, mf->cur, off));
case SEEK_END: return (mf->cur = off_safe_add(mf->size, mf->size, off));
case SEEK_SET: return mf->cur = off;
case SEEK_CUR: return mf->cur = off_safe_add(mf->size, mf->cur, off);
case SEEK_END: return mf->cur = off_safe_add(mf->size, mf->size, off);
default: break;
}
errno = EINVAL;
return (off_t) -1;
}
# else
static int mock_file_seek(void *cookie, cr_off *off, int whence) {
static int mock_file_seek(void *cookie, cr_off *off, int whence)
{
struct memfile *mf = cookie;
switch (whence) {
case SEEK_SET: mf->cur = *off; break;
case SEEK_CUR: *off = (mf->cur = off_safe_add(mf->size, mf->cur, *off)); break;
@ -141,16 +151,19 @@ static int mock_file_seek(void *cookie, cr_off *off, int whence) {
}
# endif
static int mock_file_close(void *cookie) {
static int mock_file_close(void *cookie)
{
struct memfile *mf = cookie;
free(mf->mem);
free(cookie);
return 0;
}
#endif /* defined(HAVE_FUNOPEN) || defined(HAVE_FOPENCOOKIE) */
FILE *cr_mock_file_size(size_t max_size) {
#if defined(HAVE_FUNOPEN) || defined(HAVE_FOPENCOOKIE)
FILE *cr_mock_file_size(size_t max_size)
{
#if defined (HAVE_FUNOPEN) || defined (HAVE_FOPENCOOKIE)
struct memfile *cookie = malloc(sizeof (struct memfile));
*cookie = (struct memfile) {
.max_size = max_size,
@ -159,7 +172,7 @@ FILE *cr_mock_file_size(size_t max_size) {
};
FILE *f;
# if defined(HAVE_FOPENCOOKIE)
# if defined (HAVE_FOPENCOOKIE)
f = fopencookie(cookie, "w+", (cookie_io_functions_t) {
.read = mock_file_read,
.write = mock_file_write,
@ -168,10 +181,10 @@ FILE *cr_mock_file_size(size_t max_size) {
});
# else
f = funopen(cookie,
mock_file_read,
mock_file_write,
mock_file_seek,
mock_file_close);
mock_file_read,
mock_file_write,
mock_file_seek,
mock_file_close);
# endif
return f;
#elif defined (HAVE_OPEN_MEMSTREAM)
@ -187,7 +200,7 @@ FILE *cr_mock_file_size(size_t max_size) {
#else
(void) max_size;
// fallback to tmpfile()
return tmpfile();
/* fallback to tmpfile() */
return tmpfile();
#endif
}

View file

@ -22,9 +22,9 @@
* THE SOFTWARE.
*/
#ifndef CR_OFF_T_DEFINED
# define CR_OFF_T_DEFINED
#define CR_OFF_T_DEFINED
# include <stdint.h>
#include <stdint.h>
typedef int32_t cr_off32;
typedef int64_t cr_off64;

View file

@ -22,10 +22,10 @@
* THE SOFTWARE.
*/
#ifndef PIPE_INTERNAL_H_
# define PIPE_INTERNAL_H_
#define PIPE_INTERNAL_H_
# include "internal.h"
# include "pipe.h"
#include "internal.h"
#include "pipe.h"
struct pipe_handle {
#ifdef VANILLA_WIN32

View file

@ -27,7 +27,8 @@
#include "criterion/assert.h"
#include "pipe-internal.h"
FILE *pipe_in(s_pipe_handle *p, enum pipe_opt opts) {
FILE *pipe_in(s_pipe_handle *p, enum pipe_opt opts)
{
#ifdef VANILLA_WIN32
if (opts & PIPE_CLOSE)
CloseHandle(p->fhs[1]);
@ -52,7 +53,8 @@ FILE *pipe_in(s_pipe_handle *p, enum pipe_opt opts) {
return in;
}
FILE *pipe_out(s_pipe_handle *p, enum pipe_opt opts) {
FILE *pipe_out(s_pipe_handle *p, enum pipe_opt opts)
{
#ifdef VANILLA_WIN32
if (opts & PIPE_CLOSE)
CloseHandle(p->fhs[0]);
@ -77,69 +79,73 @@ FILE *pipe_out(s_pipe_handle *p, enum pipe_opt opts) {
return out;
}
int stdpipe_stack(s_pipe_handle *out) {
int stdpipe_stack(s_pipe_handle *out)
{
#ifdef VANILLA_WIN32
HANDLE fhs[2];
SECURITY_ATTRIBUTES attr = {
.nLength = sizeof (SECURITY_ATTRIBUTES),
.nLength = sizeof (SECURITY_ATTRIBUTES),
.bInheritHandle = TRUE
};
if (!CreatePipe(fhs, fhs + 1, &attr, 0))
return -1;
*out = (s_pipe_handle) {{ fhs[0], fhs[1] }};
*out = (s_pipe_handle) { { fhs[0], fhs[1] } };
#else
int fds[2] = { -1, -1 };
if (pipe(fds) == -1)
return -1;
*out = (s_pipe_handle) {{ fds[0], fds[1] }};
*out = (s_pipe_handle) { { fds[0], fds[1] } };
#endif
return 0;
}
s_pipe_handle *stdpipe() {
s_pipe_handle *stdpipe()
{
s_pipe_handle *handle = smalloc(sizeof (s_pipe_handle));
if (stdpipe_stack(handle) < 0)
return NULL;
return handle;
}
int stdpipe_options(s_pipe_handle *handle, int id, int noblock) {
int stdpipe_options(s_pipe_handle *handle, int id, int noblock)
{
#ifdef VANILLA_WIN32
HANDLE fhs[2];
SECURITY_ATTRIBUTES attr = {
.nLength = sizeof (SECURITY_ATTRIBUTES),
.nLength = sizeof (SECURITY_ATTRIBUTES),
.bInheritHandle = TRUE
};
char pipe_name[256] = {0};
char pipe_name[256] = { 0 };
snprintf(pipe_name, sizeof (pipe_name),
"\\\\.\\pipe\\criterion_%lu_%d", GetCurrentProcessId(), id);
"\\\\.\\pipe\\criterion_%lu_%d", GetCurrentProcessId(), id);
fhs[0] = CreateNamedPipe(pipe_name,
PIPE_ACCESS_INBOUND,
PIPE_TYPE_BYTE | PIPE_READMODE_BYTE
| (noblock ? PIPE_NOWAIT : PIPE_WAIT),
1,
4096 * 4,
4096 * 4,
0,
&attr);
PIPE_ACCESS_INBOUND,
PIPE_TYPE_BYTE | PIPE_READMODE_BYTE
| (noblock ? PIPE_NOWAIT : PIPE_WAIT),
1,
4096 * 4,
4096 * 4,
0,
&attr);
if (fhs[0] == INVALID_HANDLE_VALUE)
return 0;
fhs[1] = CreateFile(pipe_name,
GENERIC_WRITE,
0,
&attr,
OPEN_EXISTING,
0,
NULL);
GENERIC_WRITE,
0,
&attr,
OPEN_EXISTING,
0,
NULL);
if (fhs[1] == INVALID_HANDLE_VALUE) {
CloseHandle(fhs[0]);
return 0;
}
*handle = (s_pipe_handle) {{ fhs[0], fhs[1] }};
*handle = (s_pipe_handle) { { fhs[0], fhs[1] } };
#else
(void) id;
@ -151,13 +157,15 @@ int stdpipe_options(s_pipe_handle *handle, int id, int noblock) {
for (int i = 0; i < 2; ++i)
fcntl(fds[i], F_SETFL, fcntl(fds[i], F_GETFL) | O_NONBLOCK);
*handle = (s_pipe_handle) {{ fds[0], fds[1] }};
*handle = (s_pipe_handle) { { fds[0], fds[1] } };
#endif
return 1;
}
void pipe_std_redirect(s_pipe_handle *pipe, enum criterion_std_fd fd) {
void pipe_std_redirect(s_pipe_handle *pipe, enum criterion_std_fd fd)
{
enum pipe_end end = fd == CR_STDIN ? PIPE_READ : PIPE_WRITE;
#ifdef VANILLA_WIN32
int stdfd = _open_osfhandle((intptr_t) pipe->fhs[end], end == PIPE_READ ? _O_RDONLY : _O_WRONLY);
if (stdfd == -1)
@ -182,8 +190,10 @@ void pipe_std_redirect(s_pipe_handle *pipe, enum criterion_std_fd fd) {
#endif
}
void close_pipe_file_handle(void *ptr, CR_UNUSED void *meta) {
void close_pipe_file_handle(void *ptr, CR_UNUSED void *meta)
{
s_pipe_file_handle *h = ptr;
#ifdef VANILLA_WIN32
CloseHandle(h->fh);
#else
@ -192,20 +202,23 @@ void close_pipe_file_handle(void *ptr, CR_UNUSED void *meta) {
}
#ifdef VANILLA_WIN32
static HANDLE win_dup(HANDLE h) {
static HANDLE win_dup(HANDLE h)
{
HANDLE dup;
DuplicateHandle(GetCurrentProcess(),
h,
GetCurrentProcess(),
&dup,
0,
TRUE,
DUPLICATE_SAME_ACCESS);
h,
GetCurrentProcess(),
&dup,
0,
TRUE,
DUPLICATE_SAME_ACCESS);
return dup;
}
#endif
s_pipe_file_handle *pipe_out_handle(s_pipe_handle *p, enum pipe_opt opts) {
s_pipe_file_handle *pipe_out_handle(s_pipe_handle *p, enum pipe_opt opts)
{
#ifdef VANILLA_WIN32
if (opts & PIPE_CLOSE)
CloseHandle(p->fhs[0]);
@ -214,8 +227,8 @@ s_pipe_file_handle *pipe_out_handle(s_pipe_handle *p, enum pipe_opt opts) {
fh = win_dup(fh);
s_pipe_file_handle *h = smalloc(
.size = sizeof (s_pipe_file_handle),
.dtor = close_pipe_file_handle);
.size = sizeof (s_pipe_file_handle),
.dtor = close_pipe_file_handle);
h->fh = fh;
return h;
@ -227,15 +240,16 @@ s_pipe_file_handle *pipe_out_handle(s_pipe_handle *p, enum pipe_opt opts) {
fd = dup(fd);
s_pipe_file_handle *h = smalloc(
.size = sizeof (s_pipe_file_handle),
.dtor = close_pipe_file_handle);
.size = sizeof (s_pipe_file_handle),
.dtor = close_pipe_file_handle);
h->fd = fd;
return h;
#endif
}
s_pipe_file_handle *pipe_in_handle(s_pipe_handle *p, enum pipe_opt opts) {
s_pipe_file_handle *pipe_in_handle(s_pipe_handle *p, enum pipe_opt opts)
{
#ifdef VANILLA_WIN32
if (opts & PIPE_CLOSE)
CloseHandle(p->fhs[1]);
@ -244,8 +258,8 @@ s_pipe_file_handle *pipe_in_handle(s_pipe_handle *p, enum pipe_opt opts) {
fh = win_dup(fh);
s_pipe_file_handle *h = smalloc(
.size = sizeof (s_pipe_file_handle),
.dtor = close_pipe_file_handle);
.size = sizeof (s_pipe_file_handle),
.dtor = close_pipe_file_handle);
h->fh = fh;
return h;
@ -257,15 +271,16 @@ s_pipe_file_handle *pipe_in_handle(s_pipe_handle *p, enum pipe_opt opts) {
fd = dup(fd);
s_pipe_file_handle *h = smalloc(
.size = sizeof (s_pipe_file_handle),
.dtor = close_pipe_file_handle);
.size = sizeof (s_pipe_file_handle),
.dtor = close_pipe_file_handle);
h->fd = fd;
return h;
#endif
}
int pipe_write(const void *buf, size_t size, s_pipe_file_handle *pipe) {
int pipe_write(const void *buf, size_t size, s_pipe_file_handle *pipe)
{
#ifdef VANILLA_WIN32
DWORD written = 0;
size_t off = 0;
@ -288,7 +303,8 @@ int pipe_write(const void *buf, size_t size, s_pipe_file_handle *pipe) {
#endif
}
int pipe_read(void *buf, size_t size, s_pipe_file_handle *pipe) {
int pipe_read(void *buf, size_t size, s_pipe_file_handle *pipe)
{
#ifdef VANILLA_WIN32
DWORD read = 0;
size_t off = 0;
@ -319,20 +335,22 @@ s_pipe_handle *stdout_redir = &stdout_redir_;
s_pipe_handle *stderr_redir = &stderr_redir_;
s_pipe_handle *stdin_redir = &stdin_redir_;
s_pipe_file_handle *pipe_file_open(const char *path) {
s_pipe_file_handle *pipe_file_open(const char *path)
{
s_pipe_file_handle *h = smalloc(
.size = sizeof (s_pipe_file_handle),
.dtor = close_pipe_file_handle);
.size = sizeof (s_pipe_file_handle),
.dtor = close_pipe_file_handle);
#ifdef VANILLA_WIN32
if (!path)
path = "nul";
h->fh = CreateFile(path,
GENERIC_READ | GENERIC_WRITE,
0,
NULL,
OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL,
NULL);
GENERIC_READ | GENERIC_WRITE,
0,
NULL,
OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL,
NULL);
#else
if (!path)
path = "/dev/null";

View file

@ -22,12 +22,12 @@
* THE SOFTWARE.
*/
#ifndef PIPE_H_
# define PIPE_H_
#define PIPE_H_
# include <stdio.h>
# include <stdlib.h>
# include "common.h"
# include "log/logging.h"
#include <stdio.h>
#include <stdlib.h>
#include "common.h"
#include "log/logging.h"
struct pipe_handle;
typedef struct pipe_handle s_pipe_handle;
@ -48,7 +48,7 @@ enum criterion_std_fd {
enum pipe_opt {
PIPE_NOOPT = 0,
PIPE_DUP = 1 << 0,
PIPE_DUP = 1 << 0,
PIPE_CLOSE = 1 << 1,
};
@ -65,7 +65,8 @@ void pipe_std_redirect(s_pipe_handle *pipe, enum criterion_std_fd fd);
int pipe_write(const void *buf, size_t size, s_pipe_file_handle *pipe);
int pipe_read(void *buf, size_t size, s_pipe_file_handle *pipe);
CR_INLINE FILE* get_std_file(enum criterion_std_fd fd_kind) {
CR_INLINE FILE *get_std_file(enum criterion_std_fd fd_kind)
{
switch (fd_kind) {
case CR_STDIN: return stdin;
case CR_STDOUT: return stdout;

View file

@ -22,53 +22,53 @@
* THE SOFTWARE.
*/
#ifndef POSIX_COMPAT_H_
# define POSIX_COMPAT_H_
#define POSIX_COMPAT_H_
# if defined(_WIN32) && !defined(__CYGWIN__)
# define VANILLA_WIN32
# endif
#if defined (_WIN32) && !defined (__CYGWIN__)
# define VANILLA_WIN32
#endif
# if defined(BSD) \
|| defined(__FreeBSD__) \
|| defined(__NetBSD__) \
|| defined(__OpenBSD__) \
|| defined(__DragonFly__)
# define OS_BSD 1
# endif
#if defined (BSD) \
|| defined (__FreeBSD__) \
|| defined (__NetBSD__) \
|| defined (__OpenBSD__) \
|| defined (__DragonFly__)
# define OS_BSD 1
#endif
# if !defined(_POSIX_SOURCE)
# define _POSIX_SOURCE 1
# define TMP_POSIX
# endif
# if defined(MINGW_DEFINE_OFF_T) && (defined(__MINGW32__) || defined(__MINGW64__))
# include "off_t.h"
#if !defined (_POSIX_SOURCE)
# define _POSIX_SOURCE 1
# define TMP_POSIX
#endif
#if defined (MINGW_DEFINE_OFF_T) && (defined (__MINGW32__) || defined (__MINGW64__))
# include "off_t.h"
# if !defined(__MINGW64__)
# define off_t cr_off32
# else
# define off_t cr_off64
# endif
# define off64_t cr_off64
# endif
# include <stdio.h>
# include <string.h>
# if defined(MINGW_DEFINE_OFF_T) && defined(__MINGW32__) || defined(__MINGW64__)
# undef off_t
# undef off64_t
# endif
# ifdef TMP_POSIX
# undef _POSIX_SOURCE
# undef TMP_POSIX
# if !defined (__MINGW64__)
# define off_t cr_off32
# else
# define off_t cr_off64
# endif
# define off64_t cr_off64
#endif
#include <stdio.h>
#include <string.h>
#if defined (MINGW_DEFINE_OFF_T) && defined (__MINGW32__) || defined (__MINGW64__)
# undef off_t
# undef off64_t
#endif
#ifdef TMP_POSIX
# undef _POSIX_SOURCE
# undef TMP_POSIX
#endif
# ifdef VANILLA_WIN32
# define WEXITSTATUS(Status) (((Status) & 0xFF00) >> 8)
# define WTERMSIG(Status) ((Status) & 0x7F)
# define WIFEXITED(Status) (WTERMSIG(Status) == 0)
# define WIFSIGNALED(Status) (((signed char) (WTERMSIG(Status) + 1) >> 1) > 0)
#ifdef VANILLA_WIN32
# define WEXITSTATUS(Status) (((Status) & 0xFF00) >> 8)
# define WTERMSIG(Status) ((Status) & 0x7F)
# define WIFEXITED(Status) (WTERMSIG(Status) == 0)
# define WIFSIGNALED(Status) (((signed char) (WTERMSIG(Status) + 1) >> 1) > 0)
# define SIGPROF 27
# define SIGSYS 31
# define SIGPROF 27
# define SIGSYS 31
/*
* We define a custom exception code following the ntstatus specification:
@ -81,15 +81,15 @@
* |`------------------------------------- Customer code: Yes (0b1)
* `-------------------------------------- Severity: Error (0b11)
*/
# define CR_EXCEPTION_TIMEOUT 0xEFFFFFFF
# define CR_EXCEPTION_TIMEOUT 0xEFFFFFFF
# else
# include <sys/wait.h>
# endif
#else
# include <sys/wait.h>
#endif
# include "compat/pipe.h"
# include "compat/section.h"
# include "compat/process.h"
# include "compat/basename.h"
#include "compat/pipe.h"
#include "compat/section.h"
#include "compat/process.h"
#include "compat/basename.h"
#endif /* !POSIX_COMPAT_H_ */

View file

@ -24,7 +24,8 @@
#include "process.h"
#include "internal.h"
unsigned long long get_process_id(void) {
unsigned long long get_process_id(void)
{
#ifdef VANILLA_WIN32
return (unsigned long long) GetCurrentProcessId();
#else

View file

@ -22,7 +22,7 @@
* THE SOFTWARE.
*/
#ifndef COMPAT_PROCESS_H_
# define COMPAT_PROCESS_H_
#define COMPAT_PROCESS_H_
unsigned long long get_process_id(void);

View file

@ -24,7 +24,8 @@
#include "internal.h"
size_t get_processor_count(void) {
size_t get_processor_count(void)
{
#ifdef _WIN32
/* This code shall return 1 until
https://github.com/Snaipe/Criterion/issues/118 gets fixed. */
@ -36,7 +37,7 @@ size_t get_processor_count(void) {
# else
return 1;
# endif
#elif defined(BSD)
#elif defined (BSD)
int mib[2] = { CTL_HW, HW_NCPU };
# ifdef __APPLE__
size_t miblen = 2;
@ -51,7 +52,7 @@ size_t get_processor_count(void) {
if (count < 1 || res == -1)
count = 1;
return (size_t) count;
#elif defined(__linux__)
#elif defined (__linux__)
return sysconf(_SC_NPROCESSORS_ONLN);
#else
# error System not supported

View file

@ -22,9 +22,9 @@
* THE SOFTWARE.
*/
#ifndef COMPAT_PROCESSOR_H_
# define COMPAT_PROCESSOR_H_
#define COMPAT_PROCESSOR_H_
# include <stddef.h>
#include <stddef.h>
size_t get_processor_count(void);

View file

@ -21,14 +21,15 @@
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
# include "section.h"
#include "section.h"
# include <string.h>
# include <sys/mman.h>
# include <fcntl.h>
# include <unistd.h>
#include <string.h>
#include <sys/mman.h>
#include <fcntl.h>
#include <unistd.h>
static int open_self(void) {
static int open_self(void)
{
#if defined __linux__
return open("/proc/self/exe", O_RDONLY);
#elif defined __NetBSD__
@ -54,20 +55,20 @@ static int open_self(void) {
static int open_module_map(mod_handle *mod)
{
/* Load the ELF header and the section header table */
const ElfW(Ehdr) *elf = mmap(NULL, sizeof (ElfW(Ehdr)),
PROT_READ, MAP_PRIVATE, mod->fd, 0);
const ElfW(Ehdr) * elf = mmap(NULL, sizeof (ElfW(Ehdr)),
PROT_READ, MAP_PRIVATE, mod->fd, 0);
const void *oldm = elf;
if (elf == MAP_FAILED)
goto fail;
if (memcmp(elf->e_ident, (char [4]) { 0x7f, 'E', 'L', 'F' }, 4))
if (memcmp(elf->e_ident, (char[4]) { 0x7f, 'E', 'L', 'F' }, 4))
goto fail;
size_t new_map_len = elf->e_shoff + elf->e_shnum * elf->e_shentsize;
#ifdef HAVE_MREMAP
elf = mremap((void*) elf, sizeof (ElfW(Ehdr)), new_map_len, MREMAP_MAYMOVE);
elf = mremap((void *) elf, sizeof (ElfW(Ehdr)), new_map_len, MREMAP_MAYMOVE);
#else
elf = mmap(NULL, new_map_len, PROT_READ, MAP_PRIVATE, mod->fd, 0);
#endif
@ -98,6 +99,7 @@ static void close_module_map(mod_handle *mod)
int open_module_self(mod_handle *mod)
{
int fd = open_self();
if (fd == -1)
return 0;
@ -111,13 +113,13 @@ void close_module(mod_handle *mod)
close(mod->fd);
}
static const void *map_shdr(int fd, const ElfW(Shdr) *shdr, struct section_mapping *out)
static const void *map_shdr(int fd, const ElfW (Shdr) *shdr, struct section_mapping *out)
{
size_t shdr_map_off = shdr->sh_offset & ~0xfffllu;
size_t shdr_map_len = shdr->sh_size + (shdr->sh_offset - shdr_map_off);
const uint8_t *shdr_map = mmap(NULL, shdr_map_len,
PROT_READ, MAP_PRIVATE, fd, shdr_map_off);
PROT_READ, MAP_PRIVATE, fd, shdr_map_off);
if (shdr_map == MAP_FAILED)
return NULL;
@ -132,14 +134,14 @@ static const void *map_shdr(int fd, const ElfW(Shdr) *shdr, struct section_mappi
static void unmap_shdr(struct section_mapping *map)
{
munmap((void*) map->map, map->len);
munmap((void *) map->map, map->len);
}
void *map_section_data(mod_handle *mod, const char *name,
struct section_mapping *map)
{
const ElfW(Shdr) *shdr = (void *) ((char *) mod->map + mod->map->e_shoff);
const ElfW(Shdr) *shstr_shdr = shdr + mod->map->e_shstrndx;
const ElfW(Shdr) * shdr = (void *) ((char *) mod->map + mod->map->e_shoff);
const ElfW(Shdr) * shstr_shdr = shdr + mod->map->e_shstrndx;
struct section_mapping shstr_map;
const char *shstr = map_shdr(mod->fd, shstr_shdr, &shstr_map);
@ -148,7 +150,7 @@ void *map_section_data(mod_handle *mod, const char *name,
for (size_t i = 0; i < mod->map->e_shnum; i++) {
const char *section_name = shstr + shdr[i].sh_name;
if (!strcmp(section_name, name)) {
const ElfW(Shdr) *hdr = shdr + i;
const ElfW(Shdr) * hdr = shdr + i;
ptr = map_shdr(mod->fd, hdr, map);
map->sec_len = hdr->sh_size;
break;
@ -156,12 +158,10 @@ void *map_section_data(mod_handle *mod, const char *name,
}
unmap_shdr(&shstr_map);
return (void *)ptr;
return (void *) ptr;
}
void unmap_section_data(struct section_mapping *map)
{
unmap_shdr(map);
}

View file

@ -36,12 +36,13 @@ typedef struct mach_header mach_hdr;
typedef struct section section;
#endif
static inline void *get_real_address(int lib, void *addr) {
static inline void *get_real_address(int lib, void *addr)
{
if (!addr)
return NULL;
// We need to slide the section address to get a valid pointer
// because ASLR will shift the image by a random offset
/* We need to slide the section address to get a valid pointer
because ASLR will shift the image by a random offset */
return addr + _dyld_get_image_vmaddr_slide(lib);
}
@ -79,7 +80,7 @@ void *map_section_data(mod_handle *mod, const char *name,
continue;
map->sec_len = s->size;
return get_real_address(*mod, (void *)(uintptr_t) s->addr);
return get_real_address(*mod, (void *) (uintptr_t) s->addr);
}
} else if (lc->cmd == LC_SEGMENT_64) {
const struct segment_command_64 *sc = (void *) lc;
@ -91,7 +92,7 @@ void *map_section_data(mod_handle *mod, const char *name,
continue;
map->sec_len = s->size;
return get_real_address(*mod, (void *)(uintptr_t) s->addr);
return get_real_address(*mod, (void *) (uintptr_t) s->addr);
}
}
}

View file

@ -43,7 +43,8 @@ void *map_section_data(mod_handle *mod, const char *name,
+ dos_hdr->e_lfanew);
PIMAGE_SECTION_HEADER sec_hdr = IMAGE_FIRST_SECTION(nt_hdr);
for(int i = 0; i < nt_hdr->FileHeader.NumberOfSections; i++, sec_hdr++) {
for (int i = 0; i < nt_hdr->FileHeader.NumberOfSections; i++, sec_hdr++) {
if (!strncmp((char *) sec_hdr->Name, name, IMAGE_SIZEOF_SHORT_NAME)) {
map->sec_len = sec_hdr->SizeOfRawData;
return (char *) dos_hdr + sec_hdr->VirtualAddress;

View file

@ -22,27 +22,27 @@
* THE SOFTWARE.
*/
#ifndef SECTION_H_
# define SECTION_H_
#define SECTION_H_
# include "config.h"
#include "config.h"
# if defined (__ELF__)
# define MODULE_INVALID NULL
# include <link.h>
#if defined (__ELF__)
# define MODULE_INVALID NULL
# include <link.h>
typedef struct mod_handle {
int fd;
const ElfW(Ehdr) *map;
const ElfW(Ehdr) * map;
size_t len;
} mod_handle;
# elif defined (__APPLE__)
# define MODULE_INVALID -1
#elif defined (__APPLE__)
# define MODULE_INVALID -1
typedef int mod_handle;
# elif defined (_WIN32)
# include <windows.h>
# define MODULE_INVALID NULL
#elif defined (_WIN32)
# include <windows.h>
# define MODULE_INVALID NULL
typedef HMODULE mod_handle;
# endif
#endif
struct section_mapping {
const void *map;

View file

@ -22,24 +22,25 @@
* THE SOFTWARE.
*/
#ifndef COMPAT_STRTOK_H_
# define COMPAT_STRTOK_H_
#define COMPAT_STRTOK_H_
# include "config.h"
#include "config.h"
# ifdef VANILLA_WIN32
# if !HAVE_STRTOK_R
# if HAVE_STRTOK_S
# define strtok_r strtok_s
# else
static CR_INLINE char *strtok_r(char *str, const char *delim, CR_UNUSED char **saveptr) {
return strtok(str, delim);
#ifdef VANILLA_WIN32
# if !HAVE_STRTOK_R
# if HAVE_STRTOK_S
# define strtok_r strtok_s
# else
static CR_INLINE char *strtok_r(char *str, const char *delim, CR_UNUSED char **saveptr)
{
return strtok(str, delim);
}
# endif
# endif
# ifdef _MSC_VER
# define strdup _strdup
# endif
# endif
# ifdef _MSC_VER
# define strdup _strdup
# endif
#endif
#endif /* !COMPAT_STRTOK_H_ */

View file

@ -26,43 +26,43 @@
#include "config.h"
#include "time.h"
#define KILO 1000ull
#define MEGA (KILO * 1000ull)
#define GIGA (MEGA * 1000ull)
#define KILO 1000ull
#define MEGA (KILO * 1000ull)
#define GIGA (MEGA * 1000ull)
#if defined(HAVE_GETTIMEOFDAY)
#if defined (HAVE_GETTIMEOFDAY)
# include <sys/time.h>
#endif
#if defined(HAVE_CLOCK_GETTIME)
#if defined (HAVE_CLOCK_GETTIME)
# include <time.h>
#endif
#if defined(__APPLE__)
#if defined (__APPLE__)
# include <mach/clock.h>
# include <mach/mach.h>
# include <pthread.h>
#endif
#if defined(_WIN32) || defined(__CYGWIN__)
#if defined (_WIN32) || defined (__CYGWIN__)
# include <windows.h>
#endif
#if defined(HAVE_CLOCK_GETTIME)
# if defined(HAVE_CLOCK_MONOTONIC_RAW)
# define CLOCK CLOCK_MONOTONIC_RAW
#if defined (HAVE_CLOCK_GETTIME)
# if defined (HAVE_CLOCK_MONOTONIC_RAW)
# define CLOCK CLOCK_MONOTONIC_RAW
# else
# define CLOCK CLOCK_MONOTONIC
# define CLOCK CLOCK_MONOTONIC
# endif
#endif
uint64_t cri_timestamp_monotonic(void)
{
#if defined(HAVE_CLOCK_GETTIME)
#if defined (HAVE_CLOCK_GETTIME)
struct timespec now;
clock_gettime(CLOCK, &now);
return now.tv_sec * GIGA + now.tv_nsec;
#elif defined(__APPLE__)
#elif defined (__APPLE__)
clock_serv_t cclock;
mach_timespec_t mts;
@ -71,10 +71,10 @@ uint64_t cri_timestamp_monotonic(void)
mach_port_deallocate(mach_task_self(), cclock);
return mts.tv_sec * GIGA + mts.tv_nsec;
#elif defined(_WIN32) || defined(__CYGWIN__)
#elif defined (_WIN32) || defined (__CYGWIN__)
LARGE_INTEGER freq, count;
if (!QueryPerformanceFrequency(&freq)
|| !QueryPerformanceCounter(&count))
|| !QueryPerformanceCounter(&count))
return -1;
uint64_t sec = count.QuadPart / freq.QuadPart;

View file

@ -22,9 +22,9 @@
* THE SOFTWARE.
*/
#ifndef TIMER_H_
# define TIMER_H_
#define TIMER_H_
# include <stdint.h>
#include <stdint.h>
uint64_t cri_timestamp_monotonic(void);

View file

@ -33,17 +33,19 @@
jmp_buf g_pre_test;
void criterion_abort_test(void) {
void criterion_abort_test(void)
{
if (criterion_options.crash)
debug_break();
longjmp(g_pre_test, 1);
}
void criterion_skip_test(const char *format, ...) {
void criterion_skip_test(const char *format, ...)
{
char *msg = NULL;
if(*format)
{
if (*format) {
va_list args;
va_start(args, format);
cr_vasprintf(&msg, format, args);
@ -51,10 +53,10 @@ void criterion_skip_test(const char *format, ...) {
}
criterion_protocol_msg skip_msg = criterion_message(phase,
.phase = criterion_protocol_phase_kind_SKIP,
.name = (char *) criterion_current_test->name,
.message = msg,
);
.phase = criterion_protocol_phase_kind_SKIP,
.name = (char *) criterion_current_test->name,
.message = msg,
);
criterion_message_set_id(skip_msg);
cr_send_to_runner(&skip_msg);
free(msg);
@ -62,13 +64,16 @@ void criterion_skip_test(const char *format, ...) {
exit(0);
}
void criterion_continue_test(void) {
void criterion_continue_test(void)
{
if (criterion_options.crash)
debug_break();
}
void criterion_test_die(const char *msg, ...) {
void criterion_test_die(const char *msg, ...)
{
va_list vl;
va_start(vl, msg);
char *formatted_msg = NULL;
int res = cr_vasprintf(&formatted_msg, msg, vl);
@ -78,10 +83,10 @@ void criterion_test_die(const char *msg, ...) {
abort();
criterion_protocol_msg abort_msg = criterion_message(phase,
.phase = criterion_protocol_phase_kind_ABORT,
.name = (char *) criterion_current_test->name,
.message = formatted_msg,
);
.phase = criterion_protocol_phase_kind_ABORT,
.name = (char *) criterion_current_test->name,
.message = formatted_msg,
);
criterion_message_set_id(abort_msg);
cr_send_to_runner(&abort_msg);

View file

@ -22,10 +22,10 @@
* THE SOFTWARE.
*/
#ifndef ABORT_H_
# define ABORT_H_
#define ABORT_H_
# include <criterion/abort.h>
# include <setjmp.h>
#include <criterion/abort.h>
#include <setjmp.h>
extern jmp_buf g_pre_test;

View file

@ -58,8 +58,8 @@ static const char *state_to_string[] = {
[CS_SKIP] = "skip",
};
typedef bool message_handler(struct server_ctx *, struct client_ctx *, const criterion_protocol_msg *);
typedef bool phase_handler(struct server_ctx *, struct client_ctx *, const criterion_protocol_phase *);
typedef bool message_handler (struct server_ctx *, struct client_ctx *, const criterion_protocol_msg *);
typedef bool phase_handler (struct server_ctx *, struct client_ctx *, const criterion_protocol_phase *);
bool handle_birth(struct server_ctx *, struct client_ctx *, const criterion_protocol_msg *);
bool handle_phase(struct server_ctx *, struct client_ctx *, const criterion_protocol_msg *);
@ -75,7 +75,8 @@ static message_handler *message_handlers[] = {
[criterion_protocol_submessage_message_tag] = handle_message,
};
static void get_message_id(char *out, size_t n, const criterion_protocol_msg *msg) {
static void get_message_id(char *out, size_t n, const criterion_protocol_msg *msg)
{
switch (msg->which_id) {
case criterion_protocol_msg_pid_tag:
snprintf(out, n, "[PID %" PRId64 "]", msg->id.pid); return;
@ -85,7 +86,8 @@ static void get_message_id(char *out, size_t n, const criterion_protocol_msg *ms
}
}
void init_server_context(struct server_ctx *sctx, struct criterion_global_stats *gstats) {
void init_server_context(struct server_ctx *sctx, struct criterion_global_stats *gstats)
{
sctx->subprocesses = kh_init(ht_client);
sctx->clients = kh_init(ht_extern);
@ -100,7 +102,8 @@ void init_server_context(struct server_ctx *sctx, struct criterion_global_stats
sctx->extern_sstats = suite_stats_init(&sctx->extern_suite);
}
void destroy_client_context(struct client_ctx *ctx) {
void destroy_client_context(struct client_ctx *ctx)
{
if (ctx->kind == WORKER) {
int rc = bxf_wait(ctx->instance, BXF_FOREVER);
if (rc < 0)
@ -113,13 +116,14 @@ void destroy_client_context(struct client_ctx *ctx) {
sfree(ctx->sstats);
}
void destroy_server_context(struct server_ctx *sctx) {
void destroy_server_context(struct server_ctx *sctx)
{
khint_t k;
struct client_ctx v;
kh_foreach(sctx->subprocesses, k, v, {
destroy_client_context(&v);
});
destroy_client_context(&v);
});
(void) k;
(void) v;
@ -137,27 +141,32 @@ struct client_ctx *add_client_from_worker(struct server_ctx *sctx,
unsigned long long pid = instance->pid;
int absent;
khint_t k = kh_put(ht_client, sctx->subprocesses, pid, &absent);
ctx->instance = instance;
ctx->kind = WORKER;
kh_value(sctx->subprocesses, k) = *ctx;
return &kh_value(sctx->subprocesses, k);
}
void remove_client_by_pid(struct server_ctx *sctx, int pid) {
void remove_client_by_pid(struct server_ctx *sctx, int pid)
{
khint_t k = kh_get(ht_client, sctx->subprocesses, pid);
if (k != kh_end(sctx->subprocesses)) {
destroy_client_context(&kh_value(sctx->subprocesses, k));
kh_del(ht_client, sctx->subprocesses, k);
}
}
struct client_ctx *add_external_client(struct server_ctx *sctx, char *id) {
struct client_ctx *add_external_client(struct server_ctx *sctx, char *id)
{
int absent;
khint_t k = kh_put(ht_extern, sctx->clients, id, &absent);
kh_value(sctx->clients, k) = (struct client_ctx) {
.kind = EXTERN,
.extern_test = {
.name = strdup(id),
.name = strdup(id),
.category = "external",
},
.gstats = sctx->gstats,
@ -173,9 +182,11 @@ struct client_ctx *add_external_client(struct server_ctx *sctx, char *id) {
return ctx;
}
static void process_client_message_impl(struct server_ctx *sctx, struct client_ctx *ctx, const criterion_protocol_msg *msg) {
static void process_client_message_impl(struct server_ctx *sctx, struct client_ctx *ctx, const criterion_protocol_msg *msg)
{
message_handler *handler = message_handlers[msg->data.which_value];
bool ack = false;
if (handler)
ack = handler(sctx, ctx, msg);
@ -183,13 +194,14 @@ static void process_client_message_impl(struct server_ctx *sctx, struct client_c
send_ack(sctx->socket, true, NULL);
}
# define handler_error(Ctx, IdFmt, Id, Fmt, ...) \
do { \
criterion_perror(IdFmt Fmt "\n", Id, __VA_ARGS__); \
send_ack((Ctx)->socket, false, Fmt, __VA_ARGS__); \
#define handler_error(Ctx, IdFmt, Id, Fmt, ...) \
do { \
criterion_perror(IdFmt Fmt "\n", Id, __VA_ARGS__); \
send_ack((Ctx)->socket, false, Fmt, __VA_ARGS__); \
} while (0)
struct client_ctx *process_client_message(struct server_ctx *ctx, const criterion_protocol_msg *msg) {
struct client_ctx *process_client_message(struct server_ctx *ctx, const criterion_protocol_msg *msg)
{
if (msg->version != PROTOCOL_V1) {
handler_error(ctx, "%s", "", "Received message using invalid protocol version number '%" PRIi32 "'.", msg->version);
return NULL;
@ -199,24 +211,22 @@ struct client_ctx *process_client_message(struct server_ctx *ctx, const criterio
switch (msg->which_id) {
case criterion_protocol_msg_pid_tag: {
khiter_t k = kh_get(ht_client, ctx->subprocesses, msg->id.pid);
if (k != kh_end(ctx->subprocesses)) {
if (k != kh_end(ctx->subprocesses))
client = &kh_value(ctx->subprocesses, k);
} else {
else
handler_error(ctx, "%s", "", "Received message identified by a PID '%" PRIi64 "' "
"that is not a child process.", msg->id.pid);
}
} break;
case criterion_protocol_msg_uid_tag: {
khiter_t k = kh_get(ht_extern, ctx->clients, msg->id.uid);
bool client_found = k != kh_end(ctx->clients);
if (!client_found && msg->data.which_value == criterion_protocol_submessage_birth_tag) {
if (!client_found && msg->data.which_value == criterion_protocol_submessage_birth_tag)
client = add_external_client(ctx, msg->id.uid);
} else if (client_found) {
else if (client_found)
client = &kh_value(ctx->clients, k);
} else {
else
handler_error(ctx, "%s", "", "Received message identified by the ID '%s'"
"that did not send a birth message previously.", msg->id.uid);
}
} break;
default: {
handler_error(ctx, "%s", "", "Received message with malformed id tag '%d'.\n",
@ -229,24 +239,25 @@ struct client_ctx *process_client_message(struct server_ctx *ctx, const criterio
return client;
}
#define push_event(...) \
do { \
push_event_noreport(__VA_ARGS__); \
report(CR_VA_HEAD(__VA_ARGS__), ctx->tstats); \
#define push_event(...) \
do { \
push_event_noreport(__VA_ARGS__); \
report(CR_VA_HEAD(__VA_ARGS__), ctx->tstats); \
} while (0)
#define push_event_noreport(...) \
do { \
stat_push_event(ctx->gstats, \
ctx->sstats, \
ctx->tstats, \
&(struct event) { \
.kind = CR_VA_HEAD(__VA_ARGS__), \
CR_VA_TAIL(__VA_ARGS__) \
}); \
#define push_event_noreport(...) \
do { \
stat_push_event(ctx->gstats, \
ctx->sstats, \
ctx->tstats, \
&(struct event) { \
.kind = CR_VA_HEAD(__VA_ARGS__), \
CR_VA_TAIL(__VA_ARGS__) \
}); \
} while (0)
bool handle_birth(struct server_ctx *sctx, struct client_ctx *ctx, const criterion_protocol_msg *msg) {
bool handle_birth(struct server_ctx *sctx, struct client_ctx *ctx, const criterion_protocol_msg *msg)
{
(void) sctx;
(void) msg;
@ -254,11 +265,12 @@ bool handle_birth(struct server_ctx *sctx, struct client_ctx *ctx, const criteri
return false;
}
bool handle_pre_init(struct server_ctx *sctx, struct client_ctx *ctx, const criterion_protocol_phase *msg) {
bool handle_pre_init(struct server_ctx *sctx, struct client_ctx *ctx, const criterion_protocol_phase *msg)
{
(void) sctx;
(void) msg;
if (ctx->state == 0) { // only pre_init if there are no nested states
if (ctx->state == 0) { /* only pre_init if there are no nested states */
push_event_noreport(PRE_INIT);
report(PRE_INIT, ctx->test);
log(pre_init, ctx->suite, ctx->test);
@ -266,7 +278,8 @@ bool handle_pre_init(struct server_ctx *sctx, struct client_ctx *ctx, const crit
return false;
}
bool handle_pre_test(struct server_ctx *sctx, struct client_ctx *ctx, const criterion_protocol_phase *msg) {
bool handle_pre_test(struct server_ctx *sctx, struct client_ctx *ctx, const criterion_protocol_phase *msg)
{
(void) sctx;
(void) msg;
@ -278,12 +291,13 @@ bool handle_pre_test(struct server_ctx *sctx, struct client_ctx *ctx, const crit
return false;
}
bool handle_post_test(struct server_ctx *sctx, struct client_ctx *ctx, const criterion_protocol_phase *msg) {
bool handle_post_test(struct server_ctx *sctx, struct client_ctx *ctx, const criterion_protocol_phase *msg)
{
(void) sctx;
(void) msg;
if (ctx->state < CS_MAX_CLIENT_STATES) {
double elapsed_time = 0; // TODO: restore elapsed time handling
double elapsed_time = 0; /* TODO: restore elapsed time handling */
push_event_noreport(POST_TEST, .data = &elapsed_time);
report(POST_TEST, ctx->tstats);
log(post_test, ctx->tstats);
@ -291,7 +305,8 @@ bool handle_post_test(struct server_ctx *sctx, struct client_ctx *ctx, const cri
return false;
}
bool handle_post_fini(struct server_ctx *sctx, struct client_ctx *ctx, const criterion_protocol_phase *msg) {
bool handle_post_fini(struct server_ctx *sctx, struct client_ctx *ctx, const criterion_protocol_phase *msg)
{
(void) sctx;
(void) ctx;
(void) msg;
@ -302,7 +317,8 @@ bool handle_post_fini(struct server_ctx *sctx, struct client_ctx *ctx, const cri
return false;
}
bool handle_abort(struct server_ctx *sctx, struct client_ctx *ctx, const criterion_protocol_phase *msg) {
bool handle_abort(struct server_ctx *sctx, struct client_ctx *ctx, const criterion_protocol_phase *msg)
{
(void) sctx;
(void) ctx;
(void) msg;
@ -325,7 +341,7 @@ bool handle_abort(struct server_ctx *sctx, struct client_ctx *ctx, const criteri
} else {
struct criterion_theory_stats ths = {
.formatted_args = strdup(msg->message),
.stats = ctx->tstats,
.stats = ctx->tstats,
};
report(THEORY_FAIL, &ths);
log(theory_fail, &ths);
@ -333,7 +349,8 @@ bool handle_abort(struct server_ctx *sctx, struct client_ctx *ctx, const criteri
return false;
}
bool handle_timeout(struct server_ctx *sctx, struct client_ctx *ctx, const criterion_protocol_phase *msg) {
bool handle_timeout(struct server_ctx *sctx, struct client_ctx *ctx, const criterion_protocol_phase *msg)
{
(void) sctx;
(void) msg;
@ -347,7 +364,8 @@ bool handle_timeout(struct server_ctx *sctx, struct client_ctx *ctx, const crite
return false;
}
bool handle_skip(struct server_ctx *sctx, struct client_ctx *ctx, const criterion_protocol_phase *msg) {
bool handle_skip(struct server_ctx *sctx, struct client_ctx *ctx, const criterion_protocol_phase *msg)
{
(void) sctx;
(void) msg;
@ -361,9 +379,10 @@ bool handle_skip(struct server_ctx *sctx, struct client_ctx *ctx, const criterio
}
return false;
}
# define MAX_TEST_DEPTH 16
#define MAX_TEST_DEPTH 16
bool handle_phase(struct server_ctx *sctx, struct client_ctx *ctx, const criterion_protocol_msg *msg) {
bool handle_phase(struct server_ctx *sctx, struct client_ctx *ctx, const criterion_protocol_msg *msg)
{
const criterion_protocol_phase *phase_msg = &msg->data.value.phase;
enum client_state new_state = phase_to_state[phase_msg->phase];
@ -414,11 +433,11 @@ bool handle_phase(struct server_ctx *sctx, struct client_ctx *ctx, const criteri
if (new_state >= CS_END) {
if ((ctx->state >> 2) != 0)
ctx->state >>= 2; // pop the current state
ctx->state >>= 2; /* pop the current state */
else
ctx->state = CS_END;
} else if (new_state == CS_SETUP) {
ctx->state <<= 2; // shift the state to make space for a new state
ctx->state <<= 2; /* shift the state to make space for a new state */
} else {
++ctx->state;
}
@ -426,7 +445,8 @@ bool handle_phase(struct server_ctx *sctx, struct client_ctx *ctx, const criteri
return ack;
}
bool handle_death(struct server_ctx *sctx, struct client_ctx *ctx, const criterion_protocol_msg *msg) {
bool handle_death(struct server_ctx *sctx, struct client_ctx *ctx, const criterion_protocol_msg *msg)
{
(void) sctx;
ctx->alive = false;
@ -483,16 +503,17 @@ bool handle_death(struct server_ctx *sctx, struct client_ctx *ctx, const criteri
return false;
}
bool handle_assert(struct server_ctx *sctx, struct client_ctx *ctx, const criterion_protocol_msg *msg) {
bool handle_assert(struct server_ctx *sctx, struct client_ctx *ctx, const criterion_protocol_msg *msg)
{
(void) sctx;
(void) ctx;
(void) msg;
const criterion_protocol_assert *asrt = &msg->data.value.assert;
struct criterion_assert_stats asrt_stats = {
.message = asrt->message,
.passed = asrt->passed,
.line = asrt->has_line ? asrt->line : 0,
.file = asrt->file ? asrt->file : "unknown",
.passed = asrt->passed,
.line = asrt->has_line ? asrt->line : 0,
.file = asrt->file ? asrt->file : "unknown",
};
push_event_noreport(ASSERT, .data = &asrt_stats);
@ -501,7 +522,8 @@ bool handle_assert(struct server_ctx *sctx, struct client_ctx *ctx, const criter
return false;
}
bool handle_message(struct server_ctx *sctx, struct client_ctx *ctx, const criterion_protocol_msg *msg) {
bool handle_message(struct server_ctx *sctx, struct client_ctx *ctx, const criterion_protocol_msg *msg)
{
(void) sctx;
(void) ctx;
const criterion_protocol_log *lg = &msg->data.value.message;

View file

@ -22,27 +22,27 @@
* THE SOFTWARE.
*/
#ifndef CLIENT_H_
# define CLIENT_H_
#define CLIENT_H_
# include <khash.h>
# include <boxfort.h>
#include <khash.h>
#include <boxfort.h>
// order matters here
/* order matters here */
enum client_state {
CS_SETUP,
CS_MAIN,
CS_TEARDOWN,
CS_END,
// The states belows are non-states that should not be
// added in the state count
/* The states belows are non-states that should not be
added in the state count */
CS_ABORT,
CS_TIMEOUT,
CS_SKIP,
};
// always make it a power of 2
# define CS_MAX_CLIENT_STATES 4
/* always make it a power of 2 */
#define CS_MAX_CLIENT_STATES 4
enum client_kind {
WORKER,

View file

@ -27,58 +27,63 @@
#include <csptr/smalloc.h>
#include "common.h"
static void destroy_ordered_set(void *ptr, CR_UNUSED void *meta) {
static void destroy_ordered_set(void *ptr, CR_UNUSED void *meta)
{
sfree(((struct criterion_ordered_set *) ptr)->first);
}
static CR_INLINE void nothing(CR_UNUSED void *ptr, CR_UNUSED void *meta) {}
static void destroy_ordered_set_node(void *ptr, void *meta) {
static void destroy_ordered_set_node(void *ptr, void *meta)
{
struct criterion_ordered_set *set = *(void **) meta;
struct criterion_ordered_set_node *n = ptr;
DEF(set->dtor, nothing)(n + 1, NULL);
sfree(((struct criterion_ordered_set_node *) ptr)->next);
}
struct criterion_ordered_set *new_ordered_set(f_criterion_cmp cmp,
f_destructor dtor) {
f_destructor dtor)
{
struct criterion_ordered_set *newset = smalloc(
.size = sizeof (struct criterion_ordered_set),
.dtor = destroy_ordered_set
.size = sizeof (struct criterion_ordered_set),
.dtor = destroy_ordered_set
);
struct criterion_ordered_set data = { .cmp = cmp, .dtor = dtor };
memcpy(newset, &data, sizeof (struct criterion_ordered_set));
return newset;
}
void *insert_ordered_set(struct criterion_ordered_set *l,
void *ptr,
size_t size) {
void *ptr,
size_t size)
{
int cmp;
struct criterion_ordered_set_node *n, *prev = NULL;
for (n = l->first; n && (cmp = l->cmp(ptr, n + 1)) > 0; n = n->next)
prev = n;
if (n && !cmp) // element already exists
if (n && !cmp) /* element already exists */
return n + 1;
struct criterion_ordered_set_node *new = smalloc(
.size = sizeof(struct criterion_ordered_set_node) + size,
.dtor = destroy_ordered_set_node,
.meta = { &l, sizeof (void *) },
.size = sizeof (struct criterion_ordered_set_node) + size,
.dtor = destroy_ordered_set_node,
.meta = { &l, sizeof (void *) },
);
if (!new)
return NULL;
memcpy(new + 1, ptr, size);
new->next = n;
if (prev) {
if (prev)
prev->next = new;
} else {
else
l->first = new;
}
++l->size;
return new + 1;

View file

@ -33,22 +33,22 @@
#include "config.h"
#include "compat/posix.h"
#define CR_HSEC_STR(Kind) CR_HSEC_STR_(CR_HOOK_SECTION(Kind))
#define CR_HSEC_STR_(S) CR_HSEC_STR__(S)
#define CR_HSEC_STR__(S) #S
#define CR_HSEC_STR(Kind) CR_HSEC_STR_(CR_HOOK_SECTION(Kind))
#define CR_HSEC_STR_(S) CR_HSEC_STR__(S)
#define CR_HSEC_STR__(S) #S
#define IMPL_CALL_REPORT_HOOKS(Kind) \
void call_report_hooks_##Kind(void *data) { \
mod_handle self; \
struct section_mapping sect; \
if (!open_module_self(&self)) \
abort(); \
void *start = map_section_data(&self, CR_HSEC_STR(Kind), &sect); \
if (!start) \
return; \
void *end = (char *)start + sect.sec_len; \
for (f_report_hook *hook = start; hook < (f_report_hook*) end; ++hook) \
(*hook ? *hook : nothing)(data); \
#define IMPL_CALL_REPORT_HOOKS(Kind) \
void call_report_hooks_ ## Kind(void *data) { \
mod_handle self; \
struct section_mapping sect; \
if (!open_module_self(&self)) \
abort(); \
void *start = map_section_data(&self, CR_HSEC_STR(Kind), &sect); \
if (!start) \
return; \
void *end = (char *) start + sect.sec_len; \
for (f_report_hook *hook = start; hook < (f_report_hook *) end; ++hook) \
(*hook ? *hook : nothing)(data); \
}
IMPL_CALL_REPORT_HOOKS(PRE_ALL)
@ -63,15 +63,25 @@ IMPL_CALL_REPORT_HOOKS(POST_FINI)
IMPL_CALL_REPORT_HOOKS(POST_SUITE)
IMPL_CALL_REPORT_HOOKS(POST_ALL)
ReportHook(PRE_ALL)(CR_UNUSED struct criterion_test_set *arg) {}
ReportHook(PRE_SUITE)(CR_UNUSED struct criterion_suite_set *arg) {}
ReportHook(PRE_INIT)(CR_UNUSED struct criterion_test *arg) {}
ReportHook(PRE_TEST)(CR_UNUSED struct criterion_test *arg) {}
ReportHook(ASSERT)(CR_UNUSED struct criterion_assert_stats *arg) {}
ReportHook(THEORY_FAIL)(CR_UNUSED struct criterion_theory_stats *arg) {}
ReportHook(TEST_CRASH)(CR_UNUSED struct criterion_test_stats *arg) {}
ReportHook(POST_TEST)(CR_UNUSED struct criterion_test_stats *arg) {}
ReportHook(POST_FINI)(CR_UNUSED struct criterion_test_stats *arg) {}
ReportHook(POST_SUITE)(CR_UNUSED struct criterion_suite_stats *arg) {}
ReportHook(POST_ALL)(CR_UNUSED struct criterion_global_stats *arg) {}
ReportHook(PRE_ALL)(CR_UNUSED struct criterion_test_set *arg) {
}
ReportHook(PRE_SUITE)(CR_UNUSED struct criterion_suite_set *arg) {
}
ReportHook(PRE_INIT)(CR_UNUSED struct criterion_test *arg) {
}
ReportHook(PRE_TEST)(CR_UNUSED struct criterion_test *arg) {
}
ReportHook(ASSERT)(CR_UNUSED struct criterion_assert_stats *arg) {
}
ReportHook(THEORY_FAIL)(CR_UNUSED struct criterion_theory_stats *arg) {
}
ReportHook(TEST_CRASH)(CR_UNUSED struct criterion_test_stats *arg) {
}
ReportHook(POST_TEST)(CR_UNUSED struct criterion_test_stats *arg) {
}
ReportHook(POST_FINI)(CR_UNUSED struct criterion_test_stats *arg) {
}
ReportHook(POST_SUITE)(CR_UNUSED struct criterion_suite_stats *arg) {
}
ReportHook(POST_ALL)(CR_UNUSED struct criterion_global_stats *arg) {
}

View file

@ -22,16 +22,16 @@
* THE SOFTWARE.
*/
#ifndef REPORT_H_
# define REPORT_H_
#define REPORT_H_
# include "criterion/hooks.h"
# include "criterion/options.h"
#include "criterion/hooks.h"
#include "criterion/options.h"
# define report(Kind, Data) report_(Kind, Data)
# define report_(Kind, Data) call_report_hooks_##Kind(Data)
#define report(Kind, Data) report_(Kind, Data)
#define report_(Kind, Data) call_report_hooks_ ## Kind(Data)
# define DECL_CALL_REPORT_HOOKS(Kind) \
void call_report_hooks_##Kind(void *data)
#define DECL_CALL_REPORT_HOOKS(Kind) \
void call_report_hooks_ ## Kind(void *data)
DECL_CALL_REPORT_HOOKS(PRE_ALL);
DECL_CALL_REPORT_HOOKS(PRE_SUITE);

View file

@ -59,65 +59,70 @@
# include <valgrind/valgrind.h>
#else
# define ENABLE_VALGRIND_ERRORS
# define RUNNING_ON_VALGRIND 0
# define RUNNING_ON_VALGRIND 0
#endif
typedef const char *const msg_t;
#ifdef ENABLE_NLS
static msg_t msg_valgrind_jobs = N_("%1$sWarning! Criterion has detected "
"that it is running under valgrind, but the number of jobs have been "
"explicitely set. Reports might appear confusing!%2$s\n");
"that it is running under valgrind, but the number of jobs have been "
"explicitely set. Reports might appear confusing!%2$s\n");
#else
static msg_t msg_valgrind_jobs = "%sWarning! Criterion has detected "
"that it is running under valgrind, but the number of jobs have been "
"explicitely set. Reports might appear confusing!%s\n";
#endif
// This is here to make the test suite & test sections non-empty
/* This is here to make the test suite & test sections non-empty */
CR_SECTION_("cr_sts") struct criterion_suite *dummy_suite = NULL;
CR_SECTION_("cr_tst") struct criterion_test *dummy_test = NULL;
CR_SECTION_("cr_tst") struct criterion_test *dummy_test = NULL;
static int cmp_suite(void *a, void *b)
{
struct criterion_suite *s1 = a, *s2 = b;
return strcmp(s1->name, s2->name);
}
static int cmp_test(void *a, void *b)
{
struct criterion_test *s1 = a, *s2 = b;
return strcmp(s1->name, s2->name);
}
static void dtor_suite_set(void *ptr, CR_UNUSED void *meta)
{
struct criterion_suite_set *s = ptr;
sfree(s->tests);
}
static void dtor_test_set(void *ptr, CR_UNUSED void *meta)
{
struct criterion_test_set *t = ptr;
sfree(t->suites);
}
CR_API void criterion_register_test(struct criterion_test_set *set,
struct criterion_test *test)
{
struct criterion_suite_set css = {
.suite = { .name = test->category },
};
struct criterion_suite_set *s = insert_ordered_set(set->suites, &css, sizeof (css));
if (!s->tests)
s->tests = new_ordered_set(cmp_test, NULL);
insert_ordered_set(s->tests, test, sizeof(*test));
insert_ordered_set(s->tests, test, sizeof (*test));
++set->tests;
}
struct criterion_test_set *criterion_init(void) {
struct criterion_test_set *criterion_init(void)
{
struct criterion_ordered_set *suites = new_ordered_set(cmp_suite, dtor_suite_set);
mod_handle self;
@ -140,8 +145,8 @@ struct criterion_test_set *criterion_init(void) {
}
struct criterion_test_set *set = smalloc(
.size = sizeof (struct criterion_test_set),
.dtor = dtor_test_set
.size = sizeof (struct criterion_test_set),
.dtor = dtor_test_set
);
*set = (struct criterion_test_set) {
@ -166,37 +171,38 @@ struct criterion_test_set *criterion_init(void) {
return set;
}
#define push_event(...) \
do { \
stat_push_event(ctx->stats, \
ctx->suite_stats, \
ctx->test_stats, \
&(struct event) { \
.kind = CR_VA_HEAD(__VA_ARGS__), \
CR_VA_TAIL(__VA_ARGS__) \
}); \
report(CR_VA_HEAD(__VA_ARGS__), ctx->test_stats); \
#define push_event(...) \
do { \
stat_push_event(ctx->stats, \
ctx->suite_stats, \
ctx->test_stats, \
&(struct event) { \
.kind = CR_VA_HEAD(__VA_ARGS__), \
CR_VA_TAIL(__VA_ARGS__) \
}); \
report(CR_VA_HEAD(__VA_ARGS__), ctx->test_stats); \
} while (0)
void disable_unmatching(struct criterion_test_set *set) {
if (!compile_pattern(criterion_options.pattern)) {
void disable_unmatching(struct criterion_test_set *set)
{
if (!compile_pattern(criterion_options.pattern))
exit(3);
}
FOREACH_SET(struct criterion_suite_set *s, set->suites) {
if ((s->suite.data && s->suite.data->disabled) || !s->tests)
continue;
FOREACH_SET(struct criterion_test *test, s->tests) {
int ret = match(test->data->identifier_);
if (ret == 0) {
if (ret == 0)
test->data->disabled = true;
}
}
}
free_pattern();
}
CR_API struct criterion_test_set *criterion_initialize(void) {
CR_API struct criterion_test_set *criterion_initialize(void)
{
init_i18n();
#ifndef ENABLE_VALGRIND_ERRORS
@ -216,7 +222,8 @@ CR_API struct criterion_test_set *criterion_initialize(void) {
return criterion_init();
}
CR_API void criterion_finalize(struct criterion_test_set *set) {
CR_API void criterion_finalize(struct criterion_test_set *set)
{
sfree(set);
#ifndef ENABLE_VALGRIND_ERRORS
@ -226,10 +233,12 @@ CR_API void criterion_finalize(struct criterion_test_set *set) {
criterion_free_output();
}
static struct client_ctx *spawn_next_client(struct server_ctx *sctx, ccrContext *ctx) {
static struct client_ctx *spawn_next_client(struct server_ctx *sctx, ccrContext *ctx)
{
struct client_ctx new_ctx;
bxf_instance *instance = cri_run_next_test(NULL, NULL, NULL, &new_ctx, ctx);
if (!instance)
return NULL;
@ -237,9 +246,9 @@ static struct client_ctx *spawn_next_client(struct server_ctx *sctx, ccrContext
}
static void run_tests_async(struct criterion_test_set *set,
struct criterion_global_stats *stats,
const char *url,
int socket)
struct criterion_global_stats *stats,
const char *url,
int socket)
{
ccrContext ctx = 0;
@ -248,11 +257,12 @@ static void run_tests_async(struct criterion_test_set *set,
int has_msg = 0;
struct server_ctx sctx;
init_server_context(&sctx, stats);
sctx.socket = socket;
// initialization of coroutine
/* initialization of coroutine */
cri_run_next_test(set, stats, url, NULL, &ctx);
for (size_t i = 0; i < nb_workers; ++i) {
@ -270,14 +280,13 @@ static void run_tests_async(struct criterion_test_set *set,
while ((has_msg = read_message(socket, &msg)) == 1) {
struct client_ctx *cctx = process_client_message(&sctx, &msg);
// drop invalid messages
/* drop invalid messages */
if (!cctx)
continue;
if (!cctx->alive) {
if ((cctx->tstats->test_status == CR_STATUS_FAILED) && criterion_options.fail_fast) {
if ((cctx->tstats->test_status == CR_STATUS_FAILED) && criterion_options.fail_fast)
cr_terminate(cctx->gstats);
}
if (cctx->kind == WORKER) {
remove_client_by_pid(&sctx, cctx->instance->pid);
@ -348,9 +357,8 @@ CR_API int criterion_run_all_tests(struct criterion_test_set *set)
VALGRIND_DISABLE_ERROR_REPORTING;
#endif
if (criterion_options.pattern) {
if (criterion_options.pattern)
disable_unmatching(set);
}
if (criterion_options.debug) {
criterion_options.jobs = 1;

View file

@ -22,21 +22,21 @@
* THE SOFTWARE.
*/
#ifndef CRITERION_RUNNER_H_
# define CRITERION_RUNNER_H_
#define CRITERION_RUNNER_H_
# include "criterion/types.h"
# include "compat/pipe.h"
#include "criterion/types.h"
#include "compat/pipe.h"
struct criterion_test_set *criterion_init(void);
# define FOREACH_TEST_SEC(Test, Start, End) \
for (struct criterion_test **Test = Start; \
Test < (struct criterion_test**) End; \
#define FOREACH_TEST_SEC(Test, Start, End) \
for (struct criterion_test **Test = Start; \
Test < (struct criterion_test **) End; \
++Test)
# define FOREACH_SUITE_SEC(Suite, Start, End) \
for (struct criterion_suite **Suite = Start; \
Suite < (struct criterion_suite**) End; \
#define FOREACH_SUITE_SEC(Suite, Start, End) \
for (struct criterion_suite **Suite = Start; \
Suite < (struct criterion_suite **) End; \
++Suite)
#endif /* !CRITERION_RUNNER_H_ */

View file

@ -47,7 +47,7 @@
# include <valgrind/valgrind.h>
#else
# define ENABLE_VALGRIND_ERRORS
# define RUNNING_ON_VALGRIND 0
# define RUNNING_ON_VALGRIND 0
#endif
/* *INDENT-OFF* - This is a structure definition in disguise */
@ -69,7 +69,7 @@ ccrBeginDefineContextType(run_next_context);
ccrEndDefineContextType;
/* *INDENT-ON* */
CR_API const struct criterion_test *criterion_current_test;
CR_API const struct criterion_test *criterion_current_test;
CR_API const struct criterion_suite *criterion_current_suite;
static int serialize_test(bxf_context ctx, struct criterion_test *test,
@ -79,36 +79,36 @@ static int serialize_test(bxf_context ctx, struct criterion_test *test,
if (!rc)
rc = bxf_context_addobject(ctx, "criterion.test.name",
test->name, strlen(test->name) + 1);
test->name, strlen(test->name) + 1);
if (!rc)
rc = bxf_context_addobject(ctx, "criterion.test.suite",
test->category, strlen(test->category) + 1);
test->category, strlen(test->category) + 1);
if (!rc && test->test)
rc = bxf_context_addfnaddr(ctx, "criterion.test.test",
test->test);
test->test);
if (!rc)
rc = bxf_context_addobject(ctx, "criterion.test.extra",
test->data, sizeof (*test->data));
test->data, sizeof (*test->data));
if (!rc && test->data->init)
rc = bxf_context_addfnaddr(ctx, "criterion.test.extra.init",
test->data->init);
test->data->init);
if (!rc && test->data->fini)
rc = bxf_context_addfnaddr(ctx, "criterion.test.extra.fini",
test->data->fini);
test->data->fini);
if (!rc)
rc = bxf_context_addobject(ctx, "criterion.suite.name",
suite->name, strlen(suite->name) + 1);
suite->name, strlen(suite->name) + 1);
if (suite->data) {
if (!rc)
rc = bxf_context_addobject(ctx, "criterion.suite.extra",
suite->data, sizeof (*suite->data));
suite->data, sizeof (*suite->data));
if (!rc && suite->data->init)
rc = bxf_context_addfnaddr(ctx, "criterion.suite.extra.init",
suite->data->init);
suite->data->init);
if (!rc && suite->data->fini)
rc = bxf_context_addfnaddr(ctx, "criterion.suite.extra.fini",
suite->data->fini);
suite->data->fini);
}
return rc;
}
@ -124,44 +124,44 @@ static int deserialize_test(struct criterion_test *test,
int rc;
rc = bxf_context_getobject(ctx, "criterion.test.name",
(void **)&test->name);
(void **) &test->name);
if (rc <= 0) goto err;
rc = bxf_context_getobject(ctx, "criterion.test.suite",
(void **)&test->category);
(void **) &test->category);
if (rc <= 0) goto err;
rc = bxf_context_getfnaddr(ctx, "criterion.test.test",
&test->test);
&test->test);
if (rc < 0) goto err;
rc = bxf_context_getobject(ctx, "criterion.test.extra",
(void **)&test_data);
(void **) &test_data);
if (rc <= 0) goto err;
rc = bxf_context_getfnaddr(ctx, "criterion.test.extra.init",
&test_data->init);
&test_data->init);
if (rc < 0) goto err;
rc = bxf_context_getfnaddr(ctx, "criterion.test.extra.fini",
&test_data->fini);
&test_data->fini);
if (rc < 0) goto err;
rc = bxf_context_getobject(ctx, "criterion.suite.name",
(void **)&suite->name);
(void **) &suite->name);
if (rc <= 0) goto err;
rc = bxf_context_getobject(ctx, "criterion.suite.extra",
(void **)&suite_data);
(void **) &suite_data);
if (rc < 0) goto err;
if (suite_data) {
rc = bxf_context_getfnaddr(ctx, "criterion.suite.extra.init",
&suite_data->init);
&suite_data->init);
if (rc < 0) goto err;
rc = bxf_context_getfnaddr(ctx, "criterion.suite.extra.fini",
&suite_data->fini);
&suite_data->fini);
if (rc < 0) goto err;
}
@ -175,7 +175,6 @@ err:
static int run_test_child(void)
{
#ifndef ENABLE_VALGRIND_ERRORS
VALGRIND_DISABLE_ERROR_REPORTING;
#endif
@ -191,7 +190,7 @@ static int run_test_child(void)
int rc = deserialize_test(&test, &suite);
if (rc > 0)
rc = bxf_context_getobject(ctx, "criterion.url", (void **)&url);
rc = bxf_context_getobject(ctx, "criterion.url", (void **) &url);
if (rc < 0)
cr_panic("Could not get the test context: %s", strerror(-rc));
else if (!rc)
@ -203,7 +202,7 @@ static int run_test_child(void)
if (g_client_socket < 0)
cr_panic("could not initialize the message client: %s", strerror(errno));
// Notify the runner that the test was born
/* Notify the runner that the test was born */
criterion_protocol_msg msg = criterion_message(birth, .name = (char *) test.name);
criterion_message_set_id(msg);
cr_send_to_runner(&msg);
@ -233,16 +232,16 @@ static int run_test_child(void)
static void death_callback(bxf_instance *instance)
{
int result = instance->status.signal
? criterion_protocol_death_result_type_CRASH
: criterion_protocol_death_result_type_NORMAL;
? criterion_protocol_death_result_type_CRASH
: criterion_protocol_death_result_type_NORMAL;
int code = instance->status.signal
? instance->status.signal
: instance->status.exit;
? instance->status.signal
: instance->status.exit;
if (instance->status.timed_out) {
criterion_protocol_msg msg = criterion_message(phase,
.phase = criterion_protocol_phase_kind_TIMEOUT,
);
.phase = criterion_protocol_phase_kind_TIMEOUT,
);
msg.id.pid = instance->pid;
cr_send_to_runner(&msg);
@ -252,10 +251,10 @@ static void death_callback(bxf_instance *instance)
}
criterion_protocol_msg msg = criterion_message(death,
.result = result,
.has_status = true,
.status = code,
);
.result = result,
.has_status = true,
.status = code,
);
msg.id.pid = instance->pid;
cr_send_to_runner(&msg);
@ -276,7 +275,7 @@ static bxf_instance *run_test(struct run_next_context *ctx,
if (!rc && ctx->params.params) {
void *param = (char *) ctx->params.params + ctx->i * ctx->params.size;
rc = bxf_context_addobject(inst_ctx, "criterion.param",
param, ctx->params.size);
param, ctx->params.size);
}
if (!rc)
@ -286,8 +285,8 @@ static bxf_instance *run_test(struct run_next_context *ctx,
cr_panic("Could not initialize test context: %s", strerror(-rc));
struct bxf_spawn_params sp = {
.fn = run_test_child,
.callback = death_callback,
.fn = run_test_child,
.callback = death_callback,
.inherit.context = inst_ctx,
};
@ -301,11 +300,11 @@ static bxf_instance *run_test(struct run_next_context *ctx,
default: break;
}
} else {
debugger = (enum bxf_debugger)(criterion_options.debug - 1);
debugger = (enum bxf_debugger) (criterion_options.debug - 1);
}
if (!debugger)
cr_panic("Could not choose the debugger server for an "
"unknown compiler");
"unknown compiler");
sp.debug.debugger = debugger;
sp.debug.tcp = criterion_options.debug_port;
}
@ -341,11 +340,9 @@ static bxf_instance *run_test(struct run_next_context *ctx,
static CR_INLINE bool is_disabled(struct criterion_test *t,
struct criterion_suite *s)
{
return t->data->disabled || (s->data && s->data->disabled);
}
static int skip_disabled(struct run_next_context *ctx)
{
if (is_disabled(ctx->test, ctx->suite_stats->suite)) {
@ -381,7 +378,7 @@ bxf_instance *cri_run_next_test(struct criterion_test_set *p_set,
} while (ctx->set == NULL && ctx->stats == NULL);
for (ctx->ns = ctx->set->suites->first; ctx->ns; ctx->ns = ctx->ns->next) {
ctx->suite_set = (void*) (ctx->ns + 1);
ctx->suite_set = (void *) (ctx->ns + 1);
if (!ctx->suite_set->tests)
continue;
@ -394,14 +391,13 @@ bxf_instance *cri_run_next_test(struct criterion_test_set *p_set,
stat_push_event(ctx->stats, ctx->suite_stats, NULL, &(struct event) { .kind = PRE_SUITE });
for (ctx->nt = ctx->suite_set->tests->first; ctx->nt; ctx->nt = ctx->nt->next) {
ctx->test = (void*) (ctx->nt + 1);
ctx->test = (void *) (ctx->nt + 1);
if (skip_disabled(ctx))
continue;
if (ctx->test->data->kind_ == CR_TEST_PARAMETERIZED
&& ctx->test->data->param_) {
ctx->params = ctx->test->data->param_();
for (ctx->i = 0; ctx->i < ctx->params.length; ++ctx->i)
ccrReturn(run_test(ctx, client));

View file

@ -22,10 +22,10 @@
* THE SOFTWARE.
*/
#ifndef RUNNER_COROUTINE_H_
# define RUNNER_COROUTINE_H_
#define RUNNER_COROUTINE_H_
# include <boxfort.h>
# include "coroutine.h"
#include <boxfort.h>
#include "coroutine.h"
bxf_instance *cri_run_next_test(struct criterion_test_set *p_set,
struct criterion_global_stats *p_stats,

View file

@ -30,98 +30,113 @@
#include <assert.h>
typedef struct criterion_global_stats s_glob_stats;
typedef struct criterion_suite_stats s_suite_stats;
typedef struct criterion_test_stats s_test_stats;
typedef struct criterion_suite_stats s_suite_stats;
typedef struct criterion_test_stats s_test_stats;
typedef struct criterion_assert_stats s_assert_stats;
static void push_pre_suite(s_glob_stats *stats,
s_suite_stats *sstats,
s_test_stats *tstats,
void *data);
s_suite_stats *sstats,
s_test_stats *tstats,
void *data);
static void push_pre_init(s_glob_stats *stats,
s_suite_stats *sstats,
s_test_stats *tstats,
void *data);
s_suite_stats *sstats,
s_test_stats *tstats,
void *data);
static void push_assert(s_glob_stats *stats,
s_suite_stats *sstats,
s_test_stats *tstats,
void *data);
s_suite_stats *sstats,
s_test_stats *tstats,
void *data);
static void push_post_test(s_glob_stats *stats,
s_suite_stats *sstats,
s_test_stats *tstats,
void *data);
s_suite_stats *sstats,
s_test_stats *tstats,
void *data);
static void push_test_crash(s_glob_stats *stats,
s_suite_stats *sstats,
s_test_stats *tstats,
void *data);
s_suite_stats *sstats,
s_test_stats *tstats,
void *data);
static void nothing(CR_UNUSED s_glob_stats *stats,
CR_UNUSED s_suite_stats *sstats,
CR_UNUSED s_test_stats *tstats,
CR_UNUSED void *data) {
CR_UNUSED s_suite_stats *sstats,
CR_UNUSED s_test_stats *tstats,
CR_UNUSED void *data)
{
}
static void destroy_stats(void *ptr, CR_UNUSED void *meta) {
static void destroy_stats(void *ptr, CR_UNUSED void *meta)
{
s_glob_stats *stats = ptr;
for (s_suite_stats *s = stats->suites, *next; s; s = next) {
next = s->next;
sfree(s);
}
}
s_glob_stats *stats_init(void) {
s_glob_stats *stats_init(void)
{
s_glob_stats *stats = smalloc(
.size = sizeof (s_glob_stats),
.kind = SHARED,
.dtor = destroy_stats
.size = sizeof (s_glob_stats),
.kind = SHARED,
.dtor = destroy_stats
);
*stats = (s_glob_stats) { .suites = NULL };
return stats;
}
static void destroy_suite_stats(void *ptr, CR_UNUSED void *meta) {
static void destroy_suite_stats(void *ptr, CR_UNUSED void *meta)
{
s_suite_stats *stats = ptr;
for (s_test_stats *t = stats->tests, *next; t; t = next) {
next = t->next;
sfree(t);
}
}
s_suite_stats *suite_stats_init(struct criterion_suite *s) {
s_suite_stats *suite_stats_init(struct criterion_suite *s)
{
s_suite_stats *stats = smalloc(
.size = sizeof (s_suite_stats),
.kind = SHARED,
.dtor = destroy_suite_stats
.size = sizeof (s_suite_stats),
.kind = SHARED,
.dtor = destroy_suite_stats
);
*stats = (s_suite_stats) { .suite = s };
return stats;
}
static void destroy_test_stats(void *ptr, CR_UNUSED void *meta) {
static void destroy_test_stats(void *ptr, CR_UNUSED void *meta)
{
s_test_stats *stats = ptr;
for (s_assert_stats *a = stats->asserts, *next; a; a = next) {
next = a->next;
sfree(a);
}
free((void*)stats->message);
free((void *) stats->message);
}
static void destroy_assert_stats(void *ptr, CR_UNUSED void *meta) {
static void destroy_assert_stats(void *ptr, CR_UNUSED void *meta)
{
s_assert_stats *stats = ptr;
free((void *) stats->message);
free((void *) stats->file);
}
s_test_stats *test_stats_init(struct criterion_test *t) {
s_test_stats *test_stats_init(struct criterion_test *t)
{
s_test_stats *stats = smalloc(
.size = sizeof (s_test_stats),
.kind = SHARED,
.dtor = destroy_test_stats
.size = sizeof (s_test_stats),
.kind = SHARED,
.dtor = destroy_test_stats
);
*stats = (s_test_stats) {
.test = t,
.progress = t->data->line_,
.file = t->data->file_
.test = t,
.progress = t->data->line_,
.file = t->data->file_
};
return stats;
}
@ -129,21 +144,22 @@ s_test_stats *test_stats_init(struct criterion_test *t) {
typedef void (*f_handle)(s_glob_stats *, s_suite_stats *, s_test_stats *, void *);
void stat_push_event(s_glob_stats *stats,
s_suite_stats *suite,
s_test_stats *test,
struct event *data) {
s_suite_stats *suite,
s_test_stats *test,
struct event *data)
{
static const f_handle handles[] = {
nothing, // PRE_ALL
push_pre_suite, // PRE_SUITE
push_pre_init, // PRE_INIT
nothing, // PRE_TEST
push_assert, // ASSERT
nothing, // THEORY_FAIL
push_test_crash, // TEST_CRASH
push_post_test, // POST_TEST
nothing, // POST_FINI
nothing, // PRE_SUITE
nothing, // POST_ALL
nothing, /* PRE_ALL */
push_pre_suite, /* PRE_SUITE */
push_pre_init, /* PRE_INIT */
nothing, /* PRE_TEST */
push_assert, /* ASSERT */
nothing, /* THEORY_FAIL */
push_test_crash, /* TEST_CRASH */
push_post_test, /* POST_TEST */
nothing, /* POST_FINI */
nothing, /* PRE_SUITE */
nothing, /* POST_ALL */
};
assert(data->kind > 0);
@ -153,19 +169,20 @@ void stat_push_event(s_glob_stats *stats,
}
static void push_pre_suite(s_glob_stats *stats,
s_suite_stats *suite,
CR_UNUSED s_test_stats *test,
CR_UNUSED void *ptr) {
s_suite_stats *suite,
CR_UNUSED s_test_stats *test,
CR_UNUSED void *ptr)
{
suite->next = stats->suites;
stats->suites = sref(suite);
++stats->nb_suites;
}
static void push_pre_init(s_glob_stats *stats,
s_suite_stats *suite,
s_test_stats *test,
CR_UNUSED void *ptr) {
s_suite_stats *suite,
s_test_stats *test,
CR_UNUSED void *ptr)
{
test->next = suite->tests;
suite->tests = sref(test);
++stats->nb_tests;
@ -178,15 +195,16 @@ static void push_pre_init(s_glob_stats *stats,
}
static void push_assert(s_glob_stats *stats,
s_suite_stats *suite,
s_test_stats *test,
void *ptr) {
s_suite_stats *suite,
s_test_stats *test,
void *ptr)
{
s_assert_stats *data = ptr;
s_assert_stats *dup = smalloc(
.size = sizeof (s_assert_stats),
.dtor = destroy_assert_stats);
.size = sizeof (s_assert_stats),
.dtor = destroy_assert_stats);
memcpy(dup, data, sizeof (s_assert_stats));
dup->message = strdup(data->message);
dup->file = strdup(data->file);
@ -209,18 +227,18 @@ static void push_assert(s_glob_stats *stats,
}
static void push_post_test(s_glob_stats *stats,
s_suite_stats *suite,
s_test_stats *test,
void *ptr) {
s_suite_stats *suite,
s_test_stats *test,
void *ptr)
{
double *data = ptr;
test->elapsed_time = (float) *data;
if (test->failed_asserts > 0
|| test->timed_out
|| test->signal != test->test->data->signal
|| test->exit_code != test->test->data->exit_code) {
|| test->exit_code != test->test->data->exit_code)
test->test_status = CR_STATUS_FAILED;
}
switch (test->test_status) {
case CR_STATUS_FAILED:
@ -236,13 +254,13 @@ static void push_post_test(s_glob_stats *stats,
++suite->tests_skipped;
break;
}
}
static void push_test_crash(s_glob_stats *stats,
s_suite_stats *suite,
s_test_stats *test,
CR_UNUSED void *ptr) {
s_suite_stats *suite,
s_test_stats *test,
CR_UNUSED void *ptr)
{
test->test_status = CR_STATUS_FAILED;
test->crashed = 1;
++suite->tests_failed;

View file

@ -22,17 +22,17 @@
* THE SOFTWARE.
*/
#ifndef STATS_H_
# define STATS_H_
#define STATS_H_
# include "criterion/stats.h"
# include "io/event.h"
#include "criterion/stats.h"
#include "io/event.h"
struct criterion_global_stats *stats_init(void);
struct criterion_test_stats *test_stats_init(struct criterion_test *t);
struct criterion_suite_stats *suite_stats_init(struct criterion_suite *s);
void stat_push_event(struct criterion_global_stats *stats,
struct criterion_suite_stats *suite,
struct criterion_test_stats *test,
struct event *data);
struct criterion_suite_stats *suite,
struct criterion_test_stats *test,
struct event *data);
#endif /* !STATS_H_ */

View file

@ -31,19 +31,22 @@
#include "protocol/messages.h"
#include "io/event.h"
extern const struct criterion_test *criterion_current_test;
extern const struct criterion_test *criterion_current_test;
extern const struct criterion_suite *criterion_current_suite;
static void send_event(int phase) {
static void send_event(int phase)
{
criterion_protocol_msg msg = criterion_message(phase,
.phase = phase,
.name = (char *) criterion_current_test->name,
);
.phase = phase,
.name = (char *) criterion_current_test->name,
);
criterion_message_set_id(msg);
cr_send_to_runner(&msg);
}
void criterion_internal_test_setup(void) {
void criterion_internal_test_setup(void)
{
const struct criterion_suite *suite = criterion_current_suite;
const struct criterion_test *test = criterion_current_test;
@ -58,7 +61,8 @@ static void *getparam(void)
void *param;
bxf_context ctx = bxf_context_current();
int rc = bxf_context_getobject(ctx, "criterion.param", (void **)&param);
int rc = bxf_context_getobject(ctx, "criterion.param", (void **) &param);
if (rc < 0) {
cr_log_error("Could not retrieve test parameter -- aborting.");
abort();
@ -66,7 +70,8 @@ static void *getparam(void)
return param;
}
void criterion_internal_test_main(void (*fn)(void)) {
void criterion_internal_test_main(void (*fn)(void))
{
const struct criterion_test *test = criterion_current_test;
send_event(criterion_protocol_phase_kind_MAIN);
@ -75,7 +80,7 @@ void criterion_internal_test_main(void (*fn)(void)) {
if (!test->data->param_) {
fn();
} else {
void(*param_test_func)(void *) = (void(*)(void*)) fn;
void (*param_test_func)(void *) = (void (*)(void *))fn;
param_test_func(getparam());
}
}
@ -83,7 +88,8 @@ void criterion_internal_test_main(void (*fn)(void)) {
send_event(criterion_protocol_phase_kind_TEARDOWN);
}
void criterion_internal_test_teardown(void) {
void criterion_internal_test_teardown(void)
{
const struct criterion_suite *suite = criterion_current_suite;
const struct criterion_test *test = criterion_current_test;
@ -93,4 +99,3 @@ void criterion_internal_test_teardown(void) {
send_event(criterion_protocol_phase_kind_END);
}

View file

@ -36,139 +36,150 @@
#include "abort.h"
struct criterion_theory_context {
DCCallVM* vm;
DCCallVM *vm;
};
void cr_theory_push_arg(struct criterion_theory_context *ctx, bool is_float, size_t size, void *ptr) {
void cr_theory_push_arg(struct criterion_theory_context *ctx, bool is_float, size_t size, void *ptr)
{
if (is_float) {
if (size == sizeof (float)) {
dcArgFloat(ctx->vm, *(float*)ptr);
} else if (size == sizeof (double)) {
dcArgDouble(ctx->vm, *(double*)ptr);
} else if (size == sizeof (long double)) {
dcArgDouble(ctx->vm, *(long double*)ptr);
}
if (size == sizeof (float))
dcArgFloat(ctx->vm, *(float *) ptr);
else if (size == sizeof (double))
dcArgDouble(ctx->vm, *(double *) ptr);
else if (size == sizeof (long double))
dcArgDouble(ctx->vm, *(long double *) ptr);
} else {
if (size == sizeof (char)) {
dcArgChar(ctx->vm, *(char*)ptr);
dcArgChar(ctx->vm, *(char *) ptr);
} else if (size == sizeof (short)) {
dcArgShort(ctx->vm, *(short*)ptr);
dcArgShort(ctx->vm, *(short *) ptr);
} else if (size == sizeof (int)) {
dcArgInt(ctx->vm, *(int*)ptr);
dcArgInt(ctx->vm, *(int *) ptr);
} else if (size == sizeof (bool)) {
dcArgBool(ctx->vm, *(bool*)ptr);
dcArgBool(ctx->vm, *(bool *) ptr);
#if INT_MAX < LONG_MAX
} else if (size == sizeof (long)) {
dcArgLong(ctx->vm, *(long*)ptr);
dcArgLong(ctx->vm, *(long *) ptr);
#endif
#if LONG_MAX < LLONG_MAX
} else if (size == sizeof (long long)) {
dcArgLongLong(ctx->vm, *(long long*)ptr);
dcArgLongLong(ctx->vm, *(long long *) ptr);
#endif
} else if (size == sizeof (void*)) {
dcArgPointer(ctx->vm, *(void**)ptr);
} else if (size == sizeof (void *)) {
dcArgPointer(ctx->vm, *(void **) ptr);
} else {
dcArgPointer(ctx->vm, ptr);
}
}
}
struct criterion_theory_context* cr_theory_init(void) {
struct criterion_theory_context* ctx = malloc(sizeof (struct criterion_theory_context));
struct criterion_theory_context *cr_theory_init(void)
{
struct criterion_theory_context *ctx = malloc(sizeof (struct criterion_theory_context));
ctx->vm = dcNewCallVM(4096);
dcMode(ctx->vm, DC_CALL_C_DEFAULT);
return ctx;
}
void cr_theory_free(struct criterion_theory_context *ctx) {
void cr_theory_free(struct criterion_theory_context *ctx)
{
dcFree(ctx->vm);
}
static jmp_buf theory_jmp;
void cr_theory_abort(void) {
void cr_theory_abort(void)
{
longjmp(theory_jmp, 1);
}
void cr_theory_reset(struct criterion_theory_context *ctx) {
void cr_theory_reset(struct criterion_theory_context *ctx)
{
dcReset(ctx->vm);
}
void cr_theory_call(struct criterion_theory_context *ctx, void (*fnptr)(void)) {
void cr_theory_call(struct criterion_theory_context *ctx, void (*fnptr)(void))
{
dcCallVoid(ctx->vm, (DCpointer) fnptr);
}
static bool contains_word(const char *str, const char *pattern, size_t sz) {
static bool contains_word(const char *str, const char *pattern, size_t sz)
{
char *res = strstr(str, pattern);
return res
&& (res == str || (res > str && res[-1] == ' '))
&& (!res[sz - 1] || res[sz - 1] == ' ');
&& (res == str || (res > str && res[-1] == ' '))
&& (!res[sz - 1] || res[sz - 1] == ' ');
}
static bool is_string(const char *name) {
static bool is_string(const char *name)
{
return !strcmp(name, "char*")
|| !strcmp(name, "char *")
|| !strcmp(name, "const char*")
|| !strcmp(name, "const char *")
|| !strcmp(name, "char const *")
|| !strcmp(name, "char const*")
|| !strcmp(name, "char[]")
|| !strcmp(name, "char []")
|| !strcmp(name, "const char[]")
|| !strcmp(name, "const char []")
|| !strcmp(name, "char const[]")
|| !strcmp(name, "char const []");
|| !strcmp(name, "char *")
|| !strcmp(name, "const char*")
|| !strcmp(name, "const char *")
|| !strcmp(name, "char const *")
|| !strcmp(name, "char const*")
|| !strcmp(name, "char[]")
|| !strcmp(name, "char []")
|| !strcmp(name, "const char[]")
|| !strcmp(name, "const char []")
|| !strcmp(name, "char const[]")
|| !strcmp(name, "char const []");
}
static bool is_float(const char *name) {
static bool is_float(const char *name)
{
return contains_word(name, "float", sizeof ("float"))
|| contains_word(name, "double", sizeof ("double"));
|| contains_word(name, "double", sizeof ("double"));
}
static bool is_unsigned_int(const char *name) {
static bool is_unsigned_int(const char *name)
{
return contains_word(name, "unsigned", sizeof ("unsigned"))
|| !strncmp(name, "uint", 4);
|| !strncmp(name, "uint", 4);
}
static bool is_bool(const char *name) {
static bool is_bool(const char *name)
{
return contains_word(name, "bool", sizeof ("bool"))
|| contains_word(name, "_Bool", sizeof ("_Bool"));
|| contains_word(name, "_Bool", sizeof ("_Bool"));
}
static void format_arg(char (*arg)[1024], struct criterion_datapoints *dp, void *data) {
static void format_arg(char (*arg)[1024], struct criterion_datapoints *dp, void *data)
{
if (is_float(dp->name)) {
if (dp->size == sizeof (float)) {
snprintf(*arg, sizeof (*arg) - 1, "%gf", *(float*) data);
} else if (dp->size == sizeof (double)) {
snprintf(*arg, sizeof (*arg) - 1, "%g", *(double*) data);
} else if (dp->size == sizeof (long double)) {
snprintf(*arg, sizeof (*arg) - 1, "%gl", (double) *(long double*) data);
}
if (dp->size == sizeof (float))
snprintf(*arg, sizeof (*arg) - 1, "%gf", *(float *) data);
else if (dp->size == sizeof (double))
snprintf(*arg, sizeof (*arg) - 1, "%g", *(double *) data);
else if (dp->size == sizeof (long double))
snprintf(*arg, sizeof (*arg) - 1, "%gl", (double) *(long double *) data);
} else {
if (is_string(dp->name)) {
snprintf(*arg, sizeof (*arg) - 1, "\"%s\"", *(char**) data);
snprintf(*arg, sizeof (*arg) - 1, "\"%s\"", *(char **) data);
} else if (dp->size == sizeof (bool) && is_bool(dp->name)) {
snprintf(*arg, sizeof (*arg) - 1, "%s", (*(bool*) data) ? "true" : "false");
snprintf(*arg, sizeof (*arg) - 1, "%s", (*(bool *) data) ? "true" : "false");
} else if (dp->size == sizeof (char)) {
snprintf(*arg, sizeof (*arg) - 1, "'%c'", *(char*) data);
snprintf(*arg, sizeof (*arg) - 1, "'%c'", *(char *) data);
} else if (dp->size == sizeof (short)) {
const char *fmt = is_unsigned_int(dp->name) ? "%hu" : "%hd";
snprintf(*arg, sizeof (*arg) - 1, fmt, *(short*) data);
snprintf(*arg, sizeof (*arg) - 1, fmt, *(short *) data);
} else if (dp->size == sizeof (int)) {
const char *fmt = is_unsigned_int(dp->name) ? "%u" : "%d";
snprintf(*arg, sizeof (*arg) - 1, fmt, *(int*) data);
} else if (dp->size == sizeof (void*) && strstr(dp->name, "*")) {
snprintf(*arg, sizeof (*arg) - 1, "%p", *(void**) data);
snprintf(*arg, sizeof (*arg) - 1, fmt, *(int *) data);
} else if (dp->size == sizeof (void *) && strstr(dp->name, "*")) {
snprintf(*arg, sizeof (*arg) - 1, "%p", *(void **) data);
#if INT_MAX < LONG_MAX
} else if (dp->size == sizeof (long)) {
const char *fmt = is_unsigned_int(dp->name) ? "%lulu" : "%ldl";
snprintf(*arg, sizeof (*arg) - 1, fmt, *(long*) data);
snprintf(*arg, sizeof (*arg) - 1, fmt, *(long *) data);
#endif
#if LONG_MAX < LLONG_MAX
} else if (dp->size == sizeof (long long)) {
const char *fmt = is_unsigned_int(dp->name) ? "%llullu" : "%lldll";
snprintf(*arg, sizeof (*arg) - 1, fmt, *(long long*) data);
snprintf(*arg, sizeof (*arg) - 1, fmt, *(long long *) data);
#endif
} else {
snprintf(*arg, sizeof (*arg) - 1, "%s", "<np>");
@ -176,17 +187,20 @@ static void format_arg(char (*arg)[1024], struct criterion_datapoints *dp, void
}
}
# define BUFSIZE 4096
#define BUFSIZE 4096
static void concat_arg(char (*msg)[BUFSIZE], struct criterion_datapoints *dps, size_t *indices, size_t i) {
void *data = ((char*) dps[i].arr) + dps[i].size * indices[i];
static void concat_arg(char (*msg)[BUFSIZE], struct criterion_datapoints *dps, size_t *indices, size_t i)
{
void *data = ((char *) dps[i].arr) + dps[i].size * indices[i];
char arg[1024];
format_arg(&arg, dps + i, data);
strncat(*msg, arg, BUFSIZE - 1);
}
int try_call_theory(struct criterion_theory_context *ctx, void (*fnptr)(void)) {
int try_call_theory(struct criterion_theory_context *ctx, void (*fnptr)(void))
{
if (!setjmp(g_pre_test)) {
cr_theory_call(ctx, fnptr);
return 1;
@ -194,10 +208,12 @@ int try_call_theory(struct criterion_theory_context *ctx, void (*fnptr)(void)) {
return 0;
}
void cr_theory_main(struct criterion_datapoints *dps, size_t datapoints, void (*fnptr)(void)) {
void cr_theory_main(struct criterion_datapoints *dps, size_t datapoints, void (*fnptr)(void))
{
struct criterion_theory_context *ctx = cr_theory_init();
size_t *indices = malloc(sizeof (size_t) * datapoints);
memset(indices, 0, datapoints * sizeof (size_t));
volatile int round = 1;
@ -207,16 +223,16 @@ void cr_theory_main(struct criterion_datapoints *dps, size_t datapoints, void (*
cr_asprintf(&name, "%s::%d", criterion_current_test->name, round);
criterion_protocol_msg setup_msg = criterion_message(phase,
.phase = criterion_protocol_phase_kind_SETUP,
.name = name,
);
.phase = criterion_protocol_phase_kind_SETUP,
.name = name,
);
criterion_message_set_id(setup_msg);
cr_send_to_runner(&setup_msg);
criterion_protocol_msg main_msg = criterion_message(phase,
.phase = criterion_protocol_phase_kind_MAIN,
.name = name,
);
.phase = criterion_protocol_phase_kind_MAIN,
.name = name,
);
criterion_message_set_id(main_msg);
cr_send_to_runner(&main_msg);
@ -224,14 +240,13 @@ void cr_theory_main(struct criterion_datapoints *dps, size_t datapoints, void (*
if (!setjmp(theory_jmp)) {
cr_theory_reset(ctx);
for (size_t i = 0; i < datapoints; ++i) {
bool is_float = contains_word(dps[i].name, "float", sizeof ("float"))
|| contains_word(dps[i].name, "double", sizeof ("double"));
|| contains_word(dps[i].name, "double", sizeof ("double"));
cr_theory_push_arg(ctx,
is_float,
dps[i].size,
((char*) dps[i].arr) + dps[i].size * indices[i]);
((char *) dps[i].arr) + dps[i].size * indices[i]);
}
if (!try_call_theory(ctx, fnptr)) {
@ -251,10 +266,10 @@ void cr_theory_main(struct criterion_datapoints *dps, size_t datapoints, void (*
result.msg[result.len] = '\0';
criterion_protocol_msg msg = criterion_message(phase,
.phase = criterion_protocol_phase_kind_ABORT,
.name = name,
.message = result.msg
);
.phase = criterion_protocol_phase_kind_ABORT,
.name = name,
.message = result.msg
);
criterion_message_set_id(msg);
cr_send_to_runner(&msg);
}
@ -262,16 +277,16 @@ void cr_theory_main(struct criterion_datapoints *dps, size_t datapoints, void (*
if (!theory_aborted) {
criterion_protocol_msg teardown_msg = criterion_message(phase,
.phase = criterion_protocol_phase_kind_TEARDOWN,
.name = name,
);
.phase = criterion_protocol_phase_kind_TEARDOWN,
.name = name,
);
criterion_message_set_id(teardown_msg);
cr_send_to_runner(&teardown_msg);
criterion_protocol_msg end_msg = criterion_message(phase,
.phase = criterion_protocol_phase_kind_END,
.name = name,
);
.phase = criterion_protocol_phase_kind_END,
.name = name,
);
criterion_message_set_id(end_msg);
cr_send_to_runner(&end_msg);
}

View file

@ -23,10 +23,12 @@
*/
#include "criterion/criterion.h"
CR_API int main(int argc, char *argv[]) {
CR_API int main(int argc, char *argv[])
{
struct criterion_test_set *tests = criterion_initialize();
int result = 0;
if (criterion_handle_args(argc, argv, true))
result = !criterion_run_all_tests(tests);

View file

@ -21,7 +21,7 @@
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
# include "criterion/options.h"
#include "criterion/options.h"
CR_API struct criterion_options criterion_options = {
.logging_threshold = CRITERION_IMPORTANT,

View file

@ -41,67 +41,71 @@
# include <libintl.h>
#endif
# define VERSION_MSG "Tests compiled with Criterion v" VERSION "\n"
#define VERSION_MSG "Tests compiled with Criterion v" VERSION "\n"
# define USAGE \
#define USAGE \
VERSION_MSG "\n" \
"usage: %s OPTIONS\n" \
"options: \n" \
" -h or --help: prints this message\n" \
" -q or --quiet: disables all logging\n" \
" -v or --version: prints the version of criterion " \
"these tests have been linked against\n" \
"these tests have been linked against\n" \
" -l or --list: prints all the tests in a list\n" \
" -jN or --jobs N: use N concurrent jobs\n" \
" -f or --fail-fast: exit after the first failure\n" \
" --ascii: don't use fancy unicode symbols " \
"or colors in the output\n" \
"or colors in the output\n" \
" -S or --short-filename: only display the base " \
"name of the source file on a failure\n" \
"name of the source file on a failure\n" \
" --filter [PATTERN]: run tests matching the " \
"given pattern\n" \
"given pattern\n" \
" --timeout [TIMEOUT]: set a timeout (in seconds) " \
"for all tests\n" \
"for all tests\n" \
" --tap[=FILE]: writes TAP report in FILE " \
"(no file or \"-\" means stderr)\n" \
"(no file or \"-\" means stderr)\n" \
" --xml[=FILE]: writes XML report in FILE " \
"(no file or \"-\" means stderr)\n" \
"(no file or \"-\" means stderr)\n" \
" --always-succeed: always exit with 0\n" \
" --verbose[=level]: sets verbosity to level " \
"(1 by default)\n" \
"(1 by default)\n" \
" --crash: crash failing assertions rather than " \
"aborting (for debugging purposes)\n" \
"aborting (for debugging purposes)\n" \
" --debug[=TYPE]: run tests with a debugging " \
"server, listening on localhost:1234 by " \
"default. TYPE may be gdb, lldb, or wingbd.\n" \
"server, listening on localhost:1234 by " \
"default. TYPE may be gdb, lldb, or wingbd.\n" \
" --debug-transport=VAL: the transport to use by " \
"the debugging server. `tcp:1234` by default\n" \
"the debugging server. `tcp:1234` by default\n" \
" -OP:F or --output=PROVIDER=FILE: write test " \
"report to FILE using the specified provider\n"
"report to FILE using the specified provider\n"
int print_usage(char *progname) {
int print_usage(char *progname)
{
fprintf(stderr, USAGE, progname);
return 0;
}
int print_version(void) {
int print_version(void)
{
fputs(VERSION_MSG, stderr);
return 0;
}
# define UTF8_TREE_NODE "├"
# define UTF8_TREE_END "└"
# define UTF8_TREE_JOIN "──"
#define UTF8_TREE_NODE "├"
#define UTF8_TREE_END "└"
#define UTF8_TREE_JOIN "──"
# define ASCII_TREE_NODE "|"
# define ASCII_TREE_END "`"
# define ASCII_TREE_JOIN "--"
#define ASCII_TREE_NODE "|"
#define ASCII_TREE_END "`"
#define ASCII_TREE_JOIN "--"
bool is_disabled(struct criterion_suite *s, struct criterion_test *t) {
bool is_disabled(struct criterion_suite *s, struct criterion_test *t)
{
return (s->data && s->data->disabled) || t->data->disabled;
}
int list_tests(bool unicode) {
int list_tests(bool unicode)
{
struct criterion_test_set *set = criterion_init();
const char *node = unicode ? UTF8_TREE_NODE : ASCII_TREE_NODE;
@ -110,6 +114,7 @@ int list_tests(bool unicode) {
FOREACH_SET(struct criterion_suite_set *s, set->suites) {
size_t tests = s->tests ? s->tests->size : 0;
if (!tests)
continue;
@ -131,8 +136,10 @@ int list_tests(bool unicode) {
return 0;
}
int atou(const char *str) {
int atou(const char *str)
{
int res = atoi(str);
return res < 0 ? 0 : res;
}
@ -145,6 +152,7 @@ static int parse_dbg_transport(const char *arg)
char *val = dup + strlen(transport) + 1;
int ok = 1;
if (!strcmp(transport, "tcp")) {
criterion_options.debug_port = atou(val);
} else {
@ -162,8 +170,8 @@ static int parse_dbg(const char *arg)
return CR_DBG_NATIVE;
static struct { char *name; enum criterion_debugger dbg; } values[] = {
{ "gdb", CR_DBG_GDB },
{ "lldb", CR_DBG_LLDB },
{ "gdb", CR_DBG_GDB },
{ "lldb", CR_DBG_LLDB },
{ "windbg", CR_DBG_WINDBG },
};
@ -182,35 +190,35 @@ CR_API int criterion_handle_args(int argc, char *argv[],
bool handle_unknown_arg)
{
static struct option opts[] = {
{"verbose", optional_argument, 0, 'b'},
{"quiet", no_argument, 0, 'q'},
{"version", no_argument, 0, 'v'},
{"tap", optional_argument, 0, 'T'},
{"xml", optional_argument, 0, 'x'},
{"json", optional_argument, 0, 'n'},
{"help", no_argument, 0, 'h'},
{"list", no_argument, 0, 'l'},
{"ascii", no_argument, 0, 'k'},
{"jobs", required_argument, 0, 'j'},
{"timeout", required_argument, 0, 't'},
{"fail-fast", no_argument, 0, 'f'},
{"short-filename", no_argument, 0, 'S'},
{"single", required_argument, 0, 's'},
{"pattern", required_argument, 0, 'p'},
{"filter", required_argument, 0, 'F'},
{"always-succeed", no_argument, 0, 'y'},
{"no-early-exit", no_argument, 0, 'z'},
{"output", required_argument, 0, 'O'},
{"wait", no_argument, 0, 'w'},
{"crash", no_argument, 0, 'c'},
{"debug", optional_argument, 0, 'd'},
{"debug-transport", required_argument, 0, 'D'},
{0, 0, 0, 0 }
{ "verbose", optional_argument, 0, 'b' },
{ "quiet", no_argument, 0, 'q' },
{ "version", no_argument, 0, 'v' },
{ "tap", optional_argument, 0, 'T' },
{ "xml", optional_argument, 0, 'x' },
{ "json", optional_argument, 0, 'n' },
{ "help", no_argument, 0, 'h' },
{ "list", no_argument, 0, 'l' },
{ "ascii", no_argument, 0, 'k' },
{ "jobs", required_argument, 0, 'j' },
{ "timeout", required_argument, 0, 't' },
{ "fail-fast", no_argument, 0, 'f' },
{ "short-filename", no_argument, 0, 'S' },
{ "single", required_argument, 0, 's' },
{ "pattern", required_argument, 0, 'p' },
{ "filter", required_argument, 0, 'F' },
{ "always-succeed", no_argument, 0, 'y' },
{ "no-early-exit", no_argument, 0, 'z' },
{ "output", required_argument, 0, 'O' },
{ "wait", no_argument, 0, 'w' },
{ "crash", no_argument, 0, 'c' },
{ "debug", optional_argument, 0, 'd' },
{ "debug-transport", required_argument, 0, 'D' },
{ 0, 0, 0, 0 }
};
setlocale(LC_ALL, "");
#if ENABLE_NLS
textdomain (PACKAGE "-test");
textdomain(PACKAGE "-test");
#endif
if (!handle_unknown_arg)
@ -247,8 +255,8 @@ CR_API int criterion_handle_args(int argc, char *argv[],
bool quiet = false;
// CRITERION_ENABLE_TAP backward compatibility.
// The environment variable is otherwise deprecated.
/* CRITERION_ENABLE_TAP backward compatibility.
The environment variable is otherwise deprecated. */
if (!strcmp("1", DEF(getenv("CRITERION_ENABLE_TAP"), "0"))) {
quiet = true;
criterion_add_output("tap", DEF(optarg, "-"));
@ -306,7 +314,7 @@ CR_API int criterion_handle_args(int argc, char *argv[],
exit(3);
break;
/* *INDENT-OFF* - Duff devices are often mishandled by formatters */
/* *INDENT-OFF* - Duff devices are often mishandled by formatters */
{
const char *provider;
case 'T': provider = "tap"; goto provider_def;
@ -318,7 +326,7 @@ CR_API int criterion_handle_args(int argc, char *argv[],
quiet = !strcmp(path, "-");
criterion_add_output(provider, path);
} break;
/* *INDENT-ON* */
/* *INDENT-ON* */
case 'l': do_list_tests = true; break;
case 'v': do_print_version = true; break;
@ -326,7 +334,7 @@ CR_API int criterion_handle_args(int argc, char *argv[],
case 'O': {
char *arg = strdup(optarg);
char *buf = NULL;
strtok_r(arg, ":", &buf);
strtok_r(arg, ":", &buf);
char *path = strtok_r(NULL, ":", &buf);
if (arg == NULL || path == NULL) {
@ -343,7 +351,7 @@ CR_API int criterion_handle_args(int argc, char *argv[],
exit(3);
case '?':
case 'c': criterion_options.crash = true; break;
default : do_print_usage = handle_unknown_arg; break;
default: do_print_usage = handle_unknown_arg; break;
}
}

View file

@ -30,6 +30,7 @@
CR_NORETURN void cr_panic(const char *str, ...)
{
va_list vl;
va_start(vl, str);
fprintf(stderr, "criterion: ");
vfprintf(stderr, str, vl);

Some files were not shown because too many files have changed in this diff Show more