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.

259 lines
5.8 KiB

  1. /*****************************************************************************
  2. *
  3. * assert.c - Assertion stuff
  4. *
  5. *****************************************************************************/
  6. #include "map.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 the C preprocessor is lame.
  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. #if 0
  127. case 'W': /* UNICODE string */
  128. #ifdef UNICODE
  129. OutputDebugStringW(pal->rgpv[i]);
  130. #else
  131. OleStrToStrN(sz, cA(sz), pal->rgpv[i], -1);
  132. OutputDebugStringA(sz);
  133. #endif
  134. break;
  135. #endif
  136. case 'G': /* GUID */
  137. wsprintfA(sz, "%08x", *(LPDWORD)pal->rgpv[i]);
  138. OutputDebugStringA(sz);
  139. break;
  140. case 'u': /* 32-bit unsigned decimal */
  141. wsprintfA(sz, "%u", pal->rgpv[i]);
  142. OutputDebugStringA(sz);
  143. break;
  144. case 'C':
  145. if (GetClipboardFormatNameA(PtrToInt(pal->rgpv[i]), sz, cA(sz))) {
  146. } else {
  147. wsprintfA(sz, "[%04x]", pal->rgpv[i]);
  148. }
  149. OutputDebugStringA(sz);
  150. break;
  151. default: AssertF(0); /* Invalid */
  152. }
  153. }
  154. OutputDebugString(TEXT(")"));
  155. }
  156. /*****************************************************************************
  157. *
  158. * EnterSqflPtsz
  159. *
  160. * Mark entry to a procedure. Arguments were already collected by
  161. * ArgsPszV.
  162. *
  163. * sqfl -> squirty flags
  164. * pszProc -> procedure name
  165. * pal -> place to save the name and get the format/args
  166. *
  167. *****************************************************************************/
  168. void EXTERNAL
  169. EnterSqflPszPal(SQFL sqfl, LPCSTR pszProc, PARGLIST pal)
  170. {
  171. pal->pszProc = pszProc;
  172. if (sqfl == 0 || (sqfl & sqflCur)) {
  173. EmitPal(pal);
  174. OutputDebugString(TEXT("\r\n"));
  175. }
  176. }
  177. /*****************************************************************************
  178. *
  179. * ExitSqflPalHresPpv
  180. *
  181. * Mark exit from a procedure.
  182. *
  183. * pal -> argument list
  184. * hres -> exit result
  185. * ppv -> optional OUT pointer;
  186. * 1 means that hres is a boolean
  187. * 2 means that hres is nothing at all
  188. *
  189. *****************************************************************************/
  190. void EXTERNAL
  191. ExitSqflPalHresPpv(SQFL sqfl, PARGLIST pal, HRESULT hres, PPV ppvObj)
  192. {
  193. DWORD le = GetLastError();
  194. if (ppvObj == ppvVoid) {
  195. } else if (ppvObj == ppvBool) {
  196. if (hres == 0) {
  197. sqfl |= sqflError;
  198. }
  199. } else {
  200. if (FAILED(hres)) {
  201. AssertF(fLimpFF(ppvObj, *ppvObj == 0));
  202. sqfl |= sqflError;
  203. }
  204. }
  205. if (sqfl == 0 || (sqfl & sqflCur)) {
  206. EmitPal(pal);
  207. OutputDebugString(TEXT(" -> "));
  208. if (ppvObj != ppvVoid) {
  209. TCHAR tszBuf[32];
  210. wsprintf(tszBuf, TEXT("%08x"), hres);
  211. OutputDebugString(tszBuf);
  212. if (ppvObj != ppvBool) {
  213. if (ppvObj) {
  214. wsprintf(tszBuf, TEXT(" [%08x]"), *ppvObj);
  215. OutputDebugString(tszBuf);
  216. }
  217. } else if (hres == 0) {
  218. wsprintf(tszBuf, TEXT(" [%d]"), le);
  219. OutputDebugString(tszBuf);
  220. }
  221. }
  222. OutputDebugString(TEXT("\r\n"));
  223. }
  224. /*
  225. * This redundant test prevents a breakpoint on SetLastError()
  226. * from being hit constantly.
  227. */
  228. if (le != GetLastError()) {
  229. SetLastError(le);
  230. }
  231. }
  232. #endif