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