From 1676b285ae726eb858d4d7ed089496133ce3de4b Mon Sep 17 00:00:00 2001 From: Miodrag Milanovic Date: Thu, 28 Jun 2018 17:56:44 +0200 Subject: adapted python-console for easier use --- 3rdparty/python-console/modified/pyinterpreter.cc | 155 ++++++++++++++++++++++ 1 file changed, 155 insertions(+) create mode 100644 3rdparty/python-console/modified/pyinterpreter.cc (limited to '3rdparty/python-console/modified/pyinterpreter.cc') diff --git a/3rdparty/python-console/modified/pyinterpreter.cc b/3rdparty/python-console/modified/pyinterpreter.cc new file mode 100644 index 00000000..ee8c4aa8 --- /dev/null +++ b/3rdparty/python-console/modified/pyinterpreter.cc @@ -0,0 +1,155 @@ +/** +python-console +Copyright (C) 2014 Alex Tsui + +Permission is hereby granted, free of charge, to any person obtaining a copy of +this software and associated documentation files (the "Software"), to deal in +the Software without restriction, including without limitation the rights to +use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies +of the Software, and to permit persons to whom the Software is furnished to do +so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. +*/ + +#include "pyinterpreter.h" +#include +#include +#include +#include +#include "pyredirector.h" + +static PyThreadState *MainThreadState = NULL; + +static PyThreadState *m_threadState = NULL; +static PyObject *glb = NULL; +static PyObject *loc = NULL; + +static std::list m_suggestions; + +template std::string string_format(const std::string &format, Args... args) +{ + size_t size = std::snprintf(nullptr, 0, format.c_str(), args...) + 1; // Extra space for '\0' + std::unique_ptr buf(new char[size]); + std::snprintf(buf.get(), size, format.c_str(), args...); + return std::string(buf.get(), buf.get() + size - 1); // We don't want the '\0' inside +} + +std::string pyinterpreter_execute(const std::string &command, int *errorCode) +{ + PyEval_AcquireThread(m_threadState); + *errorCode = 0; + + PyObject *py_result; + PyObject *dum; + std::string res; + py_result = Py_CompileString(command.c_str(), "", Py_single_input); + if (py_result == 0) { + if (PyErr_Occurred()) { + *errorCode = 1; + PyErr_Print(); + res = redirector_take_output(m_threadState); + } + + PyEval_ReleaseThread(m_threadState); + return res; + } + dum = PyEval_EvalCode(py_result, glb, loc); + Py_XDECREF(dum); + Py_XDECREF(py_result); + if (PyErr_Occurred()) { + *errorCode = 1; + PyErr_Print(); + } + + res = redirector_take_output(m_threadState); + + PyEval_ReleaseThread(m_threadState); + return res; +} + +const std::list &pyinterpreter_suggest(const std::string &hint) +{ + PyEval_AcquireThread(m_threadState); + m_suggestions.clear(); + int i = 0; + std::string command = string_format("sys.completer.complete('%s', %d)\n", hint.c_str(), i); + std::string res; + do { + PyObject *py_result; + PyObject *dum; + py_result = Py_CompileString(command.c_str(), "", Py_single_input); + dum = PyEval_EvalCode(py_result, glb, loc); + Py_XDECREF(dum); + Py_XDECREF(py_result); + res = redirector_take_output(m_threadState); + + ++i; + command = string_format("sys.completer.complete('%s', %d)\n", hint.c_str(), i); + if (res.size()) { + // throw away the newline + res = res.substr(1, res.size() - 3); + m_suggestions.push_back(res); + } + } while (res.size()); + + PyEval_ReleaseThread(m_threadState); + return m_suggestions; +} + +void pyinterpreter_preinit() +{ + m_suggestions.clear(); + inittab_redirector(); +} + +void pyinterpreter_initialize() +{ + PyEval_InitThreads(); + MainThreadState = PyEval_SaveThread(); + PyEval_AcquireThread(MainThreadState); + m_threadState = Py_NewInterpreter(); + + PyObject *module = PyImport_ImportModule("__main__"); + loc = glb = PyModule_GetDict(module); + + PyRun_SimpleString("import sys\n" + "import redirector\n" + "sys.path.insert(0, \".\")\n" // add current path + "sys.stdout = redirector.redirector()\n" + "sys.stderr = sys.stdout\n" + "import rlcompleter\n" + "sys.completer = rlcompleter.Completer()\n"); + + PyEval_ReleaseThread(m_threadState); +} + +void pyinterpreter_finalize() +{ + m_suggestions.clear(); + + PyEval_AcquireThread(m_threadState); + Py_EndInterpreter(m_threadState); + PyEval_ReleaseLock(); + + PyEval_RestoreThread(MainThreadState); +} + +void pyinterpreter_aquire() +{ + PyEval_AcquireThread(m_threadState); +} + +void pyinterpreter_release() +{ + PyEval_ReleaseThread(m_threadState); +} -- cgit v1.2.3