2 * ParametersPlugin_PyInterp.cpp
4 * Created on: Apr 2, 2015
8 #include <ParametersPlugin_PyInterp.h>
12 ParametersPlugin_PyInterp::ParametersPlugin_PyInterp()
17 ParametersPlugin_PyInterp::~ParametersPlugin_PyInterp()
21 std::list<std::string> ParametersPlugin_PyInterp::compile(const std::string& theExpression)
23 PyGILState_STATE aGilState = PyGILState_Ensure();
24 std::list<std::string> res = this->_compile(theExpression);
25 PyGILState_Release(aGilState);
29 void ParametersPlugin_PyInterp::extendLocalContext(const std::list<std::string>& theParameters)
31 PyGILState_STATE aGilState = PyGILState_Ensure();
32 this->_extendLocalContext(theParameters);
33 PyGILState_Release(aGilState);
36 double ParametersPlugin_PyInterp::evaluate(const std::string& theExpression,
37 std::string& theError)
39 PyGILState_STATE aGilState = PyGILState_Ensure();
40 double res = this->_evaluate(theExpression, theError);
41 PyGILState_Release(aGilState);
46 std::list<std::string> ParametersPlugin_PyInterp::_compile(const std::string& theExpression)
49 std::list<std::string> aResult;
50 PyObject *aCodeopModule = PyImport_AddModule("codeop");
51 if(!aCodeopModule) { // Fatal error. No way to go on.
56 PyObject *aCodePyObj =
57 PyObject_CallMethod(aCodeopModule, "compile_command", "(s)", theExpression.c_str());
59 if(!aCodePyObj || aCodePyObj == Py_None || !PyCode_Check(aCodePyObj)) {
60 Py_XDECREF(aCodePyObj);
64 PyCodeObject* aCodeObj = (PyCodeObject*) aCodePyObj;
65 // co_names should be tuple, but can be changed in modern versions of python (>2.7.3)
66 if(!PyTuple_Check(aCodeObj->co_names))
69 int params_size = PyTuple_Size(aCodeObj->co_names);
70 if (params_size > 0) {
71 for (int i = 0; i < params_size; i++) {
72 PyObject* aParamObj = PyTuple_GetItem(aCodeObj->co_names, i);
73 PyObject* aParamObjStr = PyObject_Str(aParamObj);
74 std::string aParamName(PyString_AsString(aParamObjStr));
75 aResult.push_back(aParamName);
76 Py_XDECREF(aParamObjStr);
83 void ParametersPlugin_PyInterp::_extendLocalContext(const std::list<std::string>& theParameters)
85 if (theParameters.empty())
90 double ParametersPlugin_PyInterp::_evaluate(const std::string& theExpression, std::string& theError)
92 PyCodeObject* anExprCode = (PyCodeObject *) Py_CompileString(theExpression.c_str(),
93 "<string>", Py_eval_input);
95 theError = errorMessage();
96 Py_XDECREF(anExprCode);
100 PyObject* anEvalResult = PyEval_EvalCode(anExprCode, _global_context, _local_context);
102 theError = errorMessage();
103 Py_XDECREF(anExprCode);
104 Py_XDECREF(anEvalResult);
108 PyObject* anEvalStrObj = PyObject_Str(anEvalResult);
109 std::string anEvalStr(PyString_AsString(anEvalStrObj));
110 double result = std::stod(anEvalStr);
115 std::string ParametersPlugin_PyInterp::errorMessage()
117 std::string aPyError;
118 if (PyErr_Occurred()) {
119 PyObject *pstr, *ptype, *pvalue, *ptraceback;
120 PyErr_Fetch(&ptype, &pvalue, &ptraceback);
121 PyErr_NormalizeException(&ptype, &pvalue, &ptraceback);
122 pstr = PyObject_Str(pvalue);
123 aPyError = std::string(PyString_AsString(pstr));
127 Py_XDECREF(ptraceback);