source: trunk/Utilities/Miscellaneous/AtlReleaseTrace/roatlreleasetrace.h @ 606

Last change on this file since 606 was 606, checked in by roman, 6 years ago
File size: 8.2 KB
Line 
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#include <math.h>
11#include <atlstr.h>
12
13using namespace ATL;
14
15////////////////////////////////////////////////////////////
16// CDebugTrace, ATLTRACE, ATLTRACE2
17
18#if !defined(_TRACELEVEL)
19        #define _TRACELEVEL 4
20#endif // !defined(_TRACELEVEL)
21
22#define _TRACESUFFIX_PROCESSIDENTIFIER 0x01
23#define _TRACESUFFIX_THREADIDENTIFIER  0x02
24
25#if !defined(_TRACESUFFIX)
26        #define _TRACESUFFIX _TRACESUFFIX_THREADIDENTIFIER
27#endif // !defined(_TRACESUFFIX)
28
29class CDebugTraceBase
30{
31public:
32// CDebugTraceBase
33        static const CHAR* ShortFileNameFromFileName(const CHAR* pszFileName)
34        {
35                if(pszFileName)
36                {
37                        const CHAR* pszShortFileName = strrchr(pszFileName, '\\');
38                        if(pszShortFileName)
39                                return pszShortFileName + 1;
40                }
41                return pszFileName;
42        }
43        static CString ApplyTraceSuffix(CString sText)
44        {
45                #if defined(_TRACESUFFIX) && _TRACESUFFIX > 0
46                        sText.TrimRight(_T("\t\n\r ."));
47                        sText.Append(_T(" ["));
48                        #if _TRACESUFFIX & _TRACESUFFIX_PROCESSIDENTIFIER
49                                sText.AppendFormat(_T("P %d, "), GetCurrentProcessId());
50                        #endif
51                        #if _TRACESUFFIX & _TRACESUFFIX_THREADIDENTIFIER
52                                sText.AppendFormat(_T("T %d, "), GetCurrentThreadId());
53                        #endif
54                        sText.TrimRight(_T(" ,"));
55                        sText.Append(_T("]\n"));
56                #endif // !defined(_TRACESUFFIX)
57                return sText;
58        }
59};
60
61class CDebugTrace :
62        public CDebugTraceBase
63{
64private:
65        LPCSTR m_pszFileName;
66        INT m_nLineNumber;
67        LPCSTR m_pszFunctionName;
68
69        CDebugTrace& __cdecl operator = (const CDebugTrace&); // Not implemented
70
71        static VOID TraceV(LPCSTR pszFileName, INT nLineNumber, LPCSTR pszFunctionName, DWORD_PTR nCategory, UINT nLevel, LPCSTR pszFormat, va_list& Arguments)
72        {
73                nCategory;
74                nLevel;
75                pszFileName = ShortFileNameFromFileName(pszFileName);
76                static const SIZE_T g_nTextLength = 8 << 10; // 8 KB
77                CHAR pszText[g_nTextLength] = { 0 };
78                SIZE_T nTextLength = 0;
79                if(pszFileName)
80                        nTextLength += sprintf_s(pszText + nTextLength, _countof(pszText) - nTextLength, "%hs(%d): %hs: ", pszFileName, nLineNumber, pszFunctionName);
81                nTextLength += vsprintf_s(pszText + nTextLength, _countof(pszText) - nTextLength, pszFormat, Arguments);
82                #if defined(_TRACESUFFIX) && _TRACESUFFIX > 0
83                        CString sText(pszText);
84                        OutputDebugString(ApplyTraceSuffix(sText));
85                #else
86                        OutputDebugStringA(pszText);
87                #endif // defined(_TRACESUFFIX)
88        }
89        static VOID TraceV(LPCSTR pszFileName, INT nLineNumber, LPCSTR pszFunctionName, DWORD_PTR nCategory, UINT nLevel, LPCWSTR pszFormat, va_list& Arguments)
90        {
91                nCategory;
92                nLevel;
93                pszFileName = ShortFileNameFromFileName(pszFileName);
94                static const SIZE_T g_nTextLength = 8 << 10; // 8 KB
95                WCHAR pszText[g_nTextLength] = { 0 };
96                SIZE_T nTextLength = 0;
97                if(pszFileName)
98                        nTextLength += swprintf_s(pszText + nTextLength, _countof(pszText) - nTextLength, L"%hs(%d): %hs: ", pszFileName, nLineNumber, pszFunctionName);
99                nTextLength += vswprintf_s(pszText + nTextLength, _countof(pszText) - nTextLength, pszFormat, Arguments);
100                #if defined(_TRACESUFFIX) && _TRACESUFFIX > 0
101                        CString sText(pszText);
102                        OutputDebugString(ApplyTraceSuffix(sText));
103                #else
104                        OutputDebugStringA(pszText);
105                #endif // defined(_TRACESUFFIX)
106        }
107
108public:
109// CDebugTrace
110        CDebugTrace(LPCSTR pszFileName, INT nLineNumber, LPCSTR pszFunctionName) :
111                m_pszFileName(pszFileName),
112                m_nLineNumber(nLineNumber),
113                m_pszFunctionName(pszFunctionName)
114        {
115        }
116        __forceinline VOID __cdecl operator () (DWORD_PTR nCategory, UINT nLevel, LPCSTR pszFormat, ...)
117        {
118                #if defined(_DEBUG)
119                        if(!nCategory)
120                                return;
121                #endif // defined(_DEBUG)
122                if(nLevel > _TRACELEVEL)
123                        return;
124                va_list Arguments;
125                va_start(Arguments, pszFormat);
126                __try
127                {
128                        TraceV(m_pszFileName, m_nLineNumber, m_pszFunctionName, nCategory, nLevel, pszFormat, Arguments);
129                }
130                __except(EXCEPTION_EXECUTE_HANDLER)
131                {
132                }
133                va_end(Arguments);
134        }
135        __forceinline VOID __cdecl operator () (LPCSTR pszFormat, ...)
136        {
137                //#if defined(_DEBUG)
138                //      if(!nCategory)
139                //              return;
140                //#endif // defined(_DEBUG)
141                //if(nLevel > _TRACELEVEL)
142                //      return;
143                va_list Arguments;
144                va_start(Arguments, pszFormat);
145                __try
146                {
147                        static const DWORD_PTR g_nCategory = 1;
148                        static const DWORD_PTR g_nLevel = 2;
149                        TraceV(m_pszFileName, m_nLineNumber, m_pszFunctionName, g_nCategory, g_nLevel, pszFormat, Arguments);
150                }
151                __except(EXCEPTION_EXECUTE_HANDLER)
152                {
153                }
154                va_end(Arguments);
155        }
156        __forceinline VOID __cdecl operator () (DWORD_PTR nCategory, UINT nLevel, LPCWSTR pszFormat, ...)
157        {
158                #if defined(_DEBUG)
159                        if(!nCategory)
160                                return;
161                #endif // defined(_DEBUG)
162                if(nLevel > _TRACELEVEL)
163                        return;
164                va_list Arguments;
165                va_start(Arguments, pszFormat);
166                __try
167                {
168                        TraceV(m_pszFileName, m_nLineNumber, m_pszFunctionName, nCategory, nLevel, pszFormat, Arguments);
169                }
170                __except(EXCEPTION_EXECUTE_HANDLER)
171                {
172                }
173                va_end(Arguments);
174        }
175        __forceinline VOID __cdecl operator () (LPCWSTR pszFormat, ...)
176        {
177                //#if defined(_DEBUG)
178                //      if(!nCategory)
179                //              return;
180                //#endif // defined(_DEBUG)
181                //if(nLevel > _TRACELEVEL)
182                //      return;
183                va_list Arguments;
184                va_start(Arguments, pszFormat);
185                __try
186                {
187                        static const DWORD_PTR g_nCategory = 1;
188                        static const DWORD_PTR g_nLevel = 2;
189                        TraceV(m_pszFileName, m_nLineNumber, m_pszFunctionName, g_nCategory, g_nLevel, pszFormat, Arguments);
190                }
191                __except(EXCEPTION_EXECUTE_HANDLER)
192                {
193                }
194                va_end(Arguments);
195        }
196};
197
198#undef ATLTRACE
199#undef ATLTRACE2
200#define ATLTRACE        CDebugTrace(__FILE__, __LINE__, __FUNCTION__)
201#define ATLTRACE2       ATLTRACE
202
203#define _Z                      ATLTRACE
204#define _Z0                     ATLTRACE
205#define _Z1                     ATLTRACE
206#define _Z2                     ATLTRACE
207#define _Z3                     ATLTRACE
208#define _Z4                     ATLTRACE
209#define _Z5                     ATLTRACE
210#define _Z6                     ATLTRACE
211
212////////////////////////////////////////////////////////////
213// ATLASSERT, ATLVERIFY
214
215__forceinline VOID AtlAssert(BOOL bResult, LPCSTR pszFile, INT nLine, LPCSTR pszFunction, LPCSTR pszExpression)
216{ 
217        if(bResult)
218                return;
219        _ATLTRY
220        { 
221                _Z1(atlTraceException, 1, _T("Assertion failed: %hs\n") _T("%hs(%d): Assertion failed in function %hs\n"), pszExpression, pszFile, nLine, pszFunction); 
222                AtlThrow(E_FAIL); 
223        }
224        _ATLCATCHALL() 
225        {
226        } 
227}
228
229#undef ATLASSERT
230#undef ATLVERIFY
231#define ATLASSERT(x)    AtlAssert((x) != 0, __FILE__, __LINE__, __FUNCTION__, #x);
232#define ATLVERIFY(x)    ATLASSERT(x)
233
234#define _A              ATLASSERT
235#define _W              ATLVERIFY
236
237#undef _ASSERT
238#define _ASSERT ATLASSERT
239
240////////////////////////////////////////////////////////////
241// CDebugTraceContext
242
243class CDebugTraceContext :
244        public CDebugTraceBase
245{
246private:
247        LPCSTR m_pszFileName;
248        INT m_nLineNumber;
249        LPCSTR m_pszFunctionName;
250        CString m_sText;
251        BOOL m_bTerminated;
252
253public:
254// CDebugTraceContext
255        CDebugTraceContext(LPCSTR pszFileName, INT nLineNumber, LPCSTR pszFunctionName) :
256                m_pszFileName(pszFileName),
257                m_nLineNumber(nLineNumber),
258                m_pszFunctionName(pszFunctionName),
259                m_bTerminated(FALSE)
260        {
261        }
262        ~CDebugTraceContext()
263        {
264                if(!m_bTerminated)
265                {
266                        CString sText;
267                        sText.Format(_T("%hs(%d): %hs: Context not terminated"), ShortFileNameFromFileName(m_pszFileName), m_nLineNumber, m_pszFunctionName);
268                        if(!m_sText.IsEmpty())
269                                sText.AppendFormat(_T(", %s"), m_sText);
270                        OutputDebugString(ApplyTraceSuffix(sText));
271                }
272        }
273        VOID Terminate()
274        {
275                m_bTerminated = TRUE;
276        }
277        __forceinline VOID __cdecl operator () (LPCSTR pszFormat, ...)
278        {
279                va_list Arguments;
280                va_start(Arguments, pszFormat);
281                CStringA sText;
282                sText.FormatV(pszFormat, Arguments);
283                m_sText.Append(CString(sText));
284                va_end(Arguments);
285        }
286        __forceinline VOID __cdecl operator () (LPCWSTR pszFormat, ...)
287        {
288                va_list Arguments;
289                va_start(Arguments, pszFormat);
290                CStringW sText;
291                sText.FormatV(pszFormat, Arguments);
292                m_sText.Append(CString(sText));
293                va_end(Arguments);
294        }
295};
296
297#undef _Y1
298#undef _Y2
299#define _Y1     CDebugTraceContext DebugTraceContext(__FILE__, __LINE__, __FUNCTION__); DebugTraceContext
300#define _Y2 DebugTraceContext.Terminate
Note: See TracBrowser for help on using the repository browser.