2 * Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
3 * Copyright (C) 2014 - Scilab Enterprises - Antoine ELIAS
5 * This file must be used under the terms of the CeCILL.
6 * This source file is licensed as described in the file COPYING, which
7 * you should have received as part of this distribution. The terms
8 * are also available at
9 * http://www.cecill.info/licences/Licence_CeCILL_V2-en.txt
13 #include "configvariable.hxx"
14 #include "context.hxx"
15 #include "loadlib.hxx"
16 #include "macrofile.hxx"
20 #include "FileExist.h"
21 #include "sci_malloc.h"
22 #include "os_string.h"
23 #include "expandPathVariable.h"
25 #include <libxml/xpath.h>
26 #include <libxml/xmlreader.h>
29 #define DEFAULT_ENCODING "UTF-8"
31 static char *GetXmlFileEncoding(std::string _filename);
33 types::Library* loadlib(const std::wstring& _wstXML, int* err, bool _isFile, bool _bAddInContext)
35 types::Library* lib = NULL;
37 wchar_t* pwstPathLib = expandPathVariableW((wchar_t*)_wstXML.c_str());
39 std::wstring wstOriginalPath(_wstXML);
40 std::wstring wstFile(pwstPathLib);
41 std::wstring wstPath(pwstPathLib);
46 //remove / or \ at the end
47 size_t pos = wstPath.find_last_of(L"/\\");
48 wstPath = wstPath.substr(0, pos);
49 pos = wstOriginalPath.find_last_of(L"/\\");
50 wstOriginalPath = wstOriginalPath.substr(0, pos + 1); //with ending /
54 if (wstFile.empty() == false && *wstFile.rbegin() != DIR_SEPARATORW[0])
56 wstFile += DIR_SEPARATORW;
65 *err = parseLibFile(wstFile, lst, libname);
71 lib = new types::Library(wstOriginalPath);
73 std::wstring stFilename(wstPath);
74 if (stFilename.empty() == false && *stFilename.rbegin() != DIR_SEPARATORW[0])
76 stFilename += DIR_SEPARATORW;
80 for (const auto& macro : lst)
82 lib->add(macro.second.name, new types::MacroFile(macro.second.name, stFilename + macro.second.file, libname));
88 symbol::Context* ctx = symbol::Context::getInstance();
89 symbol::Symbol sym = symbol::Symbol(libname);
90 if (ctx->isprotected(sym) == false)
105 int parseLibFile(const std::wstring& _wstXML, MacroInfoList& info, std::wstring& libname)
109 char* pstFile = wide_string_to_UTF8(_wstXML.data());
111 if (FileExist(pstFile) == FALSE)
117 char *encoding = GetXmlFileEncoding(pstFile);
119 /* Don't care about line return / empty line */
120 xmlKeepBlanksDefault(0);
121 /* check if the XML file has been encoded with utf8 (unicode) or not */
122 if (stricmp("utf-8", encoding))
130 xmlXPathContextPtr xpathCtxt = NULL;
131 xmlXPathObjectPtr xpathObj = NULL;
132 wchar_t* pstName = NULL;
133 wchar_t* pstLibName = NULL;
134 wchar_t* pstFileName = NULL;
135 wchar_t* pstMd5 = NULL;
139 doc = xmlParseFile(pstFile);
149 xpathCtxt = xmlXPathNewContext(doc);
150 xpathObj = xmlXPathEval((const xmlChar*)"//scilablib", xpathCtxt);
151 if (xpathObj && xpathObj->nodesetval->nodeMax)
153 xmlAttrPtr attrib = xpathObj->nodesetval->nodeTab[0]->properties;
154 if (xmlStrEqual(attrib->name, (const xmlChar*)"name"))
156 /* we found the tag name */
157 const char *str = (const char*)attrib->children->content;
158 pstLibName = to_wide_string(str);
159 libname = pstLibName;
161 xmlXPathFreeObject(xpathObj);
167 xmlXPathFreeContext(xpathCtxt);
169 xmlXPathFreeObject(xpathObj);
174 xpathObj = xmlXPathEval((const xmlChar*)"//scilablib/macro", xpathCtxt);
175 if (xpathObj && xpathObj->nodesetval->nodeMax)
177 /* the Xpath has been understood and there are node */
178 for (int i = 0; i < xpathObj->nodesetval->nodeNr; i++)
180 xmlAttrPtr attrib = xpathObj->nodesetval->nodeTab[i]->properties;
181 /* Get the properties of <module> */
182 while (attrib != NULL)
184 /* loop until when have read all the attributes */
185 if (xmlStrEqual(attrib->name, (const xmlChar*)"name"))
187 /* we found the tag name */
188 const char *str = (const char*)attrib->children->content;
189 pstName = to_wide_string(str);
191 else if (xmlStrEqual(attrib->name, (const xmlChar*)"file"))
193 /* we found the tag activate */
194 const char *str = (const char*)attrib->children->content;
195 pstFileName = to_wide_string(str);
197 else if (xmlStrEqual(attrib->name, (const xmlChar*)"md5"))
199 /* we found the tag activate */
200 const char *str = (const char*)attrib->children->content;
201 pstMd5 = to_wide_string(str);
203 attrib = attrib->next;
206 if (pstName && pstFileName && pstMd5)
208 info[pstFileName] = MacroInfo(pstName, pstFileName, pstMd5);
233 xmlXPathFreeObject(xpathObj);
237 xmlXPathFreeContext(xpathCtxt);
244 static char *GetXmlFileEncoding(std::string _filename)
246 char *encoding = NULL;
247 xmlDocPtr doc = NULL;
250 encoding = os_strdup(DEFAULT_ENCODING);
252 doc = xmlParseFile(_filename.c_str());
262 encoding = os_strdup((char*)doc->encoding);