Util: Simplify the logic of the long option parsing function
This commit is contained in:
+35
-38
@@ -143,72 +143,69 @@ bool ArgParser::parseShortOption(std::string_view option, std::string_view next)
|
|||||||
// Optional: directly after, separated by '='
|
// Optional: directly after, separated by '='
|
||||||
bool ArgParser::parseLongOption(std::string_view option, std::string_view next)
|
bool ArgParser::parseLongOption(std::string_view option, std::string_view next)
|
||||||
{
|
{
|
||||||
bool result = true;
|
|
||||||
|
|
||||||
std::string name = std::string(option.substr(0, option.find_first_of('=')));
|
std::string name = std::string(option.substr(0, option.find_first_of('=')));
|
||||||
std::string_view value = option.substr(option.find_first_of('=') + 1);
|
std::string_view value = option.substr(option.find_first_of('=') + 1);
|
||||||
|
|
||||||
bool argumentProvided = true;
|
|
||||||
if (name.compare(value) == 0 && option.find('=') == std::string_view::npos) {
|
|
||||||
argumentProvided = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
printf("Parsing long option: '%s' with value '%s'\n", name.data(), argumentProvided ? value.data() : "");
|
|
||||||
|
|
||||||
auto foundOption = std::find_if(m_options.begin(), m_options.end(), [&name](Option& it) -> bool {
|
auto foundOption = std::find_if(m_options.begin(), m_options.end(), [&name](Option& it) -> bool {
|
||||||
return it.longName && it.longName == name;
|
return it.longName && it.longName == name;
|
||||||
});
|
});
|
||||||
|
|
||||||
if (foundOption == m_options.cend()) {
|
if (foundOption == m_options.cend()) {
|
||||||
printError(name.data(), Error::OptionUnrecognized);
|
printError(name.data(), Error::OptionUnrecognized);
|
||||||
|
return false;
|
||||||
result = false;
|
|
||||||
}
|
}
|
||||||
else if (argumentProvided) {
|
|
||||||
|
enum class ArgumentProvided {
|
||||||
|
No,
|
||||||
|
DirectlyAfter,
|
||||||
|
Seperated,
|
||||||
|
};
|
||||||
|
|
||||||
|
auto argument = ArgumentProvided::No;
|
||||||
|
if (name != value || option.find('=') != std::string_view::npos) {
|
||||||
|
argument = ArgumentProvided::DirectlyAfter;
|
||||||
|
}
|
||||||
|
else if (!next.empty() && next[0] != '-') {
|
||||||
|
argument = ArgumentProvided::Seperated;
|
||||||
|
value = next;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool result = true;
|
||||||
|
|
||||||
if (foundOption->requiresArgument == Required::No) {
|
if (foundOption->requiresArgument == Required::No) {
|
||||||
|
if (argument == ArgumentProvided::DirectlyAfter) {
|
||||||
foundOption->error = Error::OptionDoesntAllowArgument;
|
foundOption->error = Error::OptionDoesntAllowArgument;
|
||||||
printError(name.data(), Error::OptionDoesntAllowArgument);
|
printError(name.data(), Error::OptionDoesntAllowArgument);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
result = false;
|
// FIXME: Figure out why providing a nullptr breaks the lambda here.
|
||||||
|
result = foundOption->acceptValue("");
|
||||||
}
|
}
|
||||||
else if (foundOption->requiresArgument == Required::Yes) {
|
else if (foundOption->requiresArgument == Required::Yes) {
|
||||||
|
if (argument == ArgumentProvided::No) {
|
||||||
|
foundOption->error = Error::OptionRequiresArgument;
|
||||||
|
printError(name.data(), Error::OptionRequiresArgument);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
result = foundOption->acceptValue(value.data());
|
result = foundOption->acceptValue(value.data());
|
||||||
if (!result) {
|
if (!result) {
|
||||||
printError(name.data(), Error::OptionInvalidArgumentType);
|
printError(name.data(), Error::OptionInvalidArgumentType);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (argument == ArgumentProvided::Seperated) {
|
||||||
|
m_optionIndex++;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else if (foundOption->requiresArgument == Required::Optional) {
|
else if (foundOption->requiresArgument == Required::Optional) {
|
||||||
|
if (argument == ArgumentProvided::DirectlyAfter) {
|
||||||
result = foundOption->acceptValue(value.data());
|
result = foundOption->acceptValue(value.data());
|
||||||
if (!result) {
|
if (!result) {
|
||||||
printError(name.data(), Error::OptionInvalidArgumentType);
|
printError(name.data(), Error::OptionInvalidArgumentType);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (!next.empty() && foundOption->requiresArgument == Required::Yes) {
|
|
||||||
if (next[0] == '-') {
|
|
||||||
foundOption->error = Error::OptionRequiresArgument;
|
|
||||||
printError(name.data(), Error::OptionRequiresArgument);
|
|
||||||
|
|
||||||
result = false;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
result = foundOption->acceptValue(next.data());
|
|
||||||
m_optionIndex++;
|
|
||||||
if (!result) {
|
|
||||||
printError(name.data(), Error::OptionInvalidArgumentType);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (foundOption->requiresArgument == Required::Yes) {
|
|
||||||
foundOption->error = Error::OptionRequiresArgument;
|
|
||||||
printError(name.data(), Error::OptionRequiresArgument);
|
|
||||||
|
|
||||||
result = false;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
// FIXME: Figure out why providing a nullptr breaks the lambda here.
|
|
||||||
result = foundOption->acceptValue("");
|
|
||||||
}
|
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user