[Python-checkins] python/dist/src/Modules pyexpat.c,2.77,2.78

loewis@users.sourceforge.net loewis@users.sourceforge.net
Tue, 21 Jan 2003 02:58:22 -0800


Update of /cvsroot/python/python/dist/src/Modules
In directory sc8-pr-cvs1:/tmp/cvs-serv21858

Modified Files:
	pyexpat.c 
Log Message:
Merge with PyXML 1.71:
60: Added support for the SkippedEntityHandler, new in Expat 1.95.4.
61: Added support for namespace prefixes, which can be enabled by setting the
    "namespace_prefixes" attribute on the parser object.
65: Disable profiling changes for Python 2.0 and 2.1.
66: Update pyexpat to export the Expat 1.95.5 XML_GetFeatureList()
    information, and tighten up a type declaration now that Expat is using
    an incomplete type rather than a void * for the XML_Parser type.
67: Clarified a comment.
    Added support for XML_UseForeignDTD(), new in Expat 1.95.5.
68: Refactor to avoid partial duplication of the code to construct an
    ExpatError instance, and actually conform to the API for the exception
    instance as well.
69: Remove some spurious trailing whitespace.
    Add a special external-entity-ref handler that gets installed once a
    handler has raised a Python exception; this can cancel actual parsing
    earlier if there's an external entity reference in the input data
    after the the Python excpetion has been raised.
70: Untabify APPEND.
71: Backport PyMODINIT_FUNC for 2.2 and earlier.


Index: pyexpat.c
===================================================================
RCS file: /cvsroot/python/python/dist/src/Modules/pyexpat.c,v
retrieving revision 2.77
retrieving revision 2.78
diff -C2 -d -r2.77 -r2.78
*** pyexpat.c	19 Jan 2003 15:40:09 -0000	2.77
--- pyexpat.c	21 Jan 2003 10:58:18 -0000	2.78
***************
*** 7,10 ****
--- 7,18 ----
  
  #ifndef PyDoc_STRVAR
+ 
+ /*
+  * fdrake says:
+  * Don't change the PyDoc_STR macro definition to (str), because
+  * '''the parentheses cause compile failures
+  * ("non-constant static initializer" or something like that)
+  * on some platforms (Irix?)'''
+  */
  #define PyDoc_STR(str)         str
  #define PyDoc_VAR(name)        static char name[]
***************
*** 15,18 ****
--- 23,27 ----
  /* In Python 2.0 and  2.1, disabling Unicode was not possible. */
  #define Py_USING_UNICODE
+ #define NOFIX_TRACE
  #endif
  
***************
*** 39,42 ****
--- 48,52 ----
      ElementDecl,
      AttlistDecl,
+     SkippedEntity,
      _DummyDecl
  };
***************
*** 57,60 ****
--- 67,71 ----
      int specified_attributes;   /* Report only specified attributes. */
      int in_callback;            /* Is a callback active? */
+     int ns_prefixes;            /* Namespace-triplets mode? */
      XML_Char *buffer;           /* Buffer used when accumulating characters */
                                  /* NULL if not enabled */
***************
*** 101,105 ****
   */
  static PyObject *
! set_error(xmlparseobject *self)
  {
      PyObject *err;
--- 112,116 ----
   */
  static PyObject *
! set_error(xmlparseobject *self, enum XML_Error code)
  {
      PyObject *err;
***************
*** 108,112 ****
      int lineno = XML_GetErrorLineNumber(parser);
      int column = XML_GetErrorColumnNumber(parser);
-     enum XML_Error code = XML_GetErrorCode(parser);
  
      /* There is no risk of overflowing this buffer, since
--- 119,122 ----
***************
*** 208,215 ****
--- 218,240 ----
  static void clear_handlers(xmlparseobject *self, int initial);
  
+ /* This handler is used when an error has been detected, in the hope
+    that actual parsing can be terminated early.  This will only help
+    if an external entity reference is encountered. */
+ static int
+ error_external_entity_ref_handler(XML_Parser parser,
+                                   const XML_Char *context,
+                                   const XML_Char *base,
+                                   const XML_Char *systemId,
+                                   const XML_Char *publicId)
+ {
+     return 0;
+ }
+ 
  static void
  flag_error(xmlparseobject *self)
  {
      clear_handlers(self, 0);
+     XML_SetExternalEntityRefHandler(self->itself,
+                                     error_external_entity_ref_handler);
  }
  
***************
*** 265,268 ****
--- 290,294 ----
  }
  
+ #ifndef NOFIX_TRACE
  static int
  trace_frame(PyThreadState *tstate, PyFrameObject *f, int code, PyObject *val)
***************
*** 291,294 ****
--- 317,321 ----
      return result;
  }
+ #endif
  
  static PyObject*
***************
*** 311,321 ****
--- 338,351 ----
          return NULL;
      tstate->frame = f;
+ #ifndef NOFIX_TRACE
      if (trace_frame(tstate, f, PyTrace_CALL, Py_None)) {
  	Py_DECREF(f);
  	return NULL;
      }
+ #endif
      res = PyEval_CallObject(func, args);
      if (res == NULL && tstate->curexc_traceback == NULL)
          PyTraceBack_Here(f);
+ #ifndef NOFIX_TRACE
      else {
  	if (trace_frame(tstate, f, PyTrace_RETURN, res)) {
***************
*** 324,327 ****
--- 354,358 ----
  	}
      }
+ #endif
      tstate->frame = f->f_back;
      Py_DECREF(f);
***************
*** 332,336 ****
  #define STRING_CONV_FUNC conv_string_to_utf8
  #else
! /* Python 2.0 and later versions */
  #define STRING_CONV_FUNC (self->returns_unicode \
                            ? conv_string_to_unicode : conv_string_to_utf8)
--- 363,367 ----
  #define STRING_CONV_FUNC conv_string_to_utf8
  #else
! /* Python 2.0 and later versions, when built with Unicode support */
  #define STRING_CONV_FUNC (self->returns_unicode \
                            ? conv_string_to_unicode : conv_string_to_utf8)
***************
*** 691,694 ****
--- 722,732 ----
                isrequired))
  
+ VOID_HANDLER(SkippedEntity,
+              (void *userData,
+               const XML_Char *entityName,
+               int is_parameter_entity),
+              ("Ni",
+               string_intern(self, entityName), is_parameter_entity))
+ 
  VOID_HANDLER(NotationDecl,
  		(void *userData,
***************
*** 785,789 ****
      }
      if (rv == 0) {
!         return set_error(self);
      }
      if (flush_character_buffer(self) < 0) {
--- 823,827 ----
      }
      if (rv == 0) {
!         return set_error(self, XML_GetErrorCode(self->itself));
      }
      if (flush_character_buffer(self) < 0) {
***************
*** 1024,1027 ****
--- 1062,1066 ----
      new_parser->specified_attributes = self->specified_attributes;
      new_parser->in_callback = 0;
+     new_parser->ns_prefixes = self->ns_prefixes;
      new_parser->itself = XML_ExternalEntityParserCreate(self->itself, context,
  							encoding);
***************
*** 1084,1087 ****
--- 1123,1152 ----
  }
  
+ PyDoc_STRVAR(xmlparse_UseForeignDTD__doc__,
+ "UseForeignDTD([flag])\n\
+ Allows the application to provide an artificial external subset if one is\n\
+ not specified as part of the document instance.  This readily allows the\n\
+ use of a 'default' document type controlled by the application, while still\n\
+ getting the advantage of providing document type information to the parser.\n\
+ 'flag' defaults to True if not provided.");
+ 
+ static PyObject *
+ xmlparse_UseForeignDTD(xmlparseobject *self, PyObject *args)
+ {
+     PyObject *flagobj = NULL;
+     XML_Bool flag = XML_TRUE;
+     enum XML_Error rc;
+     if (!PyArg_ParseTuple(args, "|O:UseForeignDTD", &flagobj))
+         return NULL;
+     if (flagobj != NULL)
+         flag = PyObject_IsTrue(flagobj) ? XML_TRUE : XML_FALSE;
+     rc = XML_UseForeignDTD(self->itself, flag);
+     if (rc != XML_ERROR_NONE) {
+         return set_error(self, rc);
+     }
+     Py_INCREF(Py_None);
+     return Py_None;
+ }
+ 
  static struct PyMethodDef xmlparse_methods[] = {
      {"Parse",	  (PyCFunction)xmlparse_Parse,
***************
*** 1090,1103 ****
  		  METH_VARARGS,	xmlparse_ParseFile__doc__},
      {"SetBase",   (PyCFunction)xmlparse_SetBase,
! 		  METH_VARARGS,      xmlparse_SetBase__doc__},
      {"GetBase",   (PyCFunction)xmlparse_GetBase,
! 		  METH_VARARGS,      xmlparse_GetBase__doc__},
      {"ExternalEntityParserCreate", (PyCFunction)xmlparse_ExternalEntityParserCreate,
! 	 	  METH_VARARGS,      xmlparse_ExternalEntityParserCreate__doc__},
      {"SetParamEntityParsing", (PyCFunction)xmlparse_SetParamEntityParsing,
  		  METH_VARARGS, xmlparse_SetParamEntityParsing__doc__},
      {"GetInputContext", (PyCFunction)xmlparse_GetInputContext,
  		  METH_VARARGS, xmlparse_GetInputContext__doc__},
! 	{NULL,		NULL}		/* sentinel */
  };
  
--- 1155,1170 ----
  		  METH_VARARGS,	xmlparse_ParseFile__doc__},
      {"SetBase",   (PyCFunction)xmlparse_SetBase,
! 		  METH_VARARGS, xmlparse_SetBase__doc__},
      {"GetBase",   (PyCFunction)xmlparse_GetBase,
! 		  METH_VARARGS, xmlparse_GetBase__doc__},
      {"ExternalEntityParserCreate", (PyCFunction)xmlparse_ExternalEntityParserCreate,
! 	 	  METH_VARARGS, xmlparse_ExternalEntityParserCreate__doc__},
      {"SetParamEntityParsing", (PyCFunction)xmlparse_SetParamEntityParsing,
  		  METH_VARARGS, xmlparse_SetParamEntityParsing__doc__},
      {"GetInputContext", (PyCFunction)xmlparse_GetInputContext,
  		  METH_VARARGS, xmlparse_GetInputContext__doc__},
!     {"UseForeignDTD", (PyCFunction)xmlparse_UseForeignDTD,
! 		  METH_VARARGS, xmlparse_UseForeignDTD__doc__},
!     {NULL,	  NULL}		/* sentinel */
  };
  
***************
*** 1185,1188 ****
--- 1252,1256 ----
      self->specified_attributes = 0;
      self->in_callback = 0;
+     self->ns_prefixes = 0;
      self->handlers = NULL;
      if (namespace_separator != NULL) {
***************
*** 1316,1319 ****
--- 1384,1389 ----
              return PyInt_FromLong((long) self->buffer_used);
      }
+     if (strcmp(name, "namespace_prefixes") == 0)
+         return get_pybool(self->ns_prefixes);
      if (strcmp(name, "ordered_attributes") == 0)
          return get_pybool(self->ordered_attributes);
***************
*** 1334,1343 ****
  
  #define APPEND(list, str)				\
! 	do {						\
! 		PyObject *o = PyString_FromString(str);	\
! 		if (o != NULL)				\
! 			PyList_Append(list, o);		\
! 		Py_XDECREF(o);				\
! 	} while (0)
  
      if (strcmp(name, "__members__") == 0) {
--- 1404,1413 ----
  
  #define APPEND(list, str)				\
!         do {						\
!                 PyObject *o = PyString_FromString(str);	\
!                 if (o != NULL)				\
!         	        PyList_Append(list, o);		\
!                 Py_XDECREF(o);				\
!         } while (0)
  
      if (strcmp(name, "__members__") == 0) {
***************
*** 1357,1360 ****
--- 1427,1431 ----
          APPEND(rc, "buffer_text");
          APPEND(rc, "buffer_used");
+         APPEND(rc, "namespace_prefixes");
          APPEND(rc, "ordered_attributes");
          APPEND(rc, "returns_unicode");
***************
*** 1417,1420 ****
--- 1488,1499 ----
          return 0;
      }
+     if (strcmp(name, "namespace_prefixes") == 0) {
+         if (PyObject_IsTrue(v))
+             self->ns_prefixes = 1;
+         else
+             self->ns_prefixes = 0;
+         XML_SetReturnNSTriplet(self->itself, self->ns_prefixes);
+         return 0;
+     }
      if (strcmp(name, "ordered_attributes") == 0) {
          if (PyObject_IsTrue(v))
***************
*** 1515,1519 ****
  	Py_TPFLAGS_DEFAULT | Py_TPFLAGS_GC, /*tp_flags*/
  #endif
! 	Xmlparsetype__doc__, /* Documentation string */
  #ifdef WITH_CYCLE_GC
  	(traverseproc)xmlparse_traverse,	/* tp_traverse */
--- 1594,1598 ----
  	Py_TPFLAGS_DEFAULT | Py_TPFLAGS_GC, /*tp_flags*/
  #endif
! 	Xmlparsetype__doc__, /* tp_doc - Documentation string */
  #ifdef WITH_CYCLE_GC
  	(traverseproc)xmlparse_traverse,	/* tp_traverse */
***************
*** 1634,1640 ****
  #endif
  
  PyMODINIT_FUNC MODULE_INITFUNC(void);  /* avoid compiler warnings */
  
! PyMODINIT_FUNC MODULE_INITFUNC(void)
  {
      PyObject *m, *d;
--- 1713,1728 ----
  #endif
  
+ #ifndef PyMODINIT_FUNC
+ #   ifdef MS_WINDOWS
+ #       define PyMODINIT_FUNC __declspec(dllexport) void
+ #   else
+ #       define PyMODINIT_FUNC void
+ #   endif
+ #endif
+ 
  PyMODINIT_FUNC MODULE_INITFUNC(void);  /* avoid compiler warnings */
  
! PyMODINIT_FUNC
! MODULE_INITFUNC(void)
  {
      PyObject *m, *d;
***************
*** 1714,1717 ****
--- 1802,1834 ----
          /* Don't core dump later! */
          return;
+     
+     {
+         const XML_Feature *features = XML_GetFeatureList();
+         PyObject *list = PyList_New(0);
+         if (list == NULL)
+             /* just ignore it */
+             PyErr_Clear();
+         else {
+             int i = 0;
+             for (; features[i].feature != XML_FEATURE_END; ++i) {
+                 int ok;
+                 PyObject *item = Py_BuildValue("si", features[i].name,
+                                                features[i].value);
+                 if (item == NULL) {
+                     Py_DECREF(list);
+                     list = NULL;
+                     break;
+                 }
+                 ok = PyList_Append(list, item);
+                 Py_DECREF(item);
+                 if (ok < 0) {
+                     PyErr_Clear();
+                     break;
+                 }
+             }
+             if (list != NULL)
+                 PyModule_AddObject(m, "features", list);
+         }
+     }
  
  #define MYCONST(name) \
***************
*** 1853,1856 ****
--- 1970,1976 ----
       (xmlhandlersetter)XML_SetAttlistDeclHandler,
       (xmlhandler)my_AttlistDeclHandler},
+     {"SkippedEntityHandler",
+      (xmlhandlersetter)XML_SetSkippedEntityHandler,
+      (xmlhandler)my_SkippedEntityHandler},
  
      {NULL, NULL, NULL} /* sentinel */