#3507: Reference counting for bound configuration in Util::Option is broken

This commit is contained in:
Günter Obiltschnig 2022-02-19 10:35:30 +01:00
parent 3b1484ca50
commit 010cf8b7d0
2 changed files with 45 additions and 53 deletions

View File

@ -90,19 +90,19 @@ public:
Option& operator = (const Option& option);
/// Assignment operator.
void swap(Option& option);
/// Swaps the option with another one.
Option& shortName(const std::string& name);
/// Sets the short name of the option.
Option& fullName(const std::string& name);
/// Sets the full name of the option.
Option& description(const std::string& text);
/// Sets the description of the option.
Option& required(bool flag);
/// Sets whether the option is required (flag == true)
/// or optional (flag == false).
@ -110,28 +110,28 @@ public:
Option& repeatable(bool flag);
/// Sets whether the option can be specified more than once
/// (flag == true) or at most once (flag == false).
Option& argument(const std::string& name, bool required = true);
/// Specifies that the option takes an (optional or required)
/// argument.
Option& noArgument();
/// Specifies that the option does not take an argument (default).
Option& group(const std::string& group);
/// Specifies the option group the option is part of.
Option& binding(const std::string& propertyName);
/// Binds the option to the configuration property with the given name.
///
/// The configuration will automatically receive the option's argument.
Option& binding(const std::string& propertyName, AbstractConfiguration* pConfig);
/// Binds the option to the configuration property with the given name,
Option& binding(const std::string& propertyName, AbstractConfiguration::Ptr pConfig);
/// Binds the option to the configuration property with the given name,
/// using the given AbstractConfiguration.
///
/// The configuration will automatically receive the option's argument.
Option& callback(const AbstractOptionCallback& cb);
/// Binds the option to the given method.
///
@ -149,49 +149,49 @@ public:
const std::string& shortName() const;
/// Returns the short name of the option.
const std::string& fullName() const;
/// Returns the full name of the option.
const std::string& description() const;
/// Returns the description of the option.
bool required() const;
/// Returns true if the option is required, false if not.
bool repeatable() const;
/// Returns true if the option can be specified more than
/// once, or false if at most once.
bool takesArgument() const;
/// Returns true if the options takes an (optional) argument.
bool argumentRequired() const;
/// Returns true if the argument is required.
const std::string& argumentName() const;
/// Returns the argument name, if specified.
const std::string& group() const;
/// Returns the option group the option is part of,
/// or an empty string, if the option is not part of
/// a group.
const std::string& binding() const;
/// Returns the property name the option is bound to,
/// or an empty string in case it is not bound.
AbstractOptionCallback* callback() const;
/// Returns a pointer to the callback method for the option,
/// or NULL if no callback has been specified.
Validator* validator() const;
/// Returns the option's Validator, if one has been specified,
/// or NULL otherwise.
/// or NULL otherwise.
AbstractConfiguration::Ptr config() const;
/// Returns the configuration, if specified, or NULL otherwise.
bool matchesShort(const std::string& option) const;
/// Returns true if the given option string matches the
/// short name.
@ -214,7 +214,7 @@ public:
///
/// The option string must partially match the full
/// name (case insensitive).
void process(const std::string& option, std::string& arg) const;
/// Verifies that the given option string matches the
/// requirements of the option, and extracts the option argument,
@ -225,7 +225,7 @@ public:
///
/// Throws a MissingArgumentException if a required argument
/// is missing. Throws an UnexpectedArgumentException if an
/// argument has been found, but none is expected.
/// argument has been found, but none is expected.
private:
std::string _shortName;
@ -253,19 +253,19 @@ inline const std::string& Option::shortName() const
return _shortName;
}
inline const std::string& Option::fullName() const
{
return _fullName;
}
inline const std::string& Option::description() const
{
return _description;
}
inline bool Option::required() const
{
return _required;
@ -277,13 +277,13 @@ inline bool Option::repeatable() const
return _repeatable;
}
inline bool Option::takesArgument() const
{
return !_argName.empty();
}
inline bool Option::argumentRequired() const
{
return _argRequired;

View File

@ -27,13 +27,12 @@ namespace Poco {
namespace Util {
Option::Option():
_required(false),
_repeatable(false),
Option::Option():
_required(false),
_repeatable(false),
_argRequired(false),
_pValidator(0),
_pCallback(0),
_pConfig(0)
_pCallback(0)
{
}
@ -54,7 +53,6 @@ Option::Option(const Option& option):
{
if (_pValidator) _pValidator->duplicate();
if (_pCallback) _pCallback = _pCallback->clone();
if (_pConfig) _pConfig->duplicate();
}
@ -65,8 +63,7 @@ Option::Option(const std::string& fullName, const std::string& shortName):
_repeatable(false),
_argRequired(false),
_pValidator(0),
_pCallback(0),
_pConfig(0)
_pCallback(0)
{
}
@ -79,8 +76,7 @@ Option::Option(const std::string& fullName, const std::string& shortName, const
_repeatable(false),
_argRequired(false),
_pValidator(0),
_pCallback(0),
_pConfig(0)
_pCallback(0)
{
}
@ -94,8 +90,7 @@ Option::Option(const std::string& fullName, const std::string& shortName, const
_argName(argName),
_argRequired(argRequired),
_pValidator(0),
_pCallback(0),
_pConfig(0)
_pCallback(0)
{
}
@ -103,7 +98,6 @@ Option::Option(const std::string& fullName, const std::string& shortName, const
Option::~Option()
{
if (_pValidator) _pValidator->release();
if (_pConfig) _pConfig->release();
delete _pCallback;
}
@ -135,7 +129,7 @@ void Option::swap(Option& option)
std::swap(_pConfig, option._pConfig);
}
Option& Option::shortName(const std::string& name)
{
_shortName = name;
@ -149,14 +143,14 @@ Option& Option::fullName(const std::string& name)
return *this;
}
Option& Option::description(const std::string& text)
{
_description = text;
return *this;
}
Option& Option::required(bool flag)
{
_required = flag;
@ -170,7 +164,7 @@ Option& Option::repeatable(bool flag)
return *this;
}
Option& Option::argument(const std::string& name, bool required)
{
_argName = name;
@ -178,7 +172,7 @@ Option& Option::argument(const std::string& name, bool required)
return *this;
}
Option& Option::noArgument()
{
_argName.clear();
@ -200,12 +194,10 @@ Option& Option::binding(const std::string& propertyName)
}
Option& Option::binding(const std::string& propertyName, AbstractConfiguration* pConfig)
Option& Option::binding(const std::string& propertyName, AbstractConfiguration::Ptr pConfig)
{
_binding = propertyName;
if (_pConfig) _pConfig->release();
_pConfig = pConfig;
if (_pConfig) _pConfig->duplicate();
return *this;
}
@ -227,7 +219,7 @@ Option& Option::validator(Validator* pValidator)
bool Option::matchesShort(const std::string& option) const
{
return option.length() > 0
return option.length() > 0
&& !_shortName.empty() && option.compare(0, _shortName.length(), _shortName) == 0;
}
@ -245,7 +237,7 @@ bool Option::matchesPartial(const std::string& option) const
{
std::string::size_type pos = option.find_first_of(":=");
std::string::size_type len = pos == std::string::npos ? option.length() : pos;
return option.length() > 0
return option.length() > 0
&& icompare(option, 0, len, _fullName, 0, len) == 0;
}