blob: e3728359d45df0f2a4f62a249f0c4508b7aa4307 [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
61extern void xmlMemFree(void *ptr);
62extern void *xmlMemMalloc(size_t size);
Daniel Veillardd2379012002-03-15 22:24:56 +000063extern void *xmlMemRealloc(void *ptr, size_t size);
Daniel Veillard4e1b26c2002-02-03 20:13:06 +000064extern char *xmlMemoryStrdup(const char *str);
65
66static int libxmlMemoryDebugActivated = 0;
67static long libxmlMemoryAllocatedBase = 0;
68
69static int libxmlMemoryDebug = 0;
70static xmlFreeFunc freeFunc = NULL;
71static xmlMallocFunc mallocFunc = NULL;
72static xmlReallocFunc reallocFunc = NULL;
73static xmlStrdupFunc strdupFunc = NULL;
74
75PyObject *
Daniel Veillardd2379012002-03-15 22:24:56 +000076libxml_xmlDebugMemory(ATTRIBUTE_UNUSED PyObject * self, PyObject * args)
77{
Daniel Veillard4e1b26c2002-02-03 20:13:06 +000078 int activate;
79 PyObject *py_retval;
80 long ret;
81
Daniel Veillardd2379012002-03-15 22:24:56 +000082 if (!PyArg_ParseTuple(args, (char *) "i:xmlDebugMemory", &activate))
83 return (NULL);
Daniel Veillard4e1b26c2002-02-03 20:13:06 +000084
85#ifdef DEBUG_MEMORY
86 printf("libxml_xmlDebugMemory(%d) called\n", activate);
87#endif
88
89 if (activate != 0) {
Daniel Veillardd2379012002-03-15 22:24:56 +000090 if (libxmlMemoryDebug == 0) {
91 /*
92 * First initialize the library and grab the old memory handlers
93 * and switch the library to memory debugging
94 */
95 xmlMemGet((xmlFreeFunc *) & freeFunc,
96 (xmlMallocFunc *) & mallocFunc,
97 (xmlReallocFunc *) & reallocFunc,
98 (xmlStrdupFunc *) & strdupFunc);
99 if ((freeFunc == xmlMemFree) && (mallocFunc == xmlMemMalloc) &&
100 (reallocFunc == xmlMemRealloc) &&
101 (strdupFunc == xmlMemoryStrdup)) {
102 libxmlMemoryAllocatedBase = xmlMemUsed();
103 } else {
104 ret = (long) xmlMemSetup(xmlMemFree, xmlMemMalloc,
105 xmlMemRealloc, xmlMemoryStrdup);
106 if (ret < 0)
107 goto error;
108 libxmlMemoryAllocatedBase = xmlMemUsed();
109 }
110 xmlInitParser();
111 ret = 0;
112 } else if (libxmlMemoryDebugActivated == 0) {
113 libxmlMemoryAllocatedBase = xmlMemUsed();
114 ret = 0;
115 } else {
116 ret = xmlMemUsed() - libxmlMemoryAllocatedBase;
117 }
118 libxmlMemoryDebug = 1;
119 libxmlMemoryDebugActivated = 1;
Daniel Veillard4e1b26c2002-02-03 20:13:06 +0000120 } else {
Daniel Veillardd2379012002-03-15 22:24:56 +0000121 if (libxmlMemoryDebugActivated == 1)
122 ret = xmlMemUsed() - libxmlMemoryAllocatedBase;
123 else
124 ret = 0;
125 libxmlMemoryDebugActivated = 0;
Daniel Veillard4e1b26c2002-02-03 20:13:06 +0000126 }
Daniel Veillardd2379012002-03-15 22:24:56 +0000127 error:
Daniel Veillard4e1b26c2002-02-03 20:13:06 +0000128 py_retval = libxml_longWrap(ret);
Daniel Veillardd2379012002-03-15 22:24:56 +0000129 return (py_retval);
Daniel Veillard4e1b26c2002-02-03 20:13:06 +0000130}
131
132PyObject *
Daniel Veillardd2379012002-03-15 22:24:56 +0000133libxml_xmlDumpMemory(ATTRIBUTE_UNUSED PyObject * self,
134 ATTRIBUTE_UNUSED PyObject * args)
135{
Daniel Veillard4e1b26c2002-02-03 20:13:06 +0000136
137 if (libxmlMemoryDebug != 0)
Daniel Veillardd2379012002-03-15 22:24:56 +0000138 xmlMemoryDump();
Daniel Veillard4e1b26c2002-02-03 20:13:06 +0000139 Py_INCREF(Py_None);
Daniel Veillardd2379012002-03-15 22:24:56 +0000140 return (Py_None);
Daniel Veillard4e1b26c2002-02-03 20:13:06 +0000141}
Daniel Veillardd2897fd2002-01-30 16:37:32 +0000142
143/************************************************************************
144 * *
Daniel Veillardc6d4a932002-09-12 15:00:57 +0000145 * Handling Python FILE I/O at the C level *
146 * The raw I/O attack diectly the File objects, while the *
147 * other routines address the ioWrapper instance instead *
148 * *
149 ************************************************************************/
150
151/**
152 * xmlPythonFileCloseUnref:
153 * @context: the I/O context
154 *
155 * Close an I/O channel
156 */
157static int
158xmlPythonFileCloseRaw (void * context) {
159 PyObject *file, *ret;
160
161#ifdef DEBUG_FILES
162 printf("xmlPythonFileCloseUnref\n");
163#endif
164 file = (PyObject *) context;
165 if (file == NULL) return(-1);
Daniel Veillard118aed72002-09-24 14:13:13 +0000166 ret = PyEval_CallMethod(file, (char *) "close", (char *) "()");
Daniel Veillardc6d4a932002-09-12 15:00:57 +0000167 if (ret != NULL) {
168 Py_DECREF(ret);
169 }
170 Py_DECREF(file);
171 return(0);
172}
173
174/**
175 * xmlPythonFileReadRaw:
176 * @context: the I/O context
177 * @buffer: where to drop data
178 * @len: number of bytes to write
179 *
180 * Read @len bytes to @buffer from the Python file in the I/O channel
181 *
182 * Returns the number of bytes read
183 */
184static int
185xmlPythonFileReadRaw (void * context, char * buffer, int len) {
186 PyObject *file;
187 PyObject *ret;
188 int lenread = -1;
189 char *data;
190
191#ifdef DEBUG_FILES
192 printf("xmlPythonFileReadRaw: %d\n", len);
193#endif
194 file = (PyObject *) context;
195 if (file == NULL) return(-1);
Daniel Veillard118aed72002-09-24 14:13:13 +0000196 ret = PyEval_CallMethod(file, (char *) "read", (char *) "(i)", len);
Daniel Veillardc6d4a932002-09-12 15:00:57 +0000197 if (ret == NULL) {
198 printf("xmlPythonFileReadRaw: result is NULL\n");
199 return(-1);
200 } else if (PyString_Check(ret)) {
201 lenread = PyString_Size(ret);
202 data = PyString_AsString(ret);
203 if (lenread > len)
204 memcpy(buffer, data, len);
205 else
206 memcpy(buffer, data, lenread);
207 Py_DECREF(ret);
208 } else {
209 printf("xmlPythonFileReadRaw: result is not a String\n");
210 Py_DECREF(ret);
211 }
212 return(lenread);
213}
214
215/**
216 * xmlPythonFileRead:
217 * @context: the I/O context
218 * @buffer: where to drop data
219 * @len: number of bytes to write
220 *
221 * Read @len bytes to @buffer from the I/O channel.
222 *
223 * Returns the number of bytes read
224 */
225static int
226xmlPythonFileRead (void * context, char * buffer, int len) {
227 PyObject *file;
228 PyObject *ret;
229 int lenread = -1;
230 char *data;
231
232#ifdef DEBUG_FILES
233 printf("xmlPythonFileRead: %d\n", len);
234#endif
235 file = (PyObject *) context;
236 if (file == NULL) return(-1);
Daniel Veillard118aed72002-09-24 14:13:13 +0000237 ret = PyEval_CallMethod(file, (char *) "io_read", (char *) "(i)", len);
Daniel Veillardc6d4a932002-09-12 15:00:57 +0000238 if (ret == NULL) {
239 printf("xmlPythonFileRead: result is NULL\n");
240 return(-1);
241 } else if (PyString_Check(ret)) {
242 lenread = PyString_Size(ret);
243 data = PyString_AsString(ret);
244 if (lenread > len)
245 memcpy(buffer, data, len);
246 else
247 memcpy(buffer, data, lenread);
248 Py_DECREF(ret);
249 } else {
250 printf("xmlPythonFileRead: result is not a String\n");
251 Py_DECREF(ret);
252 }
253 return(lenread);
254}
255
256/**
257 * xmlFileWrite:
258 * @context: the I/O context
259 * @buffer: where to drop data
260 * @len: number of bytes to write
261 *
262 * Write @len bytes from @buffer to the I/O channel.
263 *
264 * Returns the number of bytes written
265 */
266static int
267xmlPythonFileWrite (void * context, const char * buffer, int len) {
268 PyObject *file;
269 PyObject *string;
270 PyObject *ret;
271 int written = -1;
272
273#ifdef DEBUG_FILES
274 printf("xmlPythonFileWrite: %d\n", len);
275#endif
276 file = (PyObject *) context;
277 if (file == NULL) return(-1);
278 string = PyString_FromStringAndSize(buffer, len);
279 if (string == NULL) return(-1);
Daniel Veillard118aed72002-09-24 14:13:13 +0000280 ret = PyEval_CallMethod(file, (char *) "io_write", (char *) "(O)", string);
Daniel Veillardc6d4a932002-09-12 15:00:57 +0000281 Py_DECREF(string);
282 if (ret == NULL) {
283 printf("xmlPythonFileWrite: result is NULL\n");
284 return(-1);
285 } else if (PyInt_Check(ret)) {
286 written = (int) PyInt_AsLong(ret);
287 Py_DECREF(ret);
288 } else if (ret == Py_None) {
289 written = len;
290 Py_DECREF(ret);
291 } else {
292 printf("xmlPythonFileWrite: result is not an Int nor None\n");
293 Py_DECREF(ret);
294 }
295 return(written);
296}
297
298/**
299 * xmlPythonFileClose:
300 * @context: the I/O context
301 *
302 * Close an I/O channel
303 */
304static int
305xmlPythonFileClose (void * context) {
306 PyObject *file, *ret;
307
308#ifdef DEBUG_FILES
309 printf("xmlPythonFileClose\n");
310#endif
311 file = (PyObject *) context;
312 if (file == NULL) return(-1);
Daniel Veillard118aed72002-09-24 14:13:13 +0000313 ret = PyEval_CallMethod(file, (char *) "io_close", (char *) "()");
Daniel Veillardc6d4a932002-09-12 15:00:57 +0000314 if (ret != NULL) {
315 Py_DECREF(ret);
316 }
317 return(0);
318}
319
320/**
321 * xmlOutputBufferCreatePythonFile:
322 * @file: a PyFile_Type
323 * @encoder: the encoding converter or NULL
324 *
325 * Create a buffered output for the progressive saving to a PyFile_Type
326 * buffered C I/O
327 *
328 * Returns the new parser output or NULL
329 */
Daniel Veillard118aed72002-09-24 14:13:13 +0000330static xmlOutputBufferPtr
Daniel Veillardc6d4a932002-09-12 15:00:57 +0000331xmlOutputBufferCreatePythonFile(PyObject *file,
332 xmlCharEncodingHandlerPtr encoder) {
333 xmlOutputBufferPtr ret;
334
335 if (file == NULL) return(NULL);
336
337 ret = xmlAllocOutputBuffer(encoder);
338 if (ret != NULL) {
339 ret->context = file;
340 /* Py_INCREF(file); */
341 ret->writecallback = xmlPythonFileWrite;
342 ret->closecallback = xmlPythonFileClose;
343 }
344
345 return(ret);
346}
347
348PyObject *
349libxml_xmlCreateOutputBuffer(ATTRIBUTE_UNUSED PyObject *self, PyObject *args) {
350 PyObject *py_retval;
351 PyObject *file;
352 xmlChar *encoding;
353 xmlCharEncodingHandlerPtr handler = NULL;
354 xmlOutputBufferPtr buffer;
355
356
357 if (!PyArg_ParseTuple(args, (char *)"Oz:xmlOutputBufferCreate",
358 &file, &encoding))
359 return(NULL);
360 if ((encoding != NULL) && (encoding[0] != 0)) {
Daniel Veillard118aed72002-09-24 14:13:13 +0000361 handler = xmlFindCharEncodingHandler((const char *) encoding);
Daniel Veillardc6d4a932002-09-12 15:00:57 +0000362 }
363 buffer = xmlOutputBufferCreatePythonFile(file, handler);
364 if (buffer == NULL)
365 printf("libxml_xmlCreateOutputBuffer: buffer == NULL\n");
366 py_retval = libxml_xmlOutputBufferPtrWrap(buffer);
367 return(py_retval);
368}
369
370
371/**
372 * xmlParserInputBufferCreatePythonFile:
373 * @file: a PyFile_Type
374 * @encoder: the encoding converter or NULL
375 *
376 * Create a buffered output for the progressive saving to a PyFile_Type
377 * buffered C I/O
378 *
379 * Returns the new parser output or NULL
380 */
Daniel Veillard118aed72002-09-24 14:13:13 +0000381static xmlParserInputBufferPtr
Daniel Veillardc6d4a932002-09-12 15:00:57 +0000382xmlParserInputBufferCreatePythonFile(PyObject *file,
383 xmlCharEncoding encoding) {
384 xmlParserInputBufferPtr ret;
385
386 if (file == NULL) return(NULL);
387
388 ret = xmlAllocParserInputBuffer(encoding);
389 if (ret != NULL) {
390 ret->context = file;
391 /* Py_INCREF(file); */
392 ret->readcallback = xmlPythonFileRead;
393 ret->closecallback = xmlPythonFileClose;
394 }
395
396 return(ret);
397}
398
399PyObject *
400libxml_xmlCreateInputBuffer(ATTRIBUTE_UNUSED PyObject *self, PyObject *args) {
401 PyObject *py_retval;
402 PyObject *file;
403 xmlChar *encoding;
404 xmlCharEncoding enc = XML_CHAR_ENCODING_NONE;
405 xmlParserInputBufferPtr buffer;
406
407
408 if (!PyArg_ParseTuple(args, (char *)"Oz:xmlParserInputBufferCreate",
409 &file, &encoding))
410 return(NULL);
411 if ((encoding != NULL) && (encoding[0] != 0)) {
Daniel Veillard118aed72002-09-24 14:13:13 +0000412 enc = xmlParseCharEncoding((const char *) encoding);
Daniel Veillardc6d4a932002-09-12 15:00:57 +0000413 }
414 buffer = xmlParserInputBufferCreatePythonFile(file, enc);
415 if (buffer == NULL)
416 printf("libxml_xmlParserInputBufferCreate: buffer == NULL\n");
417 py_retval = libxml_xmlParserInputBufferPtrWrap(buffer);
418 return(py_retval);
419}
420
421/************************************************************************
422 * *
423 * Providing the resolver at the Python level *
424 * *
425 ************************************************************************/
426
427static xmlExternalEntityLoader defaultExternalEntityLoader = NULL;
428static PyObject *pythonExternalEntityLoaderObjext;
429
430static xmlParserInputPtr
431pythonExternalEntityLoader(const char *URL, const char *ID,
432 xmlParserCtxtPtr ctxt) {
433 xmlParserInputPtr result = NULL;
434 if (pythonExternalEntityLoaderObjext != NULL) {
435 PyObject *ret;
436 PyObject *ctxtobj;
437
438 ctxtobj = libxml_xmlParserCtxtPtrWrap(ctxt);
439#ifdef DEBUG_LOADER
440 printf("pythonExternalEntityLoader: ready to call\n");
441#endif
442
443 ret = PyObject_CallFunction(pythonExternalEntityLoaderObjext,
Daniel Veillard118aed72002-09-24 14:13:13 +0000444 (char *) "(ssO)", URL, ID, ctxtobj);
Daniel Veillarde4a07e72003-01-14 14:40:25 +0000445 Py_XDECREF(ctxtobj);
Daniel Veillardc6d4a932002-09-12 15:00:57 +0000446#ifdef DEBUG_LOADER
447 printf("pythonExternalEntityLoader: result ");
448 PyObject_Print(ret, stdout, 0);
449 printf("\n");
450#endif
451
452 if (ret != NULL) {
Daniel Veillard118aed72002-09-24 14:13:13 +0000453 if (PyObject_HasAttrString(ret, (char *) "read")) {
Daniel Veillardc6d4a932002-09-12 15:00:57 +0000454 xmlParserInputBufferPtr buf;
455
456 buf = xmlAllocParserInputBuffer(XML_CHAR_ENCODING_NONE);
457 if (buf != NULL) {
458 buf->context = ret;
459 buf->readcallback = xmlPythonFileReadRaw;
460 buf->closecallback = xmlPythonFileCloseRaw;
461 result = xmlNewIOInputStream(ctxt, buf,
462 XML_CHAR_ENCODING_NONE);
463 }
464 } else {
465 printf("pythonExternalEntityLoader: can't read\n");
466 }
467 if (result == NULL) {
468 Py_DECREF(ret);
Daniel Veillardc64b8e92003-02-24 11:47:13 +0000469 } else if (URL != NULL) {
470 result->filename = xmlStrdup(URL);
471 result->directory = xmlParserGetDirectory((const char *) URL);
Daniel Veillardc6d4a932002-09-12 15:00:57 +0000472 }
473 }
474 }
475 if ((result == NULL) && (defaultExternalEntityLoader != NULL)) {
476 result = defaultExternalEntityLoader(URL, ID, ctxt);
477 }
478 return(result);
479}
480
481PyObject *
482libxml_xmlSetEntityLoader(ATTRIBUTE_UNUSED PyObject *self, PyObject *args) {
483 PyObject *py_retval;
484 PyObject *loader;
485
486 if (!PyArg_ParseTuple(args, (char *)"O:libxml_xmlSetEntityLoader",
487 &loader))
488 return(NULL);
489
490#ifdef DEBUG_LOADER
491 printf("libxml_xmlSetEntityLoader\n");
492#endif
493 if (defaultExternalEntityLoader == NULL)
494 defaultExternalEntityLoader = xmlGetExternalEntityLoader();
495
496 pythonExternalEntityLoaderObjext = loader;
497 xmlSetExternalEntityLoader(pythonExternalEntityLoader);
498
499 py_retval = PyInt_FromLong(0);
500 return(py_retval);
501}
502
503
504/************************************************************************
505 * *
Daniel Veillard3ce52572002-02-03 15:08:05 +0000506 * Handling SAX/xmllib/sgmlop callback interfaces *
Daniel Veillardd2897fd2002-01-30 16:37:32 +0000507 * *
508 ************************************************************************/
Daniel Veillardd2897fd2002-01-30 16:37:32 +0000509
Daniel Veillard33caa0b2002-02-04 14:07:26 +0000510static void
511pythonStartElement(void *user_data, const xmlChar * name,
512 const xmlChar ** attrs)
513{
514 int i;
515 PyObject *handler;
516 PyObject *dict;
517 PyObject *attrname;
518 PyObject *attrvalue;
Daniel Veillardd2379012002-03-15 22:24:56 +0000519 PyObject *result = NULL;
Daniel Veillard33caa0b2002-02-04 14:07:26 +0000520 int type = 0;
521
Daniel Veillard797a5652002-02-12 13:46:21 +0000522#ifdef DEBUG_SAX
523 printf("pythonStartElement(%s) called\n", name);
524#endif
Daniel Veillard33caa0b2002-02-04 14:07:26 +0000525 handler = (PyObject *) user_data;
Daniel Veillardd2379012002-03-15 22:24:56 +0000526 if (PyObject_HasAttrString(handler, (char *) "startElement"))
Daniel Veillard33caa0b2002-02-04 14:07:26 +0000527 type = 1;
Daniel Veillardd2379012002-03-15 22:24:56 +0000528 else if (PyObject_HasAttrString(handler, (char *) "start"))
Daniel Veillard33caa0b2002-02-04 14:07:26 +0000529 type = 2;
530 if (type != 0) {
531 /*
532 * the xmllib interface always generate a dictionnary,
533 * possibly empty
534 */
535 if ((attrs == NULL) && (type == 1)) {
536 Py_XINCREF(Py_None);
537 dict = Py_None;
Daniel Veillardd2379012002-03-15 22:24:56 +0000538 } else if (attrs == NULL) {
539 dict = PyDict_New();
Daniel Veillard33caa0b2002-02-04 14:07:26 +0000540 } else {
541 dict = PyDict_New();
542 for (i = 0; attrs[i] != NULL; i++) {
Daniel Veillardd2379012002-03-15 22:24:56 +0000543 attrname = PyString_FromString((char *) attrs[i]);
Daniel Veillard33caa0b2002-02-04 14:07:26 +0000544 i++;
545 if (attrs[i] != NULL) {
Daniel Veillardd2379012002-03-15 22:24:56 +0000546 attrvalue = PyString_FromString((char *) attrs[i]);
Daniel Veillard33caa0b2002-02-04 14:07:26 +0000547 } else {
548 Py_XINCREF(Py_None);
549 attrvalue = Py_None;
550 }
551 PyDict_SetItem(dict, attrname, attrvalue);
552 }
553 }
554
555 if (type == 1)
Daniel Veillardd2379012002-03-15 22:24:56 +0000556 result = PyObject_CallMethod(handler, (char *) "startElement",
557 (char *) "sO", name, dict);
Daniel Veillard33caa0b2002-02-04 14:07:26 +0000558 else if (type == 2)
Daniel Veillardd2379012002-03-15 22:24:56 +0000559 result = PyObject_CallMethod(handler, (char *) "start",
560 (char *) "sO", name, dict);
561 if (PyErr_Occurred())
562 PyErr_Print();
Daniel Veillard33caa0b2002-02-04 14:07:26 +0000563 Py_XDECREF(dict);
564 Py_XDECREF(result);
565 }
566}
567
568static void
569pythonStartDocument(void *user_data)
570{
571 PyObject *handler;
572 PyObject *result;
573
Daniel Veillard797a5652002-02-12 13:46:21 +0000574#ifdef DEBUG_SAX
575 printf("pythonStartDocument() called\n");
576#endif
Daniel Veillard33caa0b2002-02-04 14:07:26 +0000577 handler = (PyObject *) user_data;
Daniel Veillardd2379012002-03-15 22:24:56 +0000578 if (PyObject_HasAttrString(handler, (char *) "startDocument")) {
579 result =
580 PyObject_CallMethod(handler, (char *) "startDocument", NULL);
581 if (PyErr_Occurred())
582 PyErr_Print();
Daniel Veillard33caa0b2002-02-04 14:07:26 +0000583 Py_XDECREF(result);
584 }
585}
586
587static void
588pythonEndDocument(void *user_data)
589{
590 PyObject *handler;
591 PyObject *result;
592
Daniel Veillard797a5652002-02-12 13:46:21 +0000593#ifdef DEBUG_SAX
594 printf("pythonEndDocument() called\n");
595#endif
Daniel Veillard33caa0b2002-02-04 14:07:26 +0000596 handler = (PyObject *) user_data;
Daniel Veillardd2379012002-03-15 22:24:56 +0000597 if (PyObject_HasAttrString(handler, (char *) "endDocument")) {
598 result =
599 PyObject_CallMethod(handler, (char *) "endDocument", NULL);
600 if (PyErr_Occurred())
601 PyErr_Print();
Daniel Veillard33caa0b2002-02-04 14:07:26 +0000602 Py_XDECREF(result);
603 }
604 /*
605 * The reference to the handler is released there
606 */
607 Py_XDECREF(handler);
608}
609
610static void
611pythonEndElement(void *user_data, const xmlChar * name)
612{
613 PyObject *handler;
614 PyObject *result;
615
Daniel Veillard797a5652002-02-12 13:46:21 +0000616#ifdef DEBUG_SAX
617 printf("pythonEndElement(%s) called\n", name);
618#endif
Daniel Veillard33caa0b2002-02-04 14:07:26 +0000619 handler = (PyObject *) user_data;
Daniel Veillardd2379012002-03-15 22:24:56 +0000620 if (PyObject_HasAttrString(handler, (char *) "endElement")) {
621 result = PyObject_CallMethod(handler, (char *) "endElement",
622 (char *) "s", name);
623 if (PyErr_Occurred())
624 PyErr_Print();
Daniel Veillard33caa0b2002-02-04 14:07:26 +0000625 Py_XDECREF(result);
Daniel Veillardd2379012002-03-15 22:24:56 +0000626 } else if (PyObject_HasAttrString(handler, (char *) "end")) {
627 result = PyObject_CallMethod(handler, (char *) "end",
628 (char *) "s", name);
629 if (PyErr_Occurred())
630 PyErr_Print();
Daniel Veillard797a5652002-02-12 13:46:21 +0000631 Py_XDECREF(result);
Daniel Veillard33caa0b2002-02-04 14:07:26 +0000632 }
633}
634
635static void
636pythonReference(void *user_data, const xmlChar * name)
637{
638 PyObject *handler;
639 PyObject *result;
640
Daniel Veillard797a5652002-02-12 13:46:21 +0000641#ifdef DEBUG_SAX
642 printf("pythonReference(%s) called\n", name);
643#endif
Daniel Veillard33caa0b2002-02-04 14:07:26 +0000644 handler = (PyObject *) user_data;
Daniel Veillardd2379012002-03-15 22:24:56 +0000645 if (PyObject_HasAttrString(handler, (char *) "reference")) {
646 result = PyObject_CallMethod(handler, (char *) "reference",
647 (char *) "s", name);
648 if (PyErr_Occurred())
649 PyErr_Print();
Daniel Veillard33caa0b2002-02-04 14:07:26 +0000650 Py_XDECREF(result);
651 }
652}
653
654static void
655pythonCharacters(void *user_data, const xmlChar * ch, int len)
656{
657 PyObject *handler;
Daniel Veillardd2379012002-03-15 22:24:56 +0000658 PyObject *result = NULL;
Daniel Veillard33caa0b2002-02-04 14:07:26 +0000659 int type = 0;
660
Daniel Veillard797a5652002-02-12 13:46:21 +0000661#ifdef DEBUG_SAX
662 printf("pythonCharacters(%s, %d) called\n", ch, len);
663#endif
Daniel Veillard33caa0b2002-02-04 14:07:26 +0000664 handler = (PyObject *) user_data;
Daniel Veillardd2379012002-03-15 22:24:56 +0000665 if (PyObject_HasAttrString(handler, (char *) "characters"))
666 type = 1;
667 else if (PyObject_HasAttrString(handler, (char *) "data"))
668 type = 2;
Daniel Veillard33caa0b2002-02-04 14:07:26 +0000669 if (type != 0) {
Daniel Veillardd2379012002-03-15 22:24:56 +0000670 if (type == 1)
671 result = PyObject_CallMethod(handler, (char *) "characters",
672 (char *) "s#", ch, len);
673 else if (type == 2)
674 result = PyObject_CallMethod(handler, (char *) "data",
675 (char *) "s#", ch, len);
676 if (PyErr_Occurred())
677 PyErr_Print();
Daniel Veillard33caa0b2002-02-04 14:07:26 +0000678 Py_XDECREF(result);
679 }
680}
681
682static void
683pythonIgnorableWhitespace(void *user_data, const xmlChar * ch, int len)
684{
685 PyObject *handler;
Daniel Veillardd2379012002-03-15 22:24:56 +0000686 PyObject *result = NULL;
Daniel Veillard33caa0b2002-02-04 14:07:26 +0000687 int type = 0;
688
Daniel Veillard797a5652002-02-12 13:46:21 +0000689#ifdef DEBUG_SAX
690 printf("pythonIgnorableWhitespace(%s, %d) called\n", ch, len);
691#endif
Daniel Veillard33caa0b2002-02-04 14:07:26 +0000692 handler = (PyObject *) user_data;
Daniel Veillardd2379012002-03-15 22:24:56 +0000693 if (PyObject_HasAttrString(handler, (char *) "ignorableWhitespace"))
Daniel Veillard33caa0b2002-02-04 14:07:26 +0000694 type = 1;
Daniel Veillardd2379012002-03-15 22:24:56 +0000695 else if (PyObject_HasAttrString(handler, (char *) "data"))
Daniel Veillard33caa0b2002-02-04 14:07:26 +0000696 type = 2;
697 if (type != 0) {
698 if (type == 1)
699 result =
Daniel Veillardd2379012002-03-15 22:24:56 +0000700 PyObject_CallMethod(handler,
701 (char *) "ignorableWhitespace",
702 (char *) "s#", ch, len);
Daniel Veillard33caa0b2002-02-04 14:07:26 +0000703 else if (type == 2)
Daniel Veillardd2379012002-03-15 22:24:56 +0000704 result =
705 PyObject_CallMethod(handler, (char *) "data",
706 (char *) "s#", ch, len);
Daniel Veillard33caa0b2002-02-04 14:07:26 +0000707 Py_XDECREF(result);
708 }
709}
710
711static void
712pythonProcessingInstruction(void *user_data,
713 const xmlChar * target, const xmlChar * data)
714{
715 PyObject *handler;
716 PyObject *result;
717
Daniel Veillard797a5652002-02-12 13:46:21 +0000718#ifdef DEBUG_SAX
719 printf("pythonProcessingInstruction(%s, %s) called\n", target, data);
720#endif
Daniel Veillard33caa0b2002-02-04 14:07:26 +0000721 handler = (PyObject *) user_data;
Daniel Veillardd2379012002-03-15 22:24:56 +0000722 if (PyObject_HasAttrString(handler, (char *) "processingInstruction")) {
723 result = PyObject_CallMethod(handler, (char *)
724 "processingInstruction",
725 (char *) "ss", target, data);
Daniel Veillard33caa0b2002-02-04 14:07:26 +0000726 Py_XDECREF(result);
727 }
728}
729
730static void
731pythonComment(void *user_data, const xmlChar * value)
732{
733 PyObject *handler;
734 PyObject *result;
735
Daniel Veillard797a5652002-02-12 13:46:21 +0000736#ifdef DEBUG_SAX
737 printf("pythonComment(%s) called\n", value);
738#endif
Daniel Veillard33caa0b2002-02-04 14:07:26 +0000739 handler = (PyObject *) user_data;
Daniel Veillardd2379012002-03-15 22:24:56 +0000740 if (PyObject_HasAttrString(handler, (char *) "comment")) {
741 result =
742 PyObject_CallMethod(handler, (char *) "comment", (char *) "s",
743 value);
744 if (PyErr_Occurred())
745 PyErr_Print();
Daniel Veillard33caa0b2002-02-04 14:07:26 +0000746 Py_XDECREF(result);
747 }
748}
749
750static void
751pythonWarning(void *user_data, const char *msg, ...)
752{
753 PyObject *handler;
754 PyObject *result;
755 va_list args;
756 char buf[1024];
757
Daniel Veillard797a5652002-02-12 13:46:21 +0000758#ifdef DEBUG_SAX
759 printf("pythonWarning(%s) called\n", msg);
760#endif
Daniel Veillard33caa0b2002-02-04 14:07:26 +0000761 handler = (PyObject *) user_data;
Daniel Veillardd2379012002-03-15 22:24:56 +0000762 if (PyObject_HasAttrString(handler, (char *) "warning")) {
Daniel Veillard33caa0b2002-02-04 14:07:26 +0000763 va_start(args, msg);
764 vsnprintf(buf, 1023, msg, args);
Daniel Veillardd2379012002-03-15 22:24:56 +0000765 va_end(args);
766 buf[1023] = 0;
767 result =
768 PyObject_CallMethod(handler, (char *) "warning", (char *) "s",
769 buf);
770 if (PyErr_Occurred())
771 PyErr_Print();
Daniel Veillard33caa0b2002-02-04 14:07:26 +0000772 Py_XDECREF(result);
773 }
774}
775
776static void
777pythonError(void *user_data, const char *msg, ...)
778{
779 PyObject *handler;
780 PyObject *result;
781 va_list args;
782 char buf[1024];
783
Daniel Veillard797a5652002-02-12 13:46:21 +0000784#ifdef DEBUG_SAX
785 printf("pythonError(%s) called\n", msg);
786#endif
Daniel Veillard33caa0b2002-02-04 14:07:26 +0000787 handler = (PyObject *) user_data;
Daniel Veillardd2379012002-03-15 22:24:56 +0000788 if (PyObject_HasAttrString(handler, (char *) "error")) {
Daniel Veillard33caa0b2002-02-04 14:07:26 +0000789 va_start(args, msg);
790 vsnprintf(buf, 1023, msg, args);
Daniel Veillardd2379012002-03-15 22:24:56 +0000791 va_end(args);
792 buf[1023] = 0;
793 result =
794 PyObject_CallMethod(handler, (char *) "error", (char *) "s",
795 buf);
796 if (PyErr_Occurred())
797 PyErr_Print();
Daniel Veillard33caa0b2002-02-04 14:07:26 +0000798 Py_XDECREF(result);
799 }
800}
801
802static void
803pythonFatalError(void *user_data, const char *msg, ...)
804{
805 PyObject *handler;
806 PyObject *result;
807 va_list args;
808 char buf[1024];
809
Daniel Veillard797a5652002-02-12 13:46:21 +0000810#ifdef DEBUG_SAX
811 printf("pythonFatalError(%s) called\n", msg);
812#endif
Daniel Veillard33caa0b2002-02-04 14:07:26 +0000813 handler = (PyObject *) user_data;
Daniel Veillardd2379012002-03-15 22:24:56 +0000814 if (PyObject_HasAttrString(handler, (char *) "fatalError")) {
Daniel Veillard33caa0b2002-02-04 14:07:26 +0000815 va_start(args, msg);
816 vsnprintf(buf, 1023, msg, args);
Daniel Veillardd2379012002-03-15 22:24:56 +0000817 va_end(args);
818 buf[1023] = 0;
819 result =
820 PyObject_CallMethod(handler, (char *) "fatalError",
821 (char *) "s", buf);
822 if (PyErr_Occurred())
823 PyErr_Print();
Daniel Veillard33caa0b2002-02-04 14:07:26 +0000824 Py_XDECREF(result);
825 }
826}
827
828static void
829pythonCdataBlock(void *user_data, const xmlChar * ch, int len)
830{
831 PyObject *handler;
Daniel Veillardd2379012002-03-15 22:24:56 +0000832 PyObject *result = NULL;
Daniel Veillard33caa0b2002-02-04 14:07:26 +0000833 int type = 0;
834
Daniel Veillard797a5652002-02-12 13:46:21 +0000835#ifdef DEBUG_SAX
836 printf("pythonCdataBlock(%s, %d) called\n", ch, len);
837#endif
Daniel Veillard33caa0b2002-02-04 14:07:26 +0000838 handler = (PyObject *) user_data;
Daniel Veillardd2379012002-03-15 22:24:56 +0000839 if (PyObject_HasAttrString(handler, (char *) "cdataBlock"))
840 type = 1;
841 else if (PyObject_HasAttrString(handler, (char *) "cdata"))
842 type = 2;
Daniel Veillard33caa0b2002-02-04 14:07:26 +0000843 if (type != 0) {
Daniel Veillardd2379012002-03-15 22:24:56 +0000844 if (type == 1)
845 result =
846 PyObject_CallMethod(handler, (char *) "cdataBlock",
847 (char *) "s#", ch, len);
848 else if (type == 2)
849 result =
850 PyObject_CallMethod(handler, (char *) "cdata",
851 (char *) "s#", ch, len);
852 if (PyErr_Occurred())
853 PyErr_Print();
Daniel Veillard33caa0b2002-02-04 14:07:26 +0000854 Py_XDECREF(result);
855 }
856}
857
858static void
859pythonExternalSubset(void *user_data,
860 const xmlChar * name,
861 const xmlChar * externalID, const xmlChar * systemID)
862{
863 PyObject *handler;
864 PyObject *result;
865
Daniel Veillard797a5652002-02-12 13:46:21 +0000866#ifdef DEBUG_SAX
867 printf("pythonExternalSubset(%s, %s, %s) called\n",
Daniel Veillardd2379012002-03-15 22:24:56 +0000868 name, externalID, systemID);
Daniel Veillard797a5652002-02-12 13:46:21 +0000869#endif
Daniel Veillard33caa0b2002-02-04 14:07:26 +0000870 handler = (PyObject *) user_data;
Daniel Veillardd2379012002-03-15 22:24:56 +0000871 if (PyObject_HasAttrString(handler, (char *) "externalSubset")) {
Daniel Veillard33caa0b2002-02-04 14:07:26 +0000872 result =
Daniel Veillardd2379012002-03-15 22:24:56 +0000873 PyObject_CallMethod(handler, (char *) "externalSubset",
874 (char *) "sss", name, externalID,
875 systemID);
Daniel Veillard33caa0b2002-02-04 14:07:26 +0000876 Py_XDECREF(result);
877 }
878}
879
880static void
881pythonEntityDecl(void *user_data,
882 const xmlChar * name,
883 int type,
884 const xmlChar * publicId,
885 const xmlChar * systemId, xmlChar * content)
886{
887 PyObject *handler;
888 PyObject *result;
889
890 handler = (PyObject *) user_data;
Daniel Veillardd2379012002-03-15 22:24:56 +0000891 if (PyObject_HasAttrString(handler, (char *) "entityDecl")) {
892 result = PyObject_CallMethod(handler, (char *) "entityDecl",
893 (char *) "sisss", name, type,
894 publicId, systemId, content);
895 if (PyErr_Occurred())
896 PyErr_Print();
Daniel Veillard33caa0b2002-02-04 14:07:26 +0000897 Py_XDECREF(result);
898 }
899}
900
901
902
903static void
904
905pythonNotationDecl(void *user_data,
906 const xmlChar * name,
907 const xmlChar * publicId, const xmlChar * systemId)
908{
909 PyObject *handler;
910 PyObject *result;
911
912 handler = (PyObject *) user_data;
Daniel Veillardd2379012002-03-15 22:24:56 +0000913 if (PyObject_HasAttrString(handler, (char *) "notationDecl")) {
914 result = PyObject_CallMethod(handler, (char *) "notationDecl",
915 (char *) "sss", name, publicId,
916 systemId);
917 if (PyErr_Occurred())
918 PyErr_Print();
Daniel Veillard33caa0b2002-02-04 14:07:26 +0000919 Py_XDECREF(result);
920 }
921}
922
923static void
924pythonAttributeDecl(void *user_data,
925 const xmlChar * elem,
926 const xmlChar * name,
927 int type,
928 int def,
Daniel Veillardd2379012002-03-15 22:24:56 +0000929 const xmlChar * defaultValue, xmlEnumerationPtr tree)
Daniel Veillard33caa0b2002-02-04 14:07:26 +0000930{
931 PyObject *handler;
932 PyObject *nameList;
933 PyObject *newName;
934 xmlEnumerationPtr node;
935 PyObject *result;
936 int count;
937
938 handler = (PyObject *) user_data;
Daniel Veillardd2379012002-03-15 22:24:56 +0000939 if (PyObject_HasAttrString(handler, (char *) "attributeDecl")) {
Daniel Veillard33caa0b2002-02-04 14:07:26 +0000940 count = 0;
941 for (node = tree; node != NULL; node = node->next) {
942 count++;
943 }
944 nameList = PyList_New(count);
945 count = 0;
946 for (node = tree; node != NULL; node = node->next) {
Daniel Veillardd2379012002-03-15 22:24:56 +0000947 newName = PyString_FromString((char *) node->name);
Daniel Veillard33caa0b2002-02-04 14:07:26 +0000948 PyList_SetItem(nameList, count, newName);
949 count++;
950 }
Daniel Veillardd2379012002-03-15 22:24:56 +0000951 result = PyObject_CallMethod(handler, (char *) "attributeDecl",
952 (char *) "ssiisO", elem, name, type,
953 def, defaultValue, nameList);
954 if (PyErr_Occurred())
955 PyErr_Print();
Daniel Veillard33caa0b2002-02-04 14:07:26 +0000956 Py_XDECREF(nameList);
957 Py_XDECREF(result);
958 }
959}
960
961static void
962pythonElementDecl(void *user_data,
963 const xmlChar * name,
Daniel Veillardd2379012002-03-15 22:24:56 +0000964 int type, ATTRIBUTE_UNUSED xmlElementContentPtr content)
Daniel Veillard33caa0b2002-02-04 14:07:26 +0000965{
966 PyObject *handler;
967 PyObject *obj;
968 PyObject *result;
969
970 handler = (PyObject *) user_data;
Daniel Veillardd2379012002-03-15 22:24:56 +0000971 if (PyObject_HasAttrString(handler, (char *) "elementDecl")) {
972 /* TODO: wrap in an elementContent object */
973 printf
974 ("pythonElementDecl: xmlElementContentPtr wrapper missing !\n");
975 obj = Py_None;
976 /* Py_XINCREF(Py_None); isn't the reference just borrowed ??? */
977 result = PyObject_CallMethod(handler, (char *) "elementDecl",
978 (char *) "siO", name, type, obj);
979 if (PyErr_Occurred())
980 PyErr_Print();
Daniel Veillard33caa0b2002-02-04 14:07:26 +0000981 Py_XDECREF(result);
982 }
983}
984
985static void
986pythonUnparsedEntityDecl(void *user_data,
987 const xmlChar * name,
988 const xmlChar * publicId,
989 const xmlChar * systemId,
990 const xmlChar * notationName)
991{
992 PyObject *handler;
993 PyObject *result;
994
995 handler = (PyObject *) user_data;
Daniel Veillardd2379012002-03-15 22:24:56 +0000996 if (PyObject_HasAttrString(handler, (char *) "unparsedEntityDecl")) {
997 result =
998 PyObject_CallMethod(handler, (char *) "unparsedEntityDecl",
999 (char *) "ssss", name, publicId, systemId,
1000 notationName);
1001 if (PyErr_Occurred())
1002 PyErr_Print();
Daniel Veillard33caa0b2002-02-04 14:07:26 +00001003 Py_XDECREF(result);
1004 }
1005}
1006
1007static void
1008pythonInternalSubset(void *user_data, const xmlChar * name,
1009 const xmlChar * ExternalID, const xmlChar * SystemID)
1010{
1011 PyObject *handler;
1012 PyObject *result;
1013
Daniel Veillard797a5652002-02-12 13:46:21 +00001014#ifdef DEBUG_SAX
1015 printf("pythonInternalSubset(%s, %s, %s) called\n",
Daniel Veillardd2379012002-03-15 22:24:56 +00001016 name, ExternalID, SystemID);
Daniel Veillard797a5652002-02-12 13:46:21 +00001017#endif
Daniel Veillard33caa0b2002-02-04 14:07:26 +00001018 handler = (PyObject *) user_data;
Daniel Veillardd2379012002-03-15 22:24:56 +00001019 if (PyObject_HasAttrString(handler, (char *) "internalSubset")) {
1020 result = PyObject_CallMethod(handler, (char *) "internalSubset",
1021 (char *) "sss", name, ExternalID,
1022 SystemID);
1023 if (PyErr_Occurred())
1024 PyErr_Print();
Daniel Veillard33caa0b2002-02-04 14:07:26 +00001025 Py_XDECREF(result);
1026 }
1027}
1028
1029static xmlSAXHandler pythonSaxHandler = {
1030 pythonInternalSubset,
Daniel Veillardd2379012002-03-15 22:24:56 +00001031 NULL, /* TODO pythonIsStandalone, */
1032 NULL, /* TODO pythonHasInternalSubset, */
1033 NULL, /* TODO pythonHasExternalSubset, */
1034 NULL, /* TODO pythonResolveEntity, */
1035 NULL, /* TODO pythonGetEntity, */
Daniel Veillard33caa0b2002-02-04 14:07:26 +00001036 pythonEntityDecl,
1037 pythonNotationDecl,
1038 pythonAttributeDecl,
1039 pythonElementDecl,
1040 pythonUnparsedEntityDecl,
Daniel Veillardd2379012002-03-15 22:24:56 +00001041 NULL, /* OBSOLETED pythonSetDocumentLocator, */
Daniel Veillard33caa0b2002-02-04 14:07:26 +00001042 pythonStartDocument,
1043 pythonEndDocument,
1044 pythonStartElement,
1045 pythonEndElement,
1046 pythonReference,
1047 pythonCharacters,
1048 pythonIgnorableWhitespace,
1049 pythonProcessingInstruction,
1050 pythonComment,
1051 pythonWarning,
1052 pythonError,
1053 pythonFatalError,
Daniel Veillardd2379012002-03-15 22:24:56 +00001054 NULL, /* TODO pythonGetParameterEntity, */
Daniel Veillard33caa0b2002-02-04 14:07:26 +00001055 pythonCdataBlock,
1056 pythonExternalSubset,
1057 1
1058};
Daniel Veillard3ce52572002-02-03 15:08:05 +00001059
1060/************************************************************************
1061 * *
1062 * Handling of specific parser context *
1063 * *
1064 ************************************************************************/
Daniel Veillardd2897fd2002-01-30 16:37:32 +00001065
1066PyObject *
Daniel Veillardd2379012002-03-15 22:24:56 +00001067libxml_xmlCreatePushParser(ATTRIBUTE_UNUSED PyObject * self,
1068 PyObject * args)
1069{
1070 const char *chunk;
Daniel Veillard3ce52572002-02-03 15:08:05 +00001071 int size;
Daniel Veillardd2379012002-03-15 22:24:56 +00001072 const char *URI;
Daniel Veillard33caa0b2002-02-04 14:07:26 +00001073 PyObject *pyobj_SAX = NULL;
Daniel Veillard3ce52572002-02-03 15:08:05 +00001074 xmlSAXHandlerPtr SAX = NULL;
Daniel Veillard3ce52572002-02-03 15:08:05 +00001075 xmlParserCtxtPtr ret;
1076 PyObject *pyret;
Daniel Veillard96fe0952002-01-30 20:52:23 +00001077
Daniel Veillardd2379012002-03-15 22:24:56 +00001078 if (!PyArg_ParseTuple
1079 (args, (char *) "Oziz:xmlCreatePushParser", &pyobj_SAX, &chunk,
1080 &size, &URI))
1081 return (NULL);
Daniel Veillard3ce52572002-02-03 15:08:05 +00001082
Daniel Veillard8d24cc12002-03-05 15:41:29 +00001083#ifdef DEBUG
Daniel Veillard3ce52572002-02-03 15:08:05 +00001084 printf("libxml_xmlCreatePushParser(%p, %s, %d, %s) called\n",
Daniel Veillardd2379012002-03-15 22:24:56 +00001085 pyobj_SAX, chunk, size, URI);
Daniel Veillard96fe0952002-01-30 20:52:23 +00001086#endif
Daniel Veillard3ce52572002-02-03 15:08:05 +00001087 if (pyobj_SAX != Py_None) {
Daniel Veillardd2379012002-03-15 22:24:56 +00001088 SAX = &pythonSaxHandler;
1089 Py_INCREF(pyobj_SAX);
1090 /* The reference is released in pythonEndDocument() */
Daniel Veillardd2897fd2002-01-30 16:37:32 +00001091 }
Daniel Veillard33caa0b2002-02-04 14:07:26 +00001092 ret = xmlCreatePushParserCtxt(SAX, pyobj_SAX, chunk, size, URI);
Daniel Veillard3ce52572002-02-03 15:08:05 +00001093 pyret = libxml_xmlParserCtxtPtrWrap(ret);
Daniel Veillardd2379012002-03-15 22:24:56 +00001094 return (pyret);
Daniel Veillarda7340c82002-02-01 17:56:45 +00001095}
Daniel Veillard5d819032002-02-02 21:49:17 +00001096
Daniel Veillard4e1b26c2002-02-03 20:13:06 +00001097PyObject *
Daniel Veillardd2379012002-03-15 22:24:56 +00001098libxml_htmlCreatePushParser(ATTRIBUTE_UNUSED PyObject * self,
1099 PyObject * args)
1100{
1101 const char *chunk;
Daniel Veillard4e1b26c2002-02-03 20:13:06 +00001102 int size;
Daniel Veillardd2379012002-03-15 22:24:56 +00001103 const char *URI;
Daniel Veillard33caa0b2002-02-04 14:07:26 +00001104 PyObject *pyobj_SAX = NULL;
Daniel Veillard4e1b26c2002-02-03 20:13:06 +00001105 xmlSAXHandlerPtr SAX = NULL;
Daniel Veillard4e1b26c2002-02-03 20:13:06 +00001106 xmlParserCtxtPtr ret;
1107 PyObject *pyret;
1108
Daniel Veillardd2379012002-03-15 22:24:56 +00001109 if (!PyArg_ParseTuple
1110 (args, (char *) "Oziz:htmlCreatePushParser", &pyobj_SAX, &chunk,
1111 &size, &URI))
1112 return (NULL);
Daniel Veillard4e1b26c2002-02-03 20:13:06 +00001113
Daniel Veillard8d24cc12002-03-05 15:41:29 +00001114#ifdef DEBUG
Daniel Veillard4e1b26c2002-02-03 20:13:06 +00001115 printf("libxml_htmlCreatePushParser(%p, %s, %d, %s) called\n",
Daniel Veillardd2379012002-03-15 22:24:56 +00001116 pyobj_SAX, chunk, size, URI);
Daniel Veillard4e1b26c2002-02-03 20:13:06 +00001117#endif
1118 if (pyobj_SAX != Py_None) {
Daniel Veillardd2379012002-03-15 22:24:56 +00001119 SAX = &pythonSaxHandler;
1120 Py_INCREF(pyobj_SAX);
1121 /* The reference is released in pythonEndDocument() */
Daniel Veillard4e1b26c2002-02-03 20:13:06 +00001122 }
Daniel Veillard33caa0b2002-02-04 14:07:26 +00001123 ret = htmlCreatePushParserCtxt(SAX, pyobj_SAX, chunk, size, URI,
Daniel Veillardd2379012002-03-15 22:24:56 +00001124 XML_CHAR_ENCODING_NONE);
Daniel Veillard4e1b26c2002-02-03 20:13:06 +00001125 pyret = libxml_xmlParserCtxtPtrWrap(ret);
Daniel Veillardd2379012002-03-15 22:24:56 +00001126 return (pyret);
Daniel Veillard4e1b26c2002-02-03 20:13:06 +00001127}
1128
Daniel Veillard8d24cc12002-03-05 15:41:29 +00001129PyObject *
Daniel Veillardd2379012002-03-15 22:24:56 +00001130libxml_xmlSAXParseFile(ATTRIBUTE_UNUSED PyObject * self, PyObject * args)
1131{
Daniel Veillard8d24cc12002-03-05 15:41:29 +00001132 int recover;
Daniel Veillardd2379012002-03-15 22:24:56 +00001133 const char *URI;
Daniel Veillard8d24cc12002-03-05 15:41:29 +00001134 PyObject *pyobj_SAX = NULL;
1135 xmlSAXHandlerPtr SAX = NULL;
1136
Daniel Veillardd2379012002-03-15 22:24:56 +00001137 if (!PyArg_ParseTuple(args, (char *) "Osi:xmlSAXParseFile", &pyobj_SAX,
1138 &URI, &recover))
1139 return (NULL);
Daniel Veillard8d24cc12002-03-05 15:41:29 +00001140
1141#ifdef DEBUG
1142 printf("libxml_xmlSAXParseFile(%p, %s, %d) called\n",
Daniel Veillardd2379012002-03-15 22:24:56 +00001143 pyobj_SAX, URI, recover);
Daniel Veillard8d24cc12002-03-05 15:41:29 +00001144#endif
1145 if (pyobj_SAX == Py_None) {
Daniel Veillardd2379012002-03-15 22:24:56 +00001146 Py_INCREF(Py_None);
1147 return (Py_None);
Daniel Veillard8d24cc12002-03-05 15:41:29 +00001148 }
1149 SAX = &pythonSaxHandler;
1150 Py_INCREF(pyobj_SAX);
1151 /* The reference is released in pythonEndDocument() */
1152 xmlSAXParseFileWithData(SAX, URI, recover, pyobj_SAX);
1153 Py_INCREF(Py_None);
Daniel Veillardd2379012002-03-15 22:24:56 +00001154 return (Py_None);
Daniel Veillard8d24cc12002-03-05 15:41:29 +00001155}
1156
1157PyObject *
Daniel Veillardd2379012002-03-15 22:24:56 +00001158libxml_htmlSAXParseFile(ATTRIBUTE_UNUSED PyObject * self, PyObject * args)
1159{
1160 const char *URI;
1161 const char *encoding;
Daniel Veillard8d24cc12002-03-05 15:41:29 +00001162 PyObject *pyobj_SAX = NULL;
1163 xmlSAXHandlerPtr SAX = NULL;
1164
Daniel Veillardd2379012002-03-15 22:24:56 +00001165 if (!PyArg_ParseTuple
1166 (args, (char *) "Osz:htmlSAXParseFile", &pyobj_SAX, &URI,
1167 &encoding))
1168 return (NULL);
Daniel Veillard8d24cc12002-03-05 15:41:29 +00001169
1170#ifdef DEBUG
1171 printf("libxml_htmlSAXParseFile(%p, %s, %s) called\n",
Daniel Veillardd2379012002-03-15 22:24:56 +00001172 pyobj_SAX, URI, encoding);
Daniel Veillard8d24cc12002-03-05 15:41:29 +00001173#endif
1174 if (pyobj_SAX == Py_None) {
Daniel Veillardd2379012002-03-15 22:24:56 +00001175 Py_INCREF(Py_None);
1176 return (Py_None);
Daniel Veillard8d24cc12002-03-05 15:41:29 +00001177 }
1178 SAX = &pythonSaxHandler;
1179 Py_INCREF(pyobj_SAX);
1180 /* The reference is released in pythonEndDocument() */
1181 htmlSAXParseFile(URI, encoding, SAX, pyobj_SAX);
1182 Py_INCREF(Py_None);
Daniel Veillardd2379012002-03-15 22:24:56 +00001183 return (Py_None);
Daniel Veillard8d24cc12002-03-05 15:41:29 +00001184}
1185
Daniel Veillard5d819032002-02-02 21:49:17 +00001186/************************************************************************
1187 * *
1188 * Error message callback *
1189 * *
1190 ************************************************************************/
1191
1192static PyObject *libxml_xmlPythonErrorFuncHandler = NULL;
1193static PyObject *libxml_xmlPythonErrorFuncCtxt = NULL;
1194
Daniel Veillarde6227e02003-01-14 11:42:39 +00001195/* helper to build a xmlMalloc'ed string from a format and va_list */
1196static char *
1197libxml_buildMessage(const char *msg, va_list ap)
Daniel Veillardd2379012002-03-15 22:24:56 +00001198{
1199 int size;
1200 int chars;
1201 char *larger;
Daniel Veillarde6227e02003-01-14 11:42:39 +00001202 char *str;
1203
1204 str = (char *) xmlMalloc(150);
1205 if (str == NULL)
1206 return NULL;
1207
1208 size = 150;
1209
1210 while (1) {
1211 chars = vsnprintf(str, size, msg, ap);
1212 if ((chars > -1) && (chars < size))
1213 break;
1214 if (chars > -1)
1215 size += chars + 1;
1216 else
1217 size += 100;
1218 if ((larger = (char *) xmlRealloc(str, size)) == NULL) {
1219 xmlFree(str);
1220 return NULL;
1221 }
1222 str = larger;
1223 }
1224
1225 return str;
1226}
1227
1228static void
1229libxml_xmlErrorFuncHandler(ATTRIBUTE_UNUSED void *ctx, const char *msg,
1230 ...)
1231{
Daniel Veillardd2379012002-03-15 22:24:56 +00001232 va_list ap;
1233 char *str;
Daniel Veillard5d819032002-02-02 21:49:17 +00001234 PyObject *list;
1235 PyObject *message;
1236 PyObject *result;
1237
1238#ifdef DEBUG_ERROR
1239 printf("libxml_xmlErrorFuncHandler(%p, %s, ...) called\n", ctx, msg);
1240#endif
1241
1242
1243 if (libxml_xmlPythonErrorFuncHandler == NULL) {
Daniel Veillardd2379012002-03-15 22:24:56 +00001244 va_start(ap, msg);
1245 vfprintf(stdout, msg, ap);
1246 va_end(ap);
Daniel Veillard5d819032002-02-02 21:49:17 +00001247 } else {
Daniel Veillarde6227e02003-01-14 11:42:39 +00001248 va_start(ap, msg);
1249 str = libxml_buildMessage(msg,ap);
1250 va_end(ap);
Daniel Veillard5d819032002-02-02 21:49:17 +00001251
Daniel Veillardd2379012002-03-15 22:24:56 +00001252 list = PyTuple_New(2);
1253 PyTuple_SetItem(list, 0, libxml_xmlPythonErrorFuncCtxt);
1254 Py_XINCREF(libxml_xmlPythonErrorFuncCtxt);
1255 message = libxml_charPtrWrap(str);
1256 PyTuple_SetItem(list, 1, message);
1257 result = PyEval_CallObject(libxml_xmlPythonErrorFuncHandler, list);
1258 Py_XDECREF(list);
1259 Py_XDECREF(result);
Daniel Veillard5d819032002-02-02 21:49:17 +00001260 }
1261}
1262
1263static void
Daniel Veillardd2379012002-03-15 22:24:56 +00001264libxml_xmlErrorInitialize(void)
1265{
Daniel Veillard5d819032002-02-02 21:49:17 +00001266#ifdef DEBUG_ERROR
1267 printf("libxml_xmlErrorInitialize() called\n");
1268#endif
1269 xmlSetGenericErrorFunc(NULL, libxml_xmlErrorFuncHandler);
Daniel Veillard781ac8b2003-05-15 22:11:36 +00001270 xmlThrDefSetGenericErrorFunc(NULL, libxml_xmlErrorFuncHandler);
Daniel Veillard5d819032002-02-02 21:49:17 +00001271}
1272
1273PyObject *
Daniel Veillardd2379012002-03-15 22:24:56 +00001274libxml_xmlRegisterErrorHandler(ATTRIBUTE_UNUSED PyObject * self,
1275 PyObject * args)
1276{
Daniel Veillard5d819032002-02-02 21:49:17 +00001277 PyObject *py_retval;
1278 PyObject *pyobj_f;
1279 PyObject *pyobj_ctx;
1280
Daniel Veillardd2379012002-03-15 22:24:56 +00001281 if (!PyArg_ParseTuple
1282 (args, (char *) "OO:xmlRegisterErrorHandler", &pyobj_f,
1283 &pyobj_ctx))
1284 return (NULL);
Daniel Veillard5d819032002-02-02 21:49:17 +00001285
1286#ifdef DEBUG_ERROR
Daniel Veillardd2379012002-03-15 22:24:56 +00001287 printf("libxml_registerXPathFunction(%p, %p) called\n", pyobj_ctx,
1288 pyobj_f);
Daniel Veillard5d819032002-02-02 21:49:17 +00001289#endif
1290
1291 if (libxml_xmlPythonErrorFuncHandler != NULL) {
Daniel Veillardd2379012002-03-15 22:24:56 +00001292 Py_XDECREF(libxml_xmlPythonErrorFuncHandler);
Daniel Veillard5d819032002-02-02 21:49:17 +00001293 }
1294 if (libxml_xmlPythonErrorFuncCtxt != NULL) {
Daniel Veillardd2379012002-03-15 22:24:56 +00001295 Py_XDECREF(libxml_xmlPythonErrorFuncCtxt);
Daniel Veillard5d819032002-02-02 21:49:17 +00001296 }
1297
1298 Py_XINCREF(pyobj_ctx);
1299 Py_XINCREF(pyobj_f);
1300
1301 /* TODO: check f is a function ! */
1302 libxml_xmlPythonErrorFuncHandler = pyobj_f;
1303 libxml_xmlPythonErrorFuncCtxt = pyobj_ctx;
1304
1305 py_retval = libxml_intWrap(1);
Daniel Veillardd2379012002-03-15 22:24:56 +00001306 return (py_retval);
Daniel Veillard5d819032002-02-02 21:49:17 +00001307}
Daniel Veillardd2379012002-03-15 22:24:56 +00001308
Daniel Veillarde6227e02003-01-14 11:42:39 +00001309
1310/************************************************************************
1311 * *
1312 * Per parserCtxt error handler *
1313 * *
1314 ************************************************************************/
1315
Daniel Veillard417be3a2003-01-20 21:26:34 +00001316typedef struct
Daniel Veillarde6227e02003-01-14 11:42:39 +00001317{
Daniel Veillard417be3a2003-01-20 21:26:34 +00001318 PyObject *f;
1319 PyObject *arg;
1320} xmlParserCtxtPyCtxt;
1321typedef xmlParserCtxtPyCtxt *xmlParserCtxtPyCtxtPtr;
1322
1323static void
1324libxml_xmlParserCtxtGenericErrorFuncHandler(void *ctx, int severity, char *str)
1325{
Daniel Veillarde6227e02003-01-14 11:42:39 +00001326 PyObject *list;
Daniel Veillarde6227e02003-01-14 11:42:39 +00001327 PyObject *result;
Daniel Veillard417be3a2003-01-20 21:26:34 +00001328 xmlParserCtxtPtr ctxt;
Daniel Veillarde6227e02003-01-14 11:42:39 +00001329 xmlParserCtxtPyCtxtPtr pyCtxt;
1330
1331#ifdef DEBUG_ERROR
Daniel Veillard417be3a2003-01-20 21:26:34 +00001332 printf("libxml_xmlParserCtxtGenericErrorFuncHandler(%p, %s, ...) called\n", ctx, msg);
Daniel Veillarde6227e02003-01-14 11:42:39 +00001333#endif
1334
Daniel Veillard417be3a2003-01-20 21:26:34 +00001335 ctxt = (xmlParserCtxtPtr)ctx;
1336 pyCtxt = (xmlParserCtxtPyCtxtPtr)ctxt->_private;
Daniel Veillarde6227e02003-01-14 11:42:39 +00001337
Daniel Veillard417be3a2003-01-20 21:26:34 +00001338 list = PyTuple_New(4);
1339 PyTuple_SetItem(list, 0, pyCtxt->arg);
1340 Py_XINCREF(pyCtxt->arg);
1341 PyTuple_SetItem(list, 1, libxml_charPtrWrap(str));
1342 PyTuple_SetItem(list, 2, libxml_intWrap(severity));
1343 PyTuple_SetItem(list, 3, Py_None);
1344 Py_INCREF(Py_None);
1345 result = PyEval_CallObject(pyCtxt->f, list);
1346 if (result == NULL)
1347 {
1348 /* TODO: manage for the exception to be propagated... */
1349 PyErr_Print();
Daniel Veillarde6227e02003-01-14 11:42:39 +00001350 }
Daniel Veillard417be3a2003-01-20 21:26:34 +00001351 Py_XDECREF(list);
1352 Py_XDECREF(result);
1353}
1354
1355static void
1356libxml_xmlParserCtxtErrorFuncHandler(void *ctx, const char *msg, ...)
1357{
1358 va_list ap;
1359
1360 va_start(ap, msg);
1361 libxml_xmlParserCtxtGenericErrorFuncHandler(ctx,XML_PARSER_SEVERITY_ERROR,libxml_buildMessage(msg,ap));
1362 va_end(ap);
1363}
1364
1365static void
1366libxml_xmlParserCtxtWarningFuncHandler(void *ctx, const char *msg, ...)
1367{
1368 va_list ap;
1369
1370 va_start(ap, msg);
1371 libxml_xmlParserCtxtGenericErrorFuncHandler(ctx,XML_PARSER_SEVERITY_WARNING,libxml_buildMessage(msg,ap));
1372 va_end(ap);
1373}
1374
1375static void
1376libxml_xmlParserCtxtValidityErrorFuncHandler(void *ctx, const char *msg, ...)
1377{
1378 va_list ap;
1379
1380 va_start(ap, msg);
1381 libxml_xmlParserCtxtGenericErrorFuncHandler(ctx,XML_PARSER_SEVERITY_VALIDITY_ERROR,libxml_buildMessage(msg,ap));
1382 va_end(ap);
1383}
1384
1385static void
1386libxml_xmlParserCtxtValidityWarningFuncHandler(void *ctx, const char *msg, ...)
1387{
1388 va_list ap;
1389
1390 va_start(ap, msg);
1391 libxml_xmlParserCtxtGenericErrorFuncHandler(ctx,XML_PARSER_SEVERITY_VALIDITY_WARNING,libxml_buildMessage(msg,ap));
1392 va_end(ap);
Daniel Veillarde6227e02003-01-14 11:42:39 +00001393}
1394
1395PyObject *
Daniel Veillard417be3a2003-01-20 21:26:34 +00001396libxml_xmlParserCtxtSetErrorHandler(ATTRIBUTE_UNUSED PyObject *self, PyObject *args)
Daniel Veillarde6227e02003-01-14 11:42:39 +00001397{
1398 PyObject *py_retval;
1399 xmlParserCtxtPtr ctxt;
Daniel Veillarde4a07e72003-01-14 14:40:25 +00001400 xmlParserCtxtPyCtxtPtr pyCtxt;
Daniel Veillarde6227e02003-01-14 11:42:39 +00001401 PyObject *pyobj_ctxt;
1402 PyObject *pyobj_f;
1403 PyObject *pyobj_arg;
1404
Daniel Veillard417be3a2003-01-20 21:26:34 +00001405 if (!PyArg_ParseTuple(args, (char *)"OOO:xmlParserCtxtSetErrorHandler",
Daniel Veillarde6227e02003-01-14 11:42:39 +00001406 &pyobj_ctxt, &pyobj_f, &pyobj_arg))
1407 return(NULL);
1408 ctxt = (xmlParserCtxtPtr) PyparserCtxt_Get(pyobj_ctxt);
1409 if (ctxt->_private == NULL) {
Daniel Veillarde6227e02003-01-14 11:42:39 +00001410 pyCtxt = xmlMalloc(sizeof(xmlParserCtxtPyCtxt));
1411 if (pyCtxt == NULL) {
1412 py_retval = libxml_intWrap(-1);
1413 return(py_retval);
1414 }
1415 memset(pyCtxt,0,sizeof(xmlParserCtxtPyCtxt));
1416 ctxt->_private = pyCtxt;
1417 }
Daniel Veillarde4a07e72003-01-14 14:40:25 +00001418 else {
Daniel Veillard417be3a2003-01-20 21:26:34 +00001419 pyCtxt = (xmlParserCtxtPyCtxtPtr)ctxt->_private;
Daniel Veillarde4a07e72003-01-14 14:40:25 +00001420 }
Daniel Veillarde6227e02003-01-14 11:42:39 +00001421 /* TODO: check f is a function ! */
Daniel Veillard417be3a2003-01-20 21:26:34 +00001422 Py_XDECREF(pyCtxt->f);
Daniel Veillarde6227e02003-01-14 11:42:39 +00001423 Py_XINCREF(pyobj_f);
Daniel Veillard417be3a2003-01-20 21:26:34 +00001424 pyCtxt->f = pyobj_f;
1425 Py_XDECREF(pyCtxt->arg);
Daniel Veillarde6227e02003-01-14 11:42:39 +00001426 Py_XINCREF(pyobj_arg);
Daniel Veillard417be3a2003-01-20 21:26:34 +00001427 pyCtxt->arg = pyobj_arg;
Daniel Veillarde6227e02003-01-14 11:42:39 +00001428
Daniel Veillard417be3a2003-01-20 21:26:34 +00001429 if (pyobj_f != Py_None) {
1430 ctxt->sax->error = libxml_xmlParserCtxtErrorFuncHandler;
1431 ctxt->sax->warning = libxml_xmlParserCtxtWarningFuncHandler;
1432 ctxt->vctxt.error = libxml_xmlParserCtxtValidityErrorFuncHandler;
1433 ctxt->vctxt.warning = libxml_xmlParserCtxtValidityWarningFuncHandler;
1434 }
1435 else {
1436 ctxt->sax->error = xmlParserError;
1437 ctxt->vctxt.error = xmlParserValidityError;
1438 ctxt->sax->warning = xmlParserWarning;
1439 ctxt->vctxt.warning = xmlParserValidityWarning;
1440 }
Daniel Veillarde6227e02003-01-14 11:42:39 +00001441
1442 py_retval = libxml_intWrap(1);
1443 return(py_retval);
1444}
1445
Daniel Veillarde6227e02003-01-14 11:42:39 +00001446PyObject *
Daniel Veillard417be3a2003-01-20 21:26:34 +00001447libxml_xmlParserCtxtGetErrorHandler(ATTRIBUTE_UNUSED PyObject *self, PyObject *args)
Daniel Veillarde6227e02003-01-14 11:42:39 +00001448{
1449 PyObject *py_retval;
1450 xmlParserCtxtPtr ctxt;
Daniel Veillarde4a07e72003-01-14 14:40:25 +00001451 xmlParserCtxtPyCtxtPtr pyCtxt;
Daniel Veillarde6227e02003-01-14 11:42:39 +00001452 PyObject *pyobj_ctxt;
Daniel Veillarde6227e02003-01-14 11:42:39 +00001453
Daniel Veillard417be3a2003-01-20 21:26:34 +00001454 if (!PyArg_ParseTuple(args, (char *)"O:xmlParserCtxtGetErrorHandler",
1455 &pyobj_ctxt))
Daniel Veillarde6227e02003-01-14 11:42:39 +00001456 return(NULL);
1457 ctxt = (xmlParserCtxtPtr) PyparserCtxt_Get(pyobj_ctxt);
Daniel Veillard417be3a2003-01-20 21:26:34 +00001458 py_retval = PyTuple_New(2);
1459 if (ctxt->_private != NULL) {
1460 pyCtxt = (xmlParserCtxtPyCtxtPtr)ctxt->_private;
1461
1462 PyTuple_SetItem(py_retval, 0, pyCtxt->f);
1463 Py_XINCREF(pyCtxt->f);
1464 PyTuple_SetItem(py_retval, 1, pyCtxt->arg);
1465 Py_XINCREF(pyCtxt->arg);
Daniel Veillarde4a07e72003-01-14 14:40:25 +00001466 }
1467 else {
Daniel Veillard417be3a2003-01-20 21:26:34 +00001468 /* no python error handler registered */
1469 PyTuple_SetItem(py_retval, 0, Py_None);
1470 Py_XINCREF(Py_None);
1471 PyTuple_SetItem(py_retval, 1, Py_None);
1472 Py_XINCREF(Py_None);
Daniel Veillarde4a07e72003-01-14 14:40:25 +00001473 }
Daniel Veillarde6227e02003-01-14 11:42:39 +00001474 return(py_retval);
1475}
1476
Daniel Veillard417be3a2003-01-20 21:26:34 +00001477PyObject *
1478libxml_xmlFreeParserCtxt(ATTRIBUTE_UNUSED PyObject *self, PyObject *args) {
1479 xmlParserCtxtPtr ctxt;
1480 PyObject *pyobj_ctxt;
1481 xmlParserCtxtPyCtxtPtr pyCtxt;
1482
1483 if (!PyArg_ParseTuple(args, (char *)"O:xmlFreeParserCtxt", &pyobj_ctxt))
1484 return(NULL);
1485 ctxt = (xmlParserCtxtPtr) PyparserCtxt_Get(pyobj_ctxt);
1486
1487 if (ctxt != NULL) {
1488 pyCtxt = (xmlParserCtxtPyCtxtPtr)((xmlParserCtxtPtr)ctxt)->_private;
1489 if (pyCtxt) {
1490 Py_XDECREF(pyCtxt->f);
1491 Py_XDECREF(pyCtxt->arg);
1492 xmlFree(pyCtxt);
1493 }
1494 xmlFreeParserCtxt(ctxt);
1495 }
1496
1497 Py_INCREF(Py_None);
1498 return(Py_None);
1499}
1500
Daniel Veillarda7340c82002-02-01 17:56:45 +00001501/************************************************************************
1502 * *
Daniel Veillard26f70262003-01-16 22:45:08 +00001503 * Per xmlTextReader error handler *
1504 * *
1505 ************************************************************************/
1506
1507typedef struct
1508{
1509 PyObject *f;
1510 PyObject *arg;
1511} xmlTextReaderPyCtxt;
1512typedef xmlTextReaderPyCtxt *xmlTextReaderPyCtxtPtr;
1513
1514static void
1515libxml_xmlTextReaderErrorCallback(void *arg,
1516 const char *msg,
Daniel Veillard417be3a2003-01-20 21:26:34 +00001517 int severity,
1518 xmlTextReaderLocatorPtr locator)
Daniel Veillard26f70262003-01-16 22:45:08 +00001519{
1520 xmlTextReaderPyCtxt *pyCtxt = (xmlTextReaderPyCtxt *)arg;
1521 PyObject *list;
1522 PyObject *result;
1523
Daniel Veillard417be3a2003-01-20 21:26:34 +00001524 list = PyTuple_New(4);
Daniel Veillard26f70262003-01-16 22:45:08 +00001525 PyTuple_SetItem(list, 0, pyCtxt->arg);
1526 Py_XINCREF(pyCtxt->arg);
1527 PyTuple_SetItem(list, 1, libxml_charPtrConstWrap(msg));
Daniel Veillard417be3a2003-01-20 21:26:34 +00001528 PyTuple_SetItem(list, 2, libxml_intWrap(severity));
1529 PyTuple_SetItem(list, 3, libxml_xmlTextReaderLocatorPtrWrap(locator));
Daniel Veillard26f70262003-01-16 22:45:08 +00001530 result = PyEval_CallObject(pyCtxt->f, list);
1531 if (result == NULL)
1532 {
Daniel Veillard417be3a2003-01-20 21:26:34 +00001533 /* TODO: manage for the exception to be propagated... */
Daniel Veillard26f70262003-01-16 22:45:08 +00001534 PyErr_Print();
1535 }
1536 Py_XDECREF(list);
1537 Py_XDECREF(result);
1538}
1539
1540PyObject *
1541libxml_xmlTextReaderSetErrorHandler(ATTRIBUTE_UNUSED PyObject *self, PyObject *args)
1542{
1543 xmlTextReaderPtr reader;
1544 xmlTextReaderPyCtxtPtr pyCtxt;
1545 xmlTextReaderErrorFunc f;
1546 void *arg;
1547 PyObject *pyobj_reader;
1548 PyObject *pyobj_f;
1549 PyObject *pyobj_arg;
1550 PyObject *py_retval;
1551
1552 if (!PyArg_ParseTuple(args, (char *)"OOO:xmlTextReaderSetErrorHandler", &pyobj_reader, &pyobj_f, &pyobj_arg))
1553 return(NULL);
1554 reader = (xmlTextReaderPtr) PyxmlTextReader_Get(pyobj_reader);
1555 /* clear previous error handler */
1556 xmlTextReaderGetErrorHandler(reader,&f,&arg);
1557 if (arg != NULL) {
1558 if (f == libxml_xmlTextReaderErrorCallback) {
1559 /* ok, it's our error handler! */
1560 pyCtxt = (xmlTextReaderPyCtxtPtr)arg;
1561 Py_XDECREF(pyCtxt->f);
1562 Py_XDECREF(pyCtxt->arg);
1563 xmlFree(pyCtxt);
1564 }
1565 else {
1566 /*
1567 * there already an arg, and it's not ours,
1568 * there is definitely something wrong going on here...
1569 * we don't know how to free it, so we bail out...
1570 */
1571 py_retval = libxml_intWrap(-1);
1572 return(py_retval);
1573 }
1574 }
1575 xmlTextReaderSetErrorHandler(reader,NULL,NULL);
1576 /* set new error handler */
1577 if (pyobj_f != Py_None)
1578 {
1579 pyCtxt = (xmlTextReaderPyCtxtPtr)xmlMalloc(sizeof(xmlTextReaderPyCtxt));
1580 if (pyCtxt == NULL) {
1581 py_retval = libxml_intWrap(-1);
1582 return(py_retval);
1583 }
1584 Py_XINCREF(pyobj_f);
1585 pyCtxt->f = pyobj_f;
1586 Py_XINCREF(pyobj_arg);
1587 pyCtxt->arg = pyobj_arg;
1588 xmlTextReaderSetErrorHandler(reader,libxml_xmlTextReaderErrorCallback,pyCtxt);
1589 }
1590
1591 py_retval = libxml_intWrap(1);
1592 return(py_retval);
1593}
1594
1595PyObject *
1596libxml_xmlTextReaderGetErrorHandler(ATTRIBUTE_UNUSED PyObject *self, PyObject *args)
1597{
1598 xmlTextReaderPtr reader;
1599 xmlTextReaderPyCtxtPtr pyCtxt;
1600 xmlTextReaderErrorFunc f;
1601 void *arg;
1602 PyObject *pyobj_reader;
1603 PyObject *py_retval;
1604
1605 if (!PyArg_ParseTuple(args, (char *)"O:xmlTextReaderSetErrorHandler", &pyobj_reader))
1606 return(NULL);
1607 reader = (xmlTextReaderPtr) PyxmlTextReader_Get(pyobj_reader);
1608 xmlTextReaderGetErrorHandler(reader,&f,&arg);
1609 py_retval = PyTuple_New(2);
1610 if (f == libxml_xmlTextReaderErrorCallback) {
1611 /* ok, it's our error handler! */
1612 pyCtxt = (xmlTextReaderPyCtxtPtr)arg;
1613 PyTuple_SetItem(py_retval, 0, pyCtxt->f);
1614 Py_XINCREF(pyCtxt->f);
1615 PyTuple_SetItem(py_retval, 1, pyCtxt->arg);
1616 Py_XINCREF(pyCtxt->arg);
1617 }
1618 else
1619 {
1620 /* f is null or it's not our error handler */
1621 PyTuple_SetItem(py_retval, 0, Py_None);
1622 Py_XINCREF(Py_None);
1623 PyTuple_SetItem(py_retval, 1, Py_None);
1624 Py_XINCREF(Py_None);
1625 }
1626 return(py_retval);
1627}
1628
1629PyObject *
1630libxml_xmlFreeTextReader(ATTRIBUTE_UNUSED PyObject *self, PyObject *args) {
1631 xmlTextReaderPtr reader;
1632 PyObject *pyobj_reader;
1633 xmlTextReaderPyCtxtPtr pyCtxt;
1634 xmlTextReaderErrorFunc f;
1635 void *arg;
1636
1637 if (!PyArg_ParseTuple(args, (char *)"O:xmlFreeTextReader", &pyobj_reader))
1638 return(NULL);
1639 reader = (xmlTextReaderPtr) PyxmlTextReader_Get(pyobj_reader);
1640
1641 xmlTextReaderGetErrorHandler(reader,&f,&arg);
1642 if (arg != NULL) {
1643 if (f == libxml_xmlTextReaderErrorCallback) {
1644 /* ok, it's our error handler! */
1645 pyCtxt = (xmlTextReaderPyCtxtPtr)arg;
1646 Py_XDECREF(pyCtxt->f);
1647 Py_XDECREF(pyCtxt->arg);
1648 xmlFree(pyCtxt);
1649 }
1650 /*
1651 * else, something wrong happened, because the error handler is
1652 * not owned by the python bindings...
1653 */
1654 }
1655
1656 xmlFreeTextReader(reader);
1657 Py_INCREF(Py_None);
1658 return(Py_None);
1659}
1660
1661/************************************************************************
1662 * *
Daniel Veillarda7340c82002-02-01 17:56:45 +00001663 * XPath extensions *
1664 * *
1665 ************************************************************************/
1666
1667static int libxml_xpathCallbacksInitialized = 0;
1668
1669typedef struct libxml_xpathCallback {
1670 xmlXPathContextPtr ctx;
1671 xmlChar *name;
1672 xmlChar *ns_uri;
1673 PyObject *function;
1674} libxml_xpathCallback, *libxml_xpathCallbackPtr;
1675static libxml_xpathCallback libxml_xpathCallbacks[10];
1676static int libxml_xpathCallbacksNb = 0;
1677static int libxml_xpathCallbacksMax = 10;
1678
Daniel Veillarda7340c82002-02-01 17:56:45 +00001679static void
Daniel Veillardd2379012002-03-15 22:24:56 +00001680libxml_xmlXPathFuncCallback(xmlXPathParserContextPtr ctxt, int nargs)
1681{
Daniel Veillarda7340c82002-02-01 17:56:45 +00001682 PyObject *list, *cur, *result;
1683 xmlXPathObjectPtr obj;
Daniel Veillard70cab352002-02-06 16:06:58 +00001684 xmlXPathContextPtr rctxt;
1685 PyObject *current_function = NULL;
1686 const xmlChar *name;
1687 const xmlChar *ns_uri;
Daniel Veillarda7340c82002-02-01 17:56:45 +00001688 int i;
1689
Daniel Veillard70cab352002-02-06 16:06:58 +00001690 if (ctxt == NULL)
Daniel Veillardd2379012002-03-15 22:24:56 +00001691 return;
Daniel Veillard70cab352002-02-06 16:06:58 +00001692 rctxt = ctxt->context;
1693 if (rctxt == NULL)
Daniel Veillardd2379012002-03-15 22:24:56 +00001694 return;
Daniel Veillard70cab352002-02-06 16:06:58 +00001695 name = rctxt->function;
1696 ns_uri = rctxt->functionURI;
Daniel Veillarda7340c82002-02-01 17:56:45 +00001697#ifdef DEBUG_XPATH
Daniel Veillardd2379012002-03-15 22:24:56 +00001698 printf("libxml_xmlXPathFuncCallback called name %s URI %s\n", name,
1699 ns_uri);
Daniel Veillarda7340c82002-02-01 17:56:45 +00001700#endif
1701
Daniel Veillard70cab352002-02-06 16:06:58 +00001702 /*
1703 * Find the function, it should be there it was there at lookup
1704 */
Daniel Veillardd2379012002-03-15 22:24:56 +00001705 for (i = 0; i < libxml_xpathCallbacksNb; i++) {
1706 if ( /* TODO (ctxt == libxml_xpathCallbacks[i].ctx) && */
1707 (xmlStrEqual(name, libxml_xpathCallbacks[i].name)) &&
1708 (xmlStrEqual(ns_uri, libxml_xpathCallbacks[i].ns_uri))) {
1709 current_function = libxml_xpathCallbacks[i].function;
1710 }
Daniel Veillard70cab352002-02-06 16:06:58 +00001711 }
1712 if (current_function == NULL) {
Daniel Veillardd2379012002-03-15 22:24:56 +00001713 printf
1714 ("libxml_xmlXPathFuncCallback: internal error %s not found !\n",
1715 name);
1716 return;
Daniel Veillard70cab352002-02-06 16:06:58 +00001717 }
1718
Daniel Veillardc575b992002-02-08 13:28:40 +00001719 list = PyTuple_New(nargs + 1);
1720 PyTuple_SetItem(list, 0, libxml_xmlXPathParserContextPtrWrap(ctxt));
Daniel Veillardd2379012002-03-15 22:24:56 +00001721 for (i = 0; i < nargs; i++) {
1722 obj = valuePop(ctxt);
1723 cur = libxml_xmlXPathObjectPtrWrap(obj);
1724 PyTuple_SetItem(list, i + 1, cur);
Daniel Veillarda7340c82002-02-01 17:56:45 +00001725 }
1726 result = PyEval_CallObject(current_function, list);
1727 Py_DECREF(list);
1728
1729 obj = libxml_xmlXPathObjectPtrConvert(result);
1730 valuePush(ctxt, obj);
1731}
1732
1733static xmlXPathFunction
Daniel Veillardd2379012002-03-15 22:24:56 +00001734libxml_xmlXPathFuncLookupFunc(void *ctxt, const xmlChar * name,
1735 const xmlChar * ns_uri)
1736{
Daniel Veillarda7340c82002-02-01 17:56:45 +00001737 int i;
Daniel Veillardd2379012002-03-15 22:24:56 +00001738
Daniel Veillarda7340c82002-02-01 17:56:45 +00001739#ifdef DEBUG_XPATH
1740 printf("libxml_xmlXPathFuncLookupFunc(%p, %s, %s) called\n",
Daniel Veillardd2379012002-03-15 22:24:56 +00001741 ctxt, name, ns_uri);
Daniel Veillarda7340c82002-02-01 17:56:45 +00001742#endif
Daniel Veillard70cab352002-02-06 16:06:58 +00001743 /*
1744 * This is called once only. The address is then stored in the
1745 * XPath expression evaluation, the proper object to call can
1746 * then still be found using the execution context function
1747 * and functionURI fields.
1748 */
Daniel Veillardd2379012002-03-15 22:24:56 +00001749 for (i = 0; i < libxml_xpathCallbacksNb; i++) {
1750 if ((ctxt == libxml_xpathCallbacks[i].ctx) &&
1751 (xmlStrEqual(name, libxml_xpathCallbacks[i].name)) &&
1752 (xmlStrEqual(ns_uri, libxml_xpathCallbacks[i].ns_uri))) {
1753 return (libxml_xmlXPathFuncCallback);
1754 }
Daniel Veillarda7340c82002-02-01 17:56:45 +00001755 }
Daniel Veillardd2379012002-03-15 22:24:56 +00001756 return (NULL);
Daniel Veillarda7340c82002-02-01 17:56:45 +00001757}
1758
1759static void
Daniel Veillardd2379012002-03-15 22:24:56 +00001760libxml_xpathCallbacksInitialize(void)
1761{
Daniel Veillarda7340c82002-02-01 17:56:45 +00001762 int i;
1763
1764 if (libxml_xpathCallbacksInitialized != 0)
Daniel Veillardd2379012002-03-15 22:24:56 +00001765 return;
Daniel Veillarda7340c82002-02-01 17:56:45 +00001766
1767#ifdef DEBUG_XPATH
1768 printf("libxml_xpathCallbacksInitialized called\n");
1769#endif
1770
Daniel Veillard781ac8b2003-05-15 22:11:36 +00001771 for (i = 0; i < libxml_xpathCallbacksMax; i++) {
Daniel Veillardd2379012002-03-15 22:24:56 +00001772 libxml_xpathCallbacks[i].ctx = NULL;
1773 libxml_xpathCallbacks[i].name = NULL;
1774 libxml_xpathCallbacks[i].ns_uri = NULL;
1775 libxml_xpathCallbacks[i].function = NULL;
Daniel Veillarda7340c82002-02-01 17:56:45 +00001776 }
Daniel Veillarda7340c82002-02-01 17:56:45 +00001777 libxml_xpathCallbacksInitialized = 1;
1778}
1779
1780PyObject *
Daniel Veillardd2379012002-03-15 22:24:56 +00001781libxml_xmlRegisterXPathFunction(ATTRIBUTE_UNUSED PyObject * self,
1782 PyObject * args)
1783{
Daniel Veillarda7340c82002-02-01 17:56:45 +00001784 PyObject *py_retval;
1785 int c_retval = 0;
1786 xmlChar *name;
1787 xmlChar *ns_uri;
1788 xmlXPathContextPtr ctx;
1789 PyObject *pyobj_ctx;
1790 PyObject *pyobj_f;
1791 int i;
1792
Daniel Veillardd2379012002-03-15 22:24:56 +00001793 if (!PyArg_ParseTuple
1794 (args, (char *) "OszO:registerXPathFunction", &pyobj_ctx, &name,
1795 &ns_uri, &pyobj_f))
1796 return (NULL);
Daniel Veillarda7340c82002-02-01 17:56:45 +00001797
1798 ctx = (xmlXPathContextPtr) PyxmlXPathContext_Get(pyobj_ctx);
1799 if (libxml_xpathCallbacksInitialized == 0)
Daniel Veillardd2379012002-03-15 22:24:56 +00001800 libxml_xpathCallbacksInitialize();
Daniel Veillarda7340c82002-02-01 17:56:45 +00001801 xmlXPathRegisterFuncLookup(ctx, libxml_xmlXPathFuncLookupFunc, ctx);
1802
1803 if ((pyobj_ctx == NULL) || (name == NULL) || (pyobj_f == NULL)) {
Daniel Veillardd2379012002-03-15 22:24:56 +00001804 py_retval = libxml_intWrap(-1);
1805 return (py_retval);
Daniel Veillarda7340c82002-02-01 17:56:45 +00001806 }
Daniel Veillarda7340c82002-02-01 17:56:45 +00001807#ifdef DEBUG_XPATH
1808 printf("libxml_registerXPathFunction(%p, %s, %s) called\n",
Daniel Veillardd2379012002-03-15 22:24:56 +00001809 ctx, name, ns_uri);
Daniel Veillarda7340c82002-02-01 17:56:45 +00001810#endif
Daniel Veillardd2379012002-03-15 22:24:56 +00001811 for (i = 0; i < libxml_xpathCallbacksNb; i++) {
1812 if ((ctx == libxml_xpathCallbacks[i].ctx) &&
1813 (xmlStrEqual(name, libxml_xpathCallbacks[i].name)) &&
1814 (xmlStrEqual(ns_uri, libxml_xpathCallbacks[i].ns_uri))) {
1815 Py_XINCREF(pyobj_f);
1816 Py_XDECREF(libxml_xpathCallbacks[i].function);
1817 libxml_xpathCallbacks[i].function = pyobj_f;
1818 c_retval = 1;
1819 goto done;
1820 }
Daniel Veillarda7340c82002-02-01 17:56:45 +00001821 }
1822 if (libxml_xpathCallbacksNb >= libxml_xpathCallbacksMax) {
Daniel Veillardd2379012002-03-15 22:24:56 +00001823 printf("libxml_registerXPathFunction() table full\n");
Daniel Veillarda7340c82002-02-01 17:56:45 +00001824 } else {
Daniel Veillardd2379012002-03-15 22:24:56 +00001825 i = libxml_xpathCallbacksNb++;
1826 Py_XINCREF(pyobj_f);
Daniel Veillarda7340c82002-02-01 17:56:45 +00001827 libxml_xpathCallbacks[i].ctx = ctx;
1828 libxml_xpathCallbacks[i].name = xmlStrdup(name);
1829 libxml_xpathCallbacks[i].ns_uri = xmlStrdup(ns_uri);
Daniel Veillardd2379012002-03-15 22:24:56 +00001830 libxml_xpathCallbacks[i].function = pyobj_f;
1831 c_retval = 1;
Daniel Veillarda7340c82002-02-01 17:56:45 +00001832 }
Daniel Veillardd2379012002-03-15 22:24:56 +00001833 done:
Daniel Veillarda7340c82002-02-01 17:56:45 +00001834 py_retval = libxml_intWrap((int) c_retval);
Daniel Veillardd2379012002-03-15 22:24:56 +00001835 return (py_retval);
Daniel Veillarda7340c82002-02-01 17:56:45 +00001836}
1837
Daniel Veillard1971ee22002-01-31 20:29:19 +00001838/************************************************************************
1839 * *
Daniel Veillardd2897fd2002-01-30 16:37:32 +00001840 * Global properties access *
1841 * *
1842 ************************************************************************/
1843static PyObject *
Daniel Veillardd2379012002-03-15 22:24:56 +00001844libxml_name(ATTRIBUTE_UNUSED PyObject * self, PyObject * args)
Daniel Veillardd2897fd2002-01-30 16:37:32 +00001845{
1846 PyObject *resultobj, *obj;
1847 xmlNodePtr cur;
1848 const xmlChar *res;
1849
Daniel Veillardd2379012002-03-15 22:24:56 +00001850 if (!PyArg_ParseTuple(args, (char *) "O:name", &obj))
Daniel Veillardd2897fd2002-01-30 16:37:32 +00001851 return NULL;
1852 cur = PyxmlNode_Get(obj);
1853
1854#ifdef DEBUG
1855 printf("libxml_name: cur = %p type %d\n", cur, cur->type);
1856#endif
1857
Daniel Veillardd2379012002-03-15 22:24:56 +00001858 switch (cur->type) {
1859 case XML_DOCUMENT_NODE:
Daniel Veillardd2897fd2002-01-30 16:37:32 +00001860#ifdef LIBXML_DOCB_ENABLED
Daniel Veillardd2379012002-03-15 22:24:56 +00001861 case XML_DOCB_DOCUMENT_NODE:
Daniel Veillardd2897fd2002-01-30 16:37:32 +00001862#endif
Daniel Veillardd2379012002-03-15 22:24:56 +00001863 case XML_HTML_DOCUMENT_NODE:{
1864 xmlDocPtr doc = (xmlDocPtr) cur;
1865
1866 res = doc->URL;
1867 break;
1868 }
1869 case XML_ATTRIBUTE_NODE:{
1870 xmlAttrPtr attr = (xmlAttrPtr) cur;
1871
1872 res = attr->name;
1873 break;
1874 }
1875 case XML_NAMESPACE_DECL:{
1876 xmlNsPtr ns = (xmlNsPtr) cur;
1877
1878 res = ns->prefix;
1879 break;
1880 }
1881 default:
1882 res = cur->name;
1883 break;
Daniel Veillardd2897fd2002-01-30 16:37:32 +00001884 }
Daniel Veillard1971ee22002-01-31 20:29:19 +00001885 resultobj = libxml_constxmlCharPtrWrap(res);
Daniel Veillardd2897fd2002-01-30 16:37:32 +00001886
1887 return resultobj;
1888}
1889
1890static PyObject *
Daniel Veillardd2379012002-03-15 22:24:56 +00001891libxml_doc(ATTRIBUTE_UNUSED PyObject * self, PyObject * args)
Daniel Veillardd2897fd2002-01-30 16:37:32 +00001892{
1893 PyObject *resultobj, *obj;
1894 xmlNodePtr cur;
1895 xmlDocPtr res;
1896
Daniel Veillardd2379012002-03-15 22:24:56 +00001897 if (!PyArg_ParseTuple(args, (char *) "O:doc", &obj))
Daniel Veillardd2897fd2002-01-30 16:37:32 +00001898 return NULL;
1899 cur = PyxmlNode_Get(obj);
1900
1901#ifdef DEBUG
1902 printf("libxml_doc: cur = %p\n", cur);
1903#endif
1904
Daniel Veillardd2379012002-03-15 22:24:56 +00001905 switch (cur->type) {
1906 case XML_DOCUMENT_NODE:
Daniel Veillardd2897fd2002-01-30 16:37:32 +00001907#ifdef LIBXML_DOCB_ENABLED
Daniel Veillardd2379012002-03-15 22:24:56 +00001908 case XML_DOCB_DOCUMENT_NODE:
Daniel Veillardd2897fd2002-01-30 16:37:32 +00001909#endif
Daniel Veillardd2379012002-03-15 22:24:56 +00001910 case XML_HTML_DOCUMENT_NODE:
1911 res = NULL;
1912 break;
1913 case XML_ATTRIBUTE_NODE:{
1914 xmlAttrPtr attr = (xmlAttrPtr) cur;
1915
1916 res = attr->doc;
1917 break;
1918 }
1919 case XML_NAMESPACE_DECL:
1920 res = NULL;
1921 break;
1922 default:
1923 res = cur->doc;
1924 break;
Daniel Veillardd2897fd2002-01-30 16:37:32 +00001925 }
1926 resultobj = libxml_xmlDocPtrWrap(res);
1927 return resultobj;
1928}
1929
1930static PyObject *
Daniel Veillardd2379012002-03-15 22:24:56 +00001931libxml_properties(ATTRIBUTE_UNUSED PyObject * self, PyObject * args)
Daniel Veillardd2897fd2002-01-30 16:37:32 +00001932{
1933 PyObject *resultobj, *obj;
1934 xmlNodePtr cur = NULL;
1935 xmlAttrPtr res;
1936
Daniel Veillardd2379012002-03-15 22:24:56 +00001937 if (!PyArg_ParseTuple(args, (char *) "O:properties", &obj))
Daniel Veillardd2897fd2002-01-30 16:37:32 +00001938 return NULL;
1939 cur = PyxmlNode_Get(obj);
1940 if (cur->type == XML_ELEMENT_NODE)
Daniel Veillardd2379012002-03-15 22:24:56 +00001941 res = cur->properties;
Daniel Veillardd2897fd2002-01-30 16:37:32 +00001942 else
Daniel Veillardd2379012002-03-15 22:24:56 +00001943 res = NULL;
Daniel Veillardd2897fd2002-01-30 16:37:32 +00001944 resultobj = libxml_xmlAttrPtrWrap(res);
1945 return resultobj;
1946}
1947
1948static PyObject *
Daniel Veillardd2379012002-03-15 22:24:56 +00001949libxml_next(ATTRIBUTE_UNUSED PyObject * self, PyObject * args)
Daniel Veillardd2897fd2002-01-30 16:37:32 +00001950{
1951 PyObject *resultobj, *obj;
1952 xmlNodePtr cur;
1953 xmlNodePtr res;
1954
Daniel Veillardd2379012002-03-15 22:24:56 +00001955 if (!PyArg_ParseTuple(args, (char *) "O:next", &obj))
Daniel Veillardd2897fd2002-01-30 16:37:32 +00001956 return NULL;
1957 cur = PyxmlNode_Get(obj);
1958
1959#ifdef DEBUG
1960 printf("libxml_next: cur = %p\n", cur);
1961#endif
1962
Daniel Veillardd2379012002-03-15 22:24:56 +00001963 switch (cur->type) {
1964 case XML_DOCUMENT_NODE:
Daniel Veillardd2897fd2002-01-30 16:37:32 +00001965#ifdef LIBXML_DOCB_ENABLED
Daniel Veillardd2379012002-03-15 22:24:56 +00001966 case XML_DOCB_DOCUMENT_NODE:
Daniel Veillardd2897fd2002-01-30 16:37:32 +00001967#endif
Daniel Veillardd2379012002-03-15 22:24:56 +00001968 case XML_HTML_DOCUMENT_NODE:
1969 res = NULL;
1970 break;
1971 case XML_ATTRIBUTE_NODE:{
1972 xmlAttrPtr attr = (xmlAttrPtr) cur;
1973
1974 res = (xmlNodePtr) attr->next;
1975 break;
1976 }
1977 case XML_NAMESPACE_DECL:{
1978 xmlNsPtr ns = (xmlNsPtr) cur;
1979
1980 res = (xmlNodePtr) ns->next;
1981 break;
1982 }
1983 default:
1984 res = cur->next;
1985 break;
Daniel Veillardd2897fd2002-01-30 16:37:32 +00001986
1987 }
1988 resultobj = libxml_xmlNodePtrWrap(res);
1989 return resultobj;
1990}
1991
1992static PyObject *
Daniel Veillardd2379012002-03-15 22:24:56 +00001993libxml_prev(ATTRIBUTE_UNUSED PyObject * self, PyObject * args)
Daniel Veillardd2897fd2002-01-30 16:37:32 +00001994{
1995 PyObject *resultobj, *obj;
1996 xmlNodePtr cur;
1997 xmlNodePtr res;
1998
Daniel Veillardd2379012002-03-15 22:24:56 +00001999 if (!PyArg_ParseTuple(args, (char *) "O:prev", &obj))
Daniel Veillardd2897fd2002-01-30 16:37:32 +00002000 return NULL;
2001 cur = PyxmlNode_Get(obj);
2002
2003#ifdef DEBUG
2004 printf("libxml_prev: cur = %p\n", cur);
2005#endif
2006
Daniel Veillardd2379012002-03-15 22:24:56 +00002007 switch (cur->type) {
2008 case XML_DOCUMENT_NODE:
Daniel Veillardd2897fd2002-01-30 16:37:32 +00002009#ifdef LIBXML_DOCB_ENABLED
Daniel Veillardd2379012002-03-15 22:24:56 +00002010 case XML_DOCB_DOCUMENT_NODE:
Daniel Veillardd2897fd2002-01-30 16:37:32 +00002011#endif
Daniel Veillardd2379012002-03-15 22:24:56 +00002012 case XML_HTML_DOCUMENT_NODE:
2013 res = NULL;
2014 break;
2015 case XML_ATTRIBUTE_NODE:{
2016 xmlAttrPtr attr = (xmlAttrPtr) cur;
2017
Daniel Veillardfaa35ff2002-11-24 13:53:43 +00002018 res = (xmlNodePtr) attr->prev;
Daniel Veillardd2379012002-03-15 22:24:56 +00002019 }
2020 case XML_NAMESPACE_DECL:
2021 res = NULL;
2022 break;
2023 default:
Daniel Veillardfaa35ff2002-11-24 13:53:43 +00002024 res = cur->prev;
Daniel Veillardd2379012002-03-15 22:24:56 +00002025 break;
Daniel Veillardd2897fd2002-01-30 16:37:32 +00002026 }
2027 resultobj = libxml_xmlNodePtrWrap(res);
2028 return resultobj;
2029}
2030
2031static PyObject *
Daniel Veillardd2379012002-03-15 22:24:56 +00002032libxml_children(ATTRIBUTE_UNUSED PyObject * self, PyObject * args)
Daniel Veillardd2897fd2002-01-30 16:37:32 +00002033{
2034 PyObject *resultobj, *obj;
2035 xmlNodePtr cur;
2036 xmlNodePtr res;
2037
Daniel Veillardd2379012002-03-15 22:24:56 +00002038 if (!PyArg_ParseTuple(args, (char *) "O:children", &obj))
Daniel Veillardd2897fd2002-01-30 16:37:32 +00002039 return NULL;
2040 cur = PyxmlNode_Get(obj);
2041
2042#ifdef DEBUG
2043 printf("libxml_children: cur = %p\n", cur);
2044#endif
2045
Daniel Veillardd2379012002-03-15 22:24:56 +00002046 switch (cur->type) {
2047 case XML_ELEMENT_NODE:
2048 case XML_ENTITY_REF_NODE:
2049 case XML_ENTITY_NODE:
2050 case XML_PI_NODE:
2051 case XML_COMMENT_NODE:
2052 case XML_DOCUMENT_NODE:
Daniel Veillardd2897fd2002-01-30 16:37:32 +00002053#ifdef LIBXML_DOCB_ENABLED
Daniel Veillardd2379012002-03-15 22:24:56 +00002054 case XML_DOCB_DOCUMENT_NODE:
Daniel Veillardd2897fd2002-01-30 16:37:32 +00002055#endif
Daniel Veillardd2379012002-03-15 22:24:56 +00002056 case XML_HTML_DOCUMENT_NODE:
2057 case XML_DTD_NODE:
2058 res = cur->children;
2059 break;
2060 case XML_ATTRIBUTE_NODE:{
2061 xmlAttrPtr attr = (xmlAttrPtr) cur;
2062
2063 res = attr->children;
2064 break;
2065 }
2066 default:
2067 res = NULL;
2068 break;
Daniel Veillardd2897fd2002-01-30 16:37:32 +00002069 }
2070 resultobj = libxml_xmlNodePtrWrap(res);
2071 return resultobj;
2072}
2073
2074static PyObject *
Daniel Veillardd2379012002-03-15 22:24:56 +00002075libxml_last(ATTRIBUTE_UNUSED PyObject * self, PyObject * args)
Daniel Veillardd2897fd2002-01-30 16:37:32 +00002076{
2077 PyObject *resultobj, *obj;
2078 xmlNodePtr cur;
2079 xmlNodePtr res;
2080
Daniel Veillardd2379012002-03-15 22:24:56 +00002081 if (!PyArg_ParseTuple(args, (char *) "O:last", &obj))
Daniel Veillardd2897fd2002-01-30 16:37:32 +00002082 return NULL;
2083 cur = PyxmlNode_Get(obj);
2084
2085#ifdef DEBUG
2086 printf("libxml_last: cur = %p\n", cur);
2087#endif
2088
Daniel Veillardd2379012002-03-15 22:24:56 +00002089 switch (cur->type) {
2090 case XML_ELEMENT_NODE:
2091 case XML_ENTITY_REF_NODE:
2092 case XML_ENTITY_NODE:
2093 case XML_PI_NODE:
2094 case XML_COMMENT_NODE:
2095 case XML_DOCUMENT_NODE:
Daniel Veillardd2897fd2002-01-30 16:37:32 +00002096#ifdef LIBXML_DOCB_ENABLED
Daniel Veillardd2379012002-03-15 22:24:56 +00002097 case XML_DOCB_DOCUMENT_NODE:
Daniel Veillardd2897fd2002-01-30 16:37:32 +00002098#endif
Daniel Veillardd2379012002-03-15 22:24:56 +00002099 case XML_HTML_DOCUMENT_NODE:
2100 case XML_DTD_NODE:
2101 res = cur->last;
2102 break;
2103 case XML_ATTRIBUTE_NODE:{
2104 xmlAttrPtr attr = (xmlAttrPtr) cur;
2105
2106 res = attr->last;
2107 }
2108 default:
2109 res = NULL;
2110 break;
Daniel Veillardd2897fd2002-01-30 16:37:32 +00002111 }
2112 resultobj = libxml_xmlNodePtrWrap(res);
2113 return resultobj;
2114}
2115
2116static PyObject *
Daniel Veillardd2379012002-03-15 22:24:56 +00002117libxml_parent(ATTRIBUTE_UNUSED PyObject * self, PyObject * args)
Daniel Veillardd2897fd2002-01-30 16:37:32 +00002118{
2119 PyObject *resultobj, *obj;
2120 xmlNodePtr cur;
2121 xmlNodePtr res;
2122
Daniel Veillardd2379012002-03-15 22:24:56 +00002123 if (!PyArg_ParseTuple(args, (char *) "O:parent", &obj))
Daniel Veillardd2897fd2002-01-30 16:37:32 +00002124 return NULL;
2125 cur = PyxmlNode_Get(obj);
2126
2127#ifdef DEBUG
2128 printf("libxml_parent: cur = %p\n", cur);
2129#endif
2130
Daniel Veillardd2379012002-03-15 22:24:56 +00002131 switch (cur->type) {
2132 case XML_DOCUMENT_NODE:
2133 case XML_HTML_DOCUMENT_NODE:
Daniel Veillardd2897fd2002-01-30 16:37:32 +00002134#ifdef LIBXML_DOCB_ENABLED
Daniel Veillardd2379012002-03-15 22:24:56 +00002135 case XML_DOCB_DOCUMENT_NODE:
Daniel Veillardd2897fd2002-01-30 16:37:32 +00002136#endif
Daniel Veillardd2379012002-03-15 22:24:56 +00002137 res = NULL;
2138 break;
2139 case XML_ATTRIBUTE_NODE:{
2140 xmlAttrPtr attr = (xmlAttrPtr) cur;
2141
2142 res = attr->parent;
2143 }
2144 case XML_ENTITY_DECL:
2145 case XML_NAMESPACE_DECL:
2146 case XML_XINCLUDE_START:
2147 case XML_XINCLUDE_END:
2148 res = NULL;
2149 break;
2150 default:
2151 res = cur->parent;
2152 break;
Daniel Veillardd2897fd2002-01-30 16:37:32 +00002153 }
2154 resultobj = libxml_xmlNodePtrWrap(res);
2155 return resultobj;
2156}
2157
2158static PyObject *
Daniel Veillardd2379012002-03-15 22:24:56 +00002159libxml_type(ATTRIBUTE_UNUSED PyObject * self, PyObject * args)
Daniel Veillardd2897fd2002-01-30 16:37:32 +00002160{
2161 PyObject *resultobj, *obj;
2162 xmlNodePtr cur;
Daniel Veillardd2379012002-03-15 22:24:56 +00002163 const xmlChar *res = NULL;
Daniel Veillardd2897fd2002-01-30 16:37:32 +00002164
Daniel Veillardd2379012002-03-15 22:24:56 +00002165 if (!PyArg_ParseTuple(args, (char *) "O:last", &obj))
Daniel Veillardd2897fd2002-01-30 16:37:32 +00002166 return NULL;
2167 cur = PyxmlNode_Get(obj);
2168
2169#ifdef DEBUG
2170 printf("libxml_type: cur = %p\n", cur);
2171#endif
2172
Daniel Veillardd2379012002-03-15 22:24:56 +00002173 switch (cur->type) {
Daniel Veillardd2897fd2002-01-30 16:37:32 +00002174 case XML_ELEMENT_NODE:
Daniel Veillardd2379012002-03-15 22:24:56 +00002175 res = (const xmlChar *) "element";
2176 break;
Daniel Veillardd2897fd2002-01-30 16:37:32 +00002177 case XML_ATTRIBUTE_NODE:
Daniel Veillardd2379012002-03-15 22:24:56 +00002178 res = (const xmlChar *) "attribute";
2179 break;
Daniel Veillardd2897fd2002-01-30 16:37:32 +00002180 case XML_TEXT_NODE:
Daniel Veillardd2379012002-03-15 22:24:56 +00002181 res = (const xmlChar *) "text";
2182 break;
Daniel Veillardd2897fd2002-01-30 16:37:32 +00002183 case XML_CDATA_SECTION_NODE:
Daniel Veillardd2379012002-03-15 22:24:56 +00002184 res = (const xmlChar *) "cdata";
2185 break;
Daniel Veillardd2897fd2002-01-30 16:37:32 +00002186 case XML_ENTITY_REF_NODE:
Daniel Veillardd2379012002-03-15 22:24:56 +00002187 res = (const xmlChar *) "entity_ref";
2188 break;
Daniel Veillardd2897fd2002-01-30 16:37:32 +00002189 case XML_ENTITY_NODE:
Daniel Veillardd2379012002-03-15 22:24:56 +00002190 res = (const xmlChar *) "entity";
2191 break;
Daniel Veillardd2897fd2002-01-30 16:37:32 +00002192 case XML_PI_NODE:
Daniel Veillardd2379012002-03-15 22:24:56 +00002193 res = (const xmlChar *) "pi";
2194 break;
Daniel Veillardd2897fd2002-01-30 16:37:32 +00002195 case XML_COMMENT_NODE:
Daniel Veillardd2379012002-03-15 22:24:56 +00002196 res = (const xmlChar *) "comment";
2197 break;
Daniel Veillardd2897fd2002-01-30 16:37:32 +00002198 case XML_DOCUMENT_NODE:
Daniel Veillardd2379012002-03-15 22:24:56 +00002199 res = (const xmlChar *) "document_xml";
2200 break;
Daniel Veillardd2897fd2002-01-30 16:37:32 +00002201 case XML_DOCUMENT_TYPE_NODE:
Daniel Veillardd2379012002-03-15 22:24:56 +00002202 res = (const xmlChar *) "doctype";
2203 break;
Daniel Veillardd2897fd2002-01-30 16:37:32 +00002204 case XML_DOCUMENT_FRAG_NODE:
Daniel Veillardd2379012002-03-15 22:24:56 +00002205 res = (const xmlChar *) "fragment";
2206 break;
Daniel Veillardd2897fd2002-01-30 16:37:32 +00002207 case XML_NOTATION_NODE:
Daniel Veillardd2379012002-03-15 22:24:56 +00002208 res = (const xmlChar *) "notation";
2209 break;
Daniel Veillardd2897fd2002-01-30 16:37:32 +00002210 case XML_HTML_DOCUMENT_NODE:
Daniel Veillardd2379012002-03-15 22:24:56 +00002211 res = (const xmlChar *) "document_html";
2212 break;
Daniel Veillardd2897fd2002-01-30 16:37:32 +00002213 case XML_DTD_NODE:
Daniel Veillardd2379012002-03-15 22:24:56 +00002214 res = (const xmlChar *) "dtd";
2215 break;
Daniel Veillardd2897fd2002-01-30 16:37:32 +00002216 case XML_ELEMENT_DECL:
Daniel Veillardd2379012002-03-15 22:24:56 +00002217 res = (const xmlChar *) "elem_decl";
2218 break;
Daniel Veillardd2897fd2002-01-30 16:37:32 +00002219 case XML_ATTRIBUTE_DECL:
Daniel Veillardd2379012002-03-15 22:24:56 +00002220 res = (const xmlChar *) "attribute_decl";
2221 break;
Daniel Veillardd2897fd2002-01-30 16:37:32 +00002222 case XML_ENTITY_DECL:
Daniel Veillardd2379012002-03-15 22:24:56 +00002223 res = (const xmlChar *) "entity_decl";
2224 break;
Daniel Veillardd2897fd2002-01-30 16:37:32 +00002225 case XML_NAMESPACE_DECL:
Daniel Veillardd2379012002-03-15 22:24:56 +00002226 res = (const xmlChar *) "namespace";
2227 break;
Daniel Veillardd2897fd2002-01-30 16:37:32 +00002228 case XML_XINCLUDE_START:
Daniel Veillardd2379012002-03-15 22:24:56 +00002229 res = (const xmlChar *) "xinclude_start";
2230 break;
Daniel Veillardd2897fd2002-01-30 16:37:32 +00002231 case XML_XINCLUDE_END:
Daniel Veillardd2379012002-03-15 22:24:56 +00002232 res = (const xmlChar *) "xinclude_end";
2233 break;
Daniel Veillardd2897fd2002-01-30 16:37:32 +00002234#ifdef LIBXML_DOCB_ENABLED
Daniel Veillardd2379012002-03-15 22:24:56 +00002235 case XML_DOCB_DOCUMENT_NODE:
2236 res = (const xmlChar *) "document_docbook";
2237 break;
Daniel Veillardd2897fd2002-01-30 16:37:32 +00002238#endif
2239 }
2240#ifdef DEBUG
2241 printf("libxml_type: cur = %p: %s\n", cur, res);
2242#endif
2243
Daniel Veillard1971ee22002-01-31 20:29:19 +00002244 resultobj = libxml_constxmlCharPtrWrap(res);
Daniel Veillardd2897fd2002-01-30 16:37:32 +00002245 return resultobj;
2246}
2247
2248/************************************************************************
2249 * *
Daniel Veillard36eea2d2002-02-04 00:17:01 +00002250 * Specific accessor functions *
2251 * *
2252 ************************************************************************/
2253PyObject *
Daniel Veillardd2379012002-03-15 22:24:56 +00002254libxml_xmlNodeGetNsDefs(ATTRIBUTE_UNUSED PyObject * self, PyObject * args)
2255{
Daniel Veillard36eea2d2002-02-04 00:17:01 +00002256 PyObject *py_retval;
2257 xmlNsPtr c_retval;
2258 xmlNodePtr node;
2259 PyObject *pyobj_node;
2260
Daniel Veillardd2379012002-03-15 22:24:56 +00002261 if (!PyArg_ParseTuple
2262 (args, (char *) "O:xmlNodeGetNsDefs", &pyobj_node))
2263 return (NULL);
Daniel Veillard36eea2d2002-02-04 00:17:01 +00002264 node = (xmlNodePtr) PyxmlNode_Get(pyobj_node);
2265
2266 if ((node == NULL) || (node->type != XML_ELEMENT_NODE)) {
Daniel Veillardd2379012002-03-15 22:24:56 +00002267 Py_INCREF(Py_None);
2268 return (Py_None);
Daniel Veillard36eea2d2002-02-04 00:17:01 +00002269 }
2270 c_retval = node->nsDef;
2271 py_retval = libxml_xmlNsPtrWrap((xmlNsPtr) c_retval);
Daniel Veillardd2379012002-03-15 22:24:56 +00002272 return (py_retval);
Daniel Veillard36eea2d2002-02-04 00:17:01 +00002273}
2274
2275PyObject *
Daniel Veillardd2379012002-03-15 22:24:56 +00002276libxml_xmlNodeGetNs(ATTRIBUTE_UNUSED PyObject * self, PyObject * args)
2277{
Daniel Veillard36eea2d2002-02-04 00:17:01 +00002278 PyObject *py_retval;
2279 xmlNsPtr c_retval;
2280 xmlNodePtr node;
2281 PyObject *pyobj_node;
2282
Daniel Veillardd2379012002-03-15 22:24:56 +00002283 if (!PyArg_ParseTuple(args, (char *) "O:xmlNodeGetNs", &pyobj_node))
2284 return (NULL);
Daniel Veillard36eea2d2002-02-04 00:17:01 +00002285 node = (xmlNodePtr) PyxmlNode_Get(pyobj_node);
2286
2287 if ((node == NULL) || (node->type != XML_ELEMENT_NODE)) {
Daniel Veillardd2379012002-03-15 22:24:56 +00002288 Py_INCREF(Py_None);
2289 return (Py_None);
Daniel Veillard36eea2d2002-02-04 00:17:01 +00002290 }
2291 c_retval = node->ns;
2292 py_retval = libxml_xmlNsPtrWrap((xmlNsPtr) c_retval);
Daniel Veillardd2379012002-03-15 22:24:56 +00002293 return (py_retval);
Daniel Veillard36eea2d2002-02-04 00:17:01 +00002294}
2295
2296/************************************************************************
2297 * *
Daniel Veillard1e774382002-03-06 17:35:40 +00002298 * Serialization front-end *
2299 * *
2300 ************************************************************************/
2301
Daniel Veillardd2379012002-03-15 22:24:56 +00002302static PyObject *
2303libxml_serializeNode(ATTRIBUTE_UNUSED PyObject * self, PyObject * args)
2304{
Daniel Veillard1e774382002-03-06 17:35:40 +00002305 PyObject *py_retval = NULL;
2306 xmlChar *c_retval;
2307 PyObject *pyobj_node;
2308 xmlNodePtr node;
2309 xmlDocPtr doc;
Daniel Veillardd2379012002-03-15 22:24:56 +00002310 const char *encoding;
Daniel Veillard1e774382002-03-06 17:35:40 +00002311 int format;
2312 int len;
2313
Daniel Veillardd2379012002-03-15 22:24:56 +00002314 if (!PyArg_ParseTuple(args, (char *) "Ozi:serializeNode", &pyobj_node,
2315 &encoding, &format))
2316 return (NULL);
Daniel Veillard1e774382002-03-06 17:35:40 +00002317 node = (xmlNodePtr) PyxmlNode_Get(pyobj_node);
2318
2319 if (node == NULL) {
Daniel Veillardd2379012002-03-15 22:24:56 +00002320 Py_INCREF(Py_None);
2321 return (Py_None);
Daniel Veillard1e774382002-03-06 17:35:40 +00002322 }
2323 if (node->type == XML_DOCUMENT_NODE) {
Daniel Veillardd2379012002-03-15 22:24:56 +00002324 doc = (xmlDocPtr) node;
2325 xmlDocDumpFormatMemoryEnc(doc, &c_retval, &len,
2326 (const char *) encoding, format);
2327 py_retval = libxml_charPtrWrap((char *) c_retval);
Daniel Veillard1e774382002-03-06 17:35:40 +00002328 } else if (node->type == XML_HTML_DOCUMENT_NODE) {
Daniel Veillardd2379012002-03-15 22:24:56 +00002329 xmlOutputBufferPtr buf;
2330 xmlCharEncodingHandlerPtr handler = NULL;
Daniel Veillard1e774382002-03-06 17:35:40 +00002331
Daniel Veillardd2379012002-03-15 22:24:56 +00002332 doc = (xmlDocPtr) node;
2333 if (encoding != NULL)
2334 htmlSetMetaEncoding(doc, (const xmlChar *) encoding);
2335 encoding = (const char *) htmlGetMetaEncoding(doc);
Daniel Veillard1e774382002-03-06 17:35:40 +00002336
Daniel Veillardd2379012002-03-15 22:24:56 +00002337 if (encoding != NULL) {
2338 handler = xmlFindCharEncodingHandler(encoding);
2339 if (handler == NULL) {
2340 Py_INCREF(Py_None);
2341 return (Py_None);
2342 }
2343 }
Daniel Veillard1e774382002-03-06 17:35:40 +00002344
Daniel Veillardd2379012002-03-15 22:24:56 +00002345 /*
2346 * Fallback to HTML or ASCII when the encoding is unspecified
2347 */
2348 if (handler == NULL)
2349 handler = xmlFindCharEncodingHandler("HTML");
2350 if (handler == NULL)
2351 handler = xmlFindCharEncodingHandler("ascii");
Daniel Veillard1e774382002-03-06 17:35:40 +00002352
Daniel Veillardd2379012002-03-15 22:24:56 +00002353 buf = xmlAllocOutputBuffer(handler);
2354 if (buf == NULL) {
2355 Py_INCREF(Py_None);
2356 return (Py_None);
2357 }
2358 htmlDocContentDumpFormatOutput(buf, doc, encoding, format);
2359 xmlOutputBufferFlush(buf);
2360 if (buf->conv != NULL) {
2361 len = buf->conv->use;
2362 c_retval = buf->conv->content;
2363 buf->conv->content = NULL;
2364 } else {
2365 len = buf->buffer->use;
2366 c_retval = buf->buffer->content;
2367 buf->buffer->content = NULL;
2368 }
2369 (void) xmlOutputBufferClose(buf);
2370 py_retval = libxml_charPtrWrap((char *) c_retval);
Daniel Veillard1e774382002-03-06 17:35:40 +00002371 } else {
Daniel Veillardd2379012002-03-15 22:24:56 +00002372 doc = node->doc;
Daniel Veillarda8c0adb2002-11-17 22:37:35 +00002373 if ((doc == NULL) || (doc->type == XML_DOCUMENT_NODE)) {
Daniel Veillardd2379012002-03-15 22:24:56 +00002374 xmlOutputBufferPtr buf;
2375 xmlCharEncodingHandlerPtr handler = NULL;
Daniel Veillard1e774382002-03-06 17:35:40 +00002376
Daniel Veillardd2379012002-03-15 22:24:56 +00002377 if (encoding != NULL) {
2378 handler = xmlFindCharEncodingHandler(encoding);
2379 if (handler == NULL) {
2380 Py_INCREF(Py_None);
2381 return (Py_None);
2382 }
2383 }
Daniel Veillard1e774382002-03-06 17:35:40 +00002384
Daniel Veillardd2379012002-03-15 22:24:56 +00002385 buf = xmlAllocOutputBuffer(handler);
2386 if (buf == NULL) {
2387 Py_INCREF(Py_None);
2388 return (Py_None);
2389 }
2390 xmlNodeDumpOutput(buf, doc, node, 0, format, encoding);
2391 xmlOutputBufferFlush(buf);
2392 if (buf->conv != NULL) {
2393 len = buf->conv->use;
2394 c_retval = buf->conv->content;
2395 buf->conv->content = NULL;
2396 } else {
2397 len = buf->buffer->use;
2398 c_retval = buf->buffer->content;
2399 buf->buffer->content = NULL;
2400 }
2401 (void) xmlOutputBufferClose(buf);
2402 py_retval = libxml_charPtrWrap((char *) c_retval);
2403 } else if (doc->type == XML_HTML_DOCUMENT_NODE) {
2404 xmlOutputBufferPtr buf;
2405 xmlCharEncodingHandlerPtr handler = NULL;
Daniel Veillard1e774382002-03-06 17:35:40 +00002406
Daniel Veillardd2379012002-03-15 22:24:56 +00002407 if (encoding != NULL)
2408 htmlSetMetaEncoding(doc, (const xmlChar *) encoding);
2409 encoding = (const char *) htmlGetMetaEncoding(doc);
2410 if (encoding != NULL) {
2411 handler = xmlFindCharEncodingHandler(encoding);
2412 if (handler == NULL) {
2413 Py_INCREF(Py_None);
2414 return (Py_None);
2415 }
2416 }
Daniel Veillard1e774382002-03-06 17:35:40 +00002417
Daniel Veillardd2379012002-03-15 22:24:56 +00002418 /*
2419 * Fallback to HTML or ASCII when the encoding is unspecified
2420 */
2421 if (handler == NULL)
2422 handler = xmlFindCharEncodingHandler("HTML");
2423 if (handler == NULL)
2424 handler = xmlFindCharEncodingHandler("ascii");
Daniel Veillard1e774382002-03-06 17:35:40 +00002425
Daniel Veillardd2379012002-03-15 22:24:56 +00002426 buf = xmlAllocOutputBuffer(handler);
2427 if (buf == NULL) {
2428 Py_INCREF(Py_None);
2429 return (Py_None);
2430 }
2431 htmlNodeDumpFormatOutput(buf, doc, node, encoding, format);
2432 xmlOutputBufferFlush(buf);
2433 if (buf->conv != NULL) {
2434 len = buf->conv->use;
2435 c_retval = buf->conv->content;
2436 buf->conv->content = NULL;
2437 } else {
2438 len = buf->buffer->use;
2439 c_retval = buf->buffer->content;
2440 buf->buffer->content = NULL;
2441 }
2442 (void) xmlOutputBufferClose(buf);
2443 py_retval = libxml_charPtrWrap((char *) c_retval);
2444 } else {
2445 Py_INCREF(Py_None);
2446 return (Py_None);
2447 }
Daniel Veillard1e774382002-03-06 17:35:40 +00002448 }
Daniel Veillardd2379012002-03-15 22:24:56 +00002449 return (py_retval);
Daniel Veillard1e774382002-03-06 17:35:40 +00002450}
2451
Daniel Veillardd2379012002-03-15 22:24:56 +00002452static PyObject *
2453libxml_saveNodeTo(ATTRIBUTE_UNUSED PyObject * self, PyObject * args)
2454{
Daniel Veillard1e774382002-03-06 17:35:40 +00002455 PyObject *py_file = NULL;
2456 FILE *output;
2457 PyObject *pyobj_node;
2458 xmlNodePtr node;
2459 xmlDocPtr doc;
Daniel Veillardd2379012002-03-15 22:24:56 +00002460 const char *encoding;
Daniel Veillard1e774382002-03-06 17:35:40 +00002461 int format;
2462 int len;
2463 xmlOutputBufferPtr buf;
2464 xmlCharEncodingHandlerPtr handler = NULL;
2465
Daniel Veillardd2379012002-03-15 22:24:56 +00002466 if (!PyArg_ParseTuple(args, (char *) "OOzi:serializeNode", &pyobj_node,
2467 &py_file, &encoding, &format))
2468 return (NULL);
Daniel Veillard1e774382002-03-06 17:35:40 +00002469 node = (xmlNodePtr) PyxmlNode_Get(pyobj_node);
2470
2471 if (node == NULL) {
Daniel Veillardd2379012002-03-15 22:24:56 +00002472 return (PyInt_FromLong((long) -1));
Daniel Veillard1e774382002-03-06 17:35:40 +00002473 }
2474 if ((py_file == NULL) || (!(PyFile_Check(py_file)))) {
Daniel Veillardd2379012002-03-15 22:24:56 +00002475 return (PyInt_FromLong((long) -1));
Daniel Veillard1e774382002-03-06 17:35:40 +00002476 }
2477 output = PyFile_AsFile(py_file);
2478 if (output == NULL) {
Daniel Veillardd2379012002-03-15 22:24:56 +00002479 return (PyInt_FromLong((long) -1));
Daniel Veillard1e774382002-03-06 17:35:40 +00002480 }
2481
2482 if (node->type == XML_DOCUMENT_NODE) {
Daniel Veillardd2379012002-03-15 22:24:56 +00002483 doc = (xmlDocPtr) node;
Daniel Veillard1e774382002-03-06 17:35:40 +00002484 } else if (node->type == XML_HTML_DOCUMENT_NODE) {
Daniel Veillardd2379012002-03-15 22:24:56 +00002485 doc = (xmlDocPtr) node;
Daniel Veillard1e774382002-03-06 17:35:40 +00002486 } else {
Daniel Veillardd2379012002-03-15 22:24:56 +00002487 doc = node->doc;
Daniel Veillard1e774382002-03-06 17:35:40 +00002488 }
2489 if (doc->type == XML_HTML_DOCUMENT_NODE) {
Daniel Veillardd2379012002-03-15 22:24:56 +00002490 if (encoding == NULL)
2491 encoding = (const char *) htmlGetMetaEncoding(doc);
Daniel Veillard1e774382002-03-06 17:35:40 +00002492 }
2493 if (encoding != NULL) {
Daniel Veillardd2379012002-03-15 22:24:56 +00002494 handler = xmlFindCharEncodingHandler(encoding);
2495 if (handler == NULL) {
2496 return (PyInt_FromLong((long) -1));
2497 }
Daniel Veillard1e774382002-03-06 17:35:40 +00002498 }
2499 if (doc->type == XML_HTML_DOCUMENT_NODE) {
Daniel Veillardd2379012002-03-15 22:24:56 +00002500 if (handler == NULL)
2501 handler = xmlFindCharEncodingHandler("HTML");
2502 if (handler == NULL)
2503 handler = xmlFindCharEncodingHandler("ascii");
Daniel Veillard1e774382002-03-06 17:35:40 +00002504 }
2505
2506 buf = xmlOutputBufferCreateFile(output, handler);
2507 if (node->type == XML_DOCUMENT_NODE) {
Daniel Veillardd2379012002-03-15 22:24:56 +00002508 len = xmlSaveFormatFileTo(buf, doc, encoding, format);
Daniel Veillard1e774382002-03-06 17:35:40 +00002509 } else if (node->type == XML_HTML_DOCUMENT_NODE) {
Daniel Veillardd2379012002-03-15 22:24:56 +00002510 htmlDocContentDumpFormatOutput(buf, doc, encoding, format);
2511 len = xmlOutputBufferClose(buf);
Daniel Veillard1e774382002-03-06 17:35:40 +00002512 } else if (doc->type == XML_HTML_DOCUMENT_NODE) {
Daniel Veillardd2379012002-03-15 22:24:56 +00002513 htmlNodeDumpFormatOutput(buf, doc, node, encoding, format);
2514 len = xmlOutputBufferClose(buf);
Daniel Veillard1e774382002-03-06 17:35:40 +00002515 } else {
Daniel Veillardd2379012002-03-15 22:24:56 +00002516 xmlNodeDumpOutput(buf, doc, node, 0, format, encoding);
2517 len = xmlOutputBufferClose(buf);
Daniel Veillard1e774382002-03-06 17:35:40 +00002518 }
Daniel Veillardd2379012002-03-15 22:24:56 +00002519 return (PyInt_FromLong((long) len));
Daniel Veillard1e774382002-03-06 17:35:40 +00002520}
2521
2522/************************************************************************
2523 * *
Daniel Veillarda94ec6f2002-03-01 13:00:53 +00002524 * Extra stuff *
2525 * *
2526 ************************************************************************/
2527PyObject *
Daniel Veillardd2379012002-03-15 22:24:56 +00002528libxml_xmlNewNode(ATTRIBUTE_UNUSED PyObject * self, PyObject * args)
2529{
Daniel Veillarda94ec6f2002-03-01 13:00:53 +00002530 PyObject *py_retval;
Daniel Veillardd2379012002-03-15 22:24:56 +00002531 xmlChar *name;
Daniel Veillarda94ec6f2002-03-01 13:00:53 +00002532 xmlNodePtr node;
2533
Daniel Veillardd2379012002-03-15 22:24:56 +00002534 if (!PyArg_ParseTuple(args, (char *) "s:xmlNewNode", &name))
2535 return (NULL);
Daniel Veillarda94ec6f2002-03-01 13:00:53 +00002536 node = (xmlNodePtr) xmlNewNode(NULL, name);
Daniel Veillard3b2e4e12003-02-03 08:52:58 +00002537#ifdef DEBUG
Daniel Veillardd2379012002-03-15 22:24:56 +00002538 printf("NewNode: %s : %p\n", name, (void *) node);
Daniel Veillard3b2e4e12003-02-03 08:52:58 +00002539#endif
Daniel Veillarda94ec6f2002-03-01 13:00:53 +00002540
2541 if (node == NULL) {
Daniel Veillardd2379012002-03-15 22:24:56 +00002542 Py_INCREF(Py_None);
2543 return (Py_None);
Daniel Veillarda94ec6f2002-03-01 13:00:53 +00002544 }
2545 py_retval = libxml_xmlNodePtrWrap(node);
Daniel Veillardd2379012002-03-15 22:24:56 +00002546 return (py_retval);
Daniel Veillarda94ec6f2002-03-01 13:00:53 +00002547}
2548
Daniel Veillard54396242003-04-23 07:36:50 +00002549
2550/************************************************************************
2551 * *
2552 * Local Catalog stuff *
2553 * *
2554 ************************************************************************/
2555static PyObject *
2556libxml_addLocalCatalog(ATTRIBUTE_UNUSED PyObject * self, PyObject * args)
2557{
2558 xmlChar *URL;
2559 xmlParserCtxtPtr ctxt;
2560 PyObject *pyobj_ctxt;
2561
2562 if (!PyArg_ParseTuple(args, (char *)"Os:addLocalCatalog", &pyobj_ctxt, &URL))
2563 return(NULL);
2564
2565 ctxt = (xmlParserCtxtPtr) PyparserCtxt_Get(pyobj_ctxt);
2566
2567 if (URL != NULL) {
2568 ctxt->catalogs = xmlCatalogAddLocal(ctxt->catalogs, URL);
2569 }
2570
2571#ifdef DEBUG
2572 printf("LocalCatalog: %s\n", URL);
2573#endif
2574
2575 Py_INCREF(Py_None);
2576 return (Py_None);
2577}
2578
Daniel Veillarda94ec6f2002-03-01 13:00:53 +00002579/************************************************************************
2580 * *
Daniel Veillardd2897fd2002-01-30 16:37:32 +00002581 * The registration stuff *
2582 * *
2583 ************************************************************************/
2584static PyMethodDef libxmlMethods[] = {
Daniel Veillard96fe0952002-01-30 20:52:23 +00002585#include "libxml2-export.c"
Daniel Veillardd2379012002-03-15 22:24:56 +00002586 {(char *) "name", libxml_name, METH_VARARGS, NULL},
2587 {(char *) "children", libxml_children, METH_VARARGS, NULL},
2588 {(char *) "properties", libxml_properties, METH_VARARGS, NULL},
2589 {(char *) "last", libxml_last, METH_VARARGS, NULL},
2590 {(char *) "prev", libxml_prev, METH_VARARGS, NULL},
2591 {(char *) "next", libxml_next, METH_VARARGS, NULL},
2592 {(char *) "parent", libxml_parent, METH_VARARGS, NULL},
2593 {(char *) "type", libxml_type, METH_VARARGS, NULL},
2594 {(char *) "doc", libxml_doc, METH_VARARGS, NULL},
2595 {(char *) "xmlNewNode", libxml_xmlNewNode, METH_VARARGS, NULL},
2596 {(char *) "serializeNode", libxml_serializeNode, METH_VARARGS, NULL},
2597 {(char *) "saveNodeTo", libxml_saveNodeTo, METH_VARARGS, NULL},
Daniel Veillardc6d4a932002-09-12 15:00:57 +00002598 {(char *) "outputBufferCreate", libxml_xmlCreateOutputBuffer, METH_VARARGS, NULL},
2599 {(char *) "inputBufferCreate", libxml_xmlCreateInputBuffer, METH_VARARGS, NULL},
2600 {(char *) "setEntityLoader", libxml_xmlSetEntityLoader, METH_VARARGS, NULL},
Daniel Veillard3e20a292003-01-10 13:14:40 +00002601 {(char *)"xmlRegisterErrorHandler", libxml_xmlRegisterErrorHandler, METH_VARARGS, NULL },
Daniel Veillard417be3a2003-01-20 21:26:34 +00002602 {(char *)"xmlParserCtxtSetErrorHandler", libxml_xmlParserCtxtSetErrorHandler, METH_VARARGS, NULL },
2603 {(char *)"xmlParserCtxtGetErrorHandler", libxml_xmlParserCtxtGetErrorHandler, METH_VARARGS, NULL },
Daniel Veillarde6227e02003-01-14 11:42:39 +00002604 {(char *)"xmlFreeParserCtxt", libxml_xmlFreeParserCtxt, METH_VARARGS, NULL },
Daniel Veillard26f70262003-01-16 22:45:08 +00002605 {(char *)"xmlTextReaderSetErrorHandler", libxml_xmlTextReaderSetErrorHandler, METH_VARARGS, NULL },
2606 {(char *)"xmlTextReaderGetErrorHandler", libxml_xmlTextReaderGetErrorHandler, METH_VARARGS, NULL },
2607 {(char *)"xmlFreeTextReader", libxml_xmlFreeTextReader, METH_VARARGS, NULL },
Daniel Veillard54396242003-04-23 07:36:50 +00002608 {(char *)"addLocalCatalog", libxml_addLocalCatalog, METH_VARARGS, NULL },
Daniel Veillardd2379012002-03-15 22:24:56 +00002609 {NULL, NULL, 0, NULL}
Daniel Veillardd2897fd2002-01-30 16:37:32 +00002610};
2611
Daniel Veillard0fea6f42002-02-22 22:51:13 +00002612#ifdef MERGED_MODULES
Daniel Veillard6361da02002-02-23 10:10:33 +00002613extern void initlibxsltmod(void);
Daniel Veillard0fea6f42002-02-22 22:51:13 +00002614#endif
2615
Daniel Veillardd2379012002-03-15 22:24:56 +00002616void
2617initlibxml2mod(void)
2618{
Daniel Veillardaf43f632002-03-08 15:05:20 +00002619 static int initialized = 0;
Daniel Veillard3ce52572002-02-03 15:08:05 +00002620 PyObject *m;
Daniel Veillardaf43f632002-03-08 15:05:20 +00002621
2622 if (initialized != 0)
Daniel Veillardd2379012002-03-15 22:24:56 +00002623 return;
Daniel Veillard781ac8b2003-05-15 22:11:36 +00002624 /* XXX xmlInitParser does much more than this */
2625 xmlInitGlobals();
Daniel Veillardc6d4a932002-09-12 15:00:57 +00002626 xmlRegisterDefaultOutputCallbacks();
2627 xmlRegisterDefaultInputCallbacks();
Daniel Veillardd2379012002-03-15 22:24:56 +00002628 m = Py_InitModule((char *) "libxml2mod", libxmlMethods);
Daniel Veillardaf43f632002-03-08 15:05:20 +00002629 initialized = 1;
Daniel Veillard5d819032002-02-02 21:49:17 +00002630 libxml_xmlErrorInitialize();
Daniel Veillard6361da02002-02-23 10:10:33 +00002631
Daniel Veillard0fea6f42002-02-22 22:51:13 +00002632#ifdef MERGED_MODULES
2633 initlibxsltmod();
2634#endif
Daniel Veillardd2897fd2002-01-30 16:37:32 +00002635}