blob: bf4c652c15b482532bd4551266d693d825ec7cb4 [file] [log] [blame]
Daniel Veillard3ce52572002-02-03 15:08:05 +00001/*
2 * libxml.c: this modules implements the main part of the glue of the
3 * libxml2 library and the Python interpreter. It provides the
4 * entry points where an automatically generated stub is either
5 * unpractical or would not match cleanly the Python model.
6 *
Daniel Veillard0fea6f42002-02-22 22:51:13 +00007 * If compiled with MERGED_MODULES, the entry point will be used to
8 * initialize both the libxml2 and the libxslt wrappers
9 *
Daniel Veillard3ce52572002-02-03 15:08:05 +000010 * See Copyright for the status of this software.
11 *
12 * daniel@veillard.com
13 */
Daniel Veillardd2897fd2002-01-30 16:37:32 +000014#include <Python.h>
Daniel Veillardc6d4a932002-09-12 15:00:57 +000015#include <fileobject.h>
Daniel Veillarda1196ed2002-11-23 11:22:49 +000016/* #include "config.h" */
Daniel Veillardf1d0e6b2002-01-31 23:42:44 +000017#include <libxml/xmlmemory.h>
Daniel Veillardd2897fd2002-01-30 16:37:32 +000018#include <libxml/parser.h>
19#include <libxml/tree.h>
Daniel Veillarda7340c82002-02-01 17:56:45 +000020#include <libxml/xpath.h>
Daniel Veillard5d819032002-02-02 21:49:17 +000021#include <libxml/xmlerror.h>
Daniel Veillarda7340c82002-02-01 17:56:45 +000022#include <libxml/xpathInternals.h>
Daniel Veillard4e1b26c2002-02-03 20:13:06 +000023#include <libxml/xmlmemory.h>
Daniel Veillardc6d4a932002-09-12 15:00:57 +000024#include <libxml/xmlIO.h>
Daniel Veillardd2897fd2002-01-30 16:37:32 +000025#include "libxml_wrap.h"
Daniel Veillard96fe0952002-01-30 20:52:23 +000026#include "libxml2-py.h"
Daniel Veillardd2897fd2002-01-30 16:37:32 +000027
Daniel Veillard0d132cf2002-12-23 14:43:32 +000028#if (defined(_MSC_VER) || defined(__MINGW32__)) && !defined(vsnprintf)
29#define vsnprintf(b,c,f,a) _vsnprintf(b,c,f,a)
Daniel Veillarde4fa2932003-03-26 00:38:10 +000030#elif defined(WITH_TRIO)
31#include "trio.h"
32#define vsnprintf trio_vsnprintf
Daniel Veillard0d132cf2002-12-23 14:43:32 +000033#endif
34
Daniel Veillardd2897fd2002-01-30 16:37:32 +000035/* #define DEBUG */
Daniel Veillard797a5652002-02-12 13:46:21 +000036/* #define DEBUG_SAX */
Daniel Veillarda7340c82002-02-01 17:56:45 +000037/* #define DEBUG_XPATH */
Daniel Veillard5d819032002-02-02 21:49:17 +000038/* #define DEBUG_ERROR */
Daniel Veillard4e1b26c2002-02-03 20:13:06 +000039/* #define DEBUG_MEMORY */
Daniel Veillardc6d4a932002-09-12 15:00:57 +000040/* #define DEBUG_FILES */
41/* #define DEBUG_LOADER */
Daniel Veillard4e1b26c2002-02-03 20:13:06 +000042
Daniel Veillardd2379012002-03-15 22:24:56 +000043void initlibxml2mod(void);
44
Daniel Veillardc6d4a932002-09-12 15:00:57 +000045/**
46 * TODO:
47 *
48 * macro to flag unimplemented blocks
49 */
50#define TODO \
51 xmlGenericError(xmlGenericErrorContext, \
52 "Unimplemented block at %s:%d\n", \
53 __FILE__, __LINE__);
54
Daniel Veillard4e1b26c2002-02-03 20:13:06 +000055/************************************************************************
56 * *
57 * Memory debug interface *
58 * *
59 ************************************************************************/
60
Daniel Veillardc2664642003-07-29 20:44:53 +000061#if 0
Daniel Veillard4e1b26c2002-02-03 20:13:06 +000062extern void xmlMemFree(void *ptr);
63extern void *xmlMemMalloc(size_t size);
Daniel Veillardd2379012002-03-15 22:24:56 +000064extern void *xmlMemRealloc(void *ptr, size_t size);
Daniel Veillard4e1b26c2002-02-03 20:13:06 +000065extern char *xmlMemoryStrdup(const char *str);
Daniel Veillardc2664642003-07-29 20:44:53 +000066#endif
Daniel Veillard4e1b26c2002-02-03 20:13:06 +000067
68static int libxmlMemoryDebugActivated = 0;
69static long libxmlMemoryAllocatedBase = 0;
70
71static int libxmlMemoryDebug = 0;
72static xmlFreeFunc freeFunc = NULL;
73static xmlMallocFunc mallocFunc = NULL;
74static xmlReallocFunc reallocFunc = NULL;
75static xmlStrdupFunc strdupFunc = NULL;
76
77PyObject *
Daniel Veillardd2379012002-03-15 22:24:56 +000078libxml_xmlDebugMemory(ATTRIBUTE_UNUSED PyObject * self, PyObject * args)
79{
Daniel Veillard4e1b26c2002-02-03 20:13:06 +000080 int activate;
81 PyObject *py_retval;
82 long ret;
83
Daniel Veillardd2379012002-03-15 22:24:56 +000084 if (!PyArg_ParseTuple(args, (char *) "i:xmlDebugMemory", &activate))
85 return (NULL);
Daniel Veillard4e1b26c2002-02-03 20:13:06 +000086
87#ifdef DEBUG_MEMORY
88 printf("libxml_xmlDebugMemory(%d) called\n", activate);
89#endif
90
91 if (activate != 0) {
Daniel Veillardd2379012002-03-15 22:24:56 +000092 if (libxmlMemoryDebug == 0) {
93 /*
94 * First initialize the library and grab the old memory handlers
95 * and switch the library to memory debugging
96 */
97 xmlMemGet((xmlFreeFunc *) & freeFunc,
98 (xmlMallocFunc *) & mallocFunc,
99 (xmlReallocFunc *) & reallocFunc,
100 (xmlStrdupFunc *) & strdupFunc);
101 if ((freeFunc == xmlMemFree) && (mallocFunc == xmlMemMalloc) &&
102 (reallocFunc == xmlMemRealloc) &&
103 (strdupFunc == xmlMemoryStrdup)) {
104 libxmlMemoryAllocatedBase = xmlMemUsed();
105 } else {
106 ret = (long) xmlMemSetup(xmlMemFree, xmlMemMalloc,
107 xmlMemRealloc, xmlMemoryStrdup);
108 if (ret < 0)
109 goto error;
110 libxmlMemoryAllocatedBase = xmlMemUsed();
111 }
112 xmlInitParser();
113 ret = 0;
114 } else if (libxmlMemoryDebugActivated == 0) {
115 libxmlMemoryAllocatedBase = xmlMemUsed();
116 ret = 0;
117 } else {
118 ret = xmlMemUsed() - libxmlMemoryAllocatedBase;
119 }
120 libxmlMemoryDebug = 1;
121 libxmlMemoryDebugActivated = 1;
Daniel Veillard4e1b26c2002-02-03 20:13:06 +0000122 } else {
Daniel Veillardd2379012002-03-15 22:24:56 +0000123 if (libxmlMemoryDebugActivated == 1)
124 ret = xmlMemUsed() - libxmlMemoryAllocatedBase;
125 else
126 ret = 0;
127 libxmlMemoryDebugActivated = 0;
Daniel Veillard4e1b26c2002-02-03 20:13:06 +0000128 }
Daniel Veillardd2379012002-03-15 22:24:56 +0000129 error:
Daniel Veillard4e1b26c2002-02-03 20:13:06 +0000130 py_retval = libxml_longWrap(ret);
Daniel Veillardd2379012002-03-15 22:24:56 +0000131 return (py_retval);
Daniel Veillard4e1b26c2002-02-03 20:13:06 +0000132}
133
134PyObject *
Daniel Veillardd2379012002-03-15 22:24:56 +0000135libxml_xmlDumpMemory(ATTRIBUTE_UNUSED PyObject * self,
136 ATTRIBUTE_UNUSED PyObject * args)
137{
Daniel Veillard4e1b26c2002-02-03 20:13:06 +0000138
139 if (libxmlMemoryDebug != 0)
Daniel Veillardd2379012002-03-15 22:24:56 +0000140 xmlMemoryDump();
Daniel Veillard4e1b26c2002-02-03 20:13:06 +0000141 Py_INCREF(Py_None);
Daniel Veillardd2379012002-03-15 22:24:56 +0000142 return (Py_None);
Daniel Veillard4e1b26c2002-02-03 20:13:06 +0000143}
Daniel Veillardd2897fd2002-01-30 16:37:32 +0000144
145/************************************************************************
146 * *
Daniel Veillardc6d4a932002-09-12 15:00:57 +0000147 * Handling Python FILE I/O at the C level *
148 * The raw I/O attack diectly the File objects, while the *
149 * other routines address the ioWrapper instance instead *
150 * *
151 ************************************************************************/
152
153/**
154 * xmlPythonFileCloseUnref:
155 * @context: the I/O context
156 *
157 * Close an I/O channel
158 */
159static int
160xmlPythonFileCloseRaw (void * context) {
161 PyObject *file, *ret;
162
163#ifdef DEBUG_FILES
164 printf("xmlPythonFileCloseUnref\n");
165#endif
166 file = (PyObject *) context;
167 if (file == NULL) return(-1);
Daniel Veillard118aed72002-09-24 14:13:13 +0000168 ret = PyEval_CallMethod(file, (char *) "close", (char *) "()");
Daniel Veillardc6d4a932002-09-12 15:00:57 +0000169 if (ret != NULL) {
170 Py_DECREF(ret);
171 }
172 Py_DECREF(file);
173 return(0);
174}
175
176/**
177 * xmlPythonFileReadRaw:
178 * @context: the I/O context
179 * @buffer: where to drop data
180 * @len: number of bytes to write
181 *
182 * Read @len bytes to @buffer from the Python file in the I/O channel
183 *
184 * Returns the number of bytes read
185 */
186static int
187xmlPythonFileReadRaw (void * context, char * buffer, int len) {
188 PyObject *file;
189 PyObject *ret;
190 int lenread = -1;
191 char *data;
192
193#ifdef DEBUG_FILES
194 printf("xmlPythonFileReadRaw: %d\n", len);
195#endif
196 file = (PyObject *) context;
197 if (file == NULL) return(-1);
Daniel Veillard118aed72002-09-24 14:13:13 +0000198 ret = PyEval_CallMethod(file, (char *) "read", (char *) "(i)", len);
Daniel Veillardc6d4a932002-09-12 15:00:57 +0000199 if (ret == NULL) {
200 printf("xmlPythonFileReadRaw: result is NULL\n");
201 return(-1);
202 } else if (PyString_Check(ret)) {
203 lenread = PyString_Size(ret);
204 data = PyString_AsString(ret);
205 if (lenread > len)
206 memcpy(buffer, data, len);
207 else
208 memcpy(buffer, data, lenread);
209 Py_DECREF(ret);
210 } else {
211 printf("xmlPythonFileReadRaw: result is not a String\n");
212 Py_DECREF(ret);
213 }
214 return(lenread);
215}
216
217/**
218 * xmlPythonFileRead:
219 * @context: the I/O context
220 * @buffer: where to drop data
221 * @len: number of bytes to write
222 *
223 * Read @len bytes to @buffer from the I/O channel.
224 *
225 * Returns the number of bytes read
226 */
227static int
228xmlPythonFileRead (void * context, char * buffer, int len) {
229 PyObject *file;
230 PyObject *ret;
231 int lenread = -1;
232 char *data;
233
234#ifdef DEBUG_FILES
235 printf("xmlPythonFileRead: %d\n", len);
236#endif
237 file = (PyObject *) context;
238 if (file == NULL) return(-1);
Daniel Veillard118aed72002-09-24 14:13:13 +0000239 ret = PyEval_CallMethod(file, (char *) "io_read", (char *) "(i)", len);
Daniel Veillardc6d4a932002-09-12 15:00:57 +0000240 if (ret == NULL) {
241 printf("xmlPythonFileRead: result is NULL\n");
242 return(-1);
243 } else if (PyString_Check(ret)) {
244 lenread = PyString_Size(ret);
245 data = PyString_AsString(ret);
246 if (lenread > len)
247 memcpy(buffer, data, len);
248 else
249 memcpy(buffer, data, lenread);
250 Py_DECREF(ret);
251 } else {
252 printf("xmlPythonFileRead: result is not a String\n");
253 Py_DECREF(ret);
254 }
255 return(lenread);
256}
257
258/**
259 * xmlFileWrite:
260 * @context: the I/O context
261 * @buffer: where to drop data
262 * @len: number of bytes to write
263 *
264 * Write @len bytes from @buffer to the I/O channel.
265 *
266 * Returns the number of bytes written
267 */
268static int
269xmlPythonFileWrite (void * context, const char * buffer, int len) {
270 PyObject *file;
271 PyObject *string;
272 PyObject *ret;
273 int written = -1;
274
275#ifdef DEBUG_FILES
276 printf("xmlPythonFileWrite: %d\n", len);
277#endif
278 file = (PyObject *) context;
279 if (file == NULL) return(-1);
280 string = PyString_FromStringAndSize(buffer, len);
281 if (string == NULL) return(-1);
Daniel Veillard118aed72002-09-24 14:13:13 +0000282 ret = PyEval_CallMethod(file, (char *) "io_write", (char *) "(O)", string);
Daniel Veillardc6d4a932002-09-12 15:00:57 +0000283 Py_DECREF(string);
284 if (ret == NULL) {
285 printf("xmlPythonFileWrite: result is NULL\n");
286 return(-1);
287 } else if (PyInt_Check(ret)) {
288 written = (int) PyInt_AsLong(ret);
289 Py_DECREF(ret);
290 } else if (ret == Py_None) {
291 written = len;
292 Py_DECREF(ret);
293 } else {
294 printf("xmlPythonFileWrite: result is not an Int nor None\n");
295 Py_DECREF(ret);
296 }
297 return(written);
298}
299
300/**
301 * xmlPythonFileClose:
302 * @context: the I/O context
303 *
304 * Close an I/O channel
305 */
306static int
307xmlPythonFileClose (void * context) {
308 PyObject *file, *ret;
309
310#ifdef DEBUG_FILES
311 printf("xmlPythonFileClose\n");
312#endif
313 file = (PyObject *) context;
314 if (file == NULL) return(-1);
Daniel Veillard118aed72002-09-24 14:13:13 +0000315 ret = PyEval_CallMethod(file, (char *) "io_close", (char *) "()");
Daniel Veillardc6d4a932002-09-12 15:00:57 +0000316 if (ret != NULL) {
317 Py_DECREF(ret);
318 }
319 return(0);
320}
321
Daniel Veillarda9cce9c2003-09-29 13:20:24 +0000322#ifdef LIBXML_OUTPUT_ENABLED
Daniel Veillardc6d4a932002-09-12 15:00:57 +0000323/**
324 * xmlOutputBufferCreatePythonFile:
325 * @file: a PyFile_Type
326 * @encoder: the encoding converter or NULL
327 *
328 * Create a buffered output for the progressive saving to a PyFile_Type
329 * buffered C I/O
330 *
331 * Returns the new parser output or NULL
332 */
Daniel Veillard118aed72002-09-24 14:13:13 +0000333static xmlOutputBufferPtr
Daniel Veillardc6d4a932002-09-12 15:00:57 +0000334xmlOutputBufferCreatePythonFile(PyObject *file,
335 xmlCharEncodingHandlerPtr encoder) {
336 xmlOutputBufferPtr ret;
337
338 if (file == NULL) return(NULL);
339
340 ret = xmlAllocOutputBuffer(encoder);
341 if (ret != NULL) {
342 ret->context = file;
343 /* Py_INCREF(file); */
344 ret->writecallback = xmlPythonFileWrite;
345 ret->closecallback = xmlPythonFileClose;
346 }
347
348 return(ret);
349}
350
351PyObject *
352libxml_xmlCreateOutputBuffer(ATTRIBUTE_UNUSED PyObject *self, PyObject *args) {
353 PyObject *py_retval;
354 PyObject *file;
355 xmlChar *encoding;
356 xmlCharEncodingHandlerPtr handler = NULL;
357 xmlOutputBufferPtr buffer;
358
359
360 if (!PyArg_ParseTuple(args, (char *)"Oz:xmlOutputBufferCreate",
361 &file, &encoding))
362 return(NULL);
363 if ((encoding != NULL) && (encoding[0] != 0)) {
Daniel Veillard118aed72002-09-24 14:13:13 +0000364 handler = xmlFindCharEncodingHandler((const char *) encoding);
Daniel Veillardc6d4a932002-09-12 15:00:57 +0000365 }
366 buffer = xmlOutputBufferCreatePythonFile(file, handler);
367 if (buffer == NULL)
368 printf("libxml_xmlCreateOutputBuffer: buffer == NULL\n");
369 py_retval = libxml_xmlOutputBufferPtrWrap(buffer);
370 return(py_retval);
371}
Daniel Veillarda9cce9c2003-09-29 13:20:24 +0000372#endif /* LIBXML_OUTPUT_ENABLED */
Daniel Veillardc6d4a932002-09-12 15:00:57 +0000373
374
375/**
376 * xmlParserInputBufferCreatePythonFile:
377 * @file: a PyFile_Type
378 * @encoder: the encoding converter or NULL
379 *
380 * Create a buffered output for the progressive saving to a PyFile_Type
381 * buffered C I/O
382 *
383 * Returns the new parser output or NULL
384 */
Daniel Veillard118aed72002-09-24 14:13:13 +0000385static xmlParserInputBufferPtr
Daniel Veillardc6d4a932002-09-12 15:00:57 +0000386xmlParserInputBufferCreatePythonFile(PyObject *file,
387 xmlCharEncoding encoding) {
388 xmlParserInputBufferPtr ret;
389
390 if (file == NULL) return(NULL);
391
392 ret = xmlAllocParserInputBuffer(encoding);
393 if (ret != NULL) {
394 ret->context = file;
395 /* Py_INCREF(file); */
396 ret->readcallback = xmlPythonFileRead;
397 ret->closecallback = xmlPythonFileClose;
398 }
399
400 return(ret);
401}
402
403PyObject *
404libxml_xmlCreateInputBuffer(ATTRIBUTE_UNUSED PyObject *self, PyObject *args) {
405 PyObject *py_retval;
406 PyObject *file;
407 xmlChar *encoding;
408 xmlCharEncoding enc = XML_CHAR_ENCODING_NONE;
409 xmlParserInputBufferPtr buffer;
410
411
412 if (!PyArg_ParseTuple(args, (char *)"Oz:xmlParserInputBufferCreate",
413 &file, &encoding))
414 return(NULL);
415 if ((encoding != NULL) && (encoding[0] != 0)) {
Daniel Veillard118aed72002-09-24 14:13:13 +0000416 enc = xmlParseCharEncoding((const char *) encoding);
Daniel Veillardc6d4a932002-09-12 15:00:57 +0000417 }
418 buffer = xmlParserInputBufferCreatePythonFile(file, enc);
419 if (buffer == NULL)
420 printf("libxml_xmlParserInputBufferCreate: buffer == NULL\n");
421 py_retval = libxml_xmlParserInputBufferPtrWrap(buffer);
422 return(py_retval);
423}
424
425/************************************************************************
426 * *
427 * Providing the resolver at the Python level *
428 * *
429 ************************************************************************/
430
431static xmlExternalEntityLoader defaultExternalEntityLoader = NULL;
432static PyObject *pythonExternalEntityLoaderObjext;
433
434static xmlParserInputPtr
435pythonExternalEntityLoader(const char *URL, const char *ID,
436 xmlParserCtxtPtr ctxt) {
437 xmlParserInputPtr result = NULL;
438 if (pythonExternalEntityLoaderObjext != NULL) {
439 PyObject *ret;
440 PyObject *ctxtobj;
441
442 ctxtobj = libxml_xmlParserCtxtPtrWrap(ctxt);
443#ifdef DEBUG_LOADER
444 printf("pythonExternalEntityLoader: ready to call\n");
445#endif
446
447 ret = PyObject_CallFunction(pythonExternalEntityLoaderObjext,
Daniel Veillard118aed72002-09-24 14:13:13 +0000448 (char *) "(ssO)", URL, ID, ctxtobj);
Daniel Veillarde4a07e72003-01-14 14:40:25 +0000449 Py_XDECREF(ctxtobj);
Daniel Veillardc6d4a932002-09-12 15:00:57 +0000450#ifdef DEBUG_LOADER
451 printf("pythonExternalEntityLoader: result ");
Daniel Veillard007d51e2003-09-17 20:07:28 +0000452 PyObject_Print(ret, stderr, 0);
Daniel Veillardc6d4a932002-09-12 15:00:57 +0000453 printf("\n");
454#endif
455
456 if (ret != NULL) {
Daniel Veillard118aed72002-09-24 14:13:13 +0000457 if (PyObject_HasAttrString(ret, (char *) "read")) {
Daniel Veillardc6d4a932002-09-12 15:00:57 +0000458 xmlParserInputBufferPtr buf;
459
460 buf = xmlAllocParserInputBuffer(XML_CHAR_ENCODING_NONE);
461 if (buf != NULL) {
462 buf->context = ret;
463 buf->readcallback = xmlPythonFileReadRaw;
464 buf->closecallback = xmlPythonFileCloseRaw;
465 result = xmlNewIOInputStream(ctxt, buf,
466 XML_CHAR_ENCODING_NONE);
467 }
468 } else {
469 printf("pythonExternalEntityLoader: can't read\n");
470 }
471 if (result == NULL) {
472 Py_DECREF(ret);
Daniel Veillardc64b8e92003-02-24 11:47:13 +0000473 } else if (URL != NULL) {
William M. Brackc1939562003-08-05 15:52:22 +0000474 result->filename = (char *) xmlStrdup((const xmlChar *)URL);
Daniel Veillardc64b8e92003-02-24 11:47:13 +0000475 result->directory = xmlParserGetDirectory((const char *) URL);
Daniel Veillardc6d4a932002-09-12 15:00:57 +0000476 }
477 }
478 }
479 if ((result == NULL) && (defaultExternalEntityLoader != NULL)) {
480 result = defaultExternalEntityLoader(URL, ID, ctxt);
481 }
482 return(result);
483}
484
485PyObject *
486libxml_xmlSetEntityLoader(ATTRIBUTE_UNUSED PyObject *self, PyObject *args) {
487 PyObject *py_retval;
488 PyObject *loader;
489
490 if (!PyArg_ParseTuple(args, (char *)"O:libxml_xmlSetEntityLoader",
491 &loader))
492 return(NULL);
493
494#ifdef DEBUG_LOADER
495 printf("libxml_xmlSetEntityLoader\n");
496#endif
497 if (defaultExternalEntityLoader == NULL)
498 defaultExternalEntityLoader = xmlGetExternalEntityLoader();
499
500 pythonExternalEntityLoaderObjext = loader;
501 xmlSetExternalEntityLoader(pythonExternalEntityLoader);
502
503 py_retval = PyInt_FromLong(0);
504 return(py_retval);
505}
506
507
508/************************************************************************
509 * *
Daniel Veillard3ce52572002-02-03 15:08:05 +0000510 * Handling SAX/xmllib/sgmlop callback interfaces *
Daniel Veillardd2897fd2002-01-30 16:37:32 +0000511 * *
512 ************************************************************************/
Daniel Veillardd2897fd2002-01-30 16:37:32 +0000513
Daniel Veillard33caa0b2002-02-04 14:07:26 +0000514static void
515pythonStartElement(void *user_data, const xmlChar * name,
516 const xmlChar ** attrs)
517{
518 int i;
519 PyObject *handler;
520 PyObject *dict;
521 PyObject *attrname;
522 PyObject *attrvalue;
Daniel Veillardd2379012002-03-15 22:24:56 +0000523 PyObject *result = NULL;
Daniel Veillard33caa0b2002-02-04 14:07:26 +0000524 int type = 0;
525
Daniel Veillard797a5652002-02-12 13:46:21 +0000526#ifdef DEBUG_SAX
527 printf("pythonStartElement(%s) called\n", name);
528#endif
Daniel Veillard33caa0b2002-02-04 14:07:26 +0000529 handler = (PyObject *) user_data;
Daniel Veillardd2379012002-03-15 22:24:56 +0000530 if (PyObject_HasAttrString(handler, (char *) "startElement"))
Daniel Veillard33caa0b2002-02-04 14:07:26 +0000531 type = 1;
Daniel Veillardd2379012002-03-15 22:24:56 +0000532 else if (PyObject_HasAttrString(handler, (char *) "start"))
Daniel Veillard33caa0b2002-02-04 14:07:26 +0000533 type = 2;
534 if (type != 0) {
535 /*
536 * the xmllib interface always generate a dictionnary,
537 * possibly empty
538 */
539 if ((attrs == NULL) && (type == 1)) {
540 Py_XINCREF(Py_None);
541 dict = Py_None;
Daniel Veillardd2379012002-03-15 22:24:56 +0000542 } else if (attrs == NULL) {
543 dict = PyDict_New();
Daniel Veillard33caa0b2002-02-04 14:07:26 +0000544 } else {
545 dict = PyDict_New();
546 for (i = 0; attrs[i] != NULL; i++) {
Daniel Veillardd2379012002-03-15 22:24:56 +0000547 attrname = PyString_FromString((char *) attrs[i]);
Daniel Veillard33caa0b2002-02-04 14:07:26 +0000548 i++;
549 if (attrs[i] != NULL) {
Daniel Veillardd2379012002-03-15 22:24:56 +0000550 attrvalue = PyString_FromString((char *) attrs[i]);
Daniel Veillard33caa0b2002-02-04 14:07:26 +0000551 } else {
552 Py_XINCREF(Py_None);
553 attrvalue = Py_None;
554 }
555 PyDict_SetItem(dict, attrname, attrvalue);
556 }
557 }
558
559 if (type == 1)
Daniel Veillardd2379012002-03-15 22:24:56 +0000560 result = PyObject_CallMethod(handler, (char *) "startElement",
561 (char *) "sO", name, dict);
Daniel Veillard33caa0b2002-02-04 14:07:26 +0000562 else if (type == 2)
Daniel Veillardd2379012002-03-15 22:24:56 +0000563 result = PyObject_CallMethod(handler, (char *) "start",
564 (char *) "sO", name, dict);
565 if (PyErr_Occurred())
566 PyErr_Print();
Daniel Veillard33caa0b2002-02-04 14:07:26 +0000567 Py_XDECREF(dict);
568 Py_XDECREF(result);
569 }
570}
571
572static void
573pythonStartDocument(void *user_data)
574{
575 PyObject *handler;
576 PyObject *result;
577
Daniel Veillard797a5652002-02-12 13:46:21 +0000578#ifdef DEBUG_SAX
579 printf("pythonStartDocument() called\n");
580#endif
Daniel Veillard33caa0b2002-02-04 14:07:26 +0000581 handler = (PyObject *) user_data;
Daniel Veillardd2379012002-03-15 22:24:56 +0000582 if (PyObject_HasAttrString(handler, (char *) "startDocument")) {
583 result =
584 PyObject_CallMethod(handler, (char *) "startDocument", NULL);
585 if (PyErr_Occurred())
586 PyErr_Print();
Daniel Veillard33caa0b2002-02-04 14:07:26 +0000587 Py_XDECREF(result);
588 }
589}
590
591static void
592pythonEndDocument(void *user_data)
593{
594 PyObject *handler;
595 PyObject *result;
596
Daniel Veillard797a5652002-02-12 13:46:21 +0000597#ifdef DEBUG_SAX
598 printf("pythonEndDocument() called\n");
599#endif
Daniel Veillard33caa0b2002-02-04 14:07:26 +0000600 handler = (PyObject *) user_data;
Daniel Veillardd2379012002-03-15 22:24:56 +0000601 if (PyObject_HasAttrString(handler, (char *) "endDocument")) {
602 result =
603 PyObject_CallMethod(handler, (char *) "endDocument", NULL);
604 if (PyErr_Occurred())
605 PyErr_Print();
Daniel Veillard33caa0b2002-02-04 14:07:26 +0000606 Py_XDECREF(result);
607 }
608 /*
609 * The reference to the handler is released there
610 */
611 Py_XDECREF(handler);
612}
613
614static void
615pythonEndElement(void *user_data, const xmlChar * name)
616{
617 PyObject *handler;
618 PyObject *result;
619
Daniel Veillard797a5652002-02-12 13:46:21 +0000620#ifdef DEBUG_SAX
621 printf("pythonEndElement(%s) called\n", name);
622#endif
Daniel Veillard33caa0b2002-02-04 14:07:26 +0000623 handler = (PyObject *) user_data;
Daniel Veillardd2379012002-03-15 22:24:56 +0000624 if (PyObject_HasAttrString(handler, (char *) "endElement")) {
625 result = PyObject_CallMethod(handler, (char *) "endElement",
626 (char *) "s", name);
627 if (PyErr_Occurred())
628 PyErr_Print();
Daniel Veillard33caa0b2002-02-04 14:07:26 +0000629 Py_XDECREF(result);
Daniel Veillardd2379012002-03-15 22:24:56 +0000630 } else if (PyObject_HasAttrString(handler, (char *) "end")) {
631 result = PyObject_CallMethod(handler, (char *) "end",
632 (char *) "s", name);
633 if (PyErr_Occurred())
634 PyErr_Print();
Daniel Veillard797a5652002-02-12 13:46:21 +0000635 Py_XDECREF(result);
Daniel Veillard33caa0b2002-02-04 14:07:26 +0000636 }
637}
638
639static void
640pythonReference(void *user_data, const xmlChar * name)
641{
642 PyObject *handler;
643 PyObject *result;
644
Daniel Veillard797a5652002-02-12 13:46:21 +0000645#ifdef DEBUG_SAX
646 printf("pythonReference(%s) called\n", name);
647#endif
Daniel Veillard33caa0b2002-02-04 14:07:26 +0000648 handler = (PyObject *) user_data;
Daniel Veillardd2379012002-03-15 22:24:56 +0000649 if (PyObject_HasAttrString(handler, (char *) "reference")) {
650 result = PyObject_CallMethod(handler, (char *) "reference",
651 (char *) "s", name);
652 if (PyErr_Occurred())
653 PyErr_Print();
Daniel Veillard33caa0b2002-02-04 14:07:26 +0000654 Py_XDECREF(result);
655 }
656}
657
658static void
659pythonCharacters(void *user_data, const xmlChar * ch, int len)
660{
661 PyObject *handler;
Daniel Veillardd2379012002-03-15 22:24:56 +0000662 PyObject *result = NULL;
Daniel Veillard33caa0b2002-02-04 14:07:26 +0000663 int type = 0;
664
Daniel Veillard797a5652002-02-12 13:46:21 +0000665#ifdef DEBUG_SAX
666 printf("pythonCharacters(%s, %d) called\n", ch, len);
667#endif
Daniel Veillard33caa0b2002-02-04 14:07:26 +0000668 handler = (PyObject *) user_data;
Daniel Veillardd2379012002-03-15 22:24:56 +0000669 if (PyObject_HasAttrString(handler, (char *) "characters"))
670 type = 1;
671 else if (PyObject_HasAttrString(handler, (char *) "data"))
672 type = 2;
Daniel Veillard33caa0b2002-02-04 14:07:26 +0000673 if (type != 0) {
Daniel Veillardd2379012002-03-15 22:24:56 +0000674 if (type == 1)
675 result = PyObject_CallMethod(handler, (char *) "characters",
676 (char *) "s#", ch, len);
677 else if (type == 2)
678 result = PyObject_CallMethod(handler, (char *) "data",
679 (char *) "s#", ch, len);
680 if (PyErr_Occurred())
681 PyErr_Print();
Daniel Veillard33caa0b2002-02-04 14:07:26 +0000682 Py_XDECREF(result);
683 }
684}
685
686static void
687pythonIgnorableWhitespace(void *user_data, const xmlChar * ch, int len)
688{
689 PyObject *handler;
Daniel Veillardd2379012002-03-15 22:24:56 +0000690 PyObject *result = NULL;
Daniel Veillard33caa0b2002-02-04 14:07:26 +0000691 int type = 0;
692
Daniel Veillard797a5652002-02-12 13:46:21 +0000693#ifdef DEBUG_SAX
694 printf("pythonIgnorableWhitespace(%s, %d) called\n", ch, len);
695#endif
Daniel Veillard33caa0b2002-02-04 14:07:26 +0000696 handler = (PyObject *) user_data;
Daniel Veillardd2379012002-03-15 22:24:56 +0000697 if (PyObject_HasAttrString(handler, (char *) "ignorableWhitespace"))
Daniel Veillard33caa0b2002-02-04 14:07:26 +0000698 type = 1;
Daniel Veillardd2379012002-03-15 22:24:56 +0000699 else if (PyObject_HasAttrString(handler, (char *) "data"))
Daniel Veillard33caa0b2002-02-04 14:07:26 +0000700 type = 2;
701 if (type != 0) {
702 if (type == 1)
703 result =
Daniel Veillardd2379012002-03-15 22:24:56 +0000704 PyObject_CallMethod(handler,
705 (char *) "ignorableWhitespace",
706 (char *) "s#", ch, len);
Daniel Veillard33caa0b2002-02-04 14:07:26 +0000707 else if (type == 2)
Daniel Veillardd2379012002-03-15 22:24:56 +0000708 result =
709 PyObject_CallMethod(handler, (char *) "data",
710 (char *) "s#", ch, len);
Daniel Veillard33caa0b2002-02-04 14:07:26 +0000711 Py_XDECREF(result);
712 }
713}
714
715static void
716pythonProcessingInstruction(void *user_data,
717 const xmlChar * target, const xmlChar * data)
718{
719 PyObject *handler;
720 PyObject *result;
721
Daniel Veillard797a5652002-02-12 13:46:21 +0000722#ifdef DEBUG_SAX
723 printf("pythonProcessingInstruction(%s, %s) called\n", target, data);
724#endif
Daniel Veillard33caa0b2002-02-04 14:07:26 +0000725 handler = (PyObject *) user_data;
Daniel Veillardd2379012002-03-15 22:24:56 +0000726 if (PyObject_HasAttrString(handler, (char *) "processingInstruction")) {
727 result = PyObject_CallMethod(handler, (char *)
728 "processingInstruction",
729 (char *) "ss", target, data);
Daniel Veillard33caa0b2002-02-04 14:07:26 +0000730 Py_XDECREF(result);
731 }
732}
733
734static void
735pythonComment(void *user_data, const xmlChar * value)
736{
737 PyObject *handler;
738 PyObject *result;
739
Daniel Veillard797a5652002-02-12 13:46:21 +0000740#ifdef DEBUG_SAX
741 printf("pythonComment(%s) called\n", value);
742#endif
Daniel Veillard33caa0b2002-02-04 14:07:26 +0000743 handler = (PyObject *) user_data;
Daniel Veillardd2379012002-03-15 22:24:56 +0000744 if (PyObject_HasAttrString(handler, (char *) "comment")) {
745 result =
746 PyObject_CallMethod(handler, (char *) "comment", (char *) "s",
747 value);
748 if (PyErr_Occurred())
749 PyErr_Print();
Daniel Veillard33caa0b2002-02-04 14:07:26 +0000750 Py_XDECREF(result);
751 }
752}
753
754static void
755pythonWarning(void *user_data, const char *msg, ...)
756{
757 PyObject *handler;
758 PyObject *result;
759 va_list args;
760 char buf[1024];
761
Daniel Veillard797a5652002-02-12 13:46:21 +0000762#ifdef DEBUG_SAX
763 printf("pythonWarning(%s) called\n", msg);
764#endif
Daniel Veillard33caa0b2002-02-04 14:07:26 +0000765 handler = (PyObject *) user_data;
Daniel Veillardd2379012002-03-15 22:24:56 +0000766 if (PyObject_HasAttrString(handler, (char *) "warning")) {
Daniel Veillard33caa0b2002-02-04 14:07:26 +0000767 va_start(args, msg);
768 vsnprintf(buf, 1023, msg, args);
Daniel Veillardd2379012002-03-15 22:24:56 +0000769 va_end(args);
770 buf[1023] = 0;
771 result =
772 PyObject_CallMethod(handler, (char *) "warning", (char *) "s",
773 buf);
774 if (PyErr_Occurred())
775 PyErr_Print();
Daniel Veillard33caa0b2002-02-04 14:07:26 +0000776 Py_XDECREF(result);
777 }
778}
779
780static void
781pythonError(void *user_data, const char *msg, ...)
782{
783 PyObject *handler;
784 PyObject *result;
785 va_list args;
786 char buf[1024];
787
Daniel Veillard797a5652002-02-12 13:46:21 +0000788#ifdef DEBUG_SAX
789 printf("pythonError(%s) called\n", msg);
790#endif
Daniel Veillard33caa0b2002-02-04 14:07:26 +0000791 handler = (PyObject *) user_data;
Daniel Veillardd2379012002-03-15 22:24:56 +0000792 if (PyObject_HasAttrString(handler, (char *) "error")) {
Daniel Veillard33caa0b2002-02-04 14:07:26 +0000793 va_start(args, msg);
794 vsnprintf(buf, 1023, msg, args);
Daniel Veillardd2379012002-03-15 22:24:56 +0000795 va_end(args);
796 buf[1023] = 0;
797 result =
798 PyObject_CallMethod(handler, (char *) "error", (char *) "s",
799 buf);
800 if (PyErr_Occurred())
801 PyErr_Print();
Daniel Veillard33caa0b2002-02-04 14:07:26 +0000802 Py_XDECREF(result);
803 }
804}
805
806static void
807pythonFatalError(void *user_data, const char *msg, ...)
808{
809 PyObject *handler;
810 PyObject *result;
811 va_list args;
812 char buf[1024];
813
Daniel Veillard797a5652002-02-12 13:46:21 +0000814#ifdef DEBUG_SAX
815 printf("pythonFatalError(%s) called\n", msg);
816#endif
Daniel Veillard33caa0b2002-02-04 14:07:26 +0000817 handler = (PyObject *) user_data;
Daniel Veillardd2379012002-03-15 22:24:56 +0000818 if (PyObject_HasAttrString(handler, (char *) "fatalError")) {
Daniel Veillard33caa0b2002-02-04 14:07:26 +0000819 va_start(args, msg);
820 vsnprintf(buf, 1023, msg, args);
Daniel Veillardd2379012002-03-15 22:24:56 +0000821 va_end(args);
822 buf[1023] = 0;
823 result =
824 PyObject_CallMethod(handler, (char *) "fatalError",
825 (char *) "s", buf);
826 if (PyErr_Occurred())
827 PyErr_Print();
Daniel Veillard33caa0b2002-02-04 14:07:26 +0000828 Py_XDECREF(result);
829 }
830}
831
832static void
833pythonCdataBlock(void *user_data, const xmlChar * ch, int len)
834{
835 PyObject *handler;
Daniel Veillardd2379012002-03-15 22:24:56 +0000836 PyObject *result = NULL;
Daniel Veillard33caa0b2002-02-04 14:07:26 +0000837 int type = 0;
838
Daniel Veillard797a5652002-02-12 13:46:21 +0000839#ifdef DEBUG_SAX
840 printf("pythonCdataBlock(%s, %d) called\n", ch, len);
841#endif
Daniel Veillard33caa0b2002-02-04 14:07:26 +0000842 handler = (PyObject *) user_data;
Daniel Veillardd2379012002-03-15 22:24:56 +0000843 if (PyObject_HasAttrString(handler, (char *) "cdataBlock"))
844 type = 1;
845 else if (PyObject_HasAttrString(handler, (char *) "cdata"))
846 type = 2;
Daniel Veillard33caa0b2002-02-04 14:07:26 +0000847 if (type != 0) {
Daniel Veillardd2379012002-03-15 22:24:56 +0000848 if (type == 1)
849 result =
850 PyObject_CallMethod(handler, (char *) "cdataBlock",
851 (char *) "s#", ch, len);
852 else if (type == 2)
853 result =
854 PyObject_CallMethod(handler, (char *) "cdata",
855 (char *) "s#", ch, len);
856 if (PyErr_Occurred())
857 PyErr_Print();
Daniel Veillard33caa0b2002-02-04 14:07:26 +0000858 Py_XDECREF(result);
859 }
860}
861
862static void
863pythonExternalSubset(void *user_data,
864 const xmlChar * name,
865 const xmlChar * externalID, const xmlChar * systemID)
866{
867 PyObject *handler;
868 PyObject *result;
869
Daniel Veillard797a5652002-02-12 13:46:21 +0000870#ifdef DEBUG_SAX
871 printf("pythonExternalSubset(%s, %s, %s) called\n",
Daniel Veillardd2379012002-03-15 22:24:56 +0000872 name, externalID, systemID);
Daniel Veillard797a5652002-02-12 13:46:21 +0000873#endif
Daniel Veillard33caa0b2002-02-04 14:07:26 +0000874 handler = (PyObject *) user_data;
Daniel Veillardd2379012002-03-15 22:24:56 +0000875 if (PyObject_HasAttrString(handler, (char *) "externalSubset")) {
Daniel Veillard33caa0b2002-02-04 14:07:26 +0000876 result =
Daniel Veillardd2379012002-03-15 22:24:56 +0000877 PyObject_CallMethod(handler, (char *) "externalSubset",
878 (char *) "sss", name, externalID,
879 systemID);
Daniel Veillard33caa0b2002-02-04 14:07:26 +0000880 Py_XDECREF(result);
881 }
882}
883
884static void
885pythonEntityDecl(void *user_data,
886 const xmlChar * name,
887 int type,
888 const xmlChar * publicId,
889 const xmlChar * systemId, xmlChar * content)
890{
891 PyObject *handler;
892 PyObject *result;
893
894 handler = (PyObject *) user_data;
Daniel Veillardd2379012002-03-15 22:24:56 +0000895 if (PyObject_HasAttrString(handler, (char *) "entityDecl")) {
896 result = PyObject_CallMethod(handler, (char *) "entityDecl",
897 (char *) "sisss", name, type,
898 publicId, systemId, content);
899 if (PyErr_Occurred())
900 PyErr_Print();
Daniel Veillard33caa0b2002-02-04 14:07:26 +0000901 Py_XDECREF(result);
902 }
903}
904
905
906
907static void
908
909pythonNotationDecl(void *user_data,
910 const xmlChar * name,
911 const xmlChar * publicId, const xmlChar * systemId)
912{
913 PyObject *handler;
914 PyObject *result;
915
916 handler = (PyObject *) user_data;
Daniel Veillardd2379012002-03-15 22:24:56 +0000917 if (PyObject_HasAttrString(handler, (char *) "notationDecl")) {
918 result = PyObject_CallMethod(handler, (char *) "notationDecl",
919 (char *) "sss", name, publicId,
920 systemId);
921 if (PyErr_Occurred())
922 PyErr_Print();
Daniel Veillard33caa0b2002-02-04 14:07:26 +0000923 Py_XDECREF(result);
924 }
925}
926
927static void
928pythonAttributeDecl(void *user_data,
929 const xmlChar * elem,
930 const xmlChar * name,
931 int type,
932 int def,
Daniel Veillardd2379012002-03-15 22:24:56 +0000933 const xmlChar * defaultValue, xmlEnumerationPtr tree)
Daniel Veillard33caa0b2002-02-04 14:07:26 +0000934{
935 PyObject *handler;
936 PyObject *nameList;
937 PyObject *newName;
938 xmlEnumerationPtr node;
939 PyObject *result;
940 int count;
941
942 handler = (PyObject *) user_data;
Daniel Veillardd2379012002-03-15 22:24:56 +0000943 if (PyObject_HasAttrString(handler, (char *) "attributeDecl")) {
Daniel Veillard33caa0b2002-02-04 14:07:26 +0000944 count = 0;
945 for (node = tree; node != NULL; node = node->next) {
946 count++;
947 }
948 nameList = PyList_New(count);
949 count = 0;
950 for (node = tree; node != NULL; node = node->next) {
Daniel Veillardd2379012002-03-15 22:24:56 +0000951 newName = PyString_FromString((char *) node->name);
Daniel Veillard33caa0b2002-02-04 14:07:26 +0000952 PyList_SetItem(nameList, count, newName);
953 count++;
954 }
Daniel Veillardd2379012002-03-15 22:24:56 +0000955 result = PyObject_CallMethod(handler, (char *) "attributeDecl",
956 (char *) "ssiisO", elem, name, type,
957 def, defaultValue, nameList);
958 if (PyErr_Occurred())
959 PyErr_Print();
Daniel Veillard33caa0b2002-02-04 14:07:26 +0000960 Py_XDECREF(nameList);
961 Py_XDECREF(result);
962 }
963}
964
965static void
966pythonElementDecl(void *user_data,
967 const xmlChar * name,
Daniel Veillardd2379012002-03-15 22:24:56 +0000968 int type, ATTRIBUTE_UNUSED xmlElementContentPtr content)
Daniel Veillard33caa0b2002-02-04 14:07:26 +0000969{
970 PyObject *handler;
971 PyObject *obj;
972 PyObject *result;
973
974 handler = (PyObject *) user_data;
Daniel Veillardd2379012002-03-15 22:24:56 +0000975 if (PyObject_HasAttrString(handler, (char *) "elementDecl")) {
976 /* TODO: wrap in an elementContent object */
977 printf
978 ("pythonElementDecl: xmlElementContentPtr wrapper missing !\n");
979 obj = Py_None;
980 /* Py_XINCREF(Py_None); isn't the reference just borrowed ??? */
981 result = PyObject_CallMethod(handler, (char *) "elementDecl",
982 (char *) "siO", name, type, obj);
983 if (PyErr_Occurred())
984 PyErr_Print();
Daniel Veillard33caa0b2002-02-04 14:07:26 +0000985 Py_XDECREF(result);
986 }
987}
988
989static void
990pythonUnparsedEntityDecl(void *user_data,
991 const xmlChar * name,
992 const xmlChar * publicId,
993 const xmlChar * systemId,
994 const xmlChar * notationName)
995{
996 PyObject *handler;
997 PyObject *result;
998
999 handler = (PyObject *) user_data;
Daniel Veillardd2379012002-03-15 22:24:56 +00001000 if (PyObject_HasAttrString(handler, (char *) "unparsedEntityDecl")) {
1001 result =
1002 PyObject_CallMethod(handler, (char *) "unparsedEntityDecl",
1003 (char *) "ssss", name, publicId, systemId,
1004 notationName);
1005 if (PyErr_Occurred())
1006 PyErr_Print();
Daniel Veillard33caa0b2002-02-04 14:07:26 +00001007 Py_XDECREF(result);
1008 }
1009}
1010
1011static void
1012pythonInternalSubset(void *user_data, const xmlChar * name,
1013 const xmlChar * ExternalID, const xmlChar * SystemID)
1014{
1015 PyObject *handler;
1016 PyObject *result;
1017
Daniel Veillard797a5652002-02-12 13:46:21 +00001018#ifdef DEBUG_SAX
1019 printf("pythonInternalSubset(%s, %s, %s) called\n",
Daniel Veillardd2379012002-03-15 22:24:56 +00001020 name, ExternalID, SystemID);
Daniel Veillard797a5652002-02-12 13:46:21 +00001021#endif
Daniel Veillard33caa0b2002-02-04 14:07:26 +00001022 handler = (PyObject *) user_data;
Daniel Veillardd2379012002-03-15 22:24:56 +00001023 if (PyObject_HasAttrString(handler, (char *) "internalSubset")) {
1024 result = PyObject_CallMethod(handler, (char *) "internalSubset",
1025 (char *) "sss", name, ExternalID,
1026 SystemID);
1027 if (PyErr_Occurred())
1028 PyErr_Print();
Daniel Veillard33caa0b2002-02-04 14:07:26 +00001029 Py_XDECREF(result);
1030 }
1031}
1032
1033static xmlSAXHandler pythonSaxHandler = {
1034 pythonInternalSubset,
Daniel Veillardd2379012002-03-15 22:24:56 +00001035 NULL, /* TODO pythonIsStandalone, */
1036 NULL, /* TODO pythonHasInternalSubset, */
1037 NULL, /* TODO pythonHasExternalSubset, */
1038 NULL, /* TODO pythonResolveEntity, */
1039 NULL, /* TODO pythonGetEntity, */
Daniel Veillard33caa0b2002-02-04 14:07:26 +00001040 pythonEntityDecl,
1041 pythonNotationDecl,
1042 pythonAttributeDecl,
1043 pythonElementDecl,
1044 pythonUnparsedEntityDecl,
Daniel Veillardd2379012002-03-15 22:24:56 +00001045 NULL, /* OBSOLETED pythonSetDocumentLocator, */
Daniel Veillard33caa0b2002-02-04 14:07:26 +00001046 pythonStartDocument,
1047 pythonEndDocument,
1048 pythonStartElement,
1049 pythonEndElement,
1050 pythonReference,
1051 pythonCharacters,
1052 pythonIgnorableWhitespace,
1053 pythonProcessingInstruction,
1054 pythonComment,
1055 pythonWarning,
1056 pythonError,
1057 pythonFatalError,
Daniel Veillardd2379012002-03-15 22:24:56 +00001058 NULL, /* TODO pythonGetParameterEntity, */
Daniel Veillard33caa0b2002-02-04 14:07:26 +00001059 pythonCdataBlock,
1060 pythonExternalSubset,
Daniel Veillarda9cce9c2003-09-29 13:20:24 +00001061 1,
1062 NULL, /* TODO mograte to SAX2 */
1063 NULL,
William M. Brack871611b2003-10-18 04:53:14 +00001064 NULL,
Daniel Veillarda9cce9c2003-09-29 13:20:24 +00001065 NULL
Daniel Veillard33caa0b2002-02-04 14:07:26 +00001066};
Daniel Veillard3ce52572002-02-03 15:08:05 +00001067
1068/************************************************************************
1069 * *
1070 * Handling of specific parser context *
1071 * *
1072 ************************************************************************/
Daniel Veillardd2897fd2002-01-30 16:37:32 +00001073
1074PyObject *
Daniel Veillardd2379012002-03-15 22:24:56 +00001075libxml_xmlCreatePushParser(ATTRIBUTE_UNUSED PyObject * self,
1076 PyObject * args)
1077{
1078 const char *chunk;
Daniel Veillard3ce52572002-02-03 15:08:05 +00001079 int size;
Daniel Veillardd2379012002-03-15 22:24:56 +00001080 const char *URI;
Daniel Veillard33caa0b2002-02-04 14:07:26 +00001081 PyObject *pyobj_SAX = NULL;
Daniel Veillard3ce52572002-02-03 15:08:05 +00001082 xmlSAXHandlerPtr SAX = NULL;
Daniel Veillard3ce52572002-02-03 15:08:05 +00001083 xmlParserCtxtPtr ret;
1084 PyObject *pyret;
Daniel Veillard96fe0952002-01-30 20:52:23 +00001085
Daniel Veillardd2379012002-03-15 22:24:56 +00001086 if (!PyArg_ParseTuple
1087 (args, (char *) "Oziz:xmlCreatePushParser", &pyobj_SAX, &chunk,
1088 &size, &URI))
1089 return (NULL);
Daniel Veillard3ce52572002-02-03 15:08:05 +00001090
Daniel Veillard8d24cc12002-03-05 15:41:29 +00001091#ifdef DEBUG
Daniel Veillard3ce52572002-02-03 15:08:05 +00001092 printf("libxml_xmlCreatePushParser(%p, %s, %d, %s) called\n",
Daniel Veillardd2379012002-03-15 22:24:56 +00001093 pyobj_SAX, chunk, size, URI);
Daniel Veillard96fe0952002-01-30 20:52:23 +00001094#endif
Daniel Veillard3ce52572002-02-03 15:08:05 +00001095 if (pyobj_SAX != Py_None) {
Daniel Veillardd2379012002-03-15 22:24:56 +00001096 SAX = &pythonSaxHandler;
1097 Py_INCREF(pyobj_SAX);
1098 /* The reference is released in pythonEndDocument() */
Daniel Veillardd2897fd2002-01-30 16:37:32 +00001099 }
Daniel Veillard33caa0b2002-02-04 14:07:26 +00001100 ret = xmlCreatePushParserCtxt(SAX, pyobj_SAX, chunk, size, URI);
Daniel Veillard3ce52572002-02-03 15:08:05 +00001101 pyret = libxml_xmlParserCtxtPtrWrap(ret);
Daniel Veillardd2379012002-03-15 22:24:56 +00001102 return (pyret);
Daniel Veillarda7340c82002-02-01 17:56:45 +00001103}
Daniel Veillard5d819032002-02-02 21:49:17 +00001104
Daniel Veillard4e1b26c2002-02-03 20:13:06 +00001105PyObject *
Daniel Veillardd2379012002-03-15 22:24:56 +00001106libxml_htmlCreatePushParser(ATTRIBUTE_UNUSED PyObject * self,
1107 PyObject * args)
1108{
1109 const char *chunk;
Daniel Veillard4e1b26c2002-02-03 20:13:06 +00001110 int size;
Daniel Veillardd2379012002-03-15 22:24:56 +00001111 const char *URI;
Daniel Veillard33caa0b2002-02-04 14:07:26 +00001112 PyObject *pyobj_SAX = NULL;
Daniel Veillard4e1b26c2002-02-03 20:13:06 +00001113 xmlSAXHandlerPtr SAX = NULL;
Daniel Veillard4e1b26c2002-02-03 20:13:06 +00001114 xmlParserCtxtPtr ret;
1115 PyObject *pyret;
1116
Daniel Veillardd2379012002-03-15 22:24:56 +00001117 if (!PyArg_ParseTuple
1118 (args, (char *) "Oziz:htmlCreatePushParser", &pyobj_SAX, &chunk,
1119 &size, &URI))
1120 return (NULL);
Daniel Veillard4e1b26c2002-02-03 20:13:06 +00001121
Daniel Veillard8d24cc12002-03-05 15:41:29 +00001122#ifdef DEBUG
Daniel Veillard4e1b26c2002-02-03 20:13:06 +00001123 printf("libxml_htmlCreatePushParser(%p, %s, %d, %s) called\n",
Daniel Veillardd2379012002-03-15 22:24:56 +00001124 pyobj_SAX, chunk, size, URI);
Daniel Veillard4e1b26c2002-02-03 20:13:06 +00001125#endif
1126 if (pyobj_SAX != Py_None) {
Daniel Veillardd2379012002-03-15 22:24:56 +00001127 SAX = &pythonSaxHandler;
1128 Py_INCREF(pyobj_SAX);
1129 /* The reference is released in pythonEndDocument() */
Daniel Veillard4e1b26c2002-02-03 20:13:06 +00001130 }
Daniel Veillard33caa0b2002-02-04 14:07:26 +00001131 ret = htmlCreatePushParserCtxt(SAX, pyobj_SAX, chunk, size, URI,
Daniel Veillardd2379012002-03-15 22:24:56 +00001132 XML_CHAR_ENCODING_NONE);
Daniel Veillard4e1b26c2002-02-03 20:13:06 +00001133 pyret = libxml_xmlParserCtxtPtrWrap(ret);
Daniel Veillardd2379012002-03-15 22:24:56 +00001134 return (pyret);
Daniel Veillard4e1b26c2002-02-03 20:13:06 +00001135}
1136
Daniel Veillard8d24cc12002-03-05 15:41:29 +00001137PyObject *
Daniel Veillardd2379012002-03-15 22:24:56 +00001138libxml_xmlSAXParseFile(ATTRIBUTE_UNUSED PyObject * self, PyObject * args)
1139{
Daniel Veillard8d24cc12002-03-05 15:41:29 +00001140 int recover;
Daniel Veillardd2379012002-03-15 22:24:56 +00001141 const char *URI;
Daniel Veillard8d24cc12002-03-05 15:41:29 +00001142 PyObject *pyobj_SAX = NULL;
1143 xmlSAXHandlerPtr SAX = NULL;
1144
Daniel Veillardd2379012002-03-15 22:24:56 +00001145 if (!PyArg_ParseTuple(args, (char *) "Osi:xmlSAXParseFile", &pyobj_SAX,
1146 &URI, &recover))
1147 return (NULL);
Daniel Veillard8d24cc12002-03-05 15:41:29 +00001148
1149#ifdef DEBUG
1150 printf("libxml_xmlSAXParseFile(%p, %s, %d) called\n",
Daniel Veillardd2379012002-03-15 22:24:56 +00001151 pyobj_SAX, URI, recover);
Daniel Veillard8d24cc12002-03-05 15:41:29 +00001152#endif
1153 if (pyobj_SAX == Py_None) {
Daniel Veillardd2379012002-03-15 22:24:56 +00001154 Py_INCREF(Py_None);
1155 return (Py_None);
Daniel Veillard8d24cc12002-03-05 15:41:29 +00001156 }
1157 SAX = &pythonSaxHandler;
1158 Py_INCREF(pyobj_SAX);
1159 /* The reference is released in pythonEndDocument() */
1160 xmlSAXParseFileWithData(SAX, URI, recover, pyobj_SAX);
1161 Py_INCREF(Py_None);
Daniel Veillardd2379012002-03-15 22:24:56 +00001162 return (Py_None);
Daniel Veillard8d24cc12002-03-05 15:41:29 +00001163}
1164
1165PyObject *
Daniel Veillardd2379012002-03-15 22:24:56 +00001166libxml_htmlSAXParseFile(ATTRIBUTE_UNUSED PyObject * self, PyObject * args)
1167{
1168 const char *URI;
1169 const char *encoding;
Daniel Veillard8d24cc12002-03-05 15:41:29 +00001170 PyObject *pyobj_SAX = NULL;
1171 xmlSAXHandlerPtr SAX = NULL;
1172
Daniel Veillardd2379012002-03-15 22:24:56 +00001173 if (!PyArg_ParseTuple
1174 (args, (char *) "Osz:htmlSAXParseFile", &pyobj_SAX, &URI,
1175 &encoding))
1176 return (NULL);
Daniel Veillard8d24cc12002-03-05 15:41:29 +00001177
1178#ifdef DEBUG
1179 printf("libxml_htmlSAXParseFile(%p, %s, %s) called\n",
Daniel Veillardd2379012002-03-15 22:24:56 +00001180 pyobj_SAX, URI, encoding);
Daniel Veillard8d24cc12002-03-05 15:41:29 +00001181#endif
1182 if (pyobj_SAX == Py_None) {
Daniel Veillardd2379012002-03-15 22:24:56 +00001183 Py_INCREF(Py_None);
1184 return (Py_None);
Daniel Veillard8d24cc12002-03-05 15:41:29 +00001185 }
1186 SAX = &pythonSaxHandler;
1187 Py_INCREF(pyobj_SAX);
1188 /* The reference is released in pythonEndDocument() */
1189 htmlSAXParseFile(URI, encoding, SAX, pyobj_SAX);
1190 Py_INCREF(Py_None);
Daniel Veillardd2379012002-03-15 22:24:56 +00001191 return (Py_None);
Daniel Veillard8d24cc12002-03-05 15:41:29 +00001192}
1193
Daniel Veillard5d819032002-02-02 21:49:17 +00001194/************************************************************************
1195 * *
1196 * Error message callback *
1197 * *
1198 ************************************************************************/
1199
1200static PyObject *libxml_xmlPythonErrorFuncHandler = NULL;
1201static PyObject *libxml_xmlPythonErrorFuncCtxt = NULL;
1202
Daniel Veillarde6227e02003-01-14 11:42:39 +00001203/* helper to build a xmlMalloc'ed string from a format and va_list */
1204static char *
1205libxml_buildMessage(const char *msg, va_list ap)
Daniel Veillardd2379012002-03-15 22:24:56 +00001206{
1207 int size;
1208 int chars;
1209 char *larger;
Daniel Veillarde6227e02003-01-14 11:42:39 +00001210 char *str;
1211
1212 str = (char *) xmlMalloc(150);
1213 if (str == NULL)
1214 return NULL;
1215
1216 size = 150;
1217
1218 while (1) {
1219 chars = vsnprintf(str, size, msg, ap);
1220 if ((chars > -1) && (chars < size))
1221 break;
1222 if (chars > -1)
1223 size += chars + 1;
1224 else
1225 size += 100;
1226 if ((larger = (char *) xmlRealloc(str, size)) == NULL) {
1227 xmlFree(str);
1228 return NULL;
1229 }
1230 str = larger;
1231 }
1232
1233 return str;
1234}
1235
1236static void
1237libxml_xmlErrorFuncHandler(ATTRIBUTE_UNUSED void *ctx, const char *msg,
1238 ...)
1239{
Daniel Veillardd2379012002-03-15 22:24:56 +00001240 va_list ap;
1241 char *str;
Daniel Veillard5d819032002-02-02 21:49:17 +00001242 PyObject *list;
1243 PyObject *message;
1244 PyObject *result;
1245
1246#ifdef DEBUG_ERROR
1247 printf("libxml_xmlErrorFuncHandler(%p, %s, ...) called\n", ctx, msg);
1248#endif
1249
1250
1251 if (libxml_xmlPythonErrorFuncHandler == NULL) {
Daniel Veillardd2379012002-03-15 22:24:56 +00001252 va_start(ap, msg);
Daniel Veillard007d51e2003-09-17 20:07:28 +00001253 vfprintf(stderr, msg, ap);
Daniel Veillardd2379012002-03-15 22:24:56 +00001254 va_end(ap);
Daniel Veillard5d819032002-02-02 21:49:17 +00001255 } else {
Daniel Veillarde6227e02003-01-14 11:42:39 +00001256 va_start(ap, msg);
1257 str = libxml_buildMessage(msg,ap);
1258 va_end(ap);
Daniel Veillard5d819032002-02-02 21:49:17 +00001259
Daniel Veillardd2379012002-03-15 22:24:56 +00001260 list = PyTuple_New(2);
1261 PyTuple_SetItem(list, 0, libxml_xmlPythonErrorFuncCtxt);
1262 Py_XINCREF(libxml_xmlPythonErrorFuncCtxt);
1263 message = libxml_charPtrWrap(str);
1264 PyTuple_SetItem(list, 1, message);
1265 result = PyEval_CallObject(libxml_xmlPythonErrorFuncHandler, list);
1266 Py_XDECREF(list);
1267 Py_XDECREF(result);
Daniel Veillard5d819032002-02-02 21:49:17 +00001268 }
1269}
1270
1271static void
Daniel Veillardd2379012002-03-15 22:24:56 +00001272libxml_xmlErrorInitialize(void)
1273{
Daniel Veillard5d819032002-02-02 21:49:17 +00001274#ifdef DEBUG_ERROR
1275 printf("libxml_xmlErrorInitialize() called\n");
1276#endif
1277 xmlSetGenericErrorFunc(NULL, libxml_xmlErrorFuncHandler);
Daniel Veillard781ac8b2003-05-15 22:11:36 +00001278 xmlThrDefSetGenericErrorFunc(NULL, libxml_xmlErrorFuncHandler);
Daniel Veillard5d819032002-02-02 21:49:17 +00001279}
1280
Daniel Veillardc2664642003-07-29 20:44:53 +00001281static PyObject *
Daniel Veillardd2379012002-03-15 22:24:56 +00001282libxml_xmlRegisterErrorHandler(ATTRIBUTE_UNUSED PyObject * self,
1283 PyObject * args)
1284{
Daniel Veillard5d819032002-02-02 21:49:17 +00001285 PyObject *py_retval;
1286 PyObject *pyobj_f;
1287 PyObject *pyobj_ctx;
1288
Daniel Veillardd2379012002-03-15 22:24:56 +00001289 if (!PyArg_ParseTuple
1290 (args, (char *) "OO:xmlRegisterErrorHandler", &pyobj_f,
1291 &pyobj_ctx))
1292 return (NULL);
Daniel Veillard5d819032002-02-02 21:49:17 +00001293
1294#ifdef DEBUG_ERROR
Daniel Veillardd2379012002-03-15 22:24:56 +00001295 printf("libxml_registerXPathFunction(%p, %p) called\n", pyobj_ctx,
1296 pyobj_f);
Daniel Veillard5d819032002-02-02 21:49:17 +00001297#endif
1298
1299 if (libxml_xmlPythonErrorFuncHandler != NULL) {
Daniel Veillardd2379012002-03-15 22:24:56 +00001300 Py_XDECREF(libxml_xmlPythonErrorFuncHandler);
Daniel Veillard5d819032002-02-02 21:49:17 +00001301 }
1302 if (libxml_xmlPythonErrorFuncCtxt != NULL) {
Daniel Veillardd2379012002-03-15 22:24:56 +00001303 Py_XDECREF(libxml_xmlPythonErrorFuncCtxt);
Daniel Veillard5d819032002-02-02 21:49:17 +00001304 }
1305
1306 Py_XINCREF(pyobj_ctx);
1307 Py_XINCREF(pyobj_f);
1308
1309 /* TODO: check f is a function ! */
1310 libxml_xmlPythonErrorFuncHandler = pyobj_f;
1311 libxml_xmlPythonErrorFuncCtxt = pyobj_ctx;
1312
1313 py_retval = libxml_intWrap(1);
Daniel Veillardd2379012002-03-15 22:24:56 +00001314 return (py_retval);
Daniel Veillard5d819032002-02-02 21:49:17 +00001315}
Daniel Veillardd2379012002-03-15 22:24:56 +00001316
Daniel Veillarde6227e02003-01-14 11:42:39 +00001317
1318/************************************************************************
1319 * *
1320 * Per parserCtxt error handler *
1321 * *
1322 ************************************************************************/
1323
Daniel Veillard417be3a2003-01-20 21:26:34 +00001324typedef struct
Daniel Veillarde6227e02003-01-14 11:42:39 +00001325{
Daniel Veillard417be3a2003-01-20 21:26:34 +00001326 PyObject *f;
1327 PyObject *arg;
1328} xmlParserCtxtPyCtxt;
1329typedef xmlParserCtxtPyCtxt *xmlParserCtxtPyCtxtPtr;
1330
1331static void
1332libxml_xmlParserCtxtGenericErrorFuncHandler(void *ctx, int severity, char *str)
1333{
Daniel Veillarde6227e02003-01-14 11:42:39 +00001334 PyObject *list;
Daniel Veillarde6227e02003-01-14 11:42:39 +00001335 PyObject *result;
Daniel Veillard417be3a2003-01-20 21:26:34 +00001336 xmlParserCtxtPtr ctxt;
Daniel Veillarde6227e02003-01-14 11:42:39 +00001337 xmlParserCtxtPyCtxtPtr pyCtxt;
1338
1339#ifdef DEBUG_ERROR
Daniel Veillard417be3a2003-01-20 21:26:34 +00001340 printf("libxml_xmlParserCtxtGenericErrorFuncHandler(%p, %s, ...) called\n", ctx, msg);
Daniel Veillarde6227e02003-01-14 11:42:39 +00001341#endif
1342
Daniel Veillard417be3a2003-01-20 21:26:34 +00001343 ctxt = (xmlParserCtxtPtr)ctx;
1344 pyCtxt = (xmlParserCtxtPyCtxtPtr)ctxt->_private;
Daniel Veillarde6227e02003-01-14 11:42:39 +00001345
Daniel Veillard417be3a2003-01-20 21:26:34 +00001346 list = PyTuple_New(4);
1347 PyTuple_SetItem(list, 0, pyCtxt->arg);
1348 Py_XINCREF(pyCtxt->arg);
1349 PyTuple_SetItem(list, 1, libxml_charPtrWrap(str));
1350 PyTuple_SetItem(list, 2, libxml_intWrap(severity));
1351 PyTuple_SetItem(list, 3, Py_None);
1352 Py_INCREF(Py_None);
1353 result = PyEval_CallObject(pyCtxt->f, list);
1354 if (result == NULL)
1355 {
1356 /* TODO: manage for the exception to be propagated... */
1357 PyErr_Print();
Daniel Veillarde6227e02003-01-14 11:42:39 +00001358 }
Daniel Veillard417be3a2003-01-20 21:26:34 +00001359 Py_XDECREF(list);
1360 Py_XDECREF(result);
1361}
1362
1363static void
1364libxml_xmlParserCtxtErrorFuncHandler(void *ctx, const char *msg, ...)
1365{
1366 va_list ap;
1367
1368 va_start(ap, msg);
1369 libxml_xmlParserCtxtGenericErrorFuncHandler(ctx,XML_PARSER_SEVERITY_ERROR,libxml_buildMessage(msg,ap));
1370 va_end(ap);
1371}
1372
1373static void
1374libxml_xmlParserCtxtWarningFuncHandler(void *ctx, const char *msg, ...)
1375{
1376 va_list ap;
1377
1378 va_start(ap, msg);
1379 libxml_xmlParserCtxtGenericErrorFuncHandler(ctx,XML_PARSER_SEVERITY_WARNING,libxml_buildMessage(msg,ap));
1380 va_end(ap);
1381}
1382
1383static void
1384libxml_xmlParserCtxtValidityErrorFuncHandler(void *ctx, const char *msg, ...)
1385{
1386 va_list ap;
1387
1388 va_start(ap, msg);
1389 libxml_xmlParserCtxtGenericErrorFuncHandler(ctx,XML_PARSER_SEVERITY_VALIDITY_ERROR,libxml_buildMessage(msg,ap));
1390 va_end(ap);
1391}
1392
1393static void
1394libxml_xmlParserCtxtValidityWarningFuncHandler(void *ctx, const char *msg, ...)
1395{
1396 va_list ap;
1397
1398 va_start(ap, msg);
1399 libxml_xmlParserCtxtGenericErrorFuncHandler(ctx,XML_PARSER_SEVERITY_VALIDITY_WARNING,libxml_buildMessage(msg,ap));
1400 va_end(ap);
Daniel Veillarde6227e02003-01-14 11:42:39 +00001401}
1402
Daniel Veillardc2664642003-07-29 20:44:53 +00001403static PyObject *
Daniel Veillard417be3a2003-01-20 21:26:34 +00001404libxml_xmlParserCtxtSetErrorHandler(ATTRIBUTE_UNUSED PyObject *self, PyObject *args)
Daniel Veillarde6227e02003-01-14 11:42:39 +00001405{
1406 PyObject *py_retval;
1407 xmlParserCtxtPtr ctxt;
Daniel Veillarde4a07e72003-01-14 14:40:25 +00001408 xmlParserCtxtPyCtxtPtr pyCtxt;
Daniel Veillarde6227e02003-01-14 11:42:39 +00001409 PyObject *pyobj_ctxt;
1410 PyObject *pyobj_f;
1411 PyObject *pyobj_arg;
1412
Daniel Veillard417be3a2003-01-20 21:26:34 +00001413 if (!PyArg_ParseTuple(args, (char *)"OOO:xmlParserCtxtSetErrorHandler",
Daniel Veillarde6227e02003-01-14 11:42:39 +00001414 &pyobj_ctxt, &pyobj_f, &pyobj_arg))
1415 return(NULL);
1416 ctxt = (xmlParserCtxtPtr) PyparserCtxt_Get(pyobj_ctxt);
1417 if (ctxt->_private == NULL) {
Daniel Veillarde6227e02003-01-14 11:42:39 +00001418 pyCtxt = xmlMalloc(sizeof(xmlParserCtxtPyCtxt));
1419 if (pyCtxt == NULL) {
1420 py_retval = libxml_intWrap(-1);
1421 return(py_retval);
1422 }
1423 memset(pyCtxt,0,sizeof(xmlParserCtxtPyCtxt));
1424 ctxt->_private = pyCtxt;
1425 }
Daniel Veillarde4a07e72003-01-14 14:40:25 +00001426 else {
Daniel Veillard417be3a2003-01-20 21:26:34 +00001427 pyCtxt = (xmlParserCtxtPyCtxtPtr)ctxt->_private;
Daniel Veillarde4a07e72003-01-14 14:40:25 +00001428 }
Daniel Veillarde6227e02003-01-14 11:42:39 +00001429 /* TODO: check f is a function ! */
Daniel Veillard417be3a2003-01-20 21:26:34 +00001430 Py_XDECREF(pyCtxt->f);
Daniel Veillarde6227e02003-01-14 11:42:39 +00001431 Py_XINCREF(pyobj_f);
Daniel Veillard417be3a2003-01-20 21:26:34 +00001432 pyCtxt->f = pyobj_f;
1433 Py_XDECREF(pyCtxt->arg);
Daniel Veillarde6227e02003-01-14 11:42:39 +00001434 Py_XINCREF(pyobj_arg);
Daniel Veillard417be3a2003-01-20 21:26:34 +00001435 pyCtxt->arg = pyobj_arg;
Daniel Veillarde6227e02003-01-14 11:42:39 +00001436
Daniel Veillard417be3a2003-01-20 21:26:34 +00001437 if (pyobj_f != Py_None) {
1438 ctxt->sax->error = libxml_xmlParserCtxtErrorFuncHandler;
1439 ctxt->sax->warning = libxml_xmlParserCtxtWarningFuncHandler;
1440 ctxt->vctxt.error = libxml_xmlParserCtxtValidityErrorFuncHandler;
1441 ctxt->vctxt.warning = libxml_xmlParserCtxtValidityWarningFuncHandler;
1442 }
1443 else {
1444 ctxt->sax->error = xmlParserError;
1445 ctxt->vctxt.error = xmlParserValidityError;
1446 ctxt->sax->warning = xmlParserWarning;
1447 ctxt->vctxt.warning = xmlParserValidityWarning;
1448 }
Daniel Veillarde6227e02003-01-14 11:42:39 +00001449
1450 py_retval = libxml_intWrap(1);
1451 return(py_retval);
1452}
1453
Daniel Veillardc2664642003-07-29 20:44:53 +00001454static PyObject *
Daniel Veillard417be3a2003-01-20 21:26:34 +00001455libxml_xmlParserCtxtGetErrorHandler(ATTRIBUTE_UNUSED PyObject *self, PyObject *args)
Daniel Veillarde6227e02003-01-14 11:42:39 +00001456{
1457 PyObject *py_retval;
1458 xmlParserCtxtPtr ctxt;
Daniel Veillarde4a07e72003-01-14 14:40:25 +00001459 xmlParserCtxtPyCtxtPtr pyCtxt;
Daniel Veillarde6227e02003-01-14 11:42:39 +00001460 PyObject *pyobj_ctxt;
Daniel Veillarde6227e02003-01-14 11:42:39 +00001461
Daniel Veillard417be3a2003-01-20 21:26:34 +00001462 if (!PyArg_ParseTuple(args, (char *)"O:xmlParserCtxtGetErrorHandler",
1463 &pyobj_ctxt))
Daniel Veillarde6227e02003-01-14 11:42:39 +00001464 return(NULL);
1465 ctxt = (xmlParserCtxtPtr) PyparserCtxt_Get(pyobj_ctxt);
Daniel Veillard417be3a2003-01-20 21:26:34 +00001466 py_retval = PyTuple_New(2);
1467 if (ctxt->_private != NULL) {
1468 pyCtxt = (xmlParserCtxtPyCtxtPtr)ctxt->_private;
1469
1470 PyTuple_SetItem(py_retval, 0, pyCtxt->f);
1471 Py_XINCREF(pyCtxt->f);
1472 PyTuple_SetItem(py_retval, 1, pyCtxt->arg);
1473 Py_XINCREF(pyCtxt->arg);
Daniel Veillarde4a07e72003-01-14 14:40:25 +00001474 }
1475 else {
Daniel Veillard417be3a2003-01-20 21:26:34 +00001476 /* no python error handler registered */
1477 PyTuple_SetItem(py_retval, 0, Py_None);
1478 Py_XINCREF(Py_None);
1479 PyTuple_SetItem(py_retval, 1, Py_None);
1480 Py_XINCREF(Py_None);
Daniel Veillarde4a07e72003-01-14 14:40:25 +00001481 }
Daniel Veillarde6227e02003-01-14 11:42:39 +00001482 return(py_retval);
1483}
1484
Daniel Veillardc2664642003-07-29 20:44:53 +00001485static PyObject *
Daniel Veillard417be3a2003-01-20 21:26:34 +00001486libxml_xmlFreeParserCtxt(ATTRIBUTE_UNUSED PyObject *self, PyObject *args) {
1487 xmlParserCtxtPtr ctxt;
1488 PyObject *pyobj_ctxt;
1489 xmlParserCtxtPyCtxtPtr pyCtxt;
1490
1491 if (!PyArg_ParseTuple(args, (char *)"O:xmlFreeParserCtxt", &pyobj_ctxt))
1492 return(NULL);
1493 ctxt = (xmlParserCtxtPtr) PyparserCtxt_Get(pyobj_ctxt);
1494
1495 if (ctxt != NULL) {
1496 pyCtxt = (xmlParserCtxtPyCtxtPtr)((xmlParserCtxtPtr)ctxt)->_private;
1497 if (pyCtxt) {
1498 Py_XDECREF(pyCtxt->f);
1499 Py_XDECREF(pyCtxt->arg);
1500 xmlFree(pyCtxt);
1501 }
1502 xmlFreeParserCtxt(ctxt);
1503 }
1504
1505 Py_INCREF(Py_None);
1506 return(Py_None);
1507}
1508
Daniel Veillarda7340c82002-02-01 17:56:45 +00001509/************************************************************************
1510 * *
Daniel Veillard26f70262003-01-16 22:45:08 +00001511 * Per xmlTextReader error handler *
1512 * *
1513 ************************************************************************/
1514
1515typedef struct
1516{
1517 PyObject *f;
1518 PyObject *arg;
1519} xmlTextReaderPyCtxt;
1520typedef xmlTextReaderPyCtxt *xmlTextReaderPyCtxtPtr;
1521
1522static void
1523libxml_xmlTextReaderErrorCallback(void *arg,
1524 const char *msg,
Daniel Veillard417be3a2003-01-20 21:26:34 +00001525 int severity,
1526 xmlTextReaderLocatorPtr locator)
Daniel Veillard26f70262003-01-16 22:45:08 +00001527{
1528 xmlTextReaderPyCtxt *pyCtxt = (xmlTextReaderPyCtxt *)arg;
1529 PyObject *list;
1530 PyObject *result;
1531
Daniel Veillard417be3a2003-01-20 21:26:34 +00001532 list = PyTuple_New(4);
Daniel Veillard26f70262003-01-16 22:45:08 +00001533 PyTuple_SetItem(list, 0, pyCtxt->arg);
1534 Py_XINCREF(pyCtxt->arg);
1535 PyTuple_SetItem(list, 1, libxml_charPtrConstWrap(msg));
Daniel Veillard417be3a2003-01-20 21:26:34 +00001536 PyTuple_SetItem(list, 2, libxml_intWrap(severity));
1537 PyTuple_SetItem(list, 3, libxml_xmlTextReaderLocatorPtrWrap(locator));
Daniel Veillard26f70262003-01-16 22:45:08 +00001538 result = PyEval_CallObject(pyCtxt->f, list);
1539 if (result == NULL)
1540 {
Daniel Veillard417be3a2003-01-20 21:26:34 +00001541 /* TODO: manage for the exception to be propagated... */
Daniel Veillard26f70262003-01-16 22:45:08 +00001542 PyErr_Print();
1543 }
1544 Py_XDECREF(list);
1545 Py_XDECREF(result);
1546}
1547
Daniel Veillardc2664642003-07-29 20:44:53 +00001548static PyObject *
Daniel Veillard26f70262003-01-16 22:45:08 +00001549libxml_xmlTextReaderSetErrorHandler(ATTRIBUTE_UNUSED PyObject *self, PyObject *args)
1550{
1551 xmlTextReaderPtr reader;
1552 xmlTextReaderPyCtxtPtr pyCtxt;
1553 xmlTextReaderErrorFunc f;
1554 void *arg;
1555 PyObject *pyobj_reader;
1556 PyObject *pyobj_f;
1557 PyObject *pyobj_arg;
1558 PyObject *py_retval;
1559
1560 if (!PyArg_ParseTuple(args, (char *)"OOO:xmlTextReaderSetErrorHandler", &pyobj_reader, &pyobj_f, &pyobj_arg))
1561 return(NULL);
1562 reader = (xmlTextReaderPtr) PyxmlTextReader_Get(pyobj_reader);
1563 /* clear previous error handler */
1564 xmlTextReaderGetErrorHandler(reader,&f,&arg);
1565 if (arg != NULL) {
Daniel Veillardc2664642003-07-29 20:44:53 +00001566 if (f == (xmlTextReaderErrorFunc) libxml_xmlTextReaderErrorCallback) {
Daniel Veillard26f70262003-01-16 22:45:08 +00001567 /* ok, it's our error handler! */
1568 pyCtxt = (xmlTextReaderPyCtxtPtr)arg;
1569 Py_XDECREF(pyCtxt->f);
1570 Py_XDECREF(pyCtxt->arg);
1571 xmlFree(pyCtxt);
1572 }
1573 else {
1574 /*
1575 * there already an arg, and it's not ours,
1576 * there is definitely something wrong going on here...
1577 * we don't know how to free it, so we bail out...
1578 */
1579 py_retval = libxml_intWrap(-1);
1580 return(py_retval);
1581 }
1582 }
1583 xmlTextReaderSetErrorHandler(reader,NULL,NULL);
1584 /* set new error handler */
1585 if (pyobj_f != Py_None)
1586 {
1587 pyCtxt = (xmlTextReaderPyCtxtPtr)xmlMalloc(sizeof(xmlTextReaderPyCtxt));
1588 if (pyCtxt == NULL) {
1589 py_retval = libxml_intWrap(-1);
1590 return(py_retval);
1591 }
1592 Py_XINCREF(pyobj_f);
1593 pyCtxt->f = pyobj_f;
1594 Py_XINCREF(pyobj_arg);
1595 pyCtxt->arg = pyobj_arg;
Daniel Veillardc2664642003-07-29 20:44:53 +00001596 xmlTextReaderSetErrorHandler(reader,
1597 (xmlTextReaderErrorFunc) libxml_xmlTextReaderErrorCallback,
1598 pyCtxt);
Daniel Veillard26f70262003-01-16 22:45:08 +00001599 }
1600
1601 py_retval = libxml_intWrap(1);
1602 return(py_retval);
1603}
1604
Daniel Veillardc2664642003-07-29 20:44:53 +00001605static PyObject *
Daniel Veillard26f70262003-01-16 22:45:08 +00001606libxml_xmlTextReaderGetErrorHandler(ATTRIBUTE_UNUSED PyObject *self, PyObject *args)
1607{
1608 xmlTextReaderPtr reader;
1609 xmlTextReaderPyCtxtPtr pyCtxt;
1610 xmlTextReaderErrorFunc f;
1611 void *arg;
1612 PyObject *pyobj_reader;
1613 PyObject *py_retval;
1614
1615 if (!PyArg_ParseTuple(args, (char *)"O:xmlTextReaderSetErrorHandler", &pyobj_reader))
1616 return(NULL);
1617 reader = (xmlTextReaderPtr) PyxmlTextReader_Get(pyobj_reader);
1618 xmlTextReaderGetErrorHandler(reader,&f,&arg);
1619 py_retval = PyTuple_New(2);
Daniel Veillardc2664642003-07-29 20:44:53 +00001620 if (f == (xmlTextReaderErrorFunc)libxml_xmlTextReaderErrorCallback) {
Daniel Veillard26f70262003-01-16 22:45:08 +00001621 /* ok, it's our error handler! */
1622 pyCtxt = (xmlTextReaderPyCtxtPtr)arg;
1623 PyTuple_SetItem(py_retval, 0, pyCtxt->f);
1624 Py_XINCREF(pyCtxt->f);
1625 PyTuple_SetItem(py_retval, 1, pyCtxt->arg);
1626 Py_XINCREF(pyCtxt->arg);
1627 }
1628 else
1629 {
1630 /* f is null or it's not our error handler */
1631 PyTuple_SetItem(py_retval, 0, Py_None);
1632 Py_XINCREF(Py_None);
1633 PyTuple_SetItem(py_retval, 1, Py_None);
1634 Py_XINCREF(Py_None);
1635 }
1636 return(py_retval);
1637}
1638
Daniel Veillardc2664642003-07-29 20:44:53 +00001639static PyObject *
Daniel Veillard26f70262003-01-16 22:45:08 +00001640libxml_xmlFreeTextReader(ATTRIBUTE_UNUSED PyObject *self, PyObject *args) {
1641 xmlTextReaderPtr reader;
1642 PyObject *pyobj_reader;
1643 xmlTextReaderPyCtxtPtr pyCtxt;
1644 xmlTextReaderErrorFunc f;
1645 void *arg;
1646
Daniel Veillard157fee02003-10-31 10:36:03 +00001647 if (!PyArg_ParseTuple(args, (char *)"O:xmlFreeTextReader", &pyobj_reader))
1648 return(NULL);
1649 if (!PyCObject_Check(pyobj_reader)) {
Daniel Veillardbb3ba322003-10-30 13:12:43 +00001650 Py_INCREF(Py_None);
1651 return(Py_None);
1652 }
Daniel Veillard26f70262003-01-16 22:45:08 +00001653 reader = (xmlTextReaderPtr) PyxmlTextReader_Get(pyobj_reader);
Daniel Veillardbb3ba322003-10-30 13:12:43 +00001654 if (reader == NULL) {
1655 Py_INCREF(Py_None);
1656 return(Py_None);
1657 }
Daniel Veillard26f70262003-01-16 22:45:08 +00001658
1659 xmlTextReaderGetErrorHandler(reader,&f,&arg);
1660 if (arg != NULL) {
Daniel Veillardc2664642003-07-29 20:44:53 +00001661 if (f == (xmlTextReaderErrorFunc) libxml_xmlTextReaderErrorCallback) {
Daniel Veillard26f70262003-01-16 22:45:08 +00001662 /* ok, it's our error handler! */
1663 pyCtxt = (xmlTextReaderPyCtxtPtr)arg;
1664 Py_XDECREF(pyCtxt->f);
1665 Py_XDECREF(pyCtxt->arg);
1666 xmlFree(pyCtxt);
1667 }
1668 /*
1669 * else, something wrong happened, because the error handler is
1670 * not owned by the python bindings...
1671 */
1672 }
1673
1674 xmlFreeTextReader(reader);
1675 Py_INCREF(Py_None);
1676 return(Py_None);
1677}
1678
1679/************************************************************************
1680 * *
Daniel Veillarda7340c82002-02-01 17:56:45 +00001681 * XPath extensions *
1682 * *
1683 ************************************************************************/
1684
1685static int libxml_xpathCallbacksInitialized = 0;
1686
1687typedef struct libxml_xpathCallback {
1688 xmlXPathContextPtr ctx;
1689 xmlChar *name;
1690 xmlChar *ns_uri;
1691 PyObject *function;
1692} libxml_xpathCallback, *libxml_xpathCallbackPtr;
1693static libxml_xpathCallback libxml_xpathCallbacks[10];
1694static int libxml_xpathCallbacksNb = 0;
1695static int libxml_xpathCallbacksMax = 10;
1696
Daniel Veillarda7340c82002-02-01 17:56:45 +00001697static void
Daniel Veillardd2379012002-03-15 22:24:56 +00001698libxml_xmlXPathFuncCallback(xmlXPathParserContextPtr ctxt, int nargs)
1699{
Daniel Veillarda7340c82002-02-01 17:56:45 +00001700 PyObject *list, *cur, *result;
1701 xmlXPathObjectPtr obj;
Daniel Veillard70cab352002-02-06 16:06:58 +00001702 xmlXPathContextPtr rctxt;
1703 PyObject *current_function = NULL;
1704 const xmlChar *name;
1705 const xmlChar *ns_uri;
Daniel Veillarda7340c82002-02-01 17:56:45 +00001706 int i;
1707
Daniel Veillard70cab352002-02-06 16:06:58 +00001708 if (ctxt == NULL)
Daniel Veillardd2379012002-03-15 22:24:56 +00001709 return;
Daniel Veillard70cab352002-02-06 16:06:58 +00001710 rctxt = ctxt->context;
1711 if (rctxt == NULL)
Daniel Veillardd2379012002-03-15 22:24:56 +00001712 return;
Daniel Veillard70cab352002-02-06 16:06:58 +00001713 name = rctxt->function;
1714 ns_uri = rctxt->functionURI;
Daniel Veillarda7340c82002-02-01 17:56:45 +00001715#ifdef DEBUG_XPATH
Daniel Veillardd2379012002-03-15 22:24:56 +00001716 printf("libxml_xmlXPathFuncCallback called name %s URI %s\n", name,
1717 ns_uri);
Daniel Veillarda7340c82002-02-01 17:56:45 +00001718#endif
1719
Daniel Veillard70cab352002-02-06 16:06:58 +00001720 /*
1721 * Find the function, it should be there it was there at lookup
1722 */
Daniel Veillardd2379012002-03-15 22:24:56 +00001723 for (i = 0; i < libxml_xpathCallbacksNb; i++) {
1724 if ( /* TODO (ctxt == libxml_xpathCallbacks[i].ctx) && */
1725 (xmlStrEqual(name, libxml_xpathCallbacks[i].name)) &&
1726 (xmlStrEqual(ns_uri, libxml_xpathCallbacks[i].ns_uri))) {
1727 current_function = libxml_xpathCallbacks[i].function;
1728 }
Daniel Veillard70cab352002-02-06 16:06:58 +00001729 }
1730 if (current_function == NULL) {
Daniel Veillardd2379012002-03-15 22:24:56 +00001731 printf
1732 ("libxml_xmlXPathFuncCallback: internal error %s not found !\n",
1733 name);
1734 return;
Daniel Veillard70cab352002-02-06 16:06:58 +00001735 }
1736
Daniel Veillardc575b992002-02-08 13:28:40 +00001737 list = PyTuple_New(nargs + 1);
1738 PyTuple_SetItem(list, 0, libxml_xmlXPathParserContextPtrWrap(ctxt));
Daniel Veillardd2379012002-03-15 22:24:56 +00001739 for (i = 0; i < nargs; i++) {
1740 obj = valuePop(ctxt);
1741 cur = libxml_xmlXPathObjectPtrWrap(obj);
1742 PyTuple_SetItem(list, i + 1, cur);
Daniel Veillarda7340c82002-02-01 17:56:45 +00001743 }
1744 result = PyEval_CallObject(current_function, list);
1745 Py_DECREF(list);
1746
1747 obj = libxml_xmlXPathObjectPtrConvert(result);
1748 valuePush(ctxt, obj);
1749}
1750
1751static xmlXPathFunction
Daniel Veillardd2379012002-03-15 22:24:56 +00001752libxml_xmlXPathFuncLookupFunc(void *ctxt, const xmlChar * name,
1753 const xmlChar * ns_uri)
1754{
Daniel Veillarda7340c82002-02-01 17:56:45 +00001755 int i;
Daniel Veillardd2379012002-03-15 22:24:56 +00001756
Daniel Veillarda7340c82002-02-01 17:56:45 +00001757#ifdef DEBUG_XPATH
1758 printf("libxml_xmlXPathFuncLookupFunc(%p, %s, %s) called\n",
Daniel Veillardd2379012002-03-15 22:24:56 +00001759 ctxt, name, ns_uri);
Daniel Veillarda7340c82002-02-01 17:56:45 +00001760#endif
Daniel Veillard70cab352002-02-06 16:06:58 +00001761 /*
1762 * This is called once only. The address is then stored in the
1763 * XPath expression evaluation, the proper object to call can
1764 * then still be found using the execution context function
1765 * and functionURI fields.
1766 */
Daniel Veillardd2379012002-03-15 22:24:56 +00001767 for (i = 0; i < libxml_xpathCallbacksNb; i++) {
1768 if ((ctxt == libxml_xpathCallbacks[i].ctx) &&
1769 (xmlStrEqual(name, libxml_xpathCallbacks[i].name)) &&
1770 (xmlStrEqual(ns_uri, libxml_xpathCallbacks[i].ns_uri))) {
1771 return (libxml_xmlXPathFuncCallback);
1772 }
Daniel Veillarda7340c82002-02-01 17:56:45 +00001773 }
Daniel Veillardd2379012002-03-15 22:24:56 +00001774 return (NULL);
Daniel Veillarda7340c82002-02-01 17:56:45 +00001775}
1776
1777static void
Daniel Veillardd2379012002-03-15 22:24:56 +00001778libxml_xpathCallbacksInitialize(void)
1779{
Daniel Veillarda7340c82002-02-01 17:56:45 +00001780 int i;
1781
1782 if (libxml_xpathCallbacksInitialized != 0)
Daniel Veillardd2379012002-03-15 22:24:56 +00001783 return;
Daniel Veillarda7340c82002-02-01 17:56:45 +00001784
1785#ifdef DEBUG_XPATH
1786 printf("libxml_xpathCallbacksInitialized called\n");
1787#endif
1788
Daniel Veillard781ac8b2003-05-15 22:11:36 +00001789 for (i = 0; i < libxml_xpathCallbacksMax; i++) {
Daniel Veillardd2379012002-03-15 22:24:56 +00001790 libxml_xpathCallbacks[i].ctx = NULL;
1791 libxml_xpathCallbacks[i].name = NULL;
1792 libxml_xpathCallbacks[i].ns_uri = NULL;
1793 libxml_xpathCallbacks[i].function = NULL;
Daniel Veillarda7340c82002-02-01 17:56:45 +00001794 }
Daniel Veillarda7340c82002-02-01 17:56:45 +00001795 libxml_xpathCallbacksInitialized = 1;
1796}
1797
1798PyObject *
Daniel Veillardd2379012002-03-15 22:24:56 +00001799libxml_xmlRegisterXPathFunction(ATTRIBUTE_UNUSED PyObject * self,
1800 PyObject * args)
1801{
Daniel Veillarda7340c82002-02-01 17:56:45 +00001802 PyObject *py_retval;
1803 int c_retval = 0;
1804 xmlChar *name;
1805 xmlChar *ns_uri;
1806 xmlXPathContextPtr ctx;
1807 PyObject *pyobj_ctx;
1808 PyObject *pyobj_f;
1809 int i;
1810
Daniel Veillardd2379012002-03-15 22:24:56 +00001811 if (!PyArg_ParseTuple
1812 (args, (char *) "OszO:registerXPathFunction", &pyobj_ctx, &name,
1813 &ns_uri, &pyobj_f))
1814 return (NULL);
Daniel Veillarda7340c82002-02-01 17:56:45 +00001815
1816 ctx = (xmlXPathContextPtr) PyxmlXPathContext_Get(pyobj_ctx);
1817 if (libxml_xpathCallbacksInitialized == 0)
Daniel Veillardd2379012002-03-15 22:24:56 +00001818 libxml_xpathCallbacksInitialize();
Daniel Veillarda7340c82002-02-01 17:56:45 +00001819 xmlXPathRegisterFuncLookup(ctx, libxml_xmlXPathFuncLookupFunc, ctx);
1820
1821 if ((pyobj_ctx == NULL) || (name == NULL) || (pyobj_f == NULL)) {
Daniel Veillardd2379012002-03-15 22:24:56 +00001822 py_retval = libxml_intWrap(-1);
1823 return (py_retval);
Daniel Veillarda7340c82002-02-01 17:56:45 +00001824 }
Daniel Veillarda7340c82002-02-01 17:56:45 +00001825#ifdef DEBUG_XPATH
1826 printf("libxml_registerXPathFunction(%p, %s, %s) called\n",
Daniel Veillardd2379012002-03-15 22:24:56 +00001827 ctx, name, ns_uri);
Daniel Veillarda7340c82002-02-01 17:56:45 +00001828#endif
Daniel Veillardd2379012002-03-15 22:24:56 +00001829 for (i = 0; i < libxml_xpathCallbacksNb; i++) {
1830 if ((ctx == libxml_xpathCallbacks[i].ctx) &&
1831 (xmlStrEqual(name, libxml_xpathCallbacks[i].name)) &&
1832 (xmlStrEqual(ns_uri, libxml_xpathCallbacks[i].ns_uri))) {
1833 Py_XINCREF(pyobj_f);
1834 Py_XDECREF(libxml_xpathCallbacks[i].function);
1835 libxml_xpathCallbacks[i].function = pyobj_f;
1836 c_retval = 1;
1837 goto done;
1838 }
Daniel Veillarda7340c82002-02-01 17:56:45 +00001839 }
1840 if (libxml_xpathCallbacksNb >= libxml_xpathCallbacksMax) {
Daniel Veillardd2379012002-03-15 22:24:56 +00001841 printf("libxml_registerXPathFunction() table full\n");
Daniel Veillarda7340c82002-02-01 17:56:45 +00001842 } else {
Daniel Veillardd2379012002-03-15 22:24:56 +00001843 i = libxml_xpathCallbacksNb++;
1844 Py_XINCREF(pyobj_f);
Daniel Veillarda7340c82002-02-01 17:56:45 +00001845 libxml_xpathCallbacks[i].ctx = ctx;
1846 libxml_xpathCallbacks[i].name = xmlStrdup(name);
1847 libxml_xpathCallbacks[i].ns_uri = xmlStrdup(ns_uri);
Daniel Veillardd2379012002-03-15 22:24:56 +00001848 libxml_xpathCallbacks[i].function = pyobj_f;
1849 c_retval = 1;
Daniel Veillarda7340c82002-02-01 17:56:45 +00001850 }
Daniel Veillardd2379012002-03-15 22:24:56 +00001851 done:
Daniel Veillarda7340c82002-02-01 17:56:45 +00001852 py_retval = libxml_intWrap((int) c_retval);
Daniel Veillardd2379012002-03-15 22:24:56 +00001853 return (py_retval);
Daniel Veillarda7340c82002-02-01 17:56:45 +00001854}
1855
Daniel Veillard1971ee22002-01-31 20:29:19 +00001856/************************************************************************
1857 * *
Daniel Veillardd2897fd2002-01-30 16:37:32 +00001858 * Global properties access *
1859 * *
1860 ************************************************************************/
1861static PyObject *
Daniel Veillardd2379012002-03-15 22:24:56 +00001862libxml_name(ATTRIBUTE_UNUSED PyObject * self, PyObject * args)
Daniel Veillardd2897fd2002-01-30 16:37:32 +00001863{
1864 PyObject *resultobj, *obj;
1865 xmlNodePtr cur;
1866 const xmlChar *res;
1867
Daniel Veillardd2379012002-03-15 22:24:56 +00001868 if (!PyArg_ParseTuple(args, (char *) "O:name", &obj))
Daniel Veillardd2897fd2002-01-30 16:37:32 +00001869 return NULL;
1870 cur = PyxmlNode_Get(obj);
1871
1872#ifdef DEBUG
1873 printf("libxml_name: cur = %p type %d\n", cur, cur->type);
1874#endif
1875
Daniel Veillardd2379012002-03-15 22:24:56 +00001876 switch (cur->type) {
1877 case XML_DOCUMENT_NODE:
Daniel Veillardd2897fd2002-01-30 16:37:32 +00001878#ifdef LIBXML_DOCB_ENABLED
Daniel Veillardd2379012002-03-15 22:24:56 +00001879 case XML_DOCB_DOCUMENT_NODE:
Daniel Veillardd2897fd2002-01-30 16:37:32 +00001880#endif
Daniel Veillardd2379012002-03-15 22:24:56 +00001881 case XML_HTML_DOCUMENT_NODE:{
1882 xmlDocPtr doc = (xmlDocPtr) cur;
1883
1884 res = doc->URL;
1885 break;
1886 }
1887 case XML_ATTRIBUTE_NODE:{
1888 xmlAttrPtr attr = (xmlAttrPtr) cur;
1889
1890 res = attr->name;
1891 break;
1892 }
1893 case XML_NAMESPACE_DECL:{
1894 xmlNsPtr ns = (xmlNsPtr) cur;
1895
1896 res = ns->prefix;
1897 break;
1898 }
1899 default:
1900 res = cur->name;
1901 break;
Daniel Veillardd2897fd2002-01-30 16:37:32 +00001902 }
Daniel Veillard1971ee22002-01-31 20:29:19 +00001903 resultobj = libxml_constxmlCharPtrWrap(res);
Daniel Veillardd2897fd2002-01-30 16:37:32 +00001904
1905 return resultobj;
1906}
1907
1908static PyObject *
Daniel Veillardd2379012002-03-15 22:24:56 +00001909libxml_doc(ATTRIBUTE_UNUSED PyObject * self, PyObject * args)
Daniel Veillardd2897fd2002-01-30 16:37:32 +00001910{
1911 PyObject *resultobj, *obj;
1912 xmlNodePtr cur;
1913 xmlDocPtr res;
1914
Daniel Veillardd2379012002-03-15 22:24:56 +00001915 if (!PyArg_ParseTuple(args, (char *) "O:doc", &obj))
Daniel Veillardd2897fd2002-01-30 16:37:32 +00001916 return NULL;
1917 cur = PyxmlNode_Get(obj);
1918
1919#ifdef DEBUG
1920 printf("libxml_doc: cur = %p\n", cur);
1921#endif
1922
Daniel Veillardd2379012002-03-15 22:24:56 +00001923 switch (cur->type) {
1924 case XML_DOCUMENT_NODE:
Daniel Veillardd2897fd2002-01-30 16:37:32 +00001925#ifdef LIBXML_DOCB_ENABLED
Daniel Veillardd2379012002-03-15 22:24:56 +00001926 case XML_DOCB_DOCUMENT_NODE:
Daniel Veillardd2897fd2002-01-30 16:37:32 +00001927#endif
Daniel Veillardd2379012002-03-15 22:24:56 +00001928 case XML_HTML_DOCUMENT_NODE:
1929 res = NULL;
1930 break;
1931 case XML_ATTRIBUTE_NODE:{
1932 xmlAttrPtr attr = (xmlAttrPtr) cur;
1933
1934 res = attr->doc;
1935 break;
1936 }
1937 case XML_NAMESPACE_DECL:
1938 res = NULL;
1939 break;
1940 default:
1941 res = cur->doc;
1942 break;
Daniel Veillardd2897fd2002-01-30 16:37:32 +00001943 }
1944 resultobj = libxml_xmlDocPtrWrap(res);
1945 return resultobj;
1946}
1947
1948static PyObject *
Daniel Veillardd2379012002-03-15 22:24:56 +00001949libxml_properties(ATTRIBUTE_UNUSED PyObject * self, PyObject * args)
Daniel Veillardd2897fd2002-01-30 16:37:32 +00001950{
1951 PyObject *resultobj, *obj;
1952 xmlNodePtr cur = NULL;
1953 xmlAttrPtr res;
1954
Daniel Veillardd2379012002-03-15 22:24:56 +00001955 if (!PyArg_ParseTuple(args, (char *) "O:properties", &obj))
Daniel Veillardd2897fd2002-01-30 16:37:32 +00001956 return NULL;
1957 cur = PyxmlNode_Get(obj);
1958 if (cur->type == XML_ELEMENT_NODE)
Daniel Veillardd2379012002-03-15 22:24:56 +00001959 res = cur->properties;
Daniel Veillardd2897fd2002-01-30 16:37:32 +00001960 else
Daniel Veillardd2379012002-03-15 22:24:56 +00001961 res = NULL;
Daniel Veillardd2897fd2002-01-30 16:37:32 +00001962 resultobj = libxml_xmlAttrPtrWrap(res);
1963 return resultobj;
1964}
1965
1966static PyObject *
Daniel Veillardd2379012002-03-15 22:24:56 +00001967libxml_next(ATTRIBUTE_UNUSED PyObject * self, PyObject * args)
Daniel Veillardd2897fd2002-01-30 16:37:32 +00001968{
1969 PyObject *resultobj, *obj;
1970 xmlNodePtr cur;
1971 xmlNodePtr res;
1972
Daniel Veillardd2379012002-03-15 22:24:56 +00001973 if (!PyArg_ParseTuple(args, (char *) "O:next", &obj))
Daniel Veillardd2897fd2002-01-30 16:37:32 +00001974 return NULL;
1975 cur = PyxmlNode_Get(obj);
1976
1977#ifdef DEBUG
1978 printf("libxml_next: cur = %p\n", cur);
1979#endif
1980
Daniel Veillardd2379012002-03-15 22:24:56 +00001981 switch (cur->type) {
1982 case XML_DOCUMENT_NODE:
Daniel Veillardd2897fd2002-01-30 16:37:32 +00001983#ifdef LIBXML_DOCB_ENABLED
Daniel Veillardd2379012002-03-15 22:24:56 +00001984 case XML_DOCB_DOCUMENT_NODE:
Daniel Veillardd2897fd2002-01-30 16:37:32 +00001985#endif
Daniel Veillardd2379012002-03-15 22:24:56 +00001986 case XML_HTML_DOCUMENT_NODE:
1987 res = NULL;
1988 break;
1989 case XML_ATTRIBUTE_NODE:{
1990 xmlAttrPtr attr = (xmlAttrPtr) cur;
1991
1992 res = (xmlNodePtr) attr->next;
1993 break;
1994 }
1995 case XML_NAMESPACE_DECL:{
1996 xmlNsPtr ns = (xmlNsPtr) cur;
1997
1998 res = (xmlNodePtr) ns->next;
1999 break;
2000 }
2001 default:
2002 res = cur->next;
2003 break;
Daniel Veillardd2897fd2002-01-30 16:37:32 +00002004
2005 }
2006 resultobj = libxml_xmlNodePtrWrap(res);
2007 return resultobj;
2008}
2009
2010static PyObject *
Daniel Veillardd2379012002-03-15 22:24:56 +00002011libxml_prev(ATTRIBUTE_UNUSED PyObject * self, PyObject * args)
Daniel Veillardd2897fd2002-01-30 16:37:32 +00002012{
2013 PyObject *resultobj, *obj;
2014 xmlNodePtr cur;
2015 xmlNodePtr res;
2016
Daniel Veillardd2379012002-03-15 22:24:56 +00002017 if (!PyArg_ParseTuple(args, (char *) "O:prev", &obj))
Daniel Veillardd2897fd2002-01-30 16:37:32 +00002018 return NULL;
2019 cur = PyxmlNode_Get(obj);
2020
2021#ifdef DEBUG
2022 printf("libxml_prev: cur = %p\n", cur);
2023#endif
2024
Daniel Veillardd2379012002-03-15 22:24:56 +00002025 switch (cur->type) {
2026 case XML_DOCUMENT_NODE:
Daniel Veillardd2897fd2002-01-30 16:37:32 +00002027#ifdef LIBXML_DOCB_ENABLED
Daniel Veillardd2379012002-03-15 22:24:56 +00002028 case XML_DOCB_DOCUMENT_NODE:
Daniel Veillardd2897fd2002-01-30 16:37:32 +00002029#endif
Daniel Veillardd2379012002-03-15 22:24:56 +00002030 case XML_HTML_DOCUMENT_NODE:
2031 res = NULL;
2032 break;
2033 case XML_ATTRIBUTE_NODE:{
2034 xmlAttrPtr attr = (xmlAttrPtr) cur;
2035
Daniel Veillardfaa35ff2002-11-24 13:53:43 +00002036 res = (xmlNodePtr) attr->prev;
Daniel Veillardd2379012002-03-15 22:24:56 +00002037 }
2038 case XML_NAMESPACE_DECL:
2039 res = NULL;
2040 break;
2041 default:
Daniel Veillardfaa35ff2002-11-24 13:53:43 +00002042 res = cur->prev;
Daniel Veillardd2379012002-03-15 22:24:56 +00002043 break;
Daniel Veillardd2897fd2002-01-30 16:37:32 +00002044 }
2045 resultobj = libxml_xmlNodePtrWrap(res);
2046 return resultobj;
2047}
2048
2049static PyObject *
Daniel Veillardd2379012002-03-15 22:24:56 +00002050libxml_children(ATTRIBUTE_UNUSED PyObject * self, PyObject * args)
Daniel Veillardd2897fd2002-01-30 16:37:32 +00002051{
2052 PyObject *resultobj, *obj;
2053 xmlNodePtr cur;
2054 xmlNodePtr res;
2055
Daniel Veillardd2379012002-03-15 22:24:56 +00002056 if (!PyArg_ParseTuple(args, (char *) "O:children", &obj))
Daniel Veillardd2897fd2002-01-30 16:37:32 +00002057 return NULL;
2058 cur = PyxmlNode_Get(obj);
2059
2060#ifdef DEBUG
2061 printf("libxml_children: cur = %p\n", cur);
2062#endif
2063
Daniel Veillardd2379012002-03-15 22:24:56 +00002064 switch (cur->type) {
2065 case XML_ELEMENT_NODE:
2066 case XML_ENTITY_REF_NODE:
2067 case XML_ENTITY_NODE:
2068 case XML_PI_NODE:
2069 case XML_COMMENT_NODE:
2070 case XML_DOCUMENT_NODE:
Daniel Veillardd2897fd2002-01-30 16:37:32 +00002071#ifdef LIBXML_DOCB_ENABLED
Daniel Veillardd2379012002-03-15 22:24:56 +00002072 case XML_DOCB_DOCUMENT_NODE:
Daniel Veillardd2897fd2002-01-30 16:37:32 +00002073#endif
Daniel Veillardd2379012002-03-15 22:24:56 +00002074 case XML_HTML_DOCUMENT_NODE:
2075 case XML_DTD_NODE:
2076 res = cur->children;
2077 break;
2078 case XML_ATTRIBUTE_NODE:{
2079 xmlAttrPtr attr = (xmlAttrPtr) cur;
2080
2081 res = attr->children;
2082 break;
2083 }
2084 default:
2085 res = NULL;
2086 break;
Daniel Veillardd2897fd2002-01-30 16:37:32 +00002087 }
2088 resultobj = libxml_xmlNodePtrWrap(res);
2089 return resultobj;
2090}
2091
2092static PyObject *
Daniel Veillardd2379012002-03-15 22:24:56 +00002093libxml_last(ATTRIBUTE_UNUSED PyObject * self, PyObject * args)
Daniel Veillardd2897fd2002-01-30 16:37:32 +00002094{
2095 PyObject *resultobj, *obj;
2096 xmlNodePtr cur;
2097 xmlNodePtr res;
2098
Daniel Veillardd2379012002-03-15 22:24:56 +00002099 if (!PyArg_ParseTuple(args, (char *) "O:last", &obj))
Daniel Veillardd2897fd2002-01-30 16:37:32 +00002100 return NULL;
2101 cur = PyxmlNode_Get(obj);
2102
2103#ifdef DEBUG
2104 printf("libxml_last: cur = %p\n", cur);
2105#endif
2106
Daniel Veillardd2379012002-03-15 22:24:56 +00002107 switch (cur->type) {
2108 case XML_ELEMENT_NODE:
2109 case XML_ENTITY_REF_NODE:
2110 case XML_ENTITY_NODE:
2111 case XML_PI_NODE:
2112 case XML_COMMENT_NODE:
2113 case XML_DOCUMENT_NODE:
Daniel Veillardd2897fd2002-01-30 16:37:32 +00002114#ifdef LIBXML_DOCB_ENABLED
Daniel Veillardd2379012002-03-15 22:24:56 +00002115 case XML_DOCB_DOCUMENT_NODE:
Daniel Veillardd2897fd2002-01-30 16:37:32 +00002116#endif
Daniel Veillardd2379012002-03-15 22:24:56 +00002117 case XML_HTML_DOCUMENT_NODE:
2118 case XML_DTD_NODE:
2119 res = cur->last;
2120 break;
2121 case XML_ATTRIBUTE_NODE:{
2122 xmlAttrPtr attr = (xmlAttrPtr) cur;
2123
2124 res = attr->last;
2125 }
2126 default:
2127 res = NULL;
2128 break;
Daniel Veillardd2897fd2002-01-30 16:37:32 +00002129 }
2130 resultobj = libxml_xmlNodePtrWrap(res);
2131 return resultobj;
2132}
2133
2134static PyObject *
Daniel Veillardd2379012002-03-15 22:24:56 +00002135libxml_parent(ATTRIBUTE_UNUSED PyObject * self, PyObject * args)
Daniel Veillardd2897fd2002-01-30 16:37:32 +00002136{
2137 PyObject *resultobj, *obj;
2138 xmlNodePtr cur;
2139 xmlNodePtr res;
2140
Daniel Veillardd2379012002-03-15 22:24:56 +00002141 if (!PyArg_ParseTuple(args, (char *) "O:parent", &obj))
Daniel Veillardd2897fd2002-01-30 16:37:32 +00002142 return NULL;
2143 cur = PyxmlNode_Get(obj);
2144
2145#ifdef DEBUG
2146 printf("libxml_parent: cur = %p\n", cur);
2147#endif
2148
Daniel Veillardd2379012002-03-15 22:24:56 +00002149 switch (cur->type) {
2150 case XML_DOCUMENT_NODE:
2151 case XML_HTML_DOCUMENT_NODE:
Daniel Veillardd2897fd2002-01-30 16:37:32 +00002152#ifdef LIBXML_DOCB_ENABLED
Daniel Veillardd2379012002-03-15 22:24:56 +00002153 case XML_DOCB_DOCUMENT_NODE:
Daniel Veillardd2897fd2002-01-30 16:37:32 +00002154#endif
Daniel Veillardd2379012002-03-15 22:24:56 +00002155 res = NULL;
2156 break;
2157 case XML_ATTRIBUTE_NODE:{
2158 xmlAttrPtr attr = (xmlAttrPtr) cur;
2159
2160 res = attr->parent;
2161 }
2162 case XML_ENTITY_DECL:
2163 case XML_NAMESPACE_DECL:
2164 case XML_XINCLUDE_START:
2165 case XML_XINCLUDE_END:
2166 res = NULL;
2167 break;
2168 default:
2169 res = cur->parent;
2170 break;
Daniel Veillardd2897fd2002-01-30 16:37:32 +00002171 }
2172 resultobj = libxml_xmlNodePtrWrap(res);
2173 return resultobj;
2174}
2175
2176static PyObject *
Daniel Veillardd2379012002-03-15 22:24:56 +00002177libxml_type(ATTRIBUTE_UNUSED PyObject * self, PyObject * args)
Daniel Veillardd2897fd2002-01-30 16:37:32 +00002178{
2179 PyObject *resultobj, *obj;
2180 xmlNodePtr cur;
Daniel Veillardd2379012002-03-15 22:24:56 +00002181 const xmlChar *res = NULL;
Daniel Veillardd2897fd2002-01-30 16:37:32 +00002182
Daniel Veillardd2379012002-03-15 22:24:56 +00002183 if (!PyArg_ParseTuple(args, (char *) "O:last", &obj))
Daniel Veillardd2897fd2002-01-30 16:37:32 +00002184 return NULL;
2185 cur = PyxmlNode_Get(obj);
2186
2187#ifdef DEBUG
2188 printf("libxml_type: cur = %p\n", cur);
2189#endif
2190
Daniel Veillardd2379012002-03-15 22:24:56 +00002191 switch (cur->type) {
Daniel Veillardd2897fd2002-01-30 16:37:32 +00002192 case XML_ELEMENT_NODE:
Daniel Veillardd2379012002-03-15 22:24:56 +00002193 res = (const xmlChar *) "element";
2194 break;
Daniel Veillardd2897fd2002-01-30 16:37:32 +00002195 case XML_ATTRIBUTE_NODE:
Daniel Veillardd2379012002-03-15 22:24:56 +00002196 res = (const xmlChar *) "attribute";
2197 break;
Daniel Veillardd2897fd2002-01-30 16:37:32 +00002198 case XML_TEXT_NODE:
Daniel Veillardd2379012002-03-15 22:24:56 +00002199 res = (const xmlChar *) "text";
2200 break;
Daniel Veillardd2897fd2002-01-30 16:37:32 +00002201 case XML_CDATA_SECTION_NODE:
Daniel Veillardd2379012002-03-15 22:24:56 +00002202 res = (const xmlChar *) "cdata";
2203 break;
Daniel Veillardd2897fd2002-01-30 16:37:32 +00002204 case XML_ENTITY_REF_NODE:
Daniel Veillardd2379012002-03-15 22:24:56 +00002205 res = (const xmlChar *) "entity_ref";
2206 break;
Daniel Veillardd2897fd2002-01-30 16:37:32 +00002207 case XML_ENTITY_NODE:
Daniel Veillardd2379012002-03-15 22:24:56 +00002208 res = (const xmlChar *) "entity";
2209 break;
Daniel Veillardd2897fd2002-01-30 16:37:32 +00002210 case XML_PI_NODE:
Daniel Veillardd2379012002-03-15 22:24:56 +00002211 res = (const xmlChar *) "pi";
2212 break;
Daniel Veillardd2897fd2002-01-30 16:37:32 +00002213 case XML_COMMENT_NODE:
Daniel Veillardd2379012002-03-15 22:24:56 +00002214 res = (const xmlChar *) "comment";
2215 break;
Daniel Veillardd2897fd2002-01-30 16:37:32 +00002216 case XML_DOCUMENT_NODE:
Daniel Veillardd2379012002-03-15 22:24:56 +00002217 res = (const xmlChar *) "document_xml";
2218 break;
Daniel Veillardd2897fd2002-01-30 16:37:32 +00002219 case XML_DOCUMENT_TYPE_NODE:
Daniel Veillardd2379012002-03-15 22:24:56 +00002220 res = (const xmlChar *) "doctype";
2221 break;
Daniel Veillardd2897fd2002-01-30 16:37:32 +00002222 case XML_DOCUMENT_FRAG_NODE:
Daniel Veillardd2379012002-03-15 22:24:56 +00002223 res = (const xmlChar *) "fragment";
2224 break;
Daniel Veillardd2897fd2002-01-30 16:37:32 +00002225 case XML_NOTATION_NODE:
Daniel Veillardd2379012002-03-15 22:24:56 +00002226 res = (const xmlChar *) "notation";
2227 break;
Daniel Veillardd2897fd2002-01-30 16:37:32 +00002228 case XML_HTML_DOCUMENT_NODE:
Daniel Veillardd2379012002-03-15 22:24:56 +00002229 res = (const xmlChar *) "document_html";
2230 break;
Daniel Veillardd2897fd2002-01-30 16:37:32 +00002231 case XML_DTD_NODE:
Daniel Veillardd2379012002-03-15 22:24:56 +00002232 res = (const xmlChar *) "dtd";
2233 break;
Daniel Veillardd2897fd2002-01-30 16:37:32 +00002234 case XML_ELEMENT_DECL:
Daniel Veillardd2379012002-03-15 22:24:56 +00002235 res = (const xmlChar *) "elem_decl";
2236 break;
Daniel Veillardd2897fd2002-01-30 16:37:32 +00002237 case XML_ATTRIBUTE_DECL:
Daniel Veillardd2379012002-03-15 22:24:56 +00002238 res = (const xmlChar *) "attribute_decl";
2239 break;
Daniel Veillardd2897fd2002-01-30 16:37:32 +00002240 case XML_ENTITY_DECL:
Daniel Veillardd2379012002-03-15 22:24:56 +00002241 res = (const xmlChar *) "entity_decl";
2242 break;
Daniel Veillardd2897fd2002-01-30 16:37:32 +00002243 case XML_NAMESPACE_DECL:
Daniel Veillardd2379012002-03-15 22:24:56 +00002244 res = (const xmlChar *) "namespace";
2245 break;
Daniel Veillardd2897fd2002-01-30 16:37:32 +00002246 case XML_XINCLUDE_START:
Daniel Veillardd2379012002-03-15 22:24:56 +00002247 res = (const xmlChar *) "xinclude_start";
2248 break;
Daniel Veillardd2897fd2002-01-30 16:37:32 +00002249 case XML_XINCLUDE_END:
Daniel Veillardd2379012002-03-15 22:24:56 +00002250 res = (const xmlChar *) "xinclude_end";
2251 break;
Daniel Veillardd2897fd2002-01-30 16:37:32 +00002252#ifdef LIBXML_DOCB_ENABLED
Daniel Veillardd2379012002-03-15 22:24:56 +00002253 case XML_DOCB_DOCUMENT_NODE:
2254 res = (const xmlChar *) "document_docbook";
2255 break;
Daniel Veillardd2897fd2002-01-30 16:37:32 +00002256#endif
2257 }
2258#ifdef DEBUG
2259 printf("libxml_type: cur = %p: %s\n", cur, res);
2260#endif
2261
Daniel Veillard1971ee22002-01-31 20:29:19 +00002262 resultobj = libxml_constxmlCharPtrWrap(res);
Daniel Veillardd2897fd2002-01-30 16:37:32 +00002263 return resultobj;
2264}
2265
2266/************************************************************************
2267 * *
Daniel Veillard36eea2d2002-02-04 00:17:01 +00002268 * Specific accessor functions *
2269 * *
2270 ************************************************************************/
2271PyObject *
Daniel Veillardd2379012002-03-15 22:24:56 +00002272libxml_xmlNodeGetNsDefs(ATTRIBUTE_UNUSED PyObject * self, PyObject * args)
2273{
Daniel Veillard36eea2d2002-02-04 00:17:01 +00002274 PyObject *py_retval;
2275 xmlNsPtr c_retval;
2276 xmlNodePtr node;
2277 PyObject *pyobj_node;
2278
Daniel Veillardd2379012002-03-15 22:24:56 +00002279 if (!PyArg_ParseTuple
2280 (args, (char *) "O:xmlNodeGetNsDefs", &pyobj_node))
2281 return (NULL);
Daniel Veillard36eea2d2002-02-04 00:17:01 +00002282 node = (xmlNodePtr) PyxmlNode_Get(pyobj_node);
2283
2284 if ((node == NULL) || (node->type != XML_ELEMENT_NODE)) {
Daniel Veillardd2379012002-03-15 22:24:56 +00002285 Py_INCREF(Py_None);
2286 return (Py_None);
Daniel Veillard36eea2d2002-02-04 00:17:01 +00002287 }
2288 c_retval = node->nsDef;
2289 py_retval = libxml_xmlNsPtrWrap((xmlNsPtr) c_retval);
Daniel Veillardd2379012002-03-15 22:24:56 +00002290 return (py_retval);
Daniel Veillard36eea2d2002-02-04 00:17:01 +00002291}
2292
2293PyObject *
Daniel Veillardd2379012002-03-15 22:24:56 +00002294libxml_xmlNodeGetNs(ATTRIBUTE_UNUSED PyObject * self, PyObject * args)
2295{
Daniel Veillard36eea2d2002-02-04 00:17:01 +00002296 PyObject *py_retval;
2297 xmlNsPtr c_retval;
2298 xmlNodePtr node;
2299 PyObject *pyobj_node;
2300
Daniel Veillardd2379012002-03-15 22:24:56 +00002301 if (!PyArg_ParseTuple(args, (char *) "O:xmlNodeGetNs", &pyobj_node))
2302 return (NULL);
Daniel Veillard36eea2d2002-02-04 00:17:01 +00002303 node = (xmlNodePtr) PyxmlNode_Get(pyobj_node);
2304
Daniel Veillarde96a2a42003-09-24 21:23:56 +00002305 if ((node == NULL) ||
2306 ((node->type != XML_ELEMENT_NODE) &&
2307 (node->type != XML_ATTRIBUTE_NODE))) {
Daniel Veillardd2379012002-03-15 22:24:56 +00002308 Py_INCREF(Py_None);
2309 return (Py_None);
Daniel Veillard36eea2d2002-02-04 00:17:01 +00002310 }
2311 c_retval = node->ns;
2312 py_retval = libxml_xmlNsPtrWrap((xmlNsPtr) c_retval);
Daniel Veillardd2379012002-03-15 22:24:56 +00002313 return (py_retval);
Daniel Veillard36eea2d2002-02-04 00:17:01 +00002314}
2315
Daniel Veillarda9cce9c2003-09-29 13:20:24 +00002316#ifdef LIBXML_OUTPUT_ENABLED
Daniel Veillard36eea2d2002-02-04 00:17:01 +00002317/************************************************************************
2318 * *
Daniel Veillard1e774382002-03-06 17:35:40 +00002319 * Serialization front-end *
2320 * *
2321 ************************************************************************/
2322
Daniel Veillardd2379012002-03-15 22:24:56 +00002323static PyObject *
2324libxml_serializeNode(ATTRIBUTE_UNUSED PyObject * self, PyObject * args)
2325{
Daniel Veillard1e774382002-03-06 17:35:40 +00002326 PyObject *py_retval = NULL;
2327 xmlChar *c_retval;
2328 PyObject *pyobj_node;
2329 xmlNodePtr node;
2330 xmlDocPtr doc;
Daniel Veillardd2379012002-03-15 22:24:56 +00002331 const char *encoding;
Daniel Veillard1e774382002-03-06 17:35:40 +00002332 int format;
2333 int len;
2334
Daniel Veillardd2379012002-03-15 22:24:56 +00002335 if (!PyArg_ParseTuple(args, (char *) "Ozi:serializeNode", &pyobj_node,
2336 &encoding, &format))
2337 return (NULL);
Daniel Veillard1e774382002-03-06 17:35:40 +00002338 node = (xmlNodePtr) PyxmlNode_Get(pyobj_node);
2339
2340 if (node == NULL) {
Daniel Veillardd2379012002-03-15 22:24:56 +00002341 Py_INCREF(Py_None);
2342 return (Py_None);
Daniel Veillard1e774382002-03-06 17:35:40 +00002343 }
2344 if (node->type == XML_DOCUMENT_NODE) {
Daniel Veillardd2379012002-03-15 22:24:56 +00002345 doc = (xmlDocPtr) node;
2346 xmlDocDumpFormatMemoryEnc(doc, &c_retval, &len,
2347 (const char *) encoding, format);
2348 py_retval = libxml_charPtrWrap((char *) c_retval);
Daniel Veillard1e774382002-03-06 17:35:40 +00002349 } else if (node->type == XML_HTML_DOCUMENT_NODE) {
Daniel Veillardd2379012002-03-15 22:24:56 +00002350 xmlOutputBufferPtr buf;
2351 xmlCharEncodingHandlerPtr handler = NULL;
Daniel Veillard1e774382002-03-06 17:35:40 +00002352
Daniel Veillardd2379012002-03-15 22:24:56 +00002353 doc = (xmlDocPtr) node;
2354 if (encoding != NULL)
2355 htmlSetMetaEncoding(doc, (const xmlChar *) encoding);
2356 encoding = (const char *) htmlGetMetaEncoding(doc);
Daniel Veillard1e774382002-03-06 17:35:40 +00002357
Daniel Veillardd2379012002-03-15 22:24:56 +00002358 if (encoding != NULL) {
2359 handler = xmlFindCharEncodingHandler(encoding);
2360 if (handler == NULL) {
2361 Py_INCREF(Py_None);
2362 return (Py_None);
2363 }
2364 }
Daniel Veillard1e774382002-03-06 17:35:40 +00002365
Daniel Veillardd2379012002-03-15 22:24:56 +00002366 /*
2367 * Fallback to HTML or ASCII when the encoding is unspecified
2368 */
2369 if (handler == NULL)
2370 handler = xmlFindCharEncodingHandler("HTML");
2371 if (handler == NULL)
2372 handler = xmlFindCharEncodingHandler("ascii");
Daniel Veillard1e774382002-03-06 17:35:40 +00002373
Daniel Veillardd2379012002-03-15 22:24:56 +00002374 buf = xmlAllocOutputBuffer(handler);
2375 if (buf == NULL) {
2376 Py_INCREF(Py_None);
2377 return (Py_None);
2378 }
2379 htmlDocContentDumpFormatOutput(buf, doc, encoding, format);
2380 xmlOutputBufferFlush(buf);
2381 if (buf->conv != NULL) {
2382 len = buf->conv->use;
2383 c_retval = buf->conv->content;
2384 buf->conv->content = NULL;
2385 } else {
2386 len = buf->buffer->use;
2387 c_retval = buf->buffer->content;
2388 buf->buffer->content = NULL;
2389 }
2390 (void) xmlOutputBufferClose(buf);
2391 py_retval = libxml_charPtrWrap((char *) c_retval);
Daniel Veillard1e774382002-03-06 17:35:40 +00002392 } else {
Daniel Veillardd2379012002-03-15 22:24:56 +00002393 doc = node->doc;
Daniel Veillarda8c0adb2002-11-17 22:37:35 +00002394 if ((doc == NULL) || (doc->type == XML_DOCUMENT_NODE)) {
Daniel Veillardd2379012002-03-15 22:24:56 +00002395 xmlOutputBufferPtr buf;
2396 xmlCharEncodingHandlerPtr handler = NULL;
Daniel Veillard1e774382002-03-06 17:35:40 +00002397
Daniel Veillardd2379012002-03-15 22:24:56 +00002398 if (encoding != NULL) {
2399 handler = xmlFindCharEncodingHandler(encoding);
2400 if (handler == NULL) {
2401 Py_INCREF(Py_None);
2402 return (Py_None);
2403 }
2404 }
Daniel Veillard1e774382002-03-06 17:35:40 +00002405
Daniel Veillardd2379012002-03-15 22:24:56 +00002406 buf = xmlAllocOutputBuffer(handler);
2407 if (buf == NULL) {
2408 Py_INCREF(Py_None);
2409 return (Py_None);
2410 }
2411 xmlNodeDumpOutput(buf, doc, node, 0, format, encoding);
2412 xmlOutputBufferFlush(buf);
2413 if (buf->conv != NULL) {
2414 len = buf->conv->use;
2415 c_retval = buf->conv->content;
2416 buf->conv->content = NULL;
2417 } else {
2418 len = buf->buffer->use;
2419 c_retval = buf->buffer->content;
2420 buf->buffer->content = NULL;
2421 }
2422 (void) xmlOutputBufferClose(buf);
2423 py_retval = libxml_charPtrWrap((char *) c_retval);
2424 } else if (doc->type == XML_HTML_DOCUMENT_NODE) {
2425 xmlOutputBufferPtr buf;
2426 xmlCharEncodingHandlerPtr handler = NULL;
Daniel Veillard1e774382002-03-06 17:35:40 +00002427
Daniel Veillardd2379012002-03-15 22:24:56 +00002428 if (encoding != NULL)
2429 htmlSetMetaEncoding(doc, (const xmlChar *) encoding);
2430 encoding = (const char *) htmlGetMetaEncoding(doc);
2431 if (encoding != NULL) {
2432 handler = xmlFindCharEncodingHandler(encoding);
2433 if (handler == NULL) {
2434 Py_INCREF(Py_None);
2435 return (Py_None);
2436 }
2437 }
Daniel Veillard1e774382002-03-06 17:35:40 +00002438
Daniel Veillardd2379012002-03-15 22:24:56 +00002439 /*
2440 * Fallback to HTML or ASCII when the encoding is unspecified
2441 */
2442 if (handler == NULL)
2443 handler = xmlFindCharEncodingHandler("HTML");
2444 if (handler == NULL)
2445 handler = xmlFindCharEncodingHandler("ascii");
Daniel Veillard1e774382002-03-06 17:35:40 +00002446
Daniel Veillardd2379012002-03-15 22:24:56 +00002447 buf = xmlAllocOutputBuffer(handler);
2448 if (buf == NULL) {
2449 Py_INCREF(Py_None);
2450 return (Py_None);
2451 }
2452 htmlNodeDumpFormatOutput(buf, doc, node, encoding, format);
2453 xmlOutputBufferFlush(buf);
2454 if (buf->conv != NULL) {
2455 len = buf->conv->use;
2456 c_retval = buf->conv->content;
2457 buf->conv->content = NULL;
2458 } else {
2459 len = buf->buffer->use;
2460 c_retval = buf->buffer->content;
2461 buf->buffer->content = NULL;
2462 }
2463 (void) xmlOutputBufferClose(buf);
2464 py_retval = libxml_charPtrWrap((char *) c_retval);
2465 } else {
2466 Py_INCREF(Py_None);
2467 return (Py_None);
2468 }
Daniel Veillard1e774382002-03-06 17:35:40 +00002469 }
Daniel Veillardd2379012002-03-15 22:24:56 +00002470 return (py_retval);
Daniel Veillard1e774382002-03-06 17:35:40 +00002471}
2472
Daniel Veillardd2379012002-03-15 22:24:56 +00002473static PyObject *
2474libxml_saveNodeTo(ATTRIBUTE_UNUSED PyObject * self, PyObject * args)
2475{
Daniel Veillard1e774382002-03-06 17:35:40 +00002476 PyObject *py_file = NULL;
2477 FILE *output;
2478 PyObject *pyobj_node;
2479 xmlNodePtr node;
2480 xmlDocPtr doc;
Daniel Veillardd2379012002-03-15 22:24:56 +00002481 const char *encoding;
Daniel Veillard1e774382002-03-06 17:35:40 +00002482 int format;
2483 int len;
2484 xmlOutputBufferPtr buf;
2485 xmlCharEncodingHandlerPtr handler = NULL;
2486
Daniel Veillardd2379012002-03-15 22:24:56 +00002487 if (!PyArg_ParseTuple(args, (char *) "OOzi:serializeNode", &pyobj_node,
2488 &py_file, &encoding, &format))
2489 return (NULL);
Daniel Veillard1e774382002-03-06 17:35:40 +00002490 node = (xmlNodePtr) PyxmlNode_Get(pyobj_node);
2491
2492 if (node == NULL) {
Daniel Veillardd2379012002-03-15 22:24:56 +00002493 return (PyInt_FromLong((long) -1));
Daniel Veillard1e774382002-03-06 17:35:40 +00002494 }
2495 if ((py_file == NULL) || (!(PyFile_Check(py_file)))) {
Daniel Veillardd2379012002-03-15 22:24:56 +00002496 return (PyInt_FromLong((long) -1));
Daniel Veillard1e774382002-03-06 17:35:40 +00002497 }
2498 output = PyFile_AsFile(py_file);
2499 if (output == NULL) {
Daniel Veillardd2379012002-03-15 22:24:56 +00002500 return (PyInt_FromLong((long) -1));
Daniel Veillard1e774382002-03-06 17:35:40 +00002501 }
2502
2503 if (node->type == XML_DOCUMENT_NODE) {
Daniel Veillardd2379012002-03-15 22:24:56 +00002504 doc = (xmlDocPtr) node;
Daniel Veillard1e774382002-03-06 17:35:40 +00002505 } else if (node->type == XML_HTML_DOCUMENT_NODE) {
Daniel Veillardd2379012002-03-15 22:24:56 +00002506 doc = (xmlDocPtr) node;
Daniel Veillard1e774382002-03-06 17:35:40 +00002507 } else {
Daniel Veillardd2379012002-03-15 22:24:56 +00002508 doc = node->doc;
Daniel Veillard1e774382002-03-06 17:35:40 +00002509 }
2510 if (doc->type == XML_HTML_DOCUMENT_NODE) {
Daniel Veillardd2379012002-03-15 22:24:56 +00002511 if (encoding == NULL)
2512 encoding = (const char *) htmlGetMetaEncoding(doc);
Daniel Veillard1e774382002-03-06 17:35:40 +00002513 }
2514 if (encoding != NULL) {
Daniel Veillardd2379012002-03-15 22:24:56 +00002515 handler = xmlFindCharEncodingHandler(encoding);
2516 if (handler == NULL) {
2517 return (PyInt_FromLong((long) -1));
2518 }
Daniel Veillard1e774382002-03-06 17:35:40 +00002519 }
2520 if (doc->type == XML_HTML_DOCUMENT_NODE) {
Daniel Veillardd2379012002-03-15 22:24:56 +00002521 if (handler == NULL)
2522 handler = xmlFindCharEncodingHandler("HTML");
2523 if (handler == NULL)
2524 handler = xmlFindCharEncodingHandler("ascii");
Daniel Veillard1e774382002-03-06 17:35:40 +00002525 }
2526
2527 buf = xmlOutputBufferCreateFile(output, handler);
2528 if (node->type == XML_DOCUMENT_NODE) {
Daniel Veillardd2379012002-03-15 22:24:56 +00002529 len = xmlSaveFormatFileTo(buf, doc, encoding, format);
Daniel Veillard1e774382002-03-06 17:35:40 +00002530 } else if (node->type == XML_HTML_DOCUMENT_NODE) {
Daniel Veillardd2379012002-03-15 22:24:56 +00002531 htmlDocContentDumpFormatOutput(buf, doc, encoding, format);
2532 len = xmlOutputBufferClose(buf);
Daniel Veillard1e774382002-03-06 17:35:40 +00002533 } else if (doc->type == XML_HTML_DOCUMENT_NODE) {
Daniel Veillardd2379012002-03-15 22:24:56 +00002534 htmlNodeDumpFormatOutput(buf, doc, node, encoding, format);
2535 len = xmlOutputBufferClose(buf);
Daniel Veillard1e774382002-03-06 17:35:40 +00002536 } else {
Daniel Veillardd2379012002-03-15 22:24:56 +00002537 xmlNodeDumpOutput(buf, doc, node, 0, format, encoding);
2538 len = xmlOutputBufferClose(buf);
Daniel Veillard1e774382002-03-06 17:35:40 +00002539 }
Daniel Veillardd2379012002-03-15 22:24:56 +00002540 return (PyInt_FromLong((long) len));
Daniel Veillard1e774382002-03-06 17:35:40 +00002541}
Daniel Veillarda9cce9c2003-09-29 13:20:24 +00002542#endif /* LIBXML_OUTPUT_ENABLED */
Daniel Veillard1e774382002-03-06 17:35:40 +00002543
2544/************************************************************************
2545 * *
Daniel Veillarda94ec6f2002-03-01 13:00:53 +00002546 * Extra stuff *
2547 * *
2548 ************************************************************************/
2549PyObject *
Daniel Veillardd2379012002-03-15 22:24:56 +00002550libxml_xmlNewNode(ATTRIBUTE_UNUSED PyObject * self, PyObject * args)
2551{
Daniel Veillarda94ec6f2002-03-01 13:00:53 +00002552 PyObject *py_retval;
Daniel Veillardd2379012002-03-15 22:24:56 +00002553 xmlChar *name;
Daniel Veillarda94ec6f2002-03-01 13:00:53 +00002554 xmlNodePtr node;
2555
Daniel Veillardd2379012002-03-15 22:24:56 +00002556 if (!PyArg_ParseTuple(args, (char *) "s:xmlNewNode", &name))
2557 return (NULL);
Daniel Veillarda94ec6f2002-03-01 13:00:53 +00002558 node = (xmlNodePtr) xmlNewNode(NULL, name);
Daniel Veillard3b2e4e12003-02-03 08:52:58 +00002559#ifdef DEBUG
Daniel Veillardd2379012002-03-15 22:24:56 +00002560 printf("NewNode: %s : %p\n", name, (void *) node);
Daniel Veillard3b2e4e12003-02-03 08:52:58 +00002561#endif
Daniel Veillarda94ec6f2002-03-01 13:00:53 +00002562
2563 if (node == NULL) {
Daniel Veillardd2379012002-03-15 22:24:56 +00002564 Py_INCREF(Py_None);
2565 return (Py_None);
Daniel Veillarda94ec6f2002-03-01 13:00:53 +00002566 }
2567 py_retval = libxml_xmlNodePtrWrap(node);
Daniel Veillardd2379012002-03-15 22:24:56 +00002568 return (py_retval);
Daniel Veillarda94ec6f2002-03-01 13:00:53 +00002569}
2570
Daniel Veillard54396242003-04-23 07:36:50 +00002571
2572/************************************************************************
2573 * *
2574 * Local Catalog stuff *
2575 * *
2576 ************************************************************************/
2577static PyObject *
2578libxml_addLocalCatalog(ATTRIBUTE_UNUSED PyObject * self, PyObject * args)
2579{
2580 xmlChar *URL;
2581 xmlParserCtxtPtr ctxt;
2582 PyObject *pyobj_ctxt;
2583
2584 if (!PyArg_ParseTuple(args, (char *)"Os:addLocalCatalog", &pyobj_ctxt, &URL))
2585 return(NULL);
2586
2587 ctxt = (xmlParserCtxtPtr) PyparserCtxt_Get(pyobj_ctxt);
2588
2589 if (URL != NULL) {
2590 ctxt->catalogs = xmlCatalogAddLocal(ctxt->catalogs, URL);
2591 }
2592
2593#ifdef DEBUG
2594 printf("LocalCatalog: %s\n", URL);
2595#endif
2596
2597 Py_INCREF(Py_None);
2598 return (Py_None);
2599}
2600
Daniel Veillardc2664642003-07-29 20:44:53 +00002601#ifdef LIBXML_SCHEMAS_ENABLED
2602
2603/************************************************************************
2604 * *
2605 * RelaxNG error handler registration *
2606 * *
2607 ************************************************************************/
2608
2609typedef struct
2610{
2611 PyObject *warn;
2612 PyObject *error;
2613 PyObject *arg;
2614} xmlRelaxNGValidCtxtPyCtxt;
2615typedef xmlRelaxNGValidCtxtPyCtxt *xmlRelaxNGValidCtxtPyCtxtPtr;
2616
2617static void
2618libxml_xmlRelaxNGValidityGenericErrorFuncHandler(void *ctx, char *str)
2619{
2620 PyObject *list;
2621 PyObject *result;
2622 xmlRelaxNGValidCtxtPyCtxtPtr pyCtxt;
2623
2624#ifdef DEBUG_ERROR
2625 printf("libxml_xmlRelaxNGValidityGenericErrorFuncHandler(%p, %s, ...) called\n", ctx, str);
2626#endif
2627
2628 pyCtxt = (xmlRelaxNGValidCtxtPyCtxtPtr)ctx;
2629
2630 list = PyTuple_New(2);
2631 PyTuple_SetItem(list, 0, libxml_charPtrWrap(str));
2632 PyTuple_SetItem(list, 1, pyCtxt->arg);
2633 Py_XINCREF(pyCtxt->arg);
2634 result = PyEval_CallObject(pyCtxt->error, list);
2635 if (result == NULL)
2636 {
2637 /* TODO: manage for the exception to be propagated... */
2638 PyErr_Print();
2639 }
2640 Py_XDECREF(list);
2641 Py_XDECREF(result);
2642}
2643
2644static void
2645libxml_xmlRelaxNGValidityGenericWarningFuncHandler(void *ctx, char *str)
2646{
2647 PyObject *list;
2648 PyObject *result;
2649 xmlRelaxNGValidCtxtPyCtxtPtr pyCtxt;
2650
2651#ifdef DEBUG_ERROR
2652 printf("libxml_xmlRelaxNGValidityGenericWarningFuncHandler(%p, %s, ...) called\n", ctx, str);
2653#endif
2654
2655 pyCtxt = (xmlRelaxNGValidCtxtPyCtxtPtr)ctx;
2656
2657 list = PyTuple_New(2);
2658 PyTuple_SetItem(list, 0, libxml_charPtrWrap(str));
2659 PyTuple_SetItem(list, 1, pyCtxt->arg);
2660 Py_XINCREF(pyCtxt->arg);
2661 result = PyEval_CallObject(pyCtxt->warn, list);
2662 if (result == NULL)
2663 {
2664 /* TODO: manage for the exception to be propagated... */
2665 PyErr_Print();
2666 }
2667 Py_XDECREF(list);
2668 Py_XDECREF(result);
2669}
2670
2671static void
2672libxml_xmlRelaxNGValidityErrorFunc(void *ctx, const char *msg, ...)
2673{
2674 va_list ap;
2675
2676 va_start(ap, msg);
2677 libxml_xmlRelaxNGValidityGenericErrorFuncHandler(ctx, libxml_buildMessage(msg, ap));
2678 va_end(ap);
2679}
2680
2681static void
2682libxml_xmlRelaxNGValidityWarningFunc(void *ctx, const char *msg, ...)
2683{
2684 va_list ap;
2685
2686 va_start(ap, msg);
2687 libxml_xmlRelaxNGValidityGenericWarningFuncHandler(ctx, libxml_buildMessage(msg, ap));
2688 va_end(ap);
2689}
2690
2691static PyObject *
2692libxml_xmlRelaxNGSetValidErrors(ATTRIBUTE_UNUSED PyObject * self, PyObject * args)
2693{
2694 PyObject *py_retval;
2695 PyObject *pyobj_error;
2696 PyObject *pyobj_warn;
2697 PyObject *pyobj_ctx;
2698 PyObject *pyobj_arg = Py_None;
2699 xmlRelaxNGValidCtxtPtr ctxt;
2700 xmlRelaxNGValidCtxtPyCtxtPtr pyCtxt;
2701
2702 if (!PyArg_ParseTuple
2703 (args, (char *) "OOO|O:xmlRelaxNGSetValidErrors", &pyobj_ctx, &pyobj_error, &pyobj_warn, &pyobj_arg))
2704 return (NULL);
2705
2706#ifdef DEBUG_ERROR
2707 printf("libxml_xmlRelaxNGSetValidErrors(%p, %p, %p) called\n", pyobj_ctx, pyobj_error, pyobj_warn);
2708#endif
2709
2710 ctxt = PyrelaxNgValidCtxt_Get(pyobj_ctx);
William M. Brackc1939562003-08-05 15:52:22 +00002711 if (xmlRelaxNGGetValidErrors(ctxt, NULL, NULL, (void **) &pyCtxt) == -1)
Daniel Veillardc2664642003-07-29 20:44:53 +00002712 {
2713 py_retval = libxml_intWrap(-1);
2714 return(py_retval);
2715 }
2716
2717 if (pyCtxt == NULL)
2718 {
2719 /* first time to set the error handlers */
2720 pyCtxt = xmlMalloc(sizeof(xmlRelaxNGValidCtxtPyCtxt));
2721 if (pyCtxt == NULL) {
2722 py_retval = libxml_intWrap(-1);
2723 return(py_retval);
2724 }
2725 memset(pyCtxt, 0, sizeof(xmlRelaxNGValidCtxtPyCtxt));
2726 }
2727
2728 /* TODO: check warn and error is a function ! */
2729 Py_XDECREF(pyCtxt->error);
2730 Py_XINCREF(pyobj_error);
2731 pyCtxt->error = pyobj_error;
2732
2733 Py_XDECREF(pyCtxt->warn);
2734 Py_XINCREF(pyobj_warn);
2735 pyCtxt->warn = pyobj_warn;
2736
2737 Py_XDECREF(pyCtxt->arg);
2738 Py_XINCREF(pyobj_arg);
2739 pyCtxt->arg = pyobj_arg;
2740
2741 xmlRelaxNGSetValidErrors(ctxt, &libxml_xmlRelaxNGValidityErrorFunc, &libxml_xmlRelaxNGValidityWarningFunc, pyCtxt);
2742
2743 py_retval = libxml_intWrap(1);
2744 return (py_retval);
2745}
2746
2747static PyObject *
2748libxml_xmlRelaxNGFreeValidCtxt(ATTRIBUTE_UNUSED PyObject *self, PyObject *args) {
2749 xmlRelaxNGValidCtxtPtr ctxt;
2750 xmlRelaxNGValidCtxtPyCtxtPtr pyCtxt;
2751 PyObject *pyobj_ctxt;
2752
2753 if (!PyArg_ParseTuple(args, (char *)"O:xmlRelaxNGFreeValidCtxt", &pyobj_ctxt))
2754 return(NULL);
2755 ctxt = (xmlRelaxNGValidCtxtPtr) PyrelaxNgValidCtxt_Get(pyobj_ctxt);
2756
William M. Brackc1939562003-08-05 15:52:22 +00002757 if (xmlRelaxNGGetValidErrors(ctxt, NULL, NULL, (void **) &pyCtxt) == 0)
Daniel Veillardc2664642003-07-29 20:44:53 +00002758 {
2759 if (pyCtxt != NULL)
2760 {
2761 Py_XDECREF(pyCtxt->error);
2762 Py_XDECREF(pyCtxt->warn);
2763 Py_XDECREF(pyCtxt->arg);
2764 xmlFree(pyCtxt);
2765 }
2766 }
2767
2768 xmlRelaxNGFreeValidCtxt(ctxt);
2769 Py_INCREF(Py_None);
2770 return(Py_None);
2771}
2772
2773#endif
2774
Daniel Veillarda94ec6f2002-03-01 13:00:53 +00002775/************************************************************************
2776 * *
Daniel Veillardd2897fd2002-01-30 16:37:32 +00002777 * The registration stuff *
2778 * *
2779 ************************************************************************/
2780static PyMethodDef libxmlMethods[] = {
Daniel Veillard96fe0952002-01-30 20:52:23 +00002781#include "libxml2-export.c"
Daniel Veillardd2379012002-03-15 22:24:56 +00002782 {(char *) "name", libxml_name, METH_VARARGS, NULL},
2783 {(char *) "children", libxml_children, METH_VARARGS, NULL},
2784 {(char *) "properties", libxml_properties, METH_VARARGS, NULL},
2785 {(char *) "last", libxml_last, METH_VARARGS, NULL},
2786 {(char *) "prev", libxml_prev, METH_VARARGS, NULL},
2787 {(char *) "next", libxml_next, METH_VARARGS, NULL},
2788 {(char *) "parent", libxml_parent, METH_VARARGS, NULL},
2789 {(char *) "type", libxml_type, METH_VARARGS, NULL},
2790 {(char *) "doc", libxml_doc, METH_VARARGS, NULL},
2791 {(char *) "xmlNewNode", libxml_xmlNewNode, METH_VARARGS, NULL},
Daniel Veillarda9cce9c2003-09-29 13:20:24 +00002792#ifdef LIBXML_OUTPUT_ENABLED
Daniel Veillardd2379012002-03-15 22:24:56 +00002793 {(char *) "serializeNode", libxml_serializeNode, METH_VARARGS, NULL},
2794 {(char *) "saveNodeTo", libxml_saveNodeTo, METH_VARARGS, NULL},
Daniel Veillardc6d4a932002-09-12 15:00:57 +00002795 {(char *) "outputBufferCreate", libxml_xmlCreateOutputBuffer, METH_VARARGS, NULL},
Daniel Veillarda9cce9c2003-09-29 13:20:24 +00002796#endif /* LIBXML_OUTPUT_ENABLED */
Daniel Veillardc6d4a932002-09-12 15:00:57 +00002797 {(char *) "inputBufferCreate", libxml_xmlCreateInputBuffer, METH_VARARGS, NULL},
2798 {(char *) "setEntityLoader", libxml_xmlSetEntityLoader, METH_VARARGS, NULL},
Daniel Veillard3e20a292003-01-10 13:14:40 +00002799 {(char *)"xmlRegisterErrorHandler", libxml_xmlRegisterErrorHandler, METH_VARARGS, NULL },
Daniel Veillard417be3a2003-01-20 21:26:34 +00002800 {(char *)"xmlParserCtxtSetErrorHandler", libxml_xmlParserCtxtSetErrorHandler, METH_VARARGS, NULL },
2801 {(char *)"xmlParserCtxtGetErrorHandler", libxml_xmlParserCtxtGetErrorHandler, METH_VARARGS, NULL },
Daniel Veillarde6227e02003-01-14 11:42:39 +00002802 {(char *)"xmlFreeParserCtxt", libxml_xmlFreeParserCtxt, METH_VARARGS, NULL },
Daniel Veillard26f70262003-01-16 22:45:08 +00002803 {(char *)"xmlTextReaderSetErrorHandler", libxml_xmlTextReaderSetErrorHandler, METH_VARARGS, NULL },
2804 {(char *)"xmlTextReaderGetErrorHandler", libxml_xmlTextReaderGetErrorHandler, METH_VARARGS, NULL },
2805 {(char *)"xmlFreeTextReader", libxml_xmlFreeTextReader, METH_VARARGS, NULL },
Daniel Veillard54396242003-04-23 07:36:50 +00002806 {(char *)"addLocalCatalog", libxml_addLocalCatalog, METH_VARARGS, NULL },
Daniel Veillardc2664642003-07-29 20:44:53 +00002807#ifdef LIBXML_SCHEMAS_ENABLED
2808 {(char *)"xmlRelaxNGSetValidErrors", libxml_xmlRelaxNGSetValidErrors, METH_VARARGS, NULL},
2809 {(char *)"xmlRelaxNGFreeValidCtxt", libxml_xmlRelaxNGFreeValidCtxt, METH_VARARGS, NULL},
2810#endif
Daniel Veillardd2379012002-03-15 22:24:56 +00002811 {NULL, NULL, 0, NULL}
Daniel Veillardd2897fd2002-01-30 16:37:32 +00002812};
2813
Daniel Veillard0fea6f42002-02-22 22:51:13 +00002814#ifdef MERGED_MODULES
Daniel Veillard6361da02002-02-23 10:10:33 +00002815extern void initlibxsltmod(void);
Daniel Veillard0fea6f42002-02-22 22:51:13 +00002816#endif
2817
Daniel Veillardd2379012002-03-15 22:24:56 +00002818void
2819initlibxml2mod(void)
2820{
Daniel Veillardaf43f632002-03-08 15:05:20 +00002821 static int initialized = 0;
Daniel Veillard3ce52572002-02-03 15:08:05 +00002822 PyObject *m;
Daniel Veillardaf43f632002-03-08 15:05:20 +00002823
2824 if (initialized != 0)
Daniel Veillardd2379012002-03-15 22:24:56 +00002825 return;
Daniel Veillard781ac8b2003-05-15 22:11:36 +00002826 /* XXX xmlInitParser does much more than this */
2827 xmlInitGlobals();
Daniel Veillarda9cce9c2003-09-29 13:20:24 +00002828#ifdef LIBXML_OUTPUT_ENABLED
Daniel Veillardc6d4a932002-09-12 15:00:57 +00002829 xmlRegisterDefaultOutputCallbacks();
Daniel Veillarda9cce9c2003-09-29 13:20:24 +00002830#endif /* LIBXML_OUTPUT_ENABLED */
Daniel Veillardc6d4a932002-09-12 15:00:57 +00002831 xmlRegisterDefaultInputCallbacks();
Daniel Veillardd2379012002-03-15 22:24:56 +00002832 m = Py_InitModule((char *) "libxml2mod", libxmlMethods);
Daniel Veillardaf43f632002-03-08 15:05:20 +00002833 initialized = 1;
Daniel Veillard5d819032002-02-02 21:49:17 +00002834 libxml_xmlErrorInitialize();
Daniel Veillard6361da02002-02-23 10:10:33 +00002835
Daniel Veillard0fea6f42002-02-22 22:51:13 +00002836#ifdef MERGED_MODULES
2837 initlibxsltmod();
2838#endif
Daniel Veillardd2897fd2002-01-30 16:37:32 +00002839}