Skip to content

Commit

Permalink
command_line/arguments: Implemented gathering and passing of the set …
Browse files Browse the repository at this point in the history
…of global options through recursive arguments_t::parseFrom() calls
  • Loading branch information
dragonmux committed Jan 9, 2024
1 parent e90568f commit 31ce9ec
Showing 1 changed file with 29 additions and 4 deletions.
33 changes: 29 additions & 4 deletions impl/command_line/arguments.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -233,7 +233,8 @@ namespace substrate::commandLine
static std::optional<optionMatch_t> matchOption(tokeniser_t &lexer, const option_t &option,
const std::string_view &argument) noexcept;
static std::optional<optionMatch_t> matchOptionSet(tokeniser_t &lexer, const optionSet_t &option,
const std::string_view &argument) noexcept;
const std::string_view &argument, const options_t &options,
const std::set<internal::optionsItem_t> &globalOptions) noexcept;
template<typename set_t> static bool checkMatchValid(const optionsItem_t &option, set_t &optionsVisited) noexcept;
template<typename set_t> static std::optional<bool> handleResult(arguments_t &arguments, const optionsItem_t &option,
set_t &optionsVisited, const std::string_view &argument, const optionMatch_t &match) noexcept;
Expand Down Expand Up @@ -277,7 +278,8 @@ namespace substrate::commandLine
std::visit(match_t
{
[&](const option_t &value) { return matchOption(lexer, value, argument); },
[&](const optionSet_t &value) { return matchOptionSet(lexer, value, argument); },
[&](const optionSet_t &value)
{ return matchOptionSet(lexer, value, argument, options, globalOptions); },
}, option)
};

Expand Down Expand Up @@ -355,8 +357,31 @@ namespace substrate::commandLine
return flag_t{option.metaName(), std::move(*value)};
}

static std::set<internal::optionsItem_t> gatherGlobals(const options_t &options,
const std::set<internal::optionsItem_t> &globalOptions) noexcept
{
// Clone the existing set of global options
auto result{globalOptions};
// Loop through the current level's options and pull out any that are global
for (const auto &option : options)
{
std::visit(match_t
{
[&](const option_t &value)
{
if (value.isGlobal())
result.insert(value);
},
[&](const optionSet_t &) { },
}, option);
}
// Having gathered all of them up, return the new set
return result;
}

static std::optional<optionMatch_t> matchOptionSet(tokeniser_t &lexer, const optionSet_t &option,
const std::string_view &argument) noexcept
const std::string_view &argument, const options_t &options,
const std::set<internal::optionsItem_t> &globalOptions) noexcept
{
// Check if we're parsing an alternation from a set
const auto match{option.matches(argument)};
Expand All @@ -369,7 +394,7 @@ namespace substrate::commandLine
lexer.next();
arguments_t subarguments{};
const auto &suboptions{alternation.suboptions()};
if (!suboptions.empty() && !subarguments.parseFrom(lexer, suboptions, {}))
if (!suboptions.empty() && !subarguments.parseFrom(lexer, suboptions, gatherGlobals(options, globalOptions)))
// If the operation fails, use monostate to signal match-but-fail.
return std::monostate{};
return choice_t{option.metaName(), argument, std::move(subarguments)};
Expand Down

0 comments on commit 31ce9ec

Please sign in to comment.