Geant4  9.6.p02
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
G4INCLLogger.hh
Go to the documentation of this file.
1 //
2 // ********************************************************************
3 // * License and Disclaimer *
4 // * *
5 // * The Geant4 software is copyright of the Copyright Holders of *
6 // * the Geant4 Collaboration. It is provided under the terms and *
7 // * conditions of the Geant4 Software License, included in the file *
8 // * LICENSE and available at http://cern.ch/geant4/license . These *
9 // * include a list of copyright holders. *
10 // * *
11 // * Neither the authors of this software system, nor their employing *
12 // * institutes,nor the agencies providing financial support for this *
13 // * work make any representation or warranty, express or implied, *
14 // * regarding this software system or assume any liability for its *
15 // * use. Please see the license in the file LICENSE and URL above *
16 // * for the full disclaimer and the limitation of liability. *
17 // * *
18 // * This code implementation is the result of the scientific and *
19 // * technical work of the GEANT4 collaboration. *
20 // * By using, copying, modifying or distributing the software (or *
21 // * any work based on the software) you agree to acknowledge its *
22 // * use in resulting scientific publications, and indicate your *
23 // * acceptance of all terms of the Geant4 Software license. *
24 // ********************************************************************
25 //
26 // INCL++ intra-nuclear cascade model
27 // Pekka Kaitaniemi, CEA and Helsinki Institute of Physics
28 // Davide Mancusi, CEA
29 // Alain Boudard, CEA
30 // Sylvie Leray, CEA
31 // Joseph Cugnon, University of Liege
32 //
33 #define INCLXX_IN_GEANT4_MODE 1
34 
35 #include "globals.hh"
36 
37 #ifndef G4INCLLogger_hh
38 #define G4INCLLogger_hh 1
39 
40 #include <iostream>
41 #include <fstream>
42 #include <sstream>
43 #include <string>
44 #include <cstdlib>
45 
46 namespace G4INCL {
47 
51  enum MessageType { InfoMsg = 1,
52  FatalMsg = 2,
53  ErrorMsg = 3,
55  DebugMsg = 7,
57  ZeroMsg = 0 };
58 
59 #if defined(INCL_DEBUG_LOG) && !defined(INCLXX_IN_GEANT4_MODE)
60 
61  class LoggerSlave {
62  public:
63  // By default, log fatal errors, errors and warnings
64  LoggerSlave(std::string const &logFileName) : logStream(0), verbosityLevel(4) {
65  if(logFileName=="-") {
66  logStream = &(std::cout);
67  logToStdout = true;
68  } else {
69  logToStdout = false;
70  logStream = new std::ofstream(logFileName.c_str());
71  if(!logStream)
72  {
73  std::cerr << "Fatal error: couldn't open log file " << logFileName << std::endl;
74  std::exit(EXIT_FAILURE);
75  }
76  }
77 
78  // Spell out "true" and "false" when logging G4bool variables
79  std::boolalpha(*logStream);
80 
81  logMessage(InfoMsg, __FILE__,__LINE__, "# Logging enabled!\n");
82  };
83  ~LoggerSlave() {
84  if(!logToStdout)
85  delete logStream;
86  };
87 
91  void setVerbosityLevel(G4int lvl) { verbosityLevel = lvl; }
92 
96  G4int getVerbosityLevel() { return verbosityLevel; }
97 
99  void logMessage(const MessageType type, const std::string &fileName, const G4int lineNumber, std::string const &s) const;
100 
102  void flush() { logStream->flush(); }
103 
105  void logDataBlock(const std::string &block, const std::string &fileName, const G4int lineNumber) const;
106 
107  typedef std::basic_ostream<char, std::char_traits<char> > CoutType;
108  typedef CoutType& (*StandardEndLine)(CoutType&);
110  LoggerSlave const &operator<<(StandardEndLine const &manip) const {
111  manip(*logStream);
112  return *this;
113  }
114 
116  template<typename T>
117  LoggerSlave const &operator<<(const T &t) const {
118  (*logStream) << t;
119  return *this;
120  }
121 
122  private:
123  std::ostream *logStream;
124  G4int verbosityLevel;
125  G4bool logToStdout;
126  };
127 
128  class Logger {
129  public:
131  static void logMessage(const MessageType type, std::string const &fileName, const G4int lineNumber, std::string const &s) {
132  theLoggerSlave->logMessage(type, fileName, lineNumber, s);
133  }
134 
136  static void flush() { theLoggerSlave->flush(); }
137 
139  static void dataBlock(const std::string &block, const std::string &fileName, const G4int lineNumber) {
140  theLoggerSlave->logDataBlock(block, fileName, lineNumber);
141  }
142 
144  static void setLoggerSlave(LoggerSlave * const logger) { theLoggerSlave = logger; }
145 
147  static void setVerbosityLevel(G4int lvl) { theLoggerSlave->setVerbosityLevel(lvl); }
148 
150  static G4int getVerbosityLevel() { return theLoggerSlave->getVerbosityLevel(); }
151 
153  static void deleteLoggerSlave() {
154  delete theLoggerSlave;
155  theLoggerSlave=NULL;
156  }
157 
158  private:
159  static LoggerSlave *theLoggerSlave;
160  };
161 
162  // Macro definitions for line numbering in log files!
163 #define FATAL(x) \
164  if(true) {\
165  std::stringstream ss;\
166  ss << x;\
167  G4INCL::Logger::logMessage(G4INCL::FatalMsg, __FILE__,__LINE__, ss.str());\
168  G4INCL::Logger::flush();\
169  std::exit(EXIT_FAILURE);\
170  } else (void)0
171 #define ERROR(x) \
172  if(G4INCL::ErrorMsg <= G4INCL::Logger::getVerbosityLevel()) {\
173  std::stringstream ss;\
174  ss << x;\
175  G4INCL::Logger::logMessage(G4INCL::ErrorMsg, __FILE__,__LINE__, ss.str());\
176  } else (void)0
177 #define WARN(x) \
178  if(G4INCL::WarningMsg <= G4INCL::Logger::getVerbosityLevel()) {\
179  std::stringstream ss;\
180  ss << x;\
181  G4INCL::Logger::logMessage(G4INCL::WarningMsg, __FILE__,__LINE__, ss.str());\
182  } else (void)0
183 #define INFO(x) \
184  if(G4INCL::InfoMsg <= G4INCL::Logger::getVerbosityLevel()) {\
185  std::stringstream ss;\
186  ss << x;\
187  G4INCL::Logger::logMessage(G4INCL::InfoMsg, __FILE__,__LINE__, ss.str());\
188  } else (void)0
189 #define DEBUG(x) \
190  if(G4INCL::DebugMsg <= G4INCL::Logger::getVerbosityLevel()) {\
191  std::stringstream ss;\
192  ss << x;\
193  G4INCL::Logger::logMessage(G4INCL::DebugMsg, __FILE__,__LINE__, ss.str());\
194  } else (void)0
195 #define DATABLOCK(x) \
196  if(G4INCL::DataBlockMsg <= G4INCL::Logger::getVerbosityLevel()) {\
197  G4INCL::Logger::dataBlock(x,__FILE__,__LINE__);\
198  } else (void)0
199 
200 #else
201  // Empty logger for normal (production) use:
202  class LoggerSlave {
203  public:
204  LoggerSlave(std::string const &) {};
208  };
209 
210  class Logger {
211  public:
212  Logger() {};
213  ~Logger() {};
214  static void setVerbosityLevel(G4int) {};
215  static void setLoggerSlave(LoggerSlave * const slave) { theLoggerSlave = slave; }
216  static void deleteLoggerSlave() {
217  delete theLoggerSlave;
218  theLoggerSlave=NULL;
219  }
220  private:
221  static LoggerSlave *theLoggerSlave;
222  };
223 
224 #define FATAL(x) \
225  if(true) {\
226  std::stringstream ss;\
227  ss << x;\
228  std::stringstream location;\
229  location << __FILE__ << ":" << __LINE__;\
230  G4Exception(location.str().c_str(), "INCLXX0000", FatalException, ss.str().c_str());\
231  } else (void)0
232 #define ERROR(x);
233 #define WARN(x);
234 #define INFO(x);
235 #define DEBUG(x);
236 #define DATABLOCK(x);
237 
238 #endif
239 }
240 #endif