Lunchbox
1.6.0
|
00001 00002 /* Copyright (c) 2005-2012, Stefan Eilemann <eile@equalizergraphics.com> 00003 * 2011, Daniel Nachbaur <danielnachbaur@gmail.com> 00004 * 00005 * This library is free software; you can redistribute it and/or modify it under 00006 * the terms of the GNU Lesser General Public License version 2.1 as published 00007 * by the Free Software Foundation. 00008 * 00009 * This library is distributed in the hope that it will be useful, but WITHOUT 00010 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS 00011 * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more 00012 * details. 00013 * 00014 * You should have received a copy of the GNU Lesser General Public License 00015 * along with this library; if not, write to the Free Software Foundation, Inc., 00016 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 00017 */ 00018 00027 #ifndef LUNCHBOX_LOG_H 00028 #define LUNCHBOX_LOG_H 00029 00030 #include <lunchbox/api.h> 00031 #include <lunchbox/types.h> 00032 00033 #include <assert.h> 00034 #include <iomanip> 00035 #include <iostream> 00036 #include <sstream> 00037 00038 namespace lunchbox 00039 { 00041 enum LogLevel 00042 { 00043 LOG_ERROR = 1, 00044 LOG_WARN, 00045 LOG_INFO, 00046 LOG_VERB, 00047 LOG_ALL 00048 }; 00049 00056 enum LogTopic 00057 { 00058 LOG_CUSTOM = 0x10, 00059 LOG_ANY = 0xffffu 00060 }; 00061 00063 class LogBuffer : public std::streambuf 00064 { 00065 public: 00066 LogBuffer( std::ostream& stream ) 00067 : _line(0), _indent(0), _blocked(0), _noHeader(0), 00068 _newLine(true), _stream(stream) 00069 { _thread[0] = 0; } 00070 virtual ~LogBuffer() {} 00071 00072 void indent() { ++_indent; } 00073 void exdent() { --_indent; } 00074 00075 void disableFlush() { ++_blocked; assert( _blocked < 100 ); } 00076 void enableFlush() 00077 { 00078 assert( _blocked );// Too many enableFlush on log stream 00079 --_blocked; 00080 } 00081 00082 void disableHeader() { ++_noHeader; } // use counted variable to allow 00083 void enableHeader() { --_noHeader; } // nested enable/disable calls 00084 00085 LUNCHBOX_API void setThreadName( const std::string& name ); 00086 const char* getThreadName() const { return _thread; } 00087 00088 void setLogInfo( const char* file, const int line ) 00089 { _file = file; _line = line; } 00090 00091 protected: 00092 virtual int_type overflow( LogBuffer::int_type c ); 00093 00094 virtual int sync(); 00095 00096 private: 00097 LogBuffer( const LogBuffer& ); 00098 LogBuffer& operator = ( const LogBuffer& ); 00099 00101 char _thread[12]; 00102 00104 std::string _file; 00105 00107 int _line; 00108 00110 int _indent; 00111 00113 int _blocked; 00114 00116 int _noHeader; 00117 00119 bool _newLine; 00120 00122 std::ostringstream _stringStream; 00123 00125 std::ostream& _stream; 00126 00128 static Lock _lock; 00129 }; 00130 00132 class Log : public std::ostream 00133 { 00134 public: 00135 00136 Log() : std::ostream( &_logBuffer ), _logBuffer( getOutput( )){} 00137 virtual ~Log() { _logBuffer.pubsync(); } 00138 00139 void indent() { _logBuffer.indent(); } 00140 void exdent() { _logBuffer.exdent(); } 00141 void disableFlush() { _logBuffer.disableFlush(); } 00142 void enableFlush() { _logBuffer.enableFlush(); } 00143 void forceFlush() { _logBuffer.pubsync(); } 00144 void disableHeader() { _logBuffer.disableHeader(); } 00145 void enableHeader() { _logBuffer.enableHeader(); } 00146 00148 static LUNCHBOX_API int level; 00149 00151 static LUNCHBOX_API unsigned topics; 00152 00154 static LUNCHBOX_API Log& instance(); 00155 00157 static LUNCHBOX_API Log& instance( const char* file, const int line ); 00158 00160 static LUNCHBOX_API void exit(); 00161 00163 static LUNCHBOX_API void reset(); 00164 00166 static std::string& getLogLevelString(); 00167 00169 static LUNCHBOX_API int getLogLevel( const char* level ); 00170 00172 static LUNCHBOX_API void setOutput( std::ostream& stream ); 00173 00175 static LUNCHBOX_API bool setOutput( const std::string& file ); 00176 00178 static LUNCHBOX_API std::ostream& getOutput (); 00179 00188 static LUNCHBOX_API void setClock( Clock* clock ); 00189 00190 static const Clock& getClock(); 00191 00193 void setThreadName( const std::string& name ) 00194 { _logBuffer.setThreadName( name ); } 00195 00197 const char* getThreadName() const { return _logBuffer.getThreadName(); } 00198 00199 private: 00200 LogBuffer _logBuffer; 00201 00202 Log( const Log& ); 00203 Log& operator = ( const Log& ); 00204 00205 void setLogInfo( const char* file, const int line ) 00206 { _logBuffer.setLogInfo( file, line ); } 00207 }; 00208 00214 LUNCHBOX_API std::ostream& indent( std::ostream& os ); 00216 LUNCHBOX_API std::ostream& exdent( std::ostream& os ); 00217 00219 LUNCHBOX_API std::ostream& disableFlush( std::ostream& os ); 00221 LUNCHBOX_API std::ostream& enableFlush( std::ostream& os ); 00223 LUNCHBOX_API std::ostream& forceFlush( std::ostream& os ); 00224 00226 LUNCHBOX_API std::ostream& disableHeader( std::ostream& os ); 00228 LUNCHBOX_API std::ostream& enableHeader( std::ostream& os ); 00229 } 00230 00232 #define LBERROR (lunchbox::Log::level >= lunchbox::LOG_ERROR) && \ 00233 lunchbox::Log::instance( __FILE__, __LINE__ ) 00234 00235 #define LBWARN (lunchbox::Log::level >= lunchbox::LOG_WARN) && \ 00236 lunchbox::Log::instance( __FILE__, __LINE__ ) 00237 00238 #define LBINFO (lunchbox::Log::level >= lunchbox::LOG_INFO) && \ 00239 lunchbox::Log::instance( __FILE__, __LINE__ ) 00240 00241 #ifdef NDEBUG 00242 # define LBVERB if( false ) \ 00243 lunchbox::Log::instance( __FILE__, __LINE__ ) 00244 #else 00245 00246 # define LBVERB (lunchbox::Log::level >= lunchbox::LOG_VERB) && \ 00247 lunchbox::Log::instance( __FILE__, __LINE__ ) 00248 #endif 00249 00254 #define LBLOG(topic) (lunchbox::Log::topics & (topic)) && \ 00255 lunchbox::Log::instance( __FILE__, __LINE__ ) 00256 00257 #endif //LUNCHBOX_LOG_H