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.
Showing the changes to scripts (1 of 1 file). Show all
Unified · Split
| @@ -37,7 +37,7 @@ enum input_mode { · 36 unmodified lines | ||
| 37 | 37 | mod2yesconfig, |
| 38 | 38 | }; |
| 39 | 39 | static enum input_mode input_mode = oldaskconfig; |
| 40 | − | |
| 40 | +static int input_mode_opt; | |
| 41 | 41 | static int indent = 1; |
| 42 | 42 | static int tty_stdio; |
| 43 | 43 | static int sync_kconfig; |
| @@ -474,21 +474,21 @@ static void check_conf(struct menu *menu) · 430 unmodified lines | ||
| 474 | 474 | } |
| 475 | 475 | |
| 476 | 476 | static struct option long_opts[] = { |
| 477 | − {"oldaskconfig", no_argument, NULL, oldaskconfig}, | |
| 478 | − {"oldconfig", no_argument, NULL, oldconfig}, | |
| 479 | − {"syncconfig", no_argument, NULL, syncconfig}, | |
| 480 | − {"defconfig", required_argument, NULL, defconfig}, | |
| 481 | − {"savedefconfig", required_argument, NULL, savedefconfig}, | |
| 482 | − {"allnoconfig", no_argument, NULL, allnoconfig}, | |
| 483 | − {"allyesconfig", no_argument, NULL, allyesconfig}, | |
| 484 | − {"allmodconfig", no_argument, NULL, allmodconfig}, | |
| 485 | − {"alldefconfig", no_argument, NULL, alldefconfig}, | |
| 486 | − {"randconfig", no_argument, NULL, randconfig}, | |
| 487 | − {"listnewconfig", no_argument, NULL, listnewconfig}, | |
| 488 | − {"helpnewconfig", no_argument, NULL, helpnewconfig}, | |
| 489 | − {"olddefconfig", no_argument, NULL, olddefconfig}, | |
| 490 | − {"yes2modconfig", no_argument, NULL, yes2modconfig}, | |
| 491 | − {"mod2yesconfig", no_argument, NULL, mod2yesconfig}, | |
| 477 | + {"oldaskconfig", no_argument, &input_mode_opt, oldaskconfig}, | |
| 478 | + {"oldconfig", no_argument, &input_mode_opt, oldconfig}, | |
| 479 | + {"syncconfig", no_argument, &input_mode_opt, syncconfig}, | |
| 480 | + {"defconfig", required_argument, &input_mode_opt, defconfig}, | |
| 481 | + {"savedefconfig", required_argument, &input_mode_opt, savedefconfig}, | |
| 482 | + {"allnoconfig", no_argument, &input_mode_opt, allnoconfig}, | |
| 483 | + {"allyesconfig", no_argument, &input_mode_opt, allyesconfig}, | |
| 484 | + {"allmodconfig", no_argument, &input_mode_opt, allmodconfig}, | |
| 485 | + {"alldefconfig", no_argument, &input_mode_opt, alldefconfig}, | |
| 486 | + {"randconfig", no_argument, &input_mode_opt, randconfig}, | |
| 487 | + {"listnewconfig", no_argument, &input_mode_opt, listnewconfig}, | |
| 488 | + {"helpnewconfig", no_argument, &input_mode_opt, helpnewconfig}, | |
| 489 | + {"olddefconfig", no_argument, &input_mode_opt, olddefconfig}, | |
| 490 | + {"yes2modconfig", no_argument, &input_mode_opt, yes2modconfig}, | |
| 491 | + {"mod2yesconfig", no_argument, &input_mode_opt, mod2yesconfig}, | |
| 492 | 492 | {NULL, 0, NULL, 0} |
| 493 | 493 | }; |
| 494 | 494 | |
| @@ -526,43 +526,38 @@ int main(int ac, char **av) · 31 unmodified lines | ||
| 526 | 526 | tty_stdio = isatty(0) && isatty(1); |
| 527 | 527 | |
| 528 | 528 | while ((opt = getopt_long(ac, av, "hs", long_opts, NULL)) != -1) { |
| 529 | − if (opt == 's') { | |
| 530 | − conf_set_message_callback(NULL); | |
| 531 | − continue; | |
| 532 | − } | |
| 533 | − input_mode = (enum input_mode)opt; | |
| 534 | 529 | switch (opt) { |
| 535 | − case syncconfig: | |
| 536 | − /* | |
| 537 | − * syncconfig is invoked during the build stage. | |
| 538 | − * Suppress distracting "configuration written to ..." | |
| 539 | − */ | |
| 540 | − conf_set_message_callback(NULL); | |
| 541 | − sync_kconfig = 1; | |
| 542 | − break; | |
| 543 | − case defconfig: | |
| 544 | − case savedefconfig: | |
| 545 | − defconfig_file = optarg; | |
| 546 | − break; | |
| 547 | − case randconfig: | |
| 548 | − set_randconfig_seed(); | |
| 549 | − break; | |
| 550 | − case oldaskconfig: | |
| 551 | − case oldconfig: | |
| 552 | − case allnoconfig: | |
| 553 | − case allyesconfig: | |
| 554 | − case allmodconfig: | |
| 555 | − case alldefconfig: | |
| 556 | − case listnewconfig: | |
| 557 | − case helpnewconfig: | |
| 558 | − case olddefconfig: | |
| 559 | − case yes2modconfig: | |
| 560 | − case mod2yesconfig: | |
| 561 | − break; | |
| 562 | 530 | case 'h': |
| 563 | 531 | conf_usage(progname); |
| 564 | 532 | exit(1); |
| 565 | 533 | break; |
| 534 | + case 's': | |
| 535 | + conf_set_message_callback(NULL); | |
| 536 | + break; | |
| 537 | + case 0: | |
| 538 | + input_mode = input_mode_opt; | |
| 539 | + switch (input_mode) { | |
| 540 | + case syncconfig: | |
| 541 | + /* | |
| 542 | + * syncconfig is invoked during the build stage. | |
| 543 | + * Suppress distracting | |
| 544 | + * "configuration written to ..." | |
| 545 | + */ | |
| 546 | + conf_set_message_callback(NULL); | |
| 547 | + sync_kconfig = 1; | |
| 548 | + break; | |
| 549 | + case defconfig: | |
| 550 | + case savedefconfig: | |
| 551 | + defconfig_file = optarg; | |
| 552 | + break; | |
| 553 | + case randconfig: | |
| 554 | + set_randconfig_seed(); | |
| 555 | + break; | |
| 556 | + default: | |
| 557 | + break; | |
| 558 | + } | |
| 559 | + default: | |
| 560 | + break; | |
| 566 | 561 | } |
| 567 | 562 | } |
| 568 | 563 | if (ac == optind) { |