📄 ncbidiag.cpp
字号:
CMutexGuard LOCK(s_DiagMutex); flags &= ~flag;}extern TDiagPostFlags SetDiagPostAllFlags(TDiagPostFlags flags){ return s_SetDiagPostAllFlags(CDiagBuffer::sm_PostFlags, flags);}extern void SetDiagPostFlag(EDiagPostFlag flag){ s_SetDiagPostFlag(CDiagBuffer::sm_PostFlags, flag);}extern void UnsetDiagPostFlag(EDiagPostFlag flag){ s_UnsetDiagPostFlag(CDiagBuffer::sm_PostFlags, flag);}extern TDiagPostFlags SetDiagTraceAllFlags(TDiagPostFlags flags){ return s_SetDiagPostAllFlags(CDiagBuffer::sm_TraceFlags, flags);}extern void SetDiagTraceFlag(EDiagPostFlag flag){ s_SetDiagPostFlag(CDiagBuffer::sm_TraceFlags, flag);}extern void UnsetDiagTraceFlag(EDiagPostFlag flag){ s_UnsetDiagPostFlag(CDiagBuffer::sm_TraceFlags, flag);}extern void SetDiagPostPrefix(const char* prefix){ CDiagBuffer& buf = GetDiagBuffer(); if ( prefix ) { buf.m_PostPrefix = prefix; } else { buf.m_PostPrefix.erase(); } buf.m_PrefixList.clear();}extern void PushDiagPostPrefix(const char* prefix){ if (prefix && *prefix) { CDiagBuffer& buf = GetDiagBuffer(); buf.m_PrefixList.push_back(prefix); buf.UpdatePrefix(); }}extern void PopDiagPostPrefix(void){ CDiagBuffer& buf = GetDiagBuffer(); if ( !buf.m_PrefixList.empty() ) { buf.m_PrefixList.pop_back(); buf.UpdatePrefix(); }}extern EDiagSev SetDiagPostLevel(EDiagSev post_sev){ if (post_sev < eDiagSevMin || post_sev > eDiagSevMax) { NCBI_THROW(CCoreException, eInvalidArg, "SetDiagPostLevel() -- Severity must be in the range " "[eDiagSevMin..eDiagSevMax]"); } CMutexGuard LOCK(s_DiagMutex); EDiagSev sev = CDiagBuffer::sm_PostSeverity; if ( CDiagBuffer::sm_PostSeverityChange != eDiagSC_Disable) { CDiagBuffer::sm_PostSeverity = post_sev; } return sev;}extern void SetDiagFixedPostLevel(const EDiagSev post_sev){ SetDiagPostLevel(post_sev); DisableDiagPostLevelChange();}extern bool DisableDiagPostLevelChange(bool disable_change){ CMutexGuard LOCK(s_DiagMutex); bool prev_status = (CDiagBuffer::sm_PostSeverityChange == eDiagSC_Enable); CDiagBuffer::sm_PostSeverityChange = disable_change ? eDiagSC_Disable : eDiagSC_Enable; return prev_status;}extern EDiagSev SetDiagDieLevel(EDiagSev die_sev){ if (die_sev < eDiagSevMin || die_sev > eDiag_Fatal) { NCBI_THROW(CCoreException, eInvalidArg, "SetDiagDieLevel() -- Severity must be in the range " "[eDiagSevMin..eDiag_Fatal]"); } CMutexGuard LOCK(s_DiagMutex); EDiagSev sev = CDiagBuffer::sm_DieSeverity; CDiagBuffer::sm_DieSeverity = die_sev; return sev;}extern void IgnoreDiagDieLevel(bool ignore, EDiagSev* prev_sev){ if (!!ignore != !!prev_sev) { NCBI_THROW(CCoreException, eInvalidArg, "IgnoreDiagDieLevel() -- Illegal 'ignore'/'prev_sev' " "combination"); } CMutexGuard LOCK(s_DiagMutex); if ( ignore ) { *prev_sev = CDiagBuffer::sm_DieSeverity; CDiagBuffer::sm_DieSeverity = eDiag_Trace; } else { CDiagBuffer::sm_DieSeverity = eDiag_Fatal; CNcbiDiag diag(eDiag_Info); }}extern void SetDiagTrace(EDiagTrace how, EDiagTrace dflt){ CMutexGuard LOCK(s_DiagMutex); (void) CDiagBuffer::GetTraceEnabled(); if (dflt != eDT_Default) CDiagBuffer::sm_TraceDefault = dflt; if (how == eDT_Default) how = CDiagBuffer::sm_TraceDefault; CDiagBuffer::sm_TraceEnabled = (how == eDT_Enable);}extern void SetDiagHandler(CDiagHandler* handler, bool can_delete){ CMutexGuard LOCK(s_DiagMutex); if ( CDiagBuffer::sm_CanDeleteHandler ) delete CDiagBuffer::sm_Handler; CDiagBuffer::sm_Handler = handler; CDiagBuffer::sm_CanDeleteHandler = can_delete;}extern bool IsSetDiagHandler(void){ return (CDiagBuffer::sm_Handler != s_DefaultHandler);}extern CDiagHandler* GetDiagHandler(bool take_ownership){ CMutexGuard LOCK(s_DiagMutex); if (take_ownership) { _ASSERT(CDiagBuffer::sm_CanDeleteHandler); CDiagBuffer::sm_CanDeleteHandler = false; } return CDiagBuffer::sm_Handler;}static void s_TlsDataCleanup(CDiagBuffer* old_value, void* /* cleanup_data */){ delete old_value;}static bool s_TlsDestroyed; /* = false */static void s_TlsObjectCleanup(void* /* ptr */){ s_TlsDestroyed = true;}extern CDiagBuffer& GetDiagBuffer(void){ static CSafeStaticRef< CTls<CDiagBuffer> > s_DiagBufferTls(s_TlsObjectCleanup); // Create and use dummy buffer if all real buffers are gone already // (on the application exit) if ( s_TlsDestroyed ) { static CDiagBuffer s_DiagBuffer; return s_DiagBuffer; } // Create thread-specific diag.buffer (if not created yet), // and store it to TLS CDiagBuffer* msg_buf = s_DiagBufferTls->GetValue(); if ( !msg_buf ) { msg_buf = new CDiagBuffer; s_DiagBufferTls->SetValue(msg_buf, s_TlsDataCleanup); } return *msg_buf;}void CStreamDiagHandler::Post(const SDiagMessage& mess){ if (m_Stream) { (*m_Stream) << mess; if (m_QuickFlush) { (*m_Stream) << NcbiFlush; } }}extern bool IsDiagStream(const CNcbiOstream* os){ CStreamDiagHandler* sdh = dynamic_cast<CStreamDiagHandler*>(CDiagBuffer::sm_Handler); return (sdh && sdh->m_Stream == os);}extern void SetDiagErrCodeInfo(CDiagErrCodeInfo* info, bool can_delete){ CMutexGuard LOCK(s_DiagMutex); if ( CDiagBuffer::sm_CanDeleteErrCodeInfo ) delete CDiagBuffer::sm_ErrCodeInfo; CDiagBuffer::sm_ErrCodeInfo = info; CDiagBuffer::sm_CanDeleteErrCodeInfo = can_delete;}extern bool IsSetDiagErrCodeInfo(void){ return (CDiagBuffer::sm_ErrCodeInfo != 0);}extern CDiagErrCodeInfo* GetDiagErrCodeInfo(bool take_ownership){ CMutexGuard LOCK(s_DiagMutex); if (take_ownership) { _ASSERT(CDiagBuffer::sm_CanDeleteErrCodeInfo); CDiagBuffer::sm_CanDeleteErrCodeInfo = false; } return CDiagBuffer::sm_ErrCodeInfo;}///////////////////////////////////////////////////////// CNcbiDiag::CNcbiDiag::CNcbiDiag(EDiagSev sev, TDiagPostFlags post_flags) : m_Severity(sev), m_Line(0), m_ErrCode(0), m_ErrSubCode(0), m_Buffer(GetDiagBuffer()), m_PostFlags(post_flags){ *m_File = '\0';}CNcbiDiag::CNcbiDiag(const char* file, size_t line, EDiagSev sev, TDiagPostFlags post_flags) : m_Severity(sev), m_Line(line), m_ErrCode(0), m_ErrSubCode(0), m_Buffer(GetDiagBuffer()), m_PostFlags(post_flags){ SetFile(file);}const CNcbiDiag& CNcbiDiag::SetFile(const char* file) const{ if (file && *file) { strncpy(m_File, file, sizeof(m_File)); m_File[sizeof(m_File) - 1] = '\0'; } else { *m_File = '\0'; } return *this;}const CNcbiDiag& CNcbiDiag::operator<< (const CException& ex) const{ { ostrstream os; os << '\n' << "NCBI C++ Exception:" << '\n'; *this << string(CNcbiOstrstreamToString(os)); } const CException* pex; stack<const CException*> pile; // invert the order for (pex = &ex; pex; pex = pex->GetPredecessor()) { pile.push(pex); } for (; !pile.empty(); pile.pop()) { pex = pile.top(); string text(pex->GetMsg()); { ostrstream os; pex->ReportExtra(os); if (os.pcount() != 0) { text += " ("; text += (string)CNcbiOstrstreamToString(os); text += ')'; } } string err_type(pex->GetType()); err_type += "::"; err_type += pex->GetErrCodeString(); SDiagMessage diagmsg( eDiag_Error, text.c_str(), text.size(), (pex->GetFile()).c_str(), pex->GetLine(), GetPostFlags(), 0,0,0,err_type.c_str()); string report; diagmsg.Write(report); *this << " "; // indentation *this << report; } return *this;}bool CNcbiDiag::StrToSeverityLevel(const char* str_sev, EDiagSev& sev){ if (!str_sev || !*str_sev) { return false; } // Digital value int nsev = NStr::StringToNumeric(str_sev); if (nsev > eDiagSevMax) { nsev = eDiagSevMax; } else if ( nsev == -1 ) { // String value for (int s = eDiagSevMin; s <= eDiagSevMax; s++) { if (NStr::CompareNocase(CNcbiDiag::SeverityName(EDiagSev(s)), str_sev) == 0) { nsev = s; break; } } } sev = EDiagSev(nsev); // Unknown value return sev >= eDiagSevMin && sev <= eDiagSevMax;}void CNcbiDiag::DiagFatal(const char* file, size_t line, const char* message){ CNcbiDiag(file, line, NCBI_NS_NCBI::eDiag_Fatal) << message << Endm;}void CNcbiDiag::DiagTrouble(const char* file, size_t line){ DiagFatal(file, line, "Trouble!");}void CNcbiDiag::DiagAssert(const char* file, size_t line, const char* expression){ CNcbiDiag(file, line, NCBI_NS_NCBI::eDiag_Fatal, eDPF_Trace) << "Assertion failed: (" << expression << ')' << Endm;}void CNcbiDiag::DiagValidate(const char* file, size_t line, const char* _DEBUG_ARG(expression), const char* message){#ifdef _DEBUG if ( xncbi_GetValidateAction() != eValidate_Throw ) { DiagAssert(file, line, expression); }#endif throw CCoreException(file, (int) line, 0, CCoreException::eCore, message);}///////////////////////////////////////////////////////// CDiagRestorer::CDiagRestorer::CDiagRestorer(void){ CMutexGuard LOCK(s_DiagMutex); const CDiagBuffer& buf = GetDiagBuffer(); m_PostPrefix = buf.m_PostPrefix; m_PrefixList = buf.m_PrefixList; m_PostFlags = buf.sm_PostFlags; m_PostSeverity = buf.sm_PostSeverity; m_PostSeverityChange = buf.sm_PostSeverityChange; m_DieSeverity = buf.sm_DieSeverity; m_TraceDefault = buf.sm_TraceDefault; m_TraceEnabled = buf.sm_TraceEnabled; m_Handler = buf.sm_Handler; m_CanDeleteHandler = buf.sm_CanDeleteHandler; m_ErrCodeInfo = buf.sm_ErrCodeInfo; m_CanDeleteErrCodeInfo = buf.sm_CanDeleteErrCodeInfo; // avoid premature cleanup buf.sm_CanDeleteHandler = false; buf.sm_CanDeleteErrCodeInfo = false;}CDiagRestorer::~CDiagRestorer(void){ {{ CMutexGuard LOCK(s_DiagMutex); CDiagBuffer& buf = GetDiagBuffer(); buf.m_PostPrefix = m_PostPrefix; buf.m_PrefixList = m_PrefixList; buf.sm_PostFlags = m_PostFlags; buf.sm_PostSeverity = m_PostSeverity; buf.sm_PostSeverityChange = m_PostSeverityChange; buf.sm_DieSeverity = m_DieSeverity; buf.sm_TraceDefault = m_TraceDefault; buf.sm_TraceEnabled = m_TraceEnabled; }} SetDiagHandler(m_Handler, m_CanDeleteHandler); SetDiagErrCodeInfo(m_ErrCodeInfo, m_CanDeleteErrCodeInfo);}//////////////////////////////////////////////////////// internal diag. handler classes for compatibility:class CCompatDiagHandler : public CDiagHandler{public: CCompatDiagHandler(FDiagHandler func, void* data, FDiagCleanup cleanup) : m_Func(func), m_Data(data), m_Cleanup(cleanup) { } ~CCompatDiagHandler(void) { if (m_Cleanup) { m_Cleanup(m_Data); } } virtual void Post(const SDiagMessage& mess) { m_Func(mess); }private: FDiagHandler m_Func; void* m_Data; FDiagCleanup m_Cleanup;};extern void SetDiagHandler(FDiagHandler func, void* data, FDiagCleanup cleanup){ SetDiagHandler(new CCompatDiagHandler(func, data, cleanup));}class CCompatStreamDiagHandler : public CStreamDiagHandler{public: CCompatStreamDiagHandler(CNcbiOstream* os, bool quick_flush = true, FDiagCleanup cleanup = 0, void* cleanup_data = 0) : CStreamDiagHandler(os, quick_flush), m_Cleanup(cleanup), m_CleanupData(cleanup_data) { } ~CCompatStreamDiagHandler(void) { if (m_Cleanup) { m_Cleanup(m_CleanupData); } }private: FDiagCleanup m_Cleanup; void* m_CleanupData;};extern void SetDiagStream(CNcbiOstream* os, bool quick_flush, FDiagCleanup cleanup, void* cleanup_data){ SetDiagHandler(new CCompatStreamDiagHandler(os, quick_flush, cleanup, cleanup_data));}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -