summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Modules/_elementtree.c85
1 files changed, 42 insertions, 43 deletions
diff --git a/Modules/_elementtree.c b/Modules/_elementtree.c
index 42de3c6..00d9f64 100644
--- a/Modules/_elementtree.c
+++ b/Modules/_elementtree.c
@@ -15,6 +15,8 @@
#include "Python.h"
#include "structmember.h" // PyMemberDef
+#include "expat.h"
+#include "pyexpat.h"
/* -------------------------------------------------------------------- */
/* configuration */
@@ -90,6 +92,8 @@ typedef struct {
PyTypeObject *ElementIter_Type;
PyTypeObject *TreeBuilder_Type;
PyTypeObject *XMLParser_Type;
+
+ struct PyExpat_CAPI *expat_capi;
} elementtreestate;
static struct PyModuleDef elementtreemodule;
@@ -146,6 +150,8 @@ elementtree_clear(PyObject *m)
Py_CLEAR(st->ElementIter_Type);
Py_CLEAR(st->TreeBuilder_Type);
Py_CLEAR(st->XMLParser_Type);
+
+ st->expat_capi = NULL;
return 0;
}
@@ -3031,14 +3037,7 @@ _elementtree_TreeBuilder_start_impl(TreeBuilderObject *self, PyObject *tag,
/* ==================================================================== */
/* the expat interface */
-#include "expat.h"
-#include "pyexpat.h"
-
-/* The PyExpat_CAPI structure is an immutable dispatch table, so it can be
- * cached globally without being in per-module state.
- */
-static struct PyExpat_CAPI *expat_capi;
-#define EXPAT(func) (expat_capi->func)
+#define EXPAT(st, func) ((st)->expat_capi->func)
static XML_Memory_Handling_Suite ExpatMemoryHandler = {
PyObject_Malloc, PyObject_Realloc, PyObject_Free};
@@ -3147,7 +3146,7 @@ expat_set_error(elementtreestate *st, enum XML_Error error_code,
PyObject *errmsg, *error, *position, *code;
errmsg = PyUnicode_FromFormat("%s: line %zd, column %zd",
- message ? message : EXPAT(ErrorString)(error_code),
+ message ? message : EXPAT(st, ErrorString)(error_code),
line, column);
if (errmsg == NULL)
return;
@@ -3227,8 +3226,8 @@ expat_default_handler(XMLParserObject* self, const XML_Char* data_in,
expat_set_error(
st,
XML_ERROR_UNDEFINED_ENTITY,
- EXPAT(GetErrorLineNumber)(self->parser),
- EXPAT(GetErrorColumnNumber)(self->parser),
+ EXPAT(st, GetErrorLineNumber)(self->parser),
+ EXPAT(st, GetErrorColumnNumber)(self->parser),
message
);
}
@@ -3648,8 +3647,8 @@ _elementtree_XMLParser___init___impl(XMLParserObject *self, PyObject *target,
Py_CLEAR(self->entity);
return -1;
}
-
- self->parser = EXPAT(ParserCreate_MM)(encoding, &ExpatMemoryHandler, "}");
+ elementtreestate *st = self->state;
+ self->parser = EXPAT(st, ParserCreate_MM)(encoding, &ExpatMemoryHandler, "}");
if (!self->parser) {
Py_CLEAR(self->entity);
Py_CLEAR(self->names);
@@ -3657,15 +3656,14 @@ _elementtree_XMLParser___init___impl(XMLParserObject *self, PyObject *target,
return -1;
}
/* expat < 2.1.0 has no XML_SetHashSalt() */
- if (EXPAT(SetHashSalt) != NULL) {
- EXPAT(SetHashSalt)(self->parser,
+ if (EXPAT(st, SetHashSalt) != NULL) {
+ EXPAT(st, SetHashSalt)(self->parser,
(unsigned long)_Py_HashSecret.expat.hashsalt);
}
if (target != Py_None) {
Py_INCREF(target);
} else {
- elementtreestate *st = self->state;
target = treebuilder_new(st->TreeBuilder_Type, NULL, NULL);
if (!target) {
Py_CLEAR(self->entity);
@@ -3713,43 +3711,43 @@ _elementtree_XMLParser___init___impl(XMLParserObject *self, PyObject *target,
}
/* configure parser */
- EXPAT(SetUserData)(self->parser, self);
+ EXPAT(st, SetUserData)(self->parser, self);
if (self->handle_start_ns || self->handle_end_ns)
- EXPAT(SetNamespaceDeclHandler)(
+ EXPAT(st, SetNamespaceDeclHandler)(
self->parser,
(XML_StartNamespaceDeclHandler) expat_start_ns_handler,
(XML_EndNamespaceDeclHandler) expat_end_ns_handler
);
- EXPAT(SetElementHandler)(
+ EXPAT(st, SetElementHandler)(
self->parser,
(XML_StartElementHandler) expat_start_handler,
(XML_EndElementHandler) expat_end_handler
);
- EXPAT(SetDefaultHandlerExpand)(
+ EXPAT(st, SetDefaultHandlerExpand)(
self->parser,
(XML_DefaultHandler) expat_default_handler
);
- EXPAT(SetCharacterDataHandler)(
+ EXPAT(st, SetCharacterDataHandler)(
self->parser,
(XML_CharacterDataHandler) expat_data_handler
);
if (self->handle_comment)
- EXPAT(SetCommentHandler)(
+ EXPAT(st, SetCommentHandler)(
self->parser,
(XML_CommentHandler) expat_comment_handler
);
if (self->handle_pi)
- EXPAT(SetProcessingInstructionHandler)(
+ EXPAT(st, SetProcessingInstructionHandler)(
self->parser,
(XML_ProcessingInstructionHandler) expat_pi_handler
);
- EXPAT(SetStartDoctypeDeclHandler)(
+ EXPAT(st, SetStartDoctypeDeclHandler)(
self->parser,
(XML_StartDoctypeDeclHandler) expat_start_doctype_handler
);
- EXPAT(SetUnknownEncodingHandler)(
+ EXPAT(st, SetUnknownEncodingHandler)(
self->parser,
- EXPAT(DefaultUnknownEncodingHandler), NULL
+ EXPAT(st, DefaultUnknownEncodingHandler), NULL
);
return 0;
@@ -3779,10 +3777,11 @@ xmlparser_gc_traverse(XMLParserObject *self, visitproc visit, void *arg)
static int
xmlparser_gc_clear(XMLParserObject *self)
{
+ elementtreestate *st = self->state;
if (self->parser != NULL) {
XML_Parser parser = self->parser;
self->parser = NULL;
- EXPAT(ParserFree)(parser);
+ EXPAT(st, ParserFree)(parser);
}
Py_CLEAR(self->handle_close);
@@ -3830,7 +3829,7 @@ expat_parse(elementtreestate *st, XMLParserObject *self, const char *data,
int ok;
assert(!PyErr_Occurred());
- ok = EXPAT(Parse)(self->parser, data, data_len, final);
+ ok = EXPAT(st, Parse)(self->parser, data, data_len, final);
if (PyErr_Occurred())
return NULL;
@@ -3838,9 +3837,9 @@ expat_parse(elementtreestate *st, XMLParserObject *self, const char *data,
if (!ok) {
expat_set_error(
st,
- EXPAT(GetErrorCode)(self->parser),
- EXPAT(GetErrorLineNumber)(self->parser),
- EXPAT(GetErrorColumnNumber)(self->parser),
+ EXPAT(st, GetErrorCode)(self->parser),
+ EXPAT(st, GetErrorLineNumber)(self->parser),
+ EXPAT(st, GetErrorColumnNumber)(self->parser),
NULL
);
return NULL;
@@ -3911,7 +3910,7 @@ _elementtree_XMLParser_feed(XMLParserObject *self, PyObject *data)
return NULL;
}
/* Explicitly set UTF-8 encoding. Return code ignored. */
- (void)EXPAT(SetEncoding)(self->parser, "utf-8");
+ (void)EXPAT(st, SetEncoding)(self->parser, "utf-8");
return expat_parse(st, self, data_ptr, (int)data_len, 0);
}
@@ -4099,27 +4098,27 @@ _elementtree_XMLParser__setevents_impl(XMLParserObject *self,
Py_XSETREF(target->end_event_obj, Py_NewRef(event_name_obj));
} else if (strcmp(event_name, "start-ns") == 0) {
Py_XSETREF(target->start_ns_event_obj, Py_NewRef(event_name_obj));
- EXPAT(SetNamespaceDeclHandler)(
+ EXPAT(st, SetNamespaceDeclHandler)(
self->parser,
(XML_StartNamespaceDeclHandler) expat_start_ns_handler,
(XML_EndNamespaceDeclHandler) expat_end_ns_handler
);
} else if (strcmp(event_name, "end-ns") == 0) {
Py_XSETREF(target->end_ns_event_obj, Py_NewRef(event_name_obj));
- EXPAT(SetNamespaceDeclHandler)(
+ EXPAT(st, SetNamespaceDeclHandler)(
self->parser,
(XML_StartNamespaceDeclHandler) expat_start_ns_handler,
(XML_EndNamespaceDeclHandler) expat_end_ns_handler
);
} else if (strcmp(event_name, "comment") == 0) {
Py_XSETREF(target->comment_event_obj, Py_NewRef(event_name_obj));
- EXPAT(SetCommentHandler)(
+ EXPAT(st, SetCommentHandler)(
self->parser,
(XML_CommentHandler) expat_comment_handler
);
} else if (strcmp(event_name, "pi") == 0) {
Py_XSETREF(target->pi_event_obj, Py_NewRef(event_name_obj));
- EXPAT(SetProcessingInstructionHandler)(
+ EXPAT(st, SetProcessingInstructionHandler)(
self->parser,
(XML_ProcessingInstructionHandler) expat_pi_handler
);
@@ -4344,14 +4343,14 @@ module_exec(PyObject *m)
goto error;
/* link against pyexpat */
- expat_capi = PyCapsule_Import(PyExpat_CAPSULE_NAME, 0);
- if (expat_capi) {
+ st->expat_capi = PyCapsule_Import(PyExpat_CAPSULE_NAME, 0);
+ if (st->expat_capi) {
/* check that it's usable */
- if (strcmp(expat_capi->magic, PyExpat_CAPI_MAGIC) != 0 ||
- (size_t)expat_capi->size < sizeof(struct PyExpat_CAPI) ||
- expat_capi->MAJOR_VERSION != XML_MAJOR_VERSION ||
- expat_capi->MINOR_VERSION != XML_MINOR_VERSION ||
- expat_capi->MICRO_VERSION != XML_MICRO_VERSION) {
+ if (strcmp(st->expat_capi->magic, PyExpat_CAPI_MAGIC) != 0 ||
+ (size_t)st->expat_capi->size < sizeof(struct PyExpat_CAPI) ||
+ st->expat_capi->MAJOR_VERSION != XML_MAJOR_VERSION ||
+ st->expat_capi->MINOR_VERSION != XML_MINOR_VERSION ||
+ st->expat_capi->MICRO_VERSION != XML_MICRO_VERSION) {
PyErr_SetString(PyExc_ImportError,
"pyexpat version is incompatible");
goto error;