implemented comparisons for Schemas values. fixed some bugs in duration

* relaxng.c: implemented comparisons for Schemas values.
* xmlschemastypes.c include/libxml/xmlschemastypes.h: fixed
  some bugs in duration handling, comparisons for durations
  and decimals, removed all memory leaks pointed out by James
  testsuite. Current status is now
  found 238 test schemas: 197 success 41 failures
  found 1035 test instances: 803 success 130 failures
Daniel
diff --git a/ChangeLog b/ChangeLog
index e64e9d6..cb54b95 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,13 @@
+Fri Mar 28 14:24:08 CET 2003 Daniel Veillard <daniel@veillard.com>
+
+	* relaxng.c: implemented comparisons for Schemas values.
+	* xmlschemastypes.c include/libxml/xmlschemastypes.h: fixed
+	  some bugs in duration handling, comparisons for durations
+	  and decimals, removed all memory leaks pointed out by James
+	  testsuite. Current status is now
+	  found 238 test schemas: 197 success 41 failures
+	  found 1035 test instances: 803 success 130 failures
+
 Fri Mar 28 00:41:55 CET 2003 Daniel Veillard <daniel@veillard.com>
 
 	* xmlschemas.c include/libxml/xmlschemas.h: fixed bugs and memory
diff --git a/include/libxml/xmlschemastypes.h b/include/libxml/xmlschemastypes.h
index b19f5d0..b226c55 100644
--- a/include/libxml/xmlschemastypes.h
+++ b/include/libxml/xmlschemastypes.h
@@ -44,6 +44,8 @@
 						 xmlSchemaParserCtxtPtr ctxt,
 						 const xmlChar *name);
 void		xmlSchemaFreeFacet		(xmlSchemaFacetPtr facet);
+int		xmlSchemaCompareValues		(xmlSchemaValPtr x,
+						 xmlSchemaValPtr y);
 
 #ifdef __cplusplus
 }
diff --git a/relaxng.c b/relaxng.c
index b8c0b5c..a916fda 100644
--- a/relaxng.c
+++ b/relaxng.c
@@ -2305,24 +2305,68 @@
 }
 
 /**
+ * xmlRelaxNGSchemaFreeValue:
+ * @data:  data needed for the library
+ * @value:  the value to free
+ *
+ * Function provided by a type library to free a Schemas value
+ *
+ * Returns 1 if yes, 0 if no and -1 in case of error.
+ */
+static void
+xmlRelaxNGSchemaFreeValue (void *data ATTRIBUTE_UNUSED, void *value) {
+    xmlSchemaFreeValue(value);
+}
+
+/**
  * xmlRelaxNGSchemaTypeCompare:
  * @data:  data needed for the library
  * @type:  the type name
  * @value1:  the first value
  * @value2:  the second value
  *
- * Compare two values accordingly a type from the W3C XMLSchema
+ * Compare two values for equality accordingly a type from the W3C XMLSchema
  * Datatype library.
  *
- * Returns 1 if yes, 0 if no and -1 in case of error.
+ * Returns 1 if equal, 0 if no and -1 in case of error.
  */
 static int
 xmlRelaxNGSchemaTypeCompare(void *data ATTRIBUTE_UNUSED,
 	                    const xmlChar *type ATTRIBUTE_UNUSED,
 	                    const xmlChar *value1 ATTRIBUTE_UNUSED,
 			    const xmlChar *value2 ATTRIBUTE_UNUSED) {
-    TODO
-    return(1);
+    int ret;
+    xmlSchemaTypePtr typ;
+    xmlSchemaValPtr res1 = NULL, res2 = NULL;
+
+    if ((type == NULL) || (value1 == NULL) || (value2 == NULL))
+	return(-1);
+    typ = xmlSchemaGetPredefinedType(type, 
+	       BAD_CAST "http://www.w3.org/2001/XMLSchema");
+    if (typ == NULL)
+	return(-1);
+    ret = xmlSchemaValPredefTypeNode(typ, value1, &res1, NULL);
+    if (ret != 0)
+	return(-1);
+    if (res1 == NULL)
+	return(-1);
+    ret = xmlSchemaValPredefTypeNode(typ, value2, &res2, NULL);
+    if (ret != 0) {
+	xmlSchemaFreeValue(res1);
+	return(-1);
+    }
+    if (res1 == NULL) {
+	xmlSchemaFreeValue(res1);
+	return(-1);
+    }
+    ret = xmlSchemaCompareValues(res1, res2);
+    xmlSchemaFreeValue(res1);
+    xmlSchemaFreeValue(res2);
+    if (ret == -2)
+	return(-1);
+    if (ret == 0)
+	return(1);
+    return(0);
 }
  
 /**
@@ -2522,7 +2566,7 @@
 	    xmlRelaxNGSchemaTypeCheck,
 	    xmlRelaxNGSchemaTypeCompare,
 	    xmlRelaxNGSchemaFacetCheck,
-	    (xmlRelaxNGTypeFree) xmlSchemaFreeValue);
+	    xmlRelaxNGSchemaFreeValue);
     xmlRelaxNGRegisterTypeLibrary(
 	    xmlRelaxNGNs,
 	    NULL,
diff --git a/xmlschemastypes.c b/xmlschemastypes.c
index 1ef762f..753ae79 100644
--- a/xmlschemastypes.c
+++ b/xmlschemastypes.c
@@ -821,6 +821,8 @@
 	    dt->type = t;					\
             if (val != NULL)                                    \
                 *val = dt;                                      \
+            else						\
+		xmlSchemaFreeValue(dt);				\
 	    return 0;						\
 	}							\
     }
@@ -943,6 +945,8 @@
 
     if (val != NULL)
         *val = dt;
+    else
+	xmlSchemaFreeValue(dt);
 
     return 0;
 
@@ -984,6 +988,9 @@
     if (*cur++ != 'P')
 	return 1;
 
+    if (*cur == 0)
+	return 1;
+
     dur = xmlSchemaNewValue(XML_SCHEMAS_DURATION);
     if (dur == NULL)
 	return -1;
@@ -1053,6 +1060,8 @@
 
     if (val != NULL)
         *val = dur;
+    else
+	xmlSchemaFreeValue(dur);
 
     return 0;
 
@@ -1731,16 +1740,20 @@
     int order = 1;
     unsigned long tmp;
 
-    if ((x->value.decimal.sign) && (x->value.decimal.sign))
-        order = -1;
-    else if (x->value.decimal.sign)
-        return (-1);
-    else if (y->value.decimal.sign)
+    if ((x->value.decimal.sign) && (x->value.decimal.base != 0)) {
+	if ((y->value.decimal.sign) && (y->value.decimal.base != 0))
+	    order = -1;
+	else
+	    return (-1);
+    } else if ((y->value.decimal.sign) && (y->value.decimal.base != 0)) {
         return (1);
+    }
     if (x->value.decimal.frac == y->value.decimal.frac) {
         if (x->value.decimal.base < y->value.decimal.base)
-            return (-1);
-        return (x->value.decimal.base > y->value.decimal.base);
+            return (-order);
+        if (x->value.decimal.base > y->value.decimal.base)
+	    return(order);
+	return(0);
     }
     if (y->value.decimal.frac > x->value.decimal.frac) {
         swp = y;
@@ -1780,7 +1793,8 @@
 {
     long carry, mon, day;
     double sec;
-    long xmon, xday, myear, lyear, minday, maxday;
+    int invert = 1;
+    long xmon, xday, myear, minday, maxday;
     static const long dayRange [2][12] = {
         { 0, 28, 59, 89, 120, 150, 181, 212, 242, 273, 303, 334, },
         { 0, 31, 62, 92, 123, 153, 184, 215, 245, 276, 306, 337} };
@@ -1824,23 +1838,31 @@
     } else if ((day <= 0) && (sec <= 0.0)) {
         return -1;
     } else {
+	invert = -1;
         xmon = -mon;
         xday = day;
     }
 
     myear = xmon / 12;
-    lyear = myear / 4;
-    minday = (myear * 365) + (lyear != 0 ? lyear - 1 : 0);
-    maxday = (myear * 365) + (lyear != 0 ? lyear + 1 : 0);
-        
+    if (myear == 0) {
+	minday = 0;
+	maxday = 0;
+    } else {
+	maxday = 366 * ((myear + 3) / 4) +
+	         365 * ((myear - 1) % 4);
+	minday = maxday - 1;
+    }
+
     xmon = xmon % 12;
     minday += dayRange[0][xmon];
     maxday += dayRange[1][xmon];
 
+    if ((maxday == minday) && (maxday == xday))
+	return(0); /* can this really happen ? */
     if (maxday < xday)
-        return 1;
-    else if (minday > xday)
-        return -1;
+        return(-invert);
+    if (minday > xday)
+        return(invert);
 
     /* indeterminate */
     return 2;
@@ -2354,16 +2376,44 @@
  * Returns -1 if x < y, 0 if x == y, 1 if x > y, 2 if x <> y, and -2 in
  * case of error
  */
-static int
+int
 xmlSchemaCompareValues(xmlSchemaValPtr x, xmlSchemaValPtr y) {
     if ((x == NULL) || (y == NULL))
 	return(-2);
 
     switch (x->type) {
-	case XML_SCHEMAS_STRING:
-	    TODO
+	case XML_SCHEMAS_UNKNOWN:
+	    return(-2);
+        case XML_SCHEMAS_INTEGER:
+        case XML_SCHEMAS_NPINTEGER:
+        case XML_SCHEMAS_NINTEGER:
+        case XML_SCHEMAS_NNINTEGER:
+        case XML_SCHEMAS_PINTEGER:
+        case XML_SCHEMAS_INT:
+        case XML_SCHEMAS_UINT:
+        case XML_SCHEMAS_LONG:
+        case XML_SCHEMAS_ULONG:
+        case XML_SCHEMAS_SHORT:
+        case XML_SCHEMAS_USHORT:
+        case XML_SCHEMAS_BYTE:
+        case XML_SCHEMAS_UBYTE:
 	case XML_SCHEMAS_DECIMAL:
-	    if (y->type == XML_SCHEMAS_DECIMAL)
+	    if (y->type == x->type)
+		return(xmlSchemaCompareDecimals(x, y));
+	    if ((y->type == XML_SCHEMAS_DECIMAL) ||
+		(y->type == XML_SCHEMAS_INTEGER) ||
+		(y->type == XML_SCHEMAS_NPINTEGER) ||
+		(y->type == XML_SCHEMAS_NINTEGER) ||
+		(y->type == XML_SCHEMAS_NNINTEGER) ||
+		(y->type == XML_SCHEMAS_PINTEGER) ||
+		(y->type == XML_SCHEMAS_INT) ||
+		(y->type == XML_SCHEMAS_UINT) ||
+		(y->type == XML_SCHEMAS_LONG) ||
+		(y->type == XML_SCHEMAS_ULONG) ||
+		(y->type == XML_SCHEMAS_SHORT) ||
+		(y->type == XML_SCHEMAS_USHORT) ||
+		(y->type == XML_SCHEMAS_BYTE) ||
+		(y->type == XML_SCHEMAS_UBYTE))
 		return(xmlSchemaCompareDecimals(x, y));
 	    return(-2);
         case XML_SCHEMAS_DURATION:
@@ -2387,9 +2437,26 @@
                 (y->type == XML_SCHEMAS_DATE)      ||
                 (y->type == XML_SCHEMAS_GYEARMONTH))
                 return (xmlSchemaCompareDates(x, y));
-
             return (-2);
-	default:
+        case XML_SCHEMAS_STRING:
+        case XML_SCHEMAS_NORMSTRING:
+        case XML_SCHEMAS_FLOAT:
+        case XML_SCHEMAS_DOUBLE:
+        case XML_SCHEMAS_BOOLEAN:
+        case XML_SCHEMAS_TOKEN:
+        case XML_SCHEMAS_LANGUAGE:
+        case XML_SCHEMAS_NMTOKEN:
+        case XML_SCHEMAS_NMTOKENS:
+        case XML_SCHEMAS_NAME:
+        case XML_SCHEMAS_QNAME:
+        case XML_SCHEMAS_NCNAME:
+        case XML_SCHEMAS_ID:
+        case XML_SCHEMAS_IDREF:
+        case XML_SCHEMAS_IDREFS:
+        case XML_SCHEMAS_ENTITY:
+        case XML_SCHEMAS_ENTITIES:
+        case XML_SCHEMAS_NOTATION:
+        case XML_SCHEMAS_ANYURI:
 	    TODO
     }
     return -2;