libxml.c revision 781ac8b19bfc10635a8bb83158f874116fd7559e
13ce5257b293ed75d8feb18ed7ab18ea2b52510bdDaniel Veillard/*
23ce5257b293ed75d8feb18ed7ab18ea2b52510bdDaniel Veillard * libxml.c: this modules implements the main part of the glue of the
33ce5257b293ed75d8feb18ed7ab18ea2b52510bdDaniel Veillard *           libxml2 library and the Python interpreter. It provides the
43ce5257b293ed75d8feb18ed7ab18ea2b52510bdDaniel Veillard *           entry points where an automatically generated stub is either
53ce5257b293ed75d8feb18ed7ab18ea2b52510bdDaniel Veillard *           unpractical or would not match cleanly the Python model.
63ce5257b293ed75d8feb18ed7ab18ea2b52510bdDaniel Veillard *
70fea6f45cd6f158418318c0af922533e44f9c0e2Daniel Veillard * If compiled with MERGED_MODULES, the entry point will be used to
80fea6f45cd6f158418318c0af922533e44f9c0e2Daniel Veillard * initialize both the libxml2 and the libxslt wrappers
90fea6f45cd6f158418318c0af922533e44f9c0e2Daniel Veillard *
103ce5257b293ed75d8feb18ed7ab18ea2b52510bdDaniel Veillard * See Copyright for the status of this software.
113ce5257b293ed75d8feb18ed7ab18ea2b52510bdDaniel Veillard *
123ce5257b293ed75d8feb18ed7ab18ea2b52510bdDaniel Veillard * daniel@veillard.com
133ce5257b293ed75d8feb18ed7ab18ea2b52510bdDaniel Veillard */
14d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard#include <Python.h>
15c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard#include <fileobject.h>
16a1196ed4142269343ac98e698f195966886319e1Daniel Veillard/* #include "config.h" */
17f1d0e6be57b76cf4fb8a7c0612ea5e71cce5c5c2Daniel Veillard#include <libxml/xmlmemory.h>
18d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard#include <libxml/parser.h>
19d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard#include <libxml/tree.h>
20a7340c830e4bddd86201cfdb97ac81e30b0dee62Daniel Veillard#include <libxml/xpath.h>
215d81903b06418c7d8cc72cf9add81c4026a2f3bcDaniel Veillard#include <libxml/xmlerror.h>
22a7340c830e4bddd86201cfdb97ac81e30b0dee62Daniel Veillard#include <libxml/xpathInternals.h>
234e1b26cfeba7f5fad4f8bd12fb5ce7029f930b79Daniel Veillard#include <libxml/xmlmemory.h>
24c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard#include <libxml/xmlIO.h>
25d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard#include "libxml_wrap.h"
2696fe095d4bf3c76301ed58ebe1ba10f8004f87efDaniel Veillard#include "libxml2-py.h"
27d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard
280d132cffc1733447f0fa9624f0265369a7f8c02aDaniel Veillard#if (defined(_MSC_VER) || defined(__MINGW32__)) && !defined(vsnprintf)
290d132cffc1733447f0fa9624f0265369a7f8c02aDaniel Veillard#define vsnprintf(b,c,f,a) _vsnprintf(b,c,f,a)
30e4fa293265c935365717dc9accf6c6ec23d5f22fDaniel Veillard#elif defined(WITH_TRIO)
31e4fa293265c935365717dc9accf6c6ec23d5f22fDaniel Veillard#include "trio.h"
32e4fa293265c935365717dc9accf6c6ec23d5f22fDaniel Veillard#define vsnprintf trio_vsnprintf
330d132cffc1733447f0fa9624f0265369a7f8c02aDaniel Veillard#endif
340d132cffc1733447f0fa9624f0265369a7f8c02aDaniel Veillard
35d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard/* #define DEBUG */
36797a565a2f6a2c0a8480670174e9eaef30d271a4Daniel Veillard/* #define DEBUG_SAX */
37a7340c830e4bddd86201cfdb97ac81e30b0dee62Daniel Veillard/* #define DEBUG_XPATH */
385d81903b06418c7d8cc72cf9add81c4026a2f3bcDaniel Veillard/* #define DEBUG_ERROR */
394e1b26cfeba7f5fad4f8bd12fb5ce7029f930b79Daniel Veillard/* #define DEBUG_MEMORY */
40c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard/* #define DEBUG_FILES */
41c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard/* #define DEBUG_LOADER */
424e1b26cfeba7f5fad4f8bd12fb5ce7029f930b79Daniel Veillard
43d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillardvoid initlibxml2mod(void);
44d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard
45c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard/**
46c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard * TODO:
47c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard *
48c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard * macro to flag unimplemented blocks
49c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard */
50c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard#define TODO 								\
51c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard    xmlGenericError(xmlGenericErrorContext,				\
52c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard	    "Unimplemented block at %s:%d\n",				\
53c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard            __FILE__, __LINE__);
54c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard
554e1b26cfeba7f5fad4f8bd12fb5ce7029f930b79Daniel Veillard/************************************************************************
564e1b26cfeba7f5fad4f8bd12fb5ce7029f930b79Daniel Veillard *									*
574e1b26cfeba7f5fad4f8bd12fb5ce7029f930b79Daniel Veillard *		Memory debug interface					*
584e1b26cfeba7f5fad4f8bd12fb5ce7029f930b79Daniel Veillard *									*
594e1b26cfeba7f5fad4f8bd12fb5ce7029f930b79Daniel Veillard ************************************************************************/
604e1b26cfeba7f5fad4f8bd12fb5ce7029f930b79Daniel Veillard
614e1b26cfeba7f5fad4f8bd12fb5ce7029f930b79Daniel Veillardextern void xmlMemFree(void *ptr);
624e1b26cfeba7f5fad4f8bd12fb5ce7029f930b79Daniel Veillardextern void *xmlMemMalloc(size_t size);
63d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillardextern void *xmlMemRealloc(void *ptr, size_t size);
644e1b26cfeba7f5fad4f8bd12fb5ce7029f930b79Daniel Veillardextern char *xmlMemoryStrdup(const char *str);
654e1b26cfeba7f5fad4f8bd12fb5ce7029f930b79Daniel Veillard
664e1b26cfeba7f5fad4f8bd12fb5ce7029f930b79Daniel Veillardstatic int libxmlMemoryDebugActivated = 0;
674e1b26cfeba7f5fad4f8bd12fb5ce7029f930b79Daniel Veillardstatic long libxmlMemoryAllocatedBase = 0;
684e1b26cfeba7f5fad4f8bd12fb5ce7029f930b79Daniel Veillard
694e1b26cfeba7f5fad4f8bd12fb5ce7029f930b79Daniel Veillardstatic int libxmlMemoryDebug = 0;
704e1b26cfeba7f5fad4f8bd12fb5ce7029f930b79Daniel Veillardstatic xmlFreeFunc freeFunc = NULL;
714e1b26cfeba7f5fad4f8bd12fb5ce7029f930b79Daniel Veillardstatic xmlMallocFunc mallocFunc = NULL;
724e1b26cfeba7f5fad4f8bd12fb5ce7029f930b79Daniel Veillardstatic xmlReallocFunc reallocFunc = NULL;
734e1b26cfeba7f5fad4f8bd12fb5ce7029f930b79Daniel Veillardstatic xmlStrdupFunc strdupFunc = NULL;
744e1b26cfeba7f5fad4f8bd12fb5ce7029f930b79Daniel Veillard
754e1b26cfeba7f5fad4f8bd12fb5ce7029f930b79Daniel VeillardPyObject *
76d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillardlibxml_xmlDebugMemory(ATTRIBUTE_UNUSED PyObject * self, PyObject * args)
77d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard{
784e1b26cfeba7f5fad4f8bd12fb5ce7029f930b79Daniel Veillard    int activate;
794e1b26cfeba7f5fad4f8bd12fb5ce7029f930b79Daniel Veillard    PyObject *py_retval;
804e1b26cfeba7f5fad4f8bd12fb5ce7029f930b79Daniel Veillard    long ret;
814e1b26cfeba7f5fad4f8bd12fb5ce7029f930b79Daniel Veillard
82d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard    if (!PyArg_ParseTuple(args, (char *) "i:xmlDebugMemory", &activate))
83d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        return (NULL);
844e1b26cfeba7f5fad4f8bd12fb5ce7029f930b79Daniel Veillard
854e1b26cfeba7f5fad4f8bd12fb5ce7029f930b79Daniel Veillard#ifdef DEBUG_MEMORY
864e1b26cfeba7f5fad4f8bd12fb5ce7029f930b79Daniel Veillard    printf("libxml_xmlDebugMemory(%d) called\n", activate);
874e1b26cfeba7f5fad4f8bd12fb5ce7029f930b79Daniel Veillard#endif
884e1b26cfeba7f5fad4f8bd12fb5ce7029f930b79Daniel Veillard
894e1b26cfeba7f5fad4f8bd12fb5ce7029f930b79Daniel Veillard    if (activate != 0) {
90d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        if (libxmlMemoryDebug == 0) {
91d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            /*
92d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard             * First initialize the library and grab the old memory handlers
93d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard             * and switch the library to memory debugging
94d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard             */
95d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            xmlMemGet((xmlFreeFunc *) & freeFunc,
96d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard                      (xmlMallocFunc *) & mallocFunc,
97d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard                      (xmlReallocFunc *) & reallocFunc,
98d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard                      (xmlStrdupFunc *) & strdupFunc);
99d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            if ((freeFunc == xmlMemFree) && (mallocFunc == xmlMemMalloc) &&
100d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard                (reallocFunc == xmlMemRealloc) &&
101d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard                (strdupFunc == xmlMemoryStrdup)) {
102d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard                libxmlMemoryAllocatedBase = xmlMemUsed();
103d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            } else {
104d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard                ret = (long) xmlMemSetup(xmlMemFree, xmlMemMalloc,
105d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard                                         xmlMemRealloc, xmlMemoryStrdup);
106d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard                if (ret < 0)
107d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard                    goto error;
108d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard                libxmlMemoryAllocatedBase = xmlMemUsed();
109d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            }
110d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            xmlInitParser();
111d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            ret = 0;
112d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        } else if (libxmlMemoryDebugActivated == 0) {
113d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            libxmlMemoryAllocatedBase = xmlMemUsed();
114d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            ret = 0;
115d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        } else {
116d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            ret = xmlMemUsed() - libxmlMemoryAllocatedBase;
117d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        }
118d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        libxmlMemoryDebug = 1;
119d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        libxmlMemoryDebugActivated = 1;
1204e1b26cfeba7f5fad4f8bd12fb5ce7029f930b79Daniel Veillard    } else {
121d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        if (libxmlMemoryDebugActivated == 1)
122d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            ret = xmlMemUsed() - libxmlMemoryAllocatedBase;
123d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        else
124d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            ret = 0;
125d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        libxmlMemoryDebugActivated = 0;
1264e1b26cfeba7f5fad4f8bd12fb5ce7029f930b79Daniel Veillard    }
127d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard  error:
1284e1b26cfeba7f5fad4f8bd12fb5ce7029f930b79Daniel Veillard    py_retval = libxml_longWrap(ret);
129d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard    return (py_retval);
1304e1b26cfeba7f5fad4f8bd12fb5ce7029f930b79Daniel Veillard}
1314e1b26cfeba7f5fad4f8bd12fb5ce7029f930b79Daniel Veillard
1324e1b26cfeba7f5fad4f8bd12fb5ce7029f930b79Daniel VeillardPyObject *
133d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillardlibxml_xmlDumpMemory(ATTRIBUTE_UNUSED PyObject * self,
134d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard                     ATTRIBUTE_UNUSED PyObject * args)
135d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard{
1364e1b26cfeba7f5fad4f8bd12fb5ce7029f930b79Daniel Veillard
1374e1b26cfeba7f5fad4f8bd12fb5ce7029f930b79Daniel Veillard    if (libxmlMemoryDebug != 0)
138d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        xmlMemoryDump();
1394e1b26cfeba7f5fad4f8bd12fb5ce7029f930b79Daniel Veillard    Py_INCREF(Py_None);
140d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard    return (Py_None);
1414e1b26cfeba7f5fad4f8bd12fb5ce7029f930b79Daniel Veillard}
142d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard
143d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard/************************************************************************
144d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard *									*
145c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard *		Handling Python FILE I/O at the C level			*
146c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard *	The raw I/O attack diectly the File objects, while the		*
147c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard *	other routines address the ioWrapper instance instead		*
148c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard *									*
149c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard ************************************************************************/
150c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard
151c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard/**
152c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard * xmlPythonFileCloseUnref:
153c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard * @context:  the I/O context
154c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard *
155c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard * Close an I/O channel
156c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard */
157c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillardstatic int
158c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel VeillardxmlPythonFileCloseRaw (void * context) {
159c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard    PyObject *file, *ret;
160c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard
161c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard#ifdef DEBUG_FILES
162c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard    printf("xmlPythonFileCloseUnref\n");
163c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard#endif
164c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard    file = (PyObject *) context;
165c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard    if (file == NULL) return(-1);
166118aed78f360f51d182770e62b251ef324707aa2Daniel Veillard    ret = PyEval_CallMethod(file, (char *) "close", (char *) "()");
167c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard    if (ret != NULL) {
168c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard	Py_DECREF(ret);
169c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard    }
170c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard    Py_DECREF(file);
171c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard    return(0);
172c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard}
173c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard
174c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard/**
175c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard * xmlPythonFileReadRaw:
176c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard * @context:  the I/O context
177c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard * @buffer:  where to drop data
178c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard * @len:  number of bytes to write
179c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard *
180c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard * Read @len bytes to @buffer from the Python file in the I/O channel
181c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard *
182c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard * Returns the number of bytes read
183c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard */
184c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillardstatic int
185c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel VeillardxmlPythonFileReadRaw (void * context, char * buffer, int len) {
186c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard    PyObject *file;
187c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard    PyObject *ret;
188c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard    int lenread = -1;
189c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard    char *data;
190c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard
191c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard#ifdef DEBUG_FILES
192c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard    printf("xmlPythonFileReadRaw: %d\n", len);
193c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard#endif
194c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard    file = (PyObject *) context;
195c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard    if (file == NULL) return(-1);
196118aed78f360f51d182770e62b251ef324707aa2Daniel Veillard    ret = PyEval_CallMethod(file, (char *) "read", (char *) "(i)", len);
197c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard    if (ret == NULL) {
198c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard	printf("xmlPythonFileReadRaw: result is NULL\n");
199c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard	return(-1);
200c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard    } else if (PyString_Check(ret)) {
201c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard	lenread = PyString_Size(ret);
202c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard	data = PyString_AsString(ret);
203c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard	if (lenread > len)
204c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard	    memcpy(buffer, data, len);
205c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard	else
206c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard	    memcpy(buffer, data, lenread);
207c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard	Py_DECREF(ret);
208c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard    } else {
209c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard	printf("xmlPythonFileReadRaw: result is not a String\n");
210c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard	Py_DECREF(ret);
211c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard    }
212c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard    return(lenread);
213c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard}
214c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard
215c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard/**
216c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard * xmlPythonFileRead:
217c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard * @context:  the I/O context
218c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard * @buffer:  where to drop data
219c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard * @len:  number of bytes to write
220c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard *
221c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard * Read @len bytes to @buffer from the I/O channel.
222c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard *
223c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard * Returns the number of bytes read
224c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard */
225c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillardstatic int
226c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel VeillardxmlPythonFileRead (void * context, char * buffer, int len) {
227c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard    PyObject *file;
228c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard    PyObject *ret;
229c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard    int lenread = -1;
230c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard    char *data;
231c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard
232c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard#ifdef DEBUG_FILES
233c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard    printf("xmlPythonFileRead: %d\n", len);
234c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard#endif
235c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard    file = (PyObject *) context;
236c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard    if (file == NULL) return(-1);
237118aed78f360f51d182770e62b251ef324707aa2Daniel Veillard    ret = PyEval_CallMethod(file, (char *) "io_read", (char *) "(i)", len);
238c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard    if (ret == NULL) {
239c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard	printf("xmlPythonFileRead: result is NULL\n");
240c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard	return(-1);
241c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard    } else if (PyString_Check(ret)) {
242c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard	lenread = PyString_Size(ret);
243c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard	data = PyString_AsString(ret);
244c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard	if (lenread > len)
245c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard	    memcpy(buffer, data, len);
246c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard	else
247c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard	    memcpy(buffer, data, lenread);
248c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard	Py_DECREF(ret);
249c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard    } else {
250c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard	printf("xmlPythonFileRead: result is not a String\n");
251c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard	Py_DECREF(ret);
252c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard    }
253c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard    return(lenread);
254c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard}
255c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard
256c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard/**
257c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard * xmlFileWrite:
258c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard * @context:  the I/O context
259c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard * @buffer:  where to drop data
260c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard * @len:  number of bytes to write
261c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard *
262c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard * Write @len bytes from @buffer to the I/O channel.
263c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard *
264c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard * Returns the number of bytes written
265c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard */
266c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillardstatic int
267c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel VeillardxmlPythonFileWrite (void * context, const char * buffer, int len) {
268c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard    PyObject *file;
269c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard    PyObject *string;
270c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard    PyObject *ret;
271c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard    int written = -1;
272c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard
273c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard#ifdef DEBUG_FILES
274c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard    printf("xmlPythonFileWrite: %d\n", len);
275c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard#endif
276c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard    file = (PyObject *) context;
277c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard    if (file == NULL) return(-1);
278c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard    string = PyString_FromStringAndSize(buffer, len);
279c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard    if (string == NULL) return(-1);
280118aed78f360f51d182770e62b251ef324707aa2Daniel Veillard    ret = PyEval_CallMethod(file, (char *) "io_write", (char *) "(O)", string);
281c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard    Py_DECREF(string);
282c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard    if (ret == NULL) {
283c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard	printf("xmlPythonFileWrite: result is NULL\n");
284c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard	return(-1);
285c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard    } else if (PyInt_Check(ret)) {
286c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard	written = (int) PyInt_AsLong(ret);
287c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard	Py_DECREF(ret);
288c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard    } else if (ret == Py_None) {
289c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard	written = len;
290c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard	Py_DECREF(ret);
291c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard    } else {
292c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard	printf("xmlPythonFileWrite: result is not an Int nor None\n");
293c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard	Py_DECREF(ret);
294c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard    }
295c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard    return(written);
296c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard}
297c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard
298c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard/**
299c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard * xmlPythonFileClose:
300c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard * @context:  the I/O context
301c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard *
302c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard * Close an I/O channel
303c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard */
304c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillardstatic int
305c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel VeillardxmlPythonFileClose (void * context) {
306c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard    PyObject *file, *ret;
307c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard
308c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard#ifdef DEBUG_FILES
309c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard    printf("xmlPythonFileClose\n");
310c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard#endif
311c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard    file = (PyObject *) context;
312c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard    if (file == NULL) return(-1);
313118aed78f360f51d182770e62b251ef324707aa2Daniel Veillard    ret = PyEval_CallMethod(file, (char *) "io_close", (char *) "()");
314c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard    if (ret != NULL) {
315c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard	Py_DECREF(ret);
316c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard    }
317c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard    return(0);
318c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard}
319c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard
320c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard/**
321c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard * xmlOutputBufferCreatePythonFile:
322c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard * @file:  a PyFile_Type
323c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard * @encoder:  the encoding converter or NULL
324c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard *
325c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard * Create a buffered output for the progressive saving to a PyFile_Type
326c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard * buffered C I/O
327c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard *
328c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard * Returns the new parser output or NULL
329c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard */
330118aed78f360f51d182770e62b251ef324707aa2Daniel Veillardstatic xmlOutputBufferPtr
331c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel VeillardxmlOutputBufferCreatePythonFile(PyObject *file,
332c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard	                        xmlCharEncodingHandlerPtr encoder) {
333c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard    xmlOutputBufferPtr ret;
334c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard
335c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard    if (file == NULL) return(NULL);
336c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard
337c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard    ret = xmlAllocOutputBuffer(encoder);
338c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard    if (ret != NULL) {
339c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard        ret->context = file;
340c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard	/* Py_INCREF(file); */
341c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard	ret->writecallback = xmlPythonFileWrite;
342c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard	ret->closecallback = xmlPythonFileClose;
343c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard    }
344c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard
345c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard    return(ret);
346c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard}
347c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard
348c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel VeillardPyObject *
349c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillardlibxml_xmlCreateOutputBuffer(ATTRIBUTE_UNUSED PyObject *self, PyObject *args) {
350c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard    PyObject *py_retval;
351c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard    PyObject *file;
352c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard    xmlChar  *encoding;
353c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard    xmlCharEncodingHandlerPtr handler = NULL;
354c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard    xmlOutputBufferPtr buffer;
355c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard
356c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard
357c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard    if (!PyArg_ParseTuple(args, (char *)"Oz:xmlOutputBufferCreate",
358c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard		&file, &encoding))
359c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard	return(NULL);
360c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard    if ((encoding != NULL) && (encoding[0] != 0)) {
361118aed78f360f51d182770e62b251ef324707aa2Daniel Veillard	handler = xmlFindCharEncodingHandler((const char *) encoding);
362c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard    }
363c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard    buffer = xmlOutputBufferCreatePythonFile(file, handler);
364c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard    if (buffer == NULL)
365c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard	printf("libxml_xmlCreateOutputBuffer: buffer == NULL\n");
366c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard    py_retval = libxml_xmlOutputBufferPtrWrap(buffer);
367c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard    return(py_retval);
368c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard}
369c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard
370c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard
371c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard/**
372c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard * xmlParserInputBufferCreatePythonFile:
373c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard * @file:  a PyFile_Type
374c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard * @encoder:  the encoding converter or NULL
375c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard *
376c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard * Create a buffered output for the progressive saving to a PyFile_Type
377c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard * buffered C I/O
378c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard *
379c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard * Returns the new parser output or NULL
380c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard */
381118aed78f360f51d182770e62b251ef324707aa2Daniel Veillardstatic xmlParserInputBufferPtr
382c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel VeillardxmlParserInputBufferCreatePythonFile(PyObject *file,
383c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard	                        xmlCharEncoding encoding) {
384c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard    xmlParserInputBufferPtr ret;
385c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard
386c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard    if (file == NULL) return(NULL);
387c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard
388c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard    ret = xmlAllocParserInputBuffer(encoding);
389c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard    if (ret != NULL) {
390c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard        ret->context = file;
391c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard	/* Py_INCREF(file); */
392c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard	ret->readcallback = xmlPythonFileRead;
393c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard	ret->closecallback = xmlPythonFileClose;
394c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard    }
395c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard
396c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard    return(ret);
397c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard}
398c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard
399c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel VeillardPyObject *
400c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillardlibxml_xmlCreateInputBuffer(ATTRIBUTE_UNUSED PyObject *self, PyObject *args) {
401c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard    PyObject *py_retval;
402c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard    PyObject *file;
403c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard    xmlChar  *encoding;
404c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard    xmlCharEncoding enc = XML_CHAR_ENCODING_NONE;
405c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard    xmlParserInputBufferPtr buffer;
406c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard
407c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard
408c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard    if (!PyArg_ParseTuple(args, (char *)"Oz:xmlParserInputBufferCreate",
409c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard		&file, &encoding))
410c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard	return(NULL);
411c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard    if ((encoding != NULL) && (encoding[0] != 0)) {
412118aed78f360f51d182770e62b251ef324707aa2Daniel Veillard	enc = xmlParseCharEncoding((const char *) encoding);
413c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard    }
414c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard    buffer = xmlParserInputBufferCreatePythonFile(file, enc);
415c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard    if (buffer == NULL)
416c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard	printf("libxml_xmlParserInputBufferCreate: buffer == NULL\n");
417c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard    py_retval = libxml_xmlParserInputBufferPtrWrap(buffer);
418c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard    return(py_retval);
419c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard}
420c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard
421c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard/************************************************************************
422c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard *									*
423c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard *		Providing the resolver at the Python level		*
424c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard *									*
425c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard ************************************************************************/
426c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard
427c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillardstatic xmlExternalEntityLoader defaultExternalEntityLoader = NULL;
428c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillardstatic PyObject *pythonExternalEntityLoaderObjext;
429c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard
430c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillardstatic xmlParserInputPtr
431c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel VeillardpythonExternalEntityLoader(const char *URL, const char *ID,
432c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard			   xmlParserCtxtPtr ctxt) {
433c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard    xmlParserInputPtr result = NULL;
434c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard    if (pythonExternalEntityLoaderObjext != NULL) {
435c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard	PyObject *ret;
436c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard	PyObject *ctxtobj;
437c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard
438c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard	ctxtobj = libxml_xmlParserCtxtPtrWrap(ctxt);
439c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard#ifdef DEBUG_LOADER
440c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard	printf("pythonExternalEntityLoader: ready to call\n");
441c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard#endif
442c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard
443c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard	ret = PyObject_CallFunction(pythonExternalEntityLoaderObjext,
444118aed78f360f51d182770e62b251ef324707aa2Daniel Veillard		      (char *) "(ssO)", URL, ID, ctxtobj);
445e4a07e7b77b191d61291d44dffa19b65387e04e4Daniel Veillard	Py_XDECREF(ctxtobj);
446c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard#ifdef DEBUG_LOADER
447c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard	printf("pythonExternalEntityLoader: result ");
448c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard	PyObject_Print(ret, stdout, 0);
449c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard	printf("\n");
450c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard#endif
451c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard
452c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard	if (ret != NULL) {
453118aed78f360f51d182770e62b251ef324707aa2Daniel Veillard	    if (PyObject_HasAttrString(ret, (char *) "read")) {
454c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard		xmlParserInputBufferPtr buf;
455c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard
456c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard		buf = xmlAllocParserInputBuffer(XML_CHAR_ENCODING_NONE);
457c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard		if (buf != NULL) {
458c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard		    buf->context = ret;
459c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard		    buf->readcallback = xmlPythonFileReadRaw;
460c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard		    buf->closecallback = xmlPythonFileCloseRaw;
461c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard		    result = xmlNewIOInputStream(ctxt, buf,
462c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard			                         XML_CHAR_ENCODING_NONE);
463c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard		}
464c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard	    } else {
465c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard		printf("pythonExternalEntityLoader: can't read\n");
466c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard	    }
467c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard	    if (result == NULL) {
468c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard		Py_DECREF(ret);
469c64b8e984c13a0d989dea436c13128b289a4d4d6Daniel Veillard	    } else if (URL != NULL) {
470c64b8e984c13a0d989dea436c13128b289a4d4d6Daniel Veillard		result->filename = xmlStrdup(URL);
471c64b8e984c13a0d989dea436c13128b289a4d4d6Daniel Veillard		result->directory = xmlParserGetDirectory((const char *) URL);
472c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard	    }
473c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard	}
474c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard    }
475c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard    if ((result == NULL) && (defaultExternalEntityLoader != NULL)) {
476c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard	result = defaultExternalEntityLoader(URL, ID, ctxt);
477c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard    }
478c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard    return(result);
479c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard}
480c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard
481c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel VeillardPyObject *
482c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillardlibxml_xmlSetEntityLoader(ATTRIBUTE_UNUSED PyObject *self, PyObject *args) {
483c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard    PyObject *py_retval;
484c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard    PyObject *loader;
485c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard
486c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard    if (!PyArg_ParseTuple(args, (char *)"O:libxml_xmlSetEntityLoader",
487c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard		&loader))
488c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard	return(NULL);
489c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard
490c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard#ifdef DEBUG_LOADER
491c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard    printf("libxml_xmlSetEntityLoader\n");
492c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard#endif
493c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard    if (defaultExternalEntityLoader == NULL)
494c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard	defaultExternalEntityLoader = xmlGetExternalEntityLoader();
495c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard
496c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard    pythonExternalEntityLoaderObjext = loader;
497c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard    xmlSetExternalEntityLoader(pythonExternalEntityLoader);
498c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard
499c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard    py_retval = PyInt_FromLong(0);
500c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard    return(py_retval);
501c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard}
502c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard
503c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard
504c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard/************************************************************************
505c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard *									*
5063ce5257b293ed75d8feb18ed7ab18ea2b52510bdDaniel Veillard *		Handling SAX/xmllib/sgmlop callback interfaces		*
507d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard *									*
508d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard ************************************************************************/
5091971ee2698cb84c7699c96d3302f00e20d42c0d3Daniel Veillard
51033caa0b8307eccf22010400747830b1967edb292Daniel Veillardstatic void
51133caa0b8307eccf22010400747830b1967edb292Daniel VeillardpythonStartElement(void *user_data, const xmlChar * name,
51233caa0b8307eccf22010400747830b1967edb292Daniel Veillard                   const xmlChar ** attrs)
51333caa0b8307eccf22010400747830b1967edb292Daniel Veillard{
51433caa0b8307eccf22010400747830b1967edb292Daniel Veillard    int i;
51533caa0b8307eccf22010400747830b1967edb292Daniel Veillard    PyObject *handler;
51633caa0b8307eccf22010400747830b1967edb292Daniel Veillard    PyObject *dict;
51733caa0b8307eccf22010400747830b1967edb292Daniel Veillard    PyObject *attrname;
51833caa0b8307eccf22010400747830b1967edb292Daniel Veillard    PyObject *attrvalue;
519d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard    PyObject *result = NULL;
52033caa0b8307eccf22010400747830b1967edb292Daniel Veillard    int type = 0;
52133caa0b8307eccf22010400747830b1967edb292Daniel Veillard
522797a565a2f6a2c0a8480670174e9eaef30d271a4Daniel Veillard#ifdef DEBUG_SAX
523797a565a2f6a2c0a8480670174e9eaef30d271a4Daniel Veillard    printf("pythonStartElement(%s) called\n", name);
524797a565a2f6a2c0a8480670174e9eaef30d271a4Daniel Veillard#endif
52533caa0b8307eccf22010400747830b1967edb292Daniel Veillard    handler = (PyObject *) user_data;
526d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard    if (PyObject_HasAttrString(handler, (char *) "startElement"))
52733caa0b8307eccf22010400747830b1967edb292Daniel Veillard        type = 1;
528d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard    else if (PyObject_HasAttrString(handler, (char *) "start"))
52933caa0b8307eccf22010400747830b1967edb292Daniel Veillard        type = 2;
53033caa0b8307eccf22010400747830b1967edb292Daniel Veillard    if (type != 0) {
53133caa0b8307eccf22010400747830b1967edb292Daniel Veillard        /*
53233caa0b8307eccf22010400747830b1967edb292Daniel Veillard         * the xmllib interface always generate a dictionnary,
53333caa0b8307eccf22010400747830b1967edb292Daniel Veillard         * possibly empty
53433caa0b8307eccf22010400747830b1967edb292Daniel Veillard         */
53533caa0b8307eccf22010400747830b1967edb292Daniel Veillard        if ((attrs == NULL) && (type == 1)) {
53633caa0b8307eccf22010400747830b1967edb292Daniel Veillard            Py_XINCREF(Py_None);
53733caa0b8307eccf22010400747830b1967edb292Daniel Veillard            dict = Py_None;
538d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        } else if (attrs == NULL) {
539d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            dict = PyDict_New();
54033caa0b8307eccf22010400747830b1967edb292Daniel Veillard        } else {
54133caa0b8307eccf22010400747830b1967edb292Daniel Veillard            dict = PyDict_New();
54233caa0b8307eccf22010400747830b1967edb292Daniel Veillard            for (i = 0; attrs[i] != NULL; i++) {
543d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard                attrname = PyString_FromString((char *) attrs[i]);
54433caa0b8307eccf22010400747830b1967edb292Daniel Veillard                i++;
54533caa0b8307eccf22010400747830b1967edb292Daniel Veillard                if (attrs[i] != NULL) {
546d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard                    attrvalue = PyString_FromString((char *) attrs[i]);
54733caa0b8307eccf22010400747830b1967edb292Daniel Veillard                } else {
54833caa0b8307eccf22010400747830b1967edb292Daniel Veillard                    Py_XINCREF(Py_None);
54933caa0b8307eccf22010400747830b1967edb292Daniel Veillard                    attrvalue = Py_None;
55033caa0b8307eccf22010400747830b1967edb292Daniel Veillard                }
55133caa0b8307eccf22010400747830b1967edb292Daniel Veillard                PyDict_SetItem(dict, attrname, attrvalue);
55233caa0b8307eccf22010400747830b1967edb292Daniel Veillard            }
55333caa0b8307eccf22010400747830b1967edb292Daniel Veillard        }
55433caa0b8307eccf22010400747830b1967edb292Daniel Veillard
55533caa0b8307eccf22010400747830b1967edb292Daniel Veillard        if (type == 1)
556d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            result = PyObject_CallMethod(handler, (char *) "startElement",
557d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard                                         (char *) "sO", name, dict);
55833caa0b8307eccf22010400747830b1967edb292Daniel Veillard        else if (type == 2)
559d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            result = PyObject_CallMethod(handler, (char *) "start",
560d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard                                         (char *) "sO", name, dict);
561d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        if (PyErr_Occurred())
562d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            PyErr_Print();
56333caa0b8307eccf22010400747830b1967edb292Daniel Veillard        Py_XDECREF(dict);
56433caa0b8307eccf22010400747830b1967edb292Daniel Veillard        Py_XDECREF(result);
56533caa0b8307eccf22010400747830b1967edb292Daniel Veillard    }
56633caa0b8307eccf22010400747830b1967edb292Daniel Veillard}
56733caa0b8307eccf22010400747830b1967edb292Daniel Veillard
56833caa0b8307eccf22010400747830b1967edb292Daniel Veillardstatic void
56933caa0b8307eccf22010400747830b1967edb292Daniel VeillardpythonStartDocument(void *user_data)
57033caa0b8307eccf22010400747830b1967edb292Daniel Veillard{
57133caa0b8307eccf22010400747830b1967edb292Daniel Veillard    PyObject *handler;
57233caa0b8307eccf22010400747830b1967edb292Daniel Veillard    PyObject *result;
57333caa0b8307eccf22010400747830b1967edb292Daniel Veillard
574797a565a2f6a2c0a8480670174e9eaef30d271a4Daniel Veillard#ifdef DEBUG_SAX
575797a565a2f6a2c0a8480670174e9eaef30d271a4Daniel Veillard    printf("pythonStartDocument() called\n");
576797a565a2f6a2c0a8480670174e9eaef30d271a4Daniel Veillard#endif
57733caa0b8307eccf22010400747830b1967edb292Daniel Veillard    handler = (PyObject *) user_data;
578d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard    if (PyObject_HasAttrString(handler, (char *) "startDocument")) {
579d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        result =
580d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            PyObject_CallMethod(handler, (char *) "startDocument", NULL);
581d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        if (PyErr_Occurred())
582d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            PyErr_Print();
58333caa0b8307eccf22010400747830b1967edb292Daniel Veillard        Py_XDECREF(result);
58433caa0b8307eccf22010400747830b1967edb292Daniel Veillard    }
58533caa0b8307eccf22010400747830b1967edb292Daniel Veillard}
58633caa0b8307eccf22010400747830b1967edb292Daniel Veillard
58733caa0b8307eccf22010400747830b1967edb292Daniel Veillardstatic void
58833caa0b8307eccf22010400747830b1967edb292Daniel VeillardpythonEndDocument(void *user_data)
58933caa0b8307eccf22010400747830b1967edb292Daniel Veillard{
59033caa0b8307eccf22010400747830b1967edb292Daniel Veillard    PyObject *handler;
59133caa0b8307eccf22010400747830b1967edb292Daniel Veillard    PyObject *result;
59233caa0b8307eccf22010400747830b1967edb292Daniel Veillard
593797a565a2f6a2c0a8480670174e9eaef30d271a4Daniel Veillard#ifdef DEBUG_SAX
594797a565a2f6a2c0a8480670174e9eaef30d271a4Daniel Veillard    printf("pythonEndDocument() called\n");
595797a565a2f6a2c0a8480670174e9eaef30d271a4Daniel Veillard#endif
59633caa0b8307eccf22010400747830b1967edb292Daniel Veillard    handler = (PyObject *) user_data;
597d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard    if (PyObject_HasAttrString(handler, (char *) "endDocument")) {
598d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        result =
599d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            PyObject_CallMethod(handler, (char *) "endDocument", NULL);
600d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        if (PyErr_Occurred())
601d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            PyErr_Print();
60233caa0b8307eccf22010400747830b1967edb292Daniel Veillard        Py_XDECREF(result);
60333caa0b8307eccf22010400747830b1967edb292Daniel Veillard    }
60433caa0b8307eccf22010400747830b1967edb292Daniel Veillard    /*
60533caa0b8307eccf22010400747830b1967edb292Daniel Veillard     * The reference to the handler is released there
60633caa0b8307eccf22010400747830b1967edb292Daniel Veillard     */
60733caa0b8307eccf22010400747830b1967edb292Daniel Veillard    Py_XDECREF(handler);
60833caa0b8307eccf22010400747830b1967edb292Daniel Veillard}
60933caa0b8307eccf22010400747830b1967edb292Daniel Veillard
61033caa0b8307eccf22010400747830b1967edb292Daniel Veillardstatic void
61133caa0b8307eccf22010400747830b1967edb292Daniel VeillardpythonEndElement(void *user_data, const xmlChar * name)
61233caa0b8307eccf22010400747830b1967edb292Daniel Veillard{
61333caa0b8307eccf22010400747830b1967edb292Daniel Veillard    PyObject *handler;
61433caa0b8307eccf22010400747830b1967edb292Daniel Veillard    PyObject *result;
61533caa0b8307eccf22010400747830b1967edb292Daniel Veillard
616797a565a2f6a2c0a8480670174e9eaef30d271a4Daniel Veillard#ifdef DEBUG_SAX
617797a565a2f6a2c0a8480670174e9eaef30d271a4Daniel Veillard    printf("pythonEndElement(%s) called\n", name);
618797a565a2f6a2c0a8480670174e9eaef30d271a4Daniel Veillard#endif
61933caa0b8307eccf22010400747830b1967edb292Daniel Veillard    handler = (PyObject *) user_data;
620d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard    if (PyObject_HasAttrString(handler, (char *) "endElement")) {
621d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        result = PyObject_CallMethod(handler, (char *) "endElement",
622d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard                                     (char *) "s", name);
623d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        if (PyErr_Occurred())
624d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            PyErr_Print();
62533caa0b8307eccf22010400747830b1967edb292Daniel Veillard        Py_XDECREF(result);
626d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard    } else if (PyObject_HasAttrString(handler, (char *) "end")) {
627d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        result = PyObject_CallMethod(handler, (char *) "end",
628d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard                                     (char *) "s", name);
629d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        if (PyErr_Occurred())
630d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            PyErr_Print();
631797a565a2f6a2c0a8480670174e9eaef30d271a4Daniel Veillard        Py_XDECREF(result);
63233caa0b8307eccf22010400747830b1967edb292Daniel Veillard    }
63333caa0b8307eccf22010400747830b1967edb292Daniel Veillard}
63433caa0b8307eccf22010400747830b1967edb292Daniel Veillard
63533caa0b8307eccf22010400747830b1967edb292Daniel Veillardstatic void
63633caa0b8307eccf22010400747830b1967edb292Daniel VeillardpythonReference(void *user_data, const xmlChar * name)
63733caa0b8307eccf22010400747830b1967edb292Daniel Veillard{
63833caa0b8307eccf22010400747830b1967edb292Daniel Veillard    PyObject *handler;
63933caa0b8307eccf22010400747830b1967edb292Daniel Veillard    PyObject *result;
64033caa0b8307eccf22010400747830b1967edb292Daniel Veillard
641797a565a2f6a2c0a8480670174e9eaef30d271a4Daniel Veillard#ifdef DEBUG_SAX
642797a565a2f6a2c0a8480670174e9eaef30d271a4Daniel Veillard    printf("pythonReference(%s) called\n", name);
643797a565a2f6a2c0a8480670174e9eaef30d271a4Daniel Veillard#endif
64433caa0b8307eccf22010400747830b1967edb292Daniel Veillard    handler = (PyObject *) user_data;
645d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard    if (PyObject_HasAttrString(handler, (char *) "reference")) {
646d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        result = PyObject_CallMethod(handler, (char *) "reference",
647d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard                                     (char *) "s", name);
648d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        if (PyErr_Occurred())
649d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            PyErr_Print();
65033caa0b8307eccf22010400747830b1967edb292Daniel Veillard        Py_XDECREF(result);
65133caa0b8307eccf22010400747830b1967edb292Daniel Veillard    }
65233caa0b8307eccf22010400747830b1967edb292Daniel Veillard}
65333caa0b8307eccf22010400747830b1967edb292Daniel Veillard
65433caa0b8307eccf22010400747830b1967edb292Daniel Veillardstatic void
65533caa0b8307eccf22010400747830b1967edb292Daniel VeillardpythonCharacters(void *user_data, const xmlChar * ch, int len)
65633caa0b8307eccf22010400747830b1967edb292Daniel Veillard{
65733caa0b8307eccf22010400747830b1967edb292Daniel Veillard    PyObject *handler;
658d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard    PyObject *result = NULL;
65933caa0b8307eccf22010400747830b1967edb292Daniel Veillard    int type = 0;
66033caa0b8307eccf22010400747830b1967edb292Daniel Veillard
661797a565a2f6a2c0a8480670174e9eaef30d271a4Daniel Veillard#ifdef DEBUG_SAX
662797a565a2f6a2c0a8480670174e9eaef30d271a4Daniel Veillard    printf("pythonCharacters(%s, %d) called\n", ch, len);
663797a565a2f6a2c0a8480670174e9eaef30d271a4Daniel Veillard#endif
66433caa0b8307eccf22010400747830b1967edb292Daniel Veillard    handler = (PyObject *) user_data;
665d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard    if (PyObject_HasAttrString(handler, (char *) "characters"))
666d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        type = 1;
667d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard    else if (PyObject_HasAttrString(handler, (char *) "data"))
668d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        type = 2;
66933caa0b8307eccf22010400747830b1967edb292Daniel Veillard    if (type != 0) {
670d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        if (type == 1)
671d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            result = PyObject_CallMethod(handler, (char *) "characters",
672d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard                                         (char *) "s#", ch, len);
673d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        else if (type == 2)
674d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            result = PyObject_CallMethod(handler, (char *) "data",
675d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard                                         (char *) "s#", ch, len);
676d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        if (PyErr_Occurred())
677d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            PyErr_Print();
67833caa0b8307eccf22010400747830b1967edb292Daniel Veillard        Py_XDECREF(result);
67933caa0b8307eccf22010400747830b1967edb292Daniel Veillard    }
68033caa0b8307eccf22010400747830b1967edb292Daniel Veillard}
68133caa0b8307eccf22010400747830b1967edb292Daniel Veillard
68233caa0b8307eccf22010400747830b1967edb292Daniel Veillardstatic void
68333caa0b8307eccf22010400747830b1967edb292Daniel VeillardpythonIgnorableWhitespace(void *user_data, const xmlChar * ch, int len)
68433caa0b8307eccf22010400747830b1967edb292Daniel Veillard{
68533caa0b8307eccf22010400747830b1967edb292Daniel Veillard    PyObject *handler;
686d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard    PyObject *result = NULL;
68733caa0b8307eccf22010400747830b1967edb292Daniel Veillard    int type = 0;
68833caa0b8307eccf22010400747830b1967edb292Daniel Veillard
689797a565a2f6a2c0a8480670174e9eaef30d271a4Daniel Veillard#ifdef DEBUG_SAX
690797a565a2f6a2c0a8480670174e9eaef30d271a4Daniel Veillard    printf("pythonIgnorableWhitespace(%s, %d) called\n", ch, len);
691797a565a2f6a2c0a8480670174e9eaef30d271a4Daniel Veillard#endif
69233caa0b8307eccf22010400747830b1967edb292Daniel Veillard    handler = (PyObject *) user_data;
693d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard    if (PyObject_HasAttrString(handler, (char *) "ignorableWhitespace"))
69433caa0b8307eccf22010400747830b1967edb292Daniel Veillard        type = 1;
695d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard    else if (PyObject_HasAttrString(handler, (char *) "data"))
69633caa0b8307eccf22010400747830b1967edb292Daniel Veillard        type = 2;
69733caa0b8307eccf22010400747830b1967edb292Daniel Veillard    if (type != 0) {
69833caa0b8307eccf22010400747830b1967edb292Daniel Veillard        if (type == 1)
69933caa0b8307eccf22010400747830b1967edb292Daniel Veillard            result =
700d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard                PyObject_CallMethod(handler,
701d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard                                    (char *) "ignorableWhitespace",
702d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard                                    (char *) "s#", ch, len);
70333caa0b8307eccf22010400747830b1967edb292Daniel Veillard        else if (type == 2)
704d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            result =
705d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard                PyObject_CallMethod(handler, (char *) "data",
706d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard                                    (char *) "s#", ch, len);
70733caa0b8307eccf22010400747830b1967edb292Daniel Veillard        Py_XDECREF(result);
70833caa0b8307eccf22010400747830b1967edb292Daniel Veillard    }
70933caa0b8307eccf22010400747830b1967edb292Daniel Veillard}
71033caa0b8307eccf22010400747830b1967edb292Daniel Veillard
71133caa0b8307eccf22010400747830b1967edb292Daniel Veillardstatic void
71233caa0b8307eccf22010400747830b1967edb292Daniel VeillardpythonProcessingInstruction(void *user_data,
71333caa0b8307eccf22010400747830b1967edb292Daniel Veillard                            const xmlChar * target, const xmlChar * data)
71433caa0b8307eccf22010400747830b1967edb292Daniel Veillard{
71533caa0b8307eccf22010400747830b1967edb292Daniel Veillard    PyObject *handler;
71633caa0b8307eccf22010400747830b1967edb292Daniel Veillard    PyObject *result;
71733caa0b8307eccf22010400747830b1967edb292Daniel Veillard
718797a565a2f6a2c0a8480670174e9eaef30d271a4Daniel Veillard#ifdef DEBUG_SAX
719797a565a2f6a2c0a8480670174e9eaef30d271a4Daniel Veillard    printf("pythonProcessingInstruction(%s, %s) called\n", target, data);
720797a565a2f6a2c0a8480670174e9eaef30d271a4Daniel Veillard#endif
72133caa0b8307eccf22010400747830b1967edb292Daniel Veillard    handler = (PyObject *) user_data;
722d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard    if (PyObject_HasAttrString(handler, (char *) "processingInstruction")) {
723d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        result = PyObject_CallMethod(handler, (char *)
724d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard                                     "processingInstruction",
725d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard                                     (char *) "ss", target, data);
72633caa0b8307eccf22010400747830b1967edb292Daniel Veillard        Py_XDECREF(result);
72733caa0b8307eccf22010400747830b1967edb292Daniel Veillard    }
72833caa0b8307eccf22010400747830b1967edb292Daniel Veillard}
72933caa0b8307eccf22010400747830b1967edb292Daniel Veillard
73033caa0b8307eccf22010400747830b1967edb292Daniel Veillardstatic void
73133caa0b8307eccf22010400747830b1967edb292Daniel VeillardpythonComment(void *user_data, const xmlChar * value)
73233caa0b8307eccf22010400747830b1967edb292Daniel Veillard{
73333caa0b8307eccf22010400747830b1967edb292Daniel Veillard    PyObject *handler;
73433caa0b8307eccf22010400747830b1967edb292Daniel Veillard    PyObject *result;
73533caa0b8307eccf22010400747830b1967edb292Daniel Veillard
736797a565a2f6a2c0a8480670174e9eaef30d271a4Daniel Veillard#ifdef DEBUG_SAX
737797a565a2f6a2c0a8480670174e9eaef30d271a4Daniel Veillard    printf("pythonComment(%s) called\n", value);
738797a565a2f6a2c0a8480670174e9eaef30d271a4Daniel Veillard#endif
73933caa0b8307eccf22010400747830b1967edb292Daniel Veillard    handler = (PyObject *) user_data;
740d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard    if (PyObject_HasAttrString(handler, (char *) "comment")) {
741d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        result =
742d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            PyObject_CallMethod(handler, (char *) "comment", (char *) "s",
743d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard                                value);
744d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        if (PyErr_Occurred())
745d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            PyErr_Print();
74633caa0b8307eccf22010400747830b1967edb292Daniel Veillard        Py_XDECREF(result);
74733caa0b8307eccf22010400747830b1967edb292Daniel Veillard    }
74833caa0b8307eccf22010400747830b1967edb292Daniel Veillard}
74933caa0b8307eccf22010400747830b1967edb292Daniel Veillard
75033caa0b8307eccf22010400747830b1967edb292Daniel Veillardstatic void
75133caa0b8307eccf22010400747830b1967edb292Daniel VeillardpythonWarning(void *user_data, const char *msg, ...)
75233caa0b8307eccf22010400747830b1967edb292Daniel Veillard{
75333caa0b8307eccf22010400747830b1967edb292Daniel Veillard    PyObject *handler;
75433caa0b8307eccf22010400747830b1967edb292Daniel Veillard    PyObject *result;
75533caa0b8307eccf22010400747830b1967edb292Daniel Veillard    va_list args;
75633caa0b8307eccf22010400747830b1967edb292Daniel Veillard    char buf[1024];
75733caa0b8307eccf22010400747830b1967edb292Daniel Veillard
758797a565a2f6a2c0a8480670174e9eaef30d271a4Daniel Veillard#ifdef DEBUG_SAX
759797a565a2f6a2c0a8480670174e9eaef30d271a4Daniel Veillard    printf("pythonWarning(%s) called\n", msg);
760797a565a2f6a2c0a8480670174e9eaef30d271a4Daniel Veillard#endif
76133caa0b8307eccf22010400747830b1967edb292Daniel Veillard    handler = (PyObject *) user_data;
762d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard    if (PyObject_HasAttrString(handler, (char *) "warning")) {
76333caa0b8307eccf22010400747830b1967edb292Daniel Veillard        va_start(args, msg);
76433caa0b8307eccf22010400747830b1967edb292Daniel Veillard        vsnprintf(buf, 1023, msg, args);
765d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        va_end(args);
766d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        buf[1023] = 0;
767d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        result =
768d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            PyObject_CallMethod(handler, (char *) "warning", (char *) "s",
769d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard                                buf);
770d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        if (PyErr_Occurred())
771d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            PyErr_Print();
77233caa0b8307eccf22010400747830b1967edb292Daniel Veillard        Py_XDECREF(result);
77333caa0b8307eccf22010400747830b1967edb292Daniel Veillard    }
77433caa0b8307eccf22010400747830b1967edb292Daniel Veillard}
77533caa0b8307eccf22010400747830b1967edb292Daniel Veillard
77633caa0b8307eccf22010400747830b1967edb292Daniel Veillardstatic void
77733caa0b8307eccf22010400747830b1967edb292Daniel VeillardpythonError(void *user_data, const char *msg, ...)
77833caa0b8307eccf22010400747830b1967edb292Daniel Veillard{
77933caa0b8307eccf22010400747830b1967edb292Daniel Veillard    PyObject *handler;
78033caa0b8307eccf22010400747830b1967edb292Daniel Veillard    PyObject *result;
78133caa0b8307eccf22010400747830b1967edb292Daniel Veillard    va_list args;
78233caa0b8307eccf22010400747830b1967edb292Daniel Veillard    char buf[1024];
78333caa0b8307eccf22010400747830b1967edb292Daniel Veillard
784797a565a2f6a2c0a8480670174e9eaef30d271a4Daniel Veillard#ifdef DEBUG_SAX
785797a565a2f6a2c0a8480670174e9eaef30d271a4Daniel Veillard    printf("pythonError(%s) called\n", msg);
786797a565a2f6a2c0a8480670174e9eaef30d271a4Daniel Veillard#endif
78733caa0b8307eccf22010400747830b1967edb292Daniel Veillard    handler = (PyObject *) user_data;
788d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard    if (PyObject_HasAttrString(handler, (char *) "error")) {
78933caa0b8307eccf22010400747830b1967edb292Daniel Veillard        va_start(args, msg);
79033caa0b8307eccf22010400747830b1967edb292Daniel Veillard        vsnprintf(buf, 1023, msg, args);
791d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        va_end(args);
792d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        buf[1023] = 0;
793d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        result =
794d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            PyObject_CallMethod(handler, (char *) "error", (char *) "s",
795d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard                                buf);
796d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        if (PyErr_Occurred())
797d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            PyErr_Print();
79833caa0b8307eccf22010400747830b1967edb292Daniel Veillard        Py_XDECREF(result);
79933caa0b8307eccf22010400747830b1967edb292Daniel Veillard    }
80033caa0b8307eccf22010400747830b1967edb292Daniel Veillard}
80133caa0b8307eccf22010400747830b1967edb292Daniel Veillard
80233caa0b8307eccf22010400747830b1967edb292Daniel Veillardstatic void
80333caa0b8307eccf22010400747830b1967edb292Daniel VeillardpythonFatalError(void *user_data, const char *msg, ...)
80433caa0b8307eccf22010400747830b1967edb292Daniel Veillard{
80533caa0b8307eccf22010400747830b1967edb292Daniel Veillard    PyObject *handler;
80633caa0b8307eccf22010400747830b1967edb292Daniel Veillard    PyObject *result;
80733caa0b8307eccf22010400747830b1967edb292Daniel Veillard    va_list args;
80833caa0b8307eccf22010400747830b1967edb292Daniel Veillard    char buf[1024];
80933caa0b8307eccf22010400747830b1967edb292Daniel Veillard
810797a565a2f6a2c0a8480670174e9eaef30d271a4Daniel Veillard#ifdef DEBUG_SAX
811797a565a2f6a2c0a8480670174e9eaef30d271a4Daniel Veillard    printf("pythonFatalError(%s) called\n", msg);
812797a565a2f6a2c0a8480670174e9eaef30d271a4Daniel Veillard#endif
81333caa0b8307eccf22010400747830b1967edb292Daniel Veillard    handler = (PyObject *) user_data;
814d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard    if (PyObject_HasAttrString(handler, (char *) "fatalError")) {
81533caa0b8307eccf22010400747830b1967edb292Daniel Veillard        va_start(args, msg);
81633caa0b8307eccf22010400747830b1967edb292Daniel Veillard        vsnprintf(buf, 1023, msg, args);
817d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        va_end(args);
818d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        buf[1023] = 0;
819d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        result =
820d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            PyObject_CallMethod(handler, (char *) "fatalError",
821d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard                                (char *) "s", buf);
822d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        if (PyErr_Occurred())
823d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            PyErr_Print();
82433caa0b8307eccf22010400747830b1967edb292Daniel Veillard        Py_XDECREF(result);
82533caa0b8307eccf22010400747830b1967edb292Daniel Veillard    }
82633caa0b8307eccf22010400747830b1967edb292Daniel Veillard}
82733caa0b8307eccf22010400747830b1967edb292Daniel Veillard
82833caa0b8307eccf22010400747830b1967edb292Daniel Veillardstatic void
82933caa0b8307eccf22010400747830b1967edb292Daniel VeillardpythonCdataBlock(void *user_data, const xmlChar * ch, int len)
83033caa0b8307eccf22010400747830b1967edb292Daniel Veillard{
83133caa0b8307eccf22010400747830b1967edb292Daniel Veillard    PyObject *handler;
832d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard    PyObject *result = NULL;
83333caa0b8307eccf22010400747830b1967edb292Daniel Veillard    int type = 0;
83433caa0b8307eccf22010400747830b1967edb292Daniel Veillard
835797a565a2f6a2c0a8480670174e9eaef30d271a4Daniel Veillard#ifdef DEBUG_SAX
836797a565a2f6a2c0a8480670174e9eaef30d271a4Daniel Veillard    printf("pythonCdataBlock(%s, %d) called\n", ch, len);
837797a565a2f6a2c0a8480670174e9eaef30d271a4Daniel Veillard#endif
83833caa0b8307eccf22010400747830b1967edb292Daniel Veillard    handler = (PyObject *) user_data;
839d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard    if (PyObject_HasAttrString(handler, (char *) "cdataBlock"))
840d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        type = 1;
841d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard    else if (PyObject_HasAttrString(handler, (char *) "cdata"))
842d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        type = 2;
84333caa0b8307eccf22010400747830b1967edb292Daniel Veillard    if (type != 0) {
844d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        if (type == 1)
845d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            result =
846d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard                PyObject_CallMethod(handler, (char *) "cdataBlock",
847d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard                                    (char *) "s#", ch, len);
848d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        else if (type == 2)
849d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            result =
850d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard                PyObject_CallMethod(handler, (char *) "cdata",
851d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard                                    (char *) "s#", ch, len);
852d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        if (PyErr_Occurred())
853d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            PyErr_Print();
85433caa0b8307eccf22010400747830b1967edb292Daniel Veillard        Py_XDECREF(result);
85533caa0b8307eccf22010400747830b1967edb292Daniel Veillard    }
85633caa0b8307eccf22010400747830b1967edb292Daniel Veillard}
85733caa0b8307eccf22010400747830b1967edb292Daniel Veillard
85833caa0b8307eccf22010400747830b1967edb292Daniel Veillardstatic void
85933caa0b8307eccf22010400747830b1967edb292Daniel VeillardpythonExternalSubset(void *user_data,
86033caa0b8307eccf22010400747830b1967edb292Daniel Veillard                     const xmlChar * name,
86133caa0b8307eccf22010400747830b1967edb292Daniel Veillard                     const xmlChar * externalID, const xmlChar * systemID)
86233caa0b8307eccf22010400747830b1967edb292Daniel Veillard{
86333caa0b8307eccf22010400747830b1967edb292Daniel Veillard    PyObject *handler;
86433caa0b8307eccf22010400747830b1967edb292Daniel Veillard    PyObject *result;
86533caa0b8307eccf22010400747830b1967edb292Daniel Veillard
866797a565a2f6a2c0a8480670174e9eaef30d271a4Daniel Veillard#ifdef DEBUG_SAX
867797a565a2f6a2c0a8480670174e9eaef30d271a4Daniel Veillard    printf("pythonExternalSubset(%s, %s, %s) called\n",
868d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard           name, externalID, systemID);
869797a565a2f6a2c0a8480670174e9eaef30d271a4Daniel Veillard#endif
87033caa0b8307eccf22010400747830b1967edb292Daniel Veillard    handler = (PyObject *) user_data;
871d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard    if (PyObject_HasAttrString(handler, (char *) "externalSubset")) {
87233caa0b8307eccf22010400747830b1967edb292Daniel Veillard        result =
873d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            PyObject_CallMethod(handler, (char *) "externalSubset",
874d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard                                (char *) "sss", name, externalID,
875d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard                                systemID);
87633caa0b8307eccf22010400747830b1967edb292Daniel Veillard        Py_XDECREF(result);
87733caa0b8307eccf22010400747830b1967edb292Daniel Veillard    }
87833caa0b8307eccf22010400747830b1967edb292Daniel Veillard}
87933caa0b8307eccf22010400747830b1967edb292Daniel Veillard
88033caa0b8307eccf22010400747830b1967edb292Daniel Veillardstatic void
88133caa0b8307eccf22010400747830b1967edb292Daniel VeillardpythonEntityDecl(void *user_data,
88233caa0b8307eccf22010400747830b1967edb292Daniel Veillard                 const xmlChar * name,
88333caa0b8307eccf22010400747830b1967edb292Daniel Veillard                 int type,
88433caa0b8307eccf22010400747830b1967edb292Daniel Veillard                 const xmlChar * publicId,
88533caa0b8307eccf22010400747830b1967edb292Daniel Veillard                 const xmlChar * systemId, xmlChar * content)
88633caa0b8307eccf22010400747830b1967edb292Daniel Veillard{
88733caa0b8307eccf22010400747830b1967edb292Daniel Veillard    PyObject *handler;
88833caa0b8307eccf22010400747830b1967edb292Daniel Veillard    PyObject *result;
88933caa0b8307eccf22010400747830b1967edb292Daniel Veillard
89033caa0b8307eccf22010400747830b1967edb292Daniel Veillard    handler = (PyObject *) user_data;
891d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard    if (PyObject_HasAttrString(handler, (char *) "entityDecl")) {
892d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        result = PyObject_CallMethod(handler, (char *) "entityDecl",
893d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard                                     (char *) "sisss", name, type,
894d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard                                     publicId, systemId, content);
895d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        if (PyErr_Occurred())
896d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            PyErr_Print();
89733caa0b8307eccf22010400747830b1967edb292Daniel Veillard        Py_XDECREF(result);
89833caa0b8307eccf22010400747830b1967edb292Daniel Veillard    }
89933caa0b8307eccf22010400747830b1967edb292Daniel Veillard}
90033caa0b8307eccf22010400747830b1967edb292Daniel Veillard
90133caa0b8307eccf22010400747830b1967edb292Daniel Veillard
90233caa0b8307eccf22010400747830b1967edb292Daniel Veillard
90333caa0b8307eccf22010400747830b1967edb292Daniel Veillardstatic void
90433caa0b8307eccf22010400747830b1967edb292Daniel Veillard
90533caa0b8307eccf22010400747830b1967edb292Daniel VeillardpythonNotationDecl(void *user_data,
90633caa0b8307eccf22010400747830b1967edb292Daniel Veillard                   const xmlChar * name,
90733caa0b8307eccf22010400747830b1967edb292Daniel Veillard                   const xmlChar * publicId, const xmlChar * systemId)
90833caa0b8307eccf22010400747830b1967edb292Daniel Veillard{
90933caa0b8307eccf22010400747830b1967edb292Daniel Veillard    PyObject *handler;
91033caa0b8307eccf22010400747830b1967edb292Daniel Veillard    PyObject *result;
91133caa0b8307eccf22010400747830b1967edb292Daniel Veillard
91233caa0b8307eccf22010400747830b1967edb292Daniel Veillard    handler = (PyObject *) user_data;
913d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard    if (PyObject_HasAttrString(handler, (char *) "notationDecl")) {
914d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        result = PyObject_CallMethod(handler, (char *) "notationDecl",
915d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard                                     (char *) "sss", name, publicId,
916d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard                                     systemId);
917d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        if (PyErr_Occurred())
918d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            PyErr_Print();
91933caa0b8307eccf22010400747830b1967edb292Daniel Veillard        Py_XDECREF(result);
92033caa0b8307eccf22010400747830b1967edb292Daniel Veillard    }
92133caa0b8307eccf22010400747830b1967edb292Daniel Veillard}
92233caa0b8307eccf22010400747830b1967edb292Daniel Veillard
92333caa0b8307eccf22010400747830b1967edb292Daniel Veillardstatic void
92433caa0b8307eccf22010400747830b1967edb292Daniel VeillardpythonAttributeDecl(void *user_data,
92533caa0b8307eccf22010400747830b1967edb292Daniel Veillard                    const xmlChar * elem,
92633caa0b8307eccf22010400747830b1967edb292Daniel Veillard                    const xmlChar * name,
92733caa0b8307eccf22010400747830b1967edb292Daniel Veillard                    int type,
92833caa0b8307eccf22010400747830b1967edb292Daniel Veillard                    int def,
929d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard                    const xmlChar * defaultValue, xmlEnumerationPtr tree)
93033caa0b8307eccf22010400747830b1967edb292Daniel Veillard{
93133caa0b8307eccf22010400747830b1967edb292Daniel Veillard    PyObject *handler;
93233caa0b8307eccf22010400747830b1967edb292Daniel Veillard    PyObject *nameList;
93333caa0b8307eccf22010400747830b1967edb292Daniel Veillard    PyObject *newName;
93433caa0b8307eccf22010400747830b1967edb292Daniel Veillard    xmlEnumerationPtr node;
93533caa0b8307eccf22010400747830b1967edb292Daniel Veillard    PyObject *result;
93633caa0b8307eccf22010400747830b1967edb292Daniel Veillard    int count;
93733caa0b8307eccf22010400747830b1967edb292Daniel Veillard
93833caa0b8307eccf22010400747830b1967edb292Daniel Veillard    handler = (PyObject *) user_data;
939d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard    if (PyObject_HasAttrString(handler, (char *) "attributeDecl")) {
94033caa0b8307eccf22010400747830b1967edb292Daniel Veillard        count = 0;
94133caa0b8307eccf22010400747830b1967edb292Daniel Veillard        for (node = tree; node != NULL; node = node->next) {
94233caa0b8307eccf22010400747830b1967edb292Daniel Veillard            count++;
94333caa0b8307eccf22010400747830b1967edb292Daniel Veillard        }
94433caa0b8307eccf22010400747830b1967edb292Daniel Veillard        nameList = PyList_New(count);
94533caa0b8307eccf22010400747830b1967edb292Daniel Veillard        count = 0;
94633caa0b8307eccf22010400747830b1967edb292Daniel Veillard        for (node = tree; node != NULL; node = node->next) {
947d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            newName = PyString_FromString((char *) node->name);
94833caa0b8307eccf22010400747830b1967edb292Daniel Veillard            PyList_SetItem(nameList, count, newName);
94933caa0b8307eccf22010400747830b1967edb292Daniel Veillard            count++;
95033caa0b8307eccf22010400747830b1967edb292Daniel Veillard        }
951d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        result = PyObject_CallMethod(handler, (char *) "attributeDecl",
952d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard                                     (char *) "ssiisO", elem, name, type,
953d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard                                     def, defaultValue, nameList);
954d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        if (PyErr_Occurred())
955d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            PyErr_Print();
95633caa0b8307eccf22010400747830b1967edb292Daniel Veillard        Py_XDECREF(nameList);
95733caa0b8307eccf22010400747830b1967edb292Daniel Veillard        Py_XDECREF(result);
95833caa0b8307eccf22010400747830b1967edb292Daniel Veillard    }
95933caa0b8307eccf22010400747830b1967edb292Daniel Veillard}
96033caa0b8307eccf22010400747830b1967edb292Daniel Veillard
96133caa0b8307eccf22010400747830b1967edb292Daniel Veillardstatic void
96233caa0b8307eccf22010400747830b1967edb292Daniel VeillardpythonElementDecl(void *user_data,
96333caa0b8307eccf22010400747830b1967edb292Daniel Veillard                  const xmlChar * name,
964d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard                  int type, ATTRIBUTE_UNUSED xmlElementContentPtr content)
96533caa0b8307eccf22010400747830b1967edb292Daniel Veillard{
96633caa0b8307eccf22010400747830b1967edb292Daniel Veillard    PyObject *handler;
96733caa0b8307eccf22010400747830b1967edb292Daniel Veillard    PyObject *obj;
96833caa0b8307eccf22010400747830b1967edb292Daniel Veillard    PyObject *result;
96933caa0b8307eccf22010400747830b1967edb292Daniel Veillard
97033caa0b8307eccf22010400747830b1967edb292Daniel Veillard    handler = (PyObject *) user_data;
971d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard    if (PyObject_HasAttrString(handler, (char *) "elementDecl")) {
972d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        /* TODO: wrap in an elementContent object */
973d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        printf
974d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            ("pythonElementDecl: xmlElementContentPtr wrapper missing !\n");
975d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        obj = Py_None;
976d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        /* Py_XINCREF(Py_None); isn't the reference just borrowed ??? */
977d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        result = PyObject_CallMethod(handler, (char *) "elementDecl",
978d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard                                     (char *) "siO", name, type, obj);
979d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        if (PyErr_Occurred())
980d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            PyErr_Print();
98133caa0b8307eccf22010400747830b1967edb292Daniel Veillard        Py_XDECREF(result);
98233caa0b8307eccf22010400747830b1967edb292Daniel Veillard    }
98333caa0b8307eccf22010400747830b1967edb292Daniel Veillard}
98433caa0b8307eccf22010400747830b1967edb292Daniel Veillard
98533caa0b8307eccf22010400747830b1967edb292Daniel Veillardstatic void
98633caa0b8307eccf22010400747830b1967edb292Daniel VeillardpythonUnparsedEntityDecl(void *user_data,
98733caa0b8307eccf22010400747830b1967edb292Daniel Veillard                         const xmlChar * name,
98833caa0b8307eccf22010400747830b1967edb292Daniel Veillard                         const xmlChar * publicId,
98933caa0b8307eccf22010400747830b1967edb292Daniel Veillard                         const xmlChar * systemId,
99033caa0b8307eccf22010400747830b1967edb292Daniel Veillard                         const xmlChar * notationName)
99133caa0b8307eccf22010400747830b1967edb292Daniel Veillard{
99233caa0b8307eccf22010400747830b1967edb292Daniel Veillard    PyObject *handler;
99333caa0b8307eccf22010400747830b1967edb292Daniel Veillard    PyObject *result;
99433caa0b8307eccf22010400747830b1967edb292Daniel Veillard
99533caa0b8307eccf22010400747830b1967edb292Daniel Veillard    handler = (PyObject *) user_data;
996d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard    if (PyObject_HasAttrString(handler, (char *) "unparsedEntityDecl")) {
997d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        result =
998d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            PyObject_CallMethod(handler, (char *) "unparsedEntityDecl",
999d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard                                (char *) "ssss", name, publicId, systemId,
1000d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard                                notationName);
1001d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        if (PyErr_Occurred())
1002d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            PyErr_Print();
100333caa0b8307eccf22010400747830b1967edb292Daniel Veillard        Py_XDECREF(result);
100433caa0b8307eccf22010400747830b1967edb292Daniel Veillard    }
100533caa0b8307eccf22010400747830b1967edb292Daniel Veillard}
100633caa0b8307eccf22010400747830b1967edb292Daniel Veillard
100733caa0b8307eccf22010400747830b1967edb292Daniel Veillardstatic void
100833caa0b8307eccf22010400747830b1967edb292Daniel VeillardpythonInternalSubset(void *user_data, const xmlChar * name,
100933caa0b8307eccf22010400747830b1967edb292Daniel Veillard                     const xmlChar * ExternalID, const xmlChar * SystemID)
101033caa0b8307eccf22010400747830b1967edb292Daniel Veillard{
101133caa0b8307eccf22010400747830b1967edb292Daniel Veillard    PyObject *handler;
101233caa0b8307eccf22010400747830b1967edb292Daniel Veillard    PyObject *result;
101333caa0b8307eccf22010400747830b1967edb292Daniel Veillard
1014797a565a2f6a2c0a8480670174e9eaef30d271a4Daniel Veillard#ifdef DEBUG_SAX
1015797a565a2f6a2c0a8480670174e9eaef30d271a4Daniel Veillard    printf("pythonInternalSubset(%s, %s, %s) called\n",
1016d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard           name, ExternalID, SystemID);
1017797a565a2f6a2c0a8480670174e9eaef30d271a4Daniel Veillard#endif
101833caa0b8307eccf22010400747830b1967edb292Daniel Veillard    handler = (PyObject *) user_data;
1019d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard    if (PyObject_HasAttrString(handler, (char *) "internalSubset")) {
1020d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        result = PyObject_CallMethod(handler, (char *) "internalSubset",
1021d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard                                     (char *) "sss", name, ExternalID,
1022d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard                                     SystemID);
1023d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        if (PyErr_Occurred())
1024d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            PyErr_Print();
102533caa0b8307eccf22010400747830b1967edb292Daniel Veillard        Py_XDECREF(result);
102633caa0b8307eccf22010400747830b1967edb292Daniel Veillard    }
102733caa0b8307eccf22010400747830b1967edb292Daniel Veillard}
102833caa0b8307eccf22010400747830b1967edb292Daniel Veillard
102933caa0b8307eccf22010400747830b1967edb292Daniel Veillardstatic xmlSAXHandler pythonSaxHandler = {
103033caa0b8307eccf22010400747830b1967edb292Daniel Veillard    pythonInternalSubset,
1031d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard    NULL,                       /* TODO pythonIsStandalone, */
1032d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard    NULL,                       /* TODO pythonHasInternalSubset, */
1033d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard    NULL,                       /* TODO pythonHasExternalSubset, */
1034d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard    NULL,                       /* TODO pythonResolveEntity, */
1035d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard    NULL,                       /* TODO pythonGetEntity, */
103633caa0b8307eccf22010400747830b1967edb292Daniel Veillard    pythonEntityDecl,
103733caa0b8307eccf22010400747830b1967edb292Daniel Veillard    pythonNotationDecl,
103833caa0b8307eccf22010400747830b1967edb292Daniel Veillard    pythonAttributeDecl,
103933caa0b8307eccf22010400747830b1967edb292Daniel Veillard    pythonElementDecl,
104033caa0b8307eccf22010400747830b1967edb292Daniel Veillard    pythonUnparsedEntityDecl,
1041d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard    NULL,                       /* OBSOLETED pythonSetDocumentLocator, */
104233caa0b8307eccf22010400747830b1967edb292Daniel Veillard    pythonStartDocument,
104333caa0b8307eccf22010400747830b1967edb292Daniel Veillard    pythonEndDocument,
104433caa0b8307eccf22010400747830b1967edb292Daniel Veillard    pythonStartElement,
104533caa0b8307eccf22010400747830b1967edb292Daniel Veillard    pythonEndElement,
104633caa0b8307eccf22010400747830b1967edb292Daniel Veillard    pythonReference,
104733caa0b8307eccf22010400747830b1967edb292Daniel Veillard    pythonCharacters,
104833caa0b8307eccf22010400747830b1967edb292Daniel Veillard    pythonIgnorableWhitespace,
104933caa0b8307eccf22010400747830b1967edb292Daniel Veillard    pythonProcessingInstruction,
105033caa0b8307eccf22010400747830b1967edb292Daniel Veillard    pythonComment,
105133caa0b8307eccf22010400747830b1967edb292Daniel Veillard    pythonWarning,
105233caa0b8307eccf22010400747830b1967edb292Daniel Veillard    pythonError,
105333caa0b8307eccf22010400747830b1967edb292Daniel Veillard    pythonFatalError,
1054d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard    NULL,                       /* TODO pythonGetParameterEntity, */
105533caa0b8307eccf22010400747830b1967edb292Daniel Veillard    pythonCdataBlock,
105633caa0b8307eccf22010400747830b1967edb292Daniel Veillard    pythonExternalSubset,
105733caa0b8307eccf22010400747830b1967edb292Daniel Veillard    1
105833caa0b8307eccf22010400747830b1967edb292Daniel Veillard};
1059d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard
10603ce5257b293ed75d8feb18ed7ab18ea2b52510bdDaniel Veillard/************************************************************************
10613ce5257b293ed75d8feb18ed7ab18ea2b52510bdDaniel Veillard *									*
10623ce5257b293ed75d8feb18ed7ab18ea2b52510bdDaniel Veillard *		Handling of specific parser context			*
10633ce5257b293ed75d8feb18ed7ab18ea2b52510bdDaniel Veillard *									*
10643ce5257b293ed75d8feb18ed7ab18ea2b52510bdDaniel Veillard ************************************************************************/
10651971ee2698cb84c7699c96d3302f00e20d42c0d3Daniel Veillard
10661971ee2698cb84c7699c96d3302f00e20d42c0d3Daniel VeillardPyObject *
1067d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillardlibxml_xmlCreatePushParser(ATTRIBUTE_UNUSED PyObject * self,
1068d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard                           PyObject * args)
1069d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard{
1070d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard    const char *chunk;
10713ce5257b293ed75d8feb18ed7ab18ea2b52510bdDaniel Veillard    int size;
1072d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard    const char *URI;
107333caa0b8307eccf22010400747830b1967edb292Daniel Veillard    PyObject *pyobj_SAX = NULL;
10743ce5257b293ed75d8feb18ed7ab18ea2b52510bdDaniel Veillard    xmlSAXHandlerPtr SAX = NULL;
10753ce5257b293ed75d8feb18ed7ab18ea2b52510bdDaniel Veillard    xmlParserCtxtPtr ret;
10763ce5257b293ed75d8feb18ed7ab18ea2b52510bdDaniel Veillard    PyObject *pyret;
10773ce5257b293ed75d8feb18ed7ab18ea2b52510bdDaniel Veillard
1078d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard    if (!PyArg_ParseTuple
1079d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        (args, (char *) "Oziz:xmlCreatePushParser", &pyobj_SAX, &chunk,
1080d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard         &size, &URI))
1081d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        return (NULL);
10821971ee2698cb84c7699c96d3302f00e20d42c0d3Daniel Veillard
10838d24cc189845663509623fbd6b5106cc01266994Daniel Veillard#ifdef DEBUG
10843ce5257b293ed75d8feb18ed7ab18ea2b52510bdDaniel Veillard    printf("libxml_xmlCreatePushParser(%p, %s, %d, %s) called\n",
1085d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard           pyobj_SAX, chunk, size, URI);
10861971ee2698cb84c7699c96d3302f00e20d42c0d3Daniel Veillard#endif
10873ce5257b293ed75d8feb18ed7ab18ea2b52510bdDaniel Veillard    if (pyobj_SAX != Py_None) {
1088d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        SAX = &pythonSaxHandler;
1089d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        Py_INCREF(pyobj_SAX);
1090d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        /* The reference is released in pythonEndDocument() */
10911971ee2698cb84c7699c96d3302f00e20d42c0d3Daniel Veillard    }
109233caa0b8307eccf22010400747830b1967edb292Daniel Veillard    ret = xmlCreatePushParserCtxt(SAX, pyobj_SAX, chunk, size, URI);
10933ce5257b293ed75d8feb18ed7ab18ea2b52510bdDaniel Veillard    pyret = libxml_xmlParserCtxtPtrWrap(ret);
1094d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard    return (pyret);
1095a7340c830e4bddd86201cfdb97ac81e30b0dee62Daniel Veillard}
10965d81903b06418c7d8cc72cf9add81c4026a2f3bcDaniel Veillard
10974e1b26cfeba7f5fad4f8bd12fb5ce7029f930b79Daniel VeillardPyObject *
1098d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillardlibxml_htmlCreatePushParser(ATTRIBUTE_UNUSED PyObject * self,
1099d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard                            PyObject * args)
1100d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard{
1101d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard    const char *chunk;
11024e1b26cfeba7f5fad4f8bd12fb5ce7029f930b79Daniel Veillard    int size;
1103d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard    const char *URI;
110433caa0b8307eccf22010400747830b1967edb292Daniel Veillard    PyObject *pyobj_SAX = NULL;
11054e1b26cfeba7f5fad4f8bd12fb5ce7029f930b79Daniel Veillard    xmlSAXHandlerPtr SAX = NULL;
11064e1b26cfeba7f5fad4f8bd12fb5ce7029f930b79Daniel Veillard    xmlParserCtxtPtr ret;
11074e1b26cfeba7f5fad4f8bd12fb5ce7029f930b79Daniel Veillard    PyObject *pyret;
11084e1b26cfeba7f5fad4f8bd12fb5ce7029f930b79Daniel Veillard
1109d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard    if (!PyArg_ParseTuple
1110d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        (args, (char *) "Oziz:htmlCreatePushParser", &pyobj_SAX, &chunk,
1111d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard         &size, &URI))
1112d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        return (NULL);
11134e1b26cfeba7f5fad4f8bd12fb5ce7029f930b79Daniel Veillard
11148d24cc189845663509623fbd6b5106cc01266994Daniel Veillard#ifdef DEBUG
11154e1b26cfeba7f5fad4f8bd12fb5ce7029f930b79Daniel Veillard    printf("libxml_htmlCreatePushParser(%p, %s, %d, %s) called\n",
1116d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard           pyobj_SAX, chunk, size, URI);
11174e1b26cfeba7f5fad4f8bd12fb5ce7029f930b79Daniel Veillard#endif
11184e1b26cfeba7f5fad4f8bd12fb5ce7029f930b79Daniel Veillard    if (pyobj_SAX != Py_None) {
1119d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        SAX = &pythonSaxHandler;
1120d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        Py_INCREF(pyobj_SAX);
1121d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        /* The reference is released in pythonEndDocument() */
11224e1b26cfeba7f5fad4f8bd12fb5ce7029f930b79Daniel Veillard    }
112333caa0b8307eccf22010400747830b1967edb292Daniel Veillard    ret = htmlCreatePushParserCtxt(SAX, pyobj_SAX, chunk, size, URI,
1124d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard                                   XML_CHAR_ENCODING_NONE);
11254e1b26cfeba7f5fad4f8bd12fb5ce7029f930b79Daniel Veillard    pyret = libxml_xmlParserCtxtPtrWrap(ret);
1126d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard    return (pyret);
11274e1b26cfeba7f5fad4f8bd12fb5ce7029f930b79Daniel Veillard}
11284e1b26cfeba7f5fad4f8bd12fb5ce7029f930b79Daniel Veillard
11298d24cc189845663509623fbd6b5106cc01266994Daniel VeillardPyObject *
1130d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillardlibxml_xmlSAXParseFile(ATTRIBUTE_UNUSED PyObject * self, PyObject * args)
1131d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard{
11328d24cc189845663509623fbd6b5106cc01266994Daniel Veillard    int recover;
1133d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard    const char *URI;
11348d24cc189845663509623fbd6b5106cc01266994Daniel Veillard    PyObject *pyobj_SAX = NULL;
11358d24cc189845663509623fbd6b5106cc01266994Daniel Veillard    xmlSAXHandlerPtr SAX = NULL;
11368d24cc189845663509623fbd6b5106cc01266994Daniel Veillard
1137d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard    if (!PyArg_ParseTuple(args, (char *) "Osi:xmlSAXParseFile", &pyobj_SAX,
1138d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard                          &URI, &recover))
1139d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        return (NULL);
11408d24cc189845663509623fbd6b5106cc01266994Daniel Veillard
11418d24cc189845663509623fbd6b5106cc01266994Daniel Veillard#ifdef DEBUG
11428d24cc189845663509623fbd6b5106cc01266994Daniel Veillard    printf("libxml_xmlSAXParseFile(%p, %s, %d) called\n",
1143d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard           pyobj_SAX, URI, recover);
11448d24cc189845663509623fbd6b5106cc01266994Daniel Veillard#endif
11458d24cc189845663509623fbd6b5106cc01266994Daniel Veillard    if (pyobj_SAX == Py_None) {
1146d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        Py_INCREF(Py_None);
1147d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        return (Py_None);
11488d24cc189845663509623fbd6b5106cc01266994Daniel Veillard    }
11498d24cc189845663509623fbd6b5106cc01266994Daniel Veillard    SAX = &pythonSaxHandler;
11508d24cc189845663509623fbd6b5106cc01266994Daniel Veillard    Py_INCREF(pyobj_SAX);
11518d24cc189845663509623fbd6b5106cc01266994Daniel Veillard    /* The reference is released in pythonEndDocument() */
11528d24cc189845663509623fbd6b5106cc01266994Daniel Veillard    xmlSAXParseFileWithData(SAX, URI, recover, pyobj_SAX);
11538d24cc189845663509623fbd6b5106cc01266994Daniel Veillard    Py_INCREF(Py_None);
1154d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard    return (Py_None);
11558d24cc189845663509623fbd6b5106cc01266994Daniel Veillard}
11568d24cc189845663509623fbd6b5106cc01266994Daniel Veillard
11578d24cc189845663509623fbd6b5106cc01266994Daniel VeillardPyObject *
1158d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillardlibxml_htmlSAXParseFile(ATTRIBUTE_UNUSED PyObject * self, PyObject * args)
1159d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard{
1160d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard    const char *URI;
1161d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard    const char *encoding;
11628d24cc189845663509623fbd6b5106cc01266994Daniel Veillard    PyObject *pyobj_SAX = NULL;
11638d24cc189845663509623fbd6b5106cc01266994Daniel Veillard    xmlSAXHandlerPtr SAX = NULL;
11648d24cc189845663509623fbd6b5106cc01266994Daniel Veillard
1165d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard    if (!PyArg_ParseTuple
1166d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        (args, (char *) "Osz:htmlSAXParseFile", &pyobj_SAX, &URI,
1167d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard         &encoding))
1168d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        return (NULL);
11698d24cc189845663509623fbd6b5106cc01266994Daniel Veillard
11708d24cc189845663509623fbd6b5106cc01266994Daniel Veillard#ifdef DEBUG
11718d24cc189845663509623fbd6b5106cc01266994Daniel Veillard    printf("libxml_htmlSAXParseFile(%p, %s, %s) called\n",
1172d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard           pyobj_SAX, URI, encoding);
11738d24cc189845663509623fbd6b5106cc01266994Daniel Veillard#endif
11748d24cc189845663509623fbd6b5106cc01266994Daniel Veillard    if (pyobj_SAX == Py_None) {
1175d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        Py_INCREF(Py_None);
1176d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        return (Py_None);
11778d24cc189845663509623fbd6b5106cc01266994Daniel Veillard    }
11788d24cc189845663509623fbd6b5106cc01266994Daniel Veillard    SAX = &pythonSaxHandler;
11798d24cc189845663509623fbd6b5106cc01266994Daniel Veillard    Py_INCREF(pyobj_SAX);
11808d24cc189845663509623fbd6b5106cc01266994Daniel Veillard    /* The reference is released in pythonEndDocument() */
11818d24cc189845663509623fbd6b5106cc01266994Daniel Veillard    htmlSAXParseFile(URI, encoding, SAX, pyobj_SAX);
11828d24cc189845663509623fbd6b5106cc01266994Daniel Veillard    Py_INCREF(Py_None);
1183d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard    return (Py_None);
11848d24cc189845663509623fbd6b5106cc01266994Daniel Veillard}
11858d24cc189845663509623fbd6b5106cc01266994Daniel Veillard
11865d81903b06418c7d8cc72cf9add81c4026a2f3bcDaniel Veillard/************************************************************************
11875d81903b06418c7d8cc72cf9add81c4026a2f3bcDaniel Veillard *									*
11885d81903b06418c7d8cc72cf9add81c4026a2f3bcDaniel Veillard *			Error message callback				*
11895d81903b06418c7d8cc72cf9add81c4026a2f3bcDaniel Veillard *									*
11905d81903b06418c7d8cc72cf9add81c4026a2f3bcDaniel Veillard ************************************************************************/
11915d81903b06418c7d8cc72cf9add81c4026a2f3bcDaniel Veillard
11925d81903b06418c7d8cc72cf9add81c4026a2f3bcDaniel Veillardstatic PyObject *libxml_xmlPythonErrorFuncHandler = NULL;
11935d81903b06418c7d8cc72cf9add81c4026a2f3bcDaniel Veillardstatic PyObject *libxml_xmlPythonErrorFuncCtxt = NULL;
11945d81903b06418c7d8cc72cf9add81c4026a2f3bcDaniel Veillard
1195e6227e0549490b5bf9271ecd2d874a97c3f4852bDaniel Veillard/* helper to build a xmlMalloc'ed string from a format and va_list */
1196e6227e0549490b5bf9271ecd2d874a97c3f4852bDaniel Veillardstatic char *
1197e6227e0549490b5bf9271ecd2d874a97c3f4852bDaniel Veillardlibxml_buildMessage(const char *msg, va_list ap)
1198d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard{
1199d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard    int size;
1200d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard    int chars;
1201d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard    char *larger;
1202e6227e0549490b5bf9271ecd2d874a97c3f4852bDaniel Veillard    char *str;
1203e6227e0549490b5bf9271ecd2d874a97c3f4852bDaniel Veillard
1204e6227e0549490b5bf9271ecd2d874a97c3f4852bDaniel Veillard    str = (char *) xmlMalloc(150);
1205e6227e0549490b5bf9271ecd2d874a97c3f4852bDaniel Veillard    if (str == NULL)
1206e6227e0549490b5bf9271ecd2d874a97c3f4852bDaniel Veillard        return NULL;
1207e6227e0549490b5bf9271ecd2d874a97c3f4852bDaniel Veillard
1208e6227e0549490b5bf9271ecd2d874a97c3f4852bDaniel Veillard    size = 150;
1209e6227e0549490b5bf9271ecd2d874a97c3f4852bDaniel Veillard
1210e6227e0549490b5bf9271ecd2d874a97c3f4852bDaniel Veillard    while (1) {
1211e6227e0549490b5bf9271ecd2d874a97c3f4852bDaniel Veillard        chars = vsnprintf(str, size, msg, ap);
1212e6227e0549490b5bf9271ecd2d874a97c3f4852bDaniel Veillard        if ((chars > -1) && (chars < size))
1213e6227e0549490b5bf9271ecd2d874a97c3f4852bDaniel Veillard            break;
1214e6227e0549490b5bf9271ecd2d874a97c3f4852bDaniel Veillard        if (chars > -1)
1215e6227e0549490b5bf9271ecd2d874a97c3f4852bDaniel Veillard            size += chars + 1;
1216e6227e0549490b5bf9271ecd2d874a97c3f4852bDaniel Veillard        else
1217e6227e0549490b5bf9271ecd2d874a97c3f4852bDaniel Veillard            size += 100;
1218e6227e0549490b5bf9271ecd2d874a97c3f4852bDaniel Veillard        if ((larger = (char *) xmlRealloc(str, size)) == NULL) {
1219e6227e0549490b5bf9271ecd2d874a97c3f4852bDaniel Veillard            xmlFree(str);
1220e6227e0549490b5bf9271ecd2d874a97c3f4852bDaniel Veillard            return NULL;
1221e6227e0549490b5bf9271ecd2d874a97c3f4852bDaniel Veillard        }
1222e6227e0549490b5bf9271ecd2d874a97c3f4852bDaniel Veillard        str = larger;
1223e6227e0549490b5bf9271ecd2d874a97c3f4852bDaniel Veillard    }
1224e6227e0549490b5bf9271ecd2d874a97c3f4852bDaniel Veillard
1225e6227e0549490b5bf9271ecd2d874a97c3f4852bDaniel Veillard    return str;
1226e6227e0549490b5bf9271ecd2d874a97c3f4852bDaniel Veillard}
1227e6227e0549490b5bf9271ecd2d874a97c3f4852bDaniel Veillard
1228e6227e0549490b5bf9271ecd2d874a97c3f4852bDaniel Veillardstatic void
1229e6227e0549490b5bf9271ecd2d874a97c3f4852bDaniel Veillardlibxml_xmlErrorFuncHandler(ATTRIBUTE_UNUSED void *ctx, const char *msg,
1230e6227e0549490b5bf9271ecd2d874a97c3f4852bDaniel Veillard                           ...)
1231e6227e0549490b5bf9271ecd2d874a97c3f4852bDaniel Veillard{
1232d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard    va_list ap;
1233d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard    char *str;
12345d81903b06418c7d8cc72cf9add81c4026a2f3bcDaniel Veillard    PyObject *list;
12355d81903b06418c7d8cc72cf9add81c4026a2f3bcDaniel Veillard    PyObject *message;
12365d81903b06418c7d8cc72cf9add81c4026a2f3bcDaniel Veillard    PyObject *result;
12375d81903b06418c7d8cc72cf9add81c4026a2f3bcDaniel Veillard
12385d81903b06418c7d8cc72cf9add81c4026a2f3bcDaniel Veillard#ifdef DEBUG_ERROR
12395d81903b06418c7d8cc72cf9add81c4026a2f3bcDaniel Veillard    printf("libxml_xmlErrorFuncHandler(%p, %s, ...) called\n", ctx, msg);
12405d81903b06418c7d8cc72cf9add81c4026a2f3bcDaniel Veillard#endif
12415d81903b06418c7d8cc72cf9add81c4026a2f3bcDaniel Veillard
12425d81903b06418c7d8cc72cf9add81c4026a2f3bcDaniel Veillard
12435d81903b06418c7d8cc72cf9add81c4026a2f3bcDaniel Veillard    if (libxml_xmlPythonErrorFuncHandler == NULL) {
1244d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        va_start(ap, msg);
1245d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        vfprintf(stdout, msg, ap);
1246d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        va_end(ap);
12475d81903b06418c7d8cc72cf9add81c4026a2f3bcDaniel Veillard    } else {
1248e6227e0549490b5bf9271ecd2d874a97c3f4852bDaniel Veillard        va_start(ap, msg);
1249e6227e0549490b5bf9271ecd2d874a97c3f4852bDaniel Veillard        str = libxml_buildMessage(msg,ap);
1250e6227e0549490b5bf9271ecd2d874a97c3f4852bDaniel Veillard        va_end(ap);
1251d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard
1252d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        list = PyTuple_New(2);
1253d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        PyTuple_SetItem(list, 0, libxml_xmlPythonErrorFuncCtxt);
1254d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        Py_XINCREF(libxml_xmlPythonErrorFuncCtxt);
1255d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        message = libxml_charPtrWrap(str);
1256d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        PyTuple_SetItem(list, 1, message);
1257d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        result = PyEval_CallObject(libxml_xmlPythonErrorFuncHandler, list);
1258d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        Py_XDECREF(list);
1259d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        Py_XDECREF(result);
12605d81903b06418c7d8cc72cf9add81c4026a2f3bcDaniel Veillard    }
12615d81903b06418c7d8cc72cf9add81c4026a2f3bcDaniel Veillard}
12625d81903b06418c7d8cc72cf9add81c4026a2f3bcDaniel Veillard
12635d81903b06418c7d8cc72cf9add81c4026a2f3bcDaniel Veillardstatic void
1264d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillardlibxml_xmlErrorInitialize(void)
1265d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard{
12665d81903b06418c7d8cc72cf9add81c4026a2f3bcDaniel Veillard#ifdef DEBUG_ERROR
12675d81903b06418c7d8cc72cf9add81c4026a2f3bcDaniel Veillard    printf("libxml_xmlErrorInitialize() called\n");
12685d81903b06418c7d8cc72cf9add81c4026a2f3bcDaniel Veillard#endif
12695d81903b06418c7d8cc72cf9add81c4026a2f3bcDaniel Veillard    xmlSetGenericErrorFunc(NULL, libxml_xmlErrorFuncHandler);
1270781ac8b19bfc10635a8bb83158f874116fd7559eDaniel Veillard    xmlThrDefSetGenericErrorFunc(NULL, libxml_xmlErrorFuncHandler);
12715d81903b06418c7d8cc72cf9add81c4026a2f3bcDaniel Veillard}
12725d81903b06418c7d8cc72cf9add81c4026a2f3bcDaniel Veillard
12735d81903b06418c7d8cc72cf9add81c4026a2f3bcDaniel VeillardPyObject *
1274d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillardlibxml_xmlRegisterErrorHandler(ATTRIBUTE_UNUSED PyObject * self,
1275d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard                               PyObject * args)
1276d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard{
12775d81903b06418c7d8cc72cf9add81c4026a2f3bcDaniel Veillard    PyObject *py_retval;
12785d81903b06418c7d8cc72cf9add81c4026a2f3bcDaniel Veillard    PyObject *pyobj_f;
12795d81903b06418c7d8cc72cf9add81c4026a2f3bcDaniel Veillard    PyObject *pyobj_ctx;
12805d81903b06418c7d8cc72cf9add81c4026a2f3bcDaniel Veillard
1281d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard    if (!PyArg_ParseTuple
1282d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        (args, (char *) "OO:xmlRegisterErrorHandler", &pyobj_f,
1283d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard         &pyobj_ctx))
1284d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        return (NULL);
12855d81903b06418c7d8cc72cf9add81c4026a2f3bcDaniel Veillard
12865d81903b06418c7d8cc72cf9add81c4026a2f3bcDaniel Veillard#ifdef DEBUG_ERROR
1287d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard    printf("libxml_registerXPathFunction(%p, %p) called\n", pyobj_ctx,
1288d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard           pyobj_f);
12895d81903b06418c7d8cc72cf9add81c4026a2f3bcDaniel Veillard#endif
12905d81903b06418c7d8cc72cf9add81c4026a2f3bcDaniel Veillard
12915d81903b06418c7d8cc72cf9add81c4026a2f3bcDaniel Veillard    if (libxml_xmlPythonErrorFuncHandler != NULL) {
1292d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        Py_XDECREF(libxml_xmlPythonErrorFuncHandler);
12935d81903b06418c7d8cc72cf9add81c4026a2f3bcDaniel Veillard    }
12945d81903b06418c7d8cc72cf9add81c4026a2f3bcDaniel Veillard    if (libxml_xmlPythonErrorFuncCtxt != NULL) {
1295d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        Py_XDECREF(libxml_xmlPythonErrorFuncCtxt);
12965d81903b06418c7d8cc72cf9add81c4026a2f3bcDaniel Veillard    }
12975d81903b06418c7d8cc72cf9add81c4026a2f3bcDaniel Veillard
12985d81903b06418c7d8cc72cf9add81c4026a2f3bcDaniel Veillard    Py_XINCREF(pyobj_ctx);
12995d81903b06418c7d8cc72cf9add81c4026a2f3bcDaniel Veillard    Py_XINCREF(pyobj_f);
13005d81903b06418c7d8cc72cf9add81c4026a2f3bcDaniel Veillard
13015d81903b06418c7d8cc72cf9add81c4026a2f3bcDaniel Veillard    /* TODO: check f is a function ! */
13025d81903b06418c7d8cc72cf9add81c4026a2f3bcDaniel Veillard    libxml_xmlPythonErrorFuncHandler = pyobj_f;
13035d81903b06418c7d8cc72cf9add81c4026a2f3bcDaniel Veillard    libxml_xmlPythonErrorFuncCtxt = pyobj_ctx;
13045d81903b06418c7d8cc72cf9add81c4026a2f3bcDaniel Veillard
13055d81903b06418c7d8cc72cf9add81c4026a2f3bcDaniel Veillard    py_retval = libxml_intWrap(1);
1306d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard    return (py_retval);
13075d81903b06418c7d8cc72cf9add81c4026a2f3bcDaniel Veillard}
1308d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard
1309e6227e0549490b5bf9271ecd2d874a97c3f4852bDaniel Veillard
1310e6227e0549490b5bf9271ecd2d874a97c3f4852bDaniel Veillard/************************************************************************
1311e6227e0549490b5bf9271ecd2d874a97c3f4852bDaniel Veillard *									*
1312e6227e0549490b5bf9271ecd2d874a97c3f4852bDaniel Veillard *                      Per parserCtxt error handler                    *
1313e6227e0549490b5bf9271ecd2d874a97c3f4852bDaniel Veillard *									*
1314e6227e0549490b5bf9271ecd2d874a97c3f4852bDaniel Veillard ************************************************************************/
1315e6227e0549490b5bf9271ecd2d874a97c3f4852bDaniel Veillard
1316417be3ae08346c6510c28d2042dd42a22a74b331Daniel Veillardtypedef struct
1317417be3ae08346c6510c28d2042dd42a22a74b331Daniel Veillard{
1318417be3ae08346c6510c28d2042dd42a22a74b331Daniel Veillard    PyObject *f;
1319417be3ae08346c6510c28d2042dd42a22a74b331Daniel Veillard    PyObject *arg;
1320417be3ae08346c6510c28d2042dd42a22a74b331Daniel Veillard} xmlParserCtxtPyCtxt;
1321417be3ae08346c6510c28d2042dd42a22a74b331Daniel Veillardtypedef xmlParserCtxtPyCtxt *xmlParserCtxtPyCtxtPtr;
1322417be3ae08346c6510c28d2042dd42a22a74b331Daniel Veillard
1323417be3ae08346c6510c28d2042dd42a22a74b331Daniel Veillardstatic void
1324417be3ae08346c6510c28d2042dd42a22a74b331Daniel Veillardlibxml_xmlParserCtxtGenericErrorFuncHandler(void *ctx, int severity, char *str)
1325e6227e0549490b5bf9271ecd2d874a97c3f4852bDaniel Veillard{
1326e6227e0549490b5bf9271ecd2d874a97c3f4852bDaniel Veillard    PyObject *list;
1327e6227e0549490b5bf9271ecd2d874a97c3f4852bDaniel Veillard    PyObject *result;
1328417be3ae08346c6510c28d2042dd42a22a74b331Daniel Veillard    xmlParserCtxtPtr ctxt;
1329e6227e0549490b5bf9271ecd2d874a97c3f4852bDaniel Veillard    xmlParserCtxtPyCtxtPtr pyCtxt;
1330e6227e0549490b5bf9271ecd2d874a97c3f4852bDaniel Veillard
1331e6227e0549490b5bf9271ecd2d874a97c3f4852bDaniel Veillard#ifdef DEBUG_ERROR
1332417be3ae08346c6510c28d2042dd42a22a74b331Daniel Veillard    printf("libxml_xmlParserCtxtGenericErrorFuncHandler(%p, %s, ...) called\n", ctx, msg);
1333e6227e0549490b5bf9271ecd2d874a97c3f4852bDaniel Veillard#endif
1334e6227e0549490b5bf9271ecd2d874a97c3f4852bDaniel Veillard
1335417be3ae08346c6510c28d2042dd42a22a74b331Daniel Veillard    ctxt = (xmlParserCtxtPtr)ctx;
1336417be3ae08346c6510c28d2042dd42a22a74b331Daniel Veillard    pyCtxt = (xmlParserCtxtPyCtxtPtr)ctxt->_private;
1337e6227e0549490b5bf9271ecd2d874a97c3f4852bDaniel Veillard
1338417be3ae08346c6510c28d2042dd42a22a74b331Daniel Veillard    list = PyTuple_New(4);
1339417be3ae08346c6510c28d2042dd42a22a74b331Daniel Veillard    PyTuple_SetItem(list, 0, pyCtxt->arg);
1340417be3ae08346c6510c28d2042dd42a22a74b331Daniel Veillard    Py_XINCREF(pyCtxt->arg);
1341417be3ae08346c6510c28d2042dd42a22a74b331Daniel Veillard    PyTuple_SetItem(list, 1, libxml_charPtrWrap(str));
1342417be3ae08346c6510c28d2042dd42a22a74b331Daniel Veillard    PyTuple_SetItem(list, 2, libxml_intWrap(severity));
1343417be3ae08346c6510c28d2042dd42a22a74b331Daniel Veillard    PyTuple_SetItem(list, 3, Py_None);
1344417be3ae08346c6510c28d2042dd42a22a74b331Daniel Veillard    Py_INCREF(Py_None);
1345417be3ae08346c6510c28d2042dd42a22a74b331Daniel Veillard    result = PyEval_CallObject(pyCtxt->f, list);
1346417be3ae08346c6510c28d2042dd42a22a74b331Daniel Veillard    if (result == NULL)
1347417be3ae08346c6510c28d2042dd42a22a74b331Daniel Veillard    {
1348417be3ae08346c6510c28d2042dd42a22a74b331Daniel Veillard	/* TODO: manage for the exception to be propagated... */
1349417be3ae08346c6510c28d2042dd42a22a74b331Daniel Veillard	PyErr_Print();
1350e6227e0549490b5bf9271ecd2d874a97c3f4852bDaniel Veillard    }
1351417be3ae08346c6510c28d2042dd42a22a74b331Daniel Veillard    Py_XDECREF(list);
1352417be3ae08346c6510c28d2042dd42a22a74b331Daniel Veillard    Py_XDECREF(result);
1353417be3ae08346c6510c28d2042dd42a22a74b331Daniel Veillard}
1354417be3ae08346c6510c28d2042dd42a22a74b331Daniel Veillard
1355417be3ae08346c6510c28d2042dd42a22a74b331Daniel Veillardstatic void
1356417be3ae08346c6510c28d2042dd42a22a74b331Daniel Veillardlibxml_xmlParserCtxtErrorFuncHandler(void *ctx, const char *msg, ...)
1357417be3ae08346c6510c28d2042dd42a22a74b331Daniel Veillard{
1358417be3ae08346c6510c28d2042dd42a22a74b331Daniel Veillard    va_list ap;
1359417be3ae08346c6510c28d2042dd42a22a74b331Daniel Veillard
1360417be3ae08346c6510c28d2042dd42a22a74b331Daniel Veillard    va_start(ap, msg);
1361417be3ae08346c6510c28d2042dd42a22a74b331Daniel Veillard    libxml_xmlParserCtxtGenericErrorFuncHandler(ctx,XML_PARSER_SEVERITY_ERROR,libxml_buildMessage(msg,ap));
1362417be3ae08346c6510c28d2042dd42a22a74b331Daniel Veillard    va_end(ap);
1363417be3ae08346c6510c28d2042dd42a22a74b331Daniel Veillard}
1364417be3ae08346c6510c28d2042dd42a22a74b331Daniel Veillard
1365417be3ae08346c6510c28d2042dd42a22a74b331Daniel Veillardstatic void
1366417be3ae08346c6510c28d2042dd42a22a74b331Daniel Veillardlibxml_xmlParserCtxtWarningFuncHandler(void *ctx, const char *msg, ...)
1367417be3ae08346c6510c28d2042dd42a22a74b331Daniel Veillard{
1368417be3ae08346c6510c28d2042dd42a22a74b331Daniel Veillard    va_list ap;
1369417be3ae08346c6510c28d2042dd42a22a74b331Daniel Veillard
1370417be3ae08346c6510c28d2042dd42a22a74b331Daniel Veillard    va_start(ap, msg);
1371417be3ae08346c6510c28d2042dd42a22a74b331Daniel Veillard    libxml_xmlParserCtxtGenericErrorFuncHandler(ctx,XML_PARSER_SEVERITY_WARNING,libxml_buildMessage(msg,ap));
1372417be3ae08346c6510c28d2042dd42a22a74b331Daniel Veillard    va_end(ap);
1373417be3ae08346c6510c28d2042dd42a22a74b331Daniel Veillard}
1374417be3ae08346c6510c28d2042dd42a22a74b331Daniel Veillard
1375417be3ae08346c6510c28d2042dd42a22a74b331Daniel Veillardstatic void
1376417be3ae08346c6510c28d2042dd42a22a74b331Daniel Veillardlibxml_xmlParserCtxtValidityErrorFuncHandler(void *ctx, const char *msg, ...)
1377417be3ae08346c6510c28d2042dd42a22a74b331Daniel Veillard{
1378417be3ae08346c6510c28d2042dd42a22a74b331Daniel Veillard    va_list ap;
1379417be3ae08346c6510c28d2042dd42a22a74b331Daniel Veillard
1380417be3ae08346c6510c28d2042dd42a22a74b331Daniel Veillard    va_start(ap, msg);
1381417be3ae08346c6510c28d2042dd42a22a74b331Daniel Veillard    libxml_xmlParserCtxtGenericErrorFuncHandler(ctx,XML_PARSER_SEVERITY_VALIDITY_ERROR,libxml_buildMessage(msg,ap));
1382417be3ae08346c6510c28d2042dd42a22a74b331Daniel Veillard    va_end(ap);
1383417be3ae08346c6510c28d2042dd42a22a74b331Daniel Veillard}
1384417be3ae08346c6510c28d2042dd42a22a74b331Daniel Veillard
1385417be3ae08346c6510c28d2042dd42a22a74b331Daniel Veillardstatic void
1386417be3ae08346c6510c28d2042dd42a22a74b331Daniel Veillardlibxml_xmlParserCtxtValidityWarningFuncHandler(void *ctx, const char *msg, ...)
1387417be3ae08346c6510c28d2042dd42a22a74b331Daniel Veillard{
1388417be3ae08346c6510c28d2042dd42a22a74b331Daniel Veillard    va_list ap;
1389417be3ae08346c6510c28d2042dd42a22a74b331Daniel Veillard
1390417be3ae08346c6510c28d2042dd42a22a74b331Daniel Veillard    va_start(ap, msg);
1391417be3ae08346c6510c28d2042dd42a22a74b331Daniel Veillard    libxml_xmlParserCtxtGenericErrorFuncHandler(ctx,XML_PARSER_SEVERITY_VALIDITY_WARNING,libxml_buildMessage(msg,ap));
1392417be3ae08346c6510c28d2042dd42a22a74b331Daniel Veillard    va_end(ap);
1393e6227e0549490b5bf9271ecd2d874a97c3f4852bDaniel Veillard}
1394e6227e0549490b5bf9271ecd2d874a97c3f4852bDaniel Veillard
1395e6227e0549490b5bf9271ecd2d874a97c3f4852bDaniel VeillardPyObject *
1396417be3ae08346c6510c28d2042dd42a22a74b331Daniel Veillardlibxml_xmlParserCtxtSetErrorHandler(ATTRIBUTE_UNUSED PyObject *self, PyObject *args)
1397e6227e0549490b5bf9271ecd2d874a97c3f4852bDaniel Veillard{
1398e6227e0549490b5bf9271ecd2d874a97c3f4852bDaniel Veillard    PyObject *py_retval;
1399e6227e0549490b5bf9271ecd2d874a97c3f4852bDaniel Veillard    xmlParserCtxtPtr ctxt;
1400e4a07e7b77b191d61291d44dffa19b65387e04e4Daniel Veillard    xmlParserCtxtPyCtxtPtr pyCtxt;
1401e6227e0549490b5bf9271ecd2d874a97c3f4852bDaniel Veillard    PyObject *pyobj_ctxt;
1402e6227e0549490b5bf9271ecd2d874a97c3f4852bDaniel Veillard    PyObject *pyobj_f;
1403e6227e0549490b5bf9271ecd2d874a97c3f4852bDaniel Veillard    PyObject *pyobj_arg;
1404e6227e0549490b5bf9271ecd2d874a97c3f4852bDaniel Veillard
1405417be3ae08346c6510c28d2042dd42a22a74b331Daniel Veillard    if (!PyArg_ParseTuple(args, (char *)"OOO:xmlParserCtxtSetErrorHandler",
1406e6227e0549490b5bf9271ecd2d874a97c3f4852bDaniel Veillard		          &pyobj_ctxt, &pyobj_f, &pyobj_arg))
1407e6227e0549490b5bf9271ecd2d874a97c3f4852bDaniel Veillard        return(NULL);
1408e6227e0549490b5bf9271ecd2d874a97c3f4852bDaniel Veillard    ctxt = (xmlParserCtxtPtr) PyparserCtxt_Get(pyobj_ctxt);
1409e6227e0549490b5bf9271ecd2d874a97c3f4852bDaniel Veillard    if (ctxt->_private == NULL) {
1410e6227e0549490b5bf9271ecd2d874a97c3f4852bDaniel Veillard	pyCtxt = xmlMalloc(sizeof(xmlParserCtxtPyCtxt));
1411e6227e0549490b5bf9271ecd2d874a97c3f4852bDaniel Veillard	if (pyCtxt == NULL) {
1412e6227e0549490b5bf9271ecd2d874a97c3f4852bDaniel Veillard	    py_retval = libxml_intWrap(-1);
1413e6227e0549490b5bf9271ecd2d874a97c3f4852bDaniel Veillard	    return(py_retval);
1414e6227e0549490b5bf9271ecd2d874a97c3f4852bDaniel Veillard	}
1415e6227e0549490b5bf9271ecd2d874a97c3f4852bDaniel Veillard	memset(pyCtxt,0,sizeof(xmlParserCtxtPyCtxt));
1416e6227e0549490b5bf9271ecd2d874a97c3f4852bDaniel Veillard	ctxt->_private = pyCtxt;
1417e6227e0549490b5bf9271ecd2d874a97c3f4852bDaniel Veillard    }
1418e4a07e7b77b191d61291d44dffa19b65387e04e4Daniel Veillard    else {
1419417be3ae08346c6510c28d2042dd42a22a74b331Daniel Veillard	pyCtxt = (xmlParserCtxtPyCtxtPtr)ctxt->_private;
1420e4a07e7b77b191d61291d44dffa19b65387e04e4Daniel Veillard    }
1421e6227e0549490b5bf9271ecd2d874a97c3f4852bDaniel Veillard    /* TODO: check f is a function ! */
1422417be3ae08346c6510c28d2042dd42a22a74b331Daniel Veillard    Py_XDECREF(pyCtxt->f);
1423e6227e0549490b5bf9271ecd2d874a97c3f4852bDaniel Veillard    Py_XINCREF(pyobj_f);
1424417be3ae08346c6510c28d2042dd42a22a74b331Daniel Veillard    pyCtxt->f = pyobj_f;
1425417be3ae08346c6510c28d2042dd42a22a74b331Daniel Veillard    Py_XDECREF(pyCtxt->arg);
1426e6227e0549490b5bf9271ecd2d874a97c3f4852bDaniel Veillard    Py_XINCREF(pyobj_arg);
1427417be3ae08346c6510c28d2042dd42a22a74b331Daniel Veillard    pyCtxt->arg = pyobj_arg;
1428e6227e0549490b5bf9271ecd2d874a97c3f4852bDaniel Veillard
1429417be3ae08346c6510c28d2042dd42a22a74b331Daniel Veillard    if (pyobj_f != Py_None) {
1430417be3ae08346c6510c28d2042dd42a22a74b331Daniel Veillard	ctxt->sax->error = libxml_xmlParserCtxtErrorFuncHandler;
1431417be3ae08346c6510c28d2042dd42a22a74b331Daniel Veillard	ctxt->sax->warning = libxml_xmlParserCtxtWarningFuncHandler;
1432417be3ae08346c6510c28d2042dd42a22a74b331Daniel Veillard	ctxt->vctxt.error = libxml_xmlParserCtxtValidityErrorFuncHandler;
1433417be3ae08346c6510c28d2042dd42a22a74b331Daniel Veillard	ctxt->vctxt.warning = libxml_xmlParserCtxtValidityWarningFuncHandler;
1434417be3ae08346c6510c28d2042dd42a22a74b331Daniel Veillard    }
1435417be3ae08346c6510c28d2042dd42a22a74b331Daniel Veillard    else {
1436417be3ae08346c6510c28d2042dd42a22a74b331Daniel Veillard	ctxt->sax->error = xmlParserError;
1437417be3ae08346c6510c28d2042dd42a22a74b331Daniel Veillard	ctxt->vctxt.error = xmlParserValidityError;
1438417be3ae08346c6510c28d2042dd42a22a74b331Daniel Veillard	ctxt->sax->warning = xmlParserWarning;
1439417be3ae08346c6510c28d2042dd42a22a74b331Daniel Veillard	ctxt->vctxt.warning = xmlParserValidityWarning;
1440417be3ae08346c6510c28d2042dd42a22a74b331Daniel Veillard    }
1441e6227e0549490b5bf9271ecd2d874a97c3f4852bDaniel Veillard
1442e6227e0549490b5bf9271ecd2d874a97c3f4852bDaniel Veillard    py_retval = libxml_intWrap(1);
1443e6227e0549490b5bf9271ecd2d874a97c3f4852bDaniel Veillard    return(py_retval);
1444e6227e0549490b5bf9271ecd2d874a97c3f4852bDaniel Veillard}
1445e6227e0549490b5bf9271ecd2d874a97c3f4852bDaniel Veillard
1446417be3ae08346c6510c28d2042dd42a22a74b331Daniel VeillardPyObject *
1447417be3ae08346c6510c28d2042dd42a22a74b331Daniel Veillardlibxml_xmlParserCtxtGetErrorHandler(ATTRIBUTE_UNUSED PyObject *self, PyObject *args)
1448e6227e0549490b5bf9271ecd2d874a97c3f4852bDaniel Veillard{
1449417be3ae08346c6510c28d2042dd42a22a74b331Daniel Veillard    PyObject *py_retval;
1450417be3ae08346c6510c28d2042dd42a22a74b331Daniel Veillard    xmlParserCtxtPtr ctxt;
1451e6227e0549490b5bf9271ecd2d874a97c3f4852bDaniel Veillard    xmlParserCtxtPyCtxtPtr pyCtxt;
1452417be3ae08346c6510c28d2042dd42a22a74b331Daniel Veillard    PyObject *pyobj_ctxt;
1453e6227e0549490b5bf9271ecd2d874a97c3f4852bDaniel Veillard
1454417be3ae08346c6510c28d2042dd42a22a74b331Daniel Veillard    if (!PyArg_ParseTuple(args, (char *)"O:xmlParserCtxtGetErrorHandler",
1455417be3ae08346c6510c28d2042dd42a22a74b331Daniel Veillard		          &pyobj_ctxt))
1456417be3ae08346c6510c28d2042dd42a22a74b331Daniel Veillard        return(NULL);
1457417be3ae08346c6510c28d2042dd42a22a74b331Daniel Veillard    ctxt = (xmlParserCtxtPtr) PyparserCtxt_Get(pyobj_ctxt);
1458417be3ae08346c6510c28d2042dd42a22a74b331Daniel Veillard    py_retval = PyTuple_New(2);
1459417be3ae08346c6510c28d2042dd42a22a74b331Daniel Veillard    if (ctxt->_private != NULL) {
1460417be3ae08346c6510c28d2042dd42a22a74b331Daniel Veillard	pyCtxt = (xmlParserCtxtPyCtxtPtr)ctxt->_private;
1461e6227e0549490b5bf9271ecd2d874a97c3f4852bDaniel Veillard
1462417be3ae08346c6510c28d2042dd42a22a74b331Daniel Veillard	PyTuple_SetItem(py_retval, 0, pyCtxt->f);
1463417be3ae08346c6510c28d2042dd42a22a74b331Daniel Veillard	Py_XINCREF(pyCtxt->f);
1464417be3ae08346c6510c28d2042dd42a22a74b331Daniel Veillard	PyTuple_SetItem(py_retval, 1, pyCtxt->arg);
1465417be3ae08346c6510c28d2042dd42a22a74b331Daniel Veillard	Py_XINCREF(pyCtxt->arg);
1466417be3ae08346c6510c28d2042dd42a22a74b331Daniel Veillard    }
1467417be3ae08346c6510c28d2042dd42a22a74b331Daniel Veillard    else {
1468417be3ae08346c6510c28d2042dd42a22a74b331Daniel Veillard	/* no python error handler registered */
1469417be3ae08346c6510c28d2042dd42a22a74b331Daniel Veillard	PyTuple_SetItem(py_retval, 0, Py_None);
1470417be3ae08346c6510c28d2042dd42a22a74b331Daniel Veillard	Py_XINCREF(Py_None);
1471417be3ae08346c6510c28d2042dd42a22a74b331Daniel Veillard	PyTuple_SetItem(py_retval, 1, Py_None);
1472417be3ae08346c6510c28d2042dd42a22a74b331Daniel Veillard	Py_XINCREF(Py_None);
1473e6227e0549490b5bf9271ecd2d874a97c3f4852bDaniel Veillard    }
1474417be3ae08346c6510c28d2042dd42a22a74b331Daniel Veillard    return(py_retval);
1475e6227e0549490b5bf9271ecd2d874a97c3f4852bDaniel Veillard}
1476e6227e0549490b5bf9271ecd2d874a97c3f4852bDaniel Veillard
1477e6227e0549490b5bf9271ecd2d874a97c3f4852bDaniel VeillardPyObject *
1478417be3ae08346c6510c28d2042dd42a22a74b331Daniel Veillardlibxml_xmlFreeParserCtxt(ATTRIBUTE_UNUSED PyObject *self, PyObject *args) {
1479e6227e0549490b5bf9271ecd2d874a97c3f4852bDaniel Veillard    xmlParserCtxtPtr ctxt;
1480e6227e0549490b5bf9271ecd2d874a97c3f4852bDaniel Veillard    PyObject *pyobj_ctxt;
1481417be3ae08346c6510c28d2042dd42a22a74b331Daniel Veillard    xmlParserCtxtPyCtxtPtr pyCtxt;
1482e6227e0549490b5bf9271ecd2d874a97c3f4852bDaniel Veillard
1483417be3ae08346c6510c28d2042dd42a22a74b331Daniel Veillard    if (!PyArg_ParseTuple(args, (char *)"O:xmlFreeParserCtxt", &pyobj_ctxt))
1484e6227e0549490b5bf9271ecd2d874a97c3f4852bDaniel Veillard        return(NULL);
1485e6227e0549490b5bf9271ecd2d874a97c3f4852bDaniel Veillard    ctxt = (xmlParserCtxtPtr) PyparserCtxt_Get(pyobj_ctxt);
1486417be3ae08346c6510c28d2042dd42a22a74b331Daniel Veillard
1487417be3ae08346c6510c28d2042dd42a22a74b331Daniel Veillard    if (ctxt != NULL) {
1488417be3ae08346c6510c28d2042dd42a22a74b331Daniel Veillard	pyCtxt = (xmlParserCtxtPyCtxtPtr)((xmlParserCtxtPtr)ctxt)->_private;
1489417be3ae08346c6510c28d2042dd42a22a74b331Daniel Veillard	if (pyCtxt) {
1490417be3ae08346c6510c28d2042dd42a22a74b331Daniel Veillard	    Py_XDECREF(pyCtxt->f);
1491417be3ae08346c6510c28d2042dd42a22a74b331Daniel Veillard	    Py_XDECREF(pyCtxt->arg);
1492417be3ae08346c6510c28d2042dd42a22a74b331Daniel Veillard	    xmlFree(pyCtxt);
1493e4a07e7b77b191d61291d44dffa19b65387e04e4Daniel Veillard	}
1494417be3ae08346c6510c28d2042dd42a22a74b331Daniel Veillard	xmlFreeParserCtxt(ctxt);
1495e4a07e7b77b191d61291d44dffa19b65387e04e4Daniel Veillard    }
1496e6227e0549490b5bf9271ecd2d874a97c3f4852bDaniel Veillard
1497417be3ae08346c6510c28d2042dd42a22a74b331Daniel Veillard    Py_INCREF(Py_None);
1498417be3ae08346c6510c28d2042dd42a22a74b331Daniel Veillard    return(Py_None);
1499e6227e0549490b5bf9271ecd2d874a97c3f4852bDaniel Veillard}
1500e6227e0549490b5bf9271ecd2d874a97c3f4852bDaniel Veillard
1501a7340c830e4bddd86201cfdb97ac81e30b0dee62Daniel Veillard/************************************************************************
1502a7340c830e4bddd86201cfdb97ac81e30b0dee62Daniel Veillard *									*
150326f70269c80140a7fb8a7aae9ef09c95efa98e70Daniel Veillard *                      Per xmlTextReader error handler                 *
150426f70269c80140a7fb8a7aae9ef09c95efa98e70Daniel Veillard *									*
150526f70269c80140a7fb8a7aae9ef09c95efa98e70Daniel Veillard ************************************************************************/
150626f70269c80140a7fb8a7aae9ef09c95efa98e70Daniel Veillard
150726f70269c80140a7fb8a7aae9ef09c95efa98e70Daniel Veillardtypedef struct
150826f70269c80140a7fb8a7aae9ef09c95efa98e70Daniel Veillard{
150926f70269c80140a7fb8a7aae9ef09c95efa98e70Daniel Veillard    PyObject *f;
151026f70269c80140a7fb8a7aae9ef09c95efa98e70Daniel Veillard    PyObject *arg;
151126f70269c80140a7fb8a7aae9ef09c95efa98e70Daniel Veillard} xmlTextReaderPyCtxt;
151226f70269c80140a7fb8a7aae9ef09c95efa98e70Daniel Veillardtypedef xmlTextReaderPyCtxt *xmlTextReaderPyCtxtPtr;
151326f70269c80140a7fb8a7aae9ef09c95efa98e70Daniel Veillard
151426f70269c80140a7fb8a7aae9ef09c95efa98e70Daniel Veillardstatic void
151526f70269c80140a7fb8a7aae9ef09c95efa98e70Daniel Veillardlibxml_xmlTextReaderErrorCallback(void *arg,
151626f70269c80140a7fb8a7aae9ef09c95efa98e70Daniel Veillard				  const char *msg,
1517417be3ae08346c6510c28d2042dd42a22a74b331Daniel Veillard				  int severity,
1518417be3ae08346c6510c28d2042dd42a22a74b331Daniel Veillard				  xmlTextReaderLocatorPtr locator)
151926f70269c80140a7fb8a7aae9ef09c95efa98e70Daniel Veillard{
152026f70269c80140a7fb8a7aae9ef09c95efa98e70Daniel Veillard    xmlTextReaderPyCtxt *pyCtxt = (xmlTextReaderPyCtxt *)arg;
152126f70269c80140a7fb8a7aae9ef09c95efa98e70Daniel Veillard    PyObject *list;
152226f70269c80140a7fb8a7aae9ef09c95efa98e70Daniel Veillard    PyObject *result;
152326f70269c80140a7fb8a7aae9ef09c95efa98e70Daniel Veillard
1524417be3ae08346c6510c28d2042dd42a22a74b331Daniel Veillard    list = PyTuple_New(4);
152526f70269c80140a7fb8a7aae9ef09c95efa98e70Daniel Veillard    PyTuple_SetItem(list, 0, pyCtxt->arg);
152626f70269c80140a7fb8a7aae9ef09c95efa98e70Daniel Veillard    Py_XINCREF(pyCtxt->arg);
152726f70269c80140a7fb8a7aae9ef09c95efa98e70Daniel Veillard    PyTuple_SetItem(list, 1, libxml_charPtrConstWrap(msg));
1528417be3ae08346c6510c28d2042dd42a22a74b331Daniel Veillard    PyTuple_SetItem(list, 2, libxml_intWrap(severity));
1529417be3ae08346c6510c28d2042dd42a22a74b331Daniel Veillard    PyTuple_SetItem(list, 3, libxml_xmlTextReaderLocatorPtrWrap(locator));
153026f70269c80140a7fb8a7aae9ef09c95efa98e70Daniel Veillard    result = PyEval_CallObject(pyCtxt->f, list);
153126f70269c80140a7fb8a7aae9ef09c95efa98e70Daniel Veillard    if (result == NULL)
153226f70269c80140a7fb8a7aae9ef09c95efa98e70Daniel Veillard    {
1533417be3ae08346c6510c28d2042dd42a22a74b331Daniel Veillard	/* TODO: manage for the exception to be propagated... */
153426f70269c80140a7fb8a7aae9ef09c95efa98e70Daniel Veillard	PyErr_Print();
153526f70269c80140a7fb8a7aae9ef09c95efa98e70Daniel Veillard    }
153626f70269c80140a7fb8a7aae9ef09c95efa98e70Daniel Veillard    Py_XDECREF(list);
153726f70269c80140a7fb8a7aae9ef09c95efa98e70Daniel Veillard    Py_XDECREF(result);
153826f70269c80140a7fb8a7aae9ef09c95efa98e70Daniel Veillard}
153926f70269c80140a7fb8a7aae9ef09c95efa98e70Daniel Veillard
154026f70269c80140a7fb8a7aae9ef09c95efa98e70Daniel VeillardPyObject *
154126f70269c80140a7fb8a7aae9ef09c95efa98e70Daniel Veillardlibxml_xmlTextReaderSetErrorHandler(ATTRIBUTE_UNUSED PyObject *self, PyObject *args)
154226f70269c80140a7fb8a7aae9ef09c95efa98e70Daniel Veillard{
154326f70269c80140a7fb8a7aae9ef09c95efa98e70Daniel Veillard    xmlTextReaderPtr reader;
154426f70269c80140a7fb8a7aae9ef09c95efa98e70Daniel Veillard    xmlTextReaderPyCtxtPtr pyCtxt;
154526f70269c80140a7fb8a7aae9ef09c95efa98e70Daniel Veillard    xmlTextReaderErrorFunc f;
154626f70269c80140a7fb8a7aae9ef09c95efa98e70Daniel Veillard    void *arg;
154726f70269c80140a7fb8a7aae9ef09c95efa98e70Daniel Veillard    PyObject *pyobj_reader;
154826f70269c80140a7fb8a7aae9ef09c95efa98e70Daniel Veillard    PyObject *pyobj_f;
154926f70269c80140a7fb8a7aae9ef09c95efa98e70Daniel Veillard    PyObject *pyobj_arg;
155026f70269c80140a7fb8a7aae9ef09c95efa98e70Daniel Veillard    PyObject *py_retval;
155126f70269c80140a7fb8a7aae9ef09c95efa98e70Daniel Veillard
155226f70269c80140a7fb8a7aae9ef09c95efa98e70Daniel Veillard    if (!PyArg_ParseTuple(args, (char *)"OOO:xmlTextReaderSetErrorHandler", &pyobj_reader, &pyobj_f, &pyobj_arg))
155326f70269c80140a7fb8a7aae9ef09c95efa98e70Daniel Veillard        return(NULL);
155426f70269c80140a7fb8a7aae9ef09c95efa98e70Daniel Veillard    reader = (xmlTextReaderPtr) PyxmlTextReader_Get(pyobj_reader);
155526f70269c80140a7fb8a7aae9ef09c95efa98e70Daniel Veillard    /* clear previous error handler */
155626f70269c80140a7fb8a7aae9ef09c95efa98e70Daniel Veillard    xmlTextReaderGetErrorHandler(reader,&f,&arg);
155726f70269c80140a7fb8a7aae9ef09c95efa98e70Daniel Veillard    if (arg != NULL) {
155826f70269c80140a7fb8a7aae9ef09c95efa98e70Daniel Veillard	if (f == libxml_xmlTextReaderErrorCallback) {
155926f70269c80140a7fb8a7aae9ef09c95efa98e70Daniel Veillard	    /* ok, it's our error handler! */
156026f70269c80140a7fb8a7aae9ef09c95efa98e70Daniel Veillard	    pyCtxt = (xmlTextReaderPyCtxtPtr)arg;
156126f70269c80140a7fb8a7aae9ef09c95efa98e70Daniel Veillard	    Py_XDECREF(pyCtxt->f);
156226f70269c80140a7fb8a7aae9ef09c95efa98e70Daniel Veillard	    Py_XDECREF(pyCtxt->arg);
156326f70269c80140a7fb8a7aae9ef09c95efa98e70Daniel Veillard	    xmlFree(pyCtxt);
156426f70269c80140a7fb8a7aae9ef09c95efa98e70Daniel Veillard	}
156526f70269c80140a7fb8a7aae9ef09c95efa98e70Daniel Veillard	else {
156626f70269c80140a7fb8a7aae9ef09c95efa98e70Daniel Veillard	    /*
156726f70269c80140a7fb8a7aae9ef09c95efa98e70Daniel Veillard	     * there already an arg, and it's not ours,
156826f70269c80140a7fb8a7aae9ef09c95efa98e70Daniel Veillard	     * there is definitely something wrong going on here...
156926f70269c80140a7fb8a7aae9ef09c95efa98e70Daniel Veillard	     * we don't know how to free it, so we bail out...
157026f70269c80140a7fb8a7aae9ef09c95efa98e70Daniel Veillard	     */
157126f70269c80140a7fb8a7aae9ef09c95efa98e70Daniel Veillard	    py_retval = libxml_intWrap(-1);
157226f70269c80140a7fb8a7aae9ef09c95efa98e70Daniel Veillard	    return(py_retval);
157326f70269c80140a7fb8a7aae9ef09c95efa98e70Daniel Veillard	}
157426f70269c80140a7fb8a7aae9ef09c95efa98e70Daniel Veillard    }
157526f70269c80140a7fb8a7aae9ef09c95efa98e70Daniel Veillard    xmlTextReaderSetErrorHandler(reader,NULL,NULL);
157626f70269c80140a7fb8a7aae9ef09c95efa98e70Daniel Veillard    /* set new error handler */
157726f70269c80140a7fb8a7aae9ef09c95efa98e70Daniel Veillard    if (pyobj_f != Py_None)
157826f70269c80140a7fb8a7aae9ef09c95efa98e70Daniel Veillard    {
157926f70269c80140a7fb8a7aae9ef09c95efa98e70Daniel Veillard	pyCtxt = (xmlTextReaderPyCtxtPtr)xmlMalloc(sizeof(xmlTextReaderPyCtxt));
158026f70269c80140a7fb8a7aae9ef09c95efa98e70Daniel Veillard	if (pyCtxt == NULL) {
158126f70269c80140a7fb8a7aae9ef09c95efa98e70Daniel Veillard	    py_retval = libxml_intWrap(-1);
158226f70269c80140a7fb8a7aae9ef09c95efa98e70Daniel Veillard	    return(py_retval);
158326f70269c80140a7fb8a7aae9ef09c95efa98e70Daniel Veillard	}
158426f70269c80140a7fb8a7aae9ef09c95efa98e70Daniel Veillard	Py_XINCREF(pyobj_f);
158526f70269c80140a7fb8a7aae9ef09c95efa98e70Daniel Veillard	pyCtxt->f = pyobj_f;
158626f70269c80140a7fb8a7aae9ef09c95efa98e70Daniel Veillard	Py_XINCREF(pyobj_arg);
158726f70269c80140a7fb8a7aae9ef09c95efa98e70Daniel Veillard	pyCtxt->arg = pyobj_arg;
158826f70269c80140a7fb8a7aae9ef09c95efa98e70Daniel Veillard	xmlTextReaderSetErrorHandler(reader,libxml_xmlTextReaderErrorCallback,pyCtxt);
158926f70269c80140a7fb8a7aae9ef09c95efa98e70Daniel Veillard    }
159026f70269c80140a7fb8a7aae9ef09c95efa98e70Daniel Veillard
159126f70269c80140a7fb8a7aae9ef09c95efa98e70Daniel Veillard    py_retval = libxml_intWrap(1);
159226f70269c80140a7fb8a7aae9ef09c95efa98e70Daniel Veillard    return(py_retval);
159326f70269c80140a7fb8a7aae9ef09c95efa98e70Daniel Veillard}
159426f70269c80140a7fb8a7aae9ef09c95efa98e70Daniel Veillard
159526f70269c80140a7fb8a7aae9ef09c95efa98e70Daniel VeillardPyObject *
159626f70269c80140a7fb8a7aae9ef09c95efa98e70Daniel Veillardlibxml_xmlTextReaderGetErrorHandler(ATTRIBUTE_UNUSED PyObject *self, PyObject *args)
159726f70269c80140a7fb8a7aae9ef09c95efa98e70Daniel Veillard{
159826f70269c80140a7fb8a7aae9ef09c95efa98e70Daniel Veillard    xmlTextReaderPtr reader;
159926f70269c80140a7fb8a7aae9ef09c95efa98e70Daniel Veillard    xmlTextReaderPyCtxtPtr pyCtxt;
160026f70269c80140a7fb8a7aae9ef09c95efa98e70Daniel Veillard    xmlTextReaderErrorFunc f;
160126f70269c80140a7fb8a7aae9ef09c95efa98e70Daniel Veillard    void *arg;
160226f70269c80140a7fb8a7aae9ef09c95efa98e70Daniel Veillard    PyObject *pyobj_reader;
160326f70269c80140a7fb8a7aae9ef09c95efa98e70Daniel Veillard    PyObject *py_retval;
160426f70269c80140a7fb8a7aae9ef09c95efa98e70Daniel Veillard
160526f70269c80140a7fb8a7aae9ef09c95efa98e70Daniel Veillard    if (!PyArg_ParseTuple(args, (char *)"O:xmlTextReaderSetErrorHandler", &pyobj_reader))
160626f70269c80140a7fb8a7aae9ef09c95efa98e70Daniel Veillard        return(NULL);
160726f70269c80140a7fb8a7aae9ef09c95efa98e70Daniel Veillard    reader = (xmlTextReaderPtr) PyxmlTextReader_Get(pyobj_reader);
160826f70269c80140a7fb8a7aae9ef09c95efa98e70Daniel Veillard    xmlTextReaderGetErrorHandler(reader,&f,&arg);
160926f70269c80140a7fb8a7aae9ef09c95efa98e70Daniel Veillard    py_retval = PyTuple_New(2);
161026f70269c80140a7fb8a7aae9ef09c95efa98e70Daniel Veillard    if (f == libxml_xmlTextReaderErrorCallback) {
161126f70269c80140a7fb8a7aae9ef09c95efa98e70Daniel Veillard	/* ok, it's our error handler! */
161226f70269c80140a7fb8a7aae9ef09c95efa98e70Daniel Veillard	pyCtxt = (xmlTextReaderPyCtxtPtr)arg;
161326f70269c80140a7fb8a7aae9ef09c95efa98e70Daniel Veillard	PyTuple_SetItem(py_retval, 0, pyCtxt->f);
161426f70269c80140a7fb8a7aae9ef09c95efa98e70Daniel Veillard	Py_XINCREF(pyCtxt->f);
161526f70269c80140a7fb8a7aae9ef09c95efa98e70Daniel Veillard	PyTuple_SetItem(py_retval, 1, pyCtxt->arg);
161626f70269c80140a7fb8a7aae9ef09c95efa98e70Daniel Veillard	Py_XINCREF(pyCtxt->arg);
161726f70269c80140a7fb8a7aae9ef09c95efa98e70Daniel Veillard    }
161826f70269c80140a7fb8a7aae9ef09c95efa98e70Daniel Veillard    else
161926f70269c80140a7fb8a7aae9ef09c95efa98e70Daniel Veillard    {
162026f70269c80140a7fb8a7aae9ef09c95efa98e70Daniel Veillard	/* f is null or it's not our error handler */
162126f70269c80140a7fb8a7aae9ef09c95efa98e70Daniel Veillard	PyTuple_SetItem(py_retval, 0, Py_None);
162226f70269c80140a7fb8a7aae9ef09c95efa98e70Daniel Veillard	Py_XINCREF(Py_None);
162326f70269c80140a7fb8a7aae9ef09c95efa98e70Daniel Veillard	PyTuple_SetItem(py_retval, 1, Py_None);
162426f70269c80140a7fb8a7aae9ef09c95efa98e70Daniel Veillard	Py_XINCREF(Py_None);
162526f70269c80140a7fb8a7aae9ef09c95efa98e70Daniel Veillard    }
162626f70269c80140a7fb8a7aae9ef09c95efa98e70Daniel Veillard    return(py_retval);
162726f70269c80140a7fb8a7aae9ef09c95efa98e70Daniel Veillard}
162826f70269c80140a7fb8a7aae9ef09c95efa98e70Daniel Veillard
162926f70269c80140a7fb8a7aae9ef09c95efa98e70Daniel VeillardPyObject *
163026f70269c80140a7fb8a7aae9ef09c95efa98e70Daniel Veillardlibxml_xmlFreeTextReader(ATTRIBUTE_UNUSED PyObject *self, PyObject *args) {
163126f70269c80140a7fb8a7aae9ef09c95efa98e70Daniel Veillard    xmlTextReaderPtr reader;
163226f70269c80140a7fb8a7aae9ef09c95efa98e70Daniel Veillard    PyObject *pyobj_reader;
163326f70269c80140a7fb8a7aae9ef09c95efa98e70Daniel Veillard    xmlTextReaderPyCtxtPtr pyCtxt;
163426f70269c80140a7fb8a7aae9ef09c95efa98e70Daniel Veillard    xmlTextReaderErrorFunc f;
163526f70269c80140a7fb8a7aae9ef09c95efa98e70Daniel Veillard    void *arg;
163626f70269c80140a7fb8a7aae9ef09c95efa98e70Daniel Veillard
163726f70269c80140a7fb8a7aae9ef09c95efa98e70Daniel Veillard    if (!PyArg_ParseTuple(args, (char *)"O:xmlFreeTextReader", &pyobj_reader))
163826f70269c80140a7fb8a7aae9ef09c95efa98e70Daniel Veillard        return(NULL);
163926f70269c80140a7fb8a7aae9ef09c95efa98e70Daniel Veillard    reader = (xmlTextReaderPtr) PyxmlTextReader_Get(pyobj_reader);
164026f70269c80140a7fb8a7aae9ef09c95efa98e70Daniel Veillard
164126f70269c80140a7fb8a7aae9ef09c95efa98e70Daniel Veillard    xmlTextReaderGetErrorHandler(reader,&f,&arg);
164226f70269c80140a7fb8a7aae9ef09c95efa98e70Daniel Veillard    if (arg != NULL) {
164326f70269c80140a7fb8a7aae9ef09c95efa98e70Daniel Veillard	if (f == libxml_xmlTextReaderErrorCallback) {
164426f70269c80140a7fb8a7aae9ef09c95efa98e70Daniel Veillard	    /* ok, it's our error handler! */
164526f70269c80140a7fb8a7aae9ef09c95efa98e70Daniel Veillard	    pyCtxt = (xmlTextReaderPyCtxtPtr)arg;
164626f70269c80140a7fb8a7aae9ef09c95efa98e70Daniel Veillard	    Py_XDECREF(pyCtxt->f);
164726f70269c80140a7fb8a7aae9ef09c95efa98e70Daniel Veillard	    Py_XDECREF(pyCtxt->arg);
164826f70269c80140a7fb8a7aae9ef09c95efa98e70Daniel Veillard	    xmlFree(pyCtxt);
164926f70269c80140a7fb8a7aae9ef09c95efa98e70Daniel Veillard	}
165026f70269c80140a7fb8a7aae9ef09c95efa98e70Daniel Veillard	/*
165126f70269c80140a7fb8a7aae9ef09c95efa98e70Daniel Veillard	 * else, something wrong happened, because the error handler is
165226f70269c80140a7fb8a7aae9ef09c95efa98e70Daniel Veillard	 * not owned by the python bindings...
165326f70269c80140a7fb8a7aae9ef09c95efa98e70Daniel Veillard	 */
165426f70269c80140a7fb8a7aae9ef09c95efa98e70Daniel Veillard    }
165526f70269c80140a7fb8a7aae9ef09c95efa98e70Daniel Veillard
165626f70269c80140a7fb8a7aae9ef09c95efa98e70Daniel Veillard    xmlFreeTextReader(reader);
165726f70269c80140a7fb8a7aae9ef09c95efa98e70Daniel Veillard    Py_INCREF(Py_None);
165826f70269c80140a7fb8a7aae9ef09c95efa98e70Daniel Veillard    return(Py_None);
165926f70269c80140a7fb8a7aae9ef09c95efa98e70Daniel Veillard}
166026f70269c80140a7fb8a7aae9ef09c95efa98e70Daniel Veillard
166126f70269c80140a7fb8a7aae9ef09c95efa98e70Daniel Veillard/************************************************************************
166226f70269c80140a7fb8a7aae9ef09c95efa98e70Daniel Veillard *									*
1663a7340c830e4bddd86201cfdb97ac81e30b0dee62Daniel Veillard *			XPath extensions				*
1664a7340c830e4bddd86201cfdb97ac81e30b0dee62Daniel Veillard *									*
1665a7340c830e4bddd86201cfdb97ac81e30b0dee62Daniel Veillard ************************************************************************/
1666a7340c830e4bddd86201cfdb97ac81e30b0dee62Daniel Veillard
1667a7340c830e4bddd86201cfdb97ac81e30b0dee62Daniel Veillardstatic int libxml_xpathCallbacksInitialized = 0;
1668a7340c830e4bddd86201cfdb97ac81e30b0dee62Daniel Veillard
1669a7340c830e4bddd86201cfdb97ac81e30b0dee62Daniel Veillardtypedef struct libxml_xpathCallback {
1670a7340c830e4bddd86201cfdb97ac81e30b0dee62Daniel Veillard    xmlXPathContextPtr ctx;
1671a7340c830e4bddd86201cfdb97ac81e30b0dee62Daniel Veillard    xmlChar *name;
1672a7340c830e4bddd86201cfdb97ac81e30b0dee62Daniel Veillard    xmlChar *ns_uri;
1673a7340c830e4bddd86201cfdb97ac81e30b0dee62Daniel Veillard    PyObject *function;
1674a7340c830e4bddd86201cfdb97ac81e30b0dee62Daniel Veillard} libxml_xpathCallback, *libxml_xpathCallbackPtr;
1675a7340c830e4bddd86201cfdb97ac81e30b0dee62Daniel Veillardstatic libxml_xpathCallback libxml_xpathCallbacks[10];
1676a7340c830e4bddd86201cfdb97ac81e30b0dee62Daniel Veillardstatic int libxml_xpathCallbacksNb = 0;
1677a7340c830e4bddd86201cfdb97ac81e30b0dee62Daniel Veillardstatic int libxml_xpathCallbacksMax = 10;
1678a7340c830e4bddd86201cfdb97ac81e30b0dee62Daniel Veillard
1679a7340c830e4bddd86201cfdb97ac81e30b0dee62Daniel Veillardstatic void
1680d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillardlibxml_xmlXPathFuncCallback(xmlXPathParserContextPtr ctxt, int nargs)
1681d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard{
1682a7340c830e4bddd86201cfdb97ac81e30b0dee62Daniel Veillard    PyObject *list, *cur, *result;
1683a7340c830e4bddd86201cfdb97ac81e30b0dee62Daniel Veillard    xmlXPathObjectPtr obj;
168470cab35abbb75eb9f0e328d498aa7a85195a1d5bDaniel Veillard    xmlXPathContextPtr rctxt;
168570cab35abbb75eb9f0e328d498aa7a85195a1d5bDaniel Veillard    PyObject *current_function = NULL;
168670cab35abbb75eb9f0e328d498aa7a85195a1d5bDaniel Veillard    const xmlChar *name;
168770cab35abbb75eb9f0e328d498aa7a85195a1d5bDaniel Veillard    const xmlChar *ns_uri;
1688a7340c830e4bddd86201cfdb97ac81e30b0dee62Daniel Veillard    int i;
1689a7340c830e4bddd86201cfdb97ac81e30b0dee62Daniel Veillard
169070cab35abbb75eb9f0e328d498aa7a85195a1d5bDaniel Veillard    if (ctxt == NULL)
1691d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        return;
169270cab35abbb75eb9f0e328d498aa7a85195a1d5bDaniel Veillard    rctxt = ctxt->context;
169370cab35abbb75eb9f0e328d498aa7a85195a1d5bDaniel Veillard    if (rctxt == NULL)
1694d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        return;
169570cab35abbb75eb9f0e328d498aa7a85195a1d5bDaniel Veillard    name = rctxt->function;
169670cab35abbb75eb9f0e328d498aa7a85195a1d5bDaniel Veillard    ns_uri = rctxt->functionURI;
1697a7340c830e4bddd86201cfdb97ac81e30b0dee62Daniel Veillard#ifdef DEBUG_XPATH
1698d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard    printf("libxml_xmlXPathFuncCallback called name %s URI %s\n", name,
1699d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard           ns_uri);
1700a7340c830e4bddd86201cfdb97ac81e30b0dee62Daniel Veillard#endif
1701a7340c830e4bddd86201cfdb97ac81e30b0dee62Daniel Veillard
170270cab35abbb75eb9f0e328d498aa7a85195a1d5bDaniel Veillard    /*
170370cab35abbb75eb9f0e328d498aa7a85195a1d5bDaniel Veillard     * Find the function, it should be there it was there at lookup
170470cab35abbb75eb9f0e328d498aa7a85195a1d5bDaniel Veillard     */
1705d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard    for (i = 0; i < libxml_xpathCallbacksNb; i++) {
1706d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        if (                    /* TODO (ctxt == libxml_xpathCallbacks[i].ctx) && */
1707d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard               (xmlStrEqual(name, libxml_xpathCallbacks[i].name)) &&
1708d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard               (xmlStrEqual(ns_uri, libxml_xpathCallbacks[i].ns_uri))) {
1709d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            current_function = libxml_xpathCallbacks[i].function;
1710d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        }
171170cab35abbb75eb9f0e328d498aa7a85195a1d5bDaniel Veillard    }
171270cab35abbb75eb9f0e328d498aa7a85195a1d5bDaniel Veillard    if (current_function == NULL) {
1713d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        printf
1714d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            ("libxml_xmlXPathFuncCallback: internal error %s not found !\n",
1715d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard             name);
1716d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        return;
171770cab35abbb75eb9f0e328d498aa7a85195a1d5bDaniel Veillard    }
171870cab35abbb75eb9f0e328d498aa7a85195a1d5bDaniel Veillard
1719c575b997d85d4791d852ad43e175d47a64cf8b3cDaniel Veillard    list = PyTuple_New(nargs + 1);
1720c575b997d85d4791d852ad43e175d47a64cf8b3cDaniel Veillard    PyTuple_SetItem(list, 0, libxml_xmlXPathParserContextPtrWrap(ctxt));
1721d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard    for (i = 0; i < nargs; i++) {
1722d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        obj = valuePop(ctxt);
1723d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        cur = libxml_xmlXPathObjectPtrWrap(obj);
1724d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        PyTuple_SetItem(list, i + 1, cur);
1725a7340c830e4bddd86201cfdb97ac81e30b0dee62Daniel Veillard    }
1726a7340c830e4bddd86201cfdb97ac81e30b0dee62Daniel Veillard    result = PyEval_CallObject(current_function, list);
1727a7340c830e4bddd86201cfdb97ac81e30b0dee62Daniel Veillard    Py_DECREF(list);
1728a7340c830e4bddd86201cfdb97ac81e30b0dee62Daniel Veillard
1729a7340c830e4bddd86201cfdb97ac81e30b0dee62Daniel Veillard    obj = libxml_xmlXPathObjectPtrConvert(result);
1730a7340c830e4bddd86201cfdb97ac81e30b0dee62Daniel Veillard    valuePush(ctxt, obj);
1731a7340c830e4bddd86201cfdb97ac81e30b0dee62Daniel Veillard}
1732a7340c830e4bddd86201cfdb97ac81e30b0dee62Daniel Veillard
1733a7340c830e4bddd86201cfdb97ac81e30b0dee62Daniel Veillardstatic xmlXPathFunction
1734d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillardlibxml_xmlXPathFuncLookupFunc(void *ctxt, const xmlChar * name,
1735d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard                              const xmlChar * ns_uri)
1736d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard{
1737a7340c830e4bddd86201cfdb97ac81e30b0dee62Daniel Veillard    int i;
1738d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard
1739a7340c830e4bddd86201cfdb97ac81e30b0dee62Daniel Veillard#ifdef DEBUG_XPATH
1740a7340c830e4bddd86201cfdb97ac81e30b0dee62Daniel Veillard    printf("libxml_xmlXPathFuncLookupFunc(%p, %s, %s) called\n",
1741d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard           ctxt, name, ns_uri);
1742a7340c830e4bddd86201cfdb97ac81e30b0dee62Daniel Veillard#endif
174370cab35abbb75eb9f0e328d498aa7a85195a1d5bDaniel Veillard    /*
174470cab35abbb75eb9f0e328d498aa7a85195a1d5bDaniel Veillard     * This is called once only. The address is then stored in the
174570cab35abbb75eb9f0e328d498aa7a85195a1d5bDaniel Veillard     * XPath expression evaluation, the proper object to call can
174670cab35abbb75eb9f0e328d498aa7a85195a1d5bDaniel Veillard     * then still be found using the execution context function
174770cab35abbb75eb9f0e328d498aa7a85195a1d5bDaniel Veillard     * and functionURI fields.
174870cab35abbb75eb9f0e328d498aa7a85195a1d5bDaniel Veillard     */
1749d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard    for (i = 0; i < libxml_xpathCallbacksNb; i++) {
1750d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        if ((ctxt == libxml_xpathCallbacks[i].ctx) &&
1751d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            (xmlStrEqual(name, libxml_xpathCallbacks[i].name)) &&
1752d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            (xmlStrEqual(ns_uri, libxml_xpathCallbacks[i].ns_uri))) {
1753d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            return (libxml_xmlXPathFuncCallback);
1754d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        }
1755a7340c830e4bddd86201cfdb97ac81e30b0dee62Daniel Veillard    }
1756d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard    return (NULL);
1757a7340c830e4bddd86201cfdb97ac81e30b0dee62Daniel Veillard}
1758a7340c830e4bddd86201cfdb97ac81e30b0dee62Daniel Veillard
1759a7340c830e4bddd86201cfdb97ac81e30b0dee62Daniel Veillardstatic void
1760d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillardlibxml_xpathCallbacksInitialize(void)
1761d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard{
1762a7340c830e4bddd86201cfdb97ac81e30b0dee62Daniel Veillard    int i;
1763a7340c830e4bddd86201cfdb97ac81e30b0dee62Daniel Veillard
1764a7340c830e4bddd86201cfdb97ac81e30b0dee62Daniel Veillard    if (libxml_xpathCallbacksInitialized != 0)
1765d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        return;
1766a7340c830e4bddd86201cfdb97ac81e30b0dee62Daniel Veillard
1767a7340c830e4bddd86201cfdb97ac81e30b0dee62Daniel Veillard#ifdef DEBUG_XPATH
1768a7340c830e4bddd86201cfdb97ac81e30b0dee62Daniel Veillard    printf("libxml_xpathCallbacksInitialized called\n");
1769a7340c830e4bddd86201cfdb97ac81e30b0dee62Daniel Veillard#endif
1770a7340c830e4bddd86201cfdb97ac81e30b0dee62Daniel Veillard
1771781ac8b19bfc10635a8bb83158f874116fd7559eDaniel Veillard    for (i = 0; i < libxml_xpathCallbacksMax; i++) {
1772d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        libxml_xpathCallbacks[i].ctx = NULL;
1773d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        libxml_xpathCallbacks[i].name = NULL;
1774d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        libxml_xpathCallbacks[i].ns_uri = NULL;
1775d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        libxml_xpathCallbacks[i].function = NULL;
1776a7340c830e4bddd86201cfdb97ac81e30b0dee62Daniel Veillard    }
1777a7340c830e4bddd86201cfdb97ac81e30b0dee62Daniel Veillard    libxml_xpathCallbacksInitialized = 1;
1778a7340c830e4bddd86201cfdb97ac81e30b0dee62Daniel Veillard}
1779a7340c830e4bddd86201cfdb97ac81e30b0dee62Daniel Veillard
1780a7340c830e4bddd86201cfdb97ac81e30b0dee62Daniel VeillardPyObject *
1781d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillardlibxml_xmlRegisterXPathFunction(ATTRIBUTE_UNUSED PyObject * self,
1782d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard                                PyObject * args)
1783d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard{
1784a7340c830e4bddd86201cfdb97ac81e30b0dee62Daniel Veillard    PyObject *py_retval;
1785a7340c830e4bddd86201cfdb97ac81e30b0dee62Daniel Veillard    int c_retval = 0;
1786a7340c830e4bddd86201cfdb97ac81e30b0dee62Daniel Veillard    xmlChar *name;
1787a7340c830e4bddd86201cfdb97ac81e30b0dee62Daniel Veillard    xmlChar *ns_uri;
1788a7340c830e4bddd86201cfdb97ac81e30b0dee62Daniel Veillard    xmlXPathContextPtr ctx;
1789a7340c830e4bddd86201cfdb97ac81e30b0dee62Daniel Veillard    PyObject *pyobj_ctx;
1790a7340c830e4bddd86201cfdb97ac81e30b0dee62Daniel Veillard    PyObject *pyobj_f;
1791a7340c830e4bddd86201cfdb97ac81e30b0dee62Daniel Veillard    int i;
1792a7340c830e4bddd86201cfdb97ac81e30b0dee62Daniel Veillard
1793d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard    if (!PyArg_ParseTuple
1794d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        (args, (char *) "OszO:registerXPathFunction", &pyobj_ctx, &name,
1795d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard         &ns_uri, &pyobj_f))
1796d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        return (NULL);
1797a7340c830e4bddd86201cfdb97ac81e30b0dee62Daniel Veillard
1798a7340c830e4bddd86201cfdb97ac81e30b0dee62Daniel Veillard    ctx = (xmlXPathContextPtr) PyxmlXPathContext_Get(pyobj_ctx);
1799a7340c830e4bddd86201cfdb97ac81e30b0dee62Daniel Veillard    if (libxml_xpathCallbacksInitialized == 0)
1800d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        libxml_xpathCallbacksInitialize();
1801a7340c830e4bddd86201cfdb97ac81e30b0dee62Daniel Veillard    xmlXPathRegisterFuncLookup(ctx, libxml_xmlXPathFuncLookupFunc, ctx);
1802a7340c830e4bddd86201cfdb97ac81e30b0dee62Daniel Veillard
1803a7340c830e4bddd86201cfdb97ac81e30b0dee62Daniel Veillard    if ((pyobj_ctx == NULL) || (name == NULL) || (pyobj_f == NULL)) {
1804d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        py_retval = libxml_intWrap(-1);
1805d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        return (py_retval);
1806a7340c830e4bddd86201cfdb97ac81e30b0dee62Daniel Veillard    }
1807a7340c830e4bddd86201cfdb97ac81e30b0dee62Daniel Veillard#ifdef DEBUG_XPATH
1808a7340c830e4bddd86201cfdb97ac81e30b0dee62Daniel Veillard    printf("libxml_registerXPathFunction(%p, %s, %s) called\n",
1809d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard           ctx, name, ns_uri);
1810a7340c830e4bddd86201cfdb97ac81e30b0dee62Daniel Veillard#endif
1811d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard    for (i = 0; i < libxml_xpathCallbacksNb; i++) {
1812d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        if ((ctx == libxml_xpathCallbacks[i].ctx) &&
1813d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            (xmlStrEqual(name, libxml_xpathCallbacks[i].name)) &&
1814d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            (xmlStrEqual(ns_uri, libxml_xpathCallbacks[i].ns_uri))) {
1815d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            Py_XINCREF(pyobj_f);
1816d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            Py_XDECREF(libxml_xpathCallbacks[i].function);
1817d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            libxml_xpathCallbacks[i].function = pyobj_f;
1818d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            c_retval = 1;
1819d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            goto done;
1820d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        }
1821a7340c830e4bddd86201cfdb97ac81e30b0dee62Daniel Veillard    }
1822a7340c830e4bddd86201cfdb97ac81e30b0dee62Daniel Veillard    if (libxml_xpathCallbacksNb >= libxml_xpathCallbacksMax) {
1823d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        printf("libxml_registerXPathFunction() table full\n");
1824a7340c830e4bddd86201cfdb97ac81e30b0dee62Daniel Veillard    } else {
1825d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        i = libxml_xpathCallbacksNb++;
1826d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        Py_XINCREF(pyobj_f);
1827a7340c830e4bddd86201cfdb97ac81e30b0dee62Daniel Veillard        libxml_xpathCallbacks[i].ctx = ctx;
1828a7340c830e4bddd86201cfdb97ac81e30b0dee62Daniel Veillard        libxml_xpathCallbacks[i].name = xmlStrdup(name);
1829a7340c830e4bddd86201cfdb97ac81e30b0dee62Daniel Veillard        libxml_xpathCallbacks[i].ns_uri = xmlStrdup(ns_uri);
1830d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        libxml_xpathCallbacks[i].function = pyobj_f;
1831d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        c_retval = 1;
1832a7340c830e4bddd86201cfdb97ac81e30b0dee62Daniel Veillard    }
1833d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard  done:
1834a7340c830e4bddd86201cfdb97ac81e30b0dee62Daniel Veillard    py_retval = libxml_intWrap((int) c_retval);
1835d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard    return (py_retval);
1836a7340c830e4bddd86201cfdb97ac81e30b0dee62Daniel Veillard}
1837a7340c830e4bddd86201cfdb97ac81e30b0dee62Daniel Veillard
18381971ee2698cb84c7699c96d3302f00e20d42c0d3Daniel Veillard/************************************************************************
18391971ee2698cb84c7699c96d3302f00e20d42c0d3Daniel Veillard *									*
1840d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard *			Global properties access			*
1841d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard *									*
1842d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard ************************************************************************/
1843d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillardstatic PyObject *
1844d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillardlibxml_name(ATTRIBUTE_UNUSED PyObject * self, PyObject * args)
1845d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard{
1846d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard    PyObject *resultobj, *obj;
1847d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard    xmlNodePtr cur;
1848d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard    const xmlChar *res;
1849d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard
1850d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard    if (!PyArg_ParseTuple(args, (char *) "O:name", &obj))
1851d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard        return NULL;
1852d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard    cur = PyxmlNode_Get(obj);
1853d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard
1854d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard#ifdef DEBUG
1855d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard    printf("libxml_name: cur = %p type %d\n", cur, cur->type);
1856d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard#endif
1857d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard
1858d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard    switch (cur->type) {
1859d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        case XML_DOCUMENT_NODE:
1860d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard#ifdef LIBXML_DOCB_ENABLED
1861d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        case XML_DOCB_DOCUMENT_NODE:
1862d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard#endif
1863d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        case XML_HTML_DOCUMENT_NODE:{
1864d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard                xmlDocPtr doc = (xmlDocPtr) cur;
1865d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard
1866d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard                res = doc->URL;
1867d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard                break;
1868d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            }
1869d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        case XML_ATTRIBUTE_NODE:{
1870d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard                xmlAttrPtr attr = (xmlAttrPtr) cur;
1871d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard
1872d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard                res = attr->name;
1873d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard                break;
1874d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            }
1875d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        case XML_NAMESPACE_DECL:{
1876d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard                xmlNsPtr ns = (xmlNsPtr) cur;
1877d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard
1878d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard                res = ns->prefix;
1879d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard                break;
1880d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            }
1881d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        default:
1882d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            res = cur->name;
1883d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            break;
1884d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard    }
18851971ee2698cb84c7699c96d3302f00e20d42c0d3Daniel Veillard    resultobj = libxml_constxmlCharPtrWrap(res);
1886d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard
1887d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard    return resultobj;
1888d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard}
1889d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard
1890d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillardstatic PyObject *
1891d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillardlibxml_doc(ATTRIBUTE_UNUSED PyObject * self, PyObject * args)
1892d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard{
1893d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard    PyObject *resultobj, *obj;
1894d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard    xmlNodePtr cur;
1895d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard    xmlDocPtr res;
1896d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard
1897d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard    if (!PyArg_ParseTuple(args, (char *) "O:doc", &obj))
1898d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard        return NULL;
1899d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard    cur = PyxmlNode_Get(obj);
1900d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard
1901d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard#ifdef DEBUG
1902d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard    printf("libxml_doc: cur = %p\n", cur);
1903d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard#endif
1904d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard
1905d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard    switch (cur->type) {
1906d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        case XML_DOCUMENT_NODE:
1907d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard#ifdef LIBXML_DOCB_ENABLED
1908d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        case XML_DOCB_DOCUMENT_NODE:
1909d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard#endif
1910d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        case XML_HTML_DOCUMENT_NODE:
1911d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            res = NULL;
1912d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            break;
1913d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        case XML_ATTRIBUTE_NODE:{
1914d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard                xmlAttrPtr attr = (xmlAttrPtr) cur;
1915d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard
1916d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard                res = attr->doc;
1917d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard                break;
1918d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            }
1919d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        case XML_NAMESPACE_DECL:
1920d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            res = NULL;
1921d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            break;
1922d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        default:
1923d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            res = cur->doc;
1924d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            break;
1925d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard    }
1926d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard    resultobj = libxml_xmlDocPtrWrap(res);
1927d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard    return resultobj;
1928d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard}
1929d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard
1930d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillardstatic PyObject *
1931d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillardlibxml_properties(ATTRIBUTE_UNUSED PyObject * self, PyObject * args)
1932d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard{
1933d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard    PyObject *resultobj, *obj;
1934d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard    xmlNodePtr cur = NULL;
1935d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard    xmlAttrPtr res;
1936d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard
1937d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard    if (!PyArg_ParseTuple(args, (char *) "O:properties", &obj))
1938d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard        return NULL;
1939d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard    cur = PyxmlNode_Get(obj);
1940d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard    if (cur->type == XML_ELEMENT_NODE)
1941d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        res = cur->properties;
1942d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard    else
1943d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        res = NULL;
1944d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard    resultobj = libxml_xmlAttrPtrWrap(res);
1945d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard    return resultobj;
1946d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard}
1947d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard
1948d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillardstatic PyObject *
1949d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillardlibxml_next(ATTRIBUTE_UNUSED PyObject * self, PyObject * args)
1950d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard{
1951d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard    PyObject *resultobj, *obj;
1952d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard    xmlNodePtr cur;
1953d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard    xmlNodePtr res;
1954d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard
1955d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard    if (!PyArg_ParseTuple(args, (char *) "O:next", &obj))
1956d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard        return NULL;
1957d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard    cur = PyxmlNode_Get(obj);
1958d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard
1959d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard#ifdef DEBUG
1960d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard    printf("libxml_next: cur = %p\n", cur);
1961d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard#endif
1962d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard
1963d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard    switch (cur->type) {
1964d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        case XML_DOCUMENT_NODE:
1965d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard#ifdef LIBXML_DOCB_ENABLED
1966d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        case XML_DOCB_DOCUMENT_NODE:
1967d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard#endif
1968d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        case XML_HTML_DOCUMENT_NODE:
1969d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            res = NULL;
1970d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            break;
1971d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        case XML_ATTRIBUTE_NODE:{
1972d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard                xmlAttrPtr attr = (xmlAttrPtr) cur;
1973d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard
1974d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard                res = (xmlNodePtr) attr->next;
1975d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard                break;
1976d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            }
1977d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        case XML_NAMESPACE_DECL:{
1978d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard                xmlNsPtr ns = (xmlNsPtr) cur;
1979d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard
1980d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard                res = (xmlNodePtr) ns->next;
1981d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard                break;
1982d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            }
1983d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        default:
1984d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            res = cur->next;
1985d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            break;
1986d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard
1987d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard    }
1988d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard    resultobj = libxml_xmlNodePtrWrap(res);
1989d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard    return resultobj;
1990d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard}
1991d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard
1992d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillardstatic PyObject *
1993d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillardlibxml_prev(ATTRIBUTE_UNUSED PyObject * self, PyObject * args)
1994d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard{
1995d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard    PyObject *resultobj, *obj;
1996d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard    xmlNodePtr cur;
1997d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard    xmlNodePtr res;
1998d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard
1999d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard    if (!PyArg_ParseTuple(args, (char *) "O:prev", &obj))
2000d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard        return NULL;
2001d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard    cur = PyxmlNode_Get(obj);
2002d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard
2003d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard#ifdef DEBUG
2004d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard    printf("libxml_prev: cur = %p\n", cur);
2005d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard#endif
2006d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard
2007d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard    switch (cur->type) {
2008d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        case XML_DOCUMENT_NODE:
2009d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard#ifdef LIBXML_DOCB_ENABLED
2010d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        case XML_DOCB_DOCUMENT_NODE:
2011d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard#endif
2012d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        case XML_HTML_DOCUMENT_NODE:
2013d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            res = NULL;
2014d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            break;
2015d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        case XML_ATTRIBUTE_NODE:{
2016d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard                xmlAttrPtr attr = (xmlAttrPtr) cur;
2017d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard
2018faa35ff3cdcf15154dd207606a31b34923da9be9Daniel Veillard                res = (xmlNodePtr) attr->prev;
2019d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            }
2020d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        case XML_NAMESPACE_DECL:
2021d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            res = NULL;
2022d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            break;
2023d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        default:
2024faa35ff3cdcf15154dd207606a31b34923da9be9Daniel Veillard            res = cur->prev;
2025d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            break;
2026d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard    }
2027d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard    resultobj = libxml_xmlNodePtrWrap(res);
2028d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard    return resultobj;
2029d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard}
2030d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard
2031d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillardstatic PyObject *
2032d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillardlibxml_children(ATTRIBUTE_UNUSED PyObject * self, PyObject * args)
2033d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard{
2034d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard    PyObject *resultobj, *obj;
2035d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard    xmlNodePtr cur;
2036d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard    xmlNodePtr res;
2037d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard
2038d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard    if (!PyArg_ParseTuple(args, (char *) "O:children", &obj))
2039d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard        return NULL;
2040d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard    cur = PyxmlNode_Get(obj);
2041d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard
2042d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard#ifdef DEBUG
2043d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard    printf("libxml_children: cur = %p\n", cur);
2044d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard#endif
2045d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard
2046d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard    switch (cur->type) {
2047d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        case XML_ELEMENT_NODE:
2048d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        case XML_ENTITY_REF_NODE:
2049d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        case XML_ENTITY_NODE:
2050d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        case XML_PI_NODE:
2051d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        case XML_COMMENT_NODE:
2052d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        case XML_DOCUMENT_NODE:
2053d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard#ifdef LIBXML_DOCB_ENABLED
2054d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        case XML_DOCB_DOCUMENT_NODE:
2055d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard#endif
2056d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        case XML_HTML_DOCUMENT_NODE:
2057d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        case XML_DTD_NODE:
2058d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            res = cur->children;
2059d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            break;
2060d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        case XML_ATTRIBUTE_NODE:{
2061d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard                xmlAttrPtr attr = (xmlAttrPtr) cur;
2062d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard
2063d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard                res = attr->children;
2064d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard                break;
2065d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            }
2066d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        default:
2067d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            res = NULL;
2068d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            break;
2069d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard    }
2070d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard    resultobj = libxml_xmlNodePtrWrap(res);
2071d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard    return resultobj;
2072d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard}
2073d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard
2074d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillardstatic PyObject *
2075d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillardlibxml_last(ATTRIBUTE_UNUSED PyObject * self, PyObject * args)
2076d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard{
2077d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard    PyObject *resultobj, *obj;
2078d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard    xmlNodePtr cur;
2079d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard    xmlNodePtr res;
2080d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard
2081d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard    if (!PyArg_ParseTuple(args, (char *) "O:last", &obj))
2082d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard        return NULL;
2083d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard    cur = PyxmlNode_Get(obj);
2084d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard
2085d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard#ifdef DEBUG
2086d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard    printf("libxml_last: cur = %p\n", cur);
2087d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard#endif
2088d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard
2089d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard    switch (cur->type) {
2090d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        case XML_ELEMENT_NODE:
2091d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        case XML_ENTITY_REF_NODE:
2092d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        case XML_ENTITY_NODE:
2093d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        case XML_PI_NODE:
2094d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        case XML_COMMENT_NODE:
2095d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        case XML_DOCUMENT_NODE:
2096d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard#ifdef LIBXML_DOCB_ENABLED
2097d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        case XML_DOCB_DOCUMENT_NODE:
2098d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard#endif
2099d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        case XML_HTML_DOCUMENT_NODE:
2100d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        case XML_DTD_NODE:
2101d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            res = cur->last;
2102d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            break;
2103d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        case XML_ATTRIBUTE_NODE:{
2104d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard                xmlAttrPtr attr = (xmlAttrPtr) cur;
2105d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard
2106d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard                res = attr->last;
2107d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            }
2108d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        default:
2109d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            res = NULL;
2110d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            break;
2111d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard    }
2112d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard    resultobj = libxml_xmlNodePtrWrap(res);
2113d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard    return resultobj;
2114d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard}
2115d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard
2116d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillardstatic PyObject *
2117d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillardlibxml_parent(ATTRIBUTE_UNUSED PyObject * self, PyObject * args)
2118d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard{
2119d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard    PyObject *resultobj, *obj;
2120d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard    xmlNodePtr cur;
2121d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard    xmlNodePtr res;
2122d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard
2123d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard    if (!PyArg_ParseTuple(args, (char *) "O:parent", &obj))
2124d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard        return NULL;
2125d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard    cur = PyxmlNode_Get(obj);
2126d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard
2127d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard#ifdef DEBUG
2128d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard    printf("libxml_parent: cur = %p\n", cur);
2129d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard#endif
2130d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard
2131d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard    switch (cur->type) {
2132d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        case XML_DOCUMENT_NODE:
2133d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        case XML_HTML_DOCUMENT_NODE:
2134d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard#ifdef LIBXML_DOCB_ENABLED
2135d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        case XML_DOCB_DOCUMENT_NODE:
2136d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard#endif
2137d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            res = NULL;
2138d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            break;
2139d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        case XML_ATTRIBUTE_NODE:{
2140d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard                xmlAttrPtr attr = (xmlAttrPtr) cur;
2141d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard
2142d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard                res = attr->parent;
2143d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            }
2144d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        case XML_ENTITY_DECL:
2145d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        case XML_NAMESPACE_DECL:
2146d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        case XML_XINCLUDE_START:
2147d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        case XML_XINCLUDE_END:
2148d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            res = NULL;
2149d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            break;
2150d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        default:
2151d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            res = cur->parent;
2152d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            break;
2153d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard    }
2154d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard    resultobj = libxml_xmlNodePtrWrap(res);
2155d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard    return resultobj;
2156d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard}
2157d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard
2158d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillardstatic PyObject *
2159d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillardlibxml_type(ATTRIBUTE_UNUSED PyObject * self, PyObject * args)
2160d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard{
2161d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard    PyObject *resultobj, *obj;
2162d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard    xmlNodePtr cur;
2163d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard    const xmlChar *res = NULL;
2164d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard
2165d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard    if (!PyArg_ParseTuple(args, (char *) "O:last", &obj))
2166d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard        return NULL;
2167d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard    cur = PyxmlNode_Get(obj);
2168d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard
2169d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard#ifdef DEBUG
2170d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard    printf("libxml_type: cur = %p\n", cur);
2171d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard#endif
2172d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard
2173d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard    switch (cur->type) {
2174d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard        case XML_ELEMENT_NODE:
2175d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            res = (const xmlChar *) "element";
2176d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            break;
2177d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard        case XML_ATTRIBUTE_NODE:
2178d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            res = (const xmlChar *) "attribute";
2179d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            break;
2180d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard        case XML_TEXT_NODE:
2181d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            res = (const xmlChar *) "text";
2182d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            break;
2183d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard        case XML_CDATA_SECTION_NODE:
2184d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            res = (const xmlChar *) "cdata";
2185d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            break;
2186d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard        case XML_ENTITY_REF_NODE:
2187d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            res = (const xmlChar *) "entity_ref";
2188d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            break;
2189d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard        case XML_ENTITY_NODE:
2190d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            res = (const xmlChar *) "entity";
2191d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            break;
2192d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard        case XML_PI_NODE:
2193d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            res = (const xmlChar *) "pi";
2194d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            break;
2195d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard        case XML_COMMENT_NODE:
2196d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            res = (const xmlChar *) "comment";
2197d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            break;
2198d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard        case XML_DOCUMENT_NODE:
2199d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            res = (const xmlChar *) "document_xml";
2200d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            break;
2201d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard        case XML_DOCUMENT_TYPE_NODE:
2202d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            res = (const xmlChar *) "doctype";
2203d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            break;
2204d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard        case XML_DOCUMENT_FRAG_NODE:
2205d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            res = (const xmlChar *) "fragment";
2206d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            break;
2207d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard        case XML_NOTATION_NODE:
2208d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            res = (const xmlChar *) "notation";
2209d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            break;
2210d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard        case XML_HTML_DOCUMENT_NODE:
2211d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            res = (const xmlChar *) "document_html";
2212d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            break;
2213d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard        case XML_DTD_NODE:
2214d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            res = (const xmlChar *) "dtd";
2215d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            break;
2216d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard        case XML_ELEMENT_DECL:
2217d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            res = (const xmlChar *) "elem_decl";
2218d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            break;
2219d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard        case XML_ATTRIBUTE_DECL:
2220d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            res = (const xmlChar *) "attribute_decl";
2221d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            break;
2222d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard        case XML_ENTITY_DECL:
2223d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            res = (const xmlChar *) "entity_decl";
2224d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            break;
2225d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard        case XML_NAMESPACE_DECL:
2226d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            res = (const xmlChar *) "namespace";
2227d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            break;
2228d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard        case XML_XINCLUDE_START:
2229d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            res = (const xmlChar *) "xinclude_start";
2230d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            break;
2231d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard        case XML_XINCLUDE_END:
2232d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            res = (const xmlChar *) "xinclude_end";
2233d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            break;
2234d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard#ifdef LIBXML_DOCB_ENABLED
2235d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        case XML_DOCB_DOCUMENT_NODE:
2236d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            res = (const xmlChar *) "document_docbook";
2237d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            break;
2238d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard#endif
2239d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard    }
2240d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard#ifdef DEBUG
2241d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard    printf("libxml_type: cur = %p: %s\n", cur, res);
2242d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard#endif
2243d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard
22441971ee2698cb84c7699c96d3302f00e20d42c0d3Daniel Veillard    resultobj = libxml_constxmlCharPtrWrap(res);
2245d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard    return resultobj;
2246d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard}
2247d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard
2248d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard/************************************************************************
2249d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard *									*
225036eea2d2ee84132e66552f84724e9b377d687681Daniel Veillard *			Specific accessor functions			*
225136eea2d2ee84132e66552f84724e9b377d687681Daniel Veillard *									*
225236eea2d2ee84132e66552f84724e9b377d687681Daniel Veillard ************************************************************************/
225336eea2d2ee84132e66552f84724e9b377d687681Daniel VeillardPyObject *
2254d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillardlibxml_xmlNodeGetNsDefs(ATTRIBUTE_UNUSED PyObject * self, PyObject * args)
2255d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard{
225636eea2d2ee84132e66552f84724e9b377d687681Daniel Veillard    PyObject *py_retval;
225736eea2d2ee84132e66552f84724e9b377d687681Daniel Veillard    xmlNsPtr c_retval;
225836eea2d2ee84132e66552f84724e9b377d687681Daniel Veillard    xmlNodePtr node;
225936eea2d2ee84132e66552f84724e9b377d687681Daniel Veillard    PyObject *pyobj_node;
226036eea2d2ee84132e66552f84724e9b377d687681Daniel Veillard
2261d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard    if (!PyArg_ParseTuple
2262d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        (args, (char *) "O:xmlNodeGetNsDefs", &pyobj_node))
2263d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        return (NULL);
226436eea2d2ee84132e66552f84724e9b377d687681Daniel Veillard    node = (xmlNodePtr) PyxmlNode_Get(pyobj_node);
226536eea2d2ee84132e66552f84724e9b377d687681Daniel Veillard
226636eea2d2ee84132e66552f84724e9b377d687681Daniel Veillard    if ((node == NULL) || (node->type != XML_ELEMENT_NODE)) {
2267d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        Py_INCREF(Py_None);
2268d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        return (Py_None);
226936eea2d2ee84132e66552f84724e9b377d687681Daniel Veillard    }
227036eea2d2ee84132e66552f84724e9b377d687681Daniel Veillard    c_retval = node->nsDef;
227136eea2d2ee84132e66552f84724e9b377d687681Daniel Veillard    py_retval = libxml_xmlNsPtrWrap((xmlNsPtr) c_retval);
2272d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard    return (py_retval);
227336eea2d2ee84132e66552f84724e9b377d687681Daniel Veillard}
227436eea2d2ee84132e66552f84724e9b377d687681Daniel Veillard
227536eea2d2ee84132e66552f84724e9b377d687681Daniel VeillardPyObject *
2276d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillardlibxml_xmlNodeGetNs(ATTRIBUTE_UNUSED PyObject * self, PyObject * args)
2277d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard{
227836eea2d2ee84132e66552f84724e9b377d687681Daniel Veillard    PyObject *py_retval;
227936eea2d2ee84132e66552f84724e9b377d687681Daniel Veillard    xmlNsPtr c_retval;
228036eea2d2ee84132e66552f84724e9b377d687681Daniel Veillard    xmlNodePtr node;
228136eea2d2ee84132e66552f84724e9b377d687681Daniel Veillard    PyObject *pyobj_node;
228236eea2d2ee84132e66552f84724e9b377d687681Daniel Veillard
2283d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard    if (!PyArg_ParseTuple(args, (char *) "O:xmlNodeGetNs", &pyobj_node))
2284d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        return (NULL);
228536eea2d2ee84132e66552f84724e9b377d687681Daniel Veillard    node = (xmlNodePtr) PyxmlNode_Get(pyobj_node);
228636eea2d2ee84132e66552f84724e9b377d687681Daniel Veillard
228736eea2d2ee84132e66552f84724e9b377d687681Daniel Veillard    if ((node == NULL) || (node->type != XML_ELEMENT_NODE)) {
2288d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        Py_INCREF(Py_None);
2289d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        return (Py_None);
229036eea2d2ee84132e66552f84724e9b377d687681Daniel Veillard    }
229136eea2d2ee84132e66552f84724e9b377d687681Daniel Veillard    c_retval = node->ns;
229236eea2d2ee84132e66552f84724e9b377d687681Daniel Veillard    py_retval = libxml_xmlNsPtrWrap((xmlNsPtr) c_retval);
2293d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard    return (py_retval);
229436eea2d2ee84132e66552f84724e9b377d687681Daniel Veillard}
229536eea2d2ee84132e66552f84724e9b377d687681Daniel Veillard
229636eea2d2ee84132e66552f84724e9b377d687681Daniel Veillard/************************************************************************
229736eea2d2ee84132e66552f84724e9b377d687681Daniel Veillard *									*
22981e77438da7dd912885effa97b1079867d1e041beDaniel Veillard *			Serialization front-end				*
22991e77438da7dd912885effa97b1079867d1e041beDaniel Veillard *									*
23001e77438da7dd912885effa97b1079867d1e041beDaniel Veillard ************************************************************************/
23011e77438da7dd912885effa97b1079867d1e041beDaniel Veillard
2302d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillardstatic PyObject *
2303d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillardlibxml_serializeNode(ATTRIBUTE_UNUSED PyObject * self, PyObject * args)
2304d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard{
23051e77438da7dd912885effa97b1079867d1e041beDaniel Veillard    PyObject *py_retval = NULL;
23061e77438da7dd912885effa97b1079867d1e041beDaniel Veillard    xmlChar *c_retval;
23071e77438da7dd912885effa97b1079867d1e041beDaniel Veillard    PyObject *pyobj_node;
23081e77438da7dd912885effa97b1079867d1e041beDaniel Veillard    xmlNodePtr node;
23091e77438da7dd912885effa97b1079867d1e041beDaniel Veillard    xmlDocPtr doc;
2310d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard    const char *encoding;
23111e77438da7dd912885effa97b1079867d1e041beDaniel Veillard    int format;
23121e77438da7dd912885effa97b1079867d1e041beDaniel Veillard    int len;
23131e77438da7dd912885effa97b1079867d1e041beDaniel Veillard
2314d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard    if (!PyArg_ParseTuple(args, (char *) "Ozi:serializeNode", &pyobj_node,
2315d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard                          &encoding, &format))
2316d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        return (NULL);
23171e77438da7dd912885effa97b1079867d1e041beDaniel Veillard    node = (xmlNodePtr) PyxmlNode_Get(pyobj_node);
23181e77438da7dd912885effa97b1079867d1e041beDaniel Veillard
23191e77438da7dd912885effa97b1079867d1e041beDaniel Veillard    if (node == NULL) {
2320d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        Py_INCREF(Py_None);
2321d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        return (Py_None);
23221e77438da7dd912885effa97b1079867d1e041beDaniel Veillard    }
23231e77438da7dd912885effa97b1079867d1e041beDaniel Veillard    if (node->type == XML_DOCUMENT_NODE) {
2324d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        doc = (xmlDocPtr) node;
2325d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        xmlDocDumpFormatMemoryEnc(doc, &c_retval, &len,
2326d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard                                  (const char *) encoding, format);
2327d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        py_retval = libxml_charPtrWrap((char *) c_retval);
23281e77438da7dd912885effa97b1079867d1e041beDaniel Veillard    } else if (node->type == XML_HTML_DOCUMENT_NODE) {
2329d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        xmlOutputBufferPtr buf;
2330d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        xmlCharEncodingHandlerPtr handler = NULL;
2331d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard
2332d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        doc = (xmlDocPtr) node;
2333d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        if (encoding != NULL)
2334d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            htmlSetMetaEncoding(doc, (const xmlChar *) encoding);
2335d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        encoding = (const char *) htmlGetMetaEncoding(doc);
2336d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard
2337d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        if (encoding != NULL) {
2338d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            handler = xmlFindCharEncodingHandler(encoding);
2339d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            if (handler == NULL) {
2340d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard                Py_INCREF(Py_None);
2341d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard                return (Py_None);
2342d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            }
2343d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        }
2344d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard
2345d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        /*
2346d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard         * Fallback to HTML or ASCII when the encoding is unspecified
2347d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard         */
2348d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        if (handler == NULL)
2349d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            handler = xmlFindCharEncodingHandler("HTML");
2350d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        if (handler == NULL)
2351d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            handler = xmlFindCharEncodingHandler("ascii");
2352d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard
2353d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        buf = xmlAllocOutputBuffer(handler);
2354d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        if (buf == NULL) {
2355d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            Py_INCREF(Py_None);
2356d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            return (Py_None);
2357d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        }
2358d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        htmlDocContentDumpFormatOutput(buf, doc, encoding, format);
2359d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        xmlOutputBufferFlush(buf);
2360d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        if (buf->conv != NULL) {
2361d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            len = buf->conv->use;
2362d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            c_retval = buf->conv->content;
2363d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            buf->conv->content = NULL;
2364d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        } else {
2365d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            len = buf->buffer->use;
2366d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            c_retval = buf->buffer->content;
2367d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            buf->buffer->content = NULL;
2368d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        }
2369d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        (void) xmlOutputBufferClose(buf);
2370d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        py_retval = libxml_charPtrWrap((char *) c_retval);
23711e77438da7dd912885effa97b1079867d1e041beDaniel Veillard    } else {
2372d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        doc = node->doc;
2373a8c0adbc395e48f0a65ccbd6c4931525380cf55cDaniel Veillard        if ((doc == NULL) || (doc->type == XML_DOCUMENT_NODE)) {
2374d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            xmlOutputBufferPtr buf;
2375d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            xmlCharEncodingHandlerPtr handler = NULL;
2376d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard
2377d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            if (encoding != NULL) {
2378d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard                handler = xmlFindCharEncodingHandler(encoding);
2379d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard                if (handler == NULL) {
2380d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard                    Py_INCREF(Py_None);
2381d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard                    return (Py_None);
2382d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard                }
2383d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            }
2384d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard
2385d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            buf = xmlAllocOutputBuffer(handler);
2386d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            if (buf == NULL) {
2387d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard                Py_INCREF(Py_None);
2388d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard                return (Py_None);
2389d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            }
2390d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            xmlNodeDumpOutput(buf, doc, node, 0, format, encoding);
2391d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            xmlOutputBufferFlush(buf);
2392d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            if (buf->conv != NULL) {
2393d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard                len = buf->conv->use;
2394d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard                c_retval = buf->conv->content;
2395d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard                buf->conv->content = NULL;
2396d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            } else {
2397d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard                len = buf->buffer->use;
2398d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard                c_retval = buf->buffer->content;
2399d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard                buf->buffer->content = NULL;
2400d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            }
2401d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            (void) xmlOutputBufferClose(buf);
2402d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            py_retval = libxml_charPtrWrap((char *) c_retval);
2403d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        } else if (doc->type == XML_HTML_DOCUMENT_NODE) {
2404d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            xmlOutputBufferPtr buf;
2405d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            xmlCharEncodingHandlerPtr handler = NULL;
2406d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard
2407d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            if (encoding != NULL)
2408d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard                htmlSetMetaEncoding(doc, (const xmlChar *) encoding);
2409d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            encoding = (const char *) htmlGetMetaEncoding(doc);
2410d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            if (encoding != NULL) {
2411d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard                handler = xmlFindCharEncodingHandler(encoding);
2412d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard                if (handler == NULL) {
2413d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard                    Py_INCREF(Py_None);
2414d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard                    return (Py_None);
2415d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard                }
2416d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            }
2417d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard
2418d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            /*
2419d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard             * Fallback to HTML or ASCII when the encoding is unspecified
2420d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard             */
2421d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            if (handler == NULL)
2422d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard                handler = xmlFindCharEncodingHandler("HTML");
2423d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            if (handler == NULL)
2424d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard                handler = xmlFindCharEncodingHandler("ascii");
2425d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard
2426d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            buf = xmlAllocOutputBuffer(handler);
2427d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            if (buf == NULL) {
2428d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard                Py_INCREF(Py_None);
2429d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard                return (Py_None);
2430d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            }
2431d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            htmlNodeDumpFormatOutput(buf, doc, node, encoding, format);
2432d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            xmlOutputBufferFlush(buf);
2433d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            if (buf->conv != NULL) {
2434d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard                len = buf->conv->use;
2435d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard                c_retval = buf->conv->content;
2436d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard                buf->conv->content = NULL;
2437d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            } else {
2438d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard                len = buf->buffer->use;
2439d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard                c_retval = buf->buffer->content;
2440d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard                buf->buffer->content = NULL;
2441d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            }
2442d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            (void) xmlOutputBufferClose(buf);
2443d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            py_retval = libxml_charPtrWrap((char *) c_retval);
2444d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        } else {
2445d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            Py_INCREF(Py_None);
2446d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            return (Py_None);
2447d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        }
24481e77438da7dd912885effa97b1079867d1e041beDaniel Veillard    }
2449d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard    return (py_retval);
24501e77438da7dd912885effa97b1079867d1e041beDaniel Veillard}
24511e77438da7dd912885effa97b1079867d1e041beDaniel Veillard
2452d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillardstatic PyObject *
2453d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillardlibxml_saveNodeTo(ATTRIBUTE_UNUSED PyObject * self, PyObject * args)
2454d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard{
24551e77438da7dd912885effa97b1079867d1e041beDaniel Veillard    PyObject *py_file = NULL;
24561e77438da7dd912885effa97b1079867d1e041beDaniel Veillard    FILE *output;
24571e77438da7dd912885effa97b1079867d1e041beDaniel Veillard    PyObject *pyobj_node;
24581e77438da7dd912885effa97b1079867d1e041beDaniel Veillard    xmlNodePtr node;
24591e77438da7dd912885effa97b1079867d1e041beDaniel Veillard    xmlDocPtr doc;
2460d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard    const char *encoding;
24611e77438da7dd912885effa97b1079867d1e041beDaniel Veillard    int format;
24621e77438da7dd912885effa97b1079867d1e041beDaniel Veillard    int len;
24631e77438da7dd912885effa97b1079867d1e041beDaniel Veillard    xmlOutputBufferPtr buf;
24641e77438da7dd912885effa97b1079867d1e041beDaniel Veillard    xmlCharEncodingHandlerPtr handler = NULL;
24651e77438da7dd912885effa97b1079867d1e041beDaniel Veillard
2466d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard    if (!PyArg_ParseTuple(args, (char *) "OOzi:serializeNode", &pyobj_node,
2467d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard                          &py_file, &encoding, &format))
2468d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        return (NULL);
24691e77438da7dd912885effa97b1079867d1e041beDaniel Veillard    node = (xmlNodePtr) PyxmlNode_Get(pyobj_node);
24701e77438da7dd912885effa97b1079867d1e041beDaniel Veillard
24711e77438da7dd912885effa97b1079867d1e041beDaniel Veillard    if (node == NULL) {
2472d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        return (PyInt_FromLong((long) -1));
24731e77438da7dd912885effa97b1079867d1e041beDaniel Veillard    }
24741e77438da7dd912885effa97b1079867d1e041beDaniel Veillard    if ((py_file == NULL) || (!(PyFile_Check(py_file)))) {
2475d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        return (PyInt_FromLong((long) -1));
24761e77438da7dd912885effa97b1079867d1e041beDaniel Veillard    }
24771e77438da7dd912885effa97b1079867d1e041beDaniel Veillard    output = PyFile_AsFile(py_file);
24781e77438da7dd912885effa97b1079867d1e041beDaniel Veillard    if (output == NULL) {
2479d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        return (PyInt_FromLong((long) -1));
24801e77438da7dd912885effa97b1079867d1e041beDaniel Veillard    }
24811e77438da7dd912885effa97b1079867d1e041beDaniel Veillard
24821e77438da7dd912885effa97b1079867d1e041beDaniel Veillard    if (node->type == XML_DOCUMENT_NODE) {
2483d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        doc = (xmlDocPtr) node;
24841e77438da7dd912885effa97b1079867d1e041beDaniel Veillard    } else if (node->type == XML_HTML_DOCUMENT_NODE) {
2485d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        doc = (xmlDocPtr) node;
24861e77438da7dd912885effa97b1079867d1e041beDaniel Veillard    } else {
2487d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        doc = node->doc;
24881e77438da7dd912885effa97b1079867d1e041beDaniel Veillard    }
24891e77438da7dd912885effa97b1079867d1e041beDaniel Veillard    if (doc->type == XML_HTML_DOCUMENT_NODE) {
2490d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        if (encoding == NULL)
2491d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            encoding = (const char *) htmlGetMetaEncoding(doc);
24921e77438da7dd912885effa97b1079867d1e041beDaniel Veillard    }
24931e77438da7dd912885effa97b1079867d1e041beDaniel Veillard    if (encoding != NULL) {
2494d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        handler = xmlFindCharEncodingHandler(encoding);
2495d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        if (handler == NULL) {
2496d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            return (PyInt_FromLong((long) -1));
2497d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        }
24981e77438da7dd912885effa97b1079867d1e041beDaniel Veillard    }
24991e77438da7dd912885effa97b1079867d1e041beDaniel Veillard    if (doc->type == XML_HTML_DOCUMENT_NODE) {
2500d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        if (handler == NULL)
2501d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            handler = xmlFindCharEncodingHandler("HTML");
2502d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        if (handler == NULL)
2503d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            handler = xmlFindCharEncodingHandler("ascii");
25041e77438da7dd912885effa97b1079867d1e041beDaniel Veillard    }
25051e77438da7dd912885effa97b1079867d1e041beDaniel Veillard
25061e77438da7dd912885effa97b1079867d1e041beDaniel Veillard    buf = xmlOutputBufferCreateFile(output, handler);
25071e77438da7dd912885effa97b1079867d1e041beDaniel Veillard    if (node->type == XML_DOCUMENT_NODE) {
2508d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        len = xmlSaveFormatFileTo(buf, doc, encoding, format);
25091e77438da7dd912885effa97b1079867d1e041beDaniel Veillard    } else if (node->type == XML_HTML_DOCUMENT_NODE) {
2510d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        htmlDocContentDumpFormatOutput(buf, doc, encoding, format);
2511d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        len = xmlOutputBufferClose(buf);
25121e77438da7dd912885effa97b1079867d1e041beDaniel Veillard    } else if (doc->type == XML_HTML_DOCUMENT_NODE) {
2513d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        htmlNodeDumpFormatOutput(buf, doc, node, encoding, format);
2514d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        len = xmlOutputBufferClose(buf);
25151e77438da7dd912885effa97b1079867d1e041beDaniel Veillard    } else {
2516d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        xmlNodeDumpOutput(buf, doc, node, 0, format, encoding);
2517d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        len = xmlOutputBufferClose(buf);
25181e77438da7dd912885effa97b1079867d1e041beDaniel Veillard    }
2519d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard    return (PyInt_FromLong((long) len));
25201e77438da7dd912885effa97b1079867d1e041beDaniel Veillard}
25211e77438da7dd912885effa97b1079867d1e041beDaniel Veillard
25221e77438da7dd912885effa97b1079867d1e041beDaniel Veillard/************************************************************************
25231e77438da7dd912885effa97b1079867d1e041beDaniel Veillard *									*
2524a94ec6ff13d9617ff22e790cef82208e7d1bd375Daniel Veillard *			Extra stuff					*
2525a94ec6ff13d9617ff22e790cef82208e7d1bd375Daniel Veillard *									*
2526a94ec6ff13d9617ff22e790cef82208e7d1bd375Daniel Veillard ************************************************************************/
2527a94ec6ff13d9617ff22e790cef82208e7d1bd375Daniel VeillardPyObject *
2528d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillardlibxml_xmlNewNode(ATTRIBUTE_UNUSED PyObject * self, PyObject * args)
2529d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard{
2530a94ec6ff13d9617ff22e790cef82208e7d1bd375Daniel Veillard    PyObject *py_retval;
2531d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard    xmlChar *name;
2532a94ec6ff13d9617ff22e790cef82208e7d1bd375Daniel Veillard    xmlNodePtr node;
2533a94ec6ff13d9617ff22e790cef82208e7d1bd375Daniel Veillard
2534d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard    if (!PyArg_ParseTuple(args, (char *) "s:xmlNewNode", &name))
2535d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        return (NULL);
2536a94ec6ff13d9617ff22e790cef82208e7d1bd375Daniel Veillard    node = (xmlNodePtr) xmlNewNode(NULL, name);
25373b2e4e1c1477e9eb0889a8c9d35da4ce36a2e3f1Daniel Veillard#ifdef DEBUG
2538d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard    printf("NewNode: %s : %p\n", name, (void *) node);
25393b2e4e1c1477e9eb0889a8c9d35da4ce36a2e3f1Daniel Veillard#endif
2540a94ec6ff13d9617ff22e790cef82208e7d1bd375Daniel Veillard
2541a94ec6ff13d9617ff22e790cef82208e7d1bd375Daniel Veillard    if (node == NULL) {
2542d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        Py_INCREF(Py_None);
2543d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        return (Py_None);
2544a94ec6ff13d9617ff22e790cef82208e7d1bd375Daniel Veillard    }
2545a94ec6ff13d9617ff22e790cef82208e7d1bd375Daniel Veillard    py_retval = libxml_xmlNodePtrWrap(node);
2546d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard    return (py_retval);
2547a94ec6ff13d9617ff22e790cef82208e7d1bd375Daniel Veillard}
2548a94ec6ff13d9617ff22e790cef82208e7d1bd375Daniel Veillard
25495439624bd9167dbb880ea4a75d91677d20a6ebe3Daniel Veillard
25505439624bd9167dbb880ea4a75d91677d20a6ebe3Daniel Veillard/************************************************************************
25515439624bd9167dbb880ea4a75d91677d20a6ebe3Daniel Veillard *									*
25525439624bd9167dbb880ea4a75d91677d20a6ebe3Daniel Veillard *			Local Catalog stuff				*
25535439624bd9167dbb880ea4a75d91677d20a6ebe3Daniel Veillard *									*
25545439624bd9167dbb880ea4a75d91677d20a6ebe3Daniel Veillard ************************************************************************/
25555439624bd9167dbb880ea4a75d91677d20a6ebe3Daniel Veillardstatic PyObject *
25565439624bd9167dbb880ea4a75d91677d20a6ebe3Daniel Veillardlibxml_addLocalCatalog(ATTRIBUTE_UNUSED PyObject * self, PyObject * args)
25575439624bd9167dbb880ea4a75d91677d20a6ebe3Daniel Veillard{
25585439624bd9167dbb880ea4a75d91677d20a6ebe3Daniel Veillard    xmlChar *URL;
25595439624bd9167dbb880ea4a75d91677d20a6ebe3Daniel Veillard    xmlParserCtxtPtr ctxt;
25605439624bd9167dbb880ea4a75d91677d20a6ebe3Daniel Veillard    PyObject *pyobj_ctxt;
25615439624bd9167dbb880ea4a75d91677d20a6ebe3Daniel Veillard
25625439624bd9167dbb880ea4a75d91677d20a6ebe3Daniel Veillard    if (!PyArg_ParseTuple(args, (char *)"Os:addLocalCatalog", &pyobj_ctxt, &URL))
25635439624bd9167dbb880ea4a75d91677d20a6ebe3Daniel Veillard        return(NULL);
25645439624bd9167dbb880ea4a75d91677d20a6ebe3Daniel Veillard
25655439624bd9167dbb880ea4a75d91677d20a6ebe3Daniel Veillard    ctxt = (xmlParserCtxtPtr) PyparserCtxt_Get(pyobj_ctxt);
25665439624bd9167dbb880ea4a75d91677d20a6ebe3Daniel Veillard
25675439624bd9167dbb880ea4a75d91677d20a6ebe3Daniel Veillard    if (URL != NULL) {
25685439624bd9167dbb880ea4a75d91677d20a6ebe3Daniel Veillard	ctxt->catalogs = xmlCatalogAddLocal(ctxt->catalogs, URL);
25695439624bd9167dbb880ea4a75d91677d20a6ebe3Daniel Veillard    }
25705439624bd9167dbb880ea4a75d91677d20a6ebe3Daniel Veillard
25715439624bd9167dbb880ea4a75d91677d20a6ebe3Daniel Veillard#ifdef DEBUG
25725439624bd9167dbb880ea4a75d91677d20a6ebe3Daniel Veillard    printf("LocalCatalog: %s\n", URL);
25735439624bd9167dbb880ea4a75d91677d20a6ebe3Daniel Veillard#endif
25745439624bd9167dbb880ea4a75d91677d20a6ebe3Daniel Veillard
25755439624bd9167dbb880ea4a75d91677d20a6ebe3Daniel Veillard    Py_INCREF(Py_None);
25765439624bd9167dbb880ea4a75d91677d20a6ebe3Daniel Veillard    return (Py_None);
25775439624bd9167dbb880ea4a75d91677d20a6ebe3Daniel Veillard}
25785439624bd9167dbb880ea4a75d91677d20a6ebe3Daniel Veillard
2579a94ec6ff13d9617ff22e790cef82208e7d1bd375Daniel Veillard/************************************************************************
2580a94ec6ff13d9617ff22e790cef82208e7d1bd375Daniel Veillard *									*
2581d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard *			The registration stuff				*
2582d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard *									*
2583d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard ************************************************************************/
2584d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillardstatic PyMethodDef libxmlMethods[] = {
258596fe095d4bf3c76301ed58ebe1ba10f8004f87efDaniel Veillard#include "libxml2-export.c"
2586d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard    {(char *) "name", libxml_name, METH_VARARGS, NULL},
2587d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard    {(char *) "children", libxml_children, METH_VARARGS, NULL},
2588d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard    {(char *) "properties", libxml_properties, METH_VARARGS, NULL},
2589d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard    {(char *) "last", libxml_last, METH_VARARGS, NULL},
2590d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard    {(char *) "prev", libxml_prev, METH_VARARGS, NULL},
2591d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard    {(char *) "next", libxml_next, METH_VARARGS, NULL},
2592d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard    {(char *) "parent", libxml_parent, METH_VARARGS, NULL},
2593d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard    {(char *) "type", libxml_type, METH_VARARGS, NULL},
2594d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard    {(char *) "doc", libxml_doc, METH_VARARGS, NULL},
2595d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard    {(char *) "xmlNewNode", libxml_xmlNewNode, METH_VARARGS, NULL},
2596d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard    {(char *) "serializeNode", libxml_serializeNode, METH_VARARGS, NULL},
2597d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard    {(char *) "saveNodeTo", libxml_saveNodeTo, METH_VARARGS, NULL},
2598c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard    {(char *) "outputBufferCreate", libxml_xmlCreateOutputBuffer, METH_VARARGS, NULL},
2599c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard    {(char *) "inputBufferCreate", libxml_xmlCreateInputBuffer, METH_VARARGS, NULL},
2600c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard    {(char *) "setEntityLoader", libxml_xmlSetEntityLoader, METH_VARARGS, NULL},
26013e20a2921373677d1cf54fcf6081b3492e0c7558Daniel Veillard    {(char *)"xmlRegisterErrorHandler", libxml_xmlRegisterErrorHandler, METH_VARARGS, NULL },
2602417be3ae08346c6510c28d2042dd42a22a74b331Daniel Veillard    {(char *)"xmlParserCtxtSetErrorHandler", libxml_xmlParserCtxtSetErrorHandler, METH_VARARGS, NULL },
2603417be3ae08346c6510c28d2042dd42a22a74b331Daniel Veillard    {(char *)"xmlParserCtxtGetErrorHandler", libxml_xmlParserCtxtGetErrorHandler, METH_VARARGS, NULL },
2604e6227e0549490b5bf9271ecd2d874a97c3f4852bDaniel Veillard    {(char *)"xmlFreeParserCtxt", libxml_xmlFreeParserCtxt, METH_VARARGS, NULL },
260526f70269c80140a7fb8a7aae9ef09c95efa98e70Daniel Veillard    {(char *)"xmlTextReaderSetErrorHandler", libxml_xmlTextReaderSetErrorHandler, METH_VARARGS, NULL },
260626f70269c80140a7fb8a7aae9ef09c95efa98e70Daniel Veillard    {(char *)"xmlTextReaderGetErrorHandler", libxml_xmlTextReaderGetErrorHandler, METH_VARARGS, NULL },
260726f70269c80140a7fb8a7aae9ef09c95efa98e70Daniel Veillard    {(char *)"xmlFreeTextReader", libxml_xmlFreeTextReader, METH_VARARGS, NULL },
26085439624bd9167dbb880ea4a75d91677d20a6ebe3Daniel Veillard    {(char *)"addLocalCatalog", libxml_addLocalCatalog, METH_VARARGS, NULL },
2609d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard    {NULL, NULL, 0, NULL}
2610d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard};
2611d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard
26120fea6f45cd6f158418318c0af922533e44f9c0e2Daniel Veillard#ifdef MERGED_MODULES
26136361da0c25e355affdeed84cfccb187ccaadfccbDaniel Veillardextern void initlibxsltmod(void);
26140fea6f45cd6f158418318c0af922533e44f9c0e2Daniel Veillard#endif
26150fea6f45cd6f158418318c0af922533e44f9c0e2Daniel Veillard
2616d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillardvoid
2617d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillardinitlibxml2mod(void)
2618d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard{
2619af43f63aaabf0dc4b4a070773875d0927da3d8a2Daniel Veillard    static int initialized = 0;
26203ce5257b293ed75d8feb18ed7ab18ea2b52510bdDaniel Veillard    PyObject *m;
2621af43f63aaabf0dc4b4a070773875d0927da3d8a2Daniel Veillard
2622af43f63aaabf0dc4b4a070773875d0927da3d8a2Daniel Veillard    if (initialized != 0)
2623d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        return;
2624781ac8b19bfc10635a8bb83158f874116fd7559eDaniel Veillard    /* XXX xmlInitParser does much more than this */
2625781ac8b19bfc10635a8bb83158f874116fd7559eDaniel Veillard    xmlInitGlobals();
2626c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard    xmlRegisterDefaultOutputCallbacks();
2627c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard    xmlRegisterDefaultInputCallbacks();
2628d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard    m = Py_InitModule((char *) "libxml2mod", libxmlMethods);
2629af43f63aaabf0dc4b4a070773875d0927da3d8a2Daniel Veillard    initialized = 1;
26305d81903b06418c7d8cc72cf9add81c4026a2f3bcDaniel Veillard    libxml_xmlErrorInitialize();
26316361da0c25e355affdeed84cfccb187ccaadfccbDaniel Veillard
26320fea6f45cd6f158418318c0af922533e44f9c0e2Daniel Veillard#ifdef MERGED_MODULES
26330fea6f45cd6f158418318c0af922533e44f9c0e2Daniel Veillard    initlibxsltmod();
26340fea6f45cd6f158418318c0af922533e44f9c0e2Daniel Veillard#endif
2635d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard}
2636