debug.h

Go to the documentation of this file.
00001 
00005 /* Copyright, 2000 Nevrax Ltd.
00006  *
00007  * This file is part of NEVRAX NEL.
00008  * NEVRAX NEL is free software; you can redistribute it and/or modify
00009  * it under the terms of the GNU General Public License as published by
00010  * the Free Software Foundation; either version 2, or (at your option)
00011  * any later version.
00012 
00013  * NEVRAX NEL is distributed in the hope that it will be useful, but
00014  * WITHOUT ANY WARRANTY; without even the implied warranty of
00015  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
00016  * General Public License for more details.
00017 
00018  * You should have received a copy of the GNU General Public License
00019  * along with NEVRAX NEL; see the file COPYING. If not, write to the
00020  * Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
00021  * MA 02111-1307, USA.
00022  */
00023 
00024 #ifndef NL_DEBUG_H
00025 #define NL_DEBUG_H
00026 
00027 #include <cstdio>
00028 
00029 #include "common.h"
00030 #include "log.h"
00031 #include "mutex.h"
00032 #include "mem_displayer.h"
00033 #include "displayer.h"
00034 #include "app_context.h"
00035 #include <set>
00036 
00037 namespace NLMISC
00038 {
00039 
00040 #ifdef ASSERT_THROW_EXCEPTION
00041 #define ASSERT_THROW_EXCEPTION_CODE(exp) ASSERT_THROW_EXCEPTION_CODE_EX(exp, #exp)
00042 #define ASSERT_THROW_EXCEPTION_CODE_EX(exp, str) if(!(exp)) throw NLMISC::Exception(str" returns false");
00043 #else
00044 #define ASSERT_THROW_EXCEPTION_CODE(exp)
00045 #define ASSERT_THROW_EXCEPTION_CODE_EX(exp, str)
00046 #endif
00047 
00055 class CImposterLog
00056 {
00057 private:
00058     typedef CLog *(INelContext::*TAccessor)();
00059 
00060     // Method to access the Log
00061     TAccessor   _Accessor;
00062 public:
00063     CImposterLog(TAccessor accessor);
00064     CLog* operator -> ();
00065     operator CLog*();
00066     CLog &operator ()();
00067 };
00068 
00069 
00070 //
00071 // Externals
00072 //
00073 
00074 // NOTE: The following are all NULL until createDebug() has been called at least once
00075 // NOTE2: You must not use this class before the main() (not inside a static class ctor)
00076 extern CImposterLog     ErrorLog;
00077 extern CImposterLog     WarningLog;
00078 extern CImposterLog     InfoLog;
00079 extern CImposterLog     DebugLog;
00080 extern CImposterLog     AssertLog;
00081 
00082 extern CMemDisplayer *DefaultMemDisplayer;
00083 extern CMsgBoxDisplayer *DefaultMsgBoxDisplayer;
00084 
00085 
00086 //
00087 // Functions
00088 //
00089 
00090 // internal use only
00091 void createDebug (const char *logPath = NULL, bool logInFile = true, bool eraseLastLog = false);
00092 
00094 void destroyDebug();
00095 
00096 // call this if you want to change the dir of the log.log file
00097 void changeLogDirectory(const std::string &dir);
00098 
00099 // internal breakpoint window
00100 void enterBreakpoint (const char *message);
00101 
00102 // if true, the assert generates an assert
00103 // if false, the assert just displays a warning and continue
00104 void setAssert (bool assert);
00105 
00106 // Beep (Windows only, no effect elsewhere)
00107 void beep( uint freq, uint duration );
00108 
00109 
00110 typedef std::string (*TCrashCallback)();
00111 
00112 // this function enables user application to add information in the log when a crash occurs
00113 void setCrashCallback(TCrashCallback crashCallback);
00114 
00115 // For Crash report window. allow to know if a crash has already raised in the application
00116 bool    isCrashAlreadyReported();
00117 void    setCrashAlreadyReported(bool state);
00118 
00119 
00120 // This very amazing macro __FUNCTION__ doesn't exist on VC6, map it to NULL
00121 #ifdef NL_COMP_VC6
00122 #   define __FUNCTION__ NULL
00123 #endif
00124 
00125 
00126 // Macros
00127 
00129 #define NL_MACRO_TO_STR_SUBPART(x) #x
00130 
00139 #define NL_MACRO_TO_STR(x) NL_MACRO_TO_STR_SUBPART(x)
00140 
00158 #define NL_LOC_MSG __FILE__"("NL_MACRO_TO_STR(__LINE__)") : Message: "
00159 #define NL_LOC_WRN __FILE__"("NL_MACRO_TO_STR(__LINE__)") : Warning Msg: "
00160 
00161 
00175 #ifdef NL_NO_DEBUG
00176 #   if defined(NL_COMP_VC71) || defined(NL_COMP_VC8) || defined(NL_COMP_VC9)
00177 #       define nldebug __noop
00178 #   else
00179 #       define nldebug 0&&
00180 #   endif
00181 #else // NL_NO_DEBUG
00182     extern bool DisableNLDebug;
00183 #   define nldebug if (NLMISC::DisableNLDebug) {} else (NLMISC::createDebug(), NLMISC::INelContext::getInstance().getDebugLog()->setPosition( __LINE__, __FILE__, __FUNCTION__ ), NLMISC::INelContext::getInstance().getDebugLog())->displayNL
00184 #endif // NL_NO_DEBUG
00185 
00190 #ifdef NL_NO_DEBUG
00191 #   if defined(NL_COMP_VC71) || defined(NL_COMP_VC8) || defined(NL_COMP_VC9)
00192 #       define nlinfo __noop
00193 #   else
00194 #       define nlinfo 0&&
00195 #   endif
00196 #else // NL_NO_DEBUG
00197 #   define nlinfo (NLMISC::createDebug(), NLMISC::INelContext::getInstance().getInfoLog()->setPosition( __LINE__, __FILE__, __FUNCTION__ ), NLMISC::INelContext::getInstance().getInfoLog())->displayNL
00198 #endif // NL_NO_DEBUG
00199 
00218 #ifdef NL_NO_DEBUG
00219 #   if defined(NL_COMP_VC71) || defined(NL_COMP_VC8) || defined(NL_COMP_VC9)
00220 #       define nlwarning __noop
00221 #   else
00222 #       define nlwarning 0&&
00223 #   endif
00224 #else // NL_NO_DEBUG
00225 #   define nlwarning (NLMISC::createDebug(), NLMISC::INelContext::getInstance().getWarningLog()->setPosition( __LINE__, __FILE__, __FUNCTION__ ), NLMISC::INelContext::getInstance().getWarningLog())->displayNL
00226 #endif // NL_NO_DEBUG
00227 
00244 #define nlerror (NLMISC::createDebug (), NLMISC::INelContext::getInstance().getErrorLog()->setPosition( __LINE__, __FILE__, __FUNCTION__ ), NLMISC::nlFatalError)
00245 
00246 
00252 #define nlerrornoex (NLMISC::createDebug (), NLMISC::INelContext::getInstance().getErrorLog()->setPosition( __LINE__, __FILE__, __FUNCTION__ ), NLMISC::nlError)
00253 
00254 
00356 // removed because we always check assert (even in release mode) #if defined (NL_OS_WINDOWS) && defined (NL_DEBUG)
00357 #if defined (NL_OS_WINDOWS)
00358 #define NLMISC_BREAKPOINT __debugbreak();
00359 #else
00360 #define NLMISC_BREAKPOINT abort()
00361 #endif
00362 
00363 // Internal, don't use it (make smaller assert code)
00364 extern bool _assert_stop(bool &ignoreNextTime, sint line, const char *file, const char *funcName, const char *exp);
00365 extern void _assertex_stop_0(bool &ignoreNextTime, sint line, const char *file, const char *funcName, const char *exp);
00366 extern bool _assertex_stop_1(bool &ignoreNextTime);
00367 
00368 // removed because we always check assert (even in release mode) #if defined(NL_DEBUG)
00369 
00370 #ifdef NL_NO_DEBUG
00371 #   define nlassert(exp) if(false)
00372 #   define nlassertonce(exp) if(false)
00373 #   define nlassertex(exp, str) if(false)
00374 #   define nlverify(exp) { exp; }
00375 #   define nlverifyonce(exp) { exp; }
00376 #   define nlverifyex(exp, str) { exp; }
00377 #else // NL_NO_DEBUG
00378 
00379 #   ifdef NL_OS_UNIX
00380 
00381 // Linux set of asserts is reduced due to that there is no message box displayer
00382 
00383 #define nlassert(exp) \
00384 { \
00385     if (!(exp)) { \
00386         NLMISC::createDebug (); \
00387         NLMISC::INelContext::getInstance().getAssertLog()->setPosition (__LINE__, __FILE__, __FUNCTION__); \
00388         NLMISC::INelContext::getInstance().getAssertLog()->displayNL ("\"%s\" ", #exp); \
00389         NLMISC_BREAKPOINT; \
00390     } \
00391 }
00392 
00393 #define nlassertonce(exp) nlassert(exp)
00394 
00395 #define nlassertex(exp, str) \
00396 { \
00397     if (!(exp)) { \
00398         NLMISC::createDebug (); \
00399         NLMISC::INelContext::getInstance().getAssertLog()->setPosition (__LINE__, __FILE__, __FUNCTION__); \
00400         NLMISC::INelContext::getInstance().getAssertLog()->displayNL ("\"%s\" ", #exp); \
00401         NLMISC::INelContext::getInstance().getAssertLog()->displayRawNL str; \
00402         NLMISC_BREAKPOINT; \
00403     } \
00404 }
00405 
00406 #define nlverify(exp) nlassert(exp)
00407 #define nlverifyonce(exp) nlassert(exp)
00408 #define nlverifyex(exp, str) nlassertex(exp, str)
00409 
00410 #   else // NL_OS_UNIX
00411 
00412 #define nlassert(exp) \
00413 { \
00414     static bool ignoreNextTime = false; \
00415     bool _expResult_ = (exp) ? true : false; \
00416     if (!ignoreNextTime && !_expResult_) { \
00417         if(NLMISC::_assert_stop(ignoreNextTime, __LINE__, __FILE__, __FUNCTION__, #exp)) \
00418             NLMISC_BREAKPOINT; \
00419     } \
00420     ASSERT_THROW_EXCEPTION_CODE_EX(_expResult_, #exp) \
00421 }
00422 
00423 #define nlassertonce(exp) \
00424 { \
00425     static bool ignoreNextTime = false; \
00426     if (!ignoreNextTime && !(exp)) { \
00427         ignoreNextTime = true; \
00428         if(NLMISC::_assert_stop(ignoreNextTime, __LINE__, __FILE__, __FUNCTION__, #exp)) \
00429             NLMISC_BREAKPOINT; \
00430     } \
00431 }
00432 
00433 #define nlassertex(exp, str) \
00434 { \
00435     static bool ignoreNextTime = false; \
00436     bool _expResult_ = (exp) ? true : false; \
00437     if (!ignoreNextTime && !_expResult_) { \
00438         NLMISC::_assertex_stop_0(ignoreNextTime, __LINE__, __FILE__, __FUNCTION__, #exp); \
00439         NLMISC::INelContext::getInstance().getAssertLog()->displayRawNL str; \
00440         if(NLMISC::_assertex_stop_1(ignoreNextTime)) \
00441             NLMISC_BREAKPOINT; \
00442     } \
00443     ASSERT_THROW_EXCEPTION_CODE_EX(_expResult_, #exp) \
00444 }
00445 
00446 #define nlverify(exp) \
00447 { \
00448     static bool ignoreNextTime = false; \
00449     bool _expResult_ = (exp) ? true : false; \
00450     if (!_expResult_ && !ignoreNextTime) { \
00451         if(NLMISC::_assert_stop(ignoreNextTime, __LINE__, __FILE__, __FUNCTION__, #exp)) \
00452             NLMISC_BREAKPOINT; \
00453     } \
00454     ASSERT_THROW_EXCEPTION_CODE_EX(_expResult_, #exp) \
00455 }
00456 
00457 #define nlverifyonce(exp) \
00458 { \
00459     static bool ignoreNextTime = false; \
00460     bool _expResult_ = (exp) ? true : false; \
00461     if (!_expResult_ && !ignoreNextTime) { \
00462         ignoreNextTime = true; \
00463         if(NLMISC::_assert_stop(ignoreNextTime, __LINE__, __FILE__, __FUNCTION__, #exp)) \
00464             NLMISC_BREAKPOINT; \
00465     } \
00466 }
00467 
00468 #define nlverifyex(exp, str) \
00469 { \
00470     static bool ignoreNextTime = false; \
00471     bool _expResult_ = (exp) ? true : false; \
00472     if (!_expResult_ && !ignoreNextTime) { \
00473         NLMISC::_assertex_stop_0(ignoreNextTime, __LINE__, __FILE__, __FUNCTION__, #exp); \
00474         NLMISC::INelContext::getInstance().getAssertLog()->displayRawNL str; \
00475         if(NLMISC::_assertex_stop_1(ignoreNextTime)) \
00476             NLMISC_BREAKPOINT; \
00477     } \
00478     ASSERT_THROW_EXCEPTION_CODE_EX(_expResult_, #exp) \
00479 }
00480 
00481 #   endif // NL_OS_UNIX
00482 
00483 #endif // NL_NO_DEBUG
00484 
00485 #define nlunreferenced(identifier) (identifier)
00486 
00487 #define nlstop \
00488 { \
00489     static bool ignoreNextTime = false; \
00490     if (!ignoreNextTime) { \
00491         if(NLMISC::_assert_stop(ignoreNextTime, __LINE__, __FILE__, __FUNCTION__, NULL)) \
00492             NLMISC_BREAKPOINT; \
00493     } \
00494     ASSERT_THROW_EXCEPTION_CODE(false) \
00495 }
00496 
00497 #define nlstoponce \
00498 { \
00499     static bool ignoreNextTime = false; \
00500     if (!ignoreNextTime) { \
00501         ignoreNextTime = true; \
00502         if(NLMISC::_assert_stop(ignoreNextTime, __LINE__, __FILE__, __FUNCTION__, NULL)) \
00503             NLMISC_BREAKPOINT; \
00504     } \
00505 }
00506 
00507 
00508 #define nlstopex(str) \
00509 { \
00510     static bool ignoreNextTime = false; \
00511     if (!ignoreNextTime) { \
00512         NLMISC::_assertex_stop_0(ignoreNextTime, __LINE__, __FILE__, __FUNCTION__, NULL); \
00513         NLMISC::INelContext::getInstance().getAssertLog()->displayRawNL str; \
00514         if(NLMISC::_assertex_stop_1(ignoreNextTime)) \
00515             NLMISC_BREAKPOINT; \
00516     } \
00517 }
00518 
00519 
00520 struct EFatalError : public Exception
00521 {
00522     EFatalError() : Exception( "nlerror() called" ) {}
00523 };
00524 
00525 class ETrapDebug : public Exception
00526 {
00527 };
00528 
00529 // undef default assert to force people to use nlassert() instead of assert()
00530 // if NL_MAP_ASSERT is set we map assert to nlassert instead of removing it
00531 // this makes it compatible with zeroc's ICE network library
00532 
00533 #ifdef NL_MAP_ASSERT
00534 #   ifdef assert
00535 #       undef assert
00536 #       define assert nlassert
00537 #   endif
00538 #else
00539 #   ifdef assert
00540 #       undef assert
00541 #       define assert(a) you_must_not_use_assert___use_nl_assert___read_debug_h_file
00542 #   endif
00543 #endif
00544 
00545 
00547 void getCallStack(std::string &result, sint skipNFirst = 0);
00548 
00550 void getCallStackAndLog (std::string &result, sint skipNFirst = 0);
00551 
00556 template<class T, class U>  inline T    safe_cast(U o)
00557 {
00558     // NB: must check debug because assert may still be here in release
00559 #ifdef NL_DEBUG
00560     nlassert(dynamic_cast<T>(o));
00561 #endif
00562     return static_cast<T>(o);
00563 }
00564 
00570 template<class T, class U>  inline T    type_cast(U o)
00571 {
00572     // NB: must check debug because assert may still be here in release
00573 #ifdef NL_DEBUG
00574     if (o)
00575         nlassert(dynamic_cast<T>(o));
00576 #endif
00577     //  optimization made to check pointer validity before address translation. (hope it works on linux).
00578     if ((size_t)(static_cast<T>((U)0x0400)) == (size_t)((U)0x0400))
00579     {
00580         return static_cast<T>(o);
00581     }
00582     else
00583     {
00584         return (o==0)?0:static_cast<T>(o);
00585     }
00586 }
00587 
00590 #define nlctassert(cond) sizeof(uint[(cond) ? 1 : 0])
00591 
00610 // Need a breakpoint in the assert / verify macro
00611 extern bool DebugNeedAssert;
00612 
00613 // Internal process, don't use it
00614 extern bool NoAssert;
00615 
00616 
00617 template<class T>
00618 class CMustConsume
00619 {
00620 public:
00621     CMustConsume(const T &val) : Value(val)
00622 #if !FINAL_VERSION
00623     , Consumed(false)
00624 #endif
00625     {
00626     }
00627 
00628     ~CMustConsume()
00629     {
00630 #if !FINAL_VERSION
00631         nlassert(Consumed == true);
00632 #endif
00633     }
00634 
00635     //  Get the value without validating the access.
00636     const T &value() const
00637     {
00638         return Value;
00639     }
00640 
00641     operator const T &() const
00642     {
00643 #if !FINAL_VERSION
00644         Consumed = true;
00645 #endif
00646         return Value;
00647     }
00648 
00649     //  Get the value and validate the access.
00650     const T &consumeValue() const
00651     {
00652 #if !FINAL_VERSION
00653         Consumed = true;
00654 #endif
00655         return Value;
00656     }
00657     //  Only consume the access.
00658     void consume() const
00659     {
00660 #if !FINAL_VERSION
00661         Consumed = true;
00662 #endif
00663     }
00664 
00665 private:
00666     T               Value;
00667 #if !FINAL_VERSION
00668     mutable bool    Consumed;
00669 #endif
00670 };
00671 
00673 struct TInstanceCounterData
00674 {
00675     sint32      _InstanceCounter;
00676     sint32      _DeltaCounter;
00677     const char  *_ClassName;
00678     bool        _Touched;
00679 
00680     TInstanceCounterData(const char *className);
00681 
00682     ~TInstanceCounterData();
00683 };
00684 
00685 // forward declaration for members of CInstanceCounterManager
00686 class CInstanceCounterLocalManager;
00687 
00688 // The singleton used to display the instance counter
00689 class CInstanceCounterManager
00690 {
00691 //  NLMISC_SAFE_SINGLETON_DECL(CInstanceCounterManager);
00692     private:
00693         /* declare private constructors*/
00694         CInstanceCounterManager () {}
00695         CInstanceCounterManager (const CInstanceCounterManager &) {}
00696         /* the local static pointer to the singleton instance */
00697         static CInstanceCounterManager  *_Instance;
00698     public:
00699         static CInstanceCounterManager &getInstance()
00700         {
00701             if (_Instance == NULL)
00702             {
00703                 /* the nel context MUST be initialised */
00704 //              nlassert(NLMISC::NelContext != NULL);
00705                 void *ptr = NLMISC::INelContext::getInstance().getSingletonPointer("CInstanceCounterManager");
00706                 if (ptr == NULL)
00707                 {
00708                     /* allocate the singleton and register it */
00709                     _Instance = new CInstanceCounterManager;
00710                     NLMISC::INelContext::getInstance().setSingletonPointer("CInstanceCounterManager", _Instance);
00711                 }
00712                 else
00713                 {
00714                     _Instance = reinterpret_cast<CInstanceCounterManager*>(ptr);
00715                 }
00716             }
00717             return *_Instance;
00718         }
00719     private:
00720 public:
00721 
00722     std::string displayCounters() const;
00723 
00724     void resetDeltaCounter();
00725 
00726     uint32 getInstanceCounter(const std::string &className) const;
00727     sint32 getInstanceCounterDelta(const std::string &className) const;
00728 
00729 private:
00730 
00731     friend class CInstanceCounterLocalManager;
00732 
00733     void registerInstaceCounterLocalManager(CInstanceCounterLocalManager *localMgr);
00734     void unregisterInstaceCounterLocalManager(CInstanceCounterLocalManager *localMgr);
00735 
00736 //  static CInstanceCounterManager      *_Instance;
00737     std::set<CInstanceCounterLocalManager*> _InstanceCounterMgrs;
00738 };
00739 
00740 //
00741 // Local instance counter
00742 //
00743 class CInstanceCounterLocalManager
00744 {
00745 public:
00746     static CInstanceCounterLocalManager &getInstance()
00747     {
00748         if (_Instance == NULL)
00749         {
00750             _Instance = new CInstanceCounterLocalManager;
00751         }
00752         return *_Instance;
00753     }
00754 
00755     static void releaseInstance()
00756     {
00757         if (_Instance != NULL)
00758         {
00759             delete _Instance;
00760             _Instance = NULL;
00761         }
00762     }
00763 
00764     void registerInstanceCounter(TInstanceCounterData *counter)
00765     {
00766         _InstanceCounters.insert(counter);
00767     }
00768 
00769     void unregisterInstanceCounter(TInstanceCounterData *counter);
00770 
00771     ~CInstanceCounterLocalManager()
00772     {
00773         CInstanceCounterManager::getInstance().unregisterInstaceCounterLocalManager(this);
00774     }
00775 
00776 private:
00777     friend class CInstanceCounterManager;
00778     friend class INelContext;
00779 
00780     CInstanceCounterLocalManager()
00781     {
00782     }
00783 
00784     void registerLocalManager()
00785     {
00786         CInstanceCounterManager::getInstance().registerInstaceCounterLocalManager(this);
00787     }
00788 
00789     static CInstanceCounterLocalManager     *_Instance;
00790     std::set<TInstanceCounterData*>         _InstanceCounters;
00791 };
00792 
00793 
00816 #define NL_INSTANCE_COUNTER_DECL(className) \
00817 public: \
00818     struct className##InstanceCounter \
00819     { \
00820         className##InstanceCounter() \
00821         { \
00822             _InstanceCounterData._InstanceCounter++; \
00823             _InstanceCounterData._Touched = true; \
00824         } \
00825         className##InstanceCounter(const className##InstanceCounter &/* other */) \
00826         { \
00827             _InstanceCounterData._InstanceCounter++; \
00828             _InstanceCounterData._Touched = true; \
00829         } \
00830         \
00831         ~className##InstanceCounter()\
00832         { \
00833             _InstanceCounterData._InstanceCounter--; \
00834         } \
00835         static sint32 getInstanceCounter() \
00836         { \
00837             return _InstanceCounterData._InstanceCounter; \
00838         } \
00839         static sint32 getInstanceCounterDelta() \
00840         { \
00841             return _InstanceCounterData._InstanceCounter - _InstanceCounterData._DeltaCounter; \
00842         } \
00843         static NLMISC::TInstanceCounterData _InstanceCounterData; \
00844     }; \
00845      \
00846     className##InstanceCounter  _##className##InstanceCounter; \
00847 private:
00848 
00850 #define NL_INSTANCE_COUNTER_IMPL(className) NLMISC::TInstanceCounterData className::className##InstanceCounter::_InstanceCounterData(#className);
00851 
00853 #define NL_GET_LOCAL_INSTANCE_COUNTER(className) className::className##InstanceCounter::getInstanceCounter()
00854 #define NL_GET_INSTANCE_COUNTER(className) NLMISC::CInstanceCounterManager::getInstance().getInstanceCounter(#className)
00855 
00857 #define NL_GET_LOCAL_INSTANCE_COUNTER_DELTA(className) className::className##InstanceCounter::getInstanceCounterDelta()
00858 #define NL_GET_INSTANCE_COUNTER_DELTA(className) NLMISC::CInstanceCounterManager::getInstance().getInstanceCounterDelta(#className)
00859 
00860 //
00861 // Following are internal functions, you should never use them
00862 //
00863 
00865 void nlFatalError (const char *format, ...);
00866 
00868 void nlError (const char *format, ...);
00869 
00870 #define NL_CRASH_DUMP_FILE "nel_debug.dmp"
00871 
00872 // Standard API to retrieve error code and test for windows or unix platform
00873 
00875 int getLastError();
00876 
00878 std::string formatErrorMessage(int errorCode);
00879 
00880 
00881 //-------------------------------------------------------------------------------------------------
00882 // A handy 'nldebug', 'nlinfo' & 'nlwarning' override system
00883 //-------------------------------------------------------------------------------------------------
00884 //
00885 // The system includes a set of object classes
00886 // To override one or more of the standard NeL log channels one simply instantiates the appropriate class
00887 // with the new log channel as a parameter.
00888 // The log channel in question will revert to its previous value on destruction of the override object
00889 //
00890 // Usage Example:
00891 //
00892 //  void doSomething()
00893 //  {
00894 //      nlinfo("bla");
00895 //      nlwarning("bla");
00896 //  }
00897 //
00898 //  NLMISC_COMMAND(bla,"bla","bla")
00899 //  {
00900 //      CNLLogOverride(&log);
00901 //      doSomething();
00902 //      return true;
00903 //  }
00904 //
00905 
00906 //-------------------------------------------------------------------------------------------------
00907 
00908 class CNLDebugOverride
00909 {
00910 public:
00911     CNLDebugOverride(NLMISC::CLog *debugLog)
00912     {
00913         nlassert(debugLog!=NULL);
00914         _OldValue=NLMISC::DebugLog;
00915         nlassert(_OldValue!=NULL);
00916         NLMISC::INelContext::getInstance().setDebugLog(debugLog);
00917     }
00918     ~CNLDebugOverride()
00919     {
00920         NLMISC::INelContext::getInstance().setDebugLog(_OldValue);
00921     }
00922 private:
00923     // prohibit copy
00924     CNLDebugOverride(const CNLDebugOverride&);
00925     NLMISC::CLog *_OldValue;
00926 };
00927 
00928 //-------------------------------------------------------------------------------------------------
00929 
00930 class CNLInfoOverride
00931 {
00932 public:
00933     CNLInfoOverride(NLMISC::CLog *infoLog)
00934     {
00935         nlassert(infoLog!=NULL);
00936         _OldValue=NLMISC::InfoLog;
00937         nlassert(_OldValue!=NULL);
00938         NLMISC::INelContext::getInstance().setInfoLog(infoLog);
00939     }
00940     ~CNLInfoOverride()
00941     {
00942         NLMISC::INelContext::getInstance().setInfoLog(_OldValue);
00943     }
00944 private:
00945     // prohibit copy
00946     CNLInfoOverride(const CNLInfoOverride&);
00947     NLMISC::CLog *_OldValue;
00948 };
00949 
00950 //-------------------------------------------------------------------------------------------------
00951 
00952 class CNLWarningOverride
00953 {
00954 public:
00955     CNLWarningOverride(NLMISC::CLog *warningLog)
00956     {
00957         nlassert(warningLog!=NULL);
00958         _OldValue=NLMISC::WarningLog;
00959         nlassert(_OldValue!=NULL);
00960         NLMISC::INelContext::getInstance().setWarningLog(warningLog);
00961     }
00962     ~CNLWarningOverride()
00963     {
00964         NLMISC::INelContext::getInstance().setWarningLog(_OldValue);
00965     }
00966 private:
00967     // prohibit copy
00968     CNLWarningOverride(const CNLWarningOverride&);
00969     NLMISC::CLog *_OldValue;
00970 };
00971 
00972 //-------------------------------------------------------------------------------------------------
00973 
00974 class CNLLogOverride
00975 {
00976 public:
00977     CNLLogOverride(NLMISC::CLog *commonLog): _DebugLog(commonLog), _InfoLog(commonLog), _WarningLog(commonLog)  {}
00978 
00979 private:
00980     CNLDebugOverride    _DebugLog;
00981     CNLInfoOverride     _InfoLog;
00982     CNLWarningOverride  _WarningLog;
00983 };
00984 
00985 
00986 //-------------------------------------------------------------------------------------------------
00987 
00988 class CNLSmartLogOverride
00989 {
00990 public:
00991     CNLSmartLogOverride(NLMISC::CLog *commonLog):
00992         _DebugLog(commonLog==NLMISC::InfoLog?NLMISC::DebugLog:commonLog),
00993         _InfoLog(commonLog),
00994         _WarningLog(commonLog==NLMISC::InfoLog?NLMISC::WarningLog:commonLog)
00995         {}
00996 
00997 private:
00998     CNLDebugOverride    _DebugLog;
00999     CNLInfoOverride     _InfoLog;
01000     CNLWarningOverride  _WarningLog;
01001 };
01002 
01003 
01004 
01005 
01006 } // NLMISC
01007 
01008 #endif // NL_DEBUG_H
01009 
01010 /* End of debug.h */

Generated on Thu Jan 7 08:26:22 2010 for NeL by  doxygen 1.6.1