~ubuntu-branches/ubuntu/utopic/libxml2/utopic

« back to all changes in this revision

Viewing changes to .pc/0004-Fix-missing-break-on-last-function-for-attributes.patch/python/libxml.c

  • Committer: Package Import Robot
  • Author(s): Aron Xu, Christian Svensson, Daniel Schepler, Helmut Grohne, Adam Conrad, Matthias Klose, Aron Xu
  • Date: 2014-07-09 05:40:15 UTC
  • mto: This revision was merged to the branch mainline in revision 75.
  • Revision ID: package-import@ubuntu.com-20140709054015-rdnfjxrf3zvmw6l7
[ Christian Svensson ]
* Do not build-depend on readline (Closes: #742350)

[ Daniel Schepler ]
* Patch to bootstrap without python (Closes: #738080)

[ Helmut Grohne ]
* Drop unneeded B-D on perl and binutils (Closes: #753005)

[ Adam Conrad ]
* Actually run dh_autoreconf, which the old/new mixed rules file misses.

[ Matthias Klose ]
* Add patch to fix python multiarch issue
* Allow the package to cross-build by tweaking B-Ds on python
* Set PYTHON_LIBS for cross builds

[ Aron Xu ]
* Use correct $CC
* Configure udeb without python
* New round of cherry-picking upstream fixes
  - Includes fixes for CVE-2014-0191 (Closes: #747309).
* Call prename with -vf
* Require python-all-dev (>= 2.7.5-5~)
* Bump std-ver: 3.9.4 -> 3.9.5, no change

Show diffs side-by-side

added added

removed removed

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