| Eli Bendersky | bf05df2 | 2013-04-20 05:44:01 -0700 | [diff] [blame] | 1 | /*-------------------------------------------------------------------- | 
 | 2 |  * Licensed to PSF under a Contributor Agreement. | 
 | 3 |  * See http://www.python.org/psf/license for licensing details. | 
| Fredrik Lundh | 8c8836b | 2005-12-16 22:06:06 +0000 | [diff] [blame] | 4 |  * | 
| Eli Bendersky | bf05df2 | 2013-04-20 05:44:01 -0700 | [diff] [blame] | 5 |  * _elementtree - C accelerator for xml.etree.ElementTree | 
| Florent Xicluna | f15351d | 2010-03-13 23:24:31 +0000 | [diff] [blame] | 6 |  * Copyright (c) 1999-2009 by Secret Labs AB.  All rights reserved. | 
 | 7 |  * Copyright (c) 1999-2009 by Fredrik Lundh. | 
| Fredrik Lundh | 8c8836b | 2005-12-16 22:06:06 +0000 | [diff] [blame] | 8 |  * | 
 | 9 |  * info@pythonware.com | 
 | 10 |  * http://www.pythonware.com | 
| Eli Bendersky | bf05df2 | 2013-04-20 05:44:01 -0700 | [diff] [blame] | 11 |  *-------------------------------------------------------------------- | 
| Fredrik Lundh | 8c8836b | 2005-12-16 22:06:06 +0000 | [diff] [blame] | 12 |  */ | 
 | 13 |  | 
| Serhiy Storchaka | 26861b0 | 2015-02-16 20:52:17 +0200 | [diff] [blame] | 14 | #define PY_SSIZE_T_CLEAN | 
 | 15 |  | 
| Fredrik Lundh | 8c8836b | 2005-12-16 22:06:06 +0000 | [diff] [blame] | 16 | #include "Python.h" | 
| Eli Bendersky | ebf37a2 | 2012-04-03 22:02:37 +0300 | [diff] [blame] | 17 | #include "structmember.h" | 
| Fredrik Lundh | 8c8836b | 2005-12-16 22:06:06 +0000 | [diff] [blame] | 18 |  | 
| Fredrik Lundh | 8c8836b | 2005-12-16 22:06:06 +0000 | [diff] [blame] | 19 | /* -------------------------------------------------------------------- */ | 
 | 20 | /* configuration */ | 
 | 21 |  | 
| Fredrik Lundh | 8c8836b | 2005-12-16 22:06:06 +0000 | [diff] [blame] | 22 | /* An element can hold this many children without extra memory | 
 | 23 |    allocations. */ | 
 | 24 | #define STATIC_CHILDREN 4 | 
 | 25 |  | 
 | 26 | /* For best performance, chose a value so that 80-90% of all nodes | 
 | 27 |    have no more than the given number of children.  Set this to zero | 
 | 28 |    to minimize the size of the element structure itself (this only | 
 | 29 |    helps if you have lots of leaf nodes with attributes). */ | 
 | 30 |  | 
 | 31 | /* Also note that pymalloc always allocates blocks in multiples of | 
| Florent Xicluna | a72a98f | 2012-02-13 11:03:30 +0100 | [diff] [blame] | 32 |    eight bytes.  For the current C version of ElementTree, this means | 
| Fredrik Lundh | 8c8836b | 2005-12-16 22:06:06 +0000 | [diff] [blame] | 33 |    that the number of children should be an even number, at least on | 
 | 34 |    32-bit platforms. */ | 
 | 35 |  | 
 | 36 | /* -------------------------------------------------------------------- */ | 
 | 37 |  | 
 | 38 | #if 0 | 
 | 39 | static int memory = 0; | 
 | 40 | #define ALLOC(size, comment)\ | 
 | 41 | do { memory += size; printf("%8d - %s\n", memory, comment); } while (0) | 
 | 42 | #define RELEASE(size, comment)\ | 
 | 43 | do { memory -= size; printf("%8d - %s\n", memory, comment); } while (0) | 
 | 44 | #else | 
 | 45 | #define ALLOC(size, comment) | 
 | 46 | #define RELEASE(size, comment) | 
 | 47 | #endif | 
 | 48 |  | 
 | 49 | /* compiler tweaks */ | 
 | 50 | #if defined(_MSC_VER) | 
 | 51 | #define LOCAL(type) static __inline type __fastcall | 
 | 52 | #else | 
 | 53 | #define LOCAL(type) static type | 
 | 54 | #endif | 
 | 55 |  | 
| Fredrik Lundh | 8c8836b | 2005-12-16 22:06:06 +0000 | [diff] [blame] | 56 | /* macros used to store 'join' flags in string object pointers.  note | 
 | 57 |    that all use of text and tail as object pointers must be wrapped in | 
 | 58 |    JOIN_OBJ.  see comments in the ElementObject definition for more | 
 | 59 |    info. */ | 
| Benjamin Peterson | ca47063 | 2016-09-06 13:47:26 -0700 | [diff] [blame] | 60 | #define JOIN_GET(p) ((uintptr_t) (p) & 1) | 
 | 61 | #define JOIN_SET(p, flag) ((void*) ((uintptr_t) (JOIN_OBJ(p)) | (flag))) | 
 | 62 | #define JOIN_OBJ(p) ((PyObject*) ((uintptr_t) (p) & ~(uintptr_t)1)) | 
| Fredrik Lundh | 8c8836b | 2005-12-16 22:06:06 +0000 | [diff] [blame] | 63 |  | 
| Oren Milman | 39ecb9c | 2017-10-10 23:26:24 +0300 | [diff] [blame] | 64 | /* Py_SETREF for a PyObject* that uses a join flag. */ | 
 | 65 | Py_LOCAL_INLINE(void) | 
 | 66 | _set_joined_ptr(PyObject **p, PyObject *new_joined_ptr) | 
 | 67 | { | 
 | 68 |     PyObject *tmp = JOIN_OBJ(*p); | 
 | 69 |     *p = new_joined_ptr; | 
 | 70 |     Py_DECREF(tmp); | 
 | 71 | } | 
 | 72 |  | 
| Eli Bendersky | dd3661e | 2013-09-13 06:24:25 -0700 | [diff] [blame] | 73 | /* Py_CLEAR for a PyObject* that uses a join flag. Pass the pointer by | 
 | 74 |  * reference since this function sets it to NULL. | 
 | 75 | */ | 
| doko@ubuntu.com | 0648bf7 | 2013-09-18 12:12:28 +0200 | [diff] [blame] | 76 | static void _clear_joined_ptr(PyObject **p) | 
| Eli Bendersky | dd3661e | 2013-09-13 06:24:25 -0700 | [diff] [blame] | 77 | { | 
 | 78 |     if (*p) { | 
| Oren Milman | 39ecb9c | 2017-10-10 23:26:24 +0300 | [diff] [blame] | 79 |         _set_joined_ptr(p, NULL); | 
| Eli Bendersky | dd3661e | 2013-09-13 06:24:25 -0700 | [diff] [blame] | 80 |     } | 
 | 81 | } | 
 | 82 |  | 
| Ronald Oussoren | 138d080 | 2013-07-19 11:11:25 +0200 | [diff] [blame] | 83 | /* Types defined by this extension */ | 
 | 84 | static PyTypeObject Element_Type; | 
 | 85 | static PyTypeObject ElementIter_Type; | 
 | 86 | static PyTypeObject TreeBuilder_Type; | 
 | 87 | static PyTypeObject XMLParser_Type; | 
 | 88 |  | 
 | 89 |  | 
| Eli Bendersky | 532d03e | 2013-08-10 08:00:39 -0700 | [diff] [blame] | 90 | /* Per-module state; PEP 3121 */ | 
 | 91 | typedef struct { | 
 | 92 |     PyObject *parseerror_obj; | 
 | 93 |     PyObject *deepcopy_obj; | 
 | 94 |     PyObject *elementpath_obj; | 
| Stefan Behnel | 43851a2 | 2019-05-01 21:20:38 +0200 | [diff] [blame] | 95 |     PyObject *comment_factory; | 
 | 96 |     PyObject *pi_factory; | 
| Eli Bendersky | 532d03e | 2013-08-10 08:00:39 -0700 | [diff] [blame] | 97 | } elementtreestate; | 
 | 98 |  | 
 | 99 | static struct PyModuleDef elementtreemodule; | 
 | 100 |  | 
 | 101 | /* Given a module object (assumed to be _elementtree), get its per-module | 
 | 102 |  * state. | 
 | 103 |  */ | 
 | 104 | #define ET_STATE(mod) ((elementtreestate *) PyModule_GetState(mod)) | 
 | 105 |  | 
 | 106 | /* Find the module instance imported in the currently running sub-interpreter | 
 | 107 |  * and get its state. | 
 | 108 |  */ | 
 | 109 | #define ET_STATE_GLOBAL \ | 
 | 110 |     ((elementtreestate *) PyModule_GetState(PyState_FindModule(&elementtreemodule))) | 
 | 111 |  | 
 | 112 | static int | 
 | 113 | elementtree_clear(PyObject *m) | 
 | 114 | { | 
 | 115 |     elementtreestate *st = ET_STATE(m); | 
 | 116 |     Py_CLEAR(st->parseerror_obj); | 
 | 117 |     Py_CLEAR(st->deepcopy_obj); | 
 | 118 |     Py_CLEAR(st->elementpath_obj); | 
| Stefan Behnel | 43851a2 | 2019-05-01 21:20:38 +0200 | [diff] [blame] | 119 |     Py_CLEAR(st->comment_factory); | 
 | 120 |     Py_CLEAR(st->pi_factory); | 
| Eli Bendersky | 532d03e | 2013-08-10 08:00:39 -0700 | [diff] [blame] | 121 |     return 0; | 
 | 122 | } | 
 | 123 |  | 
 | 124 | static int | 
 | 125 | elementtree_traverse(PyObject *m, visitproc visit, void *arg) | 
 | 126 | { | 
 | 127 |     elementtreestate *st = ET_STATE(m); | 
 | 128 |     Py_VISIT(st->parseerror_obj); | 
 | 129 |     Py_VISIT(st->deepcopy_obj); | 
 | 130 |     Py_VISIT(st->elementpath_obj); | 
| Stefan Behnel | 43851a2 | 2019-05-01 21:20:38 +0200 | [diff] [blame] | 131 |     Py_VISIT(st->comment_factory); | 
 | 132 |     Py_VISIT(st->pi_factory); | 
| Eli Bendersky | 532d03e | 2013-08-10 08:00:39 -0700 | [diff] [blame] | 133 |     return 0; | 
 | 134 | } | 
 | 135 |  | 
 | 136 | static void | 
 | 137 | elementtree_free(void *m) | 
 | 138 | { | 
 | 139 |     elementtree_clear((PyObject *)m); | 
 | 140 | } | 
| Fredrik Lundh | 8c8836b | 2005-12-16 22:06:06 +0000 | [diff] [blame] | 141 |  | 
 | 142 | /* helpers */ | 
 | 143 |  | 
 | 144 | LOCAL(PyObject*) | 
| Fredrik Lundh | 8c8836b | 2005-12-16 22:06:06 +0000 | [diff] [blame] | 145 | list_join(PyObject* list) | 
 | 146 | { | 
| Serhiy Storchaka | 576def0 | 2017-03-30 09:47:31 +0300 | [diff] [blame] | 147 |     /* join list elements */ | 
| Fredrik Lundh | 8c8836b | 2005-12-16 22:06:06 +0000 | [diff] [blame] | 148 |     PyObject* joiner; | 
| Fredrik Lundh | 8c8836b | 2005-12-16 22:06:06 +0000 | [diff] [blame] | 149 |     PyObject* result; | 
 | 150 |  | 
| Antoine Pitrou | c194884 | 2012-10-01 23:40:37 +0200 | [diff] [blame] | 151 |     joiner = PyUnicode_FromStringAndSize("", 0); | 
| Fredrik Lundh | 8c8836b | 2005-12-16 22:06:06 +0000 | [diff] [blame] | 152 |     if (!joiner) | 
 | 153 |         return NULL; | 
| Antoine Pitrou | c194884 | 2012-10-01 23:40:37 +0200 | [diff] [blame] | 154 |     result = PyUnicode_Join(joiner, list); | 
| Fredrik Lundh | 8c8836b | 2005-12-16 22:06:06 +0000 | [diff] [blame] | 155 |     Py_DECREF(joiner); | 
| Fredrik Lundh | 8c8836b | 2005-12-16 22:06:06 +0000 | [diff] [blame] | 156 |     return result; | 
 | 157 | } | 
 | 158 |  | 
| Eli Bendersky | 48d358b | 2012-05-30 17:57:50 +0300 | [diff] [blame] | 159 | /* Is the given object an empty dictionary? | 
 | 160 | */ | 
 | 161 | static int | 
 | 162 | is_empty_dict(PyObject *obj) | 
 | 163 | { | 
| Serhiy Storchaka | 5ab81d7 | 2016-12-16 16:18:57 +0200 | [diff] [blame] | 164 |     return PyDict_CheckExact(obj) && PyDict_GET_SIZE(obj) == 0; | 
| Eli Bendersky | 48d358b | 2012-05-30 17:57:50 +0300 | [diff] [blame] | 165 | } | 
 | 166 |  | 
 | 167 |  | 
| Fredrik Lundh | 8c8836b | 2005-12-16 22:06:06 +0000 | [diff] [blame] | 168 | /* -------------------------------------------------------------------- */ | 
| Eli Bendersky | 092af1f | 2012-03-04 07:14:03 +0200 | [diff] [blame] | 169 | /* the Element type */ | 
| Fredrik Lundh | 8c8836b | 2005-12-16 22:06:06 +0000 | [diff] [blame] | 170 |  | 
 | 171 | typedef struct { | 
 | 172 |  | 
 | 173 |     /* attributes (a dictionary object), or None if no attributes */ | 
 | 174 |     PyObject* attrib; | 
 | 175 |  | 
 | 176 |     /* child elements */ | 
| Serhiy Storchaka | 26861b0 | 2015-02-16 20:52:17 +0200 | [diff] [blame] | 177 |     Py_ssize_t length; /* actual number of items */ | 
 | 178 |     Py_ssize_t allocated; /* allocated items */ | 
| Fredrik Lundh | 8c8836b | 2005-12-16 22:06:06 +0000 | [diff] [blame] | 179 |  | 
 | 180 |     /* this either points to _children or to a malloced buffer */ | 
 | 181 |     PyObject* *children; | 
 | 182 |  | 
 | 183 |     PyObject* _children[STATIC_CHILDREN]; | 
| Victor Stinner | bfc7bf0 | 2011-03-21 13:23:42 +0100 | [diff] [blame] | 184 |  | 
| Fredrik Lundh | 8c8836b | 2005-12-16 22:06:06 +0000 | [diff] [blame] | 185 | } ElementObjectExtra; | 
 | 186 |  | 
 | 187 | typedef struct { | 
 | 188 |     PyObject_HEAD | 
 | 189 |  | 
 | 190 |     /* element tag (a string). */ | 
 | 191 |     PyObject* tag; | 
 | 192 |  | 
 | 193 |     /* text before first child.  note that this is a tagged pointer; | 
 | 194 |        use JOIN_OBJ to get the object pointer.  the join flag is used | 
 | 195 |        to distinguish lists created by the tree builder from lists | 
 | 196 |        assigned to the attribute by application code; the former | 
 | 197 |        should be joined before being returned to the user, the latter | 
 | 198 |        should be left intact. */ | 
 | 199 |     PyObject* text; | 
 | 200 |  | 
 | 201 |     /* text after this element, in parent.  note that this is a tagged | 
 | 202 |        pointer; use JOIN_OBJ to get the object pointer. */ | 
 | 203 |     PyObject* tail; | 
 | 204 |  | 
 | 205 |     ElementObjectExtra* extra; | 
 | 206 |  | 
| Eli Bendersky | ebf37a2 | 2012-04-03 22:02:37 +0300 | [diff] [blame] | 207 |     PyObject *weakreflist; /* For tp_weaklistoffset */ | 
 | 208 |  | 
| Fredrik Lundh | 8c8836b | 2005-12-16 22:06:06 +0000 | [diff] [blame] | 209 | } ElementObject; | 
 | 210 |  | 
| Fredrik Lundh | 8c8836b | 2005-12-16 22:06:06 +0000 | [diff] [blame] | 211 |  | 
| Christian Heimes | 90aa764 | 2007-12-19 02:45:37 +0000 | [diff] [blame] | 212 | #define Element_CheckExact(op) (Py_TYPE(op) == &Element_Type) | 
| Serhiy Storchaka | b11c566 | 2018-10-14 10:32:19 +0300 | [diff] [blame] | 213 | #define Element_Check(op) PyObject_TypeCheck(op, &Element_Type) | 
 | 214 |  | 
| Fredrik Lundh | 8c8836b | 2005-12-16 22:06:06 +0000 | [diff] [blame] | 215 |  | 
 | 216 | /* -------------------------------------------------------------------- */ | 
| Eli Bendersky | 092af1f | 2012-03-04 07:14:03 +0200 | [diff] [blame] | 217 | /* Element constructors and destructor */ | 
| Fredrik Lundh | 8c8836b | 2005-12-16 22:06:06 +0000 | [diff] [blame] | 218 |  | 
 | 219 | LOCAL(int) | 
| Eli Bendersky | 092af1f | 2012-03-04 07:14:03 +0200 | [diff] [blame] | 220 | create_extra(ElementObject* self, PyObject* attrib) | 
| Fredrik Lundh | 8c8836b | 2005-12-16 22:06:06 +0000 | [diff] [blame] | 221 | { | 
 | 222 |     self->extra = PyObject_Malloc(sizeof(ElementObjectExtra)); | 
| Victor Stinner | 81aac73 | 2013-07-12 02:03:34 +0200 | [diff] [blame] | 223 |     if (!self->extra) { | 
 | 224 |         PyErr_NoMemory(); | 
| Fredrik Lundh | 8c8836b | 2005-12-16 22:06:06 +0000 | [diff] [blame] | 225 |         return -1; | 
| Victor Stinner | 81aac73 | 2013-07-12 02:03:34 +0200 | [diff] [blame] | 226 |     } | 
| Fredrik Lundh | 8c8836b | 2005-12-16 22:06:06 +0000 | [diff] [blame] | 227 |  | 
 | 228 |     if (!attrib) | 
 | 229 |         attrib = Py_None; | 
 | 230 |  | 
 | 231 |     Py_INCREF(attrib); | 
 | 232 |     self->extra->attrib = attrib; | 
 | 233 |  | 
 | 234 |     self->extra->length = 0; | 
 | 235 |     self->extra->allocated = STATIC_CHILDREN; | 
 | 236 |     self->extra->children = self->extra->_children; | 
 | 237 |  | 
 | 238 |     return 0; | 
 | 239 | } | 
 | 240 |  | 
 | 241 | LOCAL(void) | 
| Serhiy Storchaka | 6f906b3 | 2018-10-18 09:49:54 +0300 | [diff] [blame] | 242 | dealloc_extra(ElementObjectExtra *extra) | 
 | 243 | { | 
 | 244 |     Py_ssize_t i; | 
 | 245 |  | 
 | 246 |     if (!extra) | 
 | 247 |         return; | 
 | 248 |  | 
 | 249 |     Py_DECREF(extra->attrib); | 
 | 250 |  | 
 | 251 |     for (i = 0; i < extra->length; i++) | 
 | 252 |         Py_DECREF(extra->children[i]); | 
 | 253 |  | 
 | 254 |     if (extra->children != extra->_children) | 
 | 255 |         PyObject_Free(extra->children); | 
 | 256 |  | 
 | 257 |     PyObject_Free(extra); | 
 | 258 | } | 
 | 259 |  | 
 | 260 | LOCAL(void) | 
 | 261 | clear_extra(ElementObject* self) | 
| Fredrik Lundh | 8c8836b | 2005-12-16 22:06:06 +0000 | [diff] [blame] | 262 | { | 
| Eli Bendersky | 08b8529 | 2012-04-04 15:55:07 +0300 | [diff] [blame] | 263 |     ElementObjectExtra *myextra; | 
| Eli Bendersky | 08b8529 | 2012-04-04 15:55:07 +0300 | [diff] [blame] | 264 |  | 
| Eli Bendersky | ebf37a2 | 2012-04-03 22:02:37 +0300 | [diff] [blame] | 265 |     if (!self->extra) | 
 | 266 |         return; | 
 | 267 |  | 
 | 268 |     /* Avoid DECREFs calling into this code again (cycles, etc.) | 
 | 269 |     */ | 
| Eli Bendersky | 08b8529 | 2012-04-04 15:55:07 +0300 | [diff] [blame] | 270 |     myextra = self->extra; | 
| Eli Bendersky | ebf37a2 | 2012-04-03 22:02:37 +0300 | [diff] [blame] | 271 |     self->extra = NULL; | 
 | 272 |  | 
| Serhiy Storchaka | 6f906b3 | 2018-10-18 09:49:54 +0300 | [diff] [blame] | 273 |     dealloc_extra(myextra); | 
| Fredrik Lundh | 8c8836b | 2005-12-16 22:06:06 +0000 | [diff] [blame] | 274 | } | 
 | 275 |  | 
| Eli Bendersky | 092af1f | 2012-03-04 07:14:03 +0200 | [diff] [blame] | 276 | /* Convenience internal function to create new Element objects with the given | 
 | 277 |  * tag and attributes. | 
 | 278 | */ | 
| Fredrik Lundh | 8c8836b | 2005-12-16 22:06:06 +0000 | [diff] [blame] | 279 | LOCAL(PyObject*) | 
| Eli Bendersky | 092af1f | 2012-03-04 07:14:03 +0200 | [diff] [blame] | 280 | create_new_element(PyObject* tag, PyObject* attrib) | 
| Fredrik Lundh | 8c8836b | 2005-12-16 22:06:06 +0000 | [diff] [blame] | 281 | { | 
 | 282 |     ElementObject* self; | 
 | 283 |  | 
| Eli Bendersky | 0192ba3 | 2012-03-30 16:38:33 +0300 | [diff] [blame] | 284 |     self = PyObject_GC_New(ElementObject, &Element_Type); | 
| Fredrik Lundh | 8c8836b | 2005-12-16 22:06:06 +0000 | [diff] [blame] | 285 |     if (self == NULL) | 
 | 286 |         return NULL; | 
| Fredrik Lundh | 8c8836b | 2005-12-16 22:06:06 +0000 | [diff] [blame] | 287 |     self->extra = NULL; | 
 | 288 |  | 
| Fredrik Lundh | 8c8836b | 2005-12-16 22:06:06 +0000 | [diff] [blame] | 289 |     Py_INCREF(tag); | 
 | 290 |     self->tag = tag; | 
 | 291 |  | 
 | 292 |     Py_INCREF(Py_None); | 
 | 293 |     self->text = Py_None; | 
 | 294 |  | 
 | 295 |     Py_INCREF(Py_None); | 
 | 296 |     self->tail = Py_None; | 
 | 297 |  | 
| Eli Bendersky | ebf37a2 | 2012-04-03 22:02:37 +0300 | [diff] [blame] | 298 |     self->weakreflist = NULL; | 
 | 299 |  | 
| Victor Stinner | d917dcb | 2013-07-12 02:05:17 +0200 | [diff] [blame] | 300 |     ALLOC(sizeof(ElementObject), "create element"); | 
 | 301 |     PyObject_GC_Track(self); | 
 | 302 |  | 
| Victor Stinner | 71c8b7e | 2013-07-11 23:08:39 +0200 | [diff] [blame] | 303 |     if (attrib != Py_None && !is_empty_dict(attrib)) { | 
 | 304 |         if (create_extra(self, attrib) < 0) { | 
| Victor Stinner | d917dcb | 2013-07-12 02:05:17 +0200 | [diff] [blame] | 305 |             Py_DECREF(self); | 
| Victor Stinner | 71c8b7e | 2013-07-11 23:08:39 +0200 | [diff] [blame] | 306 |             return NULL; | 
 | 307 |         } | 
 | 308 |     } | 
 | 309 |  | 
| Fredrik Lundh | 8c8836b | 2005-12-16 22:06:06 +0000 | [diff] [blame] | 310 |     return (PyObject*) self; | 
 | 311 | } | 
 | 312 |  | 
| Eli Bendersky | 092af1f | 2012-03-04 07:14:03 +0200 | [diff] [blame] | 313 | static PyObject * | 
 | 314 | element_new(PyTypeObject *type, PyObject *args, PyObject *kwds) | 
 | 315 | { | 
 | 316 |     ElementObject *e = (ElementObject *)type->tp_alloc(type, 0); | 
 | 317 |     if (e != NULL) { | 
 | 318 |         Py_INCREF(Py_None); | 
 | 319 |         e->tag = Py_None; | 
 | 320 |  | 
 | 321 |         Py_INCREF(Py_None); | 
 | 322 |         e->text = Py_None; | 
 | 323 |  | 
 | 324 |         Py_INCREF(Py_None); | 
 | 325 |         e->tail = Py_None; | 
 | 326 |  | 
 | 327 |         e->extra = NULL; | 
| Eli Bendersky | ebf37a2 | 2012-04-03 22:02:37 +0300 | [diff] [blame] | 328 |         e->weakreflist = NULL; | 
| Eli Bendersky | 092af1f | 2012-03-04 07:14:03 +0200 | [diff] [blame] | 329 |     } | 
 | 330 |     return (PyObject *)e; | 
 | 331 | } | 
 | 332 |  | 
| Eli Bendersky | 737b173 | 2012-05-29 06:02:56 +0300 | [diff] [blame] | 333 | /* Helper function for extracting the attrib dictionary from a keywords dict. | 
 | 334 |  * This is required by some constructors/functions in this module that can | 
| Eli Bendersky | 4583990 | 2013-01-13 05:14:47 -0800 | [diff] [blame] | 335 |  * either accept attrib as a keyword argument or all attributes splashed | 
| Eli Bendersky | 737b173 | 2012-05-29 06:02:56 +0300 | [diff] [blame] | 336 |  * directly into *kwds. | 
| Eli Bendersky | d4cb4b7 | 2013-04-22 05:25:25 -0700 | [diff] [blame] | 337 |  * | 
 | 338 |  * Return a dictionary with the content of kwds merged into the content of | 
 | 339 |  * attrib. If there is no attrib keyword, return a copy of kwds. | 
| Eli Bendersky | 737b173 | 2012-05-29 06:02:56 +0300 | [diff] [blame] | 340 |  */ | 
 | 341 | static PyObject* | 
 | 342 | get_attrib_from_keywords(PyObject *kwds) | 
 | 343 | { | 
| Eli Bendersky | 45f3d2f | 2013-04-24 05:34:07 -0700 | [diff] [blame] | 344 |     PyObject *attrib_str = PyUnicode_FromString("attrib"); | 
| Zackery Spytz | 9f3ed3e | 2018-10-23 13:28:06 -0600 | [diff] [blame] | 345 |     if (attrib_str == NULL) { | 
 | 346 |         return NULL; | 
 | 347 |     } | 
| Serhiy Storchaka | a24107b | 2019-02-25 17:59:46 +0200 | [diff] [blame] | 348 |     PyObject *attrib = PyDict_GetItemWithError(kwds, attrib_str); | 
| Eli Bendersky | 737b173 | 2012-05-29 06:02:56 +0300 | [diff] [blame] | 349 |  | 
 | 350 |     if (attrib) { | 
 | 351 |         /* If attrib was found in kwds, copy its value and remove it from | 
 | 352 |          * kwds | 
 | 353 |          */ | 
 | 354 |         if (!PyDict_Check(attrib)) { | 
| Eli Bendersky | 45f3d2f | 2013-04-24 05:34:07 -0700 | [diff] [blame] | 355 |             Py_DECREF(attrib_str); | 
| Eli Bendersky | 737b173 | 2012-05-29 06:02:56 +0300 | [diff] [blame] | 356 |             PyErr_Format(PyExc_TypeError, "attrib must be dict, not %.100s", | 
 | 357 |                          Py_TYPE(attrib)->tp_name); | 
 | 358 |             return NULL; | 
 | 359 |         } | 
 | 360 |         attrib = PyDict_Copy(attrib); | 
| Serhiy Storchaka | 8905fcc | 2018-12-11 08:38:03 +0200 | [diff] [blame] | 361 |         if (attrib && PyDict_DelItem(kwds, attrib_str) < 0) { | 
 | 362 |             Py_DECREF(attrib); | 
 | 363 |             attrib = NULL; | 
 | 364 |         } | 
| Serhiy Storchaka | a24107b | 2019-02-25 17:59:46 +0200 | [diff] [blame] | 365 |     } | 
 | 366 |     else if (!PyErr_Occurred()) { | 
| Eli Bendersky | 737b173 | 2012-05-29 06:02:56 +0300 | [diff] [blame] | 367 |         attrib = PyDict_New(); | 
 | 368 |     } | 
| Eli Bendersky | 45f3d2f | 2013-04-24 05:34:07 -0700 | [diff] [blame] | 369 |  | 
 | 370 |     Py_DECREF(attrib_str); | 
 | 371 |  | 
| Zackery Spytz | 9f3ed3e | 2018-10-23 13:28:06 -0600 | [diff] [blame] | 372 |     if (attrib != NULL && PyDict_Update(attrib, kwds) < 0) { | 
 | 373 |         Py_DECREF(attrib); | 
 | 374 |         return NULL; | 
 | 375 |     } | 
| Eli Bendersky | 737b173 | 2012-05-29 06:02:56 +0300 | [diff] [blame] | 376 |     return attrib; | 
 | 377 | } | 
 | 378 |  | 
| Serhiy Storchaka | cb98556 | 2015-05-04 15:32:48 +0300 | [diff] [blame] | 379 | /*[clinic input] | 
 | 380 | module _elementtree | 
 | 381 | class _elementtree.Element "ElementObject *" "&Element_Type" | 
 | 382 | class _elementtree.TreeBuilder "TreeBuilderObject *" "&TreeBuilder_Type" | 
 | 383 | class _elementtree.XMLParser "XMLParserObject *" "&XMLParser_Type" | 
 | 384 | [clinic start generated code]*/ | 
 | 385 | /*[clinic end generated code: output=da39a3ee5e6b4b0d input=159aa50a54061c22]*/ | 
 | 386 |  | 
| Eli Bendersky | 092af1f | 2012-03-04 07:14:03 +0200 | [diff] [blame] | 387 | static int | 
 | 388 | element_init(PyObject *self, PyObject *args, PyObject *kwds) | 
 | 389 | { | 
 | 390 |     PyObject *tag; | 
| Eli Bendersky | 092af1f | 2012-03-04 07:14:03 +0200 | [diff] [blame] | 391 |     PyObject *attrib = NULL; | 
 | 392 |     ElementObject *self_elem; | 
 | 393 |  | 
 | 394 |     if (!PyArg_ParseTuple(args, "O|O!:Element", &tag, &PyDict_Type, &attrib)) | 
 | 395 |         return -1; | 
 | 396 |  | 
| Eli Bendersky | 737b173 | 2012-05-29 06:02:56 +0300 | [diff] [blame] | 397 |     if (attrib) { | 
 | 398 |         /* attrib passed as positional arg */ | 
 | 399 |         attrib = PyDict_Copy(attrib); | 
| Eli Bendersky | 092af1f | 2012-03-04 07:14:03 +0200 | [diff] [blame] | 400 |         if (!attrib) | 
 | 401 |             return -1; | 
| Eli Bendersky | 737b173 | 2012-05-29 06:02:56 +0300 | [diff] [blame] | 402 |         if (kwds) { | 
 | 403 |             if (PyDict_Update(attrib, kwds) < 0) { | 
| Antoine Pitrou | c194884 | 2012-10-01 23:40:37 +0200 | [diff] [blame] | 404 |                 Py_DECREF(attrib); | 
| Eli Bendersky | 737b173 | 2012-05-29 06:02:56 +0300 | [diff] [blame] | 405 |                 return -1; | 
 | 406 |             } | 
 | 407 |         } | 
 | 408 |     } else if (kwds) { | 
 | 409 |         /* have keywords args */ | 
 | 410 |         attrib = get_attrib_from_keywords(kwds); | 
 | 411 |         if (!attrib) | 
 | 412 |             return -1; | 
| Eli Bendersky | 092af1f | 2012-03-04 07:14:03 +0200 | [diff] [blame] | 413 |     } | 
 | 414 |  | 
 | 415 |     self_elem = (ElementObject *)self; | 
 | 416 |  | 
| Antoine Pitrou | c194884 | 2012-10-01 23:40:37 +0200 | [diff] [blame] | 417 |     if (attrib != NULL && !is_empty_dict(attrib)) { | 
| Eli Bendersky | 092af1f | 2012-03-04 07:14:03 +0200 | [diff] [blame] | 418 |         if (create_extra(self_elem, attrib) < 0) { | 
| Antoine Pitrou | c194884 | 2012-10-01 23:40:37 +0200 | [diff] [blame] | 419 |             Py_DECREF(attrib); | 
| Eli Bendersky | 092af1f | 2012-03-04 07:14:03 +0200 | [diff] [blame] | 420 |             return -1; | 
 | 421 |         } | 
 | 422 |     } | 
 | 423 |  | 
| Eli Bendersky | 48d358b | 2012-05-30 17:57:50 +0300 | [diff] [blame] | 424 |     /* We own a reference to attrib here and it's no longer needed. */ | 
| Antoine Pitrou | c194884 | 2012-10-01 23:40:37 +0200 | [diff] [blame] | 425 |     Py_XDECREF(attrib); | 
| Eli Bendersky | 092af1f | 2012-03-04 07:14:03 +0200 | [diff] [blame] | 426 |  | 
 | 427 |     /* Replace the objects already pointed to by tag, text and tail. */ | 
| Eli Bendersky | 092af1f | 2012-03-04 07:14:03 +0200 | [diff] [blame] | 428 |     Py_INCREF(tag); | 
| Serhiy Storchaka | ec39756 | 2016-04-06 09:50:03 +0300 | [diff] [blame] | 429 |     Py_XSETREF(self_elem->tag, tag); | 
| Eli Bendersky | 092af1f | 2012-03-04 07:14:03 +0200 | [diff] [blame] | 430 |  | 
| Eli Bendersky | 092af1f | 2012-03-04 07:14:03 +0200 | [diff] [blame] | 431 |     Py_INCREF(Py_None); | 
| Oren Milman | 39ecb9c | 2017-10-10 23:26:24 +0300 | [diff] [blame] | 432 |     _set_joined_ptr(&self_elem->text, Py_None); | 
| Eli Bendersky | 092af1f | 2012-03-04 07:14:03 +0200 | [diff] [blame] | 433 |  | 
| Eli Bendersky | 092af1f | 2012-03-04 07:14:03 +0200 | [diff] [blame] | 434 |     Py_INCREF(Py_None); | 
| Oren Milman | 39ecb9c | 2017-10-10 23:26:24 +0300 | [diff] [blame] | 435 |     _set_joined_ptr(&self_elem->tail, Py_None); | 
| Eli Bendersky | 092af1f | 2012-03-04 07:14:03 +0200 | [diff] [blame] | 436 |  | 
 | 437 |     return 0; | 
 | 438 | } | 
 | 439 |  | 
| Fredrik Lundh | 8c8836b | 2005-12-16 22:06:06 +0000 | [diff] [blame] | 440 | LOCAL(int) | 
| Serhiy Storchaka | 26861b0 | 2015-02-16 20:52:17 +0200 | [diff] [blame] | 441 | element_resize(ElementObject* self, Py_ssize_t extra) | 
| Fredrik Lundh | 8c8836b | 2005-12-16 22:06:06 +0000 | [diff] [blame] | 442 | { | 
| Serhiy Storchaka | 26861b0 | 2015-02-16 20:52:17 +0200 | [diff] [blame] | 443 |     Py_ssize_t size; | 
| Fredrik Lundh | 8c8836b | 2005-12-16 22:06:06 +0000 | [diff] [blame] | 444 |     PyObject* *children; | 
 | 445 |  | 
| Serhiy Storchaka | 6f906b3 | 2018-10-18 09:49:54 +0300 | [diff] [blame] | 446 |     assert(extra >= 0); | 
| Fredrik Lundh | 8c8836b | 2005-12-16 22:06:06 +0000 | [diff] [blame] | 447 |     /* make sure self->children can hold the given number of extra | 
 | 448 |        elements.  set an exception and return -1 if allocation failed */ | 
 | 449 |  | 
| Victor Stinner | 5f0af23 | 2013-07-11 23:01:36 +0200 | [diff] [blame] | 450 |     if (!self->extra) { | 
 | 451 |         if (create_extra(self, NULL) < 0) | 
 | 452 |             return -1; | 
 | 453 |     } | 
| Fredrik Lundh | 8c8836b | 2005-12-16 22:06:06 +0000 | [diff] [blame] | 454 |  | 
| Serhiy Storchaka | 26861b0 | 2015-02-16 20:52:17 +0200 | [diff] [blame] | 455 |     size = self->extra->length + extra;  /* never overflows */ | 
| Fredrik Lundh | 8c8836b | 2005-12-16 22:06:06 +0000 | [diff] [blame] | 456 |  | 
 | 457 |     if (size > self->extra->allocated) { | 
 | 458 |         /* use Python 2.4's list growth strategy */ | 
 | 459 |         size = (size >> 3) + (size < 9 ? 3 : 6) + size; | 
| Christian Heimes | 679db4a | 2008-01-18 09:56:22 +0000 | [diff] [blame] | 460 |         /* Coverity CID #182 size_error: Allocating 1 bytes to pointer "children" | 
| Victor Stinner | bfc7bf0 | 2011-03-21 13:23:42 +0100 | [diff] [blame] | 461 |          * which needs at least 4 bytes. | 
 | 462 |          * Although it's a false alarm always assume at least one child to | 
| Christian Heimes | 679db4a | 2008-01-18 09:56:22 +0000 | [diff] [blame] | 463 |          * be safe. | 
 | 464 |          */ | 
 | 465 |         size = size ? size : 1; | 
| Serhiy Storchaka | 26861b0 | 2015-02-16 20:52:17 +0200 | [diff] [blame] | 466 |         if ((size_t)size > PY_SSIZE_T_MAX/sizeof(PyObject*)) | 
 | 467 |             goto nomemory; | 
| Fredrik Lundh | 8c8836b | 2005-12-16 22:06:06 +0000 | [diff] [blame] | 468 |         if (self->extra->children != self->extra->_children) { | 
| Christian Heimes | 679db4a | 2008-01-18 09:56:22 +0000 | [diff] [blame] | 469 |             /* Coverity CID #182 size_error: Allocating 1 bytes to pointer | 
| Victor Stinner | bfc7bf0 | 2011-03-21 13:23:42 +0100 | [diff] [blame] | 470 |              * "children", which needs at least 4 bytes. Although it's a | 
| Christian Heimes | 679db4a | 2008-01-18 09:56:22 +0000 | [diff] [blame] | 471 |              * false alarm always assume at least one child to be safe. | 
 | 472 |              */ | 
| Fredrik Lundh | 8c8836b | 2005-12-16 22:06:06 +0000 | [diff] [blame] | 473 |             children = PyObject_Realloc(self->extra->children, | 
 | 474 |                                         size * sizeof(PyObject*)); | 
 | 475 |             if (!children) | 
 | 476 |                 goto nomemory; | 
 | 477 |         } else { | 
 | 478 |             children = PyObject_Malloc(size * sizeof(PyObject*)); | 
 | 479 |             if (!children) | 
 | 480 |                 goto nomemory; | 
 | 481 |             /* copy existing children from static area to malloc buffer */ | 
 | 482 |             memcpy(children, self->extra->children, | 
 | 483 |                    self->extra->length * sizeof(PyObject*)); | 
 | 484 |         } | 
 | 485 |         self->extra->children = children; | 
 | 486 |         self->extra->allocated = size; | 
 | 487 |     } | 
 | 488 |  | 
 | 489 |     return 0; | 
 | 490 |  | 
 | 491 |   nomemory: | 
 | 492 |     PyErr_NoMemory(); | 
 | 493 |     return -1; | 
 | 494 | } | 
 | 495 |  | 
| Serhiy Storchaka | f081fd8 | 2018-10-19 12:12:57 +0300 | [diff] [blame] | 496 | LOCAL(void) | 
 | 497 | raise_type_error(PyObject *element) | 
 | 498 | { | 
 | 499 |     PyErr_Format(PyExc_TypeError, | 
 | 500 |                  "expected an Element, not \"%.200s\"", | 
 | 501 |                  Py_TYPE(element)->tp_name); | 
 | 502 | } | 
 | 503 |  | 
| Fredrik Lundh | 8c8836b | 2005-12-16 22:06:06 +0000 | [diff] [blame] | 504 | LOCAL(int) | 
 | 505 | element_add_subelement(ElementObject* self, PyObject* element) | 
 | 506 | { | 
 | 507 |     /* add a child element to a parent */ | 
 | 508 |  | 
| Serhiy Storchaka | f081fd8 | 2018-10-19 12:12:57 +0300 | [diff] [blame] | 509 |     if (!Element_Check(element)) { | 
 | 510 |         raise_type_error(element); | 
 | 511 |         return -1; | 
 | 512 |     } | 
 | 513 |  | 
| Fredrik Lundh | 8c8836b | 2005-12-16 22:06:06 +0000 | [diff] [blame] | 514 |     if (element_resize(self, 1) < 0) | 
 | 515 |         return -1; | 
 | 516 |  | 
 | 517 |     Py_INCREF(element); | 
 | 518 |     self->extra->children[self->extra->length] = element; | 
 | 519 |  | 
 | 520 |     self->extra->length++; | 
 | 521 |  | 
 | 522 |     return 0; | 
 | 523 | } | 
 | 524 |  | 
 | 525 | LOCAL(PyObject*) | 
 | 526 | element_get_attrib(ElementObject* self) | 
 | 527 | { | 
 | 528 |     /* return borrowed reference to attrib dictionary */ | 
 | 529 |     /* note: this function assumes that the extra section exists */ | 
 | 530 |  | 
 | 531 |     PyObject* res = self->extra->attrib; | 
 | 532 |  | 
 | 533 |     if (res == Py_None) { | 
 | 534 |         /* create missing dictionary */ | 
 | 535 |         res = PyDict_New(); | 
 | 536 |         if (!res) | 
 | 537 |             return NULL; | 
| Antoine Pitrou | c194884 | 2012-10-01 23:40:37 +0200 | [diff] [blame] | 538 |         Py_DECREF(Py_None); | 
| Fredrik Lundh | 8c8836b | 2005-12-16 22:06:06 +0000 | [diff] [blame] | 539 |         self->extra->attrib = res; | 
 | 540 |     } | 
 | 541 |  | 
 | 542 |     return res; | 
 | 543 | } | 
 | 544 |  | 
 | 545 | LOCAL(PyObject*) | 
 | 546 | element_get_text(ElementObject* self) | 
 | 547 | { | 
 | 548 |     /* return borrowed reference to text attribute */ | 
 | 549 |  | 
| Serhiy Storchaka | 576def0 | 2017-03-30 09:47:31 +0300 | [diff] [blame] | 550 |     PyObject *res = self->text; | 
| Fredrik Lundh | 8c8836b | 2005-12-16 22:06:06 +0000 | [diff] [blame] | 551 |  | 
 | 552 |     if (JOIN_GET(res)) { | 
 | 553 |         res = JOIN_OBJ(res); | 
 | 554 |         if (PyList_CheckExact(res)) { | 
| Serhiy Storchaka | 576def0 | 2017-03-30 09:47:31 +0300 | [diff] [blame] | 555 |             PyObject *tmp = list_join(res); | 
 | 556 |             if (!tmp) | 
| Fredrik Lundh | 8c8836b | 2005-12-16 22:06:06 +0000 | [diff] [blame] | 557 |                 return NULL; | 
| Serhiy Storchaka | 576def0 | 2017-03-30 09:47:31 +0300 | [diff] [blame] | 558 |             self->text = tmp; | 
 | 559 |             Py_DECREF(res); | 
 | 560 |             res = tmp; | 
| Fredrik Lundh | 8c8836b | 2005-12-16 22:06:06 +0000 | [diff] [blame] | 561 |         } | 
 | 562 |     } | 
 | 563 |  | 
 | 564 |     return res; | 
 | 565 | } | 
 | 566 |  | 
 | 567 | LOCAL(PyObject*) | 
 | 568 | element_get_tail(ElementObject* self) | 
 | 569 | { | 
 | 570 |     /* return borrowed reference to text attribute */ | 
 | 571 |  | 
| Serhiy Storchaka | 576def0 | 2017-03-30 09:47:31 +0300 | [diff] [blame] | 572 |     PyObject *res = self->tail; | 
| Fredrik Lundh | 8c8836b | 2005-12-16 22:06:06 +0000 | [diff] [blame] | 573 |  | 
 | 574 |     if (JOIN_GET(res)) { | 
 | 575 |         res = JOIN_OBJ(res); | 
 | 576 |         if (PyList_CheckExact(res)) { | 
| Serhiy Storchaka | 576def0 | 2017-03-30 09:47:31 +0300 | [diff] [blame] | 577 |             PyObject *tmp = list_join(res); | 
 | 578 |             if (!tmp) | 
| Fredrik Lundh | 8c8836b | 2005-12-16 22:06:06 +0000 | [diff] [blame] | 579 |                 return NULL; | 
| Serhiy Storchaka | 576def0 | 2017-03-30 09:47:31 +0300 | [diff] [blame] | 580 |             self->tail = tmp; | 
 | 581 |             Py_DECREF(res); | 
 | 582 |             res = tmp; | 
| Fredrik Lundh | 8c8836b | 2005-12-16 22:06:06 +0000 | [diff] [blame] | 583 |         } | 
 | 584 |     } | 
 | 585 |  | 
 | 586 |     return res; | 
 | 587 | } | 
 | 588 |  | 
 | 589 | static PyObject* | 
| Eli Bendersky | 737b173 | 2012-05-29 06:02:56 +0300 | [diff] [blame] | 590 | subelement(PyObject *self, PyObject *args, PyObject *kwds) | 
| Fredrik Lundh | 8c8836b | 2005-12-16 22:06:06 +0000 | [diff] [blame] | 591 | { | 
 | 592 |     PyObject* elem; | 
 | 593 |  | 
 | 594 |     ElementObject* parent; | 
 | 595 |     PyObject* tag; | 
 | 596 |     PyObject* attrib = NULL; | 
 | 597 |     if (!PyArg_ParseTuple(args, "O!O|O!:SubElement", | 
 | 598 |                           &Element_Type, &parent, &tag, | 
| Eli Bendersky | 163d7f0 | 2013-11-24 06:55:04 -0800 | [diff] [blame] | 599 |                           &PyDict_Type, &attrib)) { | 
| Fredrik Lundh | 8c8836b | 2005-12-16 22:06:06 +0000 | [diff] [blame] | 600 |         return NULL; | 
| Eli Bendersky | 163d7f0 | 2013-11-24 06:55:04 -0800 | [diff] [blame] | 601 |     } | 
| Fredrik Lundh | 8c8836b | 2005-12-16 22:06:06 +0000 | [diff] [blame] | 602 |  | 
| Eli Bendersky | 737b173 | 2012-05-29 06:02:56 +0300 | [diff] [blame] | 603 |     if (attrib) { | 
 | 604 |         /* attrib passed as positional arg */ | 
 | 605 |         attrib = PyDict_Copy(attrib); | 
| Fredrik Lundh | 8c8836b | 2005-12-16 22:06:06 +0000 | [diff] [blame] | 606 |         if (!attrib) | 
 | 607 |             return NULL; | 
| Zackery Spytz | 9f3ed3e | 2018-10-23 13:28:06 -0600 | [diff] [blame] | 608 |         if (kwds != NULL && PyDict_Update(attrib, kwds) < 0) { | 
 | 609 |             Py_DECREF(attrib); | 
 | 610 |             return NULL; | 
| Eli Bendersky | 737b173 | 2012-05-29 06:02:56 +0300 | [diff] [blame] | 611 |         } | 
 | 612 |     } else if (kwds) { | 
 | 613 |         /* have keyword args */ | 
 | 614 |         attrib = get_attrib_from_keywords(kwds); | 
 | 615 |         if (!attrib) | 
 | 616 |             return NULL; | 
| Fredrik Lundh | 8c8836b | 2005-12-16 22:06:06 +0000 | [diff] [blame] | 617 |     } else { | 
| Eli Bendersky | 737b173 | 2012-05-29 06:02:56 +0300 | [diff] [blame] | 618 |         /* no attrib arg, no kwds, so no attribute */ | 
| Fredrik Lundh | 8c8836b | 2005-12-16 22:06:06 +0000 | [diff] [blame] | 619 |         Py_INCREF(Py_None); | 
 | 620 |         attrib = Py_None; | 
 | 621 |     } | 
 | 622 |  | 
| Eli Bendersky | 092af1f | 2012-03-04 07:14:03 +0200 | [diff] [blame] | 623 |     elem = create_new_element(tag, attrib); | 
| Fredrik Lundh | 8c8836b | 2005-12-16 22:06:06 +0000 | [diff] [blame] | 624 |     Py_DECREF(attrib); | 
| Victor Stinner | 71c8b7e | 2013-07-11 23:08:39 +0200 | [diff] [blame] | 625 |     if (elem == NULL) | 
 | 626 |         return NULL; | 
| Fredrik Lundh | 8c8836b | 2005-12-16 22:06:06 +0000 | [diff] [blame] | 627 |  | 
| Fredrik Lundh | 44ed4db | 2006-03-12 21:06:35 +0000 | [diff] [blame] | 628 |     if (element_add_subelement(parent, elem) < 0) { | 
 | 629 |         Py_DECREF(elem); | 
| Fredrik Lundh | 8c8836b | 2005-12-16 22:06:06 +0000 | [diff] [blame] | 630 |         return NULL; | 
| Fredrik Lundh | 44ed4db | 2006-03-12 21:06:35 +0000 | [diff] [blame] | 631 |     } | 
| Fredrik Lundh | 8c8836b | 2005-12-16 22:06:06 +0000 | [diff] [blame] | 632 |  | 
 | 633 |     return elem; | 
 | 634 | } | 
 | 635 |  | 
| Eli Bendersky | 0192ba3 | 2012-03-30 16:38:33 +0300 | [diff] [blame] | 636 | static int | 
 | 637 | element_gc_traverse(ElementObject *self, visitproc visit, void *arg) | 
 | 638 | { | 
 | 639 |     Py_VISIT(self->tag); | 
 | 640 |     Py_VISIT(JOIN_OBJ(self->text)); | 
 | 641 |     Py_VISIT(JOIN_OBJ(self->tail)); | 
 | 642 |  | 
 | 643 |     if (self->extra) { | 
| Serhiy Storchaka | 26861b0 | 2015-02-16 20:52:17 +0200 | [diff] [blame] | 644 |         Py_ssize_t i; | 
| Eli Bendersky | 0192ba3 | 2012-03-30 16:38:33 +0300 | [diff] [blame] | 645 |         Py_VISIT(self->extra->attrib); | 
 | 646 |  | 
 | 647 |         for (i = 0; i < self->extra->length; ++i) | 
 | 648 |             Py_VISIT(self->extra->children[i]); | 
 | 649 |     } | 
 | 650 |     return 0; | 
 | 651 | } | 
 | 652 |  | 
 | 653 | static int | 
 | 654 | element_gc_clear(ElementObject *self) | 
 | 655 | { | 
| Eli Bendersky | 0192ba3 | 2012-03-30 16:38:33 +0300 | [diff] [blame] | 656 |     Py_CLEAR(self->tag); | 
| Eli Bendersky | dd3661e | 2013-09-13 06:24:25 -0700 | [diff] [blame] | 657 |     _clear_joined_ptr(&self->text); | 
 | 658 |     _clear_joined_ptr(&self->tail); | 
| Eli Bendersky | 0192ba3 | 2012-03-30 16:38:33 +0300 | [diff] [blame] | 659 |  | 
 | 660 |     /* After dropping all references from extra, it's no longer valid anyway, | 
| Eli Bendersky | ebf37a2 | 2012-04-03 22:02:37 +0300 | [diff] [blame] | 661 |      * so fully deallocate it. | 
| Eli Bendersky | 0192ba3 | 2012-03-30 16:38:33 +0300 | [diff] [blame] | 662 |     */ | 
| Serhiy Storchaka | 6f906b3 | 2018-10-18 09:49:54 +0300 | [diff] [blame] | 663 |     clear_extra(self); | 
| Eli Bendersky | 0192ba3 | 2012-03-30 16:38:33 +0300 | [diff] [blame] | 664 |     return 0; | 
 | 665 | } | 
 | 666 |  | 
| Fredrik Lundh | 8c8836b | 2005-12-16 22:06:06 +0000 | [diff] [blame] | 667 | static void | 
 | 668 | element_dealloc(ElementObject* self) | 
 | 669 | { | 
| INADA Naoki | a6296d3 | 2017-08-24 14:55:17 +0900 | [diff] [blame] | 670 |     /* bpo-31095: UnTrack is needed before calling any callbacks */ | 
| Eli Bendersky | 0192ba3 | 2012-03-30 16:38:33 +0300 | [diff] [blame] | 671 |     PyObject_GC_UnTrack(self); | 
| Serhiy Storchaka | 18f018c | 2016-12-21 12:32:56 +0200 | [diff] [blame] | 672 |     Py_TRASHCAN_SAFE_BEGIN(self) | 
| Eli Bendersky | ebf37a2 | 2012-04-03 22:02:37 +0300 | [diff] [blame] | 673 |  | 
 | 674 |     if (self->weakreflist != NULL) | 
 | 675 |         PyObject_ClearWeakRefs((PyObject *) self); | 
 | 676 |  | 
| Eli Bendersky | 0192ba3 | 2012-03-30 16:38:33 +0300 | [diff] [blame] | 677 |     /* element_gc_clear clears all references and deallocates extra | 
 | 678 |     */ | 
 | 679 |     element_gc_clear(self); | 
| Fredrik Lundh | 8c8836b | 2005-12-16 22:06:06 +0000 | [diff] [blame] | 680 |  | 
 | 681 |     RELEASE(sizeof(ElementObject), "destroy element"); | 
| Eli Bendersky | 092af1f | 2012-03-04 07:14:03 +0200 | [diff] [blame] | 682 |     Py_TYPE(self)->tp_free((PyObject *)self); | 
| Serhiy Storchaka | 18f018c | 2016-12-21 12:32:56 +0200 | [diff] [blame] | 683 |     Py_TRASHCAN_SAFE_END(self) | 
| Fredrik Lundh | 8c8836b | 2005-12-16 22:06:06 +0000 | [diff] [blame] | 684 | } | 
 | 685 |  | 
 | 686 | /* -------------------------------------------------------------------- */ | 
| Fredrik Lundh | 8c8836b | 2005-12-16 22:06:06 +0000 | [diff] [blame] | 687 |  | 
| Serhiy Storchaka | cb98556 | 2015-05-04 15:32:48 +0300 | [diff] [blame] | 688 | /*[clinic input] | 
 | 689 | _elementtree.Element.append | 
| Fredrik Lundh | 8c8836b | 2005-12-16 22:06:06 +0000 | [diff] [blame] | 690 |  | 
| Serhiy Storchaka | cb98556 | 2015-05-04 15:32:48 +0300 | [diff] [blame] | 691 |     subelement: object(subclass_of='&Element_Type') | 
 | 692 |     / | 
 | 693 |  | 
 | 694 | [clinic start generated code]*/ | 
 | 695 |  | 
 | 696 | static PyObject * | 
 | 697 | _elementtree_Element_append_impl(ElementObject *self, PyObject *subelement) | 
 | 698 | /*[clinic end generated code: output=54a884b7cf2295f4 input=3ed648beb5bfa22a]*/ | 
 | 699 | { | 
 | 700 |     if (element_add_subelement(self, subelement) < 0) | 
| Fredrik Lundh | 8c8836b | 2005-12-16 22:06:06 +0000 | [diff] [blame] | 701 |         return NULL; | 
 | 702 |  | 
 | 703 |     Py_RETURN_NONE; | 
 | 704 | } | 
 | 705 |  | 
| Serhiy Storchaka | cb98556 | 2015-05-04 15:32:48 +0300 | [diff] [blame] | 706 | /*[clinic input] | 
 | 707 | _elementtree.Element.clear | 
| Fredrik Lundh | 8c8836b | 2005-12-16 22:06:06 +0000 | [diff] [blame] | 708 |  | 
| Serhiy Storchaka | cb98556 | 2015-05-04 15:32:48 +0300 | [diff] [blame] | 709 | [clinic start generated code]*/ | 
 | 710 |  | 
 | 711 | static PyObject * | 
 | 712 | _elementtree_Element_clear_impl(ElementObject *self) | 
 | 713 | /*[clinic end generated code: output=8bcd7a51f94cfff6 input=3c719ff94bf45dd6]*/ | 
 | 714 | { | 
| Serhiy Storchaka | 6f906b3 | 2018-10-18 09:49:54 +0300 | [diff] [blame] | 715 |     clear_extra(self); | 
| Fredrik Lundh | 8c8836b | 2005-12-16 22:06:06 +0000 | [diff] [blame] | 716 |  | 
 | 717 |     Py_INCREF(Py_None); | 
| Oren Milman | 39ecb9c | 2017-10-10 23:26:24 +0300 | [diff] [blame] | 718 |     _set_joined_ptr(&self->text, Py_None); | 
| Fredrik Lundh | 8c8836b | 2005-12-16 22:06:06 +0000 | [diff] [blame] | 719 |  | 
 | 720 |     Py_INCREF(Py_None); | 
| Oren Milman | 39ecb9c | 2017-10-10 23:26:24 +0300 | [diff] [blame] | 721 |     _set_joined_ptr(&self->tail, Py_None); | 
| Fredrik Lundh | 8c8836b | 2005-12-16 22:06:06 +0000 | [diff] [blame] | 722 |  | 
 | 723 |     Py_RETURN_NONE; | 
 | 724 | } | 
 | 725 |  | 
| Serhiy Storchaka | cb98556 | 2015-05-04 15:32:48 +0300 | [diff] [blame] | 726 | /*[clinic input] | 
 | 727 | _elementtree.Element.__copy__ | 
 | 728 |  | 
 | 729 | [clinic start generated code]*/ | 
 | 730 |  | 
 | 731 | static PyObject * | 
 | 732 | _elementtree_Element___copy___impl(ElementObject *self) | 
 | 733 | /*[clinic end generated code: output=2c701ebff7247781 input=ad87aaebe95675bf]*/ | 
| Fredrik Lundh | 8c8836b | 2005-12-16 22:06:06 +0000 | [diff] [blame] | 734 | { | 
| Serhiy Storchaka | 26861b0 | 2015-02-16 20:52:17 +0200 | [diff] [blame] | 735 |     Py_ssize_t i; | 
| Fredrik Lundh | 8c8836b | 2005-12-16 22:06:06 +0000 | [diff] [blame] | 736 |     ElementObject* element; | 
 | 737 |  | 
| Eli Bendersky | 092af1f | 2012-03-04 07:14:03 +0200 | [diff] [blame] | 738 |     element = (ElementObject*) create_new_element( | 
| Eli Bendersky | 163d7f0 | 2013-11-24 06:55:04 -0800 | [diff] [blame] | 739 |         self->tag, (self->extra) ? self->extra->attrib : Py_None); | 
| Fredrik Lundh | 8c8836b | 2005-12-16 22:06:06 +0000 | [diff] [blame] | 740 |     if (!element) | 
 | 741 |         return NULL; | 
 | 742 |  | 
| Oren Milman | 39ecb9c | 2017-10-10 23:26:24 +0300 | [diff] [blame] | 743 |     Py_INCREF(JOIN_OBJ(self->text)); | 
 | 744 |     _set_joined_ptr(&element->text, self->text); | 
| Fredrik Lundh | 8c8836b | 2005-12-16 22:06:06 +0000 | [diff] [blame] | 745 |  | 
| Oren Milman | 39ecb9c | 2017-10-10 23:26:24 +0300 | [diff] [blame] | 746 |     Py_INCREF(JOIN_OBJ(self->tail)); | 
 | 747 |     _set_joined_ptr(&element->tail, self->tail); | 
| Fredrik Lundh | 8c8836b | 2005-12-16 22:06:06 +0000 | [diff] [blame] | 748 |  | 
| Serhiy Storchaka | 6f906b3 | 2018-10-18 09:49:54 +0300 | [diff] [blame] | 749 |     assert(!element->extra || !element->extra->length); | 
| Fredrik Lundh | 8c8836b | 2005-12-16 22:06:06 +0000 | [diff] [blame] | 750 |     if (self->extra) { | 
| Fredrik Lundh | 44ed4db | 2006-03-12 21:06:35 +0000 | [diff] [blame] | 751 |         if (element_resize(element, self->extra->length) < 0) { | 
 | 752 |             Py_DECREF(element); | 
| Fredrik Lundh | 8c8836b | 2005-12-16 22:06:06 +0000 | [diff] [blame] | 753 |             return NULL; | 
| Fredrik Lundh | 44ed4db | 2006-03-12 21:06:35 +0000 | [diff] [blame] | 754 |         } | 
| Fredrik Lundh | 8c8836b | 2005-12-16 22:06:06 +0000 | [diff] [blame] | 755 |  | 
 | 756 |         for (i = 0; i < self->extra->length; i++) { | 
 | 757 |             Py_INCREF(self->extra->children[i]); | 
 | 758 |             element->extra->children[i] = self->extra->children[i]; | 
 | 759 |         } | 
 | 760 |  | 
| Serhiy Storchaka | 6f906b3 | 2018-10-18 09:49:54 +0300 | [diff] [blame] | 761 |         assert(!element->extra->length); | 
| Fredrik Lundh | 8c8836b | 2005-12-16 22:06:06 +0000 | [diff] [blame] | 762 |         element->extra->length = self->extra->length; | 
| Fredrik Lundh | 8c8836b | 2005-12-16 22:06:06 +0000 | [diff] [blame] | 763 |     } | 
 | 764 |  | 
 | 765 |     return (PyObject*) element; | 
 | 766 | } | 
 | 767 |  | 
| Serhiy Storchaka | 060ed71 | 2015-12-21 12:57:27 +0200 | [diff] [blame] | 768 | /* Helper for a deep copy. */ | 
 | 769 | LOCAL(PyObject *) deepcopy(PyObject *, PyObject *); | 
 | 770 |  | 
| Serhiy Storchaka | cb98556 | 2015-05-04 15:32:48 +0300 | [diff] [blame] | 771 | /*[clinic input] | 
 | 772 | _elementtree.Element.__deepcopy__ | 
 | 773 |  | 
| Oren Milman | d056818 | 2017-09-12 17:39:15 +0300 | [diff] [blame] | 774 |     memo: object(subclass_of="&PyDict_Type") | 
| Serhiy Storchaka | cb98556 | 2015-05-04 15:32:48 +0300 | [diff] [blame] | 775 |     / | 
 | 776 |  | 
 | 777 | [clinic start generated code]*/ | 
 | 778 |  | 
 | 779 | static PyObject * | 
| Oren Milman | d056818 | 2017-09-12 17:39:15 +0300 | [diff] [blame] | 780 | _elementtree_Element___deepcopy___impl(ElementObject *self, PyObject *memo) | 
 | 781 | /*[clinic end generated code: output=eefc3df50465b642 input=a2d40348c0aade10]*/ | 
| Fredrik Lundh | 8c8836b | 2005-12-16 22:06:06 +0000 | [diff] [blame] | 782 | { | 
| Serhiy Storchaka | 26861b0 | 2015-02-16 20:52:17 +0200 | [diff] [blame] | 783 |     Py_ssize_t i; | 
| Fredrik Lundh | 8c8836b | 2005-12-16 22:06:06 +0000 | [diff] [blame] | 784 |     ElementObject* element; | 
 | 785 |     PyObject* tag; | 
 | 786 |     PyObject* attrib; | 
 | 787 |     PyObject* text; | 
 | 788 |     PyObject* tail; | 
 | 789 |     PyObject* id; | 
 | 790 |  | 
| Fredrik Lundh | 8c8836b | 2005-12-16 22:06:06 +0000 | [diff] [blame] | 791 |     tag = deepcopy(self->tag, memo); | 
 | 792 |     if (!tag) | 
 | 793 |         return NULL; | 
 | 794 |  | 
 | 795 |     if (self->extra) { | 
 | 796 |         attrib = deepcopy(self->extra->attrib, memo); | 
 | 797 |         if (!attrib) { | 
 | 798 |             Py_DECREF(tag); | 
 | 799 |             return NULL; | 
 | 800 |         } | 
 | 801 |     } else { | 
 | 802 |         Py_INCREF(Py_None); | 
 | 803 |         attrib = Py_None; | 
 | 804 |     } | 
 | 805 |  | 
| Eli Bendersky | 092af1f | 2012-03-04 07:14:03 +0200 | [diff] [blame] | 806 |     element = (ElementObject*) create_new_element(tag, attrib); | 
| Fredrik Lundh | 8c8836b | 2005-12-16 22:06:06 +0000 | [diff] [blame] | 807 |  | 
 | 808 |     Py_DECREF(tag); | 
 | 809 |     Py_DECREF(attrib); | 
 | 810 |  | 
 | 811 |     if (!element) | 
 | 812 |         return NULL; | 
| Victor Stinner | bfc7bf0 | 2011-03-21 13:23:42 +0100 | [diff] [blame] | 813 |  | 
| Fredrik Lundh | 8c8836b | 2005-12-16 22:06:06 +0000 | [diff] [blame] | 814 |     text = deepcopy(JOIN_OBJ(self->text), memo); | 
 | 815 |     if (!text) | 
 | 816 |         goto error; | 
| Oren Milman | 39ecb9c | 2017-10-10 23:26:24 +0300 | [diff] [blame] | 817 |     _set_joined_ptr(&element->text, JOIN_SET(text, JOIN_GET(self->text))); | 
| Fredrik Lundh | 8c8836b | 2005-12-16 22:06:06 +0000 | [diff] [blame] | 818 |  | 
 | 819 |     tail = deepcopy(JOIN_OBJ(self->tail), memo); | 
 | 820 |     if (!tail) | 
 | 821 |         goto error; | 
| Oren Milman | 39ecb9c | 2017-10-10 23:26:24 +0300 | [diff] [blame] | 822 |     _set_joined_ptr(&element->tail, JOIN_SET(tail, JOIN_GET(self->tail))); | 
| Fredrik Lundh | 8c8836b | 2005-12-16 22:06:06 +0000 | [diff] [blame] | 823 |  | 
| Serhiy Storchaka | 6f906b3 | 2018-10-18 09:49:54 +0300 | [diff] [blame] | 824 |     assert(!element->extra || !element->extra->length); | 
| Fredrik Lundh | 8c8836b | 2005-12-16 22:06:06 +0000 | [diff] [blame] | 825 |     if (self->extra) { | 
| Fredrik Lundh | 8c8836b | 2005-12-16 22:06:06 +0000 | [diff] [blame] | 826 |         if (element_resize(element, self->extra->length) < 0) | 
 | 827 |             goto error; | 
 | 828 |  | 
 | 829 |         for (i = 0; i < self->extra->length; i++) { | 
 | 830 |             PyObject* child = deepcopy(self->extra->children[i], memo); | 
| Serhiy Storchaka | f081fd8 | 2018-10-19 12:12:57 +0300 | [diff] [blame] | 831 |             if (!child || !Element_Check(child)) { | 
 | 832 |                 if (child) { | 
 | 833 |                     raise_type_error(child); | 
 | 834 |                     Py_DECREF(child); | 
 | 835 |                 } | 
| Fredrik Lundh | 8c8836b | 2005-12-16 22:06:06 +0000 | [diff] [blame] | 836 |                 element->extra->length = i; | 
 | 837 |                 goto error; | 
 | 838 |             } | 
 | 839 |             element->extra->children[i] = child; | 
 | 840 |         } | 
 | 841 |  | 
| Serhiy Storchaka | 6f906b3 | 2018-10-18 09:49:54 +0300 | [diff] [blame] | 842 |         assert(!element->extra->length); | 
| Fredrik Lundh | 8c8836b | 2005-12-16 22:06:06 +0000 | [diff] [blame] | 843 |         element->extra->length = self->extra->length; | 
| Fredrik Lundh | 8c8836b | 2005-12-16 22:06:06 +0000 | [diff] [blame] | 844 |     } | 
 | 845 |  | 
 | 846 |     /* add object to memo dictionary (so deepcopy won't visit it again) */ | 
| Benjamin Peterson | ca47063 | 2016-09-06 13:47:26 -0700 | [diff] [blame] | 847 |     id = PyLong_FromSsize_t((uintptr_t) self); | 
| Florent Xicluna | f15351d | 2010-03-13 23:24:31 +0000 | [diff] [blame] | 848 |     if (!id) | 
 | 849 |         goto error; | 
| Fredrik Lundh | 8c8836b | 2005-12-16 22:06:06 +0000 | [diff] [blame] | 850 |  | 
 | 851 |     i = PyDict_SetItem(memo, id, (PyObject*) element); | 
 | 852 |  | 
 | 853 |     Py_DECREF(id); | 
 | 854 |  | 
 | 855 |     if (i < 0) | 
 | 856 |         goto error; | 
 | 857 |  | 
 | 858 |     return (PyObject*) element; | 
 | 859 |  | 
 | 860 |   error: | 
 | 861 |     Py_DECREF(element); | 
 | 862 |     return NULL; | 
 | 863 | } | 
 | 864 |  | 
| Serhiy Storchaka | 060ed71 | 2015-12-21 12:57:27 +0200 | [diff] [blame] | 865 | LOCAL(PyObject *) | 
 | 866 | deepcopy(PyObject *object, PyObject *memo) | 
 | 867 | { | 
 | 868 |     /* do a deep copy of the given object */ | 
| Serhiy Storchaka | 060ed71 | 2015-12-21 12:57:27 +0200 | [diff] [blame] | 869 |     elementtreestate *st; | 
| Victor Stinner | 7fbac45 | 2016-08-20 01:34:44 +0200 | [diff] [blame] | 870 |     PyObject *stack[2]; | 
| Serhiy Storchaka | 060ed71 | 2015-12-21 12:57:27 +0200 | [diff] [blame] | 871 |  | 
 | 872 |     /* Fast paths */ | 
 | 873 |     if (object == Py_None || PyUnicode_CheckExact(object)) { | 
 | 874 |         Py_INCREF(object); | 
 | 875 |         return object; | 
 | 876 |     } | 
 | 877 |  | 
 | 878 |     if (Py_REFCNT(object) == 1) { | 
 | 879 |         if (PyDict_CheckExact(object)) { | 
 | 880 |             PyObject *key, *value; | 
 | 881 |             Py_ssize_t pos = 0; | 
 | 882 |             int simple = 1; | 
 | 883 |             while (PyDict_Next(object, &pos, &key, &value)) { | 
 | 884 |                 if (!PyUnicode_CheckExact(key) || !PyUnicode_CheckExact(value)) { | 
 | 885 |                     simple = 0; | 
 | 886 |                     break; | 
 | 887 |                 } | 
 | 888 |             } | 
 | 889 |             if (simple) | 
 | 890 |                 return PyDict_Copy(object); | 
 | 891 |             /* Fall through to general case */ | 
 | 892 |         } | 
 | 893 |         else if (Element_CheckExact(object)) { | 
| Oren Milman | d056818 | 2017-09-12 17:39:15 +0300 | [diff] [blame] | 894 |             return _elementtree_Element___deepcopy___impl( | 
 | 895 |                 (ElementObject *)object, memo); | 
| Serhiy Storchaka | 060ed71 | 2015-12-21 12:57:27 +0200 | [diff] [blame] | 896 |         } | 
 | 897 |     } | 
 | 898 |  | 
 | 899 |     /* General case */ | 
 | 900 |     st = ET_STATE_GLOBAL; | 
 | 901 |     if (!st->deepcopy_obj) { | 
 | 902 |         PyErr_SetString(PyExc_RuntimeError, | 
 | 903 |                         "deepcopy helper not found"); | 
 | 904 |         return NULL; | 
 | 905 |     } | 
 | 906 |  | 
| Victor Stinner | 7fbac45 | 2016-08-20 01:34:44 +0200 | [diff] [blame] | 907 |     stack[0] = object; | 
 | 908 |     stack[1] = memo; | 
| Victor Stinner | 559bb6a | 2016-08-22 22:48:54 +0200 | [diff] [blame] | 909 |     return _PyObject_FastCall(st->deepcopy_obj, stack, 2); | 
| Serhiy Storchaka | 060ed71 | 2015-12-21 12:57:27 +0200 | [diff] [blame] | 910 | } | 
 | 911 |  | 
 | 912 |  | 
| Serhiy Storchaka | cb98556 | 2015-05-04 15:32:48 +0300 | [diff] [blame] | 913 | /*[clinic input] | 
 | 914 | _elementtree.Element.__sizeof__ -> Py_ssize_t | 
 | 915 |  | 
 | 916 | [clinic start generated code]*/ | 
 | 917 |  | 
 | 918 | static Py_ssize_t | 
 | 919 | _elementtree_Element___sizeof___impl(ElementObject *self) | 
 | 920 | /*[clinic end generated code: output=bf73867721008000 input=70f4b323d55a17c1]*/ | 
| Martin v. Löwis | bce1666 | 2012-06-17 10:41:22 +0200 | [diff] [blame] | 921 | { | 
| Serhiy Storchaka | 5c4064e | 2015-12-19 20:05:25 +0200 | [diff] [blame] | 922 |     Py_ssize_t result = _PyObject_SIZE(Py_TYPE(self)); | 
| Martin v. Löwis | bce1666 | 2012-06-17 10:41:22 +0200 | [diff] [blame] | 923 |     if (self->extra) { | 
 | 924 |         result += sizeof(ElementObjectExtra); | 
 | 925 |         if (self->extra->children != self->extra->_children) | 
 | 926 |             result += sizeof(PyObject*) * self->extra->allocated; | 
 | 927 |     } | 
| Serhiy Storchaka | cb98556 | 2015-05-04 15:32:48 +0300 | [diff] [blame] | 928 |     return result; | 
| Martin v. Löwis | bce1666 | 2012-06-17 10:41:22 +0200 | [diff] [blame] | 929 | } | 
 | 930 |  | 
| Eli Bendersky | 698bdb2 | 2013-01-10 06:01:06 -0800 | [diff] [blame] | 931 | /* dict keys for getstate/setstate. */ | 
 | 932 | #define PICKLED_TAG "tag" | 
 | 933 | #define PICKLED_CHILDREN "_children" | 
 | 934 | #define PICKLED_ATTRIB "attrib" | 
 | 935 | #define PICKLED_TAIL "tail" | 
 | 936 | #define PICKLED_TEXT "text" | 
 | 937 |  | 
 | 938 | /* __getstate__ returns a fabricated instance dict as in the pure-Python | 
 | 939 |  * Element implementation, for interoperability/interchangeability.  This | 
 | 940 |  * makes the pure-Python implementation details an API, but (a) there aren't | 
 | 941 |  * any unnecessary structures there; and (b) it buys compatibility with 3.2 | 
 | 942 |  * pickles.  See issue #16076. | 
 | 943 |  */ | 
| Serhiy Storchaka | cb98556 | 2015-05-04 15:32:48 +0300 | [diff] [blame] | 944 | /*[clinic input] | 
 | 945 | _elementtree.Element.__getstate__ | 
 | 946 |  | 
 | 947 | [clinic start generated code]*/ | 
 | 948 |  | 
| Eli Bendersky | 698bdb2 | 2013-01-10 06:01:06 -0800 | [diff] [blame] | 949 | static PyObject * | 
| Serhiy Storchaka | cb98556 | 2015-05-04 15:32:48 +0300 | [diff] [blame] | 950 | _elementtree_Element___getstate___impl(ElementObject *self) | 
 | 951 | /*[clinic end generated code: output=37279aeeb6bb5b04 input=f0d16d7ec2f7adc1]*/ | 
| Eli Bendersky | 698bdb2 | 2013-01-10 06:01:06 -0800 | [diff] [blame] | 952 | { | 
| Serhiy Storchaka | 26861b0 | 2015-02-16 20:52:17 +0200 | [diff] [blame] | 953 |     Py_ssize_t i, noattrib; | 
| Eli Bendersky | 698bdb2 | 2013-01-10 06:01:06 -0800 | [diff] [blame] | 954 |     PyObject *instancedict = NULL, *children; | 
 | 955 |  | 
 | 956 |     /* Build a list of children. */ | 
 | 957 |     children = PyList_New(self->extra ? self->extra->length : 0); | 
 | 958 |     if (!children) | 
 | 959 |         return NULL; | 
 | 960 |     for (i = 0; i < PyList_GET_SIZE(children); i++) { | 
 | 961 |         PyObject *child = self->extra->children[i]; | 
 | 962 |         Py_INCREF(child); | 
 | 963 |         PyList_SET_ITEM(children, i, child); | 
 | 964 |     } | 
 | 965 |  | 
 | 966 |     /* Construct the state object. */ | 
 | 967 |     noattrib = (self->extra == NULL || self->extra->attrib == Py_None); | 
 | 968 |     if (noattrib) | 
 | 969 |         instancedict = Py_BuildValue("{sOsOs{}sOsO}", | 
 | 970 |                                      PICKLED_TAG, self->tag, | 
 | 971 |                                      PICKLED_CHILDREN, children, | 
 | 972 |                                      PICKLED_ATTRIB, | 
| Eli Bendersky | dd3661e | 2013-09-13 06:24:25 -0700 | [diff] [blame] | 973 |                                      PICKLED_TEXT, JOIN_OBJ(self->text), | 
 | 974 |                                      PICKLED_TAIL, JOIN_OBJ(self->tail)); | 
| Eli Bendersky | 698bdb2 | 2013-01-10 06:01:06 -0800 | [diff] [blame] | 975 |     else | 
 | 976 |         instancedict = Py_BuildValue("{sOsOsOsOsO}", | 
 | 977 |                                      PICKLED_TAG, self->tag, | 
 | 978 |                                      PICKLED_CHILDREN, children, | 
 | 979 |                                      PICKLED_ATTRIB, self->extra->attrib, | 
| Eli Bendersky | dd3661e | 2013-09-13 06:24:25 -0700 | [diff] [blame] | 980 |                                      PICKLED_TEXT, JOIN_OBJ(self->text), | 
 | 981 |                                      PICKLED_TAIL, JOIN_OBJ(self->tail)); | 
| Eli Bendersky | b8f6dc8 | 2013-01-12 05:20:16 -0800 | [diff] [blame] | 982 |     if (instancedict) { | 
 | 983 |         Py_DECREF(children); | 
| Eli Bendersky | 698bdb2 | 2013-01-10 06:01:06 -0800 | [diff] [blame] | 984 |         return instancedict; | 
| Eli Bendersky | b8f6dc8 | 2013-01-12 05:20:16 -0800 | [diff] [blame] | 985 |     } | 
| Eli Bendersky | 698bdb2 | 2013-01-10 06:01:06 -0800 | [diff] [blame] | 986 |     else { | 
 | 987 |         for (i = 0; i < PyList_GET_SIZE(children); i++) | 
 | 988 |             Py_DECREF(PyList_GET_ITEM(children, i)); | 
 | 989 |         Py_DECREF(children); | 
 | 990 |  | 
 | 991 |         return NULL; | 
 | 992 |     } | 
 | 993 | } | 
 | 994 |  | 
 | 995 | static PyObject * | 
 | 996 | element_setstate_from_attributes(ElementObject *self, | 
 | 997 |                                  PyObject *tag, | 
 | 998 |                                  PyObject *attrib, | 
 | 999 |                                  PyObject *text, | 
 | 1000 |                                  PyObject *tail, | 
 | 1001 |                                  PyObject *children) | 
 | 1002 | { | 
 | 1003 |     Py_ssize_t i, nchildren; | 
| Serhiy Storchaka | 6f906b3 | 2018-10-18 09:49:54 +0300 | [diff] [blame] | 1004 |     ElementObjectExtra *oldextra = NULL; | 
| Eli Bendersky | 698bdb2 | 2013-01-10 06:01:06 -0800 | [diff] [blame] | 1005 |  | 
 | 1006 |     if (!tag) { | 
 | 1007 |         PyErr_SetString(PyExc_TypeError, "tag may not be NULL"); | 
 | 1008 |         return NULL; | 
 | 1009 |     } | 
| Eli Bendersky | 698bdb2 | 2013-01-10 06:01:06 -0800 | [diff] [blame] | 1010 |  | 
| Serhiy Storchaka | 191321d | 2015-12-27 15:41:34 +0200 | [diff] [blame] | 1011 |     Py_INCREF(tag); | 
| Serhiy Storchaka | 4884271 | 2016-04-06 09:45:48 +0300 | [diff] [blame] | 1012 |     Py_XSETREF(self->tag, tag); | 
| Eli Bendersky | 698bdb2 | 2013-01-10 06:01:06 -0800 | [diff] [blame] | 1013 |  | 
| Oren Milman | 39ecb9c | 2017-10-10 23:26:24 +0300 | [diff] [blame] | 1014 |     text = text ? JOIN_SET(text, PyList_CheckExact(text)) : Py_None; | 
 | 1015 |     Py_INCREF(JOIN_OBJ(text)); | 
 | 1016 |     _set_joined_ptr(&self->text, text); | 
| Eli Bendersky | 698bdb2 | 2013-01-10 06:01:06 -0800 | [diff] [blame] | 1017 |  | 
| Oren Milman | 39ecb9c | 2017-10-10 23:26:24 +0300 | [diff] [blame] | 1018 |     tail = tail ? JOIN_SET(tail, PyList_CheckExact(tail)) : Py_None; | 
 | 1019 |     Py_INCREF(JOIN_OBJ(tail)); | 
 | 1020 |     _set_joined_ptr(&self->tail, tail); | 
| Eli Bendersky | 698bdb2 | 2013-01-10 06:01:06 -0800 | [diff] [blame] | 1021 |  | 
 | 1022 |     /* Handle ATTRIB and CHILDREN. */ | 
| Serhiy Storchaka | 6f906b3 | 2018-10-18 09:49:54 +0300 | [diff] [blame] | 1023 |     if (!children && !attrib) { | 
| Eli Bendersky | 698bdb2 | 2013-01-10 06:01:06 -0800 | [diff] [blame] | 1024 |         Py_RETURN_NONE; | 
| Serhiy Storchaka | 6f906b3 | 2018-10-18 09:49:54 +0300 | [diff] [blame] | 1025 |     } | 
| Eli Bendersky | 698bdb2 | 2013-01-10 06:01:06 -0800 | [diff] [blame] | 1026 |  | 
 | 1027 |     /* Compute 'nchildren'. */ | 
 | 1028 |     if (children) { | 
 | 1029 |         if (!PyList_Check(children)) { | 
 | 1030 |             PyErr_SetString(PyExc_TypeError, "'_children' is not a list"); | 
 | 1031 |             return NULL; | 
 | 1032 |         } | 
| Serhiy Storchaka | 6f906b3 | 2018-10-18 09:49:54 +0300 | [diff] [blame] | 1033 |         nchildren = PyList_GET_SIZE(children); | 
 | 1034 |  | 
 | 1035 |         /* (Re-)allocate 'extra'. | 
 | 1036 |            Avoid DECREFs calling into this code again (cycles, etc.) | 
 | 1037 |          */ | 
 | 1038 |         oldextra = self->extra; | 
 | 1039 |         self->extra = NULL; | 
 | 1040 |         if (element_resize(self, nchildren)) { | 
 | 1041 |             assert(!self->extra || !self->extra->length); | 
 | 1042 |             clear_extra(self); | 
 | 1043 |             self->extra = oldextra; | 
 | 1044 |             return NULL; | 
 | 1045 |         } | 
 | 1046 |         assert(self->extra); | 
 | 1047 |         assert(self->extra->allocated >= nchildren); | 
 | 1048 |         if (oldextra) { | 
 | 1049 |             assert(self->extra->attrib == Py_None); | 
 | 1050 |             self->extra->attrib = oldextra->attrib; | 
 | 1051 |             oldextra->attrib = Py_None; | 
 | 1052 |         } | 
 | 1053 |  | 
 | 1054 |         /* Copy children */ | 
 | 1055 |         for (i = 0; i < nchildren; i++) { | 
| Serhiy Storchaka | f081fd8 | 2018-10-19 12:12:57 +0300 | [diff] [blame] | 1056 |             PyObject *child = PyList_GET_ITEM(children, i); | 
 | 1057 |             if (!Element_Check(child)) { | 
 | 1058 |                 raise_type_error(child); | 
 | 1059 |                 self->extra->length = i; | 
 | 1060 |                 dealloc_extra(oldextra); | 
 | 1061 |                 return NULL; | 
 | 1062 |             } | 
 | 1063 |             Py_INCREF(child); | 
 | 1064 |             self->extra->children[i] = child; | 
| Serhiy Storchaka | 6f906b3 | 2018-10-18 09:49:54 +0300 | [diff] [blame] | 1065 |         } | 
 | 1066 |  | 
 | 1067 |         assert(!self->extra->length); | 
 | 1068 |         self->extra->length = nchildren; | 
| Eli Bendersky | 698bdb2 | 2013-01-10 06:01:06 -0800 | [diff] [blame] | 1069 |     } | 
 | 1070 |     else { | 
| Serhiy Storchaka | 6f906b3 | 2018-10-18 09:49:54 +0300 | [diff] [blame] | 1071 |         if (element_resize(self, 0)) { | 
 | 1072 |             return NULL; | 
 | 1073 |         } | 
| Eli Bendersky | 698bdb2 | 2013-01-10 06:01:06 -0800 | [diff] [blame] | 1074 |     } | 
 | 1075 |  | 
| Eli Bendersky | 698bdb2 | 2013-01-10 06:01:06 -0800 | [diff] [blame] | 1076 |     /* Stash attrib. */ | 
 | 1077 |     if (attrib) { | 
| Eli Bendersky | 698bdb2 | 2013-01-10 06:01:06 -0800 | [diff] [blame] | 1078 |         Py_INCREF(attrib); | 
| Serhiy Storchaka | 4884271 | 2016-04-06 09:45:48 +0300 | [diff] [blame] | 1079 |         Py_XSETREF(self->extra->attrib, attrib); | 
| Eli Bendersky | 698bdb2 | 2013-01-10 06:01:06 -0800 | [diff] [blame] | 1080 |     } | 
| Serhiy Storchaka | 6f906b3 | 2018-10-18 09:49:54 +0300 | [diff] [blame] | 1081 |     dealloc_extra(oldextra); | 
| Eli Bendersky | 698bdb2 | 2013-01-10 06:01:06 -0800 | [diff] [blame] | 1082 |  | 
 | 1083 |     Py_RETURN_NONE; | 
 | 1084 | } | 
 | 1085 |  | 
 | 1086 | /* __setstate__ for Element instance from the Python implementation. | 
 | 1087 |  * 'state' should be the instance dict. | 
 | 1088 |  */ | 
| Serhiy Storchaka | cb98556 | 2015-05-04 15:32:48 +0300 | [diff] [blame] | 1089 |  | 
| Eli Bendersky | 698bdb2 | 2013-01-10 06:01:06 -0800 | [diff] [blame] | 1090 | static PyObject * | 
 | 1091 | element_setstate_from_Python(ElementObject *self, PyObject *state) | 
 | 1092 | { | 
 | 1093 |     static char *kwlist[] = {PICKLED_TAG, PICKLED_ATTRIB, PICKLED_TEXT, | 
 | 1094 |                              PICKLED_TAIL, PICKLED_CHILDREN, 0}; | 
 | 1095 |     PyObject *args; | 
 | 1096 |     PyObject *tag, *attrib, *text, *tail, *children; | 
| Eli Bendersky | 799e3ed | 2013-01-12 05:42:38 -0800 | [diff] [blame] | 1097 |     PyObject *retval; | 
| Eli Bendersky | 698bdb2 | 2013-01-10 06:01:06 -0800 | [diff] [blame] | 1098 |  | 
| Eli Bendersky | 698bdb2 | 2013-01-10 06:01:06 -0800 | [diff] [blame] | 1099 |     tag = attrib = text = tail = children = NULL; | 
 | 1100 |     args = PyTuple_New(0); | 
| Eli Bendersky | 799e3ed | 2013-01-12 05:42:38 -0800 | [diff] [blame] | 1101 |     if (!args) | 
| Eli Bendersky | 698bdb2 | 2013-01-10 06:01:06 -0800 | [diff] [blame] | 1102 |         return NULL; | 
| Eli Bendersky | 799e3ed | 2013-01-12 05:42:38 -0800 | [diff] [blame] | 1103 |  | 
 | 1104 |     if (PyArg_ParseTupleAndKeywords(args, state, "|$OOOOO", kwlist, &tag, | 
 | 1105 |                                     &attrib, &text, &tail, &children)) | 
 | 1106 |         retval = element_setstate_from_attributes(self, tag, attrib, text, | 
 | 1107 |                                                   tail, children); | 
| Eli Bendersky | 698bdb2 | 2013-01-10 06:01:06 -0800 | [diff] [blame] | 1108 |     else | 
| Eli Bendersky | 799e3ed | 2013-01-12 05:42:38 -0800 | [diff] [blame] | 1109 |         retval = NULL; | 
 | 1110 |  | 
 | 1111 |     Py_DECREF(args); | 
 | 1112 |     return retval; | 
| Eli Bendersky | 698bdb2 | 2013-01-10 06:01:06 -0800 | [diff] [blame] | 1113 | } | 
 | 1114 |  | 
| Serhiy Storchaka | cb98556 | 2015-05-04 15:32:48 +0300 | [diff] [blame] | 1115 | /*[clinic input] | 
 | 1116 | _elementtree.Element.__setstate__ | 
 | 1117 |  | 
 | 1118 |     state: object | 
 | 1119 |     / | 
 | 1120 |  | 
 | 1121 | [clinic start generated code]*/ | 
 | 1122 |  | 
| Eli Bendersky | 698bdb2 | 2013-01-10 06:01:06 -0800 | [diff] [blame] | 1123 | static PyObject * | 
| Serhiy Storchaka | cb98556 | 2015-05-04 15:32:48 +0300 | [diff] [blame] | 1124 | _elementtree_Element___setstate__(ElementObject *self, PyObject *state) | 
 | 1125 | /*[clinic end generated code: output=ea28bf3491b1f75e input=aaf80abea7c1e3b9]*/ | 
| Eli Bendersky | 698bdb2 | 2013-01-10 06:01:06 -0800 | [diff] [blame] | 1126 | { | 
 | 1127 |     if (!PyDict_CheckExact(state)) { | 
 | 1128 |         PyErr_Format(PyExc_TypeError, | 
 | 1129 |                      "Don't know how to unpickle \"%.200R\" as an Element", | 
 | 1130 |                      state); | 
 | 1131 |         return NULL; | 
 | 1132 |     } | 
 | 1133 |     else | 
 | 1134 |         return element_setstate_from_Python(self, state); | 
 | 1135 | } | 
 | 1136 |  | 
| Fredrik Lundh | 8c8836b | 2005-12-16 22:06:06 +0000 | [diff] [blame] | 1137 | LOCAL(int) | 
 | 1138 | checkpath(PyObject* tag) | 
 | 1139 | { | 
| Thomas Wouters | 0e3f591 | 2006-08-11 14:57:12 +0000 | [diff] [blame] | 1140 |     Py_ssize_t i; | 
 | 1141 |     int check = 1; | 
| Fredrik Lundh | 8c8836b | 2005-12-16 22:06:06 +0000 | [diff] [blame] | 1142 |  | 
 | 1143 |     /* check if a tag contains an xpath character */ | 
 | 1144 |  | 
| Florent Xicluna | f15351d | 2010-03-13 23:24:31 +0000 | [diff] [blame] | 1145 | #define PATHCHAR(ch) \ | 
 | 1146 |     (ch == '/' || ch == '*' || ch == '[' || ch == '@' || ch == '.') | 
| Fredrik Lundh | 8c8836b | 2005-12-16 22:06:06 +0000 | [diff] [blame] | 1147 |  | 
| Fredrik Lundh | 8c8836b | 2005-12-16 22:06:06 +0000 | [diff] [blame] | 1148 |     if (PyUnicode_Check(tag)) { | 
| Martin v. Löwis | d63a3b8 | 2011-09-28 07:41:54 +0200 | [diff] [blame] | 1149 |         const Py_ssize_t len = PyUnicode_GET_LENGTH(tag); | 
 | 1150 |         void *data = PyUnicode_DATA(tag); | 
 | 1151 |         unsigned int kind = PyUnicode_KIND(tag); | 
| Stefan Behnel | 4754168 | 2019-05-03 20:58:16 +0200 | [diff] [blame] | 1152 |         if (len >= 3 && PyUnicode_READ(kind, data, 0) == '{' && ( | 
 | 1153 |                 PyUnicode_READ(kind, data, 1) == '}' || ( | 
 | 1154 |                 PyUnicode_READ(kind, data, 1) == '*' && | 
 | 1155 |                 PyUnicode_READ(kind, data, 2) == '}'))) { | 
 | 1156 |             /* wildcard: '{}tag' or '{*}tag' */ | 
 | 1157 |             return 1; | 
 | 1158 |         } | 
| Martin v. Löwis | d63a3b8 | 2011-09-28 07:41:54 +0200 | [diff] [blame] | 1159 |         for (i = 0; i < len; i++) { | 
 | 1160 |             Py_UCS4 ch = PyUnicode_READ(kind, data, i); | 
 | 1161 |             if (ch == '{') | 
| Fredrik Lundh | 8c8836b | 2005-12-16 22:06:06 +0000 | [diff] [blame] | 1162 |                 check = 0; | 
| Martin v. Löwis | d63a3b8 | 2011-09-28 07:41:54 +0200 | [diff] [blame] | 1163 |             else if (ch == '}') | 
| Fredrik Lundh | 8c8836b | 2005-12-16 22:06:06 +0000 | [diff] [blame] | 1164 |                 check = 1; | 
| Martin v. Löwis | d63a3b8 | 2011-09-28 07:41:54 +0200 | [diff] [blame] | 1165 |             else if (check && PATHCHAR(ch)) | 
| Fredrik Lundh | 8c8836b | 2005-12-16 22:06:06 +0000 | [diff] [blame] | 1166 |                 return 1; | 
 | 1167 |         } | 
 | 1168 |         return 0; | 
 | 1169 |     } | 
| Christian Heimes | 72b710a | 2008-05-26 13:28:38 +0000 | [diff] [blame] | 1170 |     if (PyBytes_Check(tag)) { | 
 | 1171 |         char *p = PyBytes_AS_STRING(tag); | 
| Stefan Behnel | 4754168 | 2019-05-03 20:58:16 +0200 | [diff] [blame] | 1172 |         const Py_ssize_t len = PyBytes_GET_SIZE(tag); | 
 | 1173 |         if (len >= 3 && p[0] == '{' && ( | 
| Stefan Behnel | 6b95149 | 2019-05-06 17:36:35 +0200 | [diff] [blame^] | 1174 |                 p[1] == '}' || (p[1] == '*' && p[2] == '}'))) { | 
| Stefan Behnel | 4754168 | 2019-05-03 20:58:16 +0200 | [diff] [blame] | 1175 |             /* wildcard: '{}tag' or '{*}tag' */ | 
 | 1176 |             return 1; | 
 | 1177 |         } | 
 | 1178 |         for (i = 0; i < len; i++) { | 
| Fredrik Lundh | 8c8836b | 2005-12-16 22:06:06 +0000 | [diff] [blame] | 1179 |             if (p[i] == '{') | 
 | 1180 |                 check = 0; | 
 | 1181 |             else if (p[i] == '}') | 
 | 1182 |                 check = 1; | 
 | 1183 |             else if (check && PATHCHAR(p[i])) | 
 | 1184 |                 return 1; | 
 | 1185 |         } | 
 | 1186 |         return 0; | 
 | 1187 |     } | 
 | 1188 |  | 
 | 1189 |     return 1; /* unknown type; might be path expression */ | 
 | 1190 | } | 
 | 1191 |  | 
| Serhiy Storchaka | cb98556 | 2015-05-04 15:32:48 +0300 | [diff] [blame] | 1192 | /*[clinic input] | 
 | 1193 | _elementtree.Element.extend | 
 | 1194 |  | 
 | 1195 |     elements: object | 
 | 1196 |     / | 
 | 1197 |  | 
 | 1198 | [clinic start generated code]*/ | 
 | 1199 |  | 
 | 1200 | static PyObject * | 
 | 1201 | _elementtree_Element_extend(ElementObject *self, PyObject *elements) | 
 | 1202 | /*[clinic end generated code: output=f6e67fc2ff529191 input=807bc4f31c69f7c0]*/ | 
| Florent Xicluna | f15351d | 2010-03-13 23:24:31 +0000 | [diff] [blame] | 1203 | { | 
 | 1204 |     PyObject* seq; | 
| Serhiy Storchaka | 5bf3120 | 2015-05-18 18:29:33 +0300 | [diff] [blame] | 1205 |     Py_ssize_t i; | 
| Florent Xicluna | f15351d | 2010-03-13 23:24:31 +0000 | [diff] [blame] | 1206 |  | 
| Serhiy Storchaka | cb98556 | 2015-05-04 15:32:48 +0300 | [diff] [blame] | 1207 |     seq = PySequence_Fast(elements, ""); | 
| Florent Xicluna | f15351d | 2010-03-13 23:24:31 +0000 | [diff] [blame] | 1208 |     if (!seq) { | 
 | 1209 |         PyErr_Format( | 
 | 1210 |             PyExc_TypeError, | 
| Serhiy Storchaka | cb98556 | 2015-05-04 15:32:48 +0300 | [diff] [blame] | 1211 |             "expected sequence, not \"%.200s\"", Py_TYPE(elements)->tp_name | 
| Florent Xicluna | f15351d | 2010-03-13 23:24:31 +0000 | [diff] [blame] | 1212 |             ); | 
 | 1213 |         return NULL; | 
 | 1214 |     } | 
 | 1215 |  | 
| Serhiy Storchaka | 5bf3120 | 2015-05-18 18:29:33 +0300 | [diff] [blame] | 1216 |     for (i = 0; i < PySequence_Fast_GET_SIZE(seq); i++) { | 
| Florent Xicluna | f15351d | 2010-03-13 23:24:31 +0000 | [diff] [blame] | 1217 |         PyObject* element = PySequence_Fast_GET_ITEM(seq, i); | 
| Serhiy Storchaka | 5bf3120 | 2015-05-18 18:29:33 +0300 | [diff] [blame] | 1218 |         Py_INCREF(element); | 
| Florent Xicluna | f15351d | 2010-03-13 23:24:31 +0000 | [diff] [blame] | 1219 |         if (element_add_subelement(self, element) < 0) { | 
 | 1220 |             Py_DECREF(seq); | 
| Serhiy Storchaka | 5bf3120 | 2015-05-18 18:29:33 +0300 | [diff] [blame] | 1221 |             Py_DECREF(element); | 
| Florent Xicluna | f15351d | 2010-03-13 23:24:31 +0000 | [diff] [blame] | 1222 |             return NULL; | 
 | 1223 |         } | 
| Serhiy Storchaka | 5bf3120 | 2015-05-18 18:29:33 +0300 | [diff] [blame] | 1224 |         Py_DECREF(element); | 
| Florent Xicluna | f15351d | 2010-03-13 23:24:31 +0000 | [diff] [blame] | 1225 |     } | 
 | 1226 |  | 
 | 1227 |     Py_DECREF(seq); | 
 | 1228 |  | 
 | 1229 |     Py_RETURN_NONE; | 
 | 1230 | } | 
 | 1231 |  | 
| Serhiy Storchaka | cb98556 | 2015-05-04 15:32:48 +0300 | [diff] [blame] | 1232 | /*[clinic input] | 
 | 1233 | _elementtree.Element.find | 
 | 1234 |  | 
 | 1235 |     path: object | 
 | 1236 |     namespaces: object = None | 
 | 1237 |  | 
 | 1238 | [clinic start generated code]*/ | 
 | 1239 |  | 
 | 1240 | static PyObject * | 
 | 1241 | _elementtree_Element_find_impl(ElementObject *self, PyObject *path, | 
 | 1242 |                                PyObject *namespaces) | 
 | 1243 | /*[clinic end generated code: output=41b43f0f0becafae input=359b6985f6489d2e]*/ | 
| Fredrik Lundh | 8c8836b | 2005-12-16 22:06:06 +0000 | [diff] [blame] | 1244 | { | 
| Serhiy Storchaka | 26861b0 | 2015-02-16 20:52:17 +0200 | [diff] [blame] | 1245 |     Py_ssize_t i; | 
| Eli Bendersky | 532d03e | 2013-08-10 08:00:39 -0700 | [diff] [blame] | 1246 |     elementtreestate *st = ET_STATE_GLOBAL; | 
| Martin v. Löwis | afe55bb | 2011-10-09 10:38:36 +0200 | [diff] [blame] | 1247 |  | 
| Serhiy Storchaka | cb98556 | 2015-05-04 15:32:48 +0300 | [diff] [blame] | 1248 |     if (checkpath(path) || namespaces != Py_None) { | 
| Martin v. Löwis | bd928fe | 2011-10-14 10:20:37 +0200 | [diff] [blame] | 1249 |         _Py_IDENTIFIER(find); | 
| Victor Stinner | f561634 | 2016-12-09 15:26:00 +0100 | [diff] [blame] | 1250 |         return _PyObject_CallMethodIdObjArgs( | 
 | 1251 |             st->elementpath_obj, &PyId_find, self, path, namespaces, NULL | 
| Fredrik Lundh | 8c8836b | 2005-12-16 22:06:06 +0000 | [diff] [blame] | 1252 |             ); | 
| Martin v. Löwis | afe55bb | 2011-10-09 10:38:36 +0200 | [diff] [blame] | 1253 |     } | 
| Fredrik Lundh | 8c8836b | 2005-12-16 22:06:06 +0000 | [diff] [blame] | 1254 |  | 
 | 1255 |     if (!self->extra) | 
 | 1256 |         Py_RETURN_NONE; | 
| Victor Stinner | bfc7bf0 | 2011-03-21 13:23:42 +0100 | [diff] [blame] | 1257 |  | 
| Fredrik Lundh | 8c8836b | 2005-12-16 22:06:06 +0000 | [diff] [blame] | 1258 |     for (i = 0; i < self->extra->length; i++) { | 
 | 1259 |         PyObject* item = self->extra->children[i]; | 
| Serhiy Storchaka | 5bf3120 | 2015-05-18 18:29:33 +0300 | [diff] [blame] | 1260 |         int rc; | 
| Serhiy Storchaka | f081fd8 | 2018-10-19 12:12:57 +0300 | [diff] [blame] | 1261 |         assert(Element_Check(item)); | 
| Serhiy Storchaka | 5bf3120 | 2015-05-18 18:29:33 +0300 | [diff] [blame] | 1262 |         Py_INCREF(item); | 
| Serhiy Storchaka | a2c145c | 2015-05-18 18:33:31 +0300 | [diff] [blame] | 1263 |         rc = PyObject_RichCompareBool(((ElementObject*)item)->tag, path, Py_EQ); | 
| Serhiy Storchaka | 5bf3120 | 2015-05-18 18:29:33 +0300 | [diff] [blame] | 1264 |         if (rc > 0) | 
| Fredrik Lundh | 8c8836b | 2005-12-16 22:06:06 +0000 | [diff] [blame] | 1265 |             return item; | 
| Serhiy Storchaka | 5bf3120 | 2015-05-18 18:29:33 +0300 | [diff] [blame] | 1266 |         Py_DECREF(item); | 
 | 1267 |         if (rc < 0) | 
 | 1268 |             return NULL; | 
| Fredrik Lundh | 8c8836b | 2005-12-16 22:06:06 +0000 | [diff] [blame] | 1269 |     } | 
 | 1270 |  | 
 | 1271 |     Py_RETURN_NONE; | 
 | 1272 | } | 
 | 1273 |  | 
| Serhiy Storchaka | cb98556 | 2015-05-04 15:32:48 +0300 | [diff] [blame] | 1274 | /*[clinic input] | 
 | 1275 | _elementtree.Element.findtext | 
 | 1276 |  | 
 | 1277 |     path: object | 
 | 1278 |     default: object = None | 
 | 1279 |     namespaces: object = None | 
 | 1280 |  | 
 | 1281 | [clinic start generated code]*/ | 
 | 1282 |  | 
 | 1283 | static PyObject * | 
 | 1284 | _elementtree_Element_findtext_impl(ElementObject *self, PyObject *path, | 
 | 1285 |                                    PyObject *default_value, | 
 | 1286 |                                    PyObject *namespaces) | 
 | 1287 | /*[clinic end generated code: output=83b3ba4535d308d2 input=b53a85aa5aa2a916]*/ | 
| Fredrik Lundh | 8c8836b | 2005-12-16 22:06:06 +0000 | [diff] [blame] | 1288 | { | 
| Serhiy Storchaka | 26861b0 | 2015-02-16 20:52:17 +0200 | [diff] [blame] | 1289 |     Py_ssize_t i; | 
| Martin v. Löwis | bd928fe | 2011-10-14 10:20:37 +0200 | [diff] [blame] | 1290 |     _Py_IDENTIFIER(findtext); | 
| Eli Bendersky | 532d03e | 2013-08-10 08:00:39 -0700 | [diff] [blame] | 1291 |     elementtreestate *st = ET_STATE_GLOBAL; | 
| Martin v. Löwis | afe55bb | 2011-10-09 10:38:36 +0200 | [diff] [blame] | 1292 |  | 
| Serhiy Storchaka | cb98556 | 2015-05-04 15:32:48 +0300 | [diff] [blame] | 1293 |     if (checkpath(path) || namespaces != Py_None) | 
| Victor Stinner | f561634 | 2016-12-09 15:26:00 +0100 | [diff] [blame] | 1294 |         return _PyObject_CallMethodIdObjArgs( | 
 | 1295 |             st->elementpath_obj, &PyId_findtext, | 
 | 1296 |             self, path, default_value, namespaces, NULL | 
| Fredrik Lundh | 8c8836b | 2005-12-16 22:06:06 +0000 | [diff] [blame] | 1297 |             ); | 
 | 1298 |  | 
 | 1299 |     if (!self->extra) { | 
 | 1300 |         Py_INCREF(default_value); | 
 | 1301 |         return default_value; | 
 | 1302 |     } | 
 | 1303 |  | 
 | 1304 |     for (i = 0; i < self->extra->length; i++) { | 
| Serhiy Storchaka | b11c566 | 2018-10-14 10:32:19 +0300 | [diff] [blame] | 1305 |         PyObject *item = self->extra->children[i]; | 
| Serhiy Storchaka | 5bf3120 | 2015-05-18 18:29:33 +0300 | [diff] [blame] | 1306 |         int rc; | 
| Serhiy Storchaka | f081fd8 | 2018-10-19 12:12:57 +0300 | [diff] [blame] | 1307 |         assert(Element_Check(item)); | 
| Serhiy Storchaka | 5bf3120 | 2015-05-18 18:29:33 +0300 | [diff] [blame] | 1308 |         Py_INCREF(item); | 
| Serhiy Storchaka | b11c566 | 2018-10-14 10:32:19 +0300 | [diff] [blame] | 1309 |         rc = PyObject_RichCompareBool(((ElementObject*)item)->tag, path, Py_EQ); | 
| Serhiy Storchaka | 5bf3120 | 2015-05-18 18:29:33 +0300 | [diff] [blame] | 1310 |         if (rc > 0) { | 
| Serhiy Storchaka | b11c566 | 2018-10-14 10:32:19 +0300 | [diff] [blame] | 1311 |             PyObject* text = element_get_text((ElementObject*)item); | 
| Serhiy Storchaka | 5bf3120 | 2015-05-18 18:29:33 +0300 | [diff] [blame] | 1312 |             if (text == Py_None) { | 
 | 1313 |                 Py_DECREF(item); | 
| Eli Bendersky | 25771b3 | 2013-01-13 05:26:07 -0800 | [diff] [blame] | 1314 |                 return PyUnicode_New(0, 0); | 
| Serhiy Storchaka | 5bf3120 | 2015-05-18 18:29:33 +0300 | [diff] [blame] | 1315 |             } | 
| Thomas Wouters | 00ee7ba | 2006-08-21 19:07:27 +0000 | [diff] [blame] | 1316 |             Py_XINCREF(text); | 
| Serhiy Storchaka | 5bf3120 | 2015-05-18 18:29:33 +0300 | [diff] [blame] | 1317 |             Py_DECREF(item); | 
| Fredrik Lundh | 8c8836b | 2005-12-16 22:06:06 +0000 | [diff] [blame] | 1318 |             return text; | 
 | 1319 |         } | 
| Serhiy Storchaka | 5bf3120 | 2015-05-18 18:29:33 +0300 | [diff] [blame] | 1320 |         Py_DECREF(item); | 
 | 1321 |         if (rc < 0) | 
 | 1322 |             return NULL; | 
| Fredrik Lundh | 8c8836b | 2005-12-16 22:06:06 +0000 | [diff] [blame] | 1323 |     } | 
 | 1324 |  | 
 | 1325 |     Py_INCREF(default_value); | 
 | 1326 |     return default_value; | 
 | 1327 | } | 
 | 1328 |  | 
| Serhiy Storchaka | cb98556 | 2015-05-04 15:32:48 +0300 | [diff] [blame] | 1329 | /*[clinic input] | 
 | 1330 | _elementtree.Element.findall | 
 | 1331 |  | 
 | 1332 |     path: object | 
 | 1333 |     namespaces: object = None | 
 | 1334 |  | 
 | 1335 | [clinic start generated code]*/ | 
 | 1336 |  | 
 | 1337 | static PyObject * | 
 | 1338 | _elementtree_Element_findall_impl(ElementObject *self, PyObject *path, | 
 | 1339 |                                   PyObject *namespaces) | 
 | 1340 | /*[clinic end generated code: output=1a0bd9f5541b711d input=4d9e6505a638550c]*/ | 
| Fredrik Lundh | 8c8836b | 2005-12-16 22:06:06 +0000 | [diff] [blame] | 1341 | { | 
| Serhiy Storchaka | 26861b0 | 2015-02-16 20:52:17 +0200 | [diff] [blame] | 1342 |     Py_ssize_t i; | 
| Fredrik Lundh | 8c8836b | 2005-12-16 22:06:06 +0000 | [diff] [blame] | 1343 |     PyObject* out; | 
| Eli Bendersky | 532d03e | 2013-08-10 08:00:39 -0700 | [diff] [blame] | 1344 |     elementtreestate *st = ET_STATE_GLOBAL; | 
| Martin v. Löwis | afe55bb | 2011-10-09 10:38:36 +0200 | [diff] [blame] | 1345 |  | 
| Serhiy Storchaka | b11c566 | 2018-10-14 10:32:19 +0300 | [diff] [blame] | 1346 |     if (checkpath(path) || namespaces != Py_None) { | 
| Martin v. Löwis | bd928fe | 2011-10-14 10:20:37 +0200 | [diff] [blame] | 1347 |         _Py_IDENTIFIER(findall); | 
| Victor Stinner | f561634 | 2016-12-09 15:26:00 +0100 | [diff] [blame] | 1348 |         return _PyObject_CallMethodIdObjArgs( | 
| Serhiy Storchaka | b11c566 | 2018-10-14 10:32:19 +0300 | [diff] [blame] | 1349 |             st->elementpath_obj, &PyId_findall, self, path, namespaces, NULL | 
| Fredrik Lundh | 8c8836b | 2005-12-16 22:06:06 +0000 | [diff] [blame] | 1350 |             ); | 
| Martin v. Löwis | afe55bb | 2011-10-09 10:38:36 +0200 | [diff] [blame] | 1351 |     } | 
| Fredrik Lundh | 8c8836b | 2005-12-16 22:06:06 +0000 | [diff] [blame] | 1352 |  | 
 | 1353 |     out = PyList_New(0); | 
 | 1354 |     if (!out) | 
 | 1355 |         return NULL; | 
 | 1356 |  | 
 | 1357 |     if (!self->extra) | 
 | 1358 |         return out; | 
 | 1359 |  | 
 | 1360 |     for (i = 0; i < self->extra->length; i++) { | 
 | 1361 |         PyObject* item = self->extra->children[i]; | 
| Serhiy Storchaka | 5bf3120 | 2015-05-18 18:29:33 +0300 | [diff] [blame] | 1362 |         int rc; | 
| Serhiy Storchaka | f081fd8 | 2018-10-19 12:12:57 +0300 | [diff] [blame] | 1363 |         assert(Element_Check(item)); | 
| Serhiy Storchaka | 5bf3120 | 2015-05-18 18:29:33 +0300 | [diff] [blame] | 1364 |         Py_INCREF(item); | 
| Serhiy Storchaka | b11c566 | 2018-10-14 10:32:19 +0300 | [diff] [blame] | 1365 |         rc = PyObject_RichCompareBool(((ElementObject*)item)->tag, path, Py_EQ); | 
| Serhiy Storchaka | 5bf3120 | 2015-05-18 18:29:33 +0300 | [diff] [blame] | 1366 |         if (rc != 0 && (rc < 0 || PyList_Append(out, item) < 0)) { | 
 | 1367 |             Py_DECREF(item); | 
 | 1368 |             Py_DECREF(out); | 
 | 1369 |             return NULL; | 
| Fredrik Lundh | 8c8836b | 2005-12-16 22:06:06 +0000 | [diff] [blame] | 1370 |         } | 
| Serhiy Storchaka | 5bf3120 | 2015-05-18 18:29:33 +0300 | [diff] [blame] | 1371 |         Py_DECREF(item); | 
| Fredrik Lundh | 8c8836b | 2005-12-16 22:06:06 +0000 | [diff] [blame] | 1372 |     } | 
 | 1373 |  | 
 | 1374 |     return out; | 
 | 1375 | } | 
 | 1376 |  | 
| Serhiy Storchaka | cb98556 | 2015-05-04 15:32:48 +0300 | [diff] [blame] | 1377 | /*[clinic input] | 
 | 1378 | _elementtree.Element.iterfind | 
| Martin v. Löwis | afe55bb | 2011-10-09 10:38:36 +0200 | [diff] [blame] | 1379 |  | 
| Serhiy Storchaka | cb98556 | 2015-05-04 15:32:48 +0300 | [diff] [blame] | 1380 |     path: object | 
 | 1381 |     namespaces: object = None | 
 | 1382 |  | 
 | 1383 | [clinic start generated code]*/ | 
 | 1384 |  | 
 | 1385 | static PyObject * | 
 | 1386 | _elementtree_Element_iterfind_impl(ElementObject *self, PyObject *path, | 
 | 1387 |                                    PyObject *namespaces) | 
 | 1388 | /*[clinic end generated code: output=ecdd56d63b19d40f input=abb974e350fb65c7]*/ | 
 | 1389 | { | 
 | 1390 |     PyObject* tag = path; | 
 | 1391 |     _Py_IDENTIFIER(iterfind); | 
 | 1392 |     elementtreestate *st = ET_STATE_GLOBAL; | 
| Florent Xicluna | f15351d | 2010-03-13 23:24:31 +0000 | [diff] [blame] | 1393 |  | 
| Victor Stinner | f561634 | 2016-12-09 15:26:00 +0100 | [diff] [blame] | 1394 |     return _PyObject_CallMethodIdObjArgs( | 
 | 1395 |         st->elementpath_obj, &PyId_iterfind, self, tag, namespaces, NULL); | 
| Florent Xicluna | f15351d | 2010-03-13 23:24:31 +0000 | [diff] [blame] | 1396 | } | 
 | 1397 |  | 
| Serhiy Storchaka | cb98556 | 2015-05-04 15:32:48 +0300 | [diff] [blame] | 1398 | /*[clinic input] | 
 | 1399 | _elementtree.Element.get | 
 | 1400 |  | 
 | 1401 |     key: object | 
 | 1402 |     default: object = None | 
 | 1403 |  | 
 | 1404 | [clinic start generated code]*/ | 
 | 1405 |  | 
 | 1406 | static PyObject * | 
 | 1407 | _elementtree_Element_get_impl(ElementObject *self, PyObject *key, | 
 | 1408 |                               PyObject *default_value) | 
 | 1409 | /*[clinic end generated code: output=523c614142595d75 input=ee153bbf8cdb246e]*/ | 
| Fredrik Lundh | 8c8836b | 2005-12-16 22:06:06 +0000 | [diff] [blame] | 1410 | { | 
 | 1411 |     PyObject* value; | 
| Fredrik Lundh | 8c8836b | 2005-12-16 22:06:06 +0000 | [diff] [blame] | 1412 |  | 
 | 1413 |     if (!self->extra || self->extra->attrib == Py_None) | 
 | 1414 |         value = default_value; | 
 | 1415 |     else { | 
| Serhiy Storchaka | a24107b | 2019-02-25 17:59:46 +0200 | [diff] [blame] | 1416 |         value = PyDict_GetItemWithError(self->extra->attrib, key); | 
 | 1417 |         if (!value) { | 
 | 1418 |             if (PyErr_Occurred()) { | 
 | 1419 |                 return NULL; | 
 | 1420 |             } | 
| Fredrik Lundh | 8c8836b | 2005-12-16 22:06:06 +0000 | [diff] [blame] | 1421 |             value = default_value; | 
| Serhiy Storchaka | a24107b | 2019-02-25 17:59:46 +0200 | [diff] [blame] | 1422 |         } | 
| Fredrik Lundh | 8c8836b | 2005-12-16 22:06:06 +0000 | [diff] [blame] | 1423 |     } | 
 | 1424 |  | 
 | 1425 |     Py_INCREF(value); | 
 | 1426 |     return value; | 
 | 1427 | } | 
 | 1428 |  | 
| Serhiy Storchaka | cb98556 | 2015-05-04 15:32:48 +0300 | [diff] [blame] | 1429 | /*[clinic input] | 
 | 1430 | _elementtree.Element.getchildren | 
 | 1431 |  | 
 | 1432 | [clinic start generated code]*/ | 
 | 1433 |  | 
 | 1434 | static PyObject * | 
 | 1435 | _elementtree_Element_getchildren_impl(ElementObject *self) | 
 | 1436 | /*[clinic end generated code: output=e50ffe118637b14f input=0f754dfded150d5f]*/ | 
| Fredrik Lundh | 8c8836b | 2005-12-16 22:06:06 +0000 | [diff] [blame] | 1437 | { | 
| Serhiy Storchaka | 26861b0 | 2015-02-16 20:52:17 +0200 | [diff] [blame] | 1438 |     Py_ssize_t i; | 
| Fredrik Lundh | 8c8836b | 2005-12-16 22:06:06 +0000 | [diff] [blame] | 1439 |     PyObject* list; | 
 | 1440 |  | 
| Serhiy Storchaka | 762ec97 | 2017-03-30 18:12:06 +0300 | [diff] [blame] | 1441 |     if (PyErr_WarnEx(PyExc_DeprecationWarning, | 
 | 1442 |                      "This method will be removed in future versions.  " | 
 | 1443 |                      "Use 'list(elem)' or iteration over elem instead.", | 
 | 1444 |                      1) < 0) { | 
 | 1445 |         return NULL; | 
 | 1446 |     } | 
| Florent Xicluna | f15351d | 2010-03-13 23:24:31 +0000 | [diff] [blame] | 1447 |  | 
| Fredrik Lundh | 8c8836b | 2005-12-16 22:06:06 +0000 | [diff] [blame] | 1448 |     if (!self->extra) | 
 | 1449 |         return PyList_New(0); | 
 | 1450 |  | 
 | 1451 |     list = PyList_New(self->extra->length); | 
 | 1452 |     if (!list) | 
 | 1453 |         return NULL; | 
 | 1454 |  | 
 | 1455 |     for (i = 0; i < self->extra->length; i++) { | 
 | 1456 |         PyObject* item = self->extra->children[i]; | 
 | 1457 |         Py_INCREF(item); | 
 | 1458 |         PyList_SET_ITEM(list, i, item); | 
 | 1459 |     } | 
 | 1460 |  | 
 | 1461 |     return list; | 
 | 1462 | } | 
 | 1463 |  | 
| Victor Stinner | bfc7bf0 | 2011-03-21 13:23:42 +0100 | [diff] [blame] | 1464 |  | 
| Eli Bendersky | 64d11e6 | 2012-06-15 07:42:50 +0300 | [diff] [blame] | 1465 | static PyObject * | 
 | 1466 | create_elementiter(ElementObject *self, PyObject *tag, int gettext); | 
 | 1467 |  | 
 | 1468 |  | 
| Serhiy Storchaka | cb98556 | 2015-05-04 15:32:48 +0300 | [diff] [blame] | 1469 | /*[clinic input] | 
 | 1470 | _elementtree.Element.iter | 
 | 1471 |  | 
 | 1472 |     tag: object = None | 
 | 1473 |  | 
 | 1474 | [clinic start generated code]*/ | 
 | 1475 |  | 
| Eli Bendersky | 64d11e6 | 2012-06-15 07:42:50 +0300 | [diff] [blame] | 1476 | static PyObject * | 
| Serhiy Storchaka | cb98556 | 2015-05-04 15:32:48 +0300 | [diff] [blame] | 1477 | _elementtree_Element_iter_impl(ElementObject *self, PyObject *tag) | 
 | 1478 | /*[clinic end generated code: output=3f49f9a862941cc5 input=774d5b12e573aedd]*/ | 
| Eli Bendersky | 64d11e6 | 2012-06-15 07:42:50 +0300 | [diff] [blame] | 1479 | { | 
| Serhiy Storchaka | d6a69d8 | 2015-12-09 11:27:07 +0200 | [diff] [blame] | 1480 |     if (PyUnicode_Check(tag)) { | 
 | 1481 |         if (PyUnicode_READY(tag) < 0) | 
 | 1482 |             return NULL; | 
 | 1483 |         if (PyUnicode_GET_LENGTH(tag) == 1 && PyUnicode_READ_CHAR(tag, 0) == '*') | 
 | 1484 |             tag = Py_None; | 
 | 1485 |     } | 
 | 1486 |     else if (PyBytes_Check(tag)) { | 
 | 1487 |         if (PyBytes_GET_SIZE(tag) == 1 && *PyBytes_AS_STRING(tag) == '*') | 
 | 1488 |             tag = Py_None; | 
 | 1489 |     } | 
 | 1490 |  | 
| Eli Bendersky | 64d11e6 | 2012-06-15 07:42:50 +0300 | [diff] [blame] | 1491 |     return create_elementiter(self, tag, 0); | 
| Florent Xicluna | f15351d | 2010-03-13 23:24:31 +0000 | [diff] [blame] | 1492 | } | 
 | 1493 |  | 
 | 1494 |  | 
| Serhiy Storchaka | cb98556 | 2015-05-04 15:32:48 +0300 | [diff] [blame] | 1495 | /*[clinic input] | 
| Serhiy Storchaka | 762ec97 | 2017-03-30 18:12:06 +0300 | [diff] [blame] | 1496 | _elementtree.Element.getiterator | 
 | 1497 |  | 
 | 1498 |     tag: object = None | 
 | 1499 |  | 
 | 1500 | [clinic start generated code]*/ | 
 | 1501 |  | 
 | 1502 | static PyObject * | 
 | 1503 | _elementtree_Element_getiterator_impl(ElementObject *self, PyObject *tag) | 
 | 1504 | /*[clinic end generated code: output=cb69ff4a3742dfa1 input=500da1a03f7b9e28]*/ | 
 | 1505 | { | 
| Serhiy Storchaka | 02ec92f | 2018-07-24 12:03:34 +0300 | [diff] [blame] | 1506 |     if (PyErr_WarnEx(PyExc_DeprecationWarning, | 
| Serhiy Storchaka | 762ec97 | 2017-03-30 18:12:06 +0300 | [diff] [blame] | 1507 |                      "This method will be removed in future versions.  " | 
 | 1508 |                      "Use 'tree.iter()' or 'list(tree.iter())' instead.", | 
 | 1509 |                      1) < 0) { | 
 | 1510 |         return NULL; | 
 | 1511 |     } | 
 | 1512 |     return _elementtree_Element_iter_impl(self, tag); | 
 | 1513 | } | 
 | 1514 |  | 
 | 1515 |  | 
 | 1516 | /*[clinic input] | 
| Serhiy Storchaka | cb98556 | 2015-05-04 15:32:48 +0300 | [diff] [blame] | 1517 | _elementtree.Element.itertext | 
| Florent Xicluna | f15351d | 2010-03-13 23:24:31 +0000 | [diff] [blame] | 1518 |  | 
| Serhiy Storchaka | cb98556 | 2015-05-04 15:32:48 +0300 | [diff] [blame] | 1519 | [clinic start generated code]*/ | 
 | 1520 |  | 
 | 1521 | static PyObject * | 
 | 1522 | _elementtree_Element_itertext_impl(ElementObject *self) | 
 | 1523 | /*[clinic end generated code: output=5fa34b2fbcb65df6 input=af8f0e42cb239c89]*/ | 
 | 1524 | { | 
| Eli Bendersky | 64d11e6 | 2012-06-15 07:42:50 +0300 | [diff] [blame] | 1525 |     return create_elementiter(self, Py_None, 1); | 
| Fredrik Lundh | 8c8836b | 2005-12-16 22:06:06 +0000 | [diff] [blame] | 1526 | } | 
 | 1527 |  | 
| Eli Bendersky | 64d11e6 | 2012-06-15 07:42:50 +0300 | [diff] [blame] | 1528 |  | 
| Fredrik Lundh | 8c8836b | 2005-12-16 22:06:06 +0000 | [diff] [blame] | 1529 | static PyObject* | 
| Fredrik Lundh | 44ed4db | 2006-03-12 21:06:35 +0000 | [diff] [blame] | 1530 | element_getitem(PyObject* self_, Py_ssize_t index) | 
| Fredrik Lundh | 8c8836b | 2005-12-16 22:06:06 +0000 | [diff] [blame] | 1531 | { | 
| Fredrik Lundh | 44ed4db | 2006-03-12 21:06:35 +0000 | [diff] [blame] | 1532 |     ElementObject* self = (ElementObject*) self_; | 
 | 1533 |  | 
| Fredrik Lundh | 8c8836b | 2005-12-16 22:06:06 +0000 | [diff] [blame] | 1534 |     if (!self->extra || index < 0 || index >= self->extra->length) { | 
 | 1535 |         PyErr_SetString( | 
 | 1536 |             PyExc_IndexError, | 
 | 1537 |             "child index out of range" | 
 | 1538 |             ); | 
 | 1539 |         return NULL; | 
 | 1540 |     } | 
 | 1541 |  | 
 | 1542 |     Py_INCREF(self->extra->children[index]); | 
 | 1543 |     return self->extra->children[index]; | 
 | 1544 | } | 
 | 1545 |  | 
| Serhiy Storchaka | cb98556 | 2015-05-04 15:32:48 +0300 | [diff] [blame] | 1546 | /*[clinic input] | 
 | 1547 | _elementtree.Element.insert | 
 | 1548 |  | 
 | 1549 |     index: Py_ssize_t | 
 | 1550 |     subelement: object(subclass_of='&Element_Type') | 
 | 1551 |     / | 
 | 1552 |  | 
 | 1553 | [clinic start generated code]*/ | 
 | 1554 |  | 
 | 1555 | static PyObject * | 
 | 1556 | _elementtree_Element_insert_impl(ElementObject *self, Py_ssize_t index, | 
 | 1557 |                                  PyObject *subelement) | 
 | 1558 | /*[clinic end generated code: output=990adfef4d424c0b input=cd6fbfcdab52d7a8]*/ | 
| Fredrik Lundh | 8c8836b | 2005-12-16 22:06:06 +0000 | [diff] [blame] | 1559 | { | 
| Serhiy Storchaka | cb98556 | 2015-05-04 15:32:48 +0300 | [diff] [blame] | 1560 |     Py_ssize_t i; | 
| Fredrik Lundh | 8c8836b | 2005-12-16 22:06:06 +0000 | [diff] [blame] | 1561 |  | 
| Victor Stinner | 5f0af23 | 2013-07-11 23:01:36 +0200 | [diff] [blame] | 1562 |     if (!self->extra) { | 
 | 1563 |         if (create_extra(self, NULL) < 0) | 
 | 1564 |             return NULL; | 
 | 1565 |     } | 
| Fredrik Lundh | 8c8836b | 2005-12-16 22:06:06 +0000 | [diff] [blame] | 1566 |  | 
| Florent Xicluna | f15351d | 2010-03-13 23:24:31 +0000 | [diff] [blame] | 1567 |     if (index < 0) { | 
 | 1568 |         index += self->extra->length; | 
 | 1569 |         if (index < 0) | 
 | 1570 |             index = 0; | 
 | 1571 |     } | 
| Fredrik Lundh | 8c8836b | 2005-12-16 22:06:06 +0000 | [diff] [blame] | 1572 |     if (index > self->extra->length) | 
 | 1573 |         index = self->extra->length; | 
 | 1574 |  | 
 | 1575 |     if (element_resize(self, 1) < 0) | 
 | 1576 |         return NULL; | 
 | 1577 |  | 
 | 1578 |     for (i = self->extra->length; i > index; i--) | 
 | 1579 |         self->extra->children[i] = self->extra->children[i-1]; | 
 | 1580 |  | 
| Serhiy Storchaka | cb98556 | 2015-05-04 15:32:48 +0300 | [diff] [blame] | 1581 |     Py_INCREF(subelement); | 
 | 1582 |     self->extra->children[index] = subelement; | 
| Fredrik Lundh | 8c8836b | 2005-12-16 22:06:06 +0000 | [diff] [blame] | 1583 |  | 
 | 1584 |     self->extra->length++; | 
 | 1585 |  | 
 | 1586 |     Py_RETURN_NONE; | 
 | 1587 | } | 
 | 1588 |  | 
| Serhiy Storchaka | cb98556 | 2015-05-04 15:32:48 +0300 | [diff] [blame] | 1589 | /*[clinic input] | 
 | 1590 | _elementtree.Element.items | 
| Fredrik Lundh | 8c8836b | 2005-12-16 22:06:06 +0000 | [diff] [blame] | 1591 |  | 
| Serhiy Storchaka | cb98556 | 2015-05-04 15:32:48 +0300 | [diff] [blame] | 1592 | [clinic start generated code]*/ | 
 | 1593 |  | 
 | 1594 | static PyObject * | 
 | 1595 | _elementtree_Element_items_impl(ElementObject *self) | 
 | 1596 | /*[clinic end generated code: output=6db2c778ce3f5a4d input=adbe09aaea474447]*/ | 
 | 1597 | { | 
| Fredrik Lundh | 8c8836b | 2005-12-16 22:06:06 +0000 | [diff] [blame] | 1598 |     if (!self->extra || self->extra->attrib == Py_None) | 
 | 1599 |         return PyList_New(0); | 
 | 1600 |  | 
 | 1601 |     return PyDict_Items(self->extra->attrib); | 
 | 1602 | } | 
 | 1603 |  | 
| Serhiy Storchaka | cb98556 | 2015-05-04 15:32:48 +0300 | [diff] [blame] | 1604 | /*[clinic input] | 
 | 1605 | _elementtree.Element.keys | 
| Fredrik Lundh | 8c8836b | 2005-12-16 22:06:06 +0000 | [diff] [blame] | 1606 |  | 
| Serhiy Storchaka | cb98556 | 2015-05-04 15:32:48 +0300 | [diff] [blame] | 1607 | [clinic start generated code]*/ | 
 | 1608 |  | 
 | 1609 | static PyObject * | 
 | 1610 | _elementtree_Element_keys_impl(ElementObject *self) | 
 | 1611 | /*[clinic end generated code: output=bc5bfabbf20eeb3c input=f02caf5b496b5b0b]*/ | 
 | 1612 | { | 
| Fredrik Lundh | 8c8836b | 2005-12-16 22:06:06 +0000 | [diff] [blame] | 1613 |     if (!self->extra || self->extra->attrib == Py_None) | 
 | 1614 |         return PyList_New(0); | 
 | 1615 |  | 
 | 1616 |     return PyDict_Keys(self->extra->attrib); | 
 | 1617 | } | 
 | 1618 |  | 
| Martin v. Löwis | 18e1655 | 2006-02-15 17:27:45 +0000 | [diff] [blame] | 1619 | static Py_ssize_t | 
| Fredrik Lundh | 8c8836b | 2005-12-16 22:06:06 +0000 | [diff] [blame] | 1620 | element_length(ElementObject* self) | 
 | 1621 | { | 
 | 1622 |     if (!self->extra) | 
 | 1623 |         return 0; | 
 | 1624 |  | 
 | 1625 |     return self->extra->length; | 
 | 1626 | } | 
 | 1627 |  | 
| Serhiy Storchaka | cb98556 | 2015-05-04 15:32:48 +0300 | [diff] [blame] | 1628 | /*[clinic input] | 
 | 1629 | _elementtree.Element.makeelement | 
 | 1630 |  | 
 | 1631 |     tag: object | 
 | 1632 |     attrib: object | 
 | 1633 |     / | 
 | 1634 |  | 
 | 1635 | [clinic start generated code]*/ | 
 | 1636 |  | 
 | 1637 | static PyObject * | 
 | 1638 | _elementtree_Element_makeelement_impl(ElementObject *self, PyObject *tag, | 
 | 1639 |                                       PyObject *attrib) | 
 | 1640 | /*[clinic end generated code: output=4109832d5bb789ef input=9480d1d2e3e68235]*/ | 
| Fredrik Lundh | 8c8836b | 2005-12-16 22:06:06 +0000 | [diff] [blame] | 1641 | { | 
 | 1642 |     PyObject* elem; | 
 | 1643 |  | 
| Fredrik Lundh | 8c8836b | 2005-12-16 22:06:06 +0000 | [diff] [blame] | 1644 |     attrib = PyDict_Copy(attrib); | 
 | 1645 |     if (!attrib) | 
 | 1646 |         return NULL; | 
 | 1647 |  | 
| Eli Bendersky | 092af1f | 2012-03-04 07:14:03 +0200 | [diff] [blame] | 1648 |     elem = create_new_element(tag, attrib); | 
| Fredrik Lundh | 8c8836b | 2005-12-16 22:06:06 +0000 | [diff] [blame] | 1649 |  | 
 | 1650 |     Py_DECREF(attrib); | 
 | 1651 |  | 
 | 1652 |     return elem; | 
 | 1653 | } | 
 | 1654 |  | 
| Serhiy Storchaka | cb98556 | 2015-05-04 15:32:48 +0300 | [diff] [blame] | 1655 | /*[clinic input] | 
 | 1656 | _elementtree.Element.remove | 
 | 1657 |  | 
 | 1658 |     subelement: object(subclass_of='&Element_Type') | 
 | 1659 |     / | 
 | 1660 |  | 
 | 1661 | [clinic start generated code]*/ | 
 | 1662 |  | 
 | 1663 | static PyObject * | 
 | 1664 | _elementtree_Element_remove_impl(ElementObject *self, PyObject *subelement) | 
 | 1665 | /*[clinic end generated code: output=38fe6c07d6d87d1f input=d52fc28ededc0bd8]*/ | 
| Fredrik Lundh | 8c8836b | 2005-12-16 22:06:06 +0000 | [diff] [blame] | 1666 | { | 
| Serhiy Storchaka | 26861b0 | 2015-02-16 20:52:17 +0200 | [diff] [blame] | 1667 |     Py_ssize_t i; | 
| Serhiy Storchaka | a2c145c | 2015-05-18 18:33:31 +0300 | [diff] [blame] | 1668 |     int rc; | 
 | 1669 |     PyObject *found; | 
| Fredrik Lundh | 8c8836b | 2005-12-16 22:06:06 +0000 | [diff] [blame] | 1670 |  | 
| Fredrik Lundh | 8c8836b | 2005-12-16 22:06:06 +0000 | [diff] [blame] | 1671 |     if (!self->extra) { | 
 | 1672 |         /* element has no children, so raise exception */ | 
 | 1673 |         PyErr_SetString( | 
 | 1674 |             PyExc_ValueError, | 
 | 1675 |             "list.remove(x): x not in list" | 
 | 1676 |             ); | 
 | 1677 |         return NULL; | 
 | 1678 |     } | 
 | 1679 |  | 
 | 1680 |     for (i = 0; i < self->extra->length; i++) { | 
| Serhiy Storchaka | cb98556 | 2015-05-04 15:32:48 +0300 | [diff] [blame] | 1681 |         if (self->extra->children[i] == subelement) | 
| Fredrik Lundh | 8c8836b | 2005-12-16 22:06:06 +0000 | [diff] [blame] | 1682 |             break; | 
| Serhiy Storchaka | a2c145c | 2015-05-18 18:33:31 +0300 | [diff] [blame] | 1683 |         rc = PyObject_RichCompareBool(self->extra->children[i], subelement, Py_EQ); | 
| Serhiy Storchaka | 5bf3120 | 2015-05-18 18:29:33 +0300 | [diff] [blame] | 1684 |         if (rc > 0) | 
| Fredrik Lundh | 8c8836b | 2005-12-16 22:06:06 +0000 | [diff] [blame] | 1685 |             break; | 
| Serhiy Storchaka | 5bf3120 | 2015-05-18 18:29:33 +0300 | [diff] [blame] | 1686 |         if (rc < 0) | 
 | 1687 |             return NULL; | 
| Fredrik Lundh | 8c8836b | 2005-12-16 22:06:06 +0000 | [diff] [blame] | 1688 |     } | 
 | 1689 |  | 
| Serhiy Storchaka | 5bf3120 | 2015-05-18 18:29:33 +0300 | [diff] [blame] | 1690 |     if (i >= self->extra->length) { | 
| Serhiy Storchaka | cb98556 | 2015-05-04 15:32:48 +0300 | [diff] [blame] | 1691 |         /* subelement is not in children, so raise exception */ | 
| Fredrik Lundh | 8c8836b | 2005-12-16 22:06:06 +0000 | [diff] [blame] | 1692 |         PyErr_SetString( | 
 | 1693 |             PyExc_ValueError, | 
 | 1694 |             "list.remove(x): x not in list" | 
 | 1695 |             ); | 
 | 1696 |         return NULL; | 
 | 1697 |     } | 
 | 1698 |  | 
| Serhiy Storchaka | 5bf3120 | 2015-05-18 18:29:33 +0300 | [diff] [blame] | 1699 |     found = self->extra->children[i]; | 
| Fredrik Lundh | 8c8836b | 2005-12-16 22:06:06 +0000 | [diff] [blame] | 1700 |  | 
 | 1701 |     self->extra->length--; | 
| Fredrik Lundh | 8c8836b | 2005-12-16 22:06:06 +0000 | [diff] [blame] | 1702 |     for (; i < self->extra->length; i++) | 
 | 1703 |         self->extra->children[i] = self->extra->children[i+1]; | 
 | 1704 |  | 
| Serhiy Storchaka | 5bf3120 | 2015-05-18 18:29:33 +0300 | [diff] [blame] | 1705 |     Py_DECREF(found); | 
| Fredrik Lundh | 8c8836b | 2005-12-16 22:06:06 +0000 | [diff] [blame] | 1706 |     Py_RETURN_NONE; | 
 | 1707 | } | 
 | 1708 |  | 
 | 1709 | static PyObject* | 
 | 1710 | element_repr(ElementObject* self) | 
 | 1711 | { | 
| Serhiy Storchaka | 9062c26 | 2016-06-12 09:43:55 +0300 | [diff] [blame] | 1712 |     int status; | 
 | 1713 |  | 
 | 1714 |     if (self->tag == NULL) | 
| Eli Bendersky | 092af1f | 2012-03-04 07:14:03 +0200 | [diff] [blame] | 1715 |         return PyUnicode_FromFormat("<Element at %p>", self); | 
| Serhiy Storchaka | 9062c26 | 2016-06-12 09:43:55 +0300 | [diff] [blame] | 1716 |  | 
 | 1717 |     status = Py_ReprEnter((PyObject *)self); | 
 | 1718 |     if (status == 0) { | 
 | 1719 |         PyObject *res; | 
 | 1720 |         res = PyUnicode_FromFormat("<Element %R at %p>", self->tag, self); | 
 | 1721 |         Py_ReprLeave((PyObject *)self); | 
 | 1722 |         return res; | 
 | 1723 |     } | 
 | 1724 |     if (status > 0) | 
 | 1725 |         PyErr_Format(PyExc_RuntimeError, | 
 | 1726 |                      "reentrant call inside %s.__repr__", | 
 | 1727 |                      Py_TYPE(self)->tp_name); | 
 | 1728 |     return NULL; | 
| Fredrik Lundh | 8c8836b | 2005-12-16 22:06:06 +0000 | [diff] [blame] | 1729 | } | 
 | 1730 |  | 
| Serhiy Storchaka | cb98556 | 2015-05-04 15:32:48 +0300 | [diff] [blame] | 1731 | /*[clinic input] | 
 | 1732 | _elementtree.Element.set | 
 | 1733 |  | 
 | 1734 |     key: object | 
 | 1735 |     value: object | 
 | 1736 |     / | 
 | 1737 |  | 
 | 1738 | [clinic start generated code]*/ | 
 | 1739 |  | 
 | 1740 | static PyObject * | 
 | 1741 | _elementtree_Element_set_impl(ElementObject *self, PyObject *key, | 
 | 1742 |                               PyObject *value) | 
 | 1743 | /*[clinic end generated code: output=fb938806be3c5656 input=1efe90f7d82b3fe9]*/ | 
| Fredrik Lundh | 8c8836b | 2005-12-16 22:06:06 +0000 | [diff] [blame] | 1744 | { | 
 | 1745 |     PyObject* attrib; | 
 | 1746 |  | 
| Victor Stinner | 5f0af23 | 2013-07-11 23:01:36 +0200 | [diff] [blame] | 1747 |     if (!self->extra) { | 
 | 1748 |         if (create_extra(self, NULL) < 0) | 
 | 1749 |             return NULL; | 
 | 1750 |     } | 
| Fredrik Lundh | 8c8836b | 2005-12-16 22:06:06 +0000 | [diff] [blame] | 1751 |  | 
 | 1752 |     attrib = element_get_attrib(self); | 
 | 1753 |     if (!attrib) | 
 | 1754 |         return NULL; | 
 | 1755 |  | 
 | 1756 |     if (PyDict_SetItem(attrib, key, value) < 0) | 
 | 1757 |         return NULL; | 
 | 1758 |  | 
 | 1759 |     Py_RETURN_NONE; | 
 | 1760 | } | 
 | 1761 |  | 
 | 1762 | static int | 
| Fredrik Lundh | 44ed4db | 2006-03-12 21:06:35 +0000 | [diff] [blame] | 1763 | element_setitem(PyObject* self_, Py_ssize_t index, PyObject* item) | 
| Fredrik Lundh | 8c8836b | 2005-12-16 22:06:06 +0000 | [diff] [blame] | 1764 | { | 
| Fredrik Lundh | 44ed4db | 2006-03-12 21:06:35 +0000 | [diff] [blame] | 1765 |     ElementObject* self = (ElementObject*) self_; | 
| Serhiy Storchaka | 26861b0 | 2015-02-16 20:52:17 +0200 | [diff] [blame] | 1766 |     Py_ssize_t i; | 
| Fredrik Lundh | 8c8836b | 2005-12-16 22:06:06 +0000 | [diff] [blame] | 1767 |     PyObject* old; | 
 | 1768 |  | 
 | 1769 |     if (!self->extra || index < 0 || index >= self->extra->length) { | 
 | 1770 |         PyErr_SetString( | 
 | 1771 |             PyExc_IndexError, | 
 | 1772 |             "child assignment index out of range"); | 
 | 1773 |         return -1; | 
 | 1774 |     } | 
 | 1775 |  | 
 | 1776 |     old = self->extra->children[index]; | 
 | 1777 |  | 
 | 1778 |     if (item) { | 
| Serhiy Storchaka | f081fd8 | 2018-10-19 12:12:57 +0300 | [diff] [blame] | 1779 |         if (!Element_Check(item)) { | 
 | 1780 |             raise_type_error(item); | 
 | 1781 |             return -1; | 
 | 1782 |         } | 
| Fredrik Lundh | 8c8836b | 2005-12-16 22:06:06 +0000 | [diff] [blame] | 1783 |         Py_INCREF(item); | 
 | 1784 |         self->extra->children[index] = item; | 
 | 1785 |     } else { | 
 | 1786 |         self->extra->length--; | 
 | 1787 |         for (i = index; i < self->extra->length; i++) | 
 | 1788 |             self->extra->children[i] = self->extra->children[i+1]; | 
 | 1789 |     } | 
 | 1790 |  | 
 | 1791 |     Py_DECREF(old); | 
 | 1792 |  | 
 | 1793 |     return 0; | 
 | 1794 | } | 
 | 1795 |  | 
| Florent Xicluna | f15351d | 2010-03-13 23:24:31 +0000 | [diff] [blame] | 1796 | static PyObject* | 
 | 1797 | element_subscr(PyObject* self_, PyObject* item) | 
 | 1798 | { | 
 | 1799 |     ElementObject* self = (ElementObject*) self_; | 
 | 1800 |  | 
| Florent Xicluna | f15351d | 2010-03-13 23:24:31 +0000 | [diff] [blame] | 1801 |     if (PyIndex_Check(item)) { | 
 | 1802 |         Py_ssize_t i = PyNumber_AsSsize_t(item, PyExc_IndexError); | 
| Florent Xicluna | f15351d | 2010-03-13 23:24:31 +0000 | [diff] [blame] | 1803 |  | 
 | 1804 |         if (i == -1 && PyErr_Occurred()) { | 
 | 1805 |             return NULL; | 
 | 1806 |         } | 
 | 1807 |         if (i < 0 && self->extra) | 
 | 1808 |             i += self->extra->length; | 
 | 1809 |         return element_getitem(self_, i); | 
 | 1810 |     } | 
 | 1811 |     else if (PySlice_Check(item)) { | 
 | 1812 |         Py_ssize_t start, stop, step, slicelen, cur, i; | 
 | 1813 |         PyObject* list; | 
 | 1814 |  | 
 | 1815 |         if (!self->extra) | 
 | 1816 |             return PyList_New(0); | 
 | 1817 |  | 
| Serhiy Storchaka | b879fe8 | 2017-04-08 09:53:51 +0300 | [diff] [blame] | 1818 |         if (PySlice_Unpack(item, &start, &stop, &step) < 0) { | 
| Florent Xicluna | f15351d | 2010-03-13 23:24:31 +0000 | [diff] [blame] | 1819 |             return NULL; | 
 | 1820 |         } | 
| Serhiy Storchaka | b879fe8 | 2017-04-08 09:53:51 +0300 | [diff] [blame] | 1821 |         slicelen = PySlice_AdjustIndices(self->extra->length, &start, &stop, | 
 | 1822 |                                          step); | 
| Florent Xicluna | f15351d | 2010-03-13 23:24:31 +0000 | [diff] [blame] | 1823 |  | 
 | 1824 |         if (slicelen <= 0) | 
 | 1825 |             return PyList_New(0); | 
 | 1826 |         else { | 
 | 1827 |             list = PyList_New(slicelen); | 
 | 1828 |             if (!list) | 
 | 1829 |                 return NULL; | 
 | 1830 |  | 
 | 1831 |             for (cur = start, i = 0; i < slicelen; | 
 | 1832 |                  cur += step, i++) { | 
 | 1833 |                 PyObject* item = self->extra->children[cur]; | 
 | 1834 |                 Py_INCREF(item); | 
 | 1835 |                 PyList_SET_ITEM(list, i, item); | 
 | 1836 |             } | 
 | 1837 |  | 
 | 1838 |             return list; | 
 | 1839 |         } | 
 | 1840 |     } | 
 | 1841 |     else { | 
 | 1842 |         PyErr_SetString(PyExc_TypeError, | 
 | 1843 |                 "element indices must be integers"); | 
 | 1844 |         return NULL; | 
 | 1845 |     } | 
 | 1846 | } | 
 | 1847 |  | 
 | 1848 | static int | 
 | 1849 | element_ass_subscr(PyObject* self_, PyObject* item, PyObject* value) | 
 | 1850 | { | 
 | 1851 |     ElementObject* self = (ElementObject*) self_; | 
 | 1852 |  | 
| Florent Xicluna | f15351d | 2010-03-13 23:24:31 +0000 | [diff] [blame] | 1853 |     if (PyIndex_Check(item)) { | 
 | 1854 |         Py_ssize_t i = PyNumber_AsSsize_t(item, PyExc_IndexError); | 
| Florent Xicluna | f15351d | 2010-03-13 23:24:31 +0000 | [diff] [blame] | 1855 |  | 
 | 1856 |         if (i == -1 && PyErr_Occurred()) { | 
 | 1857 |             return -1; | 
 | 1858 |         } | 
 | 1859 |         if (i < 0 && self->extra) | 
 | 1860 |             i += self->extra->length; | 
 | 1861 |         return element_setitem(self_, i, value); | 
 | 1862 |     } | 
 | 1863 |     else if (PySlice_Check(item)) { | 
 | 1864 |         Py_ssize_t start, stop, step, slicelen, newlen, cur, i; | 
 | 1865 |  | 
 | 1866 |         PyObject* recycle = NULL; | 
| Serhiy Storchaka | 04d759b | 2015-11-22 12:18:38 +0200 | [diff] [blame] | 1867 |         PyObject* seq; | 
| Florent Xicluna | f15351d | 2010-03-13 23:24:31 +0000 | [diff] [blame] | 1868 |  | 
| Victor Stinner | 5f0af23 | 2013-07-11 23:01:36 +0200 | [diff] [blame] | 1869 |         if (!self->extra) { | 
 | 1870 |             if (create_extra(self, NULL) < 0) | 
 | 1871 |                 return -1; | 
 | 1872 |         } | 
| Florent Xicluna | f15351d | 2010-03-13 23:24:31 +0000 | [diff] [blame] | 1873 |  | 
| Serhiy Storchaka | b879fe8 | 2017-04-08 09:53:51 +0300 | [diff] [blame] | 1874 |         if (PySlice_Unpack(item, &start, &stop, &step) < 0) { | 
| Florent Xicluna | f15351d | 2010-03-13 23:24:31 +0000 | [diff] [blame] | 1875 |             return -1; | 
 | 1876 |         } | 
| Serhiy Storchaka | b879fe8 | 2017-04-08 09:53:51 +0300 | [diff] [blame] | 1877 |         slicelen = PySlice_AdjustIndices(self->extra->length, &start, &stop, | 
 | 1878 |                                          step); | 
| Florent Xicluna | f15351d | 2010-03-13 23:24:31 +0000 | [diff] [blame] | 1879 |  | 
| Eli Bendersky | 865756a | 2012-03-09 13:38:15 +0200 | [diff] [blame] | 1880 |         if (value == NULL) { | 
 | 1881 |             /* Delete slice */ | 
 | 1882 |             size_t cur; | 
 | 1883 |             Py_ssize_t i; | 
 | 1884 |  | 
 | 1885 |             if (slicelen <= 0) | 
 | 1886 |                 return 0; | 
 | 1887 |  | 
 | 1888 |             /* Since we're deleting, the direction of the range doesn't matter, | 
 | 1889 |              * so for simplicity make it always ascending. | 
 | 1890 |             */ | 
 | 1891 |             if (step < 0) { | 
 | 1892 |                 stop = start + 1; | 
 | 1893 |                 start = stop + step * (slicelen - 1) - 1; | 
 | 1894 |                 step = -step; | 
 | 1895 |             } | 
 | 1896 |  | 
| Benjamin Peterson | 2f8bfef | 2016-09-07 09:26:18 -0700 | [diff] [blame] | 1897 |             assert((size_t)slicelen <= SIZE_MAX / sizeof(PyObject *)); | 
| Eli Bendersky | 865756a | 2012-03-09 13:38:15 +0200 | [diff] [blame] | 1898 |  | 
 | 1899 |             /* recycle is a list that will contain all the children | 
 | 1900 |              * scheduled for removal. | 
 | 1901 |             */ | 
 | 1902 |             if (!(recycle = PyList_New(slicelen))) { | 
| Eli Bendersky | 865756a | 2012-03-09 13:38:15 +0200 | [diff] [blame] | 1903 |                 return -1; | 
 | 1904 |             } | 
 | 1905 |  | 
 | 1906 |             /* This loop walks over all the children that have to be deleted, | 
 | 1907 |              * with cur pointing at them. num_moved is the amount of children | 
 | 1908 |              * until the next deleted child that have to be "shifted down" to | 
 | 1909 |              * occupy the deleted's places. | 
 | 1910 |              * Note that in the ith iteration, shifting is done i+i places down | 
 | 1911 |              * because i children were already removed. | 
 | 1912 |             */ | 
 | 1913 |             for (cur = start, i = 0; cur < (size_t)stop; cur += step, ++i) { | 
 | 1914 |                 /* Compute how many children have to be moved, clipping at the | 
 | 1915 |                  * list end. | 
 | 1916 |                 */ | 
 | 1917 |                 Py_ssize_t num_moved = step - 1; | 
 | 1918 |                 if (cur + step >= (size_t)self->extra->length) { | 
 | 1919 |                     num_moved = self->extra->length - cur - 1; | 
 | 1920 |                 } | 
 | 1921 |  | 
 | 1922 |                 PyList_SET_ITEM(recycle, i, self->extra->children[cur]); | 
 | 1923 |  | 
 | 1924 |                 memmove( | 
 | 1925 |                     self->extra->children + cur - i, | 
 | 1926 |                     self->extra->children + cur + 1, | 
 | 1927 |                     num_moved * sizeof(PyObject *)); | 
 | 1928 |             } | 
 | 1929 |  | 
 | 1930 |             /* Leftover "tail" after the last removed child */ | 
 | 1931 |             cur = start + (size_t)slicelen * step; | 
 | 1932 |             if (cur < (size_t)self->extra->length) { | 
 | 1933 |                 memmove( | 
 | 1934 |                     self->extra->children + cur - slicelen, | 
 | 1935 |                     self->extra->children + cur, | 
 | 1936 |                     (self->extra->length - cur) * sizeof(PyObject *)); | 
 | 1937 |             } | 
 | 1938 |  | 
 | 1939 |             self->extra->length -= slicelen; | 
 | 1940 |  | 
 | 1941 |             /* Discard the recycle list with all the deleted sub-elements */ | 
| Zackery Spytz | 9f3ed3e | 2018-10-23 13:28:06 -0600 | [diff] [blame] | 1942 |             Py_DECREF(recycle); | 
| Eli Bendersky | 865756a | 2012-03-09 13:38:15 +0200 | [diff] [blame] | 1943 |             return 0; | 
 | 1944 |         } | 
| Serhiy Storchaka | 04d759b | 2015-11-22 12:18:38 +0200 | [diff] [blame] | 1945 |  | 
 | 1946 |         /* A new slice is actually being assigned */ | 
 | 1947 |         seq = PySequence_Fast(value, ""); | 
 | 1948 |         if (!seq) { | 
 | 1949 |             PyErr_Format( | 
 | 1950 |                 PyExc_TypeError, | 
 | 1951 |                 "expected sequence, not \"%.200s\"", Py_TYPE(value)->tp_name | 
 | 1952 |                 ); | 
 | 1953 |             return -1; | 
| Florent Xicluna | f15351d | 2010-03-13 23:24:31 +0000 | [diff] [blame] | 1954 |         } | 
| Serhiy Storchaka | bf623ae | 2017-04-19 20:03:52 +0300 | [diff] [blame] | 1955 |         newlen = PySequence_Fast_GET_SIZE(seq); | 
| Florent Xicluna | f15351d | 2010-03-13 23:24:31 +0000 | [diff] [blame] | 1956 |  | 
 | 1957 |         if (step !=  1 && newlen != slicelen) | 
 | 1958 |         { | 
| Serhiy Storchaka | 04d759b | 2015-11-22 12:18:38 +0200 | [diff] [blame] | 1959 |             Py_DECREF(seq); | 
| Florent Xicluna | f15351d | 2010-03-13 23:24:31 +0000 | [diff] [blame] | 1960 |             PyErr_Format(PyExc_ValueError, | 
| Florent Xicluna | f15351d | 2010-03-13 23:24:31 +0000 | [diff] [blame] | 1961 |                 "attempt to assign sequence of size %zd " | 
 | 1962 |                 "to extended slice of size %zd", | 
| Florent Xicluna | f15351d | 2010-03-13 23:24:31 +0000 | [diff] [blame] | 1963 |                 newlen, slicelen | 
 | 1964 |                 ); | 
 | 1965 |             return -1; | 
 | 1966 |         } | 
 | 1967 |  | 
| Florent Xicluna | f15351d | 2010-03-13 23:24:31 +0000 | [diff] [blame] | 1968 |         /* Resize before creating the recycle bin, to prevent refleaks. */ | 
 | 1969 |         if (newlen > slicelen) { | 
 | 1970 |             if (element_resize(self, newlen - slicelen) < 0) { | 
| Serhiy Storchaka | 04d759b | 2015-11-22 12:18:38 +0200 | [diff] [blame] | 1971 |                 Py_DECREF(seq); | 
| Florent Xicluna | f15351d | 2010-03-13 23:24:31 +0000 | [diff] [blame] | 1972 |                 return -1; | 
 | 1973 |             } | 
 | 1974 |         } | 
 | 1975 |  | 
| Serhiy Storchaka | f081fd8 | 2018-10-19 12:12:57 +0300 | [diff] [blame] | 1976 |         for (i = 0; i < newlen; i++) { | 
 | 1977 |             PyObject *element = PySequence_Fast_GET_ITEM(seq, i); | 
 | 1978 |             if (!Element_Check(element)) { | 
 | 1979 |                 raise_type_error(element); | 
 | 1980 |                 Py_DECREF(seq); | 
 | 1981 |                 return -1; | 
 | 1982 |             } | 
 | 1983 |         } | 
 | 1984 |  | 
| Florent Xicluna | f15351d | 2010-03-13 23:24:31 +0000 | [diff] [blame] | 1985 |         if (slicelen > 0) { | 
 | 1986 |             /* to avoid recursive calls to this method (via decref), move | 
 | 1987 |                old items to the recycle bin here, and get rid of them when | 
 | 1988 |                we're done modifying the element */ | 
 | 1989 |             recycle = PyList_New(slicelen); | 
 | 1990 |             if (!recycle) { | 
| Serhiy Storchaka | 04d759b | 2015-11-22 12:18:38 +0200 | [diff] [blame] | 1991 |                 Py_DECREF(seq); | 
| Florent Xicluna | f15351d | 2010-03-13 23:24:31 +0000 | [diff] [blame] | 1992 |                 return -1; | 
 | 1993 |             } | 
 | 1994 |             for (cur = start, i = 0; i < slicelen; | 
 | 1995 |                  cur += step, i++) | 
 | 1996 |                 PyList_SET_ITEM(recycle, i, self->extra->children[cur]); | 
 | 1997 |         } | 
 | 1998 |  | 
 | 1999 |         if (newlen < slicelen) { | 
 | 2000 |             /* delete slice */ | 
 | 2001 |             for (i = stop; i < self->extra->length; i++) | 
 | 2002 |                 self->extra->children[i + newlen - slicelen] = self->extra->children[i]; | 
 | 2003 |         } else if (newlen > slicelen) { | 
 | 2004 |             /* insert slice */ | 
 | 2005 |             for (i = self->extra->length-1; i >= stop; i--) | 
 | 2006 |                 self->extra->children[i + newlen - slicelen] = self->extra->children[i]; | 
 | 2007 |         } | 
 | 2008 |  | 
 | 2009 |         /* replace the slice */ | 
 | 2010 |         for (cur = start, i = 0; i < newlen; | 
 | 2011 |              cur += step, i++) { | 
 | 2012 |             PyObject* element = PySequence_Fast_GET_ITEM(seq, i); | 
 | 2013 |             Py_INCREF(element); | 
 | 2014 |             self->extra->children[cur] = element; | 
 | 2015 |         } | 
 | 2016 |  | 
 | 2017 |         self->extra->length += newlen - slicelen; | 
 | 2018 |  | 
| Serhiy Storchaka | 04d759b | 2015-11-22 12:18:38 +0200 | [diff] [blame] | 2019 |         Py_DECREF(seq); | 
| Florent Xicluna | f15351d | 2010-03-13 23:24:31 +0000 | [diff] [blame] | 2020 |  | 
 | 2021 |         /* discard the recycle bin, and everything in it */ | 
 | 2022 |         Py_XDECREF(recycle); | 
 | 2023 |  | 
 | 2024 |         return 0; | 
 | 2025 |     } | 
 | 2026 |     else { | 
 | 2027 |         PyErr_SetString(PyExc_TypeError, | 
 | 2028 |                 "element indices must be integers"); | 
 | 2029 |         return -1; | 
 | 2030 |     } | 
 | 2031 | } | 
 | 2032 |  | 
| Florent Xicluna | f15351d | 2010-03-13 23:24:31 +0000 | [diff] [blame] | 2033 | static PyObject* | 
| Serhiy Storchaka | dde0815 | 2015-11-25 15:28:13 +0200 | [diff] [blame] | 2034 | element_tag_getter(ElementObject *self, void *closure) | 
| Fredrik Lundh | 8c8836b | 2005-12-16 22:06:06 +0000 | [diff] [blame] | 2035 | { | 
| Serhiy Storchaka | dde0815 | 2015-11-25 15:28:13 +0200 | [diff] [blame] | 2036 |     PyObject *res = self->tag; | 
| Florent Xicluna | f15351d | 2010-03-13 23:24:31 +0000 | [diff] [blame] | 2037 |     Py_INCREF(res); | 
| Fredrik Lundh | 8c8836b | 2005-12-16 22:06:06 +0000 | [diff] [blame] | 2038 |     return res; | 
 | 2039 | } | 
 | 2040 |  | 
| Serhiy Storchaka | dde0815 | 2015-11-25 15:28:13 +0200 | [diff] [blame] | 2041 | static PyObject* | 
 | 2042 | element_text_getter(ElementObject *self, void *closure) | 
| Fredrik Lundh | 8c8836b | 2005-12-16 22:06:06 +0000 | [diff] [blame] | 2043 | { | 
| Serhiy Storchaka | dde0815 | 2015-11-25 15:28:13 +0200 | [diff] [blame] | 2044 |     PyObject *res = element_get_text(self); | 
 | 2045 |     Py_XINCREF(res); | 
 | 2046 |     return res; | 
 | 2047 | } | 
| Serhiy Storchaka | b6aa537 | 2015-11-23 08:42:25 +0200 | [diff] [blame] | 2048 |  | 
| Serhiy Storchaka | dde0815 | 2015-11-25 15:28:13 +0200 | [diff] [blame] | 2049 | static PyObject* | 
 | 2050 | element_tail_getter(ElementObject *self, void *closure) | 
 | 2051 | { | 
 | 2052 |     PyObject *res = element_get_tail(self); | 
 | 2053 |     Py_XINCREF(res); | 
 | 2054 |     return res; | 
 | 2055 | } | 
 | 2056 |  | 
 | 2057 | static PyObject* | 
 | 2058 | element_attrib_getter(ElementObject *self, void *closure) | 
 | 2059 | { | 
 | 2060 |     PyObject *res; | 
 | 2061 |     if (!self->extra) { | 
 | 2062 |         if (create_extra(self, NULL) < 0) | 
 | 2063 |             return NULL; | 
| Serhiy Storchaka | b6aa537 | 2015-11-23 08:42:25 +0200 | [diff] [blame] | 2064 |     } | 
| Serhiy Storchaka | dde0815 | 2015-11-25 15:28:13 +0200 | [diff] [blame] | 2065 |     res = element_get_attrib(self); | 
 | 2066 |     Py_XINCREF(res); | 
 | 2067 |     return res; | 
 | 2068 | } | 
| Victor Stinner | 4d46343 | 2013-07-11 23:05:03 +0200 | [diff] [blame] | 2069 |  | 
| Serhiy Storchaka | dde0815 | 2015-11-25 15:28:13 +0200 | [diff] [blame] | 2070 | /* macro for setter validation */ | 
 | 2071 | #define _VALIDATE_ATTR_VALUE(V)                     \ | 
 | 2072 |     if ((V) == NULL) {                              \ | 
 | 2073 |         PyErr_SetString(                            \ | 
 | 2074 |             PyExc_AttributeError,                   \ | 
 | 2075 |             "can't delete element attribute");      \ | 
 | 2076 |         return -1;                                  \ | 
| Fredrik Lundh | 8c8836b | 2005-12-16 22:06:06 +0000 | [diff] [blame] | 2077 |     } | 
 | 2078 |  | 
| Serhiy Storchaka | dde0815 | 2015-11-25 15:28:13 +0200 | [diff] [blame] | 2079 | static int | 
 | 2080 | element_tag_setter(ElementObject *self, PyObject *value, void *closure) | 
 | 2081 | { | 
 | 2082 |     _VALIDATE_ATTR_VALUE(value); | 
 | 2083 |     Py_INCREF(value); | 
| Serhiy Storchaka | f01e408 | 2016-04-10 18:12:01 +0300 | [diff] [blame] | 2084 |     Py_SETREF(self->tag, value); | 
| Serhiy Storchaka | dde0815 | 2015-11-25 15:28:13 +0200 | [diff] [blame] | 2085 |     return 0; | 
 | 2086 | } | 
 | 2087 |  | 
 | 2088 | static int | 
 | 2089 | element_text_setter(ElementObject *self, PyObject *value, void *closure) | 
 | 2090 | { | 
 | 2091 |     _VALIDATE_ATTR_VALUE(value); | 
 | 2092 |     Py_INCREF(value); | 
| Oren Milman | 39ecb9c | 2017-10-10 23:26:24 +0300 | [diff] [blame] | 2093 |     _set_joined_ptr(&self->text, value); | 
| Serhiy Storchaka | dde0815 | 2015-11-25 15:28:13 +0200 | [diff] [blame] | 2094 |     return 0; | 
 | 2095 | } | 
 | 2096 |  | 
 | 2097 | static int | 
 | 2098 | element_tail_setter(ElementObject *self, PyObject *value, void *closure) | 
 | 2099 | { | 
 | 2100 |     _VALIDATE_ATTR_VALUE(value); | 
 | 2101 |     Py_INCREF(value); | 
| Oren Milman | 39ecb9c | 2017-10-10 23:26:24 +0300 | [diff] [blame] | 2102 |     _set_joined_ptr(&self->tail, value); | 
| Serhiy Storchaka | dde0815 | 2015-11-25 15:28:13 +0200 | [diff] [blame] | 2103 |     return 0; | 
 | 2104 | } | 
 | 2105 |  | 
 | 2106 | static int | 
 | 2107 | element_attrib_setter(ElementObject *self, PyObject *value, void *closure) | 
 | 2108 | { | 
 | 2109 |     _VALIDATE_ATTR_VALUE(value); | 
 | 2110 |     if (!self->extra) { | 
 | 2111 |         if (create_extra(self, NULL) < 0) | 
 | 2112 |             return -1; | 
 | 2113 |     } | 
 | 2114 |     Py_INCREF(value); | 
| Serhiy Storchaka | f01e408 | 2016-04-10 18:12:01 +0300 | [diff] [blame] | 2115 |     Py_SETREF(self->extra->attrib, value); | 
| Eli Bendersky | ef9683b | 2013-05-18 07:52:34 -0700 | [diff] [blame] | 2116 |     return 0; | 
| Fredrik Lundh | 8c8836b | 2005-12-16 22:06:06 +0000 | [diff] [blame] | 2117 | } | 
 | 2118 |  | 
 | 2119 | static PySequenceMethods element_as_sequence = { | 
| Martin v. Löwis | 18e1655 | 2006-02-15 17:27:45 +0000 | [diff] [blame] | 2120 |     (lenfunc) element_length, | 
| Fredrik Lundh | 8c8836b | 2005-12-16 22:06:06 +0000 | [diff] [blame] | 2121 |     0, /* sq_concat */ | 
 | 2122 |     0, /* sq_repeat */ | 
| Martin v. Löwis | 18e1655 | 2006-02-15 17:27:45 +0000 | [diff] [blame] | 2123 |     element_getitem, | 
| Florent Xicluna | f15351d | 2010-03-13 23:24:31 +0000 | [diff] [blame] | 2124 |     0, | 
| Martin v. Löwis | 18e1655 | 2006-02-15 17:27:45 +0000 | [diff] [blame] | 2125 |     element_setitem, | 
| Florent Xicluna | f15351d | 2010-03-13 23:24:31 +0000 | [diff] [blame] | 2126 |     0, | 
 | 2127 | }; | 
 | 2128 |  | 
| Eli Bendersky | 64d11e6 | 2012-06-15 07:42:50 +0300 | [diff] [blame] | 2129 | /******************************* Element iterator ****************************/ | 
 | 2130 |  | 
 | 2131 | /* ElementIterObject represents the iteration state over an XML element in | 
 | 2132 |  * pre-order traversal. To keep track of which sub-element should be returned | 
 | 2133 |  * next, a stack of parents is maintained. This is a standard stack-based | 
 | 2134 |  * iterative pre-order traversal of a tree. | 
| Serhiy Storchaka | 22adf2a | 2015-12-21 12:43:54 +0200 | [diff] [blame] | 2135 |  * The stack is managed using a continuous array. | 
 | 2136 |  * Each stack item contains the saved parent to which we should return after | 
| Eli Bendersky | 64d11e6 | 2012-06-15 07:42:50 +0300 | [diff] [blame] | 2137 |  * the current one is exhausted, and the next child to examine in that parent. | 
 | 2138 |  */ | 
 | 2139 | typedef struct ParentLocator_t { | 
 | 2140 |     ElementObject *parent; | 
 | 2141 |     Py_ssize_t child_index; | 
| Eli Bendersky | 64d11e6 | 2012-06-15 07:42:50 +0300 | [diff] [blame] | 2142 | } ParentLocator; | 
 | 2143 |  | 
 | 2144 | typedef struct { | 
 | 2145 |     PyObject_HEAD | 
 | 2146 |     ParentLocator *parent_stack; | 
| Serhiy Storchaka | 22adf2a | 2015-12-21 12:43:54 +0200 | [diff] [blame] | 2147 |     Py_ssize_t parent_stack_used; | 
 | 2148 |     Py_ssize_t parent_stack_size; | 
| Eli Bendersky | 64d11e6 | 2012-06-15 07:42:50 +0300 | [diff] [blame] | 2149 |     ElementObject *root_element; | 
 | 2150 |     PyObject *sought_tag; | 
| Eli Bendersky | 64d11e6 | 2012-06-15 07:42:50 +0300 | [diff] [blame] | 2151 |     int gettext; | 
 | 2152 | } ElementIterObject; | 
 | 2153 |  | 
 | 2154 |  | 
 | 2155 | static void | 
 | 2156 | elementiter_dealloc(ElementIterObject *it) | 
 | 2157 | { | 
| Serhiy Storchaka | 22adf2a | 2015-12-21 12:43:54 +0200 | [diff] [blame] | 2158 |     Py_ssize_t i = it->parent_stack_used; | 
 | 2159 |     it->parent_stack_used = 0; | 
| INADA Naoki | a6296d3 | 2017-08-24 14:55:17 +0900 | [diff] [blame] | 2160 |     /* bpo-31095: UnTrack is needed before calling any callbacks */ | 
 | 2161 |     PyObject_GC_UnTrack(it); | 
| Serhiy Storchaka | 22adf2a | 2015-12-21 12:43:54 +0200 | [diff] [blame] | 2162 |     while (i--) | 
 | 2163 |         Py_XDECREF(it->parent_stack[i].parent); | 
 | 2164 |     PyMem_Free(it->parent_stack); | 
| Eli Bendersky | 64d11e6 | 2012-06-15 07:42:50 +0300 | [diff] [blame] | 2165 |  | 
 | 2166 |     Py_XDECREF(it->sought_tag); | 
 | 2167 |     Py_XDECREF(it->root_element); | 
 | 2168 |  | 
| Eli Bendersky | 64d11e6 | 2012-06-15 07:42:50 +0300 | [diff] [blame] | 2169 |     PyObject_GC_Del(it); | 
 | 2170 | } | 
 | 2171 |  | 
 | 2172 | static int | 
 | 2173 | elementiter_traverse(ElementIterObject *it, visitproc visit, void *arg) | 
 | 2174 | { | 
| Serhiy Storchaka | 22adf2a | 2015-12-21 12:43:54 +0200 | [diff] [blame] | 2175 |     Py_ssize_t i = it->parent_stack_used; | 
 | 2176 |     while (i--) | 
 | 2177 |         Py_VISIT(it->parent_stack[i].parent); | 
| Eli Bendersky | 64d11e6 | 2012-06-15 07:42:50 +0300 | [diff] [blame] | 2178 |  | 
 | 2179 |     Py_VISIT(it->root_element); | 
 | 2180 |     Py_VISIT(it->sought_tag); | 
 | 2181 |     return 0; | 
 | 2182 | } | 
 | 2183 |  | 
 | 2184 | /* Helper function for elementiter_next. Add a new parent to the parent stack. | 
 | 2185 |  */ | 
| Serhiy Storchaka | 22adf2a | 2015-12-21 12:43:54 +0200 | [diff] [blame] | 2186 | static int | 
 | 2187 | parent_stack_push_new(ElementIterObject *it, ElementObject *parent) | 
| Eli Bendersky | 64d11e6 | 2012-06-15 07:42:50 +0300 | [diff] [blame] | 2188 | { | 
| Serhiy Storchaka | 22adf2a | 2015-12-21 12:43:54 +0200 | [diff] [blame] | 2189 |     ParentLocator *item; | 
 | 2190 |  | 
 | 2191 |     if (it->parent_stack_used >= it->parent_stack_size) { | 
 | 2192 |         Py_ssize_t new_size = it->parent_stack_size * 2;  /* never overflow */ | 
 | 2193 |         ParentLocator *parent_stack = it->parent_stack; | 
 | 2194 |         PyMem_Resize(parent_stack, ParentLocator, new_size); | 
 | 2195 |         if (parent_stack == NULL) | 
 | 2196 |             return -1; | 
 | 2197 |         it->parent_stack = parent_stack; | 
 | 2198 |         it->parent_stack_size = new_size; | 
| Eli Bendersky | 64d11e6 | 2012-06-15 07:42:50 +0300 | [diff] [blame] | 2199 |     } | 
| Serhiy Storchaka | 22adf2a | 2015-12-21 12:43:54 +0200 | [diff] [blame] | 2200 |     item = it->parent_stack + it->parent_stack_used++; | 
 | 2201 |     Py_INCREF(parent); | 
 | 2202 |     item->parent = parent; | 
 | 2203 |     item->child_index = 0; | 
 | 2204 |     return 0; | 
| Eli Bendersky | 64d11e6 | 2012-06-15 07:42:50 +0300 | [diff] [blame] | 2205 | } | 
 | 2206 |  | 
 | 2207 | static PyObject * | 
 | 2208 | elementiter_next(ElementIterObject *it) | 
 | 2209 | { | 
 | 2210 |     /* Sub-element iterator. | 
| Eli Bendersky | 4583990 | 2013-01-13 05:14:47 -0800 | [diff] [blame] | 2211 |      * | 
| Eli Bendersky | 64d11e6 | 2012-06-15 07:42:50 +0300 | [diff] [blame] | 2212 |      * A short note on gettext: this function serves both the iter() and | 
 | 2213 |      * itertext() methods to avoid code duplication. However, there are a few | 
 | 2214 |      * small differences in the way these iterations work. Namely: | 
 | 2215 |      *   - itertext() only yields text from nodes that have it, and continues | 
 | 2216 |      *     iterating when a node doesn't have text (so it doesn't return any | 
 | 2217 |      *     node like iter()) | 
 | 2218 |      *   - itertext() also has to handle tail, after finishing with all the | 
 | 2219 |      *     children of a node. | 
 | 2220 |      */ | 
| Serhiy Storchaka | 5bf3120 | 2015-05-18 18:29:33 +0300 | [diff] [blame] | 2221 |     int rc; | 
| Serhiy Storchaka | 66c08d9 | 2015-12-21 11:09:48 +0200 | [diff] [blame] | 2222 |     ElementObject *elem; | 
| Serhiy Storchaka | 22adf2a | 2015-12-21 12:43:54 +0200 | [diff] [blame] | 2223 |     PyObject *text; | 
| Eli Bendersky | 64d11e6 | 2012-06-15 07:42:50 +0300 | [diff] [blame] | 2224 |  | 
 | 2225 |     while (1) { | 
 | 2226 |         /* Handle the case reached in the beginning and end of iteration, where | 
| Serhiy Storchaka | 22adf2a | 2015-12-21 12:43:54 +0200 | [diff] [blame] | 2227 |          * the parent stack is empty. If root_element is NULL and we're here, the | 
| Eli Bendersky | 64d11e6 | 2012-06-15 07:42:50 +0300 | [diff] [blame] | 2228 |          * iterator is exhausted. | 
 | 2229 |          */ | 
| Serhiy Storchaka | 22adf2a | 2015-12-21 12:43:54 +0200 | [diff] [blame] | 2230 |         if (!it->parent_stack_used) { | 
 | 2231 |             if (!it->root_element) { | 
| Eli Bendersky | 64d11e6 | 2012-06-15 07:42:50 +0300 | [diff] [blame] | 2232 |                 PyErr_SetNone(PyExc_StopIteration); | 
 | 2233 |                 return NULL; | 
| Eli Bendersky | 64d11e6 | 2012-06-15 07:42:50 +0300 | [diff] [blame] | 2234 |             } | 
 | 2235 |  | 
| Serhiy Storchaka | 22adf2a | 2015-12-21 12:43:54 +0200 | [diff] [blame] | 2236 |             elem = it->root_element;  /* steals a reference */ | 
 | 2237 |             it->root_element = NULL; | 
| Eli Bendersky | 64d11e6 | 2012-06-15 07:42:50 +0300 | [diff] [blame] | 2238 |         } | 
 | 2239 |         else { | 
| Serhiy Storchaka | 22adf2a | 2015-12-21 12:43:54 +0200 | [diff] [blame] | 2240 |             /* See if there are children left to traverse in the current parent. If | 
 | 2241 |              * yes, visit the next child. If not, pop the stack and try again. | 
| Eli Bendersky | 64d11e6 | 2012-06-15 07:42:50 +0300 | [diff] [blame] | 2242 |              */ | 
| Serhiy Storchaka | 22adf2a | 2015-12-21 12:43:54 +0200 | [diff] [blame] | 2243 |             ParentLocator *item = &it->parent_stack[it->parent_stack_used - 1]; | 
 | 2244 |             Py_ssize_t child_index = item->child_index; | 
 | 2245 |             ElementObjectExtra *extra; | 
 | 2246 |             elem = item->parent; | 
 | 2247 |             extra = elem->extra; | 
 | 2248 |             if (!extra || child_index >= extra->length) { | 
 | 2249 |                 it->parent_stack_used--; | 
 | 2250 |                 /* Note that extra condition on it->parent_stack_used here; | 
 | 2251 |                  * this is because itertext() is supposed to only return *inner* | 
 | 2252 |                  * text, not text following the element it began iteration with. | 
 | 2253 |                  */ | 
 | 2254 |                 if (it->gettext && it->parent_stack_used) { | 
 | 2255 |                     text = element_get_tail(elem); | 
 | 2256 |                     goto gettext; | 
 | 2257 |                 } | 
 | 2258 |                 Py_DECREF(elem); | 
 | 2259 |                 continue; | 
| Serhiy Storchaka | 66c08d9 | 2015-12-21 11:09:48 +0200 | [diff] [blame] | 2260 |             } | 
| Serhiy Storchaka | 22adf2a | 2015-12-21 12:43:54 +0200 | [diff] [blame] | 2261 |  | 
| Serhiy Storchaka | f081fd8 | 2018-10-19 12:12:57 +0300 | [diff] [blame] | 2262 |             assert(Element_Check(extra->children[child_index])); | 
| Serhiy Storchaka | 22adf2a | 2015-12-21 12:43:54 +0200 | [diff] [blame] | 2263 |             elem = (ElementObject *)extra->children[child_index]; | 
 | 2264 |             item->child_index++; | 
 | 2265 |             Py_INCREF(elem); | 
 | 2266 |         } | 
 | 2267 |  | 
 | 2268 |         if (parent_stack_push_new(it, elem) < 0) { | 
 | 2269 |             Py_DECREF(elem); | 
 | 2270 |             PyErr_NoMemory(); | 
 | 2271 |             return NULL; | 
 | 2272 |         } | 
 | 2273 |         if (it->gettext) { | 
 | 2274 |             text = element_get_text(elem); | 
 | 2275 |             goto gettext; | 
 | 2276 |         } | 
 | 2277 |  | 
 | 2278 |         if (it->sought_tag == Py_None) | 
 | 2279 |             return (PyObject *)elem; | 
 | 2280 |  | 
 | 2281 |         rc = PyObject_RichCompareBool(elem->tag, it->sought_tag, Py_EQ); | 
 | 2282 |         if (rc > 0) | 
 | 2283 |             return (PyObject *)elem; | 
 | 2284 |  | 
 | 2285 |         Py_DECREF(elem); | 
 | 2286 |         if (rc < 0) | 
 | 2287 |             return NULL; | 
 | 2288 |         continue; | 
 | 2289 |  | 
 | 2290 | gettext: | 
 | 2291 |         if (!text) { | 
 | 2292 |             Py_DECREF(elem); | 
 | 2293 |             return NULL; | 
 | 2294 |         } | 
 | 2295 |         if (text == Py_None) { | 
 | 2296 |             Py_DECREF(elem); | 
 | 2297 |         } | 
 | 2298 |         else { | 
 | 2299 |             Py_INCREF(text); | 
 | 2300 |             Py_DECREF(elem); | 
 | 2301 |             rc = PyObject_IsTrue(text); | 
 | 2302 |             if (rc > 0) | 
 | 2303 |                 return text; | 
 | 2304 |             Py_DECREF(text); | 
 | 2305 |             if (rc < 0) | 
 | 2306 |                 return NULL; | 
| Eli Bendersky | 64d11e6 | 2012-06-15 07:42:50 +0300 | [diff] [blame] | 2307 |         } | 
 | 2308 |     } | 
 | 2309 |  | 
 | 2310 |     return NULL; | 
 | 2311 | } | 
 | 2312 |  | 
 | 2313 |  | 
 | 2314 | static PyTypeObject ElementIter_Type = { | 
 | 2315 |     PyVarObject_HEAD_INIT(NULL, 0) | 
| Eli Bendersky | 698bdb2 | 2013-01-10 06:01:06 -0800 | [diff] [blame] | 2316 |     /* Using the module's name since the pure-Python implementation does not | 
 | 2317 |        have such a type. */ | 
| Eli Bendersky | 64d11e6 | 2012-06-15 07:42:50 +0300 | [diff] [blame] | 2318 |     "_elementtree._element_iterator",           /* tp_name */ | 
 | 2319 |     sizeof(ElementIterObject),                  /* tp_basicsize */ | 
 | 2320 |     0,                                          /* tp_itemsize */ | 
 | 2321 |     /* methods */ | 
 | 2322 |     (destructor)elementiter_dealloc,            /* tp_dealloc */ | 
 | 2323 |     0,                                          /* tp_print */ | 
 | 2324 |     0,                                          /* tp_getattr */ | 
 | 2325 |     0,                                          /* tp_setattr */ | 
 | 2326 |     0,                                          /* tp_reserved */ | 
 | 2327 |     0,                                          /* tp_repr */ | 
 | 2328 |     0,                                          /* tp_as_number */ | 
 | 2329 |     0,                                          /* tp_as_sequence */ | 
 | 2330 |     0,                                          /* tp_as_mapping */ | 
 | 2331 |     0,                                          /* tp_hash */ | 
 | 2332 |     0,                                          /* tp_call */ | 
 | 2333 |     0,                                          /* tp_str */ | 
 | 2334 |     0,                                          /* tp_getattro */ | 
 | 2335 |     0,                                          /* tp_setattro */ | 
 | 2336 |     0,                                          /* tp_as_buffer */ | 
 | 2337 |     Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC,    /* tp_flags */ | 
 | 2338 |     0,                                          /* tp_doc */ | 
 | 2339 |     (traverseproc)elementiter_traverse,         /* tp_traverse */ | 
 | 2340 |     0,                                          /* tp_clear */ | 
 | 2341 |     0,                                          /* tp_richcompare */ | 
 | 2342 |     0,                                          /* tp_weaklistoffset */ | 
 | 2343 |     PyObject_SelfIter,                          /* tp_iter */ | 
 | 2344 |     (iternextfunc)elementiter_next,             /* tp_iternext */ | 
 | 2345 |     0,                                          /* tp_methods */ | 
 | 2346 |     0,                                          /* tp_members */ | 
 | 2347 |     0,                                          /* tp_getset */ | 
 | 2348 |     0,                                          /* tp_base */ | 
 | 2349 |     0,                                          /* tp_dict */ | 
 | 2350 |     0,                                          /* tp_descr_get */ | 
 | 2351 |     0,                                          /* tp_descr_set */ | 
 | 2352 |     0,                                          /* tp_dictoffset */ | 
 | 2353 |     0,                                          /* tp_init */ | 
 | 2354 |     0,                                          /* tp_alloc */ | 
 | 2355 |     0,                                          /* tp_new */ | 
 | 2356 | }; | 
 | 2357 |  | 
| Serhiy Storchaka | 22adf2a | 2015-12-21 12:43:54 +0200 | [diff] [blame] | 2358 | #define INIT_PARENT_STACK_SIZE 8 | 
| Eli Bendersky | 64d11e6 | 2012-06-15 07:42:50 +0300 | [diff] [blame] | 2359 |  | 
 | 2360 | static PyObject * | 
 | 2361 | create_elementiter(ElementObject *self, PyObject *tag, int gettext) | 
 | 2362 | { | 
 | 2363 |     ElementIterObject *it; | 
| Eli Bendersky | 64d11e6 | 2012-06-15 07:42:50 +0300 | [diff] [blame] | 2364 |  | 
 | 2365 |     it = PyObject_GC_New(ElementIterObject, &ElementIter_Type); | 
 | 2366 |     if (!it) | 
 | 2367 |         return NULL; | 
| Eli Bendersky | 64d11e6 | 2012-06-15 07:42:50 +0300 | [diff] [blame] | 2368 |  | 
| Victor Stinner | 4d46343 | 2013-07-11 23:05:03 +0200 | [diff] [blame] | 2369 |     Py_INCREF(tag); | 
| Eli Bendersky | 64d11e6 | 2012-06-15 07:42:50 +0300 | [diff] [blame] | 2370 |     it->sought_tag = tag; | 
| Eli Bendersky | 64d11e6 | 2012-06-15 07:42:50 +0300 | [diff] [blame] | 2371 |     it->gettext = gettext; | 
| Victor Stinner | 4d46343 | 2013-07-11 23:05:03 +0200 | [diff] [blame] | 2372 |     Py_INCREF(self); | 
| Eli Bendersky | 64d11e6 | 2012-06-15 07:42:50 +0300 | [diff] [blame] | 2373 |     it->root_element = self; | 
 | 2374 |  | 
| Eli Bendersky | 64d11e6 | 2012-06-15 07:42:50 +0300 | [diff] [blame] | 2375 |     PyObject_GC_Track(it); | 
| Victor Stinner | d917dcb | 2013-07-12 02:05:17 +0200 | [diff] [blame] | 2376 |  | 
| Serhiy Storchaka | 22adf2a | 2015-12-21 12:43:54 +0200 | [diff] [blame] | 2377 |     it->parent_stack = PyMem_New(ParentLocator, INIT_PARENT_STACK_SIZE); | 
| Victor Stinner | d917dcb | 2013-07-12 02:05:17 +0200 | [diff] [blame] | 2378 |     if (it->parent_stack == NULL) { | 
 | 2379 |         Py_DECREF(it); | 
 | 2380 |         PyErr_NoMemory(); | 
 | 2381 |         return NULL; | 
 | 2382 |     } | 
| Serhiy Storchaka | 22adf2a | 2015-12-21 12:43:54 +0200 | [diff] [blame] | 2383 |     it->parent_stack_used = 0; | 
 | 2384 |     it->parent_stack_size = INIT_PARENT_STACK_SIZE; | 
| Victor Stinner | d917dcb | 2013-07-12 02:05:17 +0200 | [diff] [blame] | 2385 |  | 
| Eli Bendersky | 64d11e6 | 2012-06-15 07:42:50 +0300 | [diff] [blame] | 2386 |     return (PyObject *)it; | 
 | 2387 | } | 
 | 2388 |  | 
 | 2389 |  | 
| Fredrik Lundh | 8c8836b | 2005-12-16 22:06:06 +0000 | [diff] [blame] | 2390 | /* ==================================================================== */ | 
 | 2391 | /* the tree builder type */ | 
 | 2392 |  | 
 | 2393 | typedef struct { | 
 | 2394 |     PyObject_HEAD | 
 | 2395 |  | 
| Eli Bendersky | 58d548d | 2012-05-29 15:45:16 +0300 | [diff] [blame] | 2396 |     PyObject *root; /* root node (first created node) */ | 
| Fredrik Lundh | 8c8836b | 2005-12-16 22:06:06 +0000 | [diff] [blame] | 2397 |  | 
| Antoine Pitrou | ee32931 | 2012-10-04 19:53:29 +0200 | [diff] [blame] | 2398 |     PyObject *this; /* current node */ | 
 | 2399 |     PyObject *last; /* most recently created node */ | 
| Fredrik Lundh | 8c8836b | 2005-12-16 22:06:06 +0000 | [diff] [blame] | 2400 |  | 
| Eli Bendersky | 58d548d | 2012-05-29 15:45:16 +0300 | [diff] [blame] | 2401 |     PyObject *data; /* data collector (string or list), or NULL */ | 
| Fredrik Lundh | 8c8836b | 2005-12-16 22:06:06 +0000 | [diff] [blame] | 2402 |  | 
| Eli Bendersky | 58d548d | 2012-05-29 15:45:16 +0300 | [diff] [blame] | 2403 |     PyObject *stack; /* element stack */ | 
 | 2404 |     Py_ssize_t index; /* current stack size (0 means empty) */ | 
| Fredrik Lundh | 8c8836b | 2005-12-16 22:06:06 +0000 | [diff] [blame] | 2405 |  | 
| Eli Bendersky | 48d358b | 2012-05-30 17:57:50 +0300 | [diff] [blame] | 2406 |     PyObject *element_factory; | 
| Stefan Behnel | 43851a2 | 2019-05-01 21:20:38 +0200 | [diff] [blame] | 2407 |     PyObject *comment_factory; | 
 | 2408 |     PyObject *pi_factory; | 
| Eli Bendersky | 48d358b | 2012-05-30 17:57:50 +0300 | [diff] [blame] | 2409 |  | 
| Fredrik Lundh | 8c8836b | 2005-12-16 22:06:06 +0000 | [diff] [blame] | 2410 |     /* element tracing */ | 
| Serhiy Storchaka | 9ec5e25 | 2015-12-07 02:31:11 +0200 | [diff] [blame] | 2411 |     PyObject *events_append; /* the append method of the list of events, or NULL */ | 
| Eli Bendersky | 58d548d | 2012-05-29 15:45:16 +0300 | [diff] [blame] | 2412 |     PyObject *start_event_obj; /* event objects (NULL to ignore) */ | 
 | 2413 |     PyObject *end_event_obj; | 
 | 2414 |     PyObject *start_ns_event_obj; | 
 | 2415 |     PyObject *end_ns_event_obj; | 
| Stefan Behnel | 43851a2 | 2019-05-01 21:20:38 +0200 | [diff] [blame] | 2416 |     PyObject *comment_event_obj; | 
 | 2417 |     PyObject *pi_event_obj; | 
 | 2418 |  | 
 | 2419 |     char insert_comments; | 
 | 2420 |     char insert_pis; | 
| Fredrik Lundh | 8c8836b | 2005-12-16 22:06:06 +0000 | [diff] [blame] | 2421 | } TreeBuilderObject; | 
 | 2422 |  | 
| Christian Heimes | 90aa764 | 2007-12-19 02:45:37 +0000 | [diff] [blame] | 2423 | #define TreeBuilder_CheckExact(op) (Py_TYPE(op) == &TreeBuilder_Type) | 
| Fredrik Lundh | 8c8836b | 2005-12-16 22:06:06 +0000 | [diff] [blame] | 2424 |  | 
 | 2425 | /* -------------------------------------------------------------------- */ | 
 | 2426 | /* constructor and destructor */ | 
 | 2427 |  | 
| Eli Bendersky | 58d548d | 2012-05-29 15:45:16 +0300 | [diff] [blame] | 2428 | static PyObject * | 
 | 2429 | treebuilder_new(PyTypeObject *type, PyObject *args, PyObject *kwds) | 
| Fredrik Lundh | 8c8836b | 2005-12-16 22:06:06 +0000 | [diff] [blame] | 2430 | { | 
| Eli Bendersky | 58d548d | 2012-05-29 15:45:16 +0300 | [diff] [blame] | 2431 |     TreeBuilderObject *t = (TreeBuilderObject *)type->tp_alloc(type, 0); | 
 | 2432 |     if (t != NULL) { | 
 | 2433 |         t->root = NULL; | 
| Fredrik Lundh | 8c8836b | 2005-12-16 22:06:06 +0000 | [diff] [blame] | 2434 |  | 
| Eli Bendersky | 58d548d | 2012-05-29 15:45:16 +0300 | [diff] [blame] | 2435 |         Py_INCREF(Py_None); | 
| Antoine Pitrou | ee32931 | 2012-10-04 19:53:29 +0200 | [diff] [blame] | 2436 |         t->this = Py_None; | 
| Eli Bendersky | 58d548d | 2012-05-29 15:45:16 +0300 | [diff] [blame] | 2437 |         Py_INCREF(Py_None); | 
| Antoine Pitrou | ee32931 | 2012-10-04 19:53:29 +0200 | [diff] [blame] | 2438 |         t->last = Py_None; | 
| Fredrik Lundh | 8c8836b | 2005-12-16 22:06:06 +0000 | [diff] [blame] | 2439 |  | 
| Eli Bendersky | 58d548d | 2012-05-29 15:45:16 +0300 | [diff] [blame] | 2440 |         t->data = NULL; | 
| Eli Bendersky | 48d358b | 2012-05-30 17:57:50 +0300 | [diff] [blame] | 2441 |         t->element_factory = NULL; | 
| Stefan Behnel | 43851a2 | 2019-05-01 21:20:38 +0200 | [diff] [blame] | 2442 |         t->comment_factory = NULL; | 
 | 2443 |         t->pi_factory = NULL; | 
| Eli Bendersky | 58d548d | 2012-05-29 15:45:16 +0300 | [diff] [blame] | 2444 |         t->stack = PyList_New(20); | 
 | 2445 |         if (!t->stack) { | 
 | 2446 |             Py_DECREF(t->this); | 
 | 2447 |             Py_DECREF(t->last); | 
| Antoine Pitrou | c194884 | 2012-10-01 23:40:37 +0200 | [diff] [blame] | 2448 |             Py_DECREF((PyObject *) t); | 
| Eli Bendersky | 58d548d | 2012-05-29 15:45:16 +0300 | [diff] [blame] | 2449 |             return NULL; | 
 | 2450 |         } | 
 | 2451 |         t->index = 0; | 
| Fredrik Lundh | 8c8836b | 2005-12-16 22:06:06 +0000 | [diff] [blame] | 2452 |  | 
| Serhiy Storchaka | 9ec5e25 | 2015-12-07 02:31:11 +0200 | [diff] [blame] | 2453 |         t->events_append = NULL; | 
| Eli Bendersky | 58d548d | 2012-05-29 15:45:16 +0300 | [diff] [blame] | 2454 |         t->start_event_obj = t->end_event_obj = NULL; | 
 | 2455 |         t->start_ns_event_obj = t->end_ns_event_obj = NULL; | 
| Stefan Behnel | 43851a2 | 2019-05-01 21:20:38 +0200 | [diff] [blame] | 2456 |         t->comment_event_obj = t->pi_event_obj = NULL; | 
 | 2457 |         t->insert_comments = t->insert_pis = 0; | 
| Eli Bendersky | 58d548d | 2012-05-29 15:45:16 +0300 | [diff] [blame] | 2458 |     } | 
 | 2459 |     return (PyObject *)t; | 
| Fredrik Lundh | 8c8836b | 2005-12-16 22:06:06 +0000 | [diff] [blame] | 2460 | } | 
 | 2461 |  | 
| Serhiy Storchaka | cb98556 | 2015-05-04 15:32:48 +0300 | [diff] [blame] | 2462 | /*[clinic input] | 
 | 2463 | _elementtree.TreeBuilder.__init__ | 
| Eli Bendersky | 48d358b | 2012-05-30 17:57:50 +0300 | [diff] [blame] | 2464 |  | 
| Serhiy Storchaka | cb98556 | 2015-05-04 15:32:48 +0300 | [diff] [blame] | 2465 |     element_factory: object = NULL | 
| Stefan Behnel | 43851a2 | 2019-05-01 21:20:38 +0200 | [diff] [blame] | 2466 |     * | 
 | 2467 |     comment_factory: object = NULL | 
 | 2468 |     pi_factory: object = NULL | 
 | 2469 |     insert_comments: bool = False | 
 | 2470 |     insert_pis: bool = False | 
| Serhiy Storchaka | cb98556 | 2015-05-04 15:32:48 +0300 | [diff] [blame] | 2471 |  | 
 | 2472 | [clinic start generated code]*/ | 
 | 2473 |  | 
 | 2474 | static int | 
 | 2475 | _elementtree_TreeBuilder___init___impl(TreeBuilderObject *self, | 
| Stefan Behnel | 43851a2 | 2019-05-01 21:20:38 +0200 | [diff] [blame] | 2476 |                                        PyObject *element_factory, | 
 | 2477 |                                        PyObject *comment_factory, | 
 | 2478 |                                        PyObject *pi_factory, | 
 | 2479 |                                        int insert_comments, int insert_pis) | 
 | 2480 | /*[clinic end generated code: output=8571d4dcadfdf952 input=1f967b5c245e0a71]*/ | 
| Serhiy Storchaka | cb98556 | 2015-05-04 15:32:48 +0300 | [diff] [blame] | 2481 | { | 
| Stefan Behnel | 43851a2 | 2019-05-01 21:20:38 +0200 | [diff] [blame] | 2482 |     if (element_factory && element_factory != Py_None) { | 
| Eli Bendersky | 48d358b | 2012-05-30 17:57:50 +0300 | [diff] [blame] | 2483 |         Py_INCREF(element_factory); | 
| Serhiy Storchaka | ec39756 | 2016-04-06 09:50:03 +0300 | [diff] [blame] | 2484 |         Py_XSETREF(self->element_factory, element_factory); | 
| Stefan Behnel | 43851a2 | 2019-05-01 21:20:38 +0200 | [diff] [blame] | 2485 |     } else { | 
 | 2486 |         Py_CLEAR(self->element_factory); | 
 | 2487 |     } | 
 | 2488 |  | 
 | 2489 |     if (!comment_factory || comment_factory == Py_None) { | 
 | 2490 |         elementtreestate *st = ET_STATE_GLOBAL; | 
 | 2491 |         comment_factory = st->comment_factory; | 
 | 2492 |     } | 
 | 2493 |     if (comment_factory) { | 
 | 2494 |         Py_INCREF(comment_factory); | 
 | 2495 |         Py_XSETREF(self->comment_factory, comment_factory); | 
 | 2496 |         self->insert_comments = insert_comments; | 
 | 2497 |     } else { | 
 | 2498 |         Py_CLEAR(self->comment_factory); | 
 | 2499 |         self->insert_comments = 0; | 
 | 2500 |     } | 
 | 2501 |  | 
 | 2502 |     if (!pi_factory || pi_factory == Py_None) { | 
 | 2503 |         elementtreestate *st = ET_STATE_GLOBAL; | 
 | 2504 |         pi_factory = st->pi_factory; | 
 | 2505 |     } | 
 | 2506 |     if (pi_factory) { | 
 | 2507 |         Py_INCREF(pi_factory); | 
 | 2508 |         Py_XSETREF(self->pi_factory, pi_factory); | 
 | 2509 |         self->insert_pis = insert_pis; | 
 | 2510 |     } else { | 
 | 2511 |         Py_CLEAR(self->pi_factory); | 
 | 2512 |         self->insert_pis = 0; | 
| Eli Bendersky | 48d358b | 2012-05-30 17:57:50 +0300 | [diff] [blame] | 2513 |     } | 
 | 2514 |  | 
| Eli Bendersky | 58d548d | 2012-05-29 15:45:16 +0300 | [diff] [blame] | 2515 |     return 0; | 
| Fredrik Lundh | 8c8836b | 2005-12-16 22:06:06 +0000 | [diff] [blame] | 2516 | } | 
 | 2517 |  | 
| Eli Bendersky | 48d358b | 2012-05-30 17:57:50 +0300 | [diff] [blame] | 2518 | static int | 
 | 2519 | treebuilder_gc_traverse(TreeBuilderObject *self, visitproc visit, void *arg) | 
 | 2520 | { | 
| Stefan Behnel | 43851a2 | 2019-05-01 21:20:38 +0200 | [diff] [blame] | 2521 |     Py_VISIT(self->pi_event_obj); | 
 | 2522 |     Py_VISIT(self->comment_event_obj); | 
| Serhiy Storchaka | d2a75c6 | 2018-12-18 22:29:14 +0200 | [diff] [blame] | 2523 |     Py_VISIT(self->end_ns_event_obj); | 
 | 2524 |     Py_VISIT(self->start_ns_event_obj); | 
 | 2525 |     Py_VISIT(self->end_event_obj); | 
 | 2526 |     Py_VISIT(self->start_event_obj); | 
 | 2527 |     Py_VISIT(self->events_append); | 
| Eli Bendersky | 48d358b | 2012-05-30 17:57:50 +0300 | [diff] [blame] | 2528 |     Py_VISIT(self->root); | 
 | 2529 |     Py_VISIT(self->this); | 
 | 2530 |     Py_VISIT(self->last); | 
 | 2531 |     Py_VISIT(self->data); | 
 | 2532 |     Py_VISIT(self->stack); | 
| Stefan Behnel | 43851a2 | 2019-05-01 21:20:38 +0200 | [diff] [blame] | 2533 |     Py_VISIT(self->pi_factory); | 
 | 2534 |     Py_VISIT(self->comment_factory); | 
| Eli Bendersky | 48d358b | 2012-05-30 17:57:50 +0300 | [diff] [blame] | 2535 |     Py_VISIT(self->element_factory); | 
 | 2536 |     return 0; | 
 | 2537 | } | 
 | 2538 |  | 
 | 2539 | static int | 
 | 2540 | treebuilder_gc_clear(TreeBuilderObject *self) | 
| Fredrik Lundh | 8c8836b | 2005-12-16 22:06:06 +0000 | [diff] [blame] | 2541 | { | 
| Stefan Behnel | 43851a2 | 2019-05-01 21:20:38 +0200 | [diff] [blame] | 2542 |     Py_CLEAR(self->pi_event_obj); | 
 | 2543 |     Py_CLEAR(self->comment_event_obj); | 
| Antoine Pitrou | c194884 | 2012-10-01 23:40:37 +0200 | [diff] [blame] | 2544 |     Py_CLEAR(self->end_ns_event_obj); | 
 | 2545 |     Py_CLEAR(self->start_ns_event_obj); | 
 | 2546 |     Py_CLEAR(self->end_event_obj); | 
 | 2547 |     Py_CLEAR(self->start_event_obj); | 
| Serhiy Storchaka | 9ec5e25 | 2015-12-07 02:31:11 +0200 | [diff] [blame] | 2548 |     Py_CLEAR(self->events_append); | 
| Antoine Pitrou | c194884 | 2012-10-01 23:40:37 +0200 | [diff] [blame] | 2549 |     Py_CLEAR(self->stack); | 
 | 2550 |     Py_CLEAR(self->data); | 
 | 2551 |     Py_CLEAR(self->last); | 
 | 2552 |     Py_CLEAR(self->this); | 
| Stefan Behnel | 43851a2 | 2019-05-01 21:20:38 +0200 | [diff] [blame] | 2553 |     Py_CLEAR(self->pi_factory); | 
 | 2554 |     Py_CLEAR(self->comment_factory); | 
| Eli Bendersky | 48d358b | 2012-05-30 17:57:50 +0300 | [diff] [blame] | 2555 |     Py_CLEAR(self->element_factory); | 
| Antoine Pitrou | c194884 | 2012-10-01 23:40:37 +0200 | [diff] [blame] | 2556 |     Py_CLEAR(self->root); | 
| Eli Bendersky | 48d358b | 2012-05-30 17:57:50 +0300 | [diff] [blame] | 2557 |     return 0; | 
 | 2558 | } | 
| Fredrik Lundh | 8c8836b | 2005-12-16 22:06:06 +0000 | [diff] [blame] | 2559 |  | 
| Eli Bendersky | 48d358b | 2012-05-30 17:57:50 +0300 | [diff] [blame] | 2560 | static void | 
 | 2561 | treebuilder_dealloc(TreeBuilderObject *self) | 
 | 2562 | { | 
 | 2563 |     PyObject_GC_UnTrack(self); | 
 | 2564 |     treebuilder_gc_clear(self); | 
| Eli Bendersky | 58d548d | 2012-05-29 15:45:16 +0300 | [diff] [blame] | 2565 |     Py_TYPE(self)->tp_free((PyObject *)self); | 
| Fredrik Lundh | 8c8836b | 2005-12-16 22:06:06 +0000 | [diff] [blame] | 2566 | } | 
 | 2567 |  | 
 | 2568 | /* -------------------------------------------------------------------- */ | 
| Antoine Pitrou | ee32931 | 2012-10-04 19:53:29 +0200 | [diff] [blame] | 2569 | /* helpers for handling of arbitrary element-like objects */ | 
 | 2570 |  | 
| Stefan Behnel | 43851a2 | 2019-05-01 21:20:38 +0200 | [diff] [blame] | 2571 | /*[clinic input] | 
 | 2572 | _elementtree._set_factories | 
 | 2573 |  | 
 | 2574 |     comment_factory: object | 
 | 2575 |     pi_factory: object | 
 | 2576 |     / | 
 | 2577 |  | 
 | 2578 | Change the factories used to create comments and processing instructions. | 
 | 2579 |  | 
 | 2580 | For internal use only. | 
 | 2581 | [clinic start generated code]*/ | 
 | 2582 |  | 
 | 2583 | static PyObject * | 
 | 2584 | _elementtree__set_factories_impl(PyObject *module, PyObject *comment_factory, | 
 | 2585 |                                  PyObject *pi_factory) | 
 | 2586 | /*[clinic end generated code: output=813b408adee26535 input=99d17627aea7fb3b]*/ | 
 | 2587 | { | 
 | 2588 |     elementtreestate *st = ET_STATE_GLOBAL; | 
 | 2589 |     PyObject *old; | 
 | 2590 |  | 
 | 2591 |     if (!PyCallable_Check(comment_factory) && comment_factory != Py_None) { | 
 | 2592 |         PyErr_Format(PyExc_TypeError, "Comment factory must be callable, not %.100s", | 
 | 2593 |                      Py_TYPE(comment_factory)->tp_name); | 
 | 2594 |         return NULL; | 
 | 2595 |     } | 
 | 2596 |     if (!PyCallable_Check(pi_factory) && pi_factory != Py_None) { | 
 | 2597 |         PyErr_Format(PyExc_TypeError, "PI factory must be callable, not %.100s", | 
 | 2598 |                      Py_TYPE(pi_factory)->tp_name); | 
 | 2599 |         return NULL; | 
 | 2600 |     } | 
 | 2601 |  | 
 | 2602 |     old = PyTuple_Pack(2, | 
 | 2603 |         st->comment_factory ? st->comment_factory : Py_None, | 
 | 2604 |         st->pi_factory ? st->pi_factory : Py_None); | 
 | 2605 |  | 
 | 2606 |     if (comment_factory == Py_None) { | 
 | 2607 |         Py_CLEAR(st->comment_factory); | 
 | 2608 |     } else { | 
 | 2609 |         Py_INCREF(comment_factory); | 
 | 2610 |         Py_XSETREF(st->comment_factory, comment_factory); | 
 | 2611 |     } | 
 | 2612 |     if (pi_factory == Py_None) { | 
 | 2613 |         Py_CLEAR(st->pi_factory); | 
 | 2614 |     } else { | 
 | 2615 |         Py_INCREF(pi_factory); | 
 | 2616 |         Py_XSETREF(st->pi_factory, pi_factory); | 
 | 2617 |     } | 
 | 2618 |  | 
 | 2619 |     return old; | 
 | 2620 | } | 
 | 2621 |  | 
| Antoine Pitrou | ee32931 | 2012-10-04 19:53:29 +0200 | [diff] [blame] | 2622 | static int | 
| Serhiy Storchaka | 576def0 | 2017-03-30 09:47:31 +0300 | [diff] [blame] | 2623 | treebuilder_set_element_text_or_tail(PyObject *element, PyObject **data, | 
| Antoine Pitrou | ee32931 | 2012-10-04 19:53:29 +0200 | [diff] [blame] | 2624 |                                      PyObject **dest, _Py_Identifier *name) | 
 | 2625 | { | 
 | 2626 |     if (Element_CheckExact(element)) { | 
| Serhiy Storchaka | 576def0 | 2017-03-30 09:47:31 +0300 | [diff] [blame] | 2627 |         PyObject *tmp = JOIN_OBJ(*dest); | 
 | 2628 |         *dest = JOIN_SET(*data, PyList_CheckExact(*data)); | 
 | 2629 |         *data = NULL; | 
 | 2630 |         Py_DECREF(tmp); | 
| Antoine Pitrou | ee32931 | 2012-10-04 19:53:29 +0200 | [diff] [blame] | 2631 |         return 0; | 
 | 2632 |     } | 
 | 2633 |     else { | 
| Serhiy Storchaka | 576def0 | 2017-03-30 09:47:31 +0300 | [diff] [blame] | 2634 |         PyObject *joined = list_join(*data); | 
| Antoine Pitrou | ee32931 | 2012-10-04 19:53:29 +0200 | [diff] [blame] | 2635 |         int r; | 
 | 2636 |         if (joined == NULL) | 
 | 2637 |             return -1; | 
 | 2638 |         r = _PyObject_SetAttrId(element, name, joined); | 
 | 2639 |         Py_DECREF(joined); | 
| Serhiy Storchaka | 576def0 | 2017-03-30 09:47:31 +0300 | [diff] [blame] | 2640 |         if (r < 0) | 
 | 2641 |             return -1; | 
 | 2642 |         Py_CLEAR(*data); | 
 | 2643 |         return 0; | 
| Antoine Pitrou | ee32931 | 2012-10-04 19:53:29 +0200 | [diff] [blame] | 2644 |     } | 
 | 2645 | } | 
 | 2646 |  | 
| Serhiy Storchaka | 576def0 | 2017-03-30 09:47:31 +0300 | [diff] [blame] | 2647 | LOCAL(int) | 
 | 2648 | treebuilder_flush_data(TreeBuilderObject* self) | 
| Antoine Pitrou | ee32931 | 2012-10-04 19:53:29 +0200 | [diff] [blame] | 2649 | { | 
| Serhiy Storchaka | 576def0 | 2017-03-30 09:47:31 +0300 | [diff] [blame] | 2650 |     PyObject *element = self->last; | 
| Antoine Pitrou | ee32931 | 2012-10-04 19:53:29 +0200 | [diff] [blame] | 2651 |  | 
| Serhiy Storchaka | 576def0 | 2017-03-30 09:47:31 +0300 | [diff] [blame] | 2652 |     if (!self->data) { | 
 | 2653 |         return 0; | 
 | 2654 |     } | 
 | 2655 |  | 
 | 2656 |     if (self->this == element) { | 
 | 2657 |         _Py_IDENTIFIER(text); | 
 | 2658 |         return treebuilder_set_element_text_or_tail( | 
 | 2659 |                 element, &self->data, | 
 | 2660 |                 &((ElementObject *) element)->text, &PyId_text); | 
 | 2661 |     } | 
 | 2662 |     else { | 
 | 2663 |         _Py_IDENTIFIER(tail); | 
 | 2664 |         return treebuilder_set_element_text_or_tail( | 
 | 2665 |                 element, &self->data, | 
 | 2666 |                 &((ElementObject *) element)->tail, &PyId_tail); | 
 | 2667 |     } | 
| Antoine Pitrou | ee32931 | 2012-10-04 19:53:29 +0200 | [diff] [blame] | 2668 | } | 
 | 2669 |  | 
 | 2670 | static int | 
 | 2671 | treebuilder_add_subelement(PyObject *element, PyObject *child) | 
 | 2672 | { | 
 | 2673 |     _Py_IDENTIFIER(append); | 
 | 2674 |     if (Element_CheckExact(element)) { | 
 | 2675 |         ElementObject *elem = (ElementObject *) element; | 
 | 2676 |         return element_add_subelement(elem, child); | 
 | 2677 |     } | 
 | 2678 |     else { | 
 | 2679 |         PyObject *res; | 
| Victor Stinner | f561634 | 2016-12-09 15:26:00 +0100 | [diff] [blame] | 2680 |         res = _PyObject_CallMethodIdObjArgs(element, &PyId_append, child, NULL); | 
| Antoine Pitrou | ee32931 | 2012-10-04 19:53:29 +0200 | [diff] [blame] | 2681 |         if (res == NULL) | 
 | 2682 |             return -1; | 
 | 2683 |         Py_DECREF(res); | 
 | 2684 |         return 0; | 
 | 2685 |     } | 
 | 2686 | } | 
 | 2687 |  | 
| Serhiy Storchaka | 7efaf95 | 2015-12-06 23:51:44 +0200 | [diff] [blame] | 2688 | LOCAL(int) | 
 | 2689 | treebuilder_append_event(TreeBuilderObject *self, PyObject *action, | 
 | 2690 |                          PyObject *node) | 
 | 2691 | { | 
 | 2692 |     if (action != NULL) { | 
| Serhiy Storchaka | 9ec5e25 | 2015-12-07 02:31:11 +0200 | [diff] [blame] | 2693 |         PyObject *res; | 
 | 2694 |         PyObject *event = PyTuple_Pack(2, action, node); | 
 | 2695 |         if (event == NULL) | 
 | 2696 |             return -1; | 
| Stefan Behnel | 43851a2 | 2019-05-01 21:20:38 +0200 | [diff] [blame] | 2697 |         res = _PyObject_FastCall(self->events_append, &event, 1); | 
| Serhiy Storchaka | 9ec5e25 | 2015-12-07 02:31:11 +0200 | [diff] [blame] | 2698 |         Py_DECREF(event); | 
| Serhiy Storchaka | 7efaf95 | 2015-12-06 23:51:44 +0200 | [diff] [blame] | 2699 |         if (res == NULL) | 
 | 2700 |             return -1; | 
| Serhiy Storchaka | 7efaf95 | 2015-12-06 23:51:44 +0200 | [diff] [blame] | 2701 |         Py_DECREF(res); | 
 | 2702 |     } | 
 | 2703 |     return 0; | 
 | 2704 | } | 
 | 2705 |  | 
| Antoine Pitrou | ee32931 | 2012-10-04 19:53:29 +0200 | [diff] [blame] | 2706 | /* -------------------------------------------------------------------- */ | 
| Fredrik Lundh | 8c8836b | 2005-12-16 22:06:06 +0000 | [diff] [blame] | 2707 | /* handlers */ | 
 | 2708 |  | 
 | 2709 | LOCAL(PyObject*) | 
| Fredrik Lundh | 8c8836b | 2005-12-16 22:06:06 +0000 | [diff] [blame] | 2710 | treebuilder_handle_start(TreeBuilderObject* self, PyObject* tag, | 
 | 2711 |                          PyObject* attrib) | 
 | 2712 | { | 
 | 2713 |     PyObject* node; | 
 | 2714 |     PyObject* this; | 
| Eli Bendersky | 532d03e | 2013-08-10 08:00:39 -0700 | [diff] [blame] | 2715 |     elementtreestate *st = ET_STATE_GLOBAL; | 
| Fredrik Lundh | 8c8836b | 2005-12-16 22:06:06 +0000 | [diff] [blame] | 2716 |  | 
| Serhiy Storchaka | 576def0 | 2017-03-30 09:47:31 +0300 | [diff] [blame] | 2717 |     if (treebuilder_flush_data(self) < 0) { | 
 | 2718 |         return NULL; | 
| Fredrik Lundh | 8c8836b | 2005-12-16 22:06:06 +0000 | [diff] [blame] | 2719 |     } | 
 | 2720 |  | 
| Stefan Behnel | 43851a2 | 2019-05-01 21:20:38 +0200 | [diff] [blame] | 2721 |     if (!self->element_factory) { | 
| Eli Bendersky | 48d358b | 2012-05-30 17:57:50 +0300 | [diff] [blame] | 2722 |         node = create_new_element(tag, attrib); | 
| Serhiy Storchaka | 36ff997 | 2015-12-10 09:51:53 +0200 | [diff] [blame] | 2723 |     } else if (attrib == Py_None) { | 
 | 2724 |         attrib = PyDict_New(); | 
 | 2725 |         if (!attrib) | 
 | 2726 |             return NULL; | 
| Victor Stinner | 5abaa2b | 2016-12-09 16:22:32 +0100 | [diff] [blame] | 2727 |         node = PyObject_CallFunctionObjArgs(self->element_factory, | 
 | 2728 |                                             tag, attrib, NULL); | 
| Serhiy Storchaka | 36ff997 | 2015-12-10 09:51:53 +0200 | [diff] [blame] | 2729 |         Py_DECREF(attrib); | 
 | 2730 |     } | 
 | 2731 |     else { | 
| Victor Stinner | 5abaa2b | 2016-12-09 16:22:32 +0100 | [diff] [blame] | 2732 |         node = PyObject_CallFunctionObjArgs(self->element_factory, | 
 | 2733 |                                             tag, attrib, NULL); | 
| Eli Bendersky | 48d358b | 2012-05-30 17:57:50 +0300 | [diff] [blame] | 2734 |     } | 
 | 2735 |     if (!node) { | 
| Fredrik Lundh | 8c8836b | 2005-12-16 22:06:06 +0000 | [diff] [blame] | 2736 |         return NULL; | 
| Eli Bendersky | 48d358b | 2012-05-30 17:57:50 +0300 | [diff] [blame] | 2737 |     } | 
| Fredrik Lundh | 8c8836b | 2005-12-16 22:06:06 +0000 | [diff] [blame] | 2738 |  | 
| Antoine Pitrou | ee32931 | 2012-10-04 19:53:29 +0200 | [diff] [blame] | 2739 |     this = self->this; | 
| Fredrik Lundh | 8c8836b | 2005-12-16 22:06:06 +0000 | [diff] [blame] | 2740 |  | 
 | 2741 |     if (this != Py_None) { | 
| Antoine Pitrou | ee32931 | 2012-10-04 19:53:29 +0200 | [diff] [blame] | 2742 |         if (treebuilder_add_subelement(this, node) < 0) | 
| Fredrik Lundh | 44ed4db | 2006-03-12 21:06:35 +0000 | [diff] [blame] | 2743 |             goto error; | 
| Fredrik Lundh | 8c8836b | 2005-12-16 22:06:06 +0000 | [diff] [blame] | 2744 |     } else { | 
 | 2745 |         if (self->root) { | 
 | 2746 |             PyErr_SetString( | 
| Eli Bendersky | 532d03e | 2013-08-10 08:00:39 -0700 | [diff] [blame] | 2747 |                 st->parseerror_obj, | 
| Fredrik Lundh | 8c8836b | 2005-12-16 22:06:06 +0000 | [diff] [blame] | 2748 |                 "multiple elements on top level" | 
 | 2749 |                 ); | 
| Fredrik Lundh | 44ed4db | 2006-03-12 21:06:35 +0000 | [diff] [blame] | 2750 |             goto error; | 
| Fredrik Lundh | 8c8836b | 2005-12-16 22:06:06 +0000 | [diff] [blame] | 2751 |         } | 
 | 2752 |         Py_INCREF(node); | 
 | 2753 |         self->root = node; | 
 | 2754 |     } | 
 | 2755 |  | 
 | 2756 |     if (self->index < PyList_GET_SIZE(self->stack)) { | 
 | 2757 |         if (PyList_SetItem(self->stack, self->index, this) < 0) | 
| Fredrik Lundh | 44ed4db | 2006-03-12 21:06:35 +0000 | [diff] [blame] | 2758 |             goto error; | 
| Fredrik Lundh | 8c8836b | 2005-12-16 22:06:06 +0000 | [diff] [blame] | 2759 |         Py_INCREF(this); | 
 | 2760 |     } else { | 
 | 2761 |         if (PyList_Append(self->stack, this) < 0) | 
| Fredrik Lundh | 44ed4db | 2006-03-12 21:06:35 +0000 | [diff] [blame] | 2762 |             goto error; | 
| Fredrik Lundh | 8c8836b | 2005-12-16 22:06:06 +0000 | [diff] [blame] | 2763 |     } | 
 | 2764 |     self->index++; | 
 | 2765 |  | 
| Fredrik Lundh | 8c8836b | 2005-12-16 22:06:06 +0000 | [diff] [blame] | 2766 |     Py_INCREF(node); | 
| Serhiy Storchaka | 57a01d3 | 2016-04-10 18:05:40 +0300 | [diff] [blame] | 2767 |     Py_SETREF(self->this, node); | 
| Fredrik Lundh | 8c8836b | 2005-12-16 22:06:06 +0000 | [diff] [blame] | 2768 |     Py_INCREF(node); | 
| Serhiy Storchaka | 57a01d3 | 2016-04-10 18:05:40 +0300 | [diff] [blame] | 2769 |     Py_SETREF(self->last, node); | 
| Fredrik Lundh | 8c8836b | 2005-12-16 22:06:06 +0000 | [diff] [blame] | 2770 |  | 
| Serhiy Storchaka | 7efaf95 | 2015-12-06 23:51:44 +0200 | [diff] [blame] | 2771 |     if (treebuilder_append_event(self, self->start_event_obj, node) < 0) | 
 | 2772 |         goto error; | 
| Fredrik Lundh | 8c8836b | 2005-12-16 22:06:06 +0000 | [diff] [blame] | 2773 |  | 
 | 2774 |     return node; | 
| Fredrik Lundh | 44ed4db | 2006-03-12 21:06:35 +0000 | [diff] [blame] | 2775 |  | 
 | 2776 |   error: | 
 | 2777 |     Py_DECREF(node); | 
 | 2778 |     return NULL; | 
| Fredrik Lundh | 8c8836b | 2005-12-16 22:06:06 +0000 | [diff] [blame] | 2779 | } | 
 | 2780 |  | 
 | 2781 | LOCAL(PyObject*) | 
 | 2782 | treebuilder_handle_data(TreeBuilderObject* self, PyObject* data) | 
 | 2783 | { | 
 | 2784 |     if (!self->data) { | 
| Antoine Pitrou | ee32931 | 2012-10-04 19:53:29 +0200 | [diff] [blame] | 2785 |         if (self->last == Py_None) { | 
| Thomas Wouters | 00ee7ba | 2006-08-21 19:07:27 +0000 | [diff] [blame] | 2786 |             /* ignore calls to data before the first call to start */ | 
 | 2787 |             Py_RETURN_NONE; | 
 | 2788 |         } | 
| Fredrik Lundh | 8c8836b | 2005-12-16 22:06:06 +0000 | [diff] [blame] | 2789 |         /* store the first item as is */ | 
 | 2790 |         Py_INCREF(data); self->data = data; | 
 | 2791 |     } else { | 
 | 2792 |         /* more than one item; use a list to collect items */ | 
| Christian Heimes | 72b710a | 2008-05-26 13:28:38 +0000 | [diff] [blame] | 2793 |         if (PyBytes_CheckExact(self->data) && Py_REFCNT(self->data) == 1 && | 
 | 2794 |             PyBytes_CheckExact(data) && PyBytes_GET_SIZE(data) == 1) { | 
| Antoine Pitrou | c194884 | 2012-10-01 23:40:37 +0200 | [diff] [blame] | 2795 |             /* XXX this code path unused in Python 3? */ | 
| Fredrik Lundh | 8c8836b | 2005-12-16 22:06:06 +0000 | [diff] [blame] | 2796 |             /* expat often generates single character data sections; handle | 
 | 2797 |                the most common case by resizing the existing string... */ | 
| Christian Heimes | 72b710a | 2008-05-26 13:28:38 +0000 | [diff] [blame] | 2798 |             Py_ssize_t size = PyBytes_GET_SIZE(self->data); | 
 | 2799 |             if (_PyBytes_Resize(&self->data, size + 1) < 0) | 
| Fredrik Lundh | 8c8836b | 2005-12-16 22:06:06 +0000 | [diff] [blame] | 2800 |                 return NULL; | 
| Christian Heimes | 72b710a | 2008-05-26 13:28:38 +0000 | [diff] [blame] | 2801 |             PyBytes_AS_STRING(self->data)[size] = PyBytes_AS_STRING(data)[0]; | 
| Fredrik Lundh | 8c8836b | 2005-12-16 22:06:06 +0000 | [diff] [blame] | 2802 |         } else if (PyList_CheckExact(self->data)) { | 
 | 2803 |             if (PyList_Append(self->data, data) < 0) | 
 | 2804 |                 return NULL; | 
 | 2805 |         } else { | 
 | 2806 |             PyObject* list = PyList_New(2); | 
 | 2807 |             if (!list) | 
 | 2808 |                 return NULL; | 
 | 2809 |             PyList_SET_ITEM(list, 0, self->data); | 
 | 2810 |             Py_INCREF(data); PyList_SET_ITEM(list, 1, data); | 
 | 2811 |             self->data = list; | 
 | 2812 |         } | 
 | 2813 |     } | 
 | 2814 |  | 
 | 2815 |     Py_RETURN_NONE; | 
 | 2816 | } | 
 | 2817 |  | 
 | 2818 | LOCAL(PyObject*) | 
 | 2819 | treebuilder_handle_end(TreeBuilderObject* self, PyObject* tag) | 
 | 2820 | { | 
 | 2821 |     PyObject* item; | 
 | 2822 |  | 
| Serhiy Storchaka | 576def0 | 2017-03-30 09:47:31 +0300 | [diff] [blame] | 2823 |     if (treebuilder_flush_data(self) < 0) { | 
 | 2824 |         return NULL; | 
| Fredrik Lundh | 8c8836b | 2005-12-16 22:06:06 +0000 | [diff] [blame] | 2825 |     } | 
 | 2826 |  | 
 | 2827 |     if (self->index == 0) { | 
 | 2828 |         PyErr_SetString( | 
 | 2829 |             PyExc_IndexError, | 
 | 2830 |             "pop from empty stack" | 
 | 2831 |             ); | 
 | 2832 |         return NULL; | 
 | 2833 |     } | 
 | 2834 |  | 
| Serhiy Storchaka | 191321d | 2015-12-27 15:41:34 +0200 | [diff] [blame] | 2835 |     item = self->last; | 
| Antoine Pitrou | ee32931 | 2012-10-04 19:53:29 +0200 | [diff] [blame] | 2836 |     self->last = self->this; | 
| Serhiy Storchaka | 191321d | 2015-12-27 15:41:34 +0200 | [diff] [blame] | 2837 |     self->index--; | 
 | 2838 |     self->this = PyList_GET_ITEM(self->stack, self->index); | 
 | 2839 |     Py_INCREF(self->this); | 
 | 2840 |     Py_DECREF(item); | 
| Fredrik Lundh | 8c8836b | 2005-12-16 22:06:06 +0000 | [diff] [blame] | 2841 |  | 
| Serhiy Storchaka | 7efaf95 | 2015-12-06 23:51:44 +0200 | [diff] [blame] | 2842 |     if (treebuilder_append_event(self, self->end_event_obj, self->last) < 0) | 
 | 2843 |         return NULL; | 
| Fredrik Lundh | 8c8836b | 2005-12-16 22:06:06 +0000 | [diff] [blame] | 2844 |  | 
 | 2845 |     Py_INCREF(self->last); | 
 | 2846 |     return (PyObject*) self->last; | 
 | 2847 | } | 
 | 2848 |  | 
| Stefan Behnel | 43851a2 | 2019-05-01 21:20:38 +0200 | [diff] [blame] | 2849 | LOCAL(PyObject*) | 
 | 2850 | treebuilder_handle_comment(TreeBuilderObject* self, PyObject* text) | 
 | 2851 | { | 
 | 2852 |     PyObject* comment = NULL; | 
 | 2853 |     PyObject* this; | 
 | 2854 |  | 
 | 2855 |     if (treebuilder_flush_data(self) < 0) { | 
 | 2856 |         return NULL; | 
 | 2857 |     } | 
 | 2858 |  | 
 | 2859 |     if (self->comment_factory) { | 
 | 2860 |         comment = _PyObject_FastCall(self->comment_factory, &text, 1); | 
 | 2861 |         if (!comment) | 
 | 2862 |             return NULL; | 
 | 2863 |  | 
 | 2864 |         this = self->this; | 
 | 2865 |         if (self->insert_comments && this != Py_None) { | 
 | 2866 |             if (treebuilder_add_subelement(this, comment) < 0) | 
 | 2867 |                 goto error; | 
 | 2868 |         } | 
 | 2869 |     } else { | 
 | 2870 |         Py_INCREF(text); | 
 | 2871 |         comment = text; | 
 | 2872 |     } | 
 | 2873 |  | 
 | 2874 |     if (self->events_append && self->comment_event_obj) { | 
 | 2875 |         if (treebuilder_append_event(self, self->comment_event_obj, comment) < 0) | 
 | 2876 |             goto error; | 
 | 2877 |     } | 
 | 2878 |  | 
 | 2879 |     return comment; | 
 | 2880 |  | 
 | 2881 |   error: | 
 | 2882 |     Py_DECREF(comment); | 
 | 2883 |     return NULL; | 
 | 2884 | } | 
 | 2885 |  | 
 | 2886 | LOCAL(PyObject*) | 
 | 2887 | treebuilder_handle_pi(TreeBuilderObject* self, PyObject* target, PyObject* text) | 
 | 2888 | { | 
 | 2889 |     PyObject* pi = NULL; | 
 | 2890 |     PyObject* this; | 
 | 2891 |     PyObject* stack[2] = {target, text}; | 
 | 2892 |  | 
 | 2893 |     if (treebuilder_flush_data(self) < 0) { | 
 | 2894 |         return NULL; | 
 | 2895 |     } | 
 | 2896 |  | 
 | 2897 |     if (self->pi_factory) { | 
 | 2898 |         pi = _PyObject_FastCall(self->pi_factory, stack, 2); | 
 | 2899 |         if (!pi) { | 
 | 2900 |             return NULL; | 
 | 2901 |         } | 
 | 2902 |  | 
 | 2903 |         this = self->this; | 
 | 2904 |         if (self->insert_pis && this != Py_None) { | 
 | 2905 |             if (treebuilder_add_subelement(this, pi) < 0) | 
 | 2906 |                 goto error; | 
 | 2907 |         } | 
 | 2908 |     } else { | 
 | 2909 |         pi = PyTuple_Pack(2, target, text); | 
 | 2910 |         if (!pi) { | 
 | 2911 |             return NULL; | 
 | 2912 |         } | 
 | 2913 |     } | 
 | 2914 |  | 
 | 2915 |     if (self->events_append && self->pi_event_obj) { | 
 | 2916 |         if (treebuilder_append_event(self, self->pi_event_obj, pi) < 0) | 
 | 2917 |             goto error; | 
 | 2918 |     } | 
 | 2919 |  | 
 | 2920 |     return pi; | 
 | 2921 |  | 
 | 2922 |   error: | 
 | 2923 |     Py_DECREF(pi); | 
 | 2924 |     return NULL; | 
 | 2925 | } | 
 | 2926 |  | 
| Stefan Behnel | dde3eeb | 2019-05-01 21:49:58 +0200 | [diff] [blame] | 2927 | LOCAL(PyObject*) | 
 | 2928 | treebuilder_handle_start_ns(TreeBuilderObject* self, PyObject* prefix, PyObject* uri) | 
 | 2929 | { | 
 | 2930 |     PyObject* parcel; | 
 | 2931 |  | 
 | 2932 |     if (self->events_append && self->start_ns_event_obj) { | 
 | 2933 |         parcel = PyTuple_Pack(2, prefix, uri); | 
 | 2934 |         if (!parcel) { | 
 | 2935 |             return NULL; | 
 | 2936 |         } | 
 | 2937 |  | 
 | 2938 |         if (treebuilder_append_event(self, self->start_ns_event_obj, parcel) < 0) { | 
 | 2939 |             Py_DECREF(parcel); | 
 | 2940 |             return NULL; | 
 | 2941 |         } | 
 | 2942 |         Py_DECREF(parcel); | 
 | 2943 |     } | 
 | 2944 |  | 
 | 2945 |     Py_RETURN_NONE; | 
 | 2946 | } | 
 | 2947 |  | 
 | 2948 | LOCAL(PyObject*) | 
 | 2949 | treebuilder_handle_end_ns(TreeBuilderObject* self, PyObject* prefix) | 
 | 2950 | { | 
 | 2951 |     if (self->events_append && self->end_ns_event_obj) { | 
 | 2952 |         if (treebuilder_append_event(self, self->end_ns_event_obj, prefix) < 0) { | 
 | 2953 |             return NULL; | 
 | 2954 |         } | 
 | 2955 |     } | 
 | 2956 |  | 
 | 2957 |     Py_RETURN_NONE; | 
 | 2958 | } | 
 | 2959 |  | 
| Fredrik Lundh | 8c8836b | 2005-12-16 22:06:06 +0000 | [diff] [blame] | 2960 | /* -------------------------------------------------------------------- */ | 
 | 2961 | /* methods (in alphabetical order) */ | 
 | 2962 |  | 
| Serhiy Storchaka | cb98556 | 2015-05-04 15:32:48 +0300 | [diff] [blame] | 2963 | /*[clinic input] | 
 | 2964 | _elementtree.TreeBuilder.data | 
| Fredrik Lundh | 8c8836b | 2005-12-16 22:06:06 +0000 | [diff] [blame] | 2965 |  | 
| Serhiy Storchaka | cb98556 | 2015-05-04 15:32:48 +0300 | [diff] [blame] | 2966 |     data: object | 
 | 2967 |     / | 
 | 2968 |  | 
 | 2969 | [clinic start generated code]*/ | 
 | 2970 |  | 
 | 2971 | static PyObject * | 
 | 2972 | _elementtree_TreeBuilder_data(TreeBuilderObject *self, PyObject *data) | 
 | 2973 | /*[clinic end generated code: output=69144c7100795bb2 input=a0540c532b284d29]*/ | 
 | 2974 | { | 
| Fredrik Lundh | 8c8836b | 2005-12-16 22:06:06 +0000 | [diff] [blame] | 2975 |     return treebuilder_handle_data(self, data); | 
 | 2976 | } | 
 | 2977 |  | 
| Serhiy Storchaka | cb98556 | 2015-05-04 15:32:48 +0300 | [diff] [blame] | 2978 | /*[clinic input] | 
 | 2979 | _elementtree.TreeBuilder.end | 
| Fredrik Lundh | 8c8836b | 2005-12-16 22:06:06 +0000 | [diff] [blame] | 2980 |  | 
| Serhiy Storchaka | cb98556 | 2015-05-04 15:32:48 +0300 | [diff] [blame] | 2981 |     tag: object | 
 | 2982 |     / | 
 | 2983 |  | 
 | 2984 | [clinic start generated code]*/ | 
 | 2985 |  | 
 | 2986 | static PyObject * | 
 | 2987 | _elementtree_TreeBuilder_end(TreeBuilderObject *self, PyObject *tag) | 
 | 2988 | /*[clinic end generated code: output=9a98727cc691cd9d input=22dc3674236f5745]*/ | 
 | 2989 | { | 
| Fredrik Lundh | 8c8836b | 2005-12-16 22:06:06 +0000 | [diff] [blame] | 2990 |     return treebuilder_handle_end(self, tag); | 
 | 2991 | } | 
 | 2992 |  | 
| Stefan Behnel | 43851a2 | 2019-05-01 21:20:38 +0200 | [diff] [blame] | 2993 | /*[clinic input] | 
 | 2994 | _elementtree.TreeBuilder.comment | 
 | 2995 |  | 
 | 2996 |     text: object | 
 | 2997 |     / | 
 | 2998 |  | 
 | 2999 | [clinic start generated code]*/ | 
 | 3000 |  | 
 | 3001 | static PyObject * | 
 | 3002 | _elementtree_TreeBuilder_comment(TreeBuilderObject *self, PyObject *text) | 
 | 3003 | /*[clinic end generated code: output=22835be41deeaa27 input=47e7ebc48ed01dfa]*/ | 
 | 3004 | { | 
 | 3005 |     return treebuilder_handle_comment(self, text); | 
 | 3006 | } | 
 | 3007 |  | 
 | 3008 | /*[clinic input] | 
 | 3009 | _elementtree.TreeBuilder.pi | 
 | 3010 |  | 
 | 3011 |     target: object | 
 | 3012 |     text: object = None | 
 | 3013 |     / | 
 | 3014 |  | 
 | 3015 | [clinic start generated code]*/ | 
 | 3016 |  | 
 | 3017 | static PyObject * | 
 | 3018 | _elementtree_TreeBuilder_pi_impl(TreeBuilderObject *self, PyObject *target, | 
 | 3019 |                                  PyObject *text) | 
 | 3020 | /*[clinic end generated code: output=21eb95ec9d04d1d9 input=349342bd79c35570]*/ | 
 | 3021 | { | 
 | 3022 |     return treebuilder_handle_pi(self, target, text); | 
 | 3023 | } | 
 | 3024 |  | 
| Fredrik Lundh | 8c8836b | 2005-12-16 22:06:06 +0000 | [diff] [blame] | 3025 | LOCAL(PyObject*) | 
 | 3026 | treebuilder_done(TreeBuilderObject* self) | 
 | 3027 | { | 
 | 3028 |     PyObject* res; | 
 | 3029 |  | 
 | 3030 |     /* FIXME: check stack size? */ | 
 | 3031 |  | 
 | 3032 |     if (self->root) | 
 | 3033 |         res = self->root; | 
 | 3034 |     else | 
 | 3035 |         res = Py_None; | 
 | 3036 |  | 
 | 3037 |     Py_INCREF(res); | 
 | 3038 |     return res; | 
 | 3039 | } | 
 | 3040 |  | 
| Serhiy Storchaka | cb98556 | 2015-05-04 15:32:48 +0300 | [diff] [blame] | 3041 | /*[clinic input] | 
 | 3042 | _elementtree.TreeBuilder.close | 
| Fredrik Lundh | 8c8836b | 2005-12-16 22:06:06 +0000 | [diff] [blame] | 3043 |  | 
| Serhiy Storchaka | cb98556 | 2015-05-04 15:32:48 +0300 | [diff] [blame] | 3044 | [clinic start generated code]*/ | 
 | 3045 |  | 
 | 3046 | static PyObject * | 
 | 3047 | _elementtree_TreeBuilder_close_impl(TreeBuilderObject *self) | 
 | 3048 | /*[clinic end generated code: output=b441fee3202f61ee input=f7c9c65dc718de14]*/ | 
 | 3049 | { | 
| Fredrik Lundh | 8c8836b | 2005-12-16 22:06:06 +0000 | [diff] [blame] | 3050 |     return treebuilder_done(self); | 
 | 3051 | } | 
 | 3052 |  | 
| Serhiy Storchaka | cb98556 | 2015-05-04 15:32:48 +0300 | [diff] [blame] | 3053 | /*[clinic input] | 
 | 3054 | _elementtree.TreeBuilder.start | 
 | 3055 |  | 
 | 3056 |     tag: object | 
 | 3057 |     attrs: object = None | 
 | 3058 |     / | 
 | 3059 |  | 
 | 3060 | [clinic start generated code]*/ | 
 | 3061 |  | 
 | 3062 | static PyObject * | 
 | 3063 | _elementtree_TreeBuilder_start_impl(TreeBuilderObject *self, PyObject *tag, | 
 | 3064 |                                     PyObject *attrs) | 
 | 3065 | /*[clinic end generated code: output=e7e9dc2861349411 input=95fc1758dd042c65]*/ | 
| Fredrik Lundh | 8c8836b | 2005-12-16 22:06:06 +0000 | [diff] [blame] | 3066 | { | 
| Serhiy Storchaka | cb98556 | 2015-05-04 15:32:48 +0300 | [diff] [blame] | 3067 |     return treebuilder_handle_start(self, tag, attrs); | 
| Fredrik Lundh | 8c8836b | 2005-12-16 22:06:06 +0000 | [diff] [blame] | 3068 | } | 
 | 3069 |  | 
| Fredrik Lundh | 8c8836b | 2005-12-16 22:06:06 +0000 | [diff] [blame] | 3070 | /* ==================================================================== */ | 
 | 3071 | /* the expat interface */ | 
 | 3072 |  | 
| Fredrik Lundh | 8c8836b | 2005-12-16 22:06:06 +0000 | [diff] [blame] | 3073 | #include "expat.h" | 
| Fredrik Lundh | 8c8836b | 2005-12-16 22:06:06 +0000 | [diff] [blame] | 3074 | #include "pyexpat.h" | 
| Eli Bendersky | 532d03e | 2013-08-10 08:00:39 -0700 | [diff] [blame] | 3075 |  | 
 | 3076 | /* The PyExpat_CAPI structure is an immutable dispatch table, so it can be | 
 | 3077 |  * cached globally without being in per-module state. | 
 | 3078 |  */ | 
| Eli Bendersky | 20d4174 | 2012-06-01 09:48:37 +0300 | [diff] [blame] | 3079 | static struct PyExpat_CAPI *expat_capi; | 
| Fredrik Lundh | 8c8836b | 2005-12-16 22:06:06 +0000 | [diff] [blame] | 3080 | #define EXPAT(func) (expat_capi->func) | 
| Fredrik Lundh | 8c8836b | 2005-12-16 22:06:06 +0000 | [diff] [blame] | 3081 |  | 
| Eli Bendersky | 52467b1 | 2012-06-01 07:13:08 +0300 | [diff] [blame] | 3082 | static XML_Memory_Handling_Suite ExpatMemoryHandler = { | 
 | 3083 |     PyObject_Malloc, PyObject_Realloc, PyObject_Free}; | 
 | 3084 |  | 
| Fredrik Lundh | 8c8836b | 2005-12-16 22:06:06 +0000 | [diff] [blame] | 3085 | typedef struct { | 
 | 3086 |     PyObject_HEAD | 
 | 3087 |  | 
 | 3088 |     XML_Parser parser; | 
 | 3089 |  | 
| Eli Bendersky | 2b6b73e | 2012-06-01 11:32:34 +0300 | [diff] [blame] | 3090 |     PyObject *target; | 
 | 3091 |     PyObject *entity; | 
| Fredrik Lundh | 8c8836b | 2005-12-16 22:06:06 +0000 | [diff] [blame] | 3092 |  | 
| Eli Bendersky | 2b6b73e | 2012-06-01 11:32:34 +0300 | [diff] [blame] | 3093 |     PyObject *names; | 
| Fredrik Lundh | 8c8836b | 2005-12-16 22:06:06 +0000 | [diff] [blame] | 3094 |  | 
| Stefan Behnel | dde3eeb | 2019-05-01 21:49:58 +0200 | [diff] [blame] | 3095 |     PyObject *handle_start_ns; | 
 | 3096 |     PyObject *handle_end_ns; | 
| Eli Bendersky | 2b6b73e | 2012-06-01 11:32:34 +0300 | [diff] [blame] | 3097 |     PyObject *handle_start; | 
 | 3098 |     PyObject *handle_data; | 
 | 3099 |     PyObject *handle_end; | 
| Fredrik Lundh | 8c8836b | 2005-12-16 22:06:06 +0000 | [diff] [blame] | 3100 |  | 
| Eli Bendersky | 2b6b73e | 2012-06-01 11:32:34 +0300 | [diff] [blame] | 3101 |     PyObject *handle_comment; | 
 | 3102 |     PyObject *handle_pi; | 
 | 3103 |     PyObject *handle_doctype; | 
| Fredrik Lundh | 8c8836b | 2005-12-16 22:06:06 +0000 | [diff] [blame] | 3104 |  | 
| Eli Bendersky | 2b6b73e | 2012-06-01 11:32:34 +0300 | [diff] [blame] | 3105 |     PyObject *handle_close; | 
| Florent Xicluna | f15351d | 2010-03-13 23:24:31 +0000 | [diff] [blame] | 3106 |  | 
| Fredrik Lundh | 8c8836b | 2005-12-16 22:06:06 +0000 | [diff] [blame] | 3107 | } XMLParserObject; | 
 | 3108 |  | 
| Fredrik Lundh | 8c8836b | 2005-12-16 22:06:06 +0000 | [diff] [blame] | 3109 | /* helpers */ | 
 | 3110 |  | 
| Fredrik Lundh | 8c8836b | 2005-12-16 22:06:06 +0000 | [diff] [blame] | 3111 | LOCAL(PyObject*) | 
 | 3112 | makeuniversal(XMLParserObject* self, const char* string) | 
 | 3113 | { | 
 | 3114 |     /* convert a UTF-8 tag/attribute name from the expat parser | 
 | 3115 |        to a universal name string */ | 
 | 3116 |  | 
| Antoine Pitrou | c194884 | 2012-10-01 23:40:37 +0200 | [diff] [blame] | 3117 |     Py_ssize_t size = (Py_ssize_t) strlen(string); | 
| Fredrik Lundh | 8c8836b | 2005-12-16 22:06:06 +0000 | [diff] [blame] | 3118 |     PyObject* key; | 
 | 3119 |     PyObject* value; | 
 | 3120 |  | 
 | 3121 |     /* look the 'raw' name up in the names dictionary */ | 
| Christian Heimes | 72b710a | 2008-05-26 13:28:38 +0000 | [diff] [blame] | 3122 |     key = PyBytes_FromStringAndSize(string, size); | 
| Fredrik Lundh | 8c8836b | 2005-12-16 22:06:06 +0000 | [diff] [blame] | 3123 |     if (!key) | 
 | 3124 |         return NULL; | 
 | 3125 |  | 
| Serhiy Storchaka | a24107b | 2019-02-25 17:59:46 +0200 | [diff] [blame] | 3126 |     value = PyDict_GetItemWithError(self->names, key); | 
| Fredrik Lundh | 8c8836b | 2005-12-16 22:06:06 +0000 | [diff] [blame] | 3127 |  | 
 | 3128 |     if (value) { | 
 | 3129 |         Py_INCREF(value); | 
| Serhiy Storchaka | a24107b | 2019-02-25 17:59:46 +0200 | [diff] [blame] | 3130 |     } | 
 | 3131 |     else if (!PyErr_Occurred()) { | 
| Fredrik Lundh | 8c8836b | 2005-12-16 22:06:06 +0000 | [diff] [blame] | 3132 |         /* new name.  convert to universal name, and decode as | 
 | 3133 |            necessary */ | 
 | 3134 |  | 
 | 3135 |         PyObject* tag; | 
 | 3136 |         char* p; | 
| Antoine Pitrou | c194884 | 2012-10-01 23:40:37 +0200 | [diff] [blame] | 3137 |         Py_ssize_t i; | 
| Fredrik Lundh | 8c8836b | 2005-12-16 22:06:06 +0000 | [diff] [blame] | 3138 |  | 
 | 3139 |         /* look for namespace separator */ | 
 | 3140 |         for (i = 0; i < size; i++) | 
 | 3141 |             if (string[i] == '}') | 
 | 3142 |                 break; | 
 | 3143 |         if (i != size) { | 
 | 3144 |             /* convert to universal name */ | 
| Christian Heimes | 72b710a | 2008-05-26 13:28:38 +0000 | [diff] [blame] | 3145 |             tag = PyBytes_FromStringAndSize(NULL, size+1); | 
| Victor Stinner | 71c8b7e | 2013-07-11 23:08:39 +0200 | [diff] [blame] | 3146 |             if (tag == NULL) { | 
 | 3147 |                 Py_DECREF(key); | 
 | 3148 |                 return NULL; | 
 | 3149 |             } | 
| Christian Heimes | 72b710a | 2008-05-26 13:28:38 +0000 | [diff] [blame] | 3150 |             p = PyBytes_AS_STRING(tag); | 
| Fredrik Lundh | 8c8836b | 2005-12-16 22:06:06 +0000 | [diff] [blame] | 3151 |             p[0] = '{'; | 
 | 3152 |             memcpy(p+1, string, size); | 
 | 3153 |             size++; | 
 | 3154 |         } else { | 
 | 3155 |             /* plain name; use key as tag */ | 
 | 3156 |             Py_INCREF(key); | 
 | 3157 |             tag = key; | 
 | 3158 |         } | 
| Victor Stinner | bfc7bf0 | 2011-03-21 13:23:42 +0100 | [diff] [blame] | 3159 |  | 
| Fredrik Lundh | 8c8836b | 2005-12-16 22:06:06 +0000 | [diff] [blame] | 3160 |         /* decode universal name */ | 
| Christian Heimes | 72b710a | 2008-05-26 13:28:38 +0000 | [diff] [blame] | 3161 |         p = PyBytes_AS_STRING(tag); | 
| Neal Norwitz | 0269b91 | 2007-08-08 06:56:02 +0000 | [diff] [blame] | 3162 |         value = PyUnicode_DecodeUTF8(p, size, "strict"); | 
 | 3163 |         Py_DECREF(tag); | 
 | 3164 |         if (!value) { | 
 | 3165 |             Py_DECREF(key); | 
 | 3166 |             return NULL; | 
 | 3167 |         } | 
| Fredrik Lundh | 8c8836b | 2005-12-16 22:06:06 +0000 | [diff] [blame] | 3168 |  | 
 | 3169 |         /* add to names dictionary */ | 
 | 3170 |         if (PyDict_SetItem(self->names, key, value) < 0) { | 
 | 3171 |             Py_DECREF(key); | 
 | 3172 |             Py_DECREF(value); | 
 | 3173 |             return NULL; | 
 | 3174 |         } | 
 | 3175 |     } | 
 | 3176 |  | 
 | 3177 |     Py_DECREF(key); | 
 | 3178 |     return value; | 
 | 3179 | } | 
 | 3180 |  | 
| Eli Bendersky | 5b77d81 | 2012-03-16 08:20:05 +0200 | [diff] [blame] | 3181 | /* Set the ParseError exception with the given parameters. | 
 | 3182 |  * If message is not NULL, it's used as the error string. Otherwise, the | 
 | 3183 |  * message string is the default for the given error_code. | 
 | 3184 | */ | 
| Florent Xicluna | f15351d | 2010-03-13 23:24:31 +0000 | [diff] [blame] | 3185 | static void | 
| Serhiy Storchaka | 26861b0 | 2015-02-16 20:52:17 +0200 | [diff] [blame] | 3186 | expat_set_error(enum XML_Error error_code, Py_ssize_t line, Py_ssize_t column, | 
 | 3187 |                 const char *message) | 
| Florent Xicluna | f15351d | 2010-03-13 23:24:31 +0000 | [diff] [blame] | 3188 | { | 
| Eli Bendersky | 5b77d81 | 2012-03-16 08:20:05 +0200 | [diff] [blame] | 3189 |     PyObject *errmsg, *error, *position, *code; | 
| Eli Bendersky | 532d03e | 2013-08-10 08:00:39 -0700 | [diff] [blame] | 3190 |     elementtreestate *st = ET_STATE_GLOBAL; | 
| Florent Xicluna | f15351d | 2010-03-13 23:24:31 +0000 | [diff] [blame] | 3191 |  | 
| Serhiy Storchaka | 26861b0 | 2015-02-16 20:52:17 +0200 | [diff] [blame] | 3192 |     errmsg = PyUnicode_FromFormat("%s: line %zd, column %zd", | 
| Eli Bendersky | 5b77d81 | 2012-03-16 08:20:05 +0200 | [diff] [blame] | 3193 |                 message ? message : EXPAT(ErrorString)(error_code), | 
 | 3194 |                 line, column); | 
| Victor Stinner | 499dfcf | 2011-03-21 13:26:24 +0100 | [diff] [blame] | 3195 |     if (errmsg == NULL) | 
 | 3196 |         return; | 
| Florent Xicluna | f15351d | 2010-03-13 23:24:31 +0000 | [diff] [blame] | 3197 |  | 
| Stefan Behnel | 43851a2 | 2019-05-01 21:20:38 +0200 | [diff] [blame] | 3198 |     error = _PyObject_FastCall(st->parseerror_obj, &errmsg, 1); | 
| Victor Stinner | 499dfcf | 2011-03-21 13:26:24 +0100 | [diff] [blame] | 3199 |     Py_DECREF(errmsg); | 
| Florent Xicluna | f15351d | 2010-03-13 23:24:31 +0000 | [diff] [blame] | 3200 |     if (!error) | 
 | 3201 |         return; | 
 | 3202 |  | 
| Eli Bendersky | 5b77d81 | 2012-03-16 08:20:05 +0200 | [diff] [blame] | 3203 |     /* Add code and position attributes */ | 
 | 3204 |     code = PyLong_FromLong((long)error_code); | 
 | 3205 |     if (!code) { | 
 | 3206 |         Py_DECREF(error); | 
 | 3207 |         return; | 
 | 3208 |     } | 
 | 3209 |     if (PyObject_SetAttrString(error, "code", code) == -1) { | 
 | 3210 |         Py_DECREF(error); | 
 | 3211 |         Py_DECREF(code); | 
 | 3212 |         return; | 
 | 3213 |     } | 
 | 3214 |     Py_DECREF(code); | 
 | 3215 |  | 
| Serhiy Storchaka | 26861b0 | 2015-02-16 20:52:17 +0200 | [diff] [blame] | 3216 |     position = Py_BuildValue("(nn)", line, column); | 
| Florent Xicluna | f15351d | 2010-03-13 23:24:31 +0000 | [diff] [blame] | 3217 |     if (!position) { | 
 | 3218 |         Py_DECREF(error); | 
 | 3219 |         return; | 
 | 3220 |     } | 
 | 3221 |     if (PyObject_SetAttrString(error, "position", position) == -1) { | 
 | 3222 |         Py_DECREF(error); | 
 | 3223 |         Py_DECREF(position); | 
 | 3224 |         return; | 
 | 3225 |     } | 
 | 3226 |     Py_DECREF(position); | 
 | 3227 |  | 
| Eli Bendersky | 532d03e | 2013-08-10 08:00:39 -0700 | [diff] [blame] | 3228 |     PyErr_SetObject(st->parseerror_obj, error); | 
| Florent Xicluna | f15351d | 2010-03-13 23:24:31 +0000 | [diff] [blame] | 3229 |     Py_DECREF(error); | 
 | 3230 | } | 
 | 3231 |  | 
| Fredrik Lundh | 8c8836b | 2005-12-16 22:06:06 +0000 | [diff] [blame] | 3232 | /* -------------------------------------------------------------------- */ | 
 | 3233 | /* handlers */ | 
 | 3234 |  | 
 | 3235 | static void | 
 | 3236 | expat_default_handler(XMLParserObject* self, const XML_Char* data_in, | 
 | 3237 |                       int data_len) | 
 | 3238 | { | 
 | 3239 |     PyObject* key; | 
 | 3240 |     PyObject* value; | 
 | 3241 |     PyObject* res; | 
 | 3242 |  | 
 | 3243 |     if (data_len < 2 || data_in[0] != '&') | 
 | 3244 |         return; | 
 | 3245 |  | 
| Victor Stinner | 3fd8cbd | 2013-07-18 22:46:14 +0200 | [diff] [blame] | 3246 |     if (PyErr_Occurred()) | 
 | 3247 |         return; | 
 | 3248 |  | 
| Neal Norwitz | 0269b91 | 2007-08-08 06:56:02 +0000 | [diff] [blame] | 3249 |     key = PyUnicode_DecodeUTF8(data_in + 1, data_len - 2, "strict"); | 
| Fredrik Lundh | 8c8836b | 2005-12-16 22:06:06 +0000 | [diff] [blame] | 3250 |     if (!key) | 
 | 3251 |         return; | 
 | 3252 |  | 
| Serhiy Storchaka | a24107b | 2019-02-25 17:59:46 +0200 | [diff] [blame] | 3253 |     value = PyDict_GetItemWithError(self->entity, key); | 
| Fredrik Lundh | 8c8836b | 2005-12-16 22:06:06 +0000 | [diff] [blame] | 3254 |  | 
 | 3255 |     if (value) { | 
 | 3256 |         if (TreeBuilder_CheckExact(self->target)) | 
 | 3257 |             res = treebuilder_handle_data( | 
 | 3258 |                 (TreeBuilderObject*) self->target, value | 
 | 3259 |                 ); | 
 | 3260 |         else if (self->handle_data) | 
| Stefan Behnel | 43851a2 | 2019-05-01 21:20:38 +0200 | [diff] [blame] | 3261 |             res = _PyObject_FastCall(self->handle_data, &value, 1); | 
| Fredrik Lundh | 8c8836b | 2005-12-16 22:06:06 +0000 | [diff] [blame] | 3262 |         else | 
 | 3263 |             res = NULL; | 
| Fredrik Lundh | 8c8836b | 2005-12-16 22:06:06 +0000 | [diff] [blame] | 3264 |         Py_XDECREF(res); | 
| Florent Xicluna | f15351d | 2010-03-13 23:24:31 +0000 | [diff] [blame] | 3265 |     } else if (!PyErr_Occurred()) { | 
 | 3266 |         /* Report the first error, not the last */ | 
| Alexander Belopolsky | e239d23 | 2010-12-08 23:31:48 +0000 | [diff] [blame] | 3267 |         char message[128] = "undefined entity "; | 
 | 3268 |         strncat(message, data_in, data_len < 100?data_len:100); | 
| Florent Xicluna | f15351d | 2010-03-13 23:24:31 +0000 | [diff] [blame] | 3269 |         expat_set_error( | 
| Eli Bendersky | 5b77d81 | 2012-03-16 08:20:05 +0200 | [diff] [blame] | 3270 |             XML_ERROR_UNDEFINED_ENTITY, | 
| Fredrik Lundh | 8c8836b | 2005-12-16 22:06:06 +0000 | [diff] [blame] | 3271 |             EXPAT(GetErrorLineNumber)(self->parser), | 
| Eli Bendersky | 5b77d81 | 2012-03-16 08:20:05 +0200 | [diff] [blame] | 3272 |             EXPAT(GetErrorColumnNumber)(self->parser), | 
 | 3273 |             message | 
| Fredrik Lundh | 8c8836b | 2005-12-16 22:06:06 +0000 | [diff] [blame] | 3274 |             ); | 
 | 3275 |     } | 
 | 3276 |  | 
 | 3277 |     Py_DECREF(key); | 
 | 3278 | } | 
 | 3279 |  | 
 | 3280 | static void | 
 | 3281 | expat_start_handler(XMLParserObject* self, const XML_Char* tag_in, | 
 | 3282 |                     const XML_Char **attrib_in) | 
 | 3283 | { | 
 | 3284 |     PyObject* res; | 
 | 3285 |     PyObject* tag; | 
 | 3286 |     PyObject* attrib; | 
 | 3287 |     int ok; | 
 | 3288 |  | 
| Victor Stinner | 3fd8cbd | 2013-07-18 22:46:14 +0200 | [diff] [blame] | 3289 |     if (PyErr_Occurred()) | 
 | 3290 |         return; | 
 | 3291 |  | 
| Fredrik Lundh | 8c8836b | 2005-12-16 22:06:06 +0000 | [diff] [blame] | 3292 |     /* tag name */ | 
 | 3293 |     tag = makeuniversal(self, tag_in); | 
 | 3294 |     if (!tag) | 
 | 3295 |         return; /* parser will look for errors */ | 
 | 3296 |  | 
 | 3297 |     /* attributes */ | 
 | 3298 |     if (attrib_in[0]) { | 
 | 3299 |         attrib = PyDict_New(); | 
| Serhiy Storchaka | a29eb08 | 2015-12-09 19:44:30 +0200 | [diff] [blame] | 3300 |         if (!attrib) { | 
 | 3301 |             Py_DECREF(tag); | 
| Fredrik Lundh | 8c8836b | 2005-12-16 22:06:06 +0000 | [diff] [blame] | 3302 |             return; | 
| Serhiy Storchaka | a29eb08 | 2015-12-09 19:44:30 +0200 | [diff] [blame] | 3303 |         } | 
| Fredrik Lundh | 8c8836b | 2005-12-16 22:06:06 +0000 | [diff] [blame] | 3304 |         while (attrib_in[0] && attrib_in[1]) { | 
 | 3305 |             PyObject* key = makeuniversal(self, attrib_in[0]); | 
| Neal Norwitz | 0269b91 | 2007-08-08 06:56:02 +0000 | [diff] [blame] | 3306 |             PyObject* value = PyUnicode_DecodeUTF8(attrib_in[1], strlen(attrib_in[1]), "strict"); | 
| Fredrik Lundh | 8c8836b | 2005-12-16 22:06:06 +0000 | [diff] [blame] | 3307 |             if (!key || !value) { | 
 | 3308 |                 Py_XDECREF(value); | 
 | 3309 |                 Py_XDECREF(key); | 
 | 3310 |                 Py_DECREF(attrib); | 
| Serhiy Storchaka | a29eb08 | 2015-12-09 19:44:30 +0200 | [diff] [blame] | 3311 |                 Py_DECREF(tag); | 
| Fredrik Lundh | 8c8836b | 2005-12-16 22:06:06 +0000 | [diff] [blame] | 3312 |                 return; | 
 | 3313 |             } | 
 | 3314 |             ok = PyDict_SetItem(attrib, key, value); | 
 | 3315 |             Py_DECREF(value); | 
 | 3316 |             Py_DECREF(key); | 
 | 3317 |             if (ok < 0) { | 
 | 3318 |                 Py_DECREF(attrib); | 
| Serhiy Storchaka | a29eb08 | 2015-12-09 19:44:30 +0200 | [diff] [blame] | 3319 |                 Py_DECREF(tag); | 
| Fredrik Lundh | 8c8836b | 2005-12-16 22:06:06 +0000 | [diff] [blame] | 3320 |                 return; | 
 | 3321 |             } | 
 | 3322 |             attrib_in += 2; | 
 | 3323 |         } | 
 | 3324 |     } else { | 
| Serhiy Storchaka | 36ff997 | 2015-12-10 09:51:53 +0200 | [diff] [blame] | 3325 |         Py_INCREF(Py_None); | 
 | 3326 |         attrib = Py_None; | 
| Eli Bendersky | 48d358b | 2012-05-30 17:57:50 +0300 | [diff] [blame] | 3327 |     } | 
 | 3328 |  | 
 | 3329 |     if (TreeBuilder_CheckExact(self->target)) { | 
| Fredrik Lundh | 8c8836b | 2005-12-16 22:06:06 +0000 | [diff] [blame] | 3330 |         /* shortcut */ | 
 | 3331 |         res = treebuilder_handle_start((TreeBuilderObject*) self->target, | 
 | 3332 |                                        tag, attrib); | 
| Eli Bendersky | 48d358b | 2012-05-30 17:57:50 +0300 | [diff] [blame] | 3333 |     } | 
| Florent Xicluna | f15351d | 2010-03-13 23:24:31 +0000 | [diff] [blame] | 3334 |     else if (self->handle_start) { | 
| Serhiy Storchaka | 36ff997 | 2015-12-10 09:51:53 +0200 | [diff] [blame] | 3335 |         if (attrib == Py_None) { | 
 | 3336 |             Py_DECREF(attrib); | 
 | 3337 |             attrib = PyDict_New(); | 
 | 3338 |             if (!attrib) { | 
 | 3339 |                 Py_DECREF(tag); | 
 | 3340 |                 return; | 
 | 3341 |             } | 
 | 3342 |         } | 
| Victor Stinner | 5abaa2b | 2016-12-09 16:22:32 +0100 | [diff] [blame] | 3343 |         res = PyObject_CallFunctionObjArgs(self->handle_start, | 
 | 3344 |                                            tag, attrib, NULL); | 
| Florent Xicluna | f15351d | 2010-03-13 23:24:31 +0000 | [diff] [blame] | 3345 |     } else | 
| Fredrik Lundh | 8c8836b | 2005-12-16 22:06:06 +0000 | [diff] [blame] | 3346 |         res = NULL; | 
 | 3347 |  | 
 | 3348 |     Py_DECREF(tag); | 
 | 3349 |     Py_DECREF(attrib); | 
 | 3350 |  | 
 | 3351 |     Py_XDECREF(res); | 
 | 3352 | } | 
 | 3353 |  | 
 | 3354 | static void | 
 | 3355 | expat_data_handler(XMLParserObject* self, const XML_Char* data_in, | 
 | 3356 |                    int data_len) | 
 | 3357 | { | 
 | 3358 |     PyObject* data; | 
 | 3359 |     PyObject* res; | 
 | 3360 |  | 
| Victor Stinner | 3fd8cbd | 2013-07-18 22:46:14 +0200 | [diff] [blame] | 3361 |     if (PyErr_Occurred()) | 
 | 3362 |         return; | 
 | 3363 |  | 
| Neal Norwitz | 0269b91 | 2007-08-08 06:56:02 +0000 | [diff] [blame] | 3364 |     data = PyUnicode_DecodeUTF8(data_in, data_len, "strict"); | 
| Fredrik Lundh | 44ed4db | 2006-03-12 21:06:35 +0000 | [diff] [blame] | 3365 |     if (!data) | 
 | 3366 |         return; /* parser will look for errors */ | 
| Fredrik Lundh | 8c8836b | 2005-12-16 22:06:06 +0000 | [diff] [blame] | 3367 |  | 
 | 3368 |     if (TreeBuilder_CheckExact(self->target)) | 
 | 3369 |         /* shortcut */ | 
 | 3370 |         res = treebuilder_handle_data((TreeBuilderObject*) self->target, data); | 
 | 3371 |     else if (self->handle_data) | 
| Stefan Behnel | 43851a2 | 2019-05-01 21:20:38 +0200 | [diff] [blame] | 3372 |         res = _PyObject_FastCall(self->handle_data, &data, 1); | 
| Fredrik Lundh | 8c8836b | 2005-12-16 22:06:06 +0000 | [diff] [blame] | 3373 |     else | 
 | 3374 |         res = NULL; | 
 | 3375 |  | 
 | 3376 |     Py_DECREF(data); | 
 | 3377 |  | 
 | 3378 |     Py_XDECREF(res); | 
 | 3379 | } | 
 | 3380 |  | 
 | 3381 | static void | 
 | 3382 | expat_end_handler(XMLParserObject* self, const XML_Char* tag_in) | 
 | 3383 | { | 
 | 3384 |     PyObject* tag; | 
 | 3385 |     PyObject* res = NULL; | 
 | 3386 |  | 
| Victor Stinner | 3fd8cbd | 2013-07-18 22:46:14 +0200 | [diff] [blame] | 3387 |     if (PyErr_Occurred()) | 
 | 3388 |         return; | 
 | 3389 |  | 
| Fredrik Lundh | 8c8836b | 2005-12-16 22:06:06 +0000 | [diff] [blame] | 3390 |     if (TreeBuilder_CheckExact(self->target)) | 
 | 3391 |         /* shortcut */ | 
 | 3392 |         /* the standard tree builder doesn't look at the end tag */ | 
 | 3393 |         res = treebuilder_handle_end( | 
 | 3394 |             (TreeBuilderObject*) self->target, Py_None | 
 | 3395 |             ); | 
 | 3396 |     else if (self->handle_end) { | 
 | 3397 |         tag = makeuniversal(self, tag_in); | 
 | 3398 |         if (tag) { | 
| Stefan Behnel | 43851a2 | 2019-05-01 21:20:38 +0200 | [diff] [blame] | 3399 |             res = _PyObject_FastCall(self->handle_end, &tag, 1); | 
| Fredrik Lundh | 8c8836b | 2005-12-16 22:06:06 +0000 | [diff] [blame] | 3400 |             Py_DECREF(tag); | 
 | 3401 |         } | 
 | 3402 |     } | 
 | 3403 |  | 
 | 3404 |     Py_XDECREF(res); | 
 | 3405 | } | 
 | 3406 |  | 
 | 3407 | static void | 
| Stefan Behnel | dde3eeb | 2019-05-01 21:49:58 +0200 | [diff] [blame] | 3408 | expat_start_ns_handler(XMLParserObject* self, const XML_Char* prefix_in, | 
 | 3409 |                        const XML_Char *uri_in) | 
| Fredrik Lundh | 8c8836b | 2005-12-16 22:06:06 +0000 | [diff] [blame] | 3410 | { | 
| Stefan Behnel | dde3eeb | 2019-05-01 21:49:58 +0200 | [diff] [blame] | 3411 |     PyObject* res = NULL; | 
 | 3412 |     PyObject* uri; | 
 | 3413 |     PyObject* prefix; | 
 | 3414 |     PyObject* stack[2]; | 
| Florent Xicluna | f15351d | 2010-03-13 23:24:31 +0000 | [diff] [blame] | 3415 |  | 
| Victor Stinner | 3fd8cbd | 2013-07-18 22:46:14 +0200 | [diff] [blame] | 3416 |     if (PyErr_Occurred()) | 
 | 3417 |         return; | 
 | 3418 |  | 
| Stefan Behnel | dde3eeb | 2019-05-01 21:49:58 +0200 | [diff] [blame] | 3419 |     if (!uri_in) | 
 | 3420 |         uri_in = ""; | 
 | 3421 |     if (!prefix_in) | 
 | 3422 |         prefix_in = ""; | 
| Florent Xicluna | f15351d | 2010-03-13 23:24:31 +0000 | [diff] [blame] | 3423 |  | 
| Stefan Behnel | dde3eeb | 2019-05-01 21:49:58 +0200 | [diff] [blame] | 3424 |     if (TreeBuilder_CheckExact(self->target)) { | 
 | 3425 |         /* shortcut - TreeBuilder does not actually implement .start_ns() */ | 
 | 3426 |         TreeBuilderObject *target = (TreeBuilderObject*) self->target; | 
| Serhiy Storchaka | 7efaf95 | 2015-12-06 23:51:44 +0200 | [diff] [blame] | 3427 |  | 
| Stefan Behnel | dde3eeb | 2019-05-01 21:49:58 +0200 | [diff] [blame] | 3428 |         if (target->events_append && target->start_ns_event_obj) { | 
 | 3429 |             prefix = PyUnicode_DecodeUTF8(prefix_in, strlen(prefix_in), "strict"); | 
 | 3430 |             if (!prefix) | 
 | 3431 |                 return; | 
 | 3432 |             uri = PyUnicode_DecodeUTF8(uri_in, strlen(uri_in), "strict"); | 
 | 3433 |             if (!uri) { | 
 | 3434 |                 Py_DECREF(prefix); | 
 | 3435 |                 return; | 
 | 3436 |             } | 
 | 3437 |  | 
 | 3438 |             res = treebuilder_handle_start_ns(target, prefix, uri); | 
 | 3439 |             Py_DECREF(uri); | 
 | 3440 |             Py_DECREF(prefix); | 
 | 3441 |         } | 
 | 3442 |     } else if (self->handle_start_ns) { | 
 | 3443 |         prefix = PyUnicode_DecodeUTF8(prefix_in, strlen(prefix_in), "strict"); | 
 | 3444 |         if (!prefix) | 
 | 3445 |             return; | 
 | 3446 |         uri = PyUnicode_DecodeUTF8(uri_in, strlen(uri_in), "strict"); | 
 | 3447 |         if (!uri) { | 
 | 3448 |             Py_DECREF(prefix); | 
 | 3449 |             return; | 
 | 3450 |         } | 
 | 3451 |  | 
 | 3452 |         stack[0] = prefix; | 
 | 3453 |         stack[1] = uri; | 
 | 3454 |         res = _PyObject_FastCall(self->handle_start_ns, stack, 2); | 
 | 3455 |         Py_DECREF(uri); | 
 | 3456 |         Py_DECREF(prefix); | 
 | 3457 |     } | 
 | 3458 |  | 
 | 3459 |     Py_XDECREF(res); | 
| Fredrik Lundh | 8c8836b | 2005-12-16 22:06:06 +0000 | [diff] [blame] | 3460 | } | 
 | 3461 |  | 
 | 3462 | static void | 
 | 3463 | expat_end_ns_handler(XMLParserObject* self, const XML_Char* prefix_in) | 
 | 3464 | { | 
| Stefan Behnel | dde3eeb | 2019-05-01 21:49:58 +0200 | [diff] [blame] | 3465 |     PyObject *res = NULL; | 
 | 3466 |     PyObject* prefix; | 
| Serhiy Storchaka | 7efaf95 | 2015-12-06 23:51:44 +0200 | [diff] [blame] | 3467 |  | 
| Victor Stinner | 3fd8cbd | 2013-07-18 22:46:14 +0200 | [diff] [blame] | 3468 |     if (PyErr_Occurred()) | 
 | 3469 |         return; | 
 | 3470 |  | 
| Stefan Behnel | dde3eeb | 2019-05-01 21:49:58 +0200 | [diff] [blame] | 3471 |     if (!prefix_in) | 
 | 3472 |         prefix_in = ""; | 
| Serhiy Storchaka | 7efaf95 | 2015-12-06 23:51:44 +0200 | [diff] [blame] | 3473 |  | 
| Stefan Behnel | dde3eeb | 2019-05-01 21:49:58 +0200 | [diff] [blame] | 3474 |     if (TreeBuilder_CheckExact(self->target)) { | 
 | 3475 |         /* shortcut - TreeBuilder does not actually implement .end_ns() */ | 
 | 3476 |         TreeBuilderObject *target = (TreeBuilderObject*) self->target; | 
 | 3477 |  | 
 | 3478 |         if (target->events_append && target->end_ns_event_obj) { | 
 | 3479 |             res = treebuilder_handle_end_ns(target, Py_None); | 
 | 3480 |         } | 
 | 3481 |     } else if (self->handle_end_ns) { | 
 | 3482 |         prefix = PyUnicode_DecodeUTF8(prefix_in, strlen(prefix_in), "strict"); | 
 | 3483 |         if (!prefix) | 
 | 3484 |             return; | 
 | 3485 |  | 
 | 3486 |         res = _PyObject_FastCall(self->handle_end_ns, &prefix, 1); | 
 | 3487 |         Py_DECREF(prefix); | 
 | 3488 |     } | 
 | 3489 |  | 
 | 3490 |     Py_XDECREF(res); | 
| Fredrik Lundh | 8c8836b | 2005-12-16 22:06:06 +0000 | [diff] [blame] | 3491 | } | 
 | 3492 |  | 
 | 3493 | static void | 
 | 3494 | expat_comment_handler(XMLParserObject* self, const XML_Char* comment_in) | 
 | 3495 | { | 
| Stefan Behnel | 43851a2 | 2019-05-01 21:20:38 +0200 | [diff] [blame] | 3496 |     PyObject* comment = NULL; | 
 | 3497 |     PyObject* res = NULL; | 
| Fredrik Lundh | 8c8836b | 2005-12-16 22:06:06 +0000 | [diff] [blame] | 3498 |  | 
| Victor Stinner | 3fd8cbd | 2013-07-18 22:46:14 +0200 | [diff] [blame] | 3499 |     if (PyErr_Occurred()) | 
 | 3500 |         return; | 
 | 3501 |  | 
| Stefan Behnel | 43851a2 | 2019-05-01 21:20:38 +0200 | [diff] [blame] | 3502 |     if (TreeBuilder_CheckExact(self->target)) { | 
 | 3503 |         /* shortcut */ | 
 | 3504 |         TreeBuilderObject *target = (TreeBuilderObject*) self->target; | 
 | 3505 |  | 
| Neal Norwitz | 0269b91 | 2007-08-08 06:56:02 +0000 | [diff] [blame] | 3506 |         comment = PyUnicode_DecodeUTF8(comment_in, strlen(comment_in), "strict"); | 
| Stefan Behnel | 43851a2 | 2019-05-01 21:20:38 +0200 | [diff] [blame] | 3507 |         if (!comment) | 
 | 3508 |             return; /* parser will look for errors */ | 
 | 3509 |  | 
 | 3510 |         res = treebuilder_handle_comment(target,  comment); | 
 | 3511 |     } else if (self->handle_comment) { | 
 | 3512 |         comment = PyUnicode_DecodeUTF8(comment_in, strlen(comment_in), "strict"); | 
 | 3513 |         if (!comment) | 
 | 3514 |             return; | 
 | 3515 |  | 
 | 3516 |         res = _PyObject_FastCall(self->handle_comment, &comment, 1); | 
| Fredrik Lundh | 8c8836b | 2005-12-16 22:06:06 +0000 | [diff] [blame] | 3517 |     } | 
| Stefan Behnel | 43851a2 | 2019-05-01 21:20:38 +0200 | [diff] [blame] | 3518 |  | 
 | 3519 |     Py_XDECREF(res); | 
 | 3520 |     Py_DECREF(comment); | 
| Fredrik Lundh | 8c8836b | 2005-12-16 22:06:06 +0000 | [diff] [blame] | 3521 | } | 
 | 3522 |  | 
| Eli Bendersky | 4583990 | 2013-01-13 05:14:47 -0800 | [diff] [blame] | 3523 | static void | 
| Eli Bendersky | 2b6b73e | 2012-06-01 11:32:34 +0300 | [diff] [blame] | 3524 | expat_start_doctype_handler(XMLParserObject *self, | 
 | 3525 |                             const XML_Char *doctype_name, | 
 | 3526 |                             const XML_Char *sysid, | 
 | 3527 |                             const XML_Char *pubid, | 
 | 3528 |                             int has_internal_subset) | 
 | 3529 | { | 
| Serhiy Storchaka | 02ec92f | 2018-07-24 12:03:34 +0300 | [diff] [blame] | 3530 |     _Py_IDENTIFIER(doctype); | 
| Eli Bendersky | 2b6b73e | 2012-06-01 11:32:34 +0300 | [diff] [blame] | 3531 |     PyObject *doctype_name_obj, *sysid_obj, *pubid_obj; | 
| Serhiy Storchaka | 02ec92f | 2018-07-24 12:03:34 +0300 | [diff] [blame] | 3532 |     PyObject *res; | 
| Eli Bendersky | 2b6b73e | 2012-06-01 11:32:34 +0300 | [diff] [blame] | 3533 |  | 
| Victor Stinner | 3fd8cbd | 2013-07-18 22:46:14 +0200 | [diff] [blame] | 3534 |     if (PyErr_Occurred()) | 
 | 3535 |         return; | 
 | 3536 |  | 
| Eli Bendersky | 2b6b73e | 2012-06-01 11:32:34 +0300 | [diff] [blame] | 3537 |     doctype_name_obj = makeuniversal(self, doctype_name); | 
 | 3538 |     if (!doctype_name_obj) | 
 | 3539 |         return; | 
 | 3540 |  | 
 | 3541 |     if (sysid) { | 
 | 3542 |         sysid_obj = makeuniversal(self, sysid); | 
 | 3543 |         if (!sysid_obj) { | 
 | 3544 |             Py_DECREF(doctype_name_obj); | 
 | 3545 |             return; | 
 | 3546 |         } | 
 | 3547 |     } else { | 
 | 3548 |         Py_INCREF(Py_None); | 
 | 3549 |         sysid_obj = Py_None; | 
 | 3550 |     } | 
 | 3551 |  | 
 | 3552 |     if (pubid) { | 
 | 3553 |         pubid_obj = makeuniversal(self, pubid); | 
 | 3554 |         if (!pubid_obj) { | 
 | 3555 |             Py_DECREF(doctype_name_obj); | 
 | 3556 |             Py_DECREF(sysid_obj); | 
 | 3557 |             return; | 
 | 3558 |         } | 
 | 3559 |     } else { | 
 | 3560 |         Py_INCREF(Py_None); | 
 | 3561 |         pubid_obj = Py_None; | 
 | 3562 |     } | 
 | 3563 |  | 
 | 3564 |     /* If the target has a handler for doctype, call it. */ | 
 | 3565 |     if (self->handle_doctype) { | 
| Victor Stinner | 5abaa2b | 2016-12-09 16:22:32 +0100 | [diff] [blame] | 3566 |         res = PyObject_CallFunctionObjArgs(self->handle_doctype, | 
 | 3567 |                                            doctype_name_obj, pubid_obj, | 
 | 3568 |                                            sysid_obj, NULL); | 
| Serhiy Storchaka | 02ec92f | 2018-07-24 12:03:34 +0300 | [diff] [blame] | 3569 |         Py_XDECREF(res); | 
| Eli Bendersky | 2b6b73e | 2012-06-01 11:32:34 +0300 | [diff] [blame] | 3570 |     } | 
| Serhiy Storchaka | 02ec92f | 2018-07-24 12:03:34 +0300 | [diff] [blame] | 3571 |     else if (_PyObject_LookupAttrId((PyObject *)self, &PyId_doctype, &res) > 0) { | 
 | 3572 |         (void)PyErr_WarnEx(PyExc_RuntimeWarning, | 
 | 3573 |                 "The doctype() method of XMLParser is ignored.  " | 
 | 3574 |                 "Define doctype() method on the TreeBuilder target.", | 
 | 3575 |                 1); | 
| Serhiy Storchaka | ee98e7b | 2018-07-25 14:52:45 +0300 | [diff] [blame] | 3576 |         Py_DECREF(res); | 
| Eli Bendersky | 2b6b73e | 2012-06-01 11:32:34 +0300 | [diff] [blame] | 3577 |     } | 
 | 3578 |  | 
| Eli Bendersky | 2b6b73e | 2012-06-01 11:32:34 +0300 | [diff] [blame] | 3579 |     Py_DECREF(doctype_name_obj); | 
 | 3580 |     Py_DECREF(pubid_obj); | 
 | 3581 |     Py_DECREF(sysid_obj); | 
 | 3582 | } | 
 | 3583 |  | 
| Fredrik Lundh | 8c8836b | 2005-12-16 22:06:06 +0000 | [diff] [blame] | 3584 | static void | 
 | 3585 | expat_pi_handler(XMLParserObject* self, const XML_Char* target_in, | 
 | 3586 |                  const XML_Char* data_in) | 
 | 3587 | { | 
| Stefan Behnel | 43851a2 | 2019-05-01 21:20:38 +0200 | [diff] [blame] | 3588 |     PyObject* pi_target = NULL; | 
| Fredrik Lundh | 8c8836b | 2005-12-16 22:06:06 +0000 | [diff] [blame] | 3589 |     PyObject* data; | 
 | 3590 |     PyObject* res; | 
| Stefan Behnel | 43851a2 | 2019-05-01 21:20:38 +0200 | [diff] [blame] | 3591 |     PyObject* stack[2]; | 
| Fredrik Lundh | 8c8836b | 2005-12-16 22:06:06 +0000 | [diff] [blame] | 3592 |  | 
| Victor Stinner | 3fd8cbd | 2013-07-18 22:46:14 +0200 | [diff] [blame] | 3593 |     if (PyErr_Occurred()) | 
 | 3594 |         return; | 
 | 3595 |  | 
| Stefan Behnel | 43851a2 | 2019-05-01 21:20:38 +0200 | [diff] [blame] | 3596 |     if (TreeBuilder_CheckExact(self->target)) { | 
 | 3597 |         /* shortcut */ | 
 | 3598 |         TreeBuilderObject *target = (TreeBuilderObject*) self->target; | 
 | 3599 |  | 
 | 3600 |         if (target->events_append && target->pi_event_obj) { | 
 | 3601 |             pi_target = PyUnicode_DecodeUTF8(target_in, strlen(target_in), "strict"); | 
 | 3602 |             if (!pi_target) | 
 | 3603 |                 goto error; | 
 | 3604 |             data = PyUnicode_DecodeUTF8(data_in, strlen(data_in), "strict"); | 
 | 3605 |             if (!data) | 
 | 3606 |                 goto error; | 
 | 3607 |             res = treebuilder_handle_pi(target, pi_target, data); | 
| Fredrik Lundh | 8c8836b | 2005-12-16 22:06:06 +0000 | [diff] [blame] | 3608 |             Py_XDECREF(res); | 
 | 3609 |             Py_DECREF(data); | 
| Stefan Behnel | 43851a2 | 2019-05-01 21:20:38 +0200 | [diff] [blame] | 3610 |             Py_DECREF(pi_target); | 
| Fredrik Lundh | 8c8836b | 2005-12-16 22:06:06 +0000 | [diff] [blame] | 3611 |         } | 
| Stefan Behnel | 43851a2 | 2019-05-01 21:20:38 +0200 | [diff] [blame] | 3612 |     } else if (self->handle_pi) { | 
 | 3613 |         pi_target = PyUnicode_DecodeUTF8(target_in, strlen(target_in), "strict"); | 
 | 3614 |         if (!pi_target) | 
 | 3615 |             goto error; | 
 | 3616 |         data = PyUnicode_DecodeUTF8(data_in, strlen(data_in), "strict"); | 
 | 3617 |         if (!data) | 
 | 3618 |             goto error; | 
 | 3619 |  | 
 | 3620 |         stack[0] = pi_target; | 
 | 3621 |         stack[1] = data; | 
 | 3622 |         res = _PyObject_FastCall(self->handle_pi, stack, 2); | 
 | 3623 |         Py_XDECREF(res); | 
 | 3624 |         Py_DECREF(data); | 
 | 3625 |         Py_DECREF(pi_target); | 
| Fredrik Lundh | 8c8836b | 2005-12-16 22:06:06 +0000 | [diff] [blame] | 3626 |     } | 
| Stefan Behnel | 43851a2 | 2019-05-01 21:20:38 +0200 | [diff] [blame] | 3627 |  | 
 | 3628 |     return; | 
 | 3629 |  | 
 | 3630 |   error: | 
 | 3631 |     Py_XDECREF(pi_target); | 
 | 3632 |     return; | 
| Fredrik Lundh | 8c8836b | 2005-12-16 22:06:06 +0000 | [diff] [blame] | 3633 | } | 
 | 3634 |  | 
| Fredrik Lundh | 8c8836b | 2005-12-16 22:06:06 +0000 | [diff] [blame] | 3635 | /* -------------------------------------------------------------------- */ | 
| Fredrik Lundh | 8c8836b | 2005-12-16 22:06:06 +0000 | [diff] [blame] | 3636 |  | 
| Eli Bendersky | 52467b1 | 2012-06-01 07:13:08 +0300 | [diff] [blame] | 3637 | static PyObject * | 
 | 3638 | xmlparser_new(PyTypeObject *type, PyObject *args, PyObject *kwds) | 
| Fredrik Lundh | 8c8836b | 2005-12-16 22:06:06 +0000 | [diff] [blame] | 3639 | { | 
| Eli Bendersky | 52467b1 | 2012-06-01 07:13:08 +0300 | [diff] [blame] | 3640 |     XMLParserObject *self = (XMLParserObject *)type->tp_alloc(type, 0); | 
 | 3641 |     if (self) { | 
 | 3642 |         self->parser = NULL; | 
 | 3643 |         self->target = self->entity = self->names = NULL; | 
| Stefan Behnel | dde3eeb | 2019-05-01 21:49:58 +0200 | [diff] [blame] | 3644 |         self->handle_start_ns = self->handle_end_ns = NULL; | 
| Eli Bendersky | 52467b1 | 2012-06-01 07:13:08 +0300 | [diff] [blame] | 3645 |         self->handle_start = self->handle_data = self->handle_end = NULL; | 
 | 3646 |         self->handle_comment = self->handle_pi = self->handle_close = NULL; | 
| Eli Bendersky | 2b6b73e | 2012-06-01 11:32:34 +0300 | [diff] [blame] | 3647 |         self->handle_doctype = NULL; | 
| Fredrik Lundh | 8c8836b | 2005-12-16 22:06:06 +0000 | [diff] [blame] | 3648 |     } | 
| Eli Bendersky | 52467b1 | 2012-06-01 07:13:08 +0300 | [diff] [blame] | 3649 |     return (PyObject *)self; | 
 | 3650 | } | 
| Fredrik Lundh | 8c8836b | 2005-12-16 22:06:06 +0000 | [diff] [blame] | 3651 |  | 
| scoder | c8d8e15 | 2017-09-14 22:00:03 +0200 | [diff] [blame] | 3652 | static int | 
 | 3653 | ignore_attribute_error(PyObject *value) | 
 | 3654 | { | 
 | 3655 |     if (value == NULL) { | 
 | 3656 |         if (!PyErr_ExceptionMatches(PyExc_AttributeError)) { | 
 | 3657 |             return -1; | 
 | 3658 |         } | 
 | 3659 |         PyErr_Clear(); | 
 | 3660 |     } | 
 | 3661 |     return 0; | 
 | 3662 | } | 
 | 3663 |  | 
| Serhiy Storchaka | cb98556 | 2015-05-04 15:32:48 +0300 | [diff] [blame] | 3664 | /*[clinic input] | 
 | 3665 | _elementtree.XMLParser.__init__ | 
 | 3666 |  | 
| Serhiy Storchaka | 02ec92f | 2018-07-24 12:03:34 +0300 | [diff] [blame] | 3667 |     * | 
| Serhiy Storchaka | cb98556 | 2015-05-04 15:32:48 +0300 | [diff] [blame] | 3668 |     target: object = NULL | 
| Larry Hastings | dbfdc38 | 2015-05-04 06:59:46 -0700 | [diff] [blame] | 3669 |     encoding: str(accept={str, NoneType}) = NULL | 
| Serhiy Storchaka | cb98556 | 2015-05-04 15:32:48 +0300 | [diff] [blame] | 3670 |  | 
 | 3671 | [clinic start generated code]*/ | 
 | 3672 |  | 
| Eli Bendersky | 52467b1 | 2012-06-01 07:13:08 +0300 | [diff] [blame] | 3673 | static int | 
| Serhiy Storchaka | 02ec92f | 2018-07-24 12:03:34 +0300 | [diff] [blame] | 3674 | _elementtree_XMLParser___init___impl(XMLParserObject *self, PyObject *target, | 
 | 3675 |                                      const char *encoding) | 
 | 3676 | /*[clinic end generated code: output=3ae45ec6cdf344e4 input=96288fcba916cfce]*/ | 
| Eli Bendersky | 52467b1 | 2012-06-01 07:13:08 +0300 | [diff] [blame] | 3677 | { | 
| Serhiy Storchaka | cb98556 | 2015-05-04 15:32:48 +0300 | [diff] [blame] | 3678 |     self->entity = PyDict_New(); | 
 | 3679 |     if (!self->entity) | 
 | 3680 |         return -1; | 
| Fredrik Lundh | 8c8836b | 2005-12-16 22:06:06 +0000 | [diff] [blame] | 3681 |  | 
| Serhiy Storchaka | cb98556 | 2015-05-04 15:32:48 +0300 | [diff] [blame] | 3682 |     self->names = PyDict_New(); | 
 | 3683 |     if (!self->names) { | 
 | 3684 |         Py_CLEAR(self->entity); | 
| Eli Bendersky | 52467b1 | 2012-06-01 07:13:08 +0300 | [diff] [blame] | 3685 |         return -1; | 
| Fredrik Lundh | 8c8836b | 2005-12-16 22:06:06 +0000 | [diff] [blame] | 3686 |     } | 
| Victor Stinner | bfc7bf0 | 2011-03-21 13:23:42 +0100 | [diff] [blame] | 3687 |  | 
| Serhiy Storchaka | cb98556 | 2015-05-04 15:32:48 +0300 | [diff] [blame] | 3688 |     self->parser = EXPAT(ParserCreate_MM)(encoding, &ExpatMemoryHandler, "}"); | 
 | 3689 |     if (!self->parser) { | 
 | 3690 |         Py_CLEAR(self->entity); | 
 | 3691 |         Py_CLEAR(self->names); | 
| Fredrik Lundh | 8c8836b | 2005-12-16 22:06:06 +0000 | [diff] [blame] | 3692 |         PyErr_NoMemory(); | 
| Eli Bendersky | 52467b1 | 2012-06-01 07:13:08 +0300 | [diff] [blame] | 3693 |         return -1; | 
| Fredrik Lundh | 8c8836b | 2005-12-16 22:06:06 +0000 | [diff] [blame] | 3694 |     } | 
| Christian Heimes | cb5778f | 2018-09-18 14:38:58 +0200 | [diff] [blame] | 3695 |     /* expat < 2.1.0 has no XML_SetHashSalt() */ | 
 | 3696 |     if (EXPAT(SetHashSalt) != NULL) { | 
 | 3697 |         EXPAT(SetHashSalt)(self->parser, | 
 | 3698 |                            (unsigned long)_Py_HashSecret.expat.hashsalt); | 
 | 3699 |     } | 
| Fredrik Lundh | 8c8836b | 2005-12-16 22:06:06 +0000 | [diff] [blame] | 3700 |  | 
| Eli Bendersky | 52467b1 | 2012-06-01 07:13:08 +0300 | [diff] [blame] | 3701 |     if (target) { | 
 | 3702 |         Py_INCREF(target); | 
 | 3703 |     } else { | 
| Eli Bendersky | 58d548d | 2012-05-29 15:45:16 +0300 | [diff] [blame] | 3704 |         target = treebuilder_new(&TreeBuilder_Type, NULL, NULL); | 
| Fredrik Lundh | 8c8836b | 2005-12-16 22:06:06 +0000 | [diff] [blame] | 3705 |         if (!target) { | 
| Serhiy Storchaka | cb98556 | 2015-05-04 15:32:48 +0300 | [diff] [blame] | 3706 |             Py_CLEAR(self->entity); | 
 | 3707 |             Py_CLEAR(self->names); | 
| Eli Bendersky | 52467b1 | 2012-06-01 07:13:08 +0300 | [diff] [blame] | 3708 |             return -1; | 
| Fredrik Lundh | 8c8836b | 2005-12-16 22:06:06 +0000 | [diff] [blame] | 3709 |         } | 
| Eli Bendersky | 52467b1 | 2012-06-01 07:13:08 +0300 | [diff] [blame] | 3710 |     } | 
| Serhiy Storchaka | cb98556 | 2015-05-04 15:32:48 +0300 | [diff] [blame] | 3711 |     self->target = target; | 
| Fredrik Lundh | 8c8836b | 2005-12-16 22:06:06 +0000 | [diff] [blame] | 3712 |  | 
| Stefan Behnel | dde3eeb | 2019-05-01 21:49:58 +0200 | [diff] [blame] | 3713 |     self->handle_start_ns = PyObject_GetAttrString(target, "start_ns"); | 
 | 3714 |     if (ignore_attribute_error(self->handle_start_ns)) { | 
 | 3715 |         return -1; | 
 | 3716 |     } | 
 | 3717 |     self->handle_end_ns = PyObject_GetAttrString(target, "end_ns"); | 
 | 3718 |     if (ignore_attribute_error(self->handle_end_ns)) { | 
 | 3719 |         return -1; | 
 | 3720 |     } | 
| Serhiy Storchaka | cb98556 | 2015-05-04 15:32:48 +0300 | [diff] [blame] | 3721 |     self->handle_start = PyObject_GetAttrString(target, "start"); | 
| scoder | c8d8e15 | 2017-09-14 22:00:03 +0200 | [diff] [blame] | 3722 |     if (ignore_attribute_error(self->handle_start)) { | 
 | 3723 |         return -1; | 
 | 3724 |     } | 
| Serhiy Storchaka | cb98556 | 2015-05-04 15:32:48 +0300 | [diff] [blame] | 3725 |     self->handle_data = PyObject_GetAttrString(target, "data"); | 
| scoder | c8d8e15 | 2017-09-14 22:00:03 +0200 | [diff] [blame] | 3726 |     if (ignore_attribute_error(self->handle_data)) { | 
 | 3727 |         return -1; | 
 | 3728 |     } | 
| Serhiy Storchaka | cb98556 | 2015-05-04 15:32:48 +0300 | [diff] [blame] | 3729 |     self->handle_end = PyObject_GetAttrString(target, "end"); | 
| scoder | c8d8e15 | 2017-09-14 22:00:03 +0200 | [diff] [blame] | 3730 |     if (ignore_attribute_error(self->handle_end)) { | 
 | 3731 |         return -1; | 
 | 3732 |     } | 
| Serhiy Storchaka | cb98556 | 2015-05-04 15:32:48 +0300 | [diff] [blame] | 3733 |     self->handle_comment = PyObject_GetAttrString(target, "comment"); | 
| scoder | c8d8e15 | 2017-09-14 22:00:03 +0200 | [diff] [blame] | 3734 |     if (ignore_attribute_error(self->handle_comment)) { | 
 | 3735 |         return -1; | 
 | 3736 |     } | 
| Serhiy Storchaka | cb98556 | 2015-05-04 15:32:48 +0300 | [diff] [blame] | 3737 |     self->handle_pi = PyObject_GetAttrString(target, "pi"); | 
| scoder | c8d8e15 | 2017-09-14 22:00:03 +0200 | [diff] [blame] | 3738 |     if (ignore_attribute_error(self->handle_pi)) { | 
 | 3739 |         return -1; | 
 | 3740 |     } | 
| Serhiy Storchaka | cb98556 | 2015-05-04 15:32:48 +0300 | [diff] [blame] | 3741 |     self->handle_close = PyObject_GetAttrString(target, "close"); | 
| scoder | c8d8e15 | 2017-09-14 22:00:03 +0200 | [diff] [blame] | 3742 |     if (ignore_attribute_error(self->handle_close)) { | 
 | 3743 |         return -1; | 
 | 3744 |     } | 
| Serhiy Storchaka | cb98556 | 2015-05-04 15:32:48 +0300 | [diff] [blame] | 3745 |     self->handle_doctype = PyObject_GetAttrString(target, "doctype"); | 
| scoder | c8d8e15 | 2017-09-14 22:00:03 +0200 | [diff] [blame] | 3746 |     if (ignore_attribute_error(self->handle_doctype)) { | 
 | 3747 |         return -1; | 
 | 3748 |     } | 
| Eli Bendersky | 4583990 | 2013-01-13 05:14:47 -0800 | [diff] [blame] | 3749 |  | 
| Fredrik Lundh | 8c8836b | 2005-12-16 22:06:06 +0000 | [diff] [blame] | 3750 |     /* configure parser */ | 
| Serhiy Storchaka | cb98556 | 2015-05-04 15:32:48 +0300 | [diff] [blame] | 3751 |     EXPAT(SetUserData)(self->parser, self); | 
| Stefan Behnel | dde3eeb | 2019-05-01 21:49:58 +0200 | [diff] [blame] | 3752 |     if (self->handle_start_ns || self->handle_end_ns) | 
 | 3753 |         EXPAT(SetNamespaceDeclHandler)( | 
 | 3754 |             self->parser, | 
 | 3755 |             (XML_StartNamespaceDeclHandler) expat_start_ns_handler, | 
 | 3756 |             (XML_EndNamespaceDeclHandler) expat_end_ns_handler | 
 | 3757 |             ); | 
| Fredrik Lundh | 8c8836b | 2005-12-16 22:06:06 +0000 | [diff] [blame] | 3758 |     EXPAT(SetElementHandler)( | 
| Serhiy Storchaka | cb98556 | 2015-05-04 15:32:48 +0300 | [diff] [blame] | 3759 |         self->parser, | 
| Fredrik Lundh | 8c8836b | 2005-12-16 22:06:06 +0000 | [diff] [blame] | 3760 |         (XML_StartElementHandler) expat_start_handler, | 
 | 3761 |         (XML_EndElementHandler) expat_end_handler | 
 | 3762 |         ); | 
 | 3763 |     EXPAT(SetDefaultHandlerExpand)( | 
| Serhiy Storchaka | cb98556 | 2015-05-04 15:32:48 +0300 | [diff] [blame] | 3764 |         self->parser, | 
| Fredrik Lundh | 8c8836b | 2005-12-16 22:06:06 +0000 | [diff] [blame] | 3765 |         (XML_DefaultHandler) expat_default_handler | 
 | 3766 |         ); | 
 | 3767 |     EXPAT(SetCharacterDataHandler)( | 
| Serhiy Storchaka | cb98556 | 2015-05-04 15:32:48 +0300 | [diff] [blame] | 3768 |         self->parser, | 
| Fredrik Lundh | 8c8836b | 2005-12-16 22:06:06 +0000 | [diff] [blame] | 3769 |         (XML_CharacterDataHandler) expat_data_handler | 
 | 3770 |         ); | 
| Serhiy Storchaka | cb98556 | 2015-05-04 15:32:48 +0300 | [diff] [blame] | 3771 |     if (self->handle_comment) | 
| Fredrik Lundh | 8c8836b | 2005-12-16 22:06:06 +0000 | [diff] [blame] | 3772 |         EXPAT(SetCommentHandler)( | 
| Serhiy Storchaka | cb98556 | 2015-05-04 15:32:48 +0300 | [diff] [blame] | 3773 |             self->parser, | 
| Fredrik Lundh | 8c8836b | 2005-12-16 22:06:06 +0000 | [diff] [blame] | 3774 |             (XML_CommentHandler) expat_comment_handler | 
 | 3775 |             ); | 
| Serhiy Storchaka | cb98556 | 2015-05-04 15:32:48 +0300 | [diff] [blame] | 3776 |     if (self->handle_pi) | 
| Fredrik Lundh | 8c8836b | 2005-12-16 22:06:06 +0000 | [diff] [blame] | 3777 |         EXPAT(SetProcessingInstructionHandler)( | 
| Serhiy Storchaka | cb98556 | 2015-05-04 15:32:48 +0300 | [diff] [blame] | 3778 |             self->parser, | 
| Fredrik Lundh | 8c8836b | 2005-12-16 22:06:06 +0000 | [diff] [blame] | 3779 |             (XML_ProcessingInstructionHandler) expat_pi_handler | 
 | 3780 |             ); | 
| Eli Bendersky | 2b6b73e | 2012-06-01 11:32:34 +0300 | [diff] [blame] | 3781 |     EXPAT(SetStartDoctypeDeclHandler)( | 
| Serhiy Storchaka | cb98556 | 2015-05-04 15:32:48 +0300 | [diff] [blame] | 3782 |         self->parser, | 
| Eli Bendersky | 2b6b73e | 2012-06-01 11:32:34 +0300 | [diff] [blame] | 3783 |         (XML_StartDoctypeDeclHandler) expat_start_doctype_handler | 
 | 3784 |         ); | 
| Fredrik Lundh | 8c8836b | 2005-12-16 22:06:06 +0000 | [diff] [blame] | 3785 |     EXPAT(SetUnknownEncodingHandler)( | 
| Serhiy Storchaka | cb98556 | 2015-05-04 15:32:48 +0300 | [diff] [blame] | 3786 |         self->parser, | 
| Eli Bendersky | 6dc32b3 | 2013-05-25 05:25:48 -0700 | [diff] [blame] | 3787 |         EXPAT(DefaultUnknownEncodingHandler), NULL | 
| Fredrik Lundh | 8c8836b | 2005-12-16 22:06:06 +0000 | [diff] [blame] | 3788 |         ); | 
| Fredrik Lundh | 8c8836b | 2005-12-16 22:06:06 +0000 | [diff] [blame] | 3789 |  | 
| Eli Bendersky | 52467b1 | 2012-06-01 07:13:08 +0300 | [diff] [blame] | 3790 |     return 0; | 
| Fredrik Lundh | 8c8836b | 2005-12-16 22:06:06 +0000 | [diff] [blame] | 3791 | } | 
 | 3792 |  | 
| Eli Bendersky | 52467b1 | 2012-06-01 07:13:08 +0300 | [diff] [blame] | 3793 | static int | 
 | 3794 | xmlparser_gc_traverse(XMLParserObject *self, visitproc visit, void *arg) | 
 | 3795 | { | 
 | 3796 |     Py_VISIT(self->handle_close); | 
 | 3797 |     Py_VISIT(self->handle_pi); | 
 | 3798 |     Py_VISIT(self->handle_comment); | 
 | 3799 |     Py_VISIT(self->handle_end); | 
 | 3800 |     Py_VISIT(self->handle_data); | 
 | 3801 |     Py_VISIT(self->handle_start); | 
| Stefan Behnel | dde3eeb | 2019-05-01 21:49:58 +0200 | [diff] [blame] | 3802 |     Py_VISIT(self->handle_start_ns); | 
 | 3803 |     Py_VISIT(self->handle_end_ns); | 
 | 3804 |     Py_VISIT(self->handle_doctype); | 
| Eli Bendersky | 52467b1 | 2012-06-01 07:13:08 +0300 | [diff] [blame] | 3805 |  | 
 | 3806 |     Py_VISIT(self->target); | 
 | 3807 |     Py_VISIT(self->entity); | 
 | 3808 |     Py_VISIT(self->names); | 
 | 3809 |  | 
 | 3810 |     return 0; | 
 | 3811 | } | 
 | 3812 |  | 
 | 3813 | static int | 
 | 3814 | xmlparser_gc_clear(XMLParserObject *self) | 
| Fredrik Lundh | 8c8836b | 2005-12-16 22:06:06 +0000 | [diff] [blame] | 3815 | { | 
| Victor Stinner | e727d41 | 2017-09-18 05:29:37 -0700 | [diff] [blame] | 3816 |     if (self->parser != NULL) { | 
 | 3817 |         XML_Parser parser = self->parser; | 
 | 3818 |         self->parser = NULL; | 
 | 3819 |         EXPAT(ParserFree)(parser); | 
 | 3820 |     } | 
| Fredrik Lundh | 8c8836b | 2005-12-16 22:06:06 +0000 | [diff] [blame] | 3821 |  | 
| Antoine Pitrou | c194884 | 2012-10-01 23:40:37 +0200 | [diff] [blame] | 3822 |     Py_CLEAR(self->handle_close); | 
 | 3823 |     Py_CLEAR(self->handle_pi); | 
 | 3824 |     Py_CLEAR(self->handle_comment); | 
 | 3825 |     Py_CLEAR(self->handle_end); | 
 | 3826 |     Py_CLEAR(self->handle_data); | 
 | 3827 |     Py_CLEAR(self->handle_start); | 
| Stefan Behnel | dde3eeb | 2019-05-01 21:49:58 +0200 | [diff] [blame] | 3828 |     Py_CLEAR(self->handle_start_ns); | 
 | 3829 |     Py_CLEAR(self->handle_end_ns); | 
| Antoine Pitrou | c194884 | 2012-10-01 23:40:37 +0200 | [diff] [blame] | 3830 |     Py_CLEAR(self->handle_doctype); | 
| Fredrik Lundh | 8c8836b | 2005-12-16 22:06:06 +0000 | [diff] [blame] | 3831 |  | 
| Antoine Pitrou | c194884 | 2012-10-01 23:40:37 +0200 | [diff] [blame] | 3832 |     Py_CLEAR(self->target); | 
 | 3833 |     Py_CLEAR(self->entity); | 
 | 3834 |     Py_CLEAR(self->names); | 
| Fredrik Lundh | 8c8836b | 2005-12-16 22:06:06 +0000 | [diff] [blame] | 3835 |  | 
| Eli Bendersky | 52467b1 | 2012-06-01 07:13:08 +0300 | [diff] [blame] | 3836 |     return 0; | 
| Fredrik Lundh | 8c8836b | 2005-12-16 22:06:06 +0000 | [diff] [blame] | 3837 | } | 
 | 3838 |  | 
| Eli Bendersky | 52467b1 | 2012-06-01 07:13:08 +0300 | [diff] [blame] | 3839 | static void | 
 | 3840 | xmlparser_dealloc(XMLParserObject* self) | 
 | 3841 | { | 
 | 3842 |     PyObject_GC_UnTrack(self); | 
 | 3843 |     xmlparser_gc_clear(self); | 
 | 3844 |     Py_TYPE(self)->tp_free((PyObject *)self); | 
 | 3845 | } | 
| Fredrik Lundh | 8c8836b | 2005-12-16 22:06:06 +0000 | [diff] [blame] | 3846 |  | 
 | 3847 | LOCAL(PyObject*) | 
| Serhiy Storchaka | 66d53fa | 2013-05-22 17:07:51 +0300 | [diff] [blame] | 3848 | expat_parse(XMLParserObject* self, const char* data, int data_len, int final) | 
| Fredrik Lundh | 8c8836b | 2005-12-16 22:06:06 +0000 | [diff] [blame] | 3849 | { | 
 | 3850 |     int ok; | 
 | 3851 |  | 
| Victor Stinner | 3fd8cbd | 2013-07-18 22:46:14 +0200 | [diff] [blame] | 3852 |     assert(!PyErr_Occurred()); | 
| Fredrik Lundh | 8c8836b | 2005-12-16 22:06:06 +0000 | [diff] [blame] | 3853 |     ok = EXPAT(Parse)(self->parser, data, data_len, final); | 
 | 3854 |  | 
 | 3855 |     if (PyErr_Occurred()) | 
 | 3856 |         return NULL; | 
 | 3857 |  | 
 | 3858 |     if (!ok) { | 
| Florent Xicluna | f15351d | 2010-03-13 23:24:31 +0000 | [diff] [blame] | 3859 |         expat_set_error( | 
| Eli Bendersky | 5b77d81 | 2012-03-16 08:20:05 +0200 | [diff] [blame] | 3860 |             EXPAT(GetErrorCode)(self->parser), | 
| Fredrik Lundh | 8c8836b | 2005-12-16 22:06:06 +0000 | [diff] [blame] | 3861 |             EXPAT(GetErrorLineNumber)(self->parser), | 
| Eli Bendersky | 5b77d81 | 2012-03-16 08:20:05 +0200 | [diff] [blame] | 3862 |             EXPAT(GetErrorColumnNumber)(self->parser), | 
 | 3863 |             NULL | 
| Fredrik Lundh | 8c8836b | 2005-12-16 22:06:06 +0000 | [diff] [blame] | 3864 |             ); | 
 | 3865 |         return NULL; | 
 | 3866 |     } | 
 | 3867 |  | 
 | 3868 |     Py_RETURN_NONE; | 
 | 3869 | } | 
 | 3870 |  | 
| Serhiy Storchaka | cb98556 | 2015-05-04 15:32:48 +0300 | [diff] [blame] | 3871 | /*[clinic input] | 
 | 3872 | _elementtree.XMLParser.close | 
 | 3873 |  | 
 | 3874 | [clinic start generated code]*/ | 
 | 3875 |  | 
 | 3876 | static PyObject * | 
 | 3877 | _elementtree_XMLParser_close_impl(XMLParserObject *self) | 
 | 3878 | /*[clinic end generated code: output=d68d375dd23bc7fb input=ca7909ca78c3abfe]*/ | 
| Fredrik Lundh | 8c8836b | 2005-12-16 22:06:06 +0000 | [diff] [blame] | 3879 | { | 
 | 3880 |     /* end feeding data to parser */ | 
 | 3881 |  | 
 | 3882 |     PyObject* res; | 
| Fredrik Lundh | 8c8836b | 2005-12-16 22:06:06 +0000 | [diff] [blame] | 3883 |     res = expat_parse(self, "", 0, 1); | 
| Florent Xicluna | f15351d | 2010-03-13 23:24:31 +0000 | [diff] [blame] | 3884 |     if (!res) | 
 | 3885 |         return NULL; | 
| Fredrik Lundh | 8c8836b | 2005-12-16 22:06:06 +0000 | [diff] [blame] | 3886 |  | 
| Florent Xicluna | f15351d | 2010-03-13 23:24:31 +0000 | [diff] [blame] | 3887 |     if (TreeBuilder_CheckExact(self->target)) { | 
| Fredrik Lundh | 8c8836b | 2005-12-16 22:06:06 +0000 | [diff] [blame] | 3888 |         Py_DECREF(res); | 
 | 3889 |         return treebuilder_done((TreeBuilderObject*) self->target); | 
| Eli Bendersky | 6eb50b1 | 2013-08-24 15:17:08 -0700 | [diff] [blame] | 3890 |     } | 
 | 3891 |     else if (self->handle_close) { | 
| Florent Xicluna | f15351d | 2010-03-13 23:24:31 +0000 | [diff] [blame] | 3892 |         Py_DECREF(res); | 
| Victor Stinner | 3466bde | 2016-09-05 18:16:01 -0700 | [diff] [blame] | 3893 |         return _PyObject_CallNoArg(self->handle_close); | 
| Eli Bendersky | 6eb50b1 | 2013-08-24 15:17:08 -0700 | [diff] [blame] | 3894 |     } | 
 | 3895 |     else { | 
| Florent Xicluna | f15351d | 2010-03-13 23:24:31 +0000 | [diff] [blame] | 3896 |         return res; | 
| Eli Bendersky | 6eb50b1 | 2013-08-24 15:17:08 -0700 | [diff] [blame] | 3897 |     } | 
| Fredrik Lundh | 8c8836b | 2005-12-16 22:06:06 +0000 | [diff] [blame] | 3898 | } | 
 | 3899 |  | 
| Serhiy Storchaka | cb98556 | 2015-05-04 15:32:48 +0300 | [diff] [blame] | 3900 | /*[clinic input] | 
 | 3901 | _elementtree.XMLParser.feed | 
 | 3902 |  | 
 | 3903 |     data: object | 
 | 3904 |     / | 
 | 3905 |  | 
 | 3906 | [clinic start generated code]*/ | 
 | 3907 |  | 
 | 3908 | static PyObject * | 
 | 3909 | _elementtree_XMLParser_feed(XMLParserObject *self, PyObject *data) | 
 | 3910 | /*[clinic end generated code: output=e42b6a78eec7446d input=fe231b6b8de3ce1f]*/ | 
| Fredrik Lundh | 8c8836b | 2005-12-16 22:06:06 +0000 | [diff] [blame] | 3911 | { | 
 | 3912 |     /* feed data to parser */ | 
 | 3913 |  | 
| Serhiy Storchaka | cb98556 | 2015-05-04 15:32:48 +0300 | [diff] [blame] | 3914 |     if (PyUnicode_Check(data)) { | 
| Serhiy Storchaka | 66d53fa | 2013-05-22 17:07:51 +0300 | [diff] [blame] | 3915 |         Py_ssize_t data_len; | 
| Serhiy Storchaka | cb98556 | 2015-05-04 15:32:48 +0300 | [diff] [blame] | 3916 |         const char *data_ptr = PyUnicode_AsUTF8AndSize(data, &data_len); | 
 | 3917 |         if (data_ptr == NULL) | 
| Serhiy Storchaka | 66d53fa | 2013-05-22 17:07:51 +0300 | [diff] [blame] | 3918 |             return NULL; | 
 | 3919 |         if (data_len > INT_MAX) { | 
 | 3920 |             PyErr_SetString(PyExc_OverflowError, "size does not fit in an int"); | 
 | 3921 |             return NULL; | 
 | 3922 |         } | 
 | 3923 |         /* Explicitly set UTF-8 encoding. Return code ignored. */ | 
 | 3924 |         (void)EXPAT(SetEncoding)(self->parser, "utf-8"); | 
| Serhiy Storchaka | cb98556 | 2015-05-04 15:32:48 +0300 | [diff] [blame] | 3925 |         return expat_parse(self, data_ptr, (int)data_len, 0); | 
| Serhiy Storchaka | 66d53fa | 2013-05-22 17:07:51 +0300 | [diff] [blame] | 3926 |     } | 
 | 3927 |     else { | 
 | 3928 |         Py_buffer view; | 
 | 3929 |         PyObject *res; | 
| Serhiy Storchaka | cb98556 | 2015-05-04 15:32:48 +0300 | [diff] [blame] | 3930 |         if (PyObject_GetBuffer(data, &view, PyBUF_SIMPLE) < 0) | 
| Serhiy Storchaka | 66d53fa | 2013-05-22 17:07:51 +0300 | [diff] [blame] | 3931 |             return NULL; | 
 | 3932 |         if (view.len > INT_MAX) { | 
 | 3933 |             PyBuffer_Release(&view); | 
 | 3934 |             PyErr_SetString(PyExc_OverflowError, "size does not fit in an int"); | 
 | 3935 |             return NULL; | 
 | 3936 |         } | 
 | 3937 |         res = expat_parse(self, view.buf, (int)view.len, 0); | 
 | 3938 |         PyBuffer_Release(&view); | 
 | 3939 |         return res; | 
 | 3940 |     } | 
| Fredrik Lundh | 8c8836b | 2005-12-16 22:06:06 +0000 | [diff] [blame] | 3941 | } | 
 | 3942 |  | 
| Serhiy Storchaka | cb98556 | 2015-05-04 15:32:48 +0300 | [diff] [blame] | 3943 | /*[clinic input] | 
 | 3944 | _elementtree.XMLParser._parse_whole | 
 | 3945 |  | 
 | 3946 |     file: object | 
 | 3947 |     / | 
 | 3948 |  | 
 | 3949 | [clinic start generated code]*/ | 
 | 3950 |  | 
 | 3951 | static PyObject * | 
 | 3952 | _elementtree_XMLParser__parse_whole(XMLParserObject *self, PyObject *file) | 
 | 3953 | /*[clinic end generated code: output=f797197bb818dda3 input=19ecc893b6f3e752]*/ | 
| Fredrik Lundh | 8c8836b | 2005-12-16 22:06:06 +0000 | [diff] [blame] | 3954 | { | 
| Eli Bendersky | a369923 | 2013-05-19 18:47:23 -0700 | [diff] [blame] | 3955 |     /* (internal) parse the whole input, until end of stream */ | 
| Fredrik Lundh | 8c8836b | 2005-12-16 22:06:06 +0000 | [diff] [blame] | 3956 |     PyObject* reader; | 
 | 3957 |     PyObject* buffer; | 
| Eli Bendersky | f996e77 | 2012-03-16 05:53:30 +0200 | [diff] [blame] | 3958 |     PyObject* temp; | 
| Fredrik Lundh | 8c8836b | 2005-12-16 22:06:06 +0000 | [diff] [blame] | 3959 |     PyObject* res; | 
 | 3960 |  | 
| Serhiy Storchaka | cb98556 | 2015-05-04 15:32:48 +0300 | [diff] [blame] | 3961 |     reader = PyObject_GetAttrString(file, "read"); | 
| Fredrik Lundh | 8c8836b | 2005-12-16 22:06:06 +0000 | [diff] [blame] | 3962 |     if (!reader) | 
 | 3963 |         return NULL; | 
| Victor Stinner | bfc7bf0 | 2011-03-21 13:23:42 +0100 | [diff] [blame] | 3964 |  | 
| Fredrik Lundh | 8c8836b | 2005-12-16 22:06:06 +0000 | [diff] [blame] | 3965 |     /* read from open file object */ | 
 | 3966 |     for (;;) { | 
 | 3967 |  | 
 | 3968 |         buffer = PyObject_CallFunction(reader, "i", 64*1024); | 
 | 3969 |  | 
 | 3970 |         if (!buffer) { | 
 | 3971 |             /* read failed (e.g. due to KeyboardInterrupt) */ | 
 | 3972 |             Py_DECREF(reader); | 
 | 3973 |             return NULL; | 
 | 3974 |         } | 
 | 3975 |  | 
| Eli Bendersky | f996e77 | 2012-03-16 05:53:30 +0200 | [diff] [blame] | 3976 |         if (PyUnicode_CheckExact(buffer)) { | 
 | 3977 |             /* A unicode object is encoded into bytes using UTF-8 */ | 
| Victor Stinner | 59799a8 | 2013-11-13 14:17:30 +0100 | [diff] [blame] | 3978 |             if (PyUnicode_GET_LENGTH(buffer) == 0) { | 
| Eli Bendersky | f996e77 | 2012-03-16 05:53:30 +0200 | [diff] [blame] | 3979 |                 Py_DECREF(buffer); | 
 | 3980 |                 break; | 
 | 3981 |             } | 
 | 3982 |             temp = PyUnicode_AsEncodedString(buffer, "utf-8", "surrogatepass"); | 
| Antoine Pitrou | c194884 | 2012-10-01 23:40:37 +0200 | [diff] [blame] | 3983 |             Py_DECREF(buffer); | 
| Eli Bendersky | f996e77 | 2012-03-16 05:53:30 +0200 | [diff] [blame] | 3984 |             if (!temp) { | 
 | 3985 |                 /* Propagate exception from PyUnicode_AsEncodedString */ | 
| Eli Bendersky | f996e77 | 2012-03-16 05:53:30 +0200 | [diff] [blame] | 3986 |                 Py_DECREF(reader); | 
 | 3987 |                 return NULL; | 
 | 3988 |             } | 
| Eli Bendersky | f996e77 | 2012-03-16 05:53:30 +0200 | [diff] [blame] | 3989 |             buffer = temp; | 
 | 3990 |         } | 
 | 3991 |         else if (!PyBytes_CheckExact(buffer) || PyBytes_GET_SIZE(buffer) == 0) { | 
| Fredrik Lundh | 8c8836b | 2005-12-16 22:06:06 +0000 | [diff] [blame] | 3992 |             Py_DECREF(buffer); | 
 | 3993 |             break; | 
 | 3994 |         } | 
 | 3995 |  | 
| Serhiy Storchaka | 26861b0 | 2015-02-16 20:52:17 +0200 | [diff] [blame] | 3996 |         if (PyBytes_GET_SIZE(buffer) > INT_MAX) { | 
 | 3997 |             Py_DECREF(buffer); | 
 | 3998 |             Py_DECREF(reader); | 
 | 3999 |             PyErr_SetString(PyExc_OverflowError, "size does not fit in an int"); | 
 | 4000 |             return NULL; | 
 | 4001 |         } | 
| Fredrik Lundh | 8c8836b | 2005-12-16 22:06:06 +0000 | [diff] [blame] | 4002 |         res = expat_parse( | 
| Serhiy Storchaka | 26861b0 | 2015-02-16 20:52:17 +0200 | [diff] [blame] | 4003 |             self, PyBytes_AS_STRING(buffer), (int)PyBytes_GET_SIZE(buffer), 0 | 
| Fredrik Lundh | 8c8836b | 2005-12-16 22:06:06 +0000 | [diff] [blame] | 4004 |             ); | 
 | 4005 |  | 
 | 4006 |         Py_DECREF(buffer); | 
 | 4007 |  | 
 | 4008 |         if (!res) { | 
 | 4009 |             Py_DECREF(reader); | 
 | 4010 |             return NULL; | 
 | 4011 |         } | 
 | 4012 |         Py_DECREF(res); | 
 | 4013 |  | 
 | 4014 |     } | 
 | 4015 |  | 
 | 4016 |     Py_DECREF(reader); | 
 | 4017 |  | 
 | 4018 |     res = expat_parse(self, "", 0, 1); | 
 | 4019 |  | 
 | 4020 |     if (res && TreeBuilder_CheckExact(self->target)) { | 
 | 4021 |         Py_DECREF(res); | 
 | 4022 |         return treebuilder_done((TreeBuilderObject*) self->target); | 
 | 4023 |     } | 
 | 4024 |  | 
 | 4025 |     return res; | 
 | 4026 | } | 
 | 4027 |  | 
| Serhiy Storchaka | cb98556 | 2015-05-04 15:32:48 +0300 | [diff] [blame] | 4028 | /*[clinic input] | 
| Serhiy Storchaka | cb98556 | 2015-05-04 15:32:48 +0300 | [diff] [blame] | 4029 | _elementtree.XMLParser._setevents | 
 | 4030 |  | 
| Serhiy Storchaka | 9ec5e25 | 2015-12-07 02:31:11 +0200 | [diff] [blame] | 4031 |     events_queue: object | 
| Serhiy Storchaka | cb98556 | 2015-05-04 15:32:48 +0300 | [diff] [blame] | 4032 |     events_to_report: object = None | 
 | 4033 |     / | 
 | 4034 |  | 
 | 4035 | [clinic start generated code]*/ | 
 | 4036 |  | 
 | 4037 | static PyObject * | 
 | 4038 | _elementtree_XMLParser__setevents_impl(XMLParserObject *self, | 
 | 4039 |                                        PyObject *events_queue, | 
 | 4040 |                                        PyObject *events_to_report) | 
| Serhiy Storchaka | 9ec5e25 | 2015-12-07 02:31:11 +0200 | [diff] [blame] | 4041 | /*[clinic end generated code: output=1440092922b13ed1 input=abf90830a1c3b0fc]*/ | 
| Fredrik Lundh | 8c8836b | 2005-12-16 22:06:06 +0000 | [diff] [blame] | 4042 | { | 
 | 4043 |     /* activate element event reporting */ | 
| Serhiy Storchaka | bc4ded95 | 2015-12-24 11:51:57 +0200 | [diff] [blame] | 4044 |     Py_ssize_t i; | 
| Eli Bendersky | 3a4fbd8 | 2013-05-19 09:01:49 -0700 | [diff] [blame] | 4045 |     TreeBuilderObject *target; | 
| Serhiy Storchaka | 9ec5e25 | 2015-12-07 02:31:11 +0200 | [diff] [blame] | 4046 |     PyObject *events_append, *events_seq; | 
| Fredrik Lundh | 8c8836b | 2005-12-16 22:06:06 +0000 | [diff] [blame] | 4047 |  | 
 | 4048 |     if (!TreeBuilder_CheckExact(self->target)) { | 
 | 4049 |         PyErr_SetString( | 
 | 4050 |             PyExc_TypeError, | 
| Florent Xicluna | a72a98f | 2012-02-13 11:03:30 +0100 | [diff] [blame] | 4051 |             "event handling only supported for ElementTree.TreeBuilder " | 
| Fredrik Lundh | 8c8836b | 2005-12-16 22:06:06 +0000 | [diff] [blame] | 4052 |             "targets" | 
 | 4053 |             ); | 
 | 4054 |         return NULL; | 
 | 4055 |     } | 
 | 4056 |  | 
 | 4057 |     target = (TreeBuilderObject*) self->target; | 
 | 4058 |  | 
| Serhiy Storchaka | 9ec5e25 | 2015-12-07 02:31:11 +0200 | [diff] [blame] | 4059 |     events_append = PyObject_GetAttrString(events_queue, "append"); | 
 | 4060 |     if (events_append == NULL) | 
 | 4061 |         return NULL; | 
| Serhiy Storchaka | ec39756 | 2016-04-06 09:50:03 +0300 | [diff] [blame] | 4062 |     Py_XSETREF(target->events_append, events_append); | 
| Fredrik Lundh | 8c8836b | 2005-12-16 22:06:06 +0000 | [diff] [blame] | 4063 |  | 
 | 4064 |     /* clear out existing events */ | 
| Antoine Pitrou | c194884 | 2012-10-01 23:40:37 +0200 | [diff] [blame] | 4065 |     Py_CLEAR(target->start_event_obj); | 
 | 4066 |     Py_CLEAR(target->end_event_obj); | 
 | 4067 |     Py_CLEAR(target->start_ns_event_obj); | 
 | 4068 |     Py_CLEAR(target->end_ns_event_obj); | 
| Stefan Behnel | 43851a2 | 2019-05-01 21:20:38 +0200 | [diff] [blame] | 4069 |     Py_CLEAR(target->comment_event_obj); | 
 | 4070 |     Py_CLEAR(target->pi_event_obj); | 
| Fredrik Lundh | 8c8836b | 2005-12-16 22:06:06 +0000 | [diff] [blame] | 4071 |  | 
| Eli Bendersky | 3a4fbd8 | 2013-05-19 09:01:49 -0700 | [diff] [blame] | 4072 |     if (events_to_report == Py_None) { | 
| Fredrik Lundh | 8c8836b | 2005-12-16 22:06:06 +0000 | [diff] [blame] | 4073 |         /* default is "end" only */ | 
| Florent Xicluna | f15351d | 2010-03-13 23:24:31 +0000 | [diff] [blame] | 4074 |         target->end_event_obj = PyUnicode_FromString("end"); | 
| Fredrik Lundh | 8c8836b | 2005-12-16 22:06:06 +0000 | [diff] [blame] | 4075 |         Py_RETURN_NONE; | 
 | 4076 |     } | 
 | 4077 |  | 
| Eli Bendersky | 3a4fbd8 | 2013-05-19 09:01:49 -0700 | [diff] [blame] | 4078 |     if (!(events_seq = PySequence_Fast(events_to_report, | 
 | 4079 |                                        "events must be a sequence"))) { | 
 | 4080 |         return NULL; | 
 | 4081 |     } | 
| Fredrik Lundh | 8c8836b | 2005-12-16 22:06:06 +0000 | [diff] [blame] | 4082 |  | 
| Serhiy Storchaka | bf623ae | 2017-04-19 20:03:52 +0300 | [diff] [blame] | 4083 |     for (i = 0; i < PySequence_Fast_GET_SIZE(events_seq); ++i) { | 
| Eli Bendersky | 3a4fbd8 | 2013-05-19 09:01:49 -0700 | [diff] [blame] | 4084 |         PyObject *event_name_obj = PySequence_Fast_GET_ITEM(events_seq, i); | 
| Serhiy Storchaka | 85b0f5b | 2016-11-20 10:16:47 +0200 | [diff] [blame] | 4085 |         const char *event_name = NULL; | 
| Eli Bendersky | 3a4fbd8 | 2013-05-19 09:01:49 -0700 | [diff] [blame] | 4086 |         if (PyUnicode_Check(event_name_obj)) { | 
| Serhiy Storchaka | bc4ded95 | 2015-12-24 11:51:57 +0200 | [diff] [blame] | 4087 |             event_name = PyUnicode_AsUTF8(event_name_obj); | 
| Eli Bendersky | 3a4fbd8 | 2013-05-19 09:01:49 -0700 | [diff] [blame] | 4088 |         } else if (PyBytes_Check(event_name_obj)) { | 
 | 4089 |             event_name = PyBytes_AS_STRING(event_name_obj); | 
| Florent Xicluna | f15351d | 2010-03-13 23:24:31 +0000 | [diff] [blame] | 4090 |         } | 
| Eli Bendersky | 3a4fbd8 | 2013-05-19 09:01:49 -0700 | [diff] [blame] | 4091 |         if (event_name == NULL) { | 
 | 4092 |             Py_DECREF(events_seq); | 
 | 4093 |             PyErr_Format(PyExc_ValueError, "invalid events sequence"); | 
 | 4094 |             return NULL; | 
| Serhiy Storchaka | bc4ded95 | 2015-12-24 11:51:57 +0200 | [diff] [blame] | 4095 |         } | 
 | 4096 |  | 
 | 4097 |         Py_INCREF(event_name_obj); | 
 | 4098 |         if (strcmp(event_name, "start") == 0) { | 
| Serhiy Storchaka | 4884271 | 2016-04-06 09:45:48 +0300 | [diff] [blame] | 4099 |             Py_XSETREF(target->start_event_obj, event_name_obj); | 
| Eli Bendersky | 3a4fbd8 | 2013-05-19 09:01:49 -0700 | [diff] [blame] | 4100 |         } else if (strcmp(event_name, "end") == 0) { | 
| Serhiy Storchaka | 4884271 | 2016-04-06 09:45:48 +0300 | [diff] [blame] | 4101 |             Py_XSETREF(target->end_event_obj, event_name_obj); | 
| Eli Bendersky | 3a4fbd8 | 2013-05-19 09:01:49 -0700 | [diff] [blame] | 4102 |         } else if (strcmp(event_name, "start-ns") == 0) { | 
| Serhiy Storchaka | 4884271 | 2016-04-06 09:45:48 +0300 | [diff] [blame] | 4103 |             Py_XSETREF(target->start_ns_event_obj, event_name_obj); | 
| Fredrik Lundh | 8c8836b | 2005-12-16 22:06:06 +0000 | [diff] [blame] | 4104 |             EXPAT(SetNamespaceDeclHandler)( | 
 | 4105 |                 self->parser, | 
 | 4106 |                 (XML_StartNamespaceDeclHandler) expat_start_ns_handler, | 
 | 4107 |                 (XML_EndNamespaceDeclHandler) expat_end_ns_handler | 
 | 4108 |                 ); | 
| Eli Bendersky | 3a4fbd8 | 2013-05-19 09:01:49 -0700 | [diff] [blame] | 4109 |         } else if (strcmp(event_name, "end-ns") == 0) { | 
| Serhiy Storchaka | 4884271 | 2016-04-06 09:45:48 +0300 | [diff] [blame] | 4110 |             Py_XSETREF(target->end_ns_event_obj, event_name_obj); | 
| Fredrik Lundh | 8c8836b | 2005-12-16 22:06:06 +0000 | [diff] [blame] | 4111 |             EXPAT(SetNamespaceDeclHandler)( | 
 | 4112 |                 self->parser, | 
 | 4113 |                 (XML_StartNamespaceDeclHandler) expat_start_ns_handler, | 
 | 4114 |                 (XML_EndNamespaceDeclHandler) expat_end_ns_handler | 
 | 4115 |                 ); | 
| Stefan Behnel | 43851a2 | 2019-05-01 21:20:38 +0200 | [diff] [blame] | 4116 |         } else if (strcmp(event_name, "comment") == 0) { | 
 | 4117 |             Py_XSETREF(target->comment_event_obj, event_name_obj); | 
 | 4118 |             EXPAT(SetCommentHandler)( | 
 | 4119 |                 self->parser, | 
 | 4120 |                 (XML_CommentHandler) expat_comment_handler | 
 | 4121 |                 ); | 
 | 4122 |         } else if (strcmp(event_name, "pi") == 0) { | 
 | 4123 |             Py_XSETREF(target->pi_event_obj, event_name_obj); | 
 | 4124 |             EXPAT(SetProcessingInstructionHandler)( | 
 | 4125 |                 self->parser, | 
 | 4126 |                 (XML_ProcessingInstructionHandler) expat_pi_handler | 
 | 4127 |                 ); | 
| Fredrik Lundh | 8c8836b | 2005-12-16 22:06:06 +0000 | [diff] [blame] | 4128 |         } else { | 
| Serhiy Storchaka | bc4ded95 | 2015-12-24 11:51:57 +0200 | [diff] [blame] | 4129 |             Py_DECREF(event_name_obj); | 
| Eli Bendersky | 3a4fbd8 | 2013-05-19 09:01:49 -0700 | [diff] [blame] | 4130 |             Py_DECREF(events_seq); | 
 | 4131 |             PyErr_Format(PyExc_ValueError, "unknown event '%s'", event_name); | 
| Fredrik Lundh | 8c8836b | 2005-12-16 22:06:06 +0000 | [diff] [blame] | 4132 |             return NULL; | 
 | 4133 |         } | 
 | 4134 |     } | 
 | 4135 |  | 
| Eli Bendersky | 3a4fbd8 | 2013-05-19 09:01:49 -0700 | [diff] [blame] | 4136 |     Py_DECREF(events_seq); | 
| Fredrik Lundh | 8c8836b | 2005-12-16 22:06:06 +0000 | [diff] [blame] | 4137 |     Py_RETURN_NONE; | 
| Fredrik Lundh | 8c8836b | 2005-12-16 22:06:06 +0000 | [diff] [blame] | 4138 | } | 
 | 4139 |  | 
| Serhiy Storchaka | b2953fa | 2018-10-04 10:41:27 +0300 | [diff] [blame] | 4140 | static PyMemberDef xmlparser_members[] = { | 
 | 4141 |     {"entity", T_OBJECT, offsetof(XMLParserObject, entity), READONLY, NULL}, | 
 | 4142 |     {"target", T_OBJECT, offsetof(XMLParserObject, target), READONLY, NULL}, | 
 | 4143 |     {NULL} | 
 | 4144 | }; | 
| Fredrik Lundh | 8c8836b | 2005-12-16 22:06:06 +0000 | [diff] [blame] | 4145 |  | 
| Serhiy Storchaka | b2953fa | 2018-10-04 10:41:27 +0300 | [diff] [blame] | 4146 | static PyObject* | 
 | 4147 | xmlparser_version_getter(XMLParserObject *self, void *closure) | 
 | 4148 | { | 
 | 4149 |     return PyUnicode_FromFormat( | 
 | 4150 |         "Expat %d.%d.%d", XML_MAJOR_VERSION, | 
 | 4151 |         XML_MINOR_VERSION, XML_MICRO_VERSION); | 
| Fredrik Lundh | 8c8836b | 2005-12-16 22:06:06 +0000 | [diff] [blame] | 4152 | } | 
 | 4153 |  | 
| Serhiy Storchaka | b2953fa | 2018-10-04 10:41:27 +0300 | [diff] [blame] | 4154 | static PyGetSetDef xmlparser_getsetlist[] = { | 
 | 4155 |     {"version", (getter)xmlparser_version_getter, NULL, NULL}, | 
 | 4156 |     {NULL}, | 
 | 4157 | }; | 
 | 4158 |  | 
| Serhiy Storchaka | cb98556 | 2015-05-04 15:32:48 +0300 | [diff] [blame] | 4159 | #include "clinic/_elementtree.c.h" | 
 | 4160 |  | 
 | 4161 | static PyMethodDef element_methods[] = { | 
 | 4162 |  | 
 | 4163 |     _ELEMENTTREE_ELEMENT_CLEAR_METHODDEF | 
 | 4164 |  | 
 | 4165 |     _ELEMENTTREE_ELEMENT_GET_METHODDEF | 
 | 4166 |     _ELEMENTTREE_ELEMENT_SET_METHODDEF | 
 | 4167 |  | 
 | 4168 |     _ELEMENTTREE_ELEMENT_FIND_METHODDEF | 
 | 4169 |     _ELEMENTTREE_ELEMENT_FINDTEXT_METHODDEF | 
 | 4170 |     _ELEMENTTREE_ELEMENT_FINDALL_METHODDEF | 
 | 4171 |  | 
 | 4172 |     _ELEMENTTREE_ELEMENT_APPEND_METHODDEF | 
 | 4173 |     _ELEMENTTREE_ELEMENT_EXTEND_METHODDEF | 
 | 4174 |     _ELEMENTTREE_ELEMENT_INSERT_METHODDEF | 
 | 4175 |     _ELEMENTTREE_ELEMENT_REMOVE_METHODDEF | 
 | 4176 |  | 
 | 4177 |     _ELEMENTTREE_ELEMENT_ITER_METHODDEF | 
 | 4178 |     _ELEMENTTREE_ELEMENT_ITERTEXT_METHODDEF | 
 | 4179 |     _ELEMENTTREE_ELEMENT_ITERFIND_METHODDEF | 
 | 4180 |  | 
| Serhiy Storchaka | 762ec97 | 2017-03-30 18:12:06 +0300 | [diff] [blame] | 4181 |     _ELEMENTTREE_ELEMENT_GETITERATOR_METHODDEF | 
| Serhiy Storchaka | cb98556 | 2015-05-04 15:32:48 +0300 | [diff] [blame] | 4182 |     _ELEMENTTREE_ELEMENT_GETCHILDREN_METHODDEF | 
 | 4183 |  | 
 | 4184 |     _ELEMENTTREE_ELEMENT_ITEMS_METHODDEF | 
 | 4185 |     _ELEMENTTREE_ELEMENT_KEYS_METHODDEF | 
 | 4186 |  | 
 | 4187 |     _ELEMENTTREE_ELEMENT_MAKEELEMENT_METHODDEF | 
 | 4188 |  | 
 | 4189 |     _ELEMENTTREE_ELEMENT___COPY___METHODDEF | 
 | 4190 |     _ELEMENTTREE_ELEMENT___DEEPCOPY___METHODDEF | 
 | 4191 |     _ELEMENTTREE_ELEMENT___SIZEOF___METHODDEF | 
 | 4192 |     _ELEMENTTREE_ELEMENT___GETSTATE___METHODDEF | 
 | 4193 |     _ELEMENTTREE_ELEMENT___SETSTATE___METHODDEF | 
 | 4194 |  | 
 | 4195 |     {NULL, NULL} | 
 | 4196 | }; | 
 | 4197 |  | 
 | 4198 | static PyMappingMethods element_as_mapping = { | 
 | 4199 |     (lenfunc) element_length, | 
 | 4200 |     (binaryfunc) element_subscr, | 
 | 4201 |     (objobjargproc) element_ass_subscr, | 
 | 4202 | }; | 
 | 4203 |  | 
| Serhiy Storchaka | dde0815 | 2015-11-25 15:28:13 +0200 | [diff] [blame] | 4204 | static PyGetSetDef element_getsetlist[] = { | 
 | 4205 |     {"tag", | 
 | 4206 |         (getter)element_tag_getter, | 
 | 4207 |         (setter)element_tag_setter, | 
 | 4208 |         "A string identifying what kind of data this element represents"}, | 
 | 4209 |     {"text", | 
 | 4210 |         (getter)element_text_getter, | 
 | 4211 |         (setter)element_text_setter, | 
 | 4212 |         "A string of text directly after the start tag, or None"}, | 
 | 4213 |     {"tail", | 
 | 4214 |         (getter)element_tail_getter, | 
 | 4215 |         (setter)element_tail_setter, | 
 | 4216 |         "A string of text directly after the end tag, or None"}, | 
 | 4217 |     {"attrib", | 
 | 4218 |         (getter)element_attrib_getter, | 
 | 4219 |         (setter)element_attrib_setter, | 
 | 4220 |         "A dictionary containing the element's attributes"}, | 
 | 4221 |     {NULL}, | 
 | 4222 | }; | 
 | 4223 |  | 
| Serhiy Storchaka | cb98556 | 2015-05-04 15:32:48 +0300 | [diff] [blame] | 4224 | static PyTypeObject Element_Type = { | 
 | 4225 |     PyVarObject_HEAD_INIT(NULL, 0) | 
 | 4226 |     "xml.etree.ElementTree.Element", sizeof(ElementObject), 0, | 
 | 4227 |     /* methods */ | 
 | 4228 |     (destructor)element_dealloc,                    /* tp_dealloc */ | 
 | 4229 |     0,                                              /* tp_print */ | 
 | 4230 |     0,                                              /* tp_getattr */ | 
 | 4231 |     0,                                              /* tp_setattr */ | 
 | 4232 |     0,                                              /* tp_reserved */ | 
 | 4233 |     (reprfunc)element_repr,                         /* tp_repr */ | 
 | 4234 |     0,                                              /* tp_as_number */ | 
 | 4235 |     &element_as_sequence,                           /* tp_as_sequence */ | 
 | 4236 |     &element_as_mapping,                            /* tp_as_mapping */ | 
 | 4237 |     0,                                              /* tp_hash */ | 
 | 4238 |     0,                                              /* tp_call */ | 
 | 4239 |     0,                                              /* tp_str */ | 
| Serhiy Storchaka | dde0815 | 2015-11-25 15:28:13 +0200 | [diff] [blame] | 4240 |     PyObject_GenericGetAttr,                        /* tp_getattro */ | 
 | 4241 |     0,                                              /* tp_setattro */ | 
| Serhiy Storchaka | cb98556 | 2015-05-04 15:32:48 +0300 | [diff] [blame] | 4242 |     0,                                              /* tp_as_buffer */ | 
 | 4243 |     Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC, | 
 | 4244 |                                                     /* tp_flags */ | 
 | 4245 |     0,                                              /* tp_doc */ | 
 | 4246 |     (traverseproc)element_gc_traverse,              /* tp_traverse */ | 
 | 4247 |     (inquiry)element_gc_clear,                      /* tp_clear */ | 
 | 4248 |     0,                                              /* tp_richcompare */ | 
 | 4249 |     offsetof(ElementObject, weakreflist),           /* tp_weaklistoffset */ | 
 | 4250 |     0,                                              /* tp_iter */ | 
 | 4251 |     0,                                              /* tp_iternext */ | 
 | 4252 |     element_methods,                                /* tp_methods */ | 
 | 4253 |     0,                                              /* tp_members */ | 
| Serhiy Storchaka | dde0815 | 2015-11-25 15:28:13 +0200 | [diff] [blame] | 4254 |     element_getsetlist,                             /* tp_getset */ | 
| Serhiy Storchaka | cb98556 | 2015-05-04 15:32:48 +0300 | [diff] [blame] | 4255 |     0,                                              /* tp_base */ | 
 | 4256 |     0,                                              /* tp_dict */ | 
 | 4257 |     0,                                              /* tp_descr_get */ | 
 | 4258 |     0,                                              /* tp_descr_set */ | 
 | 4259 |     0,                                              /* tp_dictoffset */ | 
 | 4260 |     (initproc)element_init,                         /* tp_init */ | 
 | 4261 |     PyType_GenericAlloc,                            /* tp_alloc */ | 
 | 4262 |     element_new,                                    /* tp_new */ | 
 | 4263 |     0,                                              /* tp_free */ | 
 | 4264 | }; | 
 | 4265 |  | 
 | 4266 | static PyMethodDef treebuilder_methods[] = { | 
 | 4267 |     _ELEMENTTREE_TREEBUILDER_DATA_METHODDEF | 
 | 4268 |     _ELEMENTTREE_TREEBUILDER_START_METHODDEF | 
 | 4269 |     _ELEMENTTREE_TREEBUILDER_END_METHODDEF | 
| Stefan Behnel | 43851a2 | 2019-05-01 21:20:38 +0200 | [diff] [blame] | 4270 |     _ELEMENTTREE_TREEBUILDER_COMMENT_METHODDEF | 
 | 4271 |     _ELEMENTTREE_TREEBUILDER_PI_METHODDEF | 
| Serhiy Storchaka | cb98556 | 2015-05-04 15:32:48 +0300 | [diff] [blame] | 4272 |     _ELEMENTTREE_TREEBUILDER_CLOSE_METHODDEF | 
 | 4273 |     {NULL, NULL} | 
 | 4274 | }; | 
 | 4275 |  | 
 | 4276 | static PyTypeObject TreeBuilder_Type = { | 
 | 4277 |     PyVarObject_HEAD_INIT(NULL, 0) | 
 | 4278 |     "xml.etree.ElementTree.TreeBuilder", sizeof(TreeBuilderObject), 0, | 
 | 4279 |     /* methods */ | 
 | 4280 |     (destructor)treebuilder_dealloc,                /* tp_dealloc */ | 
 | 4281 |     0,                                              /* tp_print */ | 
 | 4282 |     0,                                              /* tp_getattr */ | 
 | 4283 |     0,                                              /* tp_setattr */ | 
 | 4284 |     0,                                              /* tp_reserved */ | 
 | 4285 |     0,                                              /* tp_repr */ | 
 | 4286 |     0,                                              /* tp_as_number */ | 
 | 4287 |     0,                                              /* tp_as_sequence */ | 
 | 4288 |     0,                                              /* tp_as_mapping */ | 
 | 4289 |     0,                                              /* tp_hash */ | 
 | 4290 |     0,                                              /* tp_call */ | 
 | 4291 |     0,                                              /* tp_str */ | 
 | 4292 |     0,                                              /* tp_getattro */ | 
 | 4293 |     0,                                              /* tp_setattro */ | 
 | 4294 |     0,                                              /* tp_as_buffer */ | 
 | 4295 |     Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC, | 
 | 4296 |                                                     /* tp_flags */ | 
 | 4297 |     0,                                              /* tp_doc */ | 
 | 4298 |     (traverseproc)treebuilder_gc_traverse,          /* tp_traverse */ | 
 | 4299 |     (inquiry)treebuilder_gc_clear,                  /* tp_clear */ | 
 | 4300 |     0,                                              /* tp_richcompare */ | 
 | 4301 |     0,                                              /* tp_weaklistoffset */ | 
 | 4302 |     0,                                              /* tp_iter */ | 
 | 4303 |     0,                                              /* tp_iternext */ | 
 | 4304 |     treebuilder_methods,                            /* tp_methods */ | 
 | 4305 |     0,                                              /* tp_members */ | 
 | 4306 |     0,                                              /* tp_getset */ | 
 | 4307 |     0,                                              /* tp_base */ | 
 | 4308 |     0,                                              /* tp_dict */ | 
 | 4309 |     0,                                              /* tp_descr_get */ | 
 | 4310 |     0,                                              /* tp_descr_set */ | 
 | 4311 |     0,                                              /* tp_dictoffset */ | 
 | 4312 |     _elementtree_TreeBuilder___init__,              /* tp_init */ | 
 | 4313 |     PyType_GenericAlloc,                            /* tp_alloc */ | 
 | 4314 |     treebuilder_new,                                /* tp_new */ | 
 | 4315 |     0,                                              /* tp_free */ | 
 | 4316 | }; | 
 | 4317 |  | 
 | 4318 | static PyMethodDef xmlparser_methods[] = { | 
 | 4319 |     _ELEMENTTREE_XMLPARSER_FEED_METHODDEF | 
 | 4320 |     _ELEMENTTREE_XMLPARSER_CLOSE_METHODDEF | 
 | 4321 |     _ELEMENTTREE_XMLPARSER__PARSE_WHOLE_METHODDEF | 
 | 4322 |     _ELEMENTTREE_XMLPARSER__SETEVENTS_METHODDEF | 
| Serhiy Storchaka | cb98556 | 2015-05-04 15:32:48 +0300 | [diff] [blame] | 4323 |     {NULL, NULL} | 
 | 4324 | }; | 
 | 4325 |  | 
| Neal Norwitz | 227b533 | 2006-03-22 09:28:35 +0000 | [diff] [blame] | 4326 | static PyTypeObject XMLParser_Type = { | 
| Martin v. Löwis | 9f2e346 | 2007-07-21 17:22:18 +0000 | [diff] [blame] | 4327 |     PyVarObject_HEAD_INIT(NULL, 0) | 
| Eli Bendersky | 698bdb2 | 2013-01-10 06:01:06 -0800 | [diff] [blame] | 4328 |     "xml.etree.ElementTree.XMLParser", sizeof(XMLParserObject), 0, | 
| Fredrik Lundh | 8c8836b | 2005-12-16 22:06:06 +0000 | [diff] [blame] | 4329 |     /* methods */ | 
| Eli Bendersky | 52467b1 | 2012-06-01 07:13:08 +0300 | [diff] [blame] | 4330 |     (destructor)xmlparser_dealloc,                  /* tp_dealloc */ | 
 | 4331 |     0,                                              /* tp_print */ | 
 | 4332 |     0,                                              /* tp_getattr */ | 
 | 4333 |     0,                                              /* tp_setattr */ | 
 | 4334 |     0,                                              /* tp_reserved */ | 
 | 4335 |     0,                                              /* tp_repr */ | 
 | 4336 |     0,                                              /* tp_as_number */ | 
 | 4337 |     0,                                              /* tp_as_sequence */ | 
 | 4338 |     0,                                              /* tp_as_mapping */ | 
 | 4339 |     0,                                              /* tp_hash */ | 
 | 4340 |     0,                                              /* tp_call */ | 
 | 4341 |     0,                                              /* tp_str */ | 
| Serhiy Storchaka | b2953fa | 2018-10-04 10:41:27 +0300 | [diff] [blame] | 4342 |     0,                                              /* tp_getattro */ | 
| Eli Bendersky | 52467b1 | 2012-06-01 07:13:08 +0300 | [diff] [blame] | 4343 |     0,                                              /* tp_setattro */ | 
 | 4344 |     0,                                              /* tp_as_buffer */ | 
 | 4345 |     Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC, | 
 | 4346 |                                                     /* tp_flags */ | 
 | 4347 |     0,                                              /* tp_doc */ | 
 | 4348 |     (traverseproc)xmlparser_gc_traverse,            /* tp_traverse */ | 
 | 4349 |     (inquiry)xmlparser_gc_clear,                    /* tp_clear */ | 
 | 4350 |     0,                                              /* tp_richcompare */ | 
 | 4351 |     0,                                              /* tp_weaklistoffset */ | 
 | 4352 |     0,                                              /* tp_iter */ | 
 | 4353 |     0,                                              /* tp_iternext */ | 
 | 4354 |     xmlparser_methods,                              /* tp_methods */ | 
| Serhiy Storchaka | b2953fa | 2018-10-04 10:41:27 +0300 | [diff] [blame] | 4355 |     xmlparser_members,                              /* tp_members */ | 
 | 4356 |     xmlparser_getsetlist,                           /* tp_getset */ | 
| Eli Bendersky | 52467b1 | 2012-06-01 07:13:08 +0300 | [diff] [blame] | 4357 |     0,                                              /* tp_base */ | 
 | 4358 |     0,                                              /* tp_dict */ | 
 | 4359 |     0,                                              /* tp_descr_get */ | 
 | 4360 |     0,                                              /* tp_descr_set */ | 
 | 4361 |     0,                                              /* tp_dictoffset */ | 
| Serhiy Storchaka | cb98556 | 2015-05-04 15:32:48 +0300 | [diff] [blame] | 4362 |     _elementtree_XMLParser___init__,                /* tp_init */ | 
| Eli Bendersky | 52467b1 | 2012-06-01 07:13:08 +0300 | [diff] [blame] | 4363 |     PyType_GenericAlloc,                            /* tp_alloc */ | 
 | 4364 |     xmlparser_new,                                  /* tp_new */ | 
 | 4365 |     0,                                              /* tp_free */ | 
| Fredrik Lundh | 8c8836b | 2005-12-16 22:06:06 +0000 | [diff] [blame] | 4366 | }; | 
 | 4367 |  | 
| Fredrik Lundh | 8c8836b | 2005-12-16 22:06:06 +0000 | [diff] [blame] | 4368 | /* ==================================================================== */ | 
 | 4369 | /* python module interface */ | 
 | 4370 |  | 
 | 4371 | static PyMethodDef _functions[] = { | 
| Serhiy Storchaka | 62be742 | 2018-11-27 13:27:31 +0200 | [diff] [blame] | 4372 |     {"SubElement", (PyCFunction)(void(*)(void)) subelement, METH_VARARGS | METH_KEYWORDS}, | 
| Stefan Behnel | 43851a2 | 2019-05-01 21:20:38 +0200 | [diff] [blame] | 4373 |     _ELEMENTTREE__SET_FACTORIES_METHODDEF | 
| Fredrik Lundh | 8c8836b | 2005-12-16 22:06:06 +0000 | [diff] [blame] | 4374 |     {NULL, NULL} | 
 | 4375 | }; | 
 | 4376 |  | 
| Martin v. Löwis | 1a21451 | 2008-06-11 05:26:20 +0000 | [diff] [blame] | 4377 |  | 
| Eli Bendersky | 532d03e | 2013-08-10 08:00:39 -0700 | [diff] [blame] | 4378 | static struct PyModuleDef elementtreemodule = { | 
 | 4379 |     PyModuleDef_HEAD_INIT, | 
 | 4380 |     "_elementtree", | 
 | 4381 |     NULL, | 
 | 4382 |     sizeof(elementtreestate), | 
 | 4383 |     _functions, | 
 | 4384 |     NULL, | 
 | 4385 |     elementtree_traverse, | 
 | 4386 |     elementtree_clear, | 
 | 4387 |     elementtree_free | 
| Martin v. Löwis | 1a21451 | 2008-06-11 05:26:20 +0000 | [diff] [blame] | 4388 | }; | 
 | 4389 |  | 
| Neal Norwitz | f6657e6 | 2006-12-28 04:47:50 +0000 | [diff] [blame] | 4390 | PyMODINIT_FUNC | 
| Martin v. Löwis | 1a21451 | 2008-06-11 05:26:20 +0000 | [diff] [blame] | 4391 | PyInit__elementtree(void) | 
| Fredrik Lundh | 8c8836b | 2005-12-16 22:06:06 +0000 | [diff] [blame] | 4392 | { | 
| Eli Bendersky | 64d11e6 | 2012-06-15 07:42:50 +0300 | [diff] [blame] | 4393 |     PyObject *m, *temp; | 
| Eli Bendersky | 532d03e | 2013-08-10 08:00:39 -0700 | [diff] [blame] | 4394 |     elementtreestate *st; | 
 | 4395 |  | 
 | 4396 |     m = PyState_FindModule(&elementtreemodule); | 
 | 4397 |     if (m) { | 
 | 4398 |         Py_INCREF(m); | 
 | 4399 |         return m; | 
 | 4400 |     } | 
| Fredrik Lundh | 8c8836b | 2005-12-16 22:06:06 +0000 | [diff] [blame] | 4401 |  | 
| Amaury Forgeot d'Arc | ba4105c | 2008-07-02 21:41:01 +0000 | [diff] [blame] | 4402 |     /* Initialize object types */ | 
| Ronald Oussoren | 138d080 | 2013-07-19 11:11:25 +0200 | [diff] [blame] | 4403 |     if (PyType_Ready(&ElementIter_Type) < 0) | 
 | 4404 |         return NULL; | 
| Amaury Forgeot d'Arc | ba4105c | 2008-07-02 21:41:01 +0000 | [diff] [blame] | 4405 |     if (PyType_Ready(&TreeBuilder_Type) < 0) | 
| Alexander Belopolsky | f0f4514 | 2010-08-11 17:31:17 +0000 | [diff] [blame] | 4406 |         return NULL; | 
| Amaury Forgeot d'Arc | ba4105c | 2008-07-02 21:41:01 +0000 | [diff] [blame] | 4407 |     if (PyType_Ready(&Element_Type) < 0) | 
| Alexander Belopolsky | f0f4514 | 2010-08-11 17:31:17 +0000 | [diff] [blame] | 4408 |         return NULL; | 
| Amaury Forgeot d'Arc | ba4105c | 2008-07-02 21:41:01 +0000 | [diff] [blame] | 4409 |     if (PyType_Ready(&XMLParser_Type) < 0) | 
| Alexander Belopolsky | f0f4514 | 2010-08-11 17:31:17 +0000 | [diff] [blame] | 4410 |         return NULL; | 
| Fredrik Lundh | 8c8836b | 2005-12-16 22:06:06 +0000 | [diff] [blame] | 4411 |  | 
| Eli Bendersky | 532d03e | 2013-08-10 08:00:39 -0700 | [diff] [blame] | 4412 |     m = PyModule_Create(&elementtreemodule); | 
| Fredrik Lundh | 44ed4db | 2006-03-12 21:06:35 +0000 | [diff] [blame] | 4413 |     if (!m) | 
| Martin v. Löwis | 1a21451 | 2008-06-11 05:26:20 +0000 | [diff] [blame] | 4414 |         return NULL; | 
| Eli Bendersky | 532d03e | 2013-08-10 08:00:39 -0700 | [diff] [blame] | 4415 |     st = ET_STATE(m); | 
| Martin v. Löwis | 1a21451 | 2008-06-11 05:26:20 +0000 | [diff] [blame] | 4416 |  | 
| Eli Bendersky | 828efde | 2012-04-05 05:40:58 +0300 | [diff] [blame] | 4417 |     if (!(temp = PyImport_ImportModule("copy"))) | 
 | 4418 |         return NULL; | 
| Eli Bendersky | 532d03e | 2013-08-10 08:00:39 -0700 | [diff] [blame] | 4419 |     st->deepcopy_obj = PyObject_GetAttrString(temp, "deepcopy"); | 
| Eli Bendersky | 828efde | 2012-04-05 05:40:58 +0300 | [diff] [blame] | 4420 |     Py_XDECREF(temp); | 
 | 4421 |  | 
| Victor Stinner | b136f11 | 2017-07-10 22:28:02 +0200 | [diff] [blame] | 4422 |     if (st->deepcopy_obj == NULL) { | 
 | 4423 |         return NULL; | 
 | 4424 |     } | 
 | 4425 |  | 
 | 4426 |     assert(!PyErr_Occurred()); | 
| Eli Bendersky | 532d03e | 2013-08-10 08:00:39 -0700 | [diff] [blame] | 4427 |     if (!(st->elementpath_obj = PyImport_ImportModule("xml.etree.ElementPath"))) | 
| Eli Bendersky | 828efde | 2012-04-05 05:40:58 +0300 | [diff] [blame] | 4428 |         return NULL; | 
 | 4429 |  | 
| Eli Bendersky | 20d4174 | 2012-06-01 09:48:37 +0300 | [diff] [blame] | 4430 |     /* link against pyexpat */ | 
| Florent Xicluna | f15351d | 2010-03-13 23:24:31 +0000 | [diff] [blame] | 4431 |     expat_capi = PyCapsule_Import(PyExpat_CAPSULE_NAME, 0); | 
 | 4432 |     if (expat_capi) { | 
 | 4433 |         /* check that it's usable */ | 
 | 4434 |         if (strcmp(expat_capi->magic, PyExpat_CAPI_MAGIC) != 0 || | 
| Victor Stinner | 706768c | 2014-08-16 01:03:39 +0200 | [diff] [blame] | 4435 |             (size_t)expat_capi->size < sizeof(struct PyExpat_CAPI) || | 
| Florent Xicluna | f15351d | 2010-03-13 23:24:31 +0000 | [diff] [blame] | 4436 |             expat_capi->MAJOR_VERSION != XML_MAJOR_VERSION || | 
 | 4437 |             expat_capi->MINOR_VERSION != XML_MINOR_VERSION || | 
| Eli Bendersky | 52467b1 | 2012-06-01 07:13:08 +0300 | [diff] [blame] | 4438 |             expat_capi->MICRO_VERSION != XML_MICRO_VERSION) { | 
| Eli Bendersky | ef391ac | 2012-07-21 20:28:46 +0300 | [diff] [blame] | 4439 |             PyErr_SetString(PyExc_ImportError, | 
 | 4440 |                             "pyexpat version is incompatible"); | 
 | 4441 |             return NULL; | 
| Eli Bendersky | 52467b1 | 2012-06-01 07:13:08 +0300 | [diff] [blame] | 4442 |         } | 
| Eli Bendersky | ef391ac | 2012-07-21 20:28:46 +0300 | [diff] [blame] | 4443 |     } else { | 
| Eli Bendersky | 52467b1 | 2012-06-01 07:13:08 +0300 | [diff] [blame] | 4444 |         return NULL; | 
| Eli Bendersky | ef391ac | 2012-07-21 20:28:46 +0300 | [diff] [blame] | 4445 |     } | 
| Fredrik Lundh | 8c8836b | 2005-12-16 22:06:06 +0000 | [diff] [blame] | 4446 |  | 
| Eli Bendersky | 532d03e | 2013-08-10 08:00:39 -0700 | [diff] [blame] | 4447 |     st->parseerror_obj = PyErr_NewException( | 
| Florent Xicluna | a72a98f | 2012-02-13 11:03:30 +0100 | [diff] [blame] | 4448 |         "xml.etree.ElementTree.ParseError", PyExc_SyntaxError, NULL | 
| Florent Xicluna | f15351d | 2010-03-13 23:24:31 +0000 | [diff] [blame] | 4449 |         ); | 
| Eli Bendersky | 532d03e | 2013-08-10 08:00:39 -0700 | [diff] [blame] | 4450 |     Py_INCREF(st->parseerror_obj); | 
 | 4451 |     PyModule_AddObject(m, "ParseError", st->parseerror_obj); | 
| Florent Xicluna | f15351d | 2010-03-13 23:24:31 +0000 | [diff] [blame] | 4452 |  | 
| Eli Bendersky | 092af1f | 2012-03-04 07:14:03 +0200 | [diff] [blame] | 4453 |     Py_INCREF((PyObject *)&Element_Type); | 
 | 4454 |     PyModule_AddObject(m, "Element", (PyObject *)&Element_Type); | 
 | 4455 |  | 
| Eli Bendersky | 58d548d | 2012-05-29 15:45:16 +0300 | [diff] [blame] | 4456 |     Py_INCREF((PyObject *)&TreeBuilder_Type); | 
 | 4457 |     PyModule_AddObject(m, "TreeBuilder", (PyObject *)&TreeBuilder_Type); | 
 | 4458 |  | 
| Eli Bendersky | 52467b1 | 2012-06-01 07:13:08 +0300 | [diff] [blame] | 4459 |     Py_INCREF((PyObject *)&XMLParser_Type); | 
 | 4460 |     PyModule_AddObject(m, "XMLParser", (PyObject *)&XMLParser_Type); | 
| Eli Bendersky | 52467b1 | 2012-06-01 07:13:08 +0300 | [diff] [blame] | 4461 |  | 
| Florent Xicluna | f15351d | 2010-03-13 23:24:31 +0000 | [diff] [blame] | 4462 |     return m; | 
| Fredrik Lundh | 8c8836b | 2005-12-16 22:06:06 +0000 | [diff] [blame] | 4463 | } |