-#include <lib/python/python.h>
#include <lib/base/eerror.h>
-#include <Python.h>
-
+ /* avoid warnigs :) */
+#undef _POSIX_C_SOURCE
+#define _POSIX_C_SOURCE 200112L
extern "C" void init_enigma();
+extern "C" void eBaseInit(void);
+extern "C" void eConsoleInit(void);
+extern void bsodFatal(const char *component);
-#if 0
-ePyObject::ePyObject(void *ptr): m_object(ptr)
-{
- Py_XINCREF((PyObject*)ptr);
-}
+#define SKIP_PART2
+#include <lib/python/python.h>
+#undef SKIP_PART2
-ePyObject::ePyObject(ePyObject &p)
+#ifdef PYTHON_REFCOUNT_DEBUG
+ePyObject &ePyObject::operator=(PyObject *ob)
{
- m_object = p.m_object;
- Py_XINCREF((PyObject*)m_object);
+ m_ob=ob;
+ m_file=0;
+ m_line=0;
+ m_from=m_to=0;
+ m_erased=false;
+ return *this;
}
-ePyObject::ePyObject(): m_object(0)
+ePyObject &ePyObject::operator=(const ePyObject &ob)
{
+ m_ob=ob.m_ob;
+ m_file=ob.m_file;
+ m_line=ob.m_line;
+ m_from=ob.m_from;
+ m_to=ob.m_to;
+ m_erased=ob.m_erased;
+ return *this;
}
-ePyObject::~ePyObject()
+ePyObject::operator PyObject*()
{
- Py_XDECREF((PyObject*)m_object);
+ if (m_ob)
+ {
+ if (!m_erased && m_ob->ob_refcnt > 0)
+ return m_ob;
+ eDebug("invalid access PyObject %s with refcount <= 0 %d",
+ m_erased ? "deleted" : "undeleted", m_ob->ob_refcnt);
+ if (m_file)
+ eDebug("last modified in file %s line %d from %d to %d",
+ m_file, m_line, m_from, m_to);
+ bsodFatal("enigma2, refcnt");
+ }
+ return 0;
}
-ePyObject &ePyObject::operator=(ePyObject &p)
+void ePyObject::incref(const char *file, int line)
{
- Py_XDECREF((PyObject*)m_object);
- m_object = p.m_object;
- Py_XINCREF((PyObject*)m_object);
- return *this;
+ if (!m_ob)
+ {
+ eDebug("invalid incref python object with null pointer %s %d!!!", file, line);
+ if (m_file)
+ eDebug("last modified in file %s line %d from %d to %d",
+ m_file, m_line, m_from, m_to);
+ bsodFatal("enigma2, refcnt");
+ }
+ if (m_erased || m_ob->ob_refcnt <= 0)
+ {
+ eDebug("invalid incref %s python object with refcounting value %d in file %s line %d!!!",
+ m_erased ? "deleted" : "undeleted", m_ob->ob_refcnt, file, line);
+ if (m_file)
+ eDebug("last modified in file %s line %d from %d to %d",
+ m_file, m_line, m_from, m_to);
+ bsodFatal("enigma2, refcnt");
+ }
+ if (m_ob->ob_refcnt == 0x7FFFFFFF)
+ {
+ eDebug("invalid incref %s python object with refcounting value %d (MAX_INT!!!) in file %s line %d!!!",
+ m_erased ? "deleted" : "undeleted", m_ob->ob_refcnt, file, line);
+ if (m_file)
+ eDebug("last modified in file %s line %d from %d to %d",
+ m_file, m_line, m_from, m_to);
+ bsodFatal("enigma2, refcnt");
+ }
+ m_file = file;
+ m_line = line;
+ m_from = m_ob->ob_refcnt;
+ m_to = m_from+1;
+ Py_INCREF(m_ob);
}
-ePyObject &ePyObject::operator=(void *object)
+void ePyObject::decref(const char *file, int line)
{
- Py_XDECREF((PyObject*)m_object);
- m_object = object;
- Py_XINCREF((PyObject*)m_object);
- return *this;
+ if (!m_ob)
+ {
+ eDebug("invalid decref python object with null pointer %s %d!!!", file, line);
+ if (m_file)
+ eDebug("last modified in file %s line %d from %d to %d",
+ m_file, m_line, m_from, m_to);
+ bsodFatal("enigma2, refcnt");
+ }
+ if (m_erased || m_ob->ob_refcnt <= 0)
+ {
+ eDebug("invalid decref %s python object with refcounting value %d in file %s line %d!!!",
+ m_erased ? "deleted" : "undeleted", m_ob->ob_refcnt, file, line);
+ if (m_file)
+ eDebug("last modified in file %s line %d from %d to %d",
+ m_file, m_line, m_from, m_to);
+ bsodFatal("enigma2, refcnt");
+ }
+ m_file = file;
+ m_line = line;
+ m_from = m_ob->ob_refcnt;
+ m_to = m_from-1;
+ m_erased = !m_to;
+ Py_DECREF(m_ob);
}
-#endif
+#endif // PYTHON_REFCOUNT_DEBUG
+
+#define SKIP_PART1
+#include <lib/python/python.h>
+#undef SKIP_PART1
ePython::ePython()
{
- Py_Initialize();
+// Py_VerboseFlag = 1;
+// Py_OptimizeFlag = 1;
+
+ Py_Initialize();
+ PyEval_InitThreads();
+
init_enigma();
+ eBaseInit();
+ eConsoleInit();
}
ePython::~ePython()
Py_Finalize();
}
+int ePython::execFile(const char *file)
+{
+ FILE *fp = fopen(file, "r");
+ if (!fp)
+ return -ENOENT;
+ int ret = PyRun_SimpleFile(fp, file);
+ fclose(fp);
+ return ret;
+}
+
int ePython::execute(const std::string &pythonfile, const std::string &funcname)
{
- PyObject *pName, *pModule, *pDict, *pFunc, *pArgs, *pValue;
-
+ ePyObject pName, pModule, pDict, pFunc, pArgs, pValue;
pName = PyString_FromString(pythonfile.c_str());
-
+
pModule = PyImport_Import(pName);
Py_DECREF(pName);
- if (pModule != NULL)
+ if (pModule)
{
pDict = PyModule_GetDict(pModule);
// implement arguments..
pValue = PyObject_CallObject(pFunc, pArgs);
Py_DECREF(pArgs);
- if (pValue != NULL)
+ if (pValue)
{
printf("Result of call: %ld\n", PyInt_AsLong(pValue));
Py_DECREF(pValue);
return 0;
}
-int ePython::call(PyObject *pFunc, PyObject *pArgs)
+int ePython::call(ePyObject pFunc, ePyObject pArgs)
{
int res = -1;
- PyObject *pValue;
+ ePyObject pValue;
if (pFunc && PyCallable_Check(pFunc))
{
pValue = PyObject_CallObject(pFunc, pArgs);
- if (pValue != NULL)
+ if (pValue)
{
if (PyInt_Check(pValue))
res = PyInt_AsLong(pValue);
} else
{
PyErr_Print();
+ ePyObject FuncStr = PyObject_Str(pFunc);
+ ePyObject ArgStr = PyObject_Str(pArgs);
+ eDebug("(PyObject_CallObject(%s,%s) failed)", PyString_AS_STRING(FuncStr), PyString_AS_STRING(ArgStr));
+ Py_DECREF(FuncStr);
+ Py_DECREF(ArgStr);
+ bsodFatal(0);
}
}
return res;
}
-PyObject *ePython::resolve(const std::string &pythonfile, const std::string &funcname)
+ePyObject ePython::resolve(const std::string &pythonfile, const std::string &funcname)
{
- PyObject *pName, *pModule, *pDict, *pFunc;
+ ePyObject pName, pModule, pDict, pFunc;
pName = PyString_FromString(pythonfile.c_str());
pModule = PyImport_Import(pName);
Py_DECREF(pName);
- if (pModule != NULL)
+ if (pModule)
{
pDict = PyModule_GetDict(pModule);
pFunc = PyDict_GetItemString(pDict, funcname.c_str());
Py_XINCREF(pFunc);
Py_DECREF(pModule);
- eDebug("resolved to %p", pFunc);
- return pFunc;
- } else
- {
- if (PyErr_Occurred())
- PyErr_Print();
- return 0;
- }
+ } else if (PyErr_Occurred())
+ PyErr_Print();
+ return pFunc;
}