commiting some work done while in the Maldives (hence the timezone on the

* relaxng.c xmlschemas.c include/libxml/schemasInternals.h: commiting
  some work done while in the Maldives (hence the timezone on the
  laptop !)
* result/schemas/length3* test/schemas/deter0_*
  test/schemas/group0_*: some tests added too
Daniel
diff --git a/ChangeLog b/ChangeLog
index b2a56ab..c9eea99 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,11 @@
+Mon Jun  2 21:56:15 MVT 2003 Daniel Veillard <daniel@veillard.com>
+
+	* relaxng.c xmlschemas.c include/libxml/schemasInternals.h: commiting
+	  some work done while in the Maldives (hence the timezone on the
+	  laptop !)
+	* result/schemas/length3* test/schemas/deter0_*
+	  test/schemas/group0_*: some tests added too
+
 Mon Jun  2 15:34:17 CEST 2003 Daniel Veillard <daniel@veillard.com>
 
 	* encoding.c: small fix
diff --git a/include/libxml/schemasInternals.h b/include/libxml/schemasInternals.h
index 54e8fb3..3cf3ff6 100644
--- a/include/libxml/schemasInternals.h
+++ b/include/libxml/schemasInternals.h
@@ -342,6 +342,7 @@
     xmlHashTablePtr schemasImports;
 
     void *_private;	/* unused by the library for users or bindings */
+    xmlHashTablePtr groupDecl;
 };
 
 void	xmlSchemaFreeType	(xmlSchemaTypePtr type);
diff --git a/relaxng.c b/relaxng.c
index 99ff9e9..c17b344 100644
--- a/relaxng.c
+++ b/relaxng.c
@@ -2659,9 +2659,9 @@
  */
 void	
 xmlRelaxNGCleanupTypes(void) {
+    xmlSchemaCleanupTypes();
     if (xmlRelaxNGTypeInitialized == 0)
 	return;
-    xmlSchemaCleanupTypes();
     xmlHashFree(xmlRelaxNGRegisteredTypes, (xmlHashDeallocator)
 	        xmlRelaxNGFreeTypeLibrary);
     xmlRelaxNGTypeInitialized = 0;
diff --git a/result/schemas/length3_0_0 b/result/schemas/length3_0_0
index 6ea7515..e69de29 100644
--- a/result/schemas/length3_0_0
+++ b/result/schemas/length3_0_0
@@ -1 +0,0 @@
-./test/schemas/length3_0.xml validates
diff --git a/result/schemas/length3_0_0.err b/result/schemas/length3_0_0.err
index fa7cd52..d7d8041 100644
--- a/result/schemas/length3_0_0.err
+++ b/result/schemas/length3_0_0.err
@@ -1 +1,2 @@
+compilation error
 Schemas: element size type non-positive-integer not found
diff --git a/test/schemas/deter0_0.xml b/test/schemas/deter0_0.xml
new file mode 100644
index 0000000..0ea1a41
--- /dev/null
+++ b/test/schemas/deter0_0.xml
@@ -0,0 +1,5 @@
+<book>
+  <odd-page>first page</odd-page>
+  <even-page>second page</even-page>
+  <odd-page>third page</odd-page>
+</book>
diff --git a/test/schemas/deter0_0.xsd b/test/schemas/deter0_0.xsd
new file mode 100644
index 0000000..8b5da69
--- /dev/null
+++ b/test/schemas/deter0_0.xsd
@@ -0,0 +1,16 @@
+<?xml version="1.0" encoding="utf-8"?>
+<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
+  <xs:element name="odd-page" type="xs:string"/>
+  <xs:element name="even-page" type="xs:string"/>
+  <xs:element name="book">
+    <xs:complexType>
+      <xs:sequence>
+        <xs:sequence minOccurs="0" maxOccurs="unbounded">
+          <xs:element ref="odd-page"/>
+          <xs:element ref="even-page"/>
+        </xs:sequence>
+        <xs:element ref="odd-page" minOccurs="0"/>
+      </xs:sequence>
+    </xs:complexType>
+  </xs:element>
+</xs:schema>
diff --git a/test/schemas/group0_0.xml b/test/schemas/group0_0.xml
new file mode 100644
index 0000000..bf58ba6
--- /dev/null
+++ b/test/schemas/group0_0.xml
@@ -0,0 +1,3 @@
+<author>
+  <name>Foo Bar</name>
+</author>
diff --git a/test/schemas/group0_0.xsd b/test/schemas/group0_0.xsd
new file mode 100644
index 0000000..7dfa393
--- /dev/null
+++ b/test/schemas/group0_0.xsd
@@ -0,0 +1,18 @@
+<?xml version="1.0" encoding="utf-8"?>
+<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
+  <xs:group name="name">
+    <xs:choice>
+      <xs:element name="name" type="xs:string"/>
+      <xs:sequence>
+        <xs:element name="first-name" type="xs:string"/>
+        <xs:element name="middle-name" type="xs:string" minOccurs="0"/>
+        <xs:element name="last-name" type="xs:string"/>
+      </xs:sequence>
+    </xs:choice>
+  </xs:group>
+  <xs:element name="author">
+    <xs:complexType>
+      <xs:group ref="name"/>
+    </xs:complexType>
+  </xs:element>
+</xs:schema>
diff --git a/xmlschemas.c b/xmlschemas.c
index f2049af..fa623a8 100644
--- a/xmlschemas.c
+++ b/xmlschemas.c
@@ -25,7 +25,7 @@
 #include <libxml/xmlautomata.h>
 #include <libxml/xmlregexp.h>
 
-/* #define DEBUG 1       */         /* very verbose output */
+/* #define DEBUG 1 */
 /* #define DEBUG_CONTENT 1 */
 /* #define DEBUG_TYPE 1 */
 /* #define DEBUG_CONTENT_REGEXP 1 */
@@ -406,6 +406,9 @@
     if (schema->typeDecl != NULL)
         xmlHashFree(schema->typeDecl,
                     (xmlHashDeallocator) xmlSchemaFreeType);
+    if (schema->groupDecl != NULL)
+        xmlHashFree(schema->groupDecl,
+                    (xmlHashDeallocator) xmlSchemaFreeType);
     if (schema->annot != NULL)
 	xmlSchemaFreeAnnot(schema->annot);
     if (schema->doc != NULL)
@@ -436,6 +439,7 @@
     int line = 0;
     const xmlChar *file = NULL;
     const xmlChar *name = NULL;
+    const xmlChar *prefix = NULL;
     const char *type = "error";
 
     if ((ctxt == NULL) || (ctxt->error == NULL))
@@ -467,6 +471,9 @@
 		file = node->doc->URL;
 	    if (node->name != NULL)
 		name = node->name;
+	    if ((node->type == XML_ELEMENT_NODE) && (node->ns != NULL) &&
+	        (node->ns->prefix != NULL))
+		prefix = node->ns->prefix;
 	}
     } 
     
@@ -475,9 +482,15 @@
     else if (schema != NULL)
 	type = "runtime error";
 
-    if ((file != NULL) && (line != 0) && (name != NULL))
+    if ((file != NULL) && (line != 0) && (name != NULL) && (prefix != NULL))
+	ctxt->error(ctxt->userData, "%s: file %s line %d element %s:%s\n",
+		type, file, line, prefix, name);
+    else if ((file != NULL) && (line != 0) && (name != NULL))
 	ctxt->error(ctxt->userData, "%s: file %s line %d element %s\n",
 		type, file, line, name);
+    else if ((file != NULL) && (name != NULL) && (prefix != NULL))
+	ctxt->error(ctxt->userData, "%s: file %s element %s:%s\n",
+		type, file, prefix, name);
     else if ((file != NULL) && (name != NULL))
 	ctxt->error(ctxt->userData, "%s: file %s element %s\n",
 		type, file, name);
@@ -485,6 +498,8 @@
 	ctxt->error(ctxt->userData, "%s: file %s line %d\n", type, file, line);
     else if (file != NULL)
 	ctxt->error(ctxt->userData, "%s: file %s\n", type, file);
+    else if ((name != NULL) && (prefix != NULL))
+	ctxt->error(ctxt->userData, "%s: element %s:%s\n", type, prefix, name);
     else if (name != NULL)
 	ctxt->error(ctxt->userData, "%s: element %s\n", type, name);
     else
@@ -741,7 +756,7 @@
  *
  * Lookup a type in the schemas or the predefined types
  *
- * Returns 1 if the string is NULL or made of blanks chars, 0 otherwise
+ * Returns the group definition or NULL if not found.
  */
 static xmlSchemaTypePtr
 xmlSchemaGetType(xmlSchemaPtr schema, const xmlChar * name,
@@ -835,7 +850,7 @@
     if (val != 0) {
         ctxt->nberrors++;
         if ((ctxt != NULL) && (ctxt->error != NULL))
-            ctxt->error(ctxt->userData, "Could not add notation %s\n",
+            ctxt->error(ctxt->userData, "Notation %s already defined\n",
                         name);
         xmlFree((char *) ret->name);
         xmlFree(ret);
@@ -886,7 +901,7 @@
     if (val != 0) {
         ctxt->nberrors++;
         if ((ctxt != NULL) && (ctxt->error != NULL))
-            ctxt->error(ctxt->userData, "Could not add attribute %s\n",
+            ctxt->error(ctxt->userData, "Attribute %s already defined\n",
                         name);
         xmlFree((char *) ret->name);
         xmlFree(ret);
@@ -934,7 +949,7 @@
     if (val != 0) {
         ctxt->nberrors++;
         if ((ctxt != NULL) && (ctxt->error != NULL))
-            ctxt->error(ctxt->userData, "Could not add attribute group %s\n",
+            ctxt->error(ctxt->userData, "Attribute group %s already defined\n",
                         name);
         xmlFree((char *) ret->name);
         xmlFree(ret);
@@ -990,7 +1005,7 @@
 	if (val != 0) {
 	    ctxt->nberrors++;
 	    if ((ctxt != NULL) && (ctxt->error != NULL))
-		ctxt->error(ctxt->userData, "Could not add element %s\n",
+		ctxt->error(ctxt->userData, "Element %s already defined\n",
 			    name);
 	    xmlFree((char *) ret->name);
 	    xmlFree(ret);
@@ -1040,7 +1055,57 @@
     if (val != 0) {
         ctxt->nberrors++;
         if ((ctxt != NULL) && (ctxt->error != NULL))
-            ctxt->error(ctxt->userData, "Could not add type %s\n", name);
+            ctxt->error(ctxt->userData, "Type %s already defined\n", name);
+        xmlFree((char *) ret->name);
+        xmlFree(ret);
+        return (NULL);
+    }
+    ret->minOccurs = 1;
+    ret->maxOccurs = 1;
+
+    return (ret);
+}
+
+/**
+ * xmlSchemaAddGroup:
+ * @ctxt:  a schema validation context
+ * @schema:  the schema being built
+ * @name:  the group name
+ *
+ * Add an XML schema Group definition
+ *
+ * Returns the new struture or NULL in case of error
+ */
+static xmlSchemaTypePtr
+xmlSchemaAddGroup(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
+                 const xmlChar * name)
+{
+    xmlSchemaTypePtr ret = NULL;
+    int val;
+
+    if ((ctxt == NULL) || (schema == NULL) || (name == NULL))
+        return (NULL);
+
+    if (schema->groupDecl == NULL)
+        schema->groupDecl = xmlHashCreate(10);
+    if (schema->groupDecl == NULL)
+        return (NULL);
+
+    ret = (xmlSchemaTypePtr) xmlMalloc(sizeof(xmlSchemaType));
+    if (ret == NULL) {
+        ctxt->nberrors++;
+        if ((ctxt != NULL) && (ctxt->error != NULL))
+            ctxt->error(ctxt->userData, "Out of memory\n");
+        return (NULL);
+    }
+    memset(ret, 0, sizeof(xmlSchemaType));
+    ret->name = xmlStrdup(name);
+    val = xmlHashAddEntry2(schema->groupDecl, name, schema->targetNamespace,
+                           ret);
+    if (val != 0) {
+        ctxt->nberrors++;
+        if ((ctxt != NULL) && (ctxt->error != NULL))
+            ctxt->error(ctxt->userData, "Group %s already defined\n", name);
         xmlFree((char *) ret->name);
         xmlFree(ret);
         return (NULL);
@@ -1808,6 +1873,7 @@
                                 schema->targetNamespace);
     else
         ret = xmlSchemaAddElement(ctxt, schema, name, namespace);
+    ret->node = node;
     if (namespace != NULL)
         xmlFree(namespace);
     if (ret == NULL) {
@@ -2118,7 +2184,7 @@
 	snprintf(buf, 99, "anongroup%d", ctxt->counter++ + 1);
 	name = xmlStrdup((xmlChar *) buf);
     }
-    type = xmlSchemaAddType(ctxt, schema, name);
+    type = xmlSchemaAddGroup(ctxt, schema, name);
     if (type == NULL)
         return (NULL);
     type->node = node;
@@ -3456,6 +3522,8 @@
 		xmlSchemaBuildAContentModel(type->subtypes, ctxt, name);
 	    break;
 	case XML_SCHEMA_TYPE_GROUP:
+	    if (type->subtypes == NULL) {
+	    }
 	case XML_SCHEMA_TYPE_COMPLEX:
 	case XML_SCHEMA_TYPE_COMPLEX_CONTENT:
 	    if (type->subtypes != NULL)
@@ -3470,10 +3538,11 @@
 }
 /**
  * xmlSchemaBuildContentModel:
- * @typeDecl:  the schema type definition
+ * @elem:  the element
  * @ctxt:  the schema parser context
+ * @name:  the element name
  *
- * Fixes the content model of the element.
+ * Builds the content model of the element.
  */
 static void
 xmlSchemaBuildContentModel(xmlSchemaElementPtr elem,
@@ -3507,19 +3576,29 @@
     xmlSchemaBuildAContentModel(elem->subtypes, ctxt, name);
     xmlAutomataSetFinalState(ctxt->am, ctxt->state);
     elem->contModel = xmlAutomataCompile(ctxt->am);
-    if (!xmlAutomataIsDeterminist(ctxt->am)) {
-	xmlGenericError(xmlGenericErrorContext,
+    if (elem->contModel == NULL) {
+	xmlSchemaErrorContext(ctxt, NULL, elem->node, NULL);
+	if ((ctxt != NULL) && (ctxt->error != NULL))
+	    ctxt->error(ctxt->userData,
+			"failed to compile %s content model\n",
+			name);
+	ctxt->err = XML_SCHEMAS_ERR_INTERNAL;
+	ctxt->nberrors++;
+    } else if (xmlRegexpIsDeterminist(elem->contModel) != 1) {
+	xmlSchemaErrorContext(ctxt, NULL, elem->node, NULL);
+	if ((ctxt != NULL) && (ctxt->error != NULL))
+	    ctxt->error(ctxt->userData,
 			"Content model of %s is not determinist:\n", name);
 	ctxt->err = XML_SCHEMAS_ERR_NOTDETERMINIST;
-	ctxt->state = NULL;
+	ctxt->nberrors++;
     } else {
 #ifdef DEBUG_CONTENT_REGEXP
 	xmlGenericError(xmlGenericErrorContext,
 			"Content model of %s:\n", name);
 	xmlRegexpPrint(stderr, elem->contModel);
 #endif
-	ctxt->state = NULL;
     }
+    ctxt->state = NULL;
     xmlFreeAutomata(ctxt->am);
     ctxt->am = NULL;
 }