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