17db96d56Sopenharmony_ci/*--------------------------------------------------------------------
27db96d56Sopenharmony_ci * Licensed to PSF under a Contributor Agreement.
37db96d56Sopenharmony_ci * See https://www.python.org/psf/license for licensing details.
47db96d56Sopenharmony_ci *
57db96d56Sopenharmony_ci * _elementtree - C accelerator for xml.etree.ElementTree
67db96d56Sopenharmony_ci * Copyright (c) 1999-2009 by Secret Labs AB.  All rights reserved.
77db96d56Sopenharmony_ci * Copyright (c) 1999-2009 by Fredrik Lundh.
87db96d56Sopenharmony_ci *
97db96d56Sopenharmony_ci * info@pythonware.com
107db96d56Sopenharmony_ci * http://www.pythonware.com
117db96d56Sopenharmony_ci *--------------------------------------------------------------------
127db96d56Sopenharmony_ci */
137db96d56Sopenharmony_ci
147db96d56Sopenharmony_ci#define PY_SSIZE_T_CLEAN
157db96d56Sopenharmony_ci#define NEEDS_PY_IDENTIFIER
167db96d56Sopenharmony_ci
177db96d56Sopenharmony_ci#include "Python.h"
187db96d56Sopenharmony_ci#include "structmember.h"         // PyMemberDef
197db96d56Sopenharmony_ci
207db96d56Sopenharmony_ci/* -------------------------------------------------------------------- */
217db96d56Sopenharmony_ci/* configuration */
227db96d56Sopenharmony_ci
237db96d56Sopenharmony_ci/* An element can hold this many children without extra memory
247db96d56Sopenharmony_ci   allocations. */
257db96d56Sopenharmony_ci#define STATIC_CHILDREN 4
267db96d56Sopenharmony_ci
277db96d56Sopenharmony_ci/* For best performance, chose a value so that 80-90% of all nodes
287db96d56Sopenharmony_ci   have no more than the given number of children.  Set this to zero
297db96d56Sopenharmony_ci   to minimize the size of the element structure itself (this only
307db96d56Sopenharmony_ci   helps if you have lots of leaf nodes with attributes). */
317db96d56Sopenharmony_ci
327db96d56Sopenharmony_ci/* Also note that pymalloc always allocates blocks in multiples of
337db96d56Sopenharmony_ci   eight bytes.  For the current C version of ElementTree, this means
347db96d56Sopenharmony_ci   that the number of children should be an even number, at least on
357db96d56Sopenharmony_ci   32-bit platforms. */
367db96d56Sopenharmony_ci
377db96d56Sopenharmony_ci/* -------------------------------------------------------------------- */
387db96d56Sopenharmony_ci
397db96d56Sopenharmony_ci/* compiler tweaks */
407db96d56Sopenharmony_ci#if defined(_MSC_VER)
417db96d56Sopenharmony_ci#define LOCAL(type) static __inline type __fastcall
427db96d56Sopenharmony_ci#else
437db96d56Sopenharmony_ci#define LOCAL(type) static type
447db96d56Sopenharmony_ci#endif
457db96d56Sopenharmony_ci
467db96d56Sopenharmony_ci/* macros used to store 'join' flags in string object pointers.  note
477db96d56Sopenharmony_ci   that all use of text and tail as object pointers must be wrapped in
487db96d56Sopenharmony_ci   JOIN_OBJ.  see comments in the ElementObject definition for more
497db96d56Sopenharmony_ci   info. */
507db96d56Sopenharmony_ci#define JOIN_GET(p) ((uintptr_t) (p) & 1)
517db96d56Sopenharmony_ci#define JOIN_SET(p, flag) ((void*) ((uintptr_t) (JOIN_OBJ(p)) | (flag)))
527db96d56Sopenharmony_ci#define JOIN_OBJ(p) ((PyObject*) ((uintptr_t) (p) & ~(uintptr_t)1))
537db96d56Sopenharmony_ci
547db96d56Sopenharmony_ci/* Py_SETREF for a PyObject* that uses a join flag. */
557db96d56Sopenharmony_ciPy_LOCAL_INLINE(void)
567db96d56Sopenharmony_ci_set_joined_ptr(PyObject **p, PyObject *new_joined_ptr)
577db96d56Sopenharmony_ci{
587db96d56Sopenharmony_ci    PyObject *tmp = JOIN_OBJ(*p);
597db96d56Sopenharmony_ci    *p = new_joined_ptr;
607db96d56Sopenharmony_ci    Py_DECREF(tmp);
617db96d56Sopenharmony_ci}
627db96d56Sopenharmony_ci
637db96d56Sopenharmony_ci/* Py_CLEAR for a PyObject* that uses a join flag. Pass the pointer by
647db96d56Sopenharmony_ci * reference since this function sets it to NULL.
657db96d56Sopenharmony_ci*/
667db96d56Sopenharmony_cistatic void _clear_joined_ptr(PyObject **p)
677db96d56Sopenharmony_ci{
687db96d56Sopenharmony_ci    if (*p) {
697db96d56Sopenharmony_ci        _set_joined_ptr(p, NULL);
707db96d56Sopenharmony_ci    }
717db96d56Sopenharmony_ci}
727db96d56Sopenharmony_ci
737db96d56Sopenharmony_ci/* Types defined by this extension */
747db96d56Sopenharmony_cistatic PyTypeObject Element_Type;
757db96d56Sopenharmony_cistatic PyTypeObject ElementIter_Type;
767db96d56Sopenharmony_cistatic PyTypeObject TreeBuilder_Type;
777db96d56Sopenharmony_cistatic PyTypeObject XMLParser_Type;
787db96d56Sopenharmony_ci
797db96d56Sopenharmony_ci
807db96d56Sopenharmony_ci/* Per-module state; PEP 3121 */
817db96d56Sopenharmony_citypedef struct {
827db96d56Sopenharmony_ci    PyObject *parseerror_obj;
837db96d56Sopenharmony_ci    PyObject *deepcopy_obj;
847db96d56Sopenharmony_ci    PyObject *elementpath_obj;
857db96d56Sopenharmony_ci    PyObject *comment_factory;
867db96d56Sopenharmony_ci    PyObject *pi_factory;
877db96d56Sopenharmony_ci} elementtreestate;
887db96d56Sopenharmony_ci
897db96d56Sopenharmony_cistatic struct PyModuleDef elementtreemodule;
907db96d56Sopenharmony_ci
917db96d56Sopenharmony_ci/* Given a module object (assumed to be _elementtree), get its per-module
927db96d56Sopenharmony_ci * state.
937db96d56Sopenharmony_ci */
947db96d56Sopenharmony_cistatic inline elementtreestate*
957db96d56Sopenharmony_ciget_elementtree_state(PyObject *module)
967db96d56Sopenharmony_ci{
977db96d56Sopenharmony_ci    void *state = PyModule_GetState(module);
987db96d56Sopenharmony_ci    assert(state != NULL);
997db96d56Sopenharmony_ci    return (elementtreestate *)state;
1007db96d56Sopenharmony_ci}
1017db96d56Sopenharmony_ci
1027db96d56Sopenharmony_ci/* Find the module instance imported in the currently running sub-interpreter
1037db96d56Sopenharmony_ci * and get its state.
1047db96d56Sopenharmony_ci */
1057db96d56Sopenharmony_ci#define ET_STATE_GLOBAL \
1067db96d56Sopenharmony_ci    ((elementtreestate *) PyModule_GetState(PyState_FindModule(&elementtreemodule)))
1077db96d56Sopenharmony_ci
1087db96d56Sopenharmony_cistatic int
1097db96d56Sopenharmony_cielementtree_clear(PyObject *m)
1107db96d56Sopenharmony_ci{
1117db96d56Sopenharmony_ci    elementtreestate *st = get_elementtree_state(m);
1127db96d56Sopenharmony_ci    Py_CLEAR(st->parseerror_obj);
1137db96d56Sopenharmony_ci    Py_CLEAR(st->deepcopy_obj);
1147db96d56Sopenharmony_ci    Py_CLEAR(st->elementpath_obj);
1157db96d56Sopenharmony_ci    Py_CLEAR(st->comment_factory);
1167db96d56Sopenharmony_ci    Py_CLEAR(st->pi_factory);
1177db96d56Sopenharmony_ci    return 0;
1187db96d56Sopenharmony_ci}
1197db96d56Sopenharmony_ci
1207db96d56Sopenharmony_cistatic int
1217db96d56Sopenharmony_cielementtree_traverse(PyObject *m, visitproc visit, void *arg)
1227db96d56Sopenharmony_ci{
1237db96d56Sopenharmony_ci    elementtreestate *st = get_elementtree_state(m);
1247db96d56Sopenharmony_ci    Py_VISIT(st->parseerror_obj);
1257db96d56Sopenharmony_ci    Py_VISIT(st->deepcopy_obj);
1267db96d56Sopenharmony_ci    Py_VISIT(st->elementpath_obj);
1277db96d56Sopenharmony_ci    Py_VISIT(st->comment_factory);
1287db96d56Sopenharmony_ci    Py_VISIT(st->pi_factory);
1297db96d56Sopenharmony_ci    return 0;
1307db96d56Sopenharmony_ci}
1317db96d56Sopenharmony_ci
1327db96d56Sopenharmony_cistatic void
1337db96d56Sopenharmony_cielementtree_free(void *m)
1347db96d56Sopenharmony_ci{
1357db96d56Sopenharmony_ci    elementtree_clear((PyObject *)m);
1367db96d56Sopenharmony_ci}
1377db96d56Sopenharmony_ci
1387db96d56Sopenharmony_ci/* helpers */
1397db96d56Sopenharmony_ci
1407db96d56Sopenharmony_ciLOCAL(PyObject*)
1417db96d56Sopenharmony_cilist_join(PyObject* list)
1427db96d56Sopenharmony_ci{
1437db96d56Sopenharmony_ci    /* join list elements */
1447db96d56Sopenharmony_ci    PyObject* joiner;
1457db96d56Sopenharmony_ci    PyObject* result;
1467db96d56Sopenharmony_ci
1477db96d56Sopenharmony_ci    joiner = PyUnicode_FromStringAndSize("", 0);
1487db96d56Sopenharmony_ci    if (!joiner)
1497db96d56Sopenharmony_ci        return NULL;
1507db96d56Sopenharmony_ci    result = PyUnicode_Join(joiner, list);
1517db96d56Sopenharmony_ci    Py_DECREF(joiner);
1527db96d56Sopenharmony_ci    return result;
1537db96d56Sopenharmony_ci}
1547db96d56Sopenharmony_ci
1557db96d56Sopenharmony_ci/* Is the given object an empty dictionary?
1567db96d56Sopenharmony_ci*/
1577db96d56Sopenharmony_cistatic int
1587db96d56Sopenharmony_ciis_empty_dict(PyObject *obj)
1597db96d56Sopenharmony_ci{
1607db96d56Sopenharmony_ci    return PyDict_CheckExact(obj) && PyDict_GET_SIZE(obj) == 0;
1617db96d56Sopenharmony_ci}
1627db96d56Sopenharmony_ci
1637db96d56Sopenharmony_ci
1647db96d56Sopenharmony_ci/* -------------------------------------------------------------------- */
1657db96d56Sopenharmony_ci/* the Element type */
1667db96d56Sopenharmony_ci
1677db96d56Sopenharmony_citypedef struct {
1687db96d56Sopenharmony_ci
1697db96d56Sopenharmony_ci    /* attributes (a dictionary object), or NULL if no attributes */
1707db96d56Sopenharmony_ci    PyObject* attrib;
1717db96d56Sopenharmony_ci
1727db96d56Sopenharmony_ci    /* child elements */
1737db96d56Sopenharmony_ci    Py_ssize_t length; /* actual number of items */
1747db96d56Sopenharmony_ci    Py_ssize_t allocated; /* allocated items */
1757db96d56Sopenharmony_ci
1767db96d56Sopenharmony_ci    /* this either points to _children or to a malloced buffer */
1777db96d56Sopenharmony_ci    PyObject* *children;
1787db96d56Sopenharmony_ci
1797db96d56Sopenharmony_ci    PyObject* _children[STATIC_CHILDREN];
1807db96d56Sopenharmony_ci
1817db96d56Sopenharmony_ci} ElementObjectExtra;
1827db96d56Sopenharmony_ci
1837db96d56Sopenharmony_citypedef struct {
1847db96d56Sopenharmony_ci    PyObject_HEAD
1857db96d56Sopenharmony_ci
1867db96d56Sopenharmony_ci    /* element tag (a string). */
1877db96d56Sopenharmony_ci    PyObject* tag;
1887db96d56Sopenharmony_ci
1897db96d56Sopenharmony_ci    /* text before first child.  note that this is a tagged pointer;
1907db96d56Sopenharmony_ci       use JOIN_OBJ to get the object pointer.  the join flag is used
1917db96d56Sopenharmony_ci       to distinguish lists created by the tree builder from lists
1927db96d56Sopenharmony_ci       assigned to the attribute by application code; the former
1937db96d56Sopenharmony_ci       should be joined before being returned to the user, the latter
1947db96d56Sopenharmony_ci       should be left intact. */
1957db96d56Sopenharmony_ci    PyObject* text;
1967db96d56Sopenharmony_ci
1977db96d56Sopenharmony_ci    /* text after this element, in parent.  note that this is a tagged
1987db96d56Sopenharmony_ci       pointer; use JOIN_OBJ to get the object pointer. */
1997db96d56Sopenharmony_ci    PyObject* tail;
2007db96d56Sopenharmony_ci
2017db96d56Sopenharmony_ci    ElementObjectExtra* extra;
2027db96d56Sopenharmony_ci
2037db96d56Sopenharmony_ci    PyObject *weakreflist; /* For tp_weaklistoffset */
2047db96d56Sopenharmony_ci
2057db96d56Sopenharmony_ci} ElementObject;
2067db96d56Sopenharmony_ci
2077db96d56Sopenharmony_ci
2087db96d56Sopenharmony_ci#define Element_CheckExact(op) Py_IS_TYPE(op, &Element_Type)
2097db96d56Sopenharmony_ci#define Element_Check(op) PyObject_TypeCheck(op, &Element_Type)
2107db96d56Sopenharmony_ci
2117db96d56Sopenharmony_ci
2127db96d56Sopenharmony_ci/* -------------------------------------------------------------------- */
2137db96d56Sopenharmony_ci/* Element constructors and destructor */
2147db96d56Sopenharmony_ci
2157db96d56Sopenharmony_ciLOCAL(int)
2167db96d56Sopenharmony_cicreate_extra(ElementObject* self, PyObject* attrib)
2177db96d56Sopenharmony_ci{
2187db96d56Sopenharmony_ci    self->extra = PyObject_Malloc(sizeof(ElementObjectExtra));
2197db96d56Sopenharmony_ci    if (!self->extra) {
2207db96d56Sopenharmony_ci        PyErr_NoMemory();
2217db96d56Sopenharmony_ci        return -1;
2227db96d56Sopenharmony_ci    }
2237db96d56Sopenharmony_ci
2247db96d56Sopenharmony_ci    Py_XINCREF(attrib);
2257db96d56Sopenharmony_ci    self->extra->attrib = attrib;
2267db96d56Sopenharmony_ci
2277db96d56Sopenharmony_ci    self->extra->length = 0;
2287db96d56Sopenharmony_ci    self->extra->allocated = STATIC_CHILDREN;
2297db96d56Sopenharmony_ci    self->extra->children = self->extra->_children;
2307db96d56Sopenharmony_ci
2317db96d56Sopenharmony_ci    return 0;
2327db96d56Sopenharmony_ci}
2337db96d56Sopenharmony_ci
2347db96d56Sopenharmony_ciLOCAL(void)
2357db96d56Sopenharmony_cidealloc_extra(ElementObjectExtra *extra)
2367db96d56Sopenharmony_ci{
2377db96d56Sopenharmony_ci    Py_ssize_t i;
2387db96d56Sopenharmony_ci
2397db96d56Sopenharmony_ci    if (!extra)
2407db96d56Sopenharmony_ci        return;
2417db96d56Sopenharmony_ci
2427db96d56Sopenharmony_ci    Py_XDECREF(extra->attrib);
2437db96d56Sopenharmony_ci
2447db96d56Sopenharmony_ci    for (i = 0; i < extra->length; i++)
2457db96d56Sopenharmony_ci        Py_DECREF(extra->children[i]);
2467db96d56Sopenharmony_ci
2477db96d56Sopenharmony_ci    if (extra->children != extra->_children)
2487db96d56Sopenharmony_ci        PyObject_Free(extra->children);
2497db96d56Sopenharmony_ci
2507db96d56Sopenharmony_ci    PyObject_Free(extra);
2517db96d56Sopenharmony_ci}
2527db96d56Sopenharmony_ci
2537db96d56Sopenharmony_ciLOCAL(void)
2547db96d56Sopenharmony_ciclear_extra(ElementObject* self)
2557db96d56Sopenharmony_ci{
2567db96d56Sopenharmony_ci    ElementObjectExtra *myextra;
2577db96d56Sopenharmony_ci
2587db96d56Sopenharmony_ci    if (!self->extra)
2597db96d56Sopenharmony_ci        return;
2607db96d56Sopenharmony_ci
2617db96d56Sopenharmony_ci    /* Avoid DECREFs calling into this code again (cycles, etc.)
2627db96d56Sopenharmony_ci    */
2637db96d56Sopenharmony_ci    myextra = self->extra;
2647db96d56Sopenharmony_ci    self->extra = NULL;
2657db96d56Sopenharmony_ci
2667db96d56Sopenharmony_ci    dealloc_extra(myextra);
2677db96d56Sopenharmony_ci}
2687db96d56Sopenharmony_ci
2697db96d56Sopenharmony_ci/* Convenience internal function to create new Element objects with the given
2707db96d56Sopenharmony_ci * tag and attributes.
2717db96d56Sopenharmony_ci*/
2727db96d56Sopenharmony_ciLOCAL(PyObject*)
2737db96d56Sopenharmony_cicreate_new_element(PyObject* tag, PyObject* attrib)
2747db96d56Sopenharmony_ci{
2757db96d56Sopenharmony_ci    ElementObject* self;
2767db96d56Sopenharmony_ci
2777db96d56Sopenharmony_ci    self = PyObject_GC_New(ElementObject, &Element_Type);
2787db96d56Sopenharmony_ci    if (self == NULL)
2797db96d56Sopenharmony_ci        return NULL;
2807db96d56Sopenharmony_ci    self->extra = NULL;
2817db96d56Sopenharmony_ci
2827db96d56Sopenharmony_ci    Py_INCREF(tag);
2837db96d56Sopenharmony_ci    self->tag = tag;
2847db96d56Sopenharmony_ci
2857db96d56Sopenharmony_ci    Py_INCREF(Py_None);
2867db96d56Sopenharmony_ci    self->text = Py_None;
2877db96d56Sopenharmony_ci
2887db96d56Sopenharmony_ci    Py_INCREF(Py_None);
2897db96d56Sopenharmony_ci    self->tail = Py_None;
2907db96d56Sopenharmony_ci
2917db96d56Sopenharmony_ci    self->weakreflist = NULL;
2927db96d56Sopenharmony_ci
2937db96d56Sopenharmony_ci    PyObject_GC_Track(self);
2947db96d56Sopenharmony_ci
2957db96d56Sopenharmony_ci    if (attrib != NULL && !is_empty_dict(attrib)) {
2967db96d56Sopenharmony_ci        if (create_extra(self, attrib) < 0) {
2977db96d56Sopenharmony_ci            Py_DECREF(self);
2987db96d56Sopenharmony_ci            return NULL;
2997db96d56Sopenharmony_ci        }
3007db96d56Sopenharmony_ci    }
3017db96d56Sopenharmony_ci
3027db96d56Sopenharmony_ci    return (PyObject*) self;
3037db96d56Sopenharmony_ci}
3047db96d56Sopenharmony_ci
3057db96d56Sopenharmony_cistatic PyObject *
3067db96d56Sopenharmony_cielement_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
3077db96d56Sopenharmony_ci{
3087db96d56Sopenharmony_ci    ElementObject *e = (ElementObject *)type->tp_alloc(type, 0);
3097db96d56Sopenharmony_ci    if (e != NULL) {
3107db96d56Sopenharmony_ci        Py_INCREF(Py_None);
3117db96d56Sopenharmony_ci        e->tag = Py_None;
3127db96d56Sopenharmony_ci
3137db96d56Sopenharmony_ci        Py_INCREF(Py_None);
3147db96d56Sopenharmony_ci        e->text = Py_None;
3157db96d56Sopenharmony_ci
3167db96d56Sopenharmony_ci        Py_INCREF(Py_None);
3177db96d56Sopenharmony_ci        e->tail = Py_None;
3187db96d56Sopenharmony_ci
3197db96d56Sopenharmony_ci        e->extra = NULL;
3207db96d56Sopenharmony_ci        e->weakreflist = NULL;
3217db96d56Sopenharmony_ci    }
3227db96d56Sopenharmony_ci    return (PyObject *)e;
3237db96d56Sopenharmony_ci}
3247db96d56Sopenharmony_ci
3257db96d56Sopenharmony_ci/* Helper function for extracting the attrib dictionary from a keywords dict.
3267db96d56Sopenharmony_ci * This is required by some constructors/functions in this module that can
3277db96d56Sopenharmony_ci * either accept attrib as a keyword argument or all attributes splashed
3287db96d56Sopenharmony_ci * directly into *kwds.
3297db96d56Sopenharmony_ci *
3307db96d56Sopenharmony_ci * Return a dictionary with the content of kwds merged into the content of
3317db96d56Sopenharmony_ci * attrib. If there is no attrib keyword, return a copy of kwds.
3327db96d56Sopenharmony_ci */
3337db96d56Sopenharmony_cistatic PyObject*
3347db96d56Sopenharmony_ciget_attrib_from_keywords(PyObject *kwds)
3357db96d56Sopenharmony_ci{
3367db96d56Sopenharmony_ci    PyObject *attrib_str = PyUnicode_FromString("attrib");
3377db96d56Sopenharmony_ci    if (attrib_str == NULL) {
3387db96d56Sopenharmony_ci        return NULL;
3397db96d56Sopenharmony_ci    }
3407db96d56Sopenharmony_ci    PyObject *attrib = PyDict_GetItemWithError(kwds, attrib_str);
3417db96d56Sopenharmony_ci
3427db96d56Sopenharmony_ci    if (attrib) {
3437db96d56Sopenharmony_ci        /* If attrib was found in kwds, copy its value and remove it from
3447db96d56Sopenharmony_ci         * kwds
3457db96d56Sopenharmony_ci         */
3467db96d56Sopenharmony_ci        if (!PyDict_Check(attrib)) {
3477db96d56Sopenharmony_ci            Py_DECREF(attrib_str);
3487db96d56Sopenharmony_ci            PyErr_Format(PyExc_TypeError, "attrib must be dict, not %.100s",
3497db96d56Sopenharmony_ci                         Py_TYPE(attrib)->tp_name);
3507db96d56Sopenharmony_ci            return NULL;
3517db96d56Sopenharmony_ci        }
3527db96d56Sopenharmony_ci        attrib = PyDict_Copy(attrib);
3537db96d56Sopenharmony_ci        if (attrib && PyDict_DelItem(kwds, attrib_str) < 0) {
3547db96d56Sopenharmony_ci            Py_DECREF(attrib);
3557db96d56Sopenharmony_ci            attrib = NULL;
3567db96d56Sopenharmony_ci        }
3577db96d56Sopenharmony_ci    }
3587db96d56Sopenharmony_ci    else if (!PyErr_Occurred()) {
3597db96d56Sopenharmony_ci        attrib = PyDict_New();
3607db96d56Sopenharmony_ci    }
3617db96d56Sopenharmony_ci
3627db96d56Sopenharmony_ci    Py_DECREF(attrib_str);
3637db96d56Sopenharmony_ci
3647db96d56Sopenharmony_ci    if (attrib != NULL && PyDict_Update(attrib, kwds) < 0) {
3657db96d56Sopenharmony_ci        Py_DECREF(attrib);
3667db96d56Sopenharmony_ci        return NULL;
3677db96d56Sopenharmony_ci    }
3687db96d56Sopenharmony_ci    return attrib;
3697db96d56Sopenharmony_ci}
3707db96d56Sopenharmony_ci
3717db96d56Sopenharmony_ci/*[clinic input]
3727db96d56Sopenharmony_cimodule _elementtree
3737db96d56Sopenharmony_ciclass _elementtree.Element "ElementObject *" "&Element_Type"
3747db96d56Sopenharmony_ciclass _elementtree.TreeBuilder "TreeBuilderObject *" "&TreeBuilder_Type"
3757db96d56Sopenharmony_ciclass _elementtree.XMLParser "XMLParserObject *" "&XMLParser_Type"
3767db96d56Sopenharmony_ci[clinic start generated code]*/
3777db96d56Sopenharmony_ci/*[clinic end generated code: output=da39a3ee5e6b4b0d input=159aa50a54061c22]*/
3787db96d56Sopenharmony_ci
3797db96d56Sopenharmony_cistatic int
3807db96d56Sopenharmony_cielement_init(PyObject *self, PyObject *args, PyObject *kwds)
3817db96d56Sopenharmony_ci{
3827db96d56Sopenharmony_ci    PyObject *tag;
3837db96d56Sopenharmony_ci    PyObject *attrib = NULL;
3847db96d56Sopenharmony_ci    ElementObject *self_elem;
3857db96d56Sopenharmony_ci
3867db96d56Sopenharmony_ci    if (!PyArg_ParseTuple(args, "O|O!:Element", &tag, &PyDict_Type, &attrib))
3877db96d56Sopenharmony_ci        return -1;
3887db96d56Sopenharmony_ci
3897db96d56Sopenharmony_ci    if (attrib) {
3907db96d56Sopenharmony_ci        /* attrib passed as positional arg */
3917db96d56Sopenharmony_ci        attrib = PyDict_Copy(attrib);
3927db96d56Sopenharmony_ci        if (!attrib)
3937db96d56Sopenharmony_ci            return -1;
3947db96d56Sopenharmony_ci        if (kwds) {
3957db96d56Sopenharmony_ci            if (PyDict_Update(attrib, kwds) < 0) {
3967db96d56Sopenharmony_ci                Py_DECREF(attrib);
3977db96d56Sopenharmony_ci                return -1;
3987db96d56Sopenharmony_ci            }
3997db96d56Sopenharmony_ci        }
4007db96d56Sopenharmony_ci    } else if (kwds) {
4017db96d56Sopenharmony_ci        /* have keywords args */
4027db96d56Sopenharmony_ci        attrib = get_attrib_from_keywords(kwds);
4037db96d56Sopenharmony_ci        if (!attrib)
4047db96d56Sopenharmony_ci            return -1;
4057db96d56Sopenharmony_ci    }
4067db96d56Sopenharmony_ci
4077db96d56Sopenharmony_ci    self_elem = (ElementObject *)self;
4087db96d56Sopenharmony_ci
4097db96d56Sopenharmony_ci    if (attrib != NULL && !is_empty_dict(attrib)) {
4107db96d56Sopenharmony_ci        if (create_extra(self_elem, attrib) < 0) {
4117db96d56Sopenharmony_ci            Py_DECREF(attrib);
4127db96d56Sopenharmony_ci            return -1;
4137db96d56Sopenharmony_ci        }
4147db96d56Sopenharmony_ci    }
4157db96d56Sopenharmony_ci
4167db96d56Sopenharmony_ci    /* We own a reference to attrib here and it's no longer needed. */
4177db96d56Sopenharmony_ci    Py_XDECREF(attrib);
4187db96d56Sopenharmony_ci
4197db96d56Sopenharmony_ci    /* Replace the objects already pointed to by tag, text and tail. */
4207db96d56Sopenharmony_ci    Py_INCREF(tag);
4217db96d56Sopenharmony_ci    Py_XSETREF(self_elem->tag, tag);
4227db96d56Sopenharmony_ci
4237db96d56Sopenharmony_ci    Py_INCREF(Py_None);
4247db96d56Sopenharmony_ci    _set_joined_ptr(&self_elem->text, Py_None);
4257db96d56Sopenharmony_ci
4267db96d56Sopenharmony_ci    Py_INCREF(Py_None);
4277db96d56Sopenharmony_ci    _set_joined_ptr(&self_elem->tail, Py_None);
4287db96d56Sopenharmony_ci
4297db96d56Sopenharmony_ci    return 0;
4307db96d56Sopenharmony_ci}
4317db96d56Sopenharmony_ci
4327db96d56Sopenharmony_ciLOCAL(int)
4337db96d56Sopenharmony_cielement_resize(ElementObject* self, Py_ssize_t extra)
4347db96d56Sopenharmony_ci{
4357db96d56Sopenharmony_ci    Py_ssize_t size;
4367db96d56Sopenharmony_ci    PyObject* *children;
4377db96d56Sopenharmony_ci
4387db96d56Sopenharmony_ci    assert(extra >= 0);
4397db96d56Sopenharmony_ci    /* make sure self->children can hold the given number of extra
4407db96d56Sopenharmony_ci       elements.  set an exception and return -1 if allocation failed */
4417db96d56Sopenharmony_ci
4427db96d56Sopenharmony_ci    if (!self->extra) {
4437db96d56Sopenharmony_ci        if (create_extra(self, NULL) < 0)
4447db96d56Sopenharmony_ci            return -1;
4457db96d56Sopenharmony_ci    }
4467db96d56Sopenharmony_ci
4477db96d56Sopenharmony_ci    size = self->extra->length + extra;  /* never overflows */
4487db96d56Sopenharmony_ci
4497db96d56Sopenharmony_ci    if (size > self->extra->allocated) {
4507db96d56Sopenharmony_ci        /* use Python 2.4's list growth strategy */
4517db96d56Sopenharmony_ci        size = (size >> 3) + (size < 9 ? 3 : 6) + size;
4527db96d56Sopenharmony_ci        /* Coverity CID #182 size_error: Allocating 1 bytes to pointer "children"
4537db96d56Sopenharmony_ci         * which needs at least 4 bytes.
4547db96d56Sopenharmony_ci         * Although it's a false alarm always assume at least one child to
4557db96d56Sopenharmony_ci         * be safe.
4567db96d56Sopenharmony_ci         */
4577db96d56Sopenharmony_ci        size = size ? size : 1;
4587db96d56Sopenharmony_ci        if ((size_t)size > PY_SSIZE_T_MAX/sizeof(PyObject*))
4597db96d56Sopenharmony_ci            goto nomemory;
4607db96d56Sopenharmony_ci        if (self->extra->children != self->extra->_children) {
4617db96d56Sopenharmony_ci            /* Coverity CID #182 size_error: Allocating 1 bytes to pointer
4627db96d56Sopenharmony_ci             * "children", which needs at least 4 bytes. Although it's a
4637db96d56Sopenharmony_ci             * false alarm always assume at least one child to be safe.
4647db96d56Sopenharmony_ci             */
4657db96d56Sopenharmony_ci            children = PyObject_Realloc(self->extra->children,
4667db96d56Sopenharmony_ci                                        size * sizeof(PyObject*));
4677db96d56Sopenharmony_ci            if (!children)
4687db96d56Sopenharmony_ci                goto nomemory;
4697db96d56Sopenharmony_ci        } else {
4707db96d56Sopenharmony_ci            children = PyObject_Malloc(size * sizeof(PyObject*));
4717db96d56Sopenharmony_ci            if (!children)
4727db96d56Sopenharmony_ci                goto nomemory;
4737db96d56Sopenharmony_ci            /* copy existing children from static area to malloc buffer */
4747db96d56Sopenharmony_ci            memcpy(children, self->extra->children,
4757db96d56Sopenharmony_ci                   self->extra->length * sizeof(PyObject*));
4767db96d56Sopenharmony_ci        }
4777db96d56Sopenharmony_ci        self->extra->children = children;
4787db96d56Sopenharmony_ci        self->extra->allocated = size;
4797db96d56Sopenharmony_ci    }
4807db96d56Sopenharmony_ci
4817db96d56Sopenharmony_ci    return 0;
4827db96d56Sopenharmony_ci
4837db96d56Sopenharmony_ci  nomemory:
4847db96d56Sopenharmony_ci    PyErr_NoMemory();
4857db96d56Sopenharmony_ci    return -1;
4867db96d56Sopenharmony_ci}
4877db96d56Sopenharmony_ci
4887db96d56Sopenharmony_ciLOCAL(void)
4897db96d56Sopenharmony_ciraise_type_error(PyObject *element)
4907db96d56Sopenharmony_ci{
4917db96d56Sopenharmony_ci    PyErr_Format(PyExc_TypeError,
4927db96d56Sopenharmony_ci                 "expected an Element, not \"%.200s\"",
4937db96d56Sopenharmony_ci                 Py_TYPE(element)->tp_name);
4947db96d56Sopenharmony_ci}
4957db96d56Sopenharmony_ci
4967db96d56Sopenharmony_ciLOCAL(int)
4977db96d56Sopenharmony_cielement_add_subelement(ElementObject* self, PyObject* element)
4987db96d56Sopenharmony_ci{
4997db96d56Sopenharmony_ci    /* add a child element to a parent */
5007db96d56Sopenharmony_ci
5017db96d56Sopenharmony_ci    if (!Element_Check(element)) {
5027db96d56Sopenharmony_ci        raise_type_error(element);
5037db96d56Sopenharmony_ci        return -1;
5047db96d56Sopenharmony_ci    }
5057db96d56Sopenharmony_ci
5067db96d56Sopenharmony_ci    if (element_resize(self, 1) < 0)
5077db96d56Sopenharmony_ci        return -1;
5087db96d56Sopenharmony_ci
5097db96d56Sopenharmony_ci    Py_INCREF(element);
5107db96d56Sopenharmony_ci    self->extra->children[self->extra->length] = element;
5117db96d56Sopenharmony_ci
5127db96d56Sopenharmony_ci    self->extra->length++;
5137db96d56Sopenharmony_ci
5147db96d56Sopenharmony_ci    return 0;
5157db96d56Sopenharmony_ci}
5167db96d56Sopenharmony_ci
5177db96d56Sopenharmony_ciLOCAL(PyObject*)
5187db96d56Sopenharmony_cielement_get_attrib(ElementObject* self)
5197db96d56Sopenharmony_ci{
5207db96d56Sopenharmony_ci    /* return borrowed reference to attrib dictionary */
5217db96d56Sopenharmony_ci    /* note: this function assumes that the extra section exists */
5227db96d56Sopenharmony_ci
5237db96d56Sopenharmony_ci    PyObject* res = self->extra->attrib;
5247db96d56Sopenharmony_ci
5257db96d56Sopenharmony_ci    if (!res) {
5267db96d56Sopenharmony_ci        /* create missing dictionary */
5277db96d56Sopenharmony_ci        res = self->extra->attrib = PyDict_New();
5287db96d56Sopenharmony_ci    }
5297db96d56Sopenharmony_ci
5307db96d56Sopenharmony_ci    return res;
5317db96d56Sopenharmony_ci}
5327db96d56Sopenharmony_ci
5337db96d56Sopenharmony_ciLOCAL(PyObject*)
5347db96d56Sopenharmony_cielement_get_text(ElementObject* self)
5357db96d56Sopenharmony_ci{
5367db96d56Sopenharmony_ci    /* return borrowed reference to text attribute */
5377db96d56Sopenharmony_ci
5387db96d56Sopenharmony_ci    PyObject *res = self->text;
5397db96d56Sopenharmony_ci
5407db96d56Sopenharmony_ci    if (JOIN_GET(res)) {
5417db96d56Sopenharmony_ci        res = JOIN_OBJ(res);
5427db96d56Sopenharmony_ci        if (PyList_CheckExact(res)) {
5437db96d56Sopenharmony_ci            PyObject *tmp = list_join(res);
5447db96d56Sopenharmony_ci            if (!tmp)
5457db96d56Sopenharmony_ci                return NULL;
5467db96d56Sopenharmony_ci            self->text = tmp;
5477db96d56Sopenharmony_ci            Py_DECREF(res);
5487db96d56Sopenharmony_ci            res = tmp;
5497db96d56Sopenharmony_ci        }
5507db96d56Sopenharmony_ci    }
5517db96d56Sopenharmony_ci
5527db96d56Sopenharmony_ci    return res;
5537db96d56Sopenharmony_ci}
5547db96d56Sopenharmony_ci
5557db96d56Sopenharmony_ciLOCAL(PyObject*)
5567db96d56Sopenharmony_cielement_get_tail(ElementObject* self)
5577db96d56Sopenharmony_ci{
5587db96d56Sopenharmony_ci    /* return borrowed reference to text attribute */
5597db96d56Sopenharmony_ci
5607db96d56Sopenharmony_ci    PyObject *res = self->tail;
5617db96d56Sopenharmony_ci
5627db96d56Sopenharmony_ci    if (JOIN_GET(res)) {
5637db96d56Sopenharmony_ci        res = JOIN_OBJ(res);
5647db96d56Sopenharmony_ci        if (PyList_CheckExact(res)) {
5657db96d56Sopenharmony_ci            PyObject *tmp = list_join(res);
5667db96d56Sopenharmony_ci            if (!tmp)
5677db96d56Sopenharmony_ci                return NULL;
5687db96d56Sopenharmony_ci            self->tail = tmp;
5697db96d56Sopenharmony_ci            Py_DECREF(res);
5707db96d56Sopenharmony_ci            res = tmp;
5717db96d56Sopenharmony_ci        }
5727db96d56Sopenharmony_ci    }
5737db96d56Sopenharmony_ci
5747db96d56Sopenharmony_ci    return res;
5757db96d56Sopenharmony_ci}
5767db96d56Sopenharmony_ci
5777db96d56Sopenharmony_cistatic PyObject*
5787db96d56Sopenharmony_cisubelement(PyObject *self, PyObject *args, PyObject *kwds)
5797db96d56Sopenharmony_ci{
5807db96d56Sopenharmony_ci    PyObject* elem;
5817db96d56Sopenharmony_ci
5827db96d56Sopenharmony_ci    ElementObject* parent;
5837db96d56Sopenharmony_ci    PyObject* tag;
5847db96d56Sopenharmony_ci    PyObject* attrib = NULL;
5857db96d56Sopenharmony_ci    if (!PyArg_ParseTuple(args, "O!O|O!:SubElement",
5867db96d56Sopenharmony_ci                          &Element_Type, &parent, &tag,
5877db96d56Sopenharmony_ci                          &PyDict_Type, &attrib)) {
5887db96d56Sopenharmony_ci        return NULL;
5897db96d56Sopenharmony_ci    }
5907db96d56Sopenharmony_ci
5917db96d56Sopenharmony_ci    if (attrib) {
5927db96d56Sopenharmony_ci        /* attrib passed as positional arg */
5937db96d56Sopenharmony_ci        attrib = PyDict_Copy(attrib);
5947db96d56Sopenharmony_ci        if (!attrib)
5957db96d56Sopenharmony_ci            return NULL;
5967db96d56Sopenharmony_ci        if (kwds != NULL && PyDict_Update(attrib, kwds) < 0) {
5977db96d56Sopenharmony_ci            Py_DECREF(attrib);
5987db96d56Sopenharmony_ci            return NULL;
5997db96d56Sopenharmony_ci        }
6007db96d56Sopenharmony_ci    } else if (kwds) {
6017db96d56Sopenharmony_ci        /* have keyword args */
6027db96d56Sopenharmony_ci        attrib = get_attrib_from_keywords(kwds);
6037db96d56Sopenharmony_ci        if (!attrib)
6047db96d56Sopenharmony_ci            return NULL;
6057db96d56Sopenharmony_ci    } else {
6067db96d56Sopenharmony_ci        /* no attrib arg, no kwds, so no attribute */
6077db96d56Sopenharmony_ci    }
6087db96d56Sopenharmony_ci
6097db96d56Sopenharmony_ci    elem = create_new_element(tag, attrib);
6107db96d56Sopenharmony_ci    Py_XDECREF(attrib);
6117db96d56Sopenharmony_ci    if (elem == NULL)
6127db96d56Sopenharmony_ci        return NULL;
6137db96d56Sopenharmony_ci
6147db96d56Sopenharmony_ci    if (element_add_subelement(parent, elem) < 0) {
6157db96d56Sopenharmony_ci        Py_DECREF(elem);
6167db96d56Sopenharmony_ci        return NULL;
6177db96d56Sopenharmony_ci    }
6187db96d56Sopenharmony_ci
6197db96d56Sopenharmony_ci    return elem;
6207db96d56Sopenharmony_ci}
6217db96d56Sopenharmony_ci
6227db96d56Sopenharmony_cistatic int
6237db96d56Sopenharmony_cielement_gc_traverse(ElementObject *self, visitproc visit, void *arg)
6247db96d56Sopenharmony_ci{
6257db96d56Sopenharmony_ci    Py_VISIT(self->tag);
6267db96d56Sopenharmony_ci    Py_VISIT(JOIN_OBJ(self->text));
6277db96d56Sopenharmony_ci    Py_VISIT(JOIN_OBJ(self->tail));
6287db96d56Sopenharmony_ci
6297db96d56Sopenharmony_ci    if (self->extra) {
6307db96d56Sopenharmony_ci        Py_ssize_t i;
6317db96d56Sopenharmony_ci        Py_VISIT(self->extra->attrib);
6327db96d56Sopenharmony_ci
6337db96d56Sopenharmony_ci        for (i = 0; i < self->extra->length; ++i)
6347db96d56Sopenharmony_ci            Py_VISIT(self->extra->children[i]);
6357db96d56Sopenharmony_ci    }
6367db96d56Sopenharmony_ci    return 0;
6377db96d56Sopenharmony_ci}
6387db96d56Sopenharmony_ci
6397db96d56Sopenharmony_cistatic int
6407db96d56Sopenharmony_cielement_gc_clear(ElementObject *self)
6417db96d56Sopenharmony_ci{
6427db96d56Sopenharmony_ci    Py_CLEAR(self->tag);
6437db96d56Sopenharmony_ci    _clear_joined_ptr(&self->text);
6447db96d56Sopenharmony_ci    _clear_joined_ptr(&self->tail);
6457db96d56Sopenharmony_ci
6467db96d56Sopenharmony_ci    /* After dropping all references from extra, it's no longer valid anyway,
6477db96d56Sopenharmony_ci     * so fully deallocate it.
6487db96d56Sopenharmony_ci    */
6497db96d56Sopenharmony_ci    clear_extra(self);
6507db96d56Sopenharmony_ci    return 0;
6517db96d56Sopenharmony_ci}
6527db96d56Sopenharmony_ci
6537db96d56Sopenharmony_cistatic void
6547db96d56Sopenharmony_cielement_dealloc(ElementObject* self)
6557db96d56Sopenharmony_ci{
6567db96d56Sopenharmony_ci    /* bpo-31095: UnTrack is needed before calling any callbacks */
6577db96d56Sopenharmony_ci    PyObject_GC_UnTrack(self);
6587db96d56Sopenharmony_ci    Py_TRASHCAN_BEGIN(self, element_dealloc)
6597db96d56Sopenharmony_ci
6607db96d56Sopenharmony_ci    if (self->weakreflist != NULL)
6617db96d56Sopenharmony_ci        PyObject_ClearWeakRefs((PyObject *) self);
6627db96d56Sopenharmony_ci
6637db96d56Sopenharmony_ci    /* element_gc_clear clears all references and deallocates extra
6647db96d56Sopenharmony_ci    */
6657db96d56Sopenharmony_ci    element_gc_clear(self);
6667db96d56Sopenharmony_ci
6677db96d56Sopenharmony_ci    Py_TYPE(self)->tp_free((PyObject *)self);
6687db96d56Sopenharmony_ci    Py_TRASHCAN_END
6697db96d56Sopenharmony_ci}
6707db96d56Sopenharmony_ci
6717db96d56Sopenharmony_ci/* -------------------------------------------------------------------- */
6727db96d56Sopenharmony_ci
6737db96d56Sopenharmony_ci/*[clinic input]
6747db96d56Sopenharmony_ci_elementtree.Element.append
6757db96d56Sopenharmony_ci
6767db96d56Sopenharmony_ci    subelement: object(subclass_of='&Element_Type')
6777db96d56Sopenharmony_ci    /
6787db96d56Sopenharmony_ci
6797db96d56Sopenharmony_ci[clinic start generated code]*/
6807db96d56Sopenharmony_ci
6817db96d56Sopenharmony_cistatic PyObject *
6827db96d56Sopenharmony_ci_elementtree_Element_append_impl(ElementObject *self, PyObject *subelement)
6837db96d56Sopenharmony_ci/*[clinic end generated code: output=54a884b7cf2295f4 input=3ed648beb5bfa22a]*/
6847db96d56Sopenharmony_ci{
6857db96d56Sopenharmony_ci    if (element_add_subelement(self, subelement) < 0)
6867db96d56Sopenharmony_ci        return NULL;
6877db96d56Sopenharmony_ci
6887db96d56Sopenharmony_ci    Py_RETURN_NONE;
6897db96d56Sopenharmony_ci}
6907db96d56Sopenharmony_ci
6917db96d56Sopenharmony_ci/*[clinic input]
6927db96d56Sopenharmony_ci_elementtree.Element.clear
6937db96d56Sopenharmony_ci
6947db96d56Sopenharmony_ci[clinic start generated code]*/
6957db96d56Sopenharmony_ci
6967db96d56Sopenharmony_cistatic PyObject *
6977db96d56Sopenharmony_ci_elementtree_Element_clear_impl(ElementObject *self)
6987db96d56Sopenharmony_ci/*[clinic end generated code: output=8bcd7a51f94cfff6 input=3c719ff94bf45dd6]*/
6997db96d56Sopenharmony_ci{
7007db96d56Sopenharmony_ci    clear_extra(self);
7017db96d56Sopenharmony_ci
7027db96d56Sopenharmony_ci    Py_INCREF(Py_None);
7037db96d56Sopenharmony_ci    _set_joined_ptr(&self->text, Py_None);
7047db96d56Sopenharmony_ci
7057db96d56Sopenharmony_ci    Py_INCREF(Py_None);
7067db96d56Sopenharmony_ci    _set_joined_ptr(&self->tail, Py_None);
7077db96d56Sopenharmony_ci
7087db96d56Sopenharmony_ci    Py_RETURN_NONE;
7097db96d56Sopenharmony_ci}
7107db96d56Sopenharmony_ci
7117db96d56Sopenharmony_ci/*[clinic input]
7127db96d56Sopenharmony_ci_elementtree.Element.__copy__
7137db96d56Sopenharmony_ci
7147db96d56Sopenharmony_ci[clinic start generated code]*/
7157db96d56Sopenharmony_ci
7167db96d56Sopenharmony_cistatic PyObject *
7177db96d56Sopenharmony_ci_elementtree_Element___copy___impl(ElementObject *self)
7187db96d56Sopenharmony_ci/*[clinic end generated code: output=2c701ebff7247781 input=ad87aaebe95675bf]*/
7197db96d56Sopenharmony_ci{
7207db96d56Sopenharmony_ci    Py_ssize_t i;
7217db96d56Sopenharmony_ci    ElementObject* element;
7227db96d56Sopenharmony_ci
7237db96d56Sopenharmony_ci    element = (ElementObject*) create_new_element(
7247db96d56Sopenharmony_ci        self->tag, self->extra ? self->extra->attrib : NULL);
7257db96d56Sopenharmony_ci    if (!element)
7267db96d56Sopenharmony_ci        return NULL;
7277db96d56Sopenharmony_ci
7287db96d56Sopenharmony_ci    Py_INCREF(JOIN_OBJ(self->text));
7297db96d56Sopenharmony_ci    _set_joined_ptr(&element->text, self->text);
7307db96d56Sopenharmony_ci
7317db96d56Sopenharmony_ci    Py_INCREF(JOIN_OBJ(self->tail));
7327db96d56Sopenharmony_ci    _set_joined_ptr(&element->tail, self->tail);
7337db96d56Sopenharmony_ci
7347db96d56Sopenharmony_ci    assert(!element->extra || !element->extra->length);
7357db96d56Sopenharmony_ci    if (self->extra) {
7367db96d56Sopenharmony_ci        if (element_resize(element, self->extra->length) < 0) {
7377db96d56Sopenharmony_ci            Py_DECREF(element);
7387db96d56Sopenharmony_ci            return NULL;
7397db96d56Sopenharmony_ci        }
7407db96d56Sopenharmony_ci
7417db96d56Sopenharmony_ci        for (i = 0; i < self->extra->length; i++) {
7427db96d56Sopenharmony_ci            Py_INCREF(self->extra->children[i]);
7437db96d56Sopenharmony_ci            element->extra->children[i] = self->extra->children[i];
7447db96d56Sopenharmony_ci        }
7457db96d56Sopenharmony_ci
7467db96d56Sopenharmony_ci        assert(!element->extra->length);
7477db96d56Sopenharmony_ci        element->extra->length = self->extra->length;
7487db96d56Sopenharmony_ci    }
7497db96d56Sopenharmony_ci
7507db96d56Sopenharmony_ci    return (PyObject*) element;
7517db96d56Sopenharmony_ci}
7527db96d56Sopenharmony_ci
7537db96d56Sopenharmony_ci/* Helper for a deep copy. */
7547db96d56Sopenharmony_ciLOCAL(PyObject *) deepcopy(PyObject *, PyObject *);
7557db96d56Sopenharmony_ci
7567db96d56Sopenharmony_ci/*[clinic input]
7577db96d56Sopenharmony_ci_elementtree.Element.__deepcopy__
7587db96d56Sopenharmony_ci
7597db96d56Sopenharmony_ci    memo: object(subclass_of="&PyDict_Type")
7607db96d56Sopenharmony_ci    /
7617db96d56Sopenharmony_ci
7627db96d56Sopenharmony_ci[clinic start generated code]*/
7637db96d56Sopenharmony_ci
7647db96d56Sopenharmony_cistatic PyObject *
7657db96d56Sopenharmony_ci_elementtree_Element___deepcopy___impl(ElementObject *self, PyObject *memo)
7667db96d56Sopenharmony_ci/*[clinic end generated code: output=eefc3df50465b642 input=a2d40348c0aade10]*/
7677db96d56Sopenharmony_ci{
7687db96d56Sopenharmony_ci    Py_ssize_t i;
7697db96d56Sopenharmony_ci    ElementObject* element;
7707db96d56Sopenharmony_ci    PyObject* tag;
7717db96d56Sopenharmony_ci    PyObject* attrib;
7727db96d56Sopenharmony_ci    PyObject* text;
7737db96d56Sopenharmony_ci    PyObject* tail;
7747db96d56Sopenharmony_ci    PyObject* id;
7757db96d56Sopenharmony_ci
7767db96d56Sopenharmony_ci    tag = deepcopy(self->tag, memo);
7777db96d56Sopenharmony_ci    if (!tag)
7787db96d56Sopenharmony_ci        return NULL;
7797db96d56Sopenharmony_ci
7807db96d56Sopenharmony_ci    if (self->extra && self->extra->attrib) {
7817db96d56Sopenharmony_ci        attrib = deepcopy(self->extra->attrib, memo);
7827db96d56Sopenharmony_ci        if (!attrib) {
7837db96d56Sopenharmony_ci            Py_DECREF(tag);
7847db96d56Sopenharmony_ci            return NULL;
7857db96d56Sopenharmony_ci        }
7867db96d56Sopenharmony_ci    } else {
7877db96d56Sopenharmony_ci        attrib = NULL;
7887db96d56Sopenharmony_ci    }
7897db96d56Sopenharmony_ci
7907db96d56Sopenharmony_ci    element = (ElementObject*) create_new_element(tag, attrib);
7917db96d56Sopenharmony_ci
7927db96d56Sopenharmony_ci    Py_DECREF(tag);
7937db96d56Sopenharmony_ci    Py_XDECREF(attrib);
7947db96d56Sopenharmony_ci
7957db96d56Sopenharmony_ci    if (!element)
7967db96d56Sopenharmony_ci        return NULL;
7977db96d56Sopenharmony_ci
7987db96d56Sopenharmony_ci    text = deepcopy(JOIN_OBJ(self->text), memo);
7997db96d56Sopenharmony_ci    if (!text)
8007db96d56Sopenharmony_ci        goto error;
8017db96d56Sopenharmony_ci    _set_joined_ptr(&element->text, JOIN_SET(text, JOIN_GET(self->text)));
8027db96d56Sopenharmony_ci
8037db96d56Sopenharmony_ci    tail = deepcopy(JOIN_OBJ(self->tail), memo);
8047db96d56Sopenharmony_ci    if (!tail)
8057db96d56Sopenharmony_ci        goto error;
8067db96d56Sopenharmony_ci    _set_joined_ptr(&element->tail, JOIN_SET(tail, JOIN_GET(self->tail)));
8077db96d56Sopenharmony_ci
8087db96d56Sopenharmony_ci    assert(!element->extra || !element->extra->length);
8097db96d56Sopenharmony_ci    if (self->extra) {
8107db96d56Sopenharmony_ci        if (element_resize(element, self->extra->length) < 0)
8117db96d56Sopenharmony_ci            goto error;
8127db96d56Sopenharmony_ci
8137db96d56Sopenharmony_ci        for (i = 0; i < self->extra->length; i++) {
8147db96d56Sopenharmony_ci            PyObject* child = deepcopy(self->extra->children[i], memo);
8157db96d56Sopenharmony_ci            if (!child || !Element_Check(child)) {
8167db96d56Sopenharmony_ci                if (child) {
8177db96d56Sopenharmony_ci                    raise_type_error(child);
8187db96d56Sopenharmony_ci                    Py_DECREF(child);
8197db96d56Sopenharmony_ci                }
8207db96d56Sopenharmony_ci                element->extra->length = i;
8217db96d56Sopenharmony_ci                goto error;
8227db96d56Sopenharmony_ci            }
8237db96d56Sopenharmony_ci            element->extra->children[i] = child;
8247db96d56Sopenharmony_ci        }
8257db96d56Sopenharmony_ci
8267db96d56Sopenharmony_ci        assert(!element->extra->length);
8277db96d56Sopenharmony_ci        element->extra->length = self->extra->length;
8287db96d56Sopenharmony_ci    }
8297db96d56Sopenharmony_ci
8307db96d56Sopenharmony_ci    /* add object to memo dictionary (so deepcopy won't visit it again) */
8317db96d56Sopenharmony_ci    id = PyLong_FromSsize_t((uintptr_t) self);
8327db96d56Sopenharmony_ci    if (!id)
8337db96d56Sopenharmony_ci        goto error;
8347db96d56Sopenharmony_ci
8357db96d56Sopenharmony_ci    i = PyDict_SetItem(memo, id, (PyObject*) element);
8367db96d56Sopenharmony_ci
8377db96d56Sopenharmony_ci    Py_DECREF(id);
8387db96d56Sopenharmony_ci
8397db96d56Sopenharmony_ci    if (i < 0)
8407db96d56Sopenharmony_ci        goto error;
8417db96d56Sopenharmony_ci
8427db96d56Sopenharmony_ci    return (PyObject*) element;
8437db96d56Sopenharmony_ci
8447db96d56Sopenharmony_ci  error:
8457db96d56Sopenharmony_ci    Py_DECREF(element);
8467db96d56Sopenharmony_ci    return NULL;
8477db96d56Sopenharmony_ci}
8487db96d56Sopenharmony_ci
8497db96d56Sopenharmony_ciLOCAL(PyObject *)
8507db96d56Sopenharmony_cideepcopy(PyObject *object, PyObject *memo)
8517db96d56Sopenharmony_ci{
8527db96d56Sopenharmony_ci    /* do a deep copy of the given object */
8537db96d56Sopenharmony_ci    elementtreestate *st;
8547db96d56Sopenharmony_ci    PyObject *stack[2];
8557db96d56Sopenharmony_ci
8567db96d56Sopenharmony_ci    /* Fast paths */
8577db96d56Sopenharmony_ci    if (object == Py_None || PyUnicode_CheckExact(object)) {
8587db96d56Sopenharmony_ci        Py_INCREF(object);
8597db96d56Sopenharmony_ci        return object;
8607db96d56Sopenharmony_ci    }
8617db96d56Sopenharmony_ci
8627db96d56Sopenharmony_ci    if (Py_REFCNT(object) == 1) {
8637db96d56Sopenharmony_ci        if (PyDict_CheckExact(object)) {
8647db96d56Sopenharmony_ci            PyObject *key, *value;
8657db96d56Sopenharmony_ci            Py_ssize_t pos = 0;
8667db96d56Sopenharmony_ci            int simple = 1;
8677db96d56Sopenharmony_ci            while (PyDict_Next(object, &pos, &key, &value)) {
8687db96d56Sopenharmony_ci                if (!PyUnicode_CheckExact(key) || !PyUnicode_CheckExact(value)) {
8697db96d56Sopenharmony_ci                    simple = 0;
8707db96d56Sopenharmony_ci                    break;
8717db96d56Sopenharmony_ci                }
8727db96d56Sopenharmony_ci            }
8737db96d56Sopenharmony_ci            if (simple)
8747db96d56Sopenharmony_ci                return PyDict_Copy(object);
8757db96d56Sopenharmony_ci            /* Fall through to general case */
8767db96d56Sopenharmony_ci        }
8777db96d56Sopenharmony_ci        else if (Element_CheckExact(object)) {
8787db96d56Sopenharmony_ci            return _elementtree_Element___deepcopy___impl(
8797db96d56Sopenharmony_ci                (ElementObject *)object, memo);
8807db96d56Sopenharmony_ci        }
8817db96d56Sopenharmony_ci    }
8827db96d56Sopenharmony_ci
8837db96d56Sopenharmony_ci    /* General case */
8847db96d56Sopenharmony_ci    st = ET_STATE_GLOBAL;
8857db96d56Sopenharmony_ci    if (!st->deepcopy_obj) {
8867db96d56Sopenharmony_ci        PyErr_SetString(PyExc_RuntimeError,
8877db96d56Sopenharmony_ci                        "deepcopy helper not found");
8887db96d56Sopenharmony_ci        return NULL;
8897db96d56Sopenharmony_ci    }
8907db96d56Sopenharmony_ci
8917db96d56Sopenharmony_ci    stack[0] = object;
8927db96d56Sopenharmony_ci    stack[1] = memo;
8937db96d56Sopenharmony_ci    return _PyObject_FastCall(st->deepcopy_obj, stack, 2);
8947db96d56Sopenharmony_ci}
8957db96d56Sopenharmony_ci
8967db96d56Sopenharmony_ci
8977db96d56Sopenharmony_ci/*[clinic input]
8987db96d56Sopenharmony_ci_elementtree.Element.__sizeof__ -> Py_ssize_t
8997db96d56Sopenharmony_ci
9007db96d56Sopenharmony_ci[clinic start generated code]*/
9017db96d56Sopenharmony_ci
9027db96d56Sopenharmony_cistatic Py_ssize_t
9037db96d56Sopenharmony_ci_elementtree_Element___sizeof___impl(ElementObject *self)
9047db96d56Sopenharmony_ci/*[clinic end generated code: output=bf73867721008000 input=70f4b323d55a17c1]*/
9057db96d56Sopenharmony_ci{
9067db96d56Sopenharmony_ci    Py_ssize_t result = _PyObject_SIZE(Py_TYPE(self));
9077db96d56Sopenharmony_ci    if (self->extra) {
9087db96d56Sopenharmony_ci        result += sizeof(ElementObjectExtra);
9097db96d56Sopenharmony_ci        if (self->extra->children != self->extra->_children)
9107db96d56Sopenharmony_ci            result += sizeof(PyObject*) * self->extra->allocated;
9117db96d56Sopenharmony_ci    }
9127db96d56Sopenharmony_ci    return result;
9137db96d56Sopenharmony_ci}
9147db96d56Sopenharmony_ci
9157db96d56Sopenharmony_ci/* dict keys for getstate/setstate. */
9167db96d56Sopenharmony_ci#define PICKLED_TAG "tag"
9177db96d56Sopenharmony_ci#define PICKLED_CHILDREN "_children"
9187db96d56Sopenharmony_ci#define PICKLED_ATTRIB "attrib"
9197db96d56Sopenharmony_ci#define PICKLED_TAIL "tail"
9207db96d56Sopenharmony_ci#define PICKLED_TEXT "text"
9217db96d56Sopenharmony_ci
9227db96d56Sopenharmony_ci/* __getstate__ returns a fabricated instance dict as in the pure-Python
9237db96d56Sopenharmony_ci * Element implementation, for interoperability/interchangeability.  This
9247db96d56Sopenharmony_ci * makes the pure-Python implementation details an API, but (a) there aren't
9257db96d56Sopenharmony_ci * any unnecessary structures there; and (b) it buys compatibility with 3.2
9267db96d56Sopenharmony_ci * pickles.  See issue #16076.
9277db96d56Sopenharmony_ci */
9287db96d56Sopenharmony_ci/*[clinic input]
9297db96d56Sopenharmony_ci_elementtree.Element.__getstate__
9307db96d56Sopenharmony_ci
9317db96d56Sopenharmony_ci[clinic start generated code]*/
9327db96d56Sopenharmony_ci
9337db96d56Sopenharmony_cistatic PyObject *
9347db96d56Sopenharmony_ci_elementtree_Element___getstate___impl(ElementObject *self)
9357db96d56Sopenharmony_ci/*[clinic end generated code: output=37279aeeb6bb5b04 input=f0d16d7ec2f7adc1]*/
9367db96d56Sopenharmony_ci{
9377db96d56Sopenharmony_ci    Py_ssize_t i;
9387db96d56Sopenharmony_ci    PyObject *children, *attrib;
9397db96d56Sopenharmony_ci
9407db96d56Sopenharmony_ci    /* Build a list of children. */
9417db96d56Sopenharmony_ci    children = PyList_New(self->extra ? self->extra->length : 0);
9427db96d56Sopenharmony_ci    if (!children)
9437db96d56Sopenharmony_ci        return NULL;
9447db96d56Sopenharmony_ci    for (i = 0; i < PyList_GET_SIZE(children); i++) {
9457db96d56Sopenharmony_ci        PyObject *child = self->extra->children[i];
9467db96d56Sopenharmony_ci        Py_INCREF(child);
9477db96d56Sopenharmony_ci        PyList_SET_ITEM(children, i, child);
9487db96d56Sopenharmony_ci    }
9497db96d56Sopenharmony_ci
9507db96d56Sopenharmony_ci    if (self->extra && self->extra->attrib) {
9517db96d56Sopenharmony_ci        attrib = self->extra->attrib;
9527db96d56Sopenharmony_ci        Py_INCREF(attrib);
9537db96d56Sopenharmony_ci    }
9547db96d56Sopenharmony_ci    else {
9557db96d56Sopenharmony_ci        attrib = PyDict_New();
9567db96d56Sopenharmony_ci        if (!attrib) {
9577db96d56Sopenharmony_ci            Py_DECREF(children);
9587db96d56Sopenharmony_ci            return NULL;
9597db96d56Sopenharmony_ci        }
9607db96d56Sopenharmony_ci    }
9617db96d56Sopenharmony_ci
9627db96d56Sopenharmony_ci    return Py_BuildValue("{sOsNsNsOsO}",
9637db96d56Sopenharmony_ci                         PICKLED_TAG, self->tag,
9647db96d56Sopenharmony_ci                         PICKLED_CHILDREN, children,
9657db96d56Sopenharmony_ci                         PICKLED_ATTRIB, attrib,
9667db96d56Sopenharmony_ci                         PICKLED_TEXT, JOIN_OBJ(self->text),
9677db96d56Sopenharmony_ci                         PICKLED_TAIL, JOIN_OBJ(self->tail));
9687db96d56Sopenharmony_ci}
9697db96d56Sopenharmony_ci
9707db96d56Sopenharmony_cistatic PyObject *
9717db96d56Sopenharmony_cielement_setstate_from_attributes(ElementObject *self,
9727db96d56Sopenharmony_ci                                 PyObject *tag,
9737db96d56Sopenharmony_ci                                 PyObject *attrib,
9747db96d56Sopenharmony_ci                                 PyObject *text,
9757db96d56Sopenharmony_ci                                 PyObject *tail,
9767db96d56Sopenharmony_ci                                 PyObject *children)
9777db96d56Sopenharmony_ci{
9787db96d56Sopenharmony_ci    Py_ssize_t i, nchildren;
9797db96d56Sopenharmony_ci    ElementObjectExtra *oldextra = NULL;
9807db96d56Sopenharmony_ci
9817db96d56Sopenharmony_ci    if (!tag) {
9827db96d56Sopenharmony_ci        PyErr_SetString(PyExc_TypeError, "tag may not be NULL");
9837db96d56Sopenharmony_ci        return NULL;
9847db96d56Sopenharmony_ci    }
9857db96d56Sopenharmony_ci
9867db96d56Sopenharmony_ci    Py_INCREF(tag);
9877db96d56Sopenharmony_ci    Py_XSETREF(self->tag, tag);
9887db96d56Sopenharmony_ci
9897db96d56Sopenharmony_ci    text = text ? JOIN_SET(text, PyList_CheckExact(text)) : Py_None;
9907db96d56Sopenharmony_ci    Py_INCREF(JOIN_OBJ(text));
9917db96d56Sopenharmony_ci    _set_joined_ptr(&self->text, text);
9927db96d56Sopenharmony_ci
9937db96d56Sopenharmony_ci    tail = tail ? JOIN_SET(tail, PyList_CheckExact(tail)) : Py_None;
9947db96d56Sopenharmony_ci    Py_INCREF(JOIN_OBJ(tail));
9957db96d56Sopenharmony_ci    _set_joined_ptr(&self->tail, tail);
9967db96d56Sopenharmony_ci
9977db96d56Sopenharmony_ci    /* Handle ATTRIB and CHILDREN. */
9987db96d56Sopenharmony_ci    if (!children && !attrib) {
9997db96d56Sopenharmony_ci        Py_RETURN_NONE;
10007db96d56Sopenharmony_ci    }
10017db96d56Sopenharmony_ci
10027db96d56Sopenharmony_ci    /* Compute 'nchildren'. */
10037db96d56Sopenharmony_ci    if (children) {
10047db96d56Sopenharmony_ci        if (!PyList_Check(children)) {
10057db96d56Sopenharmony_ci            PyErr_SetString(PyExc_TypeError, "'_children' is not a list");
10067db96d56Sopenharmony_ci            return NULL;
10077db96d56Sopenharmony_ci        }
10087db96d56Sopenharmony_ci        nchildren = PyList_GET_SIZE(children);
10097db96d56Sopenharmony_ci
10107db96d56Sopenharmony_ci        /* (Re-)allocate 'extra'.
10117db96d56Sopenharmony_ci           Avoid DECREFs calling into this code again (cycles, etc.)
10127db96d56Sopenharmony_ci         */
10137db96d56Sopenharmony_ci        oldextra = self->extra;
10147db96d56Sopenharmony_ci        self->extra = NULL;
10157db96d56Sopenharmony_ci        if (element_resize(self, nchildren)) {
10167db96d56Sopenharmony_ci            assert(!self->extra || !self->extra->length);
10177db96d56Sopenharmony_ci            clear_extra(self);
10187db96d56Sopenharmony_ci            self->extra = oldextra;
10197db96d56Sopenharmony_ci            return NULL;
10207db96d56Sopenharmony_ci        }
10217db96d56Sopenharmony_ci        assert(self->extra);
10227db96d56Sopenharmony_ci        assert(self->extra->allocated >= nchildren);
10237db96d56Sopenharmony_ci        if (oldextra) {
10247db96d56Sopenharmony_ci            assert(self->extra->attrib == NULL);
10257db96d56Sopenharmony_ci            self->extra->attrib = oldextra->attrib;
10267db96d56Sopenharmony_ci            oldextra->attrib = NULL;
10277db96d56Sopenharmony_ci        }
10287db96d56Sopenharmony_ci
10297db96d56Sopenharmony_ci        /* Copy children */
10307db96d56Sopenharmony_ci        for (i = 0; i < nchildren; i++) {
10317db96d56Sopenharmony_ci            PyObject *child = PyList_GET_ITEM(children, i);
10327db96d56Sopenharmony_ci            if (!Element_Check(child)) {
10337db96d56Sopenharmony_ci                raise_type_error(child);
10347db96d56Sopenharmony_ci                self->extra->length = i;
10357db96d56Sopenharmony_ci                dealloc_extra(oldextra);
10367db96d56Sopenharmony_ci                return NULL;
10377db96d56Sopenharmony_ci            }
10387db96d56Sopenharmony_ci            Py_INCREF(child);
10397db96d56Sopenharmony_ci            self->extra->children[i] = child;
10407db96d56Sopenharmony_ci        }
10417db96d56Sopenharmony_ci
10427db96d56Sopenharmony_ci        assert(!self->extra->length);
10437db96d56Sopenharmony_ci        self->extra->length = nchildren;
10447db96d56Sopenharmony_ci    }
10457db96d56Sopenharmony_ci    else {
10467db96d56Sopenharmony_ci        if (element_resize(self, 0)) {
10477db96d56Sopenharmony_ci            return NULL;
10487db96d56Sopenharmony_ci        }
10497db96d56Sopenharmony_ci    }
10507db96d56Sopenharmony_ci
10517db96d56Sopenharmony_ci    /* Stash attrib. */
10527db96d56Sopenharmony_ci    Py_XINCREF(attrib);
10537db96d56Sopenharmony_ci    Py_XSETREF(self->extra->attrib, attrib);
10547db96d56Sopenharmony_ci    dealloc_extra(oldextra);
10557db96d56Sopenharmony_ci
10567db96d56Sopenharmony_ci    Py_RETURN_NONE;
10577db96d56Sopenharmony_ci}
10587db96d56Sopenharmony_ci
10597db96d56Sopenharmony_ci/* __setstate__ for Element instance from the Python implementation.
10607db96d56Sopenharmony_ci * 'state' should be the instance dict.
10617db96d56Sopenharmony_ci */
10627db96d56Sopenharmony_ci
10637db96d56Sopenharmony_cistatic PyObject *
10647db96d56Sopenharmony_cielement_setstate_from_Python(ElementObject *self, PyObject *state)
10657db96d56Sopenharmony_ci{
10667db96d56Sopenharmony_ci    static char *kwlist[] = {PICKLED_TAG, PICKLED_ATTRIB, PICKLED_TEXT,
10677db96d56Sopenharmony_ci                             PICKLED_TAIL, PICKLED_CHILDREN, 0};
10687db96d56Sopenharmony_ci    PyObject *args;
10697db96d56Sopenharmony_ci    PyObject *tag, *attrib, *text, *tail, *children;
10707db96d56Sopenharmony_ci    PyObject *retval;
10717db96d56Sopenharmony_ci
10727db96d56Sopenharmony_ci    tag = attrib = text = tail = children = NULL;
10737db96d56Sopenharmony_ci    args = PyTuple_New(0);
10747db96d56Sopenharmony_ci    if (!args)
10757db96d56Sopenharmony_ci        return NULL;
10767db96d56Sopenharmony_ci
10777db96d56Sopenharmony_ci    if (PyArg_ParseTupleAndKeywords(args, state, "|$OOOOO", kwlist, &tag,
10787db96d56Sopenharmony_ci                                    &attrib, &text, &tail, &children))
10797db96d56Sopenharmony_ci        retval = element_setstate_from_attributes(self, tag, attrib, text,
10807db96d56Sopenharmony_ci                                                  tail, children);
10817db96d56Sopenharmony_ci    else
10827db96d56Sopenharmony_ci        retval = NULL;
10837db96d56Sopenharmony_ci
10847db96d56Sopenharmony_ci    Py_DECREF(args);
10857db96d56Sopenharmony_ci    return retval;
10867db96d56Sopenharmony_ci}
10877db96d56Sopenharmony_ci
10887db96d56Sopenharmony_ci/*[clinic input]
10897db96d56Sopenharmony_ci_elementtree.Element.__setstate__
10907db96d56Sopenharmony_ci
10917db96d56Sopenharmony_ci    state: object
10927db96d56Sopenharmony_ci    /
10937db96d56Sopenharmony_ci
10947db96d56Sopenharmony_ci[clinic start generated code]*/
10957db96d56Sopenharmony_ci
10967db96d56Sopenharmony_cistatic PyObject *
10977db96d56Sopenharmony_ci_elementtree_Element___setstate__(ElementObject *self, PyObject *state)
10987db96d56Sopenharmony_ci/*[clinic end generated code: output=ea28bf3491b1f75e input=aaf80abea7c1e3b9]*/
10997db96d56Sopenharmony_ci{
11007db96d56Sopenharmony_ci    if (!PyDict_CheckExact(state)) {
11017db96d56Sopenharmony_ci        PyErr_Format(PyExc_TypeError,
11027db96d56Sopenharmony_ci                     "Don't know how to unpickle \"%.200R\" as an Element",
11037db96d56Sopenharmony_ci                     state);
11047db96d56Sopenharmony_ci        return NULL;
11057db96d56Sopenharmony_ci    }
11067db96d56Sopenharmony_ci    else
11077db96d56Sopenharmony_ci        return element_setstate_from_Python(self, state);
11087db96d56Sopenharmony_ci}
11097db96d56Sopenharmony_ci
11107db96d56Sopenharmony_ciLOCAL(int)
11117db96d56Sopenharmony_cicheckpath(PyObject* tag)
11127db96d56Sopenharmony_ci{
11137db96d56Sopenharmony_ci    Py_ssize_t i;
11147db96d56Sopenharmony_ci    int check = 1;
11157db96d56Sopenharmony_ci
11167db96d56Sopenharmony_ci    /* check if a tag contains an xpath character */
11177db96d56Sopenharmony_ci
11187db96d56Sopenharmony_ci#define PATHCHAR(ch) \
11197db96d56Sopenharmony_ci    (ch == '/' || ch == '*' || ch == '[' || ch == '@' || ch == '.')
11207db96d56Sopenharmony_ci
11217db96d56Sopenharmony_ci    if (PyUnicode_Check(tag)) {
11227db96d56Sopenharmony_ci        const Py_ssize_t len = PyUnicode_GET_LENGTH(tag);
11237db96d56Sopenharmony_ci        const void *data = PyUnicode_DATA(tag);
11247db96d56Sopenharmony_ci        unsigned int kind = PyUnicode_KIND(tag);
11257db96d56Sopenharmony_ci        if (len >= 3 && PyUnicode_READ(kind, data, 0) == '{' && (
11267db96d56Sopenharmony_ci                PyUnicode_READ(kind, data, 1) == '}' || (
11277db96d56Sopenharmony_ci                PyUnicode_READ(kind, data, 1) == '*' &&
11287db96d56Sopenharmony_ci                PyUnicode_READ(kind, data, 2) == '}'))) {
11297db96d56Sopenharmony_ci            /* wildcard: '{}tag' or '{*}tag' */
11307db96d56Sopenharmony_ci            return 1;
11317db96d56Sopenharmony_ci        }
11327db96d56Sopenharmony_ci        for (i = 0; i < len; i++) {
11337db96d56Sopenharmony_ci            Py_UCS4 ch = PyUnicode_READ(kind, data, i);
11347db96d56Sopenharmony_ci            if (ch == '{')
11357db96d56Sopenharmony_ci                check = 0;
11367db96d56Sopenharmony_ci            else if (ch == '}')
11377db96d56Sopenharmony_ci                check = 1;
11387db96d56Sopenharmony_ci            else if (check && PATHCHAR(ch))
11397db96d56Sopenharmony_ci                return 1;
11407db96d56Sopenharmony_ci        }
11417db96d56Sopenharmony_ci        return 0;
11427db96d56Sopenharmony_ci    }
11437db96d56Sopenharmony_ci    if (PyBytes_Check(tag)) {
11447db96d56Sopenharmony_ci        const char *p = PyBytes_AS_STRING(tag);
11457db96d56Sopenharmony_ci        const Py_ssize_t len = PyBytes_GET_SIZE(tag);
11467db96d56Sopenharmony_ci        if (len >= 3 && p[0] == '{' && (
11477db96d56Sopenharmony_ci                p[1] == '}' || (p[1] == '*' && p[2] == '}'))) {
11487db96d56Sopenharmony_ci            /* wildcard: '{}tag' or '{*}tag' */
11497db96d56Sopenharmony_ci            return 1;
11507db96d56Sopenharmony_ci        }
11517db96d56Sopenharmony_ci        for (i = 0; i < len; i++) {
11527db96d56Sopenharmony_ci            if (p[i] == '{')
11537db96d56Sopenharmony_ci                check = 0;
11547db96d56Sopenharmony_ci            else if (p[i] == '}')
11557db96d56Sopenharmony_ci                check = 1;
11567db96d56Sopenharmony_ci            else if (check && PATHCHAR(p[i]))
11577db96d56Sopenharmony_ci                return 1;
11587db96d56Sopenharmony_ci        }
11597db96d56Sopenharmony_ci        return 0;
11607db96d56Sopenharmony_ci    }
11617db96d56Sopenharmony_ci
11627db96d56Sopenharmony_ci    return 1; /* unknown type; might be path expression */
11637db96d56Sopenharmony_ci}
11647db96d56Sopenharmony_ci
11657db96d56Sopenharmony_ci/*[clinic input]
11667db96d56Sopenharmony_ci_elementtree.Element.extend
11677db96d56Sopenharmony_ci
11687db96d56Sopenharmony_ci    elements: object
11697db96d56Sopenharmony_ci    /
11707db96d56Sopenharmony_ci
11717db96d56Sopenharmony_ci[clinic start generated code]*/
11727db96d56Sopenharmony_ci
11737db96d56Sopenharmony_cistatic PyObject *
11747db96d56Sopenharmony_ci_elementtree_Element_extend(ElementObject *self, PyObject *elements)
11757db96d56Sopenharmony_ci/*[clinic end generated code: output=f6e67fc2ff529191 input=807bc4f31c69f7c0]*/
11767db96d56Sopenharmony_ci{
11777db96d56Sopenharmony_ci    PyObject* seq;
11787db96d56Sopenharmony_ci    Py_ssize_t i;
11797db96d56Sopenharmony_ci
11807db96d56Sopenharmony_ci    seq = PySequence_Fast(elements, "");
11817db96d56Sopenharmony_ci    if (!seq) {
11827db96d56Sopenharmony_ci        PyErr_Format(
11837db96d56Sopenharmony_ci            PyExc_TypeError,
11847db96d56Sopenharmony_ci            "expected sequence, not \"%.200s\"", Py_TYPE(elements)->tp_name
11857db96d56Sopenharmony_ci            );
11867db96d56Sopenharmony_ci        return NULL;
11877db96d56Sopenharmony_ci    }
11887db96d56Sopenharmony_ci
11897db96d56Sopenharmony_ci    for (i = 0; i < PySequence_Fast_GET_SIZE(seq); i++) {
11907db96d56Sopenharmony_ci        PyObject* element = PySequence_Fast_GET_ITEM(seq, i);
11917db96d56Sopenharmony_ci        Py_INCREF(element);
11927db96d56Sopenharmony_ci        if (element_add_subelement(self, element) < 0) {
11937db96d56Sopenharmony_ci            Py_DECREF(seq);
11947db96d56Sopenharmony_ci            Py_DECREF(element);
11957db96d56Sopenharmony_ci            return NULL;
11967db96d56Sopenharmony_ci        }
11977db96d56Sopenharmony_ci        Py_DECREF(element);
11987db96d56Sopenharmony_ci    }
11997db96d56Sopenharmony_ci
12007db96d56Sopenharmony_ci    Py_DECREF(seq);
12017db96d56Sopenharmony_ci
12027db96d56Sopenharmony_ci    Py_RETURN_NONE;
12037db96d56Sopenharmony_ci}
12047db96d56Sopenharmony_ci
12057db96d56Sopenharmony_ci/*[clinic input]
12067db96d56Sopenharmony_ci_elementtree.Element.find
12077db96d56Sopenharmony_ci
12087db96d56Sopenharmony_ci    path: object
12097db96d56Sopenharmony_ci    namespaces: object = None
12107db96d56Sopenharmony_ci
12117db96d56Sopenharmony_ci[clinic start generated code]*/
12127db96d56Sopenharmony_ci
12137db96d56Sopenharmony_cistatic PyObject *
12147db96d56Sopenharmony_ci_elementtree_Element_find_impl(ElementObject *self, PyObject *path,
12157db96d56Sopenharmony_ci                               PyObject *namespaces)
12167db96d56Sopenharmony_ci/*[clinic end generated code: output=41b43f0f0becafae input=359b6985f6489d2e]*/
12177db96d56Sopenharmony_ci{
12187db96d56Sopenharmony_ci    Py_ssize_t i;
12197db96d56Sopenharmony_ci    elementtreestate *st = ET_STATE_GLOBAL;
12207db96d56Sopenharmony_ci
12217db96d56Sopenharmony_ci    if (checkpath(path) || namespaces != Py_None) {
12227db96d56Sopenharmony_ci        _Py_IDENTIFIER(find);
12237db96d56Sopenharmony_ci        return _PyObject_CallMethodIdObjArgs(
12247db96d56Sopenharmony_ci            st->elementpath_obj, &PyId_find, self, path, namespaces, NULL
12257db96d56Sopenharmony_ci            );
12267db96d56Sopenharmony_ci    }
12277db96d56Sopenharmony_ci
12287db96d56Sopenharmony_ci    if (!self->extra)
12297db96d56Sopenharmony_ci        Py_RETURN_NONE;
12307db96d56Sopenharmony_ci
12317db96d56Sopenharmony_ci    for (i = 0; i < self->extra->length; i++) {
12327db96d56Sopenharmony_ci        PyObject* item = self->extra->children[i];
12337db96d56Sopenharmony_ci        int rc;
12347db96d56Sopenharmony_ci        assert(Element_Check(item));
12357db96d56Sopenharmony_ci        Py_INCREF(item);
12367db96d56Sopenharmony_ci        rc = PyObject_RichCompareBool(((ElementObject*)item)->tag, path, Py_EQ);
12377db96d56Sopenharmony_ci        if (rc > 0)
12387db96d56Sopenharmony_ci            return item;
12397db96d56Sopenharmony_ci        Py_DECREF(item);
12407db96d56Sopenharmony_ci        if (rc < 0)
12417db96d56Sopenharmony_ci            return NULL;
12427db96d56Sopenharmony_ci    }
12437db96d56Sopenharmony_ci
12447db96d56Sopenharmony_ci    Py_RETURN_NONE;
12457db96d56Sopenharmony_ci}
12467db96d56Sopenharmony_ci
12477db96d56Sopenharmony_ci/*[clinic input]
12487db96d56Sopenharmony_ci_elementtree.Element.findtext
12497db96d56Sopenharmony_ci
12507db96d56Sopenharmony_ci    path: object
12517db96d56Sopenharmony_ci    default: object = None
12527db96d56Sopenharmony_ci    namespaces: object = None
12537db96d56Sopenharmony_ci
12547db96d56Sopenharmony_ci[clinic start generated code]*/
12557db96d56Sopenharmony_ci
12567db96d56Sopenharmony_cistatic PyObject *
12577db96d56Sopenharmony_ci_elementtree_Element_findtext_impl(ElementObject *self, PyObject *path,
12587db96d56Sopenharmony_ci                                   PyObject *default_value,
12597db96d56Sopenharmony_ci                                   PyObject *namespaces)
12607db96d56Sopenharmony_ci/*[clinic end generated code: output=83b3ba4535d308d2 input=b53a85aa5aa2a916]*/
12617db96d56Sopenharmony_ci{
12627db96d56Sopenharmony_ci    Py_ssize_t i;
12637db96d56Sopenharmony_ci    _Py_IDENTIFIER(findtext);
12647db96d56Sopenharmony_ci    elementtreestate *st = ET_STATE_GLOBAL;
12657db96d56Sopenharmony_ci
12667db96d56Sopenharmony_ci    if (checkpath(path) || namespaces != Py_None)
12677db96d56Sopenharmony_ci        return _PyObject_CallMethodIdObjArgs(
12687db96d56Sopenharmony_ci            st->elementpath_obj, &PyId_findtext,
12697db96d56Sopenharmony_ci            self, path, default_value, namespaces, NULL
12707db96d56Sopenharmony_ci            );
12717db96d56Sopenharmony_ci
12727db96d56Sopenharmony_ci    if (!self->extra) {
12737db96d56Sopenharmony_ci        Py_INCREF(default_value);
12747db96d56Sopenharmony_ci        return default_value;
12757db96d56Sopenharmony_ci    }
12767db96d56Sopenharmony_ci
12777db96d56Sopenharmony_ci    for (i = 0; i < self->extra->length; i++) {
12787db96d56Sopenharmony_ci        PyObject *item = self->extra->children[i];
12797db96d56Sopenharmony_ci        int rc;
12807db96d56Sopenharmony_ci        assert(Element_Check(item));
12817db96d56Sopenharmony_ci        Py_INCREF(item);
12827db96d56Sopenharmony_ci        rc = PyObject_RichCompareBool(((ElementObject*)item)->tag, path, Py_EQ);
12837db96d56Sopenharmony_ci        if (rc > 0) {
12847db96d56Sopenharmony_ci            PyObject* text = element_get_text((ElementObject*)item);
12857db96d56Sopenharmony_ci            if (text == Py_None) {
12867db96d56Sopenharmony_ci                Py_DECREF(item);
12877db96d56Sopenharmony_ci                return PyUnicode_New(0, 0);
12887db96d56Sopenharmony_ci            }
12897db96d56Sopenharmony_ci            Py_XINCREF(text);
12907db96d56Sopenharmony_ci            Py_DECREF(item);
12917db96d56Sopenharmony_ci            return text;
12927db96d56Sopenharmony_ci        }
12937db96d56Sopenharmony_ci        Py_DECREF(item);
12947db96d56Sopenharmony_ci        if (rc < 0)
12957db96d56Sopenharmony_ci            return NULL;
12967db96d56Sopenharmony_ci    }
12977db96d56Sopenharmony_ci
12987db96d56Sopenharmony_ci    Py_INCREF(default_value);
12997db96d56Sopenharmony_ci    return default_value;
13007db96d56Sopenharmony_ci}
13017db96d56Sopenharmony_ci
13027db96d56Sopenharmony_ci/*[clinic input]
13037db96d56Sopenharmony_ci_elementtree.Element.findall
13047db96d56Sopenharmony_ci
13057db96d56Sopenharmony_ci    path: object
13067db96d56Sopenharmony_ci    namespaces: object = None
13077db96d56Sopenharmony_ci
13087db96d56Sopenharmony_ci[clinic start generated code]*/
13097db96d56Sopenharmony_ci
13107db96d56Sopenharmony_cistatic PyObject *
13117db96d56Sopenharmony_ci_elementtree_Element_findall_impl(ElementObject *self, PyObject *path,
13127db96d56Sopenharmony_ci                                  PyObject *namespaces)
13137db96d56Sopenharmony_ci/*[clinic end generated code: output=1a0bd9f5541b711d input=4d9e6505a638550c]*/
13147db96d56Sopenharmony_ci{
13157db96d56Sopenharmony_ci    Py_ssize_t i;
13167db96d56Sopenharmony_ci    PyObject* out;
13177db96d56Sopenharmony_ci    elementtreestate *st = ET_STATE_GLOBAL;
13187db96d56Sopenharmony_ci
13197db96d56Sopenharmony_ci    if (checkpath(path) || namespaces != Py_None) {
13207db96d56Sopenharmony_ci        _Py_IDENTIFIER(findall);
13217db96d56Sopenharmony_ci        return _PyObject_CallMethodIdObjArgs(
13227db96d56Sopenharmony_ci            st->elementpath_obj, &PyId_findall, self, path, namespaces, NULL
13237db96d56Sopenharmony_ci            );
13247db96d56Sopenharmony_ci    }
13257db96d56Sopenharmony_ci
13267db96d56Sopenharmony_ci    out = PyList_New(0);
13277db96d56Sopenharmony_ci    if (!out)
13287db96d56Sopenharmony_ci        return NULL;
13297db96d56Sopenharmony_ci
13307db96d56Sopenharmony_ci    if (!self->extra)
13317db96d56Sopenharmony_ci        return out;
13327db96d56Sopenharmony_ci
13337db96d56Sopenharmony_ci    for (i = 0; i < self->extra->length; i++) {
13347db96d56Sopenharmony_ci        PyObject* item = self->extra->children[i];
13357db96d56Sopenharmony_ci        int rc;
13367db96d56Sopenharmony_ci        assert(Element_Check(item));
13377db96d56Sopenharmony_ci        Py_INCREF(item);
13387db96d56Sopenharmony_ci        rc = PyObject_RichCompareBool(((ElementObject*)item)->tag, path, Py_EQ);
13397db96d56Sopenharmony_ci        if (rc != 0 && (rc < 0 || PyList_Append(out, item) < 0)) {
13407db96d56Sopenharmony_ci            Py_DECREF(item);
13417db96d56Sopenharmony_ci            Py_DECREF(out);
13427db96d56Sopenharmony_ci            return NULL;
13437db96d56Sopenharmony_ci        }
13447db96d56Sopenharmony_ci        Py_DECREF(item);
13457db96d56Sopenharmony_ci    }
13467db96d56Sopenharmony_ci
13477db96d56Sopenharmony_ci    return out;
13487db96d56Sopenharmony_ci}
13497db96d56Sopenharmony_ci
13507db96d56Sopenharmony_ci/*[clinic input]
13517db96d56Sopenharmony_ci_elementtree.Element.iterfind
13527db96d56Sopenharmony_ci
13537db96d56Sopenharmony_ci    path: object
13547db96d56Sopenharmony_ci    namespaces: object = None
13557db96d56Sopenharmony_ci
13567db96d56Sopenharmony_ci[clinic start generated code]*/
13577db96d56Sopenharmony_ci
13587db96d56Sopenharmony_cistatic PyObject *
13597db96d56Sopenharmony_ci_elementtree_Element_iterfind_impl(ElementObject *self, PyObject *path,
13607db96d56Sopenharmony_ci                                   PyObject *namespaces)
13617db96d56Sopenharmony_ci/*[clinic end generated code: output=ecdd56d63b19d40f input=abb974e350fb65c7]*/
13627db96d56Sopenharmony_ci{
13637db96d56Sopenharmony_ci    PyObject* tag = path;
13647db96d56Sopenharmony_ci    _Py_IDENTIFIER(iterfind);
13657db96d56Sopenharmony_ci    elementtreestate *st = ET_STATE_GLOBAL;
13667db96d56Sopenharmony_ci
13677db96d56Sopenharmony_ci    return _PyObject_CallMethodIdObjArgs(
13687db96d56Sopenharmony_ci        st->elementpath_obj, &PyId_iterfind, self, tag, namespaces, NULL);
13697db96d56Sopenharmony_ci}
13707db96d56Sopenharmony_ci
13717db96d56Sopenharmony_ci/*[clinic input]
13727db96d56Sopenharmony_ci_elementtree.Element.get
13737db96d56Sopenharmony_ci
13747db96d56Sopenharmony_ci    key: object
13757db96d56Sopenharmony_ci    default: object = None
13767db96d56Sopenharmony_ci
13777db96d56Sopenharmony_ci[clinic start generated code]*/
13787db96d56Sopenharmony_ci
13797db96d56Sopenharmony_cistatic PyObject *
13807db96d56Sopenharmony_ci_elementtree_Element_get_impl(ElementObject *self, PyObject *key,
13817db96d56Sopenharmony_ci                              PyObject *default_value)
13827db96d56Sopenharmony_ci/*[clinic end generated code: output=523c614142595d75 input=ee153bbf8cdb246e]*/
13837db96d56Sopenharmony_ci{
13847db96d56Sopenharmony_ci    if (self->extra && self->extra->attrib) {
13857db96d56Sopenharmony_ci        PyObject *attrib = self->extra->attrib;
13867db96d56Sopenharmony_ci        Py_INCREF(attrib);
13877db96d56Sopenharmony_ci        PyObject *value = PyDict_GetItemWithError(attrib, key);
13887db96d56Sopenharmony_ci        Py_XINCREF(value);
13897db96d56Sopenharmony_ci        Py_DECREF(attrib);
13907db96d56Sopenharmony_ci        if (value != NULL || PyErr_Occurred()) {
13917db96d56Sopenharmony_ci            return value;
13927db96d56Sopenharmony_ci        }
13937db96d56Sopenharmony_ci    }
13947db96d56Sopenharmony_ci
13957db96d56Sopenharmony_ci    Py_INCREF(default_value);
13967db96d56Sopenharmony_ci    return default_value;
13977db96d56Sopenharmony_ci}
13987db96d56Sopenharmony_ci
13997db96d56Sopenharmony_cistatic PyObject *
14007db96d56Sopenharmony_cicreate_elementiter(ElementObject *self, PyObject *tag, int gettext);
14017db96d56Sopenharmony_ci
14027db96d56Sopenharmony_ci
14037db96d56Sopenharmony_ci/*[clinic input]
14047db96d56Sopenharmony_ci_elementtree.Element.iter
14057db96d56Sopenharmony_ci
14067db96d56Sopenharmony_ci    tag: object = None
14077db96d56Sopenharmony_ci
14087db96d56Sopenharmony_ci[clinic start generated code]*/
14097db96d56Sopenharmony_ci
14107db96d56Sopenharmony_cistatic PyObject *
14117db96d56Sopenharmony_ci_elementtree_Element_iter_impl(ElementObject *self, PyObject *tag)
14127db96d56Sopenharmony_ci/*[clinic end generated code: output=3f49f9a862941cc5 input=774d5b12e573aedd]*/
14137db96d56Sopenharmony_ci{
14147db96d56Sopenharmony_ci    if (PyUnicode_Check(tag)) {
14157db96d56Sopenharmony_ci        if (PyUnicode_READY(tag) < 0)
14167db96d56Sopenharmony_ci            return NULL;
14177db96d56Sopenharmony_ci        if (PyUnicode_GET_LENGTH(tag) == 1 && PyUnicode_READ_CHAR(tag, 0) == '*')
14187db96d56Sopenharmony_ci            tag = Py_None;
14197db96d56Sopenharmony_ci    }
14207db96d56Sopenharmony_ci    else if (PyBytes_Check(tag)) {
14217db96d56Sopenharmony_ci        if (PyBytes_GET_SIZE(tag) == 1 && *PyBytes_AS_STRING(tag) == '*')
14227db96d56Sopenharmony_ci            tag = Py_None;
14237db96d56Sopenharmony_ci    }
14247db96d56Sopenharmony_ci
14257db96d56Sopenharmony_ci    return create_elementiter(self, tag, 0);
14267db96d56Sopenharmony_ci}
14277db96d56Sopenharmony_ci
14287db96d56Sopenharmony_ci
14297db96d56Sopenharmony_ci/*[clinic input]
14307db96d56Sopenharmony_ci_elementtree.Element.itertext
14317db96d56Sopenharmony_ci
14327db96d56Sopenharmony_ci[clinic start generated code]*/
14337db96d56Sopenharmony_ci
14347db96d56Sopenharmony_cistatic PyObject *
14357db96d56Sopenharmony_ci_elementtree_Element_itertext_impl(ElementObject *self)
14367db96d56Sopenharmony_ci/*[clinic end generated code: output=5fa34b2fbcb65df6 input=af8f0e42cb239c89]*/
14377db96d56Sopenharmony_ci{
14387db96d56Sopenharmony_ci    return create_elementiter(self, Py_None, 1);
14397db96d56Sopenharmony_ci}
14407db96d56Sopenharmony_ci
14417db96d56Sopenharmony_ci
14427db96d56Sopenharmony_cistatic PyObject*
14437db96d56Sopenharmony_cielement_getitem(PyObject* self_, Py_ssize_t index)
14447db96d56Sopenharmony_ci{
14457db96d56Sopenharmony_ci    ElementObject* self = (ElementObject*) self_;
14467db96d56Sopenharmony_ci
14477db96d56Sopenharmony_ci    if (!self->extra || index < 0 || index >= self->extra->length) {
14487db96d56Sopenharmony_ci        PyErr_SetString(
14497db96d56Sopenharmony_ci            PyExc_IndexError,
14507db96d56Sopenharmony_ci            "child index out of range"
14517db96d56Sopenharmony_ci            );
14527db96d56Sopenharmony_ci        return NULL;
14537db96d56Sopenharmony_ci    }
14547db96d56Sopenharmony_ci
14557db96d56Sopenharmony_ci    Py_INCREF(self->extra->children[index]);
14567db96d56Sopenharmony_ci    return self->extra->children[index];
14577db96d56Sopenharmony_ci}
14587db96d56Sopenharmony_ci
14597db96d56Sopenharmony_ci/*[clinic input]
14607db96d56Sopenharmony_ci_elementtree.Element.insert
14617db96d56Sopenharmony_ci
14627db96d56Sopenharmony_ci    index: Py_ssize_t
14637db96d56Sopenharmony_ci    subelement: object(subclass_of='&Element_Type')
14647db96d56Sopenharmony_ci    /
14657db96d56Sopenharmony_ci
14667db96d56Sopenharmony_ci[clinic start generated code]*/
14677db96d56Sopenharmony_ci
14687db96d56Sopenharmony_cistatic PyObject *
14697db96d56Sopenharmony_ci_elementtree_Element_insert_impl(ElementObject *self, Py_ssize_t index,
14707db96d56Sopenharmony_ci                                 PyObject *subelement)
14717db96d56Sopenharmony_ci/*[clinic end generated code: output=990adfef4d424c0b input=cd6fbfcdab52d7a8]*/
14727db96d56Sopenharmony_ci{
14737db96d56Sopenharmony_ci    Py_ssize_t i;
14747db96d56Sopenharmony_ci
14757db96d56Sopenharmony_ci    if (!self->extra) {
14767db96d56Sopenharmony_ci        if (create_extra(self, NULL) < 0)
14777db96d56Sopenharmony_ci            return NULL;
14787db96d56Sopenharmony_ci    }
14797db96d56Sopenharmony_ci
14807db96d56Sopenharmony_ci    if (index < 0) {
14817db96d56Sopenharmony_ci        index += self->extra->length;
14827db96d56Sopenharmony_ci        if (index < 0)
14837db96d56Sopenharmony_ci            index = 0;
14847db96d56Sopenharmony_ci    }
14857db96d56Sopenharmony_ci    if (index > self->extra->length)
14867db96d56Sopenharmony_ci        index = self->extra->length;
14877db96d56Sopenharmony_ci
14887db96d56Sopenharmony_ci    if (element_resize(self, 1) < 0)
14897db96d56Sopenharmony_ci        return NULL;
14907db96d56Sopenharmony_ci
14917db96d56Sopenharmony_ci    for (i = self->extra->length; i > index; i--)
14927db96d56Sopenharmony_ci        self->extra->children[i] = self->extra->children[i-1];
14937db96d56Sopenharmony_ci
14947db96d56Sopenharmony_ci    Py_INCREF(subelement);
14957db96d56Sopenharmony_ci    self->extra->children[index] = subelement;
14967db96d56Sopenharmony_ci
14977db96d56Sopenharmony_ci    self->extra->length++;
14987db96d56Sopenharmony_ci
14997db96d56Sopenharmony_ci    Py_RETURN_NONE;
15007db96d56Sopenharmony_ci}
15017db96d56Sopenharmony_ci
15027db96d56Sopenharmony_ci/*[clinic input]
15037db96d56Sopenharmony_ci_elementtree.Element.items
15047db96d56Sopenharmony_ci
15057db96d56Sopenharmony_ci[clinic start generated code]*/
15067db96d56Sopenharmony_ci
15077db96d56Sopenharmony_cistatic PyObject *
15087db96d56Sopenharmony_ci_elementtree_Element_items_impl(ElementObject *self)
15097db96d56Sopenharmony_ci/*[clinic end generated code: output=6db2c778ce3f5a4d input=adbe09aaea474447]*/
15107db96d56Sopenharmony_ci{
15117db96d56Sopenharmony_ci    if (!self->extra || !self->extra->attrib)
15127db96d56Sopenharmony_ci        return PyList_New(0);
15137db96d56Sopenharmony_ci
15147db96d56Sopenharmony_ci    return PyDict_Items(self->extra->attrib);
15157db96d56Sopenharmony_ci}
15167db96d56Sopenharmony_ci
15177db96d56Sopenharmony_ci/*[clinic input]
15187db96d56Sopenharmony_ci_elementtree.Element.keys
15197db96d56Sopenharmony_ci
15207db96d56Sopenharmony_ci[clinic start generated code]*/
15217db96d56Sopenharmony_ci
15227db96d56Sopenharmony_cistatic PyObject *
15237db96d56Sopenharmony_ci_elementtree_Element_keys_impl(ElementObject *self)
15247db96d56Sopenharmony_ci/*[clinic end generated code: output=bc5bfabbf20eeb3c input=f02caf5b496b5b0b]*/
15257db96d56Sopenharmony_ci{
15267db96d56Sopenharmony_ci    if (!self->extra || !self->extra->attrib)
15277db96d56Sopenharmony_ci        return PyList_New(0);
15287db96d56Sopenharmony_ci
15297db96d56Sopenharmony_ci    return PyDict_Keys(self->extra->attrib);
15307db96d56Sopenharmony_ci}
15317db96d56Sopenharmony_ci
15327db96d56Sopenharmony_cistatic Py_ssize_t
15337db96d56Sopenharmony_cielement_length(ElementObject* self)
15347db96d56Sopenharmony_ci{
15357db96d56Sopenharmony_ci    if (!self->extra)
15367db96d56Sopenharmony_ci        return 0;
15377db96d56Sopenharmony_ci
15387db96d56Sopenharmony_ci    return self->extra->length;
15397db96d56Sopenharmony_ci}
15407db96d56Sopenharmony_ci
15417db96d56Sopenharmony_ci/*[clinic input]
15427db96d56Sopenharmony_ci_elementtree.Element.makeelement
15437db96d56Sopenharmony_ci
15447db96d56Sopenharmony_ci    tag: object
15457db96d56Sopenharmony_ci    attrib: object(subclass_of='&PyDict_Type')
15467db96d56Sopenharmony_ci    /
15477db96d56Sopenharmony_ci
15487db96d56Sopenharmony_ci[clinic start generated code]*/
15497db96d56Sopenharmony_ci
15507db96d56Sopenharmony_cistatic PyObject *
15517db96d56Sopenharmony_ci_elementtree_Element_makeelement_impl(ElementObject *self, PyObject *tag,
15527db96d56Sopenharmony_ci                                      PyObject *attrib)
15537db96d56Sopenharmony_ci/*[clinic end generated code: output=4109832d5bb789ef input=2279d974529c3861]*/
15547db96d56Sopenharmony_ci{
15557db96d56Sopenharmony_ci    PyObject* elem;
15567db96d56Sopenharmony_ci
15577db96d56Sopenharmony_ci    attrib = PyDict_Copy(attrib);
15587db96d56Sopenharmony_ci    if (!attrib)
15597db96d56Sopenharmony_ci        return NULL;
15607db96d56Sopenharmony_ci
15617db96d56Sopenharmony_ci    elem = create_new_element(tag, attrib);
15627db96d56Sopenharmony_ci
15637db96d56Sopenharmony_ci    Py_DECREF(attrib);
15647db96d56Sopenharmony_ci
15657db96d56Sopenharmony_ci    return elem;
15667db96d56Sopenharmony_ci}
15677db96d56Sopenharmony_ci
15687db96d56Sopenharmony_ci/*[clinic input]
15697db96d56Sopenharmony_ci_elementtree.Element.remove
15707db96d56Sopenharmony_ci
15717db96d56Sopenharmony_ci    subelement: object(subclass_of='&Element_Type')
15727db96d56Sopenharmony_ci    /
15737db96d56Sopenharmony_ci
15747db96d56Sopenharmony_ci[clinic start generated code]*/
15757db96d56Sopenharmony_ci
15767db96d56Sopenharmony_cistatic PyObject *
15777db96d56Sopenharmony_ci_elementtree_Element_remove_impl(ElementObject *self, PyObject *subelement)
15787db96d56Sopenharmony_ci/*[clinic end generated code: output=38fe6c07d6d87d1f input=d52fc28ededc0bd8]*/
15797db96d56Sopenharmony_ci{
15807db96d56Sopenharmony_ci    Py_ssize_t i;
15817db96d56Sopenharmony_ci    int rc;
15827db96d56Sopenharmony_ci    PyObject *found;
15837db96d56Sopenharmony_ci
15847db96d56Sopenharmony_ci    if (!self->extra) {
15857db96d56Sopenharmony_ci        /* element has no children, so raise exception */
15867db96d56Sopenharmony_ci        PyErr_SetString(
15877db96d56Sopenharmony_ci            PyExc_ValueError,
15887db96d56Sopenharmony_ci            "list.remove(x): x not in list"
15897db96d56Sopenharmony_ci            );
15907db96d56Sopenharmony_ci        return NULL;
15917db96d56Sopenharmony_ci    }
15927db96d56Sopenharmony_ci
15937db96d56Sopenharmony_ci    for (i = 0; i < self->extra->length; i++) {
15947db96d56Sopenharmony_ci        if (self->extra->children[i] == subelement)
15957db96d56Sopenharmony_ci            break;
15967db96d56Sopenharmony_ci        rc = PyObject_RichCompareBool(self->extra->children[i], subelement, Py_EQ);
15977db96d56Sopenharmony_ci        if (rc > 0)
15987db96d56Sopenharmony_ci            break;
15997db96d56Sopenharmony_ci        if (rc < 0)
16007db96d56Sopenharmony_ci            return NULL;
16017db96d56Sopenharmony_ci    }
16027db96d56Sopenharmony_ci
16037db96d56Sopenharmony_ci    if (i >= self->extra->length) {
16047db96d56Sopenharmony_ci        /* subelement is not in children, so raise exception */
16057db96d56Sopenharmony_ci        PyErr_SetString(
16067db96d56Sopenharmony_ci            PyExc_ValueError,
16077db96d56Sopenharmony_ci            "list.remove(x): x not in list"
16087db96d56Sopenharmony_ci            );
16097db96d56Sopenharmony_ci        return NULL;
16107db96d56Sopenharmony_ci    }
16117db96d56Sopenharmony_ci
16127db96d56Sopenharmony_ci    found = self->extra->children[i];
16137db96d56Sopenharmony_ci
16147db96d56Sopenharmony_ci    self->extra->length--;
16157db96d56Sopenharmony_ci    for (; i < self->extra->length; i++)
16167db96d56Sopenharmony_ci        self->extra->children[i] = self->extra->children[i+1];
16177db96d56Sopenharmony_ci
16187db96d56Sopenharmony_ci    Py_DECREF(found);
16197db96d56Sopenharmony_ci    Py_RETURN_NONE;
16207db96d56Sopenharmony_ci}
16217db96d56Sopenharmony_ci
16227db96d56Sopenharmony_cistatic PyObject*
16237db96d56Sopenharmony_cielement_repr(ElementObject* self)
16247db96d56Sopenharmony_ci{
16257db96d56Sopenharmony_ci    int status;
16267db96d56Sopenharmony_ci
16277db96d56Sopenharmony_ci    if (self->tag == NULL)
16287db96d56Sopenharmony_ci        return PyUnicode_FromFormat("<Element at %p>", self);
16297db96d56Sopenharmony_ci
16307db96d56Sopenharmony_ci    status = Py_ReprEnter((PyObject *)self);
16317db96d56Sopenharmony_ci    if (status == 0) {
16327db96d56Sopenharmony_ci        PyObject *res;
16337db96d56Sopenharmony_ci        res = PyUnicode_FromFormat("<Element %R at %p>", self->tag, self);
16347db96d56Sopenharmony_ci        Py_ReprLeave((PyObject *)self);
16357db96d56Sopenharmony_ci        return res;
16367db96d56Sopenharmony_ci    }
16377db96d56Sopenharmony_ci    if (status > 0)
16387db96d56Sopenharmony_ci        PyErr_Format(PyExc_RuntimeError,
16397db96d56Sopenharmony_ci                     "reentrant call inside %s.__repr__",
16407db96d56Sopenharmony_ci                     Py_TYPE(self)->tp_name);
16417db96d56Sopenharmony_ci    return NULL;
16427db96d56Sopenharmony_ci}
16437db96d56Sopenharmony_ci
16447db96d56Sopenharmony_ci/*[clinic input]
16457db96d56Sopenharmony_ci_elementtree.Element.set
16467db96d56Sopenharmony_ci
16477db96d56Sopenharmony_ci    key: object
16487db96d56Sopenharmony_ci    value: object
16497db96d56Sopenharmony_ci    /
16507db96d56Sopenharmony_ci
16517db96d56Sopenharmony_ci[clinic start generated code]*/
16527db96d56Sopenharmony_ci
16537db96d56Sopenharmony_cistatic PyObject *
16547db96d56Sopenharmony_ci_elementtree_Element_set_impl(ElementObject *self, PyObject *key,
16557db96d56Sopenharmony_ci                              PyObject *value)
16567db96d56Sopenharmony_ci/*[clinic end generated code: output=fb938806be3c5656 input=1efe90f7d82b3fe9]*/
16577db96d56Sopenharmony_ci{
16587db96d56Sopenharmony_ci    PyObject* attrib;
16597db96d56Sopenharmony_ci
16607db96d56Sopenharmony_ci    if (!self->extra) {
16617db96d56Sopenharmony_ci        if (create_extra(self, NULL) < 0)
16627db96d56Sopenharmony_ci            return NULL;
16637db96d56Sopenharmony_ci    }
16647db96d56Sopenharmony_ci
16657db96d56Sopenharmony_ci    attrib = element_get_attrib(self);
16667db96d56Sopenharmony_ci    if (!attrib)
16677db96d56Sopenharmony_ci        return NULL;
16687db96d56Sopenharmony_ci
16697db96d56Sopenharmony_ci    if (PyDict_SetItem(attrib, key, value) < 0)
16707db96d56Sopenharmony_ci        return NULL;
16717db96d56Sopenharmony_ci
16727db96d56Sopenharmony_ci    Py_RETURN_NONE;
16737db96d56Sopenharmony_ci}
16747db96d56Sopenharmony_ci
16757db96d56Sopenharmony_cistatic int
16767db96d56Sopenharmony_cielement_setitem(PyObject* self_, Py_ssize_t index, PyObject* item)
16777db96d56Sopenharmony_ci{
16787db96d56Sopenharmony_ci    ElementObject* self = (ElementObject*) self_;
16797db96d56Sopenharmony_ci    Py_ssize_t i;
16807db96d56Sopenharmony_ci    PyObject* old;
16817db96d56Sopenharmony_ci
16827db96d56Sopenharmony_ci    if (!self->extra || index < 0 || index >= self->extra->length) {
16837db96d56Sopenharmony_ci        PyErr_SetString(
16847db96d56Sopenharmony_ci            PyExc_IndexError,
16857db96d56Sopenharmony_ci            "child assignment index out of range");
16867db96d56Sopenharmony_ci        return -1;
16877db96d56Sopenharmony_ci    }
16887db96d56Sopenharmony_ci
16897db96d56Sopenharmony_ci    old = self->extra->children[index];
16907db96d56Sopenharmony_ci
16917db96d56Sopenharmony_ci    if (item) {
16927db96d56Sopenharmony_ci        if (!Element_Check(item)) {
16937db96d56Sopenharmony_ci            raise_type_error(item);
16947db96d56Sopenharmony_ci            return -1;
16957db96d56Sopenharmony_ci        }
16967db96d56Sopenharmony_ci        Py_INCREF(item);
16977db96d56Sopenharmony_ci        self->extra->children[index] = item;
16987db96d56Sopenharmony_ci    } else {
16997db96d56Sopenharmony_ci        self->extra->length--;
17007db96d56Sopenharmony_ci        for (i = index; i < self->extra->length; i++)
17017db96d56Sopenharmony_ci            self->extra->children[i] = self->extra->children[i+1];
17027db96d56Sopenharmony_ci    }
17037db96d56Sopenharmony_ci
17047db96d56Sopenharmony_ci    Py_DECREF(old);
17057db96d56Sopenharmony_ci
17067db96d56Sopenharmony_ci    return 0;
17077db96d56Sopenharmony_ci}
17087db96d56Sopenharmony_ci
17097db96d56Sopenharmony_cistatic PyObject*
17107db96d56Sopenharmony_cielement_subscr(PyObject* self_, PyObject* item)
17117db96d56Sopenharmony_ci{
17127db96d56Sopenharmony_ci    ElementObject* self = (ElementObject*) self_;
17137db96d56Sopenharmony_ci
17147db96d56Sopenharmony_ci    if (PyIndex_Check(item)) {
17157db96d56Sopenharmony_ci        Py_ssize_t i = PyNumber_AsSsize_t(item, PyExc_IndexError);
17167db96d56Sopenharmony_ci
17177db96d56Sopenharmony_ci        if (i == -1 && PyErr_Occurred()) {
17187db96d56Sopenharmony_ci            return NULL;
17197db96d56Sopenharmony_ci        }
17207db96d56Sopenharmony_ci        if (i < 0 && self->extra)
17217db96d56Sopenharmony_ci            i += self->extra->length;
17227db96d56Sopenharmony_ci        return element_getitem(self_, i);
17237db96d56Sopenharmony_ci    }
17247db96d56Sopenharmony_ci    else if (PySlice_Check(item)) {
17257db96d56Sopenharmony_ci        Py_ssize_t start, stop, step, slicelen, i;
17267db96d56Sopenharmony_ci        size_t cur;
17277db96d56Sopenharmony_ci        PyObject* list;
17287db96d56Sopenharmony_ci
17297db96d56Sopenharmony_ci        if (!self->extra)
17307db96d56Sopenharmony_ci            return PyList_New(0);
17317db96d56Sopenharmony_ci
17327db96d56Sopenharmony_ci        if (PySlice_Unpack(item, &start, &stop, &step) < 0) {
17337db96d56Sopenharmony_ci            return NULL;
17347db96d56Sopenharmony_ci        }
17357db96d56Sopenharmony_ci        slicelen = PySlice_AdjustIndices(self->extra->length, &start, &stop,
17367db96d56Sopenharmony_ci                                         step);
17377db96d56Sopenharmony_ci
17387db96d56Sopenharmony_ci        if (slicelen <= 0)
17397db96d56Sopenharmony_ci            return PyList_New(0);
17407db96d56Sopenharmony_ci        else {
17417db96d56Sopenharmony_ci            list = PyList_New(slicelen);
17427db96d56Sopenharmony_ci            if (!list)
17437db96d56Sopenharmony_ci                return NULL;
17447db96d56Sopenharmony_ci
17457db96d56Sopenharmony_ci            for (cur = start, i = 0; i < slicelen;
17467db96d56Sopenharmony_ci                 cur += step, i++) {
17477db96d56Sopenharmony_ci                PyObject* item = self->extra->children[cur];
17487db96d56Sopenharmony_ci                Py_INCREF(item);
17497db96d56Sopenharmony_ci                PyList_SET_ITEM(list, i, item);
17507db96d56Sopenharmony_ci            }
17517db96d56Sopenharmony_ci
17527db96d56Sopenharmony_ci            return list;
17537db96d56Sopenharmony_ci        }
17547db96d56Sopenharmony_ci    }
17557db96d56Sopenharmony_ci    else {
17567db96d56Sopenharmony_ci        PyErr_SetString(PyExc_TypeError,
17577db96d56Sopenharmony_ci                "element indices must be integers");
17587db96d56Sopenharmony_ci        return NULL;
17597db96d56Sopenharmony_ci    }
17607db96d56Sopenharmony_ci}
17617db96d56Sopenharmony_ci
17627db96d56Sopenharmony_cistatic int
17637db96d56Sopenharmony_cielement_ass_subscr(PyObject* self_, PyObject* item, PyObject* value)
17647db96d56Sopenharmony_ci{
17657db96d56Sopenharmony_ci    ElementObject* self = (ElementObject*) self_;
17667db96d56Sopenharmony_ci
17677db96d56Sopenharmony_ci    if (PyIndex_Check(item)) {
17687db96d56Sopenharmony_ci        Py_ssize_t i = PyNumber_AsSsize_t(item, PyExc_IndexError);
17697db96d56Sopenharmony_ci
17707db96d56Sopenharmony_ci        if (i == -1 && PyErr_Occurred()) {
17717db96d56Sopenharmony_ci            return -1;
17727db96d56Sopenharmony_ci        }
17737db96d56Sopenharmony_ci        if (i < 0 && self->extra)
17747db96d56Sopenharmony_ci            i += self->extra->length;
17757db96d56Sopenharmony_ci        return element_setitem(self_, i, value);
17767db96d56Sopenharmony_ci    }
17777db96d56Sopenharmony_ci    else if (PySlice_Check(item)) {
17787db96d56Sopenharmony_ci        Py_ssize_t start, stop, step, slicelen, newlen, i;
17797db96d56Sopenharmony_ci        size_t cur;
17807db96d56Sopenharmony_ci
17817db96d56Sopenharmony_ci        PyObject* recycle = NULL;
17827db96d56Sopenharmony_ci        PyObject* seq;
17837db96d56Sopenharmony_ci
17847db96d56Sopenharmony_ci        if (!self->extra) {
17857db96d56Sopenharmony_ci            if (create_extra(self, NULL) < 0)
17867db96d56Sopenharmony_ci                return -1;
17877db96d56Sopenharmony_ci        }
17887db96d56Sopenharmony_ci
17897db96d56Sopenharmony_ci        if (PySlice_Unpack(item, &start, &stop, &step) < 0) {
17907db96d56Sopenharmony_ci            return -1;
17917db96d56Sopenharmony_ci        }
17927db96d56Sopenharmony_ci        slicelen = PySlice_AdjustIndices(self->extra->length, &start, &stop,
17937db96d56Sopenharmony_ci                                         step);
17947db96d56Sopenharmony_ci
17957db96d56Sopenharmony_ci        if (value == NULL) {
17967db96d56Sopenharmony_ci            /* Delete slice */
17977db96d56Sopenharmony_ci            size_t cur;
17987db96d56Sopenharmony_ci            Py_ssize_t i;
17997db96d56Sopenharmony_ci
18007db96d56Sopenharmony_ci            if (slicelen <= 0)
18017db96d56Sopenharmony_ci                return 0;
18027db96d56Sopenharmony_ci
18037db96d56Sopenharmony_ci            /* Since we're deleting, the direction of the range doesn't matter,
18047db96d56Sopenharmony_ci             * so for simplicity make it always ascending.
18057db96d56Sopenharmony_ci            */
18067db96d56Sopenharmony_ci            if (step < 0) {
18077db96d56Sopenharmony_ci                stop = start + 1;
18087db96d56Sopenharmony_ci                start = stop + step * (slicelen - 1) - 1;
18097db96d56Sopenharmony_ci                step = -step;
18107db96d56Sopenharmony_ci            }
18117db96d56Sopenharmony_ci
18127db96d56Sopenharmony_ci            assert((size_t)slicelen <= SIZE_MAX / sizeof(PyObject *));
18137db96d56Sopenharmony_ci
18147db96d56Sopenharmony_ci            /* recycle is a list that will contain all the children
18157db96d56Sopenharmony_ci             * scheduled for removal.
18167db96d56Sopenharmony_ci            */
18177db96d56Sopenharmony_ci            if (!(recycle = PyList_New(slicelen))) {
18187db96d56Sopenharmony_ci                return -1;
18197db96d56Sopenharmony_ci            }
18207db96d56Sopenharmony_ci
18217db96d56Sopenharmony_ci            /* This loop walks over all the children that have to be deleted,
18227db96d56Sopenharmony_ci             * with cur pointing at them. num_moved is the amount of children
18237db96d56Sopenharmony_ci             * until the next deleted child that have to be "shifted down" to
18247db96d56Sopenharmony_ci             * occupy the deleted's places.
18257db96d56Sopenharmony_ci             * Note that in the ith iteration, shifting is done i+i places down
18267db96d56Sopenharmony_ci             * because i children were already removed.
18277db96d56Sopenharmony_ci            */
18287db96d56Sopenharmony_ci            for (cur = start, i = 0; cur < (size_t)stop; cur += step, ++i) {
18297db96d56Sopenharmony_ci                /* Compute how many children have to be moved, clipping at the
18307db96d56Sopenharmony_ci                 * list end.
18317db96d56Sopenharmony_ci                */
18327db96d56Sopenharmony_ci                Py_ssize_t num_moved = step - 1;
18337db96d56Sopenharmony_ci                if (cur + step >= (size_t)self->extra->length) {
18347db96d56Sopenharmony_ci                    num_moved = self->extra->length - cur - 1;
18357db96d56Sopenharmony_ci                }
18367db96d56Sopenharmony_ci
18377db96d56Sopenharmony_ci                PyList_SET_ITEM(recycle, i, self->extra->children[cur]);
18387db96d56Sopenharmony_ci
18397db96d56Sopenharmony_ci                memmove(
18407db96d56Sopenharmony_ci                    self->extra->children + cur - i,
18417db96d56Sopenharmony_ci                    self->extra->children + cur + 1,
18427db96d56Sopenharmony_ci                    num_moved * sizeof(PyObject *));
18437db96d56Sopenharmony_ci            }
18447db96d56Sopenharmony_ci
18457db96d56Sopenharmony_ci            /* Leftover "tail" after the last removed child */
18467db96d56Sopenharmony_ci            cur = start + (size_t)slicelen * step;
18477db96d56Sopenharmony_ci            if (cur < (size_t)self->extra->length) {
18487db96d56Sopenharmony_ci                memmove(
18497db96d56Sopenharmony_ci                    self->extra->children + cur - slicelen,
18507db96d56Sopenharmony_ci                    self->extra->children + cur,
18517db96d56Sopenharmony_ci                    (self->extra->length - cur) * sizeof(PyObject *));
18527db96d56Sopenharmony_ci            }
18537db96d56Sopenharmony_ci
18547db96d56Sopenharmony_ci            self->extra->length -= slicelen;
18557db96d56Sopenharmony_ci
18567db96d56Sopenharmony_ci            /* Discard the recycle list with all the deleted sub-elements */
18577db96d56Sopenharmony_ci            Py_DECREF(recycle);
18587db96d56Sopenharmony_ci            return 0;
18597db96d56Sopenharmony_ci        }
18607db96d56Sopenharmony_ci
18617db96d56Sopenharmony_ci        /* A new slice is actually being assigned */
18627db96d56Sopenharmony_ci        seq = PySequence_Fast(value, "");
18637db96d56Sopenharmony_ci        if (!seq) {
18647db96d56Sopenharmony_ci            PyErr_Format(
18657db96d56Sopenharmony_ci                PyExc_TypeError,
18667db96d56Sopenharmony_ci                "expected sequence, not \"%.200s\"", Py_TYPE(value)->tp_name
18677db96d56Sopenharmony_ci                );
18687db96d56Sopenharmony_ci            return -1;
18697db96d56Sopenharmony_ci        }
18707db96d56Sopenharmony_ci        newlen = PySequence_Fast_GET_SIZE(seq);
18717db96d56Sopenharmony_ci
18727db96d56Sopenharmony_ci        if (step !=  1 && newlen != slicelen)
18737db96d56Sopenharmony_ci        {
18747db96d56Sopenharmony_ci            Py_DECREF(seq);
18757db96d56Sopenharmony_ci            PyErr_Format(PyExc_ValueError,
18767db96d56Sopenharmony_ci                "attempt to assign sequence of size %zd "
18777db96d56Sopenharmony_ci                "to extended slice of size %zd",
18787db96d56Sopenharmony_ci                newlen, slicelen
18797db96d56Sopenharmony_ci                );
18807db96d56Sopenharmony_ci            return -1;
18817db96d56Sopenharmony_ci        }
18827db96d56Sopenharmony_ci
18837db96d56Sopenharmony_ci        /* Resize before creating the recycle bin, to prevent refleaks. */
18847db96d56Sopenharmony_ci        if (newlen > slicelen) {
18857db96d56Sopenharmony_ci            if (element_resize(self, newlen - slicelen) < 0) {
18867db96d56Sopenharmony_ci                Py_DECREF(seq);
18877db96d56Sopenharmony_ci                return -1;
18887db96d56Sopenharmony_ci            }
18897db96d56Sopenharmony_ci        }
18907db96d56Sopenharmony_ci
18917db96d56Sopenharmony_ci        for (i = 0; i < newlen; i++) {
18927db96d56Sopenharmony_ci            PyObject *element = PySequence_Fast_GET_ITEM(seq, i);
18937db96d56Sopenharmony_ci            if (!Element_Check(element)) {
18947db96d56Sopenharmony_ci                raise_type_error(element);
18957db96d56Sopenharmony_ci                Py_DECREF(seq);
18967db96d56Sopenharmony_ci                return -1;
18977db96d56Sopenharmony_ci            }
18987db96d56Sopenharmony_ci        }
18997db96d56Sopenharmony_ci
19007db96d56Sopenharmony_ci        if (slicelen > 0) {
19017db96d56Sopenharmony_ci            /* to avoid recursive calls to this method (via decref), move
19027db96d56Sopenharmony_ci               old items to the recycle bin here, and get rid of them when
19037db96d56Sopenharmony_ci               we're done modifying the element */
19047db96d56Sopenharmony_ci            recycle = PyList_New(slicelen);
19057db96d56Sopenharmony_ci            if (!recycle) {
19067db96d56Sopenharmony_ci                Py_DECREF(seq);
19077db96d56Sopenharmony_ci                return -1;
19087db96d56Sopenharmony_ci            }
19097db96d56Sopenharmony_ci            for (cur = start, i = 0; i < slicelen;
19107db96d56Sopenharmony_ci                 cur += step, i++)
19117db96d56Sopenharmony_ci                PyList_SET_ITEM(recycle, i, self->extra->children[cur]);
19127db96d56Sopenharmony_ci        }
19137db96d56Sopenharmony_ci
19147db96d56Sopenharmony_ci        if (newlen < slicelen) {
19157db96d56Sopenharmony_ci            /* delete slice */
19167db96d56Sopenharmony_ci            for (i = stop; i < self->extra->length; i++)
19177db96d56Sopenharmony_ci                self->extra->children[i + newlen - slicelen] = self->extra->children[i];
19187db96d56Sopenharmony_ci        } else if (newlen > slicelen) {
19197db96d56Sopenharmony_ci            /* insert slice */
19207db96d56Sopenharmony_ci            for (i = self->extra->length-1; i >= stop; i--)
19217db96d56Sopenharmony_ci                self->extra->children[i + newlen - slicelen] = self->extra->children[i];
19227db96d56Sopenharmony_ci        }
19237db96d56Sopenharmony_ci
19247db96d56Sopenharmony_ci        /* replace the slice */
19257db96d56Sopenharmony_ci        for (cur = start, i = 0; i < newlen;
19267db96d56Sopenharmony_ci             cur += step, i++) {
19277db96d56Sopenharmony_ci            PyObject* element = PySequence_Fast_GET_ITEM(seq, i);
19287db96d56Sopenharmony_ci            Py_INCREF(element);
19297db96d56Sopenharmony_ci            self->extra->children[cur] = element;
19307db96d56Sopenharmony_ci        }
19317db96d56Sopenharmony_ci
19327db96d56Sopenharmony_ci        self->extra->length += newlen - slicelen;
19337db96d56Sopenharmony_ci
19347db96d56Sopenharmony_ci        Py_DECREF(seq);
19357db96d56Sopenharmony_ci
19367db96d56Sopenharmony_ci        /* discard the recycle bin, and everything in it */
19377db96d56Sopenharmony_ci        Py_XDECREF(recycle);
19387db96d56Sopenharmony_ci
19397db96d56Sopenharmony_ci        return 0;
19407db96d56Sopenharmony_ci    }
19417db96d56Sopenharmony_ci    else {
19427db96d56Sopenharmony_ci        PyErr_SetString(PyExc_TypeError,
19437db96d56Sopenharmony_ci                "element indices must be integers");
19447db96d56Sopenharmony_ci        return -1;
19457db96d56Sopenharmony_ci    }
19467db96d56Sopenharmony_ci}
19477db96d56Sopenharmony_ci
19487db96d56Sopenharmony_cistatic PyObject*
19497db96d56Sopenharmony_cielement_tag_getter(ElementObject *self, void *closure)
19507db96d56Sopenharmony_ci{
19517db96d56Sopenharmony_ci    PyObject *res = self->tag;
19527db96d56Sopenharmony_ci    Py_INCREF(res);
19537db96d56Sopenharmony_ci    return res;
19547db96d56Sopenharmony_ci}
19557db96d56Sopenharmony_ci
19567db96d56Sopenharmony_cistatic PyObject*
19577db96d56Sopenharmony_cielement_text_getter(ElementObject *self, void *closure)
19587db96d56Sopenharmony_ci{
19597db96d56Sopenharmony_ci    PyObject *res = element_get_text(self);
19607db96d56Sopenharmony_ci    Py_XINCREF(res);
19617db96d56Sopenharmony_ci    return res;
19627db96d56Sopenharmony_ci}
19637db96d56Sopenharmony_ci
19647db96d56Sopenharmony_cistatic PyObject*
19657db96d56Sopenharmony_cielement_tail_getter(ElementObject *self, void *closure)
19667db96d56Sopenharmony_ci{
19677db96d56Sopenharmony_ci    PyObject *res = element_get_tail(self);
19687db96d56Sopenharmony_ci    Py_XINCREF(res);
19697db96d56Sopenharmony_ci    return res;
19707db96d56Sopenharmony_ci}
19717db96d56Sopenharmony_ci
19727db96d56Sopenharmony_cistatic PyObject*
19737db96d56Sopenharmony_cielement_attrib_getter(ElementObject *self, void *closure)
19747db96d56Sopenharmony_ci{
19757db96d56Sopenharmony_ci    PyObject *res;
19767db96d56Sopenharmony_ci    if (!self->extra) {
19777db96d56Sopenharmony_ci        if (create_extra(self, NULL) < 0)
19787db96d56Sopenharmony_ci            return NULL;
19797db96d56Sopenharmony_ci    }
19807db96d56Sopenharmony_ci    res = element_get_attrib(self);
19817db96d56Sopenharmony_ci    Py_XINCREF(res);
19827db96d56Sopenharmony_ci    return res;
19837db96d56Sopenharmony_ci}
19847db96d56Sopenharmony_ci
19857db96d56Sopenharmony_ci/* macro for setter validation */
19867db96d56Sopenharmony_ci#define _VALIDATE_ATTR_VALUE(V)                     \
19877db96d56Sopenharmony_ci    if ((V) == NULL) {                              \
19887db96d56Sopenharmony_ci        PyErr_SetString(                            \
19897db96d56Sopenharmony_ci            PyExc_AttributeError,                   \
19907db96d56Sopenharmony_ci            "can't delete element attribute");      \
19917db96d56Sopenharmony_ci        return -1;                                  \
19927db96d56Sopenharmony_ci    }
19937db96d56Sopenharmony_ci
19947db96d56Sopenharmony_cistatic int
19957db96d56Sopenharmony_cielement_tag_setter(ElementObject *self, PyObject *value, void *closure)
19967db96d56Sopenharmony_ci{
19977db96d56Sopenharmony_ci    _VALIDATE_ATTR_VALUE(value);
19987db96d56Sopenharmony_ci    Py_INCREF(value);
19997db96d56Sopenharmony_ci    Py_SETREF(self->tag, value);
20007db96d56Sopenharmony_ci    return 0;
20017db96d56Sopenharmony_ci}
20027db96d56Sopenharmony_ci
20037db96d56Sopenharmony_cistatic int
20047db96d56Sopenharmony_cielement_text_setter(ElementObject *self, PyObject *value, void *closure)
20057db96d56Sopenharmony_ci{
20067db96d56Sopenharmony_ci    _VALIDATE_ATTR_VALUE(value);
20077db96d56Sopenharmony_ci    Py_INCREF(value);
20087db96d56Sopenharmony_ci    _set_joined_ptr(&self->text, value);
20097db96d56Sopenharmony_ci    return 0;
20107db96d56Sopenharmony_ci}
20117db96d56Sopenharmony_ci
20127db96d56Sopenharmony_cistatic int
20137db96d56Sopenharmony_cielement_tail_setter(ElementObject *self, PyObject *value, void *closure)
20147db96d56Sopenharmony_ci{
20157db96d56Sopenharmony_ci    _VALIDATE_ATTR_VALUE(value);
20167db96d56Sopenharmony_ci    Py_INCREF(value);
20177db96d56Sopenharmony_ci    _set_joined_ptr(&self->tail, value);
20187db96d56Sopenharmony_ci    return 0;
20197db96d56Sopenharmony_ci}
20207db96d56Sopenharmony_ci
20217db96d56Sopenharmony_cistatic int
20227db96d56Sopenharmony_cielement_attrib_setter(ElementObject *self, PyObject *value, void *closure)
20237db96d56Sopenharmony_ci{
20247db96d56Sopenharmony_ci    _VALIDATE_ATTR_VALUE(value);
20257db96d56Sopenharmony_ci    if (!PyDict_Check(value)) {
20267db96d56Sopenharmony_ci        PyErr_Format(PyExc_TypeError,
20277db96d56Sopenharmony_ci                     "attrib must be dict, not %.200s",
20287db96d56Sopenharmony_ci                     Py_TYPE(value)->tp_name);
20297db96d56Sopenharmony_ci        return -1;
20307db96d56Sopenharmony_ci    }
20317db96d56Sopenharmony_ci    if (!self->extra) {
20327db96d56Sopenharmony_ci        if (create_extra(self, NULL) < 0)
20337db96d56Sopenharmony_ci            return -1;
20347db96d56Sopenharmony_ci    }
20357db96d56Sopenharmony_ci    Py_INCREF(value);
20367db96d56Sopenharmony_ci    Py_XSETREF(self->extra->attrib, value);
20377db96d56Sopenharmony_ci    return 0;
20387db96d56Sopenharmony_ci}
20397db96d56Sopenharmony_ci
20407db96d56Sopenharmony_cistatic PySequenceMethods element_as_sequence = {
20417db96d56Sopenharmony_ci    (lenfunc) element_length,
20427db96d56Sopenharmony_ci    0, /* sq_concat */
20437db96d56Sopenharmony_ci    0, /* sq_repeat */
20447db96d56Sopenharmony_ci    element_getitem,
20457db96d56Sopenharmony_ci    0,
20467db96d56Sopenharmony_ci    element_setitem,
20477db96d56Sopenharmony_ci    0,
20487db96d56Sopenharmony_ci};
20497db96d56Sopenharmony_ci
20507db96d56Sopenharmony_ci/******************************* Element iterator ****************************/
20517db96d56Sopenharmony_ci
20527db96d56Sopenharmony_ci/* ElementIterObject represents the iteration state over an XML element in
20537db96d56Sopenharmony_ci * pre-order traversal. To keep track of which sub-element should be returned
20547db96d56Sopenharmony_ci * next, a stack of parents is maintained. This is a standard stack-based
20557db96d56Sopenharmony_ci * iterative pre-order traversal of a tree.
20567db96d56Sopenharmony_ci * The stack is managed using a continuous array.
20577db96d56Sopenharmony_ci * Each stack item contains the saved parent to which we should return after
20587db96d56Sopenharmony_ci * the current one is exhausted, and the next child to examine in that parent.
20597db96d56Sopenharmony_ci */
20607db96d56Sopenharmony_citypedef struct ParentLocator_t {
20617db96d56Sopenharmony_ci    ElementObject *parent;
20627db96d56Sopenharmony_ci    Py_ssize_t child_index;
20637db96d56Sopenharmony_ci} ParentLocator;
20647db96d56Sopenharmony_ci
20657db96d56Sopenharmony_citypedef struct {
20667db96d56Sopenharmony_ci    PyObject_HEAD
20677db96d56Sopenharmony_ci    ParentLocator *parent_stack;
20687db96d56Sopenharmony_ci    Py_ssize_t parent_stack_used;
20697db96d56Sopenharmony_ci    Py_ssize_t parent_stack_size;
20707db96d56Sopenharmony_ci    ElementObject *root_element;
20717db96d56Sopenharmony_ci    PyObject *sought_tag;
20727db96d56Sopenharmony_ci    int gettext;
20737db96d56Sopenharmony_ci} ElementIterObject;
20747db96d56Sopenharmony_ci
20757db96d56Sopenharmony_ci
20767db96d56Sopenharmony_cistatic void
20777db96d56Sopenharmony_cielementiter_dealloc(ElementIterObject *it)
20787db96d56Sopenharmony_ci{
20797db96d56Sopenharmony_ci    Py_ssize_t i = it->parent_stack_used;
20807db96d56Sopenharmony_ci    it->parent_stack_used = 0;
20817db96d56Sopenharmony_ci    /* bpo-31095: UnTrack is needed before calling any callbacks */
20827db96d56Sopenharmony_ci    PyObject_GC_UnTrack(it);
20837db96d56Sopenharmony_ci    while (i--)
20847db96d56Sopenharmony_ci        Py_XDECREF(it->parent_stack[i].parent);
20857db96d56Sopenharmony_ci    PyMem_Free(it->parent_stack);
20867db96d56Sopenharmony_ci
20877db96d56Sopenharmony_ci    Py_XDECREF(it->sought_tag);
20887db96d56Sopenharmony_ci    Py_XDECREF(it->root_element);
20897db96d56Sopenharmony_ci
20907db96d56Sopenharmony_ci    PyObject_GC_Del(it);
20917db96d56Sopenharmony_ci}
20927db96d56Sopenharmony_ci
20937db96d56Sopenharmony_cistatic int
20947db96d56Sopenharmony_cielementiter_traverse(ElementIterObject *it, visitproc visit, void *arg)
20957db96d56Sopenharmony_ci{
20967db96d56Sopenharmony_ci    Py_ssize_t i = it->parent_stack_used;
20977db96d56Sopenharmony_ci    while (i--)
20987db96d56Sopenharmony_ci        Py_VISIT(it->parent_stack[i].parent);
20997db96d56Sopenharmony_ci
21007db96d56Sopenharmony_ci    Py_VISIT(it->root_element);
21017db96d56Sopenharmony_ci    Py_VISIT(it->sought_tag);
21027db96d56Sopenharmony_ci    return 0;
21037db96d56Sopenharmony_ci}
21047db96d56Sopenharmony_ci
21057db96d56Sopenharmony_ci/* Helper function for elementiter_next. Add a new parent to the parent stack.
21067db96d56Sopenharmony_ci */
21077db96d56Sopenharmony_cistatic int
21087db96d56Sopenharmony_ciparent_stack_push_new(ElementIterObject *it, ElementObject *parent)
21097db96d56Sopenharmony_ci{
21107db96d56Sopenharmony_ci    ParentLocator *item;
21117db96d56Sopenharmony_ci
21127db96d56Sopenharmony_ci    if (it->parent_stack_used >= it->parent_stack_size) {
21137db96d56Sopenharmony_ci        Py_ssize_t new_size = it->parent_stack_size * 2;  /* never overflow */
21147db96d56Sopenharmony_ci        ParentLocator *parent_stack = it->parent_stack;
21157db96d56Sopenharmony_ci        PyMem_Resize(parent_stack, ParentLocator, new_size);
21167db96d56Sopenharmony_ci        if (parent_stack == NULL)
21177db96d56Sopenharmony_ci            return -1;
21187db96d56Sopenharmony_ci        it->parent_stack = parent_stack;
21197db96d56Sopenharmony_ci        it->parent_stack_size = new_size;
21207db96d56Sopenharmony_ci    }
21217db96d56Sopenharmony_ci    item = it->parent_stack + it->parent_stack_used++;
21227db96d56Sopenharmony_ci    Py_INCREF(parent);
21237db96d56Sopenharmony_ci    item->parent = parent;
21247db96d56Sopenharmony_ci    item->child_index = 0;
21257db96d56Sopenharmony_ci    return 0;
21267db96d56Sopenharmony_ci}
21277db96d56Sopenharmony_ci
21287db96d56Sopenharmony_cistatic PyObject *
21297db96d56Sopenharmony_cielementiter_next(ElementIterObject *it)
21307db96d56Sopenharmony_ci{
21317db96d56Sopenharmony_ci    /* Sub-element iterator.
21327db96d56Sopenharmony_ci     *
21337db96d56Sopenharmony_ci     * A short note on gettext: this function serves both the iter() and
21347db96d56Sopenharmony_ci     * itertext() methods to avoid code duplication. However, there are a few
21357db96d56Sopenharmony_ci     * small differences in the way these iterations work. Namely:
21367db96d56Sopenharmony_ci     *   - itertext() only yields text from nodes that have it, and continues
21377db96d56Sopenharmony_ci     *     iterating when a node doesn't have text (so it doesn't return any
21387db96d56Sopenharmony_ci     *     node like iter())
21397db96d56Sopenharmony_ci     *   - itertext() also has to handle tail, after finishing with all the
21407db96d56Sopenharmony_ci     *     children of a node.
21417db96d56Sopenharmony_ci     */
21427db96d56Sopenharmony_ci    int rc;
21437db96d56Sopenharmony_ci    ElementObject *elem;
21447db96d56Sopenharmony_ci    PyObject *text;
21457db96d56Sopenharmony_ci
21467db96d56Sopenharmony_ci    while (1) {
21477db96d56Sopenharmony_ci        /* Handle the case reached in the beginning and end of iteration, where
21487db96d56Sopenharmony_ci         * the parent stack is empty. If root_element is NULL and we're here, the
21497db96d56Sopenharmony_ci         * iterator is exhausted.
21507db96d56Sopenharmony_ci         */
21517db96d56Sopenharmony_ci        if (!it->parent_stack_used) {
21527db96d56Sopenharmony_ci            if (!it->root_element) {
21537db96d56Sopenharmony_ci                PyErr_SetNone(PyExc_StopIteration);
21547db96d56Sopenharmony_ci                return NULL;
21557db96d56Sopenharmony_ci            }
21567db96d56Sopenharmony_ci
21577db96d56Sopenharmony_ci            elem = it->root_element;  /* steals a reference */
21587db96d56Sopenharmony_ci            it->root_element = NULL;
21597db96d56Sopenharmony_ci        }
21607db96d56Sopenharmony_ci        else {
21617db96d56Sopenharmony_ci            /* See if there are children left to traverse in the current parent. If
21627db96d56Sopenharmony_ci             * yes, visit the next child. If not, pop the stack and try again.
21637db96d56Sopenharmony_ci             */
21647db96d56Sopenharmony_ci            ParentLocator *item = &it->parent_stack[it->parent_stack_used - 1];
21657db96d56Sopenharmony_ci            Py_ssize_t child_index = item->child_index;
21667db96d56Sopenharmony_ci            ElementObjectExtra *extra;
21677db96d56Sopenharmony_ci            elem = item->parent;
21687db96d56Sopenharmony_ci            extra = elem->extra;
21697db96d56Sopenharmony_ci            if (!extra || child_index >= extra->length) {
21707db96d56Sopenharmony_ci                it->parent_stack_used--;
21717db96d56Sopenharmony_ci                /* Note that extra condition on it->parent_stack_used here;
21727db96d56Sopenharmony_ci                 * this is because itertext() is supposed to only return *inner*
21737db96d56Sopenharmony_ci                 * text, not text following the element it began iteration with.
21747db96d56Sopenharmony_ci                 */
21757db96d56Sopenharmony_ci                if (it->gettext && it->parent_stack_used) {
21767db96d56Sopenharmony_ci                    text = element_get_tail(elem);
21777db96d56Sopenharmony_ci                    goto gettext;
21787db96d56Sopenharmony_ci                }
21797db96d56Sopenharmony_ci                Py_DECREF(elem);
21807db96d56Sopenharmony_ci                continue;
21817db96d56Sopenharmony_ci            }
21827db96d56Sopenharmony_ci
21837db96d56Sopenharmony_ci            assert(Element_Check(extra->children[child_index]));
21847db96d56Sopenharmony_ci            elem = (ElementObject *)extra->children[child_index];
21857db96d56Sopenharmony_ci            item->child_index++;
21867db96d56Sopenharmony_ci            Py_INCREF(elem);
21877db96d56Sopenharmony_ci        }
21887db96d56Sopenharmony_ci
21897db96d56Sopenharmony_ci        if (parent_stack_push_new(it, elem) < 0) {
21907db96d56Sopenharmony_ci            Py_DECREF(elem);
21917db96d56Sopenharmony_ci            PyErr_NoMemory();
21927db96d56Sopenharmony_ci            return NULL;
21937db96d56Sopenharmony_ci        }
21947db96d56Sopenharmony_ci        if (it->gettext) {
21957db96d56Sopenharmony_ci            text = element_get_text(elem);
21967db96d56Sopenharmony_ci            goto gettext;
21977db96d56Sopenharmony_ci        }
21987db96d56Sopenharmony_ci
21997db96d56Sopenharmony_ci        if (it->sought_tag == Py_None)
22007db96d56Sopenharmony_ci            return (PyObject *)elem;
22017db96d56Sopenharmony_ci
22027db96d56Sopenharmony_ci        rc = PyObject_RichCompareBool(elem->tag, it->sought_tag, Py_EQ);
22037db96d56Sopenharmony_ci        if (rc > 0)
22047db96d56Sopenharmony_ci            return (PyObject *)elem;
22057db96d56Sopenharmony_ci
22067db96d56Sopenharmony_ci        Py_DECREF(elem);
22077db96d56Sopenharmony_ci        if (rc < 0)
22087db96d56Sopenharmony_ci            return NULL;
22097db96d56Sopenharmony_ci        continue;
22107db96d56Sopenharmony_ci
22117db96d56Sopenharmony_cigettext:
22127db96d56Sopenharmony_ci        if (!text) {
22137db96d56Sopenharmony_ci            Py_DECREF(elem);
22147db96d56Sopenharmony_ci            return NULL;
22157db96d56Sopenharmony_ci        }
22167db96d56Sopenharmony_ci        if (text == Py_None) {
22177db96d56Sopenharmony_ci            Py_DECREF(elem);
22187db96d56Sopenharmony_ci        }
22197db96d56Sopenharmony_ci        else {
22207db96d56Sopenharmony_ci            Py_INCREF(text);
22217db96d56Sopenharmony_ci            Py_DECREF(elem);
22227db96d56Sopenharmony_ci            rc = PyObject_IsTrue(text);
22237db96d56Sopenharmony_ci            if (rc > 0)
22247db96d56Sopenharmony_ci                return text;
22257db96d56Sopenharmony_ci            Py_DECREF(text);
22267db96d56Sopenharmony_ci            if (rc < 0)
22277db96d56Sopenharmony_ci                return NULL;
22287db96d56Sopenharmony_ci        }
22297db96d56Sopenharmony_ci    }
22307db96d56Sopenharmony_ci
22317db96d56Sopenharmony_ci    return NULL;
22327db96d56Sopenharmony_ci}
22337db96d56Sopenharmony_ci
22347db96d56Sopenharmony_ci
22357db96d56Sopenharmony_cistatic PyTypeObject ElementIter_Type = {
22367db96d56Sopenharmony_ci    PyVarObject_HEAD_INIT(NULL, 0)
22377db96d56Sopenharmony_ci    /* Using the module's name since the pure-Python implementation does not
22387db96d56Sopenharmony_ci       have such a type. */
22397db96d56Sopenharmony_ci    "_elementtree._element_iterator",           /* tp_name */
22407db96d56Sopenharmony_ci    sizeof(ElementIterObject),                  /* tp_basicsize */
22417db96d56Sopenharmony_ci    0,                                          /* tp_itemsize */
22427db96d56Sopenharmony_ci    /* methods */
22437db96d56Sopenharmony_ci    (destructor)elementiter_dealloc,            /* tp_dealloc */
22447db96d56Sopenharmony_ci    0,                                          /* tp_vectorcall_offset */
22457db96d56Sopenharmony_ci    0,                                          /* tp_getattr */
22467db96d56Sopenharmony_ci    0,                                          /* tp_setattr */
22477db96d56Sopenharmony_ci    0,                                          /* tp_as_async */
22487db96d56Sopenharmony_ci    0,                                          /* tp_repr */
22497db96d56Sopenharmony_ci    0,                                          /* tp_as_number */
22507db96d56Sopenharmony_ci    0,                                          /* tp_as_sequence */
22517db96d56Sopenharmony_ci    0,                                          /* tp_as_mapping */
22527db96d56Sopenharmony_ci    0,                                          /* tp_hash */
22537db96d56Sopenharmony_ci    0,                                          /* tp_call */
22547db96d56Sopenharmony_ci    0,                                          /* tp_str */
22557db96d56Sopenharmony_ci    0,                                          /* tp_getattro */
22567db96d56Sopenharmony_ci    0,                                          /* tp_setattro */
22577db96d56Sopenharmony_ci    0,                                          /* tp_as_buffer */
22587db96d56Sopenharmony_ci    Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC,    /* tp_flags */
22597db96d56Sopenharmony_ci    0,                                          /* tp_doc */
22607db96d56Sopenharmony_ci    (traverseproc)elementiter_traverse,         /* tp_traverse */
22617db96d56Sopenharmony_ci    0,                                          /* tp_clear */
22627db96d56Sopenharmony_ci    0,                                          /* tp_richcompare */
22637db96d56Sopenharmony_ci    0,                                          /* tp_weaklistoffset */
22647db96d56Sopenharmony_ci    PyObject_SelfIter,                          /* tp_iter */
22657db96d56Sopenharmony_ci    (iternextfunc)elementiter_next,             /* tp_iternext */
22667db96d56Sopenharmony_ci    0,                                          /* tp_methods */
22677db96d56Sopenharmony_ci    0,                                          /* tp_members */
22687db96d56Sopenharmony_ci    0,                                          /* tp_getset */
22697db96d56Sopenharmony_ci    0,                                          /* tp_base */
22707db96d56Sopenharmony_ci    0,                                          /* tp_dict */
22717db96d56Sopenharmony_ci    0,                                          /* tp_descr_get */
22727db96d56Sopenharmony_ci    0,                                          /* tp_descr_set */
22737db96d56Sopenharmony_ci    0,                                          /* tp_dictoffset */
22747db96d56Sopenharmony_ci    0,                                          /* tp_init */
22757db96d56Sopenharmony_ci    0,                                          /* tp_alloc */
22767db96d56Sopenharmony_ci    0,                                          /* tp_new */
22777db96d56Sopenharmony_ci};
22787db96d56Sopenharmony_ci
22797db96d56Sopenharmony_ci#define INIT_PARENT_STACK_SIZE 8
22807db96d56Sopenharmony_ci
22817db96d56Sopenharmony_cistatic PyObject *
22827db96d56Sopenharmony_cicreate_elementiter(ElementObject *self, PyObject *tag, int gettext)
22837db96d56Sopenharmony_ci{
22847db96d56Sopenharmony_ci    ElementIterObject *it;
22857db96d56Sopenharmony_ci
22867db96d56Sopenharmony_ci    it = PyObject_GC_New(ElementIterObject, &ElementIter_Type);
22877db96d56Sopenharmony_ci    if (!it)
22887db96d56Sopenharmony_ci        return NULL;
22897db96d56Sopenharmony_ci
22907db96d56Sopenharmony_ci    Py_INCREF(tag);
22917db96d56Sopenharmony_ci    it->sought_tag = tag;
22927db96d56Sopenharmony_ci    it->gettext = gettext;
22937db96d56Sopenharmony_ci    Py_INCREF(self);
22947db96d56Sopenharmony_ci    it->root_element = self;
22957db96d56Sopenharmony_ci
22967db96d56Sopenharmony_ci    it->parent_stack = PyMem_New(ParentLocator, INIT_PARENT_STACK_SIZE);
22977db96d56Sopenharmony_ci    if (it->parent_stack == NULL) {
22987db96d56Sopenharmony_ci        Py_DECREF(it);
22997db96d56Sopenharmony_ci        PyErr_NoMemory();
23007db96d56Sopenharmony_ci        return NULL;
23017db96d56Sopenharmony_ci    }
23027db96d56Sopenharmony_ci    it->parent_stack_used = 0;
23037db96d56Sopenharmony_ci    it->parent_stack_size = INIT_PARENT_STACK_SIZE;
23047db96d56Sopenharmony_ci
23057db96d56Sopenharmony_ci    PyObject_GC_Track(it);
23067db96d56Sopenharmony_ci
23077db96d56Sopenharmony_ci    return (PyObject *)it;
23087db96d56Sopenharmony_ci}
23097db96d56Sopenharmony_ci
23107db96d56Sopenharmony_ci
23117db96d56Sopenharmony_ci/* ==================================================================== */
23127db96d56Sopenharmony_ci/* the tree builder type */
23137db96d56Sopenharmony_ci
23147db96d56Sopenharmony_citypedef struct {
23157db96d56Sopenharmony_ci    PyObject_HEAD
23167db96d56Sopenharmony_ci
23177db96d56Sopenharmony_ci    PyObject *root; /* root node (first created node) */
23187db96d56Sopenharmony_ci
23197db96d56Sopenharmony_ci    PyObject *this; /* current node */
23207db96d56Sopenharmony_ci    PyObject *last; /* most recently created node */
23217db96d56Sopenharmony_ci    PyObject *last_for_tail; /* most recently created node that takes a tail */
23227db96d56Sopenharmony_ci
23237db96d56Sopenharmony_ci    PyObject *data; /* data collector (string or list), or NULL */
23247db96d56Sopenharmony_ci
23257db96d56Sopenharmony_ci    PyObject *stack; /* element stack */
23267db96d56Sopenharmony_ci    Py_ssize_t index; /* current stack size (0 means empty) */
23277db96d56Sopenharmony_ci
23287db96d56Sopenharmony_ci    PyObject *element_factory;
23297db96d56Sopenharmony_ci    PyObject *comment_factory;
23307db96d56Sopenharmony_ci    PyObject *pi_factory;
23317db96d56Sopenharmony_ci
23327db96d56Sopenharmony_ci    /* element tracing */
23337db96d56Sopenharmony_ci    PyObject *events_append; /* the append method of the list of events, or NULL */
23347db96d56Sopenharmony_ci    PyObject *start_event_obj; /* event objects (NULL to ignore) */
23357db96d56Sopenharmony_ci    PyObject *end_event_obj;
23367db96d56Sopenharmony_ci    PyObject *start_ns_event_obj;
23377db96d56Sopenharmony_ci    PyObject *end_ns_event_obj;
23387db96d56Sopenharmony_ci    PyObject *comment_event_obj;
23397db96d56Sopenharmony_ci    PyObject *pi_event_obj;
23407db96d56Sopenharmony_ci
23417db96d56Sopenharmony_ci    char insert_comments;
23427db96d56Sopenharmony_ci    char insert_pis;
23437db96d56Sopenharmony_ci} TreeBuilderObject;
23447db96d56Sopenharmony_ci
23457db96d56Sopenharmony_ci#define TreeBuilder_CheckExact(op) Py_IS_TYPE((op), &TreeBuilder_Type)
23467db96d56Sopenharmony_ci
23477db96d56Sopenharmony_ci/* -------------------------------------------------------------------- */
23487db96d56Sopenharmony_ci/* constructor and destructor */
23497db96d56Sopenharmony_ci
23507db96d56Sopenharmony_cistatic PyObject *
23517db96d56Sopenharmony_citreebuilder_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
23527db96d56Sopenharmony_ci{
23537db96d56Sopenharmony_ci    TreeBuilderObject *t = (TreeBuilderObject *)type->tp_alloc(type, 0);
23547db96d56Sopenharmony_ci    if (t != NULL) {
23557db96d56Sopenharmony_ci        t->root = NULL;
23567db96d56Sopenharmony_ci
23577db96d56Sopenharmony_ci        Py_INCREF(Py_None);
23587db96d56Sopenharmony_ci        t->this = Py_None;
23597db96d56Sopenharmony_ci        Py_INCREF(Py_None);
23607db96d56Sopenharmony_ci        t->last = Py_None;
23617db96d56Sopenharmony_ci
23627db96d56Sopenharmony_ci        t->data = NULL;
23637db96d56Sopenharmony_ci        t->element_factory = NULL;
23647db96d56Sopenharmony_ci        t->comment_factory = NULL;
23657db96d56Sopenharmony_ci        t->pi_factory = NULL;
23667db96d56Sopenharmony_ci        t->stack = PyList_New(20);
23677db96d56Sopenharmony_ci        if (!t->stack) {
23687db96d56Sopenharmony_ci            Py_DECREF(t->this);
23697db96d56Sopenharmony_ci            Py_DECREF(t->last);
23707db96d56Sopenharmony_ci            Py_DECREF((PyObject *) t);
23717db96d56Sopenharmony_ci            return NULL;
23727db96d56Sopenharmony_ci        }
23737db96d56Sopenharmony_ci        t->index = 0;
23747db96d56Sopenharmony_ci
23757db96d56Sopenharmony_ci        t->events_append = NULL;
23767db96d56Sopenharmony_ci        t->start_event_obj = t->end_event_obj = NULL;
23777db96d56Sopenharmony_ci        t->start_ns_event_obj = t->end_ns_event_obj = NULL;
23787db96d56Sopenharmony_ci        t->comment_event_obj = t->pi_event_obj = NULL;
23797db96d56Sopenharmony_ci        t->insert_comments = t->insert_pis = 0;
23807db96d56Sopenharmony_ci    }
23817db96d56Sopenharmony_ci    return (PyObject *)t;
23827db96d56Sopenharmony_ci}
23837db96d56Sopenharmony_ci
23847db96d56Sopenharmony_ci/*[clinic input]
23857db96d56Sopenharmony_ci_elementtree.TreeBuilder.__init__
23867db96d56Sopenharmony_ci
23877db96d56Sopenharmony_ci    element_factory: object = None
23887db96d56Sopenharmony_ci    *
23897db96d56Sopenharmony_ci    comment_factory: object = None
23907db96d56Sopenharmony_ci    pi_factory: object = None
23917db96d56Sopenharmony_ci    insert_comments: bool = False
23927db96d56Sopenharmony_ci    insert_pis: bool = False
23937db96d56Sopenharmony_ci
23947db96d56Sopenharmony_ci[clinic start generated code]*/
23957db96d56Sopenharmony_ci
23967db96d56Sopenharmony_cistatic int
23977db96d56Sopenharmony_ci_elementtree_TreeBuilder___init___impl(TreeBuilderObject *self,
23987db96d56Sopenharmony_ci                                       PyObject *element_factory,
23997db96d56Sopenharmony_ci                                       PyObject *comment_factory,
24007db96d56Sopenharmony_ci                                       PyObject *pi_factory,
24017db96d56Sopenharmony_ci                                       int insert_comments, int insert_pis)
24027db96d56Sopenharmony_ci/*[clinic end generated code: output=8571d4dcadfdf952 input=ae98a94df20b5cc3]*/
24037db96d56Sopenharmony_ci{
24047db96d56Sopenharmony_ci    if (element_factory != Py_None) {
24057db96d56Sopenharmony_ci        Py_INCREF(element_factory);
24067db96d56Sopenharmony_ci        Py_XSETREF(self->element_factory, element_factory);
24077db96d56Sopenharmony_ci    } else {
24087db96d56Sopenharmony_ci        Py_CLEAR(self->element_factory);
24097db96d56Sopenharmony_ci    }
24107db96d56Sopenharmony_ci
24117db96d56Sopenharmony_ci    if (comment_factory == Py_None) {
24127db96d56Sopenharmony_ci        elementtreestate *st = ET_STATE_GLOBAL;
24137db96d56Sopenharmony_ci        comment_factory = st->comment_factory;
24147db96d56Sopenharmony_ci    }
24157db96d56Sopenharmony_ci    if (comment_factory) {
24167db96d56Sopenharmony_ci        Py_INCREF(comment_factory);
24177db96d56Sopenharmony_ci        Py_XSETREF(self->comment_factory, comment_factory);
24187db96d56Sopenharmony_ci        self->insert_comments = insert_comments;
24197db96d56Sopenharmony_ci    } else {
24207db96d56Sopenharmony_ci        Py_CLEAR(self->comment_factory);
24217db96d56Sopenharmony_ci        self->insert_comments = 0;
24227db96d56Sopenharmony_ci    }
24237db96d56Sopenharmony_ci
24247db96d56Sopenharmony_ci    if (pi_factory == Py_None) {
24257db96d56Sopenharmony_ci        elementtreestate *st = ET_STATE_GLOBAL;
24267db96d56Sopenharmony_ci        pi_factory = st->pi_factory;
24277db96d56Sopenharmony_ci    }
24287db96d56Sopenharmony_ci    if (pi_factory) {
24297db96d56Sopenharmony_ci        Py_INCREF(pi_factory);
24307db96d56Sopenharmony_ci        Py_XSETREF(self->pi_factory, pi_factory);
24317db96d56Sopenharmony_ci        self->insert_pis = insert_pis;
24327db96d56Sopenharmony_ci    } else {
24337db96d56Sopenharmony_ci        Py_CLEAR(self->pi_factory);
24347db96d56Sopenharmony_ci        self->insert_pis = 0;
24357db96d56Sopenharmony_ci    }
24367db96d56Sopenharmony_ci
24377db96d56Sopenharmony_ci    return 0;
24387db96d56Sopenharmony_ci}
24397db96d56Sopenharmony_ci
24407db96d56Sopenharmony_cistatic int
24417db96d56Sopenharmony_citreebuilder_gc_traverse(TreeBuilderObject *self, visitproc visit, void *arg)
24427db96d56Sopenharmony_ci{
24437db96d56Sopenharmony_ci    Py_VISIT(self->pi_event_obj);
24447db96d56Sopenharmony_ci    Py_VISIT(self->comment_event_obj);
24457db96d56Sopenharmony_ci    Py_VISIT(self->end_ns_event_obj);
24467db96d56Sopenharmony_ci    Py_VISIT(self->start_ns_event_obj);
24477db96d56Sopenharmony_ci    Py_VISIT(self->end_event_obj);
24487db96d56Sopenharmony_ci    Py_VISIT(self->start_event_obj);
24497db96d56Sopenharmony_ci    Py_VISIT(self->events_append);
24507db96d56Sopenharmony_ci    Py_VISIT(self->root);
24517db96d56Sopenharmony_ci    Py_VISIT(self->this);
24527db96d56Sopenharmony_ci    Py_VISIT(self->last);
24537db96d56Sopenharmony_ci    Py_VISIT(self->last_for_tail);
24547db96d56Sopenharmony_ci    Py_VISIT(self->data);
24557db96d56Sopenharmony_ci    Py_VISIT(self->stack);
24567db96d56Sopenharmony_ci    Py_VISIT(self->pi_factory);
24577db96d56Sopenharmony_ci    Py_VISIT(self->comment_factory);
24587db96d56Sopenharmony_ci    Py_VISIT(self->element_factory);
24597db96d56Sopenharmony_ci    return 0;
24607db96d56Sopenharmony_ci}
24617db96d56Sopenharmony_ci
24627db96d56Sopenharmony_cistatic int
24637db96d56Sopenharmony_citreebuilder_gc_clear(TreeBuilderObject *self)
24647db96d56Sopenharmony_ci{
24657db96d56Sopenharmony_ci    Py_CLEAR(self->pi_event_obj);
24667db96d56Sopenharmony_ci    Py_CLEAR(self->comment_event_obj);
24677db96d56Sopenharmony_ci    Py_CLEAR(self->end_ns_event_obj);
24687db96d56Sopenharmony_ci    Py_CLEAR(self->start_ns_event_obj);
24697db96d56Sopenharmony_ci    Py_CLEAR(self->end_event_obj);
24707db96d56Sopenharmony_ci    Py_CLEAR(self->start_event_obj);
24717db96d56Sopenharmony_ci    Py_CLEAR(self->events_append);
24727db96d56Sopenharmony_ci    Py_CLEAR(self->stack);
24737db96d56Sopenharmony_ci    Py_CLEAR(self->data);
24747db96d56Sopenharmony_ci    Py_CLEAR(self->last);
24757db96d56Sopenharmony_ci    Py_CLEAR(self->last_for_tail);
24767db96d56Sopenharmony_ci    Py_CLEAR(self->this);
24777db96d56Sopenharmony_ci    Py_CLEAR(self->pi_factory);
24787db96d56Sopenharmony_ci    Py_CLEAR(self->comment_factory);
24797db96d56Sopenharmony_ci    Py_CLEAR(self->element_factory);
24807db96d56Sopenharmony_ci    Py_CLEAR(self->root);
24817db96d56Sopenharmony_ci    return 0;
24827db96d56Sopenharmony_ci}
24837db96d56Sopenharmony_ci
24847db96d56Sopenharmony_cistatic void
24857db96d56Sopenharmony_citreebuilder_dealloc(TreeBuilderObject *self)
24867db96d56Sopenharmony_ci{
24877db96d56Sopenharmony_ci    PyObject_GC_UnTrack(self);
24887db96d56Sopenharmony_ci    treebuilder_gc_clear(self);
24897db96d56Sopenharmony_ci    Py_TYPE(self)->tp_free((PyObject *)self);
24907db96d56Sopenharmony_ci}
24917db96d56Sopenharmony_ci
24927db96d56Sopenharmony_ci/* -------------------------------------------------------------------- */
24937db96d56Sopenharmony_ci/* helpers for handling of arbitrary element-like objects */
24947db96d56Sopenharmony_ci
24957db96d56Sopenharmony_ci/*[clinic input]
24967db96d56Sopenharmony_ci_elementtree._set_factories
24977db96d56Sopenharmony_ci
24987db96d56Sopenharmony_ci    comment_factory: object
24997db96d56Sopenharmony_ci    pi_factory: object
25007db96d56Sopenharmony_ci    /
25017db96d56Sopenharmony_ci
25027db96d56Sopenharmony_ciChange the factories used to create comments and processing instructions.
25037db96d56Sopenharmony_ci
25047db96d56Sopenharmony_ciFor internal use only.
25057db96d56Sopenharmony_ci[clinic start generated code]*/
25067db96d56Sopenharmony_ci
25077db96d56Sopenharmony_cistatic PyObject *
25087db96d56Sopenharmony_ci_elementtree__set_factories_impl(PyObject *module, PyObject *comment_factory,
25097db96d56Sopenharmony_ci                                 PyObject *pi_factory)
25107db96d56Sopenharmony_ci/*[clinic end generated code: output=813b408adee26535 input=99d17627aea7fb3b]*/
25117db96d56Sopenharmony_ci{
25127db96d56Sopenharmony_ci    elementtreestate *st = ET_STATE_GLOBAL;
25137db96d56Sopenharmony_ci    PyObject *old;
25147db96d56Sopenharmony_ci
25157db96d56Sopenharmony_ci    if (!PyCallable_Check(comment_factory) && comment_factory != Py_None) {
25167db96d56Sopenharmony_ci        PyErr_Format(PyExc_TypeError, "Comment factory must be callable, not %.100s",
25177db96d56Sopenharmony_ci                     Py_TYPE(comment_factory)->tp_name);
25187db96d56Sopenharmony_ci        return NULL;
25197db96d56Sopenharmony_ci    }
25207db96d56Sopenharmony_ci    if (!PyCallable_Check(pi_factory) && pi_factory != Py_None) {
25217db96d56Sopenharmony_ci        PyErr_Format(PyExc_TypeError, "PI factory must be callable, not %.100s",
25227db96d56Sopenharmony_ci                     Py_TYPE(pi_factory)->tp_name);
25237db96d56Sopenharmony_ci        return NULL;
25247db96d56Sopenharmony_ci    }
25257db96d56Sopenharmony_ci
25267db96d56Sopenharmony_ci    old = PyTuple_Pack(2,
25277db96d56Sopenharmony_ci        st->comment_factory ? st->comment_factory : Py_None,
25287db96d56Sopenharmony_ci        st->pi_factory ? st->pi_factory : Py_None);
25297db96d56Sopenharmony_ci
25307db96d56Sopenharmony_ci    if (comment_factory == Py_None) {
25317db96d56Sopenharmony_ci        Py_CLEAR(st->comment_factory);
25327db96d56Sopenharmony_ci    } else {
25337db96d56Sopenharmony_ci        Py_INCREF(comment_factory);
25347db96d56Sopenharmony_ci        Py_XSETREF(st->comment_factory, comment_factory);
25357db96d56Sopenharmony_ci    }
25367db96d56Sopenharmony_ci    if (pi_factory == Py_None) {
25377db96d56Sopenharmony_ci        Py_CLEAR(st->pi_factory);
25387db96d56Sopenharmony_ci    } else {
25397db96d56Sopenharmony_ci        Py_INCREF(pi_factory);
25407db96d56Sopenharmony_ci        Py_XSETREF(st->pi_factory, pi_factory);
25417db96d56Sopenharmony_ci    }
25427db96d56Sopenharmony_ci
25437db96d56Sopenharmony_ci    return old;
25447db96d56Sopenharmony_ci}
25457db96d56Sopenharmony_ci
25467db96d56Sopenharmony_cistatic int
25477db96d56Sopenharmony_citreebuilder_extend_element_text_or_tail(PyObject *element, PyObject **data,
25487db96d56Sopenharmony_ci                                        PyObject **dest, _Py_Identifier *name)
25497db96d56Sopenharmony_ci{
25507db96d56Sopenharmony_ci    /* Fast paths for the "almost always" cases. */
25517db96d56Sopenharmony_ci    if (Element_CheckExact(element)) {
25527db96d56Sopenharmony_ci        PyObject *dest_obj = JOIN_OBJ(*dest);
25537db96d56Sopenharmony_ci        if (dest_obj == Py_None) {
25547db96d56Sopenharmony_ci            *dest = JOIN_SET(*data, PyList_CheckExact(*data));
25557db96d56Sopenharmony_ci            *data = NULL;
25567db96d56Sopenharmony_ci            Py_DECREF(dest_obj);
25577db96d56Sopenharmony_ci            return 0;
25587db96d56Sopenharmony_ci        }
25597db96d56Sopenharmony_ci        else if (JOIN_GET(*dest)) {
25607db96d56Sopenharmony_ci            if (PyList_SetSlice(dest_obj, PY_SSIZE_T_MAX, PY_SSIZE_T_MAX, *data) < 0) {
25617db96d56Sopenharmony_ci                return -1;
25627db96d56Sopenharmony_ci            }
25637db96d56Sopenharmony_ci            Py_CLEAR(*data);
25647db96d56Sopenharmony_ci            return 0;
25657db96d56Sopenharmony_ci        }
25667db96d56Sopenharmony_ci    }
25677db96d56Sopenharmony_ci
25687db96d56Sopenharmony_ci    /*  Fallback for the non-Element / non-trivial cases. */
25697db96d56Sopenharmony_ci    {
25707db96d56Sopenharmony_ci        int r;
25717db96d56Sopenharmony_ci        PyObject* joined;
25727db96d56Sopenharmony_ci        PyObject* previous = _PyObject_GetAttrId(element, name);
25737db96d56Sopenharmony_ci        if (!previous)
25747db96d56Sopenharmony_ci            return -1;
25757db96d56Sopenharmony_ci        joined = list_join(*data);
25767db96d56Sopenharmony_ci        if (!joined) {
25777db96d56Sopenharmony_ci            Py_DECREF(previous);
25787db96d56Sopenharmony_ci            return -1;
25797db96d56Sopenharmony_ci        }
25807db96d56Sopenharmony_ci        if (previous != Py_None) {
25817db96d56Sopenharmony_ci            PyObject *tmp = PyNumber_Add(previous, joined);
25827db96d56Sopenharmony_ci            Py_DECREF(joined);
25837db96d56Sopenharmony_ci            Py_DECREF(previous);
25847db96d56Sopenharmony_ci            if (!tmp)
25857db96d56Sopenharmony_ci                return -1;
25867db96d56Sopenharmony_ci            joined = tmp;
25877db96d56Sopenharmony_ci        } else {
25887db96d56Sopenharmony_ci            Py_DECREF(previous);
25897db96d56Sopenharmony_ci        }
25907db96d56Sopenharmony_ci
25917db96d56Sopenharmony_ci        r = _PyObject_SetAttrId(element, name, joined);
25927db96d56Sopenharmony_ci        Py_DECREF(joined);
25937db96d56Sopenharmony_ci        if (r < 0)
25947db96d56Sopenharmony_ci            return -1;
25957db96d56Sopenharmony_ci        Py_CLEAR(*data);
25967db96d56Sopenharmony_ci        return 0;
25977db96d56Sopenharmony_ci    }
25987db96d56Sopenharmony_ci}
25997db96d56Sopenharmony_ci
26007db96d56Sopenharmony_ciLOCAL(int)
26017db96d56Sopenharmony_citreebuilder_flush_data(TreeBuilderObject* self)
26027db96d56Sopenharmony_ci{
26037db96d56Sopenharmony_ci    if (!self->data) {
26047db96d56Sopenharmony_ci        return 0;
26057db96d56Sopenharmony_ci    }
26067db96d56Sopenharmony_ci
26077db96d56Sopenharmony_ci    if (!self->last_for_tail) {
26087db96d56Sopenharmony_ci        PyObject *element = self->last;
26097db96d56Sopenharmony_ci        _Py_IDENTIFIER(text);
26107db96d56Sopenharmony_ci        return treebuilder_extend_element_text_or_tail(
26117db96d56Sopenharmony_ci                element, &self->data,
26127db96d56Sopenharmony_ci                &((ElementObject *) element)->text, &PyId_text);
26137db96d56Sopenharmony_ci    }
26147db96d56Sopenharmony_ci    else {
26157db96d56Sopenharmony_ci        PyObject *element = self->last_for_tail;
26167db96d56Sopenharmony_ci        _Py_IDENTIFIER(tail);
26177db96d56Sopenharmony_ci        return treebuilder_extend_element_text_or_tail(
26187db96d56Sopenharmony_ci                element, &self->data,
26197db96d56Sopenharmony_ci                &((ElementObject *) element)->tail, &PyId_tail);
26207db96d56Sopenharmony_ci    }
26217db96d56Sopenharmony_ci}
26227db96d56Sopenharmony_ci
26237db96d56Sopenharmony_cistatic int
26247db96d56Sopenharmony_citreebuilder_add_subelement(PyObject *element, PyObject *child)
26257db96d56Sopenharmony_ci{
26267db96d56Sopenharmony_ci    _Py_IDENTIFIER(append);
26277db96d56Sopenharmony_ci    if (Element_CheckExact(element)) {
26287db96d56Sopenharmony_ci        ElementObject *elem = (ElementObject *) element;
26297db96d56Sopenharmony_ci        return element_add_subelement(elem, child);
26307db96d56Sopenharmony_ci    }
26317db96d56Sopenharmony_ci    else {
26327db96d56Sopenharmony_ci        PyObject *res;
26337db96d56Sopenharmony_ci        res = _PyObject_CallMethodIdOneArg(element, &PyId_append, child);
26347db96d56Sopenharmony_ci        if (res == NULL)
26357db96d56Sopenharmony_ci            return -1;
26367db96d56Sopenharmony_ci        Py_DECREF(res);
26377db96d56Sopenharmony_ci        return 0;
26387db96d56Sopenharmony_ci    }
26397db96d56Sopenharmony_ci}
26407db96d56Sopenharmony_ci
26417db96d56Sopenharmony_ciLOCAL(int)
26427db96d56Sopenharmony_citreebuilder_append_event(TreeBuilderObject *self, PyObject *action,
26437db96d56Sopenharmony_ci                         PyObject *node)
26447db96d56Sopenharmony_ci{
26457db96d56Sopenharmony_ci    if (action != NULL) {
26467db96d56Sopenharmony_ci        PyObject *res;
26477db96d56Sopenharmony_ci        PyObject *event = PyTuple_Pack(2, action, node);
26487db96d56Sopenharmony_ci        if (event == NULL)
26497db96d56Sopenharmony_ci            return -1;
26507db96d56Sopenharmony_ci        res = PyObject_CallOneArg(self->events_append, event);
26517db96d56Sopenharmony_ci        Py_DECREF(event);
26527db96d56Sopenharmony_ci        if (res == NULL)
26537db96d56Sopenharmony_ci            return -1;
26547db96d56Sopenharmony_ci        Py_DECREF(res);
26557db96d56Sopenharmony_ci    }
26567db96d56Sopenharmony_ci    return 0;
26577db96d56Sopenharmony_ci}
26587db96d56Sopenharmony_ci
26597db96d56Sopenharmony_ci/* -------------------------------------------------------------------- */
26607db96d56Sopenharmony_ci/* handlers */
26617db96d56Sopenharmony_ci
26627db96d56Sopenharmony_ciLOCAL(PyObject*)
26637db96d56Sopenharmony_citreebuilder_handle_start(TreeBuilderObject* self, PyObject* tag,
26647db96d56Sopenharmony_ci                         PyObject* attrib)
26657db96d56Sopenharmony_ci{
26667db96d56Sopenharmony_ci    PyObject* node;
26677db96d56Sopenharmony_ci    PyObject* this;
26687db96d56Sopenharmony_ci    elementtreestate *st = ET_STATE_GLOBAL;
26697db96d56Sopenharmony_ci
26707db96d56Sopenharmony_ci    if (treebuilder_flush_data(self) < 0) {
26717db96d56Sopenharmony_ci        return NULL;
26727db96d56Sopenharmony_ci    }
26737db96d56Sopenharmony_ci
26747db96d56Sopenharmony_ci    if (!self->element_factory) {
26757db96d56Sopenharmony_ci        node = create_new_element(tag, attrib);
26767db96d56Sopenharmony_ci    } else if (attrib == NULL) {
26777db96d56Sopenharmony_ci        attrib = PyDict_New();
26787db96d56Sopenharmony_ci        if (!attrib)
26797db96d56Sopenharmony_ci            return NULL;
26807db96d56Sopenharmony_ci        node = PyObject_CallFunctionObjArgs(self->element_factory,
26817db96d56Sopenharmony_ci                                            tag, attrib, NULL);
26827db96d56Sopenharmony_ci        Py_DECREF(attrib);
26837db96d56Sopenharmony_ci    }
26847db96d56Sopenharmony_ci    else {
26857db96d56Sopenharmony_ci        node = PyObject_CallFunctionObjArgs(self->element_factory,
26867db96d56Sopenharmony_ci                                            tag, attrib, NULL);
26877db96d56Sopenharmony_ci    }
26887db96d56Sopenharmony_ci    if (!node) {
26897db96d56Sopenharmony_ci        return NULL;
26907db96d56Sopenharmony_ci    }
26917db96d56Sopenharmony_ci
26927db96d56Sopenharmony_ci    this = self->this;
26937db96d56Sopenharmony_ci    Py_CLEAR(self->last_for_tail);
26947db96d56Sopenharmony_ci
26957db96d56Sopenharmony_ci    if (this != Py_None) {
26967db96d56Sopenharmony_ci        if (treebuilder_add_subelement(this, node) < 0)
26977db96d56Sopenharmony_ci            goto error;
26987db96d56Sopenharmony_ci    } else {
26997db96d56Sopenharmony_ci        if (self->root) {
27007db96d56Sopenharmony_ci            PyErr_SetString(
27017db96d56Sopenharmony_ci                st->parseerror_obj,
27027db96d56Sopenharmony_ci                "multiple elements on top level"
27037db96d56Sopenharmony_ci                );
27047db96d56Sopenharmony_ci            goto error;
27057db96d56Sopenharmony_ci        }
27067db96d56Sopenharmony_ci        Py_INCREF(node);
27077db96d56Sopenharmony_ci        self->root = node;
27087db96d56Sopenharmony_ci    }
27097db96d56Sopenharmony_ci
27107db96d56Sopenharmony_ci    if (self->index < PyList_GET_SIZE(self->stack)) {
27117db96d56Sopenharmony_ci        if (PyList_SetItem(self->stack, self->index, this) < 0)
27127db96d56Sopenharmony_ci            goto error;
27137db96d56Sopenharmony_ci        Py_INCREF(this);
27147db96d56Sopenharmony_ci    } else {
27157db96d56Sopenharmony_ci        if (PyList_Append(self->stack, this) < 0)
27167db96d56Sopenharmony_ci            goto error;
27177db96d56Sopenharmony_ci    }
27187db96d56Sopenharmony_ci    self->index++;
27197db96d56Sopenharmony_ci
27207db96d56Sopenharmony_ci    Py_INCREF(node);
27217db96d56Sopenharmony_ci    Py_SETREF(self->this, node);
27227db96d56Sopenharmony_ci    Py_INCREF(node);
27237db96d56Sopenharmony_ci    Py_SETREF(self->last, node);
27247db96d56Sopenharmony_ci
27257db96d56Sopenharmony_ci    if (treebuilder_append_event(self, self->start_event_obj, node) < 0)
27267db96d56Sopenharmony_ci        goto error;
27277db96d56Sopenharmony_ci
27287db96d56Sopenharmony_ci    return node;
27297db96d56Sopenharmony_ci
27307db96d56Sopenharmony_ci  error:
27317db96d56Sopenharmony_ci    Py_DECREF(node);
27327db96d56Sopenharmony_ci    return NULL;
27337db96d56Sopenharmony_ci}
27347db96d56Sopenharmony_ci
27357db96d56Sopenharmony_ciLOCAL(PyObject*)
27367db96d56Sopenharmony_citreebuilder_handle_data(TreeBuilderObject* self, PyObject* data)
27377db96d56Sopenharmony_ci{
27387db96d56Sopenharmony_ci    if (!self->data) {
27397db96d56Sopenharmony_ci        if (self->last == Py_None) {
27407db96d56Sopenharmony_ci            /* ignore calls to data before the first call to start */
27417db96d56Sopenharmony_ci            Py_RETURN_NONE;
27427db96d56Sopenharmony_ci        }
27437db96d56Sopenharmony_ci        /* store the first item as is */
27447db96d56Sopenharmony_ci        Py_INCREF(data); self->data = data;
27457db96d56Sopenharmony_ci    } else {
27467db96d56Sopenharmony_ci        /* more than one item; use a list to collect items */
27477db96d56Sopenharmony_ci        if (PyBytes_CheckExact(self->data) && Py_REFCNT(self->data) == 1 &&
27487db96d56Sopenharmony_ci            PyBytes_CheckExact(data) && PyBytes_GET_SIZE(data) == 1) {
27497db96d56Sopenharmony_ci            /* XXX this code path unused in Python 3? */
27507db96d56Sopenharmony_ci            /* expat often generates single character data sections; handle
27517db96d56Sopenharmony_ci               the most common case by resizing the existing string... */
27527db96d56Sopenharmony_ci            Py_ssize_t size = PyBytes_GET_SIZE(self->data);
27537db96d56Sopenharmony_ci            if (_PyBytes_Resize(&self->data, size + 1) < 0)
27547db96d56Sopenharmony_ci                return NULL;
27557db96d56Sopenharmony_ci            PyBytes_AS_STRING(self->data)[size] = PyBytes_AS_STRING(data)[0];
27567db96d56Sopenharmony_ci        } else if (PyList_CheckExact(self->data)) {
27577db96d56Sopenharmony_ci            if (PyList_Append(self->data, data) < 0)
27587db96d56Sopenharmony_ci                return NULL;
27597db96d56Sopenharmony_ci        } else {
27607db96d56Sopenharmony_ci            PyObject* list = PyList_New(2);
27617db96d56Sopenharmony_ci            if (!list)
27627db96d56Sopenharmony_ci                return NULL;
27637db96d56Sopenharmony_ci            PyList_SET_ITEM(list, 0, self->data);
27647db96d56Sopenharmony_ci            Py_INCREF(data); PyList_SET_ITEM(list, 1, data);
27657db96d56Sopenharmony_ci            self->data = list;
27667db96d56Sopenharmony_ci        }
27677db96d56Sopenharmony_ci    }
27687db96d56Sopenharmony_ci
27697db96d56Sopenharmony_ci    Py_RETURN_NONE;
27707db96d56Sopenharmony_ci}
27717db96d56Sopenharmony_ci
27727db96d56Sopenharmony_ciLOCAL(PyObject*)
27737db96d56Sopenharmony_citreebuilder_handle_end(TreeBuilderObject* self, PyObject* tag)
27747db96d56Sopenharmony_ci{
27757db96d56Sopenharmony_ci    PyObject* item;
27767db96d56Sopenharmony_ci
27777db96d56Sopenharmony_ci    if (treebuilder_flush_data(self) < 0) {
27787db96d56Sopenharmony_ci        return NULL;
27797db96d56Sopenharmony_ci    }
27807db96d56Sopenharmony_ci
27817db96d56Sopenharmony_ci    if (self->index == 0) {
27827db96d56Sopenharmony_ci        PyErr_SetString(
27837db96d56Sopenharmony_ci            PyExc_IndexError,
27847db96d56Sopenharmony_ci            "pop from empty stack"
27857db96d56Sopenharmony_ci            );
27867db96d56Sopenharmony_ci        return NULL;
27877db96d56Sopenharmony_ci    }
27887db96d56Sopenharmony_ci
27897db96d56Sopenharmony_ci    item = self->last;
27907db96d56Sopenharmony_ci    self->last = self->this;
27917db96d56Sopenharmony_ci    Py_INCREF(self->last);
27927db96d56Sopenharmony_ci    Py_XSETREF(self->last_for_tail, self->last);
27937db96d56Sopenharmony_ci    self->index--;
27947db96d56Sopenharmony_ci    self->this = PyList_GET_ITEM(self->stack, self->index);
27957db96d56Sopenharmony_ci    Py_INCREF(self->this);
27967db96d56Sopenharmony_ci    Py_DECREF(item);
27977db96d56Sopenharmony_ci
27987db96d56Sopenharmony_ci    if (treebuilder_append_event(self, self->end_event_obj, self->last) < 0)
27997db96d56Sopenharmony_ci        return NULL;
28007db96d56Sopenharmony_ci
28017db96d56Sopenharmony_ci    Py_INCREF(self->last);
28027db96d56Sopenharmony_ci    return (PyObject*) self->last;
28037db96d56Sopenharmony_ci}
28047db96d56Sopenharmony_ci
28057db96d56Sopenharmony_ciLOCAL(PyObject*)
28067db96d56Sopenharmony_citreebuilder_handle_comment(TreeBuilderObject* self, PyObject* text)
28077db96d56Sopenharmony_ci{
28087db96d56Sopenharmony_ci    PyObject* comment;
28097db96d56Sopenharmony_ci    PyObject* this;
28107db96d56Sopenharmony_ci
28117db96d56Sopenharmony_ci    if (treebuilder_flush_data(self) < 0) {
28127db96d56Sopenharmony_ci        return NULL;
28137db96d56Sopenharmony_ci    }
28147db96d56Sopenharmony_ci
28157db96d56Sopenharmony_ci    if (self->comment_factory) {
28167db96d56Sopenharmony_ci        comment = PyObject_CallOneArg(self->comment_factory, text);
28177db96d56Sopenharmony_ci        if (!comment)
28187db96d56Sopenharmony_ci            return NULL;
28197db96d56Sopenharmony_ci
28207db96d56Sopenharmony_ci        this = self->this;
28217db96d56Sopenharmony_ci        if (self->insert_comments && this != Py_None) {
28227db96d56Sopenharmony_ci            if (treebuilder_add_subelement(this, comment) < 0)
28237db96d56Sopenharmony_ci                goto error;
28247db96d56Sopenharmony_ci            Py_INCREF(comment);
28257db96d56Sopenharmony_ci            Py_XSETREF(self->last_for_tail, comment);
28267db96d56Sopenharmony_ci        }
28277db96d56Sopenharmony_ci    } else {
28287db96d56Sopenharmony_ci        Py_INCREF(text);
28297db96d56Sopenharmony_ci        comment = text;
28307db96d56Sopenharmony_ci    }
28317db96d56Sopenharmony_ci
28327db96d56Sopenharmony_ci    if (self->events_append && self->comment_event_obj) {
28337db96d56Sopenharmony_ci        if (treebuilder_append_event(self, self->comment_event_obj, comment) < 0)
28347db96d56Sopenharmony_ci            goto error;
28357db96d56Sopenharmony_ci    }
28367db96d56Sopenharmony_ci
28377db96d56Sopenharmony_ci    return comment;
28387db96d56Sopenharmony_ci
28397db96d56Sopenharmony_ci  error:
28407db96d56Sopenharmony_ci    Py_DECREF(comment);
28417db96d56Sopenharmony_ci    return NULL;
28427db96d56Sopenharmony_ci}
28437db96d56Sopenharmony_ci
28447db96d56Sopenharmony_ciLOCAL(PyObject*)
28457db96d56Sopenharmony_citreebuilder_handle_pi(TreeBuilderObject* self, PyObject* target, PyObject* text)
28467db96d56Sopenharmony_ci{
28477db96d56Sopenharmony_ci    PyObject* pi;
28487db96d56Sopenharmony_ci    PyObject* this;
28497db96d56Sopenharmony_ci    PyObject* stack[2] = {target, text};
28507db96d56Sopenharmony_ci
28517db96d56Sopenharmony_ci    if (treebuilder_flush_data(self) < 0) {
28527db96d56Sopenharmony_ci        return NULL;
28537db96d56Sopenharmony_ci    }
28547db96d56Sopenharmony_ci
28557db96d56Sopenharmony_ci    if (self->pi_factory) {
28567db96d56Sopenharmony_ci        pi = _PyObject_FastCall(self->pi_factory, stack, 2);
28577db96d56Sopenharmony_ci        if (!pi) {
28587db96d56Sopenharmony_ci            return NULL;
28597db96d56Sopenharmony_ci        }
28607db96d56Sopenharmony_ci
28617db96d56Sopenharmony_ci        this = self->this;
28627db96d56Sopenharmony_ci        if (self->insert_pis && this != Py_None) {
28637db96d56Sopenharmony_ci            if (treebuilder_add_subelement(this, pi) < 0)
28647db96d56Sopenharmony_ci                goto error;
28657db96d56Sopenharmony_ci            Py_INCREF(pi);
28667db96d56Sopenharmony_ci            Py_XSETREF(self->last_for_tail, pi);
28677db96d56Sopenharmony_ci        }
28687db96d56Sopenharmony_ci    } else {
28697db96d56Sopenharmony_ci        pi = PyTuple_Pack(2, target, text);
28707db96d56Sopenharmony_ci        if (!pi) {
28717db96d56Sopenharmony_ci            return NULL;
28727db96d56Sopenharmony_ci        }
28737db96d56Sopenharmony_ci    }
28747db96d56Sopenharmony_ci
28757db96d56Sopenharmony_ci    if (self->events_append && self->pi_event_obj) {
28767db96d56Sopenharmony_ci        if (treebuilder_append_event(self, self->pi_event_obj, pi) < 0)
28777db96d56Sopenharmony_ci            goto error;
28787db96d56Sopenharmony_ci    }
28797db96d56Sopenharmony_ci
28807db96d56Sopenharmony_ci    return pi;
28817db96d56Sopenharmony_ci
28827db96d56Sopenharmony_ci  error:
28837db96d56Sopenharmony_ci    Py_DECREF(pi);
28847db96d56Sopenharmony_ci    return NULL;
28857db96d56Sopenharmony_ci}
28867db96d56Sopenharmony_ci
28877db96d56Sopenharmony_ciLOCAL(PyObject*)
28887db96d56Sopenharmony_citreebuilder_handle_start_ns(TreeBuilderObject* self, PyObject* prefix, PyObject* uri)
28897db96d56Sopenharmony_ci{
28907db96d56Sopenharmony_ci    PyObject* parcel;
28917db96d56Sopenharmony_ci
28927db96d56Sopenharmony_ci    if (self->events_append && self->start_ns_event_obj) {
28937db96d56Sopenharmony_ci        parcel = PyTuple_Pack(2, prefix, uri);
28947db96d56Sopenharmony_ci        if (!parcel) {
28957db96d56Sopenharmony_ci            return NULL;
28967db96d56Sopenharmony_ci        }
28977db96d56Sopenharmony_ci
28987db96d56Sopenharmony_ci        if (treebuilder_append_event(self, self->start_ns_event_obj, parcel) < 0) {
28997db96d56Sopenharmony_ci            Py_DECREF(parcel);
29007db96d56Sopenharmony_ci            return NULL;
29017db96d56Sopenharmony_ci        }
29027db96d56Sopenharmony_ci        Py_DECREF(parcel);
29037db96d56Sopenharmony_ci    }
29047db96d56Sopenharmony_ci
29057db96d56Sopenharmony_ci    Py_RETURN_NONE;
29067db96d56Sopenharmony_ci}
29077db96d56Sopenharmony_ci
29087db96d56Sopenharmony_ciLOCAL(PyObject*)
29097db96d56Sopenharmony_citreebuilder_handle_end_ns(TreeBuilderObject* self, PyObject* prefix)
29107db96d56Sopenharmony_ci{
29117db96d56Sopenharmony_ci    if (self->events_append && self->end_ns_event_obj) {
29127db96d56Sopenharmony_ci        if (treebuilder_append_event(self, self->end_ns_event_obj, prefix) < 0) {
29137db96d56Sopenharmony_ci            return NULL;
29147db96d56Sopenharmony_ci        }
29157db96d56Sopenharmony_ci    }
29167db96d56Sopenharmony_ci
29177db96d56Sopenharmony_ci    Py_RETURN_NONE;
29187db96d56Sopenharmony_ci}
29197db96d56Sopenharmony_ci
29207db96d56Sopenharmony_ci/* -------------------------------------------------------------------- */
29217db96d56Sopenharmony_ci/* methods (in alphabetical order) */
29227db96d56Sopenharmony_ci
29237db96d56Sopenharmony_ci/*[clinic input]
29247db96d56Sopenharmony_ci_elementtree.TreeBuilder.data
29257db96d56Sopenharmony_ci
29267db96d56Sopenharmony_ci    data: object
29277db96d56Sopenharmony_ci    /
29287db96d56Sopenharmony_ci
29297db96d56Sopenharmony_ci[clinic start generated code]*/
29307db96d56Sopenharmony_ci
29317db96d56Sopenharmony_cistatic PyObject *
29327db96d56Sopenharmony_ci_elementtree_TreeBuilder_data(TreeBuilderObject *self, PyObject *data)
29337db96d56Sopenharmony_ci/*[clinic end generated code: output=69144c7100795bb2 input=a0540c532b284d29]*/
29347db96d56Sopenharmony_ci{
29357db96d56Sopenharmony_ci    return treebuilder_handle_data(self, data);
29367db96d56Sopenharmony_ci}
29377db96d56Sopenharmony_ci
29387db96d56Sopenharmony_ci/*[clinic input]
29397db96d56Sopenharmony_ci_elementtree.TreeBuilder.end
29407db96d56Sopenharmony_ci
29417db96d56Sopenharmony_ci    tag: object
29427db96d56Sopenharmony_ci    /
29437db96d56Sopenharmony_ci
29447db96d56Sopenharmony_ci[clinic start generated code]*/
29457db96d56Sopenharmony_ci
29467db96d56Sopenharmony_cistatic PyObject *
29477db96d56Sopenharmony_ci_elementtree_TreeBuilder_end(TreeBuilderObject *self, PyObject *tag)
29487db96d56Sopenharmony_ci/*[clinic end generated code: output=9a98727cc691cd9d input=22dc3674236f5745]*/
29497db96d56Sopenharmony_ci{
29507db96d56Sopenharmony_ci    return treebuilder_handle_end(self, tag);
29517db96d56Sopenharmony_ci}
29527db96d56Sopenharmony_ci
29537db96d56Sopenharmony_ci/*[clinic input]
29547db96d56Sopenharmony_ci_elementtree.TreeBuilder.comment
29557db96d56Sopenharmony_ci
29567db96d56Sopenharmony_ci    text: object
29577db96d56Sopenharmony_ci    /
29587db96d56Sopenharmony_ci
29597db96d56Sopenharmony_ci[clinic start generated code]*/
29607db96d56Sopenharmony_ci
29617db96d56Sopenharmony_cistatic PyObject *
29627db96d56Sopenharmony_ci_elementtree_TreeBuilder_comment(TreeBuilderObject *self, PyObject *text)
29637db96d56Sopenharmony_ci/*[clinic end generated code: output=22835be41deeaa27 input=47e7ebc48ed01dfa]*/
29647db96d56Sopenharmony_ci{
29657db96d56Sopenharmony_ci    return treebuilder_handle_comment(self, text);
29667db96d56Sopenharmony_ci}
29677db96d56Sopenharmony_ci
29687db96d56Sopenharmony_ci/*[clinic input]
29697db96d56Sopenharmony_ci_elementtree.TreeBuilder.pi
29707db96d56Sopenharmony_ci
29717db96d56Sopenharmony_ci    target: object
29727db96d56Sopenharmony_ci    text: object = None
29737db96d56Sopenharmony_ci    /
29747db96d56Sopenharmony_ci
29757db96d56Sopenharmony_ci[clinic start generated code]*/
29767db96d56Sopenharmony_ci
29777db96d56Sopenharmony_cistatic PyObject *
29787db96d56Sopenharmony_ci_elementtree_TreeBuilder_pi_impl(TreeBuilderObject *self, PyObject *target,
29797db96d56Sopenharmony_ci                                 PyObject *text)
29807db96d56Sopenharmony_ci/*[clinic end generated code: output=21eb95ec9d04d1d9 input=349342bd79c35570]*/
29817db96d56Sopenharmony_ci{
29827db96d56Sopenharmony_ci    return treebuilder_handle_pi(self, target, text);
29837db96d56Sopenharmony_ci}
29847db96d56Sopenharmony_ci
29857db96d56Sopenharmony_ciLOCAL(PyObject*)
29867db96d56Sopenharmony_citreebuilder_done(TreeBuilderObject* self)
29877db96d56Sopenharmony_ci{
29887db96d56Sopenharmony_ci    PyObject* res;
29897db96d56Sopenharmony_ci
29907db96d56Sopenharmony_ci    /* FIXME: check stack size? */
29917db96d56Sopenharmony_ci
29927db96d56Sopenharmony_ci    if (self->root)
29937db96d56Sopenharmony_ci        res = self->root;
29947db96d56Sopenharmony_ci    else
29957db96d56Sopenharmony_ci        res = Py_None;
29967db96d56Sopenharmony_ci
29977db96d56Sopenharmony_ci    Py_INCREF(res);
29987db96d56Sopenharmony_ci    return res;
29997db96d56Sopenharmony_ci}
30007db96d56Sopenharmony_ci
30017db96d56Sopenharmony_ci/*[clinic input]
30027db96d56Sopenharmony_ci_elementtree.TreeBuilder.close
30037db96d56Sopenharmony_ci
30047db96d56Sopenharmony_ci[clinic start generated code]*/
30057db96d56Sopenharmony_ci
30067db96d56Sopenharmony_cistatic PyObject *
30077db96d56Sopenharmony_ci_elementtree_TreeBuilder_close_impl(TreeBuilderObject *self)
30087db96d56Sopenharmony_ci/*[clinic end generated code: output=b441fee3202f61ee input=f7c9c65dc718de14]*/
30097db96d56Sopenharmony_ci{
30107db96d56Sopenharmony_ci    return treebuilder_done(self);
30117db96d56Sopenharmony_ci}
30127db96d56Sopenharmony_ci
30137db96d56Sopenharmony_ci/*[clinic input]
30147db96d56Sopenharmony_ci_elementtree.TreeBuilder.start
30157db96d56Sopenharmony_ci
30167db96d56Sopenharmony_ci    tag: object
30177db96d56Sopenharmony_ci    attrs: object(subclass_of='&PyDict_Type')
30187db96d56Sopenharmony_ci    /
30197db96d56Sopenharmony_ci
30207db96d56Sopenharmony_ci[clinic start generated code]*/
30217db96d56Sopenharmony_ci
30227db96d56Sopenharmony_cistatic PyObject *
30237db96d56Sopenharmony_ci_elementtree_TreeBuilder_start_impl(TreeBuilderObject *self, PyObject *tag,
30247db96d56Sopenharmony_ci                                    PyObject *attrs)
30257db96d56Sopenharmony_ci/*[clinic end generated code: output=e7e9dc2861349411 input=7288e9e38e63b2b6]*/
30267db96d56Sopenharmony_ci{
30277db96d56Sopenharmony_ci    return treebuilder_handle_start(self, tag, attrs);
30287db96d56Sopenharmony_ci}
30297db96d56Sopenharmony_ci
30307db96d56Sopenharmony_ci/* ==================================================================== */
30317db96d56Sopenharmony_ci/* the expat interface */
30327db96d56Sopenharmony_ci
30337db96d56Sopenharmony_ci#include "expat.h"
30347db96d56Sopenharmony_ci#include "pyexpat.h"
30357db96d56Sopenharmony_ci
30367db96d56Sopenharmony_ci/* The PyExpat_CAPI structure is an immutable dispatch table, so it can be
30377db96d56Sopenharmony_ci * cached globally without being in per-module state.
30387db96d56Sopenharmony_ci */
30397db96d56Sopenharmony_cistatic struct PyExpat_CAPI *expat_capi;
30407db96d56Sopenharmony_ci#define EXPAT(func) (expat_capi->func)
30417db96d56Sopenharmony_ci
30427db96d56Sopenharmony_cistatic XML_Memory_Handling_Suite ExpatMemoryHandler = {
30437db96d56Sopenharmony_ci    PyObject_Malloc, PyObject_Realloc, PyObject_Free};
30447db96d56Sopenharmony_ci
30457db96d56Sopenharmony_citypedef struct {
30467db96d56Sopenharmony_ci    PyObject_HEAD
30477db96d56Sopenharmony_ci
30487db96d56Sopenharmony_ci    XML_Parser parser;
30497db96d56Sopenharmony_ci
30507db96d56Sopenharmony_ci    PyObject *target;
30517db96d56Sopenharmony_ci    PyObject *entity;
30527db96d56Sopenharmony_ci
30537db96d56Sopenharmony_ci    PyObject *names;
30547db96d56Sopenharmony_ci
30557db96d56Sopenharmony_ci    PyObject *handle_start_ns;
30567db96d56Sopenharmony_ci    PyObject *handle_end_ns;
30577db96d56Sopenharmony_ci    PyObject *handle_start;
30587db96d56Sopenharmony_ci    PyObject *handle_data;
30597db96d56Sopenharmony_ci    PyObject *handle_end;
30607db96d56Sopenharmony_ci
30617db96d56Sopenharmony_ci    PyObject *handle_comment;
30627db96d56Sopenharmony_ci    PyObject *handle_pi;
30637db96d56Sopenharmony_ci    PyObject *handle_doctype;
30647db96d56Sopenharmony_ci
30657db96d56Sopenharmony_ci    PyObject *handle_close;
30667db96d56Sopenharmony_ci
30677db96d56Sopenharmony_ci} XMLParserObject;
30687db96d56Sopenharmony_ci
30697db96d56Sopenharmony_ci/* helpers */
30707db96d56Sopenharmony_ci
30717db96d56Sopenharmony_ciLOCAL(PyObject*)
30727db96d56Sopenharmony_cimakeuniversal(XMLParserObject* self, const char* string)
30737db96d56Sopenharmony_ci{
30747db96d56Sopenharmony_ci    /* convert a UTF-8 tag/attribute name from the expat parser
30757db96d56Sopenharmony_ci       to a universal name string */
30767db96d56Sopenharmony_ci
30777db96d56Sopenharmony_ci    Py_ssize_t size = (Py_ssize_t) strlen(string);
30787db96d56Sopenharmony_ci    PyObject* key;
30797db96d56Sopenharmony_ci    PyObject* value;
30807db96d56Sopenharmony_ci
30817db96d56Sopenharmony_ci    /* look the 'raw' name up in the names dictionary */
30827db96d56Sopenharmony_ci    key = PyBytes_FromStringAndSize(string, size);
30837db96d56Sopenharmony_ci    if (!key)
30847db96d56Sopenharmony_ci        return NULL;
30857db96d56Sopenharmony_ci
30867db96d56Sopenharmony_ci    value = PyDict_GetItemWithError(self->names, key);
30877db96d56Sopenharmony_ci
30887db96d56Sopenharmony_ci    if (value) {
30897db96d56Sopenharmony_ci        Py_INCREF(value);
30907db96d56Sopenharmony_ci    }
30917db96d56Sopenharmony_ci    else if (!PyErr_Occurred()) {
30927db96d56Sopenharmony_ci        /* new name.  convert to universal name, and decode as
30937db96d56Sopenharmony_ci           necessary */
30947db96d56Sopenharmony_ci
30957db96d56Sopenharmony_ci        PyObject* tag;
30967db96d56Sopenharmony_ci        char* p;
30977db96d56Sopenharmony_ci        Py_ssize_t i;
30987db96d56Sopenharmony_ci
30997db96d56Sopenharmony_ci        /* look for namespace separator */
31007db96d56Sopenharmony_ci        for (i = 0; i < size; i++)
31017db96d56Sopenharmony_ci            if (string[i] == '}')
31027db96d56Sopenharmony_ci                break;
31037db96d56Sopenharmony_ci        if (i != size) {
31047db96d56Sopenharmony_ci            /* convert to universal name */
31057db96d56Sopenharmony_ci            tag = PyBytes_FromStringAndSize(NULL, size+1);
31067db96d56Sopenharmony_ci            if (tag == NULL) {
31077db96d56Sopenharmony_ci                Py_DECREF(key);
31087db96d56Sopenharmony_ci                return NULL;
31097db96d56Sopenharmony_ci            }
31107db96d56Sopenharmony_ci            p = PyBytes_AS_STRING(tag);
31117db96d56Sopenharmony_ci            p[0] = '{';
31127db96d56Sopenharmony_ci            memcpy(p+1, string, size);
31137db96d56Sopenharmony_ci            size++;
31147db96d56Sopenharmony_ci        } else {
31157db96d56Sopenharmony_ci            /* plain name; use key as tag */
31167db96d56Sopenharmony_ci            Py_INCREF(key);
31177db96d56Sopenharmony_ci            tag = key;
31187db96d56Sopenharmony_ci        }
31197db96d56Sopenharmony_ci
31207db96d56Sopenharmony_ci        /* decode universal name */
31217db96d56Sopenharmony_ci        p = PyBytes_AS_STRING(tag);
31227db96d56Sopenharmony_ci        value = PyUnicode_DecodeUTF8(p, size, "strict");
31237db96d56Sopenharmony_ci        Py_DECREF(tag);
31247db96d56Sopenharmony_ci        if (!value) {
31257db96d56Sopenharmony_ci            Py_DECREF(key);
31267db96d56Sopenharmony_ci            return NULL;
31277db96d56Sopenharmony_ci        }
31287db96d56Sopenharmony_ci
31297db96d56Sopenharmony_ci        /* add to names dictionary */
31307db96d56Sopenharmony_ci        if (PyDict_SetItem(self->names, key, value) < 0) {
31317db96d56Sopenharmony_ci            Py_DECREF(key);
31327db96d56Sopenharmony_ci            Py_DECREF(value);
31337db96d56Sopenharmony_ci            return NULL;
31347db96d56Sopenharmony_ci        }
31357db96d56Sopenharmony_ci    }
31367db96d56Sopenharmony_ci
31377db96d56Sopenharmony_ci    Py_DECREF(key);
31387db96d56Sopenharmony_ci    return value;
31397db96d56Sopenharmony_ci}
31407db96d56Sopenharmony_ci
31417db96d56Sopenharmony_ci/* Set the ParseError exception with the given parameters.
31427db96d56Sopenharmony_ci * If message is not NULL, it's used as the error string. Otherwise, the
31437db96d56Sopenharmony_ci * message string is the default for the given error_code.
31447db96d56Sopenharmony_ci*/
31457db96d56Sopenharmony_cistatic void
31467db96d56Sopenharmony_ciexpat_set_error(enum XML_Error error_code, Py_ssize_t line, Py_ssize_t column,
31477db96d56Sopenharmony_ci                const char *message)
31487db96d56Sopenharmony_ci{
31497db96d56Sopenharmony_ci    PyObject *errmsg, *error, *position, *code;
31507db96d56Sopenharmony_ci    elementtreestate *st = ET_STATE_GLOBAL;
31517db96d56Sopenharmony_ci
31527db96d56Sopenharmony_ci    errmsg = PyUnicode_FromFormat("%s: line %zd, column %zd",
31537db96d56Sopenharmony_ci                message ? message : EXPAT(ErrorString)(error_code),
31547db96d56Sopenharmony_ci                line, column);
31557db96d56Sopenharmony_ci    if (errmsg == NULL)
31567db96d56Sopenharmony_ci        return;
31577db96d56Sopenharmony_ci
31587db96d56Sopenharmony_ci    error = PyObject_CallOneArg(st->parseerror_obj, errmsg);
31597db96d56Sopenharmony_ci    Py_DECREF(errmsg);
31607db96d56Sopenharmony_ci    if (!error)
31617db96d56Sopenharmony_ci        return;
31627db96d56Sopenharmony_ci
31637db96d56Sopenharmony_ci    /* Add code and position attributes */
31647db96d56Sopenharmony_ci    code = PyLong_FromLong((long)error_code);
31657db96d56Sopenharmony_ci    if (!code) {
31667db96d56Sopenharmony_ci        Py_DECREF(error);
31677db96d56Sopenharmony_ci        return;
31687db96d56Sopenharmony_ci    }
31697db96d56Sopenharmony_ci    if (PyObject_SetAttrString(error, "code", code) == -1) {
31707db96d56Sopenharmony_ci        Py_DECREF(error);
31717db96d56Sopenharmony_ci        Py_DECREF(code);
31727db96d56Sopenharmony_ci        return;
31737db96d56Sopenharmony_ci    }
31747db96d56Sopenharmony_ci    Py_DECREF(code);
31757db96d56Sopenharmony_ci
31767db96d56Sopenharmony_ci    position = Py_BuildValue("(nn)", line, column);
31777db96d56Sopenharmony_ci    if (!position) {
31787db96d56Sopenharmony_ci        Py_DECREF(error);
31797db96d56Sopenharmony_ci        return;
31807db96d56Sopenharmony_ci    }
31817db96d56Sopenharmony_ci    if (PyObject_SetAttrString(error, "position", position) == -1) {
31827db96d56Sopenharmony_ci        Py_DECREF(error);
31837db96d56Sopenharmony_ci        Py_DECREF(position);
31847db96d56Sopenharmony_ci        return;
31857db96d56Sopenharmony_ci    }
31867db96d56Sopenharmony_ci    Py_DECREF(position);
31877db96d56Sopenharmony_ci
31887db96d56Sopenharmony_ci    PyErr_SetObject(st->parseerror_obj, error);
31897db96d56Sopenharmony_ci    Py_DECREF(error);
31907db96d56Sopenharmony_ci}
31917db96d56Sopenharmony_ci
31927db96d56Sopenharmony_ci/* -------------------------------------------------------------------- */
31937db96d56Sopenharmony_ci/* handlers */
31947db96d56Sopenharmony_ci
31957db96d56Sopenharmony_cistatic void
31967db96d56Sopenharmony_ciexpat_default_handler(XMLParserObject* self, const XML_Char* data_in,
31977db96d56Sopenharmony_ci                      int data_len)
31987db96d56Sopenharmony_ci{
31997db96d56Sopenharmony_ci    PyObject* key;
32007db96d56Sopenharmony_ci    PyObject* value;
32017db96d56Sopenharmony_ci    PyObject* res;
32027db96d56Sopenharmony_ci
32037db96d56Sopenharmony_ci    if (data_len < 2 || data_in[0] != '&')
32047db96d56Sopenharmony_ci        return;
32057db96d56Sopenharmony_ci
32067db96d56Sopenharmony_ci    if (PyErr_Occurred())
32077db96d56Sopenharmony_ci        return;
32087db96d56Sopenharmony_ci
32097db96d56Sopenharmony_ci    key = PyUnicode_DecodeUTF8(data_in + 1, data_len - 2, "strict");
32107db96d56Sopenharmony_ci    if (!key)
32117db96d56Sopenharmony_ci        return;
32127db96d56Sopenharmony_ci
32137db96d56Sopenharmony_ci    value = PyDict_GetItemWithError(self->entity, key);
32147db96d56Sopenharmony_ci
32157db96d56Sopenharmony_ci    if (value) {
32167db96d56Sopenharmony_ci        if (TreeBuilder_CheckExact(self->target))
32177db96d56Sopenharmony_ci            res = treebuilder_handle_data(
32187db96d56Sopenharmony_ci                (TreeBuilderObject*) self->target, value
32197db96d56Sopenharmony_ci                );
32207db96d56Sopenharmony_ci        else if (self->handle_data)
32217db96d56Sopenharmony_ci            res = PyObject_CallOneArg(self->handle_data, value);
32227db96d56Sopenharmony_ci        else
32237db96d56Sopenharmony_ci            res = NULL;
32247db96d56Sopenharmony_ci        Py_XDECREF(res);
32257db96d56Sopenharmony_ci    } else if (!PyErr_Occurred()) {
32267db96d56Sopenharmony_ci        /* Report the first error, not the last */
32277db96d56Sopenharmony_ci        char message[128] = "undefined entity ";
32287db96d56Sopenharmony_ci        strncat(message, data_in, data_len < 100?data_len:100);
32297db96d56Sopenharmony_ci        expat_set_error(
32307db96d56Sopenharmony_ci            XML_ERROR_UNDEFINED_ENTITY,
32317db96d56Sopenharmony_ci            EXPAT(GetErrorLineNumber)(self->parser),
32327db96d56Sopenharmony_ci            EXPAT(GetErrorColumnNumber)(self->parser),
32337db96d56Sopenharmony_ci            message
32347db96d56Sopenharmony_ci            );
32357db96d56Sopenharmony_ci    }
32367db96d56Sopenharmony_ci
32377db96d56Sopenharmony_ci    Py_DECREF(key);
32387db96d56Sopenharmony_ci}
32397db96d56Sopenharmony_ci
32407db96d56Sopenharmony_cistatic void
32417db96d56Sopenharmony_ciexpat_start_handler(XMLParserObject* self, const XML_Char* tag_in,
32427db96d56Sopenharmony_ci                    const XML_Char **attrib_in)
32437db96d56Sopenharmony_ci{
32447db96d56Sopenharmony_ci    PyObject* res;
32457db96d56Sopenharmony_ci    PyObject* tag;
32467db96d56Sopenharmony_ci    PyObject* attrib;
32477db96d56Sopenharmony_ci    int ok;
32487db96d56Sopenharmony_ci
32497db96d56Sopenharmony_ci    if (PyErr_Occurred())
32507db96d56Sopenharmony_ci        return;
32517db96d56Sopenharmony_ci
32527db96d56Sopenharmony_ci    /* tag name */
32537db96d56Sopenharmony_ci    tag = makeuniversal(self, tag_in);
32547db96d56Sopenharmony_ci    if (!tag)
32557db96d56Sopenharmony_ci        return; /* parser will look for errors */
32567db96d56Sopenharmony_ci
32577db96d56Sopenharmony_ci    /* attributes */
32587db96d56Sopenharmony_ci    if (attrib_in[0]) {
32597db96d56Sopenharmony_ci        attrib = PyDict_New();
32607db96d56Sopenharmony_ci        if (!attrib) {
32617db96d56Sopenharmony_ci            Py_DECREF(tag);
32627db96d56Sopenharmony_ci            return;
32637db96d56Sopenharmony_ci        }
32647db96d56Sopenharmony_ci        while (attrib_in[0] && attrib_in[1]) {
32657db96d56Sopenharmony_ci            PyObject* key = makeuniversal(self, attrib_in[0]);
32667db96d56Sopenharmony_ci            PyObject* value = PyUnicode_DecodeUTF8(attrib_in[1], strlen(attrib_in[1]), "strict");
32677db96d56Sopenharmony_ci            if (!key || !value) {
32687db96d56Sopenharmony_ci                Py_XDECREF(value);
32697db96d56Sopenharmony_ci                Py_XDECREF(key);
32707db96d56Sopenharmony_ci                Py_DECREF(attrib);
32717db96d56Sopenharmony_ci                Py_DECREF(tag);
32727db96d56Sopenharmony_ci                return;
32737db96d56Sopenharmony_ci            }
32747db96d56Sopenharmony_ci            ok = PyDict_SetItem(attrib, key, value);
32757db96d56Sopenharmony_ci            Py_DECREF(value);
32767db96d56Sopenharmony_ci            Py_DECREF(key);
32777db96d56Sopenharmony_ci            if (ok < 0) {
32787db96d56Sopenharmony_ci                Py_DECREF(attrib);
32797db96d56Sopenharmony_ci                Py_DECREF(tag);
32807db96d56Sopenharmony_ci                return;
32817db96d56Sopenharmony_ci            }
32827db96d56Sopenharmony_ci            attrib_in += 2;
32837db96d56Sopenharmony_ci        }
32847db96d56Sopenharmony_ci    } else {
32857db96d56Sopenharmony_ci        attrib = NULL;
32867db96d56Sopenharmony_ci    }
32877db96d56Sopenharmony_ci
32887db96d56Sopenharmony_ci    if (TreeBuilder_CheckExact(self->target)) {
32897db96d56Sopenharmony_ci        /* shortcut */
32907db96d56Sopenharmony_ci        res = treebuilder_handle_start((TreeBuilderObject*) self->target,
32917db96d56Sopenharmony_ci                                       tag, attrib);
32927db96d56Sopenharmony_ci    }
32937db96d56Sopenharmony_ci    else if (self->handle_start) {
32947db96d56Sopenharmony_ci        if (attrib == NULL) {
32957db96d56Sopenharmony_ci            attrib = PyDict_New();
32967db96d56Sopenharmony_ci            if (!attrib) {
32977db96d56Sopenharmony_ci                Py_DECREF(tag);
32987db96d56Sopenharmony_ci                return;
32997db96d56Sopenharmony_ci            }
33007db96d56Sopenharmony_ci        }
33017db96d56Sopenharmony_ci        res = PyObject_CallFunctionObjArgs(self->handle_start,
33027db96d56Sopenharmony_ci                                           tag, attrib, NULL);
33037db96d56Sopenharmony_ci    } else
33047db96d56Sopenharmony_ci        res = NULL;
33057db96d56Sopenharmony_ci
33067db96d56Sopenharmony_ci    Py_DECREF(tag);
33077db96d56Sopenharmony_ci    Py_XDECREF(attrib);
33087db96d56Sopenharmony_ci
33097db96d56Sopenharmony_ci    Py_XDECREF(res);
33107db96d56Sopenharmony_ci}
33117db96d56Sopenharmony_ci
33127db96d56Sopenharmony_cistatic void
33137db96d56Sopenharmony_ciexpat_data_handler(XMLParserObject* self, const XML_Char* data_in,
33147db96d56Sopenharmony_ci                   int data_len)
33157db96d56Sopenharmony_ci{
33167db96d56Sopenharmony_ci    PyObject* data;
33177db96d56Sopenharmony_ci    PyObject* res;
33187db96d56Sopenharmony_ci
33197db96d56Sopenharmony_ci    if (PyErr_Occurred())
33207db96d56Sopenharmony_ci        return;
33217db96d56Sopenharmony_ci
33227db96d56Sopenharmony_ci    data = PyUnicode_DecodeUTF8(data_in, data_len, "strict");
33237db96d56Sopenharmony_ci    if (!data)
33247db96d56Sopenharmony_ci        return; /* parser will look for errors */
33257db96d56Sopenharmony_ci
33267db96d56Sopenharmony_ci    if (TreeBuilder_CheckExact(self->target))
33277db96d56Sopenharmony_ci        /* shortcut */
33287db96d56Sopenharmony_ci        res = treebuilder_handle_data((TreeBuilderObject*) self->target, data);
33297db96d56Sopenharmony_ci    else if (self->handle_data)
33307db96d56Sopenharmony_ci        res = PyObject_CallOneArg(self->handle_data, data);
33317db96d56Sopenharmony_ci    else
33327db96d56Sopenharmony_ci        res = NULL;
33337db96d56Sopenharmony_ci
33347db96d56Sopenharmony_ci    Py_DECREF(data);
33357db96d56Sopenharmony_ci
33367db96d56Sopenharmony_ci    Py_XDECREF(res);
33377db96d56Sopenharmony_ci}
33387db96d56Sopenharmony_ci
33397db96d56Sopenharmony_cistatic void
33407db96d56Sopenharmony_ciexpat_end_handler(XMLParserObject* self, const XML_Char* tag_in)
33417db96d56Sopenharmony_ci{
33427db96d56Sopenharmony_ci    PyObject* tag;
33437db96d56Sopenharmony_ci    PyObject* res = NULL;
33447db96d56Sopenharmony_ci
33457db96d56Sopenharmony_ci    if (PyErr_Occurred())
33467db96d56Sopenharmony_ci        return;
33477db96d56Sopenharmony_ci
33487db96d56Sopenharmony_ci    if (TreeBuilder_CheckExact(self->target))
33497db96d56Sopenharmony_ci        /* shortcut */
33507db96d56Sopenharmony_ci        /* the standard tree builder doesn't look at the end tag */
33517db96d56Sopenharmony_ci        res = treebuilder_handle_end(
33527db96d56Sopenharmony_ci            (TreeBuilderObject*) self->target, Py_None
33537db96d56Sopenharmony_ci            );
33547db96d56Sopenharmony_ci    else if (self->handle_end) {
33557db96d56Sopenharmony_ci        tag = makeuniversal(self, tag_in);
33567db96d56Sopenharmony_ci        if (tag) {
33577db96d56Sopenharmony_ci            res = PyObject_CallOneArg(self->handle_end, tag);
33587db96d56Sopenharmony_ci            Py_DECREF(tag);
33597db96d56Sopenharmony_ci        }
33607db96d56Sopenharmony_ci    }
33617db96d56Sopenharmony_ci
33627db96d56Sopenharmony_ci    Py_XDECREF(res);
33637db96d56Sopenharmony_ci}
33647db96d56Sopenharmony_ci
33657db96d56Sopenharmony_cistatic void
33667db96d56Sopenharmony_ciexpat_start_ns_handler(XMLParserObject* self, const XML_Char* prefix_in,
33677db96d56Sopenharmony_ci                       const XML_Char *uri_in)
33687db96d56Sopenharmony_ci{
33697db96d56Sopenharmony_ci    PyObject* res = NULL;
33707db96d56Sopenharmony_ci    PyObject* uri;
33717db96d56Sopenharmony_ci    PyObject* prefix;
33727db96d56Sopenharmony_ci    PyObject* stack[2];
33737db96d56Sopenharmony_ci
33747db96d56Sopenharmony_ci    if (PyErr_Occurred())
33757db96d56Sopenharmony_ci        return;
33767db96d56Sopenharmony_ci
33777db96d56Sopenharmony_ci    if (!uri_in)
33787db96d56Sopenharmony_ci        uri_in = "";
33797db96d56Sopenharmony_ci    if (!prefix_in)
33807db96d56Sopenharmony_ci        prefix_in = "";
33817db96d56Sopenharmony_ci
33827db96d56Sopenharmony_ci    if (TreeBuilder_CheckExact(self->target)) {
33837db96d56Sopenharmony_ci        /* shortcut - TreeBuilder does not actually implement .start_ns() */
33847db96d56Sopenharmony_ci        TreeBuilderObject *target = (TreeBuilderObject*) self->target;
33857db96d56Sopenharmony_ci
33867db96d56Sopenharmony_ci        if (target->events_append && target->start_ns_event_obj) {
33877db96d56Sopenharmony_ci            prefix = PyUnicode_DecodeUTF8(prefix_in, strlen(prefix_in), "strict");
33887db96d56Sopenharmony_ci            if (!prefix)
33897db96d56Sopenharmony_ci                return;
33907db96d56Sopenharmony_ci            uri = PyUnicode_DecodeUTF8(uri_in, strlen(uri_in), "strict");
33917db96d56Sopenharmony_ci            if (!uri) {
33927db96d56Sopenharmony_ci                Py_DECREF(prefix);
33937db96d56Sopenharmony_ci                return;
33947db96d56Sopenharmony_ci            }
33957db96d56Sopenharmony_ci
33967db96d56Sopenharmony_ci            res = treebuilder_handle_start_ns(target, prefix, uri);
33977db96d56Sopenharmony_ci            Py_DECREF(uri);
33987db96d56Sopenharmony_ci            Py_DECREF(prefix);
33997db96d56Sopenharmony_ci        }
34007db96d56Sopenharmony_ci    } else if (self->handle_start_ns) {
34017db96d56Sopenharmony_ci        prefix = PyUnicode_DecodeUTF8(prefix_in, strlen(prefix_in), "strict");
34027db96d56Sopenharmony_ci        if (!prefix)
34037db96d56Sopenharmony_ci            return;
34047db96d56Sopenharmony_ci        uri = PyUnicode_DecodeUTF8(uri_in, strlen(uri_in), "strict");
34057db96d56Sopenharmony_ci        if (!uri) {
34067db96d56Sopenharmony_ci            Py_DECREF(prefix);
34077db96d56Sopenharmony_ci            return;
34087db96d56Sopenharmony_ci        }
34097db96d56Sopenharmony_ci
34107db96d56Sopenharmony_ci        stack[0] = prefix;
34117db96d56Sopenharmony_ci        stack[1] = uri;
34127db96d56Sopenharmony_ci        res = _PyObject_FastCall(self->handle_start_ns, stack, 2);
34137db96d56Sopenharmony_ci        Py_DECREF(uri);
34147db96d56Sopenharmony_ci        Py_DECREF(prefix);
34157db96d56Sopenharmony_ci    }
34167db96d56Sopenharmony_ci
34177db96d56Sopenharmony_ci    Py_XDECREF(res);
34187db96d56Sopenharmony_ci}
34197db96d56Sopenharmony_ci
34207db96d56Sopenharmony_cistatic void
34217db96d56Sopenharmony_ciexpat_end_ns_handler(XMLParserObject* self, const XML_Char* prefix_in)
34227db96d56Sopenharmony_ci{
34237db96d56Sopenharmony_ci    PyObject *res = NULL;
34247db96d56Sopenharmony_ci    PyObject* prefix;
34257db96d56Sopenharmony_ci
34267db96d56Sopenharmony_ci    if (PyErr_Occurred())
34277db96d56Sopenharmony_ci        return;
34287db96d56Sopenharmony_ci
34297db96d56Sopenharmony_ci    if (!prefix_in)
34307db96d56Sopenharmony_ci        prefix_in = "";
34317db96d56Sopenharmony_ci
34327db96d56Sopenharmony_ci    if (TreeBuilder_CheckExact(self->target)) {
34337db96d56Sopenharmony_ci        /* shortcut - TreeBuilder does not actually implement .end_ns() */
34347db96d56Sopenharmony_ci        TreeBuilderObject *target = (TreeBuilderObject*) self->target;
34357db96d56Sopenharmony_ci
34367db96d56Sopenharmony_ci        if (target->events_append && target->end_ns_event_obj) {
34377db96d56Sopenharmony_ci            res = treebuilder_handle_end_ns(target, Py_None);
34387db96d56Sopenharmony_ci        }
34397db96d56Sopenharmony_ci    } else if (self->handle_end_ns) {
34407db96d56Sopenharmony_ci        prefix = PyUnicode_DecodeUTF8(prefix_in, strlen(prefix_in), "strict");
34417db96d56Sopenharmony_ci        if (!prefix)
34427db96d56Sopenharmony_ci            return;
34437db96d56Sopenharmony_ci
34447db96d56Sopenharmony_ci        res = PyObject_CallOneArg(self->handle_end_ns, prefix);
34457db96d56Sopenharmony_ci        Py_DECREF(prefix);
34467db96d56Sopenharmony_ci    }
34477db96d56Sopenharmony_ci
34487db96d56Sopenharmony_ci    Py_XDECREF(res);
34497db96d56Sopenharmony_ci}
34507db96d56Sopenharmony_ci
34517db96d56Sopenharmony_cistatic void
34527db96d56Sopenharmony_ciexpat_comment_handler(XMLParserObject* self, const XML_Char* comment_in)
34537db96d56Sopenharmony_ci{
34547db96d56Sopenharmony_ci    PyObject* comment;
34557db96d56Sopenharmony_ci    PyObject* res;
34567db96d56Sopenharmony_ci
34577db96d56Sopenharmony_ci    if (PyErr_Occurred())
34587db96d56Sopenharmony_ci        return;
34597db96d56Sopenharmony_ci
34607db96d56Sopenharmony_ci    if (TreeBuilder_CheckExact(self->target)) {
34617db96d56Sopenharmony_ci        /* shortcut */
34627db96d56Sopenharmony_ci        TreeBuilderObject *target = (TreeBuilderObject*) self->target;
34637db96d56Sopenharmony_ci
34647db96d56Sopenharmony_ci        comment = PyUnicode_DecodeUTF8(comment_in, strlen(comment_in), "strict");
34657db96d56Sopenharmony_ci        if (!comment)
34667db96d56Sopenharmony_ci            return; /* parser will look for errors */
34677db96d56Sopenharmony_ci
34687db96d56Sopenharmony_ci        res = treebuilder_handle_comment(target,  comment);
34697db96d56Sopenharmony_ci        Py_XDECREF(res);
34707db96d56Sopenharmony_ci        Py_DECREF(comment);
34717db96d56Sopenharmony_ci    } else if (self->handle_comment) {
34727db96d56Sopenharmony_ci        comment = PyUnicode_DecodeUTF8(comment_in, strlen(comment_in), "strict");
34737db96d56Sopenharmony_ci        if (!comment)
34747db96d56Sopenharmony_ci            return;
34757db96d56Sopenharmony_ci
34767db96d56Sopenharmony_ci        res = PyObject_CallOneArg(self->handle_comment, comment);
34777db96d56Sopenharmony_ci        Py_XDECREF(res);
34787db96d56Sopenharmony_ci        Py_DECREF(comment);
34797db96d56Sopenharmony_ci    }
34807db96d56Sopenharmony_ci}
34817db96d56Sopenharmony_ci
34827db96d56Sopenharmony_cistatic void
34837db96d56Sopenharmony_ciexpat_start_doctype_handler(XMLParserObject *self,
34847db96d56Sopenharmony_ci                            const XML_Char *doctype_name,
34857db96d56Sopenharmony_ci                            const XML_Char *sysid,
34867db96d56Sopenharmony_ci                            const XML_Char *pubid,
34877db96d56Sopenharmony_ci                            int has_internal_subset)
34887db96d56Sopenharmony_ci{
34897db96d56Sopenharmony_ci    _Py_IDENTIFIER(doctype);
34907db96d56Sopenharmony_ci    PyObject *doctype_name_obj, *sysid_obj, *pubid_obj;
34917db96d56Sopenharmony_ci    PyObject *res;
34927db96d56Sopenharmony_ci
34937db96d56Sopenharmony_ci    if (PyErr_Occurred())
34947db96d56Sopenharmony_ci        return;
34957db96d56Sopenharmony_ci
34967db96d56Sopenharmony_ci    doctype_name_obj = makeuniversal(self, doctype_name);
34977db96d56Sopenharmony_ci    if (!doctype_name_obj)
34987db96d56Sopenharmony_ci        return;
34997db96d56Sopenharmony_ci
35007db96d56Sopenharmony_ci    if (sysid) {
35017db96d56Sopenharmony_ci        sysid_obj = makeuniversal(self, sysid);
35027db96d56Sopenharmony_ci        if (!sysid_obj) {
35037db96d56Sopenharmony_ci            Py_DECREF(doctype_name_obj);
35047db96d56Sopenharmony_ci            return;
35057db96d56Sopenharmony_ci        }
35067db96d56Sopenharmony_ci    } else {
35077db96d56Sopenharmony_ci        Py_INCREF(Py_None);
35087db96d56Sopenharmony_ci        sysid_obj = Py_None;
35097db96d56Sopenharmony_ci    }
35107db96d56Sopenharmony_ci
35117db96d56Sopenharmony_ci    if (pubid) {
35127db96d56Sopenharmony_ci        pubid_obj = makeuniversal(self, pubid);
35137db96d56Sopenharmony_ci        if (!pubid_obj) {
35147db96d56Sopenharmony_ci            Py_DECREF(doctype_name_obj);
35157db96d56Sopenharmony_ci            Py_DECREF(sysid_obj);
35167db96d56Sopenharmony_ci            return;
35177db96d56Sopenharmony_ci        }
35187db96d56Sopenharmony_ci    } else {
35197db96d56Sopenharmony_ci        Py_INCREF(Py_None);
35207db96d56Sopenharmony_ci        pubid_obj = Py_None;
35217db96d56Sopenharmony_ci    }
35227db96d56Sopenharmony_ci
35237db96d56Sopenharmony_ci    /* If the target has a handler for doctype, call it. */
35247db96d56Sopenharmony_ci    if (self->handle_doctype) {
35257db96d56Sopenharmony_ci        res = PyObject_CallFunctionObjArgs(self->handle_doctype,
35267db96d56Sopenharmony_ci                                           doctype_name_obj, pubid_obj,
35277db96d56Sopenharmony_ci                                           sysid_obj, NULL);
35287db96d56Sopenharmony_ci        Py_XDECREF(res);
35297db96d56Sopenharmony_ci    }
35307db96d56Sopenharmony_ci    else if (_PyObject_LookupAttrId((PyObject *)self, &PyId_doctype, &res) > 0) {
35317db96d56Sopenharmony_ci        (void)PyErr_WarnEx(PyExc_RuntimeWarning,
35327db96d56Sopenharmony_ci                "The doctype() method of XMLParser is ignored.  "
35337db96d56Sopenharmony_ci                "Define doctype() method on the TreeBuilder target.",
35347db96d56Sopenharmony_ci                1);
35357db96d56Sopenharmony_ci        Py_DECREF(res);
35367db96d56Sopenharmony_ci    }
35377db96d56Sopenharmony_ci
35387db96d56Sopenharmony_ci    Py_DECREF(doctype_name_obj);
35397db96d56Sopenharmony_ci    Py_DECREF(pubid_obj);
35407db96d56Sopenharmony_ci    Py_DECREF(sysid_obj);
35417db96d56Sopenharmony_ci}
35427db96d56Sopenharmony_ci
35437db96d56Sopenharmony_cistatic void
35447db96d56Sopenharmony_ciexpat_pi_handler(XMLParserObject* self, const XML_Char* target_in,
35457db96d56Sopenharmony_ci                 const XML_Char* data_in)
35467db96d56Sopenharmony_ci{
35477db96d56Sopenharmony_ci    PyObject* pi_target;
35487db96d56Sopenharmony_ci    PyObject* data;
35497db96d56Sopenharmony_ci    PyObject* res;
35507db96d56Sopenharmony_ci    PyObject* stack[2];
35517db96d56Sopenharmony_ci
35527db96d56Sopenharmony_ci    if (PyErr_Occurred())
35537db96d56Sopenharmony_ci        return;
35547db96d56Sopenharmony_ci
35557db96d56Sopenharmony_ci    if (TreeBuilder_CheckExact(self->target)) {
35567db96d56Sopenharmony_ci        /* shortcut */
35577db96d56Sopenharmony_ci        TreeBuilderObject *target = (TreeBuilderObject*) self->target;
35587db96d56Sopenharmony_ci
35597db96d56Sopenharmony_ci        if ((target->events_append && target->pi_event_obj) || target->insert_pis) {
35607db96d56Sopenharmony_ci            pi_target = PyUnicode_DecodeUTF8(target_in, strlen(target_in), "strict");
35617db96d56Sopenharmony_ci            if (!pi_target)
35627db96d56Sopenharmony_ci                goto error;
35637db96d56Sopenharmony_ci            data = PyUnicode_DecodeUTF8(data_in, strlen(data_in), "strict");
35647db96d56Sopenharmony_ci            if (!data)
35657db96d56Sopenharmony_ci                goto error;
35667db96d56Sopenharmony_ci            res = treebuilder_handle_pi(target, pi_target, data);
35677db96d56Sopenharmony_ci            Py_XDECREF(res);
35687db96d56Sopenharmony_ci            Py_DECREF(data);
35697db96d56Sopenharmony_ci            Py_DECREF(pi_target);
35707db96d56Sopenharmony_ci        }
35717db96d56Sopenharmony_ci    } else if (self->handle_pi) {
35727db96d56Sopenharmony_ci        pi_target = PyUnicode_DecodeUTF8(target_in, strlen(target_in), "strict");
35737db96d56Sopenharmony_ci        if (!pi_target)
35747db96d56Sopenharmony_ci            goto error;
35757db96d56Sopenharmony_ci        data = PyUnicode_DecodeUTF8(data_in, strlen(data_in), "strict");
35767db96d56Sopenharmony_ci        if (!data)
35777db96d56Sopenharmony_ci            goto error;
35787db96d56Sopenharmony_ci
35797db96d56Sopenharmony_ci        stack[0] = pi_target;
35807db96d56Sopenharmony_ci        stack[1] = data;
35817db96d56Sopenharmony_ci        res = _PyObject_FastCall(self->handle_pi, stack, 2);
35827db96d56Sopenharmony_ci        Py_XDECREF(res);
35837db96d56Sopenharmony_ci        Py_DECREF(data);
35847db96d56Sopenharmony_ci        Py_DECREF(pi_target);
35857db96d56Sopenharmony_ci    }
35867db96d56Sopenharmony_ci
35877db96d56Sopenharmony_ci    return;
35887db96d56Sopenharmony_ci
35897db96d56Sopenharmony_ci  error:
35907db96d56Sopenharmony_ci    Py_XDECREF(pi_target);
35917db96d56Sopenharmony_ci    return;
35927db96d56Sopenharmony_ci}
35937db96d56Sopenharmony_ci
35947db96d56Sopenharmony_ci/* -------------------------------------------------------------------- */
35957db96d56Sopenharmony_ci
35967db96d56Sopenharmony_cistatic PyObject *
35977db96d56Sopenharmony_cixmlparser_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
35987db96d56Sopenharmony_ci{
35997db96d56Sopenharmony_ci    XMLParserObject *self = (XMLParserObject *)type->tp_alloc(type, 0);
36007db96d56Sopenharmony_ci    if (self) {
36017db96d56Sopenharmony_ci        self->parser = NULL;
36027db96d56Sopenharmony_ci        self->target = self->entity = self->names = NULL;
36037db96d56Sopenharmony_ci        self->handle_start_ns = self->handle_end_ns = NULL;
36047db96d56Sopenharmony_ci        self->handle_start = self->handle_data = self->handle_end = NULL;
36057db96d56Sopenharmony_ci        self->handle_comment = self->handle_pi = self->handle_close = NULL;
36067db96d56Sopenharmony_ci        self->handle_doctype = NULL;
36077db96d56Sopenharmony_ci    }
36087db96d56Sopenharmony_ci    return (PyObject *)self;
36097db96d56Sopenharmony_ci}
36107db96d56Sopenharmony_ci
36117db96d56Sopenharmony_cistatic int
36127db96d56Sopenharmony_ciignore_attribute_error(PyObject *value)
36137db96d56Sopenharmony_ci{
36147db96d56Sopenharmony_ci    if (value == NULL) {
36157db96d56Sopenharmony_ci        if (!PyErr_ExceptionMatches(PyExc_AttributeError)) {
36167db96d56Sopenharmony_ci            return -1;
36177db96d56Sopenharmony_ci        }
36187db96d56Sopenharmony_ci        PyErr_Clear();
36197db96d56Sopenharmony_ci    }
36207db96d56Sopenharmony_ci    return 0;
36217db96d56Sopenharmony_ci}
36227db96d56Sopenharmony_ci
36237db96d56Sopenharmony_ci/*[clinic input]
36247db96d56Sopenharmony_ci_elementtree.XMLParser.__init__
36257db96d56Sopenharmony_ci
36267db96d56Sopenharmony_ci    *
36277db96d56Sopenharmony_ci    target: object = None
36287db96d56Sopenharmony_ci    encoding: str(accept={str, NoneType}) = None
36297db96d56Sopenharmony_ci
36307db96d56Sopenharmony_ci[clinic start generated code]*/
36317db96d56Sopenharmony_ci
36327db96d56Sopenharmony_cistatic int
36337db96d56Sopenharmony_ci_elementtree_XMLParser___init___impl(XMLParserObject *self, PyObject *target,
36347db96d56Sopenharmony_ci                                     const char *encoding)
36357db96d56Sopenharmony_ci/*[clinic end generated code: output=3ae45ec6cdf344e4 input=7e716dd6e4f3e439]*/
36367db96d56Sopenharmony_ci{
36377db96d56Sopenharmony_ci    self->entity = PyDict_New();
36387db96d56Sopenharmony_ci    if (!self->entity)
36397db96d56Sopenharmony_ci        return -1;
36407db96d56Sopenharmony_ci
36417db96d56Sopenharmony_ci    self->names = PyDict_New();
36427db96d56Sopenharmony_ci    if (!self->names) {
36437db96d56Sopenharmony_ci        Py_CLEAR(self->entity);
36447db96d56Sopenharmony_ci        return -1;
36457db96d56Sopenharmony_ci    }
36467db96d56Sopenharmony_ci
36477db96d56Sopenharmony_ci    self->parser = EXPAT(ParserCreate_MM)(encoding, &ExpatMemoryHandler, "}");
36487db96d56Sopenharmony_ci    if (!self->parser) {
36497db96d56Sopenharmony_ci        Py_CLEAR(self->entity);
36507db96d56Sopenharmony_ci        Py_CLEAR(self->names);
36517db96d56Sopenharmony_ci        PyErr_NoMemory();
36527db96d56Sopenharmony_ci        return -1;
36537db96d56Sopenharmony_ci    }
36547db96d56Sopenharmony_ci    /* expat < 2.1.0 has no XML_SetHashSalt() */
36557db96d56Sopenharmony_ci    if (EXPAT(SetHashSalt) != NULL) {
36567db96d56Sopenharmony_ci        EXPAT(SetHashSalt)(self->parser,
36577db96d56Sopenharmony_ci                           (unsigned long)_Py_HashSecret.expat.hashsalt);
36587db96d56Sopenharmony_ci    }
36597db96d56Sopenharmony_ci
36607db96d56Sopenharmony_ci    if (target != Py_None) {
36617db96d56Sopenharmony_ci        Py_INCREF(target);
36627db96d56Sopenharmony_ci    } else {
36637db96d56Sopenharmony_ci        target = treebuilder_new(&TreeBuilder_Type, NULL, NULL);
36647db96d56Sopenharmony_ci        if (!target) {
36657db96d56Sopenharmony_ci            Py_CLEAR(self->entity);
36667db96d56Sopenharmony_ci            Py_CLEAR(self->names);
36677db96d56Sopenharmony_ci            return -1;
36687db96d56Sopenharmony_ci        }
36697db96d56Sopenharmony_ci    }
36707db96d56Sopenharmony_ci    self->target = target;
36717db96d56Sopenharmony_ci
36727db96d56Sopenharmony_ci    self->handle_start_ns = PyObject_GetAttrString(target, "start_ns");
36737db96d56Sopenharmony_ci    if (ignore_attribute_error(self->handle_start_ns)) {
36747db96d56Sopenharmony_ci        return -1;
36757db96d56Sopenharmony_ci    }
36767db96d56Sopenharmony_ci    self->handle_end_ns = PyObject_GetAttrString(target, "end_ns");
36777db96d56Sopenharmony_ci    if (ignore_attribute_error(self->handle_end_ns)) {
36787db96d56Sopenharmony_ci        return -1;
36797db96d56Sopenharmony_ci    }
36807db96d56Sopenharmony_ci    self->handle_start = PyObject_GetAttrString(target, "start");
36817db96d56Sopenharmony_ci    if (ignore_attribute_error(self->handle_start)) {
36827db96d56Sopenharmony_ci        return -1;
36837db96d56Sopenharmony_ci    }
36847db96d56Sopenharmony_ci    self->handle_data = PyObject_GetAttrString(target, "data");
36857db96d56Sopenharmony_ci    if (ignore_attribute_error(self->handle_data)) {
36867db96d56Sopenharmony_ci        return -1;
36877db96d56Sopenharmony_ci    }
36887db96d56Sopenharmony_ci    self->handle_end = PyObject_GetAttrString(target, "end");
36897db96d56Sopenharmony_ci    if (ignore_attribute_error(self->handle_end)) {
36907db96d56Sopenharmony_ci        return -1;
36917db96d56Sopenharmony_ci    }
36927db96d56Sopenharmony_ci    self->handle_comment = PyObject_GetAttrString(target, "comment");
36937db96d56Sopenharmony_ci    if (ignore_attribute_error(self->handle_comment)) {
36947db96d56Sopenharmony_ci        return -1;
36957db96d56Sopenharmony_ci    }
36967db96d56Sopenharmony_ci    self->handle_pi = PyObject_GetAttrString(target, "pi");
36977db96d56Sopenharmony_ci    if (ignore_attribute_error(self->handle_pi)) {
36987db96d56Sopenharmony_ci        return -1;
36997db96d56Sopenharmony_ci    }
37007db96d56Sopenharmony_ci    self->handle_close = PyObject_GetAttrString(target, "close");
37017db96d56Sopenharmony_ci    if (ignore_attribute_error(self->handle_close)) {
37027db96d56Sopenharmony_ci        return -1;
37037db96d56Sopenharmony_ci    }
37047db96d56Sopenharmony_ci    self->handle_doctype = PyObject_GetAttrString(target, "doctype");
37057db96d56Sopenharmony_ci    if (ignore_attribute_error(self->handle_doctype)) {
37067db96d56Sopenharmony_ci        return -1;
37077db96d56Sopenharmony_ci    }
37087db96d56Sopenharmony_ci
37097db96d56Sopenharmony_ci    /* configure parser */
37107db96d56Sopenharmony_ci    EXPAT(SetUserData)(self->parser, self);
37117db96d56Sopenharmony_ci    if (self->handle_start_ns || self->handle_end_ns)
37127db96d56Sopenharmony_ci        EXPAT(SetNamespaceDeclHandler)(
37137db96d56Sopenharmony_ci            self->parser,
37147db96d56Sopenharmony_ci            (XML_StartNamespaceDeclHandler) expat_start_ns_handler,
37157db96d56Sopenharmony_ci            (XML_EndNamespaceDeclHandler) expat_end_ns_handler
37167db96d56Sopenharmony_ci            );
37177db96d56Sopenharmony_ci    EXPAT(SetElementHandler)(
37187db96d56Sopenharmony_ci        self->parser,
37197db96d56Sopenharmony_ci        (XML_StartElementHandler) expat_start_handler,
37207db96d56Sopenharmony_ci        (XML_EndElementHandler) expat_end_handler
37217db96d56Sopenharmony_ci        );
37227db96d56Sopenharmony_ci    EXPAT(SetDefaultHandlerExpand)(
37237db96d56Sopenharmony_ci        self->parser,
37247db96d56Sopenharmony_ci        (XML_DefaultHandler) expat_default_handler
37257db96d56Sopenharmony_ci        );
37267db96d56Sopenharmony_ci    EXPAT(SetCharacterDataHandler)(
37277db96d56Sopenharmony_ci        self->parser,
37287db96d56Sopenharmony_ci        (XML_CharacterDataHandler) expat_data_handler
37297db96d56Sopenharmony_ci        );
37307db96d56Sopenharmony_ci    if (self->handle_comment)
37317db96d56Sopenharmony_ci        EXPAT(SetCommentHandler)(
37327db96d56Sopenharmony_ci            self->parser,
37337db96d56Sopenharmony_ci            (XML_CommentHandler) expat_comment_handler
37347db96d56Sopenharmony_ci            );
37357db96d56Sopenharmony_ci    if (self->handle_pi)
37367db96d56Sopenharmony_ci        EXPAT(SetProcessingInstructionHandler)(
37377db96d56Sopenharmony_ci            self->parser,
37387db96d56Sopenharmony_ci            (XML_ProcessingInstructionHandler) expat_pi_handler
37397db96d56Sopenharmony_ci            );
37407db96d56Sopenharmony_ci    EXPAT(SetStartDoctypeDeclHandler)(
37417db96d56Sopenharmony_ci        self->parser,
37427db96d56Sopenharmony_ci        (XML_StartDoctypeDeclHandler) expat_start_doctype_handler
37437db96d56Sopenharmony_ci        );
37447db96d56Sopenharmony_ci    EXPAT(SetUnknownEncodingHandler)(
37457db96d56Sopenharmony_ci        self->parser,
37467db96d56Sopenharmony_ci        EXPAT(DefaultUnknownEncodingHandler), NULL
37477db96d56Sopenharmony_ci        );
37487db96d56Sopenharmony_ci
37497db96d56Sopenharmony_ci    return 0;
37507db96d56Sopenharmony_ci}
37517db96d56Sopenharmony_ci
37527db96d56Sopenharmony_cistatic int
37537db96d56Sopenharmony_cixmlparser_gc_traverse(XMLParserObject *self, visitproc visit, void *arg)
37547db96d56Sopenharmony_ci{
37557db96d56Sopenharmony_ci    Py_VISIT(self->handle_close);
37567db96d56Sopenharmony_ci    Py_VISIT(self->handle_pi);
37577db96d56Sopenharmony_ci    Py_VISIT(self->handle_comment);
37587db96d56Sopenharmony_ci    Py_VISIT(self->handle_end);
37597db96d56Sopenharmony_ci    Py_VISIT(self->handle_data);
37607db96d56Sopenharmony_ci    Py_VISIT(self->handle_start);
37617db96d56Sopenharmony_ci    Py_VISIT(self->handle_start_ns);
37627db96d56Sopenharmony_ci    Py_VISIT(self->handle_end_ns);
37637db96d56Sopenharmony_ci    Py_VISIT(self->handle_doctype);
37647db96d56Sopenharmony_ci
37657db96d56Sopenharmony_ci    Py_VISIT(self->target);
37667db96d56Sopenharmony_ci    Py_VISIT(self->entity);
37677db96d56Sopenharmony_ci    Py_VISIT(self->names);
37687db96d56Sopenharmony_ci
37697db96d56Sopenharmony_ci    return 0;
37707db96d56Sopenharmony_ci}
37717db96d56Sopenharmony_ci
37727db96d56Sopenharmony_cistatic int
37737db96d56Sopenharmony_cixmlparser_gc_clear(XMLParserObject *self)
37747db96d56Sopenharmony_ci{
37757db96d56Sopenharmony_ci    if (self->parser != NULL) {
37767db96d56Sopenharmony_ci        XML_Parser parser = self->parser;
37777db96d56Sopenharmony_ci        self->parser = NULL;
37787db96d56Sopenharmony_ci        EXPAT(ParserFree)(parser);
37797db96d56Sopenharmony_ci    }
37807db96d56Sopenharmony_ci
37817db96d56Sopenharmony_ci    Py_CLEAR(self->handle_close);
37827db96d56Sopenharmony_ci    Py_CLEAR(self->handle_pi);
37837db96d56Sopenharmony_ci    Py_CLEAR(self->handle_comment);
37847db96d56Sopenharmony_ci    Py_CLEAR(self->handle_end);
37857db96d56Sopenharmony_ci    Py_CLEAR(self->handle_data);
37867db96d56Sopenharmony_ci    Py_CLEAR(self->handle_start);
37877db96d56Sopenharmony_ci    Py_CLEAR(self->handle_start_ns);
37887db96d56Sopenharmony_ci    Py_CLEAR(self->handle_end_ns);
37897db96d56Sopenharmony_ci    Py_CLEAR(self->handle_doctype);
37907db96d56Sopenharmony_ci
37917db96d56Sopenharmony_ci    Py_CLEAR(self->target);
37927db96d56Sopenharmony_ci    Py_CLEAR(self->entity);
37937db96d56Sopenharmony_ci    Py_CLEAR(self->names);
37947db96d56Sopenharmony_ci
37957db96d56Sopenharmony_ci    return 0;
37967db96d56Sopenharmony_ci}
37977db96d56Sopenharmony_ci
37987db96d56Sopenharmony_cistatic void
37997db96d56Sopenharmony_cixmlparser_dealloc(XMLParserObject* self)
38007db96d56Sopenharmony_ci{
38017db96d56Sopenharmony_ci    PyObject_GC_UnTrack(self);
38027db96d56Sopenharmony_ci    xmlparser_gc_clear(self);
38037db96d56Sopenharmony_ci    Py_TYPE(self)->tp_free((PyObject *)self);
38047db96d56Sopenharmony_ci}
38057db96d56Sopenharmony_ci
38067db96d56Sopenharmony_ciPy_LOCAL_INLINE(int)
38077db96d56Sopenharmony_ci_check_xmlparser(XMLParserObject* self)
38087db96d56Sopenharmony_ci{
38097db96d56Sopenharmony_ci    if (self->target == NULL) {
38107db96d56Sopenharmony_ci        PyErr_SetString(PyExc_ValueError,
38117db96d56Sopenharmony_ci                        "XMLParser.__init__() wasn't called");
38127db96d56Sopenharmony_ci        return 0;
38137db96d56Sopenharmony_ci    }
38147db96d56Sopenharmony_ci    return 1;
38157db96d56Sopenharmony_ci}
38167db96d56Sopenharmony_ci
38177db96d56Sopenharmony_ciLOCAL(PyObject*)
38187db96d56Sopenharmony_ciexpat_parse(XMLParserObject* self, const char* data, int data_len, int final)
38197db96d56Sopenharmony_ci{
38207db96d56Sopenharmony_ci    int ok;
38217db96d56Sopenharmony_ci
38227db96d56Sopenharmony_ci    assert(!PyErr_Occurred());
38237db96d56Sopenharmony_ci    ok = EXPAT(Parse)(self->parser, data, data_len, final);
38247db96d56Sopenharmony_ci
38257db96d56Sopenharmony_ci    if (PyErr_Occurred())
38267db96d56Sopenharmony_ci        return NULL;
38277db96d56Sopenharmony_ci
38287db96d56Sopenharmony_ci    if (!ok) {
38297db96d56Sopenharmony_ci        expat_set_error(
38307db96d56Sopenharmony_ci            EXPAT(GetErrorCode)(self->parser),
38317db96d56Sopenharmony_ci            EXPAT(GetErrorLineNumber)(self->parser),
38327db96d56Sopenharmony_ci            EXPAT(GetErrorColumnNumber)(self->parser),
38337db96d56Sopenharmony_ci            NULL
38347db96d56Sopenharmony_ci            );
38357db96d56Sopenharmony_ci        return NULL;
38367db96d56Sopenharmony_ci    }
38377db96d56Sopenharmony_ci
38387db96d56Sopenharmony_ci    Py_RETURN_NONE;
38397db96d56Sopenharmony_ci}
38407db96d56Sopenharmony_ci
38417db96d56Sopenharmony_ci/*[clinic input]
38427db96d56Sopenharmony_ci_elementtree.XMLParser.close
38437db96d56Sopenharmony_ci
38447db96d56Sopenharmony_ci[clinic start generated code]*/
38457db96d56Sopenharmony_ci
38467db96d56Sopenharmony_cistatic PyObject *
38477db96d56Sopenharmony_ci_elementtree_XMLParser_close_impl(XMLParserObject *self)
38487db96d56Sopenharmony_ci/*[clinic end generated code: output=d68d375dd23bc7fb input=ca7909ca78c3abfe]*/
38497db96d56Sopenharmony_ci{
38507db96d56Sopenharmony_ci    /* end feeding data to parser */
38517db96d56Sopenharmony_ci
38527db96d56Sopenharmony_ci    PyObject* res;
38537db96d56Sopenharmony_ci
38547db96d56Sopenharmony_ci    if (!_check_xmlparser(self)) {
38557db96d56Sopenharmony_ci        return NULL;
38567db96d56Sopenharmony_ci    }
38577db96d56Sopenharmony_ci    res = expat_parse(self, "", 0, 1);
38587db96d56Sopenharmony_ci    if (!res)
38597db96d56Sopenharmony_ci        return NULL;
38607db96d56Sopenharmony_ci
38617db96d56Sopenharmony_ci    if (TreeBuilder_CheckExact(self->target)) {
38627db96d56Sopenharmony_ci        Py_DECREF(res);
38637db96d56Sopenharmony_ci        return treebuilder_done((TreeBuilderObject*) self->target);
38647db96d56Sopenharmony_ci    }
38657db96d56Sopenharmony_ci    else if (self->handle_close) {
38667db96d56Sopenharmony_ci        Py_DECREF(res);
38677db96d56Sopenharmony_ci        return PyObject_CallNoArgs(self->handle_close);
38687db96d56Sopenharmony_ci    }
38697db96d56Sopenharmony_ci    else {
38707db96d56Sopenharmony_ci        return res;
38717db96d56Sopenharmony_ci    }
38727db96d56Sopenharmony_ci}
38737db96d56Sopenharmony_ci
38747db96d56Sopenharmony_ci/*[clinic input]
38757db96d56Sopenharmony_ci_elementtree.XMLParser.feed
38767db96d56Sopenharmony_ci
38777db96d56Sopenharmony_ci    data: object
38787db96d56Sopenharmony_ci    /
38797db96d56Sopenharmony_ci
38807db96d56Sopenharmony_ci[clinic start generated code]*/
38817db96d56Sopenharmony_ci
38827db96d56Sopenharmony_cistatic PyObject *
38837db96d56Sopenharmony_ci_elementtree_XMLParser_feed(XMLParserObject *self, PyObject *data)
38847db96d56Sopenharmony_ci/*[clinic end generated code: output=e42b6a78eec7446d input=fe231b6b8de3ce1f]*/
38857db96d56Sopenharmony_ci{
38867db96d56Sopenharmony_ci    /* feed data to parser */
38877db96d56Sopenharmony_ci
38887db96d56Sopenharmony_ci    if (!_check_xmlparser(self)) {
38897db96d56Sopenharmony_ci        return NULL;
38907db96d56Sopenharmony_ci    }
38917db96d56Sopenharmony_ci    if (PyUnicode_Check(data)) {
38927db96d56Sopenharmony_ci        Py_ssize_t data_len;
38937db96d56Sopenharmony_ci        const char *data_ptr = PyUnicode_AsUTF8AndSize(data, &data_len);
38947db96d56Sopenharmony_ci        if (data_ptr == NULL)
38957db96d56Sopenharmony_ci            return NULL;
38967db96d56Sopenharmony_ci        if (data_len > INT_MAX) {
38977db96d56Sopenharmony_ci            PyErr_SetString(PyExc_OverflowError, "size does not fit in an int");
38987db96d56Sopenharmony_ci            return NULL;
38997db96d56Sopenharmony_ci        }
39007db96d56Sopenharmony_ci        /* Explicitly set UTF-8 encoding. Return code ignored. */
39017db96d56Sopenharmony_ci        (void)EXPAT(SetEncoding)(self->parser, "utf-8");
39027db96d56Sopenharmony_ci        return expat_parse(self, data_ptr, (int)data_len, 0);
39037db96d56Sopenharmony_ci    }
39047db96d56Sopenharmony_ci    else {
39057db96d56Sopenharmony_ci        Py_buffer view;
39067db96d56Sopenharmony_ci        PyObject *res;
39077db96d56Sopenharmony_ci        if (PyObject_GetBuffer(data, &view, PyBUF_SIMPLE) < 0)
39087db96d56Sopenharmony_ci            return NULL;
39097db96d56Sopenharmony_ci        if (view.len > INT_MAX) {
39107db96d56Sopenharmony_ci            PyBuffer_Release(&view);
39117db96d56Sopenharmony_ci            PyErr_SetString(PyExc_OverflowError, "size does not fit in an int");
39127db96d56Sopenharmony_ci            return NULL;
39137db96d56Sopenharmony_ci        }
39147db96d56Sopenharmony_ci        res = expat_parse(self, view.buf, (int)view.len, 0);
39157db96d56Sopenharmony_ci        PyBuffer_Release(&view);
39167db96d56Sopenharmony_ci        return res;
39177db96d56Sopenharmony_ci    }
39187db96d56Sopenharmony_ci}
39197db96d56Sopenharmony_ci
39207db96d56Sopenharmony_ci/*[clinic input]
39217db96d56Sopenharmony_ci_elementtree.XMLParser._parse_whole
39227db96d56Sopenharmony_ci
39237db96d56Sopenharmony_ci    file: object
39247db96d56Sopenharmony_ci    /
39257db96d56Sopenharmony_ci
39267db96d56Sopenharmony_ci[clinic start generated code]*/
39277db96d56Sopenharmony_ci
39287db96d56Sopenharmony_cistatic PyObject *
39297db96d56Sopenharmony_ci_elementtree_XMLParser__parse_whole(XMLParserObject *self, PyObject *file)
39307db96d56Sopenharmony_ci/*[clinic end generated code: output=f797197bb818dda3 input=19ecc893b6f3e752]*/
39317db96d56Sopenharmony_ci{
39327db96d56Sopenharmony_ci    /* (internal) parse the whole input, until end of stream */
39337db96d56Sopenharmony_ci    PyObject* reader;
39347db96d56Sopenharmony_ci    PyObject* buffer;
39357db96d56Sopenharmony_ci    PyObject* temp;
39367db96d56Sopenharmony_ci    PyObject* res;
39377db96d56Sopenharmony_ci
39387db96d56Sopenharmony_ci    if (!_check_xmlparser(self)) {
39397db96d56Sopenharmony_ci        return NULL;
39407db96d56Sopenharmony_ci    }
39417db96d56Sopenharmony_ci    reader = PyObject_GetAttrString(file, "read");
39427db96d56Sopenharmony_ci    if (!reader)
39437db96d56Sopenharmony_ci        return NULL;
39447db96d56Sopenharmony_ci
39457db96d56Sopenharmony_ci    /* read from open file object */
39467db96d56Sopenharmony_ci    for (;;) {
39477db96d56Sopenharmony_ci
39487db96d56Sopenharmony_ci        buffer = PyObject_CallFunction(reader, "i", 64*1024);
39497db96d56Sopenharmony_ci
39507db96d56Sopenharmony_ci        if (!buffer) {
39517db96d56Sopenharmony_ci            /* read failed (e.g. due to KeyboardInterrupt) */
39527db96d56Sopenharmony_ci            Py_DECREF(reader);
39537db96d56Sopenharmony_ci            return NULL;
39547db96d56Sopenharmony_ci        }
39557db96d56Sopenharmony_ci
39567db96d56Sopenharmony_ci        if (PyUnicode_CheckExact(buffer)) {
39577db96d56Sopenharmony_ci            /* A unicode object is encoded into bytes using UTF-8 */
39587db96d56Sopenharmony_ci            if (PyUnicode_GET_LENGTH(buffer) == 0) {
39597db96d56Sopenharmony_ci                Py_DECREF(buffer);
39607db96d56Sopenharmony_ci                break;
39617db96d56Sopenharmony_ci            }
39627db96d56Sopenharmony_ci            temp = PyUnicode_AsEncodedString(buffer, "utf-8", "surrogatepass");
39637db96d56Sopenharmony_ci            Py_DECREF(buffer);
39647db96d56Sopenharmony_ci            if (!temp) {
39657db96d56Sopenharmony_ci                /* Propagate exception from PyUnicode_AsEncodedString */
39667db96d56Sopenharmony_ci                Py_DECREF(reader);
39677db96d56Sopenharmony_ci                return NULL;
39687db96d56Sopenharmony_ci            }
39697db96d56Sopenharmony_ci            buffer = temp;
39707db96d56Sopenharmony_ci        }
39717db96d56Sopenharmony_ci        else if (!PyBytes_CheckExact(buffer) || PyBytes_GET_SIZE(buffer) == 0) {
39727db96d56Sopenharmony_ci            Py_DECREF(buffer);
39737db96d56Sopenharmony_ci            break;
39747db96d56Sopenharmony_ci        }
39757db96d56Sopenharmony_ci
39767db96d56Sopenharmony_ci        if (PyBytes_GET_SIZE(buffer) > INT_MAX) {
39777db96d56Sopenharmony_ci            Py_DECREF(buffer);
39787db96d56Sopenharmony_ci            Py_DECREF(reader);
39797db96d56Sopenharmony_ci            PyErr_SetString(PyExc_OverflowError, "size does not fit in an int");
39807db96d56Sopenharmony_ci            return NULL;
39817db96d56Sopenharmony_ci        }
39827db96d56Sopenharmony_ci        res = expat_parse(
39837db96d56Sopenharmony_ci            self, PyBytes_AS_STRING(buffer), (int)PyBytes_GET_SIZE(buffer), 0
39847db96d56Sopenharmony_ci            );
39857db96d56Sopenharmony_ci
39867db96d56Sopenharmony_ci        Py_DECREF(buffer);
39877db96d56Sopenharmony_ci
39887db96d56Sopenharmony_ci        if (!res) {
39897db96d56Sopenharmony_ci            Py_DECREF(reader);
39907db96d56Sopenharmony_ci            return NULL;
39917db96d56Sopenharmony_ci        }
39927db96d56Sopenharmony_ci        Py_DECREF(res);
39937db96d56Sopenharmony_ci
39947db96d56Sopenharmony_ci    }
39957db96d56Sopenharmony_ci
39967db96d56Sopenharmony_ci    Py_DECREF(reader);
39977db96d56Sopenharmony_ci
39987db96d56Sopenharmony_ci    res = expat_parse(self, "", 0, 1);
39997db96d56Sopenharmony_ci
40007db96d56Sopenharmony_ci    if (res && TreeBuilder_CheckExact(self->target)) {
40017db96d56Sopenharmony_ci        Py_DECREF(res);
40027db96d56Sopenharmony_ci        return treebuilder_done((TreeBuilderObject*) self->target);
40037db96d56Sopenharmony_ci    }
40047db96d56Sopenharmony_ci
40057db96d56Sopenharmony_ci    return res;
40067db96d56Sopenharmony_ci}
40077db96d56Sopenharmony_ci
40087db96d56Sopenharmony_ci/*[clinic input]
40097db96d56Sopenharmony_ci_elementtree.XMLParser._setevents
40107db96d56Sopenharmony_ci
40117db96d56Sopenharmony_ci    events_queue: object
40127db96d56Sopenharmony_ci    events_to_report: object = None
40137db96d56Sopenharmony_ci    /
40147db96d56Sopenharmony_ci
40157db96d56Sopenharmony_ci[clinic start generated code]*/
40167db96d56Sopenharmony_ci
40177db96d56Sopenharmony_cistatic PyObject *
40187db96d56Sopenharmony_ci_elementtree_XMLParser__setevents_impl(XMLParserObject *self,
40197db96d56Sopenharmony_ci                                       PyObject *events_queue,
40207db96d56Sopenharmony_ci                                       PyObject *events_to_report)
40217db96d56Sopenharmony_ci/*[clinic end generated code: output=1440092922b13ed1 input=abf90830a1c3b0fc]*/
40227db96d56Sopenharmony_ci{
40237db96d56Sopenharmony_ci    /* activate element event reporting */
40247db96d56Sopenharmony_ci    Py_ssize_t i;
40257db96d56Sopenharmony_ci    TreeBuilderObject *target;
40267db96d56Sopenharmony_ci    PyObject *events_append, *events_seq;
40277db96d56Sopenharmony_ci
40287db96d56Sopenharmony_ci    if (!_check_xmlparser(self)) {
40297db96d56Sopenharmony_ci        return NULL;
40307db96d56Sopenharmony_ci    }
40317db96d56Sopenharmony_ci    if (!TreeBuilder_CheckExact(self->target)) {
40327db96d56Sopenharmony_ci        PyErr_SetString(
40337db96d56Sopenharmony_ci            PyExc_TypeError,
40347db96d56Sopenharmony_ci            "event handling only supported for ElementTree.TreeBuilder "
40357db96d56Sopenharmony_ci            "targets"
40367db96d56Sopenharmony_ci            );
40377db96d56Sopenharmony_ci        return NULL;
40387db96d56Sopenharmony_ci    }
40397db96d56Sopenharmony_ci
40407db96d56Sopenharmony_ci    target = (TreeBuilderObject*) self->target;
40417db96d56Sopenharmony_ci
40427db96d56Sopenharmony_ci    events_append = PyObject_GetAttrString(events_queue, "append");
40437db96d56Sopenharmony_ci    if (events_append == NULL)
40447db96d56Sopenharmony_ci        return NULL;
40457db96d56Sopenharmony_ci    Py_XSETREF(target->events_append, events_append);
40467db96d56Sopenharmony_ci
40477db96d56Sopenharmony_ci    /* clear out existing events */
40487db96d56Sopenharmony_ci    Py_CLEAR(target->start_event_obj);
40497db96d56Sopenharmony_ci    Py_CLEAR(target->end_event_obj);
40507db96d56Sopenharmony_ci    Py_CLEAR(target->start_ns_event_obj);
40517db96d56Sopenharmony_ci    Py_CLEAR(target->end_ns_event_obj);
40527db96d56Sopenharmony_ci    Py_CLEAR(target->comment_event_obj);
40537db96d56Sopenharmony_ci    Py_CLEAR(target->pi_event_obj);
40547db96d56Sopenharmony_ci
40557db96d56Sopenharmony_ci    if (events_to_report == Py_None) {
40567db96d56Sopenharmony_ci        /* default is "end" only */
40577db96d56Sopenharmony_ci        target->end_event_obj = PyUnicode_FromString("end");
40587db96d56Sopenharmony_ci        Py_RETURN_NONE;
40597db96d56Sopenharmony_ci    }
40607db96d56Sopenharmony_ci
40617db96d56Sopenharmony_ci    if (!(events_seq = PySequence_Fast(events_to_report,
40627db96d56Sopenharmony_ci                                       "events must be a sequence"))) {
40637db96d56Sopenharmony_ci        return NULL;
40647db96d56Sopenharmony_ci    }
40657db96d56Sopenharmony_ci
40667db96d56Sopenharmony_ci    for (i = 0; i < PySequence_Fast_GET_SIZE(events_seq); ++i) {
40677db96d56Sopenharmony_ci        PyObject *event_name_obj = PySequence_Fast_GET_ITEM(events_seq, i);
40687db96d56Sopenharmony_ci        const char *event_name = NULL;
40697db96d56Sopenharmony_ci        if (PyUnicode_Check(event_name_obj)) {
40707db96d56Sopenharmony_ci            event_name = PyUnicode_AsUTF8(event_name_obj);
40717db96d56Sopenharmony_ci        } else if (PyBytes_Check(event_name_obj)) {
40727db96d56Sopenharmony_ci            event_name = PyBytes_AS_STRING(event_name_obj);
40737db96d56Sopenharmony_ci        }
40747db96d56Sopenharmony_ci        if (event_name == NULL) {
40757db96d56Sopenharmony_ci            Py_DECREF(events_seq);
40767db96d56Sopenharmony_ci            PyErr_Format(PyExc_ValueError, "invalid events sequence");
40777db96d56Sopenharmony_ci            return NULL;
40787db96d56Sopenharmony_ci        }
40797db96d56Sopenharmony_ci
40807db96d56Sopenharmony_ci        Py_INCREF(event_name_obj);
40817db96d56Sopenharmony_ci        if (strcmp(event_name, "start") == 0) {
40827db96d56Sopenharmony_ci            Py_XSETREF(target->start_event_obj, event_name_obj);
40837db96d56Sopenharmony_ci        } else if (strcmp(event_name, "end") == 0) {
40847db96d56Sopenharmony_ci            Py_XSETREF(target->end_event_obj, event_name_obj);
40857db96d56Sopenharmony_ci        } else if (strcmp(event_name, "start-ns") == 0) {
40867db96d56Sopenharmony_ci            Py_XSETREF(target->start_ns_event_obj, event_name_obj);
40877db96d56Sopenharmony_ci            EXPAT(SetNamespaceDeclHandler)(
40887db96d56Sopenharmony_ci                self->parser,
40897db96d56Sopenharmony_ci                (XML_StartNamespaceDeclHandler) expat_start_ns_handler,
40907db96d56Sopenharmony_ci                (XML_EndNamespaceDeclHandler) expat_end_ns_handler
40917db96d56Sopenharmony_ci                );
40927db96d56Sopenharmony_ci        } else if (strcmp(event_name, "end-ns") == 0) {
40937db96d56Sopenharmony_ci            Py_XSETREF(target->end_ns_event_obj, event_name_obj);
40947db96d56Sopenharmony_ci            EXPAT(SetNamespaceDeclHandler)(
40957db96d56Sopenharmony_ci                self->parser,
40967db96d56Sopenharmony_ci                (XML_StartNamespaceDeclHandler) expat_start_ns_handler,
40977db96d56Sopenharmony_ci                (XML_EndNamespaceDeclHandler) expat_end_ns_handler
40987db96d56Sopenharmony_ci                );
40997db96d56Sopenharmony_ci        } else if (strcmp(event_name, "comment") == 0) {
41007db96d56Sopenharmony_ci            Py_XSETREF(target->comment_event_obj, event_name_obj);
41017db96d56Sopenharmony_ci            EXPAT(SetCommentHandler)(
41027db96d56Sopenharmony_ci                self->parser,
41037db96d56Sopenharmony_ci                (XML_CommentHandler) expat_comment_handler
41047db96d56Sopenharmony_ci                );
41057db96d56Sopenharmony_ci        } else if (strcmp(event_name, "pi") == 0) {
41067db96d56Sopenharmony_ci            Py_XSETREF(target->pi_event_obj, event_name_obj);
41077db96d56Sopenharmony_ci            EXPAT(SetProcessingInstructionHandler)(
41087db96d56Sopenharmony_ci                self->parser,
41097db96d56Sopenharmony_ci                (XML_ProcessingInstructionHandler) expat_pi_handler
41107db96d56Sopenharmony_ci                );
41117db96d56Sopenharmony_ci        } else {
41127db96d56Sopenharmony_ci            Py_DECREF(event_name_obj);
41137db96d56Sopenharmony_ci            Py_DECREF(events_seq);
41147db96d56Sopenharmony_ci            PyErr_Format(PyExc_ValueError, "unknown event '%s'", event_name);
41157db96d56Sopenharmony_ci            return NULL;
41167db96d56Sopenharmony_ci        }
41177db96d56Sopenharmony_ci    }
41187db96d56Sopenharmony_ci
41197db96d56Sopenharmony_ci    Py_DECREF(events_seq);
41207db96d56Sopenharmony_ci    Py_RETURN_NONE;
41217db96d56Sopenharmony_ci}
41227db96d56Sopenharmony_ci
41237db96d56Sopenharmony_cistatic PyMemberDef xmlparser_members[] = {
41247db96d56Sopenharmony_ci    {"entity", T_OBJECT, offsetof(XMLParserObject, entity), READONLY, NULL},
41257db96d56Sopenharmony_ci    {"target", T_OBJECT, offsetof(XMLParserObject, target), READONLY, NULL},
41267db96d56Sopenharmony_ci    {NULL}
41277db96d56Sopenharmony_ci};
41287db96d56Sopenharmony_ci
41297db96d56Sopenharmony_cistatic PyObject*
41307db96d56Sopenharmony_cixmlparser_version_getter(XMLParserObject *self, void *closure)
41317db96d56Sopenharmony_ci{
41327db96d56Sopenharmony_ci    return PyUnicode_FromFormat(
41337db96d56Sopenharmony_ci        "Expat %d.%d.%d", XML_MAJOR_VERSION,
41347db96d56Sopenharmony_ci        XML_MINOR_VERSION, XML_MICRO_VERSION);
41357db96d56Sopenharmony_ci}
41367db96d56Sopenharmony_ci
41377db96d56Sopenharmony_cistatic PyGetSetDef xmlparser_getsetlist[] = {
41387db96d56Sopenharmony_ci    {"version", (getter)xmlparser_version_getter, NULL, NULL},
41397db96d56Sopenharmony_ci    {NULL},
41407db96d56Sopenharmony_ci};
41417db96d56Sopenharmony_ci
41427db96d56Sopenharmony_ci#include "clinic/_elementtree.c.h"
41437db96d56Sopenharmony_ci
41447db96d56Sopenharmony_cistatic PyMethodDef element_methods[] = {
41457db96d56Sopenharmony_ci
41467db96d56Sopenharmony_ci    _ELEMENTTREE_ELEMENT_CLEAR_METHODDEF
41477db96d56Sopenharmony_ci
41487db96d56Sopenharmony_ci    _ELEMENTTREE_ELEMENT_GET_METHODDEF
41497db96d56Sopenharmony_ci    _ELEMENTTREE_ELEMENT_SET_METHODDEF
41507db96d56Sopenharmony_ci
41517db96d56Sopenharmony_ci    _ELEMENTTREE_ELEMENT_FIND_METHODDEF
41527db96d56Sopenharmony_ci    _ELEMENTTREE_ELEMENT_FINDTEXT_METHODDEF
41537db96d56Sopenharmony_ci    _ELEMENTTREE_ELEMENT_FINDALL_METHODDEF
41547db96d56Sopenharmony_ci
41557db96d56Sopenharmony_ci    _ELEMENTTREE_ELEMENT_APPEND_METHODDEF
41567db96d56Sopenharmony_ci    _ELEMENTTREE_ELEMENT_EXTEND_METHODDEF
41577db96d56Sopenharmony_ci    _ELEMENTTREE_ELEMENT_INSERT_METHODDEF
41587db96d56Sopenharmony_ci    _ELEMENTTREE_ELEMENT_REMOVE_METHODDEF
41597db96d56Sopenharmony_ci
41607db96d56Sopenharmony_ci    _ELEMENTTREE_ELEMENT_ITER_METHODDEF
41617db96d56Sopenharmony_ci    _ELEMENTTREE_ELEMENT_ITERTEXT_METHODDEF
41627db96d56Sopenharmony_ci    _ELEMENTTREE_ELEMENT_ITERFIND_METHODDEF
41637db96d56Sopenharmony_ci
41647db96d56Sopenharmony_ci    _ELEMENTTREE_ELEMENT_ITEMS_METHODDEF
41657db96d56Sopenharmony_ci    _ELEMENTTREE_ELEMENT_KEYS_METHODDEF
41667db96d56Sopenharmony_ci
41677db96d56Sopenharmony_ci    _ELEMENTTREE_ELEMENT_MAKEELEMENT_METHODDEF
41687db96d56Sopenharmony_ci
41697db96d56Sopenharmony_ci    _ELEMENTTREE_ELEMENT___COPY___METHODDEF
41707db96d56Sopenharmony_ci    _ELEMENTTREE_ELEMENT___DEEPCOPY___METHODDEF
41717db96d56Sopenharmony_ci    _ELEMENTTREE_ELEMENT___SIZEOF___METHODDEF
41727db96d56Sopenharmony_ci    _ELEMENTTREE_ELEMENT___GETSTATE___METHODDEF
41737db96d56Sopenharmony_ci    _ELEMENTTREE_ELEMENT___SETSTATE___METHODDEF
41747db96d56Sopenharmony_ci
41757db96d56Sopenharmony_ci    {NULL, NULL}
41767db96d56Sopenharmony_ci};
41777db96d56Sopenharmony_ci
41787db96d56Sopenharmony_cistatic PyMappingMethods element_as_mapping = {
41797db96d56Sopenharmony_ci    (lenfunc) element_length,
41807db96d56Sopenharmony_ci    (binaryfunc) element_subscr,
41817db96d56Sopenharmony_ci    (objobjargproc) element_ass_subscr,
41827db96d56Sopenharmony_ci};
41837db96d56Sopenharmony_ci
41847db96d56Sopenharmony_cistatic PyGetSetDef element_getsetlist[] = {
41857db96d56Sopenharmony_ci    {"tag",
41867db96d56Sopenharmony_ci        (getter)element_tag_getter,
41877db96d56Sopenharmony_ci        (setter)element_tag_setter,
41887db96d56Sopenharmony_ci        "A string identifying what kind of data this element represents"},
41897db96d56Sopenharmony_ci    {"text",
41907db96d56Sopenharmony_ci        (getter)element_text_getter,
41917db96d56Sopenharmony_ci        (setter)element_text_setter,
41927db96d56Sopenharmony_ci        "A string of text directly after the start tag, or None"},
41937db96d56Sopenharmony_ci    {"tail",
41947db96d56Sopenharmony_ci        (getter)element_tail_getter,
41957db96d56Sopenharmony_ci        (setter)element_tail_setter,
41967db96d56Sopenharmony_ci        "A string of text directly after the end tag, or None"},
41977db96d56Sopenharmony_ci    {"attrib",
41987db96d56Sopenharmony_ci        (getter)element_attrib_getter,
41997db96d56Sopenharmony_ci        (setter)element_attrib_setter,
42007db96d56Sopenharmony_ci        "A dictionary containing the element's attributes"},
42017db96d56Sopenharmony_ci    {NULL},
42027db96d56Sopenharmony_ci};
42037db96d56Sopenharmony_ci
42047db96d56Sopenharmony_cistatic PyTypeObject Element_Type = {
42057db96d56Sopenharmony_ci    PyVarObject_HEAD_INIT(NULL, 0)
42067db96d56Sopenharmony_ci    "xml.etree.ElementTree.Element", sizeof(ElementObject), 0,
42077db96d56Sopenharmony_ci    /* methods */
42087db96d56Sopenharmony_ci    (destructor)element_dealloc,                    /* tp_dealloc */
42097db96d56Sopenharmony_ci    0,                                              /* tp_vectorcall_offset */
42107db96d56Sopenharmony_ci    0,                                              /* tp_getattr */
42117db96d56Sopenharmony_ci    0,                                              /* tp_setattr */
42127db96d56Sopenharmony_ci    0,                                              /* tp_as_async */
42137db96d56Sopenharmony_ci    (reprfunc)element_repr,                         /* tp_repr */
42147db96d56Sopenharmony_ci    0,                                              /* tp_as_number */
42157db96d56Sopenharmony_ci    &element_as_sequence,                           /* tp_as_sequence */
42167db96d56Sopenharmony_ci    &element_as_mapping,                            /* tp_as_mapping */
42177db96d56Sopenharmony_ci    0,                                              /* tp_hash */
42187db96d56Sopenharmony_ci    0,                                              /* tp_call */
42197db96d56Sopenharmony_ci    0,                                              /* tp_str */
42207db96d56Sopenharmony_ci    PyObject_GenericGetAttr,                        /* tp_getattro */
42217db96d56Sopenharmony_ci    0,                                              /* tp_setattro */
42227db96d56Sopenharmony_ci    0,                                              /* tp_as_buffer */
42237db96d56Sopenharmony_ci    Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC,
42247db96d56Sopenharmony_ci                                                    /* tp_flags */
42257db96d56Sopenharmony_ci    0,                                              /* tp_doc */
42267db96d56Sopenharmony_ci    (traverseproc)element_gc_traverse,              /* tp_traverse */
42277db96d56Sopenharmony_ci    (inquiry)element_gc_clear,                      /* tp_clear */
42287db96d56Sopenharmony_ci    0,                                              /* tp_richcompare */
42297db96d56Sopenharmony_ci    offsetof(ElementObject, weakreflist),           /* tp_weaklistoffset */
42307db96d56Sopenharmony_ci    0,                                              /* tp_iter */
42317db96d56Sopenharmony_ci    0,                                              /* tp_iternext */
42327db96d56Sopenharmony_ci    element_methods,                                /* tp_methods */
42337db96d56Sopenharmony_ci    0,                                              /* tp_members */
42347db96d56Sopenharmony_ci    element_getsetlist,                             /* tp_getset */
42357db96d56Sopenharmony_ci    0,                                              /* tp_base */
42367db96d56Sopenharmony_ci    0,                                              /* tp_dict */
42377db96d56Sopenharmony_ci    0,                                              /* tp_descr_get */
42387db96d56Sopenharmony_ci    0,                                              /* tp_descr_set */
42397db96d56Sopenharmony_ci    0,                                              /* tp_dictoffset */
42407db96d56Sopenharmony_ci    (initproc)element_init,                         /* tp_init */
42417db96d56Sopenharmony_ci    PyType_GenericAlloc,                            /* tp_alloc */
42427db96d56Sopenharmony_ci    element_new,                                    /* tp_new */
42437db96d56Sopenharmony_ci    0,                                              /* tp_free */
42447db96d56Sopenharmony_ci};
42457db96d56Sopenharmony_ci
42467db96d56Sopenharmony_cistatic PyMethodDef treebuilder_methods[] = {
42477db96d56Sopenharmony_ci    _ELEMENTTREE_TREEBUILDER_DATA_METHODDEF
42487db96d56Sopenharmony_ci    _ELEMENTTREE_TREEBUILDER_START_METHODDEF
42497db96d56Sopenharmony_ci    _ELEMENTTREE_TREEBUILDER_END_METHODDEF
42507db96d56Sopenharmony_ci    _ELEMENTTREE_TREEBUILDER_COMMENT_METHODDEF
42517db96d56Sopenharmony_ci    _ELEMENTTREE_TREEBUILDER_PI_METHODDEF
42527db96d56Sopenharmony_ci    _ELEMENTTREE_TREEBUILDER_CLOSE_METHODDEF
42537db96d56Sopenharmony_ci    {NULL, NULL}
42547db96d56Sopenharmony_ci};
42557db96d56Sopenharmony_ci
42567db96d56Sopenharmony_cistatic PyTypeObject TreeBuilder_Type = {
42577db96d56Sopenharmony_ci    PyVarObject_HEAD_INIT(NULL, 0)
42587db96d56Sopenharmony_ci    "xml.etree.ElementTree.TreeBuilder", sizeof(TreeBuilderObject), 0,
42597db96d56Sopenharmony_ci    /* methods */
42607db96d56Sopenharmony_ci    (destructor)treebuilder_dealloc,                /* tp_dealloc */
42617db96d56Sopenharmony_ci    0,                                              /* tp_vectorcall_offset */
42627db96d56Sopenharmony_ci    0,                                              /* tp_getattr */
42637db96d56Sopenharmony_ci    0,                                              /* tp_setattr */
42647db96d56Sopenharmony_ci    0,                                              /* tp_as_async */
42657db96d56Sopenharmony_ci    0,                                              /* tp_repr */
42667db96d56Sopenharmony_ci    0,                                              /* tp_as_number */
42677db96d56Sopenharmony_ci    0,                                              /* tp_as_sequence */
42687db96d56Sopenharmony_ci    0,                                              /* tp_as_mapping */
42697db96d56Sopenharmony_ci    0,                                              /* tp_hash */
42707db96d56Sopenharmony_ci    0,                                              /* tp_call */
42717db96d56Sopenharmony_ci    0,                                              /* tp_str */
42727db96d56Sopenharmony_ci    0,                                              /* tp_getattro */
42737db96d56Sopenharmony_ci    0,                                              /* tp_setattro */
42747db96d56Sopenharmony_ci    0,                                              /* tp_as_buffer */
42757db96d56Sopenharmony_ci    Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC,
42767db96d56Sopenharmony_ci                                                    /* tp_flags */
42777db96d56Sopenharmony_ci    0,                                              /* tp_doc */
42787db96d56Sopenharmony_ci    (traverseproc)treebuilder_gc_traverse,          /* tp_traverse */
42797db96d56Sopenharmony_ci    (inquiry)treebuilder_gc_clear,                  /* tp_clear */
42807db96d56Sopenharmony_ci    0,                                              /* tp_richcompare */
42817db96d56Sopenharmony_ci    0,                                              /* tp_weaklistoffset */
42827db96d56Sopenharmony_ci    0,                                              /* tp_iter */
42837db96d56Sopenharmony_ci    0,                                              /* tp_iternext */
42847db96d56Sopenharmony_ci    treebuilder_methods,                            /* tp_methods */
42857db96d56Sopenharmony_ci    0,                                              /* tp_members */
42867db96d56Sopenharmony_ci    0,                                              /* tp_getset */
42877db96d56Sopenharmony_ci    0,                                              /* tp_base */
42887db96d56Sopenharmony_ci    0,                                              /* tp_dict */
42897db96d56Sopenharmony_ci    0,                                              /* tp_descr_get */
42907db96d56Sopenharmony_ci    0,                                              /* tp_descr_set */
42917db96d56Sopenharmony_ci    0,                                              /* tp_dictoffset */
42927db96d56Sopenharmony_ci    _elementtree_TreeBuilder___init__,              /* tp_init */
42937db96d56Sopenharmony_ci    PyType_GenericAlloc,                            /* tp_alloc */
42947db96d56Sopenharmony_ci    treebuilder_new,                                /* tp_new */
42957db96d56Sopenharmony_ci    0,                                              /* tp_free */
42967db96d56Sopenharmony_ci};
42977db96d56Sopenharmony_ci
42987db96d56Sopenharmony_cistatic PyMethodDef xmlparser_methods[] = {
42997db96d56Sopenharmony_ci    _ELEMENTTREE_XMLPARSER_FEED_METHODDEF
43007db96d56Sopenharmony_ci    _ELEMENTTREE_XMLPARSER_CLOSE_METHODDEF
43017db96d56Sopenharmony_ci    _ELEMENTTREE_XMLPARSER__PARSE_WHOLE_METHODDEF
43027db96d56Sopenharmony_ci    _ELEMENTTREE_XMLPARSER__SETEVENTS_METHODDEF
43037db96d56Sopenharmony_ci    {NULL, NULL}
43047db96d56Sopenharmony_ci};
43057db96d56Sopenharmony_ci
43067db96d56Sopenharmony_cistatic PyTypeObject XMLParser_Type = {
43077db96d56Sopenharmony_ci    PyVarObject_HEAD_INIT(NULL, 0)
43087db96d56Sopenharmony_ci    "xml.etree.ElementTree.XMLParser", sizeof(XMLParserObject), 0,
43097db96d56Sopenharmony_ci    /* methods */
43107db96d56Sopenharmony_ci    (destructor)xmlparser_dealloc,                  /* tp_dealloc */
43117db96d56Sopenharmony_ci    0,                                              /* tp_vectorcall_offset */
43127db96d56Sopenharmony_ci    0,                                              /* tp_getattr */
43137db96d56Sopenharmony_ci    0,                                              /* tp_setattr */
43147db96d56Sopenharmony_ci    0,                                              /* tp_as_async */
43157db96d56Sopenharmony_ci    0,                                              /* tp_repr */
43167db96d56Sopenharmony_ci    0,                                              /* tp_as_number */
43177db96d56Sopenharmony_ci    0,                                              /* tp_as_sequence */
43187db96d56Sopenharmony_ci    0,                                              /* tp_as_mapping */
43197db96d56Sopenharmony_ci    0,                                              /* tp_hash */
43207db96d56Sopenharmony_ci    0,                                              /* tp_call */
43217db96d56Sopenharmony_ci    0,                                              /* tp_str */
43227db96d56Sopenharmony_ci    0,                                              /* tp_getattro */
43237db96d56Sopenharmony_ci    0,                                              /* tp_setattro */
43247db96d56Sopenharmony_ci    0,                                              /* tp_as_buffer */
43257db96d56Sopenharmony_ci    Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC,
43267db96d56Sopenharmony_ci                                                    /* tp_flags */
43277db96d56Sopenharmony_ci    0,                                              /* tp_doc */
43287db96d56Sopenharmony_ci    (traverseproc)xmlparser_gc_traverse,            /* tp_traverse */
43297db96d56Sopenharmony_ci    (inquiry)xmlparser_gc_clear,                    /* tp_clear */
43307db96d56Sopenharmony_ci    0,                                              /* tp_richcompare */
43317db96d56Sopenharmony_ci    0,                                              /* tp_weaklistoffset */
43327db96d56Sopenharmony_ci    0,                                              /* tp_iter */
43337db96d56Sopenharmony_ci    0,                                              /* tp_iternext */
43347db96d56Sopenharmony_ci    xmlparser_methods,                              /* tp_methods */
43357db96d56Sopenharmony_ci    xmlparser_members,                              /* tp_members */
43367db96d56Sopenharmony_ci    xmlparser_getsetlist,                           /* tp_getset */
43377db96d56Sopenharmony_ci    0,                                              /* tp_base */
43387db96d56Sopenharmony_ci    0,                                              /* tp_dict */
43397db96d56Sopenharmony_ci    0,                                              /* tp_descr_get */
43407db96d56Sopenharmony_ci    0,                                              /* tp_descr_set */
43417db96d56Sopenharmony_ci    0,                                              /* tp_dictoffset */
43427db96d56Sopenharmony_ci    _elementtree_XMLParser___init__,                /* tp_init */
43437db96d56Sopenharmony_ci    PyType_GenericAlloc,                            /* tp_alloc */
43447db96d56Sopenharmony_ci    xmlparser_new,                                  /* tp_new */
43457db96d56Sopenharmony_ci    0,                                              /* tp_free */
43467db96d56Sopenharmony_ci};
43477db96d56Sopenharmony_ci
43487db96d56Sopenharmony_ci/* ==================================================================== */
43497db96d56Sopenharmony_ci/* python module interface */
43507db96d56Sopenharmony_ci
43517db96d56Sopenharmony_cistatic PyMethodDef _functions[] = {
43527db96d56Sopenharmony_ci    {"SubElement", _PyCFunction_CAST(subelement), METH_VARARGS | METH_KEYWORDS},
43537db96d56Sopenharmony_ci    _ELEMENTTREE__SET_FACTORIES_METHODDEF
43547db96d56Sopenharmony_ci    {NULL, NULL}
43557db96d56Sopenharmony_ci};
43567db96d56Sopenharmony_ci
43577db96d56Sopenharmony_ci
43587db96d56Sopenharmony_cistatic struct PyModuleDef elementtreemodule = {
43597db96d56Sopenharmony_ci    PyModuleDef_HEAD_INIT,
43607db96d56Sopenharmony_ci    "_elementtree",
43617db96d56Sopenharmony_ci    NULL,
43627db96d56Sopenharmony_ci    sizeof(elementtreestate),
43637db96d56Sopenharmony_ci    _functions,
43647db96d56Sopenharmony_ci    NULL,
43657db96d56Sopenharmony_ci    elementtree_traverse,
43667db96d56Sopenharmony_ci    elementtree_clear,
43677db96d56Sopenharmony_ci    elementtree_free
43687db96d56Sopenharmony_ci};
43697db96d56Sopenharmony_ci
43707db96d56Sopenharmony_ciPyMODINIT_FUNC
43717db96d56Sopenharmony_ciPyInit__elementtree(void)
43727db96d56Sopenharmony_ci{
43737db96d56Sopenharmony_ci    PyObject *m, *temp;
43747db96d56Sopenharmony_ci    elementtreestate *st;
43757db96d56Sopenharmony_ci
43767db96d56Sopenharmony_ci    m = PyState_FindModule(&elementtreemodule);
43777db96d56Sopenharmony_ci    if (m) {
43787db96d56Sopenharmony_ci        Py_INCREF(m);
43797db96d56Sopenharmony_ci        return m;
43807db96d56Sopenharmony_ci    }
43817db96d56Sopenharmony_ci
43827db96d56Sopenharmony_ci    /* Initialize object types */
43837db96d56Sopenharmony_ci    if (PyType_Ready(&ElementIter_Type) < 0)
43847db96d56Sopenharmony_ci        return NULL;
43857db96d56Sopenharmony_ci    if (PyType_Ready(&TreeBuilder_Type) < 0)
43867db96d56Sopenharmony_ci        return NULL;
43877db96d56Sopenharmony_ci    if (PyType_Ready(&Element_Type) < 0)
43887db96d56Sopenharmony_ci        return NULL;
43897db96d56Sopenharmony_ci    if (PyType_Ready(&XMLParser_Type) < 0)
43907db96d56Sopenharmony_ci        return NULL;
43917db96d56Sopenharmony_ci
43927db96d56Sopenharmony_ci    m = PyModule_Create(&elementtreemodule);
43937db96d56Sopenharmony_ci    if (!m)
43947db96d56Sopenharmony_ci        return NULL;
43957db96d56Sopenharmony_ci    st = get_elementtree_state(m);
43967db96d56Sopenharmony_ci
43977db96d56Sopenharmony_ci    if (!(temp = PyImport_ImportModule("copy")))
43987db96d56Sopenharmony_ci        return NULL;
43997db96d56Sopenharmony_ci    st->deepcopy_obj = PyObject_GetAttrString(temp, "deepcopy");
44007db96d56Sopenharmony_ci    Py_XDECREF(temp);
44017db96d56Sopenharmony_ci
44027db96d56Sopenharmony_ci    if (st->deepcopy_obj == NULL) {
44037db96d56Sopenharmony_ci        return NULL;
44047db96d56Sopenharmony_ci    }
44057db96d56Sopenharmony_ci
44067db96d56Sopenharmony_ci    assert(!PyErr_Occurred());
44077db96d56Sopenharmony_ci    if (!(st->elementpath_obj = PyImport_ImportModule("xml.etree.ElementPath")))
44087db96d56Sopenharmony_ci        return NULL;
44097db96d56Sopenharmony_ci
44107db96d56Sopenharmony_ci    /* link against pyexpat */
44117db96d56Sopenharmony_ci    expat_capi = PyCapsule_Import(PyExpat_CAPSULE_NAME, 0);
44127db96d56Sopenharmony_ci    if (expat_capi) {
44137db96d56Sopenharmony_ci        /* check that it's usable */
44147db96d56Sopenharmony_ci        if (strcmp(expat_capi->magic, PyExpat_CAPI_MAGIC) != 0 ||
44157db96d56Sopenharmony_ci            (size_t)expat_capi->size < sizeof(struct PyExpat_CAPI) ||
44167db96d56Sopenharmony_ci            expat_capi->MAJOR_VERSION != XML_MAJOR_VERSION ||
44177db96d56Sopenharmony_ci            expat_capi->MINOR_VERSION != XML_MINOR_VERSION ||
44187db96d56Sopenharmony_ci            expat_capi->MICRO_VERSION != XML_MICRO_VERSION) {
44197db96d56Sopenharmony_ci            PyErr_SetString(PyExc_ImportError,
44207db96d56Sopenharmony_ci                            "pyexpat version is incompatible");
44217db96d56Sopenharmony_ci            return NULL;
44227db96d56Sopenharmony_ci        }
44237db96d56Sopenharmony_ci    } else {
44247db96d56Sopenharmony_ci        return NULL;
44257db96d56Sopenharmony_ci    }
44267db96d56Sopenharmony_ci
44277db96d56Sopenharmony_ci    st->parseerror_obj = PyErr_NewException(
44287db96d56Sopenharmony_ci        "xml.etree.ElementTree.ParseError", PyExc_SyntaxError, NULL
44297db96d56Sopenharmony_ci        );
44307db96d56Sopenharmony_ci    Py_INCREF(st->parseerror_obj);
44317db96d56Sopenharmony_ci    if (PyModule_AddObject(m, "ParseError", st->parseerror_obj) < 0) {
44327db96d56Sopenharmony_ci        Py_DECREF(st->parseerror_obj);
44337db96d56Sopenharmony_ci        return NULL;
44347db96d56Sopenharmony_ci    }
44357db96d56Sopenharmony_ci
44367db96d56Sopenharmony_ci    PyTypeObject *types[] = {
44377db96d56Sopenharmony_ci        &Element_Type,
44387db96d56Sopenharmony_ci        &TreeBuilder_Type,
44397db96d56Sopenharmony_ci        &XMLParser_Type
44407db96d56Sopenharmony_ci    };
44417db96d56Sopenharmony_ci
44427db96d56Sopenharmony_ci    for (size_t i = 0; i < Py_ARRAY_LENGTH(types); i++) {
44437db96d56Sopenharmony_ci        if (PyModule_AddType(m, types[i]) < 0) {
44447db96d56Sopenharmony_ci            return NULL;
44457db96d56Sopenharmony_ci        }
44467db96d56Sopenharmony_ci    }
44477db96d56Sopenharmony_ci
44487db96d56Sopenharmony_ci    return m;
44497db96d56Sopenharmony_ci}
4450