17eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel#include "Python.h"
27eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel#include <ctype.h>
37eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
47eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel#include "frameobject.h"
57eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel#include "expat.h"
67eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
77eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel#include "pyexpat.h"
87eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
97eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel#define XML_COMBINED_VERSION (10000*XML_MAJOR_VERSION+100*XML_MINOR_VERSION+XML_MICRO_VERSION)
107eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
117eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel#ifndef PyDoc_STRVAR
127eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
137eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel/*
147eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel * fdrake says:
157eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel * Don't change the PyDoc_STR macro definition to (str), because
167eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel * '''the parentheses cause compile failures
177eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel * ("non-constant static initializer" or something like that)
187eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel * on some platforms (Irix?)'''
197eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel */
207eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel#define PyDoc_STR(str)         str
217eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel#define PyDoc_VAR(name)        static char name[]
227eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel#define PyDoc_STRVAR(name,str) PyDoc_VAR(name) = PyDoc_STR(str)
237eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel#endif
247eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
257eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel#if (PY_MAJOR_VERSION == 2 && PY_MINOR_VERSION < 2)
267eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel/* In Python 2.0 and  2.1, disabling Unicode was not possible. */
277eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel#define Py_USING_UNICODE
287eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel#else
297eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel#define FIX_TRACE
307eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel#endif
317eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
327eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielenum HandlerTypes {
337eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    StartElement,
347eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    EndElement,
357eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    ProcessingInstruction,
367eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    CharacterData,
377eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    UnparsedEntityDecl,
387eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    NotationDecl,
397eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    StartNamespaceDecl,
407eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    EndNamespaceDecl,
417eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    Comment,
427eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    StartCdataSection,
437eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    EndCdataSection,
447eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    Default,
457eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    DefaultHandlerExpand,
467eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    NotStandalone,
477eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    ExternalEntityRef,
487eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    StartDoctypeDecl,
497eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    EndDoctypeDecl,
507eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    EntityDecl,
517eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    XmlDecl,
527eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    ElementDecl,
537eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    AttlistDecl,
547eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel#if XML_COMBINED_VERSION >= 19504
557eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    SkippedEntity,
567eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel#endif
577eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    _DummyDecl
587eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel};
597eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
607eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielstatic PyObject *ErrorObject;
617eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
627eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel/* ----------------------------------------------------- */
637eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
647eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel/* Declarations for objects of type xmlparser */
657eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
667eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanieltypedef struct {
677eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    PyObject_HEAD
687eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
697eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    XML_Parser itself;
707eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    int returns_unicode;        /* True if Unicode strings are returned;
717eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                                   if false, UTF-8 strings are returned */
727eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    int ordered_attributes;     /* Return attributes as a list. */
737eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    int specified_attributes;   /* Report only specified attributes. */
747eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    int in_callback;            /* Is a callback active? */
757eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    int ns_prefixes;            /* Namespace-triplets mode? */
767eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    XML_Char *buffer;           /* Buffer used when accumulating characters */
777eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                                /* NULL if not enabled */
787eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    int buffer_size;            /* Size of buffer, in XML_Char units */
797eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    int buffer_used;            /* Buffer units in use */
807eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    PyObject *intern;           /* Dictionary to intern strings */
817eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    PyObject **handlers;
827eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel} xmlparseobject;
837eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
847eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel#define CHARACTER_DATA_BUFFER_SIZE 8192
857eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
867eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielstatic PyTypeObject Xmlparsetype;
877eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
887eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanieltypedef void (*xmlhandlersetter)(XML_Parser self, void *meth);
897eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanieltypedef void* xmlhandler;
907eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
917eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielstruct HandlerInfo {
927eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    const char *name;
937eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    xmlhandlersetter setter;
947eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    xmlhandler handler;
957eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    PyCodeObject *tb_code;
967eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    PyObject *nameobj;
977eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel};
987eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
997eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielstatic struct HandlerInfo handler_info[64];
1007eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
1017eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel/* Set an integer attribute on the error object; return true on success,
1027eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel * false on an exception.
1037eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel */
1047eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielstatic int
1057eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielset_error_attr(PyObject *err, char *name, int value)
1067eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel{
1077eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    PyObject *v = PyInt_FromLong(value);
1087eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
1097eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    if (v == NULL || PyObject_SetAttrString(err, name, v) == -1) {
1107eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        Py_XDECREF(v);
1117eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        return 0;
1127eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    }
1137eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    Py_DECREF(v);
1147eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    return 1;
1157eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel}
1167eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
1177eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel/* Build and set an Expat exception, including positioning
1187eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel * information.  Always returns NULL.
1197eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel */
1207eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielstatic PyObject *
1217eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielset_error(xmlparseobject *self, enum XML_Error code)
1227eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel{
1237eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    PyObject *err;
1247eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    char buffer[256];
1257eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    XML_Parser parser = self->itself;
1267eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    int lineno = XML_GetErrorLineNumber(parser);
1277eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    int column = XML_GetErrorColumnNumber(parser);
1287eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
1297eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    /* There is no risk of overflowing this buffer, since
1307eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel       even for 64-bit integers, there is sufficient space. */
1317eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    sprintf(buffer, "%.200s: line %i, column %i",
1327eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            XML_ErrorString(code), lineno, column);
1337eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    err = PyObject_CallFunction(ErrorObject, "s", buffer);
1347eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    if (  err != NULL
1357eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel          && set_error_attr(err, "code", code)
1367eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel          && set_error_attr(err, "offset", column)
1377eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel          && set_error_attr(err, "lineno", lineno)) {
1387eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        PyErr_SetObject(ErrorObject, err);
1397eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    }
1407eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    Py_XDECREF(err);
1417eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    return NULL;
1427eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel}
1437eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
1447eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielstatic int
1457eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielhave_handler(xmlparseobject *self, int type)
1467eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel{
1477eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    PyObject *handler = self->handlers[type];
1487eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    return handler != NULL;
1497eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel}
1507eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
1517eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielstatic PyObject *
1527eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielget_handler_name(struct HandlerInfo *hinfo)
1537eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel{
1547eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    PyObject *name = hinfo->nameobj;
1557eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    if (name == NULL) {
1567eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        name = PyString_FromString(hinfo->name);
1577eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        hinfo->nameobj = name;
1587eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    }
1597eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    Py_XINCREF(name);
1607eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    return name;
1617eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel}
1627eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
1637eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
1647eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel#ifdef Py_USING_UNICODE
1657eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel/* Convert a string of XML_Chars into a Unicode string.
1667eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel   Returns None if str is a null pointer. */
1677eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
1687eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielstatic PyObject *
1697eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielconv_string_to_unicode(const XML_Char *str)
1707eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel{
1717eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    /* XXX currently this code assumes that XML_Char is 8-bit,
1727eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel       and hence in UTF-8.  */
1737eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    /* UTF-8 from Expat, Unicode desired */
1747eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    if (str == NULL) {
1757eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        Py_INCREF(Py_None);
1767eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        return Py_None;
1777eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    }
1787eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    return PyUnicode_DecodeUTF8(str, strlen(str), "strict");
1797eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel}
1807eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
1817eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielstatic PyObject *
1827eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielconv_string_len_to_unicode(const XML_Char *str, int len)
1837eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel{
1847eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    /* XXX currently this code assumes that XML_Char is 8-bit,
1857eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel       and hence in UTF-8.  */
1867eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    /* UTF-8 from Expat, Unicode desired */
1877eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    if (str == NULL) {
1887eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        Py_INCREF(Py_None);
1897eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        return Py_None;
1907eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    }
1917eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    return PyUnicode_DecodeUTF8((const char *)str, len, "strict");
1927eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel}
1937eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel#endif
1947eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
1957eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel/* Convert a string of XML_Chars into an 8-bit Python string.
1967eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel   Returns None if str is a null pointer. */
1977eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
1987eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielstatic PyObject *
1997eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielconv_string_to_utf8(const XML_Char *str)
2007eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel{
2017eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    /* XXX currently this code assumes that XML_Char is 8-bit,
2027eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel       and hence in UTF-8.  */
2037eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    /* UTF-8 from Expat, UTF-8 desired */
2047eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    if (str == NULL) {
2057eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        Py_INCREF(Py_None);
2067eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        return Py_None;
2077eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    }
2087eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    return PyString_FromString(str);
2097eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel}
2107eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
2117eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielstatic PyObject *
2127eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielconv_string_len_to_utf8(const XML_Char *str, int len)
2137eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel{
2147eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    /* XXX currently this code assumes that XML_Char is 8-bit,
2157eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel       and hence in UTF-8.  */
2167eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    /* UTF-8 from Expat, UTF-8 desired */
2177eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    if (str == NULL) {
2187eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        Py_INCREF(Py_None);
2197eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        return Py_None;
2207eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    }
2217eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    return PyString_FromStringAndSize((const char *)str, len);
2227eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel}
2237eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
2247eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel/* Callback routines */
2257eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
2267eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielstatic void clear_handlers(xmlparseobject *self, int initial);
2277eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
2287eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel/* This handler is used when an error has been detected, in the hope
2297eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel   that actual parsing can be terminated early.  This will only help
2307eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel   if an external entity reference is encountered. */
2317eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielstatic int
2327eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielerror_external_entity_ref_handler(XML_Parser parser,
2337eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                                  const XML_Char *context,
2347eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                                  const XML_Char *base,
2357eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                                  const XML_Char *systemId,
2367eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                                  const XML_Char *publicId)
2377eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel{
2387eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    return 0;
2397eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel}
2407eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
2417eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel/* Dummy character data handler used when an error (exception) has
2427eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel   been detected, and the actual parsing can be terminated early.
2437eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel   This is needed since character data handler can't be safely removed
2447eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel   from within the character data handler, but can be replaced.  It is
2457eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel   used only from the character data handler trampoline, and must be
2467eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel   used right after `flag_error()` is called. */
2477eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielstatic void
2487eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielnoop_character_data_handler(void *userData, const XML_Char *data, int len)
2497eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel{
2507eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    /* Do nothing. */
2517eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel}
2527eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
2537eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielstatic void
2547eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielflag_error(xmlparseobject *self)
2557eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel{
2567eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    clear_handlers(self, 0);
2577eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    XML_SetExternalEntityRefHandler(self->itself,
2587eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                                    error_external_entity_ref_handler);
2597eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel}
2607eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
2617eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielstatic PyCodeObject*
2627eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielgetcode(enum HandlerTypes slot, char* func_name, int lineno)
2637eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel{
2647eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    if (handler_info[slot].tb_code == NULL) {
2657eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        handler_info[slot].tb_code =
2667eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            PyCode_NewEmpty(__FILE__, func_name, lineno);
2677eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    }
2687eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    return handler_info[slot].tb_code;
2697eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel}
2707eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
2717eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel#ifdef FIX_TRACE
2727eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielstatic int
2737eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanieltrace_frame(PyThreadState *tstate, PyFrameObject *f, int code, PyObject *val)
2747eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel{
2757eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    int result = 0;
2767eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    if (!tstate->use_tracing || tstate->tracing)
2777eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        return 0;
2787eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    if (tstate->c_profilefunc != NULL) {
2797eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        tstate->tracing++;
2807eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        result = tstate->c_profilefunc(tstate->c_profileobj,
2817eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                                       f, code , val);
2827eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        tstate->use_tracing = ((tstate->c_tracefunc != NULL)
2837eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                               || (tstate->c_profilefunc != NULL));
2847eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        tstate->tracing--;
2857eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        if (result)
2867eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            return result;
2877eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    }
2887eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    if (tstate->c_tracefunc != NULL) {
2897eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        tstate->tracing++;
2907eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        result = tstate->c_tracefunc(tstate->c_traceobj,
2917eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                                     f, code , val);
2927eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        tstate->use_tracing = ((tstate->c_tracefunc != NULL)
2937eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                               || (tstate->c_profilefunc != NULL));
2947eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        tstate->tracing--;
2957eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    }
2967eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    return result;
2977eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel}
2987eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
2997eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielstatic int
3007eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanieltrace_frame_exc(PyThreadState *tstate, PyFrameObject *f)
3017eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel{
3027eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    PyObject *type, *value, *traceback, *arg;
3037eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    int err;
3047eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
3057eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    if (tstate->c_tracefunc == NULL)
3067eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        return 0;
3077eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
3087eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    PyErr_Fetch(&type, &value, &traceback);
3097eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    if (value == NULL) {
3107eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        value = Py_None;
3117eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        Py_INCREF(value);
3127eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    }
3137eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel#if PY_VERSION_HEX < 0x02040000
3147eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    arg = Py_BuildValue("(OOO)", type, value, traceback);
3157eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel#else
3167eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    arg = PyTuple_Pack(3, type, value, traceback);
3177eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel#endif
3187eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    if (arg == NULL) {
3197eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        PyErr_Restore(type, value, traceback);
3207eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        return 0;
3217eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    }
3227eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    err = trace_frame(tstate, f, PyTrace_EXCEPTION, arg);
3237eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    Py_DECREF(arg);
3247eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    if (err == 0)
3257eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        PyErr_Restore(type, value, traceback);
3267eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    else {
3277eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        Py_XDECREF(type);
3287eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        Py_XDECREF(value);
3297eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        Py_XDECREF(traceback);
3307eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    }
3317eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    return err;
3327eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel}
3337eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel#endif
3347eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
3357eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielstatic PyObject*
3367eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielcall_with_frame(PyCodeObject *c, PyObject* func, PyObject* args,
3377eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                xmlparseobject *self)
3387eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel{
3397eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    PyThreadState *tstate = PyThreadState_GET();
3407eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    PyFrameObject *f;
3417eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    PyObject *res;
3427eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
3437eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    if (c == NULL)
3447eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        return NULL;
3457eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
3467eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    f = PyFrame_New(tstate, c, PyEval_GetGlobals(), NULL);
3477eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    if (f == NULL)
3487eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        return NULL;
3497eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    tstate->frame = f;
3507eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel#ifdef FIX_TRACE
3517eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    if (trace_frame(tstate, f, PyTrace_CALL, Py_None) < 0) {
3527eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        return NULL;
3537eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    }
3547eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel#endif
3557eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    res = PyEval_CallObject(func, args);
3567eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    if (res == NULL) {
3577eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        if (tstate->curexc_traceback == NULL)
3587eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            PyTraceBack_Here(f);
3597eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        XML_StopParser(self->itself, XML_FALSE);
3607eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel#ifdef FIX_TRACE
3617eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        if (trace_frame_exc(tstate, f) < 0) {
3627eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            return NULL;
3637eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        }
3647eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    }
3657eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    else {
3667eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        if (trace_frame(tstate, f, PyTrace_RETURN, res) < 0) {
3677eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            Py_XDECREF(res);
3687eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            res = NULL;
3697eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        }
3707eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    }
3717eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel#else
3727eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    }
3737eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel#endif
3747eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    tstate->frame = f->f_back;
3757eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    Py_DECREF(f);
3767eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    return res;
3777eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel}
3787eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
3797eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel#ifndef Py_USING_UNICODE
3807eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel#define STRING_CONV_FUNC conv_string_to_utf8
3817eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel#else
3827eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel/* Python 2.0 and later versions, when built with Unicode support */
3837eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel#define STRING_CONV_FUNC (self->returns_unicode \
3847eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                          ? conv_string_to_unicode : conv_string_to_utf8)
3857eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel#endif
3867eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
3877eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielstatic PyObject*
3887eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielstring_intern(xmlparseobject *self, const char* str)
3897eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel{
3907eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    PyObject *result = STRING_CONV_FUNC(str);
3917eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    PyObject *value;
3927eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    /* result can be NULL if the unicode conversion failed. */
3937eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    if (!result)
3947eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        return result;
3957eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    if (!self->intern)
3967eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        return result;
3977eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    value = PyDict_GetItem(self->intern, result);
3987eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    if (!value) {
3997eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        if (PyDict_SetItem(self->intern, result, result) == 0)
4007eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            return result;
4017eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        else
4027eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            return NULL;
4037eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    }
4047eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    Py_INCREF(value);
4057eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    Py_DECREF(result);
4067eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    return value;
4077eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel}
4087eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
4097eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel/* Return 0 on success, -1 on exception.
4107eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel * flag_error() will be called before return if needed.
4117eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel */
4127eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielstatic int
4137eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielcall_character_handler(xmlparseobject *self, const XML_Char *buffer, int len)
4147eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel{
4157eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    PyObject *args;
4167eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    PyObject *temp;
4177eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
4187eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    if (!have_handler(self, CharacterData))
4197eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        return -1;
4207eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
4217eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    args = PyTuple_New(1);
4227eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    if (args == NULL)
4237eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        return -1;
4247eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel#ifdef Py_USING_UNICODE
4257eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    temp = (self->returns_unicode
4267eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            ? conv_string_len_to_unicode(buffer, len)
4277eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            : conv_string_len_to_utf8(buffer, len));
4287eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel#else
4297eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    temp = conv_string_len_to_utf8(buffer, len);
4307eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel#endif
4317eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    if (temp == NULL) {
4327eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        Py_DECREF(args);
4337eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        flag_error(self);
4347eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        XML_SetCharacterDataHandler(self->itself,
4357eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                                    noop_character_data_handler);
4367eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        return -1;
4377eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    }
4387eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    PyTuple_SET_ITEM(args, 0, temp);
4397eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    /* temp is now a borrowed reference; consider it unused. */
4407eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    self->in_callback = 1;
4417eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    temp = call_with_frame(getcode(CharacterData, "CharacterData", __LINE__),
4427eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                           self->handlers[CharacterData], args, self);
4437eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    /* temp is an owned reference again, or NULL */
4447eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    self->in_callback = 0;
4457eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    Py_DECREF(args);
4467eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    if (temp == NULL) {
4477eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        flag_error(self);
4487eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        XML_SetCharacterDataHandler(self->itself,
4497eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                                    noop_character_data_handler);
4507eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        return -1;
4517eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    }
4527eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    Py_DECREF(temp);
4537eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    return 0;
4547eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel}
4557eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
4567eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielstatic int
4577eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielflush_character_buffer(xmlparseobject *self)
4587eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel{
4597eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    int rc;
4607eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    if (self->buffer == NULL || self->buffer_used == 0)
4617eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        return 0;
4627eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    rc = call_character_handler(self, self->buffer, self->buffer_used);
4637eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    self->buffer_used = 0;
4647eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    return rc;
4657eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel}
4667eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
4677eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielstatic void
4687eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielmy_CharacterDataHandler(void *userData, const XML_Char *data, int len)
4697eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel{
4707eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    xmlparseobject *self = (xmlparseobject *) userData;
4717eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    if (self->buffer == NULL)
4727eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        call_character_handler(self, data, len);
4737eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    else {
4747eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        if ((self->buffer_used + len) > self->buffer_size) {
4757eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            if (flush_character_buffer(self) < 0)
4767eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                return;
4777eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            /* handler might have changed; drop the rest on the floor
4787eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel             * if there isn't a handler anymore
4797eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel             */
4807eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            if (!have_handler(self, CharacterData))
4817eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                return;
4827eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        }
4837eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        if (len > self->buffer_size) {
4847eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            call_character_handler(self, data, len);
4857eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            self->buffer_used = 0;
4867eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        }
4877eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        else {
4887eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            memcpy(self->buffer + self->buffer_used,
4897eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                   data, len * sizeof(XML_Char));
4907eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            self->buffer_used += len;
4917eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        }
4927eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    }
4937eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel}
4947eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
4957eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielstatic void
4967eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielmy_StartElementHandler(void *userData,
4977eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                       const XML_Char *name, const XML_Char *atts[])
4987eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel{
4997eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    xmlparseobject *self = (xmlparseobject *)userData;
5007eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
5017eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    if (have_handler(self, StartElement)) {
5027eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        PyObject *container, *rv, *args;
5037eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        int i, max;
5047eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
5057eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        if (flush_character_buffer(self) < 0)
5067eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            return;
5077eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        /* Set max to the number of slots filled in atts[]; max/2 is
5087eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel         * the number of attributes we need to process.
5097eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel         */
5107eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        if (self->specified_attributes) {
5117eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            max = XML_GetSpecifiedAttributeCount(self->itself);
5127eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        }
5137eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        else {
5147eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            max = 0;
5157eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            while (atts[max] != NULL)
5167eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                max += 2;
5177eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        }
5187eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        /* Build the container. */
5197eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        if (self->ordered_attributes)
5207eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            container = PyList_New(max);
5217eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        else
5227eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            container = PyDict_New();
5237eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        if (container == NULL) {
5247eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            flag_error(self);
5257eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            return;
5267eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        }
5277eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        for (i = 0; i < max; i += 2) {
5287eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            PyObject *n = string_intern(self, (XML_Char *) atts[i]);
5297eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            PyObject *v;
5307eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            if (n == NULL) {
5317eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                flag_error(self);
5327eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                Py_DECREF(container);
5337eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                return;
5347eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            }
5357eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            v = STRING_CONV_FUNC((XML_Char *) atts[i+1]);
5367eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            if (v == NULL) {
5377eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                flag_error(self);
5387eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                Py_DECREF(container);
5397eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                Py_DECREF(n);
5407eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                return;
5417eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            }
5427eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            if (self->ordered_attributes) {
5437eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                PyList_SET_ITEM(container, i, n);
5447eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                PyList_SET_ITEM(container, i+1, v);
5457eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            }
5467eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            else if (PyDict_SetItem(container, n, v)) {
5477eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                flag_error(self);
5487eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                Py_DECREF(n);
5497eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                Py_DECREF(v);
5507eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                return;
5517eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            }
5527eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            else {
5537eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                Py_DECREF(n);
5547eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                Py_DECREF(v);
5557eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            }
5567eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        }
5577eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        args = string_intern(self, name);
5587eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        if (args != NULL)
5597eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            args = Py_BuildValue("(NN)", args, container);
5607eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        if (args == NULL) {
5617eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            Py_DECREF(container);
5627eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            return;
5637eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        }
5647eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        /* Container is now a borrowed reference; ignore it. */
5657eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        self->in_callback = 1;
5667eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        rv = call_with_frame(getcode(StartElement, "StartElement", __LINE__),
5677eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                             self->handlers[StartElement], args, self);
5687eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        self->in_callback = 0;
5697eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        Py_DECREF(args);
5707eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        if (rv == NULL) {
5717eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            flag_error(self);
5727eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            return;
5737eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        }
5747eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        Py_DECREF(rv);
5757eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    }
5767eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel}
5777eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
5787eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel#define RC_HANDLER(RC, NAME, PARAMS, INIT, PARAM_FORMAT, CONVERSION, \
5797eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                RETURN, GETUSERDATA) \
5807eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielstatic RC \
5817eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielmy_##NAME##Handler PARAMS {\
5827eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    xmlparseobject *self = GETUSERDATA ; \
5837eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    PyObject *args = NULL; \
5847eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    PyObject *rv = NULL; \
5857eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    INIT \
5867eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel\
5877eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    if (have_handler(self, NAME)) { \
5887eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        if (flush_character_buffer(self) < 0) \
5897eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            return RETURN; \
5907eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        args = Py_BuildValue PARAM_FORMAT ;\
5917eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        if (!args) { flag_error(self); return RETURN;} \
5927eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        self->in_callback = 1; \
5937eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        rv = call_with_frame(getcode(NAME,#NAME,__LINE__), \
5947eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                             self->handlers[NAME], args, self); \
5957eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        self->in_callback = 0; \
5967eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        Py_DECREF(args); \
5977eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        if (rv == NULL) { \
5987eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            flag_error(self); \
5997eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            return RETURN; \
6007eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        } \
6017eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        CONVERSION \
6027eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        Py_DECREF(rv); \
6037eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    } \
6047eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    return RETURN; \
6057eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel}
6067eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
6077eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel#define VOID_HANDLER(NAME, PARAMS, PARAM_FORMAT) \
6087eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        RC_HANDLER(void, NAME, PARAMS, ;, PARAM_FORMAT, ;, ;,\
6097eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        (xmlparseobject *)userData)
6107eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
6117eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel#define INT_HANDLER(NAME, PARAMS, PARAM_FORMAT)\
6127eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        RC_HANDLER(int, NAME, PARAMS, int rc=0;, PARAM_FORMAT, \
6137eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                        rc = PyInt_AsLong(rv);, rc, \
6147eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        (xmlparseobject *)userData)
6157eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
6167eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielVOID_HANDLER(EndElement,
6177eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel             (void *userData, const XML_Char *name),
6187eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel             ("(N)", string_intern(self, name)))
6197eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
6207eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielVOID_HANDLER(ProcessingInstruction,
6217eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel             (void *userData,
6227eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel              const XML_Char *target,
6237eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel              const XML_Char *data),
6247eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel             ("(NO&)", string_intern(self, target), STRING_CONV_FUNC,data))
6257eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
6267eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielVOID_HANDLER(UnparsedEntityDecl,
6277eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel             (void *userData,
6287eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel              const XML_Char *entityName,
6297eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel              const XML_Char *base,
6307eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel              const XML_Char *systemId,
6317eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel              const XML_Char *publicId,
6327eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel              const XML_Char *notationName),
6337eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel             ("(NNNNN)",
6347eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel              string_intern(self, entityName), string_intern(self, base),
6357eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel              string_intern(self, systemId), string_intern(self, publicId),
6367eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel              string_intern(self, notationName)))
6377eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
6387eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel#ifndef Py_USING_UNICODE
6397eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielVOID_HANDLER(EntityDecl,
6407eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel             (void *userData,
6417eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel              const XML_Char *entityName,
6427eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel              int is_parameter_entity,
6437eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel              const XML_Char *value,
6447eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel              int value_length,
6457eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel              const XML_Char *base,
6467eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel              const XML_Char *systemId,
6477eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel              const XML_Char *publicId,
6487eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel              const XML_Char *notationName),
6497eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel             ("NiNNNNN",
6507eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel              string_intern(self, entityName), is_parameter_entity,
6517eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel              conv_string_len_to_utf8(value, value_length),
6527eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel              string_intern(self, base), string_intern(self, systemId),
6537eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel              string_intern(self, publicId),
6547eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel              string_intern(self, notationName)))
6557eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel#else
6567eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielVOID_HANDLER(EntityDecl,
6577eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel             (void *userData,
6587eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel              const XML_Char *entityName,
6597eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel              int is_parameter_entity,
6607eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel              const XML_Char *value,
6617eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel              int value_length,
6627eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel              const XML_Char *base,
6637eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel              const XML_Char *systemId,
6647eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel              const XML_Char *publicId,
6657eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel              const XML_Char *notationName),
6667eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel             ("NiNNNNN",
6677eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel              string_intern(self, entityName), is_parameter_entity,
6687eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel              (self->returns_unicode
6697eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel               ? conv_string_len_to_unicode(value, value_length)
6707eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel               : conv_string_len_to_utf8(value, value_length)),
6717eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel              string_intern(self, base), string_intern(self, systemId),
6727eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel              string_intern(self, publicId),
6737eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel              string_intern(self, notationName)))
6747eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel#endif
6757eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
6767eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielVOID_HANDLER(XmlDecl,
6777eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel             (void *userData,
6787eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel              const XML_Char *version,
6797eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel              const XML_Char *encoding,
6807eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel              int standalone),
6817eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel             ("(O&O&i)",
6827eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel              STRING_CONV_FUNC,version, STRING_CONV_FUNC,encoding,
6837eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel              standalone))
6847eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
6857eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielstatic PyObject *
6867eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielconv_content_model(XML_Content * const model,
6877eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                   PyObject *(*conv_string)(const XML_Char *))
6887eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel{
6897eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    PyObject *result = NULL;
6907eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    PyObject *children = PyTuple_New(model->numchildren);
6917eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    int i;
6927eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
6937eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    if (children != NULL) {
6947eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        assert(model->numchildren < INT_MAX);
6957eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        for (i = 0; i < (int)model->numchildren; ++i) {
6967eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            PyObject *child = conv_content_model(&model->children[i],
6977eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                                                 conv_string);
6987eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            if (child == NULL) {
6997eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                Py_XDECREF(children);
7007eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                return NULL;
7017eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            }
7027eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            PyTuple_SET_ITEM(children, i, child);
7037eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        }
7047eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        result = Py_BuildValue("(iiO&N)",
7057eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                               model->type, model->quant,
7067eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                               conv_string,model->name, children);
7077eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    }
7087eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    return result;
7097eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel}
7107eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
7117eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielstatic void
7127eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielmy_ElementDeclHandler(void *userData,
7137eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                      const XML_Char *name,
7147eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                      XML_Content *model)
7157eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel{
7167eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    xmlparseobject *self = (xmlparseobject *)userData;
7177eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    PyObject *args = NULL;
7187eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
7197eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    if (have_handler(self, ElementDecl)) {
7207eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        PyObject *rv = NULL;
7217eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        PyObject *modelobj, *nameobj;
7227eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
7237eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        if (flush_character_buffer(self) < 0)
7247eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            goto finally;
7257eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel#ifdef Py_USING_UNICODE
7267eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        modelobj = conv_content_model(model,
7277eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                                      (self->returns_unicode
7287eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                                       ? conv_string_to_unicode
7297eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                                       : conv_string_to_utf8));
7307eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel#else
7317eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        modelobj = conv_content_model(model, conv_string_to_utf8);
7327eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel#endif
7337eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        if (modelobj == NULL) {
7347eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            flag_error(self);
7357eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            goto finally;
7367eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        }
7377eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        nameobj = string_intern(self, name);
7387eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        if (nameobj == NULL) {
7397eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            Py_DECREF(modelobj);
7407eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            flag_error(self);
7417eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            goto finally;
7427eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        }
7437eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        args = Py_BuildValue("NN", nameobj, modelobj);
7447eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        if (args == NULL) {
7457eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            Py_DECREF(modelobj);
7467eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            flag_error(self);
7477eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            goto finally;
7487eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        }
7497eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        self->in_callback = 1;
7507eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        rv = call_with_frame(getcode(ElementDecl, "ElementDecl", __LINE__),
7517eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                             self->handlers[ElementDecl], args, self);
7527eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        self->in_callback = 0;
7537eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        if (rv == NULL) {
7547eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            flag_error(self);
7557eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            goto finally;
7567eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        }
7577eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        Py_DECREF(rv);
7587eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    }
7597eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel finally:
7607eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    Py_XDECREF(args);
7617eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    XML_FreeContentModel(self->itself, model);
7627eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    return;
7637eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel}
7647eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
7657eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielVOID_HANDLER(AttlistDecl,
7667eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel             (void *userData,
7677eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel              const XML_Char *elname,
7687eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel              const XML_Char *attname,
7697eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel              const XML_Char *att_type,
7707eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel              const XML_Char *dflt,
7717eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel              int isrequired),
7727eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel             ("(NNO&O&i)",
7737eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel              string_intern(self, elname), string_intern(self, attname),
7747eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel              STRING_CONV_FUNC,att_type, STRING_CONV_FUNC,dflt,
7757eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel              isrequired))
7767eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
7777eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel#if XML_COMBINED_VERSION >= 19504
7787eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielVOID_HANDLER(SkippedEntity,
7797eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel             (void *userData,
7807eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel              const XML_Char *entityName,
7817eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel              int is_parameter_entity),
7827eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel             ("Ni",
7837eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel              string_intern(self, entityName), is_parameter_entity))
7847eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel#endif
7857eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
7867eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielVOID_HANDLER(NotationDecl,
7877eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                (void *userData,
7887eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                        const XML_Char *notationName,
7897eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                        const XML_Char *base,
7907eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                        const XML_Char *systemId,
7917eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                        const XML_Char *publicId),
7927eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                ("(NNNN)",
7937eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                 string_intern(self, notationName), string_intern(self, base),
7947eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                 string_intern(self, systemId), string_intern(self, publicId)))
7957eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
7967eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielVOID_HANDLER(StartNamespaceDecl,
7977eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                (void *userData,
7987eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                      const XML_Char *prefix,
7997eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                      const XML_Char *uri),
8007eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                ("(NN)",
8017eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                 string_intern(self, prefix), string_intern(self, uri)))
8027eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
8037eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielVOID_HANDLER(EndNamespaceDecl,
8047eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                (void *userData,
8057eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                    const XML_Char *prefix),
8067eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                ("(N)", string_intern(self, prefix)))
8077eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
8087eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielVOID_HANDLER(Comment,
8097eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel               (void *userData, const XML_Char *data),
8107eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                ("(O&)", STRING_CONV_FUNC,data))
8117eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
8127eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielVOID_HANDLER(StartCdataSection,
8137eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel               (void *userData),
8147eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                ("()"))
8157eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
8167eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielVOID_HANDLER(EndCdataSection,
8177eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel               (void *userData),
8187eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                ("()"))
8197eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
8207eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel#ifndef Py_USING_UNICODE
8217eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielVOID_HANDLER(Default,
8227eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel              (void *userData, const XML_Char *s, int len),
8237eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel              ("(N)", conv_string_len_to_utf8(s,len)))
8247eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
8257eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielVOID_HANDLER(DefaultHandlerExpand,
8267eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel              (void *userData, const XML_Char *s, int len),
8277eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel              ("(N)", conv_string_len_to_utf8(s,len)))
8287eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel#else
8297eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielVOID_HANDLER(Default,
8307eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel              (void *userData, const XML_Char *s, int len),
8317eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel              ("(N)", (self->returns_unicode
8327eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                       ? conv_string_len_to_unicode(s,len)
8337eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                       : conv_string_len_to_utf8(s,len))))
8347eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
8357eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielVOID_HANDLER(DefaultHandlerExpand,
8367eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel              (void *userData, const XML_Char *s, int len),
8377eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel              ("(N)", (self->returns_unicode
8387eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                       ? conv_string_len_to_unicode(s,len)
8397eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                       : conv_string_len_to_utf8(s,len))))
8407eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel#endif
8417eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
8427eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielINT_HANDLER(NotStandalone,
8437eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                (void *userData),
8447eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                ("()"))
8457eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
8467eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielRC_HANDLER(int, ExternalEntityRef,
8477eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                (XML_Parser parser,
8487eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                    const XML_Char *context,
8497eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                    const XML_Char *base,
8507eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                    const XML_Char *systemId,
8517eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                    const XML_Char *publicId),
8527eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                int rc=0;,
8537eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                ("(O&NNN)",
8547eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                 STRING_CONV_FUNC,context, string_intern(self, base),
8557eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                 string_intern(self, systemId), string_intern(self, publicId)),
8567eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                rc = PyInt_AsLong(rv);, rc,
8577eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                XML_GetUserData(parser))
8587eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
8597eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel/* XXX UnknownEncodingHandler */
8607eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
8617eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielVOID_HANDLER(StartDoctypeDecl,
8627eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel             (void *userData, const XML_Char *doctypeName,
8637eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel              const XML_Char *sysid, const XML_Char *pubid,
8647eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel              int has_internal_subset),
8657eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel             ("(NNNi)", string_intern(self, doctypeName),
8667eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel              string_intern(self, sysid), string_intern(self, pubid),
8677eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel              has_internal_subset))
8687eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
8697eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielVOID_HANDLER(EndDoctypeDecl, (void *userData), ("()"))
8707eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
8717eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel/* ---------------------------------------------------------------- */
8727eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
8737eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielstatic PyObject *
8747eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielget_parse_result(xmlparseobject *self, int rv)
8757eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel{
8767eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    if (PyErr_Occurred()) {
8777eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        return NULL;
8787eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    }
8797eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    if (rv == 0) {
8807eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        return set_error(self, XML_GetErrorCode(self->itself));
8817eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    }
8827eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    if (flush_character_buffer(self) < 0) {
8837eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        return NULL;
8847eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    }
8857eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    return PyInt_FromLong(rv);
8867eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel}
8877eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
8887eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielPyDoc_STRVAR(xmlparse_Parse__doc__,
8897eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel"Parse(data[, isfinal])\n\
8907eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielParse XML data.  `isfinal' should be true at end of input.");
8917eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
8927eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielstatic PyObject *
8937eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielxmlparse_Parse(xmlparseobject *self, PyObject *args)
8947eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel{
8957eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    char *s;
8967eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    int slen;
8977eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    int isFinal = 0;
8987eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
8997eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    if (!PyArg_ParseTuple(args, "s#|i:Parse", &s, &slen, &isFinal))
9007eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        return NULL;
9017eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
9027eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    return get_parse_result(self, XML_Parse(self->itself, s, slen, isFinal));
9037eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel}
9047eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
9057eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel/* File reading copied from cPickle */
9067eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
9077eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel#define BUF_SIZE 2048
9087eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
9097eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielstatic int
9107eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielreadinst(char *buf, int buf_size, PyObject *meth)
9117eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel{
9127eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    PyObject *arg = NULL;
9137eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    PyObject *bytes = NULL;
9147eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    PyObject *str = NULL;
9157eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    int len = -1;
9167eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
9177eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    if ((bytes = PyInt_FromLong(buf_size)) == NULL)
9187eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        goto finally;
9197eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
9207eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    if ((arg = PyTuple_New(1)) == NULL) {
9217eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        Py_DECREF(bytes);
9227eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        goto finally;
9237eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    }
9247eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
9257eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    PyTuple_SET_ITEM(arg, 0, bytes);
9267eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
9277eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel#if PY_VERSION_HEX < 0x02020000
9287eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    str = PyObject_CallObject(meth, arg);
9297eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel#else
9307eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    str = PyObject_Call(meth, arg, NULL);
9317eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel#endif
9327eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    if (str == NULL)
9337eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        goto finally;
9347eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
9357eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    /* XXX what to do if it returns a Unicode string? */
9367eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    if (!PyString_Check(str)) {
9377eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        PyErr_Format(PyExc_TypeError,
9387eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                     "read() did not return a string object (type=%.400s)",
9397eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                     Py_TYPE(str)->tp_name);
9407eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        goto finally;
9417eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    }
9427eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    len = PyString_GET_SIZE(str);
9437eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    if (len > buf_size) {
9447eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        PyErr_Format(PyExc_ValueError,
9457eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                     "read() returned too much data: "
9467eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                     "%i bytes requested, %i returned",
9477eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                     buf_size, len);
9487eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        goto finally;
9497eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    }
9507eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    memcpy(buf, PyString_AsString(str), len);
9517eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielfinally:
9527eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    Py_XDECREF(arg);
9537eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    Py_XDECREF(str);
9547eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    return len;
9557eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel}
9567eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
9577eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielPyDoc_STRVAR(xmlparse_ParseFile__doc__,
9587eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel"ParseFile(file)\n\
9597eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielParse XML data from file-like object.");
9607eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
9617eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielstatic PyObject *
9627eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielxmlparse_ParseFile(xmlparseobject *self, PyObject *f)
9637eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel{
9647eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    int rv = 1;
9657eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    PyObject *readmethod = NULL;
9667eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
9677eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    readmethod = PyObject_GetAttrString(f, "read");
9687eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    if (readmethod == NULL) {
9697eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        PyErr_SetString(PyExc_TypeError,
9707eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                        "argument must have 'read' attribute");
9717eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        return NULL;
9727eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
9737eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    }
9747eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    for (;;) {
9757eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        int bytes_read;
9767eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        void *buf = XML_GetBuffer(self->itself, BUF_SIZE);
9777eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        if (buf == NULL) {
9787eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            Py_XDECREF(readmethod);
9797eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            return get_parse_result(self, 0);
9807eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        }
9817eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
9827eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        bytes_read = readinst(buf, BUF_SIZE, readmethod);
9837eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        if (bytes_read < 0) {
9847eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            Py_XDECREF(readmethod);
9857eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            return NULL;
9867eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        }
9877eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
9887eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        rv = XML_ParseBuffer(self->itself, bytes_read, bytes_read == 0);
9897eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        if (PyErr_Occurred()) {
9907eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            Py_XDECREF(readmethod);
9917eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            return NULL;
9927eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        }
9937eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
9947eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        if (!rv || bytes_read == 0)
9957eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            break;
9967eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    }
9977eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    Py_XDECREF(readmethod);
9987eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    return get_parse_result(self, rv);
9997eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel}
10007eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
10017eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielPyDoc_STRVAR(xmlparse_SetBase__doc__,
10027eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel"SetBase(base_url)\n\
10037eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielSet the base URL for the parser.");
10047eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
10057eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielstatic PyObject *
10067eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielxmlparse_SetBase(xmlparseobject *self, PyObject *args)
10077eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel{
10087eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    char *base;
10097eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
10107eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    if (!PyArg_ParseTuple(args, "s:SetBase", &base))
10117eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        return NULL;
10127eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    if (!XML_SetBase(self->itself, base)) {
10137eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        return PyErr_NoMemory();
10147eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    }
10157eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    Py_INCREF(Py_None);
10167eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    return Py_None;
10177eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel}
10187eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
10197eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielPyDoc_STRVAR(xmlparse_GetBase__doc__,
10207eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel"GetBase() -> url\n\
10217eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielReturn base URL string for the parser.");
10227eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
10237eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielstatic PyObject *
10247eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielxmlparse_GetBase(xmlparseobject *self, PyObject *unused)
10257eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel{
10267eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    return Py_BuildValue("z", XML_GetBase(self->itself));
10277eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel}
10287eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
10297eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielPyDoc_STRVAR(xmlparse_GetInputContext__doc__,
10307eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel"GetInputContext() -> string\n\
10317eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielReturn the untranslated text of the input that caused the current event.\n\
10327eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielIf the event was generated by a large amount of text (such as a start tag\n\
10337eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielfor an element with many attributes), not all of the text may be available.");
10347eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
10357eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielstatic PyObject *
10367eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielxmlparse_GetInputContext(xmlparseobject *self, PyObject *unused)
10377eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel{
10387eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    if (self->in_callback) {
10397eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        int offset, size;
10407eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        const char *buffer
10417eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            = XML_GetInputContext(self->itself, &offset, &size);
10427eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
10437eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        if (buffer != NULL)
10447eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            return PyString_FromStringAndSize(buffer + offset,
10457eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                                              size - offset);
10467eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        else
10477eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            Py_RETURN_NONE;
10487eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    }
10497eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    else
10507eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        Py_RETURN_NONE;
10517eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel}
10527eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
10537eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielPyDoc_STRVAR(xmlparse_ExternalEntityParserCreate__doc__,
10547eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel"ExternalEntityParserCreate(context[, encoding])\n\
10557eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielCreate a parser for parsing an external entity based on the\n\
10567eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielinformation passed to the ExternalEntityRefHandler.");
10577eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
10587eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielstatic PyObject *
10597eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielxmlparse_ExternalEntityParserCreate(xmlparseobject *self, PyObject *args)
10607eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel{
10617eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    char *context;
10627eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    char *encoding = NULL;
10637eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    xmlparseobject *new_parser;
10647eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    int i;
10657eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
10667eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    if (!PyArg_ParseTuple(args, "z|s:ExternalEntityParserCreate",
10677eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                          &context, &encoding)) {
10687eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        return NULL;
10697eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    }
10707eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
10717eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel#ifndef Py_TPFLAGS_HAVE_GC
10727eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    /* Python versions 2.0 and 2.1 */
10737eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    new_parser = PyObject_New(xmlparseobject, &Xmlparsetype);
10747eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel#else
10757eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    /* Python versions 2.2 and later */
10767eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    new_parser = PyObject_GC_New(xmlparseobject, &Xmlparsetype);
10777eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel#endif
10787eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
10797eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    if (new_parser == NULL)
10807eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        return NULL;
10817eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    new_parser->buffer_size = self->buffer_size;
10827eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    new_parser->buffer_used = 0;
10837eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    if (self->buffer != NULL) {
10847eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        new_parser->buffer = malloc(new_parser->buffer_size);
10857eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        if (new_parser->buffer == NULL) {
10867eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel#ifndef Py_TPFLAGS_HAVE_GC
10877eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            /* Code for versions 2.0 and 2.1 */
10887eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            PyObject_Del(new_parser);
10897eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel#else
10907eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            /* Code for versions 2.2 and later. */
10917eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            PyObject_GC_Del(new_parser);
10927eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel#endif
10937eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            return PyErr_NoMemory();
10947eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        }
10957eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    }
10967eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    else
10977eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        new_parser->buffer = NULL;
10987eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    new_parser->returns_unicode = self->returns_unicode;
10997eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    new_parser->ordered_attributes = self->ordered_attributes;
11007eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    new_parser->specified_attributes = self->specified_attributes;
11017eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    new_parser->in_callback = 0;
11027eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    new_parser->ns_prefixes = self->ns_prefixes;
11037eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    new_parser->itself = XML_ExternalEntityParserCreate(self->itself, context,
11047eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                                                        encoding);
11057eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    new_parser->handlers = 0;
11067eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    new_parser->intern = self->intern;
11077eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    Py_XINCREF(new_parser->intern);
11087eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel#ifdef Py_TPFLAGS_HAVE_GC
11097eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    PyObject_GC_Track(new_parser);
11107eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel#else
11117eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    PyObject_GC_Init(new_parser);
11127eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel#endif
11137eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
11147eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    if (!new_parser->itself) {
11157eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        Py_DECREF(new_parser);
11167eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        return PyErr_NoMemory();
11177eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    }
11187eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
11197eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    XML_SetUserData(new_parser->itself, (void *)new_parser);
11207eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
11217eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    /* allocate and clear handlers first */
11227eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    for (i = 0; handler_info[i].name != NULL; i++)
11237eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        /* do nothing */;
11247eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
11257eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    new_parser->handlers = malloc(sizeof(PyObject *) * i);
11267eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    if (!new_parser->handlers) {
11277eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        Py_DECREF(new_parser);
11287eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        return PyErr_NoMemory();
11297eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    }
11307eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    clear_handlers(new_parser, 1);
11317eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
11327eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    /* then copy handlers from self */
11337eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    for (i = 0; handler_info[i].name != NULL; i++) {
11347eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        PyObject *handler = self->handlers[i];
11357eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        if (handler != NULL) {
11367eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            Py_INCREF(handler);
11377eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            new_parser->handlers[i] = handler;
11387eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            handler_info[i].setter(new_parser->itself,
11397eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                                   handler_info[i].handler);
11407eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        }
11417eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    }
11427eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    return (PyObject *)new_parser;
11437eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel}
11447eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
11457eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielPyDoc_STRVAR(xmlparse_SetParamEntityParsing__doc__,
11467eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel"SetParamEntityParsing(flag) -> success\n\
11477eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielControls parsing of parameter entities (including the external DTD\n\
11487eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielsubset). Possible flag values are XML_PARAM_ENTITY_PARSING_NEVER,\n\
11497eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielXML_PARAM_ENTITY_PARSING_UNLESS_STANDALONE and\n\
11507eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielXML_PARAM_ENTITY_PARSING_ALWAYS. Returns true if setting the flag\n\
11517eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielwas successful.");
11527eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
11537eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielstatic PyObject*
11547eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielxmlparse_SetParamEntityParsing(xmlparseobject *p, PyObject* args)
11557eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel{
11567eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    int flag;
11577eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    if (!PyArg_ParseTuple(args, "i", &flag))
11587eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        return NULL;
11597eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    flag = XML_SetParamEntityParsing(p->itself, flag);
11607eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    return PyInt_FromLong(flag);
11617eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel}
11627eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
11637eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
11647eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel#if XML_COMBINED_VERSION >= 19505
11657eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielPyDoc_STRVAR(xmlparse_UseForeignDTD__doc__,
11667eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel"UseForeignDTD([flag])\n\
11677eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielAllows the application to provide an artificial external subset if one is\n\
11687eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielnot specified as part of the document instance.  This readily allows the\n\
11697eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanieluse of a 'default' document type controlled by the application, while still\n\
11707eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielgetting the advantage of providing document type information to the parser.\n\
11717eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel'flag' defaults to True if not provided.");
11727eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
11737eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielstatic PyObject *
11747eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielxmlparse_UseForeignDTD(xmlparseobject *self, PyObject *args)
11757eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel{
11767eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    PyObject *flagobj = NULL;
11777eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    int flag = 1;
11787eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    enum XML_Error rc;
11797eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    if (!PyArg_ParseTuple(args, "|O:UseForeignDTD", &flagobj))
11807eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        return NULL;
11817eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    if (flagobj != NULL) {
11827eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        flag = PyObject_IsTrue(flagobj);
11837eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        if (flag < 0)
11847eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            return NULL;
11857eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    }
11867eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    rc = XML_UseForeignDTD(self->itself, flag ? XML_TRUE : XML_FALSE);
11877eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    if (rc != XML_ERROR_NONE) {
11887eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        return set_error(self, rc);
11897eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    }
11907eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    Py_INCREF(Py_None);
11917eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    return Py_None;
11927eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel}
11937eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel#endif
11947eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
11957eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielstatic struct PyMethodDef xmlparse_methods[] = {
11967eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    {"Parse",     (PyCFunction)xmlparse_Parse,
11977eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                  METH_VARARGS, xmlparse_Parse__doc__},
11987eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    {"ParseFile", (PyCFunction)xmlparse_ParseFile,
11997eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                  METH_O,       xmlparse_ParseFile__doc__},
12007eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    {"SetBase",   (PyCFunction)xmlparse_SetBase,
12017eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                  METH_VARARGS, xmlparse_SetBase__doc__},
12027eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    {"GetBase",   (PyCFunction)xmlparse_GetBase,
12037eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                  METH_NOARGS, xmlparse_GetBase__doc__},
12047eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    {"ExternalEntityParserCreate", (PyCFunction)xmlparse_ExternalEntityParserCreate,
12057eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                  METH_VARARGS, xmlparse_ExternalEntityParserCreate__doc__},
12067eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    {"SetParamEntityParsing", (PyCFunction)xmlparse_SetParamEntityParsing,
12077eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                  METH_VARARGS, xmlparse_SetParamEntityParsing__doc__},
12087eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    {"GetInputContext", (PyCFunction)xmlparse_GetInputContext,
12097eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                  METH_NOARGS, xmlparse_GetInputContext__doc__},
12107eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel#if XML_COMBINED_VERSION >= 19505
12117eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    {"UseForeignDTD", (PyCFunction)xmlparse_UseForeignDTD,
12127eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                  METH_VARARGS, xmlparse_UseForeignDTD__doc__},
12137eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel#endif
12147eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    {NULL,        NULL}         /* sentinel */
12157eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel};
12167eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
12177eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel/* ---------- */
12187eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
12197eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
12207eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel#ifdef Py_USING_UNICODE
12217eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
12227eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel/* pyexpat international encoding support.
12237eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel   Make it as simple as possible.
12247eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel*/
12257eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
12267eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielstatic char template_buffer[257];
12277eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielPyObject *template_string = NULL;
12287eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
12297eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielstatic void
12307eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielinit_template_buffer(void)
12317eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel{
12327eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    int i;
12337eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    for (i = 0; i < 256; i++) {
12347eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        template_buffer[i] = i;
12357eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    }
12367eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    template_buffer[256] = 0;
12377eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel}
12387eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
12397eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielstatic int
12407eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielPyUnknownEncodingHandler(void *encodingHandlerData,
12417eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                         const XML_Char *name,
12427eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                         XML_Encoding *info)
12437eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel{
12447eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    PyUnicodeObject *_u_string = NULL;
12457eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    int result = 0;
12467eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    int i;
12477eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
12487eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    /* Yes, supports only 8bit encodings */
12497eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    _u_string = (PyUnicodeObject *)
12507eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        PyUnicode_Decode(template_buffer, 256, name, "replace");
12517eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
12527eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    if (_u_string == NULL)
12537eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        return result;
12547eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
12557eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    if (PyUnicode_GET_SIZE(_u_string) != 256) {
12567eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        Py_DECREF(_u_string);
12577eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        PyErr_SetString(PyExc_ValueError,
12587eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                        "multi-byte encodings are not supported");
12597eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        return result;
12607eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    }
12617eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
12627eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    for (i = 0; i < 256; i++) {
12637eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        /* Stupid to access directly, but fast */
12647eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        Py_UNICODE c = _u_string->str[i];
12657eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        if (c == Py_UNICODE_REPLACEMENT_CHARACTER)
12667eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            info->map[i] = -1;
12677eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        else
12687eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            info->map[i] = c;
12697eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    }
12707eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    info->data = NULL;
12717eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    info->convert = NULL;
12727eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    info->release = NULL;
12737eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    result = 1;
12747eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    Py_DECREF(_u_string);
12757eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    return result;
12767eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel}
12777eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
12787eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel#endif
12797eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
12807eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielstatic PyObject *
12817eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielnewxmlparseobject(char *encoding, char *namespace_separator, PyObject *intern)
12827eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel{
12837eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    int i;
12847eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    xmlparseobject *self;
12857eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
12867eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel#ifdef Py_TPFLAGS_HAVE_GC
12877eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    /* Code for versions 2.2 and later */
12887eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    self = PyObject_GC_New(xmlparseobject, &Xmlparsetype);
12897eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel#else
12907eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    self = PyObject_New(xmlparseobject, &Xmlparsetype);
12917eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel#endif
12927eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    if (self == NULL)
12937eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        return NULL;
12947eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
12957eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel#ifdef Py_USING_UNICODE
12967eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    self->returns_unicode = 1;
12977eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel#else
12987eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    self->returns_unicode = 0;
12997eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel#endif
13007eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
13017eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    self->buffer = NULL;
13027eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    self->buffer_size = CHARACTER_DATA_BUFFER_SIZE;
13037eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    self->buffer_used = 0;
13047eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    self->ordered_attributes = 0;
13057eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    self->specified_attributes = 0;
13067eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    self->in_callback = 0;
13077eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    self->ns_prefixes = 0;
13087eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    self->handlers = NULL;
13097eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    if (namespace_separator != NULL) {
13107eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        self->itself = XML_ParserCreateNS(encoding, *namespace_separator);
13117eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    }
13127eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    else {
13137eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        self->itself = XML_ParserCreate(encoding);
13147eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    }
13157eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel#if ((XML_MAJOR_VERSION >= 2) && (XML_MINOR_VERSION >= 1)) || defined(XML_HAS_SET_HASH_SALT)
13167eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    /* This feature was added upstream in libexpat 2.1.0.  Our expat copy
13177eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel     * has a backport of this feature where we also define XML_HAS_SET_HASH_SALT
13187eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel     * to indicate that we can still use it. */
13197eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    XML_SetHashSalt(self->itself,
13207eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                    (unsigned long)_Py_HashSecret.prefix);
13217eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel#endif
13227eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    self->intern = intern;
13237eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    Py_XINCREF(self->intern);
13247eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel#ifdef Py_TPFLAGS_HAVE_GC
13257eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    PyObject_GC_Track(self);
13267eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel#else
13277eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    PyObject_GC_Init(self);
13287eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel#endif
13297eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    if (self->itself == NULL) {
13307eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        PyErr_SetString(PyExc_RuntimeError,
13317eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                        "XML_ParserCreate failed");
13327eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        Py_DECREF(self);
13337eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        return NULL;
13347eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    }
13357eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    XML_SetUserData(self->itself, (void *)self);
13367eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel#ifdef Py_USING_UNICODE
13377eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    XML_SetUnknownEncodingHandler(self->itself,
13387eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                  (XML_UnknownEncodingHandler) PyUnknownEncodingHandler, NULL);
13397eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel#endif
13407eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
13417eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    for (i = 0; handler_info[i].name != NULL; i++)
13427eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        /* do nothing */;
13437eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
13447eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    self->handlers = malloc(sizeof(PyObject *) * i);
13457eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    if (!self->handlers) {
13467eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        Py_DECREF(self);
13477eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        return PyErr_NoMemory();
13487eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    }
13497eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    clear_handlers(self, 1);
13507eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
13517eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    return (PyObject*)self;
13527eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel}
13537eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
13547eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
13557eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielstatic void
13567eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielxmlparse_dealloc(xmlparseobject *self)
13577eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel{
13587eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    int i;
13597eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel#ifdef Py_TPFLAGS_HAVE_GC
13607eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    PyObject_GC_UnTrack(self);
13617eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel#else
13627eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    PyObject_GC_Fini(self);
13637eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel#endif
13647eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    if (self->itself != NULL)
13657eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        XML_ParserFree(self->itself);
13667eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    self->itself = NULL;
13677eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
13687eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    if (self->handlers != NULL) {
13697eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        PyObject *temp;
13707eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        for (i = 0; handler_info[i].name != NULL; i++) {
13717eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            temp = self->handlers[i];
13727eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            self->handlers[i] = NULL;
13737eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            Py_XDECREF(temp);
13747eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        }
13757eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        free(self->handlers);
13767eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        self->handlers = NULL;
13777eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    }
13787eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    if (self->buffer != NULL) {
13797eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        free(self->buffer);
13807eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        self->buffer = NULL;
13817eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    }
13827eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    Py_XDECREF(self->intern);
13837eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel#ifndef Py_TPFLAGS_HAVE_GC
13847eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    /* Code for versions 2.0 and 2.1 */
13857eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    PyObject_Del(self);
13867eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel#else
13877eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    /* Code for versions 2.2 and later. */
13887eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    PyObject_GC_Del(self);
13897eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel#endif
13907eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel}
13917eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
13927eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielstatic int
13937eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielhandlername2int(const char *name)
13947eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel{
13957eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    int i;
13967eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    for (i = 0; handler_info[i].name != NULL; i++) {
13977eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        if (strcmp(name, handler_info[i].name) == 0) {
13987eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            return i;
13997eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        }
14007eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    }
14017eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    return -1;
14027eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel}
14037eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
14047eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielstatic PyObject *
14057eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielget_pybool(int istrue)
14067eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel{
14077eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    PyObject *result = istrue ? Py_True : Py_False;
14087eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    Py_INCREF(result);
14097eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    return result;
14107eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel}
14117eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
14127eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielstatic PyObject *
14137eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielxmlparse_getattr(xmlparseobject *self, char *name)
14147eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel{
14157eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    int handlernum = handlername2int(name);
14167eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
14177eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    if (handlernum != -1) {
14187eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        PyObject *result = self->handlers[handlernum];
14197eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        if (result == NULL)
14207eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            result = Py_None;
14217eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        Py_INCREF(result);
14227eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        return result;
14237eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    }
14247eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    if (name[0] == 'E') {
14257eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        if (strcmp(name, "ErrorCode") == 0)
14267eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            return PyInt_FromLong((long)
14277eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                                  XML_GetErrorCode(self->itself));
14287eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        if (strcmp(name, "ErrorLineNumber") == 0)
14297eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            return PyInt_FromLong((long)
14307eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                                  XML_GetErrorLineNumber(self->itself));
14317eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        if (strcmp(name, "ErrorColumnNumber") == 0)
14327eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            return PyInt_FromLong((long)
14337eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                                  XML_GetErrorColumnNumber(self->itself));
14347eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        if (strcmp(name, "ErrorByteIndex") == 0)
14357eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            return PyInt_FromLong((long)
14367eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                                  XML_GetErrorByteIndex(self->itself));
14377eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    }
14387eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    if (name[0] == 'C') {
14397eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        if (strcmp(name, "CurrentLineNumber") == 0)
14407eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            return PyInt_FromLong((long)
14417eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                                  XML_GetCurrentLineNumber(self->itself));
14427eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        if (strcmp(name, "CurrentColumnNumber") == 0)
14437eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            return PyInt_FromLong((long)
14447eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                                  XML_GetCurrentColumnNumber(self->itself));
14457eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        if (strcmp(name, "CurrentByteIndex") == 0)
14467eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            return PyInt_FromLong((long)
14477eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                                  XML_GetCurrentByteIndex(self->itself));
14487eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    }
14497eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    if (name[0] == 'b') {
14507eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        if (strcmp(name, "buffer_size") == 0)
14517eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            return PyInt_FromLong((long) self->buffer_size);
14527eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        if (strcmp(name, "buffer_text") == 0)
14537eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            return get_pybool(self->buffer != NULL);
14547eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        if (strcmp(name, "buffer_used") == 0)
14557eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            return PyInt_FromLong((long) self->buffer_used);
14567eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    }
14577eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    if (strcmp(name, "namespace_prefixes") == 0)
14587eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        return get_pybool(self->ns_prefixes);
14597eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    if (strcmp(name, "ordered_attributes") == 0)
14607eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        return get_pybool(self->ordered_attributes);
14617eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    if (strcmp(name, "returns_unicode") == 0)
14627eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        return get_pybool((long) self->returns_unicode);
14637eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    if (strcmp(name, "specified_attributes") == 0)
14647eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        return get_pybool((long) self->specified_attributes);
14657eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    if (strcmp(name, "intern") == 0) {
14667eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        if (self->intern == NULL) {
14677eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            Py_INCREF(Py_None);
14687eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            return Py_None;
14697eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        }
14707eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        else {
14717eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            Py_INCREF(self->intern);
14727eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            return self->intern;
14737eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        }
14747eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    }
14757eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
14767eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel#define APPEND(list, str)                               \
14777eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        do {                                            \
14787eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                PyObject *o = PyString_FromString(str); \
14797eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                if (o != NULL)                          \
14807eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                        PyList_Append(list, o);         \
14817eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                Py_XDECREF(o);                          \
14827eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        } while (0)
14837eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
14847eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    if (strcmp(name, "__members__") == 0) {
14857eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        int i;
14867eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        PyObject *rc = PyList_New(0);
14877eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        if (!rc)
14887eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                return NULL;
14897eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        for (i = 0; handler_info[i].name != NULL; i++) {
14907eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            PyObject *o = get_handler_name(&handler_info[i]);
14917eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            if (o != NULL)
14927eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                PyList_Append(rc, o);
14937eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            Py_XDECREF(o);
14947eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        }
14957eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        APPEND(rc, "ErrorCode");
14967eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        APPEND(rc, "ErrorLineNumber");
14977eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        APPEND(rc, "ErrorColumnNumber");
14987eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        APPEND(rc, "ErrorByteIndex");
14997eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        APPEND(rc, "CurrentLineNumber");
15007eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        APPEND(rc, "CurrentColumnNumber");
15017eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        APPEND(rc, "CurrentByteIndex");
15027eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        APPEND(rc, "buffer_size");
15037eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        APPEND(rc, "buffer_text");
15047eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        APPEND(rc, "buffer_used");
15057eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        APPEND(rc, "namespace_prefixes");
15067eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        APPEND(rc, "ordered_attributes");
15077eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        APPEND(rc, "returns_unicode");
15087eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        APPEND(rc, "specified_attributes");
15097eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        APPEND(rc, "intern");
15107eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
15117eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel#undef APPEND
15127eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        return rc;
15137eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    }
15147eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    return Py_FindMethod(xmlparse_methods, (PyObject *)self, name);
15157eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel}
15167eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
15177eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielstatic int
15187eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielsethandler(xmlparseobject *self, const char *name, PyObject* v)
15197eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel{
15207eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    int handlernum = handlername2int(name);
15217eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    if (handlernum >= 0) {
15227eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        xmlhandler c_handler = NULL;
15237eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        PyObject *temp = self->handlers[handlernum];
15247eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
15257eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        if (v == Py_None) {
15267eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            /* If this is the character data handler, and a character
15277eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel               data handler is already active, we need to be more
15287eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel               careful.  What we can safely do is replace the existing
15297eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel               character data handler callback function with a no-op
15307eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel               function that will refuse to call Python.  The downside
15317eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel               is that this doesn't completely remove the character
15327eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel               data handler from the C layer if there's any callback
15337eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel               active, so Expat does a little more work than it
15347eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel               otherwise would, but that's really an odd case.  A more
15357eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel               elaborate system of handlers and state could remove the
15367eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel               C handler more effectively. */
15377eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            if (handlernum == CharacterData && self->in_callback)
15387eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                c_handler = noop_character_data_handler;
15397eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            v = NULL;
15407eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        }
15417eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        else if (v != NULL) {
15427eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            Py_INCREF(v);
15437eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            c_handler = handler_info[handlernum].handler;
15447eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        }
15457eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        self->handlers[handlernum] = v;
15467eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        Py_XDECREF(temp);
15477eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        handler_info[handlernum].setter(self->itself, c_handler);
15487eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        return 1;
15497eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    }
15507eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    return 0;
15517eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel}
15527eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
15537eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielstatic int
15547eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielxmlparse_setattr(xmlparseobject *self, char *name, PyObject *v)
15557eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel{
15567eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    /* Set attribute 'name' to value 'v'. v==NULL means delete */
15577eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    if (v == NULL) {
15587eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        PyErr_SetString(PyExc_RuntimeError, "Cannot delete attribute");
15597eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        return -1;
15607eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    }
15617eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    if (strcmp(name, "buffer_text") == 0) {
15627eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        int b = PyObject_IsTrue(v);
15637eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        if (b < 0)
15647eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            return -1;
15657eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        if (b) {
15667eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            if (self->buffer == NULL) {
15677eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                self->buffer = malloc(self->buffer_size);
15687eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                if (self->buffer == NULL) {
15697eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                    PyErr_NoMemory();
15707eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                    return -1;
15717eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                }
15727eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                self->buffer_used = 0;
15737eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            }
15747eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        }
15757eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        else if (self->buffer != NULL) {
15767eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            if (flush_character_buffer(self) < 0)
15777eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                return -1;
15787eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            free(self->buffer);
15797eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            self->buffer = NULL;
15807eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        }
15817eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        return 0;
15827eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    }
15837eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    if (strcmp(name, "namespace_prefixes") == 0) {
15847eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        int b = PyObject_IsTrue(v);
15857eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        if (b < 0)
15867eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            return -1;
15877eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        self->ns_prefixes = b;
15887eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        XML_SetReturnNSTriplet(self->itself, self->ns_prefixes);
15897eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        return 0;
15907eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    }
15917eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    if (strcmp(name, "ordered_attributes") == 0) {
15927eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        int b = PyObject_IsTrue(v);
15937eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        if (b < 0)
15947eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            return -1;
15957eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        self->ordered_attributes = b;
15967eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        return 0;
15977eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    }
15987eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    if (strcmp(name, "returns_unicode") == 0) {
15997eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        int b = PyObject_IsTrue(v);
16007eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        if (b < 0)
16017eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            return -1;
16027eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel#ifndef Py_USING_UNICODE
16037eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        if (b) {
16047eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            PyErr_SetString(PyExc_ValueError,
16057eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                            "Unicode support not available");
16067eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            return -1;
16077eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        }
16087eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel#endif
16097eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        self->returns_unicode = b;
16107eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        return 0;
16117eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    }
16127eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    if (strcmp(name, "specified_attributes") == 0) {
16137eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        int b = PyObject_IsTrue(v);
16147eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        if (b < 0)
16157eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            return -1;
16167eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        self->specified_attributes = b;
16177eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        return 0;
16187eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    }
16197eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
16207eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    if (strcmp(name, "buffer_size") == 0) {
16217eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel      long new_buffer_size;
16227eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel      if (!PyInt_Check(v)) {
16237eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        PyErr_SetString(PyExc_TypeError, "buffer_size must be an integer");
16247eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        return -1;
16257eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel      }
16267eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
16277eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel      new_buffer_size=PyInt_AS_LONG(v);
16287eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel      /* trivial case -- no change */
16297eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel      if (new_buffer_size == self->buffer_size) {
16307eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        return 0;
16317eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel      }
16327eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
16337eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel      if (new_buffer_size <= 0) {
16347eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        PyErr_SetString(PyExc_ValueError, "buffer_size must be greater than zero");
16357eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        return -1;
16367eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel      }
16377eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
16387eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel      /* check maximum */
16397eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel      if (new_buffer_size > INT_MAX) {
16407eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        char errmsg[100];
16417eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        sprintf(errmsg, "buffer_size must not be greater than %i", INT_MAX);
16427eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        PyErr_SetString(PyExc_ValueError, errmsg);
16437eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        return -1;
16447eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel      }
16457eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
16467eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel      if (self->buffer != NULL) {
16477eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        /* there is already a buffer */
16487eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        if (self->buffer_used != 0) {
16497eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel          flush_character_buffer(self);
16507eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        }
16517eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        /* free existing buffer */
16527eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        free(self->buffer);
16537eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel      }
16547eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel      self->buffer = malloc(new_buffer_size);
16557eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel      if (self->buffer == NULL) {
16567eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        PyErr_NoMemory();
16577eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        return -1;
16587eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel      }
16597eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel      self->buffer_size = new_buffer_size;
16607eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel      return 0;
16617eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    }
16627eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
16637eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    if (strcmp(name, "CharacterDataHandler") == 0) {
16647eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        /* If we're changing the character data handler, flush all
16657eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel         * cached data with the old handler.  Not sure there's a
16667eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel         * "right" thing to do, though, but this probably won't
16677eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel         * happen.
16687eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel         */
16697eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        if (flush_character_buffer(self) < 0)
16707eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            return -1;
16717eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    }
16727eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    if (sethandler(self, name, v)) {
16737eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        return 0;
16747eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    }
16757eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    PyErr_SetString(PyExc_AttributeError, name);
16767eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    return -1;
16777eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel}
16787eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
16797eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel#ifdef WITH_CYCLE_GC
16807eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielstatic int
16817eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielxmlparse_traverse(xmlparseobject *op, visitproc visit, void *arg)
16827eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel{
16837eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    int i;
16847eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    for (i = 0; handler_info[i].name != NULL; i++)
16857eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        Py_VISIT(op->handlers[i]);
16867eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    return 0;
16877eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel}
16887eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
16897eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielstatic int
16907eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielxmlparse_clear(xmlparseobject *op)
16917eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel{
16927eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    clear_handlers(op, 0);
16937eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    Py_CLEAR(op->intern);
16947eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    return 0;
16957eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel}
16967eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel#endif
16977eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
16987eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielPyDoc_STRVAR(Xmlparsetype__doc__, "XML parser");
16997eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
17007eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielstatic PyTypeObject Xmlparsetype = {
17017eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        PyVarObject_HEAD_INIT(NULL, 0)
17027eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        "pyexpat.xmlparser",            /*tp_name*/
17037eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        sizeof(xmlparseobject) + PyGC_HEAD_SIZE,/*tp_basicsize*/
17047eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        0,                              /*tp_itemsize*/
17057eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        /* methods */
17067eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        (destructor)xmlparse_dealloc,   /*tp_dealloc*/
17077eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        (printfunc)0,           /*tp_print*/
17087eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        (getattrfunc)xmlparse_getattr,  /*tp_getattr*/
17097eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        (setattrfunc)xmlparse_setattr,  /*tp_setattr*/
17107eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        (cmpfunc)0,             /*tp_compare*/
17117eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        (reprfunc)0,            /*tp_repr*/
17127eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        0,                      /*tp_as_number*/
17137eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        0,              /*tp_as_sequence*/
17147eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        0,              /*tp_as_mapping*/
17157eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        (hashfunc)0,            /*tp_hash*/
17167eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        (ternaryfunc)0,         /*tp_call*/
17177eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        (reprfunc)0,            /*tp_str*/
17187eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        0,              /* tp_getattro */
17197eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        0,              /* tp_setattro */
17207eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        0,              /* tp_as_buffer */
17217eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel#ifdef Py_TPFLAGS_HAVE_GC
17227eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, /*tp_flags*/
17237eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel#else
17247eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        Py_TPFLAGS_DEFAULT | Py_TPFLAGS_GC, /*tp_flags*/
17257eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel#endif
17267eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        Xmlparsetype__doc__, /* tp_doc - Documentation string */
17277eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel#ifdef WITH_CYCLE_GC
17287eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        (traverseproc)xmlparse_traverse,        /* tp_traverse */
17297eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        (inquiry)xmlparse_clear         /* tp_clear */
17307eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel#else
17317eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        0, 0
17327eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel#endif
17337eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel};
17347eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
17357eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel/* End of code for xmlparser objects */
17367eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel/* -------------------------------------------------------- */
17377eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
17387eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielPyDoc_STRVAR(pyexpat_ParserCreate__doc__,
17397eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel"ParserCreate([encoding[, namespace_separator]]) -> parser\n\
17407eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielReturn a new XML parser object.");
17417eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
17427eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielstatic PyObject *
17437eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielpyexpat_ParserCreate(PyObject *notused, PyObject *args, PyObject *kw)
17447eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel{
17457eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    char *encoding = NULL;
17467eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    char *namespace_separator = NULL;
17477eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    PyObject *intern = NULL;
17487eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    PyObject *result;
17497eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    int intern_decref = 0;
17507eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    static char *kwlist[] = {"encoding", "namespace_separator",
17517eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                                   "intern", NULL};
17527eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
17537eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    if (!PyArg_ParseTupleAndKeywords(args, kw, "|zzO:ParserCreate", kwlist,
17547eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                                     &encoding, &namespace_separator, &intern))
17557eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        return NULL;
17567eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    if (namespace_separator != NULL
17577eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        && strlen(namespace_separator) > 1) {
17587eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        PyErr_SetString(PyExc_ValueError,
17597eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                        "namespace_separator must be at most one"
17607eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                        " character, omitted, or None");
17617eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        return NULL;
17627eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    }
17637eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    /* Explicitly passing None means no interning is desired.
17647eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel       Not passing anything means that a new dictionary is used. */
17657eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    if (intern == Py_None)
17667eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        intern = NULL;
17677eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    else if (intern == NULL) {
17687eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        intern = PyDict_New();
17697eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        if (!intern)
17707eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            return NULL;
17717eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        intern_decref = 1;
17727eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    }
17737eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    else if (!PyDict_Check(intern)) {
17747eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        PyErr_SetString(PyExc_TypeError, "intern must be a dictionary");
17757eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        return NULL;
17767eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    }
17777eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
17787eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    result = newxmlparseobject(encoding, namespace_separator, intern);
17797eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    if (intern_decref) {
17807eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        Py_DECREF(intern);
17817eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    }
17827eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    return result;
17837eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel}
17847eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
17857eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielPyDoc_STRVAR(pyexpat_ErrorString__doc__,
17867eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel"ErrorString(errno) -> string\n\
17877eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielReturns string error for given number.");
17887eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
17897eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielstatic PyObject *
17907eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielpyexpat_ErrorString(PyObject *self, PyObject *args)
17917eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel{
17927eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    long code = 0;
17937eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
17947eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    if (!PyArg_ParseTuple(args, "l:ErrorString", &code))
17957eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        return NULL;
17967eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    return Py_BuildValue("z", XML_ErrorString((int)code));
17977eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel}
17987eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
17997eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel/* List of methods defined in the module */
18007eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
18017eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielstatic struct PyMethodDef pyexpat_methods[] = {
18027eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    {"ParserCreate",    (PyCFunction)pyexpat_ParserCreate,
18037eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel     METH_VARARGS|METH_KEYWORDS, pyexpat_ParserCreate__doc__},
18047eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    {"ErrorString",     (PyCFunction)pyexpat_ErrorString,
18057eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel     METH_VARARGS,      pyexpat_ErrorString__doc__},
18067eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
18077eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    {NULL,       (PyCFunction)NULL, 0, NULL}            /* sentinel */
18087eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel};
18097eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
18107eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel/* Module docstring */
18117eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
18127eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielPyDoc_STRVAR(pyexpat_module_documentation,
18137eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel"Python wrapper for Expat parser.");
18147eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
18157eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel/* Initialization function for the module */
18167eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
18177eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel#ifndef MODULE_NAME
18187eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel#define MODULE_NAME "pyexpat"
18197eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel#endif
18207eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
18217eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel#ifndef MODULE_INITFUNC
18227eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel#define MODULE_INITFUNC initpyexpat
18237eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel#endif
18247eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
18257eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel#ifndef PyMODINIT_FUNC
18267eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel#   ifdef MS_WINDOWS
18277eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel#       define PyMODINIT_FUNC __declspec(dllexport) void
18287eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel#   else
18297eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel#       define PyMODINIT_FUNC void
18307eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel#   endif
18317eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel#endif
18327eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
18337eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielPyMODINIT_FUNC MODULE_INITFUNC(void);  /* avoid compiler warnings */
18347eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
18357eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielPyMODINIT_FUNC
18367eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielMODULE_INITFUNC(void)
18377eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel{
18387eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    PyObject *m, *d;
18397eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    PyObject *errmod_name = PyString_FromString(MODULE_NAME ".errors");
18407eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    PyObject *errors_module;
18417eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    PyObject *modelmod_name;
18427eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    PyObject *model_module;
18437eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    PyObject *sys_modules;
18447eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    PyObject *version;
18457eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    static struct PyExpat_CAPI capi;
18467eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    PyObject* capi_object;
18477eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
18487eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    if (errmod_name == NULL)
18497eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        return;
18507eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    modelmod_name = PyString_FromString(MODULE_NAME ".model");
18517eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    if (modelmod_name == NULL)
18527eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        return;
18537eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
18547eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    Py_TYPE(&Xmlparsetype) = &PyType_Type;
18557eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
18567eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    /* Create the module and add the functions */
18577eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    m = Py_InitModule3(MODULE_NAME, pyexpat_methods,
18587eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                       pyexpat_module_documentation);
18597eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    if (m == NULL)
18607eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        return;
18617eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
18627eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    /* Add some symbolic constants to the module */
18637eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    if (ErrorObject == NULL) {
18647eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        ErrorObject = PyErr_NewException("xml.parsers.expat.ExpatError",
18657eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                                         NULL, NULL);
18667eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        if (ErrorObject == NULL)
18677eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            return;
18687eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    }
18697eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    Py_INCREF(ErrorObject);
18707eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    PyModule_AddObject(m, "error", ErrorObject);
18717eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    Py_INCREF(ErrorObject);
18727eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    PyModule_AddObject(m, "ExpatError", ErrorObject);
18737eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    Py_INCREF(&Xmlparsetype);
18747eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    PyModule_AddObject(m, "XMLParserType", (PyObject *) &Xmlparsetype);
18757eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
18767eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    version = PyString_FromString(PY_VERSION);
18777eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    if (!version)
18787eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        return;
18797eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    PyModule_AddObject(m, "__version__", version);
18807eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    PyModule_AddStringConstant(m, "EXPAT_VERSION",
18817eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                               (char *) XML_ExpatVersion());
18827eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    {
18837eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        XML_Expat_Version info = XML_ExpatVersionInfo();
18847eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        PyModule_AddObject(m, "version_info",
18857eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                           Py_BuildValue("(iii)", info.major,
18867eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                                         info.minor, info.micro));
18877eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    }
18887eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel#ifdef Py_USING_UNICODE
18897eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    init_template_buffer();
18907eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel#endif
18917eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    /* XXX When Expat supports some way of figuring out how it was
18927eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel       compiled, this should check and set native_encoding
18937eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel       appropriately.
18947eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    */
18957eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    PyModule_AddStringConstant(m, "native_encoding", "UTF-8");
18967eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
18977eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    sys_modules = PySys_GetObject("modules");
18987eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    d = PyModule_GetDict(m);
18997eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    errors_module = PyDict_GetItem(d, errmod_name);
19007eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    if (errors_module == NULL) {
19017eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        errors_module = PyModule_New(MODULE_NAME ".errors");
19027eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        if (errors_module != NULL) {
19037eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            PyDict_SetItem(sys_modules, errmod_name, errors_module);
19047eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            /* gives away the reference to errors_module */
19057eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            PyModule_AddObject(m, "errors", errors_module);
19067eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        }
19077eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    }
19087eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    Py_DECREF(errmod_name);
19097eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    model_module = PyDict_GetItem(d, modelmod_name);
19107eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    if (model_module == NULL) {
19117eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        model_module = PyModule_New(MODULE_NAME ".model");
19127eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        if (model_module != NULL) {
19137eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            PyDict_SetItem(sys_modules, modelmod_name, model_module);
19147eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            /* gives away the reference to model_module */
19157eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            PyModule_AddObject(m, "model", model_module);
19167eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        }
19177eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    }
19187eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    Py_DECREF(modelmod_name);
19197eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    if (errors_module == NULL || model_module == NULL)
19207eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        /* Don't core dump later! */
19217eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        return;
19227eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
19237eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel#if XML_COMBINED_VERSION > 19505
19247eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    {
19257eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        const XML_Feature *features = XML_GetFeatureList();
19267eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        PyObject *list = PyList_New(0);
19277eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        if (list == NULL)
19287eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            /* just ignore it */
19297eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            PyErr_Clear();
19307eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        else {
19317eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            int i = 0;
19327eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            for (; features[i].feature != XML_FEATURE_END; ++i) {
19337eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                int ok;
19347eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                PyObject *item = Py_BuildValue("si", features[i].name,
19357eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                                               features[i].value);
19367eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                if (item == NULL) {
19377eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                    Py_DECREF(list);
19387eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                    list = NULL;
19397eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                    break;
19407eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                }
19417eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                ok = PyList_Append(list, item);
19427eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                Py_DECREF(item);
19437eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                if (ok < 0) {
19447eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                    PyErr_Clear();
19457eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                    break;
19467eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                }
19477eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            }
19487eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            if (list != NULL)
19497eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                PyModule_AddObject(m, "features", list);
19507eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        }
19517eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    }
19527eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel#endif
19537eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
19547eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel#define MYCONST(name) \
19557eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    PyModule_AddStringConstant(errors_module, #name, \
19567eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                               (char*)XML_ErrorString(name))
19577eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
19587eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    MYCONST(XML_ERROR_NO_MEMORY);
19597eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    MYCONST(XML_ERROR_SYNTAX);
19607eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    MYCONST(XML_ERROR_NO_ELEMENTS);
19617eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    MYCONST(XML_ERROR_INVALID_TOKEN);
19627eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    MYCONST(XML_ERROR_UNCLOSED_TOKEN);
19637eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    MYCONST(XML_ERROR_PARTIAL_CHAR);
19647eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    MYCONST(XML_ERROR_TAG_MISMATCH);
19657eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    MYCONST(XML_ERROR_DUPLICATE_ATTRIBUTE);
19667eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    MYCONST(XML_ERROR_JUNK_AFTER_DOC_ELEMENT);
19677eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    MYCONST(XML_ERROR_PARAM_ENTITY_REF);
19687eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    MYCONST(XML_ERROR_UNDEFINED_ENTITY);
19697eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    MYCONST(XML_ERROR_RECURSIVE_ENTITY_REF);
19707eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    MYCONST(XML_ERROR_ASYNC_ENTITY);
19717eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    MYCONST(XML_ERROR_BAD_CHAR_REF);
19727eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    MYCONST(XML_ERROR_BINARY_ENTITY_REF);
19737eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    MYCONST(XML_ERROR_ATTRIBUTE_EXTERNAL_ENTITY_REF);
19747eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    MYCONST(XML_ERROR_MISPLACED_XML_PI);
19757eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    MYCONST(XML_ERROR_UNKNOWN_ENCODING);
19767eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    MYCONST(XML_ERROR_INCORRECT_ENCODING);
19777eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    MYCONST(XML_ERROR_UNCLOSED_CDATA_SECTION);
19787eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    MYCONST(XML_ERROR_EXTERNAL_ENTITY_HANDLING);
19797eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    MYCONST(XML_ERROR_NOT_STANDALONE);
19807eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    MYCONST(XML_ERROR_UNEXPECTED_STATE);
19817eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    MYCONST(XML_ERROR_ENTITY_DECLARED_IN_PE);
19827eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    MYCONST(XML_ERROR_FEATURE_REQUIRES_XML_DTD);
19837eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    MYCONST(XML_ERROR_CANT_CHANGE_FEATURE_ONCE_PARSING);
19847eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    /* Added in Expat 1.95.7. */
19857eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    MYCONST(XML_ERROR_UNBOUND_PREFIX);
19867eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    /* Added in Expat 1.95.8. */
19877eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    MYCONST(XML_ERROR_UNDECLARING_PREFIX);
19887eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    MYCONST(XML_ERROR_INCOMPLETE_PE);
19897eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    MYCONST(XML_ERROR_XML_DECL);
19907eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    MYCONST(XML_ERROR_TEXT_DECL);
19917eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    MYCONST(XML_ERROR_PUBLICID);
19927eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    MYCONST(XML_ERROR_SUSPENDED);
19937eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    MYCONST(XML_ERROR_NOT_SUSPENDED);
19947eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    MYCONST(XML_ERROR_ABORTED);
19957eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    MYCONST(XML_ERROR_FINISHED);
19967eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    MYCONST(XML_ERROR_SUSPEND_PE);
19977eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
19987eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    PyModule_AddStringConstant(errors_module, "__doc__",
19997eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                               "Constants used to describe error conditions.");
20007eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
20017eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel#undef MYCONST
20027eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
20037eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel#define MYCONST(c) PyModule_AddIntConstant(m, #c, c)
20047eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    MYCONST(XML_PARAM_ENTITY_PARSING_NEVER);
20057eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    MYCONST(XML_PARAM_ENTITY_PARSING_UNLESS_STANDALONE);
20067eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    MYCONST(XML_PARAM_ENTITY_PARSING_ALWAYS);
20077eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel#undef MYCONST
20087eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
20097eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel#define MYCONST(c) PyModule_AddIntConstant(model_module, #c, c)
20107eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    PyModule_AddStringConstant(model_module, "__doc__",
20117eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                     "Constants used to interpret content model information.");
20127eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
20137eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    MYCONST(XML_CTYPE_EMPTY);
20147eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    MYCONST(XML_CTYPE_ANY);
20157eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    MYCONST(XML_CTYPE_MIXED);
20167eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    MYCONST(XML_CTYPE_NAME);
20177eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    MYCONST(XML_CTYPE_CHOICE);
20187eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    MYCONST(XML_CTYPE_SEQ);
20197eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
20207eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    MYCONST(XML_CQUANT_NONE);
20217eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    MYCONST(XML_CQUANT_OPT);
20227eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    MYCONST(XML_CQUANT_REP);
20237eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    MYCONST(XML_CQUANT_PLUS);
20247eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel#undef MYCONST
20257eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
20267eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    /* initialize pyexpat dispatch table */
20277eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    capi.size = sizeof(capi);
20287eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    capi.magic = PyExpat_CAPI_MAGIC;
20297eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    capi.MAJOR_VERSION = XML_MAJOR_VERSION;
20307eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    capi.MINOR_VERSION = XML_MINOR_VERSION;
20317eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    capi.MICRO_VERSION = XML_MICRO_VERSION;
20327eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    capi.ErrorString = XML_ErrorString;
20337eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    capi.GetErrorCode = XML_GetErrorCode;
20347eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    capi.GetErrorColumnNumber = XML_GetErrorColumnNumber;
20357eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    capi.GetErrorLineNumber = XML_GetErrorLineNumber;
20367eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    capi.Parse = XML_Parse;
20377eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    capi.ParserCreate_MM = XML_ParserCreate_MM;
20387eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    capi.ParserFree = XML_ParserFree;
20397eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    capi.SetCharacterDataHandler = XML_SetCharacterDataHandler;
20407eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    capi.SetCommentHandler = XML_SetCommentHandler;
20417eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    capi.SetDefaultHandlerExpand = XML_SetDefaultHandlerExpand;
20427eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    capi.SetElementHandler = XML_SetElementHandler;
20437eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    capi.SetNamespaceDeclHandler = XML_SetNamespaceDeclHandler;
20447eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    capi.SetProcessingInstructionHandler = XML_SetProcessingInstructionHandler;
20457eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    capi.SetUnknownEncodingHandler = XML_SetUnknownEncodingHandler;
20467eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    capi.SetUserData = XML_SetUserData;
20477eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
20487eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    /* export using capsule */
20497eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    capi_object = PyCapsule_New(&capi, PyExpat_CAPSULE_NAME, NULL);
20507eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    if (capi_object)
20517eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        PyModule_AddObject(m, "expat_CAPI", capi_object);
20527eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel}
20537eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
20547eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielstatic void
20557eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielclear_handlers(xmlparseobject *self, int initial)
20567eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel{
20577eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    int i = 0;
20587eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    PyObject *temp;
20597eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
20607eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    for (; handler_info[i].name != NULL; i++) {
20617eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        if (initial)
20627eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            self->handlers[i] = NULL;
20637eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        else {
20647eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            temp = self->handlers[i];
20657eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            self->handlers[i] = NULL;
20667eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            Py_XDECREF(temp);
20677eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            handler_info[i].setter(self->itself, NULL);
20687eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        }
20697eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    }
20707eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel}
20717eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
20727eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielstatic struct HandlerInfo handler_info[] = {
20737eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    {"StartElementHandler",
20747eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel     (xmlhandlersetter)XML_SetStartElementHandler,
20757eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel     (xmlhandler)my_StartElementHandler},
20767eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    {"EndElementHandler",
20777eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel     (xmlhandlersetter)XML_SetEndElementHandler,
20787eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel     (xmlhandler)my_EndElementHandler},
20797eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    {"ProcessingInstructionHandler",
20807eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel     (xmlhandlersetter)XML_SetProcessingInstructionHandler,
20817eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel     (xmlhandler)my_ProcessingInstructionHandler},
20827eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    {"CharacterDataHandler",
20837eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel     (xmlhandlersetter)XML_SetCharacterDataHandler,
20847eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel     (xmlhandler)my_CharacterDataHandler},
20857eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    {"UnparsedEntityDeclHandler",
20867eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel     (xmlhandlersetter)XML_SetUnparsedEntityDeclHandler,
20877eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel     (xmlhandler)my_UnparsedEntityDeclHandler},
20887eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    {"NotationDeclHandler",
20897eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel     (xmlhandlersetter)XML_SetNotationDeclHandler,
20907eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel     (xmlhandler)my_NotationDeclHandler},
20917eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    {"StartNamespaceDeclHandler",
20927eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel     (xmlhandlersetter)XML_SetStartNamespaceDeclHandler,
20937eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel     (xmlhandler)my_StartNamespaceDeclHandler},
20947eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    {"EndNamespaceDeclHandler",
20957eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel     (xmlhandlersetter)XML_SetEndNamespaceDeclHandler,
20967eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel     (xmlhandler)my_EndNamespaceDeclHandler},
20977eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    {"CommentHandler",
20987eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel     (xmlhandlersetter)XML_SetCommentHandler,
20997eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel     (xmlhandler)my_CommentHandler},
21007eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    {"StartCdataSectionHandler",
21017eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel     (xmlhandlersetter)XML_SetStartCdataSectionHandler,
21027eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel     (xmlhandler)my_StartCdataSectionHandler},
21037eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    {"EndCdataSectionHandler",
21047eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel     (xmlhandlersetter)XML_SetEndCdataSectionHandler,
21057eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel     (xmlhandler)my_EndCdataSectionHandler},
21067eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    {"DefaultHandler",
21077eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel     (xmlhandlersetter)XML_SetDefaultHandler,
21087eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel     (xmlhandler)my_DefaultHandler},
21097eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    {"DefaultHandlerExpand",
21107eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel     (xmlhandlersetter)XML_SetDefaultHandlerExpand,
21117eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel     (xmlhandler)my_DefaultHandlerExpandHandler},
21127eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    {"NotStandaloneHandler",
21137eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel     (xmlhandlersetter)XML_SetNotStandaloneHandler,
21147eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel     (xmlhandler)my_NotStandaloneHandler},
21157eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    {"ExternalEntityRefHandler",
21167eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel     (xmlhandlersetter)XML_SetExternalEntityRefHandler,
21177eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel     (xmlhandler)my_ExternalEntityRefHandler},
21187eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    {"StartDoctypeDeclHandler",
21197eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel     (xmlhandlersetter)XML_SetStartDoctypeDeclHandler,
21207eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel     (xmlhandler)my_StartDoctypeDeclHandler},
21217eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    {"EndDoctypeDeclHandler",
21227eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel     (xmlhandlersetter)XML_SetEndDoctypeDeclHandler,
21237eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel     (xmlhandler)my_EndDoctypeDeclHandler},
21247eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    {"EntityDeclHandler",
21257eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel     (xmlhandlersetter)XML_SetEntityDeclHandler,
21267eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel     (xmlhandler)my_EntityDeclHandler},
21277eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    {"XmlDeclHandler",
21287eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel     (xmlhandlersetter)XML_SetXmlDeclHandler,
21297eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel     (xmlhandler)my_XmlDeclHandler},
21307eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    {"ElementDeclHandler",
21317eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel     (xmlhandlersetter)XML_SetElementDeclHandler,
21327eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel     (xmlhandler)my_ElementDeclHandler},
21337eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    {"AttlistDeclHandler",
21347eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel     (xmlhandlersetter)XML_SetAttlistDeclHandler,
21357eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel     (xmlhandler)my_AttlistDeclHandler},
21367eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel#if XML_COMBINED_VERSION >= 19504
21377eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    {"SkippedEntityHandler",
21387eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel     (xmlhandlersetter)XML_SetSkippedEntityHandler,
21397eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel     (xmlhandler)my_SkippedEntityHandler},
21407eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel#endif
21417eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
21427eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    {NULL, NULL, NULL} /* sentinel */
21437eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel};
2144