From c4f392e8fc57554b7e774fef0ee68280eaaf5c69 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gonzalo=20Garramu=C3=B1o?= Date: Mon, 25 Sep 2023 07:39:20 -0300 Subject: [PATCH] Added parsing with unused arguments, so multiple images can be loaded, with: getUnusedArgs(). See mrv2's lib/mrvApp/App.cpp source code for more info. --- lib/tlApp/CmdLine.h | 13 ++++++++++--- lib/tlApp/CmdLineInline.h | 22 ++++++++++++++++------ lib/tlApp/IApp.cpp | 39 ++++++++++++++++++++++++++++++--------- lib/tlApp/IApp.h | 4 ++++ 4 files changed, 60 insertions(+), 18 deletions(-) diff --git a/lib/tlApp/CmdLine.h b/lib/tlApp/CmdLine.h index b83a299b7..2d1c08b5e 100644 --- a/lib/tlApp/CmdLine.h +++ b/lib/tlApp/CmdLine.h @@ -103,7 +103,8 @@ namespace tl ICmdLineArg( const std::string& name, const std::string& help, - bool optional); + bool optional, + bool unused = false); public: virtual ~ICmdLineArg() = 0; @@ -119,11 +120,15 @@ namespace tl //! Get whether this argument is optional. bool isOptional() const; + + //! Get whether this argument is for unused arguments. + bool isUnused() const; protected: std::string _name; std::string _help; bool _optional = false; + bool _unused = false; }; //! Command line value argument. @@ -135,7 +140,8 @@ namespace tl T& value, const std::string& name, const std::string& help, - bool optional); + bool optional, + bool unused = false); public: //! Create a new command line argument. @@ -143,7 +149,8 @@ namespace tl T& value, const std::string& name, const std::string& help, - bool optional = false); + bool optional = false, + bool unused = false); void parse(std::vector& args) override; diff --git a/lib/tlApp/CmdLineInline.h b/lib/tlApp/CmdLineInline.h index 35de8d153..5154263a7 100644 --- a/lib/tlApp/CmdLineInline.h +++ b/lib/tlApp/CmdLineInline.h @@ -6,6 +6,7 @@ #include #include +#include namespace tl { @@ -112,10 +113,12 @@ namespace tl inline ICmdLineArg::ICmdLineArg( const std::string& name, const std::string& help, - bool optional) : + bool optional, + bool unused) : _name(name), _help(help), - _optional(optional) + _optional(optional), + _unused(unused) {} inline ICmdLineArg::~ICmdLineArg() @@ -136,13 +139,19 @@ namespace tl return _optional; } + inline bool ICmdLineArg::isUnused() const + { + return _unused; + } + template inline CmdLineValueArg::CmdLineValueArg( T& value, const std::string& name, const std::string& help, - bool optional) : - ICmdLineArg(name, help, optional), + bool optional, + bool unused) : + ICmdLineArg(name, help, optional, unused), _value(value) {} @@ -151,9 +160,10 @@ namespace tl T& value, const std::string& name, const std::string& help, - bool optional) + bool optional, + bool unused) { - return std::shared_ptr >(new CmdLineValueArg(value, name, help, optional)); + return std::shared_ptr >(new CmdLineValueArg(value, name, help, optional, unused)); } template diff --git a/lib/tlApp/IApp.cpp b/lib/tlApp/IApp.cpp index 4e487bebf..2024319ae 100644 --- a/lib/tlApp/IApp.cpp +++ b/lib/tlApp/IApp.cpp @@ -115,6 +115,11 @@ namespace tl return _exit; } + const std::vector IApp::getUnusedArgs() const + { + return _unusedArgs; + } + void IApp::_log(const std::string& value, log::Type type) { _context->log(_p->cmdLine.name, value, type); @@ -151,11 +156,16 @@ namespace tl arg(e.what())); } } + bool unusedArgs = false; size_t requiredArgs = 0; size_t optionalArgs = 0; for (const auto& i : p.cmdLine.args) { - if (!i->isOptional()) + if (i->isUnused()) + { + unusedArgs = true; + } + else if (!i->isOptional()) { ++requiredArgs; } @@ -165,8 +175,8 @@ namespace tl } } if (p.cmdLine.argv.size() < requiredArgs || - p.cmdLine.argv.size() > requiredArgs + optionalArgs || - _options.help) + (p.cmdLine.argv.size() > requiredArgs + optionalArgs && + !unusedArgs) || _options.help) { _printCmdLineHelp(); return 1; @@ -175,9 +185,17 @@ namespace tl { try { - if (!(p.cmdLine.argv.empty() && i->isOptional())) + if (!p.cmdLine.argv.empty()) { - i->parse(p.cmdLine.argv); + if(i->isUnused()) + { + _unusedArgs = p.cmdLine.argv; + break; + } + if (i->isOptional()) + { + i->parse(p.cmdLine.argv); + } } } catch (const std::exception& e) @@ -199,23 +217,26 @@ namespace tl { std::stringstream ss; ss << " " + p.cmdLine.name; + if (p.cmdLine.options.size()) + { + ss << " [options]..."; + } if (p.cmdLine.args.size()) { std::vector args; for (const auto& i : p.cmdLine.args) { const bool optional = i->isOptional(); + const bool unused = i->isUnused(); args.push_back( (optional ? "[" : "(") + string::toLower(i->getName()) + (optional ? "]" : ")")); + if (unused) + args.push_back("..."); } ss << " " << string::join(args, " "); } - if (p.cmdLine.options.size()) - { - ss << " [option],..."; - } _print(ss.str()); _printNewline(); } diff --git a/lib/tlApp/IApp.h b/lib/tlApp/IApp.h index 3919ffc5b..dc3292435 100644 --- a/lib/tlApp/IApp.h +++ b/lib/tlApp/IApp.h @@ -62,6 +62,9 @@ namespace tl //! Get the exit code. int getExit() const; + //! Get unused arguments + const std::vector getUnusedArgs() const; + protected: void _log(const std::string&, log::Type = log::Type::Message); @@ -69,6 +72,7 @@ namespace tl void _printNewline(); void _printError(const std::string&); + std::vector _unusedArgs; std::shared_ptr _context; Options _options; int _exit = 0;