The '--' termination test, the non-option bubble loop and the
'out of options' check are all guarded by gs->arg_index == 1: they
make sense only when we are at the start of a fresh argv[] element.
The current code repeats the guard on each one.

Pull the three out under a single 'if (gs->arg_index == 1)' so the
condition is evaluated once per outer-loop iteration. No functional
change; the compiler produces fewer compare-and-branch sequences.

Signed-off-by: Simon Glass <[email protected]>
---

(no changes since v1)

 lib/getopt.c | 55 ++++++++++++++++++++++++++--------------------------
 1 file changed, 28 insertions(+), 27 deletions(-)

diff --git a/lib/getopt.c b/lib/getopt.c
index b3ad6968f8d..d2ccefc616e 100644
--- a/lib/getopt.c
+++ b/lib/getopt.c
@@ -44,38 +44,39 @@ int getopt(struct getopt_state *gs, const char *optstring)
                log_debug("arg_index: %d index: %d nonopts: %d\n",
                          gs->arg_index, gs->index, gs->nonopts);
 
-               /* `--` indicates the end of options */
-               if (gs->arg_index == 1 && gs->index < argc &&
-                   !strcmp(argv[gs->index], "--")) {
-                       gs->index++;
-                       return -1;
-               }
-
-               /*
-                * Permute non-options to the end so we can keep scanning
-                * for options past them. In '+' mode (POSIX), stop at the
-                * first non-option instead.
-                */
-               while (gs->arg_index == 1 &&
-                      gs->index + gs->nonopts < argc) {
+               if (gs->arg_index == 1) {
                        char *cur = argv[gs->index];
-                       int i;
 
-                       if (*cur == '-')
-                               break;
-                       if (stop_nonopt)
+                       /* `--` indicates the end of options */
+                       if (gs->index < argc && !strcmp(cur, "--")) {
+                               gs->index++;
+                               return -1;
+                       }
+
+                       /*
+                        * Permute non-options to the end so we can keep
+                        * scanning for options past them. In '+' mode
+                        * (POSIX), stop at the first non-option instead.
+                        */
+                       while (gs->index + gs->nonopts < argc) {
+                               int i;
+
+                               if (*cur == '-')
+                                       break;
+                               if (stop_nonopt)
+                                       return -1;
+
+                               gs->nonopts++;
+                               for (i = gs->index; i + 1 < argc; i++)
+                                       argv[i] = argv[i + 1];
+                               argv[argc - 1] = cur;
+                               cur = argv[gs->index];
+                       }
+
+                       if (gs->index + gs->nonopts >= argc)
                                return -1;
-
-                       gs->nonopts++;
-                       for (i = gs->index; i + 1 < argc; i++)
-                               argv[i] = argv[i + 1];
-                       argv[argc - 1] = cur;
                }
 
-               /* Out of options to scan */
-               if (gs->index + gs->nonopts >= argc)
-                       return -1;
-
                /* We have found an option */
                curopt = argv[gs->index][gs->arg_index];
                if (curopt)
-- 
2.43.0

Reply via email to