1 | //////////////////////////////////////////////////////////// |
---|
2 | // Copyright (C) Roman Ryltsov, 2015 |
---|
3 | // Created by Roman Ryltsov roman@alax.info |
---|
4 | // |
---|
5 | // A permission to use the source code is granted as long as reference to |
---|
6 | // source website http://alax.info is retained. |
---|
7 | |
---|
8 | #pragma once |
---|
9 | |
---|
10 | //////////////////////////////////////////////////////////// |
---|
11 | // CDebugTrace, ATLTRACE, ATLTRACE2 |
---|
12 | |
---|
13 | #if !defined(_TRACELEVEL) |
---|
14 | #define _TRACELEVEL 4 |
---|
15 | #endif // !defined(_TRACELEVEL) |
---|
16 | |
---|
17 | class CDebugTraceBase |
---|
18 | { |
---|
19 | public: |
---|
20 | // CDebugTraceBase |
---|
21 | static const CHAR* ShortFileNameFromFileName(const CHAR* pszFileName) |
---|
22 | { |
---|
23 | if(pszFileName) |
---|
24 | { |
---|
25 | const CHAR* pszShortFileName = strrchr(pszFileName, '\\'); |
---|
26 | if(pszShortFileName) |
---|
27 | return pszShortFileName + 1; |
---|
28 | } |
---|
29 | return pszFileName; |
---|
30 | } |
---|
31 | }; |
---|
32 | |
---|
33 | class CDebugTrace : |
---|
34 | public CDebugTraceBase |
---|
35 | { |
---|
36 | private: |
---|
37 | LPCSTR m_pszFileName; |
---|
38 | INT m_nLineNumber; |
---|
39 | LPCSTR m_pszFunctionName; |
---|
40 | |
---|
41 | CDebugTrace& __cdecl operator = (const CDebugTrace&); // Not implemented |
---|
42 | |
---|
43 | static VOID TraceV(LPCSTR pszFileName, INT nLineNumber, LPCSTR pszFunctionName, DWORD_PTR nCategory, UINT nLevel, LPCSTR pszFormat, va_list& Arguments) |
---|
44 | { |
---|
45 | nCategory; |
---|
46 | nLevel; |
---|
47 | pszFileName = ShortFileNameFromFileName(pszFileName); |
---|
48 | static const SIZE_T g_nTextLength = 8 << 10; // 8 KB |
---|
49 | CHAR pszText[g_nTextLength] = { 0 }; |
---|
50 | SIZE_T nTextLength = 0; |
---|
51 | if(pszFileName) |
---|
52 | nTextLength += sprintf_s(pszText + nTextLength, _countof(pszText) - nTextLength, "%hs(%d): %hs: ", pszFileName, nLineNumber, pszFunctionName); |
---|
53 | nTextLength += vsprintf_s(pszText + nTextLength, _countof(pszText) - nTextLength, pszFormat, Arguments); |
---|
54 | OutputDebugStringA(pszText); |
---|
55 | } |
---|
56 | static VOID TraceV(LPCSTR pszFileName, INT nLineNumber, LPCSTR pszFunctionName, DWORD_PTR nCategory, UINT nLevel, LPCWSTR pszFormat, va_list& Arguments) |
---|
57 | { |
---|
58 | nCategory; |
---|
59 | nLevel; |
---|
60 | pszFileName = ShortFileNameFromFileName(pszFileName); |
---|
61 | static const SIZE_T g_nTextLength = 8 << 10; // 8 KB |
---|
62 | WCHAR pszText[g_nTextLength] = { 0 }; |
---|
63 | SIZE_T nTextLength = 0; |
---|
64 | if(pszFileName) |
---|
65 | nTextLength += swprintf_s(pszText + nTextLength, _countof(pszText) - nTextLength, L"%hs(%d): %hs: ", pszFileName, nLineNumber, pszFunctionName); |
---|
66 | nTextLength += vswprintf_s(pszText + nTextLength, _countof(pszText) - nTextLength, pszFormat, Arguments); |
---|
67 | OutputDebugStringW(pszText); |
---|
68 | } |
---|
69 | |
---|
70 | public: |
---|
71 | // CDebugTrace |
---|
72 | CDebugTrace(LPCSTR pszFileName, INT nLineNumber, LPCSTR pszFunctionName) : |
---|
73 | m_pszFileName(pszFileName), |
---|
74 | m_nLineNumber(nLineNumber), |
---|
75 | m_pszFunctionName(pszFunctionName) |
---|
76 | { |
---|
77 | } |
---|
78 | __forceinline VOID __cdecl operator () (DWORD_PTR nCategory, UINT nLevel, LPCSTR pszFormat, ...) |
---|
79 | { |
---|
80 | #if defined(_DEBUG) |
---|
81 | if(!nCategory) |
---|
82 | return; |
---|
83 | #endif // defined(_DEBUG) |
---|
84 | if(nLevel > _TRACELEVEL) |
---|
85 | return; |
---|
86 | va_list Arguments; |
---|
87 | va_start(Arguments, pszFormat); |
---|
88 | __try |
---|
89 | { |
---|
90 | TraceV(m_pszFileName, m_nLineNumber, m_pszFunctionName, nCategory, nLevel, pszFormat, Arguments); |
---|
91 | } |
---|
92 | __except(EXCEPTION_EXECUTE_HANDLER) |
---|
93 | { |
---|
94 | } |
---|
95 | va_end(Arguments); |
---|
96 | } |
---|
97 | __forceinline VOID __cdecl operator () (LPCSTR pszFormat, ...) |
---|
98 | { |
---|
99 | //#if defined(_DEBUG) |
---|
100 | // if(!nCategory) |
---|
101 | // return; |
---|
102 | //#endif // defined(_DEBUG) |
---|
103 | //if(nLevel > _TRACELEVEL) |
---|
104 | // return; |
---|
105 | va_list Arguments; |
---|
106 | va_start(Arguments, pszFormat); |
---|
107 | __try |
---|
108 | { |
---|
109 | static const DWORD_PTR g_nCategory = 1; |
---|
110 | static const DWORD_PTR g_nLevel = 2; |
---|
111 | TraceV(m_pszFileName, m_nLineNumber, m_pszFunctionName, g_nCategory, g_nLevel, pszFormat, Arguments); |
---|
112 | } |
---|
113 | __except(EXCEPTION_EXECUTE_HANDLER) |
---|
114 | { |
---|
115 | } |
---|
116 | va_end(Arguments); |
---|
117 | } |
---|
118 | __forceinline VOID __cdecl operator () (DWORD_PTR nCategory, UINT nLevel, LPCWSTR pszFormat, ...) |
---|
119 | { |
---|
120 | #if defined(_DEBUG) |
---|
121 | if(!nCategory) |
---|
122 | return; |
---|
123 | #endif // defined(_DEBUG) |
---|
124 | if(nLevel > _TRACELEVEL) |
---|
125 | return; |
---|
126 | va_list Arguments; |
---|
127 | va_start(Arguments, pszFormat); |
---|
128 | __try |
---|
129 | { |
---|
130 | TraceV(m_pszFileName, m_nLineNumber, m_pszFunctionName, nCategory, nLevel, pszFormat, Arguments); |
---|
131 | } |
---|
132 | __except(EXCEPTION_EXECUTE_HANDLER) |
---|
133 | { |
---|
134 | } |
---|
135 | va_end(Arguments); |
---|
136 | } |
---|
137 | __forceinline VOID __cdecl operator () (LPCWSTR pszFormat, ...) |
---|
138 | { |
---|
139 | //#if defined(_DEBUG) |
---|
140 | // if(!nCategory) |
---|
141 | // return; |
---|
142 | //#endif // defined(_DEBUG) |
---|
143 | //if(nLevel > _TRACELEVEL) |
---|
144 | // return; |
---|
145 | va_list Arguments; |
---|
146 | va_start(Arguments, pszFormat); |
---|
147 | __try |
---|
148 | { |
---|
149 | static const DWORD_PTR g_nCategory = 1; |
---|
150 | static const DWORD_PTR g_nLevel = 2; |
---|
151 | TraceV(m_pszFileName, m_nLineNumber, m_pszFunctionName, g_nCategory, g_nLevel, pszFormat, Arguments); |
---|
152 | } |
---|
153 | __except(EXCEPTION_EXECUTE_HANDLER) |
---|
154 | { |
---|
155 | } |
---|
156 | va_end(Arguments); |
---|
157 | } |
---|
158 | }; |
---|
159 | |
---|
160 | #undef ATLTRACE |
---|
161 | #undef ATLTRACE2 |
---|
162 | #define ATLTRACE CDebugTrace(__FILE__, __LINE__, __FUNCTION__) |
---|
163 | #define ATLTRACE2 ATLTRACE |
---|
164 | |
---|
165 | #define _Z ATLTRACE |
---|
166 | #define _Z0 ATLTRACE |
---|
167 | #define _Z1 ATLTRACE |
---|
168 | #define _Z2 ATLTRACE |
---|
169 | #define _Z3 ATLTRACE |
---|
170 | #define _Z4 ATLTRACE |
---|
171 | #define _Z5 ATLTRACE |
---|
172 | #define _Z6 ATLTRACE |
---|
173 | |
---|
174 | class CDebugTraceContext : |
---|
175 | public CDebugTraceBase |
---|
176 | { |
---|
177 | private: |
---|
178 | LPCSTR m_pszFileName; |
---|
179 | INT m_nLineNumber; |
---|
180 | LPCSTR m_pszFunctionName; |
---|
181 | CString m_sText; |
---|
182 | BOOL m_bTerminated; |
---|
183 | |
---|
184 | public: |
---|
185 | // CDebugTraceContext |
---|
186 | CDebugTraceContext(LPCSTR pszFileName, INT nLineNumber, LPCSTR pszFunctionName) : |
---|
187 | m_pszFileName(pszFileName), |
---|
188 | m_nLineNumber(nLineNumber), |
---|
189 | m_pszFunctionName(pszFunctionName), |
---|
190 | m_bTerminated(FALSE) |
---|
191 | { |
---|
192 | } |
---|
193 | ~CDebugTraceContext() |
---|
194 | { |
---|
195 | if(!m_bTerminated) |
---|
196 | { |
---|
197 | CString sText; |
---|
198 | sText.Format(_T("%hs(%d): %hs: Context not terminated"), ShortFileNameFromFileName(m_pszFileName), m_nLineNumber, m_pszFunctionName); |
---|
199 | if(!m_sText.IsEmpty()) |
---|
200 | sText.AppendFormat(_T(", %s"), m_sText); |
---|
201 | sText.Append(_T("\r\n")); |
---|
202 | OutputDebugString(sText); |
---|
203 | } |
---|
204 | } |
---|
205 | VOID Terminate() |
---|
206 | { |
---|
207 | m_bTerminated = TRUE; |
---|
208 | } |
---|
209 | __forceinline VOID __cdecl operator () (LPCSTR pszFormat, ...) |
---|
210 | { |
---|
211 | va_list Arguments; |
---|
212 | va_start(Arguments, pszFormat); |
---|
213 | CStringA sText; |
---|
214 | sText.FormatV(pszFormat, Arguments); |
---|
215 | m_sText.Append(CString(sText)); |
---|
216 | va_end(Arguments); |
---|
217 | } |
---|
218 | __forceinline VOID __cdecl operator () (LPCWSTR pszFormat, ...) |
---|
219 | { |
---|
220 | va_list Arguments; |
---|
221 | va_start(Arguments, pszFormat); |
---|
222 | CStringW sText; |
---|
223 | sText.FormatV(pszFormat, Arguments); |
---|
224 | m_sText.Append(CString(sText)); |
---|
225 | va_end(Arguments); |
---|
226 | } |
---|
227 | }; |
---|
228 | |
---|
229 | #define _Y1 CDebugTraceContext DebugTraceContext(__FILE__, __LINE__, __FUNCTION__); DebugTraceContext |
---|
230 | #define _Y2 DebugTraceContext.Terminate |
---|