From 94e54dcce75508c498478761b2e63d0ba9ff9657 Mon Sep 17 00:00:00 2001 From: Vladimir Prus Date: Sat, 27 Oct 2007 09:55:58 +0000 Subject: [PATCH] New Python rule -- 'backtrace'. [SVN r40497] --- historic/jam/src/builtins.c | 26 ++++++++++++++++++++++++++ historic/jam/src/compile.c | 3 +++ historic/jam/src/frames.c | 1 - historic/jam/src/frames.h | 8 ++++++++ historic/jam/src/jam.c | 5 +++++ 5 files changed, 42 insertions(+), 1 deletion(-) diff --git a/historic/jam/src/builtins.c b/historic/jam/src/builtins.c index 4435fac24..802baf4fe 100644 --- a/historic/jam/src/builtins.c +++ b/historic/jam/src/builtins.c @@ -1775,6 +1775,32 @@ bjam_variable(PyObject* self, PyObject* args) return result; } +PyObject* +bjam_backtrace(PyObject* self, PyObject *args) +{ + PyObject *result = PyList_New(0); + struct frame *f = frame_before_python_call; + + for(; f = f->prev;) + { + PyObject *tuple = PyTuple_New(4); + char* file; + int line; + char buf[32]; + get_source_line( f->procedure, &file, &line ); + sprintf( buf, "%d", line ); + + /* PyTuple_SetItem steals reference. */ + PyTuple_SetItem(tuple, 0, PyString_FromString(file)); + PyTuple_SetItem(tuple, 1, PyString_FromString(buf)); + PyTuple_SetItem(tuple, 2, PyString_FromString(f->module->name)); + PyTuple_SetItem(tuple, 3, PyString_FromString(f->rulename)); + + PyList_Append(result, tuple); + Py_DECREF(tuple); + } + return result; +} #endif diff --git a/historic/jam/src/compile.c b/historic/jam/src/compile.c index cd5a91941..4d64bb987 100644 --- a/historic/jam/src/compile.c +++ b/historic/jam/src/compile.c @@ -94,6 +94,8 @@ void backtrace_line( FRAME *frame ); void print_source_line( PARSE* p ); +struct frame *frame_before_python_call; + void frame_init( FRAME* frame ) { frame->prev = 0; @@ -827,6 +829,7 @@ call_python_function(RULE* r, FRAME* frame) PyTuple_SetItem(arguments, i, arg); } + frame_before_python_call = frame; py_result = PyObject_CallObject(r->python_function, arguments); Py_DECREF(arguments); if (py_result != NULL) { diff --git a/historic/jam/src/frames.c b/historic/jam/src/frames.c index c1bc1a03a..80b7197ed 100644 --- a/historic/jam/src/frames.c +++ b/historic/jam/src/frames.c @@ -7,7 +7,6 @@ # include "frames.h" # include "lists.h" - void frame_init( FRAME* frame ) { frame->prev = 0; diff --git a/historic/jam/src/frames.h b/historic/jam/src/frames.h index 4921ac395..535784141 100644 --- a/historic/jam/src/frames.h +++ b/historic/jam/src/frames.h @@ -24,6 +24,14 @@ struct frame char* rulename; }; +/* When call into Python is in progress, this + variable points to the bjam frame that + was current at the moment of call. When the call + completes, the variable is not defined. Further, + if Jam calls Python which calls Jam and so on, + this variable only keeps the most recent Jam frame. */ +extern struct frame *frame_before_python_call; + void frame_init( FRAME* ); /* implemented in compile.c */ void frame_free( FRAME* ); /* implemented in compile.c */ diff --git a/historic/jam/src/jam.c b/historic/jam/src/jam.c index 1533bfe57..d98b099c7 100644 --- a/historic/jam/src/jam.c +++ b/historic/jam/src/jam.c @@ -212,6 +212,9 @@ static void run_unit_tests() extern PyObject* bjam_variable(PyObject* self, PyObject* args); + + extern PyObject* + bjam_backtrace(PyObject* self, PyObject *args); #endif int main( int argc, char **argv, char **arg_environ ) @@ -349,6 +352,8 @@ int main( int argc, char **argv, char **arg_environ ) "Defines a command line action."}, {"variable", bjam_variable, METH_VARARGS, "Obtains a variable from bjam's global module."}, + {"backtrace", bjam_backtrace, METH_VARARGS, + "Returns bjam backtrace from the last call into Python."}, {NULL, NULL, 0, NULL} };