Merge with 2.5 -r 21619:21756.
[blender.git] / source / blender / python / intern / bpy_util.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., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
19  *
20  * Contributor(s): Campbell Barton
21  *
22  * ***** END GPL LICENSE BLOCK *****
23  */
24
25 #include "DNA_listBase.h"
26 #include "RNA_access.h"
27 #include "bpy_util.h"
28 #include "bpy_rna.h"
29
30 #include "MEM_guardedalloc.h"
31
32 #include "BLI_dynstr.h"
33 #include "BLI_listbase.h"
34
35 #include "BKE_report.h"
36 #include "BKE_image.h"
37 #include "BKE_context.h"
38
39 bContext*       __py_context = NULL;
40 bContext*       BPy_GetContext(void) { return __py_context; };
41 void            BPy_SetContext(bContext *C) { __py_context= C; };
42
43
44 PyObject *BPY_flag_to_list(struct BPY_flag_def *flagdef, int flag)
45 {
46         PyObject *list = PyList_New(0);
47         
48         PyObject *item;
49         BPY_flag_def *fd;
50
51         fd= flagdef;
52         while(fd->name) {
53                 if (fd->flag & flag) {
54                         item = PyUnicode_FromString(fd->name);
55                         PyList_Append(list, item);
56                         Py_DECREF(item);
57                 }
58                 fd++;
59         }
60         
61         return list;
62
63 }
64
65 static char *bpy_flag_error_str(BPY_flag_def *flagdef)
66 {
67         BPY_flag_def *fd= flagdef;
68         DynStr *dynstr= BLI_dynstr_new();
69         char *cstring;
70
71         BLI_dynstr_append(dynstr, "Error converting a sequence of strings into a flag.\n\tExpected only these strings...\n\t");
72
73         while(fd->name) {
74                 BLI_dynstr_appendf(dynstr, fd!=flagdef?", '%s'":"'%s'", fd->name);
75                 fd++;
76         }
77         
78         cstring = BLI_dynstr_get_cstring(dynstr);
79         BLI_dynstr_free(dynstr);
80         return cstring;
81 }
82
83 int BPY_flag_from_seq(BPY_flag_def *flagdef, PyObject *seq, int *flag)
84 {
85         int i, error_val= 0;
86         char *cstring;
87         PyObject *item;
88         BPY_flag_def *fd;
89         *flag = 0;
90
91         if (PySequence_Check(seq)) {
92                 i= PySequence_Length(seq);
93
94                 while(i--) {
95                         item = PySequence_ITEM(seq, i);
96                         cstring= _PyUnicode_AsString(item);
97                         if(cstring) {
98                                 fd= flagdef;
99                                 while(fd->name) {
100                                         if (strcmp(cstring, fd->name) == 0)
101                                                 (*flag) |= fd->flag;
102                                         fd++;
103                                 }
104                                 if (fd==NULL) { /* could not find a match */
105                                         error_val= 1;
106                                 }
107                         } else {
108                                 error_val= 1;
109                         }
110                         Py_DECREF(item);
111                 }
112         }
113         else {
114                 error_val= 1;
115         }
116
117         if (*flag == 0)
118                 error_val = 1;
119
120         if (error_val) {
121                 char *buf = bpy_flag_error_str(flagdef);
122                 PyErr_SetString(PyExc_AttributeError, buf);
123                 MEM_freeN(buf);
124                 return -1; /* error value */
125         }
126
127         return 0; /* ok */
128 }
129
130
131 /* Copied from pythons 3's Object.c */
132 #ifndef Py_CmpToRich
133 PyObject *
134 Py_CmpToRich(int op, int cmp)
135 {
136         PyObject *res;
137         int ok;
138
139         if (PyErr_Occurred())
140                 return NULL;
141         switch (op) {
142         case Py_LT:
143                 ok = cmp <  0;
144                 break;
145         case Py_LE:
146                 ok = cmp <= 0;
147                 break;
148         case Py_EQ:
149                 ok = cmp == 0;
150                 break;
151         case Py_NE:
152                 ok = cmp != 0;
153                 break;
154         case Py_GT:
155                 ok = cmp >  0;
156                 break;
157         case Py_GE:
158                 ok = cmp >= 0;
159                 break;
160         default:
161                 PyErr_BadArgument();
162                 return NULL;
163         }
164         res = ok ? Py_True : Py_False;
165         Py_INCREF(res);
166         return res;
167 }
168 #endif
169
170 /* for debugging */
171 void PyObSpit(char *name, PyObject *var) {
172         fprintf(stderr, "<%s> : ", name);
173         if (var==NULL) {
174                 fprintf(stderr, "<NIL>");
175         }
176         else {
177                 PyObject_Print(var, stderr, 0);
178                 fprintf(stderr, " ref:%d ", var->ob_refcnt);
179                 fprintf(stderr, " ptr:%p", (void *)var);
180                 
181                 fprintf(stderr, " type:");
182                 if(Py_TYPE(var))
183                         fprintf(stderr, "%s", Py_TYPE(var)->tp_name);
184                 else
185                         fprintf(stderr, "<NIL>");
186         }
187         fprintf(stderr, "\n");
188 }
189
190 void PyLineSpit(void) {
191         char *filename;
192         int lineno;
193
194         PyErr_Clear();
195         BPY_getFileAndNum(&filename, &lineno);
196         
197         fprintf(stderr, "%s:%d\n", filename, lineno);
198 }
199
200 void BPY_getFileAndNum(char **filename, int *lineno)
201 {
202         PyObject *getframe, *frame;
203         PyObject *f_lineno= NULL, *co_filename= NULL;
204         
205         if (filename)   *filename= NULL;
206         if (lineno)             *lineno = -1;
207         
208         getframe = PySys_GetObject("_getframe"); // borrowed
209         if (getframe==NULL) {
210                 return;
211         }
212         
213         frame = PyObject_CallObject(getframe, NULL);
214         if (frame==NULL)
215                 return;
216         
217         if (filename) {
218                 co_filename= PyObject_GetAttrStringArgs(frame, 1, "f_code", "co_filename");
219                 if (co_filename==NULL) {
220                         PyErr_SetString(PyExc_SystemError, "Could not access sys._getframe().f_code.co_filename");
221                         Py_DECREF(frame);
222                         return;
223                 }
224                 
225                 *filename = _PyUnicode_AsString(co_filename);
226                 Py_DECREF(co_filename);
227         }
228         
229         if (lineno) {
230                 f_lineno= PyObject_GetAttrString(frame, "f_lineno");
231                 if (f_lineno==NULL) {
232                         PyErr_SetString(PyExc_SystemError, "Could not access sys._getframe().f_lineno");
233                         Py_DECREF(frame);
234                         return;
235                 }
236                 
237                 *lineno = (int)PyLong_AsSsize_t(f_lineno);
238                 Py_DECREF(f_lineno);
239         }
240
241         Py_DECREF(frame);
242 }
243
244 /* Would be nice if python had this built in */
245 PyObject *PyObject_GetAttrStringArgs(PyObject *o, Py_ssize_t n, ...)
246 {
247         Py_ssize_t i;
248         PyObject *item= o;
249         char *attr;
250         
251         va_list vargs;
252
253         va_start(vargs, n);
254         for (i=0; i<n; i++) {
255                 attr = va_arg(vargs, char *);
256                 item = PyObject_GetAttrString(item, attr);
257                 
258                 if (item) 
259                         Py_DECREF(item);
260                 else /* python will set the error value here */
261                         break;
262                 
263         }
264         va_end(vargs);
265         
266         Py_XINCREF(item); /* final value has is increfed, to match PyObject_GetAttrString */
267         return item;
268 }
269
270 int BPY_class_validate(const char *class_type, PyObject *class, PyObject *base_class, BPY_class_attr_check* class_attrs, PyObject **py_class_attrs)
271 {
272         PyObject *item, *fitem;
273         PyObject *py_arg_count;
274         int i, arg_count;
275
276         if (base_class) {
277                 if (!PyObject_IsSubclass(class, base_class)) {
278                         PyObject *name= PyObject_GetAttrString(base_class, "__name__");
279                         PyErr_Format( PyExc_AttributeError, "expected %s subclass of class \"%s\"", class_type, name ? _PyUnicode_AsString(name):"<UNKNOWN>");
280                         Py_XDECREF(name);
281                         return -1;
282                 }
283         }
284         
285         for(i= 0;class_attrs->name; class_attrs++, i++) {
286                 item = PyObject_GetAttrString(class, class_attrs->name);
287
288                 if (py_class_attrs)
289                         py_class_attrs[i]= item;
290                 
291                 if (item==NULL) {
292                         if ((class_attrs->flag & BPY_CLASS_ATTR_OPTIONAL)==0) {
293                                 PyErr_Format( PyExc_AttributeError, "expected %s class to have an \"%s\" attribute", class_type, class_attrs->name);
294                                 return -1;
295                         }
296
297                         PyErr_Clear();
298                 }
299                 else {
300                         Py_DECREF(item); /* no need to keep a ref, the class owns it */
301
302                         if((item==Py_None) && (class_attrs->flag & BPY_CLASS_ATTR_NONE_OK)) {
303                                 /* dont do anything, this is ok, dont bother checking other types */
304                         }
305                         else {
306                                 switch(class_attrs->type) {
307                                 case 's':
308                                         if (PyUnicode_Check(item)==0) {
309                                                 PyErr_Format( PyExc_AttributeError, "expected %s class \"%s\" attribute to be a string", class_type, class_attrs->name);
310                                                 return -1;
311                                         }
312                                         if(class_attrs->len != -1 && class_attrs->len < PyUnicode_GetSize(item)) {
313                                                 PyErr_Format( PyExc_AttributeError, "expected %s class \"%s\" attribute string to be shorter then %d", class_type, class_attrs->name, class_attrs->len);
314                                                 return -1;
315                                         }
316
317                                         break;
318                                 case 'l':
319                                         if (PyList_Check(item)==0) {
320                                                 PyErr_Format( PyExc_AttributeError, "expected %s class \"%s\" attribute to be a list", class_type, class_attrs->name);
321                                                 return -1;
322                                         }
323                                         if(class_attrs->len != -1 && class_attrs->len < PyList_GET_SIZE(item)) {
324                                                 PyErr_Format( PyExc_AttributeError, "expected %s class \"%s\" attribute list to be shorter then %d", class_type, class_attrs->name, class_attrs->len);
325                                                 return -1;
326                                         }
327                                         break;
328                                 case 'f':
329                                         if (PyMethod_Check(item))
330                                                 fitem= PyMethod_Function(item); /* py 2.x */
331                                         else
332                                                 fitem= item; /* py 3.x */
333
334                                         if (PyFunction_Check(fitem)==0) {
335                                                 PyErr_Format( PyExc_AttributeError, "expected %s class \"%s\" attribute to be a function", class_type, class_attrs->name);
336                                                 return -1;
337                                         }
338                                         if (class_attrs->arg_count >= 0) { /* -1 if we dont care*/
339                                                 py_arg_count = PyObject_GetAttrString(PyFunction_GET_CODE(fitem), "co_argcount");
340                                                 arg_count = PyLong_AsSsize_t(py_arg_count);
341                                                 Py_DECREF(py_arg_count);
342
343                                                 if (arg_count != class_attrs->arg_count) {
344                                                         PyErr_Format( PyExc_AttributeError, "expected %s class \"%s\" function to have %d args", class_type, class_attrs->name, class_attrs->arg_count);
345                                                         return -1;
346                                                 }
347                                         }
348                                         break;
349                                 }
350                         }
351                 }
352         }
353         return 0;
354 }
355
356
357
358 /* returns the exception string as a new PyUnicode object, depends on external StringIO module */
359 PyObject *BPY_exception_buffer(void)
360 {
361         PyObject *stdout_backup = PySys_GetObject("stdout"); /* borrowed */
362         PyObject *stderr_backup = PySys_GetObject("stderr"); /* borrowed */
363         PyObject *string_io = NULL;
364         PyObject *string_io_buf = NULL;
365         PyObject *string_io_mod= NULL;
366         PyObject *string_io_getvalue= NULL;
367         
368         PyObject *error_type, *error_value, *error_traceback;
369         
370         if (!PyErr_Occurred())
371                 return NULL;
372         
373         PyErr_Fetch(&error_type, &error_value, &error_traceback);
374         
375         PyErr_Clear();
376         
377         /* import StringIO / io
378          * string_io = StringIO.StringIO()
379          */
380         
381 #if PY_VERSION_HEX < 0x03000000
382         if(! (string_io_mod= PyImport_ImportModule("StringIO")) ) {
383 #else
384         if(! (string_io_mod= PyImport_ImportModule("io")) ) {
385 #endif
386                 goto error_cleanup;
387         } else if (! (string_io = PyObject_CallMethod(string_io_mod, "StringIO", NULL))) {
388                 goto error_cleanup;
389         } else if (! (string_io_getvalue= PyObject_GetAttrString(string_io, "getvalue"))) {
390                 goto error_cleanup;
391         }
392         
393         Py_INCREF(stdout_backup); // since these were borrowed we dont want them freed when replaced.
394         Py_INCREF(stderr_backup);
395         
396         PySys_SetObject("stdout", string_io); // both of these are free'd when restoring
397         PySys_SetObject("stderr", string_io);
398         
399         PyErr_Restore(error_type, error_value, error_traceback);
400         PyErr_Print(); /* print the error */
401         PyErr_Clear();
402         
403         string_io_buf = PyObject_CallObject(string_io_getvalue, NULL);
404         
405         PySys_SetObject("stdout", stdout_backup);
406         PySys_SetObject("stderr", stderr_backup);
407         
408         Py_DECREF(stdout_backup); /* now sys owns the ref again */
409         Py_DECREF(stderr_backup);
410         
411         Py_DECREF(string_io_mod);
412         Py_DECREF(string_io_getvalue);
413         Py_DECREF(string_io); /* free the original reference */
414         
415         PyErr_Clear();
416         return string_io_buf;
417         
418         
419 error_cleanup:
420         /* could not import the module so print the error and close */
421         Py_XDECREF(string_io_mod);
422         Py_XDECREF(string_io);
423         
424         PyErr_Restore(error_type, error_value, error_traceback);
425         PyErr_Print(); /* print the error */
426         PyErr_Clear();
427         
428         return NULL;
429 }
430
431 char *BPy_enum_as_string(EnumPropertyItem *item)
432 {
433         DynStr *dynstr= BLI_dynstr_new();
434         EnumPropertyItem *e;
435         char *cstring;
436
437         for (e= item; item->identifier; item++) {
438                 if(item->identifier[0])
439                         BLI_dynstr_appendf(dynstr, (e==item)?"'%s'":", '%s'", item->identifier);
440         }
441
442         cstring = BLI_dynstr_get_cstring(dynstr);
443         BLI_dynstr_free(dynstr);
444         return cstring;
445 }
446
447 int BPy_reports_to_error(ReportList *reports)
448 {
449         char *report_str;
450
451         report_str= BKE_reports_string(reports, RPT_ERROR);
452
453         if(report_str) {
454                 PyErr_SetString(PyExc_SystemError, report_str);
455                 MEM_freeN(report_str);
456         }
457
458         return (report_str != NULL);
459 }
460
461
462 int BPy_errors_to_report(ReportList *reports)
463 {
464         PyObject *pystring;
465         char *cstring;
466         
467         if (!PyErr_Occurred())
468                 return 1;
469         
470         /* less hassle if we allow NULL */
471         if(reports==NULL) {
472                 PyErr_Print();
473                 PyErr_Clear();
474                 return 1;
475         }
476         
477         pystring= BPY_exception_buffer();
478         
479         if(pystring==NULL) {
480                 BKE_report(reports, RPT_ERROR, "unknown py-exception, could not convert");
481                 return 0;
482         }
483         
484         cstring= _PyUnicode_AsString(pystring);
485         
486         BKE_report(reports, RPT_ERROR, cstring);
487         fprintf(stderr, "%s\n", cstring); // not exactly needed. just for testing
488         Py_DECREF(pystring);
489         return 1;
490 }
491
492
493 /* bpy.util module */
494 static PyObject *bpy_util_copy_images(PyObject *self, PyObject *args);
495
496 struct PyMethodDef bpy_util_methods[] = {
497         {"copy_images", bpy_util_copy_images, METH_VARARGS, NULL},
498         {NULL, NULL, 0, NULL}
499 };
500
501 #if PY_VERSION_HEX >= 0x03000000
502 static struct PyModuleDef bpy_util_module = {
503         PyModuleDef_HEAD_INIT,
504         "bpyutil",
505         NULL,
506         -1,
507         bpy_util_methods,
508         NULL, NULL, NULL, NULL
509 };
510 #endif
511
512 PyObject *BPY_util_module( void )
513 {
514         PyObject *submodule, *dict;
515
516 #if PY_VERSION_HEX >= 0x03000000
517         submodule= PyModule_Create(&bpy_util_module);
518 #else /* Py2.x */
519         submodule= Py_InitModule3("bpyutil", bpy_util_methods, NULL);
520 #endif
521
522         dict = PyModule_GetDict(submodule);
523         
524         return submodule;
525 }
526
527 /*
528   copy_images(images, dest_dir)
529   return filenames
530 */
531 static PyObject *bpy_util_copy_images(PyObject *self, PyObject *args)
532 {
533         const char *dest_dir;
534         ListBase *images;
535         ListBase *paths;
536         LinkData *link;
537         PyObject *seq;
538         PyObject *ret;
539         PyObject *item;
540         int i;
541         int len;
542
543         /* check args/types */
544         if (!PyArg_ParseTuple(args, "Os", &seq, &dest_dir)) {
545                 PyErr_SetString(PyExc_TypeError, "Invalid arguments.");
546                 return NULL;
547         }
548
549         /* expecting a sequence of Image objects */
550         if (!PySequence_Check(seq)) {
551                 PyErr_SetString(PyExc_TypeError, "Expected a sequence of images.");
552                 return NULL;
553         }
554
555         /* create image list */
556         len= PySequence_Size(seq);
557
558         if (!len) {
559                 PyErr_SetString(PyExc_TypeError, "At least one image should be specified.");
560                 return NULL;
561         }
562
563         /* make sure all sequence items are Image */
564         for(i= 0; i < len; i++) {
565                 item= PySequence_GetItem(seq, i);
566
567                 if (!BPy_StructRNA_Check(item) || ((BPy_StructRNA*)item)->ptr.type != &RNA_Image) {
568                         PyErr_SetString(PyExc_TypeError, "Expected a sequence of Image objects.");
569                         return NULL;
570                 }
571         }
572
573         images= MEM_callocN(sizeof(*images), "ListBase of images");
574
575         for(i= 0; i < len; i++) {
576                 BPy_StructRNA* srna;
577
578                 item= PySequence_GetItem(seq, i);
579                 srna= (BPy_StructRNA*)item;
580
581                 link= MEM_callocN(sizeof(LinkData), "LinkData image");
582                 link->data= srna->ptr.data;
583                 BLI_addtail(images, link);
584
585                 Py_DECREF(item);
586         }
587
588         paths= MEM_callocN(sizeof(*paths), "ListBase of image paths");
589
590         /* call BKE_copy_images */
591         BKE_copy_images(images, dest_dir, paths);
592
593         /* convert filenames */
594         ret= PyList_New(0);
595
596         for(link= paths->first; link; link= link->next) {
597                 if (link->data) {
598                         item= PyUnicode_FromString(link->data);
599                         PyList_Append(ret, item);
600                         Py_DECREF(item);
601                 }
602                 else {
603                         PyList_Append(ret, Py_None);
604                 }
605         }
606
607         /* free memory */
608         BLI_freelistN(images);
609         BLI_freelistN(paths);
610
611         /* return filenames */
612         return ret;
613 }