Unverified Commit 0b7862d6 authored by Joseph Mirabel's avatar Joseph Mirabel Committed by GitHub
Browse files

Merge pull request #40 from nim65s/devel

fix #39
parents 63d0a6ef 9a27fc49
Pipeline #7538 failed with stage
in 26 minutes and 21 seconds
...@@ -178,12 +178,12 @@ __attribute__((unused)) static struct PyModuleDef dynamicGraphModuleDef = { ...@@ -178,12 +178,12 @@ __attribute__((unused)) static struct PyModuleDef dynamicGraphModuleDef = {
NULL, NULL,
NULL}; NULL};
#define GETSTATE(m) ((struct dynamicgraph::python::module_state*)PyModule_GetState(m)) #define GETSTATE(m) ((struct dynamicgraph::python::module_state*)PyModule_GetState(m))
#define DGPYERROR GETSTATE(PyState_FindModule(&dynamicGraphModuleDef))->dgpyError #define DGPYERROR(m) GETSTATE(m)->dgpyError
#define INITERROR return NULL #define INITERROR return NULL
#else #else
__attribute__((unused)) static struct module_state _state; __attribute__((unused)) static struct module_state _state;
#define GETSTATE(m) (&dynamicgraph::python::_state) #define GETSTATE(m) (&dynamicgraph::python::_state)
#define DGPYERROR dynamicgraph::python::_state.dgpyError #define DGPYERROR(m) dynamicgraph::python::dgpyError
#define INITERROR return #define INITERROR return
#endif #endif
......
...@@ -7,19 +7,19 @@ ...@@ -7,19 +7,19 @@
/// \brief Catch all exceptions which may be sent when C++ code is /// \brief Catch all exceptions which may be sent when C++ code is
/// called. /// called.
#define CATCH_ALL_EXCEPTIONS() \ #define CATCH_ALL_EXCEPTIONS(m) \
catch (const std::exception& exc) { \ catch (const std::exception& exc) { \
PyErr_SetString(DGPYERROR, exc.what()); \ PyErr_SetString(DGPYERROR(m), exc.what()); \
return NULL; \ return NULL; \
} \ } \
catch (const char* s) { \ catch (const char* s) { \
PyErr_SetString(DGPYERROR, s); \ PyErr_SetString(DGPYERROR(m), s); \
return NULL; \ return NULL; \
} \ } \
catch (...) { \ catch (...) { \
PyErr_SetString(DGPYERROR, "Unknown exception"); \ PyErr_SetString(DGPYERROR(m), "Unknown exception"); \
return NULL; \ return NULL; \
} \ } \
struct e_n_d__w_i_t_h__s_e_m_i_c_o_l_o_n struct e_n_d__w_i_t_h__s_e_m_i_c_o_l_o_n
#endif //! DYNAMIC_GRAPH_PYTHON_EXCEPTION #endif //! DYNAMIC_GRAPH_PYTHON_EXCEPTION
...@@ -21,11 +21,21 @@ typedef boost::shared_ptr<std::ofstream> ofstreamShrPtr; ...@@ -21,11 +21,21 @@ typedef boost::shared_ptr<std::ofstream> ofstreamShrPtr;
namespace dynamicgraph { namespace dynamicgraph {
namespace python { namespace python {
#if PY_MAJOR_VERSION == 2
extern PyObject* dgpyError;
# endif
namespace debug { namespace debug {
std::map<std::string, ofstreamShrPtr> mapOfFiles_; std::map<std::string, ofstreamShrPtr> mapOfFiles_;
PyObject* addLoggerFileOutputStream(PyObject* /*self*/, PyObject* args) { PyObject* addLoggerFileOutputStream(
#if PY_MAJOR_VERSION >= 3
PyObject* m, PyObject* args
#else
PyObject*, PyObject* args
#endif
) {
char* filename; char* filename;
if (!PyArg_ParseTuple(args, "s", &filename)) return NULL; if (!PyArg_ParseTuple(args, "s", &filename)) return NULL;
std::string sfilename(filename); std::string sfilename(filename);
...@@ -38,49 +48,79 @@ PyObject* addLoggerFileOutputStream(PyObject* /*self*/, PyObject* args) { ...@@ -38,49 +48,79 @@ PyObject* addLoggerFileOutputStream(PyObject* /*self*/, PyObject* args) {
dgRTLOG() << "Added " << filename << " as an output stream \n"; dgRTLOG() << "Added " << filename << " as an output stream \n";
mapOfFiles_[sfilename] = ofs_shrptr; mapOfFiles_[sfilename] = ofs_shrptr;
} }
CATCH_ALL_EXCEPTIONS(); CATCH_ALL_EXCEPTIONS(m);
return Py_BuildValue(""); return Py_BuildValue("");
} }
PyObject* closeLoggerFileOutputStream(PyObject* /*self*/, PyObject* /*args */) { PyObject* closeLoggerFileOutputStream(
#if PY_MAJOR_VERSION >= 3
PyObject* m, PyObject*
#else
PyObject*, PyObject*
#endif
) {
try { try {
for (std::map<std::string, ofstreamShrPtr>::iterator it = mapOfFiles_.begin(); it != mapOfFiles_.end(); ++it) { for (std::map<std::string, ofstreamShrPtr>::iterator it = mapOfFiles_.begin(); it != mapOfFiles_.end(); ++it) {
it->second->close(); it->second->close();
} }
} }
CATCH_ALL_EXCEPTIONS(); CATCH_ALL_EXCEPTIONS(m);
return Py_BuildValue(""); return Py_BuildValue("");
} }
PyObject* addLoggerCoutOutputStream(PyObject* /*self*/, PyObject* /*args*/) { PyObject* addLoggerCoutOutputStream(
#if PY_MAJOR_VERSION >= 3
PyObject* m, PyObject*
#else
PyObject*, PyObject*
#endif
) {
try { try {
dgADD_OSTREAM_TO_RTLOG(std::cout); dgADD_OSTREAM_TO_RTLOG(std::cout);
} }
CATCH_ALL_EXCEPTIONS(); CATCH_ALL_EXCEPTIONS(m);
return Py_BuildValue(""); return Py_BuildValue("");
} }
PyObject* realTimeLoggerDestroy(PyObject* /*self*/, PyObject* /*args*/) { PyObject* realTimeLoggerDestroy(
#if PY_MAJOR_VERSION >= 3
PyObject* m, PyObject*
#else
PyObject*, PyObject*
#endif
) {
try { try {
RealTimeLogger::destroy(); RealTimeLogger::destroy();
} }
CATCH_ALL_EXCEPTIONS(); CATCH_ALL_EXCEPTIONS(m);
return Py_BuildValue(""); return Py_BuildValue("");
} }
PyObject* realTimeLoggerSpinOnce(PyObject* /*self*/, PyObject* /*args*/) { PyObject* realTimeLoggerSpinOnce(
#if PY_MAJOR_VERSION >= 3
PyObject* m, PyObject*
#else
PyObject*, PyObject*
#endif
) {
try { try {
RealTimeLogger::instance().spinOnce(); RealTimeLogger::instance().spinOnce();
} }
CATCH_ALL_EXCEPTIONS(); CATCH_ALL_EXCEPTIONS(m);
return Py_BuildValue(""); return Py_BuildValue("");
} }
PyObject* realTimeLoggerInstance(PyObject* /*self*/, PyObject* /*args*/) { PyObject* realTimeLoggerInstance(
#if PY_MAJOR_VERSION >= 3
PyObject* m, PyObject*
#else
PyObject*, PyObject*
#endif
) {
try { try {
RealTimeLogger::instance(); RealTimeLogger::instance();
} }
CATCH_ALL_EXCEPTIONS(); CATCH_ALL_EXCEPTIONS(m);
return Py_BuildValue(""); return Py_BuildValue("");
} }
......
...@@ -14,10 +14,20 @@ ...@@ -14,10 +14,20 @@
namespace dynamicgraph { namespace dynamicgraph {
namespace python { namespace python {
#if PY_MAJOR_VERSION == 2
PyObject* dgpyError;
# endif
/** /**
\brief plug a signal into another one. \brief plug a signal into another one.
*/ */
PyObject* plug(PyObject* /*self*/, PyObject* args) { PyObject* plug(
#if PY_MAJOR_VERSION >= 3
PyObject* m, PyObject* args
#else
PyObject*, PyObject* args
#endif
) {
PyObject* objOut = NULL; PyObject* objOut = NULL;
PyObject* objIn = NULL; PyObject* objIn = NULL;
void* pObjOut; void* pObjOut;
...@@ -61,11 +71,17 @@ PyObject* plug(PyObject* /*self*/, PyObject* args) { ...@@ -61,11 +71,17 @@ PyObject* plug(PyObject* /*self*/, PyObject* args) {
try { try {
signalIn->plug(signalOut); signalIn->plug(signalOut);
} }
CATCH_ALL_EXCEPTIONS(); CATCH_ALL_EXCEPTIONS(m);
return Py_BuildValue(""); return Py_BuildValue("");
} }
PyObject* enableTrace(PyObject* /*self*/, PyObject* args) { PyObject* enableTrace(
#if PY_MAJOR_VERSION >= 3
PyObject* m, PyObject* args
#else
PyObject*, PyObject* args
#endif
) {
PyObject* boolean; PyObject* boolean;
char* filename = NULL; char* filename = NULL;
...@@ -82,12 +98,12 @@ PyObject* enableTrace(PyObject* /*self*/, PyObject* args) { ...@@ -82,12 +98,12 @@ PyObject* enableTrace(PyObject* /*self*/, PyObject* args) {
try { try {
DebugTrace::openFile(filename); DebugTrace::openFile(filename);
} }
CATCH_ALL_EXCEPTIONS(); CATCH_ALL_EXCEPTIONS(m);
} else { } else {
try { try {
DebugTrace::closeFile(filename); DebugTrace::closeFile(filename);
} }
CATCH_ALL_EXCEPTIONS(); CATCH_ALL_EXCEPTIONS(m);
} }
} else { } else {
return NULL; return NULL;
...@@ -102,8 +118,7 @@ PyObject* error_out( ...@@ -102,8 +118,7 @@ PyObject* error_out(
PyObject*, PyObject* PyObject*, PyObject*
#endif #endif
) { ) {
struct module_state* st = GETSTATE(m); PyErr_SetString(DGPYERROR(m), "something bad happened");
PyErr_SetString(st->dgpyError, "something bad happened");
return NULL; return NULL;
} }
...@@ -121,30 +136,29 @@ void initwrap(void) ...@@ -121,30 +136,29 @@ void initwrap(void)
#endif #endif
{ {
#if PY_MAJOR_VERSION >= 3 #if PY_MAJOR_VERSION >= 3
PyObject* module = PyModule_Create(&dynamicgraph::python::dynamicGraphModuleDef); PyObject* m = PyModule_Create(&dynamicgraph::python::dynamicGraphModuleDef);
#else #else
PyObject* module = Py_InitModule("wrap", dynamicgraph::python::dynamicGraphMethods); PyObject* m = Py_InitModule("wrap", dynamicgraph::python::dynamicGraphMethods);
#endif #endif
if (module == NULL) INITERROR; if (m == NULL) INITERROR;
struct dynamicgraph::python::module_state* st = GETSTATE(module);
st->dgpyError = PyErr_NewException(const_cast<char*>("dynamic_graph.dgpyError"), NULL, NULL); DGPYERROR(m) = PyErr_NewException(const_cast<char*>("dynamic_graph.dgpyError"), NULL, NULL);
if (st->dgpyError == NULL) { if (DGPYERROR(m) == NULL) {
Py_DECREF(module); Py_DECREF(m);
INITERROR; INITERROR;
} }
Py_XINCREF(st->dgpyError); Py_XINCREF(DGPYERROR(m));
if (PyModule_AddObject(module, "dgpyError", st->dgpyError) < 0) { if (PyModule_AddObject(m, "dgpyError", DGPYERROR(m)) < 0) {
Py_XDECREF(st->dgpyError); Py_XDECREF(DGPYERROR(m));
Py_CLEAR(st->dgpyError); Py_CLEAR(DGPYERROR(m));
Py_DECREF(module); Py_DECREF(m);
return NULL; INITERROR;
} }
#if PY_MAJOR_VERSION >= 3 #if PY_MAJOR_VERSION >= 3
return module; return m;
#endif #endif
} }
......
...@@ -32,12 +32,22 @@ namespace python { ...@@ -32,12 +32,22 @@ namespace python {
using namespace convert; using namespace convert;
#if PY_MAJOR_VERSION == 2
extern PyObject* dgpyError;
# endif
namespace entity { namespace entity {
/** /**
\brief Create an instance of Entity \brief Create an instance of Entity
*/ */
PyObject* create(PyObject* /*self*/, PyObject* args) { PyObject* create(
#if PY_MAJOR_VERSION >= 3
PyObject* m, PyObject* args
#else
PyObject*, PyObject* args
#endif
) {
char* className = NULL; char* className = NULL;
char* instanceName = NULL; char* instanceName = NULL;
...@@ -51,7 +61,7 @@ PyObject* create(PyObject* /*self*/, PyObject* args) { ...@@ -51,7 +61,7 @@ PyObject* create(PyObject* /*self*/, PyObject* args) {
",\n" ",\n"
"but this object is of type " + "but this object is of type " +
std::string(obj->getClassName()) + " and not " + std::string(className)); std::string(obj->getClassName()) + " and not " + std::string(className));
PyErr_SetString(DGPYERROR, msg.c_str()); PyErr_SetString(DGPYERROR(m), msg.c_str());
return NULL; return NULL;
} }
} else /* If not, create a new object. */ } else /* If not, create a new object. */
...@@ -59,7 +69,7 @@ PyObject* create(PyObject* /*self*/, PyObject* args) { ...@@ -59,7 +69,7 @@ PyObject* create(PyObject* /*self*/, PyObject* args) {
try { try {
obj = dynamicgraph::FactoryStorage::getInstance()->newEntity(std::string(className), std::string(instanceName)); obj = dynamicgraph::FactoryStorage::getInstance()->newEntity(std::string(className), std::string(instanceName));
} }
CATCH_ALL_EXCEPTIONS(); CATCH_ALL_EXCEPTIONS(m);
} }
// Return the pointer as a PyCapsule // Return the pointer as a PyCapsule
...@@ -69,7 +79,13 @@ PyObject* create(PyObject* /*self*/, PyObject* args) { ...@@ -69,7 +79,13 @@ PyObject* create(PyObject* /*self*/, PyObject* args) {
/** /**
\brief Get name of entity \brief Get name of entity
*/ */
PyObject* getName(PyObject* /*self*/, PyObject* args) { PyObject* getName(
#if PY_MAJOR_VERSION >= 3
PyObject* m, PyObject* args
#else
PyObject*, PyObject* args
#endif
) {
PyObject* object = NULL; PyObject* object = NULL;
void* pointer = NULL; void* pointer = NULL;
std::string name; std::string name;
...@@ -86,14 +102,20 @@ PyObject* getName(PyObject* /*self*/, PyObject* args) { ...@@ -86,14 +102,20 @@ PyObject* getName(PyObject* /*self*/, PyObject* args) {
try { try {
name = entity->getName(); name = entity->getName();
} }
CATCH_ALL_EXCEPTIONS(); CATCH_ALL_EXCEPTIONS(m);
return Py_BuildValue("s", name.c_str()); return Py_BuildValue("s", name.c_str());
} }
/** /**
\brief Get class name of entity \brief Get class name of entity
*/ */
PyObject* getClassName(PyObject* /*self*/, PyObject* args) { PyObject* getClassName(
#if PY_MAJOR_VERSION >= 3
PyObject* m, PyObject* args
#else
PyObject*, PyObject* args
#endif
) {
PyObject* object = NULL; PyObject* object = NULL;
void* pointer = NULL; void* pointer = NULL;
std::string name; std::string name;
...@@ -110,14 +132,20 @@ PyObject* getClassName(PyObject* /*self*/, PyObject* args) { ...@@ -110,14 +132,20 @@ PyObject* getClassName(PyObject* /*self*/, PyObject* args) {
try { try {
name = entity->getClassName(); name = entity->getClassName();
} }
CATCH_ALL_EXCEPTIONS(); CATCH_ALL_EXCEPTIONS(m);
return Py_BuildValue("s", name.c_str()); return Py_BuildValue("s", name.c_str());
} }
/** /**
\brief Check if the entity has a signal with the given name \brief Check if the entity has a signal with the given name
*/ */
PyObject* hasSignal(PyObject* /*self*/, PyObject* args) { PyObject* hasSignal(
#if PY_MAJOR_VERSION >= 3
PyObject* m, PyObject* args
#else
PyObject*, PyObject* args
#endif
) {
char* name = NULL; char* name = NULL;
PyObject* object = NULL; PyObject* object = NULL;
void* pointer = NULL; void* pointer = NULL;
...@@ -136,7 +164,7 @@ PyObject* hasSignal(PyObject* /*self*/, PyObject* args) { ...@@ -136,7 +164,7 @@ PyObject* hasSignal(PyObject* /*self*/, PyObject* args) {
try { try {
hasSignal = entity->hasSignal(std::string(name)); hasSignal = entity->hasSignal(std::string(name));
} }
CATCH_ALL_EXCEPTIONS(); CATCH_ALL_EXCEPTIONS(m);
if (hasSignal) if (hasSignal)
Py_RETURN_TRUE; Py_RETURN_TRUE;
...@@ -147,7 +175,13 @@ PyObject* hasSignal(PyObject* /*self*/, PyObject* args) { ...@@ -147,7 +175,13 @@ PyObject* hasSignal(PyObject* /*self*/, PyObject* args) {
/** /**
\brief Get a signal by name \brief Get a signal by name
*/ */
PyObject* getSignal(PyObject* /*self*/, PyObject* args) { PyObject* getSignal(
#if PY_MAJOR_VERSION >= 3
PyObject* m, PyObject* args
#else
PyObject*, PyObject* args
#endif
) {
char* name = NULL; char* name = NULL;
PyObject* object = NULL; PyObject* object = NULL;
void* pointer = NULL; void* pointer = NULL;
...@@ -166,14 +200,20 @@ PyObject* getSignal(PyObject* /*self*/, PyObject* args) { ...@@ -166,14 +200,20 @@ PyObject* getSignal(PyObject* /*self*/, PyObject* args) {
try { try {
signal = &(entity->getSignal(std::string(name))); signal = &(entity->getSignal(std::string(name)));
} }
CATCH_ALL_EXCEPTIONS(); CATCH_ALL_EXCEPTIONS(m);
// Return the pointer to the signal without destructor since the signal // Return the pointer to the signal without destructor since the signal
// is not owned by the calling object but by the Entity. // is not owned by the calling object but by the Entity.
return PyCapsule_New((void*)signal, "dynamic_graph.Signal", NULL); return PyCapsule_New((void*)signal, "dynamic_graph.Signal", NULL);
} }
PyObject* listSignals(PyObject* /*self*/, PyObject* args) { PyObject* listSignals(
#if PY_MAJOR_VERSION >= 3
PyObject* m, PyObject* args
#else
PyObject*, PyObject* args
#endif
) {
void* pointer = NULL; void* pointer = NULL;
PyObject* object = NULL; PyObject* object = NULL;
...@@ -198,11 +238,17 @@ PyObject* listSignals(PyObject* /*self*/, PyObject* args) { ...@@ -198,11 +238,17 @@ PyObject* listSignals(PyObject* /*self*/, PyObject* args) {
} }
return result; return result;
} }
CATCH_ALL_EXCEPTIONS(); CATCH_ALL_EXCEPTIONS(m);
return NULL; return NULL;
} }
PyObject* executeCommand(PyObject* /*self*/, PyObject* args) { PyObject* executeCommand(
#if PY_MAJOR_VERSION >= 3
PyObject* m, PyObject* args
#else
PyObject* , PyObject* args
#endif
) {
PyObject* object = NULL; PyObject* object = NULL;
PyObject* argTuple = NULL; PyObject* argTuple = NULL;
char* commandName = NULL; char* commandName = NULL;
...@@ -236,7 +282,7 @@ PyObject* executeCommand(PyObject* /*self*/, PyObject* args) { ...@@ -236,7 +282,7 @@ PyObject* executeCommand(PyObject* /*self*/, PyObject* args) {
if ((unsigned)size != typeVector.size()) { if ((unsigned)size != typeVector.size()) {
std::stringstream ss; std::stringstream ss;
ss << "command takes " << typeVector.size() << " parameters, " << size << " given."; ss << "command takes " << typeVector.size() << " parameters, " << size << " given.";
PyErr_SetString(DGPYERROR, ss.str().c_str()); PyErr_SetString(DGPYERROR(m), ss.str().c_str());
return NULL; return NULL;
} }
std::vector<Value> valueVector; std::vector<Value> valueVector;
...@@ -249,10 +295,10 @@ PyObject* executeCommand(PyObject* /*self*/, PyObject* args) { ...@@ -249,10 +295,10 @@ PyObject* executeCommand(PyObject* /*self*/, PyObject* args) {
} catch (const std::exception& exc) { } catch (const std::exception& exc) {
std::stringstream ss; std::stringstream ss;
ss << "while parsing argument " << iParam + 1 << ": expecting " << exc.what() << "."; ss << "while parsing argument " << iParam + 1 << ": expecting " << exc.what() << ".";
PyErr_SetString(DGPYERROR, ss.str().c_str()); PyErr_SetString(DGPYERROR(m), ss.str().c_str());
return NULL; return NULL;
} catch (...) { } catch (...) {
PyErr_SetString(DGPYERROR, "Unknown exception"); PyErr_SetString(DGPYERROR(m), "Unknown exception");
return NULL;