home *** CD-ROM | disk | FTP | other *** search
/ The Net: Ultimate Internet Guide / WWLCD1.ISO / mac / SiteBldr / AMOVIE / SDK / _SETUP / COMMON.Z / wxdebug.h < prev    next >
Encoding:
C/C++ Source or Header  |  1996-04-01  |  10.9 KB  |  328 lines

  1. //==========================================================================;
  2. //
  3. //  THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY
  4. //  KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
  5. //  IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR
  6. //  PURPOSE.
  7. //
  8. //  Copyright (c) 1992 - 1996  Microsoft Corporation.  All Rights Reserved.
  9. //
  10. //--------------------------------------------------------------------------;
  11.  
  12. // Debugging facilities, January 1995
  13.  
  14. #ifndef __WXDEBUG__
  15. #define __WXDEBUG__
  16.  
  17. // Avoid conflict with MFC
  18. #undef ASSERT
  19.  
  20. // This library provides fairly straight forward debugging functionality, this
  21. // is split into two main sections. The first is assertion handling, there are
  22. // three types of assertions provided here. The most commonly used one is the
  23. // ASSERT(condition) macro which will pop up a message box including the file
  24. // and line number if the condition evaluates to FALSE. Then there is the
  25. // EXECUTE_ASSERT macro which is the same as ASSERT except the condition will
  26. // still be executed in NON debug builds. The final type of assertion is the
  27. // KASSERT macro which is more suitable for pure (perhaps kernel) filters as
  28. // the condition is printed onto the debugger rather than in a message box.
  29. //
  30. // The other part of the debug module facilties is general purpose logging.
  31. // This is accessed by calling DbgLog(). The function takes a type and level
  32. // field which define the type of informational string you are presenting and
  33. // it's relative importance. The type field can be a combination (one or more)
  34. // of LOG_TIMING, LOG_TRACE, LOG_MEMORY, LOG_LOCKING and LOG_ERROR. The level
  35. // is a DWORD value where zero defines highest important. Use of zero as the
  36. // debug logging level is to be encouraged ONLY for major errors or events as
  37. // they will ALWAYS be displayed on the debugger. Other debug output has it's
  38. // level matched against the current debug output level stored in the registry
  39. // for this module and if less than the current setting it will be displayed.
  40. //
  41. // Each module or executable has it's own debug output level for each of the
  42. // five types. These are read in when the DbgInitialise function is called
  43. // for DLLs linking to STRMBASE.LIB this is done automatically when the DLL
  44. // is loaded, executables must call it explicitely with the module instance
  45. // handle given to them through the WINMAIN entry point. An executable must
  46. // also call DbgTerminate when they have finished to clean up the resources
  47. // the debug library uses, once again this is done automatically for DLLs
  48.  
  49. // These are the five different categories of logging information
  50.  
  51. enum {  LOG_TIMING = 0x01,    // Timing and performance measurements
  52.         LOG_TRACE = 0x02,     // General step point call tracing
  53.         LOG_MEMORY =  0x04,   // Memory and object allocation/destruction
  54.         LOG_LOCKING = 0x08,   // Locking/unlocking of critical sections
  55.         LOG_ERROR = 0x10 };   // Debug error notification
  56.  
  57. enum {  CDISP_HEX = 0x01,
  58.         CDISP_DEC = 0x02};
  59.  
  60. // For each object created derived from CBaseObject (in debug builds) we
  61. // create a descriptor that holds it's name (statically allocated memory)
  62. // and a cookie we assign it. We keep a list of all the active objects
  63. // we have registered so that we can dump a list of remaining objects
  64.  
  65. typedef struct tag_ObjectDesc {
  66.     TCHAR *m_pName;
  67.     DWORD m_dwCookie;
  68.     tag_ObjectDesc *m_pNext;
  69. } ObjectDesc;
  70.  
  71. #define DLLIMPORT __declspec(dllimport)
  72. #define DLLEXPORT __declspec(dllexport)
  73.  
  74. #ifdef DEBUG
  75.  
  76.     #define NAME(x) TEXT(x)
  77.  
  78.     // These are used internally by the debug library (PRIVATE)
  79.  
  80.     void DbgInitKeyLevels(HKEY hKey);
  81.     void DbgInitGlobalSettings();
  82.     void DbgInitModuleSettings();
  83.     void DbgInitModuleName();
  84.     DWORD DbgRegisterObjectCreation(TCHAR *pObjectName);
  85.     BOOL DbgRegisterObjectDestruction(DWORD dwCookie);
  86.  
  87.     // These are the PUBLIC entry points
  88.  
  89.     BOOL DbgCheckModuleLevel(DWORD Type,DWORD Level);
  90.     void DbgSetModuleLevel(DWORD Type,DWORD Level);
  91.  
  92.     // Initialise the library with the module handle
  93.  
  94.     void DbgInitialise(HINSTANCE hInst);
  95.     void DbgTerminate();
  96.  
  97.     void DbgDumpObjectRegister();
  98.  
  99.     // Display error and logging to the user
  100.  
  101.     void DbgAssert(const TCHAR *pCondition,const TCHAR *pFileName,INT iLine);
  102.     void DbgBreakPoint(const TCHAR *pCondition,const TCHAR *pFileName,INT iLine);
  103.     void DbgKernelAssert(const TCHAR *pCondition,const TCHAR *pFileName,INT iLine);
  104.     void DbgLogInfo(DWORD Type,DWORD Level,const TCHAR *pFormat,...);
  105.     void DbgOutString(LPCTSTR psz);
  106.  
  107.     //  Debug infinite wait stuff
  108.     DWORD DbgWaitForSingleObject(HANDLE h);
  109.     DWORD DbgWaitForMultipleObjects(DWORD nCount,
  110.                                     CONST HANDLE *lpHandles,
  111.                                     BOOL bWaitAll);
  112.     void DbgSetWaitTimeout(DWORD dwTimeout);
  113.  
  114. #ifdef __strmif_h__
  115.     void DisplayType(LPSTR label, const AM_MEDIA_TYPE *pmtIn);
  116. #endif
  117.  
  118.     #define KASSERT(_x_) if (!(_x_))         \
  119.         DbgKernelAssert(TEXT(#_x_),TEXT(__FILE__),__LINE__)
  120.  
  121.     //  Break on the debugger without putting up a message box
  122.     //  message goes to debugger instead
  123.  
  124.     #define KDbgBreak(_x_)                   \
  125.         DbgKernelAssert(TEXT(#_x_),TEXT(__FILE__),__LINE__)
  126.  
  127.     #define ASSERT(_x_) if (!(_x_))         \
  128.         DbgAssert(TEXT(#_x_),TEXT(__FILE__),__LINE__)
  129.  
  130.     //  Put up a message box informing the user of a halt
  131.     //  condition in the program
  132.  
  133.     #define DbgBreak(_x_)                   \
  134.         DbgBreakPoint(TEXT(#_x_),TEXT(__FILE__),__LINE__)
  135.  
  136.     #define EXECUTE_ASSERT(_x_) ASSERT(_x_)
  137.     #define DbgLog(_x_) DbgLogInfo _x_
  138.  
  139.     // MFC style trace macros
  140.  
  141.     #define NOTE(_x_)             DbgLog((LOG_TRACE,5,TEXT(_x_)));
  142.     #define NOTE1(_x_,a)          DbgLog((LOG_TRACE,5,TEXT(_x_),a));
  143.     #define NOTE2(_x_,a,b)        DbgLog((LOG_TRACE,5,TEXT(_x_),a,b));
  144.     #define NOTE3(_x_,a,b,c)      DbgLog((LOG_TRACE,5,TEXT(_x_),a,b,c));
  145.     #define NOTE4(_x_,a,b,c,d)    DbgLog((LOG_TRACE,5,TEXT(_x_),a,b,c,d));
  146.     #define NOTE5(_x_,a,b,c,d,e)  DbgLog((LOG_TRACE,5,TEXT(_x_),a,b,c,d,e));
  147.  
  148. #else
  149.  
  150.     // Retail builds make public debug functions inert  - WARNING the source
  151.     // files do not define or build any of the entry points in debug builds
  152.     // (public entry points compile to nothing) so if you go trying to call
  153.     // any of the private entry points in your source they won't compile
  154.  
  155.     #define NAME(_x_) NULL
  156.  
  157.     #define DbgInitialise(hInst)
  158.     #define DbgTerminate()
  159.     #define DbgLog(_x_)
  160.     #define DbgOutString(psz)
  161.  
  162.     #define DbgRegisterObjectCreation(pObjectName)
  163.     #define DbgRegisterObjectDestruction(dwCookie)
  164.     #define DbgDumpObjectRegister()
  165.  
  166.     #define DbgCheckModuleLevel(Type,Level)
  167.     #define DbgSetModuleLevel(Type,Level)
  168.  
  169.     #define DbgWaitForSingleObject(h)  WaitForSingleObject(h, INFINITE)
  170.     #define DbgWaitForMultipleObjects(nCount, lpHandles, bWaitAll)     \
  171.                WaitForMultipleObjects(nCount, lpHandles, bWaitAll, INFINITE)
  172.     #define DbgSetWaitTimeout(dwTimeout)
  173.  
  174.     #define KDbgBreak(_x_)
  175.     #define DbgBreak(_x_)
  176.  
  177.     #define KASSERT(_x_)
  178.     #define ASSERT(_x_)
  179.     #define EXECUTE_ASSERT(_x_) _x_
  180.  
  181.     // MFC style trace macros
  182.  
  183.     #define NOTE(_x_)
  184.     #define NOTE1(_x_,a)
  185.     #define NOTE2(_x_,a,b)
  186.     #define NOTE3(_x_,a,b,c)
  187.     #define NOTE4(_x_,a,b,c,d)
  188.     #define NOTE5(_x_,a,b,c,d,e)
  189.  
  190.     #define DisplayType(label, pmtIn)
  191.  
  192. #endif
  193.  
  194.  
  195. // Checks a pointer which should be non NULL - can be used as follows.
  196.  
  197. #define CheckPointer(p,ret) {if((p)==NULL) return (ret);}
  198.  
  199. //   HRESULT Foo(VOID *pBar)
  200. //   {
  201. //       CheckPointer(pBar,E_INVALIDARG)
  202. //   }
  203. //
  204. //   Or if the function returns a boolean
  205. //
  206. //   BOOL Foo(VOID *pBar)
  207. //   {
  208. //       CheckPointer(pBar,FALSE)
  209. //   }
  210.  
  211. // These validate pointers when symbol VFWROBUST is defined
  212. // This will normally be defined in debug not retail builds
  213.  
  214. #ifdef DEBUG
  215.     #define VFWROBUST
  216. #endif
  217.  
  218. #ifdef VFWROBUST
  219.  
  220.     #define ValidateReadPtr(p,cb) \
  221.         {if(IsBadReadPtr((PVOID)p,cb) == TRUE) \
  222.             DbgBreak("Invalid read pointer");}
  223.  
  224.     #define ValidateWritePtr(p,cb) \
  225.         {if(IsBadWritePtr((PVOID)p,cb) == TRUE) \
  226.             DbgBreak("Invalid write pointer");}
  227.  
  228.     #define ValidateReadWritePtr(p,cb) \
  229.         {ValidateReadPtr(p,cb) ValidateWritePtr(p,cb)}
  230.  
  231.     #define ValidateStringPtr(p) \
  232.         {if(IsBadStringPtr((LPCTSTR)p,INFINITE) == TRUE) \
  233.             DbgBreak("Invalid string pointer");}
  234.  
  235.     #define ValidateStringPtrA(p) \
  236.         {if(IsBadStringPtrA((LPCSTR)p,INFINITE) == TRUE) \
  237.             DbgBreak("Invalid ANSII string pointer");}
  238.  
  239.     #define ValidateStringPtrW(p) \
  240.         {if(IsBadStringPtrW((LPCWSTR)p,INFINITE) == TRUE) \
  241.             DbgBreak("Invalid UNICODE string pointer");}
  242.  
  243. #else
  244.     #define ValidateReadPtr(p,cb)
  245.     #define ValidateWritePtr(p,cb)
  246.     #define ValidateReadWritePtr(p,cb)
  247.     #define ValidateStringPtr(p)
  248.     #define ValidateStringPtrA(p)
  249.     #define ValidateStringPtrW(p)
  250. #endif
  251.  
  252.  
  253. #ifdef _OBJBASE_H_
  254.  
  255.     //  Outputting GUID names.  If you want to include the name
  256.     //  associated with a GUID (eg CLSID_...) then
  257.     //
  258.     //      GuidNames[yourGUID]
  259.     //
  260.     //  Returns the name defined in uuids.h as a string
  261.  
  262.     typedef struct {
  263.         TCHAR   *szName;
  264.         GUID    guid;
  265.     } GUID_STRING_ENTRY;
  266.  
  267.     class CGuidNameList {
  268.     public:
  269.         TCHAR *operator [] (const GUID& guid);
  270.     };
  271.  
  272.     extern CGuidNameList GuidNames;
  273.  
  274. #endif
  275.  
  276.  
  277. //  REMIND macro - generates warning as reminder to complete coding
  278. //  (eg) usage:
  279. //
  280. //  #pragma message (REMIND("Add automation support"))
  281.  
  282.  
  283. #define QUOTE(x) #x
  284. #define QQUOTE(y) QUOTE(y)
  285. #define REMIND(str) __FILE__ "(" QQUOTE(__LINE__) ") :  " str
  286.  
  287.  
  288. //  Hack to display objects in a useful format
  289. //
  290. //  eg If you want to display a LONGLONG ll in a debug string do (eg)
  291. //
  292. //  DbgLog((LOG_TRACE, n, TEXT("Value is %s"), (LPCTSTR)CDisp(ll, CDISP_HEX)));
  293.  
  294.  
  295. class CDispBasic
  296. {
  297. public:
  298.     CDispBasic() { m_pString = m_String; };
  299.     ~CDispBasic();
  300. protected:
  301.     PTCHAR m_pString;  // normally points to m_String... unless too much data
  302.     TCHAR m_String[50];
  303. };
  304. class CDisp : public CDispBasic
  305. {
  306. public:
  307.     CDisp(LONGLONG ll, int Format = CDISP_HEX); // Display a LONGLONG in CDISP_HEX or CDISP_DEC form
  308.     CDisp(REFCLSID clsid);      // Display a GUID
  309.     CDisp(double d);            // Display a floating point number
  310. #ifdef __strmif_h__
  311. #ifdef __STREAMS__
  312.     CDisp(CRefTime t);          // Display a Reference Time
  313. #endif
  314.     CDisp(IPin *pPin);          // Display a pin as {filter clsid}(pin name)
  315. #endif // __strmif_h__
  316.     ~CDisp();
  317.  
  318.     //  Implement cast to (LPCTSTR) as parameter to logger
  319.     operator LPCTSTR()
  320.     {
  321.         return (LPCTSTR)m_pString;
  322.     };
  323. };
  324.  
  325. #endif // __WXDEBUG__
  326.  
  327.  
  328.