From a5efcc2c538f583edd03fc9c4ae34334e432880c Mon Sep 17 00:00:00 2001 From: Krzysztof Chruscinski Date: Tue, 12 Feb 2019 14:58:27 +0100 Subject: [PATCH] shell: Add cpp-friendly shell macro for subcommands creation Add macro for creating subcommand set in a way that is accepted by C++ (SHELL_STATIC_SUBCMD_SET_CREATE). Currently, it exists along with SHELL_CREATE_STATIC_SUBCMD_SET which is used in the tree but it is not liked by cpp. Signed-off-by: Krzysztof Chruscinski --- doc/reference/shell/index.rst | 27 +++++++--------- include/shell/shell.h | 58 +++++++++++++++++++++++++---------- 2 files changed, 52 insertions(+), 33 deletions(-) diff --git a/doc/reference/shell/index.rst b/doc/reference/shell/index.rst index 14c4737ac2c..7fa18f6bdb5 100644 --- a/doc/reference/shell/index.rst +++ b/doc/reference/shell/index.rst @@ -86,11 +86,9 @@ Use the following macros for adding shell commands: All root commands must have different name. * :c:macro:`SHELL_CMD` - Initialize a command. * :c:macro:`SHELL_CMD_ARG` - Initialize a command with arguments. -* :c:macro:`SHELL_CREATE_STATIC_SUBCMD_SET` - Create a static subcommands +* :c:macro:`SHELL_STATIC_SUBCMD_SET_CREATE` - Create a static subcommands array. -* :c:macro:`SHELL_SUBCMD_SET_END` - shall be placed as last in - :c:macro:`SHELL_CREATE_STATIC_SUBCMD_SET` macro. -* :c:macro:`SHELL_CREATE_DYNAMIC_CMD` - Create a dynamic subcommands array. +* :c:macro:`SHELL_DYNAMIC_CMD_CREATE` - Create a dynamic subcommands array. Commands can be created in any file in the system that includes :file:`include/shell/shell.h`. All created commands are available for all @@ -109,13 +107,12 @@ subcommands. .. code-block:: c /* Creating subcommands (level 1 command) array for command "demo". */ - SHELL_CREATE_STATIC_SUBCMD_SET(sub_demo) - { + SHELL_STATIC_SUBCMD_SET_CREATE(sub_demo, SHELL_CMD(params, NULL, "Print params command.", cmd_demo_params), SHELL_CMD(ping, NULL, "Ping command.", cmd_demo_ping), - SHELL_SUBCMD_SET_END /* Array terminated. */ - }; + SHELL_SUBCMD_SET_END + ); /* Creating root (level 0) command "demo" */ SHELL_CMD_REGISTER(demo, &sub_demo, "Demo commands", NULL); @@ -166,9 +163,8 @@ Newly added commands can be prompted or autocompleted with the :kbd:`Tab` key. } } - SHELL_CREATE_DYNAMIC_CMD(m_sub_dynamic_set, dynamic_cmd_get); - SHELL_CREATE_STATIC_SUBCMD_SET(m_sub_dynamic) - { + SHELL_DYNAMIC_CMD_CREATE(m_sub_dynamic_set, dynamic_cmd_get); + SHELL_STATIC_SUBCMD_SET_CREATE(m_sub_dynamic, SHELL_CMD(add, NULL,"Add new command to dynamic_cmd_buffer and" " sort them alphabetically.", cmd_dynamic_add), @@ -181,7 +177,7 @@ Newly added commands can be prompted or autocompleted with the :kbd:`Tab` key. "Show all commands in dynamic_cmd_buffer.", cmd_dynamic_show), SHELL_SUBCMD_SET_END - }; + ); SHELL_CMD_REGISTER(dynamic, &m_sub_dynamic, "Demonstrate dynamic command usage.", cmd_dynamic); @@ -405,13 +401,12 @@ The following code shows a simple use case of this library: } /* Creating subcommands (level 1 command) array for command "demo". */ - SHELL_CREATE_STATIC_SUBCMD_SET(sub_demo) - { + SHELL_STATIC_SUBCMD_SET_CREATE(sub_demo, SHELL_CMD(params, NULL, "Print params command.", cmd_demo_params), SHELL_CMD(ping, NULL, "Ping command.", cmd_demo_ping), - SHELL_SUBCMD_SET_END /* Array terminated. */ - }; + SHELL_SUBCMD_SET_END + ); /* Creating root (level 0) command "demo" without a handler */ SHELL_CMD_REGISTER(demo, &sub_demo, "Demo commands", NULL); diff --git a/include/shell/shell.h b/include/shell/shell.h index 891e7ed1973..befc09de78d 100644 --- a/include/shell/shell.h +++ b/include/shell/shell.h @@ -71,17 +71,6 @@ struct shell_cmd_entry { struct shell; -/** - * @brief Initializes a shell command arguments - * - * @param[in] _mandatory Number of mandatory arguments. - * @param[in] _optional Number of optional arguments. - */ -#define SHELL_ARG(_mandatory, _optional) { \ - .mandatory = _mandatory, \ - .optional = _optional, \ -} - struct shell_static_args { u8_t mandatory; /*!< Number of mandatory arguments. */ u8_t optional; /*!< Number of optional arguments. */ @@ -137,7 +126,7 @@ struct shell_static_entry { STRINGIFY(UTIL_CAT(shell_root_cmd_, syntax))))) \ __attribute__((used)) = { \ .is_dynamic = false, \ - .u.entry = &UTIL_CAT(_shell_, syntax) \ + .u = {.entry = &UTIL_CAT(_shell_, syntax)} \ } /** @@ -159,7 +148,32 @@ struct shell_static_entry { STRINGIFY(UTIL_CAT(shell_root_cmd_, syntax))))) \ __attribute__((used)) = { \ .is_dynamic = false, \ - .u.entry = &UTIL_CAT(_shell_, syntax) \ + .u = { .entry = &UTIL_CAT(_shell_, syntax) } \ + } + +/** + * @brief Macro for creating a subcommand set. It must be used outside of any + * function body. + * + * Example usage: + * SHELL_STATIC_SUBCMD_SET_CREATE( + * foo, + * SHELL_CMD(abc, ...), + * SHELL_CMD(def, ...), + * SHELL_SUBCMD_SET_END + * ) + * + * @param[in] name Name of the subcommand set. + * @param[in] ... List of commands created with @ref SHELL_CMD_ARG or + * or @ref SHELL_CMD + */ +#define SHELL_STATIC_SUBCMD_SET_CREATE(name, ...) \ + static const struct shell_static_entry shell_##name[] = { \ + __VA_ARGS__ \ + }; \ + static const struct shell_cmd_entry name = { \ + .is_dynamic = false, \ + .u = { .entry = shell_##name } \ } /** @@ -176,6 +190,7 @@ struct shell_static_entry { }; \ static const struct shell_static_entry shell_##name[] = + /** * @brief Define ending subcommands set. * @@ -188,12 +203,21 @@ struct shell_static_entry { * @param[in] name Name of the dynamic entry. * @param[in] get Pointer to the function returning dynamic commands array */ -#define SHELL_CREATE_DYNAMIC_CMD(name, get) \ +#define SHELL_DYNAMIC_CMD_CREATE(name, get) \ static const struct shell_cmd_entry name = { \ .is_dynamic = true, \ - .u.dynamic_get = get \ + .u = { .dynamic_get = get } \ } +/** + * @brief Macro for creating a dynamic entry. + * + * @param[in] name Name of the dynamic entry. + * @param[in] get Pointer to the function returning dynamic commands array + */ +#define SHELL_CREATE_DYNAMIC_CMD(name, get) \ + SHELL_DYNAMIC_CMD_CREATE(name, get) + /** * @brief Initializes a shell command with arguments. * @@ -210,10 +234,10 @@ struct shell_static_entry { #define SHELL_CMD_ARG(_syntax, _subcmd, _help, _handler, \ _mandatory, _optional) { \ .syntax = (const char *)STRINGIFY(_syntax), \ - .subcmd = _subcmd, \ .help = (const char *)_help, \ + .subcmd = _subcmd, \ .handler = _handler, \ - .args = SHELL_ARG(_mandatory, _optional) \ + .args = {. mandatory = _mandatory, .optional = _optional} \ } /**