From 5f96c27e9714e230ed2255bc7090afe785b02bab Mon Sep 17 00:00:00 2001 From: "Marco A. Gutierrez" Date: Thu, 15 Sep 2022 08:14:48 +0000 Subject: [PATCH 1/5] updating Element calls to use Errors Signed-off-by: Marco A. Gutierrez --- include/sdf/Element.hh | 249 +++++++++++++++++++++++++++++++++++++++-- src/Element.cc | 240 +++++++++++++++++++++++++++++++-------- 2 files changed, 435 insertions(+), 54 deletions(-) diff --git a/include/sdf/Element.hh b/include/sdf/Element.hh index 1afc35799..36b704c43 100644 --- a/include/sdf/Element.hh +++ b/include/sdf/Element.hh @@ -161,12 +161,26 @@ namespace sdf /// \param[in] _prefix String value to prefix to the output. public: void PrintDescription(const std::string &_prefix) const; + /// \brief Output Element's description to stdout. + /// \param[in] _prefix String value to prefix to the output. + /// \param[out] _errors Vector of errors. + public: void PrintDescription(const std::string &_prefix, + sdf::Errors &_errors) const; + /// \brief Output Element's values to stdout. /// \param[in] _prefix String value to prefix to the output. /// \param[in] _config Configuration for printing the values. public: void PrintValues(std::string _prefix, const PrintConfig &_config = PrintConfig()) const; + /// \brief Output Element's values to stdout. + /// \param[out] _errors Vector of errors. + /// \param[in] _prefix String value to prefix to the output. + /// \param[in] _config Configuration for printing the values. + public: void PrintValues(sdf::Errors &_errors, + std::string _prefix, + const PrintConfig &_config = PrintConfig()) const; + /// \brief Output Element's values to stdout. /// \param[in] _prefix String value to prefix to the output. /// \param[in] _includeDefaultElements flag to print default elements. @@ -177,6 +191,18 @@ namespace sdf bool _includeDefaultAttributes, const PrintConfig &_config = PrintConfig()) const; + /// \brief Output Element's values to stdout. + /// \param[out] _errors Vector of errors. + /// \param[in] _prefix String value to prefix to the output. + /// \param[in] _includeDefaultElements flag to print default elements. + /// \param[in] _includeDefaultAttributes flag to print default attributes. + /// \param[in] _config Configuration for printing the values. + public: void PrintValues(sdf::Errors &_errors, + const std::string &_prefix, + bool _includeDefaultElements, + bool _includeDefaultAttributes, + const PrintConfig &_config = PrintConfig()) const; + /// \brief Helper function for SDF::PrintDoc /// /// This generates the SDF html documentation. @@ -194,24 +220,60 @@ namespace sdf public: void PrintDocRightPane(std::string &_html, int _spacing, int &_index) const; + /// \brief Helper function for SDF::PrintDoc + /// + /// This generates the SDF html documentation. + /// \param[out] _html Accumulated HTML for output. + /// \param[in] _spacing Amount of spacing for this element. + /// \param[out] _errors Vector of errors. + public: void PrintDocRightPane(std::string &_html, int _spacing, + int &_index, sdf::Errors &_errors) const; + + /// \brief Convert the element values to a string representation. + /// \param[in] _prefix String value to prefix to the output. + /// \param[in] _config Configuration for printing the values. + /// \return The string representation. + public: std::string ToString( + const std::string &_prefix, + const PrintConfig &_config = PrintConfig()) const; + /// \brief Convert the element values to a string representation. + /// \param[out] _errors Vector of errors. /// \param[in] _prefix String value to prefix to the output. /// \param[in] _config Configuration for printing the values. /// \return The string representation. + public: std::string ToString( + sdf::Errors &_errors, + const std::string &_prefix, + const PrintConfig &_config = PrintConfig()) const; + + /// \brief Convert the element values to a string representation. + /// Current behavior of ToString(const std::string &_prefix) can be + /// achieved by calling this function with _includeDefaultElements=true + /// and _includeDefaultAttributes=false + /// \param[in] _prefix String value to prefix to the output. + /// \param[in] _includeDefaultElements flag to include default elements. + /// \param[in] _includeDefaultAttributes flag to include default attributes. + /// \param[in] _config Configuration for converting to string. + /// \return The string representation. public: std::string ToString( const std::string &_prefix, + bool _includeDefaultElements, + bool _includeDefaultAttributes, const PrintConfig &_config = PrintConfig()) const; /// \brief Convert the element values to a string representation. /// Current behavior of ToString(const std::string &_prefix) can be /// achieved by calling this function with _includeDefaultElements=true /// and _includeDefaultAttributes=false + /// \param[out] _errors Vector of errors. /// \param[in] _prefix String value to prefix to the output. /// \param[in] _includeDefaultElements flag to include default elements. /// \param[in] _includeDefaultAttributes flag to include default attributes. /// \param[in] _config Configuration for converting to string. /// \return The string representation. public: std::string ToString( + sdf::Errors &_errors, const std::string &_prefix, bool _includeDefaultElements, bool _includeDefaultAttributes, @@ -371,6 +433,17 @@ namespace sdf public: std::any GetAny(sdf::Errors &_errors, const std::string &_key = "") const; + /// \brief Get the value of a key. This function assumes the _key + /// exists. + /// \param[out] _errors Vector of errors. + /// \param[in] _key the name of a child attribute or element. + /// \return The value of the _key. + /// \sa std::pair Get(const std::string &_key, + /// const T &_defaultValue) + public: template + T Get(sdf::Errors &_errors, + const std::string &_key = "") const; + /// \brief Get the value of a key. This function assumes the _key /// exists. /// \param[in] _key the name of a child attribute or element. @@ -381,6 +454,17 @@ namespace sdf T Get(const std::string &_key = "") const; /// \brief Get the value of a key. + /// \param[out] _errors Vector of errors. + /// \param[in] _key the name of a child attribute or element. + /// \param[in] _defaultValue a default value to use if _key is not + /// found. + /// \return A pair where the first element is the value of _key, and the + /// second element is true when the _key was found and false otherwise. + public: template + std::pair Get(sdf::Errors &_errors, + const std::string &_key, + const T &_defaultValue) const; + /// \brief Get the value of a key. /// \param[in] _key the name of a child attribute or element. /// \param[in] _defaultValue a default value to use if _key is not /// found. @@ -401,12 +485,32 @@ namespace sdf T &_param, const T &_defaultValue) const; + /// \brief Get the value of a key. + /// \param[out] _errors Vector of errors. + /// \param[in] _key the name of a child attribute or element. + /// \param[out] _param the parameter output + /// \param[in] _defaultValue a default value to use if _key is not + /// found. + /// \return True when the _key was found and false otherwise. + public: template + bool Get(sdf::Errors &_errors, + const std::string &_key, + T &_param, + const T &_defaultValue) const; + /// \brief Set the value of this element. /// \param[in] _value the value to set. /// \return True if the value was successfully set, false otherwise. public: template bool Set(const T &_value); + /// \brief Set the value of this element. + /// \param[in] _value the value to set. + /// \param[out] _errors Vector of errors. + /// \return True if the value was successfully set, false otherwise. + public: template + bool Set(const T &_value, sdf::Errors &_errors); + /// \brief Return true if the named element exists. /// \param[in] _name the name of the element to look for. /// \return True if the named element was found, false otherwise. @@ -443,9 +547,35 @@ namespace sdf /// names. Also return true if no elements of the specified type are found. public: bool HasUniqueChildNames(const std::string &_type = "") const; + /// \brief Checks whether any child elements of the specified element type + /// have identical name attribute values and returns false if so. + /// \param[out] _errors Vector of errors. + /// \param[in] _type The type of Element to check. If empty, check names + /// of all child elements. + /// \return True if all child elements with name attributes of the + /// specified type have unique names, return false if there are duplicated + /// names. Also return true if no elements of the specified type are found. + public: bool HasUniqueChildNames(sdf::Errors &_errors, + const std::string &_type = "") const; + + /// \brief Checks whether any child elements of the specified element type, + /// except those listed in \p _ignoreElements, have identical name attribute + /// values and returns false if so. + /// \param[in] _type The type of Element to check. If empty, check names + /// of all child elements. + /// \param[in] _ignoreElements A list of child element types to ignore when + /// checking for uniqueness. + /// \return True if all child elements with name attributes of the + /// specified type have unique names, return false if there are duplicated + /// names. Also return true if no elements of the specified type are found. + public: bool HasUniqueChildNames( + const std::string &_type, + const std::vector &_ignoreElements) const; + /// \brief Checks whether any child elements of the specified element type, /// except those listed in \p _ignoreElements, have identical name attribute /// values and returns false if so. + /// \param[out] _errors Vector of errors. /// \param[in] _type The type of Element to check. If empty, check names /// of all child elements. /// \param[in] _ignoreElements A list of child element types to ignore when @@ -454,6 +584,7 @@ namespace sdf /// specified type have unique names, return false if there are duplicated /// names. Also return true if no elements of the specified type are found. public: bool HasUniqueChildNames( + sdf::Errors &_errors, const std::string &_type, const std::vector &_ignoreElements) const; @@ -467,6 +598,18 @@ namespace sdf public: std::map CountNamedElements(const std::string &_type = "") const; + /// \brief Count the number of child elements of the specified element type + /// that have the same name attribute value. + /// \param[out] _errors Vector of errors. + /// \param[in] _type The type of Element to check. If empty, count names + /// of all child elements. + /// \return Map from Element names to a count of how many times the name + /// occurs. The count should never be 0. If all 2nd values are 1, then + /// there are exclusively unique names. + public: std::map + CountNamedElements(sdf::Errors &_errors, + const std::string &_type = "") const; + /// \brief Count the number of child elements of the specified element type /// that have the same name attribute value with the exception of elements /// listed in \p _ignoreElements. @@ -481,6 +624,22 @@ namespace sdf const std::string &_type, const std::vector &_ignoreElements) const; + /// \brief Count the number of child elements of the specified element type + /// that have the same name attribute value with the exception of elements + /// listed in \p _ignoreElements. + /// \param[out] _errors Vector of errors. + /// \param[in] _type The type of Element to check. If empty, count names + /// of all child elements. + /// \param[in] _ignoreElements A list of child element types to ignore when + /// checking for uniqueness. + /// \return Map from Element names to a count of how many times the name + /// occurs. The count should never be 0. If all 2nd values are 1, then + /// there are exclusively unique names. + public: std::map CountNamedElements( + sdf::Errors &_errors, + const std::string &_type, + const std::vector &_ignoreElements) const; + /// \brief Return a pointer to the child element with the provided name. /// /// A new child element, with the provided name, is added to this element @@ -575,6 +734,11 @@ namespace sdf /// the embedded Param. public: void Update(); + /// \brief Call the Update() callback on each element, as well as + /// the embedded Param. + /// \param[out] _errors Vector of errors. + public: void Update(sdf::Errors &_errors); + /// \brief Call reset on each element and element description /// before deleting all of them. Also clear out the /// embedded Param. @@ -661,16 +825,18 @@ namespace sdf public: static std::vector NameUniquenessExceptions(); /// \brief Generate a string (XML) representation of this object. + /// \param[out] _out the std::ostreamstream to write output to. + /// \param[out] _errors Vector of errors. /// \param[in] _prefix arbitrary prefix to put on the string. /// \param[in] _includeDefaultElements flag to include default elements. /// \param[in] _includeDefaultAttributes flag to include default attributes. /// \param[in] _config Configuration for converting to string. - /// \param[out] _out the std::ostreamstream to write output to. - private: void ToString(const std::string &_prefix, + private: void ToString(std::ostringstream &_out, + sdf::Errors &_errors, + const std::string &_prefix, bool _includeDefaultElements, bool _includeDefaultAttributes, - const PrintConfig &_config, - std::ostringstream &_out) const; + const PrintConfig &_config) const; /// \brief Generate a string (XML) representation of this object. /// \param[in] _prefix arbitrary prefix to put on the string. @@ -678,11 +844,13 @@ namespace sdf /// \param[in] _includeDefaultAttributes flag to include default attributes. /// \param[in] _config Configuration for printing values. /// \param[out] _out the std::ostringstream to write output to. + /// \param[out] _errors Vector of errors. private: void PrintValuesImpl(const std::string &_prefix, bool _includeDefaultElements, bool _includeDefaultAttributes, const PrintConfig &_config, - std::ostringstream &_out) const; + std::ostringstream &_out, + sdf::Errors &_errors) const; /// \brief Create a new Param object and return it. /// \param[in] _key Key for the parameter. @@ -782,8 +950,29 @@ namespace sdf public: void PrintAttributes(bool _includeDefaultAttributes, const PrintConfig &_config, std::ostringstream &_out) const; + + /// \brief Generate the string (XML) for the attributes. + /// \param[in] _includeDefaultAttributes flag to include default attributes. + /// \param[in] _config Configuration for printing attributes. + /// \param[out] _out the std::ostringstream to write output to. + /// \param[out] _errors Vector of errors. + public: void PrintAttributes(bool _includeDefaultAttributes, + const PrintConfig &_config, + std::ostringstream &_out, + sdf::Errors &_errors) const; }; + /////////////////////////////////////////////// + template + T Element::Get(sdf::Errors &_errors, const std::string &_key) const + { + T result = T(); + + std::pair ret = this->Get(_errors, _key, result); + + return ret.first; + } + /////////////////////////////////////////////// template T Element::Get(const std::string &_key) const @@ -795,6 +984,18 @@ namespace sdf return ret.first; } + /////////////////////////////////////////////// + template + bool Element::Get(sdf::Errors &_errors, + const std::string &_key, + T &_param, + const T &_defaultValue) const + { + std::pair ret = this->Get(_errors, _key, _defaultValue); + _param = ret.first; + return ret.second; + } + /////////////////////////////////////////////// template bool Element::Get(const std::string &_key, @@ -810,27 +1011,42 @@ namespace sdf template std::pair Element::Get(const std::string &_key, const T &_defaultValue) const + { + sdf::Errors errors; + std::pair result = this->Get(errors, _key, _defaultValue); + for(auto& error : errors) + { + sdferr << error.Message(); + } + return result; + } + + /////////////////////////////////////////////// + template + std::pair Element::Get(sdf::Errors &_errors, + const std::string &_key, + const T &_defaultValue) const { std::pair result(_defaultValue, true); if (_key.empty() && this->dataPtr->value) { - this->dataPtr->value->Get(result.first); + this->dataPtr->value->Get(result.first, _errors); } else if (!_key.empty()) { ParamPtr param = this->GetAttribute(_key); if (param) { - param->Get(result.first); + param->Get(result.first, _errors); } else if (this->HasElement(_key)) { - result.first = this->GetElementImpl(_key)->Get(); + result.first = this->GetElementImpl(_key)->Get(_errors); } else if (this->HasElementDescription(_key)) { - result.first = this->GetElementDescription(_key)->Get(); + result.first = this->GetElementDescription(_key)->Get(_errors); } else { @@ -848,10 +1064,23 @@ namespace sdf /////////////////////////////////////////////// template bool Element::Set(const T &_value) + { + sdf::Errors errors; + bool result = this->Set(_value, errors); + for(auto& error : errors) + { + sdferr << error.Message(); + } + return result; + } + + /////////////////////////////////////////////// + template + bool Element::Set(const T &_value, sdf::Errors &_errors) { if (this->dataPtr->value) { - this->dataPtr->value->Set(_value); + this->dataPtr->value->Set(_value, _errors); return true; } return false; diff --git a/src/Element.cc b/src/Element.cc index 5dfc243c6..2bc5452f5 100644 --- a/src/Element.cc +++ b/src/Element.cc @@ -141,7 +141,7 @@ void Element::AddValue(const std::string &_type, sdf::Errors errors; this->dataPtr->value = this->CreateParam(this->dataPtr->name, _type, _defaultValue, _required, errors, _description); - throwOrPrintErrors(errors); + sdf::throwOrPrintErrors(errors); } ///////////////////////////////////////////////// @@ -166,7 +166,7 @@ void Element::AddValue(const std::string &_type, sdf::Errors errors; this->AddValue(_type, _defaultValue, _required, _minValue, _maxValue, errors, _description); - throwOrPrintErrors(errors); + sdf::throwOrPrintErrors(errors); } ///////////////////////////////////////////////// @@ -218,7 +218,7 @@ void Element::AddAttribute(const std::string &_key, sdf::Errors errors; this->AddAttribute(_key, _type, _defaultValue, _required, errors, _description); - throwOrPrintErrors(errors); + sdf::throwOrPrintErrors(errors); } ///////////////////////////////////////////////// @@ -239,7 +239,7 @@ ElementPtr Element::Clone() const { sdf::Errors errors; ElementPtr elem = this->Clone(errors); - throwOrPrintErrors(errors); + sdf::throwOrPrintErrors(errors); return elem; } @@ -277,13 +277,13 @@ ElementPtr Element::Clone(sdf::Errors &_errors) const for (eiter = this->dataPtr->elementDescriptions.begin(); eiter != this->dataPtr->elementDescriptions.end(); ++eiter) { - clone->dataPtr->elementDescriptions.push_back((*eiter)->Clone()); + clone->dataPtr->elementDescriptions.push_back((*eiter)->Clone(_errors)); } for (eiter = this->dataPtr->elements.begin(); eiter != this->dataPtr->elements.end(); ++eiter) { - clone->dataPtr->elements.push_back((*eiter)->Clone()); + clone->dataPtr->elements.push_back((*eiter)->Clone(_errors)); clone->dataPtr->elements.back()->SetParent(clone); } @@ -314,7 +314,7 @@ void Element::Copy(const ElementPtr _elem) { sdf::Errors errors; this->Copy(_elem, errors); - throwOrPrintErrors(errors); + sdf::throwOrPrintErrors(errors); } ///////////////////////////////////////////////// @@ -404,6 +404,15 @@ void Element::Copy(const ElementPtr _elem, sdf::Errors &_errors) ///////////////////////////////////////////////// void Element::PrintDescription(const std::string &_prefix) const +{ + sdf::Errors errors; + this->PrintDescription(_prefix, errors); + sdf::throwOrPrintErrors(errors); +} + +///////////////////////////////////////////////// +void Element::PrintDescription(const std::string &_prefix, + sdf::Errors &_errors) const { std::cout << _prefix << "dataPtr->value->GetDefaultAsString(_errors) << "'"; - auto minValue = this->dataPtr->value->GetMinValueAsString(); + auto minValue = this->dataPtr->value->GetMinValueAsString(_errors); if (minValue.has_value()) { std::cout << " min ='" << *minValue << "'"; } - auto maxValue = this->dataPtr->value->GetMaxValueAsString(); + auto maxValue = this->dataPtr->value->GetMaxValueAsString(_errors); if (maxValue.has_value()) { std::cout << " max ='" << *maxValue << "'"; @@ -439,7 +449,7 @@ void Element::PrintDescription(const std::string &_prefix) const { std::cout << _prefix << " \n"; std::cout << _prefix << " GetDescription() @@ -464,7 +474,7 @@ void Element::PrintDescription(const std::string &_prefix) const for (eiter = this->dataPtr->elementDescriptions.begin(); eiter != this->dataPtr->elementDescriptions.end(); ++eiter) { - (*eiter)->PrintDescription(_prefix + " "); + (*eiter)->PrintDescription(_prefix + " ", _errors); } std::cout << _prefix << "\n"; @@ -473,6 +483,15 @@ void Element::PrintDescription(const std::string &_prefix) const ///////////////////////////////////////////////// void Element::PrintDocRightPane(std::string &_html, int _spacing, int &_index) const +{ + sdf::Errors errors; + this->PrintDocRightPane(_html, _spacing, _index, errors); + sdf::throwOrPrintErrors(errors); +} + +///////////////////////////////////////////////// +void Element::PrintDocRightPane(std::string &_html, int _spacing, + int &_index, sdf::Errors &_errors) const { std::ostringstream stream; ElementPtr_V::iterator eiter; @@ -483,7 +502,7 @@ void Element::PrintDocRightPane(std::string &_html, int _spacing, for (eiter = this->dataPtr->elementDescriptions.begin(); eiter != this->dataPtr->elementDescriptions.end(); ++eiter) { - (*eiter)->PrintDocRightPane(childHTML, _spacing + 4, _index); + (*eiter)->PrintDocRightPane(childHTML, _spacing + 4, _index, _errors); } stream << "dataPtr->name << start @@ -512,7 +531,7 @@ void Element::PrintDocRightPane(std::string &_html, int _spacing, stream << this->dataPtr->value->GetTypeName() << "   \n" << "Default: " - << this->dataPtr->value->GetDefaultAsString() << '\n'; + << this->dataPtr->value->GetDefaultAsString(_errors) << '\n'; } else { @@ -552,7 +571,7 @@ void Element::PrintDocRightPane(std::string &_html, int _spacing, stream << "Type: " << (*aiter)->GetTypeName() << "   " << "Default: " - << (*aiter)->GetDefaultAsString() << "
"; + << (*aiter)->GetDefaultAsString(_errors) << "
"; stream << "\n"; stream << "\n"; @@ -598,17 +617,19 @@ void Element::PrintValuesImpl(const std::string &_prefix, bool _includeDefaultElements, bool _includeDefaultAttributes, const PrintConfig &_config, - std::ostringstream &_out) const + std::ostringstream &_out, + sdf::Errors &_errors) const { if (_config.PreserveIncludes() && this->GetIncludeElement() != nullptr) { - _out << this->GetIncludeElement()->ToString(_prefix, _config); + _out << this->GetIncludeElement()->ToString(_errors, _prefix, _config); } else if (this->GetExplicitlySetInFile() || _includeDefaultElements) { _out << _prefix << "<" << this->dataPtr->name; - this->dataPtr->PrintAttributes(_includeDefaultAttributes, _config, _out); + this->dataPtr->PrintAttributes( + _includeDefaultAttributes, _config, _out, _errors); if (this->dataPtr->elements.size() > 0) { @@ -617,11 +638,12 @@ void Element::PrintValuesImpl(const std::string &_prefix, for (eiter = this->dataPtr->elements.begin(); eiter != this->dataPtr->elements.end(); ++eiter) { - (*eiter)->ToString(_prefix + " ", + (*eiter)->ToString(_out, + _errors, + _prefix + " ", _includeDefaultElements, _includeDefaultAttributes, - _config, - _out); + _config); } _out << _prefix << "dataPtr->name << ">\n"; } @@ -629,7 +651,7 @@ void Element::PrintValuesImpl(const std::string &_prefix, { if (this->dataPtr->value) { - _out << ">" << this->dataPtr->value->GetAsString(_config) + _out << ">" << this->dataPtr->value->GetAsString(_errors, _config) << "dataPtr->name << ">\n"; } else @@ -644,6 +666,18 @@ void Element::PrintValuesImpl(const std::string &_prefix, void ElementPrivate::PrintAttributes(bool _includeDefaultAttributes, const PrintConfig &_config, std::ostringstream &_out) const +{ + sdf::Errors errors; + this->PrintAttributes(_includeDefaultAttributes, _config, + _out, errors); + sdf::throwOrPrintErrors(errors); +} + +///////////////////////////////////////////////// +void ElementPrivate::PrintAttributes(bool _includeDefaultAttributes, + const PrintConfig &_config, + std::ostringstream &_out, + sdf::Errors &_errors) const { // Attribute exceptions are used in the event of a non-default PrintConfig // which modifies the Attributes of this Element that are printed out. The @@ -678,17 +712,30 @@ void ElementPrivate::PrintAttributes(bool _includeDefaultAttributes, const auto it = attributeExceptions.find(key); if (it == attributeExceptions.end()) { - _out << " " << key << "='" << (*aiter)->GetAsString(_config) << "'"; + _out << " " << key << "='" + << (*aiter)->GetAsString(_errors, _config) << "'"; } } } } ///////////////////////////////////////////////// -void Element::PrintValues(std::string _prefix, const PrintConfig &_config) const +void Element::PrintValues(std::string _prefix, + const PrintConfig &_config) const { std::ostringstream ss; - PrintValuesImpl(_prefix, true, false, _config, ss); + sdf::Errors errors; + PrintValuesImpl(_prefix, true, false, _config, ss, errors); + sdf::throwOrPrintErrors(errors); + std::cout << ss.str(); +} + +///////////////////////////////////////////////// +void Element::PrintValues(sdf::Errors &_errors, std::string _prefix, + const PrintConfig &_config) const +{ + std::ostringstream ss; + PrintValuesImpl(_prefix, true, false, _config, ss, _errors); std::cout << ss.str(); } @@ -697,22 +744,54 @@ void Element::PrintValues(const std::string &_prefix, bool _includeDefaultElements, bool _includeDefaultAttributes, const PrintConfig &_config) const +{ + std::ostringstream ss; + sdf::Errors errors; + PrintValuesImpl(_prefix, + _includeDefaultElements, + _includeDefaultAttributes, + _config, + ss, + errors); + sdf::throwOrPrintErrors(errors); + std::cout << ss.str(); +} + +///////////////////////////////////////////////// +void Element::PrintValues(sdf::Errors &_errors, + const std::string &_prefix, + bool _includeDefaultElements, + bool _includeDefaultAttributes, + const PrintConfig &_config) const { std::ostringstream ss; PrintValuesImpl(_prefix, _includeDefaultElements, _includeDefaultAttributes, _config, - ss); + ss, + _errors); std::cout << ss.str(); } ///////////////////////////////////////////////// std::string Element::ToString(const std::string &_prefix, const PrintConfig &_config) const +{ + sdf::Errors errors; + std::ostringstream out; + this->ToString(out, errors, _prefix, true, false, _config); + sdf::throwOrPrintErrors(errors); + return out.str(); +} + +///////////////////////////////////////////////// +std::string Element::ToString(sdf::Errors &_errors, + const std::string &_prefix, + const PrintConfig &_config) const { std::ostringstream out; - this->ToString(_prefix, true, false, _config, out); + this->ToString(out, _errors, _prefix, true, false, _config); return out.str(); } @@ -722,27 +801,49 @@ std::string Element::ToString(const std::string &_prefix, bool _includeDefaultAttributes, const PrintConfig &_config) const { + sdf::Errors errors; std::ostringstream out; - this->ToString(_prefix, + this->ToString(out, + errors, + _prefix, _includeDefaultElements, _includeDefaultAttributes, - _config, - out); + _config); + sdf::throwOrPrintErrors(errors); return out.str(); } ///////////////////////////////////////////////// -void Element::ToString(const std::string &_prefix, +std::string Element::ToString(sdf::Errors &_errors, + const std::string &_prefix, + bool _includeDefaultElements, + bool _includeDefaultAttributes, + const PrintConfig &_config) const +{ + std::ostringstream out; + this->ToString(out, + _errors, + _prefix, + _includeDefaultElements, + _includeDefaultAttributes, + _config); + return out.str(); +} + +///////////////////////////////////////////////// +void Element::ToString(std::ostringstream &_out, + sdf::Errors &_errors, + const std::string &_prefix, bool _includeDefaultElements, bool _includeDefaultAttributes, - const PrintConfig &_config, - std::ostringstream &_out) const + const PrintConfig &_config) const { PrintValuesImpl(_prefix, _includeDefaultElements, _includeDefaultAttributes, _config, - _out); + _out, + _errors); } ///////////////////////////////////////////////// @@ -957,12 +1058,33 @@ bool Element::HasUniqueChildNames(const std::string &_type) const return this->HasUniqueChildNames(_type, {}); } +///////////////////////////////////////////////// +bool Element::HasUniqueChildNames( + sdf::Errors &_errors, + const std::string &_type) const +{ + return this->HasUniqueChildNames(_errors, _type, {}); +} + ///////////////////////////////////////////////// bool Element::HasUniqueChildNames( const std::string &_type, const std::vector &_ignoreElements) const { - auto namedElementsCount = this->CountNamedElements(_type, _ignoreElements); + sdf::Errors errors; + bool result = this->HasUniqueChildNames(errors, _type, _ignoreElements); + sdf::throwOrPrintErrors(errors); + return result; +} + +///////////////////////////////////////////////// +bool Element::HasUniqueChildNames( + sdf::Errors &_errors, + const std::string &_type, + const std::vector &_ignoreElements) const +{ + auto namedElementsCount = this->CountNamedElements( + _errors, _type, _ignoreElements); for (auto &iter : namedElementsCount) { if (iter.second > 1) @@ -982,6 +1104,26 @@ std::map Element::CountNamedElements( ///////////////////////////////////////////////// std::map Element::CountNamedElements( + sdf::Errors &_errors, + const std::string &_type) const +{ + return this->CountNamedElements(_errors, _type, {}); +} + +///////////////////////////////////////////////// +std::map Element::CountNamedElements( + const std::string &_type, + const std::vector &_ignoreElements) const +{ + sdf::Errors errors; + auto result = this->CountNamedElements(errors, _type, _ignoreElements); + sdf::throwOrPrintErrors(errors); + return result; +} + +///////////////////////////////////////////////// +std::map Element::CountNamedElements( + sdf::Errors &_errors, const std::string &_type, const std::vector &_ignoreElements) const { @@ -1006,7 +1148,8 @@ std::map Element::CountNamedElements( // Get("name") returns attribute value if it exists before checking // for the value of a child element , so it's safe to use // here since we've checked HasAttribute("name"). - std::string childNameAttributeValue = elem->Get("name"); + std::string childNameAttributeValue = elem->Get( + _errors, "name"); if (result.find(childNameAttributeValue) == result.end()) { result[childNameAttributeValue] = 1; @@ -1028,7 +1171,7 @@ ElementPtr Element::GetElement(const std::string &_name) { sdf::Errors errors; ElementPtr result = this->GetElement(_name, errors); - throwOrPrintErrors(errors); + sdf::throwOrPrintErrors(errors); return result; } @@ -1081,7 +1224,7 @@ ElementPtr Element::AddElement(const std::string &_name) { sdf::Errors errors; ElementPtr elem = this->AddElement(_name, errors); - throwOrPrintErrors(errors); + sdf::throwOrPrintErrors(errors); return elem; } @@ -1153,24 +1296,33 @@ void Element::ClearElements() this->dataPtr->elements.clear(); } + ///////////////////////////////////////////////// void Element::Update() +{ + sdf::Errors errors; + this->Update(errors); + sdf::throwOrPrintErrors(errors); +} + +///////////////////////////////////////////////// +void Element::Update(sdf::Errors &_errors) { for (sdf::Param_V::iterator iter = this->dataPtr->attributes.begin(); iter != this->dataPtr->attributes.end(); ++iter) { - (*iter)->Update(); + (*iter)->Update(_errors); } for (sdf::ElementPtr_V::iterator iter = this->dataPtr->elements.begin(); iter != this->dataPtr->elements.end(); ++iter) { - (*iter)->Update(); + (*iter)->Update(_errors); } if (this->dataPtr->value) { - this->dataPtr->value->Update(); + this->dataPtr->value->Update(_errors); } } @@ -1305,7 +1457,7 @@ void Element::RemoveChild(ElementPtr _child) { sdf::Errors errors; RemoveChild(_child, errors); - throwOrPrintErrors(errors); + sdf::throwOrPrintErrors(errors); } ///////////////////////////////////////////////// @@ -1334,7 +1486,7 @@ std::any Element::GetAny(const std::string &_key) const { sdf::Errors errors; std::any result = this->GetAny(errors, _key); - throwOrPrintErrors(errors); + sdf::throwOrPrintErrors(errors); return result; } @@ -1344,7 +1496,7 @@ std::any Element::GetAny(sdf::Errors &_errors, const std::string &_key) const std::any result; if (_key.empty() && this->dataPtr->value) { - if (!this->dataPtr->value->GetAny(result)) + if (!this->dataPtr->value->GetAny(result, _errors)) { _errors.push_back({ErrorCode::ELEMENT_ERROR, "Couldn't get element [" + this->GetName() + "] as std::any\n"}); From 8ebdbff1502f09598dfeba2e0a4652b258d8d4ea Mon Sep 17 00:00:00 2001 From: "Marco A. Gutierrez" Date: Fri, 16 Sep 2022 06:37:52 +0000 Subject: [PATCH 2/5] Adding sdf::Errors to Plugin function calls Signed-off-by: Marco A. Gutierrez --- include/sdf/Error.hh | 5 +++- include/sdf/Plugin.hh | 49 ++++++++++++++++++++++++++++++ src/Plugin.cc | 69 +++++++++++++++++++++++++++++++++++-------- src/Plugin_TEST.cc | 29 ++++++++++++++++++ 4 files changed, 138 insertions(+), 14 deletions(-) diff --git a/include/sdf/Error.hh b/include/sdf/Error.hh index b3c58f2a1..5dec4629b 100644 --- a/include/sdf/Error.hh +++ b/include/sdf/Error.hh @@ -166,8 +166,11 @@ namespace sdf /// This has been created to help preserve behavior. FATAL_ERROR, - /// \brief Generic warning saved as error due to WarningsPolicy config + /// \brief Generic warning saved as error due to WarningsPolicy config. WARNING, + + /// \brief Generic error that happened during parsing. + PARSING_ERROR }; class SDFORMAT_VISIBLE Error diff --git a/include/sdf/Plugin.hh b/include/sdf/Plugin.hh index 05fbc8a52..cec81aa77 100644 --- a/include/sdf/Plugin.hh +++ b/include/sdf/Plugin.hh @@ -68,6 +68,18 @@ namespace sdf public: Plugin(const std::string &_filename, const std::string &_name, const std::string &_xmlContent = ""); + /// \brief A constructor that initializes the plugin's filename, name, and + /// optionally the content. + /// \param[out] _errors Vector of errors. + /// \param[in] _filename Filename of the shared library associated with + /// this plugin. + /// \param[in] _name The name of the plugin. + /// \param[in] _xmlContent Optional XML content that will be stored in + /// this plugin. + public: Plugin(sdf::Errors &_errors, const std::string &_filename, + const std::string &_name, + const std::string &_xmlContent = ""); + /// \brief Load the plugin based on a element pointer. This is *not* the /// usual entry point. Typical usage of the SDF DOM is through the Root /// object. @@ -107,6 +119,14 @@ namespace sdf /// \param[in] _elem Element to insert. public: void InsertContent(const sdf::ElementPtr _elem); + /// \brief Insert an element into the plugin content. This does not + /// modify the values in the sdf::ElementPtr returned by the `Element()` + /// function. + /// \param[in] _elem Element to insert. + /// \param[out] _errors Vector of errors. + public: void InsertContent(const sdf::ElementPtr _elem, + sdf::Errors &_errors); + /// \brief Insert XML content into this plugin. This function does not /// modify the values in the sdf::ElementPtr returned by the `Element()` /// function. The provided content must be valid XML. @@ -116,6 +136,17 @@ namespace sdf /// content of this plugin is not modified. True otherwise public: bool InsertContent(const std::string _content); + /// \brief Insert XML content into this plugin. This function does not + /// modify the values in the sdf::ElementPtr returned by the `Element()` + /// function. The provided content must be valid XML. + /// \param[in] _content A string that contains valid XML. The XML is + /// inserted into this plugin if it is valid. + /// \param[out] _errors Vector of errors. + /// \return False if the provided content was invalid, in which case the + /// content of this plugin is not modified. True otherwise + public: bool InsertContent(const std::string _content, + sdf::Errors &_errors); + /// \brief Set the filename of the shared library. /// \param[in] _filename Filename of the shared library associated with /// this plugin. @@ -134,6 +165,14 @@ namespace sdf /// \return SDF element pointer with updated plugin values. public: sdf::ElementPtr ToElement() const; + /// \brief Create and return an SDF element filled with data from this + /// plugin. + /// Note that parameter passing functionality is not captured with this + /// function. + /// \param[out] _errors Vector of errors. + /// \return SDF element pointer with updated plugin values. + public: sdf::ElementPtr ToElement(sdf::Errors &_errors) const; + /// \brief Copy assignment operator /// \param[in] _plugin Plugin to copy /// \return A reference to this plugin @@ -188,6 +227,16 @@ namespace sdf return _in; } + /// \brief Initializer function to help Plugin constructors. + /// \param[out] _errors Vector of errors. + /// \param[in] _filename Filename of the shared library associated with + /// this plugin. + /// \param[in] _name The name of the plugin. + /// \param[in] _xmlContent Optional XML content that will be stored in + /// this plugin. + private: void Init(sdf::Errors &_errors, const std::string &_filename, + const std::string &_name, const std::string &_xmlContent); + /// \brief Private data pointer. std::unique_ptr dataPtr; }; diff --git a/src/Plugin.cc b/src/Plugin.cc index c3c325979..1cee91dfe 100644 --- a/src/Plugin.cc +++ b/src/Plugin.cc @@ -47,12 +47,28 @@ Plugin::Plugin() Plugin::Plugin(const std::string &_filename, const std::string &_name, const std::string &_xmlContent) : dataPtr(std::make_unique()) +{ + sdf::Errors errors; + this->Init(errors, _filename, _name, _xmlContent); + sdf::throwOrPrintErrors(errors); +} + +///////////////////////////////////////////////// +Plugin::Plugin(sdf::Errors &_errors, const std::string &_filename, + const std::string &_name, const std::string &_xmlContent) + : dataPtr(std::make_unique()) +{ + this->Init(_errors, _filename, _name, _xmlContent); +} + +void Plugin::Init(sdf::Errors &_errors, const std::string &_filename, + const std::string &_name, const std::string &_xmlContent) { this->SetFilename(_filename); this->SetName(_name); std::string trimmed = sdf::trim(_xmlContent); if (!trimmed.empty()) - this->InsertContent(trimmed); + this->InsertContent(trimmed, _errors); } ///////////////////////////////////////////////// @@ -102,7 +118,7 @@ Errors Plugin::Load(ElementPtr _sdf) // Read the filename std::pair filenamePair = - _sdf->Get("filename", this->dataPtr->filename); + _sdf->Get(errors, "filename", this->dataPtr->filename); this->dataPtr->filename = filenamePair.first; if (!filenamePair.second) { @@ -114,7 +130,7 @@ Errors Plugin::Load(ElementPtr _sdf) for (sdf::ElementPtr innerElem = _sdf->GetFirstElement(); innerElem; innerElem = innerElem->GetNextElement("")) { - this->dataPtr->contents.push_back(innerElem->Clone()); + this->dataPtr->contents.push_back(innerElem->Clone(errors)); } return errors; @@ -150,14 +166,22 @@ sdf::ElementPtr Plugin::Element() const return this->dataPtr->sdf; } -///////////////////////////////////////////////// sdf::ElementPtr Plugin::ToElement() const +{ + sdf::Errors errors; + auto result = this->ToElement(errors); + sdf::throwOrPrintErrors(errors); + return result; +} + +///////////////////////////////////////////////// +sdf::ElementPtr Plugin::ToElement(sdf::Errors &_errors) const { sdf::ElementPtr elem(new sdf::Element); sdf::initFile("plugin.sdf", elem); - elem->GetAttribute("name")->Set(this->Name()); - elem->GetAttribute("filename")->Set(this->Filename()); + elem->GetAttribute("name")->Set(this->Name(), _errors); + elem->GetAttribute("filename")->Set(this->Filename(), _errors); // Insert plugin content for (const sdf::ElementPtr &content : this->dataPtr->contents) @@ -181,18 +205,37 @@ const std::vector &Plugin::Contents() const ///////////////////////////////////////////////// void Plugin::InsertContent(const sdf::ElementPtr _elem) { - this->dataPtr->contents.push_back(_elem->Clone()); + sdf::Errors errors; + this->dataPtr->contents.push_back(_elem->Clone(errors)); + sdf::throwOrPrintErrors(errors); +} + +///////////////////////////////////////////////// +void Plugin::InsertContent(const sdf::ElementPtr _elem, sdf::Errors &_errors) +{ + this->dataPtr->contents.push_back(_elem->Clone(_errors)); } ///////////////////////////////////////////////// bool Plugin::InsertContent(const std::string _content) +{ + sdf::Errors errors; + bool result = this->InsertContent(_content, errors); + sdf::throwOrPrintErrors(errors); + return result; +} + +///////////////////////////////////////////////// +bool Plugin::InsertContent(const std::string _content, sdf::Errors &_errors) { // Read the XML content - auto xmlDoc = tinyxml2::XMLDocument(true, tinyxml2::COLLAPSE_WHITESPACE);; + auto xmlDoc = tinyxml2::XMLDocument(true, tinyxml2::COLLAPSE_WHITESPACE); xmlDoc.Parse(_content.c_str()); if (xmlDoc.Error()) { - sdferr << "Error parsing XML from string: " << xmlDoc.ErrorStr() << '\n'; + std::stringstream ss; + ss << "Error parsing XML from string: " << xmlDoc.ErrorStr(); + _errors.push_back({ErrorCode::PARSING_ERROR, ss.str()}); return false; } @@ -209,20 +252,20 @@ bool Plugin::InsertContent(const std::string _content) for (const tinyxml2::XMLAttribute *attribute = xml->FirstAttribute(); attribute; attribute = attribute->Next()) { - element->AddAttribute(attribute->Name(), "string", "", 1, ""); + element->AddAttribute(attribute->Name(), "string", "", 1, _errors, ""); element->GetAttribute(attribute->Name())->SetFromString( - attribute->Value()); + attribute->Value(), _errors); } // Copy the value if (xml->GetText() != nullptr) - element->AddValue("string", xml->GetText(), true); + element->AddValue("string", xml->GetText(), true, _errors); // Copy all children copyChildren(element, xml, false); // Add the element to this plugin - this->InsertContent(element); + this->InsertContent(element, _errors); } return true; diff --git a/src/Plugin_TEST.cc b/src/Plugin_TEST.cc index c04cd8694..734cbbfcf 100644 --- a/src/Plugin_TEST.cc +++ b/src/Plugin_TEST.cc @@ -19,6 +19,7 @@ #include "sdf/parser.hh" #include "sdf/Plugin.hh" #include "sdf/Element.hh" +#include "test_utils.hh" ///////////////////////////////////////////////// TEST(DOMPlugin, Construction) @@ -471,3 +472,31 @@ TEST(DOMPlugin, EqualityOperators) plugin.SetFilename("new-filename"); EXPECT_EQ(plugin, plugin2); } + +/////////////////////////////////////////////// +TEST(DOMPlugin, ErrorOutput) +{ + std::stringstream buffer; + sdf::testing::RedirectConsoleStream redir( + sdf::Console::Instance()->GetMsgStream(), &buffer); + + #ifdef _WIN32 + sdf::Console::Instance()->SetQuiet(false); + sdf::testing::ScopeExit revertSetQuiet( + [] + { + sdf::Console::Instance()->SetQuiet(true); + }); + #endif + + sdf::Errors errors; + sdf::Plugin Plugin(errors, "", "", "Not valid xml"); + ASSERT_EQ(errors.size(), 1u); + EXPECT_EQ(errors[0].Code(), sdf::ErrorCode::PARSING_ERROR); + EXPECT_NE(std::string::npos, errors[0].Message().find( + "Error parsing XML from string: Error=XML_ERROR_PARSING_TEXT ErrorID=10" + " (0xa) Line number=1")); + + // Check nothing has been printed + EXPECT_TRUE(buffer.str().empty()) << buffer.str(); +} From 1420a1580f463d8a595b6352e3746188a8e7cb09 Mon Sep 17 00:00:00 2001 From: "Marco A. Gutierrez" Date: Fri, 16 Sep 2022 07:58:52 +0000 Subject: [PATCH 3/5] Removing the xmlDoc.ErrorStr() from the test Signed-off-by: Marco A. Gutierrez --- src/Plugin_TEST.cc | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/Plugin_TEST.cc b/src/Plugin_TEST.cc index 734cbbfcf..c74122472 100644 --- a/src/Plugin_TEST.cc +++ b/src/Plugin_TEST.cc @@ -494,8 +494,7 @@ TEST(DOMPlugin, ErrorOutput) ASSERT_EQ(errors.size(), 1u); EXPECT_EQ(errors[0].Code(), sdf::ErrorCode::PARSING_ERROR); EXPECT_NE(std::string::npos, errors[0].Message().find( - "Error parsing XML from string: Error=XML_ERROR_PARSING_TEXT ErrorID=10" - " (0xa) Line number=1")); + "Error parsing XML from string: ")); // Check nothing has been printed EXPECT_TRUE(buffer.str().empty()) << buffer.str(); From 2bddc15acc7381653a766c4829dc748cb98689d1 Mon Sep 17 00:00:00 2001 From: "Marco A. Gutierrez" Date: Wed, 22 Mar 2023 11:05:25 +0000 Subject: [PATCH 4/5] Fixes to changes made by merge Signed-off-by: Marco A. Gutierrez --- include/sdf/Element.hh | 9 --------- src/Element.cc | 15 +++------------ 2 files changed, 3 insertions(+), 21 deletions(-) diff --git a/include/sdf/Element.hh b/include/sdf/Element.hh index c0060efb4..1f04c8a4a 100644 --- a/include/sdf/Element.hh +++ b/include/sdf/Element.hh @@ -221,15 +221,6 @@ namespace sdf public: void PrintDocRightPane(std::string &_html, int _spacing, int &_index) const; - /// \brief Helper function for SDF::PrintDoc - /// - /// This generates the SDF html documentation. - /// \param[out] _html Accumulated HTML for output. - /// \param[in] _spacing Amount of spacing for this element. - /// \param[out] _errors Vector of errors. - public: void PrintDocRightPane(std::string &_html, int _spacing, - int &_index, sdf::Errors &_errors) const; - /// \brief Convert the element values to a string representation. /// \param[in] _prefix String value to prefix to the output. /// \param[in] _config Configuration for printing the values. diff --git a/src/Element.cc b/src/Element.cc index 40f4f442a..9ded14004 100644 --- a/src/Element.cc +++ b/src/Element.cc @@ -457,15 +457,6 @@ void Element::PrintDescription(sdf::Errors &_errors, ///////////////////////////////////////////////// void Element::PrintDocRightPane(std::string &_html, int _spacing, int &_index) const -{ - sdf::Errors errors; - this->PrintDocRightPane(_html, _spacing, _index, errors); - sdf::throwOrPrintErrors(errors); -} - -///////////////////////////////////////////////// -void Element::PrintDocRightPane(std::string &_html, int _spacing, - int &_index, sdf::Errors &_errors) const { std::ostringstream stream; ElementPtr_V::iterator eiter; @@ -476,7 +467,7 @@ void Element::PrintDocRightPane(std::string &_html, int _spacing, for (eiter = this->dataPtr->elementDescriptions.begin(); eiter != this->dataPtr->elementDescriptions.end(); ++eiter) { - (*eiter)->PrintDocRightPane(childHTML, _spacing + 4, _index, _errors); + (*eiter)->PrintDocRightPane(childHTML, _spacing + 4, _index); } stream << "
dataPtr->name << start @@ -505,7 +496,7 @@ void Element::PrintDocRightPane(std::string &_html, int _spacing, stream << this->dataPtr->value->GetTypeName() << "   \n" << "Default: " - << this->dataPtr->value->GetDefaultAsString(_errors) << '\n'; + << this->dataPtr->value->GetDefaultAsString() << '\n'; } else { @@ -545,7 +536,7 @@ void Element::PrintDocRightPane(std::string &_html, int _spacing, stream << "Type: " << (*aiter)->GetTypeName() << "   " << "Default: " - << (*aiter)->GetDefaultAsString(_errors) << "
"; + << (*aiter)->GetDefaultAsString() << "
"; stream << "\n"; stream << "\n"; From 8c3b313dd521b130f3632777da6874608992e884 Mon Sep 17 00:00:00 2001 From: "Marco A. Gutierrez" Date: Thu, 23 Mar 2023 07:42:52 +0000 Subject: [PATCH 5/5] Change args order and fixes to keep ABI Signed-off-by: Marco A. Gutierrez --- include/sdf/Plugin.hh | 14 +++++++------- src/Plugin.cc | 12 ++++++------ 2 files changed, 13 insertions(+), 13 deletions(-) diff --git a/include/sdf/Plugin.hh b/include/sdf/Plugin.hh index cec81aa77..b7f790e40 100644 --- a/include/sdf/Plugin.hh +++ b/include/sdf/Plugin.hh @@ -122,10 +122,10 @@ namespace sdf /// \brief Insert an element into the plugin content. This does not /// modify the values in the sdf::ElementPtr returned by the `Element()` /// function. - /// \param[in] _elem Element to insert. /// \param[out] _errors Vector of errors. - public: void InsertContent(const sdf::ElementPtr _elem, - sdf::Errors &_errors); + /// \param[in] _elem Element to insert. + public: void InsertContent(sdf::Errors &_errors, + const sdf::ElementPtr _elem); /// \brief Insert XML content into this plugin. This function does not /// modify the values in the sdf::ElementPtr returned by the `Element()` @@ -139,13 +139,13 @@ namespace sdf /// \brief Insert XML content into this plugin. This function does not /// modify the values in the sdf::ElementPtr returned by the `Element()` /// function. The provided content must be valid XML. + /// \param[out] _errors Vector of errors. /// \param[in] _content A string that contains valid XML. The XML is /// inserted into this plugin if it is valid. - /// \param[out] _errors Vector of errors. /// \return False if the provided content was invalid, in which case the /// content of this plugin is not modified. True otherwise - public: bool InsertContent(const std::string _content, - sdf::Errors &_errors); + public: bool InsertContent(sdf::Errors &_errors, + const std::string _content); /// \brief Set the filename of the shared library. /// \param[in] _filename Filename of the shared library associated with @@ -238,7 +238,7 @@ namespace sdf const std::string &_name, const std::string &_xmlContent); /// \brief Private data pointer. - std::unique_ptr dataPtr; + public: std::unique_ptr dataPtr; }; /// \brief A vector of Plugin. diff --git a/src/Plugin.cc b/src/Plugin.cc index 1cee91dfe..c85563519 100644 --- a/src/Plugin.cc +++ b/src/Plugin.cc @@ -68,7 +68,7 @@ void Plugin::Init(sdf::Errors &_errors, const std::string &_filename, this->SetName(_name); std::string trimmed = sdf::trim(_xmlContent); if (!trimmed.empty()) - this->InsertContent(trimmed, _errors); + this->InsertContent(_errors, trimmed); } ///////////////////////////////////////////////// @@ -206,12 +206,12 @@ const std::vector &Plugin::Contents() const void Plugin::InsertContent(const sdf::ElementPtr _elem) { sdf::Errors errors; - this->dataPtr->contents.push_back(_elem->Clone(errors)); + this->InsertContent(errors, _elem); sdf::throwOrPrintErrors(errors); } ///////////////////////////////////////////////// -void Plugin::InsertContent(const sdf::ElementPtr _elem, sdf::Errors &_errors) +void Plugin::InsertContent(sdf::Errors &_errors, const sdf::ElementPtr _elem) { this->dataPtr->contents.push_back(_elem->Clone(_errors)); } @@ -220,13 +220,13 @@ void Plugin::InsertContent(const sdf::ElementPtr _elem, sdf::Errors &_errors) bool Plugin::InsertContent(const std::string _content) { sdf::Errors errors; - bool result = this->InsertContent(_content, errors); + bool result = this->InsertContent(errors, _content); sdf::throwOrPrintErrors(errors); return result; } ///////////////////////////////////////////////// -bool Plugin::InsertContent(const std::string _content, sdf::Errors &_errors) +bool Plugin::InsertContent(sdf::Errors &_errors, const std::string _content) { // Read the XML content auto xmlDoc = tinyxml2::XMLDocument(true, tinyxml2::COLLAPSE_WHITESPACE); @@ -265,7 +265,7 @@ bool Plugin::InsertContent(const std::string _content, sdf::Errors &_errors) copyChildren(element, xml, false); // Add the element to this plugin - this->InsertContent(element, _errors); + this->InsertContent(_errors, element); } return true;