python/VirtualMachine.cpp
Go to the documentation of this file.
1 /*
2 Copyright (C) 2008 National Institute For Space Research (INPE) - Brazil.
3 
4 This file is part of the TerraLib - a Framework for building GIS enabled
5 applications.
6 
7 TerraLib is free software: you can redistribute it and/or modify
8 it under the terms of the GNU Lesser General Public License as published by
9 the Free Software Foundation, either version 3 of the License,
10 or (at your option) any later version.
11 
12 TerraLib is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU Lesser General Public License for more details.
16 
17 You should have received a copy of the GNU Lesser General Public License
18 along with TerraLib. See COPYING. If not, write to
19 TerraLib Team at <terralib-team@terralib.org>.
20 */
21 
22 /*!
23 \file terralib/vm/python/VirtualMachine.cpp
24 
25 \brief Implementation of a virtual machine for the Python Programming
26 Language.
27 
28 \author Matheus Cavassan Zaglia
29 */
30 
31 // TerraLib
32 #include "VirtualMachine.h"
33 #include "../../Defines.h"
34 #include "../../core/encoding/CharEncoding.h"
35 #include "../../core/filesystem/FileSystem.h"
36 #include "../../core/logger/Logger.h"
37 #include "../../core/translator/Translator.h"
38 #include "../../core/utils/Platform.h"
39 #include "../core/Exception.h"
40 
41 // Qt
42 #include <QThread>
43 
46  : m_vm(vm)
47 {
48 }
49 
50 void te::vm::python::VirtualMachineOutput::write(const std::string& str)
51 {
52  m_vm->write(str.c_str());
53 }
56  : m_vm(vm)
57 {
58 }
59 
61 {
62  return m_vm->readline();
63 }
64 
66  : m_stdin(this), m_stdout(this), m_stderr(this), m_readlineLoop(nullptr)
67 {
68  Py_Initialize();
69 
70  boost::python::object main = boost::python::object(boost::python::handle<>(
71  boost::python::borrowed(PyImport_AddModule("__main__"))));
72 
73  boost::python::object nspace = main.attr("__dict__");
74 
75  nspace["VirtualMachineInput"] =
76  boost::python::class_<te::vm::python::VirtualMachineInput>(
77  "VirtualMachineInput", boost::python::init<>())
79  nspace["VirtualMachineOutput"] =
80  boost::python::class_<te::vm::python::VirtualMachineOutput>(
81  "VirtualMachineOutput", boost::python::init<>())
83 
84  m_mainThreadState = PyEval_SaveThread();
85 }
86 
88 {
89  PyEval_RestoreThread(m_mainThreadState);
90 
91  Py_Finalize();
92 
93  delete m_readlineLoop;
94 }
95 
97 {
98  m_filename = file.toUtf8().data();
99 }
100 
102 {
103  PyThreadState* state = Py_NewInterpreter();
104  try
105  {
106  boost::python::import("sys").attr("stdin") = m_stdin;
107  boost::python::import("sys").attr("stdout") = m_stdout;
108  boost::python::import("sys").attr("stderr") = m_stderr;
109 
110  std::string bind_path;
111 
112 #ifdef TERRALIB_MOD_BINDING_PYTHON_DIR
113  std::string aux =
114  "bindings/" + std::string(TERRALIB_MOD_BINDING_PYTHON_DIR);
117 #endif
118 
119  std::string bin_path =
121  std::string lib_path =
123 
124 #if TE_PLATFORM == TE_PLATFORMCODE_MSWINDOWS
125  std::replace(bind_path.begin(), bind_path.end(), '\\', '/');
126  std::replace(bin_path.begin(), bin_path.end(), '\\', '/');
127  std::replace(lib_path.begin(), lib_path.end(), '\\', '/');
128 #endif
129 
130  std::string py_binds = "sys.path.append('" + bind_path + "')\n" +
131  "sys.path.append('" + bin_path + "')\n" +
132  "sys.path.append('" + lib_path + "')\n" +
133  "sys.path.append('" + bind_path +
134  ((TE_PLATFORM == TE_PLATFORMCODE_MSWINDOWS) ? "\\..')" : "/..')");
135  PyRun_SimpleString("import sys");
136  PyRun_SimpleString(py_binds.c_str());
137  PyRun_SimpleString(("exec(open('" + m_filename + "').read())").c_str());
138  }
139  catch(boost::python::error_already_set)
140  {
141  PyErr_Print();
142  }
143  Py_EndInterpreter(state);
144 }
145 
147 {
148  emit output(str);
149  QThread::currentThread()->usleep(1);
150 }
151 
153 {
154  emit requestReadline();
155  m_readlineLoop = new QEventLoop();
156  m_readlineLoop->exec();
157  return m_readlineStr;
158 }
159 
161 {
162  m_readlineStr = msg.toUtf8().data();
163  m_readlineLoop->exit();
164 }
165 
167 {
168  PyErr_SetInterrupt();
169  if(m_readlineLoop != nullptr && m_readlineLoop->isRunning())
170  m_readlineLoop->exit();
171  PyErr_CheckSignals();
172 }
173 
175 {
176  return "Python";
177 }
178 
180 {
181  std::string msg(
182  TE_TR("TerraLib Virtual Machine for the Python Programming Language"));
183 
184  return msg;
185 }
186 
188 {
189  std::string msg(TE_TR(
190  "This Virtual Machine allows applications to execute python scripts."
191  "\nAll the TerraLib API will be available for TerraLib programmers "
192  "in the Python environment"));
193 
194  return msg;
195 }
std::string getDescription() const
Returns a brief description about the underlying Virtual Machine.
VirtualMachineOutput(te::vm::core::VirtualMachine *vm=nullptr)
te::vm::core::VirtualMachine * m_vm
te::vm::core::VirtualMachine * m_vm
#define TE_TR(message)
It marks a string in order to get translated.
Definition: Translator.h:242
Implementation of a virtual machine for the Python Programming Language.
static std::string absolutePath(const std::string &path)
Retrives the absolute path for the given path in UTF-8.
Definition: FileSystem.cpp:76
VirtualMachineInput(te::vm::core::VirtualMachine *vm=nullptr)
void requestReadline()
Signal emmited when the Virtual Machine needs to execute a input operation.
int main(int argc, char *argv[])
void output(QString msg)
output Signal emmited when the Virtual Machine receives a string.
std::string getTitle() const
Return the title of Virtual Machine: a name that can be used by applications to show in a GUI...
TECOREEXPORT std::string FindInTerraLibPath(const std::string &path)
Returns the path relative to a directory or file in the context of TerraLib.
virtual std::string readline()=0
readline Method to be used by the language of the Virtual Machine when doing a input operation...
void setFileName(QString file)
setFileName Sets the file that will be used in the Virtual Machine.
file(WRITE ${CMAKE_BINARY_DIR}/config_qhelp.cmake"configure_file (${TERRALIB_ABSOLUTE_ROOT_DIR}/doc/qhelp/help.qhcp.in ${CMAKE_BINARY_DIR}/share/terraview/help/help.qhcp @ONLY)") add_custom_command(OUTPUT del_dir COMMAND $
virtual void write(const QString &str)=0
write Writes the output coming from the Virtual Machine
std::string readline()
readline Method to be used by the language of the Virtual Machine when doing a input operation...