copied over the apibuild.py from libxml2, adapted a bit and regenerated
[platform/upstream/libxslt.git] / libxslt / imports.c
1 /*
2  * imports.c: Implementation of the XSLT imports
3  *
4  * Reference:
5  *   http://www.w3.org/TR/1999/REC-xslt-19991116
6  *
7  * See Copyright for the status of this software.
8  *
9  * daniel@veillard.com
10  */
11
12 #define IN_LIBXSLT
13 #include "libxslt.h"
14
15 #include <string.h>
16
17 #ifdef HAVE_SYS_TYPES_H
18 #include <sys/types.h>
19 #endif
20 #ifdef HAVE_MATH_H
21 #include <math.h>
22 #endif
23 #ifdef HAVE_FLOAT_H
24 #include <float.h>
25 #endif
26 #ifdef HAVE_IEEEFP_H
27 #include <ieeefp.h>
28 #endif
29 #ifdef HAVE_NAN_H
30 #include <nan.h>
31 #endif
32 #ifdef HAVE_CTYPE_H
33 #include <ctype.h>
34 #endif
35
36 #include <libxml/xmlmemory.h>
37 #include <libxml/tree.h>
38 #include <libxml/hash.h>
39 #include <libxml/xmlerror.h>
40 #include <libxml/uri.h>
41 #include "xslt.h"
42 #include "xsltInternals.h"
43 #include "xsltutils.h"
44 #include "imports.h"
45 #include "documents.h"
46 #include "security.h"
47
48
49
50 /************************************************************************
51  *                                                                      *
52  *                      Module interfaces                               *
53  *                                                                      *
54  ************************************************************************/
55
56 /**
57  * xsltParseStylesheetImport:
58  * @style:  the XSLT stylesheet
59  * @cur:  the import element
60  *
61  * parse an XSLT stylesheet import element
62  *
63  * Returns 0 in case of success -1 in case of failure.
64  */
65
66 int
67 xsltParseStylesheetImport(xsltStylesheetPtr style, xmlNodePtr cur) {
68     int ret = -1;
69     xmlDocPtr import = NULL;
70     xmlChar *base = NULL;
71     xmlChar *uriRef = NULL;
72     xmlChar *URI = NULL;
73     xsltStylesheetPtr res;
74     xsltSecurityPrefsPtr sec;
75
76     if ((cur == NULL) || (style == NULL))
77         return (ret);
78
79     uriRef = xsltGetNsProp(cur, (const xmlChar *)"href", XSLT_NAMESPACE);
80     if (uriRef == NULL) {
81         xsltTransformError(NULL, style, cur,
82             "xsl:import : missing href attribute\n");
83         goto error;
84     }
85
86     base = xmlNodeGetBase(style->doc, cur);
87     URI = xmlBuildURI(uriRef, base);
88     if (URI == NULL) {
89         xsltTransformError(NULL, style, cur,
90             "xsl:import : invalid URI reference %s\n", uriRef);
91         goto error;
92     }
93
94     /*
95      * Security framework check
96      */
97     sec = xsltGetDefaultSecurityPrefs();
98     if (sec != NULL) {
99         int secres;
100
101         secres = xsltCheckRead(sec, NULL, URI);
102         if (secres == 0) {
103             xsltTransformError(NULL, NULL, NULL,
104                  "xsl:import: read rights for %s denied\n",
105                              URI);
106             goto error;
107         }
108     }
109
110     import = xmlParseFile((const char *)URI);
111     if (import == NULL) {
112         xsltTransformError(NULL, style, cur,
113             "xsl:import : unable to load %s\n", URI);
114         goto error;
115     }
116
117     res = xsltParseStylesheetDoc(import);
118     if (res != NULL) {
119         res->parent = style;
120         res->next = style->imports;
121         style->imports = res;
122         style->extrasNr += res->extrasNr;
123         ret = 0;
124     } else {
125         xmlFreeDoc(import);
126         }
127
128 error:
129     if (uriRef != NULL)
130         xmlFree(uriRef);
131     if (base != NULL)
132         xmlFree(base);
133     if (URI != NULL)
134         xmlFree(URI);
135
136     return (ret);
137 }
138
139 /**
140  * xsltParseStylesheetInclude:
141  * @style:  the XSLT stylesheet
142  * @cur:  the include node
143  *
144  * parse an XSLT stylesheet include element
145  *
146  * Returns 0 in case of success -1 in case of failure
147  */
148
149 int
150 xsltParseStylesheetInclude(xsltStylesheetPtr style, xmlNodePtr cur) {
151     int ret = -1;
152     xmlDocPtr oldDoc;
153     xmlChar *base = NULL;
154     xmlChar *uriRef = NULL;
155     xmlChar *URI = NULL;
156     xsltDocumentPtr include;
157
158     if ((cur == NULL) || (style == NULL))
159         return (ret);
160
161     uriRef = xsltGetNsProp(cur, (const xmlChar *)"href", XSLT_NAMESPACE);
162     if (uriRef == NULL) {
163         xsltTransformError(NULL, style, cur,
164             "xsl:include : missing href attribute\n");
165         goto error;
166     }
167
168     base = xmlNodeGetBase(style->doc, cur);
169     URI = xmlBuildURI(uriRef, base);
170     if (URI == NULL) {
171         xsltTransformError(NULL, style, cur,
172             "xsl:include : invalid URI reference %s\n", uriRef);
173         goto error;
174     }
175
176     include = xsltLoadStyleDocument(style, URI);
177     if (include == NULL) {
178         xsltTransformError(NULL, style, cur,
179             "xsl:include : unable to load %s\n", URI);
180         goto error;
181     }
182
183     oldDoc = style->doc;
184     style->doc = include->doc;
185     ret = (int)xsltParseStylesheetProcess(style, include->doc);
186     style->doc = oldDoc;
187     if (ret == 0) {
188                 ret = -1;
189                 goto error;
190         }
191     ret = 0;
192
193 error:
194     if (uriRef != NULL)
195         xmlFree(uriRef);
196     if (base != NULL)
197         xmlFree(base);
198     if (URI != NULL)
199         xmlFree(URI);
200
201     return (ret);
202 }
203
204 /**
205  * xsltNextImport:
206  * @cur:  the current XSLT stylesheet
207  *
208  * Find the next stylesheet in import precedence.
209  *
210  * Returns the next stylesheet or NULL if it was the last one
211  */
212
213 xsltStylesheetPtr
214 xsltNextImport(xsltStylesheetPtr cur) {
215     if (cur == NULL)
216         return(NULL);
217     if (cur->imports != NULL)
218         return(cur->imports);
219     if (cur->next != NULL)
220         return(cur->next) ;
221     do {
222         cur = cur->parent;
223         if (cur == NULL) return(NULL);
224         if (cur->next != NULL) return(cur->next);
225     } while (cur != NULL);
226     return(cur);
227 }
228
229 /**
230  * xsltNeedElemSpaceHandling:
231  * @ctxt:  an XSLT transformation context
232  *
233  * Checks whether that stylesheet requires white-space stripping
234  *
235  * Returns 1 if space should be stripped, 0 if not
236  */
237
238 int
239 xsltNeedElemSpaceHandling(xsltTransformContextPtr ctxt) {
240     xsltStylesheetPtr style;
241
242     if (ctxt == NULL)
243         return(0);
244     style = ctxt->style;
245     while (style != NULL) {
246         if (style->stripSpaces != NULL)
247             return(1);
248         style = xsltNextImport(style);
249     }
250     return(0);
251 }
252
253 /**
254  * xsltFindElemSpaceHandling:
255  * @ctxt:  an XSLT transformation context
256  * @node:  an XML node
257  *
258  * Find strip-space or preserve-space informations for an element
259  * respect the import precedence or the wildcards
260  *
261  * Returns 1 if space should be stripped, 0 if not, and 2 if everything
262  *         should be CDTATA wrapped.
263  */
264
265 int
266 xsltFindElemSpaceHandling(xsltTransformContextPtr ctxt, xmlNodePtr node) {
267     xsltStylesheetPtr style;
268     const xmlChar *val;
269
270     if ((ctxt == NULL) || (node == NULL))
271         return(0);
272     style = ctxt->style;
273     while (style != NULL) {
274         if (node->ns != NULL) {
275             val = (const xmlChar *)
276               xmlHashLookup2(style->stripSpaces, node->name, node->ns->href);
277         } else {
278             val = (const xmlChar *)
279                   xmlHashLookup2(style->stripSpaces, node->name, NULL);
280         }
281         if (val != NULL) {
282             if (xmlStrEqual(val, (xmlChar *) "strip"))
283                 return(1);
284             if (xmlStrEqual(val, (xmlChar *) "preserve"))
285                 return(0);
286         } 
287         if (style->stripAll == 1)
288             return(1);
289         if (style->stripAll == -1)
290             return(0);
291
292         style = xsltNextImport(style);
293     }
294     return(0);
295 }
296
297 /**
298  * xsltFindTemplate:
299  * @ctxt:  an XSLT transformation context
300  * @name: the template name
301  * @nameURI: the template name URI
302  *
303  * Finds the named template, apply import precedence rule.
304  *
305  * Returns the xsltTemplatePtr or NULL if not found
306  */
307 xsltTemplatePtr
308 xsltFindTemplate(xsltTransformContextPtr ctxt, const xmlChar *name,
309                  const xmlChar *nameURI) {
310     xsltTemplatePtr cur;
311     xsltStylesheetPtr style;
312
313     if ((ctxt == NULL) || (name == NULL))
314         return(NULL);
315     style = ctxt->style;
316     while (style != NULL) {
317         cur = style->templates;
318         while (cur != NULL) {
319             if (xmlStrEqual(name, cur->name)) {
320                 if (((nameURI == NULL) && (cur->nameURI == NULL)) ||
321                     ((nameURI != NULL) && (cur->nameURI != NULL) &&
322                      (xmlStrEqual(nameURI, cur->nameURI)))) {
323                     return(cur);
324                 }
325             }
326             cur = cur->next;
327         }
328
329         style = xsltNextImport(style);
330     }
331     return(NULL);
332 }
333