fixed remaining known bugs in the XPath streaming, and switched XPath to

* pattern.c xpath.c: fixed remaining known bugs in the XPath streaming,
  and switched XPath to use it by default when possible
Daniel
diff --git a/ChangeLog b/ChangeLog
index df3c002..50a6e65 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,8 @@
+Mon Feb 21 11:41:41 CET 2005 Daniel Veillard <daniel@veillard.com>
+
+	* pattern.c xpath.c: fixed remaining known bugs in the XPath streaming,
+	  and switched XPath to use it by default when possible
+
 Sat Feb 19 19:25:14 CET 2005 Daniel Veillard <daniel@veillard.com>
 
 	* xmlschemastypes.c: a bit of cleanup
diff --git a/pattern.c b/pattern.c
index 560dc20..22d5c31 100644
--- a/pattern.c
+++ b/pattern.c
@@ -231,6 +231,7 @@
     while (comp != NULL) {
 	cur = comp;
 	comp = comp->next;
+	cur->next = NULL;
 	xmlFreePattern(cur);
     }
 }
@@ -1081,6 +1082,10 @@
 	    xmlFree(name);
 	}
     } else if (CUR == '*') {
+        if (name != NULL) {
+	    ctxt->error = 1;
+	    goto error;
+	}
 	NEXT;
 	PUSH(XML_OP_ALL, token, NULL);
     } else {
@@ -1350,7 +1355,19 @@
         stream->dict = comp->dict;
 	xmlDictReference(stream->dict);
     }
-    for (i = 0;i < comp->nbStep;i++) {
+
+    /*
+     * Skip leading ./ on relative paths
+     */
+    i = 0;
+    while ((comp->flags & PAT_FROM_CUR) && (comp->nbStep > i + 2) &&
+        (comp->steps[i].op == XML_OP_ELEM) &&
+	(comp->steps[i].value == NULL) &&
+	(comp->steps[i].value2 == NULL) &&
+	(comp->steps[i + 1].op == XML_OP_PARENT)) {
+	i += 2;
+    }
+    for (;i < comp->nbStep;i++) {
         switch (comp->steps[i].op) {
 	    case XML_OP_END:
 	        break;
@@ -1374,8 +1391,15 @@
 		if (s < 0)
 		    goto error;
 		break;
-	    case XML_OP_CHILD:
 	    case XML_OP_ELEM:
+	        if ((comp->steps[i].value == NULL) &&
+		    (comp->steps[i].value2 == NULL) &&
+		    (comp->nbStep > i + 2) &&
+		    (comp->steps[i + 1].op == XML_OP_PARENT)) {
+		    i++;
+		    continue;
+		 }
+	    case XML_OP_CHILD:
 	        s = xmlStreamCompAddStep(stream, comp->steps[i].value,
 		                         comp->steps[i].value2, flags);
 		flags = 0;
@@ -1389,6 +1413,13 @@
 		    goto error;
 		break;
 	    case XML_OP_PARENT:
+	        if ((comp->nbStep > i + 1) &&
+		    (comp->steps[i + 1].op == XML_OP_ELEM) &&
+		    (comp->steps[i + 1].value == NULL) &&
+		    (comp->steps[i + 1].value2 == NULL)) {
+		    i++;
+		    continue;
+		 }
 	        break;
 	    case XML_OP_ANCESTOR:
 	        flags |= XML_STREAM_STEP_DESC;
@@ -1816,6 +1847,8 @@
     xmlPatParserContextPtr ctxt = NULL;
     const xmlChar *or, *start;
     xmlChar *tmp = NULL;
+    int type = 0;
+    int streamable = 1;
 
     if (pattern == NULL)
         return(NULL);
@@ -1851,7 +1884,19 @@
 	xmlFreePatParserContext(ctxt);
 
 
-	xmlStreamCompile(cur);
+        if (streamable) {
+	    if (type == 0) {
+	        type = cur->flags & (PAT_FROM_ROOT | PAT_FROM_CUR);
+	    } else if (type == PAT_FROM_ROOT) {
+	        if (cur->flags & PAT_FROM_CUR)
+		    streamable = 0;
+	    } else if (type == PAT_FROM_CUR) {
+	        if (cur->flags & PAT_FROM_ROOT)
+		    streamable = 0;
+	    }
+	}
+	if (streamable)
+	    xmlStreamCompile(cur);
 	if (xmlReversePattern(cur) < 0)
 	    goto error;
 	if (tmp != NULL) {
@@ -1860,6 +1905,16 @@
 	}
 	start = or;
     }
+    if (streamable == 0) {
+        cur = ret;
+	while (cur != NULL) {
+	    if (cur->stream != NULL) {
+		xmlFreeStreamComp(cur->stream);
+		cur->stream = NULL;
+	    }
+	    cur = cur->next;
+	}
+    }
     return(ret);
 error:
     if (ctxt != NULL) xmlFreePatParserContext(ctxt);
diff --git a/xpath.c b/xpath.c
index 4e7941e..c5bbf2a 100644
--- a/xpath.c
+++ b/xpath.c
@@ -56,16 +56,7 @@
 #endif
 
 #ifdef LIBXML_PATTERN_ENABLED
-/* currently only in testing for DV as it's not yet solid enough for XSLT */
-/*
- * TODO:
- *  - fix the | where there is both relative and absolute expressions
- *    probably need new pattens APIs to separate both e.g "//b | a "
- *  - fix also the 0 depth trick used for "/" and "." when or'ed
- *  - double check /. is a noop
- *  - libxslt tests show a mem leak of a few bytes
- */
-/* #define XPATH_STREAMING */
+#define XPATH_STREAMING
 #endif
 
 #define TODO 								\
@@ -10963,13 +10954,14 @@
     from_root = xmlPatternFromRoot(comp);
     if (from_root < 0)
         return(NULL);
-/*    printf("stream eval: depth %d from root %d\n", max_depth, from_root); */
+#if 0
+    printf("stream eval: depth %d from root %d\n", max_depth, from_root);
+#endif
 
     retval = xmlXPathNewNodeSet(NULL);
     if (retval == NULL)
         return(NULL);
     
-    /* FIXME '. | /' */
     if ((from_root) && (max_depth == 0)) {
 	xmlXPathNodeSetAddUnique(retval->nodesetval, (xmlNodePtr) ctxt->doc);
 	return(retval);
@@ -11085,8 +11077,10 @@
 
     } while ((cur != NULL) && (depth >= 0));
 done:
-/*    printf("stream eval: checked %d nodes selected %d\n",
-           nb_nodes, retval->nodesetval->nodeNr); */
+#if 0
+    printf("stream eval: checked %d nodes selected %d\n",
+           nb_nodes, retval->nodesetval->nodeNr);
+#endif
     xmlFreeStreamCtxt(patstream);
     return(retval);
 }