xref: /aosp_15_r20/external/libxml2/python/libxml.c (revision 7c5688314b92172186c154356a6374bf7684c3ca)
1*7c568831SAndroid Build Coastguard Worker /*
2*7c568831SAndroid Build Coastguard Worker  * libxml.c: this modules implements the main part of the glue of the
3*7c568831SAndroid Build Coastguard Worker  *           libxml2 library and the Python interpreter. It provides the
4*7c568831SAndroid Build Coastguard Worker  *           entry points where an automatically generated stub is either
5*7c568831SAndroid Build Coastguard Worker  *           unpractical or would not match cleanly the Python model.
6*7c568831SAndroid Build Coastguard Worker  *
7*7c568831SAndroid Build Coastguard Worker  * If compiled with MERGED_MODULES, the entry point will be used to
8*7c568831SAndroid Build Coastguard Worker  * initialize both the libxml2 and the libxslt wrappers
9*7c568831SAndroid Build Coastguard Worker  *
10*7c568831SAndroid Build Coastguard Worker  * See Copyright for the status of this software.
11*7c568831SAndroid Build Coastguard Worker  *
12*7c568831SAndroid Build Coastguard Worker  * [email protected]
13*7c568831SAndroid Build Coastguard Worker  */
14*7c568831SAndroid Build Coastguard Worker #define PY_SSIZE_T_CLEAN
15*7c568831SAndroid Build Coastguard Worker #include <Python.h>
16*7c568831SAndroid Build Coastguard Worker #include <fileobject.h>
17*7c568831SAndroid Build Coastguard Worker /* #include "config.h" */
18*7c568831SAndroid Build Coastguard Worker #include <libxml/xmlmemory.h>
19*7c568831SAndroid Build Coastguard Worker #include <libxml/parser.h>
20*7c568831SAndroid Build Coastguard Worker #include <libxml/tree.h>
21*7c568831SAndroid Build Coastguard Worker #include <libxml/xpath.h>
22*7c568831SAndroid Build Coastguard Worker #include <libxml/xmlerror.h>
23*7c568831SAndroid Build Coastguard Worker #include <libxml/xpathInternals.h>
24*7c568831SAndroid Build Coastguard Worker #include <libxml/xmlmemory.h>
25*7c568831SAndroid Build Coastguard Worker #include <libxml/xmlIO.h>
26*7c568831SAndroid Build Coastguard Worker #include <libxml/c14n.h>
27*7c568831SAndroid Build Coastguard Worker #include <libxml/xmlreader.h>
28*7c568831SAndroid Build Coastguard Worker #include <libxml/xmlsave.h>
29*7c568831SAndroid Build Coastguard Worker #include "libxml_wrap.h"
30*7c568831SAndroid Build Coastguard Worker #include "libxml2-py.h"
31*7c568831SAndroid Build Coastguard Worker 
32*7c568831SAndroid Build Coastguard Worker #if PY_MAJOR_VERSION >= 3
33*7c568831SAndroid Build Coastguard Worker PyObject *PyInit_libxml2mod(void);
34*7c568831SAndroid Build Coastguard Worker 
35*7c568831SAndroid Build Coastguard Worker #define PY_IMPORT_STRING_SIZE PyUnicode_FromStringAndSize
36*7c568831SAndroid Build Coastguard Worker #define PY_IMPORT_STRING PyUnicode_FromString
37*7c568831SAndroid Build Coastguard Worker #else
38*7c568831SAndroid Build Coastguard Worker void initlibxml2mod(void);
39*7c568831SAndroid Build Coastguard Worker #define PY_IMPORT_STRING_SIZE PyString_FromStringAndSize
40*7c568831SAndroid Build Coastguard Worker #define PY_IMPORT_STRING PyString_FromString
41*7c568831SAndroid Build Coastguard Worker #endif
42*7c568831SAndroid Build Coastguard Worker 
43*7c568831SAndroid Build Coastguard Worker 
44*7c568831SAndroid Build Coastguard Worker /**
45*7c568831SAndroid Build Coastguard Worker  * TODO:
46*7c568831SAndroid Build Coastguard Worker  *
47*7c568831SAndroid Build Coastguard Worker  * macro to flag unimplemented blocks
48*7c568831SAndroid Build Coastguard Worker  */
49*7c568831SAndroid Build Coastguard Worker #define TODO 								\
50*7c568831SAndroid Build Coastguard Worker     xmlGenericError(xmlGenericErrorContext,				\
51*7c568831SAndroid Build Coastguard Worker 	    "Unimplemented block at %s:%d\n",				\
52*7c568831SAndroid Build Coastguard Worker             __FILE__, __LINE__);
53*7c568831SAndroid Build Coastguard Worker 
54*7c568831SAndroid Build Coastguard Worker #ifdef LIBXML_XPATH_ENABLED
55*7c568831SAndroid Build Coastguard Worker /*
56*7c568831SAndroid Build Coastguard Worker  * the following vars are used for XPath extensions, but
57*7c568831SAndroid Build Coastguard Worker  * are also referenced within the parser cleanup routine.
58*7c568831SAndroid Build Coastguard Worker  */
59*7c568831SAndroid Build Coastguard Worker static int libxml_xpathCallbacksInitialized = 0;
60*7c568831SAndroid Build Coastguard Worker 
61*7c568831SAndroid Build Coastguard Worker typedef struct libxml_xpathCallback {
62*7c568831SAndroid Build Coastguard Worker     xmlXPathContextPtr ctx;
63*7c568831SAndroid Build Coastguard Worker     xmlChar *name;
64*7c568831SAndroid Build Coastguard Worker     xmlChar *ns_uri;
65*7c568831SAndroid Build Coastguard Worker     PyObject *function;
66*7c568831SAndroid Build Coastguard Worker } libxml_xpathCallback, *libxml_xpathCallbackPtr;
67*7c568831SAndroid Build Coastguard Worker typedef libxml_xpathCallback libxml_xpathCallbackArray[];
68*7c568831SAndroid Build Coastguard Worker static int libxml_xpathCallbacksAllocd = 10;
69*7c568831SAndroid Build Coastguard Worker static libxml_xpathCallbackArray *libxml_xpathCallbacks = NULL;
70*7c568831SAndroid Build Coastguard Worker static int libxml_xpathCallbacksNb = 0;
71*7c568831SAndroid Build Coastguard Worker #endif /* LIBXML_XPATH_ENABLED */
72*7c568831SAndroid Build Coastguard Worker 
73*7c568831SAndroid Build Coastguard Worker /************************************************************************
74*7c568831SAndroid Build Coastguard Worker  *									*
75*7c568831SAndroid Build Coastguard Worker  *		Memory debug interface					*
76*7c568831SAndroid Build Coastguard Worker  *									*
77*7c568831SAndroid Build Coastguard Worker  ************************************************************************/
78*7c568831SAndroid Build Coastguard Worker 
79*7c568831SAndroid Build Coastguard Worker #if 0
80*7c568831SAndroid Build Coastguard Worker extern void xmlMemFree(void *ptr);
81*7c568831SAndroid Build Coastguard Worker extern void *xmlMemMalloc(size_t size);
82*7c568831SAndroid Build Coastguard Worker extern void *xmlMemRealloc(void *ptr, size_t size);
83*7c568831SAndroid Build Coastguard Worker extern char *xmlMemoryStrdup(const char *str);
84*7c568831SAndroid Build Coastguard Worker #endif
85*7c568831SAndroid Build Coastguard Worker 
86*7c568831SAndroid Build Coastguard Worker static int libxmlMemoryDebugActivated = 0;
87*7c568831SAndroid Build Coastguard Worker static long libxmlMemoryAllocatedBase = 0;
88*7c568831SAndroid Build Coastguard Worker 
89*7c568831SAndroid Build Coastguard Worker static int libxmlMemoryDebug = 0;
90*7c568831SAndroid Build Coastguard Worker static xmlFreeFunc freeFunc = NULL;
91*7c568831SAndroid Build Coastguard Worker static xmlMallocFunc mallocFunc = NULL;
92*7c568831SAndroid Build Coastguard Worker static xmlReallocFunc reallocFunc = NULL;
93*7c568831SAndroid Build Coastguard Worker static xmlStrdupFunc strdupFunc = NULL;
94*7c568831SAndroid Build Coastguard Worker 
95*7c568831SAndroid Build Coastguard Worker static void
96*7c568831SAndroid Build Coastguard Worker libxml_xmlErrorInitialize(void); /* forward declare */
97*7c568831SAndroid Build Coastguard Worker 
98*7c568831SAndroid Build Coastguard Worker PyObject *
libxml_xmlMemoryUsed(PyObject * self ATTRIBUTE_UNUSED,PyObject * args ATTRIBUTE_UNUSED)99*7c568831SAndroid Build Coastguard Worker libxml_xmlMemoryUsed(PyObject * self ATTRIBUTE_UNUSED,
100*7c568831SAndroid Build Coastguard Worker         PyObject * args ATTRIBUTE_UNUSED)
101*7c568831SAndroid Build Coastguard Worker {
102*7c568831SAndroid Build Coastguard Worker     long ret;
103*7c568831SAndroid Build Coastguard Worker     PyObject *py_retval;
104*7c568831SAndroid Build Coastguard Worker 
105*7c568831SAndroid Build Coastguard Worker     ret = xmlMemUsed();
106*7c568831SAndroid Build Coastguard Worker 
107*7c568831SAndroid Build Coastguard Worker     py_retval = libxml_longWrap(ret);
108*7c568831SAndroid Build Coastguard Worker     return (py_retval);
109*7c568831SAndroid Build Coastguard Worker }
110*7c568831SAndroid Build Coastguard Worker 
111*7c568831SAndroid Build Coastguard Worker PyObject *
libxml_xmlDebugMemory(PyObject * self ATTRIBUTE_UNUSED,PyObject * args)112*7c568831SAndroid Build Coastguard Worker libxml_xmlDebugMemory(PyObject * self ATTRIBUTE_UNUSED, PyObject * args)
113*7c568831SAndroid Build Coastguard Worker {
114*7c568831SAndroid Build Coastguard Worker     int activate;
115*7c568831SAndroid Build Coastguard Worker     PyObject *py_retval;
116*7c568831SAndroid Build Coastguard Worker     long ret;
117*7c568831SAndroid Build Coastguard Worker 
118*7c568831SAndroid Build Coastguard Worker     if (!PyArg_ParseTuple(args, (char *) "i:xmlDebugMemory", &activate))
119*7c568831SAndroid Build Coastguard Worker         return (NULL);
120*7c568831SAndroid Build Coastguard Worker 
121*7c568831SAndroid Build Coastguard Worker     if (activate != 0) {
122*7c568831SAndroid Build Coastguard Worker         if (libxmlMemoryDebug == 0) {
123*7c568831SAndroid Build Coastguard Worker             /*
124*7c568831SAndroid Build Coastguard Worker              * First initialize the library and grab the old memory handlers
125*7c568831SAndroid Build Coastguard Worker              * and switch the library to memory debugging
126*7c568831SAndroid Build Coastguard Worker              */
127*7c568831SAndroid Build Coastguard Worker             xmlMemGet((xmlFreeFunc *) & freeFunc,
128*7c568831SAndroid Build Coastguard Worker                       (xmlMallocFunc *) & mallocFunc,
129*7c568831SAndroid Build Coastguard Worker                       (xmlReallocFunc *) & reallocFunc,
130*7c568831SAndroid Build Coastguard Worker                       (xmlStrdupFunc *) & strdupFunc);
131*7c568831SAndroid Build Coastguard Worker             if ((freeFunc == xmlMemFree) && (mallocFunc == xmlMemMalloc) &&
132*7c568831SAndroid Build Coastguard Worker                 (reallocFunc == xmlMemRealloc) &&
133*7c568831SAndroid Build Coastguard Worker                 (strdupFunc == xmlMemoryStrdup)) {
134*7c568831SAndroid Build Coastguard Worker             } else {
135*7c568831SAndroid Build Coastguard Worker                 ret = (long) xmlMemSetup(xmlMemFree, xmlMemMalloc,
136*7c568831SAndroid Build Coastguard Worker                                          xmlMemRealloc, xmlMemoryStrdup);
137*7c568831SAndroid Build Coastguard Worker                 if (ret < 0)
138*7c568831SAndroid Build Coastguard Worker                     goto error;
139*7c568831SAndroid Build Coastguard Worker             }
140*7c568831SAndroid Build Coastguard Worker             libxmlMemoryAllocatedBase = xmlMemUsed();
141*7c568831SAndroid Build Coastguard Worker             ret = 0;
142*7c568831SAndroid Build Coastguard Worker         } else if (libxmlMemoryDebugActivated == 0) {
143*7c568831SAndroid Build Coastguard Worker             libxmlMemoryAllocatedBase = xmlMemUsed();
144*7c568831SAndroid Build Coastguard Worker             ret = 0;
145*7c568831SAndroid Build Coastguard Worker         } else {
146*7c568831SAndroid Build Coastguard Worker             ret = xmlMemUsed() - libxmlMemoryAllocatedBase;
147*7c568831SAndroid Build Coastguard Worker         }
148*7c568831SAndroid Build Coastguard Worker         libxmlMemoryDebug = 1;
149*7c568831SAndroid Build Coastguard Worker         libxmlMemoryDebugActivated = 1;
150*7c568831SAndroid Build Coastguard Worker     } else {
151*7c568831SAndroid Build Coastguard Worker         if (libxmlMemoryDebugActivated == 1)
152*7c568831SAndroid Build Coastguard Worker             ret = xmlMemUsed() - libxmlMemoryAllocatedBase;
153*7c568831SAndroid Build Coastguard Worker         else
154*7c568831SAndroid Build Coastguard Worker             ret = 0;
155*7c568831SAndroid Build Coastguard Worker         libxmlMemoryDebugActivated = 0;
156*7c568831SAndroid Build Coastguard Worker     }
157*7c568831SAndroid Build Coastguard Worker   error:
158*7c568831SAndroid Build Coastguard Worker     py_retval = libxml_longWrap(ret);
159*7c568831SAndroid Build Coastguard Worker     return (py_retval);
160*7c568831SAndroid Build Coastguard Worker }
161*7c568831SAndroid Build Coastguard Worker 
162*7c568831SAndroid Build Coastguard Worker PyObject *
libxml_xmlPythonCleanupParser(PyObject * self ATTRIBUTE_UNUSED,PyObject * args ATTRIBUTE_UNUSED)163*7c568831SAndroid Build Coastguard Worker libxml_xmlPythonCleanupParser(PyObject *self ATTRIBUTE_UNUSED,
164*7c568831SAndroid Build Coastguard Worker                               PyObject *args ATTRIBUTE_UNUSED) {
165*7c568831SAndroid Build Coastguard Worker 
166*7c568831SAndroid Build Coastguard Worker #ifdef LIBXML_XPATH_ENABLED
167*7c568831SAndroid Build Coastguard Worker     int ix;
168*7c568831SAndroid Build Coastguard Worker 
169*7c568831SAndroid Build Coastguard Worker     /*
170*7c568831SAndroid Build Coastguard Worker      * Need to confirm whether we really want to do this (required for
171*7c568831SAndroid Build Coastguard Worker      * memcheck) in all cases...
172*7c568831SAndroid Build Coastguard Worker      */
173*7c568831SAndroid Build Coastguard Worker 
174*7c568831SAndroid Build Coastguard Worker     if (libxml_xpathCallbacks != NULL) {	/* if ext funcs declared */
175*7c568831SAndroid Build Coastguard Worker 	for (ix=0; ix<libxml_xpathCallbacksNb; ix++) {
176*7c568831SAndroid Build Coastguard Worker 	    if ((*libxml_xpathCallbacks)[ix].name != NULL)
177*7c568831SAndroid Build Coastguard Worker 	        xmlFree((*libxml_xpathCallbacks)[ix].name);
178*7c568831SAndroid Build Coastguard Worker 	    if ((*libxml_xpathCallbacks)[ix].ns_uri != NULL)
179*7c568831SAndroid Build Coastguard Worker 	        xmlFree((*libxml_xpathCallbacks)[ix].ns_uri);
180*7c568831SAndroid Build Coastguard Worker 	}
181*7c568831SAndroid Build Coastguard Worker 	libxml_xpathCallbacksNb = 0;
182*7c568831SAndroid Build Coastguard Worker         xmlFree(libxml_xpathCallbacks);
183*7c568831SAndroid Build Coastguard Worker 	libxml_xpathCallbacks = NULL;
184*7c568831SAndroid Build Coastguard Worker     }
185*7c568831SAndroid Build Coastguard Worker #endif /* LIBXML_XPATH_ENABLED */
186*7c568831SAndroid Build Coastguard Worker 
187*7c568831SAndroid Build Coastguard Worker     xmlCleanupParser();
188*7c568831SAndroid Build Coastguard Worker 
189*7c568831SAndroid Build Coastguard Worker     Py_INCREF(Py_None);
190*7c568831SAndroid Build Coastguard Worker     return(Py_None);
191*7c568831SAndroid Build Coastguard Worker }
192*7c568831SAndroid Build Coastguard Worker 
193*7c568831SAndroid Build Coastguard Worker /************************************************************************
194*7c568831SAndroid Build Coastguard Worker  *									*
195*7c568831SAndroid Build Coastguard Worker  *		Handling Python FILE I/O at the C level			*
196*7c568831SAndroid Build Coastguard Worker  *	The raw I/O attack directly the File objects, while the		*
197*7c568831SAndroid Build Coastguard Worker  *	other routines address the ioWrapper instance instead		*
198*7c568831SAndroid Build Coastguard Worker  *									*
199*7c568831SAndroid Build Coastguard Worker  ************************************************************************/
200*7c568831SAndroid Build Coastguard Worker 
201*7c568831SAndroid Build Coastguard Worker /**
202*7c568831SAndroid Build Coastguard Worker  * xmlPythonFileCloseUnref:
203*7c568831SAndroid Build Coastguard Worker  * @context:  the I/O context
204*7c568831SAndroid Build Coastguard Worker  *
205*7c568831SAndroid Build Coastguard Worker  * Close an I/O channel
206*7c568831SAndroid Build Coastguard Worker  */
207*7c568831SAndroid Build Coastguard Worker static int
xmlPythonFileCloseRaw(void * context)208*7c568831SAndroid Build Coastguard Worker xmlPythonFileCloseRaw (void * context) {
209*7c568831SAndroid Build Coastguard Worker     PyObject *file, *ret;
210*7c568831SAndroid Build Coastguard Worker 
211*7c568831SAndroid Build Coastguard Worker     file = (PyObject *) context;
212*7c568831SAndroid Build Coastguard Worker     if (file == NULL) return(-1);
213*7c568831SAndroid Build Coastguard Worker     ret = PyObject_CallMethod(file, (char *) "close", (char *) "()");
214*7c568831SAndroid Build Coastguard Worker     if (ret != NULL) {
215*7c568831SAndroid Build Coastguard Worker 	Py_DECREF(ret);
216*7c568831SAndroid Build Coastguard Worker     }
217*7c568831SAndroid Build Coastguard Worker     Py_DECREF(file);
218*7c568831SAndroid Build Coastguard Worker     return(0);
219*7c568831SAndroid Build Coastguard Worker }
220*7c568831SAndroid Build Coastguard Worker 
221*7c568831SAndroid Build Coastguard Worker /**
222*7c568831SAndroid Build Coastguard Worker  * xmlPythonFileReadRaw:
223*7c568831SAndroid Build Coastguard Worker  * @context:  the I/O context
224*7c568831SAndroid Build Coastguard Worker  * @buffer:  where to drop data
225*7c568831SAndroid Build Coastguard Worker  * @len:  number of bytes to write
226*7c568831SAndroid Build Coastguard Worker  *
227*7c568831SAndroid Build Coastguard Worker  * Read @len bytes to @buffer from the Python file in the I/O channel
228*7c568831SAndroid Build Coastguard Worker  *
229*7c568831SAndroid Build Coastguard Worker  * Returns the number of bytes read
230*7c568831SAndroid Build Coastguard Worker  */
231*7c568831SAndroid Build Coastguard Worker static int
xmlPythonFileReadRaw(void * context,char * buffer,int len)232*7c568831SAndroid Build Coastguard Worker xmlPythonFileReadRaw (void * context, char * buffer, int len) {
233*7c568831SAndroid Build Coastguard Worker     PyObject *file;
234*7c568831SAndroid Build Coastguard Worker     PyObject *ret;
235*7c568831SAndroid Build Coastguard Worker     int lenread = -1;
236*7c568831SAndroid Build Coastguard Worker     char *data;
237*7c568831SAndroid Build Coastguard Worker 
238*7c568831SAndroid Build Coastguard Worker     file = (PyObject *) context;
239*7c568831SAndroid Build Coastguard Worker     if (file == NULL) return(-1);
240*7c568831SAndroid Build Coastguard Worker     ret = PyObject_CallMethod(file, (char *) "read", (char *) "(i)", len);
241*7c568831SAndroid Build Coastguard Worker     if (ret == NULL) {
242*7c568831SAndroid Build Coastguard Worker 	printf("xmlPythonFileReadRaw: result is NULL\n");
243*7c568831SAndroid Build Coastguard Worker 	return(-1);
244*7c568831SAndroid Build Coastguard Worker     } else if (PyBytes_Check(ret)) {
245*7c568831SAndroid Build Coastguard Worker 	lenread = PyBytes_Size(ret);
246*7c568831SAndroid Build Coastguard Worker 	data = PyBytes_AsString(ret);
247*7c568831SAndroid Build Coastguard Worker #ifdef PyUnicode_Check
248*7c568831SAndroid Build Coastguard Worker     } else if (PyUnicode_Check (ret)) {
249*7c568831SAndroid Build Coastguard Worker #if PY_VERSION_HEX >= 0x03030000
250*7c568831SAndroid Build Coastguard Worker         Py_ssize_t size;
251*7c568831SAndroid Build Coastguard Worker 	const char *tmp;
252*7c568831SAndroid Build Coastguard Worker 
253*7c568831SAndroid Build Coastguard Worker 	/* tmp doesn't need to be deallocated */
254*7c568831SAndroid Build Coastguard Worker         tmp = PyUnicode_AsUTF8AndSize(ret, &size);
255*7c568831SAndroid Build Coastguard Worker 
256*7c568831SAndroid Build Coastguard Worker 	lenread = (int) size;
257*7c568831SAndroid Build Coastguard Worker 	data = (char *) tmp;
258*7c568831SAndroid Build Coastguard Worker #else
259*7c568831SAndroid Build Coastguard Worker         PyObject *b;
260*7c568831SAndroid Build Coastguard Worker 	b = PyUnicode_AsUTF8String(ret);
261*7c568831SAndroid Build Coastguard Worker 	if (b == NULL) {
262*7c568831SAndroid Build Coastguard Worker 	    printf("xmlPythonFileReadRaw: failed to convert to UTF-8\n");
263*7c568831SAndroid Build Coastguard Worker 	    return(-1);
264*7c568831SAndroid Build Coastguard Worker 	}
265*7c568831SAndroid Build Coastguard Worker 	lenread = PyBytes_Size(b);
266*7c568831SAndroid Build Coastguard Worker 	data = PyBytes_AsString(b);
267*7c568831SAndroid Build Coastguard Worker 	Py_DECREF(b);
268*7c568831SAndroid Build Coastguard Worker #endif
269*7c568831SAndroid Build Coastguard Worker #endif
270*7c568831SAndroid Build Coastguard Worker     } else {
271*7c568831SAndroid Build Coastguard Worker 	printf("xmlPythonFileReadRaw: result is not a String\n");
272*7c568831SAndroid Build Coastguard Worker 	Py_DECREF(ret);
273*7c568831SAndroid Build Coastguard Worker 	return(-1);
274*7c568831SAndroid Build Coastguard Worker     }
275*7c568831SAndroid Build Coastguard Worker     if (lenread > len)
276*7c568831SAndroid Build Coastguard Worker 	memcpy(buffer, data, len);
277*7c568831SAndroid Build Coastguard Worker     else
278*7c568831SAndroid Build Coastguard Worker 	memcpy(buffer, data, lenread);
279*7c568831SAndroid Build Coastguard Worker     Py_DECREF(ret);
280*7c568831SAndroid Build Coastguard Worker     return(lenread);
281*7c568831SAndroid Build Coastguard Worker }
282*7c568831SAndroid Build Coastguard Worker 
283*7c568831SAndroid Build Coastguard Worker /**
284*7c568831SAndroid Build Coastguard Worker  * xmlPythonFileRead:
285*7c568831SAndroid Build Coastguard Worker  * @context:  the I/O context
286*7c568831SAndroid Build Coastguard Worker  * @buffer:  where to drop data
287*7c568831SAndroid Build Coastguard Worker  * @len:  number of bytes to write
288*7c568831SAndroid Build Coastguard Worker  *
289*7c568831SAndroid Build Coastguard Worker  * Read @len bytes to @buffer from the I/O channel.
290*7c568831SAndroid Build Coastguard Worker  *
291*7c568831SAndroid Build Coastguard Worker  * Returns the number of bytes read
292*7c568831SAndroid Build Coastguard Worker  */
293*7c568831SAndroid Build Coastguard Worker static int
xmlPythonFileRead(void * context,char * buffer,int len)294*7c568831SAndroid Build Coastguard Worker xmlPythonFileRead (void * context, char * buffer, int len) {
295*7c568831SAndroid Build Coastguard Worker     PyObject *file;
296*7c568831SAndroid Build Coastguard Worker     PyObject *ret;
297*7c568831SAndroid Build Coastguard Worker     int lenread = -1;
298*7c568831SAndroid Build Coastguard Worker     char *data;
299*7c568831SAndroid Build Coastguard Worker 
300*7c568831SAndroid Build Coastguard Worker     file = (PyObject *) context;
301*7c568831SAndroid Build Coastguard Worker     if (file == NULL) return(-1);
302*7c568831SAndroid Build Coastguard Worker     ret = PyObject_CallMethod(file, (char *) "io_read", (char *) "(i)", len);
303*7c568831SAndroid Build Coastguard Worker     if (ret == NULL) {
304*7c568831SAndroid Build Coastguard Worker 	printf("xmlPythonFileRead: result is NULL\n");
305*7c568831SAndroid Build Coastguard Worker 	return(-1);
306*7c568831SAndroid Build Coastguard Worker     } else if (PyBytes_Check(ret)) {
307*7c568831SAndroid Build Coastguard Worker 	lenread = PyBytes_Size(ret);
308*7c568831SAndroid Build Coastguard Worker 	data = PyBytes_AsString(ret);
309*7c568831SAndroid Build Coastguard Worker #ifdef PyUnicode_Check
310*7c568831SAndroid Build Coastguard Worker     } else if (PyUnicode_Check (ret)) {
311*7c568831SAndroid Build Coastguard Worker #if PY_VERSION_HEX >= 0x03030000
312*7c568831SAndroid Build Coastguard Worker         Py_ssize_t size;
313*7c568831SAndroid Build Coastguard Worker 	const char *tmp;
314*7c568831SAndroid Build Coastguard Worker 
315*7c568831SAndroid Build Coastguard Worker 	/* tmp doesn't need to be deallocated */
316*7c568831SAndroid Build Coastguard Worker         tmp = PyUnicode_AsUTF8AndSize(ret, &size);
317*7c568831SAndroid Build Coastguard Worker 
318*7c568831SAndroid Build Coastguard Worker 	lenread = (int) size;
319*7c568831SAndroid Build Coastguard Worker 	data = (char *) tmp;
320*7c568831SAndroid Build Coastguard Worker #else
321*7c568831SAndroid Build Coastguard Worker         PyObject *b;
322*7c568831SAndroid Build Coastguard Worker 	b = PyUnicode_AsUTF8String(ret);
323*7c568831SAndroid Build Coastguard Worker 	if (b == NULL) {
324*7c568831SAndroid Build Coastguard Worker 	    printf("xmlPythonFileRead: failed to convert to UTF-8\n");
325*7c568831SAndroid Build Coastguard Worker 	    return(-1);
326*7c568831SAndroid Build Coastguard Worker 	}
327*7c568831SAndroid Build Coastguard Worker 	lenread = PyBytes_Size(b);
328*7c568831SAndroid Build Coastguard Worker 	data = PyBytes_AsString(b);
329*7c568831SAndroid Build Coastguard Worker 	Py_DECREF(b);
330*7c568831SAndroid Build Coastguard Worker #endif
331*7c568831SAndroid Build Coastguard Worker #endif
332*7c568831SAndroid Build Coastguard Worker     } else {
333*7c568831SAndroid Build Coastguard Worker 	printf("xmlPythonFileRead: result is not a String\n");
334*7c568831SAndroid Build Coastguard Worker 	Py_DECREF(ret);
335*7c568831SAndroid Build Coastguard Worker 	return(-1);
336*7c568831SAndroid Build Coastguard Worker     }
337*7c568831SAndroid Build Coastguard Worker     if (lenread > len)
338*7c568831SAndroid Build Coastguard Worker 	memcpy(buffer, data, len);
339*7c568831SAndroid Build Coastguard Worker     else
340*7c568831SAndroid Build Coastguard Worker 	memcpy(buffer, data, lenread);
341*7c568831SAndroid Build Coastguard Worker     Py_DECREF(ret);
342*7c568831SAndroid Build Coastguard Worker     return(lenread);
343*7c568831SAndroid Build Coastguard Worker }
344*7c568831SAndroid Build Coastguard Worker 
345*7c568831SAndroid Build Coastguard Worker #ifdef LIBXML_OUTPUT_ENABLED
346*7c568831SAndroid Build Coastguard Worker /**
347*7c568831SAndroid Build Coastguard Worker  * xmlFileWrite:
348*7c568831SAndroid Build Coastguard Worker  * @context:  the I/O context
349*7c568831SAndroid Build Coastguard Worker  * @buffer:  where to drop data
350*7c568831SAndroid Build Coastguard Worker  * @len:  number of bytes to write
351*7c568831SAndroid Build Coastguard Worker  *
352*7c568831SAndroid Build Coastguard Worker  * Write @len bytes from @buffer to the I/O channel.
353*7c568831SAndroid Build Coastguard Worker  *
354*7c568831SAndroid Build Coastguard Worker  * Returns the number of bytes written
355*7c568831SAndroid Build Coastguard Worker  */
356*7c568831SAndroid Build Coastguard Worker static int
xmlPythonFileWrite(void * context,const char * buffer,int len)357*7c568831SAndroid Build Coastguard Worker xmlPythonFileWrite (void * context, const char * buffer, int len) {
358*7c568831SAndroid Build Coastguard Worker     PyObject *file;
359*7c568831SAndroid Build Coastguard Worker     PyObject *string;
360*7c568831SAndroid Build Coastguard Worker     PyObject *ret = NULL;
361*7c568831SAndroid Build Coastguard Worker     int written = -1;
362*7c568831SAndroid Build Coastguard Worker 
363*7c568831SAndroid Build Coastguard Worker     file = (PyObject *) context;
364*7c568831SAndroid Build Coastguard Worker     if (file == NULL) return(-1);
365*7c568831SAndroid Build Coastguard Worker     string = PY_IMPORT_STRING_SIZE(buffer, len);
366*7c568831SAndroid Build Coastguard Worker     if (string == NULL) return(-1);
367*7c568831SAndroid Build Coastguard Worker     if (PyObject_HasAttrString(file, (char *) "io_write")) {
368*7c568831SAndroid Build Coastguard Worker         ret = PyObject_CallMethod(file, (char *) "io_write", (char *) "(O)",
369*7c568831SAndroid Build Coastguard Worker 	                        string);
370*7c568831SAndroid Build Coastguard Worker     } else if (PyObject_HasAttrString(file, (char *) "write")) {
371*7c568831SAndroid Build Coastguard Worker         ret = PyObject_CallMethod(file, (char *) "write", (char *) "(O)",
372*7c568831SAndroid Build Coastguard Worker 	                        string);
373*7c568831SAndroid Build Coastguard Worker     }
374*7c568831SAndroid Build Coastguard Worker     Py_DECREF(string);
375*7c568831SAndroid Build Coastguard Worker     if (ret == NULL) {
376*7c568831SAndroid Build Coastguard Worker 	printf("xmlPythonFileWrite: result is NULL\n");
377*7c568831SAndroid Build Coastguard Worker 	return(-1);
378*7c568831SAndroid Build Coastguard Worker     } else if (PyLong_Check(ret)) {
379*7c568831SAndroid Build Coastguard Worker 	written = (int) PyLong_AsLong(ret);
380*7c568831SAndroid Build Coastguard Worker 	Py_DECREF(ret);
381*7c568831SAndroid Build Coastguard Worker     } else if (ret == Py_None) {
382*7c568831SAndroid Build Coastguard Worker 	written = len;
383*7c568831SAndroid Build Coastguard Worker 	Py_DECREF(ret);
384*7c568831SAndroid Build Coastguard Worker     } else {
385*7c568831SAndroid Build Coastguard Worker 	printf("xmlPythonFileWrite: result is not an Int nor None\n");
386*7c568831SAndroid Build Coastguard Worker 	Py_DECREF(ret);
387*7c568831SAndroid Build Coastguard Worker     }
388*7c568831SAndroid Build Coastguard Worker     return(written);
389*7c568831SAndroid Build Coastguard Worker }
390*7c568831SAndroid Build Coastguard Worker #endif /* LIBXML_OUTPUT_ENABLED */
391*7c568831SAndroid Build Coastguard Worker 
392*7c568831SAndroid Build Coastguard Worker /**
393*7c568831SAndroid Build Coastguard Worker  * xmlPythonFileClose:
394*7c568831SAndroid Build Coastguard Worker  * @context:  the I/O context
395*7c568831SAndroid Build Coastguard Worker  *
396*7c568831SAndroid Build Coastguard Worker  * Close an I/O channel
397*7c568831SAndroid Build Coastguard Worker  */
398*7c568831SAndroid Build Coastguard Worker static int
xmlPythonFileClose(void * context)399*7c568831SAndroid Build Coastguard Worker xmlPythonFileClose (void * context) {
400*7c568831SAndroid Build Coastguard Worker     PyObject *file, *ret = NULL;
401*7c568831SAndroid Build Coastguard Worker 
402*7c568831SAndroid Build Coastguard Worker     file = (PyObject *) context;
403*7c568831SAndroid Build Coastguard Worker     if (file == NULL) return(-1);
404*7c568831SAndroid Build Coastguard Worker     if (PyObject_HasAttrString(file, (char *) "io_close")) {
405*7c568831SAndroid Build Coastguard Worker         ret = PyObject_CallMethod(file, (char *) "io_close", (char *) "()");
406*7c568831SAndroid Build Coastguard Worker     } else if (PyObject_HasAttrString(file, (char *) "flush")) {
407*7c568831SAndroid Build Coastguard Worker         ret = PyObject_CallMethod(file, (char *) "flush", (char *) "()");
408*7c568831SAndroid Build Coastguard Worker     }
409*7c568831SAndroid Build Coastguard Worker     if (ret != NULL) {
410*7c568831SAndroid Build Coastguard Worker 	Py_DECREF(ret);
411*7c568831SAndroid Build Coastguard Worker     }
412*7c568831SAndroid Build Coastguard Worker     return(0);
413*7c568831SAndroid Build Coastguard Worker }
414*7c568831SAndroid Build Coastguard Worker 
415*7c568831SAndroid Build Coastguard Worker #ifdef LIBXML_OUTPUT_ENABLED
416*7c568831SAndroid Build Coastguard Worker /**
417*7c568831SAndroid Build Coastguard Worker  * xmlOutputBufferCreatePythonFile:
418*7c568831SAndroid Build Coastguard Worker  * @file:  a PyFile_Type
419*7c568831SAndroid Build Coastguard Worker  * @encoder:  the encoding converter or NULL
420*7c568831SAndroid Build Coastguard Worker  *
421*7c568831SAndroid Build Coastguard Worker  * Create a buffered output for the progressive saving to a PyFile_Type
422*7c568831SAndroid Build Coastguard Worker  * buffered C I/O
423*7c568831SAndroid Build Coastguard Worker  *
424*7c568831SAndroid Build Coastguard Worker  * Returns the new parser output or NULL
425*7c568831SAndroid Build Coastguard Worker  */
426*7c568831SAndroid Build Coastguard Worker static xmlOutputBufferPtr
xmlOutputBufferCreatePythonFile(PyObject * file,xmlCharEncodingHandlerPtr encoder)427*7c568831SAndroid Build Coastguard Worker xmlOutputBufferCreatePythonFile(PyObject *file,
428*7c568831SAndroid Build Coastguard Worker 	                        xmlCharEncodingHandlerPtr encoder) {
429*7c568831SAndroid Build Coastguard Worker     xmlOutputBufferPtr ret;
430*7c568831SAndroid Build Coastguard Worker 
431*7c568831SAndroid Build Coastguard Worker     if (file == NULL) return(NULL);
432*7c568831SAndroid Build Coastguard Worker 
433*7c568831SAndroid Build Coastguard Worker     ret = xmlAllocOutputBuffer(encoder);
434*7c568831SAndroid Build Coastguard Worker     if (ret != NULL) {
435*7c568831SAndroid Build Coastguard Worker         ret->context = file;
436*7c568831SAndroid Build Coastguard Worker 	/* Py_INCREF(file); */
437*7c568831SAndroid Build Coastguard Worker 	ret->writecallback = xmlPythonFileWrite;
438*7c568831SAndroid Build Coastguard Worker 	ret->closecallback = xmlPythonFileClose;
439*7c568831SAndroid Build Coastguard Worker     }
440*7c568831SAndroid Build Coastguard Worker 
441*7c568831SAndroid Build Coastguard Worker     return(ret);
442*7c568831SAndroid Build Coastguard Worker }
443*7c568831SAndroid Build Coastguard Worker 
444*7c568831SAndroid Build Coastguard Worker PyObject *
libxml_xmlCreateOutputBuffer(ATTRIBUTE_UNUSED PyObject * self,PyObject * args)445*7c568831SAndroid Build Coastguard Worker libxml_xmlCreateOutputBuffer(ATTRIBUTE_UNUSED PyObject *self, PyObject *args) {
446*7c568831SAndroid Build Coastguard Worker     PyObject *py_retval;
447*7c568831SAndroid Build Coastguard Worker     PyObject *file;
448*7c568831SAndroid Build Coastguard Worker     xmlChar  *encoding;
449*7c568831SAndroid Build Coastguard Worker     xmlCharEncodingHandlerPtr handler = NULL;
450*7c568831SAndroid Build Coastguard Worker     xmlOutputBufferPtr buffer;
451*7c568831SAndroid Build Coastguard Worker 
452*7c568831SAndroid Build Coastguard Worker 
453*7c568831SAndroid Build Coastguard Worker     if (!PyArg_ParseTuple(args, (char *)"Oz:xmlOutputBufferCreate",
454*7c568831SAndroid Build Coastguard Worker 		&file, &encoding))
455*7c568831SAndroid Build Coastguard Worker 	return(NULL);
456*7c568831SAndroid Build Coastguard Worker     if ((encoding != NULL) && (encoding[0] != 0)) {
457*7c568831SAndroid Build Coastguard Worker 	handler = xmlFindCharEncodingHandler((const char *) encoding);
458*7c568831SAndroid Build Coastguard Worker     }
459*7c568831SAndroid Build Coastguard Worker     buffer = xmlOutputBufferCreatePythonFile(file, handler);
460*7c568831SAndroid Build Coastguard Worker     if (buffer == NULL)
461*7c568831SAndroid Build Coastguard Worker 	printf("libxml_xmlCreateOutputBuffer: buffer == NULL\n");
462*7c568831SAndroid Build Coastguard Worker     py_retval = libxml_xmlOutputBufferPtrWrap(buffer);
463*7c568831SAndroid Build Coastguard Worker     return(py_retval);
464*7c568831SAndroid Build Coastguard Worker }
465*7c568831SAndroid Build Coastguard Worker 
466*7c568831SAndroid Build Coastguard Worker /**
467*7c568831SAndroid Build Coastguard Worker  * libxml_outputBufferGetPythonFile:
468*7c568831SAndroid Build Coastguard Worker  * @buffer:  the I/O buffer
469*7c568831SAndroid Build Coastguard Worker  *
470*7c568831SAndroid Build Coastguard Worker  * read the Python I/O from the CObject
471*7c568831SAndroid Build Coastguard Worker  *
472*7c568831SAndroid Build Coastguard Worker  * Returns the new parser output or NULL
473*7c568831SAndroid Build Coastguard Worker  */
474*7c568831SAndroid Build Coastguard Worker static PyObject *
libxml_outputBufferGetPythonFile(ATTRIBUTE_UNUSED PyObject * self,PyObject * args)475*7c568831SAndroid Build Coastguard Worker libxml_outputBufferGetPythonFile(ATTRIBUTE_UNUSED PyObject *self,
476*7c568831SAndroid Build Coastguard Worker                                     PyObject *args) {
477*7c568831SAndroid Build Coastguard Worker     PyObject *buffer;
478*7c568831SAndroid Build Coastguard Worker     PyObject *file;
479*7c568831SAndroid Build Coastguard Worker     xmlOutputBufferPtr obj;
480*7c568831SAndroid Build Coastguard Worker 
481*7c568831SAndroid Build Coastguard Worker     if (!PyArg_ParseTuple(args, (char *)"O:outputBufferGetPythonFile",
482*7c568831SAndroid Build Coastguard Worker 			  &buffer))
483*7c568831SAndroid Build Coastguard Worker 	return(NULL);
484*7c568831SAndroid Build Coastguard Worker 
485*7c568831SAndroid Build Coastguard Worker     obj = PyoutputBuffer_Get(buffer);
486*7c568831SAndroid Build Coastguard Worker     if (obj == NULL) {
487*7c568831SAndroid Build Coastguard Worker 	fprintf(stderr,
488*7c568831SAndroid Build Coastguard Worker 	        "outputBufferGetPythonFile: obj == NULL\n");
489*7c568831SAndroid Build Coastguard Worker 	Py_INCREF(Py_None);
490*7c568831SAndroid Build Coastguard Worker 	return(Py_None);
491*7c568831SAndroid Build Coastguard Worker     }
492*7c568831SAndroid Build Coastguard Worker     if (obj->closecallback != xmlPythonFileClose) {
493*7c568831SAndroid Build Coastguard Worker 	fprintf(stderr,
494*7c568831SAndroid Build Coastguard Worker 	        "outputBufferGetPythonFile: not a python file wrapper\n");
495*7c568831SAndroid Build Coastguard Worker 	Py_INCREF(Py_None);
496*7c568831SAndroid Build Coastguard Worker 	return(Py_None);
497*7c568831SAndroid Build Coastguard Worker     }
498*7c568831SAndroid Build Coastguard Worker     file = (PyObject *) obj->context;
499*7c568831SAndroid Build Coastguard Worker     if (file == NULL) {
500*7c568831SAndroid Build Coastguard Worker 	Py_INCREF(Py_None);
501*7c568831SAndroid Build Coastguard Worker 	return(Py_None);
502*7c568831SAndroid Build Coastguard Worker     }
503*7c568831SAndroid Build Coastguard Worker     Py_INCREF(file);
504*7c568831SAndroid Build Coastguard Worker     return(file);
505*7c568831SAndroid Build Coastguard Worker }
506*7c568831SAndroid Build Coastguard Worker 
507*7c568831SAndroid Build Coastguard Worker static PyObject *
libxml_xmlOutputBufferClose(PyObject * self ATTRIBUTE_UNUSED,PyObject * args)508*7c568831SAndroid Build Coastguard Worker libxml_xmlOutputBufferClose(PyObject *self ATTRIBUTE_UNUSED, PyObject *args) {
509*7c568831SAndroid Build Coastguard Worker     PyObject *py_retval;
510*7c568831SAndroid Build Coastguard Worker     int c_retval;
511*7c568831SAndroid Build Coastguard Worker     xmlOutputBufferPtr out;
512*7c568831SAndroid Build Coastguard Worker     PyObject *pyobj_out;
513*7c568831SAndroid Build Coastguard Worker 
514*7c568831SAndroid Build Coastguard Worker     if (!PyArg_ParseTuple(args, (char *)"O:xmlOutputBufferClose", &pyobj_out))
515*7c568831SAndroid Build Coastguard Worker         return(NULL);
516*7c568831SAndroid Build Coastguard Worker     out = (xmlOutputBufferPtr) PyoutputBuffer_Get(pyobj_out);
517*7c568831SAndroid Build Coastguard Worker     /* Buffer may already have been destroyed elsewhere. This is harmless. */
518*7c568831SAndroid Build Coastguard Worker     if (out == NULL) {
519*7c568831SAndroid Build Coastguard Worker 	Py_INCREF(Py_None);
520*7c568831SAndroid Build Coastguard Worker 	return(Py_None);
521*7c568831SAndroid Build Coastguard Worker     }
522*7c568831SAndroid Build Coastguard Worker 
523*7c568831SAndroid Build Coastguard Worker     c_retval = xmlOutputBufferClose(out);
524*7c568831SAndroid Build Coastguard Worker     py_retval = libxml_intWrap((int) c_retval);
525*7c568831SAndroid Build Coastguard Worker     return(py_retval);
526*7c568831SAndroid Build Coastguard Worker }
527*7c568831SAndroid Build Coastguard Worker 
528*7c568831SAndroid Build Coastguard Worker static PyObject *
libxml_xmlOutputBufferFlush(PyObject * self ATTRIBUTE_UNUSED,PyObject * args)529*7c568831SAndroid Build Coastguard Worker libxml_xmlOutputBufferFlush(PyObject *self ATTRIBUTE_UNUSED, PyObject *args) {
530*7c568831SAndroid Build Coastguard Worker     PyObject *py_retval;
531*7c568831SAndroid Build Coastguard Worker     int c_retval;
532*7c568831SAndroid Build Coastguard Worker     xmlOutputBufferPtr out;
533*7c568831SAndroid Build Coastguard Worker     PyObject *pyobj_out;
534*7c568831SAndroid Build Coastguard Worker 
535*7c568831SAndroid Build Coastguard Worker     if (!PyArg_ParseTuple(args, (char *)"O:xmlOutputBufferFlush", &pyobj_out))
536*7c568831SAndroid Build Coastguard Worker         return(NULL);
537*7c568831SAndroid Build Coastguard Worker     out = (xmlOutputBufferPtr) PyoutputBuffer_Get(pyobj_out);
538*7c568831SAndroid Build Coastguard Worker 
539*7c568831SAndroid Build Coastguard Worker     c_retval = xmlOutputBufferFlush(out);
540*7c568831SAndroid Build Coastguard Worker     py_retval = libxml_intWrap((int) c_retval);
541*7c568831SAndroid Build Coastguard Worker     return(py_retval);
542*7c568831SAndroid Build Coastguard Worker }
543*7c568831SAndroid Build Coastguard Worker 
544*7c568831SAndroid Build Coastguard Worker static PyObject *
libxml_xmlSaveFileTo(PyObject * self ATTRIBUTE_UNUSED,PyObject * args)545*7c568831SAndroid Build Coastguard Worker libxml_xmlSaveFileTo(PyObject *self ATTRIBUTE_UNUSED, PyObject *args) {
546*7c568831SAndroid Build Coastguard Worker     PyObject *py_retval;
547*7c568831SAndroid Build Coastguard Worker     int c_retval;
548*7c568831SAndroid Build Coastguard Worker     xmlOutputBufferPtr buf;
549*7c568831SAndroid Build Coastguard Worker     PyObject *pyobj_buf;
550*7c568831SAndroid Build Coastguard Worker     xmlDocPtr cur;
551*7c568831SAndroid Build Coastguard Worker     PyObject *pyobj_cur;
552*7c568831SAndroid Build Coastguard Worker     char * encoding;
553*7c568831SAndroid Build Coastguard Worker 
554*7c568831SAndroid Build Coastguard Worker     if (!PyArg_ParseTuple(args, (char *)"OOz:xmlSaveFileTo", &pyobj_buf, &pyobj_cur, &encoding))
555*7c568831SAndroid Build Coastguard Worker         return(NULL);
556*7c568831SAndroid Build Coastguard Worker     buf = (xmlOutputBufferPtr) PyoutputBuffer_Get(pyobj_buf);
557*7c568831SAndroid Build Coastguard Worker     cur = (xmlDocPtr) PyxmlNode_Get(pyobj_cur);
558*7c568831SAndroid Build Coastguard Worker 
559*7c568831SAndroid Build Coastguard Worker     c_retval = xmlSaveFileTo(buf, cur, encoding);
560*7c568831SAndroid Build Coastguard Worker 	/* xmlSaveTo() freed the memory pointed to by buf, so record that in the
561*7c568831SAndroid Build Coastguard Worker 	 * Python object. */
562*7c568831SAndroid Build Coastguard Worker     ((PyoutputBuffer_Object *)(pyobj_buf))->obj = NULL;
563*7c568831SAndroid Build Coastguard Worker     py_retval = libxml_intWrap((int) c_retval);
564*7c568831SAndroid Build Coastguard Worker     return(py_retval);
565*7c568831SAndroid Build Coastguard Worker }
566*7c568831SAndroid Build Coastguard Worker 
567*7c568831SAndroid Build Coastguard Worker static PyObject *
libxml_xmlSaveFormatFileTo(PyObject * self ATTRIBUTE_UNUSED,PyObject * args)568*7c568831SAndroid Build Coastguard Worker libxml_xmlSaveFormatFileTo(PyObject *self ATTRIBUTE_UNUSED, PyObject *args) {
569*7c568831SAndroid Build Coastguard Worker     PyObject *py_retval;
570*7c568831SAndroid Build Coastguard Worker     int c_retval;
571*7c568831SAndroid Build Coastguard Worker     xmlOutputBufferPtr buf;
572*7c568831SAndroid Build Coastguard Worker     PyObject *pyobj_buf;
573*7c568831SAndroid Build Coastguard Worker     xmlDocPtr cur;
574*7c568831SAndroid Build Coastguard Worker     PyObject *pyobj_cur;
575*7c568831SAndroid Build Coastguard Worker     char * encoding;
576*7c568831SAndroid Build Coastguard Worker     int format;
577*7c568831SAndroid Build Coastguard Worker 
578*7c568831SAndroid Build Coastguard Worker     if (!PyArg_ParseTuple(args, (char *)"OOzi:xmlSaveFormatFileTo", &pyobj_buf, &pyobj_cur, &encoding, &format))
579*7c568831SAndroid Build Coastguard Worker         return(NULL);
580*7c568831SAndroid Build Coastguard Worker     buf = (xmlOutputBufferPtr) PyoutputBuffer_Get(pyobj_buf);
581*7c568831SAndroid Build Coastguard Worker     cur = (xmlDocPtr) PyxmlNode_Get(pyobj_cur);
582*7c568831SAndroid Build Coastguard Worker 
583*7c568831SAndroid Build Coastguard Worker     c_retval = xmlSaveFormatFileTo(buf, cur, encoding, format);
584*7c568831SAndroid Build Coastguard Worker 	/* xmlSaveFormatFileTo() freed the memory pointed to by buf, so record that
585*7c568831SAndroid Build Coastguard Worker 	 * in the Python object */
586*7c568831SAndroid Build Coastguard Worker 	((PyoutputBuffer_Object *)(pyobj_buf))->obj = NULL;
587*7c568831SAndroid Build Coastguard Worker     py_retval = libxml_intWrap((int) c_retval);
588*7c568831SAndroid Build Coastguard Worker     return(py_retval);
589*7c568831SAndroid Build Coastguard Worker }
590*7c568831SAndroid Build Coastguard Worker #endif /* LIBXML_OUTPUT_ENABLED */
591*7c568831SAndroid Build Coastguard Worker 
592*7c568831SAndroid Build Coastguard Worker 
593*7c568831SAndroid Build Coastguard Worker /**
594*7c568831SAndroid Build Coastguard Worker  * xmlParserInputBufferCreatePythonFile:
595*7c568831SAndroid Build Coastguard Worker  * @file:  a PyFile_Type
596*7c568831SAndroid Build Coastguard Worker  * @encoder:  the encoding converter or NULL
597*7c568831SAndroid Build Coastguard Worker  *
598*7c568831SAndroid Build Coastguard Worker  * Create a buffered output for the progressive saving to a PyFile_Type
599*7c568831SAndroid Build Coastguard Worker  * buffered C I/O
600*7c568831SAndroid Build Coastguard Worker  *
601*7c568831SAndroid Build Coastguard Worker  * Returns the new parser output or NULL
602*7c568831SAndroid Build Coastguard Worker  */
603*7c568831SAndroid Build Coastguard Worker static xmlParserInputBufferPtr
xmlParserInputBufferCreatePythonFile(PyObject * file,xmlCharEncoding encoding)604*7c568831SAndroid Build Coastguard Worker xmlParserInputBufferCreatePythonFile(PyObject *file,
605*7c568831SAndroid Build Coastguard Worker 	                        xmlCharEncoding encoding) {
606*7c568831SAndroid Build Coastguard Worker     xmlParserInputBufferPtr ret;
607*7c568831SAndroid Build Coastguard Worker 
608*7c568831SAndroid Build Coastguard Worker     if (file == NULL) return(NULL);
609*7c568831SAndroid Build Coastguard Worker 
610*7c568831SAndroid Build Coastguard Worker     ret = xmlAllocParserInputBuffer(encoding);
611*7c568831SAndroid Build Coastguard Worker     if (ret != NULL) {
612*7c568831SAndroid Build Coastguard Worker         ret->context = file;
613*7c568831SAndroid Build Coastguard Worker 	/* Py_INCREF(file); */
614*7c568831SAndroid Build Coastguard Worker 	ret->readcallback = xmlPythonFileRead;
615*7c568831SAndroid Build Coastguard Worker 	ret->closecallback = xmlPythonFileClose;
616*7c568831SAndroid Build Coastguard Worker     }
617*7c568831SAndroid Build Coastguard Worker 
618*7c568831SAndroid Build Coastguard Worker     return(ret);
619*7c568831SAndroid Build Coastguard Worker }
620*7c568831SAndroid Build Coastguard Worker 
621*7c568831SAndroid Build Coastguard Worker PyObject *
libxml_xmlCreateInputBuffer(ATTRIBUTE_UNUSED PyObject * self,PyObject * args)622*7c568831SAndroid Build Coastguard Worker libxml_xmlCreateInputBuffer(ATTRIBUTE_UNUSED PyObject *self, PyObject *args) {
623*7c568831SAndroid Build Coastguard Worker     PyObject *py_retval;
624*7c568831SAndroid Build Coastguard Worker     PyObject *file;
625*7c568831SAndroid Build Coastguard Worker     xmlChar  *encoding;
626*7c568831SAndroid Build Coastguard Worker     xmlCharEncoding enc = XML_CHAR_ENCODING_NONE;
627*7c568831SAndroid Build Coastguard Worker     xmlParserInputBufferPtr buffer;
628*7c568831SAndroid Build Coastguard Worker 
629*7c568831SAndroid Build Coastguard Worker 
630*7c568831SAndroid Build Coastguard Worker     if (!PyArg_ParseTuple(args, (char *)"Oz:xmlParserInputBufferCreate",
631*7c568831SAndroid Build Coastguard Worker 		&file, &encoding))
632*7c568831SAndroid Build Coastguard Worker 	return(NULL);
633*7c568831SAndroid Build Coastguard Worker     if ((encoding != NULL) && (encoding[0] != 0)) {
634*7c568831SAndroid Build Coastguard Worker 	enc = xmlParseCharEncoding((const char *) encoding);
635*7c568831SAndroid Build Coastguard Worker     }
636*7c568831SAndroid Build Coastguard Worker     buffer = xmlParserInputBufferCreatePythonFile(file, enc);
637*7c568831SAndroid Build Coastguard Worker     if (buffer == NULL)
638*7c568831SAndroid Build Coastguard Worker 	printf("libxml_xmlParserInputBufferCreate: buffer == NULL\n");
639*7c568831SAndroid Build Coastguard Worker     py_retval = libxml_xmlParserInputBufferPtrWrap(buffer);
640*7c568831SAndroid Build Coastguard Worker     return(py_retval);
641*7c568831SAndroid Build Coastguard Worker }
642*7c568831SAndroid Build Coastguard Worker 
643*7c568831SAndroid Build Coastguard Worker /************************************************************************
644*7c568831SAndroid Build Coastguard Worker  *									*
645*7c568831SAndroid Build Coastguard Worker  *		Providing the resolver at the Python level		*
646*7c568831SAndroid Build Coastguard Worker  *									*
647*7c568831SAndroid Build Coastguard Worker  ************************************************************************/
648*7c568831SAndroid Build Coastguard Worker 
649*7c568831SAndroid Build Coastguard Worker static xmlExternalEntityLoader defaultExternalEntityLoader = NULL;
650*7c568831SAndroid Build Coastguard Worker static PyObject *pythonExternalEntityLoaderObjext;
651*7c568831SAndroid Build Coastguard Worker 
652*7c568831SAndroid Build Coastguard Worker static xmlParserInputPtr
pythonExternalEntityLoader(const char * URL,const char * ID,xmlParserCtxtPtr ctxt)653*7c568831SAndroid Build Coastguard Worker pythonExternalEntityLoader(const char *URL, const char *ID,
654*7c568831SAndroid Build Coastguard Worker 			   xmlParserCtxtPtr ctxt) {
655*7c568831SAndroid Build Coastguard Worker     xmlParserInputPtr result = NULL;
656*7c568831SAndroid Build Coastguard Worker     if (pythonExternalEntityLoaderObjext != NULL) {
657*7c568831SAndroid Build Coastguard Worker 	PyObject *ret;
658*7c568831SAndroid Build Coastguard Worker 	PyObject *ctxtobj;
659*7c568831SAndroid Build Coastguard Worker 
660*7c568831SAndroid Build Coastguard Worker 	ctxtobj = libxml_xmlParserCtxtPtrWrap(ctxt);
661*7c568831SAndroid Build Coastguard Worker 
662*7c568831SAndroid Build Coastguard Worker 	ret = PyObject_CallFunction(pythonExternalEntityLoaderObjext,
663*7c568831SAndroid Build Coastguard Worker 		      (char *) "(ssO)", URL, ID, ctxtobj);
664*7c568831SAndroid Build Coastguard Worker 	Py_XDECREF(ctxtobj);
665*7c568831SAndroid Build Coastguard Worker 
666*7c568831SAndroid Build Coastguard Worker 	if (ret != NULL) {
667*7c568831SAndroid Build Coastguard Worker 	    if (PyObject_HasAttrString(ret, (char *) "read")) {
668*7c568831SAndroid Build Coastguard Worker 		xmlParserInputBufferPtr buf;
669*7c568831SAndroid Build Coastguard Worker 
670*7c568831SAndroid Build Coastguard Worker 		buf = xmlAllocParserInputBuffer(XML_CHAR_ENCODING_NONE);
671*7c568831SAndroid Build Coastguard Worker 		if (buf != NULL) {
672*7c568831SAndroid Build Coastguard Worker 		    buf->context = ret;
673*7c568831SAndroid Build Coastguard Worker 		    buf->readcallback = xmlPythonFileReadRaw;
674*7c568831SAndroid Build Coastguard Worker 		    buf->closecallback = xmlPythonFileCloseRaw;
675*7c568831SAndroid Build Coastguard Worker 		    result = xmlNewIOInputStream(ctxt, buf,
676*7c568831SAndroid Build Coastguard Worker 			                         XML_CHAR_ENCODING_NONE);
677*7c568831SAndroid Build Coastguard Worker 		}
678*7c568831SAndroid Build Coastguard Worker #if 0
679*7c568831SAndroid Build Coastguard Worker 	    } else {
680*7c568831SAndroid Build Coastguard Worker 		if (URL != NULL)
681*7c568831SAndroid Build Coastguard Worker 		    printf("pythonExternalEntityLoader: can't read %s\n",
682*7c568831SAndroid Build Coastguard Worker 		           URL);
683*7c568831SAndroid Build Coastguard Worker #endif
684*7c568831SAndroid Build Coastguard Worker 	    }
685*7c568831SAndroid Build Coastguard Worker 	    if (result == NULL) {
686*7c568831SAndroid Build Coastguard Worker 		Py_DECREF(ret);
687*7c568831SAndroid Build Coastguard Worker 	    } else if (URL != NULL) {
688*7c568831SAndroid Build Coastguard Worker 		result->filename = (char *) xmlStrdup((const xmlChar *)URL);
689*7c568831SAndroid Build Coastguard Worker 	    }
690*7c568831SAndroid Build Coastguard Worker 	}
691*7c568831SAndroid Build Coastguard Worker     }
692*7c568831SAndroid Build Coastguard Worker     if ((result == NULL) && (defaultExternalEntityLoader != NULL)) {
693*7c568831SAndroid Build Coastguard Worker 	result = defaultExternalEntityLoader(URL, ID, ctxt);
694*7c568831SAndroid Build Coastguard Worker     }
695*7c568831SAndroid Build Coastguard Worker     return(result);
696*7c568831SAndroid Build Coastguard Worker }
697*7c568831SAndroid Build Coastguard Worker 
698*7c568831SAndroid Build Coastguard Worker PyObject *
libxml_xmlSetEntityLoader(ATTRIBUTE_UNUSED PyObject * self,PyObject * args)699*7c568831SAndroid Build Coastguard Worker libxml_xmlSetEntityLoader(ATTRIBUTE_UNUSED PyObject *self, PyObject *args) {
700*7c568831SAndroid Build Coastguard Worker     PyObject *py_retval;
701*7c568831SAndroid Build Coastguard Worker     PyObject *loader;
702*7c568831SAndroid Build Coastguard Worker 
703*7c568831SAndroid Build Coastguard Worker     if (!PyArg_ParseTuple(args, (char *)"O:libxml_xmlSetEntityLoader",
704*7c568831SAndroid Build Coastguard Worker 		&loader))
705*7c568831SAndroid Build Coastguard Worker 	return(NULL);
706*7c568831SAndroid Build Coastguard Worker 
707*7c568831SAndroid Build Coastguard Worker     if (!PyCallable_Check(loader)) {
708*7c568831SAndroid Build Coastguard Worker 	PyErr_SetString(PyExc_ValueError, "entity loader is not callable");
709*7c568831SAndroid Build Coastguard Worker 	return(NULL);
710*7c568831SAndroid Build Coastguard Worker     }
711*7c568831SAndroid Build Coastguard Worker 
712*7c568831SAndroid Build Coastguard Worker     if (defaultExternalEntityLoader == NULL)
713*7c568831SAndroid Build Coastguard Worker 	defaultExternalEntityLoader = xmlGetExternalEntityLoader();
714*7c568831SAndroid Build Coastguard Worker 
715*7c568831SAndroid Build Coastguard Worker     Py_XDECREF(pythonExternalEntityLoaderObjext);
716*7c568831SAndroid Build Coastguard Worker     pythonExternalEntityLoaderObjext = loader;
717*7c568831SAndroid Build Coastguard Worker     Py_XINCREF(pythonExternalEntityLoaderObjext);
718*7c568831SAndroid Build Coastguard Worker     xmlSetExternalEntityLoader(pythonExternalEntityLoader);
719*7c568831SAndroid Build Coastguard Worker 
720*7c568831SAndroid Build Coastguard Worker     py_retval = PyLong_FromLong(0);
721*7c568831SAndroid Build Coastguard Worker     return(py_retval);
722*7c568831SAndroid Build Coastguard Worker }
723*7c568831SAndroid Build Coastguard Worker 
724*7c568831SAndroid Build Coastguard Worker /************************************************************************
725*7c568831SAndroid Build Coastguard Worker  *									*
726*7c568831SAndroid Build Coastguard Worker  *		Input callback registration				*
727*7c568831SAndroid Build Coastguard Worker  *									*
728*7c568831SAndroid Build Coastguard Worker  ************************************************************************/
729*7c568831SAndroid Build Coastguard Worker static PyObject *pythonInputOpenCallbackObject;
730*7c568831SAndroid Build Coastguard Worker static int pythonInputCallbackID = -1;
731*7c568831SAndroid Build Coastguard Worker 
732*7c568831SAndroid Build Coastguard Worker static int
pythonInputMatchCallback(ATTRIBUTE_UNUSED const char * URI)733*7c568831SAndroid Build Coastguard Worker pythonInputMatchCallback(ATTRIBUTE_UNUSED const char *URI)
734*7c568831SAndroid Build Coastguard Worker {
735*7c568831SAndroid Build Coastguard Worker     /* Always return success, real decision whether URI is supported will be
736*7c568831SAndroid Build Coastguard Worker      * made in open callback.  */
737*7c568831SAndroid Build Coastguard Worker     return 1;
738*7c568831SAndroid Build Coastguard Worker }
739*7c568831SAndroid Build Coastguard Worker 
740*7c568831SAndroid Build Coastguard Worker static void *
pythonInputOpenCallback(const char * URI)741*7c568831SAndroid Build Coastguard Worker pythonInputOpenCallback(const char *URI)
742*7c568831SAndroid Build Coastguard Worker {
743*7c568831SAndroid Build Coastguard Worker     PyObject *ret;
744*7c568831SAndroid Build Coastguard Worker 
745*7c568831SAndroid Build Coastguard Worker     ret = PyObject_CallFunction(pythonInputOpenCallbackObject,
746*7c568831SAndroid Build Coastguard Worker 	    (char *)"s", URI);
747*7c568831SAndroid Build Coastguard Worker     if (ret == Py_None) {
748*7c568831SAndroid Build Coastguard Worker 	Py_DECREF(Py_None);
749*7c568831SAndroid Build Coastguard Worker 	return NULL;
750*7c568831SAndroid Build Coastguard Worker     }
751*7c568831SAndroid Build Coastguard Worker     return ret;
752*7c568831SAndroid Build Coastguard Worker }
753*7c568831SAndroid Build Coastguard Worker 
754*7c568831SAndroid Build Coastguard Worker PyObject *
libxml_xmlRegisterInputCallback(ATTRIBUTE_UNUSED PyObject * self,PyObject * args)755*7c568831SAndroid Build Coastguard Worker libxml_xmlRegisterInputCallback(ATTRIBUTE_UNUSED PyObject *self,
756*7c568831SAndroid Build Coastguard Worker                                 PyObject *args) {
757*7c568831SAndroid Build Coastguard Worker     PyObject *cb;
758*7c568831SAndroid Build Coastguard Worker 
759*7c568831SAndroid Build Coastguard Worker     if (!PyArg_ParseTuple(args,
760*7c568831SAndroid Build Coastguard Worker 		(const char *)"O:libxml_xmlRegisterInputCallback", &cb))
761*7c568831SAndroid Build Coastguard Worker 	return(NULL);
762*7c568831SAndroid Build Coastguard Worker 
763*7c568831SAndroid Build Coastguard Worker     if (!PyCallable_Check(cb)) {
764*7c568831SAndroid Build Coastguard Worker 	PyErr_SetString(PyExc_ValueError, "input callback is not callable");
765*7c568831SAndroid Build Coastguard Worker 	return(NULL);
766*7c568831SAndroid Build Coastguard Worker     }
767*7c568831SAndroid Build Coastguard Worker 
768*7c568831SAndroid Build Coastguard Worker     /* Python module registers a single callback and manages the list of
769*7c568831SAndroid Build Coastguard Worker      * all callbacks internally. This is necessitated by xmlInputMatchCallback
770*7c568831SAndroid Build Coastguard Worker      * API, which does not allow for passing of data objects to discriminate
771*7c568831SAndroid Build Coastguard Worker      * different Python methods.  */
772*7c568831SAndroid Build Coastguard Worker     if (pythonInputCallbackID == -1) {
773*7c568831SAndroid Build Coastguard Worker 	pythonInputCallbackID = xmlRegisterInputCallbacks(
774*7c568831SAndroid Build Coastguard Worker 		pythonInputMatchCallback, pythonInputOpenCallback,
775*7c568831SAndroid Build Coastguard Worker 		xmlPythonFileReadRaw, xmlPythonFileCloseRaw);
776*7c568831SAndroid Build Coastguard Worker 	if (pythonInputCallbackID == -1)
777*7c568831SAndroid Build Coastguard Worker 	    return PyErr_NoMemory();
778*7c568831SAndroid Build Coastguard Worker 	pythonInputOpenCallbackObject = cb;
779*7c568831SAndroid Build Coastguard Worker 	Py_INCREF(pythonInputOpenCallbackObject);
780*7c568831SAndroid Build Coastguard Worker     }
781*7c568831SAndroid Build Coastguard Worker 
782*7c568831SAndroid Build Coastguard Worker     Py_INCREF(Py_None);
783*7c568831SAndroid Build Coastguard Worker     return(Py_None);
784*7c568831SAndroid Build Coastguard Worker }
785*7c568831SAndroid Build Coastguard Worker 
786*7c568831SAndroid Build Coastguard Worker PyObject *
libxml_xmlUnregisterInputCallback(ATTRIBUTE_UNUSED PyObject * self,ATTRIBUTE_UNUSED PyObject * args)787*7c568831SAndroid Build Coastguard Worker libxml_xmlUnregisterInputCallback(ATTRIBUTE_UNUSED PyObject *self,
788*7c568831SAndroid Build Coastguard Worker                                 ATTRIBUTE_UNUSED PyObject *args) {
789*7c568831SAndroid Build Coastguard Worker     int ret;
790*7c568831SAndroid Build Coastguard Worker 
791*7c568831SAndroid Build Coastguard Worker     ret = xmlPopInputCallbacks();
792*7c568831SAndroid Build Coastguard Worker     if (pythonInputCallbackID != -1) {
793*7c568831SAndroid Build Coastguard Worker 	/* Assert that the right input callback was popped. libxml's API does not
794*7c568831SAndroid Build Coastguard Worker 	 * allow removal by ID, so all that could be done is an assert.  */
795*7c568831SAndroid Build Coastguard Worker 	if (pythonInputCallbackID == ret) {
796*7c568831SAndroid Build Coastguard Worker 	    pythonInputCallbackID = -1;
797*7c568831SAndroid Build Coastguard Worker 	    Py_DECREF(pythonInputOpenCallbackObject);
798*7c568831SAndroid Build Coastguard Worker 	    pythonInputOpenCallbackObject = NULL;
799*7c568831SAndroid Build Coastguard Worker 	} else {
800*7c568831SAndroid Build Coastguard Worker 	    PyErr_SetString(PyExc_AssertionError, "popped non-python input callback");
801*7c568831SAndroid Build Coastguard Worker 	    return(NULL);
802*7c568831SAndroid Build Coastguard Worker 	}
803*7c568831SAndroid Build Coastguard Worker     } else if (ret == -1) {
804*7c568831SAndroid Build Coastguard Worker 	/* No more callbacks to pop */
805*7c568831SAndroid Build Coastguard Worker 	PyErr_SetString(PyExc_IndexError, "no input callbacks to pop");
806*7c568831SAndroid Build Coastguard Worker 	return(NULL);
807*7c568831SAndroid Build Coastguard Worker     }
808*7c568831SAndroid Build Coastguard Worker 
809*7c568831SAndroid Build Coastguard Worker     Py_INCREF(Py_None);
810*7c568831SAndroid Build Coastguard Worker     return(Py_None);
811*7c568831SAndroid Build Coastguard Worker }
812*7c568831SAndroid Build Coastguard Worker 
813*7c568831SAndroid Build Coastguard Worker /************************************************************************
814*7c568831SAndroid Build Coastguard Worker  *									*
815*7c568831SAndroid Build Coastguard Worker  *		Handling SAX/xmllib/sgmlop callback interfaces		*
816*7c568831SAndroid Build Coastguard Worker  *									*
817*7c568831SAndroid Build Coastguard Worker  ************************************************************************/
818*7c568831SAndroid Build Coastguard Worker 
819*7c568831SAndroid Build Coastguard Worker static void
pythonStartElement(void * user_data,const xmlChar * name,const xmlChar ** attrs)820*7c568831SAndroid Build Coastguard Worker pythonStartElement(void *user_data, const xmlChar * name,
821*7c568831SAndroid Build Coastguard Worker                    const xmlChar ** attrs)
822*7c568831SAndroid Build Coastguard Worker {
823*7c568831SAndroid Build Coastguard Worker     int i;
824*7c568831SAndroid Build Coastguard Worker     PyObject *handler;
825*7c568831SAndroid Build Coastguard Worker     PyObject *dict;
826*7c568831SAndroid Build Coastguard Worker     PyObject *attrname;
827*7c568831SAndroid Build Coastguard Worker     PyObject *attrvalue;
828*7c568831SAndroid Build Coastguard Worker     PyObject *result = NULL;
829*7c568831SAndroid Build Coastguard Worker     int type = 0;
830*7c568831SAndroid Build Coastguard Worker 
831*7c568831SAndroid Build Coastguard Worker     handler = (PyObject *) user_data;
832*7c568831SAndroid Build Coastguard Worker     if (PyObject_HasAttrString(handler, (char *) "startElement"))
833*7c568831SAndroid Build Coastguard Worker         type = 1;
834*7c568831SAndroid Build Coastguard Worker     else if (PyObject_HasAttrString(handler, (char *) "start"))
835*7c568831SAndroid Build Coastguard Worker         type = 2;
836*7c568831SAndroid Build Coastguard Worker     if (type != 0) {
837*7c568831SAndroid Build Coastguard Worker         /*
838*7c568831SAndroid Build Coastguard Worker          * the xmllib interface always generates a dictionary,
839*7c568831SAndroid Build Coastguard Worker          * possibly empty
840*7c568831SAndroid Build Coastguard Worker          */
841*7c568831SAndroid Build Coastguard Worker         if ((attrs == NULL) && (type == 1)) {
842*7c568831SAndroid Build Coastguard Worker             Py_XINCREF(Py_None);
843*7c568831SAndroid Build Coastguard Worker             dict = Py_None;
844*7c568831SAndroid Build Coastguard Worker         } else if (attrs == NULL) {
845*7c568831SAndroid Build Coastguard Worker             dict = PyDict_New();
846*7c568831SAndroid Build Coastguard Worker         } else {
847*7c568831SAndroid Build Coastguard Worker             dict = PyDict_New();
848*7c568831SAndroid Build Coastguard Worker             for (i = 0; attrs[i] != NULL; i++) {
849*7c568831SAndroid Build Coastguard Worker                 attrname = PY_IMPORT_STRING((char *) attrs[i]);
850*7c568831SAndroid Build Coastguard Worker                 i++;
851*7c568831SAndroid Build Coastguard Worker                 if (attrs[i] != NULL) {
852*7c568831SAndroid Build Coastguard Worker                     attrvalue = PY_IMPORT_STRING((char *) attrs[i]);
853*7c568831SAndroid Build Coastguard Worker                 } else {
854*7c568831SAndroid Build Coastguard Worker                     Py_XINCREF(Py_None);
855*7c568831SAndroid Build Coastguard Worker                     attrvalue = Py_None;
856*7c568831SAndroid Build Coastguard Worker                 }
857*7c568831SAndroid Build Coastguard Worker                 PyDict_SetItem(dict, attrname, attrvalue);
858*7c568831SAndroid Build Coastguard Worker 		Py_DECREF(attrname);
859*7c568831SAndroid Build Coastguard Worker 		Py_DECREF(attrvalue);
860*7c568831SAndroid Build Coastguard Worker             }
861*7c568831SAndroid Build Coastguard Worker         }
862*7c568831SAndroid Build Coastguard Worker 
863*7c568831SAndroid Build Coastguard Worker         if (type == 1)
864*7c568831SAndroid Build Coastguard Worker             result = PyObject_CallMethod(handler, (char *) "startElement",
865*7c568831SAndroid Build Coastguard Worker                                          (char *) "sO", name, dict);
866*7c568831SAndroid Build Coastguard Worker         else if (type == 2)
867*7c568831SAndroid Build Coastguard Worker             result = PyObject_CallMethod(handler, (char *) "start",
868*7c568831SAndroid Build Coastguard Worker                                          (char *) "sO", name, dict);
869*7c568831SAndroid Build Coastguard Worker         if (PyErr_Occurred())
870*7c568831SAndroid Build Coastguard Worker             PyErr_Print();
871*7c568831SAndroid Build Coastguard Worker         Py_XDECREF(dict);
872*7c568831SAndroid Build Coastguard Worker         Py_XDECREF(result);
873*7c568831SAndroid Build Coastguard Worker     }
874*7c568831SAndroid Build Coastguard Worker }
875*7c568831SAndroid Build Coastguard Worker 
876*7c568831SAndroid Build Coastguard Worker static void
pythonStartDocument(void * user_data)877*7c568831SAndroid Build Coastguard Worker pythonStartDocument(void *user_data)
878*7c568831SAndroid Build Coastguard Worker {
879*7c568831SAndroid Build Coastguard Worker     PyObject *handler;
880*7c568831SAndroid Build Coastguard Worker     PyObject *result;
881*7c568831SAndroid Build Coastguard Worker 
882*7c568831SAndroid Build Coastguard Worker     handler = (PyObject *) user_data;
883*7c568831SAndroid Build Coastguard Worker     if (PyObject_HasAttrString(handler, (char *) "startDocument")) {
884*7c568831SAndroid Build Coastguard Worker         result =
885*7c568831SAndroid Build Coastguard Worker             PyObject_CallMethod(handler, (char *) "startDocument", NULL);
886*7c568831SAndroid Build Coastguard Worker         if (PyErr_Occurred())
887*7c568831SAndroid Build Coastguard Worker             PyErr_Print();
888*7c568831SAndroid Build Coastguard Worker         Py_XDECREF(result);
889*7c568831SAndroid Build Coastguard Worker     }
890*7c568831SAndroid Build Coastguard Worker }
891*7c568831SAndroid Build Coastguard Worker 
892*7c568831SAndroid Build Coastguard Worker static void
pythonEndDocument(void * user_data)893*7c568831SAndroid Build Coastguard Worker pythonEndDocument(void *user_data)
894*7c568831SAndroid Build Coastguard Worker {
895*7c568831SAndroid Build Coastguard Worker     PyObject *handler;
896*7c568831SAndroid Build Coastguard Worker     PyObject *result;
897*7c568831SAndroid Build Coastguard Worker 
898*7c568831SAndroid Build Coastguard Worker     handler = (PyObject *) user_data;
899*7c568831SAndroid Build Coastguard Worker     if (PyObject_HasAttrString(handler, (char *) "endDocument")) {
900*7c568831SAndroid Build Coastguard Worker         result =
901*7c568831SAndroid Build Coastguard Worker             PyObject_CallMethod(handler, (char *) "endDocument", NULL);
902*7c568831SAndroid Build Coastguard Worker         if (PyErr_Occurred())
903*7c568831SAndroid Build Coastguard Worker             PyErr_Print();
904*7c568831SAndroid Build Coastguard Worker         Py_XDECREF(result);
905*7c568831SAndroid Build Coastguard Worker     }
906*7c568831SAndroid Build Coastguard Worker     /*
907*7c568831SAndroid Build Coastguard Worker      * The reference to the handler is released there
908*7c568831SAndroid Build Coastguard Worker      */
909*7c568831SAndroid Build Coastguard Worker     Py_XDECREF(handler);
910*7c568831SAndroid Build Coastguard Worker }
911*7c568831SAndroid Build Coastguard Worker 
912*7c568831SAndroid Build Coastguard Worker static void
pythonEndElement(void * user_data,const xmlChar * name)913*7c568831SAndroid Build Coastguard Worker pythonEndElement(void *user_data, const xmlChar * name)
914*7c568831SAndroid Build Coastguard Worker {
915*7c568831SAndroid Build Coastguard Worker     PyObject *handler;
916*7c568831SAndroid Build Coastguard Worker     PyObject *result;
917*7c568831SAndroid Build Coastguard Worker 
918*7c568831SAndroid Build Coastguard Worker     handler = (PyObject *) user_data;
919*7c568831SAndroid Build Coastguard Worker     if (PyObject_HasAttrString(handler, (char *) "endElement")) {
920*7c568831SAndroid Build Coastguard Worker         result = PyObject_CallMethod(handler, (char *) "endElement",
921*7c568831SAndroid Build Coastguard Worker                                      (char *) "s", name);
922*7c568831SAndroid Build Coastguard Worker         if (PyErr_Occurred())
923*7c568831SAndroid Build Coastguard Worker             PyErr_Print();
924*7c568831SAndroid Build Coastguard Worker         Py_XDECREF(result);
925*7c568831SAndroid Build Coastguard Worker     } else if (PyObject_HasAttrString(handler, (char *) "end")) {
926*7c568831SAndroid Build Coastguard Worker         result = PyObject_CallMethod(handler, (char *) "end",
927*7c568831SAndroid Build Coastguard Worker                                      (char *) "s", name);
928*7c568831SAndroid Build Coastguard Worker         if (PyErr_Occurred())
929*7c568831SAndroid Build Coastguard Worker             PyErr_Print();
930*7c568831SAndroid Build Coastguard Worker         Py_XDECREF(result);
931*7c568831SAndroid Build Coastguard Worker     }
932*7c568831SAndroid Build Coastguard Worker }
933*7c568831SAndroid Build Coastguard Worker 
934*7c568831SAndroid Build Coastguard Worker static void
pythonReference(void * user_data,const xmlChar * name)935*7c568831SAndroid Build Coastguard Worker pythonReference(void *user_data, const xmlChar * name)
936*7c568831SAndroid Build Coastguard Worker {
937*7c568831SAndroid Build Coastguard Worker     PyObject *handler;
938*7c568831SAndroid Build Coastguard Worker     PyObject *result;
939*7c568831SAndroid Build Coastguard Worker 
940*7c568831SAndroid Build Coastguard Worker     handler = (PyObject *) user_data;
941*7c568831SAndroid Build Coastguard Worker     if (PyObject_HasAttrString(handler, (char *) "reference")) {
942*7c568831SAndroid Build Coastguard Worker         result = PyObject_CallMethod(handler, (char *) "reference",
943*7c568831SAndroid Build Coastguard Worker                                      (char *) "s", name);
944*7c568831SAndroid Build Coastguard Worker         if (PyErr_Occurred())
945*7c568831SAndroid Build Coastguard Worker             PyErr_Print();
946*7c568831SAndroid Build Coastguard Worker         Py_XDECREF(result);
947*7c568831SAndroid Build Coastguard Worker     }
948*7c568831SAndroid Build Coastguard Worker }
949*7c568831SAndroid Build Coastguard Worker 
950*7c568831SAndroid Build Coastguard Worker static void
pythonCharacters(void * user_data,const xmlChar * ch,int len)951*7c568831SAndroid Build Coastguard Worker pythonCharacters(void *user_data, const xmlChar * ch, int len)
952*7c568831SAndroid Build Coastguard Worker {
953*7c568831SAndroid Build Coastguard Worker     PyObject *handler;
954*7c568831SAndroid Build Coastguard Worker     PyObject *result = NULL;
955*7c568831SAndroid Build Coastguard Worker     int type = 0;
956*7c568831SAndroid Build Coastguard Worker 
957*7c568831SAndroid Build Coastguard Worker     handler = (PyObject *) user_data;
958*7c568831SAndroid Build Coastguard Worker     if (PyObject_HasAttrString(handler, (char *) "characters"))
959*7c568831SAndroid Build Coastguard Worker         type = 1;
960*7c568831SAndroid Build Coastguard Worker     else if (PyObject_HasAttrString(handler, (char *) "data"))
961*7c568831SAndroid Build Coastguard Worker         type = 2;
962*7c568831SAndroid Build Coastguard Worker     if (type != 0) {
963*7c568831SAndroid Build Coastguard Worker         if (type == 1)
964*7c568831SAndroid Build Coastguard Worker             result = PyObject_CallMethod(handler, (char *) "characters",
965*7c568831SAndroid Build Coastguard Worker                                          (char *) "s#", ch, (Py_ssize_t)len);
966*7c568831SAndroid Build Coastguard Worker         else if (type == 2)
967*7c568831SAndroid Build Coastguard Worker             result = PyObject_CallMethod(handler, (char *) "data",
968*7c568831SAndroid Build Coastguard Worker                                          (char *) "s#", ch, (Py_ssize_t)len);
969*7c568831SAndroid Build Coastguard Worker         if (PyErr_Occurred())
970*7c568831SAndroid Build Coastguard Worker             PyErr_Print();
971*7c568831SAndroid Build Coastguard Worker         Py_XDECREF(result);
972*7c568831SAndroid Build Coastguard Worker     }
973*7c568831SAndroid Build Coastguard Worker }
974*7c568831SAndroid Build Coastguard Worker 
975*7c568831SAndroid Build Coastguard Worker static void
pythonIgnorableWhitespace(void * user_data,const xmlChar * ch,int len)976*7c568831SAndroid Build Coastguard Worker pythonIgnorableWhitespace(void *user_data, const xmlChar * ch, int len)
977*7c568831SAndroid Build Coastguard Worker {
978*7c568831SAndroid Build Coastguard Worker     PyObject *handler;
979*7c568831SAndroid Build Coastguard Worker     PyObject *result = NULL;
980*7c568831SAndroid Build Coastguard Worker     int type = 0;
981*7c568831SAndroid Build Coastguard Worker 
982*7c568831SAndroid Build Coastguard Worker     handler = (PyObject *) user_data;
983*7c568831SAndroid Build Coastguard Worker     if (PyObject_HasAttrString(handler, (char *) "ignorableWhitespace"))
984*7c568831SAndroid Build Coastguard Worker         type = 1;
985*7c568831SAndroid Build Coastguard Worker     else if (PyObject_HasAttrString(handler, (char *) "data"))
986*7c568831SAndroid Build Coastguard Worker         type = 2;
987*7c568831SAndroid Build Coastguard Worker     if (type != 0) {
988*7c568831SAndroid Build Coastguard Worker         if (type == 1)
989*7c568831SAndroid Build Coastguard Worker             result =
990*7c568831SAndroid Build Coastguard Worker                 PyObject_CallMethod(handler,
991*7c568831SAndroid Build Coastguard Worker                                     (char *) "ignorableWhitespace",
992*7c568831SAndroid Build Coastguard Worker                                     (char *) "s#", ch, (Py_ssize_t)len);
993*7c568831SAndroid Build Coastguard Worker         else if (type == 2)
994*7c568831SAndroid Build Coastguard Worker             result =
995*7c568831SAndroid Build Coastguard Worker                 PyObject_CallMethod(handler, (char *) "data",
996*7c568831SAndroid Build Coastguard Worker                                     (char *) "s#", ch, (Py_ssize_t)len);
997*7c568831SAndroid Build Coastguard Worker         Py_XDECREF(result);
998*7c568831SAndroid Build Coastguard Worker     }
999*7c568831SAndroid Build Coastguard Worker }
1000*7c568831SAndroid Build Coastguard Worker 
1001*7c568831SAndroid Build Coastguard Worker static void
pythonProcessingInstruction(void * user_data,const xmlChar * target,const xmlChar * data)1002*7c568831SAndroid Build Coastguard Worker pythonProcessingInstruction(void *user_data,
1003*7c568831SAndroid Build Coastguard Worker                             const xmlChar * target, const xmlChar * data)
1004*7c568831SAndroid Build Coastguard Worker {
1005*7c568831SAndroid Build Coastguard Worker     PyObject *handler;
1006*7c568831SAndroid Build Coastguard Worker     PyObject *result;
1007*7c568831SAndroid Build Coastguard Worker 
1008*7c568831SAndroid Build Coastguard Worker     handler = (PyObject *) user_data;
1009*7c568831SAndroid Build Coastguard Worker     if (PyObject_HasAttrString(handler, (char *) "processingInstruction")) {
1010*7c568831SAndroid Build Coastguard Worker         result = PyObject_CallMethod(handler, (char *)
1011*7c568831SAndroid Build Coastguard Worker                                      "processingInstruction",
1012*7c568831SAndroid Build Coastguard Worker                                      (char *) "ss", target, data);
1013*7c568831SAndroid Build Coastguard Worker         Py_XDECREF(result);
1014*7c568831SAndroid Build Coastguard Worker     }
1015*7c568831SAndroid Build Coastguard Worker }
1016*7c568831SAndroid Build Coastguard Worker 
1017*7c568831SAndroid Build Coastguard Worker static void
pythonComment(void * user_data,const xmlChar * value)1018*7c568831SAndroid Build Coastguard Worker pythonComment(void *user_data, const xmlChar * value)
1019*7c568831SAndroid Build Coastguard Worker {
1020*7c568831SAndroid Build Coastguard Worker     PyObject *handler;
1021*7c568831SAndroid Build Coastguard Worker     PyObject *result;
1022*7c568831SAndroid Build Coastguard Worker 
1023*7c568831SAndroid Build Coastguard Worker     handler = (PyObject *) user_data;
1024*7c568831SAndroid Build Coastguard Worker     if (PyObject_HasAttrString(handler, (char *) "comment")) {
1025*7c568831SAndroid Build Coastguard Worker         result =
1026*7c568831SAndroid Build Coastguard Worker             PyObject_CallMethod(handler, (char *) "comment", (char *) "s",
1027*7c568831SAndroid Build Coastguard Worker                                 value);
1028*7c568831SAndroid Build Coastguard Worker         if (PyErr_Occurred())
1029*7c568831SAndroid Build Coastguard Worker             PyErr_Print();
1030*7c568831SAndroid Build Coastguard Worker         Py_XDECREF(result);
1031*7c568831SAndroid Build Coastguard Worker     }
1032*7c568831SAndroid Build Coastguard Worker }
1033*7c568831SAndroid Build Coastguard Worker 
1034*7c568831SAndroid Build Coastguard Worker static void
pythonWarning(void * user_data,const char * msg,...)1035*7c568831SAndroid Build Coastguard Worker pythonWarning(void *user_data, const char *msg, ...)
1036*7c568831SAndroid Build Coastguard Worker {
1037*7c568831SAndroid Build Coastguard Worker     PyObject *handler;
1038*7c568831SAndroid Build Coastguard Worker     PyObject *result;
1039*7c568831SAndroid Build Coastguard Worker     va_list args;
1040*7c568831SAndroid Build Coastguard Worker     char buf[1024];
1041*7c568831SAndroid Build Coastguard Worker 
1042*7c568831SAndroid Build Coastguard Worker     handler = (PyObject *) user_data;
1043*7c568831SAndroid Build Coastguard Worker     if (PyObject_HasAttrString(handler, (char *) "warning")) {
1044*7c568831SAndroid Build Coastguard Worker         va_start(args, msg);
1045*7c568831SAndroid Build Coastguard Worker         vsnprintf(buf, 1023, msg, args);
1046*7c568831SAndroid Build Coastguard Worker         va_end(args);
1047*7c568831SAndroid Build Coastguard Worker         buf[1023] = 0;
1048*7c568831SAndroid Build Coastguard Worker         result =
1049*7c568831SAndroid Build Coastguard Worker             PyObject_CallMethod(handler, (char *) "warning", (char *) "s",
1050*7c568831SAndroid Build Coastguard Worker                                 buf);
1051*7c568831SAndroid Build Coastguard Worker         if (PyErr_Occurred())
1052*7c568831SAndroid Build Coastguard Worker             PyErr_Print();
1053*7c568831SAndroid Build Coastguard Worker         Py_XDECREF(result);
1054*7c568831SAndroid Build Coastguard Worker     }
1055*7c568831SAndroid Build Coastguard Worker }
1056*7c568831SAndroid Build Coastguard Worker 
1057*7c568831SAndroid Build Coastguard Worker static void
pythonError(void * user_data,const char * msg,...)1058*7c568831SAndroid Build Coastguard Worker pythonError(void *user_data, const char *msg, ...)
1059*7c568831SAndroid Build Coastguard Worker {
1060*7c568831SAndroid Build Coastguard Worker     PyObject *handler;
1061*7c568831SAndroid Build Coastguard Worker     PyObject *result;
1062*7c568831SAndroid Build Coastguard Worker     va_list args;
1063*7c568831SAndroid Build Coastguard Worker     char buf[1024];
1064*7c568831SAndroid Build Coastguard Worker 
1065*7c568831SAndroid Build Coastguard Worker     handler = (PyObject *) user_data;
1066*7c568831SAndroid Build Coastguard Worker     if (PyObject_HasAttrString(handler, (char *) "error")) {
1067*7c568831SAndroid Build Coastguard Worker         va_start(args, msg);
1068*7c568831SAndroid Build Coastguard Worker         vsnprintf(buf, 1023, msg, args);
1069*7c568831SAndroid Build Coastguard Worker         va_end(args);
1070*7c568831SAndroid Build Coastguard Worker         buf[1023] = 0;
1071*7c568831SAndroid Build Coastguard Worker         result =
1072*7c568831SAndroid Build Coastguard Worker             PyObject_CallMethod(handler, (char *) "error", (char *) "s",
1073*7c568831SAndroid Build Coastguard Worker                                 buf);
1074*7c568831SAndroid Build Coastguard Worker         if (PyErr_Occurred())
1075*7c568831SAndroid Build Coastguard Worker             PyErr_Print();
1076*7c568831SAndroid Build Coastguard Worker         Py_XDECREF(result);
1077*7c568831SAndroid Build Coastguard Worker     }
1078*7c568831SAndroid Build Coastguard Worker }
1079*7c568831SAndroid Build Coastguard Worker 
1080*7c568831SAndroid Build Coastguard Worker static void
pythonFatalError(void * user_data,const char * msg,...)1081*7c568831SAndroid Build Coastguard Worker pythonFatalError(void *user_data, const char *msg, ...)
1082*7c568831SAndroid Build Coastguard Worker {
1083*7c568831SAndroid Build Coastguard Worker     PyObject *handler;
1084*7c568831SAndroid Build Coastguard Worker     PyObject *result;
1085*7c568831SAndroid Build Coastguard Worker     va_list args;
1086*7c568831SAndroid Build Coastguard Worker     char buf[1024];
1087*7c568831SAndroid Build Coastguard Worker 
1088*7c568831SAndroid Build Coastguard Worker     handler = (PyObject *) user_data;
1089*7c568831SAndroid Build Coastguard Worker     if (PyObject_HasAttrString(handler, (char *) "fatalError")) {
1090*7c568831SAndroid Build Coastguard Worker         va_start(args, msg);
1091*7c568831SAndroid Build Coastguard Worker         vsnprintf(buf, 1023, msg, args);
1092*7c568831SAndroid Build Coastguard Worker         va_end(args);
1093*7c568831SAndroid Build Coastguard Worker         buf[1023] = 0;
1094*7c568831SAndroid Build Coastguard Worker         result =
1095*7c568831SAndroid Build Coastguard Worker             PyObject_CallMethod(handler, (char *) "fatalError",
1096*7c568831SAndroid Build Coastguard Worker                                 (char *) "s", buf);
1097*7c568831SAndroid Build Coastguard Worker         if (PyErr_Occurred())
1098*7c568831SAndroid Build Coastguard Worker             PyErr_Print();
1099*7c568831SAndroid Build Coastguard Worker         Py_XDECREF(result);
1100*7c568831SAndroid Build Coastguard Worker     }
1101*7c568831SAndroid Build Coastguard Worker }
1102*7c568831SAndroid Build Coastguard Worker 
1103*7c568831SAndroid Build Coastguard Worker static void
pythonCdataBlock(void * user_data,const xmlChar * ch,int len)1104*7c568831SAndroid Build Coastguard Worker pythonCdataBlock(void *user_data, const xmlChar * ch, int len)
1105*7c568831SAndroid Build Coastguard Worker {
1106*7c568831SAndroid Build Coastguard Worker     PyObject *handler;
1107*7c568831SAndroid Build Coastguard Worker     PyObject *result = NULL;
1108*7c568831SAndroid Build Coastguard Worker     int type = 0;
1109*7c568831SAndroid Build Coastguard Worker 
1110*7c568831SAndroid Build Coastguard Worker     handler = (PyObject *) user_data;
1111*7c568831SAndroid Build Coastguard Worker     if (PyObject_HasAttrString(handler, (char *) "cdataBlock"))
1112*7c568831SAndroid Build Coastguard Worker         type = 1;
1113*7c568831SAndroid Build Coastguard Worker     else if (PyObject_HasAttrString(handler, (char *) "cdata"))
1114*7c568831SAndroid Build Coastguard Worker         type = 2;
1115*7c568831SAndroid Build Coastguard Worker     if (type != 0) {
1116*7c568831SAndroid Build Coastguard Worker         if (type == 1)
1117*7c568831SAndroid Build Coastguard Worker             result =
1118*7c568831SAndroid Build Coastguard Worker                 PyObject_CallMethod(handler, (char *) "cdataBlock",
1119*7c568831SAndroid Build Coastguard Worker                                     (char *) "s#", ch, (Py_ssize_t)len);
1120*7c568831SAndroid Build Coastguard Worker         else if (type == 2)
1121*7c568831SAndroid Build Coastguard Worker             result =
1122*7c568831SAndroid Build Coastguard Worker                 PyObject_CallMethod(handler, (char *) "cdata",
1123*7c568831SAndroid Build Coastguard Worker                                     (char *) "s#", ch, (Py_ssize_t)len);
1124*7c568831SAndroid Build Coastguard Worker         if (PyErr_Occurred())
1125*7c568831SAndroid Build Coastguard Worker             PyErr_Print();
1126*7c568831SAndroid Build Coastguard Worker         Py_XDECREF(result);
1127*7c568831SAndroid Build Coastguard Worker     }
1128*7c568831SAndroid Build Coastguard Worker }
1129*7c568831SAndroid Build Coastguard Worker 
1130*7c568831SAndroid Build Coastguard Worker static void
pythonExternalSubset(void * user_data,const xmlChar * name,const xmlChar * externalID,const xmlChar * systemID)1131*7c568831SAndroid Build Coastguard Worker pythonExternalSubset(void *user_data,
1132*7c568831SAndroid Build Coastguard Worker                      const xmlChar * name,
1133*7c568831SAndroid Build Coastguard Worker                      const xmlChar * externalID, const xmlChar * systemID)
1134*7c568831SAndroid Build Coastguard Worker {
1135*7c568831SAndroid Build Coastguard Worker     PyObject *handler;
1136*7c568831SAndroid Build Coastguard Worker     PyObject *result;
1137*7c568831SAndroid Build Coastguard Worker 
1138*7c568831SAndroid Build Coastguard Worker     handler = (PyObject *) user_data;
1139*7c568831SAndroid Build Coastguard Worker     if (PyObject_HasAttrString(handler, (char *) "externalSubset")) {
1140*7c568831SAndroid Build Coastguard Worker         result =
1141*7c568831SAndroid Build Coastguard Worker             PyObject_CallMethod(handler, (char *) "externalSubset",
1142*7c568831SAndroid Build Coastguard Worker                                 (char *) "sss", name, externalID,
1143*7c568831SAndroid Build Coastguard Worker                                 systemID);
1144*7c568831SAndroid Build Coastguard Worker         Py_XDECREF(result);
1145*7c568831SAndroid Build Coastguard Worker     }
1146*7c568831SAndroid Build Coastguard Worker }
1147*7c568831SAndroid Build Coastguard Worker 
1148*7c568831SAndroid Build Coastguard Worker static void
pythonEntityDecl(void * user_data,const xmlChar * name,int type,const xmlChar * publicId,const xmlChar * systemId,xmlChar * content)1149*7c568831SAndroid Build Coastguard Worker pythonEntityDecl(void *user_data,
1150*7c568831SAndroid Build Coastguard Worker                  const xmlChar * name,
1151*7c568831SAndroid Build Coastguard Worker                  int type,
1152*7c568831SAndroid Build Coastguard Worker                  const xmlChar * publicId,
1153*7c568831SAndroid Build Coastguard Worker                  const xmlChar * systemId, xmlChar * content)
1154*7c568831SAndroid Build Coastguard Worker {
1155*7c568831SAndroid Build Coastguard Worker     PyObject *handler;
1156*7c568831SAndroid Build Coastguard Worker     PyObject *result;
1157*7c568831SAndroid Build Coastguard Worker 
1158*7c568831SAndroid Build Coastguard Worker     handler = (PyObject *) user_data;
1159*7c568831SAndroid Build Coastguard Worker     if (PyObject_HasAttrString(handler, (char *) "entityDecl")) {
1160*7c568831SAndroid Build Coastguard Worker         result = PyObject_CallMethod(handler, (char *) "entityDecl",
1161*7c568831SAndroid Build Coastguard Worker                                      (char *) "sisss", name, type,
1162*7c568831SAndroid Build Coastguard Worker                                      publicId, systemId, content);
1163*7c568831SAndroid Build Coastguard Worker         if (PyErr_Occurred())
1164*7c568831SAndroid Build Coastguard Worker             PyErr_Print();
1165*7c568831SAndroid Build Coastguard Worker         Py_XDECREF(result);
1166*7c568831SAndroid Build Coastguard Worker     }
1167*7c568831SAndroid Build Coastguard Worker }
1168*7c568831SAndroid Build Coastguard Worker 
1169*7c568831SAndroid Build Coastguard Worker 
1170*7c568831SAndroid Build Coastguard Worker 
1171*7c568831SAndroid Build Coastguard Worker static void
1172*7c568831SAndroid Build Coastguard Worker 
pythonNotationDecl(void * user_data,const xmlChar * name,const xmlChar * publicId,const xmlChar * systemId)1173*7c568831SAndroid Build Coastguard Worker pythonNotationDecl(void *user_data,
1174*7c568831SAndroid Build Coastguard Worker                    const xmlChar * name,
1175*7c568831SAndroid Build Coastguard Worker                    const xmlChar * publicId, const xmlChar * systemId)
1176*7c568831SAndroid Build Coastguard Worker {
1177*7c568831SAndroid Build Coastguard Worker     PyObject *handler;
1178*7c568831SAndroid Build Coastguard Worker     PyObject *result;
1179*7c568831SAndroid Build Coastguard Worker 
1180*7c568831SAndroid Build Coastguard Worker     handler = (PyObject *) user_data;
1181*7c568831SAndroid Build Coastguard Worker     if (PyObject_HasAttrString(handler, (char *) "notationDecl")) {
1182*7c568831SAndroid Build Coastguard Worker         result = PyObject_CallMethod(handler, (char *) "notationDecl",
1183*7c568831SAndroid Build Coastguard Worker                                      (char *) "sss", name, publicId,
1184*7c568831SAndroid Build Coastguard Worker                                      systemId);
1185*7c568831SAndroid Build Coastguard Worker         if (PyErr_Occurred())
1186*7c568831SAndroid Build Coastguard Worker             PyErr_Print();
1187*7c568831SAndroid Build Coastguard Worker         Py_XDECREF(result);
1188*7c568831SAndroid Build Coastguard Worker     }
1189*7c568831SAndroid Build Coastguard Worker }
1190*7c568831SAndroid Build Coastguard Worker 
1191*7c568831SAndroid Build Coastguard Worker static void
pythonAttributeDecl(void * user_data,const xmlChar * elem,const xmlChar * name,int type,int def,const xmlChar * defaultValue,xmlEnumerationPtr tree)1192*7c568831SAndroid Build Coastguard Worker pythonAttributeDecl(void *user_data,
1193*7c568831SAndroid Build Coastguard Worker                     const xmlChar * elem,
1194*7c568831SAndroid Build Coastguard Worker                     const xmlChar * name,
1195*7c568831SAndroid Build Coastguard Worker                     int type,
1196*7c568831SAndroid Build Coastguard Worker                     int def,
1197*7c568831SAndroid Build Coastguard Worker                     const xmlChar * defaultValue, xmlEnumerationPtr tree)
1198*7c568831SAndroid Build Coastguard Worker {
1199*7c568831SAndroid Build Coastguard Worker     PyObject *handler;
1200*7c568831SAndroid Build Coastguard Worker     PyObject *nameList;
1201*7c568831SAndroid Build Coastguard Worker     PyObject *newName;
1202*7c568831SAndroid Build Coastguard Worker     xmlEnumerationPtr node;
1203*7c568831SAndroid Build Coastguard Worker     PyObject *result;
1204*7c568831SAndroid Build Coastguard Worker     int count;
1205*7c568831SAndroid Build Coastguard Worker 
1206*7c568831SAndroid Build Coastguard Worker     handler = (PyObject *) user_data;
1207*7c568831SAndroid Build Coastguard Worker     if (PyObject_HasAttrString(handler, (char *) "attributeDecl")) {
1208*7c568831SAndroid Build Coastguard Worker         count = 0;
1209*7c568831SAndroid Build Coastguard Worker         for (node = tree; node != NULL; node = node->next) {
1210*7c568831SAndroid Build Coastguard Worker             count++;
1211*7c568831SAndroid Build Coastguard Worker         }
1212*7c568831SAndroid Build Coastguard Worker         nameList = PyList_New(count);
1213*7c568831SAndroid Build Coastguard Worker         count = 0;
1214*7c568831SAndroid Build Coastguard Worker         for (node = tree; node != NULL; node = node->next) {
1215*7c568831SAndroid Build Coastguard Worker             newName = PY_IMPORT_STRING((char *) node->name);
1216*7c568831SAndroid Build Coastguard Worker             PyList_SetItem(nameList, count, newName);
1217*7c568831SAndroid Build Coastguard Worker 	    Py_DECREF(newName);
1218*7c568831SAndroid Build Coastguard Worker             count++;
1219*7c568831SAndroid Build Coastguard Worker         }
1220*7c568831SAndroid Build Coastguard Worker         result = PyObject_CallMethod(handler, (char *) "attributeDecl",
1221*7c568831SAndroid Build Coastguard Worker                                      (char *) "ssiisO", elem, name, type,
1222*7c568831SAndroid Build Coastguard Worker                                      def, defaultValue, nameList);
1223*7c568831SAndroid Build Coastguard Worker         if (PyErr_Occurred())
1224*7c568831SAndroid Build Coastguard Worker             PyErr_Print();
1225*7c568831SAndroid Build Coastguard Worker         Py_XDECREF(nameList);
1226*7c568831SAndroid Build Coastguard Worker         Py_XDECREF(result);
1227*7c568831SAndroid Build Coastguard Worker     }
1228*7c568831SAndroid Build Coastguard Worker }
1229*7c568831SAndroid Build Coastguard Worker 
1230*7c568831SAndroid Build Coastguard Worker static void
pythonElementDecl(void * user_data,const xmlChar * name,int type,ATTRIBUTE_UNUSED xmlElementContentPtr content)1231*7c568831SAndroid Build Coastguard Worker pythonElementDecl(void *user_data,
1232*7c568831SAndroid Build Coastguard Worker                   const xmlChar * name,
1233*7c568831SAndroid Build Coastguard Worker                   int type, ATTRIBUTE_UNUSED xmlElementContentPtr content)
1234*7c568831SAndroid Build Coastguard Worker {
1235*7c568831SAndroid Build Coastguard Worker     PyObject *handler;
1236*7c568831SAndroid Build Coastguard Worker     PyObject *obj;
1237*7c568831SAndroid Build Coastguard Worker     PyObject *result;
1238*7c568831SAndroid Build Coastguard Worker 
1239*7c568831SAndroid Build Coastguard Worker     handler = (PyObject *) user_data;
1240*7c568831SAndroid Build Coastguard Worker     if (PyObject_HasAttrString(handler, (char *) "elementDecl")) {
1241*7c568831SAndroid Build Coastguard Worker         /* TODO: wrap in an elementContent object */
1242*7c568831SAndroid Build Coastguard Worker         printf
1243*7c568831SAndroid Build Coastguard Worker             ("pythonElementDecl: xmlElementContentPtr wrapper missing !\n");
1244*7c568831SAndroid Build Coastguard Worker         obj = Py_None;
1245*7c568831SAndroid Build Coastguard Worker         /* Py_XINCREF(Py_None); isn't the reference just borrowed ??? */
1246*7c568831SAndroid Build Coastguard Worker         result = PyObject_CallMethod(handler, (char *) "elementDecl",
1247*7c568831SAndroid Build Coastguard Worker                                      (char *) "siO", name, type, obj);
1248*7c568831SAndroid Build Coastguard Worker         if (PyErr_Occurred())
1249*7c568831SAndroid Build Coastguard Worker             PyErr_Print();
1250*7c568831SAndroid Build Coastguard Worker         Py_XDECREF(result);
1251*7c568831SAndroid Build Coastguard Worker     }
1252*7c568831SAndroid Build Coastguard Worker }
1253*7c568831SAndroid Build Coastguard Worker 
1254*7c568831SAndroid Build Coastguard Worker static void
pythonUnparsedEntityDecl(void * user_data,const xmlChar * name,const xmlChar * publicId,const xmlChar * systemId,const xmlChar * notationName)1255*7c568831SAndroid Build Coastguard Worker pythonUnparsedEntityDecl(void *user_data,
1256*7c568831SAndroid Build Coastguard Worker                          const xmlChar * name,
1257*7c568831SAndroid Build Coastguard Worker                          const xmlChar * publicId,
1258*7c568831SAndroid Build Coastguard Worker                          const xmlChar * systemId,
1259*7c568831SAndroid Build Coastguard Worker                          const xmlChar * notationName)
1260*7c568831SAndroid Build Coastguard Worker {
1261*7c568831SAndroid Build Coastguard Worker     PyObject *handler;
1262*7c568831SAndroid Build Coastguard Worker     PyObject *result;
1263*7c568831SAndroid Build Coastguard Worker 
1264*7c568831SAndroid Build Coastguard Worker     handler = (PyObject *) user_data;
1265*7c568831SAndroid Build Coastguard Worker     if (PyObject_HasAttrString(handler, (char *) "unparsedEntityDecl")) {
1266*7c568831SAndroid Build Coastguard Worker         result =
1267*7c568831SAndroid Build Coastguard Worker             PyObject_CallMethod(handler, (char *) "unparsedEntityDecl",
1268*7c568831SAndroid Build Coastguard Worker                                 (char *) "ssss", name, publicId, systemId,
1269*7c568831SAndroid Build Coastguard Worker                                 notationName);
1270*7c568831SAndroid Build Coastguard Worker         if (PyErr_Occurred())
1271*7c568831SAndroid Build Coastguard Worker             PyErr_Print();
1272*7c568831SAndroid Build Coastguard Worker         Py_XDECREF(result);
1273*7c568831SAndroid Build Coastguard Worker     }
1274*7c568831SAndroid Build Coastguard Worker }
1275*7c568831SAndroid Build Coastguard Worker 
1276*7c568831SAndroid Build Coastguard Worker static void
pythonInternalSubset(void * user_data,const xmlChar * name,const xmlChar * ExternalID,const xmlChar * SystemID)1277*7c568831SAndroid Build Coastguard Worker pythonInternalSubset(void *user_data, const xmlChar * name,
1278*7c568831SAndroid Build Coastguard Worker                      const xmlChar * ExternalID, const xmlChar * SystemID)
1279*7c568831SAndroid Build Coastguard Worker {
1280*7c568831SAndroid Build Coastguard Worker     PyObject *handler;
1281*7c568831SAndroid Build Coastguard Worker     PyObject *result;
1282*7c568831SAndroid Build Coastguard Worker 
1283*7c568831SAndroid Build Coastguard Worker     handler = (PyObject *) user_data;
1284*7c568831SAndroid Build Coastguard Worker     if (PyObject_HasAttrString(handler, (char *) "internalSubset")) {
1285*7c568831SAndroid Build Coastguard Worker         result = PyObject_CallMethod(handler, (char *) "internalSubset",
1286*7c568831SAndroid Build Coastguard Worker                                      (char *) "sss", name, ExternalID,
1287*7c568831SAndroid Build Coastguard Worker                                      SystemID);
1288*7c568831SAndroid Build Coastguard Worker         if (PyErr_Occurred())
1289*7c568831SAndroid Build Coastguard Worker             PyErr_Print();
1290*7c568831SAndroid Build Coastguard Worker         Py_XDECREF(result);
1291*7c568831SAndroid Build Coastguard Worker     }
1292*7c568831SAndroid Build Coastguard Worker }
1293*7c568831SAndroid Build Coastguard Worker 
1294*7c568831SAndroid Build Coastguard Worker static xmlSAXHandler pythonSaxHandler = {
1295*7c568831SAndroid Build Coastguard Worker     pythonInternalSubset,
1296*7c568831SAndroid Build Coastguard Worker     NULL,                       /* TODO pythonIsStandalone, */
1297*7c568831SAndroid Build Coastguard Worker     NULL,                       /* TODO pythonHasInternalSubset, */
1298*7c568831SAndroid Build Coastguard Worker     NULL,                       /* TODO pythonHasExternalSubset, */
1299*7c568831SAndroid Build Coastguard Worker     NULL,                       /* TODO pythonResolveEntity, */
1300*7c568831SAndroid Build Coastguard Worker     NULL,                       /* TODO pythonGetEntity, */
1301*7c568831SAndroid Build Coastguard Worker     pythonEntityDecl,
1302*7c568831SAndroid Build Coastguard Worker     pythonNotationDecl,
1303*7c568831SAndroid Build Coastguard Worker     pythonAttributeDecl,
1304*7c568831SAndroid Build Coastguard Worker     pythonElementDecl,
1305*7c568831SAndroid Build Coastguard Worker     pythonUnparsedEntityDecl,
1306*7c568831SAndroid Build Coastguard Worker     NULL,                       /* OBSOLETED pythonSetDocumentLocator, */
1307*7c568831SAndroid Build Coastguard Worker     pythonStartDocument,
1308*7c568831SAndroid Build Coastguard Worker     pythonEndDocument,
1309*7c568831SAndroid Build Coastguard Worker     pythonStartElement,
1310*7c568831SAndroid Build Coastguard Worker     pythonEndElement,
1311*7c568831SAndroid Build Coastguard Worker     pythonReference,
1312*7c568831SAndroid Build Coastguard Worker     pythonCharacters,
1313*7c568831SAndroid Build Coastguard Worker     pythonIgnorableWhitespace,
1314*7c568831SAndroid Build Coastguard Worker     pythonProcessingInstruction,
1315*7c568831SAndroid Build Coastguard Worker     pythonComment,
1316*7c568831SAndroid Build Coastguard Worker     pythonWarning,
1317*7c568831SAndroid Build Coastguard Worker     pythonError,
1318*7c568831SAndroid Build Coastguard Worker     pythonFatalError,
1319*7c568831SAndroid Build Coastguard Worker     NULL,                       /* TODO pythonGetParameterEntity, */
1320*7c568831SAndroid Build Coastguard Worker     pythonCdataBlock,
1321*7c568831SAndroid Build Coastguard Worker     pythonExternalSubset,
1322*7c568831SAndroid Build Coastguard Worker     1,
1323*7c568831SAndroid Build Coastguard Worker     NULL,			/* TODO migrate to SAX2 */
1324*7c568831SAndroid Build Coastguard Worker     NULL,
1325*7c568831SAndroid Build Coastguard Worker     NULL,
1326*7c568831SAndroid Build Coastguard Worker     NULL
1327*7c568831SAndroid Build Coastguard Worker };
1328*7c568831SAndroid Build Coastguard Worker 
1329*7c568831SAndroid Build Coastguard Worker /************************************************************************
1330*7c568831SAndroid Build Coastguard Worker  *									*
1331*7c568831SAndroid Build Coastguard Worker  *		Handling of specific parser context			*
1332*7c568831SAndroid Build Coastguard Worker  *									*
1333*7c568831SAndroid Build Coastguard Worker  ************************************************************************/
1334*7c568831SAndroid Build Coastguard Worker 
1335*7c568831SAndroid Build Coastguard Worker #ifdef LIBXML_PUSH_ENABLED
1336*7c568831SAndroid Build Coastguard Worker PyObject *
libxml_xmlCreatePushParser(ATTRIBUTE_UNUSED PyObject * self,PyObject * args)1337*7c568831SAndroid Build Coastguard Worker libxml_xmlCreatePushParser(ATTRIBUTE_UNUSED PyObject * self,
1338*7c568831SAndroid Build Coastguard Worker                            PyObject * args)
1339*7c568831SAndroid Build Coastguard Worker {
1340*7c568831SAndroid Build Coastguard Worker     const char *chunk;
1341*7c568831SAndroid Build Coastguard Worker     int size;
1342*7c568831SAndroid Build Coastguard Worker     const char *URI;
1343*7c568831SAndroid Build Coastguard Worker     PyObject *pyobj_SAX = NULL;
1344*7c568831SAndroid Build Coastguard Worker     xmlSAXHandlerPtr SAX = NULL;
1345*7c568831SAndroid Build Coastguard Worker     xmlParserCtxtPtr ret;
1346*7c568831SAndroid Build Coastguard Worker     PyObject *pyret;
1347*7c568831SAndroid Build Coastguard Worker 
1348*7c568831SAndroid Build Coastguard Worker     if (!PyArg_ParseTuple
1349*7c568831SAndroid Build Coastguard Worker         (args, (char *) "Oziz:xmlCreatePushParser", &pyobj_SAX, &chunk,
1350*7c568831SAndroid Build Coastguard Worker          &size, &URI))
1351*7c568831SAndroid Build Coastguard Worker         return (NULL);
1352*7c568831SAndroid Build Coastguard Worker 
1353*7c568831SAndroid Build Coastguard Worker     if (pyobj_SAX != Py_None) {
1354*7c568831SAndroid Build Coastguard Worker         SAX = &pythonSaxHandler;
1355*7c568831SAndroid Build Coastguard Worker         Py_INCREF(pyobj_SAX);
1356*7c568831SAndroid Build Coastguard Worker         /* The reference is released in pythonEndDocument() */
1357*7c568831SAndroid Build Coastguard Worker     }
1358*7c568831SAndroid Build Coastguard Worker     ret = xmlCreatePushParserCtxt(SAX, pyobj_SAX, chunk, size, URI);
1359*7c568831SAndroid Build Coastguard Worker     pyret = libxml_xmlParserCtxtPtrWrap(ret);
1360*7c568831SAndroid Build Coastguard Worker     return (pyret);
1361*7c568831SAndroid Build Coastguard Worker }
1362*7c568831SAndroid Build Coastguard Worker 
1363*7c568831SAndroid Build Coastguard Worker #ifdef LIBXML_HTML_ENABLED
1364*7c568831SAndroid Build Coastguard Worker PyObject *
libxml_htmlCreatePushParser(ATTRIBUTE_UNUSED PyObject * self,PyObject * args)1365*7c568831SAndroid Build Coastguard Worker libxml_htmlCreatePushParser(ATTRIBUTE_UNUSED PyObject * self,
1366*7c568831SAndroid Build Coastguard Worker                             PyObject * args)
1367*7c568831SAndroid Build Coastguard Worker {
1368*7c568831SAndroid Build Coastguard Worker     const char *chunk;
1369*7c568831SAndroid Build Coastguard Worker     int size;
1370*7c568831SAndroid Build Coastguard Worker     const char *URI;
1371*7c568831SAndroid Build Coastguard Worker     PyObject *pyobj_SAX = NULL;
1372*7c568831SAndroid Build Coastguard Worker     xmlSAXHandlerPtr SAX = NULL;
1373*7c568831SAndroid Build Coastguard Worker     xmlParserCtxtPtr ret;
1374*7c568831SAndroid Build Coastguard Worker     PyObject *pyret;
1375*7c568831SAndroid Build Coastguard Worker 
1376*7c568831SAndroid Build Coastguard Worker     if (!PyArg_ParseTuple
1377*7c568831SAndroid Build Coastguard Worker         (args, (char *) "Oziz:htmlCreatePushParser", &pyobj_SAX, &chunk,
1378*7c568831SAndroid Build Coastguard Worker          &size, &URI))
1379*7c568831SAndroid Build Coastguard Worker         return (NULL);
1380*7c568831SAndroid Build Coastguard Worker 
1381*7c568831SAndroid Build Coastguard Worker     if (pyobj_SAX != Py_None) {
1382*7c568831SAndroid Build Coastguard Worker         SAX = &pythonSaxHandler;
1383*7c568831SAndroid Build Coastguard Worker         Py_INCREF(pyobj_SAX);
1384*7c568831SAndroid Build Coastguard Worker         /* The reference is released in pythonEndDocument() */
1385*7c568831SAndroid Build Coastguard Worker     }
1386*7c568831SAndroid Build Coastguard Worker     ret = htmlCreatePushParserCtxt(SAX, pyobj_SAX, chunk, size, URI,
1387*7c568831SAndroid Build Coastguard Worker                                    XML_CHAR_ENCODING_NONE);
1388*7c568831SAndroid Build Coastguard Worker     pyret = libxml_xmlParserCtxtPtrWrap(ret);
1389*7c568831SAndroid Build Coastguard Worker     return (pyret);
1390*7c568831SAndroid Build Coastguard Worker }
1391*7c568831SAndroid Build Coastguard Worker #endif /* LIBXML_HTML_ENABLED */
1392*7c568831SAndroid Build Coastguard Worker #endif /* LIBXML_PUSH_ENABLED */
1393*7c568831SAndroid Build Coastguard Worker 
1394*7c568831SAndroid Build Coastguard Worker #ifdef LIBXML_SAX1_ENABLED
1395*7c568831SAndroid Build Coastguard Worker PyObject *
libxml_xmlSAXParseFile(ATTRIBUTE_UNUSED PyObject * self,PyObject * args)1396*7c568831SAndroid Build Coastguard Worker libxml_xmlSAXParseFile(ATTRIBUTE_UNUSED PyObject * self, PyObject * args)
1397*7c568831SAndroid Build Coastguard Worker {
1398*7c568831SAndroid Build Coastguard Worker     int recover;
1399*7c568831SAndroid Build Coastguard Worker     const char *URI;
1400*7c568831SAndroid Build Coastguard Worker     PyObject *pyobj_SAX = NULL;
1401*7c568831SAndroid Build Coastguard Worker     xmlSAXHandlerPtr SAX = NULL;
1402*7c568831SAndroid Build Coastguard Worker     xmlParserCtxtPtr ctxt;
1403*7c568831SAndroid Build Coastguard Worker 
1404*7c568831SAndroid Build Coastguard Worker     if (!PyArg_ParseTuple(args, (char *) "Osi:xmlSAXParseFile", &pyobj_SAX,
1405*7c568831SAndroid Build Coastguard Worker                           &URI, &recover))
1406*7c568831SAndroid Build Coastguard Worker         return (NULL);
1407*7c568831SAndroid Build Coastguard Worker 
1408*7c568831SAndroid Build Coastguard Worker     if (pyobj_SAX == Py_None) {
1409*7c568831SAndroid Build Coastguard Worker         Py_INCREF(Py_None);
1410*7c568831SAndroid Build Coastguard Worker         return (Py_None);
1411*7c568831SAndroid Build Coastguard Worker     }
1412*7c568831SAndroid Build Coastguard Worker     SAX = &pythonSaxHandler;
1413*7c568831SAndroid Build Coastguard Worker     Py_INCREF(pyobj_SAX);
1414*7c568831SAndroid Build Coastguard Worker     /* The reference is released in pythonEndDocument() */
1415*7c568831SAndroid Build Coastguard Worker     ctxt = xmlNewSAXParserCtxt(SAX, pyobj_SAX);
1416*7c568831SAndroid Build Coastguard Worker     xmlCtxtReadFile(ctxt, URI, NULL, 0);
1417*7c568831SAndroid Build Coastguard Worker     xmlFreeParserCtxt(ctxt);
1418*7c568831SAndroid Build Coastguard Worker     Py_INCREF(Py_None);
1419*7c568831SAndroid Build Coastguard Worker     return (Py_None);
1420*7c568831SAndroid Build Coastguard Worker }
1421*7c568831SAndroid Build Coastguard Worker #endif /* LIBXML_SAX1_ENABLED */
1422*7c568831SAndroid Build Coastguard Worker 
1423*7c568831SAndroid Build Coastguard Worker #ifdef LIBXML_HTML_ENABLED
1424*7c568831SAndroid Build Coastguard Worker PyObject *
libxml_htmlSAXParseFile(ATTRIBUTE_UNUSED PyObject * self,PyObject * args)1425*7c568831SAndroid Build Coastguard Worker libxml_htmlSAXParseFile(ATTRIBUTE_UNUSED PyObject * self, PyObject * args)
1426*7c568831SAndroid Build Coastguard Worker {
1427*7c568831SAndroid Build Coastguard Worker     const char *URI;
1428*7c568831SAndroid Build Coastguard Worker     const char *encoding;
1429*7c568831SAndroid Build Coastguard Worker     PyObject *pyobj_SAX = NULL;
1430*7c568831SAndroid Build Coastguard Worker     xmlSAXHandlerPtr SAX = NULL;
1431*7c568831SAndroid Build Coastguard Worker     htmlParserCtxtPtr ctxt;
1432*7c568831SAndroid Build Coastguard Worker 
1433*7c568831SAndroid Build Coastguard Worker     if (!PyArg_ParseTuple
1434*7c568831SAndroid Build Coastguard Worker         (args, (char *) "Osz:htmlSAXParseFile", &pyobj_SAX, &URI,
1435*7c568831SAndroid Build Coastguard Worker          &encoding))
1436*7c568831SAndroid Build Coastguard Worker         return (NULL);
1437*7c568831SAndroid Build Coastguard Worker 
1438*7c568831SAndroid Build Coastguard Worker     if (pyobj_SAX == Py_None) {
1439*7c568831SAndroid Build Coastguard Worker         Py_INCREF(Py_None);
1440*7c568831SAndroid Build Coastguard Worker         return (Py_None);
1441*7c568831SAndroid Build Coastguard Worker     }
1442*7c568831SAndroid Build Coastguard Worker     SAX = &pythonSaxHandler;
1443*7c568831SAndroid Build Coastguard Worker     Py_INCREF(pyobj_SAX);
1444*7c568831SAndroid Build Coastguard Worker     /* The reference is released in pythonEndDocument() */
1445*7c568831SAndroid Build Coastguard Worker     ctxt = htmlNewSAXParserCtxt(SAX, pyobj_SAX);
1446*7c568831SAndroid Build Coastguard Worker     htmlCtxtReadFile(ctxt, URI, encoding, 0);
1447*7c568831SAndroid Build Coastguard Worker     htmlFreeParserCtxt(ctxt);
1448*7c568831SAndroid Build Coastguard Worker     Py_INCREF(Py_None);
1449*7c568831SAndroid Build Coastguard Worker     return (Py_None);
1450*7c568831SAndroid Build Coastguard Worker }
1451*7c568831SAndroid Build Coastguard Worker #endif /* LIBXML_HTML_ENABLED */
1452*7c568831SAndroid Build Coastguard Worker 
1453*7c568831SAndroid Build Coastguard Worker /************************************************************************
1454*7c568831SAndroid Build Coastguard Worker  *									*
1455*7c568831SAndroid Build Coastguard Worker  *			Error message callback				*
1456*7c568831SAndroid Build Coastguard Worker  *									*
1457*7c568831SAndroid Build Coastguard Worker  ************************************************************************/
1458*7c568831SAndroid Build Coastguard Worker 
1459*7c568831SAndroid Build Coastguard Worker static PyObject *libxml_xmlPythonErrorFuncHandler = NULL;
1460*7c568831SAndroid Build Coastguard Worker static PyObject *libxml_xmlPythonErrorFuncCtxt = NULL;
1461*7c568831SAndroid Build Coastguard Worker 
1462*7c568831SAndroid Build Coastguard Worker /* helper to build a xmlMalloc'ed string from a format and va_list */
1463*7c568831SAndroid Build Coastguard Worker /*
1464*7c568831SAndroid Build Coastguard Worker  * disabled the loop, the repeated call to vsnprintf without reset of ap
1465*7c568831SAndroid Build Coastguard Worker  * in case the initial buffer was too small segfaulted on x86_64
1466*7c568831SAndroid Build Coastguard Worker  * we now directly vsnprintf on a large buffer.
1467*7c568831SAndroid Build Coastguard Worker  */
1468*7c568831SAndroid Build Coastguard Worker static char *
libxml_buildMessage(const char * msg,va_list ap)1469*7c568831SAndroid Build Coastguard Worker libxml_buildMessage(const char *msg, va_list ap)
1470*7c568831SAndroid Build Coastguard Worker {
1471*7c568831SAndroid Build Coastguard Worker     int chars;
1472*7c568831SAndroid Build Coastguard Worker     char *str;
1473*7c568831SAndroid Build Coastguard Worker 
1474*7c568831SAndroid Build Coastguard Worker     str = (char *) xmlMalloc(1000);
1475*7c568831SAndroid Build Coastguard Worker     if (str == NULL)
1476*7c568831SAndroid Build Coastguard Worker         return NULL;
1477*7c568831SAndroid Build Coastguard Worker 
1478*7c568831SAndroid Build Coastguard Worker     chars = vsnprintf(str, 999, msg, ap);
1479*7c568831SAndroid Build Coastguard Worker     if (chars >= 998)
1480*7c568831SAndroid Build Coastguard Worker         str[999] = 0;
1481*7c568831SAndroid Build Coastguard Worker 
1482*7c568831SAndroid Build Coastguard Worker     return str;
1483*7c568831SAndroid Build Coastguard Worker }
1484*7c568831SAndroid Build Coastguard Worker 
1485*7c568831SAndroid Build Coastguard Worker static void
libxml_xmlErrorFuncHandler(ATTRIBUTE_UNUSED void * ctx,const char * msg,...)1486*7c568831SAndroid Build Coastguard Worker libxml_xmlErrorFuncHandler(ATTRIBUTE_UNUSED void *ctx, const char *msg,
1487*7c568831SAndroid Build Coastguard Worker                            ...)
1488*7c568831SAndroid Build Coastguard Worker {
1489*7c568831SAndroid Build Coastguard Worker     va_list ap;
1490*7c568831SAndroid Build Coastguard Worker     PyObject *list;
1491*7c568831SAndroid Build Coastguard Worker     PyObject *message;
1492*7c568831SAndroid Build Coastguard Worker     PyObject *result;
1493*7c568831SAndroid Build Coastguard Worker     char str[1000];
1494*7c568831SAndroid Build Coastguard Worker 
1495*7c568831SAndroid Build Coastguard Worker     if (libxml_xmlPythonErrorFuncHandler == NULL) {
1496*7c568831SAndroid Build Coastguard Worker         va_start(ap, msg);
1497*7c568831SAndroid Build Coastguard Worker         vfprintf(stderr, msg, ap);
1498*7c568831SAndroid Build Coastguard Worker         va_end(ap);
1499*7c568831SAndroid Build Coastguard Worker     } else {
1500*7c568831SAndroid Build Coastguard Worker         va_start(ap, msg);
1501*7c568831SAndroid Build Coastguard Worker         if (vsnprintf(str, 999, msg, ap) >= 998)
1502*7c568831SAndroid Build Coastguard Worker 	    str[999] = 0;
1503*7c568831SAndroid Build Coastguard Worker         va_end(ap);
1504*7c568831SAndroid Build Coastguard Worker 
1505*7c568831SAndroid Build Coastguard Worker         list = PyTuple_New(2);
1506*7c568831SAndroid Build Coastguard Worker         PyTuple_SetItem(list, 0, libxml_xmlPythonErrorFuncCtxt);
1507*7c568831SAndroid Build Coastguard Worker         Py_XINCREF(libxml_xmlPythonErrorFuncCtxt);
1508*7c568831SAndroid Build Coastguard Worker         message = libxml_charPtrConstWrap(str);
1509*7c568831SAndroid Build Coastguard Worker         PyTuple_SetItem(list, 1, message);
1510*7c568831SAndroid Build Coastguard Worker         result = PyObject_CallObject(libxml_xmlPythonErrorFuncHandler, list);
1511*7c568831SAndroid Build Coastguard Worker         Py_XDECREF(list);
1512*7c568831SAndroid Build Coastguard Worker         Py_XDECREF(result);
1513*7c568831SAndroid Build Coastguard Worker     }
1514*7c568831SAndroid Build Coastguard Worker }
1515*7c568831SAndroid Build Coastguard Worker 
1516*7c568831SAndroid Build Coastguard Worker static void
libxml_xmlErrorInitialize(void)1517*7c568831SAndroid Build Coastguard Worker libxml_xmlErrorInitialize(void)
1518*7c568831SAndroid Build Coastguard Worker {
1519*7c568831SAndroid Build Coastguard Worker     xmlSetGenericErrorFunc(NULL, libxml_xmlErrorFuncHandler);
1520*7c568831SAndroid Build Coastguard Worker XML_IGNORE_DEPRECATION_WARNINGS
1521*7c568831SAndroid Build Coastguard Worker     xmlThrDefSetGenericErrorFunc(NULL, libxml_xmlErrorFuncHandler);
1522*7c568831SAndroid Build Coastguard Worker XML_POP_WARNINGS
1523*7c568831SAndroid Build Coastguard Worker }
1524*7c568831SAndroid Build Coastguard Worker 
1525*7c568831SAndroid Build Coastguard Worker static PyObject *
libxml_xmlRegisterErrorHandler(ATTRIBUTE_UNUSED PyObject * self,PyObject * args)1526*7c568831SAndroid Build Coastguard Worker libxml_xmlRegisterErrorHandler(ATTRIBUTE_UNUSED PyObject * self,
1527*7c568831SAndroid Build Coastguard Worker                                PyObject * args)
1528*7c568831SAndroid Build Coastguard Worker {
1529*7c568831SAndroid Build Coastguard Worker     PyObject *py_retval;
1530*7c568831SAndroid Build Coastguard Worker     PyObject *pyobj_f;
1531*7c568831SAndroid Build Coastguard Worker     PyObject *pyobj_ctx;
1532*7c568831SAndroid Build Coastguard Worker 
1533*7c568831SAndroid Build Coastguard Worker     if (!PyArg_ParseTuple
1534*7c568831SAndroid Build Coastguard Worker         (args, (char *) "OO:xmlRegisterErrorHandler", &pyobj_f,
1535*7c568831SAndroid Build Coastguard Worker          &pyobj_ctx))
1536*7c568831SAndroid Build Coastguard Worker         return (NULL);
1537*7c568831SAndroid Build Coastguard Worker 
1538*7c568831SAndroid Build Coastguard Worker     if (libxml_xmlPythonErrorFuncHandler != NULL) {
1539*7c568831SAndroid Build Coastguard Worker         Py_XDECREF(libxml_xmlPythonErrorFuncHandler);
1540*7c568831SAndroid Build Coastguard Worker     }
1541*7c568831SAndroid Build Coastguard Worker     if (libxml_xmlPythonErrorFuncCtxt != NULL) {
1542*7c568831SAndroid Build Coastguard Worker         Py_XDECREF(libxml_xmlPythonErrorFuncCtxt);
1543*7c568831SAndroid Build Coastguard Worker     }
1544*7c568831SAndroid Build Coastguard Worker 
1545*7c568831SAndroid Build Coastguard Worker     Py_XINCREF(pyobj_ctx);
1546*7c568831SAndroid Build Coastguard Worker     Py_XINCREF(pyobj_f);
1547*7c568831SAndroid Build Coastguard Worker 
1548*7c568831SAndroid Build Coastguard Worker     /* TODO: check f is a function ! */
1549*7c568831SAndroid Build Coastguard Worker     libxml_xmlPythonErrorFuncHandler = pyobj_f;
1550*7c568831SAndroid Build Coastguard Worker     libxml_xmlPythonErrorFuncCtxt = pyobj_ctx;
1551*7c568831SAndroid Build Coastguard Worker 
1552*7c568831SAndroid Build Coastguard Worker     py_retval = libxml_intWrap(1);
1553*7c568831SAndroid Build Coastguard Worker     return (py_retval);
1554*7c568831SAndroid Build Coastguard Worker }
1555*7c568831SAndroid Build Coastguard Worker 
1556*7c568831SAndroid Build Coastguard Worker 
1557*7c568831SAndroid Build Coastguard Worker /************************************************************************
1558*7c568831SAndroid Build Coastguard Worker  *									*
1559*7c568831SAndroid Build Coastguard Worker  *                      Per parserCtxt error handler                    *
1560*7c568831SAndroid Build Coastguard Worker  *									*
1561*7c568831SAndroid Build Coastguard Worker  ************************************************************************/
1562*7c568831SAndroid Build Coastguard Worker 
1563*7c568831SAndroid Build Coastguard Worker typedef struct
1564*7c568831SAndroid Build Coastguard Worker {
1565*7c568831SAndroid Build Coastguard Worker     PyObject *f;
1566*7c568831SAndroid Build Coastguard Worker     PyObject *arg;
1567*7c568831SAndroid Build Coastguard Worker } xmlParserCtxtPyCtxt;
1568*7c568831SAndroid Build Coastguard Worker typedef xmlParserCtxtPyCtxt *xmlParserCtxtPyCtxtPtr;
1569*7c568831SAndroid Build Coastguard Worker 
1570*7c568831SAndroid Build Coastguard Worker static void
libxml_xmlParserCtxtErrorHandler(void * ctx,const xmlError * error)1571*7c568831SAndroid Build Coastguard Worker libxml_xmlParserCtxtErrorHandler(void *ctx, const xmlError *error)
1572*7c568831SAndroid Build Coastguard Worker {
1573*7c568831SAndroid Build Coastguard Worker     PyObject *list;
1574*7c568831SAndroid Build Coastguard Worker     PyObject *result;
1575*7c568831SAndroid Build Coastguard Worker     xmlParserCtxtPtr ctxt;
1576*7c568831SAndroid Build Coastguard Worker     xmlParserCtxtPyCtxtPtr pyCtxt;
1577*7c568831SAndroid Build Coastguard Worker     int severity;
1578*7c568831SAndroid Build Coastguard Worker 
1579*7c568831SAndroid Build Coastguard Worker     ctxt = (xmlParserCtxtPtr)ctx;
1580*7c568831SAndroid Build Coastguard Worker     pyCtxt = (xmlParserCtxtPyCtxtPtr)ctxt->_private;
1581*7c568831SAndroid Build Coastguard Worker 
1582*7c568831SAndroid Build Coastguard Worker     if ((error->domain == XML_FROM_VALID) ||
1583*7c568831SAndroid Build Coastguard Worker         (error->domain == XML_FROM_DTD)) {
1584*7c568831SAndroid Build Coastguard Worker         if (error->level == XML_ERR_WARNING)
1585*7c568831SAndroid Build Coastguard Worker             severity = XML_PARSER_SEVERITY_VALIDITY_WARNING;
1586*7c568831SAndroid Build Coastguard Worker         else
1587*7c568831SAndroid Build Coastguard Worker             severity = XML_PARSER_SEVERITY_VALIDITY_ERROR;
1588*7c568831SAndroid Build Coastguard Worker     } else {
1589*7c568831SAndroid Build Coastguard Worker         if (error->level == XML_ERR_WARNING)
1590*7c568831SAndroid Build Coastguard Worker             severity = XML_PARSER_SEVERITY_WARNING;
1591*7c568831SAndroid Build Coastguard Worker         else
1592*7c568831SAndroid Build Coastguard Worker             severity = XML_PARSER_SEVERITY_ERROR;
1593*7c568831SAndroid Build Coastguard Worker     }
1594*7c568831SAndroid Build Coastguard Worker 
1595*7c568831SAndroid Build Coastguard Worker     list = PyTuple_New(4);
1596*7c568831SAndroid Build Coastguard Worker     PyTuple_SetItem(list, 0, pyCtxt->arg);
1597*7c568831SAndroid Build Coastguard Worker     Py_XINCREF(pyCtxt->arg);
1598*7c568831SAndroid Build Coastguard Worker     PyTuple_SetItem(list, 1, libxml_constcharPtrWrap(error->message));
1599*7c568831SAndroid Build Coastguard Worker     PyTuple_SetItem(list, 2, libxml_intWrap(severity));
1600*7c568831SAndroid Build Coastguard Worker     PyTuple_SetItem(list, 3, Py_None);
1601*7c568831SAndroid Build Coastguard Worker     Py_INCREF(Py_None);
1602*7c568831SAndroid Build Coastguard Worker     result = PyObject_CallObject(pyCtxt->f, list);
1603*7c568831SAndroid Build Coastguard Worker     if (result == NULL)
1604*7c568831SAndroid Build Coastguard Worker     {
1605*7c568831SAndroid Build Coastguard Worker 	/* TODO: manage for the exception to be propagated... */
1606*7c568831SAndroid Build Coastguard Worker 	PyErr_Print();
1607*7c568831SAndroid Build Coastguard Worker     }
1608*7c568831SAndroid Build Coastguard Worker     Py_XDECREF(list);
1609*7c568831SAndroid Build Coastguard Worker     Py_XDECREF(result);
1610*7c568831SAndroid Build Coastguard Worker }
1611*7c568831SAndroid Build Coastguard Worker 
1612*7c568831SAndroid Build Coastguard Worker static PyObject *
libxml_xmlParserCtxtSetErrorHandler(ATTRIBUTE_UNUSED PyObject * self,PyObject * args)1613*7c568831SAndroid Build Coastguard Worker libxml_xmlParserCtxtSetErrorHandler(ATTRIBUTE_UNUSED PyObject *self, PyObject *args)
1614*7c568831SAndroid Build Coastguard Worker {
1615*7c568831SAndroid Build Coastguard Worker     PyObject *py_retval;
1616*7c568831SAndroid Build Coastguard Worker     xmlParserCtxtPtr ctxt;
1617*7c568831SAndroid Build Coastguard Worker     xmlParserCtxtPyCtxtPtr pyCtxt;
1618*7c568831SAndroid Build Coastguard Worker     PyObject *pyobj_ctxt;
1619*7c568831SAndroid Build Coastguard Worker     PyObject *pyobj_f;
1620*7c568831SAndroid Build Coastguard Worker     PyObject *pyobj_arg;
1621*7c568831SAndroid Build Coastguard Worker 
1622*7c568831SAndroid Build Coastguard Worker     if (!PyArg_ParseTuple(args, (char *)"OOO:xmlParserCtxtSetErrorHandler",
1623*7c568831SAndroid Build Coastguard Worker 		          &pyobj_ctxt, &pyobj_f, &pyobj_arg))
1624*7c568831SAndroid Build Coastguard Worker         return(NULL);
1625*7c568831SAndroid Build Coastguard Worker     ctxt = (xmlParserCtxtPtr) PyparserCtxt_Get(pyobj_ctxt);
1626*7c568831SAndroid Build Coastguard Worker     if (ctxt->_private == NULL) {
1627*7c568831SAndroid Build Coastguard Worker 	pyCtxt = xmlMalloc(sizeof(xmlParserCtxtPyCtxt));
1628*7c568831SAndroid Build Coastguard Worker 	if (pyCtxt == NULL) {
1629*7c568831SAndroid Build Coastguard Worker 	    py_retval = libxml_intWrap(-1);
1630*7c568831SAndroid Build Coastguard Worker 	    return(py_retval);
1631*7c568831SAndroid Build Coastguard Worker 	}
1632*7c568831SAndroid Build Coastguard Worker 	memset(pyCtxt,0,sizeof(xmlParserCtxtPyCtxt));
1633*7c568831SAndroid Build Coastguard Worker 	ctxt->_private = pyCtxt;
1634*7c568831SAndroid Build Coastguard Worker     }
1635*7c568831SAndroid Build Coastguard Worker     else {
1636*7c568831SAndroid Build Coastguard Worker 	pyCtxt = (xmlParserCtxtPyCtxtPtr)ctxt->_private;
1637*7c568831SAndroid Build Coastguard Worker     }
1638*7c568831SAndroid Build Coastguard Worker     /* TODO: check f is a function ! */
1639*7c568831SAndroid Build Coastguard Worker     Py_XDECREF(pyCtxt->f);
1640*7c568831SAndroid Build Coastguard Worker     Py_XINCREF(pyobj_f);
1641*7c568831SAndroid Build Coastguard Worker     pyCtxt->f = pyobj_f;
1642*7c568831SAndroid Build Coastguard Worker     Py_XDECREF(pyCtxt->arg);
1643*7c568831SAndroid Build Coastguard Worker     Py_XINCREF(pyobj_arg);
1644*7c568831SAndroid Build Coastguard Worker     pyCtxt->arg = pyobj_arg;
1645*7c568831SAndroid Build Coastguard Worker 
1646*7c568831SAndroid Build Coastguard Worker     if (pyobj_f != Py_None) {
1647*7c568831SAndroid Build Coastguard Worker         xmlCtxtSetErrorHandler(ctxt, libxml_xmlParserCtxtErrorHandler, ctxt);
1648*7c568831SAndroid Build Coastguard Worker     }
1649*7c568831SAndroid Build Coastguard Worker     else {
1650*7c568831SAndroid Build Coastguard Worker         xmlCtxtSetErrorHandler(ctxt, NULL, NULL);
1651*7c568831SAndroid Build Coastguard Worker     }
1652*7c568831SAndroid Build Coastguard Worker 
1653*7c568831SAndroid Build Coastguard Worker     py_retval = libxml_intWrap(1);
1654*7c568831SAndroid Build Coastguard Worker     return(py_retval);
1655*7c568831SAndroid Build Coastguard Worker }
1656*7c568831SAndroid Build Coastguard Worker 
1657*7c568831SAndroid Build Coastguard Worker static PyObject *
libxml_xmlParserCtxtGetErrorHandler(ATTRIBUTE_UNUSED PyObject * self,PyObject * args)1658*7c568831SAndroid Build Coastguard Worker libxml_xmlParserCtxtGetErrorHandler(ATTRIBUTE_UNUSED PyObject *self, PyObject *args)
1659*7c568831SAndroid Build Coastguard Worker {
1660*7c568831SAndroid Build Coastguard Worker     PyObject *py_retval;
1661*7c568831SAndroid Build Coastguard Worker     xmlParserCtxtPtr ctxt;
1662*7c568831SAndroid Build Coastguard Worker     xmlParserCtxtPyCtxtPtr pyCtxt;
1663*7c568831SAndroid Build Coastguard Worker     PyObject *pyobj_ctxt;
1664*7c568831SAndroid Build Coastguard Worker 
1665*7c568831SAndroid Build Coastguard Worker     if (!PyArg_ParseTuple(args, (char *)"O:xmlParserCtxtGetErrorHandler",
1666*7c568831SAndroid Build Coastguard Worker 		          &pyobj_ctxt))
1667*7c568831SAndroid Build Coastguard Worker         return(NULL);
1668*7c568831SAndroid Build Coastguard Worker     ctxt = (xmlParserCtxtPtr) PyparserCtxt_Get(pyobj_ctxt);
1669*7c568831SAndroid Build Coastguard Worker     py_retval = PyTuple_New(2);
1670*7c568831SAndroid Build Coastguard Worker     if (ctxt->_private != NULL) {
1671*7c568831SAndroid Build Coastguard Worker 	pyCtxt = (xmlParserCtxtPyCtxtPtr)ctxt->_private;
1672*7c568831SAndroid Build Coastguard Worker 
1673*7c568831SAndroid Build Coastguard Worker 	PyTuple_SetItem(py_retval, 0, pyCtxt->f);
1674*7c568831SAndroid Build Coastguard Worker 	Py_XINCREF(pyCtxt->f);
1675*7c568831SAndroid Build Coastguard Worker 	PyTuple_SetItem(py_retval, 1, pyCtxt->arg);
1676*7c568831SAndroid Build Coastguard Worker 	Py_XINCREF(pyCtxt->arg);
1677*7c568831SAndroid Build Coastguard Worker     }
1678*7c568831SAndroid Build Coastguard Worker     else {
1679*7c568831SAndroid Build Coastguard Worker 	/* no python error handler registered */
1680*7c568831SAndroid Build Coastguard Worker 	PyTuple_SetItem(py_retval, 0, Py_None);
1681*7c568831SAndroid Build Coastguard Worker 	Py_XINCREF(Py_None);
1682*7c568831SAndroid Build Coastguard Worker 	PyTuple_SetItem(py_retval, 1, Py_None);
1683*7c568831SAndroid Build Coastguard Worker 	Py_XINCREF(Py_None);
1684*7c568831SAndroid Build Coastguard Worker     }
1685*7c568831SAndroid Build Coastguard Worker     return(py_retval);
1686*7c568831SAndroid Build Coastguard Worker }
1687*7c568831SAndroid Build Coastguard Worker 
1688*7c568831SAndroid Build Coastguard Worker static PyObject *
libxml_xmlFreeParserCtxt(ATTRIBUTE_UNUSED PyObject * self,PyObject * args)1689*7c568831SAndroid Build Coastguard Worker libxml_xmlFreeParserCtxt(ATTRIBUTE_UNUSED PyObject *self, PyObject *args) {
1690*7c568831SAndroid Build Coastguard Worker     xmlParserCtxtPtr ctxt;
1691*7c568831SAndroid Build Coastguard Worker     PyObject *pyobj_ctxt;
1692*7c568831SAndroid Build Coastguard Worker     xmlParserCtxtPyCtxtPtr pyCtxt;
1693*7c568831SAndroid Build Coastguard Worker 
1694*7c568831SAndroid Build Coastguard Worker     if (!PyArg_ParseTuple(args, (char *)"O:xmlFreeParserCtxt", &pyobj_ctxt))
1695*7c568831SAndroid Build Coastguard Worker         return(NULL);
1696*7c568831SAndroid Build Coastguard Worker     ctxt = (xmlParserCtxtPtr) PyparserCtxt_Get(pyobj_ctxt);
1697*7c568831SAndroid Build Coastguard Worker 
1698*7c568831SAndroid Build Coastguard Worker     if (ctxt != NULL) {
1699*7c568831SAndroid Build Coastguard Worker 	pyCtxt = (xmlParserCtxtPyCtxtPtr)((xmlParserCtxtPtr)ctxt)->_private;
1700*7c568831SAndroid Build Coastguard Worker 	if (pyCtxt) {
1701*7c568831SAndroid Build Coastguard Worker 	    Py_XDECREF(pyCtxt->f);
1702*7c568831SAndroid Build Coastguard Worker 	    Py_XDECREF(pyCtxt->arg);
1703*7c568831SAndroid Build Coastguard Worker 	    xmlFree(pyCtxt);
1704*7c568831SAndroid Build Coastguard Worker 	}
1705*7c568831SAndroid Build Coastguard Worker 	xmlFreeParserCtxt(ctxt);
1706*7c568831SAndroid Build Coastguard Worker     }
1707*7c568831SAndroid Build Coastguard Worker 
1708*7c568831SAndroid Build Coastguard Worker     Py_INCREF(Py_None);
1709*7c568831SAndroid Build Coastguard Worker     return(Py_None);
1710*7c568831SAndroid Build Coastguard Worker }
1711*7c568831SAndroid Build Coastguard Worker 
1712*7c568831SAndroid Build Coastguard Worker #ifdef LIBXML_VALID_ENABLED
1713*7c568831SAndroid Build Coastguard Worker /***
1714*7c568831SAndroid Build Coastguard Worker  * xmlValidCtxt stuff
1715*7c568831SAndroid Build Coastguard Worker  */
1716*7c568831SAndroid Build Coastguard Worker 
1717*7c568831SAndroid Build Coastguard Worker typedef struct
1718*7c568831SAndroid Build Coastguard Worker {
1719*7c568831SAndroid Build Coastguard Worker     PyObject *warn;
1720*7c568831SAndroid Build Coastguard Worker     PyObject *error;
1721*7c568831SAndroid Build Coastguard Worker     PyObject *arg;
1722*7c568831SAndroid Build Coastguard Worker } xmlValidCtxtPyCtxt;
1723*7c568831SAndroid Build Coastguard Worker typedef xmlValidCtxtPyCtxt *xmlValidCtxtPyCtxtPtr;
1724*7c568831SAndroid Build Coastguard Worker 
1725*7c568831SAndroid Build Coastguard Worker static void
libxml_xmlValidCtxtGenericErrorFuncHandler(void * ctx,ATTRIBUTE_UNUSED int severity,char * str)1726*7c568831SAndroid Build Coastguard Worker libxml_xmlValidCtxtGenericErrorFuncHandler(void *ctx, ATTRIBUTE_UNUSED int severity, char *str)
1727*7c568831SAndroid Build Coastguard Worker {
1728*7c568831SAndroid Build Coastguard Worker     PyObject *list;
1729*7c568831SAndroid Build Coastguard Worker     PyObject *result;
1730*7c568831SAndroid Build Coastguard Worker     xmlValidCtxtPyCtxtPtr pyCtxt;
1731*7c568831SAndroid Build Coastguard Worker 
1732*7c568831SAndroid Build Coastguard Worker     pyCtxt = (xmlValidCtxtPyCtxtPtr)ctx;
1733*7c568831SAndroid Build Coastguard Worker 
1734*7c568831SAndroid Build Coastguard Worker     list = PyTuple_New(2);
1735*7c568831SAndroid Build Coastguard Worker     PyTuple_SetItem(list, 0, libxml_charPtrWrap(str));
1736*7c568831SAndroid Build Coastguard Worker     PyTuple_SetItem(list, 1, pyCtxt->arg);
1737*7c568831SAndroid Build Coastguard Worker     Py_XINCREF(pyCtxt->arg);
1738*7c568831SAndroid Build Coastguard Worker     result = PyObject_CallObject(pyCtxt->error, list);
1739*7c568831SAndroid Build Coastguard Worker     if (result == NULL)
1740*7c568831SAndroid Build Coastguard Worker     {
1741*7c568831SAndroid Build Coastguard Worker 	/* TODO: manage for the exception to be propagated... */
1742*7c568831SAndroid Build Coastguard Worker 	PyErr_Print();
1743*7c568831SAndroid Build Coastguard Worker     }
1744*7c568831SAndroid Build Coastguard Worker     Py_XDECREF(list);
1745*7c568831SAndroid Build Coastguard Worker     Py_XDECREF(result);
1746*7c568831SAndroid Build Coastguard Worker }
1747*7c568831SAndroid Build Coastguard Worker 
1748*7c568831SAndroid Build Coastguard Worker static void
libxml_xmlValidCtxtGenericWarningFuncHandler(void * ctx,ATTRIBUTE_UNUSED int severity,char * str)1749*7c568831SAndroid Build Coastguard Worker libxml_xmlValidCtxtGenericWarningFuncHandler(void *ctx, ATTRIBUTE_UNUSED int severity, char *str)
1750*7c568831SAndroid Build Coastguard Worker {
1751*7c568831SAndroid Build Coastguard Worker     PyObject *list;
1752*7c568831SAndroid Build Coastguard Worker     PyObject *result;
1753*7c568831SAndroid Build Coastguard Worker     xmlValidCtxtPyCtxtPtr pyCtxt;
1754*7c568831SAndroid Build Coastguard Worker 
1755*7c568831SAndroid Build Coastguard Worker     pyCtxt = (xmlValidCtxtPyCtxtPtr)ctx;
1756*7c568831SAndroid Build Coastguard Worker 
1757*7c568831SAndroid Build Coastguard Worker     list = PyTuple_New(2);
1758*7c568831SAndroid Build Coastguard Worker     PyTuple_SetItem(list, 0, libxml_charPtrWrap(str));
1759*7c568831SAndroid Build Coastguard Worker     PyTuple_SetItem(list, 1, pyCtxt->arg);
1760*7c568831SAndroid Build Coastguard Worker     Py_XINCREF(pyCtxt->arg);
1761*7c568831SAndroid Build Coastguard Worker     result = PyObject_CallObject(pyCtxt->warn, list);
1762*7c568831SAndroid Build Coastguard Worker     if (result == NULL)
1763*7c568831SAndroid Build Coastguard Worker     {
1764*7c568831SAndroid Build Coastguard Worker 	/* TODO: manage for the exception to be propagated... */
1765*7c568831SAndroid Build Coastguard Worker 	PyErr_Print();
1766*7c568831SAndroid Build Coastguard Worker     }
1767*7c568831SAndroid Build Coastguard Worker     Py_XDECREF(list);
1768*7c568831SAndroid Build Coastguard Worker     Py_XDECREF(result);
1769*7c568831SAndroid Build Coastguard Worker }
1770*7c568831SAndroid Build Coastguard Worker 
1771*7c568831SAndroid Build Coastguard Worker static void
libxml_xmlValidCtxtErrorFuncHandler(void * ctx,const char * msg,...)1772*7c568831SAndroid Build Coastguard Worker libxml_xmlValidCtxtErrorFuncHandler(void *ctx, const char *msg, ...)
1773*7c568831SAndroid Build Coastguard Worker {
1774*7c568831SAndroid Build Coastguard Worker     va_list ap;
1775*7c568831SAndroid Build Coastguard Worker 
1776*7c568831SAndroid Build Coastguard Worker     va_start(ap, msg);
1777*7c568831SAndroid Build Coastguard Worker     libxml_xmlValidCtxtGenericErrorFuncHandler(ctx,XML_PARSER_SEVERITY_VALIDITY_ERROR,libxml_buildMessage(msg,ap));
1778*7c568831SAndroid Build Coastguard Worker     va_end(ap);
1779*7c568831SAndroid Build Coastguard Worker }
1780*7c568831SAndroid Build Coastguard Worker 
1781*7c568831SAndroid Build Coastguard Worker static void
libxml_xmlValidCtxtWarningFuncHandler(void * ctx,const char * msg,...)1782*7c568831SAndroid Build Coastguard Worker libxml_xmlValidCtxtWarningFuncHandler(void *ctx, const char *msg, ...)
1783*7c568831SAndroid Build Coastguard Worker {
1784*7c568831SAndroid Build Coastguard Worker     va_list ap;
1785*7c568831SAndroid Build Coastguard Worker 
1786*7c568831SAndroid Build Coastguard Worker     va_start(ap, msg);
1787*7c568831SAndroid Build Coastguard Worker     libxml_xmlValidCtxtGenericWarningFuncHandler(ctx,XML_PARSER_SEVERITY_VALIDITY_WARNING,libxml_buildMessage(msg,ap));
1788*7c568831SAndroid Build Coastguard Worker     va_end(ap);
1789*7c568831SAndroid Build Coastguard Worker }
1790*7c568831SAndroid Build Coastguard Worker 
1791*7c568831SAndroid Build Coastguard Worker static PyObject *
libxml_xmlSetValidErrors(ATTRIBUTE_UNUSED PyObject * self,PyObject * args)1792*7c568831SAndroid Build Coastguard Worker libxml_xmlSetValidErrors(ATTRIBUTE_UNUSED PyObject * self, PyObject * args)
1793*7c568831SAndroid Build Coastguard Worker {
1794*7c568831SAndroid Build Coastguard Worker     PyObject *py_retval;
1795*7c568831SAndroid Build Coastguard Worker     PyObject *pyobj_error;
1796*7c568831SAndroid Build Coastguard Worker     PyObject *pyobj_warn;
1797*7c568831SAndroid Build Coastguard Worker     PyObject *pyobj_ctx;
1798*7c568831SAndroid Build Coastguard Worker     PyObject *pyobj_arg = Py_None;
1799*7c568831SAndroid Build Coastguard Worker     xmlValidCtxtPtr ctxt;
1800*7c568831SAndroid Build Coastguard Worker     xmlValidCtxtPyCtxtPtr pyCtxt;
1801*7c568831SAndroid Build Coastguard Worker 
1802*7c568831SAndroid Build Coastguard Worker     if (!PyArg_ParseTuple
1803*7c568831SAndroid Build Coastguard Worker         (args, (char *) "OOO|O:xmlSetValidErrors", &pyobj_ctx, &pyobj_error, &pyobj_warn, &pyobj_arg))
1804*7c568831SAndroid Build Coastguard Worker         return (NULL);
1805*7c568831SAndroid Build Coastguard Worker 
1806*7c568831SAndroid Build Coastguard Worker     ctxt = PyValidCtxt_Get(pyobj_ctx);
1807*7c568831SAndroid Build Coastguard Worker     pyCtxt = xmlMalloc(sizeof(xmlValidCtxtPyCtxt));
1808*7c568831SAndroid Build Coastguard Worker     if (pyCtxt == NULL) {
1809*7c568831SAndroid Build Coastguard Worker             py_retval = libxml_intWrap(-1);
1810*7c568831SAndroid Build Coastguard Worker             return(py_retval);
1811*7c568831SAndroid Build Coastguard Worker     }
1812*7c568831SAndroid Build Coastguard Worker     memset(pyCtxt, 0, sizeof(xmlValidCtxtPyCtxt));
1813*7c568831SAndroid Build Coastguard Worker 
1814*7c568831SAndroid Build Coastguard Worker 
1815*7c568831SAndroid Build Coastguard Worker     /* TODO: check warn and error is a function ! */
1816*7c568831SAndroid Build Coastguard Worker     Py_XDECREF(pyCtxt->error);
1817*7c568831SAndroid Build Coastguard Worker     Py_XINCREF(pyobj_error);
1818*7c568831SAndroid Build Coastguard Worker     pyCtxt->error = pyobj_error;
1819*7c568831SAndroid Build Coastguard Worker 
1820*7c568831SAndroid Build Coastguard Worker     Py_XDECREF(pyCtxt->warn);
1821*7c568831SAndroid Build Coastguard Worker     Py_XINCREF(pyobj_warn);
1822*7c568831SAndroid Build Coastguard Worker     pyCtxt->warn = pyobj_warn;
1823*7c568831SAndroid Build Coastguard Worker 
1824*7c568831SAndroid Build Coastguard Worker     Py_XDECREF(pyCtxt->arg);
1825*7c568831SAndroid Build Coastguard Worker     Py_XINCREF(pyobj_arg);
1826*7c568831SAndroid Build Coastguard Worker     pyCtxt->arg = pyobj_arg;
1827*7c568831SAndroid Build Coastguard Worker 
1828*7c568831SAndroid Build Coastguard Worker     ctxt->error = libxml_xmlValidCtxtErrorFuncHandler;
1829*7c568831SAndroid Build Coastguard Worker     ctxt->warning = libxml_xmlValidCtxtWarningFuncHandler;
1830*7c568831SAndroid Build Coastguard Worker     ctxt->userData = pyCtxt;
1831*7c568831SAndroid Build Coastguard Worker 
1832*7c568831SAndroid Build Coastguard Worker     py_retval = libxml_intWrap(1);
1833*7c568831SAndroid Build Coastguard Worker     return (py_retval);
1834*7c568831SAndroid Build Coastguard Worker }
1835*7c568831SAndroid Build Coastguard Worker 
1836*7c568831SAndroid Build Coastguard Worker 
1837*7c568831SAndroid Build Coastguard Worker static PyObject *
libxml_xmlFreeValidCtxt(PyObject * self ATTRIBUTE_UNUSED,PyObject * args)1838*7c568831SAndroid Build Coastguard Worker libxml_xmlFreeValidCtxt(PyObject *self ATTRIBUTE_UNUSED, PyObject *args) {
1839*7c568831SAndroid Build Coastguard Worker     xmlValidCtxtPtr cur;
1840*7c568831SAndroid Build Coastguard Worker     xmlValidCtxtPyCtxtPtr pyCtxt;
1841*7c568831SAndroid Build Coastguard Worker     PyObject *pyobj_cur;
1842*7c568831SAndroid Build Coastguard Worker 
1843*7c568831SAndroid Build Coastguard Worker     if (!PyArg_ParseTuple(args, (char *)"O:xmlFreeValidCtxt", &pyobj_cur))
1844*7c568831SAndroid Build Coastguard Worker         return(NULL);
1845*7c568831SAndroid Build Coastguard Worker     cur = (xmlValidCtxtPtr) PyValidCtxt_Get(pyobj_cur);
1846*7c568831SAndroid Build Coastguard Worker 
1847*7c568831SAndroid Build Coastguard Worker     pyCtxt = (xmlValidCtxtPyCtxtPtr)(cur->userData);
1848*7c568831SAndroid Build Coastguard Worker     if (pyCtxt != NULL)
1849*7c568831SAndroid Build Coastguard Worker     {
1850*7c568831SAndroid Build Coastguard Worker             Py_XDECREF(pyCtxt->error);
1851*7c568831SAndroid Build Coastguard Worker             Py_XDECREF(pyCtxt->warn);
1852*7c568831SAndroid Build Coastguard Worker             Py_XDECREF(pyCtxt->arg);
1853*7c568831SAndroid Build Coastguard Worker             xmlFree(pyCtxt);
1854*7c568831SAndroid Build Coastguard Worker     }
1855*7c568831SAndroid Build Coastguard Worker 
1856*7c568831SAndroid Build Coastguard Worker     xmlFreeValidCtxt(cur);
1857*7c568831SAndroid Build Coastguard Worker     Py_INCREF(Py_None);
1858*7c568831SAndroid Build Coastguard Worker     return(Py_None);
1859*7c568831SAndroid Build Coastguard Worker }
1860*7c568831SAndroid Build Coastguard Worker #endif /* LIBXML_VALID_ENABLED */
1861*7c568831SAndroid Build Coastguard Worker 
1862*7c568831SAndroid Build Coastguard Worker #ifdef LIBXML_READER_ENABLED
1863*7c568831SAndroid Build Coastguard Worker /************************************************************************
1864*7c568831SAndroid Build Coastguard Worker  *									*
1865*7c568831SAndroid Build Coastguard Worker  *                      Per xmlTextReader error handler                 *
1866*7c568831SAndroid Build Coastguard Worker  *									*
1867*7c568831SAndroid Build Coastguard Worker  ************************************************************************/
1868*7c568831SAndroid Build Coastguard Worker 
1869*7c568831SAndroid Build Coastguard Worker typedef struct
1870*7c568831SAndroid Build Coastguard Worker {
1871*7c568831SAndroid Build Coastguard Worker     PyObject *f;
1872*7c568831SAndroid Build Coastguard Worker     PyObject *arg;
1873*7c568831SAndroid Build Coastguard Worker } xmlTextReaderPyCtxt;
1874*7c568831SAndroid Build Coastguard Worker typedef xmlTextReaderPyCtxt *xmlTextReaderPyCtxtPtr;
1875*7c568831SAndroid Build Coastguard Worker 
1876*7c568831SAndroid Build Coastguard Worker static void
libxml_xmlTextReaderErrorCallback(void * arg,const char * msg,xmlParserSeverities severity,xmlTextReaderLocatorPtr locator)1877*7c568831SAndroid Build Coastguard Worker libxml_xmlTextReaderErrorCallback(void *arg,
1878*7c568831SAndroid Build Coastguard Worker 				  const char *msg,
1879*7c568831SAndroid Build Coastguard Worker 				  xmlParserSeverities severity,
1880*7c568831SAndroid Build Coastguard Worker 				  xmlTextReaderLocatorPtr locator)
1881*7c568831SAndroid Build Coastguard Worker {
1882*7c568831SAndroid Build Coastguard Worker     xmlTextReaderPyCtxt *pyCtxt = (xmlTextReaderPyCtxt *)arg;
1883*7c568831SAndroid Build Coastguard Worker     PyObject *list;
1884*7c568831SAndroid Build Coastguard Worker     PyObject *result;
1885*7c568831SAndroid Build Coastguard Worker 
1886*7c568831SAndroid Build Coastguard Worker     list = PyTuple_New(4);
1887*7c568831SAndroid Build Coastguard Worker     PyTuple_SetItem(list, 0, pyCtxt->arg);
1888*7c568831SAndroid Build Coastguard Worker     Py_XINCREF(pyCtxt->arg);
1889*7c568831SAndroid Build Coastguard Worker     PyTuple_SetItem(list, 1, libxml_charPtrConstWrap(msg));
1890*7c568831SAndroid Build Coastguard Worker     PyTuple_SetItem(list, 2, libxml_intWrap(severity));
1891*7c568831SAndroid Build Coastguard Worker     PyTuple_SetItem(list, 3, libxml_xmlTextReaderLocatorPtrWrap(locator));
1892*7c568831SAndroid Build Coastguard Worker     result = PyObject_CallObject(pyCtxt->f, list);
1893*7c568831SAndroid Build Coastguard Worker     if (result == NULL)
1894*7c568831SAndroid Build Coastguard Worker     {
1895*7c568831SAndroid Build Coastguard Worker 	/* TODO: manage for the exception to be propagated... */
1896*7c568831SAndroid Build Coastguard Worker 	PyErr_Print();
1897*7c568831SAndroid Build Coastguard Worker     }
1898*7c568831SAndroid Build Coastguard Worker     Py_XDECREF(list);
1899*7c568831SAndroid Build Coastguard Worker     Py_XDECREF(result);
1900*7c568831SAndroid Build Coastguard Worker }
1901*7c568831SAndroid Build Coastguard Worker 
1902*7c568831SAndroid Build Coastguard Worker static PyObject *
libxml_xmlTextReaderSetErrorHandler(ATTRIBUTE_UNUSED PyObject * self,PyObject * args)1903*7c568831SAndroid Build Coastguard Worker libxml_xmlTextReaderSetErrorHandler(ATTRIBUTE_UNUSED PyObject *self, PyObject *args)
1904*7c568831SAndroid Build Coastguard Worker {
1905*7c568831SAndroid Build Coastguard Worker     xmlTextReaderPtr reader;
1906*7c568831SAndroid Build Coastguard Worker     xmlTextReaderPyCtxtPtr pyCtxt;
1907*7c568831SAndroid Build Coastguard Worker     xmlTextReaderErrorFunc f;
1908*7c568831SAndroid Build Coastguard Worker     void *arg;
1909*7c568831SAndroid Build Coastguard Worker     PyObject *pyobj_reader;
1910*7c568831SAndroid Build Coastguard Worker     PyObject *pyobj_f;
1911*7c568831SAndroid Build Coastguard Worker     PyObject *pyobj_arg;
1912*7c568831SAndroid Build Coastguard Worker     PyObject *py_retval;
1913*7c568831SAndroid Build Coastguard Worker 
1914*7c568831SAndroid Build Coastguard Worker     if (!PyArg_ParseTuple(args, (char *)"OOO:xmlTextReaderSetErrorHandler", &pyobj_reader, &pyobj_f, &pyobj_arg))
1915*7c568831SAndroid Build Coastguard Worker         return(NULL);
1916*7c568831SAndroid Build Coastguard Worker     reader = (xmlTextReaderPtr) PyxmlTextReader_Get(pyobj_reader);
1917*7c568831SAndroid Build Coastguard Worker     /* clear previous error handler */
1918*7c568831SAndroid Build Coastguard Worker     xmlTextReaderGetErrorHandler(reader,&f,&arg);
1919*7c568831SAndroid Build Coastguard Worker     if (arg != NULL) {
1920*7c568831SAndroid Build Coastguard Worker 	if (f == (xmlTextReaderErrorFunc) libxml_xmlTextReaderErrorCallback) {
1921*7c568831SAndroid Build Coastguard Worker 	    /* ok, it's our error handler! */
1922*7c568831SAndroid Build Coastguard Worker 	    pyCtxt = (xmlTextReaderPyCtxtPtr)arg;
1923*7c568831SAndroid Build Coastguard Worker 	    Py_XDECREF(pyCtxt->f);
1924*7c568831SAndroid Build Coastguard Worker 	    Py_XDECREF(pyCtxt->arg);
1925*7c568831SAndroid Build Coastguard Worker 	    xmlFree(pyCtxt);
1926*7c568831SAndroid Build Coastguard Worker 	}
1927*7c568831SAndroid Build Coastguard Worker 	else {
1928*7c568831SAndroid Build Coastguard Worker 	    /*
1929*7c568831SAndroid Build Coastguard Worker 	     * there already an arg, and it's not ours,
1930*7c568831SAndroid Build Coastguard Worker 	     * there is definitely something wrong going on here...
1931*7c568831SAndroid Build Coastguard Worker 	     * we don't know how to free it, so we bail out...
1932*7c568831SAndroid Build Coastguard Worker 	     */
1933*7c568831SAndroid Build Coastguard Worker 	    py_retval = libxml_intWrap(-1);
1934*7c568831SAndroid Build Coastguard Worker 	    return(py_retval);
1935*7c568831SAndroid Build Coastguard Worker 	}
1936*7c568831SAndroid Build Coastguard Worker     }
1937*7c568831SAndroid Build Coastguard Worker     xmlTextReaderSetErrorHandler(reader,NULL,NULL);
1938*7c568831SAndroid Build Coastguard Worker     /* set new error handler */
1939*7c568831SAndroid Build Coastguard Worker     if (pyobj_f != Py_None)
1940*7c568831SAndroid Build Coastguard Worker     {
1941*7c568831SAndroid Build Coastguard Worker 	pyCtxt = (xmlTextReaderPyCtxtPtr)xmlMalloc(sizeof(xmlTextReaderPyCtxt));
1942*7c568831SAndroid Build Coastguard Worker 	if (pyCtxt == NULL) {
1943*7c568831SAndroid Build Coastguard Worker 	    py_retval = libxml_intWrap(-1);
1944*7c568831SAndroid Build Coastguard Worker 	    return(py_retval);
1945*7c568831SAndroid Build Coastguard Worker 	}
1946*7c568831SAndroid Build Coastguard Worker 	Py_XINCREF(pyobj_f);
1947*7c568831SAndroid Build Coastguard Worker 	pyCtxt->f = pyobj_f;
1948*7c568831SAndroid Build Coastguard Worker 	Py_XINCREF(pyobj_arg);
1949*7c568831SAndroid Build Coastguard Worker 	pyCtxt->arg = pyobj_arg;
1950*7c568831SAndroid Build Coastguard Worker 	xmlTextReaderSetErrorHandler(reader,
1951*7c568831SAndroid Build Coastguard Worker 	                             libxml_xmlTextReaderErrorCallback,
1952*7c568831SAndroid Build Coastguard Worker 	                             pyCtxt);
1953*7c568831SAndroid Build Coastguard Worker     }
1954*7c568831SAndroid Build Coastguard Worker 
1955*7c568831SAndroid Build Coastguard Worker     py_retval = libxml_intWrap(1);
1956*7c568831SAndroid Build Coastguard Worker     return(py_retval);
1957*7c568831SAndroid Build Coastguard Worker }
1958*7c568831SAndroid Build Coastguard Worker 
1959*7c568831SAndroid Build Coastguard Worker static PyObject *
libxml_xmlTextReaderGetErrorHandler(ATTRIBUTE_UNUSED PyObject * self,PyObject * args)1960*7c568831SAndroid Build Coastguard Worker libxml_xmlTextReaderGetErrorHandler(ATTRIBUTE_UNUSED PyObject *self, PyObject *args)
1961*7c568831SAndroid Build Coastguard Worker {
1962*7c568831SAndroid Build Coastguard Worker     xmlTextReaderPtr reader;
1963*7c568831SAndroid Build Coastguard Worker     xmlTextReaderPyCtxtPtr pyCtxt;
1964*7c568831SAndroid Build Coastguard Worker     xmlTextReaderErrorFunc f;
1965*7c568831SAndroid Build Coastguard Worker     void *arg;
1966*7c568831SAndroid Build Coastguard Worker     PyObject *pyobj_reader;
1967*7c568831SAndroid Build Coastguard Worker     PyObject *py_retval;
1968*7c568831SAndroid Build Coastguard Worker 
1969*7c568831SAndroid Build Coastguard Worker     if (!PyArg_ParseTuple(args, (char *)"O:xmlTextReaderSetErrorHandler", &pyobj_reader))
1970*7c568831SAndroid Build Coastguard Worker         return(NULL);
1971*7c568831SAndroid Build Coastguard Worker     reader = (xmlTextReaderPtr) PyxmlTextReader_Get(pyobj_reader);
1972*7c568831SAndroid Build Coastguard Worker     xmlTextReaderGetErrorHandler(reader,&f,&arg);
1973*7c568831SAndroid Build Coastguard Worker     py_retval = PyTuple_New(2);
1974*7c568831SAndroid Build Coastguard Worker     if (f == (xmlTextReaderErrorFunc)libxml_xmlTextReaderErrorCallback) {
1975*7c568831SAndroid Build Coastguard Worker 	/* ok, it's our error handler! */
1976*7c568831SAndroid Build Coastguard Worker 	pyCtxt = (xmlTextReaderPyCtxtPtr)arg;
1977*7c568831SAndroid Build Coastguard Worker 	PyTuple_SetItem(py_retval, 0, pyCtxt->f);
1978*7c568831SAndroid Build Coastguard Worker 	Py_XINCREF(pyCtxt->f);
1979*7c568831SAndroid Build Coastguard Worker 	PyTuple_SetItem(py_retval, 1, pyCtxt->arg);
1980*7c568831SAndroid Build Coastguard Worker 	Py_XINCREF(pyCtxt->arg);
1981*7c568831SAndroid Build Coastguard Worker     }
1982*7c568831SAndroid Build Coastguard Worker     else
1983*7c568831SAndroid Build Coastguard Worker     {
1984*7c568831SAndroid Build Coastguard Worker 	/* f is null or it's not our error handler */
1985*7c568831SAndroid Build Coastguard Worker 	PyTuple_SetItem(py_retval, 0, Py_None);
1986*7c568831SAndroid Build Coastguard Worker 	Py_XINCREF(Py_None);
1987*7c568831SAndroid Build Coastguard Worker 	PyTuple_SetItem(py_retval, 1, Py_None);
1988*7c568831SAndroid Build Coastguard Worker 	Py_XINCREF(Py_None);
1989*7c568831SAndroid Build Coastguard Worker     }
1990*7c568831SAndroid Build Coastguard Worker     return(py_retval);
1991*7c568831SAndroid Build Coastguard Worker }
1992*7c568831SAndroid Build Coastguard Worker 
1993*7c568831SAndroid Build Coastguard Worker static PyObject *
libxml_xmlFreeTextReader(ATTRIBUTE_UNUSED PyObject * self,PyObject * args)1994*7c568831SAndroid Build Coastguard Worker libxml_xmlFreeTextReader(ATTRIBUTE_UNUSED PyObject *self, PyObject *args) {
1995*7c568831SAndroid Build Coastguard Worker     xmlTextReaderPtr reader;
1996*7c568831SAndroid Build Coastguard Worker     PyObject *pyobj_reader;
1997*7c568831SAndroid Build Coastguard Worker     xmlTextReaderPyCtxtPtr pyCtxt;
1998*7c568831SAndroid Build Coastguard Worker     xmlTextReaderErrorFunc f;
1999*7c568831SAndroid Build Coastguard Worker     void *arg;
2000*7c568831SAndroid Build Coastguard Worker 
2001*7c568831SAndroid Build Coastguard Worker     if (!PyArg_ParseTuple(args, (char *)"O:xmlFreeTextReader", &pyobj_reader))
2002*7c568831SAndroid Build Coastguard Worker         return(NULL);
2003*7c568831SAndroid Build Coastguard Worker     if (!PyCapsule_CheckExact(pyobj_reader)) {
2004*7c568831SAndroid Build Coastguard Worker 	Py_INCREF(Py_None);
2005*7c568831SAndroid Build Coastguard Worker 	return(Py_None);
2006*7c568831SAndroid Build Coastguard Worker     }
2007*7c568831SAndroid Build Coastguard Worker     reader = (xmlTextReaderPtr) PyxmlTextReader_Get(pyobj_reader);
2008*7c568831SAndroid Build Coastguard Worker     if (reader == NULL) {
2009*7c568831SAndroid Build Coastguard Worker 	Py_INCREF(Py_None);
2010*7c568831SAndroid Build Coastguard Worker 	return(Py_None);
2011*7c568831SAndroid Build Coastguard Worker     }
2012*7c568831SAndroid Build Coastguard Worker 
2013*7c568831SAndroid Build Coastguard Worker     xmlTextReaderGetErrorHandler(reader,&f,&arg);
2014*7c568831SAndroid Build Coastguard Worker     if (arg != NULL) {
2015*7c568831SAndroid Build Coastguard Worker 	if (f == (xmlTextReaderErrorFunc) libxml_xmlTextReaderErrorCallback) {
2016*7c568831SAndroid Build Coastguard Worker 	    /* ok, it's our error handler! */
2017*7c568831SAndroid Build Coastguard Worker 	    pyCtxt = (xmlTextReaderPyCtxtPtr)arg;
2018*7c568831SAndroid Build Coastguard Worker 	    Py_XDECREF(pyCtxt->f);
2019*7c568831SAndroid Build Coastguard Worker 	    Py_XDECREF(pyCtxt->arg);
2020*7c568831SAndroid Build Coastguard Worker 	    xmlFree(pyCtxt);
2021*7c568831SAndroid Build Coastguard Worker 	}
2022*7c568831SAndroid Build Coastguard Worker 	/*
2023*7c568831SAndroid Build Coastguard Worker 	 * else, something wrong happened, because the error handler is
2024*7c568831SAndroid Build Coastguard Worker 	 * not owned by the python bindings...
2025*7c568831SAndroid Build Coastguard Worker 	 */
2026*7c568831SAndroid Build Coastguard Worker     }
2027*7c568831SAndroid Build Coastguard Worker 
2028*7c568831SAndroid Build Coastguard Worker     xmlFreeTextReader(reader);
2029*7c568831SAndroid Build Coastguard Worker     Py_INCREF(Py_None);
2030*7c568831SAndroid Build Coastguard Worker     return(Py_None);
2031*7c568831SAndroid Build Coastguard Worker }
2032*7c568831SAndroid Build Coastguard Worker #endif
2033*7c568831SAndroid Build Coastguard Worker 
2034*7c568831SAndroid Build Coastguard Worker /************************************************************************
2035*7c568831SAndroid Build Coastguard Worker  *									*
2036*7c568831SAndroid Build Coastguard Worker  *			XPath extensions				*
2037*7c568831SAndroid Build Coastguard Worker  *									*
2038*7c568831SAndroid Build Coastguard Worker  ************************************************************************/
2039*7c568831SAndroid Build Coastguard Worker 
2040*7c568831SAndroid Build Coastguard Worker #ifdef LIBXML_XPATH_ENABLED
2041*7c568831SAndroid Build Coastguard Worker static void
libxml_xmlXPathFuncCallback(xmlXPathParserContextPtr ctxt,int nargs)2042*7c568831SAndroid Build Coastguard Worker libxml_xmlXPathFuncCallback(xmlXPathParserContextPtr ctxt, int nargs)
2043*7c568831SAndroid Build Coastguard Worker {
2044*7c568831SAndroid Build Coastguard Worker     PyObject *list, *cur, *result;
2045*7c568831SAndroid Build Coastguard Worker     xmlXPathObjectPtr obj;
2046*7c568831SAndroid Build Coastguard Worker     xmlXPathContextPtr rctxt;
2047*7c568831SAndroid Build Coastguard Worker     PyObject *current_function = NULL;
2048*7c568831SAndroid Build Coastguard Worker     const xmlChar *name;
2049*7c568831SAndroid Build Coastguard Worker     const xmlChar *ns_uri;
2050*7c568831SAndroid Build Coastguard Worker     int i;
2051*7c568831SAndroid Build Coastguard Worker 
2052*7c568831SAndroid Build Coastguard Worker     if (ctxt == NULL)
2053*7c568831SAndroid Build Coastguard Worker         return;
2054*7c568831SAndroid Build Coastguard Worker     rctxt = ctxt->context;
2055*7c568831SAndroid Build Coastguard Worker     if (rctxt == NULL)
2056*7c568831SAndroid Build Coastguard Worker         return;
2057*7c568831SAndroid Build Coastguard Worker     name = rctxt->function;
2058*7c568831SAndroid Build Coastguard Worker     ns_uri = rctxt->functionURI;
2059*7c568831SAndroid Build Coastguard Worker 
2060*7c568831SAndroid Build Coastguard Worker     /*
2061*7c568831SAndroid Build Coastguard Worker      * Find the function, it should be there it was there at lookup
2062*7c568831SAndroid Build Coastguard Worker      */
2063*7c568831SAndroid Build Coastguard Worker     for (i = 0; i < libxml_xpathCallbacksNb; i++) {
2064*7c568831SAndroid Build Coastguard Worker         if (                    /* TODO (ctxt == libxml_xpathCallbacks[i].ctx) && */
2065*7c568831SAndroid Build Coastguard Worker 						(xmlStrEqual(name, (*libxml_xpathCallbacks)[i].name)) &&
2066*7c568831SAndroid Build Coastguard Worker                (xmlStrEqual(ns_uri, (*libxml_xpathCallbacks)[i].ns_uri))) {
2067*7c568831SAndroid Build Coastguard Worker 					current_function = (*libxml_xpathCallbacks)[i].function;
2068*7c568831SAndroid Build Coastguard Worker         }
2069*7c568831SAndroid Build Coastguard Worker     }
2070*7c568831SAndroid Build Coastguard Worker     if (current_function == NULL) {
2071*7c568831SAndroid Build Coastguard Worker         printf
2072*7c568831SAndroid Build Coastguard Worker             ("libxml_xmlXPathFuncCallback: internal error %s not found !\n",
2073*7c568831SAndroid Build Coastguard Worker              name);
2074*7c568831SAndroid Build Coastguard Worker         return;
2075*7c568831SAndroid Build Coastguard Worker     }
2076*7c568831SAndroid Build Coastguard Worker 
2077*7c568831SAndroid Build Coastguard Worker     list = PyTuple_New(nargs + 1);
2078*7c568831SAndroid Build Coastguard Worker     PyTuple_SetItem(list, 0, libxml_xmlXPathParserContextPtrWrap(ctxt));
2079*7c568831SAndroid Build Coastguard Worker     for (i = nargs - 1; i >= 0; i--) {
2080*7c568831SAndroid Build Coastguard Worker         obj = valuePop(ctxt);
2081*7c568831SAndroid Build Coastguard Worker         cur = libxml_xmlXPathObjectPtrWrap(obj);
2082*7c568831SAndroid Build Coastguard Worker         PyTuple_SetItem(list, i + 1, cur);
2083*7c568831SAndroid Build Coastguard Worker     }
2084*7c568831SAndroid Build Coastguard Worker     result = PyObject_CallObject(current_function, list);
2085*7c568831SAndroid Build Coastguard Worker     Py_DECREF(list);
2086*7c568831SAndroid Build Coastguard Worker 
2087*7c568831SAndroid Build Coastguard Worker     obj = libxml_xmlXPathObjectPtrConvert(result);
2088*7c568831SAndroid Build Coastguard Worker     valuePush(ctxt, obj);
2089*7c568831SAndroid Build Coastguard Worker }
2090*7c568831SAndroid Build Coastguard Worker 
2091*7c568831SAndroid Build Coastguard Worker static xmlXPathFunction
libxml_xmlXPathFuncLookupFunc(void * ctxt,const xmlChar * name,const xmlChar * ns_uri)2092*7c568831SAndroid Build Coastguard Worker libxml_xmlXPathFuncLookupFunc(void *ctxt, const xmlChar * name,
2093*7c568831SAndroid Build Coastguard Worker                               const xmlChar * ns_uri)
2094*7c568831SAndroid Build Coastguard Worker {
2095*7c568831SAndroid Build Coastguard Worker     int i;
2096*7c568831SAndroid Build Coastguard Worker 
2097*7c568831SAndroid Build Coastguard Worker     /*
2098*7c568831SAndroid Build Coastguard Worker      * This is called once only. The address is then stored in the
2099*7c568831SAndroid Build Coastguard Worker      * XPath expression evaluation, the proper object to call can
2100*7c568831SAndroid Build Coastguard Worker      * then still be found using the execution context function
2101*7c568831SAndroid Build Coastguard Worker      * and functionURI fields.
2102*7c568831SAndroid Build Coastguard Worker      */
2103*7c568831SAndroid Build Coastguard Worker     for (i = 0; i < libxml_xpathCallbacksNb; i++) {
2104*7c568831SAndroid Build Coastguard Worker 			if ((ctxt == (*libxml_xpathCallbacks)[i].ctx) &&
2105*7c568831SAndroid Build Coastguard Worker 					(xmlStrEqual(name, (*libxml_xpathCallbacks)[i].name)) &&
2106*7c568831SAndroid Build Coastguard Worker 					(xmlStrEqual(ns_uri, (*libxml_xpathCallbacks)[i].ns_uri))) {
2107*7c568831SAndroid Build Coastguard Worker             return (libxml_xmlXPathFuncCallback);
2108*7c568831SAndroid Build Coastguard Worker         }
2109*7c568831SAndroid Build Coastguard Worker     }
2110*7c568831SAndroid Build Coastguard Worker     return (NULL);
2111*7c568831SAndroid Build Coastguard Worker }
2112*7c568831SAndroid Build Coastguard Worker 
2113*7c568831SAndroid Build Coastguard Worker static void
libxml_xpathCallbacksInitialize(void)2114*7c568831SAndroid Build Coastguard Worker libxml_xpathCallbacksInitialize(void)
2115*7c568831SAndroid Build Coastguard Worker {
2116*7c568831SAndroid Build Coastguard Worker     int i;
2117*7c568831SAndroid Build Coastguard Worker 
2118*7c568831SAndroid Build Coastguard Worker     if (libxml_xpathCallbacksInitialized != 0)
2119*7c568831SAndroid Build Coastguard Worker         return;
2120*7c568831SAndroid Build Coastguard Worker 
2121*7c568831SAndroid Build Coastguard Worker     libxml_xpathCallbacks = (libxml_xpathCallbackArray*)xmlMalloc(
2122*7c568831SAndroid Build Coastguard Worker     		libxml_xpathCallbacksAllocd*sizeof(libxml_xpathCallback));
2123*7c568831SAndroid Build Coastguard Worker 
2124*7c568831SAndroid Build Coastguard Worker     for (i = 0; i < libxml_xpathCallbacksAllocd; i++) {
2125*7c568831SAndroid Build Coastguard Worker 			(*libxml_xpathCallbacks)[i].ctx = NULL;
2126*7c568831SAndroid Build Coastguard Worker 			(*libxml_xpathCallbacks)[i].name = NULL;
2127*7c568831SAndroid Build Coastguard Worker 			(*libxml_xpathCallbacks)[i].ns_uri = NULL;
2128*7c568831SAndroid Build Coastguard Worker 			(*libxml_xpathCallbacks)[i].function = NULL;
2129*7c568831SAndroid Build Coastguard Worker     }
2130*7c568831SAndroid Build Coastguard Worker     libxml_xpathCallbacksInitialized = 1;
2131*7c568831SAndroid Build Coastguard Worker }
2132*7c568831SAndroid Build Coastguard Worker 
2133*7c568831SAndroid Build Coastguard Worker PyObject *
libxml_xmlRegisterXPathFunction(ATTRIBUTE_UNUSED PyObject * self,PyObject * args)2134*7c568831SAndroid Build Coastguard Worker libxml_xmlRegisterXPathFunction(ATTRIBUTE_UNUSED PyObject * self,
2135*7c568831SAndroid Build Coastguard Worker                                 PyObject * args)
2136*7c568831SAndroid Build Coastguard Worker {
2137*7c568831SAndroid Build Coastguard Worker     PyObject *py_retval;
2138*7c568831SAndroid Build Coastguard Worker     int c_retval = 0;
2139*7c568831SAndroid Build Coastguard Worker     xmlChar *name;
2140*7c568831SAndroid Build Coastguard Worker     xmlChar *ns_uri;
2141*7c568831SAndroid Build Coastguard Worker     xmlXPathContextPtr ctx;
2142*7c568831SAndroid Build Coastguard Worker     PyObject *pyobj_ctx;
2143*7c568831SAndroid Build Coastguard Worker     PyObject *pyobj_f;
2144*7c568831SAndroid Build Coastguard Worker     int i;
2145*7c568831SAndroid Build Coastguard Worker 
2146*7c568831SAndroid Build Coastguard Worker     if (!PyArg_ParseTuple
2147*7c568831SAndroid Build Coastguard Worker         (args, (char *) "OszO:registerXPathFunction", &pyobj_ctx, &name,
2148*7c568831SAndroid Build Coastguard Worker          &ns_uri, &pyobj_f))
2149*7c568831SAndroid Build Coastguard Worker         return (NULL);
2150*7c568831SAndroid Build Coastguard Worker 
2151*7c568831SAndroid Build Coastguard Worker     ctx = (xmlXPathContextPtr) PyxmlXPathContext_Get(pyobj_ctx);
2152*7c568831SAndroid Build Coastguard Worker     if (libxml_xpathCallbacksInitialized == 0)
2153*7c568831SAndroid Build Coastguard Worker         libxml_xpathCallbacksInitialize();
2154*7c568831SAndroid Build Coastguard Worker     xmlXPathRegisterFuncLookup(ctx, libxml_xmlXPathFuncLookupFunc, ctx);
2155*7c568831SAndroid Build Coastguard Worker 
2156*7c568831SAndroid Build Coastguard Worker     if ((pyobj_ctx == NULL) || (name == NULL) || (pyobj_f == NULL)) {
2157*7c568831SAndroid Build Coastguard Worker         py_retval = libxml_intWrap(-1);
2158*7c568831SAndroid Build Coastguard Worker         return (py_retval);
2159*7c568831SAndroid Build Coastguard Worker     }
2160*7c568831SAndroid Build Coastguard Worker     for (i = 0; i < libxml_xpathCallbacksNb; i++) {
2161*7c568831SAndroid Build Coastguard Worker 	if ((ctx == (*libxml_xpathCallbacks)[i].ctx) &&
2162*7c568831SAndroid Build Coastguard Worker             (xmlStrEqual(name, (*libxml_xpathCallbacks)[i].name)) &&
2163*7c568831SAndroid Build Coastguard Worker             (xmlStrEqual(ns_uri, (*libxml_xpathCallbacks)[i].ns_uri))) {
2164*7c568831SAndroid Build Coastguard Worker             Py_XINCREF(pyobj_f);
2165*7c568831SAndroid Build Coastguard Worker             Py_XDECREF((*libxml_xpathCallbacks)[i].function);
2166*7c568831SAndroid Build Coastguard Worker             (*libxml_xpathCallbacks)[i].function = pyobj_f;
2167*7c568831SAndroid Build Coastguard Worker             c_retval = 1;
2168*7c568831SAndroid Build Coastguard Worker             goto done;
2169*7c568831SAndroid Build Coastguard Worker         }
2170*7c568831SAndroid Build Coastguard Worker     }
2171*7c568831SAndroid Build Coastguard Worker     if (libxml_xpathCallbacksNb >= libxml_xpathCallbacksAllocd) {
2172*7c568831SAndroid Build Coastguard Worker 			libxml_xpathCallbacksAllocd+=10;
2173*7c568831SAndroid Build Coastguard Worker 	libxml_xpathCallbacks = (libxml_xpathCallbackArray*)xmlRealloc(
2174*7c568831SAndroid Build Coastguard Worker 		libxml_xpathCallbacks,
2175*7c568831SAndroid Build Coastguard Worker 		libxml_xpathCallbacksAllocd*sizeof(libxml_xpathCallback));
2176*7c568831SAndroid Build Coastguard Worker     }
2177*7c568831SAndroid Build Coastguard Worker     i = libxml_xpathCallbacksNb++;
2178*7c568831SAndroid Build Coastguard Worker     Py_XINCREF(pyobj_f);
2179*7c568831SAndroid Build Coastguard Worker     (*libxml_xpathCallbacks)[i].ctx = ctx;
2180*7c568831SAndroid Build Coastguard Worker     (*libxml_xpathCallbacks)[i].name = xmlStrdup(name);
2181*7c568831SAndroid Build Coastguard Worker     (*libxml_xpathCallbacks)[i].ns_uri = xmlStrdup(ns_uri);
2182*7c568831SAndroid Build Coastguard Worker     (*libxml_xpathCallbacks)[i].function = pyobj_f;
2183*7c568831SAndroid Build Coastguard Worker         c_retval = 1;
2184*7c568831SAndroid Build Coastguard Worker 
2185*7c568831SAndroid Build Coastguard Worker   done:
2186*7c568831SAndroid Build Coastguard Worker     py_retval = libxml_intWrap((int) c_retval);
2187*7c568831SAndroid Build Coastguard Worker     return (py_retval);
2188*7c568831SAndroid Build Coastguard Worker }
2189*7c568831SAndroid Build Coastguard Worker 
2190*7c568831SAndroid Build Coastguard Worker PyObject *
libxml_xmlXPathRegisterVariable(ATTRIBUTE_UNUSED PyObject * self,PyObject * args)2191*7c568831SAndroid Build Coastguard Worker libxml_xmlXPathRegisterVariable(ATTRIBUTE_UNUSED PyObject * self,
2192*7c568831SAndroid Build Coastguard Worker                                 PyObject * args)
2193*7c568831SAndroid Build Coastguard Worker {
2194*7c568831SAndroid Build Coastguard Worker     PyObject *py_retval;
2195*7c568831SAndroid Build Coastguard Worker     int c_retval = 0;
2196*7c568831SAndroid Build Coastguard Worker     xmlChar *name;
2197*7c568831SAndroid Build Coastguard Worker     xmlChar *ns_uri;
2198*7c568831SAndroid Build Coastguard Worker     xmlXPathContextPtr ctx;
2199*7c568831SAndroid Build Coastguard Worker     xmlXPathObjectPtr val;
2200*7c568831SAndroid Build Coastguard Worker     PyObject *pyobj_ctx;
2201*7c568831SAndroid Build Coastguard Worker     PyObject *pyobj_value;
2202*7c568831SAndroid Build Coastguard Worker 
2203*7c568831SAndroid Build Coastguard Worker     if (!PyArg_ParseTuple
2204*7c568831SAndroid Build Coastguard Worker         (args, (char *) "OszO:xpathRegisterVariable", &pyobj_ctx, &name,
2205*7c568831SAndroid Build Coastguard Worker          &ns_uri, &pyobj_value))
2206*7c568831SAndroid Build Coastguard Worker         return (NULL);
2207*7c568831SAndroid Build Coastguard Worker 
2208*7c568831SAndroid Build Coastguard Worker     ctx = (xmlXPathContextPtr) PyxmlXPathContext_Get(pyobj_ctx);
2209*7c568831SAndroid Build Coastguard Worker     val = libxml_xmlXPathObjectPtrConvert(pyobj_value);
2210*7c568831SAndroid Build Coastguard Worker 
2211*7c568831SAndroid Build Coastguard Worker     c_retval = xmlXPathRegisterVariableNS(ctx, name, ns_uri, val);
2212*7c568831SAndroid Build Coastguard Worker     py_retval = libxml_intWrap(c_retval);
2213*7c568831SAndroid Build Coastguard Worker     return (py_retval);
2214*7c568831SAndroid Build Coastguard Worker }
2215*7c568831SAndroid Build Coastguard Worker #endif /* LIBXML_XPATH_ENABLED */
2216*7c568831SAndroid Build Coastguard Worker 
2217*7c568831SAndroid Build Coastguard Worker /************************************************************************
2218*7c568831SAndroid Build Coastguard Worker  *									*
2219*7c568831SAndroid Build Coastguard Worker  *			Global properties access			*
2220*7c568831SAndroid Build Coastguard Worker  *									*
2221*7c568831SAndroid Build Coastguard Worker  ************************************************************************/
2222*7c568831SAndroid Build Coastguard Worker static PyObject *
libxml_name(ATTRIBUTE_UNUSED PyObject * self,PyObject * args)2223*7c568831SAndroid Build Coastguard Worker libxml_name(ATTRIBUTE_UNUSED PyObject * self, PyObject * args)
2224*7c568831SAndroid Build Coastguard Worker {
2225*7c568831SAndroid Build Coastguard Worker     PyObject *resultobj, *obj;
2226*7c568831SAndroid Build Coastguard Worker     xmlNodePtr cur;
2227*7c568831SAndroid Build Coastguard Worker     const xmlChar *res;
2228*7c568831SAndroid Build Coastguard Worker 
2229*7c568831SAndroid Build Coastguard Worker     if (!PyArg_ParseTuple(args, (char *) "O:name", &obj))
2230*7c568831SAndroid Build Coastguard Worker         return NULL;
2231*7c568831SAndroid Build Coastguard Worker     cur = PyxmlNode_Get(obj);
2232*7c568831SAndroid Build Coastguard Worker 
2233*7c568831SAndroid Build Coastguard Worker     switch (cur->type) {
2234*7c568831SAndroid Build Coastguard Worker         case XML_DOCUMENT_NODE:
2235*7c568831SAndroid Build Coastguard Worker         case XML_HTML_DOCUMENT_NODE:{
2236*7c568831SAndroid Build Coastguard Worker                 xmlDocPtr doc = (xmlDocPtr) cur;
2237*7c568831SAndroid Build Coastguard Worker 
2238*7c568831SAndroid Build Coastguard Worker                 res = doc->URL;
2239*7c568831SAndroid Build Coastguard Worker                 break;
2240*7c568831SAndroid Build Coastguard Worker             }
2241*7c568831SAndroid Build Coastguard Worker         case XML_ATTRIBUTE_NODE:{
2242*7c568831SAndroid Build Coastguard Worker                 xmlAttrPtr attr = (xmlAttrPtr) cur;
2243*7c568831SAndroid Build Coastguard Worker 
2244*7c568831SAndroid Build Coastguard Worker                 res = attr->name;
2245*7c568831SAndroid Build Coastguard Worker                 break;
2246*7c568831SAndroid Build Coastguard Worker             }
2247*7c568831SAndroid Build Coastguard Worker         case XML_NAMESPACE_DECL:{
2248*7c568831SAndroid Build Coastguard Worker                 xmlNsPtr ns = (xmlNsPtr) cur;
2249*7c568831SAndroid Build Coastguard Worker 
2250*7c568831SAndroid Build Coastguard Worker                 res = ns->prefix;
2251*7c568831SAndroid Build Coastguard Worker                 break;
2252*7c568831SAndroid Build Coastguard Worker             }
2253*7c568831SAndroid Build Coastguard Worker         default:
2254*7c568831SAndroid Build Coastguard Worker             res = cur->name;
2255*7c568831SAndroid Build Coastguard Worker             break;
2256*7c568831SAndroid Build Coastguard Worker     }
2257*7c568831SAndroid Build Coastguard Worker     resultobj = libxml_constxmlCharPtrWrap(res);
2258*7c568831SAndroid Build Coastguard Worker 
2259*7c568831SAndroid Build Coastguard Worker     return resultobj;
2260*7c568831SAndroid Build Coastguard Worker }
2261*7c568831SAndroid Build Coastguard Worker 
2262*7c568831SAndroid Build Coastguard Worker static PyObject *
libxml_doc(ATTRIBUTE_UNUSED PyObject * self,PyObject * args)2263*7c568831SAndroid Build Coastguard Worker libxml_doc(ATTRIBUTE_UNUSED PyObject * self, PyObject * args)
2264*7c568831SAndroid Build Coastguard Worker {
2265*7c568831SAndroid Build Coastguard Worker     PyObject *resultobj, *obj;
2266*7c568831SAndroid Build Coastguard Worker     xmlNodePtr cur;
2267*7c568831SAndroid Build Coastguard Worker     xmlDocPtr res;
2268*7c568831SAndroid Build Coastguard Worker 
2269*7c568831SAndroid Build Coastguard Worker     if (!PyArg_ParseTuple(args, (char *) "O:doc", &obj))
2270*7c568831SAndroid Build Coastguard Worker         return NULL;
2271*7c568831SAndroid Build Coastguard Worker     cur = PyxmlNode_Get(obj);
2272*7c568831SAndroid Build Coastguard Worker 
2273*7c568831SAndroid Build Coastguard Worker     switch (cur->type) {
2274*7c568831SAndroid Build Coastguard Worker         case XML_DOCUMENT_NODE:
2275*7c568831SAndroid Build Coastguard Worker         case XML_HTML_DOCUMENT_NODE:
2276*7c568831SAndroid Build Coastguard Worker             res = NULL;
2277*7c568831SAndroid Build Coastguard Worker             break;
2278*7c568831SAndroid Build Coastguard Worker         case XML_ATTRIBUTE_NODE:{
2279*7c568831SAndroid Build Coastguard Worker                 xmlAttrPtr attr = (xmlAttrPtr) cur;
2280*7c568831SAndroid Build Coastguard Worker 
2281*7c568831SAndroid Build Coastguard Worker                 res = attr->doc;
2282*7c568831SAndroid Build Coastguard Worker                 break;
2283*7c568831SAndroid Build Coastguard Worker             }
2284*7c568831SAndroid Build Coastguard Worker         case XML_NAMESPACE_DECL:
2285*7c568831SAndroid Build Coastguard Worker             res = NULL;
2286*7c568831SAndroid Build Coastguard Worker             break;
2287*7c568831SAndroid Build Coastguard Worker         default:
2288*7c568831SAndroid Build Coastguard Worker             res = cur->doc;
2289*7c568831SAndroid Build Coastguard Worker             break;
2290*7c568831SAndroid Build Coastguard Worker     }
2291*7c568831SAndroid Build Coastguard Worker     resultobj = libxml_xmlDocPtrWrap(res);
2292*7c568831SAndroid Build Coastguard Worker     return resultobj;
2293*7c568831SAndroid Build Coastguard Worker }
2294*7c568831SAndroid Build Coastguard Worker 
2295*7c568831SAndroid Build Coastguard Worker static PyObject *
libxml_properties(ATTRIBUTE_UNUSED PyObject * self,PyObject * args)2296*7c568831SAndroid Build Coastguard Worker libxml_properties(ATTRIBUTE_UNUSED PyObject * self, PyObject * args)
2297*7c568831SAndroid Build Coastguard Worker {
2298*7c568831SAndroid Build Coastguard Worker     PyObject *resultobj, *obj;
2299*7c568831SAndroid Build Coastguard Worker     xmlNodePtr cur;
2300*7c568831SAndroid Build Coastguard Worker     xmlAttrPtr res;
2301*7c568831SAndroid Build Coastguard Worker 
2302*7c568831SAndroid Build Coastguard Worker     if (!PyArg_ParseTuple(args, (char *) "O:properties", &obj))
2303*7c568831SAndroid Build Coastguard Worker         return NULL;
2304*7c568831SAndroid Build Coastguard Worker     cur = PyxmlNode_Get(obj);
2305*7c568831SAndroid Build Coastguard Worker     if ((cur != NULL) && (cur->type == XML_ELEMENT_NODE))
2306*7c568831SAndroid Build Coastguard Worker         res = cur->properties;
2307*7c568831SAndroid Build Coastguard Worker     else
2308*7c568831SAndroid Build Coastguard Worker         res = NULL;
2309*7c568831SAndroid Build Coastguard Worker     resultobj = libxml_xmlAttrPtrWrap(res);
2310*7c568831SAndroid Build Coastguard Worker     return resultobj;
2311*7c568831SAndroid Build Coastguard Worker }
2312*7c568831SAndroid Build Coastguard Worker 
2313*7c568831SAndroid Build Coastguard Worker static PyObject *
libxml_next(ATTRIBUTE_UNUSED PyObject * self,PyObject * args)2314*7c568831SAndroid Build Coastguard Worker libxml_next(ATTRIBUTE_UNUSED PyObject * self, PyObject * args)
2315*7c568831SAndroid Build Coastguard Worker {
2316*7c568831SAndroid Build Coastguard Worker     PyObject *resultobj, *obj;
2317*7c568831SAndroid Build Coastguard Worker     xmlNodePtr cur;
2318*7c568831SAndroid Build Coastguard Worker     xmlNodePtr res;
2319*7c568831SAndroid Build Coastguard Worker 
2320*7c568831SAndroid Build Coastguard Worker     if (!PyArg_ParseTuple(args, (char *) "O:next", &obj))
2321*7c568831SAndroid Build Coastguard Worker         return NULL;
2322*7c568831SAndroid Build Coastguard Worker     cur = PyxmlNode_Get(obj);
2323*7c568831SAndroid Build Coastguard Worker 
2324*7c568831SAndroid Build Coastguard Worker     switch (cur->type) {
2325*7c568831SAndroid Build Coastguard Worker         case XML_DOCUMENT_NODE:
2326*7c568831SAndroid Build Coastguard Worker         case XML_HTML_DOCUMENT_NODE:
2327*7c568831SAndroid Build Coastguard Worker             res = NULL;
2328*7c568831SAndroid Build Coastguard Worker             break;
2329*7c568831SAndroid Build Coastguard Worker         case XML_ATTRIBUTE_NODE:{
2330*7c568831SAndroid Build Coastguard Worker                 xmlAttrPtr attr = (xmlAttrPtr) cur;
2331*7c568831SAndroid Build Coastguard Worker 
2332*7c568831SAndroid Build Coastguard Worker                 res = (xmlNodePtr) attr->next;
2333*7c568831SAndroid Build Coastguard Worker                 break;
2334*7c568831SAndroid Build Coastguard Worker             }
2335*7c568831SAndroid Build Coastguard Worker         case XML_NAMESPACE_DECL:{
2336*7c568831SAndroid Build Coastguard Worker                 xmlNsPtr ns = (xmlNsPtr) cur;
2337*7c568831SAndroid Build Coastguard Worker 
2338*7c568831SAndroid Build Coastguard Worker                 res = (xmlNodePtr) ns->next;
2339*7c568831SAndroid Build Coastguard Worker                 break;
2340*7c568831SAndroid Build Coastguard Worker             }
2341*7c568831SAndroid Build Coastguard Worker         default:
2342*7c568831SAndroid Build Coastguard Worker             res = cur->next;
2343*7c568831SAndroid Build Coastguard Worker             break;
2344*7c568831SAndroid Build Coastguard Worker 
2345*7c568831SAndroid Build Coastguard Worker     }
2346*7c568831SAndroid Build Coastguard Worker     resultobj = libxml_xmlNodePtrWrap(res);
2347*7c568831SAndroid Build Coastguard Worker     return resultobj;
2348*7c568831SAndroid Build Coastguard Worker }
2349*7c568831SAndroid Build Coastguard Worker 
2350*7c568831SAndroid Build Coastguard Worker static PyObject *
libxml_prev(ATTRIBUTE_UNUSED PyObject * self,PyObject * args)2351*7c568831SAndroid Build Coastguard Worker libxml_prev(ATTRIBUTE_UNUSED PyObject * self, PyObject * args)
2352*7c568831SAndroid Build Coastguard Worker {
2353*7c568831SAndroid Build Coastguard Worker     PyObject *resultobj, *obj;
2354*7c568831SAndroid Build Coastguard Worker     xmlNodePtr cur;
2355*7c568831SAndroid Build Coastguard Worker     xmlNodePtr res;
2356*7c568831SAndroid Build Coastguard Worker 
2357*7c568831SAndroid Build Coastguard Worker     if (!PyArg_ParseTuple(args, (char *) "O:prev", &obj))
2358*7c568831SAndroid Build Coastguard Worker         return NULL;
2359*7c568831SAndroid Build Coastguard Worker     cur = PyxmlNode_Get(obj);
2360*7c568831SAndroid Build Coastguard Worker 
2361*7c568831SAndroid Build Coastguard Worker     switch (cur->type) {
2362*7c568831SAndroid Build Coastguard Worker         case XML_DOCUMENT_NODE:
2363*7c568831SAndroid Build Coastguard Worker         case XML_HTML_DOCUMENT_NODE:
2364*7c568831SAndroid Build Coastguard Worker             res = NULL;
2365*7c568831SAndroid Build Coastguard Worker             break;
2366*7c568831SAndroid Build Coastguard Worker         case XML_ATTRIBUTE_NODE:{
2367*7c568831SAndroid Build Coastguard Worker                 xmlAttrPtr attr = (xmlAttrPtr) cur;
2368*7c568831SAndroid Build Coastguard Worker 
2369*7c568831SAndroid Build Coastguard Worker                 res = (xmlNodePtr) attr->prev;
2370*7c568831SAndroid Build Coastguard Worker             }
2371*7c568831SAndroid Build Coastguard Worker             break;
2372*7c568831SAndroid Build Coastguard Worker         case XML_NAMESPACE_DECL:
2373*7c568831SAndroid Build Coastguard Worker             res = NULL;
2374*7c568831SAndroid Build Coastguard Worker             break;
2375*7c568831SAndroid Build Coastguard Worker         default:
2376*7c568831SAndroid Build Coastguard Worker             res = cur->prev;
2377*7c568831SAndroid Build Coastguard Worker             break;
2378*7c568831SAndroid Build Coastguard Worker     }
2379*7c568831SAndroid Build Coastguard Worker     resultobj = libxml_xmlNodePtrWrap(res);
2380*7c568831SAndroid Build Coastguard Worker     return resultobj;
2381*7c568831SAndroid Build Coastguard Worker }
2382*7c568831SAndroid Build Coastguard Worker 
2383*7c568831SAndroid Build Coastguard Worker static PyObject *
libxml_children(ATTRIBUTE_UNUSED PyObject * self,PyObject * args)2384*7c568831SAndroid Build Coastguard Worker libxml_children(ATTRIBUTE_UNUSED PyObject * self, PyObject * args)
2385*7c568831SAndroid Build Coastguard Worker {
2386*7c568831SAndroid Build Coastguard Worker     PyObject *resultobj, *obj;
2387*7c568831SAndroid Build Coastguard Worker     xmlNodePtr cur;
2388*7c568831SAndroid Build Coastguard Worker     xmlNodePtr res;
2389*7c568831SAndroid Build Coastguard Worker 
2390*7c568831SAndroid Build Coastguard Worker     if (!PyArg_ParseTuple(args, (char *) "O:children", &obj))
2391*7c568831SAndroid Build Coastguard Worker         return NULL;
2392*7c568831SAndroid Build Coastguard Worker     cur = PyxmlNode_Get(obj);
2393*7c568831SAndroid Build Coastguard Worker 
2394*7c568831SAndroid Build Coastguard Worker     switch (cur->type) {
2395*7c568831SAndroid Build Coastguard Worker         case XML_ELEMENT_NODE:
2396*7c568831SAndroid Build Coastguard Worker         case XML_ENTITY_REF_NODE:
2397*7c568831SAndroid Build Coastguard Worker         case XML_ENTITY_NODE:
2398*7c568831SAndroid Build Coastguard Worker         case XML_PI_NODE:
2399*7c568831SAndroid Build Coastguard Worker         case XML_COMMENT_NODE:
2400*7c568831SAndroid Build Coastguard Worker         case XML_DOCUMENT_NODE:
2401*7c568831SAndroid Build Coastguard Worker         case XML_HTML_DOCUMENT_NODE:
2402*7c568831SAndroid Build Coastguard Worker         case XML_DTD_NODE:
2403*7c568831SAndroid Build Coastguard Worker             res = cur->children;
2404*7c568831SAndroid Build Coastguard Worker             break;
2405*7c568831SAndroid Build Coastguard Worker         case XML_ATTRIBUTE_NODE:{
2406*7c568831SAndroid Build Coastguard Worker                 xmlAttrPtr attr = (xmlAttrPtr) cur;
2407*7c568831SAndroid Build Coastguard Worker 
2408*7c568831SAndroid Build Coastguard Worker                 res = attr->children;
2409*7c568831SAndroid Build Coastguard Worker                 break;
2410*7c568831SAndroid Build Coastguard Worker             }
2411*7c568831SAndroid Build Coastguard Worker         default:
2412*7c568831SAndroid Build Coastguard Worker             res = NULL;
2413*7c568831SAndroid Build Coastguard Worker             break;
2414*7c568831SAndroid Build Coastguard Worker     }
2415*7c568831SAndroid Build Coastguard Worker     resultobj = libxml_xmlNodePtrWrap(res);
2416*7c568831SAndroid Build Coastguard Worker     return resultobj;
2417*7c568831SAndroid Build Coastguard Worker }
2418*7c568831SAndroid Build Coastguard Worker 
2419*7c568831SAndroid Build Coastguard Worker static PyObject *
libxml_last(ATTRIBUTE_UNUSED PyObject * self,PyObject * args)2420*7c568831SAndroid Build Coastguard Worker libxml_last(ATTRIBUTE_UNUSED PyObject * self, PyObject * args)
2421*7c568831SAndroid Build Coastguard Worker {
2422*7c568831SAndroid Build Coastguard Worker     PyObject *resultobj, *obj;
2423*7c568831SAndroid Build Coastguard Worker     xmlNodePtr cur;
2424*7c568831SAndroid Build Coastguard Worker     xmlNodePtr res;
2425*7c568831SAndroid Build Coastguard Worker 
2426*7c568831SAndroid Build Coastguard Worker     if (!PyArg_ParseTuple(args, (char *) "O:last", &obj))
2427*7c568831SAndroid Build Coastguard Worker         return NULL;
2428*7c568831SAndroid Build Coastguard Worker     cur = PyxmlNode_Get(obj);
2429*7c568831SAndroid Build Coastguard Worker 
2430*7c568831SAndroid Build Coastguard Worker     switch (cur->type) {
2431*7c568831SAndroid Build Coastguard Worker         case XML_ELEMENT_NODE:
2432*7c568831SAndroid Build Coastguard Worker         case XML_ENTITY_REF_NODE:
2433*7c568831SAndroid Build Coastguard Worker         case XML_ENTITY_NODE:
2434*7c568831SAndroid Build Coastguard Worker         case XML_PI_NODE:
2435*7c568831SAndroid Build Coastguard Worker         case XML_COMMENT_NODE:
2436*7c568831SAndroid Build Coastguard Worker         case XML_DOCUMENT_NODE:
2437*7c568831SAndroid Build Coastguard Worker         case XML_HTML_DOCUMENT_NODE:
2438*7c568831SAndroid Build Coastguard Worker         case XML_DTD_NODE:
2439*7c568831SAndroid Build Coastguard Worker             res = cur->last;
2440*7c568831SAndroid Build Coastguard Worker             break;
2441*7c568831SAndroid Build Coastguard Worker         case XML_ATTRIBUTE_NODE:{
2442*7c568831SAndroid Build Coastguard Worker                 xmlAttrPtr attr = (xmlAttrPtr) cur;
2443*7c568831SAndroid Build Coastguard Worker 
2444*7c568831SAndroid Build Coastguard Worker                 res = attr->last;
2445*7c568831SAndroid Build Coastguard Worker 		break;
2446*7c568831SAndroid Build Coastguard Worker             }
2447*7c568831SAndroid Build Coastguard Worker         default:
2448*7c568831SAndroid Build Coastguard Worker             res = NULL;
2449*7c568831SAndroid Build Coastguard Worker             break;
2450*7c568831SAndroid Build Coastguard Worker     }
2451*7c568831SAndroid Build Coastguard Worker     resultobj = libxml_xmlNodePtrWrap(res);
2452*7c568831SAndroid Build Coastguard Worker     return resultobj;
2453*7c568831SAndroid Build Coastguard Worker }
2454*7c568831SAndroid Build Coastguard Worker 
2455*7c568831SAndroid Build Coastguard Worker static PyObject *
libxml_parent(ATTRIBUTE_UNUSED PyObject * self,PyObject * args)2456*7c568831SAndroid Build Coastguard Worker libxml_parent(ATTRIBUTE_UNUSED PyObject * self, PyObject * args)
2457*7c568831SAndroid Build Coastguard Worker {
2458*7c568831SAndroid Build Coastguard Worker     PyObject *resultobj, *obj;
2459*7c568831SAndroid Build Coastguard Worker     xmlNodePtr cur;
2460*7c568831SAndroid Build Coastguard Worker     xmlNodePtr res;
2461*7c568831SAndroid Build Coastguard Worker 
2462*7c568831SAndroid Build Coastguard Worker     if (!PyArg_ParseTuple(args, (char *) "O:parent", &obj))
2463*7c568831SAndroid Build Coastguard Worker         return NULL;
2464*7c568831SAndroid Build Coastguard Worker     cur = PyxmlNode_Get(obj);
2465*7c568831SAndroid Build Coastguard Worker 
2466*7c568831SAndroid Build Coastguard Worker     switch (cur->type) {
2467*7c568831SAndroid Build Coastguard Worker         case XML_DOCUMENT_NODE:
2468*7c568831SAndroid Build Coastguard Worker         case XML_HTML_DOCUMENT_NODE:
2469*7c568831SAndroid Build Coastguard Worker             res = NULL;
2470*7c568831SAndroid Build Coastguard Worker             break;
2471*7c568831SAndroid Build Coastguard Worker         case XML_ATTRIBUTE_NODE:{
2472*7c568831SAndroid Build Coastguard Worker                 xmlAttrPtr attr = (xmlAttrPtr) cur;
2473*7c568831SAndroid Build Coastguard Worker 
2474*7c568831SAndroid Build Coastguard Worker                 res = attr->parent;
2475*7c568831SAndroid Build Coastguard Worker             }
2476*7c568831SAndroid Build Coastguard Worker 	    break;
2477*7c568831SAndroid Build Coastguard Worker         case XML_ENTITY_DECL:
2478*7c568831SAndroid Build Coastguard Worker         case XML_NAMESPACE_DECL:
2479*7c568831SAndroid Build Coastguard Worker         case XML_XINCLUDE_START:
2480*7c568831SAndroid Build Coastguard Worker         case XML_XINCLUDE_END:
2481*7c568831SAndroid Build Coastguard Worker             res = NULL;
2482*7c568831SAndroid Build Coastguard Worker             break;
2483*7c568831SAndroid Build Coastguard Worker         default:
2484*7c568831SAndroid Build Coastguard Worker             res = cur->parent;
2485*7c568831SAndroid Build Coastguard Worker             break;
2486*7c568831SAndroid Build Coastguard Worker     }
2487*7c568831SAndroid Build Coastguard Worker     resultobj = libxml_xmlNodePtrWrap(res);
2488*7c568831SAndroid Build Coastguard Worker     return resultobj;
2489*7c568831SAndroid Build Coastguard Worker }
2490*7c568831SAndroid Build Coastguard Worker 
2491*7c568831SAndroid Build Coastguard Worker static PyObject *
libxml_type(ATTRIBUTE_UNUSED PyObject * self,PyObject * args)2492*7c568831SAndroid Build Coastguard Worker libxml_type(ATTRIBUTE_UNUSED PyObject * self, PyObject * args)
2493*7c568831SAndroid Build Coastguard Worker {
2494*7c568831SAndroid Build Coastguard Worker     PyObject *resultobj, *obj;
2495*7c568831SAndroid Build Coastguard Worker     xmlNodePtr cur;
2496*7c568831SAndroid Build Coastguard Worker     const xmlChar *res = NULL;
2497*7c568831SAndroid Build Coastguard Worker 
2498*7c568831SAndroid Build Coastguard Worker     if (!PyArg_ParseTuple(args, (char *) "O:last", &obj))
2499*7c568831SAndroid Build Coastguard Worker         return NULL;
2500*7c568831SAndroid Build Coastguard Worker     cur = PyxmlNode_Get(obj);
2501*7c568831SAndroid Build Coastguard Worker     if (cur == NULL) {
2502*7c568831SAndroid Build Coastguard Worker         Py_INCREF(Py_None);
2503*7c568831SAndroid Build Coastguard Worker 	return (Py_None);
2504*7c568831SAndroid Build Coastguard Worker     }
2505*7c568831SAndroid Build Coastguard Worker 
2506*7c568831SAndroid Build Coastguard Worker     switch (cur->type) {
2507*7c568831SAndroid Build Coastguard Worker         case XML_ELEMENT_NODE:
2508*7c568831SAndroid Build Coastguard Worker             res = (const xmlChar *) "element";
2509*7c568831SAndroid Build Coastguard Worker             break;
2510*7c568831SAndroid Build Coastguard Worker         case XML_ATTRIBUTE_NODE:
2511*7c568831SAndroid Build Coastguard Worker             res = (const xmlChar *) "attribute";
2512*7c568831SAndroid Build Coastguard Worker             break;
2513*7c568831SAndroid Build Coastguard Worker         case XML_TEXT_NODE:
2514*7c568831SAndroid Build Coastguard Worker             res = (const xmlChar *) "text";
2515*7c568831SAndroid Build Coastguard Worker             break;
2516*7c568831SAndroid Build Coastguard Worker         case XML_CDATA_SECTION_NODE:
2517*7c568831SAndroid Build Coastguard Worker             res = (const xmlChar *) "cdata";
2518*7c568831SAndroid Build Coastguard Worker             break;
2519*7c568831SAndroid Build Coastguard Worker         case XML_ENTITY_REF_NODE:
2520*7c568831SAndroid Build Coastguard Worker             res = (const xmlChar *) "entity_ref";
2521*7c568831SAndroid Build Coastguard Worker             break;
2522*7c568831SAndroid Build Coastguard Worker         case XML_ENTITY_NODE:
2523*7c568831SAndroid Build Coastguard Worker             res = (const xmlChar *) "entity";
2524*7c568831SAndroid Build Coastguard Worker             break;
2525*7c568831SAndroid Build Coastguard Worker         case XML_PI_NODE:
2526*7c568831SAndroid Build Coastguard Worker             res = (const xmlChar *) "pi";
2527*7c568831SAndroid Build Coastguard Worker             break;
2528*7c568831SAndroid Build Coastguard Worker         case XML_COMMENT_NODE:
2529*7c568831SAndroid Build Coastguard Worker             res = (const xmlChar *) "comment";
2530*7c568831SAndroid Build Coastguard Worker             break;
2531*7c568831SAndroid Build Coastguard Worker         case XML_DOCUMENT_NODE:
2532*7c568831SAndroid Build Coastguard Worker             res = (const xmlChar *) "document_xml";
2533*7c568831SAndroid Build Coastguard Worker             break;
2534*7c568831SAndroid Build Coastguard Worker         case XML_DOCUMENT_TYPE_NODE:
2535*7c568831SAndroid Build Coastguard Worker             res = (const xmlChar *) "doctype";
2536*7c568831SAndroid Build Coastguard Worker             break;
2537*7c568831SAndroid Build Coastguard Worker         case XML_DOCUMENT_FRAG_NODE:
2538*7c568831SAndroid Build Coastguard Worker             res = (const xmlChar *) "fragment";
2539*7c568831SAndroid Build Coastguard Worker             break;
2540*7c568831SAndroid Build Coastguard Worker         case XML_NOTATION_NODE:
2541*7c568831SAndroid Build Coastguard Worker             res = (const xmlChar *) "notation";
2542*7c568831SAndroid Build Coastguard Worker             break;
2543*7c568831SAndroid Build Coastguard Worker         case XML_HTML_DOCUMENT_NODE:
2544*7c568831SAndroid Build Coastguard Worker             res = (const xmlChar *) "document_html";
2545*7c568831SAndroid Build Coastguard Worker             break;
2546*7c568831SAndroid Build Coastguard Worker         case XML_DTD_NODE:
2547*7c568831SAndroid Build Coastguard Worker             res = (const xmlChar *) "dtd";
2548*7c568831SAndroid Build Coastguard Worker             break;
2549*7c568831SAndroid Build Coastguard Worker         case XML_ELEMENT_DECL:
2550*7c568831SAndroid Build Coastguard Worker             res = (const xmlChar *) "elem_decl";
2551*7c568831SAndroid Build Coastguard Worker             break;
2552*7c568831SAndroid Build Coastguard Worker         case XML_ATTRIBUTE_DECL:
2553*7c568831SAndroid Build Coastguard Worker             res = (const xmlChar *) "attribute_decl";
2554*7c568831SAndroid Build Coastguard Worker             break;
2555*7c568831SAndroid Build Coastguard Worker         case XML_ENTITY_DECL:
2556*7c568831SAndroid Build Coastguard Worker             res = (const xmlChar *) "entity_decl";
2557*7c568831SAndroid Build Coastguard Worker             break;
2558*7c568831SAndroid Build Coastguard Worker         case XML_NAMESPACE_DECL:
2559*7c568831SAndroid Build Coastguard Worker             res = (const xmlChar *) "namespace";
2560*7c568831SAndroid Build Coastguard Worker             break;
2561*7c568831SAndroid Build Coastguard Worker         case XML_XINCLUDE_START:
2562*7c568831SAndroid Build Coastguard Worker             res = (const xmlChar *) "xinclude_start";
2563*7c568831SAndroid Build Coastguard Worker             break;
2564*7c568831SAndroid Build Coastguard Worker         case XML_XINCLUDE_END:
2565*7c568831SAndroid Build Coastguard Worker             res = (const xmlChar *) "xinclude_end";
2566*7c568831SAndroid Build Coastguard Worker             break;
2567*7c568831SAndroid Build Coastguard Worker     }
2568*7c568831SAndroid Build Coastguard Worker 
2569*7c568831SAndroid Build Coastguard Worker     resultobj = libxml_constxmlCharPtrWrap(res);
2570*7c568831SAndroid Build Coastguard Worker     return resultobj;
2571*7c568831SAndroid Build Coastguard Worker }
2572*7c568831SAndroid Build Coastguard Worker 
2573*7c568831SAndroid Build Coastguard Worker /************************************************************************
2574*7c568831SAndroid Build Coastguard Worker  *									*
2575*7c568831SAndroid Build Coastguard Worker  *			Specific accessor functions			*
2576*7c568831SAndroid Build Coastguard Worker  *									*
2577*7c568831SAndroid Build Coastguard Worker  ************************************************************************/
2578*7c568831SAndroid Build Coastguard Worker PyObject *
libxml_xmlNodeGetNsDefs(ATTRIBUTE_UNUSED PyObject * self,PyObject * args)2579*7c568831SAndroid Build Coastguard Worker libxml_xmlNodeGetNsDefs(ATTRIBUTE_UNUSED PyObject * self, PyObject * args)
2580*7c568831SAndroid Build Coastguard Worker {
2581*7c568831SAndroid Build Coastguard Worker     PyObject *py_retval;
2582*7c568831SAndroid Build Coastguard Worker     xmlNsPtr c_retval;
2583*7c568831SAndroid Build Coastguard Worker     xmlNodePtr node;
2584*7c568831SAndroid Build Coastguard Worker     PyObject *pyobj_node;
2585*7c568831SAndroid Build Coastguard Worker 
2586*7c568831SAndroid Build Coastguard Worker     if (!PyArg_ParseTuple
2587*7c568831SAndroid Build Coastguard Worker         (args, (char *) "O:xmlNodeGetNsDefs", &pyobj_node))
2588*7c568831SAndroid Build Coastguard Worker         return (NULL);
2589*7c568831SAndroid Build Coastguard Worker     node = (xmlNodePtr) PyxmlNode_Get(pyobj_node);
2590*7c568831SAndroid Build Coastguard Worker 
2591*7c568831SAndroid Build Coastguard Worker     if ((node == NULL) || (node->type != XML_ELEMENT_NODE)) {
2592*7c568831SAndroid Build Coastguard Worker         Py_INCREF(Py_None);
2593*7c568831SAndroid Build Coastguard Worker         return (Py_None);
2594*7c568831SAndroid Build Coastguard Worker     }
2595*7c568831SAndroid Build Coastguard Worker     c_retval = node->nsDef;
2596*7c568831SAndroid Build Coastguard Worker     py_retval = libxml_xmlNsPtrWrap((xmlNsPtr) c_retval);
2597*7c568831SAndroid Build Coastguard Worker     return (py_retval);
2598*7c568831SAndroid Build Coastguard Worker }
2599*7c568831SAndroid Build Coastguard Worker 
2600*7c568831SAndroid Build Coastguard Worker PyObject *
libxml_xmlNodeRemoveNsDef(ATTRIBUTE_UNUSED PyObject * self,PyObject * args)2601*7c568831SAndroid Build Coastguard Worker libxml_xmlNodeRemoveNsDef(ATTRIBUTE_UNUSED PyObject * self, PyObject * args)
2602*7c568831SAndroid Build Coastguard Worker {
2603*7c568831SAndroid Build Coastguard Worker     PyObject *py_retval;
2604*7c568831SAndroid Build Coastguard Worker     xmlNsPtr ns, prev;
2605*7c568831SAndroid Build Coastguard Worker     xmlNodePtr node;
2606*7c568831SAndroid Build Coastguard Worker     PyObject *pyobj_node;
2607*7c568831SAndroid Build Coastguard Worker     xmlChar *href;
2608*7c568831SAndroid Build Coastguard Worker     xmlNsPtr c_retval;
2609*7c568831SAndroid Build Coastguard Worker 
2610*7c568831SAndroid Build Coastguard Worker     if (!PyArg_ParseTuple
2611*7c568831SAndroid Build Coastguard Worker         (args, (char *) "Oz:xmlNodeRemoveNsDef", &pyobj_node, &href))
2612*7c568831SAndroid Build Coastguard Worker         return (NULL);
2613*7c568831SAndroid Build Coastguard Worker     node = (xmlNodePtr) PyxmlNode_Get(pyobj_node);
2614*7c568831SAndroid Build Coastguard Worker     ns = NULL;
2615*7c568831SAndroid Build Coastguard Worker 
2616*7c568831SAndroid Build Coastguard Worker     if ((node == NULL) || (node->type != XML_ELEMENT_NODE)) {
2617*7c568831SAndroid Build Coastguard Worker         Py_INCREF(Py_None);
2618*7c568831SAndroid Build Coastguard Worker         return (Py_None);
2619*7c568831SAndroid Build Coastguard Worker     }
2620*7c568831SAndroid Build Coastguard Worker 
2621*7c568831SAndroid Build Coastguard Worker     if (href == NULL) {
2622*7c568831SAndroid Build Coastguard Worker 	ns = node->nsDef;
2623*7c568831SAndroid Build Coastguard Worker 	node->nsDef = NULL;
2624*7c568831SAndroid Build Coastguard Worker 	c_retval = 0;
2625*7c568831SAndroid Build Coastguard Worker     }
2626*7c568831SAndroid Build Coastguard Worker     else {
2627*7c568831SAndroid Build Coastguard Worker 	prev = NULL;
2628*7c568831SAndroid Build Coastguard Worker 	ns = node->nsDef;
2629*7c568831SAndroid Build Coastguard Worker 	while (ns != NULL) {
2630*7c568831SAndroid Build Coastguard Worker 	    if (xmlStrEqual(ns->href, href)) {
2631*7c568831SAndroid Build Coastguard Worker 		if (prev != NULL)
2632*7c568831SAndroid Build Coastguard Worker 		    prev->next = ns->next;
2633*7c568831SAndroid Build Coastguard Worker 		else
2634*7c568831SAndroid Build Coastguard Worker 		    node->nsDef = ns->next;
2635*7c568831SAndroid Build Coastguard Worker 		ns->next = NULL;
2636*7c568831SAndroid Build Coastguard Worker 		c_retval = 0;
2637*7c568831SAndroid Build Coastguard Worker 		break;
2638*7c568831SAndroid Build Coastguard Worker 	    }
2639*7c568831SAndroid Build Coastguard Worker 	    prev = ns;
2640*7c568831SAndroid Build Coastguard Worker 	    ns = ns->next;
2641*7c568831SAndroid Build Coastguard Worker 	}
2642*7c568831SAndroid Build Coastguard Worker     }
2643*7c568831SAndroid Build Coastguard Worker 
2644*7c568831SAndroid Build Coastguard Worker     c_retval = ns;
2645*7c568831SAndroid Build Coastguard Worker     py_retval = libxml_xmlNsPtrWrap((xmlNsPtr) c_retval);
2646*7c568831SAndroid Build Coastguard Worker     return (py_retval);
2647*7c568831SAndroid Build Coastguard Worker }
2648*7c568831SAndroid Build Coastguard Worker 
2649*7c568831SAndroid Build Coastguard Worker PyObject *
libxml_xmlNodeGetNs(ATTRIBUTE_UNUSED PyObject * self,PyObject * args)2650*7c568831SAndroid Build Coastguard Worker libxml_xmlNodeGetNs(ATTRIBUTE_UNUSED PyObject * self, PyObject * args)
2651*7c568831SAndroid Build Coastguard Worker {
2652*7c568831SAndroid Build Coastguard Worker     PyObject *py_retval;
2653*7c568831SAndroid Build Coastguard Worker     xmlNsPtr c_retval;
2654*7c568831SAndroid Build Coastguard Worker     xmlNodePtr node;
2655*7c568831SAndroid Build Coastguard Worker     PyObject *pyobj_node;
2656*7c568831SAndroid Build Coastguard Worker 
2657*7c568831SAndroid Build Coastguard Worker     if (!PyArg_ParseTuple(args, (char *) "O:xmlNodeGetNs", &pyobj_node))
2658*7c568831SAndroid Build Coastguard Worker         return (NULL);
2659*7c568831SAndroid Build Coastguard Worker     node = (xmlNodePtr) PyxmlNode_Get(pyobj_node);
2660*7c568831SAndroid Build Coastguard Worker 
2661*7c568831SAndroid Build Coastguard Worker     if ((node == NULL) ||
2662*7c568831SAndroid Build Coastguard Worker         ((node->type != XML_ELEMENT_NODE) &&
2663*7c568831SAndroid Build Coastguard Worker 	 (node->type != XML_ATTRIBUTE_NODE))) {
2664*7c568831SAndroid Build Coastguard Worker         Py_INCREF(Py_None);
2665*7c568831SAndroid Build Coastguard Worker         return (Py_None);
2666*7c568831SAndroid Build Coastguard Worker     }
2667*7c568831SAndroid Build Coastguard Worker     c_retval = node->ns;
2668*7c568831SAndroid Build Coastguard Worker     py_retval = libxml_xmlNsPtrWrap((xmlNsPtr) c_retval);
2669*7c568831SAndroid Build Coastguard Worker     return (py_retval);
2670*7c568831SAndroid Build Coastguard Worker }
2671*7c568831SAndroid Build Coastguard Worker 
2672*7c568831SAndroid Build Coastguard Worker #ifdef LIBXML_OUTPUT_ENABLED
2673*7c568831SAndroid Build Coastguard Worker /************************************************************************
2674*7c568831SAndroid Build Coastguard Worker  *									*
2675*7c568831SAndroid Build Coastguard Worker  *			Serialization front-end				*
2676*7c568831SAndroid Build Coastguard Worker  *									*
2677*7c568831SAndroid Build Coastguard Worker  ************************************************************************/
2678*7c568831SAndroid Build Coastguard Worker 
2679*7c568831SAndroid Build Coastguard Worker static PyObject *
libxml_serializeNode(ATTRIBUTE_UNUSED PyObject * self,PyObject * args)2680*7c568831SAndroid Build Coastguard Worker libxml_serializeNode(ATTRIBUTE_UNUSED PyObject * self, PyObject * args)
2681*7c568831SAndroid Build Coastguard Worker {
2682*7c568831SAndroid Build Coastguard Worker     PyObject *py_retval = NULL;
2683*7c568831SAndroid Build Coastguard Worker     xmlChar *c_retval;
2684*7c568831SAndroid Build Coastguard Worker     PyObject *pyobj_node;
2685*7c568831SAndroid Build Coastguard Worker     xmlNodePtr node;
2686*7c568831SAndroid Build Coastguard Worker     xmlDocPtr doc;
2687*7c568831SAndroid Build Coastguard Worker     const char *encoding;
2688*7c568831SAndroid Build Coastguard Worker     int format;
2689*7c568831SAndroid Build Coastguard Worker     xmlSaveCtxtPtr ctxt;
2690*7c568831SAndroid Build Coastguard Worker     xmlBufferPtr buf;
2691*7c568831SAndroid Build Coastguard Worker     int options = 0;
2692*7c568831SAndroid Build Coastguard Worker 
2693*7c568831SAndroid Build Coastguard Worker     if (!PyArg_ParseTuple(args, (char *) "Ozi:serializeNode", &pyobj_node,
2694*7c568831SAndroid Build Coastguard Worker                           &encoding, &format))
2695*7c568831SAndroid Build Coastguard Worker         return (NULL);
2696*7c568831SAndroid Build Coastguard Worker     node = (xmlNodePtr) PyxmlNode_Get(pyobj_node);
2697*7c568831SAndroid Build Coastguard Worker 
2698*7c568831SAndroid Build Coastguard Worker     if (node == NULL) {
2699*7c568831SAndroid Build Coastguard Worker         Py_INCREF(Py_None);
2700*7c568831SAndroid Build Coastguard Worker         return (Py_None);
2701*7c568831SAndroid Build Coastguard Worker     }
2702*7c568831SAndroid Build Coastguard Worker     if (node->type == XML_DOCUMENT_NODE) {
2703*7c568831SAndroid Build Coastguard Worker         doc = (xmlDocPtr) node;
2704*7c568831SAndroid Build Coastguard Worker 	node = NULL;
2705*7c568831SAndroid Build Coastguard Worker #ifdef LIBXML_HTML_ENABLED
2706*7c568831SAndroid Build Coastguard Worker     } else if (node->type == XML_HTML_DOCUMENT_NODE) {
2707*7c568831SAndroid Build Coastguard Worker         doc = (xmlDocPtr) node;
2708*7c568831SAndroid Build Coastguard Worker 	node = NULL;
2709*7c568831SAndroid Build Coastguard Worker #endif
2710*7c568831SAndroid Build Coastguard Worker     } else {
2711*7c568831SAndroid Build Coastguard Worker         if (node->type == XML_NAMESPACE_DECL)
2712*7c568831SAndroid Build Coastguard Worker 	    doc = NULL;
2713*7c568831SAndroid Build Coastguard Worker 	else
2714*7c568831SAndroid Build Coastguard Worker             doc = node->doc;
2715*7c568831SAndroid Build Coastguard Worker         if ((doc == NULL) || (doc->type == XML_DOCUMENT_NODE)) {
2716*7c568831SAndroid Build Coastguard Worker #ifdef LIBXML_HTML_ENABLED
2717*7c568831SAndroid Build Coastguard Worker         } else if (doc->type == XML_HTML_DOCUMENT_NODE) {
2718*7c568831SAndroid Build Coastguard Worker #endif /* LIBXML_HTML_ENABLED */
2719*7c568831SAndroid Build Coastguard Worker         } else {
2720*7c568831SAndroid Build Coastguard Worker             Py_INCREF(Py_None);
2721*7c568831SAndroid Build Coastguard Worker             return (Py_None);
2722*7c568831SAndroid Build Coastguard Worker         }
2723*7c568831SAndroid Build Coastguard Worker     }
2724*7c568831SAndroid Build Coastguard Worker 
2725*7c568831SAndroid Build Coastguard Worker 
2726*7c568831SAndroid Build Coastguard Worker     buf = xmlBufferCreate();
2727*7c568831SAndroid Build Coastguard Worker     if (buf == NULL) {
2728*7c568831SAndroid Build Coastguard Worker 	Py_INCREF(Py_None);
2729*7c568831SAndroid Build Coastguard Worker 	return (Py_None);
2730*7c568831SAndroid Build Coastguard Worker     }
2731*7c568831SAndroid Build Coastguard Worker     if (format) options |= XML_SAVE_FORMAT;
2732*7c568831SAndroid Build Coastguard Worker     ctxt = xmlSaveToBuffer(buf, encoding, options);
2733*7c568831SAndroid Build Coastguard Worker     if (ctxt == NULL) {
2734*7c568831SAndroid Build Coastguard Worker 	xmlBufferFree(buf);
2735*7c568831SAndroid Build Coastguard Worker 	Py_INCREF(Py_None);
2736*7c568831SAndroid Build Coastguard Worker 	return (Py_None);
2737*7c568831SAndroid Build Coastguard Worker     }
2738*7c568831SAndroid Build Coastguard Worker     if (node == NULL)
2739*7c568831SAndroid Build Coastguard Worker 	xmlSaveDoc(ctxt, doc);
2740*7c568831SAndroid Build Coastguard Worker     else
2741*7c568831SAndroid Build Coastguard Worker 	xmlSaveTree(ctxt, node);
2742*7c568831SAndroid Build Coastguard Worker     xmlSaveClose(ctxt);
2743*7c568831SAndroid Build Coastguard Worker 
2744*7c568831SAndroid Build Coastguard Worker     c_retval = xmlBufferDetach(buf);
2745*7c568831SAndroid Build Coastguard Worker 
2746*7c568831SAndroid Build Coastguard Worker     xmlBufferFree(buf);
2747*7c568831SAndroid Build Coastguard Worker     py_retval = libxml_charPtrWrap((char *) c_retval);
2748*7c568831SAndroid Build Coastguard Worker 
2749*7c568831SAndroid Build Coastguard Worker     return (py_retval);
2750*7c568831SAndroid Build Coastguard Worker }
2751*7c568831SAndroid Build Coastguard Worker 
2752*7c568831SAndroid Build Coastguard Worker static PyObject *
libxml_saveNodeTo(ATTRIBUTE_UNUSED PyObject * self,PyObject * args)2753*7c568831SAndroid Build Coastguard Worker libxml_saveNodeTo(ATTRIBUTE_UNUSED PyObject * self, PyObject * args)
2754*7c568831SAndroid Build Coastguard Worker {
2755*7c568831SAndroid Build Coastguard Worker     PyObject *py_file = NULL;
2756*7c568831SAndroid Build Coastguard Worker     FILE *output;
2757*7c568831SAndroid Build Coastguard Worker     PyObject *pyobj_node;
2758*7c568831SAndroid Build Coastguard Worker     xmlNodePtr node;
2759*7c568831SAndroid Build Coastguard Worker     xmlDocPtr doc;
2760*7c568831SAndroid Build Coastguard Worker     const char *encoding;
2761*7c568831SAndroid Build Coastguard Worker     int format;
2762*7c568831SAndroid Build Coastguard Worker     int len;
2763*7c568831SAndroid Build Coastguard Worker     xmlOutputBufferPtr buf;
2764*7c568831SAndroid Build Coastguard Worker     xmlCharEncodingHandlerPtr handler = NULL;
2765*7c568831SAndroid Build Coastguard Worker 
2766*7c568831SAndroid Build Coastguard Worker     if (!PyArg_ParseTuple(args, (char *) "OOzi:serializeNode", &pyobj_node,
2767*7c568831SAndroid Build Coastguard Worker                           &py_file, &encoding, &format))
2768*7c568831SAndroid Build Coastguard Worker         return (NULL);
2769*7c568831SAndroid Build Coastguard Worker     node = (xmlNodePtr) PyxmlNode_Get(pyobj_node);
2770*7c568831SAndroid Build Coastguard Worker     if (node == NULL) {
2771*7c568831SAndroid Build Coastguard Worker         return (PyLong_FromLong((long) -1));
2772*7c568831SAndroid Build Coastguard Worker     }
2773*7c568831SAndroid Build Coastguard Worker     output = PyFile_Get(py_file);
2774*7c568831SAndroid Build Coastguard Worker     if (output == NULL) {
2775*7c568831SAndroid Build Coastguard Worker         return (PyLong_FromLong((long) -1));
2776*7c568831SAndroid Build Coastguard Worker     }
2777*7c568831SAndroid Build Coastguard Worker 
2778*7c568831SAndroid Build Coastguard Worker     if (node->type == XML_DOCUMENT_NODE) {
2779*7c568831SAndroid Build Coastguard Worker         doc = (xmlDocPtr) node;
2780*7c568831SAndroid Build Coastguard Worker     } else if (node->type == XML_HTML_DOCUMENT_NODE) {
2781*7c568831SAndroid Build Coastguard Worker         doc = (xmlDocPtr) node;
2782*7c568831SAndroid Build Coastguard Worker     } else {
2783*7c568831SAndroid Build Coastguard Worker         doc = node->doc;
2784*7c568831SAndroid Build Coastguard Worker     }
2785*7c568831SAndroid Build Coastguard Worker #ifdef LIBXML_HTML_ENABLED
2786*7c568831SAndroid Build Coastguard Worker     if (doc->type == XML_HTML_DOCUMENT_NODE) {
2787*7c568831SAndroid Build Coastguard Worker         if (encoding == NULL)
2788*7c568831SAndroid Build Coastguard Worker             encoding = (const char *) htmlGetMetaEncoding(doc);
2789*7c568831SAndroid Build Coastguard Worker     }
2790*7c568831SAndroid Build Coastguard Worker #endif /* LIBXML_HTML_ENABLED */
2791*7c568831SAndroid Build Coastguard Worker     if (encoding != NULL) {
2792*7c568831SAndroid Build Coastguard Worker         handler = xmlFindCharEncodingHandler(encoding);
2793*7c568831SAndroid Build Coastguard Worker         if (handler == NULL) {
2794*7c568831SAndroid Build Coastguard Worker             PyFile_Release(output);
2795*7c568831SAndroid Build Coastguard Worker             return (PyLong_FromLong((long) -1));
2796*7c568831SAndroid Build Coastguard Worker         }
2797*7c568831SAndroid Build Coastguard Worker     }
2798*7c568831SAndroid Build Coastguard Worker     if (doc->type == XML_HTML_DOCUMENT_NODE) {
2799*7c568831SAndroid Build Coastguard Worker         if (handler == NULL)
2800*7c568831SAndroid Build Coastguard Worker             handler = xmlFindCharEncodingHandler("HTML");
2801*7c568831SAndroid Build Coastguard Worker         if (handler == NULL)
2802*7c568831SAndroid Build Coastguard Worker             handler = xmlFindCharEncodingHandler("ascii");
2803*7c568831SAndroid Build Coastguard Worker     }
2804*7c568831SAndroid Build Coastguard Worker 
2805*7c568831SAndroid Build Coastguard Worker     buf = xmlOutputBufferCreateFile(output, handler);
2806*7c568831SAndroid Build Coastguard Worker     if (node->type == XML_DOCUMENT_NODE) {
2807*7c568831SAndroid Build Coastguard Worker         len = xmlSaveFormatFileTo(buf, doc, encoding, format);
2808*7c568831SAndroid Build Coastguard Worker #ifdef LIBXML_HTML_ENABLED
2809*7c568831SAndroid Build Coastguard Worker     } else if (node->type == XML_HTML_DOCUMENT_NODE) {
2810*7c568831SAndroid Build Coastguard Worker         htmlDocContentDumpFormatOutput(buf, doc, encoding, format);
2811*7c568831SAndroid Build Coastguard Worker         len = xmlOutputBufferClose(buf);
2812*7c568831SAndroid Build Coastguard Worker     } else if (doc->type == XML_HTML_DOCUMENT_NODE) {
2813*7c568831SAndroid Build Coastguard Worker         htmlNodeDumpFormatOutput(buf, doc, node, encoding, format);
2814*7c568831SAndroid Build Coastguard Worker         len = xmlOutputBufferClose(buf);
2815*7c568831SAndroid Build Coastguard Worker #endif /* LIBXML_HTML_ENABLED */
2816*7c568831SAndroid Build Coastguard Worker     } else {
2817*7c568831SAndroid Build Coastguard Worker         xmlNodeDumpOutput(buf, doc, node, 0, format, encoding);
2818*7c568831SAndroid Build Coastguard Worker         len = xmlOutputBufferClose(buf);
2819*7c568831SAndroid Build Coastguard Worker     }
2820*7c568831SAndroid Build Coastguard Worker     PyFile_Release(output);
2821*7c568831SAndroid Build Coastguard Worker     return (PyLong_FromLong((long) len));
2822*7c568831SAndroid Build Coastguard Worker }
2823*7c568831SAndroid Build Coastguard Worker #endif /* LIBXML_OUTPUT_ENABLED */
2824*7c568831SAndroid Build Coastguard Worker 
2825*7c568831SAndroid Build Coastguard Worker /************************************************************************
2826*7c568831SAndroid Build Coastguard Worker  *									*
2827*7c568831SAndroid Build Coastguard Worker  *			Extra stuff					*
2828*7c568831SAndroid Build Coastguard Worker  *									*
2829*7c568831SAndroid Build Coastguard Worker  ************************************************************************/
2830*7c568831SAndroid Build Coastguard Worker PyObject *
libxml_xmlNewNode(ATTRIBUTE_UNUSED PyObject * self,PyObject * args)2831*7c568831SAndroid Build Coastguard Worker libxml_xmlNewNode(ATTRIBUTE_UNUSED PyObject * self, PyObject * args)
2832*7c568831SAndroid Build Coastguard Worker {
2833*7c568831SAndroid Build Coastguard Worker     PyObject *py_retval;
2834*7c568831SAndroid Build Coastguard Worker     xmlChar *name;
2835*7c568831SAndroid Build Coastguard Worker     xmlNodePtr node;
2836*7c568831SAndroid Build Coastguard Worker 
2837*7c568831SAndroid Build Coastguard Worker     if (!PyArg_ParseTuple(args, (char *) "s:xmlNewNode", &name))
2838*7c568831SAndroid Build Coastguard Worker         return (NULL);
2839*7c568831SAndroid Build Coastguard Worker     node = (xmlNodePtr) xmlNewNode(NULL, name);
2840*7c568831SAndroid Build Coastguard Worker 
2841*7c568831SAndroid Build Coastguard Worker     if (node == NULL) {
2842*7c568831SAndroid Build Coastguard Worker         Py_INCREF(Py_None);
2843*7c568831SAndroid Build Coastguard Worker         return (Py_None);
2844*7c568831SAndroid Build Coastguard Worker     }
2845*7c568831SAndroid Build Coastguard Worker     py_retval = libxml_xmlNodePtrWrap(node);
2846*7c568831SAndroid Build Coastguard Worker     return (py_retval);
2847*7c568831SAndroid Build Coastguard Worker }
2848*7c568831SAndroid Build Coastguard Worker 
2849*7c568831SAndroid Build Coastguard Worker 
2850*7c568831SAndroid Build Coastguard Worker /************************************************************************
2851*7c568831SAndroid Build Coastguard Worker  *									*
2852*7c568831SAndroid Build Coastguard Worker  *			Local Catalog stuff				*
2853*7c568831SAndroid Build Coastguard Worker  *									*
2854*7c568831SAndroid Build Coastguard Worker  ************************************************************************/
2855*7c568831SAndroid Build Coastguard Worker 
2856*7c568831SAndroid Build Coastguard Worker #ifdef LIBXML_CATALOG_ENABLED
2857*7c568831SAndroid Build Coastguard Worker static PyObject *
libxml_addLocalCatalog(ATTRIBUTE_UNUSED PyObject * self,PyObject * args)2858*7c568831SAndroid Build Coastguard Worker libxml_addLocalCatalog(ATTRIBUTE_UNUSED PyObject * self, PyObject * args)
2859*7c568831SAndroid Build Coastguard Worker {
2860*7c568831SAndroid Build Coastguard Worker     xmlChar *URL;
2861*7c568831SAndroid Build Coastguard Worker     xmlParserCtxtPtr ctxt;
2862*7c568831SAndroid Build Coastguard Worker     PyObject *pyobj_ctxt;
2863*7c568831SAndroid Build Coastguard Worker 
2864*7c568831SAndroid Build Coastguard Worker     if (!PyArg_ParseTuple(args, (char *)"Os:addLocalCatalog", &pyobj_ctxt, &URL))
2865*7c568831SAndroid Build Coastguard Worker         return(NULL);
2866*7c568831SAndroid Build Coastguard Worker 
2867*7c568831SAndroid Build Coastguard Worker     ctxt = (xmlParserCtxtPtr) PyparserCtxt_Get(pyobj_ctxt);
2868*7c568831SAndroid Build Coastguard Worker 
2869*7c568831SAndroid Build Coastguard Worker     if (URL != NULL) {
2870*7c568831SAndroid Build Coastguard Worker         void *catalogs = xmlCtxtGetCatalogs(ctxt);
2871*7c568831SAndroid Build Coastguard Worker         xmlCtxtSetCatalogs(ctxt, xmlCatalogAddLocal(catalogs, URL));
2872*7c568831SAndroid Build Coastguard Worker     }
2873*7c568831SAndroid Build Coastguard Worker 
2874*7c568831SAndroid Build Coastguard Worker     Py_INCREF(Py_None);
2875*7c568831SAndroid Build Coastguard Worker     return (Py_None);
2876*7c568831SAndroid Build Coastguard Worker }
2877*7c568831SAndroid Build Coastguard Worker #endif /* LIBXML_CATALOG_ENABLED */
2878*7c568831SAndroid Build Coastguard Worker 
2879*7c568831SAndroid Build Coastguard Worker #ifdef LIBXML_SCHEMAS_ENABLED
2880*7c568831SAndroid Build Coastguard Worker 
2881*7c568831SAndroid Build Coastguard Worker /************************************************************************
2882*7c568831SAndroid Build Coastguard Worker  *                                                                      *
2883*7c568831SAndroid Build Coastguard Worker  * RelaxNG error handler registration                                   *
2884*7c568831SAndroid Build Coastguard Worker  *                                                                      *
2885*7c568831SAndroid Build Coastguard Worker  ************************************************************************/
2886*7c568831SAndroid Build Coastguard Worker 
2887*7c568831SAndroid Build Coastguard Worker typedef struct
2888*7c568831SAndroid Build Coastguard Worker {
2889*7c568831SAndroid Build Coastguard Worker     PyObject *warn;
2890*7c568831SAndroid Build Coastguard Worker     PyObject *error;
2891*7c568831SAndroid Build Coastguard Worker     PyObject *arg;
2892*7c568831SAndroid Build Coastguard Worker } xmlRelaxNGValidCtxtPyCtxt;
2893*7c568831SAndroid Build Coastguard Worker typedef xmlRelaxNGValidCtxtPyCtxt *xmlRelaxNGValidCtxtPyCtxtPtr;
2894*7c568831SAndroid Build Coastguard Worker 
2895*7c568831SAndroid Build Coastguard Worker static void
libxml_xmlRelaxNGValidityGenericErrorFuncHandler(void * ctx,char * str)2896*7c568831SAndroid Build Coastguard Worker libxml_xmlRelaxNGValidityGenericErrorFuncHandler(void *ctx, char *str)
2897*7c568831SAndroid Build Coastguard Worker {
2898*7c568831SAndroid Build Coastguard Worker     PyObject *list;
2899*7c568831SAndroid Build Coastguard Worker     PyObject *result;
2900*7c568831SAndroid Build Coastguard Worker     xmlRelaxNGValidCtxtPyCtxtPtr pyCtxt;
2901*7c568831SAndroid Build Coastguard Worker 
2902*7c568831SAndroid Build Coastguard Worker     pyCtxt = (xmlRelaxNGValidCtxtPyCtxtPtr)ctx;
2903*7c568831SAndroid Build Coastguard Worker 
2904*7c568831SAndroid Build Coastguard Worker     list = PyTuple_New(2);
2905*7c568831SAndroid Build Coastguard Worker     PyTuple_SetItem(list, 0, libxml_charPtrWrap(str));
2906*7c568831SAndroid Build Coastguard Worker     PyTuple_SetItem(list, 1, pyCtxt->arg);
2907*7c568831SAndroid Build Coastguard Worker     Py_XINCREF(pyCtxt->arg);
2908*7c568831SAndroid Build Coastguard Worker     result = PyObject_CallObject(pyCtxt->error, list);
2909*7c568831SAndroid Build Coastguard Worker     if (result == NULL)
2910*7c568831SAndroid Build Coastguard Worker     {
2911*7c568831SAndroid Build Coastguard Worker         /* TODO: manage for the exception to be propagated... */
2912*7c568831SAndroid Build Coastguard Worker         PyErr_Print();
2913*7c568831SAndroid Build Coastguard Worker     }
2914*7c568831SAndroid Build Coastguard Worker     Py_XDECREF(list);
2915*7c568831SAndroid Build Coastguard Worker     Py_XDECREF(result);
2916*7c568831SAndroid Build Coastguard Worker }
2917*7c568831SAndroid Build Coastguard Worker 
2918*7c568831SAndroid Build Coastguard Worker static void
libxml_xmlRelaxNGValidityGenericWarningFuncHandler(void * ctx,char * str)2919*7c568831SAndroid Build Coastguard Worker libxml_xmlRelaxNGValidityGenericWarningFuncHandler(void *ctx, char *str)
2920*7c568831SAndroid Build Coastguard Worker {
2921*7c568831SAndroid Build Coastguard Worker     PyObject *list;
2922*7c568831SAndroid Build Coastguard Worker     PyObject *result;
2923*7c568831SAndroid Build Coastguard Worker     xmlRelaxNGValidCtxtPyCtxtPtr pyCtxt;
2924*7c568831SAndroid Build Coastguard Worker 
2925*7c568831SAndroid Build Coastguard Worker     pyCtxt = (xmlRelaxNGValidCtxtPyCtxtPtr)ctx;
2926*7c568831SAndroid Build Coastguard Worker 
2927*7c568831SAndroid Build Coastguard Worker     list = PyTuple_New(2);
2928*7c568831SAndroid Build Coastguard Worker     PyTuple_SetItem(list, 0, libxml_charPtrWrap(str));
2929*7c568831SAndroid Build Coastguard Worker     PyTuple_SetItem(list, 1, pyCtxt->arg);
2930*7c568831SAndroid Build Coastguard Worker     Py_XINCREF(pyCtxt->arg);
2931*7c568831SAndroid Build Coastguard Worker     result = PyObject_CallObject(pyCtxt->warn, list);
2932*7c568831SAndroid Build Coastguard Worker     if (result == NULL)
2933*7c568831SAndroid Build Coastguard Worker     {
2934*7c568831SAndroid Build Coastguard Worker         /* TODO: manage for the exception to be propagated... */
2935*7c568831SAndroid Build Coastguard Worker         PyErr_Print();
2936*7c568831SAndroid Build Coastguard Worker     }
2937*7c568831SAndroid Build Coastguard Worker     Py_XDECREF(list);
2938*7c568831SAndroid Build Coastguard Worker     Py_XDECREF(result);
2939*7c568831SAndroid Build Coastguard Worker }
2940*7c568831SAndroid Build Coastguard Worker 
2941*7c568831SAndroid Build Coastguard Worker static void
libxml_xmlRelaxNGValidityErrorFunc(void * ctx,const char * msg,...)2942*7c568831SAndroid Build Coastguard Worker libxml_xmlRelaxNGValidityErrorFunc(void *ctx, const char *msg, ...)
2943*7c568831SAndroid Build Coastguard Worker {
2944*7c568831SAndroid Build Coastguard Worker     va_list ap;
2945*7c568831SAndroid Build Coastguard Worker 
2946*7c568831SAndroid Build Coastguard Worker     va_start(ap, msg);
2947*7c568831SAndroid Build Coastguard Worker     libxml_xmlRelaxNGValidityGenericErrorFuncHandler(ctx, libxml_buildMessage(msg, ap));
2948*7c568831SAndroid Build Coastguard Worker     va_end(ap);
2949*7c568831SAndroid Build Coastguard Worker }
2950*7c568831SAndroid Build Coastguard Worker 
2951*7c568831SAndroid Build Coastguard Worker static void
libxml_xmlRelaxNGValidityWarningFunc(void * ctx,const char * msg,...)2952*7c568831SAndroid Build Coastguard Worker libxml_xmlRelaxNGValidityWarningFunc(void *ctx, const char *msg, ...)
2953*7c568831SAndroid Build Coastguard Worker {
2954*7c568831SAndroid Build Coastguard Worker     va_list ap;
2955*7c568831SAndroid Build Coastguard Worker 
2956*7c568831SAndroid Build Coastguard Worker     va_start(ap, msg);
2957*7c568831SAndroid Build Coastguard Worker     libxml_xmlRelaxNGValidityGenericWarningFuncHandler(ctx, libxml_buildMessage(msg, ap));
2958*7c568831SAndroid Build Coastguard Worker     va_end(ap);
2959*7c568831SAndroid Build Coastguard Worker }
2960*7c568831SAndroid Build Coastguard Worker 
2961*7c568831SAndroid Build Coastguard Worker static PyObject *
libxml_xmlRelaxNGSetValidErrors(ATTRIBUTE_UNUSED PyObject * self,PyObject * args)2962*7c568831SAndroid Build Coastguard Worker libxml_xmlRelaxNGSetValidErrors(ATTRIBUTE_UNUSED PyObject * self, PyObject * args)
2963*7c568831SAndroid Build Coastguard Worker {
2964*7c568831SAndroid Build Coastguard Worker     PyObject *py_retval;
2965*7c568831SAndroid Build Coastguard Worker     PyObject *pyobj_error;
2966*7c568831SAndroid Build Coastguard Worker     PyObject *pyobj_warn;
2967*7c568831SAndroid Build Coastguard Worker     PyObject *pyobj_ctx;
2968*7c568831SAndroid Build Coastguard Worker     PyObject *pyobj_arg = Py_None;
2969*7c568831SAndroid Build Coastguard Worker     xmlRelaxNGValidCtxtPtr ctxt;
2970*7c568831SAndroid Build Coastguard Worker     xmlRelaxNGValidCtxtPyCtxtPtr pyCtxt;
2971*7c568831SAndroid Build Coastguard Worker 
2972*7c568831SAndroid Build Coastguard Worker     if (!PyArg_ParseTuple
2973*7c568831SAndroid Build Coastguard Worker         (args, (char *) "OOO|O:xmlRelaxNGSetValidErrors", &pyobj_ctx, &pyobj_error, &pyobj_warn, &pyobj_arg))
2974*7c568831SAndroid Build Coastguard Worker         return (NULL);
2975*7c568831SAndroid Build Coastguard Worker 
2976*7c568831SAndroid Build Coastguard Worker     ctxt = PyrelaxNgValidCtxt_Get(pyobj_ctx);
2977*7c568831SAndroid Build Coastguard Worker     if (xmlRelaxNGGetValidErrors(ctxt, NULL, NULL, (void **) &pyCtxt) == -1)
2978*7c568831SAndroid Build Coastguard Worker     {
2979*7c568831SAndroid Build Coastguard Worker         py_retval = libxml_intWrap(-1);
2980*7c568831SAndroid Build Coastguard Worker         return(py_retval);
2981*7c568831SAndroid Build Coastguard Worker     }
2982*7c568831SAndroid Build Coastguard Worker 
2983*7c568831SAndroid Build Coastguard Worker     if (pyCtxt == NULL)
2984*7c568831SAndroid Build Coastguard Worker     {
2985*7c568831SAndroid Build Coastguard Worker         /* first time to set the error handlers */
2986*7c568831SAndroid Build Coastguard Worker         pyCtxt = xmlMalloc(sizeof(xmlRelaxNGValidCtxtPyCtxt));
2987*7c568831SAndroid Build Coastguard Worker         if (pyCtxt == NULL) {
2988*7c568831SAndroid Build Coastguard Worker             py_retval = libxml_intWrap(-1);
2989*7c568831SAndroid Build Coastguard Worker             return(py_retval);
2990*7c568831SAndroid Build Coastguard Worker         }
2991*7c568831SAndroid Build Coastguard Worker         memset(pyCtxt, 0, sizeof(xmlRelaxNGValidCtxtPyCtxt));
2992*7c568831SAndroid Build Coastguard Worker     }
2993*7c568831SAndroid Build Coastguard Worker 
2994*7c568831SAndroid Build Coastguard Worker     /* TODO: check warn and error is a function ! */
2995*7c568831SAndroid Build Coastguard Worker     Py_XDECREF(pyCtxt->error);
2996*7c568831SAndroid Build Coastguard Worker     Py_XINCREF(pyobj_error);
2997*7c568831SAndroid Build Coastguard Worker     pyCtxt->error = pyobj_error;
2998*7c568831SAndroid Build Coastguard Worker 
2999*7c568831SAndroid Build Coastguard Worker     Py_XDECREF(pyCtxt->warn);
3000*7c568831SAndroid Build Coastguard Worker     Py_XINCREF(pyobj_warn);
3001*7c568831SAndroid Build Coastguard Worker     pyCtxt->warn = pyobj_warn;
3002*7c568831SAndroid Build Coastguard Worker 
3003*7c568831SAndroid Build Coastguard Worker     Py_XDECREF(pyCtxt->arg);
3004*7c568831SAndroid Build Coastguard Worker     Py_XINCREF(pyobj_arg);
3005*7c568831SAndroid Build Coastguard Worker     pyCtxt->arg = pyobj_arg;
3006*7c568831SAndroid Build Coastguard Worker 
3007*7c568831SAndroid Build Coastguard Worker     xmlRelaxNGSetValidErrors(ctxt, &libxml_xmlRelaxNGValidityErrorFunc, &libxml_xmlRelaxNGValidityWarningFunc, pyCtxt);
3008*7c568831SAndroid Build Coastguard Worker 
3009*7c568831SAndroid Build Coastguard Worker     py_retval = libxml_intWrap(1);
3010*7c568831SAndroid Build Coastguard Worker     return (py_retval);
3011*7c568831SAndroid Build Coastguard Worker }
3012*7c568831SAndroid Build Coastguard Worker 
3013*7c568831SAndroid Build Coastguard Worker static PyObject *
libxml_xmlRelaxNGFreeValidCtxt(ATTRIBUTE_UNUSED PyObject * self,PyObject * args)3014*7c568831SAndroid Build Coastguard Worker libxml_xmlRelaxNGFreeValidCtxt(ATTRIBUTE_UNUSED PyObject *self, PyObject *args) {
3015*7c568831SAndroid Build Coastguard Worker     xmlRelaxNGValidCtxtPtr ctxt;
3016*7c568831SAndroid Build Coastguard Worker     xmlRelaxNGValidCtxtPyCtxtPtr pyCtxt;
3017*7c568831SAndroid Build Coastguard Worker     PyObject *pyobj_ctxt;
3018*7c568831SAndroid Build Coastguard Worker 
3019*7c568831SAndroid Build Coastguard Worker     if (!PyArg_ParseTuple(args, (char *)"O:xmlRelaxNGFreeValidCtxt", &pyobj_ctxt))
3020*7c568831SAndroid Build Coastguard Worker         return(NULL);
3021*7c568831SAndroid Build Coastguard Worker     ctxt = (xmlRelaxNGValidCtxtPtr) PyrelaxNgValidCtxt_Get(pyobj_ctxt);
3022*7c568831SAndroid Build Coastguard Worker 
3023*7c568831SAndroid Build Coastguard Worker     if (xmlRelaxNGGetValidErrors(ctxt, NULL, NULL, (void **) &pyCtxt) == 0)
3024*7c568831SAndroid Build Coastguard Worker     {
3025*7c568831SAndroid Build Coastguard Worker         if (pyCtxt != NULL)
3026*7c568831SAndroid Build Coastguard Worker         {
3027*7c568831SAndroid Build Coastguard Worker             Py_XDECREF(pyCtxt->error);
3028*7c568831SAndroid Build Coastguard Worker             Py_XDECREF(pyCtxt->warn);
3029*7c568831SAndroid Build Coastguard Worker             Py_XDECREF(pyCtxt->arg);
3030*7c568831SAndroid Build Coastguard Worker             xmlFree(pyCtxt);
3031*7c568831SAndroid Build Coastguard Worker         }
3032*7c568831SAndroid Build Coastguard Worker     }
3033*7c568831SAndroid Build Coastguard Worker 
3034*7c568831SAndroid Build Coastguard Worker     xmlRelaxNGFreeValidCtxt(ctxt);
3035*7c568831SAndroid Build Coastguard Worker     Py_INCREF(Py_None);
3036*7c568831SAndroid Build Coastguard Worker     return(Py_None);
3037*7c568831SAndroid Build Coastguard Worker }
3038*7c568831SAndroid Build Coastguard Worker 
3039*7c568831SAndroid Build Coastguard Worker typedef struct
3040*7c568831SAndroid Build Coastguard Worker {
3041*7c568831SAndroid Build Coastguard Worker 	PyObject *warn;
3042*7c568831SAndroid Build Coastguard Worker 	PyObject *error;
3043*7c568831SAndroid Build Coastguard Worker 	PyObject *arg;
3044*7c568831SAndroid Build Coastguard Worker } xmlSchemaValidCtxtPyCtxt;
3045*7c568831SAndroid Build Coastguard Worker typedef xmlSchemaValidCtxtPyCtxt *xmlSchemaValidCtxtPyCtxtPtr;
3046*7c568831SAndroid Build Coastguard Worker 
3047*7c568831SAndroid Build Coastguard Worker static void
libxml_xmlSchemaValidityGenericErrorFuncHandler(void * ctx,char * str)3048*7c568831SAndroid Build Coastguard Worker libxml_xmlSchemaValidityGenericErrorFuncHandler(void *ctx, char *str)
3049*7c568831SAndroid Build Coastguard Worker {
3050*7c568831SAndroid Build Coastguard Worker 	PyObject *list;
3051*7c568831SAndroid Build Coastguard Worker 	PyObject *result;
3052*7c568831SAndroid Build Coastguard Worker 	xmlSchemaValidCtxtPyCtxtPtr pyCtxt;
3053*7c568831SAndroid Build Coastguard Worker 
3054*7c568831SAndroid Build Coastguard Worker 	pyCtxt = (xmlSchemaValidCtxtPyCtxtPtr) ctx;
3055*7c568831SAndroid Build Coastguard Worker 
3056*7c568831SAndroid Build Coastguard Worker 	list = PyTuple_New(2);
3057*7c568831SAndroid Build Coastguard Worker 	PyTuple_SetItem(list, 0, libxml_charPtrWrap(str));
3058*7c568831SAndroid Build Coastguard Worker 	PyTuple_SetItem(list, 1, pyCtxt->arg);
3059*7c568831SAndroid Build Coastguard Worker 	Py_XINCREF(pyCtxt->arg);
3060*7c568831SAndroid Build Coastguard Worker 	result = PyObject_CallObject(pyCtxt->error, list);
3061*7c568831SAndroid Build Coastguard Worker 	if (result == NULL)
3062*7c568831SAndroid Build Coastguard Worker 	{
3063*7c568831SAndroid Build Coastguard Worker 		/* TODO: manage for the exception to be propagated... */
3064*7c568831SAndroid Build Coastguard Worker 		PyErr_Print();
3065*7c568831SAndroid Build Coastguard Worker 	}
3066*7c568831SAndroid Build Coastguard Worker 	Py_XDECREF(list);
3067*7c568831SAndroid Build Coastguard Worker 	Py_XDECREF(result);
3068*7c568831SAndroid Build Coastguard Worker }
3069*7c568831SAndroid Build Coastguard Worker 
3070*7c568831SAndroid Build Coastguard Worker static void
libxml_xmlSchemaValidityGenericWarningFuncHandler(void * ctx,char * str)3071*7c568831SAndroid Build Coastguard Worker libxml_xmlSchemaValidityGenericWarningFuncHandler(void *ctx, char *str)
3072*7c568831SAndroid Build Coastguard Worker {
3073*7c568831SAndroid Build Coastguard Worker 	PyObject *list;
3074*7c568831SAndroid Build Coastguard Worker 	PyObject *result;
3075*7c568831SAndroid Build Coastguard Worker 	xmlSchemaValidCtxtPyCtxtPtr pyCtxt;
3076*7c568831SAndroid Build Coastguard Worker 
3077*7c568831SAndroid Build Coastguard Worker 	pyCtxt = (xmlSchemaValidCtxtPyCtxtPtr) ctx;
3078*7c568831SAndroid Build Coastguard Worker 
3079*7c568831SAndroid Build Coastguard Worker 	list = PyTuple_New(2);
3080*7c568831SAndroid Build Coastguard Worker 	PyTuple_SetItem(list, 0, libxml_charPtrWrap(str));
3081*7c568831SAndroid Build Coastguard Worker 	PyTuple_SetItem(list, 1, pyCtxt->arg);
3082*7c568831SAndroid Build Coastguard Worker 	Py_XINCREF(pyCtxt->arg);
3083*7c568831SAndroid Build Coastguard Worker 	result = PyObject_CallObject(pyCtxt->warn, list);
3084*7c568831SAndroid Build Coastguard Worker 	if (result == NULL)
3085*7c568831SAndroid Build Coastguard Worker 	{
3086*7c568831SAndroid Build Coastguard Worker 		/* TODO: manage for the exception to be propagated... */
3087*7c568831SAndroid Build Coastguard Worker 		PyErr_Print();
3088*7c568831SAndroid Build Coastguard Worker 	}
3089*7c568831SAndroid Build Coastguard Worker 	Py_XDECREF(list);
3090*7c568831SAndroid Build Coastguard Worker 	Py_XDECREF(result);
3091*7c568831SAndroid Build Coastguard Worker }
3092*7c568831SAndroid Build Coastguard Worker 
3093*7c568831SAndroid Build Coastguard Worker static void
libxml_xmlSchemaValidityErrorFunc(void * ctx,const char * msg,...)3094*7c568831SAndroid Build Coastguard Worker libxml_xmlSchemaValidityErrorFunc(void *ctx, const char *msg, ...)
3095*7c568831SAndroid Build Coastguard Worker {
3096*7c568831SAndroid Build Coastguard Worker 	va_list ap;
3097*7c568831SAndroid Build Coastguard Worker 
3098*7c568831SAndroid Build Coastguard Worker 	va_start(ap, msg);
3099*7c568831SAndroid Build Coastguard Worker 	libxml_xmlSchemaValidityGenericErrorFuncHandler(ctx, libxml_buildMessage(msg, ap));
3100*7c568831SAndroid Build Coastguard Worker 	va_end(ap);
3101*7c568831SAndroid Build Coastguard Worker }
3102*7c568831SAndroid Build Coastguard Worker 
3103*7c568831SAndroid Build Coastguard Worker static void
libxml_xmlSchemaValidityWarningFunc(void * ctx,const char * msg,...)3104*7c568831SAndroid Build Coastguard Worker libxml_xmlSchemaValidityWarningFunc(void *ctx, const char *msg, ...)
3105*7c568831SAndroid Build Coastguard Worker {
3106*7c568831SAndroid Build Coastguard Worker 	va_list ap;
3107*7c568831SAndroid Build Coastguard Worker 
3108*7c568831SAndroid Build Coastguard Worker 	va_start(ap, msg);
3109*7c568831SAndroid Build Coastguard Worker 	libxml_xmlSchemaValidityGenericWarningFuncHandler(ctx, libxml_buildMessage(msg, ap));
3110*7c568831SAndroid Build Coastguard Worker 	va_end(ap);
3111*7c568831SAndroid Build Coastguard Worker }
3112*7c568831SAndroid Build Coastguard Worker 
3113*7c568831SAndroid Build Coastguard Worker PyObject *
libxml_xmlSchemaSetValidErrors(ATTRIBUTE_UNUSED PyObject * self,PyObject * args)3114*7c568831SAndroid Build Coastguard Worker libxml_xmlSchemaSetValidErrors(ATTRIBUTE_UNUSED PyObject * self, PyObject * args)
3115*7c568831SAndroid Build Coastguard Worker {
3116*7c568831SAndroid Build Coastguard Worker 	PyObject *py_retval;
3117*7c568831SAndroid Build Coastguard Worker 	PyObject *pyobj_error;
3118*7c568831SAndroid Build Coastguard Worker 	PyObject *pyobj_warn;
3119*7c568831SAndroid Build Coastguard Worker 	PyObject *pyobj_ctx;
3120*7c568831SAndroid Build Coastguard Worker 	PyObject *pyobj_arg = Py_None;
3121*7c568831SAndroid Build Coastguard Worker 	xmlSchemaValidCtxtPtr ctxt;
3122*7c568831SAndroid Build Coastguard Worker 	xmlSchemaValidCtxtPyCtxtPtr pyCtxt;
3123*7c568831SAndroid Build Coastguard Worker 
3124*7c568831SAndroid Build Coastguard Worker 	if (!PyArg_ParseTuple
3125*7c568831SAndroid Build Coastguard Worker 		(args, (char *) "OOO|O:xmlSchemaSetValidErrors", &pyobj_ctx, &pyobj_error, &pyobj_warn, &pyobj_arg))
3126*7c568831SAndroid Build Coastguard Worker 		return (NULL);
3127*7c568831SAndroid Build Coastguard Worker 
3128*7c568831SAndroid Build Coastguard Worker 	ctxt = PySchemaValidCtxt_Get(pyobj_ctx);
3129*7c568831SAndroid Build Coastguard Worker 	if (xmlSchemaGetValidErrors(ctxt, NULL, NULL, (void **) &pyCtxt) == -1)
3130*7c568831SAndroid Build Coastguard Worker 	{
3131*7c568831SAndroid Build Coastguard Worker 		py_retval = libxml_intWrap(-1);
3132*7c568831SAndroid Build Coastguard Worker 		return(py_retval);
3133*7c568831SAndroid Build Coastguard Worker 	}
3134*7c568831SAndroid Build Coastguard Worker 
3135*7c568831SAndroid Build Coastguard Worker 	if (pyCtxt == NULL)
3136*7c568831SAndroid Build Coastguard Worker 	{
3137*7c568831SAndroid Build Coastguard Worker 		/* first time to set the error handlers */
3138*7c568831SAndroid Build Coastguard Worker 		pyCtxt = xmlMalloc(sizeof(xmlSchemaValidCtxtPyCtxt));
3139*7c568831SAndroid Build Coastguard Worker 		if (pyCtxt == NULL) {
3140*7c568831SAndroid Build Coastguard Worker 			py_retval = libxml_intWrap(-1);
3141*7c568831SAndroid Build Coastguard Worker 			return(py_retval);
3142*7c568831SAndroid Build Coastguard Worker 		}
3143*7c568831SAndroid Build Coastguard Worker 		memset(pyCtxt, 0, sizeof(xmlSchemaValidCtxtPyCtxt));
3144*7c568831SAndroid Build Coastguard Worker 	}
3145*7c568831SAndroid Build Coastguard Worker 
3146*7c568831SAndroid Build Coastguard Worker 	/* TODO: check warn and error is a function ! */
3147*7c568831SAndroid Build Coastguard Worker 	Py_XDECREF(pyCtxt->error);
3148*7c568831SAndroid Build Coastguard Worker 	Py_XINCREF(pyobj_error);
3149*7c568831SAndroid Build Coastguard Worker 	pyCtxt->error = pyobj_error;
3150*7c568831SAndroid Build Coastguard Worker 
3151*7c568831SAndroid Build Coastguard Worker 	Py_XDECREF(pyCtxt->warn);
3152*7c568831SAndroid Build Coastguard Worker 	Py_XINCREF(pyobj_warn);
3153*7c568831SAndroid Build Coastguard Worker 	pyCtxt->warn = pyobj_warn;
3154*7c568831SAndroid Build Coastguard Worker 
3155*7c568831SAndroid Build Coastguard Worker 	Py_XDECREF(pyCtxt->arg);
3156*7c568831SAndroid Build Coastguard Worker 	Py_XINCREF(pyobj_arg);
3157*7c568831SAndroid Build Coastguard Worker 	pyCtxt->arg = pyobj_arg;
3158*7c568831SAndroid Build Coastguard Worker 
3159*7c568831SAndroid Build Coastguard Worker 	xmlSchemaSetValidErrors(ctxt, &libxml_xmlSchemaValidityErrorFunc, &libxml_xmlSchemaValidityWarningFunc, pyCtxt);
3160*7c568831SAndroid Build Coastguard Worker 
3161*7c568831SAndroid Build Coastguard Worker 	py_retval = libxml_intWrap(1);
3162*7c568831SAndroid Build Coastguard Worker 	return(py_retval);
3163*7c568831SAndroid Build Coastguard Worker }
3164*7c568831SAndroid Build Coastguard Worker 
3165*7c568831SAndroid Build Coastguard Worker static PyObject *
libxml_xmlSchemaFreeValidCtxt(ATTRIBUTE_UNUSED PyObject * self,PyObject * args)3166*7c568831SAndroid Build Coastguard Worker libxml_xmlSchemaFreeValidCtxt(ATTRIBUTE_UNUSED PyObject * self, PyObject * args)
3167*7c568831SAndroid Build Coastguard Worker {
3168*7c568831SAndroid Build Coastguard Worker 	xmlSchemaValidCtxtPtr ctxt;
3169*7c568831SAndroid Build Coastguard Worker 	xmlSchemaValidCtxtPyCtxtPtr pyCtxt;
3170*7c568831SAndroid Build Coastguard Worker 	PyObject *pyobj_ctxt;
3171*7c568831SAndroid Build Coastguard Worker 
3172*7c568831SAndroid Build Coastguard Worker 	if (!PyArg_ParseTuple(args, (char *)"O:xmlSchemaFreeValidCtxt", &pyobj_ctxt))
3173*7c568831SAndroid Build Coastguard Worker 		return(NULL);
3174*7c568831SAndroid Build Coastguard Worker 	ctxt = (xmlSchemaValidCtxtPtr) PySchemaValidCtxt_Get(pyobj_ctxt);
3175*7c568831SAndroid Build Coastguard Worker 
3176*7c568831SAndroid Build Coastguard Worker 	if (xmlSchemaGetValidErrors(ctxt, NULL, NULL, (void **) &pyCtxt) == 0)
3177*7c568831SAndroid Build Coastguard Worker 	{
3178*7c568831SAndroid Build Coastguard Worker 		if (pyCtxt != NULL)
3179*7c568831SAndroid Build Coastguard Worker 		{
3180*7c568831SAndroid Build Coastguard Worker 			Py_XDECREF(pyCtxt->error);
3181*7c568831SAndroid Build Coastguard Worker 			Py_XDECREF(pyCtxt->warn);
3182*7c568831SAndroid Build Coastguard Worker 			Py_XDECREF(pyCtxt->arg);
3183*7c568831SAndroid Build Coastguard Worker 			xmlFree(pyCtxt);
3184*7c568831SAndroid Build Coastguard Worker 		}
3185*7c568831SAndroid Build Coastguard Worker 	}
3186*7c568831SAndroid Build Coastguard Worker 
3187*7c568831SAndroid Build Coastguard Worker 	xmlSchemaFreeValidCtxt(ctxt);
3188*7c568831SAndroid Build Coastguard Worker 	Py_INCREF(Py_None);
3189*7c568831SAndroid Build Coastguard Worker 	return(Py_None);
3190*7c568831SAndroid Build Coastguard Worker }
3191*7c568831SAndroid Build Coastguard Worker 
3192*7c568831SAndroid Build Coastguard Worker #endif
3193*7c568831SAndroid Build Coastguard Worker 
3194*7c568831SAndroid Build Coastguard Worker #ifdef LIBXML_C14N_ENABLED
3195*7c568831SAndroid Build Coastguard Worker #ifdef LIBXML_OUTPUT_ENABLED
3196*7c568831SAndroid Build Coastguard Worker 
3197*7c568831SAndroid Build Coastguard Worker /************************************************************************
3198*7c568831SAndroid Build Coastguard Worker  *                                                                      *
3199*7c568831SAndroid Build Coastguard Worker  * XML Canonicalization c14n                                            *
3200*7c568831SAndroid Build Coastguard Worker  *                                                                      *
3201*7c568831SAndroid Build Coastguard Worker  ************************************************************************/
3202*7c568831SAndroid Build Coastguard Worker 
3203*7c568831SAndroid Build Coastguard Worker static int
PyxmlNodeSet_Convert(PyObject * py_nodeset,xmlNodeSetPtr * result)3204*7c568831SAndroid Build Coastguard Worker PyxmlNodeSet_Convert(PyObject *py_nodeset, xmlNodeSetPtr *result)
3205*7c568831SAndroid Build Coastguard Worker {
3206*7c568831SAndroid Build Coastguard Worker     xmlNodeSetPtr nodeSet;
3207*7c568831SAndroid Build Coastguard Worker     int is_tuple = 0;
3208*7c568831SAndroid Build Coastguard Worker 
3209*7c568831SAndroid Build Coastguard Worker     if (PyTuple_Check(py_nodeset))
3210*7c568831SAndroid Build Coastguard Worker         is_tuple = 1;
3211*7c568831SAndroid Build Coastguard Worker     else if (PyList_Check(py_nodeset))
3212*7c568831SAndroid Build Coastguard Worker         is_tuple = 0;
3213*7c568831SAndroid Build Coastguard Worker     else if (py_nodeset == Py_None) {
3214*7c568831SAndroid Build Coastguard Worker         *result = NULL;
3215*7c568831SAndroid Build Coastguard Worker         return 0;
3216*7c568831SAndroid Build Coastguard Worker     }
3217*7c568831SAndroid Build Coastguard Worker     else {
3218*7c568831SAndroid Build Coastguard Worker         PyErr_SetString(PyExc_TypeError,
3219*7c568831SAndroid Build Coastguard Worker                         "must be a tuple or list of nodes.");
3220*7c568831SAndroid Build Coastguard Worker         return -1;
3221*7c568831SAndroid Build Coastguard Worker     }
3222*7c568831SAndroid Build Coastguard Worker 
3223*7c568831SAndroid Build Coastguard Worker     nodeSet = (xmlNodeSetPtr) xmlMalloc(sizeof(xmlNodeSet));
3224*7c568831SAndroid Build Coastguard Worker     if (nodeSet == NULL) {
3225*7c568831SAndroid Build Coastguard Worker         PyErr_SetString(PyExc_MemoryError, "");
3226*7c568831SAndroid Build Coastguard Worker         return -1;
3227*7c568831SAndroid Build Coastguard Worker     }
3228*7c568831SAndroid Build Coastguard Worker 
3229*7c568831SAndroid Build Coastguard Worker     nodeSet->nodeNr = 0;
3230*7c568831SAndroid Build Coastguard Worker     nodeSet->nodeMax = (is_tuple
3231*7c568831SAndroid Build Coastguard Worker                         ? PyTuple_GET_SIZE(py_nodeset)
3232*7c568831SAndroid Build Coastguard Worker                         : PyList_GET_SIZE(py_nodeset));
3233*7c568831SAndroid Build Coastguard Worker     nodeSet->nodeTab
3234*7c568831SAndroid Build Coastguard Worker         = (xmlNodePtr *) xmlMalloc (nodeSet->nodeMax
3235*7c568831SAndroid Build Coastguard Worker                                     * sizeof(xmlNodePtr));
3236*7c568831SAndroid Build Coastguard Worker     if (nodeSet->nodeTab == NULL) {
3237*7c568831SAndroid Build Coastguard Worker         xmlFree(nodeSet);
3238*7c568831SAndroid Build Coastguard Worker         PyErr_SetString(PyExc_MemoryError, "");
3239*7c568831SAndroid Build Coastguard Worker         return -1;
3240*7c568831SAndroid Build Coastguard Worker     }
3241*7c568831SAndroid Build Coastguard Worker     memset(nodeSet->nodeTab, 0 ,
3242*7c568831SAndroid Build Coastguard Worker            nodeSet->nodeMax * sizeof(xmlNodePtr));
3243*7c568831SAndroid Build Coastguard Worker 
3244*7c568831SAndroid Build Coastguard Worker     {
3245*7c568831SAndroid Build Coastguard Worker         int idx;
3246*7c568831SAndroid Build Coastguard Worker         for (idx=0; idx < nodeSet->nodeMax; ++idx) {
3247*7c568831SAndroid Build Coastguard Worker             xmlNodePtr pynode =
3248*7c568831SAndroid Build Coastguard Worker                 PyxmlNode_Get (is_tuple
3249*7c568831SAndroid Build Coastguard Worker                                ? PyTuple_GET_ITEM(py_nodeset, idx)
3250*7c568831SAndroid Build Coastguard Worker                                : PyList_GET_ITEM(py_nodeset, idx));
3251*7c568831SAndroid Build Coastguard Worker             if (pynode)
3252*7c568831SAndroid Build Coastguard Worker                 nodeSet->nodeTab[nodeSet->nodeNr++] = pynode;
3253*7c568831SAndroid Build Coastguard Worker         }
3254*7c568831SAndroid Build Coastguard Worker     }
3255*7c568831SAndroid Build Coastguard Worker     *result = nodeSet;
3256*7c568831SAndroid Build Coastguard Worker     return 0;
3257*7c568831SAndroid Build Coastguard Worker }
3258*7c568831SAndroid Build Coastguard Worker 
3259*7c568831SAndroid Build Coastguard Worker static int
PystringSet_Convert(PyObject * py_strings,xmlChar *** result)3260*7c568831SAndroid Build Coastguard Worker PystringSet_Convert(PyObject *py_strings, xmlChar *** result)
3261*7c568831SAndroid Build Coastguard Worker {
3262*7c568831SAndroid Build Coastguard Worker     /* NOTE: the array should be freed, but the strings are shared
3263*7c568831SAndroid Build Coastguard Worker        with the python strings and so must not be freed. */
3264*7c568831SAndroid Build Coastguard Worker 
3265*7c568831SAndroid Build Coastguard Worker     xmlChar ** strings;
3266*7c568831SAndroid Build Coastguard Worker     int is_tuple = 0;
3267*7c568831SAndroid Build Coastguard Worker     int count;
3268*7c568831SAndroid Build Coastguard Worker     int init_index = 0;
3269*7c568831SAndroid Build Coastguard Worker 
3270*7c568831SAndroid Build Coastguard Worker     if (PyTuple_Check(py_strings))
3271*7c568831SAndroid Build Coastguard Worker         is_tuple = 1;
3272*7c568831SAndroid Build Coastguard Worker     else if (PyList_Check(py_strings))
3273*7c568831SAndroid Build Coastguard Worker         is_tuple = 0;
3274*7c568831SAndroid Build Coastguard Worker     else if (py_strings == Py_None) {
3275*7c568831SAndroid Build Coastguard Worker         *result = NULL;
3276*7c568831SAndroid Build Coastguard Worker         return 0;
3277*7c568831SAndroid Build Coastguard Worker     }
3278*7c568831SAndroid Build Coastguard Worker     else {
3279*7c568831SAndroid Build Coastguard Worker         PyErr_SetString(PyExc_TypeError,
3280*7c568831SAndroid Build Coastguard Worker                         "must be a tuple or list of strings.");
3281*7c568831SAndroid Build Coastguard Worker         return -1;
3282*7c568831SAndroid Build Coastguard Worker     }
3283*7c568831SAndroid Build Coastguard Worker 
3284*7c568831SAndroid Build Coastguard Worker     count = (is_tuple
3285*7c568831SAndroid Build Coastguard Worker              ? PyTuple_GET_SIZE(py_strings)
3286*7c568831SAndroid Build Coastguard Worker              : PyList_GET_SIZE(py_strings));
3287*7c568831SAndroid Build Coastguard Worker 
3288*7c568831SAndroid Build Coastguard Worker     strings = (xmlChar **) xmlMalloc(sizeof(xmlChar *) * count);
3289*7c568831SAndroid Build Coastguard Worker 
3290*7c568831SAndroid Build Coastguard Worker     if (strings == NULL) {
3291*7c568831SAndroid Build Coastguard Worker         PyErr_SetString(PyExc_MemoryError, "");
3292*7c568831SAndroid Build Coastguard Worker         return -1;
3293*7c568831SAndroid Build Coastguard Worker     }
3294*7c568831SAndroid Build Coastguard Worker 
3295*7c568831SAndroid Build Coastguard Worker     memset(strings, 0 , sizeof(xmlChar *) * count);
3296*7c568831SAndroid Build Coastguard Worker 
3297*7c568831SAndroid Build Coastguard Worker     {
3298*7c568831SAndroid Build Coastguard Worker         int idx;
3299*7c568831SAndroid Build Coastguard Worker         for (idx=0; idx < count; ++idx) {
3300*7c568831SAndroid Build Coastguard Worker             char* s = PyBytes_AsString
3301*7c568831SAndroid Build Coastguard Worker                 (is_tuple
3302*7c568831SAndroid Build Coastguard Worker                  ? PyTuple_GET_ITEM(py_strings, idx)
3303*7c568831SAndroid Build Coastguard Worker                  : PyList_GET_ITEM(py_strings, idx));
3304*7c568831SAndroid Build Coastguard Worker             if (s)
3305*7c568831SAndroid Build Coastguard Worker                 strings[init_index++] = (xmlChar *)s;
3306*7c568831SAndroid Build Coastguard Worker             else {
3307*7c568831SAndroid Build Coastguard Worker                 xmlFree(strings);
3308*7c568831SAndroid Build Coastguard Worker                 PyErr_SetString(PyExc_TypeError,
3309*7c568831SAndroid Build Coastguard Worker                                 "must be a tuple or list of strings.");
3310*7c568831SAndroid Build Coastguard Worker                 return -1;
3311*7c568831SAndroid Build Coastguard Worker             }
3312*7c568831SAndroid Build Coastguard Worker         }
3313*7c568831SAndroid Build Coastguard Worker     }
3314*7c568831SAndroid Build Coastguard Worker 
3315*7c568831SAndroid Build Coastguard Worker     *result = strings;
3316*7c568831SAndroid Build Coastguard Worker     return 0;
3317*7c568831SAndroid Build Coastguard Worker }
3318*7c568831SAndroid Build Coastguard Worker 
3319*7c568831SAndroid Build Coastguard Worker static PyObject *
libxml_C14NDocDumpMemory(ATTRIBUTE_UNUSED PyObject * self,PyObject * args)3320*7c568831SAndroid Build Coastguard Worker libxml_C14NDocDumpMemory(ATTRIBUTE_UNUSED PyObject * self,
3321*7c568831SAndroid Build Coastguard Worker                          PyObject * args)
3322*7c568831SAndroid Build Coastguard Worker {
3323*7c568831SAndroid Build Coastguard Worker     PyObject *py_retval = NULL;
3324*7c568831SAndroid Build Coastguard Worker 
3325*7c568831SAndroid Build Coastguard Worker     PyObject *pyobj_doc;
3326*7c568831SAndroid Build Coastguard Worker     PyObject *pyobj_nodes;
3327*7c568831SAndroid Build Coastguard Worker     int exclusive;
3328*7c568831SAndroid Build Coastguard Worker     PyObject *pyobj_prefixes;
3329*7c568831SAndroid Build Coastguard Worker     int with_comments;
3330*7c568831SAndroid Build Coastguard Worker 
3331*7c568831SAndroid Build Coastguard Worker     xmlDocPtr doc;
3332*7c568831SAndroid Build Coastguard Worker     xmlNodeSetPtr nodes;
3333*7c568831SAndroid Build Coastguard Worker     xmlChar **prefixes = NULL;
3334*7c568831SAndroid Build Coastguard Worker     xmlChar *doc_txt;
3335*7c568831SAndroid Build Coastguard Worker 
3336*7c568831SAndroid Build Coastguard Worker     int result;
3337*7c568831SAndroid Build Coastguard Worker 
3338*7c568831SAndroid Build Coastguard Worker     if (!PyArg_ParseTuple(args, (char *) "OOiOi:C14NDocDumpMemory",
3339*7c568831SAndroid Build Coastguard Worker                           &pyobj_doc,
3340*7c568831SAndroid Build Coastguard Worker                           &pyobj_nodes,
3341*7c568831SAndroid Build Coastguard Worker                           &exclusive,
3342*7c568831SAndroid Build Coastguard Worker                           &pyobj_prefixes,
3343*7c568831SAndroid Build Coastguard Worker                           &with_comments))
3344*7c568831SAndroid Build Coastguard Worker         return (NULL);
3345*7c568831SAndroid Build Coastguard Worker 
3346*7c568831SAndroid Build Coastguard Worker     doc = (xmlDocPtr) PyxmlNode_Get(pyobj_doc);
3347*7c568831SAndroid Build Coastguard Worker     if (!doc) {
3348*7c568831SAndroid Build Coastguard Worker         PyErr_SetString(PyExc_TypeError, "bad document.");
3349*7c568831SAndroid Build Coastguard Worker         return NULL;
3350*7c568831SAndroid Build Coastguard Worker     }
3351*7c568831SAndroid Build Coastguard Worker 
3352*7c568831SAndroid Build Coastguard Worker     result = PyxmlNodeSet_Convert(pyobj_nodes, &nodes);
3353*7c568831SAndroid Build Coastguard Worker     if (result < 0) return NULL;
3354*7c568831SAndroid Build Coastguard Worker 
3355*7c568831SAndroid Build Coastguard Worker     if (exclusive) {
3356*7c568831SAndroid Build Coastguard Worker         result = PystringSet_Convert(pyobj_prefixes, &prefixes);
3357*7c568831SAndroid Build Coastguard Worker         if (result < 0) {
3358*7c568831SAndroid Build Coastguard Worker             if (nodes) {
3359*7c568831SAndroid Build Coastguard Worker                 xmlFree(nodes->nodeTab);
3360*7c568831SAndroid Build Coastguard Worker                 xmlFree(nodes);
3361*7c568831SAndroid Build Coastguard Worker             }
3362*7c568831SAndroid Build Coastguard Worker             return NULL;
3363*7c568831SAndroid Build Coastguard Worker         }
3364*7c568831SAndroid Build Coastguard Worker     }
3365*7c568831SAndroid Build Coastguard Worker 
3366*7c568831SAndroid Build Coastguard Worker     result = xmlC14NDocDumpMemory(doc,
3367*7c568831SAndroid Build Coastguard Worker                                   nodes,
3368*7c568831SAndroid Build Coastguard Worker                                   exclusive,
3369*7c568831SAndroid Build Coastguard Worker                                   prefixes,
3370*7c568831SAndroid Build Coastguard Worker                                   with_comments,
3371*7c568831SAndroid Build Coastguard Worker                                   &doc_txt);
3372*7c568831SAndroid Build Coastguard Worker 
3373*7c568831SAndroid Build Coastguard Worker     if (nodes) {
3374*7c568831SAndroid Build Coastguard Worker         xmlFree(nodes->nodeTab);
3375*7c568831SAndroid Build Coastguard Worker         xmlFree(nodes);
3376*7c568831SAndroid Build Coastguard Worker     }
3377*7c568831SAndroid Build Coastguard Worker     if (prefixes) {
3378*7c568831SAndroid Build Coastguard Worker         xmlChar ** idx = prefixes;
3379*7c568831SAndroid Build Coastguard Worker         while (*idx) xmlFree(*(idx++));
3380*7c568831SAndroid Build Coastguard Worker         xmlFree(prefixes);
3381*7c568831SAndroid Build Coastguard Worker     }
3382*7c568831SAndroid Build Coastguard Worker 
3383*7c568831SAndroid Build Coastguard Worker     if (result < 0) {
3384*7c568831SAndroid Build Coastguard Worker         PyErr_SetString(PyExc_Exception,
3385*7c568831SAndroid Build Coastguard Worker                         "libxml2 xmlC14NDocDumpMemory failure.");
3386*7c568831SAndroid Build Coastguard Worker         return NULL;
3387*7c568831SAndroid Build Coastguard Worker     }
3388*7c568831SAndroid Build Coastguard Worker     else {
3389*7c568831SAndroid Build Coastguard Worker         py_retval = PY_IMPORT_STRING_SIZE((const char *) doc_txt,
3390*7c568831SAndroid Build Coastguard Worker                                                 result);
3391*7c568831SAndroid Build Coastguard Worker         xmlFree(doc_txt);
3392*7c568831SAndroid Build Coastguard Worker         return py_retval;
3393*7c568831SAndroid Build Coastguard Worker     }
3394*7c568831SAndroid Build Coastguard Worker }
3395*7c568831SAndroid Build Coastguard Worker 
3396*7c568831SAndroid Build Coastguard Worker static PyObject *
libxml_C14NDocSaveTo(ATTRIBUTE_UNUSED PyObject * self,PyObject * args)3397*7c568831SAndroid Build Coastguard Worker libxml_C14NDocSaveTo(ATTRIBUTE_UNUSED PyObject * self,
3398*7c568831SAndroid Build Coastguard Worker                      PyObject * args)
3399*7c568831SAndroid Build Coastguard Worker {
3400*7c568831SAndroid Build Coastguard Worker     PyObject *pyobj_doc;
3401*7c568831SAndroid Build Coastguard Worker     PyObject *py_file;
3402*7c568831SAndroid Build Coastguard Worker     PyObject *pyobj_nodes;
3403*7c568831SAndroid Build Coastguard Worker     int exclusive;
3404*7c568831SAndroid Build Coastguard Worker     PyObject *pyobj_prefixes;
3405*7c568831SAndroid Build Coastguard Worker     int with_comments;
3406*7c568831SAndroid Build Coastguard Worker 
3407*7c568831SAndroid Build Coastguard Worker     xmlDocPtr doc;
3408*7c568831SAndroid Build Coastguard Worker     xmlNodeSetPtr nodes;
3409*7c568831SAndroid Build Coastguard Worker     xmlChar **prefixes = NULL;
3410*7c568831SAndroid Build Coastguard Worker     FILE * output;
3411*7c568831SAndroid Build Coastguard Worker     xmlOutputBufferPtr buf;
3412*7c568831SAndroid Build Coastguard Worker 
3413*7c568831SAndroid Build Coastguard Worker     int result;
3414*7c568831SAndroid Build Coastguard Worker     int len;
3415*7c568831SAndroid Build Coastguard Worker 
3416*7c568831SAndroid Build Coastguard Worker     if (!PyArg_ParseTuple(args, (char *) "OOiOiO:C14NDocSaveTo",
3417*7c568831SAndroid Build Coastguard Worker                           &pyobj_doc,
3418*7c568831SAndroid Build Coastguard Worker                           &pyobj_nodes,
3419*7c568831SAndroid Build Coastguard Worker                           &exclusive,
3420*7c568831SAndroid Build Coastguard Worker                           &pyobj_prefixes,
3421*7c568831SAndroid Build Coastguard Worker                           &with_comments,
3422*7c568831SAndroid Build Coastguard Worker                           &py_file))
3423*7c568831SAndroid Build Coastguard Worker         return (NULL);
3424*7c568831SAndroid Build Coastguard Worker 
3425*7c568831SAndroid Build Coastguard Worker     doc = (xmlDocPtr) PyxmlNode_Get(pyobj_doc);
3426*7c568831SAndroid Build Coastguard Worker     if (!doc) {
3427*7c568831SAndroid Build Coastguard Worker         PyErr_SetString(PyExc_TypeError, "bad document.");
3428*7c568831SAndroid Build Coastguard Worker         return NULL;
3429*7c568831SAndroid Build Coastguard Worker     }
3430*7c568831SAndroid Build Coastguard Worker 
3431*7c568831SAndroid Build Coastguard Worker     output = PyFile_Get(py_file);
3432*7c568831SAndroid Build Coastguard Worker     if (output == NULL) {
3433*7c568831SAndroid Build Coastguard Worker         PyErr_SetString(PyExc_TypeError, "bad file.");
3434*7c568831SAndroid Build Coastguard Worker         return NULL;
3435*7c568831SAndroid Build Coastguard Worker     }
3436*7c568831SAndroid Build Coastguard Worker     buf = xmlOutputBufferCreateFile(output, NULL);
3437*7c568831SAndroid Build Coastguard Worker 
3438*7c568831SAndroid Build Coastguard Worker     result = PyxmlNodeSet_Convert(pyobj_nodes, &nodes);
3439*7c568831SAndroid Build Coastguard Worker     if (result < 0) {
3440*7c568831SAndroid Build Coastguard Worker         xmlOutputBufferClose(buf);
3441*7c568831SAndroid Build Coastguard Worker         return NULL;
3442*7c568831SAndroid Build Coastguard Worker     }
3443*7c568831SAndroid Build Coastguard Worker 
3444*7c568831SAndroid Build Coastguard Worker     if (exclusive) {
3445*7c568831SAndroid Build Coastguard Worker         result = PystringSet_Convert(pyobj_prefixes, &prefixes);
3446*7c568831SAndroid Build Coastguard Worker         if (result < 0) {
3447*7c568831SAndroid Build Coastguard Worker             if (nodes) {
3448*7c568831SAndroid Build Coastguard Worker                 xmlFree(nodes->nodeTab);
3449*7c568831SAndroid Build Coastguard Worker                 xmlFree(nodes);
3450*7c568831SAndroid Build Coastguard Worker             }
3451*7c568831SAndroid Build Coastguard Worker             xmlOutputBufferClose(buf);
3452*7c568831SAndroid Build Coastguard Worker             return NULL;
3453*7c568831SAndroid Build Coastguard Worker         }
3454*7c568831SAndroid Build Coastguard Worker     }
3455*7c568831SAndroid Build Coastguard Worker 
3456*7c568831SAndroid Build Coastguard Worker     result = xmlC14NDocSaveTo(doc,
3457*7c568831SAndroid Build Coastguard Worker                               nodes,
3458*7c568831SAndroid Build Coastguard Worker                               exclusive,
3459*7c568831SAndroid Build Coastguard Worker                               prefixes,
3460*7c568831SAndroid Build Coastguard Worker                               with_comments,
3461*7c568831SAndroid Build Coastguard Worker                               buf);
3462*7c568831SAndroid Build Coastguard Worker 
3463*7c568831SAndroid Build Coastguard Worker     if (nodes) {
3464*7c568831SAndroid Build Coastguard Worker         xmlFree(nodes->nodeTab);
3465*7c568831SAndroid Build Coastguard Worker         xmlFree(nodes);
3466*7c568831SAndroid Build Coastguard Worker     }
3467*7c568831SAndroid Build Coastguard Worker     if (prefixes) {
3468*7c568831SAndroid Build Coastguard Worker         xmlChar ** idx = prefixes;
3469*7c568831SAndroid Build Coastguard Worker         while (*idx) xmlFree(*(idx++));
3470*7c568831SAndroid Build Coastguard Worker         xmlFree(prefixes);
3471*7c568831SAndroid Build Coastguard Worker     }
3472*7c568831SAndroid Build Coastguard Worker 
3473*7c568831SAndroid Build Coastguard Worker     PyFile_Release(output);
3474*7c568831SAndroid Build Coastguard Worker     len = xmlOutputBufferClose(buf);
3475*7c568831SAndroid Build Coastguard Worker 
3476*7c568831SAndroid Build Coastguard Worker     if (result < 0) {
3477*7c568831SAndroid Build Coastguard Worker         PyErr_SetString(PyExc_Exception,
3478*7c568831SAndroid Build Coastguard Worker                         "libxml2 xmlC14NDocSaveTo failure.");
3479*7c568831SAndroid Build Coastguard Worker         return NULL;
3480*7c568831SAndroid Build Coastguard Worker     }
3481*7c568831SAndroid Build Coastguard Worker     else
3482*7c568831SAndroid Build Coastguard Worker         return PyLong_FromLong((long) len);
3483*7c568831SAndroid Build Coastguard Worker }
3484*7c568831SAndroid Build Coastguard Worker 
3485*7c568831SAndroid Build Coastguard Worker #endif
3486*7c568831SAndroid Build Coastguard Worker #endif
3487*7c568831SAndroid Build Coastguard Worker 
3488*7c568831SAndroid Build Coastguard Worker static PyObject *
libxml_getObjDesc(PyObject * self ATTRIBUTE_UNUSED,PyObject * args)3489*7c568831SAndroid Build Coastguard Worker libxml_getObjDesc(PyObject *self ATTRIBUTE_UNUSED, PyObject *args) {
3490*7c568831SAndroid Build Coastguard Worker 
3491*7c568831SAndroid Build Coastguard Worker     PyObject *obj;
3492*7c568831SAndroid Build Coastguard Worker     char *str;
3493*7c568831SAndroid Build Coastguard Worker 
3494*7c568831SAndroid Build Coastguard Worker     if (!PyArg_ParseTuple(args, (char *)"O:getObjDesc", &obj))
3495*7c568831SAndroid Build Coastguard Worker         return NULL;
3496*7c568831SAndroid Build Coastguard Worker     str = PyCapsule_GetPointer(obj, PyCapsule_GetName(obj));
3497*7c568831SAndroid Build Coastguard Worker     return Py_BuildValue((char *)"s", str);
3498*7c568831SAndroid Build Coastguard Worker }
3499*7c568831SAndroid Build Coastguard Worker 
3500*7c568831SAndroid Build Coastguard Worker static PyObject *
libxml_compareNodesEqual(PyObject * self ATTRIBUTE_UNUSED,PyObject * args)3501*7c568831SAndroid Build Coastguard Worker libxml_compareNodesEqual(PyObject *self ATTRIBUTE_UNUSED, PyObject *args) {
3502*7c568831SAndroid Build Coastguard Worker 
3503*7c568831SAndroid Build Coastguard Worker     PyObject *py_node1, *py_node2;
3504*7c568831SAndroid Build Coastguard Worker     xmlNodePtr node1, node2;
3505*7c568831SAndroid Build Coastguard Worker 
3506*7c568831SAndroid Build Coastguard Worker     if (!PyArg_ParseTuple(args, (char *)"OO:compareNodesEqual",
3507*7c568831SAndroid Build Coastguard Worker 		&py_node1, &py_node2))
3508*7c568831SAndroid Build Coastguard Worker         return NULL;
3509*7c568831SAndroid Build Coastguard Worker     /* To compare two node objects, we compare their pointer addresses */
3510*7c568831SAndroid Build Coastguard Worker     node1 = PyxmlNode_Get(py_node1);
3511*7c568831SAndroid Build Coastguard Worker     node2 = PyxmlNode_Get(py_node2);
3512*7c568831SAndroid Build Coastguard Worker     if ( node1 == node2 )
3513*7c568831SAndroid Build Coastguard Worker         return Py_BuildValue((char *)"i", 1);
3514*7c568831SAndroid Build Coastguard Worker     else
3515*7c568831SAndroid Build Coastguard Worker         return Py_BuildValue((char *)"i", 0);
3516*7c568831SAndroid Build Coastguard Worker 
3517*7c568831SAndroid Build Coastguard Worker }
3518*7c568831SAndroid Build Coastguard Worker 
3519*7c568831SAndroid Build Coastguard Worker static PyObject *
libxml_nodeHash(PyObject * self ATTRIBUTE_UNUSED,PyObject * args)3520*7c568831SAndroid Build Coastguard Worker libxml_nodeHash(PyObject *self ATTRIBUTE_UNUSED, PyObject *args) {
3521*7c568831SAndroid Build Coastguard Worker 
3522*7c568831SAndroid Build Coastguard Worker     PyObject *py_node1;
3523*7c568831SAndroid Build Coastguard Worker     xmlNodePtr node1;
3524*7c568831SAndroid Build Coastguard Worker 
3525*7c568831SAndroid Build Coastguard Worker     if (!PyArg_ParseTuple(args, (char *)"O:nodeHash", &py_node1))
3526*7c568831SAndroid Build Coastguard Worker 	    return NULL;
3527*7c568831SAndroid Build Coastguard Worker     /* For simplicity, we use the node pointer address as a hash value */
3528*7c568831SAndroid Build Coastguard Worker     node1 = PyxmlNode_Get(py_node1);
3529*7c568831SAndroid Build Coastguard Worker 
3530*7c568831SAndroid Build Coastguard Worker     return PyLong_FromVoidPtr(node1);
3531*7c568831SAndroid Build Coastguard Worker 
3532*7c568831SAndroid Build Coastguard Worker }
3533*7c568831SAndroid Build Coastguard Worker 
3534*7c568831SAndroid Build Coastguard Worker /************************************************************************
3535*7c568831SAndroid Build Coastguard Worker  *									*
3536*7c568831SAndroid Build Coastguard Worker  *		Deprecation warnings					*
3537*7c568831SAndroid Build Coastguard Worker  *									*
3538*7c568831SAndroid Build Coastguard Worker  ************************************************************************/
3539*7c568831SAndroid Build Coastguard Worker 
3540*7c568831SAndroid Build Coastguard Worker int
libxml_deprecationWarning(const char * func)3541*7c568831SAndroid Build Coastguard Worker libxml_deprecationWarning(const char *func) {
3542*7c568831SAndroid Build Coastguard Worker #if PY_VERSION_HEX >= 0x03020000
3543*7c568831SAndroid Build Coastguard Worker     return PyErr_WarnFormat(PyExc_PendingDeprecationWarning, 1,
3544*7c568831SAndroid Build Coastguard Worker             "libxml2mod.%s is deprecated and will be removed "
3545*7c568831SAndroid Build Coastguard Worker             "in future versions", func);
3546*7c568831SAndroid Build Coastguard Worker #else
3547*7c568831SAndroid Build Coastguard Worker     return PyErr_WarnEx(PyExc_PendingDeprecationWarning, func, 1);
3548*7c568831SAndroid Build Coastguard Worker #endif
3549*7c568831SAndroid Build Coastguard Worker }
3550*7c568831SAndroid Build Coastguard Worker 
3551*7c568831SAndroid Build Coastguard Worker /************************************************************************
3552*7c568831SAndroid Build Coastguard Worker  *									*
3553*7c568831SAndroid Build Coastguard Worker  *			The registration stuff				*
3554*7c568831SAndroid Build Coastguard Worker  *									*
3555*7c568831SAndroid Build Coastguard Worker  ************************************************************************/
3556*7c568831SAndroid Build Coastguard Worker static PyMethodDef libxmlMethods[] = {
3557*7c568831SAndroid Build Coastguard Worker #include "libxml2-export.c"
3558*7c568831SAndroid Build Coastguard Worker     {(char *) "name", libxml_name, METH_VARARGS, NULL},
3559*7c568831SAndroid Build Coastguard Worker     {(char *) "children", libxml_children, METH_VARARGS, NULL},
3560*7c568831SAndroid Build Coastguard Worker     {(char *) "properties", libxml_properties, METH_VARARGS, NULL},
3561*7c568831SAndroid Build Coastguard Worker     {(char *) "last", libxml_last, METH_VARARGS, NULL},
3562*7c568831SAndroid Build Coastguard Worker     {(char *) "prev", libxml_prev, METH_VARARGS, NULL},
3563*7c568831SAndroid Build Coastguard Worker     {(char *) "next", libxml_next, METH_VARARGS, NULL},
3564*7c568831SAndroid Build Coastguard Worker     {(char *) "parent", libxml_parent, METH_VARARGS, NULL},
3565*7c568831SAndroid Build Coastguard Worker     {(char *) "type", libxml_type, METH_VARARGS, NULL},
3566*7c568831SAndroid Build Coastguard Worker     {(char *) "doc", libxml_doc, METH_VARARGS, NULL},
3567*7c568831SAndroid Build Coastguard Worker     {(char *) "xmlNewNode", libxml_xmlNewNode, METH_VARARGS, NULL},
3568*7c568831SAndroid Build Coastguard Worker     {(char *) "xmlNodeRemoveNsDef", libxml_xmlNodeRemoveNsDef, METH_VARARGS, NULL},
3569*7c568831SAndroid Build Coastguard Worker #ifdef LIBXML_VALID_ENABLED
3570*7c568831SAndroid Build Coastguard Worker     {(char *)"xmlSetValidErrors", libxml_xmlSetValidErrors, METH_VARARGS, NULL},
3571*7c568831SAndroid Build Coastguard Worker     {(char *)"xmlFreeValidCtxt", libxml_xmlFreeValidCtxt, METH_VARARGS, NULL},
3572*7c568831SAndroid Build Coastguard Worker #endif /* LIBXML_VALID_ENABLED */
3573*7c568831SAndroid Build Coastguard Worker #ifdef LIBXML_OUTPUT_ENABLED
3574*7c568831SAndroid Build Coastguard Worker     {(char *) "serializeNode", libxml_serializeNode, METH_VARARGS, NULL},
3575*7c568831SAndroid Build Coastguard Worker     {(char *) "saveNodeTo", libxml_saveNodeTo, METH_VARARGS, NULL},
3576*7c568831SAndroid Build Coastguard Worker     {(char *) "outputBufferCreate", libxml_xmlCreateOutputBuffer, METH_VARARGS, NULL},
3577*7c568831SAndroid Build Coastguard Worker     {(char *) "outputBufferGetPythonFile", libxml_outputBufferGetPythonFile, METH_VARARGS, NULL},
3578*7c568831SAndroid Build Coastguard Worker     {(char *) "xmlOutputBufferClose", libxml_xmlOutputBufferClose, METH_VARARGS, NULL},
3579*7c568831SAndroid Build Coastguard Worker     { (char *)"xmlOutputBufferFlush", libxml_xmlOutputBufferFlush, METH_VARARGS, NULL },
3580*7c568831SAndroid Build Coastguard Worker     { (char *)"xmlSaveFileTo", libxml_xmlSaveFileTo, METH_VARARGS, NULL },
3581*7c568831SAndroid Build Coastguard Worker     { (char *)"xmlSaveFormatFileTo", libxml_xmlSaveFormatFileTo, METH_VARARGS, NULL },
3582*7c568831SAndroid Build Coastguard Worker #endif /* LIBXML_OUTPUT_ENABLED */
3583*7c568831SAndroid Build Coastguard Worker     {(char *) "inputBufferCreate", libxml_xmlCreateInputBuffer, METH_VARARGS, NULL},
3584*7c568831SAndroid Build Coastguard Worker     {(char *) "setEntityLoader", libxml_xmlSetEntityLoader, METH_VARARGS, NULL},
3585*7c568831SAndroid Build Coastguard Worker     {(char *)"xmlRegisterErrorHandler", libxml_xmlRegisterErrorHandler, METH_VARARGS, NULL },
3586*7c568831SAndroid Build Coastguard Worker     {(char *)"xmlParserCtxtSetErrorHandler", libxml_xmlParserCtxtSetErrorHandler, METH_VARARGS, NULL },
3587*7c568831SAndroid Build Coastguard Worker     {(char *)"xmlParserCtxtGetErrorHandler", libxml_xmlParserCtxtGetErrorHandler, METH_VARARGS, NULL },
3588*7c568831SAndroid Build Coastguard Worker     {(char *)"xmlFreeParserCtxt", libxml_xmlFreeParserCtxt, METH_VARARGS, NULL },
3589*7c568831SAndroid Build Coastguard Worker #ifdef LIBXML_READER_ENABLED
3590*7c568831SAndroid Build Coastguard Worker     {(char *)"xmlTextReaderSetErrorHandler", libxml_xmlTextReaderSetErrorHandler, METH_VARARGS, NULL },
3591*7c568831SAndroid Build Coastguard Worker     {(char *)"xmlTextReaderGetErrorHandler", libxml_xmlTextReaderGetErrorHandler, METH_VARARGS, NULL },
3592*7c568831SAndroid Build Coastguard Worker     {(char *)"xmlFreeTextReader", libxml_xmlFreeTextReader, METH_VARARGS, NULL },
3593*7c568831SAndroid Build Coastguard Worker #endif
3594*7c568831SAndroid Build Coastguard Worker #ifdef LIBXML_CATALOG_ENABLED
3595*7c568831SAndroid Build Coastguard Worker     {(char *)"addLocalCatalog", libxml_addLocalCatalog, METH_VARARGS, NULL },
3596*7c568831SAndroid Build Coastguard Worker #endif
3597*7c568831SAndroid Build Coastguard Worker #ifdef LIBXML_SCHEMAS_ENABLED
3598*7c568831SAndroid Build Coastguard Worker     {(char *)"xmlRelaxNGSetValidErrors", libxml_xmlRelaxNGSetValidErrors, METH_VARARGS, NULL},
3599*7c568831SAndroid Build Coastguard Worker     {(char *)"xmlRelaxNGFreeValidCtxt", libxml_xmlRelaxNGFreeValidCtxt, METH_VARARGS, NULL},
3600*7c568831SAndroid Build Coastguard Worker     {(char *)"xmlSchemaSetValidErrors", libxml_xmlSchemaSetValidErrors, METH_VARARGS, NULL},
3601*7c568831SAndroid Build Coastguard Worker     {(char *)"xmlSchemaFreeValidCtxt", libxml_xmlSchemaFreeValidCtxt, METH_VARARGS, NULL},
3602*7c568831SAndroid Build Coastguard Worker #endif
3603*7c568831SAndroid Build Coastguard Worker #ifdef LIBXML_C14N_ENABLED
3604*7c568831SAndroid Build Coastguard Worker #ifdef LIBXML_OUTPUT_ENABLED
3605*7c568831SAndroid Build Coastguard Worker     {(char *)"xmlC14NDocDumpMemory", libxml_C14NDocDumpMemory, METH_VARARGS, NULL},
3606*7c568831SAndroid Build Coastguard Worker     {(char *)"xmlC14NDocSaveTo", libxml_C14NDocSaveTo, METH_VARARGS, NULL},
3607*7c568831SAndroid Build Coastguard Worker #endif
3608*7c568831SAndroid Build Coastguard Worker #endif
3609*7c568831SAndroid Build Coastguard Worker     {(char *) "getObjDesc", libxml_getObjDesc, METH_VARARGS, NULL},
3610*7c568831SAndroid Build Coastguard Worker     {(char *) "compareNodesEqual", libxml_compareNodesEqual, METH_VARARGS, NULL},
3611*7c568831SAndroid Build Coastguard Worker     {(char *) "nodeHash", libxml_nodeHash, METH_VARARGS, NULL},
3612*7c568831SAndroid Build Coastguard Worker     {(char *) "xmlRegisterInputCallback", libxml_xmlRegisterInputCallback, METH_VARARGS, NULL},
3613*7c568831SAndroid Build Coastguard Worker     {(char *) "xmlUnregisterInputCallback", libxml_xmlUnregisterInputCallback, METH_VARARGS, NULL},
3614*7c568831SAndroid Build Coastguard Worker     {NULL, NULL, 0, NULL}
3615*7c568831SAndroid Build Coastguard Worker };
3616*7c568831SAndroid Build Coastguard Worker 
3617*7c568831SAndroid Build Coastguard Worker #if PY_MAJOR_VERSION >= 3
3618*7c568831SAndroid Build Coastguard Worker #define INITERROR return NULL
3619*7c568831SAndroid Build Coastguard Worker 
3620*7c568831SAndroid Build Coastguard Worker static struct PyModuleDef moduledef = {
3621*7c568831SAndroid Build Coastguard Worker         PyModuleDef_HEAD_INIT,
3622*7c568831SAndroid Build Coastguard Worker         "libxml2mod",
3623*7c568831SAndroid Build Coastguard Worker         NULL,
3624*7c568831SAndroid Build Coastguard Worker         -1,
3625*7c568831SAndroid Build Coastguard Worker         libxmlMethods,
3626*7c568831SAndroid Build Coastguard Worker         NULL,
3627*7c568831SAndroid Build Coastguard Worker         NULL,
3628*7c568831SAndroid Build Coastguard Worker         NULL,
3629*7c568831SAndroid Build Coastguard Worker         NULL
3630*7c568831SAndroid Build Coastguard Worker };
3631*7c568831SAndroid Build Coastguard Worker 
3632*7c568831SAndroid Build Coastguard Worker #else
3633*7c568831SAndroid Build Coastguard Worker #define INITERROR return
3634*7c568831SAndroid Build Coastguard Worker 
3635*7c568831SAndroid Build Coastguard Worker #ifdef MERGED_MODULES
3636*7c568831SAndroid Build Coastguard Worker extern void initlibxsltmod(void);
3637*7c568831SAndroid Build Coastguard Worker #endif
3638*7c568831SAndroid Build Coastguard Worker 
3639*7c568831SAndroid Build Coastguard Worker #endif
3640*7c568831SAndroid Build Coastguard Worker 
3641*7c568831SAndroid Build Coastguard Worker #if PY_MAJOR_VERSION >= 3
PyInit_libxml2mod(void)3642*7c568831SAndroid Build Coastguard Worker PyObject *PyInit_libxml2mod(void)
3643*7c568831SAndroid Build Coastguard Worker #else
3644*7c568831SAndroid Build Coastguard Worker void initlibxml2mod(void)
3645*7c568831SAndroid Build Coastguard Worker #endif
3646*7c568831SAndroid Build Coastguard Worker {
3647*7c568831SAndroid Build Coastguard Worker     PyObject *module;
3648*7c568831SAndroid Build Coastguard Worker 
3649*7c568831SAndroid Build Coastguard Worker #if PY_MAJOR_VERSION >= 3
3650*7c568831SAndroid Build Coastguard Worker     module = PyModule_Create(&moduledef);
3651*7c568831SAndroid Build Coastguard Worker #else
3652*7c568831SAndroid Build Coastguard Worker     /* initialize the python extension module */
3653*7c568831SAndroid Build Coastguard Worker     module = Py_InitModule((char *) "libxml2mod", libxmlMethods);
3654*7c568831SAndroid Build Coastguard Worker #endif
3655*7c568831SAndroid Build Coastguard Worker     if (module == NULL)
3656*7c568831SAndroid Build Coastguard Worker         INITERROR;
3657*7c568831SAndroid Build Coastguard Worker 
3658*7c568831SAndroid Build Coastguard Worker     /* initialize libxml2 */
3659*7c568831SAndroid Build Coastguard Worker     xmlInitParser();
3660*7c568831SAndroid Build Coastguard Worker     /* TODO this probably need to be revamped for Python3 */
3661*7c568831SAndroid Build Coastguard Worker     libxml_xmlErrorInitialize();
3662*7c568831SAndroid Build Coastguard Worker 
3663*7c568831SAndroid Build Coastguard Worker #if PY_MAJOR_VERSION < 3
3664*7c568831SAndroid Build Coastguard Worker #ifdef MERGED_MODULES
3665*7c568831SAndroid Build Coastguard Worker     initlibxsltmod();
3666*7c568831SAndroid Build Coastguard Worker #endif
3667*7c568831SAndroid Build Coastguard Worker #endif
3668*7c568831SAndroid Build Coastguard Worker 
3669*7c568831SAndroid Build Coastguard Worker #if PY_MAJOR_VERSION >= 3
3670*7c568831SAndroid Build Coastguard Worker     return module;
3671*7c568831SAndroid Build Coastguard Worker #endif
3672*7c568831SAndroid Build Coastguard Worker }
3673