#include "TMVA/MsgLogger.h"
#include "TMVA/Config.h"
#include "Riostream.h"
#include <iomanip>
#include <cstdlib>
#include <assert.h>
ClassImp(TMVA::MsgLogger)
UInt_t TMVA::MsgLogger::fgMaxSourceSize = 25;
Bool_t TMVA::MsgLogger::fgInhibitOutput = kFALSE;
const std::string TMVA::MsgLogger::fgPrefix = "--- ";
const std::string TMVA::MsgLogger::fgSuffix = ": ";
std::map<TMVA::EMsgType, std::string>* TMVA::MsgLogger::fgTypeMap = 0;
std::map<TMVA::EMsgType, std::string>* TMVA::MsgLogger::fgColorMap = 0;
Int_t TMVA::MsgLogger::fgInstanceCounter = 0;
void TMVA::MsgLogger::InhibitOutput() { fgInhibitOutput = kTRUE; }
void TMVA::MsgLogger::EnableOutput() { fgInhibitOutput = kFALSE; }
TMVA::MsgLogger::MsgLogger( const TObject* source, EMsgType minType )
: fObjSource ( source ),
fStrSource ( "" ),
fActiveType( kINFO ),
fMinType ( minType )
{
fgInstanceCounter++;
InitMaps();
}
TMVA::MsgLogger::MsgLogger( const std::string& source, EMsgType minType )
: fObjSource ( 0 ),
fStrSource ( source ),
fActiveType( kINFO ),
fMinType ( minType )
{
fgInstanceCounter++;
InitMaps();
}
TMVA::MsgLogger::MsgLogger( EMsgType minType )
: fObjSource ( 0 ),
fStrSource ( "Unknown" ),
fActiveType( kINFO ),
fMinType ( minType )
{
fgInstanceCounter++;
InitMaps();
}
TMVA::MsgLogger::MsgLogger( const MsgLogger& parent )
: std::basic_ios<MsgLogger::char_type, MsgLogger::traits_type>(),
std::ostringstream(),
TObject(),
fObjSource(0)
{
fgInstanceCounter++;
InitMaps();
*this = parent;
}
TMVA::MsgLogger::~MsgLogger()
{
fgInstanceCounter--;
if (fgInstanceCounter == 0) {
delete fgTypeMap; fgTypeMap = 0;
delete fgColorMap; fgColorMap = 0;
}
}
TMVA::MsgLogger& TMVA::MsgLogger::operator= ( const MsgLogger& parent )
{
if (&parent != this) {
fObjSource = parent.fObjSource;
fStrSource = parent.fStrSource;
fActiveType = parent.fActiveType;
fMinType = parent.fMinType;
}
return *this;
}
std::string TMVA::MsgLogger::GetFormattedSource() const
{
std::string source_name;
if (fObjSource) source_name = fObjSource->GetName();
else source_name = fStrSource;
if (source_name.size() > fgMaxSourceSize) {
source_name = source_name.substr( 0, fgMaxSourceSize - 3 );
source_name += "...";
}
return source_name;
}
std::string TMVA::MsgLogger::GetPrintedSource() const
{
std::string source_name = GetFormattedSource();
if (source_name.size() < fgMaxSourceSize)
for (std::string::size_type i=source_name.size(); i<fgMaxSourceSize; i++) source_name.push_back( ' ' );
return fgPrefix + source_name + fgSuffix;
}
void TMVA::MsgLogger::Send()
{
std::string source_name = GetFormattedSource();
std::string message = this->str();
std::string::size_type previous_pos = 0, current_pos = 0;
while (kTRUE) {
current_pos = message.find( '\n', previous_pos );
std::string line = message.substr( previous_pos, current_pos - previous_pos );
std::ostringstream message_to_send;
message_to_send.setf( std::ios::adjustfield, std::ios::left );
message_to_send.width( fgMaxSourceSize );
message_to_send << source_name << fgSuffix << line;
this->WriteMsg( fActiveType, message_to_send.str() );
if (current_pos == message.npos) break;
previous_pos = current_pos + 1;
}
this->str( "" );
fActiveType = kINFO;
return;
}
void TMVA::MsgLogger::WriteMsg( EMsgType type, const std::string& line ) const
{
if ( (type < fMinType || fgInhibitOutput) && type!=kFATAL ) return;
std::map<EMsgType, std::string>::const_iterator stype;
if ((stype = fgTypeMap->find( type )) != fgTypeMap->end()) {
if (!gConfig().IsSilent() || type==kFATAL) {
if (gConfig().UseColor()) {
if (type == kINFO || type == kVERBOSE)
std::cout << fgPrefix << line << std::endl;
else
std::cout << fgColorMap->find( type )->second << fgPrefix << "<"
<< stype->second << "> " << line << "\033[0m" << std::endl;
}
else {
if (type == kINFO) std::cout << fgPrefix << line << std::endl;
else std::cout << fgPrefix << "<" << stype->second << "> " << line << std::endl;
}
}
}
if (type == kFATAL) {
std::cout << "***> abort program execution" << std::endl;
std::exit(1);
assert(false);
}
}
TMVA::MsgLogger& TMVA::MsgLogger::Endmsg( MsgLogger& logger )
{
logger.Send();
return logger;
}
void TMVA::MsgLogger::InitMaps()
{
if (fgTypeMap != 0 && fgColorMap != 0) return;
fgTypeMap = new std::map<TMVA::EMsgType, std::string>();
fgColorMap = new std::map<TMVA::EMsgType, std::string>();
(*fgTypeMap)[kVERBOSE] = std::string("VERBOSE");
(*fgTypeMap)[kDEBUG] = std::string("DEBUG");
(*fgTypeMap)[kINFO] = std::string("INFO");
(*fgTypeMap)[kWARNING] = std::string("WARNING");
(*fgTypeMap)[kERROR] = std::string("ERROR");
(*fgTypeMap)[kFATAL] = std::string("FATAL");
(*fgTypeMap)[kSILENT] = std::string("SILENT");
(*fgColorMap)[kVERBOSE] = std::string("");
(*fgColorMap)[kDEBUG] = std::string("\033[34m");
(*fgColorMap)[kINFO] = std::string("");
(*fgColorMap)[kWARNING] = std::string("\033[1;31m");
(*fgColorMap)[kERROR] = std::string("\033[31m");
(*fgColorMap)[kFATAL] = std::string("\033[37;41;1m");
(*fgColorMap)[kSILENT] = std::string("\033[30m");
}