mirror of
https://github.com/espressif/esp-idf.git
synced 2024-10-05 20:47:46 -04:00
feat(system/console): add help command verbose level option
Support users to demonstrate command info in different verbose levels. Closes https://github.com/espressif/esp-idf/issues/9158
This commit is contained in:
parent
ea2f512cb5
commit
18f6be771d
@ -39,6 +39,8 @@ typedef struct cmd_item_ {
|
|||||||
SLIST_ENTRY(cmd_item_) next; //!< next command in the list
|
SLIST_ENTRY(cmd_item_) next; //!< next command in the list
|
||||||
} cmd_item_t;
|
} cmd_item_t;
|
||||||
|
|
||||||
|
typedef void (*const fn_print_arg_t)(cmd_item_t*);
|
||||||
|
|
||||||
/** linked list of command structures */
|
/** linked list of command structures */
|
||||||
static SLIST_HEAD(cmd_list_, cmd_item_) s_cmd_list;
|
static SLIST_HEAD(cmd_list_, cmd_item_) s_cmd_list;
|
||||||
|
|
||||||
@ -52,6 +54,8 @@ static char *s_tmp_line_buf;
|
|||||||
|
|
||||||
static const cmd_item_t *find_command_by_name(const char *name);
|
static const cmd_item_t *find_command_by_name(const char *name);
|
||||||
|
|
||||||
|
static esp_console_help_verbose_level_e s_verbose_level = ESP_CONSOLE_HELP_VERBOSE_LEVEL_1;
|
||||||
|
|
||||||
esp_err_t esp_console_init(const esp_console_config_t *config)
|
esp_err_t esp_console_init(const esp_console_config_t *config)
|
||||||
{
|
{
|
||||||
if (!config) {
|
if (!config) {
|
||||||
@ -245,6 +249,7 @@ esp_err_t esp_console_run(const char *cmdline, int *cmd_ret)
|
|||||||
|
|
||||||
static struct {
|
static struct {
|
||||||
struct arg_str *help_cmd;
|
struct arg_str *help_cmd;
|
||||||
|
struct arg_int *verbose_level;
|
||||||
struct arg_end *end;
|
struct arg_end *end;
|
||||||
} help_args;
|
} help_args;
|
||||||
|
|
||||||
@ -268,6 +273,17 @@ static void print_arg_help(cmd_item_t *it)
|
|||||||
printf("\n");
|
printf("\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void print_arg_command(cmd_item_t *it)
|
||||||
|
{
|
||||||
|
const char *hint = (it->hint) ? it->hint : "";
|
||||||
|
printf("%-s %s\n\n", it->command, hint);
|
||||||
|
}
|
||||||
|
|
||||||
|
static fn_print_arg_t print_verbose_level_arr[ESP_CONSOLE_HELP_VERBOSE_LEVEL_MAX_NUM] = {
|
||||||
|
print_arg_command,
|
||||||
|
print_arg_help,
|
||||||
|
};
|
||||||
|
|
||||||
static int help_command(int argc, char **argv)
|
static int help_command(int argc, char **argv)
|
||||||
{
|
{
|
||||||
int nerrors = arg_parse(argc, argv, (void **) &help_args);
|
int nerrors = arg_parse(argc, argv, (void **) &help_args);
|
||||||
@ -279,18 +295,33 @@ static int help_command(int argc, char **argv)
|
|||||||
|
|
||||||
cmd_item_t *it;
|
cmd_item_t *it;
|
||||||
int ret_value = 1;
|
int ret_value = 1;
|
||||||
|
esp_console_help_verbose_level_e verbose_level;
|
||||||
|
|
||||||
if (help_args.help_cmd->count == 0) {
|
if (help_args.help_cmd->count == 0) {
|
||||||
/* Print summary of each command */
|
/* If verbose level is not provided, set it as default value */
|
||||||
|
if (help_args.verbose_level->count == 0) {
|
||||||
|
verbose_level = s_verbose_level;
|
||||||
|
}
|
||||||
|
/* Else use the verbose level from input argument */
|
||||||
|
else {
|
||||||
|
verbose_level = (esp_console_help_verbose_level_e)help_args.verbose_level->ival[0];
|
||||||
|
}
|
||||||
|
/* Check if selected verbose level is valid, proceed if yes, else return */
|
||||||
|
if (verbose_level >= ESP_CONSOLE_HELP_VERBOSE_LEVEL_MAX_NUM) {
|
||||||
|
printf("help: invalid verbose level %d", (int)verbose_level);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Print info of each command based on verbose level */
|
||||||
SLIST_FOREACH(it, &s_cmd_list, next) {
|
SLIST_FOREACH(it, &s_cmd_list, next) {
|
||||||
if (it->help == NULL) {
|
if (it->help == NULL) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
print_arg_help(it);
|
print_verbose_level_arr[verbose_level](it);
|
||||||
}
|
}
|
||||||
ret_value = 0;
|
ret_value = 0;
|
||||||
} else {
|
} else {
|
||||||
/* Print summary of given command */
|
/* Print summary of given command, verbose option will be ignored */
|
||||||
bool found_command = false;
|
bool found_command = false;
|
||||||
SLIST_FOREACH(it, &s_cmd_list, next) {
|
SLIST_FOREACH(it, &s_cmd_list, next) {
|
||||||
if (it->help == NULL) {
|
if (it->help == NULL) {
|
||||||
@ -317,7 +348,9 @@ static int help_command(int argc, char **argv)
|
|||||||
esp_err_t esp_console_register_help_command(void)
|
esp_err_t esp_console_register_help_command(void)
|
||||||
{
|
{
|
||||||
help_args.help_cmd = arg_str0(NULL, NULL, "<string>", "Name of command");
|
help_args.help_cmd = arg_str0(NULL, NULL, "<string>", "Name of command");
|
||||||
help_args.end = arg_end(1);
|
help_args.verbose_level = arg_intn("v", "verbose", "<0|1>", 0, 1,
|
||||||
|
"If specified, list console commands with given verbose level");
|
||||||
|
help_args.end = arg_end(2);
|
||||||
|
|
||||||
esp_console_cmd_t command = {
|
esp_console_cmd_t command = {
|
||||||
.command = "help",
|
.command = "help",
|
||||||
@ -328,3 +361,12 @@ esp_err_t esp_console_register_help_command(void)
|
|||||||
};
|
};
|
||||||
return esp_console_cmd_register(&command);
|
return esp_console_cmd_register(&command);
|
||||||
}
|
}
|
||||||
|
esp_err_t esp_console_set_help_verbose_level(esp_console_help_verbose_level_e verbose_level)
|
||||||
|
{
|
||||||
|
/* legal verbose level sanity check */
|
||||||
|
if (verbose_level >= ESP_CONSOLE_HELP_VERBOSE_LEVEL_MAX_NUM) {
|
||||||
|
return ESP_ERR_INVALID_ARG;
|
||||||
|
}
|
||||||
|
s_verbose_level = verbose_level;
|
||||||
|
return ESP_OK;
|
||||||
|
}
|
||||||
|
@ -130,6 +130,12 @@ typedef struct {
|
|||||||
#define ESP_CONSOLE_DEV_USB_SERIAL_JTAG_CONFIG_DEFAULT() {}
|
#define ESP_CONSOLE_DEV_USB_SERIAL_JTAG_CONFIG_DEFAULT() {}
|
||||||
#endif // CONFIG_ESP_CONSOLE_USB_SERIAL_JTAG || (defined __DOXYGEN__ && SOC_USB_SERIAL_JTAG_SUPPORTED)
|
#endif // CONFIG_ESP_CONSOLE_USB_SERIAL_JTAG || (defined __DOXYGEN__ && SOC_USB_SERIAL_JTAG_SUPPORTED)
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
ESP_CONSOLE_HELP_VERBOSE_LEVEL_0 = 0,
|
||||||
|
ESP_CONSOLE_HELP_VERBOSE_LEVEL_1 = 1,
|
||||||
|
ESP_CONSOLE_HELP_VERBOSE_LEVEL_MAX_NUM = 2
|
||||||
|
} esp_console_help_verbose_level_e;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief initialize console module
|
* @brief initialize console module
|
||||||
* @param config console configuration
|
* @param config console configuration
|
||||||
@ -314,6 +320,18 @@ const char *esp_console_get_hint(const char *buf, int *color, int *bold);
|
|||||||
*/
|
*/
|
||||||
esp_err_t esp_console_register_help_command(void);
|
esp_err_t esp_console_register_help_command(void);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Set the verbose level for 'help' command
|
||||||
|
*
|
||||||
|
* Set the verbose level for 'help' command. Higher verbose level shows more details.
|
||||||
|
* Valid verbose_level values are described in esp_console_help_verbose_level_e and must be lower than `ESP_CONSOLE_HELP_VERBOSE_LEVEL_MAX_NUM`.
|
||||||
|
*
|
||||||
|
* @return
|
||||||
|
* - ESP_OK on success
|
||||||
|
* - ESP_ERR_INVALID_ARG, if invalid verbose level is provided
|
||||||
|
*/
|
||||||
|
esp_err_t esp_console_set_help_verbose_level(esp_console_help_verbose_level_e verbose_level);
|
||||||
|
|
||||||
/******************************************************************************
|
/******************************************************************************
|
||||||
* Console REPL
|
* Console REPL
|
||||||
******************************************************************************/
|
******************************************************************************/
|
||||||
|
@ -273,3 +273,37 @@ TEST_CASE("esp console test with context", "[console]")
|
|||||||
|
|
||||||
TEST_ESP_OK(esp_console_deinit());
|
TEST_ESP_OK(esp_console_deinit());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST_CASE("esp console help command - set verbose level = 0", "[console][ignore]")
|
||||||
|
{
|
||||||
|
esp_console_repl_config_t repl_config = ESP_CONSOLE_REPL_CONFIG_DEFAULT();
|
||||||
|
esp_console_dev_uart_config_t uart_config = ESP_CONSOLE_DEV_UART_CONFIG_DEFAULT();
|
||||||
|
TEST_ESP_OK(esp_console_new_repl_uart(&uart_config, &repl_config, &s_repl));
|
||||||
|
TEST_ESP_OK(esp_console_register_help_command());
|
||||||
|
TEST_ESP_ERR(ESP_ERR_INVALID_ARG, esp_console_set_help_verbose_level(ESP_CONSOLE_HELP_VERBOSE_LEVEL_MAX_NUM));
|
||||||
|
TEST_ESP_OK(esp_console_set_help_verbose_level(ESP_CONSOLE_HELP_VERBOSE_LEVEL_0));
|
||||||
|
TEST_ESP_OK(esp_console_start_repl(s_repl));
|
||||||
|
vTaskDelay(pdMS_TO_TICKS(5000));
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_CASE("esp console help command - set verbose level = 1", "[console][ignore]")
|
||||||
|
{
|
||||||
|
esp_console_repl_config_t repl_config = ESP_CONSOLE_REPL_CONFIG_DEFAULT();
|
||||||
|
esp_console_dev_uart_config_t uart_config = ESP_CONSOLE_DEV_UART_CONFIG_DEFAULT();
|
||||||
|
TEST_ESP_OK(esp_console_new_repl_uart(&uart_config, &repl_config, &s_repl));
|
||||||
|
TEST_ESP_OK(esp_console_register_help_command());
|
||||||
|
TEST_ESP_ERR(ESP_ERR_INVALID_ARG, esp_console_set_help_verbose_level(ESP_CONSOLE_HELP_VERBOSE_LEVEL_MAX_NUM));
|
||||||
|
TEST_ESP_OK(esp_console_set_help_verbose_level(ESP_CONSOLE_HELP_VERBOSE_LEVEL_1));
|
||||||
|
TEST_ESP_OK(esp_console_start_repl(s_repl));
|
||||||
|
vTaskDelay(pdMS_TO_TICKS(5000));
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_CASE("esp console help command - --verbose sub command", "[console][ignore]")
|
||||||
|
{
|
||||||
|
esp_console_repl_config_t repl_config = ESP_CONSOLE_REPL_CONFIG_DEFAULT();
|
||||||
|
esp_console_dev_uart_config_t uart_config = ESP_CONSOLE_DEV_UART_CONFIG_DEFAULT();
|
||||||
|
TEST_ESP_OK(esp_console_new_repl_uart(&uart_config, &repl_config, &s_repl));
|
||||||
|
TEST_ESP_OK(esp_console_register_help_command());
|
||||||
|
TEST_ESP_OK(esp_console_start_repl(s_repl));
|
||||||
|
vTaskDelay(pdMS_TO_TICKS(5000));
|
||||||
|
}
|
||||||
|
@ -183,3 +183,81 @@ def test_console_sorted_help_reverse_registration(dut: Dut, test_on: str) -> Non
|
|||||||
)
|
)
|
||||||
def test_console_help_quit(dut: Dut, test_on: str) -> None:
|
def test_console_help_quit(dut: Dut, test_on: str) -> None:
|
||||||
do_test_help_quit(dut)
|
do_test_help_quit(dut)
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.parametrize(
|
||||||
|
'config', [
|
||||||
|
pytest.param('defaults'),
|
||||||
|
]
|
||||||
|
)
|
||||||
|
@pytest.mark.parametrize(
|
||||||
|
'test_on', [
|
||||||
|
pytest.param('host', marks=[pytest.mark.linux, pytest.mark.host_test]),
|
||||||
|
pytest.param('target', marks=[pytest.mark.esp32, pytest.mark.generic]),
|
||||||
|
pytest.param('target', marks=[pytest.mark.esp32c3, pytest.mark.generic]),
|
||||||
|
pytest.param('qemu', marks=[pytest.mark.esp32, pytest.mark.host_test, pytest.mark.qemu]),
|
||||||
|
]
|
||||||
|
)
|
||||||
|
def test_console_help_verbose_level_0(dut: Dut, test_on: str) -> None:
|
||||||
|
help_verbose_info = 'Print the summary of all registered commands if no arguments are given,'
|
||||||
|
dut.expect_exact('Press ENTER to see the list of tests')
|
||||||
|
dut.write('"esp console help command - set verbose level = 0"')
|
||||||
|
|
||||||
|
dut.expect_exact('esp>', timeout=5)
|
||||||
|
# verify help command
|
||||||
|
dut.write('help')
|
||||||
|
dut.write('help')
|
||||||
|
dut.expect_exact('help', not_matching=help_verbose_info)
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.parametrize(
|
||||||
|
'config', [
|
||||||
|
pytest.param('defaults'),
|
||||||
|
]
|
||||||
|
)
|
||||||
|
@pytest.mark.parametrize(
|
||||||
|
'test_on', [
|
||||||
|
pytest.param('host', marks=[pytest.mark.linux, pytest.mark.host_test]),
|
||||||
|
pytest.param('target', marks=[pytest.mark.esp32, pytest.mark.generic]),
|
||||||
|
pytest.param('target', marks=[pytest.mark.esp32c3, pytest.mark.generic]),
|
||||||
|
pytest.param('qemu', marks=[pytest.mark.esp32, pytest.mark.host_test, pytest.mark.qemu]),
|
||||||
|
]
|
||||||
|
)
|
||||||
|
def test_console_help_verbose_level_1(dut: Dut, test_on: str) -> None:
|
||||||
|
help_verbose_info = 'Print the summary of all registered commands if no arguments are given,'
|
||||||
|
dut.expect_exact('Press ENTER to see the list of tests')
|
||||||
|
dut.write('"esp console help command - set verbose level = 1"')
|
||||||
|
|
||||||
|
dut.expect_exact('esp>', timeout=5)
|
||||||
|
# verify help command
|
||||||
|
dut.write('help')
|
||||||
|
dut.expect_exact(help_verbose_info)
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.parametrize(
|
||||||
|
'config', [
|
||||||
|
pytest.param('defaults'),
|
||||||
|
]
|
||||||
|
)
|
||||||
|
@pytest.mark.parametrize(
|
||||||
|
'test_on', [
|
||||||
|
pytest.param('host', marks=[pytest.mark.linux, pytest.mark.host_test]),
|
||||||
|
pytest.param('target', marks=[pytest.mark.esp32, pytest.mark.generic]),
|
||||||
|
pytest.param('target', marks=[pytest.mark.esp32c3, pytest.mark.generic]),
|
||||||
|
pytest.param('qemu', marks=[pytest.mark.esp32, pytest.mark.host_test, pytest.mark.qemu]),
|
||||||
|
]
|
||||||
|
)
|
||||||
|
def test_console_help_verbose_subcommand(dut: Dut, test_on: str) -> None:
|
||||||
|
help_verbose_info = 'Print the summary of all registered commands if no arguments are given,'
|
||||||
|
dut.expect_exact('Press ENTER to see the list of tests')
|
||||||
|
dut.write('"esp console help command - --verbose sub command"')
|
||||||
|
|
||||||
|
dut.expect_exact('esp>', timeout=5)
|
||||||
|
# verify help --verbose=0 subcommand
|
||||||
|
dut.write('help --verbose=0')
|
||||||
|
dut.write('help --verbose=0')
|
||||||
|
dut.expect_exact('help --verbose=0',not_matching=help_verbose_info)
|
||||||
|
|
||||||
|
# verify help --verbose=1 subcommand
|
||||||
|
dut.write('help --verbose=1')
|
||||||
|
dut.expect_exact(help_verbose_info)
|
||||||
|
Loading…
Reference in New Issue
Block a user