[PATCH 1/2] cmd: nvedit: Use getopt() in env export

Simon Glass sjg at chromium.org
Wed May 20 22:12:13 CEST 2026


This is one of the gnarliest hand-rolled parsers in nvedit.c

The code walks each -prefixed argv element by hand, opens an inner
while (*++arg) to split grouped flags, and tracks a fmt counter to
catch a second -b / -c / -t

It also adds a 'goto NXTARG' that jumps over the inner loop after
consuming the argument to -s SIZE, since the rest of the current
argv element no longer makes sense once -s has eaten the next slot.

getopt() collapses all of that. The mutex check for the format flags
is done after the option loop (it is a per-command rule, not an
option-parsing rule), the -s argument arrives in gs.arg, and the
trailing positional list is read from argv + gs.index.

Adjust CMD_EXPORTENV to select GETOPT so the parser is linked in on
boards that did not already enable it.

Also redo the sep_err logic, use env_set_hex() and shorten error
messages to reduce code size.

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

 cmd/Kconfig  |  1 +
 cmd/nvedit.c | 89 ++++++++++++++++++++++------------------------------
 2 files changed, 38 insertions(+), 52 deletions(-)

diff --git a/cmd/Kconfig b/cmd/Kconfig
index c71c6824a19..a5a20bde4b5 100644
--- a/cmd/Kconfig
+++ b/cmd/Kconfig
@@ -704,6 +704,7 @@ config CMD_ASKENV
 config CMD_EXPORTENV
 	bool "env export"
 	default y
+	select GETOPT
 	help
 	  Export environments.
 
diff --git a/cmd/nvedit.c b/cmd/nvedit.c
index 636bddee1be..5dca1b804fd 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>
@@ -634,73 +635,62 @@ static int do_env_delete(struct cmd_tbl *cmdtp, int flag,
 static int do_env_export(struct cmd_tbl *cmdtp, int flag,
 			 int argc, char *const argv[])
 {
-	char	buf[32];
+	struct getopt_state gs;
 	ulong	addr;
-	char	*ptr, *cmd, *res;
+	char	*ptr, *res;
 	size_t	size = 0;
 	ssize_t	len;
 	env_t	*envp;
 	char	sep = '\n';
 	int	chk = 0;
 	int	fmt = 0;
-
-	cmd = *argv;
-
-	while (--argc > 0 && **++argv == '-') {
-		char *arg = *argv;
-		while (*++arg) {
-			switch (*arg) {
-			case 'b':		/* raw binary format */
-				if (fmt++)
-					goto sep_err;
-				sep = '\0';
-				break;
-			case 'c':		/* external checksum format */
-				if (fmt++)
-					goto sep_err;
-				sep = '\0';
-				chk = 1;
-				break;
-			case 's':		/* size given */
-				if (--argc <= 0)
-					return cmd_usage(cmdtp);
-				size = hextoul(*++argv, NULL);
-				goto NXTARG;
-			case 't':		/* text format */
-				if (fmt++)
-					goto sep_err;
-				sep = '\n';
-				break;
-			default:
-				return CMD_RET_USAGE;
-			}
+	int	opt;
+
+	getopt_init_state(&gs);
+	while ((opt = getopt(&gs, argc, argv, "bcs:t")) > 0) {
+		fmt++;
+		switch (opt) {
+		case 'b':		/* raw binary format */
+			sep = '\0';
+			break;
+		case 'c':		/* external checksum format */
+			sep = '\0';
+			chk = 1;
+			break;
+		case 's':		/* size given */
+			size = hextoul(gs.arg, NULL);
+			fmt--;
+			break;
+		case 't':		/* text format (default) */
+			break;
+		default:
+			return CMD_RET_USAGE;
 		}
-NXTARG:		;
 	}
 
-	if (argc < 1)
+	if (gs.index >= argc)
 		return CMD_RET_USAGE;
+	if (fmt > 1) {
+		printf("## Error: %s: only one of -b/c/t allowed\n", argv[0]);
+		return 1;
+	}
 
-	addr = hextoul(argv[0], NULL);
+	addr = hextoul(argv[gs.index++], NULL);
 	ptr = map_sysmem(addr, size);
 
 	if (size)
 		memset(ptr, '\0', size);
 
-	argc--;
-	argv++;
-
 	if (sep) {		/* export as text file */
 		len = hexport_r(&env_htab, sep,
-				H_MATCH_KEY | H_MATCH_IDENT,
-				&ptr, size, argc, argv);
+				H_MATCH_KEY | H_MATCH_IDENT, &ptr, size,
+				argc - gs.index, &argv[gs.index]);
 		if (len < 0) {
-			pr_err("## Error: Cannot export environment: errno = %d\n",
+			pr_err("## Error: Cannot export environment (err %dE)\n",
 			       errno);
 			return 1;
 		}
-		sprintf(buf, "%zX", (size_t)len);
-		env_set("filesize", buf);
+		env_set_hex("filesize", len);
 
 		return 0;
 	}
@@ -713,10 +703,10 @@ NXTARG:		;
 		res = ptr;
 
 	len = hexport_r(&env_htab, '\0',
-			H_MATCH_KEY | H_MATCH_IDENT,
-			&res, ENV_SIZE, argc, argv);
+			H_MATCH_KEY | H_MATCH_IDENT, &res, ENV_SIZE,
+			argc - gs.index, &argv[gs.index]);
 	if (len < 0) {
-		pr_err("## Error: Cannot export environment: errno = %d\n",
+		pr_err("## Error: Cannot export environment (err %dE)\n",
 		       errno);
 		return 1;
 	}
@@ -731,11 +721,6 @@ NXTARG:		;
 	env_set_hex("filesize", len + offsetof(env_t, data));
 
 	return 0;
-
-sep_err:
-	printf("## Error: %s: only one of \"-b\", \"-c\" or \"-t\" allowed\n",
-	       cmd);
-	return 1;
 }
 #endif
 
-- 
2.43.0



More information about the U-Boot mailing list