diff options
| author | Johannes Altmanninger <aclopte@gmail.com> | 2023-02-12 20:12:52 +0100 |
|---|---|---|
| committer | Johannes Altmanninger <aclopte@gmail.com> | 2023-02-17 20:50:58 +0100 |
| commit | 64d4d29d43c78a403cff81d52ad0dabe06518f51 (patch) | |
| tree | e2fd2c840166e4f319df69a588b899cf86182cc7 /src/parameters_parser.cc | |
| parent | afaa47e93fb937fbedb60bcdbc768bb937108f86 (diff) | |
Use parameter parser to skip switch args in completion
The command line "hook -group xyz " should get scope completions but
it actually gets hook completions because "xyz" is wrongly interpreted
as positional argument.
Fix this by using the parameters parser to compute positional
arguments.
Fixes #4840
Diffstat (limited to 'src/parameters_parser.cc')
| -rw-r--r-- | src/parameters_parser.cc | 28 |
1 files changed, 24 insertions, 4 deletions
diff --git a/src/parameters_parser.cc b/src/parameters_parser.cc index 8de8241b..633cb092 100644 --- a/src/parameters_parser.cc +++ b/src/parameters_parser.cc @@ -25,7 +25,7 @@ String generate_switches_doc(const SwitchMap& switches) return res; } -ParametersParser::ParametersParser(ParameterList params, const ParameterDesc& desc) +ParametersParser::ParametersParser(ParameterList params, const ParameterDesc& desc, bool ignore_errors) : m_params(params) { const bool switches_only_at_start = desc.flags & ParameterDesc::Flags::SwitchesOnlyAtStart; @@ -36,11 +36,16 @@ ParametersParser::ParametersParser(ParameterList params, const ParameterDesc& de for (size_t i = 0; i < params.size(); ++i) { if (not only_pos and not ignore_unknown_switches and params[i] == "--") + { + m_state = State::Switch; only_pos = true; + } else if (not only_pos and not params[i].empty() and params[i][0_byte] == '-') { StringView switch_name = params[i].substr(1_byte); auto it = desc.switches.find(switch_name); + m_state = it == desc.switches.end() and ignore_unknown_switches ? + State::Positional : State::Switch; if (it == desc.switches.end()) { if (ignore_unknown_switches) @@ -50,28 +55,43 @@ ParametersParser::ParametersParser(ParameterList params, const ParameterDesc& de only_pos = true; continue; } + if (ignore_errors) + continue; throw unknown_option(params[i]); } auto switch_index = it - desc.switches.begin(); if (switch_seen[switch_index]) + { + if (ignore_errors) + continue; throw runtime_error{format("switch '-{}' specified more than once", it->key)}; + } switch_seen[switch_index] = true; - if (it->value.takes_arg and ++i == params.size()) - throw missing_option_value(it->key); + if (it->value.takes_arg) + { + if (++i == params.size()) + { + if (ignore_errors) + continue; + throw missing_option_value(it->key); + } + m_state = State::SwitchArgument; + } m_switches[switch_name.str()] = it->value.takes_arg ? params[i] : StringView{}; } else // positional { + m_state = State::Positional; if (switches_only_at_start) only_pos = true; m_positional_indices.push_back(i); } } size_t count = m_positional_indices.size(); - if (count > desc.max_positionals or count < desc.min_positionals) + if (not ignore_errors and (count > desc.max_positionals or count < desc.min_positionals)) throw wrong_argument_count(); } |
