]> granicus.if.org Git - python/commitdiff
pyexpat code cleanup and minor refactorings:
authorFred Drake <fdrake@acm.org>
Fri, 28 Jun 2002 22:29:01 +0000 (22:29 +0000)
committerFred Drake <fdrake@acm.org>
Fri, 28 Jun 2002 22:29:01 +0000 (22:29 +0000)
The handlers array on each parser now has the invariant that None will
never be set as a handler; it will always be NULL or a Python-level
value passed in for the specific handler.

have_handler():  Return true if there is a Python handler for a
    particular event.

get_handler_name():  Return a string object giving the name of a
    particular handler.  This caches the string object so it doesn't
    need to be created more than once.

get_parse_result():  Helper to allow the Parse() and ParseFile()
    methods to share the same logic for determining the return value
    or exception state.

PyUnknownEncodingHandler(), PyModule_AddIntConstant():
    Made these helpers static.  (The later is only defined for older
    versions of Python.)

pyxml_UpdatePairedHandlers(), pyxml_SetStartElementHandler(),
pyxml_SetEndElementHandler(), pyxml_SetStartNamespaceDeclHandler(),
pyxml_SetEndNamespaceDeclHandler(), pyxml_SetStartCdataSection(),
pyxml_SetEndCdataSection(), pyxml_SetStartDoctypeDeclHandler(),
pyxml_SetEndDoctypeDeclHandler():
    Removed.  These are no longer needed with Expat 1.95.x.

handler_info:
    Use the setter functions provided by Expat 1.95.x instead of the
    pyxml_Set*Handler() functions which have been removed.

Minor code formatting changes for consistency.
Trailing whitespace removed.

Modules/pyexpat.c

index 7c70f1b0586fa56804d3e282f6e969bb681bfece..ce820142a761540f9ccc8100d1fba21b52272f2f 100644 (file)
@@ -74,6 +74,7 @@ struct HandlerInfo {
     xmlhandlersetter setter;
     xmlhandler handler;
     PyCodeObject *tb_code;
+    PyObject *nameobj;
 };
 
 staticforward struct HandlerInfo handler_info[64];
@@ -118,6 +119,25 @@ set_error(xmlparseobject *self)
     return NULL;
 }
 
+static int
+have_handler(xmlparseobject *self, int type)
+{
+    PyObject *handler = self->handlers[type];
+    return handler != NULL;
+}
+
+static PyObject *
+get_handler_name(struct HandlerInfo *hinfo)
+{
+    PyObject *name = hinfo->nameobj;
+    if (name == NULL) {
+        name = PyString_FromString(hinfo->name);
+        hinfo->nameobj = name;
+    }
+    Py_XINCREF(name);
+    return name;
+}
+
 
 #ifdef Py_USING_UNICODE
 /* Convert a string of XML_Chars into a Unicode string.
@@ -126,21 +146,20 @@ set_error(xmlparseobject *self)
 static PyObject *
 conv_string_to_unicode(const XML_Char *str)
 {
-    /* XXX currently this code assumes that XML_Char is 8-bit, 
+    /* XXX currently this code assumes that XML_Char is 8-bit,
        and hence in UTF-8.  */
     /* UTF-8 from Expat, Unicode desired */
     if (str == NULL) {
         Py_INCREF(Py_None);
         return Py_None;
     }
-    return PyUnicode_DecodeUTF8(str, strlen(str), 
-                                "strict");
+    return PyUnicode_DecodeUTF8(str, strlen(str), "strict");
 }
 
 static PyObject *
 conv_string_len_to_unicode(const XML_Char *str, int len)
 {
-    /* XXX currently this code assumes that XML_Char is 8-bit, 
+    /* XXX currently this code assumes that XML_Char is 8-bit,
        and hence in UTF-8.  */
     /* UTF-8 from Expat, Unicode desired */
     if (str == NULL) {
@@ -157,7 +176,7 @@ conv_string_len_to_unicode(const XML_Char *str, int len)
 static PyObject *
 conv_string_to_utf8(const XML_Char *str)
 {
-    /* XXX currently this code assumes that XML_Char is 8-bit, 
+    /* XXX currently this code assumes that XML_Char is 8-bit,
        and hence in UTF-8.  */
     /* UTF-8 from Expat, UTF-8 desired */
     if (str == NULL) {
@@ -168,9 +187,9 @@ conv_string_to_utf8(const XML_Char *str)
 }
 
 static PyObject *
-conv_string_len_to_utf8(const XML_Char *str,  int len) 
+conv_string_len_to_utf8(const XML_Char *str, int len)
 {
-    /* XXX currently this code assumes that XML_Char is 8-bit, 
+    /* XXX currently this code assumes that XML_Char is 8-bit,
        and hence in UTF-8.  */
     /* UTF-8 from Expat, UTF-8 desired */
     if (str == NULL) {
@@ -296,12 +315,11 @@ string_intern(xmlparseobject *self, const char* str)
 
 static void
 my_StartElementHandler(void *userData,
-                       const XML_Char *name, const XML_Char **atts)
+                       const XML_Char *name, const XML_Char *atts[])
 {
     xmlparseobject *self = (xmlparseobject *)userData;
 
-    if (self->handlers[StartElement]
-        && self->handlers[StartElement] != Py_None) {
+    if (have_handler(self, StartElement)) {
         PyObject *container, *rv, *args;
         int i, max;
 
@@ -383,8 +401,7 @@ my_##NAME##Handler PARAMS {\
     PyObject *rv = NULL; \
     INIT \
 \
-    if (self->handlers[NAME] \
-        && self->handlers[NAME] != Py_None) { \
+    if (have_handler(self, NAME)) { \
         args = Py_BuildValue PARAM_FORMAT ;\
         if (!args) { flag_error(self); return RETURN;} \
         self->in_callback = 1; \
@@ -411,38 +428,38 @@ my_##NAME##Handler PARAMS {\
                        rc = PyInt_AsLong(rv);, rc, \
        (xmlparseobject *)userData)
 
-VOID_HANDLER(EndElement, 
-             (void *userData, const XML_Char *name), 
+VOID_HANDLER(EndElement,
+             (void *userData, const XML_Char *name),
              ("(N)", string_intern(self, name)))
 
 VOID_HANDLER(ProcessingInstruction,
-             (void *userData, 
-              const XML_Char *target, 
+             (void *userData,
+              const XML_Char *target,
               const XML_Char *data),
              ("(NO&)", string_intern(self, target), STRING_CONV_FUNC,data))
 
 #ifndef Py_USING_UNICODE
-VOID_HANDLER(CharacterData, 
-             (void *userData, const XML_Char *data, int len), 
+VOID_HANDLER(CharacterData,
+             (void *userData, const XML_Char *data, int len),
              ("(N)", conv_string_len_to_utf8(data,len)))
 #else
-VOID_HANDLER(CharacterData, 
-             (void *userData, const XML_Char *data, int len), 
-             ("(N)", (self->returns_unicode 
-                      ? conv_string_len_to_unicode(data,len) 
+VOID_HANDLER(CharacterData,
+             (void *userData, const XML_Char *data, int len),
+             ("(N)", (self->returns_unicode
+                      ? conv_string_len_to_unicode(data,len)
                       : conv_string_len_to_utf8(data,len))))
 #endif
 
 VOID_HANDLER(UnparsedEntityDecl,
-             (void *userData, 
+             (void *userData,
               const XML_Char *entityName,
               const XML_Char *base,
               const XML_Char *systemId,
               const XML_Char *publicId,
               const XML_Char *notationName),
              ("(NNNNN)",
-              string_intern(self, entityName), string_intern(self, base), 
-              string_intern(self, systemId), string_intern(self, publicId), 
+              string_intern(self, entityName), string_intern(self, base),
+              string_intern(self, systemId), string_intern(self, publicId),
               string_intern(self, notationName)))
 
 #ifndef Py_USING_UNICODE
@@ -475,8 +492,8 @@ VOID_HANDLER(EntityDecl,
               const XML_Char *notationName),
              ("NiNNNNN",
               string_intern(self, entityName), is_parameter_entity,
-              (self->returns_unicode 
-               ? conv_string_len_to_unicode(value, value_length) 
+              (self->returns_unicode
+               ? conv_string_len_to_unicode(value, value_length)
                : conv_string_len_to_utf8(value, value_length)),
               string_intern(self, base), string_intern(self, systemId),
               string_intern(self, publicId),
@@ -489,7 +506,7 @@ VOID_HANDLER(XmlDecl,
               const XML_Char *encoding,
               int standalone),
              ("(O&O&i)",
-              STRING_CONV_FUNC,version, STRING_CONV_FUNC,encoding, 
+              STRING_CONV_FUNC,version, STRING_CONV_FUNC,encoding,
               standalone))
 
 static PyObject *
@@ -560,14 +577,14 @@ VOID_HANDLER(AttlistDecl,
               STRING_CONV_FUNC,att_type, STRING_CONV_FUNC,dflt,
               isrequired))
 
-VOID_HANDLER(NotationDecl, 
+VOID_HANDLER(NotationDecl,
                (void *userData,
                        const XML_Char *notationName,
                        const XML_Char *base,
                        const XML_Char *systemId,
                        const XML_Char *publicId),
                 ("(NNNN)",
-                string_intern(self, notationName), string_intern(self, base), 
+                string_intern(self, notationName), string_intern(self, base),
                 string_intern(self, systemId), string_intern(self, publicId)))
 
 VOID_HANDLER(StartNamespaceDecl,
@@ -589,35 +606,35 @@ VOID_HANDLER(Comment,
 VOID_HANDLER(StartCdataSection,
                (void *userData),
                ("()"))
-               
+
 VOID_HANDLER(EndCdataSection,
                (void *userData),
                ("()"))
 
 #ifndef Py_USING_UNICODE
 VOID_HANDLER(Default,
-             (void *userData,  const XML_Char *s, int len),
+             (void *userData, const XML_Char *s, int len),
              ("(N)", conv_string_len_to_utf8(s,len)))
 
 VOID_HANDLER(DefaultHandlerExpand,
-             (void *userData,  const XML_Char *s, int len),
+             (void *userData, const XML_Char *s, int len),
              ("(N)", conv_string_len_to_utf8(s,len)))
 #else
 VOID_HANDLER(Default,
-             (void *userData,  const XML_Char *s, int len),
-             ("(N)", (self->returns_unicode 
-                      ? conv_string_len_to_unicode(s,len) 
+             (void *userData, const XML_Char *s, int len),
+             ("(N)", (self->returns_unicode
+                      ? conv_string_len_to_unicode(s,len)
                       : conv_string_len_to_utf8(s,len))))
 
 VOID_HANDLER(DefaultHandlerExpand,
-             (void *userData,  const XML_Char *s, int len),
-             ("(N)", (self->returns_unicode 
-                      ? conv_string_len_to_unicode(s,len) 
+             (void *userData, const XML_Char *s, int len),
+             ("(N)", (self->returns_unicode
+                      ? conv_string_len_to_unicode(s,len)
                       : conv_string_len_to_utf8(s,len))))
 #endif
 
-INT_HANDLER(NotStandalone, 
-               (void *userData), 
+INT_HANDLER(NotStandalone,
+               (void *userData),
                ("()"))
 
 RC_HANDLER(int, ExternalEntityRef,
@@ -628,7 +645,7 @@ RC_HANDLER(int, ExternalEntityRef,
                    const XML_Char *publicId),
                int rc=0;,
                 ("(O&NNN)",
-                STRING_CONV_FUNC,context, string_intern(self, base), 
+                STRING_CONV_FUNC,context, string_intern(self, base),
                 string_intern(self, systemId), string_intern(self, publicId)),
                rc = PyInt_AsLong(rv);, rc,
                XML_GetUserData(parser))
@@ -647,6 +664,18 @@ VOID_HANDLER(EndDoctypeDecl, (void *userData), ("()"))
 
 /* ---------------------------------------------------------------- */
 
+static PyObject *
+get_parse_result(xmlparseobject *self, int rv)
+{
+    if (PyErr_Occurred()) {
+        return NULL;
+    }
+    if (rv == 0) {
+        return set_error(self);
+    }
+    return PyInt_FromLong(rv);
+}
+
 PyDoc_STRVAR(xmlparse_Parse__doc__,
 "Parse(data[, isfinal])\n\
 Parse XML data.  `isfinal' should be true at end of input.");
@@ -657,18 +686,11 @@ xmlparse_Parse(xmlparseobject *self, PyObject *args)
     char *s;
     int slen;
     int isFinal = 0;
-    int rv;
 
     if (!PyArg_ParseTuple(args, "s#|i:Parse", &s, &slen, &isFinal))
         return NULL;
-    rv = XML_Parse(self->itself, s, slen, isFinal);
-    if (PyErr_Occurred()) {    
-        return NULL;
-    }
-    else if (rv == 0) {
-        return set_error(self);
-    }
-    return PyInt_FromLong(rv);
+
+    return get_parse_result(self, XML_Parse(self->itself, s, slen, isFinal));
 }
 
 /* File reading copied from cPickle */
@@ -696,7 +718,7 @@ readinst(char *buf, int buf_size, PyObject *meth)
 
     /* XXX what to do if it returns a Unicode string? */
     if (!PyString_Check(str)) {
-        PyErr_Format(PyExc_TypeError, 
+        PyErr_Format(PyExc_TypeError,
                      "read() did not return a string object (type=%.400s)",
                      str->ob_type->tp_name);
         goto finally;
@@ -740,7 +762,7 @@ xmlparse_ParseFile(xmlparseobject *self, PyObject *args)
         readmethod = PyObject_GetAttrString(f, "read");
         if (readmethod == NULL) {
             PyErr_Clear();
-            PyErr_SetString(PyExc_TypeError, 
+            PyErr_SetString(PyExc_TypeError,
                             "argument must have 'read' attribute");
             return 0;
         }
@@ -770,10 +792,7 @@ xmlparse_ParseFile(xmlparseobject *self, PyObject *args)
         if (!rv || bytes_read == 0)
             break;
     }
-    if (rv == 0) {
-        return set_error(self);
-    }
-    return Py_BuildValue("i", rv);
+    return get_parse_result(self, rv);
 }
 
 PyDoc_STRVAR(xmlparse_SetBase__doc__,
@@ -906,14 +925,15 @@ xmlparse_ExternalEntityParserCreate(xmlparseobject *self, PyObject *args)
 
     /* then copy handlers from self */
     for (i = 0; handler_info[i].name != NULL; i++) {
-        if (self->handlers[i]) {
-            Py_INCREF(self->handlers[i]);
-            new_parser->handlers[i] = self->handlers[i];
-            handler_info[i].setter(new_parser->itself, 
+        PyObject *handler = self->handlers[i];
+        if (handler != NULL) {
+            Py_INCREF(handler);
+            new_parser->handlers[i] = handler;
+            handler_info[i].setter(new_parser->itself,
                                    handler_info[i].handler);
         }
     }
-    return (PyObject *)new_parser;    
+    return (PyObject *)new_parser;
 }
 
 PyDoc_STRVAR(xmlparse_SetParamEntityParsing__doc__,
@@ -957,15 +977,14 @@ static struct PyMethodDef xmlparse_methods[] = {
 
 #ifdef Py_USING_UNICODE
 
-/* 
-    pyexpat international encoding support.
-    Make it as simple as possible.
+/* pyexpat international encoding support.
+   Make it as simple as possible.
 */
 
 static char template_buffer[257];
 PyObject *template_string = NULL;
 
-static void 
+static void
 init_template_buffer(void)
 {
     int i;
@@ -975,22 +994,22 @@ init_template_buffer(void)
     template_buffer[256] = 0;
 }
 
-int 
-PyUnknownEncodingHandler(void *encodingHandlerData, 
-const XML_Char *name, 
-XML_Encoding * info)
+static int
+PyUnknownEncodingHandler(void *encodingHandlerData,
+                         const XML_Char *name,
+                         XML_Encoding *info)
 {
     PyUnicodeObject *_u_string = NULL;
     int result = 0;
     int i;
-    
+
     /* Yes, supports only 8bit encodings */
     _u_string = (PyUnicodeObject *)
         PyUnicode_Decode(template_buffer, 256, name, "replace");
-    
+
     if (_u_string == NULL)
        return result;
-    
+
     for (i = 0; i < 256; i++) {
        /* Stupid to access directly, but fast */
        Py_UNICODE c = _u_string->str[i];
@@ -999,12 +1018,10 @@ XML_Encoding * info)
        else
            info->map[i] = c;
     }
-    
     info->data = NULL;
     info->convert = NULL;
     info->release = NULL;
-    result=1;
-    
+    result = 1;
     Py_DECREF(_u_string);
     return result;
 }
@@ -1016,7 +1033,7 @@ newxmlparseobject(char *encoding, char *namespace_separator, PyObject *intern)
 {
     int i;
     xmlparseobject *self;
-       
+
 #if PY_MAJOR_VERSION == 1 && PY_MINOR_VERSION < 6
     self = PyObject_NEW(xmlparseobject, &Xmlparsetype);
     if (self == NULL)
@@ -1054,7 +1071,7 @@ newxmlparseobject(char *encoding, char *namespace_separator, PyObject *intern)
     PyObject_GC_Init(self);
 #endif
     if (self->itself == NULL) {
-        PyErr_SetString(PyExc_RuntimeError, 
+        PyErr_SetString(PyExc_RuntimeError,
                         "XML_ParserCreate failed");
         Py_DECREF(self);
         return NULL;
@@ -1069,8 +1086,8 @@ newxmlparseobject(char *encoding, char *namespace_separator, PyObject *intern)
 
     self->handlers = malloc(sizeof(PyObject *)*i);
     if (!self->handlers){
-           Py_DECREF(self);
-           return PyErr_NoMemory();
+        Py_DECREF(self);
+        return PyErr_NoMemory();
     }
     clear_handlers(self, 1);
 
@@ -1099,6 +1116,7 @@ xmlparse_dealloc(xmlparseobject *self)
             Py_XDECREF(temp);
         }
         free(self->handlers);
+        self->handlers = NULL;
     }
     Py_XDECREF(self->intern);
 #if PY_MAJOR_VERSION == 1 && PY_MINOR_VERSION < 6
@@ -1119,7 +1137,7 @@ static int
 handlername2int(const char *name)
 {
     int i;
-    for (i=0; handler_info[i].name != NULL; i++) {
+    for (i = 0; handler_info[i].name != NULL; i++) {
         if (strcmp(name, handler_info[i].name) == 0) {
             return i;
         }
@@ -1127,24 +1145,46 @@ handlername2int(const char *name)
     return -1;
 }
 
+static PyObject *
+get_pybool(int istrue)
+{
+    PyObject *result = istrue ? Py_True : Py_False;
+    Py_INCREF(result);
+    return result;
+}
+
 static PyObject *
 xmlparse_getattr(xmlparseobject *self, char *name)
 {
-    int handlernum;
-    if (strcmp(name, "ErrorCode") == 0)
-        return PyInt_FromLong((long) XML_GetErrorCode(self->itself));
-    if (strcmp(name, "ErrorLineNumber") == 0)
-        return PyInt_FromLong((long) XML_GetErrorLineNumber(self->itself));
-    if (strcmp(name, "ErrorColumnNumber") == 0)
-        return PyInt_FromLong((long) XML_GetErrorColumnNumber(self->itself));
-    if (strcmp(name, "ErrorByteIndex") == 0)
-        return PyInt_FromLong((long) XML_GetErrorByteIndex(self->itself));
+    int handlernum = handlername2int(name);
+
+    if (handlernum != -1) {
+        PyObject *result = self->handlers[handlernum];
+        if (result == NULL)
+            result = Py_None;
+        Py_INCREF(result);
+        return result;
+    }
+    if (name[0] == 'E') {
+        if (strcmp(name, "ErrorCode") == 0)
+            return PyInt_FromLong((long)
+                                  XML_GetErrorCode(self->itself));
+        if (strcmp(name, "ErrorLineNumber") == 0)
+            return PyInt_FromLong((long)
+                                  XML_GetErrorLineNumber(self->itself));
+        if (strcmp(name, "ErrorColumnNumber") == 0)
+            return PyInt_FromLong((long)
+                                  XML_GetErrorColumnNumber(self->itself));
+        if (strcmp(name, "ErrorByteIndex") == 0)
+            return PyInt_FromLong((long)
+                                  XML_GetErrorByteIndex(self->itself));
+    }
     if (strcmp(name, "ordered_attributes") == 0)
-        return PyInt_FromLong((long) self->ordered_attributes);
+        return get_pybool(self->ordered_attributes);
     if (strcmp(name, "returns_unicode") == 0)
-        return PyInt_FromLong((long) self->returns_unicode);
+        return get_pybool((long) self->returns_unicode);
     if (strcmp(name, "specified_attributes") == 0)
-        return PyInt_FromLong((long) self->specified_attributes);
+        return get_pybool((long) self->specified_attributes);
     if (strcmp(name, "intern") == 0) {
         if (self->intern == NULL) {
             Py_INCREF(Py_None);
@@ -1156,17 +1196,11 @@ xmlparse_getattr(xmlparseobject *self, char *name)
         }
     }
 
-    handlernum = handlername2int(name);
-
-    if (handlernum != -1 && self->handlers[handlernum] != NULL) {
-        Py_INCREF(self->handlers[handlernum]);
-        return self->handlers[handlernum];
-    }
     if (strcmp(name, "__members__") == 0) {
         int i;
         PyObject *rc = PyList_New(0);
-        for(i = 0; handler_info[i].name != NULL; i++) {
-            PyList_Append(rc, PyString_FromString(handler_info[i].name));
+        for (i = 0; handler_info[i].name != NULL; i++) {
+            PyList_Append(rc, get_handler_name(&handler_info[i]));
         }
         PyList_Append(rc, PyString_FromString("ErrorCode"));
         PyList_Append(rc, PyString_FromString("ErrorLineNumber"));
@@ -1186,12 +1220,19 @@ static int
 sethandler(xmlparseobject *self, const char *name, PyObject* v)
 {
     int handlernum = handlername2int(name);
-    if (handlernum != -1) {
-        Py_INCREF(v);
-        Py_XDECREF(self->handlers[handlernum]);
+    if (handlernum >= 0) {
+        xmlhandler c_handler = NULL;
+        PyObject *temp = self->handlers[handlernum];
+
+        if (v == Py_None)
+            v = NULL;
+        else if (v != NULL) {
+            Py_INCREF(v);
+            c_handler = handler_info[handlernum].handler;
+        }
         self->handlers[handlernum] = v;
-        handler_info[handlernum].setter(self->itself, 
-                                        handler_info[handlernum].handler);
+        Py_XDECREF(temp);
+        handler_info[handlernum].setter(self->itself, c_handler);
         return 1;
     }
     return 0;
@@ -1215,8 +1256,8 @@ xmlparse_setattr(xmlparseobject *self, char *name, PyObject *v)
     if (strcmp(name, "returns_unicode") == 0) {
         if (PyObject_IsTrue(v)) {
 #ifndef Py_USING_UNICODE
-            PyErr_SetString(PyExc_ValueError, 
-                            "Cannot return Unicode strings in Python 1.5");
+            PyErr_SetString(PyExc_ValueError,
+                            "Unicode support not available");
             return -1;
 #else
             self->returns_unicode = 1;
@@ -1290,9 +1331,9 @@ static PyTypeObject Xmlparsetype = {
        0,              /* tp_setattro */
        0,              /* tp_as_buffer */
 #ifdef Py_TPFLAGS_HAVE_GC
-       Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, /*tp_flags*/   
+       Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, /*tp_flags*/
 #else
-       Py_TPFLAGS_DEFAULT | Py_TPFLAGS_GC, /*tp_flags*/        
+       Py_TPFLAGS_DEFAULT | Py_TPFLAGS_GC, /*tp_flags*/
 #endif
        Xmlparsetype__doc__, /* Documentation string */
 #ifdef WITH_CYCLE_GC
@@ -1318,7 +1359,7 @@ pyexpat_ParserCreate(PyObject *notused, PyObject *args, PyObject *kw)
     PyObject *intern = NULL;
     PyObject *result;
     int intern_decref = 0;
-    static char *kwlist[] = {"encoding", "namespace_separator", 
+    static char *kwlist[] = {"encoding", "namespace_separator",
                             "intern", NULL};
 
     if (!PyArg_ParseTupleAndKeywords(args, kw, "|zzO:ParserCreate", kwlist,
@@ -1340,7 +1381,7 @@ pyexpat_ParserCreate(PyObject *notused, PyObject *args, PyObject *kw)
        if (!intern)
            return NULL;
        intern_decref = 1;
-    } 
+    }
     else if (!PyDict_Check(intern)) {
        PyErr_SetString(PyExc_TypeError, "intern must be a dictionary");
        return NULL;
@@ -1374,7 +1415,7 @@ static struct PyMethodDef pyexpat_methods[] = {
      METH_VARARGS|METH_KEYWORDS, pyexpat_ParserCreate__doc__},
     {"ErrorString",    (PyCFunction)pyexpat_ErrorString,
      METH_VARARGS,     pyexpat_ErrorString__doc__},
+
     {NULL,      (PyCFunction)NULL, 0, NULL}            /* sentinel */
 };
 
@@ -1401,13 +1442,13 @@ PyModule_AddObject(PyObject *m, char *name, PyObject *o)
     return 0;
 }
 
-int 
+static int
 PyModule_AddIntConstant(PyObject *m, char *name, long value)
 {
     return PyModule_AddObject(m, name, PyInt_FromLong(value));
 }
 
-static int 
+static int
 PyModule_AddStringConstant(PyObject *m, char *name, char *value)
 {
     return PyModule_AddObject(m, name, PyString_FromString(value));
@@ -1497,8 +1538,8 @@ MODULE_INITFUNC(void)
     init_template_buffer();
 #endif
     /* XXX When Expat supports some way of figuring out how it was
-       compiled, this should check and set native_encoding 
-       appropriately. 
+       compiled, this should check and set native_encoding
+       appropriately.
     */
     PyModule_AddStringConstant(m, "native_encoding", "UTF-8");
 
@@ -1590,9 +1631,9 @@ clear_handlers(xmlparseobject *self, int initial)
     int i = 0;
     PyObject *temp;
 
-    for (; handler_info[i].name!=NULL; i++) {
+    for (; handler_info[i].name != NULL; i++) {
         if (initial)
-           self->handlers[i]=NULL;
+           self->handlers[i] = NULL;
        else {
             temp = self->handlers[i];
             self->handlers[i] = NULL;
@@ -1602,125 +1643,39 @@ clear_handlers(xmlparseobject *self, int initial)
     }
 }
 
-typedef void (*pairsetter)(XML_Parser, void *handler1, void *handler2);
-
-static void
-pyxml_UpdatePairedHandlers(xmlparseobject *self, 
-                           int startHandler, 
-                           int endHandler,
-                           pairsetter setter)
-{
-    void *start_handler = NULL;
-    void *end_handler = NULL;
-
-    if (self->handlers[startHandler]
-        && self->handlers[startHandler] != Py_None) {
-        start_handler = handler_info[startHandler].handler;
-    }
-    if (self->handlers[endHandler]
-        && self->handlers[endHandler] != Py_None) {
-        end_handler = handler_info[endHandler].handler;
-    }
-    setter(self->itself, start_handler, end_handler);
-}
-
-static void
-pyxml_SetStartElementHandler(XML_Parser *parser, void *junk)
-{
-    pyxml_UpdatePairedHandlers((xmlparseobject *)XML_GetUserData(parser),
-                               StartElement, EndElement,
-                               (pairsetter)XML_SetElementHandler);
-}
-
-static void
-pyxml_SetEndElementHandler(XML_Parser *parser, void *junk)
-{
-    pyxml_UpdatePairedHandlers((xmlparseobject *)XML_GetUserData(parser), 
-                               StartElement, EndElement,
-                               (pairsetter)XML_SetElementHandler);
-}
-
-static void
-pyxml_SetStartNamespaceDeclHandler(XML_Parser *parser, void *junk)
-{
-    pyxml_UpdatePairedHandlers((xmlparseobject *)XML_GetUserData(parser), 
-                               StartNamespaceDecl, EndNamespaceDecl,
-                               (pairsetter)XML_SetNamespaceDeclHandler);
-}
-
-static void
-pyxml_SetEndNamespaceDeclHandler(XML_Parser *parser, void *junk)
-{
-    pyxml_UpdatePairedHandlers((xmlparseobject *)XML_GetUserData(parser), 
-                               StartNamespaceDecl, EndNamespaceDecl,
-                               (pairsetter)XML_SetNamespaceDeclHandler);
-}
-
-static void
-pyxml_SetStartCdataSection(XML_Parser *parser, void *junk)
-{
-    pyxml_UpdatePairedHandlers((xmlparseobject *)XML_GetUserData(parser),
-                               StartCdataSection, EndCdataSection,
-                               (pairsetter)XML_SetCdataSectionHandler);
-}
-
-static void
-pyxml_SetEndCdataSection(XML_Parser *parser, void *junk)
-{
-    pyxml_UpdatePairedHandlers((xmlparseobject *)XML_GetUserData(parser), 
-                               StartCdataSection, EndCdataSection, 
-                               (pairsetter)XML_SetCdataSectionHandler);
-}
-
-static void
-pyxml_SetStartDoctypeDeclHandler(XML_Parser *parser, void *junk)
-{
-    pyxml_UpdatePairedHandlers((xmlparseobject *)XML_GetUserData(parser),
-                               StartDoctypeDecl, EndDoctypeDecl,
-                               (pairsetter)XML_SetDoctypeDeclHandler);
-}
-
-static void
-pyxml_SetEndDoctypeDeclHandler(XML_Parser *parser, void *junk)
-{
-    pyxml_UpdatePairedHandlers((xmlparseobject *)XML_GetUserData(parser),
-                               StartDoctypeDecl, EndDoctypeDecl,
-                               (pairsetter)XML_SetDoctypeDeclHandler);
-}
-
 statichere struct HandlerInfo handler_info[] = {
-    {"StartElementHandler", 
-     pyxml_SetStartElementHandler, 
+    {"StartElementHandler",
+     (xmlhandlersetter)XML_SetStartElementHandler,
      (xmlhandler)my_StartElementHandler},
-    {"EndElementHandler", 
-     pyxml_SetEndElementHandler, 
+    {"EndElementHandler",
+     (xmlhandlersetter)XML_SetEndElementHandler,
      (xmlhandler)my_EndElementHandler},
-    {"ProcessingInstructionHandler", 
+    {"ProcessingInstructionHandler",
      (xmlhandlersetter)XML_SetProcessingInstructionHandler,
      (xmlhandler)my_ProcessingInstructionHandler},
-    {"CharacterDataHandler", 
+    {"CharacterDataHandler",
      (xmlhandlersetter)XML_SetCharacterDataHandler,
      (xmlhandler)my_CharacterDataHandler},
-    {"UnparsedEntityDeclHandler", 
+    {"UnparsedEntityDeclHandler",
      (xmlhandlersetter)XML_SetUnparsedEntityDeclHandler,
      (xmlhandler)my_UnparsedEntityDeclHandler },
-    {"NotationDeclHandler", 
+    {"NotationDeclHandler",
      (xmlhandlersetter)XML_SetNotationDeclHandler,
      (xmlhandler)my_NotationDeclHandler },
-    {"StartNamespaceDeclHandler", 
-     pyxml_SetStartNamespaceDeclHandler,
+    {"StartNamespaceDeclHandler",
+     (xmlhandlersetter)XML_SetStartNamespaceDeclHandler,
      (xmlhandler)my_StartNamespaceDeclHandler },
-    {"EndNamespaceDeclHandler", 
-     pyxml_SetEndNamespaceDeclHandler,
+    {"EndNamespaceDeclHandler",
+     (xmlhandlersetter)XML_SetEndNamespaceDeclHandler,
      (xmlhandler)my_EndNamespaceDeclHandler },
     {"CommentHandler",
      (xmlhandlersetter)XML_SetCommentHandler,
      (xmlhandler)my_CommentHandler},
     {"StartCdataSectionHandler",
-     pyxml_SetStartCdataSection,
+     (xmlhandlersetter)XML_SetStartCdataSectionHandler,
      (xmlhandler)my_StartCdataSectionHandler},
     {"EndCdataSectionHandler",
-     pyxml_SetEndCdataSection,
+     (xmlhandlersetter)XML_SetEndCdataSectionHandler,
      (xmlhandler)my_EndCdataSectionHandler},
     {"DefaultHandler",
      (xmlhandlersetter)XML_SetDefaultHandler,
@@ -1735,10 +1690,10 @@ statichere struct HandlerInfo handler_info[] = {
      (xmlhandlersetter)XML_SetExternalEntityRefHandler,
      (xmlhandler)my_ExternalEntityRefHandler },
     {"StartDoctypeDeclHandler",
-     pyxml_SetStartDoctypeDeclHandler,
+     (xmlhandlersetter)XML_SetStartDoctypeDeclHandler,
      (xmlhandler)my_StartDoctypeDeclHandler},
     {"EndDoctypeDeclHandler",
-     pyxml_SetEndDoctypeDeclHandler,
+     (xmlhandlersetter)XML_SetEndDoctypeDeclHandler,
      (xmlhandler)my_EndDoctypeDeclHandler},
     {"EntityDeclHandler",
      (xmlhandlersetter)XML_SetEntityDeclHandler,