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.

473 lines
13 KiB

  1. //+----------------------------------------------------------------------------
  2. //
  3. // File: DAVEDBG.CPP
  4. //
  5. // Synopsis: TraceLog class for debugging
  6. //
  7. // Arguments:
  8. //
  9. // History: 23-Aug-94 Davepl Created
  10. //
  11. //-----------------------------------------------------------------------------
  12. #include "headers.hxx"
  13. #pragma hdrstop
  14. GROUPSET LEGroups = GS_CACHE; // Groups to display
  15. VERBOSITY LEVerbosity = VB_MAXIMUM; // Verbosity level to display at
  16. //+----------------------------------------------------------------------------
  17. //
  18. // Member: dprintf
  19. //
  20. // Synopsis: Dumps a printf style string to the debugger.
  21. //
  22. // Arguments: [szFormat] THIS pointer of caller
  23. // [...] Arguments
  24. //
  25. // Notes:
  26. //
  27. // History: 05-Sep-94 Davepl Created
  28. //
  29. //-----------------------------------------------------------------------------
  30. int dprintf(LPCSTR szFormat, ...)
  31. {
  32. char szBuffer[MAX_BUF];
  33. va_list vaList;
  34. va_start(vaList, szFormat);
  35. int retval = vsprintf(szBuffer, szFormat, vaList);
  36. OutputDebugStringA(szBuffer);
  37. va_end (vaList);
  38. return retval;
  39. }
  40. //+----------------------------------------------------------------------------
  41. //
  42. // Member: mprintf
  43. //
  44. // Synopsis: Dumps a printf style string to a message box.
  45. //
  46. // Arguments: [szFormat] THIS pointer of caller
  47. // [...] Arguments
  48. //
  49. // Notes:
  50. //
  51. // History: 05-Sep-94 Davepl Created
  52. //
  53. //-----------------------------------------------------------------------------
  54. int mprintf(LPCSTR szFormat, ...)
  55. {
  56. char szBuffer[MAX_BUF];
  57. va_list vaList;
  58. va_start(vaList, szFormat);
  59. int retval = vsprintf(szBuffer, szFormat, vaList);
  60. extern CCacheTestApp ctest;
  61. MessageBox(ctest.Window(),
  62. szBuffer,
  63. "CACHE UNIT TEST INFO",
  64. MB_ICONINFORMATION | MB_APPLMODAL | MB_OK);
  65. va_end (vaList);
  66. return retval;
  67. }
  68. //+----------------------------------------------------------------------------
  69. //
  70. // Member: TraceLog::TraceLog
  71. //
  72. // Synopsis: Records the THIS ptr and function name of the caller,
  73. // and determines whether or not the caller meets the
  74. // group and verbosity criteria for debug output
  75. //
  76. // Arguments: [pvThat] THIS pointer of caller
  77. // [pszFuntion] name of caller
  78. // [gsGroups] groups to which caller belongs
  79. // [vbVerbosity] verbosity level need to display debug
  80. // info for this function
  81. //
  82. // Notes:
  83. //
  84. // History: 23-Aug-94 Davepl Created
  85. //
  86. //-----------------------------------------------------------------------------
  87. TraceLog::TraceLog (void * pvThat,
  88. char * pszFunction,
  89. GROUPSET gsGroups,
  90. VERBOSITY vbVerbosity)
  91. {
  92. //
  93. // Determine whether or not the trace logging should be displayed
  94. // for this function. Iff it is, we need to track some information
  95. // about the function (ie: this ptr, func name)
  96. //
  97. // In order to be displayed, the function must belong to a group
  98. // which has been set in the group display mask, and the function
  99. // must be in an equal or lesser verbosity class.
  100. //
  101. if ( (gsGroups & LEGroups) && (LEVerbosity >= vbVerbosity) )
  102. {
  103. m_fShouldDisplay = TRUE;
  104. m_pvThat = pvThat;
  105. strncpy(m_pszFunction, pszFunction, MAX_BUF - 1);
  106. }
  107. else
  108. {
  109. m_fShouldDisplay = FALSE;
  110. }
  111. }
  112. //+----------------------------------------------------------------------------
  113. //
  114. // Member: TraceLog::OnEntry()
  115. //
  116. // Synopsis: Default entry output, which simply displays the _IN
  117. // trace with the function name and THIS pointer
  118. //
  119. // Returns: HRESULT
  120. //
  121. // Notes:
  122. //
  123. // History: 23-Aug-94 Davepl Created
  124. //
  125. //-----------------------------------------------------------------------------
  126. void TraceLog::OnEntry()
  127. {
  128. if (m_fShouldDisplay)
  129. {
  130. dprintf("[%p] _IN %s\n", m_pvThat, m_pszFunction);
  131. }
  132. }
  133. //+----------------------------------------------------------------------------
  134. //
  135. // Member: TraceLog::OnEntry
  136. //
  137. // Synopsis: Displays standard entry debug info, plus a printf
  138. // style trailer string as supplied by the caller
  139. //
  140. // Arguments: [pszFormat ...] printf style output string
  141. //
  142. // Returns: void
  143. //
  144. // Notes:
  145. //
  146. // History: 23-Aug-94 Davepl Created
  147. //
  148. //-----------------------------------------------------------------------------
  149. void TraceLog::OnEntry(char * pszFormat, ...)
  150. {
  151. //
  152. // Only display if we have already matched the correct criteria
  153. //
  154. if (m_fShouldDisplay)
  155. {
  156. char szBuffer[MAX_BUF];
  157. //
  158. // print the standard trace output, then the custom information as
  159. // received from the caller
  160. //
  161. dprintf("[%p] _IN %s ", m_pvThat, m_pszFunction);
  162. va_list vaList;
  163. va_start(vaList, pszFormat);
  164. vsprintf(szBuffer, pszFormat, vaList);
  165. dprintf(szBuffer);
  166. va_end(vaList);
  167. }
  168. }
  169. //+----------------------------------------------------------------------------
  170. //
  171. // Member: TraceLog::OnExit
  172. //
  173. // Synopsis: Sets the debug info that should be displayed when
  174. // the TraceLog object is destroyed
  175. //
  176. // Arguments: [pszFormat ...] printf style custom info
  177. //
  178. // Returns: void
  179. //
  180. // Notes: Since it would make no sense to pass variables by
  181. // value into this function (which would snapshot them
  182. // at the time this was called), variables in the arg
  183. // list must be passed by REFERENCE
  184. //
  185. // History: 23-Aug-94 Davepl Created
  186. //
  187. //-----------------------------------------------------------------------------
  188. void TraceLog::OnExit(const char * pszFormat, ...)
  189. {
  190. if (m_fShouldDisplay)
  191. {
  192. const char * pch; // ptr to walk format string
  193. BOOL fBreak; // set when past fmt specifier
  194. //
  195. // Start processing the argument list
  196. //
  197. va_list arg;
  198. va_start (arg, pszFormat);
  199. //
  200. // Save the format string for use in the destructor
  201. //
  202. strcpy (m_pszFormat, pszFormat);
  203. m_cArgs = 0;
  204. //
  205. // Walk the format string looking for % modifiers
  206. //
  207. for (pch = pszFormat; *pch; pch++)
  208. {
  209. if (*pch != '%')
  210. {
  211. continue;
  212. }
  213. // We can stop looking until EOL or end of specifier
  214. fBreak = FALSE;
  215. while (!fBreak)
  216. {
  217. if (!* (++pch)) // Hit EOL
  218. {
  219. break;
  220. }
  221. switch (*pch)
  222. {
  223. //
  224. // These are all valid format specifiers and
  225. // modifers which may be combined to reference
  226. // a single argument in the argument list
  227. //
  228. case 'F':
  229. case 'l':
  230. case 'h':
  231. case 'X':
  232. case 'x':
  233. case 'O':
  234. case 'o':
  235. case 'd':
  236. case 'u':
  237. case 'c':
  238. case 's':
  239. break;
  240. default:
  241. //
  242. // We have hit a character which is not a valid specifier,
  243. // so we stop searching in order to pull the argument
  244. // which corresponds with it from the arg list
  245. //
  246. fBreak = TRUE;
  247. break;
  248. }
  249. }
  250. //
  251. // If we have already hit the maximum number of args, we can't do
  252. // any more
  253. //
  254. if (m_cArgs == MAX_ARGS)
  255. {
  256. break;
  257. }
  258. //
  259. // Grab the argument as a NULL ptr. We will save it away and figure
  260. // out what kind of argument it was when it comes time to display it,
  261. // based on the format string
  262. //
  263. m_aPtr[m_cArgs] = va_arg (arg, void *);
  264. m_cArgs++;
  265. if (! *pch)
  266. {
  267. break;
  268. }
  269. }
  270. }
  271. }
  272. //+----------------------------------------------------------------------------
  273. //
  274. // Member: TraceLog::~TraceLog
  275. //
  276. // Synopsis: On destruction, the TraceLog class displays its debug
  277. // output as set by the OnExit() method.
  278. //
  279. // Returns: void
  280. //
  281. // Notes:
  282. //
  283. // History: 23-Aug-94 Davepl Created
  284. //
  285. //-----------------------------------------------------------------------------
  286. TraceLog::~TraceLog()
  287. {
  288. char szTmpFmt[ MAX_BUF ];
  289. char szOutStr[ MAX_BUF ];
  290. char *pszOut;
  291. char *pszszTmpFmt;
  292. const char * pszFmt;
  293. void *pv;
  294. BYTE i = 0;
  295. VARTYPE vtVarType;
  296. BOOL fBreak;
  297. pszOut = szOutStr;
  298. //
  299. // Walk the format string looking for format specifiers
  300. //
  301. for (pszFmt = m_pszFormat; *pszFmt; pszFmt++)
  302. {
  303. if (*pszFmt != '%')
  304. {
  305. *pszOut++ = *pszFmt;
  306. continue;
  307. }
  308. //
  309. // Found the start of a specifier. Reset the expected argument type,
  310. // then walk to the end of the specifier
  311. //
  312. vtVarType = NO_TYPE;
  313. fBreak = FALSE;
  314. //
  315. // Start recording the specifier for a single call to sprintf later
  316. //
  317. for (pszszTmpFmt = szTmpFmt; !fBreak; )
  318. {
  319. *pszszTmpFmt++ = *pszFmt;
  320. //
  321. // Guard against a terminator that doesn't comlete before EOL
  322. //
  323. if (!* (++pszFmt))
  324. {
  325. break;
  326. }
  327. //
  328. // These are all valid format specifiers. Skip over them and
  329. // update the vtVarType. It's end value will be our heuristic
  330. // which indicates what type of variable was really intended
  331. //
  332. switch (*pszFmt)
  333. {
  334. case 'l': vtVarType |= LONG_TYPE; break;
  335. case 'h': vtVarType |= SHORT_TYPE; break;
  336. case 'X': vtVarType |= INT_TYPE; break;
  337. case 'x': vtVarType |= INT_TYPE; break;
  338. case 'O': vtVarType |= INT_TYPE; break;
  339. case 'o': vtVarType |= INT_TYPE; break;
  340. case 'd': vtVarType |= INT_TYPE; break;
  341. case 'u': vtVarType |= INT_TYPE; break;
  342. case 'c': vtVarType |= CHAR_TYPE; break;
  343. case 's': vtVarType |= STRING_TYPE; break;
  344. case 'p': vtVarType |= PTR_TYPE; break;
  345. default: fBreak = TRUE; break;
  346. }
  347. }
  348. // NUL-terminate the end of the temporary format string
  349. *pszszTmpFmt = 0;
  350. // Grab the argument pointer which corresponds to this argument
  351. pv = m_aPtr[ i ];
  352. i++;
  353. //
  354. // Using the appropriate cast, spew the argument into our
  355. // local output buffer using the original format specifier.
  356. //
  357. if (vtVarType & STRING_TYPE)
  358. {
  359. sprintf (pszOut, szTmpFmt, (char *)pv);
  360. }
  361. else if (vtVarType & LONG_TYPE)
  362. {
  363. sprintf (pszOut, szTmpFmt, *(long *)pv);
  364. }
  365. else if (vtVarType & SHORT_TYPE)
  366. {
  367. sprintf (pszOut, szTmpFmt, *(short *)pv);
  368. }
  369. else if (vtVarType & INT_TYPE)
  370. {
  371. sprintf (pszOut, szTmpFmt, *(int *)pv);
  372. }
  373. else if (vtVarType & CHAR_TYPE)
  374. {
  375. sprintf (pszOut, szTmpFmt, (char)*(char *)pv);
  376. }
  377. else if (vtVarType & PTR_TYPE)
  378. {
  379. sprintf (pszOut, szTmpFmt, (void *)pv);
  380. }
  381. else
  382. {
  383. *pszOut = 0;
  384. }
  385. // Advance the output buffer pointer to the end of the
  386. // current buffer
  387. pszOut = &pszOut[ strlen(pszOut) ];
  388. if (! *pszFmt)
  389. {
  390. break;
  391. }
  392. }
  393. // NUL-terminate the buffer
  394. *pszOut = 0;
  395. //
  396. // Dump the resultant buffer to the output
  397. //
  398. dprintf("[%p] OUT %s %s", m_pvThat, m_pszFunction, szOutStr);
  399. }