more work on Relax-NG augmented/updated the regression tests added a

* relaxng.c: more work on Relax-NG
* test/relaxng/* result/relaxng/*: augmented/updated the
  regression tests
* xmlschemastypes.c: added a number of base type definition but not
  the associated checks, those are still TODOs
Daniel
diff --git a/relaxng.c b/relaxng.c
index a104d8e..f5ac07d 100644
--- a/relaxng.c
+++ b/relaxng.c
@@ -24,6 +24,7 @@
 #include <libxml/xmlschemastypes.h>
 #include <libxml/xmlautomata.h>
 #include <libxml/xmlregexp.h>
+#include <libxml/xmlschemastypes.h>
 
 /*
  * The Relax-NG namespace
@@ -168,10 +169,11 @@
 typedef struct _xmlRelaxNGValidState xmlRelaxNGValidState;
 typedef xmlRelaxNGValidState *xmlRelaxNGValidStatePtr;
 struct _xmlRelaxNGValidState {
-    xmlNodePtr node;		/* the current node */
-    xmlNodePtr  seq;		/* the sequence of children left to validate */
-    int     nbAttrs;		/* the number of attributes */
-    xmlChar  *value;		/* the value when operating on string */
+    xmlNodePtr   node;		/* the current node */
+    xmlNodePtr    seq;		/* the sequence of children left to validate */
+    int       nbAttrs;		/* the number of attributes */
+    xmlChar    *value;		/* the value when operating on string */
+    xmlChar *endvalue;		/* the end value when operating on string */
     xmlAttrPtr attrs[1];	/* the array of attributes */
 };
 
@@ -668,8 +670,15 @@
  */
 static int
 xmlRelaxNGSchemaTypeHave(void *data ATTRIBUTE_UNUSED,
-	                 const xmlChar *type ATTRIBUTE_UNUSED) {
-    TODO
+	                 const xmlChar *type) {
+    xmlSchemaTypePtr typ;
+
+    if (type == NULL)
+	return(-1);
+    typ = xmlSchemaGetPredefinedType(type, 
+	       BAD_CAST "http://www.w3.org/2001/XMLSchema");
+    if (typ == NULL)
+	return(0);
     return(1);
 }
 
@@ -686,10 +695,29 @@
  */
 static int
 xmlRelaxNGSchemaTypeCheck(void *data ATTRIBUTE_UNUSED,
-	                  const xmlChar *type ATTRIBUTE_UNUSED,
-			  const xmlChar *value ATTRIBUTE_UNUSED) {
-    TODO
-    return(1);
+	                  const xmlChar *type,
+			  const xmlChar *value) {
+    xmlSchemaTypePtr typ;
+    int ret;
+
+    /*
+     * TODO: the type should be cached ab provided back, interface subject
+     * to changes.
+     * TODO: handle facets, may require an additional interface and keep
+     * the value returned from the validation.
+     */
+    if ((type == NULL) || (value == NULL))
+	return(-1);
+    typ = xmlSchemaGetPredefinedType(type, 
+	       BAD_CAST "http://www.w3.org/2001/XMLSchema");
+    if (typ == NULL)
+	return(-1);
+    ret = xmlSchemaValidatePredefinedType(typ, value, NULL);
+    if (ret == 0)
+	return(1);
+    if (ret > 0)
+	return(0);
+    return(-1);
 }
 
 /**
@@ -1260,7 +1288,7 @@
 	def = xmlRelaxNGNewDefine(ctxt, node);
 	if (def == NULL)
 	    return(NULL);
-	def->type = XML_RELAXNG_ZEROORMORE;
+	def->type = XML_RELAXNG_ONEORMORE;
 	def->content = xmlRelaxNGParsePatterns(ctxt, node->children);
     } else if (IS_RELAXNG(node, "optional")) {
 	def = xmlRelaxNGNewDefine(ctxt, node);
@@ -1346,6 +1374,12 @@
 	def = NULL;
     } else if (IS_RELAXNG(node, "value")) {
 	def = xmlRelaxNGParseValue(ctxt, node);
+    } else if (IS_RELAXNG(node, "list")) {
+	def = xmlRelaxNGNewDefine(ctxt, node);
+	if (def == NULL)
+	    return(NULL);
+	def->type = XML_RELAXNG_LIST;
+	def->content = xmlRelaxNGParsePatterns(ctxt, node->children);
     } else {
 	TODO
     }
@@ -2632,6 +2666,8 @@
  ************************************************************************/
 static int xmlRelaxNGValidateDefinition(xmlRelaxNGValidCtxtPtr ctxt, 
 	                                xmlRelaxNGDefinePtr define);
+static int xmlRelaxNGValidateValue(xmlRelaxNGValidCtxtPtr ctxt, 
+	                           xmlRelaxNGDefinePtr define);
 
 /**
  * xmlRelaxNGSkipIgnored:
@@ -2745,6 +2781,55 @@
 }
 
 /**
+ * xmlRelaxNGNextValue:
+ * @ctxt:  a Relax-NG validation context
+ *
+ * Skip to the next value when validating within a list
+ *
+ * Returns 0 if the operation succeeded or an error code.
+ */
+static int
+xmlRelaxNGNextValue(xmlRelaxNGValidCtxtPtr ctxt) {
+    xmlChar *cur;
+
+    cur = ctxt->state->value;
+    if ((cur == NULL) || (ctxt->state->endvalue == NULL)) {
+	ctxt->state->value = NULL;
+	return(0);
+    }
+    while (*cur != 0) cur++;
+    while ((cur != ctxt->state->endvalue) && (*cur == 0)) cur++;
+    if (cur == ctxt->state->endvalue)
+	ctxt->state->value = NULL;
+    else
+	ctxt->state->value = cur;
+    return(0);
+}
+
+/**
+ * xmlRelaxNGValidateValueList:
+ * @ctxt:  a Relax-NG validation context
+ * @defines:  the list of definitions to verify
+ *
+ * Validate the given set of definitions for the current value
+ *
+ * Returns 0 if the validation succeeded or an error code.
+ */
+static int
+xmlRelaxNGValidateValueList(xmlRelaxNGValidCtxtPtr ctxt, 
+	                xmlRelaxNGDefinePtr defines) {
+    int ret = 0;
+
+    while (defines != NULL) {
+	ret = xmlRelaxNGValidateValue(ctxt, defines);
+	if (ret != 0)
+	    break;
+	defines = defines->next;
+    }
+    return(ret);
+}
+
+/**
  * xmlRelaxNGValidateValue:
  * @ctxt:  a Relax-NG validation context
  * @define:  the definition to verify
@@ -2767,22 +2852,6 @@
 	    break;
 	case XML_RELAXNG_TEXT:
 	    break;
-	case XML_RELAXNG_CHOICE: {
-	    xmlRelaxNGDefinePtr list = define->content;
-
-	    oldflags = ctxt->flags;
-	    ctxt->flags |= FLAGS_IGNORABLE;
-
-	    while (list != NULL) {
-		ret = xmlRelaxNGValidateValue(ctxt, list);
-		if (ret == 0) {
-		    break;
-		}
-		list = list->next;
-	    }
-	    ctxt->flags = oldflags;
-	    break;
-	}
 	case XML_RELAXNG_VALUE: {
 	    if (!xmlStrEqual(value, define->value)) {
 		if (define->name != NULL) {
@@ -2825,6 +2894,102 @@
 	    }
 	    break;
 	}
+	case XML_RELAXNG_DATATYPE: {
+	    ret = xmlRelaxNGValidateDatatype(ctxt, value, define);
+	    if (ret == 0)
+		xmlRelaxNGNextValue(ctxt);
+	    
+	    break;
+	}
+	case XML_RELAXNG_CHOICE: {
+	    xmlRelaxNGDefinePtr list = define->content;
+	    xmlChar *oldvalue;
+
+	    oldflags = ctxt->flags;
+	    ctxt->flags |= FLAGS_IGNORABLE;
+
+	    oldvalue = ctxt->state->value;
+	    while (list != NULL) {
+		ret = xmlRelaxNGValidateValue(ctxt, list);
+		if (ret == 0) {
+		    break;
+		}
+		ctxt->state->value = oldvalue;
+		list = list->next;
+	    }
+	    ctxt->flags = oldflags;
+	    break;
+	}
+	case XML_RELAXNG_LIST: {
+	    xmlRelaxNGDefinePtr list = define->content;
+	    xmlChar *oldvalue, *oldend, *val, *cur;
+
+	    oldvalue = ctxt->state->value;
+	    oldend = ctxt->state->endvalue;
+
+	    val = xmlStrdup(oldvalue);
+	    if (val == NULL) {
+		VALID_CTXT();
+		VALID_ERROR("Internal: no state\n");
+		return(-1);
+	    }
+	    cur = val;
+	    while (*cur != 0) {
+		if (IS_BLANK(*cur))
+		    *cur = 0;
+		cur++;
+	    }
+	    ctxt->state->endvalue = cur;
+	    cur = val;
+	    while ((*cur == 0) && (cur != ctxt->state->endvalue)) cur++;
+
+	    ctxt->state->value = cur;
+
+	    while (list != NULL) {
+		ret = xmlRelaxNGValidateValue(ctxt, list);
+		if (ret != 0) {
+		    break;
+		}
+		list = list->next;
+	    }
+	    if ((ret == 0) && (ctxt->state->value != NULL) &&
+		(ctxt->state->value != ctxt->state->endvalue)) {
+		VALID_CTXT();
+		VALID_ERROR("Extra data in list: %s\n", ctxt->state->value);
+		ret = -1;
+	    }
+	    xmlFree(val);
+	    ctxt->state->value = oldvalue;
+	    ctxt->state->endvalue = oldend;
+	    break;
+        }
+        case XML_RELAXNG_ONEORMORE:
+	    ret = xmlRelaxNGValidateValueList(ctxt, define->content);
+	    if (ret != 0) {
+		break;
+	    }
+	    /* no break on purpose */
+        case XML_RELAXNG_ZEROORMORE: {
+            xmlChar *cur, *temp;
+
+	    oldflags = ctxt->flags;
+	    ctxt->flags |= FLAGS_IGNORABLE;
+	    cur = ctxt->state->value;
+	    temp = NULL;
+	    while ((cur != NULL) && (cur != ctxt->state->endvalue) &&
+		   (temp != cur)) {
+		temp = cur;
+		ret = xmlRelaxNGValidateValueList(ctxt, define->content);
+		if (ret != 0) {
+		    ctxt->state->value = temp;
+		    ret = 0;
+		    break;
+		}
+		cur = ctxt->state->value;
+	    }
+	    ctxt->flags = oldflags;
+	    break;
+	}
 	default:
 	    TODO
 	    ret = -1;
@@ -3101,9 +3266,6 @@
 		            node->name, ret);
 #endif
 	    break;
-        case XML_RELAXNG_LIST:
-	    TODO
-	    break;
         case XML_RELAXNG_OPTIONAL:
 	    oldflags = ctxt->flags;
 	    ctxt->flags |= FLAGS_IGNORABLE;
@@ -3239,7 +3401,7 @@
 	     */
 	    if ((node != NULL) && (node->next != NULL)) {
 		VALID_CTXT();
-		VALID_ERROR("The data does not cover the full element %s\n",
+		VALID_ERROR("The value does not cover the full element %s\n",
 			    node->parent->name);
 		ret = -1;
 	    }
@@ -3247,9 +3409,41 @@
 		xmlFree(content);
 	    break;
 	}
+        case XML_RELAXNG_LIST: {
+	    xmlChar *content;
+	    xmlChar *oldvalue, *oldendvalue;
+	    int len;
 
-	    TODO
+	    content = xmlNodeGetContent(node);
+	    len = xmlStrlen(content);
+	    oldvalue = ctxt->state->value;
+	    oldendvalue = ctxt->state->endvalue;
+	    ctxt->state->value = content;
+	    ctxt->state->endvalue = content + len;
+	    ret = xmlRelaxNGValidateValue(ctxt, define);
+	    ctxt->state->value = oldvalue;
+	    ctxt->state->endvalue = oldendvalue;
+	    if (ret == -1) {
+		VALID_CTXT();
+		VALID_ERROR("internal error validating list\n");
+	    } else if (ret == 0) {
+		ctxt->state->seq = node->next;
+	    }
+	    /*
+	     * TODO cover the problems with
+	     * <p>12<!-- comment -->34</p>
+	     * TODO detect full element coverage at compilation time.
+	     */
+	    if ((node != NULL) && (node->next != NULL)) {
+		VALID_CTXT();
+		VALID_ERROR("The list does not cover the full element %s\n",
+			    node->parent->name);
+		ret = -1;
+	    }
+	    if (content != NULL)
+		xmlFree(content);
 	    break;
+        }
     }
     return(ret);
 }