Skip to content

Commit 7e46765

Browse files
Jakub Rzeszutkonashif
authored andcommitted
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 <[email protected]>
1 parent 74ebf5d commit 7e46765

File tree

6 files changed

+124
-1
lines changed

6 files changed

+124
-1
lines changed

include/shell/shell.h

Lines changed: 45 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,10 @@
1616
#include <logging/log.h>
1717
#include <sys/util.h>
1818

19+
#if defined CONFIG_SHELL_GETOPT
20+
#include <shell/shell_getopt.h>
21+
#endif
22+
1923
#ifdef __cplusplus
2024
extern "C" {
2125
#endif
@@ -67,6 +71,7 @@ extern "C" {
6771
* @{
6872
*/
6973

74+
struct getopt_state;
7075
struct shell_static_entry;
7176

7277
/**
@@ -649,6 +654,11 @@ struct shell_ctx {
649654
/*!< VT100 color and cursor position, terminal width.*/
650655
struct shell_vt100_ctx vt100_ctx;
651656

657+
#if defined CONFIG_SHELL_GETOPT
658+
/*!< getopt context for a shell backend. */
659+
struct getopt_state getopt_state;
660+
#endif
661+
652662
uint16_t cmd_buff_len; /*!< Command length.*/
653663
uint16_t cmd_buff_pos; /*!< Command buffer cursor position.*/
654664

@@ -958,6 +968,40 @@ void shell_help(const struct shell *shell);
958968
/* @brief Command's help has been printed */
959969
#define SHELL_CMD_HELP_PRINTED (1)
960970

971+
#if defined CONFIG_SHELL_GETOPT
972+
/**
973+
* @brief Parses the command-line arguments.
974+
*
975+
* It is based on FreeBSD implementation.
976+
*
977+
* @param[in] shell Pointer to the shell instance.
978+
* @param[in] argc Arguments count.
979+
* @param[in] argv Arguments.
980+
* @param[in] ostr String containing the legitimate option characters.
981+
*
982+
* @return If an option was successfully found, function returns
983+
* the option character.
984+
* @return If options have been detected that is not in @p ostr
985+
* function will return '?'.
986+
* If function encounters an option with a missing
987+
* argument, then the return value depends on the first
988+
* character in optstring: if it is ':', then ':' is
989+
* returned; otherwise '?' is returned.
990+
* @return -1 If all options have been parsed.
991+
*/
992+
int shell_getopt(const struct shell *shell, int argc, char *const argv[],
993+
const char *ostr);
994+
995+
/**
996+
* @brief Returns shell_getopt state.
997+
*
998+
* @param[in] shell Pointer to the shell instance.
999+
*
1000+
* @return Pointer to struct getopt_state.
1001+
*/
1002+
struct getopt_state *shell_getopt_state_get(const struct shell *shell);
1003+
#endif /* CONFIG_SHELL_GETOPT */
1004+
9611005
/** @brief Execute command.
9621006
*
9631007
* Pass command line to shell to execute.
@@ -973,7 +1017,7 @@ void shell_help(const struct shell *shell);
9731017
* @option{CONFIG_SHELL_BACKEND_DUMMY} option is enabled.
9741018
* @param[in] cmd Command to be executed.
9751019
*
976-
* @returns Result of the execution
1020+
* @return Result of the execution
9771021
*/
9781022
int shell_execute_cmd(const struct shell *shell, const char *cmd);
9791023

include/shell/shell_getopt.h

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
/*
2+
* Copyright (c) 2021 Nordic Semiconductor ASA
3+
*
4+
* SPDX-License-Identifier: Apache-2.0
5+
*/
6+
7+
#ifndef SHELL_GETOPT_H__
8+
#define SHELL_GETOPT_H__
9+
10+
#include <getopt.h>
11+
12+
#ifdef __cplusplus
13+
extern "C" {
14+
#endif
15+
16+
17+
/* Initializing shell getopt module.
18+
*
19+
* @param[in] shell Pointer to the shell instance.
20+
*/
21+
void z_shell_getopt_init(struct getopt_state *state);
22+
23+
#ifdef __cplusplus
24+
}
25+
#endif
26+
27+
#endif /* SHELL_GETOPT_H__ */

subsys/shell/CMakeLists.txt

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,11 @@ zephyr_sources_ifdef(
3535
shell_help.c
3636
)
3737

38+
zephyr_sources_ifdef(
39+
CONFIG_SHELL_GETOPT
40+
shell_getopt.c
41+
)
42+
3843
zephyr_sources_ifdef(
3944
CONFIG_SHELL_CMDS
4045
shell_cmds.c

subsys/shell/Kconfig

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -109,6 +109,12 @@ config SHELL_VT100_COLORS
109109
help
110110
If enabled VT100 colors are used in shell (e.g. print errors in red).
111111

112+
config SHELL_GETOPT
113+
bool "Enable getopt support"
114+
select GETOPT
115+
help
116+
Enables getopt support in the shell.
117+
112118
config SHELL_METAKEYS
113119
bool "Enable metakeys"
114120
default y if !SHELL_MINIMAL

subsys/shell/shell.c

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -533,6 +533,10 @@ static int exec_cmd(const struct shell *shell, size_t argc, const char **argv,
533533
}
534534

535535
if (!ret_val) {
536+
#if CONFIG_SHELL_GETOPT
537+
z_shell_getopt_init(&shell->ctx->getopt_state);
538+
#endif
539+
536540
z_flag_cmd_ctx_set(shell, true);
537541
/* Unlock thread mutex in case command would like to borrow
538542
* shell context to other thread to avoid mutex deadlock.

subsys/shell/shell_getopt.c

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
/*
2+
* Copyright (c) 2021 Nordic Semiconductor ASA
3+
*
4+
* SPDX-License-Identifier: Apache-2.0
5+
*/
6+
7+
#include <zephyr.h>
8+
#include <shell/shell.h>
9+
#include <shell/shell_getopt.h>
10+
11+
void z_shell_getopt_init(struct getopt_state *state)
12+
{
13+
getopt_init(state);
14+
}
15+
16+
int shell_getopt(const struct shell *shell, int argc, char *const argv[],
17+
const char *ostr)
18+
{
19+
if (!IS_ENABLED(CONFIG_SHELL_GETOPT)) {
20+
return 0;
21+
}
22+
23+
__ASSERT_NO_MSG(shell);
24+
25+
return getopt(&shell->ctx->getopt_state, argc, argv, ostr);
26+
}
27+
28+
struct getopt_state *shell_getopt_state_get(const struct shell *shell)
29+
{
30+
if (!IS_ENABLED(CONFIG_SHELL_GETOPT)) {
31+
return NULL;
32+
}
33+
34+
__ASSERT_NO_MSG(shell);
35+
36+
return &shell->ctx->getopt_state;
37+
}

0 commit comments

Comments
 (0)