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