⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 pyexpat.c

📁 python s60 1.4.5版本的源代码
💻 C
📖 第 1 页 / 共 4 页
字号:
/* Portions Copyright (c) 2005 Nokia Corporation */
#include "Python.h"
#if PY_VERSION_HEX < 0x020000B1
#include <assert.h>
#endif
#include <ctype.h>

#include "compile.h"
#include "frameobject.h"
#ifdef HAVE_EXPAT_H
#include "expat.h"
#ifdef XML_MAJOR_VERSION
#define EXPAT_VERSION (0x10000 * XML_MAJOR_VERSION \
                       + 0x100 * XML_MINOR_VERSION \
                       + XML_MICRO_VERSION)
#else
/* Assume the oldest Expat that used expat.h and did not have version info */
#define EXPAT_VERSION 0x015f00
#endif
#else /* !defined(HAVE_EXPAT_H) */
#include "xmlparse.h"
/* Assume Expat 1.1 unless told otherwise */
#ifndef EXPAT_VERSION
#define EXPAT_VERSION 0x010100
#endif
#endif /* !defined(HAVE_EXPAT_H) */

#ifndef PyGC_HEAD_SIZE
#define PyGC_HEAD_SIZE 0
#define PyObject_GC_Init(x)
#define PyObject_GC_Fini(m)
#define Py_TPFLAGS_GC 0
#endif

#if (PY_MAJOR_VERSION == 1 && PY_MINOR_VERSION > 5) || (PY_MAJOR_VERSION == 2 && PY_MINOR_VERSION < 2)
/* In Python 1.6, 2.0 and  2.1, disabling Unicode was not possible. */
#define Py_USING_UNICODE
#endif

enum HandlerTypes {
    StartElement,
    EndElement,
    ProcessingInstruction,
    CharacterData,
    UnparsedEntityDecl,
    NotationDecl,
    StartNamespaceDecl,
    EndNamespaceDecl,
    Comment,
    StartCdataSection,
    EndCdataSection,
    Default,
    DefaultHandlerExpand,
    NotStandalone,
    ExternalEntityRef,
#if EXPAT_VERSION >= 0x010200
    StartDoctypeDecl,
    EndDoctypeDecl,
#endif
#if EXPAT_VERSION == 0x010200
    ExternalParsedEntityDecl,
    InternalParsedEntityDecl,
#endif
#if EXPAT_VERSION >= 0x015f00
    EntityDecl,
    XmlDecl,
    ElementDecl,
    AttlistDecl,
#endif
    _DummyDecl
};

static PyObject *ErrorObject;

/* ----------------------------------------------------- */

/* Declarations for objects of type xmlparser */

typedef struct {
    PyObject_HEAD

    XML_Parser itself;
    int returns_unicode;        /* True if Unicode strings are returned;
                                   if false, UTF-8 strings are returned */
    int ordered_attributes;     /* Return attributes as a list. */
    int specified_attributes;   /* Report only specified attributes. */
    int in_callback;            /* Is a callback active? */
    PyObject **handlers;
} xmlparseobject;

staticforward PyTypeObject Xmlparsetype;

typedef void (*xmlhandlersetter)(XML_Parser self, void *meth);
typedef void* xmlhandler;

struct HandlerInfo {
    const char *name;
    xmlhandlersetter setter;
    xmlhandler handler;
    PyCodeObject *tb_code;
};

staticforward struct HandlerInfo handler_info[64];

/* Set an integer attribute on the error object; return true on success,
 * false on an exception.
 */
static int
set_error_attr(PyObject *err, char *name, int value)
{
    PyObject *v = PyInt_FromLong(value);

    if (v != NULL && PyObject_SetAttrString(err, name, v) == -1) {
        Py_DECREF(v);
        return 0;
    }
    return 1;
}

/* Build and set an Expat exception, including positioning
 * information.  Always returns NULL.
 */
static PyObject *
set_error(xmlparseobject *self)
{
    PyObject *err;
    char buffer[256];
    XML_Parser parser = self->itself;
    int lineno = XML_GetErrorLineNumber(parser);
    int column = XML_GetErrorColumnNumber(parser);
    enum XML_Error code = XML_GetErrorCode(parser);

    PyOS_snprintf(buffer, sizeof(buffer), "%.200s: line %i, column %i",
            XML_ErrorString(code), lineno, column);
    err = PyObject_CallFunction(ErrorObject, "s", buffer);
    if (  err != NULL
          && set_error_attr(err, "code", code)
          && set_error_attr(err, "offset", column)
          && set_error_attr(err, "lineno", lineno)) {
        PyErr_SetObject(ErrorObject, err);
    }
    return NULL;
}


#if EXPAT_VERSION == 0x010200
/* Convert an array of attributes and their values into a Python dict */

static PyObject *
conv_atts_using_string(XML_Char **atts)
{
    PyObject *attrs_obj = NULL;
    XML_Char **attrs_p, **attrs_k = NULL;
    int attrs_len;
    PyObject *rv;

    if ((attrs_obj = PyDict_New()) == NULL) 
        goto finally;
    for (attrs_len = 0, attrs_p = atts; 
         *attrs_p;
         attrs_p++, attrs_len++) {
        if (attrs_len % 2) {
            rv = PyString_FromString(*attrs_p);  
            if (!rv) {
                Py_DECREF(attrs_obj);
                attrs_obj = NULL;
                goto finally;
            }
            if (PyDict_SetItemString(attrs_obj,
                                     (char*)*attrs_k, rv) < 0) {
                Py_DECREF(attrs_obj);
                attrs_obj = NULL;
                goto finally;
            }
            Py_DECREF(rv);
        }
        else 
            attrs_k = attrs_p;
    }
 finally:
    return attrs_obj;
}
#endif

#ifdef Py_USING_UNICODE
#if EXPAT_VERSION == 0x010200
static PyObject *
conv_atts_using_unicode(XML_Char **atts)
{
    PyObject *attrs_obj;
    XML_Char **attrs_p, **attrs_k = NULL;
    int attrs_len;

    if ((attrs_obj = PyDict_New()) == NULL) 
        goto finally;
    for (attrs_len = 0, attrs_p = atts; 
         *attrs_p;
         attrs_p++, attrs_len++) {
        if (attrs_len % 2) {
            PyObject *attr_str, *value_str;
            const char *p = (const char *) (*attrs_k);
            attr_str = PyUnicode_DecodeUTF8(p, strlen(p), "strict"); 
            if (!attr_str) {
                Py_DECREF(attrs_obj);
                attrs_obj = NULL;
                goto finally;
            }
            p = (const char *) *attrs_p;
            value_str = PyUnicode_DecodeUTF8(p, strlen(p), "strict");
            if (!value_str) {
                Py_DECREF(attrs_obj);
                Py_DECREF(attr_str);
                attrs_obj = NULL;
                goto finally;
            }
            if (PyDict_SetItem(attrs_obj, attr_str, value_str) < 0) {
                Py_DECREF(attrs_obj);
                Py_DECREF(attr_str);
                Py_DECREF(value_str);
                attrs_obj = NULL;
                goto finally;
            }
            Py_DECREF(attr_str);
            Py_DECREF(value_str);
        }
        else
            attrs_k = attrs_p;
    }
 finally:
    return attrs_obj;
}
#endif

/* Convert a string of XML_Chars into a Unicode string.
   Returns None if str is a null pointer. */

static PyObject *
conv_string_to_unicode(XML_Char *str)
{
    /* XXX currently this code assumes that XML_Char is 8-bit, 
       and hence in UTF-8.  */
    /* UTF-8 from Expat, Unicode desired */
    if (str == NULL) {
        Py_INCREF(Py_None);
        return Py_None;
    }
    return PyUnicode_DecodeUTF8((const char *)str, 
                                strlen((const char *)str), 
                                "strict");
}

static PyObject *
conv_string_len_to_unicode(const XML_Char *str, int len)
{
    /* XXX currently this code assumes that XML_Char is 8-bit, 
       and hence in UTF-8.  */
    /* UTF-8 from Expat, Unicode desired */
    if (str == NULL) {
        Py_INCREF(Py_None);
        return Py_None;
    }
    return PyUnicode_DecodeUTF8((const char *)str, len, "strict");
}
#endif

/* Convert a string of XML_Chars into an 8-bit Python string.
   Returns None if str is a null pointer. */

static PyObject *
conv_string_to_utf8(XML_Char *str)
{
    /* XXX currently this code assumes that XML_Char is 8-bit, 
       and hence in UTF-8.  */
    /* UTF-8 from Expat, UTF-8 desired */
    if (str == NULL) {
        Py_INCREF(Py_None);
        return Py_None;
    }
    return PyString_FromString((const char *)str);
}

static PyObject *
conv_string_len_to_utf8(const XML_Char *str,  int len) 
{
    /* XXX currently this code assumes that XML_Char is 8-bit, 
       and hence in UTF-8.  */
    /* UTF-8 from Expat, UTF-8 desired */
    if (str == NULL) {
        Py_INCREF(Py_None);
        return Py_None;
    }
    return PyString_FromStringAndSize((const char *)str, len);
}

/* Callback routines */

static void clear_handlers(xmlparseobject *self, int initial);

static void
flag_error(xmlparseobject *self)
{
    clear_handlers(self, 0);
}

static PyCodeObject*
getcode(enum HandlerTypes slot, char* func_name, int lineno)
{
    PyObject *code = NULL;
    PyObject *name = NULL;
    PyObject *nulltuple = NULL;
    PyObject *filename = NULL;

    if (handler_info[slot].tb_code == NULL) {
        code = PyString_FromString("");
        if (code == NULL)
            goto failed;
        name = PyString_FromString(func_name);
        if (name == NULL)
            goto failed;
        nulltuple = PyTuple_New(0);
        if (nulltuple == NULL)
            goto failed;
        filename = PyString_FromString(__FILE__);
        handler_info[slot].tb_code =
            PyCode_New(0,		/* argcount */
                       0,		/* nlocals */
                       0,		/* stacksize */
                       0,		/* flags */
                       code,		/* code */
                       nulltuple,	/* consts */
                       nulltuple,	/* names */
                       nulltuple,	/* varnames */
#if PYTHON_API_VERSION >= 1010
                       nulltuple,	/* freevars */
                       nulltuple,	/* cellvars */
#endif
                       filename,	/* filename */
                       name,		/* name */
                       lineno,		/* firstlineno */
                       code		/* lnotab */
                       );
        if (handler_info[slot].tb_code == NULL)
            goto failed;
        Py_DECREF(code);
        Py_DECREF(nulltuple);
        Py_DECREF(filename);
        Py_DECREF(name);
    }
    return handler_info[slot].tb_code;
 failed:
    Py_XDECREF(code);
    Py_XDECREF(name);
    return NULL;
}

static int
trace_frame(PyThreadState *tstate, PyFrameObject *f, int code, PyObject *val)
{
    int result = 0;
    if (!tstate->use_tracing || tstate->tracing)
	return 0;
    if (tstate->c_profilefunc != NULL) {
	tstate->tracing++;
	result = tstate->c_profilefunc(tstate->c_profileobj,
				       f, code , val);
	tstate->use_tracing = ((tstate->c_tracefunc != NULL)
			       || (tstate->c_profilefunc != NULL));
	tstate->tracing--;
	if (result)
	    return result;
    }
    if (tstate->c_tracefunc != NULL) {
	tstate->tracing++;
	result = tstate->c_tracefunc(tstate->c_traceobj,
				     f, code , val);
	tstate->use_tracing = ((tstate->c_tracefunc != NULL)
			       || (tstate->c_profilefunc != NULL));
	tstate->tracing--;
    }	
    return result;
}

static PyObject*
call_with_frame(PyCodeObject *c, PyObject* func, PyObject* args)
{
    PyThreadState *tstate = PyThreadState_GET();
    PyFrameObject *f;
    PyObject *res;

    if (c == NULL)
        return NULL;
    
    f = PyFrame_New(
                    tstate,			/*back*/
                    c,				/*code*/
                    PyEval_GetGlobals(),	/*globals*/
                    NULL			/*locals*/
                    );
    if (f == NULL)
        return NULL;
    tstate->frame = f;
    if (trace_frame(tstate, f, PyTrace_CALL, Py_None)) {
	Py_DECREF(f);
	return NULL;
    }
    res = PyEval_CallObject(func, args);
    if (res == NULL && tstate->curexc_traceback == NULL)
        PyTraceBack_Here(f);
    else {
	if (trace_frame(tstate, f, PyTrace_RETURN, res)) {
	    Py_XDECREF(res);
	    res = NULL;
	}
    }
    tstate->frame = f->f_back;
    Py_DECREF(f);
    return res;
}

#ifndef Py_USING_UNICODE
#define STRING_CONV_FUNC conv_string_to_utf8
#else
/* Python 1.6 and later versions */
#define STRING_CONV_FUNC (self->returns_unicode \
                          ? conv_string_to_unicode : conv_string_to_utf8)
#endif

static void
my_StartElementHandler(void *userData,
                       const XML_Char *name, const XML_Char **atts)
{
    xmlparseobject *self = (xmlparseobject *)userData;

    if (self->handlers[StartElement]
        && self->handlers[StartElement] != Py_None) {
        PyObject *container, *rv, *args;
        int i, max;

        /* Set max to the number of slots filled in atts[]; max/2 is
         * the number of attributes we need to process.
         */
        if (self->specified_attributes) {
            max = XML_GetSpecifiedAttributeCount(self->itself);
        }
        else {
            max = 0;
            while (atts[max] != NULL)
                max += 2;
        }
        /* Build the container. */
        if (self->ordered_attributes)
            container = PyList_New(max);
        else
            container = PyDict_New();
        if (container == NULL) {
            flag_error(self);
            return;
        }
        for (i = 0; i < max; i += 2) {
            PyObject *n = STRING_CONV_FUNC((XML_Char *) atts[i]);
            PyObject *v;
            if (n == NULL) {
                flag_error(self);
                Py_DECREF(container);
                return;
            }
            v = STRING_CONV_FUNC((XML_Char *) atts[i+1]);
            if (v == NULL) {
                flag_error(self);
                Py_DECREF(container);
                Py_DECREF(n);
                return;
            }
            if (self->ordered_attributes) {
                PyList_SET_ITEM(container, i, n);
                PyList_SET_ITEM(container, i+1, v);
            }

⌨️ 快捷键说明

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