summaryrefslogtreecommitdiffstats
path: root/Modules
diff options
context:
space:
mode:
authorFredrik Lundh <fredrik@pythonware.com>2005-12-16 22:05:40 (GMT)
committerFredrik Lundh <fredrik@pythonware.com>2005-12-16 22:05:40 (GMT)
commit7cfe6eee0d3820f3a91a1838b93cf61fe7287e15 (patch)
treeaa25404105cd85d17d7e2d809127b9a3c7e080e2 /Modules
parent6ee6952eb2f86d1708a960e235be25cebdf65f58 (diff)
downloadcpython-7cfe6eee0d3820f3a91a1838b93cf61fe7287e15.zip
cpython-7cfe6eee0d3820f3a91a1838b93cf61fe7287e15.tar.gz
cpython-7cfe6eee0d3820f3a91a1838b93cf61fe7287e15.tar.bz2
updating to cElementTree 1.0.5
Diffstat (limited to 'Modules')
-rw-r--r--Modules/_elementtree.c2723
1 files changed, 0 insertions, 2723 deletions
diff --git a/Modules/_elementtree.c b/Modules/_elementtree.c
deleted file mode 100644
index 16547d2..0000000
--- a/Modules/_elementtree.c
+++ /dev/null
@@ -1,2723 +0,0 @@
-/*
- * ElementTree
- * $Id: /work/modules/celementtree/cElementTree.c 1089 2005-12-14T21:22:30.257830Z Fredrik $
- *
- * elementtree accelerator
- *
- * History:
- * 1999-06-20 fl created (as part of sgmlop)
- * 2001-05-29 fl effdom edition
- * 2001-06-05 fl backported to unix; fixed bogus free in clear
- * 2001-07-10 fl added findall helper
- * 2003-02-27 fl elementtree edition (alpha)
- * 2004-06-03 fl updates for elementtree 1.2
- * 2005-01-05 fl added universal name cache, Element/SubElement factories
- * 2005-01-06 fl moved python helpers into C module; removed 1.5.2 support
- * 2005-01-07 fl added 2.1 support; work around broken __copy__ in 2.3
- * 2005-01-08 fl added makeelement method; fixed path support
- * 2005-01-10 fl optimized memory usage
- * 2005-01-11 fl first public release (cElementTree 0.8)
- * 2005-01-12 fl split element object into base and extras
- * 2005-01-13 fl use tagged pointers for tail/text (cElementTree 0.9)
- * 2005-01-17 fl added treebuilder close method
- * 2005-01-17 fl fixed crash in getchildren
- * 2005-01-18 fl removed observer api, added iterparse (cElementTree 0.9.3)
- * 2005-01-23 fl revised iterparse api; added namespace event support (0.9.8)
- * 2005-01-26 fl added VERSION module property (cElementTree 1.0)
- * 2005-01-28 fl added remove method (1.0.1)
- * 2005-03-01 fl added iselement function; fixed makeelement aliasing (1.0.2)
- * 2005-03-13 fl export Comment and ProcessingInstruction/PI helpers
- * 2005-03-26 fl added Comment and PI support to XMLParser
- * 2005-03-27 fl event optimizations; complain about bogus events
- * 2005-08-08 fl fixed read error handling in parse
- * 2005-08-11 fl added runtime test for copy workaround (1.0.3)
- * 2005-12-13 fl added expat_capi support (for xml.etree)
- *
- * Copyright (c) 1999-2005 by Secret Labs AB. All rights reserved.
- * Copyright (c) 1999-2005 by Fredrik Lundh.
- *
- * info@pythonware.com
- * http://www.pythonware.com
- */
-
-/* Licensed to PSF under a Contributor Agreement. */
-/* See http://www.python.org/2.4/license for licensing details. */
-
-#include "Python.h"
-
-#define VERSION "1.0.4"
-
-/* -------------------------------------------------------------------- */
-/* configuration */
-
-/* Leave defined to include the expat-based XMLParser type */
-#define USE_EXPAT
-
-/* Define to to all expat calls via pyexpat's embedded expat library */
-/* #define USE_PYEXPAT_CAPI */
-
-/* An element can hold this many children without extra memory
- allocations. */
-#define STATIC_CHILDREN 4
-
-/* For best performance, chose a value so that 80-90% of all nodes
- have no more than the given number of children. Set this to zero
- to minimize the size of the element structure itself (this only
- helps if you have lots of leaf nodes with attributes). */
-
-/* Also note that pymalloc always allocates blocks in multiples of
- eight bytes. For the current version of cElementTree, this means
- that the number of children should be an even number, at least on
- 32-bit platforms. */
-
-/* -------------------------------------------------------------------- */
-
-#if 0
-static int memory = 0;
-#define ALLOC(size, comment)\
-do { memory += size; printf("%8d - %s\n", memory, comment); } while (0)
-#define RELEASE(size, comment)\
-do { memory -= size; printf("%8d - %s\n", memory, comment); } while (0)
-#else
-#define ALLOC(size, comment)
-#define RELEASE(size, comment)
-#endif
-
-/* compiler tweaks */
-#if defined(_MSC_VER)
-#define LOCAL(type) static __inline type __fastcall
-#else
-#define LOCAL(type) static type
-#endif
-
-/* compatibility macros */
-#if (PY_VERSION_HEX < 0x02040000)
-#define PyDict_CheckExact PyDict_Check
-#if (PY_VERSION_HEX < 0x02020000)
-#define PyList_CheckExact PyList_Check
-#define PyString_CheckExact PyString_Check
-#if (PY_VERSION_HEX >= 0x01060000)
-#define Py_USING_UNICODE /* always enabled for 2.0 and 2.1 */
-#endif
-#endif
-#endif
-
-#if (PY_VERSION_HEX >= 0x02050000)
-#define PY_CONST const /* 2.5 adds const to some API:s */
-#else
-#define PY_CONST
-#endif
-
-#if !defined(Py_RETURN_NONE)
-#define Py_RETURN_NONE return Py_INCREF(Py_None), Py_None
-#endif
-
-/* macros used to store 'join' flags in string object pointers. note
- that all use of text and tail as object pointers must be wrapped in
- JOIN_OBJ. see comments in the ElementObject definition for more
- info. */
-#define JOIN_GET(p) ((Py_uintptr_t) (p) & 1)
-#define JOIN_SET(p, flag) ((void*) ((Py_uintptr_t) (JOIN_OBJ(p)) | (flag)))
-#define JOIN_OBJ(p) ((PyObject*) ((Py_uintptr_t) (p) & ~1))
-
-/* glue functions (see the init function for details) */
-static PyObject* elementtree_copyelement_obj;
-static PyObject* elementtree_deepcopy_obj;
-static PyObject* elementtree_getiterator_obj;
-static PyObject* elementpath_obj;
-
-/* helpers */
-
-LOCAL(PyObject*)
-deepcopy(PyObject* object, PyObject* memo)
-{
- /* do a deep copy of the given object */
-
- PyObject* args;
- PyObject* result;
-
- if (!elementtree_deepcopy_obj) {
- PyErr_SetString(
- PyExc_RuntimeError,
- "deepcopy helper not found"
- );
- return NULL;
- }
-
- args = PyTuple_New(2);
- Py_INCREF(object); PyTuple_SET_ITEM(args, 0, (PyObject*) object);
- Py_INCREF(memo); PyTuple_SET_ITEM(args, 1, (PyObject*) memo);
-
- result = PyObject_CallObject(elementtree_deepcopy_obj, args);
-
- Py_DECREF(args);
-
- return result;
-}
-
-LOCAL(PyObject*)
-list_join(PyObject* list)
-{
- /* join list elements (destroying the list in the process) */
-
- PyObject* joiner;
- PyObject* function;
- PyObject* args;
- PyObject* result;
-
- switch (PyList_GET_SIZE(list)) {
- case 0:
- Py_DECREF(list);
- return PyString_FromString("");
- case 1:
- result = PyList_GET_ITEM(list, 0);
- Py_INCREF(result);
- Py_DECREF(list);
- return result;
- }
-
- /* two or more elements: slice out a suitable separator from the
- first member, and use that to join the entire list */
-
- joiner = PySequence_GetSlice(PyList_GET_ITEM(list, 0), 0, 0);
- if (!joiner)
- return NULL;
-
- function = PyObject_GetAttrString(joiner, "join");
- if (!function) {
- Py_DECREF(joiner);
- return NULL;
- }
-
- args = PyTuple_New(1);
- PyTuple_SET_ITEM(args, 0, list);
-
- result = PyObject_CallObject(function, args);
-
- Py_DECREF(args); /* also removes list */
- Py_DECREF(function);
- Py_DECREF(joiner);
-
- return result;
-}
-
-#if (PY_VERSION_HEX < 0x02020000)
-LOCAL(int)
-PyDict_Update(PyObject* dict, PyObject* other)
-{
- /* PyDict_Update emulation for 2.1 and earlier */
-
- PyObject* res;
-
- res = PyObject_CallMethod(dict, "update", "O", other);
- if (!res)
- return -1;
-
- Py_DECREF(res);
- return 0;
-}
-#endif
-
-/* -------------------------------------------------------------------- */
-/* the element type */
-
-typedef struct {
-
- /* attributes (a dictionary object), or None if no attributes */
- PyObject* attrib;
-
- /* child elements */
- int length; /* actual number of items */
- int allocated; /* allocated items */
-
- /* this either points to _children or to a malloced buffer */
- PyObject* *children;
-
- PyObject* _children[STATIC_CHILDREN];
-
-} ElementObjectExtra;
-
-typedef struct {
- PyObject_HEAD
-
- /* element tag (a string). */
- PyObject* tag;
-
- /* text before first child. note that this is a tagged pointer;
- use JOIN_OBJ to get the object pointer. the join flag is used
- to distinguish lists created by the tree builder from lists
- assigned to the attribute by application code; the former
- should be joined before being returned to the user, the latter
- should be left intact. */
- PyObject* text;
-
- /* text after this element, in parent. note that this is a tagged
- pointer; use JOIN_OBJ to get the object pointer. */
- PyObject* tail;
-
- ElementObjectExtra* extra;
-
-} ElementObject;
-
-staticforward PyTypeObject Element_Type;
-
-#define Element_CheckExact(op) ((op)->ob_type == &Element_Type)
-
-/* -------------------------------------------------------------------- */
-/* element constructor and destructor */
-
-LOCAL(int)
-element_new_extra(ElementObject* self, PyObject* attrib)
-{
- self->extra = PyObject_Malloc(sizeof(ElementObjectExtra));
- if (!self->extra)
- return -1;
-
- if (!attrib)
- attrib = Py_None;
-
- Py_INCREF(attrib);
- self->extra->attrib = attrib;
-
- self->extra->length = 0;
- self->extra->allocated = STATIC_CHILDREN;
- self->extra->children = self->extra->_children;
-
- return 0;
-}
-
-LOCAL(void)
-element_dealloc_extra(ElementObject* self)
-{
- int i;
-
- Py_DECREF(self->extra->attrib);
-
- for (i = 0; i < self->extra->length; i++)
- Py_DECREF(self->extra->children[i]);
-
- if (self->extra->children != self->extra->_children)
- PyObject_Free(self->extra->children);
-
- PyObject_Free(self->extra);
-}
-
-LOCAL(PyObject*)
-element_new(PyObject* tag, PyObject* attrib)
-{
- ElementObject* self;
-
- self = PyObject_New(ElementObject, &Element_Type);
- if (self == NULL)
- return NULL;
-
- /* use None for empty dictionaries */
- if (PyDict_CheckExact(attrib) && !PyDict_Size(attrib))
- attrib = Py_None;
-
- self->extra = NULL;
-
- if (attrib != Py_None) {
-
- if (element_new_extra(self, attrib) < 0)
- return NULL;
-
- self->extra->length = 0;
- self->extra->allocated = STATIC_CHILDREN;
- self->extra->children = self->extra->_children;
-
- }
-
- Py_INCREF(tag);
- self->tag = tag;
-
- Py_INCREF(Py_None);
- self->text = Py_None;
-
- Py_INCREF(Py_None);
- self->tail = Py_None;
-
- ALLOC(sizeof(ElementObject), "create element");
-
- return (PyObject*) self;
-}
-
-LOCAL(int)
-element_resize(ElementObject* self, int extra)
-{
- int size;
- PyObject* *children;
-
- /* make sure self->children can hold the given number of extra
- elements. set an exception and return -1 if allocation failed */
-
- if (!self->extra)
- element_new_extra(self, NULL);
-
- size = self->extra->length + extra;
-
- if (size > self->extra->allocated) {
- /* use Python 2.4's list growth strategy */
- size = (size >> 3) + (size < 9 ? 3 : 6) + size;
- if (self->extra->children != self->extra->_children) {
- children = PyObject_Realloc(self->extra->children,
- size * sizeof(PyObject*));
- if (!children)
- goto nomemory;
- } else {
- children = PyObject_Malloc(size * sizeof(PyObject*));
- if (!children)
- goto nomemory;
- /* copy existing children from static area to malloc buffer */
- memcpy(children, self->extra->children,
- self->extra->length * sizeof(PyObject*));
- }
- self->extra->children = children;
- self->extra->allocated = size;
- }
-
- return 0;
-
- nomemory:
- PyErr_NoMemory();
- return -1;
-}
-
-LOCAL(int)
-element_add_subelement(ElementObject* self, PyObject* element)
-{
- /* add a child element to a parent */
-
- if (element_resize(self, 1) < 0)
- return -1;
-
- Py_INCREF(element);
- self->extra->children[self->extra->length] = element;
-
- self->extra->length++;
-
- return 0;
-}
-
-LOCAL(PyObject*)
-element_get_attrib(ElementObject* self)
-{
- /* return borrowed reference to attrib dictionary */
- /* note: this function assumes that the extra section exists */
-
- PyObject* res = self->extra->attrib;
-
- if (res == Py_None) {
- /* create missing dictionary */
- res = PyDict_New();
- if (!res)
- return NULL;
- self->extra->attrib = res;
- }
-
- return res;
-}
-
-LOCAL(PyObject*)
-element_get_text(ElementObject* self)
-{
- /* return borrowed reference to text attribute */
-
- PyObject* res = self->text;
-
- if (JOIN_GET(res)) {
- res = JOIN_OBJ(res);
- if (PyList_CheckExact(res)) {
- res = list_join(res);
- if (!res)
- return NULL;
- self->text = res;
- }
- }
-
- return res;
-}
-
-LOCAL(PyObject*)
-element_get_tail(ElementObject* self)
-{
- /* return borrowed reference to text attribute */
-
- PyObject* res = self->tail;
-
- if (JOIN_GET(res)) {
- res = JOIN_OBJ(res);
- if (PyList_CheckExact(res)) {
- res = list_join(res);
- if (!res)
- return NULL;
- self->tail = res;
- }
- }
-
- return res;
-}
-
-static PyObject*
-element(PyObject* self, PyObject* args, PyObject* kw)
-{
- PyObject* elem;
-
- PyObject* tag;
- PyObject* attrib = NULL;
- if (!PyArg_ParseTuple(args, "O|O!:Element", &tag,
- &PyDict_Type, &attrib))
- return NULL;
-
- if (attrib || kw) {
- attrib = (attrib) ? PyDict_Copy(attrib) : PyDict_New();
- if (!attrib)
- return NULL;
- if (kw)
- PyDict_Update(attrib, kw);
- } else {
- Py_INCREF(Py_None);
- attrib = Py_None;
- }
-
- elem = element_new(tag, attrib);
-
- Py_DECREF(attrib);
-
- return elem;
-}
-
-static PyObject*
-subelement(PyObject* self, PyObject* args, PyObject* kw)
-{
- PyObject* elem;
-
- ElementObject* parent;
- PyObject* tag;
- PyObject* attrib = NULL;
- if (!PyArg_ParseTuple(args, "O!O|O!:SubElement",
- &Element_Type, &parent, &tag,
- &PyDict_Type, &attrib))
- return NULL;
-
- if (attrib || kw) {
- attrib = (attrib) ? PyDict_Copy(attrib) : PyDict_New();
- if (!attrib)
- return NULL;
- if (kw)
- PyDict_Update(attrib, kw);
- } else {
- Py_INCREF(Py_None);
- attrib = Py_None;
- }
-
- elem = element_new(tag, attrib);
-
- Py_DECREF(attrib);
-
- if (element_add_subelement(parent, elem) < 0)
- return NULL;
-
- return elem;
-}
-
-static void
-element_dealloc(ElementObject* self)
-{
- if (self->extra)
- element_dealloc_extra(self);
-
- /* discard attributes */
- Py_DECREF(self->tag);
- Py_DECREF(JOIN_OBJ(self->text));
- Py_DECREF(JOIN_OBJ(self->tail));
-
- RELEASE(sizeof(ElementObject), "destroy element");
-
- PyObject_Del(self);
-}
-
-/* -------------------------------------------------------------------- */
-/* methods (in alphabetical order) */
-
-static PyObject*
-element_append(ElementObject* self, PyObject* args)
-{
- PyObject* element;
- if (!PyArg_ParseTuple(args, "O!:append", &Element_Type, &element))
- return NULL;
-
- if (element_add_subelement(self, element) < 0)
- return NULL;
-
- Py_RETURN_NONE;
-}
-
-static PyObject*
-element_clear(ElementObject* self, PyObject* args)
-{
- if (!PyArg_ParseTuple(args, ":clear"))
- return NULL;
-
- if (self->extra) {
- element_dealloc_extra(self);
- self->extra = NULL;
- }
-
- Py_INCREF(Py_None);
- Py_DECREF(JOIN_OBJ(self->text));
- self->text = Py_None;
-
- Py_INCREF(Py_None);
- Py_DECREF(JOIN_OBJ(self->tail));
- self->tail = Py_None;
-
- Py_RETURN_NONE;
-}
-
-static PyObject*
-element_copy(ElementObject* self, PyObject* args)
-{
- int i;
- ElementObject* element;
-
- if (!PyArg_ParseTuple(args, ":__copy__"))
- return NULL;
-
- element = (ElementObject*) element_new(
- self->tag, (self->extra) ? self->extra->attrib : Py_None
- );
- if (!element)
- return NULL;
-
- Py_DECREF(JOIN_OBJ(element->text));
- element->text = self->text;
- Py_INCREF(JOIN_OBJ(element->text));
-
- Py_DECREF(JOIN_OBJ(element->tail));
- element->tail = self->tail;
- Py_INCREF(JOIN_OBJ(element->tail));
-
- if (self->extra) {
-
- if (element_resize(element, self->extra->length) < 0)
- return NULL;
-
- for (i = 0; i < self->extra->length; i++) {
- Py_INCREF(self->extra->children[i]);
- element->extra->children[i] = self->extra->children[i];
- }
-
- element->extra->length = self->extra->length;
-
- }
-
- return (PyObject*) element;
-}
-
-static PyObject*
-element_deepcopy(ElementObject* self, PyObject* args)
-{
- int i;
- ElementObject* element;
- PyObject* tag;
- PyObject* attrib;
- PyObject* text;
- PyObject* tail;
- PyObject* id;
-
- PyObject* memo;
- if (!PyArg_ParseTuple(args, "O:__deepcopy__", &memo))
- return NULL;
-
- tag = deepcopy(self->tag, memo);
- if (!tag)
- return NULL;
-
- if (self->extra) {
- attrib = deepcopy(self->extra->attrib, memo);
- if (!attrib) {
- Py_DECREF(tag);
- return NULL;
- }
- } else {
- Py_INCREF(Py_None);
- attrib = Py_None;
- }
-
- element = (ElementObject*) element_new(tag, attrib);
-
- Py_DECREF(tag);
- Py_DECREF(attrib);
-
- if (!element)
- return NULL;
-
- text = deepcopy(JOIN_OBJ(self->text), memo);
- if (!text)
- goto error;
- Py_DECREF(element->text);
- element->text = JOIN_SET(text, JOIN_GET(self->text));
-
- tail = deepcopy(JOIN_OBJ(self->tail), memo);
- if (!tail)
- goto error;
- Py_DECREF(element->tail);
- element->tail = JOIN_SET(tail, JOIN_GET(self->tail));
-
- if (self->extra) {
-
- if (element_resize(element, self->extra->length) < 0)
- goto error;
-
- for (i = 0; i < self->extra->length; i++) {
- PyObject* child = deepcopy(self->extra->children[i], memo);
- if (!child) {
- element->extra->length = i;
- goto error;
- }
- element->extra->children[i] = child;
- }
-
- element->extra->length = self->extra->length;
-
- }
-
- /* add object to memo dictionary (so deepcopy won't visit it again) */
- id = PyInt_FromLong((Py_uintptr_t) self);
-
- i = PyDict_SetItem(memo, id, (PyObject*) element);
-
- Py_DECREF(id);
-
- if (i < 0)
- goto error;
-
- return (PyObject*) element;
-
- error:
- Py_DECREF(element);
- return NULL;
-}
-
-LOCAL(int)
-checkpath(PyObject* tag)
-{
- int i, check = 1;
-
- /* check if a tag contains an xpath character */
-
-#define PATHCHAR(ch) (ch == '/' || ch == '*' || ch == '[' || ch == '@')
-
-#if defined(Py_USING_UNICODE)
- if (PyUnicode_Check(tag)) {
- Py_UNICODE *p = PyUnicode_AS_UNICODE(tag);
- for (i = 0; i < PyUnicode_GET_SIZE(tag); i++) {
- if (p[i] == '{')
- check = 0;
- else if (p[i] == '}')
- check = 1;
- else if (check && PATHCHAR(p[i]))
- return 1;
- }
- return 0;
- }
-#endif
- if (PyString_Check(tag)) {
- char *p = PyString_AS_STRING(tag);
- for (i = 0; i < PyString_GET_SIZE(tag); i++) {
- if (p[i] == '{')
- check = 0;
- else if (p[i] == '}')
- check = 1;
- else if (check && PATHCHAR(p[i]))
- return 1;
- }
- return 0;
- }
-
- return 1; /* unknown type; might be path expression */
-}
-
-static PyObject*
-element_find(ElementObject* self, PyObject* args)
-{
- int i;
-
- PyObject* tag;
- if (!PyArg_ParseTuple(args, "O:find", &tag))
- return NULL;
-
- if (checkpath(tag))
- return PyObject_CallMethod(
- elementpath_obj, "find", "OO", self, tag
- );
-
- if (!self->extra)
- Py_RETURN_NONE;
-
- for (i = 0; i < self->extra->length; i++) {
- PyObject* item = self->extra->children[i];
- if (Element_CheckExact(item) &&
- PyObject_Compare(((ElementObject*)item)->tag, tag) == 0) {
- Py_INCREF(item);
- return item;
- }
- }
-
- Py_RETURN_NONE;
-}
-
-static PyObject*
-element_findtext(ElementObject* self, PyObject* args)
-{
- int i;
-
- PyObject* tag;
- PyObject* default_value = Py_None;
- if (!PyArg_ParseTuple(args, "O|O:findtext", &tag, &default_value))
- return NULL;
-
- if (checkpath(tag))
- return PyObject_CallMethod(
- elementpath_obj, "findtext", "OOO", self, tag, default_value
- );
-
- if (!self->extra) {
- Py_INCREF(default_value);
- return default_value;
- }
-
- for (i = 0; i < self->extra->length; i++) {
- ElementObject* item = (ElementObject*) self->extra->children[i];
- if (Element_CheckExact(item) && !PyObject_Compare(item->tag, tag)) {
- PyObject* text = element_get_text(item);
- if (text == Py_None)
- return PyString_FromString("");
- Py_INCREF(text);
- return text;
- }
- }
-
- Py_INCREF(default_value);
- return default_value;
-}
-
-static PyObject*
-element_findall(ElementObject* self, PyObject* args)
-{
- int i;
- PyObject* out;
-
- PyObject* tag;
- if (!PyArg_ParseTuple(args, "O:findall", &tag))
- return NULL;
-
- if (checkpath(tag))
- return PyObject_CallMethod(
- elementpath_obj, "findall", "OO", self, tag
- );
-
- out = PyList_New(0);
- if (!out)
- return NULL;
-
- if (!self->extra)
- return out;
-
- for (i = 0; i < self->extra->length; i++) {
- PyObject* item = self->extra->children[i];
- if (Element_CheckExact(item) &&
- PyObject_Compare(((ElementObject*)item)->tag, tag) == 0) {
- if (PyList_Append(out, item) < 0) {
- Py_DECREF(out);
- return NULL;
- }
- }
- }
-
- return out;
-}
-
-static PyObject*
-element_get(ElementObject* self, PyObject* args)
-{
- PyObject* value;
-
- PyObject* key;
- PyObject* default_value = Py_None;
- if (!PyArg_ParseTuple(args, "O|O:get", &key, &default_value))
- return NULL;
-
- if (!self->extra || self->extra->attrib == Py_None)
- value = default_value;
- else {
- value = PyDict_GetItem(self->extra->attrib, key);
- if (!value)
- value = default_value;
- }
-
- Py_INCREF(value);
- return value;
-}
-
-static PyObject*
-element_getchildren(ElementObject* self, PyObject* args)
-{
- int i;
- PyObject* list;
-
- if (!PyArg_ParseTuple(args, ":getchildren"))
- return NULL;
-
- if (!self->extra)
- return PyList_New(0);
-
- list = PyList_New(self->extra->length);
- if (!list)
- return NULL;
-
- for (i = 0; i < self->extra->length; i++) {
- PyObject* item = self->extra->children[i];
- Py_INCREF(item);
- PyList_SET_ITEM(list, i, item);
- }
-
- return list;
-}
-
-static PyObject*
-element_getiterator(ElementObject* self, PyObject* args)
-{
- PyObject* result;
-
- PyObject* tag = Py_None;
- if (!PyArg_ParseTuple(args, "|O:getiterator", &tag))
- return NULL;
-
- if (!elementtree_getiterator_obj) {
- PyErr_SetString(
- PyExc_RuntimeError,
- "getiterator helper not found"
- );
- return NULL;
- }
-
- args = PyTuple_New(2);
- Py_INCREF(self); PyTuple_SET_ITEM(args, 0, (PyObject*) self);
- Py_INCREF(tag); PyTuple_SET_ITEM(args, 1, (PyObject*) tag);
-
- result = PyObject_CallObject(elementtree_getiterator_obj, args);
-
- Py_DECREF(args);
-
- return result;
-}
-
-static PyObject*
-element_getitem(ElementObject* self, int index)
-{
- if (!self->extra || index < 0 || index >= self->extra->length) {
- PyErr_SetString(
- PyExc_IndexError,
- "child index out of range"
- );
- return NULL;
- }
-
- Py_INCREF(self->extra->children[index]);
- return self->extra->children[index];
-}
-
-static PyObject*
-element_getslice(ElementObject* self, int start, int end)
-{
- int i;
- PyObject* list;
-
- if (!self->extra)
- return PyList_New(0);
-
- /* standard clamping */
- if (start < 0)
- start = 0;
- if (end < 0)
- end = 0;
- if (end > self->extra->length)
- end = self->extra->length;
- if (start > end)
- start = end;
-
- list = PyList_New(end - start);
- if (!list)
- return NULL;
-
- for (i = start; i < end; i++) {
- PyObject* item = self->extra->children[i];
- Py_INCREF(item);
- PyList_SET_ITEM(list, i - start, item);
- }
-
- return list;
-}
-
-static PyObject*
-element_insert(ElementObject* self, PyObject* args)
-{
- int i;
-
- int index;
- PyObject* element;
- if (!PyArg_ParseTuple(args, "iO!:insert", &index,
- &Element_Type, &element))
- return NULL;
-
- if (!self->extra)
- element_new_extra(self, NULL);
-
- if (index < 0)
- index = 0;
- if (index > self->extra->length)
- index = self->extra->length;
-
- if (element_resize(self, 1) < 0)
- return NULL;
-
- for (i = self->extra->length; i > index; i--)
- self->extra->children[i] = self->extra->children[i-1];
-
- Py_INCREF(element);
- self->extra->children[index] = element;
-
- self->extra->length++;
-
- Py_RETURN_NONE;
-}
-
-static PyObject*
-element_items(ElementObject* self, PyObject* args)
-{
- if (!PyArg_ParseTuple(args, ":items"))
- return NULL;
-
- if (!self->extra || self->extra->attrib == Py_None)
- return PyList_New(0);
-
- return PyDict_Items(self->extra->attrib);
-}
-
-static PyObject*
-element_keys(ElementObject* self, PyObject* args)
-{
- if (!PyArg_ParseTuple(args, ":keys"))
- return NULL;
-
- if (!self->extra || self->extra->attrib == Py_None)
- return PyList_New(0);
-
- return PyDict_Keys(self->extra->attrib);
-}
-
-static int
-element_length(ElementObject* self)
-{
- if (!self->extra)
- return 0;
-
- return self->extra->length;
-}
-
-static PyObject*
-element_makeelement(PyObject* self, PyObject* args, PyObject* kw)
-{
- PyObject* elem;
-
- PyObject* tag;
- PyObject* attrib;
- if (!PyArg_ParseTuple(args, "OO:makeelement", &tag, &attrib))
- return NULL;
-
- attrib = PyDict_Copy(attrib);
- if (!attrib)
- return NULL;
-
- elem = element_new(tag, attrib);
-
- Py_DECREF(attrib);
-
- return elem;
-}
-
-static PyObject*
-element_reduce(ElementObject* self, PyObject* args)
-{
- if (!PyArg_ParseTuple(args, ":__reduce__"))
- return NULL;
-
- /* Hack alert: This method is used to work around a __copy__
- problem on certain 2.3 and 2.4 versions. To save time and
- simplify the code, we create the copy in here, and use a dummy
- copyelement helper to trick the copy module into doing the
- right thing. */
-
- if (!elementtree_copyelement_obj) {
- PyErr_SetString(
- PyExc_RuntimeError,
- "copyelement helper not found"
- );
- return NULL;
- }
-
- return Py_BuildValue(
- "O(N)", elementtree_copyelement_obj, element_copy(self, args)
- );
-}
-
-static PyObject*
-element_remove(ElementObject* self, PyObject* args)
-{
- int i;
-
- PyObject* element;
- if (!PyArg_ParseTuple(args, "O!:remove", &Element_Type, &element))
- return NULL;
-
- if (!self->extra) {
- /* element has no children, so raise exception */
- PyErr_SetString(
- PyExc_ValueError,
- "list.remove(x): x not in list"
- );
- return NULL;
- }
-
- for (i = 0; i < self->extra->length; i++) {
- if (self->extra->children[i] == element)
- break;
- if (PyObject_Compare(self->extra->children[i], element) == 0)
- break;
- }
-
- if (i == self->extra->length) {
- /* element is not in children, so raise exception */
- PyErr_SetString(
- PyExc_ValueError,
- "list.remove(x): x not in list"
- );
- return NULL;
- }
-
- Py_DECREF(self->extra->children[i]);
-
- self->extra->length--;
-
- for (; i < self->extra->length; i++)
- self->extra->children[i] = self->extra->children[i+1];
-
- Py_RETURN_NONE;
-}
-
-static PyObject*
-element_repr(ElementObject* self)
-{
- PyObject* repr;
- char buffer[100];
-
- repr = PyString_FromString("<Element ");
-
- PyString_ConcatAndDel(&repr, PyObject_Repr(self->tag));
-
- sprintf(buffer, " at %p>", self);
- PyString_ConcatAndDel(&repr, PyString_FromString(buffer));
-
- return repr;
-}
-
-static PyObject*
-element_set(ElementObject* self, PyObject* args)
-{
- PyObject* attrib;
-
- PyObject* key;
- PyObject* value;
- if (!PyArg_ParseTuple(args, "OO:set", &key, &value))
- return NULL;
-
- if (!self->extra)
- element_new_extra(self, NULL);
-
- attrib = element_get_attrib(self);
- if (!attrib)
- return NULL;
-
- if (PyDict_SetItem(attrib, key, value) < 0)
- return NULL;
-
- Py_RETURN_NONE;
-}
-
-static int
-element_setslice(ElementObject* self, int start, int end, PyObject* item)
-{
- int i, new, old;
- PyObject* recycle = NULL;
-
- if (!self->extra)
- element_new_extra(self, NULL);
-
- /* standard clamping */
- if (start < 0)
- start = 0;
- if (end < 0)
- end = 0;
- if (end > self->extra->length)
- end = self->extra->length;
- if (start > end)
- start = end;
-
- old = end - start;
-
- if (item == NULL)
- new = 0;
- else if (PyList_CheckExact(item)) {
- new = PyList_GET_SIZE(item);
- } else {
- /* FIXME: support arbitrary sequences? */
- PyErr_Format(
- PyExc_TypeError,
- "expected list, not \"%.200s\"", item->ob_type->tp_name
- );
- return -1;
- }
-
- if (old > 0) {
- /* to avoid recursive calls to this method (via decref), move
- old items to the recycle bin here, and get rid of them when
- we're done modifying the element */
- recycle = PyList_New(old);
- for (i = 0; i < old; i++)
- PyList_SET_ITEM(recycle, i, self->extra->children[i + start]);
- }
-
- if (new < old) {
- /* delete slice */
- for (i = end; i < self->extra->length; i++)
- self->extra->children[i + new - old] = self->extra->children[i];
- } else if (new > old) {
- /* insert slice */
- if (element_resize(self, new - old) < 0)
- return -1;
- for (i = self->extra->length-1; i >= end; i--)
- self->extra->children[i + new - old] = self->extra->children[i];
- }
-
- /* replace the slice */
- for (i = 0; i < new; i++) {
- PyObject* element = PyList_GET_ITEM(item, i);
- Py_INCREF(element);
- self->extra->children[i + start] = element;
- }
-
- self->extra->length += new - old;
-
- /* discard the recycle bin, and everything in it */
- Py_XDECREF(recycle);
-
- return 0;
-}
-
-static int
-element_setitem(ElementObject* self, int index, PyObject* item)
-{
- int i;
- PyObject* old;
-
- if (!self->extra || index < 0 || index >= self->extra->length) {
- PyErr_SetString(
- PyExc_IndexError,
- "child assignment index out of range");
- return -1;
- }
-
- old = self->extra->children[index];
-
- if (item) {
- Py_INCREF(item);
- self->extra->children[index] = item;
- } else {
- self->extra->length--;
- for (i = index; i < self->extra->length; i++)
- self->extra->children[i] = self->extra->children[i+1];
- }
-
- Py_DECREF(old);
-
- return 0;
-}
-
-static PyMethodDef element_methods[] = {
-
- {"clear", (PyCFunction) element_clear, METH_VARARGS},
-
- {"get", (PyCFunction) element_get, METH_VARARGS},
- {"set", (PyCFunction) element_set, METH_VARARGS},
-
- {"find", (PyCFunction) element_find, METH_VARARGS},
- {"findtext", (PyCFunction) element_findtext, METH_VARARGS},
- {"findall", (PyCFunction) element_findall, METH_VARARGS},
-
- {"append", (PyCFunction) element_append, METH_VARARGS},
- {"insert", (PyCFunction) element_insert, METH_VARARGS},
- {"remove", (PyCFunction) element_remove, METH_VARARGS},
-
- {"getiterator", (PyCFunction) element_getiterator, METH_VARARGS},
- {"getchildren", (PyCFunction) element_getchildren, METH_VARARGS},
-
- {"items", (PyCFunction) element_items, METH_VARARGS},
- {"keys", (PyCFunction) element_keys, METH_VARARGS},
-
- {"makeelement", (PyCFunction) element_makeelement, METH_VARARGS},
-
- {"__copy__", (PyCFunction) element_copy, METH_VARARGS},
- {"__deepcopy__", (PyCFunction) element_deepcopy, METH_VARARGS},
-
- /* Some 2.3 and 2.4 versions do not handle the __copy__ method on
- C objects correctly, so we have to fake it using a __reduce__-
- based hack (see the element_reduce implementation above for
- details). */
-
- /* The behaviour has been changed in 2.3.5 and 2.4.1, so we're
- using a runtime test to figure out if we need to fake things
- or now (see the init code below). The following entry is
- enabled only if the hack is needed. */
-
- {"!__reduce__", (PyCFunction) element_reduce, METH_VARARGS},
-
- {NULL, NULL}
-};
-
-static PyObject*
-element_getattr(ElementObject* self, char* name)
-{
- PyObject* res;
-
- res = Py_FindMethod(element_methods, (PyObject*) self, name);
- if (res)
- return res;
-
- PyErr_Clear();
-
- if (strcmp(name, "tag") == 0)
- res = self->tag;
- else if (strcmp(name, "text") == 0)
- res = element_get_text(self);
- else if (strcmp(name, "tail") == 0) {
- res = element_get_tail(self);
- } else if (strcmp(name, "attrib") == 0) {
- if (!self->extra)
- element_new_extra(self, NULL);
- res = element_get_attrib(self);
- } else {
- PyErr_SetString(PyExc_AttributeError, name);
- return NULL;
- }
-
- if (!res)
- return NULL;
-
- Py_INCREF(res);
- return res;
-}
-
-static int
-element_setattr(ElementObject* self, const char* name, PyObject* value)
-{
- if (value == NULL) {
- PyErr_SetString(
- PyExc_AttributeError,
- "can't delete element attributes"
- );
- return -1;
- }
-
- if (strcmp(name, "tag") == 0) {
- Py_DECREF(self->tag);
- self->tag = value;
- Py_INCREF(self->tag);
- } else if (strcmp(name, "text") == 0) {
- Py_DECREF(JOIN_OBJ(self->text));
- self->text = value;
- Py_INCREF(self->text);
- } else if (strcmp(name, "tail") == 0) {
- Py_DECREF(JOIN_OBJ(self->tail));
- self->tail = value;
- Py_INCREF(self->tail);
- } else if (strcmp(name, "attrib") == 0) {
- if (!self->extra)
- element_new_extra(self, NULL);
- Py_DECREF(self->extra->attrib);
- self->extra->attrib = value;
- Py_INCREF(self->extra->attrib);
- } else {
- PyErr_SetString(PyExc_AttributeError, name);
- return -1;
- }
-
- return 0;
-}
-
-static PySequenceMethods element_as_sequence = {
- (inquiry) element_length,
- 0, /* sq_concat */
- 0, /* sq_repeat */
- (intargfunc) element_getitem,
- (intintargfunc) element_getslice,
- (intobjargproc) element_setitem,
- (intintobjargproc) element_setslice,
-};
-
-statichere PyTypeObject Element_Type = {
- PyObject_HEAD_INIT(NULL)
- 0, "Element", sizeof(ElementObject), 0,
- /* methods */
- (destructor)element_dealloc, /* tp_dealloc */
- 0, /* tp_print */
- (getattrfunc)element_getattr, /* tp_getattr */
- (setattrfunc)element_setattr, /* tp_setattr */
- 0, /* tp_compare */
- (reprfunc)element_repr, /* tp_repr */
- 0, /* tp_as_number */
- &element_as_sequence, /* tp_as_sequence */
-};
-
-/* ==================================================================== */
-/* the tree builder type */
-
-typedef struct {
- PyObject_HEAD
-
- PyObject* root; /* root node (first created node) */
-
- ElementObject* this; /* current node */
- ElementObject* last; /* most recently created node */
-
- PyObject* data; /* data collector (string or list), or NULL */
-
- PyObject* stack; /* element stack */
- int index; /* current stack size (0=empty) */
-
- /* element tracing */
- PyObject* events; /* list of events, or NULL if not collecting */
- PyObject* start_event_obj; /* event objects (NULL to ignore) */
- PyObject* end_event_obj;
- PyObject* start_ns_event_obj;
- PyObject* end_ns_event_obj;
-
-} TreeBuilderObject;
-
-staticforward PyTypeObject TreeBuilder_Type;
-
-#define TreeBuilder_CheckExact(op) ((op)->ob_type == &TreeBuilder_Type)
-
-/* -------------------------------------------------------------------- */
-/* constructor and destructor */
-
-LOCAL(PyObject*)
-treebuilder_new(void)
-{
- TreeBuilderObject* self;
-
- self = PyObject_New(TreeBuilderObject, &TreeBuilder_Type);
- if (self == NULL)
- return NULL;
-
- self->root = NULL;
-
- Py_INCREF(Py_None);
- self->this = (ElementObject*) Py_None;
-
- Py_INCREF(Py_None);
- self->last = (ElementObject*) Py_None;
-
- self->data = NULL;
-
- self->stack = PyList_New(20);
- self->index = 0;
-
- self->events = NULL;
- self->start_event_obj = self->end_event_obj = NULL;
- self->start_ns_event_obj = self->end_ns_event_obj = NULL;
-
- ALLOC(sizeof(TreeBuilderObject), "create treebuilder");
-
- return (PyObject*) self;
-}
-
-static PyObject*
-treebuilder(PyObject* _self, PyObject* args)
-{
- if (!PyArg_ParseTuple(args, ":TreeBuilder"))
- return NULL;
-
- return treebuilder_new();
-}
-
-static void
-treebuilder_dealloc(TreeBuilderObject* self)
-{
- Py_XDECREF(self->end_ns_event_obj);
- Py_XDECREF(self->start_ns_event_obj);
- Py_XDECREF(self->end_event_obj);
- Py_XDECREF(self->start_event_obj);
- Py_XDECREF(self->events);
- Py_DECREF(self->stack);
- Py_XDECREF(self->data);
- Py_DECREF(self->last);
- Py_DECREF(self->this);
- Py_XDECREF(self->root);
-
- RELEASE(sizeof(TreeBuilderObject), "destroy treebuilder");
-
- PyObject_Del(self);
-}
-
-/* -------------------------------------------------------------------- */
-/* handlers */
-
-LOCAL(PyObject*)
-treebuilder_handle_xml(TreeBuilderObject* self, PyObject* encoding,
- PyObject* standalone)
-{
- Py_RETURN_NONE;
-}
-
-LOCAL(PyObject*)
-treebuilder_handle_start(TreeBuilderObject* self, PyObject* tag,
- PyObject* attrib)
-{
- PyObject* node;
- PyObject* this;
-
- if (self->data) {
- if (self->this == self->last) {
- self->last->text = JOIN_SET(
- self->data, PyList_CheckExact(self->data)
- );
- } else {
- self->last->tail = JOIN_SET(
- self->data, PyList_CheckExact(self->data)
- );
- }
- self->data = NULL;
- }
-
- node = element_new(tag, attrib);
- if (!node)
- return NULL;
-
- this = (PyObject*) self->this;
-
- if (this != Py_None) {
- if (element_add_subelement((ElementObject*) this, node) < 0)
- return NULL;
- } else {
- if (self->root) {
- PyErr_SetString(
- PyExc_SyntaxError,
- "multiple elements on top level"
- );
- return NULL;
- }
- Py_INCREF(node);
- self->root = node;
- }
-
- if (self->index < PyList_GET_SIZE(self->stack)) {
- if (PyList_SetItem(self->stack, self->index, this) < 0)
- return NULL;
- Py_INCREF(this);
- } else {
- if (PyList_Append(self->stack, this) < 0)
- return NULL;
- }
- self->index++;
-
- Py_DECREF(this);
- Py_INCREF(node);
- self->this = (ElementObject*) node;
-
- Py_DECREF(self->last);
- Py_INCREF(node);
- self->last = (ElementObject*) node;
-
- if (self->start_event_obj) {
- PyObject* res;
- PyObject* action = self->start_event_obj;
- res = PyTuple_New(2);
- if (res) {
- Py_INCREF(action); PyTuple_SET_ITEM(res, 0, (PyObject*) action);
- Py_INCREF(node); PyTuple_SET_ITEM(res, 1, (PyObject*) node);
- PyList_Append(self->events, res);
- Py_DECREF(res);
- } else
- PyErr_Clear(); /* FIXME: propagate error */
- }
-
- return node;
-}
-
-LOCAL(PyObject*)
-treebuilder_handle_data(TreeBuilderObject* self, PyObject* data)
-{
- if (!self->data) {
- /* store the first item as is */
- Py_INCREF(data); self->data = data;
- } else {
- /* more than one item; use a list to collect items */
- if (PyString_CheckExact(self->data) && self->data->ob_refcnt == 1 &&
- PyString_CheckExact(data) && PyString_GET_SIZE(data) == 1) {
- /* expat often generates single character data sections; handle
- the most common case by resizing the existing string... */
- int size = PyString_GET_SIZE(self->data);
- if (_PyString_Resize(&self->data, size + 1) < 0)
- return NULL;
- PyString_AS_STRING(self->data)[size] = PyString_AS_STRING(data)[0];
- } else if (PyList_CheckExact(self->data)) {
- if (PyList_Append(self->data, data) < 0)
- return NULL;
- } else {
- PyObject* list = PyList_New(2);
- if (!list)
- return NULL;
- PyList_SET_ITEM(list, 0, self->data);
- Py_INCREF(data); PyList_SET_ITEM(list, 1, data);
- self->data = list;
- }
- }
-
- Py_RETURN_NONE;
-}
-
-LOCAL(PyObject*)
-treebuilder_handle_end(TreeBuilderObject* self, PyObject* tag)
-{
- PyObject* item;
-
- if (self->data) {
- if (self->this == self->last) {
- self->last->text = JOIN_SET(
- self->data, PyList_CheckExact(self->data)
- );
- } else {
- self->last->tail = JOIN_SET(
- self->data, PyList_CheckExact(self->data)
- );
- }
- self->data = NULL;
- }
-
- if (self->index == 0) {
- PyErr_SetString(
- PyExc_IndexError,
- "pop from empty stack"
- );
- return NULL;
- }
-
- self->index--;
-
- item = PyList_GET_ITEM(self->stack, self->index);
- Py_INCREF(item);
-
- Py_DECREF(self->last);
-
- self->last = (ElementObject*) self->this;
- self->this = (ElementObject*) item;
-
- if (self->end_event_obj) {
- PyObject* res;
- PyObject* action = self->end_event_obj;
- PyObject* node = (PyObject*) self->last;
- res = PyTuple_New(2);
- if (res) {
- Py_INCREF(action); PyTuple_SET_ITEM(res, 0, (PyObject*) action);
- Py_INCREF(node); PyTuple_SET_ITEM(res, 1, (PyObject*) node);
- PyList_Append(self->events, res);
- Py_DECREF(res);
- } else
- PyErr_Clear(); /* FIXME: propagate error */
- }
-
- Py_INCREF(self->last);
- return (PyObject*) self->last;
-}
-
-LOCAL(void)
-treebuilder_handle_namespace(TreeBuilderObject* self, int start,
- const char* prefix, const char *uri)
-{
- PyObject* res;
- PyObject* action;
- PyObject* parcel;
-
- if (!self->events)
- return;
-
- if (start) {
- if (!self->start_ns_event_obj)
- return;
- action = self->start_ns_event_obj;
- /* FIXME: prefix and uri use utf-8 encoding! */
- parcel = Py_BuildValue("ss", (prefix) ? prefix : "", uri);
- if (!parcel)
- return;
- Py_INCREF(action);
- } else {
- if (!self->end_ns_event_obj)
- return;
- action = self->end_ns_event_obj;
- Py_INCREF(action);
- parcel = Py_None;
- Py_INCREF(parcel);
- }
-
- res = PyTuple_New(2);
-
- if (res) {
- PyTuple_SET_ITEM(res, 0, action);
- PyTuple_SET_ITEM(res, 1, parcel);
- PyList_Append(self->events, res);
- Py_DECREF(res);
- } else
- PyErr_Clear(); /* FIXME: propagate error */
-}
-
-/* -------------------------------------------------------------------- */
-/* methods (in alphabetical order) */
-
-static PyObject*
-treebuilder_data(TreeBuilderObject* self, PyObject* args)
-{
- PyObject* data;
- if (!PyArg_ParseTuple(args, "O:data", &data))
- return NULL;
-
- return treebuilder_handle_data(self, data);
-}
-
-static PyObject*
-treebuilder_end(TreeBuilderObject* self, PyObject* args)
-{
- PyObject* tag;
- if (!PyArg_ParseTuple(args, "O:end", &tag))
- return NULL;
-
- return treebuilder_handle_end(self, tag);
-}
-
-LOCAL(PyObject*)
-treebuilder_done(TreeBuilderObject* self)
-{
- PyObject* res;
-
- /* FIXME: check stack size? */
-
- if (self->root)
- res = self->root;
- else
- res = Py_None;
-
- Py_INCREF(res);
- return res;
-}
-
-static PyObject*
-treebuilder_close(TreeBuilderObject* self, PyObject* args)
-{
- if (!PyArg_ParseTuple(args, ":close"))
- return NULL;
-
- return treebuilder_done(self);
-}
-
-static PyObject*
-treebuilder_start(TreeBuilderObject* self, PyObject* args)
-{
- PyObject* tag;
- PyObject* attrib = Py_None;
- if (!PyArg_ParseTuple(args, "O|O:start", &tag, &attrib))
- return NULL;
-
- return treebuilder_handle_start(self, tag, attrib);
-}
-
-static PyObject*
-treebuilder_xml(TreeBuilderObject* self, PyObject* args)
-{
- PyObject* encoding;
- PyObject* standalone;
- if (!PyArg_ParseTuple(args, "OO:xml", &encoding, &standalone))
- return NULL;
-
- return treebuilder_handle_xml(self, encoding, standalone);
-}
-
-static PyMethodDef treebuilder_methods[] = {
- {"data", (PyCFunction) treebuilder_data, METH_VARARGS},
- {"start", (PyCFunction) treebuilder_start, METH_VARARGS},
- {"end", (PyCFunction) treebuilder_end, METH_VARARGS},
- {"xml", (PyCFunction) treebuilder_xml, METH_VARARGS},
- {"close", (PyCFunction) treebuilder_close, METH_VARARGS},
- {NULL, NULL}
-};
-
-static PyObject*
-treebuilder_getattr(TreeBuilderObject* self, char* name)
-{
- return Py_FindMethod(treebuilder_methods, (PyObject*) self, name);
-}
-
-statichere PyTypeObject TreeBuilder_Type = {
- PyObject_HEAD_INIT(NULL)
- 0, "TreeBuilder", sizeof(TreeBuilderObject), 0,
- /* methods */
- (destructor)treebuilder_dealloc, /* tp_dealloc */
- 0, /* tp_print */
- (getattrfunc)treebuilder_getattr, /* tp_getattr */
-};
-
-/* ==================================================================== */
-/* the expat interface */
-
-#if defined(USE_EXPAT)
-
-#include "expat.h"
-
-#if defined(USE_PYEXPAT_CAPI)
-#include "pyexpat.h"
-static struct PyExpat_CAPI* expat_capi;
-#define EXPAT(func) (expat_capi->func)
-#else
-#define EXPAT(func) (XML_##func)
-#endif
-
-typedef struct {
- PyObject_HEAD
-
- XML_Parser parser;
-
- PyObject* target;
- PyObject* entity;
-
- PyObject* names;
-
- PyObject* handle_xml;
- PyObject* handle_start;
- PyObject* handle_data;
- PyObject* handle_end;
-
- PyObject* handle_comment;
- PyObject* handle_pi;
-
-} XMLParserObject;
-
-staticforward PyTypeObject XMLParser_Type;
-
-/* helpers */
-
-#if defined(Py_USING_UNICODE)
-LOCAL(int)
-checkstring(const char* string, int size)
-{
- int i;
-
- /* check if an 8-bit string contains UTF-8 characters */
- for (i = 0; i < size; i++)
- if (string[i] & 0x80)
- return 1;
-
- return 0;
-}
-#endif
-
-LOCAL(PyObject*)
-makestring(const char* string, int size)
-{
- /* convert a UTF-8 string to either a 7-bit ascii string or a
- Unicode string */
-
-#if defined(Py_USING_UNICODE)
- if (checkstring(string, size))
- return PyUnicode_DecodeUTF8(string, size, "strict");
-#endif
-
- return PyString_FromStringAndSize(string, size);
-}
-
-LOCAL(PyObject*)
-makeuniversal(XMLParserObject* self, const char* string)
-{
- /* convert a UTF-8 tag/attribute name from the expat parser
- to a universal name string */
-
- int size = strlen(string);
- PyObject* key;
- PyObject* value;
-
- /* look the 'raw' name up in the names dictionary */
- key = PyString_FromStringAndSize(string, size);
- if (!key)
- return NULL;
-
- value = PyDict_GetItem(self->names, key);
-
- if (value) {
- Py_INCREF(value);
- } else {
- /* new name. convert to universal name, and decode as
- necessary */
-
- PyObject* tag;
- char* p;
- int i;
-
- /* look for namespace separator */
- for (i = 0; i < size; i++)
- if (string[i] == '}')
- break;
- if (i != size) {
- /* convert to universal name */
- tag = PyString_FromStringAndSize(NULL, size+1);
- p = PyString_AS_STRING(tag);
- p[0] = '{';
- memcpy(p+1, string, size);
- size++;
- } else {
- /* plain name; use key as tag */
- Py_INCREF(key);
- tag = key;
- }
-
- /* decode universal name */
-#if defined(Py_USING_UNICODE)
- /* inline makestring, to avoid duplicating the source string if
- it's not an utf-8 string */
- p = PyString_AS_STRING(tag);
- if (checkstring(p, size)) {
- value = PyUnicode_DecodeUTF8(p, size, "strict");
- Py_DECREF(tag);
- if (!value) {
- Py_DECREF(key);
- return NULL;
- }
- } else
-#endif
- value = tag; /* use tag as is */
-
- /* add to names dictionary */
- if (PyDict_SetItem(self->names, key, value) < 0) {
- Py_DECREF(key);
- Py_DECREF(value);
- return NULL;
- }
- }
-
- Py_DECREF(key);
- return value;
-}
-
-/* -------------------------------------------------------------------- */
-/* handlers */
-
-static void
-expat_default_handler(XMLParserObject* self, const XML_Char* data_in,
- int data_len)
-{
- PyObject* key;
- PyObject* value;
- PyObject* res;
-
- if (data_len < 2 || data_in[0] != '&')
- return;
-
- key = makestring(data_in + 1, data_len - 2);
- if (!key)
- return;
-
- value = PyDict_GetItem(self->entity, key);
-
- if (value) {
- if (TreeBuilder_CheckExact(self->target))
- res = treebuilder_handle_data(
- (TreeBuilderObject*) self->target, value
- );
- else if (self->handle_data)
- res = PyObject_CallFunction(self->handle_data, "O", value);
- else
- res = NULL;
- Py_DECREF(value);
- Py_XDECREF(res);
- } else {
- PyErr_Format(
- PyExc_SyntaxError, "undefined entity &%s;: line %d, column %d",
- PyString_AS_STRING(key),
- EXPAT(GetErrorLineNumber)(self->parser),
- EXPAT(GetErrorColumnNumber)(self->parser)
- );
- }
-
- Py_DECREF(key);
-}
-
-static void
-expat_start_handler(XMLParserObject* self, const XML_Char* tag_in,
- const XML_Char **attrib_in)
-{
- PyObject* res;
- PyObject* tag;
- PyObject* attrib;
- int ok;
-
- /* tag name */
- tag = makeuniversal(self, tag_in);
- if (!tag)
- return; /* parser will look for errors */
-
- /* attributes */
- if (attrib_in[0]) {
- attrib = PyDict_New();
- if (!attrib)
- return;
- while (attrib_in[0] && attrib_in[1]) {
- PyObject* key = makeuniversal(self, attrib_in[0]);
- PyObject* value = makestring(attrib_in[1], strlen(attrib_in[1]));
- if (!key || !value) {
- Py_XDECREF(value);
- Py_XDECREF(key);
- Py_DECREF(attrib);
- return;
- }
- ok = PyDict_SetItem(attrib, key, value);
- Py_DECREF(value);
- Py_DECREF(key);
- if (ok < 0) {
- Py_DECREF(attrib);
- return;
- }
- attrib_in += 2;
- }
- } else {
- Py_INCREF(Py_None);
- attrib = Py_None;
- }
-
- if (TreeBuilder_CheckExact(self->target))
- /* shortcut */
- res = treebuilder_handle_start((TreeBuilderObject*) self->target,
- tag, attrib);
- else if (self->handle_start)
- res = PyObject_CallFunction(self->handle_start, "OO", tag, attrib);
- else
- res = NULL;
-
- Py_DECREF(tag);
- Py_DECREF(attrib);
-
- Py_XDECREF(res);
-}
-
-static void
-expat_data_handler(XMLParserObject* self, const XML_Char* data_in,
- int data_len)
-{
- PyObject* data;
- PyObject* res;
-
- data = makestring(data_in, data_len);
-
- if (TreeBuilder_CheckExact(self->target))
- /* shortcut */
- res = treebuilder_handle_data((TreeBuilderObject*) self->target, data);
- else if (self->handle_data)
- res = PyObject_CallFunction(self->handle_data, "O", data);
- else
- res = NULL;
-
- Py_DECREF(data);
-
- Py_XDECREF(res);
-}
-
-static void
-expat_end_handler(XMLParserObject* self, const XML_Char* tag_in)
-{
- PyObject* tag;
- PyObject* res = NULL;
-
- if (TreeBuilder_CheckExact(self->target))
- /* shortcut */
- /* the standard tree builder doesn't look at the end tag */
- res = treebuilder_handle_end(
- (TreeBuilderObject*) self->target, Py_None
- );
- else if (self->handle_end) {
- tag = makeuniversal(self, tag_in);
- if (tag) {
- res = PyObject_CallFunction(self->handle_end, "O", tag);
- Py_DECREF(tag);
- }
- }
-
- Py_XDECREF(res);
-}
-
-static void
-expat_start_ns_handler(XMLParserObject* self, const XML_Char* prefix,
- const XML_Char *uri)
-{
- treebuilder_handle_namespace(
- (TreeBuilderObject*) self->target, 1, prefix, uri
- );
-}
-
-static void
-expat_end_ns_handler(XMLParserObject* self, const XML_Char* prefix_in)
-{
- treebuilder_handle_namespace(
- (TreeBuilderObject*) self->target, 0, NULL, NULL
- );
-}
-
-static void
-expat_comment_handler(XMLParserObject* self, const XML_Char* comment_in)
-{
- PyObject* comment;
- PyObject* res;
-
- if (self->handle_comment) {
- comment = makestring(comment_in, strlen(comment_in));
- if (comment) {
- res = PyObject_CallFunction(self->handle_comment, "O", comment);
- Py_XDECREF(res);
- Py_DECREF(comment);
- }
- }
-}
-
-static void
-expat_pi_handler(XMLParserObject* self, const XML_Char* target_in,
- const XML_Char* data_in)
-{
- PyObject* target;
- PyObject* data;
- PyObject* res;
-
- if (self->handle_pi) {
- target = makestring(target_in, strlen(target_in));
- data = makestring(data_in, strlen(data_in));
- if (target && data) {
- res = PyObject_CallFunction(self->handle_pi, "OO", target, data);
- Py_XDECREF(res);
- Py_DECREF(data);
- Py_DECREF(target);
- } else {
- Py_XDECREF(data);
- Py_XDECREF(target);
- }
- }
-}
-
-/* -------------------------------------------------------------------- */
-/* constructor and destructor */
-
-static PyObject*
-xmlparser(PyObject* _self, PyObject* args, PyObject* kw)
-{
- XMLParserObject* self;
- /* FIXME: does this need to be static? */
- static XML_Memory_Handling_Suite memory_handler;
-
- PyObject* target = NULL;
- char* encoding = NULL;
- static PY_CONST char* kwlist[] = { "target", "encoding", NULL };
- if (!PyArg_ParseTupleAndKeywords(args, kw, "|Oz:XMLParser", kwlist,
- &target, &encoding))
- return NULL;
-
-#if defined(USE_PYEXPAT_CAPI)
- if (!expat_capi) {
- PyErr_SetString(
- PyExc_RuntimeError, "cannot load dispatch table from pyexpat"
- );
- return NULL;
- }
-#endif
-
- self = PyObject_New(XMLParserObject, &XMLParser_Type);
- if (self == NULL)
- return NULL;
-
- self->entity = PyDict_New();
- if (!self->entity) {
- PyObject_Del(self);
- return NULL; /* FIXME: cleanup on error */
- }
-
- self->names = PyDict_New();
- if (!self->names) {
- PyObject_Del(self);
- return NULL; /* FIXME: cleanup on error */
- }
-
- memory_handler.malloc_fcn = PyObject_Malloc;
- memory_handler.realloc_fcn = PyObject_Realloc;
- memory_handler.free_fcn = PyObject_Free;
-
- self->parser = EXPAT(ParserCreate_MM)(encoding, &memory_handler, "}");
- if (!self->parser) {
- PyErr_NoMemory();
- return NULL; /* FIXME: cleanup on error */
- }
-
- /* setup target handlers */
- if (!target) {
- target = treebuilder_new();
- if (!target) {
- PyObject_Del(self);
- return NULL; /* FIXME: cleanup on error */
- }
- } else
- Py_INCREF(target);
- self->target = target;
-
- self->handle_xml = PyObject_GetAttrString(target, "xml");
- self->handle_start = PyObject_GetAttrString(target, "start");
- self->handle_data = PyObject_GetAttrString(target, "data");
- self->handle_end = PyObject_GetAttrString(target, "end");
- self->handle_comment = PyObject_GetAttrString(target, "comment");
- self->handle_pi = PyObject_GetAttrString(target, "pi");
-
- PyErr_Clear();
-
- /* configure parser */
- EXPAT(SetUserData)(self->parser, self);
- EXPAT(SetElementHandler)(
- self->parser,
- (XML_StartElementHandler) expat_start_handler,
- (XML_EndElementHandler) expat_end_handler
- );
- EXPAT(SetDefaultHandlerExpand)(
- self->parser,
- (XML_DefaultHandler) expat_default_handler
- );
- EXPAT(SetCharacterDataHandler)(
- self->parser,
- (XML_CharacterDataHandler) expat_data_handler
- );
- if (self->handle_comment)
- EXPAT(SetCommentHandler)(
- self->parser,
- (XML_CommentHandler) expat_comment_handler
- );
- if (self->handle_pi)
- EXPAT(SetProcessingInstructionHandler)(
- self->parser,
- (XML_ProcessingInstructionHandler) expat_pi_handler
- );
-
- ALLOC(sizeof(XMLParserObject), "create expatparser");
-
- return (PyObject*) self;
-}
-
-static void
-xmlparser_dealloc(XMLParserObject* self)
-{
- EXPAT(ParserFree)(self->parser);
-
- Py_XDECREF(self->handle_pi);
- Py_XDECREF(self->handle_comment);
- Py_XDECREF(self->handle_end);
- Py_XDECREF(self->handle_data);
- Py_XDECREF(self->handle_start);
- Py_XDECREF(self->handle_xml);
-
- Py_DECREF(self->target);
- Py_DECREF(self->entity);
- Py_DECREF(self->names);
-
- RELEASE(sizeof(XMLParserObject), "destroy expatparser");
-
- PyObject_Del(self);
-}
-
-/* -------------------------------------------------------------------- */
-/* methods (in alphabetical order) */
-
-LOCAL(PyObject*)
-expat_parse(XMLParserObject* self, char* data, int data_len, int final)
-{
- int ok;
-
- ok = EXPAT(Parse)(self->parser, data, data_len, final);
-
- if (PyErr_Occurred())
- return NULL;
-
- if (!ok) {
- PyErr_Format(
- PyExc_SyntaxError, "%s: line %d, column %d",
- EXPAT(ErrorString)(EXPAT(GetErrorCode)(self->parser)),
- EXPAT(GetErrorLineNumber)(self->parser),
- EXPAT(GetErrorColumnNumber)(self->parser)
- );
- return NULL;
- }
-
- Py_RETURN_NONE;
-}
-
-static PyObject*
-xmlparser_close(XMLParserObject* self, PyObject* args)
-{
- /* end feeding data to parser */
-
- PyObject* res;
- if (!PyArg_ParseTuple(args, ":close"))
- return NULL;
-
- res = expat_parse(self, "", 0, 1);
-
- if (res && TreeBuilder_CheckExact(self->target)) {
- Py_DECREF(res);
- return treebuilder_done((TreeBuilderObject*) self->target);
- }
-
- return res;
-}
-
-static PyObject*
-xmlparser_feed(XMLParserObject* self, PyObject* args)
-{
- /* feed data to parser */
-
- char* data;
- int data_len;
- if (!PyArg_ParseTuple(args, "s#:feed", &data, &data_len))
- return NULL;
-
- return expat_parse(self, data, data_len, 0);
-}
-
-static PyObject*
-xmlparser_parse(XMLParserObject* self, PyObject* args)
-{
- /* (internal) parse until end of input stream */
-
- PyObject* reader;
- PyObject* buffer;
- PyObject* res;
-
- PyObject* fileobj;
- if (!PyArg_ParseTuple(args, "O:_parse", &fileobj))
- return NULL;
-
- reader = PyObject_GetAttrString(fileobj, "read");
- if (!reader)
- return NULL;
-
- /* read from open file object */
- for (;;) {
-
- buffer = PyObject_CallFunction(reader, "i", 64*1024);
-
- if (!buffer) {
- /* read failed (e.g. due to KeyboardInterrupt) */
- Py_DECREF(reader);
- return NULL;
- }
-
- if (!PyString_CheckExact(buffer) || PyString_GET_SIZE(buffer) == 0) {
- Py_DECREF(buffer);
- break;
- }
-
- res = expat_parse(
- self, PyString_AS_STRING(buffer), PyString_GET_SIZE(buffer), 0
- );
-
- Py_DECREF(buffer);
-
- if (!res) {
- Py_DECREF(reader);
- return NULL;
- }
- Py_DECREF(res);
-
- }
-
- Py_DECREF(reader);
-
- res = expat_parse(self, "", 0, 1);
-
- if (res && TreeBuilder_CheckExact(self->target)) {
- Py_DECREF(res);
- return treebuilder_done((TreeBuilderObject*) self->target);
- }
-
- return res;
-}
-
-static PyObject*
-xmlparser_setevents(XMLParserObject* self, PyObject* args)
-{
- /* activate element event reporting */
-
- int i;
- TreeBuilderObject* target;
-
- PyObject* events; /* event collector */
- PyObject* event_set = Py_None;
- if (!PyArg_ParseTuple(args, "O!|O:_setevents", &PyList_Type, &events,
- &event_set))
- return NULL;
-
- if (!TreeBuilder_CheckExact(self->target)) {
- PyErr_SetString(
- PyExc_TypeError,
- "event handling only supported for cElementTree.Treebuilder "
- "targets"
- );
- return NULL;
- }
-
- target = (TreeBuilderObject*) self->target;
-
- Py_INCREF(events);
- Py_XDECREF(target->events);
- target->events = events;
-
- /* clear out existing events */
- Py_XDECREF(target->start_event_obj); target->start_event_obj = NULL;
- Py_XDECREF(target->end_event_obj); target->end_event_obj = NULL;
- Py_XDECREF(target->start_ns_event_obj); target->start_ns_event_obj = NULL;
- Py_XDECREF(target->end_ns_event_obj); target->end_ns_event_obj = NULL;
-
- if (event_set == Py_None) {
- /* default is "end" only */
- target->end_event_obj = PyString_FromString("end");
- Py_RETURN_NONE;
- }
-
- if (!PyTuple_Check(event_set)) /* FIXME: handle arbitrary sequences */
- goto error;
-
- for (i = 0; i < PyTuple_GET_SIZE(event_set); i++) {
- PyObject* item = PyTuple_GET_ITEM(event_set, i);
- char* event;
- if (!PyString_Check(item))
- goto error;
- event = PyString_AS_STRING(item);
- if (strcmp(event, "start") == 0) {
- Py_INCREF(item);
- target->start_event_obj = item;
- } else if (strcmp(event, "end") == 0) {
- Py_INCREF(item);
- Py_XDECREF(target->end_event_obj);
- target->end_event_obj = item;
- } else if (strcmp(event, "start-ns") == 0) {
- Py_INCREF(item);
- Py_XDECREF(target->start_ns_event_obj);
- target->start_ns_event_obj = item;
- EXPAT(SetNamespaceDeclHandler)(
- self->parser,
- (XML_StartNamespaceDeclHandler) expat_start_ns_handler,
- (XML_EndNamespaceDeclHandler) expat_end_ns_handler
- );
- } else if (strcmp(event, "end-ns") == 0) {
- Py_INCREF(item);
- Py_XDECREF(target->end_ns_event_obj);
- target->end_ns_event_obj = item;
- EXPAT(SetNamespaceDeclHandler)(
- self->parser,
- (XML_StartNamespaceDeclHandler) expat_start_ns_handler,
- (XML_EndNamespaceDeclHandler) expat_end_ns_handler
- );
- } else {
- PyErr_Format(
- PyExc_ValueError,
- "unknown event '%s'", event
- );
- return NULL;
- }
- }
-
- Py_RETURN_NONE;
-
- error:
- PyErr_SetString(
- PyExc_TypeError,
- "invalid event tuple"
- );
- return NULL;
-}
-
-static PyMethodDef xmlparser_methods[] = {
- {"feed", (PyCFunction) xmlparser_feed, METH_VARARGS},
- {"close", (PyCFunction) xmlparser_close, METH_VARARGS},
- {"_parse", (PyCFunction) xmlparser_parse, METH_VARARGS},
- {"_setevents", (PyCFunction) xmlparser_setevents, METH_VARARGS},
- {NULL, NULL}
-};
-
-static PyObject*
-xmlparser_getattr(XMLParserObject* self, char* name)
-{
- PyObject* res;
-
- res = Py_FindMethod(xmlparser_methods, (PyObject*) self, name);
- if (res)
- return res;
-
- PyErr_Clear();
-
- if (strcmp(name, "entity") == 0)
- res = self->entity;
- else if (strcmp(name, "target") == 0)
- res = self->target;
- else if (strcmp(name, "version") == 0) {
- char buffer[100];
- sprintf(buffer, "Expat %d.%d.%d", XML_MAJOR_VERSION,
- XML_MINOR_VERSION, XML_MICRO_VERSION);
- return PyString_FromString(buffer);
- } else {
- PyErr_SetString(PyExc_AttributeError, name);
- return NULL;
- }
-
- Py_INCREF(res);
- return res;
-}
-
-statichere PyTypeObject XMLParser_Type = {
- PyObject_HEAD_INIT(NULL)
- 0, "XMLParser", sizeof(XMLParserObject), 0,
- /* methods */
- (destructor)xmlparser_dealloc, /* tp_dealloc */
- 0, /* tp_print */
- (getattrfunc)xmlparser_getattr, /* tp_getattr */
-};
-
-#endif
-
-/* ==================================================================== */
-/* python module interface */
-
-static PyMethodDef _functions[] = {
- {"Element", (PyCFunction) element, METH_VARARGS|METH_KEYWORDS},
- {"SubElement", (PyCFunction) subelement, METH_VARARGS|METH_KEYWORDS},
- {"TreeBuilder", (PyCFunction) treebuilder, METH_VARARGS},
-#if defined(USE_EXPAT)
- {"XMLParser", (PyCFunction) xmlparser, METH_VARARGS|METH_KEYWORDS},
- {"XMLTreeBuilder", (PyCFunction) xmlparser, METH_VARARGS|METH_KEYWORDS},
-#endif
- {NULL, NULL}
-};
-
-DL_EXPORT(void)
-init_elementtree(void)
-{
- PyObject* m;
- PyObject* g;
- char* bootstrap;
-#if defined(USE_PYEXPAT_CAPI)
- struct PyExpat_CAPI* capi;
-#endif
-
- /* Patch object type */
- Element_Type.ob_type = TreeBuilder_Type.ob_type = &PyType_Type;
-#if defined(USE_EXPAT)
- XMLParser_Type.ob_type = &PyType_Type;
-#endif
-
- m = Py_InitModule("_elementtree", _functions);
-
- /* python glue code */
-
- g = PyDict_New();
-
- PyDict_SetItemString(g, "__builtins__", PyEval_GetBuiltins());
-
- bootstrap = (
-
-#if (PY_VERSION_HEX >= 0x02020000 && PY_VERSION_HEX < 0x02030000)
- "from __future__ import generators\n" /* enable yield under 2.2 */
-#endif
-
- "from copy import copy, deepcopy\n"
-
- "try:\n"
- " from xml.etree import ElementTree\n"
- "except ImportError:\n"
- " import ElementTree\n"
- "ET = ElementTree\n"
- "del ElementTree\n"
-
- "import _elementtree as cElementTree\n"
-
- "try:\n" /* check if copy works as is */
- " copy(cElementTree.Element('x'))\n"
- "except:\n"
- " def copyelement(elem):\n"
- " return elem\n"
-
- "def Comment(text=None):\n" /* public */
- " element = cElementTree.Element(ET.Comment)\n"
- " element.text = text\n"
- " return element\n"
- "cElementTree.Comment = Comment\n"
-
- "class ElementTree(ET.ElementTree):\n" /* public */
- " def parse(self, source, parser=None):\n"
- " if not hasattr(source, 'read'):\n"
- " source = open(source, 'rb')\n"
- " if parser is not None:\n"
- " while 1:\n"
- " data = source.read(65536)\n"
- " if not data:\n"
- " break\n"
- " parser.feed(data)\n"
- " self._root = parser.close()\n"
- " else:\n"
- " parser = cElementTree.XMLParser()\n"
- " self._root = parser._parse(source)\n"
- " return self._root\n"
- "cElementTree.ElementTree = ElementTree\n"
-
- "def getiterator(node, tag=None):\n" /* helper */
- " if tag == '*':\n"
- " tag = None\n"
-#if (PY_VERSION_HEX < 0x02020000)
- " nodes = []\n" /* 2.1 doesn't have yield */
- " if tag is None or node.tag == tag:\n"
- " nodes.append(node)\n"
- " for node in node:\n"
- " nodes.extend(getiterator(node, tag))\n"
- " return nodes\n"
-#else
- " if tag is None or node.tag == tag:\n"
- " yield node\n"
- " for node in node:\n"
- " for node in getiterator(node, tag):\n"
- " yield node\n"
-#endif
-
- "def parse(source, parser=None):\n" /* public */
- " tree = ElementTree()\n"
- " tree.parse(source, parser)\n"
- " return tree\n"
- "cElementTree.parse = parse\n"
-
-#if (PY_VERSION_HEX < 0x02020000)
- "if hasattr(ET, 'iterparse'):\n"
- " cElementTree.iterparse = ET.iterparse\n" /* delegate on 2.1 */
-#else
- "class iterparse(object):\n"
- " root = None\n"
- " def __init__(self, file, events=None):\n"
- " if not hasattr(file, 'read'):\n"
- " file = open(file, 'rb')\n"
- " self._file = file\n"
- " self._events = events\n"
- " def __iter__(self):\n"
- " events = []\n"
- " b = cElementTree.TreeBuilder()\n"
- " p = cElementTree.XMLParser(b)\n"
- " p._setevents(events, self._events)\n"
- " while 1:\n"
- " data = self._file.read(16384)\n"
- " if not data:\n"
- " break\n"
- " p.feed(data)\n"
- " for event in events:\n"
- " yield event\n"
- " del events[:]\n"
- " root = p.close()\n"
- " for event in events:\n"
- " yield event\n"
- " self.root = root\n"
- "cElementTree.iterparse = iterparse\n"
-#endif
-
- "def PI(target, text=None):\n" /* public */
- " element = cElementTree.Element(ET.ProcessingInstruction)\n"
- " element.text = target\n"
- " if text:\n"
- " element.text = element.text + ' ' + text\n"
- " return element\n"
-
- " elem = cElementTree.Element(ET.PI)\n"
- " elem.text = text\n"
- " return elem\n"
- "cElementTree.PI = cElementTree.ProcessingInstruction = PI\n"
-
- "def XML(text):\n" /* public */
- " parser = cElementTree.XMLParser()\n"
- " parser.feed(text)\n"
- " return parser.close()\n"
- "cElementTree.XML = cElementTree.fromstring = XML\n"
-
- "def XMLID(text):\n" /* public */
- " tree = XML(text)\n"
- " ids = {}\n"
- " for elem in tree.getiterator():\n"
- " id = elem.get('id')\n"
- " if id:\n"
- " ids[id] = elem\n"
- " return tree, ids\n"
- "cElementTree.XMLID = XMLID\n"
-
- "cElementTree.dump = ET.dump\n"
- "cElementTree.ElementPath = ElementPath = ET.ElementPath\n"
- "cElementTree.iselement = ET.iselement\n"
- "cElementTree.QName = ET.QName\n"
- "cElementTree.tostring = ET.tostring\n"
- "cElementTree.VERSION = '" VERSION "'\n"
- "cElementTree.__version__ = '" VERSION "'\n"
- "cElementTree.XMLParserError = SyntaxError\n"
-
- );
-
- PyRun_String(bootstrap, Py_file_input, g, NULL);
-
- elementpath_obj = PyDict_GetItemString(g, "ElementPath");
-
- elementtree_copyelement_obj = PyDict_GetItemString(g, "copyelement");
- if (elementtree_copyelement_obj) {
- /* reduce hack needed; enable reduce method */
- PyMethodDef* mp;
- for (mp = element_methods; mp->ml_name; mp++)
- if (mp->ml_meth == (PyCFunction) element_reduce) {
- mp->ml_name = "__reduce__";
- break;
- }
- } else
- PyErr_Clear();
- elementtree_deepcopy_obj = PyDict_GetItemString(g, "deepcopy");
- elementtree_getiterator_obj = PyDict_GetItemString(g, "getiterator");
-
-#if defined(USE_PYEXPAT_CAPI)
- /* link against pyexpat, if possible */
- capi = PyCObject_Import("pyexpat", "expat_CAPI");
- if (capi &&
- strcmp(capi->magic, PyExpat_CAPI_MAGIC) == 0 &&
- capi->size <= sizeof(*expat_capi) &&
- capi->MAJOR_VERSION == XML_MAJOR_VERSION &&
- capi->MINOR_VERSION == XML_MINOR_VERSION &&
- capi->MICRO_VERSION == XML_MICRO_VERSION)
- expat_capi = capi;
- else
- expat_capi = NULL;
-#endif
-
-}