OSGLog.h

Go to the documentation of this file.
00001 /*---------------------------------------------------------------------------*\
00002  *                                OpenSG                                     *
00003  *                                                                           *
00004  *                                                                           *
00005  *             Copyright (C) 2000-2003 by the OpenSG Forum                   *
00006  *                                                                           *
00007  *                            www.opensg.org                                 *
00008  *                                                                           *
00009  *         contact: dirk@opensg.org, gerrit.voss@vossg.org, jbehr@zgdv.de    *
00010  *                                                                           *
00011 \*---------------------------------------------------------------------------*/
00012 /*---------------------------------------------------------------------------*\
00013  *                                License                                    *
00014  *                                                                           *
00015  * This library is free software; you can redistribute it and/or modify it   *
00016  * under the terms of the GNU Library General Public License as published    *
00017  * by the Free Software Foundation, version 2.                               *
00018  *                                                                           *
00019  * This library is distributed in the hope that it will be useful, but       *
00020  * WITHOUT ANY WARRANTY; without even the implied warranty of                *
00021  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU         *
00022  * Library General Public License for more details.                          *
00023  *                                                                           *
00024  * You should have received a copy of the GNU Library General Public         *
00025  * License along with this library; if not, write to the Free Software       *
00026  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.                 *
00027  *                                                                           *
00028 \*---------------------------------------------------------------------------*/
00029 /*---------------------------------------------------------------------------*\
00030  *                                Changes                                    *
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     /*==========================  PUBLIC  =================================*/
00150 
00151   public:
00152 
00153   // only temporary until the functors work with all compiler
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     /*==========================  PRIVATE  ================================*/
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     /*==========================  PUBLIC  =================================*/
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) {;} // TODO: implement
00274     void unlock(void) {;} // TODO: implement
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     /*=========================  PROTECTED  ===============================*/
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     /*===========================  PRIVATE  ===============================*/
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 // C interface, because it can be compiled away
00543 // don't use varargs macros, because they are not supported everywhere
00544 // use the (( )) convention instead
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 // C interface without line start outputs
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 /* _OSGLOG_H_ */