1 /*
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 *
7 * If compiled with MERGED_MODULES, the entry point will be used to
8 * initialize both the libxml2 and the libxslt wrappers
9 *
10 * See Copyright for the status of this software.
11 *
12 * [email protected]
13 */
14 #define PY_SSIZE_T_CLEAN
15 #include <Python.h>
16 #include <fileobject.h>
17 /* #include "config.h" */
18 #include <libxml/xmlmemory.h>
19 #include <libxml/parser.h>
20 #include <libxml/tree.h>
21 #include <libxml/xpath.h>
22 #include <libxml/xmlerror.h>
23 #include <libxml/xpathInternals.h>
24 #include <libxml/xmlmemory.h>
25 #include <libxml/xmlIO.h>
26 #include <libxml/c14n.h>
27 #include <libxml/xmlreader.h>
28 #include <libxml/xmlsave.h>
29 #include "libxml_wrap.h"
30 #include "libxml2-py.h"
31
32 #if PY_MAJOR_VERSION >= 3
33 PyObject *PyInit_libxml2mod(void);
34
35 #define PY_IMPORT_STRING_SIZE PyUnicode_FromStringAndSize
36 #define PY_IMPORT_STRING PyUnicode_FromString
37 #else
38 void initlibxml2mod(void);
39 #define PY_IMPORT_STRING_SIZE PyString_FromStringAndSize
40 #define PY_IMPORT_STRING PyString_FromString
41 #endif
42
43
44 /**
45 * TODO:
46 *
47 * macro to flag unimplemented blocks
48 */
49 #define TODO \
50 xmlGenericError(xmlGenericErrorContext, \
51 "Unimplemented block at %s:%d\n", \
52 __FILE__, __LINE__);
53
54 #ifdef LIBXML_XPATH_ENABLED
55 /*
56 * the following vars are used for XPath extensions, but
57 * are also referenced within the parser cleanup routine.
58 */
59 static int libxml_xpathCallbacksInitialized = 0;
60
61 typedef struct libxml_xpathCallback {
62 xmlXPathContextPtr ctx;
63 xmlChar *name;
64 xmlChar *ns_uri;
65 PyObject *function;
66 } libxml_xpathCallback, *libxml_xpathCallbackPtr;
67 typedef libxml_xpathCallback libxml_xpathCallbackArray[];
68 static int libxml_xpathCallbacksAllocd = 10;
69 static libxml_xpathCallbackArray *libxml_xpathCallbacks = NULL;
70 static int libxml_xpathCallbacksNb = 0;
71 #endif /* LIBXML_XPATH_ENABLED */
72
73 /************************************************************************
74 * *
75 * Memory debug interface *
76 * *
77 ************************************************************************/
78
79 #if 0
80 extern void xmlMemFree(void *ptr);
81 extern void *xmlMemMalloc(size_t size);
82 extern void *xmlMemRealloc(void *ptr, size_t size);
83 extern char *xmlMemoryStrdup(const char *str);
84 #endif
85
86 static int libxmlMemoryDebugActivated = 0;
87 static long libxmlMemoryAllocatedBase = 0;
88
89 static int libxmlMemoryDebug = 0;
90 static xmlFreeFunc freeFunc = NULL;
91 static xmlMallocFunc mallocFunc = NULL;
92 static xmlReallocFunc reallocFunc = NULL;
93 static xmlStrdupFunc strdupFunc = NULL;
94
95 static void
96 libxml_xmlErrorInitialize(void); /* forward declare */
97
98 PyObject *
libxml_xmlMemoryUsed(PyObject * self ATTRIBUTE_UNUSED,PyObject * args ATTRIBUTE_UNUSED)99 libxml_xmlMemoryUsed(PyObject * self ATTRIBUTE_UNUSED,
100 PyObject * args ATTRIBUTE_UNUSED)
101 {
102 long ret;
103 PyObject *py_retval;
104
105 ret = xmlMemUsed();
106
107 py_retval = libxml_longWrap(ret);
108 return (py_retval);
109 }
110
111 PyObject *
libxml_xmlDebugMemory(PyObject * self ATTRIBUTE_UNUSED,PyObject * args)112 libxml_xmlDebugMemory(PyObject * self ATTRIBUTE_UNUSED, PyObject * args)
113 {
114 int activate;
115 PyObject *py_retval;
116 long ret;
117
118 if (!PyArg_ParseTuple(args, (char *) "i:xmlDebugMemory", &activate))
119 return (NULL);
120
121 if (activate != 0) {
122 if (libxmlMemoryDebug == 0) {
123 /*
124 * First initialize the library and grab the old memory handlers
125 * and switch the library to memory debugging
126 */
127 xmlMemGet((xmlFreeFunc *) & freeFunc,
128 (xmlMallocFunc *) & mallocFunc,
129 (xmlReallocFunc *) & reallocFunc,
130 (xmlStrdupFunc *) & strdupFunc);
131 if ((freeFunc == xmlMemFree) && (mallocFunc == xmlMemMalloc) &&
132 (reallocFunc == xmlMemRealloc) &&
133 (strdupFunc == xmlMemoryStrdup)) {
134 } else {
135 ret = (long) xmlMemSetup(xmlMemFree, xmlMemMalloc,
136 xmlMemRealloc, xmlMemoryStrdup);
137 if (ret < 0)
138 goto error;
139 }
140 libxmlMemoryAllocatedBase = xmlMemUsed();
141 ret = 0;
142 } else if (libxmlMemoryDebugActivated == 0) {
143 libxmlMemoryAllocatedBase = xmlMemUsed();
144 ret = 0;
145 } else {
146 ret = xmlMemUsed() - libxmlMemoryAllocatedBase;
147 }
148 libxmlMemoryDebug = 1;
149 libxmlMemoryDebugActivated = 1;
150 } else {
151 if (libxmlMemoryDebugActivated == 1)
152 ret = xmlMemUsed() - libxmlMemoryAllocatedBase;
153 else
154 ret = 0;
155 libxmlMemoryDebugActivated = 0;
156 }
157 error:
158 py_retval = libxml_longWrap(ret);
159 return (py_retval);
160 }
161
162 PyObject *
libxml_xmlPythonCleanupParser(PyObject * self ATTRIBUTE_UNUSED,PyObject * args ATTRIBUTE_UNUSED)163 libxml_xmlPythonCleanupParser(PyObject *self ATTRIBUTE_UNUSED,
164 PyObject *args ATTRIBUTE_UNUSED) {
165
166 #ifdef LIBXML_XPATH_ENABLED
167 int ix;
168
169 /*
170 * Need to confirm whether we really want to do this (required for
171 * memcheck) in all cases...
172 */
173
174 if (libxml_xpathCallbacks != NULL) { /* if ext funcs declared */
175 for (ix=0; ix<libxml_xpathCallbacksNb; ix++) {
176 if ((*libxml_xpathCallbacks)[ix].name != NULL)
177 xmlFree((*libxml_xpathCallbacks)[ix].name);
178 if ((*libxml_xpathCallbacks)[ix].ns_uri != NULL)
179 xmlFree((*libxml_xpathCallbacks)[ix].ns_uri);
180 }
181 libxml_xpathCallbacksNb = 0;
182 xmlFree(libxml_xpathCallbacks);
183 libxml_xpathCallbacks = NULL;
184 }
185 #endif /* LIBXML_XPATH_ENABLED */
186
187 xmlCleanupParser();
188
189 Py_INCREF(Py_None);
190 return(Py_None);
191 }
192
193 /************************************************************************
194 * *
195 * Handling Python FILE I/O at the C level *
196 * The raw I/O attack directly the File objects, while the *
197 * other routines address the ioWrapper instance instead *
198 * *
199 ************************************************************************/
200
201 /**
202 * xmlPythonFileCloseUnref:
203 * @context: the I/O context
204 *
205 * Close an I/O channel
206 */
207 static int
xmlPythonFileCloseRaw(void * context)208 xmlPythonFileCloseRaw (void * context) {
209 PyObject *file, *ret;
210
211 file = (PyObject *) context;
212 if (file == NULL) return(-1);
213 ret = PyObject_CallMethod(file, (char *) "close", (char *) "()");
214 if (ret != NULL) {
215 Py_DECREF(ret);
216 }
217 Py_DECREF(file);
218 return(0);
219 }
220
221 /**
222 * xmlPythonFileReadRaw:
223 * @context: the I/O context
224 * @buffer: where to drop data
225 * @len: number of bytes to write
226 *
227 * Read @len bytes to @buffer from the Python file in the I/O channel
228 *
229 * Returns the number of bytes read
230 */
231 static int
xmlPythonFileReadRaw(void * context,char * buffer,int len)232 xmlPythonFileReadRaw (void * context, char * buffer, int len) {
233 PyObject *file;
234 PyObject *ret;
235 int lenread = -1;
236 char *data;
237
238 file = (PyObject *) context;
239 if (file == NULL) return(-1);
240 ret = PyObject_CallMethod(file, (char *) "read", (char *) "(i)", len);
241 if (ret == NULL) {
242 printf("xmlPythonFileReadRaw: result is NULL\n");
243 return(-1);
244 } else if (PyBytes_Check(ret)) {
245 lenread = PyBytes_Size(ret);
246 data = PyBytes_AsString(ret);
247 #ifdef PyUnicode_Check
248 } else if (PyUnicode_Check (ret)) {
249 #if PY_VERSION_HEX >= 0x03030000
250 Py_ssize_t size;
251 const char *tmp;
252
253 /* tmp doesn't need to be deallocated */
254 tmp = PyUnicode_AsUTF8AndSize(ret, &size);
255
256 lenread = (int) size;
257 data = (char *) tmp;
258 #else
259 PyObject *b;
260 b = PyUnicode_AsUTF8String(ret);
261 if (b == NULL) {
262 printf("xmlPythonFileReadRaw: failed to convert to UTF-8\n");
263 return(-1);
264 }
265 lenread = PyBytes_Size(b);
266 data = PyBytes_AsString(b);
267 Py_DECREF(b);
268 #endif
269 #endif
270 } else {
271 printf("xmlPythonFileReadRaw: result is not a String\n");
272 Py_DECREF(ret);
273 return(-1);
274 }
275 if (lenread > len)
276 memcpy(buffer, data, len);
277 else
278 memcpy(buffer, data, lenread);
279 Py_DECREF(ret);
280 return(lenread);
281 }
282
283 /**
284 * xmlPythonFileRead:
285 * @context: the I/O context
286 * @buffer: where to drop data
287 * @len: number of bytes to write
288 *
289 * Read @len bytes to @buffer from the I/O channel.
290 *
291 * Returns the number of bytes read
292 */
293 static int
xmlPythonFileRead(void * context,char * buffer,int len)294 xmlPythonFileRead (void * context, char * buffer, int len) {
295 PyObject *file;
296 PyObject *ret;
297 int lenread = -1;
298 char *data;
299
300 file = (PyObject *) context;
301 if (file == NULL) return(-1);
302 ret = PyObject_CallMethod(file, (char *) "io_read", (char *) "(i)", len);
303 if (ret == NULL) {
304 printf("xmlPythonFileRead: result is NULL\n");
305 return(-1);
306 } else if (PyBytes_Check(ret)) {
307 lenread = PyBytes_Size(ret);
308 data = PyBytes_AsString(ret);
309 #ifdef PyUnicode_Check
310 } else if (PyUnicode_Check (ret)) {
311 #if PY_VERSION_HEX >= 0x03030000
312 Py_ssize_t size;
313 const char *tmp;
314
315 /* tmp doesn't need to be deallocated */
316 tmp = PyUnicode_AsUTF8AndSize(ret, &size);
317
318 lenread = (int) size;
319 data = (char *) tmp;
320 #else
321 PyObject *b;
322 b = PyUnicode_AsUTF8String(ret);
323 if (b == NULL) {
324 printf("xmlPythonFileRead: failed to convert to UTF-8\n");
325 return(-1);
326 }
327 lenread = PyBytes_Size(b);
328 data = PyBytes_AsString(b);
329 Py_DECREF(b);
330 #endif
331 #endif
332 } else {
333 printf("xmlPythonFileRead: result is not a String\n");
334 Py_DECREF(ret);
335 return(-1);
336 }
337 if (lenread > len)
338 memcpy(buffer, data, len);
339 else
340 memcpy(buffer, data, lenread);
341 Py_DECREF(ret);
342 return(lenread);
343 }
344
345 #ifdef LIBXML_OUTPUT_ENABLED
346 /**
347 * xmlFileWrite:
348 * @context: the I/O context
349 * @buffer: where to drop data
350 * @len: number of bytes to write
351 *
352 * Write @len bytes from @buffer to the I/O channel.
353 *
354 * Returns the number of bytes written
355 */
356 static int
xmlPythonFileWrite(void * context,const char * buffer,int len)357 xmlPythonFileWrite (void * context, const char * buffer, int len) {
358 PyObject *file;
359 PyObject *string;
360 PyObject *ret = NULL;
361 int written = -1;
362
363 file = (PyObject *) context;
364 if (file == NULL) return(-1);
365 string = PY_IMPORT_STRING_SIZE(buffer, len);
366 if (string == NULL) return(-1);
367 if (PyObject_HasAttrString(file, (char *) "io_write")) {
368 ret = PyObject_CallMethod(file, (char *) "io_write", (char *) "(O)",
369 string);
370 } else if (PyObject_HasAttrString(file, (char *) "write")) {
371 ret = PyObject_CallMethod(file, (char *) "write", (char *) "(O)",
372 string);
373 }
374 Py_DECREF(string);
375 if (ret == NULL) {
376 printf("xmlPythonFileWrite: result is NULL\n");
377 return(-1);
378 } else if (PyLong_Check(ret)) {
379 written = (int) PyLong_AsLong(ret);
380 Py_DECREF(ret);
381 } else if (ret == Py_None) {
382 written = len;
383 Py_DECREF(ret);
384 } else {
385 printf("xmlPythonFileWrite: result is not an Int nor None\n");
386 Py_DECREF(ret);
387 }
388 return(written);
389 }
390 #endif /* LIBXML_OUTPUT_ENABLED */
391
392 /**
393 * xmlPythonFileClose:
394 * @context: the I/O context
395 *
396 * Close an I/O channel
397 */
398 static int
xmlPythonFileClose(void * context)399 xmlPythonFileClose (void * context) {
400 PyObject *file, *ret = NULL;
401
402 file = (PyObject *) context;
403 if (file == NULL) return(-1);
404 if (PyObject_HasAttrString(file, (char *) "io_close")) {
405 ret = PyObject_CallMethod(file, (char *) "io_close", (char *) "()");
406 } else if (PyObject_HasAttrString(file, (char *) "flush")) {
407 ret = PyObject_CallMethod(file, (char *) "flush", (char *) "()");
408 }
409 if (ret != NULL) {
410 Py_DECREF(ret);
411 }
412 return(0);
413 }
414
415 #ifdef LIBXML_OUTPUT_ENABLED
416 /**
417 * xmlOutputBufferCreatePythonFile:
418 * @file: a PyFile_Type
419 * @encoder: the encoding converter or NULL
420 *
421 * Create a buffered output for the progressive saving to a PyFile_Type
422 * buffered C I/O
423 *
424 * Returns the new parser output or NULL
425 */
426 static xmlOutputBufferPtr
xmlOutputBufferCreatePythonFile(PyObject * file,xmlCharEncodingHandlerPtr encoder)427 xmlOutputBufferCreatePythonFile(PyObject *file,
428 xmlCharEncodingHandlerPtr encoder) {
429 xmlOutputBufferPtr ret;
430
431 if (file == NULL) return(NULL);
432
433 ret = xmlAllocOutputBuffer(encoder);
434 if (ret != NULL) {
435 ret->context = file;
436 /* Py_INCREF(file); */
437 ret->writecallback = xmlPythonFileWrite;
438 ret->closecallback = xmlPythonFileClose;
439 }
440
441 return(ret);
442 }
443
444 PyObject *
libxml_xmlCreateOutputBuffer(ATTRIBUTE_UNUSED PyObject * self,PyObject * args)445 libxml_xmlCreateOutputBuffer(ATTRIBUTE_UNUSED PyObject *self, PyObject *args) {
446 PyObject *py_retval;
447 PyObject *file;
448 xmlChar *encoding;
449 xmlCharEncodingHandlerPtr handler = NULL;
450 xmlOutputBufferPtr buffer;
451
452
453 if (!PyArg_ParseTuple(args, (char *)"Oz:xmlOutputBufferCreate",
454 &file, &encoding))
455 return(NULL);
456 if ((encoding != NULL) && (encoding[0] != 0)) {
457 handler = xmlFindCharEncodingHandler((const char *) encoding);
458 }
459 buffer = xmlOutputBufferCreatePythonFile(file, handler);
460 if (buffer == NULL)
461 printf("libxml_xmlCreateOutputBuffer: buffer == NULL\n");
462 py_retval = libxml_xmlOutputBufferPtrWrap(buffer);
463 return(py_retval);
464 }
465
466 /**
467 * libxml_outputBufferGetPythonFile:
468 * @buffer: the I/O buffer
469 *
470 * read the Python I/O from the CObject
471 *
472 * Returns the new parser output or NULL
473 */
474 static PyObject *
libxml_outputBufferGetPythonFile(ATTRIBUTE_UNUSED PyObject * self,PyObject * args)475 libxml_outputBufferGetPythonFile(ATTRIBUTE_UNUSED PyObject *self,
476 PyObject *args) {
477 PyObject *buffer;
478 PyObject *file;
479 xmlOutputBufferPtr obj;
480
481 if (!PyArg_ParseTuple(args, (char *)"O:outputBufferGetPythonFile",
482 &buffer))
483 return(NULL);
484
485 obj = PyoutputBuffer_Get(buffer);
486 if (obj == NULL) {
487 fprintf(stderr,
488 "outputBufferGetPythonFile: obj == NULL\n");
489 Py_INCREF(Py_None);
490 return(Py_None);
491 }
492 if (obj->closecallback != xmlPythonFileClose) {
493 fprintf(stderr,
494 "outputBufferGetPythonFile: not a python file wrapper\n");
495 Py_INCREF(Py_None);
496 return(Py_None);
497 }
498 file = (PyObject *) obj->context;
499 if (file == NULL) {
500 Py_INCREF(Py_None);
501 return(Py_None);
502 }
503 Py_INCREF(file);
504 return(file);
505 }
506
507 static PyObject *
libxml_xmlOutputBufferClose(PyObject * self ATTRIBUTE_UNUSED,PyObject * args)508 libxml_xmlOutputBufferClose(PyObject *self ATTRIBUTE_UNUSED, PyObject *args) {
509 PyObject *py_retval;
510 int c_retval;
511 xmlOutputBufferPtr out;
512 PyObject *pyobj_out;
513
514 if (!PyArg_ParseTuple(args, (char *)"O:xmlOutputBufferClose", &pyobj_out))
515 return(NULL);
516 out = (xmlOutputBufferPtr) PyoutputBuffer_Get(pyobj_out);
517 /* Buffer may already have been destroyed elsewhere. This is harmless. */
518 if (out == NULL) {
519 Py_INCREF(Py_None);
520 return(Py_None);
521 }
522
523 c_retval = xmlOutputBufferClose(out);
524 py_retval = libxml_intWrap((int) c_retval);
525 return(py_retval);
526 }
527
528 static PyObject *
libxml_xmlOutputBufferFlush(PyObject * self ATTRIBUTE_UNUSED,PyObject * args)529 libxml_xmlOutputBufferFlush(PyObject *self ATTRIBUTE_UNUSED, PyObject *args) {
530 PyObject *py_retval;
531 int c_retval;
532 xmlOutputBufferPtr out;
533 PyObject *pyobj_out;
534
535 if (!PyArg_ParseTuple(args, (char *)"O:xmlOutputBufferFlush", &pyobj_out))
536 return(NULL);
537 out = (xmlOutputBufferPtr) PyoutputBuffer_Get(pyobj_out);
538
539 c_retval = xmlOutputBufferFlush(out);
540 py_retval = libxml_intWrap((int) c_retval);
541 return(py_retval);
542 }
543
544 static PyObject *
libxml_xmlSaveFileTo(PyObject * self ATTRIBUTE_UNUSED,PyObject * args)545 libxml_xmlSaveFileTo(PyObject *self ATTRIBUTE_UNUSED, PyObject *args) {
546 PyObject *py_retval;
547 int c_retval;
548 xmlOutputBufferPtr buf;
549 PyObject *pyobj_buf;
550 xmlDocPtr cur;
551 PyObject *pyobj_cur;
552 char * encoding;
553
554 if (!PyArg_ParseTuple(args, (char *)"OOz:xmlSaveFileTo", &pyobj_buf, &pyobj_cur, &encoding))
555 return(NULL);
556 buf = (xmlOutputBufferPtr) PyoutputBuffer_Get(pyobj_buf);
557 cur = (xmlDocPtr) PyxmlNode_Get(pyobj_cur);
558
559 c_retval = xmlSaveFileTo(buf, cur, encoding);
560 /* xmlSaveTo() freed the memory pointed to by buf, so record that in the
561 * Python object. */
562 ((PyoutputBuffer_Object *)(pyobj_buf))->obj = NULL;
563 py_retval = libxml_intWrap((int) c_retval);
564 return(py_retval);
565 }
566
567 static PyObject *
libxml_xmlSaveFormatFileTo(PyObject * self ATTRIBUTE_UNUSED,PyObject * args)568 libxml_xmlSaveFormatFileTo(PyObject *self ATTRIBUTE_UNUSED, PyObject *args) {
569 PyObject *py_retval;
570 int c_retval;
571 xmlOutputBufferPtr buf;
572 PyObject *pyobj_buf;
573 xmlDocPtr cur;
574 PyObject *pyobj_cur;
575 char * encoding;
576 int format;
577
578 if (!PyArg_ParseTuple(args, (char *)"OOzi:xmlSaveFormatFileTo", &pyobj_buf, &pyobj_cur, &encoding, &format))
579 return(NULL);
580 buf = (xmlOutputBufferPtr) PyoutputBuffer_Get(pyobj_buf);
581 cur = (xmlDocPtr) PyxmlNode_Get(pyobj_cur);
582
583 c_retval = xmlSaveFormatFileTo(buf, cur, encoding, format);
584 /* xmlSaveFormatFileTo() freed the memory pointed to by buf, so record that
585 * in the Python object */
586 ((PyoutputBuffer_Object *)(pyobj_buf))->obj = NULL;
587 py_retval = libxml_intWrap((int) c_retval);
588 return(py_retval);
589 }
590 #endif /* LIBXML_OUTPUT_ENABLED */
591
592
593 /**
594 * xmlParserInputBufferCreatePythonFile:
595 * @file: a PyFile_Type
596 * @encoder: the encoding converter or NULL
597 *
598 * Create a buffered output for the progressive saving to a PyFile_Type
599 * buffered C I/O
600 *
601 * Returns the new parser output or NULL
602 */
603 static xmlParserInputBufferPtr
xmlParserInputBufferCreatePythonFile(PyObject * file,xmlCharEncoding encoding)604 xmlParserInputBufferCreatePythonFile(PyObject *file,
605 xmlCharEncoding encoding) {
606 xmlParserInputBufferPtr ret;
607
608 if (file == NULL) return(NULL);
609
610 ret = xmlAllocParserInputBuffer(encoding);
611 if (ret != NULL) {
612 ret->context = file;
613 /* Py_INCREF(file); */
614 ret->readcallback = xmlPythonFileRead;
615 ret->closecallback = xmlPythonFileClose;
616 }
617
618 return(ret);
619 }
620
621 PyObject *
libxml_xmlCreateInputBuffer(ATTRIBUTE_UNUSED PyObject * self,PyObject * args)622 libxml_xmlCreateInputBuffer(ATTRIBUTE_UNUSED PyObject *self, PyObject *args) {
623 PyObject *py_retval;
624 PyObject *file;
625 xmlChar *encoding;
626 xmlCharEncoding enc = XML_CHAR_ENCODING_NONE;
627 xmlParserInputBufferPtr buffer;
628
629
630 if (!PyArg_ParseTuple(args, (char *)"Oz:xmlParserInputBufferCreate",
631 &file, &encoding))
632 return(NULL);
633 if ((encoding != NULL) && (encoding[0] != 0)) {
634 enc = xmlParseCharEncoding((const char *) encoding);
635 }
636 buffer = xmlParserInputBufferCreatePythonFile(file, enc);
637 if (buffer == NULL)
638 printf("libxml_xmlParserInputBufferCreate: buffer == NULL\n");
639 py_retval = libxml_xmlParserInputBufferPtrWrap(buffer);
640 return(py_retval);
641 }
642
643 /************************************************************************
644 * *
645 * Providing the resolver at the Python level *
646 * *
647 ************************************************************************/
648
649 static xmlExternalEntityLoader defaultExternalEntityLoader = NULL;
650 static PyObject *pythonExternalEntityLoaderObjext;
651
652 static xmlParserInputPtr
pythonExternalEntityLoader(const char * URL,const char * ID,xmlParserCtxtPtr ctxt)653 pythonExternalEntityLoader(const char *URL, const char *ID,
654 xmlParserCtxtPtr ctxt) {
655 xmlParserInputPtr result = NULL;
656 if (pythonExternalEntityLoaderObjext != NULL) {
657 PyObject *ret;
658 PyObject *ctxtobj;
659
660 ctxtobj = libxml_xmlParserCtxtPtrWrap(ctxt);
661
662 ret = PyObject_CallFunction(pythonExternalEntityLoaderObjext,
663 (char *) "(ssO)", URL, ID, ctxtobj);
664 Py_XDECREF(ctxtobj);
665
666 if (ret != NULL) {
667 if (PyObject_HasAttrString(ret, (char *) "read")) {
668 xmlParserInputBufferPtr buf;
669
670 buf = xmlAllocParserInputBuffer(XML_CHAR_ENCODING_NONE);
671 if (buf != NULL) {
672 buf->context = ret;
673 buf->readcallback = xmlPythonFileReadRaw;
674 buf->closecallback = xmlPythonFileCloseRaw;
675 result = xmlNewIOInputStream(ctxt, buf,
676 XML_CHAR_ENCODING_NONE);
677 }
678 #if 0
679 } else {
680 if (URL != NULL)
681 printf("pythonExternalEntityLoader: can't read %s\n",
682 URL);
683 #endif
684 }
685 if (result == NULL) {
686 Py_DECREF(ret);
687 } else if (URL != NULL) {
688 result->filename = (char *) xmlStrdup((const xmlChar *)URL);
689 }
690 }
691 }
692 if ((result == NULL) && (defaultExternalEntityLoader != NULL)) {
693 result = defaultExternalEntityLoader(URL, ID, ctxt);
694 }
695 return(result);
696 }
697
698 PyObject *
libxml_xmlSetEntityLoader(ATTRIBUTE_UNUSED PyObject * self,PyObject * args)699 libxml_xmlSetEntityLoader(ATTRIBUTE_UNUSED PyObject *self, PyObject *args) {
700 PyObject *py_retval;
701 PyObject *loader;
702
703 if (!PyArg_ParseTuple(args, (char *)"O:libxml_xmlSetEntityLoader",
704 &loader))
705 return(NULL);
706
707 if (!PyCallable_Check(loader)) {
708 PyErr_SetString(PyExc_ValueError, "entity loader is not callable");
709 return(NULL);
710 }
711
712 if (defaultExternalEntityLoader == NULL)
713 defaultExternalEntityLoader = xmlGetExternalEntityLoader();
714
715 Py_XDECREF(pythonExternalEntityLoaderObjext);
716 pythonExternalEntityLoaderObjext = loader;
717 Py_XINCREF(pythonExternalEntityLoaderObjext);
718 xmlSetExternalEntityLoader(pythonExternalEntityLoader);
719
720 py_retval = PyLong_FromLong(0);
721 return(py_retval);
722 }
723
724 /************************************************************************
725 * *
726 * Input callback registration *
727 * *
728 ************************************************************************/
729 static PyObject *pythonInputOpenCallbackObject;
730 static int pythonInputCallbackID = -1;
731
732 static int
pythonInputMatchCallback(ATTRIBUTE_UNUSED const char * URI)733 pythonInputMatchCallback(ATTRIBUTE_UNUSED const char *URI)
734 {
735 /* Always return success, real decision whether URI is supported will be
736 * made in open callback. */
737 return 1;
738 }
739
740 static void *
pythonInputOpenCallback(const char * URI)741 pythonInputOpenCallback(const char *URI)
742 {
743 PyObject *ret;
744
745 ret = PyObject_CallFunction(pythonInputOpenCallbackObject,
746 (char *)"s", URI);
747 if (ret == Py_None) {
748 Py_DECREF(Py_None);
749 return NULL;
750 }
751 return ret;
752 }
753
754 PyObject *
libxml_xmlRegisterInputCallback(ATTRIBUTE_UNUSED PyObject * self,PyObject * args)755 libxml_xmlRegisterInputCallback(ATTRIBUTE_UNUSED PyObject *self,
756 PyObject *args) {
757 PyObject *cb;
758
759 if (!PyArg_ParseTuple(args,
760 (const char *)"O:libxml_xmlRegisterInputCallback", &cb))
761 return(NULL);
762
763 if (!PyCallable_Check(cb)) {
764 PyErr_SetString(PyExc_ValueError, "input callback is not callable");
765 return(NULL);
766 }
767
768 /* Python module registers a single callback and manages the list of
769 * all callbacks internally. This is necessitated by xmlInputMatchCallback
770 * API, which does not allow for passing of data objects to discriminate
771 * different Python methods. */
772 if (pythonInputCallbackID == -1) {
773 pythonInputCallbackID = xmlRegisterInputCallbacks(
774 pythonInputMatchCallback, pythonInputOpenCallback,
775 xmlPythonFileReadRaw, xmlPythonFileCloseRaw);
776 if (pythonInputCallbackID == -1)
777 return PyErr_NoMemory();
778 pythonInputOpenCallbackObject = cb;
779 Py_INCREF(pythonInputOpenCallbackObject);
780 }
781
782 Py_INCREF(Py_None);
783 return(Py_None);
784 }
785
786 PyObject *
libxml_xmlUnregisterInputCallback(ATTRIBUTE_UNUSED PyObject * self,ATTRIBUTE_UNUSED PyObject * args)787 libxml_xmlUnregisterInputCallback(ATTRIBUTE_UNUSED PyObject *self,
788 ATTRIBUTE_UNUSED PyObject *args) {
789 int ret;
790
791 ret = xmlPopInputCallbacks();
792 if (pythonInputCallbackID != -1) {
793 /* Assert that the right input callback was popped. libxml's API does not
794 * allow removal by ID, so all that could be done is an assert. */
795 if (pythonInputCallbackID == ret) {
796 pythonInputCallbackID = -1;
797 Py_DECREF(pythonInputOpenCallbackObject);
798 pythonInputOpenCallbackObject = NULL;
799 } else {
800 PyErr_SetString(PyExc_AssertionError, "popped non-python input callback");
801 return(NULL);
802 }
803 } else if (ret == -1) {
804 /* No more callbacks to pop */
805 PyErr_SetString(PyExc_IndexError, "no input callbacks to pop");
806 return(NULL);
807 }
808
809 Py_INCREF(Py_None);
810 return(Py_None);
811 }
812
813 /************************************************************************
814 * *
815 * Handling SAX/xmllib/sgmlop callback interfaces *
816 * *
817 ************************************************************************/
818
819 static void
pythonStartElement(void * user_data,const xmlChar * name,const xmlChar ** attrs)820 pythonStartElement(void *user_data, const xmlChar * name,
821 const xmlChar ** attrs)
822 {
823 int i;
824 PyObject *handler;
825 PyObject *dict;
826 PyObject *attrname;
827 PyObject *attrvalue;
828 PyObject *result = NULL;
829 int type = 0;
830
831 handler = (PyObject *) user_data;
832 if (PyObject_HasAttrString(handler, (char *) "startElement"))
833 type = 1;
834 else if (PyObject_HasAttrString(handler, (char *) "start"))
835 type = 2;
836 if (type != 0) {
837 /*
838 * the xmllib interface always generates a dictionary,
839 * possibly empty
840 */
841 if ((attrs == NULL) && (type == 1)) {
842 Py_XINCREF(Py_None);
843 dict = Py_None;
844 } else if (attrs == NULL) {
845 dict = PyDict_New();
846 } else {
847 dict = PyDict_New();
848 for (i = 0; attrs[i] != NULL; i++) {
849 attrname = PY_IMPORT_STRING((char *) attrs[i]);
850 i++;
851 if (attrs[i] != NULL) {
852 attrvalue = PY_IMPORT_STRING((char *) attrs[i]);
853 } else {
854 Py_XINCREF(Py_None);
855 attrvalue = Py_None;
856 }
857 PyDict_SetItem(dict, attrname, attrvalue);
858 Py_DECREF(attrname);
859 Py_DECREF(attrvalue);
860 }
861 }
862
863 if (type == 1)
864 result = PyObject_CallMethod(handler, (char *) "startElement",
865 (char *) "sO", name, dict);
866 else if (type == 2)
867 result = PyObject_CallMethod(handler, (char *) "start",
868 (char *) "sO", name, dict);
869 if (PyErr_Occurred())
870 PyErr_Print();
871 Py_XDECREF(dict);
872 Py_XDECREF(result);
873 }
874 }
875
876 static void
pythonStartDocument(void * user_data)877 pythonStartDocument(void *user_data)
878 {
879 PyObject *handler;
880 PyObject *result;
881
882 handler = (PyObject *) user_data;
883 if (PyObject_HasAttrString(handler, (char *) "startDocument")) {
884 result =
885 PyObject_CallMethod(handler, (char *) "startDocument", NULL);
886 if (PyErr_Occurred())
887 PyErr_Print();
888 Py_XDECREF(result);
889 }
890 }
891
892 static void
pythonEndDocument(void * user_data)893 pythonEndDocument(void *user_data)
894 {
895 PyObject *handler;
896 PyObject *result;
897
898 handler = (PyObject *) user_data;
899 if (PyObject_HasAttrString(handler, (char *) "endDocument")) {
900 result =
901 PyObject_CallMethod(handler, (char *) "endDocument", NULL);
902 if (PyErr_Occurred())
903 PyErr_Print();
904 Py_XDECREF(result);
905 }
906 /*
907 * The reference to the handler is released there
908 */
909 Py_XDECREF(handler);
910 }
911
912 static void
pythonEndElement(void * user_data,const xmlChar * name)913 pythonEndElement(void *user_data, const xmlChar * name)
914 {
915 PyObject *handler;
916 PyObject *result;
917
918 handler = (PyObject *) user_data;
919 if (PyObject_HasAttrString(handler, (char *) "endElement")) {
920 result = PyObject_CallMethod(handler, (char *) "endElement",
921 (char *) "s", name);
922 if (PyErr_Occurred())
923 PyErr_Print();
924 Py_XDECREF(result);
925 } else if (PyObject_HasAttrString(handler, (char *) "end")) {
926 result = PyObject_CallMethod(handler, (char *) "end",
927 (char *) "s", name);
928 if (PyErr_Occurred())
929 PyErr_Print();
930 Py_XDECREF(result);
931 }
932 }
933
934 static void
pythonReference(void * user_data,const xmlChar * name)935 pythonReference(void *user_data, const xmlChar * name)
936 {
937 PyObject *handler;
938 PyObject *result;
939
940 handler = (PyObject *) user_data;
941 if (PyObject_HasAttrString(handler, (char *) "reference")) {
942 result = PyObject_CallMethod(handler, (char *) "reference",
943 (char *) "s", name);
944 if (PyErr_Occurred())
945 PyErr_Print();
946 Py_XDECREF(result);
947 }
948 }
949
950 static void
pythonCharacters(void * user_data,const xmlChar * ch,int len)951 pythonCharacters(void *user_data, const xmlChar * ch, int len)
952 {
953 PyObject *handler;
954 PyObject *result = NULL;
955 int type = 0;
956
957 handler = (PyObject *) user_data;
958 if (PyObject_HasAttrString(handler, (char *) "characters"))
959 type = 1;
960 else if (PyObject_HasAttrString(handler, (char *) "data"))
961 type = 2;
962 if (type != 0) {
963 if (type == 1)
964 result = PyObject_CallMethod(handler, (char *) "characters",
965 (char *) "s#", ch, (Py_ssize_t)len);
966 else if (type == 2)
967 result = PyObject_CallMethod(handler, (char *) "data",
968 (char *) "s#", ch, (Py_ssize_t)len);
969 if (PyErr_Occurred())
970 PyErr_Print();
971 Py_XDECREF(result);
972 }
973 }
974
975 static void
pythonIgnorableWhitespace(void * user_data,const xmlChar * ch,int len)976 pythonIgnorableWhitespace(void *user_data, const xmlChar * ch, int len)
977 {
978 PyObject *handler;
979 PyObject *result = NULL;
980 int type = 0;
981
982 handler = (PyObject *) user_data;
983 if (PyObject_HasAttrString(handler, (char *) "ignorableWhitespace"))
984 type = 1;
985 else if (PyObject_HasAttrString(handler, (char *) "data"))
986 type = 2;
987 if (type != 0) {
988 if (type == 1)
989 result =
990 PyObject_CallMethod(handler,
991 (char *) "ignorableWhitespace",
992 (char *) "s#", ch, (Py_ssize_t)len);
993 else if (type == 2)
994 result =
995 PyObject_CallMethod(handler, (char *) "data",
996 (char *) "s#", ch, (Py_ssize_t)len);
997 Py_XDECREF(result);
998 }
999 }
1000
1001 static void
pythonProcessingInstruction(void * user_data,const xmlChar * target,const xmlChar * data)1002 pythonProcessingInstruction(void *user_data,
1003 const xmlChar * target, const xmlChar * data)
1004 {
1005 PyObject *handler;
1006 PyObject *result;
1007
1008 handler = (PyObject *) user_data;
1009 if (PyObject_HasAttrString(handler, (char *) "processingInstruction")) {
1010 result = PyObject_CallMethod(handler, (char *)
1011 "processingInstruction",
1012 (char *) "ss", target, data);
1013 Py_XDECREF(result);
1014 }
1015 }
1016
1017 static void
pythonComment(void * user_data,const xmlChar * value)1018 pythonComment(void *user_data, const xmlChar * value)
1019 {
1020 PyObject *handler;
1021 PyObject *result;
1022
1023 handler = (PyObject *) user_data;
1024 if (PyObject_HasAttrString(handler, (char *) "comment")) {
1025 result =
1026 PyObject_CallMethod(handler, (char *) "comment", (char *) "s",
1027 value);
1028 if (PyErr_Occurred())
1029 PyErr_Print();
1030 Py_XDECREF(result);
1031 }
1032 }
1033
1034 static void
pythonWarning(void * user_data,const char * msg,...)1035 pythonWarning(void *user_data, const char *msg, ...)
1036 {
1037 PyObject *handler;
1038 PyObject *result;
1039 va_list args;
1040 char buf[1024];
1041
1042 handler = (PyObject *) user_data;
1043 if (PyObject_HasAttrString(handler, (char *) "warning")) {
1044 va_start(args, msg);
1045 vsnprintf(buf, 1023, msg, args);
1046 va_end(args);
1047 buf[1023] = 0;
1048 result =
1049 PyObject_CallMethod(handler, (char *) "warning", (char *) "s",
1050 buf);
1051 if (PyErr_Occurred())
1052 PyErr_Print();
1053 Py_XDECREF(result);
1054 }
1055 }
1056
1057 static void
pythonError(void * user_data,const char * msg,...)1058 pythonError(void *user_data, const char *msg, ...)
1059 {
1060 PyObject *handler;
1061 PyObject *result;
1062 va_list args;
1063 char buf[1024];
1064
1065 handler = (PyObject *) user_data;
1066 if (PyObject_HasAttrString(handler, (char *) "error")) {
1067 va_start(args, msg);
1068 vsnprintf(buf, 1023, msg, args);
1069 va_end(args);
1070 buf[1023] = 0;
1071 result =
1072 PyObject_CallMethod(handler, (char *) "error", (char *) "s",
1073 buf);
1074 if (PyErr_Occurred())
1075 PyErr_Print();
1076 Py_XDECREF(result);
1077 }
1078 }
1079
1080 static void
pythonFatalError(void * user_data,const char * msg,...)1081 pythonFatalError(void *user_data, const char *msg, ...)
1082 {
1083 PyObject *handler;
1084 PyObject *result;
1085 va_list args;
1086 char buf[1024];
1087
1088 handler = (PyObject *) user_data;
1089 if (PyObject_HasAttrString(handler, (char *) "fatalError")) {
1090 va_start(args, msg);
1091 vsnprintf(buf, 1023, msg, args);
1092 va_end(args);
1093 buf[1023] = 0;
1094 result =
1095 PyObject_CallMethod(handler, (char *) "fatalError",
1096 (char *) "s", buf);
1097 if (PyErr_Occurred())
1098 PyErr_Print();
1099 Py_XDECREF(result);
1100 }
1101 }
1102
1103 static void
pythonCdataBlock(void * user_data,const xmlChar * ch,int len)1104 pythonCdataBlock(void *user_data, const xmlChar * ch, int len)
1105 {
1106 PyObject *handler;
1107 PyObject *result = NULL;
1108 int type = 0;
1109
1110 handler = (PyObject *) user_data;
1111 if (PyObject_HasAttrString(handler, (char *) "cdataBlock"))
1112 type = 1;
1113 else if (PyObject_HasAttrString(handler, (char *) "cdata"))
1114 type = 2;
1115 if (type != 0) {
1116 if (type == 1)
1117 result =
1118 PyObject_CallMethod(handler, (char *) "cdataBlock",
1119 (char *) "s#", ch, (Py_ssize_t)len);
1120 else if (type == 2)
1121 result =
1122 PyObject_CallMethod(handler, (char *) "cdata",
1123 (char *) "s#", ch, (Py_ssize_t)len);
1124 if (PyErr_Occurred())
1125 PyErr_Print();
1126 Py_XDECREF(result);
1127 }
1128 }
1129
1130 static void
pythonExternalSubset(void * user_data,const xmlChar * name,const xmlChar * externalID,const xmlChar * systemID)1131 pythonExternalSubset(void *user_data,
1132 const xmlChar * name,
1133 const xmlChar * externalID, const xmlChar * systemID)
1134 {
1135 PyObject *handler;
1136 PyObject *result;
1137
1138 handler = (PyObject *) user_data;
1139 if (PyObject_HasAttrString(handler, (char *) "externalSubset")) {
1140 result =
1141 PyObject_CallMethod(handler, (char *) "externalSubset",
1142 (char *) "sss", name, externalID,
1143 systemID);
1144 Py_XDECREF(result);
1145 }
1146 }
1147
1148 static void
pythonEntityDecl(void * user_data,const xmlChar * name,int type,const xmlChar * publicId,const xmlChar * systemId,xmlChar * content)1149 pythonEntityDecl(void *user_data,
1150 const xmlChar * name,
1151 int type,
1152 const xmlChar * publicId,
1153 const xmlChar * systemId, xmlChar * content)
1154 {
1155 PyObject *handler;
1156 PyObject *result;
1157
1158 handler = (PyObject *) user_data;
1159 if (PyObject_HasAttrString(handler, (char *) "entityDecl")) {
1160 result = PyObject_CallMethod(handler, (char *) "entityDecl",
1161 (char *) "sisss", name, type,
1162 publicId, systemId, content);
1163 if (PyErr_Occurred())
1164 PyErr_Print();
1165 Py_XDECREF(result);
1166 }
1167 }
1168
1169
1170
1171 static void
1172
pythonNotationDecl(void * user_data,const xmlChar * name,const xmlChar * publicId,const xmlChar * systemId)1173 pythonNotationDecl(void *user_data,
1174 const xmlChar * name,
1175 const xmlChar * publicId, const xmlChar * systemId)
1176 {
1177 PyObject *handler;
1178 PyObject *result;
1179
1180 handler = (PyObject *) user_data;
1181 if (PyObject_HasAttrString(handler, (char *) "notationDecl")) {
1182 result = PyObject_CallMethod(handler, (char *) "notationDecl",
1183 (char *) "sss", name, publicId,
1184 systemId);
1185 if (PyErr_Occurred())
1186 PyErr_Print();
1187 Py_XDECREF(result);
1188 }
1189 }
1190
1191 static void
pythonAttributeDecl(void * user_data,const xmlChar * elem,const xmlChar * name,int type,int def,const xmlChar * defaultValue,xmlEnumerationPtr tree)1192 pythonAttributeDecl(void *user_data,
1193 const xmlChar * elem,
1194 const xmlChar * name,
1195 int type,
1196 int def,
1197 const xmlChar * defaultValue, xmlEnumerationPtr tree)
1198 {
1199 PyObject *handler;
1200 PyObject *nameList;
1201 PyObject *newName;
1202 xmlEnumerationPtr node;
1203 PyObject *result;
1204 int count;
1205
1206 handler = (PyObject *) user_data;
1207 if (PyObject_HasAttrString(handler, (char *) "attributeDecl")) {
1208 count = 0;
1209 for (node = tree; node != NULL; node = node->next) {
1210 count++;
1211 }
1212 nameList = PyList_New(count);
1213 count = 0;
1214 for (node = tree; node != NULL; node = node->next) {
1215 newName = PY_IMPORT_STRING((char *) node->name);
1216 PyList_SetItem(nameList, count, newName);
1217 Py_DECREF(newName);
1218 count++;
1219 }
1220 result = PyObject_CallMethod(handler, (char *) "attributeDecl",
1221 (char *) "ssiisO", elem, name, type,
1222 def, defaultValue, nameList);
1223 if (PyErr_Occurred())
1224 PyErr_Print();
1225 Py_XDECREF(nameList);
1226 Py_XDECREF(result);
1227 }
1228 }
1229
1230 static void
pythonElementDecl(void * user_data,const xmlChar * name,int type,ATTRIBUTE_UNUSED xmlElementContentPtr content)1231 pythonElementDecl(void *user_data,
1232 const xmlChar * name,
1233 int type, ATTRIBUTE_UNUSED xmlElementContentPtr content)
1234 {
1235 PyObject *handler;
1236 PyObject *obj;
1237 PyObject *result;
1238
1239 handler = (PyObject *) user_data;
1240 if (PyObject_HasAttrString(handler, (char *) "elementDecl")) {
1241 /* TODO: wrap in an elementContent object */
1242 printf
1243 ("pythonElementDecl: xmlElementContentPtr wrapper missing !\n");
1244 obj = Py_None;
1245 /* Py_XINCREF(Py_None); isn't the reference just borrowed ??? */
1246 result = PyObject_CallMethod(handler, (char *) "elementDecl",
1247 (char *) "siO", name, type, obj);
1248 if (PyErr_Occurred())
1249 PyErr_Print();
1250 Py_XDECREF(result);
1251 }
1252 }
1253
1254 static void
pythonUnparsedEntityDecl(void * user_data,const xmlChar * name,const xmlChar * publicId,const xmlChar * systemId,const xmlChar * notationName)1255 pythonUnparsedEntityDecl(void *user_data,
1256 const xmlChar * name,
1257 const xmlChar * publicId,
1258 const xmlChar * systemId,
1259 const xmlChar * notationName)
1260 {
1261 PyObject *handler;
1262 PyObject *result;
1263
1264 handler = (PyObject *) user_data;
1265 if (PyObject_HasAttrString(handler, (char *) "unparsedEntityDecl")) {
1266 result =
1267 PyObject_CallMethod(handler, (char *) "unparsedEntityDecl",
1268 (char *) "ssss", name, publicId, systemId,
1269 notationName);
1270 if (PyErr_Occurred())
1271 PyErr_Print();
1272 Py_XDECREF(result);
1273 }
1274 }
1275
1276 static void
pythonInternalSubset(void * user_data,const xmlChar * name,const xmlChar * ExternalID,const xmlChar * SystemID)1277 pythonInternalSubset(void *user_data, const xmlChar * name,
1278 const xmlChar * ExternalID, const xmlChar * SystemID)
1279 {
1280 PyObject *handler;
1281 PyObject *result;
1282
1283 handler = (PyObject *) user_data;
1284 if (PyObject_HasAttrString(handler, (char *) "internalSubset")) {
1285 result = PyObject_CallMethod(handler, (char *) "internalSubset",
1286 (char *) "sss", name, ExternalID,
1287 SystemID);
1288 if (PyErr_Occurred())
1289 PyErr_Print();
1290 Py_XDECREF(result);
1291 }
1292 }
1293
1294 static xmlSAXHandler pythonSaxHandler = {
1295 pythonInternalSubset,
1296 NULL, /* TODO pythonIsStandalone, */
1297 NULL, /* TODO pythonHasInternalSubset, */
1298 NULL, /* TODO pythonHasExternalSubset, */
1299 NULL, /* TODO pythonResolveEntity, */
1300 NULL, /* TODO pythonGetEntity, */
1301 pythonEntityDecl,
1302 pythonNotationDecl,
1303 pythonAttributeDecl,
1304 pythonElementDecl,
1305 pythonUnparsedEntityDecl,
1306 NULL, /* OBSOLETED pythonSetDocumentLocator, */
1307 pythonStartDocument,
1308 pythonEndDocument,
1309 pythonStartElement,
1310 pythonEndElement,
1311 pythonReference,
1312 pythonCharacters,
1313 pythonIgnorableWhitespace,
1314 pythonProcessingInstruction,
1315 pythonComment,
1316 pythonWarning,
1317 pythonError,
1318 pythonFatalError,
1319 NULL, /* TODO pythonGetParameterEntity, */
1320 pythonCdataBlock,
1321 pythonExternalSubset,
1322 1,
1323 NULL, /* TODO migrate to SAX2 */
1324 NULL,
1325 NULL,
1326 NULL
1327 };
1328
1329 /************************************************************************
1330 * *
1331 * Handling of specific parser context *
1332 * *
1333 ************************************************************************/
1334
1335 #ifdef LIBXML_PUSH_ENABLED
1336 PyObject *
libxml_xmlCreatePushParser(ATTRIBUTE_UNUSED PyObject * self,PyObject * args)1337 libxml_xmlCreatePushParser(ATTRIBUTE_UNUSED PyObject * self,
1338 PyObject * args)
1339 {
1340 const char *chunk;
1341 int size;
1342 const char *URI;
1343 PyObject *pyobj_SAX = NULL;
1344 xmlSAXHandlerPtr SAX = NULL;
1345 xmlParserCtxtPtr ret;
1346 PyObject *pyret;
1347
1348 if (!PyArg_ParseTuple
1349 (args, (char *) "Oziz:xmlCreatePushParser", &pyobj_SAX, &chunk,
1350 &size, &URI))
1351 return (NULL);
1352
1353 if (pyobj_SAX != Py_None) {
1354 SAX = &pythonSaxHandler;
1355 Py_INCREF(pyobj_SAX);
1356 /* The reference is released in pythonEndDocument() */
1357 }
1358 ret = xmlCreatePushParserCtxt(SAX, pyobj_SAX, chunk, size, URI);
1359 pyret = libxml_xmlParserCtxtPtrWrap(ret);
1360 return (pyret);
1361 }
1362
1363 #ifdef LIBXML_HTML_ENABLED
1364 PyObject *
libxml_htmlCreatePushParser(ATTRIBUTE_UNUSED PyObject * self,PyObject * args)1365 libxml_htmlCreatePushParser(ATTRIBUTE_UNUSED PyObject * self,
1366 PyObject * args)
1367 {
1368 const char *chunk;
1369 int size;
1370 const char *URI;
1371 PyObject *pyobj_SAX = NULL;
1372 xmlSAXHandlerPtr SAX = NULL;
1373 xmlParserCtxtPtr ret;
1374 PyObject *pyret;
1375
1376 if (!PyArg_ParseTuple
1377 (args, (char *) "Oziz:htmlCreatePushParser", &pyobj_SAX, &chunk,
1378 &size, &URI))
1379 return (NULL);
1380
1381 if (pyobj_SAX != Py_None) {
1382 SAX = &pythonSaxHandler;
1383 Py_INCREF(pyobj_SAX);
1384 /* The reference is released in pythonEndDocument() */
1385 }
1386 ret = htmlCreatePushParserCtxt(SAX, pyobj_SAX, chunk, size, URI,
1387 XML_CHAR_ENCODING_NONE);
1388 pyret = libxml_xmlParserCtxtPtrWrap(ret);
1389 return (pyret);
1390 }
1391 #endif /* LIBXML_HTML_ENABLED */
1392 #endif /* LIBXML_PUSH_ENABLED */
1393
1394 #ifdef LIBXML_SAX1_ENABLED
1395 PyObject *
libxml_xmlSAXParseFile(ATTRIBUTE_UNUSED PyObject * self,PyObject * args)1396 libxml_xmlSAXParseFile(ATTRIBUTE_UNUSED PyObject * self, PyObject * args)
1397 {
1398 int recover;
1399 const char *URI;
1400 PyObject *pyobj_SAX = NULL;
1401 xmlSAXHandlerPtr SAX = NULL;
1402 xmlParserCtxtPtr ctxt;
1403
1404 if (!PyArg_ParseTuple(args, (char *) "Osi:xmlSAXParseFile", &pyobj_SAX,
1405 &URI, &recover))
1406 return (NULL);
1407
1408 if (pyobj_SAX == Py_None) {
1409 Py_INCREF(Py_None);
1410 return (Py_None);
1411 }
1412 SAX = &pythonSaxHandler;
1413 Py_INCREF(pyobj_SAX);
1414 /* The reference is released in pythonEndDocument() */
1415 ctxt = xmlNewSAXParserCtxt(SAX, pyobj_SAX);
1416 xmlCtxtReadFile(ctxt, URI, NULL, 0);
1417 xmlFreeParserCtxt(ctxt);
1418 Py_INCREF(Py_None);
1419 return (Py_None);
1420 }
1421 #endif /* LIBXML_SAX1_ENABLED */
1422
1423 #ifdef LIBXML_HTML_ENABLED
1424 PyObject *
libxml_htmlSAXParseFile(ATTRIBUTE_UNUSED PyObject * self,PyObject * args)1425 libxml_htmlSAXParseFile(ATTRIBUTE_UNUSED PyObject * self, PyObject * args)
1426 {
1427 const char *URI;
1428 const char *encoding;
1429 PyObject *pyobj_SAX = NULL;
1430 xmlSAXHandlerPtr SAX = NULL;
1431 htmlParserCtxtPtr ctxt;
1432
1433 if (!PyArg_ParseTuple
1434 (args, (char *) "Osz:htmlSAXParseFile", &pyobj_SAX, &URI,
1435 &encoding))
1436 return (NULL);
1437
1438 if (pyobj_SAX == Py_None) {
1439 Py_INCREF(Py_None);
1440 return (Py_None);
1441 }
1442 SAX = &pythonSaxHandler;
1443 Py_INCREF(pyobj_SAX);
1444 /* The reference is released in pythonEndDocument() */
1445 ctxt = htmlNewSAXParserCtxt(SAX, pyobj_SAX);
1446 htmlCtxtReadFile(ctxt, URI, encoding, 0);
1447 htmlFreeParserCtxt(ctxt);
1448 Py_INCREF(Py_None);
1449 return (Py_None);
1450 }
1451 #endif /* LIBXML_HTML_ENABLED */
1452
1453 /************************************************************************
1454 * *
1455 * Error message callback *
1456 * *
1457 ************************************************************************/
1458
1459 static PyObject *libxml_xmlPythonErrorFuncHandler = NULL;
1460 static PyObject *libxml_xmlPythonErrorFuncCtxt = NULL;
1461
1462 /* helper to build a xmlMalloc'ed string from a format and va_list */
1463 /*
1464 * disabled the loop, the repeated call to vsnprintf without reset of ap
1465 * in case the initial buffer was too small segfaulted on x86_64
1466 * we now directly vsnprintf on a large buffer.
1467 */
1468 static char *
libxml_buildMessage(const char * msg,va_list ap)1469 libxml_buildMessage(const char *msg, va_list ap)
1470 {
1471 int chars;
1472 char *str;
1473
1474 str = (char *) xmlMalloc(1000);
1475 if (str == NULL)
1476 return NULL;
1477
1478 chars = vsnprintf(str, 999, msg, ap);
1479 if (chars >= 998)
1480 str[999] = 0;
1481
1482 return str;
1483 }
1484
1485 static void
libxml_xmlErrorFuncHandler(ATTRIBUTE_UNUSED void * ctx,const char * msg,...)1486 libxml_xmlErrorFuncHandler(ATTRIBUTE_UNUSED void *ctx, const char *msg,
1487 ...)
1488 {
1489 va_list ap;
1490 PyObject *list;
1491 PyObject *message;
1492 PyObject *result;
1493 char str[1000];
1494
1495 if (libxml_xmlPythonErrorFuncHandler == NULL) {
1496 va_start(ap, msg);
1497 vfprintf(stderr, msg, ap);
1498 va_end(ap);
1499 } else {
1500 va_start(ap, msg);
1501 if (vsnprintf(str, 999, msg, ap) >= 998)
1502 str[999] = 0;
1503 va_end(ap);
1504
1505 list = PyTuple_New(2);
1506 PyTuple_SetItem(list, 0, libxml_xmlPythonErrorFuncCtxt);
1507 Py_XINCREF(libxml_xmlPythonErrorFuncCtxt);
1508 message = libxml_charPtrConstWrap(str);
1509 PyTuple_SetItem(list, 1, message);
1510 result = PyObject_CallObject(libxml_xmlPythonErrorFuncHandler, list);
1511 Py_XDECREF(list);
1512 Py_XDECREF(result);
1513 }
1514 }
1515
1516 static void
libxml_xmlErrorInitialize(void)1517 libxml_xmlErrorInitialize(void)
1518 {
1519 xmlSetGenericErrorFunc(NULL, libxml_xmlErrorFuncHandler);
1520 XML_IGNORE_DEPRECATION_WARNINGS
1521 xmlThrDefSetGenericErrorFunc(NULL, libxml_xmlErrorFuncHandler);
1522 XML_POP_WARNINGS
1523 }
1524
1525 static PyObject *
libxml_xmlRegisterErrorHandler(ATTRIBUTE_UNUSED PyObject * self,PyObject * args)1526 libxml_xmlRegisterErrorHandler(ATTRIBUTE_UNUSED PyObject * self,
1527 PyObject * args)
1528 {
1529 PyObject *py_retval;
1530 PyObject *pyobj_f;
1531 PyObject *pyobj_ctx;
1532
1533 if (!PyArg_ParseTuple
1534 (args, (char *) "OO:xmlRegisterErrorHandler", &pyobj_f,
1535 &pyobj_ctx))
1536 return (NULL);
1537
1538 if (libxml_xmlPythonErrorFuncHandler != NULL) {
1539 Py_XDECREF(libxml_xmlPythonErrorFuncHandler);
1540 }
1541 if (libxml_xmlPythonErrorFuncCtxt != NULL) {
1542 Py_XDECREF(libxml_xmlPythonErrorFuncCtxt);
1543 }
1544
1545 Py_XINCREF(pyobj_ctx);
1546 Py_XINCREF(pyobj_f);
1547
1548 /* TODO: check f is a function ! */
1549 libxml_xmlPythonErrorFuncHandler = pyobj_f;
1550 libxml_xmlPythonErrorFuncCtxt = pyobj_ctx;
1551
1552 py_retval = libxml_intWrap(1);
1553 return (py_retval);
1554 }
1555
1556
1557 /************************************************************************
1558 * *
1559 * Per parserCtxt error handler *
1560 * *
1561 ************************************************************************/
1562
1563 typedef struct
1564 {
1565 PyObject *f;
1566 PyObject *arg;
1567 } xmlParserCtxtPyCtxt;
1568 typedef xmlParserCtxtPyCtxt *xmlParserCtxtPyCtxtPtr;
1569
1570 static void
libxml_xmlParserCtxtErrorHandler(void * ctx,const xmlError * error)1571 libxml_xmlParserCtxtErrorHandler(void *ctx, const xmlError *error)
1572 {
1573 PyObject *list;
1574 PyObject *result;
1575 xmlParserCtxtPtr ctxt;
1576 xmlParserCtxtPyCtxtPtr pyCtxt;
1577 int severity;
1578
1579 ctxt = (xmlParserCtxtPtr)ctx;
1580 pyCtxt = (xmlParserCtxtPyCtxtPtr)ctxt->_private;
1581
1582 if ((error->domain == XML_FROM_VALID) ||
1583 (error->domain == XML_FROM_DTD)) {
1584 if (error->level == XML_ERR_WARNING)
1585 severity = XML_PARSER_SEVERITY_VALIDITY_WARNING;
1586 else
1587 severity = XML_PARSER_SEVERITY_VALIDITY_ERROR;
1588 } else {
1589 if (error->level == XML_ERR_WARNING)
1590 severity = XML_PARSER_SEVERITY_WARNING;
1591 else
1592 severity = XML_PARSER_SEVERITY_ERROR;
1593 }
1594
1595 list = PyTuple_New(4);
1596 PyTuple_SetItem(list, 0, pyCtxt->arg);
1597 Py_XINCREF(pyCtxt->arg);
1598 PyTuple_SetItem(list, 1, libxml_constcharPtrWrap(error->message));
1599 PyTuple_SetItem(list, 2, libxml_intWrap(severity));
1600 PyTuple_SetItem(list, 3, Py_None);
1601 Py_INCREF(Py_None);
1602 result = PyObject_CallObject(pyCtxt->f, list);
1603 if (result == NULL)
1604 {
1605 /* TODO: manage for the exception to be propagated... */
1606 PyErr_Print();
1607 }
1608 Py_XDECREF(list);
1609 Py_XDECREF(result);
1610 }
1611
1612 static PyObject *
libxml_xmlParserCtxtSetErrorHandler(ATTRIBUTE_UNUSED PyObject * self,PyObject * args)1613 libxml_xmlParserCtxtSetErrorHandler(ATTRIBUTE_UNUSED PyObject *self, PyObject *args)
1614 {
1615 PyObject *py_retval;
1616 xmlParserCtxtPtr ctxt;
1617 xmlParserCtxtPyCtxtPtr pyCtxt;
1618 PyObject *pyobj_ctxt;
1619 PyObject *pyobj_f;
1620 PyObject *pyobj_arg;
1621
1622 if (!PyArg_ParseTuple(args, (char *)"OOO:xmlParserCtxtSetErrorHandler",
1623 &pyobj_ctxt, &pyobj_f, &pyobj_arg))
1624 return(NULL);
1625 ctxt = (xmlParserCtxtPtr) PyparserCtxt_Get(pyobj_ctxt);
1626 if (ctxt->_private == NULL) {
1627 pyCtxt = xmlMalloc(sizeof(xmlParserCtxtPyCtxt));
1628 if (pyCtxt == NULL) {
1629 py_retval = libxml_intWrap(-1);
1630 return(py_retval);
1631 }
1632 memset(pyCtxt,0,sizeof(xmlParserCtxtPyCtxt));
1633 ctxt->_private = pyCtxt;
1634 }
1635 else {
1636 pyCtxt = (xmlParserCtxtPyCtxtPtr)ctxt->_private;
1637 }
1638 /* TODO: check f is a function ! */
1639 Py_XDECREF(pyCtxt->f);
1640 Py_XINCREF(pyobj_f);
1641 pyCtxt->f = pyobj_f;
1642 Py_XDECREF(pyCtxt->arg);
1643 Py_XINCREF(pyobj_arg);
1644 pyCtxt->arg = pyobj_arg;
1645
1646 if (pyobj_f != Py_None) {
1647 xmlCtxtSetErrorHandler(ctxt, libxml_xmlParserCtxtErrorHandler, ctxt);
1648 }
1649 else {
1650 xmlCtxtSetErrorHandler(ctxt, NULL, NULL);
1651 }
1652
1653 py_retval = libxml_intWrap(1);
1654 return(py_retval);
1655 }
1656
1657 static PyObject *
libxml_xmlParserCtxtGetErrorHandler(ATTRIBUTE_UNUSED PyObject * self,PyObject * args)1658 libxml_xmlParserCtxtGetErrorHandler(ATTRIBUTE_UNUSED PyObject *self, PyObject *args)
1659 {
1660 PyObject *py_retval;
1661 xmlParserCtxtPtr ctxt;
1662 xmlParserCtxtPyCtxtPtr pyCtxt;
1663 PyObject *pyobj_ctxt;
1664
1665 if (!PyArg_ParseTuple(args, (char *)"O:xmlParserCtxtGetErrorHandler",
1666 &pyobj_ctxt))
1667 return(NULL);
1668 ctxt = (xmlParserCtxtPtr) PyparserCtxt_Get(pyobj_ctxt);
1669 py_retval = PyTuple_New(2);
1670 if (ctxt->_private != NULL) {
1671 pyCtxt = (xmlParserCtxtPyCtxtPtr)ctxt->_private;
1672
1673 PyTuple_SetItem(py_retval, 0, pyCtxt->f);
1674 Py_XINCREF(pyCtxt->f);
1675 PyTuple_SetItem(py_retval, 1, pyCtxt->arg);
1676 Py_XINCREF(pyCtxt->arg);
1677 }
1678 else {
1679 /* no python error handler registered */
1680 PyTuple_SetItem(py_retval, 0, Py_None);
1681 Py_XINCREF(Py_None);
1682 PyTuple_SetItem(py_retval, 1, Py_None);
1683 Py_XINCREF(Py_None);
1684 }
1685 return(py_retval);
1686 }
1687
1688 static PyObject *
libxml_xmlFreeParserCtxt(ATTRIBUTE_UNUSED PyObject * self,PyObject * args)1689 libxml_xmlFreeParserCtxt(ATTRIBUTE_UNUSED PyObject *self, PyObject *args) {
1690 xmlParserCtxtPtr ctxt;
1691 PyObject *pyobj_ctxt;
1692 xmlParserCtxtPyCtxtPtr pyCtxt;
1693
1694 if (!PyArg_ParseTuple(args, (char *)"O:xmlFreeParserCtxt", &pyobj_ctxt))
1695 return(NULL);
1696 ctxt = (xmlParserCtxtPtr) PyparserCtxt_Get(pyobj_ctxt);
1697
1698 if (ctxt != NULL) {
1699 pyCtxt = (xmlParserCtxtPyCtxtPtr)((xmlParserCtxtPtr)ctxt)->_private;
1700 if (pyCtxt) {
1701 Py_XDECREF(pyCtxt->f);
1702 Py_XDECREF(pyCtxt->arg);
1703 xmlFree(pyCtxt);
1704 }
1705 xmlFreeParserCtxt(ctxt);
1706 }
1707
1708 Py_INCREF(Py_None);
1709 return(Py_None);
1710 }
1711
1712 #ifdef LIBXML_VALID_ENABLED
1713 /***
1714 * xmlValidCtxt stuff
1715 */
1716
1717 typedef struct
1718 {
1719 PyObject *warn;
1720 PyObject *error;
1721 PyObject *arg;
1722 } xmlValidCtxtPyCtxt;
1723 typedef xmlValidCtxtPyCtxt *xmlValidCtxtPyCtxtPtr;
1724
1725 static void
libxml_xmlValidCtxtGenericErrorFuncHandler(void * ctx,ATTRIBUTE_UNUSED int severity,char * str)1726 libxml_xmlValidCtxtGenericErrorFuncHandler(void *ctx, ATTRIBUTE_UNUSED int severity, char *str)
1727 {
1728 PyObject *list;
1729 PyObject *result;
1730 xmlValidCtxtPyCtxtPtr pyCtxt;
1731
1732 pyCtxt = (xmlValidCtxtPyCtxtPtr)ctx;
1733
1734 list = PyTuple_New(2);
1735 PyTuple_SetItem(list, 0, libxml_charPtrWrap(str));
1736 PyTuple_SetItem(list, 1, pyCtxt->arg);
1737 Py_XINCREF(pyCtxt->arg);
1738 result = PyObject_CallObject(pyCtxt->error, list);
1739 if (result == NULL)
1740 {
1741 /* TODO: manage for the exception to be propagated... */
1742 PyErr_Print();
1743 }
1744 Py_XDECREF(list);
1745 Py_XDECREF(result);
1746 }
1747
1748 static void
libxml_xmlValidCtxtGenericWarningFuncHandler(void * ctx,ATTRIBUTE_UNUSED int severity,char * str)1749 libxml_xmlValidCtxtGenericWarningFuncHandler(void *ctx, ATTRIBUTE_UNUSED int severity, char *str)
1750 {
1751 PyObject *list;
1752 PyObject *result;
1753 xmlValidCtxtPyCtxtPtr pyCtxt;
1754
1755 pyCtxt = (xmlValidCtxtPyCtxtPtr)ctx;
1756
1757 list = PyTuple_New(2);
1758 PyTuple_SetItem(list, 0, libxml_charPtrWrap(str));
1759 PyTuple_SetItem(list, 1, pyCtxt->arg);
1760 Py_XINCREF(pyCtxt->arg);
1761 result = PyObject_CallObject(pyCtxt->warn, list);
1762 if (result == NULL)
1763 {
1764 /* TODO: manage for the exception to be propagated... */
1765 PyErr_Print();
1766 }
1767 Py_XDECREF(list);
1768 Py_XDECREF(result);
1769 }
1770
1771 static void
libxml_xmlValidCtxtErrorFuncHandler(void * ctx,const char * msg,...)1772 libxml_xmlValidCtxtErrorFuncHandler(void *ctx, const char *msg, ...)
1773 {
1774 va_list ap;
1775
1776 va_start(ap, msg);
1777 libxml_xmlValidCtxtGenericErrorFuncHandler(ctx,XML_PARSER_SEVERITY_VALIDITY_ERROR,libxml_buildMessage(msg,ap));
1778 va_end(ap);
1779 }
1780
1781 static void
libxml_xmlValidCtxtWarningFuncHandler(void * ctx,const char * msg,...)1782 libxml_xmlValidCtxtWarningFuncHandler(void *ctx, const char *msg, ...)
1783 {
1784 va_list ap;
1785
1786 va_start(ap, msg);
1787 libxml_xmlValidCtxtGenericWarningFuncHandler(ctx,XML_PARSER_SEVERITY_VALIDITY_WARNING,libxml_buildMessage(msg,ap));
1788 va_end(ap);
1789 }
1790
1791 static PyObject *
libxml_xmlSetValidErrors(ATTRIBUTE_UNUSED PyObject * self,PyObject * args)1792 libxml_xmlSetValidErrors(ATTRIBUTE_UNUSED PyObject * self, PyObject * args)
1793 {
1794 PyObject *py_retval;
1795 PyObject *pyobj_error;
1796 PyObject *pyobj_warn;
1797 PyObject *pyobj_ctx;
1798 PyObject *pyobj_arg = Py_None;
1799 xmlValidCtxtPtr ctxt;
1800 xmlValidCtxtPyCtxtPtr pyCtxt;
1801
1802 if (!PyArg_ParseTuple
1803 (args, (char *) "OOO|O:xmlSetValidErrors", &pyobj_ctx, &pyobj_error, &pyobj_warn, &pyobj_arg))
1804 return (NULL);
1805
1806 ctxt = PyValidCtxt_Get(pyobj_ctx);
1807 pyCtxt = xmlMalloc(sizeof(xmlValidCtxtPyCtxt));
1808 if (pyCtxt == NULL) {
1809 py_retval = libxml_intWrap(-1);
1810 return(py_retval);
1811 }
1812 memset(pyCtxt, 0, sizeof(xmlValidCtxtPyCtxt));
1813
1814
1815 /* TODO: check warn and error is a function ! */
1816 Py_XDECREF(pyCtxt->error);
1817 Py_XINCREF(pyobj_error);
1818 pyCtxt->error = pyobj_error;
1819
1820 Py_XDECREF(pyCtxt->warn);
1821 Py_XINCREF(pyobj_warn);
1822 pyCtxt->warn = pyobj_warn;
1823
1824 Py_XDECREF(pyCtxt->arg);
1825 Py_XINCREF(pyobj_arg);
1826 pyCtxt->arg = pyobj_arg;
1827
1828 ctxt->error = libxml_xmlValidCtxtErrorFuncHandler;
1829 ctxt->warning = libxml_xmlValidCtxtWarningFuncHandler;
1830 ctxt->userData = pyCtxt;
1831
1832 py_retval = libxml_intWrap(1);
1833 return (py_retval);
1834 }
1835
1836
1837 static PyObject *
libxml_xmlFreeValidCtxt(PyObject * self ATTRIBUTE_UNUSED,PyObject * args)1838 libxml_xmlFreeValidCtxt(PyObject *self ATTRIBUTE_UNUSED, PyObject *args) {
1839 xmlValidCtxtPtr cur;
1840 xmlValidCtxtPyCtxtPtr pyCtxt;
1841 PyObject *pyobj_cur;
1842
1843 if (!PyArg_ParseTuple(args, (char *)"O:xmlFreeValidCtxt", &pyobj_cur))
1844 return(NULL);
1845 cur = (xmlValidCtxtPtr) PyValidCtxt_Get(pyobj_cur);
1846
1847 pyCtxt = (xmlValidCtxtPyCtxtPtr)(cur->userData);
1848 if (pyCtxt != NULL)
1849 {
1850 Py_XDECREF(pyCtxt->error);
1851 Py_XDECREF(pyCtxt->warn);
1852 Py_XDECREF(pyCtxt->arg);
1853 xmlFree(pyCtxt);
1854 }
1855
1856 xmlFreeValidCtxt(cur);
1857 Py_INCREF(Py_None);
1858 return(Py_None);
1859 }
1860 #endif /* LIBXML_VALID_ENABLED */
1861
1862 #ifdef LIBXML_READER_ENABLED
1863 /************************************************************************
1864 * *
1865 * Per xmlTextReader error handler *
1866 * *
1867 ************************************************************************/
1868
1869 typedef struct
1870 {
1871 PyObject *f;
1872 PyObject *arg;
1873 } xmlTextReaderPyCtxt;
1874 typedef xmlTextReaderPyCtxt *xmlTextReaderPyCtxtPtr;
1875
1876 static void
libxml_xmlTextReaderErrorCallback(void * arg,const char * msg,xmlParserSeverities severity,xmlTextReaderLocatorPtr locator)1877 libxml_xmlTextReaderErrorCallback(void *arg,
1878 const char *msg,
1879 xmlParserSeverities severity,
1880 xmlTextReaderLocatorPtr locator)
1881 {
1882 xmlTextReaderPyCtxt *pyCtxt = (xmlTextReaderPyCtxt *)arg;
1883 PyObject *list;
1884 PyObject *result;
1885
1886 list = PyTuple_New(4);
1887 PyTuple_SetItem(list, 0, pyCtxt->arg);
1888 Py_XINCREF(pyCtxt->arg);
1889 PyTuple_SetItem(list, 1, libxml_charPtrConstWrap(msg));
1890 PyTuple_SetItem(list, 2, libxml_intWrap(severity));
1891 PyTuple_SetItem(list, 3, libxml_xmlTextReaderLocatorPtrWrap(locator));
1892 result = PyObject_CallObject(pyCtxt->f, list);
1893 if (result == NULL)
1894 {
1895 /* TODO: manage for the exception to be propagated... */
1896 PyErr_Print();
1897 }
1898 Py_XDECREF(list);
1899 Py_XDECREF(result);
1900 }
1901
1902 static PyObject *
libxml_xmlTextReaderSetErrorHandler(ATTRIBUTE_UNUSED PyObject * self,PyObject * args)1903 libxml_xmlTextReaderSetErrorHandler(ATTRIBUTE_UNUSED PyObject *self, PyObject *args)
1904 {
1905 xmlTextReaderPtr reader;
1906 xmlTextReaderPyCtxtPtr pyCtxt;
1907 xmlTextReaderErrorFunc f;
1908 void *arg;
1909 PyObject *pyobj_reader;
1910 PyObject *pyobj_f;
1911 PyObject *pyobj_arg;
1912 PyObject *py_retval;
1913
1914 if (!PyArg_ParseTuple(args, (char *)"OOO:xmlTextReaderSetErrorHandler", &pyobj_reader, &pyobj_f, &pyobj_arg))
1915 return(NULL);
1916 reader = (xmlTextReaderPtr) PyxmlTextReader_Get(pyobj_reader);
1917 /* clear previous error handler */
1918 xmlTextReaderGetErrorHandler(reader,&f,&arg);
1919 if (arg != NULL) {
1920 if (f == (xmlTextReaderErrorFunc) libxml_xmlTextReaderErrorCallback) {
1921 /* ok, it's our error handler! */
1922 pyCtxt = (xmlTextReaderPyCtxtPtr)arg;
1923 Py_XDECREF(pyCtxt->f);
1924 Py_XDECREF(pyCtxt->arg);
1925 xmlFree(pyCtxt);
1926 }
1927 else {
1928 /*
1929 * there already an arg, and it's not ours,
1930 * there is definitely something wrong going on here...
1931 * we don't know how to free it, so we bail out...
1932 */
1933 py_retval = libxml_intWrap(-1);
1934 return(py_retval);
1935 }
1936 }
1937 xmlTextReaderSetErrorHandler(reader,NULL,NULL);
1938 /* set new error handler */
1939 if (pyobj_f != Py_None)
1940 {
1941 pyCtxt = (xmlTextReaderPyCtxtPtr)xmlMalloc(sizeof(xmlTextReaderPyCtxt));
1942 if (pyCtxt == NULL) {
1943 py_retval = libxml_intWrap(-1);
1944 return(py_retval);
1945 }
1946 Py_XINCREF(pyobj_f);
1947 pyCtxt->f = pyobj_f;
1948 Py_XINCREF(pyobj_arg);
1949 pyCtxt->arg = pyobj_arg;
1950 xmlTextReaderSetErrorHandler(reader,
1951 libxml_xmlTextReaderErrorCallback,
1952 pyCtxt);
1953 }
1954
1955 py_retval = libxml_intWrap(1);
1956 return(py_retval);
1957 }
1958
1959 static PyObject *
libxml_xmlTextReaderGetErrorHandler(ATTRIBUTE_UNUSED PyObject * self,PyObject * args)1960 libxml_xmlTextReaderGetErrorHandler(ATTRIBUTE_UNUSED PyObject *self, PyObject *args)
1961 {
1962 xmlTextReaderPtr reader;
1963 xmlTextReaderPyCtxtPtr pyCtxt;
1964 xmlTextReaderErrorFunc f;
1965 void *arg;
1966 PyObject *pyobj_reader;
1967 PyObject *py_retval;
1968
1969 if (!PyArg_ParseTuple(args, (char *)"O:xmlTextReaderSetErrorHandler", &pyobj_reader))
1970 return(NULL);
1971 reader = (xmlTextReaderPtr) PyxmlTextReader_Get(pyobj_reader);
1972 xmlTextReaderGetErrorHandler(reader,&f,&arg);
1973 py_retval = PyTuple_New(2);
1974 if (f == (xmlTextReaderErrorFunc)libxml_xmlTextReaderErrorCallback) {
1975 /* ok, it's our error handler! */
1976 pyCtxt = (xmlTextReaderPyCtxtPtr)arg;
1977 PyTuple_SetItem(py_retval, 0, pyCtxt->f);
1978 Py_XINCREF(pyCtxt->f);
1979 PyTuple_SetItem(py_retval, 1, pyCtxt->arg);
1980 Py_XINCREF(pyCtxt->arg);
1981 }
1982 else
1983 {
1984 /* f is null or it's not our error handler */
1985 PyTuple_SetItem(py_retval, 0, Py_None);
1986 Py_XINCREF(Py_None);
1987 PyTuple_SetItem(py_retval, 1, Py_None);
1988 Py_XINCREF(Py_None);
1989 }
1990 return(py_retval);
1991 }
1992
1993 static PyObject *
libxml_xmlFreeTextReader(ATTRIBUTE_UNUSED PyObject * self,PyObject * args)1994 libxml_xmlFreeTextReader(ATTRIBUTE_UNUSED PyObject *self, PyObject *args) {
1995 xmlTextReaderPtr reader;
1996 PyObject *pyobj_reader;
1997 xmlTextReaderPyCtxtPtr pyCtxt;
1998 xmlTextReaderErrorFunc f;
1999 void *arg;
2000
2001 if (!PyArg_ParseTuple(args, (char *)"O:xmlFreeTextReader", &pyobj_reader))
2002 return(NULL);
2003 if (!PyCapsule_CheckExact(pyobj_reader)) {
2004 Py_INCREF(Py_None);
2005 return(Py_None);
2006 }
2007 reader = (xmlTextReaderPtr) PyxmlTextReader_Get(pyobj_reader);
2008 if (reader == NULL) {
2009 Py_INCREF(Py_None);
2010 return(Py_None);
2011 }
2012
2013 xmlTextReaderGetErrorHandler(reader,&f,&arg);
2014 if (arg != NULL) {
2015 if (f == (xmlTextReaderErrorFunc) libxml_xmlTextReaderErrorCallback) {
2016 /* ok, it's our error handler! */
2017 pyCtxt = (xmlTextReaderPyCtxtPtr)arg;
2018 Py_XDECREF(pyCtxt->f);
2019 Py_XDECREF(pyCtxt->arg);
2020 xmlFree(pyCtxt);
2021 }
2022 /*
2023 * else, something wrong happened, because the error handler is
2024 * not owned by the python bindings...
2025 */
2026 }
2027
2028 xmlFreeTextReader(reader);
2029 Py_INCREF(Py_None);
2030 return(Py_None);
2031 }
2032 #endif
2033
2034 /************************************************************************
2035 * *
2036 * XPath extensions *
2037 * *
2038 ************************************************************************/
2039
2040 #ifdef LIBXML_XPATH_ENABLED
2041 static void
libxml_xmlXPathFuncCallback(xmlXPathParserContextPtr ctxt,int nargs)2042 libxml_xmlXPathFuncCallback(xmlXPathParserContextPtr ctxt, int nargs)
2043 {
2044 PyObject *list, *cur, *result;
2045 xmlXPathObjectPtr obj;
2046 xmlXPathContextPtr rctxt;
2047 PyObject *current_function = NULL;
2048 const xmlChar *name;
2049 const xmlChar *ns_uri;
2050 int i;
2051
2052 if (ctxt == NULL)
2053 return;
2054 rctxt = ctxt->context;
2055 if (rctxt == NULL)
2056 return;
2057 name = rctxt->function;
2058 ns_uri = rctxt->functionURI;
2059
2060 /*
2061 * Find the function, it should be there it was there at lookup
2062 */
2063 for (i = 0; i < libxml_xpathCallbacksNb; i++) {
2064 if ( /* TODO (ctxt == libxml_xpathCallbacks[i].ctx) && */
2065 (xmlStrEqual(name, (*libxml_xpathCallbacks)[i].name)) &&
2066 (xmlStrEqual(ns_uri, (*libxml_xpathCallbacks)[i].ns_uri))) {
2067 current_function = (*libxml_xpathCallbacks)[i].function;
2068 }
2069 }
2070 if (current_function == NULL) {
2071 printf
2072 ("libxml_xmlXPathFuncCallback: internal error %s not found !\n",
2073 name);
2074 return;
2075 }
2076
2077 list = PyTuple_New(nargs + 1);
2078 PyTuple_SetItem(list, 0, libxml_xmlXPathParserContextPtrWrap(ctxt));
2079 for (i = nargs - 1; i >= 0; i--) {
2080 obj = valuePop(ctxt);
2081 cur = libxml_xmlXPathObjectPtrWrap(obj);
2082 PyTuple_SetItem(list, i + 1, cur);
2083 }
2084 result = PyObject_CallObject(current_function, list);
2085 Py_DECREF(list);
2086
2087 obj = libxml_xmlXPathObjectPtrConvert(result);
2088 valuePush(ctxt, obj);
2089 }
2090
2091 static xmlXPathFunction
libxml_xmlXPathFuncLookupFunc(void * ctxt,const xmlChar * name,const xmlChar * ns_uri)2092 libxml_xmlXPathFuncLookupFunc(void *ctxt, const xmlChar * name,
2093 const xmlChar * ns_uri)
2094 {
2095 int i;
2096
2097 /*
2098 * This is called once only. The address is then stored in the
2099 * XPath expression evaluation, the proper object to call can
2100 * then still be found using the execution context function
2101 * and functionURI fields.
2102 */
2103 for (i = 0; i < libxml_xpathCallbacksNb; i++) {
2104 if ((ctxt == (*libxml_xpathCallbacks)[i].ctx) &&
2105 (xmlStrEqual(name, (*libxml_xpathCallbacks)[i].name)) &&
2106 (xmlStrEqual(ns_uri, (*libxml_xpathCallbacks)[i].ns_uri))) {
2107 return (libxml_xmlXPathFuncCallback);
2108 }
2109 }
2110 return (NULL);
2111 }
2112
2113 static void
libxml_xpathCallbacksInitialize(void)2114 libxml_xpathCallbacksInitialize(void)
2115 {
2116 int i;
2117
2118 if (libxml_xpathCallbacksInitialized != 0)
2119 return;
2120
2121 libxml_xpathCallbacks = (libxml_xpathCallbackArray*)xmlMalloc(
2122 libxml_xpathCallbacksAllocd*sizeof(libxml_xpathCallback));
2123
2124 for (i = 0; i < libxml_xpathCallbacksAllocd; i++) {
2125 (*libxml_xpathCallbacks)[i].ctx = NULL;
2126 (*libxml_xpathCallbacks)[i].name = NULL;
2127 (*libxml_xpathCallbacks)[i].ns_uri = NULL;
2128 (*libxml_xpathCallbacks)[i].function = NULL;
2129 }
2130 libxml_xpathCallbacksInitialized = 1;
2131 }
2132
2133 PyObject *
libxml_xmlRegisterXPathFunction(ATTRIBUTE_UNUSED PyObject * self,PyObject * args)2134 libxml_xmlRegisterXPathFunction(ATTRIBUTE_UNUSED PyObject * self,
2135 PyObject * args)
2136 {
2137 PyObject *py_retval;
2138 int c_retval = 0;
2139 xmlChar *name;
2140 xmlChar *ns_uri;
2141 xmlXPathContextPtr ctx;
2142 PyObject *pyobj_ctx;
2143 PyObject *pyobj_f;
2144 int i;
2145
2146 if (!PyArg_ParseTuple
2147 (args, (char *) "OszO:registerXPathFunction", &pyobj_ctx, &name,
2148 &ns_uri, &pyobj_f))
2149 return (NULL);
2150
2151 ctx = (xmlXPathContextPtr) PyxmlXPathContext_Get(pyobj_ctx);
2152 if (libxml_xpathCallbacksInitialized == 0)
2153 libxml_xpathCallbacksInitialize();
2154 xmlXPathRegisterFuncLookup(ctx, libxml_xmlXPathFuncLookupFunc, ctx);
2155
2156 if ((pyobj_ctx == NULL) || (name == NULL) || (pyobj_f == NULL)) {
2157 py_retval = libxml_intWrap(-1);
2158 return (py_retval);
2159 }
2160 for (i = 0; i < libxml_xpathCallbacksNb; i++) {
2161 if ((ctx == (*libxml_xpathCallbacks)[i].ctx) &&
2162 (xmlStrEqual(name, (*libxml_xpathCallbacks)[i].name)) &&
2163 (xmlStrEqual(ns_uri, (*libxml_xpathCallbacks)[i].ns_uri))) {
2164 Py_XINCREF(pyobj_f);
2165 Py_XDECREF((*libxml_xpathCallbacks)[i].function);
2166 (*libxml_xpathCallbacks)[i].function = pyobj_f;
2167 c_retval = 1;
2168 goto done;
2169 }
2170 }
2171 if (libxml_xpathCallbacksNb >= libxml_xpathCallbacksAllocd) {
2172 libxml_xpathCallbacksAllocd+=10;
2173 libxml_xpathCallbacks = (libxml_xpathCallbackArray*)xmlRealloc(
2174 libxml_xpathCallbacks,
2175 libxml_xpathCallbacksAllocd*sizeof(libxml_xpathCallback));
2176 }
2177 i = libxml_xpathCallbacksNb++;
2178 Py_XINCREF(pyobj_f);
2179 (*libxml_xpathCallbacks)[i].ctx = ctx;
2180 (*libxml_xpathCallbacks)[i].name = xmlStrdup(name);
2181 (*libxml_xpathCallbacks)[i].ns_uri = xmlStrdup(ns_uri);
2182 (*libxml_xpathCallbacks)[i].function = pyobj_f;
2183 c_retval = 1;
2184
2185 done:
2186 py_retval = libxml_intWrap((int) c_retval);
2187 return (py_retval);
2188 }
2189
2190 PyObject *
libxml_xmlXPathRegisterVariable(ATTRIBUTE_UNUSED PyObject * self,PyObject * args)2191 libxml_xmlXPathRegisterVariable(ATTRIBUTE_UNUSED PyObject * self,
2192 PyObject * args)
2193 {
2194 PyObject *py_retval;
2195 int c_retval = 0;
2196 xmlChar *name;
2197 xmlChar *ns_uri;
2198 xmlXPathContextPtr ctx;
2199 xmlXPathObjectPtr val;
2200 PyObject *pyobj_ctx;
2201 PyObject *pyobj_value;
2202
2203 if (!PyArg_ParseTuple
2204 (args, (char *) "OszO:xpathRegisterVariable", &pyobj_ctx, &name,
2205 &ns_uri, &pyobj_value))
2206 return (NULL);
2207
2208 ctx = (xmlXPathContextPtr) PyxmlXPathContext_Get(pyobj_ctx);
2209 val = libxml_xmlXPathObjectPtrConvert(pyobj_value);
2210
2211 c_retval = xmlXPathRegisterVariableNS(ctx, name, ns_uri, val);
2212 py_retval = libxml_intWrap(c_retval);
2213 return (py_retval);
2214 }
2215 #endif /* LIBXML_XPATH_ENABLED */
2216
2217 /************************************************************************
2218 * *
2219 * Global properties access *
2220 * *
2221 ************************************************************************/
2222 static PyObject *
libxml_name(ATTRIBUTE_UNUSED PyObject * self,PyObject * args)2223 libxml_name(ATTRIBUTE_UNUSED PyObject * self, PyObject * args)
2224 {
2225 PyObject *resultobj, *obj;
2226 xmlNodePtr cur;
2227 const xmlChar *res;
2228
2229 if (!PyArg_ParseTuple(args, (char *) "O:name", &obj))
2230 return NULL;
2231 cur = PyxmlNode_Get(obj);
2232
2233 switch (cur->type) {
2234 case XML_DOCUMENT_NODE:
2235 case XML_HTML_DOCUMENT_NODE:{
2236 xmlDocPtr doc = (xmlDocPtr) cur;
2237
2238 res = doc->URL;
2239 break;
2240 }
2241 case XML_ATTRIBUTE_NODE:{
2242 xmlAttrPtr attr = (xmlAttrPtr) cur;
2243
2244 res = attr->name;
2245 break;
2246 }
2247 case XML_NAMESPACE_DECL:{
2248 xmlNsPtr ns = (xmlNsPtr) cur;
2249
2250 res = ns->prefix;
2251 break;
2252 }
2253 default:
2254 res = cur->name;
2255 break;
2256 }
2257 resultobj = libxml_constxmlCharPtrWrap(res);
2258
2259 return resultobj;
2260 }
2261
2262 static PyObject *
libxml_doc(ATTRIBUTE_UNUSED PyObject * self,PyObject * args)2263 libxml_doc(ATTRIBUTE_UNUSED PyObject * self, PyObject * args)
2264 {
2265 PyObject *resultobj, *obj;
2266 xmlNodePtr cur;
2267 xmlDocPtr res;
2268
2269 if (!PyArg_ParseTuple(args, (char *) "O:doc", &obj))
2270 return NULL;
2271 cur = PyxmlNode_Get(obj);
2272
2273 switch (cur->type) {
2274 case XML_DOCUMENT_NODE:
2275 case XML_HTML_DOCUMENT_NODE:
2276 res = NULL;
2277 break;
2278 case XML_ATTRIBUTE_NODE:{
2279 xmlAttrPtr attr = (xmlAttrPtr) cur;
2280
2281 res = attr->doc;
2282 break;
2283 }
2284 case XML_NAMESPACE_DECL:
2285 res = NULL;
2286 break;
2287 default:
2288 res = cur->doc;
2289 break;
2290 }
2291 resultobj = libxml_xmlDocPtrWrap(res);
2292 return resultobj;
2293 }
2294
2295 static PyObject *
libxml_properties(ATTRIBUTE_UNUSED PyObject * self,PyObject * args)2296 libxml_properties(ATTRIBUTE_UNUSED PyObject * self, PyObject * args)
2297 {
2298 PyObject *resultobj, *obj;
2299 xmlNodePtr cur;
2300 xmlAttrPtr res;
2301
2302 if (!PyArg_ParseTuple(args, (char *) "O:properties", &obj))
2303 return NULL;
2304 cur = PyxmlNode_Get(obj);
2305 if ((cur != NULL) && (cur->type == XML_ELEMENT_NODE))
2306 res = cur->properties;
2307 else
2308 res = NULL;
2309 resultobj = libxml_xmlAttrPtrWrap(res);
2310 return resultobj;
2311 }
2312
2313 static PyObject *
libxml_next(ATTRIBUTE_UNUSED PyObject * self,PyObject * args)2314 libxml_next(ATTRIBUTE_UNUSED PyObject * self, PyObject * args)
2315 {
2316 PyObject *resultobj, *obj;
2317 xmlNodePtr cur;
2318 xmlNodePtr res;
2319
2320 if (!PyArg_ParseTuple(args, (char *) "O:next", &obj))
2321 return NULL;
2322 cur = PyxmlNode_Get(obj);
2323
2324 switch (cur->type) {
2325 case XML_DOCUMENT_NODE:
2326 case XML_HTML_DOCUMENT_NODE:
2327 res = NULL;
2328 break;
2329 case XML_ATTRIBUTE_NODE:{
2330 xmlAttrPtr attr = (xmlAttrPtr) cur;
2331
2332 res = (xmlNodePtr) attr->next;
2333 break;
2334 }
2335 case XML_NAMESPACE_DECL:{
2336 xmlNsPtr ns = (xmlNsPtr) cur;
2337
2338 res = (xmlNodePtr) ns->next;
2339 break;
2340 }
2341 default:
2342 res = cur->next;
2343 break;
2344
2345 }
2346 resultobj = libxml_xmlNodePtrWrap(res);
2347 return resultobj;
2348 }
2349
2350 static PyObject *
libxml_prev(ATTRIBUTE_UNUSED PyObject * self,PyObject * args)2351 libxml_prev(ATTRIBUTE_UNUSED PyObject * self, PyObject * args)
2352 {
2353 PyObject *resultobj, *obj;
2354 xmlNodePtr cur;
2355 xmlNodePtr res;
2356
2357 if (!PyArg_ParseTuple(args, (char *) "O:prev", &obj))
2358 return NULL;
2359 cur = PyxmlNode_Get(obj);
2360
2361 switch (cur->type) {
2362 case XML_DOCUMENT_NODE:
2363 case XML_HTML_DOCUMENT_NODE:
2364 res = NULL;
2365 break;
2366 case XML_ATTRIBUTE_NODE:{
2367 xmlAttrPtr attr = (xmlAttrPtr) cur;
2368
2369 res = (xmlNodePtr) attr->prev;
2370 }
2371 break;
2372 case XML_NAMESPACE_DECL:
2373 res = NULL;
2374 break;
2375 default:
2376 res = cur->prev;
2377 break;
2378 }
2379 resultobj = libxml_xmlNodePtrWrap(res);
2380 return resultobj;
2381 }
2382
2383 static PyObject *
libxml_children(ATTRIBUTE_UNUSED PyObject * self,PyObject * args)2384 libxml_children(ATTRIBUTE_UNUSED PyObject * self, PyObject * args)
2385 {
2386 PyObject *resultobj, *obj;
2387 xmlNodePtr cur;
2388 xmlNodePtr res;
2389
2390 if (!PyArg_ParseTuple(args, (char *) "O:children", &obj))
2391 return NULL;
2392 cur = PyxmlNode_Get(obj);
2393
2394 switch (cur->type) {
2395 case XML_ELEMENT_NODE:
2396 case XML_ENTITY_REF_NODE:
2397 case XML_ENTITY_NODE:
2398 case XML_PI_NODE:
2399 case XML_COMMENT_NODE:
2400 case XML_DOCUMENT_NODE:
2401 case XML_HTML_DOCUMENT_NODE:
2402 case XML_DTD_NODE:
2403 res = cur->children;
2404 break;
2405 case XML_ATTRIBUTE_NODE:{
2406 xmlAttrPtr attr = (xmlAttrPtr) cur;
2407
2408 res = attr->children;
2409 break;
2410 }
2411 default:
2412 res = NULL;
2413 break;
2414 }
2415 resultobj = libxml_xmlNodePtrWrap(res);
2416 return resultobj;
2417 }
2418
2419 static PyObject *
libxml_last(ATTRIBUTE_UNUSED PyObject * self,PyObject * args)2420 libxml_last(ATTRIBUTE_UNUSED PyObject * self, PyObject * args)
2421 {
2422 PyObject *resultobj, *obj;
2423 xmlNodePtr cur;
2424 xmlNodePtr res;
2425
2426 if (!PyArg_ParseTuple(args, (char *) "O:last", &obj))
2427 return NULL;
2428 cur = PyxmlNode_Get(obj);
2429
2430 switch (cur->type) {
2431 case XML_ELEMENT_NODE:
2432 case XML_ENTITY_REF_NODE:
2433 case XML_ENTITY_NODE:
2434 case XML_PI_NODE:
2435 case XML_COMMENT_NODE:
2436 case XML_DOCUMENT_NODE:
2437 case XML_HTML_DOCUMENT_NODE:
2438 case XML_DTD_NODE:
2439 res = cur->last;
2440 break;
2441 case XML_ATTRIBUTE_NODE:{
2442 xmlAttrPtr attr = (xmlAttrPtr) cur;
2443
2444 res = attr->last;
2445 break;
2446 }
2447 default:
2448 res = NULL;
2449 break;
2450 }
2451 resultobj = libxml_xmlNodePtrWrap(res);
2452 return resultobj;
2453 }
2454
2455 static PyObject *
libxml_parent(ATTRIBUTE_UNUSED PyObject * self,PyObject * args)2456 libxml_parent(ATTRIBUTE_UNUSED PyObject * self, PyObject * args)
2457 {
2458 PyObject *resultobj, *obj;
2459 xmlNodePtr cur;
2460 xmlNodePtr res;
2461
2462 if (!PyArg_ParseTuple(args, (char *) "O:parent", &obj))
2463 return NULL;
2464 cur = PyxmlNode_Get(obj);
2465
2466 switch (cur->type) {
2467 case XML_DOCUMENT_NODE:
2468 case XML_HTML_DOCUMENT_NODE:
2469 res = NULL;
2470 break;
2471 case XML_ATTRIBUTE_NODE:{
2472 xmlAttrPtr attr = (xmlAttrPtr) cur;
2473
2474 res = attr->parent;
2475 }
2476 break;
2477 case XML_ENTITY_DECL:
2478 case XML_NAMESPACE_DECL:
2479 case XML_XINCLUDE_START:
2480 case XML_XINCLUDE_END:
2481 res = NULL;
2482 break;
2483 default:
2484 res = cur->parent;
2485 break;
2486 }
2487 resultobj = libxml_xmlNodePtrWrap(res);
2488 return resultobj;
2489 }
2490
2491 static PyObject *
libxml_type(ATTRIBUTE_UNUSED PyObject * self,PyObject * args)2492 libxml_type(ATTRIBUTE_UNUSED PyObject * self, PyObject * args)
2493 {
2494 PyObject *resultobj, *obj;
2495 xmlNodePtr cur;
2496 const xmlChar *res = NULL;
2497
2498 if (!PyArg_ParseTuple(args, (char *) "O:last", &obj))
2499 return NULL;
2500 cur = PyxmlNode_Get(obj);
2501 if (cur == NULL) {
2502 Py_INCREF(Py_None);
2503 return (Py_None);
2504 }
2505
2506 switch (cur->type) {
2507 case XML_ELEMENT_NODE:
2508 res = (const xmlChar *) "element";
2509 break;
2510 case XML_ATTRIBUTE_NODE:
2511 res = (const xmlChar *) "attribute";
2512 break;
2513 case XML_TEXT_NODE:
2514 res = (const xmlChar *) "text";
2515 break;
2516 case XML_CDATA_SECTION_NODE:
2517 res = (const xmlChar *) "cdata";
2518 break;
2519 case XML_ENTITY_REF_NODE:
2520 res = (const xmlChar *) "entity_ref";
2521 break;
2522 case XML_ENTITY_NODE:
2523 res = (const xmlChar *) "entity";
2524 break;
2525 case XML_PI_NODE:
2526 res = (const xmlChar *) "pi";
2527 break;
2528 case XML_COMMENT_NODE:
2529 res = (const xmlChar *) "comment";
2530 break;
2531 case XML_DOCUMENT_NODE:
2532 res = (const xmlChar *) "document_xml";
2533 break;
2534 case XML_DOCUMENT_TYPE_NODE:
2535 res = (const xmlChar *) "doctype";
2536 break;
2537 case XML_DOCUMENT_FRAG_NODE:
2538 res = (const xmlChar *) "fragment";
2539 break;
2540 case XML_NOTATION_NODE:
2541 res = (const xmlChar *) "notation";
2542 break;
2543 case XML_HTML_DOCUMENT_NODE:
2544 res = (const xmlChar *) "document_html";
2545 break;
2546 case XML_DTD_NODE:
2547 res = (const xmlChar *) "dtd";
2548 break;
2549 case XML_ELEMENT_DECL:
2550 res = (const xmlChar *) "elem_decl";
2551 break;
2552 case XML_ATTRIBUTE_DECL:
2553 res = (const xmlChar *) "attribute_decl";
2554 break;
2555 case XML_ENTITY_DECL:
2556 res = (const xmlChar *) "entity_decl";
2557 break;
2558 case XML_NAMESPACE_DECL:
2559 res = (const xmlChar *) "namespace";
2560 break;
2561 case XML_XINCLUDE_START:
2562 res = (const xmlChar *) "xinclude_start";
2563 break;
2564 case XML_XINCLUDE_END:
2565 res = (const xmlChar *) "xinclude_end";
2566 break;
2567 }
2568
2569 resultobj = libxml_constxmlCharPtrWrap(res);
2570 return resultobj;
2571 }
2572
2573 /************************************************************************
2574 * *
2575 * Specific accessor functions *
2576 * *
2577 ************************************************************************/
2578 PyObject *
libxml_xmlNodeGetNsDefs(ATTRIBUTE_UNUSED PyObject * self,PyObject * args)2579 libxml_xmlNodeGetNsDefs(ATTRIBUTE_UNUSED PyObject * self, PyObject * args)
2580 {
2581 PyObject *py_retval;
2582 xmlNsPtr c_retval;
2583 xmlNodePtr node;
2584 PyObject *pyobj_node;
2585
2586 if (!PyArg_ParseTuple
2587 (args, (char *) "O:xmlNodeGetNsDefs", &pyobj_node))
2588 return (NULL);
2589 node = (xmlNodePtr) PyxmlNode_Get(pyobj_node);
2590
2591 if ((node == NULL) || (node->type != XML_ELEMENT_NODE)) {
2592 Py_INCREF(Py_None);
2593 return (Py_None);
2594 }
2595 c_retval = node->nsDef;
2596 py_retval = libxml_xmlNsPtrWrap((xmlNsPtr) c_retval);
2597 return (py_retval);
2598 }
2599
2600 PyObject *
libxml_xmlNodeRemoveNsDef(ATTRIBUTE_UNUSED PyObject * self,PyObject * args)2601 libxml_xmlNodeRemoveNsDef(ATTRIBUTE_UNUSED PyObject * self, PyObject * args)
2602 {
2603 PyObject *py_retval;
2604 xmlNsPtr ns, prev;
2605 xmlNodePtr node;
2606 PyObject *pyobj_node;
2607 xmlChar *href;
2608 xmlNsPtr c_retval;
2609
2610 if (!PyArg_ParseTuple
2611 (args, (char *) "Oz:xmlNodeRemoveNsDef", &pyobj_node, &href))
2612 return (NULL);
2613 node = (xmlNodePtr) PyxmlNode_Get(pyobj_node);
2614 ns = NULL;
2615
2616 if ((node == NULL) || (node->type != XML_ELEMENT_NODE)) {
2617 Py_INCREF(Py_None);
2618 return (Py_None);
2619 }
2620
2621 if (href == NULL) {
2622 ns = node->nsDef;
2623 node->nsDef = NULL;
2624 c_retval = 0;
2625 }
2626 else {
2627 prev = NULL;
2628 ns = node->nsDef;
2629 while (ns != NULL) {
2630 if (xmlStrEqual(ns->href, href)) {
2631 if (prev != NULL)
2632 prev->next = ns->next;
2633 else
2634 node->nsDef = ns->next;
2635 ns->next = NULL;
2636 c_retval = 0;
2637 break;
2638 }
2639 prev = ns;
2640 ns = ns->next;
2641 }
2642 }
2643
2644 c_retval = ns;
2645 py_retval = libxml_xmlNsPtrWrap((xmlNsPtr) c_retval);
2646 return (py_retval);
2647 }
2648
2649 PyObject *
libxml_xmlNodeGetNs(ATTRIBUTE_UNUSED PyObject * self,PyObject * args)2650 libxml_xmlNodeGetNs(ATTRIBUTE_UNUSED PyObject * self, PyObject * args)
2651 {
2652 PyObject *py_retval;
2653 xmlNsPtr c_retval;
2654 xmlNodePtr node;
2655 PyObject *pyobj_node;
2656
2657 if (!PyArg_ParseTuple(args, (char *) "O:xmlNodeGetNs", &pyobj_node))
2658 return (NULL);
2659 node = (xmlNodePtr) PyxmlNode_Get(pyobj_node);
2660
2661 if ((node == NULL) ||
2662 ((node->type != XML_ELEMENT_NODE) &&
2663 (node->type != XML_ATTRIBUTE_NODE))) {
2664 Py_INCREF(Py_None);
2665 return (Py_None);
2666 }
2667 c_retval = node->ns;
2668 py_retval = libxml_xmlNsPtrWrap((xmlNsPtr) c_retval);
2669 return (py_retval);
2670 }
2671
2672 #ifdef LIBXML_OUTPUT_ENABLED
2673 /************************************************************************
2674 * *
2675 * Serialization front-end *
2676 * *
2677 ************************************************************************/
2678
2679 static PyObject *
libxml_serializeNode(ATTRIBUTE_UNUSED PyObject * self,PyObject * args)2680 libxml_serializeNode(ATTRIBUTE_UNUSED PyObject * self, PyObject * args)
2681 {
2682 PyObject *py_retval = NULL;
2683 xmlChar *c_retval;
2684 PyObject *pyobj_node;
2685 xmlNodePtr node;
2686 xmlDocPtr doc;
2687 const char *encoding;
2688 int format;
2689 xmlSaveCtxtPtr ctxt;
2690 xmlBufferPtr buf;
2691 int options = 0;
2692
2693 if (!PyArg_ParseTuple(args, (char *) "Ozi:serializeNode", &pyobj_node,
2694 &encoding, &format))
2695 return (NULL);
2696 node = (xmlNodePtr) PyxmlNode_Get(pyobj_node);
2697
2698 if (node == NULL) {
2699 Py_INCREF(Py_None);
2700 return (Py_None);
2701 }
2702 if (node->type == XML_DOCUMENT_NODE) {
2703 doc = (xmlDocPtr) node;
2704 node = NULL;
2705 #ifdef LIBXML_HTML_ENABLED
2706 } else if (node->type == XML_HTML_DOCUMENT_NODE) {
2707 doc = (xmlDocPtr) node;
2708 node = NULL;
2709 #endif
2710 } else {
2711 if (node->type == XML_NAMESPACE_DECL)
2712 doc = NULL;
2713 else
2714 doc = node->doc;
2715 if ((doc == NULL) || (doc->type == XML_DOCUMENT_NODE)) {
2716 #ifdef LIBXML_HTML_ENABLED
2717 } else if (doc->type == XML_HTML_DOCUMENT_NODE) {
2718 #endif /* LIBXML_HTML_ENABLED */
2719 } else {
2720 Py_INCREF(Py_None);
2721 return (Py_None);
2722 }
2723 }
2724
2725
2726 buf = xmlBufferCreate();
2727 if (buf == NULL) {
2728 Py_INCREF(Py_None);
2729 return (Py_None);
2730 }
2731 if (format) options |= XML_SAVE_FORMAT;
2732 ctxt = xmlSaveToBuffer(buf, encoding, options);
2733 if (ctxt == NULL) {
2734 xmlBufferFree(buf);
2735 Py_INCREF(Py_None);
2736 return (Py_None);
2737 }
2738 if (node == NULL)
2739 xmlSaveDoc(ctxt, doc);
2740 else
2741 xmlSaveTree(ctxt, node);
2742 xmlSaveClose(ctxt);
2743
2744 c_retval = xmlBufferDetach(buf);
2745
2746 xmlBufferFree(buf);
2747 py_retval = libxml_charPtrWrap((char *) c_retval);
2748
2749 return (py_retval);
2750 }
2751
2752 static PyObject *
libxml_saveNodeTo(ATTRIBUTE_UNUSED PyObject * self,PyObject * args)2753 libxml_saveNodeTo(ATTRIBUTE_UNUSED PyObject * self, PyObject * args)
2754 {
2755 PyObject *py_file = NULL;
2756 FILE *output;
2757 PyObject *pyobj_node;
2758 xmlNodePtr node;
2759 xmlDocPtr doc;
2760 const char *encoding;
2761 int format;
2762 int len;
2763 xmlOutputBufferPtr buf;
2764 xmlCharEncodingHandlerPtr handler = NULL;
2765
2766 if (!PyArg_ParseTuple(args, (char *) "OOzi:serializeNode", &pyobj_node,
2767 &py_file, &encoding, &format))
2768 return (NULL);
2769 node = (xmlNodePtr) PyxmlNode_Get(pyobj_node);
2770 if (node == NULL) {
2771 return (PyLong_FromLong((long) -1));
2772 }
2773 output = PyFile_Get(py_file);
2774 if (output == NULL) {
2775 return (PyLong_FromLong((long) -1));
2776 }
2777
2778 if (node->type == XML_DOCUMENT_NODE) {
2779 doc = (xmlDocPtr) node;
2780 } else if (node->type == XML_HTML_DOCUMENT_NODE) {
2781 doc = (xmlDocPtr) node;
2782 } else {
2783 doc = node->doc;
2784 }
2785 #ifdef LIBXML_HTML_ENABLED
2786 if (doc->type == XML_HTML_DOCUMENT_NODE) {
2787 if (encoding == NULL)
2788 encoding = (const char *) htmlGetMetaEncoding(doc);
2789 }
2790 #endif /* LIBXML_HTML_ENABLED */
2791 if (encoding != NULL) {
2792 handler = xmlFindCharEncodingHandler(encoding);
2793 if (handler == NULL) {
2794 PyFile_Release(output);
2795 return (PyLong_FromLong((long) -1));
2796 }
2797 }
2798 if (doc->type == XML_HTML_DOCUMENT_NODE) {
2799 if (handler == NULL)
2800 handler = xmlFindCharEncodingHandler("HTML");
2801 if (handler == NULL)
2802 handler = xmlFindCharEncodingHandler("ascii");
2803 }
2804
2805 buf = xmlOutputBufferCreateFile(output, handler);
2806 if (node->type == XML_DOCUMENT_NODE) {
2807 len = xmlSaveFormatFileTo(buf, doc, encoding, format);
2808 #ifdef LIBXML_HTML_ENABLED
2809 } else if (node->type == XML_HTML_DOCUMENT_NODE) {
2810 htmlDocContentDumpFormatOutput(buf, doc, encoding, format);
2811 len = xmlOutputBufferClose(buf);
2812 } else if (doc->type == XML_HTML_DOCUMENT_NODE) {
2813 htmlNodeDumpFormatOutput(buf, doc, node, encoding, format);
2814 len = xmlOutputBufferClose(buf);
2815 #endif /* LIBXML_HTML_ENABLED */
2816 } else {
2817 xmlNodeDumpOutput(buf, doc, node, 0, format, encoding);
2818 len = xmlOutputBufferClose(buf);
2819 }
2820 PyFile_Release(output);
2821 return (PyLong_FromLong((long) len));
2822 }
2823 #endif /* LIBXML_OUTPUT_ENABLED */
2824
2825 /************************************************************************
2826 * *
2827 * Extra stuff *
2828 * *
2829 ************************************************************************/
2830 PyObject *
libxml_xmlNewNode(ATTRIBUTE_UNUSED PyObject * self,PyObject * args)2831 libxml_xmlNewNode(ATTRIBUTE_UNUSED PyObject * self, PyObject * args)
2832 {
2833 PyObject *py_retval;
2834 xmlChar *name;
2835 xmlNodePtr node;
2836
2837 if (!PyArg_ParseTuple(args, (char *) "s:xmlNewNode", &name))
2838 return (NULL);
2839 node = (xmlNodePtr) xmlNewNode(NULL, name);
2840
2841 if (node == NULL) {
2842 Py_INCREF(Py_None);
2843 return (Py_None);
2844 }
2845 py_retval = libxml_xmlNodePtrWrap(node);
2846 return (py_retval);
2847 }
2848
2849
2850 /************************************************************************
2851 * *
2852 * Local Catalog stuff *
2853 * *
2854 ************************************************************************/
2855
2856 #ifdef LIBXML_CATALOG_ENABLED
2857 static PyObject *
libxml_addLocalCatalog(ATTRIBUTE_UNUSED PyObject * self,PyObject * args)2858 libxml_addLocalCatalog(ATTRIBUTE_UNUSED PyObject * self, PyObject * args)
2859 {
2860 xmlChar *URL;
2861 xmlParserCtxtPtr ctxt;
2862 PyObject *pyobj_ctxt;
2863
2864 if (!PyArg_ParseTuple(args, (char *)"Os:addLocalCatalog", &pyobj_ctxt, &URL))
2865 return(NULL);
2866
2867 ctxt = (xmlParserCtxtPtr) PyparserCtxt_Get(pyobj_ctxt);
2868
2869 if (URL != NULL) {
2870 void *catalogs = xmlCtxtGetCatalogs(ctxt);
2871 xmlCtxtSetCatalogs(ctxt, xmlCatalogAddLocal(catalogs, URL));
2872 }
2873
2874 Py_INCREF(Py_None);
2875 return (Py_None);
2876 }
2877 #endif /* LIBXML_CATALOG_ENABLED */
2878
2879 #ifdef LIBXML_SCHEMAS_ENABLED
2880
2881 /************************************************************************
2882 * *
2883 * RelaxNG error handler registration *
2884 * *
2885 ************************************************************************/
2886
2887 typedef struct
2888 {
2889 PyObject *warn;
2890 PyObject *error;
2891 PyObject *arg;
2892 } xmlRelaxNGValidCtxtPyCtxt;
2893 typedef xmlRelaxNGValidCtxtPyCtxt *xmlRelaxNGValidCtxtPyCtxtPtr;
2894
2895 static void
libxml_xmlRelaxNGValidityGenericErrorFuncHandler(void * ctx,char * str)2896 libxml_xmlRelaxNGValidityGenericErrorFuncHandler(void *ctx, char *str)
2897 {
2898 PyObject *list;
2899 PyObject *result;
2900 xmlRelaxNGValidCtxtPyCtxtPtr pyCtxt;
2901
2902 pyCtxt = (xmlRelaxNGValidCtxtPyCtxtPtr)ctx;
2903
2904 list = PyTuple_New(2);
2905 PyTuple_SetItem(list, 0, libxml_charPtrWrap(str));
2906 PyTuple_SetItem(list, 1, pyCtxt->arg);
2907 Py_XINCREF(pyCtxt->arg);
2908 result = PyObject_CallObject(pyCtxt->error, list);
2909 if (result == NULL)
2910 {
2911 /* TODO: manage for the exception to be propagated... */
2912 PyErr_Print();
2913 }
2914 Py_XDECREF(list);
2915 Py_XDECREF(result);
2916 }
2917
2918 static void
libxml_xmlRelaxNGValidityGenericWarningFuncHandler(void * ctx,char * str)2919 libxml_xmlRelaxNGValidityGenericWarningFuncHandler(void *ctx, char *str)
2920 {
2921 PyObject *list;
2922 PyObject *result;
2923 xmlRelaxNGValidCtxtPyCtxtPtr pyCtxt;
2924
2925 pyCtxt = (xmlRelaxNGValidCtxtPyCtxtPtr)ctx;
2926
2927 list = PyTuple_New(2);
2928 PyTuple_SetItem(list, 0, libxml_charPtrWrap(str));
2929 PyTuple_SetItem(list, 1, pyCtxt->arg);
2930 Py_XINCREF(pyCtxt->arg);
2931 result = PyObject_CallObject(pyCtxt->warn, list);
2932 if (result == NULL)
2933 {
2934 /* TODO: manage for the exception to be propagated... */
2935 PyErr_Print();
2936 }
2937 Py_XDECREF(list);
2938 Py_XDECREF(result);
2939 }
2940
2941 static void
libxml_xmlRelaxNGValidityErrorFunc(void * ctx,const char * msg,...)2942 libxml_xmlRelaxNGValidityErrorFunc(void *ctx, const char *msg, ...)
2943 {
2944 va_list ap;
2945
2946 va_start(ap, msg);
2947 libxml_xmlRelaxNGValidityGenericErrorFuncHandler(ctx, libxml_buildMessage(msg, ap));
2948 va_end(ap);
2949 }
2950
2951 static void
libxml_xmlRelaxNGValidityWarningFunc(void * ctx,const char * msg,...)2952 libxml_xmlRelaxNGValidityWarningFunc(void *ctx, const char *msg, ...)
2953 {
2954 va_list ap;
2955
2956 va_start(ap, msg);
2957 libxml_xmlRelaxNGValidityGenericWarningFuncHandler(ctx, libxml_buildMessage(msg, ap));
2958 va_end(ap);
2959 }
2960
2961 static PyObject *
libxml_xmlRelaxNGSetValidErrors(ATTRIBUTE_UNUSED PyObject * self,PyObject * args)2962 libxml_xmlRelaxNGSetValidErrors(ATTRIBUTE_UNUSED PyObject * self, PyObject * args)
2963 {
2964 PyObject *py_retval;
2965 PyObject *pyobj_error;
2966 PyObject *pyobj_warn;
2967 PyObject *pyobj_ctx;
2968 PyObject *pyobj_arg = Py_None;
2969 xmlRelaxNGValidCtxtPtr ctxt;
2970 xmlRelaxNGValidCtxtPyCtxtPtr pyCtxt;
2971
2972 if (!PyArg_ParseTuple
2973 (args, (char *) "OOO|O:xmlRelaxNGSetValidErrors", &pyobj_ctx, &pyobj_error, &pyobj_warn, &pyobj_arg))
2974 return (NULL);
2975
2976 ctxt = PyrelaxNgValidCtxt_Get(pyobj_ctx);
2977 if (xmlRelaxNGGetValidErrors(ctxt, NULL, NULL, (void **) &pyCtxt) == -1)
2978 {
2979 py_retval = libxml_intWrap(-1);
2980 return(py_retval);
2981 }
2982
2983 if (pyCtxt == NULL)
2984 {
2985 /* first time to set the error handlers */
2986 pyCtxt = xmlMalloc(sizeof(xmlRelaxNGValidCtxtPyCtxt));
2987 if (pyCtxt == NULL) {
2988 py_retval = libxml_intWrap(-1);
2989 return(py_retval);
2990 }
2991 memset(pyCtxt, 0, sizeof(xmlRelaxNGValidCtxtPyCtxt));
2992 }
2993
2994 /* TODO: check warn and error is a function ! */
2995 Py_XDECREF(pyCtxt->error);
2996 Py_XINCREF(pyobj_error);
2997 pyCtxt->error = pyobj_error;
2998
2999 Py_XDECREF(pyCtxt->warn);
3000 Py_XINCREF(pyobj_warn);
3001 pyCtxt->warn = pyobj_warn;
3002
3003 Py_XDECREF(pyCtxt->arg);
3004 Py_XINCREF(pyobj_arg);
3005 pyCtxt->arg = pyobj_arg;
3006
3007 xmlRelaxNGSetValidErrors(ctxt, &libxml_xmlRelaxNGValidityErrorFunc, &libxml_xmlRelaxNGValidityWarningFunc, pyCtxt);
3008
3009 py_retval = libxml_intWrap(1);
3010 return (py_retval);
3011 }
3012
3013 static PyObject *
libxml_xmlRelaxNGFreeValidCtxt(ATTRIBUTE_UNUSED PyObject * self,PyObject * args)3014 libxml_xmlRelaxNGFreeValidCtxt(ATTRIBUTE_UNUSED PyObject *self, PyObject *args) {
3015 xmlRelaxNGValidCtxtPtr ctxt;
3016 xmlRelaxNGValidCtxtPyCtxtPtr pyCtxt;
3017 PyObject *pyobj_ctxt;
3018
3019 if (!PyArg_ParseTuple(args, (char *)"O:xmlRelaxNGFreeValidCtxt", &pyobj_ctxt))
3020 return(NULL);
3021 ctxt = (xmlRelaxNGValidCtxtPtr) PyrelaxNgValidCtxt_Get(pyobj_ctxt);
3022
3023 if (xmlRelaxNGGetValidErrors(ctxt, NULL, NULL, (void **) &pyCtxt) == 0)
3024 {
3025 if (pyCtxt != NULL)
3026 {
3027 Py_XDECREF(pyCtxt->error);
3028 Py_XDECREF(pyCtxt->warn);
3029 Py_XDECREF(pyCtxt->arg);
3030 xmlFree(pyCtxt);
3031 }
3032 }
3033
3034 xmlRelaxNGFreeValidCtxt(ctxt);
3035 Py_INCREF(Py_None);
3036 return(Py_None);
3037 }
3038
3039 typedef struct
3040 {
3041 PyObject *warn;
3042 PyObject *error;
3043 PyObject *arg;
3044 } xmlSchemaValidCtxtPyCtxt;
3045 typedef xmlSchemaValidCtxtPyCtxt *xmlSchemaValidCtxtPyCtxtPtr;
3046
3047 static void
libxml_xmlSchemaValidityGenericErrorFuncHandler(void * ctx,char * str)3048 libxml_xmlSchemaValidityGenericErrorFuncHandler(void *ctx, char *str)
3049 {
3050 PyObject *list;
3051 PyObject *result;
3052 xmlSchemaValidCtxtPyCtxtPtr pyCtxt;
3053
3054 pyCtxt = (xmlSchemaValidCtxtPyCtxtPtr) ctx;
3055
3056 list = PyTuple_New(2);
3057 PyTuple_SetItem(list, 0, libxml_charPtrWrap(str));
3058 PyTuple_SetItem(list, 1, pyCtxt->arg);
3059 Py_XINCREF(pyCtxt->arg);
3060 result = PyObject_CallObject(pyCtxt->error, list);
3061 if (result == NULL)
3062 {
3063 /* TODO: manage for the exception to be propagated... */
3064 PyErr_Print();
3065 }
3066 Py_XDECREF(list);
3067 Py_XDECREF(result);
3068 }
3069
3070 static void
libxml_xmlSchemaValidityGenericWarningFuncHandler(void * ctx,char * str)3071 libxml_xmlSchemaValidityGenericWarningFuncHandler(void *ctx, char *str)
3072 {
3073 PyObject *list;
3074 PyObject *result;
3075 xmlSchemaValidCtxtPyCtxtPtr pyCtxt;
3076
3077 pyCtxt = (xmlSchemaValidCtxtPyCtxtPtr) ctx;
3078
3079 list = PyTuple_New(2);
3080 PyTuple_SetItem(list, 0, libxml_charPtrWrap(str));
3081 PyTuple_SetItem(list, 1, pyCtxt->arg);
3082 Py_XINCREF(pyCtxt->arg);
3083 result = PyObject_CallObject(pyCtxt->warn, list);
3084 if (result == NULL)
3085 {
3086 /* TODO: manage for the exception to be propagated... */
3087 PyErr_Print();
3088 }
3089 Py_XDECREF(list);
3090 Py_XDECREF(result);
3091 }
3092
3093 static void
libxml_xmlSchemaValidityErrorFunc(void * ctx,const char * msg,...)3094 libxml_xmlSchemaValidityErrorFunc(void *ctx, const char *msg, ...)
3095 {
3096 va_list ap;
3097
3098 va_start(ap, msg);
3099 libxml_xmlSchemaValidityGenericErrorFuncHandler(ctx, libxml_buildMessage(msg, ap));
3100 va_end(ap);
3101 }
3102
3103 static void
libxml_xmlSchemaValidityWarningFunc(void * ctx,const char * msg,...)3104 libxml_xmlSchemaValidityWarningFunc(void *ctx, const char *msg, ...)
3105 {
3106 va_list ap;
3107
3108 va_start(ap, msg);
3109 libxml_xmlSchemaValidityGenericWarningFuncHandler(ctx, libxml_buildMessage(msg, ap));
3110 va_end(ap);
3111 }
3112
3113 PyObject *
libxml_xmlSchemaSetValidErrors(ATTRIBUTE_UNUSED PyObject * self,PyObject * args)3114 libxml_xmlSchemaSetValidErrors(ATTRIBUTE_UNUSED PyObject * self, PyObject * args)
3115 {
3116 PyObject *py_retval;
3117 PyObject *pyobj_error;
3118 PyObject *pyobj_warn;
3119 PyObject *pyobj_ctx;
3120 PyObject *pyobj_arg = Py_None;
3121 xmlSchemaValidCtxtPtr ctxt;
3122 xmlSchemaValidCtxtPyCtxtPtr pyCtxt;
3123
3124 if (!PyArg_ParseTuple
3125 (args, (char *) "OOO|O:xmlSchemaSetValidErrors", &pyobj_ctx, &pyobj_error, &pyobj_warn, &pyobj_arg))
3126 return (NULL);
3127
3128 ctxt = PySchemaValidCtxt_Get(pyobj_ctx);
3129 if (xmlSchemaGetValidErrors(ctxt, NULL, NULL, (void **) &pyCtxt) == -1)
3130 {
3131 py_retval = libxml_intWrap(-1);
3132 return(py_retval);
3133 }
3134
3135 if (pyCtxt == NULL)
3136 {
3137 /* first time to set the error handlers */
3138 pyCtxt = xmlMalloc(sizeof(xmlSchemaValidCtxtPyCtxt));
3139 if (pyCtxt == NULL) {
3140 py_retval = libxml_intWrap(-1);
3141 return(py_retval);
3142 }
3143 memset(pyCtxt, 0, sizeof(xmlSchemaValidCtxtPyCtxt));
3144 }
3145
3146 /* TODO: check warn and error is a function ! */
3147 Py_XDECREF(pyCtxt->error);
3148 Py_XINCREF(pyobj_error);
3149 pyCtxt->error = pyobj_error;
3150
3151 Py_XDECREF(pyCtxt->warn);
3152 Py_XINCREF(pyobj_warn);
3153 pyCtxt->warn = pyobj_warn;
3154
3155 Py_XDECREF(pyCtxt->arg);
3156 Py_XINCREF(pyobj_arg);
3157 pyCtxt->arg = pyobj_arg;
3158
3159 xmlSchemaSetValidErrors(ctxt, &libxml_xmlSchemaValidityErrorFunc, &libxml_xmlSchemaValidityWarningFunc, pyCtxt);
3160
3161 py_retval = libxml_intWrap(1);
3162 return(py_retval);
3163 }
3164
3165 static PyObject *
libxml_xmlSchemaFreeValidCtxt(ATTRIBUTE_UNUSED PyObject * self,PyObject * args)3166 libxml_xmlSchemaFreeValidCtxt(ATTRIBUTE_UNUSED PyObject * self, PyObject * args)
3167 {
3168 xmlSchemaValidCtxtPtr ctxt;
3169 xmlSchemaValidCtxtPyCtxtPtr pyCtxt;
3170 PyObject *pyobj_ctxt;
3171
3172 if (!PyArg_ParseTuple(args, (char *)"O:xmlSchemaFreeValidCtxt", &pyobj_ctxt))
3173 return(NULL);
3174 ctxt = (xmlSchemaValidCtxtPtr) PySchemaValidCtxt_Get(pyobj_ctxt);
3175
3176 if (xmlSchemaGetValidErrors(ctxt, NULL, NULL, (void **) &pyCtxt) == 0)
3177 {
3178 if (pyCtxt != NULL)
3179 {
3180 Py_XDECREF(pyCtxt->error);
3181 Py_XDECREF(pyCtxt->warn);
3182 Py_XDECREF(pyCtxt->arg);
3183 xmlFree(pyCtxt);
3184 }
3185 }
3186
3187 xmlSchemaFreeValidCtxt(ctxt);
3188 Py_INCREF(Py_None);
3189 return(Py_None);
3190 }
3191
3192 #endif
3193
3194 #ifdef LIBXML_C14N_ENABLED
3195 #ifdef LIBXML_OUTPUT_ENABLED
3196
3197 /************************************************************************
3198 * *
3199 * XML Canonicalization c14n *
3200 * *
3201 ************************************************************************/
3202
3203 static int
PyxmlNodeSet_Convert(PyObject * py_nodeset,xmlNodeSetPtr * result)3204 PyxmlNodeSet_Convert(PyObject *py_nodeset, xmlNodeSetPtr *result)
3205 {
3206 xmlNodeSetPtr nodeSet;
3207 int is_tuple = 0;
3208
3209 if (PyTuple_Check(py_nodeset))
3210 is_tuple = 1;
3211 else if (PyList_Check(py_nodeset))
3212 is_tuple = 0;
3213 else if (py_nodeset == Py_None) {
3214 *result = NULL;
3215 return 0;
3216 }
3217 else {
3218 PyErr_SetString(PyExc_TypeError,
3219 "must be a tuple or list of nodes.");
3220 return -1;
3221 }
3222
3223 nodeSet = (xmlNodeSetPtr) xmlMalloc(sizeof(xmlNodeSet));
3224 if (nodeSet == NULL) {
3225 PyErr_SetString(PyExc_MemoryError, "");
3226 return -1;
3227 }
3228
3229 nodeSet->nodeNr = 0;
3230 nodeSet->nodeMax = (is_tuple
3231 ? PyTuple_GET_SIZE(py_nodeset)
3232 : PyList_GET_SIZE(py_nodeset));
3233 nodeSet->nodeTab
3234 = (xmlNodePtr *) xmlMalloc (nodeSet->nodeMax
3235 * sizeof(xmlNodePtr));
3236 if (nodeSet->nodeTab == NULL) {
3237 xmlFree(nodeSet);
3238 PyErr_SetString(PyExc_MemoryError, "");
3239 return -1;
3240 }
3241 memset(nodeSet->nodeTab, 0 ,
3242 nodeSet->nodeMax * sizeof(xmlNodePtr));
3243
3244 {
3245 int idx;
3246 for (idx=0; idx < nodeSet->nodeMax; ++idx) {
3247 xmlNodePtr pynode =
3248 PyxmlNode_Get (is_tuple
3249 ? PyTuple_GET_ITEM(py_nodeset, idx)
3250 : PyList_GET_ITEM(py_nodeset, idx));
3251 if (pynode)
3252 nodeSet->nodeTab[nodeSet->nodeNr++] = pynode;
3253 }
3254 }
3255 *result = nodeSet;
3256 return 0;
3257 }
3258
3259 static int
PystringSet_Convert(PyObject * py_strings,xmlChar *** result)3260 PystringSet_Convert(PyObject *py_strings, xmlChar *** result)
3261 {
3262 /* NOTE: the array should be freed, but the strings are shared
3263 with the python strings and so must not be freed. */
3264
3265 xmlChar ** strings;
3266 int is_tuple = 0;
3267 int count;
3268 int init_index = 0;
3269
3270 if (PyTuple_Check(py_strings))
3271 is_tuple = 1;
3272 else if (PyList_Check(py_strings))
3273 is_tuple = 0;
3274 else if (py_strings == Py_None) {
3275 *result = NULL;
3276 return 0;
3277 }
3278 else {
3279 PyErr_SetString(PyExc_TypeError,
3280 "must be a tuple or list of strings.");
3281 return -1;
3282 }
3283
3284 count = (is_tuple
3285 ? PyTuple_GET_SIZE(py_strings)
3286 : PyList_GET_SIZE(py_strings));
3287
3288 strings = (xmlChar **) xmlMalloc(sizeof(xmlChar *) * count);
3289
3290 if (strings == NULL) {
3291 PyErr_SetString(PyExc_MemoryError, "");
3292 return -1;
3293 }
3294
3295 memset(strings, 0 , sizeof(xmlChar *) * count);
3296
3297 {
3298 int idx;
3299 for (idx=0; idx < count; ++idx) {
3300 char* s = PyBytes_AsString
3301 (is_tuple
3302 ? PyTuple_GET_ITEM(py_strings, idx)
3303 : PyList_GET_ITEM(py_strings, idx));
3304 if (s)
3305 strings[init_index++] = (xmlChar *)s;
3306 else {
3307 xmlFree(strings);
3308 PyErr_SetString(PyExc_TypeError,
3309 "must be a tuple or list of strings.");
3310 return -1;
3311 }
3312 }
3313 }
3314
3315 *result = strings;
3316 return 0;
3317 }
3318
3319 static PyObject *
libxml_C14NDocDumpMemory(ATTRIBUTE_UNUSED PyObject * self,PyObject * args)3320 libxml_C14NDocDumpMemory(ATTRIBUTE_UNUSED PyObject * self,
3321 PyObject * args)
3322 {
3323 PyObject *py_retval = NULL;
3324
3325 PyObject *pyobj_doc;
3326 PyObject *pyobj_nodes;
3327 int exclusive;
3328 PyObject *pyobj_prefixes;
3329 int with_comments;
3330
3331 xmlDocPtr doc;
3332 xmlNodeSetPtr nodes;
3333 xmlChar **prefixes = NULL;
3334 xmlChar *doc_txt;
3335
3336 int result;
3337
3338 if (!PyArg_ParseTuple(args, (char *) "OOiOi:C14NDocDumpMemory",
3339 &pyobj_doc,
3340 &pyobj_nodes,
3341 &exclusive,
3342 &pyobj_prefixes,
3343 &with_comments))
3344 return (NULL);
3345
3346 doc = (xmlDocPtr) PyxmlNode_Get(pyobj_doc);
3347 if (!doc) {
3348 PyErr_SetString(PyExc_TypeError, "bad document.");
3349 return NULL;
3350 }
3351
3352 result = PyxmlNodeSet_Convert(pyobj_nodes, &nodes);
3353 if (result < 0) return NULL;
3354
3355 if (exclusive) {
3356 result = PystringSet_Convert(pyobj_prefixes, &prefixes);
3357 if (result < 0) {
3358 if (nodes) {
3359 xmlFree(nodes->nodeTab);
3360 xmlFree(nodes);
3361 }
3362 return NULL;
3363 }
3364 }
3365
3366 result = xmlC14NDocDumpMemory(doc,
3367 nodes,
3368 exclusive,
3369 prefixes,
3370 with_comments,
3371 &doc_txt);
3372
3373 if (nodes) {
3374 xmlFree(nodes->nodeTab);
3375 xmlFree(nodes);
3376 }
3377 if (prefixes) {
3378 xmlChar ** idx = prefixes;
3379 while (*idx) xmlFree(*(idx++));
3380 xmlFree(prefixes);
3381 }
3382
3383 if (result < 0) {
3384 PyErr_SetString(PyExc_Exception,
3385 "libxml2 xmlC14NDocDumpMemory failure.");
3386 return NULL;
3387 }
3388 else {
3389 py_retval = PY_IMPORT_STRING_SIZE((const char *) doc_txt,
3390 result);
3391 xmlFree(doc_txt);
3392 return py_retval;
3393 }
3394 }
3395
3396 static PyObject *
libxml_C14NDocSaveTo(ATTRIBUTE_UNUSED PyObject * self,PyObject * args)3397 libxml_C14NDocSaveTo(ATTRIBUTE_UNUSED PyObject * self,
3398 PyObject * args)
3399 {
3400 PyObject *pyobj_doc;
3401 PyObject *py_file;
3402 PyObject *pyobj_nodes;
3403 int exclusive;
3404 PyObject *pyobj_prefixes;
3405 int with_comments;
3406
3407 xmlDocPtr doc;
3408 xmlNodeSetPtr nodes;
3409 xmlChar **prefixes = NULL;
3410 FILE * output;
3411 xmlOutputBufferPtr buf;
3412
3413 int result;
3414 int len;
3415
3416 if (!PyArg_ParseTuple(args, (char *) "OOiOiO:C14NDocSaveTo",
3417 &pyobj_doc,
3418 &pyobj_nodes,
3419 &exclusive,
3420 &pyobj_prefixes,
3421 &with_comments,
3422 &py_file))
3423 return (NULL);
3424
3425 doc = (xmlDocPtr) PyxmlNode_Get(pyobj_doc);
3426 if (!doc) {
3427 PyErr_SetString(PyExc_TypeError, "bad document.");
3428 return NULL;
3429 }
3430
3431 output = PyFile_Get(py_file);
3432 if (output == NULL) {
3433 PyErr_SetString(PyExc_TypeError, "bad file.");
3434 return NULL;
3435 }
3436 buf = xmlOutputBufferCreateFile(output, NULL);
3437
3438 result = PyxmlNodeSet_Convert(pyobj_nodes, &nodes);
3439 if (result < 0) {
3440 xmlOutputBufferClose(buf);
3441 return NULL;
3442 }
3443
3444 if (exclusive) {
3445 result = PystringSet_Convert(pyobj_prefixes, &prefixes);
3446 if (result < 0) {
3447 if (nodes) {
3448 xmlFree(nodes->nodeTab);
3449 xmlFree(nodes);
3450 }
3451 xmlOutputBufferClose(buf);
3452 return NULL;
3453 }
3454 }
3455
3456 result = xmlC14NDocSaveTo(doc,
3457 nodes,
3458 exclusive,
3459 prefixes,
3460 with_comments,
3461 buf);
3462
3463 if (nodes) {
3464 xmlFree(nodes->nodeTab);
3465 xmlFree(nodes);
3466 }
3467 if (prefixes) {
3468 xmlChar ** idx = prefixes;
3469 while (*idx) xmlFree(*(idx++));
3470 xmlFree(prefixes);
3471 }
3472
3473 PyFile_Release(output);
3474 len = xmlOutputBufferClose(buf);
3475
3476 if (result < 0) {
3477 PyErr_SetString(PyExc_Exception,
3478 "libxml2 xmlC14NDocSaveTo failure.");
3479 return NULL;
3480 }
3481 else
3482 return PyLong_FromLong((long) len);
3483 }
3484
3485 #endif
3486 #endif
3487
3488 static PyObject *
libxml_getObjDesc(PyObject * self ATTRIBUTE_UNUSED,PyObject * args)3489 libxml_getObjDesc(PyObject *self ATTRIBUTE_UNUSED, PyObject *args) {
3490
3491 PyObject *obj;
3492 char *str;
3493
3494 if (!PyArg_ParseTuple(args, (char *)"O:getObjDesc", &obj))
3495 return NULL;
3496 str = PyCapsule_GetPointer(obj, PyCapsule_GetName(obj));
3497 return Py_BuildValue((char *)"s", str);
3498 }
3499
3500 static PyObject *
libxml_compareNodesEqual(PyObject * self ATTRIBUTE_UNUSED,PyObject * args)3501 libxml_compareNodesEqual(PyObject *self ATTRIBUTE_UNUSED, PyObject *args) {
3502
3503 PyObject *py_node1, *py_node2;
3504 xmlNodePtr node1, node2;
3505
3506 if (!PyArg_ParseTuple(args, (char *)"OO:compareNodesEqual",
3507 &py_node1, &py_node2))
3508 return NULL;
3509 /* To compare two node objects, we compare their pointer addresses */
3510 node1 = PyxmlNode_Get(py_node1);
3511 node2 = PyxmlNode_Get(py_node2);
3512 if ( node1 == node2 )
3513 return Py_BuildValue((char *)"i", 1);
3514 else
3515 return Py_BuildValue((char *)"i", 0);
3516
3517 }
3518
3519 static PyObject *
libxml_nodeHash(PyObject * self ATTRIBUTE_UNUSED,PyObject * args)3520 libxml_nodeHash(PyObject *self ATTRIBUTE_UNUSED, PyObject *args) {
3521
3522 PyObject *py_node1;
3523 xmlNodePtr node1;
3524
3525 if (!PyArg_ParseTuple(args, (char *)"O:nodeHash", &py_node1))
3526 return NULL;
3527 /* For simplicity, we use the node pointer address as a hash value */
3528 node1 = PyxmlNode_Get(py_node1);
3529
3530 return PyLong_FromVoidPtr(node1);
3531
3532 }
3533
3534 /************************************************************************
3535 * *
3536 * Deprecation warnings *
3537 * *
3538 ************************************************************************/
3539
3540 int
libxml_deprecationWarning(const char * func)3541 libxml_deprecationWarning(const char *func) {
3542 #if PY_VERSION_HEX >= 0x03020000
3543 return PyErr_WarnFormat(PyExc_PendingDeprecationWarning, 1,
3544 "libxml2mod.%s is deprecated and will be removed "
3545 "in future versions", func);
3546 #else
3547 return PyErr_WarnEx(PyExc_PendingDeprecationWarning, func, 1);
3548 #endif
3549 }
3550
3551 /************************************************************************
3552 * *
3553 * The registration stuff *
3554 * *
3555 ************************************************************************/
3556 static PyMethodDef libxmlMethods[] = {
3557 #include "libxml2-export.c"
3558 {(char *) "name", libxml_name, METH_VARARGS, NULL},
3559 {(char *) "children", libxml_children, METH_VARARGS, NULL},
3560 {(char *) "properties", libxml_properties, METH_VARARGS, NULL},
3561 {(char *) "last", libxml_last, METH_VARARGS, NULL},
3562 {(char *) "prev", libxml_prev, METH_VARARGS, NULL},
3563 {(char *) "next", libxml_next, METH_VARARGS, NULL},
3564 {(char *) "parent", libxml_parent, METH_VARARGS, NULL},
3565 {(char *) "type", libxml_type, METH_VARARGS, NULL},
3566 {(char *) "doc", libxml_doc, METH_VARARGS, NULL},
3567 {(char *) "xmlNewNode", libxml_xmlNewNode, METH_VARARGS, NULL},
3568 {(char *) "xmlNodeRemoveNsDef", libxml_xmlNodeRemoveNsDef, METH_VARARGS, NULL},
3569 #ifdef LIBXML_VALID_ENABLED
3570 {(char *)"xmlSetValidErrors", libxml_xmlSetValidErrors, METH_VARARGS, NULL},
3571 {(char *)"xmlFreeValidCtxt", libxml_xmlFreeValidCtxt, METH_VARARGS, NULL},
3572 #endif /* LIBXML_VALID_ENABLED */
3573 #ifdef LIBXML_OUTPUT_ENABLED
3574 {(char *) "serializeNode", libxml_serializeNode, METH_VARARGS, NULL},
3575 {(char *) "saveNodeTo", libxml_saveNodeTo, METH_VARARGS, NULL},
3576 {(char *) "outputBufferCreate", libxml_xmlCreateOutputBuffer, METH_VARARGS, NULL},
3577 {(char *) "outputBufferGetPythonFile", libxml_outputBufferGetPythonFile, METH_VARARGS, NULL},
3578 {(char *) "xmlOutputBufferClose", libxml_xmlOutputBufferClose, METH_VARARGS, NULL},
3579 { (char *)"xmlOutputBufferFlush", libxml_xmlOutputBufferFlush, METH_VARARGS, NULL },
3580 { (char *)"xmlSaveFileTo", libxml_xmlSaveFileTo, METH_VARARGS, NULL },
3581 { (char *)"xmlSaveFormatFileTo", libxml_xmlSaveFormatFileTo, METH_VARARGS, NULL },
3582 #endif /* LIBXML_OUTPUT_ENABLED */
3583 {(char *) "inputBufferCreate", libxml_xmlCreateInputBuffer, METH_VARARGS, NULL},
3584 {(char *) "setEntityLoader", libxml_xmlSetEntityLoader, METH_VARARGS, NULL},
3585 {(char *)"xmlRegisterErrorHandler", libxml_xmlRegisterErrorHandler, METH_VARARGS, NULL },
3586 {(char *)"xmlParserCtxtSetErrorHandler", libxml_xmlParserCtxtSetErrorHandler, METH_VARARGS, NULL },
3587 {(char *)"xmlParserCtxtGetErrorHandler", libxml_xmlParserCtxtGetErrorHandler, METH_VARARGS, NULL },
3588 {(char *)"xmlFreeParserCtxt", libxml_xmlFreeParserCtxt, METH_VARARGS, NULL },
3589 #ifdef LIBXML_READER_ENABLED
3590 {(char *)"xmlTextReaderSetErrorHandler", libxml_xmlTextReaderSetErrorHandler, METH_VARARGS, NULL },
3591 {(char *)"xmlTextReaderGetErrorHandler", libxml_xmlTextReaderGetErrorHandler, METH_VARARGS, NULL },
3592 {(char *)"xmlFreeTextReader", libxml_xmlFreeTextReader, METH_VARARGS, NULL },
3593 #endif
3594 #ifdef LIBXML_CATALOG_ENABLED
3595 {(char *)"addLocalCatalog", libxml_addLocalCatalog, METH_VARARGS, NULL },
3596 #endif
3597 #ifdef LIBXML_SCHEMAS_ENABLED
3598 {(char *)"xmlRelaxNGSetValidErrors", libxml_xmlRelaxNGSetValidErrors, METH_VARARGS, NULL},
3599 {(char *)"xmlRelaxNGFreeValidCtxt", libxml_xmlRelaxNGFreeValidCtxt, METH_VARARGS, NULL},
3600 {(char *)"xmlSchemaSetValidErrors", libxml_xmlSchemaSetValidErrors, METH_VARARGS, NULL},
3601 {(char *)"xmlSchemaFreeValidCtxt", libxml_xmlSchemaFreeValidCtxt, METH_VARARGS, NULL},
3602 #endif
3603 #ifdef LIBXML_C14N_ENABLED
3604 #ifdef LIBXML_OUTPUT_ENABLED
3605 {(char *)"xmlC14NDocDumpMemory", libxml_C14NDocDumpMemory, METH_VARARGS, NULL},
3606 {(char *)"xmlC14NDocSaveTo", libxml_C14NDocSaveTo, METH_VARARGS, NULL},
3607 #endif
3608 #endif
3609 {(char *) "getObjDesc", libxml_getObjDesc, METH_VARARGS, NULL},
3610 {(char *) "compareNodesEqual", libxml_compareNodesEqual, METH_VARARGS, NULL},
3611 {(char *) "nodeHash", libxml_nodeHash, METH_VARARGS, NULL},
3612 {(char *) "xmlRegisterInputCallback", libxml_xmlRegisterInputCallback, METH_VARARGS, NULL},
3613 {(char *) "xmlUnregisterInputCallback", libxml_xmlUnregisterInputCallback, METH_VARARGS, NULL},
3614 {NULL, NULL, 0, NULL}
3615 };
3616
3617 #if PY_MAJOR_VERSION >= 3
3618 #define INITERROR return NULL
3619
3620 static struct PyModuleDef moduledef = {
3621 PyModuleDef_HEAD_INIT,
3622 "libxml2mod",
3623 NULL,
3624 -1,
3625 libxmlMethods,
3626 NULL,
3627 NULL,
3628 NULL,
3629 NULL
3630 };
3631
3632 #else
3633 #define INITERROR return
3634
3635 #ifdef MERGED_MODULES
3636 extern void initlibxsltmod(void);
3637 #endif
3638
3639 #endif
3640
3641 #if PY_MAJOR_VERSION >= 3
PyInit_libxml2mod(void)3642 PyObject *PyInit_libxml2mod(void)
3643 #else
3644 void initlibxml2mod(void)
3645 #endif
3646 {
3647 PyObject *module;
3648
3649 #if PY_MAJOR_VERSION >= 3
3650 module = PyModule_Create(&moduledef);
3651 #else
3652 /* initialize the python extension module */
3653 module = Py_InitModule((char *) "libxml2mod", libxmlMethods);
3654 #endif
3655 if (module == NULL)
3656 INITERROR;
3657
3658 /* initialize libxml2 */
3659 xmlInitParser();
3660 /* TODO this probably need to be revamped for Python3 */
3661 libxml_xmlErrorInitialize();
3662
3663 #if PY_MAJOR_VERSION < 3
3664 #ifdef MERGED_MODULES
3665 initlibxsltmod();
3666 #endif
3667 #endif
3668
3669 #if PY_MAJOR_VERSION >= 3
3670 return module;
3671 #endif
3672 }
3673