| Index: third_party/libxslt/libexslt/strings.c
|
| diff --git a/third_party/libxslt/libexslt/strings.c b/third_party/libxslt/libexslt/strings.c
|
| deleted file mode 100644
|
| index 62f76fb3c067b4fe8144c22b85000c801a233e90..0000000000000000000000000000000000000000
|
| --- a/third_party/libxslt/libexslt/strings.c
|
| +++ /dev/null
|
| @@ -1,836 +0,0 @@
|
| -#define IN_LIBEXSLT
|
| -#include "libexslt/libexslt.h"
|
| -
|
| -#if defined(WIN32) && !defined (__CYGWIN__) && (!__MINGW32__)
|
| -#include <win32config.h>
|
| -#else
|
| -#include "config.h"
|
| -#endif
|
| -
|
| -#include <libxml/tree.h>
|
| -#include <libxml/xpath.h>
|
| -#include <libxml/xpathInternals.h>
|
| -#include <libxml/parser.h>
|
| -#include <libxml/encoding.h>
|
| -#include <libxml/uri.h>
|
| -
|
| -#include <libxslt/xsltconfig.h>
|
| -#include <libxslt/xsltutils.h>
|
| -#include <libxslt/xsltInternals.h>
|
| -#include <libxslt/extensions.h>
|
| -
|
| -#include "exslt.h"
|
| -
|
| -/**
|
| - * exsltStrTokenizeFunction:
|
| - * @ctxt: an XPath parser context
|
| - * @nargs: the number of arguments
|
| - *
|
| - * Splits up a string on the characters of the delimiter string and returns a
|
| - * node set of token elements, each containing one token from the string.
|
| - */
|
| -static void
|
| -exsltStrTokenizeFunction(xmlXPathParserContextPtr ctxt, int nargs)
|
| -{
|
| - xsltTransformContextPtr tctxt;
|
| - xmlChar *str, *delimiters, *cur;
|
| - const xmlChar *token, *delimiter;
|
| - xmlNodePtr node;
|
| - xmlDocPtr container;
|
| - xmlXPathObjectPtr ret = NULL;
|
| - int clen;
|
| -
|
| - if ((nargs < 1) || (nargs > 2)) {
|
| - xmlXPathSetArityError(ctxt);
|
| - return;
|
| - }
|
| -
|
| - if (nargs == 2) {
|
| - delimiters = xmlXPathPopString(ctxt);
|
| - if (xmlXPathCheckError(ctxt))
|
| - return;
|
| - } else {
|
| - delimiters = xmlStrdup((const xmlChar *) "\t\r\n ");
|
| - }
|
| - if (delimiters == NULL)
|
| - return;
|
| -
|
| - str = xmlXPathPopString(ctxt);
|
| - if (xmlXPathCheckError(ctxt) || (str == NULL)) {
|
| - xmlFree(delimiters);
|
| - return;
|
| - }
|
| -
|
| - /* Return a result tree fragment */
|
| - tctxt = xsltXPathGetTransformContext(ctxt);
|
| - if (tctxt == NULL) {
|
| - xsltTransformError(xsltXPathGetTransformContext(ctxt), NULL, NULL,
|
| - "exslt:tokenize : internal error tctxt == NULL\n");
|
| - goto fail;
|
| - }
|
| -
|
| - container = xsltCreateRVT(tctxt);
|
| - if (container != NULL) {
|
| - xsltRegisterLocalRVT(tctxt, container);
|
| - ret = xmlXPathNewNodeSet(NULL);
|
| - if (ret != NULL) {
|
| - for (cur = str, token = str; *cur != 0; cur += clen) {
|
| - clen = xmlUTF8Size(cur);
|
| - if (*delimiters == 0) { /* empty string case */
|
| - xmlChar ctmp;
|
| - ctmp = *(cur+clen);
|
| - *(cur+clen) = 0;
|
| - node = xmlNewDocRawNode(container, NULL,
|
| - (const xmlChar *) "token", cur);
|
| - xmlAddChild((xmlNodePtr) container, node);
|
| - xmlXPathNodeSetAddUnique(ret->nodesetval, node);
|
| - *(cur+clen) = ctmp; /* restore the changed byte */
|
| - token = cur + clen;
|
| - } else for (delimiter = delimiters; *delimiter != 0;
|
| - delimiter += xmlUTF8Size(delimiter)) {
|
| - if (!xmlUTF8Charcmp(cur, delimiter)) {
|
| - if (cur == token) {
|
| - /* discard empty tokens */
|
| - token = cur + clen;
|
| - break;
|
| - }
|
| - *cur = 0; /* terminate the token */
|
| - node = xmlNewDocRawNode(container, NULL,
|
| - (const xmlChar *) "token", token);
|
| - xmlAddChild((xmlNodePtr) container, node);
|
| - xmlXPathNodeSetAddUnique(ret->nodesetval, node);
|
| - *cur = *delimiter; /* restore the changed byte */
|
| - token = cur + clen;
|
| - break;
|
| - }
|
| - }
|
| - }
|
| - if (token != cur) {
|
| - node = xmlNewDocRawNode(container, NULL,
|
| - (const xmlChar *) "token", token);
|
| - xmlAddChild((xmlNodePtr) container, node);
|
| - xmlXPathNodeSetAddUnique(ret->nodesetval, node);
|
| - }
|
| - }
|
| - }
|
| -
|
| -fail:
|
| - if (str != NULL)
|
| - xmlFree(str);
|
| - if (delimiters != NULL)
|
| - xmlFree(delimiters);
|
| - if (ret != NULL)
|
| - valuePush(ctxt, ret);
|
| - else
|
| - valuePush(ctxt, xmlXPathNewNodeSet(NULL));
|
| -}
|
| -
|
| -/**
|
| - * exsltStrSplitFunction:
|
| - * @ctxt: an XPath parser context
|
| - * @nargs: the number of arguments
|
| - *
|
| - * Splits up a string on a delimiting string and returns a node set of token
|
| - * elements, each containing one token from the string.
|
| - */
|
| -static void
|
| -exsltStrSplitFunction(xmlXPathParserContextPtr ctxt, int nargs) {
|
| - xsltTransformContextPtr tctxt;
|
| - xmlChar *str, *delimiter, *cur;
|
| - const xmlChar *token;
|
| - xmlNodePtr node;
|
| - xmlDocPtr container;
|
| - xmlXPathObjectPtr ret = NULL;
|
| - int delimiterLength;
|
| -
|
| - if ((nargs < 1) || (nargs > 2)) {
|
| - xmlXPathSetArityError(ctxt);
|
| - return;
|
| - }
|
| -
|
| - if (nargs == 2) {
|
| - delimiter = xmlXPathPopString(ctxt);
|
| - if (xmlXPathCheckError(ctxt))
|
| - return;
|
| - } else {
|
| - delimiter = xmlStrdup((const xmlChar *) " ");
|
| - }
|
| - if (delimiter == NULL)
|
| - return;
|
| - delimiterLength = xmlStrlen (delimiter);
|
| -
|
| - str = xmlXPathPopString(ctxt);
|
| - if (xmlXPathCheckError(ctxt) || (str == NULL)) {
|
| - xmlFree(delimiter);
|
| - return;
|
| - }
|
| -
|
| - /* Return a result tree fragment */
|
| - tctxt = xsltXPathGetTransformContext(ctxt);
|
| - if (tctxt == NULL) {
|
| - xsltTransformError(xsltXPathGetTransformContext(ctxt), NULL, NULL,
|
| - "exslt:tokenize : internal error tctxt == NULL\n");
|
| - goto fail;
|
| - }
|
| -
|
| - /*
|
| - * OPTIMIZE TODO: We are creating an xmlDoc for every split!
|
| - */
|
| - container = xsltCreateRVT(tctxt);
|
| - if (container != NULL) {
|
| - xsltRegisterLocalRVT(tctxt, container);
|
| - ret = xmlXPathNewNodeSet(NULL);
|
| - if (ret != NULL) {
|
| - for (cur = str, token = str; *cur != 0; cur++) {
|
| - if (delimiterLength == 0) {
|
| - if (cur != token) {
|
| - xmlChar tmp = *cur;
|
| - *cur = 0;
|
| - node = xmlNewDocRawNode(container, NULL,
|
| - (const xmlChar *) "token", token);
|
| - xmlAddChild((xmlNodePtr) container, node);
|
| - xmlXPathNodeSetAddUnique(ret->nodesetval, node);
|
| - *cur = tmp;
|
| - token++;
|
| - }
|
| - }
|
| - else if (!xmlStrncasecmp(cur, delimiter, delimiterLength)) {
|
| - if (cur == token) {
|
| - /* discard empty tokens */
|
| - cur = cur + delimiterLength - 1;
|
| - token = cur + 1;
|
| - continue;
|
| - }
|
| - *cur = 0;
|
| - node = xmlNewDocRawNode(container, NULL,
|
| - (const xmlChar *) "token", token);
|
| - xmlAddChild((xmlNodePtr) container, node);
|
| - xmlXPathNodeSetAddUnique(ret->nodesetval, node);
|
| - *cur = *delimiter;
|
| - cur = cur + delimiterLength - 1;
|
| - token = cur + 1;
|
| - }
|
| - }
|
| - if (token != cur) {
|
| - node = xmlNewDocRawNode(container, NULL,
|
| - (const xmlChar *) "token", token);
|
| - xmlAddChild((xmlNodePtr) container, node);
|
| - xmlXPathNodeSetAddUnique(ret->nodesetval, node);
|
| - }
|
| - }
|
| - }
|
| -
|
| -fail:
|
| - if (str != NULL)
|
| - xmlFree(str);
|
| - if (delimiter != NULL)
|
| - xmlFree(delimiter);
|
| - if (ret != NULL)
|
| - valuePush(ctxt, ret);
|
| - else
|
| - valuePush(ctxt, xmlXPathNewNodeSet(NULL));
|
| -}
|
| -
|
| -/**
|
| - * exsltStrEncodeUriFunction:
|
| - * @ctxt: an XPath parser context
|
| - * @nargs: the number of arguments
|
| - *
|
| - * URI-Escapes a string
|
| - */
|
| -static void
|
| -exsltStrEncodeUriFunction (xmlXPathParserContextPtr ctxt, int nargs) {
|
| - int escape_all = 1, str_len = 0;
|
| - xmlChar *str = NULL, *ret = NULL, *tmp;
|
| -
|
| - if ((nargs < 2) || (nargs > 3)) {
|
| - xmlXPathSetArityError(ctxt);
|
| - return;
|
| - }
|
| -
|
| - if (nargs >= 3) {
|
| - /* check for UTF-8 if encoding was explicitly given;
|
| - we don't support anything else yet */
|
| - tmp = xmlXPathPopString(ctxt);
|
| - if (xmlUTF8Strlen(tmp) != 5 || xmlStrcmp((const xmlChar *)"UTF-8",tmp)) {
|
| - xmlXPathReturnEmptyString(ctxt);
|
| - xmlFree(tmp);
|
| - return;
|
| - }
|
| - xmlFree(tmp);
|
| - }
|
| -
|
| - escape_all = xmlXPathPopBoolean(ctxt);
|
| -
|
| - str = xmlXPathPopString(ctxt);
|
| - str_len = xmlUTF8Strlen(str);
|
| -
|
| - if (str_len == 0) {
|
| - xmlXPathReturnEmptyString(ctxt);
|
| - xmlFree(str);
|
| - return;
|
| - }
|
| -
|
| - ret = xmlURIEscapeStr(str,(const xmlChar *)(escape_all?"-_.!~*'()":"-_.!~*'();/?:@&=+$,[]"));
|
| - xmlXPathReturnString(ctxt, ret);
|
| -
|
| - if (str != NULL)
|
| - xmlFree(str);
|
| -}
|
| -
|
| -/**
|
| - * exsltStrDecodeUriFunction:
|
| - * @ctxt: an XPath parser context
|
| - * @nargs: the number of arguments
|
| - *
|
| - * reverses URI-Escaping of a string
|
| - */
|
| -static void
|
| -exsltStrDecodeUriFunction (xmlXPathParserContextPtr ctxt, int nargs) {
|
| - int str_len = 0;
|
| - xmlChar *str = NULL, *ret = NULL, *tmp;
|
| -
|
| - if ((nargs < 1) || (nargs > 2)) {
|
| - xmlXPathSetArityError(ctxt);
|
| - return;
|
| - }
|
| -
|
| - if (nargs >= 2) {
|
| - /* check for UTF-8 if encoding was explicitly given;
|
| - we don't support anything else yet */
|
| - tmp = xmlXPathPopString(ctxt);
|
| - if (xmlUTF8Strlen(tmp) != 5 || xmlStrcmp((const xmlChar *)"UTF-8",tmp)) {
|
| - xmlXPathReturnEmptyString(ctxt);
|
| - xmlFree(tmp);
|
| - return;
|
| - }
|
| - xmlFree(tmp);
|
| - }
|
| -
|
| - str = xmlXPathPopString(ctxt);
|
| - str_len = xmlUTF8Strlen(str);
|
| -
|
| - if (str_len == 0) {
|
| - xmlXPathReturnEmptyString(ctxt);
|
| - xmlFree(str);
|
| - return;
|
| - }
|
| -
|
| - ret = (xmlChar *) xmlURIUnescapeString((const char *)str,0,NULL);
|
| - if (!xmlCheckUTF8(ret)) {
|
| - /* FIXME: instead of throwing away the whole URI, we should
|
| - only discard the invalid sequence(s). How to do that? */
|
| - xmlXPathReturnEmptyString(ctxt);
|
| - xmlFree(str);
|
| - xmlFree(ret);
|
| - return;
|
| - }
|
| -
|
| - xmlXPathReturnString(ctxt, ret);
|
| -
|
| - if (str != NULL)
|
| - xmlFree(str);
|
| -}
|
| -
|
| -/**
|
| - * exsltStrPaddingFunction:
|
| - * @ctxt: an XPath parser context
|
| - * @nargs: the number of arguments
|
| - *
|
| - * Creates a padding string of a certain length.
|
| - */
|
| -static void
|
| -exsltStrPaddingFunction (xmlXPathParserContextPtr ctxt, int nargs) {
|
| - int number, str_len = 0, str_size = 0;
|
| - xmlChar *str = NULL, *ret = NULL;
|
| -
|
| - if ((nargs < 1) || (nargs > 2)) {
|
| - xmlXPathSetArityError(ctxt);
|
| - return;
|
| - }
|
| -
|
| - if (nargs == 2) {
|
| - str = xmlXPathPopString(ctxt);
|
| - str_len = xmlUTF8Strlen(str);
|
| - str_size = xmlStrlen(str);
|
| - }
|
| - if (str_len == 0) {
|
| - if (str != NULL) xmlFree(str);
|
| - str = xmlStrdup((const xmlChar *) " ");
|
| - str_len = 1;
|
| - str_size = 1;
|
| - }
|
| -
|
| - number = (int) xmlXPathPopNumber(ctxt);
|
| -
|
| - if (number <= 0) {
|
| - xmlXPathReturnEmptyString(ctxt);
|
| - xmlFree(str);
|
| - return;
|
| - }
|
| -
|
| - while (number >= str_len) {
|
| - ret = xmlStrncat(ret, str, str_size);
|
| - number -= str_len;
|
| - }
|
| - if (number > 0) {
|
| - str_size = xmlUTF8Strsize(str, number);
|
| - ret = xmlStrncat(ret, str, str_size);
|
| - }
|
| -
|
| - xmlXPathReturnString(ctxt, ret);
|
| -
|
| - if (str != NULL)
|
| - xmlFree(str);
|
| -}
|
| -
|
| -/**
|
| - * exsltStrAlignFunction:
|
| - * @ctxt: an XPath parser context
|
| - * @nargs: the number of arguments
|
| - *
|
| - * Aligns a string within another string.
|
| - */
|
| -static void
|
| -exsltStrAlignFunction (xmlXPathParserContextPtr ctxt, int nargs) {
|
| - xmlChar *str, *padding, *alignment, *ret;
|
| - int str_l, padding_l;
|
| -
|
| - if ((nargs < 2) || (nargs > 3)) {
|
| - xmlXPathSetArityError(ctxt);
|
| - return;
|
| - }
|
| -
|
| - if (nargs == 3)
|
| - alignment = xmlXPathPopString(ctxt);
|
| - else
|
| - alignment = NULL;
|
| -
|
| - padding = xmlXPathPopString(ctxt);
|
| - str = xmlXPathPopString(ctxt);
|
| -
|
| - str_l = xmlUTF8Strlen (str);
|
| - padding_l = xmlUTF8Strlen (padding);
|
| -
|
| - if (str_l == padding_l) {
|
| - xmlXPathReturnString (ctxt, str);
|
| - xmlFree(padding);
|
| - xmlFree(alignment);
|
| - return;
|
| - }
|
| -
|
| - if (str_l > padding_l) {
|
| - ret = xmlUTF8Strndup (str, padding_l);
|
| - } else {
|
| - if (xmlStrEqual(alignment, (const xmlChar *) "right")) {
|
| - ret = xmlUTF8Strndup (padding, padding_l - str_l);
|
| - ret = xmlStrcat (ret, str);
|
| - } else if (xmlStrEqual(alignment, (const xmlChar *) "center")) {
|
| - int left = (padding_l - str_l) / 2;
|
| - int right_start;
|
| -
|
| - ret = xmlUTF8Strndup (padding, left);
|
| - ret = xmlStrcat (ret, str);
|
| -
|
| - right_start = xmlUTF8Strsize (padding, left + str_l);
|
| - ret = xmlStrcat (ret, padding + right_start);
|
| - } else {
|
| - int str_s;
|
| -
|
| - str_s = xmlUTF8Strsize(padding, str_l);
|
| - ret = xmlStrdup (str);
|
| - ret = xmlStrcat (ret, padding + str_s);
|
| - }
|
| - }
|
| -
|
| - xmlXPathReturnString (ctxt, ret);
|
| -
|
| - xmlFree(str);
|
| - xmlFree(padding);
|
| - xmlFree(alignment);
|
| -}
|
| -
|
| -/**
|
| - * exsltStrConcatFunction:
|
| - * @ctxt: an XPath parser context
|
| - * @nargs: the number of arguments
|
| - *
|
| - * Takes a node set and returns the concatenation of the string values
|
| - * of the nodes in that node set. If the node set is empty, it
|
| - * returns an empty string.
|
| - */
|
| -static void
|
| -exsltStrConcatFunction (xmlXPathParserContextPtr ctxt, int nargs) {
|
| - xmlXPathObjectPtr obj;
|
| - xmlChar *ret = NULL;
|
| - int i;
|
| -
|
| - if (nargs != 1) {
|
| - xmlXPathSetArityError(ctxt);
|
| - return;
|
| - }
|
| -
|
| - if (!xmlXPathStackIsNodeSet(ctxt)) {
|
| - xmlXPathSetTypeError(ctxt);
|
| - return;
|
| - }
|
| -
|
| - obj = valuePop (ctxt);
|
| -
|
| - if (xmlXPathNodeSetIsEmpty(obj->nodesetval)) {
|
| - xmlXPathReturnEmptyString(ctxt);
|
| - return;
|
| - }
|
| -
|
| - for (i = 0; i < obj->nodesetval->nodeNr; i++) {
|
| - xmlChar *tmp;
|
| - tmp = xmlXPathCastNodeToString(obj->nodesetval->nodeTab[i]);
|
| -
|
| - ret = xmlStrcat (ret, tmp);
|
| -
|
| - xmlFree(tmp);
|
| - }
|
| -
|
| - xmlXPathFreeObject (obj);
|
| -
|
| - xmlXPathReturnString(ctxt, ret);
|
| -}
|
| -
|
| -/**
|
| - * exsltStrReturnString:
|
| - * @ctxt: an XPath parser context
|
| - * @str: a string
|
| - * @len: length of string
|
| - *
|
| - * Returns a string as a node set.
|
| - */
|
| -static int
|
| -exsltStrReturnString(xmlXPathParserContextPtr ctxt, const xmlChar *str,
|
| - int len)
|
| -{
|
| - xsltTransformContextPtr tctxt = xsltXPathGetTransformContext(ctxt);
|
| - xmlDocPtr container;
|
| - xmlNodePtr text_node;
|
| - xmlXPathObjectPtr ret;
|
| -
|
| - container = xsltCreateRVT(tctxt);
|
| - if (container == NULL) {
|
| - xmlXPathSetError(ctxt, XPATH_MEMORY_ERROR);
|
| - return(-1);
|
| - }
|
| - xsltRegisterLocalRVT(tctxt, container);
|
| -
|
| - text_node = xmlNewTextLen(str, len);
|
| - if (text_node == NULL) {
|
| - xmlXPathSetError(ctxt, XPATH_MEMORY_ERROR);
|
| - return(-1);
|
| - }
|
| - xmlAddChild((xmlNodePtr) container, text_node);
|
| -
|
| - ret = xmlXPathNewNodeSet(text_node);
|
| - if (ret == NULL) {
|
| - xmlXPathSetError(ctxt, XPATH_MEMORY_ERROR);
|
| - return(-1);
|
| - }
|
| -
|
| - valuePush(ctxt, ret);
|
| -
|
| - return(0);
|
| -}
|
| -
|
| -/**
|
| - * exsltStrReplaceFunction:
|
| - * @ctxt: an XPath parser context
|
| - * @nargs: the number of arguments
|
| - *
|
| - * Takes a string, and two node sets and returns the string with all strings in
|
| - * the first node set replaced by all strings in the second node set.
|
| - */
|
| -static void
|
| -exsltStrReplaceFunction (xmlXPathParserContextPtr ctxt, int nargs) {
|
| - int i, i_empty, n, slen0, rlen0, *slen, *rlen;
|
| - void *mem = NULL;
|
| - const xmlChar *src, *start;
|
| - xmlChar *string, *search_str = NULL, *replace_str = NULL;
|
| - xmlChar **search, **replace;
|
| - xmlNodeSetPtr search_set = NULL, replace_set = NULL;
|
| - xmlBufferPtr buf;
|
| -
|
| - if (nargs != 3) {
|
| - xmlXPathSetArityError(ctxt);
|
| - return;
|
| - }
|
| -
|
| - /* get replace argument */
|
| -
|
| - if (!xmlXPathStackIsNodeSet(ctxt))
|
| - replace_str = xmlXPathPopString(ctxt);
|
| - else
|
| - replace_set = xmlXPathPopNodeSet(ctxt);
|
| -
|
| - if (xmlXPathCheckError(ctxt))
|
| - goto fail_replace;
|
| -
|
| - /* get search argument */
|
| -
|
| - if (!xmlXPathStackIsNodeSet(ctxt)) {
|
| - search_str = xmlXPathPopString(ctxt);
|
| - n = 1;
|
| - }
|
| - else {
|
| - search_set = xmlXPathPopNodeSet(ctxt);
|
| - n = search_set != NULL ? search_set->nodeNr : 0;
|
| - }
|
| -
|
| - if (xmlXPathCheckError(ctxt))
|
| - goto fail_search;
|
| -
|
| - /* get string argument */
|
| -
|
| - string = xmlXPathPopString(ctxt);
|
| - if (xmlXPathCheckError(ctxt))
|
| - goto fail_string;
|
| -
|
| - /* check for empty search node list */
|
| -
|
| - if (n <= 0) {
|
| - exsltStrReturnString(ctxt, string, xmlStrlen(string));
|
| - goto done_empty_search;
|
| - }
|
| -
|
| - /* allocate memory for string pointer and length arrays */
|
| -
|
| - if (n == 1) {
|
| - search = &search_str;
|
| - replace = &replace_str;
|
| - slen = &slen0;
|
| - rlen = &rlen0;
|
| - }
|
| - else {
|
| - mem = xmlMalloc(2 * n * (sizeof(const xmlChar *) + sizeof(int)));
|
| - if (mem == NULL) {
|
| - xmlXPathSetError(ctxt, XPATH_MEMORY_ERROR);
|
| - goto fail_malloc;
|
| - }
|
| - search = (xmlChar **) mem;
|
| - replace = search + n;
|
| - slen = (int *) (replace + n);
|
| - rlen = slen + n;
|
| - }
|
| -
|
| - /* process arguments */
|
| -
|
| - i_empty = -1;
|
| -
|
| - for (i=0; i<n; ++i) {
|
| - if (search_set != NULL) {
|
| - search[i] = xmlXPathCastNodeToString(search_set->nodeTab[i]);
|
| - if (search[i] == NULL) {
|
| - n = i;
|
| - goto fail_process_args;
|
| - }
|
| - }
|
| -
|
| - slen[i] = xmlStrlen(search[i]);
|
| - if (i_empty < 0 && slen[i] == 0)
|
| - i_empty = i;
|
| -
|
| - if (replace_set != NULL) {
|
| - if (i < replace_set->nodeNr) {
|
| - replace[i] = xmlXPathCastNodeToString(replace_set->nodeTab[i]);
|
| - if (replace[i] == NULL) {
|
| - n = i + 1;
|
| - goto fail_process_args;
|
| - }
|
| - }
|
| - else
|
| - replace[i] = NULL;
|
| - }
|
| - else {
|
| - if (i == 0)
|
| - replace[i] = replace_str;
|
| - else
|
| - replace[i] = NULL;
|
| - }
|
| -
|
| - if (replace[i] == NULL)
|
| - rlen[i] = 0;
|
| - else
|
| - rlen[i] = xmlStrlen(replace[i]);
|
| - }
|
| -
|
| - if (i_empty >= 0 && rlen[i_empty] == 0)
|
| - i_empty = -1;
|
| -
|
| - /* replace operation */
|
| -
|
| - buf = xmlBufferCreate();
|
| - if (buf == NULL) {
|
| - xmlXPathSetError(ctxt, XPATH_MEMORY_ERROR);
|
| - goto fail_buffer;
|
| - }
|
| - src = string;
|
| - start = string;
|
| -
|
| - while (*src != 0) {
|
| - int max_len = 0, i_match = 0;
|
| -
|
| - for (i=0; i<n; ++i) {
|
| - if (*src == search[i][0] &&
|
| - slen[i] > max_len &&
|
| - xmlStrncmp(src, search[i], slen[i]) == 0)
|
| - {
|
| - i_match = i;
|
| - max_len = slen[i];
|
| - }
|
| - }
|
| -
|
| - if (max_len == 0) {
|
| - if (i_empty >= 0 && start < src) {
|
| - if (xmlBufferAdd(buf, start, src - start) ||
|
| - xmlBufferAdd(buf, replace[i_empty], rlen[i_empty]))
|
| - {
|
| - xmlXPathSetError(ctxt, XPATH_MEMORY_ERROR);
|
| - goto fail_buffer_add;
|
| - }
|
| - start = src;
|
| - }
|
| -
|
| - src += xmlUTF8Size(src);
|
| - }
|
| - else {
|
| - if ((start < src &&
|
| - xmlBufferAdd(buf, start, src - start)) ||
|
| - (rlen[i_match] &&
|
| - xmlBufferAdd(buf, replace[i_match], rlen[i_match])))
|
| - {
|
| - xmlXPathSetError(ctxt, XPATH_MEMORY_ERROR);
|
| - goto fail_buffer_add;
|
| - }
|
| -
|
| - src += slen[i_match];
|
| - start = src;
|
| - }
|
| - }
|
| -
|
| - if (start < src && xmlBufferAdd(buf, start, src - start)) {
|
| - xmlXPathSetError(ctxt, XPATH_MEMORY_ERROR);
|
| - goto fail_buffer_add;
|
| - }
|
| -
|
| - /* create result node set */
|
| -
|
| - exsltStrReturnString(ctxt, xmlBufferContent(buf), xmlBufferLength(buf));
|
| -
|
| - /* clean up */
|
| -
|
| -fail_buffer_add:
|
| - xmlBufferFree(buf);
|
| -
|
| -fail_buffer:
|
| -fail_process_args:
|
| - if (search_set != NULL) {
|
| - for (i=0; i<n; ++i)
|
| - xmlFree(search[i]);
|
| - }
|
| - if (replace_set != NULL) {
|
| - for (i=0; i<n; ++i) {
|
| - if (replace[i] != NULL)
|
| - xmlFree(replace[i]);
|
| - }
|
| - }
|
| -
|
| - if (mem != NULL)
|
| - xmlFree(mem);
|
| -
|
| -fail_malloc:
|
| -done_empty_search:
|
| - xmlFree(string);
|
| -
|
| -fail_string:
|
| - if (search_set != NULL)
|
| - xmlXPathFreeNodeSet(search_set);
|
| - else
|
| - xmlFree(search_str);
|
| -
|
| -fail_search:
|
| - if (replace_set != NULL)
|
| - xmlXPathFreeNodeSet(replace_set);
|
| - else
|
| - xmlFree(replace_str);
|
| -
|
| -fail_replace:
|
| - return;
|
| -}
|
| -
|
| -/**
|
| - * exsltStrRegister:
|
| - *
|
| - * Registers the EXSLT - Strings module
|
| - */
|
| -
|
| -void
|
| -exsltStrRegister (void) {
|
| - xsltRegisterExtModuleFunction ((const xmlChar *) "tokenize",
|
| - EXSLT_STRINGS_NAMESPACE,
|
| - exsltStrTokenizeFunction);
|
| - xsltRegisterExtModuleFunction ((const xmlChar *) "split",
|
| - EXSLT_STRINGS_NAMESPACE,
|
| - exsltStrSplitFunction);
|
| - xsltRegisterExtModuleFunction ((const xmlChar *) "encode-uri",
|
| - EXSLT_STRINGS_NAMESPACE,
|
| - exsltStrEncodeUriFunction);
|
| - xsltRegisterExtModuleFunction ((const xmlChar *) "decode-uri",
|
| - EXSLT_STRINGS_NAMESPACE,
|
| - exsltStrDecodeUriFunction);
|
| - xsltRegisterExtModuleFunction ((const xmlChar *) "padding",
|
| - EXSLT_STRINGS_NAMESPACE,
|
| - exsltStrPaddingFunction);
|
| - xsltRegisterExtModuleFunction ((const xmlChar *) "align",
|
| - EXSLT_STRINGS_NAMESPACE,
|
| - exsltStrAlignFunction);
|
| - xsltRegisterExtModuleFunction ((const xmlChar *) "concat",
|
| - EXSLT_STRINGS_NAMESPACE,
|
| - exsltStrConcatFunction);
|
| - xsltRegisterExtModuleFunction ((const xmlChar *) "replace",
|
| - EXSLT_STRINGS_NAMESPACE,
|
| - exsltStrReplaceFunction);
|
| -}
|
| -
|
| -/**
|
| - * exsltStrXpathCtxtRegister:
|
| - *
|
| - * Registers the EXSLT - Strings module for use outside XSLT
|
| - */
|
| -int
|
| -exsltStrXpathCtxtRegister (xmlXPathContextPtr ctxt, const xmlChar *prefix)
|
| -{
|
| - if (ctxt
|
| - && prefix
|
| - && !xmlXPathRegisterNs(ctxt,
|
| - prefix,
|
| - (const xmlChar *) EXSLT_STRINGS_NAMESPACE)
|
| - && !xmlXPathRegisterFuncNS(ctxt,
|
| - (const xmlChar *) "encode-uri",
|
| - (const xmlChar *) EXSLT_STRINGS_NAMESPACE,
|
| - exsltStrEncodeUriFunction)
|
| - && !xmlXPathRegisterFuncNS(ctxt,
|
| - (const xmlChar *) "decode-uri",
|
| - (const xmlChar *) EXSLT_STRINGS_NAMESPACE,
|
| - exsltStrDecodeUriFunction)
|
| - && !xmlXPathRegisterFuncNS(ctxt,
|
| - (const xmlChar *) "padding",
|
| - (const xmlChar *) EXSLT_STRINGS_NAMESPACE,
|
| - exsltStrPaddingFunction)
|
| - && !xmlXPathRegisterFuncNS(ctxt,
|
| - (const xmlChar *) "align",
|
| - (const xmlChar *) EXSLT_STRINGS_NAMESPACE,
|
| - exsltStrAlignFunction)
|
| - && !xmlXPathRegisterFuncNS(ctxt,
|
| - (const xmlChar *) "concat",
|
| - (const xmlChar *) EXSLT_STRINGS_NAMESPACE,
|
| - exsltStrConcatFunction)) {
|
| - return 0;
|
| - }
|
| - return -1;
|
| -}
|
|
|