~inkscape.dev/inkscape-devlibs64/trunk

« back to all changes in this revision

Viewing changes to python/Lib/site-packages/lxml/includes/libexslt/saxon.c

  • Committer: Eduard Braun
  • Date: 2016-10-22 16:51:19 UTC
  • Revision ID: eduard.braun2@gmx.de-20161022165119-9eosgy6lp8j1kzli
Update Python to version 2.7.12

Included modules:
  coverage 4.2
  lxml 3.6.4
  numpy 1.11.2
  scour 0.35
  six 1.10.0

Show diffs side-by-side

added added

removed removed

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