[PATCH 2/2] cmd: nvedit: Use getopt() in env import
Simon Glass
sjg at chromium.org
Wed May 20 22:12:14 CEST 2026
This is the other gnarly hand-rolled parser 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
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) and the trailing positional list is read from
argv + gs.index.
Adjust CMD_IMPORTENV to select GETOPT so the parser is linked in on
boards that did not already enable it.
Also redo the sep_err logic and error message, along with a fmt tweak
to reduce code size.
Signed-off-by: Simon Glass <sjg at chromium.org>
---
cmd/Kconfig | 1 +
cmd/nvedit.c | 95 ++++++++++++++++++++++++----------------------------
env/common.c | 2 +-
3 files changed, 46 insertions(+), 52 deletions(-)
diff --git a/cmd/Kconfig b/cmd/Kconfig
index a5a20bde4b5..72ff4dbfe60 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 5dca1b804fd..ce1f0e9bd2c 100644
--- a/cmd/nvedit.c
+++ b/cmd/nvedit.c
@@ -752,64 +752,64 @@ static int do_env_export(struct cmd_tbl *cmdtp, int flag,
static int do_env_import(struct cmd_tbl *cmdtp, int flag,
int argc, char *const argv[])
{
+ struct getopt_state gs;
ulong addr;
- char *cmd, *ptr;
+ char *ptr, *tok;
char sep = '\n';
int chk = 0;
int fmt = 0;
int del = 0;
int crlf_is_lf = 0;
- int wl = 0;
+ int wl;
size_t size;
+ int opt;
- 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 '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;
- }
+ getopt_init_state(&gs);
+ while ((opt = getopt(&gs, argc, argv, "bctrd")) > 0) {
+ fmt++;
+ switch (opt) {
+ case 'b': /* raw binary format */
+ sep = '\0';
+ break;
+ case 'c': /* external checksum format */
+ sep = '\0';
+ chk = 1;
+ break;
+ case 't': /* text format (default) */
+ break;
+ case 'r': /* handle CRLF like LF */
+ crlf_is_lf = 1;
+ fmt--;
+ break;
+ case 'd':
+ del = 1;
+ fmt--;
+ break;
+ default:
+ return CMD_RET_USAGE;
}
}
- 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 CMD_RET_USAGE;
+ }
if (!fmt)
printf("## Warning: defaulting to text format\n");
- if (sep != '\n' && crlf_is_lf )
+ if (sep != '\n' && crlf_is_lf)
crlf_is_lf = 0;
- addr = hextoul(argv[0], NULL);
+ addr = hextoul(argv[gs.index++], NULL);
ptr = map_sysmem(addr, 0);
- if (argc >= 2 && strcmp(argv[1], "-")) {
- size = hextoul(argv[1], NULL);
+ tok = gs.index < argc ? argv[gs.index++] : NULL;
+ if (tok && strcmp(tok, "-")) {
+ size = hextoul(tok, NULL);
} else if (chk) {
puts("## Error: external checksum format must pass size\n");
return CMD_RET_FAILURE;
@@ -825,22 +825,19 @@ static int do_env_import(struct cmd_tbl *cmdtp, int flag,
++size;
}
if (size == MAX_ENV_SIZE) {
- printf("## Warning: Input data exceeds %d bytes"
+ printf("## Warning: Input exceeds %d bytes"
" - truncated\n", MAX_ENV_SIZE);
}
size += 2;
- printf("## Info: input data size = %zu = 0x%zX\n", size, size);
+ printf("## Info: input size = %zu = %#zX\n", size, size);
}
- if (argc > 2)
- wl = 1;
-
if (chk) {
uint32_t crc;
env_t *ep = (env_t *)ptr;
if (size <= offsetof(env_t, data)) {
- printf("## Error: Invalid size 0x%zX\n", size);
+ printf("## Error: Invalid size %#zX\n", size);
return 1;
}
@@ -854,20 +851,16 @@ static int do_env_import(struct cmd_tbl *cmdtp, int flag,
ptr = (char *)ep->data;
}
+ wl = argc - gs.index;
if (!himport_r(&env_htab, ptr, size, sep, del ? 0 : H_NOCLEAR,
- crlf_is_lf, wl ? argc - 2 : 0, wl ? &argv[2] : NULL)) {
- pr_err("## Error: Environment import failed: errno = %d\n",
+ crlf_is_lf, wl, wl ? &argv[gs.index] : NULL)) {
+ pr_err("## Error: Environment import failed (err %dE)\n",
errno);
return 1;
}
gd->flags |= GD_FLG_ENV_READY;
return 0;
-
-sep_err:
- printf("## %s: only one of \"-b\", \"-c\" or \"-t\" allowed\n",
- cmd);
- return 1;
}
#endif
diff --git a/env/common.c b/env/common.c
index b2adbe93dbe..986400f912f 100644
--- a/env/common.c
+++ b/env/common.c
@@ -402,7 +402,7 @@ void env_set_default(const char *s, int flags)
if (himport_r(&env_htab, default_environment,
sizeof(default_environment), '\0', flags, 0,
0, NULL) == 0) {
- pr_err("## Error: Environment import failed: errno = %d\n",
+ pr_err("## Error: Environment import failed (err %dE)\n",
errno);
return;
}
--
2.43.0
More information about the U-Boot
mailing list