|
|
1.1 root 1: /*
2: * DEBUG code - Contains declarations and macros for include debug support;
3: * Contains null definitions when !_DEBUG
4: */
5:
6: #ifndef _DEBUG_H_
7: #define _DEBUG_H_
8:
9: #ifndef RC_INVOKED
10: #ifdef _DEBUG
11: #define DBGSTATE " Debug is on"
12: #else
13: #define DBGSTATE " Debug is off"
14: #endif
15: #pragma message ("INCLUDING DEBUG.H from " __FILE__ DBGSTATE)
16: #endif /* RC_INVOKED */
17:
18:
19:
20: STDAPI_(void) DumpObject( IUnknown FAR * pUnk );
21: STDAPI_(BOOL) IsObjectValid( IUnknown FAR * pUnk );
22: STDAPI_(void) DumpAllObjects( void );
23: STDAPI_(BOOL) ValidateAllObjects( BOOL fSuspicious );
24: STDAPI_(void) DumpClassName( IUnknown FAR * pUnk );
25:
26:
27: #ifdef _DEBUG
28:
29: BOOL WINAPI InstallHooks(void);
30: BOOL WINAPI UnInstallHooks(void);
31:
32: #undef ASSERTDATA
33: #ifdef _MAC
34: #ifdef __cplusplus
35: extern "C" {
36: #endif
37: void OutputDebugString(const char *);
38: #ifdef __cplusplus
39: }
40: #endif
41:
42: #define ASSERTDATA static char _szAssertFile[]= __FILE__;
43: #else
44: #ifdef WIN32
45: #define ASSERTDATA static char _szAssertFile[]= __FILE__;
46: #else
47: #define ASSERTDATA static char _based(_segname("_CODE")) _szAssertFile[]= __FILE__;
48: #endif
49: #endif
50: #undef Assert
51: // MAC compiler barfs on '(void)0'.
52: #ifdef _MAC
53: #define Assert(a) { if (!(a)) FnAssert(#a, NULL, _szAssertFile, __LINE__); }
54: #undef AssertSz
55: #define AssertSz(a, b) { if (!(a)) FnAssert(#a, b, _szAssertFile, __LINE__); }
56: #else
57: #define Assert(a) ((a) ? NOERROR : FnAssert(#a, NULL, _szAssertFile, __LINE__))
58: #undef AssertSz
59: #define AssertSz(a,b) ((a) ? NOERROR : FnAssert(#a, b, _szAssertFile, __LINE__))
60: #endif
61: #undef Verify
62: #define Verify(a) Assert(a)
63: #undef Puts
64: #define Puts(s) OutputDebugString(s)
65:
66: #define ASSERT(cond, msg)
67:
68: #else // !_DEBUG
69:
70: #define ASSERTDATA
71: #define Assert(a) ((void)0)
72: #define AssertSz(a, b) ((void)0)
73: #define Verify(a) (a)
74: #define ASSERT(cond, msg)
75: #define Puts(s) ((void)0)
76:
77: #endif // _DEBUG
78:
79: #ifdef __cplusplus
80:
81: interface IDebugStream;
82:
83: /*
84: * Class CBool wraps boolean values in such a way that they are
85: * readily distinguishable fron integers by the compiler so we can
86: * overload the stream << operator.
87: */
88:
89: class CBool
90: {
91: BOOL value;
92: public:
93: CBool (BOOL& b) {value = b;}
94: operator BOOL( void ) { return value; }
95: };
96:
97:
98:
99: /*
100: * IDebugStream is a stream to be used for debug output. One
101: * implementation uses the OutputDebugString function of Windows.
102: *
103: * The style is modeled on that of AT&T streams, and so uses
104: * overloaded operators. You can write to a stream in the
105: * following ways:
106: *
107: * *pdbstm << pUnk; // calls the IDebug::Dump function to
108: * display the object, if IDebug is supported.
109: * int n;
110: * *pdbstm << n; // writes n in decimal
111: *
112: * LPSTR sz;
113: * *pdbstm << sz; // writes a string
114: *
115: * CBool b(TRUE);
116: * *pdbstm << b; // writes True or False
117: *
118: * void FAR * pv;
119: * *pdbstm << pv; // writes the address pv in hex
120: *
121: * char ch;
122: * *pdbstm << ch; // writes the character
123: *
124: * These can be chained together, as such (somewhat artificial
125: * example):
126: *
127: * REFCLSID rclsid;
128: * pUnk->GetClass(&rclsid);
129: * *pdbstm << rclsid << " at " << (void FAR *)pUnk <<':' << pUnk;
130: *
131: * This produces something like:
132: *
133: * CFoo at A7360008: <description of object>
134: *
135: * The other useful feature is the Indent and UnIndent functions
136: * which allow an object to print some information, indent, print
137: * the info on its member objects, and unindent. This gives
138: * nicely formatted output.
139: *
140: * WARNING: do not (while implementing Dump) write
141: *
142: * *pdbstm << pUnkOuter
143: *
144: * since this will do a QueryInterface for IDebug, and start
145: * recursing! It is acceptable to write
146: *
147: * *pdbstm << (VOID FAR *)pUnkOuter
148: *
149: * as this will simply write the address of pUnkOuter.
150: *
151: */
152:
153:
154: interface IDebugStream : public IUnknown
155: {
156: STDMETHOD_(IDebugStream&, operator << ) ( IUnknown FAR * pDebug ) = 0;
157: STDMETHOD_(IDebugStream&, operator << ) ( REFCLSID rclsid ) = 0;
158: STDMETHOD_(IDebugStream&, operator << ) ( int n ) = 0;
159: STDMETHOD_(IDebugStream&, operator << ) ( long l ) = 0;
160: STDMETHOD_(IDebugStream&, operator << ) ( LPSTR sz ) = 0;
161: STDMETHOD_(IDebugStream&, operator << ) ( char ch ) = 0;
162: STDMETHOD_(IDebugStream&, operator << ) ( void FAR * pv ) = 0;
163: STDMETHOD_(IDebugStream&, operator << ) ( CBool b ) = 0;
164: STDMETHOD_(IDebugStream&, Tab )( void ) = 0;
165: STDMETHOD_(IDebugStream&, Indent )( void ) = 0;
166: STDMETHOD_(IDebugStream&, UnIndent )( void ) = 0;
167: STDMETHOD_(IDebugStream&, Return )( void ) = 0;
168: STDMETHOD_(IDebugStream&, LF )( void ) = 0;
169: };
170:
171: STDAPI_(IDebugStream FAR *) MakeDebugStream(short margin=70, short tabsize=4);
172:
173:
174: interface IDebug
175: {
176: STDMETHOD_(void, Dump )( IDebugStream FAR * pdbstm ) = 0;
177: STDMETHOD_(BOOL, IsValid )( BOOL fSuspicious = FALSE ) = 0;
178:
179: EXPORT IDebug(void);
180: EXPORT ~IDebug(void);
181:
182: private:
183:
184: #if _DEBUG
185: IDebug FAR * pIDPrev;
186: IDebug FAR * pIDNext;
187:
188: friend void STDAPICALLTYPE DumpAllObjects( void );
189: friend BOOL STDAPICALLTYPE ValidateAllObjects( BOOL fSuspicious );
190: #endif
191: };
192:
193: STDAPI_(void) DebugUninit(void);
194:
195: #ifdef _MAC
196: typedef short HFILE;
197: #endif
198:
199:
200: /*************************************************************************
201: ** The following functions can be used to log debug messages to a file
202: ** and simutaneously write them to the dbwin debug window.
203: ** The CDebugStream implementation automatically writes to a debug
204: ** log file called "debug.log" in the current working directory.
205: ** NOTE: The functions are only intended for C programmers. C++
206: ** programmers should use the "MakeDebugStream" instead.
207: *************************************************************************/
208:
209: // Open a log file.
210: STDAPI_(HFILE) DbgLogOpen(LPSTR lpszFile, LPSTR lpszMode);
211:
212: // Close the log file.
213: STDAPI_(void) DbgLogClose(HFILE fh);
214:
215: // Write to debug log and debug window (used with cvw.exe or dbwin.exe).
216: STDAPI_(void) DbgLogOutputDebugString(HFILE fh, LPSTR lpsz);
217:
218: // Write to debug log only.
219: STDAPI_(void) DbgLogWrite(HFILE fh, LPSTR lpsz);
220:
221: // Write the current Date and Time to the log file.
222: STDAPI_(void) DbgLogTimeStamp(HFILE fh, LPSTR lpsz);
223:
224: // Write a banner separater to the log to separate sections.
225: STDAPI_(void) DbgLogWriteBanner(HFILE fh, LPSTR lpsz);
226:
227:
228:
229:
230: /*
231: * STDDEBDECL macro - helper for debug declaration
232: *
233: */
234:
235: #ifdef _DEBUG
236:
237: #ifdef _MAC
238:
239: //#define STDDEBDECL(cclassname,classname)
240:
241: //#if 0
242: #define STDDEBDECL(cclassname,classname) NESTED_CLASS(cclassname, CDebug):IDebug { public: \
243: NC1(cclassname,CDebug)( cclassname FAR * p##classname ) { m_p##classname = p##classname;} \
244: ~##NC1(cclassname,CDebug)(void){} \
245: STDMETHOD_(void, Dump)(THIS_ IDebugStream FAR * pdbstm ); \
246: STDMETHOD_(BOOL, IsValid)(THIS_ BOOL fSuspicious ); \
247: private: cclassname FAR* m_p##classname; }; \
248: DECLARE_NC2(cclassname, CDebug) \
249: NC(cclassname, CDebug) m_Debug;
250: //#endif
251:
252: #else // _MAC
253:
254: #define STDDEBDECL(ignore, classname ) implement CDebug:public IDebug { public: \
255: CDebug( C##classname FAR * p##classname ) { m_p##classname = p##classname;} \
256: ~CDebug(void) {} \
257: STDMETHOD_(void, Dump)(IDebugStream FAR * pdbstm ); \
258: STDMETHOD_(BOOL, IsValid)(BOOL fSuspicious ); \
259: private: C##classname FAR* m_p##classname; }; \
260: DECLARE_NC(C##classname, CDebug) \
261: CDebug m_Debug;
262: #endif
263:
264: //#ifdef _MAC
265: //#define CONSTRUCT_DEBUG
266: //#else
267: #define CONSTRUCT_DEBUG m_Debug(this),
268: //#endif
269:
270: #else // _DEBUG
271:
272: // no debugging
273: #define STDDEBDECL(cclassname,classname)
274: #define CONSTRUCT_DEBUG
275:
276: #endif // _DEBUG
277:
278: #endif // __cplusplus
279:
280: #endif !_DEBUG_H_
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.