trace_nt.c 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187
  1. /* trace_nt.c - Debugging routines
  2. for Midnight Commander, under Win32
  3. Written 951215 by Juan Grigera <grigera@isis.unlp.edu.ar>
  4. This program is free software; you can redistribute it and/or modify
  5. it under the terms of the GNU General Public License as published by
  6. the Free Software Foundation; either version 2 of the License, or
  7. (at your option) any later version.
  8. This program is distributed in the hope that it will be useful,
  9. but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  11. GNU General Public License for more details.
  12. You should have received a copy of the GNU General Public License
  13. along with this program; if not, write to the Free Software
  14. Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
  15. */
  16. #include <config.h>
  17. #ifdef HAVE_TRACE
  18. #include <stdio.h>
  19. #ifdef _OS_NT
  20. #include <windows.h>
  21. #endif
  22. #include <errno.h>
  23. #include "trace_nt.h"
  24. /* Global variables */
  25. int __win32_tracing_enabled = 1;
  26. static int _win32_tracing_started = 0;
  27. static FILE *__win32_trace_f = NULL;
  28. /* Definitions */
  29. #define TRACE_FILE "mcTrace.out"
  30. /* Prototypes - static funcs */
  31. static void _win32InitTrace (void);
  32. static void _win32EndTrace (void);
  33. static const char* GetLastErrorText(void);
  34. static char *visbuf(const char *buf);
  35. /*
  36. void _win32InitTrace()
  37. This func will open file TRACE_FILE for output and add _win32EndTrace to onexit
  38. list of funcs.
  39. */
  40. static void _win32InitTrace()
  41. {
  42. if (!_win32_tracing_started) {
  43. _win32_tracing_started = 1;
  44. __win32_trace_f = fopen(TRACE_FILE, "wt");
  45. if (__win32_trace_f == NULL) {
  46. printf("Midnight Commander[DEBUG]: Cannot open trace file '" TRACE_FILE "': %s \n", strerror(errno));
  47. }
  48. atexit (&_win32EndTrace);
  49. }
  50. }
  51. /*
  52. void _win32EndTrace()
  53. This func closes file TRACE_FILE if opened.
  54. */
  55. static void _win32EndTrace()
  56. {
  57. if (_win32_tracing_started) {
  58. _win32_tracing_started = 0;
  59. if (__win32_trace_f)
  60. fclose (__win32_trace_f);
  61. }
  62. }
  63. /*
  64. void _win32Trace (char *fmt, ...)
  65. Format and output debug strings. They are written to TRACE_FILE.
  66. Debug Output is controlled by SetTrace (see below).
  67. Win32: Output is sent to Debug Output also.
  68. */
  69. void _win32Trace (const char *fmt, ...)
  70. {
  71. va_list ap;
  72. char buffer[256];
  73. char *vp;
  74. if (!_win32_tracing_started)
  75. _win32InitTrace();
  76. va_start(ap, fmt);
  77. vsprintf(buffer, fmt, ap);
  78. va_end(ap);
  79. vp = buffer;
  80. #ifdef _OS_NT /* Write Output to Debug monitor also */
  81. OutputDebugString (vp);
  82. #if (_MSC_VER > 800) /* Don't write newline in MSVC++ 1.0, has a dammed bug in Debug Output screen */
  83. OutputDebugString ("\n");
  84. #endif
  85. #endif
  86. if(__win32_trace_f)
  87. fprintf (__win32_trace_f, "%s\n", vp);
  88. }
  89. /*
  90. void SetTrace (int trace)
  91. Control debug output. Turn it of or on.
  92. trace: 0 = off, 1 = on.
  93. */
  94. void _win32SetTrace (int trace)
  95. {
  96. /* Prototypes - interlan funcs */
  97. __win32_tracing_enabled = trace;
  98. }
  99. void _win32TraceOn ()
  100. {
  101. __win32_tracing_enabled = 1;
  102. }
  103. void _win32TraceOff()
  104. {
  105. __win32_tracing_enabled = 0;
  106. }
  107. #ifdef _OS_NT
  108. /*
  109. void DebugFailedWin32APICall (const char* name, int line, const char* file)
  110. Report a System call failure.
  111. name - text containing the source code that called the offending API func
  112. line, file - place of "name" in code
  113. See Also: definition of win32APICALL macro.
  114. */
  115. void _win32DebugFailedWin32APICall (const char* name, int line, const char* file)
  116. {
  117. _win32Trace ("%s(%d): Call to Win32 API Failed. \"%s\".", file, line, name);
  118. _win32Trace (" System Error (%d): %s. ", GetLastError(), GetLastErrorText());
  119. }
  120. #endif
  121. /*
  122. void DebugAssertionFailed (const char* name, int line, const char* file)
  123. Report a logical condition failure. (e.g. a bad argument to a func)
  124. name - text containing the logical condition
  125. line, file - place of "name" in code
  126. See Also: definition of ASSERT macro.
  127. */
  128. void _win32DebugAssertionFailed (const char* name, int line, const char* file)
  129. {
  130. _win32Trace ("%s(%d): Assertion failed! \"%s\".", file, line, name);
  131. }
  132. /* const char* GetLastErrorText()
  133. Retrieves the text associated with the last system error.
  134. Returns pointer to static buffer. Contents valid till next call
  135. */
  136. static const char* GetLastErrorText()
  137. {
  138. #define MAX_MSG_SIZE 256
  139. static char szMsgBuf[MAX_MSG_SIZE];
  140. DWORD dwError, dwRes;
  141. dwError = GetLastError ();
  142. dwRes = FormatMessage (
  143. FORMAT_MESSAGE_FROM_SYSTEM,
  144. NULL,
  145. dwError,
  146. MAKELANGID (LANG_ENGLISH, SUBLANG_ENGLISH_US),
  147. szMsgBuf,
  148. MAX_MSG_SIZE,
  149. NULL);
  150. if (0 == dwRes) {
  151. sprintf (szMsgBuf, "FormatMessage failed with %d", GetLastError());
  152. }
  153. return szMsgBuf;
  154. }
  155. #endif /*HAVE_TRACE*/