diff --git a/CMakeLists.txt b/CMakeLists.txt index a7bf973..63388cf 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -44,13 +44,13 @@ endif() # Find dependencies -find_package(Gettext) -find_package(Libintl) -if (GETTEXT_FOUND AND LIBINTL_LIB_FOUND) - include(GettextTranslate) - add_subdirectory(po) - set(ENABLE_NLS 1) -endif () +#find_package(Gettext) +#find_package(Libintl) +#if (GETTEXT_FOUND AND LIBINTL_LIB_FOUND) +# include(GettextTranslate) +# add_subdirectory(po) +# set(ENABLE_NLS 1) +#endif () include(CheckLibraryExists) CHECK_LIBRARY_EXISTS(rt clock_gettime "time.h" HAVE_CLOCK_GETTIME) @@ -136,6 +136,12 @@ if (COVERALLS) coveralls_setup("${SOURCE_FILES}" ${COVERALLS_UPLOAD}) endif() +if (WIN32) + set_target_properties(criterion PROPERTIES LINK_FLAGS + "-Wl,--output-def,${CMAKE_CURRENT_BINARY_DIR}/libcriterion.def") + install(FILES ${CMAKE_CURRENT_BINARY_DIR}/libcriterion.def DESTINATION lib) +endif () + install(FILES ${INTERFACE_FILES} DESTINATION include/criterion) install(TARGETS criterion RUNTIME DESTINATION bin diff --git a/include/criterion/assert.h b/include/criterion/assert.h index 5e7f616..6d796b2 100644 --- a/include/criterion/assert.h +++ b/include/criterion/assert.h @@ -72,150 +72,150 @@ struct criterion_assert_args { .msg = (Message) \ ) -# define cr_assert(...) cr_assert_(__VA_ARGS__, .sentinel_ = 0) +# define cr_assert(...) CR_EXPAND(cr_assert_(__VA_ARGS__, .sentinel_ = 0)) -# define cr_expect(...) cr_expect_(__VA_ARGS__, .sentinel_ = 0) +# define cr_expect(...) CR_EXPAND(cr_expect_(__VA_ARGS__, .sentinel_ = 0)) -# define cr_assert_(Condition, ...) cr_assert_impl(FATAL, Condition, __VA_ARGS__) -# define cr_expect_(Condition, ...) cr_assert_impl(NORMAL, Condition, __VA_ARGS__) +# define cr_assert_(Condition, ...) CR_EXPAND(cr_assert_impl(FATAL, Condition, __VA_ARGS__)) +# define cr_expect_(Condition, ...) CR_EXPAND(cr_assert_impl(NORMAL, Condition, __VA_ARGS__)) -# define cr_assert_not(...) cr_assert_not_(__VA_ARGS__, .sentinel_ = 0) -# define cr_expect_not(...) cr_expect_not_(__VA_ARGS__, .sentinel_ = 0) +# define cr_assert_not(...) CR_EXPAND(cr_assert_not_(__VA_ARGS__, .sentinel_ = 0)) +# define cr_expect_not(...) CR_EXPAND(cr_expect_not_(__VA_ARGS__, .sentinel_ = 0)) # define cr_assert_not_(Condition, ...) \ - cr_assert_impl(FATAL, !(Condition), __VA_ARGS__) + CR_EXPAND(cr_assert_impl(FATAL, !(Condition), __VA_ARGS__)) # define cr_expect_not_(Condition, ...) \ - cr_expect_impl(NORMAL, !(Condition), __VA_ARGS__) + CR_EXPAND(cr_expect_impl(NORMAL, !(Condition), __VA_ARGS__)) // Native asserts # define cr_assert_op_(Op, Actual, Expected, ...) \ - cr_assert_impl(FATAL, (Actual) Op (Expected), __VA_ARGS__) + CR_EXPAND(cr_assert_impl(FATAL, (Actual) Op (Expected), __VA_ARGS__)) # define cr_expect_op_(Op, Actual, Expected, ...) \ - cr_assert_impl(NORMAL, (Actual) Op (Expected), __VA_ARGS__) + CR_EXPAND(cr_assert_impl(NORMAL, (Actual) Op (Expected), __VA_ARGS__)) -# define cr_assert_eq(...) cr_assert_op_(==, __VA_ARGS__, .sentinel_ = 0) -# define cr_expect_eq(...) cr_expect_op_(==, __VA_ARGS__, .sentinel_ = 0) +# define cr_assert_eq(...) CR_EXPAND(cr_assert_op_(==, __VA_ARGS__, .sentinel_ = 0)) +# define cr_expect_eq(...) CR_EXPAND(cr_expect_op_(==, __VA_ARGS__, .sentinel_ = 0)) -# define cr_assert_neq(...) cr_assert_op_(!=, __VA_ARGS__, .sentinel_ = 0) -# define cr_expect_neq(...) cr_expect_op_(!=, __VA_ARGS__, .sentinel_ = 0) +# define cr_assert_neq(...) CR_EXPAND(cr_assert_op_(!=, __VA_ARGS__, .sentinel_ = 0)) +# define cr_expect_neq(...) CR_EXPAND(cr_expect_op_(!=, __VA_ARGS__, .sentinel_ = 0)) -# define cr_assert_lt(...) cr_assert_op_(<, __VA_ARGS__, .sentinel_ = 0) -# define cr_expect_lt(...) cr_expect_op_(<, __VA_ARGS__, .sentinel_ = 0) +# define cr_assert_lt(...) CR_EXPAND(cr_assert_op_(<, __VA_ARGS__, .sentinel_ = 0)) +# define cr_expect_lt(...) CR_EXPAND(cr_expect_op_(<, __VA_ARGS__, .sentinel_ = 0)) -# define cr_assert_gt(...) cr_assert_op_(>, __VA_ARGS__, .sentinel_ = 0) -# define cr_expect_gt(...) cr_expect_op_(>, __VA_ARGS__, .sentinel_ = 0) +# define cr_assert_gt(...) CR_EXPAND(cr_assert_op_(>, __VA_ARGS__, .sentinel_ = 0)) +# define cr_expect_gt(...) CR_EXPAND(cr_expect_op_(>, __VA_ARGS__, .sentinel_ = 0)) -# define cr_assert_leq(...) cr_assert_op_(<=, __VA_ARGS__, .sentinel_ = 0) -# define cr_expect_leq(...) cr_expect_op_(<=, __VA_ARGS__, .sentinel_ = 0) +# define cr_assert_leq(...) CR_EXPAND(cr_assert_op_(<=, __VA_ARGS__, .sentinel_ = 0)) +# define cr_expect_leq(...) CR_EXPAND(cr_expect_op_(<=, __VA_ARGS__, .sentinel_ = 0)) -# define cr_assert_geq(...) cr_assert_op_(>=, __VA_ARGS__, .sentinel_ = 0) -# define cr_expect_geq(...) cr_expect_op_(>=, __VA_ARGS__, .sentinel_ = 0) +# define cr_assert_geq(...) CR_EXPAND(cr_assert_op_(>=, __VA_ARGS__, .sentinel_ = 0)) +# define cr_expect_geq(...) CR_EXPAND(cr_expect_op_(>=, __VA_ARGS__, .sentinel_ = 0)) # define cr_assert_null_(Value, ...) \ - cr_assert_impl(FATAL, (Value) == NULL, __VA_ARGS__) + CR_EXPAND(cr_assert_impl(FATAL, (Value) == NULL, __VA_ARGS__)) # define cr_expect_null_(Value, ...) \ - cr_assert_impl(NORMAL, (Value) == NULL, __VA_ARGS__) + CR_EXPAND(cr_assert_impl(NORMAL, (Value) == NULL, __VA_ARGS__)) -# define cr_assert_null(...) cr_assert_null_(__VA_ARGS__, .sentinel_ = 0) -# define cr_expect_null(...) cr_expect_null_(__VA_ARGS__, .sentinel_ = 0) +# define cr_assert_null(...) CR_EXPAND(cr_assert_null_(__VA_ARGS__, .sentinel_ = 0)) +# define cr_expect_null(...) CR_EXPAND(cr_expect_null_(__VA_ARGS__, .sentinel_ = 0)) # define cr_assert_not_null_(Value, ...) \ - cr_assert_impl(FATAL, (Value) != NULL, __VA_ARGS__) + CR_EXPAND(cr_assert_impl(FATAL, (Value) != NULL, __VA_ARGS__)) # define cr_expect_not_null_(Value, ...) \ - cr_assert_impl(NORMAL, (Value) != NULL, __VA_ARGS__) + CR_EXPAND(cr_assert_impl(NORMAL, (Value) != NULL, __VA_ARGS__)) -# define cr_assert_not_null(...) cr_assert_not_null_(__VA_ARGS__, .sentinel_ = 0) -# define cr_expect_not_null(...) cr_expect_not_null_(__VA_ARGS__, .sentinel_ = 0) +# define cr_assert_not_null(...) CR_EXPAND(cr_assert_not_null_(__VA_ARGS__, .sentinel_ = 0)) +# define cr_expect_not_null(...) CR_EXPAND(cr_expect_not_null_(__VA_ARGS__, .sentinel_ = 0)) // Floating-point asserts # define cr_assert_float_eq(...) \ - cr_assert_float_eq_(__VA_ARGS__, .sentinel_ = 0) + CR_EXPAND(cr_assert_float_eq_(__VA_ARGS__, .sentinel_ = 0)) # define cr_expect_float_eq(...) \ - cr_expect_float_eq_(__VA_ARGS__, .sentinel_ = 0) + CR_EXPAND(cr_expect_float_eq_(__VA_ARGS__, .sentinel_ = 0)) # define cr_assert_float_eq_(Actual, Expected, Epsilon, ...) \ - cr_assert_impl(FATAL, (Expected) - (Actual) <= (Epsilon) \ + CR_EXPAND(cr_assert_impl(FATAL, (Expected) - (Actual) <= (Epsilon) \ && (Actual) - (Expected) <= (Epsilon), \ - __VA_ARGS__) + __VA_ARGS__)) # define cr_expect_float_eq_(Actual, Expected, Epsilon, ...) \ - cr_assert_impl(NORMAL, (Expected) - (Actual) <= (Epsilon) \ + CR_EXPAND(cr_assert_impl(NORMAL, (Expected) - (Actual) <= (Epsilon) \ && (Actual) - (Expected) <= (Epsilon), \ - __VA_ARGS__) + __VA_ARGS__)) # define cr_assert_float_neq(...) \ - cr_assert_float_neq_(__VA_ARGS__, .sentinel_ = 0) + CR_EXPAND(cr_assert_float_neq_(__VA_ARGS__, .sentinel_ = 0)) # define cr_expect_float_neq(...) \ - cr_expect_float_neq_(__VA_ARGS__, .sentinel_ = 0) + CR_EXPAND(cr_expect_float_neq_(__VA_ARGS__, .sentinel_ = 0)) # define cr_assert_float_neq_(Actual, Expected, Epsilon, ...) \ - cr_assert_impl(FATAL, (Expected) - (Actual) > (Epsilon) \ + CR_EXPAND(cr_assert_impl(FATAL, (Expected) - (Actual) > (Epsilon) \ || (Actual) - (Expected) > (Epsilon), \ - __VA_ARGS__) + __VA_ARGS__)) # define cr_expect_float_neq_(Actual, Expected, Epsilon, ...) \ - cr_assert_impl(NORMAL, (Expected) - (Actual) > (Epsilon) \ + CR_EXPAND(cr_assert_impl(NORMAL, (Expected) - (Actual) > (Epsilon) \ || (Actual) - (Expected) > (Epsilon), \ - __VA_ARGS__) + __VA_ARGS__)) // String asserts # define cr_assert_strings_(Op, Actual, Expected, ...) \ - cr_assert_impl(FATAL, strcmp((Actual), (Expected)) Op 0, __VA_ARGS__) + CR_EXPAND(cr_assert_impl(FATAL, strcmp((Actual), (Expected)) Op 0, __VA_ARGS__)) # define cr_expect_strings_(Op, Actual, Expected, ...) \ - cr_assert_impl(NORMAL, strcmp((Actual), (Expected)) Op 0, __VA_ARGS__) + CR_EXPAND(cr_assert_impl(NORMAL, strcmp((Actual), (Expected)) Op 0, __VA_ARGS__)) # define cr_assert_strings_eq(...) \ - cr_assert_strings_(==, __VA_ARGS__, .sentinel_ = 0) + CR_EXPAND(cr_assert_strings_(==, __VA_ARGS__, .sentinel_ = 0)) # define cr_expect_strings_eq(...) \ - cr_expect_strings_(==, __VA_ARGS__, .sentinel_ = 0) + CR_EXPAND(cr_expect_strings_(==, __VA_ARGS__, .sentinel_ = 0)) # define cr_assert_strings_neq(...) \ - cr_assert_strings_(!=, __VA_ARGS__, .sentinel_ = 0) + CR_EXPAND(cr_assert_strings_(!=, __VA_ARGS__, .sentinel_ = 0)) # define cr_expect_strings_neq(...) \ - cr_expect_strings_(!=, __VA_ARGS__, .sentinel_ = 0) + CR_EXPAND(cr_expect_strings_(!=, __VA_ARGS__, .sentinel_ = 0)) -# define cr_assert_strings_gt(...) cr_assert_strings_(>, __VA_ARGS__, .sentinel_ = 0) -# define cr_expect_strings_gt(...) cr_expect_strings_(>, __VA_ARGS__, .sentinel_ = 0) +# define cr_assert_strings_gt(...) CR_EXPAND(cr_assert_strings_(>, __VA_ARGS__, .sentinel_ = 0)) +# define cr_expect_strings_gt(...) CR_EXPAND(cr_expect_strings_(>, __VA_ARGS__, .sentinel_ = 0)) -# define cr_assert_strings_lt(...) cr_assert_strings_(<, __VA_ARGS__, .sentinel_ = 0) -# define cr_expect_strings_lt(...) cr_expect_strings_(<, __VA_ARGS__, .sentinel_ = 0) +# define cr_assert_strings_lt(...) CR_EXPAND(cr_assert_strings_(<, __VA_ARGS__, .sentinel_ = 0)) +# define cr_expect_strings_lt(...) CR_EXPAND(cr_expect_strings_(<, __VA_ARGS__, .sentinel_ = 0)) -# define cr_assert_strings_leq(...) cr_assert_strings_(<=, __VA_ARGS__, .sentinel_ = 0) -# define cr_expect_strings_leq(...) cr_expect_strings_(<=, __VA_ARGS__, .sentinel_ = 0) +# define cr_assert_strings_leq(...) CR_EXPAND(cr_assert_strings_(<=, __VA_ARGS__, .sentinel_ = 0)) +# define cr_expect_strings_leq(...) CR_EXPAND(cr_expect_strings_(<=, __VA_ARGS__, .sentinel_ = 0)) -# define cr_assert_strings_geq(...) cr_assert_strings_(>=, __VA_ARGS__, .sentinel_ = 0) -# define cr_expect_strings_geq(...) cr_expect_strings_(>=, __VA_ARGS__, .sentinel_ = 0) +# define cr_assert_strings_geq(...) CR_EXPAND(cr_assert_strings_(>=, __VA_ARGS__, .sentinel_ = 0)) +# define cr_expect_strings_geq(...) CR_EXPAND(cr_expect_strings_(>=, __VA_ARGS__, .sentinel_ = 0)) // Array asserts # define cr_assert_arrays_eq(...) \ - cr_assert_arrays_eq_(__VA_ARGS__, .sentinel_ = 0) + CR_EXPAND(cr_assert_arrays_eq_(__VA_ARGS__, .sentinel_ = 0)) # define cr_expect_arrays_eq(...) \ - cr_expect_arrays_eq_(__VA_ARGS__, .sentinel_ = 0) + CR_EXPAND(cr_expect_arrays_eq_(__VA_ARGS__, .sentinel_ = 0)) # define cr_assert_arrays_neq(...) \ - cr_assert_arrays_neq_(__VA_ARGS__, .sentinel_ = 0) + CR_EXPAND(cr_assert_arrays_neq_(__VA_ARGS__, .sentinel_ = 0)) # define cr_expect_arrays_neq(...) \ - cr_expect_arrays_neq_(__VA_ARGS__, .sentinel_ = 0) + CR_EXPAND(cr_expect_arrays_neq_(__VA_ARGS__, .sentinel_ = 0)) # define cr_assert_arrays_eq_(A, B, Size, ...) \ - cr_assert_impl(FATAL, !memcmp((A), (B), (Size)), \ + CR_EXPAND(cr_assert_impl(FATAL, !memcmp((A), (B), (Size)), \ .default_msg = "Arrays are not equal.", \ - __VA_ARGS__) + __VA_ARGS__)) # define cr_expect_arrays_eq_(A, B, Size, ...) \ - cr_assert_impl(NORMAL, !memcmp((A), (B), (Size)), \ + CR_EXPAND(cr_assert_impl(NORMAL, !memcmp((A), (B), (Size)), \ .default_msg = "Arrays are not equal.", \ - __VA_ARGS__) + __VA_ARGS__)) # define cr_assert_arrays_neq_(A, B, Size, ...) \ - cr_assert_impl(FATAL, memcmp((A), (B), (Size)), \ + CR_EXPAND(cr_assert_impl(FATAL, memcmp((A), (B), (Size)), \ .default_msg = "Arrays are equal", \ - __VA_ARGS__) + __VA_ARGS__)) # define cr_expect_arrays_neq_(A, B, Size, ...) \ - cr_assert_impl(NORMAL, memcmp((A), (B), (Size)), \ + CR_EXPAND(cr_assert_impl(NORMAL, memcmp((A), (B), (Size)), \ .default_msg = "Arrays are equal", \ - __VA_ARGS__) + __VA_ARGS__)) # ifdef __GNUC__ # define CRIT_ARR_COMPARE_(A, B, Size, Cmp, Result) \ diff --git a/include/criterion/common.h b/include/criterion/common.h index 3a8d3a8..2a1a630 100644 --- a/include/criterion/common.h +++ b/include/criterion/common.h @@ -24,18 +24,50 @@ #ifndef CRITERION_COMMON_H_ # define CRITERION_COMMON_H_ +# define CR_EXPAND(x) x + +# 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 __APPLE__ # define SECTION_START_PREFIX __first # define SECTION_END_PREFIX __last # define SECTION_START_SUFFIX(Name) __asm("section$start$__DATA$" Name) # define SECTION_END_SUFFIX(Name) __asm("section$end$__DATA$" Name) # define SECTION_(Name) __attribute__((section("__DATA," Name))) +# define SECTION_SUFFIX_ +# elif CR_IS_MSVC +# define SECTION_START_PREFIX __start +# define SECTION_END_PREFIX __stop +# define SECTION_START_SUFFIX(Name) +# define SECTION_END_SUFFIX(Name) +# define SECTION_(Name) \ + __pragma(data_seg(push)) \ + __pragma(section(Name, read)) \ + __declspec(allocate(Name)) +# define SECTION_SUFFIX_ \ + __pragma(data_seg(pop)) # else # define SECTION_START_PREFIX __start # define SECTION_END_PREFIX __stop # define SECTION_START_SUFFIX(Name) # define SECTION_END_SUFFIX(Name) # define SECTION_(Name) __attribute__((section(Name))) +# define SECTION_SUFFIX_ # endif # define MAKE_IDENTIFIER_(Prefix, Id) MAKE_IDENTIFIER__(Prefix, Id) @@ -56,8 +88,16 @@ Type *const SECTION_START(Name) = &SECTION_START_(Name); \ Type *const SECTION_END(Name) = &SECTION_END_(Name) -# define UNUSED __attribute__((unused)) -# define NORETURN __attribute__((noreturn)) +# ifdef __GNUC__ +# define UNUSED __attribute__((unused)) +# define NORETURN __attribute__((noreturn)) +# elif CR_IS_MSVC +# define UNUSED +# define NORETURN __declspec(noreturn) +# else +# define UNUSED +# define NORETURN +# endif # ifdef _WIN32 # define SIZE_T_FORMAT "%Iu" diff --git a/include/criterion/criterion.h b/include/criterion/criterion.h index c26ad26..e68f841 100644 --- a/include/criterion/criterion.h +++ b/include/criterion/criterion.h @@ -36,7 +36,7 @@ # define SUITE_IDENTIFIER_(Name, Suffix) \ suite_ ## Name ## _ ## Suffix -# define Test(...) Test_(__VA_ARGS__, .sentinel_ = 0) +# define Test(...) CR_EXPAND(Test_(__VA_ARGS__, .sentinel_ = 0)) # define Test_(Category, Name, ...) \ TEST_PROTOTYPE_(Category, Name); \ struct criterion_test_extra_data IDENTIFIER_(Category, Name, extra) = { \ @@ -51,10 +51,10 @@ .category = #Category, \ .test = IDENTIFIER_(Category, Name, impl), \ .data = &IDENTIFIER_(Category, Name, extra) \ - }; \ + } SECTION_SUFFIX_; \ TEST_PROTOTYPE_(Category, Name) -# define TestSuite(...) TestSuite_(__VA_ARGS__, .sentinel_ = 0) +# define TestSuite(...) CR_EXPAND(TestSuite_(__VA_ARGS__, .sentinel_ = 0)) # define TestSuite_(Name, ...) \ struct criterion_test_extra_data SUITE_IDENTIFIER_(Name, extra) = { \ .file_ = __FILE__, \ @@ -65,7 +65,7 @@ const struct criterion_suite SUITE_IDENTIFIER_(Name, meta) = { \ .name = #Name, \ .data = &SUITE_IDENTIFIER_(Name, extra), \ - } + } SECTION_SUFFIX_ int criterion_run_all_tests(void); diff --git a/include/criterion/theories.h b/include/criterion/theories.h index 7d233c9..3f7cd80 100644 --- a/include/criterion/theories.h +++ b/include/criterion/theories.h @@ -69,15 +69,15 @@ void cr_theory_main(struct criterion_datapoints *dps, size_t datapoints, void (* # define CR_VAARG_ID(Suffix, Category, Name, ...) \ IDENTIFIER_(Category, Name, Suffix) -# define Theory(Args, ...) \ - void CR_VAARG_ID(theory, __VA_ARGS__,)Args; \ - Test_(__VA_ARGS__, .sentinel_ = 0) { \ - cr_theory_main( \ - CR_VAARG_ID(dps, __VA_ARGS__,), \ - CR_NB_DATAPOINTS(CR_VAARG_ID(dps, __VA_ARGS__,)), \ - (void(*)(void)) CR_VAARG_ID(theory, __VA_ARGS__,) \ - ); \ - } \ - void CR_VAARG_ID(theory, __VA_ARGS__,)Args +# define Theory(Args, ...) \ + void CR_EXPAND(CR_VAARG_ID(theory, __VA_ARGS__,))Args; \ + CR_EXPAND(Test_(__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 #endif /* !CRITERION_THEORIES_H_ */