VirtualBox

source: vbox/trunk/src/libs/libxml2-2.13.2/python/libxml.c@ 106051

最後變更 在這個檔案從106051是 105420,由 vboxsync 提交於 7 月 前

libxml2-2.12.6: Applied and adjusted our libxml2 changes to 2.12.6. bugref:10730

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

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