Newer
Older
// -*- mode: c++ -*-
// Copyright 2011, Florent Lamiraux, CNRS.
//
// This file is part of dynamic-graph-python.
// dynamic-graph is free software: you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public License
// as published by the Free Software Foundation, either version 3 of
// the License, or (at your option) any later version.
//
// dynamic-graph is distributed in the hope that it will be useful, but
// WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// General Lesser Public License for more details. You should have
// received a copy of the GNU Lesser General Public License along with
// dynamic-graph. If not, see <http://www.gnu.org/licenses/>.
#include <iostream>
#include "dynamic-graph/python/interpreter.hh"
#include "link-to-python.hh"
// Python initialization commands
namespace dynamicgraph {
namespace python {
Duong Dang
committed
"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"
};
}
}
using dynamicgraph::python::Interpreter;
using dynamicgraph::python::libpython;
Interpreter::Interpreter()
{
// load python dynamic library
// this is silly, but required to be able to import dl module.
dlopen(libpython.c_str(), RTLD_LAZY | RTLD_GLOBAL);
#else
LoadLibrary(libpython.c_str());
#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());
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();
}
std::string Interpreter::python( const std::string& command )
{
PyObject* result = PyRun_String(command.c_str(), Py_eval_input, globals_,
Duong Dang
committed
globals_);
if (!result) {
PyErr_Clear();
result = PyRun_String(command.c_str(), Py_single_input, globals_,
Duong Dang
committed
globals_);
}
if (result == NULL) {
if (PyErr_Occurred()) {
PyObject *ptype, *pvalue, *ptraceback;
PyErr_Fetch(&ptype, &pvalue, &ptraceback);
if (ptraceback == NULL) {
Duong Dang
committed
ptraceback = Py_None;
}
PyObject* args = PyTuple_New(3);
PyTuple_SET_ITEM(args, 0, ptype);
PyTuple_SET_ITEM(args, 1, pvalue);
PyTuple_SET_ITEM(args, 2, ptraceback);
result = PyObject_CallObject(traceback_format_exception_, args);
assert(PyList_Check(result));
unsigned int size = PyList_GET_SIZE(result);
std::string stringRes;
for (unsigned int i=0; i<size; i++) {
Duong Dang
committed
stringRes += std::string(PyString_AsString(PyList_GET_ITEM(result, i)));
}
result = PyString_FromString(stringRes.c_str());
PyErr_Clear();
} else {
std::cout << "Result is NULL but no error occurred." << std::endl;
}
} else {
result = PyObject_Repr(result);
}
std::string value = PyString_AsString(result);
return value;
}
Duong Dang
committed
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
void Interpreter::python( const std::string& command, std::string& res,
std::string& out, std::string& err)
{
res = "";
out = "";
err = "";
PyObject* result = PyRun_String(command.c_str(), Py_eval_input, globals_,
globals_);
if (!result) {
PyErr_Clear();
result = PyRun_String(command.c_str(), Py_single_input, globals_,
globals_);
}
if (result == NULL) {
if (PyErr_Occurred()) {
PyObject *ptype, *pvalue, *ptraceback, *pyerr;
PyErr_Fetch(&ptype, &pvalue, &ptraceback);
if (ptraceback == NULL) {
ptraceback = Py_None;
}
PyObject* args = PyTuple_New(3);
PyTuple_SET_ITEM(args, 0, ptype);
PyTuple_SET_ITEM(args, 1, pvalue);
PyTuple_SET_ITEM(args, 2, ptraceback);
pyerr = PyObject_CallObject(traceback_format_exception_, args);
assert(PyList_Check(pyerr));
unsigned int size = PyList_GET_SIZE(pyerr);
std::string stringRes;
for (unsigned int i=0; i<size; i++) {
stringRes += std::string(PyString_AsString(PyList_GET_ITEM(pyerr, i)));
}
pyerr = PyString_FromString(stringRes.c_str());
err = PyString_AsString(pyerr);
PyErr_Clear();
} else {
std::cout << "Result is NULL but no error occurred." << std::endl;
}
}
PyObject* stdout_obj = PyRun_String("stdout_catcher.fetch()",
Py_eval_input, globals_,
globals_);
out = PyString_AsString(stdout_obj);
std::cout << out;
result = PyObject_Repr(result);
res = PyString_AsString(result);
return;
}
PyObject* Interpreter::globals()
{
return globals_;
}
void Interpreter::runPythonFile( std::string filename )
{

Nicolas Mansard
committed
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();
}
}
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");
};
#else
os << "dg> ";
stream.getline(line, maxSize, ';');
command += std::string(line);
#endif
return command;
}