shell: creating new module for help functionality

1. Created new shell module: shell_help.
2. Simplified command handlers with new shell print macros.
3. Removed help functions from command handlers.

Signed-off-by: Jakub Rzeszutko <jakub.rzeszutko@nordicsemi.no>
This commit is contained in:
Jakub Rzeszutko 2018-11-26 17:09:56 +01:00 committed by Carles Cufí
commit 3064ca4f2f
27 changed files with 686 additions and 956 deletions

View file

@ -216,8 +216,6 @@ static int cmd_test(const struct shell *shell, size_t argc, char *argv[])
return 0; return 0;
} }
#define HELP_NONE "[none]"
SHELL_CREATE_STATIC_SUBCMD_SET(flash_cmds) { SHELL_CREATE_STATIC_SUBCMD_SET(flash_cmds) {
SHELL_CMD(erase, NULL, "<page address> <size>", cmd_erase), SHELL_CMD(erase, NULL, "<page address> <size>", cmd_erase),
SHELL_CMD(read, NULL, "<address> <Dword count>", cmd_read), SHELL_CMD(read, NULL, "<address> <Dword count>", cmd_read),
@ -228,22 +226,9 @@ SHELL_CREATE_STATIC_SUBCMD_SET(flash_cmds) {
static int cmd_flash(const struct shell *shell, size_t argc, char **argv) static int cmd_flash(const struct shell *shell, size_t argc, char **argv)
{ {
int err; error(shell, "%s:unknown parameter: %s", argv[0], argv[1]);
if (argc == 1) {
shell_help_print(shell);
/* shell_cmd_precheck returns 1 when help is printed */
return 1;
}
err = shell_cmd_precheck(shell, argc == 2);
if (err) {
return err;
}
error(shell, "%s:%s%s", argv[0], "unknown parameter: ", argv[1]);
return -EINVAL; return -EINVAL;
} }
SHELL_CMD_REGISTER(flash, &flash_cmds, "Flash shell commands", SHELL_CMD_ARG_REGISTER(flash, &flash_cmds, "Flash shell commands",
cmd_flash); cmd_flash, 2, 0);

View file

@ -119,14 +119,14 @@ struct shell_static_entry {
*/ */
#define SHELL_CMD_ARG_REGISTER(syntax, subcmd, help, handler, \ #define SHELL_CMD_ARG_REGISTER(syntax, subcmd, help, handler, \
mandatory, optional) \ mandatory, optional) \
static const struct shell_static_entry UTIL_CAT(shell_, syntax) = \ static const struct shell_static_entry UTIL_CAT(_shell_, syntax) = \
SHELL_CMD_ARG(syntax, subcmd, help, handler, mandatory, optional); \ SHELL_CMD_ARG(syntax, subcmd, help, handler, mandatory, optional); \
static const struct shell_cmd_entry UTIL_CAT(shell_cmd_, syntax) \ static const struct shell_cmd_entry UTIL_CAT(shell_cmd_, syntax) \
__attribute__ ((section("." \ __attribute__ ((section("." \
STRINGIFY(UTIL_CAT(shell_root_cmd_, syntax))))) \ STRINGIFY(UTIL_CAT(shell_root_cmd_, syntax))))) \
__attribute__((used)) = { \ __attribute__((used)) = { \
.is_dynamic = false, \ .is_dynamic = false, \
.u.entry = &UTIL_CAT(shell_, syntax) \ .u.entry = &UTIL_CAT(_shell_, syntax) \
} }
/** /**
@ -141,14 +141,14 @@ struct shell_static_entry {
* @param[in] handler Pointer to a function handler. * @param[in] handler Pointer to a function handler.
*/ */
#define SHELL_CMD_REGISTER(syntax, subcmd, help, handler) \ #define SHELL_CMD_REGISTER(syntax, subcmd, help, handler) \
static const struct shell_static_entry UTIL_CAT(shell_, syntax) = \ static const struct shell_static_entry UTIL_CAT(_shell_, syntax) = \
SHELL_CMD(syntax, subcmd, help, handler); \ SHELL_CMD(syntax, subcmd, help, handler); \
static const struct shell_cmd_entry UTIL_CAT(shell_cmd_, syntax) \ static const struct shell_cmd_entry UTIL_CAT(shell_cmd_, syntax) \
__attribute__ ((section("." \ __attribute__ ((section("." \
STRINGIFY(UTIL_CAT(shell_root_cmd_, syntax))))) \ STRINGIFY(UTIL_CAT(shell_root_cmd_, syntax))))) \
__attribute__((used)) = { \ __attribute__((used)) = { \
.is_dynamic = false, \ .is_dynamic = false, \
.u.entry = &UTIL_CAT(shell_, syntax) \ .u.entry = &UTIL_CAT(_shell_, syntax) \
} }
/** /**
@ -440,6 +440,8 @@ struct shell {
k_thread_stack_t *stack; k_thread_stack_t *stack;
}; };
extern void shell_print_stream(const void *user_ctx, const char *data,
size_t data_len);
/** /**
* @brief Macro for defining a shell instance. * @brief Macro for defining a shell instance.
* *
@ -614,16 +616,6 @@ void shell_fprintf(const struct shell *shell, enum shell_vt100_color color,
*/ */
void shell_process(const struct shell *shell); void shell_process(const struct shell *shell);
/**
* @brief Prints the current command help.
*
* Function will print a help string with the currently entered command and
* its subcommands (if exist).
*
* @param[in] shell Pointer to the shell instance.
*/
void shell_help_print(const struct shell *shell);
/** /**
* @brief Change displayed shell prompt. * @brief Change displayed shell prompt.
* *
@ -636,30 +628,14 @@ void shell_help_print(const struct shell *shell);
int shell_prompt_change(const struct shell *shell, char *prompt); int shell_prompt_change(const struct shell *shell, char *prompt);
/** /**
* @brief Prints help if requested and prints error message on wrong argument * @brief Prints the current command help.
* count.
* Optionally, printing help on wrong argument count can be enabled.
* *
* @param[in] shell Pointer to the shell instance. * Function will print a help string with: the currently entered command
* @param[in] arg_cnt_ok Flag indicating valid number of arguments. * and subcommands (if they exist).
* *
* @return 0 if check passed * @param[in] shell Pointer to the shell instance.
* @return 1 if help was requested
* @return -EINVAL if wrong argument count
*/ */
int shell_cmd_precheck(const struct shell *shell, void shell_help_print(const struct shell *shell);
bool arg_cnt_ok);
/**
* @internal @brief This function shall not be used directly, it is required by
* the fprintf module.
*
* @param[in] p_user_ctx Pointer to the context for the shell instance.
* @param[in] p_data Pointer to the data buffer.
* @param[in] data_len Data buffer size.
*/
void shell_print_stream(const void *user_ctx, const char *data,
size_t data_len);
/** @brief Execute command. /** @brief Execute command.
* *

View file

@ -76,7 +76,6 @@ void shell_fprintf_fmt(const struct shell_fprintf *sh_fprintf,
*/ */
void shell_fprintf_buffer_flush(const struct shell_fprintf *sh_fprintf); void shell_fprintf_buffer_flush(const struct shell_fprintf *sh_fprintf);
#ifdef __cplusplus #ifdef __cplusplus
} }
#endif #endif

View file

@ -3,7 +3,6 @@
* *
* SPDX-License-Identifier: Apache-2.0 * SPDX-License-Identifier: Apache-2.0
*/ */
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
@ -241,15 +240,11 @@ static int cmd_flash(const struct shell *shell, size_t argc, char **argv)
static int cmd_write_block_size(const struct shell *shell, size_t argc, static int cmd_write_block_size(const struct shell *shell, size_t argc,
char **argv) char **argv)
{ {
ARG_UNUSED(argc);
ARG_UNUSED(argv); ARG_UNUSED(argv);
int err = shell_cmd_precheck(shell, argc == 1); int err = check_flash_device(shell);
if (err) {
return err;
}
err = check_flash_device(shell);
if (!err) { if (!err) {
PR_SHELL(shell, "%d\n", PR_SHELL(shell, "%d\n",
flash_get_write_block_size(flash_device)); flash_get_write_block_size(flash_device));
@ -260,19 +255,13 @@ static int cmd_write_block_size(const struct shell *shell, size_t argc,
static int cmd_read(const struct shell *shell, size_t argc, char **argv) static int cmd_read(const struct shell *shell, size_t argc, char **argv)
{ {
int err = check_flash_device(shell);
int err = shell_cmd_precheck(shell, argc == 3);
unsigned long int offset, len; unsigned long int offset, len;
if (err) { if (err) {
goto exit; goto exit;
} }
err = check_flash_device(shell);
if (err) {
goto exit;
}
if (parse_ul(argv[1], &offset) || parse_ul(argv[2], &len)) { if (parse_ul(argv[1], &offset) || parse_ul(argv[2], &len)) {
PR_ERROR(shell, "Invalid arguments.\n"); PR_ERROR(shell, "Invalid arguments.\n");
err = -EINVAL; err = -EINVAL;
@ -287,18 +276,14 @@ exit:
static int cmd_erase(const struct shell *shell, size_t argc, char **argv) static int cmd_erase(const struct shell *shell, size_t argc, char **argv)
{ {
int err = shell_cmd_precheck(shell, argc == 3); int err = check_flash_device(shell);
unsigned long int offset, size; unsigned long int offset;
unsigned long int size;
if (err) { if (err) {
goto exit; goto exit;
} }
err = check_flash_device(shell);
if (err) {
goto exit;
}
if (parse_ul(argv[1], &offset) || parse_ul(argv[2], &size)) { if (parse_ul(argv[1], &offset) || parse_ul(argv[2], &size)) {
PR_ERROR(shell, "Invalid arguments.\n"); PR_ERROR(shell, "Invalid arguments.\n");
err = -EINVAL; err = -EINVAL;
@ -312,15 +297,11 @@ exit:
static int cmd_write(const struct shell *shell, size_t argc, char **argv) static int cmd_write(const struct shell *shell, size_t argc, char **argv)
{ {
int err = shell_cmd_precheck(shell, argc > 2);
unsigned long int i, offset; unsigned long int i, offset;
u8_t buf[ARGC_MAX]; u8_t buf[ARGC_MAX];
if (err) { int err = check_flash_device(shell);
goto exit;
}
err = check_flash_device(shell);
if (err) { if (err) {
goto exit; goto exit;
} }
@ -365,15 +346,11 @@ exit:
static int cmd_page_count(const struct shell *shell, size_t argc, char **argv) static int cmd_page_count(const struct shell *shell, size_t argc, char **argv)
{ {
ARG_UNUSED(argv); ARG_UNUSED(argv);
ARG_UNUSED(argc);
int err = shell_cmd_precheck(shell, argc == 1); int err = check_flash_device(shell);
size_t page_count; size_t page_count;
if (err) {
return err;
}
err = check_flash_device(shell);
if (!err) { if (!err) {
page_count = flash_get_page_count(flash_device); page_count = flash_get_page_count(flash_device);
PR_SHELL(shell, "Flash device contains %lu pages.\n", PR_SHELL(shell, "Flash device contains %lu pages.\n",
@ -409,15 +386,11 @@ static bool page_layout_cb(const struct flash_pages_info *info, void *datav)
static int cmd_page_layout(const struct shell *shell, size_t argc, char **argv) static int cmd_page_layout(const struct shell *shell, size_t argc, char **argv)
{ {
int err = shell_cmd_precheck(shell, argc <= 3);
unsigned long int start_page, end_page; unsigned long int start_page, end_page;
struct page_layout_data data; struct page_layout_data data;
if (err) { int err = check_flash_device(shell);
return err;
}
err = check_flash_device(shell);
if (err) { if (err) {
goto bail; goto bail;
} }
@ -463,12 +436,6 @@ static int cmd_page_read(const struct shell *shell, size_t argc, char **argv)
struct flash_pages_info info; struct flash_pages_info info;
int ret; int ret;
ret = shell_cmd_precheck(shell, argc == 3 || argc == 4);
if (ret) {
return ret;
}
ret = check_flash_device(shell); ret = check_flash_device(shell);
if (ret) { if (ret) {
return ret; return ret;
@ -512,11 +479,6 @@ static int cmd_page_erase(const struct shell *shell, size_t argc, char **argv)
return ret; return ret;
} }
ret = shell_cmd_precheck(shell, argc == 2 || argc == 3);
if (ret) {
return ret;
}
if (parse_ul(argv[1], &page)) { if (parse_ul(argv[1], &page)) {
ret = -EINVAL; ret = -EINVAL;
goto bail; goto bail;
@ -563,15 +525,11 @@ static int cmd_page_write(const struct shell *shell, size_t argc, char **argv)
return ret; return ret;
} }
ret = shell_cmd_precheck(shell, argc > 2); if (parse_ul(argv[1], &page) || parse_ul(argv[2], &off)) {
if (ret) {
return ret;
}
if (argc < 2 || parse_ul(argv[1], &page) || parse_ul(argv[2], &off)) {
ret = -EINVAL; ret = -EINVAL;
goto bail; goto bail;
} }
argc -= 3; argc -= 3;
argv += 3; argv += 3;
for (i = 0; i < argc; i++) { for (i = 0; i < argc; i++) {
@ -601,12 +559,6 @@ static int cmd_set_dev(const struct shell *shell, size_t argc, char **argv)
{ {
struct device *dev; struct device *dev;
const char *name; const char *name;
int ret;
ret = shell_cmd_precheck(shell, argc == 2);
if (ret) {
return ret;
}
name = argv[1]; name = argv[1];
@ -642,19 +594,21 @@ void main(void)
SHELL_CREATE_STATIC_SUBCMD_SET(sub_flash) SHELL_CREATE_STATIC_SUBCMD_SET(sub_flash)
{ {
/* Alphabetically sorted to ensure correct Tab autocompletion. */ /* Alphabetically sorted to ensure correct Tab autocompletion. */
SHELL_CMD(erase, NULL, ERASE_HELP, cmd_erase), SHELL_CMD_ARG(erase, NULL, ERASE_HELP, cmd_erase, 3, 0),
#ifdef CONFIG_FLASH_PAGE_LAYOUT #ifdef CONFIG_FLASH_PAGE_LAYOUT
SHELL_CMD(page_count, NULL, PAGE_COUNT_HELP, cmd_page_count), SHELL_CMD_ARG(page_count, NULL, PAGE_COUNT_HELP, cmd_page_count, 1, 0),
SHELL_CMD(page_errase, NULL, PAGE_ERASE_HELP, cmd_page_erase), SHELL_CMD_ARG(page_erase, NULL, PAGE_ERASE_HELP, cmd_page_erase, 2, 1),
SHELL_CMD(page_layout, NULL, PAGE_LAYOUT_HELP, cmd_page_layout), SHELL_CMD_ARG(page_layout, NULL, PAGE_LAYOUT_HELP,
SHELL_CMD(page_read, NULL, PAGE_READ_HELP, cmd_page_read), cmd_page_layout, 1, 2),
SHELL_CMD(page_write, NULL, PAGE_WRITE_HELP, cmd_page_write), SHELL_CMD_ARG(page_read, NULL, PAGE_READ_HELP, cmd_page_read, 3, 1),
SHELL_CMD_ARG(page_write, NULL, PAGE_WRITE_HELP,
cmd_page_write, 3, 255),
#endif #endif
SHELL_CMD(read, NULL, READ_HELP, cmd_read), SHELL_CMD_ARG(read, NULL, READ_HELP, cmd_read, 3, 0),
SHELL_CMD(set_device, NULL, SET_DEV_HELP, cmd_set_dev), SHELL_CMD_ARG(set_device, NULL, SET_DEV_HELP, cmd_set_dev, 2, 0),
SHELL_CMD(write, NULL, WRITE_HELP, cmd_write), SHELL_CMD_ARG(write, NULL, WRITE_HELP, cmd_write, 3, 255),
SHELL_CMD(write_block_size, NULL, WRITE_BLOCK_SIZE_HELP, SHELL_CMD_ARG(write_block_size, NULL, WRITE_BLOCK_SIZE_HELP,
cmd_write_block_size), cmd_write_block_size, 1, 0),
SHELL_SUBCMD_SET_END /* Array terminated. */ SHELL_SUBCMD_SET_END /* Array terminated. */
}; };

View file

@ -134,18 +134,6 @@ static int cmd_mtest(const struct shell *shell, size_t argc, char *argv[])
{ {
u32_t *mem; u32_t *mem;
u32_t val; u32_t val;
int err;
if (argc > 3) {
PR_ERROR(shell, "mtest accepts 1 (Read) or 2 (Write)"
"parameters\n");
return -EINVAL;
}
err = shell_cmd_precheck(shell, (argc >= 2) && (argc <= 3));
if (err) {
return err;
}
val = (u32_t)strtol(argv[1], NULL, 16); val = (u32_t)strtol(argv[1], NULL, 16);
mem = (u32_t *) val; mem = (u32_t *) val;
@ -166,7 +154,7 @@ void main(void)
SHELL_CREATE_STATIC_SUBCMD_SET(sub_mpu) SHELL_CREATE_STATIC_SUBCMD_SET(sub_mpu)
{ {
SHELL_CMD(mtest, NULL, MTEST_CMD_HELP, cmd_mtest), SHELL_CMD_ARG(mtest, NULL, MTEST_CMD_HELP, cmd_mtest, 2, 1),
SHELL_CMD(read, NULL, READ_CMD_HELP, cmd_read), SHELL_CMD(read, NULL, READ_CMD_HELP, cmd_read),
SHELL_CMD(run, NULL, RUN_CMD_HELP, cmd_run), SHELL_CMD(run, NULL, RUN_CMD_HELP, cmd_run),
#if defined(CONFIG_SOC_FLASH_MCUX) #if defined(CONFIG_SOC_FLASH_MCUX)

View file

@ -19,24 +19,6 @@ static u8_t dynamic_cmd_cnt;
typedef int cmp_t(const void *, const void *); typedef int cmp_t(const void *, const void *);
extern void qsort(void *a, size_t n, size_t es, cmp_t *cmp); extern void qsort(void *a, size_t n, size_t es, cmp_t *cmp);
static int cmd_dynamic(const struct shell *shell, size_t argc, char **argv)
{
if ((argc == 1)) {
shell_help_print(shell);
return 0;
}
if (argc > 2) {
shell_fprintf(shell, SHELL_ERROR,
"%s: bad parameter count\r\n", argv[0]);
} else {
shell_fprintf(shell, SHELL_ERROR,
"%s: please specify subcommand\r\n", argv[0]);
}
return -ENOEXEC;
}
/* function required by qsort */ /* function required by qsort */
static int string_cmp(const void *p_a, const void *p_b) static int string_cmp(const void *p_a, const void *p_b)
{ {
@ -46,40 +28,35 @@ static int string_cmp(const void *p_a, const void *p_b)
static int cmd_dynamic_add(const struct shell *shell, static int cmd_dynamic_add(const struct shell *shell,
size_t argc, char **argv) size_t argc, char **argv)
{ {
u8_t idx;
u16_t cmd_len; u16_t cmd_len;
u8_t idx;
if (argc != 2) { ARG_UNUSED(argc);
shell_fprintf(shell, SHELL_ERROR,
"%s: bad parameter count\r\n", argv[0]);
return -ENOEXEC;
}
if (dynamic_cmd_cnt >= MAX_CMD_CNT) { if (dynamic_cmd_cnt >= MAX_CMD_CNT) {
shell_fprintf(shell, SHELL_ERROR, "command limit reached\r\n"); shell_error(shell, "command limit reached");
return -ENOEXEC; return -ENOEXEC;
} }
cmd_len = strlen(argv[1]); cmd_len = strlen(argv[1]);
if (cmd_len >= MAX_CMD_LEN) { if (cmd_len >= MAX_CMD_LEN) {
shell_fprintf(shell, SHELL_ERROR, "too long command\r\n"); shell_error(shell, "too long command");
return -ENOEXEC; return -ENOEXEC;
} }
for (idx = 0U; idx < cmd_len; idx++) { for (idx = 0U; idx < cmd_len; idx++) {
if (!isalnum((int)(argv[1][idx]))) { if (!isalnum((int)(argv[1][idx]))) {
shell_fprintf(shell, SHELL_ERROR, shell_error(shell,
"bad command name - please use only" "bad command name - please use only"
" alphanumerical characters\r\n"); " alphanumerical characters");
return -ENOEXEC; return -ENOEXEC;
} }
} }
for (idx = 0U; idx < MAX_CMD_CNT; idx++) { for (idx = 0U; idx < MAX_CMD_CNT; idx++) {
if (!strcmp(dynamic_cmd_buffer[idx], argv[1])) { if (!strcmp(dynamic_cmd_buffer[idx], argv[1])) {
shell_fprintf(shell, SHELL_ERROR, shell_error(shell, "duplicated command");
"duplicated command\r\n");
return -ENOEXEC; return -ENOEXEC;
} }
} }
@ -89,32 +66,7 @@ static int cmd_dynamic_add(const struct shell *shell,
qsort(dynamic_cmd_buffer, dynamic_cmd_cnt, qsort(dynamic_cmd_buffer, dynamic_cmd_cnt,
sizeof(dynamic_cmd_buffer[0]), string_cmp); sizeof(dynamic_cmd_buffer[0]), string_cmp);
shell_fprintf(shell, SHELL_NORMAL, "command added successfully\r\n"); shell_print(shell, "command added successfully");
return 0;
}
static int cmd_dynamic_show(const struct shell *shell,
size_t argc, char **argv)
{
if (argc != 1) {
shell_fprintf(shell, SHELL_ERROR,
"%s: bad parameter count\r\n", argv[0]);
return -ENOEXEC;
}
if (dynamic_cmd_cnt == 0) {
shell_fprintf(shell, SHELL_WARNING,
"Please add some commands first.\r\n");
return -ENOEXEC;
}
shell_fprintf(shell, SHELL_NORMAL, "Dynamic command list:\r\n");
for (u8_t i = 0; i < dynamic_cmd_cnt; i++) {
shell_fprintf(shell, SHELL_NORMAL,
"[%3d] %s\r\n", i, dynamic_cmd_buffer[i]);
}
return 0; return 0;
} }
@ -122,22 +74,17 @@ static int cmd_dynamic_show(const struct shell *shell,
static int cmd_dynamic_execute(const struct shell *shell, static int cmd_dynamic_execute(const struct shell *shell,
size_t argc, char **argv) size_t argc, char **argv)
{ {
if (argc != 2) { ARG_UNUSED(argc);
shell_fprintf(shell, SHELL_ERROR, ARG_UNUSED(argv);
"%s: bad parameter count\r\n", argv[0]);
return -ENOEXEC;
}
for (u8_t idx = 0; idx < dynamic_cmd_cnt; idx++) { for (u8_t idx = 0; idx < dynamic_cmd_cnt; idx++) {
if (!strcmp(dynamic_cmd_buffer[idx], argv[1])) { if (!strcmp(dynamic_cmd_buffer[idx], argv[1])) {
shell_fprintf(shell, SHELL_NORMAL, shell_print(shell, "dynamic command: %s", argv[1]);
"dynamic command: %s\r\n", argv[1]);
return 0; return 0;
} }
} }
shell_fprintf(shell, SHELL_ERROR, shell_error(shell, "%s: uknown parameter: %s", argv[0], argv[1]);
"%s: uknown parameter: %s\r\n", argv[0], argv[1]);
return -ENOEXEC; return -ENOEXEC;
} }
@ -145,16 +92,8 @@ static int cmd_dynamic_execute(const struct shell *shell,
static int cmd_dynamic_remove(const struct shell *shell, size_t argc, static int cmd_dynamic_remove(const struct shell *shell, size_t argc,
char **argv) char **argv)
{ {
if (argc == 1) { ARG_UNUSED(argc);
shell_help_print(shell); ARG_UNUSED(argv);
return 0;
}
if (argc != 2) {
shell_fprintf(shell, SHELL_ERROR,
"%s: bad parameter count\r\n", argv[0]);
return -ENOEXEC;
}
for (u8_t idx = 0; idx < dynamic_cmd_cnt; idx++) { for (u8_t idx = 0; idx < dynamic_cmd_cnt; idx++) {
if (!strcmp(dynamic_cmd_buffer[idx], argv[1])) { if (!strcmp(dynamic_cmd_buffer[idx], argv[1])) {
@ -168,17 +107,35 @@ static int cmd_dynamic_remove(const struct shell *shell, size_t argc,
} }
--dynamic_cmd_cnt; --dynamic_cmd_cnt;
shell_fprintf(shell, SHELL_NORMAL, shell_print(shell, "command removed successfully");
"command removed successfully\r\n");
return 0; return 0;
} }
} }
shell_fprintf(shell, SHELL_ERROR, shell_error(shell, "did not find command: %s", argv[1]);
"did not find command: %s\r\n", argv[1]);
return -ENOEXEC; return -ENOEXEC;
} }
static int cmd_dynamic_show(const struct shell *shell,
size_t argc, char **argv)
{
ARG_UNUSED(argc);
ARG_UNUSED(argv);
if (dynamic_cmd_cnt == 0) {
shell_warn(shell, "Please add some commands first.");
return -ENOEXEC;
}
shell_print(shell, "Dynamic command list:");
for (u8_t i = 0; i < dynamic_cmd_cnt; i++) {
shell_print(shell, "[%3d] %s", i, dynamic_cmd_buffer[i]);
}
return 0;
}
/* dynamic command creation */ /* dynamic command creation */
static void dynamic_cmd_get(size_t idx, struct shell_static_entry *entry) static void dynamic_cmd_get(size_t idx, struct shell_static_entry *entry)
{ {
@ -201,21 +158,21 @@ static void dynamic_cmd_get(size_t idx, struct shell_static_entry *entry)
SHELL_CREATE_DYNAMIC_CMD(m_sub_dynamic_set, dynamic_cmd_get); SHELL_CREATE_DYNAMIC_CMD(m_sub_dynamic_set, dynamic_cmd_get);
SHELL_CREATE_STATIC_SUBCMD_SET(m_sub_dynamic) SHELL_CREATE_STATIC_SUBCMD_SET(m_sub_dynamic)
{ {
SHELL_CMD(add, NULL, SHELL_CMD_ARG(add, NULL,
"Add a new dynamic command.\nExample usage: [ dynamic add test " "Add a new dynamic command.\nExample usage: [ dynamic add test "
"] will add a dynamic command 'test'.\nIn this example, command" "] will add a dynamic command 'test'.\nIn this example, command"
" name length is limited to 32 chars. You can add up to 20" " name length is limited to 32 chars. You can add up to 20"
" commands. Commands are automatically sorted to ensure correct" " commands. Commands are automatically sorted to ensure correct"
" shell completion.", " shell completion.",
cmd_dynamic_add), cmd_dynamic_add, 2, 0),
SHELL_CMD(execute, &m_sub_dynamic_set, SHELL_CMD_ARG(execute, &m_sub_dynamic_set,
"Execute a command.", cmd_dynamic_execute), "Execute a command.", cmd_dynamic_execute, 2, 0),
SHELL_CMD(remove, &m_sub_dynamic_set, SHELL_CMD_ARG(remove, &m_sub_dynamic_set,
"Remove a command.", cmd_dynamic_remove), "Remove a command.", cmd_dynamic_remove, 2, 0),
SHELL_CMD(show, NULL, SHELL_CMD_ARG(show, NULL,
"Show all added dynamic commands.", cmd_dynamic_show), "Show all added dynamic commands.", cmd_dynamic_show, 1, 0),
SHELL_SUBCMD_SET_END SHELL_SUBCMD_SET_END
}; };
SHELL_CMD_REGISTER(dynamic, &m_sub_dynamic, SHELL_CMD_REGISTER(dynamic, &m_sub_dynamic,
"Demonstrate dynamic command usage.", cmd_dynamic); "Demonstrate dynamic command usage.", NULL);

View file

@ -31,29 +31,22 @@ static int cmd_log_test_start(const struct shell *shell, size_t argc,
{ {
ARG_UNUSED(argv); ARG_UNUSED(argv);
int err = shell_cmd_precheck(shell, argc == 1);
if (err) {
return err;
}
k_timer_start(&log_timer, period, period); k_timer_start(&log_timer, period, period);
shell_fprintf(shell, SHELL_NORMAL, "Log test started\n"); shell_print(shell, "Log test started\n");
return 0; return 0;
} }
static int cmd_log_test_start_demo(const struct shell *shell, size_t argc, static int cmd_log_test_start_demo(const struct shell *shell, size_t argc,
char **argv) char **argv)
{ {
cmd_log_test_start(shell, argc, argv, 200); return cmd_log_test_start(shell, argc, argv, 200);
return 0;
} }
static int cmd_log_test_start_flood(const struct shell *shell, size_t argc, static int cmd_log_test_start_flood(const struct shell *shell, size_t argc,
char **argv) char **argv)
{ {
cmd_log_test_start(shell, argc, argv, 10); return cmd_log_test_start(shell, argc, argv, 10);
return 0;
} }
static int cmd_log_test_stop(const struct shell *shell, size_t argc, static int cmd_log_test_stop(const struct shell *shell, size_t argc,
@ -62,33 +55,28 @@ static int cmd_log_test_stop(const struct shell *shell, size_t argc,
ARG_UNUSED(argc); ARG_UNUSED(argc);
ARG_UNUSED(argv); ARG_UNUSED(argv);
int err = shell_cmd_precheck(shell, argc == 1);
if (err) {
return err;
}
k_timer_stop(&log_timer); k_timer_stop(&log_timer);
shell_fprintf(shell, SHELL_NORMAL, "Log test stopped\n"); shell_print(shell, "Log test stopped");
return 0; return 0;
} }
SHELL_CREATE_STATIC_SUBCMD_SET(sub_log_test_start) SHELL_CREATE_STATIC_SUBCMD_SET(sub_log_test_start)
{ {
/* Alphabetically sorted. */ /* Alphabetically sorted. */
SHELL_CMD(demo, NULL, SHELL_CMD_ARG(demo, NULL,
"Start log timer which generates log message every 200ms.", "Start log timer which generates log message every 200ms.",
cmd_log_test_start_demo), cmd_log_test_start_demo, 1, 0),
SHELL_CMD(flood, NULL, SHELL_CMD_ARG(flood, NULL,
"Start log timer which generates log message every 10ms.", "Start log timer which generates log message every 10ms.",
cmd_log_test_start_flood), cmd_log_test_start_flood, 1, 0),
SHELL_SUBCMD_SET_END /* Array terminated. */ SHELL_SUBCMD_SET_END /* Array terminated. */
}; };
SHELL_CREATE_STATIC_SUBCMD_SET(sub_log_test) SHELL_CREATE_STATIC_SUBCMD_SET(sub_log_test)
{ {
/* Alphabetically sorted. */ /* Alphabetically sorted. */
SHELL_CMD(start, &sub_log_test_start, "Start log test", NULL), SHELL_CMD_ARG(start, &sub_log_test_start, "Start log test", NULL, 2, 0),
SHELL_CMD(stop, NULL, "Stop log test.", cmd_log_test_stop), SHELL_CMD_ARG(stop, NULL, "Stop log test.", cmd_log_test_stop, 1, 0),
SHELL_SUBCMD_SET_END /* Array terminated. */ SHELL_SUBCMD_SET_END /* Array terminated. */
}; };
@ -99,20 +87,18 @@ static int cmd_demo_ping(const struct shell *shell, size_t argc, char **argv)
ARG_UNUSED(argc); ARG_UNUSED(argc);
ARG_UNUSED(argv); ARG_UNUSED(argv);
shell_fprintf(shell, SHELL_NORMAL, "pong\n"); shell_print(shell, "pong");
return 0; return 0;
} }
static int cmd_demo_params(const struct shell *shell, size_t argc, char **argv) static int cmd_demo_params(const struct shell *shell, size_t argc, char **argv)
{ {
int cnt; shell_print(shell, "argc = %d", argc);
for (size_t cnt = 0; cnt < argc; cnt++) {
shell_fprintf(shell, SHELL_NORMAL, "argc = %d\n", argc); shell_print(shell, " argv[%d] = %s", cnt, argv[cnt]);
for (cnt = 0; cnt < argc; cnt++) {
shell_fprintf(shell, SHELL_NORMAL,
" argv[%d] = %s\n", cnt, argv[cnt]);
} }
return 0; return 0;
} }
@ -121,8 +107,8 @@ static int cmd_version(const struct shell *shell, size_t argc, char **argv)
ARG_UNUSED(argc); ARG_UNUSED(argc);
ARG_UNUSED(argv); ARG_UNUSED(argv);
shell_fprintf(shell, SHELL_NORMAL, shell_print(shell, "Zephyr version %s", KERNEL_VERSION_STRING);
"Zephyr version %s\n", KERNEL_VERSION_STRING);
return 0; return 0;
} }
@ -135,8 +121,7 @@ SHELL_CREATE_STATIC_SUBCMD_SET(sub_demo)
}; };
SHELL_CMD_REGISTER(demo, &sub_demo, "Demo commands", NULL); SHELL_CMD_REGISTER(demo, &sub_demo, "Demo commands", NULL);
SHELL_CMD_REGISTER(version, NULL, "Show kernel version", cmd_version); SHELL_CMD_ARG_REGISTER(version, NULL, "Show kernel version", cmd_version, 1, 0);
void main(void) void main(void)
{ {

View file

@ -1574,12 +1574,6 @@ static int cmd_provision(const struct shell *shell, size_t argc, char *argv[])
int cmd_timeout(const struct shell *shell, size_t argc, char *argv[]) int cmd_timeout(const struct shell *shell, size_t argc, char *argv[])
{ {
s32_t timeout; s32_t timeout;
int err;
err = shell_cmd_precheck(shell, (argc >= 1));
if (err) {
return err;
}
if (argc < 2) { if (argc < 2) {
timeout = bt_mesh_cfg_cli_timeout_get(); timeout = bt_mesh_cfg_cli_timeout_get();
@ -1619,11 +1613,6 @@ static int cmd_fault_get(const struct shell *shell, size_t argc, char *argv[])
u16_t cid; u16_t cid;
int err; int err;
err = shell_cmd_precheck(shell, (argc == 1));
if (err) {
return err;
}
cid = strtoul(argv[1], NULL, 0); cid = strtoul(argv[1], NULL, 0);
fault_count = sizeof(faults); fault_count = sizeof(faults);
@ -2043,7 +2032,7 @@ static int cmd_mesh(const struct shell *shell, size_t argc, char **argv)
{ {
if (argc == 1) { if (argc == 1) {
shell_help_print(shell); shell_help_print(shell);
/* shell_cmd_precheck returns 1 when help is printed */ /* shell returns 1 when help is printed */
return 1; return 1;
} }

View file

@ -552,7 +552,7 @@ static int cmd_br(const struct shell *shell, size_t argc, char **argv)
{ {
if (argc == 1) { if (argc == 1) {
shell_help_print(shell); shell_help_print(shell);
/* shell_cmd_precheck returns 1 when help is printed */ /* shell returns 1 when help is printed */
return 1; return 1;
} }

View file

@ -614,7 +614,7 @@ static int cmd_scan(const struct shell *shell, size_t argc, char *argv[])
dups = BT_HCI_LE_SCAN_FILTER_DUP_ENABLE; dups = BT_HCI_LE_SCAN_FILTER_DUP_ENABLE;
} else { } else {
shell_help_print(shell); shell_help_print(shell);
/* shell_cmd_precheck returns 1 when help is printed */ /* shell returns 1 when help is printed */
return 1; return 1;
} }
} }
@ -628,7 +628,7 @@ static int cmd_scan(const struct shell *shell, size_t argc, char *argv[])
return cmd_passive_scan_on(shell, dups); return cmd_passive_scan_on(shell, dups);
} else { } else {
shell_help_print(shell); shell_help_print(shell);
/* shell_cmd_precheck returns 1 when help is printed */ /* shell returns 1 when help is printed */
return 1; return 1;
} }
@ -747,7 +747,7 @@ static int cmd_disconnect(const struct shell *shell, size_t argc, char *argv[])
if (argc < 3) { if (argc < 3) {
shell_help_print(shell); shell_help_print(shell);
/* shell_cmd_precheck returns 1 when help is printed */ /* shell returns 1 when help is printed */
return 1; return 1;
} }
@ -796,7 +796,7 @@ static int cmd_auto_conn(const struct shell *shell, size_t argc, char *argv[])
return bt_le_set_auto_conn(&addr, NULL); return bt_le_set_auto_conn(&addr, NULL);
} else { } else {
shell_help_print(shell); shell_help_print(shell);
/* shell_cmd_precheck returns 1 when help is printed */ /* shell returns 1 when help is printed */
return 1; return 1;
} }
@ -823,7 +823,7 @@ static int cmd_directed_adv(const struct shell *shell,
if (strcmp(argv[3], "low")) { if (strcmp(argv[3], "low")) {
shell_help_print(shell); shell_help_print(shell);
/* shell_cmd_precheck returns 1 when help is printed */ /* shell returns 1 when help is printed */
return 1; return 1;
} }
@ -1015,7 +1015,7 @@ static int cmd_bondable(const struct shell *shell, size_t argc, char *argv[])
bt_set_bondable(false); bt_set_bondable(false);
} else { } else {
shell_help_print(shell); shell_help_print(shell);
/* shell_cmd_precheck returns 1 when help is printed */ /* shell returns 1 when help is printed */
return 1; return 1;
} }
@ -1209,7 +1209,7 @@ static int cmd_auth(const struct shell *shell, size_t argc, char *argv[])
bt_conn_auth_cb_register(NULL); bt_conn_auth_cb_register(NULL);
} else { } else {
shell_help_print(shell); shell_help_print(shell);
/* shell_cmd_precheck returns 1 when help is printed */ /* shell returns 1 when help is printed */
return 1; return 1;
} }
@ -1390,7 +1390,7 @@ static int cmd_bt(const struct shell *shell, size_t argc, char **argv)
{ {
if (argc == 1) { if (argc == 1) {
shell_help_print(shell); shell_help_print(shell);
/* shell_cmd_precheck returns 1 when help is printed */ /* shell returns 1 when help is printed */
return 1; return 1;
} }

View file

@ -797,7 +797,7 @@ static int cmd_gatt(const struct shell *shell, size_t argc, char **argv)
{ {
if (argc == 1) { if (argc == 1) {
shell_help_print(shell); shell_help_print(shell);
/* shell_cmd_precheck returns 1 when help is printed */ /* shell returns 1 when help is printed */
return 1; return 1;
} }

View file

@ -417,7 +417,7 @@ static int cmd_l2cap(const struct shell *shell, size_t argc, char **argv)
{ {
if (argc == 1) { if (argc == 1) {
shell_help_print(shell); shell_help_print(shell);
/* shell_cmd_precheck returns 1 when help is printed */ /* shell returns 1 when help is printed */
return 1; return 1;
} }

View file

@ -245,7 +245,7 @@ static int cmd_rfcomm(const struct shell *shell, size_t argc, char **argv)
{ {
if (argc == 1) { if (argc == 1) {
shell_help_print(shell); shell_help_print(shell);
/* shell_cmd_precheck returns 1 when help is printed */ /* shell returns 1 when help is printed */
return 1; return 1;
} }

View file

@ -136,7 +136,7 @@ static int cmd_ticker(const struct shell *shell, size_t argc, char **argv)
{ {
if (argc == 1) { if (argc == 1) {
shell_help_print(shell); shell_help_print(shell);
/* shell_cmd_precheck returns 1 when help is printed */ /* shell returns 1 when help is printed */
return 1; return 1;
} }

View file

@ -166,11 +166,6 @@ static int cmd_trunc(const struct shell *shell, size_t argc, char **argv)
int length; int length;
int err; int err;
err = shell_cmd_precheck(shell, (argc >= 2));
if (err) {
return err;
}
if (argv[1][0] == '/') { if (argv[1][0] == '/') {
strncpy(path, argv[1], sizeof(path) - 1); strncpy(path, argv[1], sizeof(path) - 1);
path[MAX_PATH_LEN - 1] = '\0'; path[MAX_PATH_LEN - 1] = '\0';
@ -212,11 +207,6 @@ static int cmd_mkdir(const struct shell *shell, size_t argc, char **argv)
int err; int err;
char path[MAX_PATH_LEN]; char path[MAX_PATH_LEN];
err = shell_cmd_precheck(shell, (argc == 2));
if (err) {
return err;
}
create_abs_path(argv[1], path, sizeof(path)); create_abs_path(argv[1], path, sizeof(path));
err = fs_mkdir(path); err = fs_mkdir(path);
@ -234,11 +224,6 @@ static int cmd_rm(const struct shell *shell, size_t argc, char **argv)
int err; int err;
char path[MAX_PATH_LEN]; char path[MAX_PATH_LEN];
err = shell_cmd_precheck(shell, (argc == 2));
if (err) {
return err;
}
create_abs_path(argv[1], path, sizeof(path)); create_abs_path(argv[1], path, sizeof(path));
err = fs_unlink(path); err = fs_unlink(path);
@ -260,11 +245,6 @@ static int cmd_read(const struct shell *shell, size_t argc, char **argv)
off_t offset; off_t offset;
int err; int err;
err = shell_cmd_precheck(shell, (argc >= 2));
if (err) {
return err;
}
create_abs_path(argv[1], path, sizeof(path)); create_abs_path(argv[1], path, sizeof(path));
if (argc > 2) { if (argc > 2) {
@ -356,11 +336,6 @@ static int cmd_write(const struct shell *shell, size_t argc, char **argv)
off_t offset = -1; off_t offset = -1;
int err; int err;
err = shell_cmd_precheck(shell, (argc >= 3));
if (err) {
return err;
}
create_abs_path(argv[1], path, sizeof(path)); create_abs_path(argv[1], path, sizeof(path));
if (!strcmp(argv[2], "-o")) { if (!strcmp(argv[2], "-o")) {
@ -439,11 +414,6 @@ static int cmd_mount_fat(const struct shell *shell, size_t argc, char **argv)
char *mntpt; char *mntpt;
int res; int res;
res = shell_cmd_precheck(shell, (argc == 2));
if (res) {
return res;
}
mntpt = mntpt_prepare(argv[1]); mntpt = mntpt_prepare(argv[1]);
if (!mntpt) { if (!mntpt) {
shell_fprintf(shell, SHELL_ERROR, shell_fprintf(shell, SHELL_ERROR,
@ -473,11 +443,6 @@ static int cmd_mount_nffs(const struct shell *shell, size_t argc, char **argv)
char *mntpt; char *mntpt;
int res; int res;
res = shell_cmd_precheck(shell, (argc == 2));
if (res) {
return res;
}
mntpt = mntpt_prepare(argv[1]); mntpt = mntpt_prepare(argv[1]);
if (!mntpt) { if (!mntpt) {
shell_fprintf(shell, SHELL_ERROR, shell_fprintf(shell, SHELL_ERROR,
@ -512,13 +477,15 @@ SHELL_CREATE_STATIC_SUBCMD_SET(sub_fs_mount)
{ {
#if defined(CONFIG_FAT_FILESYSTEM_ELM) #if defined(CONFIG_FAT_FILESYSTEM_ELM)
SHELL_CMD(fat, NULL, SHELL_CMD_ARG(fat, NULL,
"Mount fatfs. fs mount fat <mount-point>", cmd_mount_fat), "Mount fatfs. fs mount fat <mount-point>",
cmd_mount_fat, 2, 0),
#endif #endif
#if defined(CONFIG_FILE_SYSTEM_NFFS) #if defined(CONFIG_FILE_SYSTEM_NFFS)
SHELL_CMD(nffs, NULL, SHELL_CMD_ARG(nffs, NULL,
"Mount nffs. fs mount nffs <mount-point>", cmd_mount_nffs), "Mount nffs. fs mount nffs <mount-point>",
cmd_mount_nffs, 2, 0),
#endif #endif
SHELL_SUBCMD_SET_END SHELL_SUBCMD_SET_END
@ -530,16 +497,16 @@ SHELL_CREATE_STATIC_SUBCMD_SET(sub_fs)
SHELL_CMD(cd, NULL, SHELL_CMD(cd, NULL,
"Change working directory", cmd_cd), "Change working directory", cmd_cd),
SHELL_CMD(ls, NULL, "List files in current directory", cmd_ls), SHELL_CMD(ls, NULL, "List files in current directory", cmd_ls),
SHELL_CMD(mkdir, NULL, "Create directory", cmd_mkdir), SHELL_CMD_ARG(mkdir, NULL, "Create directory", cmd_mkdir, 2, 0),
#if defined(CONFIG_FILE_SYSTEM_NFFS) || defined(CONFIG_FAT_FILESYSTEM_ELM) #if defined(CONFIG_FILE_SYSTEM_NFFS) || defined(CONFIG_FAT_FILESYSTEM_ELM)
SHELL_CMD(mount, &sub_fs_mount, SHELL_CMD(mount, &sub_fs_mount,
"<fs e.g: fat/nffs> <mount-point>", NULL), "<fs e.g: fat/nffs> <mount-point>", NULL),
#endif #endif
SHELL_CMD(pwd, NULL, "Print current working directory", cmd_pwd), SHELL_CMD(pwd, NULL, "Print current working directory", cmd_pwd),
SHELL_CMD(read, NULL, "Read from file", cmd_read), SHELL_CMD_ARG(read, NULL, "Read from file", cmd_read, 2, 255),
SHELL_CMD(rm, NULL, "Remove file", cmd_rm), SHELL_CMD_ARG(rm, NULL, "Remove file", cmd_rm, 2, 0),
SHELL_CMD(trunc, NULL, "Truncate file", cmd_trunc), SHELL_CMD_ARG(trunc, NULL, "Truncate file", cmd_trunc, 2, 255),
SHELL_CMD(write, NULL, "Write file", cmd_write), SHELL_CMD_ARG(write, NULL, "Write file", cmd_write, 3, 255),
SHELL_SUBCMD_SET_END SHELL_SUBCMD_SET_END
}; };

View file

@ -57,8 +57,7 @@ static bool shell_state_precheck(const struct shell *shell)
{ {
if (shell->log_backend->control_block->state if (shell->log_backend->control_block->state
== SHELL_LOG_BACKEND_UNINIT) { == SHELL_LOG_BACKEND_UNINIT) {
shell_fprintf(shell, SHELL_ERROR, shell_error(shell, "Shell log backend not initialized.");
"Shell log backend not initialized.\r\n");
return false; return false;
} }
@ -82,8 +81,7 @@ static int shell_backend_cmd_execute(const struct shell *shell,
if (backend) { if (backend) {
func(shell, backend, argc, argv); func(shell, backend, argc, argv);
} else { } else {
shell_fprintf(shell, SHELL_ERROR, shell_error(shell, "Invalid backend: %s", name);
"Invalid backend: %s\r\n", name);
return -ENOEXEC; return -ENOEXEC;
} }
return 0; return 0;
@ -101,7 +99,7 @@ static int log_status(const struct shell *shell,
if (!log_backend_is_active(backend)) { if (!log_backend_is_active(backend)) {
shell_fprintf(shell, SHELL_ERROR, "Logs are halted!\r\n"); shell_warn(shell, "Logs are halted!");
} }
shell_fprintf(shell, SHELL_NORMAL, "%-40s | current | built-in \r\n", shell_fprintf(shell, SHELL_NORMAL, "%-40s | current | built-in \r\n",
@ -168,7 +166,7 @@ static void filters_set(const struct shell *shell,
int cnt = all ? log_sources_count() : argc; int cnt = all ? log_sources_count() : argc;
if (!backend->cb->active) { if (!backend->cb->active) {
shell_fprintf(shell, SHELL_WARNING, "Backend not active.\r\n"); shell_warn(shell, "Backend not active.");
} }
for (i = 0; i < cnt; i++) { for (i = 0; i < cnt; i++) {
@ -185,13 +183,11 @@ static void filters_set(const struct shell *shell,
log_source_name_get( log_source_name_get(
CONFIG_LOG_DOMAIN_ID, i) : CONFIG_LOG_DOMAIN_ID, i) :
argv[i]; argv[i];
shell_fprintf(shell, SHELL_WARNING, shell_warn(shell, "%s: level set to %s.",
"%s: level set to %s.\r\n", name, severity_lvls[set_lvl]);
name, severity_lvls[set_lvl]);
} }
} else { } else {
shell_fprintf(shell, SHELL_ERROR, shell_error(shell, "%s: unknown source name.", argv[i]);
"%s: unknown source name.\r\n", argv[i]);
} }
} }
} }
@ -214,17 +210,11 @@ static int log_enable(const struct shell *shell,
char **argv) char **argv)
{ {
int severity_level; int severity_level;
int err = shell_cmd_precheck(shell, (argc > 1));
if (err) {
return err;
}
severity_level = severity_level_get(argv[1]); severity_level = severity_level_get(argv[1]);
if (severity_level < 0) { if (severity_level < 0) {
shell_fprintf(shell, SHELL_ERROR, "Invalid severity: %s\r\n", shell_error(shell, "Invalid severity: %s", argv[1]);
argv[1]);
return -ENOEXEC; return -ENOEXEC;
} }
@ -254,12 +244,6 @@ static int log_disable(const struct shell *shell,
size_t argc, size_t argc,
char **argv) char **argv)
{ {
int err = shell_cmd_precheck(shell, (argc > 1));
if (err) {
return err;
}
filters_set(shell, backend, argc - 1, &argv[1], LOG_LEVEL_NONE); filters_set(shell, backend, argc - 1, &argv[1], LOG_LEVEL_NONE);
return 0; return 0;
} }
@ -361,11 +345,6 @@ static int cmd_log_backends_list(const struct shell *shell,
size_t argc, char **argv) size_t argc, char **argv)
{ {
int backend_count; int backend_count;
int err = shell_cmd_precheck(shell, (argc == 1));
if (err) {
return err;
}
backend_count = log_backend_count_get(); backend_count = log_backend_count_get();
@ -387,15 +366,15 @@ static int cmd_log_backends_list(const struct shell *shell,
SHELL_CREATE_STATIC_SUBCMD_SET(sub_log_backend) SHELL_CREATE_STATIC_SUBCMD_SET(sub_log_backend)
{ {
SHELL_CMD(disable, &dsub_module_name, SHELL_CMD_ARG(disable, &dsub_module_name,
"'log disable <module_0> .. <module_n>' disables logs in " "'log disable <module_0> .. <module_n>' disables logs in "
"specified modules (all if no modules specified).", "specified modules (all if no modules specified).",
cmd_log_backend_disable), cmd_log_backend_disable, 2, 255),
SHELL_CMD(enable, &dsub_severity_lvl, SHELL_CMD_ARG(enable, &dsub_severity_lvl,
"'log enable <level> <module_0> ... <module_n>' enables logs" "'log enable <level> <module_0> ... <module_n>' enables logs"
" up to given level in specified modules (all if no modules " " up to given level in specified modules (all if no modules "
"specified).", "specified).",
cmd_log_backend_enable), cmd_log_backend_enable, 2, 255),
SHELL_CMD(go, NULL, "Resume logging", cmd_log_backend_go), SHELL_CMD(go, NULL, "Resume logging", cmd_log_backend_go),
SHELL_CMD(halt, NULL, "Halt logging", cmd_log_backend_halt), SHELL_CMD(halt, NULL, "Halt logging", cmd_log_backend_halt),
SHELL_CMD(status, NULL, "Logger status", cmd_log_backend_status), SHELL_CMD(status, NULL, "Logger status", cmd_log_backend_status),
@ -423,33 +402,21 @@ SHELL_CREATE_STATIC_SUBCMD_SET(sub_log_stat)
{ {
SHELL_CMD(backend, &dsub_backend_name_dynamic, SHELL_CMD(backend, &dsub_backend_name_dynamic,
"Logger backends commands.", NULL), "Logger backends commands.", NULL),
SHELL_CMD(disable, &dsub_module_name, SHELL_CMD_ARG(disable, &dsub_module_name,
"'log disable <module_0> .. <module_n>' disables logs in specified " "'log disable <module_0> .. <module_n>' disables logs in specified "
"modules (all if no modules specified).", "modules (all if no modules specified).",
cmd_log_self_disable), cmd_log_self_disable, 2, 255),
SHELL_CMD(enable, &dsub_severity_lvl, SHELL_CMD_ARG(enable, &dsub_severity_lvl,
"'log enable <level> <module_0> ... <module_n>' enables logs up to" "'log enable <level> <module_0> ... <module_n>' enables logs up to"
" given level in specified modules (all if no modules specified).", " given level in specified modules (all if no modules specified).",
cmd_log_self_enable), cmd_log_self_enable, 2, 255),
SHELL_CMD(go, NULL, "Resume logging", cmd_log_self_go), SHELL_CMD(go, NULL, "Resume logging", cmd_log_self_go),
SHELL_CMD(halt, NULL, "Halt logging", cmd_log_self_halt), SHELL_CMD(halt, NULL, "Halt logging", cmd_log_self_halt),
SHELL_CMD(list_backends, NULL, "Lists logger backends.", SHELL_CMD_ARG(list_backends, NULL, "Lists logger backends.",
cmd_log_backends_list), cmd_log_backends_list, 1, 0),
SHELL_CMD(status, NULL, "Logger status", cmd_log_self_status), SHELL_CMD(status, NULL, "Logger status", cmd_log_self_status),
SHELL_SUBCMD_SET_END SHELL_SUBCMD_SET_END
}; };
static int cmd_log(const struct shell *shell, size_t argc, char **argv)
{
if (argc == 1) {
shell_help_print(shell);
return 0;
}
shell_fprintf(shell, SHELL_ERROR, "%s:%s%s\r\n",
argv[0], " unknown parameter: ", argv[1]);
return -ENOEXEC;
}
SHELL_CMD_REGISTER(log, &sub_log_stat, "Commands for controlling logger", SHELL_CMD_REGISTER(log, &sub_log_stat, "Commands for controlling logger",
cmd_log); NULL);

View file

@ -33,6 +33,11 @@ zephyr_sources_ifdef(
shell_rtt.c shell_rtt.c
) )
zephyr_sources_ifdef(
CONFIG_SHELL_HELP
shell_help.c
)
zephyr_sources_ifdef( zephyr_sources_ifdef(
CONFIG_SHELL_CMDS CONFIG_SHELL_CMDS
shell_cmds.c shell_cmds.c

View file

@ -9,6 +9,7 @@
#include <stdlib.h> #include <stdlib.h>
#include <shell/shell.h> #include <shell/shell.h>
#include <shell/shell_dummy.h> #include <shell/shell_dummy.h>
#include "shell_help.h"
#include "shell_utils.h" #include "shell_utils.h"
#include "shell_ops.h" #include "shell_ops.h"
#include "shell_wildcard.h" #include "shell_wildcard.h"
@ -42,26 +43,6 @@
static int shell_execute(const struct shell *shell); static int shell_execute(const struct shell *shell);
extern const struct shell_cmd_entry __shell_root_cmds_start[0];
extern const struct shell_cmd_entry __shell_root_cmds_end[0];
static inline const struct shell_cmd_entry *shell_root_cmd_get(u32_t id)
{
return &__shell_root_cmds_start[id];
}
static inline u32_t shell_root_cmd_count(void)
{
return ((u8_t *)__shell_root_cmds_end -
(u8_t *)__shell_root_cmds_start)/
sizeof(struct shell_cmd_entry);
}
static inline void transport_buffer_flush(const struct shell *shell)
{
shell_fprintf_buffer_flush(shell->fprintf_ctx);
}
/* Function returns true if delete escape code shall be interpreted as /* Function returns true if delete escape code shall be interpreted as
* backspace. * backspace.
*/ */
@ -88,93 +69,33 @@ static void shell_cmd_buffer_clear(const struct shell *shell)
shell->ctx->cmd_buff_len = 0; shell->ctx->cmd_buff_len = 0;
} }
static void shell_pend_on_txdone(const struct shell *shell) /**
{ * @brief Prints error message on wrong argument count.
if (IS_ENABLED(CONFIG_MULTITHREADING)) { * Optionally, printing help on wrong argument count.
k_poll(&shell->ctx->events[SHELL_SIGNAL_TXDONE], 1, K_FOREVER);
k_poll_signal_reset(&shell->ctx->signals[SHELL_SIGNAL_TXDONE]);
} else {
/* Blocking wait in case of bare metal. */
while (!shell->ctx->internal.flags.tx_rdy) {
}
shell->ctx->internal.flags.tx_rdy = 0;
}
}
/* Function sends data stream to the shell instance. Each time before the
* shell_write function is called, it must be ensured that IO buffer of fprintf
* is flushed to avoid synchronization issues.
* For that purpose, use function transport_buffer_flush(shell)
*/
static void shell_write(const struct shell *shell, const void *data,
size_t length)
{
__ASSERT_NO_MSG(shell && data);
size_t offset = 0;
size_t tmp_cnt;
while (length) {
int err = shell->iface->api->write(shell->iface,
&((const u8_t *) data)[offset], length,
&tmp_cnt);
(void)err;
__ASSERT_NO_MSG(err == 0);
__ASSERT_NO_MSG(length >= tmp_cnt);
offset += tmp_cnt;
length -= tmp_cnt;
if (tmp_cnt == 0 &&
(shell->ctx->state != SHELL_STATE_PANIC_MODE_ACTIVE)) {
shell_pend_on_txdone(shell);
}
}
}
/* @brief Function shall be used to search commands.
* *
* It moves the pointer entry to command of static command structure. If the * @param[in] shell Pointer to the shell instance.
* command cannot be found, the function will set entry to NULL. * @param[in] arg_cnt_ok Flag indicating valid number of arguments.
* *
* @param command Pointer to command which will be processed (no matter * @return 0 if check passed
* the root command). * @return 1 if help was requested
* @param lvl Level of the requested command. * @return -EINVAL if wrong argument count
* @param idx Index of the requested command.
* @param entry Pointer which points to subcommand[idx] after function
* execution.
* @param st_entry Pointer to the structure where dynamic entry data can be
* stored.
*/ */
static void cmd_get(const struct shell_cmd_entry *command, size_t lvl, static int shell_cmd_precheck(const struct shell *shell,
size_t idx, const struct shell_static_entry **entry, bool arg_cnt_ok)
struct shell_static_entry *d_entry)
{ {
__ASSERT_NO_MSG(entry != NULL); if (!arg_cnt_ok) {
__ASSERT_NO_MSG(d_entry != NULL); shell_fprintf(shell, SHELL_ERROR,
"%s: wrong parameter count\n",
shell->ctx->active_cmd.syntax);
if (lvl == SHELL_CMD_ROOT_LVL) { if (IS_ENABLED(CONFIG_SHELL_HELP_ON_WRONG_ARGUMENT_COUNT)) {
if (idx < shell_root_cmd_count()) { shell_help_print(shell);
const struct shell_cmd_entry *cmd;
cmd = shell_root_cmd_get(idx);
*entry = cmd->u.entry;
} else {
*entry = NULL;
} }
return;
return -EINVAL;
} }
if (command == NULL) { return 0;
*entry = NULL;
return;
}
if (command->is_dynamic) {
command->u.dynamic_get(idx, d_entry);
*entry = (d_entry->syntax != NULL) ? d_entry : NULL;
} else {
*entry = (command->u.entry[idx].syntax != NULL) ?
&command->u.entry[idx] : NULL;
}
} }
static void vt100_color_set(const struct shell *shell, static void vt100_color_set(const struct shell *shell,
@ -364,7 +285,7 @@ static const struct shell_static_entry *find_cmd(
size_t idx = 0; size_t idx = 0;
do { do {
cmd_get(cmd, lvl, idx++, &entry, d_entry); shell_cmd_get(cmd, lvl, idx++, &entry, d_entry);
if (entry && (strcmp(cmd_str, entry->syntax) == 0)) { if (entry && (strcmp(cmd_str, entry->syntax) == 0)) {
return entry; return entry;
} }
@ -490,8 +411,8 @@ static void find_completion_candidates(const struct shell_static_entry *cmd,
*cnt = 0; *cnt = 0;
while (true) { while (true) {
cmd_get(cmd ? cmd->subcmd : NULL, cmd ? 1 : 0, shell_cmd_get(cmd ? cmd->subcmd : NULL, cmd ? 1 : 0,
idx, &candidate, &dynamic_entry); idx, &candidate, &dynamic_entry);
if (!candidate) { if (!candidate) {
break; break;
@ -526,8 +447,8 @@ static void autocomplete(const struct shell *shell,
/* shell->ctx->active_cmd can be safely used outside of command context /* shell->ctx->active_cmd can be safely used outside of command context
* to save stack * to save stack
*/ */
cmd_get(cmd ? cmd->subcmd : NULL, cmd ? 1 : 0, shell_cmd_get(cmd ? cmd->subcmd : NULL, cmd ? 1 : 0,
subcmd_idx, &match, &shell->ctx->active_cmd); subcmd_idx, &match, &shell->ctx->active_cmd);
cmd_len = shell_strlen(match->syntax); cmd_len = shell_strlen(match->syntax);
/* no exact match found */ /* no exact match found */
@ -589,8 +510,8 @@ static void tab_options_print(const struct shell *shell,
/* shell->ctx->active_cmd can be safely used outside of command /* shell->ctx->active_cmd can be safely used outside of command
* context to save stack * context to save stack
*/ */
cmd_get(cmd ? cmd->subcmd : NULL, cmd ? 1 : 0, shell_cmd_get(cmd ? cmd->subcmd : NULL, cmd ? 1 : 0,
idx, &match, &shell->ctx->active_cmd); idx, &match, &shell->ctx->active_cmd);
idx++; idx++;
if (str && match->syntax && if (str && match->syntax &&
@ -617,8 +538,9 @@ static u16_t common_beginning_find(const struct shell_static_entry *cmd,
u16_t common = UINT16_MAX; u16_t common = UINT16_MAX;
size_t idx = first + 1; size_t idx = first + 1;
cmd_get(cmd ? cmd->subcmd : NULL, cmd ? 1 : 0,
first, &match, &dynamic_entry); shell_cmd_get(cmd ? cmd->subcmd : NULL, cmd ? 1 : 0,
first, &match, &dynamic_entry);
*str = match->syntax; *str = match->syntax;
@ -627,8 +549,8 @@ static u16_t common_beginning_find(const struct shell_static_entry *cmd,
const struct shell_static_entry *match2; const struct shell_static_entry *match2;
int curr_common; int curr_common;
cmd_get(cmd ? cmd->subcmd : NULL, cmd ? 1 : 0, shell_cmd_get(cmd ? cmd->subcmd : NULL, cmd ? 1 : 0,
idx++, &match2, &dynamic_entry2); idx++, &match2, &dynamic_entry2);
if (match2 == NULL) { if (match2 == NULL) {
break; break;
@ -675,6 +597,7 @@ static void shell_tab_handle(const struct shell *shell)
size_t argc; size_t argc;
size_t cnt; size_t cnt;
bool tab_possible = shell_tab_prepare(shell, &cmd, argv, &argc, bool tab_possible = shell_tab_prepare(shell, &cmd, argv, &argc,
&arg_idx, &d_entry); &arg_idx, &d_entry);
@ -949,22 +872,6 @@ static void cmd_trim(const struct shell *shell)
shell->ctx->cmd_buff_pos = shell->ctx->cmd_buff_len; shell->ctx->cmd_buff_pos = shell->ctx->cmd_buff_len;
} }
/* Function returning pointer to root command matching requested syntax. */
static const struct shell_cmd_entry *root_cmd_find(const char *syntax)
{
const size_t cmd_count = shell_root_cmd_count();
const struct shell_cmd_entry *cmd;
for (size_t cmd_idx = 0; cmd_idx < cmd_count; ++cmd_idx) {
cmd = shell_root_cmd_get(cmd_idx);
if (strcmp(syntax, cmd->u.entry->syntax) == 0) {
return cmd;
}
}
return NULL;
}
static int exec_cmd(const struct shell *shell, size_t argc, char **argv, static int exec_cmd(const struct shell *shell, size_t argc, char **argv,
struct shell_static_entry help_entry) struct shell_static_entry help_entry)
{ {
@ -976,12 +883,14 @@ static int exec_cmd(const struct shell *shell, size_t argc, char **argv,
shell->ctx->active_cmd = help_entry; shell->ctx->active_cmd = help_entry;
} }
shell_help_print(shell); shell_help_print(shell);
/* 1 is return value when shell prints help */
ret_val = 1;
} else { } else {
shell_fprintf(shell, SHELL_ERROR, shell_fprintf(shell, SHELL_ERROR,
SHELL_MSG_SPECIFY_SUBCOMMAND); SHELL_MSG_SPECIFY_SUBCOMMAND);
ret_val = -ENOEXEC;
} }
ret_val = -ENOEXEC;
goto clear; goto clear;
} }
@ -1123,7 +1032,8 @@ static int shell_execute(const struct shell *shell)
} }
} }
cmd_get(p_cmd, cmd_lvl, cmd_idx++, &p_static_entry, &d_entry); shell_cmd_get(p_cmd, cmd_lvl, cmd_idx++, &p_static_entry,
&d_entry);
if ((cmd_idx == 0) || (p_static_entry == NULL)) { if ((cmd_idx == 0) || (p_static_entry == NULL)) {
break; break;
@ -1482,13 +1392,6 @@ void shell_process(const struct shell *shell)
internal.value); internal.value);
} }
/* Function shall be only used by the fprintf module. */
void shell_print_stream(const void *user_ctx, const char *data,
size_t data_len)
{
shell_write((const struct shell *) user_ctx, data, data_len);
}
void shell_fprintf(const struct shell *shell, enum shell_vt100_color color, void shell_fprintf(const struct shell *shell, enum shell_vt100_color color,
const char *p_fmt, ...) const char *p_fmt, ...)
{ {
@ -1516,216 +1419,6 @@ void shell_fprintf(const struct shell *shell, enum shell_vt100_color color,
va_end(args); va_end(args);
} }
/* Function prints a string on terminal screen with requested margin.
* It takes care to not divide words.
* shell Pointer to shell instance.
* p_str Pointer to string to be printed.
* terminal_offset Requested left margin.
* offset_first_line Add margin to the first printed line.
*/
static void formatted_text_print(const struct shell *shell, const char *str,
size_t terminal_offset, bool offset_first_line)
{
size_t offset = 0;
size_t length;
if (str == NULL) {
return;
}
if (offset_first_line) {
shell_op_cursor_horiz_move(shell, terminal_offset);
}
/* Skipping whitespace. */
while (isspace((int) *(str + offset))) {
++offset;
}
while (true) {
size_t idx = 0;
length = shell_strlen(str) - offset;
if (length <=
shell->ctx->vt100_ctx.cons.terminal_wid - terminal_offset) {
for (idx = 0; idx < length; idx++) {
if (*(str + offset + idx) == '\n') {
transport_buffer_flush(shell);
shell_write(shell, str + offset, idx);
offset += idx + 1;
cursor_next_line_move(shell);
shell_op_cursor_horiz_move(shell,
terminal_offset);
break;
}
}
/* String will fit in one line. */
shell_raw_fprintf(shell->fprintf_ctx, str + offset);
break;
}
/* String is longer than terminal line so text needs to
* divide in the way to not divide words.
*/
length = shell->ctx->vt100_ctx.cons.terminal_wid
- terminal_offset;
while (true) {
/* Determining line break. */
if (isspace((int) (*(str + offset + idx)))) {
length = idx;
if (*(str + offset + idx) == '\n') {
break;
}
}
if ((idx + terminal_offset) >=
shell->ctx->vt100_ctx.cons.terminal_wid) {
/* End of line reached. */
break;
}
++idx;
}
/* Writing one line, fprintf IO buffer must be flushed
* before calling shell_write.
*/
transport_buffer_flush(shell);
shell_write(shell, str + offset, length);
offset += length;
/* Calculating text offset to ensure that next line will
* not begin with a space.
*/
while (isspace((int) (*(str + offset)))) {
++offset;
}
cursor_next_line_move(shell);
shell_op_cursor_horiz_move(shell, terminal_offset);
}
cursor_next_line_move(shell);
}
static void help_cmd_print(const struct shell *shell)
{
static const char cmd_sep[] = " - "; /* commands separator */
u16_t field_width = shell_strlen(shell->ctx->active_cmd.syntax) +
shell_strlen(cmd_sep);
shell_fprintf(shell, SHELL_NORMAL, "%s%s",
shell->ctx->active_cmd.syntax, cmd_sep);
formatted_text_print(shell, shell->ctx->active_cmd.help,
field_width, false);
}
static void help_item_print(const struct shell *shell, const char *item_name,
u16_t item_name_width, const char *item_help)
{
static const u8_t tabulator[] = " ";
const u16_t offset = 2 * strlen(tabulator) + item_name_width + 1;
if (item_name == NULL) {
return;
}
if (!IS_ENABLED(CONFIG_NEWLIB_LIBC) && !IS_ENABLED(CONFIG_ARCH_POSIX)) {
/* print option name */
shell_fprintf(shell, SHELL_NORMAL, "%s%-*s%s:",
tabulator,
item_name_width, item_name,
tabulator);
} else {
u16_t tmp = item_name_width - strlen(item_name);
char space = ' ';
shell_fprintf(shell, SHELL_NORMAL, "%s%s", tabulator,
item_name);
for (u16_t i = 0; i < tmp; i++) {
shell_write(shell, &space, 1);
}
shell_fprintf(shell, SHELL_NORMAL, "%s:", tabulator);
}
if (item_help == NULL) {
cursor_next_line_move(shell);
return;
}
/* print option help */
formatted_text_print(shell, item_help, offset, false);
}
/* Function is printing command help, its subcommands name and subcommands
* help string.
*/
static void help_subcmd_print(const struct shell *shell)
{
const struct shell_static_entry *entry = NULL;
struct shell_static_entry static_entry;
u16_t longest_syntax = 0U;
size_t cmd_idx = 0;
/* Checking if there are any subcommands available. */
if (!shell->ctx->active_cmd.subcmd) {
return;
}
/* Searching for the longest subcommand to print. */
do {
cmd_get(shell->ctx->active_cmd.subcmd, !SHELL_CMD_ROOT_LVL,
cmd_idx++, &entry, &static_entry);
if (!entry) {
break;
}
u16_t len = shell_strlen(entry->syntax);
longest_syntax = longest_syntax > len ? longest_syntax : len;
} while (cmd_idx != 0); /* too many commands */
if (cmd_idx == 1) {
return;
}
shell_fprintf(shell, SHELL_NORMAL, "Subcommands:\r\n");
/* Printing subcommands and help string (if exists). */
cmd_idx = 0;
while (true) {
cmd_get(shell->ctx->active_cmd.subcmd, !SHELL_CMD_ROOT_LVL,
cmd_idx++, &entry, &static_entry);
if (entry == NULL) {
break;
}
help_item_print(shell, entry->syntax, longest_syntax,
entry->help);
}
}
void shell_help_print(const struct shell *shell)
{
__ASSERT_NO_MSG(shell);
if (!IS_ENABLED(CONFIG_SHELL_HELP)) {
return;
}
help_cmd_print(shell);
help_subcmd_print(shell);
}
int shell_prompt_change(const struct shell *shell, char *prompt) int shell_prompt_change(const struct shell *shell, char *prompt)
{ {
@ -1741,22 +1434,16 @@ int shell_prompt_change(const struct shell *shell, char *prompt)
return -1; return -1;
} }
int shell_cmd_precheck(const struct shell *shell, void shell_help_print(const struct shell *shell)
bool arg_cnt_ok)
{ {
if (!arg_cnt_ok) { __ASSERT_NO_MSG(shell);
shell_fprintf(shell, SHELL_ERROR,
"%s: wrong parameter count\n",
shell->ctx->active_cmd.syntax);
if (IS_ENABLED(CONFIG_SHELL_HELP_ON_WRONG_ARGUMENT_COUNT)) { if (!IS_ENABLED(CONFIG_SHELL_HELP)) {
shell_help_print(shell); return;
}
return -EINVAL;
} }
return 0; shell_help_cmd_print(shell);
shell_help_subcmd_print(shell);
} }
int shell_execute_cmd(const struct shell *shell, const char *cmd) int shell_execute_cmd(const struct shell *shell, const char *cmd)

View file

@ -41,6 +41,7 @@
"Disable shell echo. Editing keys and meta-keys are not handled" "Disable shell echo. Editing keys and meta-keys are not handled"
#define SHELL_HELP_SHELL "Useful, not Unix-like shell commands." #define SHELL_HELP_SHELL "Useful, not Unix-like shell commands."
#define SHELL_HELP_HELP "Prints help message."
#define SHELL_MSG_UNKNOWN_PARAMETER " unknown parameter: " #define SHELL_MSG_UNKNOWN_PARAMETER " unknown parameter: "
@ -96,7 +97,7 @@ static int cursor_position_get(const struct shell *shell, u16_t *x, u16_t *y)
/* Index start position in the buffer where 'y' /* Index start position in the buffer where 'y'
* is stored. * is stored.
*/ */
buff_idx = 2U; buff_idx = 2;
while (shell->ctx->temp_buff[buff_idx] != ';') { while (shell->ctx->temp_buff[buff_idx] != ';') {
*y = *y * 10 + *y = *y * 10 +
@ -184,157 +185,84 @@ static int cmd_clear(const struct shell *shell, size_t argc, char **argv)
{ {
ARG_UNUSED(argv); ARG_UNUSED(argv);
int ret = shell_cmd_precheck(shell, (argc == 1));
if (ret) {
return ret;
}
SHELL_VT100_CMD(shell, SHELL_VT100_CURSORHOME); SHELL_VT100_CMD(shell, SHELL_VT100_CURSORHOME);
SHELL_VT100_CMD(shell, SHELL_VT100_CLEARSCREEN); SHELL_VT100_CMD(shell, SHELL_VT100_CLEARSCREEN);
return 0; return 0;
} }
static int cmd_shell(const struct shell *shell, size_t argc, char **argv)
{
int ret = shell_cmd_precheck(shell, (argc == 2));
if (ret) {
return ret;
}
shell_fprintf(shell, SHELL_ERROR, "%s:%s%s\n", argv[0],
SHELL_MSG_UNKNOWN_PARAMETER, argv[1]);
return -EINVAL;
}
static int cmd_bacskpace_mode_backspace(const struct shell *shell, size_t argc, static int cmd_bacskpace_mode_backspace(const struct shell *shell, size_t argc,
char **argv) char **argv)
{ {
ARG_UNUSED(argc);
ARG_UNUSED(argv); ARG_UNUSED(argv);
int ret = shell_cmd_precheck(shell, (argc == 1)); shell->ctx->internal.flags.mode_delete = 0;
if (ret == 0) { return 0;
shell->ctx->internal.flags.mode_delete = 0;
}
return ret;
} }
static int cmd_bacskpace_mode_delete(const struct shell *shell, size_t argc, static int cmd_bacskpace_mode_delete(const struct shell *shell, size_t argc,
char **argv) char **argv)
{ {
ARG_UNUSED(argc);
ARG_UNUSED(argv); ARG_UNUSED(argv);
int ret = shell_cmd_precheck(shell, (argc == 1)); shell->ctx->internal.flags.mode_delete = 1;
if (ret == 0) { return 0;
shell->ctx->internal.flags.mode_delete = 1;
}
return ret;
}
static int cmd_bacskpace_mode(const struct shell *shell, size_t argc,
char **argv)
{
int ret = shell_cmd_precheck(shell, (argc == 2));
if (ret) {
return ret;
}
shell_fprintf(shell, SHELL_ERROR, "%s:%s%s\n", argv[0],
SHELL_MSG_UNKNOWN_PARAMETER, argv[1]);
return -EINVAL;
} }
static int cmd_colors_off(const struct shell *shell, size_t argc, char **argv) static int cmd_colors_off(const struct shell *shell, size_t argc, char **argv)
{ {
ARG_UNUSED(argc);
ARG_UNUSED(argv); ARG_UNUSED(argv);
int ret = shell_cmd_precheck(shell, (argc == 1)); shell->ctx->internal.flags.use_colors = 0;
if (ret == 0) { return 0;
shell->ctx->internal.flags.use_colors = 0;
}
return ret;
} }
static int cmd_colors_on(const struct shell *shell, size_t argc, char **argv) static int cmd_colors_on(const struct shell *shell, size_t argc, char **argv)
{ {
ARG_UNUSED(argv); ARG_UNUSED(argv);
ARG_UNUSED(argv);
int ret = shell_cmd_precheck(shell, (argc == 1)); shell->ctx->internal.flags.use_colors = 1;
if (ret == 0) { return 0;
shell->ctx->internal.flags.use_colors = 1;
}
return ret;
}
static int cmd_colors(const struct shell *shell, size_t argc, char **argv)
{
int ret = shell_cmd_precheck(shell, (argc == 2));
if (ret) {
return ret;
}
shell_fprintf(shell, SHELL_ERROR, "%s:%s%s\n", argv[0],
SHELL_MSG_UNKNOWN_PARAMETER, argv[1]);
return -EINVAL;
} }
static int cmd_echo_off(const struct shell *shell, size_t argc, char **argv) static int cmd_echo_off(const struct shell *shell, size_t argc, char **argv)
{ {
ARG_UNUSED(argc);
ARG_UNUSED(argv); ARG_UNUSED(argv);
int ret = shell_cmd_precheck(shell, (argc == 1)); shell->ctx->internal.flags.echo = 0;
if (ret == 0) { return 0;
shell->ctx->internal.flags.echo = 0;
}
return ret;
} }
static int cmd_echo_on(const struct shell *shell, size_t argc, char **argv) static int cmd_echo_on(const struct shell *shell, size_t argc, char **argv)
{ {
ARG_UNUSED(argc);
ARG_UNUSED(argv); ARG_UNUSED(argv);
int ret = shell_cmd_precheck(shell, (argc == 1)); shell->ctx->internal.flags.echo = 1;
if (ret == 0) { return 0;
shell->ctx->internal.flags.echo = 1;
}
return ret;
} }
static int cmd_echo(const struct shell *shell, size_t argc, char **argv) static int cmd_echo(const struct shell *shell, size_t argc, char **argv)
{ {
int ret = shell_cmd_precheck(shell, (argc <= 2));
if (ret) {
return ret;
}
if (argc == 2) { if (argc == 2) {
shell_fprintf(shell, SHELL_ERROR, "%s:%s%s\n", argv[0], shell_error(shell, "%s:%s%s", argv[0],
SHELL_MSG_UNKNOWN_PARAMETER, argv[1]); SHELL_MSG_UNKNOWN_PARAMETER, argv[1]);
return -EINVAL; return -EINVAL;
} }
shell_fprintf(shell, SHELL_NORMAL, "Echo status: %s\n", shell_print(shell, "Echo status: %s",
flag_echo_is_set(shell) ? "on" : "off"); flag_echo_is_set(shell) ? "on" : "off");
return 0; return 0;
} }
@ -344,42 +272,36 @@ static int cmd_help(const struct shell *shell, size_t argc, char **argv)
ARG_UNUSED(argc); ARG_UNUSED(argc);
ARG_UNUSED(argv); ARG_UNUSED(argv);
shell_fprintf(shell, SHELL_NORMAL, shell_print(shell,
"Please press the <Tab> button to see all available commands.\n" "Please press the <Tab> button to see all available commands.\n"
"You can also use the <Tab> button to prompt or auto-complete" "You can also use the <Tab> button to prompt or auto-complete"
" all commands or its subcommands.\n" " all commands or its subcommands.\n"
"You can try to call commands with <-h> or <--help> parameter" "You can try to call commands with <-h> or <--help> parameter"
" for more information.\n"); " for more information.");
return 0; return 0;
} }
static int cmd_history(const struct shell *shell, size_t argc, char **argv) static int cmd_history(const struct shell *shell, size_t argc, char **argv)
{ {
ARG_UNUSED(argc);
ARG_UNUSED(argv); ARG_UNUSED(argv);
size_t i = 0; size_t i = 0;
size_t len; size_t len;
int ret;
if (!IS_ENABLED(CONFIG_SHELL_HISTORY)) { if (!IS_ENABLED(CONFIG_SHELL_HISTORY)) {
shell_fprintf(shell, SHELL_ERROR, SHELL_MSG_CMD_NOT_SUPPORTED); shell_error(shell, "Command not supported.");
return -ENOEXEC; return -ENOEXEC;
} }
ret = shell_cmd_precheck(shell, (argc == 1));
if (ret) {
return ret;
}
while (1) { while (1) {
shell_history_get(shell->history, true, shell_history_get(shell->history, true,
shell->ctx->temp_buff, &len); shell->ctx->temp_buff, &len);
if (len) { if (len) {
shell_fprintf(shell, SHELL_NORMAL, "[%3d] %s\n", shell_print(shell, "[%3d] %s",
i++, shell->ctx->temp_buff); i++, shell->ctx->temp_buff);
} else { } else {
break; break;
@ -394,72 +316,46 @@ static int cmd_history(const struct shell *shell, size_t argc, char **argv)
static int cmd_shell_stats_show(const struct shell *shell, size_t argc, static int cmd_shell_stats_show(const struct shell *shell, size_t argc,
char **argv) char **argv)
{ {
ARG_UNUSED(argc);
ARG_UNUSED(argv); ARG_UNUSED(argv);
if (!IS_ENABLED(CONFIG_SHELL_STATS)) { if (!IS_ENABLED(CONFIG_SHELL_STATS)) {
shell_fprintf(shell, SHELL_ERROR, SHELL_MSG_CMD_NOT_SUPPORTED); shell_error(shell, "Command not supported.");
return -ENOEXEC; return -ENOEXEC;
} }
int ret = shell_cmd_precheck(shell, (argc == 1)); shell_print(shell, "Lost logs: %u", shell->stats->log_lost_cnt);
if (ret == 0) { return 0;
shell_fprintf(shell, SHELL_NORMAL, "Lost logs: %u\n",
shell->stats->log_lost_cnt);
}
return ret;
} }
static int cmd_shell_stats_reset(const struct shell *shell, static int cmd_shell_stats_reset(const struct shell *shell,
size_t argc, char **argv) size_t argc, char **argv)
{ {
ARG_UNUSED(argc);
ARG_UNUSED(argv); ARG_UNUSED(argv);
if (!IS_ENABLED(CONFIG_SHELL_STATS)) { if (!IS_ENABLED(CONFIG_SHELL_STATS)) {
shell_fprintf(shell, SHELL_ERROR, SHELL_MSG_CMD_NOT_SUPPORTED); shell_error(shell, "Command not supported.");
return -ENOEXEC; return -ENOEXEC;
} }
int ret = shell_cmd_precheck(shell, (argc == 1)); shell->stats->log_lost_cnt = 0;
if (ret == 0) { return 0;
shell->stats->log_lost_cnt = 0;
}
return ret;
}
static int cmd_shell_stats(const struct shell *shell, size_t argc, char **argv)
{
ARG_UNUSED(argc);
if (argc == 1) {
shell_help_print(shell);
} else {
shell_fprintf(shell, SHELL_ERROR, "%s:%s%s\n", argv[0],
SHELL_MSG_UNKNOWN_PARAMETER, argv[1]);
}
return -EINVAL;
} }
static int cmd_resize_default(const struct shell *shell, static int cmd_resize_default(const struct shell *shell,
size_t argc, char **argv) size_t argc, char **argv)
{ {
ARG_UNUSED(argc);
ARG_UNUSED(argv); ARG_UNUSED(argv);
int ret = shell_cmd_precheck(shell, (argc == 1)); SHELL_VT100_CMD(shell, SHELL_VT100_SETCOL_80);
shell->ctx->vt100_ctx.cons.terminal_wid = SHELL_DEFAULT_TERMINAL_WIDTH;
shell->ctx->vt100_ctx.cons.terminal_hei = SHELL_DEFAULT_TERMINAL_HEIGHT;
if (ret == 0) { return 0;
SHELL_VT100_CMD(shell, SHELL_VT100_SETCOL_80);
shell->ctx->vt100_ctx.cons.terminal_wid =
SHELL_DEFAULT_TERMINAL_WIDTH;
shell->ctx->vt100_ctx.cons.terminal_hei =
SHELL_DEFAULT_TERMINAL_HEIGHT;
}
return ret;
} }
static int cmd_resize(const struct shell *shell, size_t argc, char **argv) static int cmd_resize(const struct shell *shell, size_t argc, char **argv)
@ -467,18 +363,13 @@ static int cmd_resize(const struct shell *shell, size_t argc, char **argv)
int err; int err;
if (!IS_ENABLED(CONFIG_SHELL_CMDS_RESIZE)) { if (!IS_ENABLED(CONFIG_SHELL_CMDS_RESIZE)) {
shell_fprintf(shell, SHELL_ERROR, SHELL_MSG_CMD_NOT_SUPPORTED); shell_error(shell, "Command not supported.");
return -ENOEXEC; return -ENOEXEC;
} }
err = shell_cmd_precheck(shell, (argc <= 2));
if (err) {
return err;
}
if (argc != 1) { if (argc != 1) {
shell_fprintf(shell, SHELL_ERROR, "%s:%s%s\n", argv[0], shell_error(shell, "%s:%s%s", argv[0],
SHELL_MSG_UNKNOWN_PARAMETER, argv[1]); SHELL_MSG_UNKNOWN_PARAMETER, argv[1]);
return -EINVAL; return -EINVAL;
} }
@ -488,9 +379,8 @@ static int cmd_resize(const struct shell *shell, size_t argc, char **argv)
SHELL_DEFAULT_TERMINAL_WIDTH; SHELL_DEFAULT_TERMINAL_WIDTH;
shell->ctx->vt100_ctx.cons.terminal_hei = shell->ctx->vt100_ctx.cons.terminal_hei =
SHELL_DEFAULT_TERMINAL_HEIGHT; SHELL_DEFAULT_TERMINAL_HEIGHT;
shell_fprintf(shell, SHELL_WARNING, shell_warn(shell, "No response from the terminal, assumed 80x24"
"No response from the terminal, assumed 80x24 " " screen size");
"screen size\n");
return -ENOEXEC; return -ENOEXEC;
} }
@ -499,54 +389,56 @@ static int cmd_resize(const struct shell *shell, size_t argc, char **argv)
SHELL_CREATE_STATIC_SUBCMD_SET(m_sub_colors) SHELL_CREATE_STATIC_SUBCMD_SET(m_sub_colors)
{ {
SHELL_CMD(off, NULL, SHELL_HELP_COLORS_OFF, cmd_colors_off), SHELL_CMD_ARG(off, NULL, SHELL_HELP_COLORS_OFF, cmd_colors_off, 1, 0),
SHELL_CMD(on, NULL, SHELL_HELP_COLORS_ON, cmd_colors_on), SHELL_CMD_ARG(on, NULL, SHELL_HELP_COLORS_ON, cmd_colors_on, 1, 0),
SHELL_SUBCMD_SET_END SHELL_SUBCMD_SET_END
}; };
SHELL_CREATE_STATIC_SUBCMD_SET(m_sub_echo) SHELL_CREATE_STATIC_SUBCMD_SET(m_sub_echo)
{ {
SHELL_CMD(off, NULL, SHELL_HELP_ECHO_OFF, cmd_echo_off), SHELL_CMD_ARG(off, NULL, SHELL_HELP_ECHO_OFF, cmd_echo_off, 1, 0),
SHELL_CMD(on, NULL, SHELL_HELP_ECHO_ON, cmd_echo_on), SHELL_CMD_ARG(on, NULL, SHELL_HELP_ECHO_ON, cmd_echo_on, 1, 0),
SHELL_SUBCMD_SET_END SHELL_SUBCMD_SET_END
}; };
SHELL_CREATE_STATIC_SUBCMD_SET(m_sub_shell_stats) SHELL_CREATE_STATIC_SUBCMD_SET(m_sub_shell_stats)
{ {
SHELL_CMD(reset, NULL, SHELL_HELP_STATISTICS_RESET, SHELL_CMD_ARG(reset, NULL, SHELL_HELP_STATISTICS_RESET,
cmd_shell_stats_reset), cmd_shell_stats_reset, 1, 0),
SHELL_CMD(show, NULL, SHELL_HELP_STATISTICS_SHOW, cmd_shell_stats_show), SHELL_CMD_ARG(show, NULL, SHELL_HELP_STATISTICS_SHOW,
cmd_shell_stats_show, 1, 0),
SHELL_SUBCMD_SET_END SHELL_SUBCMD_SET_END
}; };
SHELL_CREATE_STATIC_SUBCMD_SET(m_sub_backspace_mode) SHELL_CREATE_STATIC_SUBCMD_SET(m_sub_backspace_mode)
{ {
SHELL_CMD(backspace, NULL, SHELL_HELP_BACKSPACE_MODE_BACKSPACE, SHELL_CMD_ARG(backspace, NULL, SHELL_HELP_BACKSPACE_MODE_BACKSPACE,
cmd_bacskpace_mode_backspace), cmd_bacskpace_mode_backspace, 1, 0),
SHELL_CMD(delete, NULL, SHELL_HELP_BACKSPACE_MODE_DELETE, SHELL_CMD_ARG(delete, NULL, SHELL_HELP_BACKSPACE_MODE_DELETE,
cmd_bacskpace_mode_delete), cmd_bacskpace_mode_delete, 1, 0),
SHELL_SUBCMD_SET_END SHELL_SUBCMD_SET_END
}; };
SHELL_CREATE_STATIC_SUBCMD_SET(m_sub_shell) SHELL_CREATE_STATIC_SUBCMD_SET(m_sub_shell)
{ {
SHELL_CMD(backspace_mode, &m_sub_backspace_mode, SHELL_CMD(backspace_mode, &m_sub_backspace_mode,
SHELL_HELP_BACKSPACE_MODE, cmd_bacskpace_mode), SHELL_HELP_BACKSPACE_MODE, NULL),
SHELL_CMD(colors, &m_sub_colors, SHELL_HELP_COLORS, cmd_colors), SHELL_CMD(colors, &m_sub_colors, SHELL_HELP_COLORS, NULL),
SHELL_CMD(echo, &m_sub_echo, SHELL_HELP_ECHO, cmd_echo), SHELL_CMD_ARG(echo, &m_sub_echo, SHELL_HELP_ECHO, cmd_echo, 1, 1),
SHELL_CMD(stats, &m_sub_shell_stats, SHELL_HELP_STATISTICS, SHELL_CMD(stats, &m_sub_shell_stats, SHELL_HELP_STATISTICS, NULL),
cmd_shell_stats),
SHELL_SUBCMD_SET_END SHELL_SUBCMD_SET_END
}; };
SHELL_CREATE_STATIC_SUBCMD_SET(m_sub_resize) SHELL_CREATE_STATIC_SUBCMD_SET(m_sub_resize)
{ {
SHELL_CMD(default, NULL, SHELL_HELP_RESIZE_DEFAULT, cmd_resize_default), SHELL_CMD_ARG(default, NULL, SHELL_HELP_RESIZE_DEFAULT,
cmd_resize_default, 1, 0),
SHELL_SUBCMD_SET_END SHELL_SUBCMD_SET_END
}; };
SHELL_CMD_REGISTER(clear, NULL, SHELL_HELP_CLEAR, cmd_clear); SHELL_CMD_ARG_REGISTER(clear, NULL, SHELL_HELP_CLEAR, cmd_clear, 1, 0);
SHELL_CMD_REGISTER(shell, &m_sub_shell, SHELL_HELP_SHELL, cmd_shell); SHELL_CMD_REGISTER(shell, &m_sub_shell, SHELL_HELP_SHELL, NULL);
SHELL_CMD_REGISTER(help, NULL, NULL, cmd_help); SHELL_CMD_ARG_REGISTER(help, NULL, SHELL_HELP_HELP, cmd_help, 1, 255);
SHELL_CMD_REGISTER(history, NULL, SHELL_HELP_HISTORY, cmd_history); SHELL_CMD_ARG_REGISTER(history, NULL, SHELL_HELP_HISTORY, cmd_history, 1, 0);
SHELL_CMD_REGISTER(resize, &m_sub_resize, SHELL_HELP_RESIZE, cmd_resize); SHELL_CMD_ARG_REGISTER(resize, &m_sub_resize, SHELL_HELP_RESIZE, cmd_resize,
1, 1);

210
subsys/shell/shell_help.c Normal file
View file

@ -0,0 +1,210 @@
/*
* Copyright (c) 2018 Nordic Semiconductor ASA
*
* SPDX-License-Identifier: Apache-2.0
*/
#include <ctype.h>
#include "shell_ops.h"
#include "shell_help.h"
#include "shell_utils.h"
/* Function prints a string on terminal screen with requested margin.
* It takes care to not divide words.
* shell Pointer to shell instance.
* p_str Pointer to string to be printed.
* terminal_offset Requested left margin.
* offset_first_line Add margin to the first printed line.
*/
static void formatted_text_print(const struct shell *shell, const char *str,
size_t terminal_offset, bool offset_first_line)
{
size_t offset = 0;
size_t length;
if (str == NULL) {
return;
}
if (offset_first_line) {
shell_op_cursor_horiz_move(shell, terminal_offset);
}
/* Skipping whitespace. */
while (isspace((int) *(str + offset))) {
++offset;
}
while (true) {
size_t idx = 0;
length = shell_strlen(str) - offset;
if (length <=
shell->ctx->vt100_ctx.cons.terminal_wid - terminal_offset) {
for (idx = 0; idx < length; idx++) {
if (*(str + offset + idx) == '\n') {
transport_buffer_flush(shell);
shell_write(shell, str + offset, idx);
offset += idx + 1;
cursor_next_line_move(shell);
shell_op_cursor_horiz_move(shell,
terminal_offset);
break;
}
}
/* String will fit in one line. */
shell_raw_fprintf(shell->fprintf_ctx, str + offset);
break;
}
/* String is longer than terminal line so text needs to
* divide in the way to not divide words.
*/
length = shell->ctx->vt100_ctx.cons.terminal_wid
- terminal_offset;
while (true) {
/* Determining line break. */
if (isspace((int) (*(str + offset + idx)))) {
length = idx;
if (*(str + offset + idx) == '\n') {
break;
}
}
if ((idx + terminal_offset) >=
shell->ctx->vt100_ctx.cons.terminal_wid) {
/* End of line reached. */
break;
}
++idx;
}
/* Writing one line, fprintf IO buffer must be flushed
* before calling shell_write.
*/
transport_buffer_flush(shell);
shell_write(shell, str + offset, length);
offset += length;
/* Calculating text offset to ensure that next line will
* not begin with a space.
*/
while (isspace((int) (*(str + offset)))) {
++offset;
}
cursor_next_line_move(shell);
shell_op_cursor_horiz_move(shell, terminal_offset);
}
cursor_next_line_move(shell);
}
static void help_item_print(const struct shell *shell, const char *item_name,
u16_t item_name_width, const char *item_help)
{
static const u8_t tabulator[] = " ";
const u16_t offset = 2 * strlen(tabulator) + item_name_width + 1;
if (item_name == NULL) {
return;
}
if (!IS_ENABLED(CONFIG_NEWLIB_LIBC) && !IS_ENABLED(CONFIG_ARCH_POSIX)) {
/* print option name */
shell_fprintf(shell, SHELL_NORMAL, "%s%-*s%s:",
tabulator,
item_name_width, item_name,
tabulator);
} else {
u16_t tmp = item_name_width - strlen(item_name);
char space = ' ';
shell_fprintf(shell, SHELL_NORMAL, "%s%s", tabulator,
item_name);
for (u16_t i = 0; i < tmp; i++) {
shell_write(shell, &space, 1);
}
shell_fprintf(shell, SHELL_NORMAL, "%s:", tabulator);
}
if (item_help == NULL) {
cursor_next_line_move(shell);
return;
}
/* print option help */
formatted_text_print(shell, item_help, offset, false);
}
/* Function is printing command help, its subcommands name and subcommands
* help string.
*/
void shell_help_subcmd_print(const struct shell *shell)
{
const struct shell_static_entry *entry = NULL;
struct shell_static_entry static_entry;
u16_t longest_syntax = 0;
size_t cmd_idx = 0;
/* Checking if there are any subcommands available. */
if (!shell->ctx->active_cmd.subcmd) {
return;
}
/* Searching for the longest subcommand to print. */
do {
shell_cmd_get(shell->ctx->active_cmd.subcmd,
!SHELL_CMD_ROOT_LVL,
cmd_idx++, &entry, &static_entry);
if (!entry) {
break;
}
u16_t len = shell_strlen(entry->syntax);
longest_syntax = longest_syntax > len ? longest_syntax : len;
} while (cmd_idx != 0); /* too many commands */
if (cmd_idx == 1) {
return;
}
shell_fprintf(shell, SHELL_NORMAL, "Subcommands:\r\n");
/* Printing subcommands and help string (if exists). */
cmd_idx = 0;
while (true) {
shell_cmd_get(shell->ctx->active_cmd.subcmd,
!SHELL_CMD_ROOT_LVL,
cmd_idx++, &entry, &static_entry);
if (entry == NULL) {
break;
}
help_item_print(shell, entry->syntax, longest_syntax,
entry->help);
}
}
void shell_help_cmd_print(const struct shell *shell)
{
static const char cmd_sep[] = " - "; /* commands separator */
u16_t field_width = shell_strlen(shell->ctx->active_cmd.syntax) +
shell_strlen(cmd_sep);
shell_fprintf(shell, SHELL_NORMAL, "%s%s",
shell->ctx->active_cmd.syntax, cmd_sep);
formatted_text_print(shell, shell->ctx->active_cmd.help,
field_width, false);
}

30
subsys/shell/shell_help.h Normal file
View file

@ -0,0 +1,30 @@
/*
* Copyright (c) 2018 Nordic Semiconductor ASA
*
* SPDX-License-Identifier: Apache-2.0
*/
#ifndef SHELL_HELP_H__
#define SHELL_HELP_H__
#include <shell/shell.h>
#ifdef __cplusplus
extern "C" {
#endif
/* Function is printing command help string. */
void shell_help_cmd_print(const struct shell *shell);
/* Function is printing subcommands help string. */
void shell_help_subcmd_print(const struct shell *shell);
/**
* @}
*/
#ifdef __cplusplus
}
#endif
#endif /* SHELL_HELP__ */

View file

@ -262,3 +262,47 @@ void shell_op_completion_insert(const struct shell *shell,
{ {
data_insert(shell, compl, compl_len); data_insert(shell, compl, compl_len);
} }
static void shell_pend_on_txdone(const struct shell *shell)
{
if (IS_ENABLED(CONFIG_MULTITHREADING)) {
k_poll(&shell->ctx->events[SHELL_SIGNAL_TXDONE], 1, K_FOREVER);
k_poll_signal_reset(&shell->ctx->signals[SHELL_SIGNAL_TXDONE]);
} else {
/* Blocking wait in case of bare metal. */
while (!shell->ctx->internal.flags.tx_rdy) {
}
shell->ctx->internal.flags.tx_rdy = 0;
}
}
void shell_write(const struct shell *shell, const void *data,
size_t length)
{
__ASSERT_NO_MSG(shell && data);
size_t offset = 0;
size_t tmp_cnt;
while (length) {
int err = shell->iface->api->write(shell->iface,
&((const u8_t *) data)[offset], length,
&tmp_cnt);
(void)err;
__ASSERT_NO_MSG(err == 0);
__ASSERT_NO_MSG(length >= tmp_cnt);
offset += tmp_cnt;
length -= tmp_cnt;
if (tmp_cnt == 0 &&
(shell->ctx->state != SHELL_STATE_PANIC_MODE_ACTIVE)) {
shell_pend_on_txdone(shell);
}
}
}
/* Function shall be only used by the fprintf module. */
void shell_print_stream(const void *user_ctx, const char *data,
size_t data_len)
{
shell_write((const struct shell *) user_ctx, data, data_len);
}

View file

@ -6,7 +6,6 @@
#ifndef SHELL_OPS_H__ #ifndef SHELL_OPS_H__
#define SHELL_OPS_H__ #define SHELL_OPS_H__
#include <zephyr.h>
#include <shell/shell.h> #include <shell/shell.h>
#include "shell_vt100.h" #include "shell_vt100.h"
#include "shell_utils.h" #include "shell_utils.h"
@ -121,6 +120,29 @@ void shell_op_completion_insert(const struct shell *shell,
u16_t compl_len); u16_t compl_len);
bool shell_cursor_in_empty_line(const struct shell *shell); bool shell_cursor_in_empty_line(const struct shell *shell);
/* Function sends data stream to the shell instance. Each time before the
* shell_write function is called, it must be ensured that IO buffer of fprintf
* is flushed to avoid synchronization issues.
* For that purpose, use function transport_buffer_flush(shell)
*
* This function can be only used by shell module, it shall not be called
* directly.
*/
void shell_write(const struct shell *shell, const void *data,
size_t length);
/**
* @internal @brief This function shall not be used directly, it is required by
* the fprintf module.
*
* @param[in] p_user_ctx Pointer to the context for the shell instance.
* @param[in] p_data Pointer to the data buffer.
* @param[in] data_len Data buffer size.
*/
void shell_print_stream(const void *user_ctx, const char *data,
size_t data_len);
#ifdef __cplusplus #ifdef __cplusplus
} }
#endif #endif

View file

@ -6,6 +6,14 @@
#include "shell_utils.h" #include "shell_utils.h"
#include <ctype.h> #include <ctype.h>
extern const struct shell_cmd_entry __shell_root_cmds_start[0];
extern const struct shell_cmd_entry __shell_root_cmds_end[0];
static inline const struct shell_cmd_entry *shell_root_cmd_get(u32_t id)
{
return &__shell_root_cmds_start[id];
}
/* Calculates relative line number of given position in buffer */ /* Calculates relative line number of given position in buffer */
static u32_t line_num_with_buffer_offset_get(struct shell_multiline_cons *cons, static u32_t line_num_with_buffer_offset_get(struct shell_multiline_cons *cons,
u16_t buffer_pos) u16_t buffer_pos)
@ -209,6 +217,62 @@ void shell_pattern_remove(char *buff, u16_t *buff_len, const char *pattern)
memmove(pattern_addr, pattern_addr + pattern_len, shift); memmove(pattern_addr, pattern_addr + pattern_len, shift);
} }
static inline u32_t shell_root_cmd_count(void)
{
return ((u8_t *)__shell_root_cmds_end -
(u8_t *)__shell_root_cmds_start)/
sizeof(struct shell_cmd_entry);
}
/* Function returning pointer to root command matching requested syntax. */
const struct shell_cmd_entry *root_cmd_find(const char *syntax)
{
const size_t cmd_count = shell_root_cmd_count();
const struct shell_cmd_entry *cmd;
for (size_t cmd_idx = 0; cmd_idx < cmd_count; ++cmd_idx) {
cmd = shell_root_cmd_get(cmd_idx);
if (strcmp(syntax, cmd->u.entry->syntax) == 0) {
return cmd;
}
}
return NULL;
}
void shell_cmd_get(const struct shell_cmd_entry *command, size_t lvl,
size_t idx, const struct shell_static_entry **entry,
struct shell_static_entry *d_entry)
{
__ASSERT_NO_MSG(entry != NULL);
__ASSERT_NO_MSG(d_entry != NULL);
if (lvl == SHELL_CMD_ROOT_LVL) {
if (idx < shell_root_cmd_count()) {
const struct shell_cmd_entry *cmd;
cmd = shell_root_cmd_get(idx);
*entry = cmd->u.entry;
} else {
*entry = NULL;
}
return;
}
if (command == NULL) {
*entry = NULL;
return;
}
if (command->is_dynamic) {
command->u.dynamic_get(idx, d_entry);
*entry = (d_entry->syntax != NULL) ? d_entry : NULL;
} else {
*entry = (command->u.entry[idx].syntax != NULL) ?
&command->u.entry[idx] : NULL;
}
}
int shell_command_add(char *buff, u16_t *buff_len, int shell_command_add(char *buff, u16_t *buff_len,
const char *new_cmd, const char *pattern) const char *new_cmd, const char *pattern)
{ {

View file

@ -8,6 +8,7 @@
#include <zephyr.h> #include <zephyr.h>
#include <shell/shell.h> #include <shell/shell.h>
#ifdef __cplusplus #ifdef __cplusplus
extern "C" { extern "C" {
#endif #endif
@ -42,9 +43,29 @@ char shell_make_argv(size_t *argc, char **argv, char *cmd, uint8_t max_argc);
*/ */
void shell_pattern_remove(char *buff, u16_t *buff_len, const char *pattern); void shell_pattern_remove(char *buff, u16_t *buff_len, const char *pattern);
/* @brief Function shall be used to search commands.
*
* It moves the pointer entry to command of static command structure. If the
* command cannot be found, the function will set entry to NULL.
*
* @param command Pointer to command which will be processed (no matter
* the root command).
* @param lvl Level of the requested command.
* @param idx Index of the requested command.
* @param entry Pointer which points to subcommand[idx] after function
* execution.
* @param st_entry Pointer to the structure where dynamic entry data can be
* stored.
*/
void shell_cmd_get(const struct shell_cmd_entry *command, size_t lvl,
size_t idx, const struct shell_static_entry **entry,
struct shell_static_entry *d_entry);
int shell_command_add(char *buff, u16_t *buff_len, int shell_command_add(char *buff, u16_t *buff_len,
const char *new_cmd, const char *pattern); const char *new_cmd, const char *pattern);
const struct shell_cmd_entry *root_cmd_find(const char *syntax);
void shell_spaces_trim(char *str); void shell_spaces_trim(char *str);
/** @brief Remove white chars from beginning and end of command buffer. /** @brief Remove white chars from beginning and end of command buffer.
@ -52,6 +73,11 @@ void shell_spaces_trim(char *str);
*/ */
void shell_buffer_trim(char *buff, u16_t *buff_len); void shell_buffer_trim(char *buff, u16_t *buff_len);
static inline void transport_buffer_flush(const struct shell *shell)
{
shell_fprintf_buffer_flush(shell->fprintf_ctx);
}
#ifdef __cplusplus #ifdef __cplusplus
} }
#endif #endif

View file

@ -33,12 +33,6 @@ static bool hrs_simulate;
static int cmd_hrs_simulate(const struct shell *shell, static int cmd_hrs_simulate(const struct shell *shell,
size_t argc, char *argv[]) size_t argc, char *argv[])
{ {
int err = shell_cmd_precheck(shell, (argc == 2));
if (err) {
return err;
}
if (!strcmp(argv[1], "on")) { if (!strcmp(argv[1], "on")) {
static bool hrs_registered; static bool hrs_registered;
@ -68,34 +62,22 @@ static int cmd_hrs_simulate(const struct shell *shell,
SHELL_CREATE_STATIC_SUBCMD_SET(hrs_cmds) { SHELL_CREATE_STATIC_SUBCMD_SET(hrs_cmds) {
#if defined(CONFIG_BT_CONN) #if defined(CONFIG_BT_CONN)
SHELL_CMD(hrs-simulate, NULL, SHELL_CMD_ARG(hrs-simulate, NULL,
"register and simulate Heart Rate Service <value: on, off>", "register and simulate Heart Rate Service <value: on, off>",
cmd_hrs_simulate), cmd_hrs_simulate, 2, 0),
#endif /* CONFIG_BT_CONN */ #endif /* CONFIG_BT_CONN */
SHELL_SUBCMD_SET_END SHELL_SUBCMD_SET_END
}; };
static int cmd_hrs(const struct shell *shell, size_t argc, char **argv) static int cmd_hrs(const struct shell *shell, size_t argc, char **argv)
{ {
int err = shell_cmd_precheck(shell, (argc == 2));
if (argc == 1) {
shell_help_print(shell);
/* shell_cmd_precheck returns 1 when help is printed */
return 1;
}
if (err) {
return err;
}
shell_error(shell, "%s unknown parameter: %s", argv[0], argv[1]); shell_error(shell, "%s unknown parameter: %s", argv[0], argv[1]);
return -ENOEXEC; return -ENOEXEC;
} }
SHELL_CMD_REGISTER(hrs, &hrs_cmds, "Heart Rate Service shell commands", SHELL_CMD_ARG_REGISTER(hrs, &hrs_cmds, "Heart Rate Service shell commands",
cmd_hrs); cmd_hrs, 2, 0);
void main(void) void main(void)
{ {

View file

@ -34,8 +34,8 @@ static void test_shell_execute_cmd(const char *cmd, int result)
static void test_cmd_help(void) static void test_cmd_help(void)
{ {
test_shell_execute_cmd("help", 0); test_shell_execute_cmd("help", 0);
test_shell_execute_cmd("help -h", 0); test_shell_execute_cmd("help -h", 1);
test_shell_execute_cmd("help --help", 0); test_shell_execute_cmd("help --help", 1);
test_shell_execute_cmd("help dummy", 0); test_shell_execute_cmd("help dummy", 0);
test_shell_execute_cmd("help dummy dummy", 0); test_shell_execute_cmd("help dummy dummy", 0);
} }
@ -53,13 +53,13 @@ static void test_cmd_shell(void)
{ {
test_shell_execute_cmd("shell -h", 1); test_shell_execute_cmd("shell -h", 1);
test_shell_execute_cmd("shell --help", 1); test_shell_execute_cmd("shell --help", 1);
test_shell_execute_cmd("shell dummy", -EINVAL); test_shell_execute_cmd("shell dummy", 1);
test_shell_execute_cmd("shell dummy dummy", -EINVAL); test_shell_execute_cmd("shell dummy dummy", 1);
/* subcommand: backspace_mode */ /* subcommand: backspace_mode */
test_shell_execute_cmd("shell backspace_mode -h", 1); test_shell_execute_cmd("shell backspace_mode -h", 1);
test_shell_execute_cmd("shell backspace_mode --help", 1); test_shell_execute_cmd("shell backspace_mode --help", 1);
test_shell_execute_cmd("shell backspace_mode dummy", -EINVAL); test_shell_execute_cmd("shell backspace_mode dummy", 1);
test_shell_execute_cmd("shell backspace_mode backspace", 0); test_shell_execute_cmd("shell backspace_mode backspace", 0);
test_shell_execute_cmd("shell backspace_mode backspace -h", 1); test_shell_execute_cmd("shell backspace_mode backspace -h", 1);
@ -78,8 +78,8 @@ static void test_cmd_shell(void)
/* subcommand: colors */ /* subcommand: colors */
test_shell_execute_cmd("shell colors -h", 1); test_shell_execute_cmd("shell colors -h", 1);
test_shell_execute_cmd("shell colors --help", 1); test_shell_execute_cmd("shell colors --help", 1);
test_shell_execute_cmd("shell colors dummy", -EINVAL); test_shell_execute_cmd("shell colors dummy", 1);
test_shell_execute_cmd("shell colors dummy dummy", -EINVAL); test_shell_execute_cmd("shell colors dummy dummy", 1);
test_shell_execute_cmd("shell colors off", 0); test_shell_execute_cmd("shell colors off", 0);
test_shell_execute_cmd("shell colors off -h", 1); test_shell_execute_cmd("shell colors off -h", 1);
@ -113,11 +113,11 @@ static void test_cmd_shell(void)
test_shell_execute_cmd("shell echo on dummy dummy", -EINVAL); test_shell_execute_cmd("shell echo on dummy dummy", -EINVAL);
/* subcommand: stats */ /* subcommand: stats */
test_shell_execute_cmd("shell stats", -EINVAL); test_shell_execute_cmd("shell stats", 1);
test_shell_execute_cmd("shell stats -h", 1); test_shell_execute_cmd("shell stats -h", 1);
test_shell_execute_cmd("shell stats --help", 1); test_shell_execute_cmd("shell stats --help", 1);
test_shell_execute_cmd("shell stats dummy", -EINVAL); test_shell_execute_cmd("shell stats dummy", 1);
test_shell_execute_cmd("shell stats dummy dummy", -EINVAL); test_shell_execute_cmd("shell stats dummy dummy", 1);
test_shell_execute_cmd("shell stats reset", 0); test_shell_execute_cmd("shell stats reset", 0);
test_shell_execute_cmd("shell stats reset -h", 1); test_shell_execute_cmd("shell stats reset -h", 1);
@ -195,10 +195,11 @@ static void test_shell_wildcards_dynamic(void)
static int cmd_test_module(const struct shell *shell, size_t argc, char **argv) static int cmd_test_module(const struct shell *shell, size_t argc, char **argv)
{ {
ARG_UNUSED(argv); ARG_UNUSED(argv);
ARG_UNUSED(argc);
return shell_cmd_precheck(shell, (argc == 1)); return 0;
} }
SHELL_CMD_REGISTER(test_shell_cmd, NULL, NULL, cmd_test_module); SHELL_CMD_ARG_REGISTER(test_shell_cmd, NULL, "help", cmd_test_module, 1, 0);
static int cmd_wildcard(const struct shell *shell, size_t argc, char **argv) static int cmd_wildcard(const struct shell *shell, size_t argc, char **argv)