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())
87 std::list<std::string>::const_iterator it = theParameters.begin();
88 for ( ; it != theParameters.cend(); it++) {
89 std::string aParamValue = *it;
90 simpleRun(aParamValue.c_str(), false);
95 double ParametersPlugin_PyInterp::_evaluate(const std::string& theExpression, std::string& theError)
97 PyCodeObject* anExprCode = (PyCodeObject *) Py_CompileString(theExpression.c_str(),
98 "<string>", Py_eval_input);
100 theError = errorMessage();
101 Py_XDECREF(anExprCode);
105 PyObject* anEvalResult = PyEval_EvalCode(anExprCode, _global_context, _local_context);
107 theError = errorMessage();
108 Py_XDECREF(anExprCode);
109 Py_XDECREF(anEvalResult);
113 PyObject* anEvalStrObj = PyObject_Str(anEvalResult);
114 std::string anEvalStr(PyString_AsString(anEvalStrObj));
115 Py_XDECREF(anExprCode);
116 Py_XDECREF(anEvalResult);
117 Py_XDECREF(anEvalStrObj);
118 return std::stod(anEvalStr);
121 std::string ParametersPlugin_PyInterp::errorMessage()
123 std::string aPyError;
124 if (PyErr_Occurred()) {
125 PyObject *pstr, *ptype, *pvalue, *ptraceback;
126 PyErr_Fetch(&ptype, &pvalue, &ptraceback);
127 PyErr_NormalizeException(&ptype, &pvalue, &ptraceback);
128 pstr = PyObject_Str(pvalue);
129 aPyError = std::string(PyString_AsString(pstr));
133 Py_XDECREF(ptraceback);