[PATCH v4 00/14] cmd: Convert command option parsing to getopt()
Simon Glass
sjg at chromium.org
Wed Jul 1 13:42:20 CEST 2026
Most U-Boot commands open-code their option parsing, scanning argv[] for
"-x" strings by hand. That only recognises options in fixed positions
(so e.g. 'echo foo -n' misbehaves) and duplicates the same code in
every command.
This series introduces a getopt-based command signature: a command
marked CMDF_GETOPT receives a single 'struct getopt_state *' and parses
options with getopt(), while commands without the flag keep the classic
(cmdtp, flag, argc, argv) signature, so commands move over one at a
time.
It starts with the getopt groundwork - optional argv permutation, a
getopt_pop() helper, dropping the printed error messages and the silent
variant - then adds the U_BOOT_CMD_GETOPT() signature support and a
strlower() helper, and converts the first commands: hash, env
export/import/grep, fastboot and echo.
The signature change itself is code-size-neutral; commands parse in
POSIX mode (a '+' optstring prefix), so CONFIG_GETOPT_PERMUTE - which
would make every getopt command carry a writable argv copy - stays off
by default and is kept only as an opt-in.
The earlier RFCs grew arm64 by about 1.1K, not ideal for a series that
mainly benefits readability. To fix that, this series also restructures
struct cmd_tbl so that adding getopt() support does not cost size: the
rarely-useful ->cmd_rep function pointer is replaced by a
CMDF_REPEATABLE flag, dropping a pointer from every command entry.
Because that pointer is removed from every command on every board, the
net result is now a size reduction. On qcom (arm64, ~120 commands) the
whole series is about 6.9K smaller than mainline.
Previous attempts:
v3 just had a simple convert for env input/export
https://lore.kernel.org/u-boot/20260520201218.3752042-1-sjg@chromium.org/
v2 included the full series
https://lore.kernel.org/u-boot/20260520000630.GJ1858239@bill-the-cat/
v1 started the effort
https://lore.kernel.org/u-boot/CAFLszTiSxcKyD1MWP+2p2zBbDzLoC5Z=wnxVNHO31DGQHCrLcA@mail.gmail.com/
Changes in v4:
- Add a Kconfig to control permuting
- Reword the commit message a little
- Fix the getopt_silent() kernel-doc and the bdinfo help test
- Add new patch to narrow maxargs to a short, freeing space in
struct cmd_tbl for the flags byte
- Guard cmd_invoke() with CONFIG_IS_ENABLED(GETOPT) so boards without
GETOPT still link
- Add new patch to replace the ->cmd_rep pointer with a
CMDF_REPEATABLE flag, dropping a pointer from every command entry
- Make hash parse in POSIX mode so nothing selects GETOPT_PERMUTE
- Update commit message to mention himport_r()
- Add new patch to convert fastboot
- Rebased on us/next
Changes in v2:
- Use "permute" terminology in docs and comments
- Move the working argv array to the top of struct getopt_state and
rename it from @args to @argv (drops inter-field padding too)
- Refine kerneldoc for @index
- Restore the original worked example in getopt()'s kerneldoc
- Add tests for permuted argv, a required argument missing after a
leading non-option, and the '+' prefix
- Redo the sep_err logic to reduce code size
Simon Glass (14):
lib: getopt: Add optional argv permutation with inline reorder
lib: getopt: Add getopt_pop() helper
lib: getopt: Drop printed error messages and the silent variant
command: Narrow cmd_tbl.maxargs to a short
command: Support a getopt-based command signature
command: Replace the cmd_rep pointer with a CMDF_REPEATABLE flag
hash: Drop unused cmdtp and flag args from hash_command()
lib: string: Add strlower()
cmd: hash: Use getopt() for option parsing
cmd: nvedit: Use getopt() in env export
cmd: nvedit: Use getopt() in env import
cmd: nvedit: Use getopt() in env grep
cmd: fastboot: Use getopt() for option parsing
cmd: echo: Use getopt() for option parsing
cmd/Kconfig | 6 ++
cmd/bdinfo.c | 4 +-
cmd/echo.c | 26 ++---
cmd/fastboot.c | 48 +++++-----
cmd/hash.c | 42 +++++----
cmd/help.c | 2 +-
cmd/log.c | 12 +--
cmd/md5sum.c | 2 +-
cmd/mem.c | 2 +-
cmd/nvedit.c | 210 ++++++++++++++++++++---------------------
cmd/sha1sum.c | 2 +-
cmd/sm3sum.c | 2 +-
cmd/sound.c | 4 +-
cmd/test.c | 2 +-
cmd/x86/zboot.c | 2 +-
common/command.c | 46 ++++-----
common/hash.c | 4 +-
include/command.h | 167 +++++++++++++++++++++++---------
include/getopt.h | 116 ++++++++++++++++-------
include/hash.h | 6 +-
include/linux/string.h | 12 +++
lib/Kconfig | 17 ++++
lib/getopt.c | 93 ++++++++++++++----
lib/string.c | 10 ++
test/cmd/bdinfo.c | 1 -
test/cmd/test_echo.c | 7 ++
test/lib/getopt.c | 54 ++++++++++-
test/lib/string.c | 27 ++++++
28 files changed, 614 insertions(+), 312 deletions(-)
---
base-commit: 5602e89a834ccbedc686053b14206c062a144107
branch: clid-us4
--
2.43.0
More information about the U-Boot
mailing list