Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

384 lines
11 KiB

  1. /**********************************************************************/
  2. /** Microsoft Windows/NT **/
  3. /** Copyright(c) Microsoft Corp., 1991 **/
  4. /**********************************************************************/
  5. /*
  6. dbgstr.hxx
  7. A "stream" protocol for debugging output
  8. This lets me use a "stream" style of emitting debugging information,
  9. e.g.
  10. cdebug << "Couldn't allocate " << _cbFoo << " bytes." << dbgEOL;
  11. or
  12. cdebug << "Window moved to " << xyFinalRestingPlace << dbgEOL;
  13. All client applications have a "cdebug" stream already defined and
  14. constructed. Actually, only BLT apps have it already established;
  15. console apps must construct an output sink, and init the package
  16. like so:
  17. main()
  18. {
  19. OUTPUT_TO_STDERR out;
  20. DBGSTREAM::SetCurrent(&out);
  21. ... your code here ...
  22. DBGSTREAM::SetCurrent(NULL);
  23. }
  24. The macros DBGOUT and DBGEOL work with this global stream, ensuring
  25. that its data disappears from the object image in retail builds.
  26. DBGOUT automatically names cdebug as its destination stream; DBGEOL
  27. works likewise, but appends an end-of-line to its output. Both
  28. take a stream-output-expression, like so:
  29. DBGOUT("Number of pels: " << cPels);
  30. DBGEOL("; number of lims: " << cLims);
  31. or just
  32. DBGEOL("Number of pels: " << cPels << "; number of lims: " << cLims);
  33. If a client wants its own separate stream, it should first construct
  34. an output sink (OUTPUTSINK or derived class) for the stream, then
  35. construct the stream, passing the sink as a ctor param. E.g.
  36. OUTPUT_TO_WHEREVER out;
  37. DBGSTREAM dbgWherever(&out);
  38. dbgWherever << mumble;
  39. FILE HISTORY:
  40. beng 21-May-1991 Created
  41. beng 22-May-1991 Added IFTRACE and non-Windows sinks
  42. beng 27-Jun-1991 Removed INCL_WINDOWS. How else to
  43. use non-Win sinks?
  44. beng 06-Jul-1991 Added OUTPUT_TO_STDOUT
  45. Johnl 07-Aug-1991 Added some explanatory text
  46. beng 25-Oct-1991 Add DBG macros
  47. beng 12-Feb-1992 Rename DBG to DBGOUT (conflict w/ NT)
  48. beng 28-Feb-1992 New USE_CONSOLE def'n
  49. beng 16-Mar-1992 Simplify cdebug setups
  50. jonn 08-May-1992 Added TRACEOUT and TRACEEOL
  51. beng 10-May-1992 Removed obsolete IFTRACE
  52. */
  53. #ifndef _DBGSTR_HXX_
  54. #define _DBGSTR_HXX_
  55. // All the non-Windows versions communicate through stdio.
  56. #if !defined(INCL_WINDOWS) || defined(USE_CONSOLE)
  57. #include <stdio.h>
  58. #endif
  59. /*************************************************************************
  60. NAME: OUTPUTSINK
  61. SYNOPSIS: Abstract class describing any destination
  62. of debugging output.
  63. INTERFACE: Render() - Takes a character string and renders
  64. it on the destination. Supplies an
  65. optional second argument with the number
  66. of characters in the string as a hint
  67. for some 'sink implementations.
  68. EndOfLine() - Generate a linebreak on the destination.
  69. USES:
  70. CAVEATS:
  71. Client must supply some implementation
  72. NOTES:
  73. The OUTPUTSINK abstract class will let me extend this package
  74. to render output into a file, into a secondary window, etc.
  75. HISTORY:
  76. beng 21-May-1991 Created
  77. **************************************************************************/
  78. DLL_CLASS OUTPUTSINK
  79. {
  80. public:
  81. virtual VOID Render(const TCHAR *psz) = 0;
  82. virtual VOID Render(const TCHAR *psz, UINT cch) = 0;
  83. virtual VOID EndOfLine() = 0;
  84. };
  85. #if defined(INCL_WINDOWS)
  86. /*************************************************************************
  87. NAME: OUTPUT_TO_AUX
  88. SYNOPSIS: Delivers the debugging port for trace messages
  89. INTERFACE: Render() - Takes a character string and renders
  90. it on the debugging port.
  91. EndOfLine() - Generate a linebreak on the destination.
  92. PARENT: OUTPUTSINK
  93. HISTORY:
  94. beng 21-May-1991 Created
  95. beng 25-Oct-1991 Implementation outlined
  96. **************************************************************************/
  97. DLL_CLASS OUTPUT_TO_AUX: public OUTPUTSINK
  98. {
  99. public:
  100. virtual VOID Render(const TCHAR *psz);
  101. virtual VOID Render(const TCHAR *psz, UINT cch);
  102. virtual VOID EndOfLine();
  103. };
  104. #endif // WINDOWS
  105. #if defined(stderr)
  106. /*************************************************************************
  107. NAME: OUTPUT_TO_STDERR
  108. SYNOPSIS: Delivers the stderr stdio stream for trace messages
  109. INTERFACE: Render() - Takes a character string and renders
  110. it on handle 2.
  111. EndOfLine() - Generate a linebreak on the destination.
  112. PARENT: OUTPUTSINK
  113. HISTORY:
  114. beng 22-May-1991 Created
  115. beng 06-Jul-1991 Always assume output is cooked
  116. beng 25-Oct-1991 Implementation outlined
  117. **************************************************************************/
  118. DLL_CLASS OUTPUT_TO_STDERR: public OUTPUTSINK
  119. {
  120. public:
  121. virtual VOID Render(const TCHAR *psz);
  122. virtual VOID Render(const TCHAR *psz, UINT cch);
  123. virtual VOID EndOfLine();
  124. };
  125. #endif // STDIO
  126. #if defined(stdout)
  127. /*************************************************************************
  128. NAME: OUTPUT_TO_STDOUT
  129. SYNOPSIS: Delivers the stdout stdio stream for trace messages
  130. INTERFACE: Render() - Takes a character string and renders
  131. it on handle 1.
  132. EndOfLine() - Generate a linebreak on the destination.
  133. PARENT: OUTPUTSINK
  134. HISTORY:
  135. beng 06-Jul-1991 Created from OUTPUT_TO_STDERR
  136. beng 25-Oct-1991 Implementation outlined
  137. **************************************************************************/
  138. DLL_CLASS OUTPUT_TO_STDOUT: public OUTPUTSINK
  139. {
  140. public:
  141. virtual VOID Render(const TCHAR *psz);
  142. virtual VOID Render(const TCHAR *psz, UINT cch);
  143. virtual VOID EndOfLine();
  144. };
  145. #endif // STDIO
  146. /*************************************************************************
  147. NAME: OUTPUT_TO_NUL
  148. SYNOPSIS: Disables all trace messages.
  149. Messages to a DBGSTREAM using this sink will fall
  150. into the bitbucket w/o ado.
  151. PARENT: OUTPUTSINK
  152. NOTES:
  153. This class exists so that a stream can shut off messages
  154. on itself via SetSink.
  155. HISTORY:
  156. beng 22-May-1991 Created
  157. beng 25-Oct-1991 Implementation outlined
  158. **************************************************************************/
  159. DLL_CLASS OUTPUT_TO_NUL: public OUTPUTSINK
  160. {
  161. virtual VOID Render(const TCHAR *psz);
  162. virtual VOID Render(const TCHAR *psz, UINT cch);
  163. virtual VOID EndOfLine();
  164. };
  165. #if 0
  166. /*************************************************************************
  167. NAME: OUTPUT_TO_WIN
  168. SYNOPSIS: Pops up a scrollable window for trace messages.
  169. PARENT: OUTPUTSINK
  170. CAVEATS:
  171. Not yet implemented.
  172. NOTES:
  173. HISTORY:
  174. beng 21-May-1991 Daydreamed.
  175. **************************************************************************/
  176. DLL_CLASS OUTPUT_TO_WIN: public OUTPUTSINK
  177. {
  178. // ...
  179. };
  180. #endif
  181. // Dropping one of these on a stream results in a special action.
  182. //
  183. enum DBGSTR_SPECIAL
  184. {
  185. dbgEOL // End-of-line
  186. };
  187. /*************************************************************************
  188. NAME: DBGSTREAM
  189. SYNOPSIS: Stream-style object for debugging output
  190. INTERFACE: DBGSTREAM() - constructor, associating a
  191. sink with the stream
  192. SetSink() - change the sink on a stream
  193. operator<<() - render onto the stream. The class
  194. supports most primitive objects;
  195. in addition, "dbgEOL" will generate
  196. a linebreak.
  197. QueryCurrent() - returns a reference to the default
  198. global debugging stream, as aliased to
  199. "cdebug" in the source and used by
  200. the DBGEOL etc. macros.
  201. USES: OUTPUTSINK
  202. NOTES:
  203. Clients may supply their own operators for rendering
  204. themselves onto a DBGSTREAM.
  205. BUGBUG - the operators should use the "cch" form of Render.
  206. HISTORY:
  207. beng 21-May-1991 Created
  208. beng 25-Oct-1991 Use CCH_x manifests; implementation outlined
  209. beng 16-Mar-1992 Added QueryCurrent static etc.
  210. beng 29-Jun-1992 Outlined Set/QueryCurrent for dllization
  211. **************************************************************************/
  212. DLL_CLASS DBGSTREAM
  213. {
  214. private:
  215. OUTPUTSINK * _pout;
  216. // The home of cdebug
  217. //
  218. static DBGSTREAM * _pdbgCurrentGlobal;
  219. public:
  220. DBGSTREAM(OUTPUTSINK * pout);
  221. ~DBGSTREAM();
  222. static DBGSTREAM& QueryCurrent();
  223. static VOID SetCurrent(DBGSTREAM* pdbg);
  224. VOID SetSink(OUTPUTSINK * pout);
  225. DBGSTREAM& operator<<(TCHAR c);
  226. DBGSTREAM& operator<<(const TCHAR* psz);
  227. #if defined(UNICODE)
  228. // need these for simple output
  229. DBGSTREAM& operator<<(CHAR c);
  230. DBGSTREAM& operator<<(const CHAR* psz);
  231. #endif
  232. DBGSTREAM& operator<<(INT n);
  233. DBGSTREAM& operator<<(UINT n);
  234. DBGSTREAM& operator<<(SHORT n);
  235. #if !defined(UNICODE)
  236. // if defined, conflicts with TCHAR def'n
  237. DBGSTREAM& operator<<(USHORT n);
  238. #endif
  239. DBGSTREAM& operator<<(LONG n);
  240. DBGSTREAM& operator<<(ULONG n);
  241. DBGSTREAM& operator<<(INT64 n);
  242. DBGSTREAM& operator<<(UINT64 n);
  243. DBGSTREAM& operator<<(DBGSTR_SPECIAL dbgSpecial);
  244. };
  245. // For traditional stream-style output, declare an object named
  246. // "cdebug" (as in cin, cout, cerr).
  247. //
  248. // The BLT startup code points this at the AUX debugging console.
  249. // Command-line unit tests should hook it to stderr.
  250. //
  251. #define cdebug (DBGSTREAM::QueryCurrent())
  252. // We have to use the preprocessor to remove completely all trace
  253. // messages from the release product, since the compiler will not
  254. // optimize away unreferenced message strings.
  255. #if defined(DEBUG)
  256. #define DBGOUT(x) { cdebug << x ; }
  257. #define DBGEOL(x) { cdebug << x << dbgEOL; }
  258. #else
  259. #define DBGOUT(x) { ; }
  260. #define DBGEOL(x) { ; }
  261. #endif
  262. #if defined(DEBUG) && defined(TRACE)
  263. #define TRACEOUT(x) { cdebug << x ; }
  264. #define TRACEEOL(x) { cdebug << x << dbgEOL; }
  265. // must use semicolons after using these macros
  266. #define TRACETIMESTART DWORD dwTraceTime = ::GetTickCount()
  267. #define TRACETIMEEND(printthis) TRACEEOL( printthis << ::GetTickCount() - (dwTraceTime) << " msec" )
  268. #define TRACETIMESTART2(name) DWORD dwTraceTime##name = ::GetTickCount()
  269. #define TRACETIMEEND2(name,printthis) TRACEEOL( printthis << ::GetTickCount() - (dwTraceTime##name) << " msec" )
  270. #else
  271. #define TRACEOUT(x) { ; }
  272. #define TRACEEOL(x) { ; }
  273. #define TRACETIMESTART { ; }
  274. #define TRACETIMEEND(printthis) { ; }
  275. #define TRACETIMESTART2(name) { ; }
  276. #define TRACETIMEEND2(name,printthis) { ; }
  277. #endif
  278. #endif // _DBGSTR_HXX_