OWLNext    7.0
Borland's Object Windows Library for the modern age
Loading...
Searching...
No Matches
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