Browse Source

shell: add getopt library support

This functionality is is enabled by setting CONFIG_SHELL_GETOPT.
It is not active by default.

User can call following functions inside command handlers:
 - shell_getopt - getopt function based on freebsd implementation
 - shell_getopt_status_get - returns getopt status

Beware when getopt functionality is enabled shell will not parse
command handler to look for "-h" or "--help" options and print
help message automatically.

Signed-off-by: Jakub Rzeszutko <jakub.rzeszutko@nordicsemi.no>
pull/31544/head
Jakub Rzeszutko 5 years ago committed by Anas Nashif
parent
commit
7e46765153
  1. 46
      include/shell/shell.h
  2. 27
      include/shell/shell_getopt.h
  3. 5
      subsys/shell/CMakeLists.txt
  4. 6
      subsys/shell/Kconfig
  5. 4
      subsys/shell/shell.c
  6. 37
      subsys/shell/shell_getopt.c

46
include/shell/shell.h

@ -16,6 +16,10 @@ @@ -16,6 +16,10 @@
#include <logging/log.h>
#include <sys/util.h>
#if defined CONFIG_SHELL_GETOPT
#include <shell/shell_getopt.h>
#endif
#ifdef __cplusplus
extern "C" {
#endif
@ -67,6 +71,7 @@ extern "C" { @@ -67,6 +71,7 @@ extern "C" {
* @{
*/
struct getopt_state;
struct shell_static_entry;
/**
@ -649,6 +654,11 @@ struct shell_ctx { @@ -649,6 +654,11 @@ struct shell_ctx {
/*!< VT100 color and cursor position, terminal width.*/
struct shell_vt100_ctx vt100_ctx;
#if defined CONFIG_SHELL_GETOPT
/*!< getopt context for a shell backend. */
struct getopt_state getopt_state;
#endif
uint16_t cmd_buff_len; /*!< Command length.*/
uint16_t cmd_buff_pos; /*!< Command buffer cursor position.*/
@ -958,6 +968,40 @@ void shell_help(const struct shell *shell); @@ -958,6 +968,40 @@ void shell_help(const struct shell *shell);
/* @brief Command's help has been printed */
#define SHELL_CMD_HELP_PRINTED (1)
#if defined CONFIG_SHELL_GETOPT
/**
* @brief Parses the command-line arguments.
*
* It is based on FreeBSD implementation.
*
* @param[in] shell Pointer to the shell instance.
* @param[in] argc Arguments count.
* @param[in] argv Arguments.
* @param[in] ostr String containing the legitimate option characters.
*
* @return If an option was successfully found, function returns
* the option character.
* @return If options have been detected that is not in @p ostr
* function will return '?'.
* If function encounters an option with a missing
* argument, then the return value depends on the first
* character in optstring: if it is ':', then ':' is
* returned; otherwise '?' is returned.
* @return -1 If all options have been parsed.
*/
int shell_getopt(const struct shell *shell, int argc, char *const argv[],
const char *ostr);
/**
* @brief Returns shell_getopt state.
*
* @param[in] shell Pointer to the shell instance.
*
* @return Pointer to struct getopt_state.
*/
struct getopt_state *shell_getopt_state_get(const struct shell *shell);
#endif /* CONFIG_SHELL_GETOPT */
/** @brief Execute command.
*
* Pass command line to shell to execute.
@ -973,7 +1017,7 @@ void shell_help(const struct shell *shell); @@ -973,7 +1017,7 @@ void shell_help(const struct shell *shell);
* @option{CONFIG_SHELL_BACKEND_DUMMY} option is enabled.
* @param[in] cmd Command to be executed.
*
* @returns Result of the execution
* @return Result of the execution
*/
int shell_execute_cmd(const struct shell *shell, const char *cmd);

27
include/shell/shell_getopt.h

@ -0,0 +1,27 @@ @@ -0,0 +1,27 @@
/*
* Copyright (c) 2021 Nordic Semiconductor ASA
*
* SPDX-License-Identifier: Apache-2.0
*/
#ifndef SHELL_GETOPT_H__
#define SHELL_GETOPT_H__
#include <getopt.h>
#ifdef __cplusplus
extern "C" {
#endif
/* Initializing shell getopt module.
*
* @param[in] shell Pointer to the shell instance.
*/
void z_shell_getopt_init(struct getopt_state *state);
#ifdef __cplusplus
}
#endif
#endif /* SHELL_GETOPT_H__ */

5
subsys/shell/CMakeLists.txt

@ -35,6 +35,11 @@ zephyr_sources_ifdef( @@ -35,6 +35,11 @@ zephyr_sources_ifdef(
shell_help.c
)
zephyr_sources_ifdef(
CONFIG_SHELL_GETOPT
shell_getopt.c
)
zephyr_sources_ifdef(
CONFIG_SHELL_CMDS
shell_cmds.c

6
subsys/shell/Kconfig

@ -109,6 +109,12 @@ config SHELL_VT100_COLORS @@ -109,6 +109,12 @@ config SHELL_VT100_COLORS
help
If enabled VT100 colors are used in shell (e.g. print errors in red).
config SHELL_GETOPT
bool "Enable getopt support"
select GETOPT
help
Enables getopt support in the shell.
config SHELL_METAKEYS
bool "Enable metakeys"
default y if !SHELL_MINIMAL

4
subsys/shell/shell.c

@ -533,6 +533,10 @@ static int exec_cmd(const struct shell *shell, size_t argc, const char **argv, @@ -533,6 +533,10 @@ static int exec_cmd(const struct shell *shell, size_t argc, const char **argv,
}
if (!ret_val) {
#if CONFIG_SHELL_GETOPT
z_shell_getopt_init(&shell->ctx->getopt_state);
#endif
z_flag_cmd_ctx_set(shell, true);
/* Unlock thread mutex in case command would like to borrow
* shell context to other thread to avoid mutex deadlock.

37
subsys/shell/shell_getopt.c

@ -0,0 +1,37 @@ @@ -0,0 +1,37 @@
/*
* Copyright (c) 2021 Nordic Semiconductor ASA
*
* SPDX-License-Identifier: Apache-2.0
*/
#include <zephyr.h>
#include <shell/shell.h>
#include <shell/shell_getopt.h>
void z_shell_getopt_init(struct getopt_state *state)
{
getopt_init(state);
}
int shell_getopt(const struct shell *shell, int argc, char *const argv[],
const char *ostr)
{
if (!IS_ENABLED(CONFIG_SHELL_GETOPT)) {
return 0;
}
__ASSERT_NO_MSG(shell);
return getopt(&shell->ctx->getopt_state, argc, argv, ostr);
}
struct getopt_state *shell_getopt_state_get(const struct shell *shell)
{
if (!IS_ENABLED(CONFIG_SHELL_GETOPT)) {
return NULL;
}
__ASSERT_NO_MSG(shell);
return &shell->ctx->getopt_state;
}
Loading…
Cancel
Save