okay the DTD validation code on top of the XMLTextParser API should be

* xmlreader.c python/tests/reader2py: okay the DTD validation
  code on top of the XMLTextParser API should be solid now.
Daniel
diff --git a/ChangeLog b/ChangeLog
index ae2fa9d..81404ed 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,8 @@
+Fri Jan  3 13:50:55 CET 2003 Daniel Veillard <daniel@veillard.com>
+
+	* xmlreader.c python/tests/reader2py: okay the DTD validation
+	  code on top of the XMLTextParser API should be solid now.
+
 Fri Jan  3 02:17:18 CET 2003 Daniel Veillard <daniel@veillard.com>
 
 	* xmlreader.c python/tests/reader2py: Fixing some more mess
diff --git a/python/tests/reader2.py b/python/tests/reader2.py
index 2488820..2d0835e 100755
--- a/python/tests/reader2.py
+++ b/python/tests/reader2.py
@@ -198,6 +198,45 @@
     sys.exit(1)
 
 #
+# The same test but without entity substitution this time
+#
+
+s = """<!DOCTYPE test [
+<!ELEMENT test (x, x)>
+<!ELEMENT x (y)>
+<!ELEMENT y (#PCDATA)>
+<!ENTITY x "<x>&y;</x>">
+<!ENTITY y "<y>yyy</y>">
+]>
+<test>
+  &x;
+  &x;
+</test>"""
+expect="""1 test 0
+3 #text 1
+5 x 1
+3 #text 1
+5 x 1
+3 #text 1
+15 test 0
+"""
+res=""
+err=""
+
+input = libxml2.inputBuffer(StringIO.StringIO(s))
+reader = input.newTextReader("test4")
+reader.SetParserProp(libxml2.PARSER_VALIDATE,1)
+while reader.Read() == 1:
+    res = res + "%s %s %d\n" % (reader.NodeType(),reader.Name(),reader.Depth())
+
+if res != expect:
+    print "test5 failed: unexpected output"
+    print res
+if err != "":
+    print "test5 failed: validation error found"
+    print err
+
+#
 # cleanup
 #
 del input
diff --git a/xmlreader.c b/xmlreader.c
index f7d5b43..5bf9355 100644
--- a/xmlreader.c
+++ b/xmlreader.c
@@ -243,21 +243,12 @@
     printf("xmlTextReaderEndElement(%s)\n", fullname);
 #endif
     if ((reader != NULL) && (reader->endElement != NULL)) {
-	xmlNodePtr node = ctxt->node;
 	/*
 	 * when processing an entity, the context may have been changed
 	 */
 	origctxt = reader->ctxt;
 
 	reader->endElement(ctx, fullname);
-
-#if 0
-	123
-	if (origctxt->validate) {
-	    ctxt->valid &= xmlValidatePopElement(&origctxt->vctxt,
-		                ctxt->myDoc, node, fullname);
-	}
-#endif
     }
     if (reader != NULL) {
 	if (reader->state == XML_TEXTREADER_ELEMENT)
@@ -472,6 +463,86 @@
 	    xmlFree(qname);
     }
 }
+/**
+ * xmlTextReaderValidateEntity:
+ * @reader:  the xmlTextReaderPtr used
+ *
+ * Handle the validation when an entity reference is encountered and
+ * entity substitution is not activated. As a result the parser interface
+ * must walk through the entity and do the validation calls
+ */
+static void
+xmlTextReaderValidateEntity(xmlTextReaderPtr reader) {
+    xmlNodePtr oldnode = reader->node;
+    xmlNodePtr node = reader->node;
+    xmlParserCtxtPtr ctxt = reader->ctxt;
+
+    do {
+	if (node->type == XML_ENTITY_REF_NODE) {
+	    /*
+	     * Case where the underlying tree is not availble, lookup the entity
+	     * and walk it.
+	     */
+	    if ((node->children == NULL) && (ctxt->sax != NULL) &&
+		(ctxt->sax->getEntity != NULL)) {
+		node->children = (xmlNodePtr) 
+		    ctxt->sax->getEntity(ctxt, node->name);
+	    }
+
+	    if ((node->children != NULL) &&
+		(node->children->type == XML_ENTITY_DECL) &&
+		(node->children->children != NULL)) {
+		xmlTextReaderEntPush(reader, node);
+		node = node->children->children;
+		continue;
+	    } else {
+		/*
+		 * The error has probably be raised already.
+		 */
+		if (node == oldnode)
+		    break;
+		node = node->next;
+	    }
+	} else if (node->type == XML_ELEMENT_NODE) {
+	    reader->node = node;
+	    xmlTextReaderValidatePush(reader);
+	} else if ((node->type == XML_TEXT_NODE) ||
+		   (node->type == XML_CDATA_SECTION_NODE)) {
+	    ctxt->valid &= xmlValidatePushCData(&ctxt->vctxt,
+			      node->content, xmlStrlen(node->content));
+	}
+
+	/*
+	 * go to next node
+	 */
+	if (node->children != NULL) {
+	    node = node->children;
+	    continue;
+	}
+	if (node->next != NULL) {
+	    node = node->next;
+	    continue;
+	}
+	do {
+	    node = node->parent;
+	    if (node->type == XML_ELEMENT_NODE) {
+		reader->node = node;
+		xmlTextReaderValidatePop(reader);
+	    }
+	    if ((node->type == XML_ENTITY_DECL) &&
+		(reader->ent != NULL) && (reader->ent->children == node)) {
+		node = xmlTextReaderEntPop(reader);
+	    }
+	    if (node == oldnode)
+		break;
+	    if (node->next != NULL) {
+		node = node->next;
+		break;
+	    }
+	} while ((node != NULL) && (node != oldnode));
+    } while ((node != NULL) && (node != oldnode));
+    reader->node = oldnode;
+}
 
 
 /**
@@ -633,7 +704,7 @@
     DUMP_READER
 
     /*
-     * Handle entities enter and exit
+     * Handle entities enter and exit when in entity replacement mode
      */
     if ((reader->node != NULL) &&
 	(reader->node->type == XML_ENTITY_REF_NODE) &&
@@ -654,6 +725,10 @@
 	    xmlTextReaderEntPush(reader, reader->node);
 	    reader->node = reader->node->children->children;
 	}
+    } else if ((reader->node != NULL) &&
+	       (reader->node->type == XML_ENTITY_REF_NODE) &&
+	       (reader->ctxt != NULL) && (reader->ctxt->validate == 1)) {
+	xmlTextReaderValidateEntity(reader);
     }
     if ((reader->node != NULL) &&
 	(reader->node->type == XML_ENTITY_DECL) &&