| 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 |