adding a new API for Christian Glahn: xmlParseBalancedChunkMemoryRecover

* parser.c include/libxml/parser.h: adding a new API for Christian
  Glahn: xmlParseBalancedChunkMemoryRecover
* valid.c: patch from Rick Jones for some grammar cleanup in
  validation messages
* result/VC/* result/valid/*: this slightly change some of the
  regression tests outputs
Daniel
diff --git a/ChangeLog b/ChangeLog
index cd78bf0..0376c3f 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,12 @@
+Sat Aug  3 00:15:06 CEST 2002 Daniel Veillard <daniel@veillard.com>
+
+	* parser.c include/libxml/parser.h: adding a new API for Christian
+	  Glahn: xmlParseBalancedChunkMemoryRecover
+	* valid.c: patch from Rick Jones for some grammar cleanup in
+	  validation messages
+	* result/VC/* result/valid/*: this slightly change some of the
+	  regression tests outputs
+
 Thu Aug  1 14:50:28 CEST 2002 Daniel Veillard <daniel@veillard.com>
 
 	* tree.c: trying to fix a problem in namespaced attribute handling
diff --git a/include/libxml/parser.h b/include/libxml/parser.h
index cd48dc5..8f50096 100644
--- a/include/libxml/parser.h
+++ b/include/libxml/parser.h
@@ -767,6 +767,13 @@
 					 int depth,
 					 const xmlChar *string,
 					 xmlNodePtr *lst);
+int           xmlParseBalancedChunkMemoryRecover(xmlDocPtr doc,
+                     xmlSAXHandlerPtr sax,
+                     void *user_data,
+                     int depth,
+                     const xmlChar *string,
+                     xmlNodePtr *lst,
+                     int recover);
 int		xmlParseExternalEntity	(xmlDocPtr doc,
 					 xmlSAXHandlerPtr sax,
 					 void *user_data,
diff --git a/parser.c b/parser.c
index 38658f9..8a49b7b 100644
--- a/parser.c
+++ b/parser.c
@@ -9712,6 +9712,38 @@
 int
 xmlParseBalancedChunkMemory(xmlDocPtr doc, xmlSAXHandlerPtr sax,
      void *user_data, int depth, const xmlChar *string, xmlNodePtr *lst) {
+    return xmlParseBalancedChunkMemoryRecover( doc, sax, user_data,
+                                                depth, string, lst, 0 );
+}
+
+/**
+ * xmlParseBalancedChunkMemoryRecover:
+ * @doc:  the document the chunk pertains to
+ * @sax:  the SAX handler bloc (possibly NULL)
+ * @user_data:  The user data returned on SAX callbacks (possibly NULL)
+ * @depth:  Used for loop detection, use 0
+ * @string:  the input string in UTF8 or ISO-Latin (zero terminated)
+ * @lst:  the return value for the set of parsed nodes
+ * @recover: return nodes even if the data is broken (use 0)
+ *
+ *
+ * Parse a well-balanced chunk of an XML document
+ * called by the parser
+ * The allowed sequence for the Well Balanced Chunk is the one defined by
+ * the content production in the XML grammar:
+ *
+ * [43] content ::= (element | CharData | Reference | CDSect | PI | Comment)*
+ *
+ * Returns 0 if the chunk is well balanced, -1 in case of args problem and
+ *    the parser error code otherwise
+ *    
+ * In case recover is set to 1, the nodelist will not be empty even if
+ * the parsed chunk is not well balanced. 
+ */
+int
+xmlParseBalancedChunkMemoryRecover(xmlDocPtr doc, xmlSAXHandlerPtr sax,
+     void *user_data, int depth, const xmlChar *string, xmlNodePtr *lst, 
+     int recover) {
     xmlParserCtxtPtr ctxt;
     xmlDocPtr newDoc;
     xmlSAXHandlerPtr oldsax = NULL;
@@ -9806,8 +9838,11 @@
 	else
 	    ret = ctxt->errNo;
     } else {
-	if (lst != NULL) {
-	    xmlNodePtr cur;
+      ret = 0;
+    }
+    
+    if (lst != NULL && (ret == 0 || recover == 1)) {
+      xmlNodePtr cur;
 
 	    /*
 	     * Return the newly created nodeset after unlinking it from
@@ -9821,8 +9856,7 @@
 	    }
             newDoc->children->children = NULL;
 	}
-	ret = 0;
-    }
+	
     if (sax != NULL) 
 	ctxt->sax = oldsax;
     xmlFreeParserCtxt(ctxt);
diff --git a/result/VC/AttributeDefaultLegal b/result/VC/AttributeDefaultLegal
index 2bd897f..abba25f 100644
--- a/result/VC/AttributeDefaultLegal
+++ b/result/VC/AttributeDefaultLegal
@@ -1,12 +1,12 @@
-./test/VC/AttributeDefaultLegal:4: validity error: Attribute doc on At: invalid default value
+./test/VC/AttributeDefaultLegal:4: validity error: Attribute doc of At: invalid default value
 <!ATTLIST doc At NMTOKEN "$$$">
                               ^
-./test/VC/AttributeDefaultLegal:6: validity error: Attribute doc on bad: invalid default value
+./test/VC/AttributeDefaultLegal:6: validity error: Attribute doc of bad: invalid default value
 <!ATTLIST doc bad IDREF "1abc_2">
                                 ^
-./test/VC/AttributeDefaultLegal:8: validity error: Attribute doc on bad2: invalid default value
+./test/VC/AttributeDefaultLegal:8: validity error: Attribute doc of bad2: invalid default value
 <!ATTLIST doc bad2 IDREFS "abc:1 1abc_2">
                                         ^
-./test/VC/AttributeDefaultLegal:11: validity error: No declaration for attribute val on element doc
+./test/VC/AttributeDefaultLegal:11: validity error: No declaration for attribute val of element doc
 <doc val="v1"/>
              ^
diff --git a/result/VC/ElementValid5 b/result/VC/ElementValid5
index 1aecfb7..0d1cccf 100644
--- a/result/VC/ElementValid5
+++ b/result/VC/ElementValid5
@@ -1,4 +1,4 @@
-./test/VC/ElementValid5:7: validity error: Element doc content doesn't follow the DTD
+./test/VC/ElementValid5:7: validity error: Element doc content does not follow the DTD
 Expecting (a , b* , c+), got (a b c b)
 <doc><a/><b> but this</b><c>was not declared</c><b>seems</b></doc>
                                                                  ^
diff --git a/result/VC/ElementValid6 b/result/VC/ElementValid6
index bf63d47..21d0dfe 100644
--- a/result/VC/ElementValid6
+++ b/result/VC/ElementValid6
@@ -1,4 +1,4 @@
-./test/VC/ElementValid6:7: validity error: Element doc content doesn't follow the DTD
+./test/VC/ElementValid6:7: validity error: Element doc content does not follow the DTD
 Expecting (a , b? , c+)?, got (a b)
 <doc><a/><b>lacks c</b></doc>
                             ^
diff --git a/result/VC/ElementValid7 b/result/VC/ElementValid7
index de60754..2c9be77 100644
--- a/result/VC/ElementValid7
+++ b/result/VC/ElementValid7
@@ -1,4 +1,4 @@
-./test/VC/ElementValid7:7: validity error: Element doc content doesn't follow the DTD
+./test/VC/ElementValid7:7: validity error: Element doc content does not follow the DTD
 Expecting ((a | b)* , c+ , a , b? , c , a?), got (a b a c c a)
 <doc><a/><b/><a/><c/><c/><a/></doc>
                                   ^
diff --git a/result/VC/ElementValid8 b/result/VC/ElementValid8
index 7e88dfe..02072ab 100644
--- a/result/VC/ElementValid8
+++ b/result/VC/ElementValid8
@@ -1,3 +1,3 @@
-./test/VC/ElementValid8:7: validity warning: Element doc content model is ambiguous
+./test/VC/ElementValid8:7: validity warning: Content model for Element doc is ambiguous
 <doc><a/><c> doc is non-deterministic </c></doc>
                                                ^
diff --git a/result/VC/Enumeration b/result/VC/Enumeration
index 4663aca..a2582ad 100644
--- a/result/VC/Enumeration
+++ b/result/VC/Enumeration
@@ -1,3 +1,3 @@
-./test/VC/Enumeration:5: validity error: Value "v4" for attribute val on doc is not among the enumerated set
+./test/VC/Enumeration:5: validity error: Value "v4" for attribute val of doc is not among the enumerated set
 <doc val="v4"></doc>
              ^
diff --git a/result/VC/NS2 b/result/VC/NS2
index 5baa4dc..f039fb8 100644
--- a/result/VC/NS2
+++ b/result/VC/NS2
@@ -1,3 +1,3 @@
-./test/VC/NS2:9: validity error: No declaration for attribute attr on element doc
+./test/VC/NS2:9: validity error: No declaration for attribute attr of element doc
 <ns:doc ns:attr="val" xmlns:ns="http://www.example.org/test/">
                                                              ^
diff --git a/result/valid/rss.xml.err b/result/valid/rss.xml.err
index 98941d0..f76367d 100644
--- a/result/valid/rss.xml.err
+++ b/result/valid/rss.xml.err
@@ -1,3 +1,3 @@
-./test/valid/rss.xml:177: validity error: Element rss doesn't carry attribute version
+./test/valid/rss.xml:177: validity error: Element rss does not carry attribute version
 </rss>
      ^
diff --git a/result/valid/xlink.xml.err b/result/valid/xlink.xml.err
index 48c3b0c..27977f7 100644
--- a/result/valid/xlink.xml.err
+++ b/result/valid/xlink.xml.err
@@ -1,6 +1,6 @@
 ./test/valid/xlink.xml:450: validity error: ID dt-arc already defined
 	<p><termdef id="dt-arc" term="Arc">An <term>arc</term> is contained within an 
                                    ^
-./test/valid/xlink.xml:530: validity error: IDREF attribute def reference an unknown ID "dt-xlg"
+./test/valid/xlink.xml:530: validity error: IDREF attribute def references an unknown ID "dt-xlg"
 
 ^
diff --git a/valid.c b/valid.c
index 114ae5f..331f9fe 100644
--- a/valid.c
+++ b/valid.c
@@ -1299,7 +1299,7 @@
     }
     if ((defaultValue != NULL) && 
         (!xmlValidateAttributeValue(type, defaultValue))) {
-	VERROR(ctxt->userData, "Attribute %s on %s: invalid default value\n",
+	VERROR(ctxt->userData, "Attribute %s of %s: invalid default value\n",
 	       elem, name, defaultValue);
 	defaultValue = NULL;
 	ctxt->valid = 0;
@@ -1362,7 +1362,7 @@
 	 * The attribute is already defined in this DTD.
 	 */
 	VWARNING(ctxt->userData,
-		 "Attribute %s on %s: already defined\n",
+		 "Attribute %s of element %s: already defined\n",
 		 name, elem);
 	xmlFreeAttribute(ret);
 	return(NULL);
@@ -3203,7 +3203,7 @@
 	val = xmlValidateAttributeValue(attr->atype, attr->defaultValue);
 	if (val == 0) {
 	    VERROR(ctxt->userData, 
-	       "Syntax of default value for attribute %s on %s is not valid\n",
+	       "Syntax of default value for attribute %s of %s is not valid\n",
 	           attr->name, attr->elem);
 	}
         ret &= val;
@@ -3214,7 +3214,7 @@
         (attr->def != XML_ATTRIBUTE_IMPLIED) &&
 	(attr->def != XML_ATTRIBUTE_REQUIRED)) {
 	VERROR(ctxt->userData, 
-          "ID attribute %s on %s is not valid must be #IMPLIED or #REQUIRED\n",
+          "ID attribute %s of %s is not valid must be #IMPLIED or #REQUIRED\n",
 	       attr->name, attr->elem);
 	ret = 0;
     }
@@ -3271,7 +3271,7 @@
 	}
 	if (tree == NULL) {
 	    VERROR(ctxt->userData, 
-"Default value \"%s\" for attribute %s on %s is not among the enumerated set\n",
+"Default value \"%s\" for attribute %s of %s is not among the enumerated set\n",
 		   attr->defaultValue, attr->name, attr->elem);
 	    ret = 0;
 	}
@@ -3445,7 +3445,7 @@
     /* Validity Constraint: Attribute Value Type */
     if (attrDecl == NULL) {
 	VERROR(ctxt->userData,
-	       "No declaration for attribute %s on element %s\n",
+	       "No declaration for attribute %s of element %s\n",
 	       attr->name, elem->name);
 	return(0);
     }
@@ -3454,7 +3454,7 @@
     val = xmlValidateAttributeValue(attrDecl->atype, value);
     if (val == 0) {
 	VERROR(ctxt->userData, 
-	   "Syntax of value for attribute %s on %s is not valid\n",
+	   "Syntax of value for attribute %s of %s is not valid\n",
 	       attr->name, elem->name);
         ret = 0;
     }
@@ -3463,7 +3463,7 @@
     if (attrDecl->def == XML_ATTRIBUTE_FIXED) {
 	if (!xmlStrEqual(value, attrDecl->defaultValue)) {
 	    VERROR(ctxt->userData, 
-	   "Value for attribute %s on %s is different from default \"%s\"\n",
+	   "Value for attribute %s of %s is different from default \"%s\"\n",
 		   attr->name, elem->name, attrDecl->defaultValue);
 	    ret = 0;
 	}
@@ -3493,7 +3493,7 @@
 	
 	if (nota == NULL) {
 	    VERROR(ctxt->userData, 
-       "Value \"%s\" for attribute %s on %s is not a declared Notation\n",
+       "Value \"%s\" for attribute %s of %s is not a declared Notation\n",
 		   value, attr->name, elem->name);
 	    ret = 0;
         }
@@ -3505,7 +3505,7 @@
 	}
 	if (tree == NULL) {
 	    VERROR(ctxt->userData, 
-"Value \"%s\" for attribute %s on %s is not among the enumerated notations\n",
+"Value \"%s\" for attribute %s of %s is not among the enumerated notations\n",
 		   value, attr->name, elem->name);
 	    ret = 0;
 	}
@@ -3520,7 +3520,7 @@
 	}
 	if (tree == NULL) {
 	    VERROR(ctxt->userData, 
-       "Value \"%s\" for attribute %s on %s is not among the enumerated set\n",
+       "Value \"%s\" for attribute %s of %s is not among the enumerated set\n",
 		   value, attr->name, elem->name);
 	    ret = 0;
 	}
@@ -3530,7 +3530,7 @@
     if ((attrDecl->def == XML_ATTRIBUTE_FIXED) &&
         (!xmlStrEqual(attrDecl->defaultValue, value))) {
 	VERROR(ctxt->userData, 
-	   "Value for attribute %s on %s must be \"%s\"\n",
+	   "Value for attribute %s of %s must be \"%s\"\n",
 	       attr->name, elem->name, attrDecl->defaultValue);
         ret = 0;
     }
@@ -4082,7 +4082,7 @@
     ret = xmlValidateElementType(ctxt);
     if ((ret == -3) && (warn)) {
 	VWARNING(ctxt->userData,
-	   "Element %s content model is ambiguous\n", name);
+	   "Content model for Element %s is ambiguous\n", name);
     } else if (ret == -2) {
 	/*
 	 * An entities reference appeared at this level.
@@ -4185,21 +4185,21 @@
 
 	    if (name != NULL) {
 		VERROR(ctxt->userData,
-	   "Element %s content doesn't follow the DTD\nExpecting %s, got %s\n",
+	   "Element %s content does not follow the DTD\nExpecting %s, got %s\n",
 		       name, expr, list);
 	    } else {
 		VERROR(ctxt->userData,
-	   "Element content doesn't follow the DTD\nExpecting %s, got %s\n",
+	   "Element content does not follow the DTD\nExpecting %s, got %s\n",
 		       expr, list);
 	    }
 	} else {
 	    if (name != NULL) {
 		VERROR(ctxt->userData,
-		       "Element %s content doesn't follow the DTD\n",
+		       "Element %s content does not follow the DTD\n",
 		       name);
 	    } else {
 		VERROR(ctxt->userData,
-		       "Element content doesn't follow the DTD\n");
+		       "Element content does not follow the DTD\n");
 	    }
 	}
 	ret = 0;
@@ -4620,12 +4620,12 @@
 	    if (qualified == -1) {
 		if (attr->prefix == NULL) {
 		    VERROR(ctxt->userData,
-		       "Element %s doesn't carry attribute %s\n",
+		       "Element %s does not carry attribute %s\n",
 			   elem->name, attr->name);
 		    ret = 0;
 	        } else {
 		    VERROR(ctxt->userData,
-		       "Element %s doesn't carry attribute %s:%s\n",
+		       "Element %s does not carry attribute %s:%s\n",
 			   elem->name, attr->prefix,attr->name);
 		    ret = 0;
 		}
@@ -4669,7 +4669,7 @@
 		    if (xmlStrEqual(attr->name, ns->prefix)) {
 			if (!xmlStrEqual(attr->defaultValue, ns->href)) {
 			    VERROR(ctxt->userData,
-		   "Element %s namespace name for %s doesn't match the DTD\n",
+		   "Element %s namespace name for %s does not match the DTD\n",
 				   elem->name, ns->prefix);
 			    ret = 0;
 			}
@@ -4732,7 +4732,7 @@
 		(xmlStrEqual(root->name, BAD_CAST "html")))
 		goto name_ok;
 	    VERROR(ctxt->userData,
-		   "Not valid: root and DtD name do not match '%s' and '%s'\n",
+		   "Not valid: root and DTD name do not match '%s' and '%s'\n",
 		   root->name, doc->intSubset->name);
 	    return(0);
 	    
@@ -4820,7 +4820,7 @@
 	id = xmlGetID(ctxt->doc, name);
 	if (id == NULL) {
 	    VERROR(ctxt->userData, 
-	       "IDREF attribute %s reference an unknown ID \"%s\"\n",
+	       "IDREF attribute %s references an unknown ID \"%s\"\n",
 		   attr->name, name);
 	    ctxt->valid = 0;
 	}
@@ -4841,7 +4841,7 @@
 	    id = xmlGetID(ctxt->doc, str);
 	    if (id == NULL) {
 		VERROR(ctxt->userData, 
-	       "IDREFS attribute %s reference an unknown ID \"%s\"\n",
+	       "IDREFS attribute %s references an unknown ID \"%s\"\n",
 		       attr->name, str);
 		ctxt->valid = 0;
 	    }
@@ -5050,7 +5050,7 @@
 	}
 	if (elem->etype == XML_ELEMENT_TYPE_EMPTY) {
 	    VERROR(ctxt->userData, 
-		   "NOTATION attribute %s declared on EMPTY element %s\n",
+		   "NOTATION attribute %s declared for EMPTY element %s\n",
 		   cur->name, cur->elem);
 	    ctxt->valid = 0;
 	}
diff --git a/xinclude.c b/xinclude.c
index 7fbcaca..1e96fe9 100644
--- a/xinclude.c
+++ b/xinclude.c
@@ -32,6 +32,7 @@
 
 #define XINCLUDE_NS (const xmlChar *) "http://www.w3.org/2001/XInclude"
 #define XINCLUDE_NODE (const xmlChar *) "include"
+#define XINCLUDE_FALLBACK (const xmlChar *) "fallback"
 #define XINCLUDE_HREF (const xmlChar *) "href"
 #define XINCLUDE_PARSE (const xmlChar *) "parse"
 #define XINCLUDE_PARSE_XML (const xmlChar *) "xml"