bec3a07d32a30618e3b95dff709f2fc4fe1737f2
[blender.git] / source / blender / python / intern / bpy_util.c
1 /*
2  * ***** BEGIN GPL LICENSE BLOCK *****
3  *
4  * This program is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU General Public License
6  * as published by the Free Software Foundation; either version 2
7  * of the License, or (at your option) any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write to the Free Software Foundation,
16  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17  *
18  * Contributor(s): Campbell Barton
19  *
20  * ***** END GPL LICENSE BLOCK *****
21  */
22
23 /** \file blender/python/intern/bpy_util.c
24  *  \ingroup pythonintern
25  */
26
27
28 #include <Python.h>
29
30 #include "bpy_util.h"
31 #include "BLI_dynstr.h"
32 #include "MEM_guardedalloc.h"
33 #include "BKE_report.h"
34 #include "BKE_context.h"
35
36 #include "../generic/py_capi_utils.h"
37
38 static bContext*        __py_context= NULL;
39 bContext*       BPy_GetContext(void) { return __py_context; }
40 void            BPy_SetContext(bContext *C) { __py_context= C; }
41
42 char *BPy_enum_as_string(EnumPropertyItem *item)
43 {
44         DynStr *dynstr= BLI_dynstr_new();
45         EnumPropertyItem *e;
46         char *cstring;
47
48         for (e= item; item->identifier; item++) {
49                 if (item->identifier[0])
50                         BLI_dynstr_appendf(dynstr, (e==item)?"'%s'":", '%s'", item->identifier);
51         }
52
53         cstring= BLI_dynstr_get_cstring(dynstr);
54         BLI_dynstr_free(dynstr);
55         return cstring;
56 }
57
58 short BPy_reports_to_error(ReportList *reports, PyObject *exception, const short clear)
59 {
60         char *report_str;
61
62         report_str= BKE_reports_string(reports, RPT_ERROR);
63
64         if (clear) {
65                 BKE_reports_clear(reports);
66         }
67
68         if (report_str) {
69                 PyErr_SetString(exception, report_str);
70                 MEM_freeN(report_str);
71         }
72
73         return (report_str == NULL) ? 0 : -1;
74 }
75
76
77 short BPy_errors_to_report(ReportList *reports)
78 {
79         PyObject *pystring;
80         PyObject *pystring_format= NULL; // workaround, see below
81         char *cstring;
82
83         const char *filename;
84         int lineno;
85
86         if (!PyErr_Occurred())
87                 return 1;
88         
89         /* less hassle if we allow NULL */
90         if (reports==NULL) {
91                 PyErr_Print();
92                 PyErr_Clear();
93                 return 1;
94         }
95         
96         pystring= PyC_ExceptionBuffer();
97         
98         if (pystring==NULL) {
99                 BKE_report(reports, RPT_ERROR, "unknown py-exception, couldn't convert");
100                 return 0;
101         }
102         
103         PyC_FileAndNum(&filename, &lineno);
104         if (filename==NULL)
105                 filename= "<unknown location>";
106         
107         cstring= _PyUnicode_AsString(pystring);
108
109 #if 0 // ARG!. workaround for a bug in blenders use of vsnprintf
110         BKE_reportf(reports, RPT_ERROR, "%s\nlocation:%s:%d\n", cstring, filename, lineno);
111 #else
112         pystring_format= PyUnicode_FromFormat("%s\nlocation:%s:%d\n", cstring, filename, lineno);
113         cstring= _PyUnicode_AsString(pystring_format);
114         BKE_report(reports, RPT_ERROR, cstring);
115 #endif
116         
117         fprintf(stderr, "%s\nlocation:%s:%d\n", cstring, filename, lineno); // not exactly needed. just for testing
118         
119         Py_DECREF(pystring);
120         Py_DECREF(pystring_format); // workaround
121         return 1;
122 }