15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/*
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * extra.c: Implementation of non-standard features
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Reference:
55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *   Michael Kay "XSLT Programmer's Reference" pp 637-643
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *   The node-set() extension function
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *
85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * See Copyright for the status of this software.
95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *
105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * daniel@veillard.com
115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */
125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define IN_LIBXSLT
145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "libxslt.h"
155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <string.h>
175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef HAVE_TIME_H
185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <time.h>
195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef HAVE_STDLIB_H
215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <stdlib.h>
225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <libxml/xmlmemory.h>
255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <libxml/tree.h>
265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <libxml/hash.h>
275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <libxml/xmlerror.h>
285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <libxml/parserInternals.h>
295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "xslt.h"
305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "xsltInternals.h"
315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "xsltutils.h"
325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "extensions.h"
335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "variables.h"
345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "transform.h"
355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "extra.h"
365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "preproc.h"
375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef WITH_XSLT_DEBUG
395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define WITH_XSLT_DEBUG_EXTRA
405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/************************************************************************
435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 									*
445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 		Handling of XSLT debugging				*
455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 									*
465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ************************************************************************/
475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/**
495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * xsltDebug:
505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @ctxt:  an XSLT processing context
515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @node:  The current node
525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @inst:  the instruction in the stylesheet
535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @comp:  precomputed informations
545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *
555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Process an debug node
565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */
575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void
585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)xsltDebug(xsltTransformContextPtr ctxt, xmlNodePtr node ATTRIBUTE_UNUSED,
595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          xmlNodePtr inst ATTRIBUTE_UNUSED,
605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          xsltStylePreCompPtr comp ATTRIBUTE_UNUSED)
615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){
625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int i, j;
635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    xsltGenericError(xsltGenericErrorContext, "Templates:\n");
655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    for (i = 0, j = ctxt->templNr - 1; ((i < 15) && (j >= 0)); i++, j--) {
665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        xsltGenericError(xsltGenericErrorContext, "#%d ", i);
675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        if (ctxt->templTab[j]->name != NULL)
685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            xsltGenericError(xsltGenericErrorContext, "name %s ",
695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                             ctxt->templTab[j]->name);
705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        if (ctxt->templTab[j]->match != NULL)
715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            xsltGenericError(xsltGenericErrorContext, "name %s ",
725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                             ctxt->templTab[j]->match);
735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        if (ctxt->templTab[j]->mode != NULL)
745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            xsltGenericError(xsltGenericErrorContext, "name %s ",
755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                             ctxt->templTab[j]->mode);
765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        xsltGenericError(xsltGenericErrorContext, "\n");
775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    xsltGenericError(xsltGenericErrorContext, "Variables:\n");
795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    for (i = 0, j = ctxt->varsNr - 1; ((i < 15) && (j >= 0)); i++, j--) {
805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        xsltStackElemPtr cur;
815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        if (ctxt->varsTab[j] == NULL)
835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            continue;
845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        xsltGenericError(xsltGenericErrorContext, "#%d\n", i);
855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        cur = ctxt->varsTab[j];
865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        while (cur != NULL) {
875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            if (cur->comp == NULL) {
885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                xsltGenericError(xsltGenericErrorContext,
895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                 "corrupted !!!\n");
905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            } else if (cur->comp->type == XSLT_FUNC_PARAM) {
915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                xsltGenericError(xsltGenericErrorContext, "param ");
925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            } else if (cur->comp->type == XSLT_FUNC_VARIABLE) {
935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                xsltGenericError(xsltGenericErrorContext, "var ");
945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            }
955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            if (cur->name != NULL)
965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                xsltGenericError(xsltGenericErrorContext, "%s ",
975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                 cur->name);
985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            else
995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                xsltGenericError(xsltGenericErrorContext, "noname !!!!");
1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef LIBXML_DEBUG_ENABLED
1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            if (cur->value != NULL) {
1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                xmlXPathDebugDumpObject(stdout, cur->value, 1);
1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            } else {
1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                xsltGenericError(xsltGenericErrorContext, "NULL !!!!");
1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            }
1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            xsltGenericError(xsltGenericErrorContext, "\n");
1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            cur = cur->next;
1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        }
1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/************************************************************************
1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 									*
1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 		Classic extensions as described by M. Kay		*
1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 									*
1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ************************************************************************/
1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/**
1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * xsltFunctionNodeSet:
1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @ctxt:  the XPath Parser context
1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @nargs:  the number of arguments
1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *
1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Implement the node-set() XSLT function
1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *   node-set node-set(result-tree)
1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *
1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * This function is available in libxslt, saxon or xt namespace.
1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */
1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void
1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)xsltFunctionNodeSet(xmlXPathParserContextPtr ctxt, int nargs){
1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (nargs != 1) {
1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	xsltTransformError(xsltXPathGetTransformContext(ctxt), NULL, NULL,
1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		"node-set() : expects one result-tree arg\n");
1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	ctxt->error = XPATH_INVALID_ARITY;
1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	return;
1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if ((ctxt->value == NULL) ||
1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	((ctxt->value->type != XPATH_XSLT_TREE) &&
1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	 (ctxt->value->type != XPATH_NODESET))) {
1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	xsltTransformError(xsltXPathGetTransformContext(ctxt), NULL, NULL,
1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    "node-set() invalid arg expecting a result tree\n");
1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	ctxt->error = XPATH_INVALID_TYPE;
1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	return;
1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (ctxt->value->type == XPATH_XSLT_TREE) {
1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	ctxt->value->type = XPATH_NODESET;
1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/*
1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Okay the following really seems unportable and since it's not
1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * part of any standard I'm not too ashamed to do this
1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */
1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(linux) || defined(__sun)
1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(HAVE_MKTIME) && defined(HAVE_LOCALTIME) && defined(HAVE_ASCTIME)
1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define WITH_LOCALTIME
1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/**
1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * xsltFunctionLocalTime:
1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @ctxt:  the XPath Parser context
1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @nargs:  the number of arguments
1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *
1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Implement the localTime XSLT function used by NORM
1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *   string localTime(???)
1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *
1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * This function is available in Norm's extension namespace
1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Code (and comments) contributed by Norm
1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */
1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static void
1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)xsltFunctionLocalTime(xmlXPathParserContextPtr ctxt, int nargs) {
1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    xmlXPathObjectPtr obj;
1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    char *str;
1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    char digits[5];
1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    char result[29];
1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    long int field;
1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    time_t gmt, lmt;
1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    struct tm gmt_tm;
1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    struct tm *local_tm;
1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (nargs != 1) {
1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)       xsltTransformError(xsltXPathGetTransformContext(ctxt), NULL, NULL,
1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                      "localTime() : invalid number of args %d\n", nargs);
1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)       ctxt->error = XPATH_INVALID_ARITY;
1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)       return;
1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    obj = valuePop(ctxt);
1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (obj->type != XPATH_STRING) {
1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	obj = xmlXPathConvertString(obj);
1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (obj == NULL) {
1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	valuePush(ctxt, xmlXPathNewString((const xmlChar *)""));
1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	return;
1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    str = (char *) obj->stringval;
2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    /* str = "$Date$" */
2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    memset(digits, 0, sizeof(digits));
2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    strncpy(digits, str+7, 4);
2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    field = strtol(digits, NULL, 10);
2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    gmt_tm.tm_year = field - 1900;
2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    memset(digits, 0, sizeof(digits));
2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    strncpy(digits, str+12, 2);
2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    field = strtol(digits, NULL, 10);
2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    gmt_tm.tm_mon = field - 1;
2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    memset(digits, 0, sizeof(digits));
2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    strncpy(digits, str+15, 2);
2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    field = strtol(digits, NULL, 10);
2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    gmt_tm.tm_mday = field;
2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    memset(digits, 0, sizeof(digits));
2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    strncpy(digits, str+18, 2);
2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    field = strtol(digits, NULL, 10);
2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    gmt_tm.tm_hour = field;
2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    memset(digits, 0, sizeof(digits));
2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    strncpy(digits, str+21, 2);
2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    field = strtol(digits, NULL, 10);
2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    gmt_tm.tm_min = field;
2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    memset(digits, 0, sizeof(digits));
2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    strncpy(digits, str+24, 2);
2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    field = strtol(digits, NULL, 10);
2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    gmt_tm.tm_sec = field;
2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    /* Now turn gmt_tm into a time. */
2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    gmt = mktime(&gmt_tm);
2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    /*
2375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     * FIXME: it's been too long since I did manual memory management.
2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     * (I swore never to do it again.) Does this introduce a memory leak?
2395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     */
2405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    local_tm = localtime(&gmt);
2415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    /*
2435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     * Calling localtime() has the side-effect of setting timezone.
2445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     * After we know the timezone, we can adjust for it
2455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     */
2465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    lmt = gmt - timezone;
2475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    /*
2495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     * FIXME: it's been too long since I did manual memory management.
2505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     * (I swore never to do it again.) Does this introduce a memory leak?
2515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     */
2525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    local_tm = localtime(&lmt);
2535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    /*
2555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     * Now convert local_tm back into a string. This doesn't introduce
2565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     * a memory leak, so says asctime(3).
2575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     */
2585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    str = asctime(local_tm);           /* "Tue Jun 26 05:02:16 2001" */
2605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                       /*  0123456789 123456789 123 */
2615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    memset(result, 0, sizeof(result)); /* "Thu, 26 Jun 2001" */
2635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                       /*  0123456789 12345 */
2645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    strncpy(result, str, 20);
2665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    strcpy(result+20, "???");          /* tzname doesn't work, fake it */
2675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    strncpy(result+23, str+19, 5);
2685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    /* Ok, now result contains the string I want to send back. */
2705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    valuePush(ctxt, xmlXPathNewString((xmlChar *)result));
2715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
2735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif /* linux or sun */
2745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/**
2775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * xsltRegisterExtras:
2785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @ctxt:  a XSLT process context
2795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *
2805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Registers the built-in extensions. This function is deprecated, use
2815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * xsltRegisterAllExtras instead.
2825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */
2835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void
2845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)xsltRegisterExtras(xsltTransformContextPtr ctxt ATTRIBUTE_UNUSED) {
2855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    xsltRegisterAllExtras();
2865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/**
2895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * xsltRegisterAllExtras:
2905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *
2915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Registers the built-in extensions
2925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */
2935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void
2945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)xsltRegisterAllExtras (void) {
2955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    xsltRegisterExtModuleFunction((const xmlChar *) "node-set",
2965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)				  XSLT_LIBXSLT_NAMESPACE,
2975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)				  xsltFunctionNodeSet);
2985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    xsltRegisterExtModuleFunction((const xmlChar *) "node-set",
2995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)				  XSLT_SAXON_NAMESPACE,
3005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)				  xsltFunctionNodeSet);
3015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    xsltRegisterExtModuleFunction((const xmlChar *) "node-set",
3025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)				  XSLT_XT_NAMESPACE,
3035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)				  xsltFunctionNodeSet);
3045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef WITH_LOCALTIME
3055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    xsltRegisterExtModuleFunction((const xmlChar *) "localTime",
3065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)				  XSLT_NORM_SAXON_NAMESPACE,
3075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)				  xsltFunctionLocalTime);
3085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
3095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    xsltRegisterExtModuleElement((const xmlChar *) "debug",
3105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)				 XSLT_LIBXSLT_NAMESPACE,
3115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)				 NULL,
3125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)				 (xsltTransformFunction) xsltDebug);
3135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    xsltRegisterExtModuleElement((const xmlChar *) "output",
3145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)				 XSLT_SAXON_NAMESPACE,
3155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)				 xsltDocumentComp,
3165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)				 (xsltTransformFunction) xsltDocumentElem);
3175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    xsltRegisterExtModuleElement((const xmlChar *) "write",
3185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)				 XSLT_XALAN_NAMESPACE,
3195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)				 xsltDocumentComp,
3205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)				 (xsltTransformFunction) xsltDocumentElem);
3215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    xsltRegisterExtModuleElement((const xmlChar *) "document",
3225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)				 XSLT_XT_NAMESPACE,
3235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)				 xsltDocumentComp,
3245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)				 (xsltTransformFunction) xsltDocumentElem);
3255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    xsltRegisterExtModuleElement((const xmlChar *) "document",
3265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)				 XSLT_NAMESPACE,
3275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)				 xsltDocumentComp,
3285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)				 (xsltTransformFunction) xsltDocumentElem);
3295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
330