fixed xmlSetProp and al. when the node passed is not an element. fixed

* tree.c: fixed xmlSetProp and al. when the node passed is not an
  element.
* relaxng.c: fixed bugs 7.3 (though not complete) and memory leaks
  found 373 test schemas: 369 success 4 failures
  found 529 test instances: 525 success 4 failures
* check-relaxng-test-suite.py: added memory debug reporting
Daniel
diff --git a/relaxng.c b/relaxng.c
index 8b04b26..2f91afe 100644
--- a/relaxng.c
+++ b/relaxng.c
@@ -309,6 +309,7 @@
     xmlRelaxNGPtr	schema; /* the schema */
 };
 
+
 /************************************************************************
  * 									*
  * 		Preliminary type checking interfaces			*
@@ -969,7 +970,6 @@
      */
     doc = xmlRelaxNGCleanupDoc(ctxt, doc);
     if (doc == NULL) {
-	/* xmlFreeDoc(ctxt->include); */
 	ctxt->inc = NULL;
 	return(NULL);
     }
@@ -988,7 +988,6 @@
 	    ctxt->error(ctxt->userData,
 			"xmlRelaxNG: included document is empty %s\n", URL);
 	ctxt->nbErrors++;
-	xmlFreeDoc(doc);
 	return (NULL);
     }
     if (!IS_RELAXNG(root, "grammar")) {
@@ -997,7 +996,6 @@
 		    "xmlRelaxNG: included document %s root is not a grammar\n",
 		        URL);
 	ctxt->nbErrors++;
-	xmlFreeDoc(doc);
 	return (NULL);
     }
 
@@ -1248,7 +1246,6 @@
      */
     doc = xmlRelaxNGCleanupDoc(ctxt, doc);
     if (doc == NULL) {
-	xmlFreeDoc(ctxt->document);
 	ctxt->doc = NULL;
 	return(NULL);
     }
@@ -2052,11 +2049,14 @@
     return(def);
 }
 
+static const xmlChar *invalidName = BAD_CAST "\1";
+
 /**
- * xmlRelaxNGCompareElemDefLists:
- * @ctxt:  a Relax-NG parser context
- * @defs1:  the first list of element defs
- * @defs2:  the second list of element defs
+ * xmlRelaxNGCompareNameClasses:
+ * @defs1:  the first element/attribute defs
+ * @defs2:  the second element/attribute defs
+ * @name:  the restriction on the name
+ * @ns:  the restriction on the namespace
  *
  * Compare the 2 lists of element definitions. The comparison is
  * that if both lists do not accept the same QNames, it returns 1
@@ -2065,6 +2065,103 @@
  * Returns 1 disttinct, 0 if equal
  */
 static int
+xmlRelaxNGCompareNameClasses(xmlRelaxNGDefinePtr def1,
+	                     xmlRelaxNGDefinePtr def2) {
+    int ret = 1;
+    xmlNode node;
+    xmlNs ns;
+    xmlRelaxNGValidCtxt ctxt;
+    ctxt.flags = FLAGS_IGNORABLE;
+
+    if ((def1->type == XML_RELAXNG_ELEMENT) ||
+	(def1->type == XML_RELAXNG_ATTRIBUTE)) {
+	if (def2->type == XML_RELAXNG_TEXT)
+	    return(1);
+	if (def1->name != NULL) {
+	    node.name = def1->name;
+	} else {
+	    node.name = invalidName;
+	}
+	node.ns = &ns;
+	if (def1->ns != NULL) {
+	    if (def1->ns[0] == 0) {
+		node.ns = NULL;
+	    } else {
+		ns.href = def1->ns;
+	    }
+	} else {
+	    ns.href = invalidName;
+	}
+        if (xmlRelaxNGElementMatch(&ctxt, def2, &node)) {
+	    if (def1->nameClass != NULL) {
+		ret = xmlRelaxNGCompareNameClasses(def1->nameClass, def2);
+	    } else {
+		ret = 0;
+	    }
+	} else {
+	    ret = 1;
+	}
+    } else if (def1->type == XML_RELAXNG_TEXT) {
+	if (def2->type == XML_RELAXNG_TEXT)
+	    return(0);
+	return(1);
+    } else if (def1->type == XML_RELAXNG_EXCEPT) {
+	xmlRelaxNGDefinePtr tmp = def1->content;
+	TODO
+	ret = 0;
+    } else {
+	TODO
+	ret = 0;
+    }
+    if (ret == 0)
+	return(ret);
+    if ((def2->type == XML_RELAXNG_ELEMENT) ||
+	(def2->type == XML_RELAXNG_ATTRIBUTE)) {
+	if (def2->name != NULL) {
+	    node.name = def2->name;
+	} else {
+	    node.name = invalidName;
+	}
+	node.ns = &ns;
+	if (def2->ns != NULL) {
+	    if (def2->ns[0] == 0) {
+		node.ns = NULL;
+	    } else {
+		ns.href = def2->ns;
+	    }
+	} else {
+	    ns.href = invalidName;
+	}
+        if (xmlRelaxNGElementMatch(&ctxt, def1, &node)) {
+	    if (def2->nameClass != NULL) {
+		ret = xmlRelaxNGCompareNameClasses(def2->nameClass, def1);
+	    } else {
+		ret = 0;
+	    }
+	} else {
+	    ret = 1;
+	}
+    } else {
+	TODO
+	ret = 0;
+    }
+
+    return(ret);
+}
+
+/**
+ * xmlRelaxNGCompareElemDefLists:
+ * @ctxt:  a Relax-NG parser context
+ * @defs1:  the first list of element/attribute defs
+ * @defs2:  the second list of element/attribute defs
+ *
+ * Compare the 2 lists of element or attribute definitions. The comparison
+ * is that if both lists do not accept the same QNames, it returns 1
+ * If the 2 lists can accept the same QName the comparison returns 0
+ *
+ * Returns 1 disttinct, 0 if equal
+ */
+static int
 xmlRelaxNGCompareElemDefLists(xmlRelaxNGParserCtxtPtr ctxt ATTRIBUTE_UNUSED,
 	              xmlRelaxNGDefinePtr *def1,
 		      xmlRelaxNGDefinePtr *def2) {
@@ -2076,16 +2173,8 @@
 	return(1);
     while (*def1 != NULL) {
 	while ((*def2) != NULL) {
-	    if ((*def1)->name == NULL) {
-		if (xmlStrEqual((*def2)->ns, (*def1)->ns))
-		    return(0);
-	    } else if ((*def2)->name == NULL) {
-		if (xmlStrEqual((*def2)->ns, (*def1)->ns))
-		    return(0);
-	    } else if (xmlStrEqual((*def1)->name, (*def2)->name)) {
-		if (xmlStrEqual((*def2)->ns, (*def1)->ns))
-		    return(0);
-	    }
+	    if (xmlRelaxNGCompareNameClasses(*def1, *def2) == 0)
+		return(0);
 	    def2++;
 	}
 	def2 = basedef2;
@@ -4656,6 +4745,9 @@
     if (ctxt->documents != NULL)
 	xmlHashFree(ctxt->documents, (xmlHashDeallocator)
 		xmlRelaxNGFreeDocument);
+    if (ctxt->includes != NULL)
+	xmlHashFree(ctxt->includes, (xmlHashDeallocator)
+		xmlRelaxNGFreeInclude);
     if (ctxt->docTab != NULL)
 	xmlFree(ctxt->docTab);
     if (ctxt->incTab != NULL)
@@ -4912,6 +5004,8 @@
 			delete = cur;
 			goto skip_children;
 		    }
+		    if (ns != NULL)
+			xmlFree(ns);
 		    xmlFree(URL);
 		    cur->_private = docu;
 		} else if (xmlStrEqual(cur->name, BAD_CAST "include")) {
@@ -5311,11 +5405,14 @@
             ctxt->error(ctxt->userData, "xmlRelaxNGParse: %s is empty\n",
                         ctxt->URL);
 	ctxt->nbErrors++;
+	xmlFreeDoc(doc);
         return (NULL);
     }
     ret = xmlRelaxNGParseDocument(ctxt, root);
-    if (ret == NULL)
+    if (ret == NULL) {
+	xmlFreeDoc(doc);
 	return(NULL);
+    }
 
     /*
      * Check the ref/defines links
@@ -5345,6 +5442,7 @@
     ctxt->document = NULL;
     ret->documents = ctxt->documents;
     ctxt->documents = NULL;
+    
     ret->includes = ctxt->includes;
     ctxt->includes = NULL;
     ret->defNr = ctxt->defNr;
@@ -6222,96 +6320,6 @@
 }
 
 /**
- * xmlRelaxNGValidateTryPermutation:
- * @ctxt:  a Relax-NG validation context
- * @groups:  the array of groups
- * @nbgroups:  the number of groups in the array
- * @array:  the permutation to try
- * @len:  the size of the set
- *
- * Try to validate a permutation for the group of definitions.
- *
- * Returns 0 if the validation succeeded or an error code.
- */
-static int
-xmlRelaxNGValidateTryPermutation(xmlRelaxNGValidCtxtPtr ctxt, 
-			    xmlRelaxNGDefinePtr rule,
-			    xmlNodePtr *array, int len) {
-    int i, ret;
-
-    if (len > 0) {
-	/*
-	 * One only need the next pointer set-up to do the validation
-	 */
-	for (i = 0;i < (len - 1);i++)
-	    array[i]->next = array[i + 1];
-	array[i]->next = NULL;
-
-	/*
-	 * Now try to validate the sequence
-	 */
-	ctxt->state->seq = array[0];
-	ret = xmlRelaxNGValidateDefinition(ctxt, rule);
-    } else {
-	ctxt->state->seq = NULL;
-	ret = xmlRelaxNGValidateDefinition(ctxt, rule);
-    }
-
-    /*
-     * the sequence must be fully consumed
-     */
-    if (ctxt->state->seq != NULL)
-	return(-1);
-
-    return(ret);
-}
-
-/**
- * xmlRelaxNGValidateWalkPermutations:
- * @ctxt:  a Relax-NG validation context
- * @groups:  the array of groups
- * @nbgroups:  the number of groups in the array
- * @nodes:  the set of nodes
- * @array:  the current state of the parmutation
- * @len:  the size of the set
- * @level:  a pointer to the level variable
- * @k:  the index in the array to fill
- *
- * Validate a set of nodes for a groups of definitions, will try the
- * full set of permutations
- *
- * Returns 0 if the validation succeeded or an error code.
- */
-static int
-xmlRelaxNGValidateWalkPermutations(xmlRelaxNGValidCtxtPtr ctxt, 
-			    xmlRelaxNGDefinePtr rule, xmlNodePtr *nodes,
-			    xmlNodePtr *array, int len,
-			    int *level, int k) {
-    int i, ret;
-
-    if ((k >= 0) && (k < len))
-	array[k] = nodes[*level];
-    *level = *level + 1;
-    if (*level == len) {
-	ret = xmlRelaxNGValidateTryPermutation(ctxt, rule, array, len);
-	if (ret == 0)
-	    return(0);
-    } else {
-	for (i = 0;i < len;i++) {
-	    if (array[i] == NULL) {
-		ret = xmlRelaxNGValidateWalkPermutations(ctxt, rule,
-				    nodes, array, len, level, i);
-	        if (ret == 0)
-		    return(0);
-	    }
-	}
-    }
-    *level = *level - 1;
-    array[k] = NULL;
-    return(-1);
-}
-
-/**
  * xmlRelaxNGNodeMatchesList:
  * @node:  the node
  * @list:  a NULL terminated array of definitions
@@ -6356,91 +6364,6 @@
 }
 
 /**
- * xmlRelaxNGValidatePartGroup:
- * @ctxt:  a Relax-NG validation context
- * @groups:  the array of groups
- * @nbgroups:  the number of groups in the array
- * @nodes:  the set of nodes
- * @len:  the size of the set of nodes
- *
- * Validate a set of nodes for a groups of definitions
- *
- * Returns 0 if the validation succeeded or an error code.
- */
-static int
-xmlRelaxNGValidatePartGroup(xmlRelaxNGValidCtxtPtr ctxt, 
-			    xmlRelaxNGInterleaveGroupPtr *groups,
-			    int nbgroups, xmlNodePtr *nodes, int len) {
-    int level, ret = -1, i, j, k, top_j, max_j;
-    xmlNodePtr *array = NULL, *list, oldseq;
-    xmlRelaxNGInterleaveGroupPtr group;
-
-    list = (xmlNodePtr *) xmlMalloc(len * sizeof(xmlNodePtr));
-    if (list == NULL) {
-	return(-1);
-    }
-    array = (xmlNodePtr *) xmlMalloc(len * sizeof(xmlNodePtr));
-    if (array == NULL) {
-	xmlFree(list);
-	return(-1);
-    }
-    memset(array, 0, len * sizeof(xmlNodePtr));
-
-    /*
-     * Partition the elements and validate the subsets.
-     */
-    oldseq = ctxt->state->seq;
-    max_j = -1;
-    for (i = 0;i < nbgroups;i++) {
-	group = groups[i];
-	if (group == NULL)
-	    continue;
-	k = 0;
-	top_j = -1;
-	for (j = 0;j < len;j++) {
-	    if (nodes[j] == NULL)
-		continue;
-	    if (xmlRelaxNGNodeMatchesList(nodes[j], group->defs)) {
-		list[k++] = nodes[j];
-		nodes[j] = NULL;
-		top_j = j;
-	    }
-	}
-	if (top_j > max_j)
-	    max_j = top_j;
-	ctxt->state->seq = oldseq;
-	if (k > 1) {
-	    memset(array, 0, k * sizeof(xmlNodePtr));
-	    level = -1;
-	    ret = xmlRelaxNGValidateWalkPermutations(ctxt, group->rule,
-					  list, array, k, &level, -1);
-	} else {
-            ret = xmlRelaxNGValidateTryPermutation(ctxt, group->rule, list, k);
-	}
-	if (ret != 0) {
-	    ctxt->state->seq = oldseq;
-	    break;
-	}
-    }
-
-    for (j = 0;j < max_j;j++) {
-	if (nodes[j] != NULL) {
-	    TODO /* problem, one of the nodes didn't got a match */
-	}
-    }
-    if (ret == 0) {
-	if (max_j + 1 < len)
-	    ctxt->state->seq = nodes[max_j + 1];
-	else
-	    ctxt->state->seq = NULL;
-    }
-
-    xmlFree(list);
-    xmlFree(array);
-    return(ret);
-}
-
-/**
  * xmlRelaxNGValidateInterleave:
  * @ctxt:  a Relax-NG validation context
  * @define:  the definition to verify
@@ -6455,7 +6378,7 @@
     int ret = 0, i, nbgroups, left;
     xmlRelaxNGPartitionPtr partitions;
     xmlRelaxNGInterleaveGroupPtr group = NULL;
-    xmlNodePtr cur, start, last, lastchg = NULL, lastelem;
+    xmlNodePtr cur, start, last = NULL, lastchg = NULL, lastelem;
     xmlNodePtr *list = NULL, *lasts = NULL;
 
     if (define->data != NULL) {