From f826a45e68300b410baf7c97c10317a924e85e85 Mon Sep 17 00:00:00 2001 From: Daniel Veillard Date: Fri, 18 Jul 2003 11:15:45 +0000 Subject: [PATCH] applied patch from Shaun McCance to implement exslt:split c.f. #117752 * libexslt/strings.c: applied patch from Shaun McCance to implement exslt:split c.f. #117752 * tests/exslt/strings/Makefile.am tests/exslt/strings/split.1.*: added the test to the regression suite. Daniel --- ChangeLog | 7 +++ libexslt/strings.c | 111 +++++++++++++++++++++++++++++++++++++++- tests/exslt/strings/Makefile.am | 3 +- tests/exslt/strings/split.1.out | 13 +++++ tests/exslt/strings/split.1.xml | 1 + tests/exslt/strings/split.1.xsl | 23 +++++++++ 6 files changed, 155 insertions(+), 3 deletions(-) create mode 100644 tests/exslt/strings/split.1.out create mode 100644 tests/exslt/strings/split.1.xml create mode 100644 tests/exslt/strings/split.1.xsl diff --git a/ChangeLog b/ChangeLog index fc90ba8..856dd41 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,10 @@ +Fri Jul 18 13:13:52 CEST 2003 Daniel Veillard + + * libexslt/strings.c: applied patch from Shaun McCance to implement + exslt:split c.f. #117752 + * tests/exslt/strings/Makefile.am tests/exslt/strings/split.1.*: + added the test to the regression suite. + Thu Jul 17 10:35:22 CEST 2003 Daniel Veillard * libxslt/numbers.c: quick fix for an HP-UX compilation problem, diff --git a/libexslt/strings.c b/libexslt/strings.c index 6c02ba9..1c799cf 100644 --- a/libexslt/strings.c +++ b/libexslt/strings.c @@ -26,8 +26,8 @@ * @ctxt: an XPath parser context * @nargs: the number of arguments * - * Splits up a string and returns a node set of token elements, each - * containing one token from the string. + * 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) @@ -111,6 +111,110 @@ fail: } /** + * 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; + } + + container = xsltCreateRVT(tctxt); + if (container != NULL) { + xsltRegisterTmpRVT(tctxt, container); + ret = xmlXPathNewNodeSet(NULL); + if (ret != NULL) { + ret->boolval = 0; /* Freeing is not handled there anymore */ + for (cur = str, token = str; *cur != 0; cur++) { + if (delimiterLength == 0) { + if (cur != token) { + xmlChar tmp = *cur; + *cur = 0; + node = xmlNewChild((xmlNodePtr) container, NULL, + (const xmlChar *) "token", + token); + 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 = xmlNewChild((xmlNodePtr) container, NULL, + (const xmlChar *) "token", + token); + xmlXPathNodeSetAddUnique(ret->nodesetval, node); + *cur = *delimiter; + cur = cur + delimiterLength - 1; + token = cur + 1; + } + } + if (token != cur) { + node = + xmlNewChild((xmlNodePtr) container, NULL, + (const xmlChar *) "token", token); + 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 @@ -384,6 +488,9 @@ 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); diff --git a/tests/exslt/strings/Makefile.am b/tests/exslt/strings/Makefile.am index 78732c1..5ccb5a8 100644 --- a/tests/exslt/strings/Makefile.am +++ b/tests/exslt/strings/Makefile.am @@ -5,7 +5,8 @@ $(top_builddir)/xsltproc/xsltproc: EXTRA_DIST = \ tokenize.1.xml tokenize.1.xsl tokenize.1.out \ - tokenize.2.xml tokenize.2.xsl tokenize.2.out + tokenize.2.xml tokenize.2.xsl tokenize.2.out \ + split.1.xml split.1.xsl split.1.out all: diff --git a/tests/exslt/strings/split.1.out b/tests/exslt/strings/split.1.out new file mode 100644 index 0000000..9166a2c --- /dev/null +++ b/tests/exslt/strings/split.1.out @@ -0,0 +1,13 @@ + +; + str:split('a, simple, list', ', ') + asimplelist + + str:split('data math str') + datamathstr + + str:split('foobar', '') + foobar + + str:split('-*- hello - world -*-', '-') + * hello world * diff --git a/tests/exslt/strings/split.1.xml b/tests/exslt/strings/split.1.xml new file mode 100644 index 0000000..69d62f2 --- /dev/null +++ b/tests/exslt/strings/split.1.xml @@ -0,0 +1 @@ + diff --git a/tests/exslt/strings/split.1.xsl b/tests/exslt/strings/split.1.xsl new file mode 100644 index 0000000..42d88d5 --- /dev/null +++ b/tests/exslt/strings/split.1.xsl @@ -0,0 +1,23 @@ + + + + +; + str:split('a, simple, list', ', ') + + + str:split('data math str') + + + str:split('foobar', '') + + + str:split('-*- hello - world -*-', '-') + + + + + \ No newline at end of file -- 2.7.4