Annotation of embedaddon/libxml2/python/libxml.c, revision 1.1.1.2

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: 
1.1.1.2 ! misho      31: #if defined(_MSC_VER) && !defined(vsnprintf)
1.1       misho      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
1.1.1.2 ! misho    1748: libxml_xmlValidCtxtGenericErrorFuncHandler(void *ctx, ATTRIBUTE_UNUSED int severity, char *str)
1.1       misho    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
1.1.1.2 ! misho    1775: libxml_xmlValidCtxtGenericWarningFuncHandler(void *ctx, ATTRIBUTE_UNUSED int severity, char *str)
1.1       misho    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:     xmlSaveCtxtPtr ctxt;
                   2766:     xmlBufferPtr buf;
                   2767:     int options = 0;
                   2768: 
                   2769:     if (!PyArg_ParseTuple(args, (char *) "Ozi:serializeNode", &pyobj_node,
                   2770:                           &encoding, &format))
                   2771:         return (NULL);
                   2772:     node = (xmlNodePtr) PyxmlNode_Get(pyobj_node);
                   2773: 
                   2774:     if (node == NULL) {
                   2775:         Py_INCREF(Py_None);
                   2776:         return (Py_None);
                   2777:     }
                   2778:     if (node->type == XML_DOCUMENT_NODE) {
                   2779:         doc = (xmlDocPtr) node;
                   2780:        node = NULL;
                   2781: #ifdef LIBXML_HTML_ENABLED
                   2782:     } else if (node->type == XML_HTML_DOCUMENT_NODE) {
                   2783:         doc = (xmlDocPtr) node;
                   2784:        node = NULL;
                   2785: #endif
                   2786:     } else {
                   2787:         if (node->type == XML_NAMESPACE_DECL)
                   2788:            doc = NULL;
                   2789:        else
                   2790:             doc = node->doc;
                   2791:         if ((doc == NULL) || (doc->type == XML_DOCUMENT_NODE)) {
                   2792: #ifdef LIBXML_HTML_ENABLED
                   2793:         } else if (doc->type == XML_HTML_DOCUMENT_NODE) {
                   2794: #endif /* LIBXML_HTML_ENABLED */
                   2795:         } else {
                   2796:             Py_INCREF(Py_None);
                   2797:             return (Py_None);
                   2798:         }
                   2799:     }
                   2800: 
                   2801: 
                   2802:     buf = xmlBufferCreate();
                   2803:     if (buf == NULL) {
                   2804:        Py_INCREF(Py_None);
                   2805:        return (Py_None);
                   2806:     }
                   2807:     if (format) options |= XML_SAVE_FORMAT;
                   2808:     ctxt = xmlSaveToBuffer(buf, encoding, options);
                   2809:     if (ctxt == NULL) {
                   2810:        xmlBufferFree(buf);
                   2811:        Py_INCREF(Py_None);
                   2812:        return (Py_None);
                   2813:     }
                   2814:     if (node == NULL)
                   2815:        xmlSaveDoc(ctxt, doc);
                   2816:     else
                   2817:        xmlSaveTree(ctxt, node);
                   2818:     xmlSaveClose(ctxt);
                   2819: 
                   2820:     c_retval = buf->content;
                   2821:     buf->content = NULL;
                   2822: 
                   2823:     xmlBufferFree(buf);
                   2824:     py_retval = libxml_charPtrWrap((char *) c_retval);
                   2825: 
                   2826:     return (py_retval);
                   2827: }
                   2828: 
                   2829: static PyObject *
                   2830: libxml_saveNodeTo(ATTRIBUTE_UNUSED PyObject * self, PyObject * args)
                   2831: {
                   2832:     PyObject *py_file = NULL;
                   2833:     FILE *output;
                   2834:     PyObject *pyobj_node;
                   2835:     xmlNodePtr node;
                   2836:     xmlDocPtr doc;
                   2837:     const char *encoding;
                   2838:     int format;
                   2839:     int len;
                   2840:     xmlOutputBufferPtr buf;
                   2841:     xmlCharEncodingHandlerPtr handler = NULL;
                   2842: 
                   2843:     if (!PyArg_ParseTuple(args, (char *) "OOzi:serializeNode", &pyobj_node,
                   2844:                           &py_file, &encoding, &format))
                   2845:         return (NULL);
                   2846:     node = (xmlNodePtr) PyxmlNode_Get(pyobj_node);
                   2847: 
                   2848:     if (node == NULL) {
                   2849:         return (PyInt_FromLong((long) -1));
                   2850:     }
                   2851:     if ((py_file == NULL) || (!(PyFile_Check(py_file)))) {
                   2852:         return (PyInt_FromLong((long) -1));
                   2853:     }
                   2854:     output = PyFile_AsFile(py_file);
                   2855:     if (output == NULL) {
                   2856:         return (PyInt_FromLong((long) -1));
                   2857:     }
                   2858: 
                   2859:     if (node->type == XML_DOCUMENT_NODE) {
                   2860:         doc = (xmlDocPtr) node;
                   2861:     } else if (node->type == XML_HTML_DOCUMENT_NODE) {
                   2862:         doc = (xmlDocPtr) node;
                   2863:     } else {
                   2864:         doc = node->doc;
                   2865:     }
                   2866: #ifdef LIBXML_HTML_ENABLED
                   2867:     if (doc->type == XML_HTML_DOCUMENT_NODE) {
                   2868:         if (encoding == NULL)
                   2869:             encoding = (const char *) htmlGetMetaEncoding(doc);
                   2870:     }
                   2871: #endif /* LIBXML_HTML_ENABLED */
                   2872:     if (encoding != NULL) {
                   2873:         handler = xmlFindCharEncodingHandler(encoding);
                   2874:         if (handler == NULL) {
                   2875:             return (PyInt_FromLong((long) -1));
                   2876:         }
                   2877:     }
                   2878:     if (doc->type == XML_HTML_DOCUMENT_NODE) {
                   2879:         if (handler == NULL)
                   2880:             handler = xmlFindCharEncodingHandler("HTML");
                   2881:         if (handler == NULL)
                   2882:             handler = xmlFindCharEncodingHandler("ascii");
                   2883:     }
                   2884: 
                   2885:     buf = xmlOutputBufferCreateFile(output, handler);
                   2886:     if (node->type == XML_DOCUMENT_NODE) {
                   2887:         len = xmlSaveFormatFileTo(buf, doc, encoding, format);
                   2888: #ifdef LIBXML_HTML_ENABLED
                   2889:     } else if (node->type == XML_HTML_DOCUMENT_NODE) {
                   2890:         htmlDocContentDumpFormatOutput(buf, doc, encoding, format);
                   2891:         len = xmlOutputBufferClose(buf);
                   2892:     } else if (doc->type == XML_HTML_DOCUMENT_NODE) {
                   2893:         htmlNodeDumpFormatOutput(buf, doc, node, encoding, format);
                   2894:         len = xmlOutputBufferClose(buf);
                   2895: #endif /* LIBXML_HTML_ENABLED */
                   2896:     } else {
                   2897:         xmlNodeDumpOutput(buf, doc, node, 0, format, encoding);
                   2898:         len = xmlOutputBufferClose(buf);
                   2899:     }
                   2900:     return (PyInt_FromLong((long) len));
                   2901: }
                   2902: #endif /* LIBXML_OUTPUT_ENABLED */
                   2903: 
                   2904: /************************************************************************
                   2905:  *                                                                     *
                   2906:  *                     Extra stuff                                     *
                   2907:  *                                                                     *
                   2908:  ************************************************************************/
                   2909: PyObject *
                   2910: libxml_xmlNewNode(ATTRIBUTE_UNUSED PyObject * self, PyObject * args)
                   2911: {
                   2912:     PyObject *py_retval;
                   2913:     xmlChar *name;
                   2914:     xmlNodePtr node;
                   2915: 
                   2916:     if (!PyArg_ParseTuple(args, (char *) "s:xmlNewNode", &name))
                   2917:         return (NULL);
                   2918:     node = (xmlNodePtr) xmlNewNode(NULL, name);
                   2919: #ifdef DEBUG
                   2920:     printf("NewNode: %s : %p\n", name, (void *) node);
                   2921: #endif
                   2922: 
                   2923:     if (node == NULL) {
                   2924:         Py_INCREF(Py_None);
                   2925:         return (Py_None);
                   2926:     }
                   2927:     py_retval = libxml_xmlNodePtrWrap(node);
                   2928:     return (py_retval);
                   2929: }
                   2930: 
                   2931: 
                   2932: /************************************************************************
                   2933:  *                                                                     *
                   2934:  *                     Local Catalog stuff                             *
                   2935:  *                                                                     *
                   2936:  ************************************************************************/
                   2937: static PyObject *
                   2938: libxml_addLocalCatalog(ATTRIBUTE_UNUSED PyObject * self, PyObject * args)
                   2939: {
                   2940:     xmlChar *URL;
                   2941:     xmlParserCtxtPtr ctxt;
                   2942:     PyObject *pyobj_ctxt;
                   2943: 
                   2944:     if (!PyArg_ParseTuple(args, (char *)"Os:addLocalCatalog", &pyobj_ctxt, &URL))
                   2945:         return(NULL);
                   2946: 
                   2947:     ctxt = (xmlParserCtxtPtr) PyparserCtxt_Get(pyobj_ctxt);
                   2948: 
                   2949:     if (URL != NULL) {
                   2950:        ctxt->catalogs = xmlCatalogAddLocal(ctxt->catalogs, URL);
                   2951:     }
                   2952: 
                   2953: #ifdef DEBUG
                   2954:     printf("LocalCatalog: %s\n", URL);
                   2955: #endif
                   2956: 
                   2957:     Py_INCREF(Py_None);
                   2958:     return (Py_None);
                   2959: }
                   2960: 
                   2961: #ifdef LIBXML_SCHEMAS_ENABLED
                   2962: 
                   2963: /************************************************************************
                   2964:  *                                                                      *
                   2965:  * RelaxNG error handler registration                                   *
                   2966:  *                                                                      *
                   2967:  ************************************************************************/
                   2968: 
                   2969: typedef struct 
                   2970: {
                   2971:     PyObject *warn;
                   2972:     PyObject *error;
                   2973:     PyObject *arg;
                   2974: } xmlRelaxNGValidCtxtPyCtxt;
                   2975: typedef xmlRelaxNGValidCtxtPyCtxt *xmlRelaxNGValidCtxtPyCtxtPtr;
                   2976: 
                   2977: static void
                   2978: libxml_xmlRelaxNGValidityGenericErrorFuncHandler(void *ctx, char *str) 
                   2979: {
                   2980:     PyObject *list;
                   2981:     PyObject *result;
                   2982:     xmlRelaxNGValidCtxtPyCtxtPtr pyCtxt;
                   2983:     
                   2984: #ifdef DEBUG_ERROR
                   2985:     printf("libxml_xmlRelaxNGValidityGenericErrorFuncHandler(%p, %s, ...) called\n", ctx, str);
                   2986: #endif
                   2987: 
                   2988:     pyCtxt = (xmlRelaxNGValidCtxtPyCtxtPtr)ctx;
                   2989: 
                   2990:     list = PyTuple_New(2);
                   2991:     PyTuple_SetItem(list, 0, libxml_charPtrWrap(str));
                   2992:     PyTuple_SetItem(list, 1, pyCtxt->arg);
                   2993:     Py_XINCREF(pyCtxt->arg);
                   2994:     result = PyEval_CallObject(pyCtxt->error, list);
                   2995:     if (result == NULL) 
                   2996:     {
                   2997:         /* TODO: manage for the exception to be propagated... */
                   2998:         PyErr_Print();
                   2999:     }
                   3000:     Py_XDECREF(list);
                   3001:     Py_XDECREF(result);
                   3002: }
                   3003: 
                   3004: static void
                   3005: libxml_xmlRelaxNGValidityGenericWarningFuncHandler(void *ctx, char *str) 
                   3006: {
                   3007:     PyObject *list;
                   3008:     PyObject *result;
                   3009:     xmlRelaxNGValidCtxtPyCtxtPtr pyCtxt;
                   3010:     
                   3011: #ifdef DEBUG_ERROR
                   3012:     printf("libxml_xmlRelaxNGValidityGenericWarningFuncHandler(%p, %s, ...) called\n", ctx, str);
                   3013: #endif
                   3014: 
                   3015:     pyCtxt = (xmlRelaxNGValidCtxtPyCtxtPtr)ctx;
                   3016: 
                   3017:     list = PyTuple_New(2);
                   3018:     PyTuple_SetItem(list, 0, libxml_charPtrWrap(str));
                   3019:     PyTuple_SetItem(list, 1, pyCtxt->arg);
                   3020:     Py_XINCREF(pyCtxt->arg);
                   3021:     result = PyEval_CallObject(pyCtxt->warn, list);
                   3022:     if (result == NULL) 
                   3023:     {
                   3024:         /* TODO: manage for the exception to be propagated... */
                   3025:         PyErr_Print();
                   3026:     }
                   3027:     Py_XDECREF(list);
                   3028:     Py_XDECREF(result);
                   3029: }
                   3030: 
                   3031: static void
                   3032: libxml_xmlRelaxNGValidityErrorFunc(void *ctx, const char *msg, ...)
                   3033: {
                   3034:     va_list ap;
                   3035: 
                   3036:     va_start(ap, msg);
                   3037:     libxml_xmlRelaxNGValidityGenericErrorFuncHandler(ctx, libxml_buildMessage(msg, ap));
                   3038:     va_end(ap);
                   3039: }
                   3040: 
                   3041: static void
                   3042: libxml_xmlRelaxNGValidityWarningFunc(void *ctx, const char *msg, ...)
                   3043: {
                   3044:     va_list ap;
                   3045: 
                   3046:     va_start(ap, msg);
                   3047:     libxml_xmlRelaxNGValidityGenericWarningFuncHandler(ctx, libxml_buildMessage(msg, ap));
                   3048:     va_end(ap);
                   3049: }
                   3050: 
                   3051: static PyObject *
                   3052: libxml_xmlRelaxNGSetValidErrors(ATTRIBUTE_UNUSED PyObject * self, PyObject * args)
                   3053: {
                   3054:     PyObject *py_retval;
                   3055:     PyObject *pyobj_error;
                   3056:     PyObject *pyobj_warn;
                   3057:     PyObject *pyobj_ctx;
                   3058:     PyObject *pyobj_arg = Py_None;
                   3059:     xmlRelaxNGValidCtxtPtr ctxt;
                   3060:     xmlRelaxNGValidCtxtPyCtxtPtr pyCtxt;
                   3061: 
                   3062:     if (!PyArg_ParseTuple
                   3063:         (args, (char *) "OOO|O:xmlRelaxNGSetValidErrors", &pyobj_ctx, &pyobj_error, &pyobj_warn, &pyobj_arg))
                   3064:         return (NULL);
                   3065: 
                   3066: #ifdef DEBUG_ERROR
                   3067:     printf("libxml_xmlRelaxNGSetValidErrors(%p, %p, %p) called\n", pyobj_ctx, pyobj_error, pyobj_warn);
                   3068: #endif
                   3069: 
                   3070:     ctxt = PyrelaxNgValidCtxt_Get(pyobj_ctx);
                   3071:     if (xmlRelaxNGGetValidErrors(ctxt, NULL, NULL, (void **) &pyCtxt) == -1)
                   3072:     {
                   3073:         py_retval = libxml_intWrap(-1);
                   3074:         return(py_retval);
                   3075:     }
                   3076:     
                   3077:     if (pyCtxt == NULL)
                   3078:     {
                   3079:         /* first time to set the error handlers */
                   3080:         pyCtxt = xmlMalloc(sizeof(xmlRelaxNGValidCtxtPyCtxt));
                   3081:         if (pyCtxt == NULL) {
                   3082:             py_retval = libxml_intWrap(-1);
                   3083:             return(py_retval);
                   3084:         }
                   3085:         memset(pyCtxt, 0, sizeof(xmlRelaxNGValidCtxtPyCtxt));
                   3086:     }
                   3087:     
                   3088:     /* TODO: check warn and error is a function ! */
                   3089:     Py_XDECREF(pyCtxt->error);
                   3090:     Py_XINCREF(pyobj_error);
                   3091:     pyCtxt->error = pyobj_error;
                   3092:     
                   3093:     Py_XDECREF(pyCtxt->warn);
                   3094:     Py_XINCREF(pyobj_warn);
                   3095:     pyCtxt->warn = pyobj_warn;
                   3096:     
                   3097:     Py_XDECREF(pyCtxt->arg);
                   3098:     Py_XINCREF(pyobj_arg);
                   3099:     pyCtxt->arg = pyobj_arg;
                   3100: 
                   3101:     xmlRelaxNGSetValidErrors(ctxt, &libxml_xmlRelaxNGValidityErrorFunc, &libxml_xmlRelaxNGValidityWarningFunc, pyCtxt);
                   3102: 
                   3103:     py_retval = libxml_intWrap(1);
                   3104:     return (py_retval);
                   3105: }
                   3106: 
                   3107: static PyObject *
                   3108: libxml_xmlRelaxNGFreeValidCtxt(ATTRIBUTE_UNUSED PyObject *self, PyObject *args) {
                   3109:     xmlRelaxNGValidCtxtPtr ctxt;
                   3110:     xmlRelaxNGValidCtxtPyCtxtPtr pyCtxt;
                   3111:     PyObject *pyobj_ctxt;
                   3112: 
                   3113:     if (!PyArg_ParseTuple(args, (char *)"O:xmlRelaxNGFreeValidCtxt", &pyobj_ctxt))
                   3114:         return(NULL);
                   3115:     ctxt = (xmlRelaxNGValidCtxtPtr) PyrelaxNgValidCtxt_Get(pyobj_ctxt);
                   3116: 
                   3117:     if (xmlRelaxNGGetValidErrors(ctxt, NULL, NULL, (void **) &pyCtxt) == 0)
                   3118:     {
                   3119:         if (pyCtxt != NULL)
                   3120:         {
                   3121:             Py_XDECREF(pyCtxt->error);
                   3122:             Py_XDECREF(pyCtxt->warn);
                   3123:             Py_XDECREF(pyCtxt->arg);
                   3124:             xmlFree(pyCtxt);
                   3125:         }
                   3126:     }
                   3127:     
                   3128:     xmlRelaxNGFreeValidCtxt(ctxt);
                   3129:     Py_INCREF(Py_None);
                   3130:     return(Py_None);
                   3131: }
                   3132: 
                   3133: typedef struct
                   3134: {
                   3135:        PyObject *warn;
                   3136:        PyObject *error;
                   3137:        PyObject *arg;
                   3138: } xmlSchemaValidCtxtPyCtxt;
                   3139: typedef xmlSchemaValidCtxtPyCtxt *xmlSchemaValidCtxtPyCtxtPtr;
                   3140: 
                   3141: static void
                   3142: libxml_xmlSchemaValidityGenericErrorFuncHandler(void *ctx, char *str)
                   3143: {
                   3144:        PyObject *list;
                   3145:        PyObject *result;
                   3146:        xmlSchemaValidCtxtPyCtxtPtr pyCtxt;
                   3147: 
                   3148: #ifdef DEBUG_ERROR
                   3149:        printf("libxml_xmlSchemaValiditiyGenericErrorFuncHandler(%p, %s, ...) called\n", ctx, str);
                   3150: #endif
                   3151: 
                   3152:        pyCtxt = (xmlSchemaValidCtxtPyCtxtPtr) ctx;
                   3153: 
                   3154:        list = PyTuple_New(2);
                   3155:        PyTuple_SetItem(list, 0, libxml_charPtrWrap(str));
                   3156:        PyTuple_SetItem(list, 1, pyCtxt->arg);
                   3157:        Py_XINCREF(pyCtxt->arg);
                   3158:        result = PyEval_CallObject(pyCtxt->error, list);
                   3159:        if (result == NULL) 
                   3160:        {
                   3161:                /* TODO: manage for the exception to be propagated... */
                   3162:                PyErr_Print();
                   3163:        }
                   3164:        Py_XDECREF(list);
                   3165:        Py_XDECREF(result);
                   3166: }
                   3167: 
                   3168: static void
                   3169: libxml_xmlSchemaValidityGenericWarningFuncHandler(void *ctx, char *str)
                   3170: {
                   3171:        PyObject *list;
                   3172:        PyObject *result;
                   3173:        xmlSchemaValidCtxtPyCtxtPtr pyCtxt;
                   3174: 
                   3175: #ifdef DEBUG_ERROR
                   3176:        printf("libxml_xmlSchemaValidityGenericWarningFuncHandler(%p, %s, ...) called\n", ctx, str);
                   3177: #endif
                   3178:        
                   3179:        pyCtxt = (xmlSchemaValidCtxtPyCtxtPtr) ctx;
                   3180: 
                   3181:        list = PyTuple_New(2);
                   3182:        PyTuple_SetItem(list, 0, libxml_charPtrWrap(str));
                   3183:        PyTuple_SetItem(list, 1, pyCtxt->arg);
                   3184:        Py_XINCREF(pyCtxt->arg);
                   3185:        result = PyEval_CallObject(pyCtxt->warn, list);
                   3186:        if (result == NULL)
                   3187:        {
                   3188:                /* TODO: manage for the exception to be propagated... */
                   3189:                PyErr_Print();
                   3190:        }
                   3191:        Py_XDECREF(list);
                   3192:        Py_XDECREF(result);
                   3193: }
                   3194: 
                   3195: static void
                   3196: libxml_xmlSchemaValidityErrorFunc(void *ctx, const char *msg, ...)
                   3197: {
                   3198:        va_list ap;
                   3199:        
                   3200:        va_start(ap, msg);
                   3201:        libxml_xmlSchemaValidityGenericErrorFuncHandler(ctx, libxml_buildMessage(msg, ap));
                   3202:        va_end(ap);
                   3203: }
                   3204: 
                   3205: static void
                   3206: libxml_xmlSchemaValidityWarningFunc(void *ctx, const char *msg, ...)
                   3207: {
                   3208:        va_list ap;
                   3209: 
                   3210:        va_start(ap, msg);
                   3211:        libxml_xmlSchemaValidityGenericWarningFuncHandler(ctx, libxml_buildMessage(msg, ap));
                   3212:        va_end(ap);
                   3213: }
                   3214: 
                   3215: PyObject *
                   3216: libxml_xmlSchemaSetValidErrors(ATTRIBUTE_UNUSED PyObject * self, PyObject * args)
                   3217: {
                   3218:        PyObject *py_retval;
                   3219:        PyObject *pyobj_error;
                   3220:        PyObject *pyobj_warn;
                   3221:        PyObject *pyobj_ctx;
                   3222:        PyObject *pyobj_arg = Py_None;
                   3223:        xmlSchemaValidCtxtPtr ctxt;
                   3224:        xmlSchemaValidCtxtPyCtxtPtr pyCtxt;
                   3225: 
                   3226:        if (!PyArg_ParseTuple
                   3227:                (args, (char *) "OOO|O:xmlSchemaSetValidErrors", &pyobj_ctx, &pyobj_error, &pyobj_warn, &pyobj_arg))
                   3228:                return (NULL);
                   3229: 
                   3230: #ifdef DEBUG_ERROR
                   3231:        printf("libxml_xmlSchemaSetValidErrors(%p, %p, %p) called\n", pyobj_ctx, pyobj_error, pyobj_warn);
                   3232: #endif
                   3233: 
                   3234:        ctxt = PySchemaValidCtxt_Get(pyobj_ctx);
                   3235:        if (xmlSchemaGetValidErrors(ctxt, NULL, NULL, (void **) &pyCtxt) == -1)
                   3236:        {
                   3237:                py_retval = libxml_intWrap(-1);
                   3238:                return(py_retval);
                   3239:        }
                   3240: 
                   3241:        if (pyCtxt == NULL)
                   3242:        {
                   3243:                /* first time to set the error handlers */
                   3244:                pyCtxt = xmlMalloc(sizeof(xmlSchemaValidCtxtPyCtxt));
                   3245:                if (pyCtxt == NULL) {
                   3246:                        py_retval = libxml_intWrap(-1);
                   3247:                        return(py_retval);
                   3248:                }
                   3249:                memset(pyCtxt, 0, sizeof(xmlSchemaValidCtxtPyCtxt));
                   3250:        }
                   3251: 
                   3252:        /* TODO: check warn and error is a function ! */
                   3253:        Py_XDECREF(pyCtxt->error);
                   3254:        Py_XINCREF(pyobj_error);
                   3255:        pyCtxt->error = pyobj_error;
                   3256: 
                   3257:        Py_XDECREF(pyCtxt->warn);
                   3258:        Py_XINCREF(pyobj_warn);
                   3259:        pyCtxt->warn = pyobj_warn;
                   3260: 
                   3261:        Py_XDECREF(pyCtxt->arg);
                   3262:        Py_XINCREF(pyobj_arg);
                   3263:        pyCtxt->arg = pyobj_arg;
                   3264: 
                   3265:        xmlSchemaSetValidErrors(ctxt, &libxml_xmlSchemaValidityErrorFunc, &libxml_xmlSchemaValidityWarningFunc, pyCtxt);
                   3266: 
                   3267:        py_retval = libxml_intWrap(1);
                   3268:        return(py_retval);
                   3269: }
                   3270: 
                   3271: static PyObject *
                   3272: libxml_xmlSchemaFreeValidCtxt(ATTRIBUTE_UNUSED PyObject * self, PyObject * args)
                   3273: {
                   3274:        xmlSchemaValidCtxtPtr ctxt;
                   3275:        xmlSchemaValidCtxtPyCtxtPtr pyCtxt;
                   3276:        PyObject *pyobj_ctxt;
                   3277: 
                   3278:        if (!PyArg_ParseTuple(args, (char *)"O:xmlSchemaFreeValidCtxt", &pyobj_ctxt))
                   3279:                return(NULL);
                   3280:        ctxt = (xmlSchemaValidCtxtPtr) PySchemaValidCtxt_Get(pyobj_ctxt);
                   3281: 
                   3282:        if (xmlSchemaGetValidErrors(ctxt, NULL, NULL, (void **) &pyCtxt) == 0)
                   3283:        {
                   3284:                if (pyCtxt != NULL)
                   3285:                {
                   3286:                        Py_XDECREF(pyCtxt->error);
                   3287:                        Py_XDECREF(pyCtxt->warn);
                   3288:                        Py_XDECREF(pyCtxt->arg);
                   3289:                        xmlFree(pyCtxt);
                   3290:                }
                   3291:        }
                   3292: 
                   3293:        xmlSchemaFreeValidCtxt(ctxt);
                   3294:        Py_INCREF(Py_None);
                   3295:        return(Py_None);
                   3296: }
                   3297: 
                   3298: #endif
                   3299: 
                   3300: #ifdef LIBXML_C14N_ENABLED
                   3301: #ifdef LIBXML_OUTPUT_ENABLED
                   3302: 
                   3303: /************************************************************************
                   3304:  *                                                                      *
                   3305:  * XML Canonicalization c14n                                            *
                   3306:  *                                                                      *
                   3307:  ************************************************************************/
                   3308: 
                   3309: static int
                   3310: PyxmlNodeSet_Convert(PyObject *py_nodeset, xmlNodeSetPtr *result)
                   3311: {
                   3312:     xmlNodeSetPtr nodeSet;
                   3313:     int is_tuple = 0;
                   3314: 
                   3315:     if (PyTuple_Check(py_nodeset))
                   3316:         is_tuple = 1;
                   3317:     else if (PyList_Check(py_nodeset))
                   3318:         is_tuple = 0;
                   3319:     else if (py_nodeset == Py_None) {
                   3320:         *result = NULL;
                   3321:         return 0;
                   3322:     }
                   3323:     else {
                   3324:         PyErr_SetString(PyExc_TypeError,
                   3325:                         "must be a tuple or list of nodes.");
                   3326:         return -1;
                   3327:     }
                   3328: 
                   3329:     nodeSet = (xmlNodeSetPtr) xmlMalloc(sizeof(xmlNodeSet));
                   3330:     if (nodeSet == NULL) {
                   3331:         PyErr_SetString(PyExc_MemoryError, "");
                   3332:         return -1;
                   3333:     }
                   3334: 
                   3335:     nodeSet->nodeNr = 0;
                   3336:     nodeSet->nodeMax = (is_tuple
                   3337:                         ? PyTuple_GET_SIZE(py_nodeset)
                   3338:                         : PyList_GET_SIZE(py_nodeset));
                   3339:     nodeSet->nodeTab
                   3340:         = (xmlNodePtr *) xmlMalloc (nodeSet->nodeMax
                   3341:                                     * sizeof(xmlNodePtr));
                   3342:     if (nodeSet->nodeTab == NULL) {
                   3343:         xmlFree(nodeSet);
                   3344:         PyErr_SetString(PyExc_MemoryError, "");
                   3345:         return -1;
                   3346:     }
                   3347:     memset(nodeSet->nodeTab, 0 ,
                   3348:            nodeSet->nodeMax * sizeof(xmlNodePtr));
                   3349: 
                   3350:     {
                   3351:         int idx;
                   3352:         for (idx=0; idx < nodeSet->nodeMax; ++idx) {
                   3353:             xmlNodePtr pynode =
                   3354:                 PyxmlNode_Get (is_tuple
                   3355:                                ? PyTuple_GET_ITEM(py_nodeset, idx)
                   3356:                                : PyList_GET_ITEM(py_nodeset, idx));
                   3357:             if (pynode)
                   3358:                 nodeSet->nodeTab[nodeSet->nodeNr++] = pynode;
                   3359:         }
                   3360:     }
                   3361:     *result = nodeSet;
                   3362:     return 0;
                   3363: }
                   3364: 
                   3365: static int
                   3366: PystringSet_Convert(PyObject *py_strings, xmlChar *** result)
                   3367: {
                   3368:     /* NOTE: the array should be freed, but the strings are shared
                   3369:        with the python strings and so must not be freed. */
                   3370: 
                   3371:     xmlChar ** strings;
                   3372:     int is_tuple = 0;
                   3373:     int count;
                   3374:     int init_index = 0;
                   3375: 
                   3376:     if (PyTuple_Check(py_strings))
                   3377:         is_tuple = 1;
                   3378:     else if (PyList_Check(py_strings))
                   3379:         is_tuple = 0;
                   3380:     else if (py_strings == Py_None) {
                   3381:         *result = NULL;
                   3382:         return 0;
                   3383:     }
                   3384:     else {
                   3385:         PyErr_SetString(PyExc_TypeError,
                   3386:                         "must be a tuple or list of strings.");
                   3387:         return -1;
                   3388:     }
                   3389: 
                   3390:     count = (is_tuple
                   3391:              ? PyTuple_GET_SIZE(py_strings)
                   3392:              : PyList_GET_SIZE(py_strings));
                   3393: 
                   3394:     strings = (xmlChar **) xmlMalloc(sizeof(xmlChar *) * count);
                   3395: 
                   3396:     if (strings == NULL) {
                   3397:         PyErr_SetString(PyExc_MemoryError, "");
                   3398:         return -1;
                   3399:     }
                   3400: 
                   3401:     memset(strings, 0 , sizeof(xmlChar *) * count);
                   3402: 
                   3403:     {
                   3404:         int idx;
                   3405:         for (idx=0; idx < count; ++idx) {
                   3406:             char* s = PyString_AsString
                   3407:                 (is_tuple
                   3408:                  ? PyTuple_GET_ITEM(py_strings, idx)
                   3409:                  : PyList_GET_ITEM(py_strings, idx));
                   3410:             if (s)
                   3411:                 strings[init_index++] = (xmlChar *)s;
                   3412:             else {
                   3413:                 xmlFree(strings);
                   3414:                 PyErr_SetString(PyExc_TypeError,
                   3415:                                 "must be a tuple or list of strings.");
                   3416:                 return -1;
                   3417:             }
                   3418:         }
                   3419:     }
                   3420: 
                   3421:     *result = strings;
                   3422:     return 0;
                   3423: }
                   3424: 
                   3425: static PyObject *
                   3426: libxml_C14NDocDumpMemory(ATTRIBUTE_UNUSED PyObject * self,
                   3427:                          PyObject * args)
                   3428: {
                   3429:     PyObject *py_retval = NULL;
                   3430: 
                   3431:     PyObject *pyobj_doc;
                   3432:     PyObject *pyobj_nodes;
                   3433:     int exclusive;
                   3434:     PyObject *pyobj_prefixes;
                   3435:     int with_comments;
                   3436: 
                   3437:     xmlDocPtr doc;
                   3438:     xmlNodeSetPtr nodes;
                   3439:     xmlChar **prefixes = NULL;
                   3440:     xmlChar *doc_txt;
                   3441: 
                   3442:     int result;
                   3443: 
                   3444:     if (!PyArg_ParseTuple(args, (char *) "OOiOi:C14NDocDumpMemory",
                   3445:                           &pyobj_doc,
                   3446:                           &pyobj_nodes,
                   3447:                           &exclusive,
                   3448:                           &pyobj_prefixes,
                   3449:                           &with_comments))
                   3450:         return (NULL);
                   3451: 
                   3452:     doc = (xmlDocPtr) PyxmlNode_Get(pyobj_doc);
                   3453:     if (!doc) {
                   3454:         PyErr_SetString(PyExc_TypeError, "bad document.");
                   3455:         return NULL;
                   3456:     }
                   3457: 
                   3458:     result = PyxmlNodeSet_Convert(pyobj_nodes, &nodes);
                   3459:     if (result < 0) return NULL;
                   3460: 
                   3461:     if (exclusive) {
                   3462:         result = PystringSet_Convert(pyobj_prefixes, &prefixes);
                   3463:         if (result < 0) {
                   3464:             if (nodes) {
                   3465:                 xmlFree(nodes->nodeTab);
                   3466:                 xmlFree(nodes);
                   3467:             }
                   3468:             return NULL;
                   3469:         }
                   3470:     }
                   3471: 
                   3472:     result = xmlC14NDocDumpMemory(doc,
                   3473:                                   nodes,
                   3474:                                   exclusive,
                   3475:                                   prefixes,
                   3476:                                   with_comments,
                   3477:                                   &doc_txt);
                   3478: 
                   3479:     if (nodes) {
                   3480:         xmlFree(nodes->nodeTab);
                   3481:         xmlFree(nodes);
                   3482:     }
                   3483:     if (prefixes) {
                   3484:         xmlChar ** idx = prefixes;
                   3485:         while (*idx) xmlFree(*(idx++));
                   3486:         xmlFree(prefixes);
                   3487:     }
                   3488: 
                   3489:     if (result < 0) {
                   3490:         PyErr_SetString(PyExc_Exception,
                   3491:                         "libxml2 xmlC14NDocDumpMemory failure.");
                   3492:         return NULL;
                   3493:     }
                   3494:     else {
                   3495:         py_retval = PyString_FromStringAndSize((const char *) doc_txt,
                   3496:                                                result);
                   3497:         xmlFree(doc_txt);
                   3498:         return py_retval;
                   3499:     }
                   3500: }
                   3501: 
                   3502: static PyObject *
                   3503: libxml_C14NDocSaveTo(ATTRIBUTE_UNUSED PyObject * self,
                   3504:                      PyObject * args)
                   3505: {
                   3506:     PyObject *pyobj_doc;
                   3507:     PyObject *py_file;
                   3508:     PyObject *pyobj_nodes;
                   3509:     int exclusive;
                   3510:     PyObject *pyobj_prefixes;
                   3511:     int with_comments;
                   3512: 
                   3513:     xmlDocPtr doc;
                   3514:     xmlNodeSetPtr nodes;
                   3515:     xmlChar **prefixes = NULL;
                   3516:     FILE * output;
                   3517:     xmlOutputBufferPtr buf;
                   3518: 
                   3519:     int result;
                   3520:     int len;
                   3521: 
                   3522:     if (!PyArg_ParseTuple(args, (char *) "OOiOiO:C14NDocSaveTo",
                   3523:                           &pyobj_doc,
                   3524:                           &pyobj_nodes,
                   3525:                           &exclusive,
                   3526:                           &pyobj_prefixes,
                   3527:                           &with_comments,
                   3528:                           &py_file))
                   3529:         return (NULL);
                   3530: 
                   3531:     doc = (xmlDocPtr) PyxmlNode_Get(pyobj_doc);
                   3532:     if (!doc) {
                   3533:         PyErr_SetString(PyExc_TypeError, "bad document.");
                   3534:         return NULL;
                   3535:     }
                   3536: 
                   3537:     if ((py_file == NULL) || (!(PyFile_Check(py_file)))) {
                   3538:         PyErr_SetString(PyExc_TypeError, "bad file.");
                   3539:         return NULL;
                   3540:     }
                   3541:     output = PyFile_AsFile(py_file);
                   3542:     if (output == NULL) {
                   3543:         PyErr_SetString(PyExc_TypeError, "bad file.");
                   3544:         return NULL;
                   3545:     }
                   3546:     buf = xmlOutputBufferCreateFile(output, NULL);
                   3547: 
                   3548:     result = PyxmlNodeSet_Convert(pyobj_nodes, &nodes);
                   3549:     if (result < 0) return NULL;
                   3550: 
                   3551:     if (exclusive) {
                   3552:         result = PystringSet_Convert(pyobj_prefixes, &prefixes);
                   3553:         if (result < 0) {
                   3554:             if (nodes) {
                   3555:                 xmlFree(nodes->nodeTab);
                   3556:                 xmlFree(nodes);
                   3557:             }
                   3558:             return NULL;
                   3559:         }
                   3560:     }
                   3561: 
                   3562:     result = xmlC14NDocSaveTo(doc,
                   3563:                               nodes,
                   3564:                               exclusive,
                   3565:                               prefixes,
                   3566:                               with_comments,
                   3567:                               buf);
                   3568: 
                   3569:     if (nodes) {
                   3570:         xmlFree(nodes->nodeTab);
                   3571:         xmlFree(nodes);
                   3572:     }
                   3573:     if (prefixes) {
                   3574:         xmlChar ** idx = prefixes;
                   3575:         while (*idx) xmlFree(*(idx++));
                   3576:         xmlFree(prefixes);
                   3577:     }
                   3578: 
                   3579:     len = xmlOutputBufferClose(buf);
                   3580: 
                   3581:     if (result < 0) {
                   3582:         PyErr_SetString(PyExc_Exception,
                   3583:                         "libxml2 xmlC14NDocSaveTo failure.");
                   3584:         return NULL;
                   3585:     }
                   3586:     else
                   3587:         return PyInt_FromLong((long) len);
                   3588: }
                   3589: 
                   3590: #endif
                   3591: #endif
                   3592: 
                   3593: static PyObject *
                   3594: libxml_getObjDesc(PyObject *self ATTRIBUTE_UNUSED, PyObject *args) {
                   3595: 
                   3596:     PyObject *obj;
                   3597:     char *str;
                   3598: 
                   3599:     if (!PyArg_ParseTuple(args, (char *)"O:getObjDesc", &obj))
                   3600:         return NULL;
                   3601:     str = PyCObject_GetDesc(obj);
                   3602:     return Py_BuildValue((char *)"s", str);
                   3603: }
                   3604: 
                   3605: static PyObject *
                   3606: libxml_compareNodesEqual(PyObject *self ATTRIBUTE_UNUSED, PyObject *args) {
                   3607:     
                   3608:     PyObject *py_node1, *py_node2;
                   3609:     xmlNodePtr node1, node2;
                   3610: 
                   3611:     if (!PyArg_ParseTuple(args, (char *)"OO:compareNodesEqual",
                   3612:                &py_node1, &py_node2))
                   3613:         return NULL;
                   3614:     /* To compare two node objects, we compare their pointer addresses */
                   3615:     node1 = PyxmlNode_Get(py_node1);
                   3616:     node2 = PyxmlNode_Get(py_node2);
                   3617:     if ( node1 == node2 )
                   3618:         return Py_BuildValue((char *)"i", 1);
                   3619:     else
                   3620:         return Py_BuildValue((char *)"i", 0);
                   3621:     
                   3622: }
                   3623: 
                   3624: static PyObject *
                   3625: libxml_nodeHash(PyObject *self ATTRIBUTE_UNUSED, PyObject *args) {
                   3626: 
                   3627:     PyObject *py_node1;
                   3628:     xmlNodePtr node1;
                   3629: 
                   3630:     if (!PyArg_ParseTuple(args, (char *)"O:nodeHash", &py_node1))
                   3631:            return NULL;
                   3632:     /* For simplicity, we use the node pointer address as a hash value */
                   3633:     node1 = PyxmlNode_Get(py_node1);
                   3634: 
                   3635:     return PyLong_FromVoidPtr(node1);
                   3636: 
                   3637: }
                   3638: 
                   3639: /************************************************************************
                   3640:  *                                                                     *
                   3641:  *                     The registration stuff                          *
                   3642:  *                                                                     *
                   3643:  ************************************************************************/
                   3644: static PyMethodDef libxmlMethods[] = {
                   3645: #include "libxml2-export.c"
                   3646:     {(char *) "name", libxml_name, METH_VARARGS, NULL},
                   3647:     {(char *) "children", libxml_children, METH_VARARGS, NULL},
                   3648:     {(char *) "properties", libxml_properties, METH_VARARGS, NULL},
                   3649:     {(char *) "last", libxml_last, METH_VARARGS, NULL},
                   3650:     {(char *) "prev", libxml_prev, METH_VARARGS, NULL},
                   3651:     {(char *) "next", libxml_next, METH_VARARGS, NULL},
                   3652:     {(char *) "parent", libxml_parent, METH_VARARGS, NULL},
                   3653:     {(char *) "type", libxml_type, METH_VARARGS, NULL},
                   3654:     {(char *) "doc", libxml_doc, METH_VARARGS, NULL},
                   3655:     {(char *) "xmlNewNode", libxml_xmlNewNode, METH_VARARGS, NULL},
                   3656:     {(char *) "xmlNodeRemoveNsDef", libxml_xmlNodeRemoveNsDef, METH_VARARGS, NULL},
                   3657:     {(char *)"xmlSetValidErrors", libxml_xmlSetValidErrors, METH_VARARGS, NULL},
                   3658:     {(char *)"xmlFreeValidCtxt", libxml_xmlFreeValidCtxt, METH_VARARGS, NULL},
                   3659: #ifdef LIBXML_OUTPUT_ENABLED
                   3660:     {(char *) "serializeNode", libxml_serializeNode, METH_VARARGS, NULL},
                   3661:     {(char *) "saveNodeTo", libxml_saveNodeTo, METH_VARARGS, NULL},
                   3662:     {(char *) "outputBufferCreate", libxml_xmlCreateOutputBuffer, METH_VARARGS, NULL},
                   3663:     {(char *) "outputBufferGetPythonFile", libxml_outputBufferGetPythonFile, METH_VARARGS, NULL},
                   3664:     {(char *) "xmlOutputBufferClose", libxml_xmlOutputBufferClose, METH_VARARGS, NULL},
                   3665:     { (char *)"xmlOutputBufferFlush", libxml_xmlOutputBufferFlush, METH_VARARGS, NULL },
                   3666:     { (char *)"xmlSaveFileTo", libxml_xmlSaveFileTo, METH_VARARGS, NULL },
                   3667:     { (char *)"xmlSaveFormatFileTo", libxml_xmlSaveFormatFileTo, METH_VARARGS, NULL },
                   3668: #endif /* LIBXML_OUTPUT_ENABLED */
                   3669:     {(char *) "inputBufferCreate", libxml_xmlCreateInputBuffer, METH_VARARGS, NULL},
                   3670:     {(char *) "setEntityLoader", libxml_xmlSetEntityLoader, METH_VARARGS, NULL},
                   3671:     {(char *)"xmlRegisterErrorHandler", libxml_xmlRegisterErrorHandler, METH_VARARGS, NULL },
                   3672:     {(char *)"xmlParserCtxtSetErrorHandler", libxml_xmlParserCtxtSetErrorHandler, METH_VARARGS, NULL },
                   3673:     {(char *)"xmlParserCtxtGetErrorHandler", libxml_xmlParserCtxtGetErrorHandler, METH_VARARGS, NULL },
                   3674:     {(char *)"xmlFreeParserCtxt", libxml_xmlFreeParserCtxt, METH_VARARGS, NULL },
                   3675: #ifdef LIBXML_READER_ENABLED
                   3676:     {(char *)"xmlTextReaderSetErrorHandler", libxml_xmlTextReaderSetErrorHandler, METH_VARARGS, NULL },
                   3677:     {(char *)"xmlTextReaderGetErrorHandler", libxml_xmlTextReaderGetErrorHandler, METH_VARARGS, NULL },
                   3678:     {(char *)"xmlFreeTextReader", libxml_xmlFreeTextReader, METH_VARARGS, NULL },
                   3679: #endif
                   3680:     {(char *)"addLocalCatalog", libxml_addLocalCatalog, METH_VARARGS, NULL },
                   3681: #ifdef LIBXML_SCHEMAS_ENABLED
                   3682:     {(char *)"xmlRelaxNGSetValidErrors", libxml_xmlRelaxNGSetValidErrors, METH_VARARGS, NULL},
                   3683:     {(char *)"xmlRelaxNGFreeValidCtxt", libxml_xmlRelaxNGFreeValidCtxt, METH_VARARGS, NULL},
                   3684:     {(char *)"xmlSchemaSetValidErrors", libxml_xmlSchemaSetValidErrors, METH_VARARGS, NULL},
                   3685:     {(char *)"xmlSchemaFreeValidCtxt", libxml_xmlSchemaFreeValidCtxt, METH_VARARGS, NULL},
                   3686: #endif
                   3687: #ifdef LIBXML_C14N_ENABLED
                   3688: #ifdef LIBXML_OUTPUT_ENABLED
                   3689:     {(char *)"xmlC14NDocDumpMemory", libxml_C14NDocDumpMemory, METH_VARARGS, NULL},
                   3690:     {(char *)"xmlC14NDocSaveTo", libxml_C14NDocSaveTo, METH_VARARGS, NULL},
                   3691: #endif
                   3692: #endif
                   3693:     {(char *) "getObjDesc", libxml_getObjDesc, METH_VARARGS, NULL},
                   3694:     {(char *) "compareNodesEqual", libxml_compareNodesEqual, METH_VARARGS, NULL},
                   3695:     {(char *) "nodeHash", libxml_nodeHash, METH_VARARGS, NULL},
                   3696:     {NULL, NULL, 0, NULL}
                   3697: };
                   3698: 
                   3699: #ifdef MERGED_MODULES
                   3700: extern void initlibxsltmod(void);
                   3701: #endif
                   3702: 
                   3703: void
                   3704: initlibxml2mod(void)
                   3705: {
                   3706:     static int initialized = 0;
                   3707: 
                   3708:     if (initialized != 0)
                   3709:         return;
                   3710: 
                   3711:     /* intialize the python extension module */
                   3712:     Py_InitModule((char *) "libxml2mod", libxmlMethods);
                   3713: 
                   3714:     /* initialize libxml2 */
                   3715:     xmlInitParser();
                   3716:     libxml_xmlErrorInitialize();
                   3717: 
                   3718:     initialized = 1;
                   3719: 
                   3720: #ifdef MERGED_MODULES
                   3721:     initlibxsltmod();
                   3722: #endif
                   3723: }

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>