[PATCH v4 09/14] cmd: hash: Use getopt() for option parsing

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


The open-coded check for -v only matches it as the first argument and
duplicates the argument-shuffling logic that every option-parsing
command repeats. Convert do_hash() to the getopt-state command
signature and parse -v with getopt().

Build the optstring from IS_ENABLED(CONFIG_HASH_VERIFY) so getopt() is
always called, and prefix it with '+' so it works in POSIX mode and
stops at the first non-option. -v therefore stays a leading option
('hash -v algorithm address count'), matching the documented usage and
the existing tests, and no argv permutation is needed. After parsing,
require three positionals (algorithm address count), strlower() the
algorithm and forward the tail to hash_command() unchanged.

CMD_HASH selects only GETOPT. With this, no in-tree command selects
GETOPT_PERMUTE, so the permute machinery (the writable argv copy and
nonopts tracking) stays compiled out of a default image, which drops
about 2 KB of text. GETOPT_PERMUTE remains available as an opt-in for
commands that genuinely need options after positionals.

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

Changes in v4:
- Make hash parse in POSIX mode so nothing selects GETOPT_PERMUTE

 cmd/Kconfig |  1 +
 cmd/hash.c  | 42 +++++++++++++++++++++++-------------------
 2 files changed, 24 insertions(+), 19 deletions(-)

diff --git a/cmd/Kconfig b/cmd/Kconfig
index ca1039f6a03..3c5abddd31f 100644
--- a/cmd/Kconfig
+++ b/cmd/Kconfig
@@ -2804,6 +2804,7 @@ config CMD_BLOB
 
 config CMD_HASH
 	bool "Support 'hash' command"
+	select GETOPT
 	select HASH
 	help
 	  This provides a way to hash data in memory using various supported
diff --git a/cmd/hash.c b/cmd/hash.c
index f4f1dcf02f9..929759ce45b 100644
--- a/cmd/hash.c
+++ b/cmd/hash.c
@@ -11,8 +11,9 @@
 
 #include <command.h>
 #include <env.h>
+#include <getopt.h>
 #include <hash.h>
-#include <linux/ctype.h>
+#include <linux/string.h>
 
 #if IS_ENABLED(CONFIG_HASH_VERIFY)
 #define HARGS 6
@@ -20,31 +21,34 @@
 #define HARGS 5
 #endif
 
-static int do_hash(struct cmd_tbl *cmdtp, int flag, int argc,
-		   char *const argv[])
+static int do_hash(struct getopt_state *gs)
 {
-	char *s;
+	const char *optstring = IS_ENABLED(CONFIG_HASH_VERIFY) ? "+v" : "+";
 	int flags = HASH_FLAG_ENV;
+	char *algo;
+	int opt;
 
-	if (argc < 4)
+	while ((opt = getopt(gs, optstring)) > 0) {
+		switch (opt) {
+		case 'v':
+			flags |= HASH_FLAG_VERIFY;
+			break;
+		default:
+			return CMD_RET_USAGE;
+		}
+	}
+
+	/* Need at least: algorithm address count */
+	if (gs->argc - gs->index < 3)
 		return CMD_RET_USAGE;
 
-#if IS_ENABLED(CONFIG_HASH_VERIFY)
-	if (!strcmp(argv[1], "-v")) {
-		flags |= HASH_FLAG_VERIFY;
-		argc--;
-		argv++;
-	}
-#endif
-	/* Move forward to 'algorithm' parameter */
-	argc--;
-	argv++;
-	for (s = *argv; *s; s++)
-		*s = tolower(*s);
-	return hash_command(*argv, flags, argc - 1, argv + 1);
+	algo = strlower(getopt_pop(gs));
+
+	return hash_command(algo, flags, gs->argc - gs->index,
+			    &gs->argv[gs->index]);
 }
 
-U_BOOT_CMD(
+U_BOOT_CMD_GETOPT(
 	hash,	HARGS,	1,	do_hash,
 	"compute hash message digest",
 	"algorithm address count [[*]hash_dest]\n"
-- 
2.43.0



More information about the U-Boot mailing list