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.

248 lines
5.6 KiB

  1. /*****************************************************************************
  2. *
  3. * assert.c - Assertion stuff
  4. *
  5. *****************************************************************************/
  6. #include "fnd.h"
  7. #ifdef DEBUG
  8. #include <stdarg.h>
  9. /*****************************************************************************
  10. *
  11. * SquirtSqflPtszV
  12. *
  13. * Squirt a message with a trailing crlf.
  14. *
  15. *****************************************************************************/
  16. void EXTERNAL
  17. SquirtSqflPtszV(SQFL sqfl, LPCTSTR ptsz, ...)
  18. {
  19. if (sqfl == 0 || (sqfl & sqflCur)) {
  20. va_list ap;
  21. TCHAR tsz[1024];
  22. va_start(ap, ptsz);
  23. wvsprintf(tsz, ptsz, ap);
  24. va_end(ap);
  25. OutputDebugString(tsz);
  26. OutputDebugString(TEXT("\r\n"));
  27. }
  28. }
  29. /*****************************************************************************
  30. *
  31. * AssertPtszPtszLn
  32. *
  33. * Something bad happened.
  34. *
  35. *****************************************************************************/
  36. int EXTERNAL
  37. AssertPtszPtszLn(LPCTSTR ptszExpr, LPCTSTR ptszFile, int iLine)
  38. {
  39. SquirtSqflPtszV(sqflAlways, TEXT("Assertion failed: `%s' at %s(%d)"),
  40. ptszExpr, ptszFile, iLine);
  41. DebugBreak();
  42. return 0;
  43. }
  44. /*****************************************************************************
  45. *
  46. * Procedure call tracing is gross because of the C preprocessor.
  47. *
  48. * Oh, if only we had support for m4...
  49. *
  50. *****************************************************************************/
  51. /*****************************************************************************
  52. *
  53. * ArgsPszV
  54. *
  55. * Collect arguments to a procedure.
  56. *
  57. * psz -> ASCIIZ format string
  58. * ... = argument list
  59. *
  60. * The characters in the format string are listed in EmitPal.
  61. *
  62. *****************************************************************************/
  63. void EXTERNAL
  64. ArgsPalPszV(PARGLIST pal, LPCSTR psz, ...)
  65. {
  66. va_list ap;
  67. va_start(ap, psz);
  68. if (psz) {
  69. PPV ppv;
  70. pal->pszFormat = psz;
  71. for (ppv = pal->rgpv; *psz; psz++) {
  72. *ppv++ = va_arg(ap, PV);
  73. }
  74. } else {
  75. pal->pszFormat = "";
  76. }
  77. }
  78. /*****************************************************************************
  79. *
  80. * EmitPal
  81. *
  82. * OutputDebugString the information, given a pal. No trailing
  83. * carriage return is emitted.
  84. *
  85. * pal -> place where info was saved
  86. *
  87. * Format characters:
  88. *
  89. * p - 32-bit flat pointer
  90. * x - 32-bit hex integer
  91. * s - TCHAR string
  92. * A - ANSI string
  93. * W - UNICODE string
  94. * G - GUID
  95. * u - unsigned integer
  96. * C - clipboard format
  97. *
  98. *****************************************************************************/
  99. void INTERNAL
  100. EmitPal(PARGLIST pal)
  101. {
  102. char sz[MAX_PATH];
  103. int i;
  104. OutputDebugStringA(pal->pszProc);
  105. OutputDebugString(TEXT("("));
  106. for (i = 0; pal->pszFormat[i]; i++) {
  107. if (i) {
  108. OutputDebugString(TEXT(", "));
  109. }
  110. switch (pal->pszFormat[i]) {
  111. case 'p': /* 32-bit flat pointer */
  112. case 'x': /* 32-bit hex */
  113. wsprintfA(sz, "%08x", pal->rgpv[i]);
  114. OutputDebugStringA(sz);
  115. break;
  116. case 's': /* TCHAR string */
  117. if (pal->rgpv[i]) {
  118. OutputDebugString(pal->rgpv[i]);
  119. }
  120. break;
  121. case 'A': /* ANSI string */
  122. if (pal->rgpv[i]) {
  123. OutputDebugStringA(pal->rgpv[i]);
  124. }
  125. break;
  126. case 'G': /* GUID */
  127. wsprintfA(sz, "%08x", *(LPDWORD)pal->rgpv[i]);
  128. OutputDebugStringA(sz);
  129. break;
  130. case 'u': /* 32-bit unsigned decimal */
  131. wsprintfA(sz, "%u", pal->rgpv[i]);
  132. OutputDebugStringA(sz);
  133. break;
  134. case 'C':
  135. if (GetClipboardFormatNameA(PtrToUlong(pal->rgpv[i]), sz, cA(sz))) {
  136. } else {
  137. wsprintfA(sz, "[%04x]", pal->rgpv[i]);
  138. }
  139. OutputDebugStringA(sz);
  140. break;
  141. default: AssertF(0); /* Invalid */
  142. }
  143. }
  144. OutputDebugString(TEXT(")"));
  145. }
  146. /*****************************************************************************
  147. *
  148. * EnterSqflPtsz
  149. *
  150. * Mark entry to a procedure. Arguments were already collected by
  151. * ArgsPszV.
  152. *
  153. * sqfl -> squirty flags
  154. * pszProc -> procedure name
  155. * pal -> place to save the name and get the format/args
  156. *
  157. *****************************************************************************/
  158. void EXTERNAL
  159. EnterSqflPszPal(SQFL sqfl, LPCSTR pszProc, PARGLIST pal)
  160. {
  161. pal->pszProc = pszProc;
  162. if (sqfl == 0 || (sqfl & sqflCur)) {
  163. EmitPal(pal);
  164. OutputDebugString(TEXT("\r\n"));
  165. }
  166. }
  167. /*****************************************************************************
  168. *
  169. * ExitSqflPalHresPpv
  170. *
  171. * Mark exit from a procedure.
  172. *
  173. * pal -> argument list
  174. * hres -> exit result
  175. * ppv -> optional OUT pointer;
  176. * 1 means that hres is a boolean
  177. * 2 means that hres is nothing at all
  178. *
  179. *****************************************************************************/
  180. void EXTERNAL
  181. ExitSqflPalHresPpv(SQFL sqfl, PARGLIST pal, HRESULT hres, PPV ppvObj)
  182. {
  183. DWORD le = GetLastError();
  184. if (ppvObj == ppvVoid) {
  185. } else if (ppvObj == ppvBool) {
  186. if (hres == 0) {
  187. sqfl |= sqflError;
  188. }
  189. } else {
  190. if (FAILED(hres)) {
  191. AssertF(fLimpFF(ppvObj, *ppvObj == 0));
  192. sqfl |= sqflError;
  193. }
  194. }
  195. if (sqfl == 0 || (sqfl & sqflCur)) {
  196. EmitPal(pal);
  197. OutputDebugString(TEXT(" -> "));
  198. if (ppvObj != ppvVoid) {
  199. TCHAR tszBuf[32];
  200. wsprintf(tszBuf, TEXT("%08x"), hres);
  201. OutputDebugString(tszBuf);
  202. if (ppvObj != ppvBool) {
  203. if (ppvObj) {
  204. wsprintf(tszBuf, TEXT(" [%08x]"), *ppvObj);
  205. OutputDebugString(tszBuf);
  206. }
  207. } else if (hres == 0) {
  208. wsprintf(tszBuf, TEXT(" [%d]"), le);
  209. OutputDebugString(tszBuf);
  210. }
  211. }
  212. OutputDebugString(TEXT("\r\n"));
  213. }
  214. /*
  215. * This redundant test prevents a breakpoint on SetLastError()
  216. * from being hit constantly.
  217. */
  218. if (le != GetLastError()) {
  219. SetLastError(le);
  220. }
  221. }
  222. #endif