VirtualBox

source: vbox/trunk/src/libs/libxml2-2.12.6/python/libxml.c@ 104932

Last change on this file since 104932 was 104106, checked in by vboxsync, 9 months ago

libxml2-2.9.14: Applied and adjusted our libxml2 changes to 2.9.14. bugref:10640

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

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette