diff --git a/CHANGELOG.md b/CHANGELOG.md index 1ac4e4ed..3c6fae73 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,9 @@ ## v1.0.8 +### Features +1. Allow to porting specific interface + ### Fixed 1. Fix: cannot porting `cutest_porting_cvfprintf` diff --git a/include/cutest.h b/include/cutest.h index 0fbb9f82..3fc62df6 100644 --- a/include/cutest.h +++ b/include/cutest.h @@ -41,7 +41,7 @@ extern "C" { /** * @brief Development version. */ -#define CUTEST_VERSION_PREREL 1 +#define CUTEST_VERSION_PREREL 2 /** * @brief Ensure the api is exposed as C function. @@ -1375,9 +1375,18 @@ void cutest_skip_test(void); /** * @defgroup TEST_PORTING_SYSTEM_API System API * - * To use porting interface, add `CUTEST_USE_PORTING` (eg. `-DCUTEST_USE_PORTING`) + * To use porting all the interfaces, add `CUTEST_PORTING` (eg. `-DCUTEST_PORTING`) * when compile [cutest](https://github.com/qgymib/cutest). * + * To use specific porting interface, add one or more flags listed below: + * | Interface | Flag | + * | ------------------------------ | ----------------------------- | + * | cutest_porting_setjmp | CUTEST_PORTING_SETJMP | + * | cutest_porting_clock_gettime | CUTEST_PORTING_CLOCK_GETTIME | + * | cutest_porting_abort | CUTEST_PORTING_ABORT | + * | cutest_porting_gettid | CUTEST_PORTING_GETTID | + * | cutest_porting_cvfprintf | CUTEST_PORTING_CVFPRINTF | + * * @{ */ @@ -1398,34 +1407,51 @@ typedef struct cutest_porting_timespec typedef struct cutest_porting_jmpbuf cutest_porting_jmpbuf_t; /** - * + * @brief Function protocol for longjmp(). + * @param[in] buf Jump buffer. + * @param[in] val Jump value, cannot be 0. + */ +typedef void (*cutest_porting_longjmp_fn)(cutest_porting_jmpbuf_t* buf, int val); + +/** + * @brief Execute function when call setjmp(). + * @param[in] buf Jump buffer. + * @param[in] fn_longjmp Function to do longjmp. + * @param[in] val 0 if first call, otherwise is the value passed to \p fn_longjmp. + * @param[in] data User defined data passed to #cutest_porting_setjmp()/ + */ +typedef void (*cutest_porting_setjmp_fn)(cutest_porting_jmpbuf_t* buf, + cutest_porting_longjmp_fn fn_longjmp, int val, void* data); + +/** + * @brief Wrapper for setjmp() and longjmp(). + * + * A example implementation is: + * * ```c * struct cutest_porting_jmpbuf * { * jmp_buf buf; * }; - * void cutest_porting_setjmp(void (*execute)(cutest_porting_jmpbuf_t* buf, int val, void* data), - * void* data) + * static void _cutest_porting_longjmp(cutest_porting_jmpbuf_t* buf, int val) * { - * cutest_porting_jmpbuf_t jmpbuf; - * execute(&jmpbuf, setjmp(jmpbuf.buf), data); + * longjmp(buf->buf, val); * } - * ``` - * - * @see https://man7.org/linux/man-pages/man3/setjmp.3.html - */ -void cutest_porting_setjmp(void (*execute)(cutest_porting_jmpbuf_t* buf, int val, void* data), void* data); - -/** - * ```c - * void cutest_porting_longjmp(cutest_porting_jmpbuf_t* buf, int val) + * void cutest_porting_setjmp(cutest_porting_setjmp_fn execute, void* data) * { - * longjmp(buf->buf, val); + * cutest_porting_jmpbuf_t jmpbuf; + * + * execute( + * &jmpbuf, + * _cutest_porting_longjmp, + * setjmp(jmpbuf.buf), + * data); * } * ``` - * @see https://man7.org/linux/man-pages/man3/longjmp.3p.html + * + * @see https://man7.org/linux/man-pages/man3/setjmp.3.html */ -void cutest_porting_longjmp(cutest_porting_jmpbuf_t* buf, int val); +void cutest_porting_setjmp(cutest_porting_setjmp_fn execute, void* data); /** * @see https://linux.die.net/man/3/clock_gettime @@ -1434,6 +1460,8 @@ void cutest_porting_clock_gettime(cutest_porting_timespec_t* tp); /** * @see https://man7.org/linux/man-pages/man3/abort.3.html + * @note It is not recommend to ignore last words because that will missing + * something really important. * @param[in] fmt Last words. * @param[in] ... Arguments to last words. * @return This function does not return. @@ -1499,8 +1527,8 @@ int cutest_porting_cvfprintf(FILE* stream, int color, const char* fmt, va_list a * This works fine on most time, but there are indeed some hardware does * not follow this standard, and this technology just broken. * - * To use custom compare algorithm, define `CUTEST_USE_PORTING_FLOATING_COMPARE_ALGORITHM` - * (eg. `-DCUTEST_USE_PORTING_FLOATING_COMPARE_ALGORITHM`) when compile. + * To use custom compare algorithm, define `CUTEST_PORTING_COMPARE_FLOATING_NUMBER` + * (eg. `-DCUTEST_PORTING_COMPARE_FLOATING_NUMBER`) when compile. * * @see https://bitbashing.io/comparing-floats.html * diff --git a/src/cutest.c b/src/cutest.c index 3a016864..ef156ae2 100644 --- a/src/cutest.c +++ b/src/cutest.c @@ -22,6 +22,14 @@ // Porting /////////////////////////////////////////////////////////////////////////////// +#if defined(CUTEST_PORTING) +# define CUTEST_PORTING_SETJMP +# define CUTEST_PORTING_CLOCK_GETTIME +# define CUTEST_PORTING_ABORT +# define CUTEST_PORTING_GETTID +# define CUTEST_PORTING_CVFPRINTF +#endif + /** * @brief Abort the program if assertion \p x is false. * @note This macro does not respect `NDEBUG`. @@ -236,7 +244,7 @@ static char* cutest_porting_strchr(const char* s, int c) * @{ * BEG: cutest_porting_clock_gettime() */ -#if defined(CUTEST_USE_PORTING) +#if defined(CUTEST_PORTING_CLOCK_GETTIME) /* Do nothing */ @@ -358,7 +366,7 @@ void cutest_porting_clock_gettime(cutest_porting_timespec_t* tp) * BEG: cutest_porting_abort() */ -#if defined(CUTEST_USE_PORTING) +#if defined(CUTEST_PORTING_ABORT) /* Do nothing */ @@ -389,7 +397,7 @@ int cutest_porting_abort(const char* fmt, ...) * BEG: cutest_porting_gettid() */ -#if defined(CUTEST_USE_PORTING) +#if defined(CUTEST_PORTING_GETTID) /* Do nothing */ @@ -423,7 +431,7 @@ void* cutest_porting_gettid(void) * BEG: cutest_porting_setjmp() */ -#if defined(CUTEST_USE_PORTING) +#if defined(CUTEST_PORTING_SETJMP) /* Do nothing */ @@ -436,15 +444,18 @@ struct cutest_porting_jmpbuf jmp_buf buf; }; -void cutest_porting_setjmp(void (*execute)(cutest_porting_jmpbuf_t* buf, int val, void* data), void* data) +static void _cutest_porting_longjmp(cutest_porting_jmpbuf_t* buf, int val) { - cutest_porting_jmpbuf_t jmpbuf; - execute(&jmpbuf, setjmp(jmpbuf.buf), data); + longjmp(buf->buf, val); } -void cutest_porting_longjmp(cutest_porting_jmpbuf_t* buf, int val) +void cutest_porting_setjmp(cutest_porting_setjmp_fn execute, void* data) { - longjmp(buf->buf, val); + cutest_porting_jmpbuf_t jmpbuf; + execute(&jmpbuf, + _cutest_porting_longjmp, + setjmp(jmpbuf.buf), + data); } #endif @@ -459,7 +470,7 @@ void cutest_porting_longjmp(cutest_porting_jmpbuf_t* buf, int val) * BEG: cutest_porting_compare_floating_number() */ -#if defined(CUTEST_USE_PORTING_FLOATING_COMPARE_ALGORITHM) +#if defined(CUTEST_PORTING_COMPARE_FLOATING_NUMBER) /* Do nothing */ @@ -697,7 +708,7 @@ int cutest_porting_compare_floating_number(int type, const void* v1, const void* * @{ */ -#if defined(CUTEST_USE_PORTING) +#if defined(CUTEST_PORTING) /* do nothing */ @@ -1762,11 +1773,12 @@ typedef struct test_ctx unsigned shuffle : 1; /**< Randomize running cases */ } mask; - cutest_porting_jmpbuf_t* jmpbuf; /**< Jump buffer */ + cutest_porting_jmpbuf_t* jmpbuf; /**< Jump buffer */ + cutest_porting_longjmp_fn fn_longjmp; /**< Long jmp function. */ FILE* out; const cutest_hook_t* hook; -}test_ctx_t; +} test_ctx_t; static int _cutest_on_cmp_case(const cutest_map_node_t* key1, const cutest_map_node_t* key2, void* arg) { @@ -1815,7 +1827,7 @@ static int _cutest_on_cmp_type(const cutest_map_node_t* key1, const cutest_map_n static test_ctx_t g_test_ctx; static test_nature_t g_test_nature = { TEST_CASE_TABLE_INIT, /* .case_table */ - CUTEST_MAP_INIT(_cutest_on_cmp_type, NULL), /* .type_table */ + CUTEST_MAP_INIT(_cutest_on_cmp_type, NULL), /* .type_table */ }; static const char* s_test_help_encoded = @@ -1997,11 +2009,14 @@ static void _cutest_hook_after_fixture_setup(cutest_case_t* test_case, int ret) g_test_ctx.hook->after_setup(test_case->info.fixture_name, ret); } -static void _cutest_fixture_run_setup_jmp(cutest_porting_jmpbuf_t* buf, int val, void* data) +static void _cutest_fixture_run_setup_jmp(cutest_porting_jmpbuf_t* buf, + cutest_porting_longjmp_fn fn_longjmp, int val, void* data) { fixture_run_helper_t* helper = data; test_case_info_t* info = helper->info; + g_test_ctx.jmpbuf = buf; + g_test_ctx.fn_longjmp = fn_longjmp; if (val != 0) { @@ -2095,10 +2110,13 @@ static void _cutest_hook_after_all_test(void) g_test_ctx.hook->after_all_test(); } -static void _cutest_fixture_run_teardown_jmp(cutest_porting_jmpbuf_t* buf, int val, void* data) +static void _cutest_fixture_run_teardown_jmp(cutest_porting_jmpbuf_t* buf, + cutest_porting_longjmp_fn fn_longjmp, int val, void* data) { test_case_info_t* info = data; + g_test_ctx.jmpbuf = buf; + g_test_ctx.fn_longjmp = fn_longjmp; if (val != 0) { @@ -2155,12 +2173,14 @@ static void _cutest_finishlize(test_case_info_t* info) cutest_porting_cfprintf(g_test_ctx.out, CUTEST_COLOR_DEFAULT, "\n"); } -static void _cutest_run_case_normal_body_jmp(cutest_porting_jmpbuf_t* buf, int val, void* data) +static void _cutest_run_case_normal_body_jmp(cutest_porting_jmpbuf_t* buf, + cutest_porting_longjmp_fn fn_longjmp, int val, void* data) { test_case_helper_t* helper = data; test_case_info_t* info = helper->info; g_test_ctx.jmpbuf = buf; + g_test_ctx.fn_longjmp = fn_longjmp; if (val != 0) { @@ -2271,13 +2291,15 @@ static void _cutest_run_case_normal(cutest_case_t* test_case) _cutest_finishlize(&info); } -static void _cutest_run_case_parameterized_body_jmp(cutest_porting_jmpbuf_t* buf, int val, void* data) +static void _cutest_run_case_parameterized_body_jmp(cutest_porting_jmpbuf_t* buf, + cutest_porting_longjmp_fn fn_longjmp, int val, void* data) { test_run_parameterized_helper_t* helper = data; test_case_info_t* info = helper->info; cutest_case_t* test_case = info->test_case; g_test_ctx.jmpbuf = buf; + g_test_ctx.fn_longjmp = fn_longjmp; if (val != 0) { @@ -3205,7 +3227,7 @@ void cutest_internal_assert_failure(void) } else { - cutest_porting_longjmp(g_test_ctx.jmpbuf, MASK_FAILURE); + g_test_ctx.fn_longjmp(g_test_ctx.jmpbuf, MASK_FAILURE); } }