do_env_grep() hand-rolls the same grouped-flag parser as the other env subcommands: an outer loop over - arguments and an inner while (*++arg) over the characters, with an explicit case to spot the -- terminator.
Parse the options with getopt() instead. getopt() handles the grouped form and the -- terminator natively, and the optstring keeps the + prefix so it stops at the first non-option as the hand-rolled loop did. Read the search patterns from gs.argv[gs.index] onward. Move do_env_grep() to the getopt-state command signature, like env export and env import. The standalone grepenv command uses tab completion, so declare it with the new U_BOOT_CMD_GETOPT_COMPLETE() which keeps the auto-complete function. The existing code ORs the command flag into the hexport_r() flags. That is inherited from the original parser but is wrong: flag holds CMD_FLAG_* bits which alias the H_NOCLEAR/H_FORCE/H_INTERACTIVE bits hexport_r() uses (they happen to be ignored on the export path). Drop it and pass only grep_what | grep_how. The behaviour is otherwise unchanged. CMD_GREPENV selects GETOPT so the parser is linked in on boards that do not already enable it. Signed-off-by: Simon Glass <[email protected]> --- (no changes since v1) cmd/Kconfig | 1 + cmd/nvedit.c | 63 +++++++++++++++++++++++++--------------------------- 2 files changed, 31 insertions(+), 33 deletions(-) diff --git a/cmd/Kconfig b/cmd/Kconfig index 842afa2f390..9cafeb5d07c 100644 --- a/cmd/Kconfig +++ b/cmd/Kconfig @@ -723,6 +723,7 @@ config CMD_EDITENV config CMD_GREPENV bool "search env" + select GETOPT help Allow for searching environment variables diff --git a/cmd/nvedit.c b/cmd/nvedit.c index 95d53ba5c32..2af6e9dc03e 100644 --- a/cmd/nvedit.c +++ b/cmd/nvedit.c @@ -129,49 +129,46 @@ static int do_env_print(struct cmd_tbl *cmdtp, int flag, int argc, } #ifdef CONFIG_CMD_GREPENV -static int do_env_grep(struct cmd_tbl *cmdtp, int flag, - int argc, char *const argv[]) +static int do_env_grep(struct getopt_state *gs) { + const char *optstring = IS_ENABLED(CONFIG_REGEX) ? "+envb" : "+nvb"; char *res = NULL; int len, grep_how, grep_what; - - if (argc < 2) - return CMD_RET_USAGE; + int argc; + char *const *argv; + int opt; grep_how = H_MATCH_SUBSTR; /* default: substring search */ grep_what = H_MATCH_BOTH; /* default: grep names and values */ - while (--argc > 0 && **++argv == '-') { - char *arg = *argv; - while (*++arg) { - switch (*arg) { -#ifdef CONFIG_REGEX - case 'e': /* use regex matching */ + while ((opt = getopt(gs, optstring)) > 0) { + switch (opt) { + case 'e': /* use regex matching */ + if (IS_ENABLED(CONFIG_REGEX)) grep_how = H_MATCH_REGEX; - break; -#endif - case 'n': /* grep for name */ - grep_what = H_MATCH_KEY; - break; - case 'v': /* grep for value */ - grep_what = H_MATCH_DATA; - break; - case 'b': /* grep for both */ - grep_what = H_MATCH_BOTH; - break; - case '-': - goto DONE; - default: - return CMD_RET_USAGE; - } + break; + case 'n': /* grep for name */ + grep_what = H_MATCH_KEY; + break; + case 'v': /* grep for value */ + grep_what = H_MATCH_DATA; + break; + case 'b': /* grep for both */ + grep_what = H_MATCH_BOTH; + break; + default: + return CMD_RET_USAGE; } } -DONE: - len = hexport_r(&env_htab, '\n', - flag | grep_what | grep_how, - &res, 0, argc, argv); + argc = gs->argc - gs->index; + argv = &gs->argv[gs->index]; + if (argc < 1) + return CMD_RET_USAGE; + + len = hexport_r(&env_htab, '\n', grep_what | grep_how, &res, 0, + argc, argv); if (len > 0) { puts(res); free(res); @@ -1077,7 +1074,7 @@ static struct cmd_tbl cmd_env_sub[] = { U_BOOT_CMD_MKENT_GETOPT(export, 4, 0, do_env_export, "", ""), #endif #if defined(CONFIG_CMD_GREPENV) - U_BOOT_CMD_MKENT(grep, CONFIG_SYS_MAXARGS, 1, do_env_grep, "", ""), + U_BOOT_CMD_MKENT_GETOPT(grep, CONFIG_SYS_MAXARGS, 0, do_env_grep, "", ""), #endif #if defined(CONFIG_CMD_IMPORTENV) U_BOOT_CMD_MKENT_GETOPT(import, 5, 0, do_env_import, "", ""), @@ -1232,7 +1229,7 @@ U_BOOT_CMD_COMPLETE( ); #ifdef CONFIG_CMD_GREPENV -U_BOOT_CMD_COMPLETE( +U_BOOT_CMD_GETOPT_COMPLETE( grepenv, CONFIG_SYS_MAXARGS, 0, do_env_grep, "search environment variables", #ifdef CONFIG_REGEX -- 2.43.0

