From bb29919f026704927d604b8369a4f41ae0168dda Mon Sep 17 00:00:00 2001 From: Riyyi Date: Mon, 13 Sep 2021 17:42:34 +0200 Subject: [PATCH] Util: Simplify the logic of the long option parsing function --- src/util/argparser.cpp | 79 ++++++++++++++++++++---------------------- 1 file changed, 38 insertions(+), 41 deletions(-) diff --git a/src/util/argparser.cpp b/src/util/argparser.cpp index 53c19b6..3e362d8 100644 --- a/src/util/argparser.cpp +++ b/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; }