cleanup: collada: removed unused public class variable
[blender.git] / source / blender / blenkernel / intern / report.c
1 /*
2  * This program is free software; you can redistribute it and/or
3  * modify it under the terms of the GNU General Public License
4  * as published by the Free Software Foundation; either version 2
5  * of the License, or (at your option) any later version.
6  *
7  * This program is distributed in the hope that it will be useful,
8  * but WITHOUT ANY WARRANTY; without even the implied warranty of
9  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
10  * GNU General Public License for more details.
11  *
12  * You should have received a copy of the GNU General Public License
13  * along with this program; if not, write to the Free Software Foundation,
14  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
15  *
16  * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
17  * All rights reserved.
18  */
19
20 /** \file
21  * \ingroup bke
22  */
23
24 #include <stdarg.h>
25 #include <stdio.h>
26 #include <string.h>
27 #include <errno.h>
28
29 #include "MEM_guardedalloc.h"
30
31 #include "BLI_blenlib.h"
32 #include "BLI_dynstr.h"
33 #include "BLI_utildefines.h"
34
35 #include "BLT_translation.h"
36
37 #include "BKE_report.h"
38 #include "BKE_global.h" /* G.background only */
39
40 const char *BKE_report_type_str(ReportType type)
41 {
42   switch (type) {
43     case RPT_DEBUG:
44       return TIP_("Debug");
45     case RPT_INFO:
46       return TIP_("Info");
47     case RPT_OPERATOR:
48       return TIP_("Operator");
49     case RPT_PROPERTY:
50       return TIP_("Property");
51     case RPT_WARNING:
52       return TIP_("Warning");
53     case RPT_ERROR:
54       return TIP_("Error");
55     case RPT_ERROR_INVALID_INPUT:
56       return TIP_("Invalid Input Error");
57     case RPT_ERROR_INVALID_CONTEXT:
58       return TIP_("Invalid Context Error");
59     case RPT_ERROR_OUT_OF_MEMORY:
60       return TIP_("Out Of Memory Error");
61     default:
62       return TIP_("Undefined Type");
63   }
64 }
65
66 void BKE_reports_init(ReportList *reports, int flag)
67 {
68   if (!reports) {
69     return;
70   }
71
72   memset(reports, 0, sizeof(ReportList));
73
74   reports->storelevel = RPT_INFO;
75   reports->printlevel = RPT_ERROR;
76   reports->flag = flag;
77 }
78
79 void BKE_reports_clear(ReportList *reports)
80 {
81   Report *report, *report_next;
82
83   if (!reports) {
84     return;
85   }
86
87   report = reports->list.first;
88
89   while (report) {
90     report_next = report->next;
91     MEM_freeN((void *)report->message);
92     MEM_freeN(report);
93     report = report_next;
94   }
95
96   BLI_listbase_clear(&reports->list);
97 }
98
99 void BKE_report(ReportList *reports, ReportType type, const char *_message)
100 {
101   Report *report;
102   int len;
103   const char *message = TIP_(_message);
104
105   /* in background mode always print otherwise there are cases the errors wont be displayed,
106    * but still add to the report list since this is used for python exception handling */
107   if (G.background || !reports || ((reports->flag & RPT_PRINT) && (type >= reports->printlevel))) {
108     printf("%s: %s\n", BKE_report_type_str(type), message);
109     fflush(stdout); /* this ensures the message is printed before a crash */
110   }
111
112   if (reports && (reports->flag & RPT_STORE) && (type >= reports->storelevel)) {
113     char *message_alloc;
114     report = MEM_callocN(sizeof(Report), "Report");
115     report->type = type;
116     report->typestr = BKE_report_type_str(type);
117
118     len = strlen(message);
119     message_alloc = MEM_callocN(sizeof(char) * (len + 1), "ReportMessage");
120     memcpy(message_alloc, message, sizeof(char) * (len + 1));
121     report->message = message_alloc;
122     report->len = len;
123     BLI_addtail(&reports->list, report);
124   }
125 }
126
127 void BKE_reportf(ReportList *reports, ReportType type, const char *_format, ...)
128 {
129   DynStr *ds;
130   Report *report;
131   va_list args;
132   const char *format = TIP_(_format);
133
134   if (G.background || !reports || ((reports->flag & RPT_PRINT) && (type >= reports->printlevel))) {
135     printf("%s: ", BKE_report_type_str(type));
136     va_start(args, _format);
137     vprintf(format, args);
138     va_end(args);
139     fprintf(stdout, "\n"); /* otherwise each report needs to include a \n */
140     fflush(stdout);        /* this ensures the message is printed before a crash */
141   }
142
143   if (reports && (reports->flag & RPT_STORE) && (type >= reports->storelevel)) {
144     report = MEM_callocN(sizeof(Report), "Report");
145
146     ds = BLI_dynstr_new();
147     va_start(args, _format);
148     BLI_dynstr_vappendf(ds, format, args);
149     va_end(args);
150
151     report->message = BLI_dynstr_get_cstring(ds);
152     report->len = BLI_dynstr_get_len(ds);
153     BLI_dynstr_free(ds);
154
155     report->type = type;
156     report->typestr = BKE_report_type_str(type);
157
158     BLI_addtail(&reports->list, report);
159   }
160 }
161
162 void BKE_reports_prepend(ReportList *reports, const char *_prepend)
163 {
164   Report *report;
165   DynStr *ds;
166   const char *prepend = TIP_(_prepend);
167
168   if (!reports) {
169     return;
170   }
171
172   for (report = reports->list.first; report; report = report->next) {
173     ds = BLI_dynstr_new();
174
175     BLI_dynstr_append(ds, prepend);
176     BLI_dynstr_append(ds, report->message);
177     MEM_freeN((void *)report->message);
178
179     report->message = BLI_dynstr_get_cstring(ds);
180     report->len = BLI_dynstr_get_len(ds);
181
182     BLI_dynstr_free(ds);
183   }
184 }
185
186 void BKE_reports_prependf(ReportList *reports, const char *_prepend, ...)
187 {
188   Report *report;
189   DynStr *ds;
190   va_list args;
191   const char *prepend = TIP_(_prepend);
192
193   if (!reports) {
194     return;
195   }
196
197   for (report = reports->list.first; report; report = report->next) {
198     ds = BLI_dynstr_new();
199     va_start(args, _prepend);
200     BLI_dynstr_vappendf(ds, prepend, args);
201     va_end(args);
202
203     BLI_dynstr_append(ds, report->message);
204     MEM_freeN((void *)report->message);
205
206     report->message = BLI_dynstr_get_cstring(ds);
207     report->len = BLI_dynstr_get_len(ds);
208
209     BLI_dynstr_free(ds);
210   }
211 }
212
213 ReportType BKE_report_print_level(ReportList *reports)
214 {
215   if (!reports) {
216     return RPT_ERROR;
217   }
218
219   return reports->printlevel;
220 }
221
222 void BKE_report_print_level_set(ReportList *reports, ReportType level)
223 {
224   if (!reports) {
225     return;
226   }
227
228   reports->printlevel = level;
229 }
230
231 ReportType BKE_report_store_level(ReportList *reports)
232 {
233   if (!reports) {
234     return RPT_ERROR;
235   }
236
237   return reports->storelevel;
238 }
239
240 void BKE_report_store_level_set(ReportList *reports, ReportType level)
241 {
242   if (!reports) {
243     return;
244   }
245
246   reports->storelevel = level;
247 }
248
249 char *BKE_reports_string(ReportList *reports, ReportType level)
250 {
251   Report *report;
252   DynStr *ds;
253   char *cstring;
254
255   if (!reports || !reports->list.first) {
256     return NULL;
257   }
258
259   ds = BLI_dynstr_new();
260   for (report = reports->list.first; report; report = report->next) {
261     if (report->type >= level) {
262       BLI_dynstr_appendf(ds, "%s: %s\n", report->typestr, report->message);
263     }
264   }
265
266   if (BLI_dynstr_get_len(ds)) {
267     cstring = BLI_dynstr_get_cstring(ds);
268   }
269   else {
270     cstring = NULL;
271   }
272
273   BLI_dynstr_free(ds);
274   return cstring;
275 }
276
277 void BKE_reports_print(ReportList *reports, ReportType level)
278 {
279   char *cstring = BKE_reports_string(reports, level);
280
281   if (cstring == NULL) {
282     return;
283   }
284
285   puts(cstring);
286   fflush(stdout);
287   MEM_freeN(cstring);
288 }
289
290 Report *BKE_reports_last_displayable(ReportList *reports)
291 {
292   Report *report;
293
294   for (report = reports->list.last; report; report = report->prev) {
295     if (ELEM(report->type, RPT_ERROR, RPT_WARNING, RPT_INFO)) {
296       return report;
297     }
298   }
299
300   return NULL;
301 }
302
303 bool BKE_reports_contain(ReportList *reports, ReportType level)
304 {
305   Report *report;
306   if (reports != NULL) {
307     for (report = reports->list.first; report; report = report->next) {
308       if (report->type >= level) {
309         return true;
310       }
311     }
312   }
313   return false;
314 }
315
316 bool BKE_report_write_file_fp(FILE *fp, ReportList *reports, const char *header)
317 {
318   Report *report;
319
320   if (header) {
321     fputs(header, fp);
322   }
323
324   for (report = reports->list.first; report; report = report->next) {
325     fprintf((FILE *)fp, "%s  # %s\n", report->message, report->typestr);
326   }
327
328   return true;
329 }
330
331 bool BKE_report_write_file(const char *filepath, ReportList *reports, const char *header)
332 {
333   FILE *fp;
334
335   errno = 0;
336   fp = BLI_fopen(filepath, "wb");
337   if (fp == NULL) {
338     fprintf(stderr,
339             "Unable to save '%s': %s\n",
340             filepath,
341             errno ? strerror(errno) : "Unknown error opening file");
342     return false;
343   }
344
345   BKE_report_write_file_fp(fp, reports, header);
346
347   fclose(fp);
348
349   return true;
350 }