[PATCH v4 12/14] cmd: nvedit: Use getopt() in env grep

Simon Glass sjg at chromium.org
Wed Jul 1 13:42:32 CEST 2026


do_env_grep() hand-rolls the same grouped-flag parser as the other env
subcommands: an outer loop over - arguments and an inner while (*++arg)
over the characters, with an explicit case to spot the -- terminator.

Parse the options with getopt() instead. getopt() handles the grouped
form and the -- terminator natively, and the optstring keeps the +
prefix so it stops at the first non-option as the hand-rolled loop did.
Read the search patterns from gs.argv[gs.index] onward.

Move do_env_grep() to the getopt-state command signature, like env
export and env import. The standalone grepenv command uses tab
completion, so declare it with the new U_BOOT_CMD_GETOPT_COMPLETE()
which keeps the auto-complete function.

The existing code ORs the command flag into the hexport_r() flags. That
is inherited from the original parser but is wrong: flag holds
CMD_FLAG_* bits which alias the H_NOCLEAR/H_FORCE/H_INTERACTIVE bits
hexport_r() uses (they happen to be ignored on the export path). Drop it
and pass only grep_what | grep_how. The behaviour is otherwise
unchanged.

CMD_GREPENV selects GETOPT so the parser is linked in on boards that do
not already enable it.

Signed-off-by: Simon Glass <sjg at chromium.org>
---

(no changes since v1)

 cmd/Kconfig  |  1 +
 cmd/nvedit.c | 63 +++++++++++++++++++++++++---------------------------
 2 files changed, 31 insertions(+), 33 deletions(-)

diff --git a/cmd/Kconfig b/cmd/Kconfig
index 842afa2f390..9cafeb5d07c 100644
--- a/cmd/Kconfig
+++ b/cmd/Kconfig
@@ -723,6 +723,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 95d53ba5c32..2af6e9dc03e 100644
--- a/cmd/nvedit.c
+++ b/cmd/nvedit.c
@@ -129,49 +129,46 @@ static int do_env_print(struct cmd_tbl *cmdtp, int flag, int argc,
 }
 
 #ifdef CONFIG_CMD_GREPENV
-static int do_env_grep(struct cmd_tbl *cmdtp, int flag,
-		       int argc, char *const argv[])
+static int do_env_grep(struct getopt_state *gs)
 {
+	const char *optstring = IS_ENABLED(CONFIG_REGEX) ? "+envb" : "+nvb";
 	char *res = NULL;
 	int len, grep_how, grep_what;
-
-	if (argc < 2)
-		return CMD_RET_USAGE;
+	int argc;
+	char *const *argv;
+	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 */
+	while ((opt = getopt(gs, optstring)) > 0) {
+		switch (opt) {
+		case 'e':		/* use regex matching */
+			if (IS_ENABLED(CONFIG_REGEX))
 				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;
-			}
+			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:
-	len = hexport_r(&env_htab, '\n',
-			flag | grep_what | grep_how,
-			&res, 0, argc, argv);
+	argc = gs->argc - gs->index;
+	argv = &gs->argv[gs->index];
 
+	if (argc < 1)
+		return CMD_RET_USAGE;
+
+	len = hexport_r(&env_htab, '\n', grep_what | grep_how, &res, 0,
+			argc, argv);
 	if (len > 0) {
 		puts(res);
 		free(res);
@@ -1077,7 +1074,7 @@ static struct cmd_tbl cmd_env_sub[] = {
 	U_BOOT_CMD_MKENT_GETOPT(export, 4, 0, do_env_export, "", ""),
 #endif
 #if defined(CONFIG_CMD_GREPENV)
-	U_BOOT_CMD_MKENT(grep, CONFIG_SYS_MAXARGS, 1, do_env_grep, "", ""),
+	U_BOOT_CMD_MKENT_GETOPT(grep, CONFIG_SYS_MAXARGS, 0, do_env_grep, "", ""),
 #endif
 #if defined(CONFIG_CMD_IMPORTENV)
 	U_BOOT_CMD_MKENT_GETOPT(import, 5, 0, do_env_import, "", ""),
@@ -1232,7 +1229,7 @@ U_BOOT_CMD_COMPLETE(
 );
 
 #ifdef CONFIG_CMD_GREPENV
-U_BOOT_CMD_COMPLETE(
+U_BOOT_CMD_GETOPT_COMPLETE(
 	grepenv, CONFIG_SYS_MAXARGS, 0,  do_env_grep,
 	"search environment variables",
 #ifdef CONFIG_REGEX
-- 
2.43.0



More information about the U-Boot mailing list