Skip to content

Commit

Permalink
command_line/arguments: Implemented checks to enforce exclusivity on …
Browse files Browse the repository at this point in the history
…parsed options
  • Loading branch information
dragonmux committed Jan 7, 2024
1 parent 820634b commit bea2e9d
Showing 1 changed file with 34 additions and 1 deletion.
35 changes: 34 additions & 1 deletion impl/command_line/arguments.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -150,7 +150,7 @@ namespace substrate::commandLine
return requiredOptions;
}

static auto displayName(const optionsItem_t &item)
[[nodiscard]] static auto displayName(const optionsItem_t &item)
{
if (item.valueless_by_exception())
return ""s;
Expand All @@ -161,6 +161,35 @@ namespace substrate::commandLine
}, item);
}

[[nodiscard]] static bool checkExclusivity(const std::set<internal::optionsItem_t> &options)
{
std::set<option_t> exclusiveOptions{};
// Loop through all the visited options
for (const auto &option : options)
{
// Dispatch on the option type
std::visit(match_t
{
[&](const option_t &value)
{
if (value.isExclusive())
exclusiveOptions.insert(value);
},
[](const optionSet_t &) { },
}, option);
}
// Now we've collected all the options that are exclusive, display diagnostics
// if there is more than one in the set and return failure, otherwise success
if (exclusiveOptions.size() > 1)
{
console.error("Multiple mutually exclusive options given together on command line, only one allowed."sv);
console.error("Mutually exclusive options given are:"sv);
for (const auto &option : exclusiveOptions)
console.error(" "sv, option.displayName());
}
return exclusiveOptions.size() <= 1;
}

// NOLINTNEXTLINE(readability-convert-member-functions-to-static)
bool arguments_t::parseFrom(tokeniser_t &lexer, const options_t &options)
{
Expand All @@ -181,6 +210,10 @@ namespace substrate::commandLine
return false;
}
}
// Having parsed as many options as we can, collect all exclusive options seen and
// perform the exclusivity check
if (!checkExclusivity(optionsVisited))
return false;
// Having parsed as many options as we can, collect all the required options into a set
const auto requiredOptions{collectRequiredOptions(options)};
optionsVisited_t missingOptions{};
Expand Down

0 comments on commit bea2e9d

Please sign in to comment.