Commit 1d505bed authored by Francois Keith's avatar Francois Keith
Browse files

Add a method allowing to execute a file and retrived the error (if any) via a string.

parent 49bf3e82
......@@ -45,6 +45,7 @@ ADD_REQUIRED_DEPENDENCY("dynamic-graph >= 2.5.5-6")
PKG_CONFIG_APPEND_LIBS("dynamic-graph-python")
# Search for Boost.
SET(BOOST_COMPONENTS python filesystem system thread program_options unit_test_framework)
SEARCH_FOR_BOOST()
# Make sure Boost.Filesystem v2 is used.
......
......@@ -51,6 +51,7 @@ namespace dynamicgraph {
/// \brief Method to exectue a python script.
/// \param filename the filename
void runPythonFile( std::string filename );
void runPythonFile( std::string filename, std::string& err);
void runMain( void );
/// \brief Process input stream to send relevant blocks to python
......
......@@ -19,6 +19,13 @@
#include "dynamic-graph/python/interpreter.hh"
#include "link-to-python.hh"
#include <boost/python/errors.hpp>
#include <boost/python/object.hpp>
#include <boost/python/handle.hpp>
#include <boost/python/extract.hpp>
using namespace boost::python;
std::ofstream dg_debugfile( "/tmp/dynamic-graph-traces.txt", std::ios::trunc&std::ios::out );
// Python initialization commands
......@@ -136,6 +143,8 @@ Interpreter::Interpreter()
PyRun_SimpleString(pythonPrefix[2].c_str());
PyRun_SimpleString(pythonPrefix[3].c_str());
PyRun_SimpleString(pythonPrefix[4].c_str());
PyRun_SimpleString("import linecache");
traceback_format_exception_ = PyDict_GetItemString
(PyModule_GetDict(PyImport_AddModule("traceback")), "format_exception");
assert(PyCallable_Check(traceback_format_exception_));
......@@ -229,13 +238,64 @@ PyObject* Interpreter::globals()
void Interpreter::runPythonFile( std::string filename )
{
std::string err = "";
runPythonFile(filename, err);
}
void Interpreter::runPythonFile( std::string filename, std::string& err)
{
err = "";
PyObject* pymainContext = globals_;
PyObject* run = PyRun_FileExFlags(fopen( filename.c_str(),"r" ), filename.c_str(),
Py_file_input, pymainContext,pymainContext, true, NULL);
if (PyErr_Occurred())
{
std::cout << "Error occures..." << std::endl;
PyErr_Print();
PyObject *ptype, *pvalue, *ptraceback;
PyErr_Fetch(&ptype, &pvalue, &ptraceback);
handle<> hTraceback(ptraceback);
object traceback(hTraceback);
//Extract error message
std::string strErrorMessage = extract<std::string>(pvalue);
std::ostringstream errstream;
//TODO does not work for now for a single command.
do
{
//Extract line number (top entry of call stack)
// if you want to extract another levels of call stack
// also process traceback.attr("tb_next") recurently
long lineno = extract<long> (traceback.attr("tb_lineno"));
std::string filename = extract<std::string>
(traceback.attr("tb_frame").attr("f_code").attr("co_filename"));
std::string funcname = extract<std::string>
(traceback.attr("tb_frame").attr("f_code").attr("co_name"));
errstream << " File \"" << filename <<"\", line "
<< lineno << ", in "<< funcname << std::endl;
// get the corresponding line.
std::ostringstream cmd;
cmd << "linecache.getline('"<<filename<<"', "<<lineno <<")";
PyObject* line_obj = PyRun_String(cmd.str().c_str(),
Py_eval_input, globals_, globals_);
std::string line = PyString_AsString(line_obj);
Py_DecRef(line_obj);
// remove the spaces at the beginning of the line.
size_t index = line.find_first_not_of (" \t");
errstream << " " << line.substr(index, line.size()-index);
// go to the next line.
traceback = traceback.attr("tb_next");
}
while (traceback);
// recreate the error message
errstream << strErrorMessage << std::endl;
err =errstream.str();
std::cerr << err;
}
Py_DecRef(run);
}
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment