Browse Source

Util: Simplify the logic of the long option parsing function

master
Riyyi 3 years ago
parent
commit
bb29919f02
  1. 79
      src/util/argparser.cpp

79
src/util/argparser.cpp

@ -143,72 +143,69 @@ bool ArgParser::parseShortOption(std::string_view option, std::string_view next)
// Optional: directly after, separated by '='
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_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 {
return it.longName && it.longName == name;
});
if (foundOption == m_options.cend()) {
printError(name.data(), Error::OptionUnrecognized);
return false;
}
enum class ArgumentProvided {
No,
DirectlyAfter,
Seperated,
};
result = false;
auto argument = ArgumentProvided::No;
if (name != value || option.find('=') != std::string_view::npos) {
argument = ArgumentProvided::DirectlyAfter;
}
else if (argumentProvided) {
if (foundOption->requiresArgument == Required::No) {
else if (!next.empty() && next[0] != '-') {
argument = ArgumentProvided::Seperated;
value = next;
}
bool result = true;
if (foundOption->requiresArgument == Required::No) {
if (argument == ArgumentProvided::DirectlyAfter) {
foundOption->error = Error::OptionDoesntAllowArgument;
printError(name.data(), Error::OptionDoesntAllowArgument);
result = false;
}
else if (foundOption->requiresArgument == Required::Yes) {
result = foundOption->acceptValue(value.data());
if (!result) {
printError(name.data(), Error::OptionInvalidArgumentType);
}
}
else if (foundOption->requiresArgument == Required::Optional) {
result = foundOption->acceptValue(value.data());
if (!result) {
printError(name.data(), Error::OptionInvalidArgumentType);
}
return false;
}
// FIXME: Figure out why providing a nullptr breaks the lambda here.
result = foundOption->acceptValue("");
}
else if (!next.empty() && foundOption->requiresArgument == Required::Yes) {
if (next[0] == '-') {
else if (foundOption->requiresArgument == Required::Yes) {
if (argument == ArgumentProvided::No) {
foundOption->error = Error::OptionRequiresArgument;
printError(name.data(), Error::OptionRequiresArgument);
return false;
}
result = false;
result = foundOption->acceptValue(value.data());
if (!result) {
printError(name.data(), Error::OptionInvalidArgumentType);
}
else {
result = foundOption->acceptValue(next.data());
if (argument == ArgumentProvided::Seperated) {
m_optionIndex++;
}
}
else if (foundOption->requiresArgument == Required::Optional) {
if (argument == ArgumentProvided::DirectlyAfter) {
result = foundOption->acceptValue(value.data());
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;
}

Loading…
Cancel
Save