Currently when using hooks the function prototypes turn into the following: hook_l<line_num>_impl. This ends up causing the following issues:
- When you create a custom macro with a bunch of calls to
ReportHook you get a compiler error for multiple definitions as all of the macros expand to the same line. Example below:
#define HOOK_CONTAINER \
ReportHook(PRE_INIT)(struct criterion_test *test) { \
... \
} \
ReportHook(PRE_TEST)(struct criterion_test *test) { \
... \
}
HOOK_CONTAINER
- When you have several files and by chance in two different files you invoke
ReportHook on the same line you also get the same compiler issue for multiple definitions. Example below:
file_1.c
// Line 1 of the file
ReportHook(PRE_INIT)(struct criterion_test *test) {
...
}
file_2.c
// Line 1 of the file
ReportHook(PRE_INIT)(struct criterion_test *test) {
...
}
The following fix should solve all of these issues, if the function prototype were to expand to the following:
hook_l<line_num>_c<count>_<optional_id>_impl
which could be done with the possible code change:
include/criterion/internal/hooks.h
#define CR_HOOK_IDENTIFIER_(Cnt, Suffix, ...) CR_HOOK_IDENTIFIER__(__LINE__, Cnt, CR_VA_HEAD(__VA_ARGS__), Suffix)
#define CR_HOOK_IDENTIFIER__(Line, Cnt, Opt_Id, Suffix) CR_HOOK_IDENTIFIER___(Line, Cnt, Opt_Id, Suffix)
#define CR_HOOK_IDENTIFIER___(Line, Cnt, Opt_Id, Suffix) hook_l ## Line ## _c ## Cnt ## _ ## Opt_Id ## _ ## Suffix
#ifdef __cplusplus
# define CR_HOOK_PROTOTYPE_(Cnt, ...) \
extern "C" void CR_HOOK_IDENTIFIER_(Cnt, impl, __VA_ARGS__)
#else
# define CR_HOOK_PROTOTYPE_(Cnt, ...) \
void CR_HOOK_IDENTIFIER_(Cnt, impl, __VA_ARGS__)
#endif
include/criterion/internal/hooks.h
#define CR_REPORT_HOOK_IMPL(Kind, Cnt, ...) \
CR_HOOK_PROTOTYPE_(Cnt, __VA_ARGS__)(CR_HOOK_PARAM_TYPE(Kind)); \
CR_SECTION_(CR_HOOK_SECTION_STRINGIFY(Kind)) \
f_report_hook CR_HOOK_IDENTIFIER_(Cnt, func, __VA_ARGS__) = \
(f_report_hook) CR_HOOK_IDENTIFIER_(Cnt, impl, __VA_ARGS__) \
CR_SECTION_SUFFIX_; \
CR_HOOK_PROTOTYPE_(Cnt, __VA_ARGS__)
include/criterion/hooks.h
/**
* ReportHook(Kind)(Type *param) { Function Body }
*
* Defines a report hook for the phase defined by Kind.
*
* The type of the parameter depends on the phase:
*
* - struct criterion_test_set for PRE_ALL.
* - struct criterion_suite_set for PRE_SUITE.
* - struct criterion_test for PRE_INIT and PRE_TEST.
* - struct criterion_assert_stats for ASSERT.
* - struct criterion_theory_stats for THEORY_FAIL.
* - struct criterion_test_stats for POST_TEST, POST_FINI, and TEST_CRASH.
* - struct criterion_suite_stats for POST_SUITE.
* - struct criterion_global_stats for POST_ALL.
*
* @param Kind The report phase to hook the function onto.
* @param ... Optional Hook Id to distinguish between hooks on the same line.
*
* @note __COUNTER__ is used to reduce the chance the developer needs to provide an optional hook id.
*/
#define ReportHook(Kind, ...) CR_REPORT_HOOK_IMPL(Kind, __COUNTER__, __VA_ARGS__)
Might require some other changes but this is a base to work from.
Currently when using hooks the function prototypes turn into the following:
hook_l<line_num>_impl. This ends up causing the following issues:ReportHookyou get a compiler error for multiple definitions as all of the macros expand to the same line. Example below:ReportHookon the same line you also get the same compiler issue for multiple definitions. Example below:file_1.c
file_2.c
The following fix should solve all of these issues, if the function prototype were to expand to the following:
which could be done with the possible code change:
include/criterion/internal/hooks.h
include/criterion/internal/hooks.h
include/criterion/hooks.h
Might require some other changes but this is a base to work from.