in fboss/cli/fboss2/CLI11/App.hpp [2451:2548]
bool _parse_positional(std::vector<std::string> &args, bool haltOnSubcommand) {
const std::string &positional = args.back();
if(positionals_at_end_) {
// deal with the case of required arguments at the end which should take precedence over other arguments
auto arg_rem = args.size();
auto remreq = _count_remaining_positionals(true);
if(arg_rem <= remreq) {
for(const Option_p &opt : options_) {
if(opt->get_positional() && opt->required_) {
if(static_cast<int>(opt->count()) < opt->get_items_expected_min()) {
if(validate_positionals_) {
std::string pos = positional;
pos = opt->_validate(pos, 0);
if(!pos.empty()) {
continue;
}
}
opt->add_result(positional);
parse_order_.push_back(opt.get());
args.pop_back();
return true;
}
}
}
}
}
for(const Option_p &opt : options_) {
// Eat options, one by one, until done
if(opt->get_positional() &&
(static_cast<int>(opt->count()) < opt->get_items_expected_min() || opt->get_allow_extra_args())) {
if(validate_positionals_) {
std::string pos = positional;
pos = opt->_validate(pos, 0);
if(!pos.empty()) {
continue;
}
}
opt->add_result(positional);
parse_order_.push_back(opt.get());
args.pop_back();
return true;
}
}
for(auto &subc : subcommands_) {
if((subc->name_.empty()) && (!subc->disabled_)) {
if(subc->_parse_positional(args, false)) {
if(!subc->pre_parse_called_) {
subc->_trigger_pre_parse(args.size());
}
return true;
}
}
}
// let the parent deal with it if possible
if(parent_ != nullptr && fallthrough_)
return _get_fallthrough_parent()->_parse_positional(args, static_cast<bool>(parse_complete_callback_));
/// Try to find a local subcommand that is repeated
auto com = _find_subcommand(args.back(), true, false);
if(com != nullptr && (require_subcommand_max_ == 0 || require_subcommand_max_ > parsed_subcommands_.size())) {
if(haltOnSubcommand) {
return false;
}
args.pop_back();
com->_parse(args);
return true;
}
/// now try one last gasp at subcommands that have been executed before, go to root app and try to find a
/// subcommand in a broader way, if one exists let the parent deal with it
auto parent_app = (parent_ != nullptr) ? _get_fallthrough_parent() : this;
com = parent_app->_find_subcommand(args.back(), true, false);
if(com != nullptr && (com->parent_->require_subcommand_max_ == 0 ||
com->parent_->require_subcommand_max_ > com->parent_->parsed_subcommands_.size())) {
return false;
}
if(positionals_at_end_) {
throw CLI::ExtrasError(name_, args);
}
/// If this is an option group don't deal with it
if(parent_ != nullptr && name_.empty()) {
return false;
}
/// We are out of other options this goes to missing
_move_to_missing(detail::Classifier::NONE, positional);
args.pop_back();
if(prefix_command_) {
while(!args.empty()) {
_move_to_missing(detail::Classifier::NONE, args.back());
args.pop_back();
}
}
return true;
}