1 // Copyright (C) 2014-2023 CEA, EDF
3 // This library is free software; you can redistribute it and/or
4 // modify it under the terms of the GNU Lesser General Public
5 // License as published by the Free Software Foundation; either
6 // version 2.1 of the License, or (at your option) any later version.
8 // This library is distributed in the hope that it will be useful,
9 // but WITHOUT ANY WARRANTY; without even the implied warranty of
10 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
11 // Lesser General Public License for more details.
13 // You should have received a copy of the GNU Lesser General Public
14 // License along with this library; if not, write to the Free Software
15 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
20 #include "Config_Common.h"
21 #include <Config_Keywords.h>
23 #include <libxml/parser.h>
24 #include <libxml/tree.h>
26 #include <sstream> // for stringstream
29 #include <algorithm> // for std::transform
32 bool isElementNode(xmlNodePtr theNode)
36 return theNode->type == XML_ELEMENT_NODE;
39 bool isNode(xmlNodePtr theNode, const char* theNodeName, ...)
41 const xmlChar* aName = theNode->name;
42 if (!aName || !isElementNode(theNode)) {
45 if (!xmlStrcmp(aName, (const xmlChar *) theNodeName)) {
48 va_list args; // define argument list variable
49 va_start(args, theNodeName); // init list; point to last defined argument
51 char *anArg = va_arg (args, char*); // get next argument
54 if (!xmlStrcmp(aName, (const xmlChar *) anArg)) {
55 va_end(args); // cleanup the system stack
59 va_end(args); // cleanup the system stack
63 bool isAttributeNode(xmlNodePtr theNode)
65 if(!isElementNode(theNode))
67 // it's parent is "feature" or "source" or page ("case" or "box")
68 if(!hasParent(theNode, NODE_FEATURE, NODE_SOURCE,
69 WDG_GROUP, WDG_OPTIONALBOX,
70 WDG_TOOLBOX_BOX, WDG_RADIOBOX_ITEM,
71 WDG_SWITCH_CASE, NULL))
74 //it should not be a "source" or a "validator" node
75 bool isLogical = isNode(theNode, NODE_SOURCE, NODE_VALIDATOR, NULL);
76 // here must be only widgets not connected to attributes
77 bool isPagedContainer = isNode(theNode, WDG_TOOLBOX_BOX,
79 WDG_SWITCH_CASE, NULL);
80 return !isLogical && !isPagedContainer;
83 bool isWidgetNode(xmlNodePtr theNode)
85 if(!isElementNode(theNode))
87 // it's parent is "feature" or "source" or a page ("box", "case")
88 if(!hasParent(theNode, NODE_FEATURE, NODE_SOURCE, WDG_GROUP, WDG_OPTIONALBOX,
89 WDG_TOOLBOX_BOX, WDG_RADIOBOX_ITEM, WDG_SWITCH_CASE, WDG_FILTER, NULL))
92 //it should not be a "source" or a "validator" node
93 return !isNode(theNode, NODE_SOURCE, NODE_VALIDATOR, NULL);
98 bool isCaseNode(xmlNodePtr theNode)
100 if(!isElementNode(theNode))
103 return isNode(theNode, WDG_OPTIONALBOX, WDG_SWITCH_CASE, WDG_TOOLBOX_BOX,
104 WDG_RADIOBOX_ITEM, NULL);
108 bool hasChild(xmlNodePtr theNode)
110 xmlNodePtr aNode = theNode->children;
111 for (; aNode; aNode = aNode->next) {
112 if (isElementNode(theNode)) {
119 bool hasParent(xmlNodePtr theNode)
121 xmlNodePtr aNode = theNode->parent;
125 for (; aNode; aNode = aNode->next) {
126 if (isElementNode(theNode)) {
133 bool hasParent(xmlNodePtr theNode, const char* theNodeName, ...)
135 if (!hasParent(theNode)) {
136 return false; // have no parents at all
138 xmlNodePtr aNode = theNode->parent;
139 const xmlChar* aName = aNode->name;
140 if (!aName || !isElementNode(aNode)) {
143 if (!xmlStrcmp(aName, (const xmlChar *) theNodeName)) {
146 va_list args; // define argument list variable
147 va_start(args, theNodeName); // init list; point to last defined argument
149 char *anArg = va_arg (args, char*); // get next argument
152 if (!xmlStrcmp(aName, (const xmlChar *) anArg)) {
153 va_end(args); // cleanup the system stack
157 va_end(args); // cleanup the system stack
161 xmlNodePtr hasParentRecursive(xmlNodePtr theNode, const std::vector<const char*>& theNodeNames)
163 if (!hasParent(theNode)) {
164 return 0; // have no parents at all
166 xmlNodePtr aNode = theNode->parent;
167 const xmlChar* aName = aNode->name;
168 if (!aName || !isElementNode(aNode)) {
171 for (size_t anIndex = 0; anIndex < theNodeNames.size(); ++anIndex) {
172 if (!xmlStrcmp(aName, (const xmlChar *) theNodeNames[anIndex]))
175 return hasParentRecursive(aNode, theNodeNames);
178 xmlNodePtr hasParentRecursive(xmlNodePtr theNode, const char* theNodeName, ...)
180 std::vector<const char*> aNodeNames;
181 va_list args; // define argument list variable
182 va_start(args, theNodeName); // init list; point to last defined argument
183 aNodeNames.push_back(theNodeName);
185 char *anArg = va_arg (args, char*); // get next argument
188 aNodeNames.push_back(anArg);
190 va_end(args); // cleanup the system stack
191 return hasParentRecursive(theNode, aNodeNames);
194 bool getParametersInfo(xmlNodePtr theNode, std::string& outPropertyId,
195 std::list<std::string>& outValidatorParameters)
198 char* anIdProp = (char*) xmlGetProp(theNode, BAD_CAST _ID);
199 if (!anIdProp || anIdProp[0] == 0) {
202 outPropertyId = std::string(anIdProp);
204 //Property parameters:
205 char* aParamProp = (char*) xmlGetProp(theNode, BAD_CAST _PARAMETERS);
206 if (aParamProp && aParamProp[0] != 0) {
207 std::string aPropString = std::string(aParamProp);
208 std::stringstream aPropStringStream(aPropString);
209 char COMMA_DELIM = ',';
210 std::string aParameter;
211 while (std::getline(aPropStringStream, aParameter, COMMA_DELIM)) {
212 outValidatorParameters.push_back(aParameter);
218 std::string library(const std::string& theLibName)
220 if(theLibName.empty())
221 return std::string();
222 std::string aLibName = theLibName;
224 static std::string aLibExt( ".so" );
225 if (aLibName.size() < 3 || aLibName.substr(0, 3) !="lib") {
226 aLibName = "lib" + aLibName;
229 static std::string aLibExt(".dll");
231 std::string anExt = aLibName.substr(aLibName.size() - 4);
232 if (anExt != aLibExt)
238 bool BothAreSpaces(char lhs, char rhs) { return (lhs == rhs) && (lhs == ' '); }
240 std::string getProperty(xmlNodePtr theNode, const char* thePropName)
242 std::string result = "";
243 xmlChar* aPropChars = xmlGetProp(theNode, BAD_CAST thePropName);
244 if (!aPropChars || aPropChars[0] == 0)
246 result = std::string((char*)aPropChars);
249 std::string::iterator new_end = std::unique(result.begin(), result.end(), BothAreSpaces);
250 result.erase(new_end, result.end());
256 std::string getContent(xmlNodePtr theNode)
258 std::string result = "";
259 xmlChar* aContent = xmlNodeGetContent(theNode);
260 if (!aContent || aContent[0] == 0)
262 result = std::string((char*)aContent);
268 std::string getNormalizedProperty(xmlNodePtr theNode, const char* thePropName)
270 return normalize(getProperty(theNode, thePropName));
273 bool getBooleanAttribute(xmlNodePtr theNode, const char* theAttributeName, bool theDefault)
275 std::string prop = normalize(getProperty(theNode, theAttributeName));
276 bool result = theDefault;
277 if (prop == "true" || prop == "1") {
279 } else if (prop == "false" || prop == "0") {
285 CONFIG_EXPORT std::string normalize(const std::string& theString)
287 std::string result = theString;
288 std::transform(result.begin(), result.end(), result.begin(),
289 [](char c) { return static_cast<char>(::tolower(c)); });