diff Python/traceback.c @ 86:a6934380c6e7 legacy-trunk

"Compiling" version
author Guido van Rossum <guido@python.org>
date Thu, 20 Dec 1990 15:06:42 +0000
parents
children 853b736a6a9e
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Python/traceback.c	Thu Dec 20 15:06:42 1990 +0000
@@ -0,0 +1,193 @@
+/* Traceback implementation */
+
+#include "allobjects.h"
+
+#include "compile.h"
+#include "frameobject.h"
+#include "traceback.h"
+#include "structmember.h"
+
+typedef struct _tracebackobject {
+	OB_HEAD
+	struct _tracebackobject *tb_next;
+	frameobject *tb_frame;
+	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 */
+};
+
+static object *
+tb_getattr(tb, name)
+	tracebackobject *tb;
+	char *name;
+{
+	return getmember((char *)tb, tb_memberlist, name);
+}
+
+static void
+tb_dealloc(tb)
+	tracebackobject *tb;
+{
+	XDECREF(tb->tb_next);
+	XDECREF(tb->tb_frame);
+	DEL(tb);
+}
+
+static typeobject Tracebacktype = {
+	OB_HEAD_INIT(&Typetype)
+	0,
+	"traceback",
+	sizeof(tracebackobject),
+	0,
+	tb_dealloc,	/*tp_dealloc*/
+	0,		/*tp_print*/
+	tb_getattr,	/*tp_getattr*/
+	0,		/*tp_setattr*/
+	0,		/*tp_compare*/
+	0,		/*tp_repr*/
+	0,		/*tp_as_number*/
+	0,		/*tp_as_sequence*/
+	0,		/*tp_as_mapping*/
+};
+
+#define is_tracebackobject(v) ((v)->ob_type == &Tracebacktype)
+
+static tracebackobject *
+newtracebackobject(next, frame, lasti, lineno)
+	tracebackobject *next;
+	frameobject *frame;
+	int lasti, lineno;
+{
+	tracebackobject *tb;
+	if ((next != NULL && !is_tracebackobject(next)) ||
+			frame == NULL || !is_frameobject(frame)) {
+		err_badcall();
+		return NULL;
+	}
+	tb = NEWOBJ(tracebackobject, &Tracebacktype);
+	if (tb != NULL) {
+		XINCREF(next);
+		tb->tb_next = next;
+		XINCREF(frame);
+		tb->tb_frame = frame;
+		tb->tb_lasti = lasti;
+		tb->tb_lineno = lineno;
+	}
+	return tb;
+}
+
+static tracebackobject *tb_current = NULL;
+
+int
+tb_here(frame, lasti, lineno)
+	frameobject *frame;
+	int lasti;
+	int lineno;
+{
+	tracebackobject *tb;
+	tb = newtracebackobject(tb_current, frame, lasti, lineno);
+	if (tb == NULL)
+		return -1;
+	XDECREF(tb_current);
+	tb_current = tb;
+	return 0;
+}
+
+object *
+tb_fetch()
+{
+	object *v;
+	v = (object *)tb_current;
+	tb_current = NULL;
+	return v;
+}
+
+int
+tb_store(v)
+	object *v;
+{
+	if (v != NULL && !is_tracebackobject(v)) {
+		err_badcall();
+		return -1;
+	}
+	XDECREF(tb_current);
+	XINCREF(v);
+	tb_current = (tracebackobject *)v;
+	return 0;
+}
+
+static void
+tb_displayline(fp, filename, lineno)
+	FILE *fp;
+	char *filename;
+	int lineno;
+{
+	FILE *xfp;
+	char buf[1000];
+	int i;
+	if (filename[0] == '<' && filename[strlen(filename)-1] == '>')
+		return;
+	xfp = fopen(filename, "r");
+	if (xfp == NULL) {
+		fprintf(fp, "    (cannot open \"%s\")\n", filename);
+		return;
+	}
+	for (i = 0; i < lineno; i++) {
+		if (fgets(buf, sizeof buf, xfp) == NULL)
+			break;
+	}
+	if (i == lineno) {
+		char *p = buf;
+		while (*p == ' ' || *p == '\t')
+			p++;
+		fprintf(fp, "    %s", p);
+		if (strchr(p, '\n') == NULL)
+			fprintf(fp, "\n");
+	}
+	fclose(xfp);
+}
+
+static void
+tb_printinternal(tb, fp)
+	tracebackobject *tb;
+	FILE *fp;
+{
+	while (tb != NULL) {
+		if (intrcheck()) {
+			fprintf(fp, "[interrupted]\n");
+			break;
+		}
+		fprintf(fp, "  File \"");
+		printobject(tb->tb_frame->f_code->co_filename, fp, PRINT_RAW);
+		fprintf(fp, "\", line %d\n", tb->tb_lineno);
+		tb_displayline(fp,
+		     getstringvalue(tb->tb_frame->f_code->co_filename),
+							tb->tb_lineno);
+		tb = tb->tb_next;
+	}
+}
+
+int
+tb_print(v, fp)
+	object *v;
+	FILE *fp;
+{
+	if (v == NULL)
+		return 0;
+	if (!is_tracebackobject(v)) {
+		err_badcall();
+		return -1;
+	}
+	sysset("last_traceback", v);
+	tb_printinternal((tracebackobject *)v, fp);
+	return 0;
+}