~ubuntu-branches/ubuntu/wily/opencollada/wily-proposed

« back to all changes in this revision

Viewing changes to Externals/LibXML/python/libxml.c

  • Committer: Package Import Robot
  • Author(s): Matteo F. Vescovi
  • Date: 2015-05-14 17:23:27 UTC
  • Revision ID: package-import@ubuntu.com-20150514172327-f862u8envms01fra
Tags: upstream-0.1.0~20140703.ddf8f47+dfsg1
ImportĀ upstreamĀ versionĀ 0.1.0~20140703.ddf8f47+dfsg1

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