Skip to content

Commit

Permalink
command_line/options: Refactored to properly recursively traverse opt…
Browse files Browse the repository at this point in the history
…ionSet_t's for all parsed arguments in the path to finding the right help to display
  • Loading branch information
dragonmux committed Oct 13, 2024
1 parent 79e2a9a commit 7c66173
Show file tree
Hide file tree
Showing 2 changed files with 49 additions and 39 deletions.
72 changes: 40 additions & 32 deletions impl/command_line/options.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -162,6 +162,25 @@ namespace substrate::commandLine
}
}

bool optionSet_t::displayHelp(const arguments_t &args) const noexcept
{
const auto arg{args[_metaName]};
// We found a match so we now need to find out which one matched
if (arg)
{
// Extract the choice made and loop through the possible choice alternations
const auto &choice{std::get<choice_t>(*arg)};
for (const auto &option : _alternations)
{
// If the alternation matches the one actually selected, display it
if (option.matches(choice.value()))
option.suboptions().displayHelp(choice.arguments(), _metaName);
}
}
// Return if we found a match
return arg;
}

// Implementation of the innards of optionSet_t as otherwise we get compile errors
const optionAlternation_t *optionSet_t::begin() const noexcept
{ return _alternations.begin(); }
Expand Down Expand Up @@ -284,12 +303,29 @@ namespace substrate::commandLine
}

// NOTLINENEXTLINE(readability-convert-member-functions-to-static)
void optionsHolder_t::displayHelp(const std::string_view &optionsTitle) const noexcept
void optionsHolder_t::displayHelp(const arguments_t &args, const std::string_view &optionsTitle) const noexcept
{
// Figure out how much padding is needed to make everything neat
// First check to see if we should actually be displaying some alternation's help
for (const auto &option : *this)
{
const auto handled
{
std::visit(match_t
{
[](const option_t &) { return false; },
[&](const optionSet_t &optionSet) { return optionSet.displayHelp(args); },
}, option)
};
// If we have indeed managed to handle things, finish early
if (handled)
return;
}

// No optionSet_t's to traverse, so now figure out how much padding is needed to make everything neat
const auto padding{displayPadding()};
std::vector<optionSet_t> optionSets{};

// Display the title block for the non-alternation options
if (optionsTitle.empty())
console.writeln("Options:"sv);
else
Expand Down Expand Up @@ -320,36 +356,8 @@ namespace substrate::commandLine
console.writeln(_helpHeader);
console.writeln();
}
// Now see if any of the option sets appear in the arguments parsed
auto foundMatch{false};
for (const auto &option : _options)
{
foundMatch |= std::visit(match_t
{
[](const option_t &) { return false; },
[&](const optionSet_t &optionSet) -> bool
{
const auto arg{args[optionSet.metaName()]};
// We found a match so we now need to find out which one matched
if (arg)
{
// Extract the choice made and loop through the possible choice alternations
const auto &choice{std::get<choice_t>(*arg)};
for (const auto &alternation : optionSet)
{
// If the alternation matches the one actually selected, display it
if (alternation.matches(choice.value()))
alternation.suboptions().displayHelp(optionSet.metaName());
}
}
// Return if we found a match
return arg;
},
}, option);
}
// If we found no matching options, display the base help
if (!foundMatch)
_options.displayHelp();
// Now display the appropriate options help
_options.displayHelp(args);

// Finish up by displaying the help footer
if (!_helpFooter.empty())
Expand Down
16 changes: 9 additions & 7 deletions substrate/command_line/options
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,7 @@ namespace substrate::commandLine
};

struct optionAlternation_t;
struct arguments_t;
using optionValueParser_t = std::optional<std::any> (*)(const std::string_view &) noexcept;

// A singular command line option such as a simple flag
Expand Down Expand Up @@ -222,6 +223,7 @@ namespace substrate::commandLine
matches(const std::string_view &argument) const noexcept;
[[nodiscard]] size_t displayPadding() const noexcept;
void displayHelp(size_t padding = 0U) const noexcept;
bool displayHelp(const arguments_t &args) const noexcept;

[[nodiscard]] const optionAlternation_t *begin() const noexcept;
[[nodiscard]] const optionAlternation_t *end() const noexcept;
Expand Down Expand Up @@ -264,7 +266,7 @@ namespace substrate::commandLine
constexpr optionsItem_t operator [](const size_t index) const { return optionAt<0U>(index, _options); }
constexpr auto &options() const noexcept { return _options; }

void displayHelp(const std::string_view &optionsTitle) const noexcept;
void displayHelp(const arguments_t &args, const std::string_view &optionsTitle) const noexcept;
};

template<typename... options_t> optionsStorage_t(const std::tuple<options_t...> &) ->
Expand Down Expand Up @@ -332,14 +334,15 @@ namespace substrate::commandLine
constexpr auto end() const noexcept { return optionsIterator_t{storage, length, indexFn}; }

[[nodiscard]] size_t displayPadding() const noexcept;
void displayHelp(const std::string_view &optionsTitle) const noexcept;
void displayHelp(const arguments_t &args, const std::string_view &optionsTitle) const noexcept;
};

template<typename... options_t>
void optionsStorage_t<options_t...>::displayHelp(const std::string_view &optionsTitle) const noexcept
void optionsStorage_t<options_t...>::displayHelp(const arguments_t &args,
const std::string_view &optionsTitle) const noexcept
{
optionsHolder_t holder{*this};
holder.displayHelp(optionsTitle);
holder.displayHelp(args, optionsTitle);
}
}

Expand All @@ -363,7 +366,8 @@ namespace substrate::commandLine
[[nodiscard]] constexpr auto end() const noexcept { return _options.end(); }

[[nodiscard]] size_t displayPadding() const noexcept { return _options.displayPadding(); }
void displayHelp(std::string_view optionsTitle = {}) const noexcept { _options.displayHelp(optionsTitle); }
void displayHelp(const arguments_t &args, std::string_view optionsTitle = {}) const noexcept
{ _options.displayHelp(args, optionsTitle); }
};

namespace internal
Expand Down Expand Up @@ -427,8 +431,6 @@ namespace substrate::commandLine
[[nodiscard]] constexpr auto &helpText() const noexcept { return _help; }
};

struct arguments_t;

namespace internal
{
struct optionsRoot_t final
Expand Down

0 comments on commit 7c66173

Please sign in to comment.