Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBrecht Van Lommel <brechtvanlommel@pandora.be>2008-12-29 16:38:08 +0300
committerBrecht Van Lommel <brechtvanlommel@pandora.be>2008-12-29 16:38:08 +0300
commit0a8a00cd1060ee7aa9eae4223fc8c2577533247f (patch)
tree6dc09a68c1d8e35bd807d784f3507b57c9c1f62f /source/blender/blenkernel
parentd51bc24384a70f3cdcd4b72091873c96d542d642 (diff)
2.5: Error reporting
* Added a report list to operator, to which they can report errors and warnings. When the operator ends, it will display them with a popup. For python these should become exceptions when calling operators. * Added a function to make a popup menu from a report list. * Also added a utility function to prepend a string before the reports to indicate what they relates to. Also made the report functions used BLI_dynstr to simplify the code. * Made file reading and writing report errors to the user again using this system, also replacing the left over uncommented bad level error() calls.
Diffstat (limited to 'source/blender/blenkernel')
-rw-r--r--source/blender/blenkernel/BKE_blender.h7
-rw-r--r--source/blender/blenkernel/BKE_report.h4
-rw-r--r--source/blender/blenkernel/intern/blender.c62
-rw-r--r--source/blender/blenkernel/intern/context.c25
-rw-r--r--source/blender/blenkernel/intern/report.c140
5 files changed, 121 insertions, 117 deletions
diff --git a/source/blender/blenkernel/BKE_blender.h b/source/blender/blenkernel/BKE_blender.h
index 5eb3de4404e..dbdb570b2f8 100644
--- a/source/blender/blenkernel/BKE_blender.h
+++ b/source/blender/blenkernel/BKE_blender.h
@@ -40,6 +40,7 @@ extern "C" {
struct ListBase;
struct MemFile;
struct bContext;
+struct ReportList;
#define BLENDER_VERSION 250
#define BLENDER_SUBVERSION 0
@@ -47,9 +48,9 @@ struct bContext;
#define BLENDER_MINVERSION 250
#define BLENDER_MINSUBVERSION 0
-int BKE_read_file(struct bContext *C, char *dir, void *type_r);
-int BKE_read_file_from_memory(struct bContext *C, char* filebuf, int filelength, void *type_r);
-int BKE_read_file_from_memfile(struct bContext *C, struct MemFile *memfile);
+int BKE_read_file(struct bContext *C, char *dir, void *type_r, struct ReportList *reports);
+int BKE_read_file_from_memory(struct bContext *C, char* filebuf, int filelength, void *type_r, struct ReportList *reports);
+int BKE_read_file_from_memfile(struct bContext *C, struct MemFile *memfile, struct ReportList *reports);
void free_blender(void);
void initglobals(void);
diff --git a/source/blender/blenkernel/BKE_report.h b/source/blender/blenkernel/BKE_report.h
index f87910d7872..8a5c623a225 100644
--- a/source/blender/blenkernel/BKE_report.h
+++ b/source/blender/blenkernel/BKE_report.h
@@ -49,7 +49,6 @@ typedef enum ReportType {
enum ReportListFlags {
RPT_PRINT = 1,
RPT_STORE = 2,
- RPT_HAS_ERROR = 4
};
typedef struct Report {
@@ -72,6 +71,9 @@ void BKE_reports_clear(ReportList *reports);
void BKE_report(ReportList *reports, ReportType type, const char *message);
void BKE_reportf(ReportList *reports, ReportType type, const char *format, ...);
+void BKE_reports_prepend(ReportList *reports, const char *prepend);
+void BKE_reports_prependf(ReportList *reports, const char *prepend, ...);
+
ReportType BKE_report_print_level(ReportList *reports);
void BKE_report_print_level_set(ReportList *reports, ReportType level);
diff --git a/source/blender/blenkernel/intern/blender.c b/source/blender/blenkernel/intern/blender.c
index 7c2d4502e5e..1ae61bad8b2 100644
--- a/source/blender/blenkernel/intern/blender.c
+++ b/source/blender/blenkernel/intern/blender.c
@@ -424,15 +424,12 @@ static void handle_subversion_warning(Main *main)
2: OK, and with new user settings
*/
-int BKE_read_file(bContext *C, char *dir, void *unused)
+int BKE_read_file(bContext *C, char *dir, void *unused, ReportList *reports)
{
- ReportList reports;
BlendFileData *bfd;
int retval= 1;
-
- BKE_reports_init(&reports, RPT_STORE);
- bfd= BLO_read_from_file(dir, &reports);
+ bfd= BLO_read_from_file(dir, reports);
if (bfd) {
if(bfd->user) retval= 2;
@@ -440,50 +437,35 @@ int BKE_read_file(bContext *C, char *dir, void *unused)
handle_subversion_warning(G.main);
}
- else {
-// XXX error("Loading %s failed: %s", dir, BLO_bre_as_string(bre));
- }
-
- BKE_reports_clear(&reports);
+ else
+ BKE_reports_prependf(reports, "Loading %s failed: ", dir);
return (bfd?retval:0);
}
-int BKE_read_file_from_memory(bContext *C, char* filebuf, int filelength, void *unused)
+int BKE_read_file_from_memory(bContext *C, char* filebuf, int filelength, void *unused, ReportList *reports)
{
- ReportList reports;
BlendFileData *bfd;
- BKE_reports_init(&reports, RPT_STORE);
-
- bfd= BLO_read_from_memory(filebuf, filelength, &reports);
- if (bfd) {
+ bfd= BLO_read_from_memory(filebuf, filelength, reports);
+ if (bfd)
setup_app_data(C, bfd, "<memory2>");
- } else {
-// XXX error("Loading failed: %s", BLO_bre_as_string(bre));
- }
-
- BKE_reports_clear(&reports);
+ else
+ BKE_reports_prepend(reports, "Loading failed: ");
return (bfd?1:0);
}
/* memfile is the undo buffer */
-int BKE_read_file_from_memfile(bContext *C, MemFile *memfile)
+int BKE_read_file_from_memfile(bContext *C, MemFile *memfile, ReportList *reports)
{
- ReportList reports;
BlendFileData *bfd;
-
- BKE_reports_init(&reports, RPT_STORE);
- bfd= BLO_read_from_memfile(CTX_data_main(C), G.sce, memfile, &reports);
- if (bfd) {
+ bfd= BLO_read_from_memfile(CTX_data_main(C), G.sce, memfile, reports);
+ if (bfd)
setup_app_data(C, bfd, "<memory1>");
- } else {
-// XXX error("Loading failed: %s", BLO_bre_as_string(bre));
- }
-
- BKE_reports_clear(&reports);
+ else
+ BKE_reports_prepend(reports, "Loading failed: ");
return (bfd?1:0);
}
@@ -516,10 +498,10 @@ static int read_undosave(bContext *C, UndoElem *uel)
G.fileflags |= G_FILE_NO_UI;
if(UNDO_DISK)
- success= BKE_read_file(C, uel->str, NULL);
+ success= BKE_read_file(C, uel->str, NULL, NULL);
else
- success= BKE_read_file_from_memfile(C, &uel->memfile);
-
+ success= BKE_read_file_from_memfile(C, &uel->memfile, NULL);
+
/* restore */
strcpy(G.sce, scestr);
G.fileflags= fileflags;
@@ -571,7 +553,6 @@ void BKE_write_undo(bContext *C, char *name)
/* disk save version */
if(UNDO_DISK) {
- ReportList reports;
static int counter= 0;
char tstr[FILE_MAXDIR+FILE_MAXFILE];
char numstr[32];
@@ -583,22 +564,17 @@ void BKE_write_undo(bContext *C, char *name)
sprintf(numstr, "%d.blend", counter);
BLI_make_file_string("/", tstr, btempdir, numstr);
- BKE_reports_init(&reports, 0);
- success= BLO_write_file(CTX_data_main(C), tstr, G.fileflags, &reports);
- BKE_reports_clear(&reports);
+ success= BLO_write_file(CTX_data_main(C), tstr, G.fileflags, NULL);
strcpy(curundo->str, tstr);
}
else {
- ReportList reports;
MemFile *prevfile=NULL;
if(curundo->prev) prevfile= &(curundo->prev->memfile);
memused= MEM_get_memory_in_use();
- BKE_reports_init(&reports, 0);
- success= BLO_write_file_mem(CTX_data_main(C), prevfile, &curundo->memfile, G.fileflags, &reports);
- BKE_reports_clear(&reports);
+ success= BLO_write_file_mem(CTX_data_main(C), prevfile, &curundo->memfile, G.fileflags, NULL);
curundo->undosize= MEM_get_memory_in_use() - memused;
}
diff --git a/source/blender/blenkernel/intern/context.c b/source/blender/blenkernel/intern/context.c
index fa5740f74e9..aec497537cf 100644
--- a/source/blender/blenkernel/intern/context.c
+++ b/source/blender/blenkernel/intern/context.c
@@ -60,9 +60,6 @@ struct bContext {
struct ARegion *region;
struct uiBlock *block;
- bContextDataCallback screen_cb;
- bContextDataCallback area_cb;
- bContextDataCallback region_cb;
bContextDataCallback block_cb;
} wm;
@@ -191,26 +188,22 @@ void CTX_wm_window_set(bContext *C, wmWindow *win)
C->wm.window= win;
C->wm.screen= (win)? win->screen: NULL;
C->data.scene= (C->wm.screen)? C->wm.screen->scene: NULL;
- C->wm.screen_cb= (C->wm.screen)? C->wm.screen->context: NULL;
}
void CTX_wm_screen_set(bContext *C, bScreen *screen)
{
C->wm.screen= screen;
C->data.scene= (C->wm.screen)? C->wm.screen->scene: NULL;
- C->wm.screen_cb= (C->wm.screen)? C->wm.screen->context: NULL;
}
void CTX_wm_area_set(bContext *C, ScrArea *area)
{
C->wm.area= area;
- C->wm.area_cb= (area && area->type)? area->type->context: NULL;
}
void CTX_wm_region_set(bContext *C, ARegion *region)
{
C->wm.region= region;
- C->wm.region_cb= (region && region->type)? region->type->context: NULL;
}
void CTX_wm_ui_block_set(bContext *C, struct uiBlock *block, bContextDataCallback cb)
@@ -240,21 +233,25 @@ static int ctx_data_get(bContext *C, const bContextDataMember *member, bContextD
/* we check recursion to ensure that we do not get infinite
* loops requesting data from ourselfs in a context callback */
- if(!done && recursion < 1 && C->wm.block_cb) {
+ if(!done && recursion < 1 && C->wm.block) {
C->data.recursion= 1;
done= C->wm.block_cb(C, member, result);
}
- if(!done && recursion < 2 && C->wm.region_cb) {
+ if(!done && recursion < 2 && C->wm.region) {
C->data.recursion= 2;
- done= C->wm.region_cb(C, member, result);
+ if(C->wm.region->type->context)
+ done= C->wm.region->type->context(C, member, result);
}
- if(!done && recursion < 3 && C->wm.area_cb) {
+ if(!done && recursion < 3 && C->wm.area) {
C->data.recursion= 3;
- done= C->wm.area_cb(C, member, result);
+ if(C->wm.area->type->context)
+ done= C->wm.area->type->context(C, member, result);
}
- if(!done && recursion < 4 && C->wm.screen_cb) {
+ if(!done && recursion < 4 && C->wm.screen) {
+ bContextDataCallback cb= C->wm.screen->context;
C->data.recursion= 4;
- done= C->wm.screen_cb(C, member, result);
+ if(cb)
+ done= cb(C, member, result);
}
C->data.recursion= recursion;
diff --git a/source/blender/blenkernel/intern/report.c b/source/blender/blenkernel/intern/report.c
index 12fbaf806d5..97bbaf66b3a 100644
--- a/source/blender/blenkernel/intern/report.c
+++ b/source/blender/blenkernel/intern/report.c
@@ -30,6 +30,7 @@
#include "DNA_listBase.h"
#include "BLI_blenlib.h"
+#include "BLI_dynstr.h"
#include "BKE_report.h"
@@ -59,6 +60,9 @@ static char *report_type_str(int type)
void BKE_reports_init(ReportList *reports, int flag)
{
+ if(!reports)
+ return;
+
memset(reports, 0, sizeof(ReportList));
reports->storelevel= RPT_WARNING;
@@ -70,6 +74,9 @@ void BKE_reports_clear(ReportList *reports)
{
Report *report;
+ if(!reports)
+ return;
+
for(report=reports->list.first; report; report=report->next)
MEM_freeN(report->message);
@@ -81,18 +88,12 @@ void BKE_report(ReportList *reports, ReportType type, const char *message)
Report *report;
int len;
- if(!reports)
- return;
-
- if(type >= RPT_ERROR)
- reports->flag |= RPT_HAS_ERROR;
-
- if((reports->flag & RPT_PRINT) && (type >= reports->printlevel)) {
+ if(!reports || ((reports->flag & RPT_PRINT) && (type >= reports->printlevel))) {
printf("%s: %s\n", report_type_str(type), message);
fflush(stdout); /* this ensures the message is printed before a crash */
}
- if((reports->flag & RPT_STORE) && (type >= reports->storelevel)) {
+ if(reports && (reports->flag & RPT_STORE) && (type >= reports->storelevel)) {
report= MEM_callocN(sizeof(Report), "Report");
report->type= type;
report->typestr= report_type_str(type);
@@ -107,83 +108,110 @@ void BKE_report(ReportList *reports, ReportType type, const char *message)
void BKE_reportf(ReportList *reports, ReportType type, const char *format, ...)
{
+ DynStr *ds;
Report *report;
va_list args;
- char *message;
- int len= 256, maxlen= 65536, retval;
-
- if(!reports)
- return;
-
- if(type >= RPT_ERROR)
- reports->flag |= RPT_HAS_ERROR;
- if((reports->flag & RPT_PRINT) && (type >= reports->printlevel)) {
+ if(!reports || ((reports->flag & RPT_PRINT) && (type >= reports->printlevel))) {
va_start(args, format);
vprintf(format, args);
va_end(args);
fflush(stdout); /* this ensures the message is printed before a crash */
}
- if((reports->flag & RPT_STORE) && (type >= reports->storelevel)) {
- while(1) {
- message= MEM_callocN(sizeof(char)*len+1, "ReportMessage");
-
- va_start(args, format);
- retval= vsnprintf(message, len, format, args);
- va_end(args);
-
- if(retval == -1) {
- /* -1 means not enough space, but on windows it may also mean
- * there is a formatting error, so we impose a maximum length */
- MEM_freeN(message);
- message= NULL;
-
- len *= 2;
- if(len > maxlen) {
- fprintf(stderr, "BKE_reportf message too long or format error.\n");
- break;
- }
- }
- else if(retval > len) {
- /* in C99 the actual length required is returned */
- MEM_freeN(message);
- message= NULL;
-
- len= retval;
- }
- else
- break;
- }
-
- if(message) {
- report= MEM_callocN(sizeof(Report), "Report");
- report->type= type;
- report->typestr= report_type_str(type);
- report->message= message;
-
- BLI_addtail(&reports->list, report);
- }
+ 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);
+
+ BLI_dynstr_free(ds);
+
+ report->type= type;
+ report->typestr= report_type_str(type);
+
+ BLI_addtail(&reports->list, report);
+ }
+}
+
+void BKE_reports_prepend(ReportList *reports, const char *prepend)
+{
+ Report *report;
+ DynStr *ds;
+
+ 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(report->message);
+
+ report->message= BLI_dynstr_get_cstring(ds);
+
+ BLI_dynstr_free(ds);
+ }
+}
+
+void BKE_reports_prependf(ReportList *reports, const char *prepend, ...)
+{
+ Report *report;
+ DynStr *ds;
+ va_list args;
+
+ 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(report->message);
+
+ report->message= BLI_dynstr_get_cstring(ds);
+
+ BLI_dynstr_free(ds);
}
}
ReportType BKE_report_print_level(ReportList *reports)
{
+ if(!reports)
+ return RPT_ERROR;
+
return reports->printlevel;
}
void BKE_report_print_level_set(ReportList *reports, ReportType level)
{
+ if(!reports)
+ return;
+
reports->printlevel= level;
}
ReportType BKE_report_store_level(ReportList *reports)
{
+ if(!reports)
+ return RPT_ERROR;
+
return reports->storelevel;
}
void BKE_report_store_level_set(ReportList *reports, ReportType level)
{
+ if(!reports)
+ return;
+
reports->storelevel= level;
}