kconfig: refactor option parse code
authorMasahiro Yamada <masahiroy@kernel.org>
Sat, 13 Mar 2021 19:48:25 +0000 (04:48 +0900)
committerMasahiro Yamada <masahiroy@kernel.org>
Thu, 25 Mar 2021 04:34:37 +0000 (13:34 +0900)
The current option parse code is clumsy.

The 's' option is separately handled in an if-conditional due to the
following code:

    input_mode = (enum input_mode)opt;

If 's' is moved to the switch statement, the invalid value 's' would
be assigned to the input_mode.

Another potential problem is that we are mixing 'enum input_mode' and
ASCII characters. They could overwrap if we add more input modes.

To separate them out, set the flag field of long options to a pointer
of input_mode_opt. For mode select options, getopt_long() returns 0,
which never causes overwrap with ASCII characters that represent short
options.

Signed-off-by: Masahiro Yamada <masahiroy@kernel.org>
scripts/kconfig/conf.c

index 063c9e7..dc1a67f 100644 (file)
@@ -37,7 +37,7 @@ enum input_mode {
        mod2yesconfig,
 };
 static enum input_mode input_mode = oldaskconfig;
-
+static int input_mode_opt;
 static int indent = 1;
 static int tty_stdio;
 static int sync_kconfig;
@@ -474,21 +474,21 @@ static void check_conf(struct menu *menu)
 }
 
 static struct option long_opts[] = {
-       {"oldaskconfig",    no_argument,       NULL, oldaskconfig},
-       {"oldconfig",       no_argument,       NULL, oldconfig},
-       {"syncconfig",      no_argument,       NULL, syncconfig},
-       {"defconfig",       required_argument, NULL, defconfig},
-       {"savedefconfig",   required_argument, NULL, savedefconfig},
-       {"allnoconfig",     no_argument,       NULL, allnoconfig},
-       {"allyesconfig",    no_argument,       NULL, allyesconfig},
-       {"allmodconfig",    no_argument,       NULL, allmodconfig},
-       {"alldefconfig",    no_argument,       NULL, alldefconfig},
-       {"randconfig",      no_argument,       NULL, randconfig},
-       {"listnewconfig",   no_argument,       NULL, listnewconfig},
-       {"helpnewconfig",   no_argument,       NULL, helpnewconfig},
-       {"olddefconfig",    no_argument,       NULL, olddefconfig},
-       {"yes2modconfig",   no_argument,       NULL, yes2modconfig},
-       {"mod2yesconfig",   no_argument,       NULL, mod2yesconfig},
+       {"oldaskconfig",  no_argument,       &input_mode_opt, oldaskconfig},
+       {"oldconfig",     no_argument,       &input_mode_opt, oldconfig},
+       {"syncconfig",    no_argument,       &input_mode_opt, syncconfig},
+       {"defconfig",     required_argument, &input_mode_opt, defconfig},
+       {"savedefconfig", required_argument, &input_mode_opt, savedefconfig},
+       {"allnoconfig",   no_argument,       &input_mode_opt, allnoconfig},
+       {"allyesconfig",  no_argument,       &input_mode_opt, allyesconfig},
+       {"allmodconfig",  no_argument,       &input_mode_opt, allmodconfig},
+       {"alldefconfig",  no_argument,       &input_mode_opt, alldefconfig},
+       {"randconfig",    no_argument,       &input_mode_opt, randconfig},
+       {"listnewconfig", no_argument,       &input_mode_opt, listnewconfig},
+       {"helpnewconfig", no_argument,       &input_mode_opt, helpnewconfig},
+       {"olddefconfig",  no_argument,       &input_mode_opt, olddefconfig},
+       {"yes2modconfig", no_argument,       &input_mode_opt, yes2modconfig},
+       {"mod2yesconfig", no_argument,       &input_mode_opt, mod2yesconfig},
        {NULL, 0, NULL, 0}
 };
 
@@ -526,43 +526,38 @@ int main(int ac, char **av)
        tty_stdio = isatty(0) && isatty(1);
 
        while ((opt = getopt_long(ac, av, "hs", long_opts, NULL)) != -1) {
-               if (opt == 's') {
-                       conf_set_message_callback(NULL);
-                       continue;
-               }
-               input_mode = (enum input_mode)opt;
                switch (opt) {
-               case syncconfig:
-                       /*
-                        * syncconfig is invoked during the build stage.
-                        * Suppress distracting "configuration written to ..."
-                        */
-                       conf_set_message_callback(NULL);
-                       sync_kconfig = 1;
-                       break;
-               case defconfig:
-               case savedefconfig:
-                       defconfig_file = optarg;
-                       break;
-               case randconfig:
-                       set_randconfig_seed();
-                       break;
-               case oldaskconfig:
-               case oldconfig:
-               case allnoconfig:
-               case allyesconfig:
-               case allmodconfig:
-               case alldefconfig:
-               case listnewconfig:
-               case helpnewconfig:
-               case olddefconfig:
-               case yes2modconfig:
-               case mod2yesconfig:
-                       break;
                case 'h':
                        conf_usage(progname);
                        exit(1);
                        break;
+               case 's':
+                       conf_set_message_callback(NULL);
+                       break;
+               case 0:
+                       input_mode = input_mode_opt;
+                       switch (input_mode) {
+                       case syncconfig:
+                               /*
+                                * syncconfig is invoked during the build stage.
+                                * Suppress distracting
+                                *   "configuration written to ..."
+                                */
+                               conf_set_message_callback(NULL);
+                               sync_kconfig = 1;
+                               break;
+                       case defconfig:
+                       case savedefconfig:
+                               defconfig_file = optarg;
+                               break;
+                       case randconfig:
+                               set_randconfig_seed();
+                               break;
+                       default:
+                               break;
+                       }
+               default:
+                       break;
                }
        }
        if (ac == optind) {