| 
									
										
										
										
											1991-02-19 12:39:46 +00:00
										 |  |  | /***********************************************************
 | 
					
						
							| 
									
										
										
										
											1995-01-04 19:12:13 +00:00
										 |  |  | Copyright 1991-1995 by Stichting Mathematisch Centrum, Amsterdam, | 
					
						
							|  |  |  | The Netherlands. | 
					
						
							| 
									
										
										
										
											1991-02-19 12:39:46 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |                         All Rights Reserved | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											1996-10-25 14:44:06 +00:00
										 |  |  | Permission to use, copy, modify, and distribute this software and its | 
					
						
							|  |  |  | documentation for any purpose and without fee is hereby granted, | 
					
						
							| 
									
										
										
										
											1991-02-19 12:39:46 +00:00
										 |  |  | provided that the above copyright notice appear in all copies and that | 
					
						
							| 
									
										
										
										
											1996-10-25 14:44:06 +00:00
										 |  |  | both that copyright notice and this permission notice appear in | 
					
						
							| 
									
										
										
										
											1991-02-19 12:39:46 +00:00
										 |  |  | supporting documentation, and that the names of Stichting Mathematisch | 
					
						
							| 
									
										
										
										
											1996-10-25 14:44:06 +00:00
										 |  |  | Centrum or CWI or Corporation for National Research Initiatives or | 
					
						
							|  |  |  | CNRI not be used in advertising or publicity pertaining to | 
					
						
							|  |  |  | distribution of the software without specific, written prior | 
					
						
							|  |  |  | permission. | 
					
						
							| 
									
										
										
										
											1991-02-19 12:39:46 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											1996-10-25 14:44:06 +00:00
										 |  |  | While CWI is the initial source for this software, a modified version | 
					
						
							|  |  |  | is made available by the Corporation for National Research Initiatives | 
					
						
							|  |  |  | (CNRI) at the Internet address ftp://ftp.python.org.
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | STICHTING MATHEMATISCH CENTRUM AND CNRI DISCLAIM ALL WARRANTIES WITH | 
					
						
							|  |  |  | REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF | 
					
						
							|  |  |  | MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL STICHTING MATHEMATISCH | 
					
						
							|  |  |  | CENTRUM OR CNRI BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL | 
					
						
							|  |  |  | DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR | 
					
						
							|  |  |  | PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER | 
					
						
							|  |  |  | TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR | 
					
						
							|  |  |  | PERFORMANCE OF THIS SOFTWARE. | 
					
						
							| 
									
										
										
										
											1991-02-19 12:39:46 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | ******************************************************************/ | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											1990-12-20 15:06:42 +00:00
										 |  |  | /* Traceback implementation */ | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											1997-04-29 18:33:38 +00:00
										 |  |  | #include "Python.h"
 | 
					
						
							| 
									
										
										
										
											1990-12-20 15:06:42 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | #include "compile.h"
 | 
					
						
							|  |  |  | #include "frameobject.h"
 | 
					
						
							|  |  |  | #include "structmember.h"
 | 
					
						
							| 
									
										
										
										
											1992-02-26 15:17:59 +00:00
										 |  |  | #include "osdefs.h"
 | 
					
						
							| 
									
										
										
										
											1990-12-20 15:06:42 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | typedef struct _tracebackobject { | 
					
						
							| 
									
										
										
										
											1997-04-29 18:33:38 +00:00
										 |  |  | 	PyObject_HEAD | 
					
						
							| 
									
										
										
										
											1990-12-20 15:06:42 +00:00
										 |  |  | 	struct _tracebackobject *tb_next; | 
					
						
							| 
									
										
										
										
											1997-04-29 18:33:38 +00:00
										 |  |  | 	PyFrameObject *tb_frame; | 
					
						
							| 
									
										
										
										
											1990-12-20 15:06:42 +00:00
										 |  |  | 	int tb_lasti; | 
					
						
							|  |  |  | 	int tb_lineno; | 
					
						
							|  |  |  | } tracebackobject; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #define OFF(x) offsetof(tracebackobject, x)
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static struct memberlist tb_memberlist[] = { | 
					
						
							|  |  |  | 	{"tb_next",	T_OBJECT,	OFF(tb_next)}, | 
					
						
							|  |  |  | 	{"tb_frame",	T_OBJECT,	OFF(tb_frame)}, | 
					
						
							|  |  |  | 	{"tb_lasti",	T_INT,		OFF(tb_lasti)}, | 
					
						
							|  |  |  | 	{"tb_lineno",	T_INT,		OFF(tb_lineno)}, | 
					
						
							|  |  |  | 	{NULL}	/* Sentinel */ | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											1997-04-29 18:33:38 +00:00
										 |  |  | static PyObject * | 
					
						
							| 
									
										
										
										
											1990-12-20 15:06:42 +00:00
										 |  |  | tb_getattr(tb, name) | 
					
						
							|  |  |  | 	tracebackobject *tb; | 
					
						
							|  |  |  | 	char *name; | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											1997-04-29 18:33:38 +00:00
										 |  |  | 	return PyMember_Get((char *)tb, tb_memberlist, name); | 
					
						
							| 
									
										
										
										
											1990-12-20 15:06:42 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static void | 
					
						
							|  |  |  | tb_dealloc(tb) | 
					
						
							|  |  |  | 	tracebackobject *tb; | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											1997-04-29 18:33:38 +00:00
										 |  |  | 	Py_XDECREF(tb->tb_next); | 
					
						
							|  |  |  | 	Py_XDECREF(tb->tb_frame); | 
					
						
							|  |  |  | 	PyMem_DEL(tb); | 
					
						
							| 
									
										
										
										
											1990-12-20 15:06:42 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											1995-09-18 21:29:36 +00:00
										 |  |  | #define Tracebacktype PyTraceBack_Type
 | 
					
						
							|  |  |  | #define is_tracebackobject PyTraceBack_Check
 | 
					
						
							| 
									
										
										
										
											1995-07-18 14:51:37 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											1997-04-29 18:33:38 +00:00
										 |  |  | PyTypeObject Tracebacktype = { | 
					
						
							|  |  |  | 	PyObject_HEAD_INIT(&PyType_Type) | 
					
						
							| 
									
										
										
										
											1990-12-20 15:06:42 +00:00
										 |  |  | 	0, | 
					
						
							|  |  |  | 	"traceback", | 
					
						
							|  |  |  | 	sizeof(tracebackobject), | 
					
						
							|  |  |  | 	0, | 
					
						
							| 
									
										
										
										
											1994-08-29 12:09:58 +00:00
										 |  |  | 	(destructor)tb_dealloc, /*tp_dealloc*/ | 
					
						
							| 
									
										
										
										
											1990-12-20 15:06:42 +00:00
										 |  |  | 	0,		/*tp_print*/ | 
					
						
							| 
									
										
										
										
											1994-08-29 12:09:58 +00:00
										 |  |  | 	(getattrfunc)tb_getattr, /*tp_getattr*/ | 
					
						
							| 
									
										
										
										
											1990-12-20 15:06:42 +00:00
										 |  |  | 	0,		/*tp_setattr*/ | 
					
						
							|  |  |  | 	0,		/*tp_compare*/ | 
					
						
							|  |  |  | 	0,		/*tp_repr*/ | 
					
						
							|  |  |  | 	0,		/*tp_as_number*/ | 
					
						
							|  |  |  | 	0,		/*tp_as_sequence*/ | 
					
						
							|  |  |  | 	0,		/*tp_as_mapping*/ | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static tracebackobject * | 
					
						
							|  |  |  | newtracebackobject(next, frame, lasti, lineno) | 
					
						
							|  |  |  | 	tracebackobject *next; | 
					
						
							| 
									
										
										
										
											1997-04-29 18:33:38 +00:00
										 |  |  | 	PyFrameObject *frame; | 
					
						
							| 
									
										
										
										
											1990-12-20 15:06:42 +00:00
										 |  |  | 	int lasti, lineno; | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	tracebackobject *tb; | 
					
						
							|  |  |  | 	if ((next != NULL && !is_tracebackobject(next)) || | 
					
						
							| 
									
										
										
										
											1997-04-29 18:33:38 +00:00
										 |  |  | 			frame == NULL || !PyFrame_Check(frame)) { | 
					
						
							|  |  |  | 		PyErr_BadInternalCall(); | 
					
						
							| 
									
										
										
										
											1990-12-20 15:06:42 +00:00
										 |  |  | 		return NULL; | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											1997-04-29 18:33:38 +00:00
										 |  |  | 	tb = PyObject_NEW(tracebackobject, &Tracebacktype); | 
					
						
							| 
									
										
										
										
											1990-12-20 15:06:42 +00:00
										 |  |  | 	if (tb != NULL) { | 
					
						
							| 
									
										
										
										
											1997-04-29 18:33:38 +00:00
										 |  |  | 		Py_XINCREF(next); | 
					
						
							| 
									
										
										
										
											1990-12-20 15:06:42 +00:00
										 |  |  | 		tb->tb_next = next; | 
					
						
							| 
									
										
										
										
											1997-04-29 18:33:38 +00:00
										 |  |  | 		Py_XINCREF(frame); | 
					
						
							| 
									
										
										
										
											1990-12-20 15:06:42 +00:00
										 |  |  | 		tb->tb_frame = frame; | 
					
						
							|  |  |  | 		tb->tb_lasti = lasti; | 
					
						
							|  |  |  | 		tb->tb_lineno = lineno; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	return tb; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | int | 
					
						
							| 
									
										
										
										
											1997-04-29 18:33:38 +00:00
										 |  |  | PyTraceBack_Here(frame) | 
					
						
							|  |  |  | 	PyFrameObject *frame; | 
					
						
							| 
									
										
										
										
											1990-12-20 15:06:42 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											1997-05-05 20:56:21 +00:00
										 |  |  | 	PyThreadState *tstate = frame->f_tstate; | 
					
						
							|  |  |  | 	tracebackobject *oldtb = (tracebackobject *) tstate->curexc_traceback; | 
					
						
							|  |  |  | 	tracebackobject *tb = newtracebackobject(oldtb, | 
					
						
							|  |  |  | 				frame, frame->f_lasti, frame->f_lineno); | 
					
						
							| 
									
										
										
										
											1990-12-20 15:06:42 +00:00
										 |  |  | 	if (tb == NULL) | 
					
						
							|  |  |  | 		return -1; | 
					
						
							| 
									
										
										
										
											1997-05-05 20:56:21 +00:00
										 |  |  | 	tstate->curexc_traceback = (PyObject *)tb; | 
					
						
							|  |  |  | 	Py_XDECREF(oldtb); | 
					
						
							| 
									
										
										
										
											1990-12-20 15:06:42 +00:00
										 |  |  | 	return 0; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											1997-05-22 22:35:47 +00:00
										 |  |  | static int | 
					
						
							| 
									
										
										
										
											1994-08-29 12:09:58 +00:00
										 |  |  | tb_displayline(f, filename, lineno, name) | 
					
						
							| 
									
										
										
										
											1997-04-29 18:33:38 +00:00
										 |  |  | 	PyObject *f; | 
					
						
							| 
									
										
										
										
											1990-12-20 15:06:42 +00:00
										 |  |  | 	char *filename; | 
					
						
							|  |  |  | 	int lineno; | 
					
						
							| 
									
										
										
										
											1994-08-29 12:09:58 +00:00
										 |  |  | 	char *name; | 
					
						
							| 
									
										
										
										
											1990-12-20 15:06:42 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											1997-05-22 22:35:47 +00:00
										 |  |  | 	int err = 0; | 
					
						
							| 
									
										
										
										
											1990-12-20 15:06:42 +00:00
										 |  |  | 	FILE *xfp; | 
					
						
							| 
									
										
										
										
											1992-02-26 15:17:59 +00:00
										 |  |  | 	char linebuf[1000]; | 
					
						
							| 
									
										
										
										
											1990-12-20 15:06:42 +00:00
										 |  |  | 	int i; | 
					
						
							| 
									
										
										
										
											1997-05-22 22:35:47 +00:00
										 |  |  | 	if (filename == NULL || name == NULL) | 
					
						
							|  |  |  | 		return -1; | 
					
						
							| 
									
										
										
										
											1994-08-29 12:09:58 +00:00
										 |  |  | #ifdef MPW
 | 
					
						
							|  |  |  | 	/* This is needed by MPW's File and Line commands */ | 
					
						
							|  |  |  | #define FMT "  File \"%.900s\"; line %d # in %s\n"
 | 
					
						
							|  |  |  | #else
 | 
					
						
							|  |  |  | 	/* This is needed by Emacs' compile command */ | 
					
						
							|  |  |  | #define FMT "  File \"%.900s\", line %d, in %s\n"
 | 
					
						
							|  |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											1990-12-20 15:06:42 +00:00
										 |  |  | 	xfp = fopen(filename, "r"); | 
					
						
							|  |  |  | 	if (xfp == NULL) { | 
					
						
							| 
									
										
										
										
											1992-02-26 15:17:59 +00:00
										 |  |  | 		/* Search tail of filename in sys.path before giving up */ | 
					
						
							| 
									
										
										
										
											1997-04-29 18:33:38 +00:00
										 |  |  | 		PyObject *path; | 
					
						
							| 
									
										
										
										
											1992-02-26 15:17:59 +00:00
										 |  |  | 		char *tail = strrchr(filename, SEP); | 
					
						
							|  |  |  | 		if (tail == NULL) | 
					
						
							|  |  |  | 			tail = filename; | 
					
						
							|  |  |  | 		else | 
					
						
							|  |  |  | 			tail++; | 
					
						
							| 
									
										
										
										
											1997-04-29 18:33:38 +00:00
										 |  |  | 		path = PySys_GetObject("path"); | 
					
						
							|  |  |  | 		if (path != NULL && PyList_Check(path)) { | 
					
						
							|  |  |  | 			int npath = PyList_Size(path); | 
					
						
							| 
									
										
										
										
											1994-09-29 09:38:04 +00:00
										 |  |  | 			int taillen = strlen(tail); | 
					
						
							| 
									
										
										
										
											1992-02-26 15:17:59 +00:00
										 |  |  | 			char namebuf[MAXPATHLEN+1]; | 
					
						
							|  |  |  | 			for (i = 0; i < npath; i++) { | 
					
						
							| 
									
										
										
										
											1997-04-29 18:33:38 +00:00
										 |  |  | 				PyObject *v = PyList_GetItem(path, i); | 
					
						
							| 
									
										
										
										
											1997-05-22 22:35:47 +00:00
										 |  |  | 				if (v == NULL) { | 
					
						
							|  |  |  | 					PyErr_Clear(); | 
					
						
							|  |  |  | 					break; | 
					
						
							|  |  |  | 				} | 
					
						
							| 
									
										
										
										
											1997-04-29 18:33:38 +00:00
										 |  |  | 				if (PyString_Check(v)) { | 
					
						
							| 
									
										
										
										
											1992-02-26 15:17:59 +00:00
										 |  |  | 					int len; | 
					
						
							| 
									
										
										
										
											1997-04-29 18:33:38 +00:00
										 |  |  | 					len = PyString_Size(v); | 
					
						
							| 
									
										
										
										
											1994-09-29 09:38:04 +00:00
										 |  |  | 					if (len + 1 + taillen >= MAXPATHLEN) | 
					
						
							|  |  |  | 						continue; /* Too long */ | 
					
						
							| 
									
										
										
										
											1997-04-29 18:33:38 +00:00
										 |  |  | 					strcpy(namebuf, PyString_AsString(v)); | 
					
						
							| 
									
										
										
										
											1997-04-11 20:37:35 +00:00
										 |  |  | 					if ((int)strlen(namebuf) != len) | 
					
						
							| 
									
										
										
										
											1994-09-29 09:38:04 +00:00
										 |  |  | 						continue; /* v contains '\0' */ | 
					
						
							| 
									
										
										
										
											1992-02-26 15:17:59 +00:00
										 |  |  | 					if (len > 0 && namebuf[len-1] != SEP) | 
					
						
							|  |  |  | 						namebuf[len++] = SEP; | 
					
						
							|  |  |  | 					strcpy(namebuf+len, tail); | 
					
						
							|  |  |  | 					xfp = fopen(namebuf, "r"); | 
					
						
							|  |  |  | 					if (xfp != NULL) { | 
					
						
							|  |  |  | 						filename = namebuf; | 
					
						
							|  |  |  | 						break; | 
					
						
							|  |  |  | 					} | 
					
						
							|  |  |  | 				} | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											1990-12-20 15:06:42 +00:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											1994-08-29 12:09:58 +00:00
										 |  |  | 	sprintf(linebuf, FMT, filename, lineno, name); | 
					
						
							| 
									
										
										
										
											1997-05-22 22:35:47 +00:00
										 |  |  | 	err = PyFile_WriteString(linebuf, f); | 
					
						
							|  |  |  | 	if (xfp == NULL || err != 0) | 
					
						
							|  |  |  | 		return err; | 
					
						
							| 
									
										
										
										
											1990-12-20 15:06:42 +00:00
										 |  |  | 	for (i = 0; i < lineno; i++) { | 
					
						
							| 
									
										
										
										
											1999-09-18 20:49:39 +00:00
										 |  |  | 		char* pLastChar = &linebuf[sizeof(linebuf)-2]; | 
					
						
							|  |  |  | 		do { | 
					
						
							|  |  |  | 			*pLastChar = '\0'; | 
					
						
							|  |  |  | 			if (fgets(linebuf, sizeof linebuf, xfp) == NULL) | 
					
						
							|  |  |  | 				break; | 
					
						
							|  |  |  | 			/* fgets read *something*; if it didn't get as
 | 
					
						
							|  |  |  | 			   far as pLastChar, it must have found a newline | 
					
						
							|  |  |  | 			   or hit the end of the file;	if pLastChar is \n, | 
					
						
							|  |  |  | 			   it obviously found a newline; else we haven't | 
					
						
							|  |  |  | 			   yet seen a newline, so must continue */ | 
					
						
							|  |  |  | 		} while (*pLastChar != '\0' && *pLastChar != '\n'); | 
					
						
							| 
									
										
										
										
											1990-12-20 15:06:42 +00:00
										 |  |  | 	} | 
					
						
							|  |  |  | 	if (i == lineno) { | 
					
						
							| 
									
										
										
										
											1992-02-26 15:17:59 +00:00
										 |  |  | 		char *p = linebuf; | 
					
						
							| 
									
										
										
										
											1995-07-07 22:45:41 +00:00
										 |  |  | 		while (*p == ' ' || *p == '\t' || *p == '\014') | 
					
						
							| 
									
										
										
										
											1990-12-20 15:06:42 +00:00
										 |  |  | 			p++; | 
					
						
							| 
									
										
										
										
											1997-05-22 22:35:47 +00:00
										 |  |  | 		err = PyFile_WriteString("    ", f); | 
					
						
							|  |  |  | 		if (err == 0) { | 
					
						
							|  |  |  | 			err = PyFile_WriteString(p, f); | 
					
						
							|  |  |  | 			if (err == 0 && strchr(p, '\n') == NULL) | 
					
						
							|  |  |  | 				err = PyFile_WriteString("\n", f); | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											1990-12-20 15:06:42 +00:00
										 |  |  | 	} | 
					
						
							|  |  |  | 	fclose(xfp); | 
					
						
							| 
									
										
										
										
											1997-05-22 22:35:47 +00:00
										 |  |  | 	return err; | 
					
						
							| 
									
										
										
										
											1990-12-20 15:06:42 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											1997-05-22 22:35:47 +00:00
										 |  |  | static int | 
					
						
							| 
									
										
										
										
											1993-12-17 12:09:14 +00:00
										 |  |  | tb_printinternal(tb, f, limit) | 
					
						
							| 
									
										
										
										
											1990-12-20 15:06:42 +00:00
										 |  |  | 	tracebackobject *tb; | 
					
						
							| 
									
										
										
										
											1997-04-29 18:33:38 +00:00
										 |  |  | 	PyObject *f; | 
					
						
							| 
									
										
										
										
											1993-12-17 12:09:14 +00:00
										 |  |  | 	int limit; | 
					
						
							| 
									
										
										
										
											1990-12-20 15:06:42 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											1997-05-22 22:35:47 +00:00
										 |  |  | 	int err = 0; | 
					
						
							| 
									
										
										
										
											1993-12-17 12:09:14 +00:00
										 |  |  | 	int depth = 0; | 
					
						
							|  |  |  | 	tracebackobject *tb1 = tb; | 
					
						
							|  |  |  | 	while (tb1 != NULL) { | 
					
						
							|  |  |  | 		depth++; | 
					
						
							|  |  |  | 		tb1 = tb1->tb_next; | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											1997-05-22 22:35:47 +00:00
										 |  |  | 	while (tb != NULL && err == 0) { | 
					
						
							| 
									
										
										
										
											1997-01-24 04:02:55 +00:00
										 |  |  | 		if (depth <= limit) { | 
					
						
							| 
									
										
										
										
											1997-05-05 20:53:25 +00:00
										 |  |  | 			if (Py_OptimizeFlag) | 
					
						
							|  |  |  | 				tb->tb_lineno = PyCode_Addr2Line( | 
					
						
							|  |  |  | 					tb->tb_frame->f_code, tb->tb_lasti); | 
					
						
							| 
									
										
										
										
											1997-05-22 22:35:47 +00:00
										 |  |  | 			err = tb_displayline(f, | 
					
						
							| 
									
										
										
										
											1997-04-29 18:33:38 +00:00
										 |  |  | 			    PyString_AsString( | 
					
						
							|  |  |  | 				    tb->tb_frame->f_code->co_filename), | 
					
						
							| 
									
										
										
										
											1994-08-29 12:09:58 +00:00
										 |  |  | 			    tb->tb_lineno, | 
					
						
							| 
									
										
										
										
											1997-04-29 18:33:38 +00:00
										 |  |  | 			    PyString_AsString(tb->tb_frame->f_code->co_name)); | 
					
						
							| 
									
										
										
										
											1997-01-24 04:02:55 +00:00
										 |  |  | 		} | 
					
						
							| 
									
										
										
										
											1993-12-17 12:09:14 +00:00
										 |  |  | 		depth--; | 
					
						
							| 
									
										
										
										
											1990-12-20 15:06:42 +00:00
										 |  |  | 		tb = tb->tb_next; | 
					
						
							| 
									
										
										
										
											1997-05-22 22:35:47 +00:00
										 |  |  | 		if (err == 0) | 
					
						
							|  |  |  | 			err = PyErr_CheckSignals(); | 
					
						
							| 
									
										
										
										
											1990-12-20 15:06:42 +00:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											1997-05-22 22:35:47 +00:00
										 |  |  | 	return err; | 
					
						
							| 
									
										
										
										
											1990-12-20 15:06:42 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | int | 
					
						
							| 
									
										
										
										
											1997-04-29 18:33:38 +00:00
										 |  |  | PyTraceBack_Print(v, f) | 
					
						
							|  |  |  | 	PyObject *v; | 
					
						
							|  |  |  | 	PyObject *f; | 
					
						
							| 
									
										
										
										
											1990-12-20 15:06:42 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											1997-05-22 22:35:47 +00:00
										 |  |  | 	int err; | 
					
						
							| 
									
										
										
										
											1997-04-29 18:33:38 +00:00
										 |  |  | 	PyObject *limitv; | 
					
						
							| 
									
										
										
										
											1993-12-17 12:09:14 +00:00
										 |  |  | 	int limit = 1000; | 
					
						
							| 
									
										
										
										
											1990-12-20 15:06:42 +00:00
										 |  |  | 	if (v == NULL) | 
					
						
							|  |  |  | 		return 0; | 
					
						
							|  |  |  | 	if (!is_tracebackobject(v)) { | 
					
						
							| 
									
										
										
										
											1997-04-29 18:33:38 +00:00
										 |  |  | 		PyErr_BadInternalCall(); | 
					
						
							| 
									
										
										
										
											1990-12-20 15:06:42 +00:00
										 |  |  | 		return -1; | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											1997-04-29 18:33:38 +00:00
										 |  |  | 	limitv = PySys_GetObject("tracebacklimit"); | 
					
						
							|  |  |  | 	if (limitv && PyInt_Check(limitv)) { | 
					
						
							|  |  |  | 		limit = PyInt_AsLong(limitv); | 
					
						
							| 
									
										
										
										
											1993-12-17 12:09:14 +00:00
										 |  |  | 		if (limit <= 0) | 
					
						
							|  |  |  | 			return 0; | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											1997-05-22 22:35:47 +00:00
										 |  |  | 	err = PyFile_WriteString("Traceback (innermost last):\n", f); | 
					
						
							|  |  |  | 	if (!err) | 
					
						
							|  |  |  | 		err = tb_printinternal((tracebackobject *)v, f, limit); | 
					
						
							|  |  |  | 	return err; | 
					
						
							| 
									
										
										
										
											1990-12-20 15:06:42 +00:00
										 |  |  | } |