added param support for relaxng type checking, started to increment the

* relaxng.c xmlschemas.c xmlschemastypes.c
  include/libxml/xmlschemastypes.h: added param support for relaxng
  type checking, started to increment the pool of simple types
  registered, still much work to be done on simple types and
  facets checkings.
Daniel
diff --git a/relaxng.c b/relaxng.c
index 29db131..ff11f3e 100644
--- a/relaxng.c
+++ b/relaxng.c
@@ -332,13 +332,40 @@
  * @data:  data needed for the library
  * @type:  the type name
  * @value:  the value to check
+ * @result:  place to store the result if needed
  *
  * Function provided by a type library to check if a value match a type
  *
  * Returns 1 if yes, 0 if no and -1 in case of error.
  */
 typedef int (*xmlRelaxNGTypeCheck) (void *data, const xmlChar *type,
-	                            const xmlChar *value);
+	                            const xmlChar *value, void **result);
+
+/**
+ * xmlRelaxNGFacetCheck:
+ * @data:  data needed for the library
+ * @type:  the type name
+ * @facet:  the facet name
+ * @val:  the facet value
+ * @strval:  the string value
+ * @value:  the value to check
+ *
+ * Function provided by a type library to check a value facet
+ *
+ * Returns 1 if yes, 0 if no and -1 in case of error.
+ */
+typedef int (*xmlRelaxNGFacetCheck) (void *data, const xmlChar *type,
+	                             const xmlChar *facet, const xmlChar *val,
+				     const xmlChar *strval, void *value);
+
+/**
+ * xmlRelaxNGTypeFree:
+ * @data:  data needed for the library
+ * @result:  the value to free
+ *
+ * Function provided by a type library to free a returned result
+ */
+typedef void (*xmlRelaxNGTypeFree) (void *data, void *result);
 
 /**
  * xmlRelaxNGTypeCompare:
@@ -363,6 +390,8 @@
     xmlRelaxNGTypeHave      have;	/* the export function */
     xmlRelaxNGTypeCheck    check;	/* the checking function */
     xmlRelaxNGTypeCompare   comp;	/* the compare function */
+    xmlRelaxNGFacetCheck   facet;	/* the facet check function */
+    xmlRelaxNGTypeFree     freef;	/* the freeing function */
 };
 
 /************************************************************************
@@ -1440,7 +1469,8 @@
 static int
 xmlRelaxNGSchemaTypeCheck(void *data ATTRIBUTE_UNUSED,
 	                  const xmlChar *type,
-			  const xmlChar *value) {
+			  const xmlChar *value,
+			  void **result) {
     xmlSchemaTypePtr typ;
     int ret;
 
@@ -1456,7 +1486,8 @@
 	       BAD_CAST "http://www.w3.org/2001/XMLSchema");
     if (typ == NULL)
 	return(-1);
-    ret = xmlSchemaValidatePredefinedType(typ, value, NULL);
+    ret = xmlSchemaValidatePredefinedType(typ, value,
+	                                  (xmlSchemaValPtr *) result);
     if (ret == 0)
 	return(1);
     if (ret > 0)
@@ -1465,6 +1496,79 @@
 }
 
 /**
+ * xmlRelaxNGSchemaFacetCheck:
+ * @data:  data needed for the library
+ * @type:  the type name
+ * @facet:  the facet name
+ * @val:  the facet value
+ * @strval:  the string value
+ * @value:  the value to check
+ *
+ * Function provided by a type library to check a value facet
+ *
+ * Returns 1 if yes, 0 if no and -1 in case of error.
+ */
+static int
+xmlRelaxNGSchemaFacetCheck (void *data, const xmlChar *type,
+	                    const xmlChar *facetname, const xmlChar *val,
+			    const xmlChar *strval, void *value) {
+    xmlSchemaFacetPtr facet;
+    xmlSchemaTypePtr typ;
+    int ret;
+
+    if ((type == NULL) || (strval == NULL))
+	return(-1);
+    typ = xmlSchemaGetPredefinedType(type, 
+	       BAD_CAST "http://www.w3.org/2001/XMLSchema");
+    if (typ == NULL)
+	return(-1);
+
+    facet = xmlSchemaNewFacet();
+    if (facet == NULL)
+	return(-1);
+
+    if (xmlStrEqual(facetname, BAD_CAST "minInclusive"))  {
+        facet->type = XML_SCHEMA_FACET_MININCLUSIVE;
+    } else if (xmlStrEqual(facetname, BAD_CAST "minExclusive"))  {
+        facet->type = XML_SCHEMA_FACET_MINEXCLUSIVE;
+    } else if (xmlStrEqual(facetname, BAD_CAST "maxInclusive"))  {
+        facet->type = XML_SCHEMA_FACET_MAXINCLUSIVE;
+    } else if (xmlStrEqual(facetname, BAD_CAST "maxExclusive"))  {
+        facet->type = XML_SCHEMA_FACET_MAXEXCLUSIVE;
+    } else if (xmlStrEqual(facetname, BAD_CAST "totalDigits"))  {
+        facet->type = XML_SCHEMA_FACET_TOTALDIGITS;
+    } else if (xmlStrEqual(facetname, BAD_CAST "fractionDigits"))  {
+        facet->type = XML_SCHEMA_FACET_FRACTIONDIGITS;
+    } else if (xmlStrEqual(facetname, BAD_CAST "pattern"))  {
+        facet->type = XML_SCHEMA_FACET_PATTERN;
+    } else if (xmlStrEqual(facetname, BAD_CAST "enumeration"))  {
+        facet->type = XML_SCHEMA_FACET_ENUMERATION;
+    } else if (xmlStrEqual(facetname, BAD_CAST "whiteSpace"))  {
+        facet->type = XML_SCHEMA_FACET_WHITESPACE;
+    } else if (xmlStrEqual(facetname, BAD_CAST "length"))  {
+        facet->type = XML_SCHEMA_FACET_LENGTH;
+    } else if (xmlStrEqual(facetname, BAD_CAST "maxLength"))  {
+        facet->type = XML_SCHEMA_FACET_MAXLENGTH;
+    } else if (xmlStrEqual(facetname, BAD_CAST "minLength")) {
+        facet->type = XML_SCHEMA_FACET_MINLENGTH;
+    } else {
+	xmlSchemaFreeFacet(facet);
+	return(-1);
+    }
+    facet->value = xmlStrdup(val);
+    ret = xmlSchemaCheckFacet(facet, typ, NULL, type);
+    if (ret != 0) {
+	xmlSchemaFreeFacet(facet);
+	return(-1);
+    }
+    ret = xmlSchemaValidateFacet(typ, facet, strval, value);
+    xmlSchemaFreeFacet(facet);
+    if (ret != 0)
+	return(-1);
+    return(0);
+}
+
+/**
  * xmlRelaxNGSchemaTypeCompare:
  * @data:  data needed for the library
  * @type:  the type name
@@ -1520,21 +1624,13 @@
 static int
 xmlRelaxNGDefaultTypeCheck(void *data ATTRIBUTE_UNUSED,
 	                   const xmlChar *type ATTRIBUTE_UNUSED,
-			  const xmlChar *value ATTRIBUTE_UNUSED) {
+			   const xmlChar *value ATTRIBUTE_UNUSED,
+			   void **result ATTRIBUTE_UNUSED) {
     if (value == NULL)
 	return(-1);
     if (xmlStrEqual(type, BAD_CAST "string"))
 	return(1);
     if (xmlStrEqual(type, BAD_CAST "token")) {
-#if 0
-	const xmlChar *cur = value;
-
-	while (*cur != 0) {
-	    if (!IS_BLANK(*cur))
-		return(1);
-	    cur++;
-	}
-#endif
 	return(1);
     }
 
@@ -1624,7 +1720,8 @@
 static int
 xmlRelaxNGRegisterTypeLibrary(const xmlChar *namespace, void *data,
     xmlRelaxNGTypeHave have, xmlRelaxNGTypeCheck check,
-    xmlRelaxNGTypeCompare comp) {
+    xmlRelaxNGTypeCompare comp, xmlRelaxNGFacetCheck facet,
+    xmlRelaxNGTypeFree freef) {
     xmlRelaxNGTypeLibraryPtr lib;
     int ret;
 
@@ -1650,6 +1747,8 @@
     lib->have = have;
     lib->comp = comp;
     lib->check = check;
+    lib->facet = facet;
+    lib->freef = freef;
     ret = xmlHashAddEntry(xmlRelaxNGRegisteredTypes, namespace, lib);
     if (ret < 0) {
 	xmlGenericError(xmlGenericErrorContext,
@@ -1683,13 +1782,17 @@
 	    NULL,
 	    xmlRelaxNGSchemaTypeHave,
 	    xmlRelaxNGSchemaTypeCheck,
-	    xmlRelaxNGSchemaTypeCompare);
+	    xmlRelaxNGSchemaTypeCompare,
+	    xmlRelaxNGSchemaFacetCheck,
+	    (xmlRelaxNGTypeFree) xmlSchemaFreeValue);
     xmlRelaxNGRegisterTypeLibrary(
 	    xmlRelaxNGNs,
 	    NULL,
 	    xmlRelaxNGDefaultTypeHave,
 	    xmlRelaxNGDefaultTypeCheck,
-	    xmlRelaxNGDefaultTypeCompare);
+	    xmlRelaxNGDefaultTypeCompare,
+	    NULL,
+	    NULL);
     xmlRelaxNGTypeInitialized = 1;
     return(0);
 }
@@ -2009,6 +2112,8 @@
 		    lastparam->next = param;
 		    lastparam = param;
 		}
+		if (lib != NULL) {
+		}
 	    }
 	    content = content->next;
 	}
@@ -2960,11 +3065,6 @@
 	}
     } else if (IS_RELAXNG(node, "data")) {
 	def = xmlRelaxNGParseData(ctxt, node);
-#if 0
-    } else if (IS_RELAXNG(node, "define")) {
-	xmlRelaxNGParseDefine(ctxt, node);
-	def = NULL;
-#endif
     } else if (IS_RELAXNG(node, "value")) {
 	def = xmlRelaxNGParseValue(ctxt, node);
     } else if (IS_RELAXNG(node, "list")) {
@@ -5835,29 +5935,47 @@
 static int
 xmlRelaxNGValidateDatatype(xmlRelaxNGValidCtxtPtr ctxt, const xmlChar *value,
 	                   xmlRelaxNGDefinePtr define) {
-    int ret;
+    int ret, tmp;
     xmlRelaxNGTypeLibraryPtr lib;
+    void *result = NULL;
+    xmlRelaxNGDefinePtr cur;
 
     if ((define == NULL) || (define->data == NULL)) {
 	return(-1);
     }
     lib = (xmlRelaxNGTypeLibraryPtr) define->data;
-    if (lib->check != NULL)
-	ret = lib->check(lib->data, define->name, value);
-    else 
+    if (lib->check != NULL) {
+	if ((define->attrs != NULL) &&
+	    (define->attrs->type == XML_RELAXNG_PARAM)) {
+	    ret = lib->check(lib->data, define->name, value, &result);
+	} else {
+	    ret = lib->check(lib->data, define->name, value, NULL);
+	}
+    } else 
 	ret = -1;
     if (ret < 0) {
 	VALID_CTXT();
-	VALID_ERROR2("Internal: failed to validate type %s\n", define->name);
+	VALID_ERROR2("failed to validate type %s\n", define->name);
+	if ((result != NULL) && (lib != NULL) && (lib->freef != NULL))
+	    lib->freef(lib->data, result);
 	return(-1);
     } else if (ret == 1) {
 	ret = 0;
     } else {
 	VALID_CTXT();
 	VALID_ERROR3("Type %s doesn't allow value %s\n", define->name, value);
-	return(-1);
 	ret = -1;
     }
+    cur = define->attrs;
+    while ((ret == 0) && (cur != NULL) && (cur->type == XML_RELAXNG_PARAM)) {
+	if (lib->facet != NULL) {
+	    tmp = lib->facet(lib->data, define->name, cur->name,
+		             cur->value, value, result);
+            if (tmp != 0)
+	        ret = -1;
+	}
+	cur = cur->next;
+    }
     if ((ret == 0) && (define->content != NULL)) {
 	const xmlChar *oldvalue, *oldendvalue;
 
@@ -5869,6 +5987,8 @@
 	ctxt->state->value = (xmlChar *) oldvalue;
 	ctxt->state->endvalue = (xmlChar *) oldendvalue;
     }
+    if ((result != NULL) && (lib != NULL) && (lib->freef != NULL))
+	lib->freef(lib->data, result);
     return(ret);
 }
 
@@ -6998,7 +7118,7 @@
 	    ret = xmlRelaxNGValidateDatatype(ctxt, content, define);
 	    if (ret == -1) {
 		VALID_CTXT();
-		VALID_ERROR2("internal error validating %s\n", define->name);
+		VALID_ERROR2("Error validating %s\n", define->name);
 	    } else if (ret == 0) {
 		ctxt->state->seq = NULL;
 	    }