diff --git a/src/App/Metadata.cpp b/src/App/Metadata.cpp index cc70eecf10..2504924797 100644 --- a/src/App/Metadata.cpp +++ b/src/App/Metadata.cpp @@ -1,24 +1,24 @@ -/*************************************************************************** - * Copyright (c) 2022 FreeCAD Project Association * - * * - * This file is part of the FreeCAD CAx development system. * - * * - * This library is free software; you can redistribute it and/or * - * modify it under the terms of the GNU Library General Public * - * License as published by the Free Software Foundation; either * - * version 2 of the License, or (at your option) any later version. * - * * - * This library is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Library General Public License for more details. * - * * - * You should have received a copy of the GNU Library General Public * - * License along with this library; see the file LICENSE.html. If not, * - * write to the Free Software Foundation, Inc., 59 Temple Place, * - * Suite 330, Boston, MA 02111-1307, USA * - * * - ***************************************************************************/ +/************************************************************************** +* * +* Copyright (c) 2021-2023 FreeCAD Project Association * +* * +* This file is part of FreeCAD. * +* * +* FreeCAD is free software: you can redistribute it and/or modify it * +* under the terms of the GNU Lesser General Public License as * +* published by the Free Software Foundation, either version 2.1 of the * +* License, or (at your option) any later version. * +* * +* FreeCAD is distributed in the hope that it will be useful, but * +* WITHOUT ANY WARRANTY; without even the implied warranty of * +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * +* Lesser General Public License for more details. * +* * +* You should have received a copy of the GNU Lesser General Public * +* License along with FreeCAD. If not, see * +* . * +* * +***************************************************************************/ #include "PreCompiled.h" @@ -64,13 +64,13 @@ namespace MetadataInternal { class XMLErrorHandler: public HandlerBase { - void warning(const SAXParseException &toCatch) override + void warning(const SAXParseException& toCatch) override { // Don't deal with warnings at all boost::ignore_unused(toCatch); } - void error(const SAXParseException &toCatch) override + void error(const SAXParseException& toCatch) override { std::stringstream message; message << "Error at file \"" << StrX(toCatch.getSystemId()) << "\", line " @@ -79,7 +79,7 @@ class XMLErrorHandler: public HandlerBase throw Base::XMLBaseException(message.str()); } - void fatalError(const SAXParseException &toCatch) override + void fatalError(const SAXParseException& toCatch) override { std::stringstream message; message << "Fatal error at file \"" << StrX(toCatch.getSystemId()) << "\", line " @@ -90,7 +90,8 @@ class XMLErrorHandler: public HandlerBase }; }// namespace MetadataInternal -Metadata::Metadata(const fs::path &metadataFile) +Metadata::Metadata(const fs::path& metadataFile) + : _dom(nullptr) { #if defined(FC_OS_WIN32) auto source = @@ -101,14 +102,19 @@ Metadata::Metadata(const fs::path &metadataFile) loadFromInputSource(source); } -Metadata::Metadata() : _dom(nullptr) {} +Metadata::Metadata() + : _dom(nullptr) +{} -Metadata::Metadata(const DOMNode *domNode, int format) : _dom(nullptr) +Metadata::Metadata(const DOMNode* domNode, int format) + : _dom(nullptr) { - auto element = dynamic_cast(domNode); + auto element = dynamic_cast(domNode); if (element) { switch (format) { - case 1: parseVersion1(element); break; + case 1: + parseVersion1(element); + break; default: throw Base::XMLBaseException( "package.xml format version is not supported by this version of FreeCAD"); @@ -159,47 +165,107 @@ void Metadata::loadFromInputSource(const InputSource& source) Metadata::~Metadata() = default; -std::string Metadata::name() const { return _name; } +std::string Metadata::name() const +{ + return _name; +} -Meta::Version Metadata::version() const { return _version; } +Meta::Version Metadata::version() const +{ + return _version; +} -std::string App::Metadata::date() const { return _date; } +std::string App::Metadata::date() const +{ + return _date; +} -std::string Metadata::description() const { return _description; } +std::string Metadata::description() const +{ + return _description; +} -std::vector Metadata::maintainer() const { return _maintainer; } +std::vector Metadata::maintainer() const +{ + return _maintainer; +} -std::vector Metadata::license() const { return _license; } +std::vector Metadata::license() const +{ + return _license; +} -std::vector Metadata::url() const { return _url; } +std::vector Metadata::url() const +{ + return _url; +} -std::vector Metadata::author() const { return _author; } +std::vector Metadata::author() const +{ + return _author; +} -std::vector Metadata::depend() const { return _depend; } +std::vector Metadata::depend() const +{ + return _depend; +} -std::vector Metadata::conflict() const { return _conflict; } +std::vector Metadata::conflict() const +{ + return _conflict; +} -std::vector Metadata::replace() const { return _replace; } +std::vector Metadata::replace() const +{ + return _replace; +} -std::vector Metadata::tag() const { return _tag; } +std::vector Metadata::tag() const +{ + return _tag; +} -fs::path Metadata::icon() const { return _icon; } +fs::path Metadata::icon() const +{ + return _icon; +} -std::string Metadata::classname() const { return _classname; } +std::string Metadata::classname() const +{ + return _classname; +} -boost::filesystem::path Metadata::subdirectory() const { return _subdirectory; } +boost::filesystem::path Metadata::subdirectory() const +{ + return _subdirectory; +} -std::vector Metadata::file() const { return _file; } +std::vector Metadata::file() const +{ + return _file; +} -Meta::Version Metadata::freecadmin() const { return _freecadmin; } +Meta::Version Metadata::freecadmin() const +{ + return _freecadmin; +} -Meta::Version Metadata::freecadmax() const { return _freecadmax; } +Meta::Version Metadata::freecadmax() const +{ + return _freecadmax; +} -Meta::Version Metadata::pythonmin() const { return _pythonmin; } +Meta::Version Metadata::pythonmin() const +{ + return _pythonmin; +} -std::multimap Metadata::content() const { return _content; } +std::multimap Metadata::content() const +{ + return _content; +} -std::vector Metadata::operator[](const std::string &tag) const +std::vector Metadata::operator[](const std::string& tag) const { std::vector returnValue; auto range = _genericMetadata.equal_range(tag); @@ -209,9 +275,12 @@ std::vector Metadata::operator[](const std::string &tag) return returnValue; } -XERCES_CPP_NAMESPACE::DOMElement *Metadata::dom() const { return _dom; } +XERCES_CPP_NAMESPACE::DOMElement* Metadata::dom() const +{ + return _dom; +} -void Metadata::setName(const std::string &name) +void Metadata::setName(const std::string& name) { std::string invalidCharacters = "/\\?%*:|\"<>";// Should cover all OSes if (_name.find_first_of(invalidCharacters) != std::string::npos) { @@ -220,160 +289,250 @@ void Metadata::setName(const std::string &name) _name = name; } -void Metadata::setVersion(const Meta::Version &version) { _version = version; } +void Metadata::setVersion(const Meta::Version& version) +{ + _version = version; +} -void App::Metadata::setDate(const std::string &date) { _date = date; } +void App::Metadata::setDate(const std::string& date) +{ + _date = date; +} -void Metadata::setDescription(const std::string &description) { _description = description; } +void Metadata::setDescription(const std::string& description) +{ + _description = description; +} -void Metadata::addMaintainer(const Meta::Contact &maintainer) { _maintainer.push_back(maintainer); } +void Metadata::addMaintainer(const Meta::Contact& maintainer) +{ + _maintainer.push_back(maintainer); +} -void Metadata::addLicense(const Meta::License &license) { _license.push_back(license); } +void Metadata::addLicense(const Meta::License& license) +{ + _license.push_back(license); +} -void Metadata::addUrl(const Meta::Url &url) { _url.push_back(url); } +void Metadata::addUrl(const Meta::Url& url) +{ + _url.push_back(url); +} -void Metadata::addAuthor(const Meta::Contact &author) { _author.push_back(author); } +void Metadata::addAuthor(const Meta::Contact& author) +{ + _author.push_back(author); +} -void Metadata::addDepend(const Meta::Dependency &dep) { _depend.push_back(dep); } +void Metadata::addDepend(const Meta::Dependency& dep) +{ + _depend.push_back(dep); +} -void Metadata::addConflict(const Meta::Dependency &dep) { _conflict.push_back(dep); } +void Metadata::addConflict(const Meta::Dependency& dep) +{ + _conflict.push_back(dep); +} -void Metadata::addReplace(const Meta::Dependency &dep) { _replace.push_back(dep); } +void Metadata::addReplace(const Meta::Dependency& dep) +{ + _replace.push_back(dep); +} -void Metadata::addTag(const std::string &tag) { _tag.push_back(tag); } +void Metadata::addTag(const std::string& tag) +{ + _tag.push_back(tag); +} -void Metadata::setIcon(const fs::path &path) { _icon = path; } +void Metadata::setIcon(const fs::path& path) +{ + _icon = path; +} -void Metadata::setClassname(const std::string &name) { _classname = name; } +void Metadata::setClassname(const std::string& name) +{ + _classname = name; +} -void Metadata::setSubdirectory(const boost::filesystem::path &path) { _subdirectory = path; } +void Metadata::setSubdirectory(const boost::filesystem::path& path) +{ + _subdirectory = path; +} -void Metadata::addFile(const fs::path &path) { _file.push_back(path); } +void Metadata::addFile(const fs::path& path) +{ + _file.push_back(path); +} -void Metadata::addContentItem(const std::string &tag, const Metadata &item) +void Metadata::addContentItem(const std::string& tag, const Metadata& item) { _content.insert(std::make_pair(tag, item)); } -void Metadata::setFreeCADMin(const Meta::Version &version) { _freecadmin = version; } +void Metadata::setFreeCADMin(const Meta::Version& version) +{ + _freecadmin = version; +} -void Metadata::setPythonMin(const Meta::Version &version) { _pythonmin = version; } +void Metadata::setPythonMin(const Meta::Version& version) +{ + _pythonmin = version; +} -void Metadata::setFreeCADMax(const Meta::Version &version) { _freecadmax = version; } +void Metadata::setFreeCADMax(const Meta::Version& version) +{ + _freecadmax = version; +} -void Metadata::addGenericMetadata(const std::string &tag, - const Meta::GenericMetadata &genericMetadata) +void Metadata::addGenericMetadata(const std::string& tag, + const Meta::GenericMetadata& genericMetadata) { _genericMetadata.insert(std::make_pair(tag, genericMetadata)); } -void Metadata::removeContentItem(const std::string &tag, const std::string &itemName) +void Metadata::removeContentItem(const std::string& tag, const std::string& itemName) { auto tagRange = _content.equal_range(tag); auto foundItem = - std::find_if(tagRange.first, tagRange.second, [&itemName](const auto &check) -> bool { + std::find_if(tagRange.first, tagRange.second, [&itemName](const auto& check) -> bool { return itemName == check.second.name(); }); - if (foundItem != tagRange.second) _content.erase(foundItem); + if (foundItem != tagRange.second) { + _content.erase(foundItem); + } } -void Metadata::removeMaintainer(const Meta::Contact &maintainer) +void Metadata::removeMaintainer(const Meta::Contact& maintainer) { auto new_end = std::remove(_maintainer.begin(), _maintainer.end(), maintainer); _maintainer.erase(new_end, _maintainer.end()); } -void Metadata::removeLicense(const Meta::License &license) +void Metadata::removeLicense(const Meta::License& license) { auto new_end = std::remove(_license.begin(), _license.end(), license); _license.erase(new_end, _license.end()); } -void Metadata::removeUrl(const Meta::Url &url) +void Metadata::removeUrl(const Meta::Url& url) { auto new_end = std::remove(_url.begin(), _url.end(), url); _url.erase(new_end, _url.end()); } -void Metadata::removeAuthor(const Meta::Contact &author) +void Metadata::removeAuthor(const Meta::Contact& author) { auto new_end = std::remove(_author.begin(), _author.end(), author); _author.erase(new_end, _author.end()); } -void Metadata::removeDepend(const Meta::Dependency &dep) +void Metadata::removeDepend(const Meta::Dependency& dep) { bool found = false; - for (const auto &check : _depend) { - if (dep == check) found = true; + for (const auto& check : _depend) { + if (dep == check) { + found = true; + } + } + if (!found) { + throw Base::RuntimeError("No match found for dependency to remove"); } - if (!found) throw Base::RuntimeError("No match found for dependency to remove"); auto new_end = std::remove(_depend.begin(), _depend.end(), dep); _depend.erase(new_end, _depend.end()); } -void Metadata::removeConflict(const Meta::Dependency &dep) +void Metadata::removeConflict(const Meta::Dependency& dep) { auto new_end = std::remove(_conflict.begin(), _conflict.end(), dep); _conflict.erase(new_end, _conflict.end()); } -void Metadata::removeReplace(const Meta::Dependency &dep) +void Metadata::removeReplace(const Meta::Dependency& dep) { auto new_end = std::remove(_replace.begin(), _replace.end(), dep); _replace.erase(new_end, _replace.end()); } -void Metadata::removeTag(const std::string &tag) +void Metadata::removeTag(const std::string& tag) { auto new_end = std::remove(_tag.begin(), _tag.end(), tag); _tag.erase(new_end, _tag.end()); } -void Metadata::removeFile(const boost::filesystem::path &path) +void Metadata::removeFile(const boost::filesystem::path& path) { auto new_end = std::remove(_file.begin(), _file.end(), path); _file.erase(new_end, _file.end()); } -void Metadata::clearContent() { _content.clear(); } +void Metadata::clearContent() +{ + _content.clear(); +} -void Metadata::clearMaintainer() { _maintainer.clear(); } +void Metadata::clearMaintainer() +{ + _maintainer.clear(); +} -void Metadata::clearLicense() { _license.clear(); } +void Metadata::clearLicense() +{ + _license.clear(); +} -void Metadata::clearUrl() { _url.clear(); } +void Metadata::clearUrl() +{ + _url.clear(); +} -void Metadata::clearAuthor() { _author.clear(); } +void Metadata::clearAuthor() +{ + _author.clear(); +} -void Metadata::clearDepend() { _depend.clear(); } +void Metadata::clearDepend() +{ + _depend.clear(); +} -void Metadata::clearConflict() { _conflict.clear(); } +void Metadata::clearConflict() +{ + _conflict.clear(); +} -void Metadata::clearReplace() { _replace.clear(); } +void Metadata::clearReplace() +{ + _replace.clear(); +} -void Metadata::clearTag() { _tag.clear(); } +void Metadata::clearTag() +{ + _tag.clear(); +} -void Metadata::clearFile() { _file.clear(); } +void Metadata::clearFile() +{ + _file.clear(); +} -DOMElement *appendSimpleXMLNode(DOMElement *baseNode, const std::string &nodeName, - const std::string &nodeContents) +DOMElement* appendSimpleXMLNode(DOMElement* baseNode, const std::string& nodeName, + const std::string& nodeContents) { // For convenience (and brevity of final output) don't create nodes that don't have contents if (nodeContents.empty()) { return nullptr; } auto doc = baseNode->getOwnerDocument(); - DOMElement *namedElement = doc->createElement(XUTF8Str(nodeName.c_str()).unicodeForm()); + DOMElement* namedElement = doc->createElement(XUTF8Str(nodeName.c_str()).unicodeForm()); baseNode->appendChild(namedElement); - DOMText *namedNode = doc->createTextNode(XUTF8Str(nodeContents.c_str()).unicodeForm()); + DOMText* namedNode = doc->createTextNode(XUTF8Str(nodeContents.c_str()).unicodeForm()); namedElement->appendChild(namedNode); return namedElement; } -void addAttribute(DOMElement *node, const std::string &key, const std::string &value) +void addAttribute(DOMElement* node, const std::string& key, const std::string& value) { if (value.empty()) { return; @@ -381,30 +540,40 @@ void addAttribute(DOMElement *node, const std::string &key, const std::string &v node->setAttribute(XUTF8Str(key.c_str()).unicodeForm(), XUTF8Str(value.c_str()).unicodeForm()); } -void addAttribute(DOMElement *node, const std::string &key, bool value) +void addAttribute(DOMElement* node, const std::string& key, bool value) { - if (value) + if (value) { node->setAttribute(XUTF8Str(key.c_str()).unicodeForm(), XUTF8Str("True").unicodeForm()); - else + } + else { node->setAttribute(XUTF8Str(key.c_str()).unicodeForm(), XUTF8Str("False").unicodeForm()); + } } -void addAttribute(DOMElement *node, const std::string &key, Meta::DependencyType value) +void addAttribute(DOMElement* node, const std::string& key, Meta::DependencyType value) { // Someday we should be able to change this to use reflection, but it's not yet // available (using C++17) std::string stringified("automatic"); switch (value) { - case Meta::DependencyType::automatic: stringified = "automatic"; break; - case Meta::DependencyType::internal: stringified = "internal"; break; - case Meta::DependencyType::addon: stringified = "addon"; break; - case Meta::DependencyType::python: stringified = "python"; break; + case Meta::DependencyType::automatic: + stringified = "automatic"; + break; + case Meta::DependencyType::internal: + stringified = "internal"; + break; + case Meta::DependencyType::addon: + stringified = "addon"; + break; + case Meta::DependencyType::python: + stringified = "python"; + break; } node->setAttribute(XUTF8Str(key.c_str()).unicodeForm(), XUTF8Str(stringified.c_str()).unicodeForm()); } -void addDependencyNode(DOMElement *root, const std::string &name, const Meta::Dependency &depend) +void addDependencyNode(DOMElement* root, const std::string& name, const Meta::Dependency& depend) { auto element = appendSimpleXMLNode(root, name, depend.package); if (element) { @@ -419,34 +588,37 @@ void addDependencyNode(DOMElement *root, const std::string &name, const Meta::De } } -void Metadata::write(const fs::path &file) const +void Metadata::write(const fs::path& file) const { - DOMImplementation *impl = + DOMImplementation* impl = DOMImplementationRegistry::getDOMImplementation(XUTF8Str("Core LS").unicodeForm()); - DOMDocument *doc = impl->createDocument(nullptr, XUTF8Str("package").unicodeForm(), nullptr); - DOMElement *root = doc->getDocumentElement(); + DOMDocument* doc = impl->createDocument(nullptr, XUTF8Str("package").unicodeForm(), nullptr); + DOMElement* root = doc->getDocumentElement(); root->setAttribute(XUTF8Str("format").unicodeForm(), XUTF8Str("1").unicodeForm()); root->setAttribute(XUTF8Str("xmlns").unicodeForm(), XUTF8Str("https://wiki.freecad.org/Package_Metadata").unicodeForm()); appendToElement(root); - DOMLSSerializer *theSerializer = ((DOMImplementationLS *)impl)->createLSSerializer(); - DOMConfiguration *config = theSerializer->getDomConfig(); - if (config->canSetParameter(XMLUni::fgDOMWRTFormatPrettyPrint, true)) + DOMLSSerializer* theSerializer = ((DOMImplementationLS*)impl)->createLSSerializer(); + DOMConfiguration* config = theSerializer->getDomConfig(); + if (config->canSetParameter(XMLUni::fgDOMWRTFormatPrettyPrint, true)) { config->setParameter(XMLUni::fgDOMWRTFormatPrettyPrint, true); + } // set feature if the serializer supports the feature/mode - if (config->canSetParameter(XMLUni::fgDOMWRTSplitCdataSections, true)) + if (config->canSetParameter(XMLUni::fgDOMWRTSplitCdataSections, true)) { config->setParameter(XMLUni::fgDOMWRTSplitCdataSections, true); + } - if (config->canSetParameter(XMLUni::fgDOMWRTDiscardDefaultContent, true)) + if (config->canSetParameter(XMLUni::fgDOMWRTDiscardDefaultContent, true)) { config->setParameter(XMLUni::fgDOMWRTDiscardDefaultContent, true); + } try { - XMLFormatTarget *myFormTarget = new LocalFileFormatTarget(file.string().c_str()); - DOMLSOutput *theOutput = ((DOMImplementationLS *)impl)->createLSOutput(); + XMLFormatTarget* myFormTarget = new LocalFileFormatTarget(file.string().c_str()); + DOMLSOutput* theOutput = ((DOMImplementationLS*)impl)->createLSOutput(); theOutput->setByteStream(myFormTarget); theSerializer->write(doc, theOutput); @@ -455,14 +627,14 @@ void Metadata::write(const fs::path &file) const theSerializer->release(); delete myFormTarget; } - catch (const XMLException &toCatch) { - char *message = XMLString::transcode(toCatch.getMessage()); + catch (const XMLException& toCatch) { + char* message = XMLString::transcode(toCatch.getMessage()); std::string what = message; XMLString::release(&message); throw Base::XMLBaseException(what); } - catch (const DOMException &toCatch) { - char *message = XMLString::transcode(toCatch.getMessage()); + catch (const DOMException& toCatch) { + char* message = XMLString::transcode(toCatch.getMessage()); std::string what = message; XMLString::release(&message); throw Base::XMLBaseException(what); @@ -471,7 +643,7 @@ void Metadata::write(const fs::path &file) const doc->release(); } -bool Metadata::satisfies(const Meta::Dependency &dep) +bool Metadata::satisfies(const Meta::Dependency& dep) { if (dep.package != _name) { return false; @@ -481,12 +653,12 @@ bool Metadata::satisfies(const Meta::Dependency &dep) if (!dep.condition.empty()) { auto injectedString = dep.condition; std::map replacements; - std::map &config = App::Application::Config(); + std::map& config = App::Application::Config(); replacements.insert(std::make_pair("$BuildVersionMajor", config["BuildVersionMajor"])); replacements.insert(std::make_pair("$BuildVersionMinor", config["BuildVersionMinor"])); replacements.insert(std::make_pair("$BuildVersionMinor", config["BuildVersionPoint"])); replacements.insert(std::make_pair("$BuildRevision", config["BuildRevision"])); - for (const auto &replacement : replacements) { + for (const auto& replacement : replacements) { auto pos = injectedString.find(replacement.first); while (pos != std::string::npos) { injectedString.replace(pos, replacement.first.length(), replacement.second); @@ -532,61 +704,85 @@ bool Metadata::supportsCurrentFreeCAD() const { static auto fcVersion = Meta::Version(); if (fcVersion == Meta::Version()) { - std::map &config = App::Application::Config(); + std::map& config = App::Application::Config(); std::stringstream ss; - ss << config["BuildVersionMajor"] - << "." << config["BuildVersionMinor"] - << "." << config["BuildVersionPoint"] - << "." << (config["BuildRevision"].empty() ? "0" : config["BuildRevision"]); + ss << config["BuildVersionMajor"] << "." << config["BuildVersionMinor"] << "." + << config["BuildVersionPoint"] << "." + << (config["BuildRevision"].empty() ? "0" : config["BuildRevision"]); fcVersion = Meta::Version(ss.str()); } if (_freecadmin != Meta::Version() && _freecadmin > fcVersion) { return false; } - else if (_freecadmax != Meta::Version() && _freecadmax < fcVersion) { + if (_freecadmax != Meta::Version() && _freecadmax < fcVersion) { return false; } return true; } -void Metadata::appendToElement(DOMElement *root) const +void Metadata::appendToElement(DOMElement* root) const { appendSimpleXMLNode(root, "name", _name); appendSimpleXMLNode(root, "description", _description); - if (_version != Meta::Version()) + if (_version != Meta::Version()) { // Only append version if it's not 0.0.0 appendSimpleXMLNode(root, "version", _version.str()); + } - if (!_date.empty()) appendSimpleXMLNode(root, "date", _date); + if (!_date.empty()) { + appendSimpleXMLNode(root, "date", _date); + } - for (const auto &maintainer : _maintainer) { + for (const auto& maintainer : _maintainer) { auto element = appendSimpleXMLNode(root, "maintainer", maintainer.name); - if (element) addAttribute(element, "email", maintainer.email); + if (element) { + addAttribute(element, "email", maintainer.email); + } } - for (const auto &license : _license) { + for (const auto& license : _license) { auto element = appendSimpleXMLNode(root, "license", license.name); - if (element) addAttribute(element, "file", license.file.string()); + if (element) { + addAttribute(element, "file", license.file.string()); + } } - if (_freecadmin != Meta::Version()) appendSimpleXMLNode(root, "freecadmin", _freecadmin.str()); + if (_freecadmin != Meta::Version()) { + appendSimpleXMLNode(root, "freecadmin", _freecadmin.str()); + } - if (_freecadmax != Meta::Version()) appendSimpleXMLNode(root, "freecadmax", _freecadmax.str()); + if (_freecadmax != Meta::Version()) { + appendSimpleXMLNode(root, "freecadmax", _freecadmax.str()); + } - if (_pythonmin != Meta::Version()) appendSimpleXMLNode(root, "pythonmin", _pythonmin.str()); + if (_pythonmin != Meta::Version()) { + appendSimpleXMLNode(root, "pythonmin", _pythonmin.str()); + } - for (const auto &url : _url) { + for (const auto& url : _url) { auto element = appendSimpleXMLNode(root, "url", url.location); if (element) { std::string typeAsString("website"); switch (url.type) { - case Meta::UrlType::website: typeAsString = "website"; break; - case Meta::UrlType::repository: typeAsString = "repository"; break; - case Meta::UrlType::bugtracker: typeAsString = "bugtracker"; break; - case Meta::UrlType::readme: typeAsString = "readme"; break; - case Meta::UrlType::documentation: typeAsString = "documentation"; break; - case Meta::UrlType::discussion: typeAsString = "discussion"; break; + case Meta::UrlType::website: + typeAsString = "website"; + break; + case Meta::UrlType::repository: + typeAsString = "repository"; + break; + case Meta::UrlType::bugtracker: + typeAsString = "bugtracker"; + break; + case Meta::UrlType::readme: + typeAsString = "readme"; + break; + case Meta::UrlType::documentation: + typeAsString = "documentation"; + break; + case Meta::UrlType::discussion: + typeAsString = "discussion"; + break; } addAttribute(element, "type", typeAsString); if (url.type == Meta::UrlType::repository) { @@ -595,18 +791,28 @@ void Metadata::appendToElement(DOMElement *root) const } } - for (const auto &author : _author) { + for (const auto& author : _author) { auto element = appendSimpleXMLNode(root, "author", author.name); - if (element) addAttribute(element, "email", author.email); + if (element) { + addAttribute(element, "email", author.email); + } } - for (const auto &depend : _depend) addDependencyNode(root, "depend", depend); + for (const auto& depend : _depend) { + addDependencyNode(root, "depend", depend); + } - for (const auto &conflict : _conflict) addDependencyNode(root, "conflict", conflict); + for (const auto& conflict : _conflict) { + addDependencyNode(root, "conflict", conflict); + } - for (const auto &replace : _replace) addDependencyNode(root, "replace", replace); + for (const auto& replace : _replace) { + addDependencyNode(root, "replace", replace); + } - for (const auto &tag : _tag) appendSimpleXMLNode(root, "tag", tag); + for (const auto& tag : _tag) { + appendSimpleXMLNode(root, "tag", tag); + } appendSimpleXMLNode(root, "icon", _icon.string()); @@ -614,20 +820,23 @@ void Metadata::appendToElement(DOMElement *root) const appendSimpleXMLNode(root, "subdirectory", _subdirectory.string()); - for (const auto &file : _file) appendSimpleXMLNode(root, "file", file.string()); + for (const auto& file : _file) { + appendSimpleXMLNode(root, "file", file.string()); + } - for (const auto &md : _genericMetadata) { + for (const auto& md : _genericMetadata) { auto element = appendSimpleXMLNode(root, md.first, md.second.contents); - for (const auto &attr : md.second.attributes) + for (const auto& attr : md.second.attributes) { addAttribute(element, attr.first, attr.second); + } } if (!_content.empty()) { auto doc = root->getOwnerDocument(); - DOMElement *contentRootElement = doc->createElement(XUTF8Str("content").unicodeForm()); + DOMElement* contentRootElement = doc->createElement(XUTF8Str("content").unicodeForm()); root->appendChild(contentRootElement); - for (const auto &content : _content) { - DOMElement *contentElement = + for (const auto& content : _content) { + DOMElement* contentElement = doc->createElement(XUTF8Str(content.first.c_str()).unicodeForm()); contentRootElement->appendChild(contentElement); content.second.appendToElement(contentElement); @@ -636,75 +845,102 @@ void Metadata::appendToElement(DOMElement *root) const } -void Metadata::parseVersion1(const DOMNode *startNode) +void Metadata::parseVersion1(const DOMNode* startNode) { auto children = startNode->getChildNodes(); for (XMLSize_t i = 0; i < children->getLength(); ++i) { auto child = children->item(i); - auto element = dynamic_cast(child); - if (!element) continue; + auto element = dynamic_cast(child); + if (!element) { + continue; + } auto tag = element->getNodeName(); auto tagString = StrXUTF8(tag).str; - if (tagString == "name") _name = StrXUTF8(element->getTextContent()).str; - else if (tagString == "version") + if (tagString == "name") { + _name = StrXUTF8(element->getTextContent()).str; + } + else if (tagString == "version") { _version = Meta::Version(StrXUTF8(element->getTextContent()).str); - else if (tagString == "date") + } + else if (tagString == "date") { _date = StrXUTF8(element->getTextContent()).str; - else if (tagString == "description") + } + else if (tagString == "description") { _description = StrXUTF8(element->getTextContent()).str; - else if (tagString == "maintainer") + } + else if (tagString == "maintainer") { _maintainer.emplace_back(element); - else if (tagString == "license") + } + else if (tagString == "license") { _license.emplace_back(element); - else if (tagString == "freecadmin") + } + else if (tagString == "freecadmin") { _freecadmin = Meta::Version(StrXUTF8(element->getTextContent()).str); - else if (tagString == "freecadmax") + } + else if (tagString == "freecadmax") { _freecadmax = Meta::Version(StrXUTF8(element->getTextContent()).str); - else if (tagString == "pythonmin") + } + else if (tagString == "pythonmin") { _pythonmin = Meta::Version(StrXUTF8(element->getTextContent()).str); - else if (tagString == "url") + } + else if (tagString == "url") { _url.emplace_back(element); - else if (tagString == "author") + } + else if (tagString == "author") { _author.emplace_back(element); - else if (tagString == "depend") + } + else if (tagString == "depend") { _depend.emplace_back(element); - else if (tagString == "conflict") + } + else if (tagString == "conflict") { _conflict.emplace_back(element); - else if (tagString == "replace") + } + else if (tagString == "replace") { _replace.emplace_back(element); - else if (tagString == "tag") + } + else if (tagString == "tag") { _tag.emplace_back(StrXUTF8(element->getTextContent()).str); - else if (tagString == "file") + } + else if (tagString == "file") { _file.emplace_back(StrXUTF8(element->getTextContent()).str); - else if (tagString == "classname") + } + else if (tagString == "classname") { _classname = StrXUTF8(element->getTextContent()).str; - else if (tagString == "subdirectory") + } + else if (tagString == "subdirectory") { _subdirectory = StrXUTF8(element->getTextContent()).str; - else if (tagString == "icon") + } + else if (tagString == "icon") { _icon = fs::path(StrXUTF8(element->getTextContent()).str); - else if (tagString == "content") + } + else if (tagString == "content") { parseContentNodeVersion1(element);// Recursive call + } else { - // If none of this node's children have children of their own, it is a simple element and we + // If none of this node's nodeChildren have nodeChildren of their own, it is a simple element and we // can handle it as a GenericMetadata object - auto children = element->getChildNodes(); + auto nodeChildren = element->getChildNodes(); bool hasGrandchildren = false; - for (XMLSize_t i = 0; i < children->getLength() && !hasGrandchildren; ++i) - if (children->item(i)->getChildNodes()->getLength() > 0) hasGrandchildren = true; - if (!hasGrandchildren) + for (XMLSize_t j = 0; j < nodeChildren->getLength() && !hasGrandchildren; ++j) { + if (nodeChildren->item(j)->getChildNodes()->getLength() > 0) { + hasGrandchildren = true; + } + } + if (!hasGrandchildren) { _genericMetadata.insert(std::make_pair(tagString, Meta::GenericMetadata(element))); + } } } } -void Metadata::parseContentNodeVersion1(const DOMElement *contentNode) +void Metadata::parseContentNodeVersion1(const DOMElement* contentNode) { auto children = contentNode->getChildNodes(); for (XMLSize_t i = 0; i < children->getLength(); ++i) { - auto child = dynamic_cast(children->item(i)); + auto child = dynamic_cast(children->item(i)); if (child) { auto tag = StrXUTF8(child->getTagName()).str; _content.insert(std::make_pair(tag, Metadata(child, 1))); @@ -712,71 +948,90 @@ void Metadata::parseContentNodeVersion1(const DOMElement *contentNode) } } -Meta::Contact::Contact(const std::string &name, const std::string &email) : name(name), email(email) +Meta::Contact::Contact(std::string name, std::string email) + : name(std::move(name)), + email(std::move(email)) { // This has to be provided manually since we have another constructor } -Meta::Contact::Contact(const XERCES_CPP_NAMESPACE::DOMElement *e) +Meta::Contact::Contact(const XERCES_CPP_NAMESPACE::DOMElement* elem) { - auto emailAttribute = e->getAttribute(XUTF8Str("email").unicodeForm()); - name = StrXUTF8(e->getTextContent()).str; + auto emailAttribute = elem->getAttribute(XUTF8Str("email").unicodeForm()); + name = StrXUTF8(elem->getTextContent()).str; email = StrXUTF8(emailAttribute).str; } -bool App::Meta::Contact::operator==(const Contact &rhs) const +bool App::Meta::Contact::operator==(const Contact& rhs) const { return name == rhs.name && email == rhs.email; } -Meta::License::License(const std::string &name, fs::path file) : name(name), file(file) +Meta::License::License(std::string name, fs::path file) + : name(std::move(name)), + file(std::move(file)) { // This has to be provided manually since we have another constructor } -Meta::License::License(const XERCES_CPP_NAMESPACE::DOMElement *e) +Meta::License::License(const XERCES_CPP_NAMESPACE::DOMElement* elem) { - auto fileAttribute = e->getAttribute(XUTF8Str("file").unicodeForm()); - if (XMLString::stringLen(fileAttribute) > 0) { file = fs::path(StrXUTF8(fileAttribute).str); } - name = StrXUTF8(e->getTextContent()).str; + auto fileAttribute = elem->getAttribute(XUTF8Str("file").unicodeForm()); + if (XMLString::stringLen(fileAttribute) > 0) { + file = fs::path(StrXUTF8(fileAttribute).str); + } + name = StrXUTF8(elem->getTextContent()).str; } -bool App::Meta::License::operator==(const License &rhs) const +bool App::Meta::License::operator==(const License& rhs) const { return name == rhs.name && file == rhs.file; } -App::Meta::Url::Url() : location(""), type(App::Meta::UrlType::website) {} +App::Meta::Url::Url() + : location(""), + type(App::Meta::UrlType::website) +{} -Meta::Url::Url(const std::string &location, UrlType type) : location(location), type(type) +Meta::Url::Url(std::string location, UrlType type) + : location(std::move(location)), + type(type) { // This has to be provided manually since we have another constructor } -Meta::Url::Url(const XERCES_CPP_NAMESPACE::DOMElement *e) +Meta::Url::Url(const XERCES_CPP_NAMESPACE::DOMElement* elem) { - auto typeAttribute = StrXUTF8(e->getAttribute(XUTF8Str("type").unicodeForm())).str; - if (typeAttribute.empty() || typeAttribute == "website") type = UrlType::website; - else if (typeAttribute == "bugtracker") - type = UrlType::bugtracker; - else if (typeAttribute == "repository") - type = UrlType::repository; - else if (typeAttribute == "readme") - type = UrlType::readme; - else if (typeAttribute == "documentation") - type = UrlType::documentation; - else if (typeAttribute == "discussion") - type = UrlType::discussion; - else + auto typeAttribute = StrXUTF8(elem->getAttribute(XUTF8Str("type").unicodeForm())).str; + if (typeAttribute.empty() || typeAttribute == "website") { type = UrlType::website; + } + else if (typeAttribute == "bugtracker") { + type = UrlType::bugtracker; + } + else if (typeAttribute == "repository") { + type = UrlType::repository; + } + else if (typeAttribute == "readme") { + type = UrlType::readme; + } + else if (typeAttribute == "documentation") { + type = UrlType::documentation; + } + else if (typeAttribute == "discussion") { + type = UrlType::discussion; + } + else { + type = UrlType::website; + } if (type == UrlType::repository) { - branch = StrXUTF8(e->getAttribute(XUTF8Str("branch").unicodeForm())).str; + branch = StrXUTF8(elem->getAttribute(XUTF8Str("branch").unicodeForm())).str; } - location = StrXUTF8(e->getTextContent()).str; + location = StrXUTF8(elem->getTextContent()).str; } -bool App::Meta::Url::operator==(const Url &rhs) const +bool App::Meta::Url::operator==(const Url& rhs) const { if (type == UrlType::repository && branch != rhs.branch) { return false; @@ -785,45 +1040,54 @@ bool App::Meta::Url::operator==(const Url &rhs) const } App::Meta::Dependency::Dependency() - : optional(false), dependencyType(App::Meta::DependencyType::automatic) + : optional(false), + dependencyType(App::Meta::DependencyType::automatic) {} -App::Meta::Dependency::Dependency(const std::string &pkg) - : package(pkg), optional(false), dependencyType(App::Meta::DependencyType::automatic) +App::Meta::Dependency::Dependency(std::string pkg) + : package(std::move(pkg)), + optional(false), + dependencyType(App::Meta::DependencyType::automatic) {} -Meta::Dependency::Dependency(const XERCES_CPP_NAMESPACE::DOMElement *e) +Meta::Dependency::Dependency(const XERCES_CPP_NAMESPACE::DOMElement* elem) { - version_lt = StrXUTF8(e->getAttribute(XUTF8Str("version_lt").unicodeForm())).str; - version_lte = StrXUTF8(e->getAttribute(XUTF8Str("version_lte").unicodeForm())).str; - version_eq = StrXUTF8(e->getAttribute(XUTF8Str("version_eq").unicodeForm())).str; - version_gte = StrXUTF8(e->getAttribute(XUTF8Str("version_gte").unicodeForm())).str; - version_gt = StrXUTF8(e->getAttribute(XUTF8Str("version_gt").unicodeForm())).str; - condition = StrXUTF8(e->getAttribute(XUTF8Str("condition").unicodeForm())).str; - std::string opt_string = StrXUTF8(e->getAttribute(XUTF8Str("optional").unicodeForm())).str; + version_lt = StrXUTF8(elem->getAttribute(XUTF8Str("version_lt").unicodeForm())).str; + version_lte = StrXUTF8(elem->getAttribute(XUTF8Str("version_lte").unicodeForm())).str; + version_eq = StrXUTF8(elem->getAttribute(XUTF8Str("version_eq").unicodeForm())).str; + version_gte = StrXUTF8(elem->getAttribute(XUTF8Str("version_gte").unicodeForm())).str; + version_gt = StrXUTF8(elem->getAttribute(XUTF8Str("version_gt").unicodeForm())).str; + condition = StrXUTF8(elem->getAttribute(XUTF8Str("condition").unicodeForm())).str; + std::string opt_string = StrXUTF8(elem->getAttribute(XUTF8Str("optional").unicodeForm())).str; if (opt_string == "true" - || opt_string == "True")// Support Python capitalization in this one case... + || opt_string == "True") {// Support Python capitalization in this one case... optional = true; - else + } + else { optional = false; - std::string type_string = StrXUTF8(e->getAttribute(XUTF8Str("type").unicodeForm())).str; - if (type_string == "automatic" || type_string == "") + } + std::string type_string = StrXUTF8(elem->getAttribute(XUTF8Str("type").unicodeForm())).str; + if (type_string == "automatic" || type_string.empty()) { dependencyType = Meta::DependencyType::automatic; - else if (type_string == "addon") + } + else if (type_string == "addon") { dependencyType = Meta::DependencyType::addon; - else if (type_string == "internal") + } + else if (type_string == "internal") { dependencyType = Meta::DependencyType::internal; - else if (type_string == "python") + } + else if (type_string == "python") { dependencyType = Meta::DependencyType::python; + } else { auto message = std::string("Invalid dependency type \"") + type_string + "\""; throw Base::XMLBaseException(message); } - package = StrXUTF8(e->getTextContent()).str; + package = StrXUTF8(elem->getTextContent()).str; } -bool App::Meta::Dependency::operator==(const Dependency &rhs) const +bool App::Meta::Dependency::operator==(const Dependency& rhs) const { return package == rhs.package && version_lt == rhs.version_lt && version_lte == rhs.version_lte && version_eq == rhs.version_eq && version_gte == rhs.version_gte @@ -831,22 +1095,42 @@ bool App::Meta::Dependency::operator==(const Dependency &rhs) const && dependencyType == rhs.dependencyType; } -Meta::Version::Version() : major(0), minor(0), patch(0) {} - -Meta::Version::Version(int major, int minor, int patch, const std::string &suffix) - : major(major), minor(minor), patch(patch), suffix(suffix) +Meta::Version::Version() + : major(0), + minor(0), + patch(0) {} -Meta::Version::Version(const std::string &versionString) : minor(0), patch(0) +Meta::Version::Version(int major, int minor, int patch, std::string suffix) + : major(major), + minor(minor), + patch(patch), + suffix(std::move(suffix)) +{} + +Meta::Version::Version(const std::string& versionString) + : major(0), + minor(0), + patch(0) { std::istringstream stream(versionString); - char separator; + char separator {'.'}; stream >> major; - if (stream) stream >> separator; - if (stream) stream >> minor; - if (stream) stream >> separator; - if (stream) stream >> patch; - if (stream) stream >> suffix; + if (stream) { + stream >> separator; + } + if (stream) { + stream >> minor; + } + if (stream) { + stream >> separator; + } + if (stream) { + stream >> patch; + } + if (stream) { + stream >> suffix; + } } std::string Meta::Version::str() const @@ -859,50 +1143,52 @@ std::string Meta::Version::str() const return stream.str(); } -bool Meta::Version::operator<(const Version &rhs) const +bool Meta::Version::operator<(const Version& rhs) const { return std::tie(major, minor, patch, suffix) < std::tie(rhs.major, rhs.minor, rhs.patch, rhs.suffix); } -bool Meta::Version::operator>(const Version &rhs) const +bool Meta::Version::operator>(const Version& rhs) const { return std::tie(major, minor, patch, suffix) > std::tie(rhs.major, rhs.minor, rhs.patch, rhs.suffix); } -bool Meta::Version::operator<=(const Version &rhs) const +bool Meta::Version::operator<=(const Version& rhs) const { return std::tie(major, minor, patch, suffix) <= std::tie(rhs.major, rhs.minor, rhs.patch, rhs.suffix); } -bool Meta::Version::operator>=(const Version &rhs) const +bool Meta::Version::operator>=(const Version& rhs) const { return std::tie(major, minor, patch, suffix) >= std::tie(rhs.major, rhs.minor, rhs.patch, rhs.suffix); } -bool Meta::Version::operator==(const Version &rhs) const +bool Meta::Version::operator==(const Version& rhs) const { return std::tie(major, minor, patch, suffix) == std::tie(rhs.major, rhs.minor, rhs.patch, rhs.suffix); } -bool Meta::Version::operator!=(const Version &rhs) const +bool Meta::Version::operator!=(const Version& rhs) const { return std::tie(major, minor, patch, suffix) != std::tie(rhs.major, rhs.minor, rhs.patch, rhs.suffix); } -Meta::GenericMetadata::GenericMetadata(const XERCES_CPP_NAMESPACE::DOMElement *e) +Meta::GenericMetadata::GenericMetadata(const XERCES_CPP_NAMESPACE::DOMElement* elem) { - contents = StrXUTF8(e->getTextContent()).str; - for (XMLSize_t i = 0; i < e->getAttributes()->getLength(); ++i) { - auto a = e->getAttributes()->item(i); + contents = StrXUTF8(elem->getTextContent()).str; + for (XMLSize_t i = 0; i < elem->getAttributes()->getLength(); ++i) { + auto attr = elem->getAttributes()->item(i); attributes.insert( - std::make_pair(StrXUTF8(a->getNodeName()).str, StrXUTF8(a->getTextContent()).str)); + std::make_pair(StrXUTF8(attr->getNodeName()).str, StrXUTF8(attr->getTextContent()).str)); } } -App::Meta::GenericMetadata::GenericMetadata(const std::string &contents) : contents(contents) {} +App::Meta::GenericMetadata::GenericMetadata(std::string contents) + : contents(std::move(contents)) +{} diff --git a/src/App/Metadata.h b/src/App/Metadata.h index 6d11bb5e02..dd426b6943 100644 --- a/src/App/Metadata.h +++ b/src/App/Metadata.h @@ -1,24 +1,24 @@ -/*************************************************************************** - * Copyright (c) 2021 Chris Hennes * - * * - * This file is part of the FreeCAD CAx development system. * - * * - * This library is free software; you can redistribute it and/or * - * modify it under the terms of the GNU Library General Public * - * License as published by the Free Software Foundation; either * - * version 2 of the License, or (at your option) any later version. * - * * - * This library is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Library General Public License for more details. * - * * - * You should have received a copy of the GNU Library General Public * - * License along with this library; see the file LICENSE.html. If not, * - * write to the Free Software Foundation, Inc., 59 Temple Place, * - * Suite 330, Boston, MA 02111-1307, USA * - * * - ***************************************************************************/ +/************************************************************************** +* * +* Copyright (c) 2021-2023 FreeCAD Project Association * +* * +* This file is part of FreeCAD. * +* * +* FreeCAD is free software: you can redistribute it and/or modify it * +* under the terms of the GNU Lesser General Public License as * +* published by the Free Software Foundation, either version 2.1 of the * +* License, or (at your option) any later version. * +* * +* FreeCAD is distributed in the hope that it will be useful, but * +* WITHOUT ANY WARRANTY; without even the implied warranty of * +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * +* Lesser General Public License for more details. * +* * +* You should have received a copy of the GNU Lesser General Public * +* License along with FreeCAD. If not, see * +* . * +* * +***************************************************************************/ #ifndef BASE_METADATAREADER_H #define BASE_METADATAREADER_H @@ -43,33 +43,33 @@ namespace Meta { /** - * \struct Contact - * \brief A person or company representing a point of contact for the package (either author or maintainer). - */ + * \struct Contact + * \brief A person or company representing a point of contact for the package (either author or maintainer). + */ struct AppExport Contact { Contact() = default; - Contact(const std::string &name, const std::string &email); - explicit Contact(const XERCES_CPP_NAMESPACE::DOMElement *e); + Contact(std::string name, std::string email); + explicit Contact(const XERCES_CPP_NAMESPACE::DOMElement* elem); std::string name; //< Contact name - required std::string email;//< Contact email - may be optional - bool operator==(const Contact &rhs) const; + bool operator==(const Contact& rhs) const; }; /** - * \struct License - * \brief A license that covers some or all of this package. - * - * Many licenses also require the inclusion of the complete license text, specified in this struct - * using the "file" member. - */ + * \struct License + * \brief A license that covers some or all of this package. + * + * Many licenses also require the inclusion of the complete license text, specified in this struct + * using the "file" member. + */ struct AppExport License { License() = default; - License(const std::string &name, boost::filesystem::path file); - explicit License(const XERCES_CPP_NAMESPACE::DOMElement *e); + License(std::string name, boost::filesystem::path file); + explicit License(const XERCES_CPP_NAMESPACE::DOMElement* elem); std::string name;//< Short name of license, e.g. "LGPL2", "MIT", "Mozilla Public License", etc. boost::filesystem::path file;//< Optional path to the license file, relative to the XML file's location - bool operator==(const License &rhs) const; + bool operator==(const License& rhs) const; }; enum class UrlType @@ -83,48 +83,48 @@ enum class UrlType }; /** - * \struct Url - * \brief A URL, including type information (e.g. website, repository, or bugtracker, in package.xml) - */ + * \struct Url + * \brief A URL, including type information (e.g. website, repository, or bugtracker, in package.xml) + */ struct AppExport Url { Url(); - Url(const std::string &location, UrlType type); - explicit Url(const XERCES_CPP_NAMESPACE::DOMElement *e); + Url(std::string location, UrlType type); + explicit Url(const XERCES_CPP_NAMESPACE::DOMElement* elem); std::string location;//< The actual URL, including protocol UrlType type; //< What kind of URL this is std::string branch; //< If it's a repository, which branch to use - bool operator==(const Url &rhs) const; + bool operator==(const Url& rhs) const; }; /** - * \struct Version - * A semantic version structure providing comparison operators and conversion to and from std::string - */ + * \struct Version + * A semantic version structure providing comparison operators and conversion to and from std::string + */ struct AppExport Version { Version(); explicit Version(int major, int minor = 0, int patch = 0, - const std::string &suffix = std::string()); - explicit Version(const std::string &semanticString); + std::string suffix = std::string()); + explicit Version(const std::string& semanticString); - int major; + int major{}; int minor; int patch; std::string suffix; std::string str() const; - bool operator<(const Version &) const; - bool operator>(const Version &) const; - bool operator<=(const Version &) const; - bool operator>=(const Version &) const; - bool operator==(const Version &) const; - bool operator!=(const Version &) const; + bool operator<(const Version&) const; + bool operator>(const Version&) const; + bool operator<=(const Version&) const; + bool operator>=(const Version&) const; + bool operator==(const Version&) const; + bool operator!=(const Version&) const; }; /** - * \enum DependencyType - * The type of dependency. - */ + * \enum DependencyType + * The type of dependency. + */ enum class DependencyType { automatic, @@ -134,13 +134,13 @@ enum class DependencyType }; /** - * \struct Dependency - * \brief Another package that this package depends on, conflicts with, or replaces - */ + * \struct Dependency + * \brief Another package that this package depends on, conflicts with, or replaces + */ struct AppExport Dependency { Dependency(); - explicit Dependency(const std::string &pkg); - explicit Dependency(const XERCES_CPP_NAMESPACE::DOMElement *e); + explicit Dependency(std::string pkg); + explicit Dependency(const XERCES_CPP_NAMESPACE::DOMElement* elem); std::string package;//< Required: must exactly match the contents of the "name" element in the referenced package's package.xml file. std::string @@ -156,21 +156,21 @@ struct AppExport Dependency { std::string condition; //< Optional: Conditional expression as documented in REP149. bool optional; //< Optional: Whether this dependency is considered "optional" DependencyType dependencyType;//< Optional: defaults to "automatic" - bool operator==(const Dependency &rhs) const; + bool operator==(const Dependency& rhs) const; }; /** - * \struct GenericMetadata - * A structure to hold unrecognized single-level metadata. - * - * Most unrecognized metadata is simple: when parsing the XML, if the parser finds a tag it - * does not recognize, and that tag has no children, it is parsed into this data structure - * for convenient access by client code. - */ + * \struct GenericMetadata + * A structure to hold unrecognized single-level metadata. + * + * Most unrecognized metadata is simple: when parsing the XML, if the parser finds a tag it + * does not recognize, and that tag has no children, it is parsed into this data structure + * for convenient access by client code. + */ struct AppExport GenericMetadata { GenericMetadata() = default; - explicit GenericMetadata(const XERCES_CPP_NAMESPACE::DOMElement *e); - explicit GenericMetadata(const std::string &contents); + explicit GenericMetadata(const XERCES_CPP_NAMESPACE::DOMElement* elem); + explicit GenericMetadata(std::string contents); std::string contents; //< The contents of the tag std::map attributes;//< The XML attributes of the tag }; @@ -178,37 +178,37 @@ struct AppExport GenericMetadata { }// namespace Meta /** - * \class Metadata - * \brief Reads data from a metadata file. - * - * The metadata format is based on https://ros.org/reps/rep-0149.html, modified for FreeCAD - * use. Full format documentation is available at the FreeCAD Wiki: - * https://wiki.freecadweb.org/Package_Metadata - */ + * \class Metadata + * \brief Reads data from a metadata file. + * + * The metadata format is based on https://ros.org/reps/rep-0149.html, modified for FreeCAD + * use. Full format documentation is available at the FreeCAD Wiki: + * https://wiki.freecadweb.org/Package_Metadata + */ class AppExport Metadata { public: Metadata(); /** - * Read the data from a file on disk - * - * This constructor takes a path to an XML file and loads the XML from that file as - * metadata. - */ - explicit Metadata(const boost::filesystem::path &metadataFile); + * Read the data from a file on disk + * + * This constructor takes a path to an XML file and loads the XML from that file as + * metadata. + */ + explicit Metadata(const boost::filesystem::path& metadataFile); /** - * Construct a Metadata object from a DOM node. - * - * This node may have any tag name: it is only accessed via its children, which are - * expected to follow the standard Metadata format for the contents of the element. - */ - Metadata(const XERCES_CPP_NAMESPACE::DOMNode *domNode, int format); + * Construct a Metadata object from a DOM node. + * + * This node may have any tag name: it is only accessed via its children, which are + * expected to follow the standard Metadata format for the contents of the element. + */ + Metadata(const XERCES_CPP_NAMESPACE::DOMNode* domNode, int format); /** - * Treat the incoming rawData as metadata to be parsed. - */ + * Treat the incoming rawData as metadata to be parsed. + */ explicit Metadata(const std::string& rawData); ~Metadata(); @@ -250,73 +250,73 @@ public: Meta::Version pythonmin() const; //< The minimum Python version. /** - * Access the metadata for the content elements of this package - * - * In addition to the overall package metadata, this class reads in metadata contained in a - * element. Each entry in the content element is an element representing some - * type of package content (e.g. add-on, macro, theme, etc.). This class places no restriction - * on the types, it is up to client code to place requirements on the metadata included - * here. - * - * For example, themes might be specified: - * - * - * High Contrast - * - * - */ + * Access the metadata for the content elements of this package + * + * In addition to the overall package metadata, this class reads in metadata contained in a + * element. Each entry in the content element is an element representing some + * type of package content (e.g. add-on, macro, theme, etc.). This class places no restriction + * on the types, it is up to client code to place requirements on the metadata included + * here. + * + * For example, themes might be specified: + * + * + * High Contrast + * + * + */ std::multimap content() const; /** - * Convenience accessor for unrecognized simple metadata. - * - * If the XML parser encounters tags that it does not recognize, and those tags have - * no children, a GenericMetadata object is created. Those objects can be accessed using - * operator[], which returns a (potentially empty) vector containing all instances of the - * given tag. It cannot be used to *create* a new tag, however. See addGenericMetadata(). - */ - std::vector operator[](const std::string &tag) const; + * Convenience accessor for unrecognized simple metadata. + * + * If the XML parser encounters tags that it does not recognize, and those tags have + * no children, a GenericMetadata object is created. Those objects can be accessed using + * operator[], which returns a (potentially empty) vector containing all instances of the + * given tag. It cannot be used to *create* a new tag, however. See addGenericMetadata(). + */ + std::vector operator[](const std::string& tag) const; /** - * Directly access the DOM tree to support unrecognized multi-level metadata - */ - XERCES_CPP_NAMESPACE::DOMElement *dom() const; + * Directly access the DOM tree to support unrecognized multi-level metadata + */ + XERCES_CPP_NAMESPACE::DOMElement* dom() const; // Setters - void setName(const std::string &name); - void setVersion(const Meta::Version &version); - void setDate(const std::string &date); - void setDescription(const std::string &description); - void addMaintainer(const Meta::Contact &maintainer); - void addLicense(const Meta::License &license); - void addUrl(const Meta::Url &url); - void addAuthor(const Meta::Contact &author); - void addDepend(const Meta::Dependency &dep); - void addConflict(const Meta::Dependency &dep); - void addReplace(const Meta::Dependency &dep); - void addTag(const std::string &tag); - void setIcon(const boost::filesystem::path &path); - void setClassname(const std::string &name); - void setSubdirectory(const boost::filesystem::path &path); - void addFile(const boost::filesystem::path &path); - void addContentItem(const std::string &tag, const Metadata &item); - void setFreeCADMin(const Meta::Version &version); - void setFreeCADMax(const Meta::Version &version); - void setPythonMin(const Meta::Version &version); - void addGenericMetadata(const std::string &tag, const Meta::GenericMetadata &genericMetadata); + void setName(const std::string& name); + void setVersion(const Meta::Version& version); + void setDate(const std::string& date); + void setDescription(const std::string& description); + void addMaintainer(const Meta::Contact& maintainer); + void addLicense(const Meta::License& license); + void addUrl(const Meta::Url& url); + void addAuthor(const Meta::Contact& author); + void addDepend(const Meta::Dependency& dep); + void addConflict(const Meta::Dependency& dep); + void addReplace(const Meta::Dependency& dep); + void addTag(const std::string& tag); + void setIcon(const boost::filesystem::path& path); + void setClassname(const std::string& name); + void setSubdirectory(const boost::filesystem::path& path); + void addFile(const boost::filesystem::path& path); + void addContentItem(const std::string& tag, const Metadata& item); + void setFreeCADMin(const Meta::Version& version); + void setFreeCADMax(const Meta::Version& version); + void setPythonMin(const Meta::Version& version); + void addGenericMetadata(const std::string& tag, const Meta::GenericMetadata& genericMetadata); // Deleters - void removeContentItem(const std::string &tag, const std::string &itemName); - void removeMaintainer(const Meta::Contact &maintainer); - void removeLicense(const Meta::License &license); - void removeUrl(const Meta::Url &url); - void removeAuthor(const Meta::Contact &author); - void removeDepend(const Meta::Dependency &dep); - void removeConflict(const Meta::Dependency &dep); - void removeReplace(const Meta::Dependency &dep); - void removeTag(const std::string &tag); - void removeFile(const boost::filesystem::path &path); + void removeContentItem(const std::string& tag, const std::string& itemName); + void removeMaintainer(const Meta::Contact& maintainer); + void removeLicense(const Meta::License& license); + void removeUrl(const Meta::Url& url); + void removeAuthor(const Meta::Contact& author); + void removeDepend(const Meta::Dependency& dep); + void removeConflict(const Meta::Dependency& dep); + void removeReplace(const Meta::Dependency& dep); + void removeTag(const std::string& tag); + void removeFile(const boost::filesystem::path& path); // Utility functions to clear lists void clearContent(); @@ -331,19 +331,19 @@ public: void clearFile(); /** - * Write the metadata to an XML file - */ - void write(const boost::filesystem::path &file) const; + * Write the metadata to an XML file + */ + void write(const boost::filesystem::path& file) const; /** - * Determine whether this package satisfies the given dependency - */ - bool satisfies(const Meta::Dependency &); + * Determine whether this package satisfies the given dependency + */ + bool satisfies(const Meta::Dependency&); /** - * Determine whether the current metadata specifies support for the currently-running version of FreeCAD. - * Does not interrogate content items, which must be querried individually. - */ + * Determine whether the current metadata specifies support for the currently-running version of FreeCAD. + * Does not interrogate content items, which must be querried individually. + */ bool supportsCurrentFreeCAD() const; private: @@ -371,14 +371,14 @@ private: std::multimap _genericMetadata; - XERCES_CPP_NAMESPACE::DOMElement *_dom; + XERCES_CPP_NAMESPACE::DOMElement* _dom; std::shared_ptr _parser; void loadFromInputSource(const XERCES_CPP_NAMESPACE::InputSource& source); - void parseVersion1(const XERCES_CPP_NAMESPACE::DOMNode *startNode); - void parseContentNodeVersion1(const XERCES_CPP_NAMESPACE::DOMElement *contentNode); + void parseVersion1(const XERCES_CPP_NAMESPACE::DOMNode* startNode); + void parseContentNodeVersion1(const XERCES_CPP_NAMESPACE::DOMElement* contentNode); - void appendToElement(XERCES_CPP_NAMESPACE::DOMElement *root) const; + void appendToElement(XERCES_CPP_NAMESPACE::DOMElement* root) const; }; }// namespace App