|
Blender
V2.59
|
00001 /* 00002 * $Id: report.c 36271 2011-04-21 13:11:51Z campbellbarton $ 00003 * 00004 * ***** BEGIN GPL LICENSE BLOCK ***** 00005 * 00006 * This program is free software; you can redistribute it and/or 00007 * modify it under the terms of the GNU General Public License 00008 * as published by the Free Software Foundation; either version 2 00009 * of the License, or (at your option) any later version. 00010 * 00011 * This program is distributed in the hope that it will be useful, 00012 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00013 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00014 * GNU General Public License for more details. 00015 * 00016 * You should have received a copy of the GNU General Public License 00017 * along with this program; if not, write to the Free Software Foundation, 00018 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 00019 * 00020 * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV. 00021 * All rights reserved. 00022 * 00023 * Contributor(s): Blender Foundation (2008). 00024 * 00025 * ***** END GPL LICENSE BLOCK ***** 00026 */ 00027 00033 #include "MEM_guardedalloc.h" 00034 00035 #include "BLI_blenlib.h" 00036 #include "BLI_dynstr.h" 00037 #include "BLI_utildefines.h" 00038 00039 #include "BKE_report.h" 00040 #include "BKE_global.h" /* G.background only */ 00041 00042 00043 #include <stdarg.h> 00044 #include <stdio.h> 00045 #include <string.h> 00046 00047 #ifdef _WIN32 00048 #ifndef vsnprintf 00049 #define vsnprintf _vsnprintf 00050 #endif 00051 #endif 00052 00053 static const char *report_type_str(int type) 00054 { 00055 switch(type) { 00056 case RPT_DEBUG: return "Debug"; 00057 case RPT_INFO: return "Info"; 00058 case RPT_OPERATOR: return "Operator"; 00059 case RPT_WARNING: return "Warning"; 00060 case RPT_ERROR: return "Error"; 00061 case RPT_ERROR_INVALID_INPUT: return "Invalid Input Error"; 00062 case RPT_ERROR_INVALID_CONTEXT: return "Invalid Context Error"; 00063 case RPT_ERROR_OUT_OF_MEMORY: return "Out Of Memory Error"; 00064 default: return "Undefined Type"; 00065 } 00066 } 00067 00068 void BKE_reports_init(ReportList *reports, int flag) 00069 { 00070 if(!reports) 00071 return; 00072 00073 memset(reports, 0, sizeof(ReportList)); 00074 00075 reports->storelevel= RPT_INFO; 00076 reports->printlevel= RPT_ERROR; 00077 reports->flag= flag; 00078 } 00079 00080 void BKE_reports_clear(ReportList *reports) 00081 { 00082 Report *report, *report_next; 00083 00084 if(!reports) 00085 return; 00086 00087 report= reports->list.first; 00088 00089 while (report) { 00090 report_next= report->next; 00091 MEM_freeN((void *)report->message); 00092 MEM_freeN(report); 00093 report= report_next; 00094 } 00095 00096 reports->list.first= reports->list.last= NULL; 00097 } 00098 00099 void BKE_report(ReportList *reports, ReportType type, const char *message) 00100 { 00101 Report *report; 00102 int len; 00103 00104 /* in background mode always print otherwise there are cases the errors wont be displayed, 00105 * but still add to the report list since this is used for python exception handling */ 00106 if(G.background || !reports || ((reports->flag & RPT_PRINT) && (type >= reports->printlevel))) { 00107 printf("%s: %s\n", report_type_str(type), message); 00108 fflush(stdout); /* this ensures the message is printed before a crash */ 00109 } 00110 00111 if(reports && (reports->flag & RPT_STORE) && (type >= reports->storelevel)) { 00112 char *message_alloc; 00113 report= MEM_callocN(sizeof(Report), "Report"); 00114 report->type= type; 00115 report->typestr= report_type_str(type); 00116 00117 len= strlen(message); 00118 message_alloc= MEM_callocN(sizeof(char)*(len+1), "ReportMessage"); 00119 memcpy(message_alloc, message, sizeof(char)*(len+1)); 00120 report->message= message_alloc; 00121 report->len= len; 00122 BLI_addtail(&reports->list, report); 00123 } 00124 } 00125 00126 void BKE_reportf(ReportList *reports, ReportType type, const char *format, ...) 00127 { 00128 DynStr *ds; 00129 Report *report; 00130 va_list args; 00131 00132 if(G.background || !reports || ((reports->flag & RPT_PRINT) && (type >= reports->printlevel))) { 00133 va_start(args, format); 00134 vprintf(format, args); 00135 va_end(args); 00136 fprintf(stdout, "\n"); /* otherise each report needs to include a \n */ 00137 fflush(stdout); /* this ensures the message is printed before a crash */ 00138 } 00139 00140 if(reports && (reports->flag & RPT_STORE) && (type >= reports->storelevel)) { 00141 report= MEM_callocN(sizeof(Report), "Report"); 00142 00143 ds= BLI_dynstr_new(); 00144 va_start(args, format); 00145 BLI_dynstr_vappendf(ds, format, args); 00146 va_end(args); 00147 00148 report->message= BLI_dynstr_get_cstring(ds); 00149 report->len= BLI_dynstr_get_len(ds); 00150 BLI_dynstr_free(ds); 00151 00152 report->type= type; 00153 report->typestr= report_type_str(type); 00154 00155 BLI_addtail(&reports->list, report); 00156 } 00157 } 00158 00159 void BKE_reports_prepend(ReportList *reports, const char *prepend) 00160 { 00161 Report *report; 00162 DynStr *ds; 00163 00164 if(!reports) 00165 return; 00166 00167 for(report=reports->list.first; report; report=report->next) { 00168 ds= BLI_dynstr_new(); 00169 00170 BLI_dynstr_append(ds, prepend); 00171 BLI_dynstr_append(ds, report->message); 00172 MEM_freeN((void *)report->message); 00173 00174 report->message= BLI_dynstr_get_cstring(ds); 00175 report->len= BLI_dynstr_get_len(ds); 00176 00177 BLI_dynstr_free(ds); 00178 } 00179 } 00180 00181 void BKE_reports_prependf(ReportList *reports, const char *prepend, ...) 00182 { 00183 Report *report; 00184 DynStr *ds; 00185 va_list args; 00186 00187 if(!reports) 00188 return; 00189 00190 for(report=reports->list.first; report; report=report->next) { 00191 ds= BLI_dynstr_new(); 00192 va_start(args, prepend); 00193 BLI_dynstr_vappendf(ds, prepend, args); 00194 va_end(args); 00195 00196 BLI_dynstr_append(ds, report->message); 00197 MEM_freeN((void *)report->message); 00198 00199 report->message= BLI_dynstr_get_cstring(ds); 00200 report->len= BLI_dynstr_get_len(ds); 00201 00202 BLI_dynstr_free(ds); 00203 } 00204 } 00205 00206 ReportType BKE_report_print_level(ReportList *reports) 00207 { 00208 if(!reports) 00209 return RPT_ERROR; 00210 00211 return reports->printlevel; 00212 } 00213 00214 void BKE_report_print_level_set(ReportList *reports, ReportType level) 00215 { 00216 if(!reports) 00217 return; 00218 00219 reports->printlevel= level; 00220 } 00221 00222 ReportType BKE_report_store_level(ReportList *reports) 00223 { 00224 if(!reports) 00225 return RPT_ERROR; 00226 00227 return reports->storelevel; 00228 } 00229 00230 void BKE_report_store_level_set(ReportList *reports, ReportType level) 00231 { 00232 if(!reports) 00233 return; 00234 00235 reports->storelevel= level; 00236 } 00237 00238 char *BKE_reports_string(ReportList *reports, ReportType level) 00239 { 00240 Report *report; 00241 DynStr *ds; 00242 char *cstring; 00243 00244 if(!reports || !reports->list.first) 00245 return NULL; 00246 00247 ds= BLI_dynstr_new(); 00248 for(report=reports->list.first; report; report=report->next) 00249 if(report->type >= level) 00250 BLI_dynstr_appendf(ds, "%s: %s\n", report->typestr, report->message); 00251 00252 if (BLI_dynstr_get_len(ds)) 00253 cstring= BLI_dynstr_get_cstring(ds); 00254 else 00255 cstring= NULL; 00256 00257 BLI_dynstr_free(ds); 00258 return cstring; 00259 } 00260 00261 void BKE_reports_print(ReportList *reports, ReportType level) 00262 { 00263 char *cstring = BKE_reports_string(reports, level); 00264 00265 if (cstring == NULL) 00266 return; 00267 00268 printf("%s", cstring); 00269 fflush(stdout); 00270 MEM_freeN(cstring); 00271 } 00272 00273 Report *BKE_reports_last_displayable(ReportList *reports) 00274 { 00275 Report *report=NULL; 00276 00277 for (report= (Report *)reports->list.last; report; report=report->prev) { 00278 if (ELEM3(report->type, RPT_ERROR, RPT_WARNING, RPT_INFO)) 00279 return report; 00280 } 00281 00282 return NULL; 00283 }