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>
25d5e198ad454803c60b898451ff432f2fcf0e95ceDaniel Veillard#include <libxml/c14n.h>
26438ebbd59af78c436397ae488e42aeca5cad7542Daniel Veillard#include <libxml/xmlreader.h>
27da3fee406da96c344d7b5f4e0631faee74f7e11dDaniel Veillard#include <libxml/xmlsave.h>
28d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard#include "libxml_wrap.h"
2996fe095d4bf3c76301ed58ebe1ba10f8004f87efDaniel Veillard#include "libxml2-py.h"
30d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard
31c3b1d09ba226a138722a21cc8e8cc8ee29d80f8dRoumen Petrov#if defined(WITH_TRIO)
32e4fa293265c935365717dc9accf6c6ec23d5f22fDaniel Veillard#include "trio.h"
33e4fa293265c935365717dc9accf6c6ec23d5f22fDaniel Veillard#define vsnprintf trio_vsnprintf
340d132cffc1733447f0fa9624f0265369a7f8c02aDaniel Veillard#endif
350d132cffc1733447f0fa9624f0265369a7f8c02aDaniel Veillard
36d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard/* #define DEBUG */
37797a565a2f6a2c0a8480670174e9eaef30d271a4Daniel Veillard/* #define DEBUG_SAX */
38a7340c830e4bddd86201cfdb97ac81e30b0dee62Daniel Veillard/* #define DEBUG_XPATH */
395d81903b06418c7d8cc72cf9add81c4026a2f3bcDaniel Veillard/* #define DEBUG_ERROR */
404e1b26cfeba7f5fad4f8bd12fb5ce7029f930b79Daniel Veillard/* #define DEBUG_MEMORY */
41c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard/* #define DEBUG_FILES */
42c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard/* #define DEBUG_LOADER */
434e1b26cfeba7f5fad4f8bd12fb5ce7029f930b79Daniel Veillard
443798c4adbb91f80bef1e9f1b4b61dae72577a244Daniel Veillard#if PY_MAJOR_VERSION >= 3
453798c4adbb91f80bef1e9f1b4b61dae72577a244Daniel VeillardPyObject *PyInit_libxml2mod(void);
463798c4adbb91f80bef1e9f1b4b61dae72577a244Daniel Veillard
473798c4adbb91f80bef1e9f1b4b61dae72577a244Daniel Veillard#define PY_IMPORT_STRING_SIZE PyUnicode_FromStringAndSize
483798c4adbb91f80bef1e9f1b4b61dae72577a244Daniel Veillard#define PY_IMPORT_STRING PyUnicode_FromString
493798c4adbb91f80bef1e9f1b4b61dae72577a244Daniel Veillard#else
50d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillardvoid initlibxml2mod(void);
513798c4adbb91f80bef1e9f1b4b61dae72577a244Daniel Veillard#define PY_IMPORT_STRING_SIZE PyString_FromStringAndSize
523798c4adbb91f80bef1e9f1b4b61dae72577a244Daniel Veillard#define PY_IMPORT_STRING PyString_FromString
533798c4adbb91f80bef1e9f1b4b61dae72577a244Daniel Veillard#endif
543798c4adbb91f80bef1e9f1b4b61dae72577a244Daniel Veillard
55d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard
56c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard/**
57c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard * TODO:
58c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard *
59c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard * macro to flag unimplemented blocks
60c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard */
61c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard#define TODO 								\
62c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard    xmlGenericError(xmlGenericErrorContext,				\
63c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard	    "Unimplemented block at %s:%d\n",				\
64c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard            __FILE__, __LINE__);
658e2cc6f2b53f536692f3c8ad8112bb67e0a1a629William M. Brack/*
668e2cc6f2b53f536692f3c8ad8112bb67e0a1a629William M. Brack * the following vars are used for XPath extensions, but
678e2cc6f2b53f536692f3c8ad8112bb67e0a1a629William M. Brack * are also referenced within the parser cleanup routine.
688e2cc6f2b53f536692f3c8ad8112bb67e0a1a629William M. Brack */
698e2cc6f2b53f536692f3c8ad8112bb67e0a1a629William M. Brackstatic int libxml_xpathCallbacksInitialized = 0;
708e2cc6f2b53f536692f3c8ad8112bb67e0a1a629William M. Brack
718e2cc6f2b53f536692f3c8ad8112bb67e0a1a629William M. Bracktypedef struct libxml_xpathCallback {
728e2cc6f2b53f536692f3c8ad8112bb67e0a1a629William M. Brack    xmlXPathContextPtr ctx;
738e2cc6f2b53f536692f3c8ad8112bb67e0a1a629William M. Brack    xmlChar *name;
748e2cc6f2b53f536692f3c8ad8112bb67e0a1a629William M. Brack    xmlChar *ns_uri;
758e2cc6f2b53f536692f3c8ad8112bb67e0a1a629William M. Brack    PyObject *function;
768e2cc6f2b53f536692f3c8ad8112bb67e0a1a629William M. Brack} libxml_xpathCallback, *libxml_xpathCallbackPtr;
778e2cc6f2b53f536692f3c8ad8112bb67e0a1a629William M. Bracktypedef libxml_xpathCallback libxml_xpathCallbackArray[];
788e2cc6f2b53f536692f3c8ad8112bb67e0a1a629William M. Brackstatic int libxml_xpathCallbacksAllocd = 10;
798e2cc6f2b53f536692f3c8ad8112bb67e0a1a629William M. Brackstatic libxml_xpathCallbackArray *libxml_xpathCallbacks = NULL;
808e2cc6f2b53f536692f3c8ad8112bb67e0a1a629William M. Brackstatic int libxml_xpathCallbacksNb = 0;
81c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard
824e1b26cfeba7f5fad4f8bd12fb5ce7029f930b79Daniel Veillard/************************************************************************
834e1b26cfeba7f5fad4f8bd12fb5ce7029f930b79Daniel Veillard *									*
844e1b26cfeba7f5fad4f8bd12fb5ce7029f930b79Daniel Veillard *		Memory debug interface					*
854e1b26cfeba7f5fad4f8bd12fb5ce7029f930b79Daniel Veillard *									*
864e1b26cfeba7f5fad4f8bd12fb5ce7029f930b79Daniel Veillard ************************************************************************/
874e1b26cfeba7f5fad4f8bd12fb5ce7029f930b79Daniel Veillard
88c2664641740126714bb363bd6b5f65f724031c83Daniel Veillard#if 0
894e1b26cfeba7f5fad4f8bd12fb5ce7029f930b79Daniel Veillardextern void xmlMemFree(void *ptr);
904e1b26cfeba7f5fad4f8bd12fb5ce7029f930b79Daniel Veillardextern void *xmlMemMalloc(size_t size);
91d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillardextern void *xmlMemRealloc(void *ptr, size_t size);
924e1b26cfeba7f5fad4f8bd12fb5ce7029f930b79Daniel Veillardextern char *xmlMemoryStrdup(const char *str);
93c2664641740126714bb363bd6b5f65f724031c83Daniel Veillard#endif
944e1b26cfeba7f5fad4f8bd12fb5ce7029f930b79Daniel Veillard
954e1b26cfeba7f5fad4f8bd12fb5ce7029f930b79Daniel Veillardstatic int libxmlMemoryDebugActivated = 0;
964e1b26cfeba7f5fad4f8bd12fb5ce7029f930b79Daniel Veillardstatic long libxmlMemoryAllocatedBase = 0;
974e1b26cfeba7f5fad4f8bd12fb5ce7029f930b79Daniel Veillard
984e1b26cfeba7f5fad4f8bd12fb5ce7029f930b79Daniel Veillardstatic int libxmlMemoryDebug = 0;
994e1b26cfeba7f5fad4f8bd12fb5ce7029f930b79Daniel Veillardstatic xmlFreeFunc freeFunc = NULL;
1004e1b26cfeba7f5fad4f8bd12fb5ce7029f930b79Daniel Veillardstatic xmlMallocFunc mallocFunc = NULL;
1014e1b26cfeba7f5fad4f8bd12fb5ce7029f930b79Daniel Veillardstatic xmlReallocFunc reallocFunc = NULL;
1024e1b26cfeba7f5fad4f8bd12fb5ce7029f930b79Daniel Veillardstatic xmlStrdupFunc strdupFunc = NULL;
1034e1b26cfeba7f5fad4f8bd12fb5ce7029f930b79Daniel Veillard
104f93a866079364a006189683eaa07f94c867389d1Daniel Veillardstatic void
105f93a866079364a006189683eaa07f94c867389d1Daniel Veillardlibxml_xmlErrorInitialize(void); /* forward declare */
106f93a866079364a006189683eaa07f94c867389d1Daniel Veillard
1074e1b26cfeba7f5fad4f8bd12fb5ce7029f930b79Daniel VeillardPyObject *
108c68d78d25a17e65d172ccc1ac24d609c7c1d5cdeWilliam M. Bracklibxml_xmlMemoryUsed(PyObject * self ATTRIBUTE_UNUSED,
109c68d78d25a17e65d172ccc1ac24d609c7c1d5cdeWilliam M. Brack        PyObject * args ATTRIBUTE_UNUSED)
110529233ccdd43203fd74ec18a1d5a071c122c6e46Daniel Veillard{
111529233ccdd43203fd74ec18a1d5a071c122c6e46Daniel Veillard    long ret;
112529233ccdd43203fd74ec18a1d5a071c122c6e46Daniel Veillard    PyObject *py_retval;
113529233ccdd43203fd74ec18a1d5a071c122c6e46Daniel Veillard
114529233ccdd43203fd74ec18a1d5a071c122c6e46Daniel Veillard    ret = xmlMemUsed();
115529233ccdd43203fd74ec18a1d5a071c122c6e46Daniel Veillard
116529233ccdd43203fd74ec18a1d5a071c122c6e46Daniel Veillard    py_retval = libxml_longWrap(ret);
117529233ccdd43203fd74ec18a1d5a071c122c6e46Daniel Veillard    return (py_retval);
118529233ccdd43203fd74ec18a1d5a071c122c6e46Daniel Veillard}
119529233ccdd43203fd74ec18a1d5a071c122c6e46Daniel Veillard
120529233ccdd43203fd74ec18a1d5a071c122c6e46Daniel VeillardPyObject *
121c68d78d25a17e65d172ccc1ac24d609c7c1d5cdeWilliam M. Bracklibxml_xmlDebugMemory(PyObject * self ATTRIBUTE_UNUSED, PyObject * args)
122d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard{
1234e1b26cfeba7f5fad4f8bd12fb5ce7029f930b79Daniel Veillard    int activate;
1244e1b26cfeba7f5fad4f8bd12fb5ce7029f930b79Daniel Veillard    PyObject *py_retval;
1254e1b26cfeba7f5fad4f8bd12fb5ce7029f930b79Daniel Veillard    long ret;
1264e1b26cfeba7f5fad4f8bd12fb5ce7029f930b79Daniel Veillard
127d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard    if (!PyArg_ParseTuple(args, (char *) "i:xmlDebugMemory", &activate))
128d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        return (NULL);
1294e1b26cfeba7f5fad4f8bd12fb5ce7029f930b79Daniel Veillard
1304e1b26cfeba7f5fad4f8bd12fb5ce7029f930b79Daniel Veillard#ifdef DEBUG_MEMORY
1314e1b26cfeba7f5fad4f8bd12fb5ce7029f930b79Daniel Veillard    printf("libxml_xmlDebugMemory(%d) called\n", activate);
1324e1b26cfeba7f5fad4f8bd12fb5ce7029f930b79Daniel Veillard#endif
1334e1b26cfeba7f5fad4f8bd12fb5ce7029f930b79Daniel Veillard
1344e1b26cfeba7f5fad4f8bd12fb5ce7029f930b79Daniel Veillard    if (activate != 0) {
135d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        if (libxmlMemoryDebug == 0) {
136d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            /*
137d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard             * First initialize the library and grab the old memory handlers
138d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard             * and switch the library to memory debugging
139d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard             */
140d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            xmlMemGet((xmlFreeFunc *) & freeFunc,
141d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard                      (xmlMallocFunc *) & mallocFunc,
142d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard                      (xmlReallocFunc *) & reallocFunc,
143d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard                      (xmlStrdupFunc *) & strdupFunc);
144d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            if ((freeFunc == xmlMemFree) && (mallocFunc == xmlMemMalloc) &&
145d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard                (reallocFunc == xmlMemRealloc) &&
146d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard                (strdupFunc == xmlMemoryStrdup)) {
147d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard                libxmlMemoryAllocatedBase = xmlMemUsed();
148d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            } else {
149f93a866079364a006189683eaa07f94c867389d1Daniel Veillard                /*
150f93a866079364a006189683eaa07f94c867389d1Daniel Veillard                 * cleanup first, because some memory has been
151f93a866079364a006189683eaa07f94c867389d1Daniel Veillard                 * allocated with the non-debug malloc in xmlInitParser
152f93a866079364a006189683eaa07f94c867389d1Daniel Veillard                 * when the python module was imported
153f93a866079364a006189683eaa07f94c867389d1Daniel Veillard                 */
154f93a866079364a006189683eaa07f94c867389d1Daniel Veillard                xmlCleanupParser();
155d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard                ret = (long) xmlMemSetup(xmlMemFree, xmlMemMalloc,
156d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard                                         xmlMemRealloc, xmlMemoryStrdup);
157d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard                if (ret < 0)
158d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard                    goto error;
159d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard                libxmlMemoryAllocatedBase = xmlMemUsed();
160f93a866079364a006189683eaa07f94c867389d1Daniel Veillard                /* reinitialize */
161f93a866079364a006189683eaa07f94c867389d1Daniel Veillard                xmlInitParser();
162f93a866079364a006189683eaa07f94c867389d1Daniel Veillard                libxml_xmlErrorInitialize();
163d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            }
164d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            ret = 0;
165d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        } else if (libxmlMemoryDebugActivated == 0) {
166d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            libxmlMemoryAllocatedBase = xmlMemUsed();
167d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            ret = 0;
168d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        } else {
169d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            ret = xmlMemUsed() - libxmlMemoryAllocatedBase;
170d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        }
171d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        libxmlMemoryDebug = 1;
172d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        libxmlMemoryDebugActivated = 1;
1734e1b26cfeba7f5fad4f8bd12fb5ce7029f930b79Daniel Veillard    } else {
174d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        if (libxmlMemoryDebugActivated == 1)
175d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            ret = xmlMemUsed() - libxmlMemoryAllocatedBase;
176d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        else
177d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            ret = 0;
178d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        libxmlMemoryDebugActivated = 0;
1794e1b26cfeba7f5fad4f8bd12fb5ce7029f930b79Daniel Veillard    }
180d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard  error:
1814e1b26cfeba7f5fad4f8bd12fb5ce7029f930b79Daniel Veillard    py_retval = libxml_longWrap(ret);
182d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard    return (py_retval);
1834e1b26cfeba7f5fad4f8bd12fb5ce7029f930b79Daniel Veillard}
1844e1b26cfeba7f5fad4f8bd12fb5ce7029f930b79Daniel Veillard
1854e1b26cfeba7f5fad4f8bd12fb5ce7029f930b79Daniel VeillardPyObject *
186f93a866079364a006189683eaa07f94c867389d1Daniel Veillardlibxml_xmlPythonCleanupParser(PyObject *self ATTRIBUTE_UNUSED,
187f93a866079364a006189683eaa07f94c867389d1Daniel Veillard                              PyObject *args ATTRIBUTE_UNUSED) {
188f93a866079364a006189683eaa07f94c867389d1Daniel Veillard
1898e2cc6f2b53f536692f3c8ad8112bb67e0a1a629William M. Brack    int ix;
1908e2cc6f2b53f536692f3c8ad8112bb67e0a1a629William M. Brack    long freed = -1;
191f93a866079364a006189683eaa07f94c867389d1Daniel Veillard
192f93a866079364a006189683eaa07f94c867389d1Daniel Veillard    if (libxmlMemoryDebug) {
193f93a866079364a006189683eaa07f94c867389d1Daniel Veillard        freed = xmlMemUsed();
194f93a866079364a006189683eaa07f94c867389d1Daniel Veillard    }
195f93a866079364a006189683eaa07f94c867389d1Daniel Veillard
196f93a866079364a006189683eaa07f94c867389d1Daniel Veillard    xmlCleanupParser();
1978e2cc6f2b53f536692f3c8ad8112bb67e0a1a629William M. Brack    /*
1988e2cc6f2b53f536692f3c8ad8112bb67e0a1a629William M. Brack     * Need to confirm whether we really want to do this (required for
1998e2cc6f2b53f536692f3c8ad8112bb67e0a1a629William M. Brack     * memcheck) in all cases...
2008e2cc6f2b53f536692f3c8ad8112bb67e0a1a629William M. Brack     */
2018e2cc6f2b53f536692f3c8ad8112bb67e0a1a629William M. Brack
2028e2cc6f2b53f536692f3c8ad8112bb67e0a1a629William M. Brack    if (libxml_xpathCallbacks != NULL) {	/* if ext funcs declared */
2038e2cc6f2b53f536692f3c8ad8112bb67e0a1a629William M. Brack	for (ix=0; ix<libxml_xpathCallbacksNb; ix++) {
2048e2cc6f2b53f536692f3c8ad8112bb67e0a1a629William M. Brack	    if ((*libxml_xpathCallbacks)[ix].name != NULL)
2058e2cc6f2b53f536692f3c8ad8112bb67e0a1a629William M. Brack	        xmlFree((*libxml_xpathCallbacks)[ix].name);
2068e2cc6f2b53f536692f3c8ad8112bb67e0a1a629William M. Brack	    if ((*libxml_xpathCallbacks)[ix].ns_uri != NULL)
2078e2cc6f2b53f536692f3c8ad8112bb67e0a1a629William M. Brack	        xmlFree((*libxml_xpathCallbacks)[ix].ns_uri);
2088e2cc6f2b53f536692f3c8ad8112bb67e0a1a629William M. Brack	}
2098e2cc6f2b53f536692f3c8ad8112bb67e0a1a629William M. Brack	libxml_xpathCallbacksNb = 0;
2108e2cc6f2b53f536692f3c8ad8112bb67e0a1a629William M. Brack        xmlFree(libxml_xpathCallbacks);
2118e2cc6f2b53f536692f3c8ad8112bb67e0a1a629William M. Brack	libxml_xpathCallbacks = NULL;
2128e2cc6f2b53f536692f3c8ad8112bb67e0a1a629William M. Brack    }
213f93a866079364a006189683eaa07f94c867389d1Daniel Veillard
214f93a866079364a006189683eaa07f94c867389d1Daniel Veillard    if (libxmlMemoryDebug) {
215f93a866079364a006189683eaa07f94c867389d1Daniel Veillard        freed -= xmlMemUsed();
216f93a866079364a006189683eaa07f94c867389d1Daniel Veillard	libxmlMemoryAllocatedBase -= freed;
217f93a866079364a006189683eaa07f94c867389d1Daniel Veillard	if (libxmlMemoryAllocatedBase < 0)
218f93a866079364a006189683eaa07f94c867389d1Daniel Veillard	    libxmlMemoryAllocatedBase = 0;
219f93a866079364a006189683eaa07f94c867389d1Daniel Veillard    }
220f93a866079364a006189683eaa07f94c867389d1Daniel Veillard
221f93a866079364a006189683eaa07f94c867389d1Daniel Veillard    Py_INCREF(Py_None);
222f93a866079364a006189683eaa07f94c867389d1Daniel Veillard    return(Py_None);
223f93a866079364a006189683eaa07f94c867389d1Daniel Veillard}
224f93a866079364a006189683eaa07f94c867389d1Daniel Veillard
225f93a866079364a006189683eaa07f94c867389d1Daniel VeillardPyObject *
226d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillardlibxml_xmlDumpMemory(ATTRIBUTE_UNUSED PyObject * self,
227d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard                     ATTRIBUTE_UNUSED PyObject * args)
228d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard{
2294e1b26cfeba7f5fad4f8bd12fb5ce7029f930b79Daniel Veillard
2304e1b26cfeba7f5fad4f8bd12fb5ce7029f930b79Daniel Veillard    if (libxmlMemoryDebug != 0)
231d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        xmlMemoryDump();
2324e1b26cfeba7f5fad4f8bd12fb5ce7029f930b79Daniel Veillard    Py_INCREF(Py_None);
233d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard    return (Py_None);
2344e1b26cfeba7f5fad4f8bd12fb5ce7029f930b79Daniel Veillard}
235d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard
236d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard/************************************************************************
237d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard *									*
238c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard *		Handling Python FILE I/O at the C level			*
239c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard *	The raw I/O attack diectly the File objects, while the		*
240c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard *	other routines address the ioWrapper instance instead		*
241c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard *									*
242c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard ************************************************************************/
243c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard
244c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard/**
245c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard * xmlPythonFileCloseUnref:
246c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard * @context:  the I/O context
247c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard *
248c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard * Close an I/O channel
249c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard */
250c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillardstatic int
251c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel VeillardxmlPythonFileCloseRaw (void * context) {
252c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard    PyObject *file, *ret;
253c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard
254c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard#ifdef DEBUG_FILES
255c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard    printf("xmlPythonFileCloseUnref\n");
256c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard#endif
257c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard    file = (PyObject *) context;
258c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard    if (file == NULL) return(-1);
259118aed78f360f51d182770e62b251ef324707aa2Daniel Veillard    ret = PyEval_CallMethod(file, (char *) "close", (char *) "()");
260c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard    if (ret != NULL) {
261c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard	Py_DECREF(ret);
262c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard    }
263c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard    Py_DECREF(file);
264c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard    return(0);
265c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard}
266c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard
267c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard/**
268c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard * xmlPythonFileReadRaw:
269c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard * @context:  the I/O context
270c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard * @buffer:  where to drop data
271c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard * @len:  number of bytes to write
272c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard *
273c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard * Read @len bytes to @buffer from the Python file in the I/O channel
274c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard *
275c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard * Returns the number of bytes read
276c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard */
277c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillardstatic int
278c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel VeillardxmlPythonFileReadRaw (void * context, char * buffer, int len) {
279c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard    PyObject *file;
280c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard    PyObject *ret;
281c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard    int lenread = -1;
282c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard    char *data;
283c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard
284c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard#ifdef DEBUG_FILES
285c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard    printf("xmlPythonFileReadRaw: %d\n", len);
286c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard#endif
287c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard    file = (PyObject *) context;
288c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard    if (file == NULL) return(-1);
289118aed78f360f51d182770e62b251ef324707aa2Daniel Veillard    ret = PyEval_CallMethod(file, (char *) "read", (char *) "(i)", len);
290c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard    if (ret == NULL) {
291c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard	printf("xmlPythonFileReadRaw: result is NULL\n");
292c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard	return(-1);
2933798c4adbb91f80bef1e9f1b4b61dae72577a244Daniel Veillard    } else if (PyBytes_Check(ret)) {
2943798c4adbb91f80bef1e9f1b4b61dae72577a244Daniel Veillard	lenread = PyBytes_Size(ret);
2953798c4adbb91f80bef1e9f1b4b61dae72577a244Daniel Veillard	data = PyBytes_AsString(ret);
2963798c4adbb91f80bef1e9f1b4b61dae72577a244Daniel Veillard#ifdef PyUnicode_Check
2973798c4adbb91f80bef1e9f1b4b61dae72577a244Daniel Veillard    } else if PyUnicode_Check (ret) {
2983798c4adbb91f80bef1e9f1b4b61dae72577a244Daniel Veillard#if PY_VERSION_HEX >= 0x03030000
2996eea2f2c60e6a97491920cdf86b847869a2411ddArmin K        Py_ssize_t size;
3003798c4adbb91f80bef1e9f1b4b61dae72577a244Daniel Veillard	const char *tmp;
3013798c4adbb91f80bef1e9f1b4b61dae72577a244Daniel Veillard
3023798c4adbb91f80bef1e9f1b4b61dae72577a244Daniel Veillard	/* tmp doesn't need to be deallocated */
3033798c4adbb91f80bef1e9f1b4b61dae72577a244Daniel Veillard        tmp = PyUnicode_AsUTF8AndSize(ret, &size);
3043798c4adbb91f80bef1e9f1b4b61dae72577a244Daniel Veillard
3053798c4adbb91f80bef1e9f1b4b61dae72577a244Daniel Veillard	lenread = (int) size;
3063798c4adbb91f80bef1e9f1b4b61dae72577a244Daniel Veillard	data = (char *) tmp;
3073798c4adbb91f80bef1e9f1b4b61dae72577a244Daniel Veillard#else
3083798c4adbb91f80bef1e9f1b4b61dae72577a244Daniel Veillard        PyObject *b;
3093798c4adbb91f80bef1e9f1b4b61dae72577a244Daniel Veillard	b = PyUnicode_AsUTF8String(ret);
3103798c4adbb91f80bef1e9f1b4b61dae72577a244Daniel Veillard	if (b == NULL) {
3113798c4adbb91f80bef1e9f1b4b61dae72577a244Daniel Veillard	    printf("xmlPythonFileReadRaw: failed to convert to UTF-8\n");
3123798c4adbb91f80bef1e9f1b4b61dae72577a244Daniel Veillard	    return(-1);
3133798c4adbb91f80bef1e9f1b4b61dae72577a244Daniel Veillard	}
3143798c4adbb91f80bef1e9f1b4b61dae72577a244Daniel Veillard	lenread = PyBytes_Size(b);
3153798c4adbb91f80bef1e9f1b4b61dae72577a244Daniel Veillard	data = PyBytes_AsString(b);
3163798c4adbb91f80bef1e9f1b4b61dae72577a244Daniel Veillard	Py_DECREF(b);
3173798c4adbb91f80bef1e9f1b4b61dae72577a244Daniel Veillard#endif
3183798c4adbb91f80bef1e9f1b4b61dae72577a244Daniel Veillard#endif
319c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard    } else {
320c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard	printf("xmlPythonFileReadRaw: result is not a String\n");
321c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard	Py_DECREF(ret);
3223798c4adbb91f80bef1e9f1b4b61dae72577a244Daniel Veillard	return(-1);
323c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard    }
3243798c4adbb91f80bef1e9f1b4b61dae72577a244Daniel Veillard    if (lenread > len)
3253798c4adbb91f80bef1e9f1b4b61dae72577a244Daniel Veillard	memcpy(buffer, data, len);
3263798c4adbb91f80bef1e9f1b4b61dae72577a244Daniel Veillard    else
3273798c4adbb91f80bef1e9f1b4b61dae72577a244Daniel Veillard	memcpy(buffer, data, lenread);
3283798c4adbb91f80bef1e9f1b4b61dae72577a244Daniel Veillard    Py_DECREF(ret);
329c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard    return(lenread);
330c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard}
331c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard
332c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard/**
333c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard * xmlPythonFileRead:
334c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard * @context:  the I/O context
335c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard * @buffer:  where to drop data
336c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard * @len:  number of bytes to write
337c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard *
338c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard * Read @len bytes to @buffer from the I/O channel.
339c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard *
340c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard * Returns the number of bytes read
341c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard */
342c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillardstatic int
343c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel VeillardxmlPythonFileRead (void * context, char * buffer, int len) {
344c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard    PyObject *file;
345c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard    PyObject *ret;
346c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard    int lenread = -1;
347c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard    char *data;
348c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard
349c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard#ifdef DEBUG_FILES
350c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard    printf("xmlPythonFileRead: %d\n", len);
351c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard#endif
352c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard    file = (PyObject *) context;
353c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard    if (file == NULL) return(-1);
354118aed78f360f51d182770e62b251ef324707aa2Daniel Veillard    ret = PyEval_CallMethod(file, (char *) "io_read", (char *) "(i)", len);
355c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard    if (ret == NULL) {
356c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard	printf("xmlPythonFileRead: result is NULL\n");
357c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard	return(-1);
3583798c4adbb91f80bef1e9f1b4b61dae72577a244Daniel Veillard    } else if (PyBytes_Check(ret)) {
3593798c4adbb91f80bef1e9f1b4b61dae72577a244Daniel Veillard	lenread = PyBytes_Size(ret);
3603798c4adbb91f80bef1e9f1b4b61dae72577a244Daniel Veillard	data = PyBytes_AsString(ret);
3613798c4adbb91f80bef1e9f1b4b61dae72577a244Daniel Veillard#ifdef PyUnicode_Check
3623798c4adbb91f80bef1e9f1b4b61dae72577a244Daniel Veillard    } else if PyUnicode_Check (ret) {
3633798c4adbb91f80bef1e9f1b4b61dae72577a244Daniel Veillard#if PY_VERSION_HEX >= 0x03030000
3646eea2f2c60e6a97491920cdf86b847869a2411ddArmin K        Py_ssize_t size;
3653798c4adbb91f80bef1e9f1b4b61dae72577a244Daniel Veillard	const char *tmp;
3663798c4adbb91f80bef1e9f1b4b61dae72577a244Daniel Veillard
3673798c4adbb91f80bef1e9f1b4b61dae72577a244Daniel Veillard	/* tmp doesn't need to be deallocated */
3683798c4adbb91f80bef1e9f1b4b61dae72577a244Daniel Veillard        tmp = PyUnicode_AsUTF8AndSize(ret, &size);
3693798c4adbb91f80bef1e9f1b4b61dae72577a244Daniel Veillard
3703798c4adbb91f80bef1e9f1b4b61dae72577a244Daniel Veillard	lenread = (int) size;
3713798c4adbb91f80bef1e9f1b4b61dae72577a244Daniel Veillard	data = (char *) tmp;
3723798c4adbb91f80bef1e9f1b4b61dae72577a244Daniel Veillard#else
3733798c4adbb91f80bef1e9f1b4b61dae72577a244Daniel Veillard        PyObject *b;
3743798c4adbb91f80bef1e9f1b4b61dae72577a244Daniel Veillard	b = PyUnicode_AsUTF8String(ret);
3753798c4adbb91f80bef1e9f1b4b61dae72577a244Daniel Veillard	if (b == NULL) {
3763798c4adbb91f80bef1e9f1b4b61dae72577a244Daniel Veillard	    printf("xmlPythonFileRead: failed to convert to UTF-8\n");
3773798c4adbb91f80bef1e9f1b4b61dae72577a244Daniel Veillard	    return(-1);
3783798c4adbb91f80bef1e9f1b4b61dae72577a244Daniel Veillard	}
3793798c4adbb91f80bef1e9f1b4b61dae72577a244Daniel Veillard	lenread = PyBytes_Size(b);
3803798c4adbb91f80bef1e9f1b4b61dae72577a244Daniel Veillard	data = PyBytes_AsString(b);
3813798c4adbb91f80bef1e9f1b4b61dae72577a244Daniel Veillard	Py_DECREF(b);
3823798c4adbb91f80bef1e9f1b4b61dae72577a244Daniel Veillard#endif
3833798c4adbb91f80bef1e9f1b4b61dae72577a244Daniel Veillard#endif
384c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard    } else {
385c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard	printf("xmlPythonFileRead: result is not a String\n");
386c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard	Py_DECREF(ret);
3873798c4adbb91f80bef1e9f1b4b61dae72577a244Daniel Veillard	return(-1);
388c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard    }
3893798c4adbb91f80bef1e9f1b4b61dae72577a244Daniel Veillard    if (lenread > len)
3903798c4adbb91f80bef1e9f1b4b61dae72577a244Daniel Veillard	memcpy(buffer, data, len);
3913798c4adbb91f80bef1e9f1b4b61dae72577a244Daniel Veillard    else
3923798c4adbb91f80bef1e9f1b4b61dae72577a244Daniel Veillard	memcpy(buffer, data, lenread);
3933798c4adbb91f80bef1e9f1b4b61dae72577a244Daniel Veillard    Py_DECREF(ret);
394c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard    return(lenread);
395c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard}
396c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard
397c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard/**
398c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard * xmlFileWrite:
399c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard * @context:  the I/O context
400c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard * @buffer:  where to drop data
401c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard * @len:  number of bytes to write
402c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard *
403c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard * Write @len bytes from @buffer to the I/O channel.
404c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard *
405c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard * Returns the number of bytes written
406c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard */
407c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillardstatic int
408c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel VeillardxmlPythonFileWrite (void * context, const char * buffer, int len) {
409c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard    PyObject *file;
410c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard    PyObject *string;
4116cbd6c0738efb6c55d08f39c0731d46d678858faDaniel Veillard    PyObject *ret = NULL;
412c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard    int written = -1;
413c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard
414c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard#ifdef DEBUG_FILES
415c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard    printf("xmlPythonFileWrite: %d\n", len);
416c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard#endif
417c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard    file = (PyObject *) context;
418c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard    if (file == NULL) return(-1);
4193798c4adbb91f80bef1e9f1b4b61dae72577a244Daniel Veillard    string = PY_IMPORT_STRING_SIZE(buffer, len);
420c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard    if (string == NULL) return(-1);
4216cbd6c0738efb6c55d08f39c0731d46d678858faDaniel Veillard    if (PyObject_HasAttrString(file, (char *) "io_write")) {
4226cbd6c0738efb6c55d08f39c0731d46d678858faDaniel Veillard        ret = PyEval_CallMethod(file, (char *) "io_write", (char *) "(O)",
4236cbd6c0738efb6c55d08f39c0731d46d678858faDaniel Veillard	                        string);
4246cbd6c0738efb6c55d08f39c0731d46d678858faDaniel Veillard    } else if (PyObject_HasAttrString(file, (char *) "write")) {
4256cbd6c0738efb6c55d08f39c0731d46d678858faDaniel Veillard        ret = PyEval_CallMethod(file, (char *) "write", (char *) "(O)",
4266cbd6c0738efb6c55d08f39c0731d46d678858faDaniel Veillard	                        string);
4276cbd6c0738efb6c55d08f39c0731d46d678858faDaniel Veillard    }
428c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard    Py_DECREF(string);
429c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard    if (ret == NULL) {
430c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard	printf("xmlPythonFileWrite: result is NULL\n");
431c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard	return(-1);
4323798c4adbb91f80bef1e9f1b4b61dae72577a244Daniel Veillard    } else if (PyLong_Check(ret)) {
4333798c4adbb91f80bef1e9f1b4b61dae72577a244Daniel Veillard	written = (int) PyLong_AsLong(ret);
434c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard	Py_DECREF(ret);
435c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard    } else if (ret == Py_None) {
436c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard	written = len;
437c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard	Py_DECREF(ret);
438c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard    } else {
439c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard	printf("xmlPythonFileWrite: result is not an Int nor None\n");
440c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard	Py_DECREF(ret);
441c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard    }
442c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard    return(written);
443c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard}
444c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard
445c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard/**
446c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard * xmlPythonFileClose:
447c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard * @context:  the I/O context
448c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard *
449c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard * Close an I/O channel
450c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard */
451c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillardstatic int
452c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel VeillardxmlPythonFileClose (void * context) {
4536cbd6c0738efb6c55d08f39c0731d46d678858faDaniel Veillard    PyObject *file, *ret = NULL;
454c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard
455c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard#ifdef DEBUG_FILES
456c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard    printf("xmlPythonFileClose\n");
457c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard#endif
458c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard    file = (PyObject *) context;
459c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard    if (file == NULL) return(-1);
4606cbd6c0738efb6c55d08f39c0731d46d678858faDaniel Veillard    if (PyObject_HasAttrString(file, (char *) "io_close")) {
4616cbd6c0738efb6c55d08f39c0731d46d678858faDaniel Veillard        ret = PyEval_CallMethod(file, (char *) "io_close", (char *) "()");
4626cbd6c0738efb6c55d08f39c0731d46d678858faDaniel Veillard    } else if (PyObject_HasAttrString(file, (char *) "flush")) {
4636cbd6c0738efb6c55d08f39c0731d46d678858faDaniel Veillard        ret = PyEval_CallMethod(file, (char *) "flush", (char *) "()");
4646cbd6c0738efb6c55d08f39c0731d46d678858faDaniel Veillard    }
465c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard    if (ret != NULL) {
466c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard	Py_DECREF(ret);
467c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard    }
468c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard    return(0);
469c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard}
470c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard
471a9cce9cd0d7aff3ec318b5d8d376da131b6aaad4Daniel Veillard#ifdef LIBXML_OUTPUT_ENABLED
472c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard/**
473c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard * xmlOutputBufferCreatePythonFile:
474c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard * @file:  a PyFile_Type
475c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard * @encoder:  the encoding converter or NULL
476c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard *
477c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard * Create a buffered output for the progressive saving to a PyFile_Type
478c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard * buffered C I/O
479c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard *
480c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard * Returns the new parser output or NULL
481c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard */
482118aed78f360f51d182770e62b251ef324707aa2Daniel Veillardstatic xmlOutputBufferPtr
483c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel VeillardxmlOutputBufferCreatePythonFile(PyObject *file,
484c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard	                        xmlCharEncodingHandlerPtr encoder) {
485c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard    xmlOutputBufferPtr ret;
486c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard
487c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard    if (file == NULL) return(NULL);
488c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard
489c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard    ret = xmlAllocOutputBuffer(encoder);
490c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard    if (ret != NULL) {
491c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard        ret->context = file;
492c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard	/* Py_INCREF(file); */
493c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard	ret->writecallback = xmlPythonFileWrite;
494c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard	ret->closecallback = xmlPythonFileClose;
495c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard    }
496c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard
497c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard    return(ret);
498c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard}
499c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard
500c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel VeillardPyObject *
501c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillardlibxml_xmlCreateOutputBuffer(ATTRIBUTE_UNUSED PyObject *self, PyObject *args) {
502c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard    PyObject *py_retval;
503c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard    PyObject *file;
504c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard    xmlChar  *encoding;
505c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard    xmlCharEncodingHandlerPtr handler = NULL;
506c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard    xmlOutputBufferPtr buffer;
507c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard
508c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard
509c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard    if (!PyArg_ParseTuple(args, (char *)"Oz:xmlOutputBufferCreate",
510c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard		&file, &encoding))
511c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard	return(NULL);
512c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard    if ((encoding != NULL) && (encoding[0] != 0)) {
513118aed78f360f51d182770e62b251ef324707aa2Daniel Veillard	handler = xmlFindCharEncodingHandler((const char *) encoding);
514c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard    }
515c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard    buffer = xmlOutputBufferCreatePythonFile(file, handler);
516c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard    if (buffer == NULL)
517c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard	printf("libxml_xmlCreateOutputBuffer: buffer == NULL\n");
518c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard    py_retval = libxml_xmlOutputBufferPtrWrap(buffer);
519c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard    return(py_retval);
520c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard}
5216cbd6c0738efb6c55d08f39c0731d46d678858faDaniel Veillard
5226cbd6c0738efb6c55d08f39c0731d46d678858faDaniel Veillard/**
5236cbd6c0738efb6c55d08f39c0731d46d678858faDaniel Veillard * libxml_outputBufferGetPythonFile:
5246cbd6c0738efb6c55d08f39c0731d46d678858faDaniel Veillard * @buffer:  the I/O buffer
5256cbd6c0738efb6c55d08f39c0731d46d678858faDaniel Veillard *
5266cbd6c0738efb6c55d08f39c0731d46d678858faDaniel Veillard * read the Python I/O from the CObject
5276cbd6c0738efb6c55d08f39c0731d46d678858faDaniel Veillard *
5286cbd6c0738efb6c55d08f39c0731d46d678858faDaniel Veillard * Returns the new parser output or NULL
5296cbd6c0738efb6c55d08f39c0731d46d678858faDaniel Veillard */
5306cbd6c0738efb6c55d08f39c0731d46d678858faDaniel Veillardstatic PyObject *
5316cbd6c0738efb6c55d08f39c0731d46d678858faDaniel Veillardlibxml_outputBufferGetPythonFile(ATTRIBUTE_UNUSED PyObject *self,
5326cbd6c0738efb6c55d08f39c0731d46d678858faDaniel Veillard                                    PyObject *args) {
5336cbd6c0738efb6c55d08f39c0731d46d678858faDaniel Veillard    PyObject *buffer;
5346cbd6c0738efb6c55d08f39c0731d46d678858faDaniel Veillard    PyObject *file;
5356cbd6c0738efb6c55d08f39c0731d46d678858faDaniel Veillard    xmlOutputBufferPtr obj;
5366cbd6c0738efb6c55d08f39c0731d46d678858faDaniel Veillard
5376cbd6c0738efb6c55d08f39c0731d46d678858faDaniel Veillard    if (!PyArg_ParseTuple(args, (char *)"O:outputBufferGetPythonFile",
5386cbd6c0738efb6c55d08f39c0731d46d678858faDaniel Veillard			  &buffer))
5396cbd6c0738efb6c55d08f39c0731d46d678858faDaniel Veillard	return(NULL);
5406cbd6c0738efb6c55d08f39c0731d46d678858faDaniel Veillard
5416cbd6c0738efb6c55d08f39c0731d46d678858faDaniel Veillard    obj = PyoutputBuffer_Get(buffer);
5426cbd6c0738efb6c55d08f39c0731d46d678858faDaniel Veillard    if (obj == NULL) {
5436cbd6c0738efb6c55d08f39c0731d46d678858faDaniel Veillard	fprintf(stderr,
5446cbd6c0738efb6c55d08f39c0731d46d678858faDaniel Veillard	        "outputBufferGetPythonFile: obj == NULL\n");
5456cbd6c0738efb6c55d08f39c0731d46d678858faDaniel Veillard	Py_INCREF(Py_None);
5466cbd6c0738efb6c55d08f39c0731d46d678858faDaniel Veillard	return(Py_None);
5476cbd6c0738efb6c55d08f39c0731d46d678858faDaniel Veillard    }
5486cbd6c0738efb6c55d08f39c0731d46d678858faDaniel Veillard    if (obj->closecallback != xmlPythonFileClose) {
5496cbd6c0738efb6c55d08f39c0731d46d678858faDaniel Veillard	fprintf(stderr,
5506cbd6c0738efb6c55d08f39c0731d46d678858faDaniel Veillard	        "outputBufferGetPythonFile: not a python file wrapper\n");
5516cbd6c0738efb6c55d08f39c0731d46d678858faDaniel Veillard	Py_INCREF(Py_None);
5526cbd6c0738efb6c55d08f39c0731d46d678858faDaniel Veillard	return(Py_None);
5536cbd6c0738efb6c55d08f39c0731d46d678858faDaniel Veillard    }
5546cbd6c0738efb6c55d08f39c0731d46d678858faDaniel Veillard    file = (PyObject *) obj->context;
5556cbd6c0738efb6c55d08f39c0731d46d678858faDaniel Veillard    if (file == NULL) {
5566cbd6c0738efb6c55d08f39c0731d46d678858faDaniel Veillard	Py_INCREF(Py_None);
5576cbd6c0738efb6c55d08f39c0731d46d678858faDaniel Veillard	return(Py_None);
5586cbd6c0738efb6c55d08f39c0731d46d678858faDaniel Veillard    }
5596cbd6c0738efb6c55d08f39c0731d46d678858faDaniel Veillard    Py_INCREF(file);
5606cbd6c0738efb6c55d08f39c0731d46d678858faDaniel Veillard    return(file);
5616cbd6c0738efb6c55d08f39c0731d46d678858faDaniel Veillard}
5626cbd6c0738efb6c55d08f39c0731d46d678858faDaniel Veillard
563d5e198ad454803c60b898451ff432f2fcf0e95ceDaniel Veillardstatic PyObject *
5646cbd6c0738efb6c55d08f39c0731d46d678858faDaniel Veillardlibxml_xmlOutputBufferClose(PyObject *self ATTRIBUTE_UNUSED, PyObject *args) {
5656cbd6c0738efb6c55d08f39c0731d46d678858faDaniel Veillard    PyObject *py_retval;
5666cbd6c0738efb6c55d08f39c0731d46d678858faDaniel Veillard    int c_retval;
5676cbd6c0738efb6c55d08f39c0731d46d678858faDaniel Veillard    xmlOutputBufferPtr out;
5686cbd6c0738efb6c55d08f39c0731d46d678858faDaniel Veillard    PyObject *pyobj_out;
5696cbd6c0738efb6c55d08f39c0731d46d678858faDaniel Veillard
5706cbd6c0738efb6c55d08f39c0731d46d678858faDaniel Veillard    if (!PyArg_ParseTuple(args, (char *)"O:xmlOutputBufferClose", &pyobj_out))
5716cbd6c0738efb6c55d08f39c0731d46d678858faDaniel Veillard        return(NULL);
5726cbd6c0738efb6c55d08f39c0731d46d678858faDaniel Veillard    out = (xmlOutputBufferPtr) PyoutputBuffer_Get(pyobj_out);
573263ec86a75f7b5ec2d37dbb89356bf7fca11cff3Daniel Veillard    /* Buffer may already have been destroyed elsewhere. This is harmless. */
574263ec86a75f7b5ec2d37dbb89356bf7fca11cff3Daniel Veillard    if (out == NULL) {
575263ec86a75f7b5ec2d37dbb89356bf7fca11cff3Daniel Veillard	Py_INCREF(Py_None);
576263ec86a75f7b5ec2d37dbb89356bf7fca11cff3Daniel Veillard	return(Py_None);
577263ec86a75f7b5ec2d37dbb89356bf7fca11cff3Daniel Veillard    }
5786cbd6c0738efb6c55d08f39c0731d46d678858faDaniel Veillard
5796cbd6c0738efb6c55d08f39c0731d46d678858faDaniel Veillard    c_retval = xmlOutputBufferClose(out);
5806cbd6c0738efb6c55d08f39c0731d46d678858faDaniel Veillard    py_retval = libxml_intWrap((int) c_retval);
5816cbd6c0738efb6c55d08f39c0731d46d678858faDaniel Veillard    return(py_retval);
5826cbd6c0738efb6c55d08f39c0731d46d678858faDaniel Veillard}
5836cbd6c0738efb6c55d08f39c0731d46d678858faDaniel Veillard
584d5e198ad454803c60b898451ff432f2fcf0e95ceDaniel Veillardstatic PyObject *
5856cbd6c0738efb6c55d08f39c0731d46d678858faDaniel Veillardlibxml_xmlOutputBufferFlush(PyObject *self ATTRIBUTE_UNUSED, PyObject *args) {
5866cbd6c0738efb6c55d08f39c0731d46d678858faDaniel Veillard    PyObject *py_retval;
5876cbd6c0738efb6c55d08f39c0731d46d678858faDaniel Veillard    int c_retval;
5886cbd6c0738efb6c55d08f39c0731d46d678858faDaniel Veillard    xmlOutputBufferPtr out;
5896cbd6c0738efb6c55d08f39c0731d46d678858faDaniel Veillard    PyObject *pyobj_out;
5906cbd6c0738efb6c55d08f39c0731d46d678858faDaniel Veillard
5916cbd6c0738efb6c55d08f39c0731d46d678858faDaniel Veillard    if (!PyArg_ParseTuple(args, (char *)"O:xmlOutputBufferFlush", &pyobj_out))
5926cbd6c0738efb6c55d08f39c0731d46d678858faDaniel Veillard        return(NULL);
5936cbd6c0738efb6c55d08f39c0731d46d678858faDaniel Veillard    out = (xmlOutputBufferPtr) PyoutputBuffer_Get(pyobj_out);
5946cbd6c0738efb6c55d08f39c0731d46d678858faDaniel Veillard
5956cbd6c0738efb6c55d08f39c0731d46d678858faDaniel Veillard    c_retval = xmlOutputBufferFlush(out);
5966cbd6c0738efb6c55d08f39c0731d46d678858faDaniel Veillard    py_retval = libxml_intWrap((int) c_retval);
5976cbd6c0738efb6c55d08f39c0731d46d678858faDaniel Veillard    return(py_retval);
5986cbd6c0738efb6c55d08f39c0731d46d678858faDaniel Veillard}
599263ec86a75f7b5ec2d37dbb89356bf7fca11cff3Daniel Veillard
600263ec86a75f7b5ec2d37dbb89356bf7fca11cff3Daniel Veillardstatic PyObject *
601263ec86a75f7b5ec2d37dbb89356bf7fca11cff3Daniel Veillardlibxml_xmlSaveFileTo(PyObject *self ATTRIBUTE_UNUSED, PyObject *args) {
602263ec86a75f7b5ec2d37dbb89356bf7fca11cff3Daniel Veillard    PyObject *py_retval;
603263ec86a75f7b5ec2d37dbb89356bf7fca11cff3Daniel Veillard    int c_retval;
604263ec86a75f7b5ec2d37dbb89356bf7fca11cff3Daniel Veillard    xmlOutputBufferPtr buf;
605263ec86a75f7b5ec2d37dbb89356bf7fca11cff3Daniel Veillard    PyObject *pyobj_buf;
606263ec86a75f7b5ec2d37dbb89356bf7fca11cff3Daniel Veillard    xmlDocPtr cur;
607263ec86a75f7b5ec2d37dbb89356bf7fca11cff3Daniel Veillard    PyObject *pyobj_cur;
608263ec86a75f7b5ec2d37dbb89356bf7fca11cff3Daniel Veillard    char * encoding;
609263ec86a75f7b5ec2d37dbb89356bf7fca11cff3Daniel Veillard
610263ec86a75f7b5ec2d37dbb89356bf7fca11cff3Daniel Veillard    if (!PyArg_ParseTuple(args, (char *)"OOz:xmlSaveFileTo", &pyobj_buf, &pyobj_cur, &encoding))
611263ec86a75f7b5ec2d37dbb89356bf7fca11cff3Daniel Veillard        return(NULL);
612263ec86a75f7b5ec2d37dbb89356bf7fca11cff3Daniel Veillard    buf = (xmlOutputBufferPtr) PyoutputBuffer_Get(pyobj_buf);
613263ec86a75f7b5ec2d37dbb89356bf7fca11cff3Daniel Veillard    cur = (xmlDocPtr) PyxmlNode_Get(pyobj_cur);
614263ec86a75f7b5ec2d37dbb89356bf7fca11cff3Daniel Veillard
615263ec86a75f7b5ec2d37dbb89356bf7fca11cff3Daniel Veillard    c_retval = xmlSaveFileTo(buf, cur, encoding);
616263ec86a75f7b5ec2d37dbb89356bf7fca11cff3Daniel Veillard	/* xmlSaveTo() freed the memory pointed to by buf, so record that in the
617263ec86a75f7b5ec2d37dbb89356bf7fca11cff3Daniel Veillard	 * Python object. */
618263ec86a75f7b5ec2d37dbb89356bf7fca11cff3Daniel Veillard    ((PyoutputBuffer_Object *)(pyobj_buf))->obj = NULL;
619263ec86a75f7b5ec2d37dbb89356bf7fca11cff3Daniel Veillard    py_retval = libxml_intWrap((int) c_retval);
620263ec86a75f7b5ec2d37dbb89356bf7fca11cff3Daniel Veillard    return(py_retval);
621263ec86a75f7b5ec2d37dbb89356bf7fca11cff3Daniel Veillard}
622263ec86a75f7b5ec2d37dbb89356bf7fca11cff3Daniel Veillard
623263ec86a75f7b5ec2d37dbb89356bf7fca11cff3Daniel Veillardstatic PyObject *
624263ec86a75f7b5ec2d37dbb89356bf7fca11cff3Daniel Veillardlibxml_xmlSaveFormatFileTo(PyObject *self ATTRIBUTE_UNUSED, PyObject *args) {
625263ec86a75f7b5ec2d37dbb89356bf7fca11cff3Daniel Veillard    PyObject *py_retval;
626263ec86a75f7b5ec2d37dbb89356bf7fca11cff3Daniel Veillard    int c_retval;
627263ec86a75f7b5ec2d37dbb89356bf7fca11cff3Daniel Veillard    xmlOutputBufferPtr buf;
628263ec86a75f7b5ec2d37dbb89356bf7fca11cff3Daniel Veillard    PyObject *pyobj_buf;
629263ec86a75f7b5ec2d37dbb89356bf7fca11cff3Daniel Veillard    xmlDocPtr cur;
630263ec86a75f7b5ec2d37dbb89356bf7fca11cff3Daniel Veillard    PyObject *pyobj_cur;
631263ec86a75f7b5ec2d37dbb89356bf7fca11cff3Daniel Veillard    char * encoding;
632263ec86a75f7b5ec2d37dbb89356bf7fca11cff3Daniel Veillard    int format;
633263ec86a75f7b5ec2d37dbb89356bf7fca11cff3Daniel Veillard
634263ec86a75f7b5ec2d37dbb89356bf7fca11cff3Daniel Veillard    if (!PyArg_ParseTuple(args, (char *)"OOzi:xmlSaveFormatFileTo", &pyobj_buf, &pyobj_cur, &encoding, &format))
635263ec86a75f7b5ec2d37dbb89356bf7fca11cff3Daniel Veillard        return(NULL);
636263ec86a75f7b5ec2d37dbb89356bf7fca11cff3Daniel Veillard    buf = (xmlOutputBufferPtr) PyoutputBuffer_Get(pyobj_buf);
637263ec86a75f7b5ec2d37dbb89356bf7fca11cff3Daniel Veillard    cur = (xmlDocPtr) PyxmlNode_Get(pyobj_cur);
638263ec86a75f7b5ec2d37dbb89356bf7fca11cff3Daniel Veillard
639263ec86a75f7b5ec2d37dbb89356bf7fca11cff3Daniel Veillard    c_retval = xmlSaveFormatFileTo(buf, cur, encoding, format);
640263ec86a75f7b5ec2d37dbb89356bf7fca11cff3Daniel Veillard	/* xmlSaveFormatFileTo() freed the memory pointed to by buf, so record that
641263ec86a75f7b5ec2d37dbb89356bf7fca11cff3Daniel Veillard	 * in the Python object */
642263ec86a75f7b5ec2d37dbb89356bf7fca11cff3Daniel Veillard	((PyoutputBuffer_Object *)(pyobj_buf))->obj = NULL;
643263ec86a75f7b5ec2d37dbb89356bf7fca11cff3Daniel Veillard    py_retval = libxml_intWrap((int) c_retval);
644263ec86a75f7b5ec2d37dbb89356bf7fca11cff3Daniel Veillard    return(py_retval);
645263ec86a75f7b5ec2d37dbb89356bf7fca11cff3Daniel Veillard}
646a9cce9cd0d7aff3ec318b5d8d376da131b6aaad4Daniel Veillard#endif /* LIBXML_OUTPUT_ENABLED */
647c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard
648c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard
649c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard/**
650c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard * xmlParserInputBufferCreatePythonFile:
651c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard * @file:  a PyFile_Type
652c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard * @encoder:  the encoding converter or NULL
653c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard *
654c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard * Create a buffered output for the progressive saving to a PyFile_Type
655c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard * buffered C I/O
656c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard *
657c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard * Returns the new parser output or NULL
658c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard */
659118aed78f360f51d182770e62b251ef324707aa2Daniel Veillardstatic xmlParserInputBufferPtr
660c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel VeillardxmlParserInputBufferCreatePythonFile(PyObject *file,
661c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard	                        xmlCharEncoding encoding) {
662c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard    xmlParserInputBufferPtr ret;
663c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard
664c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard    if (file == NULL) return(NULL);
665c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard
666c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard    ret = xmlAllocParserInputBuffer(encoding);
667c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard    if (ret != NULL) {
668c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard        ret->context = file;
669c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard	/* Py_INCREF(file); */
670c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard	ret->readcallback = xmlPythonFileRead;
671c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard	ret->closecallback = xmlPythonFileClose;
672c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard    }
673c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard
674c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard    return(ret);
675c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard}
676c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard
677c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel VeillardPyObject *
678c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillardlibxml_xmlCreateInputBuffer(ATTRIBUTE_UNUSED PyObject *self, PyObject *args) {
679c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard    PyObject *py_retval;
680c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard    PyObject *file;
681c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard    xmlChar  *encoding;
682c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard    xmlCharEncoding enc = XML_CHAR_ENCODING_NONE;
683c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard    xmlParserInputBufferPtr buffer;
684c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard
685c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard
686c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard    if (!PyArg_ParseTuple(args, (char *)"Oz:xmlParserInputBufferCreate",
687c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard		&file, &encoding))
688c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard	return(NULL);
689c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard    if ((encoding != NULL) && (encoding[0] != 0)) {
690118aed78f360f51d182770e62b251ef324707aa2Daniel Veillard	enc = xmlParseCharEncoding((const char *) encoding);
691c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard    }
692c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard    buffer = xmlParserInputBufferCreatePythonFile(file, enc);
693c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard    if (buffer == NULL)
694c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard	printf("libxml_xmlParserInputBufferCreate: buffer == NULL\n");
695c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard    py_retval = libxml_xmlParserInputBufferPtrWrap(buffer);
696c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard    return(py_retval);
697c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard}
698c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard
699c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard/************************************************************************
700c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard *									*
701c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard *		Providing the resolver at the Python level		*
702c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard *									*
703c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard ************************************************************************/
704c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard
705c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillardstatic xmlExternalEntityLoader defaultExternalEntityLoader = NULL;
706c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillardstatic PyObject *pythonExternalEntityLoaderObjext;
707c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard
708c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillardstatic xmlParserInputPtr
709c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel VeillardpythonExternalEntityLoader(const char *URL, const char *ID,
710c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard			   xmlParserCtxtPtr ctxt) {
711c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard    xmlParserInputPtr result = NULL;
712c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard    if (pythonExternalEntityLoaderObjext != NULL) {
713c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard	PyObject *ret;
714c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard	PyObject *ctxtobj;
715c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard
716c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard	ctxtobj = libxml_xmlParserCtxtPtrWrap(ctxt);
717c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard#ifdef DEBUG_LOADER
718c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard	printf("pythonExternalEntityLoader: ready to call\n");
719c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard#endif
720c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard
721c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard	ret = PyObject_CallFunction(pythonExternalEntityLoaderObjext,
722118aed78f360f51d182770e62b251ef324707aa2Daniel Veillard		      (char *) "(ssO)", URL, ID, ctxtobj);
723e4a07e7b77b191d61291d44dffa19b65387e04e4Daniel Veillard	Py_XDECREF(ctxtobj);
724c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard#ifdef DEBUG_LOADER
725c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard	printf("pythonExternalEntityLoader: result ");
726a9016c492788eb4792c42b52df0c72b46136787dAlexey Neyman	PyObject_Print(ret, stdout, 0);
727c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard	printf("\n");
728c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard#endif
729c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard
730c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard	if (ret != NULL) {
731118aed78f360f51d182770e62b251ef324707aa2Daniel Veillard	    if (PyObject_HasAttrString(ret, (char *) "read")) {
732c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard		xmlParserInputBufferPtr buf;
733c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard
734c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard		buf = xmlAllocParserInputBuffer(XML_CHAR_ENCODING_NONE);
735c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard		if (buf != NULL) {
736c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard		    buf->context = ret;
737c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard		    buf->readcallback = xmlPythonFileReadRaw;
738c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard		    buf->closecallback = xmlPythonFileCloseRaw;
739c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard		    result = xmlNewIOInputStream(ctxt, buf,
740c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard			                         XML_CHAR_ENCODING_NONE);
741c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard		}
7424ea89f04ccd58de6cc4b83195252d0becba1fe69Daniel Veillard#if 0
743c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard	    } else {
7444ea89f04ccd58de6cc4b83195252d0becba1fe69Daniel Veillard		if (URL != NULL)
7454ea89f04ccd58de6cc4b83195252d0becba1fe69Daniel Veillard		    printf("pythonExternalEntityLoader: can't read %s\n",
7464ea89f04ccd58de6cc4b83195252d0becba1fe69Daniel Veillard		           URL);
7474ea89f04ccd58de6cc4b83195252d0becba1fe69Daniel Veillard#endif
748c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard	    }
749c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard	    if (result == NULL) {
750c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard		Py_DECREF(ret);
751c64b8e984c13a0d989dea436c13128b289a4d4d6Daniel Veillard	    } else if (URL != NULL) {
752c193956ee1c3b229556301cf09f6ff1b6eb9cb70William M. Brack		result->filename = (char *) xmlStrdup((const xmlChar *)URL);
753c64b8e984c13a0d989dea436c13128b289a4d4d6Daniel Veillard		result->directory = xmlParserGetDirectory((const char *) URL);
754c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard	    }
755c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard	}
756c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard    }
757c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard    if ((result == NULL) && (defaultExternalEntityLoader != NULL)) {
758c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard	result = defaultExternalEntityLoader(URL, ID, ctxt);
759c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard    }
760c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard    return(result);
761c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard}
762c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard
763c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel VeillardPyObject *
764c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillardlibxml_xmlSetEntityLoader(ATTRIBUTE_UNUSED PyObject *self, PyObject *args) {
765c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard    PyObject *py_retval;
766c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard    PyObject *loader;
767c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard
768c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard    if (!PyArg_ParseTuple(args, (char *)"O:libxml_xmlSetEntityLoader",
769c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard		&loader))
770c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard	return(NULL);
771c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard
772a9016c492788eb4792c42b52df0c72b46136787dAlexey Neyman    if (!PyCallable_Check(loader)) {
773a9016c492788eb4792c42b52df0c72b46136787dAlexey Neyman	PyErr_SetString(PyExc_ValueError, "entity loader is not callable");
774a9016c492788eb4792c42b52df0c72b46136787dAlexey Neyman	return(NULL);
775a9016c492788eb4792c42b52df0c72b46136787dAlexey Neyman    }
776a9016c492788eb4792c42b52df0c72b46136787dAlexey Neyman
777c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard#ifdef DEBUG_LOADER
778c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard    printf("libxml_xmlSetEntityLoader\n");
779c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard#endif
780c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard    if (defaultExternalEntityLoader == NULL)
781c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard	defaultExternalEntityLoader = xmlGetExternalEntityLoader();
782c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard
783a9016c492788eb4792c42b52df0c72b46136787dAlexey Neyman    Py_XDECREF(pythonExternalEntityLoaderObjext);
784c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard    pythonExternalEntityLoaderObjext = loader;
785a9016c492788eb4792c42b52df0c72b46136787dAlexey Neyman    Py_XINCREF(pythonExternalEntityLoaderObjext);
786c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard    xmlSetExternalEntityLoader(pythonExternalEntityLoader);
787c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard
7883798c4adbb91f80bef1e9f1b4b61dae72577a244Daniel Veillard    py_retval = PyLong_FromLong(0);
789c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard    return(py_retval);
790c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard}
791c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard
79248da90bc4a3809728d08ee9ee8da21d044fbca82Alexey Neyman/************************************************************************
79348da90bc4a3809728d08ee9ee8da21d044fbca82Alexey Neyman *									*
79448da90bc4a3809728d08ee9ee8da21d044fbca82Alexey Neyman *		Input callback registration				*
79548da90bc4a3809728d08ee9ee8da21d044fbca82Alexey Neyman *									*
79648da90bc4a3809728d08ee9ee8da21d044fbca82Alexey Neyman ************************************************************************/
79748da90bc4a3809728d08ee9ee8da21d044fbca82Alexey Neymanstatic PyObject *pythonInputOpenCallbackObject;
79848da90bc4a3809728d08ee9ee8da21d044fbca82Alexey Neymanstatic int pythonInputCallbackID = -1;
79948da90bc4a3809728d08ee9ee8da21d044fbca82Alexey Neyman
80048da90bc4a3809728d08ee9ee8da21d044fbca82Alexey Neymanstatic int
80148da90bc4a3809728d08ee9ee8da21d044fbca82Alexey NeymanpythonInputMatchCallback(ATTRIBUTE_UNUSED const char *URI)
80248da90bc4a3809728d08ee9ee8da21d044fbca82Alexey Neyman{
80348da90bc4a3809728d08ee9ee8da21d044fbca82Alexey Neyman    /* Always return success, real decision whether URI is supported will be
80448da90bc4a3809728d08ee9ee8da21d044fbca82Alexey Neyman     * made in open callback.  */
80548da90bc4a3809728d08ee9ee8da21d044fbca82Alexey Neyman    return 1;
80648da90bc4a3809728d08ee9ee8da21d044fbca82Alexey Neyman}
80748da90bc4a3809728d08ee9ee8da21d044fbca82Alexey Neyman
80848da90bc4a3809728d08ee9ee8da21d044fbca82Alexey Neymanstatic void *
80948da90bc4a3809728d08ee9ee8da21d044fbca82Alexey NeymanpythonInputOpenCallback(const char *URI)
81048da90bc4a3809728d08ee9ee8da21d044fbca82Alexey Neyman{
81148da90bc4a3809728d08ee9ee8da21d044fbca82Alexey Neyman    PyObject *ret;
81248da90bc4a3809728d08ee9ee8da21d044fbca82Alexey Neyman
81348da90bc4a3809728d08ee9ee8da21d044fbca82Alexey Neyman    ret = PyObject_CallFunction(pythonInputOpenCallbackObject,
81448da90bc4a3809728d08ee9ee8da21d044fbca82Alexey Neyman	    (char *)"s", URI);
81548da90bc4a3809728d08ee9ee8da21d044fbca82Alexey Neyman    if (ret == Py_None) {
81648da90bc4a3809728d08ee9ee8da21d044fbca82Alexey Neyman	Py_DECREF(Py_None);
81748da90bc4a3809728d08ee9ee8da21d044fbca82Alexey Neyman	return NULL;
81848da90bc4a3809728d08ee9ee8da21d044fbca82Alexey Neyman    }
81948da90bc4a3809728d08ee9ee8da21d044fbca82Alexey Neyman    return ret;
82048da90bc4a3809728d08ee9ee8da21d044fbca82Alexey Neyman}
82148da90bc4a3809728d08ee9ee8da21d044fbca82Alexey Neyman
82248da90bc4a3809728d08ee9ee8da21d044fbca82Alexey NeymanPyObject *
82348da90bc4a3809728d08ee9ee8da21d044fbca82Alexey Neymanlibxml_xmlRegisterInputCallback(ATTRIBUTE_UNUSED PyObject *self,
82448da90bc4a3809728d08ee9ee8da21d044fbca82Alexey Neyman                                PyObject *args) {
82548da90bc4a3809728d08ee9ee8da21d044fbca82Alexey Neyman    PyObject *cb;
82648da90bc4a3809728d08ee9ee8da21d044fbca82Alexey Neyman
82748da90bc4a3809728d08ee9ee8da21d044fbca82Alexey Neyman    if (!PyArg_ParseTuple(args,
82848da90bc4a3809728d08ee9ee8da21d044fbca82Alexey Neyman		(const char *)"O:libxml_xmlRegisterInputCallback", &cb))
82948da90bc4a3809728d08ee9ee8da21d044fbca82Alexey Neyman	return(NULL);
83048da90bc4a3809728d08ee9ee8da21d044fbca82Alexey Neyman
83148da90bc4a3809728d08ee9ee8da21d044fbca82Alexey Neyman    if (!PyCallable_Check(cb)) {
83248da90bc4a3809728d08ee9ee8da21d044fbca82Alexey Neyman	PyErr_SetString(PyExc_ValueError, "input callback is not callable");
83348da90bc4a3809728d08ee9ee8da21d044fbca82Alexey Neyman	return(NULL);
83448da90bc4a3809728d08ee9ee8da21d044fbca82Alexey Neyman    }
83548da90bc4a3809728d08ee9ee8da21d044fbca82Alexey Neyman
83648da90bc4a3809728d08ee9ee8da21d044fbca82Alexey Neyman    /* Python module registers a single callback and manages the list of
83748da90bc4a3809728d08ee9ee8da21d044fbca82Alexey Neyman     * all callbacks internally. This is necessitated by xmlInputMatchCallback
83848da90bc4a3809728d08ee9ee8da21d044fbca82Alexey Neyman     * API, which does not allow for passing of data objects to discriminate
83948da90bc4a3809728d08ee9ee8da21d044fbca82Alexey Neyman     * different Python methods.  */
84048da90bc4a3809728d08ee9ee8da21d044fbca82Alexey Neyman    if (pythonInputCallbackID == -1) {
84148da90bc4a3809728d08ee9ee8da21d044fbca82Alexey Neyman	pythonInputCallbackID = xmlRegisterInputCallbacks(
84248da90bc4a3809728d08ee9ee8da21d044fbca82Alexey Neyman		pythonInputMatchCallback, pythonInputOpenCallback,
84348da90bc4a3809728d08ee9ee8da21d044fbca82Alexey Neyman		xmlPythonFileReadRaw, xmlPythonFileCloseRaw);
84448da90bc4a3809728d08ee9ee8da21d044fbca82Alexey Neyman	if (pythonInputCallbackID == -1)
84548da90bc4a3809728d08ee9ee8da21d044fbca82Alexey Neyman	    return PyErr_NoMemory();
84648da90bc4a3809728d08ee9ee8da21d044fbca82Alexey Neyman	pythonInputOpenCallbackObject = cb;
84748da90bc4a3809728d08ee9ee8da21d044fbca82Alexey Neyman	Py_INCREF(pythonInputOpenCallbackObject);
84848da90bc4a3809728d08ee9ee8da21d044fbca82Alexey Neyman    }
84948da90bc4a3809728d08ee9ee8da21d044fbca82Alexey Neyman
85048da90bc4a3809728d08ee9ee8da21d044fbca82Alexey Neyman    Py_INCREF(Py_None);
85148da90bc4a3809728d08ee9ee8da21d044fbca82Alexey Neyman    return(Py_None);
85248da90bc4a3809728d08ee9ee8da21d044fbca82Alexey Neyman}
85348da90bc4a3809728d08ee9ee8da21d044fbca82Alexey Neyman
85448da90bc4a3809728d08ee9ee8da21d044fbca82Alexey NeymanPyObject *
85548da90bc4a3809728d08ee9ee8da21d044fbca82Alexey Neymanlibxml_xmlUnregisterInputCallback(ATTRIBUTE_UNUSED PyObject *self,
85648da90bc4a3809728d08ee9ee8da21d044fbca82Alexey Neyman                                ATTRIBUTE_UNUSED PyObject *args) {
85748da90bc4a3809728d08ee9ee8da21d044fbca82Alexey Neyman    int ret;
85848da90bc4a3809728d08ee9ee8da21d044fbca82Alexey Neyman
85948da90bc4a3809728d08ee9ee8da21d044fbca82Alexey Neyman    ret = xmlPopInputCallbacks();
86048da90bc4a3809728d08ee9ee8da21d044fbca82Alexey Neyman    if (pythonInputCallbackID != -1) {
86148da90bc4a3809728d08ee9ee8da21d044fbca82Alexey Neyman	/* Assert that the right input callback was popped. libxml's API does not
86248da90bc4a3809728d08ee9ee8da21d044fbca82Alexey Neyman	 * allow removal by ID, so all that could be done is an assert.  */
86348da90bc4a3809728d08ee9ee8da21d044fbca82Alexey Neyman	if (pythonInputCallbackID == ret) {
86448da90bc4a3809728d08ee9ee8da21d044fbca82Alexey Neyman	    pythonInputCallbackID = -1;
86548da90bc4a3809728d08ee9ee8da21d044fbca82Alexey Neyman	    Py_DECREF(pythonInputOpenCallbackObject);
86648da90bc4a3809728d08ee9ee8da21d044fbca82Alexey Neyman	    pythonInputOpenCallbackObject = NULL;
86748da90bc4a3809728d08ee9ee8da21d044fbca82Alexey Neyman	} else {
86848da90bc4a3809728d08ee9ee8da21d044fbca82Alexey Neyman	    PyErr_SetString(PyExc_AssertionError, "popped non-python input callback");
86948da90bc4a3809728d08ee9ee8da21d044fbca82Alexey Neyman	    return(NULL);
87048da90bc4a3809728d08ee9ee8da21d044fbca82Alexey Neyman	}
87148da90bc4a3809728d08ee9ee8da21d044fbca82Alexey Neyman    } else if (ret == -1) {
87248da90bc4a3809728d08ee9ee8da21d044fbca82Alexey Neyman	/* No more callbacks to pop */
87348da90bc4a3809728d08ee9ee8da21d044fbca82Alexey Neyman	PyErr_SetString(PyExc_IndexError, "no input callbacks to pop");
87448da90bc4a3809728d08ee9ee8da21d044fbca82Alexey Neyman	return(NULL);
87548da90bc4a3809728d08ee9ee8da21d044fbca82Alexey Neyman    }
87648da90bc4a3809728d08ee9ee8da21d044fbca82Alexey Neyman
87748da90bc4a3809728d08ee9ee8da21d044fbca82Alexey Neyman    Py_INCREF(Py_None);
87848da90bc4a3809728d08ee9ee8da21d044fbca82Alexey Neyman    return(Py_None);
87948da90bc4a3809728d08ee9ee8da21d044fbca82Alexey Neyman}
880c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard
881c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard/************************************************************************
882c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard *									*
8833ce5257b293ed75d8feb18ed7ab18ea2b52510bdDaniel Veillard *		Handling SAX/xmllib/sgmlop callback interfaces		*
884d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard *									*
885d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard ************************************************************************/
8861971ee2698cb84c7699c96d3302f00e20d42c0d3Daniel Veillard
88733caa0b8307eccf22010400747830b1967edb292Daniel Veillardstatic void
88833caa0b8307eccf22010400747830b1967edb292Daniel VeillardpythonStartElement(void *user_data, const xmlChar * name,
88933caa0b8307eccf22010400747830b1967edb292Daniel Veillard                   const xmlChar ** attrs)
89033caa0b8307eccf22010400747830b1967edb292Daniel Veillard{
89133caa0b8307eccf22010400747830b1967edb292Daniel Veillard    int i;
89233caa0b8307eccf22010400747830b1967edb292Daniel Veillard    PyObject *handler;
89333caa0b8307eccf22010400747830b1967edb292Daniel Veillard    PyObject *dict;
89433caa0b8307eccf22010400747830b1967edb292Daniel Veillard    PyObject *attrname;
89533caa0b8307eccf22010400747830b1967edb292Daniel Veillard    PyObject *attrvalue;
896d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard    PyObject *result = NULL;
89733caa0b8307eccf22010400747830b1967edb292Daniel Veillard    int type = 0;
89833caa0b8307eccf22010400747830b1967edb292Daniel Veillard
899797a565a2f6a2c0a8480670174e9eaef30d271a4Daniel Veillard#ifdef DEBUG_SAX
900797a565a2f6a2c0a8480670174e9eaef30d271a4Daniel Veillard    printf("pythonStartElement(%s) called\n", name);
901797a565a2f6a2c0a8480670174e9eaef30d271a4Daniel Veillard#endif
90233caa0b8307eccf22010400747830b1967edb292Daniel Veillard    handler = (PyObject *) user_data;
903d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard    if (PyObject_HasAttrString(handler, (char *) "startElement"))
90433caa0b8307eccf22010400747830b1967edb292Daniel Veillard        type = 1;
905d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard    else if (PyObject_HasAttrString(handler, (char *) "start"))
90633caa0b8307eccf22010400747830b1967edb292Daniel Veillard        type = 2;
90733caa0b8307eccf22010400747830b1967edb292Daniel Veillard    if (type != 0) {
90833caa0b8307eccf22010400747830b1967edb292Daniel Veillard        /*
90933caa0b8307eccf22010400747830b1967edb292Daniel Veillard         * the xmllib interface always generate a dictionnary,
91033caa0b8307eccf22010400747830b1967edb292Daniel Veillard         * possibly empty
91133caa0b8307eccf22010400747830b1967edb292Daniel Veillard         */
91233caa0b8307eccf22010400747830b1967edb292Daniel Veillard        if ((attrs == NULL) && (type == 1)) {
91333caa0b8307eccf22010400747830b1967edb292Daniel Veillard            Py_XINCREF(Py_None);
91433caa0b8307eccf22010400747830b1967edb292Daniel Veillard            dict = Py_None;
915d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        } else if (attrs == NULL) {
916d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            dict = PyDict_New();
91733caa0b8307eccf22010400747830b1967edb292Daniel Veillard        } else {
91833caa0b8307eccf22010400747830b1967edb292Daniel Veillard            dict = PyDict_New();
91933caa0b8307eccf22010400747830b1967edb292Daniel Veillard            for (i = 0; attrs[i] != NULL; i++) {
9203798c4adbb91f80bef1e9f1b4b61dae72577a244Daniel Veillard                attrname = PY_IMPORT_STRING((char *) attrs[i]);
92133caa0b8307eccf22010400747830b1967edb292Daniel Veillard                i++;
92233caa0b8307eccf22010400747830b1967edb292Daniel Veillard                if (attrs[i] != NULL) {
9233798c4adbb91f80bef1e9f1b4b61dae72577a244Daniel Veillard                    attrvalue = PY_IMPORT_STRING((char *) attrs[i]);
92433caa0b8307eccf22010400747830b1967edb292Daniel Veillard                } else {
92533caa0b8307eccf22010400747830b1967edb292Daniel Veillard                    Py_XINCREF(Py_None);
92633caa0b8307eccf22010400747830b1967edb292Daniel Veillard                    attrvalue = Py_None;
92733caa0b8307eccf22010400747830b1967edb292Daniel Veillard                }
92833caa0b8307eccf22010400747830b1967edb292Daniel Veillard                PyDict_SetItem(dict, attrname, attrvalue);
929a3d230513c3f28dc475ee09ffd6787762da07d56Daniel Veillard		Py_DECREF(attrname);
930a3d230513c3f28dc475ee09ffd6787762da07d56Daniel Veillard		Py_DECREF(attrvalue);
93133caa0b8307eccf22010400747830b1967edb292Daniel Veillard            }
93233caa0b8307eccf22010400747830b1967edb292Daniel Veillard        }
93333caa0b8307eccf22010400747830b1967edb292Daniel Veillard
93433caa0b8307eccf22010400747830b1967edb292Daniel Veillard        if (type == 1)
935d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            result = PyObject_CallMethod(handler, (char *) "startElement",
936d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard                                         (char *) "sO", name, dict);
93733caa0b8307eccf22010400747830b1967edb292Daniel Veillard        else if (type == 2)
938d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            result = PyObject_CallMethod(handler, (char *) "start",
939d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard                                         (char *) "sO", name, dict);
940d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        if (PyErr_Occurred())
941d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            PyErr_Print();
94233caa0b8307eccf22010400747830b1967edb292Daniel Veillard        Py_XDECREF(dict);
94333caa0b8307eccf22010400747830b1967edb292Daniel Veillard        Py_XDECREF(result);
94433caa0b8307eccf22010400747830b1967edb292Daniel Veillard    }
94533caa0b8307eccf22010400747830b1967edb292Daniel Veillard}
94633caa0b8307eccf22010400747830b1967edb292Daniel Veillard
94733caa0b8307eccf22010400747830b1967edb292Daniel Veillardstatic void
94833caa0b8307eccf22010400747830b1967edb292Daniel VeillardpythonStartDocument(void *user_data)
94933caa0b8307eccf22010400747830b1967edb292Daniel Veillard{
95033caa0b8307eccf22010400747830b1967edb292Daniel Veillard    PyObject *handler;
95133caa0b8307eccf22010400747830b1967edb292Daniel Veillard    PyObject *result;
95233caa0b8307eccf22010400747830b1967edb292Daniel Veillard
953797a565a2f6a2c0a8480670174e9eaef30d271a4Daniel Veillard#ifdef DEBUG_SAX
954797a565a2f6a2c0a8480670174e9eaef30d271a4Daniel Veillard    printf("pythonStartDocument() called\n");
955797a565a2f6a2c0a8480670174e9eaef30d271a4Daniel Veillard#endif
95633caa0b8307eccf22010400747830b1967edb292Daniel Veillard    handler = (PyObject *) user_data;
957d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard    if (PyObject_HasAttrString(handler, (char *) "startDocument")) {
958d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        result =
959d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            PyObject_CallMethod(handler, (char *) "startDocument", NULL);
960d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        if (PyErr_Occurred())
961d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            PyErr_Print();
96233caa0b8307eccf22010400747830b1967edb292Daniel Veillard        Py_XDECREF(result);
96333caa0b8307eccf22010400747830b1967edb292Daniel Veillard    }
96433caa0b8307eccf22010400747830b1967edb292Daniel Veillard}
96533caa0b8307eccf22010400747830b1967edb292Daniel Veillard
96633caa0b8307eccf22010400747830b1967edb292Daniel Veillardstatic void
96733caa0b8307eccf22010400747830b1967edb292Daniel VeillardpythonEndDocument(void *user_data)
96833caa0b8307eccf22010400747830b1967edb292Daniel Veillard{
96933caa0b8307eccf22010400747830b1967edb292Daniel Veillard    PyObject *handler;
97033caa0b8307eccf22010400747830b1967edb292Daniel Veillard    PyObject *result;
97133caa0b8307eccf22010400747830b1967edb292Daniel Veillard
972797a565a2f6a2c0a8480670174e9eaef30d271a4Daniel Veillard#ifdef DEBUG_SAX
973797a565a2f6a2c0a8480670174e9eaef30d271a4Daniel Veillard    printf("pythonEndDocument() called\n");
974797a565a2f6a2c0a8480670174e9eaef30d271a4Daniel Veillard#endif
97533caa0b8307eccf22010400747830b1967edb292Daniel Veillard    handler = (PyObject *) user_data;
976d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard    if (PyObject_HasAttrString(handler, (char *) "endDocument")) {
977d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        result =
978d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            PyObject_CallMethod(handler, (char *) "endDocument", NULL);
979d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        if (PyErr_Occurred())
980d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            PyErr_Print();
98133caa0b8307eccf22010400747830b1967edb292Daniel Veillard        Py_XDECREF(result);
98233caa0b8307eccf22010400747830b1967edb292Daniel Veillard    }
98333caa0b8307eccf22010400747830b1967edb292Daniel Veillard    /*
98433caa0b8307eccf22010400747830b1967edb292Daniel Veillard     * The reference to the handler is released there
98533caa0b8307eccf22010400747830b1967edb292Daniel Veillard     */
98633caa0b8307eccf22010400747830b1967edb292Daniel Veillard    Py_XDECREF(handler);
98733caa0b8307eccf22010400747830b1967edb292Daniel Veillard}
98833caa0b8307eccf22010400747830b1967edb292Daniel Veillard
98933caa0b8307eccf22010400747830b1967edb292Daniel Veillardstatic void
99033caa0b8307eccf22010400747830b1967edb292Daniel VeillardpythonEndElement(void *user_data, const xmlChar * name)
99133caa0b8307eccf22010400747830b1967edb292Daniel Veillard{
99233caa0b8307eccf22010400747830b1967edb292Daniel Veillard    PyObject *handler;
99333caa0b8307eccf22010400747830b1967edb292Daniel Veillard    PyObject *result;
99433caa0b8307eccf22010400747830b1967edb292Daniel Veillard
995797a565a2f6a2c0a8480670174e9eaef30d271a4Daniel Veillard#ifdef DEBUG_SAX
996797a565a2f6a2c0a8480670174e9eaef30d271a4Daniel Veillard    printf("pythonEndElement(%s) called\n", name);
997797a565a2f6a2c0a8480670174e9eaef30d271a4Daniel Veillard#endif
99833caa0b8307eccf22010400747830b1967edb292Daniel Veillard    handler = (PyObject *) user_data;
999d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard    if (PyObject_HasAttrString(handler, (char *) "endElement")) {
1000d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        result = PyObject_CallMethod(handler, (char *) "endElement",
1001d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard                                     (char *) "s", name);
1002d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        if (PyErr_Occurred())
1003d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            PyErr_Print();
100433caa0b8307eccf22010400747830b1967edb292Daniel Veillard        Py_XDECREF(result);
1005d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard    } else if (PyObject_HasAttrString(handler, (char *) "end")) {
1006d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        result = PyObject_CallMethod(handler, (char *) "end",
1007d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard                                     (char *) "s", name);
1008d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        if (PyErr_Occurred())
1009d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            PyErr_Print();
1010797a565a2f6a2c0a8480670174e9eaef30d271a4Daniel Veillard        Py_XDECREF(result);
101133caa0b8307eccf22010400747830b1967edb292Daniel Veillard    }
101233caa0b8307eccf22010400747830b1967edb292Daniel Veillard}
101333caa0b8307eccf22010400747830b1967edb292Daniel Veillard
101433caa0b8307eccf22010400747830b1967edb292Daniel Veillardstatic void
101533caa0b8307eccf22010400747830b1967edb292Daniel VeillardpythonReference(void *user_data, const xmlChar * name)
101633caa0b8307eccf22010400747830b1967edb292Daniel Veillard{
101733caa0b8307eccf22010400747830b1967edb292Daniel Veillard    PyObject *handler;
101833caa0b8307eccf22010400747830b1967edb292Daniel Veillard    PyObject *result;
101933caa0b8307eccf22010400747830b1967edb292Daniel Veillard
1020797a565a2f6a2c0a8480670174e9eaef30d271a4Daniel Veillard#ifdef DEBUG_SAX
1021797a565a2f6a2c0a8480670174e9eaef30d271a4Daniel Veillard    printf("pythonReference(%s) called\n", name);
1022797a565a2f6a2c0a8480670174e9eaef30d271a4Daniel Veillard#endif
102333caa0b8307eccf22010400747830b1967edb292Daniel Veillard    handler = (PyObject *) user_data;
1024d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard    if (PyObject_HasAttrString(handler, (char *) "reference")) {
1025d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        result = PyObject_CallMethod(handler, (char *) "reference",
1026d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard                                     (char *) "s", name);
1027d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        if (PyErr_Occurred())
1028d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            PyErr_Print();
102933caa0b8307eccf22010400747830b1967edb292Daniel Veillard        Py_XDECREF(result);
103033caa0b8307eccf22010400747830b1967edb292Daniel Veillard    }
103133caa0b8307eccf22010400747830b1967edb292Daniel Veillard}
103233caa0b8307eccf22010400747830b1967edb292Daniel Veillard
103333caa0b8307eccf22010400747830b1967edb292Daniel Veillardstatic void
103433caa0b8307eccf22010400747830b1967edb292Daniel VeillardpythonCharacters(void *user_data, const xmlChar * ch, int len)
103533caa0b8307eccf22010400747830b1967edb292Daniel Veillard{
103633caa0b8307eccf22010400747830b1967edb292Daniel Veillard    PyObject *handler;
1037d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard    PyObject *result = NULL;
103833caa0b8307eccf22010400747830b1967edb292Daniel Veillard    int type = 0;
103933caa0b8307eccf22010400747830b1967edb292Daniel Veillard
1040797a565a2f6a2c0a8480670174e9eaef30d271a4Daniel Veillard#ifdef DEBUG_SAX
1041797a565a2f6a2c0a8480670174e9eaef30d271a4Daniel Veillard    printf("pythonCharacters(%s, %d) called\n", ch, len);
1042797a565a2f6a2c0a8480670174e9eaef30d271a4Daniel Veillard#endif
104333caa0b8307eccf22010400747830b1967edb292Daniel Veillard    handler = (PyObject *) user_data;
1044d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard    if (PyObject_HasAttrString(handler, (char *) "characters"))
1045d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        type = 1;
1046d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard    else if (PyObject_HasAttrString(handler, (char *) "data"))
1047d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        type = 2;
104833caa0b8307eccf22010400747830b1967edb292Daniel Veillard    if (type != 0) {
1049d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        if (type == 1)
1050d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            result = PyObject_CallMethod(handler, (char *) "characters",
1051d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard                                         (char *) "s#", ch, len);
1052d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        else if (type == 2)
1053d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            result = PyObject_CallMethod(handler, (char *) "data",
1054d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard                                         (char *) "s#", ch, len);
1055d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        if (PyErr_Occurred())
1056d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            PyErr_Print();
105733caa0b8307eccf22010400747830b1967edb292Daniel Veillard        Py_XDECREF(result);
105833caa0b8307eccf22010400747830b1967edb292Daniel Veillard    }
105933caa0b8307eccf22010400747830b1967edb292Daniel Veillard}
106033caa0b8307eccf22010400747830b1967edb292Daniel Veillard
106133caa0b8307eccf22010400747830b1967edb292Daniel Veillardstatic void
106233caa0b8307eccf22010400747830b1967edb292Daniel VeillardpythonIgnorableWhitespace(void *user_data, const xmlChar * ch, int len)
106333caa0b8307eccf22010400747830b1967edb292Daniel Veillard{
106433caa0b8307eccf22010400747830b1967edb292Daniel Veillard    PyObject *handler;
1065d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard    PyObject *result = NULL;
106633caa0b8307eccf22010400747830b1967edb292Daniel Veillard    int type = 0;
106733caa0b8307eccf22010400747830b1967edb292Daniel Veillard
1068797a565a2f6a2c0a8480670174e9eaef30d271a4Daniel Veillard#ifdef DEBUG_SAX
1069797a565a2f6a2c0a8480670174e9eaef30d271a4Daniel Veillard    printf("pythonIgnorableWhitespace(%s, %d) called\n", ch, len);
1070797a565a2f6a2c0a8480670174e9eaef30d271a4Daniel Veillard#endif
107133caa0b8307eccf22010400747830b1967edb292Daniel Veillard    handler = (PyObject *) user_data;
1072d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard    if (PyObject_HasAttrString(handler, (char *) "ignorableWhitespace"))
107333caa0b8307eccf22010400747830b1967edb292Daniel Veillard        type = 1;
1074d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard    else if (PyObject_HasAttrString(handler, (char *) "data"))
107533caa0b8307eccf22010400747830b1967edb292Daniel Veillard        type = 2;
107633caa0b8307eccf22010400747830b1967edb292Daniel Veillard    if (type != 0) {
107733caa0b8307eccf22010400747830b1967edb292Daniel Veillard        if (type == 1)
107833caa0b8307eccf22010400747830b1967edb292Daniel Veillard            result =
1079d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard                PyObject_CallMethod(handler,
1080d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard                                    (char *) "ignorableWhitespace",
1081d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard                                    (char *) "s#", ch, len);
108233caa0b8307eccf22010400747830b1967edb292Daniel Veillard        else if (type == 2)
1083d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            result =
1084d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard                PyObject_CallMethod(handler, (char *) "data",
1085d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard                                    (char *) "s#", ch, len);
108633caa0b8307eccf22010400747830b1967edb292Daniel Veillard        Py_XDECREF(result);
108733caa0b8307eccf22010400747830b1967edb292Daniel Veillard    }
108833caa0b8307eccf22010400747830b1967edb292Daniel Veillard}
108933caa0b8307eccf22010400747830b1967edb292Daniel Veillard
109033caa0b8307eccf22010400747830b1967edb292Daniel Veillardstatic void
109133caa0b8307eccf22010400747830b1967edb292Daniel VeillardpythonProcessingInstruction(void *user_data,
109233caa0b8307eccf22010400747830b1967edb292Daniel Veillard                            const xmlChar * target, const xmlChar * data)
109333caa0b8307eccf22010400747830b1967edb292Daniel Veillard{
109433caa0b8307eccf22010400747830b1967edb292Daniel Veillard    PyObject *handler;
109533caa0b8307eccf22010400747830b1967edb292Daniel Veillard    PyObject *result;
109633caa0b8307eccf22010400747830b1967edb292Daniel Veillard
1097797a565a2f6a2c0a8480670174e9eaef30d271a4Daniel Veillard#ifdef DEBUG_SAX
1098797a565a2f6a2c0a8480670174e9eaef30d271a4Daniel Veillard    printf("pythonProcessingInstruction(%s, %s) called\n", target, data);
1099797a565a2f6a2c0a8480670174e9eaef30d271a4Daniel Veillard#endif
110033caa0b8307eccf22010400747830b1967edb292Daniel Veillard    handler = (PyObject *) user_data;
1101d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard    if (PyObject_HasAttrString(handler, (char *) "processingInstruction")) {
1102d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        result = PyObject_CallMethod(handler, (char *)
1103d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard                                     "processingInstruction",
1104d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard                                     (char *) "ss", target, data);
110533caa0b8307eccf22010400747830b1967edb292Daniel Veillard        Py_XDECREF(result);
110633caa0b8307eccf22010400747830b1967edb292Daniel Veillard    }
110733caa0b8307eccf22010400747830b1967edb292Daniel Veillard}
110833caa0b8307eccf22010400747830b1967edb292Daniel Veillard
110933caa0b8307eccf22010400747830b1967edb292Daniel Veillardstatic void
111033caa0b8307eccf22010400747830b1967edb292Daniel VeillardpythonComment(void *user_data, const xmlChar * value)
111133caa0b8307eccf22010400747830b1967edb292Daniel Veillard{
111233caa0b8307eccf22010400747830b1967edb292Daniel Veillard    PyObject *handler;
111333caa0b8307eccf22010400747830b1967edb292Daniel Veillard    PyObject *result;
111433caa0b8307eccf22010400747830b1967edb292Daniel Veillard
1115797a565a2f6a2c0a8480670174e9eaef30d271a4Daniel Veillard#ifdef DEBUG_SAX
1116797a565a2f6a2c0a8480670174e9eaef30d271a4Daniel Veillard    printf("pythonComment(%s) called\n", value);
1117797a565a2f6a2c0a8480670174e9eaef30d271a4Daniel Veillard#endif
111833caa0b8307eccf22010400747830b1967edb292Daniel Veillard    handler = (PyObject *) user_data;
1119d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard    if (PyObject_HasAttrString(handler, (char *) "comment")) {
1120d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        result =
1121d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            PyObject_CallMethod(handler, (char *) "comment", (char *) "s",
1122d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard                                value);
1123d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        if (PyErr_Occurred())
1124d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            PyErr_Print();
112533caa0b8307eccf22010400747830b1967edb292Daniel Veillard        Py_XDECREF(result);
112633caa0b8307eccf22010400747830b1967edb292Daniel Veillard    }
112733caa0b8307eccf22010400747830b1967edb292Daniel Veillard}
112833caa0b8307eccf22010400747830b1967edb292Daniel Veillard
112933caa0b8307eccf22010400747830b1967edb292Daniel Veillardstatic void
113033caa0b8307eccf22010400747830b1967edb292Daniel VeillardpythonWarning(void *user_data, const char *msg, ...)
113133caa0b8307eccf22010400747830b1967edb292Daniel Veillard{
113233caa0b8307eccf22010400747830b1967edb292Daniel Veillard    PyObject *handler;
113333caa0b8307eccf22010400747830b1967edb292Daniel Veillard    PyObject *result;
113433caa0b8307eccf22010400747830b1967edb292Daniel Veillard    va_list args;
113533caa0b8307eccf22010400747830b1967edb292Daniel Veillard    char buf[1024];
113633caa0b8307eccf22010400747830b1967edb292Daniel Veillard
1137797a565a2f6a2c0a8480670174e9eaef30d271a4Daniel Veillard#ifdef DEBUG_SAX
1138797a565a2f6a2c0a8480670174e9eaef30d271a4Daniel Veillard    printf("pythonWarning(%s) called\n", msg);
1139797a565a2f6a2c0a8480670174e9eaef30d271a4Daniel Veillard#endif
114033caa0b8307eccf22010400747830b1967edb292Daniel Veillard    handler = (PyObject *) user_data;
1141d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard    if (PyObject_HasAttrString(handler, (char *) "warning")) {
114233caa0b8307eccf22010400747830b1967edb292Daniel Veillard        va_start(args, msg);
114333caa0b8307eccf22010400747830b1967edb292Daniel Veillard        vsnprintf(buf, 1023, msg, args);
1144d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        va_end(args);
1145d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        buf[1023] = 0;
1146d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        result =
1147d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            PyObject_CallMethod(handler, (char *) "warning", (char *) "s",
1148d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard                                buf);
1149d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        if (PyErr_Occurred())
1150d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            PyErr_Print();
115133caa0b8307eccf22010400747830b1967edb292Daniel Veillard        Py_XDECREF(result);
115233caa0b8307eccf22010400747830b1967edb292Daniel Veillard    }
115333caa0b8307eccf22010400747830b1967edb292Daniel Veillard}
115433caa0b8307eccf22010400747830b1967edb292Daniel Veillard
115533caa0b8307eccf22010400747830b1967edb292Daniel Veillardstatic void
115633caa0b8307eccf22010400747830b1967edb292Daniel VeillardpythonError(void *user_data, const char *msg, ...)
115733caa0b8307eccf22010400747830b1967edb292Daniel Veillard{
115833caa0b8307eccf22010400747830b1967edb292Daniel Veillard    PyObject *handler;
115933caa0b8307eccf22010400747830b1967edb292Daniel Veillard    PyObject *result;
116033caa0b8307eccf22010400747830b1967edb292Daniel Veillard    va_list args;
116133caa0b8307eccf22010400747830b1967edb292Daniel Veillard    char buf[1024];
116233caa0b8307eccf22010400747830b1967edb292Daniel Veillard
1163797a565a2f6a2c0a8480670174e9eaef30d271a4Daniel Veillard#ifdef DEBUG_SAX
1164797a565a2f6a2c0a8480670174e9eaef30d271a4Daniel Veillard    printf("pythonError(%s) called\n", msg);
1165797a565a2f6a2c0a8480670174e9eaef30d271a4Daniel Veillard#endif
116633caa0b8307eccf22010400747830b1967edb292Daniel Veillard    handler = (PyObject *) user_data;
1167d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard    if (PyObject_HasAttrString(handler, (char *) "error")) {
116833caa0b8307eccf22010400747830b1967edb292Daniel Veillard        va_start(args, msg);
116933caa0b8307eccf22010400747830b1967edb292Daniel Veillard        vsnprintf(buf, 1023, msg, args);
1170d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        va_end(args);
1171d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        buf[1023] = 0;
1172d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        result =
1173d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            PyObject_CallMethod(handler, (char *) "error", (char *) "s",
1174d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard                                buf);
1175d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        if (PyErr_Occurred())
1176d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            PyErr_Print();
117733caa0b8307eccf22010400747830b1967edb292Daniel Veillard        Py_XDECREF(result);
117833caa0b8307eccf22010400747830b1967edb292Daniel Veillard    }
117933caa0b8307eccf22010400747830b1967edb292Daniel Veillard}
118033caa0b8307eccf22010400747830b1967edb292Daniel Veillard
118133caa0b8307eccf22010400747830b1967edb292Daniel Veillardstatic void
118233caa0b8307eccf22010400747830b1967edb292Daniel VeillardpythonFatalError(void *user_data, const char *msg, ...)
118333caa0b8307eccf22010400747830b1967edb292Daniel Veillard{
118433caa0b8307eccf22010400747830b1967edb292Daniel Veillard    PyObject *handler;
118533caa0b8307eccf22010400747830b1967edb292Daniel Veillard    PyObject *result;
118633caa0b8307eccf22010400747830b1967edb292Daniel Veillard    va_list args;
118733caa0b8307eccf22010400747830b1967edb292Daniel Veillard    char buf[1024];
118833caa0b8307eccf22010400747830b1967edb292Daniel Veillard
1189797a565a2f6a2c0a8480670174e9eaef30d271a4Daniel Veillard#ifdef DEBUG_SAX
1190797a565a2f6a2c0a8480670174e9eaef30d271a4Daniel Veillard    printf("pythonFatalError(%s) called\n", msg);
1191797a565a2f6a2c0a8480670174e9eaef30d271a4Daniel Veillard#endif
119233caa0b8307eccf22010400747830b1967edb292Daniel Veillard    handler = (PyObject *) user_data;
1193d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard    if (PyObject_HasAttrString(handler, (char *) "fatalError")) {
119433caa0b8307eccf22010400747830b1967edb292Daniel Veillard        va_start(args, msg);
119533caa0b8307eccf22010400747830b1967edb292Daniel Veillard        vsnprintf(buf, 1023, msg, args);
1196d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        va_end(args);
1197d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        buf[1023] = 0;
1198d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        result =
1199d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            PyObject_CallMethod(handler, (char *) "fatalError",
1200d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard                                (char *) "s", buf);
1201d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        if (PyErr_Occurred())
1202d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            PyErr_Print();
120333caa0b8307eccf22010400747830b1967edb292Daniel Veillard        Py_XDECREF(result);
120433caa0b8307eccf22010400747830b1967edb292Daniel Veillard    }
120533caa0b8307eccf22010400747830b1967edb292Daniel Veillard}
120633caa0b8307eccf22010400747830b1967edb292Daniel Veillard
120733caa0b8307eccf22010400747830b1967edb292Daniel Veillardstatic void
120833caa0b8307eccf22010400747830b1967edb292Daniel VeillardpythonCdataBlock(void *user_data, const xmlChar * ch, int len)
120933caa0b8307eccf22010400747830b1967edb292Daniel Veillard{
121033caa0b8307eccf22010400747830b1967edb292Daniel Veillard    PyObject *handler;
1211d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard    PyObject *result = NULL;
121233caa0b8307eccf22010400747830b1967edb292Daniel Veillard    int type = 0;
121333caa0b8307eccf22010400747830b1967edb292Daniel Veillard
1214797a565a2f6a2c0a8480670174e9eaef30d271a4Daniel Veillard#ifdef DEBUG_SAX
1215797a565a2f6a2c0a8480670174e9eaef30d271a4Daniel Veillard    printf("pythonCdataBlock(%s, %d) called\n", ch, len);
1216797a565a2f6a2c0a8480670174e9eaef30d271a4Daniel Veillard#endif
121733caa0b8307eccf22010400747830b1967edb292Daniel Veillard    handler = (PyObject *) user_data;
1218d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard    if (PyObject_HasAttrString(handler, (char *) "cdataBlock"))
1219d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        type = 1;
1220d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard    else if (PyObject_HasAttrString(handler, (char *) "cdata"))
1221d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        type = 2;
122233caa0b8307eccf22010400747830b1967edb292Daniel Veillard    if (type != 0) {
1223d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        if (type == 1)
1224d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            result =
1225d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard                PyObject_CallMethod(handler, (char *) "cdataBlock",
1226d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard                                    (char *) "s#", ch, len);
1227d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        else if (type == 2)
1228d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            result =
1229d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard                PyObject_CallMethod(handler, (char *) "cdata",
1230d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard                                    (char *) "s#", ch, len);
1231d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        if (PyErr_Occurred())
1232d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            PyErr_Print();
123333caa0b8307eccf22010400747830b1967edb292Daniel Veillard        Py_XDECREF(result);
123433caa0b8307eccf22010400747830b1967edb292Daniel Veillard    }
123533caa0b8307eccf22010400747830b1967edb292Daniel Veillard}
123633caa0b8307eccf22010400747830b1967edb292Daniel Veillard
123733caa0b8307eccf22010400747830b1967edb292Daniel Veillardstatic void
123833caa0b8307eccf22010400747830b1967edb292Daniel VeillardpythonExternalSubset(void *user_data,
123933caa0b8307eccf22010400747830b1967edb292Daniel Veillard                     const xmlChar * name,
124033caa0b8307eccf22010400747830b1967edb292Daniel Veillard                     const xmlChar * externalID, const xmlChar * systemID)
124133caa0b8307eccf22010400747830b1967edb292Daniel Veillard{
124233caa0b8307eccf22010400747830b1967edb292Daniel Veillard    PyObject *handler;
124333caa0b8307eccf22010400747830b1967edb292Daniel Veillard    PyObject *result;
124433caa0b8307eccf22010400747830b1967edb292Daniel Veillard
1245797a565a2f6a2c0a8480670174e9eaef30d271a4Daniel Veillard#ifdef DEBUG_SAX
1246797a565a2f6a2c0a8480670174e9eaef30d271a4Daniel Veillard    printf("pythonExternalSubset(%s, %s, %s) called\n",
1247d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard           name, externalID, systemID);
1248797a565a2f6a2c0a8480670174e9eaef30d271a4Daniel Veillard#endif
124933caa0b8307eccf22010400747830b1967edb292Daniel Veillard    handler = (PyObject *) user_data;
1250d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard    if (PyObject_HasAttrString(handler, (char *) "externalSubset")) {
125133caa0b8307eccf22010400747830b1967edb292Daniel Veillard        result =
1252d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            PyObject_CallMethod(handler, (char *) "externalSubset",
1253d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard                                (char *) "sss", name, externalID,
1254d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard                                systemID);
125533caa0b8307eccf22010400747830b1967edb292Daniel Veillard        Py_XDECREF(result);
125633caa0b8307eccf22010400747830b1967edb292Daniel Veillard    }
125733caa0b8307eccf22010400747830b1967edb292Daniel Veillard}
125833caa0b8307eccf22010400747830b1967edb292Daniel Veillard
125933caa0b8307eccf22010400747830b1967edb292Daniel Veillardstatic void
126033caa0b8307eccf22010400747830b1967edb292Daniel VeillardpythonEntityDecl(void *user_data,
126133caa0b8307eccf22010400747830b1967edb292Daniel Veillard                 const xmlChar * name,
126233caa0b8307eccf22010400747830b1967edb292Daniel Veillard                 int type,
126333caa0b8307eccf22010400747830b1967edb292Daniel Veillard                 const xmlChar * publicId,
126433caa0b8307eccf22010400747830b1967edb292Daniel Veillard                 const xmlChar * systemId, xmlChar * content)
126533caa0b8307eccf22010400747830b1967edb292Daniel Veillard{
126633caa0b8307eccf22010400747830b1967edb292Daniel Veillard    PyObject *handler;
126733caa0b8307eccf22010400747830b1967edb292Daniel Veillard    PyObject *result;
126833caa0b8307eccf22010400747830b1967edb292Daniel Veillard
126933caa0b8307eccf22010400747830b1967edb292Daniel Veillard    handler = (PyObject *) user_data;
1270d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard    if (PyObject_HasAttrString(handler, (char *) "entityDecl")) {
1271d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        result = PyObject_CallMethod(handler, (char *) "entityDecl",
1272d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard                                     (char *) "sisss", name, type,
1273d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard                                     publicId, systemId, content);
1274d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        if (PyErr_Occurred())
1275d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            PyErr_Print();
127633caa0b8307eccf22010400747830b1967edb292Daniel Veillard        Py_XDECREF(result);
127733caa0b8307eccf22010400747830b1967edb292Daniel Veillard    }
127833caa0b8307eccf22010400747830b1967edb292Daniel Veillard}
127933caa0b8307eccf22010400747830b1967edb292Daniel Veillard
128033caa0b8307eccf22010400747830b1967edb292Daniel Veillard
128133caa0b8307eccf22010400747830b1967edb292Daniel Veillard
128233caa0b8307eccf22010400747830b1967edb292Daniel Veillardstatic void
128333caa0b8307eccf22010400747830b1967edb292Daniel Veillard
128433caa0b8307eccf22010400747830b1967edb292Daniel VeillardpythonNotationDecl(void *user_data,
128533caa0b8307eccf22010400747830b1967edb292Daniel Veillard                   const xmlChar * name,
128633caa0b8307eccf22010400747830b1967edb292Daniel Veillard                   const xmlChar * publicId, const xmlChar * systemId)
128733caa0b8307eccf22010400747830b1967edb292Daniel Veillard{
128833caa0b8307eccf22010400747830b1967edb292Daniel Veillard    PyObject *handler;
128933caa0b8307eccf22010400747830b1967edb292Daniel Veillard    PyObject *result;
129033caa0b8307eccf22010400747830b1967edb292Daniel Veillard
129133caa0b8307eccf22010400747830b1967edb292Daniel Veillard    handler = (PyObject *) user_data;
1292d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard    if (PyObject_HasAttrString(handler, (char *) "notationDecl")) {
1293d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        result = PyObject_CallMethod(handler, (char *) "notationDecl",
1294d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard                                     (char *) "sss", name, publicId,
1295d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard                                     systemId);
1296d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        if (PyErr_Occurred())
1297d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            PyErr_Print();
129833caa0b8307eccf22010400747830b1967edb292Daniel Veillard        Py_XDECREF(result);
129933caa0b8307eccf22010400747830b1967edb292Daniel Veillard    }
130033caa0b8307eccf22010400747830b1967edb292Daniel Veillard}
130133caa0b8307eccf22010400747830b1967edb292Daniel Veillard
130233caa0b8307eccf22010400747830b1967edb292Daniel Veillardstatic void
130333caa0b8307eccf22010400747830b1967edb292Daniel VeillardpythonAttributeDecl(void *user_data,
130433caa0b8307eccf22010400747830b1967edb292Daniel Veillard                    const xmlChar * elem,
130533caa0b8307eccf22010400747830b1967edb292Daniel Veillard                    const xmlChar * name,
130633caa0b8307eccf22010400747830b1967edb292Daniel Veillard                    int type,
130733caa0b8307eccf22010400747830b1967edb292Daniel Veillard                    int def,
1308d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard                    const xmlChar * defaultValue, xmlEnumerationPtr tree)
130933caa0b8307eccf22010400747830b1967edb292Daniel Veillard{
131033caa0b8307eccf22010400747830b1967edb292Daniel Veillard    PyObject *handler;
131133caa0b8307eccf22010400747830b1967edb292Daniel Veillard    PyObject *nameList;
131233caa0b8307eccf22010400747830b1967edb292Daniel Veillard    PyObject *newName;
131333caa0b8307eccf22010400747830b1967edb292Daniel Veillard    xmlEnumerationPtr node;
131433caa0b8307eccf22010400747830b1967edb292Daniel Veillard    PyObject *result;
131533caa0b8307eccf22010400747830b1967edb292Daniel Veillard    int count;
131633caa0b8307eccf22010400747830b1967edb292Daniel Veillard
131733caa0b8307eccf22010400747830b1967edb292Daniel Veillard    handler = (PyObject *) user_data;
1318d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard    if (PyObject_HasAttrString(handler, (char *) "attributeDecl")) {
131933caa0b8307eccf22010400747830b1967edb292Daniel Veillard        count = 0;
132033caa0b8307eccf22010400747830b1967edb292Daniel Veillard        for (node = tree; node != NULL; node = node->next) {
132133caa0b8307eccf22010400747830b1967edb292Daniel Veillard            count++;
132233caa0b8307eccf22010400747830b1967edb292Daniel Veillard        }
132333caa0b8307eccf22010400747830b1967edb292Daniel Veillard        nameList = PyList_New(count);
132433caa0b8307eccf22010400747830b1967edb292Daniel Veillard        count = 0;
132533caa0b8307eccf22010400747830b1967edb292Daniel Veillard        for (node = tree; node != NULL; node = node->next) {
13263798c4adbb91f80bef1e9f1b4b61dae72577a244Daniel Veillard            newName = PY_IMPORT_STRING((char *) node->name);
132733caa0b8307eccf22010400747830b1967edb292Daniel Veillard            PyList_SetItem(nameList, count, newName);
1328a3d230513c3f28dc475ee09ffd6787762da07d56Daniel Veillard	    Py_DECREF(newName);
132933caa0b8307eccf22010400747830b1967edb292Daniel Veillard            count++;
133033caa0b8307eccf22010400747830b1967edb292Daniel Veillard        }
1331d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        result = PyObject_CallMethod(handler, (char *) "attributeDecl",
1332d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard                                     (char *) "ssiisO", elem, name, type,
1333d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard                                     def, defaultValue, nameList);
1334d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        if (PyErr_Occurred())
1335d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            PyErr_Print();
133633caa0b8307eccf22010400747830b1967edb292Daniel Veillard        Py_XDECREF(nameList);
133733caa0b8307eccf22010400747830b1967edb292Daniel Veillard        Py_XDECREF(result);
133833caa0b8307eccf22010400747830b1967edb292Daniel Veillard    }
133933caa0b8307eccf22010400747830b1967edb292Daniel Veillard}
134033caa0b8307eccf22010400747830b1967edb292Daniel Veillard
134133caa0b8307eccf22010400747830b1967edb292Daniel Veillardstatic void
134233caa0b8307eccf22010400747830b1967edb292Daniel VeillardpythonElementDecl(void *user_data,
134333caa0b8307eccf22010400747830b1967edb292Daniel Veillard                  const xmlChar * name,
1344d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard                  int type, ATTRIBUTE_UNUSED xmlElementContentPtr content)
134533caa0b8307eccf22010400747830b1967edb292Daniel Veillard{
134633caa0b8307eccf22010400747830b1967edb292Daniel Veillard    PyObject *handler;
134733caa0b8307eccf22010400747830b1967edb292Daniel Veillard    PyObject *obj;
134833caa0b8307eccf22010400747830b1967edb292Daniel Veillard    PyObject *result;
134933caa0b8307eccf22010400747830b1967edb292Daniel Veillard
135033caa0b8307eccf22010400747830b1967edb292Daniel Veillard    handler = (PyObject *) user_data;
1351d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard    if (PyObject_HasAttrString(handler, (char *) "elementDecl")) {
1352d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        /* TODO: wrap in an elementContent object */
1353d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        printf
1354d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            ("pythonElementDecl: xmlElementContentPtr wrapper missing !\n");
1355d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        obj = Py_None;
1356d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        /* Py_XINCREF(Py_None); isn't the reference just borrowed ??? */
1357d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        result = PyObject_CallMethod(handler, (char *) "elementDecl",
1358d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard                                     (char *) "siO", name, type, obj);
1359d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        if (PyErr_Occurred())
1360d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            PyErr_Print();
136133caa0b8307eccf22010400747830b1967edb292Daniel Veillard        Py_XDECREF(result);
136233caa0b8307eccf22010400747830b1967edb292Daniel Veillard    }
136333caa0b8307eccf22010400747830b1967edb292Daniel Veillard}
136433caa0b8307eccf22010400747830b1967edb292Daniel Veillard
136533caa0b8307eccf22010400747830b1967edb292Daniel Veillardstatic void
136633caa0b8307eccf22010400747830b1967edb292Daniel VeillardpythonUnparsedEntityDecl(void *user_data,
136733caa0b8307eccf22010400747830b1967edb292Daniel Veillard                         const xmlChar * name,
136833caa0b8307eccf22010400747830b1967edb292Daniel Veillard                         const xmlChar * publicId,
136933caa0b8307eccf22010400747830b1967edb292Daniel Veillard                         const xmlChar * systemId,
137033caa0b8307eccf22010400747830b1967edb292Daniel Veillard                         const xmlChar * notationName)
137133caa0b8307eccf22010400747830b1967edb292Daniel Veillard{
137233caa0b8307eccf22010400747830b1967edb292Daniel Veillard    PyObject *handler;
137333caa0b8307eccf22010400747830b1967edb292Daniel Veillard    PyObject *result;
137433caa0b8307eccf22010400747830b1967edb292Daniel Veillard
137533caa0b8307eccf22010400747830b1967edb292Daniel Veillard    handler = (PyObject *) user_data;
1376d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard    if (PyObject_HasAttrString(handler, (char *) "unparsedEntityDecl")) {
1377d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        result =
1378d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            PyObject_CallMethod(handler, (char *) "unparsedEntityDecl",
1379d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard                                (char *) "ssss", name, publicId, systemId,
1380d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard                                notationName);
1381d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        if (PyErr_Occurred())
1382d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            PyErr_Print();
138333caa0b8307eccf22010400747830b1967edb292Daniel Veillard        Py_XDECREF(result);
138433caa0b8307eccf22010400747830b1967edb292Daniel Veillard    }
138533caa0b8307eccf22010400747830b1967edb292Daniel Veillard}
138633caa0b8307eccf22010400747830b1967edb292Daniel Veillard
138733caa0b8307eccf22010400747830b1967edb292Daniel Veillardstatic void
138833caa0b8307eccf22010400747830b1967edb292Daniel VeillardpythonInternalSubset(void *user_data, const xmlChar * name,
138933caa0b8307eccf22010400747830b1967edb292Daniel Veillard                     const xmlChar * ExternalID, const xmlChar * SystemID)
139033caa0b8307eccf22010400747830b1967edb292Daniel Veillard{
139133caa0b8307eccf22010400747830b1967edb292Daniel Veillard    PyObject *handler;
139233caa0b8307eccf22010400747830b1967edb292Daniel Veillard    PyObject *result;
139333caa0b8307eccf22010400747830b1967edb292Daniel Veillard
1394797a565a2f6a2c0a8480670174e9eaef30d271a4Daniel Veillard#ifdef DEBUG_SAX
1395797a565a2f6a2c0a8480670174e9eaef30d271a4Daniel Veillard    printf("pythonInternalSubset(%s, %s, %s) called\n",
1396d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard           name, ExternalID, SystemID);
1397797a565a2f6a2c0a8480670174e9eaef30d271a4Daniel Veillard#endif
139833caa0b8307eccf22010400747830b1967edb292Daniel Veillard    handler = (PyObject *) user_data;
1399d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard    if (PyObject_HasAttrString(handler, (char *) "internalSubset")) {
1400d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        result = PyObject_CallMethod(handler, (char *) "internalSubset",
1401d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard                                     (char *) "sss", name, ExternalID,
1402d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard                                     SystemID);
1403d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        if (PyErr_Occurred())
1404d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            PyErr_Print();
140533caa0b8307eccf22010400747830b1967edb292Daniel Veillard        Py_XDECREF(result);
140633caa0b8307eccf22010400747830b1967edb292Daniel Veillard    }
140733caa0b8307eccf22010400747830b1967edb292Daniel Veillard}
140833caa0b8307eccf22010400747830b1967edb292Daniel Veillard
140933caa0b8307eccf22010400747830b1967edb292Daniel Veillardstatic xmlSAXHandler pythonSaxHandler = {
141033caa0b8307eccf22010400747830b1967edb292Daniel Veillard    pythonInternalSubset,
1411d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard    NULL,                       /* TODO pythonIsStandalone, */
1412d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard    NULL,                       /* TODO pythonHasInternalSubset, */
1413d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard    NULL,                       /* TODO pythonHasExternalSubset, */
1414d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard    NULL,                       /* TODO pythonResolveEntity, */
1415d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard    NULL,                       /* TODO pythonGetEntity, */
141633caa0b8307eccf22010400747830b1967edb292Daniel Veillard    pythonEntityDecl,
141733caa0b8307eccf22010400747830b1967edb292Daniel Veillard    pythonNotationDecl,
141833caa0b8307eccf22010400747830b1967edb292Daniel Veillard    pythonAttributeDecl,
141933caa0b8307eccf22010400747830b1967edb292Daniel Veillard    pythonElementDecl,
142033caa0b8307eccf22010400747830b1967edb292Daniel Veillard    pythonUnparsedEntityDecl,
1421d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard    NULL,                       /* OBSOLETED pythonSetDocumentLocator, */
142233caa0b8307eccf22010400747830b1967edb292Daniel Veillard    pythonStartDocument,
142333caa0b8307eccf22010400747830b1967edb292Daniel Veillard    pythonEndDocument,
142433caa0b8307eccf22010400747830b1967edb292Daniel Veillard    pythonStartElement,
142533caa0b8307eccf22010400747830b1967edb292Daniel Veillard    pythonEndElement,
142633caa0b8307eccf22010400747830b1967edb292Daniel Veillard    pythonReference,
142733caa0b8307eccf22010400747830b1967edb292Daniel Veillard    pythonCharacters,
142833caa0b8307eccf22010400747830b1967edb292Daniel Veillard    pythonIgnorableWhitespace,
142933caa0b8307eccf22010400747830b1967edb292Daniel Veillard    pythonProcessingInstruction,
143033caa0b8307eccf22010400747830b1967edb292Daniel Veillard    pythonComment,
143133caa0b8307eccf22010400747830b1967edb292Daniel Veillard    pythonWarning,
143233caa0b8307eccf22010400747830b1967edb292Daniel Veillard    pythonError,
143333caa0b8307eccf22010400747830b1967edb292Daniel Veillard    pythonFatalError,
1434d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard    NULL,                       /* TODO pythonGetParameterEntity, */
143533caa0b8307eccf22010400747830b1967edb292Daniel Veillard    pythonCdataBlock,
143633caa0b8307eccf22010400747830b1967edb292Daniel Veillard    pythonExternalSubset,
1437a9cce9cd0d7aff3ec318b5d8d376da131b6aaad4Daniel Veillard    1,
1438a9cce9cd0d7aff3ec318b5d8d376da131b6aaad4Daniel Veillard    NULL,			/* TODO mograte to SAX2 */
1439a9cce9cd0d7aff3ec318b5d8d376da131b6aaad4Daniel Veillard    NULL,
1440871611bb0325095b30559ff1edc1fdaa2ad5fd2fWilliam M. Brack    NULL,
1441a9cce9cd0d7aff3ec318b5d8d376da131b6aaad4Daniel Veillard    NULL
144233caa0b8307eccf22010400747830b1967edb292Daniel Veillard};
1443d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard
14443ce5257b293ed75d8feb18ed7ab18ea2b52510bdDaniel Veillard/************************************************************************
14453ce5257b293ed75d8feb18ed7ab18ea2b52510bdDaniel Veillard *									*
14463ce5257b293ed75d8feb18ed7ab18ea2b52510bdDaniel Veillard *		Handling of specific parser context			*
14473ce5257b293ed75d8feb18ed7ab18ea2b52510bdDaniel Veillard *									*
14483ce5257b293ed75d8feb18ed7ab18ea2b52510bdDaniel Veillard ************************************************************************/
14491971ee2698cb84c7699c96d3302f00e20d42c0d3Daniel Veillard
14501971ee2698cb84c7699c96d3302f00e20d42c0d3Daniel VeillardPyObject *
1451d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillardlibxml_xmlCreatePushParser(ATTRIBUTE_UNUSED PyObject * self,
1452d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard                           PyObject * args)
1453d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard{
1454d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard    const char *chunk;
14553ce5257b293ed75d8feb18ed7ab18ea2b52510bdDaniel Veillard    int size;
1456d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard    const char *URI;
145733caa0b8307eccf22010400747830b1967edb292Daniel Veillard    PyObject *pyobj_SAX = NULL;
14583ce5257b293ed75d8feb18ed7ab18ea2b52510bdDaniel Veillard    xmlSAXHandlerPtr SAX = NULL;
14593ce5257b293ed75d8feb18ed7ab18ea2b52510bdDaniel Veillard    xmlParserCtxtPtr ret;
14603ce5257b293ed75d8feb18ed7ab18ea2b52510bdDaniel Veillard    PyObject *pyret;
14613ce5257b293ed75d8feb18ed7ab18ea2b52510bdDaniel Veillard
1462d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard    if (!PyArg_ParseTuple
1463d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        (args, (char *) "Oziz:xmlCreatePushParser", &pyobj_SAX, &chunk,
1464d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard         &size, &URI))
1465d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        return (NULL);
14661971ee2698cb84c7699c96d3302f00e20d42c0d3Daniel Veillard
14678d24cc189845663509623fbd6b5106cc01266994Daniel Veillard#ifdef DEBUG
14683ce5257b293ed75d8feb18ed7ab18ea2b52510bdDaniel Veillard    printf("libxml_xmlCreatePushParser(%p, %s, %d, %s) called\n",
1469d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard           pyobj_SAX, chunk, size, URI);
14701971ee2698cb84c7699c96d3302f00e20d42c0d3Daniel Veillard#endif
14713ce5257b293ed75d8feb18ed7ab18ea2b52510bdDaniel Veillard    if (pyobj_SAX != Py_None) {
1472d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        SAX = &pythonSaxHandler;
1473d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        Py_INCREF(pyobj_SAX);
1474d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        /* The reference is released in pythonEndDocument() */
14751971ee2698cb84c7699c96d3302f00e20d42c0d3Daniel Veillard    }
147633caa0b8307eccf22010400747830b1967edb292Daniel Veillard    ret = xmlCreatePushParserCtxt(SAX, pyobj_SAX, chunk, size, URI);
14773ce5257b293ed75d8feb18ed7ab18ea2b52510bdDaniel Veillard    pyret = libxml_xmlParserCtxtPtrWrap(ret);
1478d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard    return (pyret);
1479a7340c830e4bddd86201cfdb97ac81e30b0dee62Daniel Veillard}
14805d81903b06418c7d8cc72cf9add81c4026a2f3bcDaniel Veillard
14814e1b26cfeba7f5fad4f8bd12fb5ce7029f930b79Daniel VeillardPyObject *
1482d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillardlibxml_htmlCreatePushParser(ATTRIBUTE_UNUSED PyObject * self,
1483d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard                            PyObject * args)
1484d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard{
1485656ce948ab664ce96298c5f419a03a7ffcc88d9dDaniel Veillard#ifdef LIBXML_HTML_ENABLED
1486d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard    const char *chunk;
14874e1b26cfeba7f5fad4f8bd12fb5ce7029f930b79Daniel Veillard    int size;
1488d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard    const char *URI;
148933caa0b8307eccf22010400747830b1967edb292Daniel Veillard    PyObject *pyobj_SAX = NULL;
14904e1b26cfeba7f5fad4f8bd12fb5ce7029f930b79Daniel Veillard    xmlSAXHandlerPtr SAX = NULL;
14914e1b26cfeba7f5fad4f8bd12fb5ce7029f930b79Daniel Veillard    xmlParserCtxtPtr ret;
14924e1b26cfeba7f5fad4f8bd12fb5ce7029f930b79Daniel Veillard    PyObject *pyret;
14934e1b26cfeba7f5fad4f8bd12fb5ce7029f930b79Daniel Veillard
1494d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard    if (!PyArg_ParseTuple
1495d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        (args, (char *) "Oziz:htmlCreatePushParser", &pyobj_SAX, &chunk,
1496d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard         &size, &URI))
1497d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        return (NULL);
14984e1b26cfeba7f5fad4f8bd12fb5ce7029f930b79Daniel Veillard
14998d24cc189845663509623fbd6b5106cc01266994Daniel Veillard#ifdef DEBUG
15004e1b26cfeba7f5fad4f8bd12fb5ce7029f930b79Daniel Veillard    printf("libxml_htmlCreatePushParser(%p, %s, %d, %s) called\n",
1501d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard           pyobj_SAX, chunk, size, URI);
15024e1b26cfeba7f5fad4f8bd12fb5ce7029f930b79Daniel Veillard#endif
15034e1b26cfeba7f5fad4f8bd12fb5ce7029f930b79Daniel Veillard    if (pyobj_SAX != Py_None) {
1504d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        SAX = &pythonSaxHandler;
1505d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        Py_INCREF(pyobj_SAX);
1506d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        /* The reference is released in pythonEndDocument() */
15074e1b26cfeba7f5fad4f8bd12fb5ce7029f930b79Daniel Veillard    }
150833caa0b8307eccf22010400747830b1967edb292Daniel Veillard    ret = htmlCreatePushParserCtxt(SAX, pyobj_SAX, chunk, size, URI,
1509d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard                                   XML_CHAR_ENCODING_NONE);
15104e1b26cfeba7f5fad4f8bd12fb5ce7029f930b79Daniel Veillard    pyret = libxml_xmlParserCtxtPtrWrap(ret);
1511d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard    return (pyret);
1512656ce948ab664ce96298c5f419a03a7ffcc88d9dDaniel Veillard#else
1513656ce948ab664ce96298c5f419a03a7ffcc88d9dDaniel Veillard    Py_INCREF(Py_None);
1514656ce948ab664ce96298c5f419a03a7ffcc88d9dDaniel Veillard    return (Py_None);
1515656ce948ab664ce96298c5f419a03a7ffcc88d9dDaniel Veillard#endif /* LIBXML_HTML_ENABLED */
15164e1b26cfeba7f5fad4f8bd12fb5ce7029f930b79Daniel Veillard}
15174e1b26cfeba7f5fad4f8bd12fb5ce7029f930b79Daniel Veillard
15188d24cc189845663509623fbd6b5106cc01266994Daniel VeillardPyObject *
1519d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillardlibxml_xmlSAXParseFile(ATTRIBUTE_UNUSED PyObject * self, PyObject * args)
1520d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard{
1521961b535c10c7d07d7919c58c1d0c6762b35503a1Akira TAGOH#ifdef LIBXML_SAX1_ENABLED
15228d24cc189845663509623fbd6b5106cc01266994Daniel Veillard    int recover;
1523d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard    const char *URI;
15248d24cc189845663509623fbd6b5106cc01266994Daniel Veillard    PyObject *pyobj_SAX = NULL;
15258d24cc189845663509623fbd6b5106cc01266994Daniel Veillard    xmlSAXHandlerPtr SAX = NULL;
15268d24cc189845663509623fbd6b5106cc01266994Daniel Veillard
1527d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard    if (!PyArg_ParseTuple(args, (char *) "Osi:xmlSAXParseFile", &pyobj_SAX,
1528d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard                          &URI, &recover))
1529d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        return (NULL);
15308d24cc189845663509623fbd6b5106cc01266994Daniel Veillard
15318d24cc189845663509623fbd6b5106cc01266994Daniel Veillard#ifdef DEBUG
15328d24cc189845663509623fbd6b5106cc01266994Daniel Veillard    printf("libxml_xmlSAXParseFile(%p, %s, %d) called\n",
1533d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard           pyobj_SAX, URI, recover);
15348d24cc189845663509623fbd6b5106cc01266994Daniel Veillard#endif
15358d24cc189845663509623fbd6b5106cc01266994Daniel Veillard    if (pyobj_SAX == Py_None) {
1536d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        Py_INCREF(Py_None);
1537d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        return (Py_None);
15388d24cc189845663509623fbd6b5106cc01266994Daniel Veillard    }
15398d24cc189845663509623fbd6b5106cc01266994Daniel Veillard    SAX = &pythonSaxHandler;
15408d24cc189845663509623fbd6b5106cc01266994Daniel Veillard    Py_INCREF(pyobj_SAX);
15418d24cc189845663509623fbd6b5106cc01266994Daniel Veillard    /* The reference is released in pythonEndDocument() */
1542f2531afe41a2232669302ceb49161d5689971ed9Daniel Veillard    xmlSAXUserParseFile(SAX, pyobj_SAX, URI);
1543961b535c10c7d07d7919c58c1d0c6762b35503a1Akira TAGOH#endif /* LIBXML_SAX1_ENABLED */
15448d24cc189845663509623fbd6b5106cc01266994Daniel Veillard    Py_INCREF(Py_None);
1545d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard    return (Py_None);
15468d24cc189845663509623fbd6b5106cc01266994Daniel Veillard}
15478d24cc189845663509623fbd6b5106cc01266994Daniel Veillard
15488d24cc189845663509623fbd6b5106cc01266994Daniel VeillardPyObject *
1549d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillardlibxml_htmlSAXParseFile(ATTRIBUTE_UNUSED PyObject * self, PyObject * args)
1550d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard{
1551656ce948ab664ce96298c5f419a03a7ffcc88d9dDaniel Veillard#ifdef LIBXML_HTML_ENABLED
1552d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard    const char *URI;
1553d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard    const char *encoding;
15548d24cc189845663509623fbd6b5106cc01266994Daniel Veillard    PyObject *pyobj_SAX = NULL;
15558d24cc189845663509623fbd6b5106cc01266994Daniel Veillard    xmlSAXHandlerPtr SAX = NULL;
15568d24cc189845663509623fbd6b5106cc01266994Daniel Veillard
1557d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard    if (!PyArg_ParseTuple
1558d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        (args, (char *) "Osz:htmlSAXParseFile", &pyobj_SAX, &URI,
1559d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard         &encoding))
1560d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        return (NULL);
15618d24cc189845663509623fbd6b5106cc01266994Daniel Veillard
15628d24cc189845663509623fbd6b5106cc01266994Daniel Veillard#ifdef DEBUG
15638d24cc189845663509623fbd6b5106cc01266994Daniel Veillard    printf("libxml_htmlSAXParseFile(%p, %s, %s) called\n",
1564d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard           pyobj_SAX, URI, encoding);
15658d24cc189845663509623fbd6b5106cc01266994Daniel Veillard#endif
15668d24cc189845663509623fbd6b5106cc01266994Daniel Veillard    if (pyobj_SAX == Py_None) {
1567d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        Py_INCREF(Py_None);
1568d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        return (Py_None);
15698d24cc189845663509623fbd6b5106cc01266994Daniel Veillard    }
15708d24cc189845663509623fbd6b5106cc01266994Daniel Veillard    SAX = &pythonSaxHandler;
15718d24cc189845663509623fbd6b5106cc01266994Daniel Veillard    Py_INCREF(pyobj_SAX);
15728d24cc189845663509623fbd6b5106cc01266994Daniel Veillard    /* The reference is released in pythonEndDocument() */
15738d24cc189845663509623fbd6b5106cc01266994Daniel Veillard    htmlSAXParseFile(URI, encoding, SAX, pyobj_SAX);
15748d24cc189845663509623fbd6b5106cc01266994Daniel Veillard    Py_INCREF(Py_None);
1575d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard    return (Py_None);
1576656ce948ab664ce96298c5f419a03a7ffcc88d9dDaniel Veillard#else
1577656ce948ab664ce96298c5f419a03a7ffcc88d9dDaniel Veillard    Py_INCREF(Py_None);
1578656ce948ab664ce96298c5f419a03a7ffcc88d9dDaniel Veillard    return (Py_None);
1579656ce948ab664ce96298c5f419a03a7ffcc88d9dDaniel Veillard#endif /* LIBXML_HTML_ENABLED */
15808d24cc189845663509623fbd6b5106cc01266994Daniel Veillard}
15818d24cc189845663509623fbd6b5106cc01266994Daniel Veillard
15825d81903b06418c7d8cc72cf9add81c4026a2f3bcDaniel Veillard/************************************************************************
15835d81903b06418c7d8cc72cf9add81c4026a2f3bcDaniel Veillard *									*
15845d81903b06418c7d8cc72cf9add81c4026a2f3bcDaniel Veillard *			Error message callback				*
15855d81903b06418c7d8cc72cf9add81c4026a2f3bcDaniel Veillard *									*
15865d81903b06418c7d8cc72cf9add81c4026a2f3bcDaniel Veillard ************************************************************************/
15875d81903b06418c7d8cc72cf9add81c4026a2f3bcDaniel Veillard
15885d81903b06418c7d8cc72cf9add81c4026a2f3bcDaniel Veillardstatic PyObject *libxml_xmlPythonErrorFuncHandler = NULL;
15895d81903b06418c7d8cc72cf9add81c4026a2f3bcDaniel Veillardstatic PyObject *libxml_xmlPythonErrorFuncCtxt = NULL;
15905d81903b06418c7d8cc72cf9add81c4026a2f3bcDaniel Veillard
1591e6227e0549490b5bf9271ecd2d874a97c3f4852bDaniel Veillard/* helper to build a xmlMalloc'ed string from a format and va_list */
1592ad9fb7c06fea9cf63911c63cc9488ab1d0267005Daniel Veillard/*
1593ad9fb7c06fea9cf63911c63cc9488ab1d0267005Daniel Veillard * disabled the loop, the repeated call to vsnprintf without reset of ap
1594ad9fb7c06fea9cf63911c63cc9488ab1d0267005Daniel Veillard * in case the initial buffer was too small segfaulted on x86_64
1595ad9fb7c06fea9cf63911c63cc9488ab1d0267005Daniel Veillard * we now directly vsnprintf on a large buffer.
1596ad9fb7c06fea9cf63911c63cc9488ab1d0267005Daniel Veillard */
1597e6227e0549490b5bf9271ecd2d874a97c3f4852bDaniel Veillardstatic char *
1598e6227e0549490b5bf9271ecd2d874a97c3f4852bDaniel Veillardlibxml_buildMessage(const char *msg, va_list ap)
1599d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard{
1600d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard    int chars;
1601e6227e0549490b5bf9271ecd2d874a97c3f4852bDaniel Veillard    char *str;
1602e6227e0549490b5bf9271ecd2d874a97c3f4852bDaniel Veillard
1603ad9fb7c06fea9cf63911c63cc9488ab1d0267005Daniel Veillard    str = (char *) xmlMalloc(1000);
1604e6227e0549490b5bf9271ecd2d874a97c3f4852bDaniel Veillard    if (str == NULL)
1605e6227e0549490b5bf9271ecd2d874a97c3f4852bDaniel Veillard        return NULL;
1606e6227e0549490b5bf9271ecd2d874a97c3f4852bDaniel Veillard
1607ad9fb7c06fea9cf63911c63cc9488ab1d0267005Daniel Veillard    chars = vsnprintf(str, 999, msg, ap);
1608ad9fb7c06fea9cf63911c63cc9488ab1d0267005Daniel Veillard    if (chars >= 998)
1609ad9fb7c06fea9cf63911c63cc9488ab1d0267005Daniel Veillard        str[999] = 0;
1610e6227e0549490b5bf9271ecd2d874a97c3f4852bDaniel Veillard
1611e6227e0549490b5bf9271ecd2d874a97c3f4852bDaniel Veillard    return str;
1612e6227e0549490b5bf9271ecd2d874a97c3f4852bDaniel Veillard}
1613e6227e0549490b5bf9271ecd2d874a97c3f4852bDaniel Veillard
1614e6227e0549490b5bf9271ecd2d874a97c3f4852bDaniel Veillardstatic void
1615e6227e0549490b5bf9271ecd2d874a97c3f4852bDaniel Veillardlibxml_xmlErrorFuncHandler(ATTRIBUTE_UNUSED void *ctx, const char *msg,
1616e6227e0549490b5bf9271ecd2d874a97c3f4852bDaniel Veillard                           ...)
1617e6227e0549490b5bf9271ecd2d874a97c3f4852bDaniel Veillard{
1618d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard    va_list ap;
16195d81903b06418c7d8cc72cf9add81c4026a2f3bcDaniel Veillard    PyObject *list;
16205d81903b06418c7d8cc72cf9add81c4026a2f3bcDaniel Veillard    PyObject *message;
16215d81903b06418c7d8cc72cf9add81c4026a2f3bcDaniel Veillard    PyObject *result;
1622ad9fb7c06fea9cf63911c63cc9488ab1d0267005Daniel Veillard    char str[1000];
16235d81903b06418c7d8cc72cf9add81c4026a2f3bcDaniel Veillard
16245d81903b06418c7d8cc72cf9add81c4026a2f3bcDaniel Veillard#ifdef DEBUG_ERROR
16255d81903b06418c7d8cc72cf9add81c4026a2f3bcDaniel Veillard    printf("libxml_xmlErrorFuncHandler(%p, %s, ...) called\n", ctx, msg);
16265d81903b06418c7d8cc72cf9add81c4026a2f3bcDaniel Veillard#endif
16275d81903b06418c7d8cc72cf9add81c4026a2f3bcDaniel Veillard
16285d81903b06418c7d8cc72cf9add81c4026a2f3bcDaniel Veillard
16295d81903b06418c7d8cc72cf9add81c4026a2f3bcDaniel Veillard    if (libxml_xmlPythonErrorFuncHandler == NULL) {
1630d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        va_start(ap, msg);
1631007d51eb73cd5c78b676e13aae5bcfce83550a5dDaniel Veillard        vfprintf(stderr, msg, ap);
1632d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        va_end(ap);
16335d81903b06418c7d8cc72cf9add81c4026a2f3bcDaniel Veillard    } else {
1634e6227e0549490b5bf9271ecd2d874a97c3f4852bDaniel Veillard        va_start(ap, msg);
1635ad9fb7c06fea9cf63911c63cc9488ab1d0267005Daniel Veillard        if (vsnprintf(str, 999, msg, ap) >= 998)
1636ad9fb7c06fea9cf63911c63cc9488ab1d0267005Daniel Veillard	    str[999] = 0;
1637e6227e0549490b5bf9271ecd2d874a97c3f4852bDaniel Veillard        va_end(ap);
1638d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard
1639d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        list = PyTuple_New(2);
1640d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        PyTuple_SetItem(list, 0, libxml_xmlPythonErrorFuncCtxt);
1641d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        Py_XINCREF(libxml_xmlPythonErrorFuncCtxt);
1642ad9fb7c06fea9cf63911c63cc9488ab1d0267005Daniel Veillard        message = libxml_charPtrConstWrap(str);
1643d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        PyTuple_SetItem(list, 1, message);
1644d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        result = PyEval_CallObject(libxml_xmlPythonErrorFuncHandler, list);
1645d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        Py_XDECREF(list);
1646d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        Py_XDECREF(result);
16475d81903b06418c7d8cc72cf9add81c4026a2f3bcDaniel Veillard    }
16485d81903b06418c7d8cc72cf9add81c4026a2f3bcDaniel Veillard}
16495d81903b06418c7d8cc72cf9add81c4026a2f3bcDaniel Veillard
16505d81903b06418c7d8cc72cf9add81c4026a2f3bcDaniel Veillardstatic void
1651d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillardlibxml_xmlErrorInitialize(void)
1652d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard{
16535d81903b06418c7d8cc72cf9add81c4026a2f3bcDaniel Veillard#ifdef DEBUG_ERROR
16545d81903b06418c7d8cc72cf9add81c4026a2f3bcDaniel Veillard    printf("libxml_xmlErrorInitialize() called\n");
16555d81903b06418c7d8cc72cf9add81c4026a2f3bcDaniel Veillard#endif
16565d81903b06418c7d8cc72cf9add81c4026a2f3bcDaniel Veillard    xmlSetGenericErrorFunc(NULL, libxml_xmlErrorFuncHandler);
1657781ac8b19bfc10635a8bb83158f874116fd7559eDaniel Veillard    xmlThrDefSetGenericErrorFunc(NULL, libxml_xmlErrorFuncHandler);
16585d81903b06418c7d8cc72cf9add81c4026a2f3bcDaniel Veillard}
16595d81903b06418c7d8cc72cf9add81c4026a2f3bcDaniel Veillard
1660c2664641740126714bb363bd6b5f65f724031c83Daniel Veillardstatic PyObject *
1661d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillardlibxml_xmlRegisterErrorHandler(ATTRIBUTE_UNUSED PyObject * self,
1662d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard                               PyObject * args)
1663d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard{
16645d81903b06418c7d8cc72cf9add81c4026a2f3bcDaniel Veillard    PyObject *py_retval;
16655d81903b06418c7d8cc72cf9add81c4026a2f3bcDaniel Veillard    PyObject *pyobj_f;
16665d81903b06418c7d8cc72cf9add81c4026a2f3bcDaniel Veillard    PyObject *pyobj_ctx;
16675d81903b06418c7d8cc72cf9add81c4026a2f3bcDaniel Veillard
1668d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard    if (!PyArg_ParseTuple
1669d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        (args, (char *) "OO:xmlRegisterErrorHandler", &pyobj_f,
1670d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard         &pyobj_ctx))
1671d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        return (NULL);
16725d81903b06418c7d8cc72cf9add81c4026a2f3bcDaniel Veillard
16735d81903b06418c7d8cc72cf9add81c4026a2f3bcDaniel Veillard#ifdef DEBUG_ERROR
16748e2cc6f2b53f536692f3c8ad8112bb67e0a1a629William M. Brack    printf("libxml_xmlRegisterErrorHandler(%p, %p) called\n", pyobj_ctx,
1675d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard           pyobj_f);
16765d81903b06418c7d8cc72cf9add81c4026a2f3bcDaniel Veillard#endif
16775d81903b06418c7d8cc72cf9add81c4026a2f3bcDaniel Veillard
16785d81903b06418c7d8cc72cf9add81c4026a2f3bcDaniel Veillard    if (libxml_xmlPythonErrorFuncHandler != NULL) {
1679d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        Py_XDECREF(libxml_xmlPythonErrorFuncHandler);
16805d81903b06418c7d8cc72cf9add81c4026a2f3bcDaniel Veillard    }
16815d81903b06418c7d8cc72cf9add81c4026a2f3bcDaniel Veillard    if (libxml_xmlPythonErrorFuncCtxt != NULL) {
1682d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        Py_XDECREF(libxml_xmlPythonErrorFuncCtxt);
16835d81903b06418c7d8cc72cf9add81c4026a2f3bcDaniel Veillard    }
16845d81903b06418c7d8cc72cf9add81c4026a2f3bcDaniel Veillard
16855d81903b06418c7d8cc72cf9add81c4026a2f3bcDaniel Veillard    Py_XINCREF(pyobj_ctx);
16865d81903b06418c7d8cc72cf9add81c4026a2f3bcDaniel Veillard    Py_XINCREF(pyobj_f);
16875d81903b06418c7d8cc72cf9add81c4026a2f3bcDaniel Veillard
16885d81903b06418c7d8cc72cf9add81c4026a2f3bcDaniel Veillard    /* TODO: check f is a function ! */
16895d81903b06418c7d8cc72cf9add81c4026a2f3bcDaniel Veillard    libxml_xmlPythonErrorFuncHandler = pyobj_f;
16905d81903b06418c7d8cc72cf9add81c4026a2f3bcDaniel Veillard    libxml_xmlPythonErrorFuncCtxt = pyobj_ctx;
16915d81903b06418c7d8cc72cf9add81c4026a2f3bcDaniel Veillard
16925d81903b06418c7d8cc72cf9add81c4026a2f3bcDaniel Veillard    py_retval = libxml_intWrap(1);
1693d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard    return (py_retval);
16945d81903b06418c7d8cc72cf9add81c4026a2f3bcDaniel Veillard}
1695d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard
1696e6227e0549490b5bf9271ecd2d874a97c3f4852bDaniel Veillard
1697e6227e0549490b5bf9271ecd2d874a97c3f4852bDaniel Veillard/************************************************************************
1698e6227e0549490b5bf9271ecd2d874a97c3f4852bDaniel Veillard *									*
1699e6227e0549490b5bf9271ecd2d874a97c3f4852bDaniel Veillard *                      Per parserCtxt error handler                    *
1700e6227e0549490b5bf9271ecd2d874a97c3f4852bDaniel Veillard *									*
1701e6227e0549490b5bf9271ecd2d874a97c3f4852bDaniel Veillard ************************************************************************/
1702e6227e0549490b5bf9271ecd2d874a97c3f4852bDaniel Veillard
1703417be3ae08346c6510c28d2042dd42a22a74b331Daniel Veillardtypedef struct
1704417be3ae08346c6510c28d2042dd42a22a74b331Daniel Veillard{
1705417be3ae08346c6510c28d2042dd42a22a74b331Daniel Veillard    PyObject *f;
1706417be3ae08346c6510c28d2042dd42a22a74b331Daniel Veillard    PyObject *arg;
1707417be3ae08346c6510c28d2042dd42a22a74b331Daniel Veillard} xmlParserCtxtPyCtxt;
1708417be3ae08346c6510c28d2042dd42a22a74b331Daniel Veillardtypedef xmlParserCtxtPyCtxt *xmlParserCtxtPyCtxtPtr;
1709417be3ae08346c6510c28d2042dd42a22a74b331Daniel Veillard
1710417be3ae08346c6510c28d2042dd42a22a74b331Daniel Veillardstatic void
1711417be3ae08346c6510c28d2042dd42a22a74b331Daniel Veillardlibxml_xmlParserCtxtGenericErrorFuncHandler(void *ctx, int severity, char *str)
1712e6227e0549490b5bf9271ecd2d874a97c3f4852bDaniel Veillard{
1713e6227e0549490b5bf9271ecd2d874a97c3f4852bDaniel Veillard    PyObject *list;
1714e6227e0549490b5bf9271ecd2d874a97c3f4852bDaniel Veillard    PyObject *result;
1715417be3ae08346c6510c28d2042dd42a22a74b331Daniel Veillard    xmlParserCtxtPtr ctxt;
1716e6227e0549490b5bf9271ecd2d874a97c3f4852bDaniel Veillard    xmlParserCtxtPyCtxtPtr pyCtxt;
1717e6227e0549490b5bf9271ecd2d874a97c3f4852bDaniel Veillard
1718e6227e0549490b5bf9271ecd2d874a97c3f4852bDaniel Veillard#ifdef DEBUG_ERROR
1719850ce9b6584ecc2893632392f1d3ba46fefc13acDaniel Veillard    printf("libxml_xmlParserCtxtGenericErrorFuncHandler(%p, %s, ...) called\n", ctx, str);
1720e6227e0549490b5bf9271ecd2d874a97c3f4852bDaniel Veillard#endif
1721e6227e0549490b5bf9271ecd2d874a97c3f4852bDaniel Veillard
1722417be3ae08346c6510c28d2042dd42a22a74b331Daniel Veillard    ctxt = (xmlParserCtxtPtr)ctx;
1723417be3ae08346c6510c28d2042dd42a22a74b331Daniel Veillard    pyCtxt = (xmlParserCtxtPyCtxtPtr)ctxt->_private;
1724e6227e0549490b5bf9271ecd2d874a97c3f4852bDaniel Veillard
1725417be3ae08346c6510c28d2042dd42a22a74b331Daniel Veillard    list = PyTuple_New(4);
1726417be3ae08346c6510c28d2042dd42a22a74b331Daniel Veillard    PyTuple_SetItem(list, 0, pyCtxt->arg);
1727417be3ae08346c6510c28d2042dd42a22a74b331Daniel Veillard    Py_XINCREF(pyCtxt->arg);
1728417be3ae08346c6510c28d2042dd42a22a74b331Daniel Veillard    PyTuple_SetItem(list, 1, libxml_charPtrWrap(str));
1729417be3ae08346c6510c28d2042dd42a22a74b331Daniel Veillard    PyTuple_SetItem(list, 2, libxml_intWrap(severity));
1730417be3ae08346c6510c28d2042dd42a22a74b331Daniel Veillard    PyTuple_SetItem(list, 3, Py_None);
1731417be3ae08346c6510c28d2042dd42a22a74b331Daniel Veillard    Py_INCREF(Py_None);
1732417be3ae08346c6510c28d2042dd42a22a74b331Daniel Veillard    result = PyEval_CallObject(pyCtxt->f, list);
1733417be3ae08346c6510c28d2042dd42a22a74b331Daniel Veillard    if (result == NULL)
1734417be3ae08346c6510c28d2042dd42a22a74b331Daniel Veillard    {
1735417be3ae08346c6510c28d2042dd42a22a74b331Daniel Veillard	/* TODO: manage for the exception to be propagated... */
1736417be3ae08346c6510c28d2042dd42a22a74b331Daniel Veillard	PyErr_Print();
1737e6227e0549490b5bf9271ecd2d874a97c3f4852bDaniel Veillard    }
1738417be3ae08346c6510c28d2042dd42a22a74b331Daniel Veillard    Py_XDECREF(list);
1739417be3ae08346c6510c28d2042dd42a22a74b331Daniel Veillard    Py_XDECREF(result);
1740417be3ae08346c6510c28d2042dd42a22a74b331Daniel Veillard}
1741417be3ae08346c6510c28d2042dd42a22a74b331Daniel Veillard
1742417be3ae08346c6510c28d2042dd42a22a74b331Daniel Veillardstatic void
1743417be3ae08346c6510c28d2042dd42a22a74b331Daniel Veillardlibxml_xmlParserCtxtErrorFuncHandler(void *ctx, const char *msg, ...)
1744417be3ae08346c6510c28d2042dd42a22a74b331Daniel Veillard{
1745417be3ae08346c6510c28d2042dd42a22a74b331Daniel Veillard    va_list ap;
1746417be3ae08346c6510c28d2042dd42a22a74b331Daniel Veillard
1747417be3ae08346c6510c28d2042dd42a22a74b331Daniel Veillard    va_start(ap, msg);
1748417be3ae08346c6510c28d2042dd42a22a74b331Daniel Veillard    libxml_xmlParserCtxtGenericErrorFuncHandler(ctx,XML_PARSER_SEVERITY_ERROR,libxml_buildMessage(msg,ap));
1749417be3ae08346c6510c28d2042dd42a22a74b331Daniel Veillard    va_end(ap);
1750417be3ae08346c6510c28d2042dd42a22a74b331Daniel Veillard}
1751417be3ae08346c6510c28d2042dd42a22a74b331Daniel Veillard
1752417be3ae08346c6510c28d2042dd42a22a74b331Daniel Veillardstatic void
1753417be3ae08346c6510c28d2042dd42a22a74b331Daniel Veillardlibxml_xmlParserCtxtWarningFuncHandler(void *ctx, const char *msg, ...)
1754417be3ae08346c6510c28d2042dd42a22a74b331Daniel Veillard{
1755417be3ae08346c6510c28d2042dd42a22a74b331Daniel Veillard    va_list ap;
1756417be3ae08346c6510c28d2042dd42a22a74b331Daniel Veillard
1757417be3ae08346c6510c28d2042dd42a22a74b331Daniel Veillard    va_start(ap, msg);
1758417be3ae08346c6510c28d2042dd42a22a74b331Daniel Veillard    libxml_xmlParserCtxtGenericErrorFuncHandler(ctx,XML_PARSER_SEVERITY_WARNING,libxml_buildMessage(msg,ap));
1759417be3ae08346c6510c28d2042dd42a22a74b331Daniel Veillard    va_end(ap);
1760417be3ae08346c6510c28d2042dd42a22a74b331Daniel Veillard}
1761417be3ae08346c6510c28d2042dd42a22a74b331Daniel Veillard
1762417be3ae08346c6510c28d2042dd42a22a74b331Daniel Veillardstatic void
1763417be3ae08346c6510c28d2042dd42a22a74b331Daniel Veillardlibxml_xmlParserCtxtValidityErrorFuncHandler(void *ctx, const char *msg, ...)
1764417be3ae08346c6510c28d2042dd42a22a74b331Daniel Veillard{
1765417be3ae08346c6510c28d2042dd42a22a74b331Daniel Veillard    va_list ap;
1766417be3ae08346c6510c28d2042dd42a22a74b331Daniel Veillard
1767417be3ae08346c6510c28d2042dd42a22a74b331Daniel Veillard    va_start(ap, msg);
1768417be3ae08346c6510c28d2042dd42a22a74b331Daniel Veillard    libxml_xmlParserCtxtGenericErrorFuncHandler(ctx,XML_PARSER_SEVERITY_VALIDITY_ERROR,libxml_buildMessage(msg,ap));
1769417be3ae08346c6510c28d2042dd42a22a74b331Daniel Veillard    va_end(ap);
1770417be3ae08346c6510c28d2042dd42a22a74b331Daniel Veillard}
1771417be3ae08346c6510c28d2042dd42a22a74b331Daniel Veillard
1772417be3ae08346c6510c28d2042dd42a22a74b331Daniel Veillardstatic void
1773417be3ae08346c6510c28d2042dd42a22a74b331Daniel Veillardlibxml_xmlParserCtxtValidityWarningFuncHandler(void *ctx, const char *msg, ...)
1774417be3ae08346c6510c28d2042dd42a22a74b331Daniel Veillard{
1775417be3ae08346c6510c28d2042dd42a22a74b331Daniel Veillard    va_list ap;
1776417be3ae08346c6510c28d2042dd42a22a74b331Daniel Veillard
1777417be3ae08346c6510c28d2042dd42a22a74b331Daniel Veillard    va_start(ap, msg);
1778417be3ae08346c6510c28d2042dd42a22a74b331Daniel Veillard    libxml_xmlParserCtxtGenericErrorFuncHandler(ctx,XML_PARSER_SEVERITY_VALIDITY_WARNING,libxml_buildMessage(msg,ap));
1779417be3ae08346c6510c28d2042dd42a22a74b331Daniel Veillard    va_end(ap);
1780e6227e0549490b5bf9271ecd2d874a97c3f4852bDaniel Veillard}
1781e6227e0549490b5bf9271ecd2d874a97c3f4852bDaniel Veillard
1782c2664641740126714bb363bd6b5f65f724031c83Daniel Veillardstatic PyObject *
1783417be3ae08346c6510c28d2042dd42a22a74b331Daniel Veillardlibxml_xmlParserCtxtSetErrorHandler(ATTRIBUTE_UNUSED PyObject *self, PyObject *args)
1784e6227e0549490b5bf9271ecd2d874a97c3f4852bDaniel Veillard{
1785e6227e0549490b5bf9271ecd2d874a97c3f4852bDaniel Veillard    PyObject *py_retval;
1786e6227e0549490b5bf9271ecd2d874a97c3f4852bDaniel Veillard    xmlParserCtxtPtr ctxt;
1787e4a07e7b77b191d61291d44dffa19b65387e04e4Daniel Veillard    xmlParserCtxtPyCtxtPtr pyCtxt;
1788e6227e0549490b5bf9271ecd2d874a97c3f4852bDaniel Veillard    PyObject *pyobj_ctxt;
1789e6227e0549490b5bf9271ecd2d874a97c3f4852bDaniel Veillard    PyObject *pyobj_f;
1790e6227e0549490b5bf9271ecd2d874a97c3f4852bDaniel Veillard    PyObject *pyobj_arg;
1791e6227e0549490b5bf9271ecd2d874a97c3f4852bDaniel Veillard
1792417be3ae08346c6510c28d2042dd42a22a74b331Daniel Veillard    if (!PyArg_ParseTuple(args, (char *)"OOO:xmlParserCtxtSetErrorHandler",
1793e6227e0549490b5bf9271ecd2d874a97c3f4852bDaniel Veillard		          &pyobj_ctxt, &pyobj_f, &pyobj_arg))
1794e6227e0549490b5bf9271ecd2d874a97c3f4852bDaniel Veillard        return(NULL);
1795e6227e0549490b5bf9271ecd2d874a97c3f4852bDaniel Veillard    ctxt = (xmlParserCtxtPtr) PyparserCtxt_Get(pyobj_ctxt);
1796e6227e0549490b5bf9271ecd2d874a97c3f4852bDaniel Veillard    if (ctxt->_private == NULL) {
1797e6227e0549490b5bf9271ecd2d874a97c3f4852bDaniel Veillard	pyCtxt = xmlMalloc(sizeof(xmlParserCtxtPyCtxt));
1798e6227e0549490b5bf9271ecd2d874a97c3f4852bDaniel Veillard	if (pyCtxt == NULL) {
1799e6227e0549490b5bf9271ecd2d874a97c3f4852bDaniel Veillard	    py_retval = libxml_intWrap(-1);
1800e6227e0549490b5bf9271ecd2d874a97c3f4852bDaniel Veillard	    return(py_retval);
1801e6227e0549490b5bf9271ecd2d874a97c3f4852bDaniel Veillard	}
1802e6227e0549490b5bf9271ecd2d874a97c3f4852bDaniel Veillard	memset(pyCtxt,0,sizeof(xmlParserCtxtPyCtxt));
1803e6227e0549490b5bf9271ecd2d874a97c3f4852bDaniel Veillard	ctxt->_private = pyCtxt;
1804e6227e0549490b5bf9271ecd2d874a97c3f4852bDaniel Veillard    }
1805e4a07e7b77b191d61291d44dffa19b65387e04e4Daniel Veillard    else {
1806417be3ae08346c6510c28d2042dd42a22a74b331Daniel Veillard	pyCtxt = (xmlParserCtxtPyCtxtPtr)ctxt->_private;
1807e4a07e7b77b191d61291d44dffa19b65387e04e4Daniel Veillard    }
1808e6227e0549490b5bf9271ecd2d874a97c3f4852bDaniel Veillard    /* TODO: check f is a function ! */
1809417be3ae08346c6510c28d2042dd42a22a74b331Daniel Veillard    Py_XDECREF(pyCtxt->f);
1810e6227e0549490b5bf9271ecd2d874a97c3f4852bDaniel Veillard    Py_XINCREF(pyobj_f);
1811417be3ae08346c6510c28d2042dd42a22a74b331Daniel Veillard    pyCtxt->f = pyobj_f;
1812417be3ae08346c6510c28d2042dd42a22a74b331Daniel Veillard    Py_XDECREF(pyCtxt->arg);
1813e6227e0549490b5bf9271ecd2d874a97c3f4852bDaniel Veillard    Py_XINCREF(pyobj_arg);
1814417be3ae08346c6510c28d2042dd42a22a74b331Daniel Veillard    pyCtxt->arg = pyobj_arg;
1815e6227e0549490b5bf9271ecd2d874a97c3f4852bDaniel Veillard
1816417be3ae08346c6510c28d2042dd42a22a74b331Daniel Veillard    if (pyobj_f != Py_None) {
1817417be3ae08346c6510c28d2042dd42a22a74b331Daniel Veillard	ctxt->sax->error = libxml_xmlParserCtxtErrorFuncHandler;
1818417be3ae08346c6510c28d2042dd42a22a74b331Daniel Veillard	ctxt->sax->warning = libxml_xmlParserCtxtWarningFuncHandler;
1819417be3ae08346c6510c28d2042dd42a22a74b331Daniel Veillard	ctxt->vctxt.error = libxml_xmlParserCtxtValidityErrorFuncHandler;
1820417be3ae08346c6510c28d2042dd42a22a74b331Daniel Veillard	ctxt->vctxt.warning = libxml_xmlParserCtxtValidityWarningFuncHandler;
1821417be3ae08346c6510c28d2042dd42a22a74b331Daniel Veillard    }
1822417be3ae08346c6510c28d2042dd42a22a74b331Daniel Veillard    else {
1823417be3ae08346c6510c28d2042dd42a22a74b331Daniel Veillard	ctxt->sax->error = xmlParserError;
1824417be3ae08346c6510c28d2042dd42a22a74b331Daniel Veillard	ctxt->vctxt.error = xmlParserValidityError;
1825417be3ae08346c6510c28d2042dd42a22a74b331Daniel Veillard	ctxt->sax->warning = xmlParserWarning;
1826417be3ae08346c6510c28d2042dd42a22a74b331Daniel Veillard	ctxt->vctxt.warning = xmlParserValidityWarning;
1827417be3ae08346c6510c28d2042dd42a22a74b331Daniel Veillard    }
1828e6227e0549490b5bf9271ecd2d874a97c3f4852bDaniel Veillard
1829e6227e0549490b5bf9271ecd2d874a97c3f4852bDaniel Veillard    py_retval = libxml_intWrap(1);
1830e6227e0549490b5bf9271ecd2d874a97c3f4852bDaniel Veillard    return(py_retval);
1831e6227e0549490b5bf9271ecd2d874a97c3f4852bDaniel Veillard}
1832e6227e0549490b5bf9271ecd2d874a97c3f4852bDaniel Veillard
1833c2664641740126714bb363bd6b5f65f724031c83Daniel Veillardstatic PyObject *
1834417be3ae08346c6510c28d2042dd42a22a74b331Daniel Veillardlibxml_xmlParserCtxtGetErrorHandler(ATTRIBUTE_UNUSED PyObject *self, PyObject *args)
1835e6227e0549490b5bf9271ecd2d874a97c3f4852bDaniel Veillard{
1836417be3ae08346c6510c28d2042dd42a22a74b331Daniel Veillard    PyObject *py_retval;
1837417be3ae08346c6510c28d2042dd42a22a74b331Daniel Veillard    xmlParserCtxtPtr ctxt;
1838e6227e0549490b5bf9271ecd2d874a97c3f4852bDaniel Veillard    xmlParserCtxtPyCtxtPtr pyCtxt;
1839417be3ae08346c6510c28d2042dd42a22a74b331Daniel Veillard    PyObject *pyobj_ctxt;
1840e6227e0549490b5bf9271ecd2d874a97c3f4852bDaniel Veillard
1841417be3ae08346c6510c28d2042dd42a22a74b331Daniel Veillard    if (!PyArg_ParseTuple(args, (char *)"O:xmlParserCtxtGetErrorHandler",
1842417be3ae08346c6510c28d2042dd42a22a74b331Daniel Veillard		          &pyobj_ctxt))
1843417be3ae08346c6510c28d2042dd42a22a74b331Daniel Veillard        return(NULL);
1844417be3ae08346c6510c28d2042dd42a22a74b331Daniel Veillard    ctxt = (xmlParserCtxtPtr) PyparserCtxt_Get(pyobj_ctxt);
1845417be3ae08346c6510c28d2042dd42a22a74b331Daniel Veillard    py_retval = PyTuple_New(2);
1846417be3ae08346c6510c28d2042dd42a22a74b331Daniel Veillard    if (ctxt->_private != NULL) {
1847417be3ae08346c6510c28d2042dd42a22a74b331Daniel Veillard	pyCtxt = (xmlParserCtxtPyCtxtPtr)ctxt->_private;
1848e6227e0549490b5bf9271ecd2d874a97c3f4852bDaniel Veillard
1849417be3ae08346c6510c28d2042dd42a22a74b331Daniel Veillard	PyTuple_SetItem(py_retval, 0, pyCtxt->f);
1850417be3ae08346c6510c28d2042dd42a22a74b331Daniel Veillard	Py_XINCREF(pyCtxt->f);
1851417be3ae08346c6510c28d2042dd42a22a74b331Daniel Veillard	PyTuple_SetItem(py_retval, 1, pyCtxt->arg);
1852417be3ae08346c6510c28d2042dd42a22a74b331Daniel Veillard	Py_XINCREF(pyCtxt->arg);
1853417be3ae08346c6510c28d2042dd42a22a74b331Daniel Veillard    }
1854417be3ae08346c6510c28d2042dd42a22a74b331Daniel Veillard    else {
1855417be3ae08346c6510c28d2042dd42a22a74b331Daniel Veillard	/* no python error handler registered */
1856417be3ae08346c6510c28d2042dd42a22a74b331Daniel Veillard	PyTuple_SetItem(py_retval, 0, Py_None);
1857417be3ae08346c6510c28d2042dd42a22a74b331Daniel Veillard	Py_XINCREF(Py_None);
1858417be3ae08346c6510c28d2042dd42a22a74b331Daniel Veillard	PyTuple_SetItem(py_retval, 1, Py_None);
1859417be3ae08346c6510c28d2042dd42a22a74b331Daniel Veillard	Py_XINCREF(Py_None);
1860e6227e0549490b5bf9271ecd2d874a97c3f4852bDaniel Veillard    }
1861417be3ae08346c6510c28d2042dd42a22a74b331Daniel Veillard    return(py_retval);
1862e6227e0549490b5bf9271ecd2d874a97c3f4852bDaniel Veillard}
1863e6227e0549490b5bf9271ecd2d874a97c3f4852bDaniel Veillard
1864c2664641740126714bb363bd6b5f65f724031c83Daniel Veillardstatic PyObject *
1865417be3ae08346c6510c28d2042dd42a22a74b331Daniel Veillardlibxml_xmlFreeParserCtxt(ATTRIBUTE_UNUSED PyObject *self, PyObject *args) {
1866e6227e0549490b5bf9271ecd2d874a97c3f4852bDaniel Veillard    xmlParserCtxtPtr ctxt;
1867e6227e0549490b5bf9271ecd2d874a97c3f4852bDaniel Veillard    PyObject *pyobj_ctxt;
1868417be3ae08346c6510c28d2042dd42a22a74b331Daniel Veillard    xmlParserCtxtPyCtxtPtr pyCtxt;
1869e6227e0549490b5bf9271ecd2d874a97c3f4852bDaniel Veillard
1870417be3ae08346c6510c28d2042dd42a22a74b331Daniel Veillard    if (!PyArg_ParseTuple(args, (char *)"O:xmlFreeParserCtxt", &pyobj_ctxt))
1871e6227e0549490b5bf9271ecd2d874a97c3f4852bDaniel Veillard        return(NULL);
1872e6227e0549490b5bf9271ecd2d874a97c3f4852bDaniel Veillard    ctxt = (xmlParserCtxtPtr) PyparserCtxt_Get(pyobj_ctxt);
1873417be3ae08346c6510c28d2042dd42a22a74b331Daniel Veillard
1874417be3ae08346c6510c28d2042dd42a22a74b331Daniel Veillard    if (ctxt != NULL) {
1875417be3ae08346c6510c28d2042dd42a22a74b331Daniel Veillard	pyCtxt = (xmlParserCtxtPyCtxtPtr)((xmlParserCtxtPtr)ctxt)->_private;
1876417be3ae08346c6510c28d2042dd42a22a74b331Daniel Veillard	if (pyCtxt) {
1877417be3ae08346c6510c28d2042dd42a22a74b331Daniel Veillard	    Py_XDECREF(pyCtxt->f);
1878417be3ae08346c6510c28d2042dd42a22a74b331Daniel Veillard	    Py_XDECREF(pyCtxt->arg);
1879417be3ae08346c6510c28d2042dd42a22a74b331Daniel Veillard	    xmlFree(pyCtxt);
1880e4a07e7b77b191d61291d44dffa19b65387e04e4Daniel Veillard	}
1881417be3ae08346c6510c28d2042dd42a22a74b331Daniel Veillard	xmlFreeParserCtxt(ctxt);
1882e4a07e7b77b191d61291d44dffa19b65387e04e4Daniel Veillard    }
1883e6227e0549490b5bf9271ecd2d874a97c3f4852bDaniel Veillard
1884417be3ae08346c6510c28d2042dd42a22a74b331Daniel Veillard    Py_INCREF(Py_None);
1885417be3ae08346c6510c28d2042dd42a22a74b331Daniel Veillard    return(Py_None);
1886e6227e0549490b5bf9271ecd2d874a97c3f4852bDaniel Veillard}
1887e6227e0549490b5bf9271ecd2d874a97c3f4852bDaniel Veillard
1888850ce9b6584ecc2893632392f1d3ba46fefc13acDaniel Veillard/***
1889850ce9b6584ecc2893632392f1d3ba46fefc13acDaniel Veillard * xmlValidCtxt stuff
1890850ce9b6584ecc2893632392f1d3ba46fefc13acDaniel Veillard */
1891850ce9b6584ecc2893632392f1d3ba46fefc13acDaniel Veillard
1892850ce9b6584ecc2893632392f1d3ba46fefc13acDaniel Veillardtypedef struct
1893850ce9b6584ecc2893632392f1d3ba46fefc13acDaniel Veillard{
1894850ce9b6584ecc2893632392f1d3ba46fefc13acDaniel Veillard    PyObject *warn;
1895850ce9b6584ecc2893632392f1d3ba46fefc13acDaniel Veillard    PyObject *error;
1896850ce9b6584ecc2893632392f1d3ba46fefc13acDaniel Veillard    PyObject *arg;
1897850ce9b6584ecc2893632392f1d3ba46fefc13acDaniel Veillard} xmlValidCtxtPyCtxt;
1898850ce9b6584ecc2893632392f1d3ba46fefc13acDaniel Veillardtypedef xmlValidCtxtPyCtxt *xmlValidCtxtPyCtxtPtr;
1899850ce9b6584ecc2893632392f1d3ba46fefc13acDaniel Veillard
1900850ce9b6584ecc2893632392f1d3ba46fefc13acDaniel Veillardstatic void
1901c31e06cc18ac5d876eb712dcd2d7e2cbe74832a6Stefan Kostlibxml_xmlValidCtxtGenericErrorFuncHandler(void *ctx, ATTRIBUTE_UNUSED int severity, char *str)
1902850ce9b6584ecc2893632392f1d3ba46fefc13acDaniel Veillard{
1903850ce9b6584ecc2893632392f1d3ba46fefc13acDaniel Veillard    PyObject *list;
1904850ce9b6584ecc2893632392f1d3ba46fefc13acDaniel Veillard    PyObject *result;
1905850ce9b6584ecc2893632392f1d3ba46fefc13acDaniel Veillard    xmlValidCtxtPyCtxtPtr pyCtxt;
1906850ce9b6584ecc2893632392f1d3ba46fefc13acDaniel Veillard
1907850ce9b6584ecc2893632392f1d3ba46fefc13acDaniel Veillard#ifdef DEBUG_ERROR
1908850ce9b6584ecc2893632392f1d3ba46fefc13acDaniel Veillard    printf("libxml_xmlValidCtxtGenericErrorFuncHandler(%p, %d, %s, ...) called\n", ctx, severity, str);
1909850ce9b6584ecc2893632392f1d3ba46fefc13acDaniel Veillard#endif
1910850ce9b6584ecc2893632392f1d3ba46fefc13acDaniel Veillard
1911850ce9b6584ecc2893632392f1d3ba46fefc13acDaniel Veillard    pyCtxt = (xmlValidCtxtPyCtxtPtr)ctx;
1912850ce9b6584ecc2893632392f1d3ba46fefc13acDaniel Veillard
1913850ce9b6584ecc2893632392f1d3ba46fefc13acDaniel Veillard    list = PyTuple_New(2);
1914850ce9b6584ecc2893632392f1d3ba46fefc13acDaniel Veillard    PyTuple_SetItem(list, 0, libxml_charPtrWrap(str));
1915850ce9b6584ecc2893632392f1d3ba46fefc13acDaniel Veillard    PyTuple_SetItem(list, 1, pyCtxt->arg);
1916850ce9b6584ecc2893632392f1d3ba46fefc13acDaniel Veillard    Py_XINCREF(pyCtxt->arg);
1917850ce9b6584ecc2893632392f1d3ba46fefc13acDaniel Veillard    result = PyEval_CallObject(pyCtxt->error, list);
1918850ce9b6584ecc2893632392f1d3ba46fefc13acDaniel Veillard    if (result == NULL)
1919850ce9b6584ecc2893632392f1d3ba46fefc13acDaniel Veillard    {
1920850ce9b6584ecc2893632392f1d3ba46fefc13acDaniel Veillard	/* TODO: manage for the exception to be propagated... */
1921850ce9b6584ecc2893632392f1d3ba46fefc13acDaniel Veillard	PyErr_Print();
1922850ce9b6584ecc2893632392f1d3ba46fefc13acDaniel Veillard    }
1923850ce9b6584ecc2893632392f1d3ba46fefc13acDaniel Veillard    Py_XDECREF(list);
1924850ce9b6584ecc2893632392f1d3ba46fefc13acDaniel Veillard    Py_XDECREF(result);
1925850ce9b6584ecc2893632392f1d3ba46fefc13acDaniel Veillard}
1926850ce9b6584ecc2893632392f1d3ba46fefc13acDaniel Veillard
1927850ce9b6584ecc2893632392f1d3ba46fefc13acDaniel Veillardstatic void
1928c31e06cc18ac5d876eb712dcd2d7e2cbe74832a6Stefan Kostlibxml_xmlValidCtxtGenericWarningFuncHandler(void *ctx, ATTRIBUTE_UNUSED int severity, char *str)
1929850ce9b6584ecc2893632392f1d3ba46fefc13acDaniel Veillard{
1930850ce9b6584ecc2893632392f1d3ba46fefc13acDaniel Veillard    PyObject *list;
1931850ce9b6584ecc2893632392f1d3ba46fefc13acDaniel Veillard    PyObject *result;
1932850ce9b6584ecc2893632392f1d3ba46fefc13acDaniel Veillard    xmlValidCtxtPyCtxtPtr pyCtxt;
1933850ce9b6584ecc2893632392f1d3ba46fefc13acDaniel Veillard
1934850ce9b6584ecc2893632392f1d3ba46fefc13acDaniel Veillard#ifdef DEBUG_ERROR
1935850ce9b6584ecc2893632392f1d3ba46fefc13acDaniel Veillard    printf("libxml_xmlValidCtxtGenericWarningFuncHandler(%p, %d, %s, ...) called\n", ctx, severity, str);
1936850ce9b6584ecc2893632392f1d3ba46fefc13acDaniel Veillard#endif
1937850ce9b6584ecc2893632392f1d3ba46fefc13acDaniel Veillard
1938850ce9b6584ecc2893632392f1d3ba46fefc13acDaniel Veillard    pyCtxt = (xmlValidCtxtPyCtxtPtr)ctx;
1939850ce9b6584ecc2893632392f1d3ba46fefc13acDaniel Veillard
1940850ce9b6584ecc2893632392f1d3ba46fefc13acDaniel Veillard    list = PyTuple_New(2);
1941850ce9b6584ecc2893632392f1d3ba46fefc13acDaniel Veillard    PyTuple_SetItem(list, 0, libxml_charPtrWrap(str));
1942850ce9b6584ecc2893632392f1d3ba46fefc13acDaniel Veillard    PyTuple_SetItem(list, 1, pyCtxt->arg);
1943850ce9b6584ecc2893632392f1d3ba46fefc13acDaniel Veillard    Py_XINCREF(pyCtxt->arg);
1944850ce9b6584ecc2893632392f1d3ba46fefc13acDaniel Veillard    result = PyEval_CallObject(pyCtxt->warn, list);
1945850ce9b6584ecc2893632392f1d3ba46fefc13acDaniel Veillard    if (result == NULL)
1946850ce9b6584ecc2893632392f1d3ba46fefc13acDaniel Veillard    {
1947850ce9b6584ecc2893632392f1d3ba46fefc13acDaniel Veillard	/* TODO: manage for the exception to be propagated... */
1948850ce9b6584ecc2893632392f1d3ba46fefc13acDaniel Veillard	PyErr_Print();
1949850ce9b6584ecc2893632392f1d3ba46fefc13acDaniel Veillard    }
1950850ce9b6584ecc2893632392f1d3ba46fefc13acDaniel Veillard    Py_XDECREF(list);
1951850ce9b6584ecc2893632392f1d3ba46fefc13acDaniel Veillard    Py_XDECREF(result);
1952850ce9b6584ecc2893632392f1d3ba46fefc13acDaniel Veillard}
1953850ce9b6584ecc2893632392f1d3ba46fefc13acDaniel Veillard
1954850ce9b6584ecc2893632392f1d3ba46fefc13acDaniel Veillardstatic void
1955850ce9b6584ecc2893632392f1d3ba46fefc13acDaniel Veillardlibxml_xmlValidCtxtErrorFuncHandler(void *ctx, const char *msg, ...)
1956850ce9b6584ecc2893632392f1d3ba46fefc13acDaniel Veillard{
1957850ce9b6584ecc2893632392f1d3ba46fefc13acDaniel Veillard    va_list ap;
1958850ce9b6584ecc2893632392f1d3ba46fefc13acDaniel Veillard
1959850ce9b6584ecc2893632392f1d3ba46fefc13acDaniel Veillard    va_start(ap, msg);
1960850ce9b6584ecc2893632392f1d3ba46fefc13acDaniel Veillard    libxml_xmlValidCtxtGenericErrorFuncHandler(ctx,XML_PARSER_SEVERITY_VALIDITY_ERROR,libxml_buildMessage(msg,ap));
1961850ce9b6584ecc2893632392f1d3ba46fefc13acDaniel Veillard    va_end(ap);
1962850ce9b6584ecc2893632392f1d3ba46fefc13acDaniel Veillard}
1963850ce9b6584ecc2893632392f1d3ba46fefc13acDaniel Veillard
1964850ce9b6584ecc2893632392f1d3ba46fefc13acDaniel Veillardstatic void
1965850ce9b6584ecc2893632392f1d3ba46fefc13acDaniel Veillardlibxml_xmlValidCtxtWarningFuncHandler(void *ctx, const char *msg, ...)
1966850ce9b6584ecc2893632392f1d3ba46fefc13acDaniel Veillard{
1967850ce9b6584ecc2893632392f1d3ba46fefc13acDaniel Veillard    va_list ap;
1968850ce9b6584ecc2893632392f1d3ba46fefc13acDaniel Veillard
1969850ce9b6584ecc2893632392f1d3ba46fefc13acDaniel Veillard    va_start(ap, msg);
1970850ce9b6584ecc2893632392f1d3ba46fefc13acDaniel Veillard    libxml_xmlValidCtxtGenericWarningFuncHandler(ctx,XML_PARSER_SEVERITY_VALIDITY_WARNING,libxml_buildMessage(msg,ap));
1971850ce9b6584ecc2893632392f1d3ba46fefc13acDaniel Veillard    va_end(ap);
1972850ce9b6584ecc2893632392f1d3ba46fefc13acDaniel Veillard}
1973850ce9b6584ecc2893632392f1d3ba46fefc13acDaniel Veillard
1974850ce9b6584ecc2893632392f1d3ba46fefc13acDaniel Veillardstatic PyObject *
1975850ce9b6584ecc2893632392f1d3ba46fefc13acDaniel Veillardlibxml_xmlSetValidErrors(ATTRIBUTE_UNUSED PyObject * self, PyObject * args)
1976850ce9b6584ecc2893632392f1d3ba46fefc13acDaniel Veillard{
1977850ce9b6584ecc2893632392f1d3ba46fefc13acDaniel Veillard    PyObject *py_retval;
1978850ce9b6584ecc2893632392f1d3ba46fefc13acDaniel Veillard    PyObject *pyobj_error;
1979850ce9b6584ecc2893632392f1d3ba46fefc13acDaniel Veillard    PyObject *pyobj_warn;
1980850ce9b6584ecc2893632392f1d3ba46fefc13acDaniel Veillard    PyObject *pyobj_ctx;
1981850ce9b6584ecc2893632392f1d3ba46fefc13acDaniel Veillard    PyObject *pyobj_arg = Py_None;
1982850ce9b6584ecc2893632392f1d3ba46fefc13acDaniel Veillard    xmlValidCtxtPtr ctxt;
1983850ce9b6584ecc2893632392f1d3ba46fefc13acDaniel Veillard    xmlValidCtxtPyCtxtPtr pyCtxt;
1984850ce9b6584ecc2893632392f1d3ba46fefc13acDaniel Veillard
1985850ce9b6584ecc2893632392f1d3ba46fefc13acDaniel Veillard    if (!PyArg_ParseTuple
1986850ce9b6584ecc2893632392f1d3ba46fefc13acDaniel Veillard        (args, (char *) "OOO|O:xmlSetValidErrors", &pyobj_ctx, &pyobj_error, &pyobj_warn, &pyobj_arg))
1987850ce9b6584ecc2893632392f1d3ba46fefc13acDaniel Veillard        return (NULL);
1988850ce9b6584ecc2893632392f1d3ba46fefc13acDaniel Veillard
1989850ce9b6584ecc2893632392f1d3ba46fefc13acDaniel Veillard#ifdef DEBUG_ERROR
1990850ce9b6584ecc2893632392f1d3ba46fefc13acDaniel Veillard    printf("libxml_xmlSetValidErrors(%p, %p, %p) called\n", pyobj_ctx, pyobj_error, pyobj_warn);
1991850ce9b6584ecc2893632392f1d3ba46fefc13acDaniel Veillard#endif
1992850ce9b6584ecc2893632392f1d3ba46fefc13acDaniel Veillard
1993850ce9b6584ecc2893632392f1d3ba46fefc13acDaniel Veillard    ctxt = PyValidCtxt_Get(pyobj_ctx);
1994850ce9b6584ecc2893632392f1d3ba46fefc13acDaniel Veillard    pyCtxt = xmlMalloc(sizeof(xmlValidCtxtPyCtxt));
1995850ce9b6584ecc2893632392f1d3ba46fefc13acDaniel Veillard    if (pyCtxt == NULL) {
1996850ce9b6584ecc2893632392f1d3ba46fefc13acDaniel Veillard            py_retval = libxml_intWrap(-1);
1997850ce9b6584ecc2893632392f1d3ba46fefc13acDaniel Veillard            return(py_retval);
1998850ce9b6584ecc2893632392f1d3ba46fefc13acDaniel Veillard    }
1999850ce9b6584ecc2893632392f1d3ba46fefc13acDaniel Veillard    memset(pyCtxt, 0, sizeof(xmlValidCtxtPyCtxt));
2000850ce9b6584ecc2893632392f1d3ba46fefc13acDaniel Veillard
2001850ce9b6584ecc2893632392f1d3ba46fefc13acDaniel Veillard
2002850ce9b6584ecc2893632392f1d3ba46fefc13acDaniel Veillard    /* TODO: check warn and error is a function ! */
2003850ce9b6584ecc2893632392f1d3ba46fefc13acDaniel Veillard    Py_XDECREF(pyCtxt->error);
2004850ce9b6584ecc2893632392f1d3ba46fefc13acDaniel Veillard    Py_XINCREF(pyobj_error);
2005850ce9b6584ecc2893632392f1d3ba46fefc13acDaniel Veillard    pyCtxt->error = pyobj_error;
2006850ce9b6584ecc2893632392f1d3ba46fefc13acDaniel Veillard
2007850ce9b6584ecc2893632392f1d3ba46fefc13acDaniel Veillard    Py_XDECREF(pyCtxt->warn);
2008850ce9b6584ecc2893632392f1d3ba46fefc13acDaniel Veillard    Py_XINCREF(pyobj_warn);
2009850ce9b6584ecc2893632392f1d3ba46fefc13acDaniel Veillard    pyCtxt->warn = pyobj_warn;
2010850ce9b6584ecc2893632392f1d3ba46fefc13acDaniel Veillard
2011850ce9b6584ecc2893632392f1d3ba46fefc13acDaniel Veillard    Py_XDECREF(pyCtxt->arg);
2012850ce9b6584ecc2893632392f1d3ba46fefc13acDaniel Veillard    Py_XINCREF(pyobj_arg);
2013850ce9b6584ecc2893632392f1d3ba46fefc13acDaniel Veillard    pyCtxt->arg = pyobj_arg;
2014850ce9b6584ecc2893632392f1d3ba46fefc13acDaniel Veillard
2015850ce9b6584ecc2893632392f1d3ba46fefc13acDaniel Veillard    ctxt->error = libxml_xmlValidCtxtErrorFuncHandler;
2016850ce9b6584ecc2893632392f1d3ba46fefc13acDaniel Veillard    ctxt->warning = libxml_xmlValidCtxtWarningFuncHandler;
2017850ce9b6584ecc2893632392f1d3ba46fefc13acDaniel Veillard    ctxt->userData = pyCtxt;
2018850ce9b6584ecc2893632392f1d3ba46fefc13acDaniel Veillard
2019850ce9b6584ecc2893632392f1d3ba46fefc13acDaniel Veillard    py_retval = libxml_intWrap(1);
2020850ce9b6584ecc2893632392f1d3ba46fefc13acDaniel Veillard    return (py_retval);
2021850ce9b6584ecc2893632392f1d3ba46fefc13acDaniel Veillard}
2022850ce9b6584ecc2893632392f1d3ba46fefc13acDaniel Veillard
202325c90c589b256f0925f081198c1525134a491e31Daniel Veillard
2024bb8502c0ef2af706fbdff69119e994e40da64a88Daniel Veillardstatic PyObject *
202525c90c589b256f0925f081198c1525134a491e31Daniel Veillardlibxml_xmlFreeValidCtxt(PyObject *self ATTRIBUTE_UNUSED, PyObject *args) {
202625c90c589b256f0925f081198c1525134a491e31Daniel Veillard    xmlValidCtxtPtr cur;
202725c90c589b256f0925f081198c1525134a491e31Daniel Veillard    xmlValidCtxtPyCtxtPtr pyCtxt;
202825c90c589b256f0925f081198c1525134a491e31Daniel Veillard    PyObject *pyobj_cur;
202925c90c589b256f0925f081198c1525134a491e31Daniel Veillard
203025c90c589b256f0925f081198c1525134a491e31Daniel Veillard    if (!PyArg_ParseTuple(args, (char *)"O:xmlFreeValidCtxt", &pyobj_cur))
203125c90c589b256f0925f081198c1525134a491e31Daniel Veillard        return(NULL);
203225c90c589b256f0925f081198c1525134a491e31Daniel Veillard    cur = (xmlValidCtxtPtr) PyValidCtxt_Get(pyobj_cur);
203325c90c589b256f0925f081198c1525134a491e31Daniel Veillard
203425c90c589b256f0925f081198c1525134a491e31Daniel Veillard    pyCtxt = (xmlValidCtxtPyCtxtPtr)(cur->userData);
203525c90c589b256f0925f081198c1525134a491e31Daniel Veillard    if (pyCtxt != NULL)
203625c90c589b256f0925f081198c1525134a491e31Daniel Veillard    {
203725c90c589b256f0925f081198c1525134a491e31Daniel Veillard            Py_XDECREF(pyCtxt->error);
203825c90c589b256f0925f081198c1525134a491e31Daniel Veillard            Py_XDECREF(pyCtxt->warn);
203925c90c589b256f0925f081198c1525134a491e31Daniel Veillard            Py_XDECREF(pyCtxt->arg);
204025c90c589b256f0925f081198c1525134a491e31Daniel Veillard            xmlFree(pyCtxt);
204125c90c589b256f0925f081198c1525134a491e31Daniel Veillard    }
204225c90c589b256f0925f081198c1525134a491e31Daniel Veillard
204325c90c589b256f0925f081198c1525134a491e31Daniel Veillard    xmlFreeValidCtxt(cur);
204425c90c589b256f0925f081198c1525134a491e31Daniel Veillard    Py_INCREF(Py_None);
204525c90c589b256f0925f081198c1525134a491e31Daniel Veillard    return(Py_None);
204625c90c589b256f0925f081198c1525134a491e31Daniel Veillard}
204725c90c589b256f0925f081198c1525134a491e31Daniel Veillard
2048438ebbd59af78c436397ae488e42aeca5cad7542Daniel Veillard#ifdef LIBXML_READER_ENABLED
2049a7340c830e4bddd86201cfdb97ac81e30b0dee62Daniel Veillard/************************************************************************
2050a7340c830e4bddd86201cfdb97ac81e30b0dee62Daniel Veillard *									*
205126f70269c80140a7fb8a7aae9ef09c95efa98e70Daniel Veillard *                      Per xmlTextReader error handler                 *
205226f70269c80140a7fb8a7aae9ef09c95efa98e70Daniel Veillard *									*
205326f70269c80140a7fb8a7aae9ef09c95efa98e70Daniel Veillard ************************************************************************/
205426f70269c80140a7fb8a7aae9ef09c95efa98e70Daniel Veillard
205526f70269c80140a7fb8a7aae9ef09c95efa98e70Daniel Veillardtypedef struct
205626f70269c80140a7fb8a7aae9ef09c95efa98e70Daniel Veillard{
205726f70269c80140a7fb8a7aae9ef09c95efa98e70Daniel Veillard    PyObject *f;
205826f70269c80140a7fb8a7aae9ef09c95efa98e70Daniel Veillard    PyObject *arg;
205926f70269c80140a7fb8a7aae9ef09c95efa98e70Daniel Veillard} xmlTextReaderPyCtxt;
206026f70269c80140a7fb8a7aae9ef09c95efa98e70Daniel Veillardtypedef xmlTextReaderPyCtxt *xmlTextReaderPyCtxtPtr;
206126f70269c80140a7fb8a7aae9ef09c95efa98e70Daniel Veillard
206226f70269c80140a7fb8a7aae9ef09c95efa98e70Daniel Veillardstatic void
206326f70269c80140a7fb8a7aae9ef09c95efa98e70Daniel Veillardlibxml_xmlTextReaderErrorCallback(void *arg,
206426f70269c80140a7fb8a7aae9ef09c95efa98e70Daniel Veillard				  const char *msg,
2065417be3ae08346c6510c28d2042dd42a22a74b331Daniel Veillard				  int severity,
2066417be3ae08346c6510c28d2042dd42a22a74b331Daniel Veillard				  xmlTextReaderLocatorPtr locator)
206726f70269c80140a7fb8a7aae9ef09c95efa98e70Daniel Veillard{
206826f70269c80140a7fb8a7aae9ef09c95efa98e70Daniel Veillard    xmlTextReaderPyCtxt *pyCtxt = (xmlTextReaderPyCtxt *)arg;
206926f70269c80140a7fb8a7aae9ef09c95efa98e70Daniel Veillard    PyObject *list;
207026f70269c80140a7fb8a7aae9ef09c95efa98e70Daniel Veillard    PyObject *result;
207126f70269c80140a7fb8a7aae9ef09c95efa98e70Daniel Veillard
2072417be3ae08346c6510c28d2042dd42a22a74b331Daniel Veillard    list = PyTuple_New(4);
207326f70269c80140a7fb8a7aae9ef09c95efa98e70Daniel Veillard    PyTuple_SetItem(list, 0, pyCtxt->arg);
207426f70269c80140a7fb8a7aae9ef09c95efa98e70Daniel Veillard    Py_XINCREF(pyCtxt->arg);
207526f70269c80140a7fb8a7aae9ef09c95efa98e70Daniel Veillard    PyTuple_SetItem(list, 1, libxml_charPtrConstWrap(msg));
2076417be3ae08346c6510c28d2042dd42a22a74b331Daniel Veillard    PyTuple_SetItem(list, 2, libxml_intWrap(severity));
2077417be3ae08346c6510c28d2042dd42a22a74b331Daniel Veillard    PyTuple_SetItem(list, 3, libxml_xmlTextReaderLocatorPtrWrap(locator));
207826f70269c80140a7fb8a7aae9ef09c95efa98e70Daniel Veillard    result = PyEval_CallObject(pyCtxt->f, list);
207926f70269c80140a7fb8a7aae9ef09c95efa98e70Daniel Veillard    if (result == NULL)
208026f70269c80140a7fb8a7aae9ef09c95efa98e70Daniel Veillard    {
2081417be3ae08346c6510c28d2042dd42a22a74b331Daniel Veillard	/* TODO: manage for the exception to be propagated... */
208226f70269c80140a7fb8a7aae9ef09c95efa98e70Daniel Veillard	PyErr_Print();
208326f70269c80140a7fb8a7aae9ef09c95efa98e70Daniel Veillard    }
208426f70269c80140a7fb8a7aae9ef09c95efa98e70Daniel Veillard    Py_XDECREF(list);
208526f70269c80140a7fb8a7aae9ef09c95efa98e70Daniel Veillard    Py_XDECREF(result);
208626f70269c80140a7fb8a7aae9ef09c95efa98e70Daniel Veillard}
208726f70269c80140a7fb8a7aae9ef09c95efa98e70Daniel Veillard
2088c2664641740126714bb363bd6b5f65f724031c83Daniel Veillardstatic PyObject *
208926f70269c80140a7fb8a7aae9ef09c95efa98e70Daniel Veillardlibxml_xmlTextReaderSetErrorHandler(ATTRIBUTE_UNUSED PyObject *self, PyObject *args)
209026f70269c80140a7fb8a7aae9ef09c95efa98e70Daniel Veillard{
209126f70269c80140a7fb8a7aae9ef09c95efa98e70Daniel Veillard    xmlTextReaderPtr reader;
209226f70269c80140a7fb8a7aae9ef09c95efa98e70Daniel Veillard    xmlTextReaderPyCtxtPtr pyCtxt;
209326f70269c80140a7fb8a7aae9ef09c95efa98e70Daniel Veillard    xmlTextReaderErrorFunc f;
209426f70269c80140a7fb8a7aae9ef09c95efa98e70Daniel Veillard    void *arg;
209526f70269c80140a7fb8a7aae9ef09c95efa98e70Daniel Veillard    PyObject *pyobj_reader;
209626f70269c80140a7fb8a7aae9ef09c95efa98e70Daniel Veillard    PyObject *pyobj_f;
209726f70269c80140a7fb8a7aae9ef09c95efa98e70Daniel Veillard    PyObject *pyobj_arg;
209826f70269c80140a7fb8a7aae9ef09c95efa98e70Daniel Veillard    PyObject *py_retval;
209926f70269c80140a7fb8a7aae9ef09c95efa98e70Daniel Veillard
210026f70269c80140a7fb8a7aae9ef09c95efa98e70Daniel Veillard    if (!PyArg_ParseTuple(args, (char *)"OOO:xmlTextReaderSetErrorHandler", &pyobj_reader, &pyobj_f, &pyobj_arg))
210126f70269c80140a7fb8a7aae9ef09c95efa98e70Daniel Veillard        return(NULL);
210226f70269c80140a7fb8a7aae9ef09c95efa98e70Daniel Veillard    reader = (xmlTextReaderPtr) PyxmlTextReader_Get(pyobj_reader);
210326f70269c80140a7fb8a7aae9ef09c95efa98e70Daniel Veillard    /* clear previous error handler */
210426f70269c80140a7fb8a7aae9ef09c95efa98e70Daniel Veillard    xmlTextReaderGetErrorHandler(reader,&f,&arg);
210526f70269c80140a7fb8a7aae9ef09c95efa98e70Daniel Veillard    if (arg != NULL) {
2106c2664641740126714bb363bd6b5f65f724031c83Daniel Veillard	if (f == (xmlTextReaderErrorFunc) libxml_xmlTextReaderErrorCallback) {
210726f70269c80140a7fb8a7aae9ef09c95efa98e70Daniel Veillard	    /* ok, it's our error handler! */
210826f70269c80140a7fb8a7aae9ef09c95efa98e70Daniel Veillard	    pyCtxt = (xmlTextReaderPyCtxtPtr)arg;
210926f70269c80140a7fb8a7aae9ef09c95efa98e70Daniel Veillard	    Py_XDECREF(pyCtxt->f);
211026f70269c80140a7fb8a7aae9ef09c95efa98e70Daniel Veillard	    Py_XDECREF(pyCtxt->arg);
211126f70269c80140a7fb8a7aae9ef09c95efa98e70Daniel Veillard	    xmlFree(pyCtxt);
211226f70269c80140a7fb8a7aae9ef09c95efa98e70Daniel Veillard	}
211326f70269c80140a7fb8a7aae9ef09c95efa98e70Daniel Veillard	else {
211426f70269c80140a7fb8a7aae9ef09c95efa98e70Daniel Veillard	    /*
211526f70269c80140a7fb8a7aae9ef09c95efa98e70Daniel Veillard	     * there already an arg, and it's not ours,
211626f70269c80140a7fb8a7aae9ef09c95efa98e70Daniel Veillard	     * there is definitely something wrong going on here...
211726f70269c80140a7fb8a7aae9ef09c95efa98e70Daniel Veillard	     * we don't know how to free it, so we bail out...
211826f70269c80140a7fb8a7aae9ef09c95efa98e70Daniel Veillard	     */
211926f70269c80140a7fb8a7aae9ef09c95efa98e70Daniel Veillard	    py_retval = libxml_intWrap(-1);
212026f70269c80140a7fb8a7aae9ef09c95efa98e70Daniel Veillard	    return(py_retval);
212126f70269c80140a7fb8a7aae9ef09c95efa98e70Daniel Veillard	}
212226f70269c80140a7fb8a7aae9ef09c95efa98e70Daniel Veillard    }
212326f70269c80140a7fb8a7aae9ef09c95efa98e70Daniel Veillard    xmlTextReaderSetErrorHandler(reader,NULL,NULL);
212426f70269c80140a7fb8a7aae9ef09c95efa98e70Daniel Veillard    /* set new error handler */
212526f70269c80140a7fb8a7aae9ef09c95efa98e70Daniel Veillard    if (pyobj_f != Py_None)
212626f70269c80140a7fb8a7aae9ef09c95efa98e70Daniel Veillard    {
212726f70269c80140a7fb8a7aae9ef09c95efa98e70Daniel Veillard	pyCtxt = (xmlTextReaderPyCtxtPtr)xmlMalloc(sizeof(xmlTextReaderPyCtxt));
212826f70269c80140a7fb8a7aae9ef09c95efa98e70Daniel Veillard	if (pyCtxt == NULL) {
212926f70269c80140a7fb8a7aae9ef09c95efa98e70Daniel Veillard	    py_retval = libxml_intWrap(-1);
213026f70269c80140a7fb8a7aae9ef09c95efa98e70Daniel Veillard	    return(py_retval);
213126f70269c80140a7fb8a7aae9ef09c95efa98e70Daniel Veillard	}
213226f70269c80140a7fb8a7aae9ef09c95efa98e70Daniel Veillard	Py_XINCREF(pyobj_f);
213326f70269c80140a7fb8a7aae9ef09c95efa98e70Daniel Veillard	pyCtxt->f = pyobj_f;
213426f70269c80140a7fb8a7aae9ef09c95efa98e70Daniel Veillard	Py_XINCREF(pyobj_arg);
213526f70269c80140a7fb8a7aae9ef09c95efa98e70Daniel Veillard	pyCtxt->arg = pyobj_arg;
2136c2664641740126714bb363bd6b5f65f724031c83Daniel Veillard	xmlTextReaderSetErrorHandler(reader,
2137c2664641740126714bb363bd6b5f65f724031c83Daniel Veillard	    (xmlTextReaderErrorFunc) libxml_xmlTextReaderErrorCallback,
2138c2664641740126714bb363bd6b5f65f724031c83Daniel Veillard	                             pyCtxt);
213926f70269c80140a7fb8a7aae9ef09c95efa98e70Daniel Veillard    }
214026f70269c80140a7fb8a7aae9ef09c95efa98e70Daniel Veillard
214126f70269c80140a7fb8a7aae9ef09c95efa98e70Daniel Veillard    py_retval = libxml_intWrap(1);
214226f70269c80140a7fb8a7aae9ef09c95efa98e70Daniel Veillard    return(py_retval);
214326f70269c80140a7fb8a7aae9ef09c95efa98e70Daniel Veillard}
214426f70269c80140a7fb8a7aae9ef09c95efa98e70Daniel Veillard
2145c2664641740126714bb363bd6b5f65f724031c83Daniel Veillardstatic PyObject *
214626f70269c80140a7fb8a7aae9ef09c95efa98e70Daniel Veillardlibxml_xmlTextReaderGetErrorHandler(ATTRIBUTE_UNUSED PyObject *self, PyObject *args)
214726f70269c80140a7fb8a7aae9ef09c95efa98e70Daniel Veillard{
214826f70269c80140a7fb8a7aae9ef09c95efa98e70Daniel Veillard    xmlTextReaderPtr reader;
214926f70269c80140a7fb8a7aae9ef09c95efa98e70Daniel Veillard    xmlTextReaderPyCtxtPtr pyCtxt;
215026f70269c80140a7fb8a7aae9ef09c95efa98e70Daniel Veillard    xmlTextReaderErrorFunc f;
215126f70269c80140a7fb8a7aae9ef09c95efa98e70Daniel Veillard    void *arg;
215226f70269c80140a7fb8a7aae9ef09c95efa98e70Daniel Veillard    PyObject *pyobj_reader;
215326f70269c80140a7fb8a7aae9ef09c95efa98e70Daniel Veillard    PyObject *py_retval;
215426f70269c80140a7fb8a7aae9ef09c95efa98e70Daniel Veillard
215526f70269c80140a7fb8a7aae9ef09c95efa98e70Daniel Veillard    if (!PyArg_ParseTuple(args, (char *)"O:xmlTextReaderSetErrorHandler", &pyobj_reader))
215626f70269c80140a7fb8a7aae9ef09c95efa98e70Daniel Veillard        return(NULL);
215726f70269c80140a7fb8a7aae9ef09c95efa98e70Daniel Veillard    reader = (xmlTextReaderPtr) PyxmlTextReader_Get(pyobj_reader);
215826f70269c80140a7fb8a7aae9ef09c95efa98e70Daniel Veillard    xmlTextReaderGetErrorHandler(reader,&f,&arg);
215926f70269c80140a7fb8a7aae9ef09c95efa98e70Daniel Veillard    py_retval = PyTuple_New(2);
2160c2664641740126714bb363bd6b5f65f724031c83Daniel Veillard    if (f == (xmlTextReaderErrorFunc)libxml_xmlTextReaderErrorCallback) {
216126f70269c80140a7fb8a7aae9ef09c95efa98e70Daniel Veillard	/* ok, it's our error handler! */
216226f70269c80140a7fb8a7aae9ef09c95efa98e70Daniel Veillard	pyCtxt = (xmlTextReaderPyCtxtPtr)arg;
216326f70269c80140a7fb8a7aae9ef09c95efa98e70Daniel Veillard	PyTuple_SetItem(py_retval, 0, pyCtxt->f);
216426f70269c80140a7fb8a7aae9ef09c95efa98e70Daniel Veillard	Py_XINCREF(pyCtxt->f);
216526f70269c80140a7fb8a7aae9ef09c95efa98e70Daniel Veillard	PyTuple_SetItem(py_retval, 1, pyCtxt->arg);
216626f70269c80140a7fb8a7aae9ef09c95efa98e70Daniel Veillard	Py_XINCREF(pyCtxt->arg);
216726f70269c80140a7fb8a7aae9ef09c95efa98e70Daniel Veillard    }
216826f70269c80140a7fb8a7aae9ef09c95efa98e70Daniel Veillard    else
216926f70269c80140a7fb8a7aae9ef09c95efa98e70Daniel Veillard    {
217026f70269c80140a7fb8a7aae9ef09c95efa98e70Daniel Veillard	/* f is null or it's not our error handler */
217126f70269c80140a7fb8a7aae9ef09c95efa98e70Daniel Veillard	PyTuple_SetItem(py_retval, 0, Py_None);
217226f70269c80140a7fb8a7aae9ef09c95efa98e70Daniel Veillard	Py_XINCREF(Py_None);
217326f70269c80140a7fb8a7aae9ef09c95efa98e70Daniel Veillard	PyTuple_SetItem(py_retval, 1, Py_None);
217426f70269c80140a7fb8a7aae9ef09c95efa98e70Daniel Veillard	Py_XINCREF(Py_None);
217526f70269c80140a7fb8a7aae9ef09c95efa98e70Daniel Veillard    }
217626f70269c80140a7fb8a7aae9ef09c95efa98e70Daniel Veillard    return(py_retval);
217726f70269c80140a7fb8a7aae9ef09c95efa98e70Daniel Veillard}
217826f70269c80140a7fb8a7aae9ef09c95efa98e70Daniel Veillard
2179c2664641740126714bb363bd6b5f65f724031c83Daniel Veillardstatic PyObject *
218026f70269c80140a7fb8a7aae9ef09c95efa98e70Daniel Veillardlibxml_xmlFreeTextReader(ATTRIBUTE_UNUSED PyObject *self, PyObject *args) {
218126f70269c80140a7fb8a7aae9ef09c95efa98e70Daniel Veillard    xmlTextReaderPtr reader;
218226f70269c80140a7fb8a7aae9ef09c95efa98e70Daniel Veillard    PyObject *pyobj_reader;
218326f70269c80140a7fb8a7aae9ef09c95efa98e70Daniel Veillard    xmlTextReaderPyCtxtPtr pyCtxt;
218426f70269c80140a7fb8a7aae9ef09c95efa98e70Daniel Veillard    xmlTextReaderErrorFunc f;
218526f70269c80140a7fb8a7aae9ef09c95efa98e70Daniel Veillard    void *arg;
218626f70269c80140a7fb8a7aae9ef09c95efa98e70Daniel Veillard
2187157fee019d02e1ba4ed377ea21172b67f479241bDaniel Veillard    if (!PyArg_ParseTuple(args, (char *)"O:xmlFreeTextReader", &pyobj_reader))
2188157fee019d02e1ba4ed377ea21172b67f479241bDaniel Veillard        return(NULL);
21893798c4adbb91f80bef1e9f1b4b61dae72577a244Daniel Veillard    if (!PyCapsule_CheckExact(pyobj_reader)) {
2190bb3ba326e6ba5b661ca51aab53b17f519eda5924Daniel Veillard	Py_INCREF(Py_None);
2191bb3ba326e6ba5b661ca51aab53b17f519eda5924Daniel Veillard	return(Py_None);
2192bb3ba326e6ba5b661ca51aab53b17f519eda5924Daniel Veillard    }
219326f70269c80140a7fb8a7aae9ef09c95efa98e70Daniel Veillard    reader = (xmlTextReaderPtr) PyxmlTextReader_Get(pyobj_reader);
2194bb3ba326e6ba5b661ca51aab53b17f519eda5924Daniel Veillard    if (reader == NULL) {
2195bb3ba326e6ba5b661ca51aab53b17f519eda5924Daniel Veillard	Py_INCREF(Py_None);
2196bb3ba326e6ba5b661ca51aab53b17f519eda5924Daniel Veillard	return(Py_None);
2197bb3ba326e6ba5b661ca51aab53b17f519eda5924Daniel Veillard    }
219826f70269c80140a7fb8a7aae9ef09c95efa98e70Daniel Veillard
219926f70269c80140a7fb8a7aae9ef09c95efa98e70Daniel Veillard    xmlTextReaderGetErrorHandler(reader,&f,&arg);
220026f70269c80140a7fb8a7aae9ef09c95efa98e70Daniel Veillard    if (arg != NULL) {
2201c2664641740126714bb363bd6b5f65f724031c83Daniel Veillard	if (f == (xmlTextReaderErrorFunc) libxml_xmlTextReaderErrorCallback) {
220226f70269c80140a7fb8a7aae9ef09c95efa98e70Daniel Veillard	    /* ok, it's our error handler! */
220326f70269c80140a7fb8a7aae9ef09c95efa98e70Daniel Veillard	    pyCtxt = (xmlTextReaderPyCtxtPtr)arg;
220426f70269c80140a7fb8a7aae9ef09c95efa98e70Daniel Veillard	    Py_XDECREF(pyCtxt->f);
220526f70269c80140a7fb8a7aae9ef09c95efa98e70Daniel Veillard	    Py_XDECREF(pyCtxt->arg);
220626f70269c80140a7fb8a7aae9ef09c95efa98e70Daniel Veillard	    xmlFree(pyCtxt);
220726f70269c80140a7fb8a7aae9ef09c95efa98e70Daniel Veillard	}
220826f70269c80140a7fb8a7aae9ef09c95efa98e70Daniel Veillard	/*
220926f70269c80140a7fb8a7aae9ef09c95efa98e70Daniel Veillard	 * else, something wrong happened, because the error handler is
221026f70269c80140a7fb8a7aae9ef09c95efa98e70Daniel Veillard	 * not owned by the python bindings...
221126f70269c80140a7fb8a7aae9ef09c95efa98e70Daniel Veillard	 */
221226f70269c80140a7fb8a7aae9ef09c95efa98e70Daniel Veillard    }
221326f70269c80140a7fb8a7aae9ef09c95efa98e70Daniel Veillard
221426f70269c80140a7fb8a7aae9ef09c95efa98e70Daniel Veillard    xmlFreeTextReader(reader);
221526f70269c80140a7fb8a7aae9ef09c95efa98e70Daniel Veillard    Py_INCREF(Py_None);
221626f70269c80140a7fb8a7aae9ef09c95efa98e70Daniel Veillard    return(Py_None);
221726f70269c80140a7fb8a7aae9ef09c95efa98e70Daniel Veillard}
2218438ebbd59af78c436397ae488e42aeca5cad7542Daniel Veillard#endif
221926f70269c80140a7fb8a7aae9ef09c95efa98e70Daniel Veillard
222026f70269c80140a7fb8a7aae9ef09c95efa98e70Daniel Veillard/************************************************************************
222126f70269c80140a7fb8a7aae9ef09c95efa98e70Daniel Veillard *									*
2222a7340c830e4bddd86201cfdb97ac81e30b0dee62Daniel Veillard *			XPath extensions				*
2223a7340c830e4bddd86201cfdb97ac81e30b0dee62Daniel Veillard *									*
2224a7340c830e4bddd86201cfdb97ac81e30b0dee62Daniel Veillard ************************************************************************/
2225a7340c830e4bddd86201cfdb97ac81e30b0dee62Daniel Veillard
2226a7340c830e4bddd86201cfdb97ac81e30b0dee62Daniel Veillardstatic void
2227d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillardlibxml_xmlXPathFuncCallback(xmlXPathParserContextPtr ctxt, int nargs)
2228d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard{
2229a7340c830e4bddd86201cfdb97ac81e30b0dee62Daniel Veillard    PyObject *list, *cur, *result;
2230a7340c830e4bddd86201cfdb97ac81e30b0dee62Daniel Veillard    xmlXPathObjectPtr obj;
223170cab35abbb75eb9f0e328d498aa7a85195a1d5bDaniel Veillard    xmlXPathContextPtr rctxt;
223270cab35abbb75eb9f0e328d498aa7a85195a1d5bDaniel Veillard    PyObject *current_function = NULL;
223370cab35abbb75eb9f0e328d498aa7a85195a1d5bDaniel Veillard    const xmlChar *name;
223470cab35abbb75eb9f0e328d498aa7a85195a1d5bDaniel Veillard    const xmlChar *ns_uri;
2235a7340c830e4bddd86201cfdb97ac81e30b0dee62Daniel Veillard    int i;
2236a7340c830e4bddd86201cfdb97ac81e30b0dee62Daniel Veillard
223770cab35abbb75eb9f0e328d498aa7a85195a1d5bDaniel Veillard    if (ctxt == NULL)
2238d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        return;
223970cab35abbb75eb9f0e328d498aa7a85195a1d5bDaniel Veillard    rctxt = ctxt->context;
224070cab35abbb75eb9f0e328d498aa7a85195a1d5bDaniel Veillard    if (rctxt == NULL)
2241d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        return;
224270cab35abbb75eb9f0e328d498aa7a85195a1d5bDaniel Veillard    name = rctxt->function;
224370cab35abbb75eb9f0e328d498aa7a85195a1d5bDaniel Veillard    ns_uri = rctxt->functionURI;
2244a7340c830e4bddd86201cfdb97ac81e30b0dee62Daniel Veillard#ifdef DEBUG_XPATH
2245d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard    printf("libxml_xmlXPathFuncCallback called name %s URI %s\n", name,
2246d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard           ns_uri);
2247a7340c830e4bddd86201cfdb97ac81e30b0dee62Daniel Veillard#endif
2248a7340c830e4bddd86201cfdb97ac81e30b0dee62Daniel Veillard
224970cab35abbb75eb9f0e328d498aa7a85195a1d5bDaniel Veillard    /*
225070cab35abbb75eb9f0e328d498aa7a85195a1d5bDaniel Veillard     * Find the function, it should be there it was there at lookup
225170cab35abbb75eb9f0e328d498aa7a85195a1d5bDaniel Veillard     */
2252d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard    for (i = 0; i < libxml_xpathCallbacksNb; i++) {
2253d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        if (                    /* TODO (ctxt == libxml_xpathCallbacks[i].ctx) && */
22548e2cc6f2b53f536692f3c8ad8112bb67e0a1a629William M. Brack						(xmlStrEqual(name, (*libxml_xpathCallbacks)[i].name)) &&
22558e2cc6f2b53f536692f3c8ad8112bb67e0a1a629William M. Brack               (xmlStrEqual(ns_uri, (*libxml_xpathCallbacks)[i].ns_uri))) {
22568e2cc6f2b53f536692f3c8ad8112bb67e0a1a629William M. Brack					current_function = (*libxml_xpathCallbacks)[i].function;
2257d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        }
225870cab35abbb75eb9f0e328d498aa7a85195a1d5bDaniel Veillard    }
225970cab35abbb75eb9f0e328d498aa7a85195a1d5bDaniel Veillard    if (current_function == NULL) {
2260d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        printf
2261d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            ("libxml_xmlXPathFuncCallback: internal error %s not found !\n",
2262d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard             name);
2263d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        return;
226470cab35abbb75eb9f0e328d498aa7a85195a1d5bDaniel Veillard    }
226570cab35abbb75eb9f0e328d498aa7a85195a1d5bDaniel Veillard
2266c575b997d85d4791d852ad43e175d47a64cf8b3cDaniel Veillard    list = PyTuple_New(nargs + 1);
2267c575b997d85d4791d852ad43e175d47a64cf8b3cDaniel Veillard    PyTuple_SetItem(list, 0, libxml_xmlXPathParserContextPtrWrap(ctxt));
226805349ab2f6995d33f06932aa3cc62cf420ce0477Daniel Veillard    for (i = nargs - 1; i >= 0; i--) {
2269d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        obj = valuePop(ctxt);
2270d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        cur = libxml_xmlXPathObjectPtrWrap(obj);
2271d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        PyTuple_SetItem(list, i + 1, cur);
2272a7340c830e4bddd86201cfdb97ac81e30b0dee62Daniel Veillard    }
2273a7340c830e4bddd86201cfdb97ac81e30b0dee62Daniel Veillard    result = PyEval_CallObject(current_function, list);
2274a7340c830e4bddd86201cfdb97ac81e30b0dee62Daniel Veillard    Py_DECREF(list);
2275a7340c830e4bddd86201cfdb97ac81e30b0dee62Daniel Veillard
2276a7340c830e4bddd86201cfdb97ac81e30b0dee62Daniel Veillard    obj = libxml_xmlXPathObjectPtrConvert(result);
2277a7340c830e4bddd86201cfdb97ac81e30b0dee62Daniel Veillard    valuePush(ctxt, obj);
2278a7340c830e4bddd86201cfdb97ac81e30b0dee62Daniel Veillard}
2279a7340c830e4bddd86201cfdb97ac81e30b0dee62Daniel Veillard
2280a7340c830e4bddd86201cfdb97ac81e30b0dee62Daniel Veillardstatic xmlXPathFunction
2281d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillardlibxml_xmlXPathFuncLookupFunc(void *ctxt, const xmlChar * name,
2282d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard                              const xmlChar * ns_uri)
2283d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard{
2284a7340c830e4bddd86201cfdb97ac81e30b0dee62Daniel Veillard    int i;
2285d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard
2286a7340c830e4bddd86201cfdb97ac81e30b0dee62Daniel Veillard#ifdef DEBUG_XPATH
2287a7340c830e4bddd86201cfdb97ac81e30b0dee62Daniel Veillard    printf("libxml_xmlXPathFuncLookupFunc(%p, %s, %s) called\n",
2288d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard           ctxt, name, ns_uri);
2289a7340c830e4bddd86201cfdb97ac81e30b0dee62Daniel Veillard#endif
229070cab35abbb75eb9f0e328d498aa7a85195a1d5bDaniel Veillard    /*
229170cab35abbb75eb9f0e328d498aa7a85195a1d5bDaniel Veillard     * This is called once only. The address is then stored in the
229270cab35abbb75eb9f0e328d498aa7a85195a1d5bDaniel Veillard     * XPath expression evaluation, the proper object to call can
229370cab35abbb75eb9f0e328d498aa7a85195a1d5bDaniel Veillard     * then still be found using the execution context function
229470cab35abbb75eb9f0e328d498aa7a85195a1d5bDaniel Veillard     * and functionURI fields.
229570cab35abbb75eb9f0e328d498aa7a85195a1d5bDaniel Veillard     */
2296d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard    for (i = 0; i < libxml_xpathCallbacksNb; i++) {
22978e2cc6f2b53f536692f3c8ad8112bb67e0a1a629William M. Brack			if ((ctxt == (*libxml_xpathCallbacks)[i].ctx) &&
22988e2cc6f2b53f536692f3c8ad8112bb67e0a1a629William M. Brack					(xmlStrEqual(name, (*libxml_xpathCallbacks)[i].name)) &&
22998e2cc6f2b53f536692f3c8ad8112bb67e0a1a629William M. Brack					(xmlStrEqual(ns_uri, (*libxml_xpathCallbacks)[i].ns_uri))) {
2300d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            return (libxml_xmlXPathFuncCallback);
2301d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        }
2302a7340c830e4bddd86201cfdb97ac81e30b0dee62Daniel Veillard    }
2303d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard    return (NULL);
2304a7340c830e4bddd86201cfdb97ac81e30b0dee62Daniel Veillard}
2305a7340c830e4bddd86201cfdb97ac81e30b0dee62Daniel Veillard
2306a7340c830e4bddd86201cfdb97ac81e30b0dee62Daniel Veillardstatic void
2307d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillardlibxml_xpathCallbacksInitialize(void)
2308d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard{
2309a7340c830e4bddd86201cfdb97ac81e30b0dee62Daniel Veillard    int i;
2310a7340c830e4bddd86201cfdb97ac81e30b0dee62Daniel Veillard
2311a7340c830e4bddd86201cfdb97ac81e30b0dee62Daniel Veillard    if (libxml_xpathCallbacksInitialized != 0)
2312d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        return;
2313a7340c830e4bddd86201cfdb97ac81e30b0dee62Daniel Veillard
2314a7340c830e4bddd86201cfdb97ac81e30b0dee62Daniel Veillard#ifdef DEBUG_XPATH
2315a7340c830e4bddd86201cfdb97ac81e30b0dee62Daniel Veillard    printf("libxml_xpathCallbacksInitialized called\n");
2316a7340c830e4bddd86201cfdb97ac81e30b0dee62Daniel Veillard#endif
23178e2cc6f2b53f536692f3c8ad8112bb67e0a1a629William M. Brack    libxml_xpathCallbacks = (libxml_xpathCallbackArray*)xmlMalloc(
23188e2cc6f2b53f536692f3c8ad8112bb67e0a1a629William M. Brack    		libxml_xpathCallbacksAllocd*sizeof(libxml_xpathCallback));
2319a7340c830e4bddd86201cfdb97ac81e30b0dee62Daniel Veillard
23208e2cc6f2b53f536692f3c8ad8112bb67e0a1a629William M. Brack    for (i = 0; i < libxml_xpathCallbacksAllocd; i++) {
23218e2cc6f2b53f536692f3c8ad8112bb67e0a1a629William M. Brack			(*libxml_xpathCallbacks)[i].ctx = NULL;
23228e2cc6f2b53f536692f3c8ad8112bb67e0a1a629William M. Brack			(*libxml_xpathCallbacks)[i].name = NULL;
23238e2cc6f2b53f536692f3c8ad8112bb67e0a1a629William M. Brack			(*libxml_xpathCallbacks)[i].ns_uri = NULL;
23248e2cc6f2b53f536692f3c8ad8112bb67e0a1a629William M. Brack			(*libxml_xpathCallbacks)[i].function = NULL;
2325a7340c830e4bddd86201cfdb97ac81e30b0dee62Daniel Veillard    }
2326a7340c830e4bddd86201cfdb97ac81e30b0dee62Daniel Veillard    libxml_xpathCallbacksInitialized = 1;
2327a7340c830e4bddd86201cfdb97ac81e30b0dee62Daniel Veillard}
2328a7340c830e4bddd86201cfdb97ac81e30b0dee62Daniel Veillard
2329a7340c830e4bddd86201cfdb97ac81e30b0dee62Daniel VeillardPyObject *
2330d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillardlibxml_xmlRegisterXPathFunction(ATTRIBUTE_UNUSED PyObject * self,
2331d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard                                PyObject * args)
2332d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard{
2333a7340c830e4bddd86201cfdb97ac81e30b0dee62Daniel Veillard    PyObject *py_retval;
2334a7340c830e4bddd86201cfdb97ac81e30b0dee62Daniel Veillard    int c_retval = 0;
2335a7340c830e4bddd86201cfdb97ac81e30b0dee62Daniel Veillard    xmlChar *name;
2336a7340c830e4bddd86201cfdb97ac81e30b0dee62Daniel Veillard    xmlChar *ns_uri;
2337a7340c830e4bddd86201cfdb97ac81e30b0dee62Daniel Veillard    xmlXPathContextPtr ctx;
2338a7340c830e4bddd86201cfdb97ac81e30b0dee62Daniel Veillard    PyObject *pyobj_ctx;
2339a7340c830e4bddd86201cfdb97ac81e30b0dee62Daniel Veillard    PyObject *pyobj_f;
2340a7340c830e4bddd86201cfdb97ac81e30b0dee62Daniel Veillard    int i;
2341a7340c830e4bddd86201cfdb97ac81e30b0dee62Daniel Veillard
2342d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard    if (!PyArg_ParseTuple
2343d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        (args, (char *) "OszO:registerXPathFunction", &pyobj_ctx, &name,
2344d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard         &ns_uri, &pyobj_f))
2345d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        return (NULL);
2346a7340c830e4bddd86201cfdb97ac81e30b0dee62Daniel Veillard
2347a7340c830e4bddd86201cfdb97ac81e30b0dee62Daniel Veillard    ctx = (xmlXPathContextPtr) PyxmlXPathContext_Get(pyobj_ctx);
2348a7340c830e4bddd86201cfdb97ac81e30b0dee62Daniel Veillard    if (libxml_xpathCallbacksInitialized == 0)
2349d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        libxml_xpathCallbacksInitialize();
2350a7340c830e4bddd86201cfdb97ac81e30b0dee62Daniel Veillard    xmlXPathRegisterFuncLookup(ctx, libxml_xmlXPathFuncLookupFunc, ctx);
2351a7340c830e4bddd86201cfdb97ac81e30b0dee62Daniel Veillard
2352a7340c830e4bddd86201cfdb97ac81e30b0dee62Daniel Veillard    if ((pyobj_ctx == NULL) || (name == NULL) || (pyobj_f == NULL)) {
2353d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        py_retval = libxml_intWrap(-1);
2354d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        return (py_retval);
2355a7340c830e4bddd86201cfdb97ac81e30b0dee62Daniel Veillard    }
2356a7340c830e4bddd86201cfdb97ac81e30b0dee62Daniel Veillard#ifdef DEBUG_XPATH
2357a7340c830e4bddd86201cfdb97ac81e30b0dee62Daniel Veillard    printf("libxml_registerXPathFunction(%p, %s, %s) called\n",
2358d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard           ctx, name, ns_uri);
2359a7340c830e4bddd86201cfdb97ac81e30b0dee62Daniel Veillard#endif
2360d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard    for (i = 0; i < libxml_xpathCallbacksNb; i++) {
23618e2cc6f2b53f536692f3c8ad8112bb67e0a1a629William M. Brack	if ((ctx == (*libxml_xpathCallbacks)[i].ctx) &&
23628e2cc6f2b53f536692f3c8ad8112bb67e0a1a629William M. Brack            (xmlStrEqual(name, (*libxml_xpathCallbacks)[i].name)) &&
23638e2cc6f2b53f536692f3c8ad8112bb67e0a1a629William M. Brack            (xmlStrEqual(ns_uri, (*libxml_xpathCallbacks)[i].ns_uri))) {
2364d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            Py_XINCREF(pyobj_f);
23658e2cc6f2b53f536692f3c8ad8112bb67e0a1a629William M. Brack            Py_XDECREF((*libxml_xpathCallbacks)[i].function);
23668e2cc6f2b53f536692f3c8ad8112bb67e0a1a629William M. Brack            (*libxml_xpathCallbacks)[i].function = pyobj_f;
2367d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            c_retval = 1;
2368d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            goto done;
2369d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        }
2370a7340c830e4bddd86201cfdb97ac81e30b0dee62Daniel Veillard    }
23718e2cc6f2b53f536692f3c8ad8112bb67e0a1a629William M. Brack    if (libxml_xpathCallbacksNb >= libxml_xpathCallbacksAllocd) {
23728e2cc6f2b53f536692f3c8ad8112bb67e0a1a629William M. Brack			libxml_xpathCallbacksAllocd+=10;
23738e2cc6f2b53f536692f3c8ad8112bb67e0a1a629William M. Brack	libxml_xpathCallbacks = (libxml_xpathCallbackArray*)xmlRealloc(
23748e2cc6f2b53f536692f3c8ad8112bb67e0a1a629William M. Brack		libxml_xpathCallbacks,
23758e2cc6f2b53f536692f3c8ad8112bb67e0a1a629William M. Brack		libxml_xpathCallbacksAllocd*sizeof(libxml_xpathCallback));
23768e2cc6f2b53f536692f3c8ad8112bb67e0a1a629William M. Brack    }
23778e2cc6f2b53f536692f3c8ad8112bb67e0a1a629William M. Brack    i = libxml_xpathCallbacksNb++;
23788e2cc6f2b53f536692f3c8ad8112bb67e0a1a629William M. Brack    Py_XINCREF(pyobj_f);
23798e2cc6f2b53f536692f3c8ad8112bb67e0a1a629William M. Brack    (*libxml_xpathCallbacks)[i].ctx = ctx;
23808e2cc6f2b53f536692f3c8ad8112bb67e0a1a629William M. Brack    (*libxml_xpathCallbacks)[i].name = xmlStrdup(name);
23818e2cc6f2b53f536692f3c8ad8112bb67e0a1a629William M. Brack    (*libxml_xpathCallbacks)[i].ns_uri = xmlStrdup(ns_uri);
23828e2cc6f2b53f536692f3c8ad8112bb67e0a1a629William M. Brack    (*libxml_xpathCallbacks)[i].function = pyobj_f;
2383d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        c_retval = 1;
23848e2cc6f2b53f536692f3c8ad8112bb67e0a1a629William M. Brack
2385d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard  done:
2386a7340c830e4bddd86201cfdb97ac81e30b0dee62Daniel Veillard    py_retval = libxml_intWrap((int) c_retval);
2387519bc6a3ab82445a8719f548d0450efe02cc9c82Shaun McCance    return (py_retval);
2388519bc6a3ab82445a8719f548d0450efe02cc9c82Shaun McCance}
2389519bc6a3ab82445a8719f548d0450efe02cc9c82Shaun McCance
2390519bc6a3ab82445a8719f548d0450efe02cc9c82Shaun McCancePyObject *
2391519bc6a3ab82445a8719f548d0450efe02cc9c82Shaun McCancelibxml_xmlXPathRegisterVariable(ATTRIBUTE_UNUSED PyObject * self,
2392519bc6a3ab82445a8719f548d0450efe02cc9c82Shaun McCance                                PyObject * args)
2393519bc6a3ab82445a8719f548d0450efe02cc9c82Shaun McCance{
2394519bc6a3ab82445a8719f548d0450efe02cc9c82Shaun McCance    PyObject *py_retval;
2395519bc6a3ab82445a8719f548d0450efe02cc9c82Shaun McCance    int c_retval = 0;
2396519bc6a3ab82445a8719f548d0450efe02cc9c82Shaun McCance    xmlChar *name;
2397519bc6a3ab82445a8719f548d0450efe02cc9c82Shaun McCance    xmlChar *ns_uri;
2398519bc6a3ab82445a8719f548d0450efe02cc9c82Shaun McCance    xmlXPathContextPtr ctx;
2399519bc6a3ab82445a8719f548d0450efe02cc9c82Shaun McCance    xmlXPathObjectPtr val;
2400519bc6a3ab82445a8719f548d0450efe02cc9c82Shaun McCance    PyObject *pyobj_ctx;
2401519bc6a3ab82445a8719f548d0450efe02cc9c82Shaun McCance    PyObject *pyobj_value;
2402519bc6a3ab82445a8719f548d0450efe02cc9c82Shaun McCance
2403519bc6a3ab82445a8719f548d0450efe02cc9c82Shaun McCance    if (!PyArg_ParseTuple
2404519bc6a3ab82445a8719f548d0450efe02cc9c82Shaun McCance        (args, (char *) "OszO:xpathRegisterVariable", &pyobj_ctx, &name,
2405519bc6a3ab82445a8719f548d0450efe02cc9c82Shaun McCance         &ns_uri, &pyobj_value))
2406519bc6a3ab82445a8719f548d0450efe02cc9c82Shaun McCance        return (NULL);
2407519bc6a3ab82445a8719f548d0450efe02cc9c82Shaun McCance
2408519bc6a3ab82445a8719f548d0450efe02cc9c82Shaun McCance    ctx = (xmlXPathContextPtr) PyxmlXPathContext_Get(pyobj_ctx);
2409519bc6a3ab82445a8719f548d0450efe02cc9c82Shaun McCance    val = libxml_xmlXPathObjectPtrConvert(pyobj_value);
2410519bc6a3ab82445a8719f548d0450efe02cc9c82Shaun McCance
2411519bc6a3ab82445a8719f548d0450efe02cc9c82Shaun McCance    c_retval = xmlXPathRegisterVariableNS(ctx, name, ns_uri, val);
2412519bc6a3ab82445a8719f548d0450efe02cc9c82Shaun McCance    py_retval = libxml_intWrap(c_retval);
2413d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard    return (py_retval);
2414a7340c830e4bddd86201cfdb97ac81e30b0dee62Daniel Veillard}
2415a7340c830e4bddd86201cfdb97ac81e30b0dee62Daniel Veillard
24161971ee2698cb84c7699c96d3302f00e20d42c0d3Daniel Veillard/************************************************************************
24171971ee2698cb84c7699c96d3302f00e20d42c0d3Daniel Veillard *									*
2418d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard *			Global properties access			*
2419d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard *									*
2420d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard ************************************************************************/
2421d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillardstatic PyObject *
2422d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillardlibxml_name(ATTRIBUTE_UNUSED PyObject * self, PyObject * args)
2423d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard{
2424d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard    PyObject *resultobj, *obj;
2425d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard    xmlNodePtr cur;
2426d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard    const xmlChar *res;
2427d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard
2428d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard    if (!PyArg_ParseTuple(args, (char *) "O:name", &obj))
2429d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard        return NULL;
2430d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard    cur = PyxmlNode_Get(obj);
2431d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard
2432d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard#ifdef DEBUG
2433d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard    printf("libxml_name: cur = %p type %d\n", cur, cur->type);
2434d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard#endif
2435d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard
2436d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard    switch (cur->type) {
2437d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        case XML_DOCUMENT_NODE:
2438d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard#ifdef LIBXML_DOCB_ENABLED
2439d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        case XML_DOCB_DOCUMENT_NODE:
2440d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard#endif
2441d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        case XML_HTML_DOCUMENT_NODE:{
2442d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard                xmlDocPtr doc = (xmlDocPtr) cur;
2443d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard
2444d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard                res = doc->URL;
2445d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard                break;
2446d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            }
2447d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        case XML_ATTRIBUTE_NODE:{
2448d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard                xmlAttrPtr attr = (xmlAttrPtr) cur;
2449d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard
2450d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard                res = attr->name;
2451d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard                break;
2452d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            }
2453d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        case XML_NAMESPACE_DECL:{
2454d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard                xmlNsPtr ns = (xmlNsPtr) cur;
2455d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard
2456d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard                res = ns->prefix;
2457d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard                break;
2458d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            }
2459d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        default:
2460d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            res = cur->name;
2461d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            break;
2462d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard    }
24631971ee2698cb84c7699c96d3302f00e20d42c0d3Daniel Veillard    resultobj = libxml_constxmlCharPtrWrap(res);
2464d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard
2465d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard    return resultobj;
2466d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard}
2467d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard
2468d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillardstatic PyObject *
2469d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillardlibxml_doc(ATTRIBUTE_UNUSED PyObject * self, PyObject * args)
2470d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard{
2471d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard    PyObject *resultobj, *obj;
2472d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard    xmlNodePtr cur;
2473d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard    xmlDocPtr res;
2474d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard
2475d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard    if (!PyArg_ParseTuple(args, (char *) "O:doc", &obj))
2476d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard        return NULL;
2477d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard    cur = PyxmlNode_Get(obj);
2478d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard
2479d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard#ifdef DEBUG
2480d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard    printf("libxml_doc: cur = %p\n", cur);
2481d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard#endif
2482d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard
2483d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard    switch (cur->type) {
2484d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        case XML_DOCUMENT_NODE:
2485d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard#ifdef LIBXML_DOCB_ENABLED
2486d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        case XML_DOCB_DOCUMENT_NODE:
2487d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard#endif
2488d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        case XML_HTML_DOCUMENT_NODE:
2489d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            res = NULL;
2490d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            break;
2491d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        case XML_ATTRIBUTE_NODE:{
2492d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard                xmlAttrPtr attr = (xmlAttrPtr) cur;
2493d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard
2494d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard                res = attr->doc;
2495d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard                break;
2496d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            }
2497d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        case XML_NAMESPACE_DECL:
2498d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            res = NULL;
2499d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            break;
2500d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        default:
2501d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            res = cur->doc;
2502d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            break;
2503d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard    }
2504d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard    resultobj = libxml_xmlDocPtrWrap(res);
2505d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard    return resultobj;
2506d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard}
2507d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard
2508d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillardstatic PyObject *
2509d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillardlibxml_properties(ATTRIBUTE_UNUSED PyObject * self, PyObject * args)
2510d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard{
2511d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard    PyObject *resultobj, *obj;
25122728f845c5581af9213057ace8b3f664d64c15a9Daniel Veillard    xmlNodePtr cur;
2513d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard    xmlAttrPtr res;
2514d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard
2515d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard    if (!PyArg_ParseTuple(args, (char *) "O:properties", &obj))
2516d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard        return NULL;
2517d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard    cur = PyxmlNode_Get(obj);
25182728f845c5581af9213057ace8b3f664d64c15a9Daniel Veillard    if ((cur != NULL) && (cur->type == XML_ELEMENT_NODE))
2519d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        res = cur->properties;
2520d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard    else
2521d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        res = NULL;
2522d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard    resultobj = libxml_xmlAttrPtrWrap(res);
2523d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard    return resultobj;
2524d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard}
2525d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard
2526d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillardstatic PyObject *
2527d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillardlibxml_next(ATTRIBUTE_UNUSED PyObject * self, PyObject * args)
2528d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard{
2529d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard    PyObject *resultobj, *obj;
2530d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard    xmlNodePtr cur;
2531d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard    xmlNodePtr res;
2532d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard
2533d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard    if (!PyArg_ParseTuple(args, (char *) "O:next", &obj))
2534d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard        return NULL;
2535d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard    cur = PyxmlNode_Get(obj);
2536d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard
2537d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard#ifdef DEBUG
2538d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard    printf("libxml_next: cur = %p\n", cur);
2539d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard#endif
2540d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard
2541d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard    switch (cur->type) {
2542d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        case XML_DOCUMENT_NODE:
2543d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard#ifdef LIBXML_DOCB_ENABLED
2544d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        case XML_DOCB_DOCUMENT_NODE:
2545d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard#endif
2546d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        case XML_HTML_DOCUMENT_NODE:
2547d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            res = NULL;
2548d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            break;
2549d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        case XML_ATTRIBUTE_NODE:{
2550d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard                xmlAttrPtr attr = (xmlAttrPtr) cur;
2551d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard
2552d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard                res = (xmlNodePtr) attr->next;
2553d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard                break;
2554d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            }
2555d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        case XML_NAMESPACE_DECL:{
2556d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard                xmlNsPtr ns = (xmlNsPtr) cur;
2557d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard
2558d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard                res = (xmlNodePtr) ns->next;
2559d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard                break;
2560d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            }
2561d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        default:
2562d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            res = cur->next;
2563d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            break;
2564d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard
2565d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard    }
2566d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard    resultobj = libxml_xmlNodePtrWrap(res);
2567d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard    return resultobj;
2568d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard}
2569d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard
2570d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillardstatic PyObject *
2571d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillardlibxml_prev(ATTRIBUTE_UNUSED PyObject * self, PyObject * args)
2572d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard{
2573d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard    PyObject *resultobj, *obj;
2574d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard    xmlNodePtr cur;
2575d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard    xmlNodePtr res;
2576d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard
2577d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard    if (!PyArg_ParseTuple(args, (char *) "O:prev", &obj))
2578d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard        return NULL;
2579d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard    cur = PyxmlNode_Get(obj);
2580d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard
2581d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard#ifdef DEBUG
2582d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard    printf("libxml_prev: cur = %p\n", cur);
2583d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard#endif
2584d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard
2585d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard    switch (cur->type) {
2586d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        case XML_DOCUMENT_NODE:
2587d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard#ifdef LIBXML_DOCB_ENABLED
2588d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        case XML_DOCB_DOCUMENT_NODE:
2589d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard#endif
2590d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        case XML_HTML_DOCUMENT_NODE:
2591d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            res = NULL;
2592d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            break;
2593d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        case XML_ATTRIBUTE_NODE:{
2594d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard                xmlAttrPtr attr = (xmlAttrPtr) cur;
2595d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard
2596faa35ff3cdcf15154dd207606a31b34923da9be9Daniel Veillard                res = (xmlNodePtr) attr->prev;
2597d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            }
2598594e5dfb48ee6fbac1b64155839063648022fc57Daniel Veillard            break;
2599d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        case XML_NAMESPACE_DECL:
2600d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            res = NULL;
2601d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            break;
2602d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        default:
2603faa35ff3cdcf15154dd207606a31b34923da9be9Daniel Veillard            res = cur->prev;
2604d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            break;
2605d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard    }
2606d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard    resultobj = libxml_xmlNodePtrWrap(res);
2607d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard    return resultobj;
2608d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard}
2609d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard
2610d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillardstatic PyObject *
2611d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillardlibxml_children(ATTRIBUTE_UNUSED PyObject * self, PyObject * args)
2612d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard{
2613d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard    PyObject *resultobj, *obj;
2614d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard    xmlNodePtr cur;
2615d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard    xmlNodePtr res;
2616d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard
2617d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard    if (!PyArg_ParseTuple(args, (char *) "O:children", &obj))
2618d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard        return NULL;
2619d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard    cur = PyxmlNode_Get(obj);
2620d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard
2621d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard#ifdef DEBUG
2622d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard    printf("libxml_children: cur = %p\n", cur);
2623d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard#endif
2624d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard
2625d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard    switch (cur->type) {
2626d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        case XML_ELEMENT_NODE:
2627d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        case XML_ENTITY_REF_NODE:
2628d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        case XML_ENTITY_NODE:
2629d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        case XML_PI_NODE:
2630d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        case XML_COMMENT_NODE:
2631d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        case XML_DOCUMENT_NODE:
2632d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard#ifdef LIBXML_DOCB_ENABLED
2633d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        case XML_DOCB_DOCUMENT_NODE:
2634d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard#endif
2635d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        case XML_HTML_DOCUMENT_NODE:
2636d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        case XML_DTD_NODE:
2637d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            res = cur->children;
2638d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            break;
2639d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        case XML_ATTRIBUTE_NODE:{
2640d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard                xmlAttrPtr attr = (xmlAttrPtr) cur;
2641d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard
2642d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard                res = attr->children;
2643d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard                break;
2644d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            }
2645d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        default:
2646d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            res = NULL;
2647d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            break;
2648d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard    }
2649d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard    resultobj = libxml_xmlNodePtrWrap(res);
2650d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard    return resultobj;
2651d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard}
2652d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard
2653d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillardstatic PyObject *
2654d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillardlibxml_last(ATTRIBUTE_UNUSED PyObject * self, PyObject * args)
2655d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard{
2656d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard    PyObject *resultobj, *obj;
2657d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard    xmlNodePtr cur;
2658d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard    xmlNodePtr res;
2659d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard
2660d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard    if (!PyArg_ParseTuple(args, (char *) "O:last", &obj))
2661d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard        return NULL;
2662d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard    cur = PyxmlNode_Get(obj);
2663d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard
2664d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard#ifdef DEBUG
2665d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard    printf("libxml_last: cur = %p\n", cur);
2666d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard#endif
2667d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard
2668d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard    switch (cur->type) {
2669d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        case XML_ELEMENT_NODE:
2670d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        case XML_ENTITY_REF_NODE:
2671d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        case XML_ENTITY_NODE:
2672d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        case XML_PI_NODE:
2673d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        case XML_COMMENT_NODE:
2674d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        case XML_DOCUMENT_NODE:
2675d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard#ifdef LIBXML_DOCB_ENABLED
2676d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        case XML_DOCB_DOCUMENT_NODE:
2677d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard#endif
2678d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        case XML_HTML_DOCUMENT_NODE:
2679d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        case XML_DTD_NODE:
2680d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            res = cur->last;
2681d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            break;
2682d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        case XML_ATTRIBUTE_NODE:{
2683d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard                xmlAttrPtr attr = (xmlAttrPtr) cur;
2684d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard
2685d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard                res = attr->last;
268610ec19ab0a49936ca8ca0d6962d24d3f889960a5dcb		break;
2687d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            }
2688d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        default:
2689d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            res = NULL;
2690d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            break;
2691d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard    }
2692d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard    resultobj = libxml_xmlNodePtrWrap(res);
2693d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard    return resultobj;
2694d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard}
2695d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard
2696d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillardstatic PyObject *
2697d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillardlibxml_parent(ATTRIBUTE_UNUSED PyObject * self, PyObject * args)
2698d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard{
2699d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard    PyObject *resultobj, *obj;
2700d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard    xmlNodePtr cur;
2701d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard    xmlNodePtr res;
2702d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard
2703d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard    if (!PyArg_ParseTuple(args, (char *) "O:parent", &obj))
2704d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard        return NULL;
2705d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard    cur = PyxmlNode_Get(obj);
2706d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard
2707d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard#ifdef DEBUG
2708d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard    printf("libxml_parent: cur = %p\n", cur);
2709d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard#endif
2710d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard
2711d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard    switch (cur->type) {
2712d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        case XML_DOCUMENT_NODE:
2713d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        case XML_HTML_DOCUMENT_NODE:
2714d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard#ifdef LIBXML_DOCB_ENABLED
2715d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        case XML_DOCB_DOCUMENT_NODE:
2716d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard#endif
2717d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            res = NULL;
2718d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            break;
2719d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        case XML_ATTRIBUTE_NODE:{
2720d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard                xmlAttrPtr attr = (xmlAttrPtr) cur;
2721d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard
2722d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard                res = attr->parent;
2723d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            }
272422eda2bc82acd047247df3f88aa9a5ab08d6a434Daniel Veillard	    break;
2725d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        case XML_ENTITY_DECL:
2726d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        case XML_NAMESPACE_DECL:
2727d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        case XML_XINCLUDE_START:
2728d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        case XML_XINCLUDE_END:
2729d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            res = NULL;
2730d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            break;
2731d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        default:
2732d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            res = cur->parent;
2733d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            break;
2734d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard    }
2735d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard    resultobj = libxml_xmlNodePtrWrap(res);
2736d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard    return resultobj;
2737d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard}
2738d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard
2739d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillardstatic PyObject *
2740d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillardlibxml_type(ATTRIBUTE_UNUSED PyObject * self, PyObject * args)
2741d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard{
2742d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard    PyObject *resultobj, *obj;
2743d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard    xmlNodePtr cur;
2744d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard    const xmlChar *res = NULL;
2745d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard
2746d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard    if (!PyArg_ParseTuple(args, (char *) "O:last", &obj))
2747d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard        return NULL;
2748d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard    cur = PyxmlNode_Get(obj);
27493798c4adbb91f80bef1e9f1b4b61dae72577a244Daniel Veillard    if (cur == NULL) {
27503798c4adbb91f80bef1e9f1b4b61dae72577a244Daniel Veillard        Py_INCREF(Py_None);
27513798c4adbb91f80bef1e9f1b4b61dae72577a244Daniel Veillard	return (Py_None);
27523798c4adbb91f80bef1e9f1b4b61dae72577a244Daniel Veillard    }
2753d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard
2754d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard#ifdef DEBUG
2755d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard    printf("libxml_type: cur = %p\n", cur);
2756d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard#endif
2757d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard
2758d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard    switch (cur->type) {
2759d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard        case XML_ELEMENT_NODE:
2760d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            res = (const xmlChar *) "element";
2761d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            break;
2762d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard        case XML_ATTRIBUTE_NODE:
2763d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            res = (const xmlChar *) "attribute";
2764d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            break;
2765d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard        case XML_TEXT_NODE:
2766d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            res = (const xmlChar *) "text";
2767d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            break;
2768d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard        case XML_CDATA_SECTION_NODE:
2769d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            res = (const xmlChar *) "cdata";
2770d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            break;
2771d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard        case XML_ENTITY_REF_NODE:
2772d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            res = (const xmlChar *) "entity_ref";
2773d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            break;
2774d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard        case XML_ENTITY_NODE:
2775d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            res = (const xmlChar *) "entity";
2776d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            break;
2777d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard        case XML_PI_NODE:
2778d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            res = (const xmlChar *) "pi";
2779d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            break;
2780d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard        case XML_COMMENT_NODE:
2781d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            res = (const xmlChar *) "comment";
2782d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            break;
2783d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard        case XML_DOCUMENT_NODE:
2784d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            res = (const xmlChar *) "document_xml";
2785d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            break;
2786d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard        case XML_DOCUMENT_TYPE_NODE:
2787d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            res = (const xmlChar *) "doctype";
2788d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            break;
2789d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard        case XML_DOCUMENT_FRAG_NODE:
2790d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            res = (const xmlChar *) "fragment";
2791d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            break;
2792d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard        case XML_NOTATION_NODE:
2793d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            res = (const xmlChar *) "notation";
2794d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            break;
2795d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard        case XML_HTML_DOCUMENT_NODE:
2796d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            res = (const xmlChar *) "document_html";
2797d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            break;
2798d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard        case XML_DTD_NODE:
2799d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            res = (const xmlChar *) "dtd";
2800d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            break;
2801d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard        case XML_ELEMENT_DECL:
2802d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            res = (const xmlChar *) "elem_decl";
2803d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            break;
2804d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard        case XML_ATTRIBUTE_DECL:
2805d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            res = (const xmlChar *) "attribute_decl";
2806d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            break;
2807d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard        case XML_ENTITY_DECL:
2808d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            res = (const xmlChar *) "entity_decl";
2809d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            break;
2810d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard        case XML_NAMESPACE_DECL:
2811d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            res = (const xmlChar *) "namespace";
2812d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            break;
2813d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard        case XML_XINCLUDE_START:
2814d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            res = (const xmlChar *) "xinclude_start";
2815d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            break;
2816d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard        case XML_XINCLUDE_END:
2817d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            res = (const xmlChar *) "xinclude_end";
2818d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            break;
2819d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard#ifdef LIBXML_DOCB_ENABLED
2820d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        case XML_DOCB_DOCUMENT_NODE:
2821d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            res = (const xmlChar *) "document_docbook";
2822d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            break;
2823d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard#endif
2824d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard    }
2825d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard#ifdef DEBUG
2826d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard    printf("libxml_type: cur = %p: %s\n", cur, res);
2827d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard#endif
2828d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard
28291971ee2698cb84c7699c96d3302f00e20d42c0d3Daniel Veillard    resultobj = libxml_constxmlCharPtrWrap(res);
2830d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard    return resultobj;
2831d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard}
2832d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard
2833d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard/************************************************************************
2834d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard *									*
283536eea2d2ee84132e66552f84724e9b377d687681Daniel Veillard *			Specific accessor functions			*
283636eea2d2ee84132e66552f84724e9b377d687681Daniel Veillard *									*
283736eea2d2ee84132e66552f84724e9b377d687681Daniel Veillard ************************************************************************/
283836eea2d2ee84132e66552f84724e9b377d687681Daniel VeillardPyObject *
2839d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillardlibxml_xmlNodeGetNsDefs(ATTRIBUTE_UNUSED PyObject * self, PyObject * args)
2840d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard{
284136eea2d2ee84132e66552f84724e9b377d687681Daniel Veillard    PyObject *py_retval;
284236eea2d2ee84132e66552f84724e9b377d687681Daniel Veillard    xmlNsPtr c_retval;
284336eea2d2ee84132e66552f84724e9b377d687681Daniel Veillard    xmlNodePtr node;
284436eea2d2ee84132e66552f84724e9b377d687681Daniel Veillard    PyObject *pyobj_node;
284536eea2d2ee84132e66552f84724e9b377d687681Daniel Veillard
2846d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard    if (!PyArg_ParseTuple
2847d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        (args, (char *) "O:xmlNodeGetNsDefs", &pyobj_node))
2848d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        return (NULL);
284936eea2d2ee84132e66552f84724e9b377d687681Daniel Veillard    node = (xmlNodePtr) PyxmlNode_Get(pyobj_node);
285036eea2d2ee84132e66552f84724e9b377d687681Daniel Veillard
285136eea2d2ee84132e66552f84724e9b377d687681Daniel Veillard    if ((node == NULL) || (node->type != XML_ELEMENT_NODE)) {
2852d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        Py_INCREF(Py_None);
2853d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        return (Py_None);
285436eea2d2ee84132e66552f84724e9b377d687681Daniel Veillard    }
285536eea2d2ee84132e66552f84724e9b377d687681Daniel Veillard    c_retval = node->nsDef;
285636eea2d2ee84132e66552f84724e9b377d687681Daniel Veillard    py_retval = libxml_xmlNsPtrWrap((xmlNsPtr) c_retval);
2857d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard    return (py_retval);
285836eea2d2ee84132e66552f84724e9b377d687681Daniel Veillard}
285936eea2d2ee84132e66552f84724e9b377d687681Daniel Veillard
286036eea2d2ee84132e66552f84724e9b377d687681Daniel VeillardPyObject *
2861f9cf6f5a01527406ed0bcbcf5a180d85b5e771deDaniel Veillardlibxml_xmlNodeRemoveNsDef(ATTRIBUTE_UNUSED PyObject * self, PyObject * args)
2862f9cf6f5a01527406ed0bcbcf5a180d85b5e771deDaniel Veillard{
2863f9cf6f5a01527406ed0bcbcf5a180d85b5e771deDaniel Veillard    PyObject *py_retval;
2864f9cf6f5a01527406ed0bcbcf5a180d85b5e771deDaniel Veillard    xmlNsPtr ns, prev;
2865f9cf6f5a01527406ed0bcbcf5a180d85b5e771deDaniel Veillard    xmlNodePtr node;
2866f9cf6f5a01527406ed0bcbcf5a180d85b5e771deDaniel Veillard    PyObject *pyobj_node;
2867f9cf6f5a01527406ed0bcbcf5a180d85b5e771deDaniel Veillard    xmlChar *href;
2868f9cf6f5a01527406ed0bcbcf5a180d85b5e771deDaniel Veillard    xmlNsPtr c_retval;
28693798c4adbb91f80bef1e9f1b4b61dae72577a244Daniel Veillard
2870f9cf6f5a01527406ed0bcbcf5a180d85b5e771deDaniel Veillard    if (!PyArg_ParseTuple
2871f9cf6f5a01527406ed0bcbcf5a180d85b5e771deDaniel Veillard        (args, (char *) "Oz:xmlNodeRemoveNsDef", &pyobj_node, &href))
2872f9cf6f5a01527406ed0bcbcf5a180d85b5e771deDaniel Veillard        return (NULL);
2873f9cf6f5a01527406ed0bcbcf5a180d85b5e771deDaniel Veillard    node = (xmlNodePtr) PyxmlNode_Get(pyobj_node);
2874f9cf6f5a01527406ed0bcbcf5a180d85b5e771deDaniel Veillard    ns = NULL;
2875f9cf6f5a01527406ed0bcbcf5a180d85b5e771deDaniel Veillard
2876f9cf6f5a01527406ed0bcbcf5a180d85b5e771deDaniel Veillard    if ((node == NULL) || (node->type != XML_ELEMENT_NODE)) {
2877f9cf6f5a01527406ed0bcbcf5a180d85b5e771deDaniel Veillard        Py_INCREF(Py_None);
2878f9cf6f5a01527406ed0bcbcf5a180d85b5e771deDaniel Veillard        return (Py_None);
2879f9cf6f5a01527406ed0bcbcf5a180d85b5e771deDaniel Veillard    }
2880f9cf6f5a01527406ed0bcbcf5a180d85b5e771deDaniel Veillard
2881f9cf6f5a01527406ed0bcbcf5a180d85b5e771deDaniel Veillard    if (href == NULL) {
2882f9cf6f5a01527406ed0bcbcf5a180d85b5e771deDaniel Veillard	ns = node->nsDef;
2883f9cf6f5a01527406ed0bcbcf5a180d85b5e771deDaniel Veillard	node->nsDef = NULL;
2884f9cf6f5a01527406ed0bcbcf5a180d85b5e771deDaniel Veillard	c_retval = 0;
2885f9cf6f5a01527406ed0bcbcf5a180d85b5e771deDaniel Veillard    }
2886f9cf6f5a01527406ed0bcbcf5a180d85b5e771deDaniel Veillard    else {
2887f9cf6f5a01527406ed0bcbcf5a180d85b5e771deDaniel Veillard	prev = NULL;
2888f9cf6f5a01527406ed0bcbcf5a180d85b5e771deDaniel Veillard	ns = node->nsDef;
2889f9cf6f5a01527406ed0bcbcf5a180d85b5e771deDaniel Veillard	while (ns != NULL) {
2890f9cf6f5a01527406ed0bcbcf5a180d85b5e771deDaniel Veillard	    if (xmlStrEqual(ns->href, href)) {
2891f9cf6f5a01527406ed0bcbcf5a180d85b5e771deDaniel Veillard		if (prev != NULL)
2892f9cf6f5a01527406ed0bcbcf5a180d85b5e771deDaniel Veillard		    prev->next = ns->next;
2893f9cf6f5a01527406ed0bcbcf5a180d85b5e771deDaniel Veillard		else
2894f9cf6f5a01527406ed0bcbcf5a180d85b5e771deDaniel Veillard		    node->nsDef = ns->next;
2895f9cf6f5a01527406ed0bcbcf5a180d85b5e771deDaniel Veillard		ns->next = NULL;
2896f9cf6f5a01527406ed0bcbcf5a180d85b5e771deDaniel Veillard		c_retval = 0;
2897f9cf6f5a01527406ed0bcbcf5a180d85b5e771deDaniel Veillard		break;
2898f9cf6f5a01527406ed0bcbcf5a180d85b5e771deDaniel Veillard	    }
2899f9cf6f5a01527406ed0bcbcf5a180d85b5e771deDaniel Veillard	    prev = ns;
2900f9cf6f5a01527406ed0bcbcf5a180d85b5e771deDaniel Veillard	    ns = ns->next;
2901f9cf6f5a01527406ed0bcbcf5a180d85b5e771deDaniel Veillard	}
2902f9cf6f5a01527406ed0bcbcf5a180d85b5e771deDaniel Veillard    }
2903f9cf6f5a01527406ed0bcbcf5a180d85b5e771deDaniel Veillard
2904f9cf6f5a01527406ed0bcbcf5a180d85b5e771deDaniel Veillard    c_retval = ns;
2905f9cf6f5a01527406ed0bcbcf5a180d85b5e771deDaniel Veillard    py_retval = libxml_xmlNsPtrWrap((xmlNsPtr) c_retval);
2906f9cf6f5a01527406ed0bcbcf5a180d85b5e771deDaniel Veillard    return (py_retval);
2907f9cf6f5a01527406ed0bcbcf5a180d85b5e771deDaniel Veillard}
2908f9cf6f5a01527406ed0bcbcf5a180d85b5e771deDaniel Veillard
2909f9cf6f5a01527406ed0bcbcf5a180d85b5e771deDaniel VeillardPyObject *
2910d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillardlibxml_xmlNodeGetNs(ATTRIBUTE_UNUSED PyObject * self, PyObject * args)
2911d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard{
291236eea2d2ee84132e66552f84724e9b377d687681Daniel Veillard    PyObject *py_retval;
291336eea2d2ee84132e66552f84724e9b377d687681Daniel Veillard    xmlNsPtr c_retval;
291436eea2d2ee84132e66552f84724e9b377d687681Daniel Veillard    xmlNodePtr node;
291536eea2d2ee84132e66552f84724e9b377d687681Daniel Veillard    PyObject *pyobj_node;
291636eea2d2ee84132e66552f84724e9b377d687681Daniel Veillard
2917d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard    if (!PyArg_ParseTuple(args, (char *) "O:xmlNodeGetNs", &pyobj_node))
2918d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        return (NULL);
291936eea2d2ee84132e66552f84724e9b377d687681Daniel Veillard    node = (xmlNodePtr) PyxmlNode_Get(pyobj_node);
292036eea2d2ee84132e66552f84724e9b377d687681Daniel Veillard
2921e96a2a4bf040ec93f83d9c33f8ae4ac3f1e512e9Daniel Veillard    if ((node == NULL) ||
2922e96a2a4bf040ec93f83d9c33f8ae4ac3f1e512e9Daniel Veillard        ((node->type != XML_ELEMENT_NODE) &&
2923e96a2a4bf040ec93f83d9c33f8ae4ac3f1e512e9Daniel Veillard	 (node->type != XML_ATTRIBUTE_NODE))) {
2924d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        Py_INCREF(Py_None);
2925d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        return (Py_None);
292636eea2d2ee84132e66552f84724e9b377d687681Daniel Veillard    }
292736eea2d2ee84132e66552f84724e9b377d687681Daniel Veillard    c_retval = node->ns;
292836eea2d2ee84132e66552f84724e9b377d687681Daniel Veillard    py_retval = libxml_xmlNsPtrWrap((xmlNsPtr) c_retval);
2929d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard    return (py_retval);
293036eea2d2ee84132e66552f84724e9b377d687681Daniel Veillard}
293136eea2d2ee84132e66552f84724e9b377d687681Daniel Veillard
2932a9cce9cd0d7aff3ec318b5d8d376da131b6aaad4Daniel Veillard#ifdef LIBXML_OUTPUT_ENABLED
293336eea2d2ee84132e66552f84724e9b377d687681Daniel Veillard/************************************************************************
293436eea2d2ee84132e66552f84724e9b377d687681Daniel Veillard *									*
29351e77438da7dd912885effa97b1079867d1e041beDaniel Veillard *			Serialization front-end				*
29361e77438da7dd912885effa97b1079867d1e041beDaniel Veillard *									*
29371e77438da7dd912885effa97b1079867d1e041beDaniel Veillard ************************************************************************/
29381e77438da7dd912885effa97b1079867d1e041beDaniel Veillard
2939d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillardstatic PyObject *
2940d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillardlibxml_serializeNode(ATTRIBUTE_UNUSED PyObject * self, PyObject * args)
2941d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard{
29421e77438da7dd912885effa97b1079867d1e041beDaniel Veillard    PyObject *py_retval = NULL;
29431e77438da7dd912885effa97b1079867d1e041beDaniel Veillard    xmlChar *c_retval;
29441e77438da7dd912885effa97b1079867d1e041beDaniel Veillard    PyObject *pyobj_node;
29451e77438da7dd912885effa97b1079867d1e041beDaniel Veillard    xmlNodePtr node;
29461e77438da7dd912885effa97b1079867d1e041beDaniel Veillard    xmlDocPtr doc;
2947d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard    const char *encoding;
29481e77438da7dd912885effa97b1079867d1e041beDaniel Veillard    int format;
2949da3fee406da96c344d7b5f4e0631faee74f7e11dDaniel Veillard    xmlSaveCtxtPtr ctxt;
2950da3fee406da96c344d7b5f4e0631faee74f7e11dDaniel Veillard    xmlBufferPtr buf;
2951da3fee406da96c344d7b5f4e0631faee74f7e11dDaniel Veillard    int options = 0;
29521e77438da7dd912885effa97b1079867d1e041beDaniel Veillard
2953d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard    if (!PyArg_ParseTuple(args, (char *) "Ozi:serializeNode", &pyobj_node,
2954d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard                          &encoding, &format))
2955d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        return (NULL);
29561e77438da7dd912885effa97b1079867d1e041beDaniel Veillard    node = (xmlNodePtr) PyxmlNode_Get(pyobj_node);
29571e77438da7dd912885effa97b1079867d1e041beDaniel Veillard
29581e77438da7dd912885effa97b1079867d1e041beDaniel Veillard    if (node == NULL) {
2959d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        Py_INCREF(Py_None);
2960d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        return (Py_None);
29611e77438da7dd912885effa97b1079867d1e041beDaniel Veillard    }
29621e77438da7dd912885effa97b1079867d1e041beDaniel Veillard    if (node->type == XML_DOCUMENT_NODE) {
2963d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        doc = (xmlDocPtr) node;
2964da3fee406da96c344d7b5f4e0631faee74f7e11dDaniel Veillard	node = NULL;
2965656ce948ab664ce96298c5f419a03a7ffcc88d9dDaniel Veillard#ifdef LIBXML_HTML_ENABLED
29661e77438da7dd912885effa97b1079867d1e041beDaniel Veillard    } else if (node->type == XML_HTML_DOCUMENT_NODE) {
2967d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        doc = (xmlDocPtr) node;
2968da3fee406da96c344d7b5f4e0631faee74f7e11dDaniel Veillard	node = NULL;
2969da3fee406da96c344d7b5f4e0631faee74f7e11dDaniel Veillard#endif
29701e77438da7dd912885effa97b1079867d1e041beDaniel Veillard    } else {
297195af594b0bd28ad8847de96ec00ff9244bd94da7William M. Brack        if (node->type == XML_NAMESPACE_DECL)
297295af594b0bd28ad8847de96ec00ff9244bd94da7William M. Brack	    doc = NULL;
297395af594b0bd28ad8847de96ec00ff9244bd94da7William M. Brack	else
297495af594b0bd28ad8847de96ec00ff9244bd94da7William M. Brack            doc = node->doc;
2975a8c0adbc395e48f0a65ccbd6c4931525380cf55cDaniel Veillard        if ((doc == NULL) || (doc->type == XML_DOCUMENT_NODE)) {
2976656ce948ab664ce96298c5f419a03a7ffcc88d9dDaniel Veillard#ifdef LIBXML_HTML_ENABLED
2977d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        } else if (doc->type == XML_HTML_DOCUMENT_NODE) {
2978656ce948ab664ce96298c5f419a03a7ffcc88d9dDaniel Veillard#endif /* LIBXML_HTML_ENABLED */
2979d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        } else {
2980d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            Py_INCREF(Py_None);
2981d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            return (Py_None);
2982d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        }
29831e77438da7dd912885effa97b1079867d1e041beDaniel Veillard    }
2984da3fee406da96c344d7b5f4e0631faee74f7e11dDaniel Veillard
2985da3fee406da96c344d7b5f4e0631faee74f7e11dDaniel Veillard
2986da3fee406da96c344d7b5f4e0631faee74f7e11dDaniel Veillard    buf = xmlBufferCreate();
2987da3fee406da96c344d7b5f4e0631faee74f7e11dDaniel Veillard    if (buf == NULL) {
2988da3fee406da96c344d7b5f4e0631faee74f7e11dDaniel Veillard	Py_INCREF(Py_None);
2989da3fee406da96c344d7b5f4e0631faee74f7e11dDaniel Veillard	return (Py_None);
2990da3fee406da96c344d7b5f4e0631faee74f7e11dDaniel Veillard    }
2991da3fee406da96c344d7b5f4e0631faee74f7e11dDaniel Veillard    if (format) options |= XML_SAVE_FORMAT;
2992da3fee406da96c344d7b5f4e0631faee74f7e11dDaniel Veillard    ctxt = xmlSaveToBuffer(buf, encoding, options);
2993da3fee406da96c344d7b5f4e0631faee74f7e11dDaniel Veillard    if (ctxt == NULL) {
2994da3fee406da96c344d7b5f4e0631faee74f7e11dDaniel Veillard	xmlBufferFree(buf);
2995da3fee406da96c344d7b5f4e0631faee74f7e11dDaniel Veillard	Py_INCREF(Py_None);
2996da3fee406da96c344d7b5f4e0631faee74f7e11dDaniel Veillard	return (Py_None);
2997da3fee406da96c344d7b5f4e0631faee74f7e11dDaniel Veillard    }
2998da3fee406da96c344d7b5f4e0631faee74f7e11dDaniel Veillard    if (node == NULL)
2999da3fee406da96c344d7b5f4e0631faee74f7e11dDaniel Veillard	xmlSaveDoc(ctxt, doc);
3000da3fee406da96c344d7b5f4e0631faee74f7e11dDaniel Veillard    else
3001da3fee406da96c344d7b5f4e0631faee74f7e11dDaniel Veillard	xmlSaveTree(ctxt, node);
3002da3fee406da96c344d7b5f4e0631faee74f7e11dDaniel Veillard    xmlSaveClose(ctxt);
3003da3fee406da96c344d7b5f4e0631faee74f7e11dDaniel Veillard
3004da3fee406da96c344d7b5f4e0631faee74f7e11dDaniel Veillard    c_retval = buf->content;
3005da3fee406da96c344d7b5f4e0631faee74f7e11dDaniel Veillard    buf->content = NULL;
3006da3fee406da96c344d7b5f4e0631faee74f7e11dDaniel Veillard
3007da3fee406da96c344d7b5f4e0631faee74f7e11dDaniel Veillard    xmlBufferFree(buf);
3008da3fee406da96c344d7b5f4e0631faee74f7e11dDaniel Veillard    py_retval = libxml_charPtrWrap((char *) c_retval);
3009da3fee406da96c344d7b5f4e0631faee74f7e11dDaniel Veillard
3010d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard    return (py_retval);
30111e77438da7dd912885effa97b1079867d1e041beDaniel Veillard}
30121e77438da7dd912885effa97b1079867d1e041beDaniel Veillard
3013d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillardstatic PyObject *
3014d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillardlibxml_saveNodeTo(ATTRIBUTE_UNUSED PyObject * self, PyObject * args)
3015d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard{
30161e77438da7dd912885effa97b1079867d1e041beDaniel Veillard    PyObject *py_file = NULL;
30171e77438da7dd912885effa97b1079867d1e041beDaniel Veillard    FILE *output;
30181e77438da7dd912885effa97b1079867d1e041beDaniel Veillard    PyObject *pyobj_node;
30191e77438da7dd912885effa97b1079867d1e041beDaniel Veillard    xmlNodePtr node;
30201e77438da7dd912885effa97b1079867d1e041beDaniel Veillard    xmlDocPtr doc;
3021d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard    const char *encoding;
30221e77438da7dd912885effa97b1079867d1e041beDaniel Veillard    int format;
30231e77438da7dd912885effa97b1079867d1e041beDaniel Veillard    int len;
30241e77438da7dd912885effa97b1079867d1e041beDaniel Veillard    xmlOutputBufferPtr buf;
30251e77438da7dd912885effa97b1079867d1e041beDaniel Veillard    xmlCharEncodingHandlerPtr handler = NULL;
30261e77438da7dd912885effa97b1079867d1e041beDaniel Veillard
3027d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard    if (!PyArg_ParseTuple(args, (char *) "OOzi:serializeNode", &pyobj_node,
3028d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard                          &py_file, &encoding, &format))
3029d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        return (NULL);
30301e77438da7dd912885effa97b1079867d1e041beDaniel Veillard    node = (xmlNodePtr) PyxmlNode_Get(pyobj_node);
30311e77438da7dd912885effa97b1079867d1e041beDaniel Veillard    if (node == NULL) {
30323798c4adbb91f80bef1e9f1b4b61dae72577a244Daniel Veillard        return (PyLong_FromLong((long) -1));
30331e77438da7dd912885effa97b1079867d1e041beDaniel Veillard    }
30343798c4adbb91f80bef1e9f1b4b61dae72577a244Daniel Veillard    output = PyFile_Get(py_file);
30351e77438da7dd912885effa97b1079867d1e041beDaniel Veillard    if (output == NULL) {
30363798c4adbb91f80bef1e9f1b4b61dae72577a244Daniel Veillard        return (PyLong_FromLong((long) -1));
30371e77438da7dd912885effa97b1079867d1e041beDaniel Veillard    }
30381e77438da7dd912885effa97b1079867d1e041beDaniel Veillard
30391e77438da7dd912885effa97b1079867d1e041beDaniel Veillard    if (node->type == XML_DOCUMENT_NODE) {
3040d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        doc = (xmlDocPtr) node;
30411e77438da7dd912885effa97b1079867d1e041beDaniel Veillard    } else if (node->type == XML_HTML_DOCUMENT_NODE) {
3042d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        doc = (xmlDocPtr) node;
30431e77438da7dd912885effa97b1079867d1e041beDaniel Veillard    } else {
3044d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        doc = node->doc;
30451e77438da7dd912885effa97b1079867d1e041beDaniel Veillard    }
3046656ce948ab664ce96298c5f419a03a7ffcc88d9dDaniel Veillard#ifdef LIBXML_HTML_ENABLED
30471e77438da7dd912885effa97b1079867d1e041beDaniel Veillard    if (doc->type == XML_HTML_DOCUMENT_NODE) {
3048d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        if (encoding == NULL)
3049d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            encoding = (const char *) htmlGetMetaEncoding(doc);
30501e77438da7dd912885effa97b1079867d1e041beDaniel Veillard    }
3051656ce948ab664ce96298c5f419a03a7ffcc88d9dDaniel Veillard#endif /* LIBXML_HTML_ENABLED */
30521e77438da7dd912885effa97b1079867d1e041beDaniel Veillard    if (encoding != NULL) {
3053d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        handler = xmlFindCharEncodingHandler(encoding);
3054d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        if (handler == NULL) {
30553798c4adbb91f80bef1e9f1b4b61dae72577a244Daniel Veillard            return (PyLong_FromLong((long) -1));
3056d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        }
30571e77438da7dd912885effa97b1079867d1e041beDaniel Veillard    }
30581e77438da7dd912885effa97b1079867d1e041beDaniel Veillard    if (doc->type == XML_HTML_DOCUMENT_NODE) {
3059d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        if (handler == NULL)
3060d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            handler = xmlFindCharEncodingHandler("HTML");
3061d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        if (handler == NULL)
3062d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            handler = xmlFindCharEncodingHandler("ascii");
30631e77438da7dd912885effa97b1079867d1e041beDaniel Veillard    }
30641e77438da7dd912885effa97b1079867d1e041beDaniel Veillard
30651e77438da7dd912885effa97b1079867d1e041beDaniel Veillard    buf = xmlOutputBufferCreateFile(output, handler);
30661e77438da7dd912885effa97b1079867d1e041beDaniel Veillard    if (node->type == XML_DOCUMENT_NODE) {
3067d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        len = xmlSaveFormatFileTo(buf, doc, encoding, format);
3068656ce948ab664ce96298c5f419a03a7ffcc88d9dDaniel Veillard#ifdef LIBXML_HTML_ENABLED
30691e77438da7dd912885effa97b1079867d1e041beDaniel Veillard    } else if (node->type == XML_HTML_DOCUMENT_NODE) {
3070d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        htmlDocContentDumpFormatOutput(buf, doc, encoding, format);
3071d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        len = xmlOutputBufferClose(buf);
30721e77438da7dd912885effa97b1079867d1e041beDaniel Veillard    } else if (doc->type == XML_HTML_DOCUMENT_NODE) {
3073d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        htmlNodeDumpFormatOutput(buf, doc, node, encoding, format);
3074d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        len = xmlOutputBufferClose(buf);
3075656ce948ab664ce96298c5f419a03a7ffcc88d9dDaniel Veillard#endif /* LIBXML_HTML_ENABLED */
30761e77438da7dd912885effa97b1079867d1e041beDaniel Veillard    } else {
3077d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        xmlNodeDumpOutput(buf, doc, node, 0, format, encoding);
3078d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        len = xmlOutputBufferClose(buf);
30791e77438da7dd912885effa97b1079867d1e041beDaniel Veillard    }
30803798c4adbb91f80bef1e9f1b4b61dae72577a244Daniel Veillard    PyFile_Release(output);
30813798c4adbb91f80bef1e9f1b4b61dae72577a244Daniel Veillard    return (PyLong_FromLong((long) len));
30821e77438da7dd912885effa97b1079867d1e041beDaniel Veillard}
3083a9cce9cd0d7aff3ec318b5d8d376da131b6aaad4Daniel Veillard#endif /* LIBXML_OUTPUT_ENABLED */
30841e77438da7dd912885effa97b1079867d1e041beDaniel Veillard
30851e77438da7dd912885effa97b1079867d1e041beDaniel Veillard/************************************************************************
30861e77438da7dd912885effa97b1079867d1e041beDaniel Veillard *									*
3087a94ec6ff13d9617ff22e790cef82208e7d1bd375Daniel Veillard *			Extra stuff					*
3088a94ec6ff13d9617ff22e790cef82208e7d1bd375Daniel Veillard *									*
3089a94ec6ff13d9617ff22e790cef82208e7d1bd375Daniel Veillard ************************************************************************/
3090a94ec6ff13d9617ff22e790cef82208e7d1bd375Daniel VeillardPyObject *
3091d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillardlibxml_xmlNewNode(ATTRIBUTE_UNUSED PyObject * self, PyObject * args)
3092d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard{
3093a94ec6ff13d9617ff22e790cef82208e7d1bd375Daniel Veillard    PyObject *py_retval;
3094d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard    xmlChar *name;
3095a94ec6ff13d9617ff22e790cef82208e7d1bd375Daniel Veillard    xmlNodePtr node;
3096a94ec6ff13d9617ff22e790cef82208e7d1bd375Daniel Veillard
3097d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard    if (!PyArg_ParseTuple(args, (char *) "s:xmlNewNode", &name))
3098d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        return (NULL);
3099a94ec6ff13d9617ff22e790cef82208e7d1bd375Daniel Veillard    node = (xmlNodePtr) xmlNewNode(NULL, name);
31003b2e4e1c1477e9eb0889a8c9d35da4ce36a2e3f1Daniel Veillard#ifdef DEBUG
3101d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard    printf("NewNode: %s : %p\n", name, (void *) node);
31023b2e4e1c1477e9eb0889a8c9d35da4ce36a2e3f1Daniel Veillard#endif
3103a94ec6ff13d9617ff22e790cef82208e7d1bd375Daniel Veillard
3104a94ec6ff13d9617ff22e790cef82208e7d1bd375Daniel Veillard    if (node == NULL) {
3105d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        Py_INCREF(Py_None);
3106d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        return (Py_None);
3107a94ec6ff13d9617ff22e790cef82208e7d1bd375Daniel Veillard    }
3108a94ec6ff13d9617ff22e790cef82208e7d1bd375Daniel Veillard    py_retval = libxml_xmlNodePtrWrap(node);
3109d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard    return (py_retval);
3110a94ec6ff13d9617ff22e790cef82208e7d1bd375Daniel Veillard}
3111a94ec6ff13d9617ff22e790cef82208e7d1bd375Daniel Veillard
31125439624bd9167dbb880ea4a75d91677d20a6ebe3Daniel Veillard
31135439624bd9167dbb880ea4a75d91677d20a6ebe3Daniel Veillard/************************************************************************
31145439624bd9167dbb880ea4a75d91677d20a6ebe3Daniel Veillard *									*
31155439624bd9167dbb880ea4a75d91677d20a6ebe3Daniel Veillard *			Local Catalog stuff				*
31165439624bd9167dbb880ea4a75d91677d20a6ebe3Daniel Veillard *									*
31175439624bd9167dbb880ea4a75d91677d20a6ebe3Daniel Veillard ************************************************************************/
31185439624bd9167dbb880ea4a75d91677d20a6ebe3Daniel Veillardstatic PyObject *
31195439624bd9167dbb880ea4a75d91677d20a6ebe3Daniel Veillardlibxml_addLocalCatalog(ATTRIBUTE_UNUSED PyObject * self, PyObject * args)
31205439624bd9167dbb880ea4a75d91677d20a6ebe3Daniel Veillard{
31215439624bd9167dbb880ea4a75d91677d20a6ebe3Daniel Veillard    xmlChar *URL;
31225439624bd9167dbb880ea4a75d91677d20a6ebe3Daniel Veillard    xmlParserCtxtPtr ctxt;
31235439624bd9167dbb880ea4a75d91677d20a6ebe3Daniel Veillard    PyObject *pyobj_ctxt;
31245439624bd9167dbb880ea4a75d91677d20a6ebe3Daniel Veillard
31255439624bd9167dbb880ea4a75d91677d20a6ebe3Daniel Veillard    if (!PyArg_ParseTuple(args, (char *)"Os:addLocalCatalog", &pyobj_ctxt, &URL))
31265439624bd9167dbb880ea4a75d91677d20a6ebe3Daniel Veillard        return(NULL);
31275439624bd9167dbb880ea4a75d91677d20a6ebe3Daniel Veillard
31285439624bd9167dbb880ea4a75d91677d20a6ebe3Daniel Veillard    ctxt = (xmlParserCtxtPtr) PyparserCtxt_Get(pyobj_ctxt);
31295439624bd9167dbb880ea4a75d91677d20a6ebe3Daniel Veillard
31305439624bd9167dbb880ea4a75d91677d20a6ebe3Daniel Veillard    if (URL != NULL) {
31315439624bd9167dbb880ea4a75d91677d20a6ebe3Daniel Veillard	ctxt->catalogs = xmlCatalogAddLocal(ctxt->catalogs, URL);
31325439624bd9167dbb880ea4a75d91677d20a6ebe3Daniel Veillard    }
31335439624bd9167dbb880ea4a75d91677d20a6ebe3Daniel Veillard
31345439624bd9167dbb880ea4a75d91677d20a6ebe3Daniel Veillard#ifdef DEBUG
31355439624bd9167dbb880ea4a75d91677d20a6ebe3Daniel Veillard    printf("LocalCatalog: %s\n", URL);
31365439624bd9167dbb880ea4a75d91677d20a6ebe3Daniel Veillard#endif
31375439624bd9167dbb880ea4a75d91677d20a6ebe3Daniel Veillard
31385439624bd9167dbb880ea4a75d91677d20a6ebe3Daniel Veillard    Py_INCREF(Py_None);
31395439624bd9167dbb880ea4a75d91677d20a6ebe3Daniel Veillard    return (Py_None);
31405439624bd9167dbb880ea4a75d91677d20a6ebe3Daniel Veillard}
31415439624bd9167dbb880ea4a75d91677d20a6ebe3Daniel Veillard
3142c2664641740126714bb363bd6b5f65f724031c83Daniel Veillard#ifdef LIBXML_SCHEMAS_ENABLED
3143c2664641740126714bb363bd6b5f65f724031c83Daniel Veillard
3144c2664641740126714bb363bd6b5f65f724031c83Daniel Veillard/************************************************************************
3145c2664641740126714bb363bd6b5f65f724031c83Daniel Veillard *                                                                      *
3146c2664641740126714bb363bd6b5f65f724031c83Daniel Veillard * RelaxNG error handler registration                                   *
3147c2664641740126714bb363bd6b5f65f724031c83Daniel Veillard *                                                                      *
3148c2664641740126714bb363bd6b5f65f724031c83Daniel Veillard ************************************************************************/
3149c2664641740126714bb363bd6b5f65f724031c83Daniel Veillard
3150c2664641740126714bb363bd6b5f65f724031c83Daniel Veillardtypedef struct
3151c2664641740126714bb363bd6b5f65f724031c83Daniel Veillard{
3152c2664641740126714bb363bd6b5f65f724031c83Daniel Veillard    PyObject *warn;
3153c2664641740126714bb363bd6b5f65f724031c83Daniel Veillard    PyObject *error;
3154c2664641740126714bb363bd6b5f65f724031c83Daniel Veillard    PyObject *arg;
3155c2664641740126714bb363bd6b5f65f724031c83Daniel Veillard} xmlRelaxNGValidCtxtPyCtxt;
3156c2664641740126714bb363bd6b5f65f724031c83Daniel Veillardtypedef xmlRelaxNGValidCtxtPyCtxt *xmlRelaxNGValidCtxtPyCtxtPtr;
3157c2664641740126714bb363bd6b5f65f724031c83Daniel Veillard
3158c2664641740126714bb363bd6b5f65f724031c83Daniel Veillardstatic void
3159c2664641740126714bb363bd6b5f65f724031c83Daniel Veillardlibxml_xmlRelaxNGValidityGenericErrorFuncHandler(void *ctx, char *str)
3160c2664641740126714bb363bd6b5f65f724031c83Daniel Veillard{
3161c2664641740126714bb363bd6b5f65f724031c83Daniel Veillard    PyObject *list;
3162c2664641740126714bb363bd6b5f65f724031c83Daniel Veillard    PyObject *result;
3163c2664641740126714bb363bd6b5f65f724031c83Daniel Veillard    xmlRelaxNGValidCtxtPyCtxtPtr pyCtxt;
3164c2664641740126714bb363bd6b5f65f724031c83Daniel Veillard
3165c2664641740126714bb363bd6b5f65f724031c83Daniel Veillard#ifdef DEBUG_ERROR
3166c2664641740126714bb363bd6b5f65f724031c83Daniel Veillard    printf("libxml_xmlRelaxNGValidityGenericErrorFuncHandler(%p, %s, ...) called\n", ctx, str);
3167c2664641740126714bb363bd6b5f65f724031c83Daniel Veillard#endif
3168c2664641740126714bb363bd6b5f65f724031c83Daniel Veillard
3169c2664641740126714bb363bd6b5f65f724031c83Daniel Veillard    pyCtxt = (xmlRelaxNGValidCtxtPyCtxtPtr)ctx;
3170c2664641740126714bb363bd6b5f65f724031c83Daniel Veillard
3171c2664641740126714bb363bd6b5f65f724031c83Daniel Veillard    list = PyTuple_New(2);
3172c2664641740126714bb363bd6b5f65f724031c83Daniel Veillard    PyTuple_SetItem(list, 0, libxml_charPtrWrap(str));
3173c2664641740126714bb363bd6b5f65f724031c83Daniel Veillard    PyTuple_SetItem(list, 1, pyCtxt->arg);
3174c2664641740126714bb363bd6b5f65f724031c83Daniel Veillard    Py_XINCREF(pyCtxt->arg);
3175c2664641740126714bb363bd6b5f65f724031c83Daniel Veillard    result = PyEval_CallObject(pyCtxt->error, list);
3176c2664641740126714bb363bd6b5f65f724031c83Daniel Veillard    if (result == NULL)
3177c2664641740126714bb363bd6b5f65f724031c83Daniel Veillard    {
3178c2664641740126714bb363bd6b5f65f724031c83Daniel Veillard        /* TODO: manage for the exception to be propagated... */
3179c2664641740126714bb363bd6b5f65f724031c83Daniel Veillard        PyErr_Print();
3180c2664641740126714bb363bd6b5f65f724031c83Daniel Veillard    }
3181c2664641740126714bb363bd6b5f65f724031c83Daniel Veillard    Py_XDECREF(list);
3182c2664641740126714bb363bd6b5f65f724031c83Daniel Veillard    Py_XDECREF(result);
3183c2664641740126714bb363bd6b5f65f724031c83Daniel Veillard}
3184c2664641740126714bb363bd6b5f65f724031c83Daniel Veillard
3185c2664641740126714bb363bd6b5f65f724031c83Daniel Veillardstatic void
3186c2664641740126714bb363bd6b5f65f724031c83Daniel Veillardlibxml_xmlRelaxNGValidityGenericWarningFuncHandler(void *ctx, char *str)
3187c2664641740126714bb363bd6b5f65f724031c83Daniel Veillard{
3188c2664641740126714bb363bd6b5f65f724031c83Daniel Veillard    PyObject *list;
3189c2664641740126714bb363bd6b5f65f724031c83Daniel Veillard    PyObject *result;
3190c2664641740126714bb363bd6b5f65f724031c83Daniel Veillard    xmlRelaxNGValidCtxtPyCtxtPtr pyCtxt;
3191c2664641740126714bb363bd6b5f65f724031c83Daniel Veillard
3192c2664641740126714bb363bd6b5f65f724031c83Daniel Veillard#ifdef DEBUG_ERROR
3193c2664641740126714bb363bd6b5f65f724031c83Daniel Veillard    printf("libxml_xmlRelaxNGValidityGenericWarningFuncHandler(%p, %s, ...) called\n", ctx, str);
3194c2664641740126714bb363bd6b5f65f724031c83Daniel Veillard#endif
3195c2664641740126714bb363bd6b5f65f724031c83Daniel Veillard
3196c2664641740126714bb363bd6b5f65f724031c83Daniel Veillard    pyCtxt = (xmlRelaxNGValidCtxtPyCtxtPtr)ctx;
3197c2664641740126714bb363bd6b5f65f724031c83Daniel Veillard
3198c2664641740126714bb363bd6b5f65f724031c83Daniel Veillard    list = PyTuple_New(2);
3199c2664641740126714bb363bd6b5f65f724031c83Daniel Veillard    PyTuple_SetItem(list, 0, libxml_charPtrWrap(str));
3200c2664641740126714bb363bd6b5f65f724031c83Daniel Veillard    PyTuple_SetItem(list, 1, pyCtxt->arg);
3201c2664641740126714bb363bd6b5f65f724031c83Daniel Veillard    Py_XINCREF(pyCtxt->arg);
3202c2664641740126714bb363bd6b5f65f724031c83Daniel Veillard    result = PyEval_CallObject(pyCtxt->warn, list);
3203c2664641740126714bb363bd6b5f65f724031c83Daniel Veillard    if (result == NULL)
3204c2664641740126714bb363bd6b5f65f724031c83Daniel Veillard    {
3205c2664641740126714bb363bd6b5f65f724031c83Daniel Veillard        /* TODO: manage for the exception to be propagated... */
3206c2664641740126714bb363bd6b5f65f724031c83Daniel Veillard        PyErr_Print();
3207c2664641740126714bb363bd6b5f65f724031c83Daniel Veillard    }
3208c2664641740126714bb363bd6b5f65f724031c83Daniel Veillard    Py_XDECREF(list);
3209c2664641740126714bb363bd6b5f65f724031c83Daniel Veillard    Py_XDECREF(result);
3210c2664641740126714bb363bd6b5f65f724031c83Daniel Veillard}
3211c2664641740126714bb363bd6b5f65f724031c83Daniel Veillard
3212c2664641740126714bb363bd6b5f65f724031c83Daniel Veillardstatic void
3213c2664641740126714bb363bd6b5f65f724031c83Daniel Veillardlibxml_xmlRelaxNGValidityErrorFunc(void *ctx, const char *msg, ...)
3214c2664641740126714bb363bd6b5f65f724031c83Daniel Veillard{
3215c2664641740126714bb363bd6b5f65f724031c83Daniel Veillard    va_list ap;
3216c2664641740126714bb363bd6b5f65f724031c83Daniel Veillard
3217c2664641740126714bb363bd6b5f65f724031c83Daniel Veillard    va_start(ap, msg);
3218c2664641740126714bb363bd6b5f65f724031c83Daniel Veillard    libxml_xmlRelaxNGValidityGenericErrorFuncHandler(ctx, libxml_buildMessage(msg, ap));
3219c2664641740126714bb363bd6b5f65f724031c83Daniel Veillard    va_end(ap);
3220c2664641740126714bb363bd6b5f65f724031c83Daniel Veillard}
3221c2664641740126714bb363bd6b5f65f724031c83Daniel Veillard
3222c2664641740126714bb363bd6b5f65f724031c83Daniel Veillardstatic void
3223c2664641740126714bb363bd6b5f65f724031c83Daniel Veillardlibxml_xmlRelaxNGValidityWarningFunc(void *ctx, const char *msg, ...)
3224c2664641740126714bb363bd6b5f65f724031c83Daniel Veillard{
3225c2664641740126714bb363bd6b5f65f724031c83Daniel Veillard    va_list ap;
3226c2664641740126714bb363bd6b5f65f724031c83Daniel Veillard
3227c2664641740126714bb363bd6b5f65f724031c83Daniel Veillard    va_start(ap, msg);
3228c2664641740126714bb363bd6b5f65f724031c83Daniel Veillard    libxml_xmlRelaxNGValidityGenericWarningFuncHandler(ctx, libxml_buildMessage(msg, ap));
3229c2664641740126714bb363bd6b5f65f724031c83Daniel Veillard    va_end(ap);
3230c2664641740126714bb363bd6b5f65f724031c83Daniel Veillard}
3231c2664641740126714bb363bd6b5f65f724031c83Daniel Veillard
3232c2664641740126714bb363bd6b5f65f724031c83Daniel Veillardstatic PyObject *
3233c2664641740126714bb363bd6b5f65f724031c83Daniel Veillardlibxml_xmlRelaxNGSetValidErrors(ATTRIBUTE_UNUSED PyObject * self, PyObject * args)
3234c2664641740126714bb363bd6b5f65f724031c83Daniel Veillard{
3235c2664641740126714bb363bd6b5f65f724031c83Daniel Veillard    PyObject *py_retval;
3236c2664641740126714bb363bd6b5f65f724031c83Daniel Veillard    PyObject *pyobj_error;
3237c2664641740126714bb363bd6b5f65f724031c83Daniel Veillard    PyObject *pyobj_warn;
3238c2664641740126714bb363bd6b5f65f724031c83Daniel Veillard    PyObject *pyobj_ctx;
3239c2664641740126714bb363bd6b5f65f724031c83Daniel Veillard    PyObject *pyobj_arg = Py_None;
3240c2664641740126714bb363bd6b5f65f724031c83Daniel Veillard    xmlRelaxNGValidCtxtPtr ctxt;
3241c2664641740126714bb363bd6b5f65f724031c83Daniel Veillard    xmlRelaxNGValidCtxtPyCtxtPtr pyCtxt;
3242c2664641740126714bb363bd6b5f65f724031c83Daniel Veillard
3243c2664641740126714bb363bd6b5f65f724031c83Daniel Veillard    if (!PyArg_ParseTuple
3244c2664641740126714bb363bd6b5f65f724031c83Daniel Veillard        (args, (char *) "OOO|O:xmlRelaxNGSetValidErrors", &pyobj_ctx, &pyobj_error, &pyobj_warn, &pyobj_arg))
3245c2664641740126714bb363bd6b5f65f724031c83Daniel Veillard        return (NULL);
3246c2664641740126714bb363bd6b5f65f724031c83Daniel Veillard
3247c2664641740126714bb363bd6b5f65f724031c83Daniel Veillard#ifdef DEBUG_ERROR
3248c2664641740126714bb363bd6b5f65f724031c83Daniel Veillard    printf("libxml_xmlRelaxNGSetValidErrors(%p, %p, %p) called\n", pyobj_ctx, pyobj_error, pyobj_warn);
3249c2664641740126714bb363bd6b5f65f724031c83Daniel Veillard#endif
3250c2664641740126714bb363bd6b5f65f724031c83Daniel Veillard
3251c2664641740126714bb363bd6b5f65f724031c83Daniel Veillard    ctxt = PyrelaxNgValidCtxt_Get(pyobj_ctx);
3252c193956ee1c3b229556301cf09f6ff1b6eb9cb70William M. Brack    if (xmlRelaxNGGetValidErrors(ctxt, NULL, NULL, (void **) &pyCtxt) == -1)
3253c2664641740126714bb363bd6b5f65f724031c83Daniel Veillard    {
3254c2664641740126714bb363bd6b5f65f724031c83Daniel Veillard        py_retval = libxml_intWrap(-1);
3255c2664641740126714bb363bd6b5f65f724031c83Daniel Veillard        return(py_retval);
3256c2664641740126714bb363bd6b5f65f724031c83Daniel Veillard    }
3257c2664641740126714bb363bd6b5f65f724031c83Daniel Veillard
3258c2664641740126714bb363bd6b5f65f724031c83Daniel Veillard    if (pyCtxt == NULL)
3259c2664641740126714bb363bd6b5f65f724031c83Daniel Veillard    {
3260c2664641740126714bb363bd6b5f65f724031c83Daniel Veillard        /* first time to set the error handlers */
3261c2664641740126714bb363bd6b5f65f724031c83Daniel Veillard        pyCtxt = xmlMalloc(sizeof(xmlRelaxNGValidCtxtPyCtxt));
3262c2664641740126714bb363bd6b5f65f724031c83Daniel Veillard        if (pyCtxt == NULL) {
3263c2664641740126714bb363bd6b5f65f724031c83Daniel Veillard            py_retval = libxml_intWrap(-1);
3264c2664641740126714bb363bd6b5f65f724031c83Daniel Veillard            return(py_retval);
3265c2664641740126714bb363bd6b5f65f724031c83Daniel Veillard        }
3266c2664641740126714bb363bd6b5f65f724031c83Daniel Veillard        memset(pyCtxt, 0, sizeof(xmlRelaxNGValidCtxtPyCtxt));
3267c2664641740126714bb363bd6b5f65f724031c83Daniel Veillard    }
3268c2664641740126714bb363bd6b5f65f724031c83Daniel Veillard
3269c2664641740126714bb363bd6b5f65f724031c83Daniel Veillard    /* TODO: check warn and error is a function ! */
3270c2664641740126714bb363bd6b5f65f724031c83Daniel Veillard    Py_XDECREF(pyCtxt->error);
3271c2664641740126714bb363bd6b5f65f724031c83Daniel Veillard    Py_XINCREF(pyobj_error);
3272c2664641740126714bb363bd6b5f65f724031c83Daniel Veillard    pyCtxt->error = pyobj_error;
3273c2664641740126714bb363bd6b5f65f724031c83Daniel Veillard
3274c2664641740126714bb363bd6b5f65f724031c83Daniel Veillard    Py_XDECREF(pyCtxt->warn);
3275c2664641740126714bb363bd6b5f65f724031c83Daniel Veillard    Py_XINCREF(pyobj_warn);
3276c2664641740126714bb363bd6b5f65f724031c83Daniel Veillard    pyCtxt->warn = pyobj_warn;
3277c2664641740126714bb363bd6b5f65f724031c83Daniel Veillard
3278c2664641740126714bb363bd6b5f65f724031c83Daniel Veillard    Py_XDECREF(pyCtxt->arg);
3279c2664641740126714bb363bd6b5f65f724031c83Daniel Veillard    Py_XINCREF(pyobj_arg);
3280c2664641740126714bb363bd6b5f65f724031c83Daniel Veillard    pyCtxt->arg = pyobj_arg;
3281c2664641740126714bb363bd6b5f65f724031c83Daniel Veillard
3282c2664641740126714bb363bd6b5f65f724031c83Daniel Veillard    xmlRelaxNGSetValidErrors(ctxt, &libxml_xmlRelaxNGValidityErrorFunc, &libxml_xmlRelaxNGValidityWarningFunc, pyCtxt);
3283c2664641740126714bb363bd6b5f65f724031c83Daniel Veillard
3284c2664641740126714bb363bd6b5f65f724031c83Daniel Veillard    py_retval = libxml_intWrap(1);
3285c2664641740126714bb363bd6b5f65f724031c83Daniel Veillard    return (py_retval);
3286c2664641740126714bb363bd6b5f65f724031c83Daniel Veillard}
3287c2664641740126714bb363bd6b5f65f724031c83Daniel Veillard
3288c2664641740126714bb363bd6b5f65f724031c83Daniel Veillardstatic PyObject *
3289c2664641740126714bb363bd6b5f65f724031c83Daniel Veillardlibxml_xmlRelaxNGFreeValidCtxt(ATTRIBUTE_UNUSED PyObject *self, PyObject *args) {
3290c2664641740126714bb363bd6b5f65f724031c83Daniel Veillard    xmlRelaxNGValidCtxtPtr ctxt;
3291c2664641740126714bb363bd6b5f65f724031c83Daniel Veillard    xmlRelaxNGValidCtxtPyCtxtPtr pyCtxt;
3292c2664641740126714bb363bd6b5f65f724031c83Daniel Veillard    PyObject *pyobj_ctxt;
3293c2664641740126714bb363bd6b5f65f724031c83Daniel Veillard
3294c2664641740126714bb363bd6b5f65f724031c83Daniel Veillard    if (!PyArg_ParseTuple(args, (char *)"O:xmlRelaxNGFreeValidCtxt", &pyobj_ctxt))
3295c2664641740126714bb363bd6b5f65f724031c83Daniel Veillard        return(NULL);
3296c2664641740126714bb363bd6b5f65f724031c83Daniel Veillard    ctxt = (xmlRelaxNGValidCtxtPtr) PyrelaxNgValidCtxt_Get(pyobj_ctxt);
3297c2664641740126714bb363bd6b5f65f724031c83Daniel Veillard
3298c193956ee1c3b229556301cf09f6ff1b6eb9cb70William M. Brack    if (xmlRelaxNGGetValidErrors(ctxt, NULL, NULL, (void **) &pyCtxt) == 0)
3299c2664641740126714bb363bd6b5f65f724031c83Daniel Veillard    {
3300c2664641740126714bb363bd6b5f65f724031c83Daniel Veillard        if (pyCtxt != NULL)
3301c2664641740126714bb363bd6b5f65f724031c83Daniel Veillard        {
3302c2664641740126714bb363bd6b5f65f724031c83Daniel Veillard            Py_XDECREF(pyCtxt->error);
3303c2664641740126714bb363bd6b5f65f724031c83Daniel Veillard            Py_XDECREF(pyCtxt->warn);
3304c2664641740126714bb363bd6b5f65f724031c83Daniel Veillard            Py_XDECREF(pyCtxt->arg);
3305c2664641740126714bb363bd6b5f65f724031c83Daniel Veillard            xmlFree(pyCtxt);
3306c2664641740126714bb363bd6b5f65f724031c83Daniel Veillard        }
3307c2664641740126714bb363bd6b5f65f724031c83Daniel Veillard    }
3308c2664641740126714bb363bd6b5f65f724031c83Daniel Veillard
3309c2664641740126714bb363bd6b5f65f724031c83Daniel Veillard    xmlRelaxNGFreeValidCtxt(ctxt);
3310c2664641740126714bb363bd6b5f65f724031c83Daniel Veillard    Py_INCREF(Py_None);
3311c2664641740126714bb363bd6b5f65f724031c83Daniel Veillard    return(Py_None);
3312c2664641740126714bb363bd6b5f65f724031c83Daniel Veillard}
3313c2664641740126714bb363bd6b5f65f724031c83Daniel Veillard
3314259f0dfa8b4f29158954959b4d0d7c03dd1eab05Daniel Veillardtypedef struct
3315259f0dfa8b4f29158954959b4d0d7c03dd1eab05Daniel Veillard{
3316259f0dfa8b4f29158954959b4d0d7c03dd1eab05Daniel Veillard	PyObject *warn;
3317259f0dfa8b4f29158954959b4d0d7c03dd1eab05Daniel Veillard	PyObject *error;
3318259f0dfa8b4f29158954959b4d0d7c03dd1eab05Daniel Veillard	PyObject *arg;
3319259f0dfa8b4f29158954959b4d0d7c03dd1eab05Daniel Veillard} xmlSchemaValidCtxtPyCtxt;
3320259f0dfa8b4f29158954959b4d0d7c03dd1eab05Daniel Veillardtypedef xmlSchemaValidCtxtPyCtxt *xmlSchemaValidCtxtPyCtxtPtr;
3321259f0dfa8b4f29158954959b4d0d7c03dd1eab05Daniel Veillard
3322259f0dfa8b4f29158954959b4d0d7c03dd1eab05Daniel Veillardstatic void
3323259f0dfa8b4f29158954959b4d0d7c03dd1eab05Daniel Veillardlibxml_xmlSchemaValidityGenericErrorFuncHandler(void *ctx, char *str)
3324259f0dfa8b4f29158954959b4d0d7c03dd1eab05Daniel Veillard{
3325259f0dfa8b4f29158954959b4d0d7c03dd1eab05Daniel Veillard	PyObject *list;
3326259f0dfa8b4f29158954959b4d0d7c03dd1eab05Daniel Veillard	PyObject *result;
3327259f0dfa8b4f29158954959b4d0d7c03dd1eab05Daniel Veillard	xmlSchemaValidCtxtPyCtxtPtr pyCtxt;
3328259f0dfa8b4f29158954959b4d0d7c03dd1eab05Daniel Veillard
3329259f0dfa8b4f29158954959b4d0d7c03dd1eab05Daniel Veillard#ifdef DEBUG_ERROR
3330259f0dfa8b4f29158954959b4d0d7c03dd1eab05Daniel Veillard	printf("libxml_xmlSchemaValiditiyGenericErrorFuncHandler(%p, %s, ...) called\n", ctx, str);
3331259f0dfa8b4f29158954959b4d0d7c03dd1eab05Daniel Veillard#endif
3332259f0dfa8b4f29158954959b4d0d7c03dd1eab05Daniel Veillard
3333259f0dfa8b4f29158954959b4d0d7c03dd1eab05Daniel Veillard	pyCtxt = (xmlSchemaValidCtxtPyCtxtPtr) ctx;
3334259f0dfa8b4f29158954959b4d0d7c03dd1eab05Daniel Veillard
3335259f0dfa8b4f29158954959b4d0d7c03dd1eab05Daniel Veillard	list = PyTuple_New(2);
3336259f0dfa8b4f29158954959b4d0d7c03dd1eab05Daniel Veillard	PyTuple_SetItem(list, 0, libxml_charPtrWrap(str));
3337259f0dfa8b4f29158954959b4d0d7c03dd1eab05Daniel Veillard	PyTuple_SetItem(list, 1, pyCtxt->arg);
3338259f0dfa8b4f29158954959b4d0d7c03dd1eab05Daniel Veillard	Py_XINCREF(pyCtxt->arg);
3339259f0dfa8b4f29158954959b4d0d7c03dd1eab05Daniel Veillard	result = PyEval_CallObject(pyCtxt->error, list);
3340259f0dfa8b4f29158954959b4d0d7c03dd1eab05Daniel Veillard	if (result == NULL)
3341259f0dfa8b4f29158954959b4d0d7c03dd1eab05Daniel Veillard	{
3342259f0dfa8b4f29158954959b4d0d7c03dd1eab05Daniel Veillard		/* TODO: manage for the exception to be propagated... */
3343259f0dfa8b4f29158954959b4d0d7c03dd1eab05Daniel Veillard		PyErr_Print();
3344259f0dfa8b4f29158954959b4d0d7c03dd1eab05Daniel Veillard	}
3345259f0dfa8b4f29158954959b4d0d7c03dd1eab05Daniel Veillard	Py_XDECREF(list);
3346259f0dfa8b4f29158954959b4d0d7c03dd1eab05Daniel Veillard	Py_XDECREF(result);
3347259f0dfa8b4f29158954959b4d0d7c03dd1eab05Daniel Veillard}
3348259f0dfa8b4f29158954959b4d0d7c03dd1eab05Daniel Veillard
3349259f0dfa8b4f29158954959b4d0d7c03dd1eab05Daniel Veillardstatic void
3350259f0dfa8b4f29158954959b4d0d7c03dd1eab05Daniel Veillardlibxml_xmlSchemaValidityGenericWarningFuncHandler(void *ctx, char *str)
3351259f0dfa8b4f29158954959b4d0d7c03dd1eab05Daniel Veillard{
3352259f0dfa8b4f29158954959b4d0d7c03dd1eab05Daniel Veillard	PyObject *list;
3353259f0dfa8b4f29158954959b4d0d7c03dd1eab05Daniel Veillard	PyObject *result;
3354259f0dfa8b4f29158954959b4d0d7c03dd1eab05Daniel Veillard	xmlSchemaValidCtxtPyCtxtPtr pyCtxt;
3355259f0dfa8b4f29158954959b4d0d7c03dd1eab05Daniel Veillard
3356259f0dfa8b4f29158954959b4d0d7c03dd1eab05Daniel Veillard#ifdef DEBUG_ERROR
3357259f0dfa8b4f29158954959b4d0d7c03dd1eab05Daniel Veillard	printf("libxml_xmlSchemaValidityGenericWarningFuncHandler(%p, %s, ...) called\n", ctx, str);
3358259f0dfa8b4f29158954959b4d0d7c03dd1eab05Daniel Veillard#endif
3359259f0dfa8b4f29158954959b4d0d7c03dd1eab05Daniel Veillard
3360259f0dfa8b4f29158954959b4d0d7c03dd1eab05Daniel Veillard	pyCtxt = (xmlSchemaValidCtxtPyCtxtPtr) ctx;
3361259f0dfa8b4f29158954959b4d0d7c03dd1eab05Daniel Veillard
3362259f0dfa8b4f29158954959b4d0d7c03dd1eab05Daniel Veillard	list = PyTuple_New(2);
3363259f0dfa8b4f29158954959b4d0d7c03dd1eab05Daniel Veillard	PyTuple_SetItem(list, 0, libxml_charPtrWrap(str));
3364259f0dfa8b4f29158954959b4d0d7c03dd1eab05Daniel Veillard	PyTuple_SetItem(list, 1, pyCtxt->arg);
3365259f0dfa8b4f29158954959b4d0d7c03dd1eab05Daniel Veillard	Py_XINCREF(pyCtxt->arg);
3366259f0dfa8b4f29158954959b4d0d7c03dd1eab05Daniel Veillard	result = PyEval_CallObject(pyCtxt->warn, list);
3367259f0dfa8b4f29158954959b4d0d7c03dd1eab05Daniel Veillard	if (result == NULL)
3368259f0dfa8b4f29158954959b4d0d7c03dd1eab05Daniel Veillard	{
3369259f0dfa8b4f29158954959b4d0d7c03dd1eab05Daniel Veillard		/* TODO: manage for the exception to be propagated... */
3370259f0dfa8b4f29158954959b4d0d7c03dd1eab05Daniel Veillard		PyErr_Print();
3371259f0dfa8b4f29158954959b4d0d7c03dd1eab05Daniel Veillard	}
3372259f0dfa8b4f29158954959b4d0d7c03dd1eab05Daniel Veillard	Py_XDECREF(list);
3373259f0dfa8b4f29158954959b4d0d7c03dd1eab05Daniel Veillard	Py_XDECREF(result);
3374259f0dfa8b4f29158954959b4d0d7c03dd1eab05Daniel Veillard}
3375259f0dfa8b4f29158954959b4d0d7c03dd1eab05Daniel Veillard
3376259f0dfa8b4f29158954959b4d0d7c03dd1eab05Daniel Veillardstatic void
3377259f0dfa8b4f29158954959b4d0d7c03dd1eab05Daniel Veillardlibxml_xmlSchemaValidityErrorFunc(void *ctx, const char *msg, ...)
3378259f0dfa8b4f29158954959b4d0d7c03dd1eab05Daniel Veillard{
3379259f0dfa8b4f29158954959b4d0d7c03dd1eab05Daniel Veillard	va_list ap;
3380259f0dfa8b4f29158954959b4d0d7c03dd1eab05Daniel Veillard
3381259f0dfa8b4f29158954959b4d0d7c03dd1eab05Daniel Veillard	va_start(ap, msg);
3382259f0dfa8b4f29158954959b4d0d7c03dd1eab05Daniel Veillard	libxml_xmlSchemaValidityGenericErrorFuncHandler(ctx, libxml_buildMessage(msg, ap));
3383259f0dfa8b4f29158954959b4d0d7c03dd1eab05Daniel Veillard	va_end(ap);
3384259f0dfa8b4f29158954959b4d0d7c03dd1eab05Daniel Veillard}
3385259f0dfa8b4f29158954959b4d0d7c03dd1eab05Daniel Veillard
3386259f0dfa8b4f29158954959b4d0d7c03dd1eab05Daniel Veillardstatic void
3387259f0dfa8b4f29158954959b4d0d7c03dd1eab05Daniel Veillardlibxml_xmlSchemaValidityWarningFunc(void *ctx, const char *msg, ...)
3388259f0dfa8b4f29158954959b4d0d7c03dd1eab05Daniel Veillard{
3389259f0dfa8b4f29158954959b4d0d7c03dd1eab05Daniel Veillard	va_list ap;
3390259f0dfa8b4f29158954959b4d0d7c03dd1eab05Daniel Veillard
3391259f0dfa8b4f29158954959b4d0d7c03dd1eab05Daniel Veillard	va_start(ap, msg);
3392259f0dfa8b4f29158954959b4d0d7c03dd1eab05Daniel Veillard	libxml_xmlSchemaValidityGenericWarningFuncHandler(ctx, libxml_buildMessage(msg, ap));
3393259f0dfa8b4f29158954959b4d0d7c03dd1eab05Daniel Veillard	va_end(ap);
3394259f0dfa8b4f29158954959b4d0d7c03dd1eab05Daniel Veillard}
3395259f0dfa8b4f29158954959b4d0d7c03dd1eab05Daniel Veillard
33966ebf3c4c1a78406d15e8629b4a7b3d52549f0c8bDaniel VeillardPyObject *
3397259f0dfa8b4f29158954959b4d0d7c03dd1eab05Daniel Veillardlibxml_xmlSchemaSetValidErrors(ATTRIBUTE_UNUSED PyObject * self, PyObject * args)
3398259f0dfa8b4f29158954959b4d0d7c03dd1eab05Daniel Veillard{
3399259f0dfa8b4f29158954959b4d0d7c03dd1eab05Daniel Veillard	PyObject *py_retval;
3400259f0dfa8b4f29158954959b4d0d7c03dd1eab05Daniel Veillard	PyObject *pyobj_error;
3401259f0dfa8b4f29158954959b4d0d7c03dd1eab05Daniel Veillard	PyObject *pyobj_warn;
3402259f0dfa8b4f29158954959b4d0d7c03dd1eab05Daniel Veillard	PyObject *pyobj_ctx;
3403259f0dfa8b4f29158954959b4d0d7c03dd1eab05Daniel Veillard	PyObject *pyobj_arg = Py_None;
3404259f0dfa8b4f29158954959b4d0d7c03dd1eab05Daniel Veillard	xmlSchemaValidCtxtPtr ctxt;
3405259f0dfa8b4f29158954959b4d0d7c03dd1eab05Daniel Veillard	xmlSchemaValidCtxtPyCtxtPtr pyCtxt;
3406259f0dfa8b4f29158954959b4d0d7c03dd1eab05Daniel Veillard
3407259f0dfa8b4f29158954959b4d0d7c03dd1eab05Daniel Veillard	if (!PyArg_ParseTuple
3408259f0dfa8b4f29158954959b4d0d7c03dd1eab05Daniel Veillard		(args, (char *) "OOO|O:xmlSchemaSetValidErrors", &pyobj_ctx, &pyobj_error, &pyobj_warn, &pyobj_arg))
3409259f0dfa8b4f29158954959b4d0d7c03dd1eab05Daniel Veillard		return (NULL);
3410259f0dfa8b4f29158954959b4d0d7c03dd1eab05Daniel Veillard
3411259f0dfa8b4f29158954959b4d0d7c03dd1eab05Daniel Veillard#ifdef DEBUG_ERROR
3412259f0dfa8b4f29158954959b4d0d7c03dd1eab05Daniel Veillard	printf("libxml_xmlSchemaSetValidErrors(%p, %p, %p) called\n", pyobj_ctx, pyobj_error, pyobj_warn);
3413259f0dfa8b4f29158954959b4d0d7c03dd1eab05Daniel Veillard#endif
3414259f0dfa8b4f29158954959b4d0d7c03dd1eab05Daniel Veillard
3415259f0dfa8b4f29158954959b4d0d7c03dd1eab05Daniel Veillard	ctxt = PySchemaValidCtxt_Get(pyobj_ctx);
3416259f0dfa8b4f29158954959b4d0d7c03dd1eab05Daniel Veillard	if (xmlSchemaGetValidErrors(ctxt, NULL, NULL, (void **) &pyCtxt) == -1)
3417259f0dfa8b4f29158954959b4d0d7c03dd1eab05Daniel Veillard	{
3418259f0dfa8b4f29158954959b4d0d7c03dd1eab05Daniel Veillard		py_retval = libxml_intWrap(-1);
3419259f0dfa8b4f29158954959b4d0d7c03dd1eab05Daniel Veillard		return(py_retval);
3420259f0dfa8b4f29158954959b4d0d7c03dd1eab05Daniel Veillard	}
3421259f0dfa8b4f29158954959b4d0d7c03dd1eab05Daniel Veillard
3422259f0dfa8b4f29158954959b4d0d7c03dd1eab05Daniel Veillard	if (pyCtxt == NULL)
3423259f0dfa8b4f29158954959b4d0d7c03dd1eab05Daniel Veillard	{
3424259f0dfa8b4f29158954959b4d0d7c03dd1eab05Daniel Veillard		/* first time to set the error handlers */
3425259f0dfa8b4f29158954959b4d0d7c03dd1eab05Daniel Veillard		pyCtxt = xmlMalloc(sizeof(xmlSchemaValidCtxtPyCtxt));
3426259f0dfa8b4f29158954959b4d0d7c03dd1eab05Daniel Veillard		if (pyCtxt == NULL) {
3427259f0dfa8b4f29158954959b4d0d7c03dd1eab05Daniel Veillard			py_retval = libxml_intWrap(-1);
3428259f0dfa8b4f29158954959b4d0d7c03dd1eab05Daniel Veillard			return(py_retval);
3429259f0dfa8b4f29158954959b4d0d7c03dd1eab05Daniel Veillard		}
3430259f0dfa8b4f29158954959b4d0d7c03dd1eab05Daniel Veillard		memset(pyCtxt, 0, sizeof(xmlSchemaValidCtxtPyCtxt));
3431259f0dfa8b4f29158954959b4d0d7c03dd1eab05Daniel Veillard	}
3432259f0dfa8b4f29158954959b4d0d7c03dd1eab05Daniel Veillard
3433259f0dfa8b4f29158954959b4d0d7c03dd1eab05Daniel Veillard	/* TODO: check warn and error is a function ! */
3434259f0dfa8b4f29158954959b4d0d7c03dd1eab05Daniel Veillard	Py_XDECREF(pyCtxt->error);
3435259f0dfa8b4f29158954959b4d0d7c03dd1eab05Daniel Veillard	Py_XINCREF(pyobj_error);
3436259f0dfa8b4f29158954959b4d0d7c03dd1eab05Daniel Veillard	pyCtxt->error = pyobj_error;
3437259f0dfa8b4f29158954959b4d0d7c03dd1eab05Daniel Veillard
3438259f0dfa8b4f29158954959b4d0d7c03dd1eab05Daniel Veillard	Py_XDECREF(pyCtxt->warn);
3439259f0dfa8b4f29158954959b4d0d7c03dd1eab05Daniel Veillard	Py_XINCREF(pyobj_warn);
3440259f0dfa8b4f29158954959b4d0d7c03dd1eab05Daniel Veillard	pyCtxt->warn = pyobj_warn;
3441259f0dfa8b4f29158954959b4d0d7c03dd1eab05Daniel Veillard
3442259f0dfa8b4f29158954959b4d0d7c03dd1eab05Daniel Veillard	Py_XDECREF(pyCtxt->arg);
3443259f0dfa8b4f29158954959b4d0d7c03dd1eab05Daniel Veillard	Py_XINCREF(pyobj_arg);
3444259f0dfa8b4f29158954959b4d0d7c03dd1eab05Daniel Veillard	pyCtxt->arg = pyobj_arg;
3445259f0dfa8b4f29158954959b4d0d7c03dd1eab05Daniel Veillard
3446259f0dfa8b4f29158954959b4d0d7c03dd1eab05Daniel Veillard	xmlSchemaSetValidErrors(ctxt, &libxml_xmlSchemaValidityErrorFunc, &libxml_xmlSchemaValidityWarningFunc, pyCtxt);
3447259f0dfa8b4f29158954959b4d0d7c03dd1eab05Daniel Veillard
3448259f0dfa8b4f29158954959b4d0d7c03dd1eab05Daniel Veillard	py_retval = libxml_intWrap(1);
3449259f0dfa8b4f29158954959b4d0d7c03dd1eab05Daniel Veillard	return(py_retval);
3450259f0dfa8b4f29158954959b4d0d7c03dd1eab05Daniel Veillard}
3451259f0dfa8b4f29158954959b4d0d7c03dd1eab05Daniel Veillard
3452bb8502c0ef2af706fbdff69119e994e40da64a88Daniel Veillardstatic PyObject *
3453259f0dfa8b4f29158954959b4d0d7c03dd1eab05Daniel Veillardlibxml_xmlSchemaFreeValidCtxt(ATTRIBUTE_UNUSED PyObject * self, PyObject * args)
3454259f0dfa8b4f29158954959b4d0d7c03dd1eab05Daniel Veillard{
3455259f0dfa8b4f29158954959b4d0d7c03dd1eab05Daniel Veillard	xmlSchemaValidCtxtPtr ctxt;
3456259f0dfa8b4f29158954959b4d0d7c03dd1eab05Daniel Veillard	xmlSchemaValidCtxtPyCtxtPtr pyCtxt;
3457259f0dfa8b4f29158954959b4d0d7c03dd1eab05Daniel Veillard	PyObject *pyobj_ctxt;
3458259f0dfa8b4f29158954959b4d0d7c03dd1eab05Daniel Veillard
3459259f0dfa8b4f29158954959b4d0d7c03dd1eab05Daniel Veillard	if (!PyArg_ParseTuple(args, (char *)"O:xmlSchemaFreeValidCtxt", &pyobj_ctxt))
3460259f0dfa8b4f29158954959b4d0d7c03dd1eab05Daniel Veillard		return(NULL);
3461259f0dfa8b4f29158954959b4d0d7c03dd1eab05Daniel Veillard	ctxt = (xmlSchemaValidCtxtPtr) PySchemaValidCtxt_Get(pyobj_ctxt);
3462259f0dfa8b4f29158954959b4d0d7c03dd1eab05Daniel Veillard
3463259f0dfa8b4f29158954959b4d0d7c03dd1eab05Daniel Veillard	if (xmlSchemaGetValidErrors(ctxt, NULL, NULL, (void **) &pyCtxt) == 0)
3464259f0dfa8b4f29158954959b4d0d7c03dd1eab05Daniel Veillard	{
3465259f0dfa8b4f29158954959b4d0d7c03dd1eab05Daniel Veillard		if (pyCtxt != NULL)
3466259f0dfa8b4f29158954959b4d0d7c03dd1eab05Daniel Veillard		{
3467259f0dfa8b4f29158954959b4d0d7c03dd1eab05Daniel Veillard			Py_XDECREF(pyCtxt->error);
3468259f0dfa8b4f29158954959b4d0d7c03dd1eab05Daniel Veillard			Py_XDECREF(pyCtxt->warn);
3469259f0dfa8b4f29158954959b4d0d7c03dd1eab05Daniel Veillard			Py_XDECREF(pyCtxt->arg);
3470259f0dfa8b4f29158954959b4d0d7c03dd1eab05Daniel Veillard			xmlFree(pyCtxt);
3471259f0dfa8b4f29158954959b4d0d7c03dd1eab05Daniel Veillard		}
3472259f0dfa8b4f29158954959b4d0d7c03dd1eab05Daniel Veillard	}
3473259f0dfa8b4f29158954959b4d0d7c03dd1eab05Daniel Veillard
3474259f0dfa8b4f29158954959b4d0d7c03dd1eab05Daniel Veillard	xmlSchemaFreeValidCtxt(ctxt);
3475259f0dfa8b4f29158954959b4d0d7c03dd1eab05Daniel Veillard	Py_INCREF(Py_None);
3476259f0dfa8b4f29158954959b4d0d7c03dd1eab05Daniel Veillard	return(Py_None);
3477259f0dfa8b4f29158954959b4d0d7c03dd1eab05Daniel Veillard}
3478259f0dfa8b4f29158954959b4d0d7c03dd1eab05Daniel Veillard
3479c2664641740126714bb363bd6b5f65f724031c83Daniel Veillard#endif
3480c2664641740126714bb363bd6b5f65f724031c83Daniel Veillard
3481d5e198ad454803c60b898451ff432f2fcf0e95ceDaniel Veillard#ifdef LIBXML_C14N_ENABLED
3482d5e198ad454803c60b898451ff432f2fcf0e95ceDaniel Veillard#ifdef LIBXML_OUTPUT_ENABLED
3483d5e198ad454803c60b898451ff432f2fcf0e95ceDaniel Veillard
3484d5e198ad454803c60b898451ff432f2fcf0e95ceDaniel Veillard/************************************************************************
3485d5e198ad454803c60b898451ff432f2fcf0e95ceDaniel Veillard *                                                                      *
3486d5e198ad454803c60b898451ff432f2fcf0e95ceDaniel Veillard * XML Canonicalization c14n                                            *
3487d5e198ad454803c60b898451ff432f2fcf0e95ceDaniel Veillard *                                                                      *
3488d5e198ad454803c60b898451ff432f2fcf0e95ceDaniel Veillard ************************************************************************/
3489d5e198ad454803c60b898451ff432f2fcf0e95ceDaniel Veillard
3490d5e198ad454803c60b898451ff432f2fcf0e95ceDaniel Veillardstatic int
3491d5e198ad454803c60b898451ff432f2fcf0e95ceDaniel VeillardPyxmlNodeSet_Convert(PyObject *py_nodeset, xmlNodeSetPtr *result)
3492d5e198ad454803c60b898451ff432f2fcf0e95ceDaniel Veillard{
3493d5e198ad454803c60b898451ff432f2fcf0e95ceDaniel Veillard    xmlNodeSetPtr nodeSet;
3494d5e198ad454803c60b898451ff432f2fcf0e95ceDaniel Veillard    int is_tuple = 0;
3495d5e198ad454803c60b898451ff432f2fcf0e95ceDaniel Veillard
3496d5e198ad454803c60b898451ff432f2fcf0e95ceDaniel Veillard    if (PyTuple_Check(py_nodeset))
3497d5e198ad454803c60b898451ff432f2fcf0e95ceDaniel Veillard        is_tuple = 1;
3498d5e198ad454803c60b898451ff432f2fcf0e95ceDaniel Veillard    else if (PyList_Check(py_nodeset))
3499d5e198ad454803c60b898451ff432f2fcf0e95ceDaniel Veillard        is_tuple = 0;
3500d5e198ad454803c60b898451ff432f2fcf0e95ceDaniel Veillard    else if (py_nodeset == Py_None) {
3501d5e198ad454803c60b898451ff432f2fcf0e95ceDaniel Veillard        *result = NULL;
3502d5e198ad454803c60b898451ff432f2fcf0e95ceDaniel Veillard        return 0;
3503d5e198ad454803c60b898451ff432f2fcf0e95ceDaniel Veillard    }
3504d5e198ad454803c60b898451ff432f2fcf0e95ceDaniel Veillard    else {
3505d5e198ad454803c60b898451ff432f2fcf0e95ceDaniel Veillard        PyErr_SetString(PyExc_TypeError,
3506d5e198ad454803c60b898451ff432f2fcf0e95ceDaniel Veillard                        "must be a tuple or list of nodes.");
3507d5e198ad454803c60b898451ff432f2fcf0e95ceDaniel Veillard        return -1;
3508d5e198ad454803c60b898451ff432f2fcf0e95ceDaniel Veillard    }
3509d5e198ad454803c60b898451ff432f2fcf0e95ceDaniel Veillard
3510d5e198ad454803c60b898451ff432f2fcf0e95ceDaniel Veillard    nodeSet = (xmlNodeSetPtr) xmlMalloc(sizeof(xmlNodeSet));
3511d5e198ad454803c60b898451ff432f2fcf0e95ceDaniel Veillard    if (nodeSet == NULL) {
3512d5e198ad454803c60b898451ff432f2fcf0e95ceDaniel Veillard        PyErr_SetString(PyExc_MemoryError, "");
3513d5e198ad454803c60b898451ff432f2fcf0e95ceDaniel Veillard        return -1;
3514d5e198ad454803c60b898451ff432f2fcf0e95ceDaniel Veillard    }
3515d5e198ad454803c60b898451ff432f2fcf0e95ceDaniel Veillard
3516d5e198ad454803c60b898451ff432f2fcf0e95ceDaniel Veillard    nodeSet->nodeNr = 0;
3517d5e198ad454803c60b898451ff432f2fcf0e95ceDaniel Veillard    nodeSet->nodeMax = (is_tuple
3518d5e198ad454803c60b898451ff432f2fcf0e95ceDaniel Veillard                        ? PyTuple_GET_SIZE(py_nodeset)
3519d5e198ad454803c60b898451ff432f2fcf0e95ceDaniel Veillard                        : PyList_GET_SIZE(py_nodeset));
3520d5e198ad454803c60b898451ff432f2fcf0e95ceDaniel Veillard    nodeSet->nodeTab
3521d5e198ad454803c60b898451ff432f2fcf0e95ceDaniel Veillard        = (xmlNodePtr *) xmlMalloc (nodeSet->nodeMax
3522d5e198ad454803c60b898451ff432f2fcf0e95ceDaniel Veillard                                    * sizeof(xmlNodePtr));
3523d5e198ad454803c60b898451ff432f2fcf0e95ceDaniel Veillard    if (nodeSet->nodeTab == NULL) {
3524d5e198ad454803c60b898451ff432f2fcf0e95ceDaniel Veillard        xmlFree(nodeSet);
3525d5e198ad454803c60b898451ff432f2fcf0e95ceDaniel Veillard        PyErr_SetString(PyExc_MemoryError, "");
3526d5e198ad454803c60b898451ff432f2fcf0e95ceDaniel Veillard        return -1;
3527d5e198ad454803c60b898451ff432f2fcf0e95ceDaniel Veillard    }
3528d5e198ad454803c60b898451ff432f2fcf0e95ceDaniel Veillard    memset(nodeSet->nodeTab, 0 ,
3529d5e198ad454803c60b898451ff432f2fcf0e95ceDaniel Veillard           nodeSet->nodeMax * sizeof(xmlNodePtr));
3530d5e198ad454803c60b898451ff432f2fcf0e95ceDaniel Veillard
3531d5e198ad454803c60b898451ff432f2fcf0e95ceDaniel Veillard    {
3532d5e198ad454803c60b898451ff432f2fcf0e95ceDaniel Veillard        int idx;
3533d5e198ad454803c60b898451ff432f2fcf0e95ceDaniel Veillard        for (idx=0; idx < nodeSet->nodeMax; ++idx) {
3534d5e198ad454803c60b898451ff432f2fcf0e95ceDaniel Veillard            xmlNodePtr pynode =
3535d5e198ad454803c60b898451ff432f2fcf0e95ceDaniel Veillard                PyxmlNode_Get (is_tuple
3536d5e198ad454803c60b898451ff432f2fcf0e95ceDaniel Veillard                               ? PyTuple_GET_ITEM(py_nodeset, idx)
3537d5e198ad454803c60b898451ff432f2fcf0e95ceDaniel Veillard                               : PyList_GET_ITEM(py_nodeset, idx));
3538d5e198ad454803c60b898451ff432f2fcf0e95ceDaniel Veillard            if (pynode)
3539d5e198ad454803c60b898451ff432f2fcf0e95ceDaniel Veillard                nodeSet->nodeTab[nodeSet->nodeNr++] = pynode;
3540d5e198ad454803c60b898451ff432f2fcf0e95ceDaniel Veillard        }
3541d5e198ad454803c60b898451ff432f2fcf0e95ceDaniel Veillard    }
3542d5e198ad454803c60b898451ff432f2fcf0e95ceDaniel Veillard    *result = nodeSet;
3543d5e198ad454803c60b898451ff432f2fcf0e95ceDaniel Veillard    return 0;
3544d5e198ad454803c60b898451ff432f2fcf0e95ceDaniel Veillard}
3545d5e198ad454803c60b898451ff432f2fcf0e95ceDaniel Veillard
3546d5e198ad454803c60b898451ff432f2fcf0e95ceDaniel Veillardstatic int
3547d5e198ad454803c60b898451ff432f2fcf0e95ceDaniel VeillardPystringSet_Convert(PyObject *py_strings, xmlChar *** result)
3548d5e198ad454803c60b898451ff432f2fcf0e95ceDaniel Veillard{
3549d5e198ad454803c60b898451ff432f2fcf0e95ceDaniel Veillard    /* NOTE: the array should be freed, but the strings are shared
3550d5e198ad454803c60b898451ff432f2fcf0e95ceDaniel Veillard       with the python strings and so must not be freed. */
3551d5e198ad454803c60b898451ff432f2fcf0e95ceDaniel Veillard
3552d5e198ad454803c60b898451ff432f2fcf0e95ceDaniel Veillard    xmlChar ** strings;
3553d5e198ad454803c60b898451ff432f2fcf0e95ceDaniel Veillard    int is_tuple = 0;
3554d5e198ad454803c60b898451ff432f2fcf0e95ceDaniel Veillard    int count;
3555d5e198ad454803c60b898451ff432f2fcf0e95ceDaniel Veillard    int init_index = 0;
3556d5e198ad454803c60b898451ff432f2fcf0e95ceDaniel Veillard
3557d5e198ad454803c60b898451ff432f2fcf0e95ceDaniel Veillard    if (PyTuple_Check(py_strings))
3558d5e198ad454803c60b898451ff432f2fcf0e95ceDaniel Veillard        is_tuple = 1;
3559d5e198ad454803c60b898451ff432f2fcf0e95ceDaniel Veillard    else if (PyList_Check(py_strings))
3560d5e198ad454803c60b898451ff432f2fcf0e95ceDaniel Veillard        is_tuple = 0;
3561d5e198ad454803c60b898451ff432f2fcf0e95ceDaniel Veillard    else if (py_strings == Py_None) {
3562d5e198ad454803c60b898451ff432f2fcf0e95ceDaniel Veillard        *result = NULL;
3563d5e198ad454803c60b898451ff432f2fcf0e95ceDaniel Veillard        return 0;
3564d5e198ad454803c60b898451ff432f2fcf0e95ceDaniel Veillard    }
3565d5e198ad454803c60b898451ff432f2fcf0e95ceDaniel Veillard    else {
3566d5e198ad454803c60b898451ff432f2fcf0e95ceDaniel Veillard        PyErr_SetString(PyExc_TypeError,
3567d5e198ad454803c60b898451ff432f2fcf0e95ceDaniel Veillard                        "must be a tuple or list of strings.");
3568d5e198ad454803c60b898451ff432f2fcf0e95ceDaniel Veillard        return -1;
3569d5e198ad454803c60b898451ff432f2fcf0e95ceDaniel Veillard    }
3570d5e198ad454803c60b898451ff432f2fcf0e95ceDaniel Veillard
3571d5e198ad454803c60b898451ff432f2fcf0e95ceDaniel Veillard    count = (is_tuple
3572d5e198ad454803c60b898451ff432f2fcf0e95ceDaniel Veillard             ? PyTuple_GET_SIZE(py_strings)
3573d5e198ad454803c60b898451ff432f2fcf0e95ceDaniel Veillard             : PyList_GET_SIZE(py_strings));
3574d5e198ad454803c60b898451ff432f2fcf0e95ceDaniel Veillard
3575d5e198ad454803c60b898451ff432f2fcf0e95ceDaniel Veillard    strings = (xmlChar **) xmlMalloc(sizeof(xmlChar *) * count);
3576d5e198ad454803c60b898451ff432f2fcf0e95ceDaniel Veillard
3577d5e198ad454803c60b898451ff432f2fcf0e95ceDaniel Veillard    if (strings == NULL) {
3578d5e198ad454803c60b898451ff432f2fcf0e95ceDaniel Veillard        PyErr_SetString(PyExc_MemoryError, "");
3579d5e198ad454803c60b898451ff432f2fcf0e95ceDaniel Veillard        return -1;
3580d5e198ad454803c60b898451ff432f2fcf0e95ceDaniel Veillard    }
3581d5e198ad454803c60b898451ff432f2fcf0e95ceDaniel Veillard
3582d5e198ad454803c60b898451ff432f2fcf0e95ceDaniel Veillard    memset(strings, 0 , sizeof(xmlChar *) * count);
3583d5e198ad454803c60b898451ff432f2fcf0e95ceDaniel Veillard
3584d5e198ad454803c60b898451ff432f2fcf0e95ceDaniel Veillard    {
3585d5e198ad454803c60b898451ff432f2fcf0e95ceDaniel Veillard        int idx;
3586d5e198ad454803c60b898451ff432f2fcf0e95ceDaniel Veillard        for (idx=0; idx < count; ++idx) {
35873798c4adbb91f80bef1e9f1b4b61dae72577a244Daniel Veillard            char* s = PyBytes_AsString
3588d5e198ad454803c60b898451ff432f2fcf0e95ceDaniel Veillard                (is_tuple
3589d5e198ad454803c60b898451ff432f2fcf0e95ceDaniel Veillard                 ? PyTuple_GET_ITEM(py_strings, idx)
3590d5e198ad454803c60b898451ff432f2fcf0e95ceDaniel Veillard                 : PyList_GET_ITEM(py_strings, idx));
3591d5e198ad454803c60b898451ff432f2fcf0e95ceDaniel Veillard            if (s)
3592d5e198ad454803c60b898451ff432f2fcf0e95ceDaniel Veillard                strings[init_index++] = (xmlChar *)s;
3593d5e198ad454803c60b898451ff432f2fcf0e95ceDaniel Veillard            else {
3594d5e198ad454803c60b898451ff432f2fcf0e95ceDaniel Veillard                xmlFree(strings);
3595d5e198ad454803c60b898451ff432f2fcf0e95ceDaniel Veillard                PyErr_SetString(PyExc_TypeError,
3596d5e198ad454803c60b898451ff432f2fcf0e95ceDaniel Veillard                                "must be a tuple or list of strings.");
3597d5e198ad454803c60b898451ff432f2fcf0e95ceDaniel Veillard                return -1;
3598d5e198ad454803c60b898451ff432f2fcf0e95ceDaniel Veillard            }
3599d5e198ad454803c60b898451ff432f2fcf0e95ceDaniel Veillard        }
3600d5e198ad454803c60b898451ff432f2fcf0e95ceDaniel Veillard    }
3601d5e198ad454803c60b898451ff432f2fcf0e95ceDaniel Veillard
3602d5e198ad454803c60b898451ff432f2fcf0e95ceDaniel Veillard    *result = strings;
3603d5e198ad454803c60b898451ff432f2fcf0e95ceDaniel Veillard    return 0;
3604d5e198ad454803c60b898451ff432f2fcf0e95ceDaniel Veillard}
3605d5e198ad454803c60b898451ff432f2fcf0e95ceDaniel Veillard
3606d5e198ad454803c60b898451ff432f2fcf0e95ceDaniel Veillardstatic PyObject *
3607d5e198ad454803c60b898451ff432f2fcf0e95ceDaniel Veillardlibxml_C14NDocDumpMemory(ATTRIBUTE_UNUSED PyObject * self,
3608d5e198ad454803c60b898451ff432f2fcf0e95ceDaniel Veillard                         PyObject * args)
3609d5e198ad454803c60b898451ff432f2fcf0e95ceDaniel Veillard{
3610d5e198ad454803c60b898451ff432f2fcf0e95ceDaniel Veillard    PyObject *py_retval = NULL;
3611d5e198ad454803c60b898451ff432f2fcf0e95ceDaniel Veillard
3612d5e198ad454803c60b898451ff432f2fcf0e95ceDaniel Veillard    PyObject *pyobj_doc;
3613d5e198ad454803c60b898451ff432f2fcf0e95ceDaniel Veillard    PyObject *pyobj_nodes;
3614d5e198ad454803c60b898451ff432f2fcf0e95ceDaniel Veillard    int exclusive;
3615d5e198ad454803c60b898451ff432f2fcf0e95ceDaniel Veillard    PyObject *pyobj_prefixes;
3616d5e198ad454803c60b898451ff432f2fcf0e95ceDaniel Veillard    int with_comments;
3617d5e198ad454803c60b898451ff432f2fcf0e95ceDaniel Veillard
3618d5e198ad454803c60b898451ff432f2fcf0e95ceDaniel Veillard    xmlDocPtr doc;
3619d5e198ad454803c60b898451ff432f2fcf0e95ceDaniel Veillard    xmlNodeSetPtr nodes;
3620d5e198ad454803c60b898451ff432f2fcf0e95ceDaniel Veillard    xmlChar **prefixes = NULL;
3621d5e198ad454803c60b898451ff432f2fcf0e95ceDaniel Veillard    xmlChar *doc_txt;
3622d5e198ad454803c60b898451ff432f2fcf0e95ceDaniel Veillard
3623d5e198ad454803c60b898451ff432f2fcf0e95ceDaniel Veillard    int result;
3624d5e198ad454803c60b898451ff432f2fcf0e95ceDaniel Veillard
3625d5e198ad454803c60b898451ff432f2fcf0e95ceDaniel Veillard    if (!PyArg_ParseTuple(args, (char *) "OOiOi:C14NDocDumpMemory",
3626d5e198ad454803c60b898451ff432f2fcf0e95ceDaniel Veillard                          &pyobj_doc,
3627d5e198ad454803c60b898451ff432f2fcf0e95ceDaniel Veillard                          &pyobj_nodes,
3628d5e198ad454803c60b898451ff432f2fcf0e95ceDaniel Veillard                          &exclusive,
3629d5e198ad454803c60b898451ff432f2fcf0e95ceDaniel Veillard                          &pyobj_prefixes,
3630d5e198ad454803c60b898451ff432f2fcf0e95ceDaniel Veillard                          &with_comments))
3631d5e198ad454803c60b898451ff432f2fcf0e95ceDaniel Veillard        return (NULL);
3632d5e198ad454803c60b898451ff432f2fcf0e95ceDaniel Veillard
3633d5e198ad454803c60b898451ff432f2fcf0e95ceDaniel Veillard    doc = (xmlDocPtr) PyxmlNode_Get(pyobj_doc);
3634d5e198ad454803c60b898451ff432f2fcf0e95ceDaniel Veillard    if (!doc) {
3635d5e198ad454803c60b898451ff432f2fcf0e95ceDaniel Veillard        PyErr_SetString(PyExc_TypeError, "bad document.");
3636d5e198ad454803c60b898451ff432f2fcf0e95ceDaniel Veillard        return NULL;
3637d5e198ad454803c60b898451ff432f2fcf0e95ceDaniel Veillard    }
3638d5e198ad454803c60b898451ff432f2fcf0e95ceDaniel Veillard
3639d5e198ad454803c60b898451ff432f2fcf0e95ceDaniel Veillard    result = PyxmlNodeSet_Convert(pyobj_nodes, &nodes);
3640d5e198ad454803c60b898451ff432f2fcf0e95ceDaniel Veillard    if (result < 0) return NULL;
3641d5e198ad454803c60b898451ff432f2fcf0e95ceDaniel Veillard
3642d5e198ad454803c60b898451ff432f2fcf0e95ceDaniel Veillard    if (exclusive) {
3643d5e198ad454803c60b898451ff432f2fcf0e95ceDaniel Veillard        result = PystringSet_Convert(pyobj_prefixes, &prefixes);
3644d5e198ad454803c60b898451ff432f2fcf0e95ceDaniel Veillard        if (result < 0) {
3645d5e198ad454803c60b898451ff432f2fcf0e95ceDaniel Veillard            if (nodes) {
3646d5e198ad454803c60b898451ff432f2fcf0e95ceDaniel Veillard                xmlFree(nodes->nodeTab);
3647d5e198ad454803c60b898451ff432f2fcf0e95ceDaniel Veillard                xmlFree(nodes);
3648d5e198ad454803c60b898451ff432f2fcf0e95ceDaniel Veillard            }
3649d5e198ad454803c60b898451ff432f2fcf0e95ceDaniel Veillard            return NULL;
3650d5e198ad454803c60b898451ff432f2fcf0e95ceDaniel Veillard        }
3651d5e198ad454803c60b898451ff432f2fcf0e95ceDaniel Veillard    }
3652d5e198ad454803c60b898451ff432f2fcf0e95ceDaniel Veillard
3653d5e198ad454803c60b898451ff432f2fcf0e95ceDaniel Veillard    result = xmlC14NDocDumpMemory(doc,
3654d5e198ad454803c60b898451ff432f2fcf0e95ceDaniel Veillard                                  nodes,
3655d5e198ad454803c60b898451ff432f2fcf0e95ceDaniel Veillard                                  exclusive,
3656d5e198ad454803c60b898451ff432f2fcf0e95ceDaniel Veillard                                  prefixes,
3657d5e198ad454803c60b898451ff432f2fcf0e95ceDaniel Veillard                                  with_comments,
3658d5e198ad454803c60b898451ff432f2fcf0e95ceDaniel Veillard                                  &doc_txt);
3659d5e198ad454803c60b898451ff432f2fcf0e95ceDaniel Veillard
3660d5e198ad454803c60b898451ff432f2fcf0e95ceDaniel Veillard    if (nodes) {
3661d5e198ad454803c60b898451ff432f2fcf0e95ceDaniel Veillard        xmlFree(nodes->nodeTab);
3662d5e198ad454803c60b898451ff432f2fcf0e95ceDaniel Veillard        xmlFree(nodes);
3663d5e198ad454803c60b898451ff432f2fcf0e95ceDaniel Veillard    }
3664d5e198ad454803c60b898451ff432f2fcf0e95ceDaniel Veillard    if (prefixes) {
3665d5e198ad454803c60b898451ff432f2fcf0e95ceDaniel Veillard        xmlChar ** idx = prefixes;
3666d5e198ad454803c60b898451ff432f2fcf0e95ceDaniel Veillard        while (*idx) xmlFree(*(idx++));
3667d5e198ad454803c60b898451ff432f2fcf0e95ceDaniel Veillard        xmlFree(prefixes);
3668d5e198ad454803c60b898451ff432f2fcf0e95ceDaniel Veillard    }
3669d5e198ad454803c60b898451ff432f2fcf0e95ceDaniel Veillard
3670d5e198ad454803c60b898451ff432f2fcf0e95ceDaniel Veillard    if (result < 0) {
3671d5e198ad454803c60b898451ff432f2fcf0e95ceDaniel Veillard        PyErr_SetString(PyExc_Exception,
3672d5e198ad454803c60b898451ff432f2fcf0e95ceDaniel Veillard                        "libxml2 xmlC14NDocDumpMemory failure.");
3673d5e198ad454803c60b898451ff432f2fcf0e95ceDaniel Veillard        return NULL;
3674d5e198ad454803c60b898451ff432f2fcf0e95ceDaniel Veillard    }
3675d5e198ad454803c60b898451ff432f2fcf0e95ceDaniel Veillard    else {
36763798c4adbb91f80bef1e9f1b4b61dae72577a244Daniel Veillard        py_retval = PY_IMPORT_STRING_SIZE((const char *) doc_txt,
36773798c4adbb91f80bef1e9f1b4b61dae72577a244Daniel Veillard                                                result);
3678d5e198ad454803c60b898451ff432f2fcf0e95ceDaniel Veillard        xmlFree(doc_txt);
3679d5e198ad454803c60b898451ff432f2fcf0e95ceDaniel Veillard        return py_retval;
3680d5e198ad454803c60b898451ff432f2fcf0e95ceDaniel Veillard    }
3681d5e198ad454803c60b898451ff432f2fcf0e95ceDaniel Veillard}
3682d5e198ad454803c60b898451ff432f2fcf0e95ceDaniel Veillard
3683d5e198ad454803c60b898451ff432f2fcf0e95ceDaniel Veillardstatic PyObject *
3684d5e198ad454803c60b898451ff432f2fcf0e95ceDaniel Veillardlibxml_C14NDocSaveTo(ATTRIBUTE_UNUSED PyObject * self,
3685d5e198ad454803c60b898451ff432f2fcf0e95ceDaniel Veillard                     PyObject * args)
3686d5e198ad454803c60b898451ff432f2fcf0e95ceDaniel Veillard{
3687d5e198ad454803c60b898451ff432f2fcf0e95ceDaniel Veillard    PyObject *pyobj_doc;
3688d5e198ad454803c60b898451ff432f2fcf0e95ceDaniel Veillard    PyObject *py_file;
3689d5e198ad454803c60b898451ff432f2fcf0e95ceDaniel Veillard    PyObject *pyobj_nodes;
3690d5e198ad454803c60b898451ff432f2fcf0e95ceDaniel Veillard    int exclusive;
3691d5e198ad454803c60b898451ff432f2fcf0e95ceDaniel Veillard    PyObject *pyobj_prefixes;
3692d5e198ad454803c60b898451ff432f2fcf0e95ceDaniel Veillard    int with_comments;
3693d5e198ad454803c60b898451ff432f2fcf0e95ceDaniel Veillard
3694d5e198ad454803c60b898451ff432f2fcf0e95ceDaniel Veillard    xmlDocPtr doc;
3695d5e198ad454803c60b898451ff432f2fcf0e95ceDaniel Veillard    xmlNodeSetPtr nodes;
3696d5e198ad454803c60b898451ff432f2fcf0e95ceDaniel Veillard    xmlChar **prefixes = NULL;
3697d5e198ad454803c60b898451ff432f2fcf0e95ceDaniel Veillard    FILE * output;
3698d5e198ad454803c60b898451ff432f2fcf0e95ceDaniel Veillard    xmlOutputBufferPtr buf;
3699d5e198ad454803c60b898451ff432f2fcf0e95ceDaniel Veillard
3700d5e198ad454803c60b898451ff432f2fcf0e95ceDaniel Veillard    int result;
3701d5e198ad454803c60b898451ff432f2fcf0e95ceDaniel Veillard    int len;
3702d5e198ad454803c60b898451ff432f2fcf0e95ceDaniel Veillard
3703d5e198ad454803c60b898451ff432f2fcf0e95ceDaniel Veillard    if (!PyArg_ParseTuple(args, (char *) "OOiOiO:C14NDocSaveTo",
3704d5e198ad454803c60b898451ff432f2fcf0e95ceDaniel Veillard                          &pyobj_doc,
3705d5e198ad454803c60b898451ff432f2fcf0e95ceDaniel Veillard                          &pyobj_nodes,
3706d5e198ad454803c60b898451ff432f2fcf0e95ceDaniel Veillard                          &exclusive,
3707d5e198ad454803c60b898451ff432f2fcf0e95ceDaniel Veillard                          &pyobj_prefixes,
3708d5e198ad454803c60b898451ff432f2fcf0e95ceDaniel Veillard                          &with_comments,
3709d5e198ad454803c60b898451ff432f2fcf0e95ceDaniel Veillard                          &py_file))
3710d5e198ad454803c60b898451ff432f2fcf0e95ceDaniel Veillard        return (NULL);
3711d5e198ad454803c60b898451ff432f2fcf0e95ceDaniel Veillard
3712d5e198ad454803c60b898451ff432f2fcf0e95ceDaniel Veillard    doc = (xmlDocPtr) PyxmlNode_Get(pyobj_doc);
3713d5e198ad454803c60b898451ff432f2fcf0e95ceDaniel Veillard    if (!doc) {
3714d5e198ad454803c60b898451ff432f2fcf0e95ceDaniel Veillard        PyErr_SetString(PyExc_TypeError, "bad document.");
3715d5e198ad454803c60b898451ff432f2fcf0e95ceDaniel Veillard        return NULL;
3716d5e198ad454803c60b898451ff432f2fcf0e95ceDaniel Veillard    }
3717d5e198ad454803c60b898451ff432f2fcf0e95ceDaniel Veillard
37183798c4adbb91f80bef1e9f1b4b61dae72577a244Daniel Veillard    output = PyFile_Get(py_file);
3719d5e198ad454803c60b898451ff432f2fcf0e95ceDaniel Veillard    if (output == NULL) {
3720d5e198ad454803c60b898451ff432f2fcf0e95ceDaniel Veillard        PyErr_SetString(PyExc_TypeError, "bad file.");
3721d5e198ad454803c60b898451ff432f2fcf0e95ceDaniel Veillard        return NULL;
3722d5e198ad454803c60b898451ff432f2fcf0e95ceDaniel Veillard    }
3723d5e198ad454803c60b898451ff432f2fcf0e95ceDaniel Veillard    buf = xmlOutputBufferCreateFile(output, NULL);
3724d5e198ad454803c60b898451ff432f2fcf0e95ceDaniel Veillard
3725d5e198ad454803c60b898451ff432f2fcf0e95ceDaniel Veillard    result = PyxmlNodeSet_Convert(pyobj_nodes, &nodes);
3726d5e198ad454803c60b898451ff432f2fcf0e95ceDaniel Veillard    if (result < 0) return NULL;
3727d5e198ad454803c60b898451ff432f2fcf0e95ceDaniel Veillard
3728d5e198ad454803c60b898451ff432f2fcf0e95ceDaniel Veillard    if (exclusive) {
3729d5e198ad454803c60b898451ff432f2fcf0e95ceDaniel Veillard        result = PystringSet_Convert(pyobj_prefixes, &prefixes);
3730d5e198ad454803c60b898451ff432f2fcf0e95ceDaniel Veillard        if (result < 0) {
3731d5e198ad454803c60b898451ff432f2fcf0e95ceDaniel Veillard            if (nodes) {
3732d5e198ad454803c60b898451ff432f2fcf0e95ceDaniel Veillard                xmlFree(nodes->nodeTab);
3733d5e198ad454803c60b898451ff432f2fcf0e95ceDaniel Veillard                xmlFree(nodes);
3734d5e198ad454803c60b898451ff432f2fcf0e95ceDaniel Veillard            }
3735d5e198ad454803c60b898451ff432f2fcf0e95ceDaniel Veillard            return NULL;
3736d5e198ad454803c60b898451ff432f2fcf0e95ceDaniel Veillard        }
3737d5e198ad454803c60b898451ff432f2fcf0e95ceDaniel Veillard    }
3738d5e198ad454803c60b898451ff432f2fcf0e95ceDaniel Veillard
3739d5e198ad454803c60b898451ff432f2fcf0e95ceDaniel Veillard    result = xmlC14NDocSaveTo(doc,
3740d5e198ad454803c60b898451ff432f2fcf0e95ceDaniel Veillard                              nodes,
3741d5e198ad454803c60b898451ff432f2fcf0e95ceDaniel Veillard                              exclusive,
3742d5e198ad454803c60b898451ff432f2fcf0e95ceDaniel Veillard                              prefixes,
3743d5e198ad454803c60b898451ff432f2fcf0e95ceDaniel Veillard                              with_comments,
3744d5e198ad454803c60b898451ff432f2fcf0e95ceDaniel Veillard                              buf);
3745d5e198ad454803c60b898451ff432f2fcf0e95ceDaniel Veillard
3746d5e198ad454803c60b898451ff432f2fcf0e95ceDaniel Veillard    if (nodes) {
3747d5e198ad454803c60b898451ff432f2fcf0e95ceDaniel Veillard        xmlFree(nodes->nodeTab);
3748d5e198ad454803c60b898451ff432f2fcf0e95ceDaniel Veillard        xmlFree(nodes);
3749d5e198ad454803c60b898451ff432f2fcf0e95ceDaniel Veillard    }
3750d5e198ad454803c60b898451ff432f2fcf0e95ceDaniel Veillard    if (prefixes) {
3751d5e198ad454803c60b898451ff432f2fcf0e95ceDaniel Veillard        xmlChar ** idx = prefixes;
3752d5e198ad454803c60b898451ff432f2fcf0e95ceDaniel Veillard        while (*idx) xmlFree(*(idx++));
3753d5e198ad454803c60b898451ff432f2fcf0e95ceDaniel Veillard        xmlFree(prefixes);
3754d5e198ad454803c60b898451ff432f2fcf0e95ceDaniel Veillard    }
3755d5e198ad454803c60b898451ff432f2fcf0e95ceDaniel Veillard
37563798c4adbb91f80bef1e9f1b4b61dae72577a244Daniel Veillard    PyFile_Release(output);
3757d5e198ad454803c60b898451ff432f2fcf0e95ceDaniel Veillard    len = xmlOutputBufferClose(buf);
3758d5e198ad454803c60b898451ff432f2fcf0e95ceDaniel Veillard
3759d5e198ad454803c60b898451ff432f2fcf0e95ceDaniel Veillard    if (result < 0) {
3760d5e198ad454803c60b898451ff432f2fcf0e95ceDaniel Veillard        PyErr_SetString(PyExc_Exception,
3761d5e198ad454803c60b898451ff432f2fcf0e95ceDaniel Veillard                        "libxml2 xmlC14NDocSaveTo failure.");
3762d5e198ad454803c60b898451ff432f2fcf0e95ceDaniel Veillard        return NULL;
3763d5e198ad454803c60b898451ff432f2fcf0e95ceDaniel Veillard    }
3764d5e198ad454803c60b898451ff432f2fcf0e95ceDaniel Veillard    else
37653798c4adbb91f80bef1e9f1b4b61dae72577a244Daniel Veillard        return PyLong_FromLong((long) len);
3766d5e198ad454803c60b898451ff432f2fcf0e95ceDaniel Veillard}
3767d5e198ad454803c60b898451ff432f2fcf0e95ceDaniel Veillard
3768d5e198ad454803c60b898451ff432f2fcf0e95ceDaniel Veillard#endif
3769d5e198ad454803c60b898451ff432f2fcf0e95ceDaniel Veillard#endif
3770d5e198ad454803c60b898451ff432f2fcf0e95ceDaniel Veillard
3771c68d78d25a17e65d172ccc1ac24d609c7c1d5cdeWilliam M. Brackstatic PyObject *
3772c68d78d25a17e65d172ccc1ac24d609c7c1d5cdeWilliam M. Bracklibxml_getObjDesc(PyObject *self ATTRIBUTE_UNUSED, PyObject *args) {
3773c68d78d25a17e65d172ccc1ac24d609c7c1d5cdeWilliam M. Brack
3774c68d78d25a17e65d172ccc1ac24d609c7c1d5cdeWilliam M. Brack    PyObject *obj;
3775c68d78d25a17e65d172ccc1ac24d609c7c1d5cdeWilliam M. Brack    char *str;
3776d5e198ad454803c60b898451ff432f2fcf0e95ceDaniel Veillard
3777c68d78d25a17e65d172ccc1ac24d609c7c1d5cdeWilliam M. Brack    if (!PyArg_ParseTuple(args, (char *)"O:getObjDesc", &obj))
3778c68d78d25a17e65d172ccc1ac24d609c7c1d5cdeWilliam M. Brack        return NULL;
37793798c4adbb91f80bef1e9f1b4b61dae72577a244Daniel Veillard    str = PyCapsule_GetPointer(obj, PyCapsule_GetName(obj));
3780c68d78d25a17e65d172ccc1ac24d609c7c1d5cdeWilliam M. Brack    return Py_BuildValue((char *)"s", str);
3781c68d78d25a17e65d172ccc1ac24d609c7c1d5cdeWilliam M. Brack}
3782d5e198ad454803c60b898451ff432f2fcf0e95ceDaniel Veillard
378340cca61fc130f0f865f51b2fb2ba15e478e102abWilliam M. Brackstatic PyObject *
378440cca61fc130f0f865f51b2fb2ba15e478e102abWilliam M. Bracklibxml_compareNodesEqual(PyObject *self ATTRIBUTE_UNUSED, PyObject *args) {
378540cca61fc130f0f865f51b2fb2ba15e478e102abWilliam M. Brack
378640cca61fc130f0f865f51b2fb2ba15e478e102abWilliam M. Brack    PyObject *py_node1, *py_node2;
378740cca61fc130f0f865f51b2fb2ba15e478e102abWilliam M. Brack    xmlNodePtr node1, node2;
378840cca61fc130f0f865f51b2fb2ba15e478e102abWilliam M. Brack
378940cca61fc130f0f865f51b2fb2ba15e478e102abWilliam M. Brack    if (!PyArg_ParseTuple(args, (char *)"OO:compareNodesEqual",
379040cca61fc130f0f865f51b2fb2ba15e478e102abWilliam M. Brack		&py_node1, &py_node2))
379140cca61fc130f0f865f51b2fb2ba15e478e102abWilliam M. Brack        return NULL;
379240cca61fc130f0f865f51b2fb2ba15e478e102abWilliam M. Brack    /* To compare two node objects, we compare their pointer addresses */
379340cca61fc130f0f865f51b2fb2ba15e478e102abWilliam M. Brack    node1 = PyxmlNode_Get(py_node1);
379440cca61fc130f0f865f51b2fb2ba15e478e102abWilliam M. Brack    node2 = PyxmlNode_Get(py_node2);
379540cca61fc130f0f865f51b2fb2ba15e478e102abWilliam M. Brack    if ( node1 == node2 )
379640cca61fc130f0f865f51b2fb2ba15e478e102abWilliam M. Brack        return Py_BuildValue((char *)"i", 1);
379740cca61fc130f0f865f51b2fb2ba15e478e102abWilliam M. Brack    else
379840cca61fc130f0f865f51b2fb2ba15e478e102abWilliam M. Brack        return Py_BuildValue((char *)"i", 0);
379940cca61fc130f0f865f51b2fb2ba15e478e102abWilliam M. Brack
380040cca61fc130f0f865f51b2fb2ba15e478e102abWilliam M. Brack}
380140cca61fc130f0f865f51b2fb2ba15e478e102abWilliam M. Brack
380240cca61fc130f0f865f51b2fb2ba15e478e102abWilliam M. Brackstatic PyObject *
380340cca61fc130f0f865f51b2fb2ba15e478e102abWilliam M. Bracklibxml_nodeHash(PyObject *self ATTRIBUTE_UNUSED, PyObject *args) {
380440cca61fc130f0f865f51b2fb2ba15e478e102abWilliam M. Brack
380540cca61fc130f0f865f51b2fb2ba15e478e102abWilliam M. Brack    PyObject *py_node1;
380640cca61fc130f0f865f51b2fb2ba15e478e102abWilliam M. Brack    xmlNodePtr node1;
380740cca61fc130f0f865f51b2fb2ba15e478e102abWilliam M. Brack
380840cca61fc130f0f865f51b2fb2ba15e478e102abWilliam M. Brack    if (!PyArg_ParseTuple(args, (char *)"O:nodeHash", &py_node1))
380940cca61fc130f0f865f51b2fb2ba15e478e102abWilliam M. Brack	    return NULL;
381040cca61fc130f0f865f51b2fb2ba15e478e102abWilliam M. Brack    /* For simplicity, we use the node pointer address as a hash value */
381140cca61fc130f0f865f51b2fb2ba15e478e102abWilliam M. Brack    node1 = PyxmlNode_Get(py_node1);
381240cca61fc130f0f865f51b2fb2ba15e478e102abWilliam M. Brack
381340cca61fc130f0f865f51b2fb2ba15e478e102abWilliam M. Brack    return PyLong_FromVoidPtr(node1);
381440cca61fc130f0f865f51b2fb2ba15e478e102abWilliam M. Brack
381540cca61fc130f0f865f51b2fb2ba15e478e102abWilliam M. Brack}
381640cca61fc130f0f865f51b2fb2ba15e478e102abWilliam M. Brack
3817a94ec6ff13d9617ff22e790cef82208e7d1bd375Daniel Veillard/************************************************************************
3818a94ec6ff13d9617ff22e790cef82208e7d1bd375Daniel Veillard *									*
3819d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard *			The registration stuff				*
3820d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard *									*
3821d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard ************************************************************************/
3822d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillardstatic PyMethodDef libxmlMethods[] = {
382396fe095d4bf3c76301ed58ebe1ba10f8004f87efDaniel Veillard#include "libxml2-export.c"
3824d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard    {(char *) "name", libxml_name, METH_VARARGS, NULL},
3825d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard    {(char *) "children", libxml_children, METH_VARARGS, NULL},
3826d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard    {(char *) "properties", libxml_properties, METH_VARARGS, NULL},
3827d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard    {(char *) "last", libxml_last, METH_VARARGS, NULL},
3828d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard    {(char *) "prev", libxml_prev, METH_VARARGS, NULL},
3829d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard    {(char *) "next", libxml_next, METH_VARARGS, NULL},
3830d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard    {(char *) "parent", libxml_parent, METH_VARARGS, NULL},
3831d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard    {(char *) "type", libxml_type, METH_VARARGS, NULL},
3832d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard    {(char *) "doc", libxml_doc, METH_VARARGS, NULL},
3833d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard    {(char *) "xmlNewNode", libxml_xmlNewNode, METH_VARARGS, NULL},
3834f9cf6f5a01527406ed0bcbcf5a180d85b5e771deDaniel Veillard    {(char *) "xmlNodeRemoveNsDef", libxml_xmlNodeRemoveNsDef, METH_VARARGS, NULL},
3835850ce9b6584ecc2893632392f1d3ba46fefc13acDaniel Veillard    {(char *)"xmlSetValidErrors", libxml_xmlSetValidErrors, METH_VARARGS, NULL},
383625c90c589b256f0925f081198c1525134a491e31Daniel Veillard    {(char *)"xmlFreeValidCtxt", libxml_xmlFreeValidCtxt, METH_VARARGS, NULL},
3837a9cce9cd0d7aff3ec318b5d8d376da131b6aaad4Daniel Veillard#ifdef LIBXML_OUTPUT_ENABLED
3838d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard    {(char *) "serializeNode", libxml_serializeNode, METH_VARARGS, NULL},
3839d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard    {(char *) "saveNodeTo", libxml_saveNodeTo, METH_VARARGS, NULL},
3840c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard    {(char *) "outputBufferCreate", libxml_xmlCreateOutputBuffer, METH_VARARGS, NULL},
38416cbd6c0738efb6c55d08f39c0731d46d678858faDaniel Veillard    {(char *) "outputBufferGetPythonFile", libxml_outputBufferGetPythonFile, METH_VARARGS, NULL},
38426cbd6c0738efb6c55d08f39c0731d46d678858faDaniel Veillard    {(char *) "xmlOutputBufferClose", libxml_xmlOutputBufferClose, METH_VARARGS, NULL},
38436cbd6c0738efb6c55d08f39c0731d46d678858faDaniel Veillard    { (char *)"xmlOutputBufferFlush", libxml_xmlOutputBufferFlush, METH_VARARGS, NULL },
3844263ec86a75f7b5ec2d37dbb89356bf7fca11cff3Daniel Veillard    { (char *)"xmlSaveFileTo", libxml_xmlSaveFileTo, METH_VARARGS, NULL },
3845263ec86a75f7b5ec2d37dbb89356bf7fca11cff3Daniel Veillard    { (char *)"xmlSaveFormatFileTo", libxml_xmlSaveFormatFileTo, METH_VARARGS, NULL },
3846a9cce9cd0d7aff3ec318b5d8d376da131b6aaad4Daniel Veillard#endif /* LIBXML_OUTPUT_ENABLED */
3847c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard    {(char *) "inputBufferCreate", libxml_xmlCreateInputBuffer, METH_VARARGS, NULL},
3848c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard    {(char *) "setEntityLoader", libxml_xmlSetEntityLoader, METH_VARARGS, NULL},
38493e20a2921373677d1cf54fcf6081b3492e0c7558Daniel Veillard    {(char *)"xmlRegisterErrorHandler", libxml_xmlRegisterErrorHandler, METH_VARARGS, NULL },
3850417be3ae08346c6510c28d2042dd42a22a74b331Daniel Veillard    {(char *)"xmlParserCtxtSetErrorHandler", libxml_xmlParserCtxtSetErrorHandler, METH_VARARGS, NULL },
3851417be3ae08346c6510c28d2042dd42a22a74b331Daniel Veillard    {(char *)"xmlParserCtxtGetErrorHandler", libxml_xmlParserCtxtGetErrorHandler, METH_VARARGS, NULL },
3852e6227e0549490b5bf9271ecd2d874a97c3f4852bDaniel Veillard    {(char *)"xmlFreeParserCtxt", libxml_xmlFreeParserCtxt, METH_VARARGS, NULL },
3853438ebbd59af78c436397ae488e42aeca5cad7542Daniel Veillard#ifdef LIBXML_READER_ENABLED
385426f70269c80140a7fb8a7aae9ef09c95efa98e70Daniel Veillard    {(char *)"xmlTextReaderSetErrorHandler", libxml_xmlTextReaderSetErrorHandler, METH_VARARGS, NULL },
385526f70269c80140a7fb8a7aae9ef09c95efa98e70Daniel Veillard    {(char *)"xmlTextReaderGetErrorHandler", libxml_xmlTextReaderGetErrorHandler, METH_VARARGS, NULL },
385626f70269c80140a7fb8a7aae9ef09c95efa98e70Daniel Veillard    {(char *)"xmlFreeTextReader", libxml_xmlFreeTextReader, METH_VARARGS, NULL },
3857438ebbd59af78c436397ae488e42aeca5cad7542Daniel Veillard#endif
38585439624bd9167dbb880ea4a75d91677d20a6ebe3Daniel Veillard    {(char *)"addLocalCatalog", libxml_addLocalCatalog, METH_VARARGS, NULL },
3859c2664641740126714bb363bd6b5f65f724031c83Daniel Veillard#ifdef LIBXML_SCHEMAS_ENABLED
3860c2664641740126714bb363bd6b5f65f724031c83Daniel Veillard    {(char *)"xmlRelaxNGSetValidErrors", libxml_xmlRelaxNGSetValidErrors, METH_VARARGS, NULL},
3861c2664641740126714bb363bd6b5f65f724031c83Daniel Veillard    {(char *)"xmlRelaxNGFreeValidCtxt", libxml_xmlRelaxNGFreeValidCtxt, METH_VARARGS, NULL},
3862eff45a92da861195551a2050487fcca0492cac7cDaniel Veillard    {(char *)"xmlSchemaSetValidErrors", libxml_xmlSchemaSetValidErrors, METH_VARARGS, NULL},
3863bb8502c0ef2af706fbdff69119e994e40da64a88Daniel Veillard    {(char *)"xmlSchemaFreeValidCtxt", libxml_xmlSchemaFreeValidCtxt, METH_VARARGS, NULL},
3864c2664641740126714bb363bd6b5f65f724031c83Daniel Veillard#endif
3865d5e198ad454803c60b898451ff432f2fcf0e95ceDaniel Veillard#ifdef LIBXML_C14N_ENABLED
3866d5e198ad454803c60b898451ff432f2fcf0e95ceDaniel Veillard#ifdef LIBXML_OUTPUT_ENABLED
3867d5e198ad454803c60b898451ff432f2fcf0e95ceDaniel Veillard    {(char *)"xmlC14NDocDumpMemory", libxml_C14NDocDumpMemory, METH_VARARGS, NULL},
3868d5e198ad454803c60b898451ff432f2fcf0e95ceDaniel Veillard    {(char *)"xmlC14NDocSaveTo", libxml_C14NDocSaveTo, METH_VARARGS, NULL},
3869d5e198ad454803c60b898451ff432f2fcf0e95ceDaniel Veillard#endif
3870d5e198ad454803c60b898451ff432f2fcf0e95ceDaniel Veillard#endif
3871c68d78d25a17e65d172ccc1ac24d609c7c1d5cdeWilliam M. Brack    {(char *) "getObjDesc", libxml_getObjDesc, METH_VARARGS, NULL},
387240cca61fc130f0f865f51b2fb2ba15e478e102abWilliam M. Brack    {(char *) "compareNodesEqual", libxml_compareNodesEqual, METH_VARARGS, NULL},
387340cca61fc130f0f865f51b2fb2ba15e478e102abWilliam M. Brack    {(char *) "nodeHash", libxml_nodeHash, METH_VARARGS, NULL},
387448da90bc4a3809728d08ee9ee8da21d044fbca82Alexey Neyman    {(char *) "xmlRegisterInputCallback", libxml_xmlRegisterInputCallback, METH_VARARGS, NULL},
387548da90bc4a3809728d08ee9ee8da21d044fbca82Alexey Neyman    {(char *) "xmlUnregisterInputCallback", libxml_xmlUnregisterInputCallback, METH_VARARGS, NULL},
3876d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard    {NULL, NULL, 0, NULL}
3877d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard};
3878d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard
38793798c4adbb91f80bef1e9f1b4b61dae72577a244Daniel Veillard#if PY_MAJOR_VERSION >= 3
38803798c4adbb91f80bef1e9f1b4b61dae72577a244Daniel Veillard#define INITERROR return NULL
38813798c4adbb91f80bef1e9f1b4b61dae72577a244Daniel Veillard
38823798c4adbb91f80bef1e9f1b4b61dae72577a244Daniel Veillardstatic struct PyModuleDef moduledef = {
38833798c4adbb91f80bef1e9f1b4b61dae72577a244Daniel Veillard        PyModuleDef_HEAD_INIT,
38843798c4adbb91f80bef1e9f1b4b61dae72577a244Daniel Veillard        "libxml2mod",
38853798c4adbb91f80bef1e9f1b4b61dae72577a244Daniel Veillard        NULL,
38863798c4adbb91f80bef1e9f1b4b61dae72577a244Daniel Veillard        -1,
38873798c4adbb91f80bef1e9f1b4b61dae72577a244Daniel Veillard        libxmlMethods,
38883798c4adbb91f80bef1e9f1b4b61dae72577a244Daniel Veillard        NULL,
38893798c4adbb91f80bef1e9f1b4b61dae72577a244Daniel Veillard        NULL,
38903798c4adbb91f80bef1e9f1b4b61dae72577a244Daniel Veillard        NULL,
38913798c4adbb91f80bef1e9f1b4b61dae72577a244Daniel Veillard        NULL
38923798c4adbb91f80bef1e9f1b4b61dae72577a244Daniel Veillard};
38933798c4adbb91f80bef1e9f1b4b61dae72577a244Daniel Veillard
38943798c4adbb91f80bef1e9f1b4b61dae72577a244Daniel Veillard#else
38953798c4adbb91f80bef1e9f1b4b61dae72577a244Daniel Veillard#define INITERROR return
38963798c4adbb91f80bef1e9f1b4b61dae72577a244Daniel Veillard
38970fea6f45cd6f158418318c0af922533e44f9c0e2Daniel Veillard#ifdef MERGED_MODULES
38986361da0c25e355affdeed84cfccb187ccaadfccbDaniel Veillardextern void initlibxsltmod(void);
38990fea6f45cd6f158418318c0af922533e44f9c0e2Daniel Veillard#endif
39000fea6f45cd6f158418318c0af922533e44f9c0e2Daniel Veillard
39013798c4adbb91f80bef1e9f1b4b61dae72577a244Daniel Veillard#endif
3902af43f63aaabf0dc4b4a070773875d0927da3d8a2Daniel Veillard
39033798c4adbb91f80bef1e9f1b4b61dae72577a244Daniel Veillard#if PY_MAJOR_VERSION >= 3
39043798c4adbb91f80bef1e9f1b4b61dae72577a244Daniel VeillardPyObject *PyInit_libxml2mod(void)
39053798c4adbb91f80bef1e9f1b4b61dae72577a244Daniel Veillard#else
39063798c4adbb91f80bef1e9f1b4b61dae72577a244Daniel Veillardvoid initlibxml2mod(void)
39073798c4adbb91f80bef1e9f1b4b61dae72577a244Daniel Veillard#endif
39083798c4adbb91f80bef1e9f1b4b61dae72577a244Daniel Veillard{
39093798c4adbb91f80bef1e9f1b4b61dae72577a244Daniel Veillard    PyObject *module;
39108e2cc6f2b53f536692f3c8ad8112bb67e0a1a629William M. Brack
39113798c4adbb91f80bef1e9f1b4b61dae72577a244Daniel Veillard#if PY_MAJOR_VERSION >= 3
39123798c4adbb91f80bef1e9f1b4b61dae72577a244Daniel Veillard    module = PyModule_Create(&moduledef);
39133798c4adbb91f80bef1e9f1b4b61dae72577a244Daniel Veillard#else
3914f93a866079364a006189683eaa07f94c867389d1Daniel Veillard    /* intialize the python extension module */
39153798c4adbb91f80bef1e9f1b4b61dae72577a244Daniel Veillard    module = Py_InitModule((char *) "libxml2mod", libxmlMethods);
39163798c4adbb91f80bef1e9f1b4b61dae72577a244Daniel Veillard#endif
39173798c4adbb91f80bef1e9f1b4b61dae72577a244Daniel Veillard    if (module == NULL)
39183798c4adbb91f80bef1e9f1b4b61dae72577a244Daniel Veillard        INITERROR;
3919f93a866079364a006189683eaa07f94c867389d1Daniel Veillard
3920f93a866079364a006189683eaa07f94c867389d1Daniel Veillard    /* initialize libxml2 */
3921f93a866079364a006189683eaa07f94c867389d1Daniel Veillard    xmlInitParser();
39223798c4adbb91f80bef1e9f1b4b61dae72577a244Daniel Veillard    /* TODO this probably need to be revamped for Python3 */
39235d81903b06418c7d8cc72cf9add81c4026a2f3bcDaniel Veillard    libxml_xmlErrorInitialize();
39246361da0c25e355affdeed84cfccb187ccaadfccbDaniel Veillard
39253798c4adbb91f80bef1e9f1b4b61dae72577a244Daniel Veillard#if PY_MAJOR_VERSION < 3
39260fea6f45cd6f158418318c0af922533e44f9c0e2Daniel Veillard#ifdef MERGED_MODULES
39270fea6f45cd6f158418318c0af922533e44f9c0e2Daniel Veillard    initlibxsltmod();
39280fea6f45cd6f158418318c0af922533e44f9c0e2Daniel Veillard#endif
39293798c4adbb91f80bef1e9f1b4b61dae72577a244Daniel Veillard#endif
39303798c4adbb91f80bef1e9f1b4b61dae72577a244Daniel Veillard
39313798c4adbb91f80bef1e9f1b4b61dae72577a244Daniel Veillard#if PY_MAJOR_VERSION >= 3
39323798c4adbb91f80bef1e9f1b4b61dae72577a244Daniel Veillard    return module;
39333798c4adbb91f80bef1e9f1b4b61dae72577a244Daniel Veillard#endif
3934d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard}
3935