cleanup the make rebuild in doc, this include new directive to stop

* globals.c xmlwriter.c doc/apibuild.py include/libxml/globals.h
  include/libxml/pattern.h include/libxml/schemasInternals.h
  include/libxml/xmlexports.h include/libxml/xmlwriter.h: cleanup
  the make rebuild in doc, this include new directive to stop
  documentation warnings
* doc/* doc/html/*: rebuilt the docs
* pattern.c xmlreader.c include/libxml/pattern.h
  include/libxml/xmlreader.h: adding xmlTextReaderPreservePattern()
  to save nodes while scanning the tree with the reader, cleanup
  the way element were freed, and xmlTextReaderPreserve()
  implementation, the API might change for namespace binding support
  when compiling patterns.
* doc/examples/*: added reader3.c exposing the xmlTextReaderPreserve()
Daniel
diff --git a/xmlreader.c b/xmlreader.c
index efdba3d..0295ddc 100644
--- a/xmlreader.c
+++ b/xmlreader.c
@@ -41,6 +41,9 @@
 #ifdef LIBXML_XINCLUDE_ENABLED
 #include <libxml/xinclude.h>
 #endif
+#ifdef LIBXML_PATTERN_ENABLED
+#include <libxml/pattern.h>
+#endif
 
 /* #define DEBUG_CALLBACKS */
 /* #define DEBUG_READER */
@@ -147,10 +150,17 @@
     xmlXIncludeCtxtPtr xincctxt;	/* the xinclude context */
     int                in_xinclude;	/* counts for xinclude */
 #endif
+#ifdef LIBXML_PATTERN_ENABLED
+    int                patternNr;       /* number of preserve patterns */
+    int                patternMax;      /* max preserve patterns */
+    xmlPatternPtr     *patternTab;      /* array of preserve patterns */
+#endif
+    int                preserves;	/* level of preserves */
 };
 
 #define NODE_IS_EMPTY		0x1
 #define NODE_IS_PRESERVED	0x2
+#define NODE_IS_SPRESERVED	0x4
 
 /**
  * CONSTSTR:
@@ -1255,13 +1265,19 @@
 	    (reader->node->type == XML_ELEMENT_NODE))
 	    xmlTextReaderValidatePop(reader);
 #endif /* LIBXML_REGEXP_ENABLED */
+        if ((reader->preserves > 0) &&
+	    (reader->node->extra & NODE_IS_SPRESERVED))
+	    reader->preserves--;
 	reader->node = reader->node->next;
 	reader->state = XML_TEXTREADER_ELEMENT;
 
 	/*
 	 * Cleanup of the old node
 	 */
-	if ((reader->node->prev != NULL) &&
+	if ((reader->preserves == 0) &&
+	    (reader->in_xinclude == 0) &&
+	    (reader->entNr == 0) &&
+	    (reader->node->prev != NULL) &&
             (reader->node->prev->type != XML_DTD_NODE) &&
 	    (reader->entNr == 0)) {
 	    xmlNodePtr tmp = reader->node->prev;
@@ -1284,6 +1300,9 @@
     if ((reader->validate) && (reader->node->type == XML_ELEMENT_NODE))
 	xmlTextReaderValidatePop(reader);
 #endif /* LIBXML_REGEXP_ENABLED */
+    if ((reader->preserves > 0) &&
+	(reader->node->extra & NODE_IS_SPRESERVED))
+	reader->preserves--;
     reader->node = reader->node->parent;
     if ((reader->node == NULL) ||
 	(reader->node->type == XML_DOCUMENT_NODE) ||
@@ -1301,7 +1320,10 @@
 	/*
 	 * Cleanup of the old node
 	 */
-	if ((oldnode->type != XML_DTD_NODE) &&
+	if ((reader->preserves == 0) &&
+	    (reader->in_xinclude == 0) &&
+	    (reader->entNr == 0) &&
+	    (oldnode->type != XML_DTD_NODE) &&
 	    ((oldnode->extra & NODE_IS_PRESERVED) == 0) &&
 	    (reader->entNr == 0)) {
 	    xmlUnlinkNode(oldnode);
@@ -1310,6 +1332,15 @@
 
 	goto node_end;
     }
+    if ((reader->preserves == 0) &&
+        (reader->in_xinclude == 0) &&
+	(reader->entNr == 0) &&
+        (reader->node->last != NULL) &&
+        ((reader->node->last->extra & NODE_IS_PRESERVED) == 0)) {
+	xmlNodePtr tmp = reader->node->last;
+	xmlUnlinkNode(tmp);
+	xmlTextReaderFreeNode(reader, tmp);
+    }
     reader->depth--;
     reader->state = XML_TEXTREADER_BACKTRACK;
 
@@ -1403,6 +1434,18 @@
 	}
     }
 #endif /* LIBXML_REGEXP_ENABLED */
+#ifdef LIBXML_PATTERN_ENABLED
+    if ((reader->patternNr > 0) && (reader->state != XML_TEXTREADER_END) &&
+        (reader->state != XML_TEXTREADER_BACKTRACK)) {
+        int i;
+	for (i = 0;i < reader->patternNr;i++) {
+	     if (xmlPatternMatch(reader->patternTab[i], reader->node) == 1) {
+	         xmlTextReaderPreserve(reader);
+		 break;
+             }
+	}
+    }
+#endif /* LIBXML_PATTERN_ENABLED */
     return(1);
 node_end:
     reader->mode = XML_TEXTREADER_DONE;
@@ -1859,6 +1902,10 @@
 #ifdef LIBXML_XINCLUDE_ENABLED
     ret->xinclude = 0;
 #endif
+#ifdef LIBXML_PATTERN_ENABLED
+    ret->patternMax = 0;
+    ret->patternTab = NULL;
+#endif
     return(ret);
 }
 
@@ -1918,6 +1965,16 @@
     if (reader->xincctxt != NULL)
 	xmlXIncludeFreeContext(reader->xincctxt);
 #endif
+#ifdef LIBXML_PATTERN_ENABLED
+    if (reader->patternTab != NULL) {
+        int i;
+	for (i = 0;i < reader->patternNr;i++) {
+	    if (reader->patternTab[i] != NULL)
+	        xmlFreePattern(reader->patternTab[i]);
+	}
+	xmlFree(reader->patternTab);
+    }
+#endif
     if (reader->ctxt != NULL) {
         if (reader->dict == reader->ctxt->dict)
 	    reader->dict = NULL;
@@ -3476,16 +3533,72 @@
         cur = reader->node;
     if (cur == NULL)
         return(NULL);
-    cur->extra |= NODE_IS_PRESERVED;
+
+    if (cur->type != XML_DOCUMENT_NODE) {
+	cur->extra |= NODE_IS_PRESERVED;
+	cur->extra |= NODE_IS_SPRESERVED;
+    }
+    reader->preserves++;
         
     parent = cur->parent;;
     while (parent != NULL) {
-        parent->extra |= NODE_IS_PRESERVED;
+        if (parent->type == XML_ELEMENT_NODE)
+	    parent->extra |= NODE_IS_PRESERVED;
 	parent = parent->parent;
     }
     return(cur);
 }
 
+#ifdef LIBXML_PATTERN_ENABLED
+/**
+ * xmlTextReaderPreservePattern:
+ * @reader:  the xmlTextReaderPtr used
+ * @pattern:  an XPath subset pattern
+ * 
+ * This tells the XML Reader to preserve all nodes matched by the
+ * pattern. The caller must also use xmlTextReaderCurrentDoc() to
+ * keep an handle on the resulting document once parsing has finished
+ *
+ * Returns a positive number in case of success and -1 in case of error
+ */
+int
+xmlTextReaderPreservePattern(xmlTextReaderPtr reader, const xmlChar *pattern) {
+    xmlPatternPtr comp;
+
+    if ((reader == NULL) || (pattern == NULL))
+	return(-1);
+    
+    comp = xmlPatterncompile(pattern, reader->dict, 0);
+    if (comp == NULL)
+        return(-1);
+
+    if (reader->patternMax <= 0) {
+	reader->patternMax = 4;
+	reader->patternTab = (xmlPatternPtr *) xmlMalloc(reader->patternMax *
+					      sizeof(reader->patternTab[0]));
+        if (reader->patternTab == NULL) {
+            xmlGenericError(xmlGenericErrorContext, "xmlMalloc failed !\n");
+            return (-1);
+        }
+    }
+    if (reader->patternNr >= reader->patternMax) {
+        xmlPatternPtr *tmp;
+        reader->patternMax *= 2;
+	tmp = (xmlPatternPtr *) xmlRealloc(reader->patternTab,
+                                      reader->patternMax *
+                                      sizeof(reader->patternTab[0]));
+        if (tmp == NULL) {
+            xmlGenericError(xmlGenericErrorContext, "xmlRealloc failed !\n");
+	    reader->patternMax /= 2;
+            return (-1);
+        }
+	reader->patternTab = tmp;
+    }
+    reader->patternTab[reader->patternNr] = comp;
+    return(reader->patternNr++);
+}
+#endif
+
 /**
  * xmlTextReaderCurrentDoc:
  * @reader:  the xmlTextReaderPtr used
@@ -4054,6 +4167,20 @@
         reader->xinclude = 0;
     reader->in_xinclude = 0;
 #endif
+#ifdef LIBXML_PATTERN_ENABLED
+    if (reader->patternTab == NULL) {
+        reader->patternNr = 0;
+	reader->patternMax = 0;
+    }
+    while (reader->patternNr > 0) {
+        reader->patternNr--;
+	if (reader->patternTab[reader->patternNr] != NULL) {
+	    xmlFreePattern(reader->patternTab[reader->patternNr]);
+            reader->patternTab[reader->patternNr] = NULL;
+	}
+    }
+#endif
+
     if (options & XML_PARSE_DTDVALID)
         reader->validate = XML_TEXTREADER_VALIDATE_DTD;