2 * ***** BEGIN GPL LICENSE BLOCK *****
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.
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.
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.
18 * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
19 * All rights reserved.
21 * Contributor(s): Blender Foundation (2008).
23 * ***** END GPL LICENSE BLOCK *****
26 /** \file blender/blenkernel/intern/report.c
35 #include "MEM_guardedalloc.h"
37 #include "BLI_blenlib.h"
38 #include "BLI_dynstr.h"
39 #include "BLI_utildefines.h"
41 #include "BLF_translation.h"
43 #include "BKE_report.h"
44 #include "BKE_global.h" /* G.background only */
46 static const char *report_type_str(int type)
54 return TIP_("Operator");
56 return TIP_("Property");
58 return TIP_("Warning");
61 case RPT_ERROR_INVALID_INPUT:
62 return TIP_("Invalid Input Error");
63 case RPT_ERROR_INVALID_CONTEXT:
64 return TIP_("Invalid Context Error");
65 case RPT_ERROR_OUT_OF_MEMORY:
66 return TIP_("Out Of Memory Error");
68 return TIP_("Undefined Type");
72 void BKE_reports_init(ReportList *reports, int flag)
77 memset(reports, 0, sizeof(ReportList));
79 reports->storelevel = RPT_INFO;
80 reports->printlevel = RPT_ERROR;
84 void BKE_reports_clear(ReportList *reports)
86 Report *report, *report_next;
91 report = reports->list.first;
94 report_next = report->next;
95 MEM_freeN((void *)report->message);
100 reports->list.first = reports->list.last = NULL;
103 void BKE_report(ReportList *reports, ReportType type, const char *_message)
107 const char *message = TIP_(_message);
109 /* in background mode always print otherwise there are cases the errors wont be displayed,
110 * but still add to the report list since this is used for python exception handling */
111 if (G.background || !reports || ((reports->flag & RPT_PRINT) && (type >= reports->printlevel))) {
112 printf("%s: %s\n", report_type_str(type), message);
113 fflush(stdout); /* this ensures the message is printed before a crash */
116 if (reports && (reports->flag & RPT_STORE) && (type >= reports->storelevel)) {
118 report = MEM_callocN(sizeof(Report), "Report");
120 report->typestr = report_type_str(type);
122 len = strlen(message);
123 message_alloc = MEM_callocN(sizeof(char) * (len + 1), "ReportMessage");
124 memcpy(message_alloc, message, sizeof(char) * (len + 1));
125 report->message = message_alloc;
127 BLI_addtail(&reports->list, report);
131 void BKE_reportf(ReportList *reports, ReportType type, const char *_format, ...)
136 const char *format = TIP_(_format);
138 if (G.background || !reports || ((reports->flag & RPT_PRINT) && (type >= reports->printlevel))) {
139 printf("%s: ", report_type_str(type));
140 va_start(args, _format);
141 vprintf(format, args);
143 fprintf(stdout, "\n"); /* otherise each report needs to include a \n */
144 fflush(stdout); /* this ensures the message is printed before a crash */
147 if (reports && (reports->flag & RPT_STORE) && (type >= reports->storelevel)) {
148 report = MEM_callocN(sizeof(Report), "Report");
150 ds = BLI_dynstr_new();
151 va_start(args, _format);
152 BLI_dynstr_vappendf(ds, format, args);
155 report->message = BLI_dynstr_get_cstring(ds);
156 report->len = BLI_dynstr_get_len(ds);
160 report->typestr = report_type_str(type);
162 BLI_addtail(&reports->list, report);
166 void BKE_reports_prepend(ReportList *reports, const char *_prepend)
170 const char *prepend = TIP_(_prepend);
175 for (report = reports->list.first; report; report = report->next) {
176 ds = BLI_dynstr_new();
178 BLI_dynstr_append(ds, prepend);
179 BLI_dynstr_append(ds, report->message);
180 MEM_freeN((void *)report->message);
182 report->message = BLI_dynstr_get_cstring(ds);
183 report->len = BLI_dynstr_get_len(ds);
189 void BKE_reports_prependf(ReportList *reports, const char *_prepend, ...)
194 const char *prepend = TIP_(_prepend);
199 for (report = reports->list.first; report; report = report->next) {
200 ds = BLI_dynstr_new();
201 va_start(args, _prepend);
202 BLI_dynstr_vappendf(ds, prepend, args);
205 BLI_dynstr_append(ds, report->message);
206 MEM_freeN((void *)report->message);
208 report->message = BLI_dynstr_get_cstring(ds);
209 report->len = BLI_dynstr_get_len(ds);
215 ReportType BKE_report_print_level(ReportList *reports)
220 return reports->printlevel;
223 void BKE_report_print_level_set(ReportList *reports, ReportType level)
228 reports->printlevel = level;
231 ReportType BKE_report_store_level(ReportList *reports)
236 return reports->storelevel;
239 void BKE_report_store_level_set(ReportList *reports, ReportType level)
244 reports->storelevel = level;
247 char *BKE_reports_string(ReportList *reports, ReportType level)
253 if (!reports || !reports->list.first)
256 ds = BLI_dynstr_new();
257 for (report = reports->list.first; report; report = report->next)
258 if (report->type >= level)
259 BLI_dynstr_appendf(ds, "%s: %s\n", report->typestr, report->message);
261 if (BLI_dynstr_get_len(ds))
262 cstring = BLI_dynstr_get_cstring(ds);
270 void BKE_reports_print(ReportList *reports, ReportType level)
272 char *cstring = BKE_reports_string(reports, level);
282 Report *BKE_reports_last_displayable(ReportList *reports)
286 for (report = reports->list.last; report; report = report->prev) {
287 if (ELEM3(report->type, RPT_ERROR, RPT_WARNING, RPT_INFO))
294 int BKE_reports_contain(ReportList *reports, ReportType level)
297 if (reports != NULL) {
298 for (report = reports->list.first; report; report = report->next)
299 if (report->type >= level)
305 bool BKE_report_write_file_fp(FILE *fp, ReportList *reports, const char *header)
313 for (report = reports->list.first; report; report = report->next) {
314 fprintf((FILE *)fp, "%s # %s\n", report->message, report->typestr);
320 bool BKE_report_write_file(const char *filepath, ReportList *reports, const char *header)
325 fp = BLI_fopen(filepath, "wb");
327 fprintf(stderr, "Unable to save '%s': %s\n",
328 filepath, errno ? strerror(errno) : "Unknown error opening file");
332 BKE_report_write_file_fp(fp, reports, header);