Advertisement
Guest User

Untitled

a guest
Apr 23rd, 2011
685
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 24.71 KB | None | 0 0
  1. //===== Copyright © 1996-2005, Valve Corporation, All rights reserved. ========//
  2. //
  3. // Purpose:
  4. //
  5. // $NoKeywords: $
  6. //
  7. //=============================================================================//
  8. #ifndef DBG_H
  9. #define DBG_H
  10.  
  11. #ifdef _WIN32
  12. #pragma once
  13. #endif
  14.  
  15. #include "basetypes.h"
  16. #include "dbgflag.h"
  17. #include "platform.h"
  18. #include <math.h>
  19. #include <stdio.h>
  20. #include <stdarg.h>
  21.  
  22. #ifdef _LINUX
  23. #define __cdecl
  24. #endif
  25.  
  26. //-----------------------------------------------------------------------------
  27. // dll export stuff
  28. //-----------------------------------------------------------------------------
  29. #ifndef STATIC_TIER0
  30.  
  31. #ifdef TIER0_DLL_EXPORT
  32. #define DBG_INTERFACE   DLL_EXPORT
  33. #define DBG_OVERLOAD    DLL_GLOBAL_EXPORT
  34. #define DBG_CLASS       DLL_CLASS_EXPORT
  35. #else
  36. #define DBG_INTERFACE   DLL_IMPORT
  37. #define DBG_OVERLOAD    DLL_GLOBAL_IMPORT
  38. #define DBG_CLASS       DLL_CLASS_IMPORT
  39. #endif
  40.  
  41. #else // BUILD_AS_DLL
  42.  
  43. #define DBG_INTERFACE   extern
  44. #define DBG_OVERLOAD   
  45. #define DBG_CLASS      
  46. #endif // BUILD_AS_DLL
  47.  
  48.  
  49. class Color;
  50.  
  51.  
  52. //-----------------------------------------------------------------------------
  53. // Usage model for the Dbg library
  54. //
  55. // 1. Spew.
  56. //
  57. //   Spew can be used in a static and a dynamic mode. The static
  58. //   mode allows us to display assertions and other messages either only
  59. //   in debug builds, or in non-release builds. The dynamic mode allows us to
  60. //   turn on and off certain spew messages while the application is running.
  61. //
  62. //   Static Spew messages:
  63. //
  64. //     Assertions are used to detect and warn about invalid states
  65. //     Spews are used to display a particular status/warning message.
  66. //
  67. //     To use an assertion, use
  68. //
  69. //     Assert( (f == 5) );
  70. //     AssertMsg( (f == 5), ("F needs to be %d here!\n", 5) );
  71. //     AssertFunc( (f == 5), BadFunc() );
  72. //     AssertEquals( f, 5 );
  73. //     AssertFloatEquals( f, 5.0f, 1e-3 );
  74. //
  75. //     The first will simply report that an assertion failed on a particular
  76. //     code file and line. The second version will display a print-f formatted message
  77. //     along with the file and line, the third will display a generic message and
  78. //     will also cause the function BadFunc to be executed, and the last two
  79. //     will report an error if f is not equal to 5 (the last one asserts within
  80. //     a particular tolerance).
  81. //
  82. //     To use a warning, use
  83. //      
  84. //     Warning("Oh I feel so %s all over\n", "yummy");
  85. //
  86. //     Warning will do its magic in only Debug builds. To perform spew in *all*
  87. //     builds, use RelWarning.
  88. //
  89. //     Three other spew types, Msg, Log, and Error, are compiled into all builds.
  90. //     These error types do *not* need two sets of parenthesis.
  91. //
  92. //     Msg( "Isn't this exciting %d?", 5 );
  93. //     Error( "I'm just thrilled" );
  94. //
  95. //   Dynamic Spew messages
  96. //
  97. //     It is possible to dynamically turn spew on and off. Dynamic spew is
  98. //     identified by a spew group and priority level. To turn spew on for a
  99. //     particular spew group, use SpewActivate( "group", level ). This will
  100. //     cause all spew in that particular group with priority levels <= the
  101. //     level specified in the SpewActivate function to be printed. Use DSpew
  102. //     to perform the spew:
  103. //
  104. //     DWarning( "group", level, "Oh I feel even yummier!\n" );
  105. //
  106. //     Priority level 0 means that the spew will *always* be printed, and group
  107. //     '*' is the default spew group. If a DWarning is encountered using a group
  108. //     whose priority has not been set, it will use the priority of the default
  109. //     group. The priority of the default group is initially set to 0.      
  110. //
  111. //   Spew output
  112. //  
  113. //     The output of the spew system can be redirected to an externally-supplied
  114. //     function which is responsible for outputting the spew. By default, the
  115. //     spew is simply printed using printf.
  116. //
  117. //     To redirect spew output, call SpewOutput.
  118. //
  119. //     SpewOutputFunc( OutputFunc );
  120. //
  121. //     This will cause OutputFunc to be called every time a spew message is
  122. //     generated. OutputFunc will be passed a spew type and a message to print.
  123. //     It must return a value indicating whether the debugger should be invoked,
  124. //     whether the program should continue running, or whether the program
  125. //     should abort.
  126. //
  127. // 2. Code activation
  128. //
  129. //   To cause code to be run only in debug builds, use DBG_CODE:
  130. //   An example is below.
  131. //
  132. //   DBG_CODE(
  133. //              {
  134. //                  int x = 5;
  135. //                  ++x;
  136. //              }
  137. //           );
  138. //
  139. //   Code can be activated based on the dynamic spew groups also. Use
  140. //  
  141. //   DBG_DCODE( "group", level,
  142. //              { int x = 5; ++x; }
  143. //            );
  144. //
  145. // 3. Breaking into the debugger.
  146. //
  147. //   To cause an unconditional break into the debugger in debug builds only, use DBG_BREAK
  148. //
  149. //   DBG_BREAK();
  150. //
  151. //   You can force a break in any build (release or debug) using
  152. //
  153. //   DebuggerBreak();
  154. //-----------------------------------------------------------------------------
  155.  
  156. /* Various types of spew messages */
  157. // I'm sure you're asking yourself why SPEW_ instead of DBG_ ?
  158. // It's because DBG_ is used all over the place in windows.h
  159. // For example, DBG_CONTINUE is defined. Feh.
  160. enum SpewType_t
  161. {
  162.     SPEW_MESSAGE = 0,
  163.     SPEW_WARNING,
  164.     SPEW_ASSERT,
  165.     SPEW_ERROR,
  166.     SPEW_LOG,
  167.  
  168.     SPEW_TYPE_COUNT
  169. };
  170.  
  171. enum SpewRetval_t
  172. {
  173.     SPEW_DEBUGGER = 0,
  174.     SPEW_CONTINUE,
  175.     SPEW_ABORT
  176. };
  177.  
  178. /* type of externally defined function used to display debug spew */
  179. typedef SpewRetval_t (*SpewOutputFunc_t)( SpewType_t spewType, const tchar *pMsg );
  180.  
  181. /* Used to redirect spew output */
  182. DBG_INTERFACE void   SpewOutputFunc( SpewOutputFunc_t func );
  183.  
  184. /* Used to get the current spew output function */
  185. DBG_INTERFACE SpewOutputFunc_t GetSpewOutputFunc( void );
  186.  
  187. /* Should be called only inside a SpewOutputFunc_t, returns groupname, level, color */
  188. DBG_INTERFACE const tchar* GetSpewOutputGroup( void );
  189. DBG_INTERFACE int GetSpewOutputLevel( void );
  190. DBG_INTERFACE const Color& GetSpewOutputColor( void );
  191.  
  192. /* Used to manage spew groups and subgroups */
  193. DBG_INTERFACE void   SpewActivate( const tchar* pGroupName, int level );
  194. DBG_INTERFACE bool   IsSpewActive( const tchar* pGroupName, int level );
  195.  
  196. /* Used to display messages, should never be called directly. */
  197. DBG_INTERFACE void   _SpewInfo( SpewType_t type, const tchar* pFile, int line );
  198. DBG_INTERFACE SpewRetval_t   _SpewMessage( const tchar* pMsg, ... );
  199. DBG_INTERFACE SpewRetval_t   _DSpewMessage( const tchar *pGroupName, int level, const tchar* pMsg, ... );
  200. DBG_INTERFACE SpewRetval_t   ColorSpewMessage( SpewType_t type, const Color *pColor, const tchar* pMsg, ... );
  201. DBG_INTERFACE void _ExitOnFatalAssert( const tchar* pFile, int line );
  202. DBG_INTERFACE bool ShouldUseNewAssertDialog();
  203.  
  204. DBG_INTERFACE bool SetupWin32ConsoleIO();
  205.  
  206. // Returns true if they want to break in the debugger.
  207. DBG_INTERFACE bool DoNewAssertDialog( const tchar *pFile, int line, const tchar *pExpression );
  208.  
  209. /* Used to define macros, never use these directly. */
  210.  
  211. #define  _AssertMsg( _exp, _msg, _executeExp, _bFatal ) \
  212.     do {                                                                \
  213.         if (!(_exp))                                                    \
  214.         {                                                               \
  215.             _SpewInfo( SPEW_ASSERT, __TFILE__, __LINE__ );              \
  216.             SpewRetval_t ret = _SpewMessage("%s", _msg);    \
  217.             _executeExp;                                                \
  218.             if ( ret == SPEW_DEBUGGER)                                  \
  219.             {                                                           \
  220.                 if ( !ShouldUseNewAssertDialog() || DoNewAssertDialog( __TFILE__, __LINE__, _msg ) ) \
  221.                     DebuggerBreak();                                    \
  222.                 if ( _bFatal )                                          \
  223.                     _ExitOnFatalAssert( __TFILE__, __LINE__ );          \
  224.             }                                                           \
  225.         }                                                               \
  226.     } while (0)
  227.  
  228. #define  _AssertMsgOnce( _exp, _msg, _bFatal ) \
  229.     do {                                                                \
  230.         static bool fAsserted;                                          \
  231.         if (!fAsserted )                                                \
  232.         {                                                               \
  233.             _AssertMsg( _exp, _msg, (fAsserted = true), _bFatal );      \
  234.         }                                                               \
  235.     } while (0)
  236.  
  237. /* Spew macros... */
  238.  
  239. // AssertFatal macros
  240. // AssertFatal is used to detect an unrecoverable error condition.
  241. // If enabled, it may display an assert dialog (if DBGFLAG_ASSERTDLG is turned on or running under the debugger),
  242. // and always terminates the application
  243.  
  244. #ifdef DBGFLAG_ASSERTFATAL
  245.  
  246. #define  AssertFatal( _exp )                                    _AssertMsg( _exp, _T("Assertion Failed: ") _T(#_exp), ((void)0), true )
  247. #define  AssertFatalOnce( _exp )                                _AssertMsgOnce( _exp, _T("Assertion Failed: ") _T(#_exp), true )
  248. #define  AssertFatalMsg( _exp, _msg )                           _AssertMsg( _exp, _msg, ((void)0), true )
  249. #define  AssertFatalMsgOnce( _exp, _msg )                       _AssertMsgOnce( _exp, _msg, true )
  250. #define  AssertFatalFunc( _exp, _f )                            _AssertMsg( _exp, _T("Assertion Failed: " _T(#_exp), _f, true )
  251. #define  AssertFatalEquals( _exp, _expectedValue )              AssertFatalMsg2( (_exp) == (_expectedValue), _T("Expected %d but got %d!"), (_expectedValue), (_exp) )
  252. #define  AssertFatalFloatEquals( _exp, _expectedValue, _tol )   AssertFatalMsg2( fabs((_exp) - (_expectedValue)) <= (_tol), _T("Expected %f but got %f!"), (_expectedValue), (_exp) )
  253. #define  VerifyFatal( _exp )                                    AssertFatal( _exp )
  254. #define  VerifyEqualsFatal( _exp, _expectedValue )              AssertFatalEquals( _exp, _expectedValue )
  255.  
  256. #define  AssertFatalMsg1( _exp, _msg, a1 )                                  AssertFatalMsg( _exp, (const tchar *)(CDbgFmtMsg( _msg, a1 )))
  257. #define  AssertFatalMsg2( _exp, _msg, a1, a2 )                              AssertFatalMsg( _exp, (const tchar *)(CDbgFmtMsg( _msg, a1, a2 )))
  258. #define  AssertFatalMsg3( _exp, _msg, a1, a2, a3 )                          AssertFatalMsg( _exp, (const tchar *)(CDbgFmtMsg( _msg, a1, a2, a3 )))
  259. #define  AssertFatalMsg4( _exp, _msg, a1, a2, a3, a4 )                      AssertFatalMsg( _exp, (const tchar *)(CDbgFmtMsg( _msg, a1, a2, a3, a4 )))
  260. #define  AssertFatalMsg5( _exp, _msg, a1, a2, a3, a4, a5 )                  AssertFatalMsg( _exp, (const tchar *)(CDbgFmtMsg( _msg, a1, a2, a3, a4, a5 )))
  261. #define  AssertFatalMsg6( _exp, _msg, a1, a2, a3, a4, a5, a6 )              AssertFatalMsg( _exp, (const tchar *)(CDbgFmtMsg( _msg, a1, a2, a3, a4, a5, a6 )))
  262. #define  AssertFatalMsg6( _exp, _msg, a1, a2, a3, a4, a5, a6 )              AssertFatalMsg( _exp, (const tchar *)(CDbgFmtMsg( _msg, a1, a2, a3, a4, a5, a6 )))
  263. #define  AssertFatalMsg7( _exp, _msg, a1, a2, a3, a4, a5, a6, a7 )          AssertFatalMsg( _exp, (const tchar *)(CDbgFmtMsg( _msg, a1, a2, a3, a4, a5, a6, a7 )))
  264. #define  AssertFatalMsg8( _exp, _msg, a1, a2, a3, a4, a5, a6, a7, a8 )      AssertFatalMsg( _exp, (const tchar *)(CDbgFmtMsg( _msg, a1, a2, a3, a4, a5, a6, a7, a8 )))
  265. #define  AssertFatalMsg9( _exp, _msg, a1, a2, a3, a4, a5, a6, a7, a8, a9 )  AssertFatalMsg( _exp, (const tchar *)(CDbgFmtMsg( _msg, a1, a2, a3, a4, a5, a6, a7, a8, a9 )))
  266.  
  267. #else // DBGFLAG_ASSERTFATAL
  268.  
  269. #define  AssertFatal( _exp )                                    ((void)0)
  270. #define  AssertFatalOnce( _exp )                                ((void)0)
  271. #define  AssertFatalMsg( _exp, _msg )                           ((void)0)
  272. #define  AssertFatalMsgOnce( _exp, _msg )                       ((void)0)
  273. #define  AssertFatalFunc( _exp, _f )                            ((void)0)
  274. #define  AssertFatalEquals( _exp, _expectedValue )              ((void)0)
  275. #define  AssertFatalFloatEquals( _exp, _expectedValue, _tol )   ((void)0)
  276. #define  VerifyFatal( _exp )                                    (_exp)
  277. #define  VerifyEqualsFatal( _exp, _expectedValue )              (_exp)
  278.  
  279. #define  AssertFatalMsg1( _exp, _msg, a1 )                                  ((void)0)
  280. #define  AssertFatalMsg2( _exp, _msg, a1, a2 )                              ((void)0)
  281. #define  AssertFatalMsg3( _exp, _msg, a1, a2, a3 )                          ((void)0)
  282. #define  AssertFatalMsg4( _exp, _msg, a1, a2, a3, a4 )                      ((void)0)
  283. #define  AssertFatalMsg5( _exp, _msg, a1, a2, a3, a4, a5 )                  ((void)0)
  284. #define  AssertFatalMsg6( _exp, _msg, a1, a2, a3, a4, a5, a6 )              ((void)0)
  285. #define  AssertFatalMsg6( _exp, _msg, a1, a2, a3, a4, a5, a6 )              ((void)0)
  286. #define  AssertFatalMsg7( _exp, _msg, a1, a2, a3, a4, a5, a6, a7 )          ((void)0)
  287. #define  AssertFatalMsg8( _exp, _msg, a1, a2, a3, a4, a5, a6, a7, a8 )      ((void)0)
  288. #define  AssertFatalMsg9( _exp, _msg, a1, a2, a3, a4, a5, a6, a7, a8, a9 )  ((void)0)
  289.  
  290. #endif // DBGFLAG_ASSERTFATAL
  291.  
  292. // Assert macros
  293. // Assert is used to detect an important but survivable error.
  294. // It's only turned on when DBGFLAG_ASSERT is true.
  295.  
  296. #ifdef DBGFLAG_ASSERT
  297.  
  298. #define  Assert( _exp )                                     _AssertMsg( _exp, _T("Assertion Failed: ") _T(#_exp), ((void)0), false )
  299. #define  AssertMsg( _exp, _msg )                            _AssertMsg( _exp, _msg, ((void)0), false )
  300. #define  AssertOnce( _exp )                                 _AssertMsgOnce( _exp, _T("Assertion Failed: ") _T(#_exp), false )
  301. #define  AssertMsgOnce( _exp, _msg )                        _AssertMsgOnce( _exp, _msg, false )
  302. #define  AssertFunc( _exp, _f )                             _AssertMsg( _exp, _T("Assertion Failed: ") _T(#_exp), _f, false )
  303. #define  AssertEquals( _exp, _expectedValue )               AssertMsg2( (_exp) == (_expectedValue), _T("Expected %d but got %d!"), (_expectedValue), (_exp) )
  304. #define  AssertFloatEquals( _exp, _expectedValue, _tol )    AssertMsg2( fabs((_exp) - (_expectedValue)) <= (_tol), _T("Expected %f but got %f!"), (_expectedValue), (_exp) )
  305. #define  Verify( _exp )                                     Assert( _exp )
  306. #define  VerifyEquals( _exp, _expectedValue )               AssertEquals( _exp, _expectedValue )
  307.  
  308. #define  AssertMsg1( _exp, _msg, a1 )                                   AssertMsg( _exp, (const tchar *)(CDbgFmtMsg( _msg, a1 )) )
  309. #define  AssertMsg2( _exp, _msg, a1, a2 )                               AssertMsg( _exp, (const tchar *)(CDbgFmtMsg( _msg, a1, a2 )) )
  310. #define  AssertMsg3( _exp, _msg, a1, a2, a3 )                           AssertMsg( _exp, (const tchar *)(CDbgFmtMsg( _msg, a1, a2, a3 )) )
  311. #define  AssertMsg4( _exp, _msg, a1, a2, a3, a4 )                       AssertMsg( _exp, (const tchar *)(CDbgFmtMsg( _msg, a1, a2, a3, a4 )) )
  312. #define  AssertMsg5( _exp, _msg, a1, a2, a3, a4, a5 )                   AssertMsg( _exp, (const tchar *)(CDbgFmtMsg( _msg, a1, a2, a3, a4, a5 )) )
  313. #define  AssertMsg6( _exp, _msg, a1, a2, a3, a4, a5, a6 )               AssertMsg( _exp, (const tchar *)(CDbgFmtMsg( _msg, a1, a2, a3, a4, a5, a6 )) )
  314. #define  AssertMsg7( _exp, _msg, a1, a2, a3, a4, a5, a6, a7 )           AssertMsg( _exp, (const tchar *)(CDbgFmtMsg( _msg, a1, a2, a3, a4, a5, a6, a7 )) )
  315. #define  AssertMsg8( _exp, _msg, a1, a2, a3, a4, a5, a6, a7, a8 )       AssertMsg( _exp, (const tchar *)(CDbgFmtMsg( _msg, a1, a2, a3, a4, a5, a6, a7, a8 )) )
  316. #define  AssertMsg9( _exp, _msg, a1, a2, a3, a4, a5, a6, a7, a8, a9 )   AssertMsg( _exp, (const tchar *)(CDbgFmtMsg( _msg, a1, a2, a3, a4, a5, a6, a7, a8, a9 )) )
  317.  
  318. #else // DBGFLAG_ASSERT
  319.  
  320. #define  Assert( _exp )                                     ((void)0)
  321. #define  AssertOnce( _exp )                                 ((void)0)
  322. #define  AssertMsg( _exp, _msg )                            ((void)0)
  323. #define  AssertMsgOnce( _exp, _msg )                        ((void)0)
  324. #define  AssertFunc( _exp, _f )                             ((void)0)
  325. #define  AssertEquals( _exp, _expectedValue )               ((void)0)
  326. #define  AssertFloatEquals( _exp, _expectedValue, _tol )    ((void)0)
  327. #define  Verify( _exp )                                     (_exp)
  328. #define  VerifyEquals( _exp, _expectedValue )               (_exp)
  329.  
  330. #define  AssertMsg1( _exp, _msg, a1 )                                   ((void)0)
  331. #define  AssertMsg2( _exp, _msg, a1, a2 )                               ((void)0)
  332. #define  AssertMsg3( _exp, _msg, a1, a2, a3 )                           ((void)0)
  333. #define  AssertMsg4( _exp, _msg, a1, a2, a3, a4 )                       ((void)0)
  334. #define  AssertMsg5( _exp, _msg, a1, a2, a3, a4, a5 )                   ((void)0)
  335. #define  AssertMsg6( _exp, _msg, a1, a2, a3, a4, a5, a6 )               ((void)0)
  336. #define  AssertMsg6( _exp, _msg, a1, a2, a3, a4, a5, a6 )               ((void)0)
  337. #define  AssertMsg7( _exp, _msg, a1, a2, a3, a4, a5, a6, a7 )           ((void)0)
  338. #define  AssertMsg8( _exp, _msg, a1, a2, a3, a4, a5, a6, a7, a8 )       ((void)0)
  339. #define  AssertMsg9( _exp, _msg, a1, a2, a3, a4, a5, a6, a7, a8, a9 )   ((void)0)
  340.  
  341. #endif // DBGFLAG_ASSERT
  342.  
  343.  
  344. #if !defined( _X360 ) || !defined( _RETAIL )
  345.  
  346. /* These are always compiled in */
  347. DBG_INTERFACE void Msg( const tchar* pMsg, ... );
  348. DBG_INTERFACE void DMsg( const tchar *pGroupName, int level, const tchar *pMsg, ... );
  349.  
  350. DBG_INTERFACE void Warning( const tchar *pMsg, ... );
  351. DBG_INTERFACE void DWarning( const tchar *pGroupName, int level, const tchar *pMsg, ... );
  352.  
  353. DBG_INTERFACE void Log( const tchar *pMsg, ... );
  354. DBG_INTERFACE void DLog( const tchar *pGroupName, int level, const tchar *pMsg, ... );
  355.  
  356. DBG_INTERFACE void Error( const tchar *pMsg, ... );
  357.  
  358. #else
  359.  
  360. inline void Msg( ... ) {}
  361. inline void DMsg( ... ) {}
  362. inline void Warning( const tchar *pMsg, ... ) {}
  363. inline void DWarning( ... ) {}
  364. inline void Log( ... ) {}
  365. inline void DLog( ... ) {}
  366. inline void Error( ... ) {}
  367.  
  368. #endif
  369.  
  370. // You can use this macro like a runtime assert macro.
  371. // If the condition fails, then Error is called with the message. This macro is called
  372. // like AssertMsg, where msg must be enclosed in parenthesis:
  373. //
  374. // ErrorIfNot( bCondition, ("a b c %d %d %d", 1, 2, 3) );
  375. #define ErrorIfNot( condition, msg ) \
  376.     if ( (condition) )      \
  377.         ;                   \
  378.     else                    \
  379.     {                       \
  380.         Error msg;          \
  381.     }
  382.  
  383. #if !defined( _X360 ) || !defined( _RETAIL )
  384.  
  385. /* A couple of super-common dynamic spew messages, here for convenience */
  386. /* These looked at the "developer" group */
  387. DBG_INTERFACE void DevMsg( int level, const tchar* pMsg, ... );
  388. DBG_INTERFACE void DevWarning( int level, const tchar *pMsg, ... );
  389. DBG_INTERFACE void DevLog( int level, const tchar *pMsg, ... );
  390.  
  391. /* default level versions (level 1) */
  392. DBG_OVERLOAD void DevMsg( const tchar* pMsg, ... );
  393. DBG_OVERLOAD void DevWarning( const tchar *pMsg, ... );
  394. DBG_OVERLOAD void DevLog( const tchar *pMsg, ... );
  395.  
  396. /* These looked at the "console" group */
  397. DBG_INTERFACE void ConColorMsg( int level, const Color& clr, const tchar* pMsg, ... );
  398. DBG_INTERFACE void ConMsg( int level, const tchar* pMsg, ... );
  399. DBG_INTERFACE void ConWarning( int level, const tchar *pMsg, ... );
  400. DBG_INTERFACE void ConLog( int level, const tchar *pMsg, ... );
  401.  
  402. /* default console version (level 1) */
  403. DBG_OVERLOAD void ConColorMsg( const Color& clr, const tchar* pMsg, ... );
  404. DBG_OVERLOAD void ConMsg( const tchar* pMsg, ... );
  405. DBG_OVERLOAD void ConWarning( const tchar *pMsg, ... );
  406. DBG_OVERLOAD void ConLog( const tchar *pMsg, ... );
  407.  
  408. /* developer console version (level 2) */
  409. DBG_INTERFACE void ConDColorMsg( const Color& clr, const tchar* pMsg, ... );
  410. DBG_INTERFACE void ConDMsg( const tchar* pMsg, ... );
  411. DBG_INTERFACE void ConDWarning( const tchar *pMsg, ... );
  412. DBG_INTERFACE void ConDLog( const tchar *pMsg, ... );
  413.  
  414. /* These looked at the "network" group */
  415. DBG_INTERFACE void NetMsg( int level, const tchar* pMsg, ... );
  416. DBG_INTERFACE void NetWarning( int level, const tchar *pMsg, ... );
  417. DBG_INTERFACE void NetLog( int level, const tchar *pMsg, ... );
  418.  
  419. void ValidateSpew( class CValidator &validator );
  420.  
  421. #else
  422.  
  423. inline void DevMsg( ... ) {}
  424. inline void DevWarning( ... ) {}
  425. inline void DevLog( ... ) {}
  426. inline void ConMsg( ... ) {}
  427. inline void ConLog( ... ) {}
  428. inline void NetMsg( ... ) {}
  429. inline void NetWarning( ... ) {}
  430. inline void NetLog( ... ) {}
  431.  
  432. #endif
  433.  
  434. DBG_INTERFACE void COM_TimestampedLog( char const *fmt, ... );
  435.  
  436. /* Code macros, debugger interface */
  437.  
  438. #ifdef _DEBUG
  439.  
  440. #define DBG_CODE( _code )            if (0) ; else { _code }
  441. #define DBG_CODE_NOSCOPE( _code )    _code
  442. #define DBG_DCODE( _g, _l, _code )   if (IsSpewActive( _g, _l )) { _code } else {}
  443. #define DBG_BREAK()                  DebuggerBreak()    /* defined in platform.h */
  444.  
  445. #else /* not _DEBUG */
  446.  
  447. #define DBG_CODE( _code )            ((void)0)
  448. #define DBG_CODE_NOSCOPE( _code )    
  449. #define DBG_DCODE( _g, _l, _code )   ((void)0)
  450. #define DBG_BREAK()                  ((void)0)
  451.  
  452. #endif /* _DEBUG */
  453.  
  454. //-----------------------------------------------------------------------------
  455.  
  456. #ifndef _RETAIL
  457. class CScopeMsg
  458. {
  459. public:
  460.     CScopeMsg( const char *pszScope )
  461.     {
  462.         m_pszScope = pszScope;
  463.         Msg( "%s { ", pszScope );
  464.     }
  465.     ~CScopeMsg()
  466.     {
  467.         Msg( "} %s", m_pszScope );
  468.     }
  469.     const char *m_pszScope;
  470. };
  471. #define SCOPE_MSG( msg ) CScopeMsg scopeMsg( msg )
  472. #else
  473. #define SCOPE_MSG( msg )
  474. #endif
  475.  
  476.  
  477. //-----------------------------------------------------------------------------
  478. // Macro to assist in asserting constant invariants during compilation
  479.  
  480. #ifdef _DEBUG
  481. #define COMPILE_TIME_ASSERT( pred ) switch(0){case 0:case pred:;}
  482. #define ASSERT_INVARIANT( pred )    static void UNIQUE_ID() { COMPILE_TIME_ASSERT( pred ) }
  483. #else
  484. #define COMPILE_TIME_ASSERT( pred )
  485. #define ASSERT_INVARIANT( pred )
  486. #endif
  487.  
  488. #ifdef _DEBUG
  489. template<typename DEST_POINTER_TYPE, typename SOURCE_POINTER_TYPE>
  490. inline DEST_POINTER_TYPE assert_cast(SOURCE_POINTER_TYPE* pSource)
  491. {
  492.     Assert( static_cast<DEST_POINTER_TYPE>(pSource) == dynamic_cast<DEST_POINTER_TYPE>(pSource) );
  493.     return static_cast<DEST_POINTER_TYPE>(pSource);
  494. }
  495. #else
  496. #define assert_cast static_cast
  497. #endif
  498.  
  499. //-----------------------------------------------------------------------------
  500. // Templates to assist in validating pointers:
  501.  
  502. // Have to use these stubs so we don't have to include windows.h here.
  503. DBG_INTERFACE void _AssertValidReadPtr( void* ptr, int count = 1 );
  504. DBG_INTERFACE void _AssertValidWritePtr( void* ptr, int count = 1 );
  505. DBG_INTERFACE void _AssertValidReadWritePtr( void* ptr, int count = 1 );
  506.  
  507. DBG_INTERFACE  void AssertValidStringPtr( const tchar* ptr, int maxchar = 0xFFFFFF );
  508. template<class T> inline void AssertValidReadPtr( T* ptr, int count = 1 )            { _AssertValidReadPtr( (void*)ptr, count ); }
  509. template<class T> inline void AssertValidWritePtr( T* ptr, int count = 1 )           { _AssertValidWritePtr( (void*)ptr, count ); }
  510. template<class T> inline void AssertValidReadWritePtr( T* ptr, int count = 1 )       { _AssertValidReadWritePtr( (void*)ptr, count ); }
  511.  
  512. #define AssertValidThis() AssertValidReadWritePtr(this,sizeof(*this))
  513.  
  514. //-----------------------------------------------------------------------------
  515. // Macro to protect functions that are not reentrant
  516.  
  517. #ifdef _DEBUG
  518. class CReentryGuard
  519. {
  520. public:
  521.     CReentryGuard(int *pSemaphore)
  522.      : m_pSemaphore(pSemaphore)
  523.     {
  524.         ++(*m_pSemaphore);
  525.     }
  526.    
  527.     ~CReentryGuard()
  528.     {
  529.         --(*m_pSemaphore);
  530.     }
  531.    
  532. private:
  533.     int *m_pSemaphore;
  534. };
  535.  
  536. #define ASSERT_NO_REENTRY() \
  537.     static int fSemaphore##__LINE__; \
  538.     Assert( !fSemaphore##__LINE__ ); \
  539.     CReentryGuard ReentryGuard##__LINE__( &fSemaphore##__LINE__ )
  540. #else
  541. #define ASSERT_NO_REENTRY()
  542. #endif
  543.  
  544. //-----------------------------------------------------------------------------
  545. //
  546. // Purpose: Inline string formatter
  547. //
  548.  
  549. #include "tier0/valve_off.h"
  550. class CDbgFmtMsg
  551. {
  552. public:
  553.     CDbgFmtMsg(const tchar *pszFormat, ...)    
  554.     {
  555.         va_list arg_ptr;
  556.  
  557.         va_start(arg_ptr, pszFormat);
  558.         _vsntprintf(m_szBuf, sizeof(m_szBuf)-1, pszFormat, arg_ptr);
  559.         va_end(arg_ptr);
  560.  
  561.         m_szBuf[sizeof(m_szBuf)-1] = 0;
  562.     }
  563.  
  564.     operator const tchar *() const             
  565.     {
  566.         return m_szBuf;
  567.     }
  568.  
  569. private:
  570.     tchar m_szBuf[256];
  571. };
  572. #include "tier0/valve_on.h"
  573.  
  574. //-----------------------------------------------------------------------------
  575. //
  576. // Purpose: Embed debug info in each file.
  577. //
  578. #if defined( _WIN32 ) && !defined( _X360 )
  579.  
  580.     #ifdef _DEBUG
  581.         #pragma comment(compiler)
  582.     #endif
  583.  
  584. #endif
  585.  
  586. //-----------------------------------------------------------------------------
  587. //
  588. // Purpose: Wrap around a variable to create a simple place to put a breakpoint
  589. //
  590.  
  591. #ifdef _DEBUG
  592.  
  593. template< class Type >
  594. class CDataWatcher
  595. {
  596. public:
  597.     const Type& operator=( const Type &val )
  598.     {
  599.         return Set( val );
  600.     }
  601.    
  602.     const Type& operator=( const CDataWatcher<Type> &val )
  603.     {
  604.         return Set( val.m_Value );
  605.     }
  606.    
  607.     const Type& Set( const Type &val )
  608.     {
  609.         // Put your breakpoint here
  610.         m_Value = val;
  611.         return m_Value;
  612.     }
  613.    
  614.     Type& GetForModify()
  615.     {
  616.         return m_Value;
  617.     }
  618.    
  619.     const Type& operator+=( const Type &val )
  620.     {
  621.         return Set( m_Value + val );
  622.     }
  623.    
  624.     const Type& operator-=( const Type &val )
  625.     {
  626.         return Set( m_Value - val );
  627.     }
  628.    
  629.     const Type& operator/=( const Type &val )
  630.     {
  631.         return Set( m_Value / val );
  632.     }
  633.    
  634.     const Type& operator*=( const Type &val )
  635.     {
  636.         return Set( m_Value * val );
  637.     }
  638.    
  639.     const Type& operator^=( const Type &val )
  640.     {
  641.         return Set( m_Value ^ val );
  642.     }
  643.    
  644.     const Type& operator|=( const Type &val )
  645.     {
  646.         return Set( m_Value | val );
  647.     }
  648.    
  649.     const Type& operator++()
  650.     {
  651.         return (*this += 1);
  652.     }
  653.    
  654.     Type operator--()
  655.     {
  656.         return (*this -= 1);
  657.     }
  658.    
  659.     Type operator++( int ) // postfix version..
  660.     {
  661.         Type val = m_Value;
  662.         (*this += 1);
  663.         return val;
  664.     }
  665.    
  666.     Type operator--( int ) // postfix version..
  667.     {
  668.         Type val = m_Value;
  669.         (*this -= 1);
  670.         return val;
  671.     }
  672.    
  673.     // For some reason the compiler only generates type conversion warnings for this operator when used like
  674.     // CNetworkVarBase<unsigned tchar> = 0x1
  675.     // (it warns about converting from an int to an unsigned char).
  676.     template< class C >
  677.     const Type& operator&=( C val )
  678.     {
  679.         return Set( m_Value & val );
  680.     }
  681.    
  682.     operator const Type&() const
  683.     {
  684.         return m_Value;
  685.     }
  686.    
  687.     const Type& Get() const
  688.     {
  689.         return m_Value;
  690.     }
  691.    
  692.     const Type* operator->() const
  693.     {
  694.         return &m_Value;
  695.     }
  696.    
  697.     Type m_Value;
  698.    
  699. };
  700.  
  701. #else
  702.  
  703. template< class Type >
  704. class CDataWatcher
  705. {
  706. private:
  707.     CDataWatcher(); // refuse to compile in non-debug builds
  708. };
  709.  
  710. #endif
  711.  
  712. //-----------------------------------------------------------------------------
  713.  
  714. #endif /* DBG_H */
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement