Blender  V3.3
report.c
Go to the documentation of this file.
1 /* SPDX-License-Identifier: GPL-2.0-or-later
2  * Copyright 2001-2002 NaN Holding BV. All rights reserved. */
3 
8 #include <errno.h>
9 #include <stdarg.h>
10 #include <stdio.h>
11 #include <string.h>
12 
13 #include "MEM_guardedalloc.h"
14 
15 #include "BLI_blenlib.h"
16 #include "BLI_dynstr.h"
17 #include "BLI_utildefines.h"
18 
19 #include "BLT_translation.h"
20 
21 #include "BKE_global.h" /* G.background only */
22 #include "BKE_report.h"
23 
25 {
26  switch (type) {
27  case RPT_DEBUG:
28  return TIP_("Debug");
29  case RPT_INFO:
30  return TIP_("Info");
31  case RPT_OPERATOR:
32  return TIP_("Operator");
33  case RPT_PROPERTY:
34  return TIP_("Property");
35  case RPT_WARNING:
36  return TIP_("Warning");
37  case RPT_ERROR:
38  return TIP_("Error");
40  return TIP_("Invalid Input Error");
42  return TIP_("Invalid Context Error");
44  return TIP_("Out Of Memory Error");
45  default:
46  return TIP_("Undefined Type");
47  }
48 }
49 
50 void BKE_reports_init(ReportList *reports, int flag)
51 {
52  if (!reports) {
53  return;
54  }
55 
56  memset(reports, 0, sizeof(ReportList));
57 
58  reports->storelevel = RPT_INFO;
59  reports->printlevel = RPT_ERROR;
60  reports->flag = flag;
61 }
62 
64 {
65  Report *report, *report_next;
66 
67  if (!reports) {
68  return;
69  }
70 
71  report = reports->list.first;
72 
73  while (report) {
74  report_next = report->next;
75  MEM_freeN((void *)report->message);
76  MEM_freeN(report);
77  report = report_next;
78  }
79 
80  BLI_listbase_clear(&reports->list);
81 }
82 
83 void BKE_report(ReportList *reports, eReportType type, const char *_message)
84 {
85  Report *report;
86  int len;
87  const char *message = TIP_(_message);
88 
89  if (BKE_reports_print_test(reports, type)) {
90  printf("%s: %s\n", BKE_report_type_str(type), message);
91  fflush(stdout); /* this ensures the message is printed before a crash */
92  }
93 
94  if (reports && (reports->flag & RPT_STORE) && (type >= reports->storelevel)) {
95  char *message_alloc;
96  report = MEM_callocN(sizeof(Report), "Report");
97  report->type = type;
98  report->typestr = BKE_report_type_str(type);
99 
100  len = strlen(message);
101  message_alloc = MEM_mallocN(sizeof(char) * (len + 1), "ReportMessage");
102  memcpy(message_alloc, message, sizeof(char) * (len + 1));
103  report->message = message_alloc;
104  report->len = len;
105  BLI_addtail(&reports->list, report);
106  }
107 }
108 
109 void BKE_reportf(ReportList *reports, eReportType type, const char *_format, ...)
110 {
111  DynStr *ds;
112  Report *report;
113  va_list args;
114  const char *format = TIP_(_format);
115 
116  if (BKE_reports_print_test(reports, type)) {
117  printf("%s: ", BKE_report_type_str(type));
118  va_start(args, _format);
119  vprintf(format, args);
120  va_end(args);
121  fprintf(stdout, "\n"); /* otherwise each report needs to include a \n */
122  fflush(stdout); /* this ensures the message is printed before a crash */
123  }
124 
125  if (reports && (reports->flag & RPT_STORE) && (type >= reports->storelevel)) {
126  report = MEM_callocN(sizeof(Report), "Report");
127 
128  ds = BLI_dynstr_new();
129  va_start(args, _format);
130  BLI_dynstr_vappendf(ds, format, args);
131  va_end(args);
132 
133  report->message = BLI_dynstr_get_cstring(ds);
134  report->len = BLI_dynstr_get_len(ds);
135  BLI_dynstr_free(ds);
136 
137  report->type = type;
138  report->typestr = BKE_report_type_str(type);
139 
140  BLI_addtail(&reports->list, report);
141  }
142 }
143 
144 void BKE_reports_prepend(ReportList *reports, const char *_prepend)
145 {
146  Report *report;
147  DynStr *ds;
148  const char *prepend = TIP_(_prepend);
149 
150  if (!reports) {
151  return;
152  }
153 
154  for (report = reports->list.first; report; report = report->next) {
155  ds = BLI_dynstr_new();
156 
157  BLI_dynstr_append(ds, prepend);
158  BLI_dynstr_append(ds, report->message);
159  MEM_freeN((void *)report->message);
160 
161  report->message = BLI_dynstr_get_cstring(ds);
162  report->len = BLI_dynstr_get_len(ds);
163 
164  BLI_dynstr_free(ds);
165  }
166 }
167 
168 void BKE_reports_prependf(ReportList *reports, const char *_prepend, ...)
169 {
170  Report *report;
171  DynStr *ds;
172  va_list args;
173  const char *prepend = TIP_(_prepend);
174 
175  if (!reports) {
176  return;
177  }
178 
179  for (report = reports->list.first; report; report = report->next) {
180  ds = BLI_dynstr_new();
181  va_start(args, _prepend);
182  BLI_dynstr_vappendf(ds, prepend, args);
183  va_end(args);
184 
185  BLI_dynstr_append(ds, report->message);
186  MEM_freeN((void *)report->message);
187 
188  report->message = BLI_dynstr_get_cstring(ds);
189  report->len = BLI_dynstr_get_len(ds);
190 
191  BLI_dynstr_free(ds);
192  }
193 }
194 
196 {
197  if (!reports) {
198  return RPT_ERROR;
199  }
200 
201  return reports->printlevel;
202 }
203 
205 {
206  if (!reports) {
207  return;
208  }
209 
210  reports->printlevel = level;
211 }
212 
214 {
215  if (!reports) {
216  return RPT_ERROR;
217  }
218 
219  return reports->storelevel;
220 }
221 
223 {
224  if (!reports) {
225  return;
226  }
227 
228  reports->storelevel = level;
229 }
230 
232 {
233  Report *report;
234  DynStr *ds;
235  char *cstring;
236 
237  if (!reports || !reports->list.first) {
238  return NULL;
239  }
240 
241  ds = BLI_dynstr_new();
242  for (report = reports->list.first; report; report = report->next) {
243  if (report->type >= level) {
244  BLI_dynstr_appendf(ds, "%s: %s\n", report->typestr, report->message);
245  }
246  }
247 
248  if (BLI_dynstr_get_len(ds)) {
249  cstring = BLI_dynstr_get_cstring(ds);
250  }
251  else {
252  cstring = NULL;
253  }
254 
255  BLI_dynstr_free(ds);
256  return cstring;
257 }
258 
260 {
261  /* In background mode always print otherwise there are cases the errors won't be displayed,
262  * but still add to the report list since this is used for python exception handling. */
263  return (G.background || (reports == NULL) ||
264  ((reports->flag & RPT_PRINT) && (type >= reports->printlevel)));
265 }
266 
268 {
269  char *cstring = BKE_reports_string(reports, level);
270 
271  if (cstring == NULL) {
272  return;
273  }
274 
275  puts(cstring);
276  fflush(stdout);
277  MEM_freeN(cstring);
278 }
279 
281 {
282  Report *report;
283 
284  for (report = reports->list.last; report; report = report->prev) {
285  if (ELEM(report->type, RPT_ERROR, RPT_WARNING, RPT_INFO)) {
286  return report;
287  }
288  }
289 
290  return NULL;
291 }
292 
294 {
295  Report *report;
296  if (reports != NULL) {
297  for (report = reports->list.first; report; report = report->next) {
298  if (report->type >= level) {
299  return true;
300  }
301  }
302  }
303  return false;
304 }
305 
306 bool BKE_report_write_file_fp(FILE *fp, ReportList *reports, const char *header)
307 {
308  Report *report;
309 
310  if (header) {
311  fputs(header, fp);
312  }
313 
314  for (report = reports->list.first; report; report = report->next) {
315  fprintf((FILE *)fp, "%s # %s\n", report->message, report->typestr);
316  }
317 
318  return true;
319 }
320 
321 bool BKE_report_write_file(const char *filepath, ReportList *reports, const char *header)
322 {
323  FILE *fp;
324 
325  errno = 0;
326  fp = BLI_fopen(filepath, "wb");
327  if (fp == NULL) {
328  fprintf(stderr,
329  "Unable to save '%s': %s\n",
330  filepath,
331  errno ? strerror(errno) : "Unknown error opening file");
332  return false;
333  }
334 
335  BKE_report_write_file_fp(fp, reports, header);
336 
337  fclose(fp);
338 
339  return true;
340 }
A dynamically sized string ADT.
DynStr * BLI_dynstr_new(void) ATTR_MALLOC ATTR_WARN_UNUSED_RESULT
Definition: BLI_dynstr.c:50
int BLI_dynstr_get_len(const DynStr *ds) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL()
Definition: BLI_dynstr.c:235
char * BLI_dynstr_get_cstring(const DynStr *ds) ATTR_MALLOC ATTR_WARN_UNUSED_RESULT ATTR_NONNULL()
Definition: BLI_dynstr.c:256
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:281
void BLI_dynstr_appendf(DynStr *__restrict ds, const char *__restrict format,...) ATTR_PRINTF_FORMAT(2
void BLI_dynstr_append(DynStr *__restrict ds, const char *cstr) ATTR_NONNULL()
Definition: BLI_dynstr.c:75
FILE * BLI_fopen(const char *filepath, const char *mode) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL()
Definition: fileops.c:906
BLI_INLINE void BLI_listbase_clear(struct ListBase *lb)
Definition: BLI_listbase.h:273
void BLI_addtail(struct ListBase *listbase, void *vlink) ATTR_NONNULL(1)
Definition: listbase.c:80
#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.
int len
Definition: draw_manager.c:108
format
Definition: logImageCore.h:38
void(* MEM_freeN)(void *vmemh)
Definition: mallocn.c:27
void *(* MEM_callocN)(size_t len, const char *str)
Definition: mallocn.c:31
void *(* MEM_mallocN)(size_t len, const char *str)
Definition: mallocn.c:33
#define G(x, y, z)
bool BKE_reports_contain(ReportList *reports, eReportType level)
Definition: report.c:293
bool BKE_reports_print_test(const ReportList *reports, eReportType type)
Definition: report.c:259
eReportType BKE_report_store_level(ReportList *reports)
Definition: report.c:213
bool BKE_report_write_file(const char *filepath, ReportList *reports, const char *header)
Definition: report.c:321
Report * BKE_reports_last_displayable(ReportList *reports)
Definition: report.c:280
bool BKE_report_write_file_fp(FILE *fp, ReportList *reports, const char *header)
Definition: report.c:306
const char * BKE_report_type_str(eReportType type)
Definition: report.c:24
void BKE_reports_prepend(ReportList *reports, const char *_prepend)
Definition: report.c:144
void BKE_report_print_level_set(ReportList *reports, eReportType level)
Definition: report.c:204
void BKE_report_store_level_set(ReportList *reports, eReportType level)
Definition: report.c:222
eReportType BKE_report_print_level(ReportList *reports)
Definition: report.c:195
void BKE_reports_clear(ReportList *reports)
Definition: report.c:63
void BKE_reports_prependf(ReportList *reports, const char *_prepend,...)
Definition: report.c:168
void BKE_reportf(ReportList *reports, eReportType type, const char *_format,...)
Definition: report.c:109
void BKE_report(ReportList *reports, eReportType type, const char *_message)
Definition: report.c:83
char * BKE_reports_string(ReportList *reports, eReportType level)
Definition: report.c:231
void BKE_reports_init(ReportList *reports, int flag)
Definition: report.c:50
void BKE_reports_print(ReportList *reports, eReportType level)
Definition: report.c:267
void * last
Definition: DNA_listBase.h:31
void * first
Definition: DNA_listBase.h:31
struct Report * next
struct Report * prev
const char * typestr
const char * message