comparison Python/traceback.c @ 55900:5dec8a12e455 legacy-trunk

tabbify
author Benjamin Peterson <benjamin@python.org>
date Wed, 09 Sep 2009 11:40:54 +0000
parents 9ef683d41c9b
children 8f6cf39c96dd
comparison
equal deleted inserted replaced
55895:67de42ca0a26 55900:5dec8a12e455
10 #include "traceback.h" 10 #include "traceback.h"
11 11
12 #define OFF(x) offsetof(PyTracebackObject, x) 12 #define OFF(x) offsetof(PyTracebackObject, x)
13 13
14 static PyMemberDef tb_memberlist[] = { 14 static PyMemberDef tb_memberlist[] = {
15 {"tb_next", T_OBJECT, OFF(tb_next), READONLY},
16 {"tb_frame", T_OBJECT, OFF(tb_frame), READONLY},
17 {"tb_lasti", T_INT, OFF(tb_lasti), READONLY}, 15 {"tb_lasti", T_INT, OFF(tb_lasti), READONLY},
18 {"tb_lineno", T_INT, OFF(tb_lineno), READONLY}, 16 {"tb_lineno", T_INT, OFF(tb_lineno), READONLY},
19 {NULL} /* Sentinel */ 17 {NULL} /* Sentinel */
20 }; 18 };
21 19
42 tb_clear(PyTracebackObject *tb) 40 tb_clear(PyTracebackObject *tb)
43 { 41 {
44 Py_CLEAR(tb->tb_next); 42 Py_CLEAR(tb->tb_next);
45 Py_CLEAR(tb->tb_frame); 43 Py_CLEAR(tb->tb_frame);
46 } 44 }
45
46 static PyObject *
47 tb_get_next(PyTracebackObject *tb) {
48 if (tb->tb_next) {
49 Py_INCREF(tb->tb_next);
50 return (PyObject *)tb->tb_next;
51 }
52 Py_RETURN_NONE;
53 }
54
55 static int
56 tb_set_next(PyTracebackObject *tb, PyObject *new, void *context) {
57 if (!new) {
58 PyErr_SetString(PyExc_TypeError, "can't delete tb_next");
59 return -1;
60 }
61 else if (new == Py_None) {
62 new = NULL;
63 }
64 else if (PyTraceBack_Check(new)) {
65 /* Check for cycles in the traceback. */
66 PyTracebackObject *current = (PyTracebackObject *)new;
67 do {
68 if (tb == current) {
69 PyErr_SetString(PyExc_ValueError, "cycle in traceback");
70 return -1;
71 }
72 } while ((current = current->tb_next));
73 Py_INCREF(new);
74 }
75 else {
76 PyErr_SetString(PyExc_TypeError,
77 "tb_next must be an traceback object");
78 return -1;
79 }
80 Py_XDECREF(tb->tb_next);
81 tb->tb_next = (PyTracebackObject *)new;
82 return 0;
83 }
84
85 static PyObject *
86 tb_get_frame(PyTracebackObject *tb) {
87 if (tb->tb_frame) {
88 Py_INCREF(tb->tb_frame);
89 return (PyObject *)tb->tb_frame;
90 }
91 Py_RETURN_NONE;
92 }
93
94 static int
95 tb_set_frame(PyTracebackObject *tb, PyObject *new, void *context) {
96 if (!new) {
97 PyErr_SetString(PyExc_TypeError,
98 "can't delete tb_frame attribute");
99 return -1;
100 }
101 else if (new == Py_None) {
102 new = NULL;
103 }
104 else if (PyFrame_Check(new)) {
105 Py_INCREF(new);
106 }
107 else {
108 PyErr_SetString(PyExc_TypeError,
109 "tb_frame must be a frame object");
110 return -1;
111 }
112 tb->tb_frame = (PyFrameObject *)new;
113 return 0;
114 }
115
116 static PyGetSetDef tb_getset[] = {
117 {"tb_next", (getter)tb_get_next, (setter)tb_set_next, NULL},
118 {"tb_frame", (getter)tb_get_frame, (setter)tb_set_frame, NULL},
119 };
47 120
48 PyTypeObject PyTraceBack_Type = { 121 PyTypeObject PyTraceBack_Type = {
49 PyVarObject_HEAD_INIT(&PyType_Type, 0) 122 PyVarObject_HEAD_INIT(&PyType_Type, 0)
50 "traceback", 123 "traceback",
51 sizeof(PyTracebackObject), 124 sizeof(PyTracebackObject),
73 0, /* tp_weaklistoffset */ 146 0, /* tp_weaklistoffset */
74 0, /* tp_iter */ 147 0, /* tp_iter */
75 0, /* tp_iternext */ 148 0, /* tp_iternext */
76 0, /* tp_methods */ 149 0, /* tp_methods */
77 tb_memberlist, /* tp_members */ 150 tb_memberlist, /* tp_members */
78 0, /* tp_getset */ 151 tb_getset, /* tp_getset */
79 0, /* tp_base */ 152 0, /* tp_base */
80 0, /* tp_dict */ 153 0, /* tp_dict */
81 }; 154 };
82 155
83 static PyTracebackObject * 156 static PyTracebackObject *
243 depth++; 316 depth++;
244 tb1 = tb1->tb_next; 317 tb1 = tb1->tb_next;
245 } 318 }
246 while (tb != NULL && err == 0) { 319 while (tb != NULL && err == 0) {
247 if (depth <= limit) { 320 if (depth <= limit) {
248 err = tb_displayline(f, 321 PyFrameObject *frame = tb->tb_frame;
249 PyString_AsString( 322 char *filename, *name;
250 tb->tb_frame->f_code->co_filename), 323 if (frame) {
251 tb->tb_lineno, 324 filename = PyString_AS_STRING(frame->f_code->co_filename);
252 PyString_AsString(tb->tb_frame->f_code->co_name)); 325 name = PyString_AS_STRING(frame->f_code->co_name);
326 }
327 else {
328 filename = name = "unkown (no frame on traceback)";
329 }
330 err = tb_displayline(f, filename, tb->tb_lineno, name);
253 } 331 }
254 depth--; 332 depth--;
255 tb = tb->tb_next; 333 tb = tb->tb_next;
256 if (err == 0) 334 if (err == 0)
257 err = PyErr_CheckSignals(); 335 err = PyErr_CheckSignals();