[Python-checkins] python/dist/src/Modules pyexpat.c,2.80,2.81

jhylton@users.sourceforge.net jhylton@users.sourceforge.net
Fri, 27 Jun 2003 09:13:19 -0700


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

Modified Files:
	pyexpat.c 
Log Message:
Fix several bugs in handling of exceptions with trace function enabled.

If the callback raised an exception but did not set curexc_traceback,
the trace function was called with PyTrace_RETURN.  That is, the trace
function was called with an exception set.  The main loop detected the
exception when the trace function returned; it complained and disabled
tracing.

Fix the logic error so that PyTrace_RETURN only occurs if the callback
returned normally.

The trace function must be called for exceptions, too.  So we had
to add new functionality to call with PyTrace_EXCEPTION.  (Leads to a
rather ugly ifdef / else block that contains only a '}'.)

Reverse the logic and name of NOFIX_TRACE to FIX_TRACE.

Joint work with Fred.


Index: pyexpat.c
===================================================================
RCS file: /cvsroot/python/python/dist/src/Modules/pyexpat.c,v
retrieving revision 2.80
retrieving revision 2.81
diff -C2 -d -r2.80 -r2.81
*** pyexpat.c	2 Feb 2003 03:54:17 -0000	2.80
--- pyexpat.c	27 Jun 2003 16:13:17 -0000	2.81
***************
*** 25,29 ****
  /* In Python 2.0 and  2.1, disabling Unicode was not possible. */
  #define Py_USING_UNICODE
! #define NOFIX_TRACE
  #endif
  
--- 25,30 ----
  /* In Python 2.0 and  2.1, disabling Unicode was not possible. */
  #define Py_USING_UNICODE
! #else
! #define FIX_TRACE
  #endif
  
***************
*** 294,298 ****
  }
  
! #ifndef NOFIX_TRACE
  static int
  trace_frame(PyThreadState *tstate, PyFrameObject *f, int code, PyObject *val)
--- 295,299 ----
  }
  
! #ifdef FIX_TRACE
  static int
  trace_frame(PyThreadState *tstate, PyFrameObject *f, int code, PyObject *val)
***************
*** 321,324 ****
--- 322,356 ----
      return result;
  }
+ 
+ static int
+ trace_frame_exc(PyThreadState *tstate, PyFrameObject *f)
+ {
+     PyObject *type, *value, *traceback, *arg;
+     int err;
+ 
+     if (tstate->c_tracefunc == NULL)
+ 	return 0;
+ 
+     PyErr_Fetch(&type, &value, &traceback);
+     if (value == NULL) {
+ 	value = Py_None;
+ 	Py_INCREF(value);
+     }
+     arg = Py_BuildValue("(OOO)", type, value, traceback);
+     if (arg == NULL) {
+ 	PyErr_Restore(type, value, traceback);
+ 	return 0;
+     }
+     err = trace_frame(tstate, f, PyTrace_EXCEPTION, arg);
+     Py_DECREF(arg);
+     if (err == 0)
+ 	PyErr_Restore(type, value, traceback);
+     else {
+ 	Py_XDECREF(type);
+ 	Py_XDECREF(value);
+ 	Py_XDECREF(traceback);
+     }
+     return err;
+ }
  #endif
  
***************
*** 333,360 ****
          return NULL;
      
!     f = PyFrame_New(
!                     tstate,			/*back*/
!                     c,				/*code*/
!                     PyEval_GetGlobals(),	/*globals*/
!                     NULL			/*locals*/
!                     );
      if (f == NULL)
          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)) {
  	    Py_XDECREF(res);
  	    res = NULL;
  	}
      }
  #endif
--- 365,393 ----
          return NULL;
      
!     f = PyFrame_New(tstate, c, PyEval_GetGlobals(), NULL);
      if (f == NULL)
          return NULL;
      tstate->frame = f;
! #ifdef FIX_TRACE
!     if (trace_frame(tstate, f, PyTrace_CALL, Py_None) < 0) {
  	return NULL;
      }
  #endif
      res = PyEval_CallObject(func, args);
!     if (res == NULL) {
! 	if (tstate->curexc_traceback == NULL)
! 	    PyTraceBack_Here(f);
! #ifdef FIX_TRACE
! 	if (trace_frame_exc(tstate, f) < 0) {
! 	    return NULL;
! 	}
!     }
      else {
! 	if (trace_frame(tstate, f, PyTrace_RETURN, res) < 0) {
  	    Py_XDECREF(res);
  	    res = NULL;
  	}
+     }
+ #else
      }
  #endif