shell: Introduce structured help message
In order to enable better and more consistent help messages for shell commands, this commit introduces a new SHELL_HELP macro that allows to document a command's description and usage in a more structured way. This will allow to get rid of inconsistent (and duplicated!) variations of "Syntax: ...", "Syntax:\n ...", "Usage: ...", in the commands, and formatting of the description+usage will be taken care of by the shell when it detects the help message is using the "structured" format. Signed-off-by: Benjamin Cabé <benjamin@zephyrproject.org>
This commit is contained in:
parent
7bdeffb5a6
commit
9ab0ea73a8
2 changed files with 108 additions and 8 deletions
|
@ -234,6 +234,82 @@ struct shell_static_entry {
|
|||
uint8_t padding[Z_SHELL_STATIC_ENTRY_PADDING];
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Shell structured help descriptor.
|
||||
*
|
||||
* @details This structure provides an organized way to specify command help
|
||||
* as opposed to a free-form string. This helps make help messages more
|
||||
* consistent and easier to read.
|
||||
*/
|
||||
struct shell_cmd_help {
|
||||
/* @cond INTERNAL_HIDDEN */
|
||||
uint32_t magic;
|
||||
/* @endcond */
|
||||
const char *description; /*!< Command description */
|
||||
const char *usage; /*!< Command usage string */
|
||||
};
|
||||
|
||||
/**
|
||||
* @cond INTERNAL_HIDDEN
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief Magic number used to identify the beginning of a structured help
|
||||
* message when cast to a char pointer.
|
||||
*/
|
||||
#define SHELL_STRUCTURED_HELP_MAGIC 0x86D20BC4
|
||||
|
||||
/**
|
||||
* @endcond
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief Check if help string is structured help.
|
||||
*
|
||||
* @param help Pointer to help string or structured help.
|
||||
* @return true if help is structured, false otherwise.
|
||||
*/
|
||||
static inline bool shell_help_is_structured(const char *help)
|
||||
{
|
||||
const struct shell_cmd_help *structured = (const struct shell_cmd_help *)help;
|
||||
|
||||
return structured != NULL && structured->magic == SHELL_STRUCTURED_HELP_MAGIC;
|
||||
}
|
||||
|
||||
#if defined(CONFIG_SHELL_HELP) || defined(__DOXYGEN__)
|
||||
/**
|
||||
* @brief Helper macro to create structured help inline.
|
||||
*
|
||||
* This macro allows you to pass structured help directly to existing shell macros.
|
||||
*
|
||||
* Example:
|
||||
*
|
||||
* @code{.c}
|
||||
* #define MY_CMD_HELP SHELL_HELP("Do stuff", "<device> <arg1> [<arg2>]")
|
||||
* SHELL_CMD_REGISTER(my_cmd, NULL, MY_CMD_HELP, &my_cmd_handler, 1, 1);
|
||||
* @endcode
|
||||
*
|
||||
* @param[in] _description Command description.
|
||||
* This can be a multi-line string. First line should be one sentence
|
||||
* describing the command. Additional lines might be used to provide
|
||||
* additional details.
|
||||
*
|
||||
* @param[in] _usage Command usage string.
|
||||
* This can be a multi-line string. First line should always be
|
||||
* indicating the command syntax (_without_ the command name).
|
||||
* Additional lines may be used to provide additional details, e.g.
|
||||
* explain the meaning of each argument, allowed values, etc.
|
||||
*/
|
||||
#define SHELL_HELP(_description, _usage) \
|
||||
((const char *)&(const struct shell_cmd_help){ \
|
||||
.magic = SHELL_STRUCTURED_HELP_MAGIC, \
|
||||
.description = (_description), \
|
||||
.usage = (_usage), \
|
||||
})
|
||||
#else
|
||||
#define SHELL_HELP(_description, _usage) NULL
|
||||
#endif /* CONFIG_SHELL_HELP */
|
||||
|
||||
/**
|
||||
* @brief Macro for defining and adding a root command (level 0) with required
|
||||
* number of arguments.
|
||||
|
@ -244,7 +320,7 @@ struct shell_static_entry {
|
|||
*
|
||||
* @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] help Pointer to a command help string (use @ref SHELL_HELP for structured help)
|
||||
* @param[in] handler Pointer to a function handler.
|
||||
* @param[in] mandatory Number of mandatory arguments including command name.
|
||||
* @param[in] optional Number of optional arguments.
|
||||
|
@ -275,7 +351,7 @@ struct shell_static_entry {
|
|||
* exists and equals 1.
|
||||
* @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] help Pointer to a command help string (use @ref SHELL_HELP for structured help).
|
||||
* @param[in] handler Pointer to a function handler.
|
||||
* @param[in] mandatory Number of mandatory arguments including command name.
|
||||
* @param[in] optional Number of optional arguments.
|
||||
|
@ -303,7 +379,7 @@ struct shell_static_entry {
|
|||
*
|
||||
* @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] help Pointer to a command help string. Use @ref SHELL_HELP for structured help.
|
||||
* @param[in] handler Pointer to a function handler.
|
||||
*/
|
||||
#define SHELL_CMD_REGISTER(syntax, subcmd, help, handler) \
|
||||
|
@ -319,7 +395,7 @@ struct shell_static_entry {
|
|||
* exists and equals 1.
|
||||
* @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] help Pointer to a command help string. Use @ref SHELL_HELP for structured help.
|
||||
* @param[in] handler Pointer to a function handler.
|
||||
*/
|
||||
#define SHELL_COND_CMD_REGISTER(flag, syntax, subcmd, help, handler) \
|
||||
|
@ -455,7 +531,7 @@ struct shell_static_entry {
|
|||
*
|
||||
* @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] help Pointer to a command help string. Use @ref SHELL_HELP for structured help.
|
||||
* @param[in] handler Pointer to a function handler.
|
||||
* @param[in] mand Number of mandatory arguments including command name.
|
||||
* @param[in] opt Number of optional arguments.
|
||||
|
@ -477,7 +553,7 @@ struct shell_static_entry {
|
|||
* exists and equals 1.
|
||||
* @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] help Pointer to a command help string. Use @ref SHELL_HELP for structured help.
|
||||
* @param[in] handler Pointer to a function handler.
|
||||
* @param[in] mand Number of mandatory arguments including command name.
|
||||
* @param[in] opt Number of optional arguments.
|
||||
|
|
|
@ -113,6 +113,22 @@ static void formatted_text_print(const struct shell *sh, const char *str,
|
|||
z_cursor_next_line_move(sh);
|
||||
}
|
||||
|
||||
static void formatted_structured_help_print(const struct shell *sh, const char *item_name,
|
||||
const char *item_help, size_t terminal_offset)
|
||||
{
|
||||
const struct shell_cmd_help *structured = (const struct shell_cmd_help *)item_help;
|
||||
|
||||
if (structured->description) {
|
||||
formatted_text_print(sh, structured->description, terminal_offset, false);
|
||||
}
|
||||
|
||||
if (structured->usage) {
|
||||
z_shell_op_cursor_horiz_move(sh, terminal_offset);
|
||||
z_shell_fprintf(sh, SHELL_NORMAL, "Usage: %s ", item_name);
|
||||
formatted_text_print(sh, structured->usage, terminal_offset + 7, false);
|
||||
}
|
||||
}
|
||||
|
||||
static void help_item_print(const struct shell *sh, const char *item_name,
|
||||
uint16_t item_name_width, const char *item_help)
|
||||
{
|
||||
|
@ -150,7 +166,11 @@ static void help_item_print(const struct shell *sh, const char *item_name,
|
|||
z_shell_fprintf(sh, SHELL_NORMAL, "%s: ", tabulator);
|
||||
}
|
||||
/* print option help */
|
||||
formatted_text_print(sh, item_help, offset, false);
|
||||
if (shell_help_is_structured(item_help)) {
|
||||
formatted_structured_help_print(sh, item_name, item_help, offset);
|
||||
} else {
|
||||
formatted_text_print(sh, item_help, offset, false);
|
||||
}
|
||||
}
|
||||
|
||||
/* Function prints all subcommands of the parent command together with their
|
||||
|
@ -197,7 +217,11 @@ void z_shell_help_cmd_print(const struct shell *sh,
|
|||
|
||||
z_shell_fprintf(sh, SHELL_NORMAL, "%s%s", cmd->syntax, cmd_sep);
|
||||
|
||||
formatted_text_print(sh, cmd->help, field_width, false);
|
||||
if (shell_help_is_structured(cmd->help)) {
|
||||
formatted_structured_help_print(sh, cmd->syntax, cmd->help, field_width);
|
||||
} else {
|
||||
formatted_text_print(sh, cmd->help, field_width, false);
|
||||
}
|
||||
}
|
||||
|
||||
bool z_shell_help_request(const char *str)
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue