7#if defined(BI_COMP_BORLANDC)
18# define __TRACE_PREVIOUSLY_DEFINED
24#if !defined(__TRACE_PREVIOUSLY_DEFINED)
25#define _DONT_DECLARE_DEF_DIAG_GROUP
30#if defined(BI_COMP_BORLANDC)
37# if defined(BI_COMP_GNUC)
44#if defined(BI_MULTI_THREAD_RTL)
56#if defined(_BUILDOWLDLL)
57# if defined(__DEBUG) && defined(__TRACE_PREVIOUSLY_DEFINED)
63# if defined(__DEBUG) && defined(__TRACE_PREVIOUSLY_DEFINED)
70struct TDiagProcessData
78 TDiagProcessData(
const TDiagProcessData&);
79 TDiagProcessData& operator =(
const TDiagProcessData&);
81 static TDiagProcessData& GetInstance()
97 static TDiagProcessData d;
101 static TDiagProcessData& InitDiagProcessDataInstance;
105#if defined(BI_MULTI_THREAD_RTL)
107 template <
class TData,
bool Shared>
115 explicit TLockT(TDiagProcessData& data = TDiagProcessData::GetInstance())
116 : TMRSWSection::TLock(data.
Section, Shared, true),
121 typedef TLockT<TDiagProcessData, false> TLock;
122 typedef TLockT<const TDiagProcessData, true> TConstLock;
124 template <
class TData,
bool Shared>
133 template <
class TData>
140 explicit TLockT(TDiagProcessData& data = TDiagProcessData::GetInstance())
145 typedef TLockT<TDiagProcessData> TLock;
146 typedef TLockT<const TDiagProcessData> TConstLock;
148 template <
class TData>
158TDiagProcessData& TDiagProcessData::InitDiagProcessDataInstance = TDiagProcessData::GetInstance();
163 Message(
"Trace", msg, level, fname, line);
169 Message(
"Warning", msg, level, fname, line);
175 TDiagProcessData::TLock lock;
177 lock.Data.GlobalHook = hook;
194 RemoveDiagGroup(
this);
200 TDiagProcessData::TLock lock;
201 if (lock.Data.DiagGroupStaticHead ==
nullptr)
202 lock.Data.DiagGroupStaticHead = group;
205 TDiagBase* last = lock.Data.DiagGroupStaticHead;
206 while (last->NextGroup)
207 last = last->NextGroup;
208 last->NextGroup = group;
213TDiagBase::RemoveDiagGroup(
TDiagBase* group)
215 TDiagProcessData::TLock lock;
216 if (lock.Data.DiagGroupStaticHead == group)
217 lock.Data.DiagGroupStaticHead = group->NextGroup;
220 TDiagBase* last = lock.Data.DiagGroupStaticHead;
221 while (last->NextGroup != group)
222 last = last->NextGroup;
223 last->NextGroup = group->NextGroup;
238 return curr->NextGroup;
240 TDiagProcessData::TConstLock lock;
241 return lock.Data.DiagGroupStaticHead;
250TDiagBase::Output(
const tstring& msg)
253 TDiagProcessData::TConstLock lock;
254 if (lock.Data.GlobalHook)
256 lock.Data.GlobalHook->
Output(
this, msg.c_str());
269TDiagBase::Message(LPCSTR type,
const tstring& msg,
int level, LPCSTR file,
int line)
273#if defined(BI_COMP_MSC)
274 out <<
_A2W(file) <<
_T(
"(");
275 out << line <<
_T(
") : ") <<
_A2W(type)
277 out <<
_A2W(type) <<
_T(
" ");
278 out <<
_A2W(file) <<
_T(
" ") << line
280 <<
_T(
": [") <<
Name <<
_T(
':') << level <<
_T(
"] ")
287static LONG TraceIndent = 0;
291 Group(group), Level(level), Function(function), File(file), Line(line),
292 Enabled(group.IsEnabled() && level <= group.GetLevel())
296 Trace(
_T(
">> "),
nullptr);
297 InterlockedIncrement(&TraceIndent);
303 Group(group), Level(level), Function(function), File(file), Line(line),
304 Enabled(group.IsEnabled() && level <= group.GetLevel())
308 Trace(
_T(
">> "), params);
309 InterlockedIncrement(&TraceIndent);
317 InterlockedDecrement(&TraceIndent);
318 Trace(
_T(
"<< "),
nullptr);
323TDiagFunction::Trace(LPCTSTR prefix, LPCTSTR params)
326 for (
int indent = TraceIndent; indent--;)
328 out << prefix << Function;
330 out <<
_T(
" (") << params <<
_T(
")");
331 Group.
Trace(out.str().c_str(), Level, File, Line);
337 MakeString(LPCSTR type,
const tstring& msg, LPCSTR file,
int line)
341 s <<
_A2W(type) <<
_T(
" failed in \"");
342 s <<
_A2W(file) <<
_T(
"\" at line ") << line <<
_T(
": ") << msg;
350 delegate(MakeString(type, msg, file, line))
377 static LONG entranceCount = 0;
378 struct TReentranceGuard
380 TReentranceGuard() {InterlockedIncrement(&entranceCount);}
381 ~TReentranceGuard() {InterlockedDecrement(&entranceCount);}
385 tstring error = MakeString(type, msg, file, line);
386 if (entranceCount > 1)
391 OutputDebugString(error.c_str());
398 HWND hParent = ::GetActiveWindow();
401 HWND hPopup = ::GetLastActivePopup(hParent);
412 bool DidRemoveQuitMsg;
413 TQuitMsgHider() : DidRemoveQuitMsg(PeekMessage(&QuitMsg,
nullptr, WM_QUIT, WM_QUIT, PM_REMOVE)) {}
414 ~TQuitMsgHider() {
if (DidRemoveQuitMsg) PostQuitMessage(
static_cast<int>(QuitMsg.wParam));}
418 error +=
_T(
"\n\nSelect Abort to terminate, Retry to debug, or Ignore to continue.");
419 int ret = ::MessageBox(hParent, error.c_str(),
_A2W(type),
420 MB_ABORTRETRYIGNORE | MB_DEFBUTTON3 | MB_TASKMODAL | MB_ICONHAND | MB_SETFOREGROUND);
#define OWL_OUTPUT_DEBUG_STRING(lpsz)
Diagnostic macros for assertions and tracing.
#define OWL_DIAG_DEFINE_GROUP_INIT(f, g, e, l)
#define OWL_DIAG_DEFINE_EXPORTGROUP_INIT(f, g, e, l)
#define DIAG_DEFINE_EXPORTGROUP_INIT(f, g, e, l)
TCheckFailure(const tstring &msg, LPCSTR file, int line)
void Trace(const tstring &msg, int level, LPCSTR file, int line)
TDiagBaseHook * LocalHook
static TDiagBase * GetDiagGroup(TDiagBase *curr=nullptr)
TDiagBase(LPCSTR name, bool enable, int level)
static TDiagBaseHook * SetGlobalHook(TDiagBaseHook *hook=nullptr)
void Warn(const tstring &msg, int level, LPCSTR file, int line)
static tstring ToString(LPCSTR s)
virtual const char * what() const noexcept
static int BreakMessage(LPCSTR type, const tstring &msg, LPCSTR file, int line)
virtual tstring why() const
TDiagException(LPCSTR type, const tstring &msg, LPCSTR file, int line)
TDiagFunction(TDiagBase &group, int level, LPCTSTR function, LPCSTR file, int line)
friend class TMRSWSection::TLock
TPreconditionFailure(const tstring &msg, LPCSTR file, int line)
const char * what() const noexcept
Definition of class TModule.
Object Windows Library (OWLNext Core).
std::ostringstream tostringstream
DIAG_DEFINE_GROUP_INIT(OWL_INI, OwlApp, 1, 0)
General definitions used by all ObjectWindows programs.
virtual void Output(TDiagBase *group, LPCTSTR str)=0