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

