00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024 #ifdef WIN32
00025 #include <windows.h>
00026 #endif
00027
00028 #include <stdio.h>
00029 #include <stdlib.h>
00030 #include "snprintf.h"
00031 #include "Varargs.h"
00032 #include "Riostream.h"
00033 #include "TError.h"
00034 #include "TSystem.h"
00035 #include "TString.h"
00036 #include "TEnv.h"
00037 #include "TVirtualMutex.h"
00038
00039
00040
00041
00042 TVirtualMutex *gErrorMutex = 0;
00043
00044 Int_t gErrorIgnoreLevel = kUnset;
00045 Int_t gErrorAbortLevel = kSysError+1;
00046 Bool_t gPrintViaErrorHandler = kFALSE;
00047
00048 const char *kAssertMsg = "%s violated at line %d of `%s'";
00049 const char *kCheckMsg = "%s not true at line %d of `%s'";
00050
00051
00052 #ifdef __APPLE__
00053 extern "C" const char *__crashreporter_info__;
00054 const char *__crashreporter_info__ = 0;
00055 #endif
00056
00057 static ErrorHandlerFunc_t gErrorHandler = DefaultErrorHandler;
00058
00059
00060
00061 static void DebugPrint(const char *fmt, ...)
00062 {
00063
00064
00065 static Int_t buf_size = 2048;
00066 static char *buf = 0;
00067
00068 R__LOCKGUARD2(gErrorMutex);
00069
00070 va_list ap;
00071 va_start(ap, fmt);
00072
00073 again:
00074 if (!buf)
00075 buf = new char[buf_size];
00076
00077 Int_t n = vsnprintf(buf, buf_size, fmt, ap);
00078
00079
00080 if (n == -1 || n >= buf_size) {
00081 if (n == -1)
00082 buf_size *= 2;
00083 else
00084 buf_size = n+1;
00085 delete [] buf;
00086 buf = 0;
00087 va_end(ap);
00088 va_start(ap, fmt);
00089 goto again;
00090 }
00091 va_end(ap);
00092
00093 fprintf(stderr, "%s", buf);
00094
00095 #ifdef WIN32
00096 ::OutputDebugString(buf);
00097 #endif
00098 }
00099
00100
00101 ErrorHandlerFunc_t SetErrorHandler(ErrorHandlerFunc_t newhandler)
00102 {
00103
00104
00105 ErrorHandlerFunc_t oldhandler = gErrorHandler;
00106 gErrorHandler = newhandler;
00107 return oldhandler;
00108 }
00109
00110
00111 ErrorHandlerFunc_t GetErrorHandler()
00112 {
00113
00114
00115 return gErrorHandler;
00116 }
00117
00118
00119 void DefaultErrorHandler(Int_t level, Bool_t abort_bool, const char *location, const char *msg)
00120 {
00121
00122
00123
00124 if (gErrorIgnoreLevel == kUnset) {
00125 R__LOCKGUARD2(gErrorMutex);
00126
00127 gErrorIgnoreLevel = 0;
00128 if (gEnv) {
00129 TString slevel = gEnv->GetValue("Root.ErrorIgnoreLevel", "Print");
00130 if (!slevel.CompareTo("Print", TString::kIgnoreCase))
00131 gErrorIgnoreLevel = kPrint;
00132 else if (!slevel.CompareTo("Info", TString::kIgnoreCase))
00133 gErrorIgnoreLevel = kInfo;
00134 else if (!slevel.CompareTo("Warning", TString::kIgnoreCase))
00135 gErrorIgnoreLevel = kWarning;
00136 else if (!slevel.CompareTo("Error", TString::kIgnoreCase))
00137 gErrorIgnoreLevel = kError;
00138 else if (!slevel.CompareTo("Break", TString::kIgnoreCase))
00139 gErrorIgnoreLevel = kBreak;
00140 else if (!slevel.CompareTo("SysError", TString::kIgnoreCase))
00141 gErrorIgnoreLevel = kSysError;
00142 else if (!slevel.CompareTo("Fatal", TString::kIgnoreCase))
00143 gErrorIgnoreLevel = kFatal;
00144 }
00145 }
00146
00147 if (level < gErrorIgnoreLevel)
00148 return;
00149
00150 const char *type = 0;
00151
00152 if (level >= kInfo)
00153 type = "Info";
00154 if (level >= kWarning)
00155 type = "Warning";
00156 if (level >= kError)
00157 type = "Error";
00158 if (level >= kBreak)
00159 type = "\n *** Break ***";
00160 if (level >= kSysError)
00161 type = "SysError";
00162 if (level >= kFatal)
00163 type = "Fatal";
00164
00165 TString smsg;
00166 if (level >= kPrint && level < kInfo)
00167 smsg.Form("%s", msg);
00168 else if (level >= kBreak && level < kSysError)
00169 smsg.Form("%s %s", type, msg);
00170 else if (!location || strlen(location) == 0)
00171 smsg.Form("%s: %s", type, msg);
00172 else
00173 smsg.Form("%s in <%s>: %s", type, location, msg);
00174
00175 DebugPrint("%s\n", smsg.Data());
00176
00177 #ifdef __APPLE__
00178 if (__crashreporter_info__)
00179 delete [] __crashreporter_info__;
00180 __crashreporter_info__ = StrDup(smsg);
00181 #endif
00182
00183 fflush(stderr);
00184 if (abort_bool) {
00185 DebugPrint("aborting\n");
00186 fflush(stderr);
00187 if (gSystem) {
00188 gSystem->StackTrace();
00189 gSystem->Abort();
00190 } else
00191 abort();
00192 }
00193 }
00194
00195
00196 void ErrorHandler(Int_t level, const char *location, const char *fmt, va_list ap)
00197 {
00198
00199
00200 R__LOCKGUARD2(gErrorMutex);
00201
00202 static Int_t buf_size = 2048;
00203 static char *buf = 0;
00204
00205 int vc = 0;
00206 va_list sap;
00207 R__VA_COPY(sap, ap);
00208
00209 again:
00210 if (!buf)
00211 buf = new char[buf_size];
00212
00213 if (!fmt)
00214 fmt = "no error message provided";
00215
00216 Int_t n = vsnprintf(buf, buf_size, fmt, ap);
00217
00218
00219 if (n == -1 || n >= buf_size) {
00220 if (n == -1)
00221 buf_size *= 2;
00222 else
00223 buf_size = n+1;
00224 delete [] buf;
00225 buf = 0;
00226 va_end(ap);
00227 R__VA_COPY(ap, sap);
00228 vc = 1;
00229 goto again;
00230 }
00231 va_end(sap);
00232 if (vc)
00233 va_end(ap);
00234
00235 char *bp;
00236 if (level >= kSysError && level < kFatal)
00237 bp = Form("%s (%s)", buf, gSystem->GetError());
00238 else
00239 bp = buf;
00240
00241 if (level != kFatal)
00242 gErrorHandler(level, level >= gErrorAbortLevel, location, bp);
00243 else
00244 gErrorHandler(level, kTRUE, location, bp);
00245 }
00246
00247
00248 void AbstractMethod(const char *method)
00249 {
00250
00251
00252
00253
00254
00255 Warning(method, "this method must be overridden!");
00256 }
00257
00258
00259 void MayNotUse(const char *method)
00260 {
00261
00262
00263
00264 Warning(method, "may not use this method");
00265 }
00266
00267
00268 void Error(const char *location, const char *va_(fmt), ...)
00269 {
00270
00271
00272 va_list ap;
00273 va_start(ap,va_(fmt));
00274 ErrorHandler(kError, location, va_(fmt), ap);
00275 va_end(ap);
00276 }
00277
00278
00279 void SysError(const char *location, const char *va_(fmt), ...)
00280 {
00281
00282
00283 va_list ap;
00284 va_start(ap, va_(fmt));
00285 ErrorHandler(kSysError, location, va_(fmt), ap);
00286 va_end(ap);
00287 }
00288
00289
00290 void Break(const char *location, const char *va_(fmt), ...)
00291 {
00292
00293
00294 va_list ap;
00295 va_start(ap,va_(fmt));
00296 ErrorHandler(kBreak, location, va_(fmt), ap);
00297 va_end(ap);
00298 }
00299
00300
00301 void Info(const char *location, const char *va_(fmt), ...)
00302 {
00303
00304
00305 va_list ap;
00306 va_start(ap,va_(fmt));
00307 ErrorHandler(kInfo, location, va_(fmt), ap);
00308 va_end(ap);
00309 }
00310
00311
00312 void Warning(const char *location, const char *va_(fmt), ...)
00313 {
00314
00315
00316 va_list ap;
00317 va_start(ap,va_(fmt));
00318 ErrorHandler(kWarning, location, va_(fmt), ap);
00319 va_end(ap);
00320 }
00321
00322
00323 void Fatal(const char *location, const char *va_(fmt), ...)
00324 {
00325
00326
00327 va_list ap;
00328 va_start(ap,va_(fmt));
00329 ErrorHandler(kFatal, location, va_(fmt), ap);
00330 va_end(ap);
00331 }