351 lines
7.6 KiB
C
351 lines
7.6 KiB
C
/* SPDX-License-Identifier: GPL-2.0-or-later
|
|
* Copyright 2001-2002 NaN Holding BV. All rights reserved. */
|
|
|
|
/** \file
|
|
* \ingroup bke
|
|
*/
|
|
|
|
#include <errno.h>
|
|
#include <stdarg.h>
|
|
#include <stdio.h>
|
|
#include <string.h>
|
|
|
|
#include "MEM_guardedalloc.h"
|
|
|
|
#include "BLI_blenlib.h"
|
|
#include "BLI_dynstr.h"
|
|
#include "BLI_utildefines.h"
|
|
|
|
#include "BLT_translation.h"
|
|
|
|
#include "BKE_global.h" /* G.background only */
|
|
#include "BKE_report.h"
|
|
|
|
const char *BKE_report_type_str(eReportType type)
|
|
{
|
|
switch (type) {
|
|
case RPT_DEBUG:
|
|
return TIP_("Debug");
|
|
case RPT_INFO:
|
|
return TIP_("Info");
|
|
case RPT_OPERATOR:
|
|
return TIP_("Operator");
|
|
case RPT_PROPERTY:
|
|
return TIP_("Property");
|
|
case RPT_WARNING:
|
|
return TIP_("Warning");
|
|
case RPT_ERROR:
|
|
return TIP_("Error");
|
|
case RPT_ERROR_INVALID_INPUT:
|
|
return TIP_("Invalid Input Error");
|
|
case RPT_ERROR_INVALID_CONTEXT:
|
|
return TIP_("Invalid Context Error");
|
|
case RPT_ERROR_OUT_OF_MEMORY:
|
|
return TIP_("Out Of Memory Error");
|
|
default:
|
|
return TIP_("Undefined Type");
|
|
}
|
|
}
|
|
|
|
void BKE_reports_init(ReportList *reports, int flag)
|
|
{
|
|
if (!reports) {
|
|
return;
|
|
}
|
|
|
|
memset(reports, 0, sizeof(ReportList));
|
|
|
|
reports->storelevel = RPT_INFO;
|
|
reports->printlevel = RPT_ERROR;
|
|
reports->flag = flag;
|
|
}
|
|
|
|
void BKE_reports_clear(ReportList *reports)
|
|
{
|
|
Report *report, *report_next;
|
|
|
|
if (!reports) {
|
|
return;
|
|
}
|
|
|
|
report = reports->list.first;
|
|
|
|
while (report) {
|
|
report_next = report->next;
|
|
MEM_freeN((void *)report->message);
|
|
MEM_freeN(report);
|
|
report = report_next;
|
|
}
|
|
|
|
BLI_listbase_clear(&reports->list);
|
|
}
|
|
|
|
void BKE_report(ReportList *reports, eReportType type, const char *_message)
|
|
{
|
|
Report *report;
|
|
int len;
|
|
const char *message = TIP_(_message);
|
|
|
|
if (BKE_reports_print_test(reports, type)) {
|
|
printf("%s: %s\n", BKE_report_type_str(type), message);
|
|
fflush(stdout); /* this ensures the message is printed before a crash */
|
|
}
|
|
|
|
if (reports && (reports->flag & RPT_STORE) && (type >= reports->storelevel)) {
|
|
char *message_alloc;
|
|
report = MEM_callocN(sizeof(Report), "Report");
|
|
report->type = type;
|
|
report->typestr = BKE_report_type_str(type);
|
|
|
|
len = strlen(message);
|
|
message_alloc = MEM_mallocN(sizeof(char) * (len + 1), "ReportMessage");
|
|
memcpy(message_alloc, message, sizeof(char) * (len + 1));
|
|
report->message = message_alloc;
|
|
report->len = len;
|
|
BLI_addtail(&reports->list, report);
|
|
}
|
|
}
|
|
|
|
void BKE_reportf(ReportList *reports, eReportType type, const char *_format, ...)
|
|
{
|
|
DynStr *ds;
|
|
Report *report;
|
|
va_list args;
|
|
const char *format = TIP_(_format);
|
|
|
|
if (BKE_reports_print_test(reports, type)) {
|
|
printf("%s: ", BKE_report_type_str(type));
|
|
va_start(args, _format);
|
|
vprintf(format, args);
|
|
va_end(args);
|
|
fprintf(stdout, "\n"); /* otherwise each report needs to include a \n */
|
|
fflush(stdout); /* this ensures the message is printed before a crash */
|
|
}
|
|
|
|
if (reports && (reports->flag & RPT_STORE) && (type >= reports->storelevel)) {
|
|
report = MEM_callocN(sizeof(Report), "Report");
|
|
|
|
ds = BLI_dynstr_new();
|
|
va_start(args, _format);
|
|
BLI_dynstr_vappendf(ds, format, args);
|
|
va_end(args);
|
|
|
|
report->message = BLI_dynstr_get_cstring(ds);
|
|
report->len = BLI_dynstr_get_len(ds);
|
|
BLI_dynstr_free(ds);
|
|
|
|
report->type = type;
|
|
report->typestr = BKE_report_type_str(type);
|
|
|
|
BLI_addtail(&reports->list, report);
|
|
}
|
|
}
|
|
|
|
void BKE_reports_prepend(ReportList *reports, const char *_prepend)
|
|
{
|
|
Report *report;
|
|
DynStr *ds;
|
|
const char *prepend = TIP_(_prepend);
|
|
|
|
if (!reports) {
|
|
return;
|
|
}
|
|
|
|
for (report = reports->list.first; report; report = report->next) {
|
|
ds = BLI_dynstr_new();
|
|
|
|
BLI_dynstr_append(ds, prepend);
|
|
BLI_dynstr_append(ds, report->message);
|
|
MEM_freeN((void *)report->message);
|
|
|
|
report->message = BLI_dynstr_get_cstring(ds);
|
|
report->len = BLI_dynstr_get_len(ds);
|
|
|
|
BLI_dynstr_free(ds);
|
|
}
|
|
}
|
|
|
|
void BKE_reports_prependf(ReportList *reports, const char *_prepend, ...)
|
|
{
|
|
Report *report;
|
|
DynStr *ds;
|
|
va_list args;
|
|
const char *prepend = TIP_(_prepend);
|
|
|
|
if (!reports) {
|
|
return;
|
|
}
|
|
|
|
for (report = reports->list.first; report; report = report->next) {
|
|
ds = BLI_dynstr_new();
|
|
va_start(args, _prepend);
|
|
BLI_dynstr_vappendf(ds, prepend, args);
|
|
va_end(args);
|
|
|
|
BLI_dynstr_append(ds, report->message);
|
|
MEM_freeN((void *)report->message);
|
|
|
|
report->message = BLI_dynstr_get_cstring(ds);
|
|
report->len = BLI_dynstr_get_len(ds);
|
|
|
|
BLI_dynstr_free(ds);
|
|
}
|
|
}
|
|
|
|
eReportType BKE_report_print_level(ReportList *reports)
|
|
{
|
|
if (!reports) {
|
|
return RPT_ERROR;
|
|
}
|
|
|
|
return reports->printlevel;
|
|
}
|
|
|
|
void BKE_report_print_level_set(ReportList *reports, eReportType level)
|
|
{
|
|
if (!reports) {
|
|
return;
|
|
}
|
|
|
|
reports->printlevel = level;
|
|
}
|
|
|
|
eReportType BKE_report_store_level(ReportList *reports)
|
|
{
|
|
if (!reports) {
|
|
return RPT_ERROR;
|
|
}
|
|
|
|
return reports->storelevel;
|
|
}
|
|
|
|
void BKE_report_store_level_set(ReportList *reports, eReportType level)
|
|
{
|
|
if (!reports) {
|
|
return;
|
|
}
|
|
|
|
reports->storelevel = level;
|
|
}
|
|
|
|
char *BKE_reports_string(ReportList *reports, eReportType level)
|
|
{
|
|
Report *report;
|
|
DynStr *ds;
|
|
char *cstring;
|
|
|
|
if (!reports || !reports->list.first) {
|
|
return NULL;
|
|
}
|
|
|
|
ds = BLI_dynstr_new();
|
|
for (report = reports->list.first; report; report = report->next) {
|
|
if (report->type >= level) {
|
|
BLI_dynstr_appendf(ds, "%s: %s\n", report->typestr, report->message);
|
|
}
|
|
}
|
|
|
|
if (BLI_dynstr_get_len(ds)) {
|
|
cstring = BLI_dynstr_get_cstring(ds);
|
|
}
|
|
else {
|
|
cstring = NULL;
|
|
}
|
|
|
|
BLI_dynstr_free(ds);
|
|
return cstring;
|
|
}
|
|
|
|
bool BKE_reports_print_test(const ReportList *reports, eReportType type)
|
|
{
|
|
if (reports == NULL) {
|
|
return true;
|
|
}
|
|
if (reports->flag & RPT_PRINT_HANDLED_BY_OWNER) {
|
|
return false;
|
|
}
|
|
/* In background mode always print otherwise there are cases the errors won't be displayed,
|
|
* but still add to the report list since this is used for Python exception handling. */
|
|
if (G.background) {
|
|
return true;
|
|
}
|
|
|
|
/* Common case. */
|
|
return (reports->flag & RPT_PRINT) && (type >= reports->printlevel);
|
|
}
|
|
|
|
void BKE_reports_print(ReportList *reports, eReportType level)
|
|
{
|
|
char *cstring = BKE_reports_string(reports, level);
|
|
|
|
if (cstring == NULL) {
|
|
return;
|
|
}
|
|
|
|
puts(cstring);
|
|
fflush(stdout);
|
|
MEM_freeN(cstring);
|
|
}
|
|
|
|
Report *BKE_reports_last_displayable(ReportList *reports)
|
|
{
|
|
Report *report;
|
|
|
|
for (report = reports->list.last; report; report = report->prev) {
|
|
if (ELEM(report->type, RPT_ERROR, RPT_WARNING, RPT_INFO)) {
|
|
return report;
|
|
}
|
|
}
|
|
|
|
return NULL;
|
|
}
|
|
|
|
bool BKE_reports_contain(ReportList *reports, eReportType level)
|
|
{
|
|
Report *report;
|
|
if (reports != NULL) {
|
|
for (report = reports->list.first; report; report = report->next) {
|
|
if (report->type >= level) {
|
|
return true;
|
|
}
|
|
}
|
|
}
|
|
return false;
|
|
}
|
|
|
|
bool BKE_report_write_file_fp(FILE *fp, ReportList *reports, const char *header)
|
|
{
|
|
Report *report;
|
|
|
|
if (header) {
|
|
fputs(header, fp);
|
|
}
|
|
|
|
for (report = reports->list.first; report; report = report->next) {
|
|
fprintf((FILE *)fp, "%s # %s\n", report->message, report->typestr);
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
bool BKE_report_write_file(const char *filepath, ReportList *reports, const char *header)
|
|
{
|
|
FILE *fp;
|
|
|
|
errno = 0;
|
|
fp = BLI_fopen(filepath, "wb");
|
|
if (fp == NULL) {
|
|
fprintf(stderr,
|
|
"Unable to save '%s': %s\n",
|
|
filepath,
|
|
errno ? strerror(errno) : "Unknown error opening file");
|
|
return false;
|
|
}
|
|
|
|
BKE_report_write_file_fp(fp, reports, header);
|
|
|
|
fclose(fp);
|
|
|
|
return true;
|
|
}
|