blob: 2cc543a83df3562c435fc8edc2228d090b34e78e [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 Veillardd2379012002-03-15 22:24:56 +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
28/* #define DEBUG */
Daniel Veillard797a5652002-02-12 13:46:21 +000029/* #define DEBUG_SAX */
Daniel Veillarda7340c82002-02-01 17:56:45 +000030/* #define DEBUG_XPATH */
Daniel Veillard5d819032002-02-02 21:49:17 +000031/* #define DEBUG_ERROR */
Daniel Veillard4e1b26c2002-02-03 20:13:06 +000032/* #define DEBUG_MEMORY */
Daniel Veillardc6d4a932002-09-12 15:00:57 +000033/* #define DEBUG_FILES */
34/* #define DEBUG_LOADER */
Daniel Veillard4e1b26c2002-02-03 20:13:06 +000035
Daniel Veillardd2379012002-03-15 22:24:56 +000036void initlibxml2mod(void);
37
Daniel Veillardc6d4a932002-09-12 15:00:57 +000038/**
39 * TODO:
40 *
41 * macro to flag unimplemented blocks
42 */
43#define TODO \
44 xmlGenericError(xmlGenericErrorContext, \
45 "Unimplemented block at %s:%d\n", \
46 __FILE__, __LINE__);
47
Daniel Veillard4e1b26c2002-02-03 20:13:06 +000048/************************************************************************
49 * *
50 * Memory debug interface *
51 * *
52 ************************************************************************/
53
54extern void xmlMemFree(void *ptr);
55extern void *xmlMemMalloc(size_t size);
Daniel Veillardd2379012002-03-15 22:24:56 +000056extern void *xmlMemRealloc(void *ptr, size_t size);
Daniel Veillard4e1b26c2002-02-03 20:13:06 +000057extern char *xmlMemoryStrdup(const char *str);
58
59static int libxmlMemoryDebugActivated = 0;
60static long libxmlMemoryAllocatedBase = 0;
61
62static int libxmlMemoryDebug = 0;
63static xmlFreeFunc freeFunc = NULL;
64static xmlMallocFunc mallocFunc = NULL;
65static xmlReallocFunc reallocFunc = NULL;
66static xmlStrdupFunc strdupFunc = NULL;
67
68PyObject *
Daniel Veillardd2379012002-03-15 22:24:56 +000069libxml_xmlDebugMemory(ATTRIBUTE_UNUSED PyObject * self, PyObject * args)
70{
Daniel Veillard4e1b26c2002-02-03 20:13:06 +000071 int activate;
72 PyObject *py_retval;
73 long ret;
74
Daniel Veillardd2379012002-03-15 22:24:56 +000075 if (!PyArg_ParseTuple(args, (char *) "i:xmlDebugMemory", &activate))
76 return (NULL);
Daniel Veillard4e1b26c2002-02-03 20:13:06 +000077
78#ifdef DEBUG_MEMORY
79 printf("libxml_xmlDebugMemory(%d) called\n", activate);
80#endif
81
82 if (activate != 0) {
Daniel Veillardd2379012002-03-15 22:24:56 +000083 if (libxmlMemoryDebug == 0) {
84 /*
85 * First initialize the library and grab the old memory handlers
86 * and switch the library to memory debugging
87 */
88 xmlMemGet((xmlFreeFunc *) & freeFunc,
89 (xmlMallocFunc *) & mallocFunc,
90 (xmlReallocFunc *) & reallocFunc,
91 (xmlStrdupFunc *) & strdupFunc);
92 if ((freeFunc == xmlMemFree) && (mallocFunc == xmlMemMalloc) &&
93 (reallocFunc == xmlMemRealloc) &&
94 (strdupFunc == xmlMemoryStrdup)) {
95 libxmlMemoryAllocatedBase = xmlMemUsed();
96 } else {
97 ret = (long) xmlMemSetup(xmlMemFree, xmlMemMalloc,
98 xmlMemRealloc, xmlMemoryStrdup);
99 if (ret < 0)
100 goto error;
101 libxmlMemoryAllocatedBase = xmlMemUsed();
102 }
103 xmlInitParser();
104 ret = 0;
105 } else if (libxmlMemoryDebugActivated == 0) {
106 libxmlMemoryAllocatedBase = xmlMemUsed();
107 ret = 0;
108 } else {
109 ret = xmlMemUsed() - libxmlMemoryAllocatedBase;
110 }
111 libxmlMemoryDebug = 1;
112 libxmlMemoryDebugActivated = 1;
Daniel Veillard4e1b26c2002-02-03 20:13:06 +0000113 } else {
Daniel Veillardd2379012002-03-15 22:24:56 +0000114 if (libxmlMemoryDebugActivated == 1)
115 ret = xmlMemUsed() - libxmlMemoryAllocatedBase;
116 else
117 ret = 0;
118 libxmlMemoryDebugActivated = 0;
Daniel Veillard4e1b26c2002-02-03 20:13:06 +0000119 }
Daniel Veillardd2379012002-03-15 22:24:56 +0000120 error:
Daniel Veillard4e1b26c2002-02-03 20:13:06 +0000121 py_retval = libxml_longWrap(ret);
Daniel Veillardd2379012002-03-15 22:24:56 +0000122 return (py_retval);
Daniel Veillard4e1b26c2002-02-03 20:13:06 +0000123}
124
125PyObject *
Daniel Veillardd2379012002-03-15 22:24:56 +0000126libxml_xmlDumpMemory(ATTRIBUTE_UNUSED PyObject * self,
127 ATTRIBUTE_UNUSED PyObject * args)
128{
Daniel Veillard4e1b26c2002-02-03 20:13:06 +0000129
130 if (libxmlMemoryDebug != 0)
Daniel Veillardd2379012002-03-15 22:24:56 +0000131 xmlMemoryDump();
Daniel Veillard4e1b26c2002-02-03 20:13:06 +0000132 Py_INCREF(Py_None);
Daniel Veillardd2379012002-03-15 22:24:56 +0000133 return (Py_None);
Daniel Veillard4e1b26c2002-02-03 20:13:06 +0000134}
Daniel Veillardd2897fd2002-01-30 16:37:32 +0000135
136/************************************************************************
137 * *
Daniel Veillardc6d4a932002-09-12 15:00:57 +0000138 * Handling Python FILE I/O at the C level *
139 * The raw I/O attack diectly the File objects, while the *
140 * other routines address the ioWrapper instance instead *
141 * *
142 ************************************************************************/
143
144/**
145 * xmlPythonFileCloseUnref:
146 * @context: the I/O context
147 *
148 * Close an I/O channel
149 */
150static int
151xmlPythonFileCloseRaw (void * context) {
152 PyObject *file, *ret;
153
154#ifdef DEBUG_FILES
155 printf("xmlPythonFileCloseUnref\n");
156#endif
157 file = (PyObject *) context;
158 if (file == NULL) return(-1);
Daniel Veillard118aed72002-09-24 14:13:13 +0000159 ret = PyEval_CallMethod(file, (char *) "close", (char *) "()");
Daniel Veillardc6d4a932002-09-12 15:00:57 +0000160 if (ret != NULL) {
161 Py_DECREF(ret);
162 }
163 Py_DECREF(file);
164 return(0);
165}
166
167/**
168 * xmlPythonFileReadRaw:
169 * @context: the I/O context
170 * @buffer: where to drop data
171 * @len: number of bytes to write
172 *
173 * Read @len bytes to @buffer from the Python file in the I/O channel
174 *
175 * Returns the number of bytes read
176 */
177static int
178xmlPythonFileReadRaw (void * context, char * buffer, int len) {
179 PyObject *file;
180 PyObject *ret;
181 int lenread = -1;
182 char *data;
183
184#ifdef DEBUG_FILES
185 printf("xmlPythonFileReadRaw: %d\n", len);
186#endif
187 file = (PyObject *) context;
188 if (file == NULL) return(-1);
Daniel Veillard118aed72002-09-24 14:13:13 +0000189 ret = PyEval_CallMethod(file, (char *) "read", (char *) "(i)", len);
Daniel Veillardc6d4a932002-09-12 15:00:57 +0000190 if (ret == NULL) {
191 printf("xmlPythonFileReadRaw: result is NULL\n");
192 return(-1);
193 } else if (PyString_Check(ret)) {
194 lenread = PyString_Size(ret);
195 data = PyString_AsString(ret);
196 if (lenread > len)
197 memcpy(buffer, data, len);
198 else
199 memcpy(buffer, data, lenread);
200 Py_DECREF(ret);
201 } else {
202 printf("xmlPythonFileReadRaw: result is not a String\n");
203 Py_DECREF(ret);
204 }
205 return(lenread);
206}
207
208/**
209 * xmlPythonFileRead:
210 * @context: the I/O context
211 * @buffer: where to drop data
212 * @len: number of bytes to write
213 *
214 * Read @len bytes to @buffer from the I/O channel.
215 *
216 * Returns the number of bytes read
217 */
218static int
219xmlPythonFileRead (void * context, char * buffer, int len) {
220 PyObject *file;
221 PyObject *ret;
222 int lenread = -1;
223 char *data;
224
225#ifdef DEBUG_FILES
226 printf("xmlPythonFileRead: %d\n", len);
227#endif
228 file = (PyObject *) context;
229 if (file == NULL) return(-1);
Daniel Veillard118aed72002-09-24 14:13:13 +0000230 ret = PyEval_CallMethod(file, (char *) "io_read", (char *) "(i)", len);
Daniel Veillardc6d4a932002-09-12 15:00:57 +0000231 if (ret == NULL) {
232 printf("xmlPythonFileRead: result is NULL\n");
233 return(-1);
234 } else if (PyString_Check(ret)) {
235 lenread = PyString_Size(ret);
236 data = PyString_AsString(ret);
237 if (lenread > len)
238 memcpy(buffer, data, len);
239 else
240 memcpy(buffer, data, lenread);
241 Py_DECREF(ret);
242 } else {
243 printf("xmlPythonFileRead: result is not a String\n");
244 Py_DECREF(ret);
245 }
246 return(lenread);
247}
248
249/**
250 * xmlFileWrite:
251 * @context: the I/O context
252 * @buffer: where to drop data
253 * @len: number of bytes to write
254 *
255 * Write @len bytes from @buffer to the I/O channel.
256 *
257 * Returns the number of bytes written
258 */
259static int
260xmlPythonFileWrite (void * context, const char * buffer, int len) {
261 PyObject *file;
262 PyObject *string;
263 PyObject *ret;
264 int written = -1;
265
266#ifdef DEBUG_FILES
267 printf("xmlPythonFileWrite: %d\n", len);
268#endif
269 file = (PyObject *) context;
270 if (file == NULL) return(-1);
271 string = PyString_FromStringAndSize(buffer, len);
272 if (string == NULL) return(-1);
Daniel Veillard118aed72002-09-24 14:13:13 +0000273 ret = PyEval_CallMethod(file, (char *) "io_write", (char *) "(O)", string);
Daniel Veillardc6d4a932002-09-12 15:00:57 +0000274 Py_DECREF(string);
275 if (ret == NULL) {
276 printf("xmlPythonFileWrite: result is NULL\n");
277 return(-1);
278 } else if (PyInt_Check(ret)) {
279 written = (int) PyInt_AsLong(ret);
280 Py_DECREF(ret);
281 } else if (ret == Py_None) {
282 written = len;
283 Py_DECREF(ret);
284 } else {
285 printf("xmlPythonFileWrite: result is not an Int nor None\n");
286 Py_DECREF(ret);
287 }
288 return(written);
289}
290
291/**
292 * xmlPythonFileClose:
293 * @context: the I/O context
294 *
295 * Close an I/O channel
296 */
297static int
298xmlPythonFileClose (void * context) {
299 PyObject *file, *ret;
300
301#ifdef DEBUG_FILES
302 printf("xmlPythonFileClose\n");
303#endif
304 file = (PyObject *) context;
305 if (file == NULL) return(-1);
Daniel Veillard118aed72002-09-24 14:13:13 +0000306 ret = PyEval_CallMethod(file, (char *) "io_close", (char *) "()");
Daniel Veillardc6d4a932002-09-12 15:00:57 +0000307 if (ret != NULL) {
308 Py_DECREF(ret);
309 }
310 return(0);
311}
312
313/**
314 * xmlOutputBufferCreatePythonFile:
315 * @file: a PyFile_Type
316 * @encoder: the encoding converter or NULL
317 *
318 * Create a buffered output for the progressive saving to a PyFile_Type
319 * buffered C I/O
320 *
321 * Returns the new parser output or NULL
322 */
Daniel Veillard118aed72002-09-24 14:13:13 +0000323static xmlOutputBufferPtr
Daniel Veillardc6d4a932002-09-12 15:00:57 +0000324xmlOutputBufferCreatePythonFile(PyObject *file,
325 xmlCharEncodingHandlerPtr encoder) {
326 xmlOutputBufferPtr ret;
327
328 if (file == NULL) return(NULL);
329
330 ret = xmlAllocOutputBuffer(encoder);
331 if (ret != NULL) {
332 ret->context = file;
333 /* Py_INCREF(file); */
334 ret->writecallback = xmlPythonFileWrite;
335 ret->closecallback = xmlPythonFileClose;
336 }
337
338 return(ret);
339}
340
341PyObject *
342libxml_xmlCreateOutputBuffer(ATTRIBUTE_UNUSED PyObject *self, PyObject *args) {
343 PyObject *py_retval;
344 PyObject *file;
345 xmlChar *encoding;
346 xmlCharEncodingHandlerPtr handler = NULL;
347 xmlOutputBufferPtr buffer;
348
349
350 if (!PyArg_ParseTuple(args, (char *)"Oz:xmlOutputBufferCreate",
351 &file, &encoding))
352 return(NULL);
353 if ((encoding != NULL) && (encoding[0] != 0)) {
Daniel Veillard118aed72002-09-24 14:13:13 +0000354 handler = xmlFindCharEncodingHandler((const char *) encoding);
Daniel Veillardc6d4a932002-09-12 15:00:57 +0000355 }
356 buffer = xmlOutputBufferCreatePythonFile(file, handler);
357 if (buffer == NULL)
358 printf("libxml_xmlCreateOutputBuffer: buffer == NULL\n");
359 py_retval = libxml_xmlOutputBufferPtrWrap(buffer);
360 return(py_retval);
361}
362
363
364/**
365 * xmlParserInputBufferCreatePythonFile:
366 * @file: a PyFile_Type
367 * @encoder: the encoding converter or NULL
368 *
369 * Create a buffered output for the progressive saving to a PyFile_Type
370 * buffered C I/O
371 *
372 * Returns the new parser output or NULL
373 */
Daniel Veillard118aed72002-09-24 14:13:13 +0000374static xmlParserInputBufferPtr
Daniel Veillardc6d4a932002-09-12 15:00:57 +0000375xmlParserInputBufferCreatePythonFile(PyObject *file,
376 xmlCharEncoding encoding) {
377 xmlParserInputBufferPtr ret;
378
379 if (file == NULL) return(NULL);
380
381 ret = xmlAllocParserInputBuffer(encoding);
382 if (ret != NULL) {
383 ret->context = file;
384 /* Py_INCREF(file); */
385 ret->readcallback = xmlPythonFileRead;
386 ret->closecallback = xmlPythonFileClose;
387 }
388
389 return(ret);
390}
391
392PyObject *
393libxml_xmlCreateInputBuffer(ATTRIBUTE_UNUSED PyObject *self, PyObject *args) {
394 PyObject *py_retval;
395 PyObject *file;
396 xmlChar *encoding;
397 xmlCharEncoding enc = XML_CHAR_ENCODING_NONE;
398 xmlParserInputBufferPtr buffer;
399
400
401 if (!PyArg_ParseTuple(args, (char *)"Oz:xmlParserInputBufferCreate",
402 &file, &encoding))
403 return(NULL);
404 if ((encoding != NULL) && (encoding[0] != 0)) {
Daniel Veillard118aed72002-09-24 14:13:13 +0000405 enc = xmlParseCharEncoding((const char *) encoding);
Daniel Veillardc6d4a932002-09-12 15:00:57 +0000406 }
407 buffer = xmlParserInputBufferCreatePythonFile(file, enc);
408 if (buffer == NULL)
409 printf("libxml_xmlParserInputBufferCreate: buffer == NULL\n");
410 py_retval = libxml_xmlParserInputBufferPtrWrap(buffer);
411 return(py_retval);
412}
413
414/************************************************************************
415 * *
416 * Providing the resolver at the Python level *
417 * *
418 ************************************************************************/
419
420static xmlExternalEntityLoader defaultExternalEntityLoader = NULL;
421static PyObject *pythonExternalEntityLoaderObjext;
422
423static xmlParserInputPtr
424pythonExternalEntityLoader(const char *URL, const char *ID,
425 xmlParserCtxtPtr ctxt) {
426 xmlParserInputPtr result = NULL;
427 if (pythonExternalEntityLoaderObjext != NULL) {
428 PyObject *ret;
429 PyObject *ctxtobj;
430
431 ctxtobj = libxml_xmlParserCtxtPtrWrap(ctxt);
432#ifdef DEBUG_LOADER
433 printf("pythonExternalEntityLoader: ready to call\n");
434#endif
435
436 ret = PyObject_CallFunction(pythonExternalEntityLoaderObjext,
Daniel Veillard118aed72002-09-24 14:13:13 +0000437 (char *) "(ssO)", URL, ID, ctxtobj);
Daniel Veillardc6d4a932002-09-12 15:00:57 +0000438#ifdef DEBUG_LOADER
439 printf("pythonExternalEntityLoader: result ");
440 PyObject_Print(ret, stdout, 0);
441 printf("\n");
442#endif
443
444 if (ret != NULL) {
Daniel Veillard118aed72002-09-24 14:13:13 +0000445 if (PyObject_HasAttrString(ret, (char *) "read")) {
Daniel Veillardc6d4a932002-09-12 15:00:57 +0000446 xmlParserInputBufferPtr buf;
447
448 buf = xmlAllocParserInputBuffer(XML_CHAR_ENCODING_NONE);
449 if (buf != NULL) {
450 buf->context = ret;
451 buf->readcallback = xmlPythonFileReadRaw;
452 buf->closecallback = xmlPythonFileCloseRaw;
453 result = xmlNewIOInputStream(ctxt, buf,
454 XML_CHAR_ENCODING_NONE);
455 }
456 } else {
457 printf("pythonExternalEntityLoader: can't read\n");
458 }
459 if (result == NULL) {
460 Py_DECREF(ret);
461 }
462 }
463 }
464 if ((result == NULL) && (defaultExternalEntityLoader != NULL)) {
465 result = defaultExternalEntityLoader(URL, ID, ctxt);
466 }
467 return(result);
468}
469
470PyObject *
471libxml_xmlSetEntityLoader(ATTRIBUTE_UNUSED PyObject *self, PyObject *args) {
472 PyObject *py_retval;
473 PyObject *loader;
474
475 if (!PyArg_ParseTuple(args, (char *)"O:libxml_xmlSetEntityLoader",
476 &loader))
477 return(NULL);
478
479#ifdef DEBUG_LOADER
480 printf("libxml_xmlSetEntityLoader\n");
481#endif
482 if (defaultExternalEntityLoader == NULL)
483 defaultExternalEntityLoader = xmlGetExternalEntityLoader();
484
485 pythonExternalEntityLoaderObjext = loader;
486 xmlSetExternalEntityLoader(pythonExternalEntityLoader);
487
488 py_retval = PyInt_FromLong(0);
489 return(py_retval);
490}
491
492
493/************************************************************************
494 * *
Daniel Veillard3ce52572002-02-03 15:08:05 +0000495 * Handling SAX/xmllib/sgmlop callback interfaces *
Daniel Veillardd2897fd2002-01-30 16:37:32 +0000496 * *
497 ************************************************************************/
Daniel Veillardd2897fd2002-01-30 16:37:32 +0000498
Daniel Veillard33caa0b2002-02-04 14:07:26 +0000499static void
500pythonStartElement(void *user_data, const xmlChar * name,
501 const xmlChar ** attrs)
502{
503 int i;
504 PyObject *handler;
505 PyObject *dict;
506 PyObject *attrname;
507 PyObject *attrvalue;
Daniel Veillardd2379012002-03-15 22:24:56 +0000508 PyObject *result = NULL;
Daniel Veillard33caa0b2002-02-04 14:07:26 +0000509 int type = 0;
510
Daniel Veillard797a5652002-02-12 13:46:21 +0000511#ifdef DEBUG_SAX
512 printf("pythonStartElement(%s) called\n", name);
513#endif
Daniel Veillard33caa0b2002-02-04 14:07:26 +0000514 handler = (PyObject *) user_data;
Daniel Veillardd2379012002-03-15 22:24:56 +0000515 if (PyObject_HasAttrString(handler, (char *) "startElement"))
Daniel Veillard33caa0b2002-02-04 14:07:26 +0000516 type = 1;
Daniel Veillardd2379012002-03-15 22:24:56 +0000517 else if (PyObject_HasAttrString(handler, (char *) "start"))
Daniel Veillard33caa0b2002-02-04 14:07:26 +0000518 type = 2;
519 if (type != 0) {
520 /*
521 * the xmllib interface always generate a dictionnary,
522 * possibly empty
523 */
524 if ((attrs == NULL) && (type == 1)) {
525 Py_XINCREF(Py_None);
526 dict = Py_None;
Daniel Veillardd2379012002-03-15 22:24:56 +0000527 } else if (attrs == NULL) {
528 dict = PyDict_New();
Daniel Veillard33caa0b2002-02-04 14:07:26 +0000529 } else {
530 dict = PyDict_New();
531 for (i = 0; attrs[i] != NULL; i++) {
Daniel Veillardd2379012002-03-15 22:24:56 +0000532 attrname = PyString_FromString((char *) attrs[i]);
Daniel Veillard33caa0b2002-02-04 14:07:26 +0000533 i++;
534 if (attrs[i] != NULL) {
Daniel Veillardd2379012002-03-15 22:24:56 +0000535 attrvalue = PyString_FromString((char *) attrs[i]);
Daniel Veillard33caa0b2002-02-04 14:07:26 +0000536 } else {
537 Py_XINCREF(Py_None);
538 attrvalue = Py_None;
539 }
540 PyDict_SetItem(dict, attrname, attrvalue);
541 }
542 }
543
544 if (type == 1)
Daniel Veillardd2379012002-03-15 22:24:56 +0000545 result = PyObject_CallMethod(handler, (char *) "startElement",
546 (char *) "sO", name, dict);
Daniel Veillard33caa0b2002-02-04 14:07:26 +0000547 else if (type == 2)
Daniel Veillardd2379012002-03-15 22:24:56 +0000548 result = PyObject_CallMethod(handler, (char *) "start",
549 (char *) "sO", name, dict);
550 if (PyErr_Occurred())
551 PyErr_Print();
Daniel Veillard33caa0b2002-02-04 14:07:26 +0000552 Py_XDECREF(dict);
553 Py_XDECREF(result);
554 }
555}
556
557static void
558pythonStartDocument(void *user_data)
559{
560 PyObject *handler;
561 PyObject *result;
562
Daniel Veillard797a5652002-02-12 13:46:21 +0000563#ifdef DEBUG_SAX
564 printf("pythonStartDocument() called\n");
565#endif
Daniel Veillard33caa0b2002-02-04 14:07:26 +0000566 handler = (PyObject *) user_data;
Daniel Veillardd2379012002-03-15 22:24:56 +0000567 if (PyObject_HasAttrString(handler, (char *) "startDocument")) {
568 result =
569 PyObject_CallMethod(handler, (char *) "startDocument", NULL);
570 if (PyErr_Occurred())
571 PyErr_Print();
Daniel Veillard33caa0b2002-02-04 14:07:26 +0000572 Py_XDECREF(result);
573 }
574}
575
576static void
577pythonEndDocument(void *user_data)
578{
579 PyObject *handler;
580 PyObject *result;
581
Daniel Veillard797a5652002-02-12 13:46:21 +0000582#ifdef DEBUG_SAX
583 printf("pythonEndDocument() called\n");
584#endif
Daniel Veillard33caa0b2002-02-04 14:07:26 +0000585 handler = (PyObject *) user_data;
Daniel Veillardd2379012002-03-15 22:24:56 +0000586 if (PyObject_HasAttrString(handler, (char *) "endDocument")) {
587 result =
588 PyObject_CallMethod(handler, (char *) "endDocument", NULL);
589 if (PyErr_Occurred())
590 PyErr_Print();
Daniel Veillard33caa0b2002-02-04 14:07:26 +0000591 Py_XDECREF(result);
592 }
593 /*
594 * The reference to the handler is released there
595 */
596 Py_XDECREF(handler);
597}
598
599static void
600pythonEndElement(void *user_data, const xmlChar * name)
601{
602 PyObject *handler;
603 PyObject *result;
604
Daniel Veillard797a5652002-02-12 13:46:21 +0000605#ifdef DEBUG_SAX
606 printf("pythonEndElement(%s) called\n", name);
607#endif
Daniel Veillard33caa0b2002-02-04 14:07:26 +0000608 handler = (PyObject *) user_data;
Daniel Veillardd2379012002-03-15 22:24:56 +0000609 if (PyObject_HasAttrString(handler, (char *) "endElement")) {
610 result = PyObject_CallMethod(handler, (char *) "endElement",
611 (char *) "s", name);
612 if (PyErr_Occurred())
613 PyErr_Print();
Daniel Veillard33caa0b2002-02-04 14:07:26 +0000614 Py_XDECREF(result);
Daniel Veillardd2379012002-03-15 22:24:56 +0000615 } else if (PyObject_HasAttrString(handler, (char *) "end")) {
616 result = PyObject_CallMethod(handler, (char *) "end",
617 (char *) "s", name);
618 if (PyErr_Occurred())
619 PyErr_Print();
Daniel Veillard797a5652002-02-12 13:46:21 +0000620 Py_XDECREF(result);
Daniel Veillard33caa0b2002-02-04 14:07:26 +0000621 }
622}
623
624static void
625pythonReference(void *user_data, const xmlChar * name)
626{
627 PyObject *handler;
628 PyObject *result;
629
Daniel Veillard797a5652002-02-12 13:46:21 +0000630#ifdef DEBUG_SAX
631 printf("pythonReference(%s) called\n", name);
632#endif
Daniel Veillard33caa0b2002-02-04 14:07:26 +0000633 handler = (PyObject *) user_data;
Daniel Veillardd2379012002-03-15 22:24:56 +0000634 if (PyObject_HasAttrString(handler, (char *) "reference")) {
635 result = PyObject_CallMethod(handler, (char *) "reference",
636 (char *) "s", name);
637 if (PyErr_Occurred())
638 PyErr_Print();
Daniel Veillard33caa0b2002-02-04 14:07:26 +0000639 Py_XDECREF(result);
640 }
641}
642
643static void
644pythonCharacters(void *user_data, const xmlChar * ch, int len)
645{
646 PyObject *handler;
Daniel Veillardd2379012002-03-15 22:24:56 +0000647 PyObject *result = NULL;
Daniel Veillard33caa0b2002-02-04 14:07:26 +0000648 int type = 0;
649
Daniel Veillard797a5652002-02-12 13:46:21 +0000650#ifdef DEBUG_SAX
651 printf("pythonCharacters(%s, %d) called\n", ch, len);
652#endif
Daniel Veillard33caa0b2002-02-04 14:07:26 +0000653 handler = (PyObject *) user_data;
Daniel Veillardd2379012002-03-15 22:24:56 +0000654 if (PyObject_HasAttrString(handler, (char *) "characters"))
655 type = 1;
656 else if (PyObject_HasAttrString(handler, (char *) "data"))
657 type = 2;
Daniel Veillard33caa0b2002-02-04 14:07:26 +0000658 if (type != 0) {
Daniel Veillardd2379012002-03-15 22:24:56 +0000659 if (type == 1)
660 result = PyObject_CallMethod(handler, (char *) "characters",
661 (char *) "s#", ch, len);
662 else if (type == 2)
663 result = PyObject_CallMethod(handler, (char *) "data",
664 (char *) "s#", ch, len);
665 if (PyErr_Occurred())
666 PyErr_Print();
Daniel Veillard33caa0b2002-02-04 14:07:26 +0000667 Py_XDECREF(result);
668 }
669}
670
671static void
672pythonIgnorableWhitespace(void *user_data, const xmlChar * ch, int len)
673{
674 PyObject *handler;
Daniel Veillardd2379012002-03-15 22:24:56 +0000675 PyObject *result = NULL;
Daniel Veillard33caa0b2002-02-04 14:07:26 +0000676 int type = 0;
677
Daniel Veillard797a5652002-02-12 13:46:21 +0000678#ifdef DEBUG_SAX
679 printf("pythonIgnorableWhitespace(%s, %d) called\n", ch, len);
680#endif
Daniel Veillard33caa0b2002-02-04 14:07:26 +0000681 handler = (PyObject *) user_data;
Daniel Veillardd2379012002-03-15 22:24:56 +0000682 if (PyObject_HasAttrString(handler, (char *) "ignorableWhitespace"))
Daniel Veillard33caa0b2002-02-04 14:07:26 +0000683 type = 1;
Daniel Veillardd2379012002-03-15 22:24:56 +0000684 else if (PyObject_HasAttrString(handler, (char *) "data"))
Daniel Veillard33caa0b2002-02-04 14:07:26 +0000685 type = 2;
686 if (type != 0) {
687 if (type == 1)
688 result =
Daniel Veillardd2379012002-03-15 22:24:56 +0000689 PyObject_CallMethod(handler,
690 (char *) "ignorableWhitespace",
691 (char *) "s#", ch, len);
Daniel Veillard33caa0b2002-02-04 14:07:26 +0000692 else if (type == 2)
Daniel Veillardd2379012002-03-15 22:24:56 +0000693 result =
694 PyObject_CallMethod(handler, (char *) "data",
695 (char *) "s#", ch, len);
Daniel Veillard33caa0b2002-02-04 14:07:26 +0000696 Py_XDECREF(result);
697 }
698}
699
700static void
701pythonProcessingInstruction(void *user_data,
702 const xmlChar * target, const xmlChar * data)
703{
704 PyObject *handler;
705 PyObject *result;
706
Daniel Veillard797a5652002-02-12 13:46:21 +0000707#ifdef DEBUG_SAX
708 printf("pythonProcessingInstruction(%s, %s) called\n", target, data);
709#endif
Daniel Veillard33caa0b2002-02-04 14:07:26 +0000710 handler = (PyObject *) user_data;
Daniel Veillardd2379012002-03-15 22:24:56 +0000711 if (PyObject_HasAttrString(handler, (char *) "processingInstruction")) {
712 result = PyObject_CallMethod(handler, (char *)
713 "processingInstruction",
714 (char *) "ss", target, data);
Daniel Veillard33caa0b2002-02-04 14:07:26 +0000715 Py_XDECREF(result);
716 }
717}
718
719static void
720pythonComment(void *user_data, const xmlChar * value)
721{
722 PyObject *handler;
723 PyObject *result;
724
Daniel Veillard797a5652002-02-12 13:46:21 +0000725#ifdef DEBUG_SAX
726 printf("pythonComment(%s) called\n", value);
727#endif
Daniel Veillard33caa0b2002-02-04 14:07:26 +0000728 handler = (PyObject *) user_data;
Daniel Veillardd2379012002-03-15 22:24:56 +0000729 if (PyObject_HasAttrString(handler, (char *) "comment")) {
730 result =
731 PyObject_CallMethod(handler, (char *) "comment", (char *) "s",
732 value);
733 if (PyErr_Occurred())
734 PyErr_Print();
Daniel Veillard33caa0b2002-02-04 14:07:26 +0000735 Py_XDECREF(result);
736 }
737}
738
739static void
740pythonWarning(void *user_data, const char *msg, ...)
741{
742 PyObject *handler;
743 PyObject *result;
744 va_list args;
745 char buf[1024];
746
Daniel Veillard797a5652002-02-12 13:46:21 +0000747#ifdef DEBUG_SAX
748 printf("pythonWarning(%s) called\n", msg);
749#endif
Daniel Veillard33caa0b2002-02-04 14:07:26 +0000750 handler = (PyObject *) user_data;
Daniel Veillardd2379012002-03-15 22:24:56 +0000751 if (PyObject_HasAttrString(handler, (char *) "warning")) {
Daniel Veillard33caa0b2002-02-04 14:07:26 +0000752 va_start(args, msg);
753 vsnprintf(buf, 1023, msg, args);
Daniel Veillardd2379012002-03-15 22:24:56 +0000754 va_end(args);
755 buf[1023] = 0;
756 result =
757 PyObject_CallMethod(handler, (char *) "warning", (char *) "s",
758 buf);
759 if (PyErr_Occurred())
760 PyErr_Print();
Daniel Veillard33caa0b2002-02-04 14:07:26 +0000761 Py_XDECREF(result);
762 }
763}
764
765static void
766pythonError(void *user_data, const char *msg, ...)
767{
768 PyObject *handler;
769 PyObject *result;
770 va_list args;
771 char buf[1024];
772
Daniel Veillard797a5652002-02-12 13:46:21 +0000773#ifdef DEBUG_SAX
774 printf("pythonError(%s) called\n", msg);
775#endif
Daniel Veillard33caa0b2002-02-04 14:07:26 +0000776 handler = (PyObject *) user_data;
Daniel Veillardd2379012002-03-15 22:24:56 +0000777 if (PyObject_HasAttrString(handler, (char *) "error")) {
Daniel Veillard33caa0b2002-02-04 14:07:26 +0000778 va_start(args, msg);
779 vsnprintf(buf, 1023, msg, args);
Daniel Veillardd2379012002-03-15 22:24:56 +0000780 va_end(args);
781 buf[1023] = 0;
782 result =
783 PyObject_CallMethod(handler, (char *) "error", (char *) "s",
784 buf);
785 if (PyErr_Occurred())
786 PyErr_Print();
Daniel Veillard33caa0b2002-02-04 14:07:26 +0000787 Py_XDECREF(result);
788 }
789}
790
791static void
792pythonFatalError(void *user_data, const char *msg, ...)
793{
794 PyObject *handler;
795 PyObject *result;
796 va_list args;
797 char buf[1024];
798
Daniel Veillard797a5652002-02-12 13:46:21 +0000799#ifdef DEBUG_SAX
800 printf("pythonFatalError(%s) called\n", msg);
801#endif
Daniel Veillard33caa0b2002-02-04 14:07:26 +0000802 handler = (PyObject *) user_data;
Daniel Veillardd2379012002-03-15 22:24:56 +0000803 if (PyObject_HasAttrString(handler, (char *) "fatalError")) {
Daniel Veillard33caa0b2002-02-04 14:07:26 +0000804 va_start(args, msg);
805 vsnprintf(buf, 1023, msg, args);
Daniel Veillardd2379012002-03-15 22:24:56 +0000806 va_end(args);
807 buf[1023] = 0;
808 result =
809 PyObject_CallMethod(handler, (char *) "fatalError",
810 (char *) "s", buf);
811 if (PyErr_Occurred())
812 PyErr_Print();
Daniel Veillard33caa0b2002-02-04 14:07:26 +0000813 Py_XDECREF(result);
814 }
815}
816
817static void
818pythonCdataBlock(void *user_data, const xmlChar * ch, int len)
819{
820 PyObject *handler;
Daniel Veillardd2379012002-03-15 22:24:56 +0000821 PyObject *result = NULL;
Daniel Veillard33caa0b2002-02-04 14:07:26 +0000822 int type = 0;
823
Daniel Veillard797a5652002-02-12 13:46:21 +0000824#ifdef DEBUG_SAX
825 printf("pythonCdataBlock(%s, %d) called\n", ch, len);
826#endif
Daniel Veillard33caa0b2002-02-04 14:07:26 +0000827 handler = (PyObject *) user_data;
Daniel Veillardd2379012002-03-15 22:24:56 +0000828 if (PyObject_HasAttrString(handler, (char *) "cdataBlock"))
829 type = 1;
830 else if (PyObject_HasAttrString(handler, (char *) "cdata"))
831 type = 2;
Daniel Veillard33caa0b2002-02-04 14:07:26 +0000832 if (type != 0) {
Daniel Veillardd2379012002-03-15 22:24:56 +0000833 if (type == 1)
834 result =
835 PyObject_CallMethod(handler, (char *) "cdataBlock",
836 (char *) "s#", ch, len);
837 else if (type == 2)
838 result =
839 PyObject_CallMethod(handler, (char *) "cdata",
840 (char *) "s#", ch, len);
841 if (PyErr_Occurred())
842 PyErr_Print();
Daniel Veillard33caa0b2002-02-04 14:07:26 +0000843 Py_XDECREF(result);
844 }
845}
846
847static void
848pythonExternalSubset(void *user_data,
849 const xmlChar * name,
850 const xmlChar * externalID, const xmlChar * systemID)
851{
852 PyObject *handler;
853 PyObject *result;
854
Daniel Veillard797a5652002-02-12 13:46:21 +0000855#ifdef DEBUG_SAX
856 printf("pythonExternalSubset(%s, %s, %s) called\n",
Daniel Veillardd2379012002-03-15 22:24:56 +0000857 name, externalID, systemID);
Daniel Veillard797a5652002-02-12 13:46:21 +0000858#endif
Daniel Veillard33caa0b2002-02-04 14:07:26 +0000859 handler = (PyObject *) user_data;
Daniel Veillardd2379012002-03-15 22:24:56 +0000860 if (PyObject_HasAttrString(handler, (char *) "externalSubset")) {
Daniel Veillard33caa0b2002-02-04 14:07:26 +0000861 result =
Daniel Veillardd2379012002-03-15 22:24:56 +0000862 PyObject_CallMethod(handler, (char *) "externalSubset",
863 (char *) "sss", name, externalID,
864 systemID);
Daniel Veillard33caa0b2002-02-04 14:07:26 +0000865 Py_XDECREF(result);
866 }
867}
868
869static void
870pythonEntityDecl(void *user_data,
871 const xmlChar * name,
872 int type,
873 const xmlChar * publicId,
874 const xmlChar * systemId, xmlChar * content)
875{
876 PyObject *handler;
877 PyObject *result;
878
879 handler = (PyObject *) user_data;
Daniel Veillardd2379012002-03-15 22:24:56 +0000880 if (PyObject_HasAttrString(handler, (char *) "entityDecl")) {
881 result = PyObject_CallMethod(handler, (char *) "entityDecl",
882 (char *) "sisss", name, type,
883 publicId, systemId, content);
884 if (PyErr_Occurred())
885 PyErr_Print();
Daniel Veillard33caa0b2002-02-04 14:07:26 +0000886 Py_XDECREF(result);
887 }
888}
889
890
891
892static void
893
894pythonNotationDecl(void *user_data,
895 const xmlChar * name,
896 const xmlChar * publicId, const xmlChar * systemId)
897{
898 PyObject *handler;
899 PyObject *result;
900
901 handler = (PyObject *) user_data;
Daniel Veillardd2379012002-03-15 22:24:56 +0000902 if (PyObject_HasAttrString(handler, (char *) "notationDecl")) {
903 result = PyObject_CallMethod(handler, (char *) "notationDecl",
904 (char *) "sss", name, publicId,
905 systemId);
906 if (PyErr_Occurred())
907 PyErr_Print();
Daniel Veillard33caa0b2002-02-04 14:07:26 +0000908 Py_XDECREF(result);
909 }
910}
911
912static void
913pythonAttributeDecl(void *user_data,
914 const xmlChar * elem,
915 const xmlChar * name,
916 int type,
917 int def,
Daniel Veillardd2379012002-03-15 22:24:56 +0000918 const xmlChar * defaultValue, xmlEnumerationPtr tree)
Daniel Veillard33caa0b2002-02-04 14:07:26 +0000919{
920 PyObject *handler;
921 PyObject *nameList;
922 PyObject *newName;
923 xmlEnumerationPtr node;
924 PyObject *result;
925 int count;
926
927 handler = (PyObject *) user_data;
Daniel Veillardd2379012002-03-15 22:24:56 +0000928 if (PyObject_HasAttrString(handler, (char *) "attributeDecl")) {
Daniel Veillard33caa0b2002-02-04 14:07:26 +0000929 count = 0;
930 for (node = tree; node != NULL; node = node->next) {
931 count++;
932 }
933 nameList = PyList_New(count);
934 count = 0;
935 for (node = tree; node != NULL; node = node->next) {
Daniel Veillardd2379012002-03-15 22:24:56 +0000936 newName = PyString_FromString((char *) node->name);
Daniel Veillard33caa0b2002-02-04 14:07:26 +0000937 PyList_SetItem(nameList, count, newName);
938 count++;
939 }
Daniel Veillardd2379012002-03-15 22:24:56 +0000940 result = PyObject_CallMethod(handler, (char *) "attributeDecl",
941 (char *) "ssiisO", elem, name, type,
942 def, defaultValue, nameList);
943 if (PyErr_Occurred())
944 PyErr_Print();
Daniel Veillard33caa0b2002-02-04 14:07:26 +0000945 Py_XDECREF(nameList);
946 Py_XDECREF(result);
947 }
948}
949
950static void
951pythonElementDecl(void *user_data,
952 const xmlChar * name,
Daniel Veillardd2379012002-03-15 22:24:56 +0000953 int type, ATTRIBUTE_UNUSED xmlElementContentPtr content)
Daniel Veillard33caa0b2002-02-04 14:07:26 +0000954{
955 PyObject *handler;
956 PyObject *obj;
957 PyObject *result;
958
959 handler = (PyObject *) user_data;
Daniel Veillardd2379012002-03-15 22:24:56 +0000960 if (PyObject_HasAttrString(handler, (char *) "elementDecl")) {
961 /* TODO: wrap in an elementContent object */
962 printf
963 ("pythonElementDecl: xmlElementContentPtr wrapper missing !\n");
964 obj = Py_None;
965 /* Py_XINCREF(Py_None); isn't the reference just borrowed ??? */
966 result = PyObject_CallMethod(handler, (char *) "elementDecl",
967 (char *) "siO", name, type, obj);
968 if (PyErr_Occurred())
969 PyErr_Print();
Daniel Veillard33caa0b2002-02-04 14:07:26 +0000970 Py_XDECREF(result);
971 }
972}
973
974static void
975pythonUnparsedEntityDecl(void *user_data,
976 const xmlChar * name,
977 const xmlChar * publicId,
978 const xmlChar * systemId,
979 const xmlChar * notationName)
980{
981 PyObject *handler;
982 PyObject *result;
983
984 handler = (PyObject *) user_data;
Daniel Veillardd2379012002-03-15 22:24:56 +0000985 if (PyObject_HasAttrString(handler, (char *) "unparsedEntityDecl")) {
986 result =
987 PyObject_CallMethod(handler, (char *) "unparsedEntityDecl",
988 (char *) "ssss", name, publicId, systemId,
989 notationName);
990 if (PyErr_Occurred())
991 PyErr_Print();
Daniel Veillard33caa0b2002-02-04 14:07:26 +0000992 Py_XDECREF(result);
993 }
994}
995
996static void
997pythonInternalSubset(void *user_data, const xmlChar * name,
998 const xmlChar * ExternalID, const xmlChar * SystemID)
999{
1000 PyObject *handler;
1001 PyObject *result;
1002
Daniel Veillard797a5652002-02-12 13:46:21 +00001003#ifdef DEBUG_SAX
1004 printf("pythonInternalSubset(%s, %s, %s) called\n",
Daniel Veillardd2379012002-03-15 22:24:56 +00001005 name, ExternalID, SystemID);
Daniel Veillard797a5652002-02-12 13:46:21 +00001006#endif
Daniel Veillard33caa0b2002-02-04 14:07:26 +00001007 handler = (PyObject *) user_data;
Daniel Veillardd2379012002-03-15 22:24:56 +00001008 if (PyObject_HasAttrString(handler, (char *) "internalSubset")) {
1009 result = PyObject_CallMethod(handler, (char *) "internalSubset",
1010 (char *) "sss", name, ExternalID,
1011 SystemID);
1012 if (PyErr_Occurred())
1013 PyErr_Print();
Daniel Veillard33caa0b2002-02-04 14:07:26 +00001014 Py_XDECREF(result);
1015 }
1016}
1017
1018static xmlSAXHandler pythonSaxHandler = {
1019 pythonInternalSubset,
Daniel Veillardd2379012002-03-15 22:24:56 +00001020 NULL, /* TODO pythonIsStandalone, */
1021 NULL, /* TODO pythonHasInternalSubset, */
1022 NULL, /* TODO pythonHasExternalSubset, */
1023 NULL, /* TODO pythonResolveEntity, */
1024 NULL, /* TODO pythonGetEntity, */
Daniel Veillard33caa0b2002-02-04 14:07:26 +00001025 pythonEntityDecl,
1026 pythonNotationDecl,
1027 pythonAttributeDecl,
1028 pythonElementDecl,
1029 pythonUnparsedEntityDecl,
Daniel Veillardd2379012002-03-15 22:24:56 +00001030 NULL, /* OBSOLETED pythonSetDocumentLocator, */
Daniel Veillard33caa0b2002-02-04 14:07:26 +00001031 pythonStartDocument,
1032 pythonEndDocument,
1033 pythonStartElement,
1034 pythonEndElement,
1035 pythonReference,
1036 pythonCharacters,
1037 pythonIgnorableWhitespace,
1038 pythonProcessingInstruction,
1039 pythonComment,
1040 pythonWarning,
1041 pythonError,
1042 pythonFatalError,
Daniel Veillardd2379012002-03-15 22:24:56 +00001043 NULL, /* TODO pythonGetParameterEntity, */
Daniel Veillard33caa0b2002-02-04 14:07:26 +00001044 pythonCdataBlock,
1045 pythonExternalSubset,
1046 1
1047};
Daniel Veillard3ce52572002-02-03 15:08:05 +00001048
1049/************************************************************************
1050 * *
1051 * Handling of specific parser context *
1052 * *
1053 ************************************************************************/
Daniel Veillardd2897fd2002-01-30 16:37:32 +00001054
1055PyObject *
Daniel Veillardd2379012002-03-15 22:24:56 +00001056libxml_xmlCreatePushParser(ATTRIBUTE_UNUSED PyObject * self,
1057 PyObject * args)
1058{
1059 const char *chunk;
Daniel Veillard3ce52572002-02-03 15:08:05 +00001060 int size;
Daniel Veillardd2379012002-03-15 22:24:56 +00001061 const char *URI;
Daniel Veillard33caa0b2002-02-04 14:07:26 +00001062 PyObject *pyobj_SAX = NULL;
Daniel Veillard3ce52572002-02-03 15:08:05 +00001063 xmlSAXHandlerPtr SAX = NULL;
Daniel Veillard3ce52572002-02-03 15:08:05 +00001064 xmlParserCtxtPtr ret;
1065 PyObject *pyret;
Daniel Veillard96fe0952002-01-30 20:52:23 +00001066
Daniel Veillardd2379012002-03-15 22:24:56 +00001067 if (!PyArg_ParseTuple
1068 (args, (char *) "Oziz:xmlCreatePushParser", &pyobj_SAX, &chunk,
1069 &size, &URI))
1070 return (NULL);
Daniel Veillard3ce52572002-02-03 15:08:05 +00001071
Daniel Veillard8d24cc12002-03-05 15:41:29 +00001072#ifdef DEBUG
Daniel Veillard3ce52572002-02-03 15:08:05 +00001073 printf("libxml_xmlCreatePushParser(%p, %s, %d, %s) called\n",
Daniel Veillardd2379012002-03-15 22:24:56 +00001074 pyobj_SAX, chunk, size, URI);
Daniel Veillard96fe0952002-01-30 20:52:23 +00001075#endif
Daniel Veillard3ce52572002-02-03 15:08:05 +00001076 if (pyobj_SAX != Py_None) {
Daniel Veillardd2379012002-03-15 22:24:56 +00001077 SAX = &pythonSaxHandler;
1078 Py_INCREF(pyobj_SAX);
1079 /* The reference is released in pythonEndDocument() */
Daniel Veillardd2897fd2002-01-30 16:37:32 +00001080 }
Daniel Veillard33caa0b2002-02-04 14:07:26 +00001081 ret = xmlCreatePushParserCtxt(SAX, pyobj_SAX, chunk, size, URI);
Daniel Veillard3ce52572002-02-03 15:08:05 +00001082 pyret = libxml_xmlParserCtxtPtrWrap(ret);
Daniel Veillardd2379012002-03-15 22:24:56 +00001083 return (pyret);
Daniel Veillarda7340c82002-02-01 17:56:45 +00001084}
Daniel Veillard5d819032002-02-02 21:49:17 +00001085
Daniel Veillard4e1b26c2002-02-03 20:13:06 +00001086PyObject *
Daniel Veillardd2379012002-03-15 22:24:56 +00001087libxml_htmlCreatePushParser(ATTRIBUTE_UNUSED PyObject * self,
1088 PyObject * args)
1089{
1090 const char *chunk;
Daniel Veillard4e1b26c2002-02-03 20:13:06 +00001091 int size;
Daniel Veillardd2379012002-03-15 22:24:56 +00001092 const char *URI;
Daniel Veillard33caa0b2002-02-04 14:07:26 +00001093 PyObject *pyobj_SAX = NULL;
Daniel Veillard4e1b26c2002-02-03 20:13:06 +00001094 xmlSAXHandlerPtr SAX = NULL;
Daniel Veillard4e1b26c2002-02-03 20:13:06 +00001095 xmlParserCtxtPtr ret;
1096 PyObject *pyret;
1097
Daniel Veillardd2379012002-03-15 22:24:56 +00001098 if (!PyArg_ParseTuple
1099 (args, (char *) "Oziz:htmlCreatePushParser", &pyobj_SAX, &chunk,
1100 &size, &URI))
1101 return (NULL);
Daniel Veillard4e1b26c2002-02-03 20:13:06 +00001102
Daniel Veillard8d24cc12002-03-05 15:41:29 +00001103#ifdef DEBUG
Daniel Veillard4e1b26c2002-02-03 20:13:06 +00001104 printf("libxml_htmlCreatePushParser(%p, %s, %d, %s) called\n",
Daniel Veillardd2379012002-03-15 22:24:56 +00001105 pyobj_SAX, chunk, size, URI);
Daniel Veillard4e1b26c2002-02-03 20:13:06 +00001106#endif
1107 if (pyobj_SAX != Py_None) {
Daniel Veillardd2379012002-03-15 22:24:56 +00001108 SAX = &pythonSaxHandler;
1109 Py_INCREF(pyobj_SAX);
1110 /* The reference is released in pythonEndDocument() */
Daniel Veillard4e1b26c2002-02-03 20:13:06 +00001111 }
Daniel Veillard33caa0b2002-02-04 14:07:26 +00001112 ret = htmlCreatePushParserCtxt(SAX, pyobj_SAX, chunk, size, URI,
Daniel Veillardd2379012002-03-15 22:24:56 +00001113 XML_CHAR_ENCODING_NONE);
Daniel Veillard4e1b26c2002-02-03 20:13:06 +00001114 pyret = libxml_xmlParserCtxtPtrWrap(ret);
Daniel Veillardd2379012002-03-15 22:24:56 +00001115 return (pyret);
Daniel Veillard4e1b26c2002-02-03 20:13:06 +00001116}
1117
Daniel Veillard8d24cc12002-03-05 15:41:29 +00001118PyObject *
Daniel Veillardd2379012002-03-15 22:24:56 +00001119libxml_xmlSAXParseFile(ATTRIBUTE_UNUSED PyObject * self, PyObject * args)
1120{
Daniel Veillard8d24cc12002-03-05 15:41:29 +00001121 int recover;
Daniel Veillardd2379012002-03-15 22:24:56 +00001122 const char *URI;
Daniel Veillard8d24cc12002-03-05 15:41:29 +00001123 PyObject *pyobj_SAX = NULL;
1124 xmlSAXHandlerPtr SAX = NULL;
1125
Daniel Veillardd2379012002-03-15 22:24:56 +00001126 if (!PyArg_ParseTuple(args, (char *) "Osi:xmlSAXParseFile", &pyobj_SAX,
1127 &URI, &recover))
1128 return (NULL);
Daniel Veillard8d24cc12002-03-05 15:41:29 +00001129
1130#ifdef DEBUG
1131 printf("libxml_xmlSAXParseFile(%p, %s, %d) called\n",
Daniel Veillardd2379012002-03-15 22:24:56 +00001132 pyobj_SAX, URI, recover);
Daniel Veillard8d24cc12002-03-05 15:41:29 +00001133#endif
1134 if (pyobj_SAX == Py_None) {
Daniel Veillardd2379012002-03-15 22:24:56 +00001135 Py_INCREF(Py_None);
1136 return (Py_None);
Daniel Veillard8d24cc12002-03-05 15:41:29 +00001137 }
1138 SAX = &pythonSaxHandler;
1139 Py_INCREF(pyobj_SAX);
1140 /* The reference is released in pythonEndDocument() */
1141 xmlSAXParseFileWithData(SAX, URI, recover, pyobj_SAX);
1142 Py_INCREF(Py_None);
Daniel Veillardd2379012002-03-15 22:24:56 +00001143 return (Py_None);
Daniel Veillard8d24cc12002-03-05 15:41:29 +00001144}
1145
1146PyObject *
Daniel Veillardd2379012002-03-15 22:24:56 +00001147libxml_htmlSAXParseFile(ATTRIBUTE_UNUSED PyObject * self, PyObject * args)
1148{
1149 const char *URI;
1150 const char *encoding;
Daniel Veillard8d24cc12002-03-05 15:41:29 +00001151 PyObject *pyobj_SAX = NULL;
1152 xmlSAXHandlerPtr SAX = NULL;
1153
Daniel Veillardd2379012002-03-15 22:24:56 +00001154 if (!PyArg_ParseTuple
1155 (args, (char *) "Osz:htmlSAXParseFile", &pyobj_SAX, &URI,
1156 &encoding))
1157 return (NULL);
Daniel Veillard8d24cc12002-03-05 15:41:29 +00001158
1159#ifdef DEBUG
1160 printf("libxml_htmlSAXParseFile(%p, %s, %s) called\n",
Daniel Veillardd2379012002-03-15 22:24:56 +00001161 pyobj_SAX, URI, encoding);
Daniel Veillard8d24cc12002-03-05 15:41:29 +00001162#endif
1163 if (pyobj_SAX == Py_None) {
Daniel Veillardd2379012002-03-15 22:24:56 +00001164 Py_INCREF(Py_None);
1165 return (Py_None);
Daniel Veillard8d24cc12002-03-05 15:41:29 +00001166 }
1167 SAX = &pythonSaxHandler;
1168 Py_INCREF(pyobj_SAX);
1169 /* The reference is released in pythonEndDocument() */
1170 htmlSAXParseFile(URI, encoding, SAX, pyobj_SAX);
1171 Py_INCREF(Py_None);
Daniel Veillardd2379012002-03-15 22:24:56 +00001172 return (Py_None);
Daniel Veillard8d24cc12002-03-05 15:41:29 +00001173}
1174
Daniel Veillard5d819032002-02-02 21:49:17 +00001175/************************************************************************
1176 * *
1177 * Error message callback *
1178 * *
1179 ************************************************************************/
1180
1181static PyObject *libxml_xmlPythonErrorFuncHandler = NULL;
1182static PyObject *libxml_xmlPythonErrorFuncCtxt = NULL;
1183
1184static void
Daniel Veillardd2379012002-03-15 22:24:56 +00001185libxml_xmlErrorFuncHandler(ATTRIBUTE_UNUSED void *ctx, const char *msg,
1186 ...)
1187{
1188 int size;
1189 int chars;
1190 char *larger;
1191 va_list ap;
1192 char *str;
Daniel Veillard5d819032002-02-02 21:49:17 +00001193 PyObject *list;
1194 PyObject *message;
1195 PyObject *result;
1196
1197#ifdef DEBUG_ERROR
1198 printf("libxml_xmlErrorFuncHandler(%p, %s, ...) called\n", ctx, msg);
1199#endif
1200
1201
1202 if (libxml_xmlPythonErrorFuncHandler == NULL) {
Daniel Veillardd2379012002-03-15 22:24:56 +00001203 va_start(ap, msg);
1204 vfprintf(stdout, msg, ap);
1205 va_end(ap);
Daniel Veillard5d819032002-02-02 21:49:17 +00001206 } else {
Daniel Veillardd2379012002-03-15 22:24:56 +00001207 str = (char *) xmlMalloc(150);
1208 if (str == NULL)
1209 return;
Daniel Veillard5d819032002-02-02 21:49:17 +00001210
Daniel Veillardd2379012002-03-15 22:24:56 +00001211 size = 150;
Daniel Veillard5d819032002-02-02 21:49:17 +00001212
Daniel Veillardd2379012002-03-15 22:24:56 +00001213 while (1) {
1214 va_start(ap, msg);
1215 chars = vsnprintf(str, size, msg, ap);
1216 va_end(ap);
1217 if ((chars > -1) && (chars < size))
1218 break;
1219 if (chars > -1)
1220 size += chars + 1;
1221 else
1222 size += 100;
1223 if ((larger = (char *) xmlRealloc(str, size)) == NULL) {
1224 xmlFree(str);
1225 return;
1226 }
1227 str = larger;
1228 }
Daniel Veillard5d819032002-02-02 21:49:17 +00001229
Daniel Veillardd2379012002-03-15 22:24:56 +00001230 list = PyTuple_New(2);
1231 PyTuple_SetItem(list, 0, libxml_xmlPythonErrorFuncCtxt);
1232 Py_XINCREF(libxml_xmlPythonErrorFuncCtxt);
1233 message = libxml_charPtrWrap(str);
1234 PyTuple_SetItem(list, 1, message);
1235 result = PyEval_CallObject(libxml_xmlPythonErrorFuncHandler, list);
1236 Py_XDECREF(list);
1237 Py_XDECREF(result);
Daniel Veillard5d819032002-02-02 21:49:17 +00001238 }
1239}
1240
1241static void
Daniel Veillardd2379012002-03-15 22:24:56 +00001242libxml_xmlErrorInitialize(void)
1243{
Daniel Veillard5d819032002-02-02 21:49:17 +00001244#ifdef DEBUG_ERROR
1245 printf("libxml_xmlErrorInitialize() called\n");
1246#endif
1247 xmlSetGenericErrorFunc(NULL, libxml_xmlErrorFuncHandler);
1248}
1249
1250PyObject *
Daniel Veillardd2379012002-03-15 22:24:56 +00001251libxml_xmlRegisterErrorHandler(ATTRIBUTE_UNUSED PyObject * self,
1252 PyObject * args)
1253{
Daniel Veillard5d819032002-02-02 21:49:17 +00001254 PyObject *py_retval;
1255 PyObject *pyobj_f;
1256 PyObject *pyobj_ctx;
1257
Daniel Veillardd2379012002-03-15 22:24:56 +00001258 if (!PyArg_ParseTuple
1259 (args, (char *) "OO:xmlRegisterErrorHandler", &pyobj_f,
1260 &pyobj_ctx))
1261 return (NULL);
Daniel Veillard5d819032002-02-02 21:49:17 +00001262
1263#ifdef DEBUG_ERROR
Daniel Veillardd2379012002-03-15 22:24:56 +00001264 printf("libxml_registerXPathFunction(%p, %p) called\n", pyobj_ctx,
1265 pyobj_f);
Daniel Veillard5d819032002-02-02 21:49:17 +00001266#endif
1267
1268 if (libxml_xmlPythonErrorFuncHandler != NULL) {
Daniel Veillardd2379012002-03-15 22:24:56 +00001269 Py_XDECREF(libxml_xmlPythonErrorFuncHandler);
Daniel Veillard5d819032002-02-02 21:49:17 +00001270 }
1271 if (libxml_xmlPythonErrorFuncCtxt != NULL) {
Daniel Veillardd2379012002-03-15 22:24:56 +00001272 Py_XDECREF(libxml_xmlPythonErrorFuncCtxt);
Daniel Veillard5d819032002-02-02 21:49:17 +00001273 }
1274
1275 Py_XINCREF(pyobj_ctx);
1276 Py_XINCREF(pyobj_f);
1277
1278 /* TODO: check f is a function ! */
1279 libxml_xmlPythonErrorFuncHandler = pyobj_f;
1280 libxml_xmlPythonErrorFuncCtxt = pyobj_ctx;
1281
1282 py_retval = libxml_intWrap(1);
Daniel Veillardd2379012002-03-15 22:24:56 +00001283 return (py_retval);
Daniel Veillard5d819032002-02-02 21:49:17 +00001284}
Daniel Veillardd2379012002-03-15 22:24:56 +00001285
Daniel Veillarda7340c82002-02-01 17:56:45 +00001286/************************************************************************
1287 * *
1288 * XPath extensions *
1289 * *
1290 ************************************************************************/
1291
1292static int libxml_xpathCallbacksInitialized = 0;
1293
1294typedef struct libxml_xpathCallback {
1295 xmlXPathContextPtr ctx;
1296 xmlChar *name;
1297 xmlChar *ns_uri;
1298 PyObject *function;
1299} libxml_xpathCallback, *libxml_xpathCallbackPtr;
1300static libxml_xpathCallback libxml_xpathCallbacks[10];
1301static int libxml_xpathCallbacksNb = 0;
1302static int libxml_xpathCallbacksMax = 10;
1303
Daniel Veillarda7340c82002-02-01 17:56:45 +00001304static void
Daniel Veillardd2379012002-03-15 22:24:56 +00001305libxml_xmlXPathFuncCallback(xmlXPathParserContextPtr ctxt, int nargs)
1306{
Daniel Veillarda7340c82002-02-01 17:56:45 +00001307 PyObject *list, *cur, *result;
1308 xmlXPathObjectPtr obj;
Daniel Veillard70cab352002-02-06 16:06:58 +00001309 xmlXPathContextPtr rctxt;
1310 PyObject *current_function = NULL;
1311 const xmlChar *name;
1312 const xmlChar *ns_uri;
Daniel Veillarda7340c82002-02-01 17:56:45 +00001313 int i;
1314
Daniel Veillard70cab352002-02-06 16:06:58 +00001315 if (ctxt == NULL)
Daniel Veillardd2379012002-03-15 22:24:56 +00001316 return;
Daniel Veillard70cab352002-02-06 16:06:58 +00001317 rctxt = ctxt->context;
1318 if (rctxt == NULL)
Daniel Veillardd2379012002-03-15 22:24:56 +00001319 return;
Daniel Veillard70cab352002-02-06 16:06:58 +00001320 name = rctxt->function;
1321 ns_uri = rctxt->functionURI;
Daniel Veillarda7340c82002-02-01 17:56:45 +00001322#ifdef DEBUG_XPATH
Daniel Veillardd2379012002-03-15 22:24:56 +00001323 printf("libxml_xmlXPathFuncCallback called name %s URI %s\n", name,
1324 ns_uri);
Daniel Veillarda7340c82002-02-01 17:56:45 +00001325#endif
1326
Daniel Veillard70cab352002-02-06 16:06:58 +00001327 /*
1328 * Find the function, it should be there it was there at lookup
1329 */
Daniel Veillardd2379012002-03-15 22:24:56 +00001330 for (i = 0; i < libxml_xpathCallbacksNb; i++) {
1331 if ( /* TODO (ctxt == libxml_xpathCallbacks[i].ctx) && */
1332 (xmlStrEqual(name, libxml_xpathCallbacks[i].name)) &&
1333 (xmlStrEqual(ns_uri, libxml_xpathCallbacks[i].ns_uri))) {
1334 current_function = libxml_xpathCallbacks[i].function;
1335 }
Daniel Veillard70cab352002-02-06 16:06:58 +00001336 }
1337 if (current_function == NULL) {
Daniel Veillardd2379012002-03-15 22:24:56 +00001338 printf
1339 ("libxml_xmlXPathFuncCallback: internal error %s not found !\n",
1340 name);
1341 return;
Daniel Veillard70cab352002-02-06 16:06:58 +00001342 }
1343
Daniel Veillardc575b992002-02-08 13:28:40 +00001344 list = PyTuple_New(nargs + 1);
1345 PyTuple_SetItem(list, 0, libxml_xmlXPathParserContextPtrWrap(ctxt));
Daniel Veillardd2379012002-03-15 22:24:56 +00001346 for (i = 0; i < nargs; i++) {
1347 obj = valuePop(ctxt);
1348 cur = libxml_xmlXPathObjectPtrWrap(obj);
1349 PyTuple_SetItem(list, i + 1, cur);
Daniel Veillarda7340c82002-02-01 17:56:45 +00001350 }
1351 result = PyEval_CallObject(current_function, list);
1352 Py_DECREF(list);
1353
1354 obj = libxml_xmlXPathObjectPtrConvert(result);
1355 valuePush(ctxt, obj);
1356}
1357
1358static xmlXPathFunction
Daniel Veillardd2379012002-03-15 22:24:56 +00001359libxml_xmlXPathFuncLookupFunc(void *ctxt, const xmlChar * name,
1360 const xmlChar * ns_uri)
1361{
Daniel Veillarda7340c82002-02-01 17:56:45 +00001362 int i;
Daniel Veillardd2379012002-03-15 22:24:56 +00001363
Daniel Veillarda7340c82002-02-01 17:56:45 +00001364#ifdef DEBUG_XPATH
1365 printf("libxml_xmlXPathFuncLookupFunc(%p, %s, %s) called\n",
Daniel Veillardd2379012002-03-15 22:24:56 +00001366 ctxt, name, ns_uri);
Daniel Veillarda7340c82002-02-01 17:56:45 +00001367#endif
Daniel Veillard70cab352002-02-06 16:06:58 +00001368 /*
1369 * This is called once only. The address is then stored in the
1370 * XPath expression evaluation, the proper object to call can
1371 * then still be found using the execution context function
1372 * and functionURI fields.
1373 */
Daniel Veillardd2379012002-03-15 22:24:56 +00001374 for (i = 0; i < libxml_xpathCallbacksNb; i++) {
1375 if ((ctxt == libxml_xpathCallbacks[i].ctx) &&
1376 (xmlStrEqual(name, libxml_xpathCallbacks[i].name)) &&
1377 (xmlStrEqual(ns_uri, libxml_xpathCallbacks[i].ns_uri))) {
1378 return (libxml_xmlXPathFuncCallback);
1379 }
Daniel Veillarda7340c82002-02-01 17:56:45 +00001380 }
Daniel Veillardd2379012002-03-15 22:24:56 +00001381 return (NULL);
Daniel Veillarda7340c82002-02-01 17:56:45 +00001382}
1383
1384static void
Daniel Veillardd2379012002-03-15 22:24:56 +00001385libxml_xpathCallbacksInitialize(void)
1386{
Daniel Veillarda7340c82002-02-01 17:56:45 +00001387 int i;
1388
1389 if (libxml_xpathCallbacksInitialized != 0)
Daniel Veillardd2379012002-03-15 22:24:56 +00001390 return;
Daniel Veillarda7340c82002-02-01 17:56:45 +00001391
1392#ifdef DEBUG_XPATH
1393 printf("libxml_xpathCallbacksInitialized called\n");
1394#endif
1395
Daniel Veillardd2379012002-03-15 22:24:56 +00001396 for (i = 0; i < 10; i++) {
1397 libxml_xpathCallbacks[i].ctx = NULL;
1398 libxml_xpathCallbacks[i].name = NULL;
1399 libxml_xpathCallbacks[i].ns_uri = NULL;
1400 libxml_xpathCallbacks[i].function = NULL;
Daniel Veillarda7340c82002-02-01 17:56:45 +00001401 }
Daniel Veillarda7340c82002-02-01 17:56:45 +00001402 libxml_xpathCallbacksInitialized = 1;
1403}
1404
1405PyObject *
Daniel Veillardd2379012002-03-15 22:24:56 +00001406libxml_xmlRegisterXPathFunction(ATTRIBUTE_UNUSED PyObject * self,
1407 PyObject * args)
1408{
Daniel Veillarda7340c82002-02-01 17:56:45 +00001409 PyObject *py_retval;
1410 int c_retval = 0;
1411 xmlChar *name;
1412 xmlChar *ns_uri;
1413 xmlXPathContextPtr ctx;
1414 PyObject *pyobj_ctx;
1415 PyObject *pyobj_f;
1416 int i;
1417
Daniel Veillardd2379012002-03-15 22:24:56 +00001418 if (!PyArg_ParseTuple
1419 (args, (char *) "OszO:registerXPathFunction", &pyobj_ctx, &name,
1420 &ns_uri, &pyobj_f))
1421 return (NULL);
Daniel Veillarda7340c82002-02-01 17:56:45 +00001422
1423 ctx = (xmlXPathContextPtr) PyxmlXPathContext_Get(pyobj_ctx);
1424 if (libxml_xpathCallbacksInitialized == 0)
Daniel Veillardd2379012002-03-15 22:24:56 +00001425 libxml_xpathCallbacksInitialize();
Daniel Veillarda7340c82002-02-01 17:56:45 +00001426 xmlXPathRegisterFuncLookup(ctx, libxml_xmlXPathFuncLookupFunc, ctx);
1427
1428 if ((pyobj_ctx == NULL) || (name == NULL) || (pyobj_f == NULL)) {
Daniel Veillardd2379012002-03-15 22:24:56 +00001429 py_retval = libxml_intWrap(-1);
1430 return (py_retval);
Daniel Veillarda7340c82002-02-01 17:56:45 +00001431 }
Daniel Veillarda7340c82002-02-01 17:56:45 +00001432#ifdef DEBUG_XPATH
1433 printf("libxml_registerXPathFunction(%p, %s, %s) called\n",
Daniel Veillardd2379012002-03-15 22:24:56 +00001434 ctx, name, ns_uri);
Daniel Veillarda7340c82002-02-01 17:56:45 +00001435#endif
Daniel Veillardd2379012002-03-15 22:24:56 +00001436 for (i = 0; i < libxml_xpathCallbacksNb; i++) {
1437 if ((ctx == libxml_xpathCallbacks[i].ctx) &&
1438 (xmlStrEqual(name, libxml_xpathCallbacks[i].name)) &&
1439 (xmlStrEqual(ns_uri, libxml_xpathCallbacks[i].ns_uri))) {
1440 Py_XINCREF(pyobj_f);
1441 Py_XDECREF(libxml_xpathCallbacks[i].function);
1442 libxml_xpathCallbacks[i].function = pyobj_f;
1443 c_retval = 1;
1444 goto done;
1445 }
Daniel Veillarda7340c82002-02-01 17:56:45 +00001446 }
1447 if (libxml_xpathCallbacksNb >= libxml_xpathCallbacksMax) {
Daniel Veillardd2379012002-03-15 22:24:56 +00001448 printf("libxml_registerXPathFunction() table full\n");
Daniel Veillarda7340c82002-02-01 17:56:45 +00001449 } else {
Daniel Veillardd2379012002-03-15 22:24:56 +00001450 i = libxml_xpathCallbacksNb++;
1451 Py_XINCREF(pyobj_f);
Daniel Veillarda7340c82002-02-01 17:56:45 +00001452 libxml_xpathCallbacks[i].ctx = ctx;
1453 libxml_xpathCallbacks[i].name = xmlStrdup(name);
1454 libxml_xpathCallbacks[i].ns_uri = xmlStrdup(ns_uri);
Daniel Veillardd2379012002-03-15 22:24:56 +00001455 libxml_xpathCallbacks[i].function = pyobj_f;
1456 c_retval = 1;
Daniel Veillarda7340c82002-02-01 17:56:45 +00001457 }
Daniel Veillardd2379012002-03-15 22:24:56 +00001458 done:
Daniel Veillarda7340c82002-02-01 17:56:45 +00001459 py_retval = libxml_intWrap((int) c_retval);
Daniel Veillardd2379012002-03-15 22:24:56 +00001460 return (py_retval);
Daniel Veillarda7340c82002-02-01 17:56:45 +00001461}
1462
Daniel Veillard1971ee22002-01-31 20:29:19 +00001463/************************************************************************
1464 * *
Daniel Veillardd2897fd2002-01-30 16:37:32 +00001465 * Global properties access *
1466 * *
1467 ************************************************************************/
1468static PyObject *
Daniel Veillardd2379012002-03-15 22:24:56 +00001469libxml_name(ATTRIBUTE_UNUSED PyObject * self, PyObject * args)
Daniel Veillardd2897fd2002-01-30 16:37:32 +00001470{
1471 PyObject *resultobj, *obj;
1472 xmlNodePtr cur;
1473 const xmlChar *res;
1474
Daniel Veillardd2379012002-03-15 22:24:56 +00001475 if (!PyArg_ParseTuple(args, (char *) "O:name", &obj))
Daniel Veillardd2897fd2002-01-30 16:37:32 +00001476 return NULL;
1477 cur = PyxmlNode_Get(obj);
1478
1479#ifdef DEBUG
1480 printf("libxml_name: cur = %p type %d\n", cur, cur->type);
1481#endif
1482
Daniel Veillardd2379012002-03-15 22:24:56 +00001483 switch (cur->type) {
1484 case XML_DOCUMENT_NODE:
Daniel Veillardd2897fd2002-01-30 16:37:32 +00001485#ifdef LIBXML_DOCB_ENABLED
Daniel Veillardd2379012002-03-15 22:24:56 +00001486 case XML_DOCB_DOCUMENT_NODE:
Daniel Veillardd2897fd2002-01-30 16:37:32 +00001487#endif
Daniel Veillardd2379012002-03-15 22:24:56 +00001488 case XML_HTML_DOCUMENT_NODE:{
1489 xmlDocPtr doc = (xmlDocPtr) cur;
1490
1491 res = doc->URL;
1492 break;
1493 }
1494 case XML_ATTRIBUTE_NODE:{
1495 xmlAttrPtr attr = (xmlAttrPtr) cur;
1496
1497 res = attr->name;
1498 break;
1499 }
1500 case XML_NAMESPACE_DECL:{
1501 xmlNsPtr ns = (xmlNsPtr) cur;
1502
1503 res = ns->prefix;
1504 break;
1505 }
1506 default:
1507 res = cur->name;
1508 break;
Daniel Veillardd2897fd2002-01-30 16:37:32 +00001509 }
Daniel Veillard1971ee22002-01-31 20:29:19 +00001510 resultobj = libxml_constxmlCharPtrWrap(res);
Daniel Veillardd2897fd2002-01-30 16:37:32 +00001511
1512 return resultobj;
1513}
1514
1515static PyObject *
Daniel Veillardd2379012002-03-15 22:24:56 +00001516libxml_doc(ATTRIBUTE_UNUSED PyObject * self, PyObject * args)
Daniel Veillardd2897fd2002-01-30 16:37:32 +00001517{
1518 PyObject *resultobj, *obj;
1519 xmlNodePtr cur;
1520 xmlDocPtr res;
1521
Daniel Veillardd2379012002-03-15 22:24:56 +00001522 if (!PyArg_ParseTuple(args, (char *) "O:doc", &obj))
Daniel Veillardd2897fd2002-01-30 16:37:32 +00001523 return NULL;
1524 cur = PyxmlNode_Get(obj);
1525
1526#ifdef DEBUG
1527 printf("libxml_doc: cur = %p\n", cur);
1528#endif
1529
Daniel Veillardd2379012002-03-15 22:24:56 +00001530 switch (cur->type) {
1531 case XML_DOCUMENT_NODE:
Daniel Veillardd2897fd2002-01-30 16:37:32 +00001532#ifdef LIBXML_DOCB_ENABLED
Daniel Veillardd2379012002-03-15 22:24:56 +00001533 case XML_DOCB_DOCUMENT_NODE:
Daniel Veillardd2897fd2002-01-30 16:37:32 +00001534#endif
Daniel Veillardd2379012002-03-15 22:24:56 +00001535 case XML_HTML_DOCUMENT_NODE:
1536 res = NULL;
1537 break;
1538 case XML_ATTRIBUTE_NODE:{
1539 xmlAttrPtr attr = (xmlAttrPtr) cur;
1540
1541 res = attr->doc;
1542 break;
1543 }
1544 case XML_NAMESPACE_DECL:
1545 res = NULL;
1546 break;
1547 default:
1548 res = cur->doc;
1549 break;
Daniel Veillardd2897fd2002-01-30 16:37:32 +00001550 }
1551 resultobj = libxml_xmlDocPtrWrap(res);
1552 return resultobj;
1553}
1554
1555static PyObject *
Daniel Veillardd2379012002-03-15 22:24:56 +00001556libxml_properties(ATTRIBUTE_UNUSED PyObject * self, PyObject * args)
Daniel Veillardd2897fd2002-01-30 16:37:32 +00001557{
1558 PyObject *resultobj, *obj;
1559 xmlNodePtr cur = NULL;
1560 xmlAttrPtr res;
1561
Daniel Veillardd2379012002-03-15 22:24:56 +00001562 if (!PyArg_ParseTuple(args, (char *) "O:properties", &obj))
Daniel Veillardd2897fd2002-01-30 16:37:32 +00001563 return NULL;
1564 cur = PyxmlNode_Get(obj);
1565 if (cur->type == XML_ELEMENT_NODE)
Daniel Veillardd2379012002-03-15 22:24:56 +00001566 res = cur->properties;
Daniel Veillardd2897fd2002-01-30 16:37:32 +00001567 else
Daniel Veillardd2379012002-03-15 22:24:56 +00001568 res = NULL;
Daniel Veillardd2897fd2002-01-30 16:37:32 +00001569 resultobj = libxml_xmlAttrPtrWrap(res);
1570 return resultobj;
1571}
1572
1573static PyObject *
Daniel Veillardd2379012002-03-15 22:24:56 +00001574libxml_next(ATTRIBUTE_UNUSED PyObject * self, PyObject * args)
Daniel Veillardd2897fd2002-01-30 16:37:32 +00001575{
1576 PyObject *resultobj, *obj;
1577 xmlNodePtr cur;
1578 xmlNodePtr res;
1579
Daniel Veillardd2379012002-03-15 22:24:56 +00001580 if (!PyArg_ParseTuple(args, (char *) "O:next", &obj))
Daniel Veillardd2897fd2002-01-30 16:37:32 +00001581 return NULL;
1582 cur = PyxmlNode_Get(obj);
1583
1584#ifdef DEBUG
1585 printf("libxml_next: cur = %p\n", cur);
1586#endif
1587
Daniel Veillardd2379012002-03-15 22:24:56 +00001588 switch (cur->type) {
1589 case XML_DOCUMENT_NODE:
Daniel Veillardd2897fd2002-01-30 16:37:32 +00001590#ifdef LIBXML_DOCB_ENABLED
Daniel Veillardd2379012002-03-15 22:24:56 +00001591 case XML_DOCB_DOCUMENT_NODE:
Daniel Veillardd2897fd2002-01-30 16:37:32 +00001592#endif
Daniel Veillardd2379012002-03-15 22:24:56 +00001593 case XML_HTML_DOCUMENT_NODE:
1594 res = NULL;
1595 break;
1596 case XML_ATTRIBUTE_NODE:{
1597 xmlAttrPtr attr = (xmlAttrPtr) cur;
1598
1599 res = (xmlNodePtr) attr->next;
1600 break;
1601 }
1602 case XML_NAMESPACE_DECL:{
1603 xmlNsPtr ns = (xmlNsPtr) cur;
1604
1605 res = (xmlNodePtr) ns->next;
1606 break;
1607 }
1608 default:
1609 res = cur->next;
1610 break;
Daniel Veillardd2897fd2002-01-30 16:37:32 +00001611
1612 }
1613 resultobj = libxml_xmlNodePtrWrap(res);
1614 return resultobj;
1615}
1616
1617static PyObject *
Daniel Veillardd2379012002-03-15 22:24:56 +00001618libxml_prev(ATTRIBUTE_UNUSED PyObject * self, PyObject * args)
Daniel Veillardd2897fd2002-01-30 16:37:32 +00001619{
1620 PyObject *resultobj, *obj;
1621 xmlNodePtr cur;
1622 xmlNodePtr res;
1623
Daniel Veillardd2379012002-03-15 22:24:56 +00001624 if (!PyArg_ParseTuple(args, (char *) "O:prev", &obj))
Daniel Veillardd2897fd2002-01-30 16:37:32 +00001625 return NULL;
1626 cur = PyxmlNode_Get(obj);
1627
1628#ifdef DEBUG
1629 printf("libxml_prev: cur = %p\n", cur);
1630#endif
1631
Daniel Veillardd2379012002-03-15 22:24:56 +00001632 switch (cur->type) {
1633 case XML_DOCUMENT_NODE:
Daniel Veillardd2897fd2002-01-30 16:37:32 +00001634#ifdef LIBXML_DOCB_ENABLED
Daniel Veillardd2379012002-03-15 22:24:56 +00001635 case XML_DOCB_DOCUMENT_NODE:
Daniel Veillardd2897fd2002-01-30 16:37:32 +00001636#endif
Daniel Veillardd2379012002-03-15 22:24:56 +00001637 case XML_HTML_DOCUMENT_NODE:
1638 res = NULL;
1639 break;
1640 case XML_ATTRIBUTE_NODE:{
1641 xmlAttrPtr attr = (xmlAttrPtr) cur;
1642
1643 res = (xmlNodePtr) attr->next;
1644 }
1645 case XML_NAMESPACE_DECL:
1646 res = NULL;
1647 break;
1648 default:
1649 res = cur->next;
1650 break;
Daniel Veillardd2897fd2002-01-30 16:37:32 +00001651 }
1652 resultobj = libxml_xmlNodePtrWrap(res);
1653 return resultobj;
1654}
1655
1656static PyObject *
Daniel Veillardd2379012002-03-15 22:24:56 +00001657libxml_children(ATTRIBUTE_UNUSED PyObject * self, PyObject * args)
Daniel Veillardd2897fd2002-01-30 16:37:32 +00001658{
1659 PyObject *resultobj, *obj;
1660 xmlNodePtr cur;
1661 xmlNodePtr res;
1662
Daniel Veillardd2379012002-03-15 22:24:56 +00001663 if (!PyArg_ParseTuple(args, (char *) "O:children", &obj))
Daniel Veillardd2897fd2002-01-30 16:37:32 +00001664 return NULL;
1665 cur = PyxmlNode_Get(obj);
1666
1667#ifdef DEBUG
1668 printf("libxml_children: cur = %p\n", cur);
1669#endif
1670
Daniel Veillardd2379012002-03-15 22:24:56 +00001671 switch (cur->type) {
1672 case XML_ELEMENT_NODE:
1673 case XML_ENTITY_REF_NODE:
1674 case XML_ENTITY_NODE:
1675 case XML_PI_NODE:
1676 case XML_COMMENT_NODE:
1677 case XML_DOCUMENT_NODE:
Daniel Veillardd2897fd2002-01-30 16:37:32 +00001678#ifdef LIBXML_DOCB_ENABLED
Daniel Veillardd2379012002-03-15 22:24:56 +00001679 case XML_DOCB_DOCUMENT_NODE:
Daniel Veillardd2897fd2002-01-30 16:37:32 +00001680#endif
Daniel Veillardd2379012002-03-15 22:24:56 +00001681 case XML_HTML_DOCUMENT_NODE:
1682 case XML_DTD_NODE:
1683 res = cur->children;
1684 break;
1685 case XML_ATTRIBUTE_NODE:{
1686 xmlAttrPtr attr = (xmlAttrPtr) cur;
1687
1688 res = attr->children;
1689 break;
1690 }
1691 default:
1692 res = NULL;
1693 break;
Daniel Veillardd2897fd2002-01-30 16:37:32 +00001694 }
1695 resultobj = libxml_xmlNodePtrWrap(res);
1696 return resultobj;
1697}
1698
1699static PyObject *
Daniel Veillardd2379012002-03-15 22:24:56 +00001700libxml_last(ATTRIBUTE_UNUSED PyObject * self, PyObject * args)
Daniel Veillardd2897fd2002-01-30 16:37:32 +00001701{
1702 PyObject *resultobj, *obj;
1703 xmlNodePtr cur;
1704 xmlNodePtr res;
1705
Daniel Veillardd2379012002-03-15 22:24:56 +00001706 if (!PyArg_ParseTuple(args, (char *) "O:last", &obj))
Daniel Veillardd2897fd2002-01-30 16:37:32 +00001707 return NULL;
1708 cur = PyxmlNode_Get(obj);
1709
1710#ifdef DEBUG
1711 printf("libxml_last: cur = %p\n", cur);
1712#endif
1713
Daniel Veillardd2379012002-03-15 22:24:56 +00001714 switch (cur->type) {
1715 case XML_ELEMENT_NODE:
1716 case XML_ENTITY_REF_NODE:
1717 case XML_ENTITY_NODE:
1718 case XML_PI_NODE:
1719 case XML_COMMENT_NODE:
1720 case XML_DOCUMENT_NODE:
Daniel Veillardd2897fd2002-01-30 16:37:32 +00001721#ifdef LIBXML_DOCB_ENABLED
Daniel Veillardd2379012002-03-15 22:24:56 +00001722 case XML_DOCB_DOCUMENT_NODE:
Daniel Veillardd2897fd2002-01-30 16:37:32 +00001723#endif
Daniel Veillardd2379012002-03-15 22:24:56 +00001724 case XML_HTML_DOCUMENT_NODE:
1725 case XML_DTD_NODE:
1726 res = cur->last;
1727 break;
1728 case XML_ATTRIBUTE_NODE:{
1729 xmlAttrPtr attr = (xmlAttrPtr) cur;
1730
1731 res = attr->last;
1732 }
1733 default:
1734 res = NULL;
1735 break;
Daniel Veillardd2897fd2002-01-30 16:37:32 +00001736 }
1737 resultobj = libxml_xmlNodePtrWrap(res);
1738 return resultobj;
1739}
1740
1741static PyObject *
Daniel Veillardd2379012002-03-15 22:24:56 +00001742libxml_parent(ATTRIBUTE_UNUSED PyObject * self, PyObject * args)
Daniel Veillardd2897fd2002-01-30 16:37:32 +00001743{
1744 PyObject *resultobj, *obj;
1745 xmlNodePtr cur;
1746 xmlNodePtr res;
1747
Daniel Veillardd2379012002-03-15 22:24:56 +00001748 if (!PyArg_ParseTuple(args, (char *) "O:parent", &obj))
Daniel Veillardd2897fd2002-01-30 16:37:32 +00001749 return NULL;
1750 cur = PyxmlNode_Get(obj);
1751
1752#ifdef DEBUG
1753 printf("libxml_parent: cur = %p\n", cur);
1754#endif
1755
Daniel Veillardd2379012002-03-15 22:24:56 +00001756 switch (cur->type) {
1757 case XML_DOCUMENT_NODE:
1758 case XML_HTML_DOCUMENT_NODE:
Daniel Veillardd2897fd2002-01-30 16:37:32 +00001759#ifdef LIBXML_DOCB_ENABLED
Daniel Veillardd2379012002-03-15 22:24:56 +00001760 case XML_DOCB_DOCUMENT_NODE:
Daniel Veillardd2897fd2002-01-30 16:37:32 +00001761#endif
Daniel Veillardd2379012002-03-15 22:24:56 +00001762 res = NULL;
1763 break;
1764 case XML_ATTRIBUTE_NODE:{
1765 xmlAttrPtr attr = (xmlAttrPtr) cur;
1766
1767 res = attr->parent;
1768 }
1769 case XML_ENTITY_DECL:
1770 case XML_NAMESPACE_DECL:
1771 case XML_XINCLUDE_START:
1772 case XML_XINCLUDE_END:
1773 res = NULL;
1774 break;
1775 default:
1776 res = cur->parent;
1777 break;
Daniel Veillardd2897fd2002-01-30 16:37:32 +00001778 }
1779 resultobj = libxml_xmlNodePtrWrap(res);
1780 return resultobj;
1781}
1782
1783static PyObject *
Daniel Veillardd2379012002-03-15 22:24:56 +00001784libxml_type(ATTRIBUTE_UNUSED PyObject * self, PyObject * args)
Daniel Veillardd2897fd2002-01-30 16:37:32 +00001785{
1786 PyObject *resultobj, *obj;
1787 xmlNodePtr cur;
Daniel Veillardd2379012002-03-15 22:24:56 +00001788 const xmlChar *res = NULL;
Daniel Veillardd2897fd2002-01-30 16:37:32 +00001789
Daniel Veillardd2379012002-03-15 22:24:56 +00001790 if (!PyArg_ParseTuple(args, (char *) "O:last", &obj))
Daniel Veillardd2897fd2002-01-30 16:37:32 +00001791 return NULL;
1792 cur = PyxmlNode_Get(obj);
1793
1794#ifdef DEBUG
1795 printf("libxml_type: cur = %p\n", cur);
1796#endif
1797
Daniel Veillardd2379012002-03-15 22:24:56 +00001798 switch (cur->type) {
Daniel Veillardd2897fd2002-01-30 16:37:32 +00001799 case XML_ELEMENT_NODE:
Daniel Veillardd2379012002-03-15 22:24:56 +00001800 res = (const xmlChar *) "element";
1801 break;
Daniel Veillardd2897fd2002-01-30 16:37:32 +00001802 case XML_ATTRIBUTE_NODE:
Daniel Veillardd2379012002-03-15 22:24:56 +00001803 res = (const xmlChar *) "attribute";
1804 break;
Daniel Veillardd2897fd2002-01-30 16:37:32 +00001805 case XML_TEXT_NODE:
Daniel Veillardd2379012002-03-15 22:24:56 +00001806 res = (const xmlChar *) "text";
1807 break;
Daniel Veillardd2897fd2002-01-30 16:37:32 +00001808 case XML_CDATA_SECTION_NODE:
Daniel Veillardd2379012002-03-15 22:24:56 +00001809 res = (const xmlChar *) "cdata";
1810 break;
Daniel Veillardd2897fd2002-01-30 16:37:32 +00001811 case XML_ENTITY_REF_NODE:
Daniel Veillardd2379012002-03-15 22:24:56 +00001812 res = (const xmlChar *) "entity_ref";
1813 break;
Daniel Veillardd2897fd2002-01-30 16:37:32 +00001814 case XML_ENTITY_NODE:
Daniel Veillardd2379012002-03-15 22:24:56 +00001815 res = (const xmlChar *) "entity";
1816 break;
Daniel Veillardd2897fd2002-01-30 16:37:32 +00001817 case XML_PI_NODE:
Daniel Veillardd2379012002-03-15 22:24:56 +00001818 res = (const xmlChar *) "pi";
1819 break;
Daniel Veillardd2897fd2002-01-30 16:37:32 +00001820 case XML_COMMENT_NODE:
Daniel Veillardd2379012002-03-15 22:24:56 +00001821 res = (const xmlChar *) "comment";
1822 break;
Daniel Veillardd2897fd2002-01-30 16:37:32 +00001823 case XML_DOCUMENT_NODE:
Daniel Veillardd2379012002-03-15 22:24:56 +00001824 res = (const xmlChar *) "document_xml";
1825 break;
Daniel Veillardd2897fd2002-01-30 16:37:32 +00001826 case XML_DOCUMENT_TYPE_NODE:
Daniel Veillardd2379012002-03-15 22:24:56 +00001827 res = (const xmlChar *) "doctype";
1828 break;
Daniel Veillardd2897fd2002-01-30 16:37:32 +00001829 case XML_DOCUMENT_FRAG_NODE:
Daniel Veillardd2379012002-03-15 22:24:56 +00001830 res = (const xmlChar *) "fragment";
1831 break;
Daniel Veillardd2897fd2002-01-30 16:37:32 +00001832 case XML_NOTATION_NODE:
Daniel Veillardd2379012002-03-15 22:24:56 +00001833 res = (const xmlChar *) "notation";
1834 break;
Daniel Veillardd2897fd2002-01-30 16:37:32 +00001835 case XML_HTML_DOCUMENT_NODE:
Daniel Veillardd2379012002-03-15 22:24:56 +00001836 res = (const xmlChar *) "document_html";
1837 break;
Daniel Veillardd2897fd2002-01-30 16:37:32 +00001838 case XML_DTD_NODE:
Daniel Veillardd2379012002-03-15 22:24:56 +00001839 res = (const xmlChar *) "dtd";
1840 break;
Daniel Veillardd2897fd2002-01-30 16:37:32 +00001841 case XML_ELEMENT_DECL:
Daniel Veillardd2379012002-03-15 22:24:56 +00001842 res = (const xmlChar *) "elem_decl";
1843 break;
Daniel Veillardd2897fd2002-01-30 16:37:32 +00001844 case XML_ATTRIBUTE_DECL:
Daniel Veillardd2379012002-03-15 22:24:56 +00001845 res = (const xmlChar *) "attribute_decl";
1846 break;
Daniel Veillardd2897fd2002-01-30 16:37:32 +00001847 case XML_ENTITY_DECL:
Daniel Veillardd2379012002-03-15 22:24:56 +00001848 res = (const xmlChar *) "entity_decl";
1849 break;
Daniel Veillardd2897fd2002-01-30 16:37:32 +00001850 case XML_NAMESPACE_DECL:
Daniel Veillardd2379012002-03-15 22:24:56 +00001851 res = (const xmlChar *) "namespace";
1852 break;
Daniel Veillardd2897fd2002-01-30 16:37:32 +00001853 case XML_XINCLUDE_START:
Daniel Veillardd2379012002-03-15 22:24:56 +00001854 res = (const xmlChar *) "xinclude_start";
1855 break;
Daniel Veillardd2897fd2002-01-30 16:37:32 +00001856 case XML_XINCLUDE_END:
Daniel Veillardd2379012002-03-15 22:24:56 +00001857 res = (const xmlChar *) "xinclude_end";
1858 break;
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:
1861 res = (const xmlChar *) "document_docbook";
1862 break;
Daniel Veillardd2897fd2002-01-30 16:37:32 +00001863#endif
1864 }
1865#ifdef DEBUG
1866 printf("libxml_type: cur = %p: %s\n", cur, res);
1867#endif
1868
Daniel Veillard1971ee22002-01-31 20:29:19 +00001869 resultobj = libxml_constxmlCharPtrWrap(res);
Daniel Veillardd2897fd2002-01-30 16:37:32 +00001870 return resultobj;
1871}
1872
1873/************************************************************************
1874 * *
Daniel Veillard36eea2d2002-02-04 00:17:01 +00001875 * Specific accessor functions *
1876 * *
1877 ************************************************************************/
1878PyObject *
Daniel Veillardd2379012002-03-15 22:24:56 +00001879libxml_xmlNodeGetNsDefs(ATTRIBUTE_UNUSED PyObject * self, PyObject * args)
1880{
Daniel Veillard36eea2d2002-02-04 00:17:01 +00001881 PyObject *py_retval;
1882 xmlNsPtr c_retval;
1883 xmlNodePtr node;
1884 PyObject *pyobj_node;
1885
Daniel Veillardd2379012002-03-15 22:24:56 +00001886 if (!PyArg_ParseTuple
1887 (args, (char *) "O:xmlNodeGetNsDefs", &pyobj_node))
1888 return (NULL);
Daniel Veillard36eea2d2002-02-04 00:17:01 +00001889 node = (xmlNodePtr) PyxmlNode_Get(pyobj_node);
1890
1891 if ((node == NULL) || (node->type != XML_ELEMENT_NODE)) {
Daniel Veillardd2379012002-03-15 22:24:56 +00001892 Py_INCREF(Py_None);
1893 return (Py_None);
Daniel Veillard36eea2d2002-02-04 00:17:01 +00001894 }
1895 c_retval = node->nsDef;
1896 py_retval = libxml_xmlNsPtrWrap((xmlNsPtr) c_retval);
Daniel Veillardd2379012002-03-15 22:24:56 +00001897 return (py_retval);
Daniel Veillard36eea2d2002-02-04 00:17:01 +00001898}
1899
1900PyObject *
Daniel Veillardd2379012002-03-15 22:24:56 +00001901libxml_xmlNodeGetNs(ATTRIBUTE_UNUSED PyObject * self, PyObject * args)
1902{
Daniel Veillard36eea2d2002-02-04 00:17:01 +00001903 PyObject *py_retval;
1904 xmlNsPtr c_retval;
1905 xmlNodePtr node;
1906 PyObject *pyobj_node;
1907
Daniel Veillardd2379012002-03-15 22:24:56 +00001908 if (!PyArg_ParseTuple(args, (char *) "O:xmlNodeGetNs", &pyobj_node))
1909 return (NULL);
Daniel Veillard36eea2d2002-02-04 00:17:01 +00001910 node = (xmlNodePtr) PyxmlNode_Get(pyobj_node);
1911
1912 if ((node == NULL) || (node->type != XML_ELEMENT_NODE)) {
Daniel Veillardd2379012002-03-15 22:24:56 +00001913 Py_INCREF(Py_None);
1914 return (Py_None);
Daniel Veillard36eea2d2002-02-04 00:17:01 +00001915 }
1916 c_retval = node->ns;
1917 py_retval = libxml_xmlNsPtrWrap((xmlNsPtr) c_retval);
Daniel Veillardd2379012002-03-15 22:24:56 +00001918 return (py_retval);
Daniel Veillard36eea2d2002-02-04 00:17:01 +00001919}
1920
1921/************************************************************************
1922 * *
Daniel Veillard1e774382002-03-06 17:35:40 +00001923 * Serialization front-end *
1924 * *
1925 ************************************************************************/
1926
Daniel Veillardd2379012002-03-15 22:24:56 +00001927static PyObject *
1928libxml_serializeNode(ATTRIBUTE_UNUSED PyObject * self, PyObject * args)
1929{
Daniel Veillard1e774382002-03-06 17:35:40 +00001930 PyObject *py_retval = NULL;
1931 xmlChar *c_retval;
1932 PyObject *pyobj_node;
1933 xmlNodePtr node;
1934 xmlDocPtr doc;
Daniel Veillardd2379012002-03-15 22:24:56 +00001935 const char *encoding;
Daniel Veillard1e774382002-03-06 17:35:40 +00001936 int format;
1937 int len;
1938
Daniel Veillardd2379012002-03-15 22:24:56 +00001939 if (!PyArg_ParseTuple(args, (char *) "Ozi:serializeNode", &pyobj_node,
1940 &encoding, &format))
1941 return (NULL);
Daniel Veillard1e774382002-03-06 17:35:40 +00001942 node = (xmlNodePtr) PyxmlNode_Get(pyobj_node);
1943
1944 if (node == NULL) {
Daniel Veillardd2379012002-03-15 22:24:56 +00001945 Py_INCREF(Py_None);
1946 return (Py_None);
Daniel Veillard1e774382002-03-06 17:35:40 +00001947 }
1948 if (node->type == XML_DOCUMENT_NODE) {
Daniel Veillardd2379012002-03-15 22:24:56 +00001949 doc = (xmlDocPtr) node;
1950 xmlDocDumpFormatMemoryEnc(doc, &c_retval, &len,
1951 (const char *) encoding, format);
1952 py_retval = libxml_charPtrWrap((char *) c_retval);
Daniel Veillard1e774382002-03-06 17:35:40 +00001953 } else if (node->type == XML_HTML_DOCUMENT_NODE) {
Daniel Veillardd2379012002-03-15 22:24:56 +00001954 xmlOutputBufferPtr buf;
1955 xmlCharEncodingHandlerPtr handler = NULL;
Daniel Veillard1e774382002-03-06 17:35:40 +00001956
Daniel Veillardd2379012002-03-15 22:24:56 +00001957 doc = (xmlDocPtr) node;
1958 if (encoding != NULL)
1959 htmlSetMetaEncoding(doc, (const xmlChar *) encoding);
1960 encoding = (const char *) htmlGetMetaEncoding(doc);
Daniel Veillard1e774382002-03-06 17:35:40 +00001961
Daniel Veillardd2379012002-03-15 22:24:56 +00001962 if (encoding != NULL) {
1963 handler = xmlFindCharEncodingHandler(encoding);
1964 if (handler == NULL) {
1965 Py_INCREF(Py_None);
1966 return (Py_None);
1967 }
1968 }
Daniel Veillard1e774382002-03-06 17:35:40 +00001969
Daniel Veillardd2379012002-03-15 22:24:56 +00001970 /*
1971 * Fallback to HTML or ASCII when the encoding is unspecified
1972 */
1973 if (handler == NULL)
1974 handler = xmlFindCharEncodingHandler("HTML");
1975 if (handler == NULL)
1976 handler = xmlFindCharEncodingHandler("ascii");
Daniel Veillard1e774382002-03-06 17:35:40 +00001977
Daniel Veillardd2379012002-03-15 22:24:56 +00001978 buf = xmlAllocOutputBuffer(handler);
1979 if (buf == NULL) {
1980 Py_INCREF(Py_None);
1981 return (Py_None);
1982 }
1983 htmlDocContentDumpFormatOutput(buf, doc, encoding, format);
1984 xmlOutputBufferFlush(buf);
1985 if (buf->conv != NULL) {
1986 len = buf->conv->use;
1987 c_retval = buf->conv->content;
1988 buf->conv->content = NULL;
1989 } else {
1990 len = buf->buffer->use;
1991 c_retval = buf->buffer->content;
1992 buf->buffer->content = NULL;
1993 }
1994 (void) xmlOutputBufferClose(buf);
1995 py_retval = libxml_charPtrWrap((char *) c_retval);
Daniel Veillard1e774382002-03-06 17:35:40 +00001996 } else {
Daniel Veillardd2379012002-03-15 22:24:56 +00001997 doc = node->doc;
1998 if (doc->type == XML_DOCUMENT_NODE) {
1999 xmlOutputBufferPtr buf;
2000 xmlCharEncodingHandlerPtr handler = NULL;
Daniel Veillard1e774382002-03-06 17:35:40 +00002001
Daniel Veillardd2379012002-03-15 22:24:56 +00002002 if (encoding != NULL) {
2003 handler = xmlFindCharEncodingHandler(encoding);
2004 if (handler == NULL) {
2005 Py_INCREF(Py_None);
2006 return (Py_None);
2007 }
2008 }
Daniel Veillard1e774382002-03-06 17:35:40 +00002009
Daniel Veillardd2379012002-03-15 22:24:56 +00002010 buf = xmlAllocOutputBuffer(handler);
2011 if (buf == NULL) {
2012 Py_INCREF(Py_None);
2013 return (Py_None);
2014 }
2015 xmlNodeDumpOutput(buf, doc, node, 0, format, encoding);
2016 xmlOutputBufferFlush(buf);
2017 if (buf->conv != NULL) {
2018 len = buf->conv->use;
2019 c_retval = buf->conv->content;
2020 buf->conv->content = NULL;
2021 } else {
2022 len = buf->buffer->use;
2023 c_retval = buf->buffer->content;
2024 buf->buffer->content = NULL;
2025 }
2026 (void) xmlOutputBufferClose(buf);
2027 py_retval = libxml_charPtrWrap((char *) c_retval);
2028 } else if (doc->type == XML_HTML_DOCUMENT_NODE) {
2029 xmlOutputBufferPtr buf;
2030 xmlCharEncodingHandlerPtr handler = NULL;
Daniel Veillard1e774382002-03-06 17:35:40 +00002031
Daniel Veillardd2379012002-03-15 22:24:56 +00002032 if (encoding != NULL)
2033 htmlSetMetaEncoding(doc, (const xmlChar *) encoding);
2034 encoding = (const char *) htmlGetMetaEncoding(doc);
2035 if (encoding != NULL) {
2036 handler = xmlFindCharEncodingHandler(encoding);
2037 if (handler == NULL) {
2038 Py_INCREF(Py_None);
2039 return (Py_None);
2040 }
2041 }
Daniel Veillard1e774382002-03-06 17:35:40 +00002042
Daniel Veillardd2379012002-03-15 22:24:56 +00002043 /*
2044 * Fallback to HTML or ASCII when the encoding is unspecified
2045 */
2046 if (handler == NULL)
2047 handler = xmlFindCharEncodingHandler("HTML");
2048 if (handler == NULL)
2049 handler = xmlFindCharEncodingHandler("ascii");
Daniel Veillard1e774382002-03-06 17:35:40 +00002050
Daniel Veillardd2379012002-03-15 22:24:56 +00002051 buf = xmlAllocOutputBuffer(handler);
2052 if (buf == NULL) {
2053 Py_INCREF(Py_None);
2054 return (Py_None);
2055 }
2056 htmlNodeDumpFormatOutput(buf, doc, node, encoding, format);
2057 xmlOutputBufferFlush(buf);
2058 if (buf->conv != NULL) {
2059 len = buf->conv->use;
2060 c_retval = buf->conv->content;
2061 buf->conv->content = NULL;
2062 } else {
2063 len = buf->buffer->use;
2064 c_retval = buf->buffer->content;
2065 buf->buffer->content = NULL;
2066 }
2067 (void) xmlOutputBufferClose(buf);
2068 py_retval = libxml_charPtrWrap((char *) c_retval);
2069 } else {
2070 Py_INCREF(Py_None);
2071 return (Py_None);
2072 }
Daniel Veillard1e774382002-03-06 17:35:40 +00002073 }
Daniel Veillardd2379012002-03-15 22:24:56 +00002074 return (py_retval);
Daniel Veillard1e774382002-03-06 17:35:40 +00002075}
2076
Daniel Veillardd2379012002-03-15 22:24:56 +00002077static PyObject *
2078libxml_saveNodeTo(ATTRIBUTE_UNUSED PyObject * self, PyObject * args)
2079{
Daniel Veillard1e774382002-03-06 17:35:40 +00002080 PyObject *py_file = NULL;
2081 FILE *output;
2082 PyObject *pyobj_node;
2083 xmlNodePtr node;
2084 xmlDocPtr doc;
Daniel Veillardd2379012002-03-15 22:24:56 +00002085 const char *encoding;
Daniel Veillard1e774382002-03-06 17:35:40 +00002086 int format;
2087 int len;
2088 xmlOutputBufferPtr buf;
2089 xmlCharEncodingHandlerPtr handler = NULL;
2090
Daniel Veillardd2379012002-03-15 22:24:56 +00002091 if (!PyArg_ParseTuple(args, (char *) "OOzi:serializeNode", &pyobj_node,
2092 &py_file, &encoding, &format))
2093 return (NULL);
Daniel Veillard1e774382002-03-06 17:35:40 +00002094 node = (xmlNodePtr) PyxmlNode_Get(pyobj_node);
2095
2096 if (node == NULL) {
Daniel Veillardd2379012002-03-15 22:24:56 +00002097 return (PyInt_FromLong((long) -1));
Daniel Veillard1e774382002-03-06 17:35:40 +00002098 }
2099 if ((py_file == NULL) || (!(PyFile_Check(py_file)))) {
Daniel Veillardd2379012002-03-15 22:24:56 +00002100 return (PyInt_FromLong((long) -1));
Daniel Veillard1e774382002-03-06 17:35:40 +00002101 }
2102 output = PyFile_AsFile(py_file);
2103 if (output == NULL) {
Daniel Veillardd2379012002-03-15 22:24:56 +00002104 return (PyInt_FromLong((long) -1));
Daniel Veillard1e774382002-03-06 17:35:40 +00002105 }
2106
2107 if (node->type == XML_DOCUMENT_NODE) {
Daniel Veillardd2379012002-03-15 22:24:56 +00002108 doc = (xmlDocPtr) node;
Daniel Veillard1e774382002-03-06 17:35:40 +00002109 } else if (node->type == XML_HTML_DOCUMENT_NODE) {
Daniel Veillardd2379012002-03-15 22:24:56 +00002110 doc = (xmlDocPtr) node;
Daniel Veillard1e774382002-03-06 17:35:40 +00002111 } else {
Daniel Veillardd2379012002-03-15 22:24:56 +00002112 doc = node->doc;
Daniel Veillard1e774382002-03-06 17:35:40 +00002113 }
2114 if (doc->type == XML_HTML_DOCUMENT_NODE) {
Daniel Veillardd2379012002-03-15 22:24:56 +00002115 if (encoding == NULL)
2116 encoding = (const char *) htmlGetMetaEncoding(doc);
Daniel Veillard1e774382002-03-06 17:35:40 +00002117 }
2118 if (encoding != NULL) {
Daniel Veillardd2379012002-03-15 22:24:56 +00002119 handler = xmlFindCharEncodingHandler(encoding);
2120 if (handler == NULL) {
2121 return (PyInt_FromLong((long) -1));
2122 }
Daniel Veillard1e774382002-03-06 17:35:40 +00002123 }
2124 if (doc->type == XML_HTML_DOCUMENT_NODE) {
Daniel Veillardd2379012002-03-15 22:24:56 +00002125 if (handler == NULL)
2126 handler = xmlFindCharEncodingHandler("HTML");
2127 if (handler == NULL)
2128 handler = xmlFindCharEncodingHandler("ascii");
Daniel Veillard1e774382002-03-06 17:35:40 +00002129 }
2130
2131 buf = xmlOutputBufferCreateFile(output, handler);
2132 if (node->type == XML_DOCUMENT_NODE) {
Daniel Veillardd2379012002-03-15 22:24:56 +00002133 len = xmlSaveFormatFileTo(buf, doc, encoding, format);
Daniel Veillard1e774382002-03-06 17:35:40 +00002134 } else if (node->type == XML_HTML_DOCUMENT_NODE) {
Daniel Veillardd2379012002-03-15 22:24:56 +00002135 htmlDocContentDumpFormatOutput(buf, doc, encoding, format);
2136 len = xmlOutputBufferClose(buf);
Daniel Veillard1e774382002-03-06 17:35:40 +00002137 } else if (doc->type == XML_HTML_DOCUMENT_NODE) {
Daniel Veillardd2379012002-03-15 22:24:56 +00002138 htmlNodeDumpFormatOutput(buf, doc, node, encoding, format);
2139 len = xmlOutputBufferClose(buf);
Daniel Veillard1e774382002-03-06 17:35:40 +00002140 } else {
Daniel Veillardd2379012002-03-15 22:24:56 +00002141 xmlNodeDumpOutput(buf, doc, node, 0, format, encoding);
2142 len = xmlOutputBufferClose(buf);
Daniel Veillard1e774382002-03-06 17:35:40 +00002143 }
Daniel Veillardd2379012002-03-15 22:24:56 +00002144 return (PyInt_FromLong((long) len));
Daniel Veillard1e774382002-03-06 17:35:40 +00002145}
2146
2147/************************************************************************
2148 * *
Daniel Veillarda94ec6f2002-03-01 13:00:53 +00002149 * Extra stuff *
2150 * *
2151 ************************************************************************/
2152PyObject *
Daniel Veillardd2379012002-03-15 22:24:56 +00002153libxml_xmlNewNode(ATTRIBUTE_UNUSED PyObject * self, PyObject * args)
2154{
Daniel Veillarda94ec6f2002-03-01 13:00:53 +00002155 PyObject *py_retval;
Daniel Veillardd2379012002-03-15 22:24:56 +00002156 xmlChar *name;
Daniel Veillarda94ec6f2002-03-01 13:00:53 +00002157 xmlNodePtr node;
2158
Daniel Veillardd2379012002-03-15 22:24:56 +00002159 if (!PyArg_ParseTuple(args, (char *) "s:xmlNewNode", &name))
2160 return (NULL);
Daniel Veillarda94ec6f2002-03-01 13:00:53 +00002161 node = (xmlNodePtr) xmlNewNode(NULL, name);
Daniel Veillardd2379012002-03-15 22:24:56 +00002162 printf("NewNode: %s : %p\n", name, (void *) node);
Daniel Veillarda94ec6f2002-03-01 13:00:53 +00002163
2164 if (node == NULL) {
Daniel Veillardd2379012002-03-15 22:24:56 +00002165 Py_INCREF(Py_None);
2166 return (Py_None);
Daniel Veillarda94ec6f2002-03-01 13:00:53 +00002167 }
2168 py_retval = libxml_xmlNodePtrWrap(node);
Daniel Veillardd2379012002-03-15 22:24:56 +00002169 return (py_retval);
Daniel Veillarda94ec6f2002-03-01 13:00:53 +00002170}
2171
2172/************************************************************************
2173 * *
Daniel Veillardd2897fd2002-01-30 16:37:32 +00002174 * The registration stuff *
2175 * *
2176 ************************************************************************/
2177static PyMethodDef libxmlMethods[] = {
Daniel Veillard96fe0952002-01-30 20:52:23 +00002178#include "libxml2-export.c"
Daniel Veillardd2379012002-03-15 22:24:56 +00002179 {(char *) "name", libxml_name, METH_VARARGS, NULL},
2180 {(char *) "children", libxml_children, METH_VARARGS, NULL},
2181 {(char *) "properties", libxml_properties, METH_VARARGS, NULL},
2182 {(char *) "last", libxml_last, METH_VARARGS, NULL},
2183 {(char *) "prev", libxml_prev, METH_VARARGS, NULL},
2184 {(char *) "next", libxml_next, METH_VARARGS, NULL},
2185 {(char *) "parent", libxml_parent, METH_VARARGS, NULL},
2186 {(char *) "type", libxml_type, METH_VARARGS, NULL},
2187 {(char *) "doc", libxml_doc, METH_VARARGS, NULL},
2188 {(char *) "xmlNewNode", libxml_xmlNewNode, METH_VARARGS, NULL},
2189 {(char *) "serializeNode", libxml_serializeNode, METH_VARARGS, NULL},
2190 {(char *) "saveNodeTo", libxml_saveNodeTo, METH_VARARGS, NULL},
Daniel Veillardc6d4a932002-09-12 15:00:57 +00002191 {(char *) "outputBufferCreate", libxml_xmlCreateOutputBuffer, METH_VARARGS, NULL},
2192 {(char *) "inputBufferCreate", libxml_xmlCreateInputBuffer, METH_VARARGS, NULL},
2193 {(char *) "setEntityLoader", libxml_xmlSetEntityLoader, METH_VARARGS, NULL},
Daniel Veillardd2379012002-03-15 22:24:56 +00002194 {NULL, NULL, 0, NULL}
Daniel Veillardd2897fd2002-01-30 16:37:32 +00002195};
2196
Daniel Veillard0fea6f42002-02-22 22:51:13 +00002197#ifdef MERGED_MODULES
Daniel Veillard6361da02002-02-23 10:10:33 +00002198extern void initlibxsltmod(void);
Daniel Veillard0fea6f42002-02-22 22:51:13 +00002199#endif
2200
Daniel Veillardd2379012002-03-15 22:24:56 +00002201void
2202initlibxml2mod(void)
2203{
Daniel Veillardaf43f632002-03-08 15:05:20 +00002204 static int initialized = 0;
Daniel Veillard3ce52572002-02-03 15:08:05 +00002205 PyObject *m;
Daniel Veillardaf43f632002-03-08 15:05:20 +00002206
2207 if (initialized != 0)
Daniel Veillardd2379012002-03-15 22:24:56 +00002208 return;
Daniel Veillardc6d4a932002-09-12 15:00:57 +00002209 xmlRegisterDefaultOutputCallbacks();
2210 xmlRegisterDefaultInputCallbacks();
Daniel Veillardd2379012002-03-15 22:24:56 +00002211 m = Py_InitModule((char *) "libxml2mod", libxmlMethods);
Daniel Veillardaf43f632002-03-08 15:05:20 +00002212 initialized = 1;
Daniel Veillard5d819032002-02-02 21:49:17 +00002213 libxml_xmlErrorInitialize();
Daniel Veillard6361da02002-02-23 10:10:33 +00002214
Daniel Veillard0fea6f42002-02-22 22:51:13 +00002215#ifdef MERGED_MODULES
2216 initlibxsltmod();
2217#endif
Daniel Veillardd2897fd2002-01-30 16:37:32 +00002218}