fix partial clipping for eListboxPythonMultiContent
[enigma2.git] / lib / python / python.cpp
index 2636a3d5fcf81a03d6fc8d9903a5228c7ff09c10..5ec07dff50d0b7e7d54aecb92c43d561b3c6a14f 100644 (file)
                 /* avoid warnigs :) */
 #undef _POSIX_C_SOURCE
 #define _POSIX_C_SOURCE 200112L
-#include <Python.h>
-
 extern "C" void init_enigma();
 extern void bsodFatal();
 
-void Impl_Py_DECREF(const char* file, int line, PyObject *obj)
+#define SKIP_PART2
+#include <lib/python/python.h>
+#undef SKIP_PART2
+
+#ifdef PYTHON_REFCOUNT_DEBUG
+ePyObject &ePyObject::operator=(PyObject *ob)
 {
-       if (!obj)
-       {
-               eDebug("decref python object null pointer %s %d!!!",
-                       file, line);
-               bsodFatal();
-       }
-       if (obj->ob_refcnt <= 0)
+       m_ob=ob;
+       m_file=0;
+       m_line=0;
+       m_from=m_to=0;
+       m_erased=false;
+       return *this;
+}
+
+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::operator PyObject*()
+{
+       if (m_ob)
        {
-               eDebug("decref python object with refcounting value %d (%s %d)!!!", obj->ob_refcnt, file, line);
+               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();
        }
-       Py_DECREF(obj);
+       return 0;
 }
 
-void Impl_Py_INCREF(const char* file, int line, PyObject *obj)
+void ePyObject::incref(const char *file, int line)
 {
-       if (!obj)
+       if (!m_ob)
        {
-               eDebug("incref python object null pointer %s %d!!!", file, line);
+               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();
        }
-       if (obj->ob_refcnt <= 0)
+       if (m_erased || m_ob->ob_refcnt <= 0)
        {
-               eDebug("incref python object with refcounting value %d (%s %d)!!!", obj->ob_refcnt, file, line);
+               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();
        }
-       if (obj->ob_refcnt == 0x7FFFFFFF)
+       if (m_ob->ob_refcnt == 0x7FFFFFFF)
        {
-               eDebug("incref python object with refcounting value %d (MAX_INT!!!) (%s %d)!!!", obj->ob_refcnt, file, line);
+               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();
        }
-       Py_INCREF(obj);
-}
-
-#include <lib/python/python.h>
-
-DEFINE_REF(TestObj);
-
-TestObj::TestObj()
-{
-       eDebug("create %p", this);
-}
-
-TestObj::~TestObj()
-{
-       eDebug("destroy %p", this);
-}
-
-#if 0
-ePyObject::ePyObject(void *ptr): m_object(ptr)
-{
-       Py_XINCREF((PyObject*)ptr);
+       m_file = file;
+       m_line = line;
+       m_from = m_ob->ob_refcnt;
+       m_to = m_from+1;
+       Py_INCREF(m_ob);
 }
 
-ePyObject::ePyObject(ePyObject &p)
+void ePyObject::decref(const char *file, int line)
 {
-       m_object = p.m_object;
-       Py_XINCREF((PyObject*)m_object);
-}
-
-ePyObject::ePyObject(): m_object(0)
-{
-}
-
-ePyObject::~ePyObject()
-{
-       Py_XDECREF((PyObject*)m_object);
-}
-
-ePyObject &ePyObject::operator=(ePyObject &p)
-{
-       Py_XDECREF((PyObject*)m_object);
-       m_object = p.m_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();
+       }
+       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();
+       }
+       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  // PYTHON_REFCOUNT_DEBUG
 
-ePyObject &ePyObject::operator=(void *object)
-{
-       Py_XDECREF((PyObject*)m_object);
-       m_object = object;
-       Py_XINCREF((PyObject*)m_object);
-       return *this;
-}
-#endif
+#define SKIP_PART1
+#include <lib/python/python.h>
+#undef SKIP_PART1
 
 ePython::ePython()
 {
@@ -102,7 +121,8 @@ ePython::ePython()
 //     Py_OptimizeFlag = 1;
        
        Py_Initialize();
-       
+       PyEval_InitThreads();
+
        init_enigma();
 }
 
@@ -113,13 +133,13 @@ ePython::~ePython()
 
 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);
                
@@ -131,7 +151,7 @@ int ePython::execute(const std::string &pythonfile, const std::string &funcname)
                                // 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);
@@ -151,14 +171,14 @@ int ePython::execute(const std::string &pythonfile, const std::string &funcname)
        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);
@@ -174,26 +194,22 @@ int ePython::call(PyObject *pFunc, PyObject *pArgs)
        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);
-               return pFunc;
-       } else
-       {
-               if (PyErr_Occurred())
-                       PyErr_Print();
-               return 0;
-       }
+       } else if (PyErr_Occurred())
+               PyErr_Print();
+       return pFunc;
 }