added the close and getattribute methods of XmlTextReader. added the

* xmlreader.c doc/libxml2-api.xml: added the close and getattribute
  methods of XmlTextReader.
* python/generator.py python/libxml_wrap.h python/types.c
  python/libxml2class.txt: added the reader to the Python bindings
* python/tests/Makefile.am python/tests/reader.py: added a specific
  test for the Python bindings of the Reader APIs
* parser.c: small cleanup.
Daniel
diff --git a/python/generator.py b/python/generator.py
index 9c75713..b42630b 100755
--- a/python/generator.py
+++ b/python/generator.py
@@ -271,6 +271,7 @@
     'xmlOutputBufferPtr': ('O', "outputBuffer", "xmlOutputBufferPtr", "xmlOutputBufferPtr"),
     'xmlParserInputBufferPtr': ('O', "inputBuffer", "xmlParserInputBufferPtr", "xmlParserInputBufferPtr"),
     'xmlRegexpPtr': ('O', "xmlReg", "xmlRegexpPtr", "xmlRegexpPtr"),
+    'xmlTextReaderPtr': ('O', "xmlTextReader", "xmlTextReaderPtr", "xmlTextReaderPtr"),
 }
 
 py_return_types = {
@@ -597,6 +598,7 @@
     "xmlOutputBufferPtr": ("._o", "outputBuffer(_obj=%s)", "outputBuffer"),
     "xmlParserInputBufferPtr": ("._o", "inputBuffer(_obj=%s)", "inputBuffer"),
     "xmlRegexpPtr": ("._o", "xmlReg(_obj=%s)", "xmlReg"),
+    "xmlTextReaderPtr": ("._o", "xmlTextReader(_obj=%s)", "xmlTextReader"),
 }
 
 converter_type = {
@@ -624,6 +626,7 @@
 #    "outputBuffer": "xmlOutputBufferClose",
     "inputBuffer": "xmlFreeParserInputBuffer",
     "xmlReg": "xmlRegFreeRegexp",
+    "xmlTextReader": "xmlFreeTextReader",
 }
 
 functions_noexcept = {
@@ -676,6 +679,9 @@
         func = "regexp" + name[9:]
     elif name[0:6] == "xmlReg" and file == "xmlregexp":
         func = "regexp" + name[6:]
+    elif name[0:13] == "xmlTextReader" and file == "xmlreader":
+        func = name[13:]
+        func = string.lower(func[0:1]) + func[1:]
     elif name[0:11] == "xmlACatalog":
         func = name[11:]
         func = string.lower(func[0:1]) + func[1:]
diff --git a/python/libxml2class.txt b/python/libxml2class.txt
index e15f599..6127f7b 100644
--- a/python/libxml2class.txt
+++ b/python/libxml2class.txt
@@ -165,6 +165,9 @@
 registerDefaultOutputCallbacks()
 registerHTTPPostCallbacks()
 
+# functions from module xmlreader
+newTextReaderFilename()
+
 # functions from module xmlregexp
 regexpCompile()
 
@@ -556,6 +559,30 @@
     freeProp()
     freePropList()
     removeProp()
+Class xmlTextReader()
+
+    # functions from module xmlreader
+    attributeCount()
+    baseUri()
+    close()
+    depth()
+    freeTextReader()
+    getAttribute()
+    getAttributeNo()
+    getAttributeNs()
+    hasAttributes()
+    hasValue()
+    isDefault()
+    isEmptyElement()
+    localName()
+    name()
+    namespaceUri()
+    nodeType()
+    prefix()
+    quoteChar()
+    read()
+    value()
+    xmlLang()
 Class xmlReg()
 
     # functions from module xmlregexp
@@ -731,6 +758,9 @@
     push()
     read()
 
+    # functions from module xmlreader
+    newTextReader()
+
 
 Class outputBuffer(ioWriteWrapper)
 
diff --git a/python/libxml_wrap.h b/python/libxml_wrap.h
index efa79d0..7a38f54 100644
--- a/python/libxml_wrap.h
+++ b/python/libxml_wrap.h
@@ -17,6 +17,26 @@
 #include <libxml/xmlunicode.h>
 #include <libxml/xmlregexp.h>
 #include <libxml/xmlautomata.h>
+#include <libxml/xmlreader.h>
+
+/**
+ * ATTRIBUTE_UNUSED:
+ *
+ * Macro used to signal to GCC unused function parameters
+ * Repeated here since the definition is not available when
+ * compiled outside the libxml2 build tree.
+ */
+#ifdef __GNUC__
+#ifdef ATTRIBUTE_UNUSED
+#undef ATTRIBUTE_UNUSED
+#endif
+#include <ansidecl.h>
+#ifndef ATTRIBUTE_UNUSED
+#define ATTRIBUTE_UNUSED
+#endif
+#else
+#define ATTRIBUTE_UNUSED
+#endif
 
 #define PyxmlNode_Get(v) (((v) == Py_None) ? NULL : \
 	(((PyxmlNode_Object *)(v))->obj))
@@ -66,6 +86,14 @@
     xmlRegexpPtr obj;
 } PyxmlReg_Object;
 
+#define PyxmlTextReader_Get(v) (((v) == Py_None) ? NULL : \
+        (((PyxmlTextReader_Object *)(v))->obj))
+
+typedef struct {
+    PyObject_HEAD
+    xmlTextReaderPtr obj;
+} PyxmlTextReader_Object;
+
 #define PyURI_Get(v) (((v) == Py_None) ? NULL : \
 	(((PyURI_Object *)(v))->obj))
 
@@ -119,5 +147,6 @@
 PyObject * libxml_xmlOutputBufferPtrWrap(xmlOutputBufferPtr buffer);
 PyObject * libxml_xmlParserInputBufferPtrWrap(xmlParserInputBufferPtr buffer);
 PyObject * libxml_xmlRegexpPtrWrap(xmlRegexpPtr regexp);
+PyObject * libxml_xmlTextReaderPtrWrap(xmlTextReaderPtr reader);
 
 xmlXPathObjectPtr libxml_xmlXPathObjectPtrConvert(PyObject * obj);
diff --git a/python/tests/Makefile.am b/python/tests/Makefile.am
index 96cb033..c6bef2c 100644
--- a/python/tests/Makefile.am
+++ b/python/tests/Makefile.am
@@ -19,7 +19,8 @@
     outbuf.py	\
     inbuf.py	\
     resolver.py \
-    regexp.py
+    regexp.py	\
+    reader.py
 
 XMLS=		\
     tst.xml	\
diff --git a/python/tests/reader.py b/python/tests/reader.py
new file mode 100755
index 0000000..1817fe9
--- /dev/null
+++ b/python/tests/reader.py
@@ -0,0 +1,94 @@
+#!/usr/bin/python -u
+import libxml2
+import StringIO
+import sys
+
+# Memory debug specific
+libxml2.debugMemory(1)
+
+f = StringIO.StringIO("""<a><b b1="b1"/><c>content of c</c></a>""")
+input = libxml2.inputBuffer(f)
+reader = input.newTextReader()
+ret = reader.read()
+if ret != 1:
+    print "Error reading to first element"
+    sys.exit(1)
+if reader.name() != "a" or reader.isEmptyElement() != 0 or \
+   reader.nodeType() != 1 or reader.hasAttributes() != 0:
+    print "Error reading the first element"
+    sys.exit(1)
+ret = reader.read()
+if ret != 1:
+    print "Error reading to second element"
+    sys.exit(1)
+if reader.name() != "b" or reader.isEmptyElement() != 1 or \
+   reader.nodeType() != 1 or reader.hasAttributes() != 1:
+    print "Error reading the second element"
+    sys.exit(1)
+ret = reader.read()
+if ret != 1:
+    print "Error reading to third element"
+    sys.exit(1)
+if reader.name() != "c" or reader.isEmptyElement() != 0 or \
+   reader.nodeType() != 1 or reader.hasAttributes() != 0:
+    print "Error reading the third element"
+    sys.exit(1)
+ret = reader.read()
+if ret != 1:
+    print "Error reading to text node"
+    sys.exit(1)
+if reader.name() != "#text" or reader.isEmptyElement() != 0 or \
+   reader.nodeType() != 3 or reader.hasAttributes() != 0 or \
+   reader.value() != "content of c":
+    print "Error reading the text node"
+    sys.exit(1)
+ret = reader.read()
+if ret != 1:
+    print "Error reading to end of third element"
+    sys.exit(1)
+if reader.name() != "c" or reader.isEmptyElement() != 0 or \
+   reader.nodeType() != 15 or reader.hasAttributes() != 0:
+    print "Error reading the end of third element"
+    sys.exit(1)
+ret = reader.read()
+if ret != 1:
+    print "Error reading to end of first element"
+    sys.exit(1)
+if reader.name() != "a" or reader.isEmptyElement() != 0 or \
+   reader.nodeType() != 15 or reader.hasAttributes() != 0:
+    print "Error reading the end of first element"
+    sys.exit(1)
+ret = reader.read()
+if ret != 0:
+    print "Error reading to end of document"
+    sys.exit(1)
+
+#
+# example from the XmlTextReader docs
+#
+f = StringIO.StringIO("""<test xmlns:dt="urn:datatypes" dt:type="int"/>""")
+input = libxml2.inputBuffer(f)
+reader = input.newTextReader()
+
+ret = reader.read()
+if ret != 1:
+    print "Error reading test element"
+    sys.exit(1)
+if reader.getAttributeNo(0) != "urn:datatypes" or \
+   reader.getAttributeNo(1) != "int" or \
+   reader.getAttributeNs("type", "urn:datatypes") != "int" or \
+   reader.getAttribute("dt:type") != "int":
+    print "error reading test attributes"
+    sys.exit(1)
+
+del f
+del input
+del reader
+
+# 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/types.c b/python/types.c
index 3f49028..2c5a13e 100644
--- a/python/types.c
+++ b/python/types.c
@@ -547,3 +547,21 @@
                                      (char *) "xmlRegexpPtr", NULL);
     return (ret);
 }
+
+PyObject *
+libxml_xmlTextReaderPtrWrap(xmlTextReaderPtr reader)
+{
+    PyObject *ret;
+
+#ifdef DEBUG
+    printf("libxml_xmlTextReaderPtrWrap: reader = %p\n", reader);
+#endif
+    if (reader == NULL) {
+        Py_INCREF(Py_None);
+        return (Py_None);
+    }
+    ret =
+        PyCObject_FromVoidPtrAndDesc((void *) reader,
+                                     (char *) "xmlTextReaderPtr", NULL);
+    return (ret);
+}