822 lines · 18.9 KB · C
RawDownload
 /* Error handling */ #include "Python.h" #ifndef __STDC__#ifndef MS_WINDOWSextern char *strerror(int);#endif#endif #ifdef MS_WINDOWS#include "windows.h"#include "winbase.h"#endif #include <ctype.h> #ifdef __cplusplusextern "C" {#endif  voidPyErr_Restore(PyObject *type, PyObject *value, PyObject *traceback){	PyThreadState *tstate = PyThreadState_GET();	PyObject *oldtype, *oldvalue, *oldtraceback; 	if (traceback != NULL && !PyTraceBack_Check(traceback)) {		/* XXX Should never happen -- fatal error instead? */		/* Well, it could be None. */		Py_DECREF(traceback);		traceback = NULL;	} 	/* Save these in locals to safeguard against recursive	   invocation through Py_XDECREF */	oldtype = tstate->curexc_type;	oldvalue = tstate->curexc_value;	oldtraceback = tstate->curexc_traceback; 	tstate->curexc_type = type;	tstate->curexc_value = value;	tstate->curexc_traceback = traceback; 	Py_XDECREF(oldtype);	Py_XDECREF(oldvalue);	Py_XDECREF(oldtraceback);} voidPyErr_SetObject(PyObject *exception, PyObject *value){	Py_XINCREF(exception);	Py_XINCREF(value);	PyErr_Restore(exception, value, (PyObject *)NULL);} voidPyErr_SetNone(PyObject *exception){	PyErr_SetObject(exception, (PyObject *)NULL);} voidPyErr_SetString(PyObject *exception, const char *string){	PyObject *value = PyString_FromString(string);	PyErr_SetObject(exception, value);	Py_XDECREF(value);}  PyObject *PyErr_Occurred(void){	PyThreadState *tstate = PyThreadState_GET(); 	return tstate->curexc_type;}  intPyErr_GivenExceptionMatches(PyObject *err, PyObject *exc){	if (err == NULL || exc == NULL) {		/* maybe caused by "import exceptions" that failed early on */		return 0;	}	if (PyTuple_Check(exc)) {		Py_ssize_t i, n;		n = PyTuple_Size(exc);		for (i = 0; i < n; i++) {			/* Test recursively */		     if (PyErr_GivenExceptionMatches(			     err, PyTuple_GET_ITEM(exc, i)))		     {			     return 1;		     }		}		return 0;	}	/* err might be an instance, so check its class. */	if (PyExceptionInstance_Check(err))		err = PyExceptionInstance_Class(err); 	if (PyExceptionClass_Check(err) && PyExceptionClass_Check(exc)) {		/* problems here!?  not sure PyObject_IsSubclass expects to		   be called with an exception pending... */		return PyObject_IsSubclass(err, exc);	} 	return err == exc;}  intPyErr_ExceptionMatches(PyObject *exc){	return PyErr_GivenExceptionMatches(PyErr_Occurred(), exc);}  /* Used in many places to normalize a raised exception, including in   eval_code2(), do_raise(), and PyErr_Print()*/voidPyErr_NormalizeException(PyObject **exc, PyObject **val, PyObject **tb){	PyObject *type = *exc;	PyObject *value = *val;	PyObject *inclass = NULL;	PyObject *initial_tb = NULL; 	if (type == NULL) {		/* There was no exception, so nothing to do. */		return;	} 	/* If PyErr_SetNone() was used, the value will have been actually	   set to NULL.	*/	if (!value) {		value = Py_None;		Py_INCREF(value);	} 	if (PyExceptionInstance_Check(value))		inclass = PyExceptionInstance_Class(value); 	/* Normalize the exception so that if the type is a class, the	   value will be an instance.	*/	if (PyExceptionClass_Check(type)) {		/* if the value was not an instance, or is not an instance		   whose class is (or is derived from) type, then use the		   value as an argument to instantiation of the type		   class.		*/		if (!inclass || !PyObject_IsSubclass(inclass, type)) {			PyObject *args, *res; 			if (value == Py_None)				args = PyTuple_New(0);			else if (PyTuple_Check(value)) {				Py_INCREF(value);				args = value;			}			else				args = PyTuple_Pack(1, value); 			if (args == NULL)				goto finally;			res = PyEval_CallObject(type, args);			Py_DECREF(args);			if (res == NULL)				goto finally;			Py_DECREF(value);			value = res;		}		/* if the class of the instance doesn't exactly match the		   class of the type, believe the instance		*/		else if (inclass != type) { 			Py_DECREF(type);			type = inclass;			Py_INCREF(type);		}	}	*exc = type;	*val = value;	return;finally:	Py_DECREF(type);	Py_DECREF(value);	/* If the new exception doesn't set a traceback and the old	   exception had a traceback, use the old traceback for the	   new exception.  It's better than nothing.	*/	initial_tb = *tb;	PyErr_Fetch(exc, val, tb);	if (initial_tb != NULL) {		if (*tb == NULL)			*tb = initial_tb;		else			Py_DECREF(initial_tb);	}	/* normalize recursively */	PyErr_NormalizeException(exc, val, tb);}  voidPyErr_Fetch(PyObject **p_type, PyObject **p_value, PyObject **p_traceback){	PyThreadState *tstate = PyThreadState_GET(); 	*p_type = tstate->curexc_type;	*p_value = tstate->curexc_value;	*p_traceback = tstate->curexc_traceback; 	tstate->curexc_type = NULL;	tstate->curexc_value = NULL;	tstate->curexc_traceback = NULL;} voidPyErr_Clear(void){	PyErr_Restore(NULL, NULL, NULL);} /* Convenience functions to set a type error exception and return 0 */ intPyErr_BadArgument(void){	PyErr_SetString(PyExc_TypeError,			"bad argument type for built-in operation");	return 0;} PyObject *PyErr_NoMemory(void){	if (PyErr_ExceptionMatches(PyExc_MemoryError))		/* already current */		return NULL; 	/* raise the pre-allocated instance if it still exists */	if (PyExc_MemoryErrorInst)		PyErr_SetObject(PyExc_MemoryError, PyExc_MemoryErrorInst);	else		/* this will probably fail since there's no memory and hee,		   hee, we have to instantiate this class		*/		PyErr_SetNone(PyExc_MemoryError); 	return NULL;} PyObject *PyErr_SetFromErrnoWithFilenameObject(PyObject *exc, PyObject *filenameObject){	PyObject *v;	char *s;	int i = errno;#ifdef PLAN9	char errbuf[ERRMAX];#endif#ifdef MS_WINDOWS	char *s_buf = NULL;	char s_small_buf[28]; /* Room for "Windows Error 0xFFFFFFFF" */#endif#ifdef EINTR	if (i == EINTR && PyErr_CheckSignals())		return NULL;#endif#ifdef PLAN9	rerrstr(errbuf, sizeof errbuf);	s = errbuf;#else	if (i == 0)		s = "Error"; /* Sometimes errno didn't get set */	else#ifndef MS_WINDOWS		s = strerror(i);#else	{		/* Note that the Win32 errors do not lineup with the		   errno error.  So if the error is in the MSVC error		   table, we use it, otherwise we assume it really _is_		   a Win32 error code		*/		if (i > 0 && i < _sys_nerr) {			s = _sys_errlist[i];		}		else {			int len = FormatMessage(				FORMAT_MESSAGE_ALLOCATE_BUFFER |				FORMAT_MESSAGE_FROM_SYSTEM |				FORMAT_MESSAGE_IGNORE_INSERTS,				NULL,	/* no message source */				i,				MAKELANGID(LANG_NEUTRAL,					   SUBLANG_DEFAULT),				           /* Default language */				(LPTSTR) &s_buf,				0,	/* size not used */				NULL);	/* no args */			if (len==0) {				/* Only ever seen this in out-of-mem				   situations */				sprintf(s_small_buf, "Windows Error 0x%X", i);				s = s_small_buf;				s_buf = NULL;			} else {				s = s_buf;				/* remove trailing cr/lf and dots */				while (len > 0 && (s[len-1] <= ' ' || s[len-1] == '.'))					s[--len] = '\0';			}		}	}#endif /* Unix/Windows */#endif /* PLAN 9*/	if (filenameObject != NULL)		v = Py_BuildValue("(isO)", i, s, filenameObject);	else		v = Py_BuildValue("(is)", i, s);	if (v != NULL) {		PyErr_SetObject(exc, v);		Py_DECREF(v);	}#ifdef MS_WINDOWS	LocalFree(s_buf);#endif	return NULL;}  PyObject *PyErr_SetFromErrnoWithFilename(PyObject *exc, char *filename){	PyObject *name = filename ? PyString_FromString(filename) : NULL;	PyObject *result = PyErr_SetFromErrnoWithFilenameObject(exc, name);	Py_XDECREF(name);	return result;} #ifdef Py_WIN_WIDE_FILENAMESPyObject *PyErr_SetFromErrnoWithUnicodeFilename(PyObject *exc, Py_UNICODE *filename){	PyObject *name = filename ?	                 PyUnicode_FromUnicode(filename, wcslen(filename)) :	                 NULL;	PyObject *result = PyErr_SetFromErrnoWithFilenameObject(exc, name);	Py_XDECREF(name);	return result;}#endif /* Py_WIN_WIDE_FILENAMES */ PyObject *PyErr_SetFromErrno(PyObject *exc){	return PyErr_SetFromErrnoWithFilenameObject(exc, NULL);} #ifdef MS_WINDOWS/* Windows specific error code handling */PyObject *PyErr_SetExcFromWindowsErrWithFilenameObject(	PyObject *exc,	int ierr,	PyObject *filenameObject){	int len;	char *s;	char *s_buf = NULL; /* Free via LocalFree */	char s_small_buf[28]; /* Room for "Windows Error 0xFFFFFFFF" */	PyObject *v;	DWORD err = (DWORD)ierr;	if (err==0) err = GetLastError();	len = FormatMessage(		/* Error API error */		FORMAT_MESSAGE_ALLOCATE_BUFFER |		FORMAT_MESSAGE_FROM_SYSTEM |		FORMAT_MESSAGE_IGNORE_INSERTS,		NULL,	/* no message source */		err,		MAKELANGID(LANG_NEUTRAL,		SUBLANG_DEFAULT), /* Default language */		(LPTSTR) &s_buf,		0,	/* size not used */		NULL);	/* no args */	if (len==0) {		/* Only seen this in out of mem situations */		sprintf(s_small_buf, "Windows Error 0x%X", err);		s = s_small_buf;		s_buf = NULL;	} else {		s = s_buf;		/* remove trailing cr/lf and dots */		while (len > 0 && (s[len-1] <= ' ' || s[len-1] == '.'))			s[--len] = '\0';	}	if (filenameObject != NULL)		v = Py_BuildValue("(isO)", err, s, filenameObject);	else		v = Py_BuildValue("(is)", err, s);	if (v != NULL) {		PyErr_SetObject(exc, v);		Py_DECREF(v);	}	LocalFree(s_buf);	return NULL;} PyObject *PyErr_SetExcFromWindowsErrWithFilename(	PyObject *exc,	int ierr,	const char *filename){	PyObject *name = filename ? PyString_FromString(filename) : NULL;	PyObject *ret = PyErr_SetExcFromWindowsErrWithFilenameObject(exc,	                                                             ierr,	                                                             name);	Py_XDECREF(name);	return ret;} #ifdef Py_WIN_WIDE_FILENAMESPyObject *PyErr_SetExcFromWindowsErrWithUnicodeFilename(	PyObject *exc,	int ierr,	const Py_UNICODE *filename){	PyObject *name = filename ?	                 PyUnicode_FromUnicode(filename, wcslen(filename)) :	                 NULL;	PyObject *ret = PyErr_SetExcFromWindowsErrWithFilenameObject(exc,	                                                             ierr,	                                                             name);	Py_XDECREF(name);	return ret;}#endif /* Py_WIN_WIDE_FILENAMES */ PyObject *PyErr_SetExcFromWindowsErr(PyObject *exc, int ierr){	return PyErr_SetExcFromWindowsErrWithFilename(exc, ierr, NULL);} PyObject *PyErr_SetFromWindowsErr(int ierr){	return PyErr_SetExcFromWindowsErrWithFilename(PyExc_WindowsError,						      ierr, NULL);}PyObject *PyErr_SetFromWindowsErrWithFilename(	int ierr,	const char *filename){	PyObject *name = filename ? PyString_FromString(filename) : NULL;	PyObject *result = PyErr_SetExcFromWindowsErrWithFilenameObject(						      PyExc_WindowsError,						      ierr, name);	Py_XDECREF(name);	return result;} #ifdef Py_WIN_WIDE_FILENAMESPyObject *PyErr_SetFromWindowsErrWithUnicodeFilename(	int ierr,	const Py_UNICODE *filename){	PyObject *name = filename ?	                 PyUnicode_FromUnicode(filename, wcslen(filename)) :	                 NULL;	PyObject *result = PyErr_SetExcFromWindowsErrWithFilenameObject(						      PyExc_WindowsError,						      ierr, name);	Py_XDECREF(name);	return result;}#endif /* Py_WIN_WIDE_FILENAMES */#endif /* MS_WINDOWS */ void_PyErr_BadInternalCall(char *filename, int lineno){	PyErr_Format(PyExc_SystemError,		     "%s:%d: bad argument to internal function",		     filename, lineno);} /* Remove the preprocessor macro for PyErr_BadInternalCall() so that we can   export the entry point for existing object code: */#undef PyErr_BadInternalCallvoid

Lines 1–500 of 822.