more work on grammars and refs/defs augmented/updated the regression tests

* relaxng: more work on grammars and refs/defs
* test/relaxng/* result/relaxng/*: augmented/updated the
  regression tests
Daniel
diff --git a/ChangeLog b/ChangeLog
index 1bb3c4c..09e7b4d 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,9 @@
+Tue Feb  4 00:20:58 CET 2003 Daniel Veillard <daniel@veillard.com>
+
+	* relaxng: more work on grammars and refs/defs
+	* test/relaxng/* result/relaxng/*: augmented/updated the
+	  regression tests
+
 Mon Feb  3 14:16:59 CET 2003 Daniel Veillard <daniel@veillard.com>
 
 	* relaxng: more work on name classes, except support
diff --git a/relaxng.c b/relaxng.c
index c6953c7..ab25bff 100644
--- a/relaxng.c
+++ b/relaxng.c
@@ -105,6 +105,7 @@
     XML_RELAXNG_DEF,		/* a definition */
     XML_RELAXNG_REF,		/* reference to a definition */
     XML_RELAXNG_EXTERNALREF,	/* reference to an external def */
+    XML_RELAXNG_PARENTREF,	/* reference to a def in the parent grammar */
     XML_RELAXNG_OPTIONAL,	/* optional patterns */
     XML_RELAXNG_ZEROORMORE,	/* zero or more non empty patterns */
     XML_RELAXNG_ONEORMORE,	/* one or more non empty patterns */
@@ -140,8 +141,10 @@
 
     xmlHashTablePtr defs;	/* define */
     xmlHashTablePtr refs;	/* references */
-    xmlHashTablePtr documents;     /* all the documents loaded */
-    xmlHashTablePtr includes;      /* all the includes loaded */
+    xmlHashTablePtr documents;  /* all the documents loaded */
+    xmlHashTablePtr includes;   /* all the includes loaded */
+    int                  defNr; /* number of defines used */
+    xmlRelaxNGDefinePtr *defTab;/* pointer to the allocated definitions */
     void *_private;	/* unused by the library for users or bindings */
 };
 
@@ -161,6 +164,7 @@
 
     xmlRelaxNGPtr      schema;        /* The schema in use */
     xmlRelaxNGGrammarPtr grammar;     /* the current grammar */
+    xmlRelaxNGGrammarPtr parentgrammar;/* the parent grammar */
     int                flags;         /* parser flags */
     int                nbErrors;      /* number of errors at parse time */
     int                nbWarnings;    /* number of warnings at parse time */
@@ -175,6 +179,10 @@
     xmlChar	      *URL;
     xmlDocPtr          document;
 
+    int                  defNr;       /* number of defines used */
+    int                  defMax;      /* number of defines aloocated */
+    xmlRelaxNGDefinePtr *defTab;      /* pointer to the allocated definitions */
+
     const char     *buffer;
     int               size;
 
@@ -337,7 +345,6 @@
  * 			Allocation functions				*
  * 									*
  ************************************************************************/
-static void xmlRelaxNGFreeDefineList(xmlRelaxNGDefinePtr defines);
 static void xmlRelaxNGFreeGrammar(xmlRelaxNGGrammarPtr grammar);
 static void xmlRelaxNGFreeDefine(xmlRelaxNGDefinePtr define);
 
@@ -430,6 +437,13 @@
     if (schema->includes != NULL)
 	xmlHashFree(schema->includes, (xmlHashDeallocator)
 		xmlRelaxNGFreeInclude);
+    if (schema->defTab != NULL) {
+	int i;
+
+	for (i = 0;i < schema->defNr;i++)
+	    xmlRelaxNGFreeDefine(schema->defTab[i]);
+	xmlFree(schema->defTab);
+    }
 
     xmlFree(schema);
 }
@@ -460,24 +474,6 @@
 }
 
 /**
- * xmlRelaxNGFreeDefineHash:
- * @defines:  a list of define structures
- *
- * Deallocate a RelaxNG definition in the hash table
- */
-static void
-xmlRelaxNGFreeDefineHash(xmlRelaxNGDefinePtr defines)
-{
-    xmlRelaxNGDefinePtr next;
-
-    while (defines != NULL) {
-	next = defines->nextHash;
-	xmlRelaxNGFreeDefine(defines);
-	defines = next;
-    }
-}
-
-/**
  * xmlRelaxNGFreeGrammar:
  * @grammar:  a grammar structure
  *
@@ -489,14 +485,14 @@
     if (grammar == NULL)
         return;
 
-    if (grammar->start != NULL)
-	xmlRelaxNGFreeDefine(grammar->start);
+    if (grammar->next != NULL) {
+	xmlRelaxNGFreeGrammar(grammar->next);
+    }
     if (grammar->refs != NULL) {
 	xmlHashFree(grammar->refs, NULL);
     }
     if (grammar->defs != NULL) {
-	xmlHashFree(grammar->defs, (xmlHashDeallocator)
-		xmlRelaxNGFreeDefineHash);
+	xmlHashFree(grammar->defs, NULL);
     }
 
     xmlFree(grammar);
@@ -516,38 +512,44 @@
 {
     xmlRelaxNGDefinePtr ret;
 
+    if (ctxt->defMax == 0) {
+	ctxt->defMax = 16;
+	ctxt->defNr = 0;
+	ctxt->defTab = (xmlRelaxNGDefinePtr *)
+	    xmlMalloc(ctxt->defMax * sizeof(xmlRelaxNGDefinePtr));
+	if (ctxt->defTab == NULL) {
+	    if ((ctxt != NULL) && (ctxt->error != NULL))
+		ctxt->error(ctxt->userData, "Out of memory\n");
+	    ctxt->nbErrors++;
+	    return (NULL);
+	}
+    } else if (ctxt->defMax <= ctxt->defNr) {
+	xmlRelaxNGDefinePtr *tmp;
+	ctxt->defMax *= 2;
+	tmp = (xmlRelaxNGDefinePtr *) xmlRealloc(ctxt->defTab,
+		ctxt->defMax * sizeof(xmlRelaxNGDefinePtr));
+	if (tmp == NULL) {
+	    if ((ctxt != NULL) && (ctxt->error != NULL))
+		ctxt->error(ctxt->userData, "Out of memory\n");
+	    ctxt->nbErrors++;
+	    return (NULL);
+	}
+	ctxt->defTab = tmp;
+    }
     ret = (xmlRelaxNGDefinePtr) xmlMalloc(sizeof(xmlRelaxNGDefine));
     if (ret == NULL) {
-        if ((ctxt != NULL) && (ctxt->error != NULL))
-            ctxt->error(ctxt->userData, "Out of memory\n");
+	if ((ctxt != NULL) && (ctxt->error != NULL))
+	    ctxt->error(ctxt->userData, "Out of memory\n");
 	ctxt->nbErrors++;
-        return (NULL);
+	return(NULL);
     }
     memset(ret, 0, sizeof(xmlRelaxNGDefine));
+    ctxt->defTab[ctxt->defNr++] = ret;
     ret->node = node;
-
     return (ret);
 }
 
 /**
- * xmlRelaxNGFreeDefineList:
- * @defines:  a list of define structures
- *
- * Deallocate a RelaxNG define structures.
- */
-static void
-xmlRelaxNGFreeDefineList(xmlRelaxNGDefinePtr defines)
-{
-    xmlRelaxNGDefinePtr next;
-
-    while (defines != NULL) {
-	next = defines->next;
-	xmlRelaxNGFreeDefine(defines);
-	defines = next;
-    }
-}
-
-/**
  * xmlRelaxNGFreePartition:
  * @partitions:  a partition set structure
  *
@@ -585,23 +587,15 @@
     if (define == NULL)
         return;
 
+    if ((define->data != NULL) &&
+	(define->type == XML_RELAXNG_INTERLEAVE))
+	xmlRelaxNGFreePartition((xmlRelaxNGPartitionPtr) define->data);
     if (define->name != NULL)
 	xmlFree(define->name);
     if (define->ns != NULL)
 	xmlFree(define->ns);
     if (define->value != NULL)
 	xmlFree(define->value);
-    if (define->attrs != NULL)
-	xmlRelaxNGFreeDefineList(define->attrs);
-    if ((define->content != NULL) &&
-	(define->type != XML_RELAXNG_REF) &&
-	(define->type != XML_RELAXNG_EXTERNALREF))
-	xmlRelaxNGFreeDefineList(define->content);
-    if (define->nameClass != NULL)
-	xmlRelaxNGFreeDefineList(define->nameClass);
-    if ((define->data != NULL) &&
-	(define->type == XML_RELAXNG_INTERLEAVE))
-	xmlRelaxNGFreePartition((xmlRelaxNGPartitionPtr) define->data);
     xmlFree(define);
 }
 
@@ -1572,6 +1566,8 @@
 static xmlRelaxNGDefinePtr xmlRelaxNGParseNameClass(
 	      xmlRelaxNGParserCtxtPtr ctxt, xmlNodePtr node,
 	      xmlRelaxNGDefinePtr def);
+static xmlRelaxNGGrammarPtr xmlRelaxNGParseGrammar(
+	      xmlRelaxNGParserCtxtPtr ctxt, xmlNodePtr nodes);
 
 
 #define IS_BLANK_NODE(n)						\
@@ -2202,7 +2198,6 @@
 			    "Could not create definition hash\n");
 	    ctxt->nbErrors++;
 	    ret = -1;
-	    xmlRelaxNGFreeDefine(def);
 	} else {
 	    tmp = xmlHashAddEntry(ctxt->grammar->defs, name, def);
 	    if (tmp < 0) {
@@ -2216,7 +2211,6 @@
 			            name);
 		    ctxt->nbErrors++;
 		    ret = -1;
-		    xmlRelaxNGFreeDefine(def);
 		} else {
 		    while (prev->nextHash != NULL)
 			prev = prev->nextHash;
@@ -2325,7 +2319,6 @@
 		ctxt->error(ctxt->userData,
 			    "Could not create references hash\n");
 	    ctxt->nbErrors++;
-	    xmlRelaxNGFreeDefine(def);
 	    def = NULL;
 	} else {
 	    int tmp;
@@ -2342,7 +2335,6 @@
 			    "Internal error refs definitions '%s'\n",
 				    def->name);
 		    ctxt->nbErrors++;
-		    xmlRelaxNGFreeDefine(def);
 		    def = NULL;
 		} else {
 		    def->nextHash = prev->nextHash;
@@ -2410,6 +2402,81 @@
 			"xmlRelaxNGParse: notAllowed element is not empty\n");
 	    ctxt->nbErrors++;
 	}
+    } else if (IS_RELAXNG(node, "grammar")) {
+	xmlRelaxNGGrammarPtr grammar, old;
+	xmlRelaxNGGrammarPtr oldparent;
+
+	oldparent = ctxt->parentgrammar;
+	old = ctxt->grammar;
+	ctxt->parentgrammar = old;
+	grammar = xmlRelaxNGParseGrammar(ctxt, node->children);
+	if (old != NULL) {
+	    ctxt->grammar = old;
+	    ctxt->parentgrammar = oldparent;
+	    if (grammar != NULL) {
+		grammar->next = old->next;
+		old->next = grammar;
+	    }
+	}
+	if (grammar != NULL)
+	    def = grammar->start;
+	else
+	    def = NULL;
+    } else if (IS_RELAXNG(node, "parentRef")) {
+	if (ctxt->parentgrammar == NULL) {
+	    if (ctxt->error != NULL)
+		ctxt->error(ctxt->userData,
+			"Use of parentRef without a parent grammar\n");
+	    ctxt->nbErrors++;
+	    return(NULL);
+	}
+	def = xmlRelaxNGNewDefine(ctxt, node);
+	if (def == NULL)
+	    return(NULL);
+	def->type = XML_RELAXNG_PARENTREF;
+	def->name = xmlGetProp(node, BAD_CAST "name");
+	if (def->name == NULL) {
+	    if (ctxt->error != NULL)
+		ctxt->error(ctxt->userData,
+			    "parentRef has no name\n");
+	    ctxt->nbErrors++;
+	}
+	if (node->children != NULL) {
+	    if (ctxt->error != NULL)
+		ctxt->error(ctxt->userData,
+			    "parentRef is not empty\n");
+	    ctxt->nbErrors++;
+	}
+	if (ctxt->parentgrammar->refs == NULL)
+	    ctxt->parentgrammar->refs = xmlHashCreate(10);
+	if (ctxt->parentgrammar->refs == NULL) {
+	    if (ctxt->error != NULL)
+		ctxt->error(ctxt->userData,
+			    "Could not create references hash\n");
+	    ctxt->nbErrors++;
+	    def = NULL;
+	} else {
+	    int tmp;
+
+	    tmp = xmlHashAddEntry(ctxt->parentgrammar->refs, def->name, def);
+	    if (tmp < 0) {
+		xmlRelaxNGDefinePtr prev;
+
+		prev = (xmlRelaxNGDefinePtr)
+		      xmlHashLookup(ctxt->parentgrammar->refs, def->name);
+		if (prev == NULL) {
+		    if (ctxt->error != NULL)
+			ctxt->error(ctxt->userData,
+			    "Internal error parentRef definitions '%s'\n",
+				    def->name);
+		    ctxt->nbErrors++;
+		    def = NULL;
+		} else {
+		    def->nextHash = prev->nextHash;
+		    prev->nextHash = def;
+		}
+	    }
+	}
     } else {
 	TODO
 	def = NULL;
@@ -2465,6 +2532,7 @@
 		case XML_RELAXNG_VALUE:
 		case XML_RELAXNG_LIST:
 		case XML_RELAXNG_REF:
+		case XML_RELAXNG_PARENTREF:
 		case XML_RELAXNG_EXTERNALREF:
 		case XML_RELAXNG_DEF:
 		case XML_RELAXNG_ONEORMORE:
@@ -2547,9 +2615,7 @@
 	else
 	    cur->type = XML_RELAXNG_ELEMENT;
 	
-        if (xmlRelaxNGParseNameClass(ctxt, child, cur) == NULL) {
-	    xmlRelaxNGFreeDefine(cur);
-	} else {
+        if (xmlRelaxNGParseNameClass(ctxt, child, cur) != NULL) {
 	    if (last == NULL) {
 		ret->content = cur;
 	    } else {
@@ -2674,6 +2740,7 @@
 		case XML_RELAXNG_VALUE:
 		case XML_RELAXNG_LIST:
 		case XML_RELAXNG_REF:
+		case XML_RELAXNG_PARENTREF:
 		case XML_RELAXNG_EXTERNALREF:
 		case XML_RELAXNG_DEF:
 		case XML_RELAXNG_ZEROORMORE:
@@ -2749,13 +2816,14 @@
 	    cur->parent = parent;
 	} else {
 	    cur = xmlRelaxNGParsePattern(ctxt, nodes);
-	    if (def == NULL) {
-		def = last = cur;
-	    } else {
-		last->next = cur;
-		last = cur;
+	    if (cur != NULL) {
+		if (def == NULL) {
+		    def = last = cur;
+		} else {
+		    last->next = cur;
+		    last = cur;
+		}
 	    }
-	    cur->parent = parent;
 	}
 	nodes = nodes->next;
     }
@@ -3321,6 +3389,13 @@
 	xmlFree(ctxt->docTab);
     if (ctxt->incTab != NULL)
 	xmlFree(ctxt->incTab);
+    if (ctxt->defTab != NULL) {
+	int i;
+
+	for (i = 0;i < ctxt->defNr;i++)
+	    xmlRelaxNGFreeDefine(ctxt->defTab[i]);
+	xmlFree(ctxt->defTab);
+    }
     xmlFree(ctxt);
 }
 
@@ -3746,6 +3821,9 @@
     ctxt->documents = NULL;
     ret->includes = ctxt->includes;
     ctxt->includes = NULL;
+    ret->defNr = ctxt->defNr;
+    ret->defTab = ctxt->defTab;
+    ctxt->defTab = NULL;
 
     return (ret);
 }
@@ -3880,6 +3958,14 @@
 	    xmlRelaxNGDumpDefines(output, define->content);
 	    fprintf(output, "</ref>\n");
 	    break;
+        case XML_RELAXNG_PARENTREF:
+	    fprintf(output, "<parentRef");
+	    if (define->name != NULL)
+		fprintf(output, " name=\"%s\"", define->name);
+	    fprintf(output, ">\n");
+	    xmlRelaxNGDumpDefines(output, define->content);
+	    fprintf(output, "</parentRef>\n");
+	    break;
 	case XML_RELAXNG_EXTERNALREF:
 	    fprintf(output, "<externalRef");
 	    xmlRelaxNGDumpDefines(output, define->content);
@@ -5081,8 +5167,9 @@
         case XML_RELAXNG_ATTRIBUTE:
 	    ret = xmlRelaxNGValidateAttribute(ctxt, define);
 	    break;
-	case XML_RELAXNG_EXTERNALREF:
         case XML_RELAXNG_REF:
+        case XML_RELAXNG_PARENTREF:
+	case XML_RELAXNG_EXTERNALREF:
 	    ret = xmlRelaxNGValidateDefinition(ctxt, define->content);
 	    break;
         case XML_RELAXNG_DATATYPE: {
diff --git a/result/relaxng/tutor10_1_4.err b/result/relaxng/tutor10_1_4.err
index f44dee7..3027e8e 100644
--- a/result/relaxng/tutor10_1_4.err
+++ b/result/relaxng/tutor10_1_4.err
@@ -1,2 +1,2 @@
-error detected at relaxng.c:4920
-error detected at relaxng.c:5223
+error detected at relaxng.c:5006
+error detected at relaxng.c:5310
diff --git a/result/relaxng/tutor10_1_5.err b/result/relaxng/tutor10_1_5.err
index 485b5f9..044426c 100644
--- a/result/relaxng/tutor10_1_5.err
+++ b/result/relaxng/tutor10_1_5.err
@@ -1,2 +1,2 @@
-error detected at relaxng.c:4925
-error detected at relaxng.c:5223
+error detected at relaxng.c:5011
+error detected at relaxng.c:5310
diff --git a/result/relaxng/tutor10_1_6.err b/result/relaxng/tutor10_1_6.err
index 485b5f9..044426c 100644
--- a/result/relaxng/tutor10_1_6.err
+++ b/result/relaxng/tutor10_1_6.err
@@ -1,2 +1,2 @@
-error detected at relaxng.c:4925
-error detected at relaxng.c:5223
+error detected at relaxng.c:5011
+error detected at relaxng.c:5310
diff --git a/result/relaxng/tutor10_2_3.err b/result/relaxng/tutor10_2_3.err
index df2b554..ae9e668 100644
--- a/result/relaxng/tutor10_2_3.err
+++ b/result/relaxng/tutor10_2_3.err
@@ -1,2 +1,2 @@
-error detected at relaxng.c:4932
-error detected at relaxng.c:5223
+error detected at relaxng.c:5018
+error detected at relaxng.c:5310
diff --git a/result/relaxng/tutor10_2_4.err b/result/relaxng/tutor10_2_4.err
index df2b554..ae9e668 100644
--- a/result/relaxng/tutor10_2_4.err
+++ b/result/relaxng/tutor10_2_4.err
@@ -1,2 +1,2 @@
-error detected at relaxng.c:4932
-error detected at relaxng.c:5223
+error detected at relaxng.c:5018
+error detected at relaxng.c:5310
diff --git a/result/relaxng/tutor10_7_3.err b/result/relaxng/tutor10_7_3.err
index e6e8943..2296156 100644
--- a/result/relaxng/tutor10_7_3.err
+++ b/result/relaxng/tutor10_7_3.err
@@ -1,5 +1,5 @@
 xmlRelaxNGValidateAttribute(email): -1
 xmlRelaxNGValidateAttribute(name): -1
 xmlRelaxNGValidateDefinition(): validated card : -1
-error detected at relaxng.c:4960
+error detected at relaxng.c:5046
 xmlRelaxNGValidateDefinition(): validated addressBook : -1
diff --git a/result/relaxng/tutor10_8_3.err b/result/relaxng/tutor10_8_3.err
index e6e8943..2296156 100644
--- a/result/relaxng/tutor10_8_3.err
+++ b/result/relaxng/tutor10_8_3.err
@@ -1,5 +1,5 @@
 xmlRelaxNGValidateAttribute(email): -1
 xmlRelaxNGValidateAttribute(name): -1
 xmlRelaxNGValidateDefinition(): validated card : -1
-error detected at relaxng.c:4960
+error detected at relaxng.c:5046
 xmlRelaxNGValidateDefinition(): validated addressBook : -1
diff --git a/result/relaxng/tutor11_2_2.err b/result/relaxng/tutor11_2_2.err
index e7c8b3b..c1dc05a 100644
--- a/result/relaxng/tutor11_2_2.err
+++ b/result/relaxng/tutor11_2_2.err
@@ -1,4 +1,4 @@
 xmlRelaxNGValidateAttribute(anyName): 0
 xmlRelaxNGValidateAttribute(anyName): -1
-error detected at relaxng.c:4968
+error detected at relaxng.c:5054
 xmlRelaxNGValidateDefinition(): validated card : -1
diff --git a/result/relaxng/tutor11_2_3.err b/result/relaxng/tutor11_2_3.err
index e7c8b3b..c1dc05a 100644
--- a/result/relaxng/tutor11_2_3.err
+++ b/result/relaxng/tutor11_2_3.err
@@ -1,4 +1,4 @@
 xmlRelaxNGValidateAttribute(anyName): 0
 xmlRelaxNGValidateAttribute(anyName): -1
-error detected at relaxng.c:4968
+error detected at relaxng.c:5054
 xmlRelaxNGValidateDefinition(): validated card : -1
diff --git a/result/relaxng/tutor11_3_1 b/result/relaxng/tutor11_3_1
new file mode 100644
index 0000000..83963d8
--- /dev/null
+++ b/result/relaxng/tutor11_3_1
@@ -0,0 +1 @@
+./test/relaxng/tutor11_3_1.xml validates
diff --git a/result/relaxng/tutor11_3_1.err b/result/relaxng/tutor11_3_1.err
new file mode 100644
index 0000000..b9c253e
--- /dev/null
+++ b/result/relaxng/tutor11_3_1.err
@@ -0,0 +1,3 @@
+xmlRelaxNGValidateAttribute(anyName): 0
+xmlRelaxNGValidateAttribute(anyName): 0
+xmlRelaxNGValidateDefinition(): validated example : 0
diff --git a/result/relaxng/tutor11_4_1 b/result/relaxng/tutor11_4_1
new file mode 100644
index 0000000..16aed5c
--- /dev/null
+++ b/result/relaxng/tutor11_4_1
@@ -0,0 +1 @@
+./test/relaxng/tutor11_4_1.xml validates
diff --git a/result/relaxng/tutor11_4_1.err b/result/relaxng/tutor11_4_1.err
new file mode 100644
index 0000000..3897976
--- /dev/null
+++ b/result/relaxng/tutor11_4_1.err
@@ -0,0 +1,4 @@
+xmlRelaxNGValidateAttribute(anyName): 0
+xmlRelaxNGValidateAttribute(anyName): -1
+xmlRelaxNGValidateAttribute(space): 0
+xmlRelaxNGValidateDefinition(): validated example : 0
diff --git a/result/relaxng/tutor12_1_1 b/result/relaxng/tutor12_1_1
new file mode 100644
index 0000000..aab20d3
--- /dev/null
+++ b/result/relaxng/tutor12_1_1
@@ -0,0 +1 @@
+./test/relaxng/tutor12_1_1.xml validates
diff --git a/result/relaxng/tutor12_1_1.err b/result/relaxng/tutor12_1_1.err
new file mode 100644
index 0000000..b6733d4
--- /dev/null
+++ b/result/relaxng/tutor12_1_1.err
@@ -0,0 +1,4 @@
+xmlRelaxNGValidateDefinition(): validated name : 0
+xmlRelaxNGValidateDefinition(): validated email : 0
+xmlRelaxNGValidateDefinition(): validated card : 0
+xmlRelaxNGValidateDefinition(): validated addressBook : 0
diff --git a/result/relaxng/tutor13_1_1 b/result/relaxng/tutor13_1_1
new file mode 100644
index 0000000..3a3f2ae
--- /dev/null
+++ b/result/relaxng/tutor13_1_1
@@ -0,0 +1 @@
+./test/relaxng/tutor13_1_1.xml validates
diff --git a/result/relaxng/tutor13_1_1.err b/result/relaxng/tutor13_1_1.err
new file mode 100644
index 0000000..d23763b
--- /dev/null
+++ b/result/relaxng/tutor13_1_1.err
@@ -0,0 +1,9 @@
+xmlRelaxNGValidateDefinition(): validated p : 0
+xmlRelaxNGValidateDefinition(): validated em : 0
+xmlRelaxNGValidateDefinition(): validated td : 0
+xmlRelaxNGValidateDefinition(): validated tr : 0
+xmlRelaxNGValidateDefinition(): validated td : 0
+xmlRelaxNGValidateDefinition(): validated tr : 0
+xmlRelaxNGValidateDefinition(): validated table : 0
+xmlRelaxNGValidateDefinition(): validated p : 0
+xmlRelaxNGValidateDefinition(): validated doc : 0
diff --git a/result/relaxng/tutor3_2_1.err b/result/relaxng/tutor3_2_1.err
index 57dfd09..01ec15f 100644
--- a/result/relaxng/tutor3_2_1.err
+++ b/result/relaxng/tutor3_2_1.err
@@ -1,3 +1,3 @@
-error detected at relaxng.c:4912
-error detected at relaxng.c:4960
+error detected at relaxng.c:4998
+error detected at relaxng.c:5046
 xmlRelaxNGValidateDefinition(): validated card : -1
diff --git a/result/relaxng/tutor3_5_2.err b/result/relaxng/tutor3_5_2.err
index 64104fc..d21e17e 100644
--- a/result/relaxng/tutor3_5_2.err
+++ b/result/relaxng/tutor3_5_2.err
@@ -1,4 +1,4 @@
 xmlRelaxNGValidateDefinition(): validated email : 0
 xmlRelaxNGValidateDefinition(): validated card : -1
-error detected at relaxng.c:4960
+error detected at relaxng.c:5046
 xmlRelaxNGValidateDefinition(): validated addressBook : -1
diff --git a/result/relaxng/tutor5_3_1.err b/result/relaxng/tutor5_3_1.err
index cbe216a..6f62fd3 100644
--- a/result/relaxng/tutor5_3_1.err
+++ b/result/relaxng/tutor5_3_1.err
@@ -1,3 +1,3 @@
-error detected at relaxng.c:5105
+error detected at relaxng.c:5192
 xmlRelaxNGValidateDefinition(): validated note : 0
 xmlRelaxNGValidateDefinition(): validated bad : -1
diff --git a/result/relaxng/tutor6_1_3.err b/result/relaxng/tutor6_1_3.err
index 079f7f1..3fbb817 100644
--- a/result/relaxng/tutor6_1_3.err
+++ b/result/relaxng/tutor6_1_3.err
@@ -1,5 +1,5 @@
 xmlRelaxNGValidateAttribute(preferredFormat): -1
 xmlRelaxNGValidateAttribute(email): 0
 xmlRelaxNGValidateAttribute(name): 0
-error detected at relaxng.c:4968
+error detected at relaxng.c:5054
 xmlRelaxNGValidateDefinition(): validated card : -1
diff --git a/result/relaxng/tutor6_2_4.err b/result/relaxng/tutor6_2_4.err
index ad2cde7..ecf180e 100644
--- a/result/relaxng/tutor6_2_4.err
+++ b/result/relaxng/tutor6_2_4.err
@@ -1,5 +1,5 @@
 xmlRelaxNGValidateDefinition(): validated name : 0
 xmlRelaxNGValidateDefinition(): validated email : 0
-error detected at relaxng.c:4960
+error detected at relaxng.c:5046
 xmlRelaxNGValidateDefinition(): validated preferredFormat : -1
 xmlRelaxNGValidateDefinition(): validated card : -1
diff --git a/result/relaxng/tutor6_3_1.err b/result/relaxng/tutor6_3_1.err
index 079f7f1..3fbb817 100644
--- a/result/relaxng/tutor6_3_1.err
+++ b/result/relaxng/tutor6_3_1.err
@@ -1,5 +1,5 @@
 xmlRelaxNGValidateAttribute(preferredFormat): -1
 xmlRelaxNGValidateAttribute(email): 0
 xmlRelaxNGValidateAttribute(name): 0
-error detected at relaxng.c:4968
+error detected at relaxng.c:5054
 xmlRelaxNGValidateDefinition(): validated card : -1
diff --git a/result/relaxng/tutor7_1_2.err b/result/relaxng/tutor7_1_2.err
index b401034..f460608 100644
--- a/result/relaxng/tutor7_1_2.err
+++ b/result/relaxng/tutor7_1_2.err
@@ -1,5 +1,5 @@
 Unimplemented block at xmlschemastypes.c:1132
-error detected at relaxng.c:4078
-error detected at relaxng.c:5159
-error detected at relaxng.c:4960
+error detected at relaxng.c:4164
+error detected at relaxng.c:5246
+error detected at relaxng.c:5046
 xmlRelaxNGValidateDefinition(): validated vector : -1
diff --git a/result/relaxng/tutor7_1_3.err b/result/relaxng/tutor7_1_3.err
index ea5baa2..fd341d5 100644
--- a/result/relaxng/tutor7_1_3.err
+++ b/result/relaxng/tutor7_1_3.err
@@ -1,6 +1,6 @@
 Unimplemented block at xmlschemastypes.c:1132
 Unimplemented block at xmlschemastypes.c:1132
-error detected at relaxng.c:4266
-error detected at relaxng.c:5159
-error detected at relaxng.c:4960
+error detected at relaxng.c:4352
+error detected at relaxng.c:5246
+error detected at relaxng.c:5046
 xmlRelaxNGValidateDefinition(): validated vector : -1
diff --git a/result/relaxng/tutor7_2_4.err b/result/relaxng/tutor7_2_4.err
index 7be81f1..be2be14 100644
--- a/result/relaxng/tutor7_2_4.err
+++ b/result/relaxng/tutor7_2_4.err
@@ -1,3 +1,3 @@
-error detected at relaxng.c:4241
-error detected at relaxng.c:5159
+error detected at relaxng.c:4327
+error detected at relaxng.c:5246
 xmlRelaxNGValidateDefinition(): validated vector : -1
diff --git a/result/relaxng/tutor7_3_4.err b/result/relaxng/tutor7_3_4.err
index 0d0056d..9e91174 100644
--- a/result/relaxng/tutor7_3_4.err
+++ b/result/relaxng/tutor7_3_4.err
@@ -1,7 +1,7 @@
 Unimplemented block at xmlschemastypes.c:1135
 Unimplemented block at xmlschemastypes.c:1135
 Unimplemented block at xmlschemastypes.c:1135
-error detected at relaxng.c:4266
-error detected at relaxng.c:5159
-error detected at relaxng.c:4960
+error detected at relaxng.c:4352
+error detected at relaxng.c:5246
+error detected at relaxng.c:5046
 xmlRelaxNGValidateDefinition(): validated path : -1
diff --git a/result/relaxng/tutor7_3_5.err b/result/relaxng/tutor7_3_5.err
index 3d48e84..6a17778 100644
--- a/result/relaxng/tutor7_3_5.err
+++ b/result/relaxng/tutor7_3_5.err
@@ -1,5 +1,5 @@
 Unimplemented block at xmlschemastypes.c:1135
-error detected at relaxng.c:4078
-error detected at relaxng.c:5159
-error detected at relaxng.c:4960
+error detected at relaxng.c:4164
+error detected at relaxng.c:5246
+error detected at relaxng.c:5046
 xmlRelaxNGValidateDefinition(): validated path : -1
diff --git a/result/relaxng/tutor8_2_4.err b/result/relaxng/tutor8_2_4.err
index bbea200..2a45574 100644
--- a/result/relaxng/tutor8_2_4.err
+++ b/result/relaxng/tutor8_2_4.err
@@ -3,5 +3,5 @@
   6 groups
 xmlRelaxNGValidateDefinition(): validated title : 0
 xmlRelaxNGValidateDefinition(): validated title : 0
-error detected at relaxng.c:4960
+error detected at relaxng.c:5046
 xmlRelaxNGValidateDefinition(): validated head : -1
diff --git a/result/relaxng/tutor8_2_5.err b/result/relaxng/tutor8_2_5.err
index 2a84fea..6279c93 100644
--- a/result/relaxng/tutor8_2_5.err
+++ b/result/relaxng/tutor8_2_5.err
@@ -1,6 +1,6 @@
 xmlRelaxNGComputeInterleaves(interleave0)
   6 child
   6 groups
-error detected at relaxng.c:4906
-error detected at relaxng.c:4960
+error detected at relaxng.c:4992
+error detected at relaxng.c:5046
 xmlRelaxNGValidateDefinition(): validated head : -1
diff --git a/result/relaxng/tutor8_2_6.err b/result/relaxng/tutor8_2_6.err
index 0393fd4..cf9e523 100644
--- a/result/relaxng/tutor8_2_6.err
+++ b/result/relaxng/tutor8_2_6.err
@@ -4,5 +4,5 @@
 xmlRelaxNGValidateDefinition(): validated title : 0
 xmlRelaxNGValidateDefinition(): validated base : 0
 xmlRelaxNGValidateDefinition(): validated base : 0
-error detected at relaxng.c:4960
+error detected at relaxng.c:5046
 xmlRelaxNGValidateDefinition(): validated head : -1
diff --git a/result/relaxng/tutor9_5_2.err b/result/relaxng/tutor9_5_2.err
index 3a61cca..2a51ff0 100644
--- a/result/relaxng/tutor9_5_2.err
+++ b/result/relaxng/tutor9_5_2.err
@@ -4,5 +4,5 @@
   2 groups
 xmlRelaxNGValidateAttribute(name): 0
 xmlRelaxNGValidateDefinition(): validated card : -1
-error detected at relaxng.c:4960
+error detected at relaxng.c:5046
 xmlRelaxNGValidateDefinition(): validated addressBook : -1
diff --git a/result/relaxng/tutor9_5_3.err b/result/relaxng/tutor9_5_3.err
index 5dbf9a3..ab16de2 100644
--- a/result/relaxng/tutor9_5_3.err
+++ b/result/relaxng/tutor9_5_3.err
@@ -5,5 +5,5 @@
 xmlRelaxNGValidateAttribute(name): 0
 xmlRelaxNGValidateAttribute(email): 0
 xmlRelaxNGValidateDefinition(): validated card : -1
-error detected at relaxng.c:4960
+error detected at relaxng.c:5046
 xmlRelaxNGValidateDefinition(): validated addressBook : -1
diff --git a/result/relaxng/tutor9_6_2.err b/result/relaxng/tutor9_6_2.err
index 856cc70..2b21d7e 100644
--- a/result/relaxng/tutor9_6_2.err
+++ b/result/relaxng/tutor9_6_2.err
@@ -1,4 +1,4 @@
 xmlRelaxNGValidateAttribute(name): 0
 xmlRelaxNGValidateDefinition(): validated card : -1
-error detected at relaxng.c:4960
+error detected at relaxng.c:5046
 xmlRelaxNGValidateDefinition(): validated addressBook : -1
diff --git a/result/relaxng/tutor9_6_3.err b/result/relaxng/tutor9_6_3.err
index fa908fc..2cc40f2 100644
--- a/result/relaxng/tutor9_6_3.err
+++ b/result/relaxng/tutor9_6_3.err
@@ -1,5 +1,5 @@
 xmlRelaxNGValidateAttribute(name): 0
 xmlRelaxNGValidateAttribute(email): 0
 xmlRelaxNGValidateDefinition(): validated card : -1
-error detected at relaxng.c:4960
+error detected at relaxng.c:5046
 xmlRelaxNGValidateDefinition(): validated addressBook : -1
diff --git a/test/relaxng/table.rng b/test/relaxng/table.rng
new file mode 100644
index 0000000..c14e603
--- /dev/null
+++ b/test/relaxng/table.rng
@@ -0,0 +1,21 @@
+<grammar xmlns="http://relaxng.org/ns/structure/1.0">
+
+<define name="cell.content">
+  <notAllowed/>
+</define>
+
+<start>
+  <element name="table">
+    <oneOrMore>
+      <element name="tr">
+        <oneOrMore>
+	  <element name="td">
+	    <ref name="cell.content"/>
+	  </element>
+        </oneOrMore>
+      </element>
+    </oneOrMore>
+  </element>
+</start>
+
+</grammar>
diff --git a/test/relaxng/tutor11_3.rng b/test/relaxng/tutor11_3.rng
new file mode 100644
index 0000000..72e041d
--- /dev/null
+++ b/test/relaxng/tutor11_3.rng
@@ -0,0 +1,15 @@
+<element name="example" xmlns="http://relaxng.org/ns/structure/1.0">
+  <zeroOrMore>
+    <attribute>
+      <anyName/>
+    </attribute>
+  </zeroOrMore>
+  <optional>
+    <attribute name="xml:space">
+      <choice>
+        <value>default</value>
+        <value>preserve</value>
+      </choice>
+    </attribute>
+  </optional>
+</element>
diff --git a/test/relaxng/tutor11_3_1.xml b/test/relaxng/tutor11_3_1.xml
new file mode 100644
index 0000000..01b47fc
--- /dev/null
+++ b/test/relaxng/tutor11_3_1.xml
@@ -0,0 +1 @@
+<example foo="bar" xml:space="default"/>
diff --git a/test/relaxng/tutor11_4.rng b/test/relaxng/tutor11_4.rng
new file mode 100644
index 0000000..158c7a5
--- /dev/null
+++ b/test/relaxng/tutor11_4.rng
@@ -0,0 +1,19 @@
+<element name="example" xmlns="http://relaxng.org/ns/structure/1.0">
+  <zeroOrMore>
+    <attribute>
+      <anyName>
+        <except>
+          <name>xml:space</name>
+        </except>
+      </anyName>
+    </attribute>
+  </zeroOrMore>
+  <optional>
+    <attribute name="xml:space">
+      <choice>
+        <value>default</value>
+        <value>preserve</value>
+      </choice>
+    </attribute>
+  </optional>
+</element>
diff --git a/test/relaxng/tutor11_4_1.xml b/test/relaxng/tutor11_4_1.xml
new file mode 100644
index 0000000..01b47fc
--- /dev/null
+++ b/test/relaxng/tutor11_4_1.xml
@@ -0,0 +1 @@
+<example foo="bar" xml:space="default"/>
diff --git a/test/relaxng/tutor12_1.rng b/test/relaxng/tutor12_1.rng
new file mode 100644
index 0000000..3902687
--- /dev/null
+++ b/test/relaxng/tutor12_1.rng
@@ -0,0 +1,13 @@
+<element name="addressBook" xmlns="http://relaxng.org/ns/structure/1.0" xmlns:a="http://www.example.com/annotation">
+  <zeroOrMore>
+    <element name="card">
+      <a:documentation>Information about a single email address.</a:documentation>
+      <element name="name">
+        <text/>
+      </element>
+      <element name="email">
+        <text/>
+      </element>
+    </element>
+  </zeroOrMore>
+</element>
diff --git a/test/relaxng/tutor12_1_1.xml b/test/relaxng/tutor12_1_1.xml
new file mode 100644
index 0000000..693df18
--- /dev/null
+++ b/test/relaxng/tutor12_1_1.xml
@@ -0,0 +1,3 @@
+<addressBook>
+  <card><name>foo</name><email>bar</email></card>
+</addressBook>
diff --git a/test/relaxng/tutor13_1.rng b/test/relaxng/tutor13_1.rng
new file mode 100644
index 0000000..f945142
--- /dev/null
+++ b/test/relaxng/tutor13_1.rng
@@ -0,0 +1,33 @@
+<grammar xmlns="http://relaxng.org/ns/structure/1.0">
+
+<start>
+  <element name="doc">
+    <zeroOrMore>
+      <choice>
+	<element name="p">
+	  <ref name="inline"/>
+	</element>
+	<grammar>
+	  <include href="table.rng">
+	    <define name="cell.content">
+	      <parentRef name="inline"/>
+	    </define>
+          </include>
+	</grammar>
+      </choice>
+    </zeroOrMore>
+  </element>
+</start>
+
+<define name="inline">
+  <zeroOrMore>
+    <choice>
+      <text/>
+      <element name="em">
+        <ref name="inline"/>
+      </element>
+    </choice>
+  </zeroOrMore>
+</define>
+
+</grammar>
diff --git a/test/relaxng/tutor13_1_1.xml b/test/relaxng/tutor13_1_1.xml
new file mode 100644
index 0000000..a5cb437
--- /dev/null
+++ b/test/relaxng/tutor13_1_1.xml
@@ -0,0 +1,12 @@
+<doc>
+  <p>start</p>
+  <table>
+    <tr>
+      <td> <em>hello</em> !</td>
+    </tr>
+    <tr>
+      <td></td>
+    </tr>
+  </table>
+  <p>end</p>
+</doc>