diff options
author | Daniel Veillard <veillard@src.gnome.org> | 2004-10-04 10:26:54 +0000 |
---|---|---|
committer | Daniel Veillard <veillard@src.gnome.org> | 2004-10-04 10:26:54 +0000 |
commit | 263ec86a75f7b5ec2d37dbb89356bf7fca11cff3 (patch) | |
tree | 1fd27981e59572018609d3b24fd23c81e924d142 /python | |
parent | 2c22844057be33925a44f0962f712e45b932ebb6 (diff) | |
download | libxml2-263ec86a75f7b5ec2d37dbb89356bf7fca11cff3.tar.gz |
applied patch from Malcolm Tredinnick fixing bug #154294 related to saving
* python/generator.py python/libxml.c python/tests/outbuf.py:
applied patch from Malcolm Tredinnick fixing bug #154294
related to saving to python file objects.
Daniel
Diffstat (limited to 'python')
-rwxr-xr-x | python/generator.py | 10 | ||||
-rw-r--r-- | python/libxml.c | 54 | ||||
-rwxr-xr-x | python/tests/outbuf.py | 116 |
3 files changed, 158 insertions, 22 deletions
diff --git a/python/generator.py b/python/generator.py index df89c4e7..04b3832f 100755 --- a/python/generator.py +++ b/python/generator.py @@ -300,6 +300,13 @@ unknown_types = {} # ####################################################################### +# Class methods which are written by hand in libxml.c but the Python-level +# code is still automatically generated (so they are not in skip_function()). +skip_impl = ( + 'xmlSaveFileTo', + 'xmlSaveFormatFileTo', +) + def skip_function(name): if name[0:12] == "xmlXPathWrap": return 1 @@ -356,6 +363,9 @@ def print_function_wrapper(name, output, export, include): return 0 if skip_function(name) == 1: return 0 + if name in skip_impl: + # Don't delete the function entry in the caller. + return 1 c_call = ""; format="" diff --git a/python/libxml.c b/python/libxml.c index 9e243146..99d9ac3e 100644 --- a/python/libxml.c +++ b/python/libxml.c @@ -512,6 +512,11 @@ libxml_xmlOutputBufferClose(PyObject *self ATTRIBUTE_UNUSED, PyObject *args) { if (!PyArg_ParseTuple(args, (char *)"O:xmlOutputBufferClose", &pyobj_out)) return(NULL); out = (xmlOutputBufferPtr) PyoutputBuffer_Get(pyobj_out); + /* Buffer may already have been destroyed elsewhere. This is harmless. */ + if (out == NULL) { + Py_INCREF(Py_None); + return(Py_None); + } c_retval = xmlOutputBufferClose(out); py_retval = libxml_intWrap((int) c_retval); @@ -533,6 +538,53 @@ libxml_xmlOutputBufferFlush(PyObject *self ATTRIBUTE_UNUSED, PyObject *args) { py_retval = libxml_intWrap((int) c_retval); return(py_retval); } + +static PyObject * +libxml_xmlSaveFileTo(PyObject *self ATTRIBUTE_UNUSED, PyObject *args) { + PyObject *py_retval; + int c_retval; + xmlOutputBufferPtr buf; + PyObject *pyobj_buf; + xmlDocPtr cur; + PyObject *pyobj_cur; + char * encoding; + + if (!PyArg_ParseTuple(args, (char *)"OOz:xmlSaveFileTo", &pyobj_buf, &pyobj_cur, &encoding)) + return(NULL); + buf = (xmlOutputBufferPtr) PyoutputBuffer_Get(pyobj_buf); + cur = (xmlDocPtr) PyxmlNode_Get(pyobj_cur); + + c_retval = xmlSaveFileTo(buf, cur, encoding); + /* xmlSaveTo() freed the memory pointed to by buf, so record that in the + * Python object. */ + ((PyoutputBuffer_Object *)(pyobj_buf))->obj = NULL; + py_retval = libxml_intWrap((int) c_retval); + return(py_retval); +} + +static PyObject * +libxml_xmlSaveFormatFileTo(PyObject *self ATTRIBUTE_UNUSED, PyObject *args) { + PyObject *py_retval; + int c_retval; + xmlOutputBufferPtr buf; + PyObject *pyobj_buf; + xmlDocPtr cur; + PyObject *pyobj_cur; + char * encoding; + int format; + + if (!PyArg_ParseTuple(args, (char *)"OOzi:xmlSaveFormatFileTo", &pyobj_buf, &pyobj_cur, &encoding, &format)) + return(NULL); + buf = (xmlOutputBufferPtr) PyoutputBuffer_Get(pyobj_buf); + cur = (xmlDocPtr) PyxmlNode_Get(pyobj_cur); + + c_retval = xmlSaveFormatFileTo(buf, cur, encoding, format); + /* xmlSaveFormatFileTo() freed the memory pointed to by buf, so record that + * in the Python object */ + ((PyoutputBuffer_Object *)(pyobj_buf))->obj = NULL; + py_retval = libxml_intWrap((int) c_retval); + return(py_retval); +} #endif /* LIBXML_OUTPUT_ENABLED */ @@ -3446,6 +3498,8 @@ static PyMethodDef libxmlMethods[] = { {(char *) "outputBufferGetPythonFile", libxml_outputBufferGetPythonFile, METH_VARARGS, NULL}, {(char *) "xmlOutputBufferClose", libxml_xmlOutputBufferClose, METH_VARARGS, NULL}, { (char *)"xmlOutputBufferFlush", libxml_xmlOutputBufferFlush, METH_VARARGS, NULL }, + { (char *)"xmlSaveFileTo", libxml_xmlSaveFileTo, METH_VARARGS, NULL }, + { (char *)"xmlSaveFormatFileTo", libxml_xmlSaveFormatFileTo, METH_VARARGS, NULL }, #endif /* LIBXML_OUTPUT_ENABLED */ {(char *) "inputBufferCreate", libxml_xmlCreateInputBuffer, METH_VARARGS, NULL}, {(char *) "setEntityLoader", libxml_xmlSetEntityLoader, METH_VARARGS, NULL}, diff --git a/python/tests/outbuf.py b/python/tests/outbuf.py index 4213159f..09cd9b5e 100755 --- a/python/tests/outbuf.py +++ b/python/tests/outbuf.py @@ -3,31 +3,103 @@ import sys import libxml2 import StringIO -#print "Skipped" -#sys.exit(1) +def testSimpleBufferWrites(): + f = StringIO.StringIO() + buf = libxml2.createOutputBuffer(f, "ISO-8859-1") + buf.write(3, "foo") + buf.writeString("bar") + buf.close() + + if f.getvalue() != "foobar": + print "Failed to save to StringIO" + sys.exit(1) -# Memory debug specific -libxml2.debugMemory(1) +def testSaveDocToBuffer(): + """ + Regression test for bug #154294. + """ + input = '<foo>Hello</foo>' + expected = '''\ +<?xml version="1.0" encoding="UTF-8"?> +<foo>Hello</foo> +''' + f = StringIO.StringIO() + buf = libxml2.createOutputBuffer(f, 'UTF-8') + doc = libxml2.parseDoc(input) + doc.saveFileTo(buf, 'UTF-8') + doc.freeDoc() + if f.getvalue() != expected: + print 'xmlDoc.saveFileTo() call failed.' + print ' got: %s' % repr(f.getvalue()) + print 'expected: %s' % repr(expected) + sys.exit(1) -#f = open('res', 'w') -f = StringIO.StringIO() -buf = libxml2.createOutputBuffer(f, "ISO-8859-1") -buf.write(3, "foo") -buf.writeString("bar") -buf.close() +def testSaveFormattedDocToBuffer(): + input = '<outer><inner>Some text</inner><inner/></outer>' + # The formatted and non-formatted versions of the output. + expected = ('''\ +<?xml version="1.0" encoding="UTF-8"?> +<outer><inner>Some text</inner><inner/></outer> +''', '''\ +<?xml version="1.0" encoding="UTF-8"?> +<outer> + <inner>Some text</inner> + <inner/> +</outer> +''') + doc = libxml2.parseDoc(input) + for i in (0, 1): + f = StringIO.StringIO() + buf = libxml2.createOutputBuffer(f, 'UTF-8') + doc.saveFormatFileTo(buf, 'UTF-8', i) + if f.getvalue() != expected[i]: + print 'xmlDoc.saveFormatFileTo() call failed.' + print ' got: %s' % repr(f.getvalue()) + print 'expected: %s' % repr(expected[i]) + sys.exit(1) + doc.freeDoc() -if f.getvalue() != "foobar": - print "Failed to save to StringIO" - sys.exit(1) +def testSaveIntoOutputBuffer(): + """ + Similar to the previous two tests, except this time we invoke the save + methods on the output buffer object and pass in an XML node object. + """ + input = '<foo>Hello</foo>' + expected = '''\ +<?xml version="1.0" encoding="UTF-8"?> +<foo>Hello</foo> +''' + f = StringIO.StringIO() + doc = libxml2.parseDoc(input) + buf = libxml2.createOutputBuffer(f, 'UTF-8') + buf.saveFileTo(doc, 'UTF-8') + if f.getvalue() != expected: + print 'outputBuffer.saveFileTo() call failed.' + print ' got: %s' % repr(f.getvalue()) + print 'expected: %s' % repr(expected) + sys.exit(1) + f = StringIO.StringIO() + buf = libxml2.createOutputBuffer(f, 'UTF-8') + buf.saveFormatFileTo(doc, 'UTF-8', 1) + if f.getvalue() != expected: + print 'outputBuffer.saveFormatFileTo() call failed.' + print ' got: %s' % repr(f.getvalue()) + print 'expected: %s' % repr(expected) + sys.exit(1) + doc.freeDoc() -del buf -del f +if __name__ == '__main__': + # Memory debug specific + libxml2.debugMemory(1) -# Memory debug specific -libxml2.cleanupParser() -if libxml2.debugMemory(1) == 0: - print "OK" -else: - print "Memory leak %d bytes" % (libxml2.debugMemory(1)) - libxml2.dumpMemory() + testSimpleBufferWrites() + testSaveDocToBuffer() + testSaveFormattedDocToBuffer() + testSaveIntoOutputBuffer() + libxml2.cleanupParser() + if libxml2.debugMemory(1) == 0: + print "OK" + else: + print "Memory leak %d bytes" % (libxml2.debugMemory(1)) + libxml2.dumpMemory() |