Blender  V2.93
report.c
Go to the documentation of this file.
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 
24 #include <errno.h>
25 #include <stdarg.h>
26 #include <stdio.h>
27 #include <string.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_global.h" /* G.background only */
38 #include "BKE_report.h"
39 
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");
56  return TIP_("Invalid Input Error");
58  return TIP_("Invalid Context Error");
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 
85 {
86  Report *report, *report_next;
87 
88  if (!reports) {
89  return;
90  }
91 
92  report = reports->list.first;
93 
94  while (report) {
95  report_next = report->next;
96  MEM_freeN((void *)report->message);
97  MEM_freeN(report);
98  report = report_next;
99  }
100 
101  BLI_listbase_clear(&reports->list);
102 }
103 
104 void BKE_report(ReportList *reports, ReportType type, const char *_message)
105 {
106  Report *report;
107  int len;
108  const char *message = TIP_(_message);
109 
110  /* in background mode always print otherwise there are cases the errors wont be displayed,
111  * but still add to the report list since this is used for python exception handling */
112  if (G.background || !reports || ((reports->flag & RPT_PRINT) && (type >= reports->printlevel))) {
113  printf("%s: %s\n", BKE_report_type_str(type), message);
114  fflush(stdout); /* this ensures the message is printed before a crash */
115  }
116 
117  if (reports && (reports->flag & RPT_STORE) && (type >= reports->storelevel)) {
118  char *message_alloc;
119  report = MEM_callocN(sizeof(Report), "Report");
120  report->type = type;
121  report->typestr = BKE_report_type_str(type);
122 
123  len = strlen(message);
124  message_alloc = MEM_mallocN(sizeof(char) * (len + 1), "ReportMessage");
125  memcpy(message_alloc, message, sizeof(char) * (len + 1));
126  report->message = message_alloc;
127  report->len = len;
128  BLI_addtail(&reports->list, report);
129  }
130 }
131 
132 void BKE_reportf(ReportList *reports, ReportType type, const char *_format, ...)
133 {
134  DynStr *ds;
135  Report *report;
136  va_list args;
137  const char *format = TIP_(_format);
138 
139  if (G.background || !reports || ((reports->flag & RPT_PRINT) && (type >= reports->printlevel))) {
140  printf("%s: ", BKE_report_type_str(type));
141  va_start(args, _format);
142  vprintf(format, args);
143  va_end(args);
144  fprintf(stdout, "\n"); /* otherwise each report needs to include a \n */
145  fflush(stdout); /* this ensures the message is printed before a crash */
146  }
147 
148  if (reports && (reports->flag & RPT_STORE) && (type >= reports->storelevel)) {
149  report = MEM_callocN(sizeof(Report), "Report");
150 
151  ds = BLI_dynstr_new();
152  va_start(args, _format);
153  BLI_dynstr_vappendf(ds, format, args);
154  va_end(args);
155 
156  report->message = BLI_dynstr_get_cstring(ds);
157  report->len = BLI_dynstr_get_len(ds);
158  BLI_dynstr_free(ds);
159 
160  report->type = type;
161  report->typestr = BKE_report_type_str(type);
162 
163  BLI_addtail(&reports->list, report);
164  }
165 }
166 
167 void BKE_reports_prepend(ReportList *reports, const char *_prepend)
168 {
169  Report *report;
170  DynStr *ds;
171  const char *prepend = TIP_(_prepend);
172 
173  if (!reports) {
174  return;
175  }
176 
177  for (report = reports->list.first; report; report = report->next) {
178  ds = BLI_dynstr_new();
179 
180  BLI_dynstr_append(ds, prepend);
181  BLI_dynstr_append(ds, report->message);
182  MEM_freeN((void *)report->message);
183 
184  report->message = BLI_dynstr_get_cstring(ds);
185  report->len = BLI_dynstr_get_len(ds);
186 
187  BLI_dynstr_free(ds);
188  }
189 }
190 
191 void BKE_reports_prependf(ReportList *reports, const char *_prepend, ...)
192 {
193  Report *report;
194  DynStr *ds;
195  va_list args;
196  const char *prepend = TIP_(_prepend);
197 
198  if (!reports) {
199  return;
200  }
201 
202  for (report = reports->list.first; report; report = report->next) {
203  ds = BLI_dynstr_new();
204  va_start(args, _prepend);
205  BLI_dynstr_vappendf(ds, prepend, args);
206  va_end(args);
207 
208  BLI_dynstr_append(ds, report->message);
209  MEM_freeN((void *)report->message);
210 
211  report->message = BLI_dynstr_get_cstring(ds);
212  report->len = BLI_dynstr_get_len(ds);
213 
214  BLI_dynstr_free(ds);
215  }
216 }
217 
219 {
220  if (!reports) {
221  return RPT_ERROR;
222  }
223 
224  return reports->printlevel;
225 }
226 
228 {
229  if (!reports) {
230  return;
231  }
232 
233  reports->printlevel = level;
234 }
235 
237 {
238  if (!reports) {
239  return RPT_ERROR;
240  }
241 
242  return reports->storelevel;
243 }
244 
246 {
247  if (!reports) {
248  return;
249  }
250 
251  reports->storelevel = level;
252 }
253 
255 {
256  Report *report;
257  DynStr *ds;
258  char *cstring;
259 
260  if (!reports || !reports->list.first) {
261  return NULL;
262  }
263 
264  ds = BLI_dynstr_new();
265  for (report = reports->list.first; report; report = report->next) {
266  if (report->type >= level) {
267  BLI_dynstr_appendf(ds, "%s: %s\n", report->typestr, report->message);
268  }
269  }
270 
271  if (BLI_dynstr_get_len(ds)) {
272  cstring = BLI_dynstr_get_cstring(ds);
273  }
274  else {
275  cstring = NULL;
276  }
277 
278  BLI_dynstr_free(ds);
279  return cstring;
280 }
281 
283 {
284  char *cstring = BKE_reports_string(reports, level);
285 
286  if (cstring == NULL) {
287  return;
288  }
289 
290  puts(cstring);
291  fflush(stdout);
292  MEM_freeN(cstring);
293 }
294 
296 {
297  Report *report;
298 
299  for (report = reports->list.last; report; report = report->prev) {
300  if (ELEM(report->type, RPT_ERROR, RPT_WARNING, RPT_INFO)) {
301  return report;
302  }
303  }
304 
305  return NULL;
306 }
307 
309 {
310  Report *report;
311  if (reports != NULL) {
312  for (report = reports->list.first; report; report = report->next) {
313  if (report->type >= level) {
314  return true;
315  }
316  }
317  }
318  return false;
319 }
320 
321 bool BKE_report_write_file_fp(FILE *fp, ReportList *reports, const char *header)
322 {
323  Report *report;
324 
325  if (header) {
326  fputs(header, fp);
327  }
328 
329  for (report = reports->list.first; report; report = report->next) {
330  fprintf((FILE *)fp, "%s # %s\n", report->message, report->typestr);
331  }
332 
333  return true;
334 }
335 
336 bool BKE_report_write_file(const char *filepath, ReportList *reports, const char *header)
337 {
338  FILE *fp;
339 
340  errno = 0;
341  fp = BLI_fopen(filepath, "wb");
342  if (fp == NULL) {
343  fprintf(stderr,
344  "Unable to save '%s': %s\n",
345  filepath,
346  errno ? strerror(errno) : "Unknown error opening file");
347  return false;
348  }
349 
350  BKE_report_write_file_fp(fp, reports, header);
351 
352  fclose(fp);
353 
354  return true;
355 }
A dynamically sized string ADT.
DynStr * BLI_dynstr_new(void) ATTR_MALLOC ATTR_WARN_UNUSED_RESULT
Definition: BLI_dynstr.c:71
int BLI_dynstr_get_len(DynStr *ds) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL()
Definition: BLI_dynstr.c:286
void BLI_dynstr_vappendf(DynStr *__restrict ds, const char *__restrict format, va_list args) ATTR_PRINTF_FORMAT(2
void BLI_dynstr_free(DynStr *ds) ATTR_NONNULL()
Definition: BLI_dynstr.c:358
void BLI_dynstr_appendf(DynStr *__restrict ds, const char *__restrict format,...) ATTR_PRINTF_FORMAT(2
char * BLI_dynstr_get_cstring(DynStr *ds) ATTR_MALLOC ATTR_WARN_UNUSED_RESULT ATTR_NONNULL()
Definition: BLI_dynstr.c:323
void BLI_dynstr_append(DynStr *__restrict ds, const char *cstr) ATTR_NONNULL()
Definition: BLI_dynstr.c:107
FILE * BLI_fopen(const char *filename, const char *mode) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL()
Definition: fileops.c:1003
BLI_INLINE void BLI_listbase_clear(struct ListBase *lb)
Definition: BLI_listbase.h:128
void BLI_addtail(struct ListBase *listbase, void *vlink) ATTR_NONNULL(1)
Definition: listbase.c:110
#define ELEM(...)
#define TIP_(msgid)
@ RPT_ERROR_OUT_OF_MEMORY
@ RPT_ERROR_INVALID_INPUT
@ RPT_ERROR_INVALID_CONTEXT
_GL_VOID GLfloat value _GL_VOID_RET _GL_VOID const GLuint GLboolean *residences _GL_BOOL_RET _GL_VOID GLsizei GLfloat GLfloat GLfloat GLfloat const GLubyte *bitmap _GL_VOID_RET _GL_VOID GLenum type
Read Guarded memory(de)allocation.
format
Definition: logImageCore.h:47
void(* MEM_freeN)(void *vmemh)
Definition: mallocn.c:41
void *(* MEM_callocN)(size_t len, const char *str)
Definition: mallocn.c:45
void *(* MEM_mallocN)(size_t len, const char *str)
Definition: mallocn.c:47
void BKE_reports_print(ReportList *reports, ReportType level)
Definition: report.c:282
ReportType BKE_report_print_level(ReportList *reports)
Definition: report.c:218
bool BKE_report_write_file(const char *filepath, ReportList *reports, const char *header)
Definition: report.c:336
Report * BKE_reports_last_displayable(ReportList *reports)
Definition: report.c:295
bool BKE_report_write_file_fp(FILE *fp, ReportList *reports, const char *header)
Definition: report.c:321
void BKE_reportf(ReportList *reports, ReportType type, const char *_format,...)
Definition: report.c:132
void BKE_report_print_level_set(ReportList *reports, ReportType level)
Definition: report.c:227
ReportType BKE_report_store_level(ReportList *reports)
Definition: report.c:236
void BKE_reports_prepend(ReportList *reports, const char *_prepend)
Definition: report.c:167
char * BKE_reports_string(ReportList *reports, ReportType level)
Definition: report.c:254
void BKE_reports_clear(ReportList *reports)
Definition: report.c:84
void BKE_reports_prependf(ReportList *reports, const char *_prepend,...)
Definition: report.c:191
const char * BKE_report_type_str(ReportType type)
Definition: report.c:40
void BKE_report(ReportList *reports, ReportType type, const char *_message)
Definition: report.c:104
void BKE_report_store_level_set(ReportList *reports, ReportType level)
Definition: report.c:245
void BKE_reports_init(ReportList *reports, int flag)
Definition: report.c:66
bool BKE_reports_contain(ReportList *reports, ReportType level)
Definition: report.c:308
void * last
Definition: DNA_listBase.h:47
void * first
Definition: DNA_listBase.h:47
struct Report * next
struct Report * prev
const char * typestr
const char * message
#define G(x, y, z)
uint len