Commit ac0060ac38ecf4fa380f49fd1e40ebaabb479596
1 parent
1c420e85
Refactor arg parsing to allow help option with parameter
Showing
1 changed file
with
67 additions
and
89 deletions
qpdf/qpdf.cc
| ... | ... | @@ -926,7 +926,6 @@ class ArgParser |
| 926 | 926 | void usage(std::string const& message); |
| 927 | 927 | void checkCompletion(); |
| 928 | 928 | void initOptionTable(); |
| 929 | - void handleHelpArgs(); | |
| 930 | 929 | void handleArgFileArguments(); |
| 931 | 930 | void handleBashArguments(); |
| 932 | 931 | void readArgsFromFile(char const* filename); |
| ... | ... | @@ -3412,37 +3411,6 @@ ArgParser::readArgsFromFile(char const* filename) |
| 3412 | 3411 | } |
| 3413 | 3412 | |
| 3414 | 3413 | void |
| 3415 | -ArgParser::handleHelpArgs() | |
| 3416 | -{ | |
| 3417 | - // Handle special-case informational options that are only | |
| 3418 | - // available as the sole option. | |
| 3419 | - | |
| 3420 | - if (argc != 2) | |
| 3421 | - { | |
| 3422 | - return; | |
| 3423 | - } | |
| 3424 | - char* arg = argv[1]; | |
| 3425 | - if (*arg != '-') | |
| 3426 | - { | |
| 3427 | - return; | |
| 3428 | - } | |
| 3429 | - ++arg; | |
| 3430 | - if (*arg == '-') | |
| 3431 | - { | |
| 3432 | - ++arg; | |
| 3433 | - } | |
| 3434 | - if (! *arg) | |
| 3435 | - { | |
| 3436 | - return; | |
| 3437 | - } | |
| 3438 | - if (this->help_option_table.count(arg)) | |
| 3439 | - { | |
| 3440 | - (this->*(this->help_option_table[arg].bare_arg_handler))(); | |
| 3441 | - exit(0); | |
| 3442 | - } | |
| 3443 | -} | |
| 3444 | - | |
| 3445 | -void | |
| 3446 | 3414 | ArgParser::parseRotationParameter(std::string const& parameter) |
| 3447 | 3415 | { |
| 3448 | 3416 | std::string angle_str; |
| ... | ... | @@ -3601,22 +3569,23 @@ void |
| 3601 | 3569 | ArgParser::parseOptions() |
| 3602 | 3570 | { |
| 3603 | 3571 | checkCompletion(); |
| 3604 | - if (! this->bash_completion) | |
| 3605 | - { | |
| 3606 | - handleHelpArgs(); | |
| 3607 | - } | |
| 3608 | 3572 | handleArgFileArguments(); |
| 3609 | 3573 | for (cur_arg = 1; cur_arg < argc; ++cur_arg) |
| 3610 | 3574 | { |
| 3575 | + bool help_option = false; | |
| 3576 | + auto oep = this->option_table->end(); | |
| 3611 | 3577 | char* arg = argv[cur_arg]; |
| 3578 | + char* parameter = nullptr; | |
| 3579 | + std::string o_arg(arg); | |
| 3580 | + std::string arg_s(arg); | |
| 3612 | 3581 | if (strcmp(arg, "--") == 0) |
| 3613 | 3582 | { |
| 3614 | 3583 | // Special case for -- option, which is used to break out |
| 3615 | 3584 | // of subparsers. |
| 3616 | - OptionEntry& oe = (*this->option_table)["--"]; | |
| 3617 | - if (oe.bare_arg_handler) | |
| 3585 | + oep = this->option_table->find("--"); | |
| 3586 | + if (oep == this->option_table->end()) | |
| 3618 | 3587 | { |
| 3619 | - (this->*(oe.bare_arg_handler))(); | |
| 3588 | + throw std::logic_error("ArgParser: -- handler not registered"); | |
| 3620 | 3589 | } |
| 3621 | 3590 | } |
| 3622 | 3591 | else if ((arg[0] == '-') && (strcmp(arg, "-") != 0)) |
| ... | ... | @@ -3627,7 +3596,6 @@ ArgParser::parseOptions() |
| 3627 | 3596 | // Be lax about -arg vs --arg |
| 3628 | 3597 | ++arg; |
| 3629 | 3598 | } |
| 3630 | - char* parameter = 0; | |
| 3631 | 3599 | if (strlen(arg) > 0) |
| 3632 | 3600 | { |
| 3633 | 3601 | // Prevent --=something from being treated as an empty |
| ... | ... | @@ -3640,72 +3608,82 @@ ArgParser::parseOptions() |
| 3640 | 3608 | *parameter++ = 0; |
| 3641 | 3609 | } |
| 3642 | 3610 | |
| 3643 | - std::string arg_s(arg); | |
| 3644 | - if (arg_s.empty() || | |
| 3645 | - (arg_s.at(0) == '-') || | |
| 3646 | - (0 == this->option_table->count(arg_s))) | |
| 3611 | + arg_s = arg; | |
| 3612 | + if (! (arg_s.empty() || (arg_s.at(0) == '-'))) | |
| 3647 | 3613 | { |
| 3648 | - usage(std::string("unknown option --") + arg); | |
| 3614 | + oep = this->option_table->find(arg_s); | |
| 3649 | 3615 | } |
| 3650 | 3616 | |
| 3651 | - OptionEntry& oe = (*this->option_table)[arg_s]; | |
| 3652 | - if ((oe.parameter_needed && (0 == parameter)) || | |
| 3653 | - ((! oe.choices.empty() && | |
| 3654 | - ((0 == parameter) || | |
| 3655 | - (0 == oe.choices.count(parameter)))))) | |
| 3617 | + if ((! this->bash_completion) && | |
| 3618 | + (argc == 2) && (cur_arg == 1) && | |
| 3619 | + (oep == this->option_table->end())) | |
| 3656 | 3620 | { |
| 3657 | - std::string message = | |
| 3658 | - "--" + arg_s + " must be given as --" + arg_s + "="; | |
| 3659 | - if (! oe.choices.empty()) | |
| 3621 | + // Handle help option, which is only valid as the sole | |
| 3622 | + // option. | |
| 3623 | + oep = this->help_option_table.find(arg_s); | |
| 3624 | + help_option = true; | |
| 3625 | + } | |
| 3626 | + } | |
| 3627 | + else | |
| 3628 | + { | |
| 3629 | + // The empty string maps to the positional argument | |
| 3630 | + // handler. | |
| 3631 | + oep = this->option_table->find(""); | |
| 3632 | + parameter = arg; | |
| 3633 | + } | |
| 3634 | + | |
| 3635 | + if (oep == this->option_table->end()) | |
| 3636 | + { | |
| 3637 | + usage("unrecognized argument " + o_arg); | |
| 3638 | + } | |
| 3639 | + | |
| 3640 | + OptionEntry& oe = oep->second; | |
| 3641 | + if ((oe.parameter_needed && (0 == parameter)) || | |
| 3642 | + ((! oe.choices.empty() && | |
| 3643 | + ((0 == parameter) || | |
| 3644 | + (0 == oe.choices.count(parameter)))))) | |
| 3645 | + { | |
| 3646 | + std::string message = | |
| 3647 | + "--" + arg_s + " must be given as --" + arg_s + "="; | |
| 3648 | + if (! oe.choices.empty()) | |
| 3649 | + { | |
| 3650 | + QTC::TC("qpdf", "qpdf required choices"); | |
| 3651 | + message += "{"; | |
| 3652 | + for (std::set<std::string>::iterator iter = | |
| 3653 | + oe.choices.begin(); | |
| 3654 | + iter != oe.choices.end(); ++iter) | |
| 3660 | 3655 | { |
| 3661 | - QTC::TC("qpdf", "qpdf required choices"); | |
| 3662 | - message += "{"; | |
| 3663 | - for (std::set<std::string>::iterator iter = | |
| 3664 | - oe.choices.begin(); | |
| 3665 | - iter != oe.choices.end(); ++iter) | |
| 3656 | + if (iter != oe.choices.begin()) | |
| 3666 | 3657 | { |
| 3667 | - if (iter != oe.choices.begin()) | |
| 3668 | - { | |
| 3669 | - message += ","; | |
| 3670 | - } | |
| 3671 | - message += *iter; | |
| 3658 | + message += ","; | |
| 3672 | 3659 | } |
| 3673 | - message += "}"; | |
| 3674 | - } | |
| 3675 | - else if (! oe.parameter_name.empty()) | |
| 3676 | - { | |
| 3677 | - QTC::TC("qpdf", "qpdf required parameter"); | |
| 3678 | - message += oe.parameter_name; | |
| 3679 | - } | |
| 3680 | - else | |
| 3681 | - { | |
| 3682 | - // should not be possible | |
| 3683 | - message += "option"; | |
| 3660 | + message += *iter; | |
| 3684 | 3661 | } |
| 3685 | - usage(message); | |
| 3662 | + message += "}"; | |
| 3686 | 3663 | } |
| 3687 | - if (oe.bare_arg_handler) | |
| 3664 | + else if (! oe.parameter_name.empty()) | |
| 3688 | 3665 | { |
| 3689 | - (this->*(oe.bare_arg_handler))(); | |
| 3666 | + QTC::TC("qpdf", "qpdf required parameter"); | |
| 3667 | + message += oe.parameter_name; | |
| 3690 | 3668 | } |
| 3691 | - else if (oe.param_arg_handler) | |
| 3669 | + else | |
| 3692 | 3670 | { |
| 3693 | - (this->*(oe.param_arg_handler))(parameter); | |
| 3671 | + // should not be possible | |
| 3672 | + message += "option"; | |
| 3694 | 3673 | } |
| 3674 | + usage(message); | |
| 3695 | 3675 | } |
| 3696 | - else if (0 != this->option_table->count("")) | |
| 3676 | + if (oe.bare_arg_handler) | |
| 3697 | 3677 | { |
| 3698 | - // The empty string maps to the positional argument | |
| 3699 | - // handler. | |
| 3700 | - OptionEntry& oe = (*this->option_table)[""]; | |
| 3701 | - if (oe.param_arg_handler) | |
| 3702 | - { | |
| 3703 | - (this->*(oe.param_arg_handler))(arg); | |
| 3704 | - } | |
| 3678 | + (this->*(oe.bare_arg_handler))(); | |
| 3705 | 3679 | } |
| 3706 | - else | |
| 3680 | + else if (oe.param_arg_handler) | |
| 3681 | + { | |
| 3682 | + (this->*(oe.param_arg_handler))(parameter); | |
| 3683 | + } | |
| 3684 | + if (help_option) | |
| 3707 | 3685 | { |
| 3708 | - usage(std::string("unknown argument ") + arg); | |
| 3686 | + exit(0); | |
| 3709 | 3687 | } |
| 3710 | 3688 | } |
| 3711 | 3689 | if (this->bash_completion) | ... | ... |