[RFC PATCH 11/11] doc: commands: Recommend getopt() for option parsing
Simon Glass
sjg at chromium.org
Fri May 15 22:33:02 CEST 2026
The getopt() helper in <getopt.h> has been available since 2020 but
only two files in cmd/ actually use it; everything else hand-rolls
argv loops to detect -x style flags. New commands keep using ad-hoc
parsers because the developer guide for commands does not mention that
a shared helper exists.
Add a "Parsing options" section to the commands documentation with a
worked example.
Signed-off-by: Simon Glass <sjg at chromium.org>
---
doc/develop/commands.rst | 62 ++++++++++++++++++++++++++++++++++++++++
1 file changed, 62 insertions(+)
diff --git a/doc/develop/commands.rst b/doc/develop/commands.rst
index 77a7a4d9c02..a1f0b59501d 100644
--- a/doc/develop/commands.rst
+++ b/doc/develop/commands.rst
@@ -118,6 +118,68 @@ CMD_RET_USAGE
The command was called with invalid parameters. This value
leads to the display of the usage string.
+Parsing options
+---------------
+
+Commands that take options (``-x``, ``-f file``, etc.) should use the
+getopt() helper in ``<getopt.h>`` rather than walking ``argv`` by hand. This
+keeps option handling consistent across commands, supports grouped flags
+(``-abc``) and arguments attached either to the option (``-ffile``) or in
+the next argv entry (``-f file``), and produces sensible errors for unknown
+or incomplete options.
+
+A typical use looks like:
+
+.. code-block:: c
+
+ #include <getopt.h>
+
+ static int do_foo(struct cmd_tbl *cmdtp, int flag, int argc,
+ char *const argv[])
+ {
+ struct getopt_state gs;
+ const char *file = NULL;
+ bool verbose = false;
+ int opt;
+
+ getopt_init_state(&gs);
+ while ((opt = getopt(&gs, argc, argv, "vf:")) > 0) {
+ switch (opt) {
+ case 'v':
+ verbose = true;
+ break;
+ case 'f':
+ file = gs.arg;
+ break;
+ default:
+ return CMD_RET_USAGE;
+ }
+ }
+
+ /* Positional arguments start at gs.index */
+ if (gs.index >= argc)
+ return CMD_RET_USAGE;
+
+ return do_the_work(file, verbose, argv[gs.index]);
+ }
+
+A few points worth noting:
+
+* Each command owns a ``struct getopt_state`` on the stack, so getopt() is
+ reentrant. There are no globals like ``optind`` or ``optarg``; the next
+ unparsed argument is at ``gs.index`` and the option argument (when one is
+ expected) is in ``gs.arg``.
+* In the option string, ``x`` is a flag, ``x:`` requires an argument, and
+ ``x::`` takes an optional argument.
+* Unlike POSIX getopt(), this implementation does **not** reorder ``argv``,
+ so options must appear before positional arguments.
+* Returning ``CMD_RET_USAGE`` from the ``default`` case prints the command's
+ usage string for free; there is no need to call ``cmd_usage()`` directly.
+* Use getopt_silent() if the command should suppress the built-in error
+ messages and report problems itself.
+
+For the full API, see :doc:`../api/getopt`.
+
Completion function
-------------------
--
2.43.0
More information about the U-Boot
mailing list