another patch from Brent Hendricks to add new handlers with the various

* python/generator.py python/libxml.py: another patch from Brent
  Hendricks to add new handlers with the various validity contexts
* python/tests/Makefile.am python/tests/validDTD.py
  python/tests/validRNG.py python/tests/validSchemas.py: also
  added the regression tests he provided
Daniel
diff --git a/ChangeLog b/ChangeLog
index 0be29c8..1acaf68 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,11 @@
+Thu Mar 31 00:45:18 CEST 2005 Daniel Veillard <daniel@veillard.com>
+
+	* python/generator.py python/libxml.py: another patch from Brent
+	  Hendricks to add new handlers with the various validity contexts
+	* python/tests/Makefile.am python/tests/validDTD.py
+	  python/tests/validRNG.py python/tests/validSchemas.py: also 
+	  added the regression tests he provided
+
 Wed Mar 30 09:39:27 CEST 2005 Daniel Veillard <daniel@veillard.com>
 
 	* python/generator.py python/libxml.c: applied patch from Brent
diff --git a/pattern.c b/pattern.c
index 041039e..ee3bcbd 100644
--- a/pattern.c
+++ b/pattern.c
@@ -1082,7 +1082,7 @@
 		ctxt->error = 1;
 		goto error;
 	    }
-	    xmlFree(name);
+	    /* NOT REACHED xmlFree(name); */
 	}
     } else if (CUR == '*') {
         if (name != NULL) {
diff --git a/python/generator.py b/python/generator.py
index 0856d76..6144e54 100755
--- a/python/generator.py
+++ b/python/generator.py
@@ -747,6 +747,9 @@
     "inputBuffer": "ioReadWrapper",
     "parserCtxt": "parserCtxtCore",
     "xmlTextReader": "xmlTextReaderCore",
+    "ValidCtxt": "ValidCtxtCore",
+    "SchemaValidCtxt": "SchemaValidCtxtCore",
+    "relaxNgValidCtxt": "relaxNgValidCtxtCore",
 }
 classes_destructors = {
     "parserCtxt": "xmlFreeParserCtxt",
diff --git a/python/libxml.py b/python/libxml.py
index bde8aba..2eca71e 100644
--- a/python/libxml.py
+++ b/python/libxml.py
@@ -587,6 +587,45 @@
         return libxml2mod.addLocalCatalog(self._o, uri)
     
 
+class ValidCtxtCore:
+
+    def __init__(self, *args, **kw):
+        pass
+
+    def setValidityErrorHandler(self, err_func, warn_func, arg=None):
+        """
+        Register error and warning handlers for DTD validation.
+        These will be called back as f(msg,arg)
+        """
+        libxml2mod.xmlSetValidErrors(self._o, err_func, warn_func, arg)
+    
+
+class SchemaValidCtxtCore:
+
+    def __init__(self, *args, **kw):
+        pass
+
+    def setValidityErrorHandler(self, err_func, warn_func, arg=None):
+        """
+        Register error and warning handlers for Schema validation.
+        These will be called back as f(msg,arg)
+        """
+        libxml2mod.xmlSchemaSetValidErrors(self._o, err_func, warn_func, arg)
+
+
+class relaxNgValidCtxtCore:
+
+    def __init__(self, *args, **kw):
+        pass
+
+    def setValidityErrorHandler(self, err_func, warn_func, arg=None):
+        """
+        Register error and warning handlers for RelaxNG validation.
+        These will be called back as f(msg,arg)
+        """
+        libxml2mod.xmlRelaxNGSetValidErrors(self._o, err_func, warn_func, arg)
+
+    
 def _xmlTextReaderErrorFunc((f,arg),msg,severity,locator):
     """Intermediate callback to wrap the locator"""
     return f(arg,msg,severity,xmlTextReaderLocator(locator))
diff --git a/python/libxml2class.txt b/python/libxml2class.txt
index f814689..c8a2de1 100644
--- a/python/libxml2class.txt
+++ b/python/libxml2class.txt
@@ -694,7 +694,9 @@
     regexpExec()
     regexpIsDeterminist()
     regexpPrint()
-Class relaxNgValidCtxt()
+
+
+Class relaxNgValidCtxt(relaxNgValidCtxtCore)
 
     # functions from module relaxng
     relaxNGValidateDoc()
@@ -885,7 +887,9 @@
 
     # functions from module xmlschemas
     schemaParse()
-Class ValidCtxt()
+
+
+Class ValidCtxt(ValidCtxtCore)
 
     # functions from module valid
     validCtxtNormalizeAttributeValue()
@@ -1111,7 +1115,9 @@
 
     # functions from module xmlreader
     newTextReader()
-Class SchemaValidCtxt()
+
+
+Class SchemaValidCtxt(SchemaValidCtxtCore)
 
     # functions from module xmlschemas
     schemaSetValidOptions()
diff --git a/python/tests/Makefile.am b/python/tests/Makefile.am
index f41cd6d..c6d03e9 100644
--- a/python/tests/Makefile.am
+++ b/python/tests/Makefile.am
@@ -39,7 +39,10 @@
     tstLastError.py \
     indexes.py \
     dtdvalid.py \
-    tstmem.py
+    tstmem.py	\
+    validDTD.py	\
+    validSchemas.py \
+    validRNG.py
 
 XMLS=		\
     tst.xml	\
diff --git a/python/tests/validDTD.py b/python/tests/validDTD.py
new file mode 100755
index 0000000..1222f9f
--- /dev/null
+++ b/python/tests/validDTD.py
@@ -0,0 +1,59 @@
+#!/usr/bin/python -u
+import libxml2
+import sys
+
+ARG = 'test string'
+
+class ErrorHandler:
+
+    def __init__(self):
+        self.errors = []
+
+    def handler(self, msg, data):
+        if data != ARG:
+            raise Exception, "Error handler did not receive correct argument"
+        self.errors.append(msg)
+
+
+# Memory debug specific
+libxml2.debugMemory(1)
+
+dtd="""<!ELEMENT foo EMPTY>"""
+valid="""<?xml version="1.0"?>
+<foo></foo>"""
+
+invalid="""<?xml version="1.0"?>
+<foo><bar/></foo>"""
+
+dtd = libxml2.parseDTD(None, 'test.dtd')
+ctxt = libxml2.newValidCtxt()
+e = ErrorHandler()
+ctxt.setValidityErrorHandler(e.handler, e.handler, ARG)
+
+# Test valid document
+doc = libxml2.parseDoc(valid)
+ret = doc.validateDtd(ctxt, dtd)
+if ret != 1 or e.errors:
+    print "error doing DTD validation"
+    sys.exit(1)
+doc.freeDoc()
+
+# Test invalid document
+doc = libxml2.parseDoc(invalid)
+ret = doc.validateDtd(ctxt, dtd)
+if ret != 0 or not e.errors:
+    print "Error: document supposed to be invalid"
+doc.freeDoc()
+
+dtd.freeDtd()
+del dtd
+del ctxt
+
+# Memory debug specific
+libxml2.cleanupParser()
+if libxml2.debugMemory(1) == 0:
+    print "OK"
+else:
+    print "Memory leak %d bytes" % (libxml2.debugMemory(1))
+    libxml2.dumpMemory()
+
diff --git a/python/tests/validRNG.py b/python/tests/validRNG.py
new file mode 100755
index 0000000..7022efe
--- /dev/null
+++ b/python/tests/validRNG.py
@@ -0,0 +1,76 @@
+#!/usr/bin/python -u
+import libxml2
+import sys
+
+ARG = 'test string'
+
+class ErrorHandler:
+
+    def __init__(self):
+        self.errors = []
+
+    def handler(self, msg, data):
+        if data != ARG:
+            raise Exception, "Error handler did not receive correct argument"
+        self.errors.append(msg)
+
+# Memory debug specific
+libxml2.debugMemory(1)
+
+schema="""<?xml version="1.0"?>
+<element name="foo"
+         xmlns="http://relaxng.org/ns/structure/1.0"
+         xmlns:a="http://relaxng.org/ns/annotation/1.0"
+         xmlns:ex1="http://www.example.com/n1"
+         xmlns:ex2="http://www.example.com/n2">
+  <a:documentation>A foo element.</a:documentation>
+  <element name="ex1:bar1">
+    <empty/>
+  </element>
+  <element name="ex2:bar2">
+    <empty/>
+  </element>
+</element>
+"""
+
+valid="""<?xml version="1.0"?>
+<foo><pre1:bar1 xmlns:pre1="http://www.example.com/n1"/><pre2:bar2 xmlns:pre2="http://www.example.com/n2"/></foo>"""
+
+invalid="""<?xml version="1.0"?>
+<foo><pre1:bar1 xmlns:pre1="http://www.example.com/n1">bad</pre1:bar1><pre2:bar2 xmlns:pre2="http://www.example.com/n2"/></foo>"""
+
+rngp = libxml2.relaxNGNewMemParserCtxt(schema, len(schema))
+rngs = rngp.relaxNGParse()
+ctxt = rngs.relaxNGNewValidCtxt()
+e = ErrorHandler()
+ctxt.setValidityErrorHandler(e.handler, e.handler, ARG)
+
+# Test valid document
+doc = libxml2.parseDoc(valid)
+ret = doc.relaxNGValidateDoc(ctxt)
+if ret != 0 or e.errors:
+    print "error doing RelaxNG validation"
+    sys.exit(1)
+doc.freeDoc()
+
+# Test invalid document
+doc = libxml2.parseDoc(invalid)
+ret = doc.relaxNGValidateDoc(ctxt)
+if ret == 0 or not e.errors:
+    print "Error: document supposed to be RelaxNG invalid"
+    sys.exit(1)
+doc.freeDoc()
+
+del rngp
+del rngs
+del ctxt
+libxml2.relaxNGCleanupTypes()
+
+# Memory debug specific
+libxml2.cleanupParser()
+if libxml2.debugMemory(1) == 0:
+    print "OK"
+else:
+    print "Memory leak %d bytes" % (libxml2.debugMemory(1))
+    libxml2.dumpMemory()
+
diff --git a/python/tests/validSchemas.py b/python/tests/validSchemas.py
new file mode 100755
index 0000000..d4d62b2
--- /dev/null
+++ b/python/tests/validSchemas.py
@@ -0,0 +1,83 @@
+#!/usr/bin/python -u
+import libxml2
+import sys
+
+ARG = 'test string'
+
+class ErrorHandler:
+
+    def __init__(self):
+        self.errors = []
+
+    def handler(self, msg, data):
+        if data != ARG:
+            raise Exception, "Error handler did not receive correct argument"
+        self.errors.append(msg)
+
+# Memory debug specific
+libxml2.debugMemory(1)
+
+schema="""<?xml version="1.0" encoding="iso-8859-1"?>
+<schema xmlns = "http://www.w3.org/2001/XMLSchema">
+	<element name = "Customer">
+		<complexType>
+			<sequence>
+				<element name = "FirstName" type = "string" />
+				<element name = "MiddleInitial" type = "string" />
+				<element name = "LastName" type = "string" />
+			</sequence>
+			<attribute name = "customerID" type = "integer" />
+		</complexType>
+	</element>
+</schema>"""
+
+valid="""<?xml version="1.0" encoding="iso-8859-1"?>
+<Customer customerID = "24332">
+	<FirstName>Raymond</FirstName>
+	<MiddleInitial>G</MiddleInitial>
+	<LastName>Bayliss</LastName>
+</Customer>	
+"""
+
+invalid="""<?xml version="1.0" encoding="iso-8859-1"?>
+<Customer customerID = "24332">
+	<MiddleInitial>G</MiddleInitial>
+	<LastName>Bayliss</LastName>
+</Customer>	
+"""
+
+e = ErrorHandler()
+ctxt_parser = libxml2.schemaNewMemParserCtxt(schema, len(schema))
+ctxt_schema = ctxt_parser.schemaParse()
+ctxt_valid  = ctxt_schema.schemaNewValidCtxt()
+ctxt_valid.setValidityErrorHandler(e.handler, e.handler, ARG)
+
+# Test valid document
+doc = libxml2.parseDoc(valid)
+ret = doc.schemaValidateDoc(ctxt_valid)
+if ret != 0 or e.errors:
+    print "error doing schema validation"
+    sys.exit(1)
+doc.freeDoc()
+
+# Test invalid document
+doc = libxml2.parseDoc(invalid)
+ret = doc.schemaValidateDoc(ctxt_valid)
+if ret == 0 or not e.errors:
+    print "Error: document supposer to be schema invalid"
+    sys.exit(1)
+doc.freeDoc()
+
+del ctxt_parser
+del ctxt_schema
+del ctxt_valid
+libxml2.schemaCleanupTypes()
+
+# Memory debug specific
+libxml2.cleanupParser()
+if libxml2.debugMemory(1) == 0:
+    print "OK"
+else:
+    print "Memory leak %d bytes" % (libxml2.debugMemory(1))
+    libxml2.dumpMemory()
+
diff --git a/xmlschemas.c b/xmlschemas.c
index 7c31eb0..7d52005 100644
--- a/xmlschemas.c
+++ b/xmlschemas.c
@@ -19677,27 +19677,25 @@
 		if (ret == 0) {
 		    xmlRegExecNextValues(ctxt->regexp, &nbval, &nbneg,
 			&values[0], &terminal);
-		    if (nbval + nbneg != 0) {
-			/*
-			* If a next value still exists, I does not have to
-			* mean that there's an element missing, since it
-			* might be an optional element. So double check it.
-			*/
-			ret = xmlRegExecPushString(ctxt->regexp,
-			    NULL, NULL);
-			if (ret <= 0) {
-			    ret = 1;
-    			    xmlSchemaVComplexTypeElemErr(ctxt,
-				XML_SCHEMAV_ELEMENT_CONTENT,
-				elem, type, "Missing child element(s)",
-				nbval, nbneg, values);			    
-			} else
-			    ret = 0;			
+		    /*
+		    * If a next value still exists, I does not have to
+		    * mean that there's an element missing, since it
+		    * might be an optional element. So double check it.
+		    */
+		    ret = xmlRegExecPushString(ctxt->regexp,
+			NULL, NULL);
+		    if (ret <= 0) {
+			ret = 1;
+			xmlSchemaVComplexTypeElemErr(ctxt,
+			    XML_SCHEMAV_ELEMENT_CONTENT,
+			    elem, type, "Missing child element(s)",
+			    nbval, nbneg, values);			    
+		    } else
+			ret = 0;			
 #ifdef DEBUG_AUTOMATA
-			xmlGenericError(xmlGenericErrorContext,
-			    "====> %s : %d\n", elem->name, ret);
+		    xmlGenericError(xmlGenericErrorContext,
+			"====> %s : %d\n", elem->name, ret);
 #endif
-		    }		    
 #ifdef DEBUG_CONTENT
 		    if (ret == 0)
 			xmlGenericError(xmlGenericErrorContext,