VirtualBox

source: vbox/trunk/src/libs/libxslt-1.1.22/libexslt/dynamic.c@ 28321

Last change on this file since 28321 was 7299, checked in by vboxsync, 17 years ago

Added vboxconfig.h for linux builds.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Date Revision Author Id
File size: 8.6 KB
Line 
1/*
2 * dynamic.c: Implementation of the EXSLT -- Dynamic module
3 *
4 * References:
5 * http://www.exslt.org/dyn/dyn.html
6 *
7 * See Copyright for the status of this software.
8 *
9 * Authors:
10 * Mark Vakoc <mark_vakoc@jdedwards.com>
11 * Thomas Broyer <tbroyer@ltgt.net>
12 *
13 * TODO:
14 * elements:
15 * functions:
16 * min
17 * max
18 * sum
19 * map
20 * closure
21 */
22
23#define IN_LIBEXSLT
24#include "libexslt/libexslt.h"
25
26#if defined(WIN32) && !defined (__CYGWIN__) && (!__MINGW32__)
27#include <win32config.h>
28#elif defined(VBOX)
29#include "vboxconfig.h"
30#else
31#include "config.h"
32#endif
33
34#include <libxml/tree.h>
35#include <libxml/xpath.h>
36#include <libxml/xpathInternals.h>
37
38#include <libxslt/xsltconfig.h>
39#include <libxslt/xsltutils.h>
40#include <libxslt/xsltInternals.h>
41#include <libxslt/extensions.h>
42
43#include "exslt.h"
44
45/**
46 * exsltDynEvaluateFunction:
47 * @ctxt: an XPath parser context
48 * @nargs: the number of arguments
49 *
50 * Evaluates the string as an XPath expression and returns the result
51 * value, which may be a boolean, number, string, node set, result tree
52 * fragment or external object.
53 */
54
55static void
56exsltDynEvaluateFunction(xmlXPathParserContextPtr ctxt, int nargs) {
57 xmlChar *str = NULL;
58 xmlXPathObjectPtr ret = NULL;
59
60 if (ctxt == NULL)
61 return;
62 if (nargs != 1) {
63 xsltPrintErrorContext(xsltXPathGetTransformContext(ctxt), NULL, NULL);
64 xsltGenericError(xsltGenericErrorContext,
65 "dyn:evalute() : invalid number of args %d\n", nargs);
66 ctxt->error = XPATH_INVALID_ARITY;
67 return;
68 }
69 str = xmlXPathPopString(ctxt);
70 /* return an empty node-set if an empty string is passed in */
71 if (!str||!xmlStrlen(str)) {
72 if (str) xmlFree(str);
73 valuePush(ctxt,xmlXPathNewNodeSet(NULL));
74 return;
75 }
76 ret = xmlXPathEval(str,ctxt->context);
77 if (ret)
78 valuePush(ctxt,ret);
79 else {
80 xsltGenericError(xsltGenericErrorContext,
81 "dyn:evaluate() : unable to evaluate expression '%s'\n",str);
82 valuePush(ctxt,xmlXPathNewNodeSet(NULL));
83 }
84 xmlFree(str);
85 return;
86}
87
88/**
89 * exsltDynMapFunction:
90 * @ctxt: an XPath parser context
91 * @nargs: the number of arguments
92 *
93 * Evaluates the string as an XPath expression and returns the result
94 * value, which may be a boolean, number, string, node set, result tree
95 * fragment or external object.
96 */
97
98static void
99exsltDynMapFunction(xmlXPathParserContextPtr ctxt, int nargs)
100{
101 xmlChar *str = NULL;
102 xmlNodeSetPtr nodeset = NULL;
103 xmlXPathCompExprPtr comp = NULL;
104 xmlXPathObjectPtr ret = NULL;
105 xmlDocPtr oldDoc, container;
106 xmlNodePtr oldNode;
107 int oldContextSize;
108 int oldProximityPosition;
109 int i, j;
110
111
112 if (nargs != 2) {
113 xmlXPathSetArityError(ctxt);
114 return;
115 }
116 str = xmlXPathPopString(ctxt);
117 if (xmlXPathCheckError(ctxt)) {
118 xmlXPathSetTypeError(ctxt);
119 return;
120 }
121
122 nodeset = xmlXPathPopNodeSet(ctxt);
123 if (xmlXPathCheckError(ctxt)) {
124 xmlXPathSetTypeError(ctxt);
125 return;
126 }
127 if (str == NULL || !xmlStrlen(str) || !(comp = xmlXPathCompile(str))) {
128 if (nodeset != NULL)
129 xmlXPathFreeNodeSet(nodeset);
130 if (str != NULL)
131 xmlFree(str);
132 valuePush(ctxt, xmlXPathNewNodeSet(NULL));
133 return;
134 }
135
136 ret = xmlXPathNewNodeSet(NULL);
137 if (ret == NULL) {
138 xsltGenericError(xsltGenericErrorContext,
139 "exsltDynMapFunctoin: ret == NULL\n");
140 goto cleanup;
141 }
142
143 oldDoc = ctxt->context->doc;
144 oldNode = ctxt->context->node;
145 oldContextSize = ctxt->context->contextSize;
146 oldProximityPosition = ctxt->context->proximityPosition;
147
148 /**
149 * since we really don't know we're going to be adding node(s)
150 * down the road we create the RVT regardless
151 */
152 container = xsltCreateRVT(xsltXPathGetTransformContext(ctxt));
153 if (container != NULL)
154 xsltRegisterLocalRVT(xsltXPathGetTransformContext(ctxt), container);
155
156 if (nodeset && nodeset->nodeNr > 0) {
157 xmlXPathNodeSetSort(nodeset);
158 ctxt->context->contextSize = nodeset->nodeNr;
159 ctxt->context->proximityPosition = 0;
160 for (i = 0; i < nodeset->nodeNr; i++) {
161 xmlXPathObjectPtr subResult = NULL;
162
163 ctxt->context->proximityPosition++;
164 ctxt->context->node = nodeset->nodeTab[i];
165 ctxt->context->doc = nodeset->nodeTab[i]->doc;
166
167 subResult = xmlXPathCompiledEval(comp, ctxt->context);
168 if (subResult != NULL) {
169 switch (subResult->type) {
170 case XPATH_NODESET:
171 if (subResult->nodesetval != NULL)
172 for (j = 0; j < subResult->nodesetval->nodeNr;
173 j++)
174 xmlXPathNodeSetAdd(ret->nodesetval,
175 subResult->nodesetval->
176 nodeTab[j]);
177 break;
178 case XPATH_BOOLEAN:
179 if (container != NULL) {
180 xmlNodePtr cur =
181 xmlNewChild((xmlNodePtr) container, NULL,
182 BAD_CAST "boolean",
183 BAD_CAST (subResult->
184 boolval ? "true" : ""));
185 if (cur != NULL) {
186 cur->ns =
187 xmlNewNs(cur,
188 BAD_CAST
189 "http://exslt.org/common",
190 BAD_CAST "exsl");
191 xmlXPathNodeSetAddUnique(ret->nodesetval,
192 cur);
193 }
194 }
195 break;
196 case XPATH_NUMBER:
197 if (container != NULL) {
198 xmlChar *val =
199 xmlXPathCastNumberToString(subResult->
200 floatval);
201 xmlNodePtr cur =
202 xmlNewChild((xmlNodePtr) container, NULL,
203 BAD_CAST "number", val);
204 if (val != NULL)
205 xmlFree(val);
206
207 if (cur != NULL) {
208 cur->ns =
209 xmlNewNs(cur,
210 BAD_CAST
211 "http://exslt.org/common",
212 BAD_CAST "exsl");
213 xmlXPathNodeSetAddUnique(ret->nodesetval,
214 cur);
215 }
216 }
217 break;
218 case XPATH_STRING:
219 if (container != NULL) {
220 xmlNodePtr cur =
221 xmlNewChild((xmlNodePtr) container, NULL,
222 BAD_CAST "string",
223 subResult->stringval);
224 if (cur != NULL) {
225 cur->ns =
226 xmlNewNs(cur,
227 BAD_CAST
228 "http://exslt.org/common",
229 BAD_CAST "exsl");
230 xmlXPathNodeSetAddUnique(ret->nodesetval,
231 cur);
232 }
233 }
234 break;
235 default:
236 break;
237 }
238 xmlXPathFreeObject(subResult);
239 }
240 }
241 }
242 ctxt->context->doc = oldDoc;
243 ctxt->context->node = oldNode;
244 ctxt->context->contextSize = oldContextSize;
245 ctxt->context->proximityPosition = oldProximityPosition;
246
247
248 cleanup:
249 /* restore the xpath context */
250 if (comp != NULL)
251 xmlXPathFreeCompExpr(comp);
252 if (nodeset != NULL)
253 xmlXPathFreeNodeSet(nodeset);
254 if (str != NULL)
255 xmlFree(str);
256 valuePush(ctxt, ret);
257 return;
258}
259
260
261/**
262 * exsltDynRegister:
263 *
264 * Registers the EXSLT - Dynamic module
265 */
266
267void
268exsltDynRegister (void) {
269 xsltRegisterExtModuleFunction ((const xmlChar *) "evaluate",
270 EXSLT_DYNAMIC_NAMESPACE,
271 exsltDynEvaluateFunction);
272 xsltRegisterExtModuleFunction ((const xmlChar *) "map",
273 EXSLT_DYNAMIC_NAMESPACE,
274 exsltDynMapFunction);
275
276}
Note: See TracBrowser for help on using the repository browser.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette