subsys : shell : Added API changing prompt

1. Added API to change shell prompt in runtime.
2. Added prompt buffer length configuration in Kconfig.

Signed-off-by: Jakub Rzeszutko <jakub.rzeszutko@nordicsemi.no>
This commit is contained in:
Jakub Rzeszutko 2018-09-21 16:41:22 +02:00 committed by Carles Cufí
commit e59b8cbef9
4 changed files with 47 additions and 14 deletions

View file

@ -349,7 +349,7 @@ extern const struct log_backend_api log_backend_shell_api;
* @brief Shell instance internals. * @brief Shell instance internals.
*/ */
struct shell { struct shell {
const char *const name; /*!< Terminal name. */ char *const prompt; /*!< shell prompt. */
const struct shell_transport *iface; /*!< Transport interface.*/ const struct shell_transport *iface; /*!< Transport interface.*/
struct shell_ctx *ctx; /*!< Internal context.*/ struct shell_ctx *ctx; /*!< Internal context.*/
@ -375,16 +375,17 @@ struct shell {
* @brief Macro for defining a shell instance. * @brief Macro for defining a shell instance.
* *
* @param[in] _name Instance name. * @param[in] _name Instance name.
* @param[in] shell_prefix Shell prefix string. * @param[in] _prompt Shell prompt string.
* @param[in] transport_iface Pointer to the transport interface. * @param[in] transport_iface Pointer to the transport interface.
* @param[in] newline_ch New line character - only allowed values are * @param[in] newline_ch New line character - only allowed values are
* '\\n' or '\\r'. * '\\n' or '\\r'.
* @param[in] log_queue_size Logger processing queue size. * @param[in] log_queue_size Logger processing queue size.
*/ */
#define SHELL_DEFINE(_name, shell_prefix, transport_iface, \ #define SHELL_DEFINE(_name, _prompt, transport_iface, \
newline_ch, log_queue_size) \ newline_ch, log_queue_size) \
static const struct shell _name; \ static const struct shell _name; \
static struct shell_ctx UTIL_CAT(_name, _ctx); \ static struct shell_ctx UTIL_CAT(_name, _ctx); \
static char _name##prompt[CONFIG_SHELL_PROMPT_LENGTH + 1] = _prompt; \
static u8_t _name##_out_buffer[CONFIG_SHELL_PRINTF_BUFF_SIZE]; \ static u8_t _name##_out_buffer[CONFIG_SHELL_PRINTF_BUFF_SIZE]; \
SHELL_LOG_BACKEND_DEFINE(_name, _name##_out_buffer, \ SHELL_LOG_BACKEND_DEFINE(_name, _name##_out_buffer, \
CONFIG_SHELL_PRINTF_BUFF_SIZE); \ CONFIG_SHELL_PRINTF_BUFF_SIZE); \
@ -397,7 +398,7 @@ struct shell {
static K_THREAD_STACK_DEFINE(_name##_stack, CONFIG_SHELL_STACK_SIZE);\ static K_THREAD_STACK_DEFINE(_name##_stack, CONFIG_SHELL_STACK_SIZE);\
static struct k_thread _name##_thread; \ static struct k_thread _name##_thread; \
static const struct shell _name = { \ static const struct shell _name = { \
.name = shell_prefix, \ .prompt = _name##prompt, \
.iface = transport_iface, \ .iface = transport_iface, \
.ctx = &UTIL_CAT(_name, _ctx), \ .ctx = &UTIL_CAT(_name, _ctx), \
.history = SHELL_HISTORY_PTR(_name), \ .history = SHELL_HISTORY_PTR(_name), \
@ -528,6 +529,17 @@ static inline bool shell_help_requested(const struct shell *shell)
void shell_help_print(const struct shell *shell, void shell_help_print(const struct shell *shell,
const struct shell_getopt_option *opt, size_t opt_len); const struct shell_getopt_option *opt, size_t opt_len);
/*
* @brief Change displayed shell prompt.
*
* @param[in] shell Pointer to the shell instance.
* @param[in] prompt New shell prompt.
*
* @return 0 success
* @return -1 new string is too long
*/
int shell_prompt_change(const struct shell *shell, char *prompt);
/* /*
* @brief Prints help if request and prints error message on wrong argument * @brief Prints help if request and prints error message on wrong argument
* count. * count.

View file

@ -67,6 +67,12 @@ config SHELL_BACKSPACE_MODE_DELETE
Some terminals send code: 0x08 (backspace) other 0x7F (delete). When Some terminals send code: 0x08 (backspace) other 0x7F (delete). When
this option is set shell will expect 0x7F for backspace key. this option is set shell will expect 0x7F for backspace key.
config SHELL_PROMPT_LENGTH
int "Maximum prompt length"
default 16
help
Maximum length of prompt name in bytes.
config SHELL_CMD_BUFF_SIZE config SHELL_CMD_BUFF_SIZE
int "Shell command buffer size" int "Shell command buffer size"
default 256 default 256

View file

@ -234,7 +234,7 @@ static void shell_state_set(const struct shell *shell, enum shell_state state)
if (state == SHELL_STATE_ACTIVE) { if (state == SHELL_STATE_ACTIVE) {
shell_cmd_buffer_clear(shell); shell_cmd_buffer_clear(shell);
shell_fprintf(shell, SHELL_INFO, "%s", shell->name); shell_fprintf(shell, SHELL_INFO, "%s", shell->prompt);
} }
} }
@ -598,7 +598,7 @@ static void tab_options_print(const struct shell *shell,
idx++; idx++;
} }
shell_fprintf(shell, SHELL_INFO, "\r\n%s", shell->name); shell_fprintf(shell, SHELL_INFO, "\r\n%s", shell->prompt);
shell_fprintf(shell, SHELL_NORMAL, "%s", shell->ctx->cmd_buff); shell_fprintf(shell, SHELL_NORMAL, "%s", shell->ctx->cmd_buff);
shell_op_cursor_position_synchronize(shell); shell_op_cursor_position_synchronize(shell);
@ -718,7 +718,7 @@ static void metakeys_handle(const struct shell *shell, char data)
case SHELL_VT100_ASCII_CTRL_L: /* CTRL + L */ case SHELL_VT100_ASCII_CTRL_L: /* CTRL + L */
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);
shell_fprintf(shell, SHELL_INFO, "%s", shell->name); shell_fprintf(shell, SHELL_INFO, "%s", shell->prompt);
if (flag_echo_is_set(shell)) { if (flag_echo_is_set(shell)) {
shell_fprintf(shell, SHELL_NORMAL, "%s", shell_fprintf(shell, SHELL_NORMAL, "%s",
shell->ctx->cmd_buff); shell->ctx->cmd_buff);
@ -1116,7 +1116,7 @@ static void shell_current_command_erase(const struct shell *shell)
static void shell_current_command_print(const struct shell *shell) static void shell_current_command_print(const struct shell *shell)
{ {
shell_fprintf(shell, SHELL_INFO, "%s", shell->name); shell_fprintf(shell, SHELL_INFO, "%s", shell->prompt);
if (flag_echo_is_set(shell)) { if (flag_echo_is_set(shell)) {
shell_fprintf(shell, SHELL_NORMAL, "%s", shell->ctx->cmd_buff); shell_fprintf(shell, SHELL_NORMAL, "%s", shell->ctx->cmd_buff);
@ -1145,7 +1145,7 @@ static int shell_instance_init(const struct shell *shell, const void *p_config,
bool use_colors) bool use_colors)
{ {
assert(shell); assert(shell);
assert(shell->ctx && shell->iface && shell->name); assert(shell->ctx && shell->iface && shell->prompt);
assert((shell->newline_char == '\n') || (shell->newline_char == '\r')); assert((shell->newline_char == '\n') || (shell->newline_char == '\r'));
int err; int err;
@ -1174,7 +1174,7 @@ static int shell_instance_init(const struct shell *shell, const void *p_config,
shell->ctx->state = SHELL_STATE_INITIALIZED; shell->ctx->state = SHELL_STATE_INITIALIZED;
shell->ctx->vt100_ctx.cons.terminal_wid = SHELL_DEFAULT_TERMINAL_WIDTH; shell->ctx->vt100_ctx.cons.terminal_wid = SHELL_DEFAULT_TERMINAL_WIDTH;
shell->ctx->vt100_ctx.cons.terminal_hei = SHELL_DEFAULT_TERMINAL_HEIGHT; shell->ctx->vt100_ctx.cons.terminal_hei = SHELL_DEFAULT_TERMINAL_HEIGHT;
shell->ctx->vt100_ctx.cons.name_len = shell_strlen(shell->name); shell->ctx->vt100_ctx.cons.name_len = shell_strlen(shell->prompt);
shell->ctx->internal.flags.use_colors = shell->ctx->internal.flags.use_colors =
IS_ENABLED(CONFIG_SHELL_VT100_COLORS); IS_ENABLED(CONFIG_SHELL_VT100_COLORS);
@ -1268,7 +1268,7 @@ int shell_init(const struct shell *shell, const void *transport_config,
static int shell_instance_uninit(const struct shell *shell) static int shell_instance_uninit(const struct shell *shell)
{ {
assert(shell); assert(shell);
assert(shell->ctx && shell->iface && shell->name); assert(shell->ctx && shell->iface && shell->prompt);
int err; int err;
if (flag_processing_is_set(shell)) { if (flag_processing_is_set(shell)) {
@ -1307,7 +1307,7 @@ int shell_uninit(const struct shell *shell)
int shell_start(const struct shell *shell) int shell_start(const struct shell *shell)
{ {
assert(shell); assert(shell);
assert(shell->ctx && shell->iface && shell->name); assert(shell->ctx && shell->iface && shell->prompt);
int err; int err;
if (shell->ctx->state != SHELL_STATE_INITIALIZED) { if (shell->ctx->state != SHELL_STATE_INITIALIZED) {
@ -1663,6 +1663,21 @@ void shell_help_print(const struct shell *shell,
help_subcmd_print(shell); help_subcmd_print(shell);
} }
int shell_prompt_change(const struct shell *shell, char *prompt)
{
size_t len = shell_strlen(prompt);
assert(shell);
assert(prompt);
if (len <= CONFIG_SHELL_PROMPT_LENGTH) {
memcpy(shell->prompt, prompt, len + 1); /* +1 for '\0' */
return 0;
}
return -1;
}
bool shell_cmd_precheck(const struct shell *shell, bool shell_cmd_precheck(const struct shell *shell,
bool arg_cnt_ok, bool arg_cnt_ok,
const struct shell_getopt_option *opt, const struct shell_getopt_option *opt,

View file

@ -29,14 +29,14 @@ void shell_op_cursor_horiz_move(const struct shell *shell, s32_t delta)
*/ */
static inline bool full_line_cmd(const struct shell *shell) static inline bool full_line_cmd(const struct shell *shell)
{ {
return ((shell->ctx->cmd_buff_len + shell_strlen(shell->name)) return ((shell->ctx->cmd_buff_len + shell_strlen(shell->prompt))
% shell->ctx->vt100_ctx.cons.terminal_wid == 0); % shell->ctx->vt100_ctx.cons.terminal_wid == 0);
} }
/* Function returns true if cursor is at beginning of an empty line. */ /* Function returns true if cursor is at beginning of an empty line. */
bool shell_cursor_in_empty_line(const struct shell *shell) bool shell_cursor_in_empty_line(const struct shell *shell)
{ {
return ((shell->ctx->cmd_buff_pos + shell_strlen(shell->name)) return ((shell->ctx->cmd_buff_pos + shell_strlen(shell->prompt))
% shell->ctx->vt100_ctx.cons.terminal_wid == 0); % shell->ctx->vt100_ctx.cons.terminal_wid == 0);
} }