Copying testplugin.c to the right place really, Daniel
[platform/upstream/libxslt.git] / tests / plugins / testplugin.c
1 /*
2  * extensions.c: Implemetation of the extensions support
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 #ifdef WITH_MODULES
16
17 #include <string.h>
18 #include <limits.h>
19
20 #include <libxml/xmlmemory.h>
21 #include <libxml/tree.h>
22 #include <libxml/hash.h>
23 #include <libxml/xmlerror.h>
24 #include <libxml/parserInternals.h>
25 #include <libxml/xpathInternals.h>
26 #include <libxml/list.h>
27 #include <libxml/xmlIO.h>
28 #include "xslt.h"
29 #include "xsltInternals.h"
30 #include "xsltutils.h"
31 #include "imports.h"
32 #include "extensions.h"
33
34 #define XSLT_TESTPLUGIN_URL "http://xmlsoft.org/xslt/testplugin"
35
36 /************************************************************************
37  *                                                                      *
38  *              Test plugin module http://xmlsoft.org/xslt/testplugin                   *
39  *                                                                      *
40  ************************************************************************/
41
42 /************************************************************************
43  *                                                                      *
44  *              Test of the extension module API                        *
45  *                                                                      *
46  ************************************************************************/
47
48 static xmlChar *testData = NULL;
49 static xmlChar *testStyleData = NULL;
50
51 /**
52  * xsltExtFunctionTest:
53  * @ctxt:  the XPath Parser context
54  * @nargs:  the number of arguments
55  *
56  * function libxslt:test() for testing the extensions support.
57  */
58 static void
59 xsltExtFunctionTest(xmlXPathParserContextPtr ctxt,
60                     int nargs ATTRIBUTE_UNUSED)
61 {
62     xsltTransformContextPtr tctxt;
63     void *data = NULL;
64
65     tctxt = xsltXPathGetTransformContext(ctxt);
66
67     if (testData == NULL) {
68         xsltGenericDebug(xsltGenericDebugContext,
69                          "xsltExtFunctionTest: not initialized,"
70                          " calling xsltGetExtData\n");
71         data = xsltGetExtData(tctxt, (const xmlChar *) XSLT_TESTPLUGIN_URL);
72         if (data == NULL) {
73             xsltTransformError(tctxt, NULL, NULL,
74                                "xsltExtElementTest: not initialized\n");
75             return;
76         }
77     }
78     if (tctxt == NULL) {
79         xsltTransformError(xsltXPathGetTransformContext(ctxt), NULL, NULL,
80                            "xsltExtFunctionTest: failed to get the transformation context\n");
81         return;
82     }
83     if (data == NULL)
84         data = xsltGetExtData(tctxt, (const xmlChar *) XSLT_TESTPLUGIN_URL);
85     if (data == NULL) {
86         xsltTransformError(xsltXPathGetTransformContext(ctxt), NULL, NULL,
87                            "xsltExtFunctionTest: failed to get module data\n");
88         return;
89     }
90     if (data != testData) {
91         xsltTransformError(xsltXPathGetTransformContext(ctxt), NULL, NULL,
92                            "xsltExtFunctionTest: got wrong module data\n");
93         return;
94     }
95 #ifdef WITH_XSLT_DEBUG_FUNCTION
96     xsltGenericDebug(xsltGenericDebugContext,
97                      "libxslt:test() called with %d args\n", nargs);
98 #endif
99 }
100
101 /**
102  * xsltExtElementPreCompTest:
103  * @style:  the stylesheet
104  * @inst:  the instruction in the stylesheet
105  *
106  * Process a libxslt:test node
107  */
108 static xsltElemPreCompPtr
109 xsltExtElementPreCompTest(xsltStylesheetPtr style, xmlNodePtr inst,
110                           xsltTransformFunction function)
111 {
112     xsltElemPreCompPtr ret;
113
114     if (style == NULL) {
115         xsltTransformError(NULL, NULL, inst,
116                            "xsltExtElementTest: no transformation context\n");
117         return (NULL);
118     }
119     if (testStyleData == NULL) {
120         xsltGenericDebug(xsltGenericDebugContext,
121                          "xsltExtElementPreCompTest: not initialized,"
122                          " calling xsltStyleGetExtData\n");
123         xsltStyleGetExtData(style, (const xmlChar *) XSLT_TESTPLUGIN_URL);
124         if (testStyleData == NULL) {
125             xsltTransformError(NULL, style, inst,
126                                "xsltExtElementPreCompTest: not initialized\n");
127             if (style != NULL)
128                 style->errors++;
129             return (NULL);
130         }
131     }
132     if (inst == NULL) {
133         xsltTransformError(NULL, style, inst,
134                            "xsltExtElementPreCompTest: no instruction\n");
135         if (style != NULL)
136             style->errors++;
137         return (NULL);
138     }
139     ret = xsltNewElemPreComp(style, inst, function);
140     return (ret);
141 }
142
143 /**
144  * xsltExtElementTest:
145  * @ctxt:  an XSLT processing context
146  * @node:  The current node
147  * @inst:  the instruction in the stylesheet
148  * @comp:  precomputed informations
149  *
150  * Process a libxslt:test node
151  */
152 static void
153 xsltExtElementTest(xsltTransformContextPtr ctxt, xmlNodePtr node,
154                    xmlNodePtr inst,
155                    xsltElemPreCompPtr comp ATTRIBUTE_UNUSED)
156 {
157     xmlNodePtr commentNode;
158
159     if (testData == NULL) {
160         xsltGenericDebug(xsltGenericDebugContext,
161                          "xsltExtElementTest: not initialized,"
162                          " calling xsltGetExtData\n");
163         xsltGetExtData(ctxt, (const xmlChar *) XSLT_TESTPLUGIN_URL);
164         if (testData == NULL) {
165             xsltTransformError(ctxt, NULL, inst,
166                                "xsltExtElementTest: not initialized\n");
167             return;
168         }
169     }
170     if (ctxt == NULL) {
171         xsltTransformError(ctxt, NULL, inst,
172                            "xsltExtElementTest: no transformation context\n");
173         return;
174     }
175     if (node == NULL) {
176         xsltTransformError(ctxt, NULL, inst,
177                            "xsltExtElementTest: no current node\n");
178         return;
179     }
180     if (inst == NULL) {
181         xsltTransformError(ctxt, NULL, inst,
182                            "xsltExtElementTest: no instruction\n");
183         return;
184     }
185     if (ctxt->insert == NULL) {
186         xsltTransformError(ctxt, NULL, inst,
187                            "xsltExtElementTest: no insertion point\n");
188         return;
189     }
190     commentNode = xmlNewComment((const xmlChar *)
191                                 "libxslt:testplugin element test worked");
192     xmlAddChild(ctxt->insert, commentNode);
193 }
194
195 /**
196  * xsltExtInitTest:
197  * @ctxt:  an XSLT transformation context
198  * @URI:  the namespace URI for the extension
199  *
200  * A function called at initialization time of an XSLT extension module
201  *
202  * Returns a pointer to the module specific data for this transformation
203  */
204 static void *
205 xsltExtInitTest(xsltTransformContextPtr ctxt, const xmlChar * URI)
206 {
207     if (testStyleData == NULL) {
208         xsltGenericDebug(xsltGenericErrorContext,
209                          "xsltExtInitTest: not initialized,"
210                          " calling xsltStyleGetExtData\n");
211         xsltStyleGetExtData(ctxt->style, URI);
212         if (testStyleData == NULL) {
213             xsltTransformError(ctxt, NULL, NULL,
214                                "xsltExtInitTest: not initialized\n");
215             return (NULL);
216         }
217     }
218     if (testData != NULL) {
219         xsltTransformError(ctxt, NULL, NULL,
220                            "xsltExtInitTest: already initialized\n");
221         return (NULL);
222     }
223     testData = (void *) "test data";
224     xsltGenericDebug(xsltGenericDebugContext,
225                      "Registered test plugin module : %s\n", URI);
226     return (testData);
227 }
228
229
230 /**
231  * xsltExtShutdownTest:
232  * @ctxt:  an XSLT transformation context
233  * @URI:  the namespace URI for the extension
234  * @data:  the data associated to this module
235  *
236  * A function called at shutdown time of an XSLT extension module
237  */
238 static void
239 xsltExtShutdownTest(xsltTransformContextPtr ctxt,
240                     const xmlChar * URI, void *data)
241 {
242     if (testData == NULL) {
243         xsltTransformError(ctxt, NULL, NULL,
244                            "xsltExtShutdownTest: not initialized\n");
245         return;
246     }
247     if (data != testData) {
248         xsltTransformError(ctxt, NULL, NULL,
249                            "xsltExtShutdownTest: wrong data\n");
250     }
251     testData = NULL;
252     xsltGenericDebug(xsltGenericDebugContext,
253                      "Unregistered test plugin module : %s\n", URI);
254 }
255
256 /**
257  * xsltExtStyleInitTest:
258  * @style:  an XSLT stylesheet
259  * @URI:  the namespace URI for the extension
260  *
261  * A function called at initialization time of an XSLT extension module
262  *
263  * Returns a pointer to the module specific data for this transformation
264  */
265 static void *
266 xsltExtStyleInitTest(xsltStylesheetPtr style ATTRIBUTE_UNUSED,
267                      const xmlChar * URI)
268 {
269     if (testStyleData != NULL) {
270         xsltTransformError(NULL, NULL, NULL,
271                            "xsltExtInitTest: already initialized\n");
272         return (NULL);
273     }
274     testStyleData = (void *) "test data";
275     xsltGenericDebug(xsltGenericDebugContext,
276                      "Registered test plugin module : %s\n", URI);
277     return (testStyleData);
278 }
279
280
281 /**
282  * xsltExtStyleShutdownTest:
283  * @style:  an XSLT stylesheet
284  * @URI:  the namespace URI for the extension
285  * @data:  the data associated to this module
286  *
287  * A function called at shutdown time of an XSLT extension module
288  */
289 static void
290 xsltExtStyleShutdownTest(xsltStylesheetPtr style ATTRIBUTE_UNUSED,
291                          const xmlChar * URI, void *data)
292 {
293     if (testStyleData == NULL) {
294         xsltGenericError(xsltGenericErrorContext,
295                          "xsltExtShutdownTest: not initialized\n");
296         return;
297     }
298     if (data != testStyleData) {
299         xsltTransformError(NULL, NULL, NULL,
300                            "xsltExtShutdownTest: wrong data\n");
301     }
302     testStyleData = NULL;
303     xsltGenericDebug(xsltGenericDebugContext,
304                      "Unregistered test plugin module : %s\n", URI);
305 }
306
307 /**
308  * xmlsoft_org_xslt_testplugin_init:
309  *
310  * Registers the test plugin module
311  */
312
313 void
314 xmlsoft_org_xslt_testplugin_init(void)
315 {
316     xsltRegisterExtModuleFull((const xmlChar *) XSLT_TESTPLUGIN_URL,
317                               xsltExtInitTest, xsltExtShutdownTest,
318                               xsltExtStyleInitTest,
319                               xsltExtStyleShutdownTest);
320     xsltRegisterExtModuleFunction((const xmlChar *) "testplugin",
321                                   (const xmlChar *) XSLT_TESTPLUGIN_URL,
322                                   xsltExtFunctionTest);
323     xsltRegisterExtModuleElement((const xmlChar *) "testplugin",
324                                  (const xmlChar *) XSLT_TESTPLUGIN_URL,
325                                  xsltExtElementPreCompTest,
326                                  xsltExtElementTest);
327 }
328
329 #endif /*WITH_MODULES*/