shell: add select command
The "select" command has been implemented, which allows user to narrow down the command tree. This implementation differs from the "select" command available in the legacy shell. In a new implementation, if the selected command has a handler and if the user has not entered the registered subcommand, the shell will call the handler of selected command and pass the text as arguments. This may be useful, for example, if someone wants to use the shell as an interface to a modem that supports AT commands. Instead of each time you write e.g: at at+command1 at at+command2 at at+command3 user can execute following commands: select at at+command1 at+command2 at+command3 where: at - root command for passing at commands to the modem at+commandX - at command passed to the modem. Signed-off-by: Jakub Rzeszutko <jakub.rzeszutko@nordicsemi.no>
This commit is contained in:
parent
fde86da6f5
commit
b633e431a4
8 changed files with 227 additions and 96 deletions
|
@ -555,6 +555,9 @@ struct shell_ctx {
|
|||
/*!< Currently executed command.*/
|
||||
struct shell_static_entry active_cmd;
|
||||
|
||||
/* New root command. If NULL shell uses default root commands. */
|
||||
const struct shell_static_entry *selected_cmd;
|
||||
|
||||
/*!< VT100 color and cursor position, terminal width.*/
|
||||
struct shell_vt100_ctx vt100_ctx;
|
||||
|
||||
|
|
|
@ -140,6 +140,13 @@ config SHELL_CMDS_RESIZE
|
|||
must be called to ensure correct text display on the terminal screen.
|
||||
The resize command can be turned off to save code memory (~0,5k).
|
||||
|
||||
config SHELL_CMDS_SELECT
|
||||
bool "Enable select command"
|
||||
depends on SHELL_CMDS
|
||||
help
|
||||
This option enables select command. It can be used to set new root
|
||||
command. Exit to main command tree is with alt+r.
|
||||
|
||||
config SHELL_LOG_BACKEND
|
||||
bool
|
||||
default y if LOG
|
||||
|
|
|
@ -207,62 +207,6 @@ static void history_handle(const struct shell *shell, bool up)
|
|||
shell_op_cond_next_line(shell);
|
||||
}
|
||||
|
||||
static const struct shell_static_entry *find_cmd(
|
||||
const struct shell_cmd_entry *cmd,
|
||||
size_t lvl,
|
||||
char *cmd_str,
|
||||
struct shell_static_entry *d_entry)
|
||||
{
|
||||
const struct shell_static_entry *entry = NULL;
|
||||
size_t idx = 0;
|
||||
|
||||
do {
|
||||
shell_cmd_get(cmd, lvl, idx++, &entry, d_entry);
|
||||
if (entry && (strcmp(cmd_str, entry->syntax) == 0)) {
|
||||
return entry;
|
||||
}
|
||||
} while (entry);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/** @brief Function for getting last valid command in list of arguments. */
|
||||
static const struct shell_static_entry *get_last_command(
|
||||
const struct shell *shell,
|
||||
size_t argc,
|
||||
char *argv[],
|
||||
size_t *match_arg,
|
||||
struct shell_static_entry *d_entry)
|
||||
{
|
||||
const struct shell_static_entry *prev_entry = NULL;
|
||||
const struct shell_cmd_entry *prev_cmd = NULL;
|
||||
const struct shell_static_entry *entry = NULL;
|
||||
*match_arg = SHELL_CMD_ROOT_LVL;
|
||||
|
||||
while (*match_arg < argc) {
|
||||
|
||||
if (IS_ENABLED(CONFIG_SHELL_WILDCARD)) {
|
||||
/* ignore wildcard argument */
|
||||
if (shell_wildcard_character_exist(argv[*match_arg])) {
|
||||
(*match_arg)++;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
entry = find_cmd(prev_cmd, *match_arg, argv[*match_arg],
|
||||
d_entry);
|
||||
if (entry) {
|
||||
prev_cmd = entry->subcmd;
|
||||
prev_entry = entry;
|
||||
(*match_arg)++;
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return entry;
|
||||
}
|
||||
|
||||
static inline u16_t completion_space_get(const struct shell *shell)
|
||||
{
|
||||
u16_t space = (CONFIG_SHELL_CMD_BUFF_SIZE - 1) -
|
||||
|
@ -273,7 +217,7 @@ static inline u16_t completion_space_get(const struct shell *shell)
|
|||
/* Prepare arguments and return number of space available for completion. */
|
||||
static bool tab_prepare(const struct shell *shell,
|
||||
const struct shell_static_entry **cmd,
|
||||
char **argv, size_t *argc,
|
||||
char ***argv, size_t *argc,
|
||||
size_t *complete_arg_idx,
|
||||
struct shell_static_entry *d_entry)
|
||||
{
|
||||
|
@ -290,9 +234,16 @@ static bool tab_prepare(const struct shell *shell,
|
|||
shell->ctx->temp_buff[shell->ctx->cmd_buff_pos] = '\0';
|
||||
|
||||
/* Create argument list. */
|
||||
(void)shell_make_argv(argc, argv, shell->ctx->temp_buff,
|
||||
(void)shell_make_argv(argc, *argv, shell->ctx->temp_buff,
|
||||
CONFIG_SHELL_ARGC_MAX);
|
||||
|
||||
if (IS_ENABLED(CONFIG_SHELL_CMDS_SELECT) &&
|
||||
(strcmp("select", (*argv)[0]) == 0) &&
|
||||
!shell_in_select_mode(shell)) {
|
||||
*argv = *argv + 1;
|
||||
*argc = *argc - 1;
|
||||
}
|
||||
|
||||
/* If last command is not completed (followed by space) it is treated
|
||||
* as uncompleted one.
|
||||
*/
|
||||
|
@ -308,11 +259,11 @@ static bool tab_prepare(const struct shell *shell,
|
|||
|
||||
search_argc = space ? *argc : *argc - 1;
|
||||
|
||||
*cmd = get_last_command(shell, search_argc, argv, complete_arg_idx,
|
||||
d_entry);
|
||||
*cmd = shell_get_last_command(shell, search_argc, *argv,
|
||||
complete_arg_idx, d_entry, false);
|
||||
|
||||
/* if search_argc == 0 (empty command line) get_last_command will return
|
||||
* NULL tab is allowed, otherwise not.
|
||||
/* if search_argc == 0 (empty command line) shell_get_last_command will
|
||||
* return NULL tab is allowed, otherwise not.
|
||||
*/
|
||||
if ((*cmd == NULL) && (search_argc != 0)) {
|
||||
return false;
|
||||
|
@ -336,7 +287,8 @@ static inline bool is_completion_candidate(const char *candidate,
|
|||
return (strncmp(candidate, str, len) == 0) ? true : false;
|
||||
}
|
||||
|
||||
static void find_completion_candidates(const struct shell_static_entry *cmd,
|
||||
static void find_completion_candidates(const struct shell *shell,
|
||||
const struct shell_static_entry *cmd,
|
||||
const char *incompl_cmd,
|
||||
size_t *first_idx, size_t *cnt,
|
||||
u16_t *longest)
|
||||
|
@ -354,7 +306,7 @@ static void find_completion_candidates(const struct shell_static_entry *cmd,
|
|||
bool is_empty;
|
||||
bool is_candidate;
|
||||
|
||||
shell_cmd_get(cmd ? cmd->subcmd : NULL, cmd ? 1 : 0,
|
||||
shell_cmd_get(shell, cmd ? cmd->subcmd : NULL, cmd ? 1 : 0,
|
||||
idx, &candidate, &dynamic_entry);
|
||||
|
||||
if (!candidate) {
|
||||
|
@ -392,7 +344,7 @@ static void autocomplete(const struct shell *shell,
|
|||
/* shell->ctx->active_cmd can be safely used outside of command context
|
||||
* to save stack
|
||||
*/
|
||||
shell_cmd_get(cmd ? cmd->subcmd : NULL, cmd ? 1 : 0,
|
||||
shell_cmd_get(shell, cmd ? cmd->subcmd : NULL, cmd ? 1 : 0,
|
||||
subcmd_idx, &match, &shell->ctx->active_cmd);
|
||||
cmd_len = shell_strlen(match->syntax);
|
||||
|
||||
|
@ -457,7 +409,7 @@ static void tab_options_print(const struct shell *shell,
|
|||
/* shell->ctx->active_cmd can be safely used outside of command
|
||||
* context to save stack
|
||||
*/
|
||||
shell_cmd_get(cmd ? cmd->subcmd : NULL, cmd ? 1 : 0,
|
||||
shell_cmd_get(shell, cmd ? cmd->subcmd : NULL, cmd ? 1 : 0,
|
||||
idx, &match, &shell->ctx->active_cmd);
|
||||
idx++;
|
||||
is_empty = is_empty_cmd(match);
|
||||
|
@ -474,7 +426,8 @@ static void tab_options_print(const struct shell *shell,
|
|||
shell_print_prompt_and_cmd(shell);
|
||||
}
|
||||
|
||||
static u16_t common_beginning_find(const struct shell_static_entry *cmd,
|
||||
static u16_t common_beginning_find(const struct shell *shell,
|
||||
const struct shell_static_entry *cmd,
|
||||
const char **str,
|
||||
size_t first, size_t cnt, u16_t arg_len)
|
||||
{
|
||||
|
@ -485,7 +438,7 @@ static u16_t common_beginning_find(const struct shell_static_entry *cmd,
|
|||
|
||||
__ASSERT_NO_MSG(cnt > 1);
|
||||
|
||||
shell_cmd_get(cmd ? cmd->subcmd : NULL, cmd ? 1 : 0,
|
||||
shell_cmd_get(shell, cmd ? cmd->subcmd : NULL, cmd ? 1 : 0,
|
||||
first, &match, &dynamic_entry);
|
||||
|
||||
*str = match->syntax;
|
||||
|
@ -495,7 +448,7 @@ static u16_t common_beginning_find(const struct shell_static_entry *cmd,
|
|||
const struct shell_static_entry *match2;
|
||||
int curr_common;
|
||||
|
||||
shell_cmd_get(cmd ? cmd->subcmd : NULL, cmd ? 1 : 0,
|
||||
shell_cmd_get(shell, cmd ? cmd->subcmd : NULL, cmd ? 1 : 0,
|
||||
idx++, &match2, &dynamic_entry2);
|
||||
|
||||
if (match2 == NULL) {
|
||||
|
@ -520,8 +473,8 @@ static void partial_autocomplete(const struct shell *shell,
|
|||
{
|
||||
const char *completion;
|
||||
u16_t arg_len = shell_strlen(arg);
|
||||
u16_t common = common_beginning_find(cmd, &completion,
|
||||
first, cnt, arg_len);
|
||||
u16_t common = common_beginning_find(shell, cmd, &completion, first,
|
||||
cnt, arg_len);
|
||||
|
||||
if (common) {
|
||||
shell_op_completion_insert(shell, &completion[arg_len],
|
||||
|
@ -672,16 +625,25 @@ static int execute(const struct shell *shell)
|
|||
}
|
||||
}
|
||||
|
||||
shell_cmd_get(p_cmd, cmd_lvl, cmd_idx++, &p_static_entry,
|
||||
shell_cmd_get(shell, p_cmd, cmd_lvl, cmd_idx++, &p_static_entry,
|
||||
&d_entry);
|
||||
|
||||
if ((cmd_idx == 0) || (p_static_entry == NULL)) {
|
||||
if (cmd_lvl == 0) {
|
||||
if (cmd_lvl == 0 &&
|
||||
(!shell_in_select_mode(shell) ||
|
||||
shell->ctx->selected_cmd->handler == NULL)) {
|
||||
shell_internal_fprintf(shell, SHELL_ERROR,
|
||||
"%s%s\n", argv[0],
|
||||
SHELL_MSG_CMD_NOT_FOUND);
|
||||
return -ENOEXEC;
|
||||
}
|
||||
if (IS_ENABLED(CONFIG_SHELL_CMDS_SELECT) &&
|
||||
shell_in_select_mode(shell) &&
|
||||
shell->ctx->selected_cmd->handler != NULL) {
|
||||
p_static_entry = shell->ctx->selected_cmd;
|
||||
shell->ctx->active_cmd = *p_static_entry;
|
||||
cmd_with_handler_lvl = cmd_lvl;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -739,24 +701,26 @@ static int execute(const struct shell *shell)
|
|||
static void tab_handle(const struct shell *shell)
|
||||
{
|
||||
/* +1 reserved for NULL in function shell_make_argv */
|
||||
char *argv[CONFIG_SHELL_ARGC_MAX + 1];
|
||||
char *__argv[CONFIG_SHELL_ARGC_MAX + 1];
|
||||
/* d_entry - placeholder for dynamic command */
|
||||
struct shell_static_entry d_entry;
|
||||
const struct shell_static_entry *cmd;
|
||||
char **argv = __argv;
|
||||
size_t first = 0;
|
||||
size_t arg_idx;
|
||||
u16_t longest;
|
||||
size_t argc;
|
||||
size_t cnt;
|
||||
|
||||
bool tab_possible = tab_prepare(shell, &cmd, argv, &argc,
|
||||
&arg_idx, &d_entry);
|
||||
bool tab_possible = tab_prepare(shell, &cmd, &argv, &argc, &arg_idx,
|
||||
&d_entry);
|
||||
|
||||
if (tab_possible == false) {
|
||||
return;
|
||||
}
|
||||
|
||||
find_completion_candidates(cmd, argv[arg_idx], &first, &cnt, &longest);
|
||||
find_completion_candidates(shell, cmd, argv[arg_idx], &first, &cnt,
|
||||
&longest);
|
||||
|
||||
if (cnt == 1) {
|
||||
/* Autocompletion.*/
|
||||
|
@ -778,6 +742,15 @@ static void alt_metakeys_handle(const struct shell *shell, char data)
|
|||
shell_op_cursor_word_move(shell, -1);
|
||||
} else if (data == SHELL_VT100_ASCII_ALT_F) {
|
||||
shell_op_cursor_word_move(shell, 1);
|
||||
} else if (data == SHELL_VT100_ASCII_ALT_R &&
|
||||
IS_ENABLED(CONFIG_SHELL_CMDS_SELECT)) {
|
||||
if (shell->ctx->selected_cmd != NULL) {
|
||||
shell_cmd_line_erase(shell);
|
||||
shell_internal_fprintf(shell, SHELL_WARNING,
|
||||
"Restored default root commands\n");
|
||||
shell->ctx->selected_cmd = NULL;
|
||||
shell_print_prompt_and_cmd(shell);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -887,7 +860,8 @@ static void state_collect(const struct shell *shell)
|
|||
switch (shell->ctx->receive_state) {
|
||||
case SHELL_RECEIVE_DEFAULT:
|
||||
if (process_nl(shell, data)) {
|
||||
if (!shell->ctx->cmd_buff_len) {
|
||||
if (!shell->ctx->cmd_buff_len &&
|
||||
shell->ctx->selected_cmd == NULL) {
|
||||
history_mode_exit(shell);
|
||||
cursor_next_line_move(shell);
|
||||
} else {
|
||||
|
|
|
@ -40,6 +40,12 @@
|
|||
#define SHELL_HELP_ECHO_OFF \
|
||||
"Disable shell echo. Editing keys and meta-keys are not handled"
|
||||
|
||||
#define SHELL_HELP_SELECT "Selects new root command. In order for the " \
|
||||
"command to be selected, it must meet the criteria:\n" \
|
||||
" - it is a static command\n" \
|
||||
" - it is not preceded by a dynamic command\n" \
|
||||
"Return to the main command tree is done by pressing alt+r."
|
||||
|
||||
#define SHELL_HELP_SHELL "Useful, not Unix-like shell commands."
|
||||
#define SHELL_HELP_HELP "Prints help message."
|
||||
|
||||
|
@ -374,6 +380,27 @@ static int cmd_resize(const struct shell *shell, size_t argc, char **argv)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int cmd_select(const struct shell *shell, size_t argc, char **argv)
|
||||
{
|
||||
const struct shell_static_entry *candidate = NULL;
|
||||
struct shell_static_entry entry;
|
||||
size_t matching_argc;
|
||||
|
||||
argc--;
|
||||
argv = argv + 1;
|
||||
candidate = shell_get_last_command(shell, argc, argv, &matching_argc,
|
||||
&entry, true);
|
||||
|
||||
if ((candidate != NULL) && (argc == matching_argc)) {
|
||||
shell->ctx->selected_cmd = candidate;
|
||||
return 0;
|
||||
}
|
||||
|
||||
shell_error(shell, "Cannot select command");
|
||||
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
SHELL_STATIC_SUBCMD_SET_CREATE(m_sub_colors,
|
||||
SHELL_CMD_ARG(off, NULL, SHELL_HELP_COLORS_OFF, cmd_colors_off, 1, 0),
|
||||
SHELL_CMD_ARG(on, NULL, SHELL_HELP_COLORS_ON, cmd_colors_on, 1, 0),
|
||||
|
@ -425,3 +452,5 @@ SHELL_COND_CMD_ARG_REGISTER(CONFIG_SHELL_HISTORY, history, NULL,
|
|||
SHELL_HELP_HISTORY, cmd_history, 1, 0);
|
||||
SHELL_COND_CMD_ARG_REGISTER(CONFIG_SHELL_CMDS_RESIZE, resize, &m_sub_resize,
|
||||
SHELL_HELP_RESIZE, cmd_resize, 1, 1);
|
||||
SHELL_COND_CMD_ARG_REGISTER(CONFIG_SHELL_CMDS_SELECT, select, NULL,
|
||||
SHELL_HELP_SELECT, cmd_select, 2, 255);
|
||||
|
|
|
@ -159,7 +159,7 @@ void shell_help_subcmd_print(const struct shell *shell)
|
|||
|
||||
/* Searching for the longest subcommand to print. */
|
||||
do {
|
||||
shell_cmd_get(shell->ctx->active_cmd.subcmd,
|
||||
shell_cmd_get(shell, shell->ctx->active_cmd.subcmd,
|
||||
!SHELL_CMD_ROOT_LVL,
|
||||
cmd_idx++, &entry, &static_entry);
|
||||
|
||||
|
@ -182,7 +182,7 @@ void shell_help_subcmd_print(const struct shell *shell)
|
|||
cmd_idx = 0;
|
||||
|
||||
while (true) {
|
||||
shell_cmd_get(shell->ctx->active_cmd.subcmd,
|
||||
shell_cmd_get(shell, shell->ctx->active_cmd.subcmd,
|
||||
!SHELL_CMD_ROOT_LVL,
|
||||
cmd_idx++, &entry, &static_entry);
|
||||
|
||||
|
|
|
@ -3,8 +3,9 @@
|
|||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
#include "shell_utils.h"
|
||||
#include <ctype.h>
|
||||
#include "shell_utils.h"
|
||||
#include "shell_wildcard.h"
|
||||
|
||||
extern const struct shell_cmd_entry __shell_root_cmds_start[0];
|
||||
extern const struct shell_cmd_entry __shell_root_cmds_end[0];
|
||||
|
@ -240,39 +241,127 @@ const struct shell_static_entry *shell_root_cmd_find(const char *syntax)
|
|||
return NULL;
|
||||
}
|
||||
|
||||
void shell_cmd_get(const struct shell_cmd_entry *command, size_t lvl,
|
||||
void shell_cmd_get(const struct shell *shell,
|
||||
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);
|
||||
|
||||
*entry = NULL;
|
||||
|
||||
if (lvl == SHELL_CMD_ROOT_LVL) {
|
||||
if (idx < shell_root_cmd_count()) {
|
||||
if (shell_in_select_mode(shell) &&
|
||||
IS_ENABLED(CONFIG_SHELL_CMDS_SELECT)) {
|
||||
const struct shell_static_entry *ptr =
|
||||
shell->ctx->selected_cmd;
|
||||
if (ptr->subcmd->u.entry[idx].syntax != NULL) {
|
||||
*entry = &ptr->subcmd->u.entry[idx];
|
||||
}
|
||||
} else 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;
|
||||
if (d_entry->syntax != NULL) {
|
||||
*entry = d_entry;
|
||||
}
|
||||
} else {
|
||||
*entry = (command->u.entry[idx].syntax != NULL) ?
|
||||
&command->u.entry[idx] : NULL;
|
||||
if (command->u.entry[idx].syntax != NULL) {
|
||||
*entry = &command->u.entry[idx];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Function returns pointer to a command matching given pattern.
|
||||
*
|
||||
* @param shell Shell instance.
|
||||
* @param cmd Pointer to commands array that will be searched.
|
||||
* @param lvl Root command indicator. If set to 0 shell will search
|
||||
* for pattern in root commands.
|
||||
* @param cmd_str Command pattern to be found.
|
||||
* @param d_entry Shell static command descriptor.
|
||||
*
|
||||
* @return Pointer to found command.
|
||||
*/
|
||||
static const struct shell_static_entry *find_cmd(
|
||||
const struct shell *shell,
|
||||
const struct shell_cmd_entry *cmd,
|
||||
size_t lvl,
|
||||
char *cmd_str,
|
||||
struct shell_static_entry *d_entry)
|
||||
{
|
||||
const struct shell_static_entry *entry = NULL;
|
||||
size_t idx = 0;
|
||||
|
||||
do {
|
||||
shell_cmd_get(shell, cmd, lvl, idx++, &entry, d_entry);
|
||||
if (entry && (strcmp(cmd_str, entry->syntax) == 0)) {
|
||||
return entry;
|
||||
}
|
||||
} while (entry);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
const struct shell_static_entry *shell_get_last_command(
|
||||
const struct shell *shell,
|
||||
size_t argc,
|
||||
char *argv[],
|
||||
size_t *match_arg,
|
||||
struct shell_static_entry *d_entry,
|
||||
bool only_static)
|
||||
{
|
||||
const struct shell_static_entry *prev_entry = NULL;
|
||||
const struct shell_static_entry *entry = NULL;
|
||||
const struct shell_cmd_entry *cmd = NULL;
|
||||
|
||||
*match_arg = SHELL_CMD_ROOT_LVL;
|
||||
|
||||
while (*match_arg < argc) {
|
||||
|
||||
if (IS_ENABLED(CONFIG_SHELL_WILDCARD)) {
|
||||
/* ignore wildcard argument */
|
||||
if (shell_wildcard_character_exist(argv[*match_arg])) {
|
||||
(*match_arg)++;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
entry = find_cmd(shell, cmd, *match_arg, argv[*match_arg],
|
||||
d_entry);
|
||||
if (entry) {
|
||||
cmd = entry->subcmd;
|
||||
prev_entry = entry;
|
||||
(*match_arg)++;
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
|
||||
if (cmd == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (only_static && cmd->is_dynamic) {
|
||||
(*match_arg)--;
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
return entry;
|
||||
}
|
||||
|
||||
int shell_command_add(char *buff, u16_t *buff_len,
|
||||
const char *new_cmd, const char *pattern)
|
||||
{
|
||||
|
|
|
@ -48,19 +48,42 @@ void shell_pattern_remove(char *buff, u16_t *buff_len, const char *pattern);
|
|||
* 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
|
||||
* @param shell Shell instance.
|
||||
* @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
|
||||
* @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.
|
||||
* @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,
|
||||
void shell_cmd_get(const struct shell *shell,
|
||||
const struct shell_cmd_entry *command, size_t lvl,
|
||||
size_t idx, const struct shell_static_entry **entry,
|
||||
struct shell_static_entry *d_entry);
|
||||
|
||||
|
||||
/* @internal @brief Function returns pointer to a shell's subcommands array
|
||||
* for a level given by argc and matching command patter provided in argv.
|
||||
*
|
||||
* @param shell Shell instance.
|
||||
* @param argc Number of arguments.
|
||||
* @param argv Pointer to an array with arguments.
|
||||
* @param match_arg Subcommand level of last matching argument.
|
||||
* @param d_entry Shell static command descriptor.
|
||||
* @param only_static If true search only for static commands.
|
||||
*
|
||||
* @return Pointer to found command.
|
||||
*/
|
||||
const struct shell_static_entry *shell_get_last_command(
|
||||
const struct shell *shell,
|
||||
size_t argc,
|
||||
char *argv[],
|
||||
size_t *match_arg,
|
||||
struct shell_static_entry *d_entry,
|
||||
bool only_static);
|
||||
|
||||
int shell_command_add(char *buff, u16_t *buff_len,
|
||||
const char *new_cmd, const char *pattern);
|
||||
|
||||
|
@ -75,6 +98,11 @@ static inline void transport_buffer_flush(const struct shell *shell)
|
|||
|
||||
void shell_cmd_trim(const struct shell *shell);
|
||||
|
||||
static inline bool shell_in_select_mode(const struct shell *shell)
|
||||
{
|
||||
return shell->ctx->selected_cmd == NULL ? false : true;
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -22,6 +22,7 @@
|
|||
#define SHELL_VT100_ASCII_CTRL_W (0x17)
|
||||
#define SHELL_VT100_ASCII_ALT_B (0x62)
|
||||
#define SHELL_VT100_ASCII_ALT_F (0x66)
|
||||
#define SHELL_VT100_ASCII_ALT_R (0x72)
|
||||
|
||||
#define SHELL_VT100_SETNL \
|
||||
{ \
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue