By Anders Holst: Improve custlist editor
[enigma2.git] / lib / python / python.cpp
1 #include <lib/base/eerror.h>
2                 /* avoid warnigs :) */
3 #undef _POSIX_C_SOURCE
4 #define _POSIX_C_SOURCE 200112L
5 extern "C" void init_enigma();
6 extern "C" void eBaseInit(void);
7 extern "C" void eConsoleInit(void);
8 extern void bsodFatal(const char *component);
9
10 #define SKIP_PART2
11 #include <lib/python/python.h>
12 #undef SKIP_PART2
13
14 #ifdef PYTHON_REFCOUNT_DEBUG
15 ePyObject &ePyObject::operator=(PyObject *ob)
16 {
17         m_ob=ob;
18         m_file=0;
19         m_line=0;
20         m_from=m_to=0;
21         m_erased=false;
22         return *this;
23 }
24
25 ePyObject &ePyObject::operator=(const ePyObject &ob)
26 {
27         m_ob=ob.m_ob;
28         m_file=ob.m_file;
29         m_line=ob.m_line;
30         m_from=ob.m_from;
31         m_to=ob.m_to;
32         m_erased=ob.m_erased;
33         return *this;
34 }
35
36 ePyObject::operator PyObject*()
37 {
38         if (m_ob)
39         {
40                 if (!m_erased && m_ob->ob_refcnt > 0)
41                         return m_ob;
42                 eDebug("invalid access PyObject %s with refcount <= 0 %d",
43                         m_erased ? "deleted" : "undeleted", m_ob->ob_refcnt);
44                 if (m_file)
45                         eDebug("last modified in file %s line %d from %d to %d",
46                                 m_file, m_line, m_from, m_to);
47                 bsodFatal("enigma2, refcnt");
48         }
49         return 0;
50 }
51
52 void ePyObject::incref(const char *file, int line)
53 {
54         if (!m_ob)
55         {
56                 eDebug("invalid incref python object with null pointer %s %d!!!", file, line);
57                 if (m_file)
58                         eDebug("last modified in file %s line %d from %d to %d",
59                                 m_file, m_line, m_from, m_to);
60                 bsodFatal("enigma2, refcnt");
61         }
62         if (m_erased || m_ob->ob_refcnt <= 0)
63         {
64                 eDebug("invalid incref %s python object with refcounting value %d in file %s line %d!!!",
65                         m_erased ? "deleted" : "undeleted", m_ob->ob_refcnt, file, line);
66                 if (m_file)
67                         eDebug("last modified in file %s line %d from %d to %d",
68                                 m_file, m_line, m_from, m_to);
69                 bsodFatal("enigma2, refcnt");
70         }
71         if (m_ob->ob_refcnt == 0x7FFFFFFF)
72         {
73                 eDebug("invalid incref %s python object with refcounting value %d (MAX_INT!!!) in file %s line %d!!!",
74                         m_erased ? "deleted" : "undeleted", m_ob->ob_refcnt, file, line);
75                 if (m_file)
76                         eDebug("last modified in file %s line %d from %d to %d",
77                                 m_file, m_line, m_from, m_to);
78                 bsodFatal("enigma2, refcnt");
79         }
80         m_file = file;
81         m_line = line;
82         m_from = m_ob->ob_refcnt;
83         m_to = m_from+1;
84         Py_INCREF(m_ob);
85 }
86
87 void ePyObject::decref(const char *file, int line)
88 {
89         if (!m_ob)
90         {
91                 eDebug("invalid decref python object with null pointer %s %d!!!", file, line);
92                 if (m_file)
93                         eDebug("last modified in file %s line %d from %d to %d",
94                                 m_file, m_line, m_from, m_to);
95                 bsodFatal("enigma2, refcnt");
96         }
97         if (m_erased || m_ob->ob_refcnt <= 0)
98         {
99                 eDebug("invalid decref %s python object with refcounting value %d in file %s line %d!!!",
100                         m_erased ? "deleted" : "undeleted", m_ob->ob_refcnt, file, line);
101                 if (m_file)
102                         eDebug("last modified in file %s line %d from %d to %d",
103                                 m_file, m_line, m_from, m_to);
104                 bsodFatal("enigma2, refcnt");
105         }
106         m_file = file;
107         m_line = line;
108         m_from = m_ob->ob_refcnt;
109         m_to = m_from-1;
110         m_erased = !m_to;
111         Py_DECREF(m_ob);
112 }
113 #endif  // PYTHON_REFCOUNT_DEBUG
114
115 #define SKIP_PART1
116 #include <lib/python/python.h>
117 #undef SKIP_PART1
118
119 ePython::ePython()
120 {
121 //      Py_VerboseFlag = 1;
122         
123 //      Py_OptimizeFlag = 1;
124         
125         Py_Initialize();
126         PyEval_InitThreads();
127
128         init_enigma();
129         eBaseInit();
130         eConsoleInit();
131 }
132
133 ePython::~ePython()
134 {
135         Py_Finalize();
136 }
137
138 int ePython::execFile(const char *file)
139 {
140         FILE *fp = fopen(file, "r");
141         if (!fp)
142                 return -ENOENT;
143         int ret = PyRun_SimpleFile(fp, file);
144         fclose(fp);
145         return ret;
146 }
147
148 int ePython::execute(const std::string &pythonfile, const std::string &funcname)
149 {
150         ePyObject pName, pModule, pDict, pFunc, pArgs, pValue;
151         pName = PyString_FromString(pythonfile.c_str());
152
153         pModule = PyImport_Import(pName);
154         Py_DECREF(pName);
155         
156         if (pModule)
157         {
158                 pDict = PyModule_GetDict(pModule);
159                 
160                 pFunc = PyDict_GetItemString(pDict, funcname.c_str());
161                 
162                 if (pFunc && PyCallable_Check(pFunc))
163                 {
164                         pArgs = PyTuple_New(0);
165                                 // implement arguments..
166                         pValue = PyObject_CallObject(pFunc, pArgs);
167                         Py_DECREF(pArgs);
168                         if (pValue)
169                         {
170                                 printf("Result of call: %ld\n", PyInt_AsLong(pValue));
171                                 Py_DECREF(pValue);
172                         } else
173                         {
174                                 Py_DECREF(pModule);
175                                 PyErr_Print();
176                                 return 1;
177                         }
178                 }
179         } else
180         {
181                 if (PyErr_Occurred())
182                         PyErr_Print();
183                 return 1;
184         }
185         return 0;
186 }
187
188 int ePython::call(ePyObject pFunc, ePyObject pArgs)
189 {
190         int res = -1;
191         ePyObject pValue;
192         if (pFunc && PyCallable_Check(pFunc))
193         {
194                 pValue = PyObject_CallObject(pFunc, pArgs);
195                 if (pValue)
196                 {
197                         if (PyInt_Check(pValue))
198                                 res = PyInt_AsLong(pValue);
199                         else
200                                 res = 0;
201                         Py_DECREF(pValue);
202                 } else
203                 {
204                         PyErr_Print();
205                         ePyObject FuncStr = PyObject_Str(pFunc);
206                         ePyObject ArgStr = PyObject_Str(pArgs);
207                         eDebug("(PyObject_CallObject(%s,%s) failed)", PyString_AS_STRING(FuncStr), PyString_AS_STRING(ArgStr));
208                         Py_DECREF(FuncStr);
209                         Py_DECREF(ArgStr);
210                         bsodFatal(0);
211                 }
212         }
213         return res;
214 }
215
216 ePyObject ePython::resolve(const std::string &pythonfile, const std::string &funcname)
217 {
218         ePyObject pName, pModule, pDict, pFunc;
219
220         pName = PyString_FromString(pythonfile.c_str());
221
222         pModule = PyImport_Import(pName);
223         Py_DECREF(pName);
224         
225         if (pModule)
226         {
227                 pDict = PyModule_GetDict(pModule);
228                 pFunc = PyDict_GetItemString(pDict, funcname.c_str());
229                 Py_XINCREF(pFunc);
230                 Py_DECREF(pModule);
231         } else if (PyErr_Occurred())
232                 PyErr_Print();
233         return pFunc;
234 }