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