shell: Shell subsystem reimplementation
New shell support features like: - multi-instance - command tree - static and dynamic commands - multiline - help print function - smart tab (autocompletion) - meta-keys - history, wildcards etc. - generic transport (initially, uart present) Signed-off-by: Jakub Rzeszutko <jakub.rzeszutko@nordicsemi.no> Signed-off-by: Krzysztof Chruscinski <krzysztof.chruscinski@nordicsemi.no> Signed-off-by: Piotr Zięcik <piotr.ziecik@nordicsemi.no>
This commit is contained in:
parent
527256501f
commit
6aed72e487
17 changed files with 3781 additions and 2 deletions
|
@ -73,3 +73,10 @@
|
|||
KEEP(*(".log_backends"));
|
||||
__log_backends_end = .;
|
||||
} GROUP_LINK_IN(ROMABLE_REGION)
|
||||
|
||||
SECTION_DATA_PROLOGUE(shell_root_cmds_sections, (OPTIONAL),)
|
||||
{
|
||||
__shell_root_cmds_start = .;
|
||||
KEEP(*(SORT(.shell_root_cmd_*)));
|
||||
__shell_root_cmds_end = .;
|
||||
} GROUP_LINK_IN(ROMABLE_REGION)
|
||||
|
|
538
include/shell/shell.h
Normal file
538
include/shell/shell.h
Normal file
|
@ -0,0 +1,538 @@
|
|||
/*
|
||||
* Copyright (c) 2018 Nordic Semiconductor ASA
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#ifndef SHELL_H__
|
||||
#define SHELL_H__
|
||||
|
||||
#include <zephyr.h>
|
||||
#include <shell/shell_types.h>
|
||||
#include <shell/shell_fprintf.h>
|
||||
#include <logging/log_backend.h>
|
||||
#include <logging/log_instance.h>
|
||||
#include <logging/log.h>
|
||||
#include <misc/util.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#define SHELL_RX_BUFF_SIZE 16
|
||||
|
||||
#ifndef CONFIG_SHELL_CMD_BUFF_SIZE
|
||||
#define CONFIG_SHELL_CMD_BUFF_SIZE 0
|
||||
#endif
|
||||
|
||||
#ifndef CONFIG_SHELL_PRINTF_BUFF_SIZE
|
||||
#define CONFIG_SHELL_PRINTF_BUFF_SIZE 0
|
||||
#endif
|
||||
|
||||
#define SHELL_CMD_ROOT_LVL (0u)
|
||||
|
||||
/*
|
||||
* @defgroup shell Shell
|
||||
* @ingroup subsys
|
||||
*
|
||||
* @brief Module for providing shell.
|
||||
*
|
||||
* @{
|
||||
*/
|
||||
|
||||
struct shell_static_entry;
|
||||
|
||||
/*
|
||||
* @brief Shell dynamic command descriptor.
|
||||
*
|
||||
* @details Function shall fill the received shell_static_entry structure
|
||||
* with requested (idx) dynamic subcommand data. If there is more than
|
||||
* one dynamic subcommand available, the function shall ensure that the
|
||||
* returned commands: entry->syntax are sorted in alphabetical order.
|
||||
* If idx exceeds the available dynamic subcommands, the function must
|
||||
* write to entry->syntax NULL value. This will indicate to the shell
|
||||
* module that there are no more dynamic commands to read.
|
||||
*/
|
||||
typedef void (*shell_dynamic_get)(size_t idx,
|
||||
struct shell_static_entry *entry);
|
||||
|
||||
/*
|
||||
* @brief Shell command descriptor.
|
||||
*/
|
||||
struct shell_cmd_entry {
|
||||
bool is_dynamic;
|
||||
union {
|
||||
/*!< Pointer to function returning dynamic commands.*/
|
||||
shell_dynamic_get dynamic_get;
|
||||
|
||||
/*!< Pointer to array of static commands. */
|
||||
const struct shell_static_entry *entry;
|
||||
} u;
|
||||
};
|
||||
|
||||
struct shell;
|
||||
|
||||
/*
|
||||
* @brief Shell command handler prototype.
|
||||
*/
|
||||
typedef void (*shell_cmd_handler)(const struct shell *shell,
|
||||
size_t argc, char **argv);
|
||||
|
||||
/*
|
||||
* @brief Shell static command descriptor.
|
||||
*/
|
||||
struct shell_static_entry {
|
||||
const char *syntax; /*!< Command syntax strings. */
|
||||
const char *help; /*!< Command help string. */
|
||||
const struct shell_cmd_entry *subcmd; /*!< Pointer to subcommand. */
|
||||
shell_cmd_handler handler; /*!< Command handler. */
|
||||
};
|
||||
|
||||
#define SHELL_CMD_NAME(name) UTIL_CAT(shell_cmd_, name)
|
||||
/*
|
||||
* @brief Macro for defining and adding a root command (level 0).
|
||||
*
|
||||
* @note Each root command shall have unique syntax.
|
||||
*
|
||||
* @param[in] syntax Command syntax (for example: history).
|
||||
* @param[in] subcmd Pointer to a subcommands array.
|
||||
* @param[in] help Pointer to a command help string.
|
||||
* @param[in] handler Pointer to a function handler.
|
||||
*/
|
||||
#define SHELL_CMD_REGISTER(syntax, subcmd, help, handler) \
|
||||
static const struct shell_static_entry UTIL_CAT(shell_, syntax) = \
|
||||
SHELL_CMD(syntax, subcmd, help, handler); \
|
||||
static const struct shell_cmd_entry UTIL_CAT(shell_cmd_, syntax) \
|
||||
__attribute__ ((section("." \
|
||||
STRINGIFY(UTIL_CAT(shell_root_cmd_, syntax))))) \
|
||||
__attribute__((used)) = { \
|
||||
.is_dynamic = false, \
|
||||
.u.entry = &UTIL_CAT(shell_, syntax) \
|
||||
}
|
||||
|
||||
/*
|
||||
* @brief Macro for creating a subcommand set. It must be used outside of any
|
||||
* function body.
|
||||
*
|
||||
* @param[in] name Name of the subcommand set.
|
||||
*/
|
||||
#define SHELL_CREATE_STATIC_SUBCMD_SET(name) \
|
||||
static const struct shell_static_entry shell_##name[]; \
|
||||
static const struct shell_cmd_entry name = { \
|
||||
.is_dynamic = false, \
|
||||
.u.entry = shell_##name \
|
||||
}; \
|
||||
static const struct shell_static_entry shell_##name[] =
|
||||
|
||||
/*
|
||||
* @brief Define ending subcommands set.
|
||||
*
|
||||
*/
|
||||
#define SHELL_SUBCMD_SET_END {NULL}
|
||||
|
||||
/*
|
||||
* @brief Macro for creating a dynamic entry.
|
||||
*
|
||||
* @param[in] name Name of the dynamic entry.
|
||||
* @param[in] get Pointer to the function returning dynamic commands array
|
||||
*/
|
||||
#define SHELL_CREATE_DYNAMIC_CMD(name, get) \
|
||||
static const struct shell_cmd_entry name = { \
|
||||
.is_dynamic = true, \
|
||||
.u.dynamic_get = get \
|
||||
}
|
||||
|
||||
/*
|
||||
* @brief Initializes a shell command.
|
||||
*
|
||||
* @param[in] _syntax Command syntax (for example: history).
|
||||
* @param[in] _subcmd Pointer to a subcommands array.
|
||||
* @param[in] _help Pointer to a command help string.
|
||||
* @param[in] _handler Pointer to a function handler.
|
||||
*/
|
||||
#define SHELL_CMD(_syntax, _subcmd, _help, _handler) { \
|
||||
.syntax = (const char *)STRINGIFY(_syntax), \
|
||||
.subcmd = _subcmd, \
|
||||
.help = (const char *)_help, \
|
||||
.handler = _handler \
|
||||
}
|
||||
|
||||
/*
|
||||
* @internal @brief Internal shell state in response to data received from the
|
||||
* terminal.
|
||||
*/
|
||||
enum shell_receive_state {
|
||||
SHELL_RECEIVE_DEFAULT,
|
||||
SHELL_RECEIVE_ESC,
|
||||
SHELL_RECEIVE_ESC_SEQ,
|
||||
SHELL_RECEIVE_TILDE_EXP
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
* @internal @brief Internal shell state.
|
||||
*/
|
||||
enum shell_state {
|
||||
SHELL_STATE_UNINITIALIZED,
|
||||
SHELL_STATE_INITIALIZED,
|
||||
SHELL_STATE_ACTIVE,
|
||||
SHELL_STATE_PANIC_MODE_ACTIVE, /*!< Panic activated.*/
|
||||
SHELL_STATE_PANIC_MODE_INACTIVE /*!< Panic requested, not supported.*/
|
||||
};
|
||||
|
||||
/* @brief Shell transport event. */
|
||||
enum shell_transport_evt {
|
||||
SHELL_TRANSPORT_EVT_RX_RDY,
|
||||
SHELL_TRANSPORT_EVT_TX_RDY
|
||||
};
|
||||
|
||||
typedef void (*shell_transport_handler_t)(enum shell_transport_evt evt,
|
||||
void *context);
|
||||
|
||||
struct shell_transport;
|
||||
|
||||
/*
|
||||
* @brief Unified shell transport interface.
|
||||
*/
|
||||
struct shell_transport_api {
|
||||
/*
|
||||
* @brief Function for initializing the shell transport interface.
|
||||
*
|
||||
* @param[in] transport Pointer to the transfer instance.
|
||||
* @param[in] config Pointer to instance configuration.
|
||||
* @param[in] evt_handler Event handler.
|
||||
* @param[in] context Pointer to the context passed to event
|
||||
* handler.
|
||||
*
|
||||
* @return Standard error code.
|
||||
*/
|
||||
int (*init)(const struct shell_transport *transport,
|
||||
const void *config,
|
||||
shell_transport_handler_t evt_handler,
|
||||
void *context);
|
||||
|
||||
/*
|
||||
* @brief Function for uninitializing the shell transport interface.
|
||||
*
|
||||
* @param[in] transport Pointer to the transfer instance.
|
||||
*
|
||||
* @return Standard error code.
|
||||
*/
|
||||
int (*uninit)(const struct shell_transport *transport);
|
||||
|
||||
/*
|
||||
* @brief Function for reconfiguring the transport to work in blocking
|
||||
* mode.
|
||||
*
|
||||
* @param transport Pointer to the transfer instance.
|
||||
* @param blocking If true, the transport is enabled in blocking mode.
|
||||
*
|
||||
* @return NRF_SUCCESS on successful enabling, error otherwise (also if
|
||||
* not supported).
|
||||
*/
|
||||
int (*enable)(const struct shell_transport *transport, bool blocking);
|
||||
|
||||
/*
|
||||
* @brief Function for writing data to the transport interface.
|
||||
*
|
||||
* @param[in] transport Pointer to the transfer instance.
|
||||
* @param[in] data Pointer to the source buffer.
|
||||
* @param[in] length Source buffer length.
|
||||
* @param[in] cnt Pointer to the sent bytes counter.
|
||||
*
|
||||
* @return Standard error code.
|
||||
*/
|
||||
int (*write)(const struct shell_transport *transport,
|
||||
const void *data, size_t length, size_t *cnt);
|
||||
|
||||
/*
|
||||
* @brief Function for reading data from the transport interface.
|
||||
*
|
||||
* @param[in] p_transport Pointer to the transfer instance.
|
||||
* @param[in] p_data Pointer to the destination buffer.
|
||||
* @param[in] length Destination buffer length.
|
||||
* @param[in] cnt Pointer to the received bytes counter.
|
||||
*
|
||||
* @return Standard error code.
|
||||
*/
|
||||
int (*read)(const struct shell_transport *transport,
|
||||
void *data, size_t length, size_t *cnt);
|
||||
|
||||
};
|
||||
|
||||
struct shell_transport {
|
||||
const struct shell_transport_api *api;
|
||||
void *ctx;
|
||||
};
|
||||
|
||||
/*
|
||||
* @internal @brief Flags for internal shell usage.
|
||||
*/
|
||||
struct shell_flags {
|
||||
u32_t insert_mode :1; /*!< Controls insert mode for text introduction.*/
|
||||
u32_t show_help :1; /*!< Shows help if -h or --help option present.*/
|
||||
u32_t use_colors :1; /*!< Controls colored syntax.*/
|
||||
u32_t echo :1; /*!< Controls shell echo.*/
|
||||
u32_t processing :1; /*!< Shell is executing process function.*/
|
||||
u32_t tx_rdy :1;
|
||||
u32_t mode_delete :1; /*!< Operation mode of backspace key */
|
||||
};
|
||||
|
||||
_Static_assert(sizeof(struct shell_flags) == sizeof(u32_t), "Must fit in 32b.");
|
||||
|
||||
/*
|
||||
* @internal @brief Union for internal shell usage.
|
||||
*/
|
||||
union shell_internal {
|
||||
u32_t value;
|
||||
struct shell_flags flags;
|
||||
};
|
||||
|
||||
enum shell_signal {
|
||||
SHELL_SIGNAL_RXRDY,
|
||||
SHELL_SIGNAL_TXDONE,
|
||||
SHELL_SIGNAL_KILL,
|
||||
SHELL_SIGNALS
|
||||
};
|
||||
|
||||
/*
|
||||
* @brief Shell instance context.
|
||||
*/
|
||||
struct shell_ctx {
|
||||
enum shell_state state; /*!< Internal module state.*/
|
||||
enum shell_receive_state receive_state;/*!< Escape sequence indicator.*/
|
||||
|
||||
/*!< Currently executed command.*/
|
||||
struct shell_static_entry active_cmd;
|
||||
|
||||
/*!< VT100 color and cursor position, terminal width.*/
|
||||
struct shell_vt100_ctx vt100_ctx;
|
||||
|
||||
u16_t cmd_buff_len;/*!< Command length.*/
|
||||
u16_t cmd_buff_pos; /*!< Command buffer cursor position.*/
|
||||
|
||||
u16_t cmd_tmp_buff_len; /*!< Command length in tmp buffer.*/
|
||||
|
||||
/*!< Command input buffer.*/
|
||||
char cmd_buff[CONFIG_SHELL_CMD_BUFF_SIZE];
|
||||
|
||||
/*!< Command temporary buffer.*/
|
||||
char temp_buff[CONFIG_SHELL_CMD_BUFF_SIZE];
|
||||
|
||||
/*!< Printf buffer size.*/
|
||||
char printf_buff[CONFIG_SHELL_PRINTF_BUFF_SIZE];
|
||||
|
||||
volatile union shell_internal internal; /*!< Internal shell data.*/
|
||||
|
||||
struct k_poll_signal signals[SHELL_SIGNALS];
|
||||
struct k_poll_event events[SHELL_SIGNALS];
|
||||
};
|
||||
|
||||
extern const struct log_backend_api log_backend_shell_api;
|
||||
|
||||
/*
|
||||
* @brief Shell instance internals.
|
||||
*/
|
||||
struct shell {
|
||||
const char *const name; /*!< Terminal name. */
|
||||
|
||||
const struct shell_transport *iface; /*!< Transport interface.*/
|
||||
struct shell_ctx *ctx; /*!< Internal context.*/
|
||||
|
||||
const struct shell_fprintf *fprintf_ctx;
|
||||
|
||||
LOG_INSTANCE_PTR_DECLARE(log);
|
||||
|
||||
/*!< New line character, only allowed values: \\n and \\r.*/
|
||||
const char newline_char;
|
||||
|
||||
struct k_thread *thread;
|
||||
k_thread_stack_t *stack;
|
||||
};
|
||||
|
||||
/*
|
||||
* @brief Macro for defining a shell instance.
|
||||
*
|
||||
* @param[in] _name Instance name.
|
||||
* @param[in] shell_prefix Shell prefix string.
|
||||
* @param[in] transport_iface Pointer to the transport interface.
|
||||
* @param[in] newline_ch New line character - only allowed values are
|
||||
* '\\n' or '\\r'.
|
||||
* @param[in] log_queue_size Logger processing queue size.
|
||||
*/
|
||||
#define SHELL_DEFINE(_name, shell_prefix, transport_iface, \
|
||||
newline_ch, log_queue_size) \
|
||||
static const struct shell _name; \
|
||||
static struct shell_ctx UTIL_CAT(_name, _ctx); \
|
||||
static u8_t _name##_out_buffer[CONFIG_SHELL_PRINTF_BUFF_SIZE]; \
|
||||
SHELL_FPRINTF_DEFINE(_name## _fprintf, &_name, _name##_out_buffer, \
|
||||
CONFIG_SHELL_PRINTF_BUFF_SIZE, \
|
||||
true, shell_print_stream); \
|
||||
LOG_INSTANCE_REGISTER(shell, _name, CONFIG_SHELL_LOG_LEVEL); \
|
||||
static struct k_thread _name##_thread; \
|
||||
static K_THREAD_STACK_DEFINE(_name##_stack, CONFIG_SHELL_STACK_SIZE); \
|
||||
static const struct shell _name = { \
|
||||
.name = shell_prefix, \
|
||||
.iface = transport_iface, \
|
||||
.ctx = &UTIL_CAT(_name, _ctx), \
|
||||
.fprintf_ctx = &_name##_fprintf, \
|
||||
LOG_INSTANCE_PTR_INIT(log, shell, _name) \
|
||||
.newline_char = newline_ch, \
|
||||
.thread = &_name##_thread, \
|
||||
.stack = _name##_stack \
|
||||
}
|
||||
|
||||
/*
|
||||
* @brief Function for initializing a transport layer and internal shell state.
|
||||
*
|
||||
* @param[in] shell Pointer to shell instance.
|
||||
* @param[in] transport_config Transport configuration during initialization.
|
||||
* @param[in] use_colors Enables colored prints.
|
||||
* @param[in] log_backend If true, the console will be used as logger
|
||||
* backend.
|
||||
* @param[in] init_log_level Default severity level for the logger.
|
||||
*
|
||||
* @return Standard error code.
|
||||
*/
|
||||
int shell_init(const struct shell *shell, const void *transport_config,
|
||||
bool use_colors, bool log_backend, u32_t init_log_level);
|
||||
|
||||
/*
|
||||
* @brief Uninitializes the transport layer and the internal shell state.
|
||||
*
|
||||
* @param shell Pointer to shell instance.
|
||||
*
|
||||
* @return Standard error code.
|
||||
*/
|
||||
int shell_uninit(const struct shell *shell);
|
||||
|
||||
/*
|
||||
* @brief Function for starting shell processing.
|
||||
*
|
||||
* @param shell Pointer to the shell instance.
|
||||
*
|
||||
* @return Standard error code.
|
||||
*/
|
||||
int shell_start(const struct shell *shell);
|
||||
|
||||
/*
|
||||
* @brief Function for stopping shell processing.
|
||||
*
|
||||
* @param shell Pointer to shell instance.
|
||||
*
|
||||
* @return Standard error code.
|
||||
*/
|
||||
int shell_stop(const struct shell *shell);
|
||||
|
||||
/*
|
||||
* @brief Shell colors for nrf_shell_fprintf function.
|
||||
*/
|
||||
#define SHELL_NORMAL SHELL_VT100_COLOR_DEFAULT
|
||||
#define SHELL_INFO SHELL_VT100_COLOR_GREEN
|
||||
#define SHELL_OPTION SHELL_VT100_COLOR_CYAN
|
||||
#define SHELL_WARNING SHELL_VT100_COLOR_YELLOW
|
||||
#define SHELL_ERROR SHELL_VT100_COLOR_RED
|
||||
|
||||
/*
|
||||
* @brief Printf-like function which sends formatted data stream to the shell.
|
||||
* This function shall not be used outside of the shell command context.
|
||||
*
|
||||
* @param[in] shell Pointer to the shell instance.
|
||||
* @param[in] color Printf color.
|
||||
* @param[in] p_fmt Format string.
|
||||
* @param[in] ... List of parameters to print.
|
||||
*/
|
||||
void shell_fprintf(const struct shell *shell, enum shell_vt100_color color,
|
||||
const char *p_fmt, ...);
|
||||
|
||||
/*
|
||||
* @brief Process function, which should be executed when data is ready in the
|
||||
* transport interface. To be used if shell thread is disabled.
|
||||
*
|
||||
* @param[in] shell Pointer to the shell instance.
|
||||
*/
|
||||
void shell_process(const struct shell *shell);
|
||||
|
||||
/*
|
||||
* @brief Option descriptor.
|
||||
*/
|
||||
struct shell_getopt_option {
|
||||
const char *optname; /*!< Option long name.*/
|
||||
const char *optname_short; /*!< Option short name.*/
|
||||
const char *optname_help; /*!< Option help string.*/
|
||||
};
|
||||
|
||||
/*
|
||||
* @brief Option structure initializer.
|
||||
*
|
||||
* @param[in] _optname Option name long.
|
||||
* @param[in] _shortname Option name short.
|
||||
* @param[in] _help Option help string.
|
||||
*/
|
||||
#define SHELL_OPT(_optname, _shortname, _help) { \
|
||||
.optname = _optname, \
|
||||
.optname_short = _shortname, \
|
||||
.optname_help = _help, \
|
||||
}
|
||||
|
||||
/*
|
||||
* @brief Informs that a command has been called with -h or --help option.
|
||||
*
|
||||
* @param[in] shell Pointer to the shell instance.
|
||||
*
|
||||
* @return True if help has been requested.
|
||||
*/
|
||||
static inline bool shell_help_requested(const struct shell *shell)
|
||||
{
|
||||
return shell->ctx->internal.flags.show_help;
|
||||
}
|
||||
|
||||
/*
|
||||
* @brief Prints the current command help.
|
||||
*
|
||||
* Function will print a help string with: the currently entered command, its
|
||||
* options,and subcommands (if they exist).
|
||||
*
|
||||
* @param[in] shell Pointer to the shell instance.
|
||||
* @param[in] opt Pointer to the optional option array.
|
||||
* @param[in] opt_len Option array size.
|
||||
*/
|
||||
void shell_help_print(const struct shell *shell,
|
||||
const struct shell_getopt_option *opt, size_t opt_len);
|
||||
|
||||
/*
|
||||
* @brief Prints help if request and prints error message on wrong argument
|
||||
* count.
|
||||
*
|
||||
* Optionally, printing help on wrong argument count can be enabled.
|
||||
*
|
||||
* @param[in] shell Pointer to the shell instance.
|
||||
* @param[in] arg_cnt_ok Flag indicating valid number of arguments.
|
||||
* @param[in] opt Pointer to the optional option array.
|
||||
* @param[in] opt_len Option array size.
|
||||
*
|
||||
* @return True if check passed, false otherwise or help was requested.
|
||||
*/
|
||||
bool shell_cmd_precheck(const struct shell *shell,
|
||||
bool arg_cnt_nok,
|
||||
const struct shell_getopt_option *opt,
|
||||
size_t opt_len);
|
||||
|
||||
/*
|
||||
* @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
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* SHELL_H__ */
|
85
include/shell/shell_fprintf.h
Normal file
85
include/shell/shell_fprintf.h
Normal file
|
@ -0,0 +1,85 @@
|
|||
/*
|
||||
* Copyright (c) 2018 Nordic Semiconductor ASA
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#ifndef SHELL_FPRINTF_H__
|
||||
#define SHELL_FPRINTF_H__
|
||||
|
||||
#include <zephyr.h>
|
||||
#include <stdbool.h>
|
||||
#include <stddef.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
typedef void (*shell_fprintf_fwrite)(const void *user_ctx,
|
||||
const char *data,
|
||||
size_t length);
|
||||
|
||||
struct shell_fprintf_control_block {
|
||||
size_t buffer_cnt;
|
||||
bool autoflush;
|
||||
};
|
||||
/**
|
||||
* @brief fprintf context
|
||||
*/
|
||||
struct shell_fprintf {
|
||||
u8_t *buffer;
|
||||
size_t buffer_size;
|
||||
shell_fprintf_fwrite fwrite;
|
||||
const void *user_ctx;
|
||||
struct shell_fprintf_control_block *ctrl_blk;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @brief Macro for defining shell_fprintf instance.
|
||||
*
|
||||
* @param _name Instance name.
|
||||
* @param _user_ctx Pointer to user data.
|
||||
* @param _buf Pointer to output buffer
|
||||
* @param _size Size of output buffer.
|
||||
* @param _autoflush Indicator if buffer shall be automatically flush.
|
||||
* @param _fwrite Pointer to function sending data stream.
|
||||
*/
|
||||
#define SHELL_FPRINTF_DEFINE(_name, _user_ctx, _buf, _size, \
|
||||
_autoflush, _fwrite) \
|
||||
static struct shell_fprintf_control_block \
|
||||
_name##_shell_fprintf_ctx = { \
|
||||
.autoflush = _autoflush, \
|
||||
.buffer_cnt = 0 \
|
||||
}; \
|
||||
static const struct shell_fprintf _name = { \
|
||||
.buffer = _buf, \
|
||||
.buffer_size = _size, \
|
||||
.fwrite = _fwrite, \
|
||||
.user_ctx = _user_ctx, \
|
||||
.ctrl_blk = &_name##_shell_fprintf_ctx \
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief fprintf like function which send formated data stream to output.
|
||||
*
|
||||
* @param sh_fprintf fprintf instance.
|
||||
* @param fmt Format string.
|
||||
* @param args List of parameters to print.
|
||||
*/
|
||||
void shell_fprintf_fmt(const struct shell_fprintf *sh_fprintf,
|
||||
char const *fmt, va_list args);
|
||||
|
||||
/**
|
||||
* @brief function flushing data stored in io_buffer.
|
||||
*
|
||||
* @param sh_fprintf fprintf instance
|
||||
*/
|
||||
void shell_fprintf_buffer_flush(const struct shell_fprintf *sh_fprintf);
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* SHELL_FPRINTF_H__ */
|
54
include/shell/shell_types.h
Normal file
54
include/shell/shell_types.h
Normal file
|
@ -0,0 +1,54 @@
|
|||
/*
|
||||
* Copyright (c) 2018 Nordic Semiconductor ASA
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
#ifndef SHELL_TYPES_H__
|
||||
#define SHELL_TYPES_H__
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
enum shell_vt100_color {
|
||||
SHELL_VT100_COLOR_DEFAULT,
|
||||
SHELL_VT100_COLOR_BLACK,
|
||||
SHELL_VT100_COLOR_RED,
|
||||
SHELL_VT100_COLOR_GREEN,
|
||||
SHELL_VT100_COLOR_YELLOW,
|
||||
SHELL_VT100_COLOR_BLUE,
|
||||
SHELL_VT100_COLOR_MAGENTA,
|
||||
SHELL_VT100_COLOR_CYAN,
|
||||
SHELL_VT100_COLOR_WHITE,
|
||||
|
||||
VT100_COLOR_END
|
||||
};
|
||||
|
||||
struct shell_vt100_colors {
|
||||
enum shell_vt100_color col; /* Text color. */
|
||||
enum shell_vt100_color bgcol; /* Background color. */
|
||||
};
|
||||
|
||||
struct shell_multiline_cons {
|
||||
u16_t cur_x; /* horizontal cursor position in edited command line.*/
|
||||
u16_t cur_x_end; /* horizontal cursor position at the end of command.*/
|
||||
u16_t cur_y; /* vertical cursor position in edited command.*/
|
||||
u16_t cur_y_end; /* vertical cursor position at the end of command.*/
|
||||
u16_t terminal_hei; /* terminal screen height.*/
|
||||
u16_t terminal_wid; /* terminal screen width.*/
|
||||
u8_t name_len; /*!<console name length.*/
|
||||
};
|
||||
|
||||
struct shell_vt100_ctx {
|
||||
struct shell_multiline_cons cons;
|
||||
struct shell_vt100_colors col;
|
||||
u16_t printed_cmd; /* printed commands counter */
|
||||
};
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* SHELL_TYPES_H__ */
|
||||
|
38
include/shell/shell_uart.h
Normal file
38
include/shell/shell_uart.h
Normal file
|
@ -0,0 +1,38 @@
|
|||
/*
|
||||
* Copyright (c) 2018 Nordic Semiconductor ASA
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#ifndef SHELL_UART_H__
|
||||
#define SHELL_UART_H__
|
||||
|
||||
#include <shell/shell.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
extern const struct shell_transport_api shell_uart_transport_api;
|
||||
|
||||
struct shell_uart {
|
||||
struct device *dev;
|
||||
shell_transport_handler_t handler;
|
||||
struct k_timer timer;
|
||||
void *context;
|
||||
u8_t rx[1];
|
||||
size_t rx_cnt;
|
||||
};
|
||||
|
||||
#define SHELL_UART_DEFINE(_name) \
|
||||
static struct shell_uart _name##_shell_uart; \
|
||||
struct shell_transport _name = { \
|
||||
.api = &shell_uart_transport_api, \
|
||||
.ctx = (struct shell_uart *)&_name##_shell_uart \
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* SHELL_UART_H__ */
|
|
@ -654,7 +654,7 @@ class SizeCalculator:
|
|||
"kobject_data", "mmu_tables", "app_pad", "priv_stacks",
|
||||
"ccm_data", "usb_descriptor", "usb_data", "usb_bos_desc",
|
||||
'log_backends_sections', 'log_dynamic_sections',
|
||||
'log_const_sections',"app_smem"]
|
||||
'log_const_sections',"app_smem", 'shell_root_cmds_sections']
|
||||
# These get copied into RAM only on non-XIP
|
||||
ro_sections = ["text", "ctors", "init_array", "reset", "object_access",
|
||||
"rodata", "devconfig", "net_l2", "vector", "_bt_settings_area"]
|
||||
|
|
|
@ -4,6 +4,7 @@ add_subdirectory(logging)
|
|||
add_subdirectory_ifdef(CONFIG_BT bluetooth)
|
||||
add_subdirectory_ifdef(CONFIG_CONSOLE_SUBSYS console)
|
||||
add_subdirectory_ifdef(CONFIG_CONSOLE_SHELL shell)
|
||||
add_subdirectory_ifdef(CONFIG_SHELL shell)
|
||||
add_subdirectory_ifdef(CONFIG_CPLUSPLUS cpp)
|
||||
add_subdirectory_ifdef(CONFIG_DISK_ACCESS disk)
|
||||
add_subdirectory(fs)
|
||||
|
|
|
@ -2,9 +2,19 @@ zephyr_include_directories_ifdef(CONFIG_CONSOLE_SHELL
|
|||
${ZEPHYR_BASE}/include/drivers
|
||||
)
|
||||
|
||||
zephyr_sources(
|
||||
zephyr_sources_ifdef(
|
||||
CONFIG_CONSOLE_SHELL
|
||||
shell_service.c
|
||||
legacy_shell.c
|
||||
)
|
||||
|
||||
add_subdirectory(modules)
|
||||
|
||||
zephyr_sources_ifdef(
|
||||
CONFIG_SHELL
|
||||
shell.c
|
||||
shell_fprintf.c
|
||||
shell_utils.c
|
||||
shell_ops.c
|
||||
shell_uart.c
|
||||
)
|
|
@ -33,3 +33,89 @@ config CONSOLE_SHELL_MAX_CMD_QUEUED
|
|||
source "subsys/shell/modules/Kconfig"
|
||||
|
||||
endif
|
||||
|
||||
config SHELL
|
||||
bool "Enable shell"
|
||||
select LOG_RUNTIME_FILTERING
|
||||
select POLL
|
||||
|
||||
if SHELL
|
||||
|
||||
module = SHELL
|
||||
module-str = Shell
|
||||
source "subsys/logging/Kconfig.template.log_config"
|
||||
|
||||
config SHELL_STACK_SIZE
|
||||
int "Shell thread stack size"
|
||||
default 1024 if MULTITHREADING
|
||||
default 0 if !MULTITHREADING
|
||||
help
|
||||
Stack size for thread created for each instance.
|
||||
|
||||
config SHELL_THREAD_PRIO
|
||||
int "Shell thread priority"
|
||||
depends on MULTITHREADING
|
||||
default -2
|
||||
help
|
||||
Shell thread priority.
|
||||
|
||||
config SHELL_BACKSPACE_MODE_DELETE
|
||||
bool "Default escape code for backspace is DELETE (0x7F)"
|
||||
default y
|
||||
help
|
||||
Terminals have different escape code settings for backspace button.
|
||||
Some terminals send code: 0x08 (backspace) other 0x7F (delete). When
|
||||
this option is set shell will expect 0x7F for backspace key.
|
||||
|
||||
config SHELL_CMD_BUFF_SIZE
|
||||
int "Shell command buffer size"
|
||||
default 256
|
||||
help
|
||||
Maximum command size.
|
||||
|
||||
config SHELL_PRINTF_BUFF_SIZE
|
||||
int "Shell print buffer size"
|
||||
default 30
|
||||
help
|
||||
Maximum text buffer size for fprintf function.
|
||||
It is working like stdio buffering in Linux systems
|
||||
to limit number of peripheral access calls.
|
||||
|
||||
config SHELL_ARGC_MAX
|
||||
int "Maximum arguments in shell command"
|
||||
default 12
|
||||
help
|
||||
Maximum number of arguments that can build a command.
|
||||
If command is composed of more than defined, argument SHELL_ARGC_MAX
|
||||
and following are passed as one argument in the string.
|
||||
|
||||
config SHELL_ECHO_STATUS
|
||||
bool "Enable echo on shell"
|
||||
default y
|
||||
help
|
||||
If enabled shell prints back every input byte.
|
||||
|
||||
config SHELL_VT100_COLORS
|
||||
bool "Enable colors in shell"
|
||||
default y
|
||||
help
|
||||
If enabled VT100 colors are used in shell (e.g. print errors in red).
|
||||
|
||||
config SHELL_METAKEYS
|
||||
bool "Enable metakeys"
|
||||
default y
|
||||
help
|
||||
Enables shell metakeys: Home, End, ctrl+a, ctrl+c, ctrl+e, ctrl+l,
|
||||
ctrl+u, ctrl+w
|
||||
|
||||
config SHELL_HELP
|
||||
bool "Enable help message"
|
||||
default y
|
||||
help
|
||||
Enables formatting help message when requested with '-h' or '--help'.
|
||||
|
||||
config SHELL_HELP_ON_WRONG_ARGUMENT_COUNT
|
||||
bool "Enable printing help on wrong argument count"
|
||||
default y
|
||||
|
||||
endif #SHELL
|
||||
|
|
1451
subsys/shell/shell.c
Normal file
1451
subsys/shell/shell.c
Normal file
File diff suppressed because it is too large
Load diff
52
subsys/shell/shell_fprintf.c
Normal file
52
subsys/shell/shell_fprintf.c
Normal file
|
@ -0,0 +1,52 @@
|
|||
/*
|
||||
* Copyright (c) 2018 Nordic Semiconductor ASA
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#include <shell/shell_fprintf.h>
|
||||
|
||||
#ifdef CONFIG_NEWLIB_LIBC
|
||||
typedef int (*out_func_t)(int c, void *ctx);
|
||||
extern void _vprintk(out_func_t out, void *ctx, const char *fmt, va_list ap);
|
||||
#else
|
||||
extern int _prf(int (*func)(), void *dest, char *format, va_list vargs);
|
||||
#endif
|
||||
|
||||
static int out_func(int c, void *ctx)
|
||||
{
|
||||
const struct shell_fprintf *sh_fprintf;
|
||||
|
||||
sh_fprintf = (const struct shell_fprintf *)ctx;
|
||||
|
||||
sh_fprintf->buffer[sh_fprintf->ctrl_blk->buffer_cnt] = (u8_t)c;
|
||||
sh_fprintf->ctrl_blk->buffer_cnt++;
|
||||
|
||||
if (sh_fprintf->ctrl_blk->buffer_cnt == sh_fprintf->buffer_size) {
|
||||
shell_fprintf_buffer_flush(sh_fprintf);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void shell_fprintf_fmt(const struct shell_fprintf *sh_fprintf,
|
||||
const char *fmt, va_list args)
|
||||
{
|
||||
#ifndef CONFIG_NEWLIB_LIBC
|
||||
(void)_prf(out_func, (void *)sh_fprintf, (char *)fmt, args);
|
||||
#else
|
||||
_vprintk(out_func, (void *)sh_fprintf, fmt, args);
|
||||
#endif
|
||||
|
||||
if (sh_fprintf->ctrl_blk->autoflush) {
|
||||
shell_fprintf_buffer_flush(sh_fprintf);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void shell_fprintf_buffer_flush(const struct shell_fprintf *sh_fprintf)
|
||||
{
|
||||
sh_fprintf->fwrite(sh_fprintf->user_ctx, sh_fprintf->buffer,
|
||||
sh_fprintf->ctrl_blk->buffer_cnt);
|
||||
sh_fprintf->ctrl_blk->buffer_cnt = 0;
|
||||
}
|
264
subsys/shell/shell_ops.c
Normal file
264
subsys/shell/shell_ops.c
Normal file
|
@ -0,0 +1,264 @@
|
|||
/*
|
||||
* Copyright (c) 2018 Nordic Semiconductor ASA
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#include "shell_ops.h"
|
||||
|
||||
void shell_op_cursor_vert_move(const struct shell *shell, s32_t delta)
|
||||
{
|
||||
if (delta != 0) {
|
||||
shell_raw_fprintf(shell->fprintf_ctx, "\033[%d%c",
|
||||
delta > 0 ? delta : -delta,
|
||||
delta > 0 ? 'A' : 'B');
|
||||
}
|
||||
}
|
||||
|
||||
void shell_op_cursor_horiz_move(const struct shell *shell, s32_t delta)
|
||||
{
|
||||
if (delta != 0) {
|
||||
shell_raw_fprintf(shell->fprintf_ctx, "\033[%d%c",
|
||||
delta > 0 ? delta : -delta,
|
||||
delta > 0 ? 'C' : 'D');
|
||||
}
|
||||
}
|
||||
|
||||
/* Function returns true if command length is equal to multiplicity of terminal
|
||||
* width.
|
||||
*/
|
||||
static inline bool full_line_cmd(const struct shell *shell)
|
||||
{
|
||||
return ((shell->ctx->cmd_buff_len + shell_strlen(shell->name))
|
||||
% shell->ctx->vt100_ctx.cons.terminal_wid == 0);
|
||||
}
|
||||
|
||||
/* Function returns true if cursor is at beginning of an empty line. */
|
||||
bool shell_cursor_in_empty_line(const struct shell *shell)
|
||||
{
|
||||
return ((shell->ctx->cmd_buff_pos + shell_strlen(shell->name))
|
||||
% shell->ctx->vt100_ctx.cons.terminal_wid == 0);
|
||||
}
|
||||
|
||||
void shell_op_cond_next_line(const struct shell *shell)
|
||||
{
|
||||
if (shell_cursor_in_empty_line(shell) || full_line_cmd(shell)) {
|
||||
cursor_next_line_move(shell);
|
||||
}
|
||||
}
|
||||
|
||||
void shell_op_cursor_position_synchronize(const struct shell *shell)
|
||||
{
|
||||
struct shell_multiline_cons *cons = &shell->ctx->vt100_ctx.cons;
|
||||
bool last_line;
|
||||
|
||||
shell_multiline_data_calc(cons, shell->ctx->cmd_buff_pos,
|
||||
shell->ctx->cmd_buff_len);
|
||||
last_line = (cons->cur_y == cons->cur_y_end);
|
||||
|
||||
/* In case cursor reaches the bottom line of a terminal, it will
|
||||
* be moved to the next line.
|
||||
*/
|
||||
if (full_line_cmd(shell)) {
|
||||
cursor_next_line_move(shell);
|
||||
}
|
||||
|
||||
if (last_line) {
|
||||
shell_op_cursor_horiz_move(shell, cons->cur_x -
|
||||
cons->cur_x_end);
|
||||
} else {
|
||||
shell_op_cursor_vert_move(shell, cons->cur_y_end - cons->cur_y);
|
||||
shell_op_cursor_horiz_move(shell, cons->cur_x -
|
||||
cons->cur_x_end);
|
||||
}
|
||||
}
|
||||
|
||||
void shell_op_cursor_move(const struct shell *shell, s16_t val)
|
||||
{
|
||||
struct shell_multiline_cons *cons = &shell->ctx->vt100_ctx.cons;
|
||||
u16_t new_pos = shell->ctx->cmd_buff_pos + val;
|
||||
s32_t row_span;
|
||||
s32_t col_span;
|
||||
|
||||
shell_multiline_data_calc(cons, shell->ctx->cmd_buff_pos,
|
||||
shell->ctx->cmd_buff_len);
|
||||
|
||||
/* Calculate the new cursor. */
|
||||
row_span = row_span_with_buffer_offsets_get(&shell->ctx->vt100_ctx.cons,
|
||||
shell->ctx->cmd_buff_pos,
|
||||
new_pos);
|
||||
col_span = column_span_with_buffer_offsets_get(
|
||||
&shell->ctx->vt100_ctx.cons,
|
||||
shell->ctx->cmd_buff_pos,
|
||||
new_pos);
|
||||
|
||||
shell_op_cursor_vert_move(shell, -row_span);
|
||||
shell_op_cursor_horiz_move(shell, col_span);
|
||||
shell->ctx->cmd_buff_pos = new_pos;
|
||||
}
|
||||
|
||||
void shell_op_word_remove(const struct shell *shell)
|
||||
{
|
||||
char *str = &shell->ctx->cmd_buff[shell->ctx->cmd_buff_pos - 1];
|
||||
char *str_start = &shell->ctx->cmd_buff[0];
|
||||
u16_t chars_to_delete;
|
||||
|
||||
/* Line must not be empty and cursor must not be at 0 to continue. */
|
||||
if ((shell->ctx->cmd_buff_len == 0) ||
|
||||
(shell->ctx->cmd_buff_pos == 0)) {
|
||||
return;
|
||||
}
|
||||
|
||||
/* Start at the current position. */
|
||||
chars_to_delete = 0;
|
||||
|
||||
/* Look back for all spaces then for non-spaces. */
|
||||
while ((str >= str_start) && (*str == ' ')) {
|
||||
++chars_to_delete;
|
||||
--str;
|
||||
}
|
||||
|
||||
while ((str >= str_start) && (*str != ' ')) {
|
||||
++chars_to_delete;
|
||||
--str;
|
||||
}
|
||||
|
||||
/* Manage the buffer. */
|
||||
memmove(str + 1, str + 1 + chars_to_delete,
|
||||
shell->ctx->cmd_buff_len - chars_to_delete);
|
||||
shell->ctx->cmd_buff_len -= chars_to_delete;
|
||||
shell->ctx->cmd_buff[shell->ctx->cmd_buff_len] = '\0';
|
||||
|
||||
/* Update display. */
|
||||
shell_op_cursor_move(shell, -chars_to_delete);
|
||||
cursor_save(shell);
|
||||
shell_fprintf(shell, SHELL_NORMAL, "%s", str + 1);
|
||||
clear_eos(shell);
|
||||
cursor_restore(shell);
|
||||
}
|
||||
|
||||
void shell_op_cursor_home_move(const struct shell *shell)
|
||||
{
|
||||
shell_op_cursor_move(shell, -shell->ctx->cmd_buff_pos);
|
||||
}
|
||||
|
||||
void shell_op_cursor_end_move(const struct shell *shell)
|
||||
{
|
||||
shell_op_cursor_move(shell, shell->ctx->cmd_buff_len -
|
||||
shell->ctx->cmd_buff_pos);
|
||||
}
|
||||
|
||||
|
||||
void shell_op_left_arrow(const struct shell *shell)
|
||||
{
|
||||
if (shell->ctx->cmd_buff_pos > 0) {
|
||||
shell_op_cursor_move(shell, -1);
|
||||
}
|
||||
}
|
||||
|
||||
void shell_op_right_arrow(const struct shell *shell)
|
||||
{
|
||||
if (shell->ctx->cmd_buff_pos < shell->ctx->cmd_buff_len) {
|
||||
shell_op_cursor_move(shell, 1);
|
||||
}
|
||||
}
|
||||
|
||||
static void reprint_from_cursor(const struct shell *shell, u16_t diff,
|
||||
bool data_removed)
|
||||
{
|
||||
/* Clear eos is needed only when newly printed command is shorter than
|
||||
* previously printed command. This can happen when delete or backspace
|
||||
* was called.
|
||||
*
|
||||
* Such condition is useful for Bluetooth devices to save number of
|
||||
* bytes transmitted between terminal and device.
|
||||
*/
|
||||
if (data_removed) {
|
||||
clear_eos(shell);
|
||||
}
|
||||
|
||||
shell_fprintf(shell, SHELL_NORMAL, "%s",
|
||||
&shell->ctx->cmd_buff[shell->ctx->cmd_buff_pos]);
|
||||
shell->ctx->cmd_buff_pos = shell->ctx->cmd_buff_len;
|
||||
|
||||
if (full_line_cmd(shell)) {
|
||||
if (((data_removed) && (diff > 0)) || (!data_removed)) {
|
||||
cursor_next_line_move(shell);
|
||||
}
|
||||
}
|
||||
|
||||
shell_op_cursor_move(shell, -diff);
|
||||
}
|
||||
|
||||
static void data_insert(const struct shell *shell, const char *data, u16_t len)
|
||||
{
|
||||
u16_t after = shell->ctx->cmd_buff_len - shell->ctx->cmd_buff_pos;
|
||||
char *curr_pos = &shell->ctx->cmd_buff[shell->ctx->cmd_buff_pos];
|
||||
|
||||
if ((shell->ctx->cmd_buff_len + len) >= CONFIG_SHELL_CMD_BUFF_SIZE) {
|
||||
return;
|
||||
}
|
||||
|
||||
memmove(curr_pos + len, curr_pos, after);
|
||||
memcpy(curr_pos, data, len);
|
||||
shell->ctx->cmd_buff_len += len;
|
||||
shell->ctx->cmd_buff[shell->ctx->cmd_buff_len] = '\0';
|
||||
|
||||
if (!flag_echo_is_set(shell)) {
|
||||
shell->ctx->cmd_buff_pos += len;
|
||||
return;
|
||||
}
|
||||
|
||||
reprint_from_cursor(shell, after, false);
|
||||
}
|
||||
|
||||
void char_replace(const struct shell *shell, char data)
|
||||
{
|
||||
shell->ctx->cmd_buff[shell->ctx->cmd_buff_pos++] = data;
|
||||
shell_raw_fprintf(shell->fprintf_ctx, "%c", data);
|
||||
if (shell_cursor_in_empty_line(shell)) {
|
||||
cursor_next_line_move(shell);
|
||||
}
|
||||
}
|
||||
|
||||
void shell_op_char_insert(const struct shell *shell, char data)
|
||||
{
|
||||
if (shell->ctx->internal.flags.insert_mode &&
|
||||
(shell->ctx->cmd_buff_len != shell->ctx->cmd_buff_pos)) {
|
||||
char_replace(shell, data);
|
||||
} else {
|
||||
data_insert(shell, &data, 1);
|
||||
}
|
||||
}
|
||||
|
||||
void shell_op_char_backspace(const struct shell *shell)
|
||||
{
|
||||
if ((shell->ctx->cmd_buff_len == 0) ||
|
||||
(shell->ctx->cmd_buff_pos == 0)) {
|
||||
return;
|
||||
}
|
||||
|
||||
shell_op_cursor_move(shell, -1);
|
||||
shell_op_char_delete(shell);
|
||||
}
|
||||
|
||||
void shell_op_char_delete(const struct shell *shell)
|
||||
{
|
||||
u16_t diff = shell->ctx->cmd_buff_len - shell->ctx->cmd_buff_pos;
|
||||
char *str = &shell->ctx->cmd_buff[shell->ctx->cmd_buff_pos];
|
||||
|
||||
if (diff == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
memmove(str, str + 1, diff);
|
||||
--shell->ctx->cmd_buff_len;
|
||||
reprint_from_cursor(shell, --diff, true);
|
||||
}
|
||||
|
||||
void shell_op_completion_insert(const struct shell *shell,
|
||||
const char *compl,
|
||||
u16_t compl_len)
|
||||
{
|
||||
data_insert(shell, compl, compl_len);
|
||||
}
|
128
subsys/shell/shell_ops.h
Normal file
128
subsys/shell/shell_ops.h
Normal file
|
@ -0,0 +1,128 @@
|
|||
/*
|
||||
* Copyright (c) 2018 Nordic Semiconductor ASA
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
#ifndef SHELL_OPS_H__
|
||||
#define SHELL_OPS_H__
|
||||
|
||||
#include <zephyr.h>
|
||||
#include <shell/shell.h>
|
||||
#include "shell_vt100.h"
|
||||
#include "shell_utils.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#define SHELL_DEFAULT_TERMINAL_WIDTH (80u) /* Default PuTTY width. */
|
||||
#define SHELL_DEFAULT_TERMINAL_HEIGHT (24u) /* Default PuTTY height. */
|
||||
|
||||
static inline void shell_raw_fprintf(const struct shell_fprintf *const ctx,
|
||||
const char *fmt, ...)
|
||||
{
|
||||
va_list args;
|
||||
|
||||
va_start(args, fmt);
|
||||
shell_fprintf_fmt(ctx, fmt, args);
|
||||
va_end(args);
|
||||
}
|
||||
|
||||
/* Macro to send VT100 commands. */
|
||||
#define SHELL_VT100_CMD(_shell_, _cmd_) \
|
||||
do { \
|
||||
static const char cmd[] = _cmd_; \
|
||||
shell_raw_fprintf(_shell_->fprintf_ctx, "%s", cmd); \
|
||||
} while (0)
|
||||
|
||||
/* Function sends VT100 command to clear the screen from cursor position to
|
||||
* end of the screen.
|
||||
*/
|
||||
static inline void clear_eos(const struct shell *shell)
|
||||
{
|
||||
SHELL_VT100_CMD(shell, SHELL_VT100_CLEAREOS);
|
||||
}
|
||||
|
||||
/* Function sends VT100 command to save cursor position. */
|
||||
static inline void cursor_save(const struct shell *shell)
|
||||
{
|
||||
SHELL_VT100_CMD(shell, SHELL_VT100_SAVECURSOR);
|
||||
}
|
||||
|
||||
/* Function sends VT100 command to restore saved cursor position. */
|
||||
static inline void cursor_restore(const struct shell *shell)
|
||||
{
|
||||
SHELL_VT100_CMD(shell, SHELL_VT100_RESTORECURSOR);
|
||||
}
|
||||
|
||||
/* Function forcing new line - cannot be replaced with function
|
||||
* cursor_down_move.
|
||||
*/
|
||||
static inline void cursor_next_line_move(const struct shell *shell)
|
||||
{
|
||||
shell_raw_fprintf(shell->fprintf_ctx, "\r\n");
|
||||
}
|
||||
|
||||
/* Function sends 1 character to the shell instance. */
|
||||
static inline void shell_putc(const struct shell *shell, char ch)
|
||||
{
|
||||
shell_raw_fprintf(shell->fprintf_ctx, "%c", ch);
|
||||
}
|
||||
|
||||
static inline bool flag_echo_is_set(const struct shell *shell)
|
||||
{
|
||||
return shell->ctx->internal.flags.echo == 1 ? true : false;
|
||||
}
|
||||
|
||||
void shell_op_cursor_vert_move(const struct shell *shell, s32_t delta);
|
||||
void shell_op_cursor_horiz_move(const struct shell *shell, s32_t delta);
|
||||
|
||||
void shell_op_cond_next_line(const struct shell *shell);
|
||||
|
||||
/* Function will move cursor back to position == cmd_buff_pos. Example usage is
|
||||
* when cursor needs to be moved back after printing some text. This function
|
||||
* cannot be used to move cursor to new location by manual change of
|
||||
* cmd_buff_pos.
|
||||
*/
|
||||
void shell_op_cursor_position_synchronize(const struct shell *shell);
|
||||
|
||||
void shell_op_cursor_move(const struct shell *shell, s16_t val);
|
||||
|
||||
void shell_op_left_arrow(const struct shell *shell);
|
||||
|
||||
void shell_op_right_arrow(const struct shell *shell);
|
||||
|
||||
/*
|
||||
* Removes the "word" to the left of the cursor:
|
||||
* - if there are spaces at the cursor position, remove all spaces to the left
|
||||
* - remove the non-spaces (word) until a space is found or a beginning of
|
||||
* buffer
|
||||
*/
|
||||
void shell_op_word_remove(const struct shell *shell);
|
||||
|
||||
/* Function moves cursor to begin of command position, just after console
|
||||
* name.
|
||||
*/
|
||||
void shell_op_cursor_home_move(const struct shell *shell);
|
||||
|
||||
/* Function moves cursor to end of command. */
|
||||
void shell_op_cursor_end_move(const struct shell *shell);
|
||||
|
||||
void char_replace(const struct shell *shell, char data);
|
||||
|
||||
void shell_op_char_insert(const struct shell *shell, char data);
|
||||
|
||||
void shell_op_char_backspace(const struct shell *shell);
|
||||
|
||||
void shell_op_char_delete(const struct shell *shell);
|
||||
|
||||
void shell_op_completion_insert(const struct shell *shell,
|
||||
const char *compl,
|
||||
u16_t compl_len);
|
||||
|
||||
bool shell_cursor_in_empty_line(const struct shell *shell);
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* SHELL_OPS_H__ */
|
89
subsys/shell/shell_uart.c
Normal file
89
subsys/shell/shell_uart.c
Normal file
|
@ -0,0 +1,89 @@
|
|||
/*
|
||||
* Copyright (c) 2018 Nordic Semiconductor ASA
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#include <shell/shell_uart.h>
|
||||
#include <uart.h>
|
||||
|
||||
static void timer_handler(struct k_timer *timer)
|
||||
{
|
||||
struct shell_uart *sh_uart =
|
||||
CONTAINER_OF(timer, struct shell_uart, timer);
|
||||
|
||||
if (uart_poll_in(sh_uart->dev, sh_uart->rx) == 0) {
|
||||
sh_uart->rx_cnt = 1;
|
||||
sh_uart->handler(SHELL_TRANSPORT_EVT_RX_RDY, sh_uart->context);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static int init(const struct shell_transport *transport,
|
||||
const void *config,
|
||||
shell_transport_handler_t evt_handler,
|
||||
void *context)
|
||||
{
|
||||
struct shell_uart *sh_uart = (struct shell_uart *)transport->ctx;
|
||||
|
||||
sh_uart->dev = device_get_binding(CONFIG_UART_CONSOLE_ON_DEV_NAME);
|
||||
sh_uart->handler = evt_handler;
|
||||
sh_uart->context = context;
|
||||
|
||||
k_timer_init(&sh_uart->timer, timer_handler, NULL);
|
||||
|
||||
k_timer_start(&sh_uart->timer, 20, 20);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int uninit(const struct shell_transport *transport)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int enable(const struct shell_transport *transport, bool blocking)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int write(const struct shell_transport *transport,
|
||||
const void *data, size_t length, size_t *cnt)
|
||||
{
|
||||
struct shell_uart *sh_uart = (struct shell_uart *)transport->ctx;
|
||||
const u8_t *data8 = (const u8_t *)data;
|
||||
|
||||
for (size_t i = 0; i < length; i++) {
|
||||
uart_poll_out(sh_uart->dev, data8[i]);
|
||||
}
|
||||
|
||||
*cnt = length;
|
||||
|
||||
sh_uart->handler(SHELL_TRANSPORT_EVT_TX_RDY, sh_uart->context);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int read(const struct shell_transport *transport,
|
||||
void *data, size_t length, size_t *cnt)
|
||||
{
|
||||
struct shell_uart *sh_uart = (struct shell_uart *)transport->ctx;
|
||||
|
||||
if (sh_uart->rx_cnt) {
|
||||
memcpy(data, sh_uart->rx, 1);
|
||||
sh_uart->rx_cnt = 0;
|
||||
*cnt = 1;
|
||||
} else {
|
||||
*cnt = 0;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
const struct shell_transport_api shell_uart_transport_api = {
|
||||
.init = init,
|
||||
.uninit = uninit,
|
||||
.enable = enable,
|
||||
.write = write,
|
||||
.read = read
|
||||
};
|
323
subsys/shell/shell_utils.c
Normal file
323
subsys/shell/shell_utils.c
Normal file
|
@ -0,0 +1,323 @@
|
|||
/*
|
||||
* Copyright (c) 2018 Nordic Semiconductor ASA
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
#include "shell_utils.h"
|
||||
#include <ctype.h>
|
||||
|
||||
/* Calculates relative line number of given position in buffer */
|
||||
static u32_t line_num_with_buffer_offset_get(struct shell_multiline_cons *cons,
|
||||
u16_t buffer_pos)
|
||||
{
|
||||
return ((buffer_pos + cons->name_len) / cons->terminal_wid);
|
||||
}
|
||||
|
||||
/* Calculates column number of given position in buffer */
|
||||
static u32_t col_num_with_buffer_offset_get(struct shell_multiline_cons *cons,
|
||||
u16_t buffer_pos)
|
||||
{
|
||||
/* columns are counted from 1 */
|
||||
return (1 + ((buffer_pos + cons->name_len) % cons->terminal_wid));
|
||||
}
|
||||
|
||||
s32_t column_span_with_buffer_offsets_get(struct shell_multiline_cons *cons,
|
||||
u16_t offset1,
|
||||
u16_t offset2)
|
||||
{
|
||||
return col_num_with_buffer_offset_get(cons, offset2)
|
||||
- col_num_with_buffer_offset_get(cons, offset1);
|
||||
}
|
||||
|
||||
s32_t row_span_with_buffer_offsets_get(struct shell_multiline_cons *cons,
|
||||
u16_t offset1,
|
||||
u16_t offset2)
|
||||
{
|
||||
return line_num_with_buffer_offset_get(cons, offset2)
|
||||
- line_num_with_buffer_offset_get(cons, offset1);
|
||||
}
|
||||
|
||||
void shell_multiline_data_calc(struct shell_multiline_cons *cons,
|
||||
u16_t buff_pos, u16_t buff_len)
|
||||
{
|
||||
/* Current cursor position in command.
|
||||
* +1 -> because home position is (1, 1)
|
||||
*/
|
||||
cons->cur_x = (buff_pos + cons->name_len) % cons->terminal_wid + 1;
|
||||
cons->cur_y = (buff_pos + cons->name_len) / cons->terminal_wid + 1;
|
||||
|
||||
/* Extreme position when cursor is at the end of command. */
|
||||
cons->cur_y_end = (buff_len + cons->name_len) / cons->terminal_wid + 1;
|
||||
cons->cur_x_end = (buff_len + cons->name_len) % cons->terminal_wid + 1;
|
||||
}
|
||||
|
||||
static void make_argv(char **ppcmd, u8_t c, u8_t quote)
|
||||
{
|
||||
char *cmd = *ppcmd;
|
||||
|
||||
while (1) {
|
||||
c = *cmd;
|
||||
|
||||
if (c == '\0') {
|
||||
break;
|
||||
}
|
||||
|
||||
if (!quote) {
|
||||
switch (c) {
|
||||
case '\\':
|
||||
memmove(cmd, cmd + 1,
|
||||
shell_strlen(cmd));
|
||||
cmd += 1;
|
||||
continue;
|
||||
|
||||
case '\'':
|
||||
case '\"':
|
||||
memmove(cmd, cmd + 1,
|
||||
shell_strlen(cmd));
|
||||
quote = c;
|
||||
continue;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (quote == c) {
|
||||
memmove(cmd, cmd + 1, shell_strlen(cmd));
|
||||
quote = 0;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (quote && c == '\\') {
|
||||
char t = *(cmd + 1);
|
||||
|
||||
if (t == quote) {
|
||||
memmove(cmd, cmd + 1,
|
||||
shell_strlen(cmd));
|
||||
cmd += 1;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (t == '0') {
|
||||
u8_t i;
|
||||
u8_t v = 0;
|
||||
|
||||
for (i = 2; i < (2 + 3); i++) {
|
||||
t = *(cmd + i);
|
||||
|
||||
if (t >= '0' && t <= '7') {
|
||||
v = (v << 3) | (t - '0');
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (i > 2) {
|
||||
memmove(cmd, cmd + (i - 1),
|
||||
shell_strlen(cmd) - (i - 2));
|
||||
*cmd++ = v;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
if (t == 'x') {
|
||||
u8_t i;
|
||||
u8_t v = 0;
|
||||
|
||||
for (i = 2; i < (2 + 2); i++) {
|
||||
t = *(cmd + i);
|
||||
|
||||
if (t >= '0' && t <= '9') {
|
||||
v = (v << 4) | (t - '0');
|
||||
} else if ((t >= 'a') &&
|
||||
(t <= 'f')) {
|
||||
v = (v << 4) | (t - 'a' + 10);
|
||||
} else if ((t >= 'A') && (t <= 'F')) {
|
||||
v = (v << 4) | (t - 'A' + 10);
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (i > 2) {
|
||||
memmove(cmd, cmd + (i - 1),
|
||||
shell_strlen(cmd) - (i - 2));
|
||||
*cmd++ = v;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!quote && isspace((int) c)) {
|
||||
break;
|
||||
}
|
||||
|
||||
cmd += 1;
|
||||
}
|
||||
*ppcmd = cmd;
|
||||
}
|
||||
|
||||
|
||||
char shell_make_argv(size_t *argc, char **argv, char *cmd, u8_t max_argc)
|
||||
{
|
||||
char quote = 0;
|
||||
char c;
|
||||
|
||||
*argc = 0;
|
||||
do {
|
||||
c = *cmd;
|
||||
if (c == '\0') {
|
||||
break;
|
||||
}
|
||||
|
||||
if (isspace((int) c)) {
|
||||
*cmd++ = '\0';
|
||||
continue;
|
||||
}
|
||||
|
||||
argv[(*argc)++] = cmd;
|
||||
quote = 0;
|
||||
|
||||
make_argv(&cmd, c, quote);
|
||||
} while (*argc < max_argc);
|
||||
|
||||
argv[*argc] = 0;
|
||||
|
||||
return quote;
|
||||
}
|
||||
|
||||
void shell_pattern_remove(char *buff, u16_t *buff_len, const char *pattern)
|
||||
{
|
||||
char *pattern_addr = strstr(buff, pattern);
|
||||
u16_t pattern_len = shell_strlen(pattern);
|
||||
size_t shift;
|
||||
|
||||
if (!pattern_addr) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (pattern_addr > buff) {
|
||||
if (*(pattern_addr - 1) == ' ') {
|
||||
pattern_len++; /* space needs to be removed as well */
|
||||
pattern_addr--; /* set pointer to space */
|
||||
}
|
||||
}
|
||||
|
||||
shift = shell_strlen(pattern_addr) - pattern_len + 1; /* +1 for EOS */
|
||||
*buff_len -= pattern_len;
|
||||
|
||||
memmove(pattern_addr, pattern_addr + pattern_len, shift);
|
||||
}
|
||||
|
||||
int shell_command_add(char *buff, u16_t *buff_len,
|
||||
const char *new_cmd, const char *pattern)
|
||||
{
|
||||
u16_t cmd_len = shell_strlen(new_cmd);
|
||||
char *cmd_source_addr;
|
||||
u16_t shift;
|
||||
|
||||
/* +1 for space */
|
||||
if ((*buff_len + cmd_len + 1) > CONFIG_SHELL_CMD_BUFF_SIZE) {
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
cmd_source_addr = strstr(buff, pattern);
|
||||
|
||||
if (!cmd_source_addr) {
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
shift = shell_strlen(cmd_source_addr);
|
||||
|
||||
/* make place for new command: + 1 for space + 1 for EOS */
|
||||
memmove(cmd_source_addr + cmd_len + 1, cmd_source_addr, shift + 1);
|
||||
memcpy(cmd_source_addr, new_cmd, cmd_len);
|
||||
cmd_source_addr[cmd_len] = ' ';
|
||||
|
||||
*buff_len += cmd_len + 1; /* + 1 for space */
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void shell_spaces_trim(char *str)
|
||||
{
|
||||
u16_t len = shell_strlen(str);
|
||||
u16_t shift = 0;
|
||||
|
||||
if (!str) {
|
||||
return;
|
||||
}
|
||||
|
||||
for (u16_t i = 0; i < len - 1; i++) {
|
||||
if (isspace((int)str[i])) {
|
||||
for (u16_t j = i + 1; j < len; j++) {
|
||||
if (isspace((int)str[j])) {
|
||||
shift++;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (shift > 0) {
|
||||
/* +1 for EOS */
|
||||
memmove(&str[i + 1],
|
||||
&str[j],
|
||||
len - shift + 1);
|
||||
len -= shift;
|
||||
shift = 0;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void shell_buffer_trim(char *buff, u16_t *buff_len)
|
||||
{
|
||||
u16_t i = 0;
|
||||
|
||||
/* no command in the buffer */
|
||||
if (buff[0] == '\0') {
|
||||
return;
|
||||
}
|
||||
|
||||
while (isspace((int) buff[*buff_len - 1])) {
|
||||
*buff_len -= 1;
|
||||
if (*buff_len == 0) {
|
||||
buff[0] = '\0';
|
||||
return;
|
||||
}
|
||||
}
|
||||
buff[*buff_len] = '\0';
|
||||
|
||||
/* Counting whitespace characters starting from beginning of the
|
||||
* command.
|
||||
*/
|
||||
while (isspace((int) buff[i++])) {
|
||||
if (i == 0) {
|
||||
buff[0] = '\0';
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
/* Removing counted whitespace characters. */
|
||||
if (--i > 0) {
|
||||
memmove(buff, buff + i, (*buff_len + 1) - i); /* +1 for '\0' */
|
||||
*buff_len = *buff_len - i;
|
||||
}
|
||||
}
|
||||
|
||||
u16_t shell_str_similarity_check(const char *str_a, const char *str_b)
|
||||
{
|
||||
u16_t cnt = 0;
|
||||
|
||||
while (str_a[cnt] != '\0') {
|
||||
if (str_a[cnt] != str_b[cnt]) {
|
||||
return cnt;
|
||||
}
|
||||
|
||||
if (++cnt == 0) {
|
||||
return --cnt; /* too long strings */
|
||||
}
|
||||
}
|
||||
|
||||
return cnt;
|
||||
}
|
64
subsys/shell/shell_utils.h
Normal file
64
subsys/shell/shell_utils.h
Normal file
|
@ -0,0 +1,64 @@
|
|||
/*
|
||||
* Copyright (c) 2018 Nordic Semiconductor ASA
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
#ifndef SHELL_UTILS_H__
|
||||
#define SHELL_UTILS_H__
|
||||
|
||||
#include <zephyr.h>
|
||||
#include <shell/shell.h>
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#define SHELL_MSG_SPECIFY_SUBCOMMAND "Please specify a subcommand.\r\n"
|
||||
|
||||
#define SHELL_DEFAULT_TERMINAL_WIDTH (80u) /* Default PuTTY width. */
|
||||
#define SHELL_DEFAULT_TERMINAL_HEIGHT (24u) /* Default PuTTY height. */
|
||||
|
||||
|
||||
|
||||
s32_t row_span_with_buffer_offsets_get(struct shell_multiline_cons *cons,
|
||||
u16_t offset1,
|
||||
u16_t offset2);
|
||||
|
||||
s32_t column_span_with_buffer_offsets_get(struct shell_multiline_cons *cons,
|
||||
u16_t offset1,
|
||||
u16_t offset2);
|
||||
|
||||
void shell_multiline_data_calc(struct shell_multiline_cons *cons,
|
||||
u16_t buff_pos, u16_t buff_len);
|
||||
|
||||
static inline size_t shell_strlen(const char *str)
|
||||
{
|
||||
return str == NULL ? 0 : strlen(str);
|
||||
}
|
||||
|
||||
char shell_make_argv(size_t *argc, char **argv, char *cmd, uint8_t max_argc);
|
||||
|
||||
/** @brief Removes pattern and following space
|
||||
*
|
||||
*/
|
||||
void shell_pattern_remove(char *buff, u16_t *buff_len, const char *pattern);
|
||||
|
||||
int shell_command_add(char *buff, u16_t *buff_len,
|
||||
const char *new_cmd, const char *pattern);
|
||||
|
||||
void shell_spaces_trim(char *str);
|
||||
|
||||
/** @brief Remove white chars from beginning and end of command buffer.
|
||||
*
|
||||
*/
|
||||
void shell_buffer_trim(char *buff, u16_t *buff_len);
|
||||
|
||||
/* Function checks how many identical characters have two strings starting
|
||||
* from the first character.
|
||||
*/
|
||||
u16_t shell_str_similarity_check(const char *str_a, const char *str_b);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* SHELL_UTILS_H__ */
|
589
subsys/shell/shell_vt100.h
Normal file
589
subsys/shell/shell_vt100.h
Normal file
|
@ -0,0 +1,589 @@
|
|||
/*
|
||||
* Copyright (c) 2018 Nordic Semiconductor ASA
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#ifndef SHELL_VT100_H__
|
||||
#define SHELL_VT100_H__
|
||||
|
||||
#define SHELL_VT100_ASCII_ESC (0x1b)
|
||||
#define SHELL_VT100_ASCII_DEL (0x7F)
|
||||
#define SHELL_VT100_ASCII_BSPACE (0x08)
|
||||
#define SHELL_VT100_ASCII_CTRL_A (0x01)
|
||||
#define SHELL_VT100_ASCII_CTRL_C (0x03)
|
||||
#define SHELL_VT100_ASCII_CTRL_E (0x05)
|
||||
#define SHELL_VT100_ASCII_CTRL_L (0x0C)
|
||||
#define SHELL_VT100_ASCII_CTRL_U (0x15)
|
||||
#define SHELL_VT100_ASCII_CTRL_W (0x17)
|
||||
|
||||
#define SHELL_VT100_SETNL \
|
||||
{ \
|
||||
SHELL_VT100_ASCII_ESC, '[', '2', '0', 'h', '\0' \
|
||||
} /* Set new line mode */
|
||||
#define SHELL_VT100_SETAPPL \
|
||||
{ \
|
||||
SHELL_VT100_ASCII_ESC, '[', '?', '1', 'h', '\0' \
|
||||
} /* Set cursor key to application */
|
||||
#define SHELL_VT100_SETCOL_132 \
|
||||
{ \
|
||||
SHELL_VT100_ASCII_ESC, '[', '?', '3', 'h', '\0' \
|
||||
} /* Set number of columns to 132 */
|
||||
#define SHELL_VT100_SETSMOOTH \
|
||||
{ \
|
||||
SHELL_VT100_ASCII_ESC, '[', '?', '4', 'h', '\0' \
|
||||
} /* Set smooth scrolling */
|
||||
#define SHELL_VT100_SETREVSCRN \
|
||||
{ \
|
||||
SHELL_VT100_ASCII_ESC, '[', '?', '5', 'h', '\0' \
|
||||
} /* Set reverse video on screen */
|
||||
#define SHELL_VT100_SETORGREL \
|
||||
{ \
|
||||
SHELL_VT100_ASCII_ESC, '[', '?', '6', 'h', '\0' \
|
||||
} /* Set origin to relative */
|
||||
#define SHELL_VT100_SETWRAP_ON \
|
||||
{ \
|
||||
SHELL_VT100_ASCII_ESC, '[', '?', '7', 'h', '\0' \
|
||||
} /* Set auto-wrap mode */
|
||||
#define SHELL_VT100_SETWRAP_OFF \
|
||||
{ \
|
||||
SHELL_VT100_ASCII_ESC, '[', '?', '7', 'l', '\0' \
|
||||
} /* Set auto-wrap mode */
|
||||
|
||||
#define SHELL_VT100_SETREP \
|
||||
{ \
|
||||
SHELL_VT100_ASCII_ESC, '[', '?', '8', 'h', '\0' \
|
||||
} /* Set auto-repeat mode */
|
||||
#define SHELL_VT100_SETINTER \
|
||||
{ \
|
||||
SHELL_VT100_ASCII_ESC, '[', '?', '9', 'h', '\0' \
|
||||
} /* Set interlacing mode */
|
||||
|
||||
#define SHELL_VT100_SETLF \
|
||||
{ \
|
||||
SHELL_VT100_ASCII_ESC, '[', '2', '0', 'l', '\0' \
|
||||
} /* Set line feed mode */
|
||||
#define SHELL_VT100_SETCURSOR \
|
||||
{ \
|
||||
SHELL_VT100_ASCII_ESC, '[', '?', '1', 'l', '\0' \
|
||||
} /* Set cursor key to cursor */
|
||||
#define SHELL_VT100_SETVT52 \
|
||||
{ \
|
||||
SHELL_VT100_ASCII_ESC, '[', '?', '2', 'l', '\0' \
|
||||
} /* Set VT52 (versus ANSI) */
|
||||
#define SHELL_VT100_SETCOL_80 \
|
||||
{ \
|
||||
SHELL_VT100_ASCII_ESC, '[', '?', '3', 'l', '\0' \
|
||||
} /* Set number of columns to 80 */
|
||||
#define SHELL_VT100_SETJUMP \
|
||||
{ \
|
||||
SHELL_VT100_ASCII_ESC, '[', '?', '4', 'l', '\0' \
|
||||
} /* Set jump scrolling */
|
||||
#define SHELL_VT100_SETNORMSCRN \
|
||||
{ \
|
||||
SHELL_VT100_ASCII_ESC, '[', '?', '5', 'l', '\0' \
|
||||
} /* Set normal video on screen */
|
||||
#define SHELL_VT100_SETORGABS \
|
||||
{ \
|
||||
SHELL_VT100_ASCII_ESC, '[', '?', '6', 'l', '\0' \
|
||||
} /* Set origin to absolute */
|
||||
#define SHELL_VT100_RESETWRAP \
|
||||
{ \
|
||||
SHELL_VT100_ASCII_ESC, '[', '?', '7', 'l', '\0' \
|
||||
} /* Reset auto-wrap mode */
|
||||
#define SHELL_VT100_RESETREP \
|
||||
{ \
|
||||
SHELL_VT100_ASCII_ESC, '[', '?', '8', 'l', '\0' \
|
||||
} /* Reset auto-repeat mode */
|
||||
#define SHELL_VT100_RESETINTER \
|
||||
{ \
|
||||
SHELL_VT100_ASCII_ESC, '[', '?', '9', 'l', '\0' \
|
||||
} /* Reset interlacing mode */
|
||||
|
||||
#define SHELL_VT100_ALTKEYPAD \
|
||||
{ \
|
||||
SHELL_VT100_ASCII_ESC, '=', '\0' \
|
||||
} /* Set alternate keypad mode */
|
||||
#define SHELL_VT100_NUMKEYPAD \
|
||||
{ \
|
||||
SHELL_VT100_ASCII_ESC, '>', '\0' \
|
||||
} /* Set numeric keypad mode */
|
||||
|
||||
#define SHELL_VT100_SETUKG0 \
|
||||
{ \
|
||||
SHELL_VT100_ASCII_ESC, '(', 'A', '\0' \
|
||||
} /* Set United Kingdom G0 character set */
|
||||
#define SHELL_VT100_SETUKG1 \
|
||||
{ \
|
||||
SHELL_VT100_ASCII_ESC, ')', 'A', '\0' \
|
||||
} /* Set United Kingdom G1 character set */
|
||||
#define SHELL_VT100_SETUSG0 \
|
||||
{ \
|
||||
SHELL_VT100_ASCII_ESC, '(', 'B', '\0' \
|
||||
} /* Set United States G0 character set */
|
||||
#define SHELL_VT100_SETUSG1 \
|
||||
{ \
|
||||
SHELL_VT100_ASCII_ESC, ')', 'B', '\0' \
|
||||
} /* Set United States G1 character set */
|
||||
#define SHELL_VT100_SETSPECG0 \
|
||||
{ \
|
||||
SHELL_VT100_ASCII_ESC, '(', '0', '\0' \
|
||||
} /* Set G0 special chars. & line set */
|
||||
#define SHELL_VT100_SETSPECG1 \
|
||||
{ \
|
||||
SHELL_VT100_ASCII_ESC, ')', '0', '\0' \
|
||||
} /* Set G1 special chars. & line set */
|
||||
#define SHELL_VT100_SETALTG0 \
|
||||
{ \
|
||||
SHELL_VT100_ASCII_ESC, '(', '1', '\0' \
|
||||
} /* Set G0 alternate character ROM */
|
||||
#define SHELL_VT100_SETALTG1 \
|
||||
{ \
|
||||
SHELL_VT100_ASCII_ESC, ')', '1', '\0' \
|
||||
} /* Set G1 alternate character ROM */
|
||||
#define SHELL_VT100_SETALTSPECG0 \
|
||||
{ \
|
||||
SHELL_VT100_ASCII_ESC, '(', '2', '\0' \
|
||||
} /* Set G0 alt char ROM and spec. graphics */
|
||||
#define SHELL_VT100_SETALTSPECG1 \
|
||||
{ \
|
||||
SHELL_VT100_ASCII_ESC, ')', '2', '\0' \
|
||||
} /* Set G1 alt char ROM and spec. graphics */
|
||||
|
||||
#define SHELL_VT100_SETSS2 \
|
||||
{ \
|
||||
SHELL_VT100_ASCII_ESC, 'N', '\0' \
|
||||
} /* Set single shift 2 */
|
||||
#define SHELL_VT100_SETSS3 \
|
||||
{ \
|
||||
SHELL_VT100_ASCII_ESC, 'O', '\0' \
|
||||
} /* Set single shift 3 */
|
||||
|
||||
#define SHELL_VT100_MODESOFF \
|
||||
{ \
|
||||
SHELL_VT100_ASCII_ESC, '[', 'm', '\0' \
|
||||
} /* Turn off character attributes */
|
||||
#define SHELL_VT100_MODESOFF_ \
|
||||
{ \
|
||||
SHELL_VT100_ASCII_ESC, '[', '0', 'm', '\0' \
|
||||
} /* Turn off character attributes */
|
||||
#define SHELL_VT100_BOLD \
|
||||
{ \
|
||||
SHELL_VT100_ASCII_ESC, '[', '1', 'm', '\0' \
|
||||
} /* Turn bold mode on */
|
||||
#define SHELL_VT100_LOWINT \
|
||||
{ \
|
||||
SHELL_VT100_ASCII_ESC, '[', '2', 'm', '\0' \
|
||||
} /* Turn low intensity mode on */
|
||||
#define SHELL_VT100_UNDERLINE \
|
||||
{ \
|
||||
SHELL_VT100_ASCII_ESC, '[', '4', 'm', '\0' \
|
||||
} /* Turn underline mode on */
|
||||
#define SHELL_VT100_BLINK \
|
||||
{ \
|
||||
SHELL_VT100_ASCII_ESC, '[', '5', 'm', '\0' \
|
||||
} /* Turn blinking mode on */
|
||||
#define SHELL_VT100_REVERSE \
|
||||
{ \
|
||||
SHELL_VT100_ASCII_ESC, '[', '7', 'm', '\0' \
|
||||
} /* Turn reverse video on */
|
||||
#define SHELL_VT100_INVISIBLE \
|
||||
{ \
|
||||
SHELL_VT100_ASCII_ESC, '[', '8', 'm', '\0' \
|
||||
} /* Turn invisible text mode on */
|
||||
|
||||
#define SHELL_VT100_SETWIN(t, b) \
|
||||
{ \
|
||||
SHELL_VT100_ASCII_ESC, '[', (t), ';', (b), 'r', '\0' \
|
||||
} /* Set top and bottom line#s of a window */
|
||||
|
||||
#define SHELL_VT100_CURSORUP(n) \
|
||||
{ \
|
||||
SHELL_VT100_ASCII_ESC, '[', (n), 'A', '\0' \
|
||||
} /* Move cursor up n lines */
|
||||
#define SHELL_VT100_CURSORDN(n) \
|
||||
{ \
|
||||
SHELL_VT100_ASCII_ESC, '[', (n), 'B', '\0' \
|
||||
} /* Move cursor down n lines */
|
||||
#define SHELL_VT100_CURSORRT(n) \
|
||||
{ \
|
||||
SHELL_VT100_ASCII_ESC, '[', (n), 'C', '\0' \
|
||||
} /* Move cursor right n lines */
|
||||
#define SHELL_VT100_CURSORLF(n) \
|
||||
{ \
|
||||
SHELL_VT100_ASCII_ESC, '[', (n), 'D', '\0' \
|
||||
} /* Move cursor left n lines */
|
||||
#define SHELL_VT100_CURSORHOME \
|
||||
{ \
|
||||
SHELL_VT100_ASCII_ESC, '[', 'H', '\0' \
|
||||
} /* Move cursor to upper left corner */
|
||||
#define SHELL_VT100_CURSORHOME_ \
|
||||
{ \
|
||||
SHELL_VT100_ASCII_ESC, '[', ';', 'H', '\0' \
|
||||
} /* Move cursor to upper left corner */
|
||||
#define SHELL_VT100_CURSORPOS(v, h) \
|
||||
{ \
|
||||
SHELL_VT100_ASCII_ESC, '[', (v), ';', (h), 'H', '\0' \
|
||||
} /* Move cursor to screen location v,h */
|
||||
|
||||
#define SHELL_VT100_HVHOME \
|
||||
{ \
|
||||
SHELL_VT100_ASCII_ESC, '[', 'f', '\0' \
|
||||
} /* Move cursor to upper left corner */
|
||||
#define SHELL_VT100_HVHOME_ \
|
||||
{ \
|
||||
SHELL_VT100_ASCII_ESC, '[', ';', 'f', '\0' \
|
||||
} /* Move cursor to upper left corner */
|
||||
#define SHELL_VT100_HVPOS(v, h) \
|
||||
{ \
|
||||
SHELL_VT100_ASCII_ESC, '[', (v), ';', (h), 'f', '\0' \
|
||||
} /* Move cursor to screen location v,h */
|
||||
#define SHELL_VT100_INDEX \
|
||||
{ \
|
||||
SHELL_VT100_ASCII_ESC, 'D', '\0' \
|
||||
} /* Move/scroll window up one line */
|
||||
#define SHELL_VT100_REVINDEX \
|
||||
{ \
|
||||
SHELL_VT100_ASCII_ESC, 'M', '\0' \
|
||||
} /* Move/scroll window down one line */
|
||||
#define SHELL_VT100_NEXTLINE \
|
||||
{ \
|
||||
SHELL_VT100_ASCII_ESC, 'E', '\0' \
|
||||
} /* Move to next line */
|
||||
#define SHELL_VT100_SAVECURSOR \
|
||||
{ \
|
||||
SHELL_VT100_ASCII_ESC, '7', '\0' \
|
||||
} /* Save cursor position and attributes */
|
||||
#define SHELL_VT100_RESTORECURSOR \
|
||||
{ \
|
||||
SHELL_VT100_ASCII_ESC, '8', '\0' \
|
||||
} /* Restore cursor position and attribute */
|
||||
|
||||
#define SHELL_VT100_TABSET \
|
||||
{ \
|
||||
SHELL_VT100_ASCII_ESC, 'H', '\0' \
|
||||
} /* Set a tab at the current column */
|
||||
#define SHELL_VT100_TABCLR \
|
||||
{ \
|
||||
SHELL_VT100_ASCII_ESC, '[', 'g', '\0' \
|
||||
} /* Clear a tab at the current column */
|
||||
#define SHELL_VT100_TABCLR_ \
|
||||
{ \
|
||||
SHELL_VT100_ASCII_ESC, '[', '0', 'g', '\0' \
|
||||
} /* Clear a tab at the current column */
|
||||
#define SHELL_VT100_TABCLRALL \
|
||||
{ \
|
||||
SHELL_VT100_ASCII_ESC, '[', '3', 'g', '\0' \
|
||||
} /* Clear all tabs */
|
||||
|
||||
#define SHELL_VT100_DHTOP \
|
||||
{ \
|
||||
SHELL_VT100_ASCII_ESC, '#', '3', '\0' \
|
||||
} /* Double-height letters, top half */
|
||||
#define SHELL_VT100_DHBOT \
|
||||
{ \
|
||||
SHELL_VT100_ASCII_ESC, '#', '4', '\0' \
|
||||
} /* Double-height letters, bottom hal */
|
||||
#define SHELL_VT100_SWSH \
|
||||
{ \
|
||||
SHELL_VT100_ASCII_ESC, '#', '5', '\0' \
|
||||
} /* Single width, single height letters */
|
||||
#define SHELL_VT100_DWSH \
|
||||
{ \
|
||||
SHELL_VT100_ASCII_ESC, '#', '6', '\0' \
|
||||
} /* Double width, single height letters */
|
||||
|
||||
#define SHELL_VT100_CLEAREOL \
|
||||
{ \
|
||||
SHELL_VT100_ASCII_ESC, '[', 'K', '\0' \
|
||||
} /* Clear line from cursor right */
|
||||
#define SHELL_VT100_CLEAREOL_ \
|
||||
{ \
|
||||
SHELL_VT100_ASCII_ESC, '[', '0', 'K', '\0' \
|
||||
} /* Clear line from cursor right */
|
||||
#define SHELL_VT100_CLEARBOL \
|
||||
{ \
|
||||
SHELL_VT100_ASCII_ESC, '[', '1', 'K', '\0' \
|
||||
} /* Clear line from cursor left */
|
||||
#define SHELL_VT100_CLEARLINE \
|
||||
{ \
|
||||
SHELL_VT100_ASCII_ESC, '[', '2', 'K', '\0' \
|
||||
} /* Clear entire line */
|
||||
|
||||
#define SHELL_VT100_CLEAREOS \
|
||||
{ \
|
||||
SHELL_VT100_ASCII_ESC, '[', 'J', '\0' \
|
||||
} /* Clear screen from cursor down */
|
||||
#define SHELL_VT100_CLEAREOS_ \
|
||||
{ \
|
||||
SHELL_VT100_ASCII_ESC, '[', '0', 'J', '\0' \
|
||||
} /* Clear screen from cursor down */
|
||||
#define SHELL_VT100_CLEARBOS \
|
||||
{ \
|
||||
SHELL_VT100_ASCII_ESC, '[', '1', 'J', '\0' \
|
||||
} /* Clear screen from cursor up */
|
||||
#define SHELL_VT100_CLEARSCREEN \
|
||||
{ \
|
||||
SHELL_VT100_ASCII_ESC, '[', '2', 'J', '\0' \
|
||||
} /* Clear entire screen */
|
||||
|
||||
#define SHELL_VT100_DEVSTAT \
|
||||
{ \
|
||||
SHELL_VT100_ASCII_ESC, '5', 'n', '\0' \
|
||||
} /* Device status report */
|
||||
#define SHELL_VT100_TERMOK \
|
||||
{ \
|
||||
SHELL_VT100_ASCII_ESC, '0', 'n', '\0' \
|
||||
} /* Response: terminal is OK */
|
||||
#define SHELL_VT100_TERMNOK \
|
||||
{ \
|
||||
SHELL_VT100_ASCII_ESC, '3', 'n', '\0' \
|
||||
} /* Response: terminal is not OK */
|
||||
|
||||
#define SHELL_VT100_GETCURSOR \
|
||||
{ \
|
||||
SHELL_VT100_ASCII_ESC, '[', '6', 'n', '\0' \
|
||||
} /* Get cursor position */
|
||||
#define SHELL_VT100_CURSORPOSAT \
|
||||
{ \
|
||||
SHELL_VT100_ASCII_ESC, (v), ';', (h), 'R', '\0' \
|
||||
} /* Response: cursor is at v,h */
|
||||
|
||||
#define SHELL_VT100_IDENT \
|
||||
{ \
|
||||
SHELL_VT100_ASCII_ESC, '[', 'c', '\0' \
|
||||
} /* Identify what terminal type */
|
||||
#define SHELL_VT100_IDENT_ \
|
||||
{ \
|
||||
SHELL_VT100_ASCII_ESC, '[', '0', 'c', '\0' \
|
||||
} /* Identify what terminal type */
|
||||
#define SHELL_VT100_GETTYPE \
|
||||
{ \
|
||||
SHELL_VT100_ASCII_ESC, '[', '?', '1', ';', (n), '0', 'c', '\0' \
|
||||
} /* Response: terminal type code n */
|
||||
|
||||
#define SHELL_VT100_RESET \
|
||||
{ \
|
||||
SHELL_VT100_ASCII_ESC, 'c', '\0' \
|
||||
} /*Reset terminal to initial state */
|
||||
|
||||
#define SHELL_VT100_ALIGN \
|
||||
{ \
|
||||
SHELL_VT100_ASCII_ESC, '#', '8', '\0' \
|
||||
} /* Screen alignment display */
|
||||
#define SHELL_VT100_TESTPU \
|
||||
{ \
|
||||
SHELL_VT100_ASCII_ESC, '[', '2', ';', '1', 'y', '\0' \
|
||||
} /* Confidence power up test */
|
||||
#define SHELL_VT100_TESTLB \
|
||||
{ \
|
||||
SHELL_VT100_ASCII_ESC, '[', '2', ';', '2', 'y', '\0' \
|
||||
} /* Confidence loopback test */
|
||||
#define SHELL_VT100_TESTPUREP \
|
||||
{ \
|
||||
SHELL_VT100_ASCII_ESC, '[', '2', ';', '9', 'y', '\0' \
|
||||
} /* Repeat power up test */
|
||||
#define SHELL_VT100_TESTLBREP \
|
||||
{ \
|
||||
SHELL_VT100_ASCII_ESC, '[', '2', ';', '1', '0', 'y', '\0' \
|
||||
} /* Repeat loopback test */
|
||||
|
||||
#define SHELL_VT100_LEDSOFF \
|
||||
{ \
|
||||
SHELL_VT100_ASCII_ESC, '[', '0', 'q', '\0' \
|
||||
} /* Turn off all four leds */
|
||||
#define SHELL_VT100_LED1 \
|
||||
{ \
|
||||
SHELL_VT100_ASCII_ESC, '[', '1', 'q', '\0' \
|
||||
} /* Turn on LED #1 */
|
||||
#define SHELL_VT100_LED2 \
|
||||
{ \
|
||||
SHELL_VT100_ASCII_ESC, '[', '2', 'q', '\0' \
|
||||
} /* Turn on LED #2 */
|
||||
#define SHELL_VT100_LED3 \
|
||||
{ \
|
||||
SHELL_VT100_ASCII_ESC, '[', '3', 'q', '\0' \
|
||||
} /* Turn on LED #3 */
|
||||
#define SHELL_VT100_LED4 \
|
||||
{ \
|
||||
SHELL_VT100_ASCII_ESC, '[', '4', 'q', '\0' \
|
||||
} /* Turn on LED #4 */
|
||||
|
||||
/* Function Keys */
|
||||
|
||||
#define SHELL_VT100_PF1 \
|
||||
{ \
|
||||
SHELL_VT100_ASCII_ESC, 'O', 'P', '\0' \
|
||||
}
|
||||
#define SHELL_VT100_PF2 \
|
||||
{ \
|
||||
SHELL_VT100_ASCII_ESC, 'O', 'Q', '\0' \
|
||||
}
|
||||
|
||||
#define SHELL_VT100_PF3 \
|
||||
{ \
|
||||
SHELL_VT100_ASCII_ESC, 'O', 'R', '\0' \
|
||||
}
|
||||
#define SHELL_VT100_PF4 \
|
||||
{ \
|
||||
SHELL_VT100_ASCII_ESC, 'O', 'S', '\0' \
|
||||
}
|
||||
|
||||
/* Arrow keys */
|
||||
|
||||
#define SHELL_VT100_UP_RESET \
|
||||
{ \
|
||||
SHELL_VT100_ASCII_ESC, 'A', '\0' \
|
||||
}
|
||||
#define SHELL_VT100_UP_SET \
|
||||
{ \
|
||||
SHELL_VT100_ASCII_ESC, 'O', 'A', '\0' \
|
||||
}
|
||||
#define SHELL_VT100_DOWN_RESET \
|
||||
{ \
|
||||
SHELL_VT100_ASCII_ESC, 'B', '\0' \
|
||||
}
|
||||
#define SHELL_VT100_DOWN_SET \
|
||||
{ \
|
||||
SHELL_VT100_ASCII_ESC, 'O', 'B', '\0' \
|
||||
}
|
||||
#define SHELL_VT100_RIGHT_RESET \
|
||||
{ \
|
||||
SHELL_VT100_ASCII_ESC, 'C', '\0' \
|
||||
}
|
||||
#define SHELL_VT100_RIGHT_SET \
|
||||
{ \
|
||||
SHELL_VT100_ASCII_ESC, 'O', 'C', '\0' \
|
||||
}
|
||||
#define SHELL_VT100_LEFT_RESET \
|
||||
{ \
|
||||
SHELL_VT100_ASCII_ESC, 'D', '\0' \
|
||||
}
|
||||
#define SHELL_VT100_LEFT_SET \
|
||||
{ \
|
||||
SHELL_VT100_ASCII_ESC, 'O', 'D', '\0' \
|
||||
}
|
||||
|
||||
/* Numeric Keypad Keys */
|
||||
#define SHELL_VT100_NUMERIC_0 \
|
||||
{ \
|
||||
'0', '\0' \
|
||||
}
|
||||
#define SHELL_VT100_ALT_0 \
|
||||
{ \
|
||||
SHELL_VT100_ASCII_ESC, 'O', 'p', '\0' \
|
||||
}
|
||||
#define SHELL_VT100_NUMERIC_1 \
|
||||
{ \
|
||||
'1', '\0' \
|
||||
}
|
||||
#define SHELL_VT100_ALT_1 \
|
||||
{ \
|
||||
SHELL_VT100_ASCII_ESC, 'O', 'q', '\0' \
|
||||
}
|
||||
#define SHELL_VT100_NUMERIC_2 \
|
||||
{ \
|
||||
'2', '\0' \
|
||||
}
|
||||
#define SHELL_VT100_ALT_2 \
|
||||
{ \
|
||||
SHELL_VT100_ASCII_ESC, 'O', 'r', '\0' \
|
||||
}
|
||||
#define SHELL_VT100_NUMERIC_3 \
|
||||
{ \
|
||||
'3', '\0' \
|
||||
}
|
||||
#define SHELL_VT100_ALT_3 \
|
||||
{ \
|
||||
SHELL_VT100_ASCII_ESC, 'O', 's', '\0' \
|
||||
}
|
||||
#define SHELL_VT100_NUMERIC_4 \
|
||||
{ \
|
||||
'4', '\0' \
|
||||
}
|
||||
#define SHELL_VT100_ALT_4 \
|
||||
{ \
|
||||
SHELL_VT100_ASCII_ESC, 'O', 't', '\0' \
|
||||
}
|
||||
#define SHELL_VT100_NUMERIC_5 \
|
||||
{ \
|
||||
'5', '\0' \
|
||||
}
|
||||
#define SHELL_VT100_ALT_5 \
|
||||
{ \
|
||||
SHELL_VT100_ASCII_ESC, 'O', 'u', '\0' \
|
||||
}
|
||||
#define SHELL_VT100_NUMERIC_6 \
|
||||
{ \
|
||||
'6', '\0' \
|
||||
}
|
||||
#define SHELL_VT100_ALT_6 \
|
||||
{ \
|
||||
SHELL_VT100_ASCII_ESC, 'O', 'v', '\0' \
|
||||
}
|
||||
#define SHELL_VT100_NUMERIC_7 \
|
||||
{ \
|
||||
'7', '\0' \
|
||||
}
|
||||
#define SHELL_VT100_ALT_7 \
|
||||
{ \
|
||||
SHELL_VT100_ASCII_ESC, 'O', 'w', '\0' \
|
||||
}
|
||||
#define SHELL_VT100_NUMERIC_8 \
|
||||
{ \
|
||||
'8', '\0' \
|
||||
}
|
||||
#define SHELL_VT100_ALT_8 \
|
||||
{ \
|
||||
SHELL_VT100_ASCII_ESC, 'O', 'x', '\0' \
|
||||
}
|
||||
#define SHELL_VT100_NUMERIC_9 \
|
||||
{ \
|
||||
'9', '\0' \
|
||||
}
|
||||
#define SHELL_VT100_ALT_9 \
|
||||
{ \
|
||||
SHELL_VT100_ASCII_ESC, 'O', 'y' \
|
||||
}
|
||||
#define SHELL_VT100_NUMERIC_MINUS \
|
||||
{ \
|
||||
'-', '\0' \
|
||||
}
|
||||
#define SHELL_VT100_ALT_MINUS \
|
||||
{ \
|
||||
SHELL_VT100_ASCII_ESC, 'O', 'm', '\0' \
|
||||
}
|
||||
#define SHELL_VT100_NUMERIC_COMMA \
|
||||
{ \
|
||||
',', '\0' \
|
||||
}
|
||||
#define SHELL_VT100_ALT_COMMA \
|
||||
{ \
|
||||
SHELL_VT100_ASCII_ESC, 'O', 'l', '\0' \
|
||||
}
|
||||
#define SHELL_VT100_NUMERIC_ENTER \
|
||||
{ \
|
||||
ASCII_CR \
|
||||
}
|
||||
#define SHELL_VT100_NUMERIC_PERIOD \
|
||||
{ \
|
||||
'.', '\0' \
|
||||
}
|
||||
#define SHELL_VT100_ALT_PERIOD \
|
||||
{ \
|
||||
SHELL_VT100_ASCII_ESC, 'O', 'n', '\0' \
|
||||
}
|
||||
#define SHELL_VT100_ALT_ENTER \
|
||||
{ \
|
||||
SHELL_VT100_ASCII_ESC, 'O', 'M', '\0' \
|
||||
}
|
||||
#define SHELL_VT100_BGCOLOR(__col) \
|
||||
{ \
|
||||
SHELL_VT100_ASCII_ESC, '[', '4', '0' + (__col), 'm', '\0' \
|
||||
}
|
||||
#define SHELL_VT100_COLOR(__col) \
|
||||
{ \
|
||||
SHELL_VT100_ASCII_ESC, '[', '1', ';', '3', '0' + (__col), 'm', '\0' \
|
||||
}
|
||||
|
||||
#endif /* SHELL_VT100_H__ */
|
Loading…
Add table
Add a link
Reference in a new issue