[libxml2] Implement xpath1() XPointer scheme



commit 4612ce303145ea152aba11a5f7ee84c0fe939cfb
Author: Nick Wellnhofer <wellnhofer aevum de>
Date:   Thu Apr 21 03:52:52 2022 +0200

    Implement xpath1() XPointer scheme
    
    See https://www.w3.org/2005/04/xpointer-schemes/

 fuzz/genSeed.c                                   |  2 ++
 result/XPath/{xptr => xptr-xp1}/chapterschildseq |  0
 result/XPath/xptr-xp1/chaptersparts              | 44 ++++++++++++++++++++++++
 result/XPath/xptr-xp1/issue289base               |  7 ++++
 result/XPath/xptr-xp1/vidbase                    |  9 +++++
 result/XPath/{xptr => xptr-xp1}/vidchildseq      |  0
 result/XPath/xptr-xp1/viderror                   |  4 +++
 result/XPath/xptr-xp1/vidparts                   | 27 +++++++++++++++
 runtest.c                                        | 20 +++++++----
 test/XPath/{xptr => xptr-xp1}/chapterschildseq   |  0
 test/XPath/xptr-xp1/chaptersparts                |  6 ++++
 test/XPath/xptr-xp1/issue289base                 |  1 +
 test/XPath/xptr-xp1/vidbase                      |  1 +
 test/XPath/{xptr => xptr-xp1}/vidchildseq        |  0
 test/XPath/xptr-xp1/viderror                     |  1 +
 test/XPath/xptr-xp1/vidparts                     |  3 ++
 xpointer.c                                       |  7 ++--
 17 files changed, 123 insertions(+), 9 deletions(-)
---
diff --git a/fuzz/genSeed.c b/fuzz/genSeed.c
index 2f038027..01f0656b 100644
--- a/fuzz/genSeed.c
+++ b/fuzz/genSeed.c
@@ -362,6 +362,8 @@ processXPathDir(const char *testDir) {
             ret = -1;
         if (processXPath(testDir, docFile, docFile, data, "xptr", 1) != 0)
             ret = -1;
+        if (processXPath(testDir, docFile, docFile, data, "xptr-xp1", 1) != 0)
+            ret = -1;
 
         xmlFree(data);
     }
diff --git a/result/XPath/xptr/chapterschildseq b/result/XPath/xptr-xp1/chapterschildseq
similarity index 100%
rename from result/XPath/xptr/chapterschildseq
rename to result/XPath/xptr-xp1/chapterschildseq
diff --git a/result/XPath/xptr-xp1/chaptersparts b/result/XPath/xptr-xp1/chaptersparts
new file mode 100644
index 00000000..83e0569b
--- /dev/null
+++ b/result/XPath/xptr-xp1/chaptersparts
@@ -0,0 +1,44 @@
+
+========================
+Expression: xpath1(//chapitre[2])
+Object is empty (NULL)
+
+========================
+Expression: xpath1(//chapter[2])
+Object is a Node Set :
+Set contains 1 nodes:
+1  ELEMENT chapter
+    ATTRIBUTE id
+      TEXT
+        content=chapter2
+
+========================
+Expression: xpath1(//chapitre[2])xpath1(//chapter[2])
+Object is a Node Set :
+Set contains 1 nodes:
+1  ELEMENT chapter
+    ATTRIBUTE id
+      TEXT
+        content=chapter2
+
+========================
+Expression: xpath1(id("chapter1"))
+Object is empty (NULL)
+
+========================
+Expression: xpath1(//*[@id="chapter1"])
+Object is a Node Set :
+Set contains 1 nodes:
+1  ELEMENT chapter
+    ATTRIBUTE id
+      TEXT
+        content=chapter1
+
+========================
+Expression: xpath1(id("chapter1"))xpath1(//*[@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-xp1/issue289base b/result/XPath/xptr-xp1/issue289base
new file mode 100644
index 00000000..ffae7e80
--- /dev/null
+++ b/result/XPath/xptr-xp1/issue289base
@@ -0,0 +1,7 @@
+
+========================
+Expression: xmlns(b=abc://d/e:f) xpath1(/b:rootB)
+Object is a Node Set :
+Set contains 1 nodes:
+1  ELEMENT rootB
+    default namespace href=abc://d/e:f
diff --git a/result/XPath/xptr-xp1/vidbase b/result/XPath/xptr-xp1/vidbase
new file mode 100644
index 00000000..a5447b05
--- /dev/null
+++ b/result/XPath/xptr-xp1/vidbase
@@ -0,0 +1,9 @@
+
+========================
+Expression: xpath1(id('chapter1')/p)
+Object is a Node Set :
+Set contains 4 nodes:
+1  ELEMENT p
+2  ELEMENT p
+3  ELEMENT p
+4  ELEMENT p
diff --git a/result/XPath/xptr/vidchildseq b/result/XPath/xptr-xp1/vidchildseq
similarity index 100%
rename from result/XPath/xptr/vidchildseq
rename to result/XPath/xptr-xp1/vidchildseq
diff --git a/result/XPath/xptr-xp1/viderror b/result/XPath/xptr-xp1/viderror
new file mode 100644
index 00000000..562cab4a
--- /dev/null
+++ b/result/XPath/xptr-xp1/viderror
@@ -0,0 +1,4 @@
+
+========================
+Expression: xpath1(non-existing-fn())
+Object is empty (NULL)
diff --git a/result/XPath/xptr-xp1/vidparts b/result/XPath/xptr-xp1/vidparts
new file mode 100644
index 00000000..918a08f0
--- /dev/null
+++ b/result/XPath/xptr-xp1/vidparts
@@ -0,0 +1,27 @@
+
+========================
+Expression: xpath1(id("chapter1"))
+Object is a Node Set :
+Set contains 1 nodes:
+1  ELEMENT chapter
+    ATTRIBUTE id
+      TEXT
+        content=chapter1
+
+========================
+Expression: xpath1(//*[@id="chapter1"])
+Object is a Node Set :
+Set contains 1 nodes:
+1  ELEMENT chapter
+    ATTRIBUTE id
+      TEXT
+        content=chapter1
+
+========================
+Expression: xpath1(id("chapter1"))xpath1(//*[@id="chapter1"])
+Object is a Node Set :
+Set contains 1 nodes:
+1  ELEMENT chapter
+    ATTRIBUTE id
+      TEXT
+        content=chapter1
diff --git a/runtest.c b/runtest.c
index df0dff4d..ea1214b6 100644
--- a/runtest.c
+++ b/runtest.c
@@ -2596,7 +2596,7 @@ xpathDocTest(const char *filename,
     return(ret);
 }
 
-#ifdef LIBXML_XPTR_LOCS_ENABLED
+#ifdef LIBXML_XPTR_ENABLED
 /**
  * xptrDocTest:
  * @filename: the file to parse
@@ -2619,23 +2619,24 @@ xptrDocTest(const char *filename,
     glob_t globbuf;
     size_t i;
     int ret = 0, res;
+    const char *subdir = options == -1 ? "xptr-xp1" : "xptr";
 
     xpathDocument = xmlReadFile(filename, NULL,
-                                options | XML_PARSE_DTDATTR | XML_PARSE_NOENT);
+                                XML_PARSE_DTDATTR | XML_PARSE_NOENT);
     if (xpathDocument == NULL) {
         fprintf(stderr, "Failed to load %s\n", filename);
        return(-1);
     }
 
-    res = snprintf(pattern, 499, "./test/XPath/xptr/%s*",
-            baseFilename(filename));
+    res = snprintf(pattern, 499, "./test/XPath/%s/%s*",
+            subdir, baseFilename(filename));
     if (res >= 499)
         pattern[499] = 0;
     globbuf.gl_offs = 0;
     glob(pattern, GLOB_DOOFFS, NULL, &globbuf);
     for (i = 0;i < globbuf.gl_pathc;i++) {
-        res = snprintf(result, 499, "result/XPath/xptr/%s",
-                baseFilename(globbuf.gl_pathv[i]));
+        res = snprintf(result, 499, "result/XPath/%s/%s",
+                subdir, baseFilename(globbuf.gl_pathv[i]));
         if (res >= 499)
             result[499] = 0;
        res = xpathCommonTest(globbuf.gl_pathv[i], &result[0], 1, 0);
@@ -4527,8 +4528,13 @@ testDesc testDescriptions[] = {
     { "XPath document queries regression tests" ,
       xpathDocTest, "./test/XPath/docs/*", NULL, NULL, NULL,
       0 },
-#ifdef LIBXML_XPTR_LOCS_ENABLED
+#ifdef LIBXML_XPTR_ENABLED
     { "XPointer document queries regression tests" ,
+      xptrDocTest, "./test/XPath/docs/*", NULL, NULL, NULL,
+      -1 },
+#endif
+#ifdef LIBXML_XPTR_LOCS_ENABLED
+    { "XPointer xpointer() queries regression tests" ,
       xptrDocTest, "./test/XPath/docs/*", NULL, NULL, NULL,
       0 },
 #endif
diff --git a/test/XPath/xptr/chapterschildseq b/test/XPath/xptr-xp1/chapterschildseq
similarity index 100%
rename from test/XPath/xptr/chapterschildseq
rename to test/XPath/xptr-xp1/chapterschildseq
diff --git a/test/XPath/xptr-xp1/chaptersparts b/test/XPath/xptr-xp1/chaptersparts
new file mode 100644
index 00000000..8b203576
--- /dev/null
+++ b/test/XPath/xptr-xp1/chaptersparts
@@ -0,0 +1,6 @@
+xpath1(//chapitre[2])
+xpath1(//chapter[2]) 
+xpath1(//chapitre[2])xpath1(//chapter[2]) 
+xpath1(id("chapter1"))
+xpath1(//*[@id="chapter1"])
+xpath1(id("chapter1"))xpath1(//*[@id="chapter1"])
diff --git a/test/XPath/xptr-xp1/issue289base b/test/XPath/xptr-xp1/issue289base
new file mode 100644
index 00000000..59379ef3
--- /dev/null
+++ b/test/XPath/xptr-xp1/issue289base
@@ -0,0 +1 @@
+xmlns(b=abc://d/e:f) xpath1(/b:rootB)
diff --git a/test/XPath/xptr-xp1/vidbase b/test/XPath/xptr-xp1/vidbase
new file mode 100644
index 00000000..82e098b6
--- /dev/null
+++ b/test/XPath/xptr-xp1/vidbase
@@ -0,0 +1 @@
+xpath1(id('chapter1')/p)
diff --git a/test/XPath/xptr/vidchildseq b/test/XPath/xptr-xp1/vidchildseq
similarity index 100%
rename from test/XPath/xptr/vidchildseq
rename to test/XPath/xptr-xp1/vidchildseq
diff --git a/test/XPath/xptr-xp1/viderror b/test/XPath/xptr-xp1/viderror
new file mode 100644
index 00000000..104e57f1
--- /dev/null
+++ b/test/XPath/xptr-xp1/viderror
@@ -0,0 +1 @@
+xpath1(non-existing-fn())
diff --git a/test/XPath/xptr-xp1/vidparts b/test/XPath/xptr-xp1/vidparts
new file mode 100644
index 00000000..bbf61768
--- /dev/null
+++ b/test/XPath/xptr-xp1/vidparts
@@ -0,0 +1,3 @@
+xpath1(id("chapter1"))
+xpath1(//*[@id="chapter1"])
+xpath1(id("chapter1"))xpath1(//*[@id="chapter1"])
diff --git a/xpointer.c b/xpointer.c
index 5805407c..ba1e31e0 100644
--- a/xpointer.c
+++ b/xpointer.c
@@ -1000,7 +1000,8 @@ xmlXPtrEvalXPtrPart(xmlXPathParserContextPtr ctxt, xmlChar *name) {
        XP_ERROR(XPTR_SYNTAX_ERROR);
     }
 
-    if (xmlStrEqual(name, (xmlChar *) "xpointer")) {
+    if (xmlStrEqual(name, (xmlChar *) "xpointer") ||
+        xmlStrEqual(name, (xmlChar *) "xpath1")) {
        const xmlChar *oldBase = ctxt->base;
        const xmlChar *oldCur = ctxt->cur;
 
@@ -1014,6 +1015,9 @@ xmlXPtrEvalXPtrPart(xmlXPathParserContextPtr ctxt, xmlChar *name) {
        ctxt->context->node = (xmlNodePtr)ctxt->context->doc;
        ctxt->context->proximityPosition = 1;
        ctxt->context->contextSize = 1;
+#ifdef LIBXML_XPTR_LOCS_ENABLED
+        ctxt->xptr = xmlStrEqual(name, (xmlChar *) "xpointer");
+#endif
        xmlXPathEvalExpr(ctxt);
        ctxt->base = oldBase;
         ctxt->cur = oldCur;
@@ -1361,7 +1365,6 @@ xmlXPtrEval(const xmlChar *str, xmlXPathContextPtr ctx) {
     ctxt = xmlXPathNewParserContext(str, ctx);
     if (ctxt == NULL)
        return(NULL);
-    ctxt->xptr = 1;
     xmlXPtrEvalXPointer(ctxt);
 
     if ((ctxt->value != NULL) &&


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]