Salome HOME
Reverted some changes in salome build/run scripts.
[modules/shaper.git] / src / InitializationPlugin / InitializationPlugin_PyInterp.cpp
index e3cce6120e3186dee0f8d45d0dbcdd559efc0ba6..b7d591b29c184ac7dae0caed20b00afbcd46436d 100644 (file)
@@ -43,6 +43,16 @@ const char* aSearchCode =
   "            positions.append((node.lineno, node.col_offset))\n"
   "FindName(name).visit(ast.parse(expression))";
 
+// make the expression be correct for the python interpreter even for the
+// beta=alfa*2 expressions
+static std::string adjustExpression(const std::string& theExpression) {
+  std::string anExpression = theExpression;
+  if (!anExpression.empty() && anExpression.back() == '=') {
+    anExpression = anExpression.substr(0, anExpression.length() - 1);
+  }
+  return anExpression;
+}
+
 std::list<std::pair<int, int> >
 InitializationPlugin_PyInterp::positions(const std::string& theExpression,
                                      const std::string& theName)
@@ -56,9 +66,10 @@ InitializationPlugin_PyInterp::positions(const std::string& theExpression,
   PyObject* aBuiltinModule = PyImport_AddModule("__builtin__");
   PyDict_SetItemString(aContext, "__builtins__", aBuiltinModule);
 
+  std::string anExpression = adjustExpression(theExpression);
   // extend aContext with variables
-  PyDict_SetItemString(aContext, "expression", PyString_FromString(theExpression.c_str()));
-  PyDict_SetItemString(aContext, "name", PyString_FromString(theName.c_str()));
+  PyDict_SetItemString(aContext, "expression", PyUnicode_FromString(anExpression.c_str()));
+  PyDict_SetItemString(aContext, "name", PyUnicode_FromString(theName.c_str()));
   PyDict_SetItemString(aContext, "positions", Py_BuildValue("[]"));
 
   // run the search code
@@ -73,8 +84,8 @@ InitializationPlugin_PyInterp::positions(const std::string& theExpression,
     PyObject* aColOffset = PyTuple_GetItem(aPosition, 1);
 
     aResult.push_back(
-        std::pair<int, int>((int)PyInt_AsLong(aLineNo),
-                            (int)PyInt_AsLong(aColOffset)));
+        std::pair<int, int>((int)PyLong_AsLong(aLineNo),
+                            (int)PyLong_AsLong(aColOffset)));
   }
 
   // TODO(spo): after this refCount of the variable is not 0. Is there memory leak?
@@ -93,10 +104,12 @@ std::list<std::string> InitializationPlugin_PyInterp::compile(const std::string&
     PyErr_Print();
     return aResult;
   }
+  // support "variable_name=" expression as "variable_name"
+  std::string anExpression = adjustExpression(theExpression);
 
   PyObject *aCodePyObj =
     PyObject_CallMethod(aCodeopModule, (char*)"compile_command", (char*)"(s)",
-                        theExpression.c_str());
+                        anExpression.c_str());
 
   if(!aCodePyObj || aCodePyObj == Py_None || !PyCode_Check(aCodePyObj)) {
     Py_XDECREF(aCodePyObj);
@@ -104,17 +117,18 @@ std::list<std::string> InitializationPlugin_PyInterp::compile(const std::string&
   }
 
   PyCodeObject* aCodeObj = (PyCodeObject*) aCodePyObj;
-  std::string aCodeName(PyString_AsString(aCodeObj->co_code));
+  std::string aCodeName(PyBytes_AsString(aCodeObj->co_code));
   // co_names should be tuple, but can be changed in modern versions of python (>2.7.3)
-  if(!PyTuple_Check(aCodeObj->co_names))
+  if(!PyTuple_Check(aCodeObj->co_names)) {
     return aResult;
+  }
 
   size_t params_size = PyTuple_Size(aCodeObj->co_names);
   if (params_size > 0) {
     for (size_t i = 0; i < params_size; i++) {
       PyObject* aParamObj = PyTuple_GetItem(aCodeObj->co_names, i);
       PyObject* aParamObjStr = PyObject_Str(aParamObj);
-      std::string aParamName(PyString_AsString(aParamObjStr));
+      std::string aParamName(PyUnicode_AsUTF8(aParamObjStr));
       aResult.push_back(aParamName);
       Py_XDECREF(aParamObjStr);
     }
@@ -144,10 +158,13 @@ void InitializationPlugin_PyInterp::clearLocalContext()
 double InitializationPlugin_PyInterp::evaluate(const std::string& theExpression,
                                                std::string& theError)
 {
+  // support "variable_name=" expression as "variable_name"
+  std::string anExpression = adjustExpression(theExpression);
+
   PyLockWrapper lck; // Acquire GIL until the end of the method
   PyCompilerFlags aFlags = {CO_FUTURE_DIVISION};
   aFlags.cf_flags = CO_FUTURE_DIVISION;
-  PyCodeObject* anExprCode = (PyCodeObject *) Py_CompileStringFlags(theExpression.c_str(),
+  PyCodeObject* anExprCode = (PyCodeObject *) Py_CompileStringFlags(anExpression.c_str(),
                                 "<string>", Py_eval_input, &aFlags);
   if(!anExprCode) {
     theError = errorMessage();
@@ -155,7 +172,7 @@ double InitializationPlugin_PyInterp::evaluate(const std::string& theExpression,
     return 0.;
   }
 
-  PyObject* anEvalResult = PyEval_EvalCode(anExprCode, _global_context, _local_context);
+  PyObject* anEvalResult = PyEval_EvalCode((PyObject *)anExprCode, _global_context, _local_context);
   if(!anEvalResult) {
     theError = errorMessage();
     Py_XDECREF(anExprCode);
@@ -164,7 +181,7 @@ double InitializationPlugin_PyInterp::evaluate(const std::string& theExpression,
   }
 
   PyObject* anEvalStrObj = PyObject_Str(anEvalResult);
-  std::string anEvalStr(PyString_AsString(anEvalStrObj));
+  std::string anEvalStr(PyUnicode_AsUTF8(anEvalStrObj));
   Py_XDECREF(anExprCode);
   Py_XDECREF(anEvalResult);
   Py_XDECREF(anEvalStrObj);
@@ -191,7 +208,7 @@ std::string InitializationPlugin_PyInterp::errorMessage()
     PyErr_Fetch(&ptype, &pvalue, &ptraceback);
     PyErr_NormalizeException(&ptype, &pvalue, &ptraceback);
     pstr = PyObject_Str(pvalue);
-    aPyError = std::string(PyString_AsString(pstr));
+    aPyError = std::string(PyUnicode_AsUTF8(pstr));
     Py_XDECREF(pstr);
     Py_XDECREF(ptype);
     Py_XDECREF(pvalue);