OLD | NEW |
1 /* | 1 /* |
2 * extra.c: Implementation of non-standard features | 2 * extra.c: Implementation of non-standard features |
3 * | 3 * |
4 * Reference: | 4 * Reference: |
5 * Michael Kay "XSLT Programmer's Reference" pp 637-643 | 5 * Michael Kay "XSLT Programmer's Reference" pp 637-643 |
6 * The node-set() extension function | 6 * The node-set() extension function |
7 * | 7 * |
8 * See Copyright for the status of this software. | 8 * See Copyright for the status of this software. |
9 * | 9 * |
10 * daniel@veillard.com | 10 * daniel@veillard.com |
11 */ | 11 */ |
12 | 12 |
13 #define IN_LIBXSLT | 13 #define IN_LIBXSLT |
14 #include "libxslt.h" | 14 #include "libxslt.h" |
15 | 15 |
16 #include <string.h> | 16 #include <string.h> |
17 #ifdef HAVE_TIME_H | |
18 #include <time.h> | |
19 #endif | |
20 #ifdef HAVE_STDLIB_H | 17 #ifdef HAVE_STDLIB_H |
21 #include <stdlib.h> | 18 #include <stdlib.h> |
22 #endif | 19 #endif |
23 | 20 |
24 #include <libxml/xmlmemory.h> | 21 #include <libxml/xmlmemory.h> |
25 #include <libxml/tree.h> | 22 #include <libxml/tree.h> |
26 #include <libxml/hash.h> | 23 #include <libxml/hash.h> |
27 #include <libxml/xmlerror.h> | 24 #include <libxml/xmlerror.h> |
28 #include <libxml/parserInternals.h> | 25 #include <libxml/parserInternals.h> |
29 #include "xslt.h" | 26 #include "xslt.h" |
(...skipping 111 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
141 xsltTransformError(xsltXPathGetTransformContext(ctxt), NULL, NULL, | 138 xsltTransformError(xsltXPathGetTransformContext(ctxt), NULL, NULL, |
142 "node-set() invalid arg expecting a result tree\n"); | 139 "node-set() invalid arg expecting a result tree\n"); |
143 ctxt->error = XPATH_INVALID_TYPE; | 140 ctxt->error = XPATH_INVALID_TYPE; |
144 return; | 141 return; |
145 } | 142 } |
146 if (ctxt->value->type == XPATH_XSLT_TREE) { | 143 if (ctxt->value->type == XPATH_XSLT_TREE) { |
147 ctxt->value->type = XPATH_NODESET; | 144 ctxt->value->type = XPATH_NODESET; |
148 } | 145 } |
149 } | 146 } |
150 | 147 |
151 | |
152 /* | |
153 * Okay the following really seems unportable and since it's not | |
154 * part of any standard I'm not too ashamed to do this | |
155 */ | |
156 #if defined(linux) || defined(__sun) | |
157 #if defined(HAVE_MKTIME) && defined(HAVE_LOCALTIME) && defined(HAVE_ASCTIME) | |
158 #define WITH_LOCALTIME | |
159 | |
160 /** | |
161 * xsltFunctionLocalTime: | |
162 * @ctxt: the XPath Parser context | |
163 * @nargs: the number of arguments | |
164 * | |
165 * Implement the localTime XSLT function used by NORM | |
166 * string localTime(???) | |
167 * | |
168 * This function is available in Norm's extension namespace | |
169 * Code (and comments) contributed by Norm | |
170 */ | |
171 static void | |
172 xsltFunctionLocalTime(xmlXPathParserContextPtr ctxt, int nargs) { | |
173 xmlXPathObjectPtr obj; | |
174 char *str; | |
175 char digits[5]; | |
176 char result[29]; | |
177 long int field; | |
178 time_t gmt, lmt; | |
179 struct tm gmt_tm; | |
180 struct tm *local_tm; | |
181 | |
182 if (nargs != 1) { | |
183 xsltTransformError(xsltXPathGetTransformContext(ctxt), NULL, NULL, | |
184 "localTime() : invalid number of args %d\n", nargs); | |
185 ctxt->error = XPATH_INVALID_ARITY; | |
186 return; | |
187 } | |
188 | |
189 obj = valuePop(ctxt); | |
190 | |
191 if (obj->type != XPATH_STRING) { | |
192 obj = xmlXPathConvertString(obj); | |
193 } | |
194 if (obj == NULL) { | |
195 valuePush(ctxt, xmlXPathNewString((const xmlChar *)"")); | |
196 return; | |
197 } | |
198 | |
199 str = (char *) obj->stringval; | |
200 | |
201 /* str = "$Date$" */ | |
202 memset(digits, 0, sizeof(digits)); | |
203 strncpy(digits, str+7, 4); | |
204 field = strtol(digits, NULL, 10); | |
205 gmt_tm.tm_year = field - 1900; | |
206 | |
207 memset(digits, 0, sizeof(digits)); | |
208 strncpy(digits, str+12, 2); | |
209 field = strtol(digits, NULL, 10); | |
210 gmt_tm.tm_mon = field - 1; | |
211 | |
212 memset(digits, 0, sizeof(digits)); | |
213 strncpy(digits, str+15, 2); | |
214 field = strtol(digits, NULL, 10); | |
215 gmt_tm.tm_mday = field; | |
216 | |
217 memset(digits, 0, sizeof(digits)); | |
218 strncpy(digits, str+18, 2); | |
219 field = strtol(digits, NULL, 10); | |
220 gmt_tm.tm_hour = field; | |
221 | |
222 memset(digits, 0, sizeof(digits)); | |
223 strncpy(digits, str+21, 2); | |
224 field = strtol(digits, NULL, 10); | |
225 gmt_tm.tm_min = field; | |
226 | |
227 memset(digits, 0, sizeof(digits)); | |
228 strncpy(digits, str+24, 2); | |
229 field = strtol(digits, NULL, 10); | |
230 gmt_tm.tm_sec = field; | |
231 | |
232 /* Now turn gmt_tm into a time. */ | |
233 gmt = mktime(&gmt_tm); | |
234 | |
235 | |
236 /* | |
237 * FIXME: it's been too long since I did manual memory management. | |
238 * (I swore never to do it again.) Does this introduce a memory leak? | |
239 */ | |
240 local_tm = localtime(&gmt); | |
241 | |
242 /* | |
243 * Calling localtime() has the side-effect of setting timezone. | |
244 * After we know the timezone, we can adjust for it | |
245 */ | |
246 #if !defined(__FreeBSD__) | |
247 lmt = gmt - timezone; | |
248 #else /* FreeBSD DOESN'T have such side-ffect */ | |
249 lmt = gmt - local_tm->tm_gmtoff; | |
250 #endif | |
251 /* | |
252 * FIXME: it's been too long since I did manual memory management. | |
253 * (I swore never to do it again.) Does this introduce a memory leak? | |
254 */ | |
255 local_tm = localtime(&lmt); | |
256 | |
257 /* | |
258 * Now convert local_tm back into a string. This doesn't introduce | |
259 * a memory leak, so says asctime(3). | |
260 */ | |
261 | |
262 str = asctime(local_tm); /* "Tue Jun 26 05:02:16 2001" */ | |
263 /* 0123456789 123456789 123 */ | |
264 | |
265 memset(result, 0, sizeof(result)); /* "Thu, 26 Jun 2001" */ | |
266 /* 0123456789 12345 */ | |
267 | |
268 strncpy(result, str, 20); | |
269 strcpy(result+20, "???"); /* tzname doesn't work, fake it */ | |
270 strncpy(result+23, str+19, 5); | |
271 | |
272 /* Ok, now result contains the string I want to send back. */ | |
273 valuePush(ctxt, xmlXPathNewString((xmlChar *)result)); | |
274 } | |
275 #endif | |
276 #endif /* linux or sun */ | |
277 | |
278 | |
279 /** | 148 /** |
280 * xsltRegisterExtras: | 149 * xsltRegisterExtras: |
281 * @ctxt: a XSLT process context | 150 * @ctxt: a XSLT process context |
282 * | 151 * |
283 * Registers the built-in extensions. This function is deprecated, use | 152 * Registers the built-in extensions. This function is deprecated, use |
284 * xsltRegisterAllExtras instead. | 153 * xsltRegisterAllExtras instead. |
285 */ | 154 */ |
286 void | 155 void |
287 xsltRegisterExtras(xsltTransformContextPtr ctxt ATTRIBUTE_UNUSED) { | 156 xsltRegisterExtras(xsltTransformContextPtr ctxt ATTRIBUTE_UNUSED) { |
288 xsltRegisterAllExtras(); | 157 xsltRegisterAllExtras(); |
289 } | 158 } |
290 | 159 |
291 /** | 160 /** |
292 * xsltRegisterAllExtras: | 161 * xsltRegisterAllExtras: |
293 * | 162 * |
294 * Registers the built-in extensions | 163 * Registers the built-in extensions |
295 */ | 164 */ |
296 void | 165 void |
297 xsltRegisterAllExtras (void) { | 166 xsltRegisterAllExtras (void) { |
298 xsltRegisterExtModuleFunction((const xmlChar *) "node-set", | 167 xsltRegisterExtModuleFunction((const xmlChar *) "node-set", |
299 XSLT_LIBXSLT_NAMESPACE, | 168 XSLT_LIBXSLT_NAMESPACE, |
300 xsltFunctionNodeSet); | 169 xsltFunctionNodeSet); |
301 xsltRegisterExtModuleFunction((const xmlChar *) "node-set", | 170 xsltRegisterExtModuleFunction((const xmlChar *) "node-set", |
302 XSLT_SAXON_NAMESPACE, | 171 XSLT_SAXON_NAMESPACE, |
303 xsltFunctionNodeSet); | 172 xsltFunctionNodeSet); |
304 xsltRegisterExtModuleFunction((const xmlChar *) "node-set", | 173 xsltRegisterExtModuleFunction((const xmlChar *) "node-set", |
305 XSLT_XT_NAMESPACE, | 174 XSLT_XT_NAMESPACE, |
306 xsltFunctionNodeSet); | 175 xsltFunctionNodeSet); |
307 #ifdef WITH_LOCALTIME | |
308 xsltRegisterExtModuleFunction((const xmlChar *) "localTime", | |
309 XSLT_NORM_SAXON_NAMESPACE, | |
310 xsltFunctionLocalTime); | |
311 #endif | |
312 xsltRegisterExtModuleElement((const xmlChar *) "debug", | 176 xsltRegisterExtModuleElement((const xmlChar *) "debug", |
313 XSLT_LIBXSLT_NAMESPACE, | 177 XSLT_LIBXSLT_NAMESPACE, |
314 NULL, | 178 NULL, |
315 (xsltTransformFunction) xsltDebug); | 179 (xsltTransformFunction) xsltDebug); |
316 xsltRegisterExtModuleElement((const xmlChar *) "output", | 180 xsltRegisterExtModuleElement((const xmlChar *) "output", |
317 XSLT_SAXON_NAMESPACE, | 181 XSLT_SAXON_NAMESPACE, |
318 xsltDocumentComp, | 182 xsltDocumentComp, |
319 (xsltTransformFunction) xsltDocumentElem); | 183 (xsltTransformFunction) xsltDocumentElem); |
320 xsltRegisterExtModuleElement((const xmlChar *) "write", | 184 xsltRegisterExtModuleElement((const xmlChar *) "write", |
321 XSLT_XALAN_NAMESPACE, | 185 XSLT_XALAN_NAMESPACE, |
322 xsltDocumentComp, | 186 xsltDocumentComp, |
323 (xsltTransformFunction) xsltDocumentElem); | 187 (xsltTransformFunction) xsltDocumentElem); |
324 xsltRegisterExtModuleElement((const xmlChar *) "document", | 188 xsltRegisterExtModuleElement((const xmlChar *) "document", |
325 XSLT_XT_NAMESPACE, | 189 XSLT_XT_NAMESPACE, |
326 xsltDocumentComp, | 190 xsltDocumentComp, |
327 (xsltTransformFunction) xsltDocumentElem); | 191 (xsltTransformFunction) xsltDocumentElem); |
328 xsltRegisterExtModuleElement((const xmlChar *) "document", | 192 xsltRegisterExtModuleElement((const xmlChar *) "document", |
329 XSLT_NAMESPACE, | 193 XSLT_NAMESPACE, |
330 xsltDocumentComp, | 194 xsltDocumentComp, |
331 (xsltTransformFunction) xsltDocumentElem); | 195 (xsltTransformFunction) xsltDocumentElem); |
332 } | 196 } |
OLD | NEW |