15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define IN_LIBEXSLT
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "libexslt/libexslt.h"
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(WIN32) && !defined (__CYGWIN__) && (!__MINGW32__)
55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <win32config.h>
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#else
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "config.h"
85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <libxml/tree.h>
115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <libxml/xpath.h>
125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <libxml/xpathInternals.h>
135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <libxml/parser.h>
145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <libxml/encoding.h>
155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <libxml/uri.h>
165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <libxslt/xsltconfig.h>
185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <libxslt/xsltutils.h>
195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <libxslt/xsltInternals.h>
205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <libxslt/extensions.h>
215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "exslt.h"
235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/**
255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * exsltStrTokenizeFunction:
265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @ctxt: an XPath parser context
275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @nargs: the number of arguments
285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *
295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Splits up a string on the characters of the delimiter string and returns a
305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * node set of token elements, each containing one token from the string.
315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */
325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static void
335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)exsltStrTokenizeFunction(xmlXPathParserContextPtr ctxt, int nargs)
345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){
355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    xsltTransformContextPtr tctxt;
365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    xmlChar *str, *delimiters, *cur;
375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const xmlChar *token, *delimiter;
385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    xmlNodePtr node;
395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    xmlDocPtr container;
405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    xmlXPathObjectPtr ret = NULL;
415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int clen;
425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if ((nargs < 1) || (nargs > 2)) {
445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        xmlXPathSetArityError(ctxt);
455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        return;
465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (nargs == 2) {
495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        delimiters = xmlXPathPopString(ctxt);
505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        if (xmlXPathCheckError(ctxt))
515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            return;
525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    } else {
535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        delimiters = xmlStrdup((const xmlChar *) "\t\r\n ");
545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (delimiters == NULL)
565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        return;
575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    str = xmlXPathPopString(ctxt);
595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (xmlXPathCheckError(ctxt) || (str == NULL)) {
605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        xmlFree(delimiters);
615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        return;
625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    /* Return a result tree fragment */
655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    tctxt = xsltXPathGetTransformContext(ctxt);
665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (tctxt == NULL) {
675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        xsltTransformError(xsltXPathGetTransformContext(ctxt), NULL, NULL,
685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	      "exslt:tokenize : internal error tctxt == NULL\n");
695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	goto fail;
705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    container = xsltCreateRVT(tctxt);
735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (container != NULL) {
745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        xsltRegisterLocalRVT(tctxt, container);
755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        ret = xmlXPathNewNodeSet(NULL);
765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        if (ret != NULL) {
775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            for (cur = str, token = str; *cur != 0; cur += clen) {
785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	        clen = xmlUTF8Size(cur);
795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		if (*delimiters == 0) {	/* empty string case */
805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    xmlChar ctmp;
815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    ctmp = *(cur+clen);
825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    *(cur+clen) = 0;
835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    node = xmlNewDocRawNode(container, NULL,
845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                       (const xmlChar *) "token", cur);
855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    xmlAddChild((xmlNodePtr) container, node);
865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    xmlXPathNodeSetAddUnique(ret->nodesetval, node);
875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    *(cur+clen) = ctmp; /* restore the changed byte */
885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    token = cur + clen;
895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                } else for (delimiter = delimiters; *delimiter != 0;
905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)				delimiter += xmlUTF8Size(delimiter)) {
915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    if (!xmlUTF8Charcmp(cur, delimiter)) {
925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                        if (cur == token) {
935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                            /* discard empty tokens */
945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                            token = cur + clen;
955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                            break;
965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                        }
975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                        *cur = 0;	/* terminate the token */
985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                        node = xmlNewDocRawNode(container, NULL,
995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                           (const xmlChar *) "token", token);
1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			xmlAddChild((xmlNodePtr) container, node);
1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			xmlXPathNodeSetAddUnique(ret->nodesetval, node);
1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                        *cur = *delimiter; /* restore the changed byte */
1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                        token = cur + clen;
1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                        break;
1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    }
1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                }
1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            }
1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            if (token != cur) {
1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    	node = xmlNewDocRawNode(container, NULL,
1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)				    (const xmlChar *) "token", token);
1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                xmlAddChild((xmlNodePtr) container, node);
1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	        xmlXPathNodeSetAddUnique(ret->nodesetval, node);
1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            }
1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    /*
1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	     * Mark it as a function result in order to avoid garbage
1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	     * collecting of tree fragments
1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	     */
1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    xsltExtensionInstructionResultRegister(tctxt, ret);
1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        }
1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)fail:
1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (str != NULL)
1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        xmlFree(str);
1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (delimiters != NULL)
1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        xmlFree(delimiters);
1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (ret != NULL)
1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        valuePush(ctxt, ret);
1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    else
1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        valuePush(ctxt, xmlXPathNewNodeSet(NULL));
1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/**
1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * exsltStrSplitFunction:
1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @ctxt: an XPath parser context
1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @nargs: the number of arguments
1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *
1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Splits up a string on a delimiting string and returns a node set of token
1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * elements, each containing one token from the string.
1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */
1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static void
1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)exsltStrSplitFunction(xmlXPathParserContextPtr ctxt, int nargs) {
1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    xsltTransformContextPtr tctxt;
1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    xmlChar *str, *delimiter, *cur;
1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const xmlChar *token;
1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    xmlNodePtr node;
1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    xmlDocPtr container;
1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    xmlXPathObjectPtr ret = NULL;
1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int delimiterLength;
1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if ((nargs < 1) || (nargs > 2)) {
1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        xmlXPathSetArityError(ctxt);
1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        return;
1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (nargs == 2) {
1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        delimiter = xmlXPathPopString(ctxt);
1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        if (xmlXPathCheckError(ctxt))
1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            return;
1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    } else {
1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        delimiter = xmlStrdup((const xmlChar *) " ");
1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (delimiter == NULL)
1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        return;
1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    delimiterLength = xmlStrlen (delimiter);
1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    str = xmlXPathPopString(ctxt);
1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (xmlXPathCheckError(ctxt) || (str == NULL)) {
1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        xmlFree(delimiter);
1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        return;
1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    /* Return a result tree fragment */
1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    tctxt = xsltXPathGetTransformContext(ctxt);
1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (tctxt == NULL) {
1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        xsltTransformError(xsltXPathGetTransformContext(ctxt), NULL, NULL,
1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	      "exslt:tokenize : internal error tctxt == NULL\n");
1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	goto fail;
1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    /*
1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    * OPTIMIZE TODO: We are creating an xmlDoc for every split!
1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    */
1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    container = xsltCreateRVT(tctxt);
1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (container != NULL) {
1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        xsltRegisterLocalRVT(tctxt, container);
1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        ret = xmlXPathNewNodeSet(NULL);
1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        if (ret != NULL) {
1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            for (cur = str, token = str; *cur != 0; cur++) {
1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		if (delimiterLength == 0) {
1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    if (cur != token) {
1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			xmlChar tmp = *cur;
1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			*cur = 0;
1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                        node = xmlNewDocRawNode(container, NULL,
1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                           (const xmlChar *) "token", token);
1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			xmlAddChild((xmlNodePtr) container, node);
1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			xmlXPathNodeSetAddUnique(ret->nodesetval, node);
1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			*cur = tmp;
1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			token++;
2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    }
2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		}
2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		else if (!xmlStrncasecmp(cur, delimiter, delimiterLength)) {
2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    if (cur == token) {
2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			/* discard empty tokens */
2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			cur = cur + delimiterLength - 1;
2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			token = cur + 1;
2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			continue;
2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    }
2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    *cur = 0;
2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    node = xmlNewDocRawNode(container, NULL,
2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)				       (const xmlChar *) "token", token);
2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    xmlAddChild((xmlNodePtr) container, node);
2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    xmlXPathNodeSetAddUnique(ret->nodesetval, node);
2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    *cur = *delimiter;
2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    cur = cur + delimiterLength - 1;
2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    token = cur + 1;
2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                }
2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            }
2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    if (token != cur) {
2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		node = xmlNewDocRawNode(container, NULL,
2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)				   (const xmlChar *) "token", token);
2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		xmlAddChild((xmlNodePtr) container, node);
2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		xmlXPathNodeSetAddUnique(ret->nodesetval, node);
2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    }
2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    /*
2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	     * Mark it as a function result in order to avoid garbage
2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	     * collecting of tree fragments
2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	     */
2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    xsltExtensionInstructionResultRegister(tctxt, ret);
2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        }
2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)fail:
2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (str != NULL)
2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        xmlFree(str);
2365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (delimiter != NULL)
2375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        xmlFree(delimiter);
2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (ret != NULL)
2395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        valuePush(ctxt, ret);
2405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    else
2415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        valuePush(ctxt, xmlXPathNewNodeSet(NULL));
2425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/**
2455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * exsltStrEncodeUriFunction:
2465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @ctxt: an XPath parser context
2475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @nargs: the number of arguments
2485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *
2495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * URI-Escapes a string
2505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */
2515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static void
2525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)exsltStrEncodeUriFunction (xmlXPathParserContextPtr ctxt, int nargs) {
2535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int escape_all = 1, str_len = 0;
2545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    xmlChar *str = NULL, *ret = NULL, *tmp;
2555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if ((nargs < 2) || (nargs > 3)) {
2575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	xmlXPathSetArityError(ctxt);
2585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	return;
2595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
2605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (nargs >= 3) {
2625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        /* check for UTF-8 if encoding was explicitly given;
2635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)           we don't support anything else yet */
2645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        tmp = xmlXPathPopString(ctxt);
2655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        if (xmlUTF8Strlen(tmp) != 5 || xmlStrcmp((const xmlChar *)"UTF-8",tmp)) {
2665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    xmlXPathReturnEmptyString(ctxt);
2675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    xmlFree(tmp);
2685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    return;
2695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
2705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	xmlFree(tmp);
2715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
2725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    escape_all = xmlXPathPopBoolean(ctxt);
2745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    str = xmlXPathPopString(ctxt);
2765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    str_len = xmlUTF8Strlen(str);
2775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (str_len == 0) {
2795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	xmlXPathReturnEmptyString(ctxt);
2805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	xmlFree(str);
2815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	return;
2825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
2835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ret = xmlURIEscapeStr(str,(const xmlChar *)(escape_all?"-_.!~*'()":"-_.!~*'();/?:@&=+$,[]"));
2855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    xmlXPathReturnString(ctxt, ret);
2865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (str != NULL)
2885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	xmlFree(str);
2895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/**
2925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * exsltStrDecodeUriFunction:
2935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @ctxt: an XPath parser context
2945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @nargs: the number of arguments
2955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *
2965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * reverses URI-Escaping of a string
2975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */
2985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static void
2995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)exsltStrDecodeUriFunction (xmlXPathParserContextPtr ctxt, int nargs) {
3005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int str_len = 0;
3015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    xmlChar *str = NULL, *ret = NULL, *tmp;
3025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if ((nargs < 1) || (nargs > 2)) {
3045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	xmlXPathSetArityError(ctxt);
3055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	return;
3065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
3075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (nargs >= 2) {
3095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        /* check for UTF-8 if encoding was explicitly given;
3105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)           we don't support anything else yet */
3115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        tmp = xmlXPathPopString(ctxt);
3125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        if (xmlUTF8Strlen(tmp) != 5 || xmlStrcmp((const xmlChar *)"UTF-8",tmp)) {
3135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    xmlXPathReturnEmptyString(ctxt);
3145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    xmlFree(tmp);
3155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    return;
3165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
3175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	xmlFree(tmp);
3185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
3195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    str = xmlXPathPopString(ctxt);
3215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    str_len = xmlUTF8Strlen(str);
3225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (str_len == 0) {
3245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	xmlXPathReturnEmptyString(ctxt);
3255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	xmlFree(str);
3265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	return;
3275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
3285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ret = (xmlChar *) xmlURIUnescapeString((const char *)str,0,NULL);
3305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (!xmlCheckUTF8(ret)) {
3315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	/* FIXME: instead of throwing away the whole URI, we should
3325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        only discard the invalid sequence(s). How to do that? */
3335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	xmlXPathReturnEmptyString(ctxt);
3345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	xmlFree(str);
3355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	xmlFree(ret);
3365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	return;
3375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
3385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    xmlXPathReturnString(ctxt, ret);
3405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (str != NULL)
3425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	xmlFree(str);
3435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/**
3465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * exsltStrPaddingFunction:
3475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @ctxt: an XPath parser context
3485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @nargs: the number of arguments
3495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *
3505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Creates a padding string of a certain length.
3515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */
3525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static void
3535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)exsltStrPaddingFunction (xmlXPathParserContextPtr ctxt, int nargs) {
3545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int number, str_len = 0;
3555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    xmlChar *str = NULL, *ret = NULL, *tmp;
3565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if ((nargs < 1) || (nargs > 2)) {
3585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	xmlXPathSetArityError(ctxt);
3595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	return;
3605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
3615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (nargs == 2) {
3635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	str = xmlXPathPopString(ctxt);
3645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	str_len = xmlUTF8Strlen(str);
3655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
3665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (str_len == 0) {
3675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (str != NULL) xmlFree(str);
3685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	str = xmlStrdup((const xmlChar *) " ");
3695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	str_len = 1;
3705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
3715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    number = (int) xmlXPathPopNumber(ctxt);
3735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (number <= 0) {
3755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	xmlXPathReturnEmptyString(ctxt);
3765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	xmlFree(str);
3775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	return;
3785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
3795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    while (number >= str_len) {
3815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	ret = xmlStrncat(ret, str, str_len);
3825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	number -= str_len;
3835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
3845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    tmp = xmlUTF8Strndup (str, number);
3855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ret = xmlStrcat(ret, tmp);
3865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (tmp != NULL)
3875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	xmlFree (tmp);
3885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    xmlXPathReturnString(ctxt, ret);
3905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (str != NULL)
3925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	xmlFree(str);
3935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/**
3965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * exsltStrAlignFunction:
3975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @ctxt: an XPath parser context
3985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @nargs: the number of arguments
3995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *
4005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Aligns a string within another string.
4015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */
4025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static void
4035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)exsltStrAlignFunction (xmlXPathParserContextPtr ctxt, int nargs) {
4045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    xmlChar *str, *padding, *alignment, *ret;
4055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int str_l, padding_l;
4065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if ((nargs < 2) || (nargs > 3)) {
4085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	xmlXPathSetArityError(ctxt);
4095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	return;
4105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
4115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (nargs == 3)
4135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	alignment = xmlXPathPopString(ctxt);
4145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    else
4155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	alignment = NULL;
4165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    padding = xmlXPathPopString(ctxt);
4185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    str = xmlXPathPopString(ctxt);
4195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    str_l = xmlUTF8Strlen (str);
4215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    padding_l = xmlUTF8Strlen (padding);
4225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (str_l == padding_l) {
4245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	xmlXPathReturnString (ctxt, str);
4255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	xmlFree(padding);
4265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	xmlFree(alignment);
4275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	return;
4285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
4295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (str_l > padding_l) {
4315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	ret = xmlUTF8Strndup (str, padding_l);
4325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    } else {
4335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (xmlStrEqual(alignment, (const xmlChar *) "right")) {
4345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    ret = xmlUTF8Strndup (padding, padding_l - str_l);
4355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    ret = xmlStrcat (ret, str);
4365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	} else if (xmlStrEqual(alignment, (const xmlChar *) "center")) {
4375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    int left = (padding_l - str_l) / 2;
4385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    int right_start;
4395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    ret = xmlUTF8Strndup (padding, left);
4415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    ret = xmlStrcat (ret, str);
4425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    right_start = xmlUTF8Strsize (padding, left + str_l);
4445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    ret = xmlStrcat (ret, padding + right_start);
4455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	} else {
4465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    int str_s;
4475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    str_s = xmlStrlen (str);
4495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    ret = xmlStrdup (str);
4505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    ret = xmlStrcat (ret, padding + str_s);
4515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
4525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
4535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    xmlXPathReturnString (ctxt, ret);
4555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    xmlFree(str);
4575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    xmlFree(padding);
4585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    xmlFree(alignment);
4595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/**
4625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * exsltStrConcatFunction:
4635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @ctxt: an XPath parser context
4645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @nargs: the number of arguments
4655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *
4665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Takes a node set and returns the concatenation of the string values
4675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * of the nodes in that node set.  If the node set is empty, it
4685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * returns an empty string.
4695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */
4705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static void
4715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)exsltStrConcatFunction (xmlXPathParserContextPtr ctxt, int nargs) {
4725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    xmlXPathObjectPtr obj;
4735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    xmlChar *ret = NULL;
4745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int i;
4755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (nargs  != 1) {
4775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	xmlXPathSetArityError(ctxt);
4785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	return;
4795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
4805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (!xmlXPathStackIsNodeSet(ctxt)) {
4825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	xmlXPathSetTypeError(ctxt);
4835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	return;
4845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
4855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    obj = valuePop (ctxt);
4875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (xmlXPathNodeSetIsEmpty(obj->nodesetval)) {
4895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	xmlXPathReturnEmptyString(ctxt);
4905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	return;
4915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
4925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    for (i = 0; i < obj->nodesetval->nodeNr; i++) {
4945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	xmlChar *tmp;
4955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	tmp = xmlXPathCastNodeToString(obj->nodesetval->nodeTab[i]);
4965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	ret = xmlStrcat (ret, tmp);
4985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	xmlFree(tmp);
5005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
5015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    xmlXPathFreeObject (obj);
5035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    xmlXPathReturnString(ctxt, ret);
5055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/**
5085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * exsltStrReplaceInternal:
5095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @str: string to modify
5105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @searchStr: string to find
5115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @replaceStr: string to replace occurrences of searchStr
5125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *
5135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Search and replace string function used by exsltStrReplaceFunction
5145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */
5155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static xmlChar*
5165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)exsltStrReplaceInternal(const xmlChar* str, const xmlChar* searchStr,
5175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                        const xmlChar* replaceStr)
5185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){
5195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const xmlChar *curr, *next;
5205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    xmlChar *ret = NULL;
5215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int searchStrSize;
5225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    curr = str;
5245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    searchStrSize = xmlStrlen(searchStr);
5255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    do {
5275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      next = xmlStrstr(curr, searchStr);
5285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      if (next == NULL) {
5295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        ret = xmlStrcat (ret, curr);
5305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        break;
5315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      }
5325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      ret = xmlStrncat (ret, curr, next - curr);
5345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      ret = xmlStrcat (ret, replaceStr);
5355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      curr = next + searchStrSize;
5365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    } while (*curr != 0);
5375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return ret;
5395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/**
5415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * exsltStrReplaceFunction:
5425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @ctxt: an XPath parser context
5435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @nargs: the number of arguments
5445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *
5455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Takes a string, and two node sets and returns the string with all strings in
5465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * the first node set replaced by all strings in the second node set.
5475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */
5485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static void
5495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)exsltStrReplaceFunction (xmlXPathParserContextPtr ctxt, int nargs) {
5505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    xmlChar *str = NULL, *searchStr = NULL, *replaceStr = NULL;
5515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    xmlNodeSetPtr replaceSet = NULL, searchSet = NULL;
5525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    xmlChar *ret = NULL, *retSwap = NULL;
5535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int i;
5545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (nargs  != 3) {
5565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      xmlXPathSetArityError(ctxt);
5575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return;
5585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
5595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    /* pull out replace argument */
5615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (!xmlXPathStackIsNodeSet(ctxt)) {
5625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      replaceStr = xmlXPathPopString(ctxt);
5635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
5645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		else {
5655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      replaceSet = xmlXPathPopNodeSet(ctxt);
5665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      if (xmlXPathCheckError(ctxt)) {
5675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        xmlXPathSetTypeError(ctxt);
5685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        goto fail;
5695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      }
5705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
5715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    /* behavior driven by search argument from here on */
5735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (!xmlXPathStackIsNodeSet(ctxt)) {
5745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      searchStr = xmlXPathPopString(ctxt);
5755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      str = xmlXPathPopString(ctxt);
5765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      if (replaceStr == NULL) {
5785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        xmlXPathSetTypeError(ctxt);
5795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        goto fail;
5805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      }
5815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      ret = exsltStrReplaceInternal(str, searchStr, replaceStr);
5835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
5845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		else {
5855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      searchSet = xmlXPathPopNodeSet(ctxt);
5865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      if (searchSet == NULL || xmlXPathCheckError(ctxt)) {
5875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        xmlXPathSetTypeError(ctxt);
5885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        goto fail;
5895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      }
5905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      str = xmlXPathPopString(ctxt);
5925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      ret = xmlStrdup(str);
5935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      for (i = 0; i < searchSet->nodeNr; i++) {
5955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	searchStr = xmlXPathCastNodeToString(searchSet->nodeTab[i]);
5965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        if (replaceSet != NULL) {
5985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          replaceStr = NULL;
5995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          if (i < replaceSet->nodeNr) {
6005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            replaceStr = xmlXPathCastNodeToString(replaceSet->nodeTab[i]);
6015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          }
6025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          retSwap = exsltStrReplaceInternal(ret, searchStr, replaceStr);
6045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          if (replaceStr != NULL) {
6065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            xmlFree(replaceStr);
6075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            replaceStr = NULL;
6085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          }
6095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        }
6105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        else {
6115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          retSwap = exsltStrReplaceInternal(ret, searchStr, replaceStr);
6125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        }
6135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)				xmlFree(ret);
6155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        if (searchStr != NULL) {
6165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          xmlFree(searchStr);
6175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          searchStr = NULL;
6185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        }
6195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)				ret = retSwap;
6215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			}
6225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      if (replaceSet != NULL)
6245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        xmlXPathFreeNodeSet(replaceSet);
6255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      if (searchSet != NULL)
6275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        xmlXPathFreeNodeSet(searchSet);
6285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		}
6295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    xmlXPathReturnString(ctxt, ret);
6315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) fail:
6335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (replaceStr != NULL)
6345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      xmlFree(replaceStr);
6355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (searchStr != NULL)
6375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      xmlFree(searchStr);
6385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (str != NULL)
6405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      xmlFree(str);
6415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
6425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/**
6445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * exsltStrRegister:
6455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *
6465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Registers the EXSLT - Strings module
6475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */
6485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void
6505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)exsltStrRegister (void) {
6515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    xsltRegisterExtModuleFunction ((const xmlChar *) "tokenize",
6525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)				   EXSLT_STRINGS_NAMESPACE,
6535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)				   exsltStrTokenizeFunction);
6545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    xsltRegisterExtModuleFunction ((const xmlChar *) "split",
6555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)				   EXSLT_STRINGS_NAMESPACE,
6565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)				   exsltStrSplitFunction);
6575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    xsltRegisterExtModuleFunction ((const xmlChar *) "encode-uri",
6585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)				   EXSLT_STRINGS_NAMESPACE,
6595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)				   exsltStrEncodeUriFunction);
6605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    xsltRegisterExtModuleFunction ((const xmlChar *) "decode-uri",
6615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)				   EXSLT_STRINGS_NAMESPACE,
6625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)				   exsltStrDecodeUriFunction);
6635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    xsltRegisterExtModuleFunction ((const xmlChar *) "padding",
6645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)				   EXSLT_STRINGS_NAMESPACE,
6655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)				   exsltStrPaddingFunction);
6665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    xsltRegisterExtModuleFunction ((const xmlChar *) "align",
6675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)				   EXSLT_STRINGS_NAMESPACE,
6685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)				   exsltStrAlignFunction);
6695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    xsltRegisterExtModuleFunction ((const xmlChar *) "concat",
6705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)				   EXSLT_STRINGS_NAMESPACE,
6715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)				   exsltStrConcatFunction);
6725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    xsltRegisterExtModuleFunction ((const xmlChar *) "replace",
6735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)				   EXSLT_STRINGS_NAMESPACE,
6745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)				   exsltStrReplaceFunction);
6755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
6765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/**
6785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * exsltStrXpathCtxtRegister:
6795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *
6805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Registers the EXSLT - Strings module for use outside XSLT
6815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */
6825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int
6835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)exsltStrXpathCtxtRegister (xmlXPathContextPtr ctxt, const xmlChar *prefix)
6845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){
6855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (ctxt
6865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        && prefix
6875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        && !xmlXPathRegisterNs(ctxt,
6885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                               prefix,
6895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                               (const xmlChar *) EXSLT_STRINGS_NAMESPACE)
6905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        && !xmlXPathRegisterFuncNS(ctxt,
6915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                   (const xmlChar *) "encode-uri",
6925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                   (const xmlChar *) EXSLT_STRINGS_NAMESPACE,
6935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                   exsltStrEncodeUriFunction)
6945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        && !xmlXPathRegisterFuncNS(ctxt,
6955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                   (const xmlChar *) "decode-uri",
6965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                   (const xmlChar *) EXSLT_STRINGS_NAMESPACE,
6975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                   exsltStrDecodeUriFunction)
6985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        && !xmlXPathRegisterFuncNS(ctxt,
6995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                   (const xmlChar *) "padding",
7005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                   (const xmlChar *) EXSLT_STRINGS_NAMESPACE,
7015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                   exsltStrPaddingFunction)
7025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        && !xmlXPathRegisterFuncNS(ctxt,
7035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                   (const xmlChar *) "align",
7045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                   (const xmlChar *) EXSLT_STRINGS_NAMESPACE,
7055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                   exsltStrAlignFunction)
7065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        && !xmlXPathRegisterFuncNS(ctxt,
7075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                   (const xmlChar *) "concat",
7085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                   (const xmlChar *) EXSLT_STRINGS_NAMESPACE,
7095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                   exsltStrConcatFunction)
7105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        && !xmlXPathRegisterFuncNS(ctxt,
7115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                   (const xmlChar *) "replace",
7125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                   (const xmlChar *) EXSLT_STRINGS_NAMESPACE,
7135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                   exsltStrReplaceFunction)) {
7145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        return 0;
7155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
7165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return -1;
7175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
718