From b8c21f7ec3a49c7919a2d47e012ce90eca886091 Mon Sep 17 00:00:00 2001 From: Olivier Stasse <olivier.stasse@gmail.com> Date: Tue, 9 Jul 2013 05:53:12 +0200 Subject: [PATCH] Improve output formating. Make possible to read the output from the process lauching the process. --- src/interpreter.cc | 306 +++++++++++++++++++++++---------------------- 1 file changed, 155 insertions(+), 151 deletions(-) diff --git a/src/interpreter.cc b/src/interpreter.cc index 2133b50..ac4fd2c 100644 --- a/src/interpreter.cc +++ b/src/interpreter.cc @@ -23,33 +23,33 @@ std::ofstream dg_debugfile( "/tmp/dynamic-graph-traces.txt", std::ios::trunc&std // Python initialization commands namespace dynamicgraph { - namespace python { - static const std::string pythonPrefix[5] = { - "import traceback\n", - "def display(s): return str(s) if not s is None else None", - "class StdoutCatcher:\n" - " def __init__(self):\n" - " self.data = ''\n" - " def write(self, stuff):\n" - " self.data = self.data + stuff\n" - " def fetch(self):\n" - " s = self.data[:]\n" - " self.data = ''\n" - " return s\n" - "stdout_catcher = StdoutCatcher()\n" - "import sys\n" - "sys.stdout = stdout_catcher" - }; - } +namespace python { +static const std::string pythonPrefix[5] = { + "import traceback\n", + "def display(s): return str(s) if not s is None else None", + "class StdoutCatcher:\n" + " def __init__(self):\n" + " self.data = ''\n" + " def write(self, stuff):\n" + " self.data = self.data + stuff\n" + " def fetch(self):\n" + " s = self.data[:]\n" + " self.data = ''\n" + " return s\n" + "stdout_catcher = StdoutCatcher()\n" + "import sys\n" + "sys.stdout = stdout_catcher" +}; +} } namespace dynamicgraph { - namespace python { +namespace python { bool HandleErr(std::string & err, - PyObject * traceback_format_exception, - PyObject * globals_, - int PythonInputType) + PyObject * traceback_format_exception, + PyObject * globals_, + int PythonInputType) { dgDEBUGIN(15); err=""; @@ -72,7 +72,7 @@ bool HandleErr(std::string & err, std::string stringRes; for (Py_ssize_t i=0; i<size; ++i) stringRes += std::string - (PyString_AsString(PyList_GET_ITEM(pyerr, i))); + (PyString_AsString(PyList_GET_ITEM(pyerr, i))); pyerr = PyString_FromString(stringRes.c_str()); err = PyString_AsString(pyerr); @@ -83,11 +83,11 @@ bool HandleErr(std::string & err, // it is maybe a statement instead of an expression. // Therefore we indicate to re-evaluate the command. if (PyErr_GivenExceptionMatches(ptype, PyExc_SyntaxError) && - (PythonInputType==Py_eval_input)) - { - dgDEBUG(15) << "Detected a syntax error " << std::endl; - lres=false; - } + (PythonInputType==Py_eval_input)) + { + dgDEBUG(15) << "Detected a syntax error " << std::endl; + lres=false; + } else lres=true; @@ -103,149 +103,153 @@ bool HandleErr(std::string & err, out = PyString_AsString(stdout_obj); // Local display for the robot (in debug mode or for the logs) if (out.length()!=0) - { dgDEBUG(15) << std::endl; } + { dgDEBUG(15) << std::endl; } else { dgDEBUG(15) << "No exception." << std::endl; } dgDEBUGOUT(15); return lres; } - Interpreter::Interpreter() - { - // load python dynamic library - // this is silly, but required to be able to import dl module. +Interpreter::Interpreter() +{ + // load python dynamic library + // this is silly, but required to be able to import dl module. #ifndef WIN32 - dlopen(libpython.c_str(), RTLD_LAZY | RTLD_GLOBAL); + dlopen(libpython.c_str(), RTLD_LAZY | RTLD_GLOBAL); #endif - Py_Initialize(); - mainmod_ = PyImport_AddModule("__main__"); - Py_INCREF(mainmod_); - globals_ = PyModule_GetDict(mainmod_); - assert(globals_); - Py_INCREF(globals_); - PyRun_SimpleString(pythonPrefix[0].c_str()); - PyRun_SimpleString(pythonPrefix[1].c_str()); - PyRun_SimpleString(pythonPrefix[2].c_str()); - PyRun_SimpleString(pythonPrefix[3].c_str()); - PyRun_SimpleString(pythonPrefix[4].c_str()); - traceback_format_exception_ = PyDict_GetItemString - (PyModule_GetDict(PyImport_AddModule("traceback")), "format_exception"); - assert(PyCallable_Check(traceback_format_exception_)); - Py_INCREF(traceback_format_exception_); - } + Py_Initialize(); + mainmod_ = PyImport_AddModule("__main__"); + Py_INCREF(mainmod_); + globals_ = PyModule_GetDict(mainmod_); + assert(globals_); + Py_INCREF(globals_); + PyRun_SimpleString(pythonPrefix[0].c_str()); + PyRun_SimpleString(pythonPrefix[1].c_str()); + PyRun_SimpleString(pythonPrefix[2].c_str()); + PyRun_SimpleString(pythonPrefix[3].c_str()); + PyRun_SimpleString(pythonPrefix[4].c_str()); + traceback_format_exception_ = PyDict_GetItemString + (PyModule_GetDict(PyImport_AddModule("traceback")), "format_exception"); + assert(PyCallable_Check(traceback_format_exception_)); + Py_INCREF(traceback_format_exception_); +} - Interpreter::~Interpreter() - { - //Py_DECREF(mainmod_); - //Py_DECREF(globals_); - //Py_DECREF(traceback_format_exception_); - Py_Finalize(); - } +Interpreter::~Interpreter() +{ + //Py_DECREF(mainmod_); + //Py_DECREF(globals_); + //Py_DECREF(traceback_format_exception_); + Py_Finalize(); +} - std::string Interpreter::python( const std::string& command ) - { - std::string lerr(""),lout(""),lres(""); - python(command,lres,lout,lerr); - return lres; - } +std::string Interpreter::python( const std::string& command ) +{ + std::string lerr(""),lout(""),lres(""); + python(command,lres,lout,lerr); + return lres; +} - void Interpreter::python( const std::string& command, std::string& res, - std::string& out, std::string& err) +void Interpreter::python( const std::string& command, std::string& res, + 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 = ""; - 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)) - { - // 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; - } + // 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 - { dgDEBUG(15) << "Result is empty" << std::endl; } - return; + // 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* Interpreter::globals() - { - return globals_; - } + PyObject* stdout_obj = 0; + 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) + 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* pymainContext = 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(); - } - } +PyObject* Interpreter::globals() +{ + return globals_; +} - void Interpreter::runMain( void ) - { - const char * argv [] = { "dg-embedded-pysh" }; - Py_Main(1,const_cast<char**>(argv)); - } +void Interpreter::runPythonFile( std::string filename ) +{ + PyObject* pymainContext = 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(); + } +} - std::string Interpreter::processStream(std::istream& stream, std::ostream& os) - { - char line[10000]; sprintf(line, "%s", "\n"); - std::string command; - std::streamsize maxSize = 10000; +void Interpreter::runMain( void ) +{ + const char * argv [] = { "dg-embedded-pysh" }; + Py_Main(1,const_cast<char**>(argv)); +} + +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 - while (line != std::string("")) { - stream.getline(line, maxSize, '\n'); - command += std::string(line) + std::string("\n"); - }; + while (line != std::string("")) { + stream.getline(line, maxSize, '\n'); + command += std::string(line) + std::string("\n"); + }; #else - os << "dg> "; - stream.getline(line, maxSize, ';'); - command += std::string(line); + os << "dg> "; + stream.getline(line, maxSize, ';'); + command += std::string(line); #endif - return command; - } - } //namespace python + return command; +} +} //namespace python } // namespace dynamicgraph -- GitLab