[RFC PATCH 09/11] cmd: nvedit: Use getopt() in env grep
Simon Glass
sjg at chromium.org
Fri May 15 22:33:00 CEST 2026
The nested while/switch parser walks each -prefixed argv element by
hand. The -- end-of-options marker is implemented by a case '-' arm
that does 'goto DONE' to jump out of both the inner switch and the
outer argv walker, leaving the remaining argv to be treated as
positionals by hexport_r().
getopt() handles all of that natively: grouped flags (-nb), the '--'
boundary (it returns -1 and advances past --), unknown-option errors
and option permutation so 'env grep arch -n' works the same as
'env grep -n arch'. The goto, the label, and the case '-' arm all
disappear.
Pass "envb" or "nvb" to getopt() depending on IS_ENABLED(CONFIG_REGEX)
so -e is not advertised when regex is compiled out, and guard the
case 'e' arm with the same check so it costs nothing in the regex-off
build.
Move the missing-argument check to after parsing. The existing argc < 2
check fires only when no args at all are given; the new gs.nonopts < 1
check also catches 'env grep -n' (options but no search pattern), where
the previous version would silently let hexport_r() run with an empty
pattern list.
CMD_GREPENV selects GETOPT so the parser is linked in on boards that did
not already enable it.
Tweak the var declarations to use Reverse Christmas Tree.
Signed-off-by: Simon Glass <sjg at chromium.org>
---
cmd/Kconfig | 1 +
cmd/nvedit.c | 56 +++++++++++++++++++++++++---------------------------
2 files changed, 28 insertions(+), 29 deletions(-)
diff --git a/cmd/Kconfig b/cmd/Kconfig
index eb7c85c1fe9..8ba7b1e6bd1 100644
--- a/cmd/Kconfig
+++ b/cmd/Kconfig
@@ -721,6 +721,7 @@ config CMD_EDITENV
config CMD_GREPENV
bool "search env"
+ select GETOPT
help
Allow for searching environment variables
diff --git a/cmd/nvedit.c b/cmd/nvedit.c
index 636bddee1be..8561c408992 100644
--- a/cmd/nvedit.c
+++ b/cmd/nvedit.c
@@ -29,6 +29,7 @@
#include <console.h>
#include <env.h>
#include <env_internal.h>
+#include <getopt.h>
#include <log.h>
#include <search.h>
#include <errno.h>
@@ -131,45 +132,42 @@ static int do_env_print(struct cmd_tbl *cmdtp, int flag, int argc,
static int do_env_grep(struct cmd_tbl *cmdtp, int flag,
int argc, char *const argv[])
{
- char *res = NULL;
int len, grep_how, grep_what;
-
- if (argc < 2)
- return CMD_RET_USAGE;
+ struct getopt_state gs;
+ char *res = NULL;
+ int opt;
grep_how = H_MATCH_SUBSTR; /* default: substring search */
grep_what = H_MATCH_BOTH; /* default: grep names and values */
- while (--argc > 0 && **++argv == '-') {
- char *arg = *argv;
- while (*++arg) {
- switch (*arg) {
-#ifdef CONFIG_REGEX
- case 'e': /* use regex matching */
- grep_how = H_MATCH_REGEX;
- break;
-#endif
- case 'n': /* grep for name */
- grep_what = H_MATCH_KEY;
- break;
- case 'v': /* grep for value */
- grep_what = H_MATCH_DATA;
- break;
- case 'b': /* grep for both */
- grep_what = H_MATCH_BOTH;
- break;
- case '-':
- goto DONE;
- default:
- return CMD_RET_USAGE;
- }
+ getopt_init_state(&gs, argc, argv);
+ while ((opt = getopt(&gs, IS_ENABLED(CONFIG_REGEX) ? "envb"
+ : "nvb")) > 0) {
+ switch (opt) {
+ case 'e': /* use regex matching */
+ if (IS_ENABLED(CONFIG_REGEX))
+ grep_how = H_MATCH_REGEX;
+ break;
+ case 'n': /* grep for name */
+ grep_what = H_MATCH_KEY;
+ break;
+ case 'v': /* grep for value */
+ grep_what = H_MATCH_DATA;
+ break;
+ case 'b': /* grep for both */
+ grep_what = H_MATCH_BOTH;
+ break;
+ default:
+ return CMD_RET_USAGE;
}
}
-DONE:
+ if (gs.nonopts < 1)
+ return CMD_RET_USAGE;
+
len = hexport_r(&env_htab, '\n',
flag | grep_what | grep_how,
- &res, 0, argc, argv);
+ &res, 0, gs.nonopts, &gs.args[gs.index]);
if (len > 0) {
puts(res);
--
2.43.0
More information about the U-Boot
mailing list