Integrated xmlRegExecErrInfo and xmlRegExecNextValues from xmlregexp.c to

* xmlschemas.c: Integrated xmlRegExecErrInfo and xmlRegExecNextValues
  from xmlregexp.c to report expected elements on content model errors.
* all_*.err any3_0_0.err choice_*.err list0_0_1.err list0_1_1.err:
  Adapted output of regression tests.
diff --git a/xmlschemas.c b/xmlschemas.c
index ef29999..9c9fcaf 100644
--- a/xmlschemas.c
+++ b/xmlschemas.c
@@ -1078,14 +1078,125 @@
 	msg = xmlStrcat(msg, xmlSchemaFormatItemForReport(&str, NULL, type, NULL, 0));
 	msg = xmlStrcat(msg, BAD_CAST "]");
     }
-    msg = xmlStrcat(msg, BAD_CAST ": %s.\n");
-    xmlSchemaVErr(ctxt, node, error, (const char *) msg, 
+    msg = xmlStrcat(msg, BAD_CAST ": %s.\n");   
+    xmlSchemaVErr(ctxt, node, error, (const char *) msg,
 	(const xmlChar *) message, NULL);
     FREE_AND_NULL(str)	
     xmlFree(msg);
 }
 
 /**
+ * xmlSchemaVComplexTypeElemErr:
+ * @ctxt:  the schema validation context
+ * @error: the error code
+ * @node: the node containing the validated value
+ * @type: the complex type used for validation
+ * @message: the error message
+ *
+ * Reports a complex type validation error.
+ */
+static void
+xmlSchemaVComplexTypeElemErr(xmlSchemaValidCtxtPtr ctxt, 
+			xmlParserErrors error,
+			xmlNodePtr node,
+			xmlSchemaTypePtr type,			
+			const char *message,
+			int nbval,
+			int nbneg,
+			xmlChar **values)
+{
+    xmlChar *str = NULL, *msg = NULL;
+    xmlChar *localName, *nsName;
+    const xmlChar *cur, *end;
+    int i;
+    
+    xmlSchemaFormatItemForReport(&msg, NULL,  NULL, node, 0);
+    /* Specify the complex type only if it is global. */
+    if ((type != NULL) && (type->flags & XML_SCHEMAS_TYPE_GLOBAL)) {
+	msg = xmlStrcat(msg, BAD_CAST " [");
+	msg = xmlStrcat(msg, xmlSchemaFormatItemForReport(&str, NULL, type, NULL, 0));
+	msg = xmlStrcat(msg, BAD_CAST "]");
+	FREE_AND_NULL(str)
+    }
+    msg = xmlStrcat(msg, BAD_CAST ": ");
+    msg = xmlStrcat(msg, (const xmlChar *) message);
+    /*
+    * Note that is does not make sense to report that we have a
+    * wildcard here, since the wildcard might be unfolded into
+    * multiple transitions.
+    */
+    if (nbval + nbneg > 0) {
+	if (nbval + nbneg > 1) {
+	    str = xmlStrdup(BAD_CAST ". Expected is one of ");
+	} else
+	    str = xmlStrdup(BAD_CAST ". Expected is ");
+	nsName = NULL;
+    	    
+	for (i = 0; i < nbval + nbneg; i++) {
+	    cur = values[i];
+	    /*
+	    * Get the local name.
+	    */
+	    localName = NULL;
+	    
+	    end = cur;
+	    if (*end == '*') {
+		localName = xmlStrdup(BAD_CAST "*");
+		*end++;
+	    } else {
+		while ((*end != 0) && (*end != '|'))
+		    end++;
+		localName = xmlStrcat(localName, BAD_CAST "'");
+		localName = xmlStrncat(localName, BAD_CAST cur, end - cur);
+		localName = xmlStrcat(localName, BAD_CAST "'");
+	    }		
+	    if (*end != 0) {		    
+		*end++;
+		/*
+		* Skip "*|*" if they come with negated expressions, since
+		* they represent the same negated wildcard.
+		*/
+		if ((nbneg == 0) || (*end != '*') || (*localName != '*')) {
+		    /*
+		    * Get the namespace name.
+		    */
+		    cur = end;
+		    if (*end == '*') {
+			nsName = xmlStrdup(BAD_CAST "{*}");
+		    } else {
+			while (*end != 0)
+			    end++;
+			
+			if (i >= nbval)
+			    nsName = xmlStrdup(BAD_CAST "{##other:");
+			else
+			    nsName = xmlStrdup(BAD_CAST "{");
+			
+			nsName = xmlStrncat(nsName, BAD_CAST cur, end - cur);
+			nsName = xmlStrcat(nsName, BAD_CAST "}");
+		    }
+		    str = xmlStrcat(str, BAD_CAST nsName);
+		    FREE_AND_NULL(nsName)
+		} else {
+		    FREE_AND_NULL(localName);
+		    continue;
+		}
+	    }	        
+	    str = xmlStrcat(str, BAD_CAST localName);
+	    FREE_AND_NULL(localName);
+		
+	    if (i < nbval + nbneg -1)
+		str = xmlStrcat(str, BAD_CAST ", ");
+	}	    
+	msg = xmlStrcat(msg, BAD_CAST str);
+	FREE_AND_NULL(str)
+    }    
+    msg = xmlStrcat(msg, BAD_CAST ".\n");
+    xmlSchemaVErr(ctxt, node, error, (const char *) msg, NULL, NULL);    	
+    xmlFree(msg);
+}
+
+/**
  * xmlSchemaPMissingAttrErr:
  * @ctxt: the schema validation context
  * @ownerDes: the designation of  the owner
@@ -8552,7 +8663,7 @@
                         oldstate = ctxt->state;
                         counter = xmlAutomataNewCounter(ctxt->am,
 			    particle->minOccurs - 1, UNBOUNDED);                      
-                        ctxt->state =                            
+                        ctxt->state =
 			    xmlAutomataNewTransition2(ctxt->am,
 				ctxt->state, NULL, 
 				elemDecl->name, 
@@ -14710,8 +14821,6 @@
 	* in the ·lexical space· of {item type definition} 
 	*/
 	
-	if (value == NULL)
-	    value = BAD_CAST "";
 	tmpType = xmlSchemaGetListSimpleTypeItemType(type);	
 	cur = value;
 	do {
@@ -15849,6 +15958,8 @@
         case XML_SCHEMA_CONTENT_ELEMENTS:
         {
 	    xmlRegExecCtxtPtr oldregexp = NULL;
+	    xmlChar *values[10];
+	    int terminal, nbval = 10, nbneg;
 	    
 	    /*
 	    * Content model check initialization.
@@ -15877,8 +15988,10 @@
 		    /*
 		    * URGENT TODO: Could we anchor an error report
 		    * here to notify of invalid elements?
+		    * TODO: Perhaps it would be better to report 
+		    * only the first erroneous element and then break.
 		    */
-#ifdef DEBUG_AUTOMATA		    
+#ifdef DEBUG_AUTOMATA
 		    if (ret < 0)
 			xmlGenericError(xmlGenericErrorContext,
 			"  --> %s Error\n", child->name);
@@ -15887,11 +16000,19 @@
 			"  --> %s\n", child->name);
 #endif
 		    if (ret < 0) {
-			xmlSchemaVComplexTypeErr(ctxt, 
+			xmlRegExecErrInfo(ctxt->regexp, NULL, &nbval, &nbneg,
+			    &values[0], &terminal);
+			xmlSchemaVComplexTypeElemErr(ctxt, 
 			    XML_SCHEMAV_ELEMENT_CONTENT,
 			    child, NULL/* type */, 
-			    "This element is not expected");
+			    "This element is not expected",
+			    nbval, nbneg, values);
 			ret = 1;
+			/*
+			* Note that this will skip further validation of the
+			* content.
+			*/
+			break;
 		    }
 		} else if ((type->contentType == XML_SCHEMA_CONTENT_ELEMENTS) && 
 		    /* 
@@ -15922,29 +16043,36 @@
 	    * Content model check finalization.
 	    */
        	    if (type->contModel != NULL) {
-		if (ret != 1) {
-		    ret = xmlRegExecPushString(ctxt->regexp, NULL, NULL);
+		if (ret == 0) {
+		    xmlRegExecNextValues(ctxt->regexp, &nbval, &nbneg,
+			&values[0], &terminal);
+		    if (nbval + nbneg != 0) {
+			/*
+			* If a next value still exists, I does not have to
+			* mean that there's an element missing, since it
+			* might be an optional element. So double check it.
+			*/
+			ret = xmlRegExecPushString(ctxt->regexp,
+			    NULL, NULL);
+			if (ret <= 0) {
+			    ret = 1;
+    			    xmlSchemaVComplexTypeElemErr(ctxt,
+				XML_SCHEMAV_ELEMENT_CONTENT,
+				elem, type, "Missing child element(s)",
+				nbval, nbneg, values);			    
+			} else
+			    ret = 0;			
 #ifdef DEBUG_AUTOMATA
-		    xmlGenericError(xmlGenericErrorContext,
-			"====> %s : %d\n", elem->name, ret);
+			xmlGenericError(xmlGenericErrorContext,
+			    "====> %s : %d\n", elem->name, ret);
 #endif
-		    if (ret == 0) {
-			/* TODO: Hmm, can this one really happen? */
-			xmlSchemaVComplexTypeErr(ctxt, 
-			    XML_SCHEMAV_ELEMENT_CONTENT,
-			    elem, type, "Missing child element(s)");
-		    } else if (ret < 0) {
-			xmlSchemaVComplexTypeErr(ctxt, 
-			    XML_SCHEMAV_ELEMENT_CONTENT,
-			    elem, type, "Missing child element(s)");
+		    }		    
 #ifdef DEBUG_CONTENT
-		    } else {
+		    if (ret == 0)
 			xmlGenericError(xmlGenericErrorContext,
 			    "Element %s content check succeeded\n",
 			    elem->name);
-			
 #endif
-		    }
 		}
 		xmlRegFreeExecCtxt(ctxt->regexp);
 		ctxt->regexp = oldregexp;
@@ -16071,8 +16199,8 @@
 		}
 	    }
 	    if (value != NULL)
-		xmlFree(value);    
-	    
+		xmlFree(value);
+
 	}
 	    break;
         default: