ReactOS 0.4.16-dev-338-g34e76ad
atltrace.h
Go to the documentation of this file.
1/*
2 * PROJECT: ReactOS ATL
3 * LICENSE: LGPL-2.0-or-later (https://spdx.org/licenses/LGPL-2.0-or-later)
4 * PURPOSE: Providing ATLTRACE macro
5 * COPYRIGHT: Copyright 2022 Katayama Hirofumi MZ <katayama.hirofumi.mz@gmail.com>
6 */
7
8#pragma once
9
10#include "atldef.h"
11
12#ifdef _DEBUG
13
14#include <stdio.h>
15#include <crtdbg.h>
16
17namespace ATL
18{
19
20template <UINT t_category = (1 << 19), UINT t_level = 0>
21class CTraceCategoryEx
22{
23public:
24 enum
25 {
26 TraceGeneral = (1 << 0),
27 TraceCom = (1 << 1),
28 TraceQI = (1 << 2),
29 TraceRegistrar = (1 << 3),
30 TraceRefcount = (1 << 4),
31 TraceWindowing = (1 << 5),
32 TraceControls = (1 << 6),
33 TraceHosting = (1 << 7),
34 TraceDBClient = (1 << 8),
35 TraceDBProvider = (1 << 9),
36 TraceSnapin = (1 << 10),
37 TraceNotImpl = (1 << 11),
38 TraceAllocation = (1 << 12),
39 TraceException = (1 << 13),
40 TraceTime = (1 << 14),
41 TraceCache = (1 << 15),
42 TraceStencil = (1 << 16),
43 TraceString = (1 << 17),
44 TraceMap = (1 << 18),
45 TraceUtil = (1 << 19),
46 TraceSecurity = (1 << 20),
47 TraceSync = (1 << 21),
48 TraceISAPI = (1 << 22),
49 TraceUser = TraceUtil
50 };
51
52 CTraceCategoryEx(LPCTSTR name = NULL) : m_name(name)
53 {
54 }
55
56 static UINT GetLevel() { return t_level; }
57 static UINT GetCategory() { return t_category; }
58 operator UINT() const { return GetCategory(); }
59 LPCTSTR GetCategoryName() const { return m_name; }
60
61protected:
62 LPCTSTR m_name;
63};
64
65class CTraceCategory : public CTraceCategoryEx<>
66{
67 CTraceCategory(LPCTSTR name = NULL) : CTraceCategoryEx<>(name)
68 {
69 }
70};
71
72#define DEFINE_TRACE_CATEGORY(name, cat) extern const DECLSPEC_SELECTANY CTraceCategoryEx<cat, 0> name(TEXT(#name))
73DEFINE_TRACE_CATEGORY(atlTraceGeneral, CTraceCategoryEx<>::TraceGeneral);
74DEFINE_TRACE_CATEGORY(atlTraceCOM, CTraceCategoryEx<>::TraceCom);
75DEFINE_TRACE_CATEGORY(atlTraceQI, CTraceCategoryEx<>::TraceQI);
76DEFINE_TRACE_CATEGORY(atlTraceRegistrar, CTraceCategoryEx<>::TraceRegistrar);
77DEFINE_TRACE_CATEGORY(atlTraceRefcount, CTraceCategoryEx<>::TraceRefcount);
78DEFINE_TRACE_CATEGORY(atlTraceWindowing, CTraceCategoryEx<>::TraceWindowing);
79DEFINE_TRACE_CATEGORY(atlTraceControls, CTraceCategoryEx<>::TraceControls);
80DEFINE_TRACE_CATEGORY(atlTraceHosting, CTraceCategoryEx<>::TraceHosting);
81DEFINE_TRACE_CATEGORY(atlTraceDBClient, CTraceCategoryEx<>::TraceDBClient);
82DEFINE_TRACE_CATEGORY(atlTraceDBProvider, CTraceCategoryEx<>::TraceDBProvider);
83DEFINE_TRACE_CATEGORY(atlTraceSnapin, CTraceCategoryEx<>::TraceSnapin);
84DEFINE_TRACE_CATEGORY(atlTraceNotImpl, CTraceCategoryEx<>::TraceNotImpl);
85DEFINE_TRACE_CATEGORY(atlTraceAllocation, CTraceCategoryEx<>::TraceAllocation);
86DEFINE_TRACE_CATEGORY(atlTraceException, CTraceCategoryEx<>::TraceException);
87DEFINE_TRACE_CATEGORY(atlTraceTime, CTraceCategoryEx<>::TraceTime);
88DEFINE_TRACE_CATEGORY(atlTraceCache, CTraceCategoryEx<>::TraceCache);
89DEFINE_TRACE_CATEGORY(atlTraceStencil, CTraceCategoryEx<>::TraceStencil);
90DEFINE_TRACE_CATEGORY(atlTraceString, CTraceCategoryEx<>::TraceString);
91DEFINE_TRACE_CATEGORY(atlTraceMap, CTraceCategoryEx<>::TraceMap);
92DEFINE_TRACE_CATEGORY(atlTraceUtil, CTraceCategoryEx<>::TraceUtil);
93DEFINE_TRACE_CATEGORY(atlTraceSecurity, CTraceCategoryEx<>::TraceSecurity);
94DEFINE_TRACE_CATEGORY(atlTraceSync, CTraceCategoryEx<>::TraceSync);
95DEFINE_TRACE_CATEGORY(atlTraceISAPI, CTraceCategoryEx<>::TraceISAPI);
96#undef DEFINE_TRACE_CATEGORY
97
98struct CTraceCategoryEasy
99{
100 UINT m_category;
101 UINT m_level;
102 LPCTSTR m_name;
103
104 template <UINT t_category, UINT t_level>
105 CTraceCategoryEasy(const CTraceCategoryEx<t_category, t_level>& cat)
106 {
107 m_category = t_category;
108 m_level = t_level;
109 m_name = cat.GetCategoryName();
110 }
111
112 operator UINT() const { return m_category; }
113
114 BOOL IsGeneral() const
115 {
116 return lstrcmp(m_name, TEXT("atlTraceGeneral")) == 0;
117 }
118};
119
120struct CTrace
121{
122 enum
123 {
124 DefaultTraceLevel = 0,
125 DisableTracing = 0xFFFFFFFF,
126 EnableAllCategories = 0xFFFFFFFF
127 };
128
129 static UINT GetLevel() { return s_level; }
130 static UINT GetCategories() { return s_categories; }
131 static void SetLevel(UINT level) { s_level = level; }
132 static void SetCategories(UINT categories) { s_categories = categories; }
133
134 static bool IsTracingEnabled(UINT category, UINT level)
135 {
136 return (s_level != DisableTracing && s_level >= level && (s_categories & category));
137 }
138
139protected:
140 static UINT s_categories;
141 static UINT s_level;
142};
143
144DECLSPEC_SELECTANY UINT CTrace::s_categories = CTrace::EnableAllCategories;
145DECLSPEC_SELECTANY UINT CTrace::s_level = CTrace::DefaultTraceLevel;
146
147template <typename X_CHAR>
148inline VOID __stdcall
149AtlTraceV(_In_opt_z_ const X_CHAR * file,
150 _In_ INT line,
151 _In_ const CTraceCategoryEasy& cat,
154 _In_ va_list va)
155{
156 char szBuff[1024], szFile[MAX_PATH];
157 size_t cch = 0;
158 const BOOL bUnicode = (sizeof(TCHAR) == 2);
159
160 if (!CTrace::IsTracingEnabled(cat, level))
161 return;
162
163#ifdef _STRSAFE_H_INCLUDED_
164 StringCchPrintfA(szFile, _countof(szFile), ((sizeof(X_CHAR) == 2) ? "%ls" : "%hs"), file);
165 if (!cat.IsGeneral())
166 {
167 StringCchPrintfA(szBuff, _countof(szBuff), (bUnicode ? "%ls - " : "%hs - "), cat.m_name);
168 StringCchLengthA(szBuff, _countof(szBuff), &cch);
169 }
170 StringCchVPrintfA(&szBuff[cch], _countof(szBuff) - cch, format, va);
171#else
172 _snprintf(szFile, _countof(szFile), ((sizeof(X_CHAR) == 2) ? "%ls" : "%hs"), file);
173 if (!cat.IsGeneral())
174 cch = _snprintf(szBuff, _countof(szBuff), (bUnicode ? "%ls - " : "%hs - "), cat.m_name);
175 _vsnprintf(&szBuff[cch], _countof(szBuff) - cch, format, va);
176#endif
177
178 _CrtDbgReport(_CRT_WARN, szFile, line, NULL, "%hs", szBuff);
179}
180
181template <typename X_CHAR>
182inline VOID __stdcall
183AtlTraceV(_In_opt_z_ const X_CHAR * file,
184 _In_ INT line,
185 _In_ const CTraceCategoryEasy& cat,
188 _In_ va_list va)
189{
190 WCHAR szBuff[1024], szFile[MAX_PATH];
191 size_t cch = 0;
192 const BOOL bUnicode = (sizeof(TCHAR) == 2);
193
194 if (!CTrace::IsTracingEnabled(cat, level))
195 return;
196
197#ifdef _STRSAFE_H_INCLUDED_
198 StringCchPrintfW(szFile, _countof(szFile), ((sizeof(X_CHAR) == 2) ? L"%ls" : L"%hs"), file);
199 if (!cat.IsGeneral())
200 {
201 StringCchPrintfW(szBuff, _countof(szBuff), (bUnicode ? L"%ls - " : L"%hs - "), cat.m_name);
202 StringCchLengthW(szBuff, _countof(szBuff), &cch);
203 }
204 StringCchVPrintfW(&szBuff[cch], _countof(szBuff) - cch, format, va);
205#else
206 _snwprintf(szFile, _countof(szFile), ((sizeof(X_CHAR) == 2) ? L"%ls" : L"%hs"), file);
207 if (!cat.IsGeneral())
208 cch = _snwprintf(szBuff, _countof(szBuff), (bUnicode ? L"%ls - " : L"%hs - "), cat.m_name);
209 _vsnwprintf(&szBuff[cch], _countof(szBuff) - cch, format, va);
210#endif
211
212 _CrtDbgReportW(_CRT_WARN, szFile, line, NULL, L"%ls", szBuff);
213}
214
215template <typename X_CHAR, typename Y_CHAR>
216inline VOID __cdecl
217AtlTraceEx(_In_opt_z_ const X_CHAR * file,
218 _In_ INT line,
219 _In_ const CTraceCategoryEasy& cat,
221 _In_z_ _Printf_format_string_ const Y_CHAR * format,
222 ...)
223{
224 va_list va;
225 va_start(va, format);
226 AtlTraceV(file, line, cat, level, format, va);
227 va_end(va);
228}
229
230template <typename X_CHAR, typename Y_CHAR>
231inline VOID __cdecl
232AtlTraceEx(_In_opt_z_ const X_CHAR *file,
233 _In_ INT line,
235 ...)
236{
237 va_list va;
238 va_start(va, format);
239 AtlTraceV(file, line, atlTraceGeneral, 0, format, va);
240 va_end(va);
241}
242
243inline VOID __stdcall
244AtlTraceEx(_In_opt_z_ PCTSTR file,
245 _In_ INT line,
247{
248 AtlTraceEx(file, line, TEXT("%ld (0x%lX)\n"), value, value);
249}
250
251template <typename X_CHAR>
252inline VOID __cdecl
253AtlTrace(_In_z_ _Printf_format_string_ const X_CHAR *format, ...)
254{
255 va_list va;
256 va_start(va, format);
257 AtlTraceV(NULL, -1, atlTraceGeneral, 0, format, va);
258 va_end(va);
259}
260
261} // namespace ATL
262
263#endif // _DEBUG
264
265#ifndef ATLTRACE
266 #ifdef _DEBUG
267 #define ATLTRACE(format, ...) ATL::AtlTraceEx(__FILE__, __LINE__, format, ##__VA_ARGS__)
268 #else
269 #define ATLTRACE(format, ...) ((void)0)
270 #endif
271#endif
272
273#define ATLTRACE2 ATLTRACE
274
275#ifdef _DEBUG
276 #define ATLTRACENOTIMPL(funcname) do { \
277 ATLTRACE(atlTraceNotImpl, 0, #funcname " is not implemented.\n"); \
278 return E_NOTIMPL; \
279 } while (0)
280#else
281 #define ATLTRACENOTIMPL(funcname) return E_NOTIMPL
282#endif
283
284#ifndef _ATL_NO_AUTOMATIC_NAMESPACE
285using namespace ATL;
286#endif
#define __cdecl
Definition: accygwin.h:79
char * va_list
Definition: acmsvcex.h:78
#define va_end(ap)
Definition: acmsvcex.h:90
#define va_start(ap, A)
Definition: acmsvcex.h:91
#define _CRT_WARN
Definition: crtdbg.h:19
EXTERN_C int __cdecl _CrtDbgReportW(int reportType, const wchar_t *filename, int linenumber, const wchar_t *moduleName, const wchar_t *format,...)
Definition: dbgrpt.cpp:483
EXTERN_C int __cdecl _CrtDbgReport(int reportType, const char *filename, int linenumber, const char *moduleName, const char *format,...)
Definition: dbgrpt.cpp:464
#define NULL
Definition: types.h:112
#define MAX_PATH
Definition: compat.h:34
unsigned int BOOL
Definition: ntddk_ex.h:94
unsigned long DWORD
Definition: ntddk_ex.h:95
GLint level
Definition: gl.h:1546
GLsizei GLenum * categories
Definition: glext.h:11561
_CRTIMP int __cdecl _vsnwprintf(wchar_t *_Dest, size_t _Count, const wchar_t *_Format, va_list _Args)
#define TEXT(s)
Definition: k32.h:26
int _snwprintf(wchar_t *buffer, size_t count, const wchar_t *format,...)
static DWORD DWORD void LPSTR DWORD cch
Definition: str.c:202
Definition: rosdlgs.h:6
unsigned int UINT
Definition: ndis.h:50
#define _In_z_
Definition: no_sal2.h:164
#define _In_opt_z_
Definition: no_sal2.h:218
#define _In_
Definition: no_sal2.h:158
#define _Printf_format_string_
Definition: no_sal2.h:356
LPCSTR PCTSTR
Definition: ntbasedef.h:496
#define L(x)
Definition: ntvdm.h:50
#define DECLSPEC_SELECTANY
Definition: guiddef.h:40
#define _countof(array)
Definition: sndvol32.h:70
STRSAFEAPI StringCchPrintfW(STRSAFE_LPWSTR pszDest, size_t cchDest, STRSAFE_LPCWSTR pszFormat,...)
Definition: strsafe.h:530
STRSAFEAPI StringCchLengthA(STRSAFE_LPCSTR psz, size_t cchMax, size_t *pcchLength)
Definition: strsafe.h:832
STRSAFEAPI StringCchVPrintfW(STRSAFE_LPWSTR pszDest, size_t cchDest, STRSAFE_LPCWSTR pszFormat, va_list argList)
Definition: strsafe.h:490
STRSAFEAPI StringCchLengthW(STRSAFE_LPCWSTR psz, size_t cchMax, size_t *pcchLength)
Definition: strsafe.h:842
STRSAFEAPI StringCchPrintfA(STRSAFE_LPSTR pszDest, size_t cchDest, STRSAFE_LPCSTR pszFormat,...)
Definition: strsafe.h:520
STRSAFEAPI StringCchVPrintfA(STRSAFE_LPSTR pszDest, size_t cchDest, STRSAFE_LPCSTR pszFormat, va_list argList)
Definition: strsafe.h:485
Definition: fci.c:127
Definition: format.c:58
Definition: parser.c:49
const uint16_t * PCWSTR
Definition: typedefs.h:57
int32_t INT
Definition: typedefs.h:58
#define __stdcall
Definition: typedefs.h:25
const char * PCSTR
Definition: typedefs.h:52
Definition: pdh_main.c:94
#define lstrcmp
Definition: winbase.h:3897
char TCHAR
Definition: xmlstorage.h:189
#define _vsnprintf
Definition: xmlstorage.h:202
__wchar_t WCHAR
Definition: xmlstorage.h:180
#define _snprintf
Definition: xmlstorage.h:200