OLD | NEW |
| (Empty) |
1 #define IN_LIBEXSLT | |
2 #include "libexslt/libexslt.h" | |
3 | |
4 #if defined(WIN32) && !defined (__CYGWIN__) && (!__MINGW32__) | |
5 #include <win32config.h> | |
6 #else | |
7 #include "config.h" | |
8 #endif | |
9 | |
10 #include <libxml/tree.h> | |
11 #include <libxml/xpath.h> | |
12 #include <libxml/xpathInternals.h> | |
13 | |
14 #include <libxslt/xsltutils.h> | |
15 #include <libxslt/xsltInternals.h> | |
16 #include <libxslt/extensions.h> | |
17 | |
18 #include "exslt.h" | |
19 | |
20 /** | |
21 * exsltSetsDifferenceFunction: | |
22 * @ctxt: an XPath parser context | |
23 * @nargs: the number of arguments | |
24 * | |
25 * Wraps #xmlXPathDifference for use by the XPath processor | |
26 */ | |
27 static void | |
28 exsltSetsDifferenceFunction (xmlXPathParserContextPtr ctxt, int nargs) { | |
29 xmlNodeSetPtr arg1, arg2, ret; | |
30 | |
31 if (nargs != 2) { | |
32 xmlXPathSetArityError(ctxt); | |
33 return; | |
34 } | |
35 | |
36 arg2 = xmlXPathPopNodeSet(ctxt); | |
37 if (xmlXPathCheckError(ctxt)) { | |
38 xmlXPathSetTypeError(ctxt); | |
39 return; | |
40 } | |
41 | |
42 arg1 = xmlXPathPopNodeSet(ctxt); | |
43 if (xmlXPathCheckError(ctxt)) { | |
44 xmlXPathSetTypeError(ctxt); | |
45 return; | |
46 } | |
47 | |
48 ret = xmlXPathDifference(arg1, arg2); | |
49 | |
50 if (ret != arg1) | |
51 xmlXPathFreeNodeSet(arg1); | |
52 xmlXPathFreeNodeSet(arg2); | |
53 | |
54 xmlXPathReturnNodeSet(ctxt, ret); | |
55 } | |
56 | |
57 /** | |
58 * exsltSetsIntersectionFunction: | |
59 * @ctxt: an XPath parser context | |
60 * @nargs: the number of arguments | |
61 * | |
62 * Wraps #xmlXPathIntersection for use by the XPath processor | |
63 */ | |
64 static void | |
65 exsltSetsIntersectionFunction (xmlXPathParserContextPtr ctxt, int nargs) { | |
66 xmlNodeSetPtr arg1, arg2, ret; | |
67 | |
68 if (nargs != 2) { | |
69 xmlXPathSetArityError(ctxt); | |
70 return; | |
71 } | |
72 | |
73 arg2 = xmlXPathPopNodeSet(ctxt); | |
74 if (xmlXPathCheckError(ctxt)) { | |
75 xmlXPathSetTypeError(ctxt); | |
76 return; | |
77 } | |
78 | |
79 arg1 = xmlXPathPopNodeSet(ctxt); | |
80 if (xmlXPathCheckError(ctxt)) { | |
81 xmlXPathSetTypeError(ctxt); | |
82 return; | |
83 } | |
84 | |
85 ret = xmlXPathIntersection(arg1, arg2); | |
86 | |
87 xmlXPathFreeNodeSet(arg1); | |
88 xmlXPathFreeNodeSet(arg2); | |
89 | |
90 xmlXPathReturnNodeSet(ctxt, ret); | |
91 } | |
92 | |
93 /** | |
94 * exsltSetsDistinctFunction: | |
95 * @ctxt: an XPath parser context | |
96 * @nargs: the number of arguments | |
97 * | |
98 * Wraps #xmlXPathDistinct for use by the XPath processor | |
99 */ | |
100 static void | |
101 exsltSetsDistinctFunction (xmlXPathParserContextPtr ctxt, int nargs) { | |
102 xmlXPathObjectPtr obj; | |
103 xmlNodeSetPtr ns, ret; | |
104 int boolval = 0; | |
105 void *user = NULL; | |
106 | |
107 if (nargs != 1) { | |
108 xmlXPathSetArityError(ctxt); | |
109 return; | |
110 } | |
111 | |
112 if (ctxt->value != NULL) { | |
113 boolval = ctxt->value->boolval; | |
114 user = ctxt->value->user; | |
115 ctxt->value->boolval = 0; | |
116 ctxt->value->user = NULL; | |
117 } | |
118 ns = xmlXPathPopNodeSet(ctxt); | |
119 if (xmlXPathCheckError(ctxt)) | |
120 return; | |
121 | |
122 /* !!! must be sorted !!! */ | |
123 ret = xmlXPathDistinctSorted(ns); | |
124 | |
125 if (ret != ns) | |
126 xmlXPathFreeNodeSet(ns); | |
127 | |
128 obj = xmlXPathWrapNodeSet(ret); | |
129 obj->user = user; | |
130 obj->boolval = boolval; | |
131 valuePush((ctxt), obj); | |
132 } | |
133 | |
134 /** | |
135 * exsltSetsHasSameNodesFunction: | |
136 * @ctxt: an XPath parser context | |
137 * @nargs: the number of arguments | |
138 * | |
139 * Wraps #xmlXPathHasSameNodes for use by the XPath processor | |
140 */ | |
141 static void | |
142 exsltSetsHasSameNodesFunction (xmlXPathParserContextPtr ctxt, | |
143 int nargs) { | |
144 xmlNodeSetPtr arg1, arg2; | |
145 int ret; | |
146 | |
147 if (nargs != 2) { | |
148 xmlXPathSetArityError(ctxt); | |
149 return; | |
150 } | |
151 | |
152 arg2 = xmlXPathPopNodeSet(ctxt); | |
153 if (xmlXPathCheckError(ctxt)) { | |
154 xmlXPathSetTypeError(ctxt); | |
155 return; | |
156 } | |
157 | |
158 arg1 = xmlXPathPopNodeSet(ctxt); | |
159 if (xmlXPathCheckError(ctxt)) { | |
160 xmlXPathSetTypeError(ctxt); | |
161 return; | |
162 } | |
163 | |
164 ret = xmlXPathHasSameNodes(arg1, arg2); | |
165 | |
166 xmlXPathFreeNodeSet(arg1); | |
167 xmlXPathFreeNodeSet(arg2); | |
168 | |
169 xmlXPathReturnBoolean(ctxt, ret); | |
170 } | |
171 | |
172 /** | |
173 * exsltSetsLeadingFunction: | |
174 * @ctxt: an XPath parser context | |
175 * @nargs: the number of arguments | |
176 * | |
177 * Wraps #xmlXPathLeading for use by the XPath processor | |
178 */ | |
179 static void | |
180 exsltSetsLeadingFunction (xmlXPathParserContextPtr ctxt, int nargs) { | |
181 xmlNodeSetPtr arg1, arg2, ret; | |
182 | |
183 if (nargs != 2) { | |
184 xmlXPathSetArityError(ctxt); | |
185 return; | |
186 } | |
187 | |
188 arg2 = xmlXPathPopNodeSet(ctxt); | |
189 if (xmlXPathCheckError(ctxt)) { | |
190 xmlXPathSetTypeError(ctxt); | |
191 return; | |
192 } | |
193 | |
194 arg1 = xmlXPathPopNodeSet(ctxt); | |
195 if (xmlXPathCheckError(ctxt)) { | |
196 xmlXPathSetTypeError(ctxt); | |
197 return; | |
198 } | |
199 | |
200 /* If the second node set is empty, then the first node set is | |
201 * returned. | |
202 */ | |
203 if (xmlXPathNodeSetIsEmpty(arg2)) { | |
204 xmlXPathReturnNodeSet(ctxt, arg1); | |
205 | |
206 xmlXPathFreeNodeSet(arg2); | |
207 | |
208 return; | |
209 } | |
210 /* !!! must be sorted */ | |
211 ret = xmlXPathNodeLeadingSorted(arg1, xmlXPathNodeSetItem(arg2, 0)); | |
212 | |
213 xmlXPathFreeNodeSet(arg1); | |
214 xmlXPathFreeNodeSet(arg2); | |
215 | |
216 xmlXPathReturnNodeSet(ctxt, ret); | |
217 } | |
218 | |
219 /** | |
220 * exsltSetsTrailingFunction: | |
221 * @ctxt: an XPath parser context | |
222 * @nargs: the number of arguments | |
223 * | |
224 * Wraps #xmlXPathTrailing for use by the XPath processor | |
225 */ | |
226 static void | |
227 exsltSetsTrailingFunction (xmlXPathParserContextPtr ctxt, int nargs) { | |
228 xmlNodeSetPtr arg1, arg2, ret; | |
229 | |
230 if (nargs != 2) { | |
231 xmlXPathSetArityError(ctxt); | |
232 return; | |
233 } | |
234 | |
235 arg2 = xmlXPathPopNodeSet(ctxt); | |
236 if (xmlXPathCheckError(ctxt)) { | |
237 xmlXPathSetTypeError(ctxt); | |
238 return; | |
239 } | |
240 | |
241 arg1 = xmlXPathPopNodeSet(ctxt); | |
242 if (xmlXPathCheckError(ctxt)) { | |
243 xmlXPathSetTypeError(ctxt); | |
244 return; | |
245 } | |
246 | |
247 /* If the second node set is empty, then the first node set is | |
248 * returned. | |
249 */ | |
250 if (xmlXPathNodeSetIsEmpty(arg2)) { | |
251 xmlXPathReturnNodeSet(ctxt, arg1); | |
252 | |
253 xmlXPathFreeNodeSet(arg2); | |
254 | |
255 return; | |
256 } | |
257 /* !!! mist be sorted */ | |
258 ret = xmlXPathNodeTrailingSorted(arg1, xmlXPathNodeSetItem(arg2, 0)); | |
259 | |
260 xmlXPathFreeNodeSet(arg1); | |
261 xmlXPathFreeNodeSet(arg2); | |
262 | |
263 xmlXPathReturnNodeSet(ctxt, ret); | |
264 } | |
265 | |
266 /** | |
267 * exsltSetsRegister: | |
268 * | |
269 * Registers the EXSLT - Sets module | |
270 */ | |
271 | |
272 void | |
273 exsltSetsRegister (void) { | |
274 xsltRegisterExtModuleFunction ((const xmlChar *) "difference", | |
275 EXSLT_SETS_NAMESPACE, | |
276 exsltSetsDifferenceFunction); | |
277 xsltRegisterExtModuleFunction ((const xmlChar *) "intersection", | |
278 EXSLT_SETS_NAMESPACE, | |
279 exsltSetsIntersectionFunction); | |
280 xsltRegisterExtModuleFunction ((const xmlChar *) "distinct", | |
281 EXSLT_SETS_NAMESPACE, | |
282 exsltSetsDistinctFunction); | |
283 xsltRegisterExtModuleFunction ((const xmlChar *) "has-same-node", | |
284 EXSLT_SETS_NAMESPACE, | |
285 exsltSetsHasSameNodesFunction); | |
286 xsltRegisterExtModuleFunction ((const xmlChar *) "leading", | |
287 EXSLT_SETS_NAMESPACE, | |
288 exsltSetsLeadingFunction); | |
289 xsltRegisterExtModuleFunction ((const xmlChar *) "trailing", | |
290 EXSLT_SETS_NAMESPACE, | |
291 exsltSetsTrailingFunction); | |
292 } | |
293 | |
294 /** | |
295 * exsltSetsXpathCtxtRegister: | |
296 * | |
297 * Registers the EXSLT - Sets module for use outside XSLT | |
298 */ | |
299 int | |
300 exsltSetsXpathCtxtRegister (xmlXPathContextPtr ctxt, const xmlChar *prefix) | |
301 { | |
302 if (ctxt | |
303 && prefix | |
304 && !xmlXPathRegisterNs(ctxt, | |
305 prefix, | |
306 (const xmlChar *) EXSLT_SETS_NAMESPACE) | |
307 && !xmlXPathRegisterFuncNS(ctxt, | |
308 (const xmlChar *) "difference", | |
309 (const xmlChar *) EXSLT_SETS_NAMESPACE, | |
310 exsltSetsDifferenceFunction) | |
311 && !xmlXPathRegisterFuncNS(ctxt, | |
312 (const xmlChar *) "intersection", | |
313 (const xmlChar *) EXSLT_SETS_NAMESPACE, | |
314 exsltSetsIntersectionFunction) | |
315 && !xmlXPathRegisterFuncNS(ctxt, | |
316 (const xmlChar *) "distinct", | |
317 (const xmlChar *) EXSLT_SETS_NAMESPACE, | |
318 exsltSetsDistinctFunction) | |
319 && !xmlXPathRegisterFuncNS(ctxt, | |
320 (const xmlChar *) "has-same-node", | |
321 (const xmlChar *) EXSLT_SETS_NAMESPACE, | |
322 exsltSetsHasSameNodesFunction) | |
323 && !xmlXPathRegisterFuncNS(ctxt, | |
324 (const xmlChar *) "leading", | |
325 (const xmlChar *) EXSLT_SETS_NAMESPACE, | |
326 exsltSetsLeadingFunction) | |
327 && !xmlXPathRegisterFuncNS(ctxt, | |
328 (const xmlChar *) "trailing", | |
329 (const xmlChar *) EXSLT_SETS_NAMESPACE, | |
330 exsltSetsTrailingFunction)) { | |
331 return 0; | |
332 } | |
333 return -1; | |
334 } | |
OLD | NEW |