VirtualBox

source: vbox/trunk/src/libs/libxslt-1.1.22/libxslt/extra.c@ 9441

Last change on this file since 9441 was 7296, checked in by vboxsync, 17 years ago

Added libxslt-1.1.22 sources.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Date Revision Author Id
File size: 9.6 KB
Line 
1/*
2 * extra.c: Implementation of non-standard features
3 *
4 * Reference:
5 * Michael Kay "XSLT Programmer's Reference" pp 637-643
6 * The node-set() extension function
7 *
8 * See Copyright for the status of this software.
9 *
10 * [email protected]
11 */
12
13#define IN_LIBXSLT
14#include "libxslt.h"
15
16#include <string.h>
17#ifdef HAVE_TIME_H
18#define __USE_XOPEN
19#include <time.h>
20#endif
21#ifdef HAVE_STDLIB_H
22#include <stdlib.h>
23#endif
24
25#include <libxml/xmlmemory.h>
26#include <libxml/tree.h>
27#include <libxml/hash.h>
28#include <libxml/xmlerror.h>
29#include <libxml/parserInternals.h>
30#include "xslt.h"
31#include "xsltInternals.h"
32#include "xsltutils.h"
33#include "extensions.h"
34#include "variables.h"
35#include "transform.h"
36#include "extra.h"
37#include "preproc.h"
38
39#ifdef WITH_XSLT_DEBUG
40#define WITH_XSLT_DEBUG_EXTRA
41#endif
42
43/************************************************************************
44 * *
45 * Handling of XSLT debugging *
46 * *
47 ************************************************************************/
48
49/**
50 * xsltDebug:
51 * @ctxt: an XSLT processing context
52 * @node: The current node
53 * @inst: the instruction in the stylesheet
54 * @comp: precomputed informations
55 *
56 * Process an debug node
57 */
58void
59xsltDebug(xsltTransformContextPtr ctxt, xmlNodePtr node ATTRIBUTE_UNUSED,
60 xmlNodePtr inst ATTRIBUTE_UNUSED,
61 xsltStylePreCompPtr comp ATTRIBUTE_UNUSED)
62{
63 int i, j;
64
65 xsltGenericError(xsltGenericErrorContext, "Templates:\n");
66 for (i = 0, j = ctxt->templNr - 1; ((i < 15) && (j >= 0)); i++, j--) {
67 xsltGenericError(xsltGenericErrorContext, "#%d ", i);
68 if (ctxt->templTab[j]->name != NULL)
69 xsltGenericError(xsltGenericErrorContext, "name %s ",
70 ctxt->templTab[j]->name);
71 if (ctxt->templTab[j]->match != NULL)
72 xsltGenericError(xsltGenericErrorContext, "name %s ",
73 ctxt->templTab[j]->match);
74 if (ctxt->templTab[j]->mode != NULL)
75 xsltGenericError(xsltGenericErrorContext, "name %s ",
76 ctxt->templTab[j]->mode);
77 xsltGenericError(xsltGenericErrorContext, "\n");
78 }
79 xsltGenericError(xsltGenericErrorContext, "Variables:\n");
80 for (i = 0, j = ctxt->varsNr - 1; ((i < 15) && (j >= 0)); i++, j--) {
81 xsltStackElemPtr cur;
82
83 if (ctxt->varsTab[j] == NULL)
84 continue;
85 xsltGenericError(xsltGenericErrorContext, "#%d\n", i);
86 cur = ctxt->varsTab[j];
87 while (cur != NULL) {
88 if (cur->comp == NULL) {
89 xsltGenericError(xsltGenericErrorContext,
90 "corrupted !!!\n");
91 } else if (cur->comp->type == XSLT_FUNC_PARAM) {
92 xsltGenericError(xsltGenericErrorContext, "param ");
93 } else if (cur->comp->type == XSLT_FUNC_VARIABLE) {
94 xsltGenericError(xsltGenericErrorContext, "var ");
95 }
96 if (cur->name != NULL)
97 xsltGenericError(xsltGenericErrorContext, "%s ",
98 cur->name);
99 else
100 xsltGenericError(xsltGenericErrorContext, "noname !!!!");
101#ifdef LIBXML_DEBUG_ENABLED
102 if (cur->value != NULL) {
103 xmlXPathDebugDumpObject(stdout, cur->value, 1);
104 } else {
105 xsltGenericError(xsltGenericErrorContext, "NULL !!!!");
106 }
107#endif
108 xsltGenericError(xsltGenericErrorContext, "\n");
109 cur = cur->next;
110 }
111
112 }
113}
114
115/************************************************************************
116 * *
117 * Classic extensions as described by M. Kay *
118 * *
119 ************************************************************************/
120
121/**
122 * xsltFunctionNodeSet:
123 * @ctxt: the XPath Parser context
124 * @nargs: the number of arguments
125 *
126 * Implement the node-set() XSLT function
127 * node-set node-set(result-tree)
128 *
129 * This function is available in libxslt, saxon or xt namespace.
130 */
131void
132xsltFunctionNodeSet(xmlXPathParserContextPtr ctxt, int nargs){
133 if (nargs != 1) {
134 xsltTransformError(xsltXPathGetTransformContext(ctxt), NULL, NULL,
135 "node-set() : expects one result-tree arg\n");
136 ctxt->error = XPATH_INVALID_ARITY;
137 return;
138 }
139 if ((ctxt->value == NULL) ||
140 ((ctxt->value->type != XPATH_XSLT_TREE) &&
141 (ctxt->value->type != XPATH_NODESET))) {
142 xsltTransformError(xsltXPathGetTransformContext(ctxt), NULL, NULL,
143 "node-set() invalid arg expecting a result tree\n");
144 ctxt->error = XPATH_INVALID_TYPE;
145 return;
146 }
147 if (ctxt->value->type == XPATH_XSLT_TREE) {
148 ctxt->value->type = XPATH_NODESET;
149 }
150}
151
152
153/*
154 * Okay the following really seems unportable and since it's not
155 * part of any standard I'm not too ashamed to do this
156 */
157#if defined(linux) || defined(__sun)
158#if defined(HAVE_MKTIME) && defined(HAVE_LOCALTIME) && defined(HAVE_ASCTIME)
159#define WITH_LOCALTIME
160
161/**
162 * xsltFunctionLocalTime:
163 * @ctxt: the XPath Parser context
164 * @nargs: the number of arguments
165 *
166 * Implement the localTime XSLT function used by NORM
167 * string localTime(???)
168 *
169 * This function is available in Norm's extension namespace
170 * Code (and comments) contributed by Norm
171 */
172static void
173xsltFunctionLocalTime(xmlXPathParserContextPtr ctxt, int nargs) {
174 xmlXPathObjectPtr obj;
175 char *str;
176 char digits[5];
177 char result[29];
178 long int field;
179 time_t gmt, lmt;
180 struct tm gmt_tm;
181 struct tm *local_tm;
182
183 if (nargs != 1) {
184 xsltTransformError(xsltXPathGetTransformContext(ctxt), NULL, NULL,
185 "localTime() : invalid number of args %d\n", nargs);
186 ctxt->error = XPATH_INVALID_ARITY;
187 return;
188 }
189
190 obj = valuePop(ctxt);
191
192 if (obj->type != XPATH_STRING) {
193 obj = xmlXPathConvertString(obj);
194 }
195 if (obj == NULL) {
196 valuePush(ctxt, xmlXPathNewString((const xmlChar *)""));
197 return;
198 }
199
200 str = (char *) obj->stringval;
201
202 /* str = "$Date: 2008-03-05 10:43:38 +0000 (Wed, 05 Mar 2008) $" */
203 memset(digits, 0, sizeof(digits));
204 strncpy(digits, str+7, 4);
205 field = strtol(digits, NULL, 10);
206 gmt_tm.tm_year = field - 1900;
207
208 memset(digits, 0, sizeof(digits));
209 strncpy(digits, str+12, 2);
210 field = strtol(digits, NULL, 10);
211 gmt_tm.tm_mon = field - 1;
212
213 memset(digits, 0, sizeof(digits));
214 strncpy(digits, str+15, 2);
215 field = strtol(digits, NULL, 10);
216 gmt_tm.tm_mday = field;
217
218 memset(digits, 0, sizeof(digits));
219 strncpy(digits, str+18, 2);
220 field = strtol(digits, NULL, 10);
221 gmt_tm.tm_hour = field;
222
223 memset(digits, 0, sizeof(digits));
224 strncpy(digits, str+21, 2);
225 field = strtol(digits, NULL, 10);
226 gmt_tm.tm_min = field;
227
228 memset(digits, 0, sizeof(digits));
229 strncpy(digits, str+24, 2);
230 field = strtol(digits, NULL, 10);
231 gmt_tm.tm_sec = field;
232
233 /* Now turn gmt_tm into a time. */
234 gmt = mktime(&gmt_tm);
235
236
237 /*
238 * FIXME: it's been too long since I did manual memory management.
239 * (I swore never to do it again.) Does this introduce a memory leak?
240 */
241 local_tm = localtime(&gmt);
242
243 /*
244 * Calling localtime() has the side-effect of setting timezone.
245 * After we know the timezone, we can adjust for it
246 */
247 lmt = gmt - timezone;
248
249 /*
250 * FIXME: it's been too long since I did manual memory management.
251 * (I swore never to do it again.) Does this introduce a memory leak?
252 */
253 local_tm = localtime(&lmt);
254
255 /*
256 * Now convert local_tm back into a string. This doesn't introduce
257 * a memory leak, so says asctime(3).
258 */
259
260 str = asctime(local_tm); /* "Tue Jun 26 05:02:16 2001" */
261 /* 0123456789 123456789 123 */
262
263 memset(result, 0, sizeof(result)); /* "Thu, 26 Jun 2001" */
264 /* 0123456789 12345 */
265
266 strncpy(result, str, 20);
267 strcpy(result+20, "???"); /* tzname doesn't work, fake it */
268 strncpy(result+23, str+19, 5);
269
270 /* Ok, now result contains the string I want to send back. */
271 valuePush(ctxt, xmlXPathNewString((xmlChar *)result));
272}
273#endif
274#endif /* linux or sun */
275
276
277/**
278 * xsltRegisterExtras:
279 * @ctxt: a XSLT process context
280 *
281 * Registers the built-in extensions. This function is deprecated, use
282 * xsltRegisterAllExtras instead.
283 */
284void
285xsltRegisterExtras(xsltTransformContextPtr ctxt ATTRIBUTE_UNUSED) {
286 xsltRegisterAllExtras();
287}
288
289/**
290 * xsltRegisterAllExtras:
291 *
292 * Registers the built-in extensions
293 */
294void
295xsltRegisterAllExtras (void) {
296 xsltRegisterExtModuleFunction((const xmlChar *) "node-set",
297 XSLT_LIBXSLT_NAMESPACE,
298 xsltFunctionNodeSet);
299 xsltRegisterExtModuleFunction((const xmlChar *) "node-set",
300 XSLT_SAXON_NAMESPACE,
301 xsltFunctionNodeSet);
302 xsltRegisterExtModuleFunction((const xmlChar *) "node-set",
303 XSLT_XT_NAMESPACE,
304 xsltFunctionNodeSet);
305#ifdef WITH_LOCALTIME
306 xsltRegisterExtModuleFunction((const xmlChar *) "localTime",
307 XSLT_NORM_SAXON_NAMESPACE,
308 xsltFunctionLocalTime);
309#endif
310 xsltRegisterExtModuleElement((const xmlChar *) "debug",
311 XSLT_LIBXSLT_NAMESPACE,
312 NULL,
313 (xsltTransformFunction) xsltDebug);
314 xsltRegisterExtModuleElement((const xmlChar *) "output",
315 XSLT_SAXON_NAMESPACE,
316 xsltDocumentComp,
317 (xsltTransformFunction) xsltDocumentElem);
318 xsltRegisterExtModuleElement((const xmlChar *) "write",
319 XSLT_XALAN_NAMESPACE,
320 xsltDocumentComp,
321 (xsltTransformFunction) xsltDocumentElem);
322 xsltRegisterExtModuleElement((const xmlChar *) "document",
323 XSLT_XT_NAMESPACE,
324 xsltDocumentComp,
325 (xsltTransformFunction) xsltDocumentElem);
326 xsltRegisterExtModuleElement((const xmlChar *) "document",
327 XSLT_NAMESPACE,
328 xsltDocumentComp,
329 (xsltTransformFunction) xsltDocumentElem);
330}
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