diff --git a/CMakeLists.txt b/CMakeLists.txt index f6f8349..6e644a8 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -169,4 +169,5 @@ endif() if (CMAKE_PROJECT_NAME STREQUAL PROJECT_NAME AND BUILD_TESTING) add_subdirectory(example) add_subdirectory(test) + add_subdirectory(test2) endif() diff --git a/test2/CMakeLists.txt b/test2/CMakeLists.txt new file mode 100644 index 0000000..bbdfcb4 --- /dev/null +++ b/test2/CMakeLists.txt @@ -0,0 +1,19 @@ +add_executable(cutest_test + tools/__init__.c + tools/help.c + main.c + test.c +) +target_include_directories(cutest_test + PUBLIC + $ + PRIVATE + ${CMAKE_CURRENT_SOURCE_DIR} +) +target_link_libraries(cutest_test + PRIVATE + cutest +) +cutest_setup_target_wall(cutest_test) + +add_test(NAME cutest_test COMMAND $) diff --git a/test2/main.c b/test2/main.c new file mode 100644 index 0000000..776f22d --- /dev/null +++ b/test2/main.c @@ -0,0 +1,6 @@ +#include "test.h" + +int main(int argc, char* argv[]) +{ + return cutest_run_tests(argc, argv, stdout, &test_hook); +} diff --git a/test2/test.c b/test2/test.c new file mode 100644 index 0000000..dd5d8dd --- /dev/null +++ b/test2/test.c @@ -0,0 +1,38 @@ +#include +#include +#include "tools/__init__.h" +#include "test.h" + +static const char* s_tool_help = +"missing argument after `--`, use `-- help` (pay attention to the space) to see\n" +"what tools builtin.\n" +; + +static void _before_all_test(int argc, char* argv[]) +{ + int i; + for (i = 0; i < argc; i++) + { + if (strcmp(argv[i], "--") == 0) + { + if (i == argc - 1) + { + fprintf(stderr, "%s", s_tool_help); + exit(EXIT_FAILURE); + } + + exit(test_tool_exec(argc - i - 1, argv + i + 1)); + } + } +} + +const cutest_hook_t test_hook = { + _before_all_test, /* .before_all_test */ + NULL, /* .after_all_test */ + NULL, /* .before_setup */ + NULL, /* .after_setup */ + NULL, /* .before_teardown */ + NULL, /* .after_teardown */ + NULL, /* .before_test */ + NULL, /* .after_test */ +}; diff --git a/test2/test.h b/test2/test.h new file mode 100644 index 0000000..a4cc4b3 --- /dev/null +++ b/test2/test.h @@ -0,0 +1,18 @@ +#ifndef __CUTEST_TEST_H__ +#define __CUTEST_TEST_H__ + +#include "cutest.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @brief Global test hook. + */ +extern const cutest_hook_t test_hook; + +#ifdef __cplusplus +} +#endif +#endif diff --git a/test2/tools/__init__.c b/test2/tools/__init__.c new file mode 100644 index 0000000..51cddd4 --- /dev/null +++ b/test2/tools/__init__.c @@ -0,0 +1,41 @@ +#include +#include +#include "__init__.h" +#include "test.h" + +extern const test_tool_t test_tool_help; + +static const test_tool_t* const g_command_table[] = { + &test_tool_help, +}; + +int test_tool_exec(int argc, char* argv[]) +{ + size_t i; + for (i = 0; i < TEST_ARRAY_SIZE(g_command_table); i++) + { + if (strcmp(argv[0], g_command_table[i]->cmd) != 0) + { + continue; + } + + return g_command_table[i]->proc(argc, argv); + } + + fprintf(stderr, "%s: command not found\n", argv[0]); + fflush(NULL); + + return EXIT_FAILURE; +} + +void test_tool_foreach(int (*cb)(const test_tool_t*, void*), void* arg) +{ + size_t i; + for (i = 0; i < TEST_ARRAY_SIZE(g_command_table); i++) + { + if (cb(g_command_table[i], arg)) + { + return; + } + } +} diff --git a/test2/tools/__init__.h b/test2/tools/__init__.h new file mode 100644 index 0000000..fa58a1b --- /dev/null +++ b/test2/tools/__init__.h @@ -0,0 +1,20 @@ +#ifndef __CUTEST_TEST_TOOL_INIT_H__ +#define __CUTEST_TEST_TOOL_INIT_H__ +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct test_tool +{ + const char* cmd; + int (*proc)(int argc, char* argv[]); + const char* help; +} test_tool_t; + +int test_tool_exec(int argc, char* argv[]); +void test_tool_foreach(int (*cb)(const test_tool_t*, void*), void* arg); + +#ifdef __cplusplus +} +#endif +#endif diff --git a/test2/tools/help.c b/test2/tools/help.c new file mode 100644 index 0000000..95b4fa0 --- /dev/null +++ b/test2/tools/help.c @@ -0,0 +1,72 @@ +#include +#include +#include "__init__.h" + +static const char* s_help_str = +"This program contains tests written using cutest. You can use the\n" +"following command line flags to control its behavior:\n" +"\n" +"Test Selection:\n" +" --help\n" +" Show what features cutest support.\n" +"\n" +"Tool Selection:\n" +" --\n" +" By using `-- [CMD]` (pay attention to the space) you are able to launch\n" +" builtin tools. Anything followed by `--` will be treat as command\n" +" arguments to builtin tools. After builtin tools finished, the program\n" +" will exit.\n" +; + +static void _print_help(const char* help, const char* prefix) +{ + size_t i; + int flag_need_prefix = 1; + + for (i = 0; help[i] != '\0'; i++) + { + if (flag_need_prefix) + { + flag_need_prefix = 0; + printf("%s", prefix); + } + + printf("%c", help[i]); + + if (help[i] == '\n') + { + flag_need_prefix = 1; + } + } + + printf("\n"); +} + +static int _print_tools(const test_tool_t* info, void* arg) +{ + (void)arg; + + printf(" -- %s\n", info->cmd); + if (info->help != NULL) + { + _print_help(info->help, " "); + } + return 0; +} + +static int _tool_help(int argc, char* argv[]) +{ + (void)argc; (void)argv; + + printf("%s", s_help_str); + test_tool_foreach(_print_tools, NULL); + + fflush(NULL); + + return EXIT_SUCCESS; +} + +const test_tool_t test_tool_help = { + "help", _tool_help, + "Show this help and exit." +};