1 /*
2 * Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
3 * Copyright (C) 2012 - Scilab Enterprises - Calixte DENIZET
4 *
5 * Copyright (C) 2012 - 2016 - Scilab Enterprises
6 *
7 * This file is hereby licensed under the terms of the GNU GPL v2.0,
8 * pursuant to article 5.3.4 of the CeCILL v.2.1.
9 * This file was originally licensed under the terms of the CeCILL v2.1,
10 * and continues to be available under such terms.
11 * For more information, see the COPYING file which you should have received
12 * along with this program.
13 *
14 */
15
16 #include <vector>
17
18 #include "XMLObject.hxx"
19 #include "XMLDocument.hxx"
20 #include "XMLElement.hxx"
21 #include "XMLNs.hxx"
22 #include "XMLAttr.hxx"
23 #include "XMLNodeList.hxx"
24
25 extern "C"
26 {
27 #include <string.h>
28 #include <stdio.h>
29 #include "gw_xml.h"
30 #include "Scierror.h"
31 #include "api_scilab.h"
32 #include "xml_mlist.h"
33 #include "xml_constants.h"
34 #include "localization.h"
35 #include "os_string.h"
36 }
37
38 using namespace org_modules_xml;
39
40 /*--------------------------------------------------------------------------*/
41
42 /**
43 * Creates a string on stack
44 * @param fname the function name
45 * @param str the string to put
46 * @param pos the stack position
47 * @return 1 if all is ok, else 0
48 */
createStringOnStack(char * fname,const char * str,int pos,void * pvApiCtx)49 int createStringOnStack(char * fname, const char * str, int pos, void* pvApiCtx)
50 {
51 SciErr err;
52
53 if (!str)
54 {
55 str = "";
56 }
57
58 if (strchr(str, '\n'))
59 {
60 char * tok = os_strdup(str);
61 char * stok = tok;
62 std::vector<char *> vector = std::vector<char *>();
63
64 tok = strtok(tok, "\n");
65 while (tok)
66 {
67 vector.push_back(tok);
68 tok = strtok(0, "\n");
69 }
70
71 if (vector.size())
72 {
73 err = createMatrixOfString(pvApiCtx, pos, (int)vector.size(), 1, const_cast<const char * const *>(&(vector[0])));
74 }
75 else
76 {
77 err = createMatrixOfDouble(pvApiCtx, pos, 0, 0, 0);
78 }
79
80 free(stok);
81 }
82 else
83 {
84 err = createMatrixOfString(pvApiCtx, pos, 1, 1, const_cast<const char * const *>(&str));
85 }
86
87 if (err.iErr)
88 {
89 printError(&err, 0);
90 return 0;
91 }
92
93 return 1;
94 }
95 /*--------------------------------------------------------------------------*/
96 /**
97 * Creates a new variable on stack according to the requested field
98 * @param fname the function name
99 * @param doc the document
100 * @param field the field name
101 * @param pos the stack position
102 * @return 1 if all is ok, else 0
103 */
createVariableOnStack(char * fname,org_modules_xml::XMLDocument & doc,const char * field,int pos,void * pvApiCtx)104 int createVariableOnStack(char * fname, org_modules_xml::XMLDocument & doc, const char * field, int pos, void* pvApiCtx)
105 {
106 if (!strcmp("root", field))
107 {
108 const XMLElement * e = doc.getRoot();
109 if (!e)
110 {
111 Scierror(999, gettext("%s: No root element.\n"), fname, field);
112 return 0;
113 }
114 return e->createOnStack(pos, pvApiCtx);
115 }
116 else if (!strcmp("url", field))
117 {
118 return createStringOnStack(fname, doc.getDocumentURL(), pos, pvApiCtx);
119 }
120 else
121 {
122 Scierror(999, gettext("%s: Unknown field: %s\n"), fname, field);
123 return 0;
124 }
125 }
126 /*--------------------------------------------------------------------------*/
127
128 /**
129 * Creates a new variable on stack according to the requested field
130 * @param fname the function name
131 * @param elem the element
132 * @param field the field name
133 * @param pos the stack position
134 * @return 1 if all is ok, else 0
135 */
createVariableOnStack(char * fname,XMLElement & elem,const char * field,int pos,void * pvApiCtx)136 int createVariableOnStack(char * fname, XMLElement & elem, const char * field, int pos, void* pvApiCtx)
137 {
138 if (!strcmp("name", field))
139 {
140 return createStringOnStack(fname, elem.getNodeName(), pos, pvApiCtx);
141 }
142 else if (!strcmp("namespace", field))
143 {
144 const XMLNs * ns = elem.getNodeNameSpace();
145 if (ns)
146 {
147 return ns->createOnStack(pos, pvApiCtx);
148 }
149 else
150 {
151 createMatrixOfDouble(pvApiCtx, pos, 0, 0, 0);
152 return 1;
153 }
154 }
155 else if (!strcmp("content", field))
156 {
157 const char * content = elem.getNodeContent();
158 int ret = createStringOnStack(fname, content, pos, pvApiCtx);
159 xmlFree(const_cast<char *>(content));
160 return ret;
161 }
162 else if (!strcmp("type", field))
163 {
164 return createStringOnStack(fname, nodes_type[elem.getNodeType() - 1], pos, pvApiCtx);
165 }
166 else if (!strcmp("parent", field))
167 {
168 const XMLElement * parent = elem.getParentElement();
169 if (parent)
170 {
171 return parent->createOnStack(pos, pvApiCtx);
172 }
173 else
174 {
175 createMatrixOfDouble(pvApiCtx, pos, 0, 0, 0);
176 return 1;
177 }
178 }
179 else if (!strcmp("attributes", field))
180 {
181 return elem.getAttributes()->createOnStack(pos, pvApiCtx);
182 }
183 else if (!strcmp("children", field))
184 {
185 return elem.getChildren()->createOnStack(pos, pvApiCtx);
186 }
187 else if (!strcmp("line", field))
188 {
189 double line = (double)elem.getDefinitionLine();
190 SciErr err = createMatrixOfDouble(pvApiCtx, pos, 1, 1, &line);
191 if (err.iErr)
192 {
193 printError(&err, 0);
194 Scierror(999, _("%s: Memory allocation error.\n"), fname);
195 return 0;
196 }
197
198 return 1;
199 }
200 else
201 {
202 Scierror(999, gettext("%s: Unknown field: %s\n"), fname, field);
203 }
204 return 0;
205 }
206 /*--------------------------------------------------------------------------*/
207
208 /**
209 * Creates a new variable on stack according to the requested field
210 * @param fname the function name
211 * @param ns the namespace
212 * @param field the field name
213 * @param pos the stack position
214 * @return 1 if all is ok, else 0
215 */
createVariableOnStack(char * fname,XMLNs & ns,const char * field,int pos,void * pvApiCtx)216 int createVariableOnStack(char * fname, XMLNs & ns, const char * field, int pos, void* pvApiCtx)
217 {
218 if (!strcmp("href", field))
219 {
220 return createStringOnStack(fname, ns.getHref(), pos, pvApiCtx);
221 }
222 else if (!strcmp("prefix", field))
223 {
224 return createStringOnStack(fname, ns.getPrefix(), pos, pvApiCtx);
225 }
226 else
227 {
228 Scierror(999, gettext("%s: Unknown field: %s\n"), fname, field);
229 return 0;
230 }
231 }
232 /*--------------------------------------------------------------------------*/
233
234 /**
235 * Function to handle extraction in different XMLObjects
236 * @param fname the function name
237 * @param fname_len the function name length
238 */
239 template<class T>
sci_extraction(char * fname,void * pvApiCtx)240 int sci_extraction(char * fname, void* pvApiCtx)
241 {
242 T * t;
243 int id;
244 SciErr err;
245 int * fieldaddr = 0;
246 int * mlistaddr = 0;
247 char * field = 0;
248 int ret;
249
250 CheckLhs(0, 1);
251 CheckRhs(2, 2);
252
253 err = getVarAddressFromPosition(pvApiCtx, 1, &fieldaddr);
254 if (err.iErr)
255 {
256 printError(&err, 0);
257 return 0;
258 }
259
260 if (!isStringType(pvApiCtx, fieldaddr))
261 {
262 Scierror(999, gettext("%s: Wrong type for input argument #%i: string expected.\n"), fname, 1);
263 return 0;
264 }
265
266 err = getVarAddressFromPosition(pvApiCtx, 2, &mlistaddr);
267 if (err.iErr)
268 {
269 printError(&err, 0);
270 Scierror(999, _("%s: Can not read input argument #%d.\n"), fname, 2);
271 return 0;
272 }
273
274 if (getAllocatedSingleString(pvApiCtx, fieldaddr, &field) != 0)
275 {
276 Scierror(999, _("%s: No more memory.\n"), fname);
277 return 0;
278 }
279 id = getXMLObjectId(mlistaddr, pvApiCtx);
280
281 t = XMLObject::getFromId<T>(id);
282 if (!t)
283 {
284 freeAllocatedSingleString(field);
285 Scierror(999, gettext("%s: XML object does not exist.\n"), fname);
286 return 0;
287 }
288
289 ret = createVariableOnStack(fname, *t, const_cast<char *>(field), Rhs + 1, pvApiCtx);
290 freeAllocatedSingleString(field);
291 if (ret)
292 {
293 LhsVar(1) = Rhs + 1;
294 }
295 else
296 {
297 LhsVar(1) = 0;
298 }
299 PutLhsVar();
300
301 return 0;
302 }
303