blob: ea0aed74c3813ebd72d7da0c158f1721d94f7587 [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
322/**
323 * xmlOutputBufferCreatePythonFile:
324 * @file: a PyFile_Type
325 * @encoder: the encoding converter or NULL
326 *
327 * Create a buffered output for the progressive saving to a PyFile_Type
328 * buffered C I/O
329 *
330 * Returns the new parser output or NULL
331 */
Daniel Veillard118aed72002-09-24 14:13:13 +0000332static xmlOutputBufferPtr
Daniel Veillardc6d4a932002-09-12 15:00:57 +0000333xmlOutputBufferCreatePythonFile(PyObject *file,
334 xmlCharEncodingHandlerPtr encoder) {
335 xmlOutputBufferPtr ret;
336
337 if (file == NULL) return(NULL);
338
339 ret = xmlAllocOutputBuffer(encoder);
340 if (ret != NULL) {
341 ret->context = file;
342 /* Py_INCREF(file); */
343 ret->writecallback = xmlPythonFileWrite;
344 ret->closecallback = xmlPythonFileClose;
345 }
346
347 return(ret);
348}
349
350PyObject *
351libxml_xmlCreateOutputBuffer(ATTRIBUTE_UNUSED PyObject *self, PyObject *args) {
352 PyObject *py_retval;
353 PyObject *file;
354 xmlChar *encoding;
355 xmlCharEncodingHandlerPtr handler = NULL;
356 xmlOutputBufferPtr buffer;
357
358
359 if (!PyArg_ParseTuple(args, (char *)"Oz:xmlOutputBufferCreate",
360 &file, &encoding))
361 return(NULL);
362 if ((encoding != NULL) && (encoding[0] != 0)) {
Daniel Veillard118aed72002-09-24 14:13:13 +0000363 handler = xmlFindCharEncodingHandler((const char *) encoding);
Daniel Veillardc6d4a932002-09-12 15:00:57 +0000364 }
365 buffer = xmlOutputBufferCreatePythonFile(file, handler);
366 if (buffer == NULL)
367 printf("libxml_xmlCreateOutputBuffer: buffer == NULL\n");
368 py_retval = libxml_xmlOutputBufferPtrWrap(buffer);
369 return(py_retval);
370}
371
372
373/**
374 * xmlParserInputBufferCreatePythonFile:
375 * @file: a PyFile_Type
376 * @encoder: the encoding converter or NULL
377 *
378 * Create a buffered output for the progressive saving to a PyFile_Type
379 * buffered C I/O
380 *
381 * Returns the new parser output or NULL
382 */
Daniel Veillard118aed72002-09-24 14:13:13 +0000383static xmlParserInputBufferPtr
Daniel Veillardc6d4a932002-09-12 15:00:57 +0000384xmlParserInputBufferCreatePythonFile(PyObject *file,
385 xmlCharEncoding encoding) {
386 xmlParserInputBufferPtr ret;
387
388 if (file == NULL) return(NULL);
389
390 ret = xmlAllocParserInputBuffer(encoding);
391 if (ret != NULL) {
392 ret->context = file;
393 /* Py_INCREF(file); */
394 ret->readcallback = xmlPythonFileRead;
395 ret->closecallback = xmlPythonFileClose;
396 }
397
398 return(ret);
399}
400
401PyObject *
402libxml_xmlCreateInputBuffer(ATTRIBUTE_UNUSED PyObject *self, PyObject *args) {
403 PyObject *py_retval;
404 PyObject *file;
405 xmlChar *encoding;
406 xmlCharEncoding enc = XML_CHAR_ENCODING_NONE;
407 xmlParserInputBufferPtr buffer;
408
409
410 if (!PyArg_ParseTuple(args, (char *)"Oz:xmlParserInputBufferCreate",
411 &file, &encoding))
412 return(NULL);
413 if ((encoding != NULL) && (encoding[0] != 0)) {
Daniel Veillard118aed72002-09-24 14:13:13 +0000414 enc = xmlParseCharEncoding((const char *) encoding);
Daniel Veillardc6d4a932002-09-12 15:00:57 +0000415 }
416 buffer = xmlParserInputBufferCreatePythonFile(file, enc);
417 if (buffer == NULL)
418 printf("libxml_xmlParserInputBufferCreate: buffer == NULL\n");
419 py_retval = libxml_xmlParserInputBufferPtrWrap(buffer);
420 return(py_retval);
421}
422
423/************************************************************************
424 * *
425 * Providing the resolver at the Python level *
426 * *
427 ************************************************************************/
428
429static xmlExternalEntityLoader defaultExternalEntityLoader = NULL;
430static PyObject *pythonExternalEntityLoaderObjext;
431
432static xmlParserInputPtr
433pythonExternalEntityLoader(const char *URL, const char *ID,
434 xmlParserCtxtPtr ctxt) {
435 xmlParserInputPtr result = NULL;
436 if (pythonExternalEntityLoaderObjext != NULL) {
437 PyObject *ret;
438 PyObject *ctxtobj;
439
440 ctxtobj = libxml_xmlParserCtxtPtrWrap(ctxt);
441#ifdef DEBUG_LOADER
442 printf("pythonExternalEntityLoader: ready to call\n");
443#endif
444
445 ret = PyObject_CallFunction(pythonExternalEntityLoaderObjext,
Daniel Veillard118aed72002-09-24 14:13:13 +0000446 (char *) "(ssO)", URL, ID, ctxtobj);
Daniel Veillarde4a07e72003-01-14 14:40:25 +0000447 Py_XDECREF(ctxtobj);
Daniel Veillardc6d4a932002-09-12 15:00:57 +0000448#ifdef DEBUG_LOADER
449 printf("pythonExternalEntityLoader: result ");
450 PyObject_Print(ret, stdout, 0);
451 printf("\n");
452#endif
453
454 if (ret != NULL) {
Daniel Veillard118aed72002-09-24 14:13:13 +0000455 if (PyObject_HasAttrString(ret, (char *) "read")) {
Daniel Veillardc6d4a932002-09-12 15:00:57 +0000456 xmlParserInputBufferPtr buf;
457
458 buf = xmlAllocParserInputBuffer(XML_CHAR_ENCODING_NONE);
459 if (buf != NULL) {
460 buf->context = ret;
461 buf->readcallback = xmlPythonFileReadRaw;
462 buf->closecallback = xmlPythonFileCloseRaw;
463 result = xmlNewIOInputStream(ctxt, buf,
464 XML_CHAR_ENCODING_NONE);
465 }
466 } else {
467 printf("pythonExternalEntityLoader: can't read\n");
468 }
469 if (result == NULL) {
470 Py_DECREF(ret);
Daniel Veillardc64b8e92003-02-24 11:47:13 +0000471 } else if (URL != NULL) {
Daniel Veillardc2664642003-07-29 20:44:53 +0000472 result->filename = xmlStrdup((const xmlChar *)URL);
Daniel Veillardc64b8e92003-02-24 11:47:13 +0000473 result->directory = xmlParserGetDirectory((const char *) URL);
Daniel Veillardc6d4a932002-09-12 15:00:57 +0000474 }
475 }
476 }
477 if ((result == NULL) && (defaultExternalEntityLoader != NULL)) {
478 result = defaultExternalEntityLoader(URL, ID, ctxt);
479 }
480 return(result);
481}
482
483PyObject *
484libxml_xmlSetEntityLoader(ATTRIBUTE_UNUSED PyObject *self, PyObject *args) {
485 PyObject *py_retval;
486 PyObject *loader;
487
488 if (!PyArg_ParseTuple(args, (char *)"O:libxml_xmlSetEntityLoader",
489 &loader))
490 return(NULL);
491
492#ifdef DEBUG_LOADER
493 printf("libxml_xmlSetEntityLoader\n");
494#endif
495 if (defaultExternalEntityLoader == NULL)
496 defaultExternalEntityLoader = xmlGetExternalEntityLoader();
497
498 pythonExternalEntityLoaderObjext = loader;
499 xmlSetExternalEntityLoader(pythonExternalEntityLoader);
500
501 py_retval = PyInt_FromLong(0);
502 return(py_retval);
503}
504
505
506/************************************************************************
507 * *
Daniel Veillard3ce52572002-02-03 15:08:05 +0000508 * Handling SAX/xmllib/sgmlop callback interfaces *
Daniel Veillardd2897fd2002-01-30 16:37:32 +0000509 * *
510 ************************************************************************/
Daniel Veillardd2897fd2002-01-30 16:37:32 +0000511
Daniel Veillard33caa0b2002-02-04 14:07:26 +0000512static void
513pythonStartElement(void *user_data, const xmlChar * name,
514 const xmlChar ** attrs)
515{
516 int i;
517 PyObject *handler;
518 PyObject *dict;
519 PyObject *attrname;
520 PyObject *attrvalue;
Daniel Veillardd2379012002-03-15 22:24:56 +0000521 PyObject *result = NULL;
Daniel Veillard33caa0b2002-02-04 14:07:26 +0000522 int type = 0;
523
Daniel Veillard797a5652002-02-12 13:46:21 +0000524#ifdef DEBUG_SAX
525 printf("pythonStartElement(%s) called\n", name);
526#endif
Daniel Veillard33caa0b2002-02-04 14:07:26 +0000527 handler = (PyObject *) user_data;
Daniel Veillardd2379012002-03-15 22:24:56 +0000528 if (PyObject_HasAttrString(handler, (char *) "startElement"))
Daniel Veillard33caa0b2002-02-04 14:07:26 +0000529 type = 1;
Daniel Veillardd2379012002-03-15 22:24:56 +0000530 else if (PyObject_HasAttrString(handler, (char *) "start"))
Daniel Veillard33caa0b2002-02-04 14:07:26 +0000531 type = 2;
532 if (type != 0) {
533 /*
534 * the xmllib interface always generate a dictionnary,
535 * possibly empty
536 */
537 if ((attrs == NULL) && (type == 1)) {
538 Py_XINCREF(Py_None);
539 dict = Py_None;
Daniel Veillardd2379012002-03-15 22:24:56 +0000540 } else if (attrs == NULL) {
541 dict = PyDict_New();
Daniel Veillard33caa0b2002-02-04 14:07:26 +0000542 } else {
543 dict = PyDict_New();
544 for (i = 0; attrs[i] != NULL; i++) {
Daniel Veillardd2379012002-03-15 22:24:56 +0000545 attrname = PyString_FromString((char *) attrs[i]);
Daniel Veillard33caa0b2002-02-04 14:07:26 +0000546 i++;
547 if (attrs[i] != NULL) {
Daniel Veillardd2379012002-03-15 22:24:56 +0000548 attrvalue = PyString_FromString((char *) attrs[i]);
Daniel Veillard33caa0b2002-02-04 14:07:26 +0000549 } else {
550 Py_XINCREF(Py_None);
551 attrvalue = Py_None;
552 }
553 PyDict_SetItem(dict, attrname, attrvalue);
554 }
555 }
556
557 if (type == 1)
Daniel Veillardd2379012002-03-15 22:24:56 +0000558 result = PyObject_CallMethod(handler, (char *) "startElement",
559 (char *) "sO", name, dict);
Daniel Veillard33caa0b2002-02-04 14:07:26 +0000560 else if (type == 2)
Daniel Veillardd2379012002-03-15 22:24:56 +0000561 result = PyObject_CallMethod(handler, (char *) "start",
562 (char *) "sO", name, dict);
563 if (PyErr_Occurred())
564 PyErr_Print();
Daniel Veillard33caa0b2002-02-04 14:07:26 +0000565 Py_XDECREF(dict);
566 Py_XDECREF(result);
567 }
568}
569
570static void
571pythonStartDocument(void *user_data)
572{
573 PyObject *handler;
574 PyObject *result;
575
Daniel Veillard797a5652002-02-12 13:46:21 +0000576#ifdef DEBUG_SAX
577 printf("pythonStartDocument() called\n");
578#endif
Daniel Veillard33caa0b2002-02-04 14:07:26 +0000579 handler = (PyObject *) user_data;
Daniel Veillardd2379012002-03-15 22:24:56 +0000580 if (PyObject_HasAttrString(handler, (char *) "startDocument")) {
581 result =
582 PyObject_CallMethod(handler, (char *) "startDocument", NULL);
583 if (PyErr_Occurred())
584 PyErr_Print();
Daniel Veillard33caa0b2002-02-04 14:07:26 +0000585 Py_XDECREF(result);
586 }
587}
588
589static void
590pythonEndDocument(void *user_data)
591{
592 PyObject *handler;
593 PyObject *result;
594
Daniel Veillard797a5652002-02-12 13:46:21 +0000595#ifdef DEBUG_SAX
596 printf("pythonEndDocument() called\n");
597#endif
Daniel Veillard33caa0b2002-02-04 14:07:26 +0000598 handler = (PyObject *) user_data;
Daniel Veillardd2379012002-03-15 22:24:56 +0000599 if (PyObject_HasAttrString(handler, (char *) "endDocument")) {
600 result =
601 PyObject_CallMethod(handler, (char *) "endDocument", NULL);
602 if (PyErr_Occurred())
603 PyErr_Print();
Daniel Veillard33caa0b2002-02-04 14:07:26 +0000604 Py_XDECREF(result);
605 }
606 /*
607 * The reference to the handler is released there
608 */
609 Py_XDECREF(handler);
610}
611
612static void
613pythonEndElement(void *user_data, const xmlChar * name)
614{
615 PyObject *handler;
616 PyObject *result;
617
Daniel Veillard797a5652002-02-12 13:46:21 +0000618#ifdef DEBUG_SAX
619 printf("pythonEndElement(%s) called\n", name);
620#endif
Daniel Veillard33caa0b2002-02-04 14:07:26 +0000621 handler = (PyObject *) user_data;
Daniel Veillardd2379012002-03-15 22:24:56 +0000622 if (PyObject_HasAttrString(handler, (char *) "endElement")) {
623 result = PyObject_CallMethod(handler, (char *) "endElement",
624 (char *) "s", name);
625 if (PyErr_Occurred())
626 PyErr_Print();
Daniel Veillard33caa0b2002-02-04 14:07:26 +0000627 Py_XDECREF(result);
Daniel Veillardd2379012002-03-15 22:24:56 +0000628 } else if (PyObject_HasAttrString(handler, (char *) "end")) {
629 result = PyObject_CallMethod(handler, (char *) "end",
630 (char *) "s", name);
631 if (PyErr_Occurred())
632 PyErr_Print();
Daniel Veillard797a5652002-02-12 13:46:21 +0000633 Py_XDECREF(result);
Daniel Veillard33caa0b2002-02-04 14:07:26 +0000634 }
635}
636
637static void
638pythonReference(void *user_data, const xmlChar * name)
639{
640 PyObject *handler;
641 PyObject *result;
642
Daniel Veillard797a5652002-02-12 13:46:21 +0000643#ifdef DEBUG_SAX
644 printf("pythonReference(%s) called\n", name);
645#endif
Daniel Veillard33caa0b2002-02-04 14:07:26 +0000646 handler = (PyObject *) user_data;
Daniel Veillardd2379012002-03-15 22:24:56 +0000647 if (PyObject_HasAttrString(handler, (char *) "reference")) {
648 result = PyObject_CallMethod(handler, (char *) "reference",
649 (char *) "s", name);
650 if (PyErr_Occurred())
651 PyErr_Print();
Daniel Veillard33caa0b2002-02-04 14:07:26 +0000652 Py_XDECREF(result);
653 }
654}
655
656static void
657pythonCharacters(void *user_data, const xmlChar * ch, int len)
658{
659 PyObject *handler;
Daniel Veillardd2379012002-03-15 22:24:56 +0000660 PyObject *result = NULL;
Daniel Veillard33caa0b2002-02-04 14:07:26 +0000661 int type = 0;
662
Daniel Veillard797a5652002-02-12 13:46:21 +0000663#ifdef DEBUG_SAX
664 printf("pythonCharacters(%s, %d) called\n", ch, len);
665#endif
Daniel Veillard33caa0b2002-02-04 14:07:26 +0000666 handler = (PyObject *) user_data;
Daniel Veillardd2379012002-03-15 22:24:56 +0000667 if (PyObject_HasAttrString(handler, (char *) "characters"))
668 type = 1;
669 else if (PyObject_HasAttrString(handler, (char *) "data"))
670 type = 2;
Daniel Veillard33caa0b2002-02-04 14:07:26 +0000671 if (type != 0) {
Daniel Veillardd2379012002-03-15 22:24:56 +0000672 if (type == 1)
673 result = PyObject_CallMethod(handler, (char *) "characters",
674 (char *) "s#", ch, len);
675 else if (type == 2)
676 result = PyObject_CallMethod(handler, (char *) "data",
677 (char *) "s#", ch, len);
678 if (PyErr_Occurred())
679 PyErr_Print();
Daniel Veillard33caa0b2002-02-04 14:07:26 +0000680 Py_XDECREF(result);
681 }
682}
683
684static void
685pythonIgnorableWhitespace(void *user_data, const xmlChar * ch, int len)
686{
687 PyObject *handler;
Daniel Veillardd2379012002-03-15 22:24:56 +0000688 PyObject *result = NULL;
Daniel Veillard33caa0b2002-02-04 14:07:26 +0000689 int type = 0;
690
Daniel Veillard797a5652002-02-12 13:46:21 +0000691#ifdef DEBUG_SAX
692 printf("pythonIgnorableWhitespace(%s, %d) called\n", ch, len);
693#endif
Daniel Veillard33caa0b2002-02-04 14:07:26 +0000694 handler = (PyObject *) user_data;
Daniel Veillardd2379012002-03-15 22:24:56 +0000695 if (PyObject_HasAttrString(handler, (char *) "ignorableWhitespace"))
Daniel Veillard33caa0b2002-02-04 14:07:26 +0000696 type = 1;
Daniel Veillardd2379012002-03-15 22:24:56 +0000697 else if (PyObject_HasAttrString(handler, (char *) "data"))
Daniel Veillard33caa0b2002-02-04 14:07:26 +0000698 type = 2;
699 if (type != 0) {
700 if (type == 1)
701 result =
Daniel Veillardd2379012002-03-15 22:24:56 +0000702 PyObject_CallMethod(handler,
703 (char *) "ignorableWhitespace",
704 (char *) "s#", ch, len);
Daniel Veillard33caa0b2002-02-04 14:07:26 +0000705 else if (type == 2)
Daniel Veillardd2379012002-03-15 22:24:56 +0000706 result =
707 PyObject_CallMethod(handler, (char *) "data",
708 (char *) "s#", ch, len);
Daniel Veillard33caa0b2002-02-04 14:07:26 +0000709 Py_XDECREF(result);
710 }
711}
712
713static void
714pythonProcessingInstruction(void *user_data,
715 const xmlChar * target, const xmlChar * data)
716{
717 PyObject *handler;
718 PyObject *result;
719
Daniel Veillard797a5652002-02-12 13:46:21 +0000720#ifdef DEBUG_SAX
721 printf("pythonProcessingInstruction(%s, %s) called\n", target, data);
722#endif
Daniel Veillard33caa0b2002-02-04 14:07:26 +0000723 handler = (PyObject *) user_data;
Daniel Veillardd2379012002-03-15 22:24:56 +0000724 if (PyObject_HasAttrString(handler, (char *) "processingInstruction")) {
725 result = PyObject_CallMethod(handler, (char *)
726 "processingInstruction",
727 (char *) "ss", target, data);
Daniel Veillard33caa0b2002-02-04 14:07:26 +0000728 Py_XDECREF(result);
729 }
730}
731
732static void
733pythonComment(void *user_data, const xmlChar * value)
734{
735 PyObject *handler;
736 PyObject *result;
737
Daniel Veillard797a5652002-02-12 13:46:21 +0000738#ifdef DEBUG_SAX
739 printf("pythonComment(%s) called\n", value);
740#endif
Daniel Veillard33caa0b2002-02-04 14:07:26 +0000741 handler = (PyObject *) user_data;
Daniel Veillardd2379012002-03-15 22:24:56 +0000742 if (PyObject_HasAttrString(handler, (char *) "comment")) {
743 result =
744 PyObject_CallMethod(handler, (char *) "comment", (char *) "s",
745 value);
746 if (PyErr_Occurred())
747 PyErr_Print();
Daniel Veillard33caa0b2002-02-04 14:07:26 +0000748 Py_XDECREF(result);
749 }
750}
751
752static void
753pythonWarning(void *user_data, const char *msg, ...)
754{
755 PyObject *handler;
756 PyObject *result;
757 va_list args;
758 char buf[1024];
759
Daniel Veillard797a5652002-02-12 13:46:21 +0000760#ifdef DEBUG_SAX
761 printf("pythonWarning(%s) called\n", msg);
762#endif
Daniel Veillard33caa0b2002-02-04 14:07:26 +0000763 handler = (PyObject *) user_data;
Daniel Veillardd2379012002-03-15 22:24:56 +0000764 if (PyObject_HasAttrString(handler, (char *) "warning")) {
Daniel Veillard33caa0b2002-02-04 14:07:26 +0000765 va_start(args, msg);
766 vsnprintf(buf, 1023, msg, args);
Daniel Veillardd2379012002-03-15 22:24:56 +0000767 va_end(args);
768 buf[1023] = 0;
769 result =
770 PyObject_CallMethod(handler, (char *) "warning", (char *) "s",
771 buf);
772 if (PyErr_Occurred())
773 PyErr_Print();
Daniel Veillard33caa0b2002-02-04 14:07:26 +0000774 Py_XDECREF(result);
775 }
776}
777
778static void
779pythonError(void *user_data, const char *msg, ...)
780{
781 PyObject *handler;
782 PyObject *result;
783 va_list args;
784 char buf[1024];
785
Daniel Veillard797a5652002-02-12 13:46:21 +0000786#ifdef DEBUG_SAX
787 printf("pythonError(%s) called\n", msg);
788#endif
Daniel Veillard33caa0b2002-02-04 14:07:26 +0000789 handler = (PyObject *) user_data;
Daniel Veillardd2379012002-03-15 22:24:56 +0000790 if (PyObject_HasAttrString(handler, (char *) "error")) {
Daniel Veillard33caa0b2002-02-04 14:07:26 +0000791 va_start(args, msg);
792 vsnprintf(buf, 1023, msg, args);
Daniel Veillardd2379012002-03-15 22:24:56 +0000793 va_end(args);
794 buf[1023] = 0;
795 result =
796 PyObject_CallMethod(handler, (char *) "error", (char *) "s",
797 buf);
798 if (PyErr_Occurred())
799 PyErr_Print();
Daniel Veillard33caa0b2002-02-04 14:07:26 +0000800 Py_XDECREF(result);
801 }
802}
803
804static void
805pythonFatalError(void *user_data, const char *msg, ...)
806{
807 PyObject *handler;
808 PyObject *result;
809 va_list args;
810 char buf[1024];
811
Daniel Veillard797a5652002-02-12 13:46:21 +0000812#ifdef DEBUG_SAX
813 printf("pythonFatalError(%s) called\n", msg);
814#endif
Daniel Veillard33caa0b2002-02-04 14:07:26 +0000815 handler = (PyObject *) user_data;
Daniel Veillardd2379012002-03-15 22:24:56 +0000816 if (PyObject_HasAttrString(handler, (char *) "fatalError")) {
Daniel Veillard33caa0b2002-02-04 14:07:26 +0000817 va_start(args, msg);
818 vsnprintf(buf, 1023, msg, args);
Daniel Veillardd2379012002-03-15 22:24:56 +0000819 va_end(args);
820 buf[1023] = 0;
821 result =
822 PyObject_CallMethod(handler, (char *) "fatalError",
823 (char *) "s", buf);
824 if (PyErr_Occurred())
825 PyErr_Print();
Daniel Veillard33caa0b2002-02-04 14:07:26 +0000826 Py_XDECREF(result);
827 }
828}
829
830static void
831pythonCdataBlock(void *user_data, const xmlChar * ch, int len)
832{
833 PyObject *handler;
Daniel Veillardd2379012002-03-15 22:24:56 +0000834 PyObject *result = NULL;
Daniel Veillard33caa0b2002-02-04 14:07:26 +0000835 int type = 0;
836
Daniel Veillard797a5652002-02-12 13:46:21 +0000837#ifdef DEBUG_SAX
838 printf("pythonCdataBlock(%s, %d) called\n", ch, len);
839#endif
Daniel Veillard33caa0b2002-02-04 14:07:26 +0000840 handler = (PyObject *) user_data;
Daniel Veillardd2379012002-03-15 22:24:56 +0000841 if (PyObject_HasAttrString(handler, (char *) "cdataBlock"))
842 type = 1;
843 else if (PyObject_HasAttrString(handler, (char *) "cdata"))
844 type = 2;
Daniel Veillard33caa0b2002-02-04 14:07:26 +0000845 if (type != 0) {
Daniel Veillardd2379012002-03-15 22:24:56 +0000846 if (type == 1)
847 result =
848 PyObject_CallMethod(handler, (char *) "cdataBlock",
849 (char *) "s#", ch, len);
850 else if (type == 2)
851 result =
852 PyObject_CallMethod(handler, (char *) "cdata",
853 (char *) "s#", ch, len);
854 if (PyErr_Occurred())
855 PyErr_Print();
Daniel Veillard33caa0b2002-02-04 14:07:26 +0000856 Py_XDECREF(result);
857 }
858}
859
860static void
861pythonExternalSubset(void *user_data,
862 const xmlChar * name,
863 const xmlChar * externalID, const xmlChar * systemID)
864{
865 PyObject *handler;
866 PyObject *result;
867
Daniel Veillard797a5652002-02-12 13:46:21 +0000868#ifdef DEBUG_SAX
869 printf("pythonExternalSubset(%s, %s, %s) called\n",
Daniel Veillardd2379012002-03-15 22:24:56 +0000870 name, externalID, systemID);
Daniel Veillard797a5652002-02-12 13:46:21 +0000871#endif
Daniel Veillard33caa0b2002-02-04 14:07:26 +0000872 handler = (PyObject *) user_data;
Daniel Veillardd2379012002-03-15 22:24:56 +0000873 if (PyObject_HasAttrString(handler, (char *) "externalSubset")) {
Daniel Veillard33caa0b2002-02-04 14:07:26 +0000874 result =
Daniel Veillardd2379012002-03-15 22:24:56 +0000875 PyObject_CallMethod(handler, (char *) "externalSubset",
876 (char *) "sss", name, externalID,
877 systemID);
Daniel Veillard33caa0b2002-02-04 14:07:26 +0000878 Py_XDECREF(result);
879 }
880}
881
882static void
883pythonEntityDecl(void *user_data,
884 const xmlChar * name,
885 int type,
886 const xmlChar * publicId,
887 const xmlChar * systemId, xmlChar * content)
888{
889 PyObject *handler;
890 PyObject *result;
891
892 handler = (PyObject *) user_data;
Daniel Veillardd2379012002-03-15 22:24:56 +0000893 if (PyObject_HasAttrString(handler, (char *) "entityDecl")) {
894 result = PyObject_CallMethod(handler, (char *) "entityDecl",
895 (char *) "sisss", name, type,
896 publicId, systemId, content);
897 if (PyErr_Occurred())
898 PyErr_Print();
Daniel Veillard33caa0b2002-02-04 14:07:26 +0000899 Py_XDECREF(result);
900 }
901}
902
903
904
905static void
906
907pythonNotationDecl(void *user_data,
908 const xmlChar * name,
909 const xmlChar * publicId, const xmlChar * systemId)
910{
911 PyObject *handler;
912 PyObject *result;
913
914 handler = (PyObject *) user_data;
Daniel Veillardd2379012002-03-15 22:24:56 +0000915 if (PyObject_HasAttrString(handler, (char *) "notationDecl")) {
916 result = PyObject_CallMethod(handler, (char *) "notationDecl",
917 (char *) "sss", name, publicId,
918 systemId);
919 if (PyErr_Occurred())
920 PyErr_Print();
Daniel Veillard33caa0b2002-02-04 14:07:26 +0000921 Py_XDECREF(result);
922 }
923}
924
925static void
926pythonAttributeDecl(void *user_data,
927 const xmlChar * elem,
928 const xmlChar * name,
929 int type,
930 int def,
Daniel Veillardd2379012002-03-15 22:24:56 +0000931 const xmlChar * defaultValue, xmlEnumerationPtr tree)
Daniel Veillard33caa0b2002-02-04 14:07:26 +0000932{
933 PyObject *handler;
934 PyObject *nameList;
935 PyObject *newName;
936 xmlEnumerationPtr node;
937 PyObject *result;
938 int count;
939
940 handler = (PyObject *) user_data;
Daniel Veillardd2379012002-03-15 22:24:56 +0000941 if (PyObject_HasAttrString(handler, (char *) "attributeDecl")) {
Daniel Veillard33caa0b2002-02-04 14:07:26 +0000942 count = 0;
943 for (node = tree; node != NULL; node = node->next) {
944 count++;
945 }
946 nameList = PyList_New(count);
947 count = 0;
948 for (node = tree; node != NULL; node = node->next) {
Daniel Veillardd2379012002-03-15 22:24:56 +0000949 newName = PyString_FromString((char *) node->name);
Daniel Veillard33caa0b2002-02-04 14:07:26 +0000950 PyList_SetItem(nameList, count, newName);
951 count++;
952 }
Daniel Veillardd2379012002-03-15 22:24:56 +0000953 result = PyObject_CallMethod(handler, (char *) "attributeDecl",
954 (char *) "ssiisO", elem, name, type,
955 def, defaultValue, nameList);
956 if (PyErr_Occurred())
957 PyErr_Print();
Daniel Veillard33caa0b2002-02-04 14:07:26 +0000958 Py_XDECREF(nameList);
959 Py_XDECREF(result);
960 }
961}
962
963static void
964pythonElementDecl(void *user_data,
965 const xmlChar * name,
Daniel Veillardd2379012002-03-15 22:24:56 +0000966 int type, ATTRIBUTE_UNUSED xmlElementContentPtr content)
Daniel Veillard33caa0b2002-02-04 14:07:26 +0000967{
968 PyObject *handler;
969 PyObject *obj;
970 PyObject *result;
971
972 handler = (PyObject *) user_data;
Daniel Veillardd2379012002-03-15 22:24:56 +0000973 if (PyObject_HasAttrString(handler, (char *) "elementDecl")) {
974 /* TODO: wrap in an elementContent object */
975 printf
976 ("pythonElementDecl: xmlElementContentPtr wrapper missing !\n");
977 obj = Py_None;
978 /* Py_XINCREF(Py_None); isn't the reference just borrowed ??? */
979 result = PyObject_CallMethod(handler, (char *) "elementDecl",
980 (char *) "siO", name, type, obj);
981 if (PyErr_Occurred())
982 PyErr_Print();
Daniel Veillard33caa0b2002-02-04 14:07:26 +0000983 Py_XDECREF(result);
984 }
985}
986
987static void
988pythonUnparsedEntityDecl(void *user_data,
989 const xmlChar * name,
990 const xmlChar * publicId,
991 const xmlChar * systemId,
992 const xmlChar * notationName)
993{
994 PyObject *handler;
995 PyObject *result;
996
997 handler = (PyObject *) user_data;
Daniel Veillardd2379012002-03-15 22:24:56 +0000998 if (PyObject_HasAttrString(handler, (char *) "unparsedEntityDecl")) {
999 result =
1000 PyObject_CallMethod(handler, (char *) "unparsedEntityDecl",
1001 (char *) "ssss", name, publicId, systemId,
1002 notationName);
1003 if (PyErr_Occurred())
1004 PyErr_Print();
Daniel Veillard33caa0b2002-02-04 14:07:26 +00001005 Py_XDECREF(result);
1006 }
1007}
1008
1009static void
1010pythonInternalSubset(void *user_data, const xmlChar * name,
1011 const xmlChar * ExternalID, const xmlChar * SystemID)
1012{
1013 PyObject *handler;
1014 PyObject *result;
1015
Daniel Veillard797a5652002-02-12 13:46:21 +00001016#ifdef DEBUG_SAX
1017 printf("pythonInternalSubset(%s, %s, %s) called\n",
Daniel Veillardd2379012002-03-15 22:24:56 +00001018 name, ExternalID, SystemID);
Daniel Veillard797a5652002-02-12 13:46:21 +00001019#endif
Daniel Veillard33caa0b2002-02-04 14:07:26 +00001020 handler = (PyObject *) user_data;
Daniel Veillardd2379012002-03-15 22:24:56 +00001021 if (PyObject_HasAttrString(handler, (char *) "internalSubset")) {
1022 result = PyObject_CallMethod(handler, (char *) "internalSubset",
1023 (char *) "sss", name, ExternalID,
1024 SystemID);
1025 if (PyErr_Occurred())
1026 PyErr_Print();
Daniel Veillard33caa0b2002-02-04 14:07:26 +00001027 Py_XDECREF(result);
1028 }
1029}
1030
1031static xmlSAXHandler pythonSaxHandler = {
1032 pythonInternalSubset,
Daniel Veillardd2379012002-03-15 22:24:56 +00001033 NULL, /* TODO pythonIsStandalone, */
1034 NULL, /* TODO pythonHasInternalSubset, */
1035 NULL, /* TODO pythonHasExternalSubset, */
1036 NULL, /* TODO pythonResolveEntity, */
1037 NULL, /* TODO pythonGetEntity, */
Daniel Veillard33caa0b2002-02-04 14:07:26 +00001038 pythonEntityDecl,
1039 pythonNotationDecl,
1040 pythonAttributeDecl,
1041 pythonElementDecl,
1042 pythonUnparsedEntityDecl,
Daniel Veillardd2379012002-03-15 22:24:56 +00001043 NULL, /* OBSOLETED pythonSetDocumentLocator, */
Daniel Veillard33caa0b2002-02-04 14:07:26 +00001044 pythonStartDocument,
1045 pythonEndDocument,
1046 pythonStartElement,
1047 pythonEndElement,
1048 pythonReference,
1049 pythonCharacters,
1050 pythonIgnorableWhitespace,
1051 pythonProcessingInstruction,
1052 pythonComment,
1053 pythonWarning,
1054 pythonError,
1055 pythonFatalError,
Daniel Veillardd2379012002-03-15 22:24:56 +00001056 NULL, /* TODO pythonGetParameterEntity, */
Daniel Veillard33caa0b2002-02-04 14:07:26 +00001057 pythonCdataBlock,
1058 pythonExternalSubset,
1059 1
1060};
Daniel Veillard3ce52572002-02-03 15:08:05 +00001061
1062/************************************************************************
1063 * *
1064 * Handling of specific parser context *
1065 * *
1066 ************************************************************************/
Daniel Veillardd2897fd2002-01-30 16:37:32 +00001067
1068PyObject *
Daniel Veillardd2379012002-03-15 22:24:56 +00001069libxml_xmlCreatePushParser(ATTRIBUTE_UNUSED PyObject * self,
1070 PyObject * args)
1071{
1072 const char *chunk;
Daniel Veillard3ce52572002-02-03 15:08:05 +00001073 int size;
Daniel Veillardd2379012002-03-15 22:24:56 +00001074 const char *URI;
Daniel Veillard33caa0b2002-02-04 14:07:26 +00001075 PyObject *pyobj_SAX = NULL;
Daniel Veillard3ce52572002-02-03 15:08:05 +00001076 xmlSAXHandlerPtr SAX = NULL;
Daniel Veillard3ce52572002-02-03 15:08:05 +00001077 xmlParserCtxtPtr ret;
1078 PyObject *pyret;
Daniel Veillard96fe0952002-01-30 20:52:23 +00001079
Daniel Veillardd2379012002-03-15 22:24:56 +00001080 if (!PyArg_ParseTuple
1081 (args, (char *) "Oziz:xmlCreatePushParser", &pyobj_SAX, &chunk,
1082 &size, &URI))
1083 return (NULL);
Daniel Veillard3ce52572002-02-03 15:08:05 +00001084
Daniel Veillard8d24cc12002-03-05 15:41:29 +00001085#ifdef DEBUG
Daniel Veillard3ce52572002-02-03 15:08:05 +00001086 printf("libxml_xmlCreatePushParser(%p, %s, %d, %s) called\n",
Daniel Veillardd2379012002-03-15 22:24:56 +00001087 pyobj_SAX, chunk, size, URI);
Daniel Veillard96fe0952002-01-30 20:52:23 +00001088#endif
Daniel Veillard3ce52572002-02-03 15:08:05 +00001089 if (pyobj_SAX != Py_None) {
Daniel Veillardd2379012002-03-15 22:24:56 +00001090 SAX = &pythonSaxHandler;
1091 Py_INCREF(pyobj_SAX);
1092 /* The reference is released in pythonEndDocument() */
Daniel Veillardd2897fd2002-01-30 16:37:32 +00001093 }
Daniel Veillard33caa0b2002-02-04 14:07:26 +00001094 ret = xmlCreatePushParserCtxt(SAX, pyobj_SAX, chunk, size, URI);
Daniel Veillard3ce52572002-02-03 15:08:05 +00001095 pyret = libxml_xmlParserCtxtPtrWrap(ret);
Daniel Veillardd2379012002-03-15 22:24:56 +00001096 return (pyret);
Daniel Veillarda7340c82002-02-01 17:56:45 +00001097}
Daniel Veillard5d819032002-02-02 21:49:17 +00001098
Daniel Veillard4e1b26c2002-02-03 20:13:06 +00001099PyObject *
Daniel Veillardd2379012002-03-15 22:24:56 +00001100libxml_htmlCreatePushParser(ATTRIBUTE_UNUSED PyObject * self,
1101 PyObject * args)
1102{
1103 const char *chunk;
Daniel Veillard4e1b26c2002-02-03 20:13:06 +00001104 int size;
Daniel Veillardd2379012002-03-15 22:24:56 +00001105 const char *URI;
Daniel Veillard33caa0b2002-02-04 14:07:26 +00001106 PyObject *pyobj_SAX = NULL;
Daniel Veillard4e1b26c2002-02-03 20:13:06 +00001107 xmlSAXHandlerPtr SAX = NULL;
Daniel Veillard4e1b26c2002-02-03 20:13:06 +00001108 xmlParserCtxtPtr ret;
1109 PyObject *pyret;
1110
Daniel Veillardd2379012002-03-15 22:24:56 +00001111 if (!PyArg_ParseTuple
1112 (args, (char *) "Oziz:htmlCreatePushParser", &pyobj_SAX, &chunk,
1113 &size, &URI))
1114 return (NULL);
Daniel Veillard4e1b26c2002-02-03 20:13:06 +00001115
Daniel Veillard8d24cc12002-03-05 15:41:29 +00001116#ifdef DEBUG
Daniel Veillard4e1b26c2002-02-03 20:13:06 +00001117 printf("libxml_htmlCreatePushParser(%p, %s, %d, %s) called\n",
Daniel Veillardd2379012002-03-15 22:24:56 +00001118 pyobj_SAX, chunk, size, URI);
Daniel Veillard4e1b26c2002-02-03 20:13:06 +00001119#endif
1120 if (pyobj_SAX != Py_None) {
Daniel Veillardd2379012002-03-15 22:24:56 +00001121 SAX = &pythonSaxHandler;
1122 Py_INCREF(pyobj_SAX);
1123 /* The reference is released in pythonEndDocument() */
Daniel Veillard4e1b26c2002-02-03 20:13:06 +00001124 }
Daniel Veillard33caa0b2002-02-04 14:07:26 +00001125 ret = htmlCreatePushParserCtxt(SAX, pyobj_SAX, chunk, size, URI,
Daniel Veillardd2379012002-03-15 22:24:56 +00001126 XML_CHAR_ENCODING_NONE);
Daniel Veillard4e1b26c2002-02-03 20:13:06 +00001127 pyret = libxml_xmlParserCtxtPtrWrap(ret);
Daniel Veillardd2379012002-03-15 22:24:56 +00001128 return (pyret);
Daniel Veillard4e1b26c2002-02-03 20:13:06 +00001129}
1130
Daniel Veillard8d24cc12002-03-05 15:41:29 +00001131PyObject *
Daniel Veillardd2379012002-03-15 22:24:56 +00001132libxml_xmlSAXParseFile(ATTRIBUTE_UNUSED PyObject * self, PyObject * args)
1133{
Daniel Veillard8d24cc12002-03-05 15:41:29 +00001134 int recover;
Daniel Veillardd2379012002-03-15 22:24:56 +00001135 const char *URI;
Daniel Veillard8d24cc12002-03-05 15:41:29 +00001136 PyObject *pyobj_SAX = NULL;
1137 xmlSAXHandlerPtr SAX = NULL;
1138
Daniel Veillardd2379012002-03-15 22:24:56 +00001139 if (!PyArg_ParseTuple(args, (char *) "Osi:xmlSAXParseFile", &pyobj_SAX,
1140 &URI, &recover))
1141 return (NULL);
Daniel Veillard8d24cc12002-03-05 15:41:29 +00001142
1143#ifdef DEBUG
1144 printf("libxml_xmlSAXParseFile(%p, %s, %d) called\n",
Daniel Veillardd2379012002-03-15 22:24:56 +00001145 pyobj_SAX, URI, recover);
Daniel Veillard8d24cc12002-03-05 15:41:29 +00001146#endif
1147 if (pyobj_SAX == Py_None) {
Daniel Veillardd2379012002-03-15 22:24:56 +00001148 Py_INCREF(Py_None);
1149 return (Py_None);
Daniel Veillard8d24cc12002-03-05 15:41:29 +00001150 }
1151 SAX = &pythonSaxHandler;
1152 Py_INCREF(pyobj_SAX);
1153 /* The reference is released in pythonEndDocument() */
1154 xmlSAXParseFileWithData(SAX, URI, recover, pyobj_SAX);
1155 Py_INCREF(Py_None);
Daniel Veillardd2379012002-03-15 22:24:56 +00001156 return (Py_None);
Daniel Veillard8d24cc12002-03-05 15:41:29 +00001157}
1158
1159PyObject *
Daniel Veillardd2379012002-03-15 22:24:56 +00001160libxml_htmlSAXParseFile(ATTRIBUTE_UNUSED PyObject * self, PyObject * args)
1161{
1162 const char *URI;
1163 const char *encoding;
Daniel Veillard8d24cc12002-03-05 15:41:29 +00001164 PyObject *pyobj_SAX = NULL;
1165 xmlSAXHandlerPtr SAX = NULL;
1166
Daniel Veillardd2379012002-03-15 22:24:56 +00001167 if (!PyArg_ParseTuple
1168 (args, (char *) "Osz:htmlSAXParseFile", &pyobj_SAX, &URI,
1169 &encoding))
1170 return (NULL);
Daniel Veillard8d24cc12002-03-05 15:41:29 +00001171
1172#ifdef DEBUG
1173 printf("libxml_htmlSAXParseFile(%p, %s, %s) called\n",
Daniel Veillardd2379012002-03-15 22:24:56 +00001174 pyobj_SAX, URI, encoding);
Daniel Veillard8d24cc12002-03-05 15:41:29 +00001175#endif
1176 if (pyobj_SAX == Py_None) {
Daniel Veillardd2379012002-03-15 22:24:56 +00001177 Py_INCREF(Py_None);
1178 return (Py_None);
Daniel Veillard8d24cc12002-03-05 15:41:29 +00001179 }
1180 SAX = &pythonSaxHandler;
1181 Py_INCREF(pyobj_SAX);
1182 /* The reference is released in pythonEndDocument() */
1183 htmlSAXParseFile(URI, encoding, SAX, pyobj_SAX);
1184 Py_INCREF(Py_None);
Daniel Veillardd2379012002-03-15 22:24:56 +00001185 return (Py_None);
Daniel Veillard8d24cc12002-03-05 15:41:29 +00001186}
1187
Daniel Veillard5d819032002-02-02 21:49:17 +00001188/************************************************************************
1189 * *
1190 * Error message callback *
1191 * *
1192 ************************************************************************/
1193
1194static PyObject *libxml_xmlPythonErrorFuncHandler = NULL;
1195static PyObject *libxml_xmlPythonErrorFuncCtxt = NULL;
1196
Daniel Veillarde6227e02003-01-14 11:42:39 +00001197/* helper to build a xmlMalloc'ed string from a format and va_list */
1198static char *
1199libxml_buildMessage(const char *msg, va_list ap)
Daniel Veillardd2379012002-03-15 22:24:56 +00001200{
1201 int size;
1202 int chars;
1203 char *larger;
Daniel Veillarde6227e02003-01-14 11:42:39 +00001204 char *str;
1205
1206 str = (char *) xmlMalloc(150);
1207 if (str == NULL)
1208 return NULL;
1209
1210 size = 150;
1211
1212 while (1) {
1213 chars = vsnprintf(str, size, msg, ap);
1214 if ((chars > -1) && (chars < size))
1215 break;
1216 if (chars > -1)
1217 size += chars + 1;
1218 else
1219 size += 100;
1220 if ((larger = (char *) xmlRealloc(str, size)) == NULL) {
1221 xmlFree(str);
1222 return NULL;
1223 }
1224 str = larger;
1225 }
1226
1227 return str;
1228}
1229
1230static void
1231libxml_xmlErrorFuncHandler(ATTRIBUTE_UNUSED void *ctx, const char *msg,
1232 ...)
1233{
Daniel Veillardd2379012002-03-15 22:24:56 +00001234 va_list ap;
1235 char *str;
Daniel Veillard5d819032002-02-02 21:49:17 +00001236 PyObject *list;
1237 PyObject *message;
1238 PyObject *result;
1239
1240#ifdef DEBUG_ERROR
1241 printf("libxml_xmlErrorFuncHandler(%p, %s, ...) called\n", ctx, msg);
1242#endif
1243
1244
1245 if (libxml_xmlPythonErrorFuncHandler == NULL) {
Daniel Veillardd2379012002-03-15 22:24:56 +00001246 va_start(ap, msg);
1247 vfprintf(stdout, msg, ap);
1248 va_end(ap);
Daniel Veillard5d819032002-02-02 21:49:17 +00001249 } else {
Daniel Veillarde6227e02003-01-14 11:42:39 +00001250 va_start(ap, msg);
1251 str = libxml_buildMessage(msg,ap);
1252 va_end(ap);
Daniel Veillard5d819032002-02-02 21:49:17 +00001253
Daniel Veillardd2379012002-03-15 22:24:56 +00001254 list = PyTuple_New(2);
1255 PyTuple_SetItem(list, 0, libxml_xmlPythonErrorFuncCtxt);
1256 Py_XINCREF(libxml_xmlPythonErrorFuncCtxt);
1257 message = libxml_charPtrWrap(str);
1258 PyTuple_SetItem(list, 1, message);
1259 result = PyEval_CallObject(libxml_xmlPythonErrorFuncHandler, list);
1260 Py_XDECREF(list);
1261 Py_XDECREF(result);
Daniel Veillard5d819032002-02-02 21:49:17 +00001262 }
1263}
1264
1265static void
Daniel Veillardd2379012002-03-15 22:24:56 +00001266libxml_xmlErrorInitialize(void)
1267{
Daniel Veillard5d819032002-02-02 21:49:17 +00001268#ifdef DEBUG_ERROR
1269 printf("libxml_xmlErrorInitialize() called\n");
1270#endif
1271 xmlSetGenericErrorFunc(NULL, libxml_xmlErrorFuncHandler);
Daniel Veillard781ac8b2003-05-15 22:11:36 +00001272 xmlThrDefSetGenericErrorFunc(NULL, libxml_xmlErrorFuncHandler);
Daniel Veillard5d819032002-02-02 21:49:17 +00001273}
1274
Daniel Veillardc2664642003-07-29 20:44:53 +00001275static PyObject *
Daniel Veillardd2379012002-03-15 22:24:56 +00001276libxml_xmlRegisterErrorHandler(ATTRIBUTE_UNUSED PyObject * self,
1277 PyObject * args)
1278{
Daniel Veillard5d819032002-02-02 21:49:17 +00001279 PyObject *py_retval;
1280 PyObject *pyobj_f;
1281 PyObject *pyobj_ctx;
1282
Daniel Veillardd2379012002-03-15 22:24:56 +00001283 if (!PyArg_ParseTuple
1284 (args, (char *) "OO:xmlRegisterErrorHandler", &pyobj_f,
1285 &pyobj_ctx))
1286 return (NULL);
Daniel Veillard5d819032002-02-02 21:49:17 +00001287
1288#ifdef DEBUG_ERROR
Daniel Veillardd2379012002-03-15 22:24:56 +00001289 printf("libxml_registerXPathFunction(%p, %p) called\n", pyobj_ctx,
1290 pyobj_f);
Daniel Veillard5d819032002-02-02 21:49:17 +00001291#endif
1292
1293 if (libxml_xmlPythonErrorFuncHandler != NULL) {
Daniel Veillardd2379012002-03-15 22:24:56 +00001294 Py_XDECREF(libxml_xmlPythonErrorFuncHandler);
Daniel Veillard5d819032002-02-02 21:49:17 +00001295 }
1296 if (libxml_xmlPythonErrorFuncCtxt != NULL) {
Daniel Veillardd2379012002-03-15 22:24:56 +00001297 Py_XDECREF(libxml_xmlPythonErrorFuncCtxt);
Daniel Veillard5d819032002-02-02 21:49:17 +00001298 }
1299
1300 Py_XINCREF(pyobj_ctx);
1301 Py_XINCREF(pyobj_f);
1302
1303 /* TODO: check f is a function ! */
1304 libxml_xmlPythonErrorFuncHandler = pyobj_f;
1305 libxml_xmlPythonErrorFuncCtxt = pyobj_ctx;
1306
1307 py_retval = libxml_intWrap(1);
Daniel Veillardd2379012002-03-15 22:24:56 +00001308 return (py_retval);
Daniel Veillard5d819032002-02-02 21:49:17 +00001309}
Daniel Veillardd2379012002-03-15 22:24:56 +00001310
Daniel Veillarde6227e02003-01-14 11:42:39 +00001311
1312/************************************************************************
1313 * *
1314 * Per parserCtxt error handler *
1315 * *
1316 ************************************************************************/
1317
Daniel Veillard417be3a2003-01-20 21:26:34 +00001318typedef struct
Daniel Veillarde6227e02003-01-14 11:42:39 +00001319{
Daniel Veillard417be3a2003-01-20 21:26:34 +00001320 PyObject *f;
1321 PyObject *arg;
1322} xmlParserCtxtPyCtxt;
1323typedef xmlParserCtxtPyCtxt *xmlParserCtxtPyCtxtPtr;
1324
1325static void
1326libxml_xmlParserCtxtGenericErrorFuncHandler(void *ctx, int severity, char *str)
1327{
Daniel Veillarde6227e02003-01-14 11:42:39 +00001328 PyObject *list;
Daniel Veillarde6227e02003-01-14 11:42:39 +00001329 PyObject *result;
Daniel Veillard417be3a2003-01-20 21:26:34 +00001330 xmlParserCtxtPtr ctxt;
Daniel Veillarde6227e02003-01-14 11:42:39 +00001331 xmlParserCtxtPyCtxtPtr pyCtxt;
1332
1333#ifdef DEBUG_ERROR
Daniel Veillard417be3a2003-01-20 21:26:34 +00001334 printf("libxml_xmlParserCtxtGenericErrorFuncHandler(%p, %s, ...) called\n", ctx, msg);
Daniel Veillarde6227e02003-01-14 11:42:39 +00001335#endif
1336
Daniel Veillard417be3a2003-01-20 21:26:34 +00001337 ctxt = (xmlParserCtxtPtr)ctx;
1338 pyCtxt = (xmlParserCtxtPyCtxtPtr)ctxt->_private;
Daniel Veillarde6227e02003-01-14 11:42:39 +00001339
Daniel Veillard417be3a2003-01-20 21:26:34 +00001340 list = PyTuple_New(4);
1341 PyTuple_SetItem(list, 0, pyCtxt->arg);
1342 Py_XINCREF(pyCtxt->arg);
1343 PyTuple_SetItem(list, 1, libxml_charPtrWrap(str));
1344 PyTuple_SetItem(list, 2, libxml_intWrap(severity));
1345 PyTuple_SetItem(list, 3, Py_None);
1346 Py_INCREF(Py_None);
1347 result = PyEval_CallObject(pyCtxt->f, list);
1348 if (result == NULL)
1349 {
1350 /* TODO: manage for the exception to be propagated... */
1351 PyErr_Print();
Daniel Veillarde6227e02003-01-14 11:42:39 +00001352 }
Daniel Veillard417be3a2003-01-20 21:26:34 +00001353 Py_XDECREF(list);
1354 Py_XDECREF(result);
1355}
1356
1357static void
1358libxml_xmlParserCtxtErrorFuncHandler(void *ctx, const char *msg, ...)
1359{
1360 va_list ap;
1361
1362 va_start(ap, msg);
1363 libxml_xmlParserCtxtGenericErrorFuncHandler(ctx,XML_PARSER_SEVERITY_ERROR,libxml_buildMessage(msg,ap));
1364 va_end(ap);
1365}
1366
1367static void
1368libxml_xmlParserCtxtWarningFuncHandler(void *ctx, const char *msg, ...)
1369{
1370 va_list ap;
1371
1372 va_start(ap, msg);
1373 libxml_xmlParserCtxtGenericErrorFuncHandler(ctx,XML_PARSER_SEVERITY_WARNING,libxml_buildMessage(msg,ap));
1374 va_end(ap);
1375}
1376
1377static void
1378libxml_xmlParserCtxtValidityErrorFuncHandler(void *ctx, const char *msg, ...)
1379{
1380 va_list ap;
1381
1382 va_start(ap, msg);
1383 libxml_xmlParserCtxtGenericErrorFuncHandler(ctx,XML_PARSER_SEVERITY_VALIDITY_ERROR,libxml_buildMessage(msg,ap));
1384 va_end(ap);
1385}
1386
1387static void
1388libxml_xmlParserCtxtValidityWarningFuncHandler(void *ctx, const char *msg, ...)
1389{
1390 va_list ap;
1391
1392 va_start(ap, msg);
1393 libxml_xmlParserCtxtGenericErrorFuncHandler(ctx,XML_PARSER_SEVERITY_VALIDITY_WARNING,libxml_buildMessage(msg,ap));
1394 va_end(ap);
Daniel Veillarde6227e02003-01-14 11:42:39 +00001395}
1396
Daniel Veillardc2664642003-07-29 20:44:53 +00001397static PyObject *
Daniel Veillard417be3a2003-01-20 21:26:34 +00001398libxml_xmlParserCtxtSetErrorHandler(ATTRIBUTE_UNUSED PyObject *self, PyObject *args)
Daniel Veillarde6227e02003-01-14 11:42:39 +00001399{
1400 PyObject *py_retval;
1401 xmlParserCtxtPtr ctxt;
Daniel Veillarde4a07e72003-01-14 14:40:25 +00001402 xmlParserCtxtPyCtxtPtr pyCtxt;
Daniel Veillarde6227e02003-01-14 11:42:39 +00001403 PyObject *pyobj_ctxt;
1404 PyObject *pyobj_f;
1405 PyObject *pyobj_arg;
1406
Daniel Veillard417be3a2003-01-20 21:26:34 +00001407 if (!PyArg_ParseTuple(args, (char *)"OOO:xmlParserCtxtSetErrorHandler",
Daniel Veillarde6227e02003-01-14 11:42:39 +00001408 &pyobj_ctxt, &pyobj_f, &pyobj_arg))
1409 return(NULL);
1410 ctxt = (xmlParserCtxtPtr) PyparserCtxt_Get(pyobj_ctxt);
1411 if (ctxt->_private == NULL) {
Daniel Veillarde6227e02003-01-14 11:42:39 +00001412 pyCtxt = xmlMalloc(sizeof(xmlParserCtxtPyCtxt));
1413 if (pyCtxt == NULL) {
1414 py_retval = libxml_intWrap(-1);
1415 return(py_retval);
1416 }
1417 memset(pyCtxt,0,sizeof(xmlParserCtxtPyCtxt));
1418 ctxt->_private = pyCtxt;
1419 }
Daniel Veillarde4a07e72003-01-14 14:40:25 +00001420 else {
Daniel Veillard417be3a2003-01-20 21:26:34 +00001421 pyCtxt = (xmlParserCtxtPyCtxtPtr)ctxt->_private;
Daniel Veillarde4a07e72003-01-14 14:40:25 +00001422 }
Daniel Veillarde6227e02003-01-14 11:42:39 +00001423 /* TODO: check f is a function ! */
Daniel Veillard417be3a2003-01-20 21:26:34 +00001424 Py_XDECREF(pyCtxt->f);
Daniel Veillarde6227e02003-01-14 11:42:39 +00001425 Py_XINCREF(pyobj_f);
Daniel Veillard417be3a2003-01-20 21:26:34 +00001426 pyCtxt->f = pyobj_f;
1427 Py_XDECREF(pyCtxt->arg);
Daniel Veillarde6227e02003-01-14 11:42:39 +00001428 Py_XINCREF(pyobj_arg);
Daniel Veillard417be3a2003-01-20 21:26:34 +00001429 pyCtxt->arg = pyobj_arg;
Daniel Veillarde6227e02003-01-14 11:42:39 +00001430
Daniel Veillard417be3a2003-01-20 21:26:34 +00001431 if (pyobj_f != Py_None) {
1432 ctxt->sax->error = libxml_xmlParserCtxtErrorFuncHandler;
1433 ctxt->sax->warning = libxml_xmlParserCtxtWarningFuncHandler;
1434 ctxt->vctxt.error = libxml_xmlParserCtxtValidityErrorFuncHandler;
1435 ctxt->vctxt.warning = libxml_xmlParserCtxtValidityWarningFuncHandler;
1436 }
1437 else {
1438 ctxt->sax->error = xmlParserError;
1439 ctxt->vctxt.error = xmlParserValidityError;
1440 ctxt->sax->warning = xmlParserWarning;
1441 ctxt->vctxt.warning = xmlParserValidityWarning;
1442 }
Daniel Veillarde6227e02003-01-14 11:42:39 +00001443
1444 py_retval = libxml_intWrap(1);
1445 return(py_retval);
1446}
1447
Daniel Veillardc2664642003-07-29 20:44:53 +00001448static PyObject *
Daniel Veillard417be3a2003-01-20 21:26:34 +00001449libxml_xmlParserCtxtGetErrorHandler(ATTRIBUTE_UNUSED PyObject *self, PyObject *args)
Daniel Veillarde6227e02003-01-14 11:42:39 +00001450{
1451 PyObject *py_retval;
1452 xmlParserCtxtPtr ctxt;
Daniel Veillarde4a07e72003-01-14 14:40:25 +00001453 xmlParserCtxtPyCtxtPtr pyCtxt;
Daniel Veillarde6227e02003-01-14 11:42:39 +00001454 PyObject *pyobj_ctxt;
Daniel Veillarde6227e02003-01-14 11:42:39 +00001455
Daniel Veillard417be3a2003-01-20 21:26:34 +00001456 if (!PyArg_ParseTuple(args, (char *)"O:xmlParserCtxtGetErrorHandler",
1457 &pyobj_ctxt))
Daniel Veillarde6227e02003-01-14 11:42:39 +00001458 return(NULL);
1459 ctxt = (xmlParserCtxtPtr) PyparserCtxt_Get(pyobj_ctxt);
Daniel Veillard417be3a2003-01-20 21:26:34 +00001460 py_retval = PyTuple_New(2);
1461 if (ctxt->_private != NULL) {
1462 pyCtxt = (xmlParserCtxtPyCtxtPtr)ctxt->_private;
1463
1464 PyTuple_SetItem(py_retval, 0, pyCtxt->f);
1465 Py_XINCREF(pyCtxt->f);
1466 PyTuple_SetItem(py_retval, 1, pyCtxt->arg);
1467 Py_XINCREF(pyCtxt->arg);
Daniel Veillarde4a07e72003-01-14 14:40:25 +00001468 }
1469 else {
Daniel Veillard417be3a2003-01-20 21:26:34 +00001470 /* no python error handler registered */
1471 PyTuple_SetItem(py_retval, 0, Py_None);
1472 Py_XINCREF(Py_None);
1473 PyTuple_SetItem(py_retval, 1, Py_None);
1474 Py_XINCREF(Py_None);
Daniel Veillarde4a07e72003-01-14 14:40:25 +00001475 }
Daniel Veillarde6227e02003-01-14 11:42:39 +00001476 return(py_retval);
1477}
1478
Daniel Veillardc2664642003-07-29 20:44:53 +00001479static PyObject *
Daniel Veillard417be3a2003-01-20 21:26:34 +00001480libxml_xmlFreeParserCtxt(ATTRIBUTE_UNUSED PyObject *self, PyObject *args) {
1481 xmlParserCtxtPtr ctxt;
1482 PyObject *pyobj_ctxt;
1483 xmlParserCtxtPyCtxtPtr pyCtxt;
1484
1485 if (!PyArg_ParseTuple(args, (char *)"O:xmlFreeParserCtxt", &pyobj_ctxt))
1486 return(NULL);
1487 ctxt = (xmlParserCtxtPtr) PyparserCtxt_Get(pyobj_ctxt);
1488
1489 if (ctxt != NULL) {
1490 pyCtxt = (xmlParserCtxtPyCtxtPtr)((xmlParserCtxtPtr)ctxt)->_private;
1491 if (pyCtxt) {
1492 Py_XDECREF(pyCtxt->f);
1493 Py_XDECREF(pyCtxt->arg);
1494 xmlFree(pyCtxt);
1495 }
1496 xmlFreeParserCtxt(ctxt);
1497 }
1498
1499 Py_INCREF(Py_None);
1500 return(Py_None);
1501}
1502
Daniel Veillarda7340c82002-02-01 17:56:45 +00001503/************************************************************************
1504 * *
Daniel Veillard26f70262003-01-16 22:45:08 +00001505 * Per xmlTextReader error handler *
1506 * *
1507 ************************************************************************/
1508
1509typedef struct
1510{
1511 PyObject *f;
1512 PyObject *arg;
1513} xmlTextReaderPyCtxt;
1514typedef xmlTextReaderPyCtxt *xmlTextReaderPyCtxtPtr;
1515
1516static void
1517libxml_xmlTextReaderErrorCallback(void *arg,
1518 const char *msg,
Daniel Veillard417be3a2003-01-20 21:26:34 +00001519 int severity,
1520 xmlTextReaderLocatorPtr locator)
Daniel Veillard26f70262003-01-16 22:45:08 +00001521{
1522 xmlTextReaderPyCtxt *pyCtxt = (xmlTextReaderPyCtxt *)arg;
1523 PyObject *list;
1524 PyObject *result;
1525
Daniel Veillard417be3a2003-01-20 21:26:34 +00001526 list = PyTuple_New(4);
Daniel Veillard26f70262003-01-16 22:45:08 +00001527 PyTuple_SetItem(list, 0, pyCtxt->arg);
1528 Py_XINCREF(pyCtxt->arg);
1529 PyTuple_SetItem(list, 1, libxml_charPtrConstWrap(msg));
Daniel Veillard417be3a2003-01-20 21:26:34 +00001530 PyTuple_SetItem(list, 2, libxml_intWrap(severity));
1531 PyTuple_SetItem(list, 3, libxml_xmlTextReaderLocatorPtrWrap(locator));
Daniel Veillard26f70262003-01-16 22:45:08 +00001532 result = PyEval_CallObject(pyCtxt->f, list);
1533 if (result == NULL)
1534 {
Daniel Veillard417be3a2003-01-20 21:26:34 +00001535 /* TODO: manage for the exception to be propagated... */
Daniel Veillard26f70262003-01-16 22:45:08 +00001536 PyErr_Print();
1537 }
1538 Py_XDECREF(list);
1539 Py_XDECREF(result);
1540}
1541
Daniel Veillardc2664642003-07-29 20:44:53 +00001542static PyObject *
Daniel Veillard26f70262003-01-16 22:45:08 +00001543libxml_xmlTextReaderSetErrorHandler(ATTRIBUTE_UNUSED PyObject *self, PyObject *args)
1544{
1545 xmlTextReaderPtr reader;
1546 xmlTextReaderPyCtxtPtr pyCtxt;
1547 xmlTextReaderErrorFunc f;
1548 void *arg;
1549 PyObject *pyobj_reader;
1550 PyObject *pyobj_f;
1551 PyObject *pyobj_arg;
1552 PyObject *py_retval;
1553
1554 if (!PyArg_ParseTuple(args, (char *)"OOO:xmlTextReaderSetErrorHandler", &pyobj_reader, &pyobj_f, &pyobj_arg))
1555 return(NULL);
1556 reader = (xmlTextReaderPtr) PyxmlTextReader_Get(pyobj_reader);
1557 /* clear previous error handler */
1558 xmlTextReaderGetErrorHandler(reader,&f,&arg);
1559 if (arg != NULL) {
Daniel Veillardc2664642003-07-29 20:44:53 +00001560 if (f == (xmlTextReaderErrorFunc) libxml_xmlTextReaderErrorCallback) {
Daniel Veillard26f70262003-01-16 22:45:08 +00001561 /* ok, it's our error handler! */
1562 pyCtxt = (xmlTextReaderPyCtxtPtr)arg;
1563 Py_XDECREF(pyCtxt->f);
1564 Py_XDECREF(pyCtxt->arg);
1565 xmlFree(pyCtxt);
1566 }
1567 else {
1568 /*
1569 * there already an arg, and it's not ours,
1570 * there is definitely something wrong going on here...
1571 * we don't know how to free it, so we bail out...
1572 */
1573 py_retval = libxml_intWrap(-1);
1574 return(py_retval);
1575 }
1576 }
1577 xmlTextReaderSetErrorHandler(reader,NULL,NULL);
1578 /* set new error handler */
1579 if (pyobj_f != Py_None)
1580 {
1581 pyCtxt = (xmlTextReaderPyCtxtPtr)xmlMalloc(sizeof(xmlTextReaderPyCtxt));
1582 if (pyCtxt == NULL) {
1583 py_retval = libxml_intWrap(-1);
1584 return(py_retval);
1585 }
1586 Py_XINCREF(pyobj_f);
1587 pyCtxt->f = pyobj_f;
1588 Py_XINCREF(pyobj_arg);
1589 pyCtxt->arg = pyobj_arg;
Daniel Veillardc2664642003-07-29 20:44:53 +00001590 xmlTextReaderSetErrorHandler(reader,
1591 (xmlTextReaderErrorFunc) libxml_xmlTextReaderErrorCallback,
1592 pyCtxt);
Daniel Veillard26f70262003-01-16 22:45:08 +00001593 }
1594
1595 py_retval = libxml_intWrap(1);
1596 return(py_retval);
1597}
1598
Daniel Veillardc2664642003-07-29 20:44:53 +00001599static PyObject *
Daniel Veillard26f70262003-01-16 22:45:08 +00001600libxml_xmlTextReaderGetErrorHandler(ATTRIBUTE_UNUSED PyObject *self, PyObject *args)
1601{
1602 xmlTextReaderPtr reader;
1603 xmlTextReaderPyCtxtPtr pyCtxt;
1604 xmlTextReaderErrorFunc f;
1605 void *arg;
1606 PyObject *pyobj_reader;
1607 PyObject *py_retval;
1608
1609 if (!PyArg_ParseTuple(args, (char *)"O:xmlTextReaderSetErrorHandler", &pyobj_reader))
1610 return(NULL);
1611 reader = (xmlTextReaderPtr) PyxmlTextReader_Get(pyobj_reader);
1612 xmlTextReaderGetErrorHandler(reader,&f,&arg);
1613 py_retval = PyTuple_New(2);
Daniel Veillardc2664642003-07-29 20:44:53 +00001614 if (f == (xmlTextReaderErrorFunc)libxml_xmlTextReaderErrorCallback) {
Daniel Veillard26f70262003-01-16 22:45:08 +00001615 /* ok, it's our error handler! */
1616 pyCtxt = (xmlTextReaderPyCtxtPtr)arg;
1617 PyTuple_SetItem(py_retval, 0, pyCtxt->f);
1618 Py_XINCREF(pyCtxt->f);
1619 PyTuple_SetItem(py_retval, 1, pyCtxt->arg);
1620 Py_XINCREF(pyCtxt->arg);
1621 }
1622 else
1623 {
1624 /* f is null or it's not our error handler */
1625 PyTuple_SetItem(py_retval, 0, Py_None);
1626 Py_XINCREF(Py_None);
1627 PyTuple_SetItem(py_retval, 1, Py_None);
1628 Py_XINCREF(Py_None);
1629 }
1630 return(py_retval);
1631}
1632
Daniel Veillardc2664642003-07-29 20:44:53 +00001633static PyObject *
Daniel Veillard26f70262003-01-16 22:45:08 +00001634libxml_xmlFreeTextReader(ATTRIBUTE_UNUSED PyObject *self, PyObject *args) {
1635 xmlTextReaderPtr reader;
1636 PyObject *pyobj_reader;
1637 xmlTextReaderPyCtxtPtr pyCtxt;
1638 xmlTextReaderErrorFunc f;
1639 void *arg;
1640
1641 if (!PyArg_ParseTuple(args, (char *)"O:xmlFreeTextReader", &pyobj_reader))
1642 return(NULL);
1643 reader = (xmlTextReaderPtr) PyxmlTextReader_Get(pyobj_reader);
1644
1645 xmlTextReaderGetErrorHandler(reader,&f,&arg);
1646 if (arg != NULL) {
Daniel Veillardc2664642003-07-29 20:44:53 +00001647 if (f == (xmlTextReaderErrorFunc) libxml_xmlTextReaderErrorCallback) {
Daniel Veillard26f70262003-01-16 22:45:08 +00001648 /* ok, it's our error handler! */
1649 pyCtxt = (xmlTextReaderPyCtxtPtr)arg;
1650 Py_XDECREF(pyCtxt->f);
1651 Py_XDECREF(pyCtxt->arg);
1652 xmlFree(pyCtxt);
1653 }
1654 /*
1655 * else, something wrong happened, because the error handler is
1656 * not owned by the python bindings...
1657 */
1658 }
1659
1660 xmlFreeTextReader(reader);
1661 Py_INCREF(Py_None);
1662 return(Py_None);
1663}
1664
1665/************************************************************************
1666 * *
Daniel Veillarda7340c82002-02-01 17:56:45 +00001667 * XPath extensions *
1668 * *
1669 ************************************************************************/
1670
1671static int libxml_xpathCallbacksInitialized = 0;
1672
1673typedef struct libxml_xpathCallback {
1674 xmlXPathContextPtr ctx;
1675 xmlChar *name;
1676 xmlChar *ns_uri;
1677 PyObject *function;
1678} libxml_xpathCallback, *libxml_xpathCallbackPtr;
1679static libxml_xpathCallback libxml_xpathCallbacks[10];
1680static int libxml_xpathCallbacksNb = 0;
1681static int libxml_xpathCallbacksMax = 10;
1682
Daniel Veillarda7340c82002-02-01 17:56:45 +00001683static void
Daniel Veillardd2379012002-03-15 22:24:56 +00001684libxml_xmlXPathFuncCallback(xmlXPathParserContextPtr ctxt, int nargs)
1685{
Daniel Veillarda7340c82002-02-01 17:56:45 +00001686 PyObject *list, *cur, *result;
1687 xmlXPathObjectPtr obj;
Daniel Veillard70cab352002-02-06 16:06:58 +00001688 xmlXPathContextPtr rctxt;
1689 PyObject *current_function = NULL;
1690 const xmlChar *name;
1691 const xmlChar *ns_uri;
Daniel Veillarda7340c82002-02-01 17:56:45 +00001692 int i;
1693
Daniel Veillard70cab352002-02-06 16:06:58 +00001694 if (ctxt == NULL)
Daniel Veillardd2379012002-03-15 22:24:56 +00001695 return;
Daniel Veillard70cab352002-02-06 16:06:58 +00001696 rctxt = ctxt->context;
1697 if (rctxt == NULL)
Daniel Veillardd2379012002-03-15 22:24:56 +00001698 return;
Daniel Veillard70cab352002-02-06 16:06:58 +00001699 name = rctxt->function;
1700 ns_uri = rctxt->functionURI;
Daniel Veillarda7340c82002-02-01 17:56:45 +00001701#ifdef DEBUG_XPATH
Daniel Veillardd2379012002-03-15 22:24:56 +00001702 printf("libxml_xmlXPathFuncCallback called name %s URI %s\n", name,
1703 ns_uri);
Daniel Veillarda7340c82002-02-01 17:56:45 +00001704#endif
1705
Daniel Veillard70cab352002-02-06 16:06:58 +00001706 /*
1707 * Find the function, it should be there it was there at lookup
1708 */
Daniel Veillardd2379012002-03-15 22:24:56 +00001709 for (i = 0; i < libxml_xpathCallbacksNb; i++) {
1710 if ( /* TODO (ctxt == libxml_xpathCallbacks[i].ctx) && */
1711 (xmlStrEqual(name, libxml_xpathCallbacks[i].name)) &&
1712 (xmlStrEqual(ns_uri, libxml_xpathCallbacks[i].ns_uri))) {
1713 current_function = libxml_xpathCallbacks[i].function;
1714 }
Daniel Veillard70cab352002-02-06 16:06:58 +00001715 }
1716 if (current_function == NULL) {
Daniel Veillardd2379012002-03-15 22:24:56 +00001717 printf
1718 ("libxml_xmlXPathFuncCallback: internal error %s not found !\n",
1719 name);
1720 return;
Daniel Veillard70cab352002-02-06 16:06:58 +00001721 }
1722
Daniel Veillardc575b992002-02-08 13:28:40 +00001723 list = PyTuple_New(nargs + 1);
1724 PyTuple_SetItem(list, 0, libxml_xmlXPathParserContextPtrWrap(ctxt));
Daniel Veillardd2379012002-03-15 22:24:56 +00001725 for (i = 0; i < nargs; i++) {
1726 obj = valuePop(ctxt);
1727 cur = libxml_xmlXPathObjectPtrWrap(obj);
1728 PyTuple_SetItem(list, i + 1, cur);
Daniel Veillarda7340c82002-02-01 17:56:45 +00001729 }
1730 result = PyEval_CallObject(current_function, list);
1731 Py_DECREF(list);
1732
1733 obj = libxml_xmlXPathObjectPtrConvert(result);
1734 valuePush(ctxt, obj);
1735}
1736
1737static xmlXPathFunction
Daniel Veillardd2379012002-03-15 22:24:56 +00001738libxml_xmlXPathFuncLookupFunc(void *ctxt, const xmlChar * name,
1739 const xmlChar * ns_uri)
1740{
Daniel Veillarda7340c82002-02-01 17:56:45 +00001741 int i;
Daniel Veillardd2379012002-03-15 22:24:56 +00001742
Daniel Veillarda7340c82002-02-01 17:56:45 +00001743#ifdef DEBUG_XPATH
1744 printf("libxml_xmlXPathFuncLookupFunc(%p, %s, %s) called\n",
Daniel Veillardd2379012002-03-15 22:24:56 +00001745 ctxt, name, ns_uri);
Daniel Veillarda7340c82002-02-01 17:56:45 +00001746#endif
Daniel Veillard70cab352002-02-06 16:06:58 +00001747 /*
1748 * This is called once only. The address is then stored in the
1749 * XPath expression evaluation, the proper object to call can
1750 * then still be found using the execution context function
1751 * and functionURI fields.
1752 */
Daniel Veillardd2379012002-03-15 22:24:56 +00001753 for (i = 0; i < libxml_xpathCallbacksNb; i++) {
1754 if ((ctxt == libxml_xpathCallbacks[i].ctx) &&
1755 (xmlStrEqual(name, libxml_xpathCallbacks[i].name)) &&
1756 (xmlStrEqual(ns_uri, libxml_xpathCallbacks[i].ns_uri))) {
1757 return (libxml_xmlXPathFuncCallback);
1758 }
Daniel Veillarda7340c82002-02-01 17:56:45 +00001759 }
Daniel Veillardd2379012002-03-15 22:24:56 +00001760 return (NULL);
Daniel Veillarda7340c82002-02-01 17:56:45 +00001761}
1762
1763static void
Daniel Veillardd2379012002-03-15 22:24:56 +00001764libxml_xpathCallbacksInitialize(void)
1765{
Daniel Veillarda7340c82002-02-01 17:56:45 +00001766 int i;
1767
1768 if (libxml_xpathCallbacksInitialized != 0)
Daniel Veillardd2379012002-03-15 22:24:56 +00001769 return;
Daniel Veillarda7340c82002-02-01 17:56:45 +00001770
1771#ifdef DEBUG_XPATH
1772 printf("libxml_xpathCallbacksInitialized called\n");
1773#endif
1774
Daniel Veillard781ac8b2003-05-15 22:11:36 +00001775 for (i = 0; i < libxml_xpathCallbacksMax; i++) {
Daniel Veillardd2379012002-03-15 22:24:56 +00001776 libxml_xpathCallbacks[i].ctx = NULL;
1777 libxml_xpathCallbacks[i].name = NULL;
1778 libxml_xpathCallbacks[i].ns_uri = NULL;
1779 libxml_xpathCallbacks[i].function = NULL;
Daniel Veillarda7340c82002-02-01 17:56:45 +00001780 }
Daniel Veillarda7340c82002-02-01 17:56:45 +00001781 libxml_xpathCallbacksInitialized = 1;
1782}
1783
1784PyObject *
Daniel Veillardd2379012002-03-15 22:24:56 +00001785libxml_xmlRegisterXPathFunction(ATTRIBUTE_UNUSED PyObject * self,
1786 PyObject * args)
1787{
Daniel Veillarda7340c82002-02-01 17:56:45 +00001788 PyObject *py_retval;
1789 int c_retval = 0;
1790 xmlChar *name;
1791 xmlChar *ns_uri;
1792 xmlXPathContextPtr ctx;
1793 PyObject *pyobj_ctx;
1794 PyObject *pyobj_f;
1795 int i;
1796
Daniel Veillardd2379012002-03-15 22:24:56 +00001797 if (!PyArg_ParseTuple
1798 (args, (char *) "OszO:registerXPathFunction", &pyobj_ctx, &name,
1799 &ns_uri, &pyobj_f))
1800 return (NULL);
Daniel Veillarda7340c82002-02-01 17:56:45 +00001801
1802 ctx = (xmlXPathContextPtr) PyxmlXPathContext_Get(pyobj_ctx);
1803 if (libxml_xpathCallbacksInitialized == 0)
Daniel Veillardd2379012002-03-15 22:24:56 +00001804 libxml_xpathCallbacksInitialize();
Daniel Veillarda7340c82002-02-01 17:56:45 +00001805 xmlXPathRegisterFuncLookup(ctx, libxml_xmlXPathFuncLookupFunc, ctx);
1806
1807 if ((pyobj_ctx == NULL) || (name == NULL) || (pyobj_f == NULL)) {
Daniel Veillardd2379012002-03-15 22:24:56 +00001808 py_retval = libxml_intWrap(-1);
1809 return (py_retval);
Daniel Veillarda7340c82002-02-01 17:56:45 +00001810 }
Daniel Veillarda7340c82002-02-01 17:56:45 +00001811#ifdef DEBUG_XPATH
1812 printf("libxml_registerXPathFunction(%p, %s, %s) called\n",
Daniel Veillardd2379012002-03-15 22:24:56 +00001813 ctx, name, ns_uri);
Daniel Veillarda7340c82002-02-01 17:56:45 +00001814#endif
Daniel Veillardd2379012002-03-15 22:24:56 +00001815 for (i = 0; i < libxml_xpathCallbacksNb; i++) {
1816 if ((ctx == libxml_xpathCallbacks[i].ctx) &&
1817 (xmlStrEqual(name, libxml_xpathCallbacks[i].name)) &&
1818 (xmlStrEqual(ns_uri, libxml_xpathCallbacks[i].ns_uri))) {
1819 Py_XINCREF(pyobj_f);
1820 Py_XDECREF(libxml_xpathCallbacks[i].function);
1821 libxml_xpathCallbacks[i].function = pyobj_f;
1822 c_retval = 1;
1823 goto done;
1824 }
Daniel Veillarda7340c82002-02-01 17:56:45 +00001825 }
1826 if (libxml_xpathCallbacksNb >= libxml_xpathCallbacksMax) {
Daniel Veillardd2379012002-03-15 22:24:56 +00001827 printf("libxml_registerXPathFunction() table full\n");
Daniel Veillarda7340c82002-02-01 17:56:45 +00001828 } else {
Daniel Veillardd2379012002-03-15 22:24:56 +00001829 i = libxml_xpathCallbacksNb++;
1830 Py_XINCREF(pyobj_f);
Daniel Veillarda7340c82002-02-01 17:56:45 +00001831 libxml_xpathCallbacks[i].ctx = ctx;
1832 libxml_xpathCallbacks[i].name = xmlStrdup(name);
1833 libxml_xpathCallbacks[i].ns_uri = xmlStrdup(ns_uri);
Daniel Veillardd2379012002-03-15 22:24:56 +00001834 libxml_xpathCallbacks[i].function = pyobj_f;
1835 c_retval = 1;
Daniel Veillarda7340c82002-02-01 17:56:45 +00001836 }
Daniel Veillardd2379012002-03-15 22:24:56 +00001837 done:
Daniel Veillarda7340c82002-02-01 17:56:45 +00001838 py_retval = libxml_intWrap((int) c_retval);
Daniel Veillardd2379012002-03-15 22:24:56 +00001839 return (py_retval);
Daniel Veillarda7340c82002-02-01 17:56:45 +00001840}
1841
Daniel Veillard1971ee22002-01-31 20:29:19 +00001842/************************************************************************
1843 * *
Daniel Veillardd2897fd2002-01-30 16:37:32 +00001844 * Global properties access *
1845 * *
1846 ************************************************************************/
1847static PyObject *
Daniel Veillardd2379012002-03-15 22:24:56 +00001848libxml_name(ATTRIBUTE_UNUSED PyObject * self, PyObject * args)
Daniel Veillardd2897fd2002-01-30 16:37:32 +00001849{
1850 PyObject *resultobj, *obj;
1851 xmlNodePtr cur;
1852 const xmlChar *res;
1853
Daniel Veillardd2379012002-03-15 22:24:56 +00001854 if (!PyArg_ParseTuple(args, (char *) "O:name", &obj))
Daniel Veillardd2897fd2002-01-30 16:37:32 +00001855 return NULL;
1856 cur = PyxmlNode_Get(obj);
1857
1858#ifdef DEBUG
1859 printf("libxml_name: cur = %p type %d\n", cur, cur->type);
1860#endif
1861
Daniel Veillardd2379012002-03-15 22:24:56 +00001862 switch (cur->type) {
1863 case XML_DOCUMENT_NODE:
Daniel Veillardd2897fd2002-01-30 16:37:32 +00001864#ifdef LIBXML_DOCB_ENABLED
Daniel Veillardd2379012002-03-15 22:24:56 +00001865 case XML_DOCB_DOCUMENT_NODE:
Daniel Veillardd2897fd2002-01-30 16:37:32 +00001866#endif
Daniel Veillardd2379012002-03-15 22:24:56 +00001867 case XML_HTML_DOCUMENT_NODE:{
1868 xmlDocPtr doc = (xmlDocPtr) cur;
1869
1870 res = doc->URL;
1871 break;
1872 }
1873 case XML_ATTRIBUTE_NODE:{
1874 xmlAttrPtr attr = (xmlAttrPtr) cur;
1875
1876 res = attr->name;
1877 break;
1878 }
1879 case XML_NAMESPACE_DECL:{
1880 xmlNsPtr ns = (xmlNsPtr) cur;
1881
1882 res = ns->prefix;
1883 break;
1884 }
1885 default:
1886 res = cur->name;
1887 break;
Daniel Veillardd2897fd2002-01-30 16:37:32 +00001888 }
Daniel Veillard1971ee22002-01-31 20:29:19 +00001889 resultobj = libxml_constxmlCharPtrWrap(res);
Daniel Veillardd2897fd2002-01-30 16:37:32 +00001890
1891 return resultobj;
1892}
1893
1894static PyObject *
Daniel Veillardd2379012002-03-15 22:24:56 +00001895libxml_doc(ATTRIBUTE_UNUSED PyObject * self, PyObject * args)
Daniel Veillardd2897fd2002-01-30 16:37:32 +00001896{
1897 PyObject *resultobj, *obj;
1898 xmlNodePtr cur;
1899 xmlDocPtr res;
1900
Daniel Veillardd2379012002-03-15 22:24:56 +00001901 if (!PyArg_ParseTuple(args, (char *) "O:doc", &obj))
Daniel Veillardd2897fd2002-01-30 16:37:32 +00001902 return NULL;
1903 cur = PyxmlNode_Get(obj);
1904
1905#ifdef DEBUG
1906 printf("libxml_doc: cur = %p\n", cur);
1907#endif
1908
Daniel Veillardd2379012002-03-15 22:24:56 +00001909 switch (cur->type) {
1910 case XML_DOCUMENT_NODE:
Daniel Veillardd2897fd2002-01-30 16:37:32 +00001911#ifdef LIBXML_DOCB_ENABLED
Daniel Veillardd2379012002-03-15 22:24:56 +00001912 case XML_DOCB_DOCUMENT_NODE:
Daniel Veillardd2897fd2002-01-30 16:37:32 +00001913#endif
Daniel Veillardd2379012002-03-15 22:24:56 +00001914 case XML_HTML_DOCUMENT_NODE:
1915 res = NULL;
1916 break;
1917 case XML_ATTRIBUTE_NODE:{
1918 xmlAttrPtr attr = (xmlAttrPtr) cur;
1919
1920 res = attr->doc;
1921 break;
1922 }
1923 case XML_NAMESPACE_DECL:
1924 res = NULL;
1925 break;
1926 default:
1927 res = cur->doc;
1928 break;
Daniel Veillardd2897fd2002-01-30 16:37:32 +00001929 }
1930 resultobj = libxml_xmlDocPtrWrap(res);
1931 return resultobj;
1932}
1933
1934static PyObject *
Daniel Veillardd2379012002-03-15 22:24:56 +00001935libxml_properties(ATTRIBUTE_UNUSED PyObject * self, PyObject * args)
Daniel Veillardd2897fd2002-01-30 16:37:32 +00001936{
1937 PyObject *resultobj, *obj;
1938 xmlNodePtr cur = NULL;
1939 xmlAttrPtr res;
1940
Daniel Veillardd2379012002-03-15 22:24:56 +00001941 if (!PyArg_ParseTuple(args, (char *) "O:properties", &obj))
Daniel Veillardd2897fd2002-01-30 16:37:32 +00001942 return NULL;
1943 cur = PyxmlNode_Get(obj);
1944 if (cur->type == XML_ELEMENT_NODE)
Daniel Veillardd2379012002-03-15 22:24:56 +00001945 res = cur->properties;
Daniel Veillardd2897fd2002-01-30 16:37:32 +00001946 else
Daniel Veillardd2379012002-03-15 22:24:56 +00001947 res = NULL;
Daniel Veillardd2897fd2002-01-30 16:37:32 +00001948 resultobj = libxml_xmlAttrPtrWrap(res);
1949 return resultobj;
1950}
1951
1952static PyObject *
Daniel Veillardd2379012002-03-15 22:24:56 +00001953libxml_next(ATTRIBUTE_UNUSED PyObject * self, PyObject * args)
Daniel Veillardd2897fd2002-01-30 16:37:32 +00001954{
1955 PyObject *resultobj, *obj;
1956 xmlNodePtr cur;
1957 xmlNodePtr res;
1958
Daniel Veillardd2379012002-03-15 22:24:56 +00001959 if (!PyArg_ParseTuple(args, (char *) "O:next", &obj))
Daniel Veillardd2897fd2002-01-30 16:37:32 +00001960 return NULL;
1961 cur = PyxmlNode_Get(obj);
1962
1963#ifdef DEBUG
1964 printf("libxml_next: cur = %p\n", cur);
1965#endif
1966
Daniel Veillardd2379012002-03-15 22:24:56 +00001967 switch (cur->type) {
1968 case XML_DOCUMENT_NODE:
Daniel Veillardd2897fd2002-01-30 16:37:32 +00001969#ifdef LIBXML_DOCB_ENABLED
Daniel Veillardd2379012002-03-15 22:24:56 +00001970 case XML_DOCB_DOCUMENT_NODE:
Daniel Veillardd2897fd2002-01-30 16:37:32 +00001971#endif
Daniel Veillardd2379012002-03-15 22:24:56 +00001972 case XML_HTML_DOCUMENT_NODE:
1973 res = NULL;
1974 break;
1975 case XML_ATTRIBUTE_NODE:{
1976 xmlAttrPtr attr = (xmlAttrPtr) cur;
1977
1978 res = (xmlNodePtr) attr->next;
1979 break;
1980 }
1981 case XML_NAMESPACE_DECL:{
1982 xmlNsPtr ns = (xmlNsPtr) cur;
1983
1984 res = (xmlNodePtr) ns->next;
1985 break;
1986 }
1987 default:
1988 res = cur->next;
1989 break;
Daniel Veillardd2897fd2002-01-30 16:37:32 +00001990
1991 }
1992 resultobj = libxml_xmlNodePtrWrap(res);
1993 return resultobj;
1994}
1995
1996static PyObject *
Daniel Veillardd2379012002-03-15 22:24:56 +00001997libxml_prev(ATTRIBUTE_UNUSED PyObject * self, PyObject * args)
Daniel Veillardd2897fd2002-01-30 16:37:32 +00001998{
1999 PyObject *resultobj, *obj;
2000 xmlNodePtr cur;
2001 xmlNodePtr res;
2002
Daniel Veillardd2379012002-03-15 22:24:56 +00002003 if (!PyArg_ParseTuple(args, (char *) "O:prev", &obj))
Daniel Veillardd2897fd2002-01-30 16:37:32 +00002004 return NULL;
2005 cur = PyxmlNode_Get(obj);
2006
2007#ifdef DEBUG
2008 printf("libxml_prev: cur = %p\n", cur);
2009#endif
2010
Daniel Veillardd2379012002-03-15 22:24:56 +00002011 switch (cur->type) {
2012 case XML_DOCUMENT_NODE:
Daniel Veillardd2897fd2002-01-30 16:37:32 +00002013#ifdef LIBXML_DOCB_ENABLED
Daniel Veillardd2379012002-03-15 22:24:56 +00002014 case XML_DOCB_DOCUMENT_NODE:
Daniel Veillardd2897fd2002-01-30 16:37:32 +00002015#endif
Daniel Veillardd2379012002-03-15 22:24:56 +00002016 case XML_HTML_DOCUMENT_NODE:
2017 res = NULL;
2018 break;
2019 case XML_ATTRIBUTE_NODE:{
2020 xmlAttrPtr attr = (xmlAttrPtr) cur;
2021
Daniel Veillardfaa35ff2002-11-24 13:53:43 +00002022 res = (xmlNodePtr) attr->prev;
Daniel Veillardd2379012002-03-15 22:24:56 +00002023 }
2024 case XML_NAMESPACE_DECL:
2025 res = NULL;
2026 break;
2027 default:
Daniel Veillardfaa35ff2002-11-24 13:53:43 +00002028 res = cur->prev;
Daniel Veillardd2379012002-03-15 22:24:56 +00002029 break;
Daniel Veillardd2897fd2002-01-30 16:37:32 +00002030 }
2031 resultobj = libxml_xmlNodePtrWrap(res);
2032 return resultobj;
2033}
2034
2035static PyObject *
Daniel Veillardd2379012002-03-15 22:24:56 +00002036libxml_children(ATTRIBUTE_UNUSED PyObject * self, PyObject * args)
Daniel Veillardd2897fd2002-01-30 16:37:32 +00002037{
2038 PyObject *resultobj, *obj;
2039 xmlNodePtr cur;
2040 xmlNodePtr res;
2041
Daniel Veillardd2379012002-03-15 22:24:56 +00002042 if (!PyArg_ParseTuple(args, (char *) "O:children", &obj))
Daniel Veillardd2897fd2002-01-30 16:37:32 +00002043 return NULL;
2044 cur = PyxmlNode_Get(obj);
2045
2046#ifdef DEBUG
2047 printf("libxml_children: cur = %p\n", cur);
2048#endif
2049
Daniel Veillardd2379012002-03-15 22:24:56 +00002050 switch (cur->type) {
2051 case XML_ELEMENT_NODE:
2052 case XML_ENTITY_REF_NODE:
2053 case XML_ENTITY_NODE:
2054 case XML_PI_NODE:
2055 case XML_COMMENT_NODE:
2056 case XML_DOCUMENT_NODE:
Daniel Veillardd2897fd2002-01-30 16:37:32 +00002057#ifdef LIBXML_DOCB_ENABLED
Daniel Veillardd2379012002-03-15 22:24:56 +00002058 case XML_DOCB_DOCUMENT_NODE:
Daniel Veillardd2897fd2002-01-30 16:37:32 +00002059#endif
Daniel Veillardd2379012002-03-15 22:24:56 +00002060 case XML_HTML_DOCUMENT_NODE:
2061 case XML_DTD_NODE:
2062 res = cur->children;
2063 break;
2064 case XML_ATTRIBUTE_NODE:{
2065 xmlAttrPtr attr = (xmlAttrPtr) cur;
2066
2067 res = attr->children;
2068 break;
2069 }
2070 default:
2071 res = NULL;
2072 break;
Daniel Veillardd2897fd2002-01-30 16:37:32 +00002073 }
2074 resultobj = libxml_xmlNodePtrWrap(res);
2075 return resultobj;
2076}
2077
2078static PyObject *
Daniel Veillardd2379012002-03-15 22:24:56 +00002079libxml_last(ATTRIBUTE_UNUSED PyObject * self, PyObject * args)
Daniel Veillardd2897fd2002-01-30 16:37:32 +00002080{
2081 PyObject *resultobj, *obj;
2082 xmlNodePtr cur;
2083 xmlNodePtr res;
2084
Daniel Veillardd2379012002-03-15 22:24:56 +00002085 if (!PyArg_ParseTuple(args, (char *) "O:last", &obj))
Daniel Veillardd2897fd2002-01-30 16:37:32 +00002086 return NULL;
2087 cur = PyxmlNode_Get(obj);
2088
2089#ifdef DEBUG
2090 printf("libxml_last: cur = %p\n", cur);
2091#endif
2092
Daniel Veillardd2379012002-03-15 22:24:56 +00002093 switch (cur->type) {
2094 case XML_ELEMENT_NODE:
2095 case XML_ENTITY_REF_NODE:
2096 case XML_ENTITY_NODE:
2097 case XML_PI_NODE:
2098 case XML_COMMENT_NODE:
2099 case XML_DOCUMENT_NODE:
Daniel Veillardd2897fd2002-01-30 16:37:32 +00002100#ifdef LIBXML_DOCB_ENABLED
Daniel Veillardd2379012002-03-15 22:24:56 +00002101 case XML_DOCB_DOCUMENT_NODE:
Daniel Veillardd2897fd2002-01-30 16:37:32 +00002102#endif
Daniel Veillardd2379012002-03-15 22:24:56 +00002103 case XML_HTML_DOCUMENT_NODE:
2104 case XML_DTD_NODE:
2105 res = cur->last;
2106 break;
2107 case XML_ATTRIBUTE_NODE:{
2108 xmlAttrPtr attr = (xmlAttrPtr) cur;
2109
2110 res = attr->last;
2111 }
2112 default:
2113 res = NULL;
2114 break;
Daniel Veillardd2897fd2002-01-30 16:37:32 +00002115 }
2116 resultobj = libxml_xmlNodePtrWrap(res);
2117 return resultobj;
2118}
2119
2120static PyObject *
Daniel Veillardd2379012002-03-15 22:24:56 +00002121libxml_parent(ATTRIBUTE_UNUSED PyObject * self, PyObject * args)
Daniel Veillardd2897fd2002-01-30 16:37:32 +00002122{
2123 PyObject *resultobj, *obj;
2124 xmlNodePtr cur;
2125 xmlNodePtr res;
2126
Daniel Veillardd2379012002-03-15 22:24:56 +00002127 if (!PyArg_ParseTuple(args, (char *) "O:parent", &obj))
Daniel Veillardd2897fd2002-01-30 16:37:32 +00002128 return NULL;
2129 cur = PyxmlNode_Get(obj);
2130
2131#ifdef DEBUG
2132 printf("libxml_parent: cur = %p\n", cur);
2133#endif
2134
Daniel Veillardd2379012002-03-15 22:24:56 +00002135 switch (cur->type) {
2136 case XML_DOCUMENT_NODE:
2137 case XML_HTML_DOCUMENT_NODE:
Daniel Veillardd2897fd2002-01-30 16:37:32 +00002138#ifdef LIBXML_DOCB_ENABLED
Daniel Veillardd2379012002-03-15 22:24:56 +00002139 case XML_DOCB_DOCUMENT_NODE:
Daniel Veillardd2897fd2002-01-30 16:37:32 +00002140#endif
Daniel Veillardd2379012002-03-15 22:24:56 +00002141 res = NULL;
2142 break;
2143 case XML_ATTRIBUTE_NODE:{
2144 xmlAttrPtr attr = (xmlAttrPtr) cur;
2145
2146 res = attr->parent;
2147 }
2148 case XML_ENTITY_DECL:
2149 case XML_NAMESPACE_DECL:
2150 case XML_XINCLUDE_START:
2151 case XML_XINCLUDE_END:
2152 res = NULL;
2153 break;
2154 default:
2155 res = cur->parent;
2156 break;
Daniel Veillardd2897fd2002-01-30 16:37:32 +00002157 }
2158 resultobj = libxml_xmlNodePtrWrap(res);
2159 return resultobj;
2160}
2161
2162static PyObject *
Daniel Veillardd2379012002-03-15 22:24:56 +00002163libxml_type(ATTRIBUTE_UNUSED PyObject * self, PyObject * args)
Daniel Veillardd2897fd2002-01-30 16:37:32 +00002164{
2165 PyObject *resultobj, *obj;
2166 xmlNodePtr cur;
Daniel Veillardd2379012002-03-15 22:24:56 +00002167 const xmlChar *res = NULL;
Daniel Veillardd2897fd2002-01-30 16:37:32 +00002168
Daniel Veillardd2379012002-03-15 22:24:56 +00002169 if (!PyArg_ParseTuple(args, (char *) "O:last", &obj))
Daniel Veillardd2897fd2002-01-30 16:37:32 +00002170 return NULL;
2171 cur = PyxmlNode_Get(obj);
2172
2173#ifdef DEBUG
2174 printf("libxml_type: cur = %p\n", cur);
2175#endif
2176
Daniel Veillardd2379012002-03-15 22:24:56 +00002177 switch (cur->type) {
Daniel Veillardd2897fd2002-01-30 16:37:32 +00002178 case XML_ELEMENT_NODE:
Daniel Veillardd2379012002-03-15 22:24:56 +00002179 res = (const xmlChar *) "element";
2180 break;
Daniel Veillardd2897fd2002-01-30 16:37:32 +00002181 case XML_ATTRIBUTE_NODE:
Daniel Veillardd2379012002-03-15 22:24:56 +00002182 res = (const xmlChar *) "attribute";
2183 break;
Daniel Veillardd2897fd2002-01-30 16:37:32 +00002184 case XML_TEXT_NODE:
Daniel Veillardd2379012002-03-15 22:24:56 +00002185 res = (const xmlChar *) "text";
2186 break;
Daniel Veillardd2897fd2002-01-30 16:37:32 +00002187 case XML_CDATA_SECTION_NODE:
Daniel Veillardd2379012002-03-15 22:24:56 +00002188 res = (const xmlChar *) "cdata";
2189 break;
Daniel Veillardd2897fd2002-01-30 16:37:32 +00002190 case XML_ENTITY_REF_NODE:
Daniel Veillardd2379012002-03-15 22:24:56 +00002191 res = (const xmlChar *) "entity_ref";
2192 break;
Daniel Veillardd2897fd2002-01-30 16:37:32 +00002193 case XML_ENTITY_NODE:
Daniel Veillardd2379012002-03-15 22:24:56 +00002194 res = (const xmlChar *) "entity";
2195 break;
Daniel Veillardd2897fd2002-01-30 16:37:32 +00002196 case XML_PI_NODE:
Daniel Veillardd2379012002-03-15 22:24:56 +00002197 res = (const xmlChar *) "pi";
2198 break;
Daniel Veillardd2897fd2002-01-30 16:37:32 +00002199 case XML_COMMENT_NODE:
Daniel Veillardd2379012002-03-15 22:24:56 +00002200 res = (const xmlChar *) "comment";
2201 break;
Daniel Veillardd2897fd2002-01-30 16:37:32 +00002202 case XML_DOCUMENT_NODE:
Daniel Veillardd2379012002-03-15 22:24:56 +00002203 res = (const xmlChar *) "document_xml";
2204 break;
Daniel Veillardd2897fd2002-01-30 16:37:32 +00002205 case XML_DOCUMENT_TYPE_NODE:
Daniel Veillardd2379012002-03-15 22:24:56 +00002206 res = (const xmlChar *) "doctype";
2207 break;
Daniel Veillardd2897fd2002-01-30 16:37:32 +00002208 case XML_DOCUMENT_FRAG_NODE:
Daniel Veillardd2379012002-03-15 22:24:56 +00002209 res = (const xmlChar *) "fragment";
2210 break;
Daniel Veillardd2897fd2002-01-30 16:37:32 +00002211 case XML_NOTATION_NODE:
Daniel Veillardd2379012002-03-15 22:24:56 +00002212 res = (const xmlChar *) "notation";
2213 break;
Daniel Veillardd2897fd2002-01-30 16:37:32 +00002214 case XML_HTML_DOCUMENT_NODE:
Daniel Veillardd2379012002-03-15 22:24:56 +00002215 res = (const xmlChar *) "document_html";
2216 break;
Daniel Veillardd2897fd2002-01-30 16:37:32 +00002217 case XML_DTD_NODE:
Daniel Veillardd2379012002-03-15 22:24:56 +00002218 res = (const xmlChar *) "dtd";
2219 break;
Daniel Veillardd2897fd2002-01-30 16:37:32 +00002220 case XML_ELEMENT_DECL:
Daniel Veillardd2379012002-03-15 22:24:56 +00002221 res = (const xmlChar *) "elem_decl";
2222 break;
Daniel Veillardd2897fd2002-01-30 16:37:32 +00002223 case XML_ATTRIBUTE_DECL:
Daniel Veillardd2379012002-03-15 22:24:56 +00002224 res = (const xmlChar *) "attribute_decl";
2225 break;
Daniel Veillardd2897fd2002-01-30 16:37:32 +00002226 case XML_ENTITY_DECL:
Daniel Veillardd2379012002-03-15 22:24:56 +00002227 res = (const xmlChar *) "entity_decl";
2228 break;
Daniel Veillardd2897fd2002-01-30 16:37:32 +00002229 case XML_NAMESPACE_DECL:
Daniel Veillardd2379012002-03-15 22:24:56 +00002230 res = (const xmlChar *) "namespace";
2231 break;
Daniel Veillardd2897fd2002-01-30 16:37:32 +00002232 case XML_XINCLUDE_START:
Daniel Veillardd2379012002-03-15 22:24:56 +00002233 res = (const xmlChar *) "xinclude_start";
2234 break;
Daniel Veillardd2897fd2002-01-30 16:37:32 +00002235 case XML_XINCLUDE_END:
Daniel Veillardd2379012002-03-15 22:24:56 +00002236 res = (const xmlChar *) "xinclude_end";
2237 break;
Daniel Veillardd2897fd2002-01-30 16:37:32 +00002238#ifdef LIBXML_DOCB_ENABLED
Daniel Veillardd2379012002-03-15 22:24:56 +00002239 case XML_DOCB_DOCUMENT_NODE:
2240 res = (const xmlChar *) "document_docbook";
2241 break;
Daniel Veillardd2897fd2002-01-30 16:37:32 +00002242#endif
2243 }
2244#ifdef DEBUG
2245 printf("libxml_type: cur = %p: %s\n", cur, res);
2246#endif
2247
Daniel Veillard1971ee22002-01-31 20:29:19 +00002248 resultobj = libxml_constxmlCharPtrWrap(res);
Daniel Veillardd2897fd2002-01-30 16:37:32 +00002249 return resultobj;
2250}
2251
2252/************************************************************************
2253 * *
Daniel Veillard36eea2d2002-02-04 00:17:01 +00002254 * Specific accessor functions *
2255 * *
2256 ************************************************************************/
2257PyObject *
Daniel Veillardd2379012002-03-15 22:24:56 +00002258libxml_xmlNodeGetNsDefs(ATTRIBUTE_UNUSED PyObject * self, PyObject * args)
2259{
Daniel Veillard36eea2d2002-02-04 00:17:01 +00002260 PyObject *py_retval;
2261 xmlNsPtr c_retval;
2262 xmlNodePtr node;
2263 PyObject *pyobj_node;
2264
Daniel Veillardd2379012002-03-15 22:24:56 +00002265 if (!PyArg_ParseTuple
2266 (args, (char *) "O:xmlNodeGetNsDefs", &pyobj_node))
2267 return (NULL);
Daniel Veillard36eea2d2002-02-04 00:17:01 +00002268 node = (xmlNodePtr) PyxmlNode_Get(pyobj_node);
2269
2270 if ((node == NULL) || (node->type != XML_ELEMENT_NODE)) {
Daniel Veillardd2379012002-03-15 22:24:56 +00002271 Py_INCREF(Py_None);
2272 return (Py_None);
Daniel Veillard36eea2d2002-02-04 00:17:01 +00002273 }
2274 c_retval = node->nsDef;
2275 py_retval = libxml_xmlNsPtrWrap((xmlNsPtr) c_retval);
Daniel Veillardd2379012002-03-15 22:24:56 +00002276 return (py_retval);
Daniel Veillard36eea2d2002-02-04 00:17:01 +00002277}
2278
2279PyObject *
Daniel Veillardd2379012002-03-15 22:24:56 +00002280libxml_xmlNodeGetNs(ATTRIBUTE_UNUSED PyObject * self, PyObject * args)
2281{
Daniel Veillard36eea2d2002-02-04 00:17:01 +00002282 PyObject *py_retval;
2283 xmlNsPtr c_retval;
2284 xmlNodePtr node;
2285 PyObject *pyobj_node;
2286
Daniel Veillardd2379012002-03-15 22:24:56 +00002287 if (!PyArg_ParseTuple(args, (char *) "O:xmlNodeGetNs", &pyobj_node))
2288 return (NULL);
Daniel Veillard36eea2d2002-02-04 00:17:01 +00002289 node = (xmlNodePtr) PyxmlNode_Get(pyobj_node);
2290
2291 if ((node == NULL) || (node->type != XML_ELEMENT_NODE)) {
Daniel Veillardd2379012002-03-15 22:24:56 +00002292 Py_INCREF(Py_None);
2293 return (Py_None);
Daniel Veillard36eea2d2002-02-04 00:17:01 +00002294 }
2295 c_retval = node->ns;
2296 py_retval = libxml_xmlNsPtrWrap((xmlNsPtr) c_retval);
Daniel Veillardd2379012002-03-15 22:24:56 +00002297 return (py_retval);
Daniel Veillard36eea2d2002-02-04 00:17:01 +00002298}
2299
2300/************************************************************************
2301 * *
Daniel Veillard1e774382002-03-06 17:35:40 +00002302 * Serialization front-end *
2303 * *
2304 ************************************************************************/
2305
Daniel Veillardd2379012002-03-15 22:24:56 +00002306static PyObject *
2307libxml_serializeNode(ATTRIBUTE_UNUSED PyObject * self, PyObject * args)
2308{
Daniel Veillard1e774382002-03-06 17:35:40 +00002309 PyObject *py_retval = NULL;
2310 xmlChar *c_retval;
2311 PyObject *pyobj_node;
2312 xmlNodePtr node;
2313 xmlDocPtr doc;
Daniel Veillardd2379012002-03-15 22:24:56 +00002314 const char *encoding;
Daniel Veillard1e774382002-03-06 17:35:40 +00002315 int format;
2316 int len;
2317
Daniel Veillardd2379012002-03-15 22:24:56 +00002318 if (!PyArg_ParseTuple(args, (char *) "Ozi:serializeNode", &pyobj_node,
2319 &encoding, &format))
2320 return (NULL);
Daniel Veillard1e774382002-03-06 17:35:40 +00002321 node = (xmlNodePtr) PyxmlNode_Get(pyobj_node);
2322
2323 if (node == NULL) {
Daniel Veillardd2379012002-03-15 22:24:56 +00002324 Py_INCREF(Py_None);
2325 return (Py_None);
Daniel Veillard1e774382002-03-06 17:35:40 +00002326 }
2327 if (node->type == XML_DOCUMENT_NODE) {
Daniel Veillardd2379012002-03-15 22:24:56 +00002328 doc = (xmlDocPtr) node;
2329 xmlDocDumpFormatMemoryEnc(doc, &c_retval, &len,
2330 (const char *) encoding, format);
2331 py_retval = libxml_charPtrWrap((char *) c_retval);
Daniel Veillard1e774382002-03-06 17:35:40 +00002332 } else if (node->type == XML_HTML_DOCUMENT_NODE) {
Daniel Veillardd2379012002-03-15 22:24:56 +00002333 xmlOutputBufferPtr buf;
2334 xmlCharEncodingHandlerPtr handler = NULL;
Daniel Veillard1e774382002-03-06 17:35:40 +00002335
Daniel Veillardd2379012002-03-15 22:24:56 +00002336 doc = (xmlDocPtr) node;
2337 if (encoding != NULL)
2338 htmlSetMetaEncoding(doc, (const xmlChar *) encoding);
2339 encoding = (const char *) htmlGetMetaEncoding(doc);
Daniel Veillard1e774382002-03-06 17:35:40 +00002340
Daniel Veillardd2379012002-03-15 22:24:56 +00002341 if (encoding != NULL) {
2342 handler = xmlFindCharEncodingHandler(encoding);
2343 if (handler == NULL) {
2344 Py_INCREF(Py_None);
2345 return (Py_None);
2346 }
2347 }
Daniel Veillard1e774382002-03-06 17:35:40 +00002348
Daniel Veillardd2379012002-03-15 22:24:56 +00002349 /*
2350 * Fallback to HTML or ASCII when the encoding is unspecified
2351 */
2352 if (handler == NULL)
2353 handler = xmlFindCharEncodingHandler("HTML");
2354 if (handler == NULL)
2355 handler = xmlFindCharEncodingHandler("ascii");
Daniel Veillard1e774382002-03-06 17:35:40 +00002356
Daniel Veillardd2379012002-03-15 22:24:56 +00002357 buf = xmlAllocOutputBuffer(handler);
2358 if (buf == NULL) {
2359 Py_INCREF(Py_None);
2360 return (Py_None);
2361 }
2362 htmlDocContentDumpFormatOutput(buf, doc, encoding, format);
2363 xmlOutputBufferFlush(buf);
2364 if (buf->conv != NULL) {
2365 len = buf->conv->use;
2366 c_retval = buf->conv->content;
2367 buf->conv->content = NULL;
2368 } else {
2369 len = buf->buffer->use;
2370 c_retval = buf->buffer->content;
2371 buf->buffer->content = NULL;
2372 }
2373 (void) xmlOutputBufferClose(buf);
2374 py_retval = libxml_charPtrWrap((char *) c_retval);
Daniel Veillard1e774382002-03-06 17:35:40 +00002375 } else {
Daniel Veillardd2379012002-03-15 22:24:56 +00002376 doc = node->doc;
Daniel Veillarda8c0adb2002-11-17 22:37:35 +00002377 if ((doc == NULL) || (doc->type == XML_DOCUMENT_NODE)) {
Daniel Veillardd2379012002-03-15 22:24:56 +00002378 xmlOutputBufferPtr buf;
2379 xmlCharEncodingHandlerPtr handler = NULL;
Daniel Veillard1e774382002-03-06 17:35:40 +00002380
Daniel Veillardd2379012002-03-15 22:24:56 +00002381 if (encoding != NULL) {
2382 handler = xmlFindCharEncodingHandler(encoding);
2383 if (handler == NULL) {
2384 Py_INCREF(Py_None);
2385 return (Py_None);
2386 }
2387 }
Daniel Veillard1e774382002-03-06 17:35:40 +00002388
Daniel Veillardd2379012002-03-15 22:24:56 +00002389 buf = xmlAllocOutputBuffer(handler);
2390 if (buf == NULL) {
2391 Py_INCREF(Py_None);
2392 return (Py_None);
2393 }
2394 xmlNodeDumpOutput(buf, doc, node, 0, format, encoding);
2395 xmlOutputBufferFlush(buf);
2396 if (buf->conv != NULL) {
2397 len = buf->conv->use;
2398 c_retval = buf->conv->content;
2399 buf->conv->content = NULL;
2400 } else {
2401 len = buf->buffer->use;
2402 c_retval = buf->buffer->content;
2403 buf->buffer->content = NULL;
2404 }
2405 (void) xmlOutputBufferClose(buf);
2406 py_retval = libxml_charPtrWrap((char *) c_retval);
2407 } else if (doc->type == XML_HTML_DOCUMENT_NODE) {
2408 xmlOutputBufferPtr buf;
2409 xmlCharEncodingHandlerPtr handler = NULL;
Daniel Veillard1e774382002-03-06 17:35:40 +00002410
Daniel Veillardd2379012002-03-15 22:24:56 +00002411 if (encoding != NULL)
2412 htmlSetMetaEncoding(doc, (const xmlChar *) encoding);
2413 encoding = (const char *) htmlGetMetaEncoding(doc);
2414 if (encoding != NULL) {
2415 handler = xmlFindCharEncodingHandler(encoding);
2416 if (handler == NULL) {
2417 Py_INCREF(Py_None);
2418 return (Py_None);
2419 }
2420 }
Daniel Veillard1e774382002-03-06 17:35:40 +00002421
Daniel Veillardd2379012002-03-15 22:24:56 +00002422 /*
2423 * Fallback to HTML or ASCII when the encoding is unspecified
2424 */
2425 if (handler == NULL)
2426 handler = xmlFindCharEncodingHandler("HTML");
2427 if (handler == NULL)
2428 handler = xmlFindCharEncodingHandler("ascii");
Daniel Veillard1e774382002-03-06 17:35:40 +00002429
Daniel Veillardd2379012002-03-15 22:24:56 +00002430 buf = xmlAllocOutputBuffer(handler);
2431 if (buf == NULL) {
2432 Py_INCREF(Py_None);
2433 return (Py_None);
2434 }
2435 htmlNodeDumpFormatOutput(buf, doc, node, encoding, format);
2436 xmlOutputBufferFlush(buf);
2437 if (buf->conv != NULL) {
2438 len = buf->conv->use;
2439 c_retval = buf->conv->content;
2440 buf->conv->content = NULL;
2441 } else {
2442 len = buf->buffer->use;
2443 c_retval = buf->buffer->content;
2444 buf->buffer->content = NULL;
2445 }
2446 (void) xmlOutputBufferClose(buf);
2447 py_retval = libxml_charPtrWrap((char *) c_retval);
2448 } else {
2449 Py_INCREF(Py_None);
2450 return (Py_None);
2451 }
Daniel Veillard1e774382002-03-06 17:35:40 +00002452 }
Daniel Veillardd2379012002-03-15 22:24:56 +00002453 return (py_retval);
Daniel Veillard1e774382002-03-06 17:35:40 +00002454}
2455
Daniel Veillardd2379012002-03-15 22:24:56 +00002456static PyObject *
2457libxml_saveNodeTo(ATTRIBUTE_UNUSED PyObject * self, PyObject * args)
2458{
Daniel Veillard1e774382002-03-06 17:35:40 +00002459 PyObject *py_file = NULL;
2460 FILE *output;
2461 PyObject *pyobj_node;
2462 xmlNodePtr node;
2463 xmlDocPtr doc;
Daniel Veillardd2379012002-03-15 22:24:56 +00002464 const char *encoding;
Daniel Veillard1e774382002-03-06 17:35:40 +00002465 int format;
2466 int len;
2467 xmlOutputBufferPtr buf;
2468 xmlCharEncodingHandlerPtr handler = NULL;
2469
Daniel Veillardd2379012002-03-15 22:24:56 +00002470 if (!PyArg_ParseTuple(args, (char *) "OOzi:serializeNode", &pyobj_node,
2471 &py_file, &encoding, &format))
2472 return (NULL);
Daniel Veillard1e774382002-03-06 17:35:40 +00002473 node = (xmlNodePtr) PyxmlNode_Get(pyobj_node);
2474
2475 if (node == NULL) {
Daniel Veillardd2379012002-03-15 22:24:56 +00002476 return (PyInt_FromLong((long) -1));
Daniel Veillard1e774382002-03-06 17:35:40 +00002477 }
2478 if ((py_file == NULL) || (!(PyFile_Check(py_file)))) {
Daniel Veillardd2379012002-03-15 22:24:56 +00002479 return (PyInt_FromLong((long) -1));
Daniel Veillard1e774382002-03-06 17:35:40 +00002480 }
2481 output = PyFile_AsFile(py_file);
2482 if (output == NULL) {
Daniel Veillardd2379012002-03-15 22:24:56 +00002483 return (PyInt_FromLong((long) -1));
Daniel Veillard1e774382002-03-06 17:35:40 +00002484 }
2485
2486 if (node->type == XML_DOCUMENT_NODE) {
Daniel Veillardd2379012002-03-15 22:24:56 +00002487 doc = (xmlDocPtr) node;
Daniel Veillard1e774382002-03-06 17:35:40 +00002488 } else if (node->type == XML_HTML_DOCUMENT_NODE) {
Daniel Veillardd2379012002-03-15 22:24:56 +00002489 doc = (xmlDocPtr) node;
Daniel Veillard1e774382002-03-06 17:35:40 +00002490 } else {
Daniel Veillardd2379012002-03-15 22:24:56 +00002491 doc = node->doc;
Daniel Veillard1e774382002-03-06 17:35:40 +00002492 }
2493 if (doc->type == XML_HTML_DOCUMENT_NODE) {
Daniel Veillardd2379012002-03-15 22:24:56 +00002494 if (encoding == NULL)
2495 encoding = (const char *) htmlGetMetaEncoding(doc);
Daniel Veillard1e774382002-03-06 17:35:40 +00002496 }
2497 if (encoding != NULL) {
Daniel Veillardd2379012002-03-15 22:24:56 +00002498 handler = xmlFindCharEncodingHandler(encoding);
2499 if (handler == NULL) {
2500 return (PyInt_FromLong((long) -1));
2501 }
Daniel Veillard1e774382002-03-06 17:35:40 +00002502 }
2503 if (doc->type == XML_HTML_DOCUMENT_NODE) {
Daniel Veillardd2379012002-03-15 22:24:56 +00002504 if (handler == NULL)
2505 handler = xmlFindCharEncodingHandler("HTML");
2506 if (handler == NULL)
2507 handler = xmlFindCharEncodingHandler("ascii");
Daniel Veillard1e774382002-03-06 17:35:40 +00002508 }
2509
2510 buf = xmlOutputBufferCreateFile(output, handler);
2511 if (node->type == XML_DOCUMENT_NODE) {
Daniel Veillardd2379012002-03-15 22:24:56 +00002512 len = xmlSaveFormatFileTo(buf, doc, encoding, format);
Daniel Veillard1e774382002-03-06 17:35:40 +00002513 } else if (node->type == XML_HTML_DOCUMENT_NODE) {
Daniel Veillardd2379012002-03-15 22:24:56 +00002514 htmlDocContentDumpFormatOutput(buf, doc, encoding, format);
2515 len = xmlOutputBufferClose(buf);
Daniel Veillard1e774382002-03-06 17:35:40 +00002516 } else if (doc->type == XML_HTML_DOCUMENT_NODE) {
Daniel Veillardd2379012002-03-15 22:24:56 +00002517 htmlNodeDumpFormatOutput(buf, doc, node, encoding, format);
2518 len = xmlOutputBufferClose(buf);
Daniel Veillard1e774382002-03-06 17:35:40 +00002519 } else {
Daniel Veillardd2379012002-03-15 22:24:56 +00002520 xmlNodeDumpOutput(buf, doc, node, 0, format, encoding);
2521 len = xmlOutputBufferClose(buf);
Daniel Veillard1e774382002-03-06 17:35:40 +00002522 }
Daniel Veillardd2379012002-03-15 22:24:56 +00002523 return (PyInt_FromLong((long) len));
Daniel Veillard1e774382002-03-06 17:35:40 +00002524}
2525
2526/************************************************************************
2527 * *
Daniel Veillarda94ec6f2002-03-01 13:00:53 +00002528 * Extra stuff *
2529 * *
2530 ************************************************************************/
2531PyObject *
Daniel Veillardd2379012002-03-15 22:24:56 +00002532libxml_xmlNewNode(ATTRIBUTE_UNUSED PyObject * self, PyObject * args)
2533{
Daniel Veillarda94ec6f2002-03-01 13:00:53 +00002534 PyObject *py_retval;
Daniel Veillardd2379012002-03-15 22:24:56 +00002535 xmlChar *name;
Daniel Veillarda94ec6f2002-03-01 13:00:53 +00002536 xmlNodePtr node;
2537
Daniel Veillardd2379012002-03-15 22:24:56 +00002538 if (!PyArg_ParseTuple(args, (char *) "s:xmlNewNode", &name))
2539 return (NULL);
Daniel Veillarda94ec6f2002-03-01 13:00:53 +00002540 node = (xmlNodePtr) xmlNewNode(NULL, name);
Daniel Veillard3b2e4e12003-02-03 08:52:58 +00002541#ifdef DEBUG
Daniel Veillardd2379012002-03-15 22:24:56 +00002542 printf("NewNode: %s : %p\n", name, (void *) node);
Daniel Veillard3b2e4e12003-02-03 08:52:58 +00002543#endif
Daniel Veillarda94ec6f2002-03-01 13:00:53 +00002544
2545 if (node == NULL) {
Daniel Veillardd2379012002-03-15 22:24:56 +00002546 Py_INCREF(Py_None);
2547 return (Py_None);
Daniel Veillarda94ec6f2002-03-01 13:00:53 +00002548 }
2549 py_retval = libxml_xmlNodePtrWrap(node);
Daniel Veillardd2379012002-03-15 22:24:56 +00002550 return (py_retval);
Daniel Veillarda94ec6f2002-03-01 13:00:53 +00002551}
2552
Daniel Veillard54396242003-04-23 07:36:50 +00002553
2554/************************************************************************
2555 * *
2556 * Local Catalog stuff *
2557 * *
2558 ************************************************************************/
2559static PyObject *
2560libxml_addLocalCatalog(ATTRIBUTE_UNUSED PyObject * self, PyObject * args)
2561{
2562 xmlChar *URL;
2563 xmlParserCtxtPtr ctxt;
2564 PyObject *pyobj_ctxt;
2565
2566 if (!PyArg_ParseTuple(args, (char *)"Os:addLocalCatalog", &pyobj_ctxt, &URL))
2567 return(NULL);
2568
2569 ctxt = (xmlParserCtxtPtr) PyparserCtxt_Get(pyobj_ctxt);
2570
2571 if (URL != NULL) {
2572 ctxt->catalogs = xmlCatalogAddLocal(ctxt->catalogs, URL);
2573 }
2574
2575#ifdef DEBUG
2576 printf("LocalCatalog: %s\n", URL);
2577#endif
2578
2579 Py_INCREF(Py_None);
2580 return (Py_None);
2581}
2582
Daniel Veillardc2664642003-07-29 20:44:53 +00002583#ifdef LIBXML_SCHEMAS_ENABLED
2584
2585/************************************************************************
2586 * *
2587 * RelaxNG error handler registration *
2588 * *
2589 ************************************************************************/
2590
2591typedef struct
2592{
2593 PyObject *warn;
2594 PyObject *error;
2595 PyObject *arg;
2596} xmlRelaxNGValidCtxtPyCtxt;
2597typedef xmlRelaxNGValidCtxtPyCtxt *xmlRelaxNGValidCtxtPyCtxtPtr;
2598
2599static void
2600libxml_xmlRelaxNGValidityGenericErrorFuncHandler(void *ctx, char *str)
2601{
2602 PyObject *list;
2603 PyObject *result;
2604 xmlRelaxNGValidCtxtPyCtxtPtr pyCtxt;
2605
2606#ifdef DEBUG_ERROR
2607 printf("libxml_xmlRelaxNGValidityGenericErrorFuncHandler(%p, %s, ...) called\n", ctx, str);
2608#endif
2609
2610 pyCtxt = (xmlRelaxNGValidCtxtPyCtxtPtr)ctx;
2611
2612 list = PyTuple_New(2);
2613 PyTuple_SetItem(list, 0, libxml_charPtrWrap(str));
2614 PyTuple_SetItem(list, 1, pyCtxt->arg);
2615 Py_XINCREF(pyCtxt->arg);
2616 result = PyEval_CallObject(pyCtxt->error, list);
2617 if (result == NULL)
2618 {
2619 /* TODO: manage for the exception to be propagated... */
2620 PyErr_Print();
2621 }
2622 Py_XDECREF(list);
2623 Py_XDECREF(result);
2624}
2625
2626static void
2627libxml_xmlRelaxNGValidityGenericWarningFuncHandler(void *ctx, char *str)
2628{
2629 PyObject *list;
2630 PyObject *result;
2631 xmlRelaxNGValidCtxtPyCtxtPtr pyCtxt;
2632
2633#ifdef DEBUG_ERROR
2634 printf("libxml_xmlRelaxNGValidityGenericWarningFuncHandler(%p, %s, ...) called\n", ctx, str);
2635#endif
2636
2637 pyCtxt = (xmlRelaxNGValidCtxtPyCtxtPtr)ctx;
2638
2639 list = PyTuple_New(2);
2640 PyTuple_SetItem(list, 0, libxml_charPtrWrap(str));
2641 PyTuple_SetItem(list, 1, pyCtxt->arg);
2642 Py_XINCREF(pyCtxt->arg);
2643 result = PyEval_CallObject(pyCtxt->warn, list);
2644 if (result == NULL)
2645 {
2646 /* TODO: manage for the exception to be propagated... */
2647 PyErr_Print();
2648 }
2649 Py_XDECREF(list);
2650 Py_XDECREF(result);
2651}
2652
2653static void
2654libxml_xmlRelaxNGValidityErrorFunc(void *ctx, const char *msg, ...)
2655{
2656 va_list ap;
2657
2658 va_start(ap, msg);
2659 libxml_xmlRelaxNGValidityGenericErrorFuncHandler(ctx, libxml_buildMessage(msg, ap));
2660 va_end(ap);
2661}
2662
2663static void
2664libxml_xmlRelaxNGValidityWarningFunc(void *ctx, const char *msg, ...)
2665{
2666 va_list ap;
2667
2668 va_start(ap, msg);
2669 libxml_xmlRelaxNGValidityGenericWarningFuncHandler(ctx, libxml_buildMessage(msg, ap));
2670 va_end(ap);
2671}
2672
2673static PyObject *
2674libxml_xmlRelaxNGSetValidErrors(ATTRIBUTE_UNUSED PyObject * self, PyObject * args)
2675{
2676 PyObject *py_retval;
2677 PyObject *pyobj_error;
2678 PyObject *pyobj_warn;
2679 PyObject *pyobj_ctx;
2680 PyObject *pyobj_arg = Py_None;
2681 xmlRelaxNGValidCtxtPtr ctxt;
2682 xmlRelaxNGValidCtxtPyCtxtPtr pyCtxt;
2683
2684 if (!PyArg_ParseTuple
2685 (args, (char *) "OOO|O:xmlRelaxNGSetValidErrors", &pyobj_ctx, &pyobj_error, &pyobj_warn, &pyobj_arg))
2686 return (NULL);
2687
2688#ifdef DEBUG_ERROR
2689 printf("libxml_xmlRelaxNGSetValidErrors(%p, %p, %p) called\n", pyobj_ctx, pyobj_error, pyobj_warn);
2690#endif
2691
2692 ctxt = PyrelaxNgValidCtxt_Get(pyobj_ctx);
2693 if (xmlRelaxNGGetValidErrors(ctxt, NULL, NULL, &pyCtxt) == -1)
2694 {
2695 py_retval = libxml_intWrap(-1);
2696 return(py_retval);
2697 }
2698
2699 if (pyCtxt == NULL)
2700 {
2701 /* first time to set the error handlers */
2702 pyCtxt = xmlMalloc(sizeof(xmlRelaxNGValidCtxtPyCtxt));
2703 if (pyCtxt == NULL) {
2704 py_retval = libxml_intWrap(-1);
2705 return(py_retval);
2706 }
2707 memset(pyCtxt, 0, sizeof(xmlRelaxNGValidCtxtPyCtxt));
2708 }
2709
2710 /* TODO: check warn and error is a function ! */
2711 Py_XDECREF(pyCtxt->error);
2712 Py_XINCREF(pyobj_error);
2713 pyCtxt->error = pyobj_error;
2714
2715 Py_XDECREF(pyCtxt->warn);
2716 Py_XINCREF(pyobj_warn);
2717 pyCtxt->warn = pyobj_warn;
2718
2719 Py_XDECREF(pyCtxt->arg);
2720 Py_XINCREF(pyobj_arg);
2721 pyCtxt->arg = pyobj_arg;
2722
2723 xmlRelaxNGSetValidErrors(ctxt, &libxml_xmlRelaxNGValidityErrorFunc, &libxml_xmlRelaxNGValidityWarningFunc, pyCtxt);
2724
2725 py_retval = libxml_intWrap(1);
2726 return (py_retval);
2727}
2728
2729static PyObject *
2730libxml_xmlRelaxNGFreeValidCtxt(ATTRIBUTE_UNUSED PyObject *self, PyObject *args) {
2731 xmlRelaxNGValidCtxtPtr ctxt;
2732 xmlRelaxNGValidCtxtPyCtxtPtr pyCtxt;
2733 PyObject *pyobj_ctxt;
2734
2735 if (!PyArg_ParseTuple(args, (char *)"O:xmlRelaxNGFreeValidCtxt", &pyobj_ctxt))
2736 return(NULL);
2737 ctxt = (xmlRelaxNGValidCtxtPtr) PyrelaxNgValidCtxt_Get(pyobj_ctxt);
2738
2739 if (xmlRelaxNGGetValidErrors(ctxt, NULL, NULL, &pyCtxt) == 0)
2740 {
2741 if (pyCtxt != NULL)
2742 {
2743 Py_XDECREF(pyCtxt->error);
2744 Py_XDECREF(pyCtxt->warn);
2745 Py_XDECREF(pyCtxt->arg);
2746 xmlFree(pyCtxt);
2747 }
2748 }
2749
2750 xmlRelaxNGFreeValidCtxt(ctxt);
2751 Py_INCREF(Py_None);
2752 return(Py_None);
2753}
2754
2755#endif
2756
Daniel Veillarda94ec6f2002-03-01 13:00:53 +00002757/************************************************************************
2758 * *
Daniel Veillardd2897fd2002-01-30 16:37:32 +00002759 * The registration stuff *
2760 * *
2761 ************************************************************************/
2762static PyMethodDef libxmlMethods[] = {
Daniel Veillard96fe0952002-01-30 20:52:23 +00002763#include "libxml2-export.c"
Daniel Veillardd2379012002-03-15 22:24:56 +00002764 {(char *) "name", libxml_name, METH_VARARGS, NULL},
2765 {(char *) "children", libxml_children, METH_VARARGS, NULL},
2766 {(char *) "properties", libxml_properties, METH_VARARGS, NULL},
2767 {(char *) "last", libxml_last, METH_VARARGS, NULL},
2768 {(char *) "prev", libxml_prev, METH_VARARGS, NULL},
2769 {(char *) "next", libxml_next, METH_VARARGS, NULL},
2770 {(char *) "parent", libxml_parent, METH_VARARGS, NULL},
2771 {(char *) "type", libxml_type, METH_VARARGS, NULL},
2772 {(char *) "doc", libxml_doc, METH_VARARGS, NULL},
2773 {(char *) "xmlNewNode", libxml_xmlNewNode, METH_VARARGS, NULL},
2774 {(char *) "serializeNode", libxml_serializeNode, METH_VARARGS, NULL},
2775 {(char *) "saveNodeTo", libxml_saveNodeTo, METH_VARARGS, NULL},
Daniel Veillardc6d4a932002-09-12 15:00:57 +00002776 {(char *) "outputBufferCreate", libxml_xmlCreateOutputBuffer, METH_VARARGS, NULL},
2777 {(char *) "inputBufferCreate", libxml_xmlCreateInputBuffer, METH_VARARGS, NULL},
2778 {(char *) "setEntityLoader", libxml_xmlSetEntityLoader, METH_VARARGS, NULL},
Daniel Veillard3e20a292003-01-10 13:14:40 +00002779 {(char *)"xmlRegisterErrorHandler", libxml_xmlRegisterErrorHandler, METH_VARARGS, NULL },
Daniel Veillard417be3a2003-01-20 21:26:34 +00002780 {(char *)"xmlParserCtxtSetErrorHandler", libxml_xmlParserCtxtSetErrorHandler, METH_VARARGS, NULL },
2781 {(char *)"xmlParserCtxtGetErrorHandler", libxml_xmlParserCtxtGetErrorHandler, METH_VARARGS, NULL },
Daniel Veillarde6227e02003-01-14 11:42:39 +00002782 {(char *)"xmlFreeParserCtxt", libxml_xmlFreeParserCtxt, METH_VARARGS, NULL },
Daniel Veillard26f70262003-01-16 22:45:08 +00002783 {(char *)"xmlTextReaderSetErrorHandler", libxml_xmlTextReaderSetErrorHandler, METH_VARARGS, NULL },
2784 {(char *)"xmlTextReaderGetErrorHandler", libxml_xmlTextReaderGetErrorHandler, METH_VARARGS, NULL },
2785 {(char *)"xmlFreeTextReader", libxml_xmlFreeTextReader, METH_VARARGS, NULL },
Daniel Veillard54396242003-04-23 07:36:50 +00002786 {(char *)"addLocalCatalog", libxml_addLocalCatalog, METH_VARARGS, NULL },
Daniel Veillardc2664642003-07-29 20:44:53 +00002787#ifdef LIBXML_SCHEMAS_ENABLED
2788 {(char *)"xmlRelaxNGSetValidErrors", libxml_xmlRelaxNGSetValidErrors, METH_VARARGS, NULL},
2789 {(char *)"xmlRelaxNGFreeValidCtxt", libxml_xmlRelaxNGFreeValidCtxt, METH_VARARGS, NULL},
2790#endif
Daniel Veillardd2379012002-03-15 22:24:56 +00002791 {NULL, NULL, 0, NULL}
Daniel Veillardd2897fd2002-01-30 16:37:32 +00002792};
2793
Daniel Veillard0fea6f42002-02-22 22:51:13 +00002794#ifdef MERGED_MODULES
Daniel Veillard6361da02002-02-23 10:10:33 +00002795extern void initlibxsltmod(void);
Daniel Veillard0fea6f42002-02-22 22:51:13 +00002796#endif
2797
Daniel Veillardd2379012002-03-15 22:24:56 +00002798void
2799initlibxml2mod(void)
2800{
Daniel Veillardaf43f632002-03-08 15:05:20 +00002801 static int initialized = 0;
Daniel Veillard3ce52572002-02-03 15:08:05 +00002802 PyObject *m;
Daniel Veillardaf43f632002-03-08 15:05:20 +00002803
2804 if (initialized != 0)
Daniel Veillardd2379012002-03-15 22:24:56 +00002805 return;
Daniel Veillard781ac8b2003-05-15 22:11:36 +00002806 /* XXX xmlInitParser does much more than this */
2807 xmlInitGlobals();
Daniel Veillardc6d4a932002-09-12 15:00:57 +00002808 xmlRegisterDefaultOutputCallbacks();
2809 xmlRegisterDefaultInputCallbacks();
Daniel Veillardd2379012002-03-15 22:24:56 +00002810 m = Py_InitModule((char *) "libxml2mod", libxmlMethods);
Daniel Veillardaf43f632002-03-08 15:05:20 +00002811 initialized = 1;
Daniel Veillard5d819032002-02-02 21:49:17 +00002812 libxml_xmlErrorInitialize();
Daniel Veillard6361da02002-02-23 10:10:33 +00002813
Daniel Veillard0fea6f42002-02-22 22:51:13 +00002814#ifdef MERGED_MODULES
2815 initlibxsltmod();
2816#endif
Daniel Veillardd2897fd2002-01-30 16:37:32 +00002817}