From 9d3237c89e58161a10917cb0d06a395ed31841e1 Mon Sep 17 00:00:00 2001 From: Szymon Janc Date: Mon, 3 Sep 2018 16:02:42 +0200 Subject: [PATCH] shell: Add support for custom line2argv callback This allows to define shells which are using different syntax for commands parsing eg. foocmd=param1,param2. This is usefull for providing compatibility with existing external tools while allowing to use Zephyr's shell subsystem. Signed-off-by: Szymon Janc --- include/shell/shell.h | 24 ++++++++++++++++++++++-- subsys/shell/shell.c | 6 +++++- 2 files changed, 27 insertions(+), 3 deletions(-) diff --git a/include/shell/shell.h b/include/shell/shell.h index 56c31341d65..cb4ff879ecf 100644 --- a/include/shell/shell.h +++ b/include/shell/shell.h @@ -38,10 +38,21 @@ struct shell_cmd { */ typedef const char *(*shell_prompt_function_t)(void); +/** @brief Callback for custom line2argv parsing + * + * If this callback is set, command parsing for specified module works only + * if it is selected as default module. This is to not break other modules. + * + * @returns Current prompt string. + */ +typedef size_t (*shell_line2argv_function_t)(char *str, char *argv[], + size_t size); + struct shell_module { const char *module_name; const struct shell_cmd *commands; shell_prompt_function_t prompt; + shell_line2argv_function_t line2argv; }; /** @typedef shell_mcumgr_function_t @@ -109,15 +120,24 @@ typedef int (*shell_mcumgr_function_t)(const char *line, void *arg); */ #ifdef CONFIG_CONSOLE_SHELL #define SHELL_REGISTER(_name, _commands) \ - SHELL_REGISTER_WITH_PROMPT(_name, _commands, NULL) + SHELL_REGISTER_WITH_PROMPT_AND_LINE2ARGV(_name, _commands, NULL, NULL) #define SHELL_REGISTER_WITH_PROMPT(_name, _commands, _prompt) \ + SHELL_REGISTER_WITH_PROMPT_AND_LINE2ARGV(_name, _commands, _prompt, NULL) + +#define SHELL_REGISTER_WITH_LINE2ARGV(_name, _commands, _line2argv) \ + SHELL_REGISTER_WITH_PROMPT_AND_LINE2ARGV(_name, _commands, NULL, \ + _line2argv) + +#define SHELL_REGISTER_WITH_PROMPT_AND_LINE2ARGV(_name, _commands, _prompt, \ + _line2argv) \ \ static struct shell_module (__shell__name) __used \ __attribute__((__section__(".shell_module_"))) = { \ .module_name = _name, \ .commands = _commands, \ - .prompt = _prompt \ + .prompt = _prompt, \ + .line2argv = _line2argv, \ } #define SHELL_REGISTER_COMMAND(name, callback, _help) \ diff --git a/subsys/shell/shell.c b/subsys/shell/shell.c index 542d625e3d9..32c95843868 100644 --- a/subsys/shell/shell.c +++ b/subsys/shell/shell.c @@ -371,7 +371,11 @@ int shell_exec(char *line) const struct shell_cmd *cmd; int argc, err; - argc = line2argv(line, argv, ARRAY_SIZE(argv)); + if (default_module && default_module->line2argv) { + argc = default_module->line2argv(line, argv, ARRAY_SIZE(argv)); + } else { + argc = line2argv(line, argv, ARRAY_SIZE(argv)); + } if (!argc) { return -EINVAL; }