diff --git a/doc/hooks.rst b/doc/hooks.rst index 1450305..dc476b8 100644 --- a/doc/hooks.rst +++ b/doc/hooks.rst @@ -22,14 +22,14 @@ Testing Phases The flow of the test process goes as follows: -1. ``PRE_EVERYTHING``: occurs before running the tests. +1. ``PRE_ALL``: occurs before running the tests. #. ``PRE_INIT``: occurs before a test is initialized. #. ``PRE_TEST``: occurs after the test initialization, but before the test is run. #. ``ASSERT``: occurs when an assertion is hit #. ``TEST_CRASH``: occurs when a test crashes unexpectedly. #. ``POST_TEST``: occurs after a test ends, but before the test finalization. #. ``POST_FINI``: occurs after a test finalization. -#. ``POST_EVERYTHING``: occurs after all the tests are done. +#. ``POST_ALL``: occurs after all the tests are done. Hook Parameters --------------- @@ -43,6 +43,6 @@ Valid types for each phases are: * ``struct criterion_test *`` for ``PRE_INIT`` and ``PRE_TEST``. * ``struct criterion_test_stats *`` for ``POST_TEST``, ``POST_FINI``, and ``TEST_CRASH``. * ``struct criterion_assert_stats *`` for ``ASSERT``. -* ``struct criterion_global_stats *`` for ``POST_EVERYTHING``. +* ``struct criterion_global_stats *`` for ``POST_ALL``. -``PRE_EVERYTHING`` does not take any parameter. +``PRE_ALL`` does not take any parameter. diff --git a/include/criterion/common.h b/include/criterion/common.h index 30995eb..e7c80b4 100644 --- a/include/criterion/common.h +++ b/include/criterion/common.h @@ -24,7 +24,37 @@ #ifndef CRITERION_COMMON_H_ # define CRITERION_COMMON_H_ -# define SECTION_(Name) __attribute__((section(Name))) +# 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))) +# else +# define SECTION_START_PREFIX __start +# define SECTION_END_PREFIX __stop +# define SECTION_START_SUFFIX +# define SECTION_END_SUFFIX +# define SECTION_(Name) __attribute__((section(Name))) +# endif + +# define MAKE_IDENTIFIER_(Prefix, Id) MAKE_IDENTIFIER__(Prefix, Id) +# define MAKE_IDENTIFIER__(Prefix, Id) Prefix ## _ ## Id + +# define SECTION_START_(Name) MAKE_IDENTIFIER_(SECTION_START_PREFIX, Name) +# define SECTION_END_(Name) MAKE_IDENTIFIER_(SECTION_END_PREFIX, Name) + +# define SECTION_START(Name) g_ ## Name ## _section_start +# define SECTION_END(Name) g_ ## Name ## _section_end + +# define DECL_SECTION_LIMITS(Type, Name) \ + extern Type SECTION_START_(Name) SECTION_START_SUFFIX(#Name); \ + extern Type SECTION_END_(Name) SECTION_END_SUFFIX(#Name) + +# define IMPL_SECTION_LIMITS(Type, Name) \ + Type *const SECTION_START(Name) = &SECTION_START_(Name); \ + Type *const SECTION_END(Name) = &SECTION_END_(Name) + # define UNUSED __attribute__((unused)) # ifdef __GNUC__ diff --git a/include/criterion/hooks.h b/include/criterion/hooks.h index 129e7c1..d427eab 100644 --- a/include/criterion/hooks.h +++ b/include/criterion/hooks.h @@ -27,14 +27,14 @@ #include "common.h" typedef enum { - PRE_EVERYTHING, + PRE_ALL, PRE_INIT, PRE_TEST, ASSERT, TEST_CRASH, POST_TEST, POST_FINI, - POST_EVERYTHING, + POST_ALL, } e_report_status; typedef void (*f_report_hook)(); @@ -48,7 +48,7 @@ typedef void (*f_report_hook)(); # define ReportHook(Kind) \ HOOK_PROTOTYPE_(); \ - SECTION_("criterion_hooks_" #Kind) \ + SECTION_("crit_" #Kind) \ const f_report_hook HOOK_IDENTIFIER_(func) = HOOK_IDENTIFIER_(impl); \ HOOK_PROTOTYPE_ diff --git a/samples/report.c b/samples/report.c index e806322..5c92b90 100644 --- a/samples/report.c +++ b/samples/report.c @@ -15,10 +15,10 @@ ReportHook(POST_TEST)(struct criterion_test_stats *stats) { stats->passed_asserts, stats->failed_asserts, stats->passed_asserts + stats->failed_asserts); } -ReportHook(PRE_EVERYTHING)() { +ReportHook(PRE_ALL)() { puts("criterion_init"); } -ReportHook(POST_EVERYTHING)() { +ReportHook(POST_ALL)() { puts("criterion_fini"); } diff --git a/src/report.c b/src/report.c index b3c0751..b10b26f 100644 --- a/src/report.c +++ b/src/report.c @@ -29,13 +29,10 @@ #include "report.h" #define IMPL_CALL_REPORT_HOOKS(Kind) \ - static f_report_hook * const g_##Kind##_section_start = \ - &__start_criterion_hooks_##Kind; \ - static f_report_hook * const g_##Kind##_section_end = \ - &__stop_criterion_hooks_##Kind; \ + IMPL_SECTION_LIMITS(f_report_hook, Kind); \ void call_report_hooks_##Kind(void *data) { \ - for (f_report_hook *hook = g_##Kind##_section_start;\ - hook < g_##Kind##_section_end; \ + for (f_report_hook *hook = SECTION_START(Kind); \ + hook < SECTION_END(Kind); \ ++hook) { \ (*hook)(data); \ } \ @@ -43,14 +40,14 @@ static size_t tap_test_index = 1; -IMPL_CALL_REPORT_HOOKS(PRE_EVERYTHING); +IMPL_CALL_REPORT_HOOKS(PRE_ALL); IMPL_CALL_REPORT_HOOKS(PRE_INIT); IMPL_CALL_REPORT_HOOKS(PRE_TEST); IMPL_CALL_REPORT_HOOKS(ASSERT); IMPL_CALL_REPORT_HOOKS(TEST_CRASH); IMPL_CALL_REPORT_HOOKS(POST_TEST); IMPL_CALL_REPORT_HOOKS(POST_FINI); -IMPL_CALL_REPORT_HOOKS(POST_EVERYTHING); +IMPL_CALL_REPORT_HOOKS(POST_ALL); ReportHook(PRE_INIT)(struct criterion_test *test) { if (criterion_options.enable_tap_format) return; @@ -90,7 +87,7 @@ ReportHook(POST_TEST)(struct criterion_test_stats *stats) { ReportHook(PRE_TEST)() {} ReportHook(POST_FINI)() {} -ReportHook(PRE_EVERYTHING)(struct criterion_test_set *set) { +ReportHook(PRE_ALL)(struct criterion_test_set *set) { if (criterion_options.enable_tap_format) { size_t enabled_count = 0, i = 0; for (struct criterion_test **test = set->tests; i < set->nb_tests; ++i) @@ -99,7 +96,7 @@ ReportHook(PRE_EVERYTHING)(struct criterion_test_set *set) { criterion_important("1..%lu\n", enabled_count); } } -ReportHook(POST_EVERYTHING)(struct criterion_global_stats *stats) { +ReportHook(POST_ALL)(struct criterion_global_stats *stats) { if (criterion_options.enable_tap_format) return; criterion_important("Synthesis: %lu tests were run. %lu passed, %lu failed (with %lu crashes)\n", diff --git a/src/report.h b/src/report.h index 4b02caa..5ab5d4c 100644 --- a/src/report.h +++ b/src/report.h @@ -28,18 +28,17 @@ # define report(Kind, Data) call_report_hooks_##Kind(Data) -# define DECL_CALL_REPORT_HOOKS(Kind) \ - extern f_report_hook __start_criterion_hooks_##Kind; \ - extern f_report_hook __stop_criterion_hooks_##Kind; \ +# define DECL_CALL_REPORT_HOOKS(Kind) \ + DECL_SECTION_LIMITS(f_report_hook, Kind); \ void call_report_hooks_##Kind(void *data) -DECL_CALL_REPORT_HOOKS(PRE_EVERYTHING); +DECL_CALL_REPORT_HOOKS(PRE_ALL); DECL_CALL_REPORT_HOOKS(PRE_INIT); DECL_CALL_REPORT_HOOKS(PRE_TEST); DECL_CALL_REPORT_HOOKS(ASSERT); DECL_CALL_REPORT_HOOKS(TEST_CRASH); DECL_CALL_REPORT_HOOKS(POST_TEST); DECL_CALL_REPORT_HOOKS(POST_FINI); -DECL_CALL_REPORT_HOOKS(POST_EVERYTHING); +DECL_CALL_REPORT_HOOKS(POST_ALL); #endif /* !REPORT_H_ */ diff --git a/src/runner.c b/src/runner.c index 706adf1..21ab2ef 100644 --- a/src/runner.c +++ b/src/runner.c @@ -34,8 +34,7 @@ #include "event.h" #include "process.h" -static struct criterion_test * const g_section_start = &__start_criterion_tests; -static struct criterion_test * const g_section_end = &__stop_criterion_tests; +IMPL_SECTION_LIMITS(struct criterion_test, criterion_tests); static int compare_test(const void *a, const void *b) { struct criterion_test *first = *(struct criterion_test **) a; @@ -56,14 +55,14 @@ static void destroy_test_set(void *ptr, UNUSED void *meta) { } static struct criterion_test_set *read_all_tests(void) { - size_t nb_tests = g_section_end - g_section_start; + size_t nb_tests = SECTION_END(criterion_tests) - SECTION_START(criterion_tests); struct criterion_test **tests = malloc(nb_tests * sizeof (void *)); if (tests == NULL) return NULL; size_t i = 0; - for (struct criterion_test *test = g_section_start; test < g_section_end; ++test) + for (struct criterion_test *test = SECTION_START(criterion_tests); test < SECTION_END(criterion_tests); ++test) tests[i++] = test; qsort(tests, nb_tests, sizeof (void *), compare_test); @@ -141,7 +140,7 @@ static void run_test(struct criterion_global_stats *stats, struct criterion_test static int criterion_run_all_tests_impl(void) { smart struct criterion_test_set *set = read_all_tests(); - report(PRE_EVERYTHING, set); + report(PRE_ALL, set); set_runner_pid(); smart struct criterion_global_stats *stats = stats_init(); @@ -152,7 +151,7 @@ static int criterion_run_all_tests_impl(void) { if (!is_runner()) return -1; - report(POST_EVERYTHING, stats); + report(POST_ALL, stats); return stats->tests_failed > 0; } diff --git a/src/runner.h b/src/runner.h index 6723104..10ccfbb 100644 --- a/src/runner.h +++ b/src/runner.h @@ -26,7 +26,6 @@ # include "criterion/criterion.h" -extern struct criterion_test __start_criterion_tests; -extern struct criterion_test __stop_criterion_tests; +DECL_SECTION_LIMITS(struct criterion_test, criterion_tests); #endif /* !CRITERION_RUNNER_H_ */ diff --git a/src/stats.c b/src/stats.c index 24199ad..ab67456 100644 --- a/src/stats.c +++ b/src/stats.c @@ -64,14 +64,14 @@ void stat_push_event(s_glob_stats *stats, s_test_stats *test, struct event *data) { static void (*const handles[])(s_glob_stats *, s_test_stats *, void *) = { - nothing, // PRE_EVERYTHING + nothing, // PRE_ALL nothing, // PRE_INIT push_pre_test, // PRE_TEST push_assert, // ASSERT push_test_crash, // TEST_CRASH push_post_test, // POST_TEST nothing, // POST_FINI - nothing, // POST_EVERYTHING + nothing, // POST_ALL }; assert(data->kind > 0);