Salome HOME
cb866a7d55dbca72facd4af0cd0c8c825b8f3d0d
[modules/shaper.git] / src / Config / Config_Common.cpp
1 // Copyright (C) 2014-20xx CEA/DEN, EDF R&D
2
3 /*
4  * Config_Common.cpp
5  *
6  *  Created on: Apr 17, 2014
7  *      Author: sbh
8  */
9
10 #include "Config_Common.h"
11 #include <Config_Keywords.h>
12
13 #include <libxml/parser.h>
14 #include <libxml/tree.h>
15
16 #include <sstream> // for stringstream
17
18 #include <string>
19 #include <algorithm> // for std::transform
20 #include <vector>
21
22 bool isElementNode(xmlNodePtr theNode)
23 {
24   if (!theNode)
25     return false;
26   return theNode->type == XML_ELEMENT_NODE;
27 }
28
29 bool isNode(xmlNodePtr theNode, const char* theNodeName, ...)
30 {
31   const xmlChar* aName = theNode->name;
32   if (!aName || !isElementNode(theNode)) {
33     return false;
34   }
35   if (!xmlStrcmp(aName, (const xmlChar *) theNodeName)) {
36     return true;
37   }
38   va_list args;  // define argument list variable
39   va_start(args, theNodeName);  // init list; point to last defined argument
40   while (true) {
41     char *anArg = va_arg (args, char*);  // get next argument
42     if (anArg == NULL)
43       break;
44     if (!xmlStrcmp(aName, (const xmlChar *) anArg)) {
45       va_end(args);  // cleanup the system stack
46       return true;
47     }
48   }
49   va_end(args);  // cleanup the system stack
50   return false;
51 }
52
53 bool isAttributeNode(xmlNodePtr theNode)
54 {
55   if(!isElementNode(theNode))
56     return false;
57   // it's parent is "feature" or "source" or page ("case" or "box")
58   if(!hasParent(theNode, NODE_FEATURE, NODE_SOURCE,
59                          WDG_GROUP, WDG_OPTIONALBOX,
60                          WDG_TOOLBOX_BOX, WDG_SWITCH_CASE, NULL))
61     return false;
62
63   //it should not be a "source" or a "validator" node
64   bool isLogical = isNode(theNode, NODE_SOURCE, NODE_VALIDATOR, NODE_SELFILTER, NULL);
65   // here must be only widgets not connected to attributes
66   bool isPagedContainer = isNode(theNode, WDG_TOOLBOX_BOX,
67                                           WDG_GROUP,
68                                           WDG_SWITCH_CASE,  NULL);
69   return !isLogical && !isPagedContainer;
70 }
71
72 bool isWidgetNode(xmlNodePtr theNode)
73 {
74   if(!isElementNode(theNode))
75     return false;
76   // it's parent is "feature" or "source" or a page ("box", "case")
77   if(!hasParent(theNode, NODE_FEATURE, NODE_SOURCE, WDG_GROUP, WDG_OPTIONALBOX,
78                          WDG_TOOLBOX_BOX, WDG_SWITCH_CASE, NULL))
79     return false;
80
81   //it should not be a "source" or a "validator" node
82   return !isNode(theNode, NODE_SOURCE, NODE_VALIDATOR, NODE_SELFILTER, NULL);
83 }
84
85 // widget api?
86 bool isCaseNode(xmlNodePtr theNode)
87 {
88   if(!isElementNode(theNode))
89     return false;
90
91   return isNode(theNode, WDG_OPTIONALBOX, WDG_SWITCH_CASE, WDG_TOOLBOX_BOX, NULL);
92 }
93
94 bool hasChild(xmlNodePtr theNode)
95 {
96   xmlNodePtr aNode = theNode->children;
97   for (; aNode; aNode = aNode->next) {
98     if (isElementNode(theNode)) {
99       return true;
100     }
101   }
102   return false;
103 }
104
105 bool hasParent(xmlNodePtr theNode)
106 {
107   xmlNodePtr aNode = theNode->parent;
108   if (!aNode) {
109     return false;
110   }
111   for (; aNode; aNode = aNode->next) {
112     if (isElementNode(theNode)) {
113       return true;
114     }
115   }
116   return false;
117 }
118
119 bool hasParent(xmlNodePtr theNode, const char* theNodeName, ...)
120 {
121   if (!hasParent(theNode)) {
122     return false; // have no parents at all
123   }
124   xmlNodePtr aNode = theNode->parent;
125   const xmlChar* aName = aNode->name;
126   if (!aName || !isElementNode(aNode)) {
127     return false;
128   }
129   if (!xmlStrcmp(aName, (const xmlChar *) theNodeName)) {
130     return true;
131   }
132   va_list args;  // define argument list variable
133   va_start(args, theNodeName);  // init list; point to last defined argument
134   while (true) {
135     char *anArg = va_arg (args, char*);  // get next argument
136     if (anArg == NULL)
137       break;
138     if (!xmlStrcmp(aName, (const xmlChar *) anArg)) {
139       va_end(args);  // cleanup the system stack
140       return true;
141     }
142   }
143   va_end(args);  // cleanup the system stack
144   return false;
145 }
146
147 xmlNodePtr hasParentRecursive(xmlNodePtr theNode, const std::vector<const char*>& theNodeNames)
148 {
149   if (!hasParent(theNode)) {
150     return 0; // have no parents at all
151   }
152   xmlNodePtr aNode = theNode->parent;
153   const xmlChar* aName = aNode->name;
154   if (!aName || !isElementNode(aNode)) {
155     return 0;
156   }
157   for (size_t anIndex = 0; anIndex < theNodeNames.size(); ++anIndex) {
158     if (!xmlStrcmp(aName, (const xmlChar *) theNodeNames[anIndex]))
159       return aNode;
160   }
161   return hasParentRecursive(aNode, theNodeNames);
162 }
163
164 xmlNodePtr hasParentRecursive(xmlNodePtr theNode, const char* theNodeName, ...)
165 {
166   std::vector<const char*> aNodeNames;
167   va_list args;  // define argument list variable
168   va_start(args, theNodeName);  // init list; point to last defined argument
169   aNodeNames.push_back(theNodeName);
170   while (true) {
171     char *anArg = va_arg (args, char*);  // get next argument
172     if (anArg == NULL)
173       break;
174     aNodeNames.push_back(anArg);
175   }
176   va_end(args);  // cleanup the system stack
177   return hasParentRecursive(theNode, aNodeNames);
178 }
179
180 bool getParametersInfo(xmlNodePtr theNode, std::string& outPropertyId,
181                       std::list<std::string>& outValidatorParameters)
182 {
183   //Property id:
184   char* anIdProp = (char*) xmlGetProp(theNode, BAD_CAST _ID);
185   if (!anIdProp || anIdProp[0] == 0) {
186     return false;
187   }
188   outPropertyId = std::string(anIdProp);
189
190   //Property parameters:
191   char* aParamProp = (char*) xmlGetProp(theNode, BAD_CAST _PARAMETERS);
192   if (aParamProp && aParamProp[0] != 0) {
193     std::string aPropString = std::string(aParamProp);
194     std::stringstream aPropStringStream(aPropString);
195     char COMMA_DELIM = ',';
196     std::string aParameter;
197     while (std::getline(aPropStringStream, aParameter, ',')) {
198       outValidatorParameters.push_back(aParameter);
199     }
200   }
201   return true;
202 }
203
204 std::string library(const std::string& theLibName)
205 {
206   if(theLibName.empty())
207     return std::string();
208   std::string aLibName = theLibName;
209 #ifndef WIN32
210   static std::string aLibExt( ".so" );
211   if (aLibName.size() < 3 || aLibName.substr(0, 3) !="lib") {
212     aLibName = "lib" + aLibName;
213   }
214 #else
215   static std::string aLibExt(".dll");
216 #endif
217   std::string anExt = aLibName.substr(aLibName.size() - 4);
218   if (anExt != aLibExt)
219     aLibName += aLibExt;
220
221   return aLibName;
222 }
223
224 bool BothAreSpaces(char lhs, char rhs) { return (lhs == rhs) && (lhs == ' '); }
225
226 std::string getProperty(xmlNodePtr theNode, const char* thePropName)
227 {
228   std::string result = "";
229   xmlChar* aPropChars = xmlGetProp(theNode, BAD_CAST thePropName);
230   if (!aPropChars || aPropChars[0] == 0)
231     return result;
232   result = std::string((char*)aPropChars);
233   xmlFree(aPropChars);
234
235   std::string::iterator new_end = std::unique(result.begin(), result.end(), BothAreSpaces);
236   result.erase(new_end, result.end());
237
238   return result;
239 }
240
241 std::string getContent(xmlNodePtr theNode)
242 {
243   std::string result = "";
244   xmlChar* aContent = xmlNodeGetContent(theNode);
245   if (!aContent || aContent[0] == 0)
246     return result;
247   result = std::string((char*)aContent);
248   xmlFree(aContent);
249   return result;
250 }
251
252 std::string getNormalizedProperty(xmlNodePtr theNode, const char* thePropName)
253 {
254   return normalize(getProperty(theNode, thePropName));
255 }
256
257 bool getBooleanAttribute(xmlNodePtr theNode, const char* theAttributeName, bool theDefault)
258 {
259   std::string prop = normalize(getProperty(theNode, theAttributeName));
260   bool result = theDefault;
261   if (prop == "true" || prop == "1") {
262     result = true;
263   } else if (prop == "false" || prop == "0") {
264     result = false;
265   }
266   return result;
267 }
268
269 CONFIG_EXPORT std::string normalize(const char* theString)
270 {
271   if (!theString)
272     return std::string();
273   return normalize(std::string(theString));
274 }
275
276 CONFIG_EXPORT std::string normalize(const std::string& theString)
277 {
278   std::string result = theString;
279   std::transform(result.begin(), result.end(), result.begin(), ::tolower);
280   return result;
281 }