mirror of
https://github.com/pocoproject/poco.git
synced 2025-10-26 18:42:41 +01:00
changes (part 1) from 1.4.3 branch (XMLConfiguration delimiter, OptionProcessor)
This commit is contained in:
@@ -58,7 +58,7 @@ class Util_API OptionProcessor
|
||||
/// The process() method takes an argument from the command line.
|
||||
/// If that argument starts with an option prefix, the argument
|
||||
/// is further processed. Otherwise, the argument is ignored and
|
||||
/// false is ignored. The argument must match one of the options
|
||||
/// false is returned. The argument must match one of the options
|
||||
/// given in the OptionSet that is passed to the OptionProcessor
|
||||
/// with the constructor. If an option is part of a group, at most
|
||||
/// one option of the group can be passed to the OptionProcessor.
|
||||
@@ -82,6 +82,16 @@ class Util_API OptionProcessor
|
||||
/// a (partial) long option name.
|
||||
/// If the special option '--' is encountered in Unix mode, all following
|
||||
/// options are ignored.
|
||||
///
|
||||
/// 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.
|
||||
{
|
||||
public:
|
||||
OptionProcessor(const OptionSet& options);
|
||||
@@ -130,6 +140,7 @@ private:
|
||||
bool _ignore;
|
||||
std::set<std::string> _groups;
|
||||
std::set<std::string> _specifiedOptions;
|
||||
std::string _deferredOption;
|
||||
};
|
||||
|
||||
|
||||
|
||||
@@ -89,29 +89,62 @@ class Util_API XMLConfiguration: public AbstractConfiguration
|
||||
///
|
||||
/// Enumerating attributes is not supported.
|
||||
/// Calling keys("prop3.prop4") will return an empty range.
|
||||
///
|
||||
/// As a special feature, the delimiter character used to delimit
|
||||
/// property names can be changed to something other than period ('.') by
|
||||
/// passing the desired character to the constructor. This allows
|
||||
/// working with XML documents having element names with periods
|
||||
/// in them.
|
||||
{
|
||||
public:
|
||||
XMLConfiguration();
|
||||
/// Creates an empty XMLConfiguration.
|
||||
|
||||
XMLConfiguration(char delim);
|
||||
/// Creates an empty XMLConfiguration, using the given
|
||||
/// delimiter char instead of the default '.'.
|
||||
|
||||
XMLConfiguration(Poco::XML::InputSource* pInputSource);
|
||||
/// Creates an XMLConfiguration and loads the XML document from
|
||||
/// the given InputSource.
|
||||
|
||||
XMLConfiguration(Poco::XML::InputSource* pInputSource, char delim);
|
||||
/// Creates an XMLConfiguration and loads the XML document from
|
||||
/// the given InputSource. Uses the given delimiter char instead
|
||||
/// of the default '.'.
|
||||
|
||||
XMLConfiguration(std::istream& istr);
|
||||
/// Creates an XMLConfiguration and loads the XML document from
|
||||
/// the given stream.
|
||||
|
||||
XMLConfiguration(std::istream& istr, char delim);
|
||||
/// Creates an XMLConfiguration and loads the XML document from
|
||||
/// the given stream. Uses the given delimiter char instead
|
||||
/// of the default '.'.
|
||||
|
||||
XMLConfiguration(const std::string& path);
|
||||
/// Creates an XMLConfiguration and loads the XML document from
|
||||
/// the given path.
|
||||
|
||||
XMLConfiguration(const std::string& path, char delim);
|
||||
/// Creates an XMLConfiguration and loads the XML document from
|
||||
/// the given path. Uses the given delimiter char instead
|
||||
/// of the default '.'.
|
||||
|
||||
XMLConfiguration(const Poco::XML::Document* pDocument);
|
||||
/// Creates the XMLConfiguration using the given XML document.
|
||||
|
||||
XMLConfiguration(const Poco::XML::Document* pDocument, char delim);
|
||||
/// Creates the XMLConfiguration using the given XML document.
|
||||
/// Uses the given delimiter char instead of the default '.'.
|
||||
|
||||
XMLConfiguration(const Poco::XML::Node* pNode);
|
||||
/// Creates the XMLConfiguration using the given XML node.
|
||||
|
||||
XMLConfiguration(const Poco::XML::Node* pNode, char delim);
|
||||
/// Creates the XMLConfiguration using the given XML node.
|
||||
/// Uses the given delimiter char instead of the default '.'.
|
||||
|
||||
void load(Poco::XML::InputSource* pInputSource);
|
||||
/// Loads the XML document containing the configuration data
|
||||
/// from the given InputSource.
|
||||
@@ -166,7 +199,7 @@ protected:
|
||||
private:
|
||||
const Poco::XML::Node* findNode(const std::string& key) const;
|
||||
Poco::XML::Node* findNode(const std::string& key);
|
||||
static Poco::XML::Node* findNode(std::string::const_iterator& it, const std::string::const_iterator& end, Poco::XML::Node* pNode, bool create = false);
|
||||
Poco::XML::Node* findNode(std::string::const_iterator& it, const std::string::const_iterator& end, Poco::XML::Node* pNode, bool create = false) const;
|
||||
static Poco::XML::Node* findElement(const std::string& name, Poco::XML::Node* pNode, bool create);
|
||||
static Poco::XML::Node* findElement(int index, Poco::XML::Node* pNode, bool create);
|
||||
static Poco::XML::Node* findElement(const std::string& attr, const std::string& value, Poco::XML::Node* pNode);
|
||||
@@ -174,6 +207,7 @@ private:
|
||||
|
||||
Poco::XML::AutoPtr<Poco::XML::Node> _pRoot;
|
||||
Poco::XML::AutoPtr<Poco::XML::Document> _pDocument;
|
||||
char _delim;
|
||||
};
|
||||
|
||||
|
||||
|
||||
@@ -371,7 +371,7 @@ void Application::processOptions()
|
||||
std::string value;
|
||||
if (processor.process(*it, name, value))
|
||||
{
|
||||
if (!name.empty()) // "--" option to end options processing
|
||||
if (!name.empty()) // "--" option to end options processing or deferred argument
|
||||
{
|
||||
handleOption(name, value);
|
||||
}
|
||||
|
||||
@@ -176,7 +176,15 @@ void HelpFormatter::formatOptions(std::ostream& ostr) const
|
||||
for (OptionSet::Iterator it = _options.begin(); it != _options.end(); ++it)
|
||||
{
|
||||
formatOption(ostr, *it, optWidth);
|
||||
if (_indent < optWidth)
|
||||
{
|
||||
ostr << '\n' << std::string(_indent, ' ');
|
||||
formatText(ostr, it->description(), _indent, _indent);
|
||||
}
|
||||
else
|
||||
{
|
||||
formatText(ostr, it->description(), _indent, optWidth);
|
||||
}
|
||||
ostr << '\n';
|
||||
}
|
||||
}
|
||||
|
||||
@@ -65,9 +65,13 @@ void OptionProcessor::setUnixStyle(bool flag)
|
||||
|
||||
bool OptionProcessor::process(const std::string& argument, std::string& optionName, std::string& optionArg)
|
||||
{
|
||||
optionName.clear();
|
||||
optionArg.clear();
|
||||
if (!_ignore)
|
||||
{
|
||||
if (_unixStyle)
|
||||
if (!_deferredOption.empty())
|
||||
return processCommon(argument, false, optionName, optionArg);
|
||||
else if (_unixStyle)
|
||||
return processUnix(argument, optionName, optionArg);
|
||||
else
|
||||
return processDefault(argument, optionName, optionArg);
|
||||
@@ -83,6 +87,12 @@ void OptionProcessor::checkRequired() const
|
||||
if (it->required() && _specifiedOptions.find(it->fullName()) == _specifiedOptions.end())
|
||||
throw MissingOptionException(it->fullName());
|
||||
}
|
||||
if (!_deferredOption.empty())
|
||||
{
|
||||
std::string optionArg;
|
||||
const Option& option = _options.getOption(_deferredOption, false);
|
||||
option.process(_deferredOption, optionArg); // will throw MissingArgumentException
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -133,6 +143,17 @@ bool OptionProcessor::processDefault(const std::string& argument, std::string& o
|
||||
|
||||
bool OptionProcessor::processCommon(const std::string& optionStr, bool isShort, std::string& optionName, std::string& optionArg)
|
||||
{
|
||||
if (!_deferredOption.empty())
|
||||
{
|
||||
const Option& option = _options.getOption(_deferredOption, false);
|
||||
std::string optionWithArg(_deferredOption);
|
||||
_deferredOption.clear();
|
||||
optionWithArg += '=';
|
||||
optionWithArg += optionStr;
|
||||
option.process(optionWithArg, optionArg);
|
||||
optionName = option.fullName();
|
||||
return true;
|
||||
}
|
||||
if (optionStr.empty()) throw EmptyOptionException();
|
||||
const Option& option = _options.getOption(optionStr, isShort);
|
||||
const std::string& group = option.group();
|
||||
@@ -146,6 +167,11 @@ bool OptionProcessor::processCommon(const std::string& optionStr, bool isShort,
|
||||
if (_specifiedOptions.find(option.fullName()) != _specifiedOptions.end() && !option.repeatable())
|
||||
throw DuplicateOptionException(option.fullName());
|
||||
_specifiedOptions.insert(option.fullName());
|
||||
if (option.argumentRequired() && ((!isShort && optionStr.find_first_of(":=") == std::string::npos) || (isShort && optionStr.length() == option.shortName().length())))
|
||||
{
|
||||
_deferredOption = option.fullName();
|
||||
return true;
|
||||
}
|
||||
option.process(optionStr, optionArg);
|
||||
optionName = option.fullName();
|
||||
return true;
|
||||
|
||||
@@ -51,36 +51,83 @@ namespace Poco {
|
||||
namespace Util {
|
||||
|
||||
|
||||
XMLConfiguration::XMLConfiguration()
|
||||
XMLConfiguration::XMLConfiguration():
|
||||
_delim('.')
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
XMLConfiguration::XMLConfiguration(Poco::XML::InputSource* pInputSource)
|
||||
XMLConfiguration::XMLConfiguration(char delim):
|
||||
_delim(delim)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
XMLConfiguration::XMLConfiguration(Poco::XML::InputSource* pInputSource):
|
||||
_delim('.')
|
||||
{
|
||||
load(pInputSource);
|
||||
}
|
||||
|
||||
|
||||
XMLConfiguration::XMLConfiguration(std::istream& istr)
|
||||
XMLConfiguration::XMLConfiguration(Poco::XML::InputSource* pInputSource, char delim):
|
||||
_delim(delim)
|
||||
{
|
||||
load(pInputSource);
|
||||
}
|
||||
|
||||
|
||||
XMLConfiguration::XMLConfiguration(std::istream& istr):
|
||||
_delim('.')
|
||||
{
|
||||
load(istr);
|
||||
}
|
||||
|
||||
|
||||
XMLConfiguration::XMLConfiguration(const std::string& path)
|
||||
XMLConfiguration::XMLConfiguration(std::istream& istr, char delim):
|
||||
_delim(delim)
|
||||
{
|
||||
load(istr);
|
||||
}
|
||||
|
||||
|
||||
XMLConfiguration::XMLConfiguration(const std::string& path):
|
||||
_delim('.')
|
||||
{
|
||||
load(path);
|
||||
}
|
||||
|
||||
|
||||
XMLConfiguration::XMLConfiguration(const Poco::XML::Document* pDocument)
|
||||
XMLConfiguration::XMLConfiguration(const std::string& path, char delim):
|
||||
_delim(delim)
|
||||
{
|
||||
load(path);
|
||||
}
|
||||
|
||||
|
||||
XMLConfiguration::XMLConfiguration(const Poco::XML::Document* pDocument):
|
||||
_delim('.')
|
||||
{
|
||||
load(pDocument);
|
||||
}
|
||||
|
||||
|
||||
XMLConfiguration::XMLConfiguration(const Poco::XML::Node* pNode)
|
||||
XMLConfiguration::XMLConfiguration(const Poco::XML::Document* pDocument, char delim):
|
||||
_delim(delim)
|
||||
{
|
||||
load(pDocument);
|
||||
}
|
||||
|
||||
|
||||
XMLConfiguration::XMLConfiguration(const Poco::XML::Node* pNode):
|
||||
_delim('.')
|
||||
{
|
||||
load(pNode);
|
||||
}
|
||||
|
||||
|
||||
XMLConfiguration::XMLConfiguration(const Poco::XML::Node* pNode, char delim):
|
||||
_delim(delim)
|
||||
{
|
||||
load(pNode);
|
||||
}
|
||||
@@ -294,7 +341,7 @@ Poco::XML::Node* XMLConfiguration::findNode(const std::string& key)
|
||||
}
|
||||
|
||||
|
||||
Poco::XML::Node* XMLConfiguration::findNode(std::string::const_iterator& it, const std::string::const_iterator& end, Poco::XML::Node* pNode, bool create)
|
||||
Poco::XML::Node* XMLConfiguration::findNode(std::string::const_iterator& it, const std::string::const_iterator& end, Poco::XML::Node* pNode, bool create) const
|
||||
{
|
||||
if (pNode && it != end)
|
||||
{
|
||||
@@ -339,9 +386,9 @@ Poco::XML::Node* XMLConfiguration::findNode(std::string::const_iterator& it, con
|
||||
}
|
||||
else
|
||||
{
|
||||
while (it != end && *it == '.') ++it;
|
||||
while (it != end && *it == _delim) ++it;
|
||||
std::string key;
|
||||
while (it != end && *it != '.' && *it != '[') key += *it++;
|
||||
while (it != end && *it != _delim && *it != '[') key += *it++;
|
||||
return findNode(it, end, findElement(key, pNode, create), create);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user