VirtualBox

source: vbox/trunk/src/libs/libxslt-1.1.22/libexslt/saxon.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.0 KB
Line 
1#define IN_LIBEXSLT
2#include "libexslt/libexslt.h"
3
4#if defined(WIN32) && !defined (__CYGWIN__) && (!__MINGW32__)
5#include <win32config.h>
6#elif defined(VBOX)
7#include "vboxconfig.h"
8#else
9#include "config.h"
10#endif
11
12#include <libxml/tree.h>
13#include <libxml/xpath.h>
14#include <libxml/xpathInternals.h>
15#include <libxml/parser.h>
16#include <libxml/hash.h>
17
18#include <libxslt/xsltconfig.h>
19#include <libxslt/xsltutils.h>
20#include <libxslt/xsltInternals.h>
21#include <libxslt/extensions.h>
22
23#include "exslt.h"
24
25/**
26 * exsltSaxonInit:
27 * @ctxt: an XSLT transformation context
28 * @URI: the namespace URI for the extension
29 *
30 * Initializes the SAXON module.
31 *
32 * Returns the data for this transformation
33 */
34static xmlHashTablePtr
35exsltSaxonInit (xsltTransformContextPtr ctxt ATTRIBUTE_UNUSED,
36 const xmlChar *URI ATTRIBUTE_UNUSED) {
37 return xmlHashCreate(1);
38}
39
40/**
41 * exsltSaxonShutdown:
42 * @ctxt: an XSLT transformation context
43 * @URI: the namespace URI for the extension
44 * @data: the module data to free up
45 *
46 * Shutdown the SAXON extension module
47 */
48static void
49exsltSaxonShutdown (xsltTransformContextPtr ctxt ATTRIBUTE_UNUSED,
50 const xmlChar *URI ATTRIBUTE_UNUSED,
51 xmlHashTablePtr data) {
52 xmlHashFree(data, (xmlHashDeallocator) xmlXPathFreeCompExpr);
53}
54
55
56/**
57 * exsltSaxonExpressionFunction:
58 * @ctxt: an XPath parser context
59 * @nargs: the number of arguments
60 *
61 * The supplied string must contain an XPath expression. The result of
62 * the function is a stored expression, which may be supplied as an
63 * argument to other extension functions such as saxon:eval(),
64 * saxon:sum() and saxon:distinct(). The result of the expression will
65 * usually depend on the current node. The expression may contain
66 * references to variables that are in scope at the point where
67 * saxon:expression() is called: these variables will be replaced in
68 * the stored expression with the values they take at the time
69 * saxon:expression() is called, not the values of the variables at
70 * the time the stored expression is evaluated. Similarly, if the
71 * expression contains namespace prefixes, these are interpreted in
72 * terms of the namespace declarations in scope at the point where the
73 * saxon:expression() function is called, not those in scope where the
74 * stored expression is evaluated.
75 *
76 * TODO: current implementation doesn't conform to SAXON behaviour
77 * regarding context and namespaces.
78 */
79static void
80exsltSaxonExpressionFunction (xmlXPathParserContextPtr ctxt, int nargs) {
81 xmlChar *arg;
82 xmlXPathCompExprPtr ret;
83 xmlHashTablePtr hash;
84 xsltTransformContextPtr tctxt = xsltXPathGetTransformContext(ctxt);
85
86 if (nargs != 1) {
87 xmlXPathSetArityError(ctxt);
88 return;
89 }
90
91 arg = xmlXPathPopString(ctxt);
92 if (xmlXPathCheckError(ctxt) || (arg == NULL)) {
93 xmlXPathSetTypeError(ctxt);
94 return;
95 }
96
97 hash = (xmlHashTablePtr) xsltGetExtData(tctxt,
98 ctxt->context->functionURI);
99
100 ret = xmlHashLookup(hash, arg);
101
102 if (ret == NULL) {
103 ret = xmlXPathCompile(arg);
104 if (ret == NULL) {
105 xmlFree(arg);
106 xsltGenericError(xsltGenericErrorContext,
107 "{%s}:%s: argument is not an XPath expression\n",
108 ctxt->context->functionURI, ctxt->context->function);
109 return;
110 }
111 xmlHashAddEntry(hash, arg, (void *) ret);
112 }
113
114 xmlFree(arg);
115
116 xmlXPathReturnExternal(ctxt, ret);
117}
118
119/**
120 * exsltSaxonEvalFunction:
121 * @ctxt: an XPath parser context
122 * @nargs: number of arguments
123 *
124 * Implements de SAXON eval() function:
125 * object saxon:eval (saxon:stored-expression)
126 * Returns the result of evaluating the supplied stored expression.
127 * A stored expression may be obtained as the result of calling
128 * the saxon:expression() function.
129 * The stored expression is evaluated in the current context, that
130 * is, the context node is the current node, and the context position
131 * and context size are the same as the result of calling position()
132 * or last() respectively.
133 */
134static void
135exsltSaxonEvalFunction (xmlXPathParserContextPtr ctxt, int nargs) {
136 xmlXPathCompExprPtr expr;
137 xmlXPathObjectPtr ret;
138
139 if (nargs != 1) {
140 xmlXPathSetArityError(ctxt);
141 return;
142 }
143
144 if (!xmlXPathStackIsExternal(ctxt)) {
145 xmlXPathSetTypeError(ctxt);
146 return;
147 }
148
149 expr = (xmlXPathCompExprPtr) xmlXPathPopExternal(ctxt);
150
151 ret = xmlXPathCompiledEval(expr, ctxt->context);
152
153 valuePush(ctxt, ret);
154}
155
156/**
157 * exsltSaxonEvaluateFunction:
158 * @ctxt: an XPath parser context
159 * @nargs: number of arguments
160 *
161 * Implements the SAXON evaluate() function
162 * object saxon:evaluate (string)
163 * The supplied string must contain an XPath expression. The result of
164 * the function is the result of evaluating the XPath expression. This
165 * is useful where an expression needs to be constructed at run-time or
166 * passed to the stylesheet as a parameter, for example where the sort
167 * key is determined dynamically. The context for the expression (e.g.
168 * which variables and namespaces are available) is exactly the same as
169 * if the expression were written explicitly at this point in the
170 * stylesheet. The function saxon:evaluate(string) is shorthand for
171 * saxon:eval(saxon:expression(string)).
172 */
173static void
174exsltSaxonEvaluateFunction (xmlXPathParserContextPtr ctxt, int nargs) {
175 if (nargs != 1) {
176 xmlXPathSetArityError(ctxt);
177 return;
178 }
179
180 exsltSaxonExpressionFunction(ctxt, 1);
181 exsltSaxonEvalFunction(ctxt, 1);
182}
183
184/**
185 * exsltSaxonLineNumberFunction:
186 * @ctxt: an XPath parser context
187 * @nargs: number of arguments
188 *
189 * Implements the SAXON line-number() function
190 * integer saxon:line-number()
191 *
192 * This returns the line number of the context node in the source document
193 * within the entity that contains it. There are no arguments. If line numbers
194 * are not maintained for the current document, the function returns -1. (To
195 * ensure that line numbers are maintained, use the -l option on the command
196 * line)
197 *
198 * The extension has been extended to have the following form:
199 * integer saxon:line-number([node-set-1])
200 * If a node-set is given, this extension will return the line number of the
201 * node in the argument node-set that is first in document order.
202 */
203static void
204exsltSaxonLineNumberFunction(xmlXPathParserContextPtr ctxt, int nargs) {
205 xmlNodePtr cur = NULL;
206
207 if (nargs == 0) {
208 cur = ctxt->context->node;
209 } else if (nargs == 1) {
210 xmlXPathObjectPtr obj;
211 xmlNodeSetPtr nodelist;
212 int i;
213
214 if ((ctxt->value == NULL) || (ctxt->value->type != XPATH_NODESET)) {
215 xsltTransformError(xsltXPathGetTransformContext(ctxt), NULL, NULL,
216 "saxon:line-number() : invalid arg expecting a node-set\n");
217 ctxt->error = XPATH_INVALID_TYPE;
218 return;
219 }
220
221 obj = valuePop(ctxt);
222 nodelist = obj->nodesetval;
223 if ((nodelist == NULL) || (nodelist->nodeNr <= 0)) {
224 xmlXPathFreeObject(obj);
225 valuePush(ctxt, xmlXPathNewFloat(-1));
226 return;
227 }
228 cur = nodelist->nodeTab[0];
229 for (i = 1;i < nodelist->nodeNr;i++) {
230 int ret = xmlXPathCmpNodes(cur, nodelist->nodeTab[i]);
231 if (ret == -1)
232 cur = nodelist->nodeTab[i];
233 }
234 xmlXPathFreeObject(obj);
235 } else {
236 xsltTransformError(xsltXPathGetTransformContext(ctxt), NULL, NULL,
237 "saxon:line-number() : invalid number of args %d\n",
238 nargs);
239 ctxt->error = XPATH_INVALID_ARITY;
240 return;
241 }
242
243 valuePush(ctxt, xmlXPathNewFloat(xmlGetLineNo(cur)));
244 return;
245}
246
247/**
248 * exsltSaxonRegister:
249 *
250 * Registers the SAXON extension module
251 */
252void
253exsltSaxonRegister (void) {
254 xsltRegisterExtModule (SAXON_NAMESPACE,
255 (xsltExtInitFunction) exsltSaxonInit,
256 (xsltExtShutdownFunction) exsltSaxonShutdown);
257 xsltRegisterExtModuleFunction((const xmlChar *) "expression",
258 SAXON_NAMESPACE,
259 exsltSaxonExpressionFunction);
260 xsltRegisterExtModuleFunction((const xmlChar *) "eval",
261 SAXON_NAMESPACE,
262 exsltSaxonEvalFunction);
263 xsltRegisterExtModuleFunction((const xmlChar *) "evaluate",
264 SAXON_NAMESPACE,
265 exsltSaxonEvaluateFunction);
266 xsltRegisterExtModuleFunction ((const xmlChar *) "line-number",
267 SAXON_NAMESPACE,
268 exsltSaxonLineNumberFunction);
269}
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