libxml.c revision 519bc6a3ab82445a8719f548d0450efe02cc9c82
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
44d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillardvoid initlibxml2mod(void);
45d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard
46c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard/**
47c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard * TODO:
48c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard *
49c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard * macro to flag unimplemented blocks
50c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard */
51c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard#define TODO 								\
52c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard    xmlGenericError(xmlGenericErrorContext,				\
53c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard	    "Unimplemented block at %s:%d\n",				\
54c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard            __FILE__, __LINE__);
558e2cc6f2b53f536692f3c8ad8112bb67e0a1a629William M. Brack/*
568e2cc6f2b53f536692f3c8ad8112bb67e0a1a629William M. Brack * the following vars are used for XPath extensions, but
578e2cc6f2b53f536692f3c8ad8112bb67e0a1a629William M. Brack * are also referenced within the parser cleanup routine.
588e2cc6f2b53f536692f3c8ad8112bb67e0a1a629William M. Brack */
598e2cc6f2b53f536692f3c8ad8112bb67e0a1a629William M. Brackstatic int libxml_xpathCallbacksInitialized = 0;
608e2cc6f2b53f536692f3c8ad8112bb67e0a1a629William M. Brack
618e2cc6f2b53f536692f3c8ad8112bb67e0a1a629William M. Bracktypedef struct libxml_xpathCallback {
628e2cc6f2b53f536692f3c8ad8112bb67e0a1a629William M. Brack    xmlXPathContextPtr ctx;
638e2cc6f2b53f536692f3c8ad8112bb67e0a1a629William M. Brack    xmlChar *name;
648e2cc6f2b53f536692f3c8ad8112bb67e0a1a629William M. Brack    xmlChar *ns_uri;
658e2cc6f2b53f536692f3c8ad8112bb67e0a1a629William M. Brack    PyObject *function;
668e2cc6f2b53f536692f3c8ad8112bb67e0a1a629William M. Brack} libxml_xpathCallback, *libxml_xpathCallbackPtr;
678e2cc6f2b53f536692f3c8ad8112bb67e0a1a629William M. Bracktypedef libxml_xpathCallback libxml_xpathCallbackArray[];
688e2cc6f2b53f536692f3c8ad8112bb67e0a1a629William M. Brackstatic int libxml_xpathCallbacksAllocd = 10;
698e2cc6f2b53f536692f3c8ad8112bb67e0a1a629William M. Brackstatic libxml_xpathCallbackArray *libxml_xpathCallbacks = NULL;
708e2cc6f2b53f536692f3c8ad8112bb67e0a1a629William M. Brackstatic int libxml_xpathCallbacksNb = 0;
71c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard
724e1b26cfeba7f5fad4f8bd12fb5ce7029f930b79Daniel Veillard/************************************************************************
734e1b26cfeba7f5fad4f8bd12fb5ce7029f930b79Daniel Veillard *									*
744e1b26cfeba7f5fad4f8bd12fb5ce7029f930b79Daniel Veillard *		Memory debug interface					*
754e1b26cfeba7f5fad4f8bd12fb5ce7029f930b79Daniel Veillard *									*
764e1b26cfeba7f5fad4f8bd12fb5ce7029f930b79Daniel Veillard ************************************************************************/
774e1b26cfeba7f5fad4f8bd12fb5ce7029f930b79Daniel Veillard
78c2664641740126714bb363bd6b5f65f724031c83Daniel Veillard#if 0
794e1b26cfeba7f5fad4f8bd12fb5ce7029f930b79Daniel Veillardextern void xmlMemFree(void *ptr);
804e1b26cfeba7f5fad4f8bd12fb5ce7029f930b79Daniel Veillardextern void *xmlMemMalloc(size_t size);
81d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillardextern void *xmlMemRealloc(void *ptr, size_t size);
824e1b26cfeba7f5fad4f8bd12fb5ce7029f930b79Daniel Veillardextern char *xmlMemoryStrdup(const char *str);
83c2664641740126714bb363bd6b5f65f724031c83Daniel Veillard#endif
844e1b26cfeba7f5fad4f8bd12fb5ce7029f930b79Daniel Veillard
854e1b26cfeba7f5fad4f8bd12fb5ce7029f930b79Daniel Veillardstatic int libxmlMemoryDebugActivated = 0;
864e1b26cfeba7f5fad4f8bd12fb5ce7029f930b79Daniel Veillardstatic long libxmlMemoryAllocatedBase = 0;
874e1b26cfeba7f5fad4f8bd12fb5ce7029f930b79Daniel Veillard
884e1b26cfeba7f5fad4f8bd12fb5ce7029f930b79Daniel Veillardstatic int libxmlMemoryDebug = 0;
894e1b26cfeba7f5fad4f8bd12fb5ce7029f930b79Daniel Veillardstatic xmlFreeFunc freeFunc = NULL;
904e1b26cfeba7f5fad4f8bd12fb5ce7029f930b79Daniel Veillardstatic xmlMallocFunc mallocFunc = NULL;
914e1b26cfeba7f5fad4f8bd12fb5ce7029f930b79Daniel Veillardstatic xmlReallocFunc reallocFunc = NULL;
924e1b26cfeba7f5fad4f8bd12fb5ce7029f930b79Daniel Veillardstatic xmlStrdupFunc strdupFunc = NULL;
934e1b26cfeba7f5fad4f8bd12fb5ce7029f930b79Daniel Veillard
94f93a866079364a006189683eaa07f94c867389d1Daniel Veillardstatic void
95f93a866079364a006189683eaa07f94c867389d1Daniel Veillardlibxml_xmlErrorInitialize(void); /* forward declare */
96f93a866079364a006189683eaa07f94c867389d1Daniel Veillard
974e1b26cfeba7f5fad4f8bd12fb5ce7029f930b79Daniel VeillardPyObject *
98c68d78d25a17e65d172ccc1ac24d609c7c1d5cdeWilliam M. Bracklibxml_xmlMemoryUsed(PyObject * self ATTRIBUTE_UNUSED,
99c68d78d25a17e65d172ccc1ac24d609c7c1d5cdeWilliam M. Brack        PyObject * args ATTRIBUTE_UNUSED)
100529233ccdd43203fd74ec18a1d5a071c122c6e46Daniel Veillard{
101529233ccdd43203fd74ec18a1d5a071c122c6e46Daniel Veillard    long ret;
102529233ccdd43203fd74ec18a1d5a071c122c6e46Daniel Veillard    PyObject *py_retval;
103529233ccdd43203fd74ec18a1d5a071c122c6e46Daniel Veillard
104529233ccdd43203fd74ec18a1d5a071c122c6e46Daniel Veillard    ret = xmlMemUsed();
105529233ccdd43203fd74ec18a1d5a071c122c6e46Daniel Veillard
106529233ccdd43203fd74ec18a1d5a071c122c6e46Daniel Veillard    py_retval = libxml_longWrap(ret);
107529233ccdd43203fd74ec18a1d5a071c122c6e46Daniel Veillard    return (py_retval);
108529233ccdd43203fd74ec18a1d5a071c122c6e46Daniel Veillard}
109529233ccdd43203fd74ec18a1d5a071c122c6e46Daniel Veillard
110529233ccdd43203fd74ec18a1d5a071c122c6e46Daniel VeillardPyObject *
111c68d78d25a17e65d172ccc1ac24d609c7c1d5cdeWilliam M. Bracklibxml_xmlDebugMemory(PyObject * self ATTRIBUTE_UNUSED, PyObject * args)
112d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard{
1134e1b26cfeba7f5fad4f8bd12fb5ce7029f930b79Daniel Veillard    int activate;
1144e1b26cfeba7f5fad4f8bd12fb5ce7029f930b79Daniel Veillard    PyObject *py_retval;
1154e1b26cfeba7f5fad4f8bd12fb5ce7029f930b79Daniel Veillard    long ret;
1164e1b26cfeba7f5fad4f8bd12fb5ce7029f930b79Daniel Veillard
117d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard    if (!PyArg_ParseTuple(args, (char *) "i:xmlDebugMemory", &activate))
118d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        return (NULL);
1194e1b26cfeba7f5fad4f8bd12fb5ce7029f930b79Daniel Veillard
1204e1b26cfeba7f5fad4f8bd12fb5ce7029f930b79Daniel Veillard#ifdef DEBUG_MEMORY
1214e1b26cfeba7f5fad4f8bd12fb5ce7029f930b79Daniel Veillard    printf("libxml_xmlDebugMemory(%d) called\n", activate);
1224e1b26cfeba7f5fad4f8bd12fb5ce7029f930b79Daniel Veillard#endif
1234e1b26cfeba7f5fad4f8bd12fb5ce7029f930b79Daniel Veillard
1244e1b26cfeba7f5fad4f8bd12fb5ce7029f930b79Daniel Veillard    if (activate != 0) {
125d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        if (libxmlMemoryDebug == 0) {
126d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            /*
127d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard             * First initialize the library and grab the old memory handlers
128d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard             * and switch the library to memory debugging
129d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard             */
130d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            xmlMemGet((xmlFreeFunc *) & freeFunc,
131d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard                      (xmlMallocFunc *) & mallocFunc,
132d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard                      (xmlReallocFunc *) & reallocFunc,
133d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard                      (xmlStrdupFunc *) & strdupFunc);
134d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            if ((freeFunc == xmlMemFree) && (mallocFunc == xmlMemMalloc) &&
135d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard                (reallocFunc == xmlMemRealloc) &&
136d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard                (strdupFunc == xmlMemoryStrdup)) {
137d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard                libxmlMemoryAllocatedBase = xmlMemUsed();
138d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            } else {
139f93a866079364a006189683eaa07f94c867389d1Daniel Veillard                /*
140f93a866079364a006189683eaa07f94c867389d1Daniel Veillard                 * cleanup first, because some memory has been
141f93a866079364a006189683eaa07f94c867389d1Daniel Veillard                 * allocated with the non-debug malloc in xmlInitParser
142f93a866079364a006189683eaa07f94c867389d1Daniel Veillard                 * when the python module was imported
143f93a866079364a006189683eaa07f94c867389d1Daniel Veillard                 */
144f93a866079364a006189683eaa07f94c867389d1Daniel Veillard                xmlCleanupParser();
145d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard                ret = (long) xmlMemSetup(xmlMemFree, xmlMemMalloc,
146d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard                                         xmlMemRealloc, xmlMemoryStrdup);
147d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard                if (ret < 0)
148d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard                    goto error;
149d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard                libxmlMemoryAllocatedBase = xmlMemUsed();
150f93a866079364a006189683eaa07f94c867389d1Daniel Veillard                /* reinitialize */
151f93a866079364a006189683eaa07f94c867389d1Daniel Veillard                xmlInitParser();
152f93a866079364a006189683eaa07f94c867389d1Daniel Veillard                libxml_xmlErrorInitialize();
153d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            }
154d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            ret = 0;
155d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        } else if (libxmlMemoryDebugActivated == 0) {
156d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            libxmlMemoryAllocatedBase = xmlMemUsed();
157d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            ret = 0;
158d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        } else {
159d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            ret = xmlMemUsed() - libxmlMemoryAllocatedBase;
160d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        }
161d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        libxmlMemoryDebug = 1;
162d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        libxmlMemoryDebugActivated = 1;
1634e1b26cfeba7f5fad4f8bd12fb5ce7029f930b79Daniel Veillard    } else {
164d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        if (libxmlMemoryDebugActivated == 1)
165d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            ret = xmlMemUsed() - libxmlMemoryAllocatedBase;
166d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        else
167d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            ret = 0;
168d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        libxmlMemoryDebugActivated = 0;
1694e1b26cfeba7f5fad4f8bd12fb5ce7029f930b79Daniel Veillard    }
170d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard  error:
1714e1b26cfeba7f5fad4f8bd12fb5ce7029f930b79Daniel Veillard    py_retval = libxml_longWrap(ret);
172d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard    return (py_retval);
1734e1b26cfeba7f5fad4f8bd12fb5ce7029f930b79Daniel Veillard}
1744e1b26cfeba7f5fad4f8bd12fb5ce7029f930b79Daniel Veillard
1754e1b26cfeba7f5fad4f8bd12fb5ce7029f930b79Daniel VeillardPyObject *
176f93a866079364a006189683eaa07f94c867389d1Daniel Veillardlibxml_xmlPythonCleanupParser(PyObject *self ATTRIBUTE_UNUSED,
177f93a866079364a006189683eaa07f94c867389d1Daniel Veillard                              PyObject *args ATTRIBUTE_UNUSED) {
178f93a866079364a006189683eaa07f94c867389d1Daniel Veillard
1798e2cc6f2b53f536692f3c8ad8112bb67e0a1a629William M. Brack    int ix;
1808e2cc6f2b53f536692f3c8ad8112bb67e0a1a629William M. Brack    long freed = -1;
181f93a866079364a006189683eaa07f94c867389d1Daniel Veillard
182f93a866079364a006189683eaa07f94c867389d1Daniel Veillard    if (libxmlMemoryDebug) {
183f93a866079364a006189683eaa07f94c867389d1Daniel Veillard        freed = xmlMemUsed();
184f93a866079364a006189683eaa07f94c867389d1Daniel Veillard    }
185f93a866079364a006189683eaa07f94c867389d1Daniel Veillard
186f93a866079364a006189683eaa07f94c867389d1Daniel Veillard    xmlCleanupParser();
1878e2cc6f2b53f536692f3c8ad8112bb67e0a1a629William M. Brack    /*
1888e2cc6f2b53f536692f3c8ad8112bb67e0a1a629William M. Brack     * Need to confirm whether we really want to do this (required for
1898e2cc6f2b53f536692f3c8ad8112bb67e0a1a629William M. Brack     * memcheck) in all cases...
1908e2cc6f2b53f536692f3c8ad8112bb67e0a1a629William M. Brack     */
1918e2cc6f2b53f536692f3c8ad8112bb67e0a1a629William M. Brack
1928e2cc6f2b53f536692f3c8ad8112bb67e0a1a629William M. Brack    if (libxml_xpathCallbacks != NULL) {	/* if ext funcs declared */
1938e2cc6f2b53f536692f3c8ad8112bb67e0a1a629William M. Brack	for (ix=0; ix<libxml_xpathCallbacksNb; ix++) {
1948e2cc6f2b53f536692f3c8ad8112bb67e0a1a629William M. Brack	    if ((*libxml_xpathCallbacks)[ix].name != NULL)
1958e2cc6f2b53f536692f3c8ad8112bb67e0a1a629William M. Brack	        xmlFree((*libxml_xpathCallbacks)[ix].name);
1968e2cc6f2b53f536692f3c8ad8112bb67e0a1a629William M. Brack	    if ((*libxml_xpathCallbacks)[ix].ns_uri != NULL)
1978e2cc6f2b53f536692f3c8ad8112bb67e0a1a629William M. Brack	        xmlFree((*libxml_xpathCallbacks)[ix].ns_uri);
1988e2cc6f2b53f536692f3c8ad8112bb67e0a1a629William M. Brack	}
1998e2cc6f2b53f536692f3c8ad8112bb67e0a1a629William M. Brack	libxml_xpathCallbacksNb = 0;
2008e2cc6f2b53f536692f3c8ad8112bb67e0a1a629William M. Brack        xmlFree(libxml_xpathCallbacks);
2018e2cc6f2b53f536692f3c8ad8112bb67e0a1a629William M. Brack	libxml_xpathCallbacks = NULL;
2028e2cc6f2b53f536692f3c8ad8112bb67e0a1a629William M. Brack    }
203f93a866079364a006189683eaa07f94c867389d1Daniel Veillard
204f93a866079364a006189683eaa07f94c867389d1Daniel Veillard    if (libxmlMemoryDebug) {
205f93a866079364a006189683eaa07f94c867389d1Daniel Veillard        freed -= xmlMemUsed();
206f93a866079364a006189683eaa07f94c867389d1Daniel Veillard	libxmlMemoryAllocatedBase -= freed;
207f93a866079364a006189683eaa07f94c867389d1Daniel Veillard	if (libxmlMemoryAllocatedBase < 0)
208f93a866079364a006189683eaa07f94c867389d1Daniel Veillard	    libxmlMemoryAllocatedBase = 0;
209f93a866079364a006189683eaa07f94c867389d1Daniel Veillard    }
210f93a866079364a006189683eaa07f94c867389d1Daniel Veillard
211f93a866079364a006189683eaa07f94c867389d1Daniel Veillard    Py_INCREF(Py_None);
212f93a866079364a006189683eaa07f94c867389d1Daniel Veillard    return(Py_None);
213f93a866079364a006189683eaa07f94c867389d1Daniel Veillard}
214f93a866079364a006189683eaa07f94c867389d1Daniel Veillard
215f93a866079364a006189683eaa07f94c867389d1Daniel VeillardPyObject *
216d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillardlibxml_xmlDumpMemory(ATTRIBUTE_UNUSED PyObject * self,
217d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard                     ATTRIBUTE_UNUSED PyObject * args)
218d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard{
2194e1b26cfeba7f5fad4f8bd12fb5ce7029f930b79Daniel Veillard
2204e1b26cfeba7f5fad4f8bd12fb5ce7029f930b79Daniel Veillard    if (libxmlMemoryDebug != 0)
221d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        xmlMemoryDump();
2224e1b26cfeba7f5fad4f8bd12fb5ce7029f930b79Daniel Veillard    Py_INCREF(Py_None);
223d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard    return (Py_None);
2244e1b26cfeba7f5fad4f8bd12fb5ce7029f930b79Daniel Veillard}
225d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard
226d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard/************************************************************************
227d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard *									*
228c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard *		Handling Python FILE I/O at the C level			*
229c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard *	The raw I/O attack diectly the File objects, while the		*
230c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard *	other routines address the ioWrapper instance instead		*
231c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard *									*
232c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard ************************************************************************/
233c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard
234c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard/**
235c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard * xmlPythonFileCloseUnref:
236c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard * @context:  the I/O context
237c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard *
238c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard * Close an I/O channel
239c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard */
240c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillardstatic int
241c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel VeillardxmlPythonFileCloseRaw (void * context) {
242c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard    PyObject *file, *ret;
243c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard
244c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard#ifdef DEBUG_FILES
245c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard    printf("xmlPythonFileCloseUnref\n");
246c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard#endif
247c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard    file = (PyObject *) context;
248c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard    if (file == NULL) return(-1);
249118aed78f360f51d182770e62b251ef324707aa2Daniel Veillard    ret = PyEval_CallMethod(file, (char *) "close", (char *) "()");
250c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard    if (ret != NULL) {
251c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard	Py_DECREF(ret);
252c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard    }
253c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard    Py_DECREF(file);
254c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard    return(0);
255c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard}
256c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard
257c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard/**
258c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard * xmlPythonFileReadRaw:
259c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard * @context:  the I/O context
260c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard * @buffer:  where to drop data
261c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard * @len:  number of bytes to write
262c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard *
263c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard * Read @len bytes to @buffer from the Python file in the I/O channel
264c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard *
265c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard * Returns the number of bytes read
266c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard */
267c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillardstatic int
268c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel VeillardxmlPythonFileReadRaw (void * context, char * buffer, int len) {
269c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard    PyObject *file;
270c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard    PyObject *ret;
271c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard    int lenread = -1;
272c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard    char *data;
273c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard
274c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard#ifdef DEBUG_FILES
275c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard    printf("xmlPythonFileReadRaw: %d\n", len);
276c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard#endif
277c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard    file = (PyObject *) context;
278c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard    if (file == NULL) return(-1);
279118aed78f360f51d182770e62b251ef324707aa2Daniel Veillard    ret = PyEval_CallMethod(file, (char *) "read", (char *) "(i)", len);
280c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard    if (ret == NULL) {
281c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard	printf("xmlPythonFileReadRaw: result is NULL\n");
282c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard	return(-1);
283c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard    } else if (PyString_Check(ret)) {
284c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard	lenread = PyString_Size(ret);
285c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard	data = PyString_AsString(ret);
286c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard	if (lenread > len)
287c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard	    memcpy(buffer, data, len);
288c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard	else
289c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard	    memcpy(buffer, data, lenread);
290c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard	Py_DECREF(ret);
291c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard    } else {
292c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard	printf("xmlPythonFileReadRaw: result is not a String\n");
293c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard	Py_DECREF(ret);
294c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard    }
295c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard    return(lenread);
296c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard}
297c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard
298c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard/**
299c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard * xmlPythonFileRead:
300c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard * @context:  the I/O context
301c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard * @buffer:  where to drop data
302c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard * @len:  number of bytes to write
303c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard *
304c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard * Read @len bytes to @buffer from the I/O channel.
305c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard *
306c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard * Returns the number of bytes read
307c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard */
308c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillardstatic int
309c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel VeillardxmlPythonFileRead (void * context, char * buffer, int len) {
310c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard    PyObject *file;
311c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard    PyObject *ret;
312c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard    int lenread = -1;
313c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard    char *data;
314c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard
315c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard#ifdef DEBUG_FILES
316c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard    printf("xmlPythonFileRead: %d\n", len);
317c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard#endif
318c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard    file = (PyObject *) context;
319c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard    if (file == NULL) return(-1);
320118aed78f360f51d182770e62b251ef324707aa2Daniel Veillard    ret = PyEval_CallMethod(file, (char *) "io_read", (char *) "(i)", len);
321c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard    if (ret == NULL) {
322c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard	printf("xmlPythonFileRead: result is NULL\n");
323c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard	return(-1);
324c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard    } else if (PyString_Check(ret)) {
325c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard	lenread = PyString_Size(ret);
326c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard	data = PyString_AsString(ret);
327c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard	if (lenread > len)
328c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard	    memcpy(buffer, data, len);
329c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard	else
330c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard	    memcpy(buffer, data, lenread);
331c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard	Py_DECREF(ret);
332c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard    } else {
333c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard	printf("xmlPythonFileRead: result is not a String\n");
334c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard	Py_DECREF(ret);
335c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard    }
336c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard    return(lenread);
337c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard}
338c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard
339c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard/**
340c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard * xmlFileWrite:
341c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard * @context:  the I/O context
342c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard * @buffer:  where to drop data
343c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard * @len:  number of bytes to write
344c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard *
345c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard * Write @len bytes from @buffer to the I/O channel.
346c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard *
347c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard * Returns the number of bytes written
348c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard */
349c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillardstatic int
350c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel VeillardxmlPythonFileWrite (void * context, const char * buffer, int len) {
351c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard    PyObject *file;
352c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard    PyObject *string;
3536cbd6c0738efb6c55d08f39c0731d46d678858faDaniel Veillard    PyObject *ret = NULL;
354c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard    int written = -1;
355c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard
356c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard#ifdef DEBUG_FILES
357c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard    printf("xmlPythonFileWrite: %d\n", len);
358c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard#endif
359c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard    file = (PyObject *) context;
360c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard    if (file == NULL) return(-1);
361c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard    string = PyString_FromStringAndSize(buffer, len);
362c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard    if (string == NULL) return(-1);
3636cbd6c0738efb6c55d08f39c0731d46d678858faDaniel Veillard    if (PyObject_HasAttrString(file, (char *) "io_write")) {
3646cbd6c0738efb6c55d08f39c0731d46d678858faDaniel Veillard        ret = PyEval_CallMethod(file, (char *) "io_write", (char *) "(O)",
3656cbd6c0738efb6c55d08f39c0731d46d678858faDaniel Veillard	                        string);
3666cbd6c0738efb6c55d08f39c0731d46d678858faDaniel Veillard    } else if (PyObject_HasAttrString(file, (char *) "write")) {
3676cbd6c0738efb6c55d08f39c0731d46d678858faDaniel Veillard        ret = PyEval_CallMethod(file, (char *) "write", (char *) "(O)",
3686cbd6c0738efb6c55d08f39c0731d46d678858faDaniel Veillard	                        string);
3696cbd6c0738efb6c55d08f39c0731d46d678858faDaniel Veillard    }
370c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard    Py_DECREF(string);
371c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard    if (ret == NULL) {
372c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard	printf("xmlPythonFileWrite: result is NULL\n");
373c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard	return(-1);
374c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard    } else if (PyInt_Check(ret)) {
375c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard	written = (int) PyInt_AsLong(ret);
376c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard	Py_DECREF(ret);
377c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard    } else if (ret == Py_None) {
378c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard	written = len;
379c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard	Py_DECREF(ret);
380c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard    } else {
381c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard	printf("xmlPythonFileWrite: result is not an Int nor None\n");
382c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard	Py_DECREF(ret);
383c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard    }
384c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard    return(written);
385c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard}
386c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard
387c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard/**
388c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard * xmlPythonFileClose:
389c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard * @context:  the I/O context
390c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard *
391c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard * Close an I/O channel
392c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard */
393c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillardstatic int
394c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel VeillardxmlPythonFileClose (void * context) {
3956cbd6c0738efb6c55d08f39c0731d46d678858faDaniel Veillard    PyObject *file, *ret = NULL;
396c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard
397c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard#ifdef DEBUG_FILES
398c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard    printf("xmlPythonFileClose\n");
399c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard#endif
400c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard    file = (PyObject *) context;
401c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard    if (file == NULL) return(-1);
4026cbd6c0738efb6c55d08f39c0731d46d678858faDaniel Veillard    if (PyObject_HasAttrString(file, (char *) "io_close")) {
4036cbd6c0738efb6c55d08f39c0731d46d678858faDaniel Veillard        ret = PyEval_CallMethod(file, (char *) "io_close", (char *) "()");
4046cbd6c0738efb6c55d08f39c0731d46d678858faDaniel Veillard    } else if (PyObject_HasAttrString(file, (char *) "flush")) {
4056cbd6c0738efb6c55d08f39c0731d46d678858faDaniel Veillard        ret = PyEval_CallMethod(file, (char *) "flush", (char *) "()");
4066cbd6c0738efb6c55d08f39c0731d46d678858faDaniel Veillard    }
407c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard    if (ret != NULL) {
408c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard	Py_DECREF(ret);
409c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard    }
410c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard    return(0);
411c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard}
412c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard
413a9cce9cd0d7aff3ec318b5d8d376da131b6aaad4Daniel Veillard#ifdef LIBXML_OUTPUT_ENABLED
414c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard/**
415c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard * xmlOutputBufferCreatePythonFile:
416c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard * @file:  a PyFile_Type
417c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard * @encoder:  the encoding converter or NULL
418c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard *
419c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard * Create a buffered output for the progressive saving to a PyFile_Type
420c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard * buffered C I/O
421c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard *
422c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard * Returns the new parser output or NULL
423c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard */
424118aed78f360f51d182770e62b251ef324707aa2Daniel Veillardstatic xmlOutputBufferPtr
425c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel VeillardxmlOutputBufferCreatePythonFile(PyObject *file,
426c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard	                        xmlCharEncodingHandlerPtr encoder) {
427c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard    xmlOutputBufferPtr ret;
428c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard
429c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard    if (file == NULL) return(NULL);
430c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard
431c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard    ret = xmlAllocOutputBuffer(encoder);
432c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard    if (ret != NULL) {
433c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard        ret->context = file;
434c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard	/* Py_INCREF(file); */
435c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard	ret->writecallback = xmlPythonFileWrite;
436c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard	ret->closecallback = xmlPythonFileClose;
437c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard    }
438c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard
439c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard    return(ret);
440c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard}
441c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard
442c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel VeillardPyObject *
443c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillardlibxml_xmlCreateOutputBuffer(ATTRIBUTE_UNUSED PyObject *self, PyObject *args) {
444c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard    PyObject *py_retval;
445c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard    PyObject *file;
446c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard    xmlChar  *encoding;
447c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard    xmlCharEncodingHandlerPtr handler = NULL;
448c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard    xmlOutputBufferPtr buffer;
449c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard
450c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard
451c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard    if (!PyArg_ParseTuple(args, (char *)"Oz:xmlOutputBufferCreate",
452c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard		&file, &encoding))
453c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard	return(NULL);
454c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard    if ((encoding != NULL) && (encoding[0] != 0)) {
455118aed78f360f51d182770e62b251ef324707aa2Daniel Veillard	handler = xmlFindCharEncodingHandler((const char *) encoding);
456c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard    }
457c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard    buffer = xmlOutputBufferCreatePythonFile(file, handler);
458c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard    if (buffer == NULL)
459c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard	printf("libxml_xmlCreateOutputBuffer: buffer == NULL\n");
460c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard    py_retval = libxml_xmlOutputBufferPtrWrap(buffer);
461c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard    return(py_retval);
462c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard}
4636cbd6c0738efb6c55d08f39c0731d46d678858faDaniel Veillard
4646cbd6c0738efb6c55d08f39c0731d46d678858faDaniel Veillard/**
4656cbd6c0738efb6c55d08f39c0731d46d678858faDaniel Veillard * libxml_outputBufferGetPythonFile:
4666cbd6c0738efb6c55d08f39c0731d46d678858faDaniel Veillard * @buffer:  the I/O buffer
4676cbd6c0738efb6c55d08f39c0731d46d678858faDaniel Veillard *
4686cbd6c0738efb6c55d08f39c0731d46d678858faDaniel Veillard * read the Python I/O from the CObject
4696cbd6c0738efb6c55d08f39c0731d46d678858faDaniel Veillard *
4706cbd6c0738efb6c55d08f39c0731d46d678858faDaniel Veillard * Returns the new parser output or NULL
4716cbd6c0738efb6c55d08f39c0731d46d678858faDaniel Veillard */
4726cbd6c0738efb6c55d08f39c0731d46d678858faDaniel Veillardstatic PyObject *
4736cbd6c0738efb6c55d08f39c0731d46d678858faDaniel Veillardlibxml_outputBufferGetPythonFile(ATTRIBUTE_UNUSED PyObject *self,
4746cbd6c0738efb6c55d08f39c0731d46d678858faDaniel Veillard                                    PyObject *args) {
4756cbd6c0738efb6c55d08f39c0731d46d678858faDaniel Veillard    PyObject *buffer;
4766cbd6c0738efb6c55d08f39c0731d46d678858faDaniel Veillard    PyObject *file;
4776cbd6c0738efb6c55d08f39c0731d46d678858faDaniel Veillard    xmlOutputBufferPtr obj;
4786cbd6c0738efb6c55d08f39c0731d46d678858faDaniel Veillard
4796cbd6c0738efb6c55d08f39c0731d46d678858faDaniel Veillard    if (!PyArg_ParseTuple(args, (char *)"O:outputBufferGetPythonFile",
4806cbd6c0738efb6c55d08f39c0731d46d678858faDaniel Veillard			  &buffer))
4816cbd6c0738efb6c55d08f39c0731d46d678858faDaniel Veillard	return(NULL);
4826cbd6c0738efb6c55d08f39c0731d46d678858faDaniel Veillard
4836cbd6c0738efb6c55d08f39c0731d46d678858faDaniel Veillard    obj = PyoutputBuffer_Get(buffer);
4846cbd6c0738efb6c55d08f39c0731d46d678858faDaniel Veillard    if (obj == NULL) {
4856cbd6c0738efb6c55d08f39c0731d46d678858faDaniel Veillard	fprintf(stderr,
4866cbd6c0738efb6c55d08f39c0731d46d678858faDaniel Veillard	        "outputBufferGetPythonFile: obj == NULL\n");
4876cbd6c0738efb6c55d08f39c0731d46d678858faDaniel Veillard	Py_INCREF(Py_None);
4886cbd6c0738efb6c55d08f39c0731d46d678858faDaniel Veillard	return(Py_None);
4896cbd6c0738efb6c55d08f39c0731d46d678858faDaniel Veillard    }
4906cbd6c0738efb6c55d08f39c0731d46d678858faDaniel Veillard    if (obj->closecallback != xmlPythonFileClose) {
4916cbd6c0738efb6c55d08f39c0731d46d678858faDaniel Veillard	fprintf(stderr,
4926cbd6c0738efb6c55d08f39c0731d46d678858faDaniel Veillard	        "outputBufferGetPythonFile: not a python file wrapper\n");
4936cbd6c0738efb6c55d08f39c0731d46d678858faDaniel Veillard	Py_INCREF(Py_None);
4946cbd6c0738efb6c55d08f39c0731d46d678858faDaniel Veillard	return(Py_None);
4956cbd6c0738efb6c55d08f39c0731d46d678858faDaniel Veillard    }
4966cbd6c0738efb6c55d08f39c0731d46d678858faDaniel Veillard    file = (PyObject *) obj->context;
4976cbd6c0738efb6c55d08f39c0731d46d678858faDaniel Veillard    if (file == NULL) {
4986cbd6c0738efb6c55d08f39c0731d46d678858faDaniel Veillard	Py_INCREF(Py_None);
4996cbd6c0738efb6c55d08f39c0731d46d678858faDaniel Veillard	return(Py_None);
5006cbd6c0738efb6c55d08f39c0731d46d678858faDaniel Veillard    }
5016cbd6c0738efb6c55d08f39c0731d46d678858faDaniel Veillard    Py_INCREF(file);
5026cbd6c0738efb6c55d08f39c0731d46d678858faDaniel Veillard    return(file);
5036cbd6c0738efb6c55d08f39c0731d46d678858faDaniel Veillard}
5046cbd6c0738efb6c55d08f39c0731d46d678858faDaniel Veillard
505d5e198ad454803c60b898451ff432f2fcf0e95ceDaniel Veillardstatic PyObject *
5066cbd6c0738efb6c55d08f39c0731d46d678858faDaniel Veillardlibxml_xmlOutputBufferClose(PyObject *self ATTRIBUTE_UNUSED, PyObject *args) {
5076cbd6c0738efb6c55d08f39c0731d46d678858faDaniel Veillard    PyObject *py_retval;
5086cbd6c0738efb6c55d08f39c0731d46d678858faDaniel Veillard    int c_retval;
5096cbd6c0738efb6c55d08f39c0731d46d678858faDaniel Veillard    xmlOutputBufferPtr out;
5106cbd6c0738efb6c55d08f39c0731d46d678858faDaniel Veillard    PyObject *pyobj_out;
5116cbd6c0738efb6c55d08f39c0731d46d678858faDaniel Veillard
5126cbd6c0738efb6c55d08f39c0731d46d678858faDaniel Veillard    if (!PyArg_ParseTuple(args, (char *)"O:xmlOutputBufferClose", &pyobj_out))
5136cbd6c0738efb6c55d08f39c0731d46d678858faDaniel Veillard        return(NULL);
5146cbd6c0738efb6c55d08f39c0731d46d678858faDaniel Veillard    out = (xmlOutputBufferPtr) PyoutputBuffer_Get(pyobj_out);
515263ec86a75f7b5ec2d37dbb89356bf7fca11cff3Daniel Veillard    /* Buffer may already have been destroyed elsewhere. This is harmless. */
516263ec86a75f7b5ec2d37dbb89356bf7fca11cff3Daniel Veillard    if (out == NULL) {
517263ec86a75f7b5ec2d37dbb89356bf7fca11cff3Daniel Veillard	Py_INCREF(Py_None);
518263ec86a75f7b5ec2d37dbb89356bf7fca11cff3Daniel Veillard	return(Py_None);
519263ec86a75f7b5ec2d37dbb89356bf7fca11cff3Daniel Veillard    }
5206cbd6c0738efb6c55d08f39c0731d46d678858faDaniel Veillard
5216cbd6c0738efb6c55d08f39c0731d46d678858faDaniel Veillard    c_retval = xmlOutputBufferClose(out);
5226cbd6c0738efb6c55d08f39c0731d46d678858faDaniel Veillard    py_retval = libxml_intWrap((int) c_retval);
5236cbd6c0738efb6c55d08f39c0731d46d678858faDaniel Veillard    return(py_retval);
5246cbd6c0738efb6c55d08f39c0731d46d678858faDaniel Veillard}
5256cbd6c0738efb6c55d08f39c0731d46d678858faDaniel Veillard
526d5e198ad454803c60b898451ff432f2fcf0e95ceDaniel Veillardstatic PyObject *
5276cbd6c0738efb6c55d08f39c0731d46d678858faDaniel Veillardlibxml_xmlOutputBufferFlush(PyObject *self ATTRIBUTE_UNUSED, PyObject *args) {
5286cbd6c0738efb6c55d08f39c0731d46d678858faDaniel Veillard    PyObject *py_retval;
5296cbd6c0738efb6c55d08f39c0731d46d678858faDaniel Veillard    int c_retval;
5306cbd6c0738efb6c55d08f39c0731d46d678858faDaniel Veillard    xmlOutputBufferPtr out;
5316cbd6c0738efb6c55d08f39c0731d46d678858faDaniel Veillard    PyObject *pyobj_out;
5326cbd6c0738efb6c55d08f39c0731d46d678858faDaniel Veillard
5336cbd6c0738efb6c55d08f39c0731d46d678858faDaniel Veillard    if (!PyArg_ParseTuple(args, (char *)"O:xmlOutputBufferFlush", &pyobj_out))
5346cbd6c0738efb6c55d08f39c0731d46d678858faDaniel Veillard        return(NULL);
5356cbd6c0738efb6c55d08f39c0731d46d678858faDaniel Veillard    out = (xmlOutputBufferPtr) PyoutputBuffer_Get(pyobj_out);
5366cbd6c0738efb6c55d08f39c0731d46d678858faDaniel Veillard
5376cbd6c0738efb6c55d08f39c0731d46d678858faDaniel Veillard    c_retval = xmlOutputBufferFlush(out);
5386cbd6c0738efb6c55d08f39c0731d46d678858faDaniel Veillard    py_retval = libxml_intWrap((int) c_retval);
5396cbd6c0738efb6c55d08f39c0731d46d678858faDaniel Veillard    return(py_retval);
5406cbd6c0738efb6c55d08f39c0731d46d678858faDaniel Veillard}
541263ec86a75f7b5ec2d37dbb89356bf7fca11cff3Daniel Veillard
542263ec86a75f7b5ec2d37dbb89356bf7fca11cff3Daniel Veillardstatic PyObject *
543263ec86a75f7b5ec2d37dbb89356bf7fca11cff3Daniel Veillardlibxml_xmlSaveFileTo(PyObject *self ATTRIBUTE_UNUSED, PyObject *args) {
544263ec86a75f7b5ec2d37dbb89356bf7fca11cff3Daniel Veillard    PyObject *py_retval;
545263ec86a75f7b5ec2d37dbb89356bf7fca11cff3Daniel Veillard    int c_retval;
546263ec86a75f7b5ec2d37dbb89356bf7fca11cff3Daniel Veillard    xmlOutputBufferPtr buf;
547263ec86a75f7b5ec2d37dbb89356bf7fca11cff3Daniel Veillard    PyObject *pyobj_buf;
548263ec86a75f7b5ec2d37dbb89356bf7fca11cff3Daniel Veillard    xmlDocPtr cur;
549263ec86a75f7b5ec2d37dbb89356bf7fca11cff3Daniel Veillard    PyObject *pyobj_cur;
550263ec86a75f7b5ec2d37dbb89356bf7fca11cff3Daniel Veillard    char * encoding;
551263ec86a75f7b5ec2d37dbb89356bf7fca11cff3Daniel Veillard
552263ec86a75f7b5ec2d37dbb89356bf7fca11cff3Daniel Veillard    if (!PyArg_ParseTuple(args, (char *)"OOz:xmlSaveFileTo", &pyobj_buf, &pyobj_cur, &encoding))
553263ec86a75f7b5ec2d37dbb89356bf7fca11cff3Daniel Veillard        return(NULL);
554263ec86a75f7b5ec2d37dbb89356bf7fca11cff3Daniel Veillard    buf = (xmlOutputBufferPtr) PyoutputBuffer_Get(pyobj_buf);
555263ec86a75f7b5ec2d37dbb89356bf7fca11cff3Daniel Veillard    cur = (xmlDocPtr) PyxmlNode_Get(pyobj_cur);
556263ec86a75f7b5ec2d37dbb89356bf7fca11cff3Daniel Veillard
557263ec86a75f7b5ec2d37dbb89356bf7fca11cff3Daniel Veillard    c_retval = xmlSaveFileTo(buf, cur, encoding);
558263ec86a75f7b5ec2d37dbb89356bf7fca11cff3Daniel Veillard	/* xmlSaveTo() freed the memory pointed to by buf, so record that in the
559263ec86a75f7b5ec2d37dbb89356bf7fca11cff3Daniel Veillard	 * Python object. */
560263ec86a75f7b5ec2d37dbb89356bf7fca11cff3Daniel Veillard    ((PyoutputBuffer_Object *)(pyobj_buf))->obj = NULL;
561263ec86a75f7b5ec2d37dbb89356bf7fca11cff3Daniel Veillard    py_retval = libxml_intWrap((int) c_retval);
562263ec86a75f7b5ec2d37dbb89356bf7fca11cff3Daniel Veillard    return(py_retval);
563263ec86a75f7b5ec2d37dbb89356bf7fca11cff3Daniel Veillard}
564263ec86a75f7b5ec2d37dbb89356bf7fca11cff3Daniel Veillard
565263ec86a75f7b5ec2d37dbb89356bf7fca11cff3Daniel Veillardstatic PyObject *
566263ec86a75f7b5ec2d37dbb89356bf7fca11cff3Daniel Veillardlibxml_xmlSaveFormatFileTo(PyObject *self ATTRIBUTE_UNUSED, PyObject *args) {
567263ec86a75f7b5ec2d37dbb89356bf7fca11cff3Daniel Veillard    PyObject *py_retval;
568263ec86a75f7b5ec2d37dbb89356bf7fca11cff3Daniel Veillard    int c_retval;
569263ec86a75f7b5ec2d37dbb89356bf7fca11cff3Daniel Veillard    xmlOutputBufferPtr buf;
570263ec86a75f7b5ec2d37dbb89356bf7fca11cff3Daniel Veillard    PyObject *pyobj_buf;
571263ec86a75f7b5ec2d37dbb89356bf7fca11cff3Daniel Veillard    xmlDocPtr cur;
572263ec86a75f7b5ec2d37dbb89356bf7fca11cff3Daniel Veillard    PyObject *pyobj_cur;
573263ec86a75f7b5ec2d37dbb89356bf7fca11cff3Daniel Veillard    char * encoding;
574263ec86a75f7b5ec2d37dbb89356bf7fca11cff3Daniel Veillard    int format;
575263ec86a75f7b5ec2d37dbb89356bf7fca11cff3Daniel Veillard
576263ec86a75f7b5ec2d37dbb89356bf7fca11cff3Daniel Veillard    if (!PyArg_ParseTuple(args, (char *)"OOzi:xmlSaveFormatFileTo", &pyobj_buf, &pyobj_cur, &encoding, &format))
577263ec86a75f7b5ec2d37dbb89356bf7fca11cff3Daniel Veillard        return(NULL);
578263ec86a75f7b5ec2d37dbb89356bf7fca11cff3Daniel Veillard    buf = (xmlOutputBufferPtr) PyoutputBuffer_Get(pyobj_buf);
579263ec86a75f7b5ec2d37dbb89356bf7fca11cff3Daniel Veillard    cur = (xmlDocPtr) PyxmlNode_Get(pyobj_cur);
580263ec86a75f7b5ec2d37dbb89356bf7fca11cff3Daniel Veillard
581263ec86a75f7b5ec2d37dbb89356bf7fca11cff3Daniel Veillard    c_retval = xmlSaveFormatFileTo(buf, cur, encoding, format);
582263ec86a75f7b5ec2d37dbb89356bf7fca11cff3Daniel Veillard	/* xmlSaveFormatFileTo() freed the memory pointed to by buf, so record that
583263ec86a75f7b5ec2d37dbb89356bf7fca11cff3Daniel Veillard	 * in the Python object */
584263ec86a75f7b5ec2d37dbb89356bf7fca11cff3Daniel Veillard	((PyoutputBuffer_Object *)(pyobj_buf))->obj = NULL;
585263ec86a75f7b5ec2d37dbb89356bf7fca11cff3Daniel Veillard    py_retval = libxml_intWrap((int) c_retval);
586263ec86a75f7b5ec2d37dbb89356bf7fca11cff3Daniel Veillard    return(py_retval);
587263ec86a75f7b5ec2d37dbb89356bf7fca11cff3Daniel Veillard}
588a9cce9cd0d7aff3ec318b5d8d376da131b6aaad4Daniel Veillard#endif /* LIBXML_OUTPUT_ENABLED */
589c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard
590c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard
591c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard/**
592c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard * xmlParserInputBufferCreatePythonFile:
593c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard * @file:  a PyFile_Type
594c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard * @encoder:  the encoding converter or NULL
595c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard *
596c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard * Create a buffered output for the progressive saving to a PyFile_Type
597c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard * buffered C I/O
598c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard *
599c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard * Returns the new parser output or NULL
600c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard */
601118aed78f360f51d182770e62b251ef324707aa2Daniel Veillardstatic xmlParserInputBufferPtr
602c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel VeillardxmlParserInputBufferCreatePythonFile(PyObject *file,
603c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard	                        xmlCharEncoding encoding) {
604c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard    xmlParserInputBufferPtr ret;
605c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard
606c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard    if (file == NULL) return(NULL);
607c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard
608c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard    ret = xmlAllocParserInputBuffer(encoding);
609c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard    if (ret != NULL) {
610c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard        ret->context = file;
611c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard	/* Py_INCREF(file); */
612c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard	ret->readcallback = xmlPythonFileRead;
613c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard	ret->closecallback = xmlPythonFileClose;
614c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard    }
615c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard
616c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard    return(ret);
617c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard}
618c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard
619c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel VeillardPyObject *
620c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillardlibxml_xmlCreateInputBuffer(ATTRIBUTE_UNUSED PyObject *self, PyObject *args) {
621c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard    PyObject *py_retval;
622c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard    PyObject *file;
623c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard    xmlChar  *encoding;
624c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard    xmlCharEncoding enc = XML_CHAR_ENCODING_NONE;
625c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard    xmlParserInputBufferPtr buffer;
626c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard
627c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard
628c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard    if (!PyArg_ParseTuple(args, (char *)"Oz:xmlParserInputBufferCreate",
629c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard		&file, &encoding))
630c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard	return(NULL);
631c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard    if ((encoding != NULL) && (encoding[0] != 0)) {
632118aed78f360f51d182770e62b251ef324707aa2Daniel Veillard	enc = xmlParseCharEncoding((const char *) encoding);
633c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard    }
634c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard    buffer = xmlParserInputBufferCreatePythonFile(file, enc);
635c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard    if (buffer == NULL)
636c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard	printf("libxml_xmlParserInputBufferCreate: buffer == NULL\n");
637c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard    py_retval = libxml_xmlParserInputBufferPtrWrap(buffer);
638c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard    return(py_retval);
639c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard}
640c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard
641c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard/************************************************************************
642c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard *									*
643c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard *		Providing the resolver at the Python level		*
644c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard *									*
645c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard ************************************************************************/
646c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard
647c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillardstatic xmlExternalEntityLoader defaultExternalEntityLoader = NULL;
648c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillardstatic PyObject *pythonExternalEntityLoaderObjext;
649c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard
650c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillardstatic xmlParserInputPtr
651c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel VeillardpythonExternalEntityLoader(const char *URL, const char *ID,
652c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard			   xmlParserCtxtPtr ctxt) {
653c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard    xmlParserInputPtr result = NULL;
654c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard    if (pythonExternalEntityLoaderObjext != NULL) {
655c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard	PyObject *ret;
656c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard	PyObject *ctxtobj;
657c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard
658c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard	ctxtobj = libxml_xmlParserCtxtPtrWrap(ctxt);
659c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard#ifdef DEBUG_LOADER
660c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard	printf("pythonExternalEntityLoader: ready to call\n");
661c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard#endif
662c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard
663c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard	ret = PyObject_CallFunction(pythonExternalEntityLoaderObjext,
664118aed78f360f51d182770e62b251ef324707aa2Daniel Veillard		      (char *) "(ssO)", URL, ID, ctxtobj);
665e4a07e7b77b191d61291d44dffa19b65387e04e4Daniel Veillard	Py_XDECREF(ctxtobj);
666c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard#ifdef DEBUG_LOADER
667c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard	printf("pythonExternalEntityLoader: result ");
668a9016c492788eb4792c42b52df0c72b46136787dAlexey Neyman	PyObject_Print(ret, stdout, 0);
669c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard	printf("\n");
670c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard#endif
671c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard
672c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard	if (ret != NULL) {
673118aed78f360f51d182770e62b251ef324707aa2Daniel Veillard	    if (PyObject_HasAttrString(ret, (char *) "read")) {
674c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard		xmlParserInputBufferPtr buf;
675c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard
676c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard		buf = xmlAllocParserInputBuffer(XML_CHAR_ENCODING_NONE);
677c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard		if (buf != NULL) {
678c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard		    buf->context = ret;
679c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard		    buf->readcallback = xmlPythonFileReadRaw;
680c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard		    buf->closecallback = xmlPythonFileCloseRaw;
681c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard		    result = xmlNewIOInputStream(ctxt, buf,
682c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard			                         XML_CHAR_ENCODING_NONE);
683c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard		}
6844ea89f04ccd58de6cc4b83195252d0becba1fe69Daniel Veillard#if 0
685c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard	    } else {
6864ea89f04ccd58de6cc4b83195252d0becba1fe69Daniel Veillard		if (URL != NULL)
6874ea89f04ccd58de6cc4b83195252d0becba1fe69Daniel Veillard		    printf("pythonExternalEntityLoader: can't read %s\n",
6884ea89f04ccd58de6cc4b83195252d0becba1fe69Daniel Veillard		           URL);
6894ea89f04ccd58de6cc4b83195252d0becba1fe69Daniel Veillard#endif
690c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard	    }
691c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard	    if (result == NULL) {
692c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard		Py_DECREF(ret);
693c64b8e984c13a0d989dea436c13128b289a4d4d6Daniel Veillard	    } else if (URL != NULL) {
694c193956ee1c3b229556301cf09f6ff1b6eb9cb70William M. Brack		result->filename = (char *) xmlStrdup((const xmlChar *)URL);
695c64b8e984c13a0d989dea436c13128b289a4d4d6Daniel Veillard		result->directory = xmlParserGetDirectory((const char *) URL);
696c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard	    }
697c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard	}
698c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard    }
699c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard    if ((result == NULL) && (defaultExternalEntityLoader != NULL)) {
700c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard	result = defaultExternalEntityLoader(URL, ID, ctxt);
701c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard    }
702c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard    return(result);
703c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard}
704c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard
705c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel VeillardPyObject *
706c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillardlibxml_xmlSetEntityLoader(ATTRIBUTE_UNUSED PyObject *self, PyObject *args) {
707c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard    PyObject *py_retval;
708c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard    PyObject *loader;
709c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard
710c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard    if (!PyArg_ParseTuple(args, (char *)"O:libxml_xmlSetEntityLoader",
711c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard		&loader))
712c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard	return(NULL);
713c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard
714a9016c492788eb4792c42b52df0c72b46136787dAlexey Neyman    if (!PyCallable_Check(loader)) {
715a9016c492788eb4792c42b52df0c72b46136787dAlexey Neyman	PyErr_SetString(PyExc_ValueError, "entity loader is not callable");
716a9016c492788eb4792c42b52df0c72b46136787dAlexey Neyman	return(NULL);
717a9016c492788eb4792c42b52df0c72b46136787dAlexey Neyman    }
718a9016c492788eb4792c42b52df0c72b46136787dAlexey Neyman
719c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard#ifdef DEBUG_LOADER
720c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard    printf("libxml_xmlSetEntityLoader\n");
721c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard#endif
722c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard    if (defaultExternalEntityLoader == NULL)
723c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard	defaultExternalEntityLoader = xmlGetExternalEntityLoader();
724c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard
725a9016c492788eb4792c42b52df0c72b46136787dAlexey Neyman    Py_XDECREF(pythonExternalEntityLoaderObjext);
726c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard    pythonExternalEntityLoaderObjext = loader;
727a9016c492788eb4792c42b52df0c72b46136787dAlexey Neyman    Py_XINCREF(pythonExternalEntityLoaderObjext);
728c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard    xmlSetExternalEntityLoader(pythonExternalEntityLoader);
729c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard
730c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard    py_retval = PyInt_FromLong(0);
731c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard    return(py_retval);
732c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard}
733c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard
73448da90bc4a3809728d08ee9ee8da21d044fbca82Alexey Neyman/************************************************************************
73548da90bc4a3809728d08ee9ee8da21d044fbca82Alexey Neyman *									*
73648da90bc4a3809728d08ee9ee8da21d044fbca82Alexey Neyman *		Input callback registration				*
73748da90bc4a3809728d08ee9ee8da21d044fbca82Alexey Neyman *									*
73848da90bc4a3809728d08ee9ee8da21d044fbca82Alexey Neyman ************************************************************************/
73948da90bc4a3809728d08ee9ee8da21d044fbca82Alexey Neymanstatic PyObject *pythonInputOpenCallbackObject;
74048da90bc4a3809728d08ee9ee8da21d044fbca82Alexey Neymanstatic int pythonInputCallbackID = -1;
74148da90bc4a3809728d08ee9ee8da21d044fbca82Alexey Neyman
74248da90bc4a3809728d08ee9ee8da21d044fbca82Alexey Neymanstatic int
74348da90bc4a3809728d08ee9ee8da21d044fbca82Alexey NeymanpythonInputMatchCallback(ATTRIBUTE_UNUSED const char *URI)
74448da90bc4a3809728d08ee9ee8da21d044fbca82Alexey Neyman{
74548da90bc4a3809728d08ee9ee8da21d044fbca82Alexey Neyman    /* Always return success, real decision whether URI is supported will be
74648da90bc4a3809728d08ee9ee8da21d044fbca82Alexey Neyman     * made in open callback.  */
74748da90bc4a3809728d08ee9ee8da21d044fbca82Alexey Neyman    return 1;
74848da90bc4a3809728d08ee9ee8da21d044fbca82Alexey Neyman}
74948da90bc4a3809728d08ee9ee8da21d044fbca82Alexey Neyman
75048da90bc4a3809728d08ee9ee8da21d044fbca82Alexey Neymanstatic void *
75148da90bc4a3809728d08ee9ee8da21d044fbca82Alexey NeymanpythonInputOpenCallback(const char *URI)
75248da90bc4a3809728d08ee9ee8da21d044fbca82Alexey Neyman{
75348da90bc4a3809728d08ee9ee8da21d044fbca82Alexey Neyman    PyObject *ret;
75448da90bc4a3809728d08ee9ee8da21d044fbca82Alexey Neyman
75548da90bc4a3809728d08ee9ee8da21d044fbca82Alexey Neyman    ret = PyObject_CallFunction(pythonInputOpenCallbackObject,
75648da90bc4a3809728d08ee9ee8da21d044fbca82Alexey Neyman	    (char *)"s", URI);
75748da90bc4a3809728d08ee9ee8da21d044fbca82Alexey Neyman    if (ret == Py_None) {
75848da90bc4a3809728d08ee9ee8da21d044fbca82Alexey Neyman	Py_DECREF(Py_None);
75948da90bc4a3809728d08ee9ee8da21d044fbca82Alexey Neyman	return NULL;
76048da90bc4a3809728d08ee9ee8da21d044fbca82Alexey Neyman    }
76148da90bc4a3809728d08ee9ee8da21d044fbca82Alexey Neyman    return ret;
76248da90bc4a3809728d08ee9ee8da21d044fbca82Alexey Neyman}
76348da90bc4a3809728d08ee9ee8da21d044fbca82Alexey Neyman
76448da90bc4a3809728d08ee9ee8da21d044fbca82Alexey NeymanPyObject *
76548da90bc4a3809728d08ee9ee8da21d044fbca82Alexey Neymanlibxml_xmlRegisterInputCallback(ATTRIBUTE_UNUSED PyObject *self,
76648da90bc4a3809728d08ee9ee8da21d044fbca82Alexey Neyman                                PyObject *args) {
76748da90bc4a3809728d08ee9ee8da21d044fbca82Alexey Neyman    PyObject *cb;
76848da90bc4a3809728d08ee9ee8da21d044fbca82Alexey Neyman
76948da90bc4a3809728d08ee9ee8da21d044fbca82Alexey Neyman    if (!PyArg_ParseTuple(args,
77048da90bc4a3809728d08ee9ee8da21d044fbca82Alexey Neyman		(const char *)"O:libxml_xmlRegisterInputCallback", &cb))
77148da90bc4a3809728d08ee9ee8da21d044fbca82Alexey Neyman	return(NULL);
77248da90bc4a3809728d08ee9ee8da21d044fbca82Alexey Neyman
77348da90bc4a3809728d08ee9ee8da21d044fbca82Alexey Neyman    if (!PyCallable_Check(cb)) {
77448da90bc4a3809728d08ee9ee8da21d044fbca82Alexey Neyman	PyErr_SetString(PyExc_ValueError, "input callback is not callable");
77548da90bc4a3809728d08ee9ee8da21d044fbca82Alexey Neyman	return(NULL);
77648da90bc4a3809728d08ee9ee8da21d044fbca82Alexey Neyman    }
77748da90bc4a3809728d08ee9ee8da21d044fbca82Alexey Neyman
77848da90bc4a3809728d08ee9ee8da21d044fbca82Alexey Neyman    /* Python module registers a single callback and manages the list of
77948da90bc4a3809728d08ee9ee8da21d044fbca82Alexey Neyman     * all callbacks internally. This is necessitated by xmlInputMatchCallback
78048da90bc4a3809728d08ee9ee8da21d044fbca82Alexey Neyman     * API, which does not allow for passing of data objects to discriminate
78148da90bc4a3809728d08ee9ee8da21d044fbca82Alexey Neyman     * different Python methods.  */
78248da90bc4a3809728d08ee9ee8da21d044fbca82Alexey Neyman    if (pythonInputCallbackID == -1) {
78348da90bc4a3809728d08ee9ee8da21d044fbca82Alexey Neyman	pythonInputCallbackID = xmlRegisterInputCallbacks(
78448da90bc4a3809728d08ee9ee8da21d044fbca82Alexey Neyman		pythonInputMatchCallback, pythonInputOpenCallback,
78548da90bc4a3809728d08ee9ee8da21d044fbca82Alexey Neyman		xmlPythonFileReadRaw, xmlPythonFileCloseRaw);
78648da90bc4a3809728d08ee9ee8da21d044fbca82Alexey Neyman	if (pythonInputCallbackID == -1)
78748da90bc4a3809728d08ee9ee8da21d044fbca82Alexey Neyman	    return PyErr_NoMemory();
78848da90bc4a3809728d08ee9ee8da21d044fbca82Alexey Neyman	pythonInputOpenCallbackObject = cb;
78948da90bc4a3809728d08ee9ee8da21d044fbca82Alexey Neyman	Py_INCREF(pythonInputOpenCallbackObject);
79048da90bc4a3809728d08ee9ee8da21d044fbca82Alexey Neyman    }
79148da90bc4a3809728d08ee9ee8da21d044fbca82Alexey Neyman
79248da90bc4a3809728d08ee9ee8da21d044fbca82Alexey Neyman    Py_INCREF(Py_None);
79348da90bc4a3809728d08ee9ee8da21d044fbca82Alexey Neyman    return(Py_None);
79448da90bc4a3809728d08ee9ee8da21d044fbca82Alexey Neyman}
79548da90bc4a3809728d08ee9ee8da21d044fbca82Alexey Neyman
79648da90bc4a3809728d08ee9ee8da21d044fbca82Alexey NeymanPyObject *
79748da90bc4a3809728d08ee9ee8da21d044fbca82Alexey Neymanlibxml_xmlUnregisterInputCallback(ATTRIBUTE_UNUSED PyObject *self,
79848da90bc4a3809728d08ee9ee8da21d044fbca82Alexey Neyman                                ATTRIBUTE_UNUSED PyObject *args) {
79948da90bc4a3809728d08ee9ee8da21d044fbca82Alexey Neyman    int ret;
80048da90bc4a3809728d08ee9ee8da21d044fbca82Alexey Neyman
80148da90bc4a3809728d08ee9ee8da21d044fbca82Alexey Neyman    ret = xmlPopInputCallbacks();
80248da90bc4a3809728d08ee9ee8da21d044fbca82Alexey Neyman    if (pythonInputCallbackID != -1) {
80348da90bc4a3809728d08ee9ee8da21d044fbca82Alexey Neyman	/* Assert that the right input callback was popped. libxml's API does not
80448da90bc4a3809728d08ee9ee8da21d044fbca82Alexey Neyman	 * allow removal by ID, so all that could be done is an assert.  */
80548da90bc4a3809728d08ee9ee8da21d044fbca82Alexey Neyman	if (pythonInputCallbackID == ret) {
80648da90bc4a3809728d08ee9ee8da21d044fbca82Alexey Neyman	    pythonInputCallbackID = -1;
80748da90bc4a3809728d08ee9ee8da21d044fbca82Alexey Neyman	    Py_DECREF(pythonInputOpenCallbackObject);
80848da90bc4a3809728d08ee9ee8da21d044fbca82Alexey Neyman	    pythonInputOpenCallbackObject = NULL;
80948da90bc4a3809728d08ee9ee8da21d044fbca82Alexey Neyman	} else {
81048da90bc4a3809728d08ee9ee8da21d044fbca82Alexey Neyman	    PyErr_SetString(PyExc_AssertionError, "popped non-python input callback");
81148da90bc4a3809728d08ee9ee8da21d044fbca82Alexey Neyman	    return(NULL);
81248da90bc4a3809728d08ee9ee8da21d044fbca82Alexey Neyman	}
81348da90bc4a3809728d08ee9ee8da21d044fbca82Alexey Neyman    } else if (ret == -1) {
81448da90bc4a3809728d08ee9ee8da21d044fbca82Alexey Neyman	/* No more callbacks to pop */
81548da90bc4a3809728d08ee9ee8da21d044fbca82Alexey Neyman	PyErr_SetString(PyExc_IndexError, "no input callbacks to pop");
81648da90bc4a3809728d08ee9ee8da21d044fbca82Alexey Neyman	return(NULL);
81748da90bc4a3809728d08ee9ee8da21d044fbca82Alexey Neyman    }
81848da90bc4a3809728d08ee9ee8da21d044fbca82Alexey Neyman
81948da90bc4a3809728d08ee9ee8da21d044fbca82Alexey Neyman    Py_INCREF(Py_None);
82048da90bc4a3809728d08ee9ee8da21d044fbca82Alexey Neyman    return(Py_None);
82148da90bc4a3809728d08ee9ee8da21d044fbca82Alexey Neyman}
822c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard
823c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard/************************************************************************
824c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard *									*
8253ce5257b293ed75d8feb18ed7ab18ea2b52510bdDaniel Veillard *		Handling SAX/xmllib/sgmlop callback interfaces		*
826d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard *									*
827d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard ************************************************************************/
8281971ee2698cb84c7699c96d3302f00e20d42c0d3Daniel Veillard
82933caa0b8307eccf22010400747830b1967edb292Daniel Veillardstatic void
83033caa0b8307eccf22010400747830b1967edb292Daniel VeillardpythonStartElement(void *user_data, const xmlChar * name,
83133caa0b8307eccf22010400747830b1967edb292Daniel Veillard                   const xmlChar ** attrs)
83233caa0b8307eccf22010400747830b1967edb292Daniel Veillard{
83333caa0b8307eccf22010400747830b1967edb292Daniel Veillard    int i;
83433caa0b8307eccf22010400747830b1967edb292Daniel Veillard    PyObject *handler;
83533caa0b8307eccf22010400747830b1967edb292Daniel Veillard    PyObject *dict;
83633caa0b8307eccf22010400747830b1967edb292Daniel Veillard    PyObject *attrname;
83733caa0b8307eccf22010400747830b1967edb292Daniel Veillard    PyObject *attrvalue;
838d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard    PyObject *result = NULL;
83933caa0b8307eccf22010400747830b1967edb292Daniel Veillard    int type = 0;
84033caa0b8307eccf22010400747830b1967edb292Daniel Veillard
841797a565a2f6a2c0a8480670174e9eaef30d271a4Daniel Veillard#ifdef DEBUG_SAX
842797a565a2f6a2c0a8480670174e9eaef30d271a4Daniel Veillard    printf("pythonStartElement(%s) called\n", name);
843797a565a2f6a2c0a8480670174e9eaef30d271a4Daniel Veillard#endif
84433caa0b8307eccf22010400747830b1967edb292Daniel Veillard    handler = (PyObject *) user_data;
845d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard    if (PyObject_HasAttrString(handler, (char *) "startElement"))
84633caa0b8307eccf22010400747830b1967edb292Daniel Veillard        type = 1;
847d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard    else if (PyObject_HasAttrString(handler, (char *) "start"))
84833caa0b8307eccf22010400747830b1967edb292Daniel Veillard        type = 2;
84933caa0b8307eccf22010400747830b1967edb292Daniel Veillard    if (type != 0) {
85033caa0b8307eccf22010400747830b1967edb292Daniel Veillard        /*
85133caa0b8307eccf22010400747830b1967edb292Daniel Veillard         * the xmllib interface always generate a dictionnary,
85233caa0b8307eccf22010400747830b1967edb292Daniel Veillard         * possibly empty
85333caa0b8307eccf22010400747830b1967edb292Daniel Veillard         */
85433caa0b8307eccf22010400747830b1967edb292Daniel Veillard        if ((attrs == NULL) && (type == 1)) {
85533caa0b8307eccf22010400747830b1967edb292Daniel Veillard            Py_XINCREF(Py_None);
85633caa0b8307eccf22010400747830b1967edb292Daniel Veillard            dict = Py_None;
857d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        } else if (attrs == NULL) {
858d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            dict = PyDict_New();
85933caa0b8307eccf22010400747830b1967edb292Daniel Veillard        } else {
86033caa0b8307eccf22010400747830b1967edb292Daniel Veillard            dict = PyDict_New();
86133caa0b8307eccf22010400747830b1967edb292Daniel Veillard            for (i = 0; attrs[i] != NULL; i++) {
862d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard                attrname = PyString_FromString((char *) attrs[i]);
86333caa0b8307eccf22010400747830b1967edb292Daniel Veillard                i++;
86433caa0b8307eccf22010400747830b1967edb292Daniel Veillard                if (attrs[i] != NULL) {
865d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard                    attrvalue = PyString_FromString((char *) attrs[i]);
86633caa0b8307eccf22010400747830b1967edb292Daniel Veillard                } else {
86733caa0b8307eccf22010400747830b1967edb292Daniel Veillard                    Py_XINCREF(Py_None);
86833caa0b8307eccf22010400747830b1967edb292Daniel Veillard                    attrvalue = Py_None;
86933caa0b8307eccf22010400747830b1967edb292Daniel Veillard                }
87033caa0b8307eccf22010400747830b1967edb292Daniel Veillard                PyDict_SetItem(dict, attrname, attrvalue);
871a3d230513c3f28dc475ee09ffd6787762da07d56Daniel Veillard		Py_DECREF(attrname);
872a3d230513c3f28dc475ee09ffd6787762da07d56Daniel Veillard		Py_DECREF(attrvalue);
87333caa0b8307eccf22010400747830b1967edb292Daniel Veillard            }
87433caa0b8307eccf22010400747830b1967edb292Daniel Veillard        }
87533caa0b8307eccf22010400747830b1967edb292Daniel Veillard
87633caa0b8307eccf22010400747830b1967edb292Daniel Veillard        if (type == 1)
877d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            result = PyObject_CallMethod(handler, (char *) "startElement",
878d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard                                         (char *) "sO", name, dict);
87933caa0b8307eccf22010400747830b1967edb292Daniel Veillard        else if (type == 2)
880d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            result = PyObject_CallMethod(handler, (char *) "start",
881d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard                                         (char *) "sO", name, dict);
882d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        if (PyErr_Occurred())
883d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            PyErr_Print();
88433caa0b8307eccf22010400747830b1967edb292Daniel Veillard        Py_XDECREF(dict);
88533caa0b8307eccf22010400747830b1967edb292Daniel Veillard        Py_XDECREF(result);
88633caa0b8307eccf22010400747830b1967edb292Daniel Veillard    }
88733caa0b8307eccf22010400747830b1967edb292Daniel Veillard}
88833caa0b8307eccf22010400747830b1967edb292Daniel Veillard
88933caa0b8307eccf22010400747830b1967edb292Daniel Veillardstatic void
89033caa0b8307eccf22010400747830b1967edb292Daniel VeillardpythonStartDocument(void *user_data)
89133caa0b8307eccf22010400747830b1967edb292Daniel Veillard{
89233caa0b8307eccf22010400747830b1967edb292Daniel Veillard    PyObject *handler;
89333caa0b8307eccf22010400747830b1967edb292Daniel Veillard    PyObject *result;
89433caa0b8307eccf22010400747830b1967edb292Daniel Veillard
895797a565a2f6a2c0a8480670174e9eaef30d271a4Daniel Veillard#ifdef DEBUG_SAX
896797a565a2f6a2c0a8480670174e9eaef30d271a4Daniel Veillard    printf("pythonStartDocument() called\n");
897797a565a2f6a2c0a8480670174e9eaef30d271a4Daniel Veillard#endif
89833caa0b8307eccf22010400747830b1967edb292Daniel Veillard    handler = (PyObject *) user_data;
899d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard    if (PyObject_HasAttrString(handler, (char *) "startDocument")) {
900d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        result =
901d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            PyObject_CallMethod(handler, (char *) "startDocument", NULL);
902d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        if (PyErr_Occurred())
903d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            PyErr_Print();
90433caa0b8307eccf22010400747830b1967edb292Daniel Veillard        Py_XDECREF(result);
90533caa0b8307eccf22010400747830b1967edb292Daniel Veillard    }
90633caa0b8307eccf22010400747830b1967edb292Daniel Veillard}
90733caa0b8307eccf22010400747830b1967edb292Daniel Veillard
90833caa0b8307eccf22010400747830b1967edb292Daniel Veillardstatic void
90933caa0b8307eccf22010400747830b1967edb292Daniel VeillardpythonEndDocument(void *user_data)
91033caa0b8307eccf22010400747830b1967edb292Daniel Veillard{
91133caa0b8307eccf22010400747830b1967edb292Daniel Veillard    PyObject *handler;
91233caa0b8307eccf22010400747830b1967edb292Daniel Veillard    PyObject *result;
91333caa0b8307eccf22010400747830b1967edb292Daniel Veillard
914797a565a2f6a2c0a8480670174e9eaef30d271a4Daniel Veillard#ifdef DEBUG_SAX
915797a565a2f6a2c0a8480670174e9eaef30d271a4Daniel Veillard    printf("pythonEndDocument() called\n");
916797a565a2f6a2c0a8480670174e9eaef30d271a4Daniel Veillard#endif
91733caa0b8307eccf22010400747830b1967edb292Daniel Veillard    handler = (PyObject *) user_data;
918d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard    if (PyObject_HasAttrString(handler, (char *) "endDocument")) {
919d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        result =
920d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            PyObject_CallMethod(handler, (char *) "endDocument", NULL);
921d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        if (PyErr_Occurred())
922d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            PyErr_Print();
92333caa0b8307eccf22010400747830b1967edb292Daniel Veillard        Py_XDECREF(result);
92433caa0b8307eccf22010400747830b1967edb292Daniel Veillard    }
92533caa0b8307eccf22010400747830b1967edb292Daniel Veillard    /*
92633caa0b8307eccf22010400747830b1967edb292Daniel Veillard     * The reference to the handler is released there
92733caa0b8307eccf22010400747830b1967edb292Daniel Veillard     */
92833caa0b8307eccf22010400747830b1967edb292Daniel Veillard    Py_XDECREF(handler);
92933caa0b8307eccf22010400747830b1967edb292Daniel Veillard}
93033caa0b8307eccf22010400747830b1967edb292Daniel Veillard
93133caa0b8307eccf22010400747830b1967edb292Daniel Veillardstatic void
93233caa0b8307eccf22010400747830b1967edb292Daniel VeillardpythonEndElement(void *user_data, const xmlChar * name)
93333caa0b8307eccf22010400747830b1967edb292Daniel Veillard{
93433caa0b8307eccf22010400747830b1967edb292Daniel Veillard    PyObject *handler;
93533caa0b8307eccf22010400747830b1967edb292Daniel Veillard    PyObject *result;
93633caa0b8307eccf22010400747830b1967edb292Daniel Veillard
937797a565a2f6a2c0a8480670174e9eaef30d271a4Daniel Veillard#ifdef DEBUG_SAX
938797a565a2f6a2c0a8480670174e9eaef30d271a4Daniel Veillard    printf("pythonEndElement(%s) called\n", name);
939797a565a2f6a2c0a8480670174e9eaef30d271a4Daniel Veillard#endif
94033caa0b8307eccf22010400747830b1967edb292Daniel Veillard    handler = (PyObject *) user_data;
941d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard    if (PyObject_HasAttrString(handler, (char *) "endElement")) {
942d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        result = PyObject_CallMethod(handler, (char *) "endElement",
943d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard                                     (char *) "s", name);
944d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        if (PyErr_Occurred())
945d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            PyErr_Print();
94633caa0b8307eccf22010400747830b1967edb292Daniel Veillard        Py_XDECREF(result);
947d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard    } else if (PyObject_HasAttrString(handler, (char *) "end")) {
948d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        result = PyObject_CallMethod(handler, (char *) "end",
949d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard                                     (char *) "s", name);
950d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        if (PyErr_Occurred())
951d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            PyErr_Print();
952797a565a2f6a2c0a8480670174e9eaef30d271a4Daniel Veillard        Py_XDECREF(result);
95333caa0b8307eccf22010400747830b1967edb292Daniel Veillard    }
95433caa0b8307eccf22010400747830b1967edb292Daniel Veillard}
95533caa0b8307eccf22010400747830b1967edb292Daniel Veillard
95633caa0b8307eccf22010400747830b1967edb292Daniel Veillardstatic void
95733caa0b8307eccf22010400747830b1967edb292Daniel VeillardpythonReference(void *user_data, const xmlChar * name)
95833caa0b8307eccf22010400747830b1967edb292Daniel Veillard{
95933caa0b8307eccf22010400747830b1967edb292Daniel Veillard    PyObject *handler;
96033caa0b8307eccf22010400747830b1967edb292Daniel Veillard    PyObject *result;
96133caa0b8307eccf22010400747830b1967edb292Daniel Veillard
962797a565a2f6a2c0a8480670174e9eaef30d271a4Daniel Veillard#ifdef DEBUG_SAX
963797a565a2f6a2c0a8480670174e9eaef30d271a4Daniel Veillard    printf("pythonReference(%s) called\n", name);
964797a565a2f6a2c0a8480670174e9eaef30d271a4Daniel Veillard#endif
96533caa0b8307eccf22010400747830b1967edb292Daniel Veillard    handler = (PyObject *) user_data;
966d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard    if (PyObject_HasAttrString(handler, (char *) "reference")) {
967d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        result = PyObject_CallMethod(handler, (char *) "reference",
968d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard                                     (char *) "s", name);
969d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        if (PyErr_Occurred())
970d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            PyErr_Print();
97133caa0b8307eccf22010400747830b1967edb292Daniel Veillard        Py_XDECREF(result);
97233caa0b8307eccf22010400747830b1967edb292Daniel Veillard    }
97333caa0b8307eccf22010400747830b1967edb292Daniel Veillard}
97433caa0b8307eccf22010400747830b1967edb292Daniel Veillard
97533caa0b8307eccf22010400747830b1967edb292Daniel Veillardstatic void
97633caa0b8307eccf22010400747830b1967edb292Daniel VeillardpythonCharacters(void *user_data, const xmlChar * ch, int len)
97733caa0b8307eccf22010400747830b1967edb292Daniel Veillard{
97833caa0b8307eccf22010400747830b1967edb292Daniel Veillard    PyObject *handler;
979d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard    PyObject *result = NULL;
98033caa0b8307eccf22010400747830b1967edb292Daniel Veillard    int type = 0;
98133caa0b8307eccf22010400747830b1967edb292Daniel Veillard
982797a565a2f6a2c0a8480670174e9eaef30d271a4Daniel Veillard#ifdef DEBUG_SAX
983797a565a2f6a2c0a8480670174e9eaef30d271a4Daniel Veillard    printf("pythonCharacters(%s, %d) called\n", ch, len);
984797a565a2f6a2c0a8480670174e9eaef30d271a4Daniel Veillard#endif
98533caa0b8307eccf22010400747830b1967edb292Daniel Veillard    handler = (PyObject *) user_data;
986d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard    if (PyObject_HasAttrString(handler, (char *) "characters"))
987d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        type = 1;
988d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard    else if (PyObject_HasAttrString(handler, (char *) "data"))
989d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        type = 2;
99033caa0b8307eccf22010400747830b1967edb292Daniel Veillard    if (type != 0) {
991d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        if (type == 1)
992d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            result = PyObject_CallMethod(handler, (char *) "characters",
993d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard                                         (char *) "s#", ch, len);
994d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        else if (type == 2)
995d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            result = PyObject_CallMethod(handler, (char *) "data",
996d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard                                         (char *) "s#", ch, len);
997d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        if (PyErr_Occurred())
998d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            PyErr_Print();
99933caa0b8307eccf22010400747830b1967edb292Daniel Veillard        Py_XDECREF(result);
100033caa0b8307eccf22010400747830b1967edb292Daniel Veillard    }
100133caa0b8307eccf22010400747830b1967edb292Daniel Veillard}
100233caa0b8307eccf22010400747830b1967edb292Daniel Veillard
100333caa0b8307eccf22010400747830b1967edb292Daniel Veillardstatic void
100433caa0b8307eccf22010400747830b1967edb292Daniel VeillardpythonIgnorableWhitespace(void *user_data, const xmlChar * ch, int len)
100533caa0b8307eccf22010400747830b1967edb292Daniel Veillard{
100633caa0b8307eccf22010400747830b1967edb292Daniel Veillard    PyObject *handler;
1007d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard    PyObject *result = NULL;
100833caa0b8307eccf22010400747830b1967edb292Daniel Veillard    int type = 0;
100933caa0b8307eccf22010400747830b1967edb292Daniel Veillard
1010797a565a2f6a2c0a8480670174e9eaef30d271a4Daniel Veillard#ifdef DEBUG_SAX
1011797a565a2f6a2c0a8480670174e9eaef30d271a4Daniel Veillard    printf("pythonIgnorableWhitespace(%s, %d) called\n", ch, len);
1012797a565a2f6a2c0a8480670174e9eaef30d271a4Daniel Veillard#endif
101333caa0b8307eccf22010400747830b1967edb292Daniel Veillard    handler = (PyObject *) user_data;
1014d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard    if (PyObject_HasAttrString(handler, (char *) "ignorableWhitespace"))
101533caa0b8307eccf22010400747830b1967edb292Daniel Veillard        type = 1;
1016d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard    else if (PyObject_HasAttrString(handler, (char *) "data"))
101733caa0b8307eccf22010400747830b1967edb292Daniel Veillard        type = 2;
101833caa0b8307eccf22010400747830b1967edb292Daniel Veillard    if (type != 0) {
101933caa0b8307eccf22010400747830b1967edb292Daniel Veillard        if (type == 1)
102033caa0b8307eccf22010400747830b1967edb292Daniel Veillard            result =
1021d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard                PyObject_CallMethod(handler,
1022d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard                                    (char *) "ignorableWhitespace",
1023d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard                                    (char *) "s#", ch, len);
102433caa0b8307eccf22010400747830b1967edb292Daniel Veillard        else if (type == 2)
1025d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            result =
1026d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard                PyObject_CallMethod(handler, (char *) "data",
1027d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard                                    (char *) "s#", ch, len);
102833caa0b8307eccf22010400747830b1967edb292Daniel Veillard        Py_XDECREF(result);
102933caa0b8307eccf22010400747830b1967edb292Daniel Veillard    }
103033caa0b8307eccf22010400747830b1967edb292Daniel Veillard}
103133caa0b8307eccf22010400747830b1967edb292Daniel Veillard
103233caa0b8307eccf22010400747830b1967edb292Daniel Veillardstatic void
103333caa0b8307eccf22010400747830b1967edb292Daniel VeillardpythonProcessingInstruction(void *user_data,
103433caa0b8307eccf22010400747830b1967edb292Daniel Veillard                            const xmlChar * target, const xmlChar * data)
103533caa0b8307eccf22010400747830b1967edb292Daniel Veillard{
103633caa0b8307eccf22010400747830b1967edb292Daniel Veillard    PyObject *handler;
103733caa0b8307eccf22010400747830b1967edb292Daniel Veillard    PyObject *result;
103833caa0b8307eccf22010400747830b1967edb292Daniel Veillard
1039797a565a2f6a2c0a8480670174e9eaef30d271a4Daniel Veillard#ifdef DEBUG_SAX
1040797a565a2f6a2c0a8480670174e9eaef30d271a4Daniel Veillard    printf("pythonProcessingInstruction(%s, %s) called\n", target, data);
1041797a565a2f6a2c0a8480670174e9eaef30d271a4Daniel Veillard#endif
104233caa0b8307eccf22010400747830b1967edb292Daniel Veillard    handler = (PyObject *) user_data;
1043d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard    if (PyObject_HasAttrString(handler, (char *) "processingInstruction")) {
1044d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        result = PyObject_CallMethod(handler, (char *)
1045d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard                                     "processingInstruction",
1046d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard                                     (char *) "ss", target, data);
104733caa0b8307eccf22010400747830b1967edb292Daniel Veillard        Py_XDECREF(result);
104833caa0b8307eccf22010400747830b1967edb292Daniel Veillard    }
104933caa0b8307eccf22010400747830b1967edb292Daniel Veillard}
105033caa0b8307eccf22010400747830b1967edb292Daniel Veillard
105133caa0b8307eccf22010400747830b1967edb292Daniel Veillardstatic void
105233caa0b8307eccf22010400747830b1967edb292Daniel VeillardpythonComment(void *user_data, const xmlChar * value)
105333caa0b8307eccf22010400747830b1967edb292Daniel Veillard{
105433caa0b8307eccf22010400747830b1967edb292Daniel Veillard    PyObject *handler;
105533caa0b8307eccf22010400747830b1967edb292Daniel Veillard    PyObject *result;
105633caa0b8307eccf22010400747830b1967edb292Daniel Veillard
1057797a565a2f6a2c0a8480670174e9eaef30d271a4Daniel Veillard#ifdef DEBUG_SAX
1058797a565a2f6a2c0a8480670174e9eaef30d271a4Daniel Veillard    printf("pythonComment(%s) called\n", value);
1059797a565a2f6a2c0a8480670174e9eaef30d271a4Daniel Veillard#endif
106033caa0b8307eccf22010400747830b1967edb292Daniel Veillard    handler = (PyObject *) user_data;
1061d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard    if (PyObject_HasAttrString(handler, (char *) "comment")) {
1062d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        result =
1063d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            PyObject_CallMethod(handler, (char *) "comment", (char *) "s",
1064d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard                                value);
1065d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        if (PyErr_Occurred())
1066d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            PyErr_Print();
106733caa0b8307eccf22010400747830b1967edb292Daniel Veillard        Py_XDECREF(result);
106833caa0b8307eccf22010400747830b1967edb292Daniel Veillard    }
106933caa0b8307eccf22010400747830b1967edb292Daniel Veillard}
107033caa0b8307eccf22010400747830b1967edb292Daniel Veillard
107133caa0b8307eccf22010400747830b1967edb292Daniel Veillardstatic void
107233caa0b8307eccf22010400747830b1967edb292Daniel VeillardpythonWarning(void *user_data, const char *msg, ...)
107333caa0b8307eccf22010400747830b1967edb292Daniel Veillard{
107433caa0b8307eccf22010400747830b1967edb292Daniel Veillard    PyObject *handler;
107533caa0b8307eccf22010400747830b1967edb292Daniel Veillard    PyObject *result;
107633caa0b8307eccf22010400747830b1967edb292Daniel Veillard    va_list args;
107733caa0b8307eccf22010400747830b1967edb292Daniel Veillard    char buf[1024];
107833caa0b8307eccf22010400747830b1967edb292Daniel Veillard
1079797a565a2f6a2c0a8480670174e9eaef30d271a4Daniel Veillard#ifdef DEBUG_SAX
1080797a565a2f6a2c0a8480670174e9eaef30d271a4Daniel Veillard    printf("pythonWarning(%s) called\n", msg);
1081797a565a2f6a2c0a8480670174e9eaef30d271a4Daniel Veillard#endif
108233caa0b8307eccf22010400747830b1967edb292Daniel Veillard    handler = (PyObject *) user_data;
1083d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard    if (PyObject_HasAttrString(handler, (char *) "warning")) {
108433caa0b8307eccf22010400747830b1967edb292Daniel Veillard        va_start(args, msg);
108533caa0b8307eccf22010400747830b1967edb292Daniel Veillard        vsnprintf(buf, 1023, msg, args);
1086d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        va_end(args);
1087d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        buf[1023] = 0;
1088d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        result =
1089d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            PyObject_CallMethod(handler, (char *) "warning", (char *) "s",
1090d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard                                buf);
1091d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        if (PyErr_Occurred())
1092d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            PyErr_Print();
109333caa0b8307eccf22010400747830b1967edb292Daniel Veillard        Py_XDECREF(result);
109433caa0b8307eccf22010400747830b1967edb292Daniel Veillard    }
109533caa0b8307eccf22010400747830b1967edb292Daniel Veillard}
109633caa0b8307eccf22010400747830b1967edb292Daniel Veillard
109733caa0b8307eccf22010400747830b1967edb292Daniel Veillardstatic void
109833caa0b8307eccf22010400747830b1967edb292Daniel VeillardpythonError(void *user_data, const char *msg, ...)
109933caa0b8307eccf22010400747830b1967edb292Daniel Veillard{
110033caa0b8307eccf22010400747830b1967edb292Daniel Veillard    PyObject *handler;
110133caa0b8307eccf22010400747830b1967edb292Daniel Veillard    PyObject *result;
110233caa0b8307eccf22010400747830b1967edb292Daniel Veillard    va_list args;
110333caa0b8307eccf22010400747830b1967edb292Daniel Veillard    char buf[1024];
110433caa0b8307eccf22010400747830b1967edb292Daniel Veillard
1105797a565a2f6a2c0a8480670174e9eaef30d271a4Daniel Veillard#ifdef DEBUG_SAX
1106797a565a2f6a2c0a8480670174e9eaef30d271a4Daniel Veillard    printf("pythonError(%s) called\n", msg);
1107797a565a2f6a2c0a8480670174e9eaef30d271a4Daniel Veillard#endif
110833caa0b8307eccf22010400747830b1967edb292Daniel Veillard    handler = (PyObject *) user_data;
1109d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard    if (PyObject_HasAttrString(handler, (char *) "error")) {
111033caa0b8307eccf22010400747830b1967edb292Daniel Veillard        va_start(args, msg);
111133caa0b8307eccf22010400747830b1967edb292Daniel Veillard        vsnprintf(buf, 1023, msg, args);
1112d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        va_end(args);
1113d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        buf[1023] = 0;
1114d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        result =
1115d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            PyObject_CallMethod(handler, (char *) "error", (char *) "s",
1116d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard                                buf);
1117d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        if (PyErr_Occurred())
1118d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            PyErr_Print();
111933caa0b8307eccf22010400747830b1967edb292Daniel Veillard        Py_XDECREF(result);
112033caa0b8307eccf22010400747830b1967edb292Daniel Veillard    }
112133caa0b8307eccf22010400747830b1967edb292Daniel Veillard}
112233caa0b8307eccf22010400747830b1967edb292Daniel Veillard
112333caa0b8307eccf22010400747830b1967edb292Daniel Veillardstatic void
112433caa0b8307eccf22010400747830b1967edb292Daniel VeillardpythonFatalError(void *user_data, const char *msg, ...)
112533caa0b8307eccf22010400747830b1967edb292Daniel Veillard{
112633caa0b8307eccf22010400747830b1967edb292Daniel Veillard    PyObject *handler;
112733caa0b8307eccf22010400747830b1967edb292Daniel Veillard    PyObject *result;
112833caa0b8307eccf22010400747830b1967edb292Daniel Veillard    va_list args;
112933caa0b8307eccf22010400747830b1967edb292Daniel Veillard    char buf[1024];
113033caa0b8307eccf22010400747830b1967edb292Daniel Veillard
1131797a565a2f6a2c0a8480670174e9eaef30d271a4Daniel Veillard#ifdef DEBUG_SAX
1132797a565a2f6a2c0a8480670174e9eaef30d271a4Daniel Veillard    printf("pythonFatalError(%s) called\n", msg);
1133797a565a2f6a2c0a8480670174e9eaef30d271a4Daniel Veillard#endif
113433caa0b8307eccf22010400747830b1967edb292Daniel Veillard    handler = (PyObject *) user_data;
1135d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard    if (PyObject_HasAttrString(handler, (char *) "fatalError")) {
113633caa0b8307eccf22010400747830b1967edb292Daniel Veillard        va_start(args, msg);
113733caa0b8307eccf22010400747830b1967edb292Daniel Veillard        vsnprintf(buf, 1023, msg, args);
1138d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        va_end(args);
1139d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        buf[1023] = 0;
1140d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        result =
1141d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            PyObject_CallMethod(handler, (char *) "fatalError",
1142d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard                                (char *) "s", buf);
1143d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        if (PyErr_Occurred())
1144d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            PyErr_Print();
114533caa0b8307eccf22010400747830b1967edb292Daniel Veillard        Py_XDECREF(result);
114633caa0b8307eccf22010400747830b1967edb292Daniel Veillard    }
114733caa0b8307eccf22010400747830b1967edb292Daniel Veillard}
114833caa0b8307eccf22010400747830b1967edb292Daniel Veillard
114933caa0b8307eccf22010400747830b1967edb292Daniel Veillardstatic void
115033caa0b8307eccf22010400747830b1967edb292Daniel VeillardpythonCdataBlock(void *user_data, const xmlChar * ch, int len)
115133caa0b8307eccf22010400747830b1967edb292Daniel Veillard{
115233caa0b8307eccf22010400747830b1967edb292Daniel Veillard    PyObject *handler;
1153d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard    PyObject *result = NULL;
115433caa0b8307eccf22010400747830b1967edb292Daniel Veillard    int type = 0;
115533caa0b8307eccf22010400747830b1967edb292Daniel Veillard
1156797a565a2f6a2c0a8480670174e9eaef30d271a4Daniel Veillard#ifdef DEBUG_SAX
1157797a565a2f6a2c0a8480670174e9eaef30d271a4Daniel Veillard    printf("pythonCdataBlock(%s, %d) called\n", ch, len);
1158797a565a2f6a2c0a8480670174e9eaef30d271a4Daniel Veillard#endif
115933caa0b8307eccf22010400747830b1967edb292Daniel Veillard    handler = (PyObject *) user_data;
1160d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard    if (PyObject_HasAttrString(handler, (char *) "cdataBlock"))
1161d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        type = 1;
1162d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard    else if (PyObject_HasAttrString(handler, (char *) "cdata"))
1163d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        type = 2;
116433caa0b8307eccf22010400747830b1967edb292Daniel Veillard    if (type != 0) {
1165d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        if (type == 1)
1166d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            result =
1167d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard                PyObject_CallMethod(handler, (char *) "cdataBlock",
1168d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard                                    (char *) "s#", ch, len);
1169d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        else if (type == 2)
1170d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            result =
1171d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard                PyObject_CallMethod(handler, (char *) "cdata",
1172d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard                                    (char *) "s#", ch, len);
1173d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        if (PyErr_Occurred())
1174d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            PyErr_Print();
117533caa0b8307eccf22010400747830b1967edb292Daniel Veillard        Py_XDECREF(result);
117633caa0b8307eccf22010400747830b1967edb292Daniel Veillard    }
117733caa0b8307eccf22010400747830b1967edb292Daniel Veillard}
117833caa0b8307eccf22010400747830b1967edb292Daniel Veillard
117933caa0b8307eccf22010400747830b1967edb292Daniel Veillardstatic void
118033caa0b8307eccf22010400747830b1967edb292Daniel VeillardpythonExternalSubset(void *user_data,
118133caa0b8307eccf22010400747830b1967edb292Daniel Veillard                     const xmlChar * name,
118233caa0b8307eccf22010400747830b1967edb292Daniel Veillard                     const xmlChar * externalID, const xmlChar * systemID)
118333caa0b8307eccf22010400747830b1967edb292Daniel Veillard{
118433caa0b8307eccf22010400747830b1967edb292Daniel Veillard    PyObject *handler;
118533caa0b8307eccf22010400747830b1967edb292Daniel Veillard    PyObject *result;
118633caa0b8307eccf22010400747830b1967edb292Daniel Veillard
1187797a565a2f6a2c0a8480670174e9eaef30d271a4Daniel Veillard#ifdef DEBUG_SAX
1188797a565a2f6a2c0a8480670174e9eaef30d271a4Daniel Veillard    printf("pythonExternalSubset(%s, %s, %s) called\n",
1189d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard           name, externalID, systemID);
1190797a565a2f6a2c0a8480670174e9eaef30d271a4Daniel Veillard#endif
119133caa0b8307eccf22010400747830b1967edb292Daniel Veillard    handler = (PyObject *) user_data;
1192d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard    if (PyObject_HasAttrString(handler, (char *) "externalSubset")) {
119333caa0b8307eccf22010400747830b1967edb292Daniel Veillard        result =
1194d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            PyObject_CallMethod(handler, (char *) "externalSubset",
1195d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard                                (char *) "sss", name, externalID,
1196d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard                                systemID);
119733caa0b8307eccf22010400747830b1967edb292Daniel Veillard        Py_XDECREF(result);
119833caa0b8307eccf22010400747830b1967edb292Daniel Veillard    }
119933caa0b8307eccf22010400747830b1967edb292Daniel Veillard}
120033caa0b8307eccf22010400747830b1967edb292Daniel Veillard
120133caa0b8307eccf22010400747830b1967edb292Daniel Veillardstatic void
120233caa0b8307eccf22010400747830b1967edb292Daniel VeillardpythonEntityDecl(void *user_data,
120333caa0b8307eccf22010400747830b1967edb292Daniel Veillard                 const xmlChar * name,
120433caa0b8307eccf22010400747830b1967edb292Daniel Veillard                 int type,
120533caa0b8307eccf22010400747830b1967edb292Daniel Veillard                 const xmlChar * publicId,
120633caa0b8307eccf22010400747830b1967edb292Daniel Veillard                 const xmlChar * systemId, xmlChar * content)
120733caa0b8307eccf22010400747830b1967edb292Daniel Veillard{
120833caa0b8307eccf22010400747830b1967edb292Daniel Veillard    PyObject *handler;
120933caa0b8307eccf22010400747830b1967edb292Daniel Veillard    PyObject *result;
121033caa0b8307eccf22010400747830b1967edb292Daniel Veillard
121133caa0b8307eccf22010400747830b1967edb292Daniel Veillard    handler = (PyObject *) user_data;
1212d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard    if (PyObject_HasAttrString(handler, (char *) "entityDecl")) {
1213d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        result = PyObject_CallMethod(handler, (char *) "entityDecl",
1214d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard                                     (char *) "sisss", name, type,
1215d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard                                     publicId, systemId, content);
1216d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        if (PyErr_Occurred())
1217d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            PyErr_Print();
121833caa0b8307eccf22010400747830b1967edb292Daniel Veillard        Py_XDECREF(result);
121933caa0b8307eccf22010400747830b1967edb292Daniel Veillard    }
122033caa0b8307eccf22010400747830b1967edb292Daniel Veillard}
122133caa0b8307eccf22010400747830b1967edb292Daniel Veillard
122233caa0b8307eccf22010400747830b1967edb292Daniel Veillard
122333caa0b8307eccf22010400747830b1967edb292Daniel Veillard
122433caa0b8307eccf22010400747830b1967edb292Daniel Veillardstatic void
122533caa0b8307eccf22010400747830b1967edb292Daniel Veillard
122633caa0b8307eccf22010400747830b1967edb292Daniel VeillardpythonNotationDecl(void *user_data,
122733caa0b8307eccf22010400747830b1967edb292Daniel Veillard                   const xmlChar * name,
122833caa0b8307eccf22010400747830b1967edb292Daniel Veillard                   const xmlChar * publicId, const xmlChar * systemId)
122933caa0b8307eccf22010400747830b1967edb292Daniel Veillard{
123033caa0b8307eccf22010400747830b1967edb292Daniel Veillard    PyObject *handler;
123133caa0b8307eccf22010400747830b1967edb292Daniel Veillard    PyObject *result;
123233caa0b8307eccf22010400747830b1967edb292Daniel Veillard
123333caa0b8307eccf22010400747830b1967edb292Daniel Veillard    handler = (PyObject *) user_data;
1234d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard    if (PyObject_HasAttrString(handler, (char *) "notationDecl")) {
1235d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        result = PyObject_CallMethod(handler, (char *) "notationDecl",
1236d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard                                     (char *) "sss", name, publicId,
1237d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard                                     systemId);
1238d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        if (PyErr_Occurred())
1239d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            PyErr_Print();
124033caa0b8307eccf22010400747830b1967edb292Daniel Veillard        Py_XDECREF(result);
124133caa0b8307eccf22010400747830b1967edb292Daniel Veillard    }
124233caa0b8307eccf22010400747830b1967edb292Daniel Veillard}
124333caa0b8307eccf22010400747830b1967edb292Daniel Veillard
124433caa0b8307eccf22010400747830b1967edb292Daniel Veillardstatic void
124533caa0b8307eccf22010400747830b1967edb292Daniel VeillardpythonAttributeDecl(void *user_data,
124633caa0b8307eccf22010400747830b1967edb292Daniel Veillard                    const xmlChar * elem,
124733caa0b8307eccf22010400747830b1967edb292Daniel Veillard                    const xmlChar * name,
124833caa0b8307eccf22010400747830b1967edb292Daniel Veillard                    int type,
124933caa0b8307eccf22010400747830b1967edb292Daniel Veillard                    int def,
1250d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard                    const xmlChar * defaultValue, xmlEnumerationPtr tree)
125133caa0b8307eccf22010400747830b1967edb292Daniel Veillard{
125233caa0b8307eccf22010400747830b1967edb292Daniel Veillard    PyObject *handler;
125333caa0b8307eccf22010400747830b1967edb292Daniel Veillard    PyObject *nameList;
125433caa0b8307eccf22010400747830b1967edb292Daniel Veillard    PyObject *newName;
125533caa0b8307eccf22010400747830b1967edb292Daniel Veillard    xmlEnumerationPtr node;
125633caa0b8307eccf22010400747830b1967edb292Daniel Veillard    PyObject *result;
125733caa0b8307eccf22010400747830b1967edb292Daniel Veillard    int count;
125833caa0b8307eccf22010400747830b1967edb292Daniel Veillard
125933caa0b8307eccf22010400747830b1967edb292Daniel Veillard    handler = (PyObject *) user_data;
1260d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard    if (PyObject_HasAttrString(handler, (char *) "attributeDecl")) {
126133caa0b8307eccf22010400747830b1967edb292Daniel Veillard        count = 0;
126233caa0b8307eccf22010400747830b1967edb292Daniel Veillard        for (node = tree; node != NULL; node = node->next) {
126333caa0b8307eccf22010400747830b1967edb292Daniel Veillard            count++;
126433caa0b8307eccf22010400747830b1967edb292Daniel Veillard        }
126533caa0b8307eccf22010400747830b1967edb292Daniel Veillard        nameList = PyList_New(count);
126633caa0b8307eccf22010400747830b1967edb292Daniel Veillard        count = 0;
126733caa0b8307eccf22010400747830b1967edb292Daniel Veillard        for (node = tree; node != NULL; node = node->next) {
1268d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            newName = PyString_FromString((char *) node->name);
126933caa0b8307eccf22010400747830b1967edb292Daniel Veillard            PyList_SetItem(nameList, count, newName);
1270a3d230513c3f28dc475ee09ffd6787762da07d56Daniel Veillard	    Py_DECREF(newName);
127133caa0b8307eccf22010400747830b1967edb292Daniel Veillard            count++;
127233caa0b8307eccf22010400747830b1967edb292Daniel Veillard        }
1273d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        result = PyObject_CallMethod(handler, (char *) "attributeDecl",
1274d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard                                     (char *) "ssiisO", elem, name, type,
1275d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard                                     def, defaultValue, nameList);
1276d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        if (PyErr_Occurred())
1277d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            PyErr_Print();
127833caa0b8307eccf22010400747830b1967edb292Daniel Veillard        Py_XDECREF(nameList);
127933caa0b8307eccf22010400747830b1967edb292Daniel Veillard        Py_XDECREF(result);
128033caa0b8307eccf22010400747830b1967edb292Daniel Veillard    }
128133caa0b8307eccf22010400747830b1967edb292Daniel Veillard}
128233caa0b8307eccf22010400747830b1967edb292Daniel Veillard
128333caa0b8307eccf22010400747830b1967edb292Daniel Veillardstatic void
128433caa0b8307eccf22010400747830b1967edb292Daniel VeillardpythonElementDecl(void *user_data,
128533caa0b8307eccf22010400747830b1967edb292Daniel Veillard                  const xmlChar * name,
1286d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard                  int type, ATTRIBUTE_UNUSED xmlElementContentPtr content)
128733caa0b8307eccf22010400747830b1967edb292Daniel Veillard{
128833caa0b8307eccf22010400747830b1967edb292Daniel Veillard    PyObject *handler;
128933caa0b8307eccf22010400747830b1967edb292Daniel Veillard    PyObject *obj;
129033caa0b8307eccf22010400747830b1967edb292Daniel Veillard    PyObject *result;
129133caa0b8307eccf22010400747830b1967edb292Daniel Veillard
129233caa0b8307eccf22010400747830b1967edb292Daniel Veillard    handler = (PyObject *) user_data;
1293d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard    if (PyObject_HasAttrString(handler, (char *) "elementDecl")) {
1294d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        /* TODO: wrap in an elementContent object */
1295d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        printf
1296d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            ("pythonElementDecl: xmlElementContentPtr wrapper missing !\n");
1297d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        obj = Py_None;
1298d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        /* Py_XINCREF(Py_None); isn't the reference just borrowed ??? */
1299d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        result = PyObject_CallMethod(handler, (char *) "elementDecl",
1300d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard                                     (char *) "siO", name, type, obj);
1301d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        if (PyErr_Occurred())
1302d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            PyErr_Print();
130333caa0b8307eccf22010400747830b1967edb292Daniel Veillard        Py_XDECREF(result);
130433caa0b8307eccf22010400747830b1967edb292Daniel Veillard    }
130533caa0b8307eccf22010400747830b1967edb292Daniel Veillard}
130633caa0b8307eccf22010400747830b1967edb292Daniel Veillard
130733caa0b8307eccf22010400747830b1967edb292Daniel Veillardstatic void
130833caa0b8307eccf22010400747830b1967edb292Daniel VeillardpythonUnparsedEntityDecl(void *user_data,
130933caa0b8307eccf22010400747830b1967edb292Daniel Veillard                         const xmlChar * name,
131033caa0b8307eccf22010400747830b1967edb292Daniel Veillard                         const xmlChar * publicId,
131133caa0b8307eccf22010400747830b1967edb292Daniel Veillard                         const xmlChar * systemId,
131233caa0b8307eccf22010400747830b1967edb292Daniel Veillard                         const xmlChar * notationName)
131333caa0b8307eccf22010400747830b1967edb292Daniel Veillard{
131433caa0b8307eccf22010400747830b1967edb292Daniel Veillard    PyObject *handler;
131533caa0b8307eccf22010400747830b1967edb292Daniel Veillard    PyObject *result;
131633caa0b8307eccf22010400747830b1967edb292Daniel Veillard
131733caa0b8307eccf22010400747830b1967edb292Daniel Veillard    handler = (PyObject *) user_data;
1318d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard    if (PyObject_HasAttrString(handler, (char *) "unparsedEntityDecl")) {
1319d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        result =
1320d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            PyObject_CallMethod(handler, (char *) "unparsedEntityDecl",
1321d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard                                (char *) "ssss", name, publicId, systemId,
1322d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard                                notationName);
1323d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        if (PyErr_Occurred())
1324d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            PyErr_Print();
132533caa0b8307eccf22010400747830b1967edb292Daniel Veillard        Py_XDECREF(result);
132633caa0b8307eccf22010400747830b1967edb292Daniel Veillard    }
132733caa0b8307eccf22010400747830b1967edb292Daniel Veillard}
132833caa0b8307eccf22010400747830b1967edb292Daniel Veillard
132933caa0b8307eccf22010400747830b1967edb292Daniel Veillardstatic void
133033caa0b8307eccf22010400747830b1967edb292Daniel VeillardpythonInternalSubset(void *user_data, const xmlChar * name,
133133caa0b8307eccf22010400747830b1967edb292Daniel Veillard                     const xmlChar * ExternalID, const xmlChar * SystemID)
133233caa0b8307eccf22010400747830b1967edb292Daniel Veillard{
133333caa0b8307eccf22010400747830b1967edb292Daniel Veillard    PyObject *handler;
133433caa0b8307eccf22010400747830b1967edb292Daniel Veillard    PyObject *result;
133533caa0b8307eccf22010400747830b1967edb292Daniel Veillard
1336797a565a2f6a2c0a8480670174e9eaef30d271a4Daniel Veillard#ifdef DEBUG_SAX
1337797a565a2f6a2c0a8480670174e9eaef30d271a4Daniel Veillard    printf("pythonInternalSubset(%s, %s, %s) called\n",
1338d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard           name, ExternalID, SystemID);
1339797a565a2f6a2c0a8480670174e9eaef30d271a4Daniel Veillard#endif
134033caa0b8307eccf22010400747830b1967edb292Daniel Veillard    handler = (PyObject *) user_data;
1341d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard    if (PyObject_HasAttrString(handler, (char *) "internalSubset")) {
1342d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        result = PyObject_CallMethod(handler, (char *) "internalSubset",
1343d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard                                     (char *) "sss", name, ExternalID,
1344d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard                                     SystemID);
1345d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        if (PyErr_Occurred())
1346d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            PyErr_Print();
134733caa0b8307eccf22010400747830b1967edb292Daniel Veillard        Py_XDECREF(result);
134833caa0b8307eccf22010400747830b1967edb292Daniel Veillard    }
134933caa0b8307eccf22010400747830b1967edb292Daniel Veillard}
135033caa0b8307eccf22010400747830b1967edb292Daniel Veillard
135133caa0b8307eccf22010400747830b1967edb292Daniel Veillardstatic xmlSAXHandler pythonSaxHandler = {
135233caa0b8307eccf22010400747830b1967edb292Daniel Veillard    pythonInternalSubset,
1353d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard    NULL,                       /* TODO pythonIsStandalone, */
1354d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard    NULL,                       /* TODO pythonHasInternalSubset, */
1355d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard    NULL,                       /* TODO pythonHasExternalSubset, */
1356d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard    NULL,                       /* TODO pythonResolveEntity, */
1357d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard    NULL,                       /* TODO pythonGetEntity, */
135833caa0b8307eccf22010400747830b1967edb292Daniel Veillard    pythonEntityDecl,
135933caa0b8307eccf22010400747830b1967edb292Daniel Veillard    pythonNotationDecl,
136033caa0b8307eccf22010400747830b1967edb292Daniel Veillard    pythonAttributeDecl,
136133caa0b8307eccf22010400747830b1967edb292Daniel Veillard    pythonElementDecl,
136233caa0b8307eccf22010400747830b1967edb292Daniel Veillard    pythonUnparsedEntityDecl,
1363d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard    NULL,                       /* OBSOLETED pythonSetDocumentLocator, */
136433caa0b8307eccf22010400747830b1967edb292Daniel Veillard    pythonStartDocument,
136533caa0b8307eccf22010400747830b1967edb292Daniel Veillard    pythonEndDocument,
136633caa0b8307eccf22010400747830b1967edb292Daniel Veillard    pythonStartElement,
136733caa0b8307eccf22010400747830b1967edb292Daniel Veillard    pythonEndElement,
136833caa0b8307eccf22010400747830b1967edb292Daniel Veillard    pythonReference,
136933caa0b8307eccf22010400747830b1967edb292Daniel Veillard    pythonCharacters,
137033caa0b8307eccf22010400747830b1967edb292Daniel Veillard    pythonIgnorableWhitespace,
137133caa0b8307eccf22010400747830b1967edb292Daniel Veillard    pythonProcessingInstruction,
137233caa0b8307eccf22010400747830b1967edb292Daniel Veillard    pythonComment,
137333caa0b8307eccf22010400747830b1967edb292Daniel Veillard    pythonWarning,
137433caa0b8307eccf22010400747830b1967edb292Daniel Veillard    pythonError,
137533caa0b8307eccf22010400747830b1967edb292Daniel Veillard    pythonFatalError,
1376d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard    NULL,                       /* TODO pythonGetParameterEntity, */
137733caa0b8307eccf22010400747830b1967edb292Daniel Veillard    pythonCdataBlock,
137833caa0b8307eccf22010400747830b1967edb292Daniel Veillard    pythonExternalSubset,
1379a9cce9cd0d7aff3ec318b5d8d376da131b6aaad4Daniel Veillard    1,
1380a9cce9cd0d7aff3ec318b5d8d376da131b6aaad4Daniel Veillard    NULL,			/* TODO mograte to SAX2 */
1381a9cce9cd0d7aff3ec318b5d8d376da131b6aaad4Daniel Veillard    NULL,
1382871611bb0325095b30559ff1edc1fdaa2ad5fd2fWilliam M. Brack    NULL,
1383a9cce9cd0d7aff3ec318b5d8d376da131b6aaad4Daniel Veillard    NULL
138433caa0b8307eccf22010400747830b1967edb292Daniel Veillard};
1385d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard
13863ce5257b293ed75d8feb18ed7ab18ea2b52510bdDaniel Veillard/************************************************************************
13873ce5257b293ed75d8feb18ed7ab18ea2b52510bdDaniel Veillard *									*
13883ce5257b293ed75d8feb18ed7ab18ea2b52510bdDaniel Veillard *		Handling of specific parser context			*
13893ce5257b293ed75d8feb18ed7ab18ea2b52510bdDaniel Veillard *									*
13903ce5257b293ed75d8feb18ed7ab18ea2b52510bdDaniel Veillard ************************************************************************/
13911971ee2698cb84c7699c96d3302f00e20d42c0d3Daniel Veillard
13921971ee2698cb84c7699c96d3302f00e20d42c0d3Daniel VeillardPyObject *
1393d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillardlibxml_xmlCreatePushParser(ATTRIBUTE_UNUSED PyObject * self,
1394d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard                           PyObject * args)
1395d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard{
1396d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard    const char *chunk;
13973ce5257b293ed75d8feb18ed7ab18ea2b52510bdDaniel Veillard    int size;
1398d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard    const char *URI;
139933caa0b8307eccf22010400747830b1967edb292Daniel Veillard    PyObject *pyobj_SAX = NULL;
14003ce5257b293ed75d8feb18ed7ab18ea2b52510bdDaniel Veillard    xmlSAXHandlerPtr SAX = NULL;
14013ce5257b293ed75d8feb18ed7ab18ea2b52510bdDaniel Veillard    xmlParserCtxtPtr ret;
14023ce5257b293ed75d8feb18ed7ab18ea2b52510bdDaniel Veillard    PyObject *pyret;
14033ce5257b293ed75d8feb18ed7ab18ea2b52510bdDaniel Veillard
1404d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard    if (!PyArg_ParseTuple
1405d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        (args, (char *) "Oziz:xmlCreatePushParser", &pyobj_SAX, &chunk,
1406d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard         &size, &URI))
1407d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        return (NULL);
14081971ee2698cb84c7699c96d3302f00e20d42c0d3Daniel Veillard
14098d24cc189845663509623fbd6b5106cc01266994Daniel Veillard#ifdef DEBUG
14103ce5257b293ed75d8feb18ed7ab18ea2b52510bdDaniel Veillard    printf("libxml_xmlCreatePushParser(%p, %s, %d, %s) called\n",
1411d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard           pyobj_SAX, chunk, size, URI);
14121971ee2698cb84c7699c96d3302f00e20d42c0d3Daniel Veillard#endif
14133ce5257b293ed75d8feb18ed7ab18ea2b52510bdDaniel Veillard    if (pyobj_SAX != Py_None) {
1414d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        SAX = &pythonSaxHandler;
1415d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        Py_INCREF(pyobj_SAX);
1416d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        /* The reference is released in pythonEndDocument() */
14171971ee2698cb84c7699c96d3302f00e20d42c0d3Daniel Veillard    }
141833caa0b8307eccf22010400747830b1967edb292Daniel Veillard    ret = xmlCreatePushParserCtxt(SAX, pyobj_SAX, chunk, size, URI);
14193ce5257b293ed75d8feb18ed7ab18ea2b52510bdDaniel Veillard    pyret = libxml_xmlParserCtxtPtrWrap(ret);
1420d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard    return (pyret);
1421a7340c830e4bddd86201cfdb97ac81e30b0dee62Daniel Veillard}
14225d81903b06418c7d8cc72cf9add81c4026a2f3bcDaniel Veillard
14234e1b26cfeba7f5fad4f8bd12fb5ce7029f930b79Daniel VeillardPyObject *
1424d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillardlibxml_htmlCreatePushParser(ATTRIBUTE_UNUSED PyObject * self,
1425d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard                            PyObject * args)
1426d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard{
1427656ce948ab664ce96298c5f419a03a7ffcc88d9dDaniel Veillard#ifdef LIBXML_HTML_ENABLED
1428d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard    const char *chunk;
14294e1b26cfeba7f5fad4f8bd12fb5ce7029f930b79Daniel Veillard    int size;
1430d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard    const char *URI;
143133caa0b8307eccf22010400747830b1967edb292Daniel Veillard    PyObject *pyobj_SAX = NULL;
14324e1b26cfeba7f5fad4f8bd12fb5ce7029f930b79Daniel Veillard    xmlSAXHandlerPtr SAX = NULL;
14334e1b26cfeba7f5fad4f8bd12fb5ce7029f930b79Daniel Veillard    xmlParserCtxtPtr ret;
14344e1b26cfeba7f5fad4f8bd12fb5ce7029f930b79Daniel Veillard    PyObject *pyret;
14354e1b26cfeba7f5fad4f8bd12fb5ce7029f930b79Daniel Veillard
1436d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard    if (!PyArg_ParseTuple
1437d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        (args, (char *) "Oziz:htmlCreatePushParser", &pyobj_SAX, &chunk,
1438d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard         &size, &URI))
1439d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        return (NULL);
14404e1b26cfeba7f5fad4f8bd12fb5ce7029f930b79Daniel Veillard
14418d24cc189845663509623fbd6b5106cc01266994Daniel Veillard#ifdef DEBUG
14424e1b26cfeba7f5fad4f8bd12fb5ce7029f930b79Daniel Veillard    printf("libxml_htmlCreatePushParser(%p, %s, %d, %s) called\n",
1443d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard           pyobj_SAX, chunk, size, URI);
14444e1b26cfeba7f5fad4f8bd12fb5ce7029f930b79Daniel Veillard#endif
14454e1b26cfeba7f5fad4f8bd12fb5ce7029f930b79Daniel Veillard    if (pyobj_SAX != Py_None) {
1446d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        SAX = &pythonSaxHandler;
1447d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        Py_INCREF(pyobj_SAX);
1448d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        /* The reference is released in pythonEndDocument() */
14494e1b26cfeba7f5fad4f8bd12fb5ce7029f930b79Daniel Veillard    }
145033caa0b8307eccf22010400747830b1967edb292Daniel Veillard    ret = htmlCreatePushParserCtxt(SAX, pyobj_SAX, chunk, size, URI,
1451d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard                                   XML_CHAR_ENCODING_NONE);
14524e1b26cfeba7f5fad4f8bd12fb5ce7029f930b79Daniel Veillard    pyret = libxml_xmlParserCtxtPtrWrap(ret);
1453d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard    return (pyret);
1454656ce948ab664ce96298c5f419a03a7ffcc88d9dDaniel Veillard#else
1455656ce948ab664ce96298c5f419a03a7ffcc88d9dDaniel Veillard    Py_INCREF(Py_None);
1456656ce948ab664ce96298c5f419a03a7ffcc88d9dDaniel Veillard    return (Py_None);
1457656ce948ab664ce96298c5f419a03a7ffcc88d9dDaniel Veillard#endif /* LIBXML_HTML_ENABLED */
14584e1b26cfeba7f5fad4f8bd12fb5ce7029f930b79Daniel Veillard}
14594e1b26cfeba7f5fad4f8bd12fb5ce7029f930b79Daniel Veillard
14608d24cc189845663509623fbd6b5106cc01266994Daniel VeillardPyObject *
1461d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillardlibxml_xmlSAXParseFile(ATTRIBUTE_UNUSED PyObject * self, PyObject * args)
1462d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard{
1463961b535c10c7d07d7919c58c1d0c6762b35503a1Akira TAGOH#ifdef LIBXML_SAX1_ENABLED
14648d24cc189845663509623fbd6b5106cc01266994Daniel Veillard    int recover;
1465d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard    const char *URI;
14668d24cc189845663509623fbd6b5106cc01266994Daniel Veillard    PyObject *pyobj_SAX = NULL;
14678d24cc189845663509623fbd6b5106cc01266994Daniel Veillard    xmlSAXHandlerPtr SAX = NULL;
14688d24cc189845663509623fbd6b5106cc01266994Daniel Veillard
1469d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard    if (!PyArg_ParseTuple(args, (char *) "Osi:xmlSAXParseFile", &pyobj_SAX,
1470d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard                          &URI, &recover))
1471d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        return (NULL);
14728d24cc189845663509623fbd6b5106cc01266994Daniel Veillard
14738d24cc189845663509623fbd6b5106cc01266994Daniel Veillard#ifdef DEBUG
14748d24cc189845663509623fbd6b5106cc01266994Daniel Veillard    printf("libxml_xmlSAXParseFile(%p, %s, %d) called\n",
1475d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard           pyobj_SAX, URI, recover);
14768d24cc189845663509623fbd6b5106cc01266994Daniel Veillard#endif
14778d24cc189845663509623fbd6b5106cc01266994Daniel Veillard    if (pyobj_SAX == Py_None) {
1478d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        Py_INCREF(Py_None);
1479d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        return (Py_None);
14808d24cc189845663509623fbd6b5106cc01266994Daniel Veillard    }
14818d24cc189845663509623fbd6b5106cc01266994Daniel Veillard    SAX = &pythonSaxHandler;
14828d24cc189845663509623fbd6b5106cc01266994Daniel Veillard    Py_INCREF(pyobj_SAX);
14838d24cc189845663509623fbd6b5106cc01266994Daniel Veillard    /* The reference is released in pythonEndDocument() */
1484f2531afe41a2232669302ceb49161d5689971ed9Daniel Veillard    xmlSAXUserParseFile(SAX, pyobj_SAX, URI);
1485961b535c10c7d07d7919c58c1d0c6762b35503a1Akira TAGOH#endif /* LIBXML_SAX1_ENABLED */
14868d24cc189845663509623fbd6b5106cc01266994Daniel Veillard    Py_INCREF(Py_None);
1487d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard    return (Py_None);
14888d24cc189845663509623fbd6b5106cc01266994Daniel Veillard}
14898d24cc189845663509623fbd6b5106cc01266994Daniel Veillard
14908d24cc189845663509623fbd6b5106cc01266994Daniel VeillardPyObject *
1491d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillardlibxml_htmlSAXParseFile(ATTRIBUTE_UNUSED PyObject * self, PyObject * args)
1492d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard{
1493656ce948ab664ce96298c5f419a03a7ffcc88d9dDaniel Veillard#ifdef LIBXML_HTML_ENABLED
1494d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard    const char *URI;
1495d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard    const char *encoding;
14968d24cc189845663509623fbd6b5106cc01266994Daniel Veillard    PyObject *pyobj_SAX = NULL;
14978d24cc189845663509623fbd6b5106cc01266994Daniel Veillard    xmlSAXHandlerPtr SAX = NULL;
14988d24cc189845663509623fbd6b5106cc01266994Daniel Veillard
1499d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard    if (!PyArg_ParseTuple
1500d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        (args, (char *) "Osz:htmlSAXParseFile", &pyobj_SAX, &URI,
1501d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard         &encoding))
1502d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        return (NULL);
15038d24cc189845663509623fbd6b5106cc01266994Daniel Veillard
15048d24cc189845663509623fbd6b5106cc01266994Daniel Veillard#ifdef DEBUG
15058d24cc189845663509623fbd6b5106cc01266994Daniel Veillard    printf("libxml_htmlSAXParseFile(%p, %s, %s) called\n",
1506d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard           pyobj_SAX, URI, encoding);
15078d24cc189845663509623fbd6b5106cc01266994Daniel Veillard#endif
15088d24cc189845663509623fbd6b5106cc01266994Daniel Veillard    if (pyobj_SAX == Py_None) {
1509d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        Py_INCREF(Py_None);
1510d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        return (Py_None);
15118d24cc189845663509623fbd6b5106cc01266994Daniel Veillard    }
15128d24cc189845663509623fbd6b5106cc01266994Daniel Veillard    SAX = &pythonSaxHandler;
15138d24cc189845663509623fbd6b5106cc01266994Daniel Veillard    Py_INCREF(pyobj_SAX);
15148d24cc189845663509623fbd6b5106cc01266994Daniel Veillard    /* The reference is released in pythonEndDocument() */
15158d24cc189845663509623fbd6b5106cc01266994Daniel Veillard    htmlSAXParseFile(URI, encoding, SAX, pyobj_SAX);
15168d24cc189845663509623fbd6b5106cc01266994Daniel Veillard    Py_INCREF(Py_None);
1517d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard    return (Py_None);
1518656ce948ab664ce96298c5f419a03a7ffcc88d9dDaniel Veillard#else
1519656ce948ab664ce96298c5f419a03a7ffcc88d9dDaniel Veillard    Py_INCREF(Py_None);
1520656ce948ab664ce96298c5f419a03a7ffcc88d9dDaniel Veillard    return (Py_None);
1521656ce948ab664ce96298c5f419a03a7ffcc88d9dDaniel Veillard#endif /* LIBXML_HTML_ENABLED */
15228d24cc189845663509623fbd6b5106cc01266994Daniel Veillard}
15238d24cc189845663509623fbd6b5106cc01266994Daniel Veillard
15245d81903b06418c7d8cc72cf9add81c4026a2f3bcDaniel Veillard/************************************************************************
15255d81903b06418c7d8cc72cf9add81c4026a2f3bcDaniel Veillard *									*
15265d81903b06418c7d8cc72cf9add81c4026a2f3bcDaniel Veillard *			Error message callback				*
15275d81903b06418c7d8cc72cf9add81c4026a2f3bcDaniel Veillard *									*
15285d81903b06418c7d8cc72cf9add81c4026a2f3bcDaniel Veillard ************************************************************************/
15295d81903b06418c7d8cc72cf9add81c4026a2f3bcDaniel Veillard
15305d81903b06418c7d8cc72cf9add81c4026a2f3bcDaniel Veillardstatic PyObject *libxml_xmlPythonErrorFuncHandler = NULL;
15315d81903b06418c7d8cc72cf9add81c4026a2f3bcDaniel Veillardstatic PyObject *libxml_xmlPythonErrorFuncCtxt = NULL;
15325d81903b06418c7d8cc72cf9add81c4026a2f3bcDaniel Veillard
1533e6227e0549490b5bf9271ecd2d874a97c3f4852bDaniel Veillard/* helper to build a xmlMalloc'ed string from a format and va_list */
1534ad9fb7c06fea9cf63911c63cc9488ab1d0267005Daniel Veillard/*
1535ad9fb7c06fea9cf63911c63cc9488ab1d0267005Daniel Veillard * disabled the loop, the repeated call to vsnprintf without reset of ap
1536ad9fb7c06fea9cf63911c63cc9488ab1d0267005Daniel Veillard * in case the initial buffer was too small segfaulted on x86_64
1537ad9fb7c06fea9cf63911c63cc9488ab1d0267005Daniel Veillard * we now directly vsnprintf on a large buffer.
1538ad9fb7c06fea9cf63911c63cc9488ab1d0267005Daniel Veillard */
1539e6227e0549490b5bf9271ecd2d874a97c3f4852bDaniel Veillardstatic char *
1540e6227e0549490b5bf9271ecd2d874a97c3f4852bDaniel Veillardlibxml_buildMessage(const char *msg, va_list ap)
1541d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard{
1542d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard    int chars;
1543e6227e0549490b5bf9271ecd2d874a97c3f4852bDaniel Veillard    char *str;
1544e6227e0549490b5bf9271ecd2d874a97c3f4852bDaniel Veillard
1545ad9fb7c06fea9cf63911c63cc9488ab1d0267005Daniel Veillard    str = (char *) xmlMalloc(1000);
1546e6227e0549490b5bf9271ecd2d874a97c3f4852bDaniel Veillard    if (str == NULL)
1547e6227e0549490b5bf9271ecd2d874a97c3f4852bDaniel Veillard        return NULL;
1548e6227e0549490b5bf9271ecd2d874a97c3f4852bDaniel Veillard
1549ad9fb7c06fea9cf63911c63cc9488ab1d0267005Daniel Veillard    chars = vsnprintf(str, 999, msg, ap);
1550ad9fb7c06fea9cf63911c63cc9488ab1d0267005Daniel Veillard    if (chars >= 998)
1551ad9fb7c06fea9cf63911c63cc9488ab1d0267005Daniel Veillard        str[999] = 0;
1552e6227e0549490b5bf9271ecd2d874a97c3f4852bDaniel Veillard
1553e6227e0549490b5bf9271ecd2d874a97c3f4852bDaniel Veillard    return str;
1554e6227e0549490b5bf9271ecd2d874a97c3f4852bDaniel Veillard}
1555e6227e0549490b5bf9271ecd2d874a97c3f4852bDaniel Veillard
1556e6227e0549490b5bf9271ecd2d874a97c3f4852bDaniel Veillardstatic void
1557e6227e0549490b5bf9271ecd2d874a97c3f4852bDaniel Veillardlibxml_xmlErrorFuncHandler(ATTRIBUTE_UNUSED void *ctx, const char *msg,
1558e6227e0549490b5bf9271ecd2d874a97c3f4852bDaniel Veillard                           ...)
1559e6227e0549490b5bf9271ecd2d874a97c3f4852bDaniel Veillard{
1560d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard    va_list ap;
15615d81903b06418c7d8cc72cf9add81c4026a2f3bcDaniel Veillard    PyObject *list;
15625d81903b06418c7d8cc72cf9add81c4026a2f3bcDaniel Veillard    PyObject *message;
15635d81903b06418c7d8cc72cf9add81c4026a2f3bcDaniel Veillard    PyObject *result;
1564ad9fb7c06fea9cf63911c63cc9488ab1d0267005Daniel Veillard    char str[1000];
15655d81903b06418c7d8cc72cf9add81c4026a2f3bcDaniel Veillard
15665d81903b06418c7d8cc72cf9add81c4026a2f3bcDaniel Veillard#ifdef DEBUG_ERROR
15675d81903b06418c7d8cc72cf9add81c4026a2f3bcDaniel Veillard    printf("libxml_xmlErrorFuncHandler(%p, %s, ...) called\n", ctx, msg);
15685d81903b06418c7d8cc72cf9add81c4026a2f3bcDaniel Veillard#endif
15695d81903b06418c7d8cc72cf9add81c4026a2f3bcDaniel Veillard
15705d81903b06418c7d8cc72cf9add81c4026a2f3bcDaniel Veillard
15715d81903b06418c7d8cc72cf9add81c4026a2f3bcDaniel Veillard    if (libxml_xmlPythonErrorFuncHandler == NULL) {
1572d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        va_start(ap, msg);
1573007d51eb73cd5c78b676e13aae5bcfce83550a5dDaniel Veillard        vfprintf(stderr, msg, ap);
1574d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        va_end(ap);
15755d81903b06418c7d8cc72cf9add81c4026a2f3bcDaniel Veillard    } else {
1576e6227e0549490b5bf9271ecd2d874a97c3f4852bDaniel Veillard        va_start(ap, msg);
1577ad9fb7c06fea9cf63911c63cc9488ab1d0267005Daniel Veillard        if (vsnprintf(str, 999, msg, ap) >= 998)
1578ad9fb7c06fea9cf63911c63cc9488ab1d0267005Daniel Veillard	    str[999] = 0;
1579e6227e0549490b5bf9271ecd2d874a97c3f4852bDaniel Veillard        va_end(ap);
1580d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard
1581d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        list = PyTuple_New(2);
1582d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        PyTuple_SetItem(list, 0, libxml_xmlPythonErrorFuncCtxt);
1583d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        Py_XINCREF(libxml_xmlPythonErrorFuncCtxt);
1584ad9fb7c06fea9cf63911c63cc9488ab1d0267005Daniel Veillard        message = libxml_charPtrConstWrap(str);
1585d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        PyTuple_SetItem(list, 1, message);
1586d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        result = PyEval_CallObject(libxml_xmlPythonErrorFuncHandler, list);
1587d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        Py_XDECREF(list);
1588d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        Py_XDECREF(result);
15895d81903b06418c7d8cc72cf9add81c4026a2f3bcDaniel Veillard    }
15905d81903b06418c7d8cc72cf9add81c4026a2f3bcDaniel Veillard}
15915d81903b06418c7d8cc72cf9add81c4026a2f3bcDaniel Veillard
15925d81903b06418c7d8cc72cf9add81c4026a2f3bcDaniel Veillardstatic void
1593d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillardlibxml_xmlErrorInitialize(void)
1594d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard{
15955d81903b06418c7d8cc72cf9add81c4026a2f3bcDaniel Veillard#ifdef DEBUG_ERROR
15965d81903b06418c7d8cc72cf9add81c4026a2f3bcDaniel Veillard    printf("libxml_xmlErrorInitialize() called\n");
15975d81903b06418c7d8cc72cf9add81c4026a2f3bcDaniel Veillard#endif
15985d81903b06418c7d8cc72cf9add81c4026a2f3bcDaniel Veillard    xmlSetGenericErrorFunc(NULL, libxml_xmlErrorFuncHandler);
1599781ac8b19bfc10635a8bb83158f874116fd7559eDaniel Veillard    xmlThrDefSetGenericErrorFunc(NULL, libxml_xmlErrorFuncHandler);
16005d81903b06418c7d8cc72cf9add81c4026a2f3bcDaniel Veillard}
16015d81903b06418c7d8cc72cf9add81c4026a2f3bcDaniel Veillard
1602c2664641740126714bb363bd6b5f65f724031c83Daniel Veillardstatic PyObject *
1603d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillardlibxml_xmlRegisterErrorHandler(ATTRIBUTE_UNUSED PyObject * self,
1604d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard                               PyObject * args)
1605d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard{
16065d81903b06418c7d8cc72cf9add81c4026a2f3bcDaniel Veillard    PyObject *py_retval;
16075d81903b06418c7d8cc72cf9add81c4026a2f3bcDaniel Veillard    PyObject *pyobj_f;
16085d81903b06418c7d8cc72cf9add81c4026a2f3bcDaniel Veillard    PyObject *pyobj_ctx;
16095d81903b06418c7d8cc72cf9add81c4026a2f3bcDaniel Veillard
1610d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard    if (!PyArg_ParseTuple
1611d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        (args, (char *) "OO:xmlRegisterErrorHandler", &pyobj_f,
1612d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard         &pyobj_ctx))
1613d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        return (NULL);
16145d81903b06418c7d8cc72cf9add81c4026a2f3bcDaniel Veillard
16155d81903b06418c7d8cc72cf9add81c4026a2f3bcDaniel Veillard#ifdef DEBUG_ERROR
16168e2cc6f2b53f536692f3c8ad8112bb67e0a1a629William M. Brack    printf("libxml_xmlRegisterErrorHandler(%p, %p) called\n", pyobj_ctx,
1617d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard           pyobj_f);
16185d81903b06418c7d8cc72cf9add81c4026a2f3bcDaniel Veillard#endif
16195d81903b06418c7d8cc72cf9add81c4026a2f3bcDaniel Veillard
16205d81903b06418c7d8cc72cf9add81c4026a2f3bcDaniel Veillard    if (libxml_xmlPythonErrorFuncHandler != NULL) {
1621d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        Py_XDECREF(libxml_xmlPythonErrorFuncHandler);
16225d81903b06418c7d8cc72cf9add81c4026a2f3bcDaniel Veillard    }
16235d81903b06418c7d8cc72cf9add81c4026a2f3bcDaniel Veillard    if (libxml_xmlPythonErrorFuncCtxt != NULL) {
1624d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        Py_XDECREF(libxml_xmlPythonErrorFuncCtxt);
16255d81903b06418c7d8cc72cf9add81c4026a2f3bcDaniel Veillard    }
16265d81903b06418c7d8cc72cf9add81c4026a2f3bcDaniel Veillard
16275d81903b06418c7d8cc72cf9add81c4026a2f3bcDaniel Veillard    Py_XINCREF(pyobj_ctx);
16285d81903b06418c7d8cc72cf9add81c4026a2f3bcDaniel Veillard    Py_XINCREF(pyobj_f);
16295d81903b06418c7d8cc72cf9add81c4026a2f3bcDaniel Veillard
16305d81903b06418c7d8cc72cf9add81c4026a2f3bcDaniel Veillard    /* TODO: check f is a function ! */
16315d81903b06418c7d8cc72cf9add81c4026a2f3bcDaniel Veillard    libxml_xmlPythonErrorFuncHandler = pyobj_f;
16325d81903b06418c7d8cc72cf9add81c4026a2f3bcDaniel Veillard    libxml_xmlPythonErrorFuncCtxt = pyobj_ctx;
16335d81903b06418c7d8cc72cf9add81c4026a2f3bcDaniel Veillard
16345d81903b06418c7d8cc72cf9add81c4026a2f3bcDaniel Veillard    py_retval = libxml_intWrap(1);
1635d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard    return (py_retval);
16365d81903b06418c7d8cc72cf9add81c4026a2f3bcDaniel Veillard}
1637d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard
1638e6227e0549490b5bf9271ecd2d874a97c3f4852bDaniel Veillard
1639e6227e0549490b5bf9271ecd2d874a97c3f4852bDaniel Veillard/************************************************************************
1640e6227e0549490b5bf9271ecd2d874a97c3f4852bDaniel Veillard *									*
1641e6227e0549490b5bf9271ecd2d874a97c3f4852bDaniel Veillard *                      Per parserCtxt error handler                    *
1642e6227e0549490b5bf9271ecd2d874a97c3f4852bDaniel Veillard *									*
1643e6227e0549490b5bf9271ecd2d874a97c3f4852bDaniel Veillard ************************************************************************/
1644e6227e0549490b5bf9271ecd2d874a97c3f4852bDaniel Veillard
1645417be3ae08346c6510c28d2042dd42a22a74b331Daniel Veillardtypedef struct
1646417be3ae08346c6510c28d2042dd42a22a74b331Daniel Veillard{
1647417be3ae08346c6510c28d2042dd42a22a74b331Daniel Veillard    PyObject *f;
1648417be3ae08346c6510c28d2042dd42a22a74b331Daniel Veillard    PyObject *arg;
1649417be3ae08346c6510c28d2042dd42a22a74b331Daniel Veillard} xmlParserCtxtPyCtxt;
1650417be3ae08346c6510c28d2042dd42a22a74b331Daniel Veillardtypedef xmlParserCtxtPyCtxt *xmlParserCtxtPyCtxtPtr;
1651417be3ae08346c6510c28d2042dd42a22a74b331Daniel Veillard
1652417be3ae08346c6510c28d2042dd42a22a74b331Daniel Veillardstatic void
1653417be3ae08346c6510c28d2042dd42a22a74b331Daniel Veillardlibxml_xmlParserCtxtGenericErrorFuncHandler(void *ctx, int severity, char *str)
1654e6227e0549490b5bf9271ecd2d874a97c3f4852bDaniel Veillard{
1655e6227e0549490b5bf9271ecd2d874a97c3f4852bDaniel Veillard    PyObject *list;
1656e6227e0549490b5bf9271ecd2d874a97c3f4852bDaniel Veillard    PyObject *result;
1657417be3ae08346c6510c28d2042dd42a22a74b331Daniel Veillard    xmlParserCtxtPtr ctxt;
1658e6227e0549490b5bf9271ecd2d874a97c3f4852bDaniel Veillard    xmlParserCtxtPyCtxtPtr pyCtxt;
1659e6227e0549490b5bf9271ecd2d874a97c3f4852bDaniel Veillard
1660e6227e0549490b5bf9271ecd2d874a97c3f4852bDaniel Veillard#ifdef DEBUG_ERROR
1661850ce9b6584ecc2893632392f1d3ba46fefc13acDaniel Veillard    printf("libxml_xmlParserCtxtGenericErrorFuncHandler(%p, %s, ...) called\n", ctx, str);
1662e6227e0549490b5bf9271ecd2d874a97c3f4852bDaniel Veillard#endif
1663e6227e0549490b5bf9271ecd2d874a97c3f4852bDaniel Veillard
1664417be3ae08346c6510c28d2042dd42a22a74b331Daniel Veillard    ctxt = (xmlParserCtxtPtr)ctx;
1665417be3ae08346c6510c28d2042dd42a22a74b331Daniel Veillard    pyCtxt = (xmlParserCtxtPyCtxtPtr)ctxt->_private;
1666e6227e0549490b5bf9271ecd2d874a97c3f4852bDaniel Veillard
1667417be3ae08346c6510c28d2042dd42a22a74b331Daniel Veillard    list = PyTuple_New(4);
1668417be3ae08346c6510c28d2042dd42a22a74b331Daniel Veillard    PyTuple_SetItem(list, 0, pyCtxt->arg);
1669417be3ae08346c6510c28d2042dd42a22a74b331Daniel Veillard    Py_XINCREF(pyCtxt->arg);
1670417be3ae08346c6510c28d2042dd42a22a74b331Daniel Veillard    PyTuple_SetItem(list, 1, libxml_charPtrWrap(str));
1671417be3ae08346c6510c28d2042dd42a22a74b331Daniel Veillard    PyTuple_SetItem(list, 2, libxml_intWrap(severity));
1672417be3ae08346c6510c28d2042dd42a22a74b331Daniel Veillard    PyTuple_SetItem(list, 3, Py_None);
1673417be3ae08346c6510c28d2042dd42a22a74b331Daniel Veillard    Py_INCREF(Py_None);
1674417be3ae08346c6510c28d2042dd42a22a74b331Daniel Veillard    result = PyEval_CallObject(pyCtxt->f, list);
1675417be3ae08346c6510c28d2042dd42a22a74b331Daniel Veillard    if (result == NULL)
1676417be3ae08346c6510c28d2042dd42a22a74b331Daniel Veillard    {
1677417be3ae08346c6510c28d2042dd42a22a74b331Daniel Veillard	/* TODO: manage for the exception to be propagated... */
1678417be3ae08346c6510c28d2042dd42a22a74b331Daniel Veillard	PyErr_Print();
1679e6227e0549490b5bf9271ecd2d874a97c3f4852bDaniel Veillard    }
1680417be3ae08346c6510c28d2042dd42a22a74b331Daniel Veillard    Py_XDECREF(list);
1681417be3ae08346c6510c28d2042dd42a22a74b331Daniel Veillard    Py_XDECREF(result);
1682417be3ae08346c6510c28d2042dd42a22a74b331Daniel Veillard}
1683417be3ae08346c6510c28d2042dd42a22a74b331Daniel Veillard
1684417be3ae08346c6510c28d2042dd42a22a74b331Daniel Veillardstatic void
1685417be3ae08346c6510c28d2042dd42a22a74b331Daniel Veillardlibxml_xmlParserCtxtErrorFuncHandler(void *ctx, const char *msg, ...)
1686417be3ae08346c6510c28d2042dd42a22a74b331Daniel Veillard{
1687417be3ae08346c6510c28d2042dd42a22a74b331Daniel Veillard    va_list ap;
1688417be3ae08346c6510c28d2042dd42a22a74b331Daniel Veillard
1689417be3ae08346c6510c28d2042dd42a22a74b331Daniel Veillard    va_start(ap, msg);
1690417be3ae08346c6510c28d2042dd42a22a74b331Daniel Veillard    libxml_xmlParserCtxtGenericErrorFuncHandler(ctx,XML_PARSER_SEVERITY_ERROR,libxml_buildMessage(msg,ap));
1691417be3ae08346c6510c28d2042dd42a22a74b331Daniel Veillard    va_end(ap);
1692417be3ae08346c6510c28d2042dd42a22a74b331Daniel Veillard}
1693417be3ae08346c6510c28d2042dd42a22a74b331Daniel Veillard
1694417be3ae08346c6510c28d2042dd42a22a74b331Daniel Veillardstatic void
1695417be3ae08346c6510c28d2042dd42a22a74b331Daniel Veillardlibxml_xmlParserCtxtWarningFuncHandler(void *ctx, const char *msg, ...)
1696417be3ae08346c6510c28d2042dd42a22a74b331Daniel Veillard{
1697417be3ae08346c6510c28d2042dd42a22a74b331Daniel Veillard    va_list ap;
1698417be3ae08346c6510c28d2042dd42a22a74b331Daniel Veillard
1699417be3ae08346c6510c28d2042dd42a22a74b331Daniel Veillard    va_start(ap, msg);
1700417be3ae08346c6510c28d2042dd42a22a74b331Daniel Veillard    libxml_xmlParserCtxtGenericErrorFuncHandler(ctx,XML_PARSER_SEVERITY_WARNING,libxml_buildMessage(msg,ap));
1701417be3ae08346c6510c28d2042dd42a22a74b331Daniel Veillard    va_end(ap);
1702417be3ae08346c6510c28d2042dd42a22a74b331Daniel Veillard}
1703417be3ae08346c6510c28d2042dd42a22a74b331Daniel Veillard
1704417be3ae08346c6510c28d2042dd42a22a74b331Daniel Veillardstatic void
1705417be3ae08346c6510c28d2042dd42a22a74b331Daniel Veillardlibxml_xmlParserCtxtValidityErrorFuncHandler(void *ctx, const char *msg, ...)
1706417be3ae08346c6510c28d2042dd42a22a74b331Daniel Veillard{
1707417be3ae08346c6510c28d2042dd42a22a74b331Daniel Veillard    va_list ap;
1708417be3ae08346c6510c28d2042dd42a22a74b331Daniel Veillard
1709417be3ae08346c6510c28d2042dd42a22a74b331Daniel Veillard    va_start(ap, msg);
1710417be3ae08346c6510c28d2042dd42a22a74b331Daniel Veillard    libxml_xmlParserCtxtGenericErrorFuncHandler(ctx,XML_PARSER_SEVERITY_VALIDITY_ERROR,libxml_buildMessage(msg,ap));
1711417be3ae08346c6510c28d2042dd42a22a74b331Daniel Veillard    va_end(ap);
1712417be3ae08346c6510c28d2042dd42a22a74b331Daniel Veillard}
1713417be3ae08346c6510c28d2042dd42a22a74b331Daniel Veillard
1714417be3ae08346c6510c28d2042dd42a22a74b331Daniel Veillardstatic void
1715417be3ae08346c6510c28d2042dd42a22a74b331Daniel Veillardlibxml_xmlParserCtxtValidityWarningFuncHandler(void *ctx, const char *msg, ...)
1716417be3ae08346c6510c28d2042dd42a22a74b331Daniel Veillard{
1717417be3ae08346c6510c28d2042dd42a22a74b331Daniel Veillard    va_list ap;
1718417be3ae08346c6510c28d2042dd42a22a74b331Daniel Veillard
1719417be3ae08346c6510c28d2042dd42a22a74b331Daniel Veillard    va_start(ap, msg);
1720417be3ae08346c6510c28d2042dd42a22a74b331Daniel Veillard    libxml_xmlParserCtxtGenericErrorFuncHandler(ctx,XML_PARSER_SEVERITY_VALIDITY_WARNING,libxml_buildMessage(msg,ap));
1721417be3ae08346c6510c28d2042dd42a22a74b331Daniel Veillard    va_end(ap);
1722e6227e0549490b5bf9271ecd2d874a97c3f4852bDaniel Veillard}
1723e6227e0549490b5bf9271ecd2d874a97c3f4852bDaniel Veillard
1724c2664641740126714bb363bd6b5f65f724031c83Daniel Veillardstatic PyObject *
1725417be3ae08346c6510c28d2042dd42a22a74b331Daniel Veillardlibxml_xmlParserCtxtSetErrorHandler(ATTRIBUTE_UNUSED PyObject *self, PyObject *args)
1726e6227e0549490b5bf9271ecd2d874a97c3f4852bDaniel Veillard{
1727e6227e0549490b5bf9271ecd2d874a97c3f4852bDaniel Veillard    PyObject *py_retval;
1728e6227e0549490b5bf9271ecd2d874a97c3f4852bDaniel Veillard    xmlParserCtxtPtr ctxt;
1729e4a07e7b77b191d61291d44dffa19b65387e04e4Daniel Veillard    xmlParserCtxtPyCtxtPtr pyCtxt;
1730e6227e0549490b5bf9271ecd2d874a97c3f4852bDaniel Veillard    PyObject *pyobj_ctxt;
1731e6227e0549490b5bf9271ecd2d874a97c3f4852bDaniel Veillard    PyObject *pyobj_f;
1732e6227e0549490b5bf9271ecd2d874a97c3f4852bDaniel Veillard    PyObject *pyobj_arg;
1733e6227e0549490b5bf9271ecd2d874a97c3f4852bDaniel Veillard
1734417be3ae08346c6510c28d2042dd42a22a74b331Daniel Veillard    if (!PyArg_ParseTuple(args, (char *)"OOO:xmlParserCtxtSetErrorHandler",
1735e6227e0549490b5bf9271ecd2d874a97c3f4852bDaniel Veillard		          &pyobj_ctxt, &pyobj_f, &pyobj_arg))
1736e6227e0549490b5bf9271ecd2d874a97c3f4852bDaniel Veillard        return(NULL);
1737e6227e0549490b5bf9271ecd2d874a97c3f4852bDaniel Veillard    ctxt = (xmlParserCtxtPtr) PyparserCtxt_Get(pyobj_ctxt);
1738e6227e0549490b5bf9271ecd2d874a97c3f4852bDaniel Veillard    if (ctxt->_private == NULL) {
1739e6227e0549490b5bf9271ecd2d874a97c3f4852bDaniel Veillard	pyCtxt = xmlMalloc(sizeof(xmlParserCtxtPyCtxt));
1740e6227e0549490b5bf9271ecd2d874a97c3f4852bDaniel Veillard	if (pyCtxt == NULL) {
1741e6227e0549490b5bf9271ecd2d874a97c3f4852bDaniel Veillard	    py_retval = libxml_intWrap(-1);
1742e6227e0549490b5bf9271ecd2d874a97c3f4852bDaniel Veillard	    return(py_retval);
1743e6227e0549490b5bf9271ecd2d874a97c3f4852bDaniel Veillard	}
1744e6227e0549490b5bf9271ecd2d874a97c3f4852bDaniel Veillard	memset(pyCtxt,0,sizeof(xmlParserCtxtPyCtxt));
1745e6227e0549490b5bf9271ecd2d874a97c3f4852bDaniel Veillard	ctxt->_private = pyCtxt;
1746e6227e0549490b5bf9271ecd2d874a97c3f4852bDaniel Veillard    }
1747e4a07e7b77b191d61291d44dffa19b65387e04e4Daniel Veillard    else {
1748417be3ae08346c6510c28d2042dd42a22a74b331Daniel Veillard	pyCtxt = (xmlParserCtxtPyCtxtPtr)ctxt->_private;
1749e4a07e7b77b191d61291d44dffa19b65387e04e4Daniel Veillard    }
1750e6227e0549490b5bf9271ecd2d874a97c3f4852bDaniel Veillard    /* TODO: check f is a function ! */
1751417be3ae08346c6510c28d2042dd42a22a74b331Daniel Veillard    Py_XDECREF(pyCtxt->f);
1752e6227e0549490b5bf9271ecd2d874a97c3f4852bDaniel Veillard    Py_XINCREF(pyobj_f);
1753417be3ae08346c6510c28d2042dd42a22a74b331Daniel Veillard    pyCtxt->f = pyobj_f;
1754417be3ae08346c6510c28d2042dd42a22a74b331Daniel Veillard    Py_XDECREF(pyCtxt->arg);
1755e6227e0549490b5bf9271ecd2d874a97c3f4852bDaniel Veillard    Py_XINCREF(pyobj_arg);
1756417be3ae08346c6510c28d2042dd42a22a74b331Daniel Veillard    pyCtxt->arg = pyobj_arg;
1757e6227e0549490b5bf9271ecd2d874a97c3f4852bDaniel Veillard
1758417be3ae08346c6510c28d2042dd42a22a74b331Daniel Veillard    if (pyobj_f != Py_None) {
1759417be3ae08346c6510c28d2042dd42a22a74b331Daniel Veillard	ctxt->sax->error = libxml_xmlParserCtxtErrorFuncHandler;
1760417be3ae08346c6510c28d2042dd42a22a74b331Daniel Veillard	ctxt->sax->warning = libxml_xmlParserCtxtWarningFuncHandler;
1761417be3ae08346c6510c28d2042dd42a22a74b331Daniel Veillard	ctxt->vctxt.error = libxml_xmlParserCtxtValidityErrorFuncHandler;
1762417be3ae08346c6510c28d2042dd42a22a74b331Daniel Veillard	ctxt->vctxt.warning = libxml_xmlParserCtxtValidityWarningFuncHandler;
1763417be3ae08346c6510c28d2042dd42a22a74b331Daniel Veillard    }
1764417be3ae08346c6510c28d2042dd42a22a74b331Daniel Veillard    else {
1765417be3ae08346c6510c28d2042dd42a22a74b331Daniel Veillard	ctxt->sax->error = xmlParserError;
1766417be3ae08346c6510c28d2042dd42a22a74b331Daniel Veillard	ctxt->vctxt.error = xmlParserValidityError;
1767417be3ae08346c6510c28d2042dd42a22a74b331Daniel Veillard	ctxt->sax->warning = xmlParserWarning;
1768417be3ae08346c6510c28d2042dd42a22a74b331Daniel Veillard	ctxt->vctxt.warning = xmlParserValidityWarning;
1769417be3ae08346c6510c28d2042dd42a22a74b331Daniel Veillard    }
1770e6227e0549490b5bf9271ecd2d874a97c3f4852bDaniel Veillard
1771e6227e0549490b5bf9271ecd2d874a97c3f4852bDaniel Veillard    py_retval = libxml_intWrap(1);
1772e6227e0549490b5bf9271ecd2d874a97c3f4852bDaniel Veillard    return(py_retval);
1773e6227e0549490b5bf9271ecd2d874a97c3f4852bDaniel Veillard}
1774e6227e0549490b5bf9271ecd2d874a97c3f4852bDaniel Veillard
1775c2664641740126714bb363bd6b5f65f724031c83Daniel Veillardstatic PyObject *
1776417be3ae08346c6510c28d2042dd42a22a74b331Daniel Veillardlibxml_xmlParserCtxtGetErrorHandler(ATTRIBUTE_UNUSED PyObject *self, PyObject *args)
1777e6227e0549490b5bf9271ecd2d874a97c3f4852bDaniel Veillard{
1778417be3ae08346c6510c28d2042dd42a22a74b331Daniel Veillard    PyObject *py_retval;
1779417be3ae08346c6510c28d2042dd42a22a74b331Daniel Veillard    xmlParserCtxtPtr ctxt;
1780e6227e0549490b5bf9271ecd2d874a97c3f4852bDaniel Veillard    xmlParserCtxtPyCtxtPtr pyCtxt;
1781417be3ae08346c6510c28d2042dd42a22a74b331Daniel Veillard    PyObject *pyobj_ctxt;
1782e6227e0549490b5bf9271ecd2d874a97c3f4852bDaniel Veillard
1783417be3ae08346c6510c28d2042dd42a22a74b331Daniel Veillard    if (!PyArg_ParseTuple(args, (char *)"O:xmlParserCtxtGetErrorHandler",
1784417be3ae08346c6510c28d2042dd42a22a74b331Daniel Veillard		          &pyobj_ctxt))
1785417be3ae08346c6510c28d2042dd42a22a74b331Daniel Veillard        return(NULL);
1786417be3ae08346c6510c28d2042dd42a22a74b331Daniel Veillard    ctxt = (xmlParserCtxtPtr) PyparserCtxt_Get(pyobj_ctxt);
1787417be3ae08346c6510c28d2042dd42a22a74b331Daniel Veillard    py_retval = PyTuple_New(2);
1788417be3ae08346c6510c28d2042dd42a22a74b331Daniel Veillard    if (ctxt->_private != NULL) {
1789417be3ae08346c6510c28d2042dd42a22a74b331Daniel Veillard	pyCtxt = (xmlParserCtxtPyCtxtPtr)ctxt->_private;
1790e6227e0549490b5bf9271ecd2d874a97c3f4852bDaniel Veillard
1791417be3ae08346c6510c28d2042dd42a22a74b331Daniel Veillard	PyTuple_SetItem(py_retval, 0, pyCtxt->f);
1792417be3ae08346c6510c28d2042dd42a22a74b331Daniel Veillard	Py_XINCREF(pyCtxt->f);
1793417be3ae08346c6510c28d2042dd42a22a74b331Daniel Veillard	PyTuple_SetItem(py_retval, 1, pyCtxt->arg);
1794417be3ae08346c6510c28d2042dd42a22a74b331Daniel Veillard	Py_XINCREF(pyCtxt->arg);
1795417be3ae08346c6510c28d2042dd42a22a74b331Daniel Veillard    }
1796417be3ae08346c6510c28d2042dd42a22a74b331Daniel Veillard    else {
1797417be3ae08346c6510c28d2042dd42a22a74b331Daniel Veillard	/* no python error handler registered */
1798417be3ae08346c6510c28d2042dd42a22a74b331Daniel Veillard	PyTuple_SetItem(py_retval, 0, Py_None);
1799417be3ae08346c6510c28d2042dd42a22a74b331Daniel Veillard	Py_XINCREF(Py_None);
1800417be3ae08346c6510c28d2042dd42a22a74b331Daniel Veillard	PyTuple_SetItem(py_retval, 1, Py_None);
1801417be3ae08346c6510c28d2042dd42a22a74b331Daniel Veillard	Py_XINCREF(Py_None);
1802e6227e0549490b5bf9271ecd2d874a97c3f4852bDaniel Veillard    }
1803417be3ae08346c6510c28d2042dd42a22a74b331Daniel Veillard    return(py_retval);
1804e6227e0549490b5bf9271ecd2d874a97c3f4852bDaniel Veillard}
1805e6227e0549490b5bf9271ecd2d874a97c3f4852bDaniel Veillard
1806c2664641740126714bb363bd6b5f65f724031c83Daniel Veillardstatic PyObject *
1807417be3ae08346c6510c28d2042dd42a22a74b331Daniel Veillardlibxml_xmlFreeParserCtxt(ATTRIBUTE_UNUSED PyObject *self, PyObject *args) {
1808e6227e0549490b5bf9271ecd2d874a97c3f4852bDaniel Veillard    xmlParserCtxtPtr ctxt;
1809e6227e0549490b5bf9271ecd2d874a97c3f4852bDaniel Veillard    PyObject *pyobj_ctxt;
1810417be3ae08346c6510c28d2042dd42a22a74b331Daniel Veillard    xmlParserCtxtPyCtxtPtr pyCtxt;
1811e6227e0549490b5bf9271ecd2d874a97c3f4852bDaniel Veillard
1812417be3ae08346c6510c28d2042dd42a22a74b331Daniel Veillard    if (!PyArg_ParseTuple(args, (char *)"O:xmlFreeParserCtxt", &pyobj_ctxt))
1813e6227e0549490b5bf9271ecd2d874a97c3f4852bDaniel Veillard        return(NULL);
1814e6227e0549490b5bf9271ecd2d874a97c3f4852bDaniel Veillard    ctxt = (xmlParserCtxtPtr) PyparserCtxt_Get(pyobj_ctxt);
1815417be3ae08346c6510c28d2042dd42a22a74b331Daniel Veillard
1816417be3ae08346c6510c28d2042dd42a22a74b331Daniel Veillard    if (ctxt != NULL) {
1817417be3ae08346c6510c28d2042dd42a22a74b331Daniel Veillard	pyCtxt = (xmlParserCtxtPyCtxtPtr)((xmlParserCtxtPtr)ctxt)->_private;
1818417be3ae08346c6510c28d2042dd42a22a74b331Daniel Veillard	if (pyCtxt) {
1819417be3ae08346c6510c28d2042dd42a22a74b331Daniel Veillard	    Py_XDECREF(pyCtxt->f);
1820417be3ae08346c6510c28d2042dd42a22a74b331Daniel Veillard	    Py_XDECREF(pyCtxt->arg);
1821417be3ae08346c6510c28d2042dd42a22a74b331Daniel Veillard	    xmlFree(pyCtxt);
1822e4a07e7b77b191d61291d44dffa19b65387e04e4Daniel Veillard	}
1823417be3ae08346c6510c28d2042dd42a22a74b331Daniel Veillard	xmlFreeParserCtxt(ctxt);
1824e4a07e7b77b191d61291d44dffa19b65387e04e4Daniel Veillard    }
1825e6227e0549490b5bf9271ecd2d874a97c3f4852bDaniel Veillard
1826417be3ae08346c6510c28d2042dd42a22a74b331Daniel Veillard    Py_INCREF(Py_None);
1827417be3ae08346c6510c28d2042dd42a22a74b331Daniel Veillard    return(Py_None);
1828e6227e0549490b5bf9271ecd2d874a97c3f4852bDaniel Veillard}
1829e6227e0549490b5bf9271ecd2d874a97c3f4852bDaniel Veillard
1830850ce9b6584ecc2893632392f1d3ba46fefc13acDaniel Veillard/***
1831850ce9b6584ecc2893632392f1d3ba46fefc13acDaniel Veillard * xmlValidCtxt stuff
1832850ce9b6584ecc2893632392f1d3ba46fefc13acDaniel Veillard */
1833850ce9b6584ecc2893632392f1d3ba46fefc13acDaniel Veillard
1834850ce9b6584ecc2893632392f1d3ba46fefc13acDaniel Veillardtypedef struct
1835850ce9b6584ecc2893632392f1d3ba46fefc13acDaniel Veillard{
1836850ce9b6584ecc2893632392f1d3ba46fefc13acDaniel Veillard    PyObject *warn;
1837850ce9b6584ecc2893632392f1d3ba46fefc13acDaniel Veillard    PyObject *error;
1838850ce9b6584ecc2893632392f1d3ba46fefc13acDaniel Veillard    PyObject *arg;
1839850ce9b6584ecc2893632392f1d3ba46fefc13acDaniel Veillard} xmlValidCtxtPyCtxt;
1840850ce9b6584ecc2893632392f1d3ba46fefc13acDaniel Veillardtypedef xmlValidCtxtPyCtxt *xmlValidCtxtPyCtxtPtr;
1841850ce9b6584ecc2893632392f1d3ba46fefc13acDaniel Veillard
1842850ce9b6584ecc2893632392f1d3ba46fefc13acDaniel Veillardstatic void
1843c31e06cc18ac5d876eb712dcd2d7e2cbe74832a6Stefan Kostlibxml_xmlValidCtxtGenericErrorFuncHandler(void *ctx, ATTRIBUTE_UNUSED int severity, char *str)
1844850ce9b6584ecc2893632392f1d3ba46fefc13acDaniel Veillard{
1845850ce9b6584ecc2893632392f1d3ba46fefc13acDaniel Veillard    PyObject *list;
1846850ce9b6584ecc2893632392f1d3ba46fefc13acDaniel Veillard    PyObject *result;
1847850ce9b6584ecc2893632392f1d3ba46fefc13acDaniel Veillard    xmlValidCtxtPyCtxtPtr pyCtxt;
1848850ce9b6584ecc2893632392f1d3ba46fefc13acDaniel Veillard
1849850ce9b6584ecc2893632392f1d3ba46fefc13acDaniel Veillard#ifdef DEBUG_ERROR
1850850ce9b6584ecc2893632392f1d3ba46fefc13acDaniel Veillard    printf("libxml_xmlValidCtxtGenericErrorFuncHandler(%p, %d, %s, ...) called\n", ctx, severity, str);
1851850ce9b6584ecc2893632392f1d3ba46fefc13acDaniel Veillard#endif
1852850ce9b6584ecc2893632392f1d3ba46fefc13acDaniel Veillard
1853850ce9b6584ecc2893632392f1d3ba46fefc13acDaniel Veillard    pyCtxt = (xmlValidCtxtPyCtxtPtr)ctx;
1854850ce9b6584ecc2893632392f1d3ba46fefc13acDaniel Veillard
1855850ce9b6584ecc2893632392f1d3ba46fefc13acDaniel Veillard    list = PyTuple_New(2);
1856850ce9b6584ecc2893632392f1d3ba46fefc13acDaniel Veillard    PyTuple_SetItem(list, 0, libxml_charPtrWrap(str));
1857850ce9b6584ecc2893632392f1d3ba46fefc13acDaniel Veillard    PyTuple_SetItem(list, 1, pyCtxt->arg);
1858850ce9b6584ecc2893632392f1d3ba46fefc13acDaniel Veillard    Py_XINCREF(pyCtxt->arg);
1859850ce9b6584ecc2893632392f1d3ba46fefc13acDaniel Veillard    result = PyEval_CallObject(pyCtxt->error, list);
1860850ce9b6584ecc2893632392f1d3ba46fefc13acDaniel Veillard    if (result == NULL)
1861850ce9b6584ecc2893632392f1d3ba46fefc13acDaniel Veillard    {
1862850ce9b6584ecc2893632392f1d3ba46fefc13acDaniel Veillard	/* TODO: manage for the exception to be propagated... */
1863850ce9b6584ecc2893632392f1d3ba46fefc13acDaniel Veillard	PyErr_Print();
1864850ce9b6584ecc2893632392f1d3ba46fefc13acDaniel Veillard    }
1865850ce9b6584ecc2893632392f1d3ba46fefc13acDaniel Veillard    Py_XDECREF(list);
1866850ce9b6584ecc2893632392f1d3ba46fefc13acDaniel Veillard    Py_XDECREF(result);
1867850ce9b6584ecc2893632392f1d3ba46fefc13acDaniel Veillard}
1868850ce9b6584ecc2893632392f1d3ba46fefc13acDaniel Veillard
1869850ce9b6584ecc2893632392f1d3ba46fefc13acDaniel Veillardstatic void
1870c31e06cc18ac5d876eb712dcd2d7e2cbe74832a6Stefan Kostlibxml_xmlValidCtxtGenericWarningFuncHandler(void *ctx, ATTRIBUTE_UNUSED int severity, char *str)
1871850ce9b6584ecc2893632392f1d3ba46fefc13acDaniel Veillard{
1872850ce9b6584ecc2893632392f1d3ba46fefc13acDaniel Veillard    PyObject *list;
1873850ce9b6584ecc2893632392f1d3ba46fefc13acDaniel Veillard    PyObject *result;
1874850ce9b6584ecc2893632392f1d3ba46fefc13acDaniel Veillard    xmlValidCtxtPyCtxtPtr pyCtxt;
1875850ce9b6584ecc2893632392f1d3ba46fefc13acDaniel Veillard
1876850ce9b6584ecc2893632392f1d3ba46fefc13acDaniel Veillard#ifdef DEBUG_ERROR
1877850ce9b6584ecc2893632392f1d3ba46fefc13acDaniel Veillard    printf("libxml_xmlValidCtxtGenericWarningFuncHandler(%p, %d, %s, ...) called\n", ctx, severity, str);
1878850ce9b6584ecc2893632392f1d3ba46fefc13acDaniel Veillard#endif
1879850ce9b6584ecc2893632392f1d3ba46fefc13acDaniel Veillard
1880850ce9b6584ecc2893632392f1d3ba46fefc13acDaniel Veillard    pyCtxt = (xmlValidCtxtPyCtxtPtr)ctx;
1881850ce9b6584ecc2893632392f1d3ba46fefc13acDaniel Veillard
1882850ce9b6584ecc2893632392f1d3ba46fefc13acDaniel Veillard    list = PyTuple_New(2);
1883850ce9b6584ecc2893632392f1d3ba46fefc13acDaniel Veillard    PyTuple_SetItem(list, 0, libxml_charPtrWrap(str));
1884850ce9b6584ecc2893632392f1d3ba46fefc13acDaniel Veillard    PyTuple_SetItem(list, 1, pyCtxt->arg);
1885850ce9b6584ecc2893632392f1d3ba46fefc13acDaniel Veillard    Py_XINCREF(pyCtxt->arg);
1886850ce9b6584ecc2893632392f1d3ba46fefc13acDaniel Veillard    result = PyEval_CallObject(pyCtxt->warn, list);
1887850ce9b6584ecc2893632392f1d3ba46fefc13acDaniel Veillard    if (result == NULL)
1888850ce9b6584ecc2893632392f1d3ba46fefc13acDaniel Veillard    {
1889850ce9b6584ecc2893632392f1d3ba46fefc13acDaniel Veillard	/* TODO: manage for the exception to be propagated... */
1890850ce9b6584ecc2893632392f1d3ba46fefc13acDaniel Veillard	PyErr_Print();
1891850ce9b6584ecc2893632392f1d3ba46fefc13acDaniel Veillard    }
1892850ce9b6584ecc2893632392f1d3ba46fefc13acDaniel Veillard    Py_XDECREF(list);
1893850ce9b6584ecc2893632392f1d3ba46fefc13acDaniel Veillard    Py_XDECREF(result);
1894850ce9b6584ecc2893632392f1d3ba46fefc13acDaniel Veillard}
1895850ce9b6584ecc2893632392f1d3ba46fefc13acDaniel Veillard
1896850ce9b6584ecc2893632392f1d3ba46fefc13acDaniel Veillardstatic void
1897850ce9b6584ecc2893632392f1d3ba46fefc13acDaniel Veillardlibxml_xmlValidCtxtErrorFuncHandler(void *ctx, const char *msg, ...)
1898850ce9b6584ecc2893632392f1d3ba46fefc13acDaniel Veillard{
1899850ce9b6584ecc2893632392f1d3ba46fefc13acDaniel Veillard    va_list ap;
1900850ce9b6584ecc2893632392f1d3ba46fefc13acDaniel Veillard
1901850ce9b6584ecc2893632392f1d3ba46fefc13acDaniel Veillard    va_start(ap, msg);
1902850ce9b6584ecc2893632392f1d3ba46fefc13acDaniel Veillard    libxml_xmlValidCtxtGenericErrorFuncHandler(ctx,XML_PARSER_SEVERITY_VALIDITY_ERROR,libxml_buildMessage(msg,ap));
1903850ce9b6584ecc2893632392f1d3ba46fefc13acDaniel Veillard    va_end(ap);
1904850ce9b6584ecc2893632392f1d3ba46fefc13acDaniel Veillard}
1905850ce9b6584ecc2893632392f1d3ba46fefc13acDaniel Veillard
1906850ce9b6584ecc2893632392f1d3ba46fefc13acDaniel Veillardstatic void
1907850ce9b6584ecc2893632392f1d3ba46fefc13acDaniel Veillardlibxml_xmlValidCtxtWarningFuncHandler(void *ctx, const char *msg, ...)
1908850ce9b6584ecc2893632392f1d3ba46fefc13acDaniel Veillard{
1909850ce9b6584ecc2893632392f1d3ba46fefc13acDaniel Veillard    va_list ap;
1910850ce9b6584ecc2893632392f1d3ba46fefc13acDaniel Veillard
1911850ce9b6584ecc2893632392f1d3ba46fefc13acDaniel Veillard    va_start(ap, msg);
1912850ce9b6584ecc2893632392f1d3ba46fefc13acDaniel Veillard    libxml_xmlValidCtxtGenericWarningFuncHandler(ctx,XML_PARSER_SEVERITY_VALIDITY_WARNING,libxml_buildMessage(msg,ap));
1913850ce9b6584ecc2893632392f1d3ba46fefc13acDaniel Veillard    va_end(ap);
1914850ce9b6584ecc2893632392f1d3ba46fefc13acDaniel Veillard}
1915850ce9b6584ecc2893632392f1d3ba46fefc13acDaniel Veillard
1916850ce9b6584ecc2893632392f1d3ba46fefc13acDaniel Veillardstatic PyObject *
1917850ce9b6584ecc2893632392f1d3ba46fefc13acDaniel Veillardlibxml_xmlSetValidErrors(ATTRIBUTE_UNUSED PyObject * self, PyObject * args)
1918850ce9b6584ecc2893632392f1d3ba46fefc13acDaniel Veillard{
1919850ce9b6584ecc2893632392f1d3ba46fefc13acDaniel Veillard    PyObject *py_retval;
1920850ce9b6584ecc2893632392f1d3ba46fefc13acDaniel Veillard    PyObject *pyobj_error;
1921850ce9b6584ecc2893632392f1d3ba46fefc13acDaniel Veillard    PyObject *pyobj_warn;
1922850ce9b6584ecc2893632392f1d3ba46fefc13acDaniel Veillard    PyObject *pyobj_ctx;
1923850ce9b6584ecc2893632392f1d3ba46fefc13acDaniel Veillard    PyObject *pyobj_arg = Py_None;
1924850ce9b6584ecc2893632392f1d3ba46fefc13acDaniel Veillard    xmlValidCtxtPtr ctxt;
1925850ce9b6584ecc2893632392f1d3ba46fefc13acDaniel Veillard    xmlValidCtxtPyCtxtPtr pyCtxt;
1926850ce9b6584ecc2893632392f1d3ba46fefc13acDaniel Veillard
1927850ce9b6584ecc2893632392f1d3ba46fefc13acDaniel Veillard    if (!PyArg_ParseTuple
1928850ce9b6584ecc2893632392f1d3ba46fefc13acDaniel Veillard        (args, (char *) "OOO|O:xmlSetValidErrors", &pyobj_ctx, &pyobj_error, &pyobj_warn, &pyobj_arg))
1929850ce9b6584ecc2893632392f1d3ba46fefc13acDaniel Veillard        return (NULL);
1930850ce9b6584ecc2893632392f1d3ba46fefc13acDaniel Veillard
1931850ce9b6584ecc2893632392f1d3ba46fefc13acDaniel Veillard#ifdef DEBUG_ERROR
1932850ce9b6584ecc2893632392f1d3ba46fefc13acDaniel Veillard    printf("libxml_xmlSetValidErrors(%p, %p, %p) called\n", pyobj_ctx, pyobj_error, pyobj_warn);
1933850ce9b6584ecc2893632392f1d3ba46fefc13acDaniel Veillard#endif
1934850ce9b6584ecc2893632392f1d3ba46fefc13acDaniel Veillard
1935850ce9b6584ecc2893632392f1d3ba46fefc13acDaniel Veillard    ctxt = PyValidCtxt_Get(pyobj_ctx);
1936850ce9b6584ecc2893632392f1d3ba46fefc13acDaniel Veillard    pyCtxt = xmlMalloc(sizeof(xmlValidCtxtPyCtxt));
1937850ce9b6584ecc2893632392f1d3ba46fefc13acDaniel Veillard    if (pyCtxt == NULL) {
1938850ce9b6584ecc2893632392f1d3ba46fefc13acDaniel Veillard            py_retval = libxml_intWrap(-1);
1939850ce9b6584ecc2893632392f1d3ba46fefc13acDaniel Veillard            return(py_retval);
1940850ce9b6584ecc2893632392f1d3ba46fefc13acDaniel Veillard    }
1941850ce9b6584ecc2893632392f1d3ba46fefc13acDaniel Veillard    memset(pyCtxt, 0, sizeof(xmlValidCtxtPyCtxt));
1942850ce9b6584ecc2893632392f1d3ba46fefc13acDaniel Veillard
1943850ce9b6584ecc2893632392f1d3ba46fefc13acDaniel Veillard
1944850ce9b6584ecc2893632392f1d3ba46fefc13acDaniel Veillard    /* TODO: check warn and error is a function ! */
1945850ce9b6584ecc2893632392f1d3ba46fefc13acDaniel Veillard    Py_XDECREF(pyCtxt->error);
1946850ce9b6584ecc2893632392f1d3ba46fefc13acDaniel Veillard    Py_XINCREF(pyobj_error);
1947850ce9b6584ecc2893632392f1d3ba46fefc13acDaniel Veillard    pyCtxt->error = pyobj_error;
1948850ce9b6584ecc2893632392f1d3ba46fefc13acDaniel Veillard
1949850ce9b6584ecc2893632392f1d3ba46fefc13acDaniel Veillard    Py_XDECREF(pyCtxt->warn);
1950850ce9b6584ecc2893632392f1d3ba46fefc13acDaniel Veillard    Py_XINCREF(pyobj_warn);
1951850ce9b6584ecc2893632392f1d3ba46fefc13acDaniel Veillard    pyCtxt->warn = pyobj_warn;
1952850ce9b6584ecc2893632392f1d3ba46fefc13acDaniel Veillard
1953850ce9b6584ecc2893632392f1d3ba46fefc13acDaniel Veillard    Py_XDECREF(pyCtxt->arg);
1954850ce9b6584ecc2893632392f1d3ba46fefc13acDaniel Veillard    Py_XINCREF(pyobj_arg);
1955850ce9b6584ecc2893632392f1d3ba46fefc13acDaniel Veillard    pyCtxt->arg = pyobj_arg;
1956850ce9b6584ecc2893632392f1d3ba46fefc13acDaniel Veillard
1957850ce9b6584ecc2893632392f1d3ba46fefc13acDaniel Veillard    ctxt->error = libxml_xmlValidCtxtErrorFuncHandler;
1958850ce9b6584ecc2893632392f1d3ba46fefc13acDaniel Veillard    ctxt->warning = libxml_xmlValidCtxtWarningFuncHandler;
1959850ce9b6584ecc2893632392f1d3ba46fefc13acDaniel Veillard    ctxt->userData = pyCtxt;
1960850ce9b6584ecc2893632392f1d3ba46fefc13acDaniel Veillard
1961850ce9b6584ecc2893632392f1d3ba46fefc13acDaniel Veillard    py_retval = libxml_intWrap(1);
1962850ce9b6584ecc2893632392f1d3ba46fefc13acDaniel Veillard    return (py_retval);
1963850ce9b6584ecc2893632392f1d3ba46fefc13acDaniel Veillard}
1964850ce9b6584ecc2893632392f1d3ba46fefc13acDaniel Veillard
196525c90c589b256f0925f081198c1525134a491e31Daniel Veillard
1966bb8502c0ef2af706fbdff69119e994e40da64a88Daniel Veillardstatic PyObject *
196725c90c589b256f0925f081198c1525134a491e31Daniel Veillardlibxml_xmlFreeValidCtxt(PyObject *self ATTRIBUTE_UNUSED, PyObject *args) {
196825c90c589b256f0925f081198c1525134a491e31Daniel Veillard    xmlValidCtxtPtr cur;
196925c90c589b256f0925f081198c1525134a491e31Daniel Veillard    xmlValidCtxtPyCtxtPtr pyCtxt;
197025c90c589b256f0925f081198c1525134a491e31Daniel Veillard    PyObject *pyobj_cur;
197125c90c589b256f0925f081198c1525134a491e31Daniel Veillard
197225c90c589b256f0925f081198c1525134a491e31Daniel Veillard    if (!PyArg_ParseTuple(args, (char *)"O:xmlFreeValidCtxt", &pyobj_cur))
197325c90c589b256f0925f081198c1525134a491e31Daniel Veillard        return(NULL);
197425c90c589b256f0925f081198c1525134a491e31Daniel Veillard    cur = (xmlValidCtxtPtr) PyValidCtxt_Get(pyobj_cur);
197525c90c589b256f0925f081198c1525134a491e31Daniel Veillard
197625c90c589b256f0925f081198c1525134a491e31Daniel Veillard    pyCtxt = (xmlValidCtxtPyCtxtPtr)(cur->userData);
197725c90c589b256f0925f081198c1525134a491e31Daniel Veillard    if (pyCtxt != NULL)
197825c90c589b256f0925f081198c1525134a491e31Daniel Veillard    {
197925c90c589b256f0925f081198c1525134a491e31Daniel Veillard            Py_XDECREF(pyCtxt->error);
198025c90c589b256f0925f081198c1525134a491e31Daniel Veillard            Py_XDECREF(pyCtxt->warn);
198125c90c589b256f0925f081198c1525134a491e31Daniel Veillard            Py_XDECREF(pyCtxt->arg);
198225c90c589b256f0925f081198c1525134a491e31Daniel Veillard            xmlFree(pyCtxt);
198325c90c589b256f0925f081198c1525134a491e31Daniel Veillard    }
198425c90c589b256f0925f081198c1525134a491e31Daniel Veillard
198525c90c589b256f0925f081198c1525134a491e31Daniel Veillard    xmlFreeValidCtxt(cur);
198625c90c589b256f0925f081198c1525134a491e31Daniel Veillard    Py_INCREF(Py_None);
198725c90c589b256f0925f081198c1525134a491e31Daniel Veillard    return(Py_None);
198825c90c589b256f0925f081198c1525134a491e31Daniel Veillard}
198925c90c589b256f0925f081198c1525134a491e31Daniel Veillard
1990438ebbd59af78c436397ae488e42aeca5cad7542Daniel Veillard#ifdef LIBXML_READER_ENABLED
1991a7340c830e4bddd86201cfdb97ac81e30b0dee62Daniel Veillard/************************************************************************
1992a7340c830e4bddd86201cfdb97ac81e30b0dee62Daniel Veillard *									*
199326f70269c80140a7fb8a7aae9ef09c95efa98e70Daniel Veillard *                      Per xmlTextReader error handler                 *
199426f70269c80140a7fb8a7aae9ef09c95efa98e70Daniel Veillard *									*
199526f70269c80140a7fb8a7aae9ef09c95efa98e70Daniel Veillard ************************************************************************/
199626f70269c80140a7fb8a7aae9ef09c95efa98e70Daniel Veillard
199726f70269c80140a7fb8a7aae9ef09c95efa98e70Daniel Veillardtypedef struct
199826f70269c80140a7fb8a7aae9ef09c95efa98e70Daniel Veillard{
199926f70269c80140a7fb8a7aae9ef09c95efa98e70Daniel Veillard    PyObject *f;
200026f70269c80140a7fb8a7aae9ef09c95efa98e70Daniel Veillard    PyObject *arg;
200126f70269c80140a7fb8a7aae9ef09c95efa98e70Daniel Veillard} xmlTextReaderPyCtxt;
200226f70269c80140a7fb8a7aae9ef09c95efa98e70Daniel Veillardtypedef xmlTextReaderPyCtxt *xmlTextReaderPyCtxtPtr;
200326f70269c80140a7fb8a7aae9ef09c95efa98e70Daniel Veillard
200426f70269c80140a7fb8a7aae9ef09c95efa98e70Daniel Veillardstatic void
200526f70269c80140a7fb8a7aae9ef09c95efa98e70Daniel Veillardlibxml_xmlTextReaderErrorCallback(void *arg,
200626f70269c80140a7fb8a7aae9ef09c95efa98e70Daniel Veillard				  const char *msg,
2007417be3ae08346c6510c28d2042dd42a22a74b331Daniel Veillard				  int severity,
2008417be3ae08346c6510c28d2042dd42a22a74b331Daniel Veillard				  xmlTextReaderLocatorPtr locator)
200926f70269c80140a7fb8a7aae9ef09c95efa98e70Daniel Veillard{
201026f70269c80140a7fb8a7aae9ef09c95efa98e70Daniel Veillard    xmlTextReaderPyCtxt *pyCtxt = (xmlTextReaderPyCtxt *)arg;
201126f70269c80140a7fb8a7aae9ef09c95efa98e70Daniel Veillard    PyObject *list;
201226f70269c80140a7fb8a7aae9ef09c95efa98e70Daniel Veillard    PyObject *result;
201326f70269c80140a7fb8a7aae9ef09c95efa98e70Daniel Veillard
2014417be3ae08346c6510c28d2042dd42a22a74b331Daniel Veillard    list = PyTuple_New(4);
201526f70269c80140a7fb8a7aae9ef09c95efa98e70Daniel Veillard    PyTuple_SetItem(list, 0, pyCtxt->arg);
201626f70269c80140a7fb8a7aae9ef09c95efa98e70Daniel Veillard    Py_XINCREF(pyCtxt->arg);
201726f70269c80140a7fb8a7aae9ef09c95efa98e70Daniel Veillard    PyTuple_SetItem(list, 1, libxml_charPtrConstWrap(msg));
2018417be3ae08346c6510c28d2042dd42a22a74b331Daniel Veillard    PyTuple_SetItem(list, 2, libxml_intWrap(severity));
2019417be3ae08346c6510c28d2042dd42a22a74b331Daniel Veillard    PyTuple_SetItem(list, 3, libxml_xmlTextReaderLocatorPtrWrap(locator));
202026f70269c80140a7fb8a7aae9ef09c95efa98e70Daniel Veillard    result = PyEval_CallObject(pyCtxt->f, list);
202126f70269c80140a7fb8a7aae9ef09c95efa98e70Daniel Veillard    if (result == NULL)
202226f70269c80140a7fb8a7aae9ef09c95efa98e70Daniel Veillard    {
2023417be3ae08346c6510c28d2042dd42a22a74b331Daniel Veillard	/* TODO: manage for the exception to be propagated... */
202426f70269c80140a7fb8a7aae9ef09c95efa98e70Daniel Veillard	PyErr_Print();
202526f70269c80140a7fb8a7aae9ef09c95efa98e70Daniel Veillard    }
202626f70269c80140a7fb8a7aae9ef09c95efa98e70Daniel Veillard    Py_XDECREF(list);
202726f70269c80140a7fb8a7aae9ef09c95efa98e70Daniel Veillard    Py_XDECREF(result);
202826f70269c80140a7fb8a7aae9ef09c95efa98e70Daniel Veillard}
202926f70269c80140a7fb8a7aae9ef09c95efa98e70Daniel Veillard
2030c2664641740126714bb363bd6b5f65f724031c83Daniel Veillardstatic PyObject *
203126f70269c80140a7fb8a7aae9ef09c95efa98e70Daniel Veillardlibxml_xmlTextReaderSetErrorHandler(ATTRIBUTE_UNUSED PyObject *self, PyObject *args)
203226f70269c80140a7fb8a7aae9ef09c95efa98e70Daniel Veillard{
203326f70269c80140a7fb8a7aae9ef09c95efa98e70Daniel Veillard    xmlTextReaderPtr reader;
203426f70269c80140a7fb8a7aae9ef09c95efa98e70Daniel Veillard    xmlTextReaderPyCtxtPtr pyCtxt;
203526f70269c80140a7fb8a7aae9ef09c95efa98e70Daniel Veillard    xmlTextReaderErrorFunc f;
203626f70269c80140a7fb8a7aae9ef09c95efa98e70Daniel Veillard    void *arg;
203726f70269c80140a7fb8a7aae9ef09c95efa98e70Daniel Veillard    PyObject *pyobj_reader;
203826f70269c80140a7fb8a7aae9ef09c95efa98e70Daniel Veillard    PyObject *pyobj_f;
203926f70269c80140a7fb8a7aae9ef09c95efa98e70Daniel Veillard    PyObject *pyobj_arg;
204026f70269c80140a7fb8a7aae9ef09c95efa98e70Daniel Veillard    PyObject *py_retval;
204126f70269c80140a7fb8a7aae9ef09c95efa98e70Daniel Veillard
204226f70269c80140a7fb8a7aae9ef09c95efa98e70Daniel Veillard    if (!PyArg_ParseTuple(args, (char *)"OOO:xmlTextReaderSetErrorHandler", &pyobj_reader, &pyobj_f, &pyobj_arg))
204326f70269c80140a7fb8a7aae9ef09c95efa98e70Daniel Veillard        return(NULL);
204426f70269c80140a7fb8a7aae9ef09c95efa98e70Daniel Veillard    reader = (xmlTextReaderPtr) PyxmlTextReader_Get(pyobj_reader);
204526f70269c80140a7fb8a7aae9ef09c95efa98e70Daniel Veillard    /* clear previous error handler */
204626f70269c80140a7fb8a7aae9ef09c95efa98e70Daniel Veillard    xmlTextReaderGetErrorHandler(reader,&f,&arg);
204726f70269c80140a7fb8a7aae9ef09c95efa98e70Daniel Veillard    if (arg != NULL) {
2048c2664641740126714bb363bd6b5f65f724031c83Daniel Veillard	if (f == (xmlTextReaderErrorFunc) libxml_xmlTextReaderErrorCallback) {
204926f70269c80140a7fb8a7aae9ef09c95efa98e70Daniel Veillard	    /* ok, it's our error handler! */
205026f70269c80140a7fb8a7aae9ef09c95efa98e70Daniel Veillard	    pyCtxt = (xmlTextReaderPyCtxtPtr)arg;
205126f70269c80140a7fb8a7aae9ef09c95efa98e70Daniel Veillard	    Py_XDECREF(pyCtxt->f);
205226f70269c80140a7fb8a7aae9ef09c95efa98e70Daniel Veillard	    Py_XDECREF(pyCtxt->arg);
205326f70269c80140a7fb8a7aae9ef09c95efa98e70Daniel Veillard	    xmlFree(pyCtxt);
205426f70269c80140a7fb8a7aae9ef09c95efa98e70Daniel Veillard	}
205526f70269c80140a7fb8a7aae9ef09c95efa98e70Daniel Veillard	else {
205626f70269c80140a7fb8a7aae9ef09c95efa98e70Daniel Veillard	    /*
205726f70269c80140a7fb8a7aae9ef09c95efa98e70Daniel Veillard	     * there already an arg, and it's not ours,
205826f70269c80140a7fb8a7aae9ef09c95efa98e70Daniel Veillard	     * there is definitely something wrong going on here...
205926f70269c80140a7fb8a7aae9ef09c95efa98e70Daniel Veillard	     * we don't know how to free it, so we bail out...
206026f70269c80140a7fb8a7aae9ef09c95efa98e70Daniel Veillard	     */
206126f70269c80140a7fb8a7aae9ef09c95efa98e70Daniel Veillard	    py_retval = libxml_intWrap(-1);
206226f70269c80140a7fb8a7aae9ef09c95efa98e70Daniel Veillard	    return(py_retval);
206326f70269c80140a7fb8a7aae9ef09c95efa98e70Daniel Veillard	}
206426f70269c80140a7fb8a7aae9ef09c95efa98e70Daniel Veillard    }
206526f70269c80140a7fb8a7aae9ef09c95efa98e70Daniel Veillard    xmlTextReaderSetErrorHandler(reader,NULL,NULL);
206626f70269c80140a7fb8a7aae9ef09c95efa98e70Daniel Veillard    /* set new error handler */
206726f70269c80140a7fb8a7aae9ef09c95efa98e70Daniel Veillard    if (pyobj_f != Py_None)
206826f70269c80140a7fb8a7aae9ef09c95efa98e70Daniel Veillard    {
206926f70269c80140a7fb8a7aae9ef09c95efa98e70Daniel Veillard	pyCtxt = (xmlTextReaderPyCtxtPtr)xmlMalloc(sizeof(xmlTextReaderPyCtxt));
207026f70269c80140a7fb8a7aae9ef09c95efa98e70Daniel Veillard	if (pyCtxt == NULL) {
207126f70269c80140a7fb8a7aae9ef09c95efa98e70Daniel Veillard	    py_retval = libxml_intWrap(-1);
207226f70269c80140a7fb8a7aae9ef09c95efa98e70Daniel Veillard	    return(py_retval);
207326f70269c80140a7fb8a7aae9ef09c95efa98e70Daniel Veillard	}
207426f70269c80140a7fb8a7aae9ef09c95efa98e70Daniel Veillard	Py_XINCREF(pyobj_f);
207526f70269c80140a7fb8a7aae9ef09c95efa98e70Daniel Veillard	pyCtxt->f = pyobj_f;
207626f70269c80140a7fb8a7aae9ef09c95efa98e70Daniel Veillard	Py_XINCREF(pyobj_arg);
207726f70269c80140a7fb8a7aae9ef09c95efa98e70Daniel Veillard	pyCtxt->arg = pyobj_arg;
2078c2664641740126714bb363bd6b5f65f724031c83Daniel Veillard	xmlTextReaderSetErrorHandler(reader,
2079c2664641740126714bb363bd6b5f65f724031c83Daniel Veillard	    (xmlTextReaderErrorFunc) libxml_xmlTextReaderErrorCallback,
2080c2664641740126714bb363bd6b5f65f724031c83Daniel Veillard	                             pyCtxt);
208126f70269c80140a7fb8a7aae9ef09c95efa98e70Daniel Veillard    }
208226f70269c80140a7fb8a7aae9ef09c95efa98e70Daniel Veillard
208326f70269c80140a7fb8a7aae9ef09c95efa98e70Daniel Veillard    py_retval = libxml_intWrap(1);
208426f70269c80140a7fb8a7aae9ef09c95efa98e70Daniel Veillard    return(py_retval);
208526f70269c80140a7fb8a7aae9ef09c95efa98e70Daniel Veillard}
208626f70269c80140a7fb8a7aae9ef09c95efa98e70Daniel Veillard
2087c2664641740126714bb363bd6b5f65f724031c83Daniel Veillardstatic PyObject *
208826f70269c80140a7fb8a7aae9ef09c95efa98e70Daniel Veillardlibxml_xmlTextReaderGetErrorHandler(ATTRIBUTE_UNUSED PyObject *self, PyObject *args)
208926f70269c80140a7fb8a7aae9ef09c95efa98e70Daniel Veillard{
209026f70269c80140a7fb8a7aae9ef09c95efa98e70Daniel Veillard    xmlTextReaderPtr reader;
209126f70269c80140a7fb8a7aae9ef09c95efa98e70Daniel Veillard    xmlTextReaderPyCtxtPtr pyCtxt;
209226f70269c80140a7fb8a7aae9ef09c95efa98e70Daniel Veillard    xmlTextReaderErrorFunc f;
209326f70269c80140a7fb8a7aae9ef09c95efa98e70Daniel Veillard    void *arg;
209426f70269c80140a7fb8a7aae9ef09c95efa98e70Daniel Veillard    PyObject *pyobj_reader;
209526f70269c80140a7fb8a7aae9ef09c95efa98e70Daniel Veillard    PyObject *py_retval;
209626f70269c80140a7fb8a7aae9ef09c95efa98e70Daniel Veillard
209726f70269c80140a7fb8a7aae9ef09c95efa98e70Daniel Veillard    if (!PyArg_ParseTuple(args, (char *)"O:xmlTextReaderSetErrorHandler", &pyobj_reader))
209826f70269c80140a7fb8a7aae9ef09c95efa98e70Daniel Veillard        return(NULL);
209926f70269c80140a7fb8a7aae9ef09c95efa98e70Daniel Veillard    reader = (xmlTextReaderPtr) PyxmlTextReader_Get(pyobj_reader);
210026f70269c80140a7fb8a7aae9ef09c95efa98e70Daniel Veillard    xmlTextReaderGetErrorHandler(reader,&f,&arg);
210126f70269c80140a7fb8a7aae9ef09c95efa98e70Daniel Veillard    py_retval = PyTuple_New(2);
2102c2664641740126714bb363bd6b5f65f724031c83Daniel Veillard    if (f == (xmlTextReaderErrorFunc)libxml_xmlTextReaderErrorCallback) {
210326f70269c80140a7fb8a7aae9ef09c95efa98e70Daniel Veillard	/* ok, it's our error handler! */
210426f70269c80140a7fb8a7aae9ef09c95efa98e70Daniel Veillard	pyCtxt = (xmlTextReaderPyCtxtPtr)arg;
210526f70269c80140a7fb8a7aae9ef09c95efa98e70Daniel Veillard	PyTuple_SetItem(py_retval, 0, pyCtxt->f);
210626f70269c80140a7fb8a7aae9ef09c95efa98e70Daniel Veillard	Py_XINCREF(pyCtxt->f);
210726f70269c80140a7fb8a7aae9ef09c95efa98e70Daniel Veillard	PyTuple_SetItem(py_retval, 1, pyCtxt->arg);
210826f70269c80140a7fb8a7aae9ef09c95efa98e70Daniel Veillard	Py_XINCREF(pyCtxt->arg);
210926f70269c80140a7fb8a7aae9ef09c95efa98e70Daniel Veillard    }
211026f70269c80140a7fb8a7aae9ef09c95efa98e70Daniel Veillard    else
211126f70269c80140a7fb8a7aae9ef09c95efa98e70Daniel Veillard    {
211226f70269c80140a7fb8a7aae9ef09c95efa98e70Daniel Veillard	/* f is null or it's not our error handler */
211326f70269c80140a7fb8a7aae9ef09c95efa98e70Daniel Veillard	PyTuple_SetItem(py_retval, 0, Py_None);
211426f70269c80140a7fb8a7aae9ef09c95efa98e70Daniel Veillard	Py_XINCREF(Py_None);
211526f70269c80140a7fb8a7aae9ef09c95efa98e70Daniel Veillard	PyTuple_SetItem(py_retval, 1, Py_None);
211626f70269c80140a7fb8a7aae9ef09c95efa98e70Daniel Veillard	Py_XINCREF(Py_None);
211726f70269c80140a7fb8a7aae9ef09c95efa98e70Daniel Veillard    }
211826f70269c80140a7fb8a7aae9ef09c95efa98e70Daniel Veillard    return(py_retval);
211926f70269c80140a7fb8a7aae9ef09c95efa98e70Daniel Veillard}
212026f70269c80140a7fb8a7aae9ef09c95efa98e70Daniel Veillard
2121c2664641740126714bb363bd6b5f65f724031c83Daniel Veillardstatic PyObject *
212226f70269c80140a7fb8a7aae9ef09c95efa98e70Daniel Veillardlibxml_xmlFreeTextReader(ATTRIBUTE_UNUSED PyObject *self, PyObject *args) {
212326f70269c80140a7fb8a7aae9ef09c95efa98e70Daniel Veillard    xmlTextReaderPtr reader;
212426f70269c80140a7fb8a7aae9ef09c95efa98e70Daniel Veillard    PyObject *pyobj_reader;
212526f70269c80140a7fb8a7aae9ef09c95efa98e70Daniel Veillard    xmlTextReaderPyCtxtPtr pyCtxt;
212626f70269c80140a7fb8a7aae9ef09c95efa98e70Daniel Veillard    xmlTextReaderErrorFunc f;
212726f70269c80140a7fb8a7aae9ef09c95efa98e70Daniel Veillard    void *arg;
212826f70269c80140a7fb8a7aae9ef09c95efa98e70Daniel Veillard
2129157fee019d02e1ba4ed377ea21172b67f479241bDaniel Veillard    if (!PyArg_ParseTuple(args, (char *)"O:xmlFreeTextReader", &pyobj_reader))
2130157fee019d02e1ba4ed377ea21172b67f479241bDaniel Veillard        return(NULL);
2131157fee019d02e1ba4ed377ea21172b67f479241bDaniel Veillard    if (!PyCObject_Check(pyobj_reader)) {
2132bb3ba326e6ba5b661ca51aab53b17f519eda5924Daniel Veillard	Py_INCREF(Py_None);
2133bb3ba326e6ba5b661ca51aab53b17f519eda5924Daniel Veillard	return(Py_None);
2134bb3ba326e6ba5b661ca51aab53b17f519eda5924Daniel Veillard    }
213526f70269c80140a7fb8a7aae9ef09c95efa98e70Daniel Veillard    reader = (xmlTextReaderPtr) PyxmlTextReader_Get(pyobj_reader);
2136bb3ba326e6ba5b661ca51aab53b17f519eda5924Daniel Veillard    if (reader == NULL) {
2137bb3ba326e6ba5b661ca51aab53b17f519eda5924Daniel Veillard	Py_INCREF(Py_None);
2138bb3ba326e6ba5b661ca51aab53b17f519eda5924Daniel Veillard	return(Py_None);
2139bb3ba326e6ba5b661ca51aab53b17f519eda5924Daniel Veillard    }
214026f70269c80140a7fb8a7aae9ef09c95efa98e70Daniel Veillard
214126f70269c80140a7fb8a7aae9ef09c95efa98e70Daniel Veillard    xmlTextReaderGetErrorHandler(reader,&f,&arg);
214226f70269c80140a7fb8a7aae9ef09c95efa98e70Daniel Veillard    if (arg != NULL) {
2143c2664641740126714bb363bd6b5f65f724031c83Daniel Veillard	if (f == (xmlTextReaderErrorFunc) libxml_xmlTextReaderErrorCallback) {
214426f70269c80140a7fb8a7aae9ef09c95efa98e70Daniel Veillard	    /* ok, it's our error handler! */
214526f70269c80140a7fb8a7aae9ef09c95efa98e70Daniel Veillard	    pyCtxt = (xmlTextReaderPyCtxtPtr)arg;
214626f70269c80140a7fb8a7aae9ef09c95efa98e70Daniel Veillard	    Py_XDECREF(pyCtxt->f);
214726f70269c80140a7fb8a7aae9ef09c95efa98e70Daniel Veillard	    Py_XDECREF(pyCtxt->arg);
214826f70269c80140a7fb8a7aae9ef09c95efa98e70Daniel Veillard	    xmlFree(pyCtxt);
214926f70269c80140a7fb8a7aae9ef09c95efa98e70Daniel Veillard	}
215026f70269c80140a7fb8a7aae9ef09c95efa98e70Daniel Veillard	/*
215126f70269c80140a7fb8a7aae9ef09c95efa98e70Daniel Veillard	 * else, something wrong happened, because the error handler is
215226f70269c80140a7fb8a7aae9ef09c95efa98e70Daniel Veillard	 * not owned by the python bindings...
215326f70269c80140a7fb8a7aae9ef09c95efa98e70Daniel Veillard	 */
215426f70269c80140a7fb8a7aae9ef09c95efa98e70Daniel Veillard    }
215526f70269c80140a7fb8a7aae9ef09c95efa98e70Daniel Veillard
215626f70269c80140a7fb8a7aae9ef09c95efa98e70Daniel Veillard    xmlFreeTextReader(reader);
215726f70269c80140a7fb8a7aae9ef09c95efa98e70Daniel Veillard    Py_INCREF(Py_None);
215826f70269c80140a7fb8a7aae9ef09c95efa98e70Daniel Veillard    return(Py_None);
215926f70269c80140a7fb8a7aae9ef09c95efa98e70Daniel Veillard}
2160438ebbd59af78c436397ae488e42aeca5cad7542Daniel Veillard#endif
216126f70269c80140a7fb8a7aae9ef09c95efa98e70Daniel Veillard
216226f70269c80140a7fb8a7aae9ef09c95efa98e70Daniel Veillard/************************************************************************
216326f70269c80140a7fb8a7aae9ef09c95efa98e70Daniel Veillard *									*
2164a7340c830e4bddd86201cfdb97ac81e30b0dee62Daniel Veillard *			XPath extensions				*
2165a7340c830e4bddd86201cfdb97ac81e30b0dee62Daniel Veillard *									*
2166a7340c830e4bddd86201cfdb97ac81e30b0dee62Daniel Veillard ************************************************************************/
2167a7340c830e4bddd86201cfdb97ac81e30b0dee62Daniel Veillard
2168a7340c830e4bddd86201cfdb97ac81e30b0dee62Daniel Veillardstatic void
2169d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillardlibxml_xmlXPathFuncCallback(xmlXPathParserContextPtr ctxt, int nargs)
2170d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard{
2171a7340c830e4bddd86201cfdb97ac81e30b0dee62Daniel Veillard    PyObject *list, *cur, *result;
2172a7340c830e4bddd86201cfdb97ac81e30b0dee62Daniel Veillard    xmlXPathObjectPtr obj;
217370cab35abbb75eb9f0e328d498aa7a85195a1d5bDaniel Veillard    xmlXPathContextPtr rctxt;
217470cab35abbb75eb9f0e328d498aa7a85195a1d5bDaniel Veillard    PyObject *current_function = NULL;
217570cab35abbb75eb9f0e328d498aa7a85195a1d5bDaniel Veillard    const xmlChar *name;
217670cab35abbb75eb9f0e328d498aa7a85195a1d5bDaniel Veillard    const xmlChar *ns_uri;
2177a7340c830e4bddd86201cfdb97ac81e30b0dee62Daniel Veillard    int i;
2178a7340c830e4bddd86201cfdb97ac81e30b0dee62Daniel Veillard
217970cab35abbb75eb9f0e328d498aa7a85195a1d5bDaniel Veillard    if (ctxt == NULL)
2180d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        return;
218170cab35abbb75eb9f0e328d498aa7a85195a1d5bDaniel Veillard    rctxt = ctxt->context;
218270cab35abbb75eb9f0e328d498aa7a85195a1d5bDaniel Veillard    if (rctxt == NULL)
2183d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        return;
218470cab35abbb75eb9f0e328d498aa7a85195a1d5bDaniel Veillard    name = rctxt->function;
218570cab35abbb75eb9f0e328d498aa7a85195a1d5bDaniel Veillard    ns_uri = rctxt->functionURI;
2186a7340c830e4bddd86201cfdb97ac81e30b0dee62Daniel Veillard#ifdef DEBUG_XPATH
2187d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard    printf("libxml_xmlXPathFuncCallback called name %s URI %s\n", name,
2188d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard           ns_uri);
2189a7340c830e4bddd86201cfdb97ac81e30b0dee62Daniel Veillard#endif
2190a7340c830e4bddd86201cfdb97ac81e30b0dee62Daniel Veillard
219170cab35abbb75eb9f0e328d498aa7a85195a1d5bDaniel Veillard    /*
219270cab35abbb75eb9f0e328d498aa7a85195a1d5bDaniel Veillard     * Find the function, it should be there it was there at lookup
219370cab35abbb75eb9f0e328d498aa7a85195a1d5bDaniel Veillard     */
2194d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard    for (i = 0; i < libxml_xpathCallbacksNb; i++) {
2195d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        if (                    /* TODO (ctxt == libxml_xpathCallbacks[i].ctx) && */
21968e2cc6f2b53f536692f3c8ad8112bb67e0a1a629William M. Brack						(xmlStrEqual(name, (*libxml_xpathCallbacks)[i].name)) &&
21978e2cc6f2b53f536692f3c8ad8112bb67e0a1a629William M. Brack               (xmlStrEqual(ns_uri, (*libxml_xpathCallbacks)[i].ns_uri))) {
21988e2cc6f2b53f536692f3c8ad8112bb67e0a1a629William M. Brack					current_function = (*libxml_xpathCallbacks)[i].function;
2199d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        }
220070cab35abbb75eb9f0e328d498aa7a85195a1d5bDaniel Veillard    }
220170cab35abbb75eb9f0e328d498aa7a85195a1d5bDaniel Veillard    if (current_function == NULL) {
2202d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        printf
2203d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            ("libxml_xmlXPathFuncCallback: internal error %s not found !\n",
2204d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard             name);
2205d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        return;
220670cab35abbb75eb9f0e328d498aa7a85195a1d5bDaniel Veillard    }
220770cab35abbb75eb9f0e328d498aa7a85195a1d5bDaniel Veillard
2208c575b997d85d4791d852ad43e175d47a64cf8b3cDaniel Veillard    list = PyTuple_New(nargs + 1);
2209c575b997d85d4791d852ad43e175d47a64cf8b3cDaniel Veillard    PyTuple_SetItem(list, 0, libxml_xmlXPathParserContextPtrWrap(ctxt));
221005349ab2f6995d33f06932aa3cc62cf420ce0477Daniel Veillard    for (i = nargs - 1; i >= 0; i--) {
2211d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        obj = valuePop(ctxt);
2212d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        cur = libxml_xmlXPathObjectPtrWrap(obj);
2213d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        PyTuple_SetItem(list, i + 1, cur);
2214a7340c830e4bddd86201cfdb97ac81e30b0dee62Daniel Veillard    }
2215a7340c830e4bddd86201cfdb97ac81e30b0dee62Daniel Veillard    result = PyEval_CallObject(current_function, list);
2216a7340c830e4bddd86201cfdb97ac81e30b0dee62Daniel Veillard    Py_DECREF(list);
2217a7340c830e4bddd86201cfdb97ac81e30b0dee62Daniel Veillard
2218a7340c830e4bddd86201cfdb97ac81e30b0dee62Daniel Veillard    obj = libxml_xmlXPathObjectPtrConvert(result);
2219a7340c830e4bddd86201cfdb97ac81e30b0dee62Daniel Veillard    valuePush(ctxt, obj);
2220a7340c830e4bddd86201cfdb97ac81e30b0dee62Daniel Veillard}
2221a7340c830e4bddd86201cfdb97ac81e30b0dee62Daniel Veillard
2222a7340c830e4bddd86201cfdb97ac81e30b0dee62Daniel Veillardstatic xmlXPathFunction
2223d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillardlibxml_xmlXPathFuncLookupFunc(void *ctxt, const xmlChar * name,
2224d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard                              const xmlChar * ns_uri)
2225d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard{
2226a7340c830e4bddd86201cfdb97ac81e30b0dee62Daniel Veillard    int i;
2227d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard
2228a7340c830e4bddd86201cfdb97ac81e30b0dee62Daniel Veillard#ifdef DEBUG_XPATH
2229a7340c830e4bddd86201cfdb97ac81e30b0dee62Daniel Veillard    printf("libxml_xmlXPathFuncLookupFunc(%p, %s, %s) called\n",
2230d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard           ctxt, name, ns_uri);
2231a7340c830e4bddd86201cfdb97ac81e30b0dee62Daniel Veillard#endif
223270cab35abbb75eb9f0e328d498aa7a85195a1d5bDaniel Veillard    /*
223370cab35abbb75eb9f0e328d498aa7a85195a1d5bDaniel Veillard     * This is called once only. The address is then stored in the
223470cab35abbb75eb9f0e328d498aa7a85195a1d5bDaniel Veillard     * XPath expression evaluation, the proper object to call can
223570cab35abbb75eb9f0e328d498aa7a85195a1d5bDaniel Veillard     * then still be found using the execution context function
223670cab35abbb75eb9f0e328d498aa7a85195a1d5bDaniel Veillard     * and functionURI fields.
223770cab35abbb75eb9f0e328d498aa7a85195a1d5bDaniel Veillard     */
2238d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard    for (i = 0; i < libxml_xpathCallbacksNb; i++) {
22398e2cc6f2b53f536692f3c8ad8112bb67e0a1a629William M. Brack			if ((ctxt == (*libxml_xpathCallbacks)[i].ctx) &&
22408e2cc6f2b53f536692f3c8ad8112bb67e0a1a629William M. Brack					(xmlStrEqual(name, (*libxml_xpathCallbacks)[i].name)) &&
22418e2cc6f2b53f536692f3c8ad8112bb67e0a1a629William M. Brack					(xmlStrEqual(ns_uri, (*libxml_xpathCallbacks)[i].ns_uri))) {
2242d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            return (libxml_xmlXPathFuncCallback);
2243d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        }
2244a7340c830e4bddd86201cfdb97ac81e30b0dee62Daniel Veillard    }
2245d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard    return (NULL);
2246a7340c830e4bddd86201cfdb97ac81e30b0dee62Daniel Veillard}
2247a7340c830e4bddd86201cfdb97ac81e30b0dee62Daniel Veillard
2248a7340c830e4bddd86201cfdb97ac81e30b0dee62Daniel Veillardstatic void
2249d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillardlibxml_xpathCallbacksInitialize(void)
2250d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard{
2251a7340c830e4bddd86201cfdb97ac81e30b0dee62Daniel Veillard    int i;
2252a7340c830e4bddd86201cfdb97ac81e30b0dee62Daniel Veillard
2253a7340c830e4bddd86201cfdb97ac81e30b0dee62Daniel Veillard    if (libxml_xpathCallbacksInitialized != 0)
2254d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        return;
2255a7340c830e4bddd86201cfdb97ac81e30b0dee62Daniel Veillard
2256a7340c830e4bddd86201cfdb97ac81e30b0dee62Daniel Veillard#ifdef DEBUG_XPATH
2257a7340c830e4bddd86201cfdb97ac81e30b0dee62Daniel Veillard    printf("libxml_xpathCallbacksInitialized called\n");
2258a7340c830e4bddd86201cfdb97ac81e30b0dee62Daniel Veillard#endif
22598e2cc6f2b53f536692f3c8ad8112bb67e0a1a629William M. Brack    libxml_xpathCallbacks = (libxml_xpathCallbackArray*)xmlMalloc(
22608e2cc6f2b53f536692f3c8ad8112bb67e0a1a629William M. Brack    		libxml_xpathCallbacksAllocd*sizeof(libxml_xpathCallback));
2261a7340c830e4bddd86201cfdb97ac81e30b0dee62Daniel Veillard
22628e2cc6f2b53f536692f3c8ad8112bb67e0a1a629William M. Brack    for (i = 0; i < libxml_xpathCallbacksAllocd; i++) {
22638e2cc6f2b53f536692f3c8ad8112bb67e0a1a629William M. Brack			(*libxml_xpathCallbacks)[i].ctx = NULL;
22648e2cc6f2b53f536692f3c8ad8112bb67e0a1a629William M. Brack			(*libxml_xpathCallbacks)[i].name = NULL;
22658e2cc6f2b53f536692f3c8ad8112bb67e0a1a629William M. Brack			(*libxml_xpathCallbacks)[i].ns_uri = NULL;
22668e2cc6f2b53f536692f3c8ad8112bb67e0a1a629William M. Brack			(*libxml_xpathCallbacks)[i].function = NULL;
2267a7340c830e4bddd86201cfdb97ac81e30b0dee62Daniel Veillard    }
2268a7340c830e4bddd86201cfdb97ac81e30b0dee62Daniel Veillard    libxml_xpathCallbacksInitialized = 1;
2269a7340c830e4bddd86201cfdb97ac81e30b0dee62Daniel Veillard}
2270a7340c830e4bddd86201cfdb97ac81e30b0dee62Daniel Veillard
2271a7340c830e4bddd86201cfdb97ac81e30b0dee62Daniel VeillardPyObject *
2272d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillardlibxml_xmlRegisterXPathFunction(ATTRIBUTE_UNUSED PyObject * self,
2273d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard                                PyObject * args)
2274d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard{
2275a7340c830e4bddd86201cfdb97ac81e30b0dee62Daniel Veillard    PyObject *py_retval;
2276a7340c830e4bddd86201cfdb97ac81e30b0dee62Daniel Veillard    int c_retval = 0;
2277a7340c830e4bddd86201cfdb97ac81e30b0dee62Daniel Veillard    xmlChar *name;
2278a7340c830e4bddd86201cfdb97ac81e30b0dee62Daniel Veillard    xmlChar *ns_uri;
2279a7340c830e4bddd86201cfdb97ac81e30b0dee62Daniel Veillard    xmlXPathContextPtr ctx;
2280a7340c830e4bddd86201cfdb97ac81e30b0dee62Daniel Veillard    PyObject *pyobj_ctx;
2281a7340c830e4bddd86201cfdb97ac81e30b0dee62Daniel Veillard    PyObject *pyobj_f;
2282a7340c830e4bddd86201cfdb97ac81e30b0dee62Daniel Veillard    int i;
2283a7340c830e4bddd86201cfdb97ac81e30b0dee62Daniel Veillard
2284d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard    if (!PyArg_ParseTuple
2285d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        (args, (char *) "OszO:registerXPathFunction", &pyobj_ctx, &name,
2286d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard         &ns_uri, &pyobj_f))
2287d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        return (NULL);
2288a7340c830e4bddd86201cfdb97ac81e30b0dee62Daniel Veillard
2289a7340c830e4bddd86201cfdb97ac81e30b0dee62Daniel Veillard    ctx = (xmlXPathContextPtr) PyxmlXPathContext_Get(pyobj_ctx);
2290a7340c830e4bddd86201cfdb97ac81e30b0dee62Daniel Veillard    if (libxml_xpathCallbacksInitialized == 0)
2291d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        libxml_xpathCallbacksInitialize();
2292a7340c830e4bddd86201cfdb97ac81e30b0dee62Daniel Veillard    xmlXPathRegisterFuncLookup(ctx, libxml_xmlXPathFuncLookupFunc, ctx);
2293a7340c830e4bddd86201cfdb97ac81e30b0dee62Daniel Veillard
2294a7340c830e4bddd86201cfdb97ac81e30b0dee62Daniel Veillard    if ((pyobj_ctx == NULL) || (name == NULL) || (pyobj_f == NULL)) {
2295d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        py_retval = libxml_intWrap(-1);
2296d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        return (py_retval);
2297a7340c830e4bddd86201cfdb97ac81e30b0dee62Daniel Veillard    }
2298a7340c830e4bddd86201cfdb97ac81e30b0dee62Daniel Veillard#ifdef DEBUG_XPATH
2299a7340c830e4bddd86201cfdb97ac81e30b0dee62Daniel Veillard    printf("libxml_registerXPathFunction(%p, %s, %s) called\n",
2300d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard           ctx, name, ns_uri);
2301a7340c830e4bddd86201cfdb97ac81e30b0dee62Daniel Veillard#endif
2302d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard    for (i = 0; i < libxml_xpathCallbacksNb; i++) {
23038e2cc6f2b53f536692f3c8ad8112bb67e0a1a629William M. Brack	if ((ctx == (*libxml_xpathCallbacks)[i].ctx) &&
23048e2cc6f2b53f536692f3c8ad8112bb67e0a1a629William M. Brack            (xmlStrEqual(name, (*libxml_xpathCallbacks)[i].name)) &&
23058e2cc6f2b53f536692f3c8ad8112bb67e0a1a629William M. Brack            (xmlStrEqual(ns_uri, (*libxml_xpathCallbacks)[i].ns_uri))) {
2306d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            Py_XINCREF(pyobj_f);
23078e2cc6f2b53f536692f3c8ad8112bb67e0a1a629William M. Brack            Py_XDECREF((*libxml_xpathCallbacks)[i].function);
23088e2cc6f2b53f536692f3c8ad8112bb67e0a1a629William M. Brack            (*libxml_xpathCallbacks)[i].function = pyobj_f;
2309d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            c_retval = 1;
2310d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            goto done;
2311d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        }
2312a7340c830e4bddd86201cfdb97ac81e30b0dee62Daniel Veillard    }
23138e2cc6f2b53f536692f3c8ad8112bb67e0a1a629William M. Brack    if (libxml_xpathCallbacksNb >= libxml_xpathCallbacksAllocd) {
23148e2cc6f2b53f536692f3c8ad8112bb67e0a1a629William M. Brack			libxml_xpathCallbacksAllocd+=10;
23158e2cc6f2b53f536692f3c8ad8112bb67e0a1a629William M. Brack	libxml_xpathCallbacks = (libxml_xpathCallbackArray*)xmlRealloc(
23168e2cc6f2b53f536692f3c8ad8112bb67e0a1a629William M. Brack		libxml_xpathCallbacks,
23178e2cc6f2b53f536692f3c8ad8112bb67e0a1a629William M. Brack		libxml_xpathCallbacksAllocd*sizeof(libxml_xpathCallback));
23188e2cc6f2b53f536692f3c8ad8112bb67e0a1a629William M. Brack    }
23198e2cc6f2b53f536692f3c8ad8112bb67e0a1a629William M. Brack    i = libxml_xpathCallbacksNb++;
23208e2cc6f2b53f536692f3c8ad8112bb67e0a1a629William M. Brack    Py_XINCREF(pyobj_f);
23218e2cc6f2b53f536692f3c8ad8112bb67e0a1a629William M. Brack    (*libxml_xpathCallbacks)[i].ctx = ctx;
23228e2cc6f2b53f536692f3c8ad8112bb67e0a1a629William M. Brack    (*libxml_xpathCallbacks)[i].name = xmlStrdup(name);
23238e2cc6f2b53f536692f3c8ad8112bb67e0a1a629William M. Brack    (*libxml_xpathCallbacks)[i].ns_uri = xmlStrdup(ns_uri);
23248e2cc6f2b53f536692f3c8ad8112bb67e0a1a629William M. Brack    (*libxml_xpathCallbacks)[i].function = pyobj_f;
2325d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        c_retval = 1;
23268e2cc6f2b53f536692f3c8ad8112bb67e0a1a629William M. Brack
2327d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard  done:
2328a7340c830e4bddd86201cfdb97ac81e30b0dee62Daniel Veillard    py_retval = libxml_intWrap((int) c_retval);
2329519bc6a3ab82445a8719f548d0450efe02cc9c82Shaun McCance    return (py_retval);
2330519bc6a3ab82445a8719f548d0450efe02cc9c82Shaun McCance}
2331519bc6a3ab82445a8719f548d0450efe02cc9c82Shaun McCance
2332519bc6a3ab82445a8719f548d0450efe02cc9c82Shaun McCancePyObject *
2333519bc6a3ab82445a8719f548d0450efe02cc9c82Shaun McCancelibxml_xmlXPathRegisterVariable(ATTRIBUTE_UNUSED PyObject * self,
2334519bc6a3ab82445a8719f548d0450efe02cc9c82Shaun McCance                                PyObject * args)
2335519bc6a3ab82445a8719f548d0450efe02cc9c82Shaun McCance{
2336519bc6a3ab82445a8719f548d0450efe02cc9c82Shaun McCance    PyObject *py_retval;
2337519bc6a3ab82445a8719f548d0450efe02cc9c82Shaun McCance    int c_retval = 0;
2338519bc6a3ab82445a8719f548d0450efe02cc9c82Shaun McCance    xmlChar *name;
2339519bc6a3ab82445a8719f548d0450efe02cc9c82Shaun McCance    xmlChar *ns_uri;
2340519bc6a3ab82445a8719f548d0450efe02cc9c82Shaun McCance    xmlXPathContextPtr ctx;
2341519bc6a3ab82445a8719f548d0450efe02cc9c82Shaun McCance    xmlXPathObjectPtr val;
2342519bc6a3ab82445a8719f548d0450efe02cc9c82Shaun McCance    PyObject *pyobj_ctx;
2343519bc6a3ab82445a8719f548d0450efe02cc9c82Shaun McCance    PyObject *pyobj_value;
2344519bc6a3ab82445a8719f548d0450efe02cc9c82Shaun McCance
2345519bc6a3ab82445a8719f548d0450efe02cc9c82Shaun McCance    if (!PyArg_ParseTuple
2346519bc6a3ab82445a8719f548d0450efe02cc9c82Shaun McCance        (args, (char *) "OszO:xpathRegisterVariable", &pyobj_ctx, &name,
2347519bc6a3ab82445a8719f548d0450efe02cc9c82Shaun McCance         &ns_uri, &pyobj_value))
2348519bc6a3ab82445a8719f548d0450efe02cc9c82Shaun McCance        return (NULL);
2349519bc6a3ab82445a8719f548d0450efe02cc9c82Shaun McCance
2350519bc6a3ab82445a8719f548d0450efe02cc9c82Shaun McCance    ctx = (xmlXPathContextPtr) PyxmlXPathContext_Get(pyobj_ctx);
2351519bc6a3ab82445a8719f548d0450efe02cc9c82Shaun McCance    val = libxml_xmlXPathObjectPtrConvert(pyobj_value);
2352519bc6a3ab82445a8719f548d0450efe02cc9c82Shaun McCance
2353519bc6a3ab82445a8719f548d0450efe02cc9c82Shaun McCance    c_retval = xmlXPathRegisterVariableNS(ctx, name, ns_uri, val);
2354519bc6a3ab82445a8719f548d0450efe02cc9c82Shaun McCance    py_retval = libxml_intWrap(c_retval);
2355d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard    return (py_retval);
2356a7340c830e4bddd86201cfdb97ac81e30b0dee62Daniel Veillard}
2357a7340c830e4bddd86201cfdb97ac81e30b0dee62Daniel Veillard
23581971ee2698cb84c7699c96d3302f00e20d42c0d3Daniel Veillard/************************************************************************
23591971ee2698cb84c7699c96d3302f00e20d42c0d3Daniel Veillard *									*
2360d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard *			Global properties access			*
2361d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard *									*
2362d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard ************************************************************************/
2363d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillardstatic PyObject *
2364d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillardlibxml_name(ATTRIBUTE_UNUSED PyObject * self, PyObject * args)
2365d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard{
2366d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard    PyObject *resultobj, *obj;
2367d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard    xmlNodePtr cur;
2368d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard    const xmlChar *res;
2369d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard
2370d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard    if (!PyArg_ParseTuple(args, (char *) "O:name", &obj))
2371d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard        return NULL;
2372d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard    cur = PyxmlNode_Get(obj);
2373d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard
2374d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard#ifdef DEBUG
2375d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard    printf("libxml_name: cur = %p type %d\n", cur, cur->type);
2376d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard#endif
2377d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard
2378d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard    switch (cur->type) {
2379d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        case XML_DOCUMENT_NODE:
2380d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard#ifdef LIBXML_DOCB_ENABLED
2381d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        case XML_DOCB_DOCUMENT_NODE:
2382d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard#endif
2383d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        case XML_HTML_DOCUMENT_NODE:{
2384d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard                xmlDocPtr doc = (xmlDocPtr) cur;
2385d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard
2386d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard                res = doc->URL;
2387d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard                break;
2388d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            }
2389d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        case XML_ATTRIBUTE_NODE:{
2390d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard                xmlAttrPtr attr = (xmlAttrPtr) cur;
2391d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard
2392d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard                res = attr->name;
2393d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard                break;
2394d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            }
2395d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        case XML_NAMESPACE_DECL:{
2396d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard                xmlNsPtr ns = (xmlNsPtr) cur;
2397d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard
2398d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard                res = ns->prefix;
2399d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard                break;
2400d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            }
2401d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        default:
2402d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            res = cur->name;
2403d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            break;
2404d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard    }
24051971ee2698cb84c7699c96d3302f00e20d42c0d3Daniel Veillard    resultobj = libxml_constxmlCharPtrWrap(res);
2406d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard
2407d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard    return resultobj;
2408d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard}
2409d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard
2410d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillardstatic PyObject *
2411d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillardlibxml_doc(ATTRIBUTE_UNUSED PyObject * self, PyObject * args)
2412d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard{
2413d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard    PyObject *resultobj, *obj;
2414d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard    xmlNodePtr cur;
2415d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard    xmlDocPtr res;
2416d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard
2417d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard    if (!PyArg_ParseTuple(args, (char *) "O:doc", &obj))
2418d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard        return NULL;
2419d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard    cur = PyxmlNode_Get(obj);
2420d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard
2421d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard#ifdef DEBUG
2422d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard    printf("libxml_doc: cur = %p\n", cur);
2423d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard#endif
2424d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard
2425d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard    switch (cur->type) {
2426d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        case XML_DOCUMENT_NODE:
2427d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard#ifdef LIBXML_DOCB_ENABLED
2428d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        case XML_DOCB_DOCUMENT_NODE:
2429d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard#endif
2430d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        case XML_HTML_DOCUMENT_NODE:
2431d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            res = NULL;
2432d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            break;
2433d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        case XML_ATTRIBUTE_NODE:{
2434d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard                xmlAttrPtr attr = (xmlAttrPtr) cur;
2435d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard
2436d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard                res = attr->doc;
2437d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard                break;
2438d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            }
2439d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        case XML_NAMESPACE_DECL:
2440d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            res = NULL;
2441d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            break;
2442d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        default:
2443d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            res = cur->doc;
2444d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            break;
2445d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard    }
2446d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard    resultobj = libxml_xmlDocPtrWrap(res);
2447d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard    return resultobj;
2448d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard}
2449d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard
2450d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillardstatic PyObject *
2451d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillardlibxml_properties(ATTRIBUTE_UNUSED PyObject * self, PyObject * args)
2452d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard{
2453d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard    PyObject *resultobj, *obj;
24542728f845c5581af9213057ace8b3f664d64c15a9Daniel Veillard    xmlNodePtr cur;
2455d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard    xmlAttrPtr res;
2456d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard
2457d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard    if (!PyArg_ParseTuple(args, (char *) "O:properties", &obj))
2458d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard        return NULL;
2459d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard    cur = PyxmlNode_Get(obj);
24602728f845c5581af9213057ace8b3f664d64c15a9Daniel Veillard    if ((cur != NULL) && (cur->type == XML_ELEMENT_NODE))
2461d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        res = cur->properties;
2462d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard    else
2463d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        res = NULL;
2464d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard    resultobj = libxml_xmlAttrPtrWrap(res);
2465d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard    return resultobj;
2466d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard}
2467d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard
2468d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillardstatic PyObject *
2469d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillardlibxml_next(ATTRIBUTE_UNUSED PyObject * self, PyObject * args)
2470d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard{
2471d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard    PyObject *resultobj, *obj;
2472d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard    xmlNodePtr cur;
2473d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard    xmlNodePtr res;
2474d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard
2475d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard    if (!PyArg_ParseTuple(args, (char *) "O:next", &obj))
2476d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard        return NULL;
2477d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard    cur = PyxmlNode_Get(obj);
2478d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard
2479d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard#ifdef DEBUG
2480d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard    printf("libxml_next: 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 = (xmlNodePtr) attr->next;
2495d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard                break;
2496d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            }
2497d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        case XML_NAMESPACE_DECL:{
2498d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard                xmlNsPtr ns = (xmlNsPtr) cur;
2499d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard
2500d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard                res = (xmlNodePtr) ns->next;
2501d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard                break;
2502d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            }
2503d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        default:
2504d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            res = cur->next;
2505d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            break;
2506d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard
2507d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard    }
2508d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard    resultobj = libxml_xmlNodePtrWrap(res);
2509d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard    return resultobj;
2510d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard}
2511d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard
2512d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillardstatic PyObject *
2513d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillardlibxml_prev(ATTRIBUTE_UNUSED PyObject * self, PyObject * args)
2514d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard{
2515d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard    PyObject *resultobj, *obj;
2516d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard    xmlNodePtr cur;
2517d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard    xmlNodePtr res;
2518d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard
2519d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard    if (!PyArg_ParseTuple(args, (char *) "O:prev", &obj))
2520d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard        return NULL;
2521d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard    cur = PyxmlNode_Get(obj);
2522d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard
2523d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard#ifdef DEBUG
2524d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard    printf("libxml_prev: cur = %p\n", cur);
2525d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard#endif
2526d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard
2527d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard    switch (cur->type) {
2528d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        case XML_DOCUMENT_NODE:
2529d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard#ifdef LIBXML_DOCB_ENABLED
2530d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        case XML_DOCB_DOCUMENT_NODE:
2531d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard#endif
2532d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        case XML_HTML_DOCUMENT_NODE:
2533d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            res = NULL;
2534d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            break;
2535d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        case XML_ATTRIBUTE_NODE:{
2536d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard                xmlAttrPtr attr = (xmlAttrPtr) cur;
2537d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard
2538faa35ff3cdcf15154dd207606a31b34923da9be9Daniel Veillard                res = (xmlNodePtr) attr->prev;
2539d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            }
2540594e5dfb48ee6fbac1b64155839063648022fc57Daniel Veillard            break;
2541d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        case XML_NAMESPACE_DECL:
2542d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            res = NULL;
2543d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            break;
2544d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        default:
2545faa35ff3cdcf15154dd207606a31b34923da9be9Daniel Veillard            res = cur->prev;
2546d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            break;
2547d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard    }
2548d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard    resultobj = libxml_xmlNodePtrWrap(res);
2549d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard    return resultobj;
2550d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard}
2551d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard
2552d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillardstatic PyObject *
2553d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillardlibxml_children(ATTRIBUTE_UNUSED PyObject * self, PyObject * args)
2554d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard{
2555d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard    PyObject *resultobj, *obj;
2556d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard    xmlNodePtr cur;
2557d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard    xmlNodePtr res;
2558d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard
2559d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard    if (!PyArg_ParseTuple(args, (char *) "O:children", &obj))
2560d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard        return NULL;
2561d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard    cur = PyxmlNode_Get(obj);
2562d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard
2563d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard#ifdef DEBUG
2564d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard    printf("libxml_children: cur = %p\n", cur);
2565d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard#endif
2566d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard
2567d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard    switch (cur->type) {
2568d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        case XML_ELEMENT_NODE:
2569d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        case XML_ENTITY_REF_NODE:
2570d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        case XML_ENTITY_NODE:
2571d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        case XML_PI_NODE:
2572d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        case XML_COMMENT_NODE:
2573d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        case XML_DOCUMENT_NODE:
2574d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard#ifdef LIBXML_DOCB_ENABLED
2575d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        case XML_DOCB_DOCUMENT_NODE:
2576d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard#endif
2577d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        case XML_HTML_DOCUMENT_NODE:
2578d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        case XML_DTD_NODE:
2579d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            res = cur->children;
2580d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            break;
2581d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        case XML_ATTRIBUTE_NODE:{
2582d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard                xmlAttrPtr attr = (xmlAttrPtr) cur;
2583d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard
2584d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard                res = attr->children;
2585d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard                break;
2586d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            }
2587d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        default:
2588d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            res = NULL;
2589d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            break;
2590d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard    }
2591d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard    resultobj = libxml_xmlNodePtrWrap(res);
2592d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard    return resultobj;
2593d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard}
2594d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard
2595d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillardstatic PyObject *
2596d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillardlibxml_last(ATTRIBUTE_UNUSED PyObject * self, PyObject * args)
2597d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard{
2598d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard    PyObject *resultobj, *obj;
2599d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard    xmlNodePtr cur;
2600d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard    xmlNodePtr res;
2601d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard
2602d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard    if (!PyArg_ParseTuple(args, (char *) "O:last", &obj))
2603d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard        return NULL;
2604d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard    cur = PyxmlNode_Get(obj);
2605d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard
2606d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard#ifdef DEBUG
2607d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard    printf("libxml_last: cur = %p\n", cur);
2608d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard#endif
2609d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard
2610d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard    switch (cur->type) {
2611d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        case XML_ELEMENT_NODE:
2612d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        case XML_ENTITY_REF_NODE:
2613d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        case XML_ENTITY_NODE:
2614d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        case XML_PI_NODE:
2615d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        case XML_COMMENT_NODE:
2616d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        case XML_DOCUMENT_NODE:
2617d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard#ifdef LIBXML_DOCB_ENABLED
2618d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        case XML_DOCB_DOCUMENT_NODE:
2619d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard#endif
2620d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        case XML_HTML_DOCUMENT_NODE:
2621d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        case XML_DTD_NODE:
2622d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            res = cur->last;
2623d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            break;
2624d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        case XML_ATTRIBUTE_NODE:{
2625d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard                xmlAttrPtr attr = (xmlAttrPtr) cur;
2626d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard
2627d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard                res = attr->last;
2628d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            }
2629d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        default:
2630d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            res = NULL;
2631d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            break;
2632d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard    }
2633d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard    resultobj = libxml_xmlNodePtrWrap(res);
2634d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard    return resultobj;
2635d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard}
2636d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard
2637d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillardstatic PyObject *
2638d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillardlibxml_parent(ATTRIBUTE_UNUSED PyObject * self, PyObject * args)
2639d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard{
2640d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard    PyObject *resultobj, *obj;
2641d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard    xmlNodePtr cur;
2642d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard    xmlNodePtr res;
2643d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard
2644d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard    if (!PyArg_ParseTuple(args, (char *) "O:parent", &obj))
2645d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard        return NULL;
2646d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard    cur = PyxmlNode_Get(obj);
2647d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard
2648d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard#ifdef DEBUG
2649d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard    printf("libxml_parent: cur = %p\n", cur);
2650d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard#endif
2651d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard
2652d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard    switch (cur->type) {
2653d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        case XML_DOCUMENT_NODE:
2654d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        case XML_HTML_DOCUMENT_NODE:
2655d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard#ifdef LIBXML_DOCB_ENABLED
2656d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        case XML_DOCB_DOCUMENT_NODE:
2657d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard#endif
2658d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            res = NULL;
2659d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            break;
2660d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        case XML_ATTRIBUTE_NODE:{
2661d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard                xmlAttrPtr attr = (xmlAttrPtr) cur;
2662d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard
2663d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard                res = attr->parent;
2664d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            }
266522eda2bc82acd047247df3f88aa9a5ab08d6a434Daniel Veillard	    break;
2666d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        case XML_ENTITY_DECL:
2667d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        case XML_NAMESPACE_DECL:
2668d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        case XML_XINCLUDE_START:
2669d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        case XML_XINCLUDE_END:
2670d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            res = NULL;
2671d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            break;
2672d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        default:
2673d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            res = cur->parent;
2674d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            break;
2675d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard    }
2676d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard    resultobj = libxml_xmlNodePtrWrap(res);
2677d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard    return resultobj;
2678d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard}
2679d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard
2680d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillardstatic PyObject *
2681d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillardlibxml_type(ATTRIBUTE_UNUSED PyObject * self, PyObject * args)
2682d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard{
2683d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard    PyObject *resultobj, *obj;
2684d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard    xmlNodePtr cur;
2685d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard    const xmlChar *res = NULL;
2686d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard
2687d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard    if (!PyArg_ParseTuple(args, (char *) "O:last", &obj))
2688d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard        return NULL;
2689d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard    cur = PyxmlNode_Get(obj);
2690d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard
2691d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard#ifdef DEBUG
2692d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard    printf("libxml_type: cur = %p\n", cur);
2693d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard#endif
2694d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard
2695d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard    switch (cur->type) {
2696d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard        case XML_ELEMENT_NODE:
2697d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            res = (const xmlChar *) "element";
2698d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            break;
2699d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard        case XML_ATTRIBUTE_NODE:
2700d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            res = (const xmlChar *) "attribute";
2701d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            break;
2702d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard        case XML_TEXT_NODE:
2703d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            res = (const xmlChar *) "text";
2704d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            break;
2705d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard        case XML_CDATA_SECTION_NODE:
2706d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            res = (const xmlChar *) "cdata";
2707d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            break;
2708d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard        case XML_ENTITY_REF_NODE:
2709d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            res = (const xmlChar *) "entity_ref";
2710d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            break;
2711d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard        case XML_ENTITY_NODE:
2712d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            res = (const xmlChar *) "entity";
2713d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            break;
2714d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard        case XML_PI_NODE:
2715d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            res = (const xmlChar *) "pi";
2716d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            break;
2717d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard        case XML_COMMENT_NODE:
2718d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            res = (const xmlChar *) "comment";
2719d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            break;
2720d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard        case XML_DOCUMENT_NODE:
2721d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            res = (const xmlChar *) "document_xml";
2722d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            break;
2723d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard        case XML_DOCUMENT_TYPE_NODE:
2724d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            res = (const xmlChar *) "doctype";
2725d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            break;
2726d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard        case XML_DOCUMENT_FRAG_NODE:
2727d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            res = (const xmlChar *) "fragment";
2728d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            break;
2729d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard        case XML_NOTATION_NODE:
2730d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            res = (const xmlChar *) "notation";
2731d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            break;
2732d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard        case XML_HTML_DOCUMENT_NODE:
2733d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            res = (const xmlChar *) "document_html";
2734d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            break;
2735d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard        case XML_DTD_NODE:
2736d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            res = (const xmlChar *) "dtd";
2737d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            break;
2738d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard        case XML_ELEMENT_DECL:
2739d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            res = (const xmlChar *) "elem_decl";
2740d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            break;
2741d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard        case XML_ATTRIBUTE_DECL:
2742d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            res = (const xmlChar *) "attribute_decl";
2743d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            break;
2744d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard        case XML_ENTITY_DECL:
2745d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            res = (const xmlChar *) "entity_decl";
2746d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            break;
2747d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard        case XML_NAMESPACE_DECL:
2748d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            res = (const xmlChar *) "namespace";
2749d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            break;
2750d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard        case XML_XINCLUDE_START:
2751d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            res = (const xmlChar *) "xinclude_start";
2752d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            break;
2753d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard        case XML_XINCLUDE_END:
2754d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            res = (const xmlChar *) "xinclude_end";
2755d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            break;
2756d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard#ifdef LIBXML_DOCB_ENABLED
2757d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        case XML_DOCB_DOCUMENT_NODE:
2758d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            res = (const xmlChar *) "document_docbook";
2759d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            break;
2760d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard#endif
2761d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard    }
2762d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard#ifdef DEBUG
2763d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard    printf("libxml_type: cur = %p: %s\n", cur, res);
2764d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard#endif
2765d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard
27661971ee2698cb84c7699c96d3302f00e20d42c0d3Daniel Veillard    resultobj = libxml_constxmlCharPtrWrap(res);
2767d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard    return resultobj;
2768d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard}
2769d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard
2770d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard/************************************************************************
2771d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard *									*
277236eea2d2ee84132e66552f84724e9b377d687681Daniel Veillard *			Specific accessor functions			*
277336eea2d2ee84132e66552f84724e9b377d687681Daniel Veillard *									*
277436eea2d2ee84132e66552f84724e9b377d687681Daniel Veillard ************************************************************************/
277536eea2d2ee84132e66552f84724e9b377d687681Daniel VeillardPyObject *
2776d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillardlibxml_xmlNodeGetNsDefs(ATTRIBUTE_UNUSED PyObject * self, PyObject * args)
2777d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard{
277836eea2d2ee84132e66552f84724e9b377d687681Daniel Veillard    PyObject *py_retval;
277936eea2d2ee84132e66552f84724e9b377d687681Daniel Veillard    xmlNsPtr c_retval;
278036eea2d2ee84132e66552f84724e9b377d687681Daniel Veillard    xmlNodePtr node;
278136eea2d2ee84132e66552f84724e9b377d687681Daniel Veillard    PyObject *pyobj_node;
278236eea2d2ee84132e66552f84724e9b377d687681Daniel Veillard
2783d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard    if (!PyArg_ParseTuple
2784d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        (args, (char *) "O:xmlNodeGetNsDefs", &pyobj_node))
2785d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        return (NULL);
278636eea2d2ee84132e66552f84724e9b377d687681Daniel Veillard    node = (xmlNodePtr) PyxmlNode_Get(pyobj_node);
278736eea2d2ee84132e66552f84724e9b377d687681Daniel Veillard
278836eea2d2ee84132e66552f84724e9b377d687681Daniel Veillard    if ((node == NULL) || (node->type != XML_ELEMENT_NODE)) {
2789d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        Py_INCREF(Py_None);
2790d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        return (Py_None);
279136eea2d2ee84132e66552f84724e9b377d687681Daniel Veillard    }
279236eea2d2ee84132e66552f84724e9b377d687681Daniel Veillard    c_retval = node->nsDef;
279336eea2d2ee84132e66552f84724e9b377d687681Daniel Veillard    py_retval = libxml_xmlNsPtrWrap((xmlNsPtr) c_retval);
2794d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard    return (py_retval);
279536eea2d2ee84132e66552f84724e9b377d687681Daniel Veillard}
279636eea2d2ee84132e66552f84724e9b377d687681Daniel Veillard
279736eea2d2ee84132e66552f84724e9b377d687681Daniel VeillardPyObject *
2798f9cf6f5a01527406ed0bcbcf5a180d85b5e771deDaniel Veillardlibxml_xmlNodeRemoveNsDef(ATTRIBUTE_UNUSED PyObject * self, PyObject * args)
2799f9cf6f5a01527406ed0bcbcf5a180d85b5e771deDaniel Veillard{
2800f9cf6f5a01527406ed0bcbcf5a180d85b5e771deDaniel Veillard    PyObject *py_retval;
2801f9cf6f5a01527406ed0bcbcf5a180d85b5e771deDaniel Veillard    xmlNsPtr ns, prev;
2802f9cf6f5a01527406ed0bcbcf5a180d85b5e771deDaniel Veillard    xmlNodePtr node;
2803f9cf6f5a01527406ed0bcbcf5a180d85b5e771deDaniel Veillard    PyObject *pyobj_node;
2804f9cf6f5a01527406ed0bcbcf5a180d85b5e771deDaniel Veillard    xmlChar *href;
2805f9cf6f5a01527406ed0bcbcf5a180d85b5e771deDaniel Veillard    xmlNsPtr c_retval;
2806f9cf6f5a01527406ed0bcbcf5a180d85b5e771deDaniel Veillard
2807f9cf6f5a01527406ed0bcbcf5a180d85b5e771deDaniel Veillard    if (!PyArg_ParseTuple
2808f9cf6f5a01527406ed0bcbcf5a180d85b5e771deDaniel Veillard        (args, (char *) "Oz:xmlNodeRemoveNsDef", &pyobj_node, &href))
2809f9cf6f5a01527406ed0bcbcf5a180d85b5e771deDaniel Veillard        return (NULL);
2810f9cf6f5a01527406ed0bcbcf5a180d85b5e771deDaniel Veillard    node = (xmlNodePtr) PyxmlNode_Get(pyobj_node);
2811f9cf6f5a01527406ed0bcbcf5a180d85b5e771deDaniel Veillard    ns = NULL;
2812f9cf6f5a01527406ed0bcbcf5a180d85b5e771deDaniel Veillard
2813f9cf6f5a01527406ed0bcbcf5a180d85b5e771deDaniel Veillard    if ((node == NULL) || (node->type != XML_ELEMENT_NODE)) {
2814f9cf6f5a01527406ed0bcbcf5a180d85b5e771deDaniel Veillard        Py_INCREF(Py_None);
2815f9cf6f5a01527406ed0bcbcf5a180d85b5e771deDaniel Veillard        return (Py_None);
2816f9cf6f5a01527406ed0bcbcf5a180d85b5e771deDaniel Veillard    }
2817f9cf6f5a01527406ed0bcbcf5a180d85b5e771deDaniel Veillard
2818f9cf6f5a01527406ed0bcbcf5a180d85b5e771deDaniel Veillard    if (href == NULL) {
2819f9cf6f5a01527406ed0bcbcf5a180d85b5e771deDaniel Veillard	ns = node->nsDef;
2820f9cf6f5a01527406ed0bcbcf5a180d85b5e771deDaniel Veillard	node->nsDef = NULL;
2821f9cf6f5a01527406ed0bcbcf5a180d85b5e771deDaniel Veillard	c_retval = 0;
2822f9cf6f5a01527406ed0bcbcf5a180d85b5e771deDaniel Veillard    }
2823f9cf6f5a01527406ed0bcbcf5a180d85b5e771deDaniel Veillard    else {
2824f9cf6f5a01527406ed0bcbcf5a180d85b5e771deDaniel Veillard	prev = NULL;
2825f9cf6f5a01527406ed0bcbcf5a180d85b5e771deDaniel Veillard	ns = node->nsDef;
2826f9cf6f5a01527406ed0bcbcf5a180d85b5e771deDaniel Veillard	while (ns != NULL) {
2827f9cf6f5a01527406ed0bcbcf5a180d85b5e771deDaniel Veillard	    if (xmlStrEqual(ns->href, href)) {
2828f9cf6f5a01527406ed0bcbcf5a180d85b5e771deDaniel Veillard		if (prev != NULL)
2829f9cf6f5a01527406ed0bcbcf5a180d85b5e771deDaniel Veillard		    prev->next = ns->next;
2830f9cf6f5a01527406ed0bcbcf5a180d85b5e771deDaniel Veillard		else
2831f9cf6f5a01527406ed0bcbcf5a180d85b5e771deDaniel Veillard		    node->nsDef = ns->next;
2832f9cf6f5a01527406ed0bcbcf5a180d85b5e771deDaniel Veillard		ns->next = NULL;
2833f9cf6f5a01527406ed0bcbcf5a180d85b5e771deDaniel Veillard		c_retval = 0;
2834f9cf6f5a01527406ed0bcbcf5a180d85b5e771deDaniel Veillard		break;
2835f9cf6f5a01527406ed0bcbcf5a180d85b5e771deDaniel Veillard	    }
2836f9cf6f5a01527406ed0bcbcf5a180d85b5e771deDaniel Veillard	    prev = ns;
2837f9cf6f5a01527406ed0bcbcf5a180d85b5e771deDaniel Veillard	    ns = ns->next;
2838f9cf6f5a01527406ed0bcbcf5a180d85b5e771deDaniel Veillard	}
2839f9cf6f5a01527406ed0bcbcf5a180d85b5e771deDaniel Veillard    }
2840f9cf6f5a01527406ed0bcbcf5a180d85b5e771deDaniel Veillard
2841f9cf6f5a01527406ed0bcbcf5a180d85b5e771deDaniel Veillard    c_retval = ns;
2842f9cf6f5a01527406ed0bcbcf5a180d85b5e771deDaniel Veillard    py_retval = libxml_xmlNsPtrWrap((xmlNsPtr) c_retval);
2843f9cf6f5a01527406ed0bcbcf5a180d85b5e771deDaniel Veillard    return (py_retval);
2844f9cf6f5a01527406ed0bcbcf5a180d85b5e771deDaniel Veillard}
2845f9cf6f5a01527406ed0bcbcf5a180d85b5e771deDaniel Veillard
2846f9cf6f5a01527406ed0bcbcf5a180d85b5e771deDaniel VeillardPyObject *
2847d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillardlibxml_xmlNodeGetNs(ATTRIBUTE_UNUSED PyObject * self, PyObject * args)
2848d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard{
284936eea2d2ee84132e66552f84724e9b377d687681Daniel Veillard    PyObject *py_retval;
285036eea2d2ee84132e66552f84724e9b377d687681Daniel Veillard    xmlNsPtr c_retval;
285136eea2d2ee84132e66552f84724e9b377d687681Daniel Veillard    xmlNodePtr node;
285236eea2d2ee84132e66552f84724e9b377d687681Daniel Veillard    PyObject *pyobj_node;
285336eea2d2ee84132e66552f84724e9b377d687681Daniel Veillard
2854d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard    if (!PyArg_ParseTuple(args, (char *) "O:xmlNodeGetNs", &pyobj_node))
2855d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        return (NULL);
285636eea2d2ee84132e66552f84724e9b377d687681Daniel Veillard    node = (xmlNodePtr) PyxmlNode_Get(pyobj_node);
285736eea2d2ee84132e66552f84724e9b377d687681Daniel Veillard
2858e96a2a4bf040ec93f83d9c33f8ae4ac3f1e512e9Daniel Veillard    if ((node == NULL) ||
2859e96a2a4bf040ec93f83d9c33f8ae4ac3f1e512e9Daniel Veillard        ((node->type != XML_ELEMENT_NODE) &&
2860e96a2a4bf040ec93f83d9c33f8ae4ac3f1e512e9Daniel Veillard	 (node->type != XML_ATTRIBUTE_NODE))) {
2861d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        Py_INCREF(Py_None);
2862d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        return (Py_None);
286336eea2d2ee84132e66552f84724e9b377d687681Daniel Veillard    }
286436eea2d2ee84132e66552f84724e9b377d687681Daniel Veillard    c_retval = node->ns;
286536eea2d2ee84132e66552f84724e9b377d687681Daniel Veillard    py_retval = libxml_xmlNsPtrWrap((xmlNsPtr) c_retval);
2866d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard    return (py_retval);
286736eea2d2ee84132e66552f84724e9b377d687681Daniel Veillard}
286836eea2d2ee84132e66552f84724e9b377d687681Daniel Veillard
2869a9cce9cd0d7aff3ec318b5d8d376da131b6aaad4Daniel Veillard#ifdef LIBXML_OUTPUT_ENABLED
287036eea2d2ee84132e66552f84724e9b377d687681Daniel Veillard/************************************************************************
287136eea2d2ee84132e66552f84724e9b377d687681Daniel Veillard *									*
28721e77438da7dd912885effa97b1079867d1e041beDaniel Veillard *			Serialization front-end				*
28731e77438da7dd912885effa97b1079867d1e041beDaniel Veillard *									*
28741e77438da7dd912885effa97b1079867d1e041beDaniel Veillard ************************************************************************/
28751e77438da7dd912885effa97b1079867d1e041beDaniel Veillard
2876d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillardstatic PyObject *
2877d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillardlibxml_serializeNode(ATTRIBUTE_UNUSED PyObject * self, PyObject * args)
2878d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard{
28791e77438da7dd912885effa97b1079867d1e041beDaniel Veillard    PyObject *py_retval = NULL;
28801e77438da7dd912885effa97b1079867d1e041beDaniel Veillard    xmlChar *c_retval;
28811e77438da7dd912885effa97b1079867d1e041beDaniel Veillard    PyObject *pyobj_node;
28821e77438da7dd912885effa97b1079867d1e041beDaniel Veillard    xmlNodePtr node;
28831e77438da7dd912885effa97b1079867d1e041beDaniel Veillard    xmlDocPtr doc;
2884d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard    const char *encoding;
28851e77438da7dd912885effa97b1079867d1e041beDaniel Veillard    int format;
2886da3fee406da96c344d7b5f4e0631faee74f7e11dDaniel Veillard    xmlSaveCtxtPtr ctxt;
2887da3fee406da96c344d7b5f4e0631faee74f7e11dDaniel Veillard    xmlBufferPtr buf;
2888da3fee406da96c344d7b5f4e0631faee74f7e11dDaniel Veillard    int options = 0;
28891e77438da7dd912885effa97b1079867d1e041beDaniel Veillard
2890d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard    if (!PyArg_ParseTuple(args, (char *) "Ozi:serializeNode", &pyobj_node,
2891d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard                          &encoding, &format))
2892d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        return (NULL);
28931e77438da7dd912885effa97b1079867d1e041beDaniel Veillard    node = (xmlNodePtr) PyxmlNode_Get(pyobj_node);
28941e77438da7dd912885effa97b1079867d1e041beDaniel Veillard
28951e77438da7dd912885effa97b1079867d1e041beDaniel Veillard    if (node == NULL) {
2896d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        Py_INCREF(Py_None);
2897d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        return (Py_None);
28981e77438da7dd912885effa97b1079867d1e041beDaniel Veillard    }
28991e77438da7dd912885effa97b1079867d1e041beDaniel Veillard    if (node->type == XML_DOCUMENT_NODE) {
2900d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        doc = (xmlDocPtr) node;
2901da3fee406da96c344d7b5f4e0631faee74f7e11dDaniel Veillard	node = NULL;
2902656ce948ab664ce96298c5f419a03a7ffcc88d9dDaniel Veillard#ifdef LIBXML_HTML_ENABLED
29031e77438da7dd912885effa97b1079867d1e041beDaniel Veillard    } else if (node->type == XML_HTML_DOCUMENT_NODE) {
2904d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        doc = (xmlDocPtr) node;
2905da3fee406da96c344d7b5f4e0631faee74f7e11dDaniel Veillard	node = NULL;
2906da3fee406da96c344d7b5f4e0631faee74f7e11dDaniel Veillard#endif
29071e77438da7dd912885effa97b1079867d1e041beDaniel Veillard    } else {
290895af594b0bd28ad8847de96ec00ff9244bd94da7William M. Brack        if (node->type == XML_NAMESPACE_DECL)
290995af594b0bd28ad8847de96ec00ff9244bd94da7William M. Brack	    doc = NULL;
291095af594b0bd28ad8847de96ec00ff9244bd94da7William M. Brack	else
291195af594b0bd28ad8847de96ec00ff9244bd94da7William M. Brack            doc = node->doc;
2912a8c0adbc395e48f0a65ccbd6c4931525380cf55cDaniel Veillard        if ((doc == NULL) || (doc->type == XML_DOCUMENT_NODE)) {
2913656ce948ab664ce96298c5f419a03a7ffcc88d9dDaniel Veillard#ifdef LIBXML_HTML_ENABLED
2914d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        } else if (doc->type == XML_HTML_DOCUMENT_NODE) {
2915656ce948ab664ce96298c5f419a03a7ffcc88d9dDaniel Veillard#endif /* LIBXML_HTML_ENABLED */
2916d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        } else {
2917d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            Py_INCREF(Py_None);
2918d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            return (Py_None);
2919d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        }
29201e77438da7dd912885effa97b1079867d1e041beDaniel Veillard    }
2921da3fee406da96c344d7b5f4e0631faee74f7e11dDaniel Veillard
2922da3fee406da96c344d7b5f4e0631faee74f7e11dDaniel Veillard
2923da3fee406da96c344d7b5f4e0631faee74f7e11dDaniel Veillard    buf = xmlBufferCreate();
2924da3fee406da96c344d7b5f4e0631faee74f7e11dDaniel Veillard    if (buf == NULL) {
2925da3fee406da96c344d7b5f4e0631faee74f7e11dDaniel Veillard	Py_INCREF(Py_None);
2926da3fee406da96c344d7b5f4e0631faee74f7e11dDaniel Veillard	return (Py_None);
2927da3fee406da96c344d7b5f4e0631faee74f7e11dDaniel Veillard    }
2928da3fee406da96c344d7b5f4e0631faee74f7e11dDaniel Veillard    if (format) options |= XML_SAVE_FORMAT;
2929da3fee406da96c344d7b5f4e0631faee74f7e11dDaniel Veillard    ctxt = xmlSaveToBuffer(buf, encoding, options);
2930da3fee406da96c344d7b5f4e0631faee74f7e11dDaniel Veillard    if (ctxt == NULL) {
2931da3fee406da96c344d7b5f4e0631faee74f7e11dDaniel Veillard	xmlBufferFree(buf);
2932da3fee406da96c344d7b5f4e0631faee74f7e11dDaniel Veillard	Py_INCREF(Py_None);
2933da3fee406da96c344d7b5f4e0631faee74f7e11dDaniel Veillard	return (Py_None);
2934da3fee406da96c344d7b5f4e0631faee74f7e11dDaniel Veillard    }
2935da3fee406da96c344d7b5f4e0631faee74f7e11dDaniel Veillard    if (node == NULL)
2936da3fee406da96c344d7b5f4e0631faee74f7e11dDaniel Veillard	xmlSaveDoc(ctxt, doc);
2937da3fee406da96c344d7b5f4e0631faee74f7e11dDaniel Veillard    else
2938da3fee406da96c344d7b5f4e0631faee74f7e11dDaniel Veillard	xmlSaveTree(ctxt, node);
2939da3fee406da96c344d7b5f4e0631faee74f7e11dDaniel Veillard    xmlSaveClose(ctxt);
2940da3fee406da96c344d7b5f4e0631faee74f7e11dDaniel Veillard
2941da3fee406da96c344d7b5f4e0631faee74f7e11dDaniel Veillard    c_retval = buf->content;
2942da3fee406da96c344d7b5f4e0631faee74f7e11dDaniel Veillard    buf->content = NULL;
2943da3fee406da96c344d7b5f4e0631faee74f7e11dDaniel Veillard
2944da3fee406da96c344d7b5f4e0631faee74f7e11dDaniel Veillard    xmlBufferFree(buf);
2945da3fee406da96c344d7b5f4e0631faee74f7e11dDaniel Veillard    py_retval = libxml_charPtrWrap((char *) c_retval);
2946da3fee406da96c344d7b5f4e0631faee74f7e11dDaniel Veillard
2947d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard    return (py_retval);
29481e77438da7dd912885effa97b1079867d1e041beDaniel Veillard}
29491e77438da7dd912885effa97b1079867d1e041beDaniel Veillard
2950d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillardstatic PyObject *
2951d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillardlibxml_saveNodeTo(ATTRIBUTE_UNUSED PyObject * self, PyObject * args)
2952d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard{
29531e77438da7dd912885effa97b1079867d1e041beDaniel Veillard    PyObject *py_file = NULL;
29541e77438da7dd912885effa97b1079867d1e041beDaniel Veillard    FILE *output;
29551e77438da7dd912885effa97b1079867d1e041beDaniel Veillard    PyObject *pyobj_node;
29561e77438da7dd912885effa97b1079867d1e041beDaniel Veillard    xmlNodePtr node;
29571e77438da7dd912885effa97b1079867d1e041beDaniel Veillard    xmlDocPtr doc;
2958d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard    const char *encoding;
29591e77438da7dd912885effa97b1079867d1e041beDaniel Veillard    int format;
29601e77438da7dd912885effa97b1079867d1e041beDaniel Veillard    int len;
29611e77438da7dd912885effa97b1079867d1e041beDaniel Veillard    xmlOutputBufferPtr buf;
29621e77438da7dd912885effa97b1079867d1e041beDaniel Veillard    xmlCharEncodingHandlerPtr handler = NULL;
29631e77438da7dd912885effa97b1079867d1e041beDaniel Veillard
2964d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard    if (!PyArg_ParseTuple(args, (char *) "OOzi:serializeNode", &pyobj_node,
2965d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard                          &py_file, &encoding, &format))
2966d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        return (NULL);
29671e77438da7dd912885effa97b1079867d1e041beDaniel Veillard    node = (xmlNodePtr) PyxmlNode_Get(pyobj_node);
29681e77438da7dd912885effa97b1079867d1e041beDaniel Veillard
29691e77438da7dd912885effa97b1079867d1e041beDaniel Veillard    if (node == NULL) {
2970d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        return (PyInt_FromLong((long) -1));
29711e77438da7dd912885effa97b1079867d1e041beDaniel Veillard    }
29721e77438da7dd912885effa97b1079867d1e041beDaniel Veillard    if ((py_file == NULL) || (!(PyFile_Check(py_file)))) {
2973d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        return (PyInt_FromLong((long) -1));
29741e77438da7dd912885effa97b1079867d1e041beDaniel Veillard    }
29751e77438da7dd912885effa97b1079867d1e041beDaniel Veillard    output = PyFile_AsFile(py_file);
29761e77438da7dd912885effa97b1079867d1e041beDaniel Veillard    if (output == NULL) {
2977d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        return (PyInt_FromLong((long) -1));
29781e77438da7dd912885effa97b1079867d1e041beDaniel Veillard    }
29791e77438da7dd912885effa97b1079867d1e041beDaniel Veillard
29801e77438da7dd912885effa97b1079867d1e041beDaniel Veillard    if (node->type == XML_DOCUMENT_NODE) {
2981d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        doc = (xmlDocPtr) node;
29821e77438da7dd912885effa97b1079867d1e041beDaniel Veillard    } else if (node->type == XML_HTML_DOCUMENT_NODE) {
2983d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        doc = (xmlDocPtr) node;
29841e77438da7dd912885effa97b1079867d1e041beDaniel Veillard    } else {
2985d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        doc = node->doc;
29861e77438da7dd912885effa97b1079867d1e041beDaniel Veillard    }
2987656ce948ab664ce96298c5f419a03a7ffcc88d9dDaniel Veillard#ifdef LIBXML_HTML_ENABLED
29881e77438da7dd912885effa97b1079867d1e041beDaniel Veillard    if (doc->type == XML_HTML_DOCUMENT_NODE) {
2989d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        if (encoding == NULL)
2990d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            encoding = (const char *) htmlGetMetaEncoding(doc);
29911e77438da7dd912885effa97b1079867d1e041beDaniel Veillard    }
2992656ce948ab664ce96298c5f419a03a7ffcc88d9dDaniel Veillard#endif /* LIBXML_HTML_ENABLED */
29931e77438da7dd912885effa97b1079867d1e041beDaniel Veillard    if (encoding != NULL) {
2994d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        handler = xmlFindCharEncodingHandler(encoding);
2995d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        if (handler == NULL) {
2996d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            return (PyInt_FromLong((long) -1));
2997d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        }
29981e77438da7dd912885effa97b1079867d1e041beDaniel Veillard    }
29991e77438da7dd912885effa97b1079867d1e041beDaniel Veillard    if (doc->type == XML_HTML_DOCUMENT_NODE) {
3000d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        if (handler == NULL)
3001d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            handler = xmlFindCharEncodingHandler("HTML");
3002d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        if (handler == NULL)
3003d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard            handler = xmlFindCharEncodingHandler("ascii");
30041e77438da7dd912885effa97b1079867d1e041beDaniel Veillard    }
30051e77438da7dd912885effa97b1079867d1e041beDaniel Veillard
30061e77438da7dd912885effa97b1079867d1e041beDaniel Veillard    buf = xmlOutputBufferCreateFile(output, handler);
30071e77438da7dd912885effa97b1079867d1e041beDaniel Veillard    if (node->type == XML_DOCUMENT_NODE) {
3008d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        len = xmlSaveFormatFileTo(buf, doc, encoding, format);
3009656ce948ab664ce96298c5f419a03a7ffcc88d9dDaniel Veillard#ifdef LIBXML_HTML_ENABLED
30101e77438da7dd912885effa97b1079867d1e041beDaniel Veillard    } else if (node->type == XML_HTML_DOCUMENT_NODE) {
3011d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        htmlDocContentDumpFormatOutput(buf, doc, encoding, format);
3012d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        len = xmlOutputBufferClose(buf);
30131e77438da7dd912885effa97b1079867d1e041beDaniel Veillard    } else if (doc->type == XML_HTML_DOCUMENT_NODE) {
3014d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        htmlNodeDumpFormatOutput(buf, doc, node, encoding, format);
3015d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        len = xmlOutputBufferClose(buf);
3016656ce948ab664ce96298c5f419a03a7ffcc88d9dDaniel Veillard#endif /* LIBXML_HTML_ENABLED */
30171e77438da7dd912885effa97b1079867d1e041beDaniel Veillard    } else {
3018d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        xmlNodeDumpOutput(buf, doc, node, 0, format, encoding);
3019d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        len = xmlOutputBufferClose(buf);
30201e77438da7dd912885effa97b1079867d1e041beDaniel Veillard    }
3021d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard    return (PyInt_FromLong((long) len));
30221e77438da7dd912885effa97b1079867d1e041beDaniel Veillard}
3023a9cce9cd0d7aff3ec318b5d8d376da131b6aaad4Daniel Veillard#endif /* LIBXML_OUTPUT_ENABLED */
30241e77438da7dd912885effa97b1079867d1e041beDaniel Veillard
30251e77438da7dd912885effa97b1079867d1e041beDaniel Veillard/************************************************************************
30261e77438da7dd912885effa97b1079867d1e041beDaniel Veillard *									*
3027a94ec6ff13d9617ff22e790cef82208e7d1bd375Daniel Veillard *			Extra stuff					*
3028a94ec6ff13d9617ff22e790cef82208e7d1bd375Daniel Veillard *									*
3029a94ec6ff13d9617ff22e790cef82208e7d1bd375Daniel Veillard ************************************************************************/
3030a94ec6ff13d9617ff22e790cef82208e7d1bd375Daniel VeillardPyObject *
3031d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillardlibxml_xmlNewNode(ATTRIBUTE_UNUSED PyObject * self, PyObject * args)
3032d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard{
3033a94ec6ff13d9617ff22e790cef82208e7d1bd375Daniel Veillard    PyObject *py_retval;
3034d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard    xmlChar *name;
3035a94ec6ff13d9617ff22e790cef82208e7d1bd375Daniel Veillard    xmlNodePtr node;
3036a94ec6ff13d9617ff22e790cef82208e7d1bd375Daniel Veillard
3037d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard    if (!PyArg_ParseTuple(args, (char *) "s:xmlNewNode", &name))
3038d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        return (NULL);
3039a94ec6ff13d9617ff22e790cef82208e7d1bd375Daniel Veillard    node = (xmlNodePtr) xmlNewNode(NULL, name);
30403b2e4e1c1477e9eb0889a8c9d35da4ce36a2e3f1Daniel Veillard#ifdef DEBUG
3041d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard    printf("NewNode: %s : %p\n", name, (void *) node);
30423b2e4e1c1477e9eb0889a8c9d35da4ce36a2e3f1Daniel Veillard#endif
3043a94ec6ff13d9617ff22e790cef82208e7d1bd375Daniel Veillard
3044a94ec6ff13d9617ff22e790cef82208e7d1bd375Daniel Veillard    if (node == NULL) {
3045d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        Py_INCREF(Py_None);
3046d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        return (Py_None);
3047a94ec6ff13d9617ff22e790cef82208e7d1bd375Daniel Veillard    }
3048a94ec6ff13d9617ff22e790cef82208e7d1bd375Daniel Veillard    py_retval = libxml_xmlNodePtrWrap(node);
3049d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard    return (py_retval);
3050a94ec6ff13d9617ff22e790cef82208e7d1bd375Daniel Veillard}
3051a94ec6ff13d9617ff22e790cef82208e7d1bd375Daniel Veillard
30525439624bd9167dbb880ea4a75d91677d20a6ebe3Daniel Veillard
30535439624bd9167dbb880ea4a75d91677d20a6ebe3Daniel Veillard/************************************************************************
30545439624bd9167dbb880ea4a75d91677d20a6ebe3Daniel Veillard *									*
30555439624bd9167dbb880ea4a75d91677d20a6ebe3Daniel Veillard *			Local Catalog stuff				*
30565439624bd9167dbb880ea4a75d91677d20a6ebe3Daniel Veillard *									*
30575439624bd9167dbb880ea4a75d91677d20a6ebe3Daniel Veillard ************************************************************************/
30585439624bd9167dbb880ea4a75d91677d20a6ebe3Daniel Veillardstatic PyObject *
30595439624bd9167dbb880ea4a75d91677d20a6ebe3Daniel Veillardlibxml_addLocalCatalog(ATTRIBUTE_UNUSED PyObject * self, PyObject * args)
30605439624bd9167dbb880ea4a75d91677d20a6ebe3Daniel Veillard{
30615439624bd9167dbb880ea4a75d91677d20a6ebe3Daniel Veillard    xmlChar *URL;
30625439624bd9167dbb880ea4a75d91677d20a6ebe3Daniel Veillard    xmlParserCtxtPtr ctxt;
30635439624bd9167dbb880ea4a75d91677d20a6ebe3Daniel Veillard    PyObject *pyobj_ctxt;
30645439624bd9167dbb880ea4a75d91677d20a6ebe3Daniel Veillard
30655439624bd9167dbb880ea4a75d91677d20a6ebe3Daniel Veillard    if (!PyArg_ParseTuple(args, (char *)"Os:addLocalCatalog", &pyobj_ctxt, &URL))
30665439624bd9167dbb880ea4a75d91677d20a6ebe3Daniel Veillard        return(NULL);
30675439624bd9167dbb880ea4a75d91677d20a6ebe3Daniel Veillard
30685439624bd9167dbb880ea4a75d91677d20a6ebe3Daniel Veillard    ctxt = (xmlParserCtxtPtr) PyparserCtxt_Get(pyobj_ctxt);
30695439624bd9167dbb880ea4a75d91677d20a6ebe3Daniel Veillard
30705439624bd9167dbb880ea4a75d91677d20a6ebe3Daniel Veillard    if (URL != NULL) {
30715439624bd9167dbb880ea4a75d91677d20a6ebe3Daniel Veillard	ctxt->catalogs = xmlCatalogAddLocal(ctxt->catalogs, URL);
30725439624bd9167dbb880ea4a75d91677d20a6ebe3Daniel Veillard    }
30735439624bd9167dbb880ea4a75d91677d20a6ebe3Daniel Veillard
30745439624bd9167dbb880ea4a75d91677d20a6ebe3Daniel Veillard#ifdef DEBUG
30755439624bd9167dbb880ea4a75d91677d20a6ebe3Daniel Veillard    printf("LocalCatalog: %s\n", URL);
30765439624bd9167dbb880ea4a75d91677d20a6ebe3Daniel Veillard#endif
30775439624bd9167dbb880ea4a75d91677d20a6ebe3Daniel Veillard
30785439624bd9167dbb880ea4a75d91677d20a6ebe3Daniel Veillard    Py_INCREF(Py_None);
30795439624bd9167dbb880ea4a75d91677d20a6ebe3Daniel Veillard    return (Py_None);
30805439624bd9167dbb880ea4a75d91677d20a6ebe3Daniel Veillard}
30815439624bd9167dbb880ea4a75d91677d20a6ebe3Daniel Veillard
3082c2664641740126714bb363bd6b5f65f724031c83Daniel Veillard#ifdef LIBXML_SCHEMAS_ENABLED
3083c2664641740126714bb363bd6b5f65f724031c83Daniel Veillard
3084c2664641740126714bb363bd6b5f65f724031c83Daniel Veillard/************************************************************************
3085c2664641740126714bb363bd6b5f65f724031c83Daniel Veillard *                                                                      *
3086c2664641740126714bb363bd6b5f65f724031c83Daniel Veillard * RelaxNG error handler registration                                   *
3087c2664641740126714bb363bd6b5f65f724031c83Daniel Veillard *                                                                      *
3088c2664641740126714bb363bd6b5f65f724031c83Daniel Veillard ************************************************************************/
3089c2664641740126714bb363bd6b5f65f724031c83Daniel Veillard
3090c2664641740126714bb363bd6b5f65f724031c83Daniel Veillardtypedef struct
3091c2664641740126714bb363bd6b5f65f724031c83Daniel Veillard{
3092c2664641740126714bb363bd6b5f65f724031c83Daniel Veillard    PyObject *warn;
3093c2664641740126714bb363bd6b5f65f724031c83Daniel Veillard    PyObject *error;
3094c2664641740126714bb363bd6b5f65f724031c83Daniel Veillard    PyObject *arg;
3095c2664641740126714bb363bd6b5f65f724031c83Daniel Veillard} xmlRelaxNGValidCtxtPyCtxt;
3096c2664641740126714bb363bd6b5f65f724031c83Daniel Veillardtypedef xmlRelaxNGValidCtxtPyCtxt *xmlRelaxNGValidCtxtPyCtxtPtr;
3097c2664641740126714bb363bd6b5f65f724031c83Daniel Veillard
3098c2664641740126714bb363bd6b5f65f724031c83Daniel Veillardstatic void
3099c2664641740126714bb363bd6b5f65f724031c83Daniel Veillardlibxml_xmlRelaxNGValidityGenericErrorFuncHandler(void *ctx, char *str)
3100c2664641740126714bb363bd6b5f65f724031c83Daniel Veillard{
3101c2664641740126714bb363bd6b5f65f724031c83Daniel Veillard    PyObject *list;
3102c2664641740126714bb363bd6b5f65f724031c83Daniel Veillard    PyObject *result;
3103c2664641740126714bb363bd6b5f65f724031c83Daniel Veillard    xmlRelaxNGValidCtxtPyCtxtPtr pyCtxt;
3104c2664641740126714bb363bd6b5f65f724031c83Daniel Veillard
3105c2664641740126714bb363bd6b5f65f724031c83Daniel Veillard#ifdef DEBUG_ERROR
3106c2664641740126714bb363bd6b5f65f724031c83Daniel Veillard    printf("libxml_xmlRelaxNGValidityGenericErrorFuncHandler(%p, %s, ...) called\n", ctx, str);
3107c2664641740126714bb363bd6b5f65f724031c83Daniel Veillard#endif
3108c2664641740126714bb363bd6b5f65f724031c83Daniel Veillard
3109c2664641740126714bb363bd6b5f65f724031c83Daniel Veillard    pyCtxt = (xmlRelaxNGValidCtxtPyCtxtPtr)ctx;
3110c2664641740126714bb363bd6b5f65f724031c83Daniel Veillard
3111c2664641740126714bb363bd6b5f65f724031c83Daniel Veillard    list = PyTuple_New(2);
3112c2664641740126714bb363bd6b5f65f724031c83Daniel Veillard    PyTuple_SetItem(list, 0, libxml_charPtrWrap(str));
3113c2664641740126714bb363bd6b5f65f724031c83Daniel Veillard    PyTuple_SetItem(list, 1, pyCtxt->arg);
3114c2664641740126714bb363bd6b5f65f724031c83Daniel Veillard    Py_XINCREF(pyCtxt->arg);
3115c2664641740126714bb363bd6b5f65f724031c83Daniel Veillard    result = PyEval_CallObject(pyCtxt->error, list);
3116c2664641740126714bb363bd6b5f65f724031c83Daniel Veillard    if (result == NULL)
3117c2664641740126714bb363bd6b5f65f724031c83Daniel Veillard    {
3118c2664641740126714bb363bd6b5f65f724031c83Daniel Veillard        /* TODO: manage for the exception to be propagated... */
3119c2664641740126714bb363bd6b5f65f724031c83Daniel Veillard        PyErr_Print();
3120c2664641740126714bb363bd6b5f65f724031c83Daniel Veillard    }
3121c2664641740126714bb363bd6b5f65f724031c83Daniel Veillard    Py_XDECREF(list);
3122c2664641740126714bb363bd6b5f65f724031c83Daniel Veillard    Py_XDECREF(result);
3123c2664641740126714bb363bd6b5f65f724031c83Daniel Veillard}
3124c2664641740126714bb363bd6b5f65f724031c83Daniel Veillard
3125c2664641740126714bb363bd6b5f65f724031c83Daniel Veillardstatic void
3126c2664641740126714bb363bd6b5f65f724031c83Daniel Veillardlibxml_xmlRelaxNGValidityGenericWarningFuncHandler(void *ctx, char *str)
3127c2664641740126714bb363bd6b5f65f724031c83Daniel Veillard{
3128c2664641740126714bb363bd6b5f65f724031c83Daniel Veillard    PyObject *list;
3129c2664641740126714bb363bd6b5f65f724031c83Daniel Veillard    PyObject *result;
3130c2664641740126714bb363bd6b5f65f724031c83Daniel Veillard    xmlRelaxNGValidCtxtPyCtxtPtr pyCtxt;
3131c2664641740126714bb363bd6b5f65f724031c83Daniel Veillard
3132c2664641740126714bb363bd6b5f65f724031c83Daniel Veillard#ifdef DEBUG_ERROR
3133c2664641740126714bb363bd6b5f65f724031c83Daniel Veillard    printf("libxml_xmlRelaxNGValidityGenericWarningFuncHandler(%p, %s, ...) called\n", ctx, str);
3134c2664641740126714bb363bd6b5f65f724031c83Daniel Veillard#endif
3135c2664641740126714bb363bd6b5f65f724031c83Daniel Veillard
3136c2664641740126714bb363bd6b5f65f724031c83Daniel Veillard    pyCtxt = (xmlRelaxNGValidCtxtPyCtxtPtr)ctx;
3137c2664641740126714bb363bd6b5f65f724031c83Daniel Veillard
3138c2664641740126714bb363bd6b5f65f724031c83Daniel Veillard    list = PyTuple_New(2);
3139c2664641740126714bb363bd6b5f65f724031c83Daniel Veillard    PyTuple_SetItem(list, 0, libxml_charPtrWrap(str));
3140c2664641740126714bb363bd6b5f65f724031c83Daniel Veillard    PyTuple_SetItem(list, 1, pyCtxt->arg);
3141c2664641740126714bb363bd6b5f65f724031c83Daniel Veillard    Py_XINCREF(pyCtxt->arg);
3142c2664641740126714bb363bd6b5f65f724031c83Daniel Veillard    result = PyEval_CallObject(pyCtxt->warn, list);
3143c2664641740126714bb363bd6b5f65f724031c83Daniel Veillard    if (result == NULL)
3144c2664641740126714bb363bd6b5f65f724031c83Daniel Veillard    {
3145c2664641740126714bb363bd6b5f65f724031c83Daniel Veillard        /* TODO: manage for the exception to be propagated... */
3146c2664641740126714bb363bd6b5f65f724031c83Daniel Veillard        PyErr_Print();
3147c2664641740126714bb363bd6b5f65f724031c83Daniel Veillard    }
3148c2664641740126714bb363bd6b5f65f724031c83Daniel Veillard    Py_XDECREF(list);
3149c2664641740126714bb363bd6b5f65f724031c83Daniel Veillard    Py_XDECREF(result);
3150c2664641740126714bb363bd6b5f65f724031c83Daniel Veillard}
3151c2664641740126714bb363bd6b5f65f724031c83Daniel Veillard
3152c2664641740126714bb363bd6b5f65f724031c83Daniel Veillardstatic void
3153c2664641740126714bb363bd6b5f65f724031c83Daniel Veillardlibxml_xmlRelaxNGValidityErrorFunc(void *ctx, const char *msg, ...)
3154c2664641740126714bb363bd6b5f65f724031c83Daniel Veillard{
3155c2664641740126714bb363bd6b5f65f724031c83Daniel Veillard    va_list ap;
3156c2664641740126714bb363bd6b5f65f724031c83Daniel Veillard
3157c2664641740126714bb363bd6b5f65f724031c83Daniel Veillard    va_start(ap, msg);
3158c2664641740126714bb363bd6b5f65f724031c83Daniel Veillard    libxml_xmlRelaxNGValidityGenericErrorFuncHandler(ctx, libxml_buildMessage(msg, ap));
3159c2664641740126714bb363bd6b5f65f724031c83Daniel Veillard    va_end(ap);
3160c2664641740126714bb363bd6b5f65f724031c83Daniel Veillard}
3161c2664641740126714bb363bd6b5f65f724031c83Daniel Veillard
3162c2664641740126714bb363bd6b5f65f724031c83Daniel Veillardstatic void
3163c2664641740126714bb363bd6b5f65f724031c83Daniel Veillardlibxml_xmlRelaxNGValidityWarningFunc(void *ctx, const char *msg, ...)
3164c2664641740126714bb363bd6b5f65f724031c83Daniel Veillard{
3165c2664641740126714bb363bd6b5f65f724031c83Daniel Veillard    va_list ap;
3166c2664641740126714bb363bd6b5f65f724031c83Daniel Veillard
3167c2664641740126714bb363bd6b5f65f724031c83Daniel Veillard    va_start(ap, msg);
3168c2664641740126714bb363bd6b5f65f724031c83Daniel Veillard    libxml_xmlRelaxNGValidityGenericWarningFuncHandler(ctx, libxml_buildMessage(msg, ap));
3169c2664641740126714bb363bd6b5f65f724031c83Daniel Veillard    va_end(ap);
3170c2664641740126714bb363bd6b5f65f724031c83Daniel Veillard}
3171c2664641740126714bb363bd6b5f65f724031c83Daniel Veillard
3172c2664641740126714bb363bd6b5f65f724031c83Daniel Veillardstatic PyObject *
3173c2664641740126714bb363bd6b5f65f724031c83Daniel Veillardlibxml_xmlRelaxNGSetValidErrors(ATTRIBUTE_UNUSED PyObject * self, PyObject * args)
3174c2664641740126714bb363bd6b5f65f724031c83Daniel Veillard{
3175c2664641740126714bb363bd6b5f65f724031c83Daniel Veillard    PyObject *py_retval;
3176c2664641740126714bb363bd6b5f65f724031c83Daniel Veillard    PyObject *pyobj_error;
3177c2664641740126714bb363bd6b5f65f724031c83Daniel Veillard    PyObject *pyobj_warn;
3178c2664641740126714bb363bd6b5f65f724031c83Daniel Veillard    PyObject *pyobj_ctx;
3179c2664641740126714bb363bd6b5f65f724031c83Daniel Veillard    PyObject *pyobj_arg = Py_None;
3180c2664641740126714bb363bd6b5f65f724031c83Daniel Veillard    xmlRelaxNGValidCtxtPtr ctxt;
3181c2664641740126714bb363bd6b5f65f724031c83Daniel Veillard    xmlRelaxNGValidCtxtPyCtxtPtr pyCtxt;
3182c2664641740126714bb363bd6b5f65f724031c83Daniel Veillard
3183c2664641740126714bb363bd6b5f65f724031c83Daniel Veillard    if (!PyArg_ParseTuple
3184c2664641740126714bb363bd6b5f65f724031c83Daniel Veillard        (args, (char *) "OOO|O:xmlRelaxNGSetValidErrors", &pyobj_ctx, &pyobj_error, &pyobj_warn, &pyobj_arg))
3185c2664641740126714bb363bd6b5f65f724031c83Daniel Veillard        return (NULL);
3186c2664641740126714bb363bd6b5f65f724031c83Daniel Veillard
3187c2664641740126714bb363bd6b5f65f724031c83Daniel Veillard#ifdef DEBUG_ERROR
3188c2664641740126714bb363bd6b5f65f724031c83Daniel Veillard    printf("libxml_xmlRelaxNGSetValidErrors(%p, %p, %p) called\n", pyobj_ctx, pyobj_error, pyobj_warn);
3189c2664641740126714bb363bd6b5f65f724031c83Daniel Veillard#endif
3190c2664641740126714bb363bd6b5f65f724031c83Daniel Veillard
3191c2664641740126714bb363bd6b5f65f724031c83Daniel Veillard    ctxt = PyrelaxNgValidCtxt_Get(pyobj_ctx);
3192c193956ee1c3b229556301cf09f6ff1b6eb9cb70William M. Brack    if (xmlRelaxNGGetValidErrors(ctxt, NULL, NULL, (void **) &pyCtxt) == -1)
3193c2664641740126714bb363bd6b5f65f724031c83Daniel Veillard    {
3194c2664641740126714bb363bd6b5f65f724031c83Daniel Veillard        py_retval = libxml_intWrap(-1);
3195c2664641740126714bb363bd6b5f65f724031c83Daniel Veillard        return(py_retval);
3196c2664641740126714bb363bd6b5f65f724031c83Daniel Veillard    }
3197c2664641740126714bb363bd6b5f65f724031c83Daniel Veillard
3198c2664641740126714bb363bd6b5f65f724031c83Daniel Veillard    if (pyCtxt == NULL)
3199c2664641740126714bb363bd6b5f65f724031c83Daniel Veillard    {
3200c2664641740126714bb363bd6b5f65f724031c83Daniel Veillard        /* first time to set the error handlers */
3201c2664641740126714bb363bd6b5f65f724031c83Daniel Veillard        pyCtxt = xmlMalloc(sizeof(xmlRelaxNGValidCtxtPyCtxt));
3202c2664641740126714bb363bd6b5f65f724031c83Daniel Veillard        if (pyCtxt == NULL) {
3203c2664641740126714bb363bd6b5f65f724031c83Daniel Veillard            py_retval = libxml_intWrap(-1);
3204c2664641740126714bb363bd6b5f65f724031c83Daniel Veillard            return(py_retval);
3205c2664641740126714bb363bd6b5f65f724031c83Daniel Veillard        }
3206c2664641740126714bb363bd6b5f65f724031c83Daniel Veillard        memset(pyCtxt, 0, sizeof(xmlRelaxNGValidCtxtPyCtxt));
3207c2664641740126714bb363bd6b5f65f724031c83Daniel Veillard    }
3208c2664641740126714bb363bd6b5f65f724031c83Daniel Veillard
3209c2664641740126714bb363bd6b5f65f724031c83Daniel Veillard    /* TODO: check warn and error is a function ! */
3210c2664641740126714bb363bd6b5f65f724031c83Daniel Veillard    Py_XDECREF(pyCtxt->error);
3211c2664641740126714bb363bd6b5f65f724031c83Daniel Veillard    Py_XINCREF(pyobj_error);
3212c2664641740126714bb363bd6b5f65f724031c83Daniel Veillard    pyCtxt->error = pyobj_error;
3213c2664641740126714bb363bd6b5f65f724031c83Daniel Veillard
3214c2664641740126714bb363bd6b5f65f724031c83Daniel Veillard    Py_XDECREF(pyCtxt->warn);
3215c2664641740126714bb363bd6b5f65f724031c83Daniel Veillard    Py_XINCREF(pyobj_warn);
3216c2664641740126714bb363bd6b5f65f724031c83Daniel Veillard    pyCtxt->warn = pyobj_warn;
3217c2664641740126714bb363bd6b5f65f724031c83Daniel Veillard
3218c2664641740126714bb363bd6b5f65f724031c83Daniel Veillard    Py_XDECREF(pyCtxt->arg);
3219c2664641740126714bb363bd6b5f65f724031c83Daniel Veillard    Py_XINCREF(pyobj_arg);
3220c2664641740126714bb363bd6b5f65f724031c83Daniel Veillard    pyCtxt->arg = pyobj_arg;
3221c2664641740126714bb363bd6b5f65f724031c83Daniel Veillard
3222c2664641740126714bb363bd6b5f65f724031c83Daniel Veillard    xmlRelaxNGSetValidErrors(ctxt, &libxml_xmlRelaxNGValidityErrorFunc, &libxml_xmlRelaxNGValidityWarningFunc, pyCtxt);
3223c2664641740126714bb363bd6b5f65f724031c83Daniel Veillard
3224c2664641740126714bb363bd6b5f65f724031c83Daniel Veillard    py_retval = libxml_intWrap(1);
3225c2664641740126714bb363bd6b5f65f724031c83Daniel Veillard    return (py_retval);
3226c2664641740126714bb363bd6b5f65f724031c83Daniel Veillard}
3227c2664641740126714bb363bd6b5f65f724031c83Daniel Veillard
3228c2664641740126714bb363bd6b5f65f724031c83Daniel Veillardstatic PyObject *
3229c2664641740126714bb363bd6b5f65f724031c83Daniel Veillardlibxml_xmlRelaxNGFreeValidCtxt(ATTRIBUTE_UNUSED PyObject *self, PyObject *args) {
3230c2664641740126714bb363bd6b5f65f724031c83Daniel Veillard    xmlRelaxNGValidCtxtPtr ctxt;
3231c2664641740126714bb363bd6b5f65f724031c83Daniel Veillard    xmlRelaxNGValidCtxtPyCtxtPtr pyCtxt;
3232c2664641740126714bb363bd6b5f65f724031c83Daniel Veillard    PyObject *pyobj_ctxt;
3233c2664641740126714bb363bd6b5f65f724031c83Daniel Veillard
3234c2664641740126714bb363bd6b5f65f724031c83Daniel Veillard    if (!PyArg_ParseTuple(args, (char *)"O:xmlRelaxNGFreeValidCtxt", &pyobj_ctxt))
3235c2664641740126714bb363bd6b5f65f724031c83Daniel Veillard        return(NULL);
3236c2664641740126714bb363bd6b5f65f724031c83Daniel Veillard    ctxt = (xmlRelaxNGValidCtxtPtr) PyrelaxNgValidCtxt_Get(pyobj_ctxt);
3237c2664641740126714bb363bd6b5f65f724031c83Daniel Veillard
3238c193956ee1c3b229556301cf09f6ff1b6eb9cb70William M. Brack    if (xmlRelaxNGGetValidErrors(ctxt, NULL, NULL, (void **) &pyCtxt) == 0)
3239c2664641740126714bb363bd6b5f65f724031c83Daniel Veillard    {
3240c2664641740126714bb363bd6b5f65f724031c83Daniel Veillard        if (pyCtxt != NULL)
3241c2664641740126714bb363bd6b5f65f724031c83Daniel Veillard        {
3242c2664641740126714bb363bd6b5f65f724031c83Daniel Veillard            Py_XDECREF(pyCtxt->error);
3243c2664641740126714bb363bd6b5f65f724031c83Daniel Veillard            Py_XDECREF(pyCtxt->warn);
3244c2664641740126714bb363bd6b5f65f724031c83Daniel Veillard            Py_XDECREF(pyCtxt->arg);
3245c2664641740126714bb363bd6b5f65f724031c83Daniel Veillard            xmlFree(pyCtxt);
3246c2664641740126714bb363bd6b5f65f724031c83Daniel Veillard        }
3247c2664641740126714bb363bd6b5f65f724031c83Daniel Veillard    }
3248c2664641740126714bb363bd6b5f65f724031c83Daniel Veillard
3249c2664641740126714bb363bd6b5f65f724031c83Daniel Veillard    xmlRelaxNGFreeValidCtxt(ctxt);
3250c2664641740126714bb363bd6b5f65f724031c83Daniel Veillard    Py_INCREF(Py_None);
3251c2664641740126714bb363bd6b5f65f724031c83Daniel Veillard    return(Py_None);
3252c2664641740126714bb363bd6b5f65f724031c83Daniel Veillard}
3253c2664641740126714bb363bd6b5f65f724031c83Daniel Veillard
3254259f0dfa8b4f29158954959b4d0d7c03dd1eab05Daniel Veillardtypedef struct
3255259f0dfa8b4f29158954959b4d0d7c03dd1eab05Daniel Veillard{
3256259f0dfa8b4f29158954959b4d0d7c03dd1eab05Daniel Veillard	PyObject *warn;
3257259f0dfa8b4f29158954959b4d0d7c03dd1eab05Daniel Veillard	PyObject *error;
3258259f0dfa8b4f29158954959b4d0d7c03dd1eab05Daniel Veillard	PyObject *arg;
3259259f0dfa8b4f29158954959b4d0d7c03dd1eab05Daniel Veillard} xmlSchemaValidCtxtPyCtxt;
3260259f0dfa8b4f29158954959b4d0d7c03dd1eab05Daniel Veillardtypedef xmlSchemaValidCtxtPyCtxt *xmlSchemaValidCtxtPyCtxtPtr;
3261259f0dfa8b4f29158954959b4d0d7c03dd1eab05Daniel Veillard
3262259f0dfa8b4f29158954959b4d0d7c03dd1eab05Daniel Veillardstatic void
3263259f0dfa8b4f29158954959b4d0d7c03dd1eab05Daniel Veillardlibxml_xmlSchemaValidityGenericErrorFuncHandler(void *ctx, char *str)
3264259f0dfa8b4f29158954959b4d0d7c03dd1eab05Daniel Veillard{
3265259f0dfa8b4f29158954959b4d0d7c03dd1eab05Daniel Veillard	PyObject *list;
3266259f0dfa8b4f29158954959b4d0d7c03dd1eab05Daniel Veillard	PyObject *result;
3267259f0dfa8b4f29158954959b4d0d7c03dd1eab05Daniel Veillard	xmlSchemaValidCtxtPyCtxtPtr pyCtxt;
3268259f0dfa8b4f29158954959b4d0d7c03dd1eab05Daniel Veillard
3269259f0dfa8b4f29158954959b4d0d7c03dd1eab05Daniel Veillard#ifdef DEBUG_ERROR
3270259f0dfa8b4f29158954959b4d0d7c03dd1eab05Daniel Veillard	printf("libxml_xmlSchemaValiditiyGenericErrorFuncHandler(%p, %s, ...) called\n", ctx, str);
3271259f0dfa8b4f29158954959b4d0d7c03dd1eab05Daniel Veillard#endif
3272259f0dfa8b4f29158954959b4d0d7c03dd1eab05Daniel Veillard
3273259f0dfa8b4f29158954959b4d0d7c03dd1eab05Daniel Veillard	pyCtxt = (xmlSchemaValidCtxtPyCtxtPtr) ctx;
3274259f0dfa8b4f29158954959b4d0d7c03dd1eab05Daniel Veillard
3275259f0dfa8b4f29158954959b4d0d7c03dd1eab05Daniel Veillard	list = PyTuple_New(2);
3276259f0dfa8b4f29158954959b4d0d7c03dd1eab05Daniel Veillard	PyTuple_SetItem(list, 0, libxml_charPtrWrap(str));
3277259f0dfa8b4f29158954959b4d0d7c03dd1eab05Daniel Veillard	PyTuple_SetItem(list, 1, pyCtxt->arg);
3278259f0dfa8b4f29158954959b4d0d7c03dd1eab05Daniel Veillard	Py_XINCREF(pyCtxt->arg);
3279259f0dfa8b4f29158954959b4d0d7c03dd1eab05Daniel Veillard	result = PyEval_CallObject(pyCtxt->error, list);
3280259f0dfa8b4f29158954959b4d0d7c03dd1eab05Daniel Veillard	if (result == NULL)
3281259f0dfa8b4f29158954959b4d0d7c03dd1eab05Daniel Veillard	{
3282259f0dfa8b4f29158954959b4d0d7c03dd1eab05Daniel Veillard		/* TODO: manage for the exception to be propagated... */
3283259f0dfa8b4f29158954959b4d0d7c03dd1eab05Daniel Veillard		PyErr_Print();
3284259f0dfa8b4f29158954959b4d0d7c03dd1eab05Daniel Veillard	}
3285259f0dfa8b4f29158954959b4d0d7c03dd1eab05Daniel Veillard	Py_XDECREF(list);
3286259f0dfa8b4f29158954959b4d0d7c03dd1eab05Daniel Veillard	Py_XDECREF(result);
3287259f0dfa8b4f29158954959b4d0d7c03dd1eab05Daniel Veillard}
3288259f0dfa8b4f29158954959b4d0d7c03dd1eab05Daniel Veillard
3289259f0dfa8b4f29158954959b4d0d7c03dd1eab05Daniel Veillardstatic void
3290259f0dfa8b4f29158954959b4d0d7c03dd1eab05Daniel Veillardlibxml_xmlSchemaValidityGenericWarningFuncHandler(void *ctx, char *str)
3291259f0dfa8b4f29158954959b4d0d7c03dd1eab05Daniel Veillard{
3292259f0dfa8b4f29158954959b4d0d7c03dd1eab05Daniel Veillard	PyObject *list;
3293259f0dfa8b4f29158954959b4d0d7c03dd1eab05Daniel Veillard	PyObject *result;
3294259f0dfa8b4f29158954959b4d0d7c03dd1eab05Daniel Veillard	xmlSchemaValidCtxtPyCtxtPtr pyCtxt;
3295259f0dfa8b4f29158954959b4d0d7c03dd1eab05Daniel Veillard
3296259f0dfa8b4f29158954959b4d0d7c03dd1eab05Daniel Veillard#ifdef DEBUG_ERROR
3297259f0dfa8b4f29158954959b4d0d7c03dd1eab05Daniel Veillard	printf("libxml_xmlSchemaValidityGenericWarningFuncHandler(%p, %s, ...) called\n", ctx, str);
3298259f0dfa8b4f29158954959b4d0d7c03dd1eab05Daniel Veillard#endif
3299259f0dfa8b4f29158954959b4d0d7c03dd1eab05Daniel Veillard
3300259f0dfa8b4f29158954959b4d0d7c03dd1eab05Daniel Veillard	pyCtxt = (xmlSchemaValidCtxtPyCtxtPtr) ctx;
3301259f0dfa8b4f29158954959b4d0d7c03dd1eab05Daniel Veillard
3302259f0dfa8b4f29158954959b4d0d7c03dd1eab05Daniel Veillard	list = PyTuple_New(2);
3303259f0dfa8b4f29158954959b4d0d7c03dd1eab05Daniel Veillard	PyTuple_SetItem(list, 0, libxml_charPtrWrap(str));
3304259f0dfa8b4f29158954959b4d0d7c03dd1eab05Daniel Veillard	PyTuple_SetItem(list, 1, pyCtxt->arg);
3305259f0dfa8b4f29158954959b4d0d7c03dd1eab05Daniel Veillard	Py_XINCREF(pyCtxt->arg);
3306259f0dfa8b4f29158954959b4d0d7c03dd1eab05Daniel Veillard	result = PyEval_CallObject(pyCtxt->warn, list);
3307259f0dfa8b4f29158954959b4d0d7c03dd1eab05Daniel Veillard	if (result == NULL)
3308259f0dfa8b4f29158954959b4d0d7c03dd1eab05Daniel Veillard	{
3309259f0dfa8b4f29158954959b4d0d7c03dd1eab05Daniel Veillard		/* TODO: manage for the exception to be propagated... */
3310259f0dfa8b4f29158954959b4d0d7c03dd1eab05Daniel Veillard		PyErr_Print();
3311259f0dfa8b4f29158954959b4d0d7c03dd1eab05Daniel Veillard	}
3312259f0dfa8b4f29158954959b4d0d7c03dd1eab05Daniel Veillard	Py_XDECREF(list);
3313259f0dfa8b4f29158954959b4d0d7c03dd1eab05Daniel Veillard	Py_XDECREF(result);
3314259f0dfa8b4f29158954959b4d0d7c03dd1eab05Daniel Veillard}
3315259f0dfa8b4f29158954959b4d0d7c03dd1eab05Daniel Veillard
3316259f0dfa8b4f29158954959b4d0d7c03dd1eab05Daniel Veillardstatic void
3317259f0dfa8b4f29158954959b4d0d7c03dd1eab05Daniel Veillardlibxml_xmlSchemaValidityErrorFunc(void *ctx, const char *msg, ...)
3318259f0dfa8b4f29158954959b4d0d7c03dd1eab05Daniel Veillard{
3319259f0dfa8b4f29158954959b4d0d7c03dd1eab05Daniel Veillard	va_list ap;
3320259f0dfa8b4f29158954959b4d0d7c03dd1eab05Daniel Veillard
3321259f0dfa8b4f29158954959b4d0d7c03dd1eab05Daniel Veillard	va_start(ap, msg);
3322259f0dfa8b4f29158954959b4d0d7c03dd1eab05Daniel Veillard	libxml_xmlSchemaValidityGenericErrorFuncHandler(ctx, libxml_buildMessage(msg, ap));
3323259f0dfa8b4f29158954959b4d0d7c03dd1eab05Daniel Veillard	va_end(ap);
3324259f0dfa8b4f29158954959b4d0d7c03dd1eab05Daniel Veillard}
3325259f0dfa8b4f29158954959b4d0d7c03dd1eab05Daniel Veillard
3326259f0dfa8b4f29158954959b4d0d7c03dd1eab05Daniel Veillardstatic void
3327259f0dfa8b4f29158954959b4d0d7c03dd1eab05Daniel Veillardlibxml_xmlSchemaValidityWarningFunc(void *ctx, const char *msg, ...)
3328259f0dfa8b4f29158954959b4d0d7c03dd1eab05Daniel Veillard{
3329259f0dfa8b4f29158954959b4d0d7c03dd1eab05Daniel Veillard	va_list ap;
3330259f0dfa8b4f29158954959b4d0d7c03dd1eab05Daniel Veillard
3331259f0dfa8b4f29158954959b4d0d7c03dd1eab05Daniel Veillard	va_start(ap, msg);
3332259f0dfa8b4f29158954959b4d0d7c03dd1eab05Daniel Veillard	libxml_xmlSchemaValidityGenericWarningFuncHandler(ctx, libxml_buildMessage(msg, ap));
3333259f0dfa8b4f29158954959b4d0d7c03dd1eab05Daniel Veillard	va_end(ap);
3334259f0dfa8b4f29158954959b4d0d7c03dd1eab05Daniel Veillard}
3335259f0dfa8b4f29158954959b4d0d7c03dd1eab05Daniel Veillard
33366ebf3c4c1a78406d15e8629b4a7b3d52549f0c8bDaniel VeillardPyObject *
3337259f0dfa8b4f29158954959b4d0d7c03dd1eab05Daniel Veillardlibxml_xmlSchemaSetValidErrors(ATTRIBUTE_UNUSED PyObject * self, PyObject * args)
3338259f0dfa8b4f29158954959b4d0d7c03dd1eab05Daniel Veillard{
3339259f0dfa8b4f29158954959b4d0d7c03dd1eab05Daniel Veillard	PyObject *py_retval;
3340259f0dfa8b4f29158954959b4d0d7c03dd1eab05Daniel Veillard	PyObject *pyobj_error;
3341259f0dfa8b4f29158954959b4d0d7c03dd1eab05Daniel Veillard	PyObject *pyobj_warn;
3342259f0dfa8b4f29158954959b4d0d7c03dd1eab05Daniel Veillard	PyObject *pyobj_ctx;
3343259f0dfa8b4f29158954959b4d0d7c03dd1eab05Daniel Veillard	PyObject *pyobj_arg = Py_None;
3344259f0dfa8b4f29158954959b4d0d7c03dd1eab05Daniel Veillard	xmlSchemaValidCtxtPtr ctxt;
3345259f0dfa8b4f29158954959b4d0d7c03dd1eab05Daniel Veillard	xmlSchemaValidCtxtPyCtxtPtr pyCtxt;
3346259f0dfa8b4f29158954959b4d0d7c03dd1eab05Daniel Veillard
3347259f0dfa8b4f29158954959b4d0d7c03dd1eab05Daniel Veillard	if (!PyArg_ParseTuple
3348259f0dfa8b4f29158954959b4d0d7c03dd1eab05Daniel Veillard		(args, (char *) "OOO|O:xmlSchemaSetValidErrors", &pyobj_ctx, &pyobj_error, &pyobj_warn, &pyobj_arg))
3349259f0dfa8b4f29158954959b4d0d7c03dd1eab05Daniel Veillard		return (NULL);
3350259f0dfa8b4f29158954959b4d0d7c03dd1eab05Daniel Veillard
3351259f0dfa8b4f29158954959b4d0d7c03dd1eab05Daniel Veillard#ifdef DEBUG_ERROR
3352259f0dfa8b4f29158954959b4d0d7c03dd1eab05Daniel Veillard	printf("libxml_xmlSchemaSetValidErrors(%p, %p, %p) called\n", pyobj_ctx, pyobj_error, pyobj_warn);
3353259f0dfa8b4f29158954959b4d0d7c03dd1eab05Daniel Veillard#endif
3354259f0dfa8b4f29158954959b4d0d7c03dd1eab05Daniel Veillard
3355259f0dfa8b4f29158954959b4d0d7c03dd1eab05Daniel Veillard	ctxt = PySchemaValidCtxt_Get(pyobj_ctx);
3356259f0dfa8b4f29158954959b4d0d7c03dd1eab05Daniel Veillard	if (xmlSchemaGetValidErrors(ctxt, NULL, NULL, (void **) &pyCtxt) == -1)
3357259f0dfa8b4f29158954959b4d0d7c03dd1eab05Daniel Veillard	{
3358259f0dfa8b4f29158954959b4d0d7c03dd1eab05Daniel Veillard		py_retval = libxml_intWrap(-1);
3359259f0dfa8b4f29158954959b4d0d7c03dd1eab05Daniel Veillard		return(py_retval);
3360259f0dfa8b4f29158954959b4d0d7c03dd1eab05Daniel Veillard	}
3361259f0dfa8b4f29158954959b4d0d7c03dd1eab05Daniel Veillard
3362259f0dfa8b4f29158954959b4d0d7c03dd1eab05Daniel Veillard	if (pyCtxt == NULL)
3363259f0dfa8b4f29158954959b4d0d7c03dd1eab05Daniel Veillard	{
3364259f0dfa8b4f29158954959b4d0d7c03dd1eab05Daniel Veillard		/* first time to set the error handlers */
3365259f0dfa8b4f29158954959b4d0d7c03dd1eab05Daniel Veillard		pyCtxt = xmlMalloc(sizeof(xmlSchemaValidCtxtPyCtxt));
3366259f0dfa8b4f29158954959b4d0d7c03dd1eab05Daniel Veillard		if (pyCtxt == NULL) {
3367259f0dfa8b4f29158954959b4d0d7c03dd1eab05Daniel Veillard			py_retval = libxml_intWrap(-1);
3368259f0dfa8b4f29158954959b4d0d7c03dd1eab05Daniel Veillard			return(py_retval);
3369259f0dfa8b4f29158954959b4d0d7c03dd1eab05Daniel Veillard		}
3370259f0dfa8b4f29158954959b4d0d7c03dd1eab05Daniel Veillard		memset(pyCtxt, 0, sizeof(xmlSchemaValidCtxtPyCtxt));
3371259f0dfa8b4f29158954959b4d0d7c03dd1eab05Daniel Veillard	}
3372259f0dfa8b4f29158954959b4d0d7c03dd1eab05Daniel Veillard
3373259f0dfa8b4f29158954959b4d0d7c03dd1eab05Daniel Veillard	/* TODO: check warn and error is a function ! */
3374259f0dfa8b4f29158954959b4d0d7c03dd1eab05Daniel Veillard	Py_XDECREF(pyCtxt->error);
3375259f0dfa8b4f29158954959b4d0d7c03dd1eab05Daniel Veillard	Py_XINCREF(pyobj_error);
3376259f0dfa8b4f29158954959b4d0d7c03dd1eab05Daniel Veillard	pyCtxt->error = pyobj_error;
3377259f0dfa8b4f29158954959b4d0d7c03dd1eab05Daniel Veillard
3378259f0dfa8b4f29158954959b4d0d7c03dd1eab05Daniel Veillard	Py_XDECREF(pyCtxt->warn);
3379259f0dfa8b4f29158954959b4d0d7c03dd1eab05Daniel Veillard	Py_XINCREF(pyobj_warn);
3380259f0dfa8b4f29158954959b4d0d7c03dd1eab05Daniel Veillard	pyCtxt->warn = pyobj_warn;
3381259f0dfa8b4f29158954959b4d0d7c03dd1eab05Daniel Veillard
3382259f0dfa8b4f29158954959b4d0d7c03dd1eab05Daniel Veillard	Py_XDECREF(pyCtxt->arg);
3383259f0dfa8b4f29158954959b4d0d7c03dd1eab05Daniel Veillard	Py_XINCREF(pyobj_arg);
3384259f0dfa8b4f29158954959b4d0d7c03dd1eab05Daniel Veillard	pyCtxt->arg = pyobj_arg;
3385259f0dfa8b4f29158954959b4d0d7c03dd1eab05Daniel Veillard
3386259f0dfa8b4f29158954959b4d0d7c03dd1eab05Daniel Veillard	xmlSchemaSetValidErrors(ctxt, &libxml_xmlSchemaValidityErrorFunc, &libxml_xmlSchemaValidityWarningFunc, pyCtxt);
3387259f0dfa8b4f29158954959b4d0d7c03dd1eab05Daniel Veillard
3388259f0dfa8b4f29158954959b4d0d7c03dd1eab05Daniel Veillard	py_retval = libxml_intWrap(1);
3389259f0dfa8b4f29158954959b4d0d7c03dd1eab05Daniel Veillard	return(py_retval);
3390259f0dfa8b4f29158954959b4d0d7c03dd1eab05Daniel Veillard}
3391259f0dfa8b4f29158954959b4d0d7c03dd1eab05Daniel Veillard
3392bb8502c0ef2af706fbdff69119e994e40da64a88Daniel Veillardstatic PyObject *
3393259f0dfa8b4f29158954959b4d0d7c03dd1eab05Daniel Veillardlibxml_xmlSchemaFreeValidCtxt(ATTRIBUTE_UNUSED PyObject * self, PyObject * args)
3394259f0dfa8b4f29158954959b4d0d7c03dd1eab05Daniel Veillard{
3395259f0dfa8b4f29158954959b4d0d7c03dd1eab05Daniel Veillard	xmlSchemaValidCtxtPtr ctxt;
3396259f0dfa8b4f29158954959b4d0d7c03dd1eab05Daniel Veillard	xmlSchemaValidCtxtPyCtxtPtr pyCtxt;
3397259f0dfa8b4f29158954959b4d0d7c03dd1eab05Daniel Veillard	PyObject *pyobj_ctxt;
3398259f0dfa8b4f29158954959b4d0d7c03dd1eab05Daniel Veillard
3399259f0dfa8b4f29158954959b4d0d7c03dd1eab05Daniel Veillard	if (!PyArg_ParseTuple(args, (char *)"O:xmlSchemaFreeValidCtxt", &pyobj_ctxt))
3400259f0dfa8b4f29158954959b4d0d7c03dd1eab05Daniel Veillard		return(NULL);
3401259f0dfa8b4f29158954959b4d0d7c03dd1eab05Daniel Veillard	ctxt = (xmlSchemaValidCtxtPtr) PySchemaValidCtxt_Get(pyobj_ctxt);
3402259f0dfa8b4f29158954959b4d0d7c03dd1eab05Daniel Veillard
3403259f0dfa8b4f29158954959b4d0d7c03dd1eab05Daniel Veillard	if (xmlSchemaGetValidErrors(ctxt, NULL, NULL, (void **) &pyCtxt) == 0)
3404259f0dfa8b4f29158954959b4d0d7c03dd1eab05Daniel Veillard	{
3405259f0dfa8b4f29158954959b4d0d7c03dd1eab05Daniel Veillard		if (pyCtxt != NULL)
3406259f0dfa8b4f29158954959b4d0d7c03dd1eab05Daniel Veillard		{
3407259f0dfa8b4f29158954959b4d0d7c03dd1eab05Daniel Veillard			Py_XDECREF(pyCtxt->error);
3408259f0dfa8b4f29158954959b4d0d7c03dd1eab05Daniel Veillard			Py_XDECREF(pyCtxt->warn);
3409259f0dfa8b4f29158954959b4d0d7c03dd1eab05Daniel Veillard			Py_XDECREF(pyCtxt->arg);
3410259f0dfa8b4f29158954959b4d0d7c03dd1eab05Daniel Veillard			xmlFree(pyCtxt);
3411259f0dfa8b4f29158954959b4d0d7c03dd1eab05Daniel Veillard		}
3412259f0dfa8b4f29158954959b4d0d7c03dd1eab05Daniel Veillard	}
3413259f0dfa8b4f29158954959b4d0d7c03dd1eab05Daniel Veillard
3414259f0dfa8b4f29158954959b4d0d7c03dd1eab05Daniel Veillard	xmlSchemaFreeValidCtxt(ctxt);
3415259f0dfa8b4f29158954959b4d0d7c03dd1eab05Daniel Veillard	Py_INCREF(Py_None);
3416259f0dfa8b4f29158954959b4d0d7c03dd1eab05Daniel Veillard	return(Py_None);
3417259f0dfa8b4f29158954959b4d0d7c03dd1eab05Daniel Veillard}
3418259f0dfa8b4f29158954959b4d0d7c03dd1eab05Daniel Veillard
3419c2664641740126714bb363bd6b5f65f724031c83Daniel Veillard#endif
3420c2664641740126714bb363bd6b5f65f724031c83Daniel Veillard
3421d5e198ad454803c60b898451ff432f2fcf0e95ceDaniel Veillard#ifdef LIBXML_C14N_ENABLED
3422d5e198ad454803c60b898451ff432f2fcf0e95ceDaniel Veillard#ifdef LIBXML_OUTPUT_ENABLED
3423d5e198ad454803c60b898451ff432f2fcf0e95ceDaniel Veillard
3424d5e198ad454803c60b898451ff432f2fcf0e95ceDaniel Veillard/************************************************************************
3425d5e198ad454803c60b898451ff432f2fcf0e95ceDaniel Veillard *                                                                      *
3426d5e198ad454803c60b898451ff432f2fcf0e95ceDaniel Veillard * XML Canonicalization c14n                                            *
3427d5e198ad454803c60b898451ff432f2fcf0e95ceDaniel Veillard *                                                                      *
3428d5e198ad454803c60b898451ff432f2fcf0e95ceDaniel Veillard ************************************************************************/
3429d5e198ad454803c60b898451ff432f2fcf0e95ceDaniel Veillard
3430d5e198ad454803c60b898451ff432f2fcf0e95ceDaniel Veillardstatic int
3431d5e198ad454803c60b898451ff432f2fcf0e95ceDaniel VeillardPyxmlNodeSet_Convert(PyObject *py_nodeset, xmlNodeSetPtr *result)
3432d5e198ad454803c60b898451ff432f2fcf0e95ceDaniel Veillard{
3433d5e198ad454803c60b898451ff432f2fcf0e95ceDaniel Veillard    xmlNodeSetPtr nodeSet;
3434d5e198ad454803c60b898451ff432f2fcf0e95ceDaniel Veillard    int is_tuple = 0;
3435d5e198ad454803c60b898451ff432f2fcf0e95ceDaniel Veillard
3436d5e198ad454803c60b898451ff432f2fcf0e95ceDaniel Veillard    if (PyTuple_Check(py_nodeset))
3437d5e198ad454803c60b898451ff432f2fcf0e95ceDaniel Veillard        is_tuple = 1;
3438d5e198ad454803c60b898451ff432f2fcf0e95ceDaniel Veillard    else if (PyList_Check(py_nodeset))
3439d5e198ad454803c60b898451ff432f2fcf0e95ceDaniel Veillard        is_tuple = 0;
3440d5e198ad454803c60b898451ff432f2fcf0e95ceDaniel Veillard    else if (py_nodeset == Py_None) {
3441d5e198ad454803c60b898451ff432f2fcf0e95ceDaniel Veillard        *result = NULL;
3442d5e198ad454803c60b898451ff432f2fcf0e95ceDaniel Veillard        return 0;
3443d5e198ad454803c60b898451ff432f2fcf0e95ceDaniel Veillard    }
3444d5e198ad454803c60b898451ff432f2fcf0e95ceDaniel Veillard    else {
3445d5e198ad454803c60b898451ff432f2fcf0e95ceDaniel Veillard        PyErr_SetString(PyExc_TypeError,
3446d5e198ad454803c60b898451ff432f2fcf0e95ceDaniel Veillard                        "must be a tuple or list of nodes.");
3447d5e198ad454803c60b898451ff432f2fcf0e95ceDaniel Veillard        return -1;
3448d5e198ad454803c60b898451ff432f2fcf0e95ceDaniel Veillard    }
3449d5e198ad454803c60b898451ff432f2fcf0e95ceDaniel Veillard
3450d5e198ad454803c60b898451ff432f2fcf0e95ceDaniel Veillard    nodeSet = (xmlNodeSetPtr) xmlMalloc(sizeof(xmlNodeSet));
3451d5e198ad454803c60b898451ff432f2fcf0e95ceDaniel Veillard    if (nodeSet == NULL) {
3452d5e198ad454803c60b898451ff432f2fcf0e95ceDaniel Veillard        PyErr_SetString(PyExc_MemoryError, "");
3453d5e198ad454803c60b898451ff432f2fcf0e95ceDaniel Veillard        return -1;
3454d5e198ad454803c60b898451ff432f2fcf0e95ceDaniel Veillard    }
3455d5e198ad454803c60b898451ff432f2fcf0e95ceDaniel Veillard
3456d5e198ad454803c60b898451ff432f2fcf0e95ceDaniel Veillard    nodeSet->nodeNr = 0;
3457d5e198ad454803c60b898451ff432f2fcf0e95ceDaniel Veillard    nodeSet->nodeMax = (is_tuple
3458d5e198ad454803c60b898451ff432f2fcf0e95ceDaniel Veillard                        ? PyTuple_GET_SIZE(py_nodeset)
3459d5e198ad454803c60b898451ff432f2fcf0e95ceDaniel Veillard                        : PyList_GET_SIZE(py_nodeset));
3460d5e198ad454803c60b898451ff432f2fcf0e95ceDaniel Veillard    nodeSet->nodeTab
3461d5e198ad454803c60b898451ff432f2fcf0e95ceDaniel Veillard        = (xmlNodePtr *) xmlMalloc (nodeSet->nodeMax
3462d5e198ad454803c60b898451ff432f2fcf0e95ceDaniel Veillard                                    * sizeof(xmlNodePtr));
3463d5e198ad454803c60b898451ff432f2fcf0e95ceDaniel Veillard    if (nodeSet->nodeTab == NULL) {
3464d5e198ad454803c60b898451ff432f2fcf0e95ceDaniel Veillard        xmlFree(nodeSet);
3465d5e198ad454803c60b898451ff432f2fcf0e95ceDaniel Veillard        PyErr_SetString(PyExc_MemoryError, "");
3466d5e198ad454803c60b898451ff432f2fcf0e95ceDaniel Veillard        return -1;
3467d5e198ad454803c60b898451ff432f2fcf0e95ceDaniel Veillard    }
3468d5e198ad454803c60b898451ff432f2fcf0e95ceDaniel Veillard    memset(nodeSet->nodeTab, 0 ,
3469d5e198ad454803c60b898451ff432f2fcf0e95ceDaniel Veillard           nodeSet->nodeMax * sizeof(xmlNodePtr));
3470d5e198ad454803c60b898451ff432f2fcf0e95ceDaniel Veillard
3471d5e198ad454803c60b898451ff432f2fcf0e95ceDaniel Veillard    {
3472d5e198ad454803c60b898451ff432f2fcf0e95ceDaniel Veillard        int idx;
3473d5e198ad454803c60b898451ff432f2fcf0e95ceDaniel Veillard        for (idx=0; idx < nodeSet->nodeMax; ++idx) {
3474d5e198ad454803c60b898451ff432f2fcf0e95ceDaniel Veillard            xmlNodePtr pynode =
3475d5e198ad454803c60b898451ff432f2fcf0e95ceDaniel Veillard                PyxmlNode_Get (is_tuple
3476d5e198ad454803c60b898451ff432f2fcf0e95ceDaniel Veillard                               ? PyTuple_GET_ITEM(py_nodeset, idx)
3477d5e198ad454803c60b898451ff432f2fcf0e95ceDaniel Veillard                               : PyList_GET_ITEM(py_nodeset, idx));
3478d5e198ad454803c60b898451ff432f2fcf0e95ceDaniel Veillard            if (pynode)
3479d5e198ad454803c60b898451ff432f2fcf0e95ceDaniel Veillard                nodeSet->nodeTab[nodeSet->nodeNr++] = pynode;
3480d5e198ad454803c60b898451ff432f2fcf0e95ceDaniel Veillard        }
3481d5e198ad454803c60b898451ff432f2fcf0e95ceDaniel Veillard    }
3482d5e198ad454803c60b898451ff432f2fcf0e95ceDaniel Veillard    *result = nodeSet;
3483d5e198ad454803c60b898451ff432f2fcf0e95ceDaniel Veillard    return 0;
3484d5e198ad454803c60b898451ff432f2fcf0e95ceDaniel Veillard}
3485d5e198ad454803c60b898451ff432f2fcf0e95ceDaniel Veillard
3486d5e198ad454803c60b898451ff432f2fcf0e95ceDaniel Veillardstatic int
3487d5e198ad454803c60b898451ff432f2fcf0e95ceDaniel VeillardPystringSet_Convert(PyObject *py_strings, xmlChar *** result)
3488d5e198ad454803c60b898451ff432f2fcf0e95ceDaniel Veillard{
3489d5e198ad454803c60b898451ff432f2fcf0e95ceDaniel Veillard    /* NOTE: the array should be freed, but the strings are shared
3490d5e198ad454803c60b898451ff432f2fcf0e95ceDaniel Veillard       with the python strings and so must not be freed. */
3491d5e198ad454803c60b898451ff432f2fcf0e95ceDaniel Veillard
3492d5e198ad454803c60b898451ff432f2fcf0e95ceDaniel Veillard    xmlChar ** strings;
3493d5e198ad454803c60b898451ff432f2fcf0e95ceDaniel Veillard    int is_tuple = 0;
3494d5e198ad454803c60b898451ff432f2fcf0e95ceDaniel Veillard    int count;
3495d5e198ad454803c60b898451ff432f2fcf0e95ceDaniel Veillard    int init_index = 0;
3496d5e198ad454803c60b898451ff432f2fcf0e95ceDaniel Veillard
3497d5e198ad454803c60b898451ff432f2fcf0e95ceDaniel Veillard    if (PyTuple_Check(py_strings))
3498d5e198ad454803c60b898451ff432f2fcf0e95ceDaniel Veillard        is_tuple = 1;
3499d5e198ad454803c60b898451ff432f2fcf0e95ceDaniel Veillard    else if (PyList_Check(py_strings))
3500d5e198ad454803c60b898451ff432f2fcf0e95ceDaniel Veillard        is_tuple = 0;
3501d5e198ad454803c60b898451ff432f2fcf0e95ceDaniel Veillard    else if (py_strings == Py_None) {
3502d5e198ad454803c60b898451ff432f2fcf0e95ceDaniel Veillard        *result = NULL;
3503d5e198ad454803c60b898451ff432f2fcf0e95ceDaniel Veillard        return 0;
3504d5e198ad454803c60b898451ff432f2fcf0e95ceDaniel Veillard    }
3505d5e198ad454803c60b898451ff432f2fcf0e95ceDaniel Veillard    else {
3506d5e198ad454803c60b898451ff432f2fcf0e95ceDaniel Veillard        PyErr_SetString(PyExc_TypeError,
3507d5e198ad454803c60b898451ff432f2fcf0e95ceDaniel Veillard                        "must be a tuple or list of strings.");
3508d5e198ad454803c60b898451ff432f2fcf0e95ceDaniel Veillard        return -1;
3509d5e198ad454803c60b898451ff432f2fcf0e95ceDaniel Veillard    }
3510d5e198ad454803c60b898451ff432f2fcf0e95ceDaniel Veillard
3511d5e198ad454803c60b898451ff432f2fcf0e95ceDaniel Veillard    count = (is_tuple
3512d5e198ad454803c60b898451ff432f2fcf0e95ceDaniel Veillard             ? PyTuple_GET_SIZE(py_strings)
3513d5e198ad454803c60b898451ff432f2fcf0e95ceDaniel Veillard             : PyList_GET_SIZE(py_strings));
3514d5e198ad454803c60b898451ff432f2fcf0e95ceDaniel Veillard
3515d5e198ad454803c60b898451ff432f2fcf0e95ceDaniel Veillard    strings = (xmlChar **) xmlMalloc(sizeof(xmlChar *) * count);
3516d5e198ad454803c60b898451ff432f2fcf0e95ceDaniel Veillard
3517d5e198ad454803c60b898451ff432f2fcf0e95ceDaniel Veillard    if (strings == NULL) {
3518d5e198ad454803c60b898451ff432f2fcf0e95ceDaniel Veillard        PyErr_SetString(PyExc_MemoryError, "");
3519d5e198ad454803c60b898451ff432f2fcf0e95ceDaniel Veillard        return -1;
3520d5e198ad454803c60b898451ff432f2fcf0e95ceDaniel Veillard    }
3521d5e198ad454803c60b898451ff432f2fcf0e95ceDaniel Veillard
3522d5e198ad454803c60b898451ff432f2fcf0e95ceDaniel Veillard    memset(strings, 0 , sizeof(xmlChar *) * count);
3523d5e198ad454803c60b898451ff432f2fcf0e95ceDaniel Veillard
3524d5e198ad454803c60b898451ff432f2fcf0e95ceDaniel Veillard    {
3525d5e198ad454803c60b898451ff432f2fcf0e95ceDaniel Veillard        int idx;
3526d5e198ad454803c60b898451ff432f2fcf0e95ceDaniel Veillard        for (idx=0; idx < count; ++idx) {
3527d5e198ad454803c60b898451ff432f2fcf0e95ceDaniel Veillard            char* s = PyString_AsString
3528d5e198ad454803c60b898451ff432f2fcf0e95ceDaniel Veillard                (is_tuple
3529d5e198ad454803c60b898451ff432f2fcf0e95ceDaniel Veillard                 ? PyTuple_GET_ITEM(py_strings, idx)
3530d5e198ad454803c60b898451ff432f2fcf0e95ceDaniel Veillard                 : PyList_GET_ITEM(py_strings, idx));
3531d5e198ad454803c60b898451ff432f2fcf0e95ceDaniel Veillard            if (s)
3532d5e198ad454803c60b898451ff432f2fcf0e95ceDaniel Veillard                strings[init_index++] = (xmlChar *)s;
3533d5e198ad454803c60b898451ff432f2fcf0e95ceDaniel Veillard            else {
3534d5e198ad454803c60b898451ff432f2fcf0e95ceDaniel Veillard                xmlFree(strings);
3535d5e198ad454803c60b898451ff432f2fcf0e95ceDaniel Veillard                PyErr_SetString(PyExc_TypeError,
3536d5e198ad454803c60b898451ff432f2fcf0e95ceDaniel Veillard                                "must be a tuple or list of strings.");
3537d5e198ad454803c60b898451ff432f2fcf0e95ceDaniel Veillard                return -1;
3538d5e198ad454803c60b898451ff432f2fcf0e95ceDaniel Veillard            }
3539d5e198ad454803c60b898451ff432f2fcf0e95ceDaniel Veillard        }
3540d5e198ad454803c60b898451ff432f2fcf0e95ceDaniel Veillard    }
3541d5e198ad454803c60b898451ff432f2fcf0e95ceDaniel Veillard
3542d5e198ad454803c60b898451ff432f2fcf0e95ceDaniel Veillard    *result = strings;
3543d5e198ad454803c60b898451ff432f2fcf0e95ceDaniel Veillard    return 0;
3544d5e198ad454803c60b898451ff432f2fcf0e95ceDaniel Veillard}
3545d5e198ad454803c60b898451ff432f2fcf0e95ceDaniel Veillard
3546d5e198ad454803c60b898451ff432f2fcf0e95ceDaniel Veillardstatic PyObject *
3547d5e198ad454803c60b898451ff432f2fcf0e95ceDaniel Veillardlibxml_C14NDocDumpMemory(ATTRIBUTE_UNUSED PyObject * self,
3548d5e198ad454803c60b898451ff432f2fcf0e95ceDaniel Veillard                         PyObject * args)
3549d5e198ad454803c60b898451ff432f2fcf0e95ceDaniel Veillard{
3550d5e198ad454803c60b898451ff432f2fcf0e95ceDaniel Veillard    PyObject *py_retval = NULL;
3551d5e198ad454803c60b898451ff432f2fcf0e95ceDaniel Veillard
3552d5e198ad454803c60b898451ff432f2fcf0e95ceDaniel Veillard    PyObject *pyobj_doc;
3553d5e198ad454803c60b898451ff432f2fcf0e95ceDaniel Veillard    PyObject *pyobj_nodes;
3554d5e198ad454803c60b898451ff432f2fcf0e95ceDaniel Veillard    int exclusive;
3555d5e198ad454803c60b898451ff432f2fcf0e95ceDaniel Veillard    PyObject *pyobj_prefixes;
3556d5e198ad454803c60b898451ff432f2fcf0e95ceDaniel Veillard    int with_comments;
3557d5e198ad454803c60b898451ff432f2fcf0e95ceDaniel Veillard
3558d5e198ad454803c60b898451ff432f2fcf0e95ceDaniel Veillard    xmlDocPtr doc;
3559d5e198ad454803c60b898451ff432f2fcf0e95ceDaniel Veillard    xmlNodeSetPtr nodes;
3560d5e198ad454803c60b898451ff432f2fcf0e95ceDaniel Veillard    xmlChar **prefixes = NULL;
3561d5e198ad454803c60b898451ff432f2fcf0e95ceDaniel Veillard    xmlChar *doc_txt;
3562d5e198ad454803c60b898451ff432f2fcf0e95ceDaniel Veillard
3563d5e198ad454803c60b898451ff432f2fcf0e95ceDaniel Veillard    int result;
3564d5e198ad454803c60b898451ff432f2fcf0e95ceDaniel Veillard
3565d5e198ad454803c60b898451ff432f2fcf0e95ceDaniel Veillard    if (!PyArg_ParseTuple(args, (char *) "OOiOi:C14NDocDumpMemory",
3566d5e198ad454803c60b898451ff432f2fcf0e95ceDaniel Veillard                          &pyobj_doc,
3567d5e198ad454803c60b898451ff432f2fcf0e95ceDaniel Veillard                          &pyobj_nodes,
3568d5e198ad454803c60b898451ff432f2fcf0e95ceDaniel Veillard                          &exclusive,
3569d5e198ad454803c60b898451ff432f2fcf0e95ceDaniel Veillard                          &pyobj_prefixes,
3570d5e198ad454803c60b898451ff432f2fcf0e95ceDaniel Veillard                          &with_comments))
3571d5e198ad454803c60b898451ff432f2fcf0e95ceDaniel Veillard        return (NULL);
3572d5e198ad454803c60b898451ff432f2fcf0e95ceDaniel Veillard
3573d5e198ad454803c60b898451ff432f2fcf0e95ceDaniel Veillard    doc = (xmlDocPtr) PyxmlNode_Get(pyobj_doc);
3574d5e198ad454803c60b898451ff432f2fcf0e95ceDaniel Veillard    if (!doc) {
3575d5e198ad454803c60b898451ff432f2fcf0e95ceDaniel Veillard        PyErr_SetString(PyExc_TypeError, "bad document.");
3576d5e198ad454803c60b898451ff432f2fcf0e95ceDaniel Veillard        return NULL;
3577d5e198ad454803c60b898451ff432f2fcf0e95ceDaniel Veillard    }
3578d5e198ad454803c60b898451ff432f2fcf0e95ceDaniel Veillard
3579d5e198ad454803c60b898451ff432f2fcf0e95ceDaniel Veillard    result = PyxmlNodeSet_Convert(pyobj_nodes, &nodes);
3580d5e198ad454803c60b898451ff432f2fcf0e95ceDaniel Veillard    if (result < 0) return NULL;
3581d5e198ad454803c60b898451ff432f2fcf0e95ceDaniel Veillard
3582d5e198ad454803c60b898451ff432f2fcf0e95ceDaniel Veillard    if (exclusive) {
3583d5e198ad454803c60b898451ff432f2fcf0e95ceDaniel Veillard        result = PystringSet_Convert(pyobj_prefixes, &prefixes);
3584d5e198ad454803c60b898451ff432f2fcf0e95ceDaniel Veillard        if (result < 0) {
3585d5e198ad454803c60b898451ff432f2fcf0e95ceDaniel Veillard            if (nodes) {
3586d5e198ad454803c60b898451ff432f2fcf0e95ceDaniel Veillard                xmlFree(nodes->nodeTab);
3587d5e198ad454803c60b898451ff432f2fcf0e95ceDaniel Veillard                xmlFree(nodes);
3588d5e198ad454803c60b898451ff432f2fcf0e95ceDaniel Veillard            }
3589d5e198ad454803c60b898451ff432f2fcf0e95ceDaniel Veillard            return NULL;
3590d5e198ad454803c60b898451ff432f2fcf0e95ceDaniel Veillard        }
3591d5e198ad454803c60b898451ff432f2fcf0e95ceDaniel Veillard    }
3592d5e198ad454803c60b898451ff432f2fcf0e95ceDaniel Veillard
3593d5e198ad454803c60b898451ff432f2fcf0e95ceDaniel Veillard    result = xmlC14NDocDumpMemory(doc,
3594d5e198ad454803c60b898451ff432f2fcf0e95ceDaniel Veillard                                  nodes,
3595d5e198ad454803c60b898451ff432f2fcf0e95ceDaniel Veillard                                  exclusive,
3596d5e198ad454803c60b898451ff432f2fcf0e95ceDaniel Veillard                                  prefixes,
3597d5e198ad454803c60b898451ff432f2fcf0e95ceDaniel Veillard                                  with_comments,
3598d5e198ad454803c60b898451ff432f2fcf0e95ceDaniel Veillard                                  &doc_txt);
3599d5e198ad454803c60b898451ff432f2fcf0e95ceDaniel Veillard
3600d5e198ad454803c60b898451ff432f2fcf0e95ceDaniel Veillard    if (nodes) {
3601d5e198ad454803c60b898451ff432f2fcf0e95ceDaniel Veillard        xmlFree(nodes->nodeTab);
3602d5e198ad454803c60b898451ff432f2fcf0e95ceDaniel Veillard        xmlFree(nodes);
3603d5e198ad454803c60b898451ff432f2fcf0e95ceDaniel Veillard    }
3604d5e198ad454803c60b898451ff432f2fcf0e95ceDaniel Veillard    if (prefixes) {
3605d5e198ad454803c60b898451ff432f2fcf0e95ceDaniel Veillard        xmlChar ** idx = prefixes;
3606d5e198ad454803c60b898451ff432f2fcf0e95ceDaniel Veillard        while (*idx) xmlFree(*(idx++));
3607d5e198ad454803c60b898451ff432f2fcf0e95ceDaniel Veillard        xmlFree(prefixes);
3608d5e198ad454803c60b898451ff432f2fcf0e95ceDaniel Veillard    }
3609d5e198ad454803c60b898451ff432f2fcf0e95ceDaniel Veillard
3610d5e198ad454803c60b898451ff432f2fcf0e95ceDaniel Veillard    if (result < 0) {
3611d5e198ad454803c60b898451ff432f2fcf0e95ceDaniel Veillard        PyErr_SetString(PyExc_Exception,
3612d5e198ad454803c60b898451ff432f2fcf0e95ceDaniel Veillard                        "libxml2 xmlC14NDocDumpMemory failure.");
3613d5e198ad454803c60b898451ff432f2fcf0e95ceDaniel Veillard        return NULL;
3614d5e198ad454803c60b898451ff432f2fcf0e95ceDaniel Veillard    }
3615d5e198ad454803c60b898451ff432f2fcf0e95ceDaniel Veillard    else {
3616d5e198ad454803c60b898451ff432f2fcf0e95ceDaniel Veillard        py_retval = PyString_FromStringAndSize((const char *) doc_txt,
3617d5e198ad454803c60b898451ff432f2fcf0e95ceDaniel Veillard                                               result);
3618d5e198ad454803c60b898451ff432f2fcf0e95ceDaniel Veillard        xmlFree(doc_txt);
3619d5e198ad454803c60b898451ff432f2fcf0e95ceDaniel Veillard        return py_retval;
3620d5e198ad454803c60b898451ff432f2fcf0e95ceDaniel Veillard    }
3621d5e198ad454803c60b898451ff432f2fcf0e95ceDaniel Veillard}
3622d5e198ad454803c60b898451ff432f2fcf0e95ceDaniel Veillard
3623d5e198ad454803c60b898451ff432f2fcf0e95ceDaniel Veillardstatic PyObject *
3624d5e198ad454803c60b898451ff432f2fcf0e95ceDaniel Veillardlibxml_C14NDocSaveTo(ATTRIBUTE_UNUSED PyObject * self,
3625d5e198ad454803c60b898451ff432f2fcf0e95ceDaniel Veillard                     PyObject * args)
3626d5e198ad454803c60b898451ff432f2fcf0e95ceDaniel Veillard{
3627d5e198ad454803c60b898451ff432f2fcf0e95ceDaniel Veillard    PyObject *pyobj_doc;
3628d5e198ad454803c60b898451ff432f2fcf0e95ceDaniel Veillard    PyObject *py_file;
3629d5e198ad454803c60b898451ff432f2fcf0e95ceDaniel Veillard    PyObject *pyobj_nodes;
3630d5e198ad454803c60b898451ff432f2fcf0e95ceDaniel Veillard    int exclusive;
3631d5e198ad454803c60b898451ff432f2fcf0e95ceDaniel Veillard    PyObject *pyobj_prefixes;
3632d5e198ad454803c60b898451ff432f2fcf0e95ceDaniel Veillard    int with_comments;
3633d5e198ad454803c60b898451ff432f2fcf0e95ceDaniel Veillard
3634d5e198ad454803c60b898451ff432f2fcf0e95ceDaniel Veillard    xmlDocPtr doc;
3635d5e198ad454803c60b898451ff432f2fcf0e95ceDaniel Veillard    xmlNodeSetPtr nodes;
3636d5e198ad454803c60b898451ff432f2fcf0e95ceDaniel Veillard    xmlChar **prefixes = NULL;
3637d5e198ad454803c60b898451ff432f2fcf0e95ceDaniel Veillard    FILE * output;
3638d5e198ad454803c60b898451ff432f2fcf0e95ceDaniel Veillard    xmlOutputBufferPtr buf;
3639d5e198ad454803c60b898451ff432f2fcf0e95ceDaniel Veillard
3640d5e198ad454803c60b898451ff432f2fcf0e95ceDaniel Veillard    int result;
3641d5e198ad454803c60b898451ff432f2fcf0e95ceDaniel Veillard    int len;
3642d5e198ad454803c60b898451ff432f2fcf0e95ceDaniel Veillard
3643d5e198ad454803c60b898451ff432f2fcf0e95ceDaniel Veillard    if (!PyArg_ParseTuple(args, (char *) "OOiOiO:C14NDocSaveTo",
3644d5e198ad454803c60b898451ff432f2fcf0e95ceDaniel Veillard                          &pyobj_doc,
3645d5e198ad454803c60b898451ff432f2fcf0e95ceDaniel Veillard                          &pyobj_nodes,
3646d5e198ad454803c60b898451ff432f2fcf0e95ceDaniel Veillard                          &exclusive,
3647d5e198ad454803c60b898451ff432f2fcf0e95ceDaniel Veillard                          &pyobj_prefixes,
3648d5e198ad454803c60b898451ff432f2fcf0e95ceDaniel Veillard                          &with_comments,
3649d5e198ad454803c60b898451ff432f2fcf0e95ceDaniel Veillard                          &py_file))
3650d5e198ad454803c60b898451ff432f2fcf0e95ceDaniel Veillard        return (NULL);
3651d5e198ad454803c60b898451ff432f2fcf0e95ceDaniel Veillard
3652d5e198ad454803c60b898451ff432f2fcf0e95ceDaniel Veillard    doc = (xmlDocPtr) PyxmlNode_Get(pyobj_doc);
3653d5e198ad454803c60b898451ff432f2fcf0e95ceDaniel Veillard    if (!doc) {
3654d5e198ad454803c60b898451ff432f2fcf0e95ceDaniel Veillard        PyErr_SetString(PyExc_TypeError, "bad document.");
3655d5e198ad454803c60b898451ff432f2fcf0e95ceDaniel Veillard        return NULL;
3656d5e198ad454803c60b898451ff432f2fcf0e95ceDaniel Veillard    }
3657d5e198ad454803c60b898451ff432f2fcf0e95ceDaniel Veillard
3658d5e198ad454803c60b898451ff432f2fcf0e95ceDaniel Veillard    if ((py_file == NULL) || (!(PyFile_Check(py_file)))) {
3659d5e198ad454803c60b898451ff432f2fcf0e95ceDaniel Veillard        PyErr_SetString(PyExc_TypeError, "bad file.");
3660d5e198ad454803c60b898451ff432f2fcf0e95ceDaniel Veillard        return NULL;
3661d5e198ad454803c60b898451ff432f2fcf0e95ceDaniel Veillard    }
3662d5e198ad454803c60b898451ff432f2fcf0e95ceDaniel Veillard    output = PyFile_AsFile(py_file);
3663d5e198ad454803c60b898451ff432f2fcf0e95ceDaniel Veillard    if (output == NULL) {
3664d5e198ad454803c60b898451ff432f2fcf0e95ceDaniel Veillard        PyErr_SetString(PyExc_TypeError, "bad file.");
3665d5e198ad454803c60b898451ff432f2fcf0e95ceDaniel Veillard        return NULL;
3666d5e198ad454803c60b898451ff432f2fcf0e95ceDaniel Veillard    }
3667d5e198ad454803c60b898451ff432f2fcf0e95ceDaniel Veillard    buf = xmlOutputBufferCreateFile(output, NULL);
3668d5e198ad454803c60b898451ff432f2fcf0e95ceDaniel Veillard
3669d5e198ad454803c60b898451ff432f2fcf0e95ceDaniel Veillard    result = PyxmlNodeSet_Convert(pyobj_nodes, &nodes);
3670d5e198ad454803c60b898451ff432f2fcf0e95ceDaniel Veillard    if (result < 0) return NULL;
3671d5e198ad454803c60b898451ff432f2fcf0e95ceDaniel Veillard
3672d5e198ad454803c60b898451ff432f2fcf0e95ceDaniel Veillard    if (exclusive) {
3673d5e198ad454803c60b898451ff432f2fcf0e95ceDaniel Veillard        result = PystringSet_Convert(pyobj_prefixes, &prefixes);
3674d5e198ad454803c60b898451ff432f2fcf0e95ceDaniel Veillard        if (result < 0) {
3675d5e198ad454803c60b898451ff432f2fcf0e95ceDaniel Veillard            if (nodes) {
3676d5e198ad454803c60b898451ff432f2fcf0e95ceDaniel Veillard                xmlFree(nodes->nodeTab);
3677d5e198ad454803c60b898451ff432f2fcf0e95ceDaniel Veillard                xmlFree(nodes);
3678d5e198ad454803c60b898451ff432f2fcf0e95ceDaniel Veillard            }
3679d5e198ad454803c60b898451ff432f2fcf0e95ceDaniel Veillard            return NULL;
3680d5e198ad454803c60b898451ff432f2fcf0e95ceDaniel Veillard        }
3681d5e198ad454803c60b898451ff432f2fcf0e95ceDaniel Veillard    }
3682d5e198ad454803c60b898451ff432f2fcf0e95ceDaniel Veillard
3683d5e198ad454803c60b898451ff432f2fcf0e95ceDaniel Veillard    result = xmlC14NDocSaveTo(doc,
3684d5e198ad454803c60b898451ff432f2fcf0e95ceDaniel Veillard                              nodes,
3685d5e198ad454803c60b898451ff432f2fcf0e95ceDaniel Veillard                              exclusive,
3686d5e198ad454803c60b898451ff432f2fcf0e95ceDaniel Veillard                              prefixes,
3687d5e198ad454803c60b898451ff432f2fcf0e95ceDaniel Veillard                              with_comments,
3688d5e198ad454803c60b898451ff432f2fcf0e95ceDaniel Veillard                              buf);
3689d5e198ad454803c60b898451ff432f2fcf0e95ceDaniel Veillard
3690d5e198ad454803c60b898451ff432f2fcf0e95ceDaniel Veillard    if (nodes) {
3691d5e198ad454803c60b898451ff432f2fcf0e95ceDaniel Veillard        xmlFree(nodes->nodeTab);
3692d5e198ad454803c60b898451ff432f2fcf0e95ceDaniel Veillard        xmlFree(nodes);
3693d5e198ad454803c60b898451ff432f2fcf0e95ceDaniel Veillard    }
3694d5e198ad454803c60b898451ff432f2fcf0e95ceDaniel Veillard    if (prefixes) {
3695d5e198ad454803c60b898451ff432f2fcf0e95ceDaniel Veillard        xmlChar ** idx = prefixes;
3696d5e198ad454803c60b898451ff432f2fcf0e95ceDaniel Veillard        while (*idx) xmlFree(*(idx++));
3697d5e198ad454803c60b898451ff432f2fcf0e95ceDaniel Veillard        xmlFree(prefixes);
3698d5e198ad454803c60b898451ff432f2fcf0e95ceDaniel Veillard    }
3699d5e198ad454803c60b898451ff432f2fcf0e95ceDaniel Veillard
3700d5e198ad454803c60b898451ff432f2fcf0e95ceDaniel Veillard    len = xmlOutputBufferClose(buf);
3701d5e198ad454803c60b898451ff432f2fcf0e95ceDaniel Veillard
3702d5e198ad454803c60b898451ff432f2fcf0e95ceDaniel Veillard    if (result < 0) {
3703d5e198ad454803c60b898451ff432f2fcf0e95ceDaniel Veillard        PyErr_SetString(PyExc_Exception,
3704d5e198ad454803c60b898451ff432f2fcf0e95ceDaniel Veillard                        "libxml2 xmlC14NDocSaveTo failure.");
3705d5e198ad454803c60b898451ff432f2fcf0e95ceDaniel Veillard        return NULL;
3706d5e198ad454803c60b898451ff432f2fcf0e95ceDaniel Veillard    }
3707d5e198ad454803c60b898451ff432f2fcf0e95ceDaniel Veillard    else
3708d5e198ad454803c60b898451ff432f2fcf0e95ceDaniel Veillard        return PyInt_FromLong((long) len);
3709d5e198ad454803c60b898451ff432f2fcf0e95ceDaniel Veillard}
3710d5e198ad454803c60b898451ff432f2fcf0e95ceDaniel Veillard
3711d5e198ad454803c60b898451ff432f2fcf0e95ceDaniel Veillard#endif
3712d5e198ad454803c60b898451ff432f2fcf0e95ceDaniel Veillard#endif
3713d5e198ad454803c60b898451ff432f2fcf0e95ceDaniel Veillard
3714c68d78d25a17e65d172ccc1ac24d609c7c1d5cdeWilliam M. Brackstatic PyObject *
3715c68d78d25a17e65d172ccc1ac24d609c7c1d5cdeWilliam M. Bracklibxml_getObjDesc(PyObject *self ATTRIBUTE_UNUSED, PyObject *args) {
3716c68d78d25a17e65d172ccc1ac24d609c7c1d5cdeWilliam M. Brack
3717c68d78d25a17e65d172ccc1ac24d609c7c1d5cdeWilliam M. Brack    PyObject *obj;
3718c68d78d25a17e65d172ccc1ac24d609c7c1d5cdeWilliam M. Brack    char *str;
3719d5e198ad454803c60b898451ff432f2fcf0e95ceDaniel Veillard
3720c68d78d25a17e65d172ccc1ac24d609c7c1d5cdeWilliam M. Brack    if (!PyArg_ParseTuple(args, (char *)"O:getObjDesc", &obj))
3721c68d78d25a17e65d172ccc1ac24d609c7c1d5cdeWilliam M. Brack        return NULL;
3722c68d78d25a17e65d172ccc1ac24d609c7c1d5cdeWilliam M. Brack    str = PyCObject_GetDesc(obj);
3723c68d78d25a17e65d172ccc1ac24d609c7c1d5cdeWilliam M. Brack    return Py_BuildValue((char *)"s", str);
3724c68d78d25a17e65d172ccc1ac24d609c7c1d5cdeWilliam M. Brack}
3725d5e198ad454803c60b898451ff432f2fcf0e95ceDaniel Veillard
372640cca61fc130f0f865f51b2fb2ba15e478e102abWilliam M. Brackstatic PyObject *
372740cca61fc130f0f865f51b2fb2ba15e478e102abWilliam M. Bracklibxml_compareNodesEqual(PyObject *self ATTRIBUTE_UNUSED, PyObject *args) {
372840cca61fc130f0f865f51b2fb2ba15e478e102abWilliam M. Brack
372940cca61fc130f0f865f51b2fb2ba15e478e102abWilliam M. Brack    PyObject *py_node1, *py_node2;
373040cca61fc130f0f865f51b2fb2ba15e478e102abWilliam M. Brack    xmlNodePtr node1, node2;
373140cca61fc130f0f865f51b2fb2ba15e478e102abWilliam M. Brack
373240cca61fc130f0f865f51b2fb2ba15e478e102abWilliam M. Brack    if (!PyArg_ParseTuple(args, (char *)"OO:compareNodesEqual",
373340cca61fc130f0f865f51b2fb2ba15e478e102abWilliam M. Brack		&py_node1, &py_node2))
373440cca61fc130f0f865f51b2fb2ba15e478e102abWilliam M. Brack        return NULL;
373540cca61fc130f0f865f51b2fb2ba15e478e102abWilliam M. Brack    /* To compare two node objects, we compare their pointer addresses */
373640cca61fc130f0f865f51b2fb2ba15e478e102abWilliam M. Brack    node1 = PyxmlNode_Get(py_node1);
373740cca61fc130f0f865f51b2fb2ba15e478e102abWilliam M. Brack    node2 = PyxmlNode_Get(py_node2);
373840cca61fc130f0f865f51b2fb2ba15e478e102abWilliam M. Brack    if ( node1 == node2 )
373940cca61fc130f0f865f51b2fb2ba15e478e102abWilliam M. Brack        return Py_BuildValue((char *)"i", 1);
374040cca61fc130f0f865f51b2fb2ba15e478e102abWilliam M. Brack    else
374140cca61fc130f0f865f51b2fb2ba15e478e102abWilliam M. Brack        return Py_BuildValue((char *)"i", 0);
374240cca61fc130f0f865f51b2fb2ba15e478e102abWilliam M. Brack
374340cca61fc130f0f865f51b2fb2ba15e478e102abWilliam M. Brack}
374440cca61fc130f0f865f51b2fb2ba15e478e102abWilliam M. Brack
374540cca61fc130f0f865f51b2fb2ba15e478e102abWilliam M. Brackstatic PyObject *
374640cca61fc130f0f865f51b2fb2ba15e478e102abWilliam M. Bracklibxml_nodeHash(PyObject *self ATTRIBUTE_UNUSED, PyObject *args) {
374740cca61fc130f0f865f51b2fb2ba15e478e102abWilliam M. Brack
374840cca61fc130f0f865f51b2fb2ba15e478e102abWilliam M. Brack    PyObject *py_node1;
374940cca61fc130f0f865f51b2fb2ba15e478e102abWilliam M. Brack    xmlNodePtr node1;
375040cca61fc130f0f865f51b2fb2ba15e478e102abWilliam M. Brack
375140cca61fc130f0f865f51b2fb2ba15e478e102abWilliam M. Brack    if (!PyArg_ParseTuple(args, (char *)"O:nodeHash", &py_node1))
375240cca61fc130f0f865f51b2fb2ba15e478e102abWilliam M. Brack	    return NULL;
375340cca61fc130f0f865f51b2fb2ba15e478e102abWilliam M. Brack    /* For simplicity, we use the node pointer address as a hash value */
375440cca61fc130f0f865f51b2fb2ba15e478e102abWilliam M. Brack    node1 = PyxmlNode_Get(py_node1);
375540cca61fc130f0f865f51b2fb2ba15e478e102abWilliam M. Brack
375640cca61fc130f0f865f51b2fb2ba15e478e102abWilliam M. Brack    return PyLong_FromVoidPtr(node1);
375740cca61fc130f0f865f51b2fb2ba15e478e102abWilliam M. Brack
375840cca61fc130f0f865f51b2fb2ba15e478e102abWilliam M. Brack}
375940cca61fc130f0f865f51b2fb2ba15e478e102abWilliam M. Brack
3760a94ec6ff13d9617ff22e790cef82208e7d1bd375Daniel Veillard/************************************************************************
3761a94ec6ff13d9617ff22e790cef82208e7d1bd375Daniel Veillard *									*
3762d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard *			The registration stuff				*
3763d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard *									*
3764d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard ************************************************************************/
3765d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillardstatic PyMethodDef libxmlMethods[] = {
376696fe095d4bf3c76301ed58ebe1ba10f8004f87efDaniel Veillard#include "libxml2-export.c"
3767d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard    {(char *) "name", libxml_name, METH_VARARGS, NULL},
3768d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard    {(char *) "children", libxml_children, METH_VARARGS, NULL},
3769d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard    {(char *) "properties", libxml_properties, METH_VARARGS, NULL},
3770d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard    {(char *) "last", libxml_last, METH_VARARGS, NULL},
3771d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard    {(char *) "prev", libxml_prev, METH_VARARGS, NULL},
3772d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard    {(char *) "next", libxml_next, METH_VARARGS, NULL},
3773d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard    {(char *) "parent", libxml_parent, METH_VARARGS, NULL},
3774d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard    {(char *) "type", libxml_type, METH_VARARGS, NULL},
3775d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard    {(char *) "doc", libxml_doc, METH_VARARGS, NULL},
3776d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard    {(char *) "xmlNewNode", libxml_xmlNewNode, METH_VARARGS, NULL},
3777f9cf6f5a01527406ed0bcbcf5a180d85b5e771deDaniel Veillard    {(char *) "xmlNodeRemoveNsDef", libxml_xmlNodeRemoveNsDef, METH_VARARGS, NULL},
3778850ce9b6584ecc2893632392f1d3ba46fefc13acDaniel Veillard    {(char *)"xmlSetValidErrors", libxml_xmlSetValidErrors, METH_VARARGS, NULL},
377925c90c589b256f0925f081198c1525134a491e31Daniel Veillard    {(char *)"xmlFreeValidCtxt", libxml_xmlFreeValidCtxt, METH_VARARGS, NULL},
3780a9cce9cd0d7aff3ec318b5d8d376da131b6aaad4Daniel Veillard#ifdef LIBXML_OUTPUT_ENABLED
3781d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard    {(char *) "serializeNode", libxml_serializeNode, METH_VARARGS, NULL},
3782d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard    {(char *) "saveNodeTo", libxml_saveNodeTo, METH_VARARGS, NULL},
3783c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard    {(char *) "outputBufferCreate", libxml_xmlCreateOutputBuffer, METH_VARARGS, NULL},
37846cbd6c0738efb6c55d08f39c0731d46d678858faDaniel Veillard    {(char *) "outputBufferGetPythonFile", libxml_outputBufferGetPythonFile, METH_VARARGS, NULL},
37856cbd6c0738efb6c55d08f39c0731d46d678858faDaniel Veillard    {(char *) "xmlOutputBufferClose", libxml_xmlOutputBufferClose, METH_VARARGS, NULL},
37866cbd6c0738efb6c55d08f39c0731d46d678858faDaniel Veillard    { (char *)"xmlOutputBufferFlush", libxml_xmlOutputBufferFlush, METH_VARARGS, NULL },
3787263ec86a75f7b5ec2d37dbb89356bf7fca11cff3Daniel Veillard    { (char *)"xmlSaveFileTo", libxml_xmlSaveFileTo, METH_VARARGS, NULL },
3788263ec86a75f7b5ec2d37dbb89356bf7fca11cff3Daniel Veillard    { (char *)"xmlSaveFormatFileTo", libxml_xmlSaveFormatFileTo, METH_VARARGS, NULL },
3789a9cce9cd0d7aff3ec318b5d8d376da131b6aaad4Daniel Veillard#endif /* LIBXML_OUTPUT_ENABLED */
3790c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard    {(char *) "inputBufferCreate", libxml_xmlCreateInputBuffer, METH_VARARGS, NULL},
3791c6d4a933f017b17cacdf2a6f6505faf8d945b0b3Daniel Veillard    {(char *) "setEntityLoader", libxml_xmlSetEntityLoader, METH_VARARGS, NULL},
37923e20a2921373677d1cf54fcf6081b3492e0c7558Daniel Veillard    {(char *)"xmlRegisterErrorHandler", libxml_xmlRegisterErrorHandler, METH_VARARGS, NULL },
3793417be3ae08346c6510c28d2042dd42a22a74b331Daniel Veillard    {(char *)"xmlParserCtxtSetErrorHandler", libxml_xmlParserCtxtSetErrorHandler, METH_VARARGS, NULL },
3794417be3ae08346c6510c28d2042dd42a22a74b331Daniel Veillard    {(char *)"xmlParserCtxtGetErrorHandler", libxml_xmlParserCtxtGetErrorHandler, METH_VARARGS, NULL },
3795e6227e0549490b5bf9271ecd2d874a97c3f4852bDaniel Veillard    {(char *)"xmlFreeParserCtxt", libxml_xmlFreeParserCtxt, METH_VARARGS, NULL },
3796438ebbd59af78c436397ae488e42aeca5cad7542Daniel Veillard#ifdef LIBXML_READER_ENABLED
379726f70269c80140a7fb8a7aae9ef09c95efa98e70Daniel Veillard    {(char *)"xmlTextReaderSetErrorHandler", libxml_xmlTextReaderSetErrorHandler, METH_VARARGS, NULL },
379826f70269c80140a7fb8a7aae9ef09c95efa98e70Daniel Veillard    {(char *)"xmlTextReaderGetErrorHandler", libxml_xmlTextReaderGetErrorHandler, METH_VARARGS, NULL },
379926f70269c80140a7fb8a7aae9ef09c95efa98e70Daniel Veillard    {(char *)"xmlFreeTextReader", libxml_xmlFreeTextReader, METH_VARARGS, NULL },
3800438ebbd59af78c436397ae488e42aeca5cad7542Daniel Veillard#endif
38015439624bd9167dbb880ea4a75d91677d20a6ebe3Daniel Veillard    {(char *)"addLocalCatalog", libxml_addLocalCatalog, METH_VARARGS, NULL },
3802c2664641740126714bb363bd6b5f65f724031c83Daniel Veillard#ifdef LIBXML_SCHEMAS_ENABLED
3803c2664641740126714bb363bd6b5f65f724031c83Daniel Veillard    {(char *)"xmlRelaxNGSetValidErrors", libxml_xmlRelaxNGSetValidErrors, METH_VARARGS, NULL},
3804c2664641740126714bb363bd6b5f65f724031c83Daniel Veillard    {(char *)"xmlRelaxNGFreeValidCtxt", libxml_xmlRelaxNGFreeValidCtxt, METH_VARARGS, NULL},
3805eff45a92da861195551a2050487fcca0492cac7cDaniel Veillard    {(char *)"xmlSchemaSetValidErrors", libxml_xmlSchemaSetValidErrors, METH_VARARGS, NULL},
3806bb8502c0ef2af706fbdff69119e994e40da64a88Daniel Veillard    {(char *)"xmlSchemaFreeValidCtxt", libxml_xmlSchemaFreeValidCtxt, METH_VARARGS, NULL},
3807c2664641740126714bb363bd6b5f65f724031c83Daniel Veillard#endif
3808d5e198ad454803c60b898451ff432f2fcf0e95ceDaniel Veillard#ifdef LIBXML_C14N_ENABLED
3809d5e198ad454803c60b898451ff432f2fcf0e95ceDaniel Veillard#ifdef LIBXML_OUTPUT_ENABLED
3810d5e198ad454803c60b898451ff432f2fcf0e95ceDaniel Veillard    {(char *)"xmlC14NDocDumpMemory", libxml_C14NDocDumpMemory, METH_VARARGS, NULL},
3811d5e198ad454803c60b898451ff432f2fcf0e95ceDaniel Veillard    {(char *)"xmlC14NDocSaveTo", libxml_C14NDocSaveTo, METH_VARARGS, NULL},
3812d5e198ad454803c60b898451ff432f2fcf0e95ceDaniel Veillard#endif
3813d5e198ad454803c60b898451ff432f2fcf0e95ceDaniel Veillard#endif
3814c68d78d25a17e65d172ccc1ac24d609c7c1d5cdeWilliam M. Brack    {(char *) "getObjDesc", libxml_getObjDesc, METH_VARARGS, NULL},
381540cca61fc130f0f865f51b2fb2ba15e478e102abWilliam M. Brack    {(char *) "compareNodesEqual", libxml_compareNodesEqual, METH_VARARGS, NULL},
381640cca61fc130f0f865f51b2fb2ba15e478e102abWilliam M. Brack    {(char *) "nodeHash", libxml_nodeHash, METH_VARARGS, NULL},
381748da90bc4a3809728d08ee9ee8da21d044fbca82Alexey Neyman    {(char *) "xmlRegisterInputCallback", libxml_xmlRegisterInputCallback, METH_VARARGS, NULL},
381848da90bc4a3809728d08ee9ee8da21d044fbca82Alexey Neyman    {(char *) "xmlUnregisterInputCallback", libxml_xmlUnregisterInputCallback, METH_VARARGS, NULL},
3819d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard    {NULL, NULL, 0, NULL}
3820d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard};
3821d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard
38220fea6f45cd6f158418318c0af922533e44f9c0e2Daniel Veillard#ifdef MERGED_MODULES
38236361da0c25e355affdeed84cfccb187ccaadfccbDaniel Veillardextern void initlibxsltmod(void);
38240fea6f45cd6f158418318c0af922533e44f9c0e2Daniel Veillard#endif
38250fea6f45cd6f158418318c0af922533e44f9c0e2Daniel Veillard
3826d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillardvoid
3827d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillardinitlibxml2mod(void)
3828d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard{
3829af43f63aaabf0dc4b4a070773875d0927da3d8a2Daniel Veillard    static int initialized = 0;
3830af43f63aaabf0dc4b4a070773875d0927da3d8a2Daniel Veillard
3831af43f63aaabf0dc4b4a070773875d0927da3d8a2Daniel Veillard    if (initialized != 0)
3832d2379010b1aa04ff87876d5b6dfd42ce2e12928fDaniel Veillard        return;
38338e2cc6f2b53f536692f3c8ad8112bb67e0a1a629William M. Brack
3834f93a866079364a006189683eaa07f94c867389d1Daniel Veillard    /* intialize the python extension module */
3835f93a866079364a006189683eaa07f94c867389d1Daniel Veillard    Py_InitModule((char *) "libxml2mod", libxmlMethods);
3836f93a866079364a006189683eaa07f94c867389d1Daniel Veillard
3837f93a866079364a006189683eaa07f94c867389d1Daniel Veillard    /* initialize libxml2 */
3838f93a866079364a006189683eaa07f94c867389d1Daniel Veillard    xmlInitParser();
38395d81903b06418c7d8cc72cf9add81c4026a2f3bcDaniel Veillard    libxml_xmlErrorInitialize();
38406361da0c25e355affdeed84cfccb187ccaadfccbDaniel Veillard
3841f93a866079364a006189683eaa07f94c867389d1Daniel Veillard    initialized = 1;
3842f93a866079364a006189683eaa07f94c867389d1Daniel Veillard
38430fea6f45cd6f158418318c0af922533e44f9c0e2Daniel Veillard#ifdef MERGED_MODULES
38440fea6f45cd6f158418318c0af922533e44f9c0e2Daniel Veillard    initlibxsltmod();
38450fea6f45cd6f158418318c0af922533e44f9c0e2Daniel Veillard#endif
3846d2897fde0089a9f349f7a589c1e58a8e130a3d61Daniel Veillard}
3847