Further enhancement for XPath streaming, consolidated with schemas usage

* pattern.c, xpath.c, include/libxml/pattern.h: Further
  enhancement for XPath streaming, consolidated with
  schemas usage of pattern.c.  Added a new enum
  xmlPatternFlags.
* doc/*, testapi.c, elfgcchack.h: updated to reflect new
  enum.
* test/XPath/tests/mixedpat, test/XPath/docs/mixed,
  result/XPath/mixedpat: added regression test for problems
  reported in bug306348
diff --git a/pattern.c b/pattern.c
index fdd9f16..7bd8bb0 100644
--- a/pattern.c
+++ b/pattern.c
@@ -48,7 +48,10 @@
 #define XML_STREAM_STEP_ROOT	4
 #define XML_STREAM_STEP_ATTR	8
 
-#define XML_PATTERN_NOTPATTERN 1
+#define XML_PATTERN_NOTPATTERN  (XML_PATTERN_XPATH | \
+				 XML_PATTERN_XSSEL | \
+				 XML_PATTERN_XSFIELD)
+#define XML_PATTERN_XSD		(XML_PATTERN_XSSEL | XML_PATTERN_XSFIELD)
 
 typedef struct _xmlStreamStep xmlStreamStep;
 typedef xmlStreamStep *xmlStreamStepPtr;
@@ -119,16 +122,15 @@
     const xmlChar *value2;
 };
 
-#define PAT_FROM_ROOT	1
-#define PAT_FROM_CUR	2
+#define PAT_FROM_ROOT	(1<<8)
+#define PAT_FROM_CUR	(1<<9)
 
 struct _xmlPattern {
     void *data;    		/* the associated template */
     xmlDictPtr dict;		/* the optional dictionary */
     struct _xmlPattern *next;	/* next pattern if | is used */
     const xmlChar *pattern;	/* the pattern */
-
-    int flags;			/* flags */
+    xmlPatternFlags flags;	/* flags */
     int nbStep;
     int maxStep;
     xmlStepOpPtr steps;        /* ops for computation */
@@ -692,11 +694,11 @@
     if (xmlPatternAdd(ctxt, ctxt->comp, (op), (val), (val2))) goto error;
 
 #define XSLT_ERROR(X)							\
-    { xsltError(ctxt, __FILE__, __LINE__, X);			\
+    { xsltError(ctxt, __FILE__, __LINE__, X);				\
       ctxt->error = (X); return; }
 
 #define XSLT_ERROR0(X)							\
-    { xsltError(ctxt, __FILE__, __LINE__, X);			\
+    { xsltError(ctxt, __FILE__, __LINE__, X);				\
       ctxt->error = (X); return(0); }
 
 #if 0
@@ -1047,8 +1049,8 @@
 		    }
 		    if (i >= ctxt->nb_namespaces) {
 			ERROR5(NULL, NULL, NULL,
-			    "xmlCompileStepPattern : no namespace bound to prefix %s\n",
-			    prefix);
+			    "xmlCompileStepPattern : no namespace bound "
+			    	"to prefix %s\n", prefix);
 			ctxt->error = 1;
 			goto error;
 		    }
@@ -1122,9 +1124,10 @@
     SKIP_BLANKS;
     if (CUR == '/') {
         ctxt->comp->flags |= PAT_FROM_ROOT;
-    } else if (CUR == '.') {
+    } else if ((CUR == '.') || (ctxt->comp->flags & XML_PATTERN_NOTPATTERN)) {
         ctxt->comp->flags |= PAT_FROM_CUR;
     }
+	
     if ((CUR == '/') && (NXT(1) == '/')) {
 	PUSH(XML_OP_ANCESTOR, NULL, NULL);
 	NEXT;
@@ -1581,9 +1584,9 @@
 	*/
 	if (comp->nbStep == 0) {
 	    /*
-	    * For non-pattern like evaluation like XML Schema IDCs,
-	    * this will match if we are at the first level only,
-	    * otherwise on every level.
+	    * For non-pattern like evaluation like XML Schema IDCs
+	    * or traditional XPath expressions, this will match if
+	    * we are at the first level only, otherwise on every level.
 	    */
 	    if ((nodeType == XML_ELEMENT_NODE) &&
 		(((stream->flags & XML_PATTERN_NOTPATTERN) == 0) ||
@@ -1593,18 +1596,20 @@
 	    stream->level++;
 	    goto stream_next;
 	}
-	tmp = stream->level;
-	for (i = 0; i < comp->nbStep; i++) {
-	    if (comp->steps[i].flags & XML_STREAM_STEP_DESC) {
-		tmp = -2;
-		break;
+	if ((stream->flags & XML_PATTERN_NOTPATTERN) != 0) {
+	    tmp = stream->level;
+	    for (i = 0; i < comp->nbStep; i++) {
+	        if (comp->steps[i].flags & XML_STREAM_STEP_DESC) {
+		    tmp = -2;
+		    break;
+	        }
 	    }
-	}
-	if (comp->nbStep < tmp) {
-	    stream->level++;
-	    goto stream_next;
-	}
+	    if (comp->nbStep <= tmp) {
+	        stream->level++;
+	        goto stream_next;
+	    }
 
+	}
 	/*
 	 * Check evolution of existing states
 	 */
@@ -1685,7 +1690,7 @@
 	*/
 	desc = comp->steps[0].flags & XML_STREAM_STEP_DESC;
 	if ( ((comp->steps[0].flags & XML_STREAM_STEP_ROOT) == 0) &&
-	     ( ((stream->flags & XML_PATTERN_NOTPATTERN) == 0) ||
+	     ( ((stream->flags & XML_PATTERN_XSD) == 0) ||
 	       ( (desc || (stream->level == 1)) )
 	     )
 	   ) {
@@ -1709,48 +1714,26 @@
 	if (!(comp->steps[0].flags & XML_STREAM_STEP_ROOT)) {
 #endif
 	*/
-	    match = 0;
-	    if (comp->dict) {
-		if (comp->steps[0].name == NULL) {
-		    if (comp->steps[0].ns == NULL)
-			match = 1;
-		    else
+	    if (comp->steps[0].name == NULL) {
+		if (comp->steps[0].ns == NULL)
+		    match = 1;
+		else {
+		    if (comp->dict)
 			match = (comp->steps[0].ns == ns);
-		} else {
-		    if (stream->flags & XML_PATTERN_NOTPATTERN) {
-			/* 
-			* Workaround for missing "self::node() on "foo".
-			*/
-			if (!desc) {
-			    xmlStreamCtxtAddState(stream, 0, stream->level);
-			    goto stream_next;
-			} else {
-			    match = ((comp->steps[0].name == name) &&
-				 (comp->steps[0].ns == ns));
-			}
-		    } else {
-			match = ((comp->steps[0].name == name) &&
-			     (comp->steps[0].ns == ns));
-		    }
-		}
-	    } else {
-		if (comp->steps[0].name == NULL) {
-		    if (comp->steps[0].ns == NULL)
-			match = 1;
 		    else
 			match = xmlStrEqual(comp->steps[0].ns, ns);
+		}
+	    } else {
+		if ((stream->flags & XML_PATTERN_XSD) && (!desc)) {
+		    /*
+		     * Workaround for missing "self::node() on "foo".
+		     */
+		    xmlStreamCtxtAddState(stream, 0, stream->level);
+		    goto stream_next;
 		} else {
-		    if (stream->flags & XML_PATTERN_NOTPATTERN) {
-			/* 
-			* Workaround for missing "self::node() on "foo".
-			*/
-			if (!desc) {
-			    xmlStreamCtxtAddState(stream, 0, stream->level);
-			    goto stream_next;
-			} else {
-			    match = ((xmlStrEqual(comp->steps[0].name, name)) &&
-				 (xmlStrEqual(comp->steps[0].ns, ns)));
-			}
+		    if (comp->dict) {
+			match = ((comp->steps[0].name == name) &&
+				 (comp->steps[0].ns == ns));
 		    } else {
 			match = ((xmlStrEqual(comp->steps[0].name, name)) &&
 			     (xmlStrEqual(comp->steps[0].ns, ns)));
@@ -1873,7 +1856,7 @@
  */
 xmlPatternPtr
 xmlPatterncompile(const xmlChar *pattern, xmlDict *dict,
-                  int flags ATTRIBUTE_UNUSED,
+                  xmlPatternFlags flags,
                   const xmlChar **namespaces) {
     xmlPatternPtr ret = NULL, cur;
     xmlPatParserContextPtr ctxt = NULL;
@@ -1933,8 +1916,10 @@
 	    xmlStreamCompile(cur);
 	if (xmlReversePattern(cur) < 0)
 	    goto error;
-	if (tmp != NULL)
+	if (tmp != NULL) {
 	    xmlFree(tmp);
+	    tmp = NULL;
+	}
 	start = or;
     }
     if (streamable == 0) {