openModeller
Version 1.4.0
|
00001 00028 #include <openmodeller/Log.hh> 00029 00030 00031 #include <openmodeller/Exceptions.hh> 00032 00033 //Needed for strlen calls otherwise gcc 4.3.2 throws error 00034 #include <string.h> 00035 00036 using std::ostream; 00037 using std::ios_base; 00038 using std::fstream; 00039 using std::endl; 00040 using std::string; 00041 // 00042 // Static calls to enforce singleton behaviour 00043 // 00044 Log *Log::mpInstance = 0; 00045 Log *Log::instance() 00046 { 00047 if (mpInstance == 0) 00048 { 00049 mpInstance = new Log(); 00050 } 00051 return mpInstance; 00052 } 00053 00054 // 00055 // WIN32 function defines 00056 // 00057 #ifdef WIN32 00058 #define snprintf _snprintf 00059 #define vsnprintf _vsnprintf 00060 #endif 00061 00062 /****************************************************************/ 00063 /******************** StdFileLogCallback ************************/ 00064 00065 class StdFileLogCallback : public Log::LogCallback { 00066 public: 00067 00068 StdFileLogCallback( std::string fileName ) { 00069 00070 file.open( fileName.c_str(), ios_base::out ); 00071 00072 if ( file.fail() ) { 00073 00074 fprintf( stderr, "Could not open log file!\n" ); 00075 } 00076 } 00077 00078 ~StdFileLogCallback() { 00079 00080 file.close(); 00081 } 00082 00083 void operator()( Log::Level level, const std::string& msg ) { 00084 00085 if ( file.is_open() ) { 00086 00087 file << msg.c_str(); 00088 file.flush(); 00089 } 00090 } 00091 00092 std::fstream file; 00093 }; 00094 00095 /****************************************************************/ 00096 /******************** OstreamCallback ***************************/ 00097 00098 Log::OstreamCallback::OstreamCallback( ostream& os ) : 00099 os( os ) 00100 {} 00101 00102 void 00103 Log::OstreamCallback::operator()(Level level, const string& msg ) { 00104 os << msg; 00105 } 00106 00107 /****************************************************************/ 00108 /******************** output function ***************************/ 00109 const char * 00110 LevelLabels[5] = 00111 { 00112 "[Debug] ", 00113 "", 00114 "[Info] ", 00115 "[Warn] ", 00116 "[Error] " 00117 }; 00118 00119 void 00120 Log::FormatAndWrite( Log::LogCallback& lc, Log::Level level, std::string pref, const char* format, va_list ap ) { 00121 00122 const int buf_size = 1024; 00123 char buf[buf_size]; 00124 00125 // Print in 'buf'. 00126 // 00127 // Header. 00128 snprintf( buf, buf_size, "%s%s", LevelLabels[level], pref.c_str() ); 00129 00130 // Print message after header. 00131 int len = strlen( buf ); 00132 char *end = buf + len; 00133 vsnprintf( end, buf_size - len, format, ap ); 00134 00135 lc( level, buf ); 00136 } 00137 00138 /****************************************************************/ 00139 /****************************** Log *****************************/ 00140 00141 std::string 00142 Log::format( const char *fmt, ... ) 00143 { 00144 std::string ret_str(""); 00145 00146 if ( NULL != fmt ) { 00147 00148 va_list marker; 00149 00150 // initalize variable arguments 00151 va_start( marker, fmt ); 00152 00153 const int buf_size = 1024; 00154 char buf[buf_size]; 00155 char *end = buf; 00156 00157 vsnprintf( end, buf_size, fmt, marker ); 00158 00159 // reset variable arguments 00160 va_end( marker ); 00161 00162 ret_str = buf; 00163 } 00164 00165 return ret_str; 00166 } 00167 00168 /*******************/ 00169 /*** constructor ***/ 00170 00171 Log::Log( ) : 00172 callback( new Log::OstreamCallback( std::cerr ) ) 00173 { 00174 _level = Log::Debug ; 00175 setPrefix( "" ); 00176 _deleteCallback = true; 00177 } 00178 00179 00180 /******************/ 00181 /*** destructor ***/ 00182 00183 Log::~Log() 00184 { 00185 if ( callback && _deleteCallback ) { 00186 00187 delete callback; 00188 } 00189 } 00190 00191 /**************************/ 00192 /*** set all parameters ***/ 00193 //void 00194 //Log::set( Log::Level level, FILE* out, char const *pref ) 00195 void 00196 Log::set( Log::Level level, std::string fileName, char const *pref ) 00197 { 00198 setLevel( level ); 00199 setCallback( new StdFileLogCallback( fileName ) ); 00200 setPrefix( pref ); 00201 _deleteCallback = true; 00202 } 00203 00204 /********************/ 00205 /*** set Callback ***/ 00206 void 00207 Log::setCallback( LogCallback *lc ) 00208 { 00209 if ( callback && _deleteCallback ) { 00210 00211 delete callback; 00212 _deleteCallback = false; 00213 } 00214 00215 callback = lc; 00216 } 00217 00218 00219 /******************/ 00220 /*** set Prefix ***/ 00221 void 00222 Log::setPrefix( const char *pref ) 00223 { 00224 _pref.assign( pref ); 00225 00226 // If prefix is non-empty, we need a trailing space 00227 if ( _pref.size() > 0 ) { 00228 00229 _pref.append(" "); 00230 } 00231 } 00232 00233 00234 /*************/ 00235 /*** debug ***/ 00236 void 00237 Log::debug( const char *format, ... ) 00238 { 00239 if ( _level > Debug || ! callback ) { 00240 00241 return; 00242 } 00243 00244 va_list ap; 00245 va_start( ap, format ); 00246 FormatAndWrite( *callback, Debug, _pref, format, ap ); 00247 va_end( ap ); 00248 00249 return; 00250 } 00251 00252 00253 /************/ 00254 /*** info ***/ 00255 void 00256 Log::info( const char *format, ... ) 00257 { 00258 if ( _level > Info || !callback ) 00259 return; 00260 00261 va_list ap; 00262 va_start( ap, format ); 00263 FormatAndWrite( *callback, Info, _pref, format, ap ); 00264 va_end( ap ); 00265 00266 return; 00267 } 00268 00269 00270 /************/ 00271 /*** warn ***/ 00272 void 00273 Log::warn( const char *format, ... ) 00274 { 00275 if ( _level > Warn || !callback ) 00276 return; 00277 00278 va_list ap; 00279 va_start( ap, format ); 00280 FormatAndWrite( *callback, Warn, _pref, format, ap ); 00281 va_end( ap ); 00282 00283 return; 00284 } 00285 00286 00287 /*************/ 00288 /*** error ***/ 00289 void 00290 Log::error( const char *format, ... ) 00291 { 00292 if ( _level > Error || !callback ) 00293 return; 00294 00295 va_list ap; 00296 va_start( ap, format ); 00297 FormatAndWrite( *callback, Error, _pref, format, ap ); 00298 va_end( ap ); 00299 00300 return; 00301 } 00302 00303 00304 /*******************/ 00305 /*** operator () ***/ 00306 void 00307 Log::operator()( const char *format, ... ) 00308 { 00309 if ( _level > Default || !callback ) 00310 return; 00311 00312 va_list ap; 00313 va_start( ap, format ); 00314 FormatAndWrite( *callback, Default, _pref, format, ap ); 00315 va_end( ap ); 00316 00317 return; 00318 }