[RFC PATCH v2 14/17] lib: getopt: Merge the optional and required-argument branches
Simon Glass
sjg at chromium.org
Wed May 20 01:31:40 CEST 2026
Both branches start with the same 'argument in same argv[] element'
test and the same advance-to-next-element bookkeeping; only the
behaviour when the argument is missing differs. Fold them into one
sequence and decide between ':' (required) and gs->arg=NULL
(optional) at the single missing-argument point.
The four cases of the original optional-argument block (in-element
arg, last-element-no-arg, next-element-arg, next-element-dash) all
collapse onto the same code path used by the required-argument
branch, with the curoptp[2] check determining only the error vs
optional-absent outcome.
Saves about 80 bytes on sandbox, similar on arm64. No functional
change; the lib_test_getopt unit tests still pass.
Signed-off-by: Simon Glass <sjg at chromium.org>
---
(no changes since v1)
lib/getopt.c | 49 ++++++++++++++-----------------------------------
1 file changed, 14 insertions(+), 35 deletions(-)
diff --git a/lib/getopt.c b/lib/getopt.c
index 5e907477e57..b3ad6968f8d 100644
--- a/lib/getopt.c
+++ b/lib/getopt.c
@@ -97,46 +97,19 @@ int getopt(struct getopt_state *gs, const char *optstring)
return '?';
}
- if (*(curoptp + 1) != ':') {
+ if (curoptp[1] != ':') {
/* option with no argument. Just return it */
gs->arg = NULL;
gs->arg_index++;
return curopt;
}
- if (curoptp[2] == ':') {
- /* optional argument */
- if (argv[gs->index][gs->arg_index + 1]) {
- /* optional argument with directly following arg */
- gs->arg = argv[gs->index++] + gs->arg_index + 1;
- gs->arg_index = 1;
- return curopt;
- }
- if (gs->index + gs->nonopts + 1 == argc) {
- /* We are at the last argv[] element */
- gs->arg = NULL;
- gs->index++;
- return curopt;
- }
- if (*argv[gs->index + 1] != '-') {
- /*
- * optional argument with arg in next argv[] element
- */
- gs->index++;
- gs->arg = argv[gs->index++];
- gs->arg_index = 1;
- return curopt;
- }
-
- /* no optional argument found */
- gs->arg = NULL;
- gs->arg_index = 1;
- gs->index++;
- return curopt;
- }
-
+ /*
+ * Option takes an argument. The argument may be in the same argv[]
+ * element (``-fXXX``) or in the next one (``-f XXX``); a ``::`` in
+ * optstring marks the argument optional.
+ */
if (argv[gs->index][gs->arg_index + 1]) {
- /* required argument with directly following arg */
gs->arg = argv[gs->index++] + gs->arg_index + 1;
gs->arg_index = 1;
return curopt;
@@ -146,8 +119,14 @@ int getopt(struct getopt_state *gs, const char *optstring)
gs->arg_index = 1;
if (gs->index + gs->nonopts >= argc || argv[gs->index][0] == '-') {
- gs->opt = curopt;
- return ':';
+ if (curoptp[2] != ':') {
+ /* required argument is missing */
+ gs->opt = curopt;
+ return ':';
+ }
+ /* optional argument absent */
+ gs->arg = NULL;
+ return curopt;
}
gs->arg = argv[gs->index++];
--
2.43.0
More information about the U-Boot
mailing list