00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039 #ifndef _OSGLOG_H_
00040 #define _OSGLOG_H_
00041 #ifdef __sgi
00042 #pragma once
00043 #endif
00044
00045 #include "OSGBaseTypes.h"
00046 #include "OSGTime.h"
00047
00048 #include <fstream>
00049 #include <list>
00050
00055 OSG_BEGIN_NAMESPACE
00056
00060 enum LogType
00061 {
00062 LOG_NONE = 0,
00063 LOG_STDOUT = 1,
00064 LOG_STDERR = 2,
00065 LOG_FILE = 3,
00066 LOG_BUFFER = 4
00067 };
00068
00072 enum LogLevel
00073 {
00074 LOG_LOG = 0,
00075 LOG_FATAL = 1,
00076 LOG_WARNING = 2,
00077 LOG_NOTICE = 3,
00078 LOG_DEBUG_GV = 4,
00079 LOG_INFO = 5,
00080 LOG_DEBUG = 6
00081 };
00082
00086 enum LogHeaderElem
00087 {
00088 LOG_NONE_HEADER = 0,
00089 LOG_BEGIN_NEWLINE_HEADER = 1,
00090 LOG_TYPE_HEADER = 2,
00091 LOG_TIMESTAMP_HEADER = 4,
00092 LOG_MODULE_HEADER = 8,
00093 LOG_FILE_HEADER = 16,
00094 LOG_LINE_HEADER = 32,
00095 LOG_END_NEWLINE_HEADER = 64,
00096
00097 LOG_COLOR_HEADER = 8192,
00098 LOG_TAB_HEADER = 16384,
00099
00100 LOG_ALL_HEADER = 127
00101 };
00102
00107 enum LogModuleHandling
00108 {
00109 LOG_MODULE_NONE = 0,
00110 LOG_MODULE_KNOWN = 1,
00111 LOG_MODULE_UNKNOWN = 2,
00112 LOG_MODULE_UNDEFINED = 4,
00113 LOG_MODULE_ALL = 7
00114 };
00115
00116 #ifndef OSG_DEFAULT_LOG_LEVEL
00117 # define OSG_DEFAULT_LOG_LEVEL LOG_WARNING
00118 #endif
00119
00120 #ifndef OSG_DEFAULT_LOG_TYPE
00121 # define OSG_DEFAULT_LOG_TYPE LOG_STDERR
00122 #endif
00123
00130 struct OSG_BASE_DLLMAPPING LogOStream : public std::ostream
00131 {
00132 public:
00133
00134 LogOStream(std::streambuf *buf);
00135
00136 virtual ~LogOStream(void);
00137
00138 void setrdbuf(std::streambuf *buf);
00139 };
00140
00147 class OSG_BASE_DLLMAPPING LogBuf : public std::streambuf
00148 {
00149
00150
00151 public:
00152
00153
00154
00155 typedef void (*Callback)(const Char8 *data,
00156 Int32 size,
00157 void *clientData);
00158
00160 struct Chunk
00161 {
00162 Char8 *data;
00163 Int32 size;
00164
00165 Chunk(void);
00166 ~Chunk(void);
00167 };
00168
00169
00173 LogBuf( UInt32 bufferSize = 1024);
00174 LogBuf(const LogBuf & );
00175
00177
00181 virtual ~LogBuf();
00182
00184
00188 bool getEnabled (void );
00189 void setEnabled (bool value = true);
00190
00191 void clearChunkBag(void );
00192
00194
00198 void setCallback (Callback cb,
00199 void *clientData = 0,
00200 bool flushData = false);
00201 void removeCallback(void );
00202
00203
00205
00206
00207 private:
00208
00209 bool _enabled;
00210
00211 std::list<Chunk*> _chunkBag;
00212
00213 Callback _callback;
00214 void *_clientData;
00215
00216 const LogBuf &operator=(const LogBuf &);
00217 void write (const Char8 *buffer,
00218 std::streamsize size );
00219
00220
00224 virtual Int32 overflow( Int32 c );
00225 virtual Int32 sync ( void );
00226 virtual std::streamsize xsputn (const Char8 *buffer,
00227 std::streamsize size);
00228
00229 };
00230
00245 class OSG_BASE_DLLMAPPING Log : public std::ostream
00246 {
00247
00248
00249 public:
00250
00251
00255 Log( LogType logType = LOG_STDERR,
00256 LogLevel logLevel = LOG_NOTICE);
00257
00258 Log(const Char8 *fileName,
00259 LogLevel logLevel = LOG_NOTICE);
00260
00262
00266 virtual ~Log(void);
00267
00269
00273 void lock (void) {;}
00274 void unlock(void) {;}
00275
00277
00281 virtual void setHeaderElem ( UInt32 elemMask,
00282 bool force = false);
00283 virtual void addHeaderElem ( LogHeaderElem elem,
00284 bool force = false);
00285 virtual void delHeaderElem ( LogHeaderElem elem,
00286 bool force = false);
00287 virtual bool hasHeaderElem ( LogHeaderElem elem);
00288
00289 virtual void addModuleHandling( LogModuleHandling handling,
00290 bool force = false);
00291 virtual void delModuleHandling( LogModuleHandling handling,
00292 bool force = false);
00293
00294 virtual void addModuleName (const Char8 *module,
00295 bool isStatic = false);
00296 virtual void delModuleName (const Char8 *module );
00297
00298 bool hasModule (const Char8 *module );
00299 bool checkModule (const Char8 *module );
00300
00302
00306 LogType getLogType ( void );
00307 void setLogType ( LogType logType, bool force = false);
00308
00309 LogLevel getLogLevel ( void);
00310 void setLogLevel ( LogLevel logLevel, bool force = false);
00311 bool checkLevel ( LogLevel logLevel );
00312
00313 void setLogFile (const Char8 *fileName, bool force = false);
00314
00315 Time getRefTime ( void );
00316 void setRefTime ( Time refTime );
00317 void resetRefTime( void );
00318
00320
00324 LogBuf &getLogBuf(void );
00325
00326 std::ostream &stream (LogLevel level);
00327 std::ostream &nilstream(void );
00328
00330
00334 std::ostream &doHeader( LogLevel level,
00335 const Char8 *module,
00336 const Char8 *file,
00337 UInt32 line );
00338
00339 void doLog (const Char8 *format, ...);
00340
00342
00343
00344 protected:
00345
00346
00350 void connect (void );
00351
00352 bool colorHeader(LogLevel level, const char *sep);
00353
00354 static void terminate(void);
00355
00357
00358
00359 private:
00360
00361 typedef std::ostream Inherited;
00362
00363 friend OSG_BASE_DLLMAPPING void doInitLog(void);
00364
00365
00370 struct OSG_BASE_DLLMAPPING nilbuf : public std::streambuf
00371 {
00372 };
00373
00375 struct Module
00376 {
00377 const Char8 *name;
00378 bool isStatic;
00379
00380 Module(void);
00381 };
00382
00384
00388 static nilbuf *_nilbufP;
00389 static std::ostream *_nilstreamP;
00390
00391 static const Char8 *_levelName [];
00392 static const Char8 *_levelColor[];
00393
00394 static Char8 *_buffer;
00395 static int _buffer_size;
00396
00398
00402 LogType _logType;
00403 LogLevel _logLevel;
00404
00405 std::fstream _fileStream;
00406
00407 LogBuf _logBuf;
00408 LogOStream *_streamVec[7];
00409
00410 UInt32 _headerElem;
00411 UInt32 _moduleHandling;
00412
00413
00414 std::list<Module> _moduleList;
00415
00416 Time _refTime;
00417
00419
00423 Log(const Log &source);
00424
00426
00430 void operator =(const Log &source);
00431
00434 friend OSG_BASE_DLLMAPPING bool osgExit(void);
00435 };
00436
00437 typedef Log *LogP;
00438
00439 #ifndef OSG_LOG_MODULE
00440 #define OSG_LOG_MODULE "OpenSG"
00441 #endif
00442
00443 extern OSG_BASE_DLLMAPPING LogP osgLogP;
00444
00445
00446 OSG_BASE_DLLMAPPING
00447 void doInitLog ( void );
00448
00449 inline
00450 void initLog ( void );
00451
00452 inline
00453 Log &osgLog ( void );
00454
00455 inline
00456 std::ostream &osgStartLog( bool logHeader,
00457 LogLevel level,
00458 const Char8 *module,
00459 const Char8 *file,
00460 UInt32 line );
00461
00462 inline
00463 std::ostream &endLog ( std::ostream &strm );
00464
00465 inline
00466 void indentLog ( UInt32 indent,
00467 std::ostream &stream );
00468
00469
00474 #define SLOG \
00475 OSG::osgStartLog(true, OSG::LOG_LOG, OSG_LOG_MODULE, __FILE__, __LINE__)
00476
00481 #define SFATAL \
00482 OSG::osgStartLog(true, OSG::LOG_FATAL, OSG_LOG_MODULE, __FILE__, __LINE__)
00483
00488 #define SWARNING \
00489 OSG::osgStartLog(true, OSG::LOG_WARNING, OSG_LOG_MODULE, __FILE__, __LINE__)
00490
00495 #define SNOTICE \
00496 OSG::osgStartLog(true, OSG::LOG_NOTICE, OSG_LOG_MODULE, __FILE__, __LINE__)
00497
00502 #define SINFO \
00503 OSG::osgStartLog(true, OSG::LOG_INFO, OSG_LOG_MODULE, __FILE__, __LINE__)
00504
00505
00510 #define PLOG \
00511 OSG::osgStartLog(false, OSG::LOG_LOG, OSG_LOG_MODULE, __FILE__, __LINE__)
00512
00517 #define PFATAL \
00518 OSG::osgStartLog(false, OSG::LOG_FATAL, OSG_LOG_MODULE, __FILE__, __LINE__)
00519
00524 #define PWARNING \
00525 OSG:: osgStartLog(false, OSG::LOG_WARNING, OSG_LOG_MODULE, __FILE__, __LINE__)
00526
00531 #define PNOTICE \
00532 OSG::osgStartLog(false, OSG::LOG_NOTICE, OSG_LOG_MODULE, __FILE__, __LINE__)
00533
00538 #define PINFO \
00539 OSG::osgStartLog(false, OSG::LOG_INFO, OSG_LOG_MODULE, __FILE__, __LINE__)
00540
00541
00542
00543
00544
00545
00550 #define FLOG(par) \
00551 { \
00552 OSG::initLog(); \
00553 OSG::osgStartLog(true, \
00554 OSG::LOG_LOG, \
00555 OSG_LOG_MODULE, \
00556 __FILE__, \
00557 __LINE__); \
00558 OSG::osgLogP->doLog par; \
00559 OSG::osgLogP->unlock(); \
00560 }
00561
00566 #define FFATAL(par) \
00567 { \
00568 OSG::initLog(); \
00569 if(OSG::osgLogP->checkLevel(OSG::LOG_FATAL)) \
00570 { \
00571 OSG::osgStartLog(true, \
00572 OSG::LOG_FATAL, \
00573 OSG_LOG_MODULE, \
00574 __FILE__, \
00575 __LINE__); \
00576 OSG::osgLogP->doLog par; \
00577 OSG::osgLogP->unlock(); \
00578 } \
00579 }
00580
00585 #define FWARNING(par) \
00586 { \
00587 OSG::initLog(); \
00588 if(OSG::osgLogP->checkLevel(OSG::LOG_WARNING)) \
00589 { \
00590 OSG::osgStartLog(true, \
00591 OSG::LOG_WARNING, \
00592 OSG_LOG_MODULE, \
00593 __FILE__, \
00594 __LINE__); \
00595 OSG::osgLogP->doLog par; \
00596 OSG::osgLogP->unlock(); \
00597 } \
00598 }
00599
00604 #define FNOTICE(par) \
00605 { \
00606 OSG::initLog(); \
00607 if(OSG::osgLogP->checkLevel(OSG::LOG_NOTICE)) \
00608 { \
00609 OSG::osgStartLog(true, \
00610 OSG::LOG_NOTICE, \
00611 OSG_LOG_MODULE, \
00612 __FILE__, \
00613 __LINE__); \
00614 OSG::osgLogP->doLog par; \
00615 OSG::osgLogP->unlock(); \
00616 } \
00617 }
00618
00623 #define FINFO(par) \
00624 { \
00625 OSG::initLog(); \
00626 if(OSG::osgLogP->checkLevel(OSG::LOG_INFO)) \
00627 { \
00628 OSG::osgStartLog(true, \
00629 OSG::LOG_INFO, \
00630 OSG_LOG_MODULE, \
00631 __FILE__, \
00632 __LINE__); \
00633 OSG::osgLogP->doLog par; \
00634 OSG::osgLogP->unlock(); \
00635 } \
00636 }
00637
00642 #ifdef OSG_DEBUG
00643 #define FDEBUG(par) \
00644 { \
00645 OSG::initLog(); \
00646 if(OSG::osgLogP->checkLevel(OSG::LOG_DEBUG)) \
00647 { \
00648 OSG::osgStartLog(true, \
00649 OSG::LOG_DEBUG,OSG_LOG_MODULE, \
00650 __FILE__, \
00651 __LINE__); \
00652 OSG::osgLogP->doLog par; \
00653 OSG::osgLogP->unlock(); \
00654 } \
00655 }
00656 #else
00657 #define FDEBUG(par)
00658 #endif
00659
00664 #ifdef OSG_DEBUG
00665 #define FDEBUG_GV(par) \
00666 { \
00667 OSG::initLog(); \
00668 if(OSG::osgLogP->checkLevel(OSG::LOG_DEBUG_GV)) \
00669 { \
00670 OSG::osgStartLog(true, \
00671 OSG::LOG_DEBUG_GV,OSG_LOG_MODULE, \
00672 __FILE__, \
00673 __LINE__); \
00674 OSG::osgLogP->doLog par; \
00675 OSG::osgLogP->unlock(); \
00676 } \
00677 }
00678 #else
00679 #define FDEBUG_GV(par)
00680 #endif
00681
00686 #define FASSERT(condition, doExit) \
00687 { \
00688 if (!condition) \
00689 { \
00690 OSG::osgLog().lock(); \
00691 OSG::osgLog().stream(OSG::LOG_FATAL) \
00692 << OSG_LOG_MODULE \
00693 << ':' \
00694 << __FILE__ \
00695 << ':' \
00696 << __LINE__ \
00697 << " FATAL ASSERT: " \
00698 << (doExit ? "exit system" : "try to keep running") \
00699 << std::flush << std::endl; \
00700 OSG::osgLog().unlock(); \
00701 if(doExit) \
00702 exit(-1); \
00703 } \
00704 }
00705
00710 #define FFASSERT(condition, doExit, par) \
00711 { \
00712 if(!condition) \
00713 { \
00714 OSG::osgLog().lock(); \
00715 OSG::osgLog().stream(OSG::LOG_FATAL) \
00716 << OSG_LOG_MODULE \
00717 << ':' \
00718 << __FILE__ \
00719 << ':' \
00720 << __LINE__ \
00721 << " FATAL ASSERT: " \
00722 << (doExit ? "exit system" : "try to keep running") \
00723 << std::flush << std::endl; \
00724 OSG::osgLogP->doLog par \
00725 OSG::osgLog().unlock(); \
00726 if(doExit) \
00727 exit(-1); \
00728 } \
00729 }
00730
00731
00732
00737 #define FPLOG(par) \
00738 { \
00739 OSG::initLog(); \
00740 OSG::osgStartLog(false, \
00741 OSG::LOG_LOG, \
00742 OSG_LOG_MODULE, \
00743 __FILE__, \
00744 __LINE__); \
00745 OSG::osgLogP->doLog par; \
00746 OSG::osgLogP->unlock(); \
00747 }
00748
00753 #define FPFPATAL(par) \
00754 { \
00755 OSG::initLog(); \
00756 if(OSG::osgLogP->checkLevel(OSG::LOG_FPATAL)) \
00757 { \
00758 OSG::osgStartLog(false, \
00759 OSG::LOG_FPATAL, \
00760 OSG_LOG_MODULE, \
00761 __FILE__, \
00762 __LINE__); \
00763 OSG::osgLogP->doLog par; \
00764 OSG::osgLogP->unlock(); \
00765 } \
00766 }
00767
00772 #define FPWARNING(par) \
00773 { \
00774 OSG::initLog(); \
00775 if(OSG::osgLogP->checkLevel(OSG::LOG_WARNING)) \
00776 { \
00777 OSG::osgStartLog(false, \
00778 OSG::LOG_WARNING, \
00779 OSG_LOG_MODULE, \
00780 __FILE__, \
00781 __LINE__); \
00782 OSG::osgLogP->doLog par; \
00783 OSG::osgLogP->unlock(); \
00784 } \
00785 }
00786
00791 #define FPNOTICE(par) \
00792 { \
00793 OSG::initLog(); \
00794 if(OSG::osgLogP->checkLevel(OSG::LOG_NOTICE)) \
00795 { \
00796 OSG::osgStartLog(false, \
00797 OSG::LOG_NOTICE, \
00798 OSG_LOG_MODULE, \
00799 __FILE__, \
00800 __LINE__); \
00801 OSG::osgLogP->doLog par; \
00802 OSG::osgLogP->unlock(); \
00803 } \
00804 }
00805
00810 #define FPINFPO(par) \
00811 { \
00812 OSG::initLog(); \
00813 if(OSG::osgLogP->checkLevel(OSG::LOG_INFPO)) \
00814 { \
00815 OSG::osgStartLog(false, \
00816 OSG::LOG_INFPO, \
00817 OSG_LOG_MODULE, \
00818 __FILE__, \
00819 __LINE__); \
00820 OSG::osgLogP->doLog par; \
00821 OSG::osgLogP->unlock(); \
00822 } \
00823 }
00824
00829 #ifdef OSG_DEBUG
00830 #define FPDEBUG(par) \
00831 { \
00832 OSG::initLog(); \
00833 if(OSG::osgLogP->checkLevel(OSG::LOG_DEBUG)) \
00834 { \
00835 OSG::osgStartLog(false, \
00836 OSG::LOG_DEBUG,OSG_LOG_MODULE, \
00837 __FILE__, \
00838 __LINE__); \
00839 OSG::osgLogP->doLog par; \
00840 OSG::osgLogP->unlock(); \
00841 } \
00842 }
00843 #else
00844 #define FPDEBUG(par)
00845 #endif
00846
00847 #ifdef OSG_DEBUG
00848 #define FPDEBUG_GV(par) \
00849 { \
00850 OSG::initLog(); \
00851 if(OSG::osgLogP->checkLevel(OSG::LOG_DEBUG_GV)) \
00852 { \
00853 OSG::osgStartLog(false, \
00854 OSG::LOG_DEBUG_GV,OSG_LOG_MODULE, \
00855 __FILE__, \
00856 __LINE__); \
00857 OSG::osgLogP->doLog par; \
00858 OSG::osgLogP->unlock(); \
00859 } \
00860 }
00861 #else
00862 #define FPDEBUG_GV(par)
00863 #endif
00864
00865 OSG_END_NAMESPACE
00866
00867 #include "OSGLog.inl"
00868
00869 #endif