[PATCH v4 11/14] cmd: nvedit: Use getopt() in env import

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


do_env_import() is the other gnarly hand-rolled parser in nvedit.c, and
walks each - argument by hand, opens an inner while (*++arg) to split
grouped flags and tracks an fmt counter to reject a second -b/-c/-t.

Replace the parser with getopt(). Move do_env_import() to the
getopt-state command signature, declared with U_BOOT_CMD_MKENT_GETOPT().
Move the format-flag mutual-exclusion check after the option loop and
read the trailing positional list from gs->argv[gs->index].

Keep the + prefix on the optstring so getopt() stops at the first
non-option, exactly as the hand-rolled loop did. This matters here: the
size positional can be a literal - (meaning no size, rely on the '\0'
termination), which the permuting parser would otherwise consume. The
behaviour is otherwise unchanged; keep the messages and the
size/checksum handling as-is.

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

Leave the himport_r() interface unchanged for now. It would benefit
from an API rethink at some point, since passing argc/argv is a bit
clunky now.

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

Changes in v4:
- Update commit message to mention himport_r()

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

diff --git a/cmd/Kconfig b/cmd/Kconfig
index e3d92055f17..842afa2f390 100644
--- a/cmd/Kconfig
+++ b/cmd/Kconfig
@@ -711,6 +711,7 @@ config CMD_EXPORTENV
 config CMD_IMPORTENV
 	bool "env import"
 	default y
+	select GETOPT
 	help
 	  Import environments.
 
diff --git a/cmd/nvedit.c b/cmd/nvedit.c
index c74898a05fb..95d53ba5c32 100644
--- a/cmd/nvedit.c
+++ b/cmd/nvedit.c
@@ -760,8 +760,7 @@ sep_err:
  *		the environment at address 'addr'. Without arguments, the whole
  *		environment gets imported.
  */
-static int do_env_import(struct cmd_tbl *cmdtp, int flag,
-			 int argc, char *const argv[])
+static int do_env_import(struct getopt_state *gs)
 {
 	ulong	addr;
 	char	*cmd, *ptr;
@@ -772,40 +771,42 @@ static int do_env_import(struct cmd_tbl *cmdtp, int flag,
 	int	crlf_is_lf = 0;
 	int	wl = 0;
 	size_t	size;
+	int	argc;
+	char	*const *argv;
+	int	opt;
 
-	cmd = *argv;
+	cmd = gs->argv[0];
 
-	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 't':		/* text format */
-				if (fmt++)
-					goto sep_err;
-				sep = '\n';
-				break;
-			case 'r':		/* handle CRLF like LF */
-				crlf_is_lf = 1;
-				break;
-			case 'd':
-				del = 1;
-				break;
-			default:
-				return CMD_RET_USAGE;
-			}
+	while ((opt = getopt(gs, "+bcdrt")) > 0) {
+		switch (opt) {
+		case 'b':		/* raw binary format */
+			sep = '\0';
+			fmt++;
+			break;
+		case 'c':		/* external checksum format */
+			sep = '\0';
+			chk = 1;
+			fmt++;
+			break;
+		case 't':		/* text format */
+			sep = '\n';
+			fmt++;
+			break;
+		case 'r':		/* handle CRLF like LF */
+			crlf_is_lf = 1;
+			break;
+		case 'd':
+			del = 1;
+			break;
+		default:
+			return CMD_RET_USAGE;
 		}
 	}
+	if (fmt > 1)
+		goto sep_err;
+
+	argc = gs->argc - gs->index;
+	argv = &gs->argv[gs->index];
 
 	if (argc < 1)
 		return CMD_RET_USAGE;
@@ -1079,7 +1080,7 @@ static struct cmd_tbl cmd_env_sub[] = {
 	U_BOOT_CMD_MKENT(grep, CONFIG_SYS_MAXARGS, 1, do_env_grep, "", ""),
 #endif
 #if defined(CONFIG_CMD_IMPORTENV)
-	U_BOOT_CMD_MKENT(import, 5, 0, do_env_import, "", ""),
+	U_BOOT_CMD_MKENT_GETOPT(import, 5, 0, do_env_import, "", ""),
 #endif
 #if defined(CONFIG_CMD_NVEDIT_INDIRECT)
 	U_BOOT_CMD_MKENT(indirect, 3, 0, do_env_indirect, "", ""),
-- 
2.43.0



More information about the U-Boot mailing list