From dc2e494e3303fbbe91b679191f88942919a2f0ba Mon Sep 17 00:00:00 2001 From: "Peter D. Barnes, Jr" Date: Fri, 21 Oct 2022 11:18:57 -0700 Subject: [PATCH] core: command-line: handle hard-coded options first --- src/core/model/command-line.cc | 125 ++++++++++++++++++++------------- src/core/model/command-line.h | 24 +++++++ 2 files changed, 102 insertions(+), 47 deletions(-) diff --git a/src/core/model/command-line.cc b/src/core/model/command-line.cc index 9124b6b4b..fd30e2382 100644 --- a/src/core/model/command-line.cc +++ b/src/core/model/command-line.cc @@ -202,6 +202,8 @@ CommandLine::Parse(std::vector& args) { args.erase(args.begin()); // discard the program name + HandleHardOptions(args); + for (const auto& param : args) { if (HandleOption(param)) @@ -224,8 +226,8 @@ CommandLine::Parse(std::vector& args) #endif } -bool -CommandLine::HandleOption(const std::string& param) const +CommandLine::HasOptionName +CommandLine::GetOptionName(const std::string& param) const { // remove leading "--" or "-" std::string arg = param; @@ -244,9 +246,10 @@ CommandLine::HandleOption(const std::string& param) const else { // non-option argument? - return false; + return {false, param, ""}; } } + // find any value following '=' cur = arg.find('='); std::string name; @@ -261,6 +264,78 @@ CommandLine::HandleOption(const std::string& param) const name = arg.substr(0, cur); value = arg.substr(cur + 1, arg.size() - (cur + 1)); } + + return {true, name, value}; +} + +void +CommandLine::HandleHardOptions(const std::vector& args) const +{ + NS_LOG_FUNCTION(this << args.size() << args); + + for (const auto& param : args) + { + auto [isOpt, name, value] = GetOptionName(param); + if (!isOpt) + { + continue; + } + + // Hard-coded options + if (name == "PrintHelp" || name == "help") + { + // method below never returns. + PrintHelp(std::cout); + std::exit(0); + } + if (name == "PrintVersion" || name == "version") + { + // Print the version, then exit the program + PrintVersion(std::cout); + std::exit(0); + } + else if (name == "PrintGroups") + { + // method below never returns. + PrintGroups(std::cout); + std::exit(0); + } + else if (name == "PrintTypeIds") + { + // method below never returns. + PrintTypeIds(std::cout); + std::exit(0); + } + else if (name == "PrintGlobals") + { + // method below never returns. + PrintGlobals(std::cout); + std::exit(0); + } + else if (name == "PrintGroup") + { + // method below never returns. + PrintGroup(std::cout, value); + std::exit(0); + } + else if (name == "PrintAttributes") + { + // method below never returns. + PrintAttributes(std::cout, value); + std::exit(0); + } + } +} + +bool +CommandLine::HandleOption(const std::string& param) const +{ + auto [isOpt, name, value] = GetOptionName(param); + if (!isOpt) + { + return false; + } + HandleArgument(name, value); return true; @@ -614,50 +689,6 @@ CommandLine::HandleArgument(const std::string& name, const std::string& value) c NS_LOG_DEBUG("Handle arg name=" << name << " value=" << value); - // Hard-coded options - if (name == "PrintHelp" || name == "help") - { - // method below never returns. - PrintHelp(std::cout); - std::exit(0); - } - if (name == "PrintVersion" || name == "version") - { - // Print the version, then exit the program - PrintVersion(std::cout); - std::exit(0); - } - else if (name == "PrintGroups") - { - // method below never returns. - PrintGroups(std::cout); - std::exit(0); - } - else if (name == "PrintTypeIds") - { - // method below never returns. - PrintTypeIds(std::cout); - std::exit(0); - } - else if (name == "PrintGlobals") - { - // method below never returns. - PrintGlobals(std::cout); - std::exit(0); - } - else if (name == "PrintGroup") - { - // method below never returns. - PrintGroup(std::cout, value); - std::exit(0); - } - else if (name == "PrintAttributes") - { - // method below never returns. - PrintAttributes(std::cout, value); - std::exit(0); - } - auto errorExit = [this, name, value]() { std::cerr << "Invalid command-line argument: --" << name; if (value != "") diff --git a/src/core/model/command-line.h b/src/core/model/command-line.h index 311ec5924..313fc797a 100644 --- a/src/core/model/command-line.h +++ b/src/core/model/command-line.h @@ -26,6 +26,7 @@ #include // shared_ptr #include #include +#include #include /** @@ -495,6 +496,29 @@ class CommandLine std::string m_default; /**< The default value, as a string, if it exists. */ }; // class CallbackItem + /** + * Tuple type returned by GetOptionName(). + * + * | Field | Meaning + * |----------|-------------------------------------------- + * | `get<0>` | Is this an option (beginning with `-`)? + * | `get<1>` | The option name (after any `-`, before `=`) + * | `get<2>` | The value (after any `=`) + */ + using HasOptionName = std::tuple; + + /** + * Strip leading `--` or `-` from options. + * \returns \c false if none found, indicating this is a non-option. + */ + HasOptionName GetOptionName(const std::string& param) const; + /** + * Handle hard-coded options. + * + * \note: if any hard-coded options are found this function exits. + */ + void HandleHardOptions(const std::vector& args) const; + /** * Handle an option in the form \c param=value. *