Added XPointer: - configure.in Makefile.am include/makefile.am: adding

Added XPointer:
- configure.in Makefile.am include/makefile.am: adding XPointer
  and XPtrtests target
- xpointer.[ch] : new files for XPointer support
- test/XPath/xptr result/XPath/xptr: added XPointer testsuite and
  more XPath tests
Daniel
diff --git a/ChangeLog b/ChangeLog
index 50dfe93..a729636 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,11 @@
+Wed Oct 11 01:46:44 CEST 2000 Daniel Veillard <Daniel.Veillard@w3.org>
+
+	* configure.in Makefile.am include/makefile.am: adding XPointer
+	  and XPtrtests target
+	* xpointer.[ch] : new files for XPointer support
+	* test/XPath/xptr result/XPath/xptr: added XPointer testsuite and
+	  more XPath tests
+
 Wed Oct 11 01:23:25 CEST 2000 Daniel Veillard <Daniel.Veillard@w3.org>
 
 	* configure.in: fixed, very broken, make distcheck works again
diff --git a/Makefile.am b/Makefile.am
index e0ae860..4fe9882 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -32,6 +32,7 @@
 		HTMLtree.c \
 		debugXML.c \
 		xpath.c \
+		xpointer.c \
 		nanohttp.c \
 		nanoftp.c
 
@@ -79,7 +80,7 @@
 
 testall : tests SVGtests SAXtests
 
-tests: XMLtests XMLenttests HTMLtests Validtests URItests XPathtests
+tests: XMLtests XMLenttests HTMLtests Validtests URItests XPathtests XPtrtests
 
 HTMLtests : testHTML
 	@(rm -f .memdump ; touch .memdump)
@@ -234,6 +235,7 @@
 	  if [ ! -d $$i ] ; then \
 	  doc=`basename $$i`; \
 	  for j in $(srcdir)/test/XPath/tests/$$doc* ; do \
+	  if [ ! -f $$j ] ; then continue ; fi ; \
 	  name=`basename $$j`; \
 	  if [ ! -d $$j ] ; then \
 	  if [ ! -f $(srcdir)/result/XPath/tests/$$name ] ; then \
@@ -246,6 +248,29 @@
 	      rm result.$$name ; \
 	  fi ; fi ; done ; fi ; done)
 
+XPtrtests : testXPath
+	@(rm -f .memdump ; touch .memdump)
+	@echo "##"
+	@echo "## XPointer regression tests"
+	@echo "##"
+	@(for i in $(srcdir)/test/XPath/docs/* ; do \
+	  if [ ! -d $$i ] ; then \
+	  doc=`basename $$i`; \
+	  for j in $(srcdir)/test/XPath/xptr/$$doc* ; do \
+	  if [ ! -f $$j ] ; then continue ; fi ; \
+	  name=`basename $$j`; \
+	  if [ ! -d $$j ] ; then \
+	  if [ ! -f $(srcdir)/result/XPath/xptr/$$name ] ; then \
+	      echo New test file $$name ; \
+	      ./testXPath -xptr -f -i $$i $$j > $(srcdir)/result/XPath/xptr/$$name ; \
+	  else \
+	      echo Testing $$name ; \
+	      ./testXPath -xptr -f -i $$i $$j > result.$$name ; \
+	      grep "MORY ALLO" .memdump  | grep -v "MEMORY ALLOCATED : 0";\
+	      diff $(srcdir)/result/XPath/xptr/$$name result.$$name ; \
+	      rm result.$$name ; \
+	  fi ; fi ; done ; fi ; done)
+
 SVGtests : xmllint
 	@echo "##"
 	@echo "## SVG parsing regression tests"
diff --git a/configure.in b/configure.in
index 7cac90f..28b4685 100644
--- a/configure.in
+++ b/configure.in
@@ -245,6 +245,18 @@
 AC_SUBST(WITH_XPATH)
 AC_SUBST(XPATH_OBJ)
 
+AC_ARG_WITH(xptr, [  --with-xptr             Add the XPointer support (on)])
+if test "$with_xptr" = "no" ; then
+    echo Disabling XPointer support
+    WITH_XPTR=0
+    XPTR_OBJ=
+else    
+    WITH_XPTR=1
+    XPTR_OBJ=xpointer.o
+fi
+AC_SUBST(WITH_XPTR)
+AC_SUBST(XPTR_OBJ)
+
 AC_ARG_WITH(iconv, [  --with-iconv            Add the ICONV support (on)])
 if test "$with_iconv" = "no" ; then
     echo Disabling ICONV support
diff --git a/include/Makefile.am b/include/Makefile.am
index eea4e9c..e2375fe 100644
--- a/include/Makefile.am
+++ b/include/Makefile.am
@@ -15,6 +15,7 @@
 		libxml/debugXML.h \
 		libxml/tree.h \
 		libxml/xpath.h \
+		libxml/xpointer.h \
 		libxml/xmlIO.h \
 		libxml/xmlmemory.h \
 		libxml/nanohttp.h \
diff --git a/include/libxml/xmlversion.h.in b/include/libxml/xmlversion.h.in
index 6b41be4..ed1c43f 100644
--- a/include/libxml/xmlversion.h.in
+++ b/include/libxml/xmlversion.h.in
@@ -78,6 +78,15 @@
 #endif
 
 /*
+ * Whether XPointer is configured in
+ */
+#if @WITH_XPTR@
+#define LIBXML_XPTR_ENABLED
+#else
+#define LIBXML_XPTR_DISABLED
+#endif
+
+/*
  * Whether iconv support is available
  */
 #if @WITH_ICONV@
diff --git a/result/XPath/tests/chaptersbase b/result/XPath/tests/chaptersbase
index b004efe..fd4040e 100644
--- a/result/XPath/tests/chaptersbase
+++ b/result/XPath/tests/chaptersbase
@@ -35,10 +35,25 @@
 Set contains 6 nodes:
 1  ELEMENT head
 2  ELEMENT chapter
+    ATTRIBUTE id
+      TEXT
+        content=chapter1
 3  ELEMENT chapter
+    ATTRIBUTE id
+      TEXT
+        content=chapter2
 4  ELEMENT chapter
+    ATTRIBUTE id
+      TEXT
+        content=chapter3
 5  ELEMENT chapter
+    ATTRIBUTE id
+      TEXT
+        content=chapter4
 6  ELEMENT chapter
+    ATTRIBUTE id
+      TEXT
+        content=chapter5
 
 ========================
 Expression: /child::EXAMPLE/child::head/child::title
@@ -75,7 +90,22 @@
 Object is a Node Set :
 Set contains 5 nodes:
 1  ELEMENT chapter
+    ATTRIBUTE id
+      TEXT
+        content=chapter1
 2  ELEMENT chapter
+    ATTRIBUTE id
+      TEXT
+        content=chapter2
 3  ELEMENT chapter
+    ATTRIBUTE id
+      TEXT
+        content=chapter3
 4  ELEMENT chapter
+    ATTRIBUTE id
+      TEXT
+        content=chapter4
 5  ELEMENT chapter
+    ATTRIBUTE id
+      TEXT
+        content=chapter5
diff --git a/result/XPath/tests/chaptersprefol b/result/XPath/tests/chaptersprefol
index 930bb7a..6222eed 100644
--- a/result/XPath/tests/chaptersprefol
+++ b/result/XPath/tests/chaptersprefol
@@ -26,6 +26,9 @@
 1  ELEMENT p
 2  ELEMENT title
 3  ELEMENT chapter
+    ATTRIBUTE id
+      TEXT
+        content=chapter2
 4  ELEMENT p
 5  ELEMENT image
     ATTRIBUTE href
@@ -34,6 +37,9 @@
 6  ELEMENT p
 7  ELEMENT title
 8  ELEMENT chapter
+    ATTRIBUTE id
+      TEXT
+        content=chapter1
 9  ELEMENT title
 10  ELEMENT head
 
@@ -42,9 +48,15 @@
 Object is a Node Set :
 Set contains 6 nodes:
 1  ELEMENT chapter
+    ATTRIBUTE id
+      TEXT
+        content=chapter4
 2  ELEMENT title
 3  ELEMENT p
 4  ELEMENT chapter
+    ATTRIBUTE id
+      TEXT
+        content=chapter5
 5  ELEMENT title
 6  ELEMENT p
 
@@ -63,14 +75,26 @@
 Set contains 13 nodes:
 1  ELEMENT p
 2  ELEMENT chapter
+    ATTRIBUTE id
+      TEXT
+        content=chapter2
 3  ELEMENT title
 4  ELEMENT p
 5  ELEMENT chapter
+    ATTRIBUTE id
+      TEXT
+        content=chapter3
 6  ELEMENT title
 7  ELEMENT p
 8  ELEMENT chapter
+    ATTRIBUTE id
+      TEXT
+        content=chapter4
 9  ELEMENT title
 10  ELEMENT p
 11  ELEMENT chapter
+    ATTRIBUTE id
+      TEXT
+        content=chapter5
 12  ELEMENT title
 13  ELEMENT p
diff --git a/result/XPath/tests/vidbase b/result/XPath/tests/vidbase
new file mode 100644
index 0000000..3c7b62f
--- /dev/null
+++ b/result/XPath/tests/vidbase
@@ -0,0 +1,42 @@
+
+========================
+Expression: id('chapter1')
+Object is a Node Set :
+Set contains 1 nodes:
+1  ELEMENT chapter
+    ATTRIBUTE id
+      TEXT
+        content=chapter1
+
+========================
+Expression: id('chapter3')
+Object is a Node Set :
+Set contains 1 nodes:
+1  ELEMENT chapter
+    ATTRIBUTE id
+      TEXT
+        content=chapter3
+
+========================
+Expression: id('chapter1')/p
+Object is a Node Set :
+Set contains 4 nodes:
+1  ELEMENT p
+2  ELEMENT p
+3  ELEMENT p
+4  ELEMENT p
+
+========================
+Expression: id('chapter1')//p
+Object is a Node Set :
+Set contains 4 nodes:
+1  ELEMENT p
+2  ELEMENT p
+3  ELEMENT p
+4  ELEMENT p
+
+========================
+Expression: id('chapter1')/p[1]
+Object is a Node Set :
+Set contains 1 nodes:
+1  ELEMENT p
diff --git a/result/XPath/xptr/chapterschildseq b/result/XPath/xptr/chapterschildseq
new file mode 100644
index 0000000..ef49ee5
--- /dev/null
+++ b/result/XPath/xptr/chapterschildseq
@@ -0,0 +1,14 @@
+
+========================
+Expression: /1/2/3
+Object is a Node Set :
+Set contains 1 nodes:
+1  ELEMENT image
+    ATTRIBUTE href
+      TEXT
+        content=linus.gif
+
+========================
+Expression: chapter1/3
+Object is a Node Set :
+Set contains 0 nodes:
diff --git a/result/XPath/xptr/chaptersparts b/result/XPath/xptr/chaptersparts
new file mode 100644
index 0000000..70b561b
--- /dev/null
+++ b/result/XPath/xptr/chaptersparts
@@ -0,0 +1,44 @@
+
+========================
+Expression: xpointer(//chapitre[2])
+Object is empty (NULL)
+
+========================
+Expression: xpointer(//chapter[2])
+Object is a Node Set :
+Set contains 1 nodes:
+1  ELEMENT chapter
+    ATTRIBUTE id
+      TEXT
+        content=chapter2
+
+========================
+Expression: xpointer(//chapitre[2])xpointer(//chapter[2])
+Object is a Node Set :
+Set contains 1 nodes:
+1  ELEMENT chapter
+    ATTRIBUTE id
+      TEXT
+        content=chapter2
+
+========================
+Expression: xpointer(id("chapter1"))
+Object is empty (NULL)
+
+========================
+Expression: xpointer(//*[@id="chapter1"])
+Object is a Node Set :
+Set contains 1 nodes:
+1  ELEMENT chapter
+    ATTRIBUTE id
+      TEXT
+        content=chapter1
+
+========================
+Expression: xpointer(id("chapter1"))xpointer(//*[@id="chapter1"])
+Object is a Node Set :
+Set contains 1 nodes:
+1  ELEMENT chapter
+    ATTRIBUTE id
+      TEXT
+        content=chapter1
diff --git a/result/XPath/xptr/chaptersrange b/result/XPath/xptr/chaptersrange
new file mode 100644
index 0000000..0b85ee7
--- /dev/null
+++ b/result/XPath/xptr/chaptersrange
@@ -0,0 +1,48 @@
+
+========================
+Expression: xpointer(//chapter[position() = 2]/range-to(following::chapter[1]))
+Object is a Location Set:
+1 :   Object is a range :
+  From node
+    ELEMENT chapter
+      ATTRIBUTE id
+        TEXT
+          content=chapter2
+  To node
+    ELEMENT chapter
+      ATTRIBUTE id
+        TEXT
+          content=chapter3
+
+
+========================
+Expression: xpointer(//chapter[position() <= 2]/range-to(following::chapter[1]))
+Object is a Location Set:
+1 :   Object is a range :
+  From node
+    ELEMENT chapter
+      ATTRIBUTE id
+        TEXT
+          content=chapter1
+  To node
+    ELEMENT chapter
+      ATTRIBUTE id
+        TEXT
+          content=chapter2
+
+2 :   Object is a range :
+  From node
+    ELEMENT chapter
+      ATTRIBUTE id
+        TEXT
+          content=chapter2
+  To node
+    ELEMENT chapter
+      ATTRIBUTE id
+        TEXT
+          content=chapter3
+
+
+========================
+Expression: xpointer(//chapter[position() = last()]/range-to(following::chapter[1]))
+Object is empty (NULL)
diff --git a/result/XPath/xptr/vidbase b/result/XPath/xptr/vidbase
new file mode 100644
index 0000000..8b9e92d
--- /dev/null
+++ b/result/XPath/xptr/vidbase
@@ -0,0 +1,19 @@
+
+========================
+Expression: xpointer(id('chapter1')/p)
+Object is a Node Set :
+Set contains 4 nodes:
+1  ELEMENT p
+2  ELEMENT p
+3  ELEMENT p
+4  ELEMENT p
+
+========================
+Expression: xpointer(id('chapter1')/p[1]/range-to(following-sibling::p[2]))
+Object is a Location Set:
+1 :   Object is a range :
+  From node
+    ELEMENT p
+  To node
+    ELEMENT p
+
diff --git a/result/XPath/xptr/vidchildseq b/result/XPath/xptr/vidchildseq
new file mode 100644
index 0000000..f06bb14
--- /dev/null
+++ b/result/XPath/xptr/vidchildseq
@@ -0,0 +1,18 @@
+
+========================
+Expression: /1/2/3
+Object is a Node Set :
+Set contains 1 nodes:
+1  ELEMENT image
+    ATTRIBUTE href
+      TEXT
+        content=linus.gif
+
+========================
+Expression: chapter1/3
+Object is a Node Set :
+Set contains 1 nodes:
+1  ELEMENT image
+    ATTRIBUTE href
+      TEXT
+        content=linus.gif
diff --git a/result/XPath/xptr/vidparts b/result/XPath/xptr/vidparts
new file mode 100644
index 0000000..bd5bd3c
--- /dev/null
+++ b/result/XPath/xptr/vidparts
@@ -0,0 +1,27 @@
+
+========================
+Expression: xpointer(id("chapter1"))
+Object is a Node Set :
+Set contains 1 nodes:
+1  ELEMENT chapter
+    ATTRIBUTE id
+      TEXT
+        content=chapter1
+
+========================
+Expression: xpointer(//*[@id="chapter1"])
+Object is a Node Set :
+Set contains 1 nodes:
+1  ELEMENT chapter
+    ATTRIBUTE id
+      TEXT
+        content=chapter1
+
+========================
+Expression: xpointer(id("chapter1"))xpointer(//*[@id="chapter1"])
+Object is a Node Set :
+Set contains 1 nodes:
+1  ELEMENT chapter
+    ATTRIBUTE id
+      TEXT
+        content=chapter1
diff --git a/test/XPath/docs/vid b/test/XPath/docs/vid
new file mode 100644
index 0000000..cdb7437
--- /dev/null
+++ b/test/XPath/docs/vid
@@ -0,0 +1,43 @@
+<?xml version="1.0"?>
+<!DOCTYPE iddemo [
+<!ELEMENT iddemo (head?, (chapter)*)>
+<!ATTLIST iddemo id ID #IMPLIED>
+<!ELEMENT head (title?, (p)*)>
+<!ATTLIST head id ID #IMPLIED>
+<!ELEMENT chapter (title?, (p | image)*)>
+<!ATTLIST chapter id ID #IMPLIED>
+<!ELEMENT image EMPTY>
+<!ATTLIST image href CDATA #IMPLIED>
+<!ELEMENT title (#PCDATA)>
+<!ELEMENT p (#PCDATA)>
+]>
+
+<iddemo>
+  <head>
+   <title>Welcome to Gnome</title>
+  </head>
+  <chapter id="chapter1">
+   <title>The Linux adventure</title>
+   <p>bla bla bla ...</p>
+   <image href="linus.gif"/>
+   <p>...</p>
+   <p>third p</p>
+   <p>fourth p</p>
+  </chapter>
+  <chapter id="chapter2">
+   <title>Chapter 2</title>
+   <p>this is chapter 2 ...</p>
+  </chapter>
+  <chapter id="chapter3">
+   <title>Chapter 3</title>
+   <p>this is chapter 3 ...</p>
+  </chapter>
+  <chapter id="chapter4">
+   <title>Chapter 4</title>
+   <p>this is chapter 4 ...</p>
+  </chapter>
+  <chapter id="chapter5">
+   <title>Chapter 5</title>
+   <p>this is chapter 5 ...</p>
+  </chapter>
+</iddemo>
diff --git a/test/XPath/tests/vidbase b/test/XPath/tests/vidbase
new file mode 100644
index 0000000..5cd79ac
--- /dev/null
+++ b/test/XPath/tests/vidbase
@@ -0,0 +1,5 @@
+id('chapter1')
+id('chapter3')
+id('chapter1')/p
+id('chapter1')//p
+id('chapter1')/p[1]
diff --git a/test/XPath/xptr/chapterschildseq b/test/XPath/xptr/chapterschildseq
new file mode 100644
index 0000000..db6278f
--- /dev/null
+++ b/test/XPath/xptr/chapterschildseq
@@ -0,0 +1,2 @@
+/1/2/3
+chapter1/3
diff --git a/test/XPath/xptr/chaptersparts b/test/XPath/xptr/chaptersparts
new file mode 100644
index 0000000..aadc47c
--- /dev/null
+++ b/test/XPath/xptr/chaptersparts
@@ -0,0 +1,6 @@
+xpointer(//chapitre[2])
+xpointer(//chapter[2]) 
+xpointer(//chapitre[2])xpointer(//chapter[2]) 
+xpointer(id("chapter1"))
+xpointer(//*[@id="chapter1"])
+xpointer(id("chapter1"))xpointer(//*[@id="chapter1"])
diff --git a/test/XPath/xptr/chaptersrange b/test/XPath/xptr/chaptersrange
new file mode 100644
index 0000000..0743111
--- /dev/null
+++ b/test/XPath/xptr/chaptersrange
@@ -0,0 +1,3 @@
+xpointer(//chapter[position() = 2]/range-to(following::chapter[1]))
+xpointer(//chapter[position() <= 2]/range-to(following::chapter[1]))
+xpointer(//chapter[position() = last()]/range-to(following::chapter[1]))
diff --git a/test/XPath/xptr/vidbase b/test/XPath/xptr/vidbase
new file mode 100644
index 0000000..b146383
--- /dev/null
+++ b/test/XPath/xptr/vidbase
@@ -0,0 +1,2 @@
+xpointer(id('chapter1')/p)
+xpointer(id('chapter1')/p[1]/range-to(following-sibling::p[2]))
diff --git a/test/XPath/xptr/vidchildseq b/test/XPath/xptr/vidchildseq
new file mode 100644
index 0000000..db6278f
--- /dev/null
+++ b/test/XPath/xptr/vidchildseq
@@ -0,0 +1,2 @@
+/1/2/3
+chapter1/3
diff --git a/test/XPath/xptr/vidparts b/test/XPath/xptr/vidparts
new file mode 100644
index 0000000..3afbbdd
--- /dev/null
+++ b/test/XPath/xptr/vidparts
@@ -0,0 +1,3 @@
+xpointer(id("chapter1"))
+xpointer(//*[@id="chapter1"])
+xpointer(id("chapter1"))xpointer(//*[@id="chapter1"])
diff --git a/xmlversion.h.in b/xmlversion.h.in
index 6b41be4..ed1c43f 100644
--- a/xmlversion.h.in
+++ b/xmlversion.h.in
@@ -78,6 +78,15 @@
 #endif
 
 /*
+ * Whether XPointer is configured in
+ */
+#if @WITH_XPTR@
+#define LIBXML_XPTR_ENABLED
+#else
+#define LIBXML_XPTR_DISABLED
+#endif
+
+/*
  * Whether iconv support is available
  */
 #if @WITH_ICONV@
diff --git a/xpath.c b/xpath.c
index 840ae4d..1d30755 100644
--- a/xpath.c
+++ b/xpath.c
@@ -784,7 +784,7 @@
 #ifdef LIBXML_XPTR_ENABLED
     } else if (obj->type == XPATH_LOCATIONSET) {
 	if (obj->user != NULL)
-	    xmlXPathFreeLocationSet(obj->user);
+	    xmlXPtrFreeLocationSet(obj->user);
 #endif
     } else if (obj->type == XPATH_STRING) {
 	if (obj->stringval != NULL)
@@ -2118,6 +2118,16 @@
     }
     fprintf(xmlXPathDebug, "Testing : ");
 #endif
+    /*
+     * 2.3 Node Tests
+     *  - For the attribute axis, the principal node type is attribute. 
+     *  - For the namespace axis, the principal node type is namespace. 
+     *  - For other axes, the principal node type is element. 
+     *
+     * A node test * is true for any node of the
+     * principal node type. For example, child::* willi
+     * select all element children of the context node
+     */
     for (i = 0;i < nodelist->nodeNr; i++) {
         ctxt->context->node = nodelist->nodeTab[i];
 
@@ -2157,8 +2167,8 @@
 		    break;
                 case NODE_TEST_ALL:
 		    if ((cur->type == XML_ELEMENT_NODE) ||
-		        (cur->type == XML_ATTRIBUTE_NODE)) {
-			/* !!! || (cur->type == XML_TEXT_NODE)) { */
+			(cur->type == XML_DOCUMENT_NODE) ||
+			(cur->type == XML_HTML_DOCUMENT_NODE)) {
 #ifdef DEBUG_STEP
                         n++;
 #endif
@@ -4756,6 +4766,15 @@
 void
 xmlXPathEvalRelativeLocationPath(xmlXPathParserContextPtr ctxt) {
     SKIP_BLANKS;
+    if ((CUR == '/') && (NXT(1) == '/')) {
+	SKIP(2);
+	SKIP_BLANKS;
+	xmlXPathNodeCollectAndTest(ctxt, AXIS_DESCENDANT_OR_SELF,
+			 NODE_TEST_TYPE, XML_ELEMENT_NODE, NULL, NULL);
+    } else if (CUR == '/') {
+	    NEXT;
+	SKIP_BLANKS;
+    }
     xmlXPathEvalStep(ctxt);
     SKIP_BLANKS;
     while (CUR == '/') {