blob: 095efbd9f198605fc2080d93ce2b909f58e61778 [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);
1270}
1271
1272PyObject *
Daniel Veillardd2379012002-03-15 22:24:56 +00001273libxml_xmlRegisterErrorHandler(ATTRIBUTE_UNUSED PyObject * self,
1274 PyObject * args)
1275{
Daniel Veillard5d819032002-02-02 21:49:17 +00001276 PyObject *py_retval;
1277 PyObject *pyobj_f;
1278 PyObject *pyobj_ctx;
1279
Daniel Veillardd2379012002-03-15 22:24:56 +00001280 if (!PyArg_ParseTuple
1281 (args, (char *) "OO:xmlRegisterErrorHandler", &pyobj_f,
1282 &pyobj_ctx))
1283 return (NULL);
Daniel Veillard5d819032002-02-02 21:49:17 +00001284
1285#ifdef DEBUG_ERROR
Daniel Veillardd2379012002-03-15 22:24:56 +00001286 printf("libxml_registerXPathFunction(%p, %p) called\n", pyobj_ctx,
1287 pyobj_f);
Daniel Veillard5d819032002-02-02 21:49:17 +00001288#endif
1289
1290 if (libxml_xmlPythonErrorFuncHandler != NULL) {
Daniel Veillardd2379012002-03-15 22:24:56 +00001291 Py_XDECREF(libxml_xmlPythonErrorFuncHandler);
Daniel Veillard5d819032002-02-02 21:49:17 +00001292 }
1293 if (libxml_xmlPythonErrorFuncCtxt != NULL) {
Daniel Veillardd2379012002-03-15 22:24:56 +00001294 Py_XDECREF(libxml_xmlPythonErrorFuncCtxt);
Daniel Veillard5d819032002-02-02 21:49:17 +00001295 }
1296
1297 Py_XINCREF(pyobj_ctx);
1298 Py_XINCREF(pyobj_f);
1299
1300 /* TODO: check f is a function ! */
1301 libxml_xmlPythonErrorFuncHandler = pyobj_f;
1302 libxml_xmlPythonErrorFuncCtxt = pyobj_ctx;
1303
1304 py_retval = libxml_intWrap(1);
Daniel Veillardd2379012002-03-15 22:24:56 +00001305 return (py_retval);
Daniel Veillard5d819032002-02-02 21:49:17 +00001306}
Daniel Veillardd2379012002-03-15 22:24:56 +00001307
Daniel Veillarde6227e02003-01-14 11:42:39 +00001308
1309/************************************************************************
1310 * *
1311 * Per parserCtxt error handler *
1312 * *
1313 ************************************************************************/
1314
Daniel Veillard417be3a2003-01-20 21:26:34 +00001315typedef struct
Daniel Veillarde6227e02003-01-14 11:42:39 +00001316{
Daniel Veillard417be3a2003-01-20 21:26:34 +00001317 PyObject *f;
1318 PyObject *arg;
1319} xmlParserCtxtPyCtxt;
1320typedef xmlParserCtxtPyCtxt *xmlParserCtxtPyCtxtPtr;
1321
1322static void
1323libxml_xmlParserCtxtGenericErrorFuncHandler(void *ctx, int severity, char *str)
1324{
Daniel Veillarde6227e02003-01-14 11:42:39 +00001325 PyObject *list;
Daniel Veillarde6227e02003-01-14 11:42:39 +00001326 PyObject *result;
Daniel Veillard417be3a2003-01-20 21:26:34 +00001327 xmlParserCtxtPtr ctxt;
Daniel Veillarde6227e02003-01-14 11:42:39 +00001328 xmlParserCtxtPyCtxtPtr pyCtxt;
1329
1330#ifdef DEBUG_ERROR
Daniel Veillard417be3a2003-01-20 21:26:34 +00001331 printf("libxml_xmlParserCtxtGenericErrorFuncHandler(%p, %s, ...) called\n", ctx, msg);
Daniel Veillarde6227e02003-01-14 11:42:39 +00001332#endif
1333
Daniel Veillard417be3a2003-01-20 21:26:34 +00001334 ctxt = (xmlParserCtxtPtr)ctx;
1335 pyCtxt = (xmlParserCtxtPyCtxtPtr)ctxt->_private;
Daniel Veillarde6227e02003-01-14 11:42:39 +00001336
Daniel Veillard417be3a2003-01-20 21:26:34 +00001337 list = PyTuple_New(4);
1338 PyTuple_SetItem(list, 0, pyCtxt->arg);
1339 Py_XINCREF(pyCtxt->arg);
1340 PyTuple_SetItem(list, 1, libxml_charPtrWrap(str));
1341 PyTuple_SetItem(list, 2, libxml_intWrap(severity));
1342 PyTuple_SetItem(list, 3, Py_None);
1343 Py_INCREF(Py_None);
1344 result = PyEval_CallObject(pyCtxt->f, list);
1345 if (result == NULL)
1346 {
1347 /* TODO: manage for the exception to be propagated... */
1348 PyErr_Print();
Daniel Veillarde6227e02003-01-14 11:42:39 +00001349 }
Daniel Veillard417be3a2003-01-20 21:26:34 +00001350 Py_XDECREF(list);
1351 Py_XDECREF(result);
1352}
1353
1354static void
1355libxml_xmlParserCtxtErrorFuncHandler(void *ctx, const char *msg, ...)
1356{
1357 va_list ap;
1358
1359 va_start(ap, msg);
1360 libxml_xmlParserCtxtGenericErrorFuncHandler(ctx,XML_PARSER_SEVERITY_ERROR,libxml_buildMessage(msg,ap));
1361 va_end(ap);
1362}
1363
1364static void
1365libxml_xmlParserCtxtWarningFuncHandler(void *ctx, const char *msg, ...)
1366{
1367 va_list ap;
1368
1369 va_start(ap, msg);
1370 libxml_xmlParserCtxtGenericErrorFuncHandler(ctx,XML_PARSER_SEVERITY_WARNING,libxml_buildMessage(msg,ap));
1371 va_end(ap);
1372}
1373
1374static void
1375libxml_xmlParserCtxtValidityErrorFuncHandler(void *ctx, const char *msg, ...)
1376{
1377 va_list ap;
1378
1379 va_start(ap, msg);
1380 libxml_xmlParserCtxtGenericErrorFuncHandler(ctx,XML_PARSER_SEVERITY_VALIDITY_ERROR,libxml_buildMessage(msg,ap));
1381 va_end(ap);
1382}
1383
1384static void
1385libxml_xmlParserCtxtValidityWarningFuncHandler(void *ctx, const char *msg, ...)
1386{
1387 va_list ap;
1388
1389 va_start(ap, msg);
1390 libxml_xmlParserCtxtGenericErrorFuncHandler(ctx,XML_PARSER_SEVERITY_VALIDITY_WARNING,libxml_buildMessage(msg,ap));
1391 va_end(ap);
Daniel Veillarde6227e02003-01-14 11:42:39 +00001392}
1393
1394PyObject *
Daniel Veillard417be3a2003-01-20 21:26:34 +00001395libxml_xmlParserCtxtSetErrorHandler(ATTRIBUTE_UNUSED PyObject *self, PyObject *args)
Daniel Veillarde6227e02003-01-14 11:42:39 +00001396{
1397 PyObject *py_retval;
1398 xmlParserCtxtPtr ctxt;
Daniel Veillarde4a07e72003-01-14 14:40:25 +00001399 xmlParserCtxtPyCtxtPtr pyCtxt;
Daniel Veillarde6227e02003-01-14 11:42:39 +00001400 PyObject *pyobj_ctxt;
1401 PyObject *pyobj_f;
1402 PyObject *pyobj_arg;
1403
Daniel Veillard417be3a2003-01-20 21:26:34 +00001404 if (!PyArg_ParseTuple(args, (char *)"OOO:xmlParserCtxtSetErrorHandler",
Daniel Veillarde6227e02003-01-14 11:42:39 +00001405 &pyobj_ctxt, &pyobj_f, &pyobj_arg))
1406 return(NULL);
1407 ctxt = (xmlParserCtxtPtr) PyparserCtxt_Get(pyobj_ctxt);
1408 if (ctxt->_private == NULL) {
Daniel Veillarde6227e02003-01-14 11:42:39 +00001409 pyCtxt = xmlMalloc(sizeof(xmlParserCtxtPyCtxt));
1410 if (pyCtxt == NULL) {
1411 py_retval = libxml_intWrap(-1);
1412 return(py_retval);
1413 }
1414 memset(pyCtxt,0,sizeof(xmlParserCtxtPyCtxt));
1415 ctxt->_private = pyCtxt;
1416 }
Daniel Veillarde4a07e72003-01-14 14:40:25 +00001417 else {
Daniel Veillard417be3a2003-01-20 21:26:34 +00001418 pyCtxt = (xmlParserCtxtPyCtxtPtr)ctxt->_private;
Daniel Veillarde4a07e72003-01-14 14:40:25 +00001419 }
Daniel Veillarde6227e02003-01-14 11:42:39 +00001420 /* TODO: check f is a function ! */
Daniel Veillard417be3a2003-01-20 21:26:34 +00001421 Py_XDECREF(pyCtxt->f);
Daniel Veillarde6227e02003-01-14 11:42:39 +00001422 Py_XINCREF(pyobj_f);
Daniel Veillard417be3a2003-01-20 21:26:34 +00001423 pyCtxt->f = pyobj_f;
1424 Py_XDECREF(pyCtxt->arg);
Daniel Veillarde6227e02003-01-14 11:42:39 +00001425 Py_XINCREF(pyobj_arg);
Daniel Veillard417be3a2003-01-20 21:26:34 +00001426 pyCtxt->arg = pyobj_arg;
Daniel Veillarde6227e02003-01-14 11:42:39 +00001427
Daniel Veillard417be3a2003-01-20 21:26:34 +00001428 if (pyobj_f != Py_None) {
1429 ctxt->sax->error = libxml_xmlParserCtxtErrorFuncHandler;
1430 ctxt->sax->warning = libxml_xmlParserCtxtWarningFuncHandler;
1431 ctxt->vctxt.error = libxml_xmlParserCtxtValidityErrorFuncHandler;
1432 ctxt->vctxt.warning = libxml_xmlParserCtxtValidityWarningFuncHandler;
1433 }
1434 else {
1435 ctxt->sax->error = xmlParserError;
1436 ctxt->vctxt.error = xmlParserValidityError;
1437 ctxt->sax->warning = xmlParserWarning;
1438 ctxt->vctxt.warning = xmlParserValidityWarning;
1439 }
Daniel Veillarde6227e02003-01-14 11:42:39 +00001440
1441 py_retval = libxml_intWrap(1);
1442 return(py_retval);
1443}
1444
Daniel Veillarde6227e02003-01-14 11:42:39 +00001445PyObject *
Daniel Veillard417be3a2003-01-20 21:26:34 +00001446libxml_xmlParserCtxtGetErrorHandler(ATTRIBUTE_UNUSED PyObject *self, PyObject *args)
Daniel Veillarde6227e02003-01-14 11:42:39 +00001447{
1448 PyObject *py_retval;
1449 xmlParserCtxtPtr ctxt;
Daniel Veillarde4a07e72003-01-14 14:40:25 +00001450 xmlParserCtxtPyCtxtPtr pyCtxt;
Daniel Veillarde6227e02003-01-14 11:42:39 +00001451 PyObject *pyobj_ctxt;
Daniel Veillarde6227e02003-01-14 11:42:39 +00001452
Daniel Veillard417be3a2003-01-20 21:26:34 +00001453 if (!PyArg_ParseTuple(args, (char *)"O:xmlParserCtxtGetErrorHandler",
1454 &pyobj_ctxt))
Daniel Veillarde6227e02003-01-14 11:42:39 +00001455 return(NULL);
1456 ctxt = (xmlParserCtxtPtr) PyparserCtxt_Get(pyobj_ctxt);
Daniel Veillard417be3a2003-01-20 21:26:34 +00001457 py_retval = PyTuple_New(2);
1458 if (ctxt->_private != NULL) {
1459 pyCtxt = (xmlParserCtxtPyCtxtPtr)ctxt->_private;
1460
1461 PyTuple_SetItem(py_retval, 0, pyCtxt->f);
1462 Py_XINCREF(pyCtxt->f);
1463 PyTuple_SetItem(py_retval, 1, pyCtxt->arg);
1464 Py_XINCREF(pyCtxt->arg);
Daniel Veillarde4a07e72003-01-14 14:40:25 +00001465 }
1466 else {
Daniel Veillard417be3a2003-01-20 21:26:34 +00001467 /* no python error handler registered */
1468 PyTuple_SetItem(py_retval, 0, Py_None);
1469 Py_XINCREF(Py_None);
1470 PyTuple_SetItem(py_retval, 1, Py_None);
1471 Py_XINCREF(Py_None);
Daniel Veillarde4a07e72003-01-14 14:40:25 +00001472 }
Daniel Veillarde6227e02003-01-14 11:42:39 +00001473 return(py_retval);
1474}
1475
Daniel Veillard417be3a2003-01-20 21:26:34 +00001476PyObject *
1477libxml_xmlFreeParserCtxt(ATTRIBUTE_UNUSED PyObject *self, PyObject *args) {
1478 xmlParserCtxtPtr ctxt;
1479 PyObject *pyobj_ctxt;
1480 xmlParserCtxtPyCtxtPtr pyCtxt;
1481
1482 if (!PyArg_ParseTuple(args, (char *)"O:xmlFreeParserCtxt", &pyobj_ctxt))
1483 return(NULL);
1484 ctxt = (xmlParserCtxtPtr) PyparserCtxt_Get(pyobj_ctxt);
1485
1486 if (ctxt != NULL) {
1487 pyCtxt = (xmlParserCtxtPyCtxtPtr)((xmlParserCtxtPtr)ctxt)->_private;
1488 if (pyCtxt) {
1489 Py_XDECREF(pyCtxt->f);
1490 Py_XDECREF(pyCtxt->arg);
1491 xmlFree(pyCtxt);
1492 }
1493 xmlFreeParserCtxt(ctxt);
1494 }
1495
1496 Py_INCREF(Py_None);
1497 return(Py_None);
1498}
1499
Daniel Veillarda7340c82002-02-01 17:56:45 +00001500/************************************************************************
1501 * *
Daniel Veillard26f70262003-01-16 22:45:08 +00001502 * Per xmlTextReader error handler *
1503 * *
1504 ************************************************************************/
1505
1506typedef struct
1507{
1508 PyObject *f;
1509 PyObject *arg;
1510} xmlTextReaderPyCtxt;
1511typedef xmlTextReaderPyCtxt *xmlTextReaderPyCtxtPtr;
1512
1513static void
1514libxml_xmlTextReaderErrorCallback(void *arg,
1515 const char *msg,
Daniel Veillard417be3a2003-01-20 21:26:34 +00001516 int severity,
1517 xmlTextReaderLocatorPtr locator)
Daniel Veillard26f70262003-01-16 22:45:08 +00001518{
1519 xmlTextReaderPyCtxt *pyCtxt = (xmlTextReaderPyCtxt *)arg;
1520 PyObject *list;
1521 PyObject *result;
1522
Daniel Veillard417be3a2003-01-20 21:26:34 +00001523 list = PyTuple_New(4);
Daniel Veillard26f70262003-01-16 22:45:08 +00001524 PyTuple_SetItem(list, 0, pyCtxt->arg);
1525 Py_XINCREF(pyCtxt->arg);
1526 PyTuple_SetItem(list, 1, libxml_charPtrConstWrap(msg));
Daniel Veillard417be3a2003-01-20 21:26:34 +00001527 PyTuple_SetItem(list, 2, libxml_intWrap(severity));
1528 PyTuple_SetItem(list, 3, libxml_xmlTextReaderLocatorPtrWrap(locator));
Daniel Veillard26f70262003-01-16 22:45:08 +00001529 result = PyEval_CallObject(pyCtxt->f, list);
1530 if (result == NULL)
1531 {
Daniel Veillard417be3a2003-01-20 21:26:34 +00001532 /* TODO: manage for the exception to be propagated... */
Daniel Veillard26f70262003-01-16 22:45:08 +00001533 PyErr_Print();
1534 }
1535 Py_XDECREF(list);
1536 Py_XDECREF(result);
1537}
1538
1539PyObject *
1540libxml_xmlTextReaderSetErrorHandler(ATTRIBUTE_UNUSED PyObject *self, PyObject *args)
1541{
1542 xmlTextReaderPtr reader;
1543 xmlTextReaderPyCtxtPtr pyCtxt;
1544 xmlTextReaderErrorFunc f;
1545 void *arg;
1546 PyObject *pyobj_reader;
1547 PyObject *pyobj_f;
1548 PyObject *pyobj_arg;
1549 PyObject *py_retval;
1550
1551 if (!PyArg_ParseTuple(args, (char *)"OOO:xmlTextReaderSetErrorHandler", &pyobj_reader, &pyobj_f, &pyobj_arg))
1552 return(NULL);
1553 reader = (xmlTextReaderPtr) PyxmlTextReader_Get(pyobj_reader);
1554 /* clear previous error handler */
1555 xmlTextReaderGetErrorHandler(reader,&f,&arg);
1556 if (arg != NULL) {
1557 if (f == libxml_xmlTextReaderErrorCallback) {
1558 /* ok, it's our error handler! */
1559 pyCtxt = (xmlTextReaderPyCtxtPtr)arg;
1560 Py_XDECREF(pyCtxt->f);
1561 Py_XDECREF(pyCtxt->arg);
1562 xmlFree(pyCtxt);
1563 }
1564 else {
1565 /*
1566 * there already an arg, and it's not ours,
1567 * there is definitely something wrong going on here...
1568 * we don't know how to free it, so we bail out...
1569 */
1570 py_retval = libxml_intWrap(-1);
1571 return(py_retval);
1572 }
1573 }
1574 xmlTextReaderSetErrorHandler(reader,NULL,NULL);
1575 /* set new error handler */
1576 if (pyobj_f != Py_None)
1577 {
1578 pyCtxt = (xmlTextReaderPyCtxtPtr)xmlMalloc(sizeof(xmlTextReaderPyCtxt));
1579 if (pyCtxt == NULL) {
1580 py_retval = libxml_intWrap(-1);
1581 return(py_retval);
1582 }
1583 Py_XINCREF(pyobj_f);
1584 pyCtxt->f = pyobj_f;
1585 Py_XINCREF(pyobj_arg);
1586 pyCtxt->arg = pyobj_arg;
1587 xmlTextReaderSetErrorHandler(reader,libxml_xmlTextReaderErrorCallback,pyCtxt);
1588 }
1589
1590 py_retval = libxml_intWrap(1);
1591 return(py_retval);
1592}
1593
1594PyObject *
1595libxml_xmlTextReaderGetErrorHandler(ATTRIBUTE_UNUSED PyObject *self, PyObject *args)
1596{
1597 xmlTextReaderPtr reader;
1598 xmlTextReaderPyCtxtPtr pyCtxt;
1599 xmlTextReaderErrorFunc f;
1600 void *arg;
1601 PyObject *pyobj_reader;
1602 PyObject *py_retval;
1603
1604 if (!PyArg_ParseTuple(args, (char *)"O:xmlTextReaderSetErrorHandler", &pyobj_reader))
1605 return(NULL);
1606 reader = (xmlTextReaderPtr) PyxmlTextReader_Get(pyobj_reader);
1607 xmlTextReaderGetErrorHandler(reader,&f,&arg);
1608 py_retval = PyTuple_New(2);
1609 if (f == libxml_xmlTextReaderErrorCallback) {
1610 /* ok, it's our error handler! */
1611 pyCtxt = (xmlTextReaderPyCtxtPtr)arg;
1612 PyTuple_SetItem(py_retval, 0, pyCtxt->f);
1613 Py_XINCREF(pyCtxt->f);
1614 PyTuple_SetItem(py_retval, 1, pyCtxt->arg);
1615 Py_XINCREF(pyCtxt->arg);
1616 }
1617 else
1618 {
1619 /* f is null or it's not our error handler */
1620 PyTuple_SetItem(py_retval, 0, Py_None);
1621 Py_XINCREF(Py_None);
1622 PyTuple_SetItem(py_retval, 1, Py_None);
1623 Py_XINCREF(Py_None);
1624 }
1625 return(py_retval);
1626}
1627
1628PyObject *
1629libxml_xmlFreeTextReader(ATTRIBUTE_UNUSED PyObject *self, PyObject *args) {
1630 xmlTextReaderPtr reader;
1631 PyObject *pyobj_reader;
1632 xmlTextReaderPyCtxtPtr pyCtxt;
1633 xmlTextReaderErrorFunc f;
1634 void *arg;
1635
1636 if (!PyArg_ParseTuple(args, (char *)"O:xmlFreeTextReader", &pyobj_reader))
1637 return(NULL);
1638 reader = (xmlTextReaderPtr) PyxmlTextReader_Get(pyobj_reader);
1639
1640 xmlTextReaderGetErrorHandler(reader,&f,&arg);
1641 if (arg != NULL) {
1642 if (f == libxml_xmlTextReaderErrorCallback) {
1643 /* ok, it's our error handler! */
1644 pyCtxt = (xmlTextReaderPyCtxtPtr)arg;
1645 Py_XDECREF(pyCtxt->f);
1646 Py_XDECREF(pyCtxt->arg);
1647 xmlFree(pyCtxt);
1648 }
1649 /*
1650 * else, something wrong happened, because the error handler is
1651 * not owned by the python bindings...
1652 */
1653 }
1654
1655 xmlFreeTextReader(reader);
1656 Py_INCREF(Py_None);
1657 return(Py_None);
1658}
1659
1660/************************************************************************
1661 * *
Daniel Veillarda7340c82002-02-01 17:56:45 +00001662 * XPath extensions *
1663 * *
1664 ************************************************************************/
1665
1666static int libxml_xpathCallbacksInitialized = 0;
1667
1668typedef struct libxml_xpathCallback {
1669 xmlXPathContextPtr ctx;
1670 xmlChar *name;
1671 xmlChar *ns_uri;
1672 PyObject *function;
1673} libxml_xpathCallback, *libxml_xpathCallbackPtr;
1674static libxml_xpathCallback libxml_xpathCallbacks[10];
1675static int libxml_xpathCallbacksNb = 0;
1676static int libxml_xpathCallbacksMax = 10;
1677
Daniel Veillarda7340c82002-02-01 17:56:45 +00001678static void
Daniel Veillardd2379012002-03-15 22:24:56 +00001679libxml_xmlXPathFuncCallback(xmlXPathParserContextPtr ctxt, int nargs)
1680{
Daniel Veillarda7340c82002-02-01 17:56:45 +00001681 PyObject *list, *cur, *result;
1682 xmlXPathObjectPtr obj;
Daniel Veillard70cab352002-02-06 16:06:58 +00001683 xmlXPathContextPtr rctxt;
1684 PyObject *current_function = NULL;
1685 const xmlChar *name;
1686 const xmlChar *ns_uri;
Daniel Veillarda7340c82002-02-01 17:56:45 +00001687 int i;
1688
Daniel Veillard70cab352002-02-06 16:06:58 +00001689 if (ctxt == NULL)
Daniel Veillardd2379012002-03-15 22:24:56 +00001690 return;
Daniel Veillard70cab352002-02-06 16:06:58 +00001691 rctxt = ctxt->context;
1692 if (rctxt == NULL)
Daniel Veillardd2379012002-03-15 22:24:56 +00001693 return;
Daniel Veillard70cab352002-02-06 16:06:58 +00001694 name = rctxt->function;
1695 ns_uri = rctxt->functionURI;
Daniel Veillarda7340c82002-02-01 17:56:45 +00001696#ifdef DEBUG_XPATH
Daniel Veillardd2379012002-03-15 22:24:56 +00001697 printf("libxml_xmlXPathFuncCallback called name %s URI %s\n", name,
1698 ns_uri);
Daniel Veillarda7340c82002-02-01 17:56:45 +00001699#endif
1700
Daniel Veillard70cab352002-02-06 16:06:58 +00001701 /*
1702 * Find the function, it should be there it was there at lookup
1703 */
Daniel Veillardd2379012002-03-15 22:24:56 +00001704 for (i = 0; i < libxml_xpathCallbacksNb; i++) {
1705 if ( /* TODO (ctxt == libxml_xpathCallbacks[i].ctx) && */
1706 (xmlStrEqual(name, libxml_xpathCallbacks[i].name)) &&
1707 (xmlStrEqual(ns_uri, libxml_xpathCallbacks[i].ns_uri))) {
1708 current_function = libxml_xpathCallbacks[i].function;
1709 }
Daniel Veillard70cab352002-02-06 16:06:58 +00001710 }
1711 if (current_function == NULL) {
Daniel Veillardd2379012002-03-15 22:24:56 +00001712 printf
1713 ("libxml_xmlXPathFuncCallback: internal error %s not found !\n",
1714 name);
1715 return;
Daniel Veillard70cab352002-02-06 16:06:58 +00001716 }
1717
Daniel Veillardc575b992002-02-08 13:28:40 +00001718 list = PyTuple_New(nargs + 1);
1719 PyTuple_SetItem(list, 0, libxml_xmlXPathParserContextPtrWrap(ctxt));
Daniel Veillardd2379012002-03-15 22:24:56 +00001720 for (i = 0; i < nargs; i++) {
1721 obj = valuePop(ctxt);
1722 cur = libxml_xmlXPathObjectPtrWrap(obj);
1723 PyTuple_SetItem(list, i + 1, cur);
Daniel Veillarda7340c82002-02-01 17:56:45 +00001724 }
1725 result = PyEval_CallObject(current_function, list);
1726 Py_DECREF(list);
1727
1728 obj = libxml_xmlXPathObjectPtrConvert(result);
1729 valuePush(ctxt, obj);
1730}
1731
1732static xmlXPathFunction
Daniel Veillardd2379012002-03-15 22:24:56 +00001733libxml_xmlXPathFuncLookupFunc(void *ctxt, const xmlChar * name,
1734 const xmlChar * ns_uri)
1735{
Daniel Veillarda7340c82002-02-01 17:56:45 +00001736 int i;
Daniel Veillardd2379012002-03-15 22:24:56 +00001737
Daniel Veillarda7340c82002-02-01 17:56:45 +00001738#ifdef DEBUG_XPATH
1739 printf("libxml_xmlXPathFuncLookupFunc(%p, %s, %s) called\n",
Daniel Veillardd2379012002-03-15 22:24:56 +00001740 ctxt, name, ns_uri);
Daniel Veillarda7340c82002-02-01 17:56:45 +00001741#endif
Daniel Veillard70cab352002-02-06 16:06:58 +00001742 /*
1743 * This is called once only. The address is then stored in the
1744 * XPath expression evaluation, the proper object to call can
1745 * then still be found using the execution context function
1746 * and functionURI fields.
1747 */
Daniel Veillardd2379012002-03-15 22:24:56 +00001748 for (i = 0; i < libxml_xpathCallbacksNb; i++) {
1749 if ((ctxt == libxml_xpathCallbacks[i].ctx) &&
1750 (xmlStrEqual(name, libxml_xpathCallbacks[i].name)) &&
1751 (xmlStrEqual(ns_uri, libxml_xpathCallbacks[i].ns_uri))) {
1752 return (libxml_xmlXPathFuncCallback);
1753 }
Daniel Veillarda7340c82002-02-01 17:56:45 +00001754 }
Daniel Veillardd2379012002-03-15 22:24:56 +00001755 return (NULL);
Daniel Veillarda7340c82002-02-01 17:56:45 +00001756}
1757
1758static void
Daniel Veillardd2379012002-03-15 22:24:56 +00001759libxml_xpathCallbacksInitialize(void)
1760{
Daniel Veillarda7340c82002-02-01 17:56:45 +00001761 int i;
1762
1763 if (libxml_xpathCallbacksInitialized != 0)
Daniel Veillardd2379012002-03-15 22:24:56 +00001764 return;
Daniel Veillarda7340c82002-02-01 17:56:45 +00001765
1766#ifdef DEBUG_XPATH
1767 printf("libxml_xpathCallbacksInitialized called\n");
1768#endif
1769
Daniel Veillardd2379012002-03-15 22:24:56 +00001770 for (i = 0; i < 10; i++) {
1771 libxml_xpathCallbacks[i].ctx = NULL;
1772 libxml_xpathCallbacks[i].name = NULL;
1773 libxml_xpathCallbacks[i].ns_uri = NULL;
1774 libxml_xpathCallbacks[i].function = NULL;
Daniel Veillarda7340c82002-02-01 17:56:45 +00001775 }
Daniel Veillarda7340c82002-02-01 17:56:45 +00001776 libxml_xpathCallbacksInitialized = 1;
1777}
1778
1779PyObject *
Daniel Veillardd2379012002-03-15 22:24:56 +00001780libxml_xmlRegisterXPathFunction(ATTRIBUTE_UNUSED PyObject * self,
1781 PyObject * args)
1782{
Daniel Veillarda7340c82002-02-01 17:56:45 +00001783 PyObject *py_retval;
1784 int c_retval = 0;
1785 xmlChar *name;
1786 xmlChar *ns_uri;
1787 xmlXPathContextPtr ctx;
1788 PyObject *pyobj_ctx;
1789 PyObject *pyobj_f;
1790 int i;
1791
Daniel Veillardd2379012002-03-15 22:24:56 +00001792 if (!PyArg_ParseTuple
1793 (args, (char *) "OszO:registerXPathFunction", &pyobj_ctx, &name,
1794 &ns_uri, &pyobj_f))
1795 return (NULL);
Daniel Veillarda7340c82002-02-01 17:56:45 +00001796
1797 ctx = (xmlXPathContextPtr) PyxmlXPathContext_Get(pyobj_ctx);
1798 if (libxml_xpathCallbacksInitialized == 0)
Daniel Veillardd2379012002-03-15 22:24:56 +00001799 libxml_xpathCallbacksInitialize();
Daniel Veillarda7340c82002-02-01 17:56:45 +00001800 xmlXPathRegisterFuncLookup(ctx, libxml_xmlXPathFuncLookupFunc, ctx);
1801
1802 if ((pyobj_ctx == NULL) || (name == NULL) || (pyobj_f == NULL)) {
Daniel Veillardd2379012002-03-15 22:24:56 +00001803 py_retval = libxml_intWrap(-1);
1804 return (py_retval);
Daniel Veillarda7340c82002-02-01 17:56:45 +00001805 }
Daniel Veillarda7340c82002-02-01 17:56:45 +00001806#ifdef DEBUG_XPATH
1807 printf("libxml_registerXPathFunction(%p, %s, %s) called\n",
Daniel Veillardd2379012002-03-15 22:24:56 +00001808 ctx, name, ns_uri);
Daniel Veillarda7340c82002-02-01 17:56:45 +00001809#endif
Daniel Veillardd2379012002-03-15 22:24:56 +00001810 for (i = 0; i < libxml_xpathCallbacksNb; i++) {
1811 if ((ctx == libxml_xpathCallbacks[i].ctx) &&
1812 (xmlStrEqual(name, libxml_xpathCallbacks[i].name)) &&
1813 (xmlStrEqual(ns_uri, libxml_xpathCallbacks[i].ns_uri))) {
1814 Py_XINCREF(pyobj_f);
1815 Py_XDECREF(libxml_xpathCallbacks[i].function);
1816 libxml_xpathCallbacks[i].function = pyobj_f;
1817 c_retval = 1;
1818 goto done;
1819 }
Daniel Veillarda7340c82002-02-01 17:56:45 +00001820 }
1821 if (libxml_xpathCallbacksNb >= libxml_xpathCallbacksMax) {
Daniel Veillardd2379012002-03-15 22:24:56 +00001822 printf("libxml_registerXPathFunction() table full\n");
Daniel Veillarda7340c82002-02-01 17:56:45 +00001823 } else {
Daniel Veillardd2379012002-03-15 22:24:56 +00001824 i = libxml_xpathCallbacksNb++;
1825 Py_XINCREF(pyobj_f);
Daniel Veillarda7340c82002-02-01 17:56:45 +00001826 libxml_xpathCallbacks[i].ctx = ctx;
1827 libxml_xpathCallbacks[i].name = xmlStrdup(name);
1828 libxml_xpathCallbacks[i].ns_uri = xmlStrdup(ns_uri);
Daniel Veillardd2379012002-03-15 22:24:56 +00001829 libxml_xpathCallbacks[i].function = pyobj_f;
1830 c_retval = 1;
Daniel Veillarda7340c82002-02-01 17:56:45 +00001831 }
Daniel Veillardd2379012002-03-15 22:24:56 +00001832 done:
Daniel Veillarda7340c82002-02-01 17:56:45 +00001833 py_retval = libxml_intWrap((int) c_retval);
Daniel Veillardd2379012002-03-15 22:24:56 +00001834 return (py_retval);
Daniel Veillarda7340c82002-02-01 17:56:45 +00001835}
1836
Daniel Veillard1971ee22002-01-31 20:29:19 +00001837/************************************************************************
1838 * *
Daniel Veillardd2897fd2002-01-30 16:37:32 +00001839 * Global properties access *
1840 * *
1841 ************************************************************************/
1842static PyObject *
Daniel Veillardd2379012002-03-15 22:24:56 +00001843libxml_name(ATTRIBUTE_UNUSED PyObject * self, PyObject * args)
Daniel Veillardd2897fd2002-01-30 16:37:32 +00001844{
1845 PyObject *resultobj, *obj;
1846 xmlNodePtr cur;
1847 const xmlChar *res;
1848
Daniel Veillardd2379012002-03-15 22:24:56 +00001849 if (!PyArg_ParseTuple(args, (char *) "O:name", &obj))
Daniel Veillardd2897fd2002-01-30 16:37:32 +00001850 return NULL;
1851 cur = PyxmlNode_Get(obj);
1852
1853#ifdef DEBUG
1854 printf("libxml_name: cur = %p type %d\n", cur, cur->type);
1855#endif
1856
Daniel Veillardd2379012002-03-15 22:24:56 +00001857 switch (cur->type) {
1858 case XML_DOCUMENT_NODE:
Daniel Veillardd2897fd2002-01-30 16:37:32 +00001859#ifdef LIBXML_DOCB_ENABLED
Daniel Veillardd2379012002-03-15 22:24:56 +00001860 case XML_DOCB_DOCUMENT_NODE:
Daniel Veillardd2897fd2002-01-30 16:37:32 +00001861#endif
Daniel Veillardd2379012002-03-15 22:24:56 +00001862 case XML_HTML_DOCUMENT_NODE:{
1863 xmlDocPtr doc = (xmlDocPtr) cur;
1864
1865 res = doc->URL;
1866 break;
1867 }
1868 case XML_ATTRIBUTE_NODE:{
1869 xmlAttrPtr attr = (xmlAttrPtr) cur;
1870
1871 res = attr->name;
1872 break;
1873 }
1874 case XML_NAMESPACE_DECL:{
1875 xmlNsPtr ns = (xmlNsPtr) cur;
1876
1877 res = ns->prefix;
1878 break;
1879 }
1880 default:
1881 res = cur->name;
1882 break;
Daniel Veillardd2897fd2002-01-30 16:37:32 +00001883 }
Daniel Veillard1971ee22002-01-31 20:29:19 +00001884 resultobj = libxml_constxmlCharPtrWrap(res);
Daniel Veillardd2897fd2002-01-30 16:37:32 +00001885
1886 return resultobj;
1887}
1888
1889static PyObject *
Daniel Veillardd2379012002-03-15 22:24:56 +00001890libxml_doc(ATTRIBUTE_UNUSED PyObject * self, PyObject * args)
Daniel Veillardd2897fd2002-01-30 16:37:32 +00001891{
1892 PyObject *resultobj, *obj;
1893 xmlNodePtr cur;
1894 xmlDocPtr res;
1895
Daniel Veillardd2379012002-03-15 22:24:56 +00001896 if (!PyArg_ParseTuple(args, (char *) "O:doc", &obj))
Daniel Veillardd2897fd2002-01-30 16:37:32 +00001897 return NULL;
1898 cur = PyxmlNode_Get(obj);
1899
1900#ifdef DEBUG
1901 printf("libxml_doc: cur = %p\n", cur);
1902#endif
1903
Daniel Veillardd2379012002-03-15 22:24:56 +00001904 switch (cur->type) {
1905 case XML_DOCUMENT_NODE:
Daniel Veillardd2897fd2002-01-30 16:37:32 +00001906#ifdef LIBXML_DOCB_ENABLED
Daniel Veillardd2379012002-03-15 22:24:56 +00001907 case XML_DOCB_DOCUMENT_NODE:
Daniel Veillardd2897fd2002-01-30 16:37:32 +00001908#endif
Daniel Veillardd2379012002-03-15 22:24:56 +00001909 case XML_HTML_DOCUMENT_NODE:
1910 res = NULL;
1911 break;
1912 case XML_ATTRIBUTE_NODE:{
1913 xmlAttrPtr attr = (xmlAttrPtr) cur;
1914
1915 res = attr->doc;
1916 break;
1917 }
1918 case XML_NAMESPACE_DECL:
1919 res = NULL;
1920 break;
1921 default:
1922 res = cur->doc;
1923 break;
Daniel Veillardd2897fd2002-01-30 16:37:32 +00001924 }
1925 resultobj = libxml_xmlDocPtrWrap(res);
1926 return resultobj;
1927}
1928
1929static PyObject *
Daniel Veillardd2379012002-03-15 22:24:56 +00001930libxml_properties(ATTRIBUTE_UNUSED PyObject * self, PyObject * args)
Daniel Veillardd2897fd2002-01-30 16:37:32 +00001931{
1932 PyObject *resultobj, *obj;
1933 xmlNodePtr cur = NULL;
1934 xmlAttrPtr res;
1935
Daniel Veillardd2379012002-03-15 22:24:56 +00001936 if (!PyArg_ParseTuple(args, (char *) "O:properties", &obj))
Daniel Veillardd2897fd2002-01-30 16:37:32 +00001937 return NULL;
1938 cur = PyxmlNode_Get(obj);
1939 if (cur->type == XML_ELEMENT_NODE)
Daniel Veillardd2379012002-03-15 22:24:56 +00001940 res = cur->properties;
Daniel Veillardd2897fd2002-01-30 16:37:32 +00001941 else
Daniel Veillardd2379012002-03-15 22:24:56 +00001942 res = NULL;
Daniel Veillardd2897fd2002-01-30 16:37:32 +00001943 resultobj = libxml_xmlAttrPtrWrap(res);
1944 return resultobj;
1945}
1946
1947static PyObject *
Daniel Veillardd2379012002-03-15 22:24:56 +00001948libxml_next(ATTRIBUTE_UNUSED PyObject * self, PyObject * args)
Daniel Veillardd2897fd2002-01-30 16:37:32 +00001949{
1950 PyObject *resultobj, *obj;
1951 xmlNodePtr cur;
1952 xmlNodePtr res;
1953
Daniel Veillardd2379012002-03-15 22:24:56 +00001954 if (!PyArg_ParseTuple(args, (char *) "O:next", &obj))
Daniel Veillardd2897fd2002-01-30 16:37:32 +00001955 return NULL;
1956 cur = PyxmlNode_Get(obj);
1957
1958#ifdef DEBUG
1959 printf("libxml_next: cur = %p\n", cur);
1960#endif
1961
Daniel Veillardd2379012002-03-15 22:24:56 +00001962 switch (cur->type) {
1963 case XML_DOCUMENT_NODE:
Daniel Veillardd2897fd2002-01-30 16:37:32 +00001964#ifdef LIBXML_DOCB_ENABLED
Daniel Veillardd2379012002-03-15 22:24:56 +00001965 case XML_DOCB_DOCUMENT_NODE:
Daniel Veillardd2897fd2002-01-30 16:37:32 +00001966#endif
Daniel Veillardd2379012002-03-15 22:24:56 +00001967 case XML_HTML_DOCUMENT_NODE:
1968 res = NULL;
1969 break;
1970 case XML_ATTRIBUTE_NODE:{
1971 xmlAttrPtr attr = (xmlAttrPtr) cur;
1972
1973 res = (xmlNodePtr) attr->next;
1974 break;
1975 }
1976 case XML_NAMESPACE_DECL:{
1977 xmlNsPtr ns = (xmlNsPtr) cur;
1978
1979 res = (xmlNodePtr) ns->next;
1980 break;
1981 }
1982 default:
1983 res = cur->next;
1984 break;
Daniel Veillardd2897fd2002-01-30 16:37:32 +00001985
1986 }
1987 resultobj = libxml_xmlNodePtrWrap(res);
1988 return resultobj;
1989}
1990
1991static PyObject *
Daniel Veillardd2379012002-03-15 22:24:56 +00001992libxml_prev(ATTRIBUTE_UNUSED PyObject * self, PyObject * args)
Daniel Veillardd2897fd2002-01-30 16:37:32 +00001993{
1994 PyObject *resultobj, *obj;
1995 xmlNodePtr cur;
1996 xmlNodePtr res;
1997
Daniel Veillardd2379012002-03-15 22:24:56 +00001998 if (!PyArg_ParseTuple(args, (char *) "O:prev", &obj))
Daniel Veillardd2897fd2002-01-30 16:37:32 +00001999 return NULL;
2000 cur = PyxmlNode_Get(obj);
2001
2002#ifdef DEBUG
2003 printf("libxml_prev: cur = %p\n", cur);
2004#endif
2005
Daniel Veillardd2379012002-03-15 22:24:56 +00002006 switch (cur->type) {
2007 case XML_DOCUMENT_NODE:
Daniel Veillardd2897fd2002-01-30 16:37:32 +00002008#ifdef LIBXML_DOCB_ENABLED
Daniel Veillardd2379012002-03-15 22:24:56 +00002009 case XML_DOCB_DOCUMENT_NODE:
Daniel Veillardd2897fd2002-01-30 16:37:32 +00002010#endif
Daniel Veillardd2379012002-03-15 22:24:56 +00002011 case XML_HTML_DOCUMENT_NODE:
2012 res = NULL;
2013 break;
2014 case XML_ATTRIBUTE_NODE:{
2015 xmlAttrPtr attr = (xmlAttrPtr) cur;
2016
Daniel Veillardfaa35ff2002-11-24 13:53:43 +00002017 res = (xmlNodePtr) attr->prev;
Daniel Veillardd2379012002-03-15 22:24:56 +00002018 }
2019 case XML_NAMESPACE_DECL:
2020 res = NULL;
2021 break;
2022 default:
Daniel Veillardfaa35ff2002-11-24 13:53:43 +00002023 res = cur->prev;
Daniel Veillardd2379012002-03-15 22:24:56 +00002024 break;
Daniel Veillardd2897fd2002-01-30 16:37:32 +00002025 }
2026 resultobj = libxml_xmlNodePtrWrap(res);
2027 return resultobj;
2028}
2029
2030static PyObject *
Daniel Veillardd2379012002-03-15 22:24:56 +00002031libxml_children(ATTRIBUTE_UNUSED PyObject * self, PyObject * args)
Daniel Veillardd2897fd2002-01-30 16:37:32 +00002032{
2033 PyObject *resultobj, *obj;
2034 xmlNodePtr cur;
2035 xmlNodePtr res;
2036
Daniel Veillardd2379012002-03-15 22:24:56 +00002037 if (!PyArg_ParseTuple(args, (char *) "O:children", &obj))
Daniel Veillardd2897fd2002-01-30 16:37:32 +00002038 return NULL;
2039 cur = PyxmlNode_Get(obj);
2040
2041#ifdef DEBUG
2042 printf("libxml_children: cur = %p\n", cur);
2043#endif
2044
Daniel Veillardd2379012002-03-15 22:24:56 +00002045 switch (cur->type) {
2046 case XML_ELEMENT_NODE:
2047 case XML_ENTITY_REF_NODE:
2048 case XML_ENTITY_NODE:
2049 case XML_PI_NODE:
2050 case XML_COMMENT_NODE:
2051 case XML_DOCUMENT_NODE:
Daniel Veillardd2897fd2002-01-30 16:37:32 +00002052#ifdef LIBXML_DOCB_ENABLED
Daniel Veillardd2379012002-03-15 22:24:56 +00002053 case XML_DOCB_DOCUMENT_NODE:
Daniel Veillardd2897fd2002-01-30 16:37:32 +00002054#endif
Daniel Veillardd2379012002-03-15 22:24:56 +00002055 case XML_HTML_DOCUMENT_NODE:
2056 case XML_DTD_NODE:
2057 res = cur->children;
2058 break;
2059 case XML_ATTRIBUTE_NODE:{
2060 xmlAttrPtr attr = (xmlAttrPtr) cur;
2061
2062 res = attr->children;
2063 break;
2064 }
2065 default:
2066 res = NULL;
2067 break;
Daniel Veillardd2897fd2002-01-30 16:37:32 +00002068 }
2069 resultobj = libxml_xmlNodePtrWrap(res);
2070 return resultobj;
2071}
2072
2073static PyObject *
Daniel Veillardd2379012002-03-15 22:24:56 +00002074libxml_last(ATTRIBUTE_UNUSED PyObject * self, PyObject * args)
Daniel Veillardd2897fd2002-01-30 16:37:32 +00002075{
2076 PyObject *resultobj, *obj;
2077 xmlNodePtr cur;
2078 xmlNodePtr res;
2079
Daniel Veillardd2379012002-03-15 22:24:56 +00002080 if (!PyArg_ParseTuple(args, (char *) "O:last", &obj))
Daniel Veillardd2897fd2002-01-30 16:37:32 +00002081 return NULL;
2082 cur = PyxmlNode_Get(obj);
2083
2084#ifdef DEBUG
2085 printf("libxml_last: cur = %p\n", cur);
2086#endif
2087
Daniel Veillardd2379012002-03-15 22:24:56 +00002088 switch (cur->type) {
2089 case XML_ELEMENT_NODE:
2090 case XML_ENTITY_REF_NODE:
2091 case XML_ENTITY_NODE:
2092 case XML_PI_NODE:
2093 case XML_COMMENT_NODE:
2094 case XML_DOCUMENT_NODE:
Daniel Veillardd2897fd2002-01-30 16:37:32 +00002095#ifdef LIBXML_DOCB_ENABLED
Daniel Veillardd2379012002-03-15 22:24:56 +00002096 case XML_DOCB_DOCUMENT_NODE:
Daniel Veillardd2897fd2002-01-30 16:37:32 +00002097#endif
Daniel Veillardd2379012002-03-15 22:24:56 +00002098 case XML_HTML_DOCUMENT_NODE:
2099 case XML_DTD_NODE:
2100 res = cur->last;
2101 break;
2102 case XML_ATTRIBUTE_NODE:{
2103 xmlAttrPtr attr = (xmlAttrPtr) cur;
2104
2105 res = attr->last;
2106 }
2107 default:
2108 res = NULL;
2109 break;
Daniel Veillardd2897fd2002-01-30 16:37:32 +00002110 }
2111 resultobj = libxml_xmlNodePtrWrap(res);
2112 return resultobj;
2113}
2114
2115static PyObject *
Daniel Veillardd2379012002-03-15 22:24:56 +00002116libxml_parent(ATTRIBUTE_UNUSED PyObject * self, PyObject * args)
Daniel Veillardd2897fd2002-01-30 16:37:32 +00002117{
2118 PyObject *resultobj, *obj;
2119 xmlNodePtr cur;
2120 xmlNodePtr res;
2121
Daniel Veillardd2379012002-03-15 22:24:56 +00002122 if (!PyArg_ParseTuple(args, (char *) "O:parent", &obj))
Daniel Veillardd2897fd2002-01-30 16:37:32 +00002123 return NULL;
2124 cur = PyxmlNode_Get(obj);
2125
2126#ifdef DEBUG
2127 printf("libxml_parent: cur = %p\n", cur);
2128#endif
2129
Daniel Veillardd2379012002-03-15 22:24:56 +00002130 switch (cur->type) {
2131 case XML_DOCUMENT_NODE:
2132 case XML_HTML_DOCUMENT_NODE:
Daniel Veillardd2897fd2002-01-30 16:37:32 +00002133#ifdef LIBXML_DOCB_ENABLED
Daniel Veillardd2379012002-03-15 22:24:56 +00002134 case XML_DOCB_DOCUMENT_NODE:
Daniel Veillardd2897fd2002-01-30 16:37:32 +00002135#endif
Daniel Veillardd2379012002-03-15 22:24:56 +00002136 res = NULL;
2137 break;
2138 case XML_ATTRIBUTE_NODE:{
2139 xmlAttrPtr attr = (xmlAttrPtr) cur;
2140
2141 res = attr->parent;
2142 }
2143 case XML_ENTITY_DECL:
2144 case XML_NAMESPACE_DECL:
2145 case XML_XINCLUDE_START:
2146 case XML_XINCLUDE_END:
2147 res = NULL;
2148 break;
2149 default:
2150 res = cur->parent;
2151 break;
Daniel Veillardd2897fd2002-01-30 16:37:32 +00002152 }
2153 resultobj = libxml_xmlNodePtrWrap(res);
2154 return resultobj;
2155}
2156
2157static PyObject *
Daniel Veillardd2379012002-03-15 22:24:56 +00002158libxml_type(ATTRIBUTE_UNUSED PyObject * self, PyObject * args)
Daniel Veillardd2897fd2002-01-30 16:37:32 +00002159{
2160 PyObject *resultobj, *obj;
2161 xmlNodePtr cur;
Daniel Veillardd2379012002-03-15 22:24:56 +00002162 const xmlChar *res = NULL;
Daniel Veillardd2897fd2002-01-30 16:37:32 +00002163
Daniel Veillardd2379012002-03-15 22:24:56 +00002164 if (!PyArg_ParseTuple(args, (char *) "O:last", &obj))
Daniel Veillardd2897fd2002-01-30 16:37:32 +00002165 return NULL;
2166 cur = PyxmlNode_Get(obj);
2167
2168#ifdef DEBUG
2169 printf("libxml_type: cur = %p\n", cur);
2170#endif
2171
Daniel Veillardd2379012002-03-15 22:24:56 +00002172 switch (cur->type) {
Daniel Veillardd2897fd2002-01-30 16:37:32 +00002173 case XML_ELEMENT_NODE:
Daniel Veillardd2379012002-03-15 22:24:56 +00002174 res = (const xmlChar *) "element";
2175 break;
Daniel Veillardd2897fd2002-01-30 16:37:32 +00002176 case XML_ATTRIBUTE_NODE:
Daniel Veillardd2379012002-03-15 22:24:56 +00002177 res = (const xmlChar *) "attribute";
2178 break;
Daniel Veillardd2897fd2002-01-30 16:37:32 +00002179 case XML_TEXT_NODE:
Daniel Veillardd2379012002-03-15 22:24:56 +00002180 res = (const xmlChar *) "text";
2181 break;
Daniel Veillardd2897fd2002-01-30 16:37:32 +00002182 case XML_CDATA_SECTION_NODE:
Daniel Veillardd2379012002-03-15 22:24:56 +00002183 res = (const xmlChar *) "cdata";
2184 break;
Daniel Veillardd2897fd2002-01-30 16:37:32 +00002185 case XML_ENTITY_REF_NODE:
Daniel Veillardd2379012002-03-15 22:24:56 +00002186 res = (const xmlChar *) "entity_ref";
2187 break;
Daniel Veillardd2897fd2002-01-30 16:37:32 +00002188 case XML_ENTITY_NODE:
Daniel Veillardd2379012002-03-15 22:24:56 +00002189 res = (const xmlChar *) "entity";
2190 break;
Daniel Veillardd2897fd2002-01-30 16:37:32 +00002191 case XML_PI_NODE:
Daniel Veillardd2379012002-03-15 22:24:56 +00002192 res = (const xmlChar *) "pi";
2193 break;
Daniel Veillardd2897fd2002-01-30 16:37:32 +00002194 case XML_COMMENT_NODE:
Daniel Veillardd2379012002-03-15 22:24:56 +00002195 res = (const xmlChar *) "comment";
2196 break;
Daniel Veillardd2897fd2002-01-30 16:37:32 +00002197 case XML_DOCUMENT_NODE:
Daniel Veillardd2379012002-03-15 22:24:56 +00002198 res = (const xmlChar *) "document_xml";
2199 break;
Daniel Veillardd2897fd2002-01-30 16:37:32 +00002200 case XML_DOCUMENT_TYPE_NODE:
Daniel Veillardd2379012002-03-15 22:24:56 +00002201 res = (const xmlChar *) "doctype";
2202 break;
Daniel Veillardd2897fd2002-01-30 16:37:32 +00002203 case XML_DOCUMENT_FRAG_NODE:
Daniel Veillardd2379012002-03-15 22:24:56 +00002204 res = (const xmlChar *) "fragment";
2205 break;
Daniel Veillardd2897fd2002-01-30 16:37:32 +00002206 case XML_NOTATION_NODE:
Daniel Veillardd2379012002-03-15 22:24:56 +00002207 res = (const xmlChar *) "notation";
2208 break;
Daniel Veillardd2897fd2002-01-30 16:37:32 +00002209 case XML_HTML_DOCUMENT_NODE:
Daniel Veillardd2379012002-03-15 22:24:56 +00002210 res = (const xmlChar *) "document_html";
2211 break;
Daniel Veillardd2897fd2002-01-30 16:37:32 +00002212 case XML_DTD_NODE:
Daniel Veillardd2379012002-03-15 22:24:56 +00002213 res = (const xmlChar *) "dtd";
2214 break;
Daniel Veillardd2897fd2002-01-30 16:37:32 +00002215 case XML_ELEMENT_DECL:
Daniel Veillardd2379012002-03-15 22:24:56 +00002216 res = (const xmlChar *) "elem_decl";
2217 break;
Daniel Veillardd2897fd2002-01-30 16:37:32 +00002218 case XML_ATTRIBUTE_DECL:
Daniel Veillardd2379012002-03-15 22:24:56 +00002219 res = (const xmlChar *) "attribute_decl";
2220 break;
Daniel Veillardd2897fd2002-01-30 16:37:32 +00002221 case XML_ENTITY_DECL:
Daniel Veillardd2379012002-03-15 22:24:56 +00002222 res = (const xmlChar *) "entity_decl";
2223 break;
Daniel Veillardd2897fd2002-01-30 16:37:32 +00002224 case XML_NAMESPACE_DECL:
Daniel Veillardd2379012002-03-15 22:24:56 +00002225 res = (const xmlChar *) "namespace";
2226 break;
Daniel Veillardd2897fd2002-01-30 16:37:32 +00002227 case XML_XINCLUDE_START:
Daniel Veillardd2379012002-03-15 22:24:56 +00002228 res = (const xmlChar *) "xinclude_start";
2229 break;
Daniel Veillardd2897fd2002-01-30 16:37:32 +00002230 case XML_XINCLUDE_END:
Daniel Veillardd2379012002-03-15 22:24:56 +00002231 res = (const xmlChar *) "xinclude_end";
2232 break;
Daniel Veillardd2897fd2002-01-30 16:37:32 +00002233#ifdef LIBXML_DOCB_ENABLED
Daniel Veillardd2379012002-03-15 22:24:56 +00002234 case XML_DOCB_DOCUMENT_NODE:
2235 res = (const xmlChar *) "document_docbook";
2236 break;
Daniel Veillardd2897fd2002-01-30 16:37:32 +00002237#endif
2238 }
2239#ifdef DEBUG
2240 printf("libxml_type: cur = %p: %s\n", cur, res);
2241#endif
2242
Daniel Veillard1971ee22002-01-31 20:29:19 +00002243 resultobj = libxml_constxmlCharPtrWrap(res);
Daniel Veillardd2897fd2002-01-30 16:37:32 +00002244 return resultobj;
2245}
2246
2247/************************************************************************
2248 * *
Daniel Veillard36eea2d2002-02-04 00:17:01 +00002249 * Specific accessor functions *
2250 * *
2251 ************************************************************************/
2252PyObject *
Daniel Veillardd2379012002-03-15 22:24:56 +00002253libxml_xmlNodeGetNsDefs(ATTRIBUTE_UNUSED PyObject * self, PyObject * args)
2254{
Daniel Veillard36eea2d2002-02-04 00:17:01 +00002255 PyObject *py_retval;
2256 xmlNsPtr c_retval;
2257 xmlNodePtr node;
2258 PyObject *pyobj_node;
2259
Daniel Veillardd2379012002-03-15 22:24:56 +00002260 if (!PyArg_ParseTuple
2261 (args, (char *) "O:xmlNodeGetNsDefs", &pyobj_node))
2262 return (NULL);
Daniel Veillard36eea2d2002-02-04 00:17:01 +00002263 node = (xmlNodePtr) PyxmlNode_Get(pyobj_node);
2264
2265 if ((node == NULL) || (node->type != XML_ELEMENT_NODE)) {
Daniel Veillardd2379012002-03-15 22:24:56 +00002266 Py_INCREF(Py_None);
2267 return (Py_None);
Daniel Veillard36eea2d2002-02-04 00:17:01 +00002268 }
2269 c_retval = node->nsDef;
2270 py_retval = libxml_xmlNsPtrWrap((xmlNsPtr) c_retval);
Daniel Veillardd2379012002-03-15 22:24:56 +00002271 return (py_retval);
Daniel Veillard36eea2d2002-02-04 00:17:01 +00002272}
2273
2274PyObject *
Daniel Veillardd2379012002-03-15 22:24:56 +00002275libxml_xmlNodeGetNs(ATTRIBUTE_UNUSED PyObject * self, PyObject * args)
2276{
Daniel Veillard36eea2d2002-02-04 00:17:01 +00002277 PyObject *py_retval;
2278 xmlNsPtr c_retval;
2279 xmlNodePtr node;
2280 PyObject *pyobj_node;
2281
Daniel Veillardd2379012002-03-15 22:24:56 +00002282 if (!PyArg_ParseTuple(args, (char *) "O:xmlNodeGetNs", &pyobj_node))
2283 return (NULL);
Daniel Veillard36eea2d2002-02-04 00:17:01 +00002284 node = (xmlNodePtr) PyxmlNode_Get(pyobj_node);
2285
2286 if ((node == NULL) || (node->type != XML_ELEMENT_NODE)) {
Daniel Veillardd2379012002-03-15 22:24:56 +00002287 Py_INCREF(Py_None);
2288 return (Py_None);
Daniel Veillard36eea2d2002-02-04 00:17:01 +00002289 }
2290 c_retval = node->ns;
2291 py_retval = libxml_xmlNsPtrWrap((xmlNsPtr) c_retval);
Daniel Veillardd2379012002-03-15 22:24:56 +00002292 return (py_retval);
Daniel Veillard36eea2d2002-02-04 00:17:01 +00002293}
2294
2295/************************************************************************
2296 * *
Daniel Veillard1e774382002-03-06 17:35:40 +00002297 * Serialization front-end *
2298 * *
2299 ************************************************************************/
2300
Daniel Veillardd2379012002-03-15 22:24:56 +00002301static PyObject *
2302libxml_serializeNode(ATTRIBUTE_UNUSED PyObject * self, PyObject * args)
2303{
Daniel Veillard1e774382002-03-06 17:35:40 +00002304 PyObject *py_retval = NULL;
2305 xmlChar *c_retval;
2306 PyObject *pyobj_node;
2307 xmlNodePtr node;
2308 xmlDocPtr doc;
Daniel Veillardd2379012002-03-15 22:24:56 +00002309 const char *encoding;
Daniel Veillard1e774382002-03-06 17:35:40 +00002310 int format;
2311 int len;
2312
Daniel Veillardd2379012002-03-15 22:24:56 +00002313 if (!PyArg_ParseTuple(args, (char *) "Ozi:serializeNode", &pyobj_node,
2314 &encoding, &format))
2315 return (NULL);
Daniel Veillard1e774382002-03-06 17:35:40 +00002316 node = (xmlNodePtr) PyxmlNode_Get(pyobj_node);
2317
2318 if (node == NULL) {
Daniel Veillardd2379012002-03-15 22:24:56 +00002319 Py_INCREF(Py_None);
2320 return (Py_None);
Daniel Veillard1e774382002-03-06 17:35:40 +00002321 }
2322 if (node->type == XML_DOCUMENT_NODE) {
Daniel Veillardd2379012002-03-15 22:24:56 +00002323 doc = (xmlDocPtr) node;
2324 xmlDocDumpFormatMemoryEnc(doc, &c_retval, &len,
2325 (const char *) encoding, format);
2326 py_retval = libxml_charPtrWrap((char *) c_retval);
Daniel Veillard1e774382002-03-06 17:35:40 +00002327 } else if (node->type == XML_HTML_DOCUMENT_NODE) {
Daniel Veillardd2379012002-03-15 22:24:56 +00002328 xmlOutputBufferPtr buf;
2329 xmlCharEncodingHandlerPtr handler = NULL;
Daniel Veillard1e774382002-03-06 17:35:40 +00002330
Daniel Veillardd2379012002-03-15 22:24:56 +00002331 doc = (xmlDocPtr) node;
2332 if (encoding != NULL)
2333 htmlSetMetaEncoding(doc, (const xmlChar *) encoding);
2334 encoding = (const char *) htmlGetMetaEncoding(doc);
Daniel Veillard1e774382002-03-06 17:35:40 +00002335
Daniel Veillardd2379012002-03-15 22:24:56 +00002336 if (encoding != NULL) {
2337 handler = xmlFindCharEncodingHandler(encoding);
2338 if (handler == NULL) {
2339 Py_INCREF(Py_None);
2340 return (Py_None);
2341 }
2342 }
Daniel Veillard1e774382002-03-06 17:35:40 +00002343
Daniel Veillardd2379012002-03-15 22:24:56 +00002344 /*
2345 * Fallback to HTML or ASCII when the encoding is unspecified
2346 */
2347 if (handler == NULL)
2348 handler = xmlFindCharEncodingHandler("HTML");
2349 if (handler == NULL)
2350 handler = xmlFindCharEncodingHandler("ascii");
Daniel Veillard1e774382002-03-06 17:35:40 +00002351
Daniel Veillardd2379012002-03-15 22:24:56 +00002352 buf = xmlAllocOutputBuffer(handler);
2353 if (buf == NULL) {
2354 Py_INCREF(Py_None);
2355 return (Py_None);
2356 }
2357 htmlDocContentDumpFormatOutput(buf, doc, encoding, format);
2358 xmlOutputBufferFlush(buf);
2359 if (buf->conv != NULL) {
2360 len = buf->conv->use;
2361 c_retval = buf->conv->content;
2362 buf->conv->content = NULL;
2363 } else {
2364 len = buf->buffer->use;
2365 c_retval = buf->buffer->content;
2366 buf->buffer->content = NULL;
2367 }
2368 (void) xmlOutputBufferClose(buf);
2369 py_retval = libxml_charPtrWrap((char *) c_retval);
Daniel Veillard1e774382002-03-06 17:35:40 +00002370 } else {
Daniel Veillardd2379012002-03-15 22:24:56 +00002371 doc = node->doc;
Daniel Veillarda8c0adb2002-11-17 22:37:35 +00002372 if ((doc == NULL) || (doc->type == XML_DOCUMENT_NODE)) {
Daniel Veillardd2379012002-03-15 22:24:56 +00002373 xmlOutputBufferPtr buf;
2374 xmlCharEncodingHandlerPtr handler = NULL;
Daniel Veillard1e774382002-03-06 17:35:40 +00002375
Daniel Veillardd2379012002-03-15 22:24:56 +00002376 if (encoding != NULL) {
2377 handler = xmlFindCharEncodingHandler(encoding);
2378 if (handler == NULL) {
2379 Py_INCREF(Py_None);
2380 return (Py_None);
2381 }
2382 }
Daniel Veillard1e774382002-03-06 17:35:40 +00002383
Daniel Veillardd2379012002-03-15 22:24:56 +00002384 buf = xmlAllocOutputBuffer(handler);
2385 if (buf == NULL) {
2386 Py_INCREF(Py_None);
2387 return (Py_None);
2388 }
2389 xmlNodeDumpOutput(buf, doc, node, 0, format, encoding);
2390 xmlOutputBufferFlush(buf);
2391 if (buf->conv != NULL) {
2392 len = buf->conv->use;
2393 c_retval = buf->conv->content;
2394 buf->conv->content = NULL;
2395 } else {
2396 len = buf->buffer->use;
2397 c_retval = buf->buffer->content;
2398 buf->buffer->content = NULL;
2399 }
2400 (void) xmlOutputBufferClose(buf);
2401 py_retval = libxml_charPtrWrap((char *) c_retval);
2402 } else if (doc->type == XML_HTML_DOCUMENT_NODE) {
2403 xmlOutputBufferPtr buf;
2404 xmlCharEncodingHandlerPtr handler = NULL;
Daniel Veillard1e774382002-03-06 17:35:40 +00002405
Daniel Veillardd2379012002-03-15 22:24:56 +00002406 if (encoding != NULL)
2407 htmlSetMetaEncoding(doc, (const xmlChar *) encoding);
2408 encoding = (const char *) htmlGetMetaEncoding(doc);
2409 if (encoding != NULL) {
2410 handler = xmlFindCharEncodingHandler(encoding);
2411 if (handler == NULL) {
2412 Py_INCREF(Py_None);
2413 return (Py_None);
2414 }
2415 }
Daniel Veillard1e774382002-03-06 17:35:40 +00002416
Daniel Veillardd2379012002-03-15 22:24:56 +00002417 /*
2418 * Fallback to HTML or ASCII when the encoding is unspecified
2419 */
2420 if (handler == NULL)
2421 handler = xmlFindCharEncodingHandler("HTML");
2422 if (handler == NULL)
2423 handler = xmlFindCharEncodingHandler("ascii");
Daniel Veillard1e774382002-03-06 17:35:40 +00002424
Daniel Veillardd2379012002-03-15 22:24:56 +00002425 buf = xmlAllocOutputBuffer(handler);
2426 if (buf == NULL) {
2427 Py_INCREF(Py_None);
2428 return (Py_None);
2429 }
2430 htmlNodeDumpFormatOutput(buf, doc, node, encoding, format);
2431 xmlOutputBufferFlush(buf);
2432 if (buf->conv != NULL) {
2433 len = buf->conv->use;
2434 c_retval = buf->conv->content;
2435 buf->conv->content = NULL;
2436 } else {
2437 len = buf->buffer->use;
2438 c_retval = buf->buffer->content;
2439 buf->buffer->content = NULL;
2440 }
2441 (void) xmlOutputBufferClose(buf);
2442 py_retval = libxml_charPtrWrap((char *) c_retval);
2443 } else {
2444 Py_INCREF(Py_None);
2445 return (Py_None);
2446 }
Daniel Veillard1e774382002-03-06 17:35:40 +00002447 }
Daniel Veillardd2379012002-03-15 22:24:56 +00002448 return (py_retval);
Daniel Veillard1e774382002-03-06 17:35:40 +00002449}
2450
Daniel Veillardd2379012002-03-15 22:24:56 +00002451static PyObject *
2452libxml_saveNodeTo(ATTRIBUTE_UNUSED PyObject * self, PyObject * args)
2453{
Daniel Veillard1e774382002-03-06 17:35:40 +00002454 PyObject *py_file = NULL;
2455 FILE *output;
2456 PyObject *pyobj_node;
2457 xmlNodePtr node;
2458 xmlDocPtr doc;
Daniel Veillardd2379012002-03-15 22:24:56 +00002459 const char *encoding;
Daniel Veillard1e774382002-03-06 17:35:40 +00002460 int format;
2461 int len;
2462 xmlOutputBufferPtr buf;
2463 xmlCharEncodingHandlerPtr handler = NULL;
2464
Daniel Veillardd2379012002-03-15 22:24:56 +00002465 if (!PyArg_ParseTuple(args, (char *) "OOzi:serializeNode", &pyobj_node,
2466 &py_file, &encoding, &format))
2467 return (NULL);
Daniel Veillard1e774382002-03-06 17:35:40 +00002468 node = (xmlNodePtr) PyxmlNode_Get(pyobj_node);
2469
2470 if (node == NULL) {
Daniel Veillardd2379012002-03-15 22:24:56 +00002471 return (PyInt_FromLong((long) -1));
Daniel Veillard1e774382002-03-06 17:35:40 +00002472 }
2473 if ((py_file == NULL) || (!(PyFile_Check(py_file)))) {
Daniel Veillardd2379012002-03-15 22:24:56 +00002474 return (PyInt_FromLong((long) -1));
Daniel Veillard1e774382002-03-06 17:35:40 +00002475 }
2476 output = PyFile_AsFile(py_file);
2477 if (output == NULL) {
Daniel Veillardd2379012002-03-15 22:24:56 +00002478 return (PyInt_FromLong((long) -1));
Daniel Veillard1e774382002-03-06 17:35:40 +00002479 }
2480
2481 if (node->type == XML_DOCUMENT_NODE) {
Daniel Veillardd2379012002-03-15 22:24:56 +00002482 doc = (xmlDocPtr) node;
Daniel Veillard1e774382002-03-06 17:35:40 +00002483 } else if (node->type == XML_HTML_DOCUMENT_NODE) {
Daniel Veillardd2379012002-03-15 22:24:56 +00002484 doc = (xmlDocPtr) node;
Daniel Veillard1e774382002-03-06 17:35:40 +00002485 } else {
Daniel Veillardd2379012002-03-15 22:24:56 +00002486 doc = node->doc;
Daniel Veillard1e774382002-03-06 17:35:40 +00002487 }
2488 if (doc->type == XML_HTML_DOCUMENT_NODE) {
Daniel Veillardd2379012002-03-15 22:24:56 +00002489 if (encoding == NULL)
2490 encoding = (const char *) htmlGetMetaEncoding(doc);
Daniel Veillard1e774382002-03-06 17:35:40 +00002491 }
2492 if (encoding != NULL) {
Daniel Veillardd2379012002-03-15 22:24:56 +00002493 handler = xmlFindCharEncodingHandler(encoding);
2494 if (handler == NULL) {
2495 return (PyInt_FromLong((long) -1));
2496 }
Daniel Veillard1e774382002-03-06 17:35:40 +00002497 }
2498 if (doc->type == XML_HTML_DOCUMENT_NODE) {
Daniel Veillardd2379012002-03-15 22:24:56 +00002499 if (handler == NULL)
2500 handler = xmlFindCharEncodingHandler("HTML");
2501 if (handler == NULL)
2502 handler = xmlFindCharEncodingHandler("ascii");
Daniel Veillard1e774382002-03-06 17:35:40 +00002503 }
2504
2505 buf = xmlOutputBufferCreateFile(output, handler);
2506 if (node->type == XML_DOCUMENT_NODE) {
Daniel Veillardd2379012002-03-15 22:24:56 +00002507 len = xmlSaveFormatFileTo(buf, doc, encoding, format);
Daniel Veillard1e774382002-03-06 17:35:40 +00002508 } else if (node->type == XML_HTML_DOCUMENT_NODE) {
Daniel Veillardd2379012002-03-15 22:24:56 +00002509 htmlDocContentDumpFormatOutput(buf, doc, encoding, format);
2510 len = xmlOutputBufferClose(buf);
Daniel Veillard1e774382002-03-06 17:35:40 +00002511 } else if (doc->type == XML_HTML_DOCUMENT_NODE) {
Daniel Veillardd2379012002-03-15 22:24:56 +00002512 htmlNodeDumpFormatOutput(buf, doc, node, encoding, format);
2513 len = xmlOutputBufferClose(buf);
Daniel Veillard1e774382002-03-06 17:35:40 +00002514 } else {
Daniel Veillardd2379012002-03-15 22:24:56 +00002515 xmlNodeDumpOutput(buf, doc, node, 0, format, encoding);
2516 len = xmlOutputBufferClose(buf);
Daniel Veillard1e774382002-03-06 17:35:40 +00002517 }
Daniel Veillardd2379012002-03-15 22:24:56 +00002518 return (PyInt_FromLong((long) len));
Daniel Veillard1e774382002-03-06 17:35:40 +00002519}
2520
2521/************************************************************************
2522 * *
Daniel Veillarda94ec6f2002-03-01 13:00:53 +00002523 * Extra stuff *
2524 * *
2525 ************************************************************************/
2526PyObject *
Daniel Veillardd2379012002-03-15 22:24:56 +00002527libxml_xmlNewNode(ATTRIBUTE_UNUSED PyObject * self, PyObject * args)
2528{
Daniel Veillarda94ec6f2002-03-01 13:00:53 +00002529 PyObject *py_retval;
Daniel Veillardd2379012002-03-15 22:24:56 +00002530 xmlChar *name;
Daniel Veillarda94ec6f2002-03-01 13:00:53 +00002531 xmlNodePtr node;
2532
Daniel Veillardd2379012002-03-15 22:24:56 +00002533 if (!PyArg_ParseTuple(args, (char *) "s:xmlNewNode", &name))
2534 return (NULL);
Daniel Veillarda94ec6f2002-03-01 13:00:53 +00002535 node = (xmlNodePtr) xmlNewNode(NULL, name);
Daniel Veillard3b2e4e12003-02-03 08:52:58 +00002536#ifdef DEBUG
Daniel Veillardd2379012002-03-15 22:24:56 +00002537 printf("NewNode: %s : %p\n", name, (void *) node);
Daniel Veillard3b2e4e12003-02-03 08:52:58 +00002538#endif
Daniel Veillarda94ec6f2002-03-01 13:00:53 +00002539
2540 if (node == NULL) {
Daniel Veillardd2379012002-03-15 22:24:56 +00002541 Py_INCREF(Py_None);
2542 return (Py_None);
Daniel Veillarda94ec6f2002-03-01 13:00:53 +00002543 }
2544 py_retval = libxml_xmlNodePtrWrap(node);
Daniel Veillardd2379012002-03-15 22:24:56 +00002545 return (py_retval);
Daniel Veillarda94ec6f2002-03-01 13:00:53 +00002546}
2547
2548/************************************************************************
2549 * *
Daniel Veillardd2897fd2002-01-30 16:37:32 +00002550 * The registration stuff *
2551 * *
2552 ************************************************************************/
2553static PyMethodDef libxmlMethods[] = {
Daniel Veillard96fe0952002-01-30 20:52:23 +00002554#include "libxml2-export.c"
Daniel Veillardd2379012002-03-15 22:24:56 +00002555 {(char *) "name", libxml_name, METH_VARARGS, NULL},
2556 {(char *) "children", libxml_children, METH_VARARGS, NULL},
2557 {(char *) "properties", libxml_properties, METH_VARARGS, NULL},
2558 {(char *) "last", libxml_last, METH_VARARGS, NULL},
2559 {(char *) "prev", libxml_prev, METH_VARARGS, NULL},
2560 {(char *) "next", libxml_next, METH_VARARGS, NULL},
2561 {(char *) "parent", libxml_parent, METH_VARARGS, NULL},
2562 {(char *) "type", libxml_type, METH_VARARGS, NULL},
2563 {(char *) "doc", libxml_doc, METH_VARARGS, NULL},
2564 {(char *) "xmlNewNode", libxml_xmlNewNode, METH_VARARGS, NULL},
2565 {(char *) "serializeNode", libxml_serializeNode, METH_VARARGS, NULL},
2566 {(char *) "saveNodeTo", libxml_saveNodeTo, METH_VARARGS, NULL},
Daniel Veillardc6d4a932002-09-12 15:00:57 +00002567 {(char *) "outputBufferCreate", libxml_xmlCreateOutputBuffer, METH_VARARGS, NULL},
2568 {(char *) "inputBufferCreate", libxml_xmlCreateInputBuffer, METH_VARARGS, NULL},
2569 {(char *) "setEntityLoader", libxml_xmlSetEntityLoader, METH_VARARGS, NULL},
Daniel Veillard3e20a292003-01-10 13:14:40 +00002570 {(char *)"xmlRegisterErrorHandler", libxml_xmlRegisterErrorHandler, METH_VARARGS, NULL },
Daniel Veillard417be3a2003-01-20 21:26:34 +00002571 {(char *)"xmlParserCtxtSetErrorHandler", libxml_xmlParserCtxtSetErrorHandler, METH_VARARGS, NULL },
2572 {(char *)"xmlParserCtxtGetErrorHandler", libxml_xmlParserCtxtGetErrorHandler, METH_VARARGS, NULL },
Daniel Veillarde6227e02003-01-14 11:42:39 +00002573 {(char *)"xmlFreeParserCtxt", libxml_xmlFreeParserCtxt, METH_VARARGS, NULL },
Daniel Veillard26f70262003-01-16 22:45:08 +00002574 {(char *)"xmlTextReaderSetErrorHandler", libxml_xmlTextReaderSetErrorHandler, METH_VARARGS, NULL },
2575 {(char *)"xmlTextReaderGetErrorHandler", libxml_xmlTextReaderGetErrorHandler, METH_VARARGS, NULL },
2576 {(char *)"xmlFreeTextReader", libxml_xmlFreeTextReader, METH_VARARGS, NULL },
Daniel Veillardd2379012002-03-15 22:24:56 +00002577 {NULL, NULL, 0, NULL}
Daniel Veillardd2897fd2002-01-30 16:37:32 +00002578};
2579
Daniel Veillard0fea6f42002-02-22 22:51:13 +00002580#ifdef MERGED_MODULES
Daniel Veillard6361da02002-02-23 10:10:33 +00002581extern void initlibxsltmod(void);
Daniel Veillard0fea6f42002-02-22 22:51:13 +00002582#endif
2583
Daniel Veillardd2379012002-03-15 22:24:56 +00002584void
2585initlibxml2mod(void)
2586{
Daniel Veillardaf43f632002-03-08 15:05:20 +00002587 static int initialized = 0;
Daniel Veillard3ce52572002-02-03 15:08:05 +00002588 PyObject *m;
Daniel Veillardaf43f632002-03-08 15:05:20 +00002589
2590 if (initialized != 0)
Daniel Veillardd2379012002-03-15 22:24:56 +00002591 return;
Daniel Veillardc6d4a932002-09-12 15:00:57 +00002592 xmlRegisterDefaultOutputCallbacks();
2593 xmlRegisterDefaultInputCallbacks();
Daniel Veillardd2379012002-03-15 22:24:56 +00002594 m = Py_InitModule((char *) "libxml2mod", libxmlMethods);
Daniel Veillardaf43f632002-03-08 15:05:20 +00002595 initialized = 1;
Daniel Veillard5d819032002-02-02 21:49:17 +00002596 libxml_xmlErrorInitialize();
Daniel Veillard6361da02002-02-23 10:10:33 +00002597
Daniel Veillard0fea6f42002-02-22 22:51:13 +00002598#ifdef MERGED_MODULES
2599 initlibxsltmod();
2600#endif
Daniel Veillardd2897fd2002-01-30 16:37:32 +00002601}