aboutsummaryrefslogtreecommitdiffstats
path: root/src/modules/pythoncore
diff options
context:
space:
mode:
authorGravatar staticfox2016-04-21 03:01:17 -0400
committerGravatar staticfox2016-04-21 03:12:20 -0400
commitc33327ff43db2e0fd8f4c2d9a7a4333a50e8c605 (patch)
treeba8c64caaf02b9d65607022c6f5b3dd0fffb8dfb /src/modules/pythoncore
parentMerge pull request #1951 from AlexanderP/travis_ppa (diff)
downloadKVIrc-c33327ff43db2e0fd8f4c2d9a7a4333a50e8c605.tar.gz
KVIrc-c33327ff43db2e0fd8f4c2d9a7a4333a50e8c605.tar.bz2
KVIrc-c33327ff43db2e0fd8f4c2d9a7a4333a50e8c605.zip
Python: Refactor python support
Closes #1866
Diffstat (limited to 'src/modules/pythoncore')
-rw-r--r--src/modules/pythoncore/kvircmodule.cpp124
-rw-r--r--src/modules/pythoncore/kvircmodule.h22
-rw-r--r--src/modules/pythoncore/libkvipythoncore.cpp296
3 files changed, 169 insertions, 273 deletions
diff --git a/src/modules/pythoncore/kvircmodule.cpp b/src/modules/pythoncore/kvircmodule.cpp
index eac16903c..bc26c0759 100644
--- a/src/modules/pythoncore/kvircmodule.cpp
+++ b/src/modules/pythoncore/kvircmodule.cpp
@@ -48,10 +48,9 @@ extern QString g_lError;
static PyObject * PyKVIrc_echo(PyObject * pSelf, PyObject * pArgs)
{
Q_UNUSED(pSelf);
- const char * pcText=0;
- int iColorSet=0;
- const char * pcWinId=0;
- KviWindow * pWnd=0;
+ const char * pcText = nullptr, *pcWinId = nullptr;
+ KviWindow * pWnd = nullptr;
+ int iColorSet = 0;
if(QThread::currentThread() != g_pApp->thread())
{
@@ -65,20 +64,18 @@ static PyObject * PyKVIrc_echo(PyObject * pSelf, PyObject * pArgs)
if(pcText)
{
if(pcWinId)
- {
pWnd = g_pApp->findWindow(pcWinId);
- }
+
if(!pWnd)
{
if(g_pCurrentKvsContext)
- {
pWnd = g_pCurrentKvsContext->window();
- } else if(g_pActiveWindow) {
+ else if(g_pActiveWindow)
pWnd = g_pActiveWindow;
- } else {
- pWnd = (KviWindow*) g_pApp->activeConsole();
- }
+ else
+ pWnd = (KviWindow *) g_pApp->activeConsole();
}
+
if(pWnd)
pWnd->outputNoFmt(iColorSet,QString::fromUtf8(pcText));
}
@@ -89,10 +86,8 @@ static PyObject * PyKVIrc_echo(PyObject * pSelf, PyObject * pArgs)
static PyObject * PyKVIrc_say(PyObject * pSelf, PyObject * pArgs)
{
Q_UNUSED(pSelf);
-
- const char * pcText=0;
- const char * pcWinId=0;
- KviWindow * pWnd=0;
+ const char * pcText = nullptr, *pcWinId = nullptr;
+ KviWindow * pWnd = nullptr;
if(QThread::currentThread() != g_pApp->thread())
{
@@ -106,23 +101,20 @@ static PyObject * PyKVIrc_say(PyObject * pSelf, PyObject * pArgs)
if(pcText)
{
if(pcWinId)
- {
pWnd = g_pApp->findWindow(pcWinId);
- }
+
if(!pWnd)
{
if(g_pCurrentKvsContext)
- {
pWnd = g_pCurrentKvsContext->window();
- } else if(g_pActiveWindow) {
+ else if(g_pActiveWindow)
pWnd = g_pActiveWindow;
- } else {
- pWnd = (KviWindow*) g_pApp->activeConsole();
- }
+ else
+ pWnd = (KviWindow *) g_pApp->activeConsole();
}
if(pWnd)
{
- QString szText=QString::fromUtf8(pcText);
+ QString szText = QString::fromUtf8(pcText);
KviUserInput::parse(szText,pWnd);
}
}
@@ -133,7 +125,7 @@ static PyObject * PyKVIrc_say(PyObject * pSelf, PyObject * pArgs)
static PyObject * PyKVIrc_warning(PyObject * pSelf, PyObject * pArgs)
{
Q_UNUSED(pSelf);
- const char * pcText=0;
+ const char * pcText = nullptr;
if(QThread::currentThread() != g_pApp->thread())
{
@@ -156,9 +148,8 @@ static PyObject * PyKVIrc_warning(PyObject * pSelf, PyObject * pArgs)
static PyObject * PyKVIrc_getLocal(PyObject * pSelf, PyObject * pArgs)
{
Q_UNUSED(pSelf);
-
+ const char * szVarName = nullptr;
QString tmp;
- const char * szVarName=0;
if(QThread::currentThread() != g_pApp->thread())
{
@@ -166,7 +157,6 @@ static PyObject * PyKVIrc_getLocal(PyObject * pSelf, PyObject * pArgs)
return 0; // Sorry, we're NOT thread safe
}
-
if(!PyArg_ParseTuple(pArgs,"s",&szVarName))
return 0;
@@ -177,7 +167,9 @@ static PyObject * PyKVIrc_getLocal(PyObject * pSelf, PyObject * pArgs)
{
pVar->asString(tmp);
return Py_BuildValue("s",tmp.toUtf8().data());
- } else return Py_BuildValue("s","");
+ } else {
+ return Py_BuildValue("s","");
+ }
}
return 0;
}
@@ -185,10 +177,8 @@ static PyObject * PyKVIrc_getLocal(PyObject * pSelf, PyObject * pArgs)
static PyObject * PyKVIrc_setLocal(PyObject * pSelf, PyObject * pArgs)
{
Q_UNUSED(pSelf);
-
+ const char * szVarName = nullptr, *szVarValue = nullptr;
QString tmp;
- const char * szVarName=0;
- const char * szVarValue=0;
if(QThread::currentThread() != g_pApp->thread())
{
@@ -216,9 +206,8 @@ static PyObject * PyKVIrc_setLocal(PyObject * pSelf, PyObject * pArgs)
static PyObject * PyKVIrc_getGlobal(PyObject * pSelf, PyObject * pArgs)
{
Q_UNUSED(pSelf);
-
+ const char * szVarName = nullptr;
QString tmp;
- const char * szVarName=0;
if(QThread::currentThread() != g_pApp->thread())
{
@@ -236,7 +225,9 @@ static PyObject * PyKVIrc_getGlobal(PyObject * pSelf, PyObject * pArgs)
{
pVar->asString(tmp);
return Py_BuildValue("s",tmp.toUtf8().data());
- } else return Py_BuildValue("s","");
+ } else {
+ return Py_BuildValue("s","");
+ }
}
return 0;
}
@@ -244,10 +235,8 @@ static PyObject * PyKVIrc_getGlobal(PyObject * pSelf, PyObject * pArgs)
static PyObject * PyKVIrc_setGlobal(PyObject * pSelf, PyObject * pArgs)
{
Q_UNUSED(pSelf);
-
+ const char * szVarName = nullptr, *szVarValue = nullptr;
QString tmp;
- const char * szVarName=0;
- const char * szVarValue=0;
if(QThread::currentThread() != g_pApp->thread())
{
@@ -255,7 +244,6 @@ static PyObject * PyKVIrc_setGlobal(PyObject * pSelf, PyObject * pArgs)
return 0; // Sorry, we're NOT thread safe
}
-
if(!PyArg_ParseTuple(pArgs,"ss",&szVarName, &szVarValue))
return 0;
@@ -276,9 +264,9 @@ static PyObject * PyKVIrc_setGlobal(PyObject * pSelf, PyObject * pArgs)
static PyObject * PyKVIrc_eval(PyObject * pSelf, PyObject * pArgs)
{
Q_UNUSED(pSelf);
- const char * pcCode=0;
- char * pcRetVal=0;
- KviWindow * pWnd=0;
+ const char * pcCode = nullptr;
+ KviWindow * pWnd = nullptr;
+ char * pcRetVal = nullptr;
if(QThread::currentThread() != g_pApp->thread())
{
@@ -292,13 +280,12 @@ static PyObject * PyKVIrc_eval(PyObject * pSelf, PyObject * pArgs)
if(pcCode)
{
if(g_pCurrentKvsContext)
- {
pWnd = g_pCurrentKvsContext->window();
- } else if(g_pActiveWindow) {
+ else if(g_pActiveWindow)
pWnd = g_pActiveWindow;
- } else {
- pWnd = (KviWindow*) g_pApp->activeConsole();
- }
+ else
+ pWnd = (KviWindow *) g_pApp->activeConsole();
+
if(pWnd)
{
KviKvsVariant ret;
@@ -317,7 +304,7 @@ static PyObject * PyKVIrc_eval(PyObject * pSelf, PyObject * pArgs)
static PyObject * PyKVIrc_internalWarning(PyObject * pSelf, PyObject * pArgs)
{
Q_UNUSED(pSelf);
- const char * pcText=0;
+ const char * pcText = nullptr;
if(QThread::currentThread() != g_pApp->thread())
{
@@ -329,9 +316,7 @@ static PyObject * PyKVIrc_internalWarning(PyObject * pSelf, PyObject * pArgs)
return 0;
if(pcText && !g_bExecuteQuiet)
- {
g_lWarningList.append(QString(pcText));
- }
return Py_BuildValue("i",1);
}
@@ -339,7 +324,7 @@ static PyObject * PyKVIrc_internalWarning(PyObject * pSelf, PyObject * pArgs)
static PyObject * PyKVIrc_error(PyObject * pSelf, PyObject * pArgs)
{
Q_UNUSED(pSelf);
- const char * pcText=0;
+ const char * pcText = nullptr;
if(QThread::currentThread() != g_pApp->thread())
{
@@ -351,9 +336,7 @@ static PyObject * PyKVIrc_error(PyObject * pSelf, PyObject * pArgs)
return 0;
if(pcText)
- {
g_lError.append(pcText);
- }
return Py_BuildValue("i",1);
}
@@ -379,32 +362,35 @@ static PyMethodDef KVIrcMethods[] = {
"" },
{ "error", PyKVIrc_error, METH_VARARGS,
"" },
- { NULL, NULL, 0, NULL }
+ { nullptr, nullptr, 0, nullptr }
};
PyMODINIT_FUNC python_init()
{
- static void * PyKVIrc_API[PyKVIrc_API_NUM];
+ static const PyCFunction PyKVIrc_API[] = {
+ PyKVIrc_echo,
+ PyKVIrc_say,
+ PyKVIrc_warning,
+ PyKVIrc_getLocal,
+ PyKVIrc_setLocal,
+ PyKVIrc_getGlobal,
+ PyKVIrc_setGlobal,
+ PyKVIrc_eval,
+ PyKVIrc_internalWarning,
+ PyKVIrc_error,
+ };
+
PyObject * pModule;
PyObject * pC_API_Object;
- pModule = Py_InitModule("kvirc",KVIrcMethods);
- if(!pModule) return;
-
- // Initialize the C API pointer array
- PyKVIrc_API[0] = (void *)PyKVIrc_echo;
- PyKVIrc_API[1] = (void *)PyKVIrc_say;
- PyKVIrc_API[2] = (void *)PyKVIrc_warning;
- PyKVIrc_API[3] = (void *)PyKVIrc_getLocal;
- PyKVIrc_API[4] = (void *)PyKVIrc_setLocal;
- PyKVIrc_API[5] = (void *)PyKVIrc_getGlobal;
- PyKVIrc_API[6] = (void *)PyKVIrc_setGlobal;
- PyKVIrc_API[7] = (void *)PyKVIrc_eval;
- PyKVIrc_API[8] = (void *)PyKVIrc_internalWarning;
- PyKVIrc_API[9] = (void *)PyKVIrc_error;
+ if(!(pModule = Py_InitModule3("kvirc", KVIrcMethods, nullptr)))
+ {
+ KVI_ASSERT("Python: Unable to initialize kvirc import module");
+ return;
+ }
// Create a CObject containing the API pointer array's address
- pC_API_Object = PyCObject_FromVoidPtr((void *)PyKVIrc_API,NULL);
+ pC_API_Object = PyCObject_FromVoidPtr(const_cast<PyCFunction *>(PyKVIrc_API), nullptr);
if(pC_API_Object)
PyModule_AddObject(pModule,"_C_API",pC_API_Object);
diff --git a/src/modules/pythoncore/kvircmodule.h b/src/modules/pythoncore/kvircmodule.h
index 32b30e2f0..4fffacee4 100644
--- a/src/modules/pythoncore/kvircmodule.h
+++ b/src/modules/pythoncore/kvircmodule.h
@@ -54,25 +54,7 @@ PyMODINIT_FUNC python_init();
#ifdef __cplusplus
extern "C" {
#endif
-
- // Total number of C API pointers
- #define PyKVIrc_API_NUM 10
-
- #ifdef KVIRC_MODULE
- // This section is used when compiling kvircmodule.cpp
- #if 0
- PyObject * PyKVIrc_echo(PyObject * pSelf, PyObject * pArgs);
- PyObject * PyKVIrc_say(PyObject * pSelf, PyObject * pArgs);
- PyObject * PyKVIrc_warning(PyObject * pSelf, PyObject * pArgs);
- PyObject * PyKVIrc_getLocal(PyObject * pSelf, PyObject * pArgs);
- PyObject * PyKVIrc_setLocal(PyObject * pSelf, PyObject * pArgs);
- PyObject * PyKVIrc_getGlobal(PyObject * pSelf, PyObject * pArgs);
- PyObject * PyKVIrc_setGlobal(PyObject * pSelf, PyObject * pArgs);
- PyObject * PyKVIrc_eval(PyObject * pSelf, PyObject * pArgs);
- PyObject * PyKVIrc_internalWarning(PyObject * pSelf, PyObject * pArgs);
- PyObject * PyKVIrc_error(PyObject * pSelf, PyObject * pArgs);
- #endif
- #else
+ #ifndef KVIRC_MODULE
// This section is used in modules that use kvircmodule's API
static void ** PyKVIrc_API;
@@ -102,7 +84,7 @@ extern "C" {
* In case on unsuccess, it sets the exception
* \return int
*/
- static int import_kvirc()
+ inline static int import_kvirc()
{
PyObject * pModule = PyImport_ImportModule("kvirc");
if(pModule)
diff --git a/src/modules/pythoncore/libkvipythoncore.cpp b/src/modules/pythoncore/libkvipythoncore.cpp
index 1f125b626..b8e6c8e7b 100644
--- a/src/modules/pythoncore/libkvipythoncore.cpp
+++ b/src/modules/pythoncore/libkvipythoncore.cpp
@@ -22,121 +22,98 @@
//
//=============================================================================
+#include <functional>
+#include <memory>
+#include <unordered_map>
+#include <utility>
#include "kvi_settings.h"
#include "KviModule.h"
#include "KviLocale.h"
-//#include "KviModuleManager.h"
-//#include "KviFileUtils.h"
-//#include "KviApplication.h"
-//#include "KviOptions.h"
-//#include "kvi_out.h"
#ifdef COMPILE_PYTHON_SUPPORT
- #include "kvircmodule.h"
- #include "pythoncoreinterface.h"
+#include "kvircmodule.h"
+#include "pythoncoreinterface.h"
- #include <Python.h>
+#include <Python.h>
-KviKvsRunTimeContext * g_pCurrentKvsContext = 0;
+KviKvsRunTimeContext * g_pCurrentKvsContext = nullptr;
bool g_bExecuteQuiet = false;
QStringList g_lWarningList;
QString g_lError;
-static KviCString g_szLastReturnValue("");
-static PyThreadState * mainThreadState = NULL;
+static PyThreadState * mainThreadState = nullptr;
-class KviPythonInterpreter
-{
-public:
- KviPythonInterpreter(const QString & szContextName);
- ~KviPythonInterpreter();
-protected:
- QString m_szContextName;
- PyThreadState * m_pThreadState;
-public:
- bool init(); // if this fails then well.. :D
- void done();
- bool execute(const QString & szCode, QStringList & lArgs, QString & szRetVal, QString & szError, QStringList & lWarnings);
- const QString & contextName() const { return m_szContextName; };
+struct KviPythonLock {
+ KviPythonLock(PyThreadState * ts) {
+ PyEval_RestoreThread(ts);
+ }
+ ~KviPythonLock() {
+ PyEval_SaveThread();
+ }
};
-KviPythonInterpreter::KviPythonInterpreter(const QString & szContextName)
-{
- m_szContextName = szContextName;
- m_pThreadState = 0;
-}
+struct KviPythonInterpreterDeleter {
+ void operator()(PyThreadState * ts) const
+ {
+ KviPythonLock lock{ts};
+ Py_EndInterpreter(ts);
+ PyThreadState_Swap(mainThreadState);
+ }
+};
-KviPythonInterpreter::~KviPythonInterpreter()
-{
- done();
-}
+struct KviPythonInterpreter {
+ KviPythonInterpreter();
+ bool execute(QString, QStringList&, QString&, QString&, QStringList&);
+ std::unique_ptr<PyThreadState, KviPythonInterpreterDeleter> m_uptrThreadState;
+};
+
+struct KviCaseInsensitiveQStringHash {
+ std::size_t operator()(const QString& s) const
+ {
+ return static_cast<std::size_t>(qHash(s.toLower()));
+ }
+};
-bool KviPythonInterpreter::init()
+struct KviCaseInsensitiveQStringEqual {
+ bool operator()(const QString& s, const QString& t) const
+ {
+ return (s.toLower() == t.toLower());
+ }
+};
+
+static std::unordered_map<QString,KviPythonInterpreter,KviCaseInsensitiveQStringHash,KviCaseInsensitiveQStringEqual> g_Interpreters;
+
+KviPythonInterpreter::KviPythonInterpreter()
{
-// get the global lock
- PyEval_AcquireLock();
- // get a reference to the PyInterpreterState
- PyInterpreterState * mainInterpreterState = mainThreadState->interp;
- // create a thread state object for this thread
- m_pThreadState = PyThreadState_New(mainInterpreterState);
- // swap in the current thread state
- PyThreadState_Swap(m_pThreadState);
- // and hook in the kvirc error handling routines
- QString szPreCode = QString( \
- "import kvirc\n" \
- "import sys\n" \
- "class kvirc_stderr_grabber:\n" \
- "\tdef write(self,s):\n" \
- "\t\tkvirc.error(s)\n" \
+ KviPythonLock lock{mainThreadState};
+ m_uptrThreadState.reset(Py_NewInterpreter());
+
+ python_init();
+
+ // hook in the kvirc error handling routines
+ QString szPreCode = QString(
+ "import kvirc\n"
+ "import sys\n"
+ "class kvirc_stderr_grabber:\n\tdef write(self,s):\n\t\tkvirc.error(s)\n"
"sys.stderr=kvirc_stderr_grabber()\n"
);
- // evaluate that
- PyRun_SimpleString(szPreCode.toUtf8().data());
- // swap out our thread state for now
- PyThreadState_Swap(NULL);
-
- // free the lock
- PyEval_ReleaseLock();
- return true;
-}
-void KviPythonInterpreter::done()
-{
- if(!m_pThreadState)return;
- // grab the lock
- PyEval_AcquireLock();
- // swap my thread state out of the interpreter
- PyThreadState_Swap(NULL);
- // clear out any cruft from thread state object
- PyThreadState_Clear(m_pThreadState);
- // delete my thread state object
- PyThreadState_Delete(m_pThreadState);
- // release the lock
- PyEval_ReleaseLock();
- m_pThreadState = 0;
+ PyRun_SimpleString(szPreCode.toUtf8().data());
}
-bool KviPythonInterpreter::execute(
- const QString &szCode,
- QStringList &lArgs, //args
- QString &szRetVal,
- QString &szError,
- QStringList &) //lWarnings
+bool KviPythonInterpreter::execute(QString szCode, QStringList& lArgs,
+ QString& szRetVal, QString& szError, QStringList&)
{
- if(!m_pThreadState)
+ if(!m_uptrThreadState)
{
szError = __tr2qs_ctx("Internal error: Python interpreter not initialized","python");
return false;
}
- int retVal;
g_lError.clear();
- // grab the global interpreter lock
- PyEval_AcquireLock();
- // swap in my thread state
- PyThreadState_Swap(m_pThreadState);
+ KviPythonLock lock{m_uptrThreadState.get()};
QString szVarCode = "aArgs = [";
@@ -155,101 +132,72 @@ bool KviPythonInterpreter::execute(
PyRun_SimpleString(szVarCode.toUtf8().data());
- //clean "cr" from the python code (ticket #1028)
- QString szCleanCode = szCode;
- szCleanCode.replace(QRegExp("\r\n?"), "\n");
- // execute some python code
- retVal = PyRun_SimpleString(szCleanCode.toUtf8().data());
+ // clean "cr" from the python code (ticket #1028)
+ szCode.replace(QRegExp("\r\n?"), "\n");
+
+ int retVal = PyRun_SimpleString(szCode.toUtf8().data());
szRetVal.setNum(retVal);
- if (PyErr_Occurred() || retVal)
- {
+ if(PyErr_Occurred() || retVal)
szError = g_lError;
- }
- // clear the thread state
- PyThreadState_Swap(NULL);
- // release our hold on the global interpreter
- PyEval_ReleaseLock();
-
- if(retVal)
- return false;
- return true;
+ return !retVal;
}
- static KviPointerHashTable<QString,KviPythonInterpreter> * g_pInterpreters = 0;
-
-static KviPythonInterpreter * pythoncore_get_interpreter(const QString &szContextName)
+static void pythoncore_destroy_interpreter(const QString& szContextName)
{
- KviPythonInterpreter * i = g_pInterpreters->find(szContextName);
- if(i)return i;
- i = new KviPythonInterpreter(szContextName);
- if(!i->init())
- {
- delete i;
- return 0;
- }
- g_pInterpreters->replace(szContextName,i);
- return i;
-}
+ const auto i = g_Interpreters.find(szContextName);
-static void pythoncore_destroy_interpreter(const QString &szContextName)
-{
- KviPythonInterpreter * i = g_pInterpreters->find(szContextName);
- if(!i)return;
- g_pInterpreters->remove(szContextName);
- i->done();
- delete i;
+ if(i != g_Interpreters.end())
+ g_Interpreters.erase(i);
}
-static void pythoncore_destroy_all_interpreters()
+#endif // COMPILE_PYTHON_SUPPORT
+
+template<typename T>
+T * castFromModParam(void * p)
{
- KviPointerHashTableIterator<QString,KviPythonInterpreter> it(*g_pInterpreters);
+ T * ex = static_cast<T *>(p);
- while(it.current())
- {
- KviPythonInterpreter * i = it.current();
- i->done();
- delete i;
- ++it;
- }
- g_pInterpreters->clear();
-}
+ if(ex->uSize != sizeof(T))
+ return nullptr;
-#endif // COMPILE_PYTHON_SUPPORT
+ return ex;
+}
static bool pythoncore_module_ctrl(KviModule *,const char * cmd,void * param)
{
#ifdef COMPILE_PYTHON_SUPPORT
- if(kvi_strEqualCS(cmd,KVI_PYTHONCORECTRLCOMMAND_EXECUTE))
+ if(!strcmp(cmd,KVI_PYTHONCORECTRLCOMMAND_EXECUTE))
{
- KviPythonCoreCtrlCommand_execute * ex = (KviPythonCoreCtrlCommand_execute *)param;
- if(ex->uSize != sizeof(KviPythonCoreCtrlCommand_execute))return false;
- g_pCurrentKvsContext = ex->pKvsContext;
- g_bExecuteQuiet = ex->bQuiet;
- if(ex->szContext.isEmpty())
+ auto * pex = castFromModParam<KviPythonCoreCtrlCommand_execute>(param);
+
+ if(!pex)
+ return false;
+
+ auto& ex = *pex;
+
+ g_pCurrentKvsContext = ex.pKvsContext;
+ g_bExecuteQuiet = ex.bQuiet;
+ if(ex.szContext.isEmpty())
{
- KviPythonInterpreter * m = new KviPythonInterpreter("temporary");
- if(!m->init())
- {
- delete m;
- return false;
- }
- ex->bExitOk = m->execute(ex->szCode,ex->lArgs,ex->szRetVal,ex->szError,ex->lWarnings);
- m->done();
- delete m;
+ KviPythonInterpreter m;
+ ex.bExitOk = m.execute(ex.szCode,ex.lArgs,ex.szRetVal,ex.szError,ex.lWarnings);
} else {
- KviPythonInterpreter * m = pythoncore_get_interpreter(ex->szContext);
- ex->bExitOk = m->execute(ex->szCode,ex->lArgs,ex->szRetVal,ex->szError,ex->lWarnings);
+ KviPythonInterpreter& m = g_Interpreters[ex.szContext];
+ ex.bExitOk = m.execute(ex.szCode,ex.lArgs,ex.szRetVal,ex.szError,ex.lWarnings);
}
return true;
}
- if(kvi_strEqualCS(cmd,KVI_PYTHONCORECTRLCOMMAND_DESTROY))
+ if(!strcmp(cmd,KVI_PYTHONCORECTRLCOMMAND_DESTROY))
{
- KviPythonCoreCtrlCommand_destroy * de = (KviPythonCoreCtrlCommand_destroy *)param;
- if(de->uSize != sizeof(KviPythonCoreCtrlCommand_destroy))return false;
- pythoncore_destroy_interpreter(de->szContext);
+ auto * pde = castFromModParam<KviPythonCoreCtrlCommand_destroy>(param);
+
+ if(!pde)
+ return false;
+
+ pythoncore_destroy_interpreter(pde->szContext);
return true;
}
#endif // COMPILE_PYTHON_SUPPORT
@@ -259,63 +207,43 @@ static bool pythoncore_module_ctrl(KviModule *,const char * cmd,void * param)
static bool pythoncore_module_init(KviModule *)
{
#ifdef COMPILE_PYTHON_SUPPORT
-
- // Initialize the Python interpreter
Py_Initialize();
PyEval_InitThreads();
- // save a pointer to the main PyThreadState object
- mainThreadState = PyThreadState_Get();
- // release the lock
- PyEval_ReleaseLock();
+ mainThreadState = PyEval_SaveThread();
- // Initialize the Python module for KVIrc
- python_init();
+ if(!g_Interpreters.empty())
+ qDebug("libkvipythoncore: init(): Called init twice??");
- g_pInterpreters = new KviPointerHashTable<QString,KviPythonInterpreter>(17,false);
- g_pInterpreters->setAutoDelete(false);
return true;
-
#endif // COMPILE_PYTHON_SUPPORT
-
return false;
}
static bool pythoncore_module_cleanup(KviModule *)
{
#ifdef COMPILE_PYTHON_SUPPORT
- pythoncore_destroy_all_interpreters();
- delete g_pInterpreters;
- g_pInterpreters = 0;
-
- // shut down the interpreter
- PyEval_AcquireLock();
- PyThreadState_Swap(mainThreadState);
- PyEval_ReleaseLock();
- //FIXME currently python hangs forever on Py_Finalize()
- //under win32/mingw; this is a (bad) workaround
-#ifndef COMPILE_ON_MINGW
+ g_Interpreters.clear();
+ PyEval_RestoreThread(mainThreadState);
Py_Finalize();
-#endif //COMPILE_ON_MINGW
-
#endif // COMPILE_PYTHON_SUPPORT
-
return true;
}
static bool pythoncore_module_can_unload(KviModule *)
{
#ifdef COMPILE_PYTHON_SUPPORT
- return (g_pInterpreters->count() == 0);
+ return g_Interpreters.empty();
#endif // COMPILE_PYTHON_SUPPORT
return true;
}
KVIRC_MODULE(
- "PythonCore", // module name
+ "PythonCore", // module name
"4.0.0", // module version
- "Copyright (C) 2008 Elvio Basello (hellvis69 at netsons dot org)\n" \
- "Copyright (C) 2009 Fabio Bas (ctrlaltca at libero dot it)",
+ "Copyright (C) 2008 Elvio Basello (hellvis69 at netsons dot org)\n"
+ "Copyright (C) 2009 Fabio Bas (ctrlaltca at libero dot it)\n"
+ "Copyright (C) 2016 Matt Ullman (staticfox at staticfox dot net)",
"Python Scripting Engine Core",
pythoncore_module_init,
pythoncore_module_can_unload,