1 // Copyright (C) 2014-20xx CEA/DEN, EDF R&D
6 * Created on: Apr 17, 2014
10 #include "Config_Common.h"
11 #include <Config_Keywords.h>
13 #include <libxml/parser.h>
14 #include <libxml/tree.h>
16 #include <sstream> // for stringstream
19 #include <algorithm> // for std::transform
22 bool isElementNode(xmlNodePtr theNode)
26 return theNode->type == XML_ELEMENT_NODE;
29 bool isNode(xmlNodePtr theNode, const char* theNodeName, ...)
31 const xmlChar* aName = theNode->name;
32 if (!aName || !isElementNode(theNode)) {
35 if (!xmlStrcmp(aName, (const xmlChar *) theNodeName)) {
38 va_list args; // define argument list variable
39 va_start(args, theNodeName); // init list; point to last defined argument
41 char *anArg = va_arg (args, char*); // get next argument
44 if (!xmlStrcmp(aName, (const xmlChar *) anArg)) {
45 va_end(args); // cleanup the system stack
49 va_end(args); // cleanup the system stack
53 bool isAttributeNode(xmlNodePtr theNode)
55 if(!isElementNode(theNode))
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))
63 //it should not be a "source" or a "validator" node
64 bool isLogical = isNode(theNode, NODE_SOURCE, NODE_VALIDATOR, NULL);
65 // here must be only widgets not connected to attributes
66 bool isPagedContainer = isNode(theNode, WDG_TOOLBOX_BOX,
68 WDG_SWITCH_CASE, NULL);
69 return !isLogical && !isPagedContainer;
72 bool isWidgetNode(xmlNodePtr theNode)
74 if(!isElementNode(theNode))
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))
81 //it should not be a "source" or a "validator" node
82 return !isNode(theNode, NODE_SOURCE, NODE_VALIDATOR, NULL);
86 bool isCaseNode(xmlNodePtr theNode)
88 if(!isElementNode(theNode))
91 return isNode(theNode, WDG_OPTIONALBOX, WDG_SWITCH_CASE, WDG_TOOLBOX_BOX, NULL);
94 bool hasChild(xmlNodePtr theNode)
96 xmlNodePtr aNode = theNode->children;
97 for (; aNode; aNode = aNode->next) {
98 if (isElementNode(theNode)) {
105 bool hasParent(xmlNodePtr theNode)
107 xmlNodePtr aNode = theNode->parent;
111 for (; aNode; aNode = aNode->next) {
112 if (isElementNode(theNode)) {
119 bool hasParent(xmlNodePtr theNode, const char* theNodeName, ...)
121 if (!hasParent(theNode)) {
122 return false; // have no parents at all
124 xmlNodePtr aNode = theNode->parent;
125 const xmlChar* aName = aNode->name;
126 if (!aName || !isElementNode(aNode)) {
129 if (!xmlStrcmp(aName, (const xmlChar *) theNodeName)) {
132 va_list args; // define argument list variable
133 va_start(args, theNodeName); // init list; point to last defined argument
135 char *anArg = va_arg (args, char*); // get next argument
138 if (!xmlStrcmp(aName, (const xmlChar *) anArg)) {
139 va_end(args); // cleanup the system stack
143 va_end(args); // cleanup the system stack
147 xmlNodePtr hasParentRecursive(xmlNodePtr theNode, const std::vector<const char*>& theNodeNames)
149 if (!hasParent(theNode)) {
150 return 0; // have no parents at all
152 xmlNodePtr aNode = theNode->parent;
153 const xmlChar* aName = aNode->name;
154 if (!aName || !isElementNode(aNode)) {
157 for (size_t anIndex = 0; anIndex < theNodeNames.size(); ++anIndex) {
158 if (!xmlStrcmp(aName, (const xmlChar *) theNodeNames[anIndex]))
161 return hasParentRecursive(aNode, theNodeNames);
164 xmlNodePtr hasParentRecursive(xmlNodePtr theNode, const char* theNodeName, ...)
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);
171 char *anArg = va_arg (args, char*); // get next argument
174 aNodeNames.push_back(anArg);
176 va_end(args); // cleanup the system stack
177 return hasParentRecursive(theNode, aNodeNames);
180 bool getParametersInfo(xmlNodePtr theNode, std::string& outPropertyId,
181 std::list<std::string>& outValidatorParameters)
184 char* anIdProp = (char*) xmlGetProp(theNode, BAD_CAST _ID);
185 if (!anIdProp || anIdProp[0] == 0) {
188 outPropertyId = std::string(anIdProp);
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);
204 std::string library(const std::string& theLibName)
206 if(theLibName.empty())
207 return std::string();
208 std::string aLibName = theLibName;
210 static std::string aLibExt( ".so" );
211 if (aLibName.size() < 3 || aLibName.substr(0, 3) !="lib") {
212 aLibName = "lib" + aLibName;
215 static std::string aLibExt(".dll");
217 std::string anExt = aLibName.substr(aLibName.size() - 4);
218 if (anExt != aLibExt)
224 bool BothAreSpaces(char lhs, char rhs) { return (lhs == rhs) && (lhs == ' '); }
226 std::string getProperty(xmlNodePtr theNode, const char* thePropName)
228 std::string result = "";
229 xmlChar* aPropChars = xmlGetProp(theNode, BAD_CAST thePropName);
230 if (!aPropChars || aPropChars[0] == 0)
232 result = std::string((char*)aPropChars);
235 std::string::iterator new_end = std::unique(result.begin(), result.end(), BothAreSpaces);
236 result.erase(new_end, result.end());
241 std::string getContent(xmlNodePtr theNode)
243 std::string result = "";
244 xmlChar* aContent = xmlNodeGetContent(theNode);
245 if (!aContent || aContent[0] == 0)
247 result = std::string((char*)aContent);
252 std::string getNormalizedProperty(xmlNodePtr theNode, const char* thePropName)
254 return normalize(getProperty(theNode, thePropName));
257 bool getBooleanAttribute(xmlNodePtr theNode, const char* theAttributeName, bool theDefault)
259 std::string prop = normalize(getProperty(theNode, theAttributeName));
260 bool result = theDefault;
261 if (prop == "true" || prop == "1") {
263 } else if (prop == "false" || prop == "0") {
269 CONFIG_EXPORT std::string normalize(const char* theString)
272 return std::string();
273 return normalize(std::string(theString));
276 CONFIG_EXPORT std::string normalize(const std::string& theString)
278 std::string result = theString;
279 std::transform(result.begin(), result.end(), result.begin(), ::tolower);