pyexpat.c

来自「python s60 1.4.5版本的源代码」· C语言 代码 · 共 1,906 行 · 第 1/4 页

C
1,906
字号
	0,			/*tp_as_number*/
	0,		/*tp_as_sequence*/
	0,		/*tp_as_mapping*/
	(hashfunc)0,		/*tp_hash*/
	(ternaryfunc)0,		/*tp_call*/
	(reprfunc)0,		/*tp_str*/
	0,		/* tp_getattro */
	0,		/* tp_setattro */
	0,		/* tp_as_buffer */
#ifdef Py_TPFLAGS_HAVE_GC
	Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, /*tp_flags*/	
#else
	Py_TPFLAGS_DEFAULT | Py_TPFLAGS_GC, /*tp_flags*/	
#endif
	Xmlparsetype__doc__, /* Documentation string */
#ifdef WITH_CYCLE_GC
	(traverseproc)xmlparse_traverse,	/* tp_traverse */
	(inquiry)xmlparse_clear		/* tp_clear */
#else
	0, 0
#endif
};

/* End of code for xmlparser objects */
/* -------------------------------------------------------- */

static char pyexpat_ParserCreate__doc__[] =
"ParserCreate([encoding[, namespace_separator]]) -> parser\n\
Return a new XML parser object.";

static PyObject *
pyexpat_ParserCreate(PyObject *notused, PyObject *args, PyObject *kw)
{
    char *encoding = NULL;
    char *namespace_separator = NULL;
    static char *kwlist[] = {"encoding", "namespace_separator", NULL};

    if (!PyArg_ParseTupleAndKeywords(args, kw, "|zz:ParserCreate", kwlist,
                                     &encoding, &namespace_separator))
        return NULL;
    if (namespace_separator != NULL
        && strlen(namespace_separator) > 1) {
        PyErr_SetString(PyExc_ValueError,
                        "namespace_separator must be at most one"
                        " character, omitted, or None");
        return NULL;
    }
    return newxmlparseobject(encoding, namespace_separator);
}

static char pyexpat_ErrorString__doc__[] =
"ErrorString(errno) -> string\n\
Returns string error for given number.";

static PyObject *
pyexpat_ErrorString(PyObject *self, PyObject *args)
{
    long code = 0;

    if (!PyArg_ParseTuple(args, "l:ErrorString", &code))
        return NULL;
    return Py_BuildValue("z", XML_ErrorString((int)code));
}

/* List of methods defined in the module */

static struct PyMethodDef pyexpat_methods[] = {
    {"ParserCreate",	(PyCFunction)pyexpat_ParserCreate,
     METH_VARARGS|METH_KEYWORDS, pyexpat_ParserCreate__doc__},
    {"ErrorString",	(PyCFunction)pyexpat_ErrorString,
     METH_VARARGS,	pyexpat_ErrorString__doc__},
 
    {NULL,	 (PyCFunction)NULL, 0, NULL}		/* sentinel */
};

/* Module docstring */

static char pyexpat_module_documentation[] = 
"Python wrapper for Expat parser.";

#if PY_VERSION_HEX < 0x20000F0

/* 1.5 compatibility: PyModule_AddObject */
static int
PyModule_AddObject(PyObject *m, char *name, PyObject *o)
{
    PyObject *dict;
    if (!PyModule_Check(m) || o == NULL)
        return -1;
    dict = PyModule_GetDict(m);
    if (dict == NULL)
        return -1;
    if (PyDict_SetItemString(dict, name, o))
        return -1;
    Py_DECREF(o);
    return 0;
}

int 
PyModule_AddIntConstant(PyObject *m, char *name, long value)
{
    return PyModule_AddObject(m, name, PyInt_FromLong(value));
}

static int 
PyModule_AddStringConstant(PyObject *m, char *name, char *value)
{
    return PyModule_AddObject(m, name, PyString_FromString(value));
}

#endif


/* Return a Python string that represents the version number without the
 * extra cruft added by revision control, even if the right options were
 * given to the "cvs export" command to make it not include the extra
 * cruft.
 */
static PyObject *
get_version_string(void)
{
    static char *rcsid = "$Revision: 1.1 $";
    char *rev = rcsid;
    int i = 0;

    while (!isdigit(*rev))
        ++rev;
    while (rev[i] != ' ' && rev[i] != '\0')
        ++i;

    return PyString_FromStringAndSize(rev, i);
}

/* Initialization function for the module */

#ifndef MODULE_NAME
#define MODULE_NAME "pyexpat"
#endif

#ifndef MODULE_INITFUNC
#define MODULE_INITFUNC initpyexpat
#endif

void MODULE_INITFUNC(void);  /* avoid compiler warnings */

DL_EXPORT(void)
MODULE_INITFUNC(void)
{
    PyObject *m, *d;
    PyObject *errmod_name = PyString_FromString(MODULE_NAME ".errors");
    PyObject *errors_module;
    PyObject *modelmod_name;
    PyObject *model_module;
    PyObject *sys_modules;

    if (errmod_name == NULL)
        return;
    modelmod_name = PyString_FromString(MODULE_NAME ".model");
    if (modelmod_name == NULL)
        return;

    Xmlparsetype.ob_type = &PyType_Type;

    /* Create the module and add the functions */
    m = Py_InitModule3(MODULE_NAME, pyexpat_methods,
                       pyexpat_module_documentation);

    /* Add some symbolic constants to the module */
    if (ErrorObject == NULL) {
        ErrorObject = PyErr_NewException("xml.parsers.expat.ExpatError",
                                         NULL, NULL);
        if (ErrorObject == NULL)
            return;
    }
    Py_INCREF(ErrorObject);
    PyModule_AddObject(m, "error", ErrorObject);
    Py_INCREF(ErrorObject);
    PyModule_AddObject(m, "ExpatError", ErrorObject);
    Py_INCREF(&Xmlparsetype);
    PyModule_AddObject(m, "XMLParserType", (PyObject *) &Xmlparsetype);

    PyModule_AddObject(m, "__version__", get_version_string());
#if EXPAT_VERSION >= 0x015f02
    PyModule_AddStringConstant(m, "EXPAT_VERSION",
                               (char *) XML_ExpatVersion());
    {
        XML_Expat_Version info = XML_ExpatVersionInfo();
        PyModule_AddObject(m, "version_info",
                           Py_BuildValue("(iii)", info.major,
                                         info.minor, info.micro));
    }
#endif
#ifdef Py_USING_UNICODE
    init_template_buffer();
#endif
    /* XXX When Expat supports some way of figuring out how it was
       compiled, this should check and set native_encoding 
       appropriately. 
    */
    PyModule_AddStringConstant(m, "native_encoding", "UTF-8");

    sys_modules = PySys_GetObject("modules");
    d = PyModule_GetDict(m);
    errors_module = PyDict_GetItem(d, errmod_name);
    if (errors_module == NULL) {
        errors_module = PyModule_New(MODULE_NAME ".errors");
        if (errors_module != NULL) {
            PyDict_SetItem(sys_modules, errmod_name, errors_module);
            /* gives away the reference to errors_module */
            PyModule_AddObject(m, "errors", errors_module);
        }
    }
    Py_DECREF(errmod_name);
    model_module = PyDict_GetItem(d, modelmod_name);
    if (model_module == NULL) {
        model_module = PyModule_New(MODULE_NAME ".model");
        if (model_module != NULL) {
            PyDict_SetItem(sys_modules, modelmod_name, model_module);
            /* gives away the reference to model_module */
            PyModule_AddObject(m, "model", model_module);
        }
    }
    Py_DECREF(modelmod_name);
    if (errors_module == NULL || model_module == NULL)
        /* Don't core dump later! */
        return;

#define MYCONST(name) \
    PyModule_AddStringConstant(errors_module, #name, \
                               (char*)XML_ErrorString(name))

    MYCONST(XML_ERROR_NO_MEMORY);
    MYCONST(XML_ERROR_SYNTAX);
    MYCONST(XML_ERROR_NO_ELEMENTS);
    MYCONST(XML_ERROR_INVALID_TOKEN);
    MYCONST(XML_ERROR_UNCLOSED_TOKEN);
    MYCONST(XML_ERROR_PARTIAL_CHAR);
    MYCONST(XML_ERROR_TAG_MISMATCH);
    MYCONST(XML_ERROR_DUPLICATE_ATTRIBUTE);
    MYCONST(XML_ERROR_JUNK_AFTER_DOC_ELEMENT);
    MYCONST(XML_ERROR_PARAM_ENTITY_REF);
    MYCONST(XML_ERROR_UNDEFINED_ENTITY);
    MYCONST(XML_ERROR_RECURSIVE_ENTITY_REF);
    MYCONST(XML_ERROR_ASYNC_ENTITY);
    MYCONST(XML_ERROR_BAD_CHAR_REF);
    MYCONST(XML_ERROR_BINARY_ENTITY_REF);
    MYCONST(XML_ERROR_ATTRIBUTE_EXTERNAL_ENTITY_REF);
    MYCONST(XML_ERROR_MISPLACED_XML_PI);
    MYCONST(XML_ERROR_UNKNOWN_ENCODING);
    MYCONST(XML_ERROR_INCORRECT_ENCODING);
    MYCONST(XML_ERROR_UNCLOSED_CDATA_SECTION);
    MYCONST(XML_ERROR_EXTERNAL_ENTITY_HANDLING);
    MYCONST(XML_ERROR_NOT_STANDALONE);

    PyModule_AddStringConstant(errors_module, "__doc__",
                               "Constants used to describe error conditions.");

#undef MYCONST

#if EXPAT_VERSION >= 0x010200
#define MYCONST(c) PyModule_AddIntConstant(m, #c, c)
    MYCONST(XML_PARAM_ENTITY_PARSING_NEVER);
    MYCONST(XML_PARAM_ENTITY_PARSING_UNLESS_STANDALONE);
    MYCONST(XML_PARAM_ENTITY_PARSING_ALWAYS);
#undef MYCONST
#endif

#if EXPAT_VERSION >= 0x015f00
#define MYCONST(c) PyModule_AddIntConstant(model_module, #c, c)
    PyModule_AddStringConstant(model_module, "__doc__",
                     "Constants used to interpret content model information.");

    MYCONST(XML_CTYPE_EMPTY);
    MYCONST(XML_CTYPE_ANY);
    MYCONST(XML_CTYPE_MIXED);
    MYCONST(XML_CTYPE_NAME);
    MYCONST(XML_CTYPE_CHOICE);
    MYCONST(XML_CTYPE_SEQ);

    MYCONST(XML_CQUANT_NONE);
    MYCONST(XML_CQUANT_OPT);
    MYCONST(XML_CQUANT_REP);
    MYCONST(XML_CQUANT_PLUS);
#undef MYCONST
#endif
}

static void
clear_handlers(xmlparseobject *self, int initial)
{
    int i = 0;
    PyObject *temp;

    for (; handler_info[i].name!=NULL; i++) {
        if (initial)
	    self->handlers[i]=NULL;
	else {
            temp = self->handlers[i];
            self->handlers[i] = NULL;
            Py_XDECREF(temp);
	    handler_info[i].setter(self->itself, NULL);
        }
    }
}

typedef void (*pairsetter)(XML_Parser, void *handler1, void *handler2);

static void
pyxml_UpdatePairedHandlers(xmlparseobject *self, 
                           int startHandler, 
                           int endHandler,
                           pairsetter setter)
{
    void *start_handler = NULL;
    void *end_handler = NULL;

    if (self->handlers[startHandler]
        && self->handlers[startHandler] != Py_None) {
        start_handler = handler_info[startHandler].handler;
    }
    if (self->handlers[endHandler]
        && self->handlers[endHandler] != Py_None) {
        end_handler = handler_info[endHandler].handler;
    }
    setter(self->itself, start_handler, end_handler);
}

static void
pyxml_SetStartElementHandler(XML_Parser parser, void *junk)
{
    pyxml_UpdatePairedHandlers((xmlparseobject *)XML_GetUserData(parser),
                               StartElement, EndElement,
                               (pairsetter)XML_SetElementHandler);
}

static void
pyxml_SetEndElementHandler(XML_Parser parser, void *junk)
{
    pyxml_UpdatePairedHandlers((xmlparseobject *)XML_GetUserData(parser), 
                               StartElement, EndElement,
                               (pairsetter)XML_SetElementHandler);
}

static void
pyxml_SetStartNamespaceDeclHandler(XML_Parser parser, void *junk)
{
    pyxml_UpdatePairedHandlers((xmlparseobject *)XML_GetUserData(parser), 
                               StartNamespaceDecl, EndNamespaceDecl,
                               (pairsetter)XML_SetNamespaceDeclHandler);
}

static void
pyxml_SetEndNamespaceDeclHandler(XML_Parser parser, void *junk)
{
    pyxml_UpdatePairedHandlers((xmlparseobject *)XML_GetUserData(parser), 
                               StartNamespaceDecl, EndNamespaceDecl,
                               (pairsetter)XML_SetNamespaceDeclHandler);
}

static void
pyxml_SetStartCdataSection(XML_Parser parser, void *junk)
{
    pyxml_UpdatePairedHandlers((xmlparseobject *)XML_GetUserData(parser),
                               StartCdataSection, EndCdataSection,
                               (pairsetter)XML_SetCdataSectionHandler);
}

static void
pyxml_SetEndCdataSection(XML_Parser parser, void *junk)
{
    pyxml_UpdatePairedHandlers((xmlparseobject *)XML_GetUserData(parser), 
                               StartCdataSection, EndCdataSection, 
                               (pairsetter)XML_SetCdataSectionHandler);
}

#if EXPAT_VERSION >= 0x010200

static void
pyxml_SetStartDoctypeDeclHandler(XML_Parser parser, void *junk)
{
    pyxml_UpdatePairedHandlers((xmlparseobject *)XML_GetUserData(parser),
                               StartDoctypeDecl, EndDoctypeDecl,
                               (pairsetter)XML_SetDoctypeDeclHandler);
}

static void
pyxml_SetEndDoctypeDeclHandler(XML_Parser parser, void *junk)
{
    pyxml_UpdatePairedHandlers((xmlparseobject *)XML_GetUserData(parser),
                               StartDoctypeDecl, EndDoctypeDecl,
                               (pairsetter)XML_SetDoctypeDeclHandler);
}

#endif

statichere struct HandlerInfo handler_info[] = {
    {"StartElementHandler", 
     pyxml_SetStartElementHandler, 
     (xmlhandler)my_StartElementHandler},
    {"EndElementHandler", 
     pyxml_SetEndElementHandler, 
     (xmlhandler)my_EndElementHandler},
    {"ProcessingInstructionHandler", 
     (xmlhandlersetter)XML_SetProcessingInstructionHandler,
     (xmlhandler)my_ProcessingInstructionHandler},
    {"CharacterDataHandler", 
     (xmlhandlersetter)XML_SetCharacterDataHandler,
     (xmlhandler)my_CharacterDataHandler},
    {"UnparsedEntityDeclHandler", 
     (xmlhandlersetter)XML_SetUnparsedEntityDeclHandler,
     (xmlhandler)my_UnparsedEntityDeclHandler },
    {"NotationDeclHandler", 
     (xmlhandlersetter)XML_SetNotationDeclHandler,
     (xmlhandler)my_NotationDeclHandler },
    {"StartNamespaceDeclHandler", 
     pyxml_SetStartNamespaceDeclHandler,
     (xmlhandler)my_StartNamespaceDeclHandler },
    {"EndNamespaceDeclHandler", 
     pyxml_SetEndNamespaceDeclHandler,
     (xmlhandler)my_EndNamespaceDeclHandler },
    {"CommentHandler",
     (xmlhandlersetter)XML_SetCommentHandler,
     (xmlhandler)my_CommentHandler},
    {"StartCdataSectionHandler",
     pyxml_SetStartCdataSection,
     (xmlhandler)my_StartCdataSectionHandler},
    {"EndCdataSectionHandler",
     pyxml_SetEndCdataSection,
     (xmlhandler)my_EndCdataSectionHandler},
    {"DefaultHandler",
     (xmlhandlersetter)XML_SetDefaultHandler,
     (xmlhandler)my_DefaultHandler},
    {"DefaultHandlerExpand",
     (xmlhandlersetter)XML_SetDefaultHandlerExpand,
     (xmlhandler)my_DefaultHandlerExpandHandler},
    {"NotStandaloneHandler",
     (xmlhandlersetter)XML_SetNotStandaloneHandler,
     (xmlhandler)my_NotStandaloneHandler},
    {"ExternalEntityRefHandler",
     (xmlhandlersetter)XML_SetExternalEntityRefHandler,
     (xmlhandler)my_ExternalEntityRefHandler },
#if EXPAT_VERSION >= 0x010200
    {"StartDoctypeDeclHandler",
     pyxml_SetStartDoctypeDeclHandler,
     (xmlhandler)my_StartDoctypeDeclHandler},
    {"EndDoctypeDeclHandler",
     pyxml_SetEndDoctypeDeclHandler,
     (xmlhandler)my_EndDoctypeDeclHandler},
#endif
#if EXPAT_VERSION == 0x010200
    {"ExternalParsedEntityDeclHandler",
     (xmlhandlersetter)XML_SetExternalParsedEntityDeclHandler,
     (xmlhandler)my_ExternalParsedEntityDeclHandler},
    {"InternalParsedEntityDeclHandler",
     (xmlhandlersetter)XML_SetInternalParsedEntityDeclHandler,
     (xmlhandler)my_InternalParsedEntityDeclHandler},
#endif
#if EXPAT_VERSION >= 0x015f00
    {"EntityDeclHandler",
     (xmlhandlersetter)XML_SetEntityDeclHandler,
     (xmlhandler)my_EntityDeclHandler},
    {"XmlDeclHandler",
     (xmlhandlersetter)XML_SetXmlDeclHandler,
     (xmlhandler)my_XmlDeclHandler},
    {"ElementDeclHandler",
     (xmlhandlersetter)XML_SetElementDeclHandler,
     (xmlhandler)my_ElementDeclHandler},
    {"AttlistDeclHandler",
     (xmlhandlersetter)XML_SetAttlistDeclHandler,
     (xmlhandler)my_AttlistDeclHandler},
#endif /* Expat version 1.95 or better */

    {NULL, NULL, NULL} /* sentinel */
};

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?