From 42681a3efe05f484882e834c55df1f38419f6827 Mon Sep 17 00:00:00 2001 From: Daniel Veillard Date: Mon, 15 Apr 2002 12:02:03 +0000 Subject: [PATCH] fixed bug #78735 added the tests in a separate directory Daniel * libxslt/keys.c: fixed bug #78735 * configure.in tests/Makefile.am tests/keys/*: added the tests in a separate directory Daniel --- ChangeLog | 6 +++ configure.in | 1 + libxslt/keys.c | 120 +++++++++++++++++++++++++++++++++++------ tests/Makefile.am | 2 +- tests/keys/Makefile.am | 22 ++++++++ tests/keys/dates.xml | 7 +++ tests/keys/month.out | 7 +++ tests/keys/month.xml | 9 ++++ tests/keys/month.xsl | 19 +++++++ 9 files changed, 177 insertions(+), 16 deletions(-) create mode 100644 tests/keys/Makefile.am create mode 100644 tests/keys/dates.xml create mode 100644 tests/keys/month.out create mode 100644 tests/keys/month.xml create mode 100644 tests/keys/month.xsl diff --git a/ChangeLog b/ChangeLog index 4e248f8a..62351c4b 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,9 @@ +Mon Apr 15 14:00:12 CEST 2002 Daniel Veillard + + * libxslt/keys.c: fixed bug #78735 + * configure.in tests/Makefile.am tests/keys/*: + added the tests in a separate directory + Mon Apr 15 00:01:07 CEST 2002 Daniel Veillard * tests/docs/Makefile.am tests/docs/bug-83.xml diff --git a/configure.in b/configure.in index 0c5afa63..7636972d 100644 --- a/configure.in +++ b/configure.in @@ -421,6 +421,7 @@ tests/general/Makefile tests/reports/Makefile tests/extensions/Makefile tests/namespaces/Makefile +tests/keys/Makefile tests/numbers/Makefile tests/documents/Makefile tests/xmlspec/Makefile diff --git a/libxslt/keys.c b/libxslt/keys.c index 6f830f62..9454a7ef 100644 --- a/libxslt/keys.c +++ b/libxslt/keys.c @@ -356,6 +356,88 @@ xsltGetKey(xsltTransformContextPtr ctxt, const xmlChar *name, return(NULL); } +/** + * xsltEvalXPathKeys: + * @ctxt: the XSLT transformation context + * @comp: the compiled XPath expression + * + * Process the expression using XPath to get the list of keys + * + * Returns the array of computed string value or NULL, must be deallocated + * by the caller. + */ +static xmlChar ** +xsltEvalXPathKeys(xsltTransformContextPtr ctxt, xmlXPathCompExprPtr comp) { + xmlChar **ret = NULL; + xmlXPathObjectPtr res; + xmlNodePtr oldInst; + xmlNodePtr oldNode; + int oldPos, oldSize; + int oldNsNr; + xmlNsPtr *oldNamespaces; + + oldInst = ctxt->inst; + oldNode = ctxt->node; + oldPos = ctxt->xpathCtxt->proximityPosition; + oldSize = ctxt->xpathCtxt->contextSize; + oldNsNr = ctxt->xpathCtxt->nsNr; + oldNamespaces = ctxt->xpathCtxt->namespaces; + + ctxt->xpathCtxt->node = ctxt->node; + /* TODO: do we need to propagate the namespaces here ? */ + ctxt->xpathCtxt->namespaces = NULL; + ctxt->xpathCtxt->nsNr = 0; + res = xmlXPathCompiledEval(comp, ctxt->xpathCtxt); + if (res != NULL) { + if (res->type == XPATH_NODESET) { + int len, i, j; + + if (res->nodesetval != NULL) + len = res->nodesetval->nodeNr; + if (len != 0) { + ret = (xmlChar **) xmlMalloc((len + 1) * sizeof(xmlChar *)); + if (ret != NULL) { + for (i = 0,j = 0;i < len;i++) { + ret[j] = xmlXPathCastNodeToString( + res->nodesetval->nodeTab[i]); + if (ret[j] != NULL) + j++; + } + ret[j] = NULL; + } + } + } else { + if (res->type != XPATH_STRING) + res = xmlXPathConvertString(res); + if (res->type == XPATH_STRING) { + ret = (xmlChar **) xmlMalloc(2 * sizeof(xmlChar *)); + if (ret != NULL) { + ret[0] = res->stringval; + ret[1] = NULL; + res->stringval = NULL; + } + } else { + xsltPrintErrorContext(ctxt, NULL, NULL); + xsltGenericError(xsltGenericErrorContext, + "xpath : string() function didn't return a String\n"); + } + } + xmlXPathFreeObject(res); + } else { + ctxt->state = XSLT_STATE_STOPPED; + } +#ifdef WITH_XSLT_DEBUG_TEMPLATES + xsltGenericDebug(xsltGenericDebugContext, + "xsltEvalXPathString: returns %s\n", ret); +#endif + ctxt->inst = oldInst; + ctxt->node = oldNode; + ctxt->xpathCtxt->contextSize = oldSize; + ctxt->xpathCtxt->proximityPosition = oldPos; + ctxt->xpathCtxt->nsNr = oldNsNr; + ctxt->xpathCtxt->namespaces = oldNamespaces; + return(ret); +} /** * xsltInitCtxtKey: * @ctxt: an XSLT transformation context @@ -370,7 +452,7 @@ xsltInitCtxtKey(xsltTransformContextPtr ctxt, xsltDocumentPtr doc, int i; xmlNodeSetPtr nodelist = NULL, keylist; xmlXPathObjectPtr res = NULL; - xmlChar *str; + xmlChar *str, **list; xsltKeyTablePtr table; int oldPos, oldSize; xmlNodePtr oldInst; @@ -447,26 +529,34 @@ xsltInitCtxtKey(xsltTransformContextPtr ctxt, xsltDocumentPtr doc, for (i = 0;i < nodelist->nodeNr;i++) { if (IS_XSLT_REAL_NODE(nodelist->nodeTab[i])) { ctxt->node = nodelist->nodeTab[i]; - str = xsltEvalXPathString(ctxt, keyd->usecomp); - if (str != NULL) { + + list = xsltEvalXPathKeys(ctxt, keyd->usecomp); + if (list != NULL) { + int index = 0; + + str = list[index++]; + while (str != NULL) { #ifdef WITH_XSLT_DEBUG_KEYS - xsltGenericDebug(xsltGenericDebugContext, - "xsl:key : node associated to(%s,%s)\n", - keyd->name, str); + xsltGenericDebug(xsltGenericDebugContext, + "xsl:key : node associated to(%s,%s)\n", + keyd->name, str); #endif - keylist = xmlHashLookup(table->keys, str); - if (keylist == NULL) { - keylist = xmlXPathNodeSetCreate(nodelist->nodeTab[i]); - xmlHashAddEntry(table->keys, str, keylist); - } else { - xmlXPathNodeSetAdd(keylist, nodelist->nodeTab[i]); + keylist = xmlHashLookup(table->keys, str); + if (keylist == NULL) { + keylist = xmlXPathNodeSetCreate(nodelist->nodeTab[i]); + xmlHashAddEntry(table->keys, str, keylist); + } else { + xmlXPathNodeSetAdd(keylist, nodelist->nodeTab[i]); + } + nodelist->nodeTab[i]->_private = keyd; + xmlFree(str); + str = list[index++]; } - nodelist->nodeTab[i]->_private = keyd; - xmlFree(str); + xmlFree(list); #ifdef WITH_XSLT_DEBUG_KEYS } else { xsltGenericDebug(xsltGenericDebugContext, - "xsl:key : use %s failed to return a string\n", + "xsl:key : use %s failed to return strings\n", keyd->use); #endif } diff --git a/tests/Makefile.am b/tests/Makefile.am index 3690bdc5..a1589203 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -1,6 +1,6 @@ ## Process this file with automake to produce Makefile.in -SUBDIRS=docs REC1 REC2 REC general namespaces numbers documents \ +SUBDIRS=docs REC1 REC2 REC general namespaces keys numbers documents \ extensions reports xmlspec multiple XSLTMark docbook exslt all: diff --git a/tests/keys/Makefile.am b/tests/keys/Makefile.am new file mode 100644 index 00000000..f47115a5 --- /dev/null +++ b/tests/keys/Makefile.am @@ -0,0 +1,22 @@ +## Process this file with automake to produce Makefile.in + +$(top_builddir)/xsltproc/xsltproc: + @(cd ../../xsltproc ; $(MAKE) xsltproc) + +EXTRA_DIST = dates.xml month.xml month.xsl month.out + +all: + +valgrind: + @echo '## Running the regression tests under Valgrind' + $(MAKE) CHECKER='valgrind -q' tests + +test tests: $(top_builddir)/xsltproc/xsltproc + @(echo > .memdump) + @($(CHECKER) $(top_builddir)/xsltproc/xsltproc $(srcdir)/month.xsl $(srcdir)/dates.xml > month.res ; \ + if [ -r $(srcdir)/month.out ] ; \ + then diff $(srcdir)/month.out month.res ; \ + else mv month.res $(srcdir)/month.out ; fi ; \ + grep "MORY ALLO" .memdump | grep -v "MEMORY ALLOCATED : 0" || true;\ + rm -f month.res) + diff --git a/tests/keys/dates.xml b/tests/keys/dates.xml new file mode 100644 index 00000000..cef3228d --- /dev/null +++ b/tests/keys/dates.xml @@ -0,0 +1,7 @@ + + + 12 + Dec + December + dismember + diff --git a/tests/keys/month.out b/tests/keys/month.out new file mode 100644 index 00000000..180559d6 --- /dev/null +++ b/tests/keys/month.out @@ -0,0 +1,7 @@ + + + December + December + December + + diff --git a/tests/keys/month.xml b/tests/keys/month.xml new file mode 100644 index 00000000..445ba698 --- /dev/null +++ b/tests/keys/month.xml @@ -0,0 +1,9 @@ + + + + December + 12 + Dec + DEC + + diff --git a/tests/keys/month.xsl b/tests/keys/month.xsl new file mode 100644 index 00000000..336c0364 --- /dev/null +++ b/tests/keys/month.xsl @@ -0,0 +1,19 @@ + + + + + + + + + + + + + + + + + + +