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