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 <[email protected]> --- 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

