Imported Upstream version 1.1.30_rc1
[platform/upstream/libxslt.git] / libexslt / common.c
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
14 #include <libxslt/xsltconfig.h>
15 #include <libxslt/xsltutils.h>
16 #include <libxslt/xsltInternals.h>
17 #include <libxslt/extensions.h>
18 #include <libxslt/transform.h>
19 #include <libxslt/extra.h>
20 #include <libxslt/preproc.h>
21
22 #include "exslt.h"
23
24 static void
25 exsltNodeSetFunction (xmlXPathParserContextPtr ctxt, int nargs) {
26     if (nargs != 1) {
27         xmlXPathSetArityError(ctxt);
28         return;
29     }
30     if (xmlXPathStackIsNodeSet (ctxt)) {
31         xsltFunctionNodeSet (ctxt, nargs);
32         return;
33     } else {
34         xmlDocPtr fragment;
35         xsltTransformContextPtr tctxt = xsltXPathGetTransformContext(ctxt);
36         xmlNodePtr txt;
37         xmlChar *strval;
38         xmlXPathObjectPtr obj;
39         /*
40         * SPEC EXSLT:
41         * "You can also use this function to turn a string into a text
42         * node, which is helpful if you want to pass a string to a
43         * function that only accepts a node-set."
44         */
45         fragment = xsltCreateRVT(tctxt);
46         if (fragment == NULL) {
47             xsltTransformError(tctxt, NULL, tctxt->inst,
48                 "exsltNodeSetFunction: Failed to create a tree fragment.\n");
49             tctxt->state = XSLT_STATE_STOPPED;
50             return;
51         }
52         xsltRegisterLocalRVT(tctxt, fragment);
53
54         strval = xmlXPathPopString (ctxt);
55
56         txt = xmlNewDocText (fragment, strval);
57         xmlAddChild((xmlNodePtr) fragment, txt);
58         obj = xmlXPathNewNodeSet(txt);
59         if (obj == NULL) {
60             xsltTransformError(tctxt, NULL, tctxt->inst,
61                 "exsltNodeSetFunction: Failed to create a node set object.\n");
62             tctxt->state = XSLT_STATE_STOPPED;
63         }
64         if (strval != NULL)
65             xmlFree (strval);
66
67         valuePush (ctxt, obj);
68     }
69 }
70
71 static void
72 exsltObjectTypeFunction (xmlXPathParserContextPtr ctxt, int nargs) {
73     xmlXPathObjectPtr obj, ret;
74
75     if (nargs != 1) {
76         xmlXPathSetArityError(ctxt);
77         return;
78     }
79
80     obj = valuePop(ctxt);
81
82     switch (obj->type) {
83     case XPATH_STRING:
84         ret = xmlXPathNewCString("string");
85         break;
86     case XPATH_NUMBER:
87         ret = xmlXPathNewCString("number");
88         break;
89     case XPATH_BOOLEAN:
90         ret = xmlXPathNewCString("boolean");
91         break;
92     case XPATH_NODESET:
93         ret = xmlXPathNewCString("node-set");
94         break;
95     case XPATH_XSLT_TREE:
96         ret = xmlXPathNewCString("RTF");
97         break;
98     case XPATH_USERS:
99         ret = xmlXPathNewCString("external");
100         break;
101     default:
102         xsltGenericError(xsltGenericErrorContext,
103                 "object-type() invalid arg\n");
104         ctxt->error = XPATH_INVALID_TYPE;
105         xmlXPathFreeObject(obj);
106         return;
107     }
108     xmlXPathFreeObject(obj);
109     valuePush(ctxt, ret);
110 }
111
112
113 /**
114  * exsltCommonRegister:
115  *
116  * Registers the EXSLT - Common module
117  */
118
119 void
120 exsltCommonRegister (void) {
121     xsltRegisterExtModuleFunction((const xmlChar *) "node-set",
122                                   EXSLT_COMMON_NAMESPACE,
123                                   exsltNodeSetFunction);
124     xsltRegisterExtModuleFunction((const xmlChar *) "object-type",
125                                   EXSLT_COMMON_NAMESPACE,
126                                   exsltObjectTypeFunction);
127     xsltRegisterExtModuleElement((const xmlChar *) "document",
128                                  EXSLT_COMMON_NAMESPACE,
129                                  (xsltPreComputeFunction) xsltDocumentComp,
130                                  (xsltTransformFunction) xsltDocumentElem);
131 }