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 <[email protected]> --- (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

