try to avoid generating conflicts applied patch from Mark Vakoc to
authorDaniel Veillard <veillard@src.gnome.org>
Sun, 10 Jul 2005 14:20:06 +0000 (14:20 +0000)
committerDaniel Veillard <veillard@src.gnome.org>
Sun, 10 Jul 2005 14:20:06 +0000 (14:20 +0000)
* libxslt/xsltwin32config.h*: try to avoid generating conflicts
* libexslt/dynamic.c: applied patch from Mark Vakoc to implement
  dyn:map
* configure.in tests/exslt/Makefile.am tests/exslt/dynamic/*:
  added test for dyn:map to the regression suite
Daniel

ChangeLog
configure.in
libexslt/dynamic.c
libxslt/xsltwin32config.h
libxslt/xsltwin32config.h.in
tests/exslt/Makefile.am
tests/exslt/dynamic/Makefile.am [new file with mode: 0644]
tests/exslt/dynamic/dynmap.out [new file with mode: 0644]
tests/exslt/dynamic/dynmap.xml [new file with mode: 0644]
tests/exslt/dynamic/dynmap.xsl [new file with mode: 0644]

index 6cf3819..781f06b 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,11 @@
+Sun Jul 10 16:17:53 CEST 2005 Daniel Veillard <daniel@veillard.com>
+
+       * libxslt/xsltwin32config.h*: try to avoid generating conflicts
+       * libexslt/dynamic.c: applied patch from Mark Vakoc to implement
+         dyn:map
+       * configure.in tests/exslt/Makefile.am tests/exslt/dynamic/*:
+         added test for dyn:map to the regression suite
+
 Sat Jul  2 02:32:24 PDT 2005 <wbrack@mmm.com.hk>
 
        * libxslt/numbers.c: further fixes for bug 309209, changing
index 4bbd311..6045b89 100644 (file)
@@ -583,6 +583,7 @@ tests/exslt/math/Makefile
 tests/exslt/sets/Makefile
 tests/exslt/strings/Makefile
 tests/exslt/date/Makefile
+tests/exslt/dynamic/Makefile
 tests/plugins/Makefile
 doc/Makefile
 xslt-config
index 1cef946..86db663 100644 (file)
@@ -84,6 +84,179 @@ exsltDynEvaluateFunction(xmlXPathParserContextPtr ctxt, int nargs) {
 }
 
 /**
+ * exsltDynMapFunction:
+ * @ctxt:  an XPath parser context
+ * @nargs:  the number of arguments
+ *
+ * Evaluates the string as an XPath expression and returns the result
+ * value, which may be a boolean, number, string, node set, result tree
+ * fragment or external object.
+ */
+
+static void
+exsltDynMapFunction(xmlXPathParserContextPtr ctxt, int nargs)
+{
+    xmlChar *str = NULL;
+    xmlNodeSetPtr nodeset = NULL;
+    xmlXPathCompExprPtr comp = NULL;
+    xmlXPathObjectPtr ret = NULL;
+    xmlDocPtr oldDoc, container;
+    xmlNodePtr oldNode;
+    int oldContextSize;
+    int oldProximityPosition;
+    int i, j;
+
+
+    if (nargs != 2) {
+        xmlXPathSetArityError(ctxt);
+        return;
+    }
+    str = xmlXPathPopString(ctxt);
+    if (xmlXPathCheckError(ctxt)) {
+        xmlXPathSetTypeError(ctxt);
+        return;
+    }
+
+    nodeset = xmlXPathPopNodeSet(ctxt);
+    if (xmlXPathCheckError(ctxt)) {
+        xmlXPathSetTypeError(ctxt);
+        return;
+    }
+    if (str == NULL || !xmlStrlen(str) || !(comp = xmlXPathCompile(str))) {
+        if (nodeset != NULL)
+            xmlXPathFreeNodeSet(nodeset);
+        if (str != NULL)
+            xmlFree(str);
+        valuePush(ctxt, xmlXPathNewNodeSet(NULL));
+        return;
+    }
+
+    ret = xmlXPathNewNodeSet(NULL);
+    if (ret == NULL) {
+        xsltGenericError(xsltGenericErrorContext,
+                         "exsltDynMapFunctoin: ret == NULL\n");
+        goto cleanup;
+    }
+
+    oldDoc = ctxt->context->doc;
+    oldNode = ctxt->context->node;
+    oldContextSize = ctxt->context->contextSize;
+    oldProximityPosition = ctxt->context->proximityPosition;
+
+        /** 
+        * since we really don't know we're going to be adding node(s) 
+        * down the road we create the RVT regardless 
+        */
+    container = xsltCreateRVT(xsltXPathGetTransformContext(ctxt));
+    if (container != NULL)
+        xsltRegisterTmpRVT(xsltXPathGetTransformContext(ctxt), container);
+
+    if (nodeset && nodeset->nodeNr > 0) {
+        xmlXPathNodeSetSort(nodeset);
+        ctxt->context->contextSize = nodeset->nodeNr;
+        ctxt->context->proximityPosition = 0;
+        for (i = 0; i < nodeset->nodeNr; i++) {
+            xmlXPathObjectPtr subResult = NULL;
+
+            ctxt->context->proximityPosition++;
+            ctxt->context->node = nodeset->nodeTab[i];
+            ctxt->context->doc = nodeset->nodeTab[i]->doc;
+
+            subResult = xmlXPathCompiledEval(comp, ctxt->context);
+            if (subResult != NULL) {
+                switch (subResult->type) {
+                    case XPATH_NODESET:
+                        if (subResult->nodesetval != NULL)
+                            for (j = 0; j < subResult->nodesetval->nodeNr;
+                                 j++)
+                                xmlXPathNodeSetAdd(ret->nodesetval,
+                                                   subResult->nodesetval->
+                                                   nodeTab[j]);
+                        break;
+                    case XPATH_BOOLEAN:
+                        if (container != NULL) {
+                            xmlNodePtr cur =
+                                xmlNewChild((xmlNodePtr) container, NULL,
+                                            BAD_CAST "boolean",
+                                            BAD_CAST (subResult->
+                                            boolval ? "true" : ""));
+                            if (cur != NULL) {
+                                cur->ns =
+                                    xmlNewNs(cur,
+                                             BAD_CAST
+                                             "http://exslt.org/common",
+                                             BAD_CAST "exsl");
+                                xmlXPathNodeSetAddUnique(ret->nodesetval,
+                                                         cur);
+                            }
+                        }
+                        break;
+                    case XPATH_NUMBER:
+                        if (container != NULL) {
+                            xmlChar *val =
+                                xmlXPathCastNumberToString(subResult->
+                                                           floatval);
+                            xmlNodePtr cur =
+                                xmlNewChild((xmlNodePtr) container, NULL,
+                                            BAD_CAST "number", val);
+                            if (val != NULL)
+                                xmlFree(val);
+
+                            if (cur != NULL) {
+                                cur->ns =
+                                    xmlNewNs(cur,
+                                             BAD_CAST
+                                             "http://exslt.org/common",
+                                             BAD_CAST "exsl");
+                                xmlXPathNodeSetAddUnique(ret->nodesetval,
+                                                         cur);
+                            }
+                        }
+                        break;
+                    case XPATH_STRING:
+                        if (container != NULL) {
+                            xmlNodePtr cur =
+                                xmlNewChild((xmlNodePtr) container, NULL,
+                                            BAD_CAST "string",
+                                            subResult->stringval);
+                            if (cur != NULL) {
+                                cur->ns =
+                                    xmlNewNs(cur,
+                                             BAD_CAST
+                                             "http://exslt.org/common",
+                                             BAD_CAST "exsl");
+                                xmlXPathNodeSetAddUnique(ret->nodesetval,
+                                                         cur);
+                            }
+                        }
+                        break;
+                   default:
+                        break;
+                }
+                xmlXPathFreeObject(subResult);
+            }
+        }
+    }
+    ctxt->context->doc = oldDoc;
+    ctxt->context->node = oldNode;
+    ctxt->context->contextSize = oldContextSize;
+    ctxt->context->proximityPosition = oldProximityPosition;
+
+
+  cleanup:
+    /* restore the xpath context */
+    if (comp != NULL)
+        xmlXPathFreeCompExpr(comp);
+    if (nodeset != NULL)
+        xmlXPathFreeNodeSet(nodeset);
+    if (str != NULL)
+        xmlFree(str);
+    valuePush(ctxt, ret);
+    return;
+}
+
+
+/**
  * exsltDynRegister:
  *
  * Registers the EXSLT - Dynamic module
@@ -94,4 +267,8 @@ exsltDynRegister (void) {
     xsltRegisterExtModuleFunction ((const xmlChar *) "evaluate",
                                   EXSLT_DYNAMIC_NAMESPACE,
                                   exsltDynEvaluateFunction);
+  xsltRegisterExtModuleFunction ((const xmlChar *) "map",
+                                  EXSLT_DYNAMIC_NAMESPACE,
+                                  exsltDynMapFunction);
+
 }
index 9fb4b9a..fe0330c 100644 (file)
@@ -44,7 +44,7 @@ extern "C" {
  *
  * extra version information, used to show a CVS compilation
  */
-#define LIBXSLT_VERSION_EXTRA "-CVS1011"
+#define LIBXSLT_VERSION_EXTRA "-win32"
 
 /**
  * WITH_XSLT_DEBUG:
index df0640b..cceeb6b 100644 (file)
@@ -44,7 +44,7 @@ extern "C" {
  *
  * extra version information, used to show a CVS compilation
  */
-#define LIBXSLT_VERSION_EXTRA "@LIBXSLT_VERSION_EXTRA@"
+#define LIBXSLT_VERSION_EXTRA "-win32"
 
 /**
  * WITH_XSLT_DEBUG:
index cc2fcb8..bbfc7e3 100644 (file)
@@ -1,6 +1,6 @@
 ## Process this file with automake to produce Makefile.in
 
-SUBDIRS=common functions math sets strings date
+SUBDIRS=common functions math sets strings dynamic date
 
 all:
 
diff --git a/tests/exslt/dynamic/Makefile.am b/tests/exslt/dynamic/Makefile.am
new file mode 100644 (file)
index 0000000..3cf8263
--- /dev/null
@@ -0,0 +1,46 @@
+## Process this file with automake to produce Makefile.in
+
+$(top_builddir)/xsltproc/xsltproc:
+       @(cd ../../../xsltproc ; $(MAKE) xsltproc)
+
+EXTRA_DIST =                                                   \
+  dynmap.out     dynmap.xml     dynmap.xsl
+
+all:
+
+valgrind:
+       @echo '## Running the regression tests under Valgrind'
+       $(MAKE) CHECKER='valgrind -q' tests
+
+test tests: $(top_builddir)/xsltproc/xsltproc
+       @echo '## Running exslt sets tests'
+       @(echo > .memdump)
+       @(for i in $(srcdir)/*.xsl ; do \
+         name=`basename $$i .xsl` ; \
+         if [ ! -f $(srcdir)/$$name.xml ] ; then continue ; fi ; \
+         log=`$(CHECKER) $(top_builddir)/xsltproc/xsltproc \
+               $(srcdir)/$$name.xsl $(srcdir)/$$name.xml > $$name.res 2>$$name.bad;\
+         if [ ! -f $(srcdir)/$$name.out ] ; then \
+               cp $$name.res $(srcdir)/$$name.out ; \
+               if [ -s $$name.bad ] ; then \
+                       mv $$name.bad $(srcdir)/$$name.err ; \
+               fi ; \
+         else \
+               if  [ ! -s $$name.res ] ; then \
+                       echo "Fatal error, no $$name.res\n" ; \
+               else \
+                       diff $(srcdir)/$$name.out $$name.res ; \
+                       if [ -s $(srcdir)/$$name.err ] ; then \
+                               diff $(srcdir)/$$name.err $$name.bad; \
+                       else \
+                               diff /dev/null $$name.bad; \
+                       fi ; \
+               fi ; \
+         fi; \
+         grep "MORY ALLO" .memdump  | grep -v "MEMORY ALLOCATED : 0" || true`;\
+         if [ -n "$$log" ] ; then \
+               echo $$name result ; \
+               echo $$log ; \
+         fi ; \
+         rm -f $$name.res $$name.bad ; \
+         done)
diff --git a/tests/exslt/dynamic/dynmap.out b/tests/exslt/dynamic/dynmap.out
new file mode 100644 (file)
index 0000000..b75b87c
--- /dev/null
@@ -0,0 +1,41 @@
+<?xml version="1.0"?>
+<result>
+  <node-set>
+    <childNode2>bbbb</childNode2>
+    <childNode4>dddd</childNode4>
+    <childNode6>ffff</childNode6>
+    <childNode8>hhhh</childNode8>
+    <childNode1>jjjj</childNode1>
+    <childNode3>llll</childNode3>
+    <childNode5>nnnn</childNode5>
+    <childNode7>pppp</childNode7>
+    <childNode9>rrrr</childNode9>
+  </node-set>
+  <boolean>
+    <exsl:boolean xmlns:exsl="http://exslt.org/common">true</exsl:boolean>
+    <exsl:boolean xmlns:exsl="http://exslt.org/common">true</exsl:boolean>
+    <exsl:boolean xmlns:exsl="http://exslt.org/common">true</exsl:boolean>
+    <exsl:boolean xmlns:exsl="http://exslt.org/common">true</exsl:boolean>
+    <exsl:boolean xmlns:exsl="http://exslt.org/common">true</exsl:boolean>
+    <exsl:boolean xmlns:exsl="http://exslt.org/common">true</exsl:boolean>
+    <exsl:boolean xmlns:exsl="http://exslt.org/common">true</exsl:boolean>
+  </boolean>
+  <number>
+    <exsl:number xmlns:exsl="http://exslt.org/common">9</exsl:number>
+    <exsl:number xmlns:exsl="http://exslt.org/common">0</exsl:number>
+    <exsl:number xmlns:exsl="http://exslt.org/common">0</exsl:number>
+    <exsl:number xmlns:exsl="http://exslt.org/common">0</exsl:number>
+    <exsl:number xmlns:exsl="http://exslt.org/common">0</exsl:number>
+    <exsl:number xmlns:exsl="http://exslt.org/common">0</exsl:number>
+    <exsl:number xmlns:exsl="http://exslt.org/common">9</exsl:number>
+  </number>
+  <string>
+    <exsl:string xmlns:exsl="http://exslt.org/common">with-child</exsl:string>
+    <exsl:string xmlns:exsl="http://exslt.org/common">without-child</exsl:string>
+    <exsl:string xmlns:exsl="http://exslt.org/common">without-child</exsl:string>
+    <exsl:string xmlns:exsl="http://exslt.org/common">without-child</exsl:string>
+    <exsl:string xmlns:exsl="http://exslt.org/common">without-child</exsl:string>
+    <exsl:string xmlns:exsl="http://exslt.org/common">without-child</exsl:string>
+    <exsl:string xmlns:exsl="http://exslt.org/common">with-child</exsl:string>
+  </string>
+</result>
diff --git a/tests/exslt/dynamic/dynmap.xml b/tests/exslt/dynamic/dynmap.xml
new file mode 100644 (file)
index 0000000..8f069a8
--- /dev/null
@@ -0,0 +1,29 @@
+<dynmap>
+ <with-child>
+  <childNode1>aaa</childNode1>
+  <childNode2>bbbb</childNode2>
+  <childNode3>ccc</childNode3>
+  <childNode4>dddd</childNode4>
+  <childNode5>eee</childNode5>
+  <childNode6>ffff</childNode6>
+  <childNode7>ggg</childNode7>
+  <childNode8>hhhh</childNode8>
+  <childNode9>iii</childNode9>
+ </with-child>
+ <without-child>some text</without-child>
+ <without-child>some text</without-child>
+ <without-child>some text</without-child>
+ <without-child>some text</without-child>
+ <without-child>some text</without-child>
+ <with-child>
+  <childNode1>jjjj</childNode1>
+  <childNode2>kkk</childNode2>
+  <childNode3>llll</childNode3>
+  <childNode4>mmm</childNode4>
+  <childNode5>nnnn</childNode5>
+  <childNode6>ooo</childNode6>
+  <childNode7>pppp</childNode7>
+  <childNode8>qqq</childNode8>
+  <childNode9>rrrr</childNode9>
+ </with-child>
+</dynmap>
diff --git a/tests/exslt/dynamic/dynmap.xsl b/tests/exslt/dynamic/dynmap.xsl
new file mode 100644 (file)
index 0000000..bfcef58
--- /dev/null
@@ -0,0 +1,24 @@
+<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0"
+ xmlns:dyn="http://exslt.org/dynamic"
+ exclude-result-prefixes="dyn"
+>
+<xsl:output indent="yes"/>
+
+<xsl:template match="/dynmap">
+<result>
+ <node-set>
+  <xsl:copy-of select="dyn:map(*, 'child::*[string-length(.) &gt; 3]')"/>
+ </node-set> 
+ <boolean>
+  <xsl:copy-of select="dyn:map(*, 'string-length(name()) &gt; 3')"/>
+ </boolean>
+ <number>
+  <xsl:copy-of select="dyn:map(*, 'count(*)')"/>
+ </number>
+ <string>
+  <xsl:copy-of select="dyn:map(*, 'name()')"/>
+ </string>  
+</result> 
+</xsl:template>
+</xsl:stylesheet>
+