libxml.c revision 417be3ae08346c6510c28d2042dd42a22a74b331
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)
300d132cffc1733447f0fa9624f0265369a7f8c02aDaniel Veillard#endif
310d132cffc1733447f0fa9624f0265369a7f8c02aDaniel Veillard
32d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard/* #define DEBUG */
33797a565a2f6a2c0a8480670174e9eaef30d271a4Daniel Veillard/* #define DEBUG_SAX */
34a7340c830e4bddd86201cfdb97ac81e30b0dee62Daniel Veillard/* #define DEBUG_XPATH */
355d81903b06418c7d8cc72cf9add81c4026a2f3bcDaniel Veillard/* #define DEBUG_ERROR */
364e1b26cfeba7f5fad4f8bd12fb5ce7029f930b79Daniel Veillard/* #define DEBUG_MEMORY */
37c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard/* #define DEBUG_FILES */
38c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard/* #define DEBUG_LOADER */
394e1b26cfeba7f5fad4f8bd12fb5ce7029f930b79Daniel Veillard
40d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillardvoid initlibxml2mod(void);
41d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard
42c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard/**
43c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard * TODO:
44c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard *
45c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard * macro to flag unimplemented blocks
46c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard */
47c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard#define TODO 								\
48c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard    xmlGenericError(xmlGenericErrorContext,				\
49c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard	    "Unimplemented block at %s:%d\n",				\
50c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard            __FILE__, __LINE__);
51c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard
524e1b26cfeba7f5fad4f8bd12fb5ce7029f930b79Daniel Veillard/************************************************************************
534e1b26cfeba7f5fad4f8bd12fb5ce7029f930b79Daniel Veillard *									*
544e1b26cfeba7f5fad4f8bd12fb5ce7029f930b79Daniel Veillard *		Memory debug interface					*
554e1b26cfeba7f5fad4f8bd12fb5ce7029f930b79Daniel Veillard *									*
564e1b26cfeba7f5fad4f8bd12fb5ce7029f930b79Daniel Veillard ************************************************************************/
574e1b26cfeba7f5fad4f8bd12fb5ce7029f930b79Daniel Veillard
584e1b26cfeba7f5fad4f8bd12fb5ce7029f930b79Daniel Veillardextern void xmlMemFree(void *ptr);
594e1b26cfeba7f5fad4f8bd12fb5ce7029f930b79Daniel Veillardextern void *xmlMemMalloc(size_t size);
60d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillardextern void *xmlMemRealloc(void *ptr, size_t size);
614e1b26cfeba7f5fad4f8bd12fb5ce7029f930b79Daniel Veillardextern char *xmlMemoryStrdup(const char *str);
624e1b26cfeba7f5fad4f8bd12fb5ce7029f930b79Daniel Veillard
634e1b26cfeba7f5fad4f8bd12fb5ce7029f930b79Daniel Veillardstatic int libxmlMemoryDebugActivated = 0;
644e1b26cfeba7f5fad4f8bd12fb5ce7029f930b79Daniel Veillardstatic long libxmlMemoryAllocatedBase = 0;
654e1b26cfeba7f5fad4f8bd12fb5ce7029f930b79Daniel Veillard
664e1b26cfeba7f5fad4f8bd12fb5ce7029f930b79Daniel Veillardstatic int libxmlMemoryDebug = 0;
674e1b26cfeba7f5fad4f8bd12fb5ce7029f930b79Daniel Veillardstatic xmlFreeFunc freeFunc = NULL;
684e1b26cfeba7f5fad4f8bd12fb5ce7029f930b79Daniel Veillardstatic xmlMallocFunc mallocFunc = NULL;
694e1b26cfeba7f5fad4f8bd12fb5ce7029f930b79Daniel Veillardstatic xmlReallocFunc reallocFunc = NULL;
704e1b26cfeba7f5fad4f8bd12fb5ce7029f930b79Daniel Veillardstatic xmlStrdupFunc strdupFunc = NULL;
714e1b26cfeba7f5fad4f8bd12fb5ce7029f930b79Daniel Veillard
724e1b26cfeba7f5fad4f8bd12fb5ce7029f930b79Daniel VeillardPyObject *
73d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillardlibxml_xmlDebugMemory(ATTRIBUTE_UNUSED PyObject * self, PyObject * args)
74d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard{
754e1b26cfeba7f5fad4f8bd12fb5ce7029f930b79Daniel Veillard    int activate;
764e1b26cfeba7f5fad4f8bd12fb5ce7029f930b79Daniel Veillard    PyObject *py_retval;
774e1b26cfeba7f5fad4f8bd12fb5ce7029f930b79Daniel Veillard    long ret;
784e1b26cfeba7f5fad4f8bd12fb5ce7029f930b79Daniel Veillard
79d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard    if (!PyArg_ParseTuple(args, (char *) "i:xmlDebugMemory", &activate))
80d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        return (NULL);
814e1b26cfeba7f5fad4f8bd12fb5ce7029f930b79Daniel Veillard
824e1b26cfeba7f5fad4f8bd12fb5ce7029f930b79Daniel Veillard#ifdef DEBUG_MEMORY
834e1b26cfeba7f5fad4f8bd12fb5ce7029f930b79Daniel Veillard    printf("libxml_xmlDebugMemory(%d) called\n", activate);
844e1b26cfeba7f5fad4f8bd12fb5ce7029f930b79Daniel Veillard#endif
854e1b26cfeba7f5fad4f8bd12fb5ce7029f930b79Daniel Veillard
864e1b26cfeba7f5fad4f8bd12fb5ce7029f930b79Daniel Veillard    if (activate != 0) {
87d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        if (libxmlMemoryDebug == 0) {
88d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            /*
89d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard             * First initialize the library and grab the old memory handlers
90d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard             * and switch the library to memory debugging
91d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard             */
92d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            xmlMemGet((xmlFreeFunc *) & freeFunc,
93d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard                      (xmlMallocFunc *) & mallocFunc,
94d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard                      (xmlReallocFunc *) & reallocFunc,
95d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard                      (xmlStrdupFunc *) & strdupFunc);
96d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            if ((freeFunc == xmlMemFree) && (mallocFunc == xmlMemMalloc) &&
97d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard                (reallocFunc == xmlMemRealloc) &&
98d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard                (strdupFunc == xmlMemoryStrdup)) {
99d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard                libxmlMemoryAllocatedBase = xmlMemUsed();
100d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            } else {
101d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard                ret = (long) xmlMemSetup(xmlMemFree, xmlMemMalloc,
102d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard                                         xmlMemRealloc, xmlMemoryStrdup);
103d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard                if (ret < 0)
104d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard                    goto error;
105d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard                libxmlMemoryAllocatedBase = xmlMemUsed();
106d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            }
107d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            xmlInitParser();
108d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            ret = 0;
109d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        } else if (libxmlMemoryDebugActivated == 0) {
110d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            libxmlMemoryAllocatedBase = xmlMemUsed();
111d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            ret = 0;
112d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        } else {
113d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            ret = xmlMemUsed() - libxmlMemoryAllocatedBase;
114d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        }
115d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        libxmlMemoryDebug = 1;
116d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        libxmlMemoryDebugActivated = 1;
1174e1b26cfeba7f5fad4f8bd12fb5ce7029f930b79Daniel Veillard    } else {
118d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        if (libxmlMemoryDebugActivated == 1)
119d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            ret = xmlMemUsed() - libxmlMemoryAllocatedBase;
120d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        else
121d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            ret = 0;
122d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        libxmlMemoryDebugActivated = 0;
1234e1b26cfeba7f5fad4f8bd12fb5ce7029f930b79Daniel Veillard    }
124d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard  error:
1254e1b26cfeba7f5fad4f8bd12fb5ce7029f930b79Daniel Veillard    py_retval = libxml_longWrap(ret);
126d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard    return (py_retval);
1274e1b26cfeba7f5fad4f8bd12fb5ce7029f930b79Daniel Veillard}
1284e1b26cfeba7f5fad4f8bd12fb5ce7029f930b79Daniel Veillard
1294e1b26cfeba7f5fad4f8bd12fb5ce7029f930b79Daniel VeillardPyObject *
130d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillardlibxml_xmlDumpMemory(ATTRIBUTE_UNUSED PyObject * self,
131d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard                     ATTRIBUTE_UNUSED PyObject * args)
132d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard{
1334e1b26cfeba7f5fad4f8bd12fb5ce7029f930b79Daniel Veillard
1344e1b26cfeba7f5fad4f8bd12fb5ce7029f930b79Daniel Veillard    if (libxmlMemoryDebug != 0)
135d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        xmlMemoryDump();
1364e1b26cfeba7f5fad4f8bd12fb5ce7029f930b79Daniel Veillard    Py_INCREF(Py_None);
137d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard    return (Py_None);
1384e1b26cfeba7f5fad4f8bd12fb5ce7029f930b79Daniel Veillard}
139d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard
140d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard/************************************************************************
141d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard *									*
142c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard *		Handling Python FILE I/O at the C level			*
143c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard *	The raw I/O attack diectly the File objects, while the		*
144c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard *	other routines address the ioWrapper instance instead		*
145c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard *									*
146c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard ************************************************************************/
147c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard
148c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard/**
149c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard * xmlPythonFileCloseUnref:
150c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard * @context:  the I/O context
151c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard *
152c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard * Close an I/O channel
153c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard */
154c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillardstatic int
155c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel VeillardxmlPythonFileCloseRaw (void * context) {
156c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard    PyObject *file, *ret;
157c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard
158c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard#ifdef DEBUG_FILES
159c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard    printf("xmlPythonFileCloseUnref\n");
160c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard#endif
161c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard    file = (PyObject *) context;
162c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard    if (file == NULL) return(-1);
163118aed78f360f51d182770e62b251ef324707aa2Daniel Veillard    ret = PyEval_CallMethod(file, (char *) "close", (char *) "()");
164c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard    if (ret != NULL) {
165c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard	Py_DECREF(ret);
166c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard    }
167c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard    Py_DECREF(file);
168c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard    return(0);
169c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard}
170c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard
171c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard/**
172c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard * xmlPythonFileReadRaw:
173c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard * @context:  the I/O context
174c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard * @buffer:  where to drop data
175c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard * @len:  number of bytes to write
176c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard *
177c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard * Read @len bytes to @buffer from the Python file in the I/O channel
178c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard *
179c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard * Returns the number of bytes read
180c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard */
181c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillardstatic int
182c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel VeillardxmlPythonFileReadRaw (void * context, char * buffer, int len) {
183c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard    PyObject *file;
184c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard    PyObject *ret;
185c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard    int lenread = -1;
186c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard    char *data;
187c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard
188c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard#ifdef DEBUG_FILES
189c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard    printf("xmlPythonFileReadRaw: %d\n", len);
190c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard#endif
191c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard    file = (PyObject *) context;
192c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard    if (file == NULL) return(-1);
193118aed78f360f51d182770e62b251ef324707aa2Daniel Veillard    ret = PyEval_CallMethod(file, (char *) "read", (char *) "(i)", len);
194c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard    if (ret == NULL) {
195c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard	printf("xmlPythonFileReadRaw: result is NULL\n");
196c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard	return(-1);
197c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard    } else if (PyString_Check(ret)) {
198c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard	lenread = PyString_Size(ret);
199c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard	data = PyString_AsString(ret);
200c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard	if (lenread > len)
201c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard	    memcpy(buffer, data, len);
202c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard	else
203c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard	    memcpy(buffer, data, lenread);
204c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard	Py_DECREF(ret);
205c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard    } else {
206c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard	printf("xmlPythonFileReadRaw: result is not a String\n");
207c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard	Py_DECREF(ret);
208c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard    }
209c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard    return(lenread);
210c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard}
211c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard
212c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard/**
213c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard * xmlPythonFileRead:
214c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard * @context:  the I/O context
215c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard * @buffer:  where to drop data
216c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard * @len:  number of bytes to write
217c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard *
218c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard * Read @len bytes to @buffer from the I/O channel.
219c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard *
220c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard * Returns the number of bytes read
221c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard */
222c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillardstatic int
223c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel VeillardxmlPythonFileRead (void * context, char * buffer, int len) {
224c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard    PyObject *file;
225c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard    PyObject *ret;
226c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard    int lenread = -1;
227c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard    char *data;
228c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard
229c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard#ifdef DEBUG_FILES
230c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard    printf("xmlPythonFileRead: %d\n", len);
231c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard#endif
232c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard    file = (PyObject *) context;
233c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard    if (file == NULL) return(-1);
234118aed78f360f51d182770e62b251ef324707aa2Daniel Veillard    ret = PyEval_CallMethod(file, (char *) "io_read", (char *) "(i)", len);
235c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard    if (ret == NULL) {
236c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard	printf("xmlPythonFileRead: result is NULL\n");
237c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard	return(-1);
238c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard    } else if (PyString_Check(ret)) {
239c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard	lenread = PyString_Size(ret);
240c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard	data = PyString_AsString(ret);
241c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard	if (lenread > len)
242c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard	    memcpy(buffer, data, len);
243c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard	else
244c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard	    memcpy(buffer, data, lenread);
245c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard	Py_DECREF(ret);
246c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard    } else {
247c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard	printf("xmlPythonFileRead: result is not a String\n");
248c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard	Py_DECREF(ret);
249c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard    }
250c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard    return(lenread);
251c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard}
252c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard
253c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard/**
254c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard * xmlFileWrite:
255c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard * @context:  the I/O context
256c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard * @buffer:  where to drop data
257c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard * @len:  number of bytes to write
258c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard *
259c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard * Write @len bytes from @buffer to the I/O channel.
260c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard *
261c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard * Returns the number of bytes written
262c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard */
263c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillardstatic int
264c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel VeillardxmlPythonFileWrite (void * context, const char * buffer, int len) {
265c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard    PyObject *file;
266c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard    PyObject *string;
267c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard    PyObject *ret;
268c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard    int written = -1;
269c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard
270c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard#ifdef DEBUG_FILES
271c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard    printf("xmlPythonFileWrite: %d\n", len);
272c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard#endif
273c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard    file = (PyObject *) context;
274c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard    if (file == NULL) return(-1);
275c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard    string = PyString_FromStringAndSize(buffer, len);
276c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard    if (string == NULL) return(-1);
277118aed78f360f51d182770e62b251ef324707aa2Daniel Veillard    ret = PyEval_CallMethod(file, (char *) "io_write", (char *) "(O)", string);
278c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard    Py_DECREF(string);
279c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard    if (ret == NULL) {
280c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard	printf("xmlPythonFileWrite: result is NULL\n");
281c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard	return(-1);
282c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard    } else if (PyInt_Check(ret)) {
283c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard	written = (int) PyInt_AsLong(ret);
284c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard	Py_DECREF(ret);
285c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard    } else if (ret == Py_None) {
286c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard	written = len;
287c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard	Py_DECREF(ret);
288c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard    } else {
289c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard	printf("xmlPythonFileWrite: result is not an Int nor None\n");
290c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard	Py_DECREF(ret);
291c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard    }
292c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard    return(written);
293c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard}
294c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard
295c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard/**
296c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard * xmlPythonFileClose:
297c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard * @context:  the I/O context
298c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard *
299c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard * Close an I/O channel
300c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard */
301c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillardstatic int
302c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel VeillardxmlPythonFileClose (void * context) {
303c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard    PyObject *file, *ret;
304c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard
305c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard#ifdef DEBUG_FILES
306c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard    printf("xmlPythonFileClose\n");
307c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard#endif
308c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard    file = (PyObject *) context;
309c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard    if (file == NULL) return(-1);
310118aed78f360f51d182770e62b251ef324707aa2Daniel Veillard    ret = PyEval_CallMethod(file, (char *) "io_close", (char *) "()");
311c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard    if (ret != NULL) {
312c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard	Py_DECREF(ret);
313c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard    }
314c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard    return(0);
315c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard}
316c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard
317c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard/**
318c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard * xmlOutputBufferCreatePythonFile:
319c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard * @file:  a PyFile_Type
320c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard * @encoder:  the encoding converter or NULL
321c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard *
322c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard * Create a buffered output for the progressive saving to a PyFile_Type
323c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard * buffered C I/O
324c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard *
325c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard * Returns the new parser output or NULL
326c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard */
327118aed78f360f51d182770e62b251ef324707aa2Daniel Veillardstatic xmlOutputBufferPtr
328c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel VeillardxmlOutputBufferCreatePythonFile(PyObject *file,
329c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard	                        xmlCharEncodingHandlerPtr encoder) {
330c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard    xmlOutputBufferPtr ret;
331c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard
332c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard    if (file == NULL) return(NULL);
333c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard
334c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard    ret = xmlAllocOutputBuffer(encoder);
335c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard    if (ret != NULL) {
336c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard        ret->context = file;
337c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard	/* Py_INCREF(file); */
338c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard	ret->writecallback = xmlPythonFileWrite;
339c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard	ret->closecallback = xmlPythonFileClose;
340c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard    }
341c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard
342c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard    return(ret);
343c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard}
344c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard
345c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel VeillardPyObject *
346c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillardlibxml_xmlCreateOutputBuffer(ATTRIBUTE_UNUSED PyObject *self, PyObject *args) {
347c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard    PyObject *py_retval;
348c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard    PyObject *file;
349c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard    xmlChar  *encoding;
350c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard    xmlCharEncodingHandlerPtr handler = NULL;
351c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard    xmlOutputBufferPtr buffer;
352c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard
353c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard
354c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard    if (!PyArg_ParseTuple(args, (char *)"Oz:xmlOutputBufferCreate",
355c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard		&file, &encoding))
356c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard	return(NULL);
357c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard    if ((encoding != NULL) && (encoding[0] != 0)) {
358118aed78f360f51d182770e62b251ef324707aa2Daniel Veillard	handler = xmlFindCharEncodingHandler((const char *) encoding);
359c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard    }
360c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard    buffer = xmlOutputBufferCreatePythonFile(file, handler);
361c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard    if (buffer == NULL)
362c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard	printf("libxml_xmlCreateOutputBuffer: buffer == NULL\n");
363c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard    py_retval = libxml_xmlOutputBufferPtrWrap(buffer);
364c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard    return(py_retval);
365c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard}
366c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard
367c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard
368c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard/**
369c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard * xmlParserInputBufferCreatePythonFile:
370c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard * @file:  a PyFile_Type
371c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard * @encoder:  the encoding converter or NULL
372c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard *
373c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard * Create a buffered output for the progressive saving to a PyFile_Type
374c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard * buffered C I/O
375c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard *
376c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard * Returns the new parser output or NULL
377c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard */
378118aed78f360f51d182770e62b251ef324707aa2Daniel Veillardstatic xmlParserInputBufferPtr
379c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel VeillardxmlParserInputBufferCreatePythonFile(PyObject *file,
380c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard	                        xmlCharEncoding encoding) {
381c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard    xmlParserInputBufferPtr ret;
382c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard
383c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard    if (file == NULL) return(NULL);
384c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard
385c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard    ret = xmlAllocParserInputBuffer(encoding);
386c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard    if (ret != NULL) {
387c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard        ret->context = file;
388c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard	/* Py_INCREF(file); */
389c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard	ret->readcallback = xmlPythonFileRead;
390c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard	ret->closecallback = xmlPythonFileClose;
391c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard    }
392c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard
393c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard    return(ret);
394c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard}
395c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard
396c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel VeillardPyObject *
397c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillardlibxml_xmlCreateInputBuffer(ATTRIBUTE_UNUSED PyObject *self, PyObject *args) {
398c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard    PyObject *py_retval;
399c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard    PyObject *file;
400c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard    xmlChar  *encoding;
401c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard    xmlCharEncoding enc = XML_CHAR_ENCODING_NONE;
402c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard    xmlParserInputBufferPtr buffer;
403c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard
404c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard
405c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard    if (!PyArg_ParseTuple(args, (char *)"Oz:xmlParserInputBufferCreate",
406c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard		&file, &encoding))
407c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard	return(NULL);
408c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard    if ((encoding != NULL) && (encoding[0] != 0)) {
409118aed78f360f51d182770e62b251ef324707aa2Daniel Veillard	enc = xmlParseCharEncoding((const char *) encoding);
410c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard    }
411c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard    buffer = xmlParserInputBufferCreatePythonFile(file, enc);
412c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard    if (buffer == NULL)
413c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard	printf("libxml_xmlParserInputBufferCreate: buffer == NULL\n");
414c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard    py_retval = libxml_xmlParserInputBufferPtrWrap(buffer);
415c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard    return(py_retval);
416c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard}
417c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard
418c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard/************************************************************************
419c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard *									*
420c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard *		Providing the resolver at the Python level		*
421c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard *									*
422c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard ************************************************************************/
423c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard
424c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillardstatic xmlExternalEntityLoader defaultExternalEntityLoader = NULL;
425c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillardstatic PyObject *pythonExternalEntityLoaderObjext;
426c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard
427c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillardstatic xmlParserInputPtr
428c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel VeillardpythonExternalEntityLoader(const char *URL, const char *ID,
429c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard			   xmlParserCtxtPtr ctxt) {
430c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard    xmlParserInputPtr result = NULL;
431c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard    if (pythonExternalEntityLoaderObjext != NULL) {
432c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard	PyObject *ret;
433c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard	PyObject *ctxtobj;
434c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard
435c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard	ctxtobj = libxml_xmlParserCtxtPtrWrap(ctxt);
436c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard#ifdef DEBUG_LOADER
437c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard	printf("pythonExternalEntityLoader: ready to call\n");
438c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard#endif
439c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard
440c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard	ret = PyObject_CallFunction(pythonExternalEntityLoaderObjext,
441118aed78f360f51d182770e62b251ef324707aa2Daniel Veillard		      (char *) "(ssO)", URL, ID, ctxtobj);
442e4a07e7b77b191d61291d44dffa19b65387e04e4Daniel Veillard	Py_XDECREF(ctxtobj);
443c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard#ifdef DEBUG_LOADER
444c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard	printf("pythonExternalEntityLoader: result ");
445c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard	PyObject_Print(ret, stdout, 0);
446c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard	printf("\n");
447c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard#endif
448c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard
449c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard	if (ret != NULL) {
450118aed78f360f51d182770e62b251ef324707aa2Daniel Veillard	    if (PyObject_HasAttrString(ret, (char *) "read")) {
451c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard		xmlParserInputBufferPtr buf;
452c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard
453c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard		buf = xmlAllocParserInputBuffer(XML_CHAR_ENCODING_NONE);
454c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard		if (buf != NULL) {
455c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard		    buf->context = ret;
456c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard		    buf->readcallback = xmlPythonFileReadRaw;
457c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard		    buf->closecallback = xmlPythonFileCloseRaw;
458c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard		    result = xmlNewIOInputStream(ctxt, buf,
459c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard			                         XML_CHAR_ENCODING_NONE);
460c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard		}
461c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard	    } else {
462c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard		printf("pythonExternalEntityLoader: can't read\n");
463c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard	    }
464c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard	    if (result == NULL) {
465c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard		Py_DECREF(ret);
466c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard	    }
467c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard	}
468c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard    }
469c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard    if ((result == NULL) && (defaultExternalEntityLoader != NULL)) {
470c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard	result = defaultExternalEntityLoader(URL, ID, ctxt);
471c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard    }
472c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard    return(result);
473c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard}
474c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard
475c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel VeillardPyObject *
476c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillardlibxml_xmlSetEntityLoader(ATTRIBUTE_UNUSED PyObject *self, PyObject *args) {
477c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard    PyObject *py_retval;
478c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard    PyObject *loader;
479c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard
480c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard    if (!PyArg_ParseTuple(args, (char *)"O:libxml_xmlSetEntityLoader",
481c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard		&loader))
482c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard	return(NULL);
483c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard
484c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard#ifdef DEBUG_LOADER
485c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard    printf("libxml_xmlSetEntityLoader\n");
486c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard#endif
487c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard    if (defaultExternalEntityLoader == NULL)
488c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard	defaultExternalEntityLoader = xmlGetExternalEntityLoader();
489c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard
490c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard    pythonExternalEntityLoaderObjext = loader;
491c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard    xmlSetExternalEntityLoader(pythonExternalEntityLoader);
492c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard
493c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard    py_retval = PyInt_FromLong(0);
494c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard    return(py_retval);
495c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard}
496c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard
497c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard
498c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard/************************************************************************
499c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard *									*
5003ce5257b293ed75d8feb18ed7ab18ea2b52510bdDaniel Veillard *		Handling SAX/xmllib/sgmlop callback interfaces		*
501d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard *									*
502d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard ************************************************************************/
5031971ee2698cb84c7699c96d3302f00e20d42c0d3Daniel Veillard
50433caa0b8307eccf22010400747830b1967edb292Daniel Veillardstatic void
50533caa0b8307eccf22010400747830b1967edb292Daniel VeillardpythonStartElement(void *user_data, const xmlChar * name,
50633caa0b8307eccf22010400747830b1967edb292Daniel Veillard                   const xmlChar ** attrs)
50733caa0b8307eccf22010400747830b1967edb292Daniel Veillard{
50833caa0b8307eccf22010400747830b1967edb292Daniel Veillard    int i;
50933caa0b8307eccf22010400747830b1967edb292Daniel Veillard    PyObject *handler;
51033caa0b8307eccf22010400747830b1967edb292Daniel Veillard    PyObject *dict;
51133caa0b8307eccf22010400747830b1967edb292Daniel Veillard    PyObject *attrname;
51233caa0b8307eccf22010400747830b1967edb292Daniel Veillard    PyObject *attrvalue;
513d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard    PyObject *result = NULL;
51433caa0b8307eccf22010400747830b1967edb292Daniel Veillard    int type = 0;
51533caa0b8307eccf22010400747830b1967edb292Daniel Veillard
516797a565a2f6a2c0a8480670174e9eaef30d271a4Daniel Veillard#ifdef DEBUG_SAX
517797a565a2f6a2c0a8480670174e9eaef30d271a4Daniel Veillard    printf("pythonStartElement(%s) called\n", name);
518797a565a2f6a2c0a8480670174e9eaef30d271a4Daniel Veillard#endif
51933caa0b8307eccf22010400747830b1967edb292Daniel Veillard    handler = (PyObject *) user_data;
520d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard    if (PyObject_HasAttrString(handler, (char *) "startElement"))
52133caa0b8307eccf22010400747830b1967edb292Daniel Veillard        type = 1;
522d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard    else if (PyObject_HasAttrString(handler, (char *) "start"))
52333caa0b8307eccf22010400747830b1967edb292Daniel Veillard        type = 2;
52433caa0b8307eccf22010400747830b1967edb292Daniel Veillard    if (type != 0) {
52533caa0b8307eccf22010400747830b1967edb292Daniel Veillard        /*
52633caa0b8307eccf22010400747830b1967edb292Daniel Veillard         * the xmllib interface always generate a dictionnary,
52733caa0b8307eccf22010400747830b1967edb292Daniel Veillard         * possibly empty
52833caa0b8307eccf22010400747830b1967edb292Daniel Veillard         */
52933caa0b8307eccf22010400747830b1967edb292Daniel Veillard        if ((attrs == NULL) && (type == 1)) {
53033caa0b8307eccf22010400747830b1967edb292Daniel Veillard            Py_XINCREF(Py_None);
53133caa0b8307eccf22010400747830b1967edb292Daniel Veillard            dict = Py_None;
532d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        } else if (attrs == NULL) {
533d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            dict = PyDict_New();
53433caa0b8307eccf22010400747830b1967edb292Daniel Veillard        } else {
53533caa0b8307eccf22010400747830b1967edb292Daniel Veillard            dict = PyDict_New();
53633caa0b8307eccf22010400747830b1967edb292Daniel Veillard            for (i = 0; attrs[i] != NULL; i++) {
537d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard                attrname = PyString_FromString((char *) attrs[i]);
53833caa0b8307eccf22010400747830b1967edb292Daniel Veillard                i++;
53933caa0b8307eccf22010400747830b1967edb292Daniel Veillard                if (attrs[i] != NULL) {
540d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard                    attrvalue = PyString_FromString((char *) attrs[i]);
54133caa0b8307eccf22010400747830b1967edb292Daniel Veillard                } else {
54233caa0b8307eccf22010400747830b1967edb292Daniel Veillard                    Py_XINCREF(Py_None);
54333caa0b8307eccf22010400747830b1967edb292Daniel Veillard                    attrvalue = Py_None;
54433caa0b8307eccf22010400747830b1967edb292Daniel Veillard                }
54533caa0b8307eccf22010400747830b1967edb292Daniel Veillard                PyDict_SetItem(dict, attrname, attrvalue);
54633caa0b8307eccf22010400747830b1967edb292Daniel Veillard            }
54733caa0b8307eccf22010400747830b1967edb292Daniel Veillard        }
54833caa0b8307eccf22010400747830b1967edb292Daniel Veillard
54933caa0b8307eccf22010400747830b1967edb292Daniel Veillard        if (type == 1)
550d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            result = PyObject_CallMethod(handler, (char *) "startElement",
551d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard                                         (char *) "sO", name, dict);
55233caa0b8307eccf22010400747830b1967edb292Daniel Veillard        else if (type == 2)
553d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            result = PyObject_CallMethod(handler, (char *) "start",
554d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard                                         (char *) "sO", name, dict);
555d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        if (PyErr_Occurred())
556d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            PyErr_Print();
55733caa0b8307eccf22010400747830b1967edb292Daniel Veillard        Py_XDECREF(dict);
55833caa0b8307eccf22010400747830b1967edb292Daniel Veillard        Py_XDECREF(result);
55933caa0b8307eccf22010400747830b1967edb292Daniel Veillard    }
56033caa0b8307eccf22010400747830b1967edb292Daniel Veillard}
56133caa0b8307eccf22010400747830b1967edb292Daniel Veillard
56233caa0b8307eccf22010400747830b1967edb292Daniel Veillardstatic void
56333caa0b8307eccf22010400747830b1967edb292Daniel VeillardpythonStartDocument(void *user_data)
56433caa0b8307eccf22010400747830b1967edb292Daniel Veillard{
56533caa0b8307eccf22010400747830b1967edb292Daniel Veillard    PyObject *handler;
56633caa0b8307eccf22010400747830b1967edb292Daniel Veillard    PyObject *result;
56733caa0b8307eccf22010400747830b1967edb292Daniel Veillard
568797a565a2f6a2c0a8480670174e9eaef30d271a4Daniel Veillard#ifdef DEBUG_SAX
569797a565a2f6a2c0a8480670174e9eaef30d271a4Daniel Veillard    printf("pythonStartDocument() called\n");
570797a565a2f6a2c0a8480670174e9eaef30d271a4Daniel Veillard#endif
57133caa0b8307eccf22010400747830b1967edb292Daniel Veillard    handler = (PyObject *) user_data;
572d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard    if (PyObject_HasAttrString(handler, (char *) "startDocument")) {
573d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        result =
574d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            PyObject_CallMethod(handler, (char *) "startDocument", NULL);
575d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        if (PyErr_Occurred())
576d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            PyErr_Print();
57733caa0b8307eccf22010400747830b1967edb292Daniel Veillard        Py_XDECREF(result);
57833caa0b8307eccf22010400747830b1967edb292Daniel Veillard    }
57933caa0b8307eccf22010400747830b1967edb292Daniel Veillard}
58033caa0b8307eccf22010400747830b1967edb292Daniel Veillard
58133caa0b8307eccf22010400747830b1967edb292Daniel Veillardstatic void
58233caa0b8307eccf22010400747830b1967edb292Daniel VeillardpythonEndDocument(void *user_data)
58333caa0b8307eccf22010400747830b1967edb292Daniel Veillard{
58433caa0b8307eccf22010400747830b1967edb292Daniel Veillard    PyObject *handler;
58533caa0b8307eccf22010400747830b1967edb292Daniel Veillard    PyObject *result;
58633caa0b8307eccf22010400747830b1967edb292Daniel Veillard
587797a565a2f6a2c0a8480670174e9eaef30d271a4Daniel Veillard#ifdef DEBUG_SAX
588797a565a2f6a2c0a8480670174e9eaef30d271a4Daniel Veillard    printf("pythonEndDocument() called\n");
589797a565a2f6a2c0a8480670174e9eaef30d271a4Daniel Veillard#endif
59033caa0b8307eccf22010400747830b1967edb292Daniel Veillard    handler = (PyObject *) user_data;
591d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard    if (PyObject_HasAttrString(handler, (char *) "endDocument")) {
592d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        result =
593d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            PyObject_CallMethod(handler, (char *) "endDocument", NULL);
594d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        if (PyErr_Occurred())
595d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            PyErr_Print();
59633caa0b8307eccf22010400747830b1967edb292Daniel Veillard        Py_XDECREF(result);
59733caa0b8307eccf22010400747830b1967edb292Daniel Veillard    }
59833caa0b8307eccf22010400747830b1967edb292Daniel Veillard    /*
59933caa0b8307eccf22010400747830b1967edb292Daniel Veillard     * The reference to the handler is released there
60033caa0b8307eccf22010400747830b1967edb292Daniel Veillard     */
60133caa0b8307eccf22010400747830b1967edb292Daniel Veillard    Py_XDECREF(handler);
60233caa0b8307eccf22010400747830b1967edb292Daniel Veillard}
60333caa0b8307eccf22010400747830b1967edb292Daniel Veillard
60433caa0b8307eccf22010400747830b1967edb292Daniel Veillardstatic void
60533caa0b8307eccf22010400747830b1967edb292Daniel VeillardpythonEndElement(void *user_data, const xmlChar * name)
60633caa0b8307eccf22010400747830b1967edb292Daniel Veillard{
60733caa0b8307eccf22010400747830b1967edb292Daniel Veillard    PyObject *handler;
60833caa0b8307eccf22010400747830b1967edb292Daniel Veillard    PyObject *result;
60933caa0b8307eccf22010400747830b1967edb292Daniel Veillard
610797a565a2f6a2c0a8480670174e9eaef30d271a4Daniel Veillard#ifdef DEBUG_SAX
611797a565a2f6a2c0a8480670174e9eaef30d271a4Daniel Veillard    printf("pythonEndElement(%s) called\n", name);
612797a565a2f6a2c0a8480670174e9eaef30d271a4Daniel Veillard#endif
61333caa0b8307eccf22010400747830b1967edb292Daniel Veillard    handler = (PyObject *) user_data;
614d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard    if (PyObject_HasAttrString(handler, (char *) "endElement")) {
615d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        result = PyObject_CallMethod(handler, (char *) "endElement",
616d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard                                     (char *) "s", name);
617d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        if (PyErr_Occurred())
618d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            PyErr_Print();
61933caa0b8307eccf22010400747830b1967edb292Daniel Veillard        Py_XDECREF(result);
620d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard    } else if (PyObject_HasAttrString(handler, (char *) "end")) {
621d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        result = PyObject_CallMethod(handler, (char *) "end",
622d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard                                     (char *) "s", name);
623d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        if (PyErr_Occurred())
624d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            PyErr_Print();
625797a565a2f6a2c0a8480670174e9eaef30d271a4Daniel Veillard        Py_XDECREF(result);
62633caa0b8307eccf22010400747830b1967edb292Daniel Veillard    }
62733caa0b8307eccf22010400747830b1967edb292Daniel Veillard}
62833caa0b8307eccf22010400747830b1967edb292Daniel Veillard
62933caa0b8307eccf22010400747830b1967edb292Daniel Veillardstatic void
63033caa0b8307eccf22010400747830b1967edb292Daniel VeillardpythonReference(void *user_data, const xmlChar * name)
63133caa0b8307eccf22010400747830b1967edb292Daniel Veillard{
63233caa0b8307eccf22010400747830b1967edb292Daniel Veillard    PyObject *handler;
63333caa0b8307eccf22010400747830b1967edb292Daniel Veillard    PyObject *result;
63433caa0b8307eccf22010400747830b1967edb292Daniel Veillard
635797a565a2f6a2c0a8480670174e9eaef30d271a4Daniel Veillard#ifdef DEBUG_SAX
636797a565a2f6a2c0a8480670174e9eaef30d271a4Daniel Veillard    printf("pythonReference(%s) called\n", name);
637797a565a2f6a2c0a8480670174e9eaef30d271a4Daniel Veillard#endif
63833caa0b8307eccf22010400747830b1967edb292Daniel Veillard    handler = (PyObject *) user_data;
639d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard    if (PyObject_HasAttrString(handler, (char *) "reference")) {
640d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        result = PyObject_CallMethod(handler, (char *) "reference",
641d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard                                     (char *) "s", name);
642d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        if (PyErr_Occurred())
643d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            PyErr_Print();
64433caa0b8307eccf22010400747830b1967edb292Daniel Veillard        Py_XDECREF(result);
64533caa0b8307eccf22010400747830b1967edb292Daniel Veillard    }
64633caa0b8307eccf22010400747830b1967edb292Daniel Veillard}
64733caa0b8307eccf22010400747830b1967edb292Daniel Veillard
64833caa0b8307eccf22010400747830b1967edb292Daniel Veillardstatic void
64933caa0b8307eccf22010400747830b1967edb292Daniel VeillardpythonCharacters(void *user_data, const xmlChar * ch, int len)
65033caa0b8307eccf22010400747830b1967edb292Daniel Veillard{
65133caa0b8307eccf22010400747830b1967edb292Daniel Veillard    PyObject *handler;
652d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard    PyObject *result = NULL;
65333caa0b8307eccf22010400747830b1967edb292Daniel Veillard    int type = 0;
65433caa0b8307eccf22010400747830b1967edb292Daniel Veillard
655797a565a2f6a2c0a8480670174e9eaef30d271a4Daniel Veillard#ifdef DEBUG_SAX
656797a565a2f6a2c0a8480670174e9eaef30d271a4Daniel Veillard    printf("pythonCharacters(%s, %d) called\n", ch, len);
657797a565a2f6a2c0a8480670174e9eaef30d271a4Daniel Veillard#endif
65833caa0b8307eccf22010400747830b1967edb292Daniel Veillard    handler = (PyObject *) user_data;
659d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard    if (PyObject_HasAttrString(handler, (char *) "characters"))
660d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        type = 1;
661d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard    else if (PyObject_HasAttrString(handler, (char *) "data"))
662d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        type = 2;
66333caa0b8307eccf22010400747830b1967edb292Daniel Veillard    if (type != 0) {
664d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        if (type == 1)
665d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            result = PyObject_CallMethod(handler, (char *) "characters",
666d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard                                         (char *) "s#", ch, len);
667d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        else if (type == 2)
668d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            result = PyObject_CallMethod(handler, (char *) "data",
669d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard                                         (char *) "s#", ch, len);
670d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        if (PyErr_Occurred())
671d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            PyErr_Print();
67233caa0b8307eccf22010400747830b1967edb292Daniel Veillard        Py_XDECREF(result);
67333caa0b8307eccf22010400747830b1967edb292Daniel Veillard    }
67433caa0b8307eccf22010400747830b1967edb292Daniel Veillard}
67533caa0b8307eccf22010400747830b1967edb292Daniel Veillard
67633caa0b8307eccf22010400747830b1967edb292Daniel Veillardstatic void
67733caa0b8307eccf22010400747830b1967edb292Daniel VeillardpythonIgnorableWhitespace(void *user_data, const xmlChar * ch, int len)
67833caa0b8307eccf22010400747830b1967edb292Daniel Veillard{
67933caa0b8307eccf22010400747830b1967edb292Daniel Veillard    PyObject *handler;
680d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard    PyObject *result = NULL;
68133caa0b8307eccf22010400747830b1967edb292Daniel Veillard    int type = 0;
68233caa0b8307eccf22010400747830b1967edb292Daniel Veillard
683797a565a2f6a2c0a8480670174e9eaef30d271a4Daniel Veillard#ifdef DEBUG_SAX
684797a565a2f6a2c0a8480670174e9eaef30d271a4Daniel Veillard    printf("pythonIgnorableWhitespace(%s, %d) called\n", ch, len);
685797a565a2f6a2c0a8480670174e9eaef30d271a4Daniel Veillard#endif
68633caa0b8307eccf22010400747830b1967edb292Daniel Veillard    handler = (PyObject *) user_data;
687d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard    if (PyObject_HasAttrString(handler, (char *) "ignorableWhitespace"))
68833caa0b8307eccf22010400747830b1967edb292Daniel Veillard        type = 1;
689d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard    else if (PyObject_HasAttrString(handler, (char *) "data"))
69033caa0b8307eccf22010400747830b1967edb292Daniel Veillard        type = 2;
69133caa0b8307eccf22010400747830b1967edb292Daniel Veillard    if (type != 0) {
69233caa0b8307eccf22010400747830b1967edb292Daniel Veillard        if (type == 1)
69333caa0b8307eccf22010400747830b1967edb292Daniel Veillard            result =
694d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard                PyObject_CallMethod(handler,
695d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard                                    (char *) "ignorableWhitespace",
696d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard                                    (char *) "s#", ch, len);
69733caa0b8307eccf22010400747830b1967edb292Daniel Veillard        else if (type == 2)
698d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            result =
699d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard                PyObject_CallMethod(handler, (char *) "data",
700d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard                                    (char *) "s#", ch, len);
70133caa0b8307eccf22010400747830b1967edb292Daniel Veillard        Py_XDECREF(result);
70233caa0b8307eccf22010400747830b1967edb292Daniel Veillard    }
70333caa0b8307eccf22010400747830b1967edb292Daniel Veillard}
70433caa0b8307eccf22010400747830b1967edb292Daniel Veillard
70533caa0b8307eccf22010400747830b1967edb292Daniel Veillardstatic void
70633caa0b8307eccf22010400747830b1967edb292Daniel VeillardpythonProcessingInstruction(void *user_data,
70733caa0b8307eccf22010400747830b1967edb292Daniel Veillard                            const xmlChar * target, const xmlChar * data)
70833caa0b8307eccf22010400747830b1967edb292Daniel Veillard{
70933caa0b8307eccf22010400747830b1967edb292Daniel Veillard    PyObject *handler;
71033caa0b8307eccf22010400747830b1967edb292Daniel Veillard    PyObject *result;
71133caa0b8307eccf22010400747830b1967edb292Daniel Veillard
712797a565a2f6a2c0a8480670174e9eaef30d271a4Daniel Veillard#ifdef DEBUG_SAX
713797a565a2f6a2c0a8480670174e9eaef30d271a4Daniel Veillard    printf("pythonProcessingInstruction(%s, %s) called\n", target, data);
714797a565a2f6a2c0a8480670174e9eaef30d271a4Daniel Veillard#endif
71533caa0b8307eccf22010400747830b1967edb292Daniel Veillard    handler = (PyObject *) user_data;
716d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard    if (PyObject_HasAttrString(handler, (char *) "processingInstruction")) {
717d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        result = PyObject_CallMethod(handler, (char *)
718d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard                                     "processingInstruction",
719d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard                                     (char *) "ss", target, data);
72033caa0b8307eccf22010400747830b1967edb292Daniel Veillard        Py_XDECREF(result);
72133caa0b8307eccf22010400747830b1967edb292Daniel Veillard    }
72233caa0b8307eccf22010400747830b1967edb292Daniel Veillard}
72333caa0b8307eccf22010400747830b1967edb292Daniel Veillard
72433caa0b8307eccf22010400747830b1967edb292Daniel Veillardstatic void
72533caa0b8307eccf22010400747830b1967edb292Daniel VeillardpythonComment(void *user_data, const xmlChar * value)
72633caa0b8307eccf22010400747830b1967edb292Daniel Veillard{
72733caa0b8307eccf22010400747830b1967edb292Daniel Veillard    PyObject *handler;
72833caa0b8307eccf22010400747830b1967edb292Daniel Veillard    PyObject *result;
72933caa0b8307eccf22010400747830b1967edb292Daniel Veillard
730797a565a2f6a2c0a8480670174e9eaef30d271a4Daniel Veillard#ifdef DEBUG_SAX
731797a565a2f6a2c0a8480670174e9eaef30d271a4Daniel Veillard    printf("pythonComment(%s) called\n", value);
732797a565a2f6a2c0a8480670174e9eaef30d271a4Daniel Veillard#endif
73333caa0b8307eccf22010400747830b1967edb292Daniel Veillard    handler = (PyObject *) user_data;
734d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard    if (PyObject_HasAttrString(handler, (char *) "comment")) {
735d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        result =
736d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            PyObject_CallMethod(handler, (char *) "comment", (char *) "s",
737d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard                                value);
738d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        if (PyErr_Occurred())
739d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            PyErr_Print();
74033caa0b8307eccf22010400747830b1967edb292Daniel Veillard        Py_XDECREF(result);
74133caa0b8307eccf22010400747830b1967edb292Daniel Veillard    }
74233caa0b8307eccf22010400747830b1967edb292Daniel Veillard}
74333caa0b8307eccf22010400747830b1967edb292Daniel Veillard
74433caa0b8307eccf22010400747830b1967edb292Daniel Veillardstatic void
74533caa0b8307eccf22010400747830b1967edb292Daniel VeillardpythonWarning(void *user_data, const char *msg, ...)
74633caa0b8307eccf22010400747830b1967edb292Daniel Veillard{
74733caa0b8307eccf22010400747830b1967edb292Daniel Veillard    PyObject *handler;
74833caa0b8307eccf22010400747830b1967edb292Daniel Veillard    PyObject *result;
74933caa0b8307eccf22010400747830b1967edb292Daniel Veillard    va_list args;
75033caa0b8307eccf22010400747830b1967edb292Daniel Veillard    char buf[1024];
75133caa0b8307eccf22010400747830b1967edb292Daniel Veillard
752797a565a2f6a2c0a8480670174e9eaef30d271a4Daniel Veillard#ifdef DEBUG_SAX
753797a565a2f6a2c0a8480670174e9eaef30d271a4Daniel Veillard    printf("pythonWarning(%s) called\n", msg);
754797a565a2f6a2c0a8480670174e9eaef30d271a4Daniel Veillard#endif
75533caa0b8307eccf22010400747830b1967edb292Daniel Veillard    handler = (PyObject *) user_data;
756d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard    if (PyObject_HasAttrString(handler, (char *) "warning")) {
75733caa0b8307eccf22010400747830b1967edb292Daniel Veillard        va_start(args, msg);
75833caa0b8307eccf22010400747830b1967edb292Daniel Veillard        vsnprintf(buf, 1023, msg, args);
759d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        va_end(args);
760d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        buf[1023] = 0;
761d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        result =
762d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            PyObject_CallMethod(handler, (char *) "warning", (char *) "s",
763d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard                                buf);
764d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        if (PyErr_Occurred())
765d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            PyErr_Print();
76633caa0b8307eccf22010400747830b1967edb292Daniel Veillard        Py_XDECREF(result);
76733caa0b8307eccf22010400747830b1967edb292Daniel Veillard    }
76833caa0b8307eccf22010400747830b1967edb292Daniel Veillard}
76933caa0b8307eccf22010400747830b1967edb292Daniel Veillard
77033caa0b8307eccf22010400747830b1967edb292Daniel Veillardstatic void
77133caa0b8307eccf22010400747830b1967edb292Daniel VeillardpythonError(void *user_data, const char *msg, ...)
77233caa0b8307eccf22010400747830b1967edb292Daniel Veillard{
77333caa0b8307eccf22010400747830b1967edb292Daniel Veillard    PyObject *handler;
77433caa0b8307eccf22010400747830b1967edb292Daniel Veillard    PyObject *result;
77533caa0b8307eccf22010400747830b1967edb292Daniel Veillard    va_list args;
77633caa0b8307eccf22010400747830b1967edb292Daniel Veillard    char buf[1024];
77733caa0b8307eccf22010400747830b1967edb292Daniel Veillard
778797a565a2f6a2c0a8480670174e9eaef30d271a4Daniel Veillard#ifdef DEBUG_SAX
779797a565a2f6a2c0a8480670174e9eaef30d271a4Daniel Veillard    printf("pythonError(%s) called\n", msg);
780797a565a2f6a2c0a8480670174e9eaef30d271a4Daniel Veillard#endif
78133caa0b8307eccf22010400747830b1967edb292Daniel Veillard    handler = (PyObject *) user_data;
782d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard    if (PyObject_HasAttrString(handler, (char *) "error")) {
78333caa0b8307eccf22010400747830b1967edb292Daniel Veillard        va_start(args, msg);
78433caa0b8307eccf22010400747830b1967edb292Daniel Veillard        vsnprintf(buf, 1023, msg, args);
785d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        va_end(args);
786d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        buf[1023] = 0;
787d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        result =
788d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            PyObject_CallMethod(handler, (char *) "error", (char *) "s",
789d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard                                buf);
790d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        if (PyErr_Occurred())
791d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            PyErr_Print();
79233caa0b8307eccf22010400747830b1967edb292Daniel Veillard        Py_XDECREF(result);
79333caa0b8307eccf22010400747830b1967edb292Daniel Veillard    }
79433caa0b8307eccf22010400747830b1967edb292Daniel Veillard}
79533caa0b8307eccf22010400747830b1967edb292Daniel Veillard
79633caa0b8307eccf22010400747830b1967edb292Daniel Veillardstatic void
79733caa0b8307eccf22010400747830b1967edb292Daniel VeillardpythonFatalError(void *user_data, const char *msg, ...)
79833caa0b8307eccf22010400747830b1967edb292Daniel Veillard{
79933caa0b8307eccf22010400747830b1967edb292Daniel Veillard    PyObject *handler;
80033caa0b8307eccf22010400747830b1967edb292Daniel Veillard    PyObject *result;
80133caa0b8307eccf22010400747830b1967edb292Daniel Veillard    va_list args;
80233caa0b8307eccf22010400747830b1967edb292Daniel Veillard    char buf[1024];
80333caa0b8307eccf22010400747830b1967edb292Daniel Veillard
804797a565a2f6a2c0a8480670174e9eaef30d271a4Daniel Veillard#ifdef DEBUG_SAX
805797a565a2f6a2c0a8480670174e9eaef30d271a4Daniel Veillard    printf("pythonFatalError(%s) called\n", msg);
806797a565a2f6a2c0a8480670174e9eaef30d271a4Daniel Veillard#endif
80733caa0b8307eccf22010400747830b1967edb292Daniel Veillard    handler = (PyObject *) user_data;
808d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard    if (PyObject_HasAttrString(handler, (char *) "fatalError")) {
80933caa0b8307eccf22010400747830b1967edb292Daniel Veillard        va_start(args, msg);
81033caa0b8307eccf22010400747830b1967edb292Daniel Veillard        vsnprintf(buf, 1023, msg, args);
811d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        va_end(args);
812d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        buf[1023] = 0;
813d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        result =
814d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            PyObject_CallMethod(handler, (char *) "fatalError",
815d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard                                (char *) "s", buf);
816d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        if (PyErr_Occurred())
817d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            PyErr_Print();
81833caa0b8307eccf22010400747830b1967edb292Daniel Veillard        Py_XDECREF(result);
81933caa0b8307eccf22010400747830b1967edb292Daniel Veillard    }
82033caa0b8307eccf22010400747830b1967edb292Daniel Veillard}
82133caa0b8307eccf22010400747830b1967edb292Daniel Veillard
82233caa0b8307eccf22010400747830b1967edb292Daniel Veillardstatic void
82333caa0b8307eccf22010400747830b1967edb292Daniel VeillardpythonCdataBlock(void *user_data, const xmlChar * ch, int len)
82433caa0b8307eccf22010400747830b1967edb292Daniel Veillard{
82533caa0b8307eccf22010400747830b1967edb292Daniel Veillard    PyObject *handler;
826d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard    PyObject *result = NULL;
82733caa0b8307eccf22010400747830b1967edb292Daniel Veillard    int type = 0;
82833caa0b8307eccf22010400747830b1967edb292Daniel Veillard
829797a565a2f6a2c0a8480670174e9eaef30d271a4Daniel Veillard#ifdef DEBUG_SAX
830797a565a2f6a2c0a8480670174e9eaef30d271a4Daniel Veillard    printf("pythonCdataBlock(%s, %d) called\n", ch, len);
831797a565a2f6a2c0a8480670174e9eaef30d271a4Daniel Veillard#endif
83233caa0b8307eccf22010400747830b1967edb292Daniel Veillard    handler = (PyObject *) user_data;
833d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard    if (PyObject_HasAttrString(handler, (char *) "cdataBlock"))
834d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        type = 1;
835d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard    else if (PyObject_HasAttrString(handler, (char *) "cdata"))
836d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        type = 2;
83733caa0b8307eccf22010400747830b1967edb292Daniel Veillard    if (type != 0) {
838d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        if (type == 1)
839d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            result =
840d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard                PyObject_CallMethod(handler, (char *) "cdataBlock",
841d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard                                    (char *) "s#", ch, len);
842d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        else if (type == 2)
843d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            result =
844d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard                PyObject_CallMethod(handler, (char *) "cdata",
845d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard                                    (char *) "s#", ch, len);
846d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        if (PyErr_Occurred())
847d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            PyErr_Print();
84833caa0b8307eccf22010400747830b1967edb292Daniel Veillard        Py_XDECREF(result);
84933caa0b8307eccf22010400747830b1967edb292Daniel Veillard    }
85033caa0b8307eccf22010400747830b1967edb292Daniel Veillard}
85133caa0b8307eccf22010400747830b1967edb292Daniel Veillard
85233caa0b8307eccf22010400747830b1967edb292Daniel Veillardstatic void
85333caa0b8307eccf22010400747830b1967edb292Daniel VeillardpythonExternalSubset(void *user_data,
85433caa0b8307eccf22010400747830b1967edb292Daniel Veillard                     const xmlChar * name,
85533caa0b8307eccf22010400747830b1967edb292Daniel Veillard                     const xmlChar * externalID, const xmlChar * systemID)
85633caa0b8307eccf22010400747830b1967edb292Daniel Veillard{
85733caa0b8307eccf22010400747830b1967edb292Daniel Veillard    PyObject *handler;
85833caa0b8307eccf22010400747830b1967edb292Daniel Veillard    PyObject *result;
85933caa0b8307eccf22010400747830b1967edb292Daniel Veillard
860797a565a2f6a2c0a8480670174e9eaef30d271a4Daniel Veillard#ifdef DEBUG_SAX
861797a565a2f6a2c0a8480670174e9eaef30d271a4Daniel Veillard    printf("pythonExternalSubset(%s, %s, %s) called\n",
862d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard           name, externalID, systemID);
863797a565a2f6a2c0a8480670174e9eaef30d271a4Daniel Veillard#endif
86433caa0b8307eccf22010400747830b1967edb292Daniel Veillard    handler = (PyObject *) user_data;
865d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard    if (PyObject_HasAttrString(handler, (char *) "externalSubset")) {
86633caa0b8307eccf22010400747830b1967edb292Daniel Veillard        result =
867d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            PyObject_CallMethod(handler, (char *) "externalSubset",
868d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard                                (char *) "sss", name, externalID,
869d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard                                systemID);
87033caa0b8307eccf22010400747830b1967edb292Daniel Veillard        Py_XDECREF(result);
87133caa0b8307eccf22010400747830b1967edb292Daniel Veillard    }
87233caa0b8307eccf22010400747830b1967edb292Daniel Veillard}
87333caa0b8307eccf22010400747830b1967edb292Daniel Veillard
87433caa0b8307eccf22010400747830b1967edb292Daniel Veillardstatic void
87533caa0b8307eccf22010400747830b1967edb292Daniel VeillardpythonEntityDecl(void *user_data,
87633caa0b8307eccf22010400747830b1967edb292Daniel Veillard                 const xmlChar * name,
87733caa0b8307eccf22010400747830b1967edb292Daniel Veillard                 int type,
87833caa0b8307eccf22010400747830b1967edb292Daniel Veillard                 const xmlChar * publicId,
87933caa0b8307eccf22010400747830b1967edb292Daniel Veillard                 const xmlChar * systemId, xmlChar * content)
88033caa0b8307eccf22010400747830b1967edb292Daniel Veillard{
88133caa0b8307eccf22010400747830b1967edb292Daniel Veillard    PyObject *handler;
88233caa0b8307eccf22010400747830b1967edb292Daniel Veillard    PyObject *result;
88333caa0b8307eccf22010400747830b1967edb292Daniel Veillard
88433caa0b8307eccf22010400747830b1967edb292Daniel Veillard    handler = (PyObject *) user_data;
885d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard    if (PyObject_HasAttrString(handler, (char *) "entityDecl")) {
886d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        result = PyObject_CallMethod(handler, (char *) "entityDecl",
887d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard                                     (char *) "sisss", name, type,
888d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard                                     publicId, systemId, content);
889d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        if (PyErr_Occurred())
890d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            PyErr_Print();
89133caa0b8307eccf22010400747830b1967edb292Daniel Veillard        Py_XDECREF(result);
89233caa0b8307eccf22010400747830b1967edb292Daniel Veillard    }
89333caa0b8307eccf22010400747830b1967edb292Daniel Veillard}
89433caa0b8307eccf22010400747830b1967edb292Daniel Veillard
89533caa0b8307eccf22010400747830b1967edb292Daniel Veillard
89633caa0b8307eccf22010400747830b1967edb292Daniel Veillard
89733caa0b8307eccf22010400747830b1967edb292Daniel Veillardstatic void
89833caa0b8307eccf22010400747830b1967edb292Daniel Veillard
89933caa0b8307eccf22010400747830b1967edb292Daniel VeillardpythonNotationDecl(void *user_data,
90033caa0b8307eccf22010400747830b1967edb292Daniel Veillard                   const xmlChar * name,
90133caa0b8307eccf22010400747830b1967edb292Daniel Veillard                   const xmlChar * publicId, const xmlChar * systemId)
90233caa0b8307eccf22010400747830b1967edb292Daniel Veillard{
90333caa0b8307eccf22010400747830b1967edb292Daniel Veillard    PyObject *handler;
90433caa0b8307eccf22010400747830b1967edb292Daniel Veillard    PyObject *result;
90533caa0b8307eccf22010400747830b1967edb292Daniel Veillard
90633caa0b8307eccf22010400747830b1967edb292Daniel Veillard    handler = (PyObject *) user_data;
907d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard    if (PyObject_HasAttrString(handler, (char *) "notationDecl")) {
908d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        result = PyObject_CallMethod(handler, (char *) "notationDecl",
909d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard                                     (char *) "sss", name, publicId,
910d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard                                     systemId);
911d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        if (PyErr_Occurred())
912d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            PyErr_Print();
91333caa0b8307eccf22010400747830b1967edb292Daniel Veillard        Py_XDECREF(result);
91433caa0b8307eccf22010400747830b1967edb292Daniel Veillard    }
91533caa0b8307eccf22010400747830b1967edb292Daniel Veillard}
91633caa0b8307eccf22010400747830b1967edb292Daniel Veillard
91733caa0b8307eccf22010400747830b1967edb292Daniel Veillardstatic void
91833caa0b8307eccf22010400747830b1967edb292Daniel VeillardpythonAttributeDecl(void *user_data,
91933caa0b8307eccf22010400747830b1967edb292Daniel Veillard                    const xmlChar * elem,
92033caa0b8307eccf22010400747830b1967edb292Daniel Veillard                    const xmlChar * name,
92133caa0b8307eccf22010400747830b1967edb292Daniel Veillard                    int type,
92233caa0b8307eccf22010400747830b1967edb292Daniel Veillard                    int def,
923d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard                    const xmlChar * defaultValue, xmlEnumerationPtr tree)
92433caa0b8307eccf22010400747830b1967edb292Daniel Veillard{
92533caa0b8307eccf22010400747830b1967edb292Daniel Veillard    PyObject *handler;
92633caa0b8307eccf22010400747830b1967edb292Daniel Veillard    PyObject *nameList;
92733caa0b8307eccf22010400747830b1967edb292Daniel Veillard    PyObject *newName;
92833caa0b8307eccf22010400747830b1967edb292Daniel Veillard    xmlEnumerationPtr node;
92933caa0b8307eccf22010400747830b1967edb292Daniel Veillard    PyObject *result;
93033caa0b8307eccf22010400747830b1967edb292Daniel Veillard    int count;
93133caa0b8307eccf22010400747830b1967edb292Daniel Veillard
93233caa0b8307eccf22010400747830b1967edb292Daniel Veillard    handler = (PyObject *) user_data;
933d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard    if (PyObject_HasAttrString(handler, (char *) "attributeDecl")) {
93433caa0b8307eccf22010400747830b1967edb292Daniel Veillard        count = 0;
93533caa0b8307eccf22010400747830b1967edb292Daniel Veillard        for (node = tree; node != NULL; node = node->next) {
93633caa0b8307eccf22010400747830b1967edb292Daniel Veillard            count++;
93733caa0b8307eccf22010400747830b1967edb292Daniel Veillard        }
93833caa0b8307eccf22010400747830b1967edb292Daniel Veillard        nameList = PyList_New(count);
93933caa0b8307eccf22010400747830b1967edb292Daniel Veillard        count = 0;
94033caa0b8307eccf22010400747830b1967edb292Daniel Veillard        for (node = tree; node != NULL; node = node->next) {
941d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            newName = PyString_FromString((char *) node->name);
94233caa0b8307eccf22010400747830b1967edb292Daniel Veillard            PyList_SetItem(nameList, count, newName);
94333caa0b8307eccf22010400747830b1967edb292Daniel Veillard            count++;
94433caa0b8307eccf22010400747830b1967edb292Daniel Veillard        }
945d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        result = PyObject_CallMethod(handler, (char *) "attributeDecl",
946d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard                                     (char *) "ssiisO", elem, name, type,
947d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard                                     def, defaultValue, nameList);
948d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        if (PyErr_Occurred())
949d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            PyErr_Print();
95033caa0b8307eccf22010400747830b1967edb292Daniel Veillard        Py_XDECREF(nameList);
95133caa0b8307eccf22010400747830b1967edb292Daniel Veillard        Py_XDECREF(result);
95233caa0b8307eccf22010400747830b1967edb292Daniel Veillard    }
95333caa0b8307eccf22010400747830b1967edb292Daniel Veillard}
95433caa0b8307eccf22010400747830b1967edb292Daniel Veillard
95533caa0b8307eccf22010400747830b1967edb292Daniel Veillardstatic void
95633caa0b8307eccf22010400747830b1967edb292Daniel VeillardpythonElementDecl(void *user_data,
95733caa0b8307eccf22010400747830b1967edb292Daniel Veillard                  const xmlChar * name,
958d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard                  int type, ATTRIBUTE_UNUSED xmlElementContentPtr content)
95933caa0b8307eccf22010400747830b1967edb292Daniel Veillard{
96033caa0b8307eccf22010400747830b1967edb292Daniel Veillard    PyObject *handler;
96133caa0b8307eccf22010400747830b1967edb292Daniel Veillard    PyObject *obj;
96233caa0b8307eccf22010400747830b1967edb292Daniel Veillard    PyObject *result;
96333caa0b8307eccf22010400747830b1967edb292Daniel Veillard
96433caa0b8307eccf22010400747830b1967edb292Daniel Veillard    handler = (PyObject *) user_data;
965d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard    if (PyObject_HasAttrString(handler, (char *) "elementDecl")) {
966d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        /* TODO: wrap in an elementContent object */
967d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        printf
968d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            ("pythonElementDecl: xmlElementContentPtr wrapper missing !\n");
969d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        obj = Py_None;
970d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        /* Py_XINCREF(Py_None); isn't the reference just borrowed ??? */
971d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        result = PyObject_CallMethod(handler, (char *) "elementDecl",
972d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard                                     (char *) "siO", name, type, obj);
973d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        if (PyErr_Occurred())
974d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            PyErr_Print();
97533caa0b8307eccf22010400747830b1967edb292Daniel Veillard        Py_XDECREF(result);
97633caa0b8307eccf22010400747830b1967edb292Daniel Veillard    }
97733caa0b8307eccf22010400747830b1967edb292Daniel Veillard}
97833caa0b8307eccf22010400747830b1967edb292Daniel Veillard
97933caa0b8307eccf22010400747830b1967edb292Daniel Veillardstatic void
98033caa0b8307eccf22010400747830b1967edb292Daniel VeillardpythonUnparsedEntityDecl(void *user_data,
98133caa0b8307eccf22010400747830b1967edb292Daniel Veillard                         const xmlChar * name,
98233caa0b8307eccf22010400747830b1967edb292Daniel Veillard                         const xmlChar * publicId,
98333caa0b8307eccf22010400747830b1967edb292Daniel Veillard                         const xmlChar * systemId,
98433caa0b8307eccf22010400747830b1967edb292Daniel Veillard                         const xmlChar * notationName)
98533caa0b8307eccf22010400747830b1967edb292Daniel Veillard{
98633caa0b8307eccf22010400747830b1967edb292Daniel Veillard    PyObject *handler;
98733caa0b8307eccf22010400747830b1967edb292Daniel Veillard    PyObject *result;
98833caa0b8307eccf22010400747830b1967edb292Daniel Veillard
98933caa0b8307eccf22010400747830b1967edb292Daniel Veillard    handler = (PyObject *) user_data;
990d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard    if (PyObject_HasAttrString(handler, (char *) "unparsedEntityDecl")) {
991d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        result =
992d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            PyObject_CallMethod(handler, (char *) "unparsedEntityDecl",
993d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard                                (char *) "ssss", name, publicId, systemId,
994d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard                                notationName);
995d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        if (PyErr_Occurred())
996d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            PyErr_Print();
99733caa0b8307eccf22010400747830b1967edb292Daniel Veillard        Py_XDECREF(result);
99833caa0b8307eccf22010400747830b1967edb292Daniel Veillard    }
99933caa0b8307eccf22010400747830b1967edb292Daniel Veillard}
100033caa0b8307eccf22010400747830b1967edb292Daniel Veillard
100133caa0b8307eccf22010400747830b1967edb292Daniel Veillardstatic void
100233caa0b8307eccf22010400747830b1967edb292Daniel VeillardpythonInternalSubset(void *user_data, const xmlChar * name,
100333caa0b8307eccf22010400747830b1967edb292Daniel Veillard                     const xmlChar * ExternalID, const xmlChar * SystemID)
100433caa0b8307eccf22010400747830b1967edb292Daniel Veillard{
100533caa0b8307eccf22010400747830b1967edb292Daniel Veillard    PyObject *handler;
100633caa0b8307eccf22010400747830b1967edb292Daniel Veillard    PyObject *result;
100733caa0b8307eccf22010400747830b1967edb292Daniel Veillard
1008797a565a2f6a2c0a8480670174e9eaef30d271a4Daniel Veillard#ifdef DEBUG_SAX
1009797a565a2f6a2c0a8480670174e9eaef30d271a4Daniel Veillard    printf("pythonInternalSubset(%s, %s, %s) called\n",
1010d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard           name, ExternalID, SystemID);
1011797a565a2f6a2c0a8480670174e9eaef30d271a4Daniel Veillard#endif
101233caa0b8307eccf22010400747830b1967edb292Daniel Veillard    handler = (PyObject *) user_data;
1013d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard    if (PyObject_HasAttrString(handler, (char *) "internalSubset")) {
1014d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        result = PyObject_CallMethod(handler, (char *) "internalSubset",
1015d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard                                     (char *) "sss", name, ExternalID,
1016d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard                                     SystemID);
1017d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        if (PyErr_Occurred())
1018d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            PyErr_Print();
101933caa0b8307eccf22010400747830b1967edb292Daniel Veillard        Py_XDECREF(result);
102033caa0b8307eccf22010400747830b1967edb292Daniel Veillard    }
102133caa0b8307eccf22010400747830b1967edb292Daniel Veillard}
102233caa0b8307eccf22010400747830b1967edb292Daniel Veillard
102333caa0b8307eccf22010400747830b1967edb292Daniel Veillardstatic xmlSAXHandler pythonSaxHandler = {
102433caa0b8307eccf22010400747830b1967edb292Daniel Veillard    pythonInternalSubset,
1025d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard    NULL,                       /* TODO pythonIsStandalone, */
1026d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard    NULL,                       /* TODO pythonHasInternalSubset, */
1027d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard    NULL,                       /* TODO pythonHasExternalSubset, */
1028d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard    NULL,                       /* TODO pythonResolveEntity, */
1029d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard    NULL,                       /* TODO pythonGetEntity, */
103033caa0b8307eccf22010400747830b1967edb292Daniel Veillard    pythonEntityDecl,
103133caa0b8307eccf22010400747830b1967edb292Daniel Veillard    pythonNotationDecl,
103233caa0b8307eccf22010400747830b1967edb292Daniel Veillard    pythonAttributeDecl,
103333caa0b8307eccf22010400747830b1967edb292Daniel Veillard    pythonElementDecl,
103433caa0b8307eccf22010400747830b1967edb292Daniel Veillard    pythonUnparsedEntityDecl,
1035d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard    NULL,                       /* OBSOLETED pythonSetDocumentLocator, */
103633caa0b8307eccf22010400747830b1967edb292Daniel Veillard    pythonStartDocument,
103733caa0b8307eccf22010400747830b1967edb292Daniel Veillard    pythonEndDocument,
103833caa0b8307eccf22010400747830b1967edb292Daniel Veillard    pythonStartElement,
103933caa0b8307eccf22010400747830b1967edb292Daniel Veillard    pythonEndElement,
104033caa0b8307eccf22010400747830b1967edb292Daniel Veillard    pythonReference,
104133caa0b8307eccf22010400747830b1967edb292Daniel Veillard    pythonCharacters,
104233caa0b8307eccf22010400747830b1967edb292Daniel Veillard    pythonIgnorableWhitespace,
104333caa0b8307eccf22010400747830b1967edb292Daniel Veillard    pythonProcessingInstruction,
104433caa0b8307eccf22010400747830b1967edb292Daniel Veillard    pythonComment,
104533caa0b8307eccf22010400747830b1967edb292Daniel Veillard    pythonWarning,
104633caa0b8307eccf22010400747830b1967edb292Daniel Veillard    pythonError,
104733caa0b8307eccf22010400747830b1967edb292Daniel Veillard    pythonFatalError,
1048d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard    NULL,                       /* TODO pythonGetParameterEntity, */
104933caa0b8307eccf22010400747830b1967edb292Daniel Veillard    pythonCdataBlock,
105033caa0b8307eccf22010400747830b1967edb292Daniel Veillard    pythonExternalSubset,
105133caa0b8307eccf22010400747830b1967edb292Daniel Veillard    1
105233caa0b8307eccf22010400747830b1967edb292Daniel Veillard};
1053d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard
10543ce5257b293ed75d8feb18ed7ab18ea2b52510bdDaniel Veillard/************************************************************************
10553ce5257b293ed75d8feb18ed7ab18ea2b52510bdDaniel Veillard *									*
10563ce5257b293ed75d8feb18ed7ab18ea2b52510bdDaniel Veillard *		Handling of specific parser context			*
10573ce5257b293ed75d8feb18ed7ab18ea2b52510bdDaniel Veillard *									*
10583ce5257b293ed75d8feb18ed7ab18ea2b52510bdDaniel Veillard ************************************************************************/
10591971ee2698cb84c7699c96d3302f00e20d42c0d3Daniel Veillard
10601971ee2698cb84c7699c96d3302f00e20d42c0d3Daniel VeillardPyObject *
1061d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillardlibxml_xmlCreatePushParser(ATTRIBUTE_UNUSED PyObject * self,
1062d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard                           PyObject * args)
1063d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard{
1064d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard    const char *chunk;
10653ce5257b293ed75d8feb18ed7ab18ea2b52510bdDaniel Veillard    int size;
1066d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard    const char *URI;
106733caa0b8307eccf22010400747830b1967edb292Daniel Veillard    PyObject *pyobj_SAX = NULL;
10683ce5257b293ed75d8feb18ed7ab18ea2b52510bdDaniel Veillard    xmlSAXHandlerPtr SAX = NULL;
10693ce5257b293ed75d8feb18ed7ab18ea2b52510bdDaniel Veillard    xmlParserCtxtPtr ret;
10703ce5257b293ed75d8feb18ed7ab18ea2b52510bdDaniel Veillard    PyObject *pyret;
10713ce5257b293ed75d8feb18ed7ab18ea2b52510bdDaniel Veillard
1072d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard    if (!PyArg_ParseTuple
1073d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        (args, (char *) "Oziz:xmlCreatePushParser", &pyobj_SAX, &chunk,
1074d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard         &size, &URI))
1075d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        return (NULL);
10761971ee2698cb84c7699c96d3302f00e20d42c0d3Daniel Veillard
10778d24cc189845663509623fbd6b5106cc01266994Daniel Veillard#ifdef DEBUG
10783ce5257b293ed75d8feb18ed7ab18ea2b52510bdDaniel Veillard    printf("libxml_xmlCreatePushParser(%p, %s, %d, %s) called\n",
1079d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard           pyobj_SAX, chunk, size, URI);
10801971ee2698cb84c7699c96d3302f00e20d42c0d3Daniel Veillard#endif
10813ce5257b293ed75d8feb18ed7ab18ea2b52510bdDaniel Veillard    if (pyobj_SAX != Py_None) {
1082d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        SAX = &pythonSaxHandler;
1083d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        Py_INCREF(pyobj_SAX);
1084d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        /* The reference is released in pythonEndDocument() */
10851971ee2698cb84c7699c96d3302f00e20d42c0d3Daniel Veillard    }
108633caa0b8307eccf22010400747830b1967edb292Daniel Veillard    ret = xmlCreatePushParserCtxt(SAX, pyobj_SAX, chunk, size, URI);
10873ce5257b293ed75d8feb18ed7ab18ea2b52510bdDaniel Veillard    pyret = libxml_xmlParserCtxtPtrWrap(ret);
1088d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard    return (pyret);
1089a7340c830e4bddd86201cfdb97ac81e30b0dee62Daniel Veillard}
10905d81903b06418c7d8cc72cf9add81c4026a2f3bcDaniel Veillard
10914e1b26cfeba7f5fad4f8bd12fb5ce7029f930b79Daniel VeillardPyObject *
1092d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillardlibxml_htmlCreatePushParser(ATTRIBUTE_UNUSED PyObject * self,
1093d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard                            PyObject * args)
1094d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard{
1095d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard    const char *chunk;
10964e1b26cfeba7f5fad4f8bd12fb5ce7029f930b79Daniel Veillard    int size;
1097d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard    const char *URI;
109833caa0b8307eccf22010400747830b1967edb292Daniel Veillard    PyObject *pyobj_SAX = NULL;
10994e1b26cfeba7f5fad4f8bd12fb5ce7029f930b79Daniel Veillard    xmlSAXHandlerPtr SAX = NULL;
11004e1b26cfeba7f5fad4f8bd12fb5ce7029f930b79Daniel Veillard    xmlParserCtxtPtr ret;
11014e1b26cfeba7f5fad4f8bd12fb5ce7029f930b79Daniel Veillard    PyObject *pyret;
11024e1b26cfeba7f5fad4f8bd12fb5ce7029f930b79Daniel Veillard
1103d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard    if (!PyArg_ParseTuple
1104d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        (args, (char *) "Oziz:htmlCreatePushParser", &pyobj_SAX, &chunk,
1105d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard         &size, &URI))
1106d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        return (NULL);
11074e1b26cfeba7f5fad4f8bd12fb5ce7029f930b79Daniel Veillard
11088d24cc189845663509623fbd6b5106cc01266994Daniel Veillard#ifdef DEBUG
11094e1b26cfeba7f5fad4f8bd12fb5ce7029f930b79Daniel Veillard    printf("libxml_htmlCreatePushParser(%p, %s, %d, %s) called\n",
1110d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard           pyobj_SAX, chunk, size, URI);
11114e1b26cfeba7f5fad4f8bd12fb5ce7029f930b79Daniel Veillard#endif
11124e1b26cfeba7f5fad4f8bd12fb5ce7029f930b79Daniel Veillard    if (pyobj_SAX != Py_None) {
1113d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        SAX = &pythonSaxHandler;
1114d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        Py_INCREF(pyobj_SAX);
1115d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        /* The reference is released in pythonEndDocument() */
11164e1b26cfeba7f5fad4f8bd12fb5ce7029f930b79Daniel Veillard    }
111733caa0b8307eccf22010400747830b1967edb292Daniel Veillard    ret = htmlCreatePushParserCtxt(SAX, pyobj_SAX, chunk, size, URI,
1118d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard                                   XML_CHAR_ENCODING_NONE);
11194e1b26cfeba7f5fad4f8bd12fb5ce7029f930b79Daniel Veillard    pyret = libxml_xmlParserCtxtPtrWrap(ret);
1120d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard    return (pyret);
11214e1b26cfeba7f5fad4f8bd12fb5ce7029f930b79Daniel Veillard}
11224e1b26cfeba7f5fad4f8bd12fb5ce7029f930b79Daniel Veillard
11238d24cc189845663509623fbd6b5106cc01266994Daniel VeillardPyObject *
1124d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillardlibxml_xmlSAXParseFile(ATTRIBUTE_UNUSED PyObject * self, PyObject * args)
1125d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard{
11268d24cc189845663509623fbd6b5106cc01266994Daniel Veillard    int recover;
1127d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard    const char *URI;
11288d24cc189845663509623fbd6b5106cc01266994Daniel Veillard    PyObject *pyobj_SAX = NULL;
11298d24cc189845663509623fbd6b5106cc01266994Daniel Veillard    xmlSAXHandlerPtr SAX = NULL;
11308d24cc189845663509623fbd6b5106cc01266994Daniel Veillard
1131d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard    if (!PyArg_ParseTuple(args, (char *) "Osi:xmlSAXParseFile", &pyobj_SAX,
1132d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard                          &URI, &recover))
1133d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        return (NULL);
11348d24cc189845663509623fbd6b5106cc01266994Daniel Veillard
11358d24cc189845663509623fbd6b5106cc01266994Daniel Veillard#ifdef DEBUG
11368d24cc189845663509623fbd6b5106cc01266994Daniel Veillard    printf("libxml_xmlSAXParseFile(%p, %s, %d) called\n",
1137d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard           pyobj_SAX, URI, recover);
11388d24cc189845663509623fbd6b5106cc01266994Daniel Veillard#endif
11398d24cc189845663509623fbd6b5106cc01266994Daniel Veillard    if (pyobj_SAX == Py_None) {
1140d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        Py_INCREF(Py_None);
1141d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        return (Py_None);
11428d24cc189845663509623fbd6b5106cc01266994Daniel Veillard    }
11438d24cc189845663509623fbd6b5106cc01266994Daniel Veillard    SAX = &pythonSaxHandler;
11448d24cc189845663509623fbd6b5106cc01266994Daniel Veillard    Py_INCREF(pyobj_SAX);
11458d24cc189845663509623fbd6b5106cc01266994Daniel Veillard    /* The reference is released in pythonEndDocument() */
11468d24cc189845663509623fbd6b5106cc01266994Daniel Veillard    xmlSAXParseFileWithData(SAX, URI, recover, pyobj_SAX);
11478d24cc189845663509623fbd6b5106cc01266994Daniel Veillard    Py_INCREF(Py_None);
1148d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard    return (Py_None);
11498d24cc189845663509623fbd6b5106cc01266994Daniel Veillard}
11508d24cc189845663509623fbd6b5106cc01266994Daniel Veillard
11518d24cc189845663509623fbd6b5106cc01266994Daniel VeillardPyObject *
1152d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillardlibxml_htmlSAXParseFile(ATTRIBUTE_UNUSED PyObject * self, PyObject * args)
1153d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard{
1154d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard    const char *URI;
1155d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard    const char *encoding;
11568d24cc189845663509623fbd6b5106cc01266994Daniel Veillard    PyObject *pyobj_SAX = NULL;
11578d24cc189845663509623fbd6b5106cc01266994Daniel Veillard    xmlSAXHandlerPtr SAX = NULL;
11588d24cc189845663509623fbd6b5106cc01266994Daniel Veillard
1159d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard    if (!PyArg_ParseTuple
1160d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        (args, (char *) "Osz:htmlSAXParseFile", &pyobj_SAX, &URI,
1161d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard         &encoding))
1162d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        return (NULL);
11638d24cc189845663509623fbd6b5106cc01266994Daniel Veillard
11648d24cc189845663509623fbd6b5106cc01266994Daniel Veillard#ifdef DEBUG
11658d24cc189845663509623fbd6b5106cc01266994Daniel Veillard    printf("libxml_htmlSAXParseFile(%p, %s, %s) called\n",
1166d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard           pyobj_SAX, URI, encoding);
11678d24cc189845663509623fbd6b5106cc01266994Daniel Veillard#endif
11688d24cc189845663509623fbd6b5106cc01266994Daniel Veillard    if (pyobj_SAX == Py_None) {
1169d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        Py_INCREF(Py_None);
1170d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        return (Py_None);
11718d24cc189845663509623fbd6b5106cc01266994Daniel Veillard    }
11728d24cc189845663509623fbd6b5106cc01266994Daniel Veillard    SAX = &pythonSaxHandler;
11738d24cc189845663509623fbd6b5106cc01266994Daniel Veillard    Py_INCREF(pyobj_SAX);
11748d24cc189845663509623fbd6b5106cc01266994Daniel Veillard    /* The reference is released in pythonEndDocument() */
11758d24cc189845663509623fbd6b5106cc01266994Daniel Veillard    htmlSAXParseFile(URI, encoding, SAX, pyobj_SAX);
11768d24cc189845663509623fbd6b5106cc01266994Daniel Veillard    Py_INCREF(Py_None);
1177d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard    return (Py_None);
11788d24cc189845663509623fbd6b5106cc01266994Daniel Veillard}
11798d24cc189845663509623fbd6b5106cc01266994Daniel Veillard
11805d81903b06418c7d8cc72cf9add81c4026a2f3bcDaniel Veillard/************************************************************************
11815d81903b06418c7d8cc72cf9add81c4026a2f3bcDaniel Veillard *									*
11825d81903b06418c7d8cc72cf9add81c4026a2f3bcDaniel Veillard *			Error message callback				*
11835d81903b06418c7d8cc72cf9add81c4026a2f3bcDaniel Veillard *									*
11845d81903b06418c7d8cc72cf9add81c4026a2f3bcDaniel Veillard ************************************************************************/
11855d81903b06418c7d8cc72cf9add81c4026a2f3bcDaniel Veillard
11865d81903b06418c7d8cc72cf9add81c4026a2f3bcDaniel Veillardstatic PyObject *libxml_xmlPythonErrorFuncHandler = NULL;
11875d81903b06418c7d8cc72cf9add81c4026a2f3bcDaniel Veillardstatic PyObject *libxml_xmlPythonErrorFuncCtxt = NULL;
11885d81903b06418c7d8cc72cf9add81c4026a2f3bcDaniel Veillard
1189e6227e0549490b5bf9271ecd2d874a97c3f4852bDaniel Veillard/* helper to build a xmlMalloc'ed string from a format and va_list */
1190e6227e0549490b5bf9271ecd2d874a97c3f4852bDaniel Veillardstatic char *
1191e6227e0549490b5bf9271ecd2d874a97c3f4852bDaniel Veillardlibxml_buildMessage(const char *msg, va_list ap)
1192d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard{
1193d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard    int size;
1194d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard    int chars;
1195d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard    char *larger;
1196e6227e0549490b5bf9271ecd2d874a97c3f4852bDaniel Veillard    char *str;
1197e6227e0549490b5bf9271ecd2d874a97c3f4852bDaniel Veillard
1198e6227e0549490b5bf9271ecd2d874a97c3f4852bDaniel Veillard    str = (char *) xmlMalloc(150);
1199e6227e0549490b5bf9271ecd2d874a97c3f4852bDaniel Veillard    if (str == NULL)
1200e6227e0549490b5bf9271ecd2d874a97c3f4852bDaniel Veillard        return NULL;
1201e6227e0549490b5bf9271ecd2d874a97c3f4852bDaniel Veillard
1202e6227e0549490b5bf9271ecd2d874a97c3f4852bDaniel Veillard    size = 150;
1203e6227e0549490b5bf9271ecd2d874a97c3f4852bDaniel Veillard
1204e6227e0549490b5bf9271ecd2d874a97c3f4852bDaniel Veillard    while (1) {
1205e6227e0549490b5bf9271ecd2d874a97c3f4852bDaniel Veillard        chars = vsnprintf(str, size, msg, ap);
1206e6227e0549490b5bf9271ecd2d874a97c3f4852bDaniel Veillard        if ((chars > -1) && (chars < size))
1207e6227e0549490b5bf9271ecd2d874a97c3f4852bDaniel Veillard            break;
1208e6227e0549490b5bf9271ecd2d874a97c3f4852bDaniel Veillard        if (chars > -1)
1209e6227e0549490b5bf9271ecd2d874a97c3f4852bDaniel Veillard            size += chars + 1;
1210e6227e0549490b5bf9271ecd2d874a97c3f4852bDaniel Veillard        else
1211e6227e0549490b5bf9271ecd2d874a97c3f4852bDaniel Veillard            size += 100;
1212e6227e0549490b5bf9271ecd2d874a97c3f4852bDaniel Veillard        if ((larger = (char *) xmlRealloc(str, size)) == NULL) {
1213e6227e0549490b5bf9271ecd2d874a97c3f4852bDaniel Veillard            xmlFree(str);
1214e6227e0549490b5bf9271ecd2d874a97c3f4852bDaniel Veillard            return NULL;
1215e6227e0549490b5bf9271ecd2d874a97c3f4852bDaniel Veillard        }
1216e6227e0549490b5bf9271ecd2d874a97c3f4852bDaniel Veillard        str = larger;
1217e6227e0549490b5bf9271ecd2d874a97c3f4852bDaniel Veillard    }
1218e6227e0549490b5bf9271ecd2d874a97c3f4852bDaniel Veillard
1219e6227e0549490b5bf9271ecd2d874a97c3f4852bDaniel Veillard    return str;
1220e6227e0549490b5bf9271ecd2d874a97c3f4852bDaniel Veillard}
1221e6227e0549490b5bf9271ecd2d874a97c3f4852bDaniel Veillard
1222e6227e0549490b5bf9271ecd2d874a97c3f4852bDaniel Veillardstatic void
1223e6227e0549490b5bf9271ecd2d874a97c3f4852bDaniel Veillardlibxml_xmlErrorFuncHandler(ATTRIBUTE_UNUSED void *ctx, const char *msg,
1224e6227e0549490b5bf9271ecd2d874a97c3f4852bDaniel Veillard                           ...)
1225e6227e0549490b5bf9271ecd2d874a97c3f4852bDaniel Veillard{
1226d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard    va_list ap;
1227d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard    char *str;
12285d81903b06418c7d8cc72cf9add81c4026a2f3bcDaniel Veillard    PyObject *list;
12295d81903b06418c7d8cc72cf9add81c4026a2f3bcDaniel Veillard    PyObject *message;
12305d81903b06418c7d8cc72cf9add81c4026a2f3bcDaniel Veillard    PyObject *result;
12315d81903b06418c7d8cc72cf9add81c4026a2f3bcDaniel Veillard
12325d81903b06418c7d8cc72cf9add81c4026a2f3bcDaniel Veillard#ifdef DEBUG_ERROR
12335d81903b06418c7d8cc72cf9add81c4026a2f3bcDaniel Veillard    printf("libxml_xmlErrorFuncHandler(%p, %s, ...) called\n", ctx, msg);
12345d81903b06418c7d8cc72cf9add81c4026a2f3bcDaniel Veillard#endif
12355d81903b06418c7d8cc72cf9add81c4026a2f3bcDaniel Veillard
12365d81903b06418c7d8cc72cf9add81c4026a2f3bcDaniel Veillard
12375d81903b06418c7d8cc72cf9add81c4026a2f3bcDaniel Veillard    if (libxml_xmlPythonErrorFuncHandler == NULL) {
1238d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        va_start(ap, msg);
1239d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        vfprintf(stdout, msg, ap);
1240d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        va_end(ap);
12415d81903b06418c7d8cc72cf9add81c4026a2f3bcDaniel Veillard    } else {
1242e6227e0549490b5bf9271ecd2d874a97c3f4852bDaniel Veillard        va_start(ap, msg);
1243e6227e0549490b5bf9271ecd2d874a97c3f4852bDaniel Veillard        str = libxml_buildMessage(msg,ap);
1244e6227e0549490b5bf9271ecd2d874a97c3f4852bDaniel Veillard        va_end(ap);
1245d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard
1246d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        list = PyTuple_New(2);
1247d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        PyTuple_SetItem(list, 0, libxml_xmlPythonErrorFuncCtxt);
1248d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        Py_XINCREF(libxml_xmlPythonErrorFuncCtxt);
1249d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        message = libxml_charPtrWrap(str);
1250d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        PyTuple_SetItem(list, 1, message);
1251d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        result = PyEval_CallObject(libxml_xmlPythonErrorFuncHandler, list);
1252d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        Py_XDECREF(list);
1253d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        Py_XDECREF(result);
12545d81903b06418c7d8cc72cf9add81c4026a2f3bcDaniel Veillard    }
12555d81903b06418c7d8cc72cf9add81c4026a2f3bcDaniel Veillard}
12565d81903b06418c7d8cc72cf9add81c4026a2f3bcDaniel Veillard
12575d81903b06418c7d8cc72cf9add81c4026a2f3bcDaniel Veillardstatic void
1258d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillardlibxml_xmlErrorInitialize(void)
1259d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard{
12605d81903b06418c7d8cc72cf9add81c4026a2f3bcDaniel Veillard#ifdef DEBUG_ERROR
12615d81903b06418c7d8cc72cf9add81c4026a2f3bcDaniel Veillard    printf("libxml_xmlErrorInitialize() called\n");
12625d81903b06418c7d8cc72cf9add81c4026a2f3bcDaniel Veillard#endif
12635d81903b06418c7d8cc72cf9add81c4026a2f3bcDaniel Veillard    xmlSetGenericErrorFunc(NULL, libxml_xmlErrorFuncHandler);
12645d81903b06418c7d8cc72cf9add81c4026a2f3bcDaniel Veillard}
12655d81903b06418c7d8cc72cf9add81c4026a2f3bcDaniel Veillard
12665d81903b06418c7d8cc72cf9add81c4026a2f3bcDaniel VeillardPyObject *
1267d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillardlibxml_xmlRegisterErrorHandler(ATTRIBUTE_UNUSED PyObject * self,
1268d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard                               PyObject * args)
1269d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard{
12705d81903b06418c7d8cc72cf9add81c4026a2f3bcDaniel Veillard    PyObject *py_retval;
12715d81903b06418c7d8cc72cf9add81c4026a2f3bcDaniel Veillard    PyObject *pyobj_f;
12725d81903b06418c7d8cc72cf9add81c4026a2f3bcDaniel Veillard    PyObject *pyobj_ctx;
12735d81903b06418c7d8cc72cf9add81c4026a2f3bcDaniel Veillard
1274d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard    if (!PyArg_ParseTuple
1275d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        (args, (char *) "OO:xmlRegisterErrorHandler", &pyobj_f,
1276d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard         &pyobj_ctx))
1277d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        return (NULL);
12785d81903b06418c7d8cc72cf9add81c4026a2f3bcDaniel Veillard
12795d81903b06418c7d8cc72cf9add81c4026a2f3bcDaniel Veillard#ifdef DEBUG_ERROR
1280d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard    printf("libxml_registerXPathFunction(%p, %p) called\n", pyobj_ctx,
1281d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard           pyobj_f);
12825d81903b06418c7d8cc72cf9add81c4026a2f3bcDaniel Veillard#endif
12835d81903b06418c7d8cc72cf9add81c4026a2f3bcDaniel Veillard
12845d81903b06418c7d8cc72cf9add81c4026a2f3bcDaniel Veillard    if (libxml_xmlPythonErrorFuncHandler != NULL) {
1285d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        Py_XDECREF(libxml_xmlPythonErrorFuncHandler);
12865d81903b06418c7d8cc72cf9add81c4026a2f3bcDaniel Veillard    }
12875d81903b06418c7d8cc72cf9add81c4026a2f3bcDaniel Veillard    if (libxml_xmlPythonErrorFuncCtxt != NULL) {
1288d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        Py_XDECREF(libxml_xmlPythonErrorFuncCtxt);
12895d81903b06418c7d8cc72cf9add81c4026a2f3bcDaniel Veillard    }
12905d81903b06418c7d8cc72cf9add81c4026a2f3bcDaniel Veillard
12915d81903b06418c7d8cc72cf9add81c4026a2f3bcDaniel Veillard    Py_XINCREF(pyobj_ctx);
12925d81903b06418c7d8cc72cf9add81c4026a2f3bcDaniel Veillard    Py_XINCREF(pyobj_f);
12935d81903b06418c7d8cc72cf9add81c4026a2f3bcDaniel Veillard
12945d81903b06418c7d8cc72cf9add81c4026a2f3bcDaniel Veillard    /* TODO: check f is a function ! */
12955d81903b06418c7d8cc72cf9add81c4026a2f3bcDaniel Veillard    libxml_xmlPythonErrorFuncHandler = pyobj_f;
12965d81903b06418c7d8cc72cf9add81c4026a2f3bcDaniel Veillard    libxml_xmlPythonErrorFuncCtxt = pyobj_ctx;
12975d81903b06418c7d8cc72cf9add81c4026a2f3bcDaniel Veillard
12985d81903b06418c7d8cc72cf9add81c4026a2f3bcDaniel Veillard    py_retval = libxml_intWrap(1);
1299d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard    return (py_retval);
13005d81903b06418c7d8cc72cf9add81c4026a2f3bcDaniel Veillard}
1301d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard
1302e6227e0549490b5bf9271ecd2d874a97c3f4852bDaniel Veillard
1303e6227e0549490b5bf9271ecd2d874a97c3f4852bDaniel Veillard/************************************************************************
1304e6227e0549490b5bf9271ecd2d874a97c3f4852bDaniel Veillard *									*
1305e6227e0549490b5bf9271ecd2d874a97c3f4852bDaniel Veillard *                      Per parserCtxt error handler                    *
1306e6227e0549490b5bf9271ecd2d874a97c3f4852bDaniel Veillard *									*
1307e6227e0549490b5bf9271ecd2d874a97c3f4852bDaniel Veillard ************************************************************************/
1308e6227e0549490b5bf9271ecd2d874a97c3f4852bDaniel Veillard
1309417be3ae08346c6510c28d2042dd42a22a74b331Daniel Veillardtypedef struct
1310417be3ae08346c6510c28d2042dd42a22a74b331Daniel Veillard{
1311417be3ae08346c6510c28d2042dd42a22a74b331Daniel Veillard    PyObject *f;
1312417be3ae08346c6510c28d2042dd42a22a74b331Daniel Veillard    PyObject *arg;
1313417be3ae08346c6510c28d2042dd42a22a74b331Daniel Veillard} xmlParserCtxtPyCtxt;
1314417be3ae08346c6510c28d2042dd42a22a74b331Daniel Veillardtypedef xmlParserCtxtPyCtxt *xmlParserCtxtPyCtxtPtr;
1315417be3ae08346c6510c28d2042dd42a22a74b331Daniel Veillard
1316417be3ae08346c6510c28d2042dd42a22a74b331Daniel Veillardstatic void
1317417be3ae08346c6510c28d2042dd42a22a74b331Daniel Veillardlibxml_xmlParserCtxtGenericErrorFuncHandler(void *ctx, int severity, char *str)
1318e6227e0549490b5bf9271ecd2d874a97c3f4852bDaniel Veillard{
1319e6227e0549490b5bf9271ecd2d874a97c3f4852bDaniel Veillard    PyObject *list;
1320e6227e0549490b5bf9271ecd2d874a97c3f4852bDaniel Veillard    PyObject *result;
1321417be3ae08346c6510c28d2042dd42a22a74b331Daniel Veillard    xmlParserCtxtPtr ctxt;
1322e6227e0549490b5bf9271ecd2d874a97c3f4852bDaniel Veillard    xmlParserCtxtPyCtxtPtr pyCtxt;
1323e6227e0549490b5bf9271ecd2d874a97c3f4852bDaniel Veillard
1324e6227e0549490b5bf9271ecd2d874a97c3f4852bDaniel Veillard#ifdef DEBUG_ERROR
1325417be3ae08346c6510c28d2042dd42a22a74b331Daniel Veillard    printf("libxml_xmlParserCtxtGenericErrorFuncHandler(%p, %s, ...) called\n", ctx, msg);
1326e6227e0549490b5bf9271ecd2d874a97c3f4852bDaniel Veillard#endif
1327e6227e0549490b5bf9271ecd2d874a97c3f4852bDaniel Veillard
1328417be3ae08346c6510c28d2042dd42a22a74b331Daniel Veillard    ctxt = (xmlParserCtxtPtr)ctx;
1329417be3ae08346c6510c28d2042dd42a22a74b331Daniel Veillard    pyCtxt = (xmlParserCtxtPyCtxtPtr)ctxt->_private;
1330e6227e0549490b5bf9271ecd2d874a97c3f4852bDaniel Veillard
1331417be3ae08346c6510c28d2042dd42a22a74b331Daniel Veillard    list = PyTuple_New(4);
1332417be3ae08346c6510c28d2042dd42a22a74b331Daniel Veillard    PyTuple_SetItem(list, 0, pyCtxt->arg);
1333417be3ae08346c6510c28d2042dd42a22a74b331Daniel Veillard    Py_XINCREF(pyCtxt->arg);
1334417be3ae08346c6510c28d2042dd42a22a74b331Daniel Veillard    PyTuple_SetItem(list, 1, libxml_charPtrWrap(str));
1335417be3ae08346c6510c28d2042dd42a22a74b331Daniel Veillard    PyTuple_SetItem(list, 2, libxml_intWrap(severity));
1336417be3ae08346c6510c28d2042dd42a22a74b331Daniel Veillard    PyTuple_SetItem(list, 3, Py_None);
1337417be3ae08346c6510c28d2042dd42a22a74b331Daniel Veillard    Py_INCREF(Py_None);
1338417be3ae08346c6510c28d2042dd42a22a74b331Daniel Veillard    result = PyEval_CallObject(pyCtxt->f, list);
1339417be3ae08346c6510c28d2042dd42a22a74b331Daniel Veillard    if (result == NULL)
1340417be3ae08346c6510c28d2042dd42a22a74b331Daniel Veillard    {
1341417be3ae08346c6510c28d2042dd42a22a74b331Daniel Veillard	/* TODO: manage for the exception to be propagated... */
1342417be3ae08346c6510c28d2042dd42a22a74b331Daniel Veillard	PyErr_Print();
1343e6227e0549490b5bf9271ecd2d874a97c3f4852bDaniel Veillard    }
1344417be3ae08346c6510c28d2042dd42a22a74b331Daniel Veillard    Py_XDECREF(list);
1345417be3ae08346c6510c28d2042dd42a22a74b331Daniel Veillard    Py_XDECREF(result);
1346417be3ae08346c6510c28d2042dd42a22a74b331Daniel Veillard}
1347417be3ae08346c6510c28d2042dd42a22a74b331Daniel Veillard
1348417be3ae08346c6510c28d2042dd42a22a74b331Daniel Veillardstatic void
1349417be3ae08346c6510c28d2042dd42a22a74b331Daniel Veillardlibxml_xmlParserCtxtErrorFuncHandler(void *ctx, const char *msg, ...)
1350417be3ae08346c6510c28d2042dd42a22a74b331Daniel Veillard{
1351417be3ae08346c6510c28d2042dd42a22a74b331Daniel Veillard    va_list ap;
1352417be3ae08346c6510c28d2042dd42a22a74b331Daniel Veillard
1353417be3ae08346c6510c28d2042dd42a22a74b331Daniel Veillard    va_start(ap, msg);
1354417be3ae08346c6510c28d2042dd42a22a74b331Daniel Veillard    libxml_xmlParserCtxtGenericErrorFuncHandler(ctx,XML_PARSER_SEVERITY_ERROR,libxml_buildMessage(msg,ap));
1355417be3ae08346c6510c28d2042dd42a22a74b331Daniel Veillard    va_end(ap);
1356417be3ae08346c6510c28d2042dd42a22a74b331Daniel Veillard}
1357417be3ae08346c6510c28d2042dd42a22a74b331Daniel Veillard
1358417be3ae08346c6510c28d2042dd42a22a74b331Daniel Veillardstatic void
1359417be3ae08346c6510c28d2042dd42a22a74b331Daniel Veillardlibxml_xmlParserCtxtWarningFuncHandler(void *ctx, const char *msg, ...)
1360417be3ae08346c6510c28d2042dd42a22a74b331Daniel Veillard{
1361417be3ae08346c6510c28d2042dd42a22a74b331Daniel Veillard    va_list ap;
1362417be3ae08346c6510c28d2042dd42a22a74b331Daniel Veillard
1363417be3ae08346c6510c28d2042dd42a22a74b331Daniel Veillard    va_start(ap, msg);
1364417be3ae08346c6510c28d2042dd42a22a74b331Daniel Veillard    libxml_xmlParserCtxtGenericErrorFuncHandler(ctx,XML_PARSER_SEVERITY_WARNING,libxml_buildMessage(msg,ap));
1365417be3ae08346c6510c28d2042dd42a22a74b331Daniel Veillard    va_end(ap);
1366417be3ae08346c6510c28d2042dd42a22a74b331Daniel Veillard}
1367417be3ae08346c6510c28d2042dd42a22a74b331Daniel Veillard
1368417be3ae08346c6510c28d2042dd42a22a74b331Daniel Veillardstatic void
1369417be3ae08346c6510c28d2042dd42a22a74b331Daniel Veillardlibxml_xmlParserCtxtValidityErrorFuncHandler(void *ctx, const char *msg, ...)
1370417be3ae08346c6510c28d2042dd42a22a74b331Daniel Veillard{
1371417be3ae08346c6510c28d2042dd42a22a74b331Daniel Veillard    va_list ap;
1372417be3ae08346c6510c28d2042dd42a22a74b331Daniel Veillard
1373417be3ae08346c6510c28d2042dd42a22a74b331Daniel Veillard    va_start(ap, msg);
1374417be3ae08346c6510c28d2042dd42a22a74b331Daniel Veillard    libxml_xmlParserCtxtGenericErrorFuncHandler(ctx,XML_PARSER_SEVERITY_VALIDITY_ERROR,libxml_buildMessage(msg,ap));
1375417be3ae08346c6510c28d2042dd42a22a74b331Daniel Veillard    va_end(ap);
1376417be3ae08346c6510c28d2042dd42a22a74b331Daniel Veillard}
1377417be3ae08346c6510c28d2042dd42a22a74b331Daniel Veillard
1378417be3ae08346c6510c28d2042dd42a22a74b331Daniel Veillardstatic void
1379417be3ae08346c6510c28d2042dd42a22a74b331Daniel Veillardlibxml_xmlParserCtxtValidityWarningFuncHandler(void *ctx, const char *msg, ...)
1380417be3ae08346c6510c28d2042dd42a22a74b331Daniel Veillard{
1381417be3ae08346c6510c28d2042dd42a22a74b331Daniel Veillard    va_list ap;
1382417be3ae08346c6510c28d2042dd42a22a74b331Daniel Veillard
1383417be3ae08346c6510c28d2042dd42a22a74b331Daniel Veillard    va_start(ap, msg);
1384417be3ae08346c6510c28d2042dd42a22a74b331Daniel Veillard    libxml_xmlParserCtxtGenericErrorFuncHandler(ctx,XML_PARSER_SEVERITY_VALIDITY_WARNING,libxml_buildMessage(msg,ap));
1385417be3ae08346c6510c28d2042dd42a22a74b331Daniel Veillard    va_end(ap);
1386e6227e0549490b5bf9271ecd2d874a97c3f4852bDaniel Veillard}
1387e6227e0549490b5bf9271ecd2d874a97c3f4852bDaniel Veillard
1388e6227e0549490b5bf9271ecd2d874a97c3f4852bDaniel VeillardPyObject *
1389417be3ae08346c6510c28d2042dd42a22a74b331Daniel Veillardlibxml_xmlParserCtxtSetErrorHandler(ATTRIBUTE_UNUSED PyObject *self, PyObject *args)
1390e6227e0549490b5bf9271ecd2d874a97c3f4852bDaniel Veillard{
1391e6227e0549490b5bf9271ecd2d874a97c3f4852bDaniel Veillard    PyObject *py_retval;
1392e6227e0549490b5bf9271ecd2d874a97c3f4852bDaniel Veillard    xmlParserCtxtPtr ctxt;
1393e4a07e7b77b191d61291d44dffa19b65387e04e4Daniel Veillard    xmlParserCtxtPyCtxtPtr pyCtxt;
1394e6227e0549490b5bf9271ecd2d874a97c3f4852bDaniel Veillard    PyObject *pyobj_ctxt;
1395e6227e0549490b5bf9271ecd2d874a97c3f4852bDaniel Veillard    PyObject *pyobj_f;
1396e6227e0549490b5bf9271ecd2d874a97c3f4852bDaniel Veillard    PyObject *pyobj_arg;
1397e6227e0549490b5bf9271ecd2d874a97c3f4852bDaniel Veillard
1398417be3ae08346c6510c28d2042dd42a22a74b331Daniel Veillard    if (!PyArg_ParseTuple(args, (char *)"OOO:xmlParserCtxtSetErrorHandler",
1399e6227e0549490b5bf9271ecd2d874a97c3f4852bDaniel Veillard		          &pyobj_ctxt, &pyobj_f, &pyobj_arg))
1400e6227e0549490b5bf9271ecd2d874a97c3f4852bDaniel Veillard        return(NULL);
1401e6227e0549490b5bf9271ecd2d874a97c3f4852bDaniel Veillard    ctxt = (xmlParserCtxtPtr) PyparserCtxt_Get(pyobj_ctxt);
1402e6227e0549490b5bf9271ecd2d874a97c3f4852bDaniel Veillard    if (ctxt->_private == NULL) {
1403e6227e0549490b5bf9271ecd2d874a97c3f4852bDaniel Veillard	pyCtxt = xmlMalloc(sizeof(xmlParserCtxtPyCtxt));
1404e6227e0549490b5bf9271ecd2d874a97c3f4852bDaniel Veillard	if (pyCtxt == NULL) {
1405e6227e0549490b5bf9271ecd2d874a97c3f4852bDaniel Veillard	    py_retval = libxml_intWrap(-1);
1406e6227e0549490b5bf9271ecd2d874a97c3f4852bDaniel Veillard	    return(py_retval);
1407e6227e0549490b5bf9271ecd2d874a97c3f4852bDaniel Veillard	}
1408e6227e0549490b5bf9271ecd2d874a97c3f4852bDaniel Veillard	memset(pyCtxt,0,sizeof(xmlParserCtxtPyCtxt));
1409e6227e0549490b5bf9271ecd2d874a97c3f4852bDaniel Veillard	ctxt->_private = pyCtxt;
1410e6227e0549490b5bf9271ecd2d874a97c3f4852bDaniel Veillard    }
1411e4a07e7b77b191d61291d44dffa19b65387e04e4Daniel Veillard    else {
1412417be3ae08346c6510c28d2042dd42a22a74b331Daniel Veillard	pyCtxt = (xmlParserCtxtPyCtxtPtr)ctxt->_private;
1413e4a07e7b77b191d61291d44dffa19b65387e04e4Daniel Veillard    }
1414e6227e0549490b5bf9271ecd2d874a97c3f4852bDaniel Veillard    /* TODO: check f is a function ! */
1415417be3ae08346c6510c28d2042dd42a22a74b331Daniel Veillard    Py_XDECREF(pyCtxt->f);
1416e6227e0549490b5bf9271ecd2d874a97c3f4852bDaniel Veillard    Py_XINCREF(pyobj_f);
1417417be3ae08346c6510c28d2042dd42a22a74b331Daniel Veillard    pyCtxt->f = pyobj_f;
1418417be3ae08346c6510c28d2042dd42a22a74b331Daniel Veillard    Py_XDECREF(pyCtxt->arg);
1419e6227e0549490b5bf9271ecd2d874a97c3f4852bDaniel Veillard    Py_XINCREF(pyobj_arg);
1420417be3ae08346c6510c28d2042dd42a22a74b331Daniel Veillard    pyCtxt->arg = pyobj_arg;
1421e6227e0549490b5bf9271ecd2d874a97c3f4852bDaniel Veillard
1422417be3ae08346c6510c28d2042dd42a22a74b331Daniel Veillard    if (pyobj_f != Py_None) {
1423417be3ae08346c6510c28d2042dd42a22a74b331Daniel Veillard	ctxt->sax->error = libxml_xmlParserCtxtErrorFuncHandler;
1424417be3ae08346c6510c28d2042dd42a22a74b331Daniel Veillard	ctxt->sax->warning = libxml_xmlParserCtxtWarningFuncHandler;
1425417be3ae08346c6510c28d2042dd42a22a74b331Daniel Veillard	ctxt->vctxt.error = libxml_xmlParserCtxtValidityErrorFuncHandler;
1426417be3ae08346c6510c28d2042dd42a22a74b331Daniel Veillard	ctxt->vctxt.warning = libxml_xmlParserCtxtValidityWarningFuncHandler;
1427417be3ae08346c6510c28d2042dd42a22a74b331Daniel Veillard    }
1428417be3ae08346c6510c28d2042dd42a22a74b331Daniel Veillard    else {
1429417be3ae08346c6510c28d2042dd42a22a74b331Daniel Veillard	ctxt->sax->error = xmlParserError;
1430417be3ae08346c6510c28d2042dd42a22a74b331Daniel Veillard	ctxt->vctxt.error = xmlParserValidityError;
1431417be3ae08346c6510c28d2042dd42a22a74b331Daniel Veillard	ctxt->sax->warning = xmlParserWarning;
1432417be3ae08346c6510c28d2042dd42a22a74b331Daniel Veillard	ctxt->vctxt.warning = xmlParserValidityWarning;
1433417be3ae08346c6510c28d2042dd42a22a74b331Daniel Veillard    }
1434e6227e0549490b5bf9271ecd2d874a97c3f4852bDaniel Veillard
1435e6227e0549490b5bf9271ecd2d874a97c3f4852bDaniel Veillard    py_retval = libxml_intWrap(1);
1436e6227e0549490b5bf9271ecd2d874a97c3f4852bDaniel Veillard    return(py_retval);
1437e6227e0549490b5bf9271ecd2d874a97c3f4852bDaniel Veillard}
1438e6227e0549490b5bf9271ecd2d874a97c3f4852bDaniel Veillard
1439417be3ae08346c6510c28d2042dd42a22a74b331Daniel VeillardPyObject *
1440417be3ae08346c6510c28d2042dd42a22a74b331Daniel Veillardlibxml_xmlParserCtxtGetErrorHandler(ATTRIBUTE_UNUSED PyObject *self, PyObject *args)
1441e6227e0549490b5bf9271ecd2d874a97c3f4852bDaniel Veillard{
1442417be3ae08346c6510c28d2042dd42a22a74b331Daniel Veillard    PyObject *py_retval;
1443417be3ae08346c6510c28d2042dd42a22a74b331Daniel Veillard    xmlParserCtxtPtr ctxt;
1444e6227e0549490b5bf9271ecd2d874a97c3f4852bDaniel Veillard    xmlParserCtxtPyCtxtPtr pyCtxt;
1445417be3ae08346c6510c28d2042dd42a22a74b331Daniel Veillard    PyObject *pyobj_ctxt;
1446e6227e0549490b5bf9271ecd2d874a97c3f4852bDaniel Veillard
1447417be3ae08346c6510c28d2042dd42a22a74b331Daniel Veillard    if (!PyArg_ParseTuple(args, (char *)"O:xmlParserCtxtGetErrorHandler",
1448417be3ae08346c6510c28d2042dd42a22a74b331Daniel Veillard		          &pyobj_ctxt))
1449417be3ae08346c6510c28d2042dd42a22a74b331Daniel Veillard        return(NULL);
1450417be3ae08346c6510c28d2042dd42a22a74b331Daniel Veillard    ctxt = (xmlParserCtxtPtr) PyparserCtxt_Get(pyobj_ctxt);
1451417be3ae08346c6510c28d2042dd42a22a74b331Daniel Veillard    py_retval = PyTuple_New(2);
1452417be3ae08346c6510c28d2042dd42a22a74b331Daniel Veillard    if (ctxt->_private != NULL) {
1453417be3ae08346c6510c28d2042dd42a22a74b331Daniel Veillard	pyCtxt = (xmlParserCtxtPyCtxtPtr)ctxt->_private;
1454e6227e0549490b5bf9271ecd2d874a97c3f4852bDaniel Veillard
1455417be3ae08346c6510c28d2042dd42a22a74b331Daniel Veillard	PyTuple_SetItem(py_retval, 0, pyCtxt->f);
1456417be3ae08346c6510c28d2042dd42a22a74b331Daniel Veillard	Py_XINCREF(pyCtxt->f);
1457417be3ae08346c6510c28d2042dd42a22a74b331Daniel Veillard	PyTuple_SetItem(py_retval, 1, pyCtxt->arg);
1458417be3ae08346c6510c28d2042dd42a22a74b331Daniel Veillard	Py_XINCREF(pyCtxt->arg);
1459417be3ae08346c6510c28d2042dd42a22a74b331Daniel Veillard    }
1460417be3ae08346c6510c28d2042dd42a22a74b331Daniel Veillard    else {
1461417be3ae08346c6510c28d2042dd42a22a74b331Daniel Veillard	/* no python error handler registered */
1462417be3ae08346c6510c28d2042dd42a22a74b331Daniel Veillard	PyTuple_SetItem(py_retval, 0, Py_None);
1463417be3ae08346c6510c28d2042dd42a22a74b331Daniel Veillard	Py_XINCREF(Py_None);
1464417be3ae08346c6510c28d2042dd42a22a74b331Daniel Veillard	PyTuple_SetItem(py_retval, 1, Py_None);
1465417be3ae08346c6510c28d2042dd42a22a74b331Daniel Veillard	Py_XINCREF(Py_None);
1466e6227e0549490b5bf9271ecd2d874a97c3f4852bDaniel Veillard    }
1467417be3ae08346c6510c28d2042dd42a22a74b331Daniel Veillard    return(py_retval);
1468e6227e0549490b5bf9271ecd2d874a97c3f4852bDaniel Veillard}
1469e6227e0549490b5bf9271ecd2d874a97c3f4852bDaniel Veillard
1470e6227e0549490b5bf9271ecd2d874a97c3f4852bDaniel VeillardPyObject *
1471417be3ae08346c6510c28d2042dd42a22a74b331Daniel Veillardlibxml_xmlFreeParserCtxt(ATTRIBUTE_UNUSED PyObject *self, PyObject *args) {
1472e6227e0549490b5bf9271ecd2d874a97c3f4852bDaniel Veillard    xmlParserCtxtPtr ctxt;
1473e6227e0549490b5bf9271ecd2d874a97c3f4852bDaniel Veillard    PyObject *pyobj_ctxt;
1474417be3ae08346c6510c28d2042dd42a22a74b331Daniel Veillard    xmlParserCtxtPyCtxtPtr pyCtxt;
1475e6227e0549490b5bf9271ecd2d874a97c3f4852bDaniel Veillard
1476417be3ae08346c6510c28d2042dd42a22a74b331Daniel Veillard    if (!PyArg_ParseTuple(args, (char *)"O:xmlFreeParserCtxt", &pyobj_ctxt))
1477e6227e0549490b5bf9271ecd2d874a97c3f4852bDaniel Veillard        return(NULL);
1478e6227e0549490b5bf9271ecd2d874a97c3f4852bDaniel Veillard    ctxt = (xmlParserCtxtPtr) PyparserCtxt_Get(pyobj_ctxt);
1479417be3ae08346c6510c28d2042dd42a22a74b331Daniel Veillard
1480417be3ae08346c6510c28d2042dd42a22a74b331Daniel Veillard    if (ctxt != NULL) {
1481417be3ae08346c6510c28d2042dd42a22a74b331Daniel Veillard	pyCtxt = (xmlParserCtxtPyCtxtPtr)((xmlParserCtxtPtr)ctxt)->_private;
1482417be3ae08346c6510c28d2042dd42a22a74b331Daniel Veillard	if (pyCtxt) {
1483417be3ae08346c6510c28d2042dd42a22a74b331Daniel Veillard	    Py_XDECREF(pyCtxt->f);
1484417be3ae08346c6510c28d2042dd42a22a74b331Daniel Veillard	    Py_XDECREF(pyCtxt->arg);
1485417be3ae08346c6510c28d2042dd42a22a74b331Daniel Veillard	    xmlFree(pyCtxt);
1486e4a07e7b77b191d61291d44dffa19b65387e04e4Daniel Veillard	}
1487417be3ae08346c6510c28d2042dd42a22a74b331Daniel Veillard	xmlFreeParserCtxt(ctxt);
1488e4a07e7b77b191d61291d44dffa19b65387e04e4Daniel Veillard    }
1489e6227e0549490b5bf9271ecd2d874a97c3f4852bDaniel Veillard
1490417be3ae08346c6510c28d2042dd42a22a74b331Daniel Veillard    Py_INCREF(Py_None);
1491417be3ae08346c6510c28d2042dd42a22a74b331Daniel Veillard    return(Py_None);
1492e6227e0549490b5bf9271ecd2d874a97c3f4852bDaniel Veillard}
1493e6227e0549490b5bf9271ecd2d874a97c3f4852bDaniel Veillard
1494a7340c830e4bddd86201cfdb97ac81e30b0dee62Daniel Veillard/************************************************************************
1495a7340c830e4bddd86201cfdb97ac81e30b0dee62Daniel Veillard *									*
149626f70269c80140a7fb8a7aae9ef09c95efa98e70Daniel Veillard *                      Per xmlTextReader error handler                 *
149726f70269c80140a7fb8a7aae9ef09c95efa98e70Daniel Veillard *									*
149826f70269c80140a7fb8a7aae9ef09c95efa98e70Daniel Veillard ************************************************************************/
149926f70269c80140a7fb8a7aae9ef09c95efa98e70Daniel Veillard
150026f70269c80140a7fb8a7aae9ef09c95efa98e70Daniel Veillardtypedef struct
150126f70269c80140a7fb8a7aae9ef09c95efa98e70Daniel Veillard{
150226f70269c80140a7fb8a7aae9ef09c95efa98e70Daniel Veillard    PyObject *f;
150326f70269c80140a7fb8a7aae9ef09c95efa98e70Daniel Veillard    PyObject *arg;
150426f70269c80140a7fb8a7aae9ef09c95efa98e70Daniel Veillard} xmlTextReaderPyCtxt;
150526f70269c80140a7fb8a7aae9ef09c95efa98e70Daniel Veillardtypedef xmlTextReaderPyCtxt *xmlTextReaderPyCtxtPtr;
150626f70269c80140a7fb8a7aae9ef09c95efa98e70Daniel Veillard
150726f70269c80140a7fb8a7aae9ef09c95efa98e70Daniel Veillardstatic void
150826f70269c80140a7fb8a7aae9ef09c95efa98e70Daniel Veillardlibxml_xmlTextReaderErrorCallback(void *arg,
150926f70269c80140a7fb8a7aae9ef09c95efa98e70Daniel Veillard				  const char *msg,
1510417be3ae08346c6510c28d2042dd42a22a74b331Daniel Veillard				  int severity,
1511417be3ae08346c6510c28d2042dd42a22a74b331Daniel Veillard				  xmlTextReaderLocatorPtr locator)
151226f70269c80140a7fb8a7aae9ef09c95efa98e70Daniel Veillard{
151326f70269c80140a7fb8a7aae9ef09c95efa98e70Daniel Veillard    xmlTextReaderPyCtxt *pyCtxt = (xmlTextReaderPyCtxt *)arg;
151426f70269c80140a7fb8a7aae9ef09c95efa98e70Daniel Veillard    PyObject *list;
151526f70269c80140a7fb8a7aae9ef09c95efa98e70Daniel Veillard    PyObject *result;
151626f70269c80140a7fb8a7aae9ef09c95efa98e70Daniel Veillard
1517417be3ae08346c6510c28d2042dd42a22a74b331Daniel Veillard    list = PyTuple_New(4);
151826f70269c80140a7fb8a7aae9ef09c95efa98e70Daniel Veillard    PyTuple_SetItem(list, 0, pyCtxt->arg);
151926f70269c80140a7fb8a7aae9ef09c95efa98e70Daniel Veillard    Py_XINCREF(pyCtxt->arg);
152026f70269c80140a7fb8a7aae9ef09c95efa98e70Daniel Veillard    PyTuple_SetItem(list, 1, libxml_charPtrConstWrap(msg));
1521417be3ae08346c6510c28d2042dd42a22a74b331Daniel Veillard    PyTuple_SetItem(list, 2, libxml_intWrap(severity));
1522417be3ae08346c6510c28d2042dd42a22a74b331Daniel Veillard    PyTuple_SetItem(list, 3, libxml_xmlTextReaderLocatorPtrWrap(locator));
152326f70269c80140a7fb8a7aae9ef09c95efa98e70Daniel Veillard    result = PyEval_CallObject(pyCtxt->f, list);
152426f70269c80140a7fb8a7aae9ef09c95efa98e70Daniel Veillard    if (result == NULL)
152526f70269c80140a7fb8a7aae9ef09c95efa98e70Daniel Veillard    {
1526417be3ae08346c6510c28d2042dd42a22a74b331Daniel Veillard	/* TODO: manage for the exception to be propagated... */
152726f70269c80140a7fb8a7aae9ef09c95efa98e70Daniel Veillard	PyErr_Print();
152826f70269c80140a7fb8a7aae9ef09c95efa98e70Daniel Veillard    }
152926f70269c80140a7fb8a7aae9ef09c95efa98e70Daniel Veillard    Py_XDECREF(list);
153026f70269c80140a7fb8a7aae9ef09c95efa98e70Daniel Veillard    Py_XDECREF(result);
153126f70269c80140a7fb8a7aae9ef09c95efa98e70Daniel Veillard}
153226f70269c80140a7fb8a7aae9ef09c95efa98e70Daniel Veillard
153326f70269c80140a7fb8a7aae9ef09c95efa98e70Daniel VeillardPyObject *
153426f70269c80140a7fb8a7aae9ef09c95efa98e70Daniel Veillardlibxml_xmlTextReaderSetErrorHandler(ATTRIBUTE_UNUSED PyObject *self, PyObject *args)
153526f70269c80140a7fb8a7aae9ef09c95efa98e70Daniel Veillard{
153626f70269c80140a7fb8a7aae9ef09c95efa98e70Daniel Veillard    xmlTextReaderPtr reader;
153726f70269c80140a7fb8a7aae9ef09c95efa98e70Daniel Veillard    xmlTextReaderPyCtxtPtr pyCtxt;
153826f70269c80140a7fb8a7aae9ef09c95efa98e70Daniel Veillard    xmlTextReaderErrorFunc f;
153926f70269c80140a7fb8a7aae9ef09c95efa98e70Daniel Veillard    void *arg;
154026f70269c80140a7fb8a7aae9ef09c95efa98e70Daniel Veillard    PyObject *pyobj_reader;
154126f70269c80140a7fb8a7aae9ef09c95efa98e70Daniel Veillard    PyObject *pyobj_f;
154226f70269c80140a7fb8a7aae9ef09c95efa98e70Daniel Veillard    PyObject *pyobj_arg;
154326f70269c80140a7fb8a7aae9ef09c95efa98e70Daniel Veillard    PyObject *py_retval;
154426f70269c80140a7fb8a7aae9ef09c95efa98e70Daniel Veillard
154526f70269c80140a7fb8a7aae9ef09c95efa98e70Daniel Veillard    if (!PyArg_ParseTuple(args, (char *)"OOO:xmlTextReaderSetErrorHandler", &pyobj_reader, &pyobj_f, &pyobj_arg))
154626f70269c80140a7fb8a7aae9ef09c95efa98e70Daniel Veillard        return(NULL);
154726f70269c80140a7fb8a7aae9ef09c95efa98e70Daniel Veillard    reader = (xmlTextReaderPtr) PyxmlTextReader_Get(pyobj_reader);
154826f70269c80140a7fb8a7aae9ef09c95efa98e70Daniel Veillard    /* clear previous error handler */
154926f70269c80140a7fb8a7aae9ef09c95efa98e70Daniel Veillard    xmlTextReaderGetErrorHandler(reader,&f,&arg);
155026f70269c80140a7fb8a7aae9ef09c95efa98e70Daniel Veillard    if (arg != NULL) {
155126f70269c80140a7fb8a7aae9ef09c95efa98e70Daniel Veillard	if (f == libxml_xmlTextReaderErrorCallback) {
155226f70269c80140a7fb8a7aae9ef09c95efa98e70Daniel Veillard	    /* ok, it's our error handler! */
155326f70269c80140a7fb8a7aae9ef09c95efa98e70Daniel Veillard	    pyCtxt = (xmlTextReaderPyCtxtPtr)arg;
155426f70269c80140a7fb8a7aae9ef09c95efa98e70Daniel Veillard	    Py_XDECREF(pyCtxt->f);
155526f70269c80140a7fb8a7aae9ef09c95efa98e70Daniel Veillard	    Py_XDECREF(pyCtxt->arg);
155626f70269c80140a7fb8a7aae9ef09c95efa98e70Daniel Veillard	    xmlFree(pyCtxt);
155726f70269c80140a7fb8a7aae9ef09c95efa98e70Daniel Veillard	}
155826f70269c80140a7fb8a7aae9ef09c95efa98e70Daniel Veillard	else {
155926f70269c80140a7fb8a7aae9ef09c95efa98e70Daniel Veillard	    /*
156026f70269c80140a7fb8a7aae9ef09c95efa98e70Daniel Veillard	     * there already an arg, and it's not ours,
156126f70269c80140a7fb8a7aae9ef09c95efa98e70Daniel Veillard	     * there is definitely something wrong going on here...
156226f70269c80140a7fb8a7aae9ef09c95efa98e70Daniel Veillard	     * we don't know how to free it, so we bail out...
156326f70269c80140a7fb8a7aae9ef09c95efa98e70Daniel Veillard	     */
156426f70269c80140a7fb8a7aae9ef09c95efa98e70Daniel Veillard	    py_retval = libxml_intWrap(-1);
156526f70269c80140a7fb8a7aae9ef09c95efa98e70Daniel Veillard	    return(py_retval);
156626f70269c80140a7fb8a7aae9ef09c95efa98e70Daniel Veillard	}
156726f70269c80140a7fb8a7aae9ef09c95efa98e70Daniel Veillard    }
156826f70269c80140a7fb8a7aae9ef09c95efa98e70Daniel Veillard    xmlTextReaderSetErrorHandler(reader,NULL,NULL);
156926f70269c80140a7fb8a7aae9ef09c95efa98e70Daniel Veillard    /* set new error handler */
157026f70269c80140a7fb8a7aae9ef09c95efa98e70Daniel Veillard    if (pyobj_f != Py_None)
157126f70269c80140a7fb8a7aae9ef09c95efa98e70Daniel Veillard    {
157226f70269c80140a7fb8a7aae9ef09c95efa98e70Daniel Veillard	pyCtxt = (xmlTextReaderPyCtxtPtr)xmlMalloc(sizeof(xmlTextReaderPyCtxt));
157326f70269c80140a7fb8a7aae9ef09c95efa98e70Daniel Veillard	if (pyCtxt == NULL) {
157426f70269c80140a7fb8a7aae9ef09c95efa98e70Daniel Veillard	    py_retval = libxml_intWrap(-1);
157526f70269c80140a7fb8a7aae9ef09c95efa98e70Daniel Veillard	    return(py_retval);
157626f70269c80140a7fb8a7aae9ef09c95efa98e70Daniel Veillard	}
157726f70269c80140a7fb8a7aae9ef09c95efa98e70Daniel Veillard	Py_XINCREF(pyobj_f);
157826f70269c80140a7fb8a7aae9ef09c95efa98e70Daniel Veillard	pyCtxt->f = pyobj_f;
157926f70269c80140a7fb8a7aae9ef09c95efa98e70Daniel Veillard	Py_XINCREF(pyobj_arg);
158026f70269c80140a7fb8a7aae9ef09c95efa98e70Daniel Veillard	pyCtxt->arg = pyobj_arg;
158126f70269c80140a7fb8a7aae9ef09c95efa98e70Daniel Veillard	xmlTextReaderSetErrorHandler(reader,libxml_xmlTextReaderErrorCallback,pyCtxt);
158226f70269c80140a7fb8a7aae9ef09c95efa98e70Daniel Veillard    }
158326f70269c80140a7fb8a7aae9ef09c95efa98e70Daniel Veillard
158426f70269c80140a7fb8a7aae9ef09c95efa98e70Daniel Veillard    py_retval = libxml_intWrap(1);
158526f70269c80140a7fb8a7aae9ef09c95efa98e70Daniel Veillard    return(py_retval);
158626f70269c80140a7fb8a7aae9ef09c95efa98e70Daniel Veillard}
158726f70269c80140a7fb8a7aae9ef09c95efa98e70Daniel Veillard
158826f70269c80140a7fb8a7aae9ef09c95efa98e70Daniel VeillardPyObject *
158926f70269c80140a7fb8a7aae9ef09c95efa98e70Daniel Veillardlibxml_xmlTextReaderGetErrorHandler(ATTRIBUTE_UNUSED PyObject *self, PyObject *args)
159026f70269c80140a7fb8a7aae9ef09c95efa98e70Daniel Veillard{
159126f70269c80140a7fb8a7aae9ef09c95efa98e70Daniel Veillard    xmlTextReaderPtr reader;
159226f70269c80140a7fb8a7aae9ef09c95efa98e70Daniel Veillard    xmlTextReaderPyCtxtPtr pyCtxt;
159326f70269c80140a7fb8a7aae9ef09c95efa98e70Daniel Veillard    xmlTextReaderErrorFunc f;
159426f70269c80140a7fb8a7aae9ef09c95efa98e70Daniel Veillard    void *arg;
159526f70269c80140a7fb8a7aae9ef09c95efa98e70Daniel Veillard    PyObject *pyobj_reader;
159626f70269c80140a7fb8a7aae9ef09c95efa98e70Daniel Veillard    PyObject *py_retval;
159726f70269c80140a7fb8a7aae9ef09c95efa98e70Daniel Veillard
159826f70269c80140a7fb8a7aae9ef09c95efa98e70Daniel Veillard    if (!PyArg_ParseTuple(args, (char *)"O:xmlTextReaderSetErrorHandler", &pyobj_reader))
159926f70269c80140a7fb8a7aae9ef09c95efa98e70Daniel Veillard        return(NULL);
160026f70269c80140a7fb8a7aae9ef09c95efa98e70Daniel Veillard    reader = (xmlTextReaderPtr) PyxmlTextReader_Get(pyobj_reader);
160126f70269c80140a7fb8a7aae9ef09c95efa98e70Daniel Veillard    xmlTextReaderGetErrorHandler(reader,&f,&arg);
160226f70269c80140a7fb8a7aae9ef09c95efa98e70Daniel Veillard    py_retval = PyTuple_New(2);
160326f70269c80140a7fb8a7aae9ef09c95efa98e70Daniel Veillard    if (f == libxml_xmlTextReaderErrorCallback) {
160426f70269c80140a7fb8a7aae9ef09c95efa98e70Daniel Veillard	/* ok, it's our error handler! */
160526f70269c80140a7fb8a7aae9ef09c95efa98e70Daniel Veillard	pyCtxt = (xmlTextReaderPyCtxtPtr)arg;
160626f70269c80140a7fb8a7aae9ef09c95efa98e70Daniel Veillard	PyTuple_SetItem(py_retval, 0, pyCtxt->f);
160726f70269c80140a7fb8a7aae9ef09c95efa98e70Daniel Veillard	Py_XINCREF(pyCtxt->f);
160826f70269c80140a7fb8a7aae9ef09c95efa98e70Daniel Veillard	PyTuple_SetItem(py_retval, 1, pyCtxt->arg);
160926f70269c80140a7fb8a7aae9ef09c95efa98e70Daniel Veillard	Py_XINCREF(pyCtxt->arg);
161026f70269c80140a7fb8a7aae9ef09c95efa98e70Daniel Veillard    }
161126f70269c80140a7fb8a7aae9ef09c95efa98e70Daniel Veillard    else
161226f70269c80140a7fb8a7aae9ef09c95efa98e70Daniel Veillard    {
161326f70269c80140a7fb8a7aae9ef09c95efa98e70Daniel Veillard	/* f is null or it's not our error handler */
161426f70269c80140a7fb8a7aae9ef09c95efa98e70Daniel Veillard	PyTuple_SetItem(py_retval, 0, Py_None);
161526f70269c80140a7fb8a7aae9ef09c95efa98e70Daniel Veillard	Py_XINCREF(Py_None);
161626f70269c80140a7fb8a7aae9ef09c95efa98e70Daniel Veillard	PyTuple_SetItem(py_retval, 1, Py_None);
161726f70269c80140a7fb8a7aae9ef09c95efa98e70Daniel Veillard	Py_XINCREF(Py_None);
161826f70269c80140a7fb8a7aae9ef09c95efa98e70Daniel Veillard    }
161926f70269c80140a7fb8a7aae9ef09c95efa98e70Daniel Veillard    return(py_retval);
162026f70269c80140a7fb8a7aae9ef09c95efa98e70Daniel Veillard}
162126f70269c80140a7fb8a7aae9ef09c95efa98e70Daniel Veillard
162226f70269c80140a7fb8a7aae9ef09c95efa98e70Daniel VeillardPyObject *
162326f70269c80140a7fb8a7aae9ef09c95efa98e70Daniel Veillardlibxml_xmlFreeTextReader(ATTRIBUTE_UNUSED PyObject *self, PyObject *args) {
162426f70269c80140a7fb8a7aae9ef09c95efa98e70Daniel Veillard    xmlTextReaderPtr reader;
162526f70269c80140a7fb8a7aae9ef09c95efa98e70Daniel Veillard    PyObject *pyobj_reader;
162626f70269c80140a7fb8a7aae9ef09c95efa98e70Daniel Veillard    xmlTextReaderPyCtxtPtr pyCtxt;
162726f70269c80140a7fb8a7aae9ef09c95efa98e70Daniel Veillard    xmlTextReaderErrorFunc f;
162826f70269c80140a7fb8a7aae9ef09c95efa98e70Daniel Veillard    void *arg;
162926f70269c80140a7fb8a7aae9ef09c95efa98e70Daniel Veillard
163026f70269c80140a7fb8a7aae9ef09c95efa98e70Daniel Veillard    if (!PyArg_ParseTuple(args, (char *)"O:xmlFreeTextReader", &pyobj_reader))
163126f70269c80140a7fb8a7aae9ef09c95efa98e70Daniel Veillard        return(NULL);
163226f70269c80140a7fb8a7aae9ef09c95efa98e70Daniel Veillard    reader = (xmlTextReaderPtr) PyxmlTextReader_Get(pyobj_reader);
163326f70269c80140a7fb8a7aae9ef09c95efa98e70Daniel Veillard
163426f70269c80140a7fb8a7aae9ef09c95efa98e70Daniel Veillard    xmlTextReaderGetErrorHandler(reader,&f,&arg);
163526f70269c80140a7fb8a7aae9ef09c95efa98e70Daniel Veillard    if (arg != NULL) {
163626f70269c80140a7fb8a7aae9ef09c95efa98e70Daniel Veillard	if (f == libxml_xmlTextReaderErrorCallback) {
163726f70269c80140a7fb8a7aae9ef09c95efa98e70Daniel Veillard	    /* ok, it's our error handler! */
163826f70269c80140a7fb8a7aae9ef09c95efa98e70Daniel Veillard	    pyCtxt = (xmlTextReaderPyCtxtPtr)arg;
163926f70269c80140a7fb8a7aae9ef09c95efa98e70Daniel Veillard	    Py_XDECREF(pyCtxt->f);
164026f70269c80140a7fb8a7aae9ef09c95efa98e70Daniel Veillard	    Py_XDECREF(pyCtxt->arg);
164126f70269c80140a7fb8a7aae9ef09c95efa98e70Daniel Veillard	    xmlFree(pyCtxt);
164226f70269c80140a7fb8a7aae9ef09c95efa98e70Daniel Veillard	}
164326f70269c80140a7fb8a7aae9ef09c95efa98e70Daniel Veillard	/*
164426f70269c80140a7fb8a7aae9ef09c95efa98e70Daniel Veillard	 * else, something wrong happened, because the error handler is
164526f70269c80140a7fb8a7aae9ef09c95efa98e70Daniel Veillard	 * not owned by the python bindings...
164626f70269c80140a7fb8a7aae9ef09c95efa98e70Daniel Veillard	 */
164726f70269c80140a7fb8a7aae9ef09c95efa98e70Daniel Veillard    }
164826f70269c80140a7fb8a7aae9ef09c95efa98e70Daniel Veillard
164926f70269c80140a7fb8a7aae9ef09c95efa98e70Daniel Veillard    xmlFreeTextReader(reader);
165026f70269c80140a7fb8a7aae9ef09c95efa98e70Daniel Veillard    Py_INCREF(Py_None);
165126f70269c80140a7fb8a7aae9ef09c95efa98e70Daniel Veillard    return(Py_None);
165226f70269c80140a7fb8a7aae9ef09c95efa98e70Daniel Veillard}
165326f70269c80140a7fb8a7aae9ef09c95efa98e70Daniel Veillard
165426f70269c80140a7fb8a7aae9ef09c95efa98e70Daniel Veillard/************************************************************************
165526f70269c80140a7fb8a7aae9ef09c95efa98e70Daniel Veillard *									*
1656a7340c830e4bddd86201cfdb97ac81e30b0dee62Daniel Veillard *			XPath extensions				*
1657a7340c830e4bddd86201cfdb97ac81e30b0dee62Daniel Veillard *									*
1658a7340c830e4bddd86201cfdb97ac81e30b0dee62Daniel Veillard ************************************************************************/
1659a7340c830e4bddd86201cfdb97ac81e30b0dee62Daniel Veillard
1660a7340c830e4bddd86201cfdb97ac81e30b0dee62Daniel Veillardstatic int libxml_xpathCallbacksInitialized = 0;
1661a7340c830e4bddd86201cfdb97ac81e30b0dee62Daniel Veillard
1662a7340c830e4bddd86201cfdb97ac81e30b0dee62Daniel Veillardtypedef struct libxml_xpathCallback {
1663a7340c830e4bddd86201cfdb97ac81e30b0dee62Daniel Veillard    xmlXPathContextPtr ctx;
1664a7340c830e4bddd86201cfdb97ac81e30b0dee62Daniel Veillard    xmlChar *name;
1665a7340c830e4bddd86201cfdb97ac81e30b0dee62Daniel Veillard    xmlChar *ns_uri;
1666a7340c830e4bddd86201cfdb97ac81e30b0dee62Daniel Veillard    PyObject *function;
1667a7340c830e4bddd86201cfdb97ac81e30b0dee62Daniel Veillard} libxml_xpathCallback, *libxml_xpathCallbackPtr;
1668a7340c830e4bddd86201cfdb97ac81e30b0dee62Daniel Veillardstatic libxml_xpathCallback libxml_xpathCallbacks[10];
1669a7340c830e4bddd86201cfdb97ac81e30b0dee62Daniel Veillardstatic int libxml_xpathCallbacksNb = 0;
1670a7340c830e4bddd86201cfdb97ac81e30b0dee62Daniel Veillardstatic int libxml_xpathCallbacksMax = 10;
1671a7340c830e4bddd86201cfdb97ac81e30b0dee62Daniel Veillard
1672a7340c830e4bddd86201cfdb97ac81e30b0dee62Daniel Veillardstatic void
1673d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillardlibxml_xmlXPathFuncCallback(xmlXPathParserContextPtr ctxt, int nargs)
1674d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard{
1675a7340c830e4bddd86201cfdb97ac81e30b0dee62Daniel Veillard    PyObject *list, *cur, *result;
1676a7340c830e4bddd86201cfdb97ac81e30b0dee62Daniel Veillard    xmlXPathObjectPtr obj;
167770cab35abbb75eb9f0e328d498aa7a85195a1d5bDaniel Veillard    xmlXPathContextPtr rctxt;
167870cab35abbb75eb9f0e328d498aa7a85195a1d5bDaniel Veillard    PyObject *current_function = NULL;
167970cab35abbb75eb9f0e328d498aa7a85195a1d5bDaniel Veillard    const xmlChar *name;
168070cab35abbb75eb9f0e328d498aa7a85195a1d5bDaniel Veillard    const xmlChar *ns_uri;
1681a7340c830e4bddd86201cfdb97ac81e30b0dee62Daniel Veillard    int i;
1682a7340c830e4bddd86201cfdb97ac81e30b0dee62Daniel Veillard
168370cab35abbb75eb9f0e328d498aa7a85195a1d5bDaniel Veillard    if (ctxt == NULL)
1684d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        return;
168570cab35abbb75eb9f0e328d498aa7a85195a1d5bDaniel Veillard    rctxt = ctxt->context;
168670cab35abbb75eb9f0e328d498aa7a85195a1d5bDaniel Veillard    if (rctxt == NULL)
1687d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        return;
168870cab35abbb75eb9f0e328d498aa7a85195a1d5bDaniel Veillard    name = rctxt->function;
168970cab35abbb75eb9f0e328d498aa7a85195a1d5bDaniel Veillard    ns_uri = rctxt->functionURI;
1690a7340c830e4bddd86201cfdb97ac81e30b0dee62Daniel Veillard#ifdef DEBUG_XPATH
1691d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard    printf("libxml_xmlXPathFuncCallback called name %s URI %s\n", name,
1692d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard           ns_uri);
1693a7340c830e4bddd86201cfdb97ac81e30b0dee62Daniel Veillard#endif
1694a7340c830e4bddd86201cfdb97ac81e30b0dee62Daniel Veillard
169570cab35abbb75eb9f0e328d498aa7a85195a1d5bDaniel Veillard    /*
169670cab35abbb75eb9f0e328d498aa7a85195a1d5bDaniel Veillard     * Find the function, it should be there it was there at lookup
169770cab35abbb75eb9f0e328d498aa7a85195a1d5bDaniel Veillard     */
1698d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard    for (i = 0; i < libxml_xpathCallbacksNb; i++) {
1699d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        if (                    /* TODO (ctxt == libxml_xpathCallbacks[i].ctx) && */
1700d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard               (xmlStrEqual(name, libxml_xpathCallbacks[i].name)) &&
1701d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard               (xmlStrEqual(ns_uri, libxml_xpathCallbacks[i].ns_uri))) {
1702d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            current_function = libxml_xpathCallbacks[i].function;
1703d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        }
170470cab35abbb75eb9f0e328d498aa7a85195a1d5bDaniel Veillard    }
170570cab35abbb75eb9f0e328d498aa7a85195a1d5bDaniel Veillard    if (current_function == NULL) {
1706d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        printf
1707d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            ("libxml_xmlXPathFuncCallback: internal error %s not found !\n",
1708d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard             name);
1709d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        return;
171070cab35abbb75eb9f0e328d498aa7a85195a1d5bDaniel Veillard    }
171170cab35abbb75eb9f0e328d498aa7a85195a1d5bDaniel Veillard
1712c575b997d85d4791d852ad43e175d47a64cf8b3cDaniel Veillard    list = PyTuple_New(nargs + 1);
1713c575b997d85d4791d852ad43e175d47a64cf8b3cDaniel Veillard    PyTuple_SetItem(list, 0, libxml_xmlXPathParserContextPtrWrap(ctxt));
1714d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard    for (i = 0; i < nargs; i++) {
1715d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        obj = valuePop(ctxt);
1716d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        cur = libxml_xmlXPathObjectPtrWrap(obj);
1717d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        PyTuple_SetItem(list, i + 1, cur);
1718a7340c830e4bddd86201cfdb97ac81e30b0dee62Daniel Veillard    }
1719a7340c830e4bddd86201cfdb97ac81e30b0dee62Daniel Veillard    result = PyEval_CallObject(current_function, list);
1720a7340c830e4bddd86201cfdb97ac81e30b0dee62Daniel Veillard    Py_DECREF(list);
1721a7340c830e4bddd86201cfdb97ac81e30b0dee62Daniel Veillard
1722a7340c830e4bddd86201cfdb97ac81e30b0dee62Daniel Veillard    obj = libxml_xmlXPathObjectPtrConvert(result);
1723a7340c830e4bddd86201cfdb97ac81e30b0dee62Daniel Veillard    valuePush(ctxt, obj);
1724a7340c830e4bddd86201cfdb97ac81e30b0dee62Daniel Veillard}
1725a7340c830e4bddd86201cfdb97ac81e30b0dee62Daniel Veillard
1726a7340c830e4bddd86201cfdb97ac81e30b0dee62Daniel Veillardstatic xmlXPathFunction
1727d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillardlibxml_xmlXPathFuncLookupFunc(void *ctxt, const xmlChar * name,
1728d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard                              const xmlChar * ns_uri)
1729d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard{
1730a7340c830e4bddd86201cfdb97ac81e30b0dee62Daniel Veillard    int i;
1731d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard
1732a7340c830e4bddd86201cfdb97ac81e30b0dee62Daniel Veillard#ifdef DEBUG_XPATH
1733a7340c830e4bddd86201cfdb97ac81e30b0dee62Daniel Veillard    printf("libxml_xmlXPathFuncLookupFunc(%p, %s, %s) called\n",
1734d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard           ctxt, name, ns_uri);
1735a7340c830e4bddd86201cfdb97ac81e30b0dee62Daniel Veillard#endif
173670cab35abbb75eb9f0e328d498aa7a85195a1d5bDaniel Veillard    /*
173770cab35abbb75eb9f0e328d498aa7a85195a1d5bDaniel Veillard     * This is called once only. The address is then stored in the
173870cab35abbb75eb9f0e328d498aa7a85195a1d5bDaniel Veillard     * XPath expression evaluation, the proper object to call can
173970cab35abbb75eb9f0e328d498aa7a85195a1d5bDaniel Veillard     * then still be found using the execution context function
174070cab35abbb75eb9f0e328d498aa7a85195a1d5bDaniel Veillard     * and functionURI fields.
174170cab35abbb75eb9f0e328d498aa7a85195a1d5bDaniel Veillard     */
1742d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard    for (i = 0; i < libxml_xpathCallbacksNb; i++) {
1743d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        if ((ctxt == libxml_xpathCallbacks[i].ctx) &&
1744d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            (xmlStrEqual(name, libxml_xpathCallbacks[i].name)) &&
1745d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            (xmlStrEqual(ns_uri, libxml_xpathCallbacks[i].ns_uri))) {
1746d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            return (libxml_xmlXPathFuncCallback);
1747d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        }
1748a7340c830e4bddd86201cfdb97ac81e30b0dee62Daniel Veillard    }
1749d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard    return (NULL);
1750a7340c830e4bddd86201cfdb97ac81e30b0dee62Daniel Veillard}
1751a7340c830e4bddd86201cfdb97ac81e30b0dee62Daniel Veillard
1752a7340c830e4bddd86201cfdb97ac81e30b0dee62Daniel Veillardstatic void
1753d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillardlibxml_xpathCallbacksInitialize(void)
1754d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard{
1755a7340c830e4bddd86201cfdb97ac81e30b0dee62Daniel Veillard    int i;
1756a7340c830e4bddd86201cfdb97ac81e30b0dee62Daniel Veillard
1757a7340c830e4bddd86201cfdb97ac81e30b0dee62Daniel Veillard    if (libxml_xpathCallbacksInitialized != 0)
1758d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        return;
1759a7340c830e4bddd86201cfdb97ac81e30b0dee62Daniel Veillard
1760a7340c830e4bddd86201cfdb97ac81e30b0dee62Daniel Veillard#ifdef DEBUG_XPATH
1761a7340c830e4bddd86201cfdb97ac81e30b0dee62Daniel Veillard    printf("libxml_xpathCallbacksInitialized called\n");
1762a7340c830e4bddd86201cfdb97ac81e30b0dee62Daniel Veillard#endif
1763a7340c830e4bddd86201cfdb97ac81e30b0dee62Daniel Veillard
1764d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard    for (i = 0; i < 10; i++) {
1765d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        libxml_xpathCallbacks[i].ctx = NULL;
1766d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        libxml_xpathCallbacks[i].name = NULL;
1767d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        libxml_xpathCallbacks[i].ns_uri = NULL;
1768d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        libxml_xpathCallbacks[i].function = NULL;
1769a7340c830e4bddd86201cfdb97ac81e30b0dee62Daniel Veillard    }
1770a7340c830e4bddd86201cfdb97ac81e30b0dee62Daniel Veillard    libxml_xpathCallbacksInitialized = 1;
1771a7340c830e4bddd86201cfdb97ac81e30b0dee62Daniel Veillard}
1772a7340c830e4bddd86201cfdb97ac81e30b0dee62Daniel Veillard
1773a7340c830e4bddd86201cfdb97ac81e30b0dee62Daniel VeillardPyObject *
1774d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillardlibxml_xmlRegisterXPathFunction(ATTRIBUTE_UNUSED PyObject * self,
1775d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard                                PyObject * args)
1776d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard{
1777a7340c830e4bddd86201cfdb97ac81e30b0dee62Daniel Veillard    PyObject *py_retval;
1778a7340c830e4bddd86201cfdb97ac81e30b0dee62Daniel Veillard    int c_retval = 0;
1779a7340c830e4bddd86201cfdb97ac81e30b0dee62Daniel Veillard    xmlChar *name;
1780a7340c830e4bddd86201cfdb97ac81e30b0dee62Daniel Veillard    xmlChar *ns_uri;
1781a7340c830e4bddd86201cfdb97ac81e30b0dee62Daniel Veillard    xmlXPathContextPtr ctx;
1782a7340c830e4bddd86201cfdb97ac81e30b0dee62Daniel Veillard    PyObject *pyobj_ctx;
1783a7340c830e4bddd86201cfdb97ac81e30b0dee62Daniel Veillard    PyObject *pyobj_f;
1784a7340c830e4bddd86201cfdb97ac81e30b0dee62Daniel Veillard    int i;
1785a7340c830e4bddd86201cfdb97ac81e30b0dee62Daniel Veillard
1786d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard    if (!PyArg_ParseTuple
1787d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        (args, (char *) "OszO:registerXPathFunction", &pyobj_ctx, &name,
1788d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard         &ns_uri, &pyobj_f))
1789d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        return (NULL);
1790a7340c830e4bddd86201cfdb97ac81e30b0dee62Daniel Veillard
1791a7340c830e4bddd86201cfdb97ac81e30b0dee62Daniel Veillard    ctx = (xmlXPathContextPtr) PyxmlXPathContext_Get(pyobj_ctx);
1792a7340c830e4bddd86201cfdb97ac81e30b0dee62Daniel Veillard    if (libxml_xpathCallbacksInitialized == 0)
1793d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        libxml_xpathCallbacksInitialize();
1794a7340c830e4bddd86201cfdb97ac81e30b0dee62Daniel Veillard    xmlXPathRegisterFuncLookup(ctx, libxml_xmlXPathFuncLookupFunc, ctx);
1795a7340c830e4bddd86201cfdb97ac81e30b0dee62Daniel Veillard
1796a7340c830e4bddd86201cfdb97ac81e30b0dee62Daniel Veillard    if ((pyobj_ctx == NULL) || (name == NULL) || (pyobj_f == NULL)) {
1797d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        py_retval = libxml_intWrap(-1);
1798d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        return (py_retval);
1799a7340c830e4bddd86201cfdb97ac81e30b0dee62Daniel Veillard    }
1800a7340c830e4bddd86201cfdb97ac81e30b0dee62Daniel Veillard#ifdef DEBUG_XPATH
1801a7340c830e4bddd86201cfdb97ac81e30b0dee62Daniel Veillard    printf("libxml_registerXPathFunction(%p, %s, %s) called\n",
1802d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard           ctx, name, ns_uri);
1803a7340c830e4bddd86201cfdb97ac81e30b0dee62Daniel Veillard#endif
1804d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard    for (i = 0; i < libxml_xpathCallbacksNb; i++) {
1805d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        if ((ctx == libxml_xpathCallbacks[i].ctx) &&
1806d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            (xmlStrEqual(name, libxml_xpathCallbacks[i].name)) &&
1807d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            (xmlStrEqual(ns_uri, libxml_xpathCallbacks[i].ns_uri))) {
1808d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            Py_XINCREF(pyobj_f);
1809d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            Py_XDECREF(libxml_xpathCallbacks[i].function);
1810d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            libxml_xpathCallbacks[i].function = pyobj_f;
1811d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            c_retval = 1;
1812d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            goto done;
1813d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        }
1814a7340c830e4bddd86201cfdb97ac81e30b0dee62Daniel Veillard    }
1815a7340c830e4bddd86201cfdb97ac81e30b0dee62Daniel Veillard    if (libxml_xpathCallbacksNb >= libxml_xpathCallbacksMax) {
1816d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        printf("libxml_registerXPathFunction() table full\n");
1817a7340c830e4bddd86201cfdb97ac81e30b0dee62Daniel Veillard    } else {
1818d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        i = libxml_xpathCallbacksNb++;
1819d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        Py_XINCREF(pyobj_f);
1820a7340c830e4bddd86201cfdb97ac81e30b0dee62Daniel Veillard        libxml_xpathCallbacks[i].ctx = ctx;
1821a7340c830e4bddd86201cfdb97ac81e30b0dee62Daniel Veillard        libxml_xpathCallbacks[i].name = xmlStrdup(name);
1822a7340c830e4bddd86201cfdb97ac81e30b0dee62Daniel Veillard        libxml_xpathCallbacks[i].ns_uri = xmlStrdup(ns_uri);
1823d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        libxml_xpathCallbacks[i].function = pyobj_f;
1824d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        c_retval = 1;
1825a7340c830e4bddd86201cfdb97ac81e30b0dee62Daniel Veillard    }
1826d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard  done:
1827a7340c830e4bddd86201cfdb97ac81e30b0dee62Daniel Veillard    py_retval = libxml_intWrap((int) c_retval);
1828d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard    return (py_retval);
1829a7340c830e4bddd86201cfdb97ac81e30b0dee62Daniel Veillard}
1830a7340c830e4bddd86201cfdb97ac81e30b0dee62Daniel Veillard
18311971ee2698cb84c7699c96d3302f00e20d42c0d3Daniel Veillard/************************************************************************
18321971ee2698cb84c7699c96d3302f00e20d42c0d3Daniel Veillard *									*
1833d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard *			Global properties access			*
1834d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard *									*
1835d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard ************************************************************************/
1836d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillardstatic PyObject *
1837d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillardlibxml_name(ATTRIBUTE_UNUSED PyObject * self, PyObject * args)
1838d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard{
1839d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard    PyObject *resultobj, *obj;
1840d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard    xmlNodePtr cur;
1841d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard    const xmlChar *res;
1842d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard
1843d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard    if (!PyArg_ParseTuple(args, (char *) "O:name", &obj))
1844d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard        return NULL;
1845d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard    cur = PyxmlNode_Get(obj);
1846d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard
1847d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard#ifdef DEBUG
1848d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard    printf("libxml_name: cur = %p type %d\n", cur, cur->type);
1849d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard#endif
1850d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard
1851d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard    switch (cur->type) {
1852d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        case XML_DOCUMENT_NODE:
1853d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard#ifdef LIBXML_DOCB_ENABLED
1854d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        case XML_DOCB_DOCUMENT_NODE:
1855d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard#endif
1856d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        case XML_HTML_DOCUMENT_NODE:{
1857d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard                xmlDocPtr doc = (xmlDocPtr) cur;
1858d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard
1859d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard                res = doc->URL;
1860d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard                break;
1861d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            }
1862d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        case XML_ATTRIBUTE_NODE:{
1863d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard                xmlAttrPtr attr = (xmlAttrPtr) cur;
1864d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard
1865d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard                res = attr->name;
1866d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard                break;
1867d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            }
1868d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        case XML_NAMESPACE_DECL:{
1869d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard                xmlNsPtr ns = (xmlNsPtr) cur;
1870d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard
1871d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard                res = ns->prefix;
1872d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard                break;
1873d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            }
1874d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        default:
1875d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            res = cur->name;
1876d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            break;
1877d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard    }
18781971ee2698cb84c7699c96d3302f00e20d42c0d3Daniel Veillard    resultobj = libxml_constxmlCharPtrWrap(res);
1879d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard
1880d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard    return resultobj;
1881d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard}
1882d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard
1883d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillardstatic PyObject *
1884d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillardlibxml_doc(ATTRIBUTE_UNUSED PyObject * self, PyObject * args)
1885d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard{
1886d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard    PyObject *resultobj, *obj;
1887d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard    xmlNodePtr cur;
1888d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard    xmlDocPtr res;
1889d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard
1890d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard    if (!PyArg_ParseTuple(args, (char *) "O:doc", &obj))
1891d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard        return NULL;
1892d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard    cur = PyxmlNode_Get(obj);
1893d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard
1894d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard#ifdef DEBUG
1895d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard    printf("libxml_doc: cur = %p\n", cur);
1896d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard#endif
1897d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard
1898d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard    switch (cur->type) {
1899d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        case XML_DOCUMENT_NODE:
1900d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard#ifdef LIBXML_DOCB_ENABLED
1901d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        case XML_DOCB_DOCUMENT_NODE:
1902d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard#endif
1903d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        case XML_HTML_DOCUMENT_NODE:
1904d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            res = NULL;
1905d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            break;
1906d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        case XML_ATTRIBUTE_NODE:{
1907d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard                xmlAttrPtr attr = (xmlAttrPtr) cur;
1908d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard
1909d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard                res = attr->doc;
1910d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard                break;
1911d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            }
1912d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        case XML_NAMESPACE_DECL:
1913d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            res = NULL;
1914d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            break;
1915d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        default:
1916d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            res = cur->doc;
1917d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            break;
1918d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard    }
1919d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard    resultobj = libxml_xmlDocPtrWrap(res);
1920d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard    return resultobj;
1921d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard}
1922d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard
1923d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillardstatic PyObject *
1924d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillardlibxml_properties(ATTRIBUTE_UNUSED PyObject * self, PyObject * args)
1925d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard{
1926d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard    PyObject *resultobj, *obj;
1927d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard    xmlNodePtr cur = NULL;
1928d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard    xmlAttrPtr res;
1929d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard
1930d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard    if (!PyArg_ParseTuple(args, (char *) "O:properties", &obj))
1931d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard        return NULL;
1932d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard    cur = PyxmlNode_Get(obj);
1933d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard    if (cur->type == XML_ELEMENT_NODE)
1934d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        res = cur->properties;
1935d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard    else
1936d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        res = NULL;
1937d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard    resultobj = libxml_xmlAttrPtrWrap(res);
1938d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard    return resultobj;
1939d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard}
1940d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard
1941d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillardstatic PyObject *
1942d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillardlibxml_next(ATTRIBUTE_UNUSED PyObject * self, PyObject * args)
1943d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard{
1944d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard    PyObject *resultobj, *obj;
1945d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard    xmlNodePtr cur;
1946d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard    xmlNodePtr res;
1947d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard
1948d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard    if (!PyArg_ParseTuple(args, (char *) "O:next", &obj))
1949d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard        return NULL;
1950d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard    cur = PyxmlNode_Get(obj);
1951d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard
1952d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard#ifdef DEBUG
1953d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard    printf("libxml_next: cur = %p\n", cur);
1954d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard#endif
1955d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard
1956d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard    switch (cur->type) {
1957d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        case XML_DOCUMENT_NODE:
1958d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard#ifdef LIBXML_DOCB_ENABLED
1959d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        case XML_DOCB_DOCUMENT_NODE:
1960d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard#endif
1961d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        case XML_HTML_DOCUMENT_NODE:
1962d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            res = NULL;
1963d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            break;
1964d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        case XML_ATTRIBUTE_NODE:{
1965d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard                xmlAttrPtr attr = (xmlAttrPtr) cur;
1966d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard
1967d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard                res = (xmlNodePtr) attr->next;
1968d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard                break;
1969d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            }
1970d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        case XML_NAMESPACE_DECL:{
1971d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard                xmlNsPtr ns = (xmlNsPtr) cur;
1972d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard
1973d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard                res = (xmlNodePtr) ns->next;
1974d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard                break;
1975d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            }
1976d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        default:
1977d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            res = cur->next;
1978d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            break;
1979d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard
1980d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard    }
1981d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard    resultobj = libxml_xmlNodePtrWrap(res);
1982d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard    return resultobj;
1983d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard}
1984d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard
1985d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillardstatic PyObject *
1986d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillardlibxml_prev(ATTRIBUTE_UNUSED PyObject * self, PyObject * args)
1987d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard{
1988d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard    PyObject *resultobj, *obj;
1989d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard    xmlNodePtr cur;
1990d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard    xmlNodePtr res;
1991d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard
1992d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard    if (!PyArg_ParseTuple(args, (char *) "O:prev", &obj))
1993d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard        return NULL;
1994d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard    cur = PyxmlNode_Get(obj);
1995d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard
1996d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard#ifdef DEBUG
1997d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard    printf("libxml_prev: cur = %p\n", cur);
1998d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard#endif
1999d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard
2000d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard    switch (cur->type) {
2001d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        case XML_DOCUMENT_NODE:
2002d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard#ifdef LIBXML_DOCB_ENABLED
2003d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        case XML_DOCB_DOCUMENT_NODE:
2004d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard#endif
2005d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        case XML_HTML_DOCUMENT_NODE:
2006d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            res = NULL;
2007d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            break;
2008d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        case XML_ATTRIBUTE_NODE:{
2009d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard                xmlAttrPtr attr = (xmlAttrPtr) cur;
2010d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard
2011faa35ff3cdcf15154dd207606a31b34923da9be9Daniel Veillard                res = (xmlNodePtr) attr->prev;
2012d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            }
2013d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        case XML_NAMESPACE_DECL:
2014d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            res = NULL;
2015d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            break;
2016d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        default:
2017faa35ff3cdcf15154dd207606a31b34923da9be9Daniel Veillard            res = cur->prev;
2018d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            break;
2019d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard    }
2020d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard    resultobj = libxml_xmlNodePtrWrap(res);
2021d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard    return resultobj;
2022d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard}
2023d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard
2024d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillardstatic PyObject *
2025d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillardlibxml_children(ATTRIBUTE_UNUSED PyObject * self, PyObject * args)
2026d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard{
2027d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard    PyObject *resultobj, *obj;
2028d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard    xmlNodePtr cur;
2029d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard    xmlNodePtr res;
2030d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard
2031d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard    if (!PyArg_ParseTuple(args, (char *) "O:children", &obj))
2032d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard        return NULL;
2033d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard    cur = PyxmlNode_Get(obj);
2034d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard
2035d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard#ifdef DEBUG
2036d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard    printf("libxml_children: cur = %p\n", cur);
2037d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard#endif
2038d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard
2039d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard    switch (cur->type) {
2040d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        case XML_ELEMENT_NODE:
2041d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        case XML_ENTITY_REF_NODE:
2042d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        case XML_ENTITY_NODE:
2043d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        case XML_PI_NODE:
2044d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        case XML_COMMENT_NODE:
2045d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        case XML_DOCUMENT_NODE:
2046d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard#ifdef LIBXML_DOCB_ENABLED
2047d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        case XML_DOCB_DOCUMENT_NODE:
2048d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard#endif
2049d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        case XML_HTML_DOCUMENT_NODE:
2050d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        case XML_DTD_NODE:
2051d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            res = cur->children;
2052d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            break;
2053d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        case XML_ATTRIBUTE_NODE:{
2054d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard                xmlAttrPtr attr = (xmlAttrPtr) cur;
2055d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard
2056d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard                res = attr->children;
2057d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard                break;
2058d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            }
2059d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        default:
2060d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            res = NULL;
2061d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            break;
2062d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard    }
2063d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard    resultobj = libxml_xmlNodePtrWrap(res);
2064d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard    return resultobj;
2065d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard}
2066d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard
2067d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillardstatic PyObject *
2068d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillardlibxml_last(ATTRIBUTE_UNUSED PyObject * self, PyObject * args)
2069d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard{
2070d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard    PyObject *resultobj, *obj;
2071d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard    xmlNodePtr cur;
2072d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard    xmlNodePtr res;
2073d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard
2074d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard    if (!PyArg_ParseTuple(args, (char *) "O:last", &obj))
2075d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard        return NULL;
2076d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard    cur = PyxmlNode_Get(obj);
2077d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard
2078d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard#ifdef DEBUG
2079d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard    printf("libxml_last: cur = %p\n", cur);
2080d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard#endif
2081d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard
2082d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard    switch (cur->type) {
2083d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        case XML_ELEMENT_NODE:
2084d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        case XML_ENTITY_REF_NODE:
2085d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        case XML_ENTITY_NODE:
2086d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        case XML_PI_NODE:
2087d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        case XML_COMMENT_NODE:
2088d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        case XML_DOCUMENT_NODE:
2089d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard#ifdef LIBXML_DOCB_ENABLED
2090d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        case XML_DOCB_DOCUMENT_NODE:
2091d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard#endif
2092d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        case XML_HTML_DOCUMENT_NODE:
2093d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        case XML_DTD_NODE:
2094d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            res = cur->last;
2095d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            break;
2096d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        case XML_ATTRIBUTE_NODE:{
2097d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard                xmlAttrPtr attr = (xmlAttrPtr) cur;
2098d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard
2099d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard                res = attr->last;
2100d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            }
2101d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        default:
2102d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            res = NULL;
2103d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            break;
2104d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard    }
2105d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard    resultobj = libxml_xmlNodePtrWrap(res);
2106d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard    return resultobj;
2107d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard}
2108d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard
2109d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillardstatic PyObject *
2110d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillardlibxml_parent(ATTRIBUTE_UNUSED PyObject * self, PyObject * args)
2111d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard{
2112d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard    PyObject *resultobj, *obj;
2113d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard    xmlNodePtr cur;
2114d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard    xmlNodePtr res;
2115d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard
2116d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard    if (!PyArg_ParseTuple(args, (char *) "O:parent", &obj))
2117d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard        return NULL;
2118d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard    cur = PyxmlNode_Get(obj);
2119d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard
2120d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard#ifdef DEBUG
2121d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard    printf("libxml_parent: cur = %p\n", cur);
2122d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard#endif
2123d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard
2124d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard    switch (cur->type) {
2125d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        case XML_DOCUMENT_NODE:
2126d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        case XML_HTML_DOCUMENT_NODE:
2127d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard#ifdef LIBXML_DOCB_ENABLED
2128d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        case XML_DOCB_DOCUMENT_NODE:
2129d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard#endif
2130d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            res = NULL;
2131d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            break;
2132d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        case XML_ATTRIBUTE_NODE:{
2133d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard                xmlAttrPtr attr = (xmlAttrPtr) cur;
2134d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard
2135d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard                res = attr->parent;
2136d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            }
2137d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        case XML_ENTITY_DECL:
2138d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        case XML_NAMESPACE_DECL:
2139d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        case XML_XINCLUDE_START:
2140d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        case XML_XINCLUDE_END:
2141d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            res = NULL;
2142d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            break;
2143d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        default:
2144d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            res = cur->parent;
2145d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            break;
2146d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard    }
2147d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard    resultobj = libxml_xmlNodePtrWrap(res);
2148d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard    return resultobj;
2149d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard}
2150d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard
2151d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillardstatic PyObject *
2152d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillardlibxml_type(ATTRIBUTE_UNUSED PyObject * self, PyObject * args)
2153d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard{
2154d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard    PyObject *resultobj, *obj;
2155d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard    xmlNodePtr cur;
2156d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard    const xmlChar *res = NULL;
2157d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard
2158d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard    if (!PyArg_ParseTuple(args, (char *) "O:last", &obj))
2159d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard        return NULL;
2160d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard    cur = PyxmlNode_Get(obj);
2161d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard
2162d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard#ifdef DEBUG
2163d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard    printf("libxml_type: cur = %p\n", cur);
2164d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard#endif
2165d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard
2166d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard    switch (cur->type) {
2167d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard        case XML_ELEMENT_NODE:
2168d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            res = (const xmlChar *) "element";
2169d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            break;
2170d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard        case XML_ATTRIBUTE_NODE:
2171d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            res = (const xmlChar *) "attribute";
2172d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            break;
2173d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard        case XML_TEXT_NODE:
2174d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            res = (const xmlChar *) "text";
2175d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            break;
2176d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard        case XML_CDATA_SECTION_NODE:
2177d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            res = (const xmlChar *) "cdata";
2178d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            break;
2179d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard        case XML_ENTITY_REF_NODE:
2180d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            res = (const xmlChar *) "entity_ref";
2181d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            break;
2182d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard        case XML_ENTITY_NODE:
2183d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            res = (const xmlChar *) "entity";
2184d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            break;
2185d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard        case XML_PI_NODE:
2186d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            res = (const xmlChar *) "pi";
2187d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            break;
2188d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard        case XML_COMMENT_NODE:
2189d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            res = (const xmlChar *) "comment";
2190d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            break;
2191d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard        case XML_DOCUMENT_NODE:
2192d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            res = (const xmlChar *) "document_xml";
2193d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            break;
2194d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard        case XML_DOCUMENT_TYPE_NODE:
2195d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            res = (const xmlChar *) "doctype";
2196d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            break;
2197d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard        case XML_DOCUMENT_FRAG_NODE:
2198d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            res = (const xmlChar *) "fragment";
2199d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            break;
2200d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard        case XML_NOTATION_NODE:
2201d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            res = (const xmlChar *) "notation";
2202d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            break;
2203d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard        case XML_HTML_DOCUMENT_NODE:
2204d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            res = (const xmlChar *) "document_html";
2205d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            break;
2206d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard        case XML_DTD_NODE:
2207d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            res = (const xmlChar *) "dtd";
2208d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            break;
2209d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard        case XML_ELEMENT_DECL:
2210d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            res = (const xmlChar *) "elem_decl";
2211d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            break;
2212d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard        case XML_ATTRIBUTE_DECL:
2213d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            res = (const xmlChar *) "attribute_decl";
2214d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            break;
2215d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard        case XML_ENTITY_DECL:
2216d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            res = (const xmlChar *) "entity_decl";
2217d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            break;
2218d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard        case XML_NAMESPACE_DECL:
2219d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            res = (const xmlChar *) "namespace";
2220d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            break;
2221d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard        case XML_XINCLUDE_START:
2222d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            res = (const xmlChar *) "xinclude_start";
2223d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            break;
2224d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard        case XML_XINCLUDE_END:
2225d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            res = (const xmlChar *) "xinclude_end";
2226d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            break;
2227d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard#ifdef LIBXML_DOCB_ENABLED
2228d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        case XML_DOCB_DOCUMENT_NODE:
2229d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            res = (const xmlChar *) "document_docbook";
2230d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            break;
2231d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard#endif
2232d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard    }
2233d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard#ifdef DEBUG
2234d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard    printf("libxml_type: cur = %p: %s\n", cur, res);
2235d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard#endif
2236d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard
22371971ee2698cb84c7699c96d3302f00e20d42c0d3Daniel Veillard    resultobj = libxml_constxmlCharPtrWrap(res);
2238d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard    return resultobj;
2239d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard}
2240d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard
2241d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard/************************************************************************
2242d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard *									*
224336eea2d2ee84132e66552f84724e9b377d687681Daniel Veillard *			Specific accessor functions			*
224436eea2d2ee84132e66552f84724e9b377d687681Daniel Veillard *									*
224536eea2d2ee84132e66552f84724e9b377d687681Daniel Veillard ************************************************************************/
224636eea2d2ee84132e66552f84724e9b377d687681Daniel VeillardPyObject *
2247d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillardlibxml_xmlNodeGetNsDefs(ATTRIBUTE_UNUSED PyObject * self, PyObject * args)
2248d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard{
224936eea2d2ee84132e66552f84724e9b377d687681Daniel Veillard    PyObject *py_retval;
225036eea2d2ee84132e66552f84724e9b377d687681Daniel Veillard    xmlNsPtr c_retval;
225136eea2d2ee84132e66552f84724e9b377d687681Daniel Veillard    xmlNodePtr node;
225236eea2d2ee84132e66552f84724e9b377d687681Daniel Veillard    PyObject *pyobj_node;
225336eea2d2ee84132e66552f84724e9b377d687681Daniel Veillard
2254d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard    if (!PyArg_ParseTuple
2255d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        (args, (char *) "O:xmlNodeGetNsDefs", &pyobj_node))
2256d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        return (NULL);
225736eea2d2ee84132e66552f84724e9b377d687681Daniel Veillard    node = (xmlNodePtr) PyxmlNode_Get(pyobj_node);
225836eea2d2ee84132e66552f84724e9b377d687681Daniel Veillard
225936eea2d2ee84132e66552f84724e9b377d687681Daniel Veillard    if ((node == NULL) || (node->type != XML_ELEMENT_NODE)) {
2260d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        Py_INCREF(Py_None);
2261d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        return (Py_None);
226236eea2d2ee84132e66552f84724e9b377d687681Daniel Veillard    }
226336eea2d2ee84132e66552f84724e9b377d687681Daniel Veillard    c_retval = node->nsDef;
226436eea2d2ee84132e66552f84724e9b377d687681Daniel Veillard    py_retval = libxml_xmlNsPtrWrap((xmlNsPtr) c_retval);
2265d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard    return (py_retval);
226636eea2d2ee84132e66552f84724e9b377d687681Daniel Veillard}
226736eea2d2ee84132e66552f84724e9b377d687681Daniel Veillard
226836eea2d2ee84132e66552f84724e9b377d687681Daniel VeillardPyObject *
2269d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillardlibxml_xmlNodeGetNs(ATTRIBUTE_UNUSED PyObject * self, PyObject * args)
2270d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard{
227136eea2d2ee84132e66552f84724e9b377d687681Daniel Veillard    PyObject *py_retval;
227236eea2d2ee84132e66552f84724e9b377d687681Daniel Veillard    xmlNsPtr c_retval;
227336eea2d2ee84132e66552f84724e9b377d687681Daniel Veillard    xmlNodePtr node;
227436eea2d2ee84132e66552f84724e9b377d687681Daniel Veillard    PyObject *pyobj_node;
227536eea2d2ee84132e66552f84724e9b377d687681Daniel Veillard
2276d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard    if (!PyArg_ParseTuple(args, (char *) "O:xmlNodeGetNs", &pyobj_node))
2277d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        return (NULL);
227836eea2d2ee84132e66552f84724e9b377d687681Daniel Veillard    node = (xmlNodePtr) PyxmlNode_Get(pyobj_node);
227936eea2d2ee84132e66552f84724e9b377d687681Daniel Veillard
228036eea2d2ee84132e66552f84724e9b377d687681Daniel Veillard    if ((node == NULL) || (node->type != XML_ELEMENT_NODE)) {
2281d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        Py_INCREF(Py_None);
2282d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        return (Py_None);
228336eea2d2ee84132e66552f84724e9b377d687681Daniel Veillard    }
228436eea2d2ee84132e66552f84724e9b377d687681Daniel Veillard    c_retval = node->ns;
228536eea2d2ee84132e66552f84724e9b377d687681Daniel Veillard    py_retval = libxml_xmlNsPtrWrap((xmlNsPtr) c_retval);
2286d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard    return (py_retval);
228736eea2d2ee84132e66552f84724e9b377d687681Daniel Veillard}
228836eea2d2ee84132e66552f84724e9b377d687681Daniel Veillard
228936eea2d2ee84132e66552f84724e9b377d687681Daniel Veillard/************************************************************************
229036eea2d2ee84132e66552f84724e9b377d687681Daniel Veillard *									*
22911e77438da7dd912885effa97b1079867d1e041beDaniel Veillard *			Serialization front-end				*
22921e77438da7dd912885effa97b1079867d1e041beDaniel Veillard *									*
22931e77438da7dd912885effa97b1079867d1e041beDaniel Veillard ************************************************************************/
22941e77438da7dd912885effa97b1079867d1e041beDaniel Veillard
2295d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillardstatic PyObject *
2296d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillardlibxml_serializeNode(ATTRIBUTE_UNUSED PyObject * self, PyObject * args)
2297d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard{
22981e77438da7dd912885effa97b1079867d1e041beDaniel Veillard    PyObject *py_retval = NULL;
22991e77438da7dd912885effa97b1079867d1e041beDaniel Veillard    xmlChar *c_retval;
23001e77438da7dd912885effa97b1079867d1e041beDaniel Veillard    PyObject *pyobj_node;
23011e77438da7dd912885effa97b1079867d1e041beDaniel Veillard    xmlNodePtr node;
23021e77438da7dd912885effa97b1079867d1e041beDaniel Veillard    xmlDocPtr doc;
2303d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard    const char *encoding;
23041e77438da7dd912885effa97b1079867d1e041beDaniel Veillard    int format;
23051e77438da7dd912885effa97b1079867d1e041beDaniel Veillard    int len;
23061e77438da7dd912885effa97b1079867d1e041beDaniel Veillard
2307d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard    if (!PyArg_ParseTuple(args, (char *) "Ozi:serializeNode", &pyobj_node,
2308d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard                          &encoding, &format))
2309d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        return (NULL);
23101e77438da7dd912885effa97b1079867d1e041beDaniel Veillard    node = (xmlNodePtr) PyxmlNode_Get(pyobj_node);
23111e77438da7dd912885effa97b1079867d1e041beDaniel Veillard
23121e77438da7dd912885effa97b1079867d1e041beDaniel Veillard    if (node == NULL) {
2313d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        Py_INCREF(Py_None);
2314d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        return (Py_None);
23151e77438da7dd912885effa97b1079867d1e041beDaniel Veillard    }
23161e77438da7dd912885effa97b1079867d1e041beDaniel Veillard    if (node->type == XML_DOCUMENT_NODE) {
2317d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        doc = (xmlDocPtr) node;
2318d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        xmlDocDumpFormatMemoryEnc(doc, &c_retval, &len,
2319d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard                                  (const char *) encoding, format);
2320d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        py_retval = libxml_charPtrWrap((char *) c_retval);
23211e77438da7dd912885effa97b1079867d1e041beDaniel Veillard    } else if (node->type == XML_HTML_DOCUMENT_NODE) {
2322d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        xmlOutputBufferPtr buf;
2323d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        xmlCharEncodingHandlerPtr handler = NULL;
2324d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard
2325d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        doc = (xmlDocPtr) node;
2326d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        if (encoding != NULL)
2327d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            htmlSetMetaEncoding(doc, (const xmlChar *) encoding);
2328d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        encoding = (const char *) htmlGetMetaEncoding(doc);
2329d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard
2330d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        if (encoding != NULL) {
2331d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            handler = xmlFindCharEncodingHandler(encoding);
2332d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            if (handler == NULL) {
2333d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard                Py_INCREF(Py_None);
2334d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard                return (Py_None);
2335d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            }
2336d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        }
2337d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard
2338d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        /*
2339d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard         * Fallback to HTML or ASCII when the encoding is unspecified
2340d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard         */
2341d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        if (handler == NULL)
2342d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            handler = xmlFindCharEncodingHandler("HTML");
2343d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        if (handler == NULL)
2344d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            handler = xmlFindCharEncodingHandler("ascii");
2345d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard
2346d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        buf = xmlAllocOutputBuffer(handler);
2347d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        if (buf == NULL) {
2348d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            Py_INCREF(Py_None);
2349d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            return (Py_None);
2350d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        }
2351d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        htmlDocContentDumpFormatOutput(buf, doc, encoding, format);
2352d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        xmlOutputBufferFlush(buf);
2353d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        if (buf->conv != NULL) {
2354d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            len = buf->conv->use;
2355d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            c_retval = buf->conv->content;
2356d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            buf->conv->content = NULL;
2357d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        } else {
2358d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            len = buf->buffer->use;
2359d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            c_retval = buf->buffer->content;
2360d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            buf->buffer->content = NULL;
2361d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        }
2362d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        (void) xmlOutputBufferClose(buf);
2363d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        py_retval = libxml_charPtrWrap((char *) c_retval);
23641e77438da7dd912885effa97b1079867d1e041beDaniel Veillard    } else {
2365d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        doc = node->doc;
2366a8c0adbc395e48f0a65ccbd6c4931525380cf55cDaniel Veillard        if ((doc == NULL) || (doc->type == XML_DOCUMENT_NODE)) {
2367d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            xmlOutputBufferPtr buf;
2368d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            xmlCharEncodingHandlerPtr handler = NULL;
2369d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard
2370d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            if (encoding != NULL) {
2371d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard                handler = xmlFindCharEncodingHandler(encoding);
2372d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard                if (handler == NULL) {
2373d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard                    Py_INCREF(Py_None);
2374d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard                    return (Py_None);
2375d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard                }
2376d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            }
2377d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard
2378d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            buf = xmlAllocOutputBuffer(handler);
2379d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            if (buf == NULL) {
2380d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard                Py_INCREF(Py_None);
2381d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard                return (Py_None);
2382d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            }
2383d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            xmlNodeDumpOutput(buf, doc, node, 0, format, encoding);
2384d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            xmlOutputBufferFlush(buf);
2385d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            if (buf->conv != NULL) {
2386d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard                len = buf->conv->use;
2387d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard                c_retval = buf->conv->content;
2388d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard                buf->conv->content = NULL;
2389d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            } else {
2390d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard                len = buf->buffer->use;
2391d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard                c_retval = buf->buffer->content;
2392d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard                buf->buffer->content = NULL;
2393d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            }
2394d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            (void) xmlOutputBufferClose(buf);
2395d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            py_retval = libxml_charPtrWrap((char *) c_retval);
2396d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        } else if (doc->type == XML_HTML_DOCUMENT_NODE) {
2397d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            xmlOutputBufferPtr buf;
2398d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            xmlCharEncodingHandlerPtr handler = NULL;
2399d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard
2400d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            if (encoding != NULL)
2401d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard                htmlSetMetaEncoding(doc, (const xmlChar *) encoding);
2402d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            encoding = (const char *) htmlGetMetaEncoding(doc);
2403d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            if (encoding != NULL) {
2404d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard                handler = xmlFindCharEncodingHandler(encoding);
2405d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard                if (handler == NULL) {
2406d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard                    Py_INCREF(Py_None);
2407d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard                    return (Py_None);
2408d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard                }
2409d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            }
2410d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard
2411d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            /*
2412d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard             * Fallback to HTML or ASCII when the encoding is unspecified
2413d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard             */
2414d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            if (handler == NULL)
2415d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard                handler = xmlFindCharEncodingHandler("HTML");
2416d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            if (handler == NULL)
2417d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard                handler = xmlFindCharEncodingHandler("ascii");
2418d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard
2419d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            buf = xmlAllocOutputBuffer(handler);
2420d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            if (buf == NULL) {
2421d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard                Py_INCREF(Py_None);
2422d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard                return (Py_None);
2423d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            }
2424d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            htmlNodeDumpFormatOutput(buf, doc, node, encoding, format);
2425d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            xmlOutputBufferFlush(buf);
2426d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            if (buf->conv != NULL) {
2427d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard                len = buf->conv->use;
2428d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard                c_retval = buf->conv->content;
2429d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard                buf->conv->content = NULL;
2430d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            } else {
2431d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard                len = buf->buffer->use;
2432d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard                c_retval = buf->buffer->content;
2433d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard                buf->buffer->content = NULL;
2434d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            }
2435d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            (void) xmlOutputBufferClose(buf);
2436d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            py_retval = libxml_charPtrWrap((char *) c_retval);
2437d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        } else {
2438d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            Py_INCREF(Py_None);
2439d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            return (Py_None);
2440d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        }
24411e77438da7dd912885effa97b1079867d1e041beDaniel Veillard    }
2442d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard    return (py_retval);
24431e77438da7dd912885effa97b1079867d1e041beDaniel Veillard}
24441e77438da7dd912885effa97b1079867d1e041beDaniel Veillard
2445d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillardstatic PyObject *
2446d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillardlibxml_saveNodeTo(ATTRIBUTE_UNUSED PyObject * self, PyObject * args)
2447d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard{
24481e77438da7dd912885effa97b1079867d1e041beDaniel Veillard    PyObject *py_file = NULL;
24491e77438da7dd912885effa97b1079867d1e041beDaniel Veillard    FILE *output;
24501e77438da7dd912885effa97b1079867d1e041beDaniel Veillard    PyObject *pyobj_node;
24511e77438da7dd912885effa97b1079867d1e041beDaniel Veillard    xmlNodePtr node;
24521e77438da7dd912885effa97b1079867d1e041beDaniel Veillard    xmlDocPtr doc;
2453d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard    const char *encoding;
24541e77438da7dd912885effa97b1079867d1e041beDaniel Veillard    int format;
24551e77438da7dd912885effa97b1079867d1e041beDaniel Veillard    int len;
24561e77438da7dd912885effa97b1079867d1e041beDaniel Veillard    xmlOutputBufferPtr buf;
24571e77438da7dd912885effa97b1079867d1e041beDaniel Veillard    xmlCharEncodingHandlerPtr handler = NULL;
24581e77438da7dd912885effa97b1079867d1e041beDaniel Veillard
2459d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard    if (!PyArg_ParseTuple(args, (char *) "OOzi:serializeNode", &pyobj_node,
2460d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard                          &py_file, &encoding, &format))
2461d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        return (NULL);
24621e77438da7dd912885effa97b1079867d1e041beDaniel Veillard    node = (xmlNodePtr) PyxmlNode_Get(pyobj_node);
24631e77438da7dd912885effa97b1079867d1e041beDaniel Veillard
24641e77438da7dd912885effa97b1079867d1e041beDaniel Veillard    if (node == NULL) {
2465d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        return (PyInt_FromLong((long) -1));
24661e77438da7dd912885effa97b1079867d1e041beDaniel Veillard    }
24671e77438da7dd912885effa97b1079867d1e041beDaniel Veillard    if ((py_file == NULL) || (!(PyFile_Check(py_file)))) {
2468d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        return (PyInt_FromLong((long) -1));
24691e77438da7dd912885effa97b1079867d1e041beDaniel Veillard    }
24701e77438da7dd912885effa97b1079867d1e041beDaniel Veillard    output = PyFile_AsFile(py_file);
24711e77438da7dd912885effa97b1079867d1e041beDaniel Veillard    if (output == NULL) {
2472d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        return (PyInt_FromLong((long) -1));
24731e77438da7dd912885effa97b1079867d1e041beDaniel Veillard    }
24741e77438da7dd912885effa97b1079867d1e041beDaniel Veillard
24751e77438da7dd912885effa97b1079867d1e041beDaniel Veillard    if (node->type == XML_DOCUMENT_NODE) {
2476d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        doc = (xmlDocPtr) node;
24771e77438da7dd912885effa97b1079867d1e041beDaniel Veillard    } else if (node->type == XML_HTML_DOCUMENT_NODE) {
2478d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        doc = (xmlDocPtr) node;
24791e77438da7dd912885effa97b1079867d1e041beDaniel Veillard    } else {
2480d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        doc = node->doc;
24811e77438da7dd912885effa97b1079867d1e041beDaniel Veillard    }
24821e77438da7dd912885effa97b1079867d1e041beDaniel Veillard    if (doc->type == XML_HTML_DOCUMENT_NODE) {
2483d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        if (encoding == NULL)
2484d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            encoding = (const char *) htmlGetMetaEncoding(doc);
24851e77438da7dd912885effa97b1079867d1e041beDaniel Veillard    }
24861e77438da7dd912885effa97b1079867d1e041beDaniel Veillard    if (encoding != NULL) {
2487d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        handler = xmlFindCharEncodingHandler(encoding);
2488d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        if (handler == NULL) {
2489d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            return (PyInt_FromLong((long) -1));
2490d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        }
24911e77438da7dd912885effa97b1079867d1e041beDaniel Veillard    }
24921e77438da7dd912885effa97b1079867d1e041beDaniel Veillard    if (doc->type == XML_HTML_DOCUMENT_NODE) {
2493d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        if (handler == NULL)
2494d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            handler = xmlFindCharEncodingHandler("HTML");
2495d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        if (handler == NULL)
2496d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            handler = xmlFindCharEncodingHandler("ascii");
24971e77438da7dd912885effa97b1079867d1e041beDaniel Veillard    }
24981e77438da7dd912885effa97b1079867d1e041beDaniel Veillard
24991e77438da7dd912885effa97b1079867d1e041beDaniel Veillard    buf = xmlOutputBufferCreateFile(output, handler);
25001e77438da7dd912885effa97b1079867d1e041beDaniel Veillard    if (node->type == XML_DOCUMENT_NODE) {
2501d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        len = xmlSaveFormatFileTo(buf, doc, encoding, format);
25021e77438da7dd912885effa97b1079867d1e041beDaniel Veillard    } else if (node->type == XML_HTML_DOCUMENT_NODE) {
2503d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        htmlDocContentDumpFormatOutput(buf, doc, encoding, format);
2504d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        len = xmlOutputBufferClose(buf);
25051e77438da7dd912885effa97b1079867d1e041beDaniel Veillard    } else if (doc->type == XML_HTML_DOCUMENT_NODE) {
2506d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        htmlNodeDumpFormatOutput(buf, doc, node, encoding, format);
2507d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        len = xmlOutputBufferClose(buf);
25081e77438da7dd912885effa97b1079867d1e041beDaniel Veillard    } else {
2509d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        xmlNodeDumpOutput(buf, doc, node, 0, format, encoding);
2510d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        len = xmlOutputBufferClose(buf);
25111e77438da7dd912885effa97b1079867d1e041beDaniel Veillard    }
2512d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard    return (PyInt_FromLong((long) len));
25131e77438da7dd912885effa97b1079867d1e041beDaniel Veillard}
25141e77438da7dd912885effa97b1079867d1e041beDaniel Veillard
25151e77438da7dd912885effa97b1079867d1e041beDaniel Veillard/************************************************************************
25161e77438da7dd912885effa97b1079867d1e041beDaniel Veillard *									*
2517a94ec6ff13d9617ff22e790cef82208e7d1bd375Daniel Veillard *			Extra stuff					*
2518a94ec6ff13d9617ff22e790cef82208e7d1bd375Daniel Veillard *									*
2519a94ec6ff13d9617ff22e790cef82208e7d1bd375Daniel Veillard ************************************************************************/
2520a94ec6ff13d9617ff22e790cef82208e7d1bd375Daniel VeillardPyObject *
2521d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillardlibxml_xmlNewNode(ATTRIBUTE_UNUSED PyObject * self, PyObject * args)
2522d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard{
2523a94ec6ff13d9617ff22e790cef82208e7d1bd375Daniel Veillard    PyObject *py_retval;
2524d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard    xmlChar *name;
2525a94ec6ff13d9617ff22e790cef82208e7d1bd375Daniel Veillard    xmlNodePtr node;
2526a94ec6ff13d9617ff22e790cef82208e7d1bd375Daniel Veillard
2527d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard    if (!PyArg_ParseTuple(args, (char *) "s:xmlNewNode", &name))
2528d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        return (NULL);
2529a94ec6ff13d9617ff22e790cef82208e7d1bd375Daniel Veillard    node = (xmlNodePtr) xmlNewNode(NULL, name);
2530d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard    printf("NewNode: %s : %p\n", name, (void *) node);
2531a94ec6ff13d9617ff22e790cef82208e7d1bd375Daniel Veillard
2532a94ec6ff13d9617ff22e790cef82208e7d1bd375Daniel Veillard    if (node == NULL) {
2533d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        Py_INCREF(Py_None);
2534d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        return (Py_None);
2535a94ec6ff13d9617ff22e790cef82208e7d1bd375Daniel Veillard    }
2536a94ec6ff13d9617ff22e790cef82208e7d1bd375Daniel Veillard    py_retval = libxml_xmlNodePtrWrap(node);
2537d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard    return (py_retval);
2538a94ec6ff13d9617ff22e790cef82208e7d1bd375Daniel Veillard}
2539a94ec6ff13d9617ff22e790cef82208e7d1bd375Daniel Veillard
2540a94ec6ff13d9617ff22e790cef82208e7d1bd375Daniel Veillard/************************************************************************
2541a94ec6ff13d9617ff22e790cef82208e7d1bd375Daniel Veillard *									*
2542d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard *			The registration stuff				*
2543d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard *									*
2544d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard ************************************************************************/
2545d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillardstatic PyMethodDef libxmlMethods[] = {
254696fe095d4bf3c76301ed58ebe1ba10f8004f87efDaniel Veillard#include "libxml2-export.c"
2547d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard    {(char *) "name", libxml_name, METH_VARARGS, NULL},
2548d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard    {(char *) "children", libxml_children, METH_VARARGS, NULL},
2549d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard    {(char *) "properties", libxml_properties, METH_VARARGS, NULL},
2550d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard    {(char *) "last", libxml_last, METH_VARARGS, NULL},
2551d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard    {(char *) "prev", libxml_prev, METH_VARARGS, NULL},
2552d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard    {(char *) "next", libxml_next, METH_VARARGS, NULL},
2553d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard    {(char *) "parent", libxml_parent, METH_VARARGS, NULL},
2554d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard    {(char *) "type", libxml_type, METH_VARARGS, NULL},
2555d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard    {(char *) "doc", libxml_doc, METH_VARARGS, NULL},
2556d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard    {(char *) "xmlNewNode", libxml_xmlNewNode, METH_VARARGS, NULL},
2557d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard    {(char *) "serializeNode", libxml_serializeNode, METH_VARARGS, NULL},
2558d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard    {(char *) "saveNodeTo", libxml_saveNodeTo, METH_VARARGS, NULL},
2559c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard    {(char *) "outputBufferCreate", libxml_xmlCreateOutputBuffer, METH_VARARGS, NULL},
2560c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard    {(char *) "inputBufferCreate", libxml_xmlCreateInputBuffer, METH_VARARGS, NULL},
2561c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard    {(char *) "setEntityLoader", libxml_xmlSetEntityLoader, METH_VARARGS, NULL},
25623e20a2921373677d1cf54fcf6081b3492e0c7558Daniel Veillard    {(char *)"xmlRegisterErrorHandler", libxml_xmlRegisterErrorHandler, METH_VARARGS, NULL },
2563417be3ae08346c6510c28d2042dd42a22a74b331Daniel Veillard    {(char *)"xmlParserCtxtSetErrorHandler", libxml_xmlParserCtxtSetErrorHandler, METH_VARARGS, NULL },
2564417be3ae08346c6510c28d2042dd42a22a74b331Daniel Veillard    {(char *)"xmlParserCtxtGetErrorHandler", libxml_xmlParserCtxtGetErrorHandler, METH_VARARGS, NULL },
2565e6227e0549490b5bf9271ecd2d874a97c3f4852bDaniel Veillard    {(char *)"xmlFreeParserCtxt", libxml_xmlFreeParserCtxt, METH_VARARGS, NULL },
256626f70269c80140a7fb8a7aae9ef09c95efa98e70Daniel Veillard    {(char *)"xmlTextReaderSetErrorHandler", libxml_xmlTextReaderSetErrorHandler, METH_VARARGS, NULL },
256726f70269c80140a7fb8a7aae9ef09c95efa98e70Daniel Veillard    {(char *)"xmlTextReaderGetErrorHandler", libxml_xmlTextReaderGetErrorHandler, METH_VARARGS, NULL },
256826f70269c80140a7fb8a7aae9ef09c95efa98e70Daniel Veillard    {(char *)"xmlFreeTextReader", libxml_xmlFreeTextReader, METH_VARARGS, NULL },
2569d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard    {NULL, NULL, 0, NULL}
2570d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard};
2571d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard
25720fea6f45cd6f158418318c0af922533e44f9c0e2Daniel Veillard#ifdef MERGED_MODULES
25736361da0c25e355affdeed84cfccb187ccaadfccbDaniel Veillardextern void initlibxsltmod(void);
25740fea6f45cd6f158418318c0af922533e44f9c0e2Daniel Veillard#endif
25750fea6f45cd6f158418318c0af922533e44f9c0e2Daniel Veillard
2576d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillardvoid
2577d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillardinitlibxml2mod(void)
2578d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard{
2579af43f63aaabf0dc4b4a070773875d0927da3d8a2Daniel Veillard    static int initialized = 0;
25803ce5257b293ed75d8feb18ed7ab18ea2b52510bdDaniel Veillard    PyObject *m;
2581af43f63aaabf0dc4b4a070773875d0927da3d8a2Daniel Veillard
2582af43f63aaabf0dc4b4a070773875d0927da3d8a2Daniel Veillard    if (initialized != 0)
2583d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        return;
2584c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard    xmlRegisterDefaultOutputCallbacks();
2585c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard    xmlRegisterDefaultInputCallbacks();
2586d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard    m = Py_InitModule((char *) "libxml2mod", libxmlMethods);
2587af43f63aaabf0dc4b4a070773875d0927da3d8a2Daniel Veillard    initialized = 1;
25885d81903b06418c7d8cc72cf9add81c4026a2f3bcDaniel Veillard    libxml_xmlErrorInitialize();
25896361da0c25e355affdeed84cfccb187ccaadfccbDaniel Veillard
25900fea6f45cd6f158418318c0af922533e44f9c0e2Daniel Veillard#ifdef MERGED_MODULES
25910fea6f45cd6f158418318c0af922533e44f9c0e2Daniel Veillard    initlibxsltmod();
25920fea6f45cd6f158418318c0af922533e44f9c0e2Daniel Veillard#endif
2593d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard}
2594