From 5ab086e337048ea2d3b525eff3204c6d75ec6e7d Mon Sep 17 00:00:00 2001 From: Max Kellermann Date: Tue, 16 Jan 2018 11:25:18 +0100 Subject: [PATCH] util/OptionParser: loop in ParseNext() until a new option is found --- src/CommandLine.cxx | 4 +--- src/util/OptionDef.hxx | 2 ++ src/util/OptionParser.cxx | 30 +++++++++++++++--------------- src/util/OptionParser.hxx | 20 ++++++-------------- 4 files changed, 24 insertions(+), 32 deletions(-) diff --git a/src/CommandLine.cxx b/src/CommandLine.cxx index 238ec7a34..bfde2f6a1 100644 --- a/src/CommandLine.cxx +++ b/src/CommandLine.cxx @@ -313,9 +313,7 @@ ParseCommandLine(int argc, char **argv, struct options *options) // First pass: handle command line options OptionParser parser(argc, argv); - while (parser.HasEntries()) { - if (!parser.ParseNext()) - continue; + while (parser.ParseNext()) { if (parser.CheckOption(opt_kill)) { options->kill = true; continue; diff --git a/src/util/OptionDef.hxx b/src/util/OptionDef.hxx index 559eb9ec9..aa83045f4 100644 --- a/src/util/OptionDef.hxx +++ b/src/util/OptionDef.hxx @@ -20,6 +20,8 @@ #ifndef MPD_UTIL_OPTIONDEF_HXX #define MPD_UTIL_OPTIONDEF_HXX +#include + /** * Command line option definition. */ diff --git a/src/util/OptionParser.cxx b/src/util/OptionParser.cxx index 5b7d7fc85..2bb5c28d5 100644 --- a/src/util/OptionParser.cxx +++ b/src/util/OptionParser.cxx @@ -39,23 +39,23 @@ OptionParser::CheckOption(const OptionDef &opt) const noexcept bool OptionParser::ParseNext() noexcept { - assert(HasEntries()); - const char *arg = args.shift(); - if (arg[0] == '-') { - if (arg[1] == '-') { - option = arg + 2; - is_long = true; + while (!args.empty()) { + const char *arg = args.shift(); + if (arg[0] == '-') { + if (arg[1] == '-') { + option = arg + 2; + is_long = true; + } + else { + option = arg + 1; + is_long = false; + } + option_raw = arg; + return true; } - else { - option = arg + 1; - is_long = false; - } - option_raw = arg; - return true; + + *remaining_tail++ = arg; } - option = nullptr; - option_raw = nullptr; - *remaining_tail++ = arg; return false; } diff --git a/src/util/OptionParser.hxx b/src/util/OptionParser.hxx index 84a4f0e4f..a4987f36a 100644 --- a/src/util/OptionParser.hxx +++ b/src/util/OptionParser.hxx @@ -22,8 +22,6 @@ #include "util/ConstBuffer.hxx" -#include - class OptionDef; /** @@ -32,8 +30,8 @@ class OptionDef; class OptionParser { ConstBuffer args; - const char *option = nullptr; - const char *option_raw = nullptr; + const char *option; + const char *option_raw; bool is_long = false; const char **const remaining_head, **remaining_tail; @@ -42,23 +40,15 @@ public: /** * Constructs #OptionParser. */ - constexpr OptionParser(int _argc, char **_argv) noexcept + OptionParser(int _argc, char **_argv) noexcept :args(_argv + 1, _argc - 1), remaining_head(const_cast(_argv + 1)), remaining_tail(remaining_head) {} - /** - * Checks if there are command line entries to process. - */ - constexpr bool HasEntries() const noexcept { - return !args.empty(); - } - /** * Gets the last parsed option. */ const char *GetOption() noexcept { - assert(option_raw != nullptr); return option_raw; } @@ -78,9 +68,11 @@ public: /** * Parses current command line entry. - * Returns true on success, false otherwise. * Regardless of result, advances current position to the next * command line entry. + * + * @return true if an option was found, false if there are no + * more options */ bool ParseNext() noexcept;