Skip to content
Snippets Groups Projects
Commit b8c21f7e authored by olivier stasse's avatar olivier stasse
Browse files

Improve output formating.

Make possible to read the output from the process lauching the process.
parent 9b6f6475
No related branches found
No related tags found
No related merge requests found
...@@ -23,33 +23,33 @@ std::ofstream dg_debugfile( "/tmp/dynamic-graph-traces.txt", std::ios::trunc&std ...@@ -23,33 +23,33 @@ std::ofstream dg_debugfile( "/tmp/dynamic-graph-traces.txt", std::ios::trunc&std
// Python initialization commands // Python initialization commands
namespace dynamicgraph { namespace dynamicgraph {
namespace python { namespace python {
static const std::string pythonPrefix[5] = { static const std::string pythonPrefix[5] = {
"import traceback\n", "import traceback\n",
"def display(s): return str(s) if not s is None else None", "def display(s): return str(s) if not s is None else None",
"class StdoutCatcher:\n" "class StdoutCatcher:\n"
" def __init__(self):\n" " def __init__(self):\n"
" self.data = ''\n" " self.data = ''\n"
" def write(self, stuff):\n" " def write(self, stuff):\n"
" self.data = self.data + stuff\n" " self.data = self.data + stuff\n"
" def fetch(self):\n" " def fetch(self):\n"
" s = self.data[:]\n" " s = self.data[:]\n"
" self.data = ''\n" " self.data = ''\n"
" return s\n" " return s\n"
"stdout_catcher = StdoutCatcher()\n" "stdout_catcher = StdoutCatcher()\n"
"import sys\n" "import sys\n"
"sys.stdout = stdout_catcher" "sys.stdout = stdout_catcher"
}; };
} }
} }
namespace dynamicgraph { namespace dynamicgraph {
namespace python { namespace python {
bool HandleErr(std::string & err, bool HandleErr(std::string & err,
PyObject * traceback_format_exception, PyObject * traceback_format_exception,
PyObject * globals_, PyObject * globals_,
int PythonInputType) int PythonInputType)
{ {
dgDEBUGIN(15); dgDEBUGIN(15);
err=""; err="";
...@@ -72,7 +72,7 @@ bool HandleErr(std::string & err, ...@@ -72,7 +72,7 @@ bool HandleErr(std::string & err,
std::string stringRes; std::string stringRes;
for (Py_ssize_t i=0; i<size; ++i) for (Py_ssize_t i=0; i<size; ++i)
stringRes += std::string stringRes += std::string
(PyString_AsString(PyList_GET_ITEM(pyerr, i))); (PyString_AsString(PyList_GET_ITEM(pyerr, i)));
pyerr = PyString_FromString(stringRes.c_str()); pyerr = PyString_FromString(stringRes.c_str());
err = PyString_AsString(pyerr); err = PyString_AsString(pyerr);
...@@ -83,11 +83,11 @@ bool HandleErr(std::string & err, ...@@ -83,11 +83,11 @@ bool HandleErr(std::string & err,
// it is maybe a statement instead of an expression. // it is maybe a statement instead of an expression.
// Therefore we indicate to re-evaluate the command. // Therefore we indicate to re-evaluate the command.
if (PyErr_GivenExceptionMatches(ptype, PyExc_SyntaxError) && if (PyErr_GivenExceptionMatches(ptype, PyExc_SyntaxError) &&
(PythonInputType==Py_eval_input)) (PythonInputType==Py_eval_input))
{ {
dgDEBUG(15) << "Detected a syntax error " << std::endl; dgDEBUG(15) << "Detected a syntax error " << std::endl;
lres=false; lres=false;
} }
else else
lres=true; lres=true;
...@@ -103,149 +103,153 @@ bool HandleErr(std::string & err, ...@@ -103,149 +103,153 @@ bool HandleErr(std::string & err,
out = PyString_AsString(stdout_obj); out = PyString_AsString(stdout_obj);
// Local display for the robot (in debug mode or for the logs) // Local display for the robot (in debug mode or for the logs)
if (out.length()!=0) if (out.length()!=0)
{ dgDEBUG(15) << std::endl; } { dgDEBUG(15) << std::endl; }
else { dgDEBUG(15) << "No exception." << std::endl; } else { dgDEBUG(15) << "No exception." << std::endl; }
dgDEBUGOUT(15); dgDEBUGOUT(15);
return lres; return lres;
} }
Interpreter::Interpreter() Interpreter::Interpreter()
{ {
// load python dynamic library // load python dynamic library
// this is silly, but required to be able to import dl module. // this is silly, but required to be able to import dl module.
#ifndef WIN32 #ifndef WIN32
dlopen(libpython.c_str(), RTLD_LAZY | RTLD_GLOBAL); dlopen(libpython.c_str(), RTLD_LAZY | RTLD_GLOBAL);
#endif #endif
Py_Initialize(); Py_Initialize();
mainmod_ = PyImport_AddModule("__main__"); mainmod_ = PyImport_AddModule("__main__");
Py_INCREF(mainmod_); Py_INCREF(mainmod_);
globals_ = PyModule_GetDict(mainmod_); globals_ = PyModule_GetDict(mainmod_);
assert(globals_); assert(globals_);
Py_INCREF(globals_); Py_INCREF(globals_);
PyRun_SimpleString(pythonPrefix[0].c_str()); PyRun_SimpleString(pythonPrefix[0].c_str());
PyRun_SimpleString(pythonPrefix[1].c_str()); PyRun_SimpleString(pythonPrefix[1].c_str());
PyRun_SimpleString(pythonPrefix[2].c_str()); PyRun_SimpleString(pythonPrefix[2].c_str());
PyRun_SimpleString(pythonPrefix[3].c_str()); PyRun_SimpleString(pythonPrefix[3].c_str());
PyRun_SimpleString(pythonPrefix[4].c_str()); PyRun_SimpleString(pythonPrefix[4].c_str());
traceback_format_exception_ = PyDict_GetItemString traceback_format_exception_ = PyDict_GetItemString
(PyModule_GetDict(PyImport_AddModule("traceback")), "format_exception"); (PyModule_GetDict(PyImport_AddModule("traceback")), "format_exception");
assert(PyCallable_Check(traceback_format_exception_)); assert(PyCallable_Check(traceback_format_exception_));
Py_INCREF(traceback_format_exception_); Py_INCREF(traceback_format_exception_);
} }
Interpreter::~Interpreter() Interpreter::~Interpreter()
{ {
//Py_DECREF(mainmod_); //Py_DECREF(mainmod_);
//Py_DECREF(globals_); //Py_DECREF(globals_);
//Py_DECREF(traceback_format_exception_); //Py_DECREF(traceback_format_exception_);
Py_Finalize(); Py_Finalize();
} }
std::string Interpreter::python( const std::string& command ) std::string Interpreter::python( const std::string& command )
{ {
std::string lerr(""),lout(""),lres(""); std::string lerr(""),lout(""),lres("");
python(command,lres,lout,lerr); python(command,lres,lout,lerr);
return lres; return lres;
} }
void Interpreter::python( const std::string& command, std::string& res, void Interpreter::python( const std::string& command, std::string& res,
std::string& out, std::string& err) std::string& out, std::string& err)
{
res = "";
out = "";
err = "";
std::cout << command.c_str() << std::endl;
PyObject* result = PyRun_String(command.c_str(), Py_eval_input, globals_,
globals_);
// Check if the result is null.
if (!result) {
// Test if this is a syntax error (due to the evaluation of an expression)
// else just output the problem.
if (!HandleErr(err,
traceback_format_exception_, globals_,
Py_eval_input))
{ {
res = ""; // If this is a statement, re-parse the command.
out = ""; result = PyRun_String(command.c_str(), Py_single_input, globals_, globals_);
err = "";
// If there is still an error build the appropriate err string.
std::cout << command.c_str() << std::endl; if (result == NULL)
PyObject* result = PyRun_String(command.c_str(), Py_eval_input, globals_, HandleErr(err,
globals_); traceback_format_exception_, globals_,
// Check if the result is null. Py_single_input);
if (!result) {
// Test if this is a syntax error (due to the evaluation of an expression)
// else just output the problem.
if (!HandleErr(err,
traceback_format_exception_, globals_,
Py_eval_input))
{
// If this is a statement, re-parse the command.
result = PyRun_String(command.c_str(), Py_single_input, globals_, globals_);
// If there is still an error build the appropriate err string.
if (result == NULL)
HandleErr(err,
traceback_format_exception_, globals_,
Py_single_input);
else
// If there is no error, make sure that the previous error message is erased.
err="";
}
else
{ dgDEBUG(15) << "Do not try a second time." << std::endl; }
}
PyObject* stdout_obj = PyRun_String("stdout_catcher.fetch()",
Py_eval_input, globals_,
globals_);
out = PyString_AsString(stdout_obj);
// Local display for the robot (in debug mode or for the logs)
std::cout << out;
result = PyObject_Repr(result);
// If python cannot build a string representation of result
// then results is equal to NULL. This will trigger a SEGV
if (result!=NULL)
{
dgDEBUG(15) << "For command :" << command << std::endl;
res = PyString_AsString(result);
dgDEBUG(15) << "Result is: " << res <<std::endl;
dgDEBUG(15) << "Out is: " << out <<std::endl;
dgDEBUG(15) << "Err is :" << err << std::endl;
}
else else
{ dgDEBUG(15) << "Result is empty" << std::endl; } // If there is no error, make sure that the previous error message is erased.
return; err="";
} }
else
{ dgDEBUG(15) << "Do not try a second time." << std::endl; }
}
PyObject* Interpreter::globals() PyObject* stdout_obj = 0;
{ stdout_obj = PyRun_String("stdout_catcher.fetch()",
return globals_; Py_eval_input, globals_,
} globals_);
out = PyString_AsString(stdout_obj);
// Local display for the robot (in debug mode or for the logs)
if (out.size()!=0)
std::cout << "Output:" << out << std::endl;
if (err.size()!=0)
std::cout << "Error:" << err << std::endl;
result = PyObject_Repr(result);
// If python cannot build a string representation of result
// then results is equal to NULL. This will trigger a SEGV
if (result!=NULL)
{
dgDEBUG(15) << "For command :" << command << std::endl;
res = PyString_AsString(result);
dgDEBUG(15) << "Result is: " << res <<std::endl;
dgDEBUG(15) << "Out is: " << out <<std::endl;
dgDEBUG(15) << "Err is :" << err << std::endl;
}
else
{ dgDEBUG(15) << "Result is empty" << std::endl; }
return;
}
void Interpreter::runPythonFile( std::string filename ) PyObject* Interpreter::globals()
{ {
PyObject* pymainContext = globals_; return globals_;
PyRun_File(fopen( filename.c_str(),"r" ), filename.c_str(), }
Py_file_input, pymainContext,pymainContext);
if (PyErr_Occurred())
{
std::cout << "Error occures..." << std::endl;
PyErr_Print();
}
}
void Interpreter::runMain( void ) void Interpreter::runPythonFile( std::string filename )
{ {
const char * argv [] = { "dg-embedded-pysh" }; PyObject* pymainContext = globals_;
Py_Main(1,const_cast<char**>(argv)); PyRun_File(fopen( filename.c_str(),"r" ), filename.c_str(),
} Py_file_input, pymainContext,pymainContext);
if (PyErr_Occurred())
{
std::cout << "Error occures..." << std::endl;
PyErr_Print();
}
}
std::string Interpreter::processStream(std::istream& stream, std::ostream& os) void Interpreter::runMain( void )
{ {
char line[10000]; sprintf(line, "%s", "\n"); const char * argv [] = { "dg-embedded-pysh" };
std::string command; Py_Main(1,const_cast<char**>(argv));
std::streamsize maxSize = 10000; }
std::string Interpreter::processStream(std::istream& stream, std::ostream& os)
{
char line[10000]; sprintf(line, "%s", "\n");
std::string command;
std::streamsize maxSize = 10000;
#if 0 #if 0
while (line != std::string("")) { while (line != std::string("")) {
stream.getline(line, maxSize, '\n'); stream.getline(line, maxSize, '\n');
command += std::string(line) + std::string("\n"); command += std::string(line) + std::string("\n");
}; };
#else #else
os << "dg> "; os << "dg> ";
stream.getline(line, maxSize, ';'); stream.getline(line, maxSize, ';');
command += std::string(line); command += std::string(line);
#endif #endif
return command; return command;
} }
} //namespace python } //namespace python
} // namespace dynamicgraph } // namespace dynamicgraph
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment