+++ /dev/null
-\r
-/* Error handling */\r
-\r
-#include "Python.h"\r
-\r
-#ifndef __STDC__\r
-#ifndef MS_WINDOWS\r
-extern char *strerror(int);\r
-#endif\r
-#endif\r
-\r
-#ifdef MS_WINDOWS\r
-#include "windows.h"\r
-#include "winbase.h"\r
-#endif\r
-\r
-#include <ctype.h>\r
-\r
-#ifdef __cplusplus\r
-extern "C" {\r
-#endif\r
-\r
-\r
-void\r
-PyErr_Restore(PyObject *type, PyObject *value, PyObject *traceback)\r
-{\r
- PyThreadState *tstate = PyThreadState_GET();\r
- PyObject *oldtype, *oldvalue, *oldtraceback;\r
-\r
- if (traceback != NULL && !PyTraceBack_Check(traceback)) {\r
- /* XXX Should never happen -- fatal error instead? */\r
- /* Well, it could be None. */\r
- Py_DECREF(traceback);\r
- traceback = NULL;\r
- }\r
-\r
- /* Save these in locals to safeguard against recursive\r
- invocation through Py_XDECREF */\r
- oldtype = tstate->curexc_type;\r
- oldvalue = tstate->curexc_value;\r
- oldtraceback = tstate->curexc_traceback;\r
-\r
- tstate->curexc_type = type;\r
- tstate->curexc_value = value;\r
- tstate->curexc_traceback = traceback;\r
-\r
- Py_XDECREF(oldtype);\r
- Py_XDECREF(oldvalue);\r
- Py_XDECREF(oldtraceback);\r
-}\r
-\r
-void\r
-PyErr_SetObject(PyObject *exception, PyObject *value)\r
-{\r
- Py_XINCREF(exception);\r
- Py_XINCREF(value);\r
- PyErr_Restore(exception, value, (PyObject *)NULL);\r
-}\r
-\r
-void\r
-PyErr_SetNone(PyObject *exception)\r
-{\r
- PyErr_SetObject(exception, (PyObject *)NULL);\r
-}\r
-\r
-void\r
-PyErr_SetString(PyObject *exception, const char *string)\r
-{\r
- PyObject *value = PyString_FromString(string);\r
- PyErr_SetObject(exception, value);\r
- Py_XDECREF(value);\r
-}\r
-\r
-\r
-PyObject *\r
-PyErr_Occurred(void)\r
-{\r
- PyThreadState *tstate = PyThreadState_GET();\r
-\r
- return tstate->curexc_type;\r
-}\r
-\r
-\r
-int\r
-PyErr_GivenExceptionMatches(PyObject *err, PyObject *exc)\r
-{\r
- if (err == NULL || exc == NULL) {\r
- /* maybe caused by "import exceptions" that failed early on */\r
- return 0;\r
- }\r
- if (PyTuple_Check(exc)) {\r
- Py_ssize_t i, n;\r
- n = PyTuple_Size(exc);\r
- for (i = 0; i < n; i++) {\r
- /* Test recursively */\r
- if (PyErr_GivenExceptionMatches(\r
- err, PyTuple_GET_ITEM(exc, i)))\r
- {\r
- return 1;\r
- }\r
- }\r
- return 0;\r
- }\r
- /* err might be an instance, so check its class. */\r
- if (PyExceptionInstance_Check(err))\r
- err = PyExceptionInstance_Class(err);\r
-\r
- if (PyExceptionClass_Check(err) && PyExceptionClass_Check(exc)) {\r
- int res = 0, reclimit;\r
- PyObject *exception, *value, *tb;\r
- PyErr_Fetch(&exception, &value, &tb);\r
- /* Temporarily bump the recursion limit, so that in the most\r
- common case PyObject_IsSubclass will not raise a recursion\r
- error we have to ignore anyway. Don't do it when the limit\r
- is already insanely high, to avoid overflow */\r
- reclimit = Py_GetRecursionLimit();\r
- if (reclimit < (1 << 30))\r
- Py_SetRecursionLimit(reclimit + 5);\r
- res = PyObject_IsSubclass(err, exc);\r
- Py_SetRecursionLimit(reclimit);\r
- /* This function must not fail, so print the error here */\r
- if (res == -1) {\r
- PyErr_WriteUnraisable(err);\r
- res = 0;\r
- }\r
- PyErr_Restore(exception, value, tb);\r
- return res;\r
- }\r
-\r
- return err == exc;\r
-}\r
-\r
-\r
-int\r
-PyErr_ExceptionMatches(PyObject *exc)\r
-{\r
- return PyErr_GivenExceptionMatches(PyErr_Occurred(), exc);\r
-}\r
-\r
-\r
-/* Used in many places to normalize a raised exception, including in\r
- eval_code2(), do_raise(), and PyErr_Print()\r
-*/\r
-void\r
-PyErr_NormalizeException(PyObject **exc, PyObject **val, PyObject **tb)\r
-{\r
- PyObject *type = *exc;\r
- PyObject *value = *val;\r
- PyObject *inclass = NULL;\r
- PyObject *initial_tb = NULL;\r
- PyThreadState *tstate = NULL;\r
-\r
- if (type == NULL) {\r
- /* There was no exception, so nothing to do. */\r
- return;\r
- }\r
-\r
- /* If PyErr_SetNone() was used, the value will have been actually\r
- set to NULL.\r
- */\r
- if (!value) {\r
- value = Py_None;\r
- Py_INCREF(value);\r
- }\r
-\r
- if (PyExceptionInstance_Check(value))\r
- inclass = PyExceptionInstance_Class(value);\r
-\r
- /* Normalize the exception so that if the type is a class, the\r
- value will be an instance.\r
- */\r
- if (PyExceptionClass_Check(type)) {\r
- /* if the value was not an instance, or is not an instance\r
- whose class is (or is derived from) type, then use the\r
- value as an argument to instantiation of the type\r
- class.\r
- */\r
- if (!inclass || !PyObject_IsSubclass(inclass, type)) {\r
- PyObject *args, *res;\r
-\r
- if (value == Py_None)\r
- args = PyTuple_New(0);\r
- else if (PyTuple_Check(value)) {\r
- Py_INCREF(value);\r
- args = value;\r
- }\r
- else\r
- args = PyTuple_Pack(1, value);\r
-\r
- if (args == NULL)\r
- goto finally;\r
- res = PyEval_CallObject(type, args);\r
- Py_DECREF(args);\r
- if (res == NULL)\r
- goto finally;\r
- Py_DECREF(value);\r
- value = res;\r
- }\r
- /* if the class of the instance doesn't exactly match the\r
- class of the type, believe the instance\r
- */\r
- else if (inclass != type) {\r
- Py_DECREF(type);\r
- type = inclass;\r
- Py_INCREF(type);\r
- }\r
- }\r
- *exc = type;\r
- *val = value;\r
- return;\r
-finally:\r
- Py_DECREF(type);\r
- Py_DECREF(value);\r
- /* If the new exception doesn't set a traceback and the old\r
- exception had a traceback, use the old traceback for the\r
- new exception. It's better than nothing.\r
- */\r
- initial_tb = *tb;\r
- PyErr_Fetch(exc, val, tb);\r
- if (initial_tb != NULL) {\r
- if (*tb == NULL)\r
- *tb = initial_tb;\r
- else\r
- Py_DECREF(initial_tb);\r
- }\r
- /* normalize recursively */\r
- tstate = PyThreadState_GET();\r
- if (++tstate->recursion_depth > Py_GetRecursionLimit()) {\r
- --tstate->recursion_depth;\r
- /* throw away the old exception... */\r
- Py_DECREF(*exc);\r
- Py_DECREF(*val);\r
- /* ... and use the recursion error instead */\r
- *exc = PyExc_RuntimeError;\r
- *val = PyExc_RecursionErrorInst;\r
- Py_INCREF(*exc);\r
- Py_INCREF(*val);\r
- /* just keeping the old traceback */\r
- return;\r
- }\r
- PyErr_NormalizeException(exc, val, tb);\r
- --tstate->recursion_depth;\r
-}\r
-\r
-\r
-void\r
-PyErr_Fetch(PyObject **p_type, PyObject **p_value, PyObject **p_traceback)\r
-{\r
- PyThreadState *tstate = PyThreadState_GET();\r
-\r
- *p_type = tstate->curexc_type;\r
- *p_value = tstate->curexc_value;\r
- *p_traceback = tstate->curexc_traceback;\r
-\r
- tstate->curexc_type = NULL;\r
- tstate->curexc_value = NULL;\r
- tstate->curexc_traceback = NULL;\r
-}\r
-\r
-void\r
-PyErr_Clear(void)\r
-{\r
- PyErr_Restore(NULL, NULL, NULL);\r
-}\r
-\r
-/* Restore previously fetched exception if an exception is not set,\r
- otherwise drop previously fetched exception.\r
- Like _PyErr_ChainExceptions() in Python 3, but doesn't set the context.\r
- */\r
-void\r
-_PyErr_ReplaceException(PyObject *exc, PyObject *val, PyObject *tb)\r
-{\r
- if (exc == NULL)\r
- return;\r
-\r
- if (PyErr_Occurred()) {\r
- Py_DECREF(exc);\r
- Py_XDECREF(val);\r
- Py_XDECREF(tb);\r
- }\r
- else {\r
- PyErr_Restore(exc, val, tb);\r
- }\r
-}\r
-\r
-/* Convenience functions to set a type error exception and return 0 */\r
-\r
-int\r
-PyErr_BadArgument(void)\r
-{\r
- PyErr_SetString(PyExc_TypeError,\r
- "bad argument type for built-in operation");\r
- return 0;\r
-}\r
-\r
-PyObject *\r
-PyErr_NoMemory(void)\r
-{\r
- if (PyErr_ExceptionMatches(PyExc_MemoryError))\r
- /* already current */\r
- return NULL;\r
-\r
- /* raise the pre-allocated instance if it still exists */\r
- if (PyExc_MemoryErrorInst)\r
- PyErr_SetObject(PyExc_MemoryError, PyExc_MemoryErrorInst);\r
- else\r
- /* this will probably fail since there's no memory and hee,\r
- hee, we have to instantiate this class\r
- */\r
- PyErr_SetNone(PyExc_MemoryError);\r
-\r
- return NULL;\r
-}\r
-\r
-PyObject *\r
-PyErr_SetFromErrnoWithFilenameObject(PyObject *exc, PyObject *filenameObject)\r
-{\r
- PyObject *v;\r
- char *s;\r
- int i = errno;\r
-#ifdef PLAN9\r
- char errbuf[ERRMAX];\r
-#endif\r
-#ifdef MS_WINDOWS\r
- char *s_buf = NULL;\r
- char s_small_buf[28]; /* Room for "Windows Error 0xFFFFFFFF" */\r
-#endif\r
-#ifdef EINTR\r
- if (i == EINTR && PyErr_CheckSignals())\r
- return NULL;\r
-#endif\r
-#ifdef PLAN9\r
- rerrstr(errbuf, sizeof errbuf);\r
- s = errbuf;\r
-#else\r
- if (i == 0)\r
- s = "Error"; /* Sometimes errno didn't get set */\r
- else\r
-#ifndef MS_WINDOWS\r
- s = strerror(i);\r
-#else\r
- {\r
- /* Note that the Win32 errors do not lineup with the\r
- errno error. So if the error is in the MSVC error\r
- table, we use it, otherwise we assume it really _is_\r
- a Win32 error code\r
- */\r
- if (i > 0 && i < _sys_nerr) {\r
- s = _sys_errlist[i];\r
- }\r
- else {\r
- int len = FormatMessage(\r
- FORMAT_MESSAGE_ALLOCATE_BUFFER |\r
- FORMAT_MESSAGE_FROM_SYSTEM |\r
- FORMAT_MESSAGE_IGNORE_INSERTS,\r
- NULL, /* no message source */\r
- i,\r
- MAKELANGID(LANG_NEUTRAL,\r
- SUBLANG_DEFAULT),\r
- /* Default language */\r
- (LPTSTR) &s_buf,\r
- 0, /* size not used */\r
- NULL); /* no args */\r
- if (len==0) {\r
- /* Only ever seen this in out-of-mem\r
- situations */\r
- sprintf(s_small_buf, "Windows Error 0x%X", i);\r
- s = s_small_buf;\r
- s_buf = NULL;\r
- } else {\r
- s = s_buf;\r
- /* remove trailing cr/lf and dots */\r
- while (len > 0 && (s[len-1] <= ' ' || s[len-1] == '.'))\r
- s[--len] = '\0';\r
- }\r
- }\r
- }\r
-#endif /* Unix/Windows */\r
-#endif /* PLAN 9*/\r
- if (filenameObject != NULL)\r
- v = Py_BuildValue("(isO)", i, s, filenameObject);\r
- else\r
- v = Py_BuildValue("(is)", i, s);\r
- if (v != NULL) {\r
- PyErr_SetObject(exc, v);\r
- Py_DECREF(v);\r
- }\r
-#ifdef MS_WINDOWS\r
- LocalFree(s_buf);\r
-#endif\r
- return NULL;\r
-}\r
-\r
-\r
-PyObject *\r
-PyErr_SetFromErrnoWithFilename(PyObject *exc, const char *filename)\r
-{\r
- PyObject *name = filename ? PyString_FromString(filename) : NULL;\r
- PyObject *result = PyErr_SetFromErrnoWithFilenameObject(exc, name);\r
- Py_XDECREF(name);\r
- return result;\r
-}\r
-\r
-#ifdef MS_WINDOWS\r
-PyObject *\r
-PyErr_SetFromErrnoWithUnicodeFilename(PyObject *exc, const Py_UNICODE *filename)\r
-{\r
- PyObject *name = filename ?\r
- PyUnicode_FromUnicode(filename, wcslen(filename)) :\r
- NULL;\r
- PyObject *result = PyErr_SetFromErrnoWithFilenameObject(exc, name);\r
- Py_XDECREF(name);\r
- return result;\r
-}\r
-#endif /* MS_WINDOWS */\r
-\r
-PyObject *\r
-PyErr_SetFromErrno(PyObject *exc)\r
-{\r
- return PyErr_SetFromErrnoWithFilenameObject(exc, NULL);\r
-}\r
-\r
-#ifdef MS_WINDOWS\r
-/* Windows specific error code handling */\r
-PyObject *PyErr_SetExcFromWindowsErrWithFilenameObject(\r
- PyObject *exc,\r
- int ierr,\r
- PyObject *filenameObject)\r
-{\r
- int len;\r
- char *s;\r
- char *s_buf = NULL; /* Free via LocalFree */\r
- char s_small_buf[28]; /* Room for "Windows Error 0xFFFFFFFF" */\r
- PyObject *v;\r
- DWORD err = (DWORD)ierr;\r
- if (err==0) err = GetLastError();\r
- len = FormatMessage(\r
- /* Error API error */\r
- FORMAT_MESSAGE_ALLOCATE_BUFFER |\r
- FORMAT_MESSAGE_FROM_SYSTEM |\r
- FORMAT_MESSAGE_IGNORE_INSERTS,\r
- NULL, /* no message source */\r
- err,\r
- MAKELANGID(LANG_NEUTRAL,\r
- SUBLANG_DEFAULT), /* Default language */\r
- (LPTSTR) &s_buf,\r
- 0, /* size not used */\r
- NULL); /* no args */\r
- if (len==0) {\r
- /* Only seen this in out of mem situations */\r
- sprintf(s_small_buf, "Windows Error 0x%X", err);\r
- s = s_small_buf;\r
- s_buf = NULL;\r
- } else {\r
- s = s_buf;\r
- /* remove trailing cr/lf and dots */\r
- while (len > 0 && (s[len-1] <= ' ' || s[len-1] == '.'))\r
- s[--len] = '\0';\r
- }\r
- if (filenameObject != NULL)\r
- v = Py_BuildValue("(isO)", err, s, filenameObject);\r
- else\r
- v = Py_BuildValue("(is)", err, s);\r
- if (v != NULL) {\r
- PyErr_SetObject(exc, v);\r
- Py_DECREF(v);\r
- }\r
- LocalFree(s_buf);\r
- return NULL;\r
-}\r
-\r
-PyObject *PyErr_SetExcFromWindowsErrWithFilename(\r
- PyObject *exc,\r
- int ierr,\r
- const char *filename)\r
-{\r
- PyObject *name = filename ? PyString_FromString(filename) : NULL;\r
- PyObject *ret = PyErr_SetExcFromWindowsErrWithFilenameObject(exc,\r
- ierr,\r
- name);\r
- Py_XDECREF(name);\r
- return ret;\r
-}\r
-\r
-PyObject *PyErr_SetExcFromWindowsErrWithUnicodeFilename(\r
- PyObject *exc,\r
- int ierr,\r
- const Py_UNICODE *filename)\r
-{\r
- PyObject *name = filename ?\r
- PyUnicode_FromUnicode(filename, wcslen(filename)) :\r
- NULL;\r
- PyObject *ret = PyErr_SetExcFromWindowsErrWithFilenameObject(exc,\r
- ierr,\r
- name);\r
- Py_XDECREF(name);\r
- return ret;\r
-}\r
-\r
-PyObject *PyErr_SetExcFromWindowsErr(PyObject *exc, int ierr)\r
-{\r
- return PyErr_SetExcFromWindowsErrWithFilename(exc, ierr, NULL);\r
-}\r
-\r
-PyObject *PyErr_SetFromWindowsErr(int ierr)\r
-{\r
- return PyErr_SetExcFromWindowsErrWithFilename(PyExc_WindowsError,\r
- ierr, NULL);\r
-}\r
-PyObject *PyErr_SetFromWindowsErrWithFilename(\r
- int ierr,\r
- const char *filename)\r
-{\r
- PyObject *name = filename ? PyString_FromString(filename) : NULL;\r
- PyObject *result = PyErr_SetExcFromWindowsErrWithFilenameObject(\r
- PyExc_WindowsError,\r
- ierr, name);\r
- Py_XDECREF(name);\r
- return result;\r
-}\r
-\r
-PyObject *PyErr_SetFromWindowsErrWithUnicodeFilename(\r
- int ierr,\r
- const Py_UNICODE *filename)\r
-{\r
- PyObject *name = filename ?\r
- PyUnicode_FromUnicode(filename, wcslen(filename)) :\r
- NULL;\r
- PyObject *result = PyErr_SetExcFromWindowsErrWithFilenameObject(\r
- PyExc_WindowsError,\r
- ierr, name);\r
- Py_XDECREF(name);\r
- return result;\r
-}\r
-#endif /* MS_WINDOWS */\r
-\r
-void\r
-_PyErr_BadInternalCall(char *filename, int lineno)\r
-{\r
- PyErr_Format(PyExc_SystemError,\r
- "%s:%d: bad argument to internal function",\r
- filename, lineno);\r
-}\r
-\r
-/* Remove the preprocessor macro for PyErr_BadInternalCall() so that we can\r
- export the entry point for existing object code: */\r
-#undef PyErr_BadInternalCall\r
-void\r
-PyErr_BadInternalCall(void)\r
-{\r
- PyErr_Format(PyExc_SystemError,\r
- "bad argument to internal function");\r
-}\r
-#define PyErr_BadInternalCall() _PyErr_BadInternalCall(__FILE__, __LINE__)\r
-\r
-\r
-\r
-PyObject *\r
-PyErr_Format(PyObject *exception, const char *format, ...)\r
-{\r
- va_list vargs;\r
- PyObject* string;\r
-\r
-#ifdef HAVE_STDARG_PROTOTYPES\r
- va_start(vargs, format);\r
-#else\r
- va_start(vargs);\r
-#endif\r
-\r
- string = PyString_FromFormatV(format, vargs);\r
- PyErr_SetObject(exception, string);\r
- Py_XDECREF(string);\r
- va_end(vargs);\r
- return NULL;\r
-}\r
-\r
-\r
-\r
-PyObject *\r
-PyErr_NewException(char *name, PyObject *base, PyObject *dict)\r
-{\r
- char *dot;\r
- PyObject *modulename = NULL;\r
- PyObject *classname = NULL;\r
- PyObject *mydict = NULL;\r
- PyObject *bases = NULL;\r
- PyObject *result = NULL;\r
- dot = strrchr(name, '.');\r
- if (dot == NULL) {\r
- PyErr_SetString(PyExc_SystemError,\r
- "PyErr_NewException: name must be module.class");\r
- return NULL;\r
- }\r
- if (base == NULL)\r
- base = PyExc_Exception;\r
- if (dict == NULL) {\r
- dict = mydict = PyDict_New();\r
- if (dict == NULL)\r
- goto failure;\r
- }\r
- if (PyDict_GetItemString(dict, "__module__") == NULL) {\r
- modulename = PyString_FromStringAndSize(name,\r
- (Py_ssize_t)(dot-name));\r
- if (modulename == NULL)\r
- goto failure;\r
- if (PyDict_SetItemString(dict, "__module__", modulename) != 0)\r
- goto failure;\r
- }\r
- if (PyTuple_Check(base)) {\r
- bases = base;\r
- /* INCREF as we create a new ref in the else branch */\r
- Py_INCREF(bases);\r
- } else {\r
- bases = PyTuple_Pack(1, base);\r
- if (bases == NULL)\r
- goto failure;\r
- }\r
- /* Create a real new-style class. */\r
- result = PyObject_CallFunction((PyObject *)&PyType_Type, "sOO",\r
- dot+1, bases, dict);\r
- failure:\r
- Py_XDECREF(bases);\r
- Py_XDECREF(mydict);\r
- Py_XDECREF(classname);\r
- Py_XDECREF(modulename);\r
- return result;\r
-}\r
-\r
-\r
-/* Create an exception with docstring */\r
-PyObject *\r
-PyErr_NewExceptionWithDoc(char *name, char *doc, PyObject *base, PyObject *dict)\r
-{\r
- int result;\r
- PyObject *ret = NULL;\r
- PyObject *mydict = NULL; /* points to the dict only if we create it */\r
- PyObject *docobj;\r
-\r
- if (dict == NULL) {\r
- dict = mydict = PyDict_New();\r
- if (dict == NULL) {\r
- return NULL;\r
- }\r
- }\r
-\r
- if (doc != NULL) {\r
- docobj = PyString_FromString(doc);\r
- if (docobj == NULL)\r
- goto failure;\r
- result = PyDict_SetItemString(dict, "__doc__", docobj);\r
- Py_DECREF(docobj);\r
- if (result < 0)\r
- goto failure;\r
- }\r
-\r
- ret = PyErr_NewException(name, base, dict);\r
- failure:\r
- Py_XDECREF(mydict);\r
- return ret;\r
-}\r
-\r
-\r
-/* Call when an exception has occurred but there is no way for Python\r
- to handle it. Examples: exception in __del__ or during GC. */\r
-void\r
-PyErr_WriteUnraisable(PyObject *obj)\r
-{\r
- PyObject *f, *t, *v, *tb;\r
- PyErr_Fetch(&t, &v, &tb);\r
- f = PySys_GetObject("stderr");\r
- if (f != NULL) {\r
- PyFile_WriteString("Exception ", f);\r
- if (t) {\r
- PyObject* moduleName;\r
- char* className;\r
- assert(PyExceptionClass_Check(t));\r
- className = PyExceptionClass_Name(t);\r
- if (className != NULL) {\r
- char *dot = strrchr(className, '.');\r
- if (dot != NULL)\r
- className = dot+1;\r
- }\r
-\r
- moduleName = PyObject_GetAttrString(t, "__module__");\r
- if (moduleName == NULL)\r
- PyFile_WriteString("<unknown>", f);\r
- else {\r
- char* modstr = PyString_AsString(moduleName);\r
- if (modstr &&\r
- strcmp(modstr, "exceptions") != 0)\r
- {\r
- PyFile_WriteString(modstr, f);\r
- PyFile_WriteString(".", f);\r
- }\r
- }\r
- if (className == NULL)\r
- PyFile_WriteString("<unknown>", f);\r
- else\r
- PyFile_WriteString(className, f);\r
- if (v && v != Py_None) {\r
- PyFile_WriteString(": ", f);\r
- PyFile_WriteObject(v, f, 0);\r
- }\r
- Py_XDECREF(moduleName);\r
- }\r
- PyFile_WriteString(" in ", f);\r
- PyFile_WriteObject(obj, f, 0);\r
- PyFile_WriteString(" ignored\n", f);\r
- PyErr_Clear(); /* Just in case */\r
- }\r
- Py_XDECREF(t);\r
- Py_XDECREF(v);\r
- Py_XDECREF(tb);\r
-}\r
-\r
-extern PyObject *PyModule_GetWarningsModule(void);\r
-\r
-\r
-/* Set file and line information for the current exception.\r
- If the exception is not a SyntaxError, also sets additional attributes\r
- to make printing of exceptions believe it is a syntax error. */\r
-\r
-void\r
-PyErr_SyntaxLocation(const char *filename, int lineno)\r
-{\r
- PyObject *exc, *v, *tb, *tmp;\r
-\r
- /* add attributes for the line number and filename for the error */\r
- PyErr_Fetch(&exc, &v, &tb);\r
- PyErr_NormalizeException(&exc, &v, &tb);\r
- /* XXX check that it is, indeed, a syntax error. It might not\r
- * be, though. */\r
- tmp = PyInt_FromLong(lineno);\r
- if (tmp == NULL)\r
- PyErr_Clear();\r
- else {\r
- if (PyObject_SetAttrString(v, "lineno", tmp))\r
- PyErr_Clear();\r
- Py_DECREF(tmp);\r
- }\r
- if (filename != NULL) {\r
- tmp = PyString_FromString(filename);\r
- if (tmp == NULL)\r
- PyErr_Clear();\r
- else {\r
- if (PyObject_SetAttrString(v, "filename", tmp))\r
- PyErr_Clear();\r
- Py_DECREF(tmp);\r
- }\r
-\r
- tmp = PyErr_ProgramText(filename, lineno);\r
- if (tmp) {\r
- if (PyObject_SetAttrString(v, "text", tmp))\r
- PyErr_Clear();\r
- Py_DECREF(tmp);\r
- }\r
- }\r
- if (PyObject_SetAttrString(v, "offset", Py_None)) {\r
- PyErr_Clear();\r
- }\r
- if (exc != PyExc_SyntaxError) {\r
- if (!PyObject_HasAttrString(v, "msg")) {\r
- tmp = PyObject_Str(v);\r
- if (tmp) {\r
- if (PyObject_SetAttrString(v, "msg", tmp))\r
- PyErr_Clear();\r
- Py_DECREF(tmp);\r
- } else {\r
- PyErr_Clear();\r
- }\r
- }\r
- if (!PyObject_HasAttrString(v, "print_file_and_line")) {\r
- if (PyObject_SetAttrString(v, "print_file_and_line",\r
- Py_None))\r
- PyErr_Clear();\r
- }\r
- }\r
- PyErr_Restore(exc, v, tb);\r
-}\r
-\r
-/* com_fetch_program_text will attempt to load the line of text that\r
- the exception refers to. If it fails, it will return NULL but will\r
- not set an exception.\r
-\r
- XXX The functionality of this function is quite similar to the\r
- functionality in tb_displayline() in traceback.c.\r
-*/\r
-\r
-PyObject *\r
-PyErr_ProgramText(const char *filename, int lineno)\r
-{\r
- FILE *fp;\r
- int i;\r
- char linebuf[1000];\r
-\r
- if (filename == NULL || *filename == '\0' || lineno <= 0)\r
- return NULL;\r
- fp = fopen(filename, "r" PY_STDIOTEXTMODE);\r
- if (fp == NULL)\r
- return NULL;\r
- for (i = 0; i < lineno; i++) {\r
- char *pLastChar = &linebuf[sizeof(linebuf) - 2];\r
- do {\r
- *pLastChar = '\0';\r
- if (Py_UniversalNewlineFgets(linebuf, sizeof linebuf, fp, NULL) == NULL)\r
- break;\r
- /* fgets read *something*; if it didn't get as\r
- far as pLastChar, it must have found a newline\r
- or hit the end of the file; if pLastChar is \n,\r
- it obviously found a newline; else we haven't\r
- yet seen a newline, so must continue */\r
- } while (*pLastChar != '\0' && *pLastChar != '\n');\r
- }\r
- fclose(fp);\r
- if (i == lineno) {\r
- char *p = linebuf;\r
- while (*p == ' ' || *p == '\t' || *p == '\014')\r
- p++;\r
- return PyString_FromString(p);\r
- }\r
- return NULL;\r
-}\r
-\r
-#ifdef __cplusplus\r
-}\r
-#endif\r
-\r