OWLNext    7.0
Borland's Object Windows Library for the modern age
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages
checks.h
Go to the documentation of this file.
1//----------------------------------------------------------------------------
2// ObjectWindows
3// Copyright (C) 1993, 1996 by Borland International, All Rights Reserved
4//
5/// \file
6/// Diagnostic macros for assertions and tracing
7/// \note
8/// The macros are controlled by the following switches:
9///
10/// __DEBUG = 0 PRECONDITION and CHECK are nops
11/// __DEBUG = 1 PRECONDITION is active
12/// __DEBUG = 2 PRECONDITION and CHECK are active
13/// __TRACE When defined enables TRACE
14/// __WARN When defined enables WARN
15//----------------------------------------------------------------------------
16
17#if !defined(OWL_PRIVATE_CHECKS_H)
18#define OWL_PRIVATE_CHECKS_H
19#define SERVICES_CHECKS_H //this file replaces old <services/checks.h>
20
21#include <owl/private/defs.h>
22#if defined(BI_HAS_PRAGMA_ONCE)
23# pragma once
24#endif
25
26#include <owl/exbase.h>
27#include <owl/private/except.h>
29
30namespace owl {
31
32#include <owl/preclass.h>
33
34class _OWLCLASS TDiagBase;
35class _OWLCLASS TModule;
36class _OWLCLASS TDiagFunction;
37
38typedef tostringstream diag_stream; // deprecated - not in use
39typedef tstring diag_string; // deprecated - not in use
40
41//
42// Static Global Redirector
43//
45{
46 virtual void Output(TDiagBase* group, LPCTSTR str) = 0;
47};
48
49//
50// TDiagBase - this class forms the base for TDiagGroup classes and handles basic message output.
51//
53{
54 public:
55
56 virtual ~TDiagBase();
57
58 void Trace(const tstring& msg, int level, LPCSTR file, int line);
59 void Warn(const tstring& msg, int level, LPCSTR file, int line);
60 LPCSTR GetName() const {return Name;}
61 void Enable(bool enable = true) {Enabled = enable;}
62 bool IsEnabled() const {return Enabled;}
63 void SetLevel(int level) {Level = level;}
64 int GetLevel() const {return Level;}
65 void SetLocalHook(TDiagBaseHook* hook) {LocalHook = hook;}
66
67 virtual TModule* GetDiagModule() = 0;
68 static TDiagBase* GetDiagGroup(TDiagBase* curr = nullptr);
69 static TDiagBaseHook* SetGlobalHook(TDiagBaseHook* hook = nullptr);
70
71 protected:
72
73 //
74 // Name have to be static string (i.e. we store the pointer, not a string copy).
75 //
76 TDiagBase(LPCSTR name, bool enable, int level);
77
78 protected:
79
81 bool Enabled;
82 int Level;
83 TDiagBaseHook* LocalHook; // second redirector
84
85 private:
86
87 TDiagBase* NextGroup;
88
89 void Message(LPCSTR type, const tstring& msg, int level, LPCSTR file, int line);
90 void Output(const tstring& msg);
91
92 static void AddDiagGroup(TDiagBase* group);
93 static void RemoveDiagGroup(TDiagBase* group);
94
95 //
96 // Prohibit copying
97 //
98 TDiagBase(const TDiagBase& base);
99 TDiagBase& operator=(const TDiagBase& base);
100
101 friend class TDiagFunction;
102};
103
104//
105// TraceFunction - idea from Don Griffin
106//
108{
109 public:
110
114
115 private:
116
117 TDiagBase& Group;
118 int Level;
119 LPCTSTR Function;
120 LPCSTR File;
121 int Line;
122 bool Enabled;
123
124 void Trace(LPCTSTR prefix, LPCTSTR param);
125
126 //
127 // Prohibit copying
128 //
129 TDiagFunction(const TDiagFunction& f); // prohibite
130 TDiagFunction& operator=(const TDiagFunction& f); // prohibite
131};
132
133//
134// Base class for assertion failures
135// We need UTF8 conversion functionality here, same as in TXBase.
136// But we don't want to be a derivative of TXBase, since we want diagnostics
137// exceptions to be separate from the other framework exceptions.
138// While we could factor out the shared functionality in TXBase to a new
139// base, instead we use TXBase as a delegate here.
140//
142 : public std::exception
143{
144 public:
145
146 TDiagException(LPCSTR type, const tstring& msg, LPCSTR file, int line);
147
148 static tstring ToString(LPCSTR s);
149 static int BreakMessage(LPCSTR type, const tstring& msg, LPCSTR file, int line);
150
151 virtual const char* what() const noexcept;
152 virtual tstring why() const;
153
154 protected:
155
156 TXBase delegate; // Holds UTF8 string and implements 'what' and 'why' for us.
157
158};
159
160//
161// Signals a failure of a PRECONDITION macro.
162//
164 : public TDiagException
165{
166 public:
167
168 TPreconditionFailure(const tstring& msg, LPCSTR file, int line);
169};
170
171//
172// Signals a failure of a CHECK macro.
173//
175 : public TDiagException
176{
177 public:
178
179 TCheckFailure(const tstring& msg, LPCSTR file, int line);
180};
181
182#include <owl/posclass.h>
183
184//
185/// Retrieves a diagnostic group's enabled flag from a private ini-file.
186/// The master enable switch 'Enabled' overrides individual group settings.
187/// The ini-file is searched for in standard profile places.
188//
190
191//
192/// Retrieves a diagnostic group's level setting from a private ini-file.
193/// The ini-file is searched for in standard profile places.
194//
196
197} // OWL namespace
198
199//
200// Macro definitions section
201//
202
203#if !defined(__DEBUG)
204# define __DEBUG 0
205#endif
206
207#if __DEBUG < 1
208# define IFDBG(a)
209# define IFNDBG(a) a
210# ifndef NDEBUG
211# define NDEBUG
212# endif
213# define VALIDPTR(p) ((p) != 0) // This is faster than IsBadReadPtr.
214#else
215# define IFDBG(a) a
216# define IFNDBG(a)
217# define VALIDPTR(p) (!::IsBadReadPtr((p),1))
218#endif
219
220#define VALIDORNULLPTR(p) (!(p) || VALIDPTR(p))
221
222//
223// Definitions of precondition macros
224//
225#undef PRECONDITION
226#undef PRECONDITIONX
227#define PRECONDITION(condition) PRECONDITIONX(condition, ::owl::TDiagException::ToString(#condition))
228#if __DEBUG >= 1
229# define PRECONDITIONX(condition, message) DIAG_ASSERT_IMPL(Precondition, condition, message)
230#else
231# define PRECONDITIONX(condition, message) ((void)0)
232#endif
233
234//
235// Definitions of check macros
236//
237#undef CHECK
238#undef CHECKX
239#define CHECK(condition) CHECKX(condition, ::owl::TDiagException::ToString(#condition))
240#if __DEBUG >= 2
241# define CHECKX(condition, message) DIAG_ASSERT_IMPL(Check, condition, message)
242# define VERIFY(condition) CHECK(condition)
243# define VERIFYX(condition, message) CHECKX(condition, message)
244#else
245# define CHECKX(condition, message) ((void)0)
246# define VERIFY(condition) ((void)(condition))
247# define VERIFYX(condition, message) ((void)(condition))
248#endif
249
250//
251// Definition of trace macros
252//
253#undef TRACE
254#undef TRACEX
255#define TRACE(message) TRACEX(Def, 0, message)
256#define TRACE_FUNCTION(function) TRACE_FUNCTIONX(Def, 0, function)
257#define TRACE_FUNCTIONP(function, condition) TRACE_FUNCTIONXP(Def, 0, function, condition)
258#if defined(__TRACE)
259# define TRACEX(group, level, message) DIAG_TRACE_IMPL(Trace, group, true, level, message)
260# define TRACE_FUNCTIONX(group, level, function) ::owl::TDiagFunction __traceFunc((::owl::TDiagBase&)__OwlDiagGroup##group, level, function, __FILE__, __LINE__)
261# define TRACE_FUNCTIONXP(group, level, function, condition) ::owl::TDiagFunction __traceFunc((::owl::TDiagBase&)__OwlDiagGroup##group, level, function, condition, __FILE__, __LINE__)
262#else
263# define TRACEX(group, level, message) ((void)0)
264# define TRACE_FUNCTIONX(group, level, function) ((void)0)
265# define TRACE_FUNCTIONXP(group, level, function, condition) ((void)0)
266#endif
267
268//
269// Definition of warning macros
270//
271#undef WARN
272#undef WARNX
273#define WARN(condition, message) WARNX(Def, condition, 0, message)
274#if defined(__WARN)
275# define WARNX(group, condition, level, message) DIAG_TRACE_IMPL(Warn, group, condition, level, message)
276#else
277# define WARNX(group, condition, level, message) ((void)0)
278#endif
279
280//
281// Alternative names
282//
283#define TRACEX_IF(condition, group, level, message) WARNX(group, condition, level, message)
284#define TRACE_IF(condition, message) WARNX(Def, condition, 0, message)
285
286//
287// Implmentation macro for PRECONDITION and CHECK
288//
289#define DIAG_ASSERT_IMPL(assertion, condition, message)\
290 if (!(condition)) {\
291 int retval = ::owl::TDiagException::BreakMessage(#assertion, message, __FILE__, __LINE__);\
292 if (retval == IDRETRY)\
293 {OWL_BREAK}\
294 else if (retval == IDABORT)\
295 {throw ::owl::T##assertion##Failure(message, __FILE__, __LINE__);}\
296 }
297
298//
299// Implmentation macro for WARN and TRACE
300//
301#define DIAG_TRACE_IMPL(operation, group, condition, level, message)\
302 do {\
303 using namespace ::owl;\
304 if (__OwlDiagGroup##group.IsEnabled() && level <= __OwlDiagGroup##group.GetLevel() && (condition)) {\
305 tostringstream out; out << message;\
306 __OwlDiagGroup##group.operation(out.str(), level, __FILE__, __LINE__);\
307 }\
308 } while (false)
309
310//
311// Definitions of diagnostics group macros
312//
313#if defined(__TRACE) || defined(__WARN)
314
315#if defined(_OWLDLL) || defined(_BUILDOWLDLL)
316# if !defined(DIAG_IMPORT)
317# define DIAG_IMPORT __declspec(dllimport)
318# endif
319# if !defined(DIAG_EXPORT)
320# define DIAG_EXPORT __declspec(dllexport)
321# endif
322#else
323# define DIAG_IMPORT /**/
324# define DIAG_EXPORT /**/
325#endif
326
327#define DECLARE_DIAG_GROUP_COMMON(group)\
328 public:\
329 TDiagGroup##group(LPCSTR name, bool enable, int level);\
330 virtual ::owl::TModule* GetDiagModule();\
331 }
332
333#define DECLARE_DIAG_GROUP(group, qual)\
334 class qual TDiagGroup##group : public ::owl::TDiagBase {\
335 DECLARE_DIAG_GROUP_COMMON(group)
336
337#define DECLARE_DIAG_STATIC_GROUP(group)\
338 class TDiagGroup##group : public ::owl::TDiagBase {\
339 DECLARE_DIAG_GROUP_COMMON(group)
340
341#define DIAG_DEFINE_GROUP_COMMON(group)\
342 TDiagGroup##group::TDiagGroup##group(LPCSTR name,bool enable, int level) : ::owl::TDiagBase(name, enable, level) {}\
343 ::owl::TModule* TDiagGroup##group::GetDiagModule() {return &::owl::GetGlobalModule();}
344
345#define _DIAG_DEFINE_GROUP_(group, enable, level, t)\
346 DECLARE_DIAG_GROUP(group, t);\
347 DIAG_DEFINE_GROUP_COMMON(group)
348
349#define _DIAG_DEFINE_GROUP_STATIC(group, enable, level)\
350 DECLARE_DIAG_STATIC_GROUP(group);\
351 DIAG_DEFINE_GROUP_COMMON(group);\
352 TDiagGroup##group __OwlDiagGroup##group(#group, enable, level)
353
354//
355// DLN: Define OwlDiagGroupDef without redefining TDiagGroupDef.
356//
357#define OWL_DIAG_DEFINE_GROUP(group, enable, level) \
358 DIAG_DEFINE_GROUP_COMMON(group); \
359 TDiagGroup##group __OwlDiagGroup##group(#group, enable, level)
360
361#define DIAG_DECLARE_GROUP(group)\
362 DECLARE_DIAG_STATIC_GROUP(group);\
363 extern TDiagGroup##group __OwlDiagGroup##group
364
365#define DIAG_DEFINE_GROUP(group, enable, level)\
366 _DIAG_DEFINE_GROUP_STATIC(group, enable, level);
367
368#define DIAG_DECLARE_EXPORTGROUP(group)\
369 DECLARE_DIAG_GROUP(group, DIAG_EXPORT);\
370 extern _OWLEXPORTDATA(TDiagGroup##group) __OwlDiagGroup##group
371
372#define DIAG_DECLARE_IMPORTTGROUP(group)\
373 DECLARE_DIAG_GROUP(group, DIAG_IMPORT);\
374 extern _OWLIMPORTDATA(TDiagGroup##group) __OwlDiagGroup##group
375
376//
377// JJH: Define group for winelib export macro without redefining TDiagGroupDef
378//
379#define OWL_DIAG_DEFINE_EXPORTGROUP(group, enable, level)\
380 DIAG_DEFINE_GROUP_COMMON(group)\
381 _OWLEXPORTDATA(TDiagGroup##group) __OwlDiagGroup##group(#group, enable, level)
382
383#define DIAG_DEFINE_EXPORTGROUP(group, enable, level)\
384 _DIAG_DEFINE_GROUP_(group, enable, level, DIAG_EXPORT);\
385 _OWLEXPORTDATA(TDiagGroup##group) __OwlDiagGroup##group(#group, enable, level)
386
387//
388// Definitions of group accessors and mutators macros
389//
390#define DIAG_ENABLE(group, s) __OwlDiagGroup##group.Enable(s)
391#define DIAG_ISENABLED(group) __OwlDiagGroup##group.IsEnabled()
392#define DIAG_SETLEVEL(group, level) __OwlDiagGroup##group.SetLevel(level)
393#define DIAG_GETLEVEL(group) __OwlDiagGroup##group.GetLevel()
394#define DIAG_REDIRECT(group, s) __OwlDiagGroup##group.SetLocalHook(s)
395
396//
397// Definitions of utility macros
398//
399#define IFDIAG(a) a
400#define IFNDIAG(a)
401
402#else // #if defined(__TRACE) | defined(__WARN)
403
404#define DIAG_DECLARE_GROUP(group)
405#define DIAG_DECLARE_EXPORTGROUP(group)
406#define DIAG_DECLARE_IMPORTTGROUP(group)
407
408#define DIAG_DEFINE_GROUP(group,enable,level)
409#define OWL_DIAG_DEFINE_GROUP(group,enable,level)
410#define DIAG_DEFINE_EXPORTGROUP(group,enable,level)
411
412#define DIAG_ENABLE(group,s) ((void)0)
413#define DIAG_ISENABLED(group) ((void)0)
414#define DIAG_SETLEVEL(group,level) ((void)0)
415#define DIAG_GETLEVEL(group) ((void)0)
416#define DIAG_REDIRECT(group,s) ((void)0)
417
418#define IFDIAG(a)
419#define IFNDIAG(a) a
420
421#endif // #if defined(__TRACE) | defined(__WARN)
422
423//
424// Define without redefining TDiagGroupDef.
425//
426#define OWL_DIAG_DEFINE_GROUP_INIT(f,g,e,l)\
427 OWL_DIAG_DEFINE_GROUP(g, ::owl::GetDiagEnabled(f,#g,e), ::owl::GetDiagLevel(f,#g,l));
428
429#define DIAG_DEFINE_GROUP_INIT(f,g,e,l)\
430 DIAG_DEFINE_GROUP(g, ::owl::GetDiagEnabled(f,#g,e), ::owl::GetDiagLevel(f,#g,l));
431
432#define OWL_DIAG_DEFINE_EXPORTGROUP_INIT(f,g,e,l)\
433 OWL_DIAG_DEFINE_EXPORTGROUP(g, ::owl::GetDiagEnabled(f,#g,e), ::owl::GetDiagLevel(f,#g,l));
434
435#define DIAG_DEFINE_EXPORTGROUP_INIT(f,g,e,l)\
436 DIAG_DEFINE_EXPORTGROUP(g, ::owl::GetDiagEnabled(f,#g,e), ::owl::GetDiagLevel(f,#g,l));
437//
438// Declaration of the Def default group
439//
440#if (defined(__TRACE) || defined(__WARN)) && !defined(_DONT_DECLARE_DEF_DIAG_GROUP) && !defined(_DEF_DECLARED)
441namespace owl {
442# define _DEF_DECLARED
443# if defined(_BUILDOWLDLL)
445# elif defined(_OWLDLL)
447# else
449# endif
450} // OWL namespace
451#endif
452
453//
454// Diagnostics helpers
455//
456
457#if defined(__TRACE) || defined(__WARN)
458
459namespace owl {
460
461//
462/// An object of this class, when streamed out, logs the contained type name.
463//
464template <class T>
465struct TTraceType
466{
467 friend tostream& operator <<(tostream& os, const TTraceType& t)
468 {return os << typeid(T).name();}
469};
470
471//
472/// Returns an object that, when streamed out, logs the pointee static type.
473///
474/// Usage:
475/// \code
476/// template <class T> void Foo() {TRACE("T type: " << TraceType<T>());}
477/// \endcode
478//
479template <class T>
480static TTraceType<T> TraceType(T* p = 0)
481{
482 InUse(p);
483 return TTraceType<T>();
484}
485
486//
487/// An object of this class, when streamed out, logs the contained pointee type and pointer value.
488//
489template <class T>
490struct TTraceId
491{
492 T* p;
493 TTraceId(T* p_) : p(p_) {}
494
495 friend tostream& operator <<(tostream& os, const TTraceId& id)
496 {return os << TraceType(id.p) << " [" << static_cast<void*>(id.p) << "]";}
497};
498
499//
500/// Returns an object that, when streamed out, logs the pointee type and pointer value.
501///
502/// Usage:
503/// \code
504/// void Foo(Bar* p) {TRACE("Foo received pointer to " << TraceId(p));}
505/// \endcode
506//
507template <class T>
508static TTraceId<T> TraceId(T* p)
509{return TTraceId<T>(p);}
510
511} // OWL namespace
512
513#endif
514
515#endif // OWL_PRIVATE_CHECKS_H
#define DIAG_DECLARE_GROUP(group)
Definition checks.h:404
#define DIAG_DECLARE_EXPORTGROUP(group)
Definition checks.h:405
#define DIAG_DECLARE_IMPORTTGROUP(group)
Definition checks.h:406
bool Enabled
Definition checks.h:81
TDiagBaseHook * LocalHook
Definition checks.h:83
bool IsEnabled() const
Definition checks.h:62
void Enable(bool enable=true)
Definition checks.h:61
LPCSTR GetName() const
Definition checks.h:60
LPCSTR Name
Definition checks.h:80
void SetLocalHook(TDiagBaseHook *hook)
Definition checks.h:65
int GetLevel() const
Definition checks.h:64
void SetLevel(int level)
Definition checks.h:63
virtual TModule * GetDiagModule()=0
ObjectWindows dynamic-link libraries (DLLs) construct an instance of TModule, which acts as an object...
Definition module.h:75
Derived from xmsg, TXBase is the base class for ObjectWindows and ObjectComponents exception-handling...
Definition exbase.h:41
Base exception support for framework exceptions.
Object Windows Library (OWLNext Core)
Definition animctrl.h:22
std::ostringstream tostringstream
Definition strmdefs.h:36
bool GetDiagEnabled(LPCSTR filename, LPCSTR diagGroup, bool defEnabled)
Retrieves a diagnostic group's enabled flag from a private ini-file.
Definition diaginit.cpp:93
tstring diag_string
Definition checks.h:39
void InUse(const T &arg)
Handy utility to avoid compiler warnings about unused parameters.
Definition defs.h:299
std::string tstring
Definition defs.h:79
tostringstream diag_stream
Definition checks.h:38
std::ostream tostream
Definition strmdefs.h:40
int GetDiagLevel(LPCSTR filename, LPCSTR diagGroup, int defLevel)
Retrieves a diagnostic group's level setting from a private ini-file.
Definition diaginit.cpp:106
#define _OWLFUNC(p)
Definition defs.h:341
#define _OWLCLASS
Definition defs.h:338
virtual void Output(TDiagBase *group, LPCTSTR str)=0