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

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

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