// // ******************************************************************** // * License and Disclaimer * // * * // * The Geant4 software is copyright of the Copyright Holders of * // * the Geant4 Collaboration. It is provided under the terms and * // * conditions of the Geant4 Software License, included in the file * // * LICENSE and available at http://cern.ch/geant4/license . These * // * include a list of copyright holders. * // * * // * Neither the authors of this software system, nor their employing * // * institutes,nor the agencies providing financial support for this * // * work make any representation or warranty, express or implied, * // * regarding this software system or assume any liability for its * // * use. Please see the license in the file LICENSE and URL above * // * for the full disclaimer and the limitation of liability. * // * * // * This code implementation is the result of the scientific and * // * technical work of the GEANT4 collaboration. * // * By using, copying, modifying or distributing the software (or * // * any work based on the software) you agree to acknowledge its * // * use in resulting scientific publications, and indicate your * // * acceptance of all terms of the Geant4 Software license. * // ******************************************************************** // // INCL++ intra-nuclear cascade model // Pekka Kaitaniemi, CEA and Helsinki Institute of Physics // Davide Mancusi, CEA // Alain Boudard, CEA // Sylvie Leray, CEA // Joseph Cugnon, University of Liege // #define INCLXX_IN_GEANT4_MODE 1 #include "globals.hh" #ifndef G4INCLLogger_hh #define G4INCLLogger_hh 1 #include #include #include #include #include namespace G4INCL { /** * Verbosity scale from 0 (fatal errors only) to 10 (print everything) */ enum MessageType { InfoMsg = 1, FatalMsg = 2, ErrorMsg = 3, WarningMsg = 4, DebugMsg = 7, DataBlockMsg = 10, ZeroMsg = 0 }; #if defined(INCL_DEBUG_LOG) && !defined(INCLXX_IN_GEANT4_MODE) class LoggerSlave { public: // By default, log fatal errors, errors and warnings LoggerSlave(std::string const &logFileName) : logStream(0), verbosityLevel(4) { if(logFileName=="-") { logStream = &(std::cout); logToStdout = true; } else { logToStdout = false; logStream = new std::ofstream(logFileName.c_str()); if(!logStream) { std::cerr << "Fatal error: couldn't open log file " << logFileName << std::endl; std::exit(EXIT_FAILURE); } } // Spell out "true" and "false" when logging G4bool variables std::boolalpha(*logStream); logMessage(InfoMsg, __FILE__,__LINE__, "# Logging enabled!\n"); }; ~LoggerSlave() { if(!logToStdout) delete logStream; }; /** * Set the verbosity level */ void setVerbosityLevel(G4int lvl) { verbosityLevel = lvl; } /** * Get the verbosity level */ G4int getVerbosityLevel() { return verbosityLevel; } /// \brief Write the log message. void logMessage(const MessageType type, const std::string &fileName, const G4int lineNumber, std::string const &s) const; /// \brief Flush the log stream void flush() { logStream->flush(); } /// \brief Log a data block. void logDataBlock(const std::string &block, const std::string &fileName, const G4int lineNumber) const; typedef std::basic_ostream > CoutType; typedef CoutType& (*StandardEndLine)(CoutType&); /// \brief Overload << operator to support std::endl. LoggerSlave const &operator<<(StandardEndLine const &manip) const { manip(*logStream); return *this; } /// \brief Overloaded << operator to provide a stream-like API. template LoggerSlave const &operator<<(const T &t) const { (*logStream) << t; return *this; } private: std::ostream *logStream; G4int verbosityLevel; G4bool logToStdout; }; class Logger { public: /// \brief Log a message. static void logMessage(const MessageType type, std::string const &fileName, const G4int lineNumber, std::string const &s) { theLoggerSlave->logMessage(type, fileName, lineNumber, s); } /// \brief Flush the log stream static void flush() { theLoggerSlave->flush(); } /// \brief Log a data block. static void dataBlock(const std::string &block, const std::string &fileName, const G4int lineNumber) { theLoggerSlave->logDataBlock(block, fileName, lineNumber); } /// \brief Set the slave Logger. static void setLoggerSlave(LoggerSlave * const logger) { theLoggerSlave = logger; } /// \brief Set the verbosity of the slave Logger. static void setVerbosityLevel(G4int lvl) { theLoggerSlave->setVerbosityLevel(lvl); } /// \brief Get the verbosity of the slave Logger. static G4int getVerbosityLevel() { return theLoggerSlave->getVerbosityLevel(); } /// \brief Delete the slave Logger. static void deleteLoggerSlave() { delete theLoggerSlave; theLoggerSlave=NULL; } private: static LoggerSlave *theLoggerSlave; }; // Macro definitions for line numbering in log files! #define FATAL(x) \ if(true) {\ std::stringstream ss;\ ss << x;\ G4INCL::Logger::logMessage(G4INCL::FatalMsg, __FILE__,__LINE__, ss.str());\ G4INCL::Logger::flush();\ std::exit(EXIT_FAILURE);\ } else (void)0 #define ERROR(x) \ if(G4INCL::ErrorMsg <= G4INCL::Logger::getVerbosityLevel()) {\ std::stringstream ss;\ ss << x;\ G4INCL::Logger::logMessage(G4INCL::ErrorMsg, __FILE__,__LINE__, ss.str());\ } else (void)0 #define WARN(x) \ if(G4INCL::WarningMsg <= G4INCL::Logger::getVerbosityLevel()) {\ std::stringstream ss;\ ss << x;\ G4INCL::Logger::logMessage(G4INCL::WarningMsg, __FILE__,__LINE__, ss.str());\ } else (void)0 #define INFO(x) \ if(G4INCL::InfoMsg <= G4INCL::Logger::getVerbosityLevel()) {\ std::stringstream ss;\ ss << x;\ G4INCL::Logger::logMessage(G4INCL::InfoMsg, __FILE__,__LINE__, ss.str());\ } else (void)0 #define DEBUG(x) \ if(G4INCL::DebugMsg <= G4INCL::Logger::getVerbosityLevel()) {\ std::stringstream ss;\ ss << x;\ G4INCL::Logger::logMessage(G4INCL::DebugMsg, __FILE__,__LINE__, ss.str());\ } else (void)0 #define DATABLOCK(x) \ if(G4INCL::DataBlockMsg <= G4INCL::Logger::getVerbosityLevel()) {\ G4INCL::Logger::dataBlock(x,__FILE__,__LINE__);\ } else (void)0 #else // Empty logger for normal (production) use: class LoggerSlave { public: LoggerSlave(std::string const &) {}; LoggerSlave() {}; ~LoggerSlave() {}; void setVerbosityLevel(G4int) {}; }; class Logger { public: Logger() {}; ~Logger() {}; static void setVerbosityLevel(G4int) {}; static void setLoggerSlave(LoggerSlave * const slave) { theLoggerSlave = slave; } static void deleteLoggerSlave() { delete theLoggerSlave; theLoggerSlave=NULL; } private: static LoggerSlave *theLoggerSlave; }; #define FATAL(x) \ if(true) {\ std::stringstream ss;\ ss << x;\ std::stringstream location;\ location << __FILE__ << ":" << __LINE__;\ G4Exception(location.str().c_str(), "INCLXX0000", FatalException, ss.str().c_str());\ } else (void)0 #define ERROR(x); #define WARN(x); #define INFO(x); #define DEBUG(x); #define DATABLOCK(x); #endif } #endif