$include_dir="/home/hyper-archives/boost-commit/include"; include("$include_dir/msg-header.inc") ?>
From: ghost_at_[hidden]
Date: 2007-10-27 05:55:59
Author: vladimir_prus
Date: 2007-10-27 05:55:58 EDT (Sat, 27 Oct 2007)
New Revision: 40497
URL: http://svn.boost.org/trac/boost/changeset/40497
Log:
New Python rule -- 'backtrace'.
Text files modified: 
   trunk/tools/jam/src/builtins.c |    26 ++++++++++++++++++++++++++              
   trunk/tools/jam/src/compile.c  |     3 +++                                     
   trunk/tools/jam/src/frames.c   |     1 -                                       
   trunk/tools/jam/src/frames.h   |     8 ++++++++                                
   trunk/tools/jam/src/jam.c      |     5 +++++                                   
   5 files changed, 42 insertions(+), 1 deletions(-)
Modified: trunk/tools/jam/src/builtins.c
==============================================================================
--- trunk/tools/jam/src/builtins.c	(original)
+++ trunk/tools/jam/src/builtins.c	2007-10-27 05:55:58 EDT (Sat, 27 Oct 2007)
@@ -1775,6 +1775,32 @@
     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
 
Modified: trunk/tools/jam/src/compile.c
==============================================================================
--- trunk/tools/jam/src/compile.c	(original)
+++ trunk/tools/jam/src/compile.c	2007-10-27 05:55:58 EDT (Sat, 27 Oct 2007)
@@ -94,6 +94,8 @@
 void print_source_line( PARSE* p );
 
 
+struct frame *frame_before_python_call;
+
 void frame_init( FRAME* frame )
 {
     frame->prev = 0;
@@ -827,6 +829,7 @@
         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) {
Modified: trunk/tools/jam/src/frames.c
==============================================================================
--- trunk/tools/jam/src/frames.c	(original)
+++ trunk/tools/jam/src/frames.c	2007-10-27 05:55:58 EDT (Sat, 27 Oct 2007)
@@ -7,7 +7,6 @@
 # include "frames.h"
 # include "lists.h"
 
-
 void frame_init( FRAME* frame )
 {
     frame->prev = 0;
Modified: trunk/tools/jam/src/frames.h
==============================================================================
--- trunk/tools/jam/src/frames.h	(original)
+++ trunk/tools/jam/src/frames.h	2007-10-27 05:55:58 EDT (Sat, 27 Oct 2007)
@@ -24,6 +24,14 @@
     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 */
 
Modified: trunk/tools/jam/src/jam.c
==============================================================================
--- trunk/tools/jam/src/jam.c	(original)
+++ trunk/tools/jam/src/jam.c	2007-10-27 05:55:58 EDT (Sat, 27 Oct 2007)
@@ -212,6 +212,9 @@
 
     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 @@
                  "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}
             };