enh(Application): add ignoreUnknownOptions() function (#4661)

* enh(Application): remove useless function

* enh(Application): add ignoreUnknownOptions() function

* fix(OptionSet): comment error

* enh(Application): public two functions: getApplicationPath/getApplicationDirectory

* enh(Application): make findAppConfigFile function public and virtual

* style(Application): code alignment

* fix(Application): do not re-throw exception
This commit is contained in:
siren186 2024-09-12 01:55:29 +08:00 committed by GitHub
parent 6a6c5f7188
commit 2812dd7049
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 63 additions and 33 deletions

View File

@ -240,6 +240,12 @@ public:
/// will be propagated to the caller. If uninitialize() throws
/// an exception, the exception will be propagated to the caller.
void getApplicationPath(Poco::Path& path) const;
/// Returns the file path of the application executable.
void getApplicationDirectory(Poco::Path& dir) const;
/// Returns the directory that contains the application executable.
std::string commandName() const;
/// Returns the command name used to invoke the application.
@ -300,6 +306,14 @@ public:
/// help information has been encountered and no other things
/// besides displaying help shall be done.
void ignoreUnknownOptions();
/// Ignore unknown options. So that we can skip those options
/// we don't care about.
///
/// When your application command line has many options,
/// calling this function can help you handle only the options
/// you want to handle
static WindowSize windowSize();
/// Returns the current window size of the console window,
/// if available.
@ -364,6 +378,12 @@ protected:
/// Returns an exit code which should be one of the values
/// from the ExitCode enumeration.
virtual bool findAppConfigFile(const std::string& appName, const std::string& extension, Poco::Path& path) const;
/// Find the application config file.
///
/// loadConfiguration will call this function to find config file,
/// you can override this function to find your own config file.
bool findFile(Poco::Path& path) const;
/// Searches for the file in path in the application directory.
///
@ -386,10 +406,7 @@ private:
void setup();
void setArgs(int argc, char* argv[]);
void setArgs(const ArgVec& args);
void getApplicationPath(Poco::Path& path) const;
void processOptions();
bool findAppConfigFile(const std::string& appName, const std::string& extension, Poco::Path& path) const;
bool findAppConfigFile(const Path& basePath, const std::string& appName, const std::string& extension, Poco::Path& path) const;
typedef LayeredConfiguration::Ptr ConfigPtr;
typedef Poco::Logger::Ptr LoggerPtr;
@ -402,9 +419,10 @@ private:
ArgVec _unprocessedArgs;
OptionSet _options;
bool _unixOptions;
Logger* _pLogger;
Logger* _pLogger;
Poco::Timestamp _startTime;
bool _stopOptionsProcessing;
bool _ignoreUnknownOptions;
#if defined(POCO_OS_FAMILY_UNIX) && !defined(POCO_VXWORKS)
std::string _workingDirAtLaunch;

View File

@ -67,8 +67,8 @@ public:
/// The name must either match the short or full name of an
/// option. Comparison case sensitive for the short name and
/// not case sensitive for the full name.
/// Throws a NotFoundException if no matching option has been found.
/// Throws an UnknownOptionException if a partial full name matches
/// Throws a UnknownOptionException if no matching option has been found.
/// Throws an AmbiguousOptionException if a partial full name matches
/// more than one option.
Iterator begin() const;

View File

@ -27,6 +27,7 @@
#include "Poco/Util/Option.h"
#include "Poco/Util/OptionProcessor.h"
#include "Poco/Util/Validator.h"
#include "Poco/Util/OptionException.h"
#include "Poco/Environment.h"
#include "Poco/Exception.h"
#include "Poco/NumberFormatter.h"
@ -76,7 +77,8 @@ Application::Application():
_initialized(false),
_unixOptions(true),
_pLogger(&Logger::get("ApplicationStartup"s)),
_stopOptionsProcessing(false)
_stopOptionsProcessing(false),
_ignoreUnknownOptions(false)
{
setup();
}
@ -87,7 +89,8 @@ Application::Application(int argc, char* argv[]):
_initialized(false),
_unixOptions(true),
_pLogger(&Logger::get("ApplicationStartup"s)),
_stopOptionsProcessing(false)
_stopOptionsProcessing(false),
_ignoreUnknownOptions(false)
{
setup();
init(argc, argv);
@ -330,6 +333,11 @@ void Application::stopOptionsProcessing()
}
void Application::ignoreUnknownOptions()
{
_ignoreUnknownOptions = true;
}
Application::WindowSize Application::windowSize()
{
WindowSize size{0, 0};
@ -430,7 +438,21 @@ void Application::processOptions()
{
std::string name;
std::string value;
if (processor.process(*it, name, value))
bool success = false;
if (_ignoreUnknownOptions)
{
try
{
success = processor.process(*it, name, value);
} catch (Poco::Util::UnknownOptionException&) { }
}
else
{
success = processor.process(*it, name, value);
}
if (success)
{
if (!name.empty()) // "--" option to end options processing or deferred argument
{
@ -438,10 +460,15 @@ void Application::processOptions()
}
it = _unprocessedArgs.erase(it);
}
else ++it;
else
{
++it;
}
}
if (!_stopOptionsProcessing)
{
processor.checkRequired();
}
}
@ -483,6 +510,14 @@ void Application::getApplicationPath(Poco::Path& appPath) const
}
void Application::getApplicationDirectory(Poco::Path& dir) const
{
Path appPath;
getApplicationPath(appPath);
dir = appPath.parent();
}
bool Application::findFile(Poco::Path& path) const
{
if (path.isAbsolute()) return true;
@ -529,29 +564,6 @@ bool Application::findAppConfigFile(const std::string& appName, const std::strin
}
bool Application::findAppConfigFile(const Path& basePath, const std::string& appName, const std::string& extension, Path& path) const
{
poco_assert (!appName.empty());
Path p(basePath,appName);
p.setExtension(extension);
bool found = findFile(p);
if (!found)
{
#if defined(_DEBUG)
if (appName[appName.length() - 1] == 'd')
{
p.setBaseName(appName.substr(0, appName.length() - 1));
found = findFile(p);
}
#endif
}
if (found)
path = p;
return found;
}
void Application::defineOptions(OptionSet& options)
{
for (auto& pSub: _subsystems)