diff options
author | William M. Brack <wbrack@src.gnome.org> | 2007-01-11 03:13:13 +0000 |
---|---|---|
committer | William M. Brack <wbrack@src.gnome.org> | 2007-01-11 03:13:13 +0000 |
commit | 40e7c29b35c975e4b7ff6275a9f8aaca24a4a86c (patch) | |
tree | ce0476e8d46fa9bebf8b289617f3e9a521dae702 /libexslt | |
parent | 7581a7896fbf2d9216622b54265ed202692ea006 (diff) | |
download | libxslt-40e7c29b35c975e4b7ff6275a9f8aaca24a4a86c.tar.gz libxslt-40e7c29b35c975e4b7ff6275a9f8aaca24a4a86c.tar.bz2 libxslt-40e7c29b35c975e4b7ff6275a9f8aaca24a4a86c.zip |
added new function replace from Joel Reed. added new test case for above.
* libexslt/strings.c: added new function replace from Joel
Reed.
* tests/exslt/Makefile.am, replace.1.xml, replace.1.xsl,
replace.1.out: added new test case for above.
* libxslt.spec.in: trivial change from Gnome to GNOME
* configure.in: trivial change for flags on my compilations
* libxslt/documents.c, libxslt/documents.h, libxslt/keys.c,
libxslt/keys.h, libxslt/variables.c, libxslt/templates.c,
libxslt/transform.c, libxslt/variables.c, libxslt/xslt.c,
libxslt/xsltutils.c: fixed some documentation/comments and
compilation warnings - no change to logic.
* re-generated the documentation.
svn path=/trunk/; revision=1413
Diffstat (limited to 'libexslt')
-rw-r--r-- | libexslt/strings.c | 140 |
1 files changed, 140 insertions, 0 deletions
diff --git a/libexslt/strings.c b/libexslt/strings.c index c867f9cb..af7aa88a 100644 --- a/libexslt/strings.c +++ b/libexslt/strings.c @@ -495,6 +495,143 @@ exsltStrConcatFunction (xmlXPathParserContextPtr ctxt, int nargs) { } /** + * exsltStrReplaceInternal: + * @str: string to modify + * @searchStr: string to find + * @replaceStr: string to replace occurrences of searchStr + * + * Search and replace string function used by exsltStrReplaceFunction + */ +static xmlChar* +exsltStrReplaceInternal(const xmlChar* str, const xmlChar* searchStr, + const xmlChar* replaceStr) +{ + const xmlChar *curr, *next; + xmlChar *ret = NULL; + int searchStrSize; + + curr = str; + searchStrSize = xmlStrlen(searchStr); + + do { + next = xmlStrstr(curr, searchStr); + if (next == NULL) { + ret = xmlStrcat (ret, curr); + break; + } + + ret = xmlStrncat (ret, curr, next - curr); + ret = xmlStrcat (ret, replaceStr); + curr = next + searchStrSize; + } while (*curr != 0); + + return ret; +} +/** + * 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) { + xmlChar *str = NULL, *searchStr = NULL, *replaceStr = NULL; + xmlNodeSetPtr replaceSet = NULL, searchSet = NULL; + xmlChar *ret = NULL, *retSwap = NULL; + int i; + + if (nargs != 3) { + xmlXPathSetArityError(ctxt); + return; + } + + /* pull out replace argument */ + if (!xmlXPathStackIsNodeSet(ctxt)) { + replaceStr = xmlXPathPopString(ctxt); + } + else { + replaceSet = xmlXPathPopNodeSet(ctxt); + if (xmlXPathCheckError(ctxt)) { + xmlXPathSetTypeError(ctxt); + goto fail; + } + } + + /* behavior driven by search argument from here on */ + if (!xmlXPathStackIsNodeSet(ctxt)) { + searchStr = xmlXPathPopString(ctxt); + str = xmlXPathPopString(ctxt); + + if (replaceStr == NULL) { + xmlXPathSetTypeError(ctxt); + goto fail; + } + + ret = exsltStrReplaceInternal(str, searchStr, replaceStr); + } + else { + searchSet = xmlXPathPopNodeSet(ctxt); + if (searchSet == NULL || xmlXPathCheckError(ctxt)) { + xmlXPathSetTypeError(ctxt); + goto fail; + } + + str = xmlXPathPopString(ctxt); + ret = xmlStrdup(str); + + for (i = 0; i < searchSet->nodeNr; i++) { + + searchStr = xmlXPathCastNodeToString(searchSet->nodeTab[i]); + + if (replaceSet != NULL) { + replaceStr = NULL; + if (i <= replaceSet->nodeNr) { + replaceStr = xmlXPathCastNodeToString(replaceSet->nodeTab[i]); + } + + retSwap = exsltStrReplaceInternal(ret, searchStr, replaceStr); + + if (replaceStr != NULL) { + xmlFree(replaceStr); + replaceStr = NULL; + } + } + else { + retSwap = exsltStrReplaceInternal(ret, searchStr, replaceStr); + } + + xmlFree(ret); + if (searchStr != NULL) { + xmlFree(searchStr); + searchStr = NULL; + } + + ret = retSwap; + } + + if (replaceSet != NULL) + xmlXPathFreeNodeSet(replaceSet); + + if (searchSet != NULL) + xmlXPathFreeNodeSet(searchSet); + } + + xmlXPathReturnString(ctxt, ret); + + fail: + if (replaceStr != NULL) + xmlFree(replaceStr); + + if (searchStr != NULL) + xmlFree(searchStr); + + if (str != NULL) + xmlFree(str); +} + +/** * exsltStrRegister: * * Registers the EXSLT - Strings module @@ -523,4 +660,7 @@ exsltStrRegister (void) { xsltRegisterExtModuleFunction ((const xmlChar *) "concat", EXSLT_STRINGS_NAMESPACE, exsltStrConcatFunction); + xsltRegisterExtModuleFunction ((const xmlChar *) "replace", + EXSLT_STRINGS_NAMESPACE, + exsltStrReplaceFunction); } |