ParserCreate(): Allow an empty string for the namespace_separator argument;
while not generally a good idea, this is used by RDF users, and works to implement RDF-style namespace+localname concatenation as defined in the RDF specifications. (This also corrects a backwards-compatibility bug.) Be more conservative while clearing out handlers; set the slot in the self->handlers array to NULL before DECREFing the callback. Still more adjustments to make the code style internally consistent.
This commit is contained in:
parent
c09cee4d92
commit
cde79131ea
|
@ -963,9 +963,9 @@ xmlparse_ExternalEntityParserCreate(xmlparseobject *self, PyObject *args)
|
||||||
xmlparseobject *new_parser;
|
xmlparseobject *new_parser;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
if (!PyArg_ParseTuple(args, "s|s:ExternalEntityParserCreate", &context,
|
if (!PyArg_ParseTuple(args, "s|s:ExternalEntityParserCreate",
|
||||||
&encoding)) {
|
&context, &encoding)) {
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
#if PY_MAJOR_VERSION == 1 && PY_MINOR_VERSION < 6
|
#if PY_MAJOR_VERSION == 1 && PY_MINOR_VERSION < 6
|
||||||
|
@ -1143,7 +1143,7 @@ newxmlparseobject(char *encoding, char *namespace_separator)
|
||||||
self->specified_attributes = 0;
|
self->specified_attributes = 0;
|
||||||
self->in_callback = 0;
|
self->in_callback = 0;
|
||||||
self->handlers = NULL;
|
self->handlers = NULL;
|
||||||
if (namespace_separator) {
|
if (namespace_separator != NULL) {
|
||||||
self->itself = XML_ParserCreateNS(encoding, *namespace_separator);
|
self->itself = XML_ParserCreateNS(encoding, *namespace_separator);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
@ -1186,8 +1186,11 @@ xmlparse_dealloc(xmlparseobject *self)
|
||||||
self->itself = NULL;
|
self->itself = NULL;
|
||||||
|
|
||||||
if (self->handlers != NULL) {
|
if (self->handlers != NULL) {
|
||||||
|
PyObject *temp;
|
||||||
for (i = 0; handler_info[i].name != NULL; i++) {
|
for (i = 0; handler_info[i].name != NULL; i++) {
|
||||||
Py_XDECREF(self->handlers[i]);
|
temp = self->handlers[i];
|
||||||
|
self->handlers[i] = NULL;
|
||||||
|
Py_XDECREF(temp);
|
||||||
}
|
}
|
||||||
free(self->handlers);
|
free(self->handlers);
|
||||||
}
|
}
|
||||||
|
@ -1318,22 +1321,22 @@ xmlparse_setattr(xmlparseobject *self, char *name, PyObject *v)
|
||||||
static int
|
static int
|
||||||
xmlparse_traverse(xmlparseobject *op, visitproc visit, void *arg)
|
xmlparse_traverse(xmlparseobject *op, visitproc visit, void *arg)
|
||||||
{
|
{
|
||||||
int i, err;
|
int i, err;
|
||||||
for (i = 0; handler_info[i].name != NULL; i++) {
|
for (i = 0; handler_info[i].name != NULL; i++) {
|
||||||
if (!op->handlers[i])
|
if (!op->handlers[i])
|
||||||
continue;
|
continue;
|
||||||
err = visit(op->handlers[i], arg);
|
err = visit(op->handlers[i], arg);
|
||||||
if (err)
|
if (err)
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
xmlparse_clear(xmlparseobject *op)
|
xmlparse_clear(xmlparseobject *op)
|
||||||
{
|
{
|
||||||
clear_handlers(op, 1);
|
clear_handlers(op, 1);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -1382,21 +1385,21 @@ Return a new XML parser object.";
|
||||||
static PyObject *
|
static PyObject *
|
||||||
pyexpat_ParserCreate(PyObject *notused, PyObject *args, PyObject *kw)
|
pyexpat_ParserCreate(PyObject *notused, PyObject *args, PyObject *kw)
|
||||||
{
|
{
|
||||||
char *encoding = NULL;
|
char *encoding = NULL;
|
||||||
char *namespace_separator = NULL;
|
char *namespace_separator = NULL;
|
||||||
static char *kwlist[] = {"encoding", "namespace_separator", NULL};
|
static char *kwlist[] = {"encoding", "namespace_separator", NULL};
|
||||||
|
|
||||||
if (!PyArg_ParseTupleAndKeywords(args, kw, "|zz:ParserCreate", kwlist,
|
if (!PyArg_ParseTupleAndKeywords(args, kw, "|zz:ParserCreate", kwlist,
|
||||||
&encoding, &namespace_separator))
|
&encoding, &namespace_separator))
|
||||||
return NULL;
|
return NULL;
|
||||||
if (namespace_separator != NULL
|
if (namespace_separator != NULL
|
||||||
&& strlen(namespace_separator) != 1) {
|
&& strlen(namespace_separator) > 1) {
|
||||||
PyErr_SetString(PyExc_ValueError,
|
PyErr_SetString(PyExc_ValueError,
|
||||||
"namespace_separator must be one character,"
|
"namespace_separator must be at most one"
|
||||||
" omitted, or None");
|
" character, omitted, or None");
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
return newxmlparseobject(encoding, namespace_separator);
|
return newxmlparseobject(encoding, namespace_separator);
|
||||||
}
|
}
|
||||||
|
|
||||||
static char pyexpat_ErrorString__doc__[] =
|
static char pyexpat_ErrorString__doc__[] =
|
||||||
|
@ -1429,38 +1432,34 @@ static struct PyMethodDef pyexpat_methods[] = {
|
||||||
static char pyexpat_module_documentation[] =
|
static char pyexpat_module_documentation[] =
|
||||||
"Python wrapper for Expat parser.";
|
"Python wrapper for Expat parser.";
|
||||||
|
|
||||||
/* Initialization function for the module */
|
|
||||||
|
|
||||||
void initpyexpat(void); /* avoid compiler warnings */
|
|
||||||
|
|
||||||
#if PY_VERSION_HEX < 0x20000F0
|
#if PY_VERSION_HEX < 0x20000F0
|
||||||
|
|
||||||
/* 1.5 compatibility: PyModule_AddObject */
|
/* 1.5 compatibility: PyModule_AddObject */
|
||||||
static int
|
static int
|
||||||
PyModule_AddObject(PyObject *m, char *name, PyObject *o)
|
PyModule_AddObject(PyObject *m, char *name, PyObject *o)
|
||||||
{
|
{
|
||||||
PyObject *dict;
|
PyObject *dict;
|
||||||
if (!PyModule_Check(m) || o == NULL)
|
if (!PyModule_Check(m) || o == NULL)
|
||||||
return -1;
|
return -1;
|
||||||
dict = PyModule_GetDict(m);
|
dict = PyModule_GetDict(m);
|
||||||
if (dict == NULL)
|
if (dict == NULL)
|
||||||
return -1;
|
return -1;
|
||||||
if (PyDict_SetItemString(dict, name, o))
|
if (PyDict_SetItemString(dict, name, o))
|
||||||
return -1;
|
return -1;
|
||||||
Py_DECREF(o);
|
Py_DECREF(o);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
PyModule_AddIntConstant(PyObject *m, char *name, long value)
|
PyModule_AddIntConstant(PyObject *m, char *name, long value)
|
||||||
{
|
{
|
||||||
return PyModule_AddObject(m, name, PyInt_FromLong(value));
|
return PyModule_AddObject(m, name, PyInt_FromLong(value));
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
PyModule_AddStringConstant(PyObject *m, char *name, char *value)
|
PyModule_AddStringConstant(PyObject *m, char *name, char *value)
|
||||||
{
|
{
|
||||||
return PyModule_AddObject(m, name, PyString_FromString(value));
|
return PyModule_AddObject(m, name, PyString_FromString(value));
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -1486,11 +1485,23 @@ get_version_string(void)
|
||||||
return PyString_FromStringAndSize(rev, i);
|
return PyString_FromStringAndSize(rev, i);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Initialization function for the module */
|
||||||
|
|
||||||
|
#ifndef MODULE_NAME
|
||||||
|
#define MODULE_NAME "pyexpat"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef MODULE_INITFUNC
|
||||||
|
#define MODULE_INITFUNC initpyexpat
|
||||||
|
#endif
|
||||||
|
|
||||||
|
void MODULE_INITFUNC(void); /* avoid compiler warnings */
|
||||||
|
|
||||||
DL_EXPORT(void)
|
DL_EXPORT(void)
|
||||||
initpyexpat(void)
|
MODULE_INITFUNC(void)
|
||||||
{
|
{
|
||||||
PyObject *m, *d;
|
PyObject *m, *d;
|
||||||
PyObject *errmod_name = PyString_FromString("pyexpat.errors");
|
PyObject *errmod_name = PyString_FromString(MODULE_NAME ".errors");
|
||||||
PyObject *errors_module;
|
PyObject *errors_module;
|
||||||
PyObject *modelmod_name;
|
PyObject *modelmod_name;
|
||||||
PyObject *model_module;
|
PyObject *model_module;
|
||||||
|
@ -1498,14 +1509,14 @@ initpyexpat(void)
|
||||||
|
|
||||||
if (errmod_name == NULL)
|
if (errmod_name == NULL)
|
||||||
return;
|
return;
|
||||||
modelmod_name = PyString_FromString("pyexpat.model");
|
modelmod_name = PyString_FromString(MODULE_NAME ".model");
|
||||||
if (modelmod_name == NULL)
|
if (modelmod_name == NULL)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
Xmlparsetype.ob_type = &PyType_Type;
|
Xmlparsetype.ob_type = &PyType_Type;
|
||||||
|
|
||||||
/* Create the module and add the functions */
|
/* Create the module and add the functions */
|
||||||
m = Py_InitModule3("pyexpat", pyexpat_methods,
|
m = Py_InitModule3(MODULE_NAME, pyexpat_methods,
|
||||||
pyexpat_module_documentation);
|
pyexpat_module_documentation);
|
||||||
|
|
||||||
/* Add some symbolic constants to the module */
|
/* Add some symbolic constants to the module */
|
||||||
|
@ -1547,7 +1558,7 @@ initpyexpat(void)
|
||||||
d = PyModule_GetDict(m);
|
d = PyModule_GetDict(m);
|
||||||
errors_module = PyDict_GetItem(d, errmod_name);
|
errors_module = PyDict_GetItem(d, errmod_name);
|
||||||
if (errors_module == NULL) {
|
if (errors_module == NULL) {
|
||||||
errors_module = PyModule_New("pyexpat.errors");
|
errors_module = PyModule_New(MODULE_NAME ".errors");
|
||||||
if (errors_module != NULL) {
|
if (errors_module != NULL) {
|
||||||
PyDict_SetItem(sys_modules, errmod_name, errors_module);
|
PyDict_SetItem(sys_modules, errmod_name, errors_module);
|
||||||
/* gives away the reference to errors_module */
|
/* gives away the reference to errors_module */
|
||||||
|
@ -1557,7 +1568,7 @@ initpyexpat(void)
|
||||||
Py_DECREF(errmod_name);
|
Py_DECREF(errmod_name);
|
||||||
model_module = PyDict_GetItem(d, modelmod_name);
|
model_module = PyDict_GetItem(d, modelmod_name);
|
||||||
if (model_module == NULL) {
|
if (model_module == NULL) {
|
||||||
model_module = PyModule_New("pyexpat.model");
|
model_module = PyModule_New(MODULE_NAME ".model");
|
||||||
if (model_module != NULL) {
|
if (model_module != NULL) {
|
||||||
PyDict_SetItem(sys_modules, modelmod_name, model_module);
|
PyDict_SetItem(sys_modules, modelmod_name, model_module);
|
||||||
/* gives away the reference to model_module */
|
/* gives away the reference to model_module */
|
||||||
|
@ -1632,15 +1643,18 @@ initpyexpat(void)
|
||||||
static void
|
static void
|
||||||
clear_handlers(xmlparseobject *self, int decref)
|
clear_handlers(xmlparseobject *self, int decref)
|
||||||
{
|
{
|
||||||
int i = 0;
|
int i = 0;
|
||||||
|
PyObject *temp;
|
||||||
|
|
||||||
for (; handler_info[i].name!=NULL; i++) {
|
for (; handler_info[i].name!=NULL; i++) {
|
||||||
if (decref){
|
if (decref) {
|
||||||
Py_XDECREF(self->handlers[i]);
|
temp = self->handlers[i];
|
||||||
}
|
self->handlers[i] = NULL;
|
||||||
self->handlers[i]=NULL;
|
Py_XDECREF(temp);
|
||||||
handler_info[i].setter(self->itself, NULL);
|
}
|
||||||
}
|
self->handlers[i]=NULL;
|
||||||
|
handler_info[i].setter(self->itself, NULL);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
typedef void (*pairsetter)(XML_Parser, void *handler1, void *handler2);
|
typedef void (*pairsetter)(XML_Parser, void *handler1, void *handler2);
|
||||||
|
@ -1651,16 +1665,16 @@ pyxml_UpdatePairedHandlers(xmlparseobject *self,
|
||||||
int endHandler,
|
int endHandler,
|
||||||
pairsetter setter)
|
pairsetter setter)
|
||||||
{
|
{
|
||||||
void *start_handler=NULL;
|
void *start_handler = NULL;
|
||||||
void *end_handler=NULL;
|
void *end_handler = NULL;
|
||||||
|
|
||||||
if (self->handlers[startHandler]
|
if (self->handlers[startHandler]
|
||||||
&& self->handlers[endHandler]!=Py_None) {
|
&& self->handlers[endHandler] != Py_None) {
|
||||||
start_handler=handler_info[startHandler].handler;
|
start_handler = handler_info[startHandler].handler;
|
||||||
}
|
}
|
||||||
if (self->handlers[EndElement]
|
if (self->handlers[EndElement]
|
||||||
&& self->handlers[EndElement] !=Py_None) {
|
&& self->handlers[EndElement] != Py_None) {
|
||||||
end_handler=handler_info[endHandler].handler;
|
end_handler = handler_info[endHandler].handler;
|
||||||
}
|
}
|
||||||
setter(self->itself, start_handler, end_handler);
|
setter(self->itself, start_handler, end_handler);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue