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