more bug-hunting added --tree to dump the intermediate rng tree patch from

* relaxng.c: more bug-hunting
* testRelax.c include/libxml/relaxng.h: added --tree to dump the
  intermediate rng tree
* python/generator.py: patch from Stephane Bidoul to fix the generator
  on python < 2.2
Daniel
diff --git a/ChangeLog b/ChangeLog
index 843e8bc..980e423 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,11 @@
+Sun Feb 16 16:40:52 CET 2003 Daniel Veillard <daniel@veillard.com>
+
+	* relaxng.c: more bug-hunting
+	* testRelax.c include/libxml/relaxng.h: added --tree to dump the
+	  intermediate rng tree
+	* python/generator.py: patch from Stephane Bidoul to fix the generator
+	  on python < 2.2
+
 Fri Feb 14 17:49:26 CET 2003 Daniel Veillard <daniel@veillard.com>
 
 	* check-relaxng-test-suite.py relaxng.c: more testing on the
diff --git a/include/libxml/relaxng.h b/include/libxml/relaxng.h
index 1264d34..788864d 100644
--- a/include/libxml/relaxng.h
+++ b/include/libxml/relaxng.h
@@ -42,6 +42,8 @@
 void		xmlRelaxNGFree		(xmlRelaxNGPtr schema);
 void		xmlRelaxNGDump		(FILE *output,
 					 xmlRelaxNGPtr schema);
+void		xmlRelaxNGDumpTree	(FILE * output,
+					 xmlRelaxNGPtr schema);
 /*
  * Interfaces for validating
  */
diff --git a/python/generator.py b/python/generator.py
index fc80417..5b5bced 100755
--- a/python/generator.py
+++ b/python/generator.py
@@ -1089,7 +1089,7 @@
 			if reference_keepers.has_key(tclass):
 			    list = reference_keepers[tclass]
 			    for pref in list:
-				if pref[0] == ref[0]:
+				if pref[0] == classname:
 				    classes.write("        __tmp.%s = self\n" %
 						  pref[1])
 			#
diff --git a/relaxng.c b/relaxng.c
index 229c816..36cec74 100644
--- a/relaxng.c
+++ b/relaxng.c
@@ -2312,6 +2312,89 @@
 }
 
 /**
+ * xmlRelaxNGProcessExternalRef:
+ * @ctxt: the parser context
+ * @node:  the externlRef node
+ *
+ * Process and compile an externlRef node
+ *
+ * Returns the xmlRelaxNGDefinePtr or NULL in case of error
+ */
+static xmlRelaxNGDefinePtr
+xmlRelaxNGProcessExternalRef(xmlRelaxNGParserCtxtPtr ctxt, xmlNodePtr node) {
+    xmlRelaxNGDocumentPtr docu;
+    xmlNodePtr root, tmp;
+    xmlChar *ns;
+    int newNs = 0;
+    xmlRelaxNGDefinePtr def;
+
+    docu = node->_private;
+    if (docu != NULL) {
+	def = xmlRelaxNGNewDefine(ctxt, node);
+	if (def == NULL)
+	    return(NULL);
+	def->type = XML_RELAXNG_EXTERNALREF;
+	
+	if (docu->content == NULL) {
+	    /*
+	     * Then do the parsing for good
+	     */
+	    root = xmlDocGetRootElement(docu->doc);
+	    if (root == NULL) {
+		if (ctxt->error != NULL)
+		    ctxt->error(ctxt->userData,
+			    "xmlRelaxNGParse: %s is empty\n",
+				ctxt->URL);
+		ctxt->nbErrors++;
+		return (NULL);
+	    }
+	    /*
+	     * ns transmission rules
+	     */
+	    ns = xmlGetProp(root, BAD_CAST "ns");
+	    if (ns == NULL) {
+		tmp = node;
+		while ((tmp != NULL) &&
+		       (tmp->type == XML_ELEMENT_NODE)) {
+		    ns = xmlGetProp(tmp, BAD_CAST "ns");
+		    if (ns != NULL) {
+			break;
+		    }
+		    tmp = tmp->parent;
+		}
+		if (ns != NULL) {
+		    xmlSetProp(root, BAD_CAST "ns", ns);
+		    newNs = 1;
+		    xmlFree(ns);
+		}
+	    } else {
+		xmlFree(ns);
+	    }
+
+	    /*
+	     * Parsing to get a precompiled schemas.
+	     */
+	    docu->schema = xmlRelaxNGParseDocument(ctxt, root);
+	    if ((docu->schema != NULL) &&
+		(docu->schema->topgrammar != NULL)) {
+		docu->content = docu->schema->topgrammar->start;
+	    }
+
+	    /*
+	     * the externalRef may be reused in a different ns context
+	     */
+	    if (newNs == 1) {
+		xmlUnsetProp(root, BAD_CAST "ns");
+	    }
+	}
+	def->content = docu->content;
+    } else {
+	def = NULL;
+    }
+    return(def);
+}
+
+/**
  * xmlRelaxNGParsePattern:
  * @ctxt:  a Relax-NG parser context
  * @node:  the pattern node.
@@ -2470,10 +2553,16 @@
 		prev = (xmlRelaxNGDefinePtr)
 		      xmlHashLookup(ctxt->grammar->refs, def->name);
 		if (prev == NULL) {
-		    if (ctxt->error != NULL)
-			ctxt->error(ctxt->userData,
-			    "Internal error refs definitions '%s'\n",
-				    def->name);
+		    if (def->name != NULL) {
+			if (ctxt->error != NULL)
+			    ctxt->error(ctxt->userData,
+				"Error refs definitions '%s'\n",
+					def->name);
+		    } else {
+			if (ctxt->error != NULL)
+			    ctxt->error(ctxt->userData,
+				"Error refs definitions\n");
+		    }
 		    ctxt->nbErrors++;
 		    def = NULL;
 		} else {
@@ -2507,39 +2596,7 @@
     } else if (IS_RELAXNG(node, "interleave")) {
 	def = xmlRelaxNGParseInterleave(ctxt, node);
     } else if (IS_RELAXNG(node, "externalRef")) {
-	xmlRelaxNGDocumentPtr docu;
-	xmlNodePtr root;
-
-	docu = node->_private;
-	if (docu != NULL) {
-	    def = xmlRelaxNGNewDefine(ctxt, node);
-	    if (def == NULL)
-		return(NULL);
-	    def->type = XML_RELAXNG_EXTERNALREF;
-	    
-	    if (docu->content == NULL) {
-		/*
-		 * Then do the parsing for good
-		 */
-		root = xmlDocGetRootElement(docu->doc);
-		if (root == NULL) {
-		    if (ctxt->error != NULL)
-			ctxt->error(ctxt->userData,
-				"xmlRelaxNGParse: %s is empty\n",
-				    ctxt->URL);
-		    ctxt->nbErrors++;
-		    return (NULL);
-		}
-		docu->schema = xmlRelaxNGParseDocument(ctxt, root);
-		if ((docu->schema != NULL) &&
-		    (docu->schema->topgrammar != NULL)) {
-		    docu->content = docu->schema->topgrammar->start;
-		}
-	    }
-	    def->content = docu->content;
-	} else {
-	    def = NULL;
-	}
+	def = xmlRelaxNGProcessExternalRef(ctxt, node);
     } else if (IS_RELAXNG(node, "notAllowed")) {
 	def = xmlRelaxNGNewDefine(ctxt, node);
 	if (def == NULL)
@@ -3934,7 +3991,7 @@
 		    cur->_private = incl;
 		} else if ((xmlStrEqual(cur->name, BAD_CAST "element")) ||
 	            (xmlStrEqual(cur->name, BAD_CAST "attribute"))) {
-		    xmlChar *name;
+		    xmlChar *name, *ns;
 		    xmlNodePtr text = NULL;
 		    
 		    /*
@@ -3956,20 +4013,23 @@
 				text = node;
 			    }
 			}
+			if (text == NULL) {
+			    if (ctxt->error != NULL)
+				ctxt->error(ctxt->userData,
+				"Failed to create a name %s element\n", name);
+			    ctxt->nbErrors++;
+			}
 			xmlUnsetProp(cur, BAD_CAST "name");
 			xmlFree(name);
-		    }
-		    if (xmlStrEqual(cur->name, BAD_CAST "attribute")) {
-			if (text == NULL) {
-			    text = cur->children;
-			    while (text != NULL) {
-				if ((text->type == XML_ELEMENT_NODE) &&
-			            (xmlStrEqual(text->name, BAD_CAST "name")))
-				    break;
-				text = text->next;
+			ns = xmlGetProp(cur, BAD_CAST "ns");
+			if (ns != NULL) {
+			    if (text != NULL) {
+				xmlSetProp(text, BAD_CAST "ns", ns);
+				/* xmlUnsetProp(cur, BAD_CAST "ns"); */
 			    }
-			}
-			if (text != NULL) {
+			    xmlFree(ns);
+			} else if (xmlStrEqual(cur->name,
+				   BAD_CAST "attribute")) {
 			    xmlSetProp(text, BAD_CAST "ns", BAD_CAST "");
 			}
 		    }
@@ -4453,6 +4513,27 @@
     xmlRelaxNGDumpGrammar(output, schema->topgrammar, 1);
 }
 
+/**
+ * xmlRelaxNGDumpTree:
+ * @output:  the file output
+ * @schema:  a schema structure
+ *
+ * Dump the transformed RelaxNG tree.
+ */
+void
+xmlRelaxNGDumpTree(FILE * output, xmlRelaxNGPtr schema)
+{
+    if (schema == NULL) {
+	fprintf(output, "RelaxNG empty or failed to compile\n");
+	return;
+    }
+    if (schema->doc == NULL) {
+	fprintf(output, "no document\n");
+    } else {
+	xmlDocDump(output, schema->doc); 
+    }
+}
+
 /************************************************************************
  * 									*
  * 			Validation implementation			*
diff --git a/testRelax.c b/testRelax.c
index 354e71e..c930b51 100644
--- a/testRelax.c
+++ b/testRelax.c
@@ -48,6 +48,7 @@
 static int debug = 0;
 #endif
 static int noout = 0;
+static int tree = 0;
 #ifdef HAVE_SYS_MMAN_H
 static int memory = 0;
 #endif
@@ -71,6 +72,9 @@
 #endif
 	if ((!strcmp(argv[i], "-noout")) || (!strcmp(argv[i], "--noout"))) {
 	    noout++;
+        } else
+	if ((!strcmp(argv[i], "-tree")) || (!strcmp(argv[i], "--tree"))) {
+	    tree++;
         }
     }
     xmlLineNumbersDefault(1);
@@ -123,6 +127,8 @@
 		if (debug)
 		    xmlRelaxNGDump(stdout, schema);
 #endif
+		if (tree)
+		    xmlRelaxNGDumpTree(stdout, schema);
 	    } else {
 		xmlDocPtr doc;
 
@@ -165,6 +171,7 @@
 	printf("\t--debug : dump a debug tree of the in-memory document\n");
 #endif
 	printf("\t--noout : do not print the result\n");
+	printf("\t--tree : print the intermediate Relax-NG document tree\n");
 #ifdef HAVE_SYS_MMAN_H
 	printf("\t--memory : test the schemas in memory parsing\n");
 #endif