带有可选参数的 Poco 选项
Poco Option with optional argument
我有一个基于 Poco (v1.9.4) 的 class
class PreprocessingApp : public Poco::Util::Application
使用这两种方法:
void PreprocessingApp::defineOptions(OptionSet& options)
{
Application::defineOptions(options);
options.addOption(
Option("proxy", "p", "Proxify connection")
.required(false)
.repeatable(false)
.argument("the value", false)
.callback(OptionCallback<PreprocessingApp>(this, &PreprocessingApp::handleBooleanOption))
);
options.addOption(
Option("test", "t", "Test something")
.required(true)
.repeatable(false)
.callback(OptionCallback<PreprocessingApp>(this, &PreprocessingApp::handleBooleanOption))
);
}
void PreprocessingApp::handleBooleanOption(const string& name, const string& value)
{
bool actualValue = value.empty() | value == "true" | value == "1";
config().setBool(name, actualValue);
}
如您所见,“proxy”是一个布尔选项。我添加了 ".argument("the value", false)" 以允许使用此选项传递参数,但将 "required" 标记为 false 以使其成为可选的。
这样我希望允许这个功能:
PreprocessingApp [-p [value]] -t [value]
两种变体都应该有效:
PreprocessingApp -p -t
PreprocessingApp -p true -t
实际调试handleBooleanOption时,“value”总是空“”。
需要切换为true(.argument("the value", true))时,"value"为"-t",省略下一个option处理。
是否有任何解决方案可以使其按预期工作?
根据 Poco documentation:
Option arguments can be specified in three ways. If a Unix short
option ("-o") is given, the argument directly follows the option name,
without any delimiting character or space ("-ovalue"). In default
option mode, or if a Unix long option ("--option") is given, the
option argument is delimited from the option name with either an equal
sign ('=') or a colon (':'), as in "--option=value" or
"/option:value". Finally, a required option argument can be specified
on the command line after the option, delimited with a space, as in
"--option value" or "-o value". The latter only works for required
option arguments, not optional ones.
基本上,必需参数需要在名称和值之间添加 space,而可选参数则不需要。因此,对于您的可选参数,请像这样指定它:-ptrue
或 --proxytrue
或 --proxy:true
.
对于必需的参数,这里还有一个问题。您可能认为使用 setter .required(true)
和 Poco::Util::Option
就足以在代码中定义所需的参数,但显然不是。您还必须使用 setter .argument()
,默认情况下将 required
设置为 true:
Option & argument(
const std::string & name,
bool required = true
);
因此,将所需参数的代码更改为:
options.addOption(
Poco::Util::Option("test", "t", "Test something")
.required(true)
.repeatable(false)
.argument("test")
.callback(Poco::Util::OptionCallback<ModbusInterface>(this, &ModbusInterface::handleBooleanOption))
);
那么您应该可以像这样调用您的应用程序,例如:
PreprocessingApp -ptrue -t true
我有一个基于 Poco (v1.9.4) 的 class
class PreprocessingApp : public Poco::Util::Application
使用这两种方法:
void PreprocessingApp::defineOptions(OptionSet& options)
{
Application::defineOptions(options);
options.addOption(
Option("proxy", "p", "Proxify connection")
.required(false)
.repeatable(false)
.argument("the value", false)
.callback(OptionCallback<PreprocessingApp>(this, &PreprocessingApp::handleBooleanOption))
);
options.addOption(
Option("test", "t", "Test something")
.required(true)
.repeatable(false)
.callback(OptionCallback<PreprocessingApp>(this, &PreprocessingApp::handleBooleanOption))
);
}
void PreprocessingApp::handleBooleanOption(const string& name, const string& value)
{
bool actualValue = value.empty() | value == "true" | value == "1";
config().setBool(name, actualValue);
}
如您所见,“proxy”是一个布尔选项。我添加了 ".argument("the value", false)" 以允许使用此选项传递参数,但将 "required" 标记为 false 以使其成为可选的。
这样我希望允许这个功能:
PreprocessingApp [-p [value]] -t [value]
两种变体都应该有效:
PreprocessingApp -p -t
PreprocessingApp -p true -t
实际调试handleBooleanOption时,“value”总是空“”。
需要切换为true(.argument("the value", true))时,"value"为"-t",省略下一个option处理。
是否有任何解决方案可以使其按预期工作?
根据 Poco documentation:
Option arguments can be specified in three ways. If a Unix short option ("-o") is given, the argument directly follows the option name, without any delimiting character or space ("-ovalue"). In default option mode, or if a Unix long option ("--option") is given, the option argument is delimited from the option name with either an equal sign ('=') or a colon (':'), as in "--option=value" or "/option:value". Finally, a required option argument can be specified on the command line after the option, delimited with a space, as in "--option value" or "-o value". The latter only works for required option arguments, not optional ones.
基本上,必需参数需要在名称和值之间添加 space,而可选参数则不需要。因此,对于您的可选参数,请像这样指定它:-ptrue
或 --proxytrue
或 --proxy:true
.
对于必需的参数,这里还有一个问题。您可能认为使用 setter .required(true)
和 Poco::Util::Option
就足以在代码中定义所需的参数,但显然不是。您还必须使用 setter .argument()
,默认情况下将 required
设置为 true:
Option & argument(
const std::string & name,
bool required = true
);
因此,将所需参数的代码更改为:
options.addOption(
Poco::Util::Option("test", "t", "Test something")
.required(true)
.repeatable(false)
.argument("test")
.callback(Poco::Util::OptionCallback<ModbusInterface>(this, &ModbusInterface::handleBooleanOption))
);
那么您应该可以像这样调用您的应用程序,例如:
PreprocessingApp -ptrue -t true