Parse a short (false) or long (true) argument, must be at the top of the list return true if the argument was processed or false if nothing was done
| 7030 | /// Parse a short (false) or long (true) argument, must be at the top of the list |
| 7031 | /// return true if the argument was processed or false if nothing was done |
| 7032 | bool _parse_arg(std::vector<std::string> &args, detail::Classifier current_type) { |
| 7033 | std::string current = args.back(); |
| 7034 | |
| 7035 | std::string arg_name; |
| 7036 | std::string value; |
| 7037 | std::string rest; |
| 7038 | |
| 7039 | switch (current_type) { |
| 7040 | case detail::Classifier::LONG: |
| 7041 | if (!detail::split_long(current, arg_name, value)) |
| 7042 | throw HorribleError("Long parsed but missing (you should not see this):" + args.back()); |
| 7043 | break; |
| 7044 | case detail::Classifier::SHORT: |
| 7045 | if (!detail::split_short(current, arg_name, rest)) |
| 7046 | throw HorribleError("Short parsed but missing! You should not see this"); |
| 7047 | break; |
| 7048 | case detail::Classifier::WINDOWS: |
| 7049 | if (!detail::split_windows_style(current, arg_name, value)) |
| 7050 | throw HorribleError("windows option parsed but missing! You should not see this"); |
| 7051 | break; |
| 7052 | case detail::Classifier::SUBCOMMAND: |
| 7053 | case detail::Classifier::SUBCOMMAND_TERMINATOR: |
| 7054 | case detail::Classifier::POSITIONAL_MARK: |
| 7055 | case detail::Classifier::NONE: |
| 7056 | default: |
| 7057 | throw HorribleError("parsing got called with invalid option! You should not see this"); |
| 7058 | } |
| 7059 | |
| 7060 | auto op_ptr = std::find_if(std::begin(options_), std::end(options_), [arg_name, current_type](const Option_p &opt) { |
| 7061 | if (current_type == detail::Classifier::LONG) return opt->check_lname(arg_name); |
| 7062 | if (current_type == detail::Classifier::SHORT) return opt->check_sname(arg_name); |
| 7063 | // this will only get called for detail::Classifier::WINDOWS |
| 7064 | return opt->check_lname(arg_name) || opt->check_sname(arg_name); |
| 7065 | }); |
| 7066 | |
| 7067 | // Option not found |
| 7068 | if (op_ptr == std::end(options_)) { |
| 7069 | for (auto &subc : subcommands_) { |
| 7070 | if (subc->name_.empty() && !subc->disabled_) { |
| 7071 | if (subc->_parse_arg(args, current_type)) { |
| 7072 | if (!subc->pre_parse_called_) { |
| 7073 | subc->_trigger_pre_parse(args.size()); |
| 7074 | } |
| 7075 | return true; |
| 7076 | } |
| 7077 | } |
| 7078 | } |
| 7079 | // If a subcommand, try the master command |
| 7080 | if (parent_ != nullptr && fallthrough_) return _get_fallthrough_parent()->_parse_arg(args, current_type); |
| 7081 | // don't capture missing if this is a nameless subcommand |
| 7082 | if (parent_ != nullptr && name_.empty()) { |
| 7083 | return false; |
| 7084 | } |
| 7085 | // Otherwise, add to missing |
| 7086 | args.pop_back(); |
| 7087 | _move_to_missing(current_type, current); |
| 7088 | return true; |
| 7089 | } |
no test coverage detected