00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026 #include "TMVA/MsgLogger.h"
00027 #include "TMVA/Config.h"
00028
00029 #include "Riostream.h"
00030
00031
00032 #include <iomanip>
00033
00034 #include <cstdlib>
00035
00036 #include <assert.h>
00037
00038
00039
00040 ClassImp(TMVA::MsgLogger)
00041
00042
00043
00044 UInt_t TMVA::MsgLogger::fgMaxSourceSize = 25;
00045 Bool_t TMVA::MsgLogger::fgInhibitOutput = kFALSE;
00046
00047 const std::string TMVA::MsgLogger::fgPrefix = "--- ";
00048 const std::string TMVA::MsgLogger::fgSuffix = ": ";
00049 std::map<TMVA::EMsgType, std::string>* TMVA::MsgLogger::fgTypeMap = 0;
00050 std::map<TMVA::EMsgType, std::string>* TMVA::MsgLogger::fgColorMap = 0;
00051 Int_t TMVA::MsgLogger::fgInstanceCounter = 0;
00052
00053 void TMVA::MsgLogger::InhibitOutput() { fgInhibitOutput = kTRUE; }
00054 void TMVA::MsgLogger::EnableOutput() { fgInhibitOutput = kFALSE; }
00055
00056 TMVA::MsgLogger::MsgLogger( const TObject* source, EMsgType minType )
00057 : fObjSource ( source ),
00058 fStrSource ( "" ),
00059 fActiveType( kINFO ),
00060 fMinType ( minType )
00061 {
00062
00063 fgInstanceCounter++;
00064 InitMaps();
00065 }
00066
00067
00068 TMVA::MsgLogger::MsgLogger( const std::string& source, EMsgType minType )
00069 : fObjSource ( 0 ),
00070 fStrSource ( source ),
00071 fActiveType( kINFO ),
00072 fMinType ( minType )
00073 {
00074
00075 fgInstanceCounter++;
00076 InitMaps();
00077 }
00078
00079
00080 TMVA::MsgLogger::MsgLogger( EMsgType minType )
00081 : fObjSource ( 0 ),
00082 fStrSource ( "Unknown" ),
00083 fActiveType( kINFO ),
00084 fMinType ( minType )
00085 {
00086
00087 fgInstanceCounter++;
00088 InitMaps();
00089 }
00090
00091
00092 TMVA::MsgLogger::MsgLogger( const MsgLogger& parent )
00093 : std::basic_ios<MsgLogger::char_type, MsgLogger::traits_type>(),
00094 std::ostringstream(),
00095 TObject()
00096 {
00097
00098 fgInstanceCounter++;
00099 InitMaps();
00100 *this = parent;
00101 }
00102
00103
00104 TMVA::MsgLogger::~MsgLogger()
00105 {
00106
00107 fgInstanceCounter--;
00108 if (fgInstanceCounter == 0) {
00109
00110 delete fgTypeMap; fgTypeMap = 0;
00111 delete fgColorMap; fgColorMap = 0;
00112 }
00113 }
00114
00115
00116 TMVA::MsgLogger& TMVA::MsgLogger::operator= ( const MsgLogger& parent )
00117 {
00118
00119 if (&parent != this) {
00120 fObjSource = parent.fObjSource;
00121 fStrSource = parent.fStrSource;
00122 fActiveType = parent.fActiveType;
00123 fMinType = parent.fMinType;
00124 }
00125
00126 return *this;
00127 }
00128
00129
00130 std::string TMVA::MsgLogger::GetFormattedSource() const
00131 {
00132
00133 std::string source_name;
00134 if (fObjSource) source_name = fObjSource->GetName();
00135 else source_name = fStrSource;
00136
00137 if (source_name.size() > fgMaxSourceSize) {
00138 source_name = source_name.substr( 0, fgMaxSourceSize - 3 );
00139 source_name += "...";
00140 }
00141
00142 return source_name;
00143 }
00144
00145
00146 std::string TMVA::MsgLogger::GetPrintedSource() const
00147 {
00148
00149 std::string source_name = GetFormattedSource();
00150 if (source_name.size() < fgMaxSourceSize)
00151 for (std::string::size_type i=source_name.size(); i<fgMaxSourceSize; i++) source_name.push_back( ' ' );
00152
00153 return fgPrefix + source_name + fgSuffix;
00154 }
00155
00156
00157 void TMVA::MsgLogger::Send()
00158 {
00159
00160
00161
00162 std::string source_name = GetFormattedSource();
00163
00164 std::string message = this->str();
00165 std::string::size_type previous_pos = 0, current_pos = 0;
00166
00167
00168 while (kTRUE) {
00169 current_pos = message.find( '\n', previous_pos );
00170 std::string line = message.substr( previous_pos, current_pos - previous_pos );
00171
00172 std::ostringstream message_to_send;
00173
00174 message_to_send.setf( std::ios::adjustfield, std::ios::left );
00175 message_to_send.width( fgMaxSourceSize );
00176 message_to_send << source_name << fgSuffix << line;
00177 this->WriteMsg( fActiveType, message_to_send.str() );
00178
00179 if (current_pos == message.npos) break;
00180 previous_pos = current_pos + 1;
00181 }
00182
00183
00184 this->str( "" );
00185 fActiveType = kINFO;
00186 return;
00187 }
00188
00189
00190 void TMVA::MsgLogger::WriteMsg( EMsgType type, const std::string& line ) const
00191 {
00192
00193
00194
00195 if ( (type < fMinType || fgInhibitOutput) && type!=kFATAL ) return;
00196
00197 std::map<EMsgType, std::string>::const_iterator stype;
00198
00199 if ((stype = fgTypeMap->find( type )) != fgTypeMap->end()) {
00200 if (!gConfig().IsSilent() || type==kFATAL) {
00201 if (gConfig().UseColor()) {
00202
00203 if (type == kINFO || type == kVERBOSE)
00204 std::cout << fgPrefix << line << std::endl;
00205 else
00206 std::cout << fgColorMap->find( type )->second << fgPrefix << "<"
00207 << stype->second << "> " << line << "\033[0m" << std::endl;
00208 }
00209 else {
00210 if (type == kINFO) std::cout << fgPrefix << line << std::endl;
00211 else std::cout << fgPrefix << "<" << stype->second << "> " << line << std::endl;
00212 }
00213 }
00214 }
00215
00216
00217 if (type == kFATAL) {
00218 std::cout << "***> abort program execution" << std::endl;
00219 std::exit(1);
00220 assert(false);
00221 }
00222 }
00223
00224
00225 TMVA::MsgLogger& TMVA::MsgLogger::Endmsg( MsgLogger& logger )
00226 {
00227
00228 logger.Send();
00229 return logger;
00230 }
00231
00232
00233 void TMVA::MsgLogger::InitMaps()
00234 {
00235
00236 if (fgTypeMap != 0 && fgColorMap != 0) return;
00237
00238 fgTypeMap = new std::map<TMVA::EMsgType, std::string>();
00239 fgColorMap = new std::map<TMVA::EMsgType, std::string>();
00240
00241 (*fgTypeMap)[kVERBOSE] = std::string("VERBOSE");
00242 (*fgTypeMap)[kDEBUG] = std::string("DEBUG");
00243 (*fgTypeMap)[kINFO] = std::string("INFO");
00244 (*fgTypeMap)[kWARNING] = std::string("WARNING");
00245 (*fgTypeMap)[kERROR] = std::string("ERROR");
00246 (*fgTypeMap)[kFATAL] = std::string("FATAL");
00247 (*fgTypeMap)[kSILENT] = std::string("SILENT");
00248
00249 (*fgColorMap)[kVERBOSE] = std::string("");
00250 (*fgColorMap)[kDEBUG] = std::string("\033[34m");
00251 (*fgColorMap)[kINFO] = std::string("");
00252 (*fgColorMap)[kWARNING] = std::string("\033[1;31m");
00253 (*fgColorMap)[kERROR] = std::string("\033[31m");
00254 (*fgColorMap)[kFATAL] = std::string("\033[37;41;1m");
00255 (*fgColorMap)[kSILENT] = std::string("\033[30m");
00256 }