Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-09-16 08:55:33

0001 /***********************************************************************************\
0002 * (c) Copyright 1998-2024 CERN for the benefit of the LHCb and ATLAS collaborations *
0003 *                                                                                   *
0004 * This software is distributed under the terms of the Apache version 2 licence,     *
0005 * copied verbatim in the file "LICENSE".                                            *
0006 *                                                                                   *
0007 * In applying this licence, CERN does not waive the privileges and immunities       *
0008 * granted to it by virtue of its status as an Intergovernmental Organization        *
0009 * or submit itself to any jurisdiction.                                             *
0010 \***********************************************************************************/
0011 #ifndef GAUDIKERNEL_MSGSTREAM_H
0012 #define GAUDIKERNEL_MSGSTREAM_H
0013 
0014 // Include files
0015 #include <GaudiKernel/IMessageSvc.h>
0016 #include <GaudiKernel/SerializeSTL.h>
0017 // Standard C++ classes
0018 #include <cstdio>
0019 #include <iomanip>
0020 #include <sstream>
0021 #include <string>
0022 
0023 /**
0024  * @class MsgStream MsgStream.h GaudiKernel/MsgStream.h
0025  *
0026  * Definition of the MsgStream class used to transmit messages.
0027  * This class is intended to ease the use of error logging to the message
0028  * service
0029  *
0030  * @author M.Frank
0031  * @author Sebastien Ponce
0032  */
0033 class MsgStream {
0034 private:
0035   /** Error return code in case ios modification is requested for inactive
0036    *  streams
0037    */
0038   typedef std::ios_base::fmtflags FLAG_TYPE;
0039   typedef std::ios_base::iostate  STATE_TYPE;
0040 
0041 protected:
0042   /// Pointer to message service if buffer has send
0043   IMessageSvc* m_service;
0044   /// Use standard string for information buffering
0045   std::string m_buffer;
0046   /// Use std::string for source information to be passed to the message service
0047   std::string m_source;
0048   /// String MsgStream associated to buffer
0049   std::ostringstream m_stream;
0050   /// Flag set to true if formatting engine is active
0051   bool m_active = false;
0052   /// Debug level of the message service
0053   MSG::Level m_level;
0054   /// Current debug level
0055   MSG::Level m_currLevel;
0056   /// use colors
0057   bool m_useColors;
0058   /// Pointer to service counting messages prepared but not printed because of
0059   /// wrong level.
0060   IInactiveMessageCounter* m_inactCounter = nullptr;
0061   /// Flag to state if the inactive messages has to be counted.
0062   static bool m_countInactive;
0063 
0064 public:
0065   /// Standard constructor: Connect to message service for output
0066   GAUDI_API MsgStream( IMessageSvc* svc, int buffer_length = 128 );
0067   /// Standard constructor: Connect to message service for output
0068   GAUDI_API MsgStream( IMessageSvc* svc, std::string source, int buffer_length = 128 );
0069   /// Copy constructor
0070   MsgStream( const MsgStream& msg )
0071       : m_service( msg.m_service )
0072       , m_active( msg.m_active )
0073       , m_level( msg.m_level )
0074       , m_currLevel( msg.m_currLevel )
0075       , m_useColors( msg.m_useColors )
0076       , m_inactCounter( msg.m_inactCounter ) {
0077     try { // ignore exception if we cannot copy the string
0078       m_source = msg.m_source;
0079     } catch ( ... ) {}
0080   }
0081   /// Standard destructor
0082   GAUDI_API virtual ~MsgStream() = default;
0083   /// Initialize report of new message: activate if print level is sufficient.
0084   MsgStream& report( int lvl ) {
0085     lvl = ( lvl >= MSG::NUM_LEVELS ) ? MSG::ALWAYS : ( lvl < MSG::NIL ) ? MSG::NIL : lvl;
0086     if ( ( m_currLevel = MSG::Level( lvl ) ) >= level() ) {
0087       activate();
0088     } else {
0089       deactivate();
0090 #ifndef NDEBUG
0091       if ( MsgStream::countInactive() && m_inactCounter ) {
0092         m_inactCounter->incrInactiveCount( MSG::Level( lvl ), m_source );
0093       }
0094 #endif
0095     }
0096     return *this;
0097   }
0098   /// Output method
0099   virtual GAUDI_API MsgStream& doOutput();
0100   /// Access string buffer
0101   const std::string& buffer() const { return m_buffer; }
0102   /// Access string MsgStream
0103   std::ostringstream& stream() { return m_stream; }
0104   /// Update @c IMessageSvc pointer
0105   void setMsgSvc( IMessageSvc* svc ) { m_service = svc; }
0106   /// Update outputlevel
0107   void setLevel( int level ) {
0108     level   = ( level >= MSG::NUM_LEVELS ) ? MSG::ALWAYS : ( level < MSG::NIL ) ? MSG::NIL : level;
0109     m_level = MSG::Level( level );
0110   }
0111   /// Retrieve output level
0112   MSG::Level level() const { return m_level; }
0113   /// Retrieve current stream output level
0114   MSG::Level currentLevel() const { return m_currLevel; }
0115   /// Activate MsgStream
0116   void activate() { m_active = true; }
0117   /// Deactivate MsgStream
0118   void deactivate() { m_active = false; }
0119   /// Accessor: is MsgStream active
0120   bool isActive() const { return m_active; }
0121   // oMsgStream flush emulation
0122   MsgStream& flush() {
0123     if ( isActive() ) m_stream.flush();
0124     return *this;
0125   }
0126   // oMsgStream write emulation
0127   MsgStream& write( const char* buff, int len ) {
0128     if ( isActive() ) m_stream.write( buff, len );
0129     return *this;
0130   }
0131   /// Accept MsgStream modifiers
0132   MsgStream& operator<<( MsgStream& ( *_f )(MsgStream&)) {
0133     if ( isActive() ) _f( *this );
0134     return *this;
0135   }
0136   /// Accept oMsgStream modifiers
0137   MsgStream& operator<<( std::ostream& ( *_f )(std::ostream&)) {
0138     if ( isActive() ) _f( m_stream );
0139     return *this;
0140   }
0141   /// Accept ios modifiers
0142   MsgStream& operator<<( std::ios& ( *_f )(std::ios&)) {
0143     if ( isActive() ) _f( m_stream );
0144     return *this;
0145   }
0146   /// Accept MsgStream activation using MsgStreamer operator
0147   MsgStream& operator<<( MSG::Level level ) { return report( level ); }
0148   MsgStream& operator<<( long long arg ) {
0149     try {
0150       // this may throw, and we cannot afford it if the stream is used in a catch block
0151       if ( isActive() ) { m_stream << arg; }
0152     } catch ( ... ) {}
0153     return *this;
0154   }
0155 
0156   /// Accept ios base class modifiers
0157   MsgStream& operator<<( std::ios_base& ( *_f )(std::ios_base&)) {
0158     if ( isActive() ) _f( m_stream );
0159     return *this;
0160   }
0161 
0162   /// IOS emulation
0163   std::streamsize width() const { return isActive() ? m_stream.width() : 0; }
0164   std::streamsize width( std::streamsize v ) { return isActive() ? m_stream.width( v ) : 0; }
0165   std::streamsize precision() const { return isActive() ? m_stream.precision() : 0; }
0166   std::streamsize precision( int v ) { return isActive() ? m_stream.precision( v ) : 0; }
0167 
0168   long flags() const { return isActive() ? m_stream.flags() : 0; }
0169   long flags( FLAG_TYPE v ) { return isActive() ? m_stream.flags( v ) : 0; }
0170   long setf( FLAG_TYPE v ) { return isActive() ? m_stream.setf( v ) : 0; }
0171   char fill() const { return isActive() ? m_stream.fill() : (char)-1; }
0172   char fill( char v ) { return isActive() ? m_stream.fill( v ) : (char)-1; }
0173   int  rdstate() const { return isActive() ? m_stream.rdstate() : std::ios_base::failbit; }
0174   bool good() const { return isActive() && m_stream.good(); }
0175   bool eof() const { return isActive() && m_stream.eof(); }
0176   bool bad() const { return isActive() && m_stream.bad(); }
0177   int  setf( FLAG_TYPE _f, FLAG_TYPE _m ) { return isActive() ? m_stream.setf( _f, _m ) : 0; }
0178   void unsetf( FLAG_TYPE _l ) {
0179     if ( isActive() ) m_stream.unsetf( _l );
0180   }
0181   void clear( STATE_TYPE _i = std::ios_base::failbit ) {
0182     if ( isActive() ) m_stream.clear( _i );
0183   }
0184 
0185   /// Set the text color
0186   GAUDI_API void setColor( MSG::Color col );
0187   /// Set the foreground and background colors
0188   GAUDI_API void setColor( MSG::Color fg, MSG::Color bg );
0189 
0190   /// Reset the colors to defaults
0191   GAUDI_API void resetColor();
0192 
0193   /// Enable/disable the count of inactive messages.
0194   /// Returns the previous state.
0195   static GAUDI_API bool enableCountInactive( bool value = true );
0196 
0197   /// Returns the state of the counting of inactive messages (enabled/disabled).
0198   static GAUDI_API bool countInactive();
0199 };
0200 
0201 /// MsgStream Modifier: endmsg. Calls the output method of the MsgStream
0202 inline MsgStream& endmsg( MsgStream& s ) { return s.doOutput(); }
0203 
0204 /// MsgStream format utility "a la sprintf(...)"
0205 GAUDI_API std::string format( const char*, ... );
0206 
0207 #ifdef _WIN32
0208 template <class _E>
0209 inline MsgStream& operator<<( MsgStream& s, const std::_Fillobj<_E>& obj ) {
0210 #  if _MSC_VER > 1300
0211   if ( s.isActive() ) s.stream().fill( obj._Fill );
0212 #  else
0213   if ( s.isActive() ) s.stream().fill( obj._Ch );
0214 #  endif
0215   return s;
0216 }
0217 template <class _Tm>
0218 inline MsgStream& operator<<( MsgStream& s, const std::_Smanip<_Tm>& manip ) {
0219 #  if _MSC_VER > 1300
0220   if ( s.isActive() ) ( *manip._Pfun )( s.stream(), manip._Manarg );
0221 #  else
0222   if ( s.isActive() ) ( *manip._Pf )( s.stream(), manip._Manarg );
0223 #  endif
0224   return s;
0225 }
0226 #elif defined( __GNUC__ )
0227 #  ifndef __APPLE__
0228 inline MsgStream& operator<<( MsgStream& s, const std::_Setiosflags& manip ) {
0229   try {
0230     // this may throw, and we cannot afford it if the stream is used in a catch block
0231     if ( s.isActive() ) s.stream() << manip;
0232   } catch ( ... ) {}
0233   return s;
0234 }
0235 inline MsgStream& operator<<( MsgStream& s, const std::_Resetiosflags& manip ) {
0236   try {
0237     // this may throw, and we cannot afford it if the stream is used in a catch block
0238     if ( s.isActive() ) s.stream() << manip;
0239   } catch ( ... ) {}
0240   return s;
0241 }
0242 inline MsgStream& operator<<( MsgStream& s, const std::_Setbase& manip ) {
0243   try {
0244     // this may throw, and we cannot afford it if the stream is used in a catch block
0245     if ( s.isActive() ) s.stream() << manip;
0246   } catch ( ... ) {}
0247   return s;
0248 }
0249 inline MsgStream& operator<<( MsgStream& s, const std::_Setprecision& manip ) {
0250   try {
0251     // this may throw, and we cannot afford it if the stream is used in a catch block
0252     if ( s.isActive() ) s.stream() << manip;
0253   } catch ( ... ) {}
0254   return s;
0255 }
0256 inline MsgStream& operator<<( MsgStream& s, const std::_Setw& manip ) {
0257   try {
0258     // this may throw, and we cannot afford it if the stream is used in a catch block
0259     if ( s.isActive() ) s.stream() << manip;
0260   } catch ( ... ) {}
0261   return s;
0262 }
0263 #  endif // not __APPLE__
0264 #else    // GCC, version << 3
0265 /// I/O Manipulator for setfill
0266 template <class _Tm>
0267 inline MsgStream& operator<<( MsgStream& s, const std::smanip<_Tm>& manip ) {
0268   try {
0269     // this may throw, and we cannot afford it if the stream is used in a catch block
0270     if ( s.isActive() ) s.stream() << manip;
0271   } catch ( ... ) {}
0272   return s;
0273 }
0274 #endif   // WIN32 or (__GNUC__)
0275 
0276 namespace MSG {
0277   inline MsgStream& dec( MsgStream& log ) {
0278     log << std::dec;
0279     return log;
0280   }
0281   inline MsgStream& hex( MsgStream& log ) {
0282     log << std::hex;
0283     return log;
0284   }
0285 } // namespace MSG
0286 
0287 /// Specialization to avoid the generation of implementations for char[].
0288 /// \see {<a href="https://savannah.cern.ch/bugs/?87340">bug #87340</a>}
0289 inline MsgStream& operator<<( MsgStream& s, const char* arg ) {
0290   try {
0291     // this may throw, and we cannot afford it if the stream is used in a catch block
0292     if ( s.isActive() ) s.stream() << arg;
0293   } catch ( ... ) {}
0294   return s;
0295 }
0296 
0297 /// General templated stream operator
0298 template <typename T>
0299 MsgStream& operator<<( MsgStream& lhs, const T& arg ) {
0300   using namespace GaudiUtils;
0301   if ( lhs.isActive() ) try {
0302       // this may throw, and we cannot afford it if the stream is used in a catch block
0303       lhs.stream() << arg;
0304     } catch ( ... ) {}
0305   return lhs;
0306 }
0307 
0308 #if defined( __GNUC__ ) and not defined( __APPLE__ )
0309 /// compiler is stupid. Must specialize
0310 template <typename T>
0311 MsgStream& operator<<( MsgStream& lhs, const std::_Setfill<T>& manip ) {
0312   if ( lhs.isActive() ) try {
0313       // this may throw, and we cannot afford it if the stream is used in a catch block
0314       lhs.stream() << manip;
0315     } catch ( ... ) {}
0316   return lhs;
0317 }
0318 #endif
0319 
0320 #endif // GAUDIKERNEL_MSGSTREAM_H