ed24c164921db8623370f71fd36ccb9af367f20d
[blender.git] / source / blender / python / generic / py_capi_utils.c
1 /*
2  * $Id$
3  *
4  * ***** BEGIN GPL LICENSE BLOCK *****
5  *
6  * This program is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU General Public License
8  * as published by the Free Software Foundation; either version 2
9  * of the License, or (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, write to the Free Software Foundation,
18  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
19  *
20  * ***** END GPL LICENSE BLOCK *****
21 */
22
23 /** \file blender/python/generic/py_capi_utils.c
24  *  \ingroup pygen
25  */
26
27
28 #include <Python.h>
29 #include <frameobject.h>
30
31 #include "py_capi_utils.h"
32
33 /* for debugging */
34 void PyC_ObSpit(const char *name, PyObject *var) {
35         fprintf(stderr, "<%s> : ", name);
36         if (var==NULL) {
37                 fprintf(stderr, "<NIL>");
38         }
39         else {
40                 PyObject_Print(var, stderr, 0);
41                 fprintf(stderr, " ref:%d ", (int)var->ob_refcnt);
42                 fprintf(stderr, " ptr:%p", (void *)var);
43                 
44                 fprintf(stderr, " type:");
45                 if(Py_TYPE(var))
46                         fprintf(stderr, "%s", Py_TYPE(var)->tp_name);
47                 else
48                         fprintf(stderr, "<NIL>");
49         }
50         fprintf(stderr, "\n");
51 }
52
53 void PyC_LineSpit(void) {
54         const char *filename;
55         int lineno;
56
57         PyErr_Clear();
58         PyC_FileAndNum(&filename, &lineno);
59         
60         fprintf(stderr, "%s:%d\n", filename, lineno);
61 }
62
63 /* python 3.2 only, copied from frameobjec.c */
64 #if PY_VERSION_HEX <  0x03020000
65 int
66 PyFrame_GetLineNumber(PyFrameObject *f)
67 {
68     if (f->f_trace)
69         return f->f_lineno;
70     else
71         return PyCode_Addr2Line(f->f_code, f->f_lasti);
72 }
73 #endif
74
75 void PyC_FileAndNum(const char **filename, int *lineno)
76 {
77         PyFrameObject *frame;
78         
79         if (filename)   *filename= NULL;
80         if (lineno)             *lineno = -1;
81
82         if (!(frame= PyThreadState_GET()->frame)) {
83                 return;
84         }
85
86         /* when executing a script */
87         if (filename) {
88                 *filename = _PyUnicode_AsString(frame->f_code->co_filename);
89         }
90
91         /* when executing a module */
92         if(filename && *filename == NULL) {
93                 /* try an alternative method to get the filename - module based
94                  * references below are all borrowed (double checked) */
95                 PyObject *mod_name= PyDict_GetItemString(PyEval_GetGlobals(), "__name__");
96                 if(mod_name) {
97                         PyObject *mod= PyDict_GetItem(PyImport_GetModuleDict(), mod_name);
98                         if(mod) {
99                                 *filename= PyModule_GetFilename(mod);
100                         }
101
102                         /* unlikely, fallback */
103                         if(*filename == NULL) {
104                                 *filename= _PyUnicode_AsString(mod_name);
105                         }
106                 }
107         }
108
109         if (lineno) {
110                 *lineno = PyFrame_GetLineNumber(frame);
111         }
112 }
113
114 /* Would be nice if python had this built in */
115 PyObject *PyC_Object_GetAttrStringArgs(PyObject *o, Py_ssize_t n, ...)
116 {
117         Py_ssize_t i;
118         PyObject *item= o;
119         char *attr;
120         
121         va_list vargs;
122
123         va_start(vargs, n);
124         for (i=0; i<n; i++) {
125                 attr = va_arg(vargs, char *);
126                 item = PyObject_GetAttrString(item, attr);
127                 
128                 if (item) 
129                         Py_DECREF(item);
130                 else /* python will set the error value here */
131                         break;
132                 
133         }
134         va_end(vargs);
135         
136         Py_XINCREF(item); /* final value has is increfed, to match PyObject_GetAttrString */
137         return item;
138 }
139
140 /* returns the exception string as a new PyUnicode object, depends on external StringIO module */
141 PyObject *PyC_ExceptionBuffer(void)
142 {
143         PyObject *stdout_backup = PySys_GetObject("stdout"); /* borrowed */
144         PyObject *stderr_backup = PySys_GetObject("stderr"); /* borrowed */
145         PyObject *string_io = NULL;
146         PyObject *string_io_buf = NULL;
147         PyObject *string_io_mod= NULL;
148         PyObject *string_io_getvalue= NULL;
149         
150         PyObject *error_type, *error_value, *error_traceback;
151         
152         if (!PyErr_Occurred())
153                 return NULL;
154         
155         PyErr_Fetch(&error_type, &error_value, &error_traceback);
156         
157         PyErr_Clear();
158         
159         /* import io
160          * string_io = io.StringIO()
161          */
162         
163         if(! (string_io_mod= PyImport_ImportModule("io")) ) {
164                 goto error_cleanup;
165         } else if (! (string_io = PyObject_CallMethod(string_io_mod, (char *)"StringIO", NULL))) {
166                 goto error_cleanup;
167         } else if (! (string_io_getvalue= PyObject_GetAttrString(string_io, "getvalue"))) {
168                 goto error_cleanup;
169         }
170         
171         Py_INCREF(stdout_backup); // since these were borrowed we dont want them freed when replaced.
172         Py_INCREF(stderr_backup);
173         
174         PySys_SetObject("stdout", string_io); // both of these are free'd when restoring
175         PySys_SetObject("stderr", string_io);
176         
177         PyErr_Restore(error_type, error_value, error_traceback);
178         PyErr_Print(); /* print the error */
179         PyErr_Clear();
180         
181         string_io_buf = PyObject_CallObject(string_io_getvalue, NULL);
182         
183         PySys_SetObject("stdout", stdout_backup);
184         PySys_SetObject("stderr", stderr_backup);
185         
186         Py_DECREF(stdout_backup); /* now sys owns the ref again */
187         Py_DECREF(stderr_backup);
188         
189         Py_DECREF(string_io_mod);
190         Py_DECREF(string_io_getvalue);
191         Py_DECREF(string_io); /* free the original reference */
192         
193         PyErr_Clear();
194         return string_io_buf;
195         
196         
197 error_cleanup:
198         /* could not import the module so print the error and close */
199         Py_XDECREF(string_io_mod);
200         Py_XDECREF(string_io);
201         
202         PyErr_Restore(error_type, error_value, error_traceback);
203         PyErr_Print(); /* print the error */
204         PyErr_Clear();
205         
206         return NULL;
207 }
208
209
210 /* string conversion, escape non-unicode chars, coerce must be set to NULL */
211 const char *PyC_UnicodeAsByte(PyObject *py_str, PyObject **coerce)
212 {
213         char *result;
214
215         result= _PyUnicode_AsString(py_str);
216
217         if(result) {
218                 /* 99% of the time this is enough but we better support non unicode
219                  * chars since blender doesnt limit this */
220                 return result;
221         }
222         else if(PyBytes_Check(py_str)) {
223                 PyErr_Clear();
224                 return PyBytes_AS_STRING(py_str);
225         }
226         else {
227                 /* mostly copied from fileio.c's, fileio_init */
228                 PyObject *stringobj;
229                 PyObject *u;
230
231                 PyErr_Clear();
232                 
233                 u= PyUnicode_FromObject(py_str); /* coerce into unicode */
234                 
235                 if (u == NULL)
236                         return NULL;
237
238                 stringobj= PyUnicode_EncodeUTF8(PyUnicode_AS_UNICODE(u), PyUnicode_GET_SIZE(u), "surrogateescape");
239                 Py_DECREF(u);
240                 if (stringobj == NULL)
241                         return NULL;
242                 if (!PyBytes_Check(stringobj)) { /* this seems wrong but it works fine */
243                         // printf("encoder failed to return bytes\n");
244                         Py_DECREF(stringobj);
245                         return NULL;
246                 }
247                 *coerce= stringobj;
248
249                 return PyBytes_AS_STRING(stringobj);
250         }
251 }
252
253 PyObject *PyC_UnicodeFromByte(const char *str)
254 {
255         PyObject *result= PyUnicode_FromString(str);
256         if(result) {
257                 /* 99% of the time this is enough but we better support non unicode
258                  * chars since blender doesnt limit this */
259                 return result;
260         }
261         else {
262                 PyErr_Clear();
263                 /* this means paths will always be accessible once converted, on all OS's */
264                 result= PyUnicode_DecodeFSDefault(str);
265                 return result;
266         }
267 }
268
269 /*****************************************************************************
270 * Description: This function creates a new Python dictionary object.
271 * note: dict is owned by sys.modules["__main__"] module, reference is borrowed
272 * note: important we use the dict from __main__, this is what python expects
273   for 'pickle' to work as well as strings like this...
274  >> foo = 10
275  >> print(__import__("__main__").foo)
276 *
277 * note: this overwrites __main__ which gives problems with nested calles.
278 * be sure to run PyC_MainModule_Backup & PyC_MainModule_Restore if there is
279 * any chance that python is in the call stack.
280 *****************************************************************************/
281 PyObject *PyC_DefaultNameSpace(const char *filename)
282 {
283         PyInterpreterState *interp= PyThreadState_GET()->interp;
284         PyObject *mod_main= PyModule_New("__main__");   
285         PyDict_SetItemString(interp->modules, "__main__", mod_main);
286         Py_DECREF(mod_main); /* sys.modules owns now */
287         PyModule_AddStringConstant(mod_main, "__name__", "__main__");
288         if(filename)
289                 PyModule_AddStringConstant(mod_main, "__file__", filename); /* __file__ only for nice UI'ness */
290         PyModule_AddObject(mod_main, "__builtins__", interp->builtins);
291         Py_INCREF(interp->builtins); /* AddObject steals a reference */
292         return PyModule_GetDict(mod_main);
293 }
294
295 /* restore MUST be called after this */
296 void PyC_MainModule_Backup(PyObject **main_mod)
297 {
298         PyInterpreterState *interp= PyThreadState_GET()->interp;
299         *main_mod= PyDict_GetItemString(interp->modules, "__main__");
300         Py_XINCREF(*main_mod); /* dont free */
301 }
302
303 void PyC_MainModule_Restore(PyObject *main_mod)
304 {
305         PyInterpreterState *interp= PyThreadState_GET()->interp;
306         PyDict_SetItemString(interp->modules, "__main__", main_mod);
307         Py_XDECREF(main_mod);
308 }
309
310 /* Would be nice if python had this built in */
311 void PyC_RunQuicky(const char *filepath, int n, ...)
312 {
313         FILE *fp= fopen(filepath, "r");
314
315         if(fp) {
316                 PyGILState_STATE gilstate= PyGILState_Ensure();
317
318                 va_list vargs;  
319
320                 int *sizes= PyMem_MALLOC(sizeof(int) * (n / 2));
321                 int i;
322
323                 PyObject *py_dict = PyC_DefaultNameSpace(filepath);
324                 PyObject *values= PyList_New(n / 2); /* namespace owns this, dont free */
325
326                 PyObject *py_result, *ret;
327
328                 PyObject *struct_mod= PyImport_ImportModule("struct");
329                 PyObject *calcsize= PyObject_GetAttrString(struct_mod, "calcsize"); /* struct.calcsize */
330                 PyObject *pack= PyObject_GetAttrString(struct_mod, "pack"); /* struct.pack */
331                 PyObject *unpack= PyObject_GetAttrString(struct_mod, "unpack"); /* struct.unpack */
332
333                 Py_DECREF(struct_mod);
334
335                 va_start(vargs, n);
336                 for (i=0; i * 2<n; i++) {
337                         char *format = va_arg(vargs, char *);
338                         void *ptr = va_arg(vargs, void *);
339
340                         ret= PyObject_CallFunction(calcsize, (char *)"s", format);
341
342                         if(ret) {
343                                 sizes[i]= PyLong_AsSsize_t(ret);
344                                 Py_DECREF(ret);
345                                 ret = PyObject_CallFunction(unpack, (char *)"sy#", format, (char *)ptr, sizes[i]);
346                         }
347
348                         if(ret == NULL) {
349                                 printf("PyC_InlineRun error, line:%d\n", __LINE__);
350                                 PyErr_Print();
351                                 PyErr_Clear();
352
353                                 PyList_SET_ITEM(values, i, Py_None); /* hold user */
354                                 Py_INCREF(Py_None);
355
356                                 sizes[i]= 0;
357                         }
358                         else {
359                                 if(PyTuple_GET_SIZE(ret) == 1) {
360                                         /* convenience, convert single tuples into single values */
361                                         PyObject *tmp= PyTuple_GET_ITEM(ret, 0);
362                                         Py_INCREF(tmp);
363                                         Py_DECREF(ret);
364                                         ret = tmp;
365                                 }
366
367                                 PyList_SET_ITEM(values, i, ret); /* hold user */
368                         }
369                 }
370                 va_end(vargs);
371                 
372                 /* set the value so we can access it */
373                 PyDict_SetItemString(py_dict, "values", values);
374
375                 py_result = PyRun_File(fp, filepath, Py_file_input, py_dict, py_dict);
376
377                 fclose(fp);
378
379                 if(py_result) {
380
381                         /* we could skip this but then only slice assignment would work
382                          * better not be so strict */
383                         values= PyDict_GetItemString(py_dict, "values");
384
385                         if(values && PyList_Check(values)) {
386
387                                 /* dont use the result */
388                                 Py_DECREF(py_result);
389                                 py_result= NULL;
390
391                                 /* now get the values back */
392                                 va_start(vargs, n);
393                                 for (i=0; i*2 <n; i++) {
394                                         char *format = va_arg(vargs, char *);
395                                         void *ptr = va_arg(vargs, void *);
396                                         
397                                         PyObject *item;
398                                         PyObject *item_new;
399                                         /* prepend the string formatting and remake the tuple */
400                                         item= PyList_GET_ITEM(values, i);
401                                         if(PyTuple_CheckExact(item)) {
402                                                 int ofs= PyTuple_GET_SIZE(item);
403                                                 item_new= PyTuple_New(ofs + 1);
404                                                 while(ofs--) {
405                                                         PyObject *member= PyTuple_GET_ITEM(item, ofs);
406                                                         PyTuple_SET_ITEM(item_new, ofs + 1, member);
407                                                         Py_INCREF(member);
408                                                 }
409
410                                                 PyTuple_SET_ITEM(item_new, 0, PyUnicode_FromString(format));
411                                         }
412                                         else {
413                                                 item_new= Py_BuildValue("sO", format, item);
414                                         }
415
416                                         ret = PyObject_Call(pack, item_new, NULL);
417
418                                         if(ret) {
419                                                 /* copy the bytes back into memory */
420                                                 memcpy(ptr, PyBytes_AS_STRING(ret), sizes[i]);
421                                                 Py_DECREF(ret);
422                                         }
423                                         else {
424                                                 printf("PyC_InlineRun error on arg '%d', line:%d\n", i, __LINE__);
425                                                 PyC_ObSpit("failed converting:", item_new);
426                                                 PyErr_Print();
427                                                 PyErr_Clear();
428                                         }
429
430                                         Py_DECREF(item_new);
431                                 }
432                                 va_end(vargs);
433                         }
434                         else {
435                                 printf("PyC_InlineRun error, 'values' not a list, line:%d\n", __LINE__);
436                         }
437                 }
438                 else {
439                         printf("PyC_InlineRun error line:%d\n", __LINE__);
440                         PyErr_Print();
441                         PyErr_Clear();
442                 }
443
444                 Py_DECREF(calcsize);
445                 Py_DECREF(pack);
446                 Py_DECREF(unpack);
447
448                 PyMem_FREE(sizes);
449
450                 PyGILState_Release(gilstate);
451         }
452 }