X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/27fc802d5c31d4b1e1d5e2d38db9338e2d09bdea..7214297d16aed4c160c1cbef6b19f153ca065ab7:/src/common/log.cpp diff --git a/src/common/log.cpp b/src/common/log.cpp index 30b8258870..686cd75754 100644 --- a/src/common/log.cpp +++ b/src/common/log.cpp @@ -29,13 +29,13 @@ // wxWindows #ifndef WX_PRECOMP + #include #include #include #include #include #include - - #include + #include #include #include #endif //WX_PRECOMP @@ -52,6 +52,8 @@ #ifdef __WXMSW__ #include + // Redefines OutputDebugString if necessary + #include "wx/msw/private.h" #else //Unix #include #endif //Win/Unix @@ -237,7 +239,14 @@ void WXDLLEXPORT wxLogSysError(long lErrCode, const char *szFormat, ...) wxLog::wxLog() { m_bHasMessages = FALSE; - m_bVerbose = FALSE; + + // enable verbose messages by default in the debug builds +#ifdef __WXDEBUG__ + m_bVerbose = TRUE; +#else // release + m_bVerbose = FALSE; +#endif // debug/release + m_szTimeFormat = "[%d/%b/%y %H:%M:%S] "; } @@ -256,8 +265,12 @@ wxLog *wxLog::GetActiveTarget() // ask the application to create a log target for us if ( wxTheApp != NULL ) ms_pLogger = wxTheApp->CreateLogTarget(); + else + ms_pLogger = new wxLogStderr; #endif + s_bInGetActiveTarget = FALSE; + // do nothing if it fails - what can we do? } } @@ -265,15 +278,17 @@ wxLog *wxLog::GetActiveTarget() return ms_pLogger; } -wxLog *wxLog::SetActiveTarget(wxLog *pLogger, bool bNoFlashOld) +wxLog *wxLog::SetActiveTarget(wxLog *pLogger) { - // flush the old messages before changing - if ( (ms_pLogger != NULL) && !bNoFlashOld ) { + if ( ms_pLogger != NULL ) { + // flush the old messages before changing because otherwise they might + // get lost later if this target is not restored ms_pLogger->Flush(); } wxLog *pOldLogger = ms_pLogger; ms_pLogger = pLogger; + return pOldLogger; } @@ -281,6 +296,9 @@ wxString wxLog::TimeStamp() const { wxString str; +/* Let's disable TimeStamp and see if anyone complains. + * If not, we'll remove it, since it's probably unlikely + * to ever be used. -- JACS 22/11/98 if ( !IsEmpty(m_szTimeFormat) ) { char szBuf[128]; time_t timeNow; @@ -292,6 +310,7 @@ wxString wxLog::TimeStamp() const strftime(szBuf, WXSIZEOF(szBuf), m_szTimeFormat, ptmNow); str = szBuf; } +*/ return str; } @@ -318,8 +337,8 @@ void wxLog::DoLog(wxLogLevel level, const char *szString) break; case wxLOG_Info: - if ( GetVerbose() ) case wxLOG_Message: + if ( GetVerbose() ) DoLogString(str + szString); // fall through @@ -330,8 +349,11 @@ void wxLog::DoLog(wxLogLevel level, const char *szString) case wxLOG_Trace: case wxLOG_Debug: #ifdef __WXDEBUG__ - DoLogString(str << (level == wxLOG_Trace ? _("Trace") : _("Debug")) - << ": " << szString); + // DoLogString(str << (level == wxLOG_Trace ? _("Trace") : _("Debug")) + // << ": " << szString); + // JACS: we don't really want to prefix with 'Debug'. It's just extra + // verbiage. + DoLogString(szString); #endif break; @@ -343,7 +365,7 @@ void wxLog::DoLog(wxLogLevel level, const char *szString) void wxLog::DoLogString(const char *WXUNUSED(szString)) { - wxFAIL_MSG(_("DoLogString must be overrided if it's called.")); + wxFAIL_MSG("DoLogString must be overriden if it's called."); } void wxLog::Flush() @@ -365,15 +387,24 @@ wxLogStderr::wxLogStderr(FILE *fp) void wxLogStderr::DoLogString(const char *szString) { - fputs(szString, m_fp); - fputc('\n', m_fp); + wxString str(szString); + str << '\n'; + + fputs(str, m_fp); fflush(m_fp); + + // under Windows, programs usually don't have stderr at all, so make show the + // messages also under debugger +#ifdef __WXMSW__ + OutputDebugString(str + '\r'); +#endif // MSW } // ---------------------------------------------------------------------------- // wxLogStream implementation // ---------------------------------------------------------------------------- +#if wxUSE_STD_IOSTREAM wxLogStream::wxLogStream(ostream *ostr) { if ( ostr == NULL ) @@ -386,14 +417,17 @@ void wxLogStream::DoLogString(const char *szString) { (*m_ostr) << szString << endl << flush; } +#endif + +#ifndef wxUSE_NOGUI // ---------------------------------------------------------------------------- // wxLogTextCtrl implementation // ---------------------------------------------------------------------------- -wxLogTextCtrl::wxLogTextCtrl(wxTextCtrl *pTextCtrl) -// @@@ TODO: in wxGTK wxTextCtrl doesn't derive from streambuf -// Also, in DLL mode in wxMSW, can't use it. +#if wxUSE_STD_IOSTREAM +wxLogTextCtrl::wxLogTextCtrl(wxTextCtrl *pTextCtrl) +// DLL mode in wxMSW, can't use it. #if defined(NO_TEXT_WINDOW_STREAM) #else : wxLogStream(new ostream(pTextCtrl)) @@ -405,13 +439,12 @@ wxLogTextCtrl::~wxLogTextCtrl() { delete m_ostr; } +#endif // ---------------------------------------------------------------------------- // wxLogGui implementation // ---------------------------------------------------------------------------- -#ifndef wxUSE_NOGUI - wxLogGui::wxLogGui() { m_bErrors = FALSE; @@ -493,20 +526,20 @@ void wxLogGui::DoLog(wxLogLevel level, const char *szString) { wxString strTime = TimeStamp(); - #if defined(__WIN32__) && !defined(__WXSTUBS__) + #ifdef __WXMSW__ // don't prepend debug/trace here: it goes to the debug window // anyhow, but do put a timestamp OutputDebugString(strTime + szString + "\n\r"); - #else //!WIN32 + #else // send them to stderr fprintf(stderr, "%s %s: %s\n", strTime.c_str(), - level == wxLOG_Trace ? _("Trace") : _("Debug"), + level == wxLOG_Trace ? "Trace" : "Debug", szString); fflush(stderr); - #endif // WIN32 + #endif } - #endif + #endif // __WXDEBUG__ break; case wxLOG_FatalError: @@ -669,22 +702,26 @@ void wxLogFrame::OnSave(wxCommandEvent& WXUNUSED(event)) // retrieve text and save it // ------------------------- -#ifdef __WXGTK__ - // @@@@ TODO: no GetNumberOfLines and GetLineText in wxGTK yet - wxLogError(_("Sorry, this function is not implemented under GTK")); -#else int nLines = m_pTextCtrl->GetNumberOfLines(); for ( int nLine = 0; bOk && nLine < nLines; nLine++ ) { - bOk = file.Write(m_pTextCtrl->GetLineText(nLine) + wxTextFile::GetEOL()); + bOk = file.Write(m_pTextCtrl->GetLineText(nLine) + +// we're not going to pull in the whole wxTextFile if all we need is this... +#if wxUSE_TEXTFILE + wxTextFile::GetEOL() +#else // !wxUSE_TEXTFILE + '\n' +#endif // wxUSE_TEXTFILE + ); } -#endif //GTK if ( bOk ) bOk = file.Close(); if ( !bOk ) { wxLogError(_("Can't save log contents to file.")); - return; + } + else { + wxLogStatus(this, _("Log saved to the file '%s'."), szFileName); } } @@ -780,8 +817,7 @@ void wxLogWindow::DoLogString(const char *szString) pText->WriteText(szString); pText->WriteText("\n"); // "\n" ok here (_not_ "\r\n") - // ensure that the line can be seen - // @@@ TODO + // TODO ensure that the line can be seen } wxFrame *wxLogWindow::GetFrame() const @@ -789,17 +825,19 @@ wxFrame *wxLogWindow::GetFrame() const return m_pLogFrame; } -void wxLogWindow::OnFrameCreate(wxFrame *WXUNUSED(frame)) +void wxLogWindow::OnFrameCreate(wxFrame * WXUNUSED(frame)) { } -void wxLogWindow::OnFrameDelete(wxFrame *WXUNUSED(frame)) +void wxLogWindow::OnFrameDelete(wxFrame * WXUNUSED(frame)) { - m_pLogFrame = (wxLogFrame *) NULL; + m_pLogFrame = (wxLogFrame *)NULL; } wxLogWindow::~wxLogWindow() { + delete m_pOldLog; + // may be NULL if log frame already auto destroyed itself delete m_pLogFrame; } @@ -814,6 +852,7 @@ wxLogWindow::~wxLogWindow() // static variables // ---------------------------------------------------------------------------- wxLog *wxLog::ms_pLogger = (wxLog *) NULL; +bool wxLog::ms_doLog = TRUE; bool wxLog::ms_bAutoCreate = TRUE; wxTraceMask wxLog::ms_ulTraceMask = (wxTraceMask)0; @@ -927,6 +966,12 @@ void Trap() DebugBreak(); #elif defined(__WXSTUBS__) // TODO + #elif defined(__WXMAC__) + #if __powerc + Debugger(); + #else + SysBreak(); + #endif #else // Unix raise(SIGTRAP); #endif // Win/Unix @@ -942,12 +987,25 @@ void wxOnAssert(const char *szFile, int nLine, const char *szMsg) if ( s_bInAssert ) { // He-e-e-e-elp!! we're trapped in endless loop Trap(); + + s_bInAssert = FALSE; + + return; } s_bInAssert = TRUE; char szBuf[LOG_BUFFER_SIZE]; - sprintf(szBuf, _("Assert failed in file %s at line %d"), szFile, nLine); + + // make life easier for people using VC++ IDE: clicking on the message will + // take us immediately to the place of the failed assert +#ifdef __VISUALC__ + sprintf(szBuf, "%s(%d): assert failed", szFile, nLine); +#else // !VC++ + // make the error message more clear for all the others + sprintf(szBuf, "Assert failed in file %s at line %d", szFile, nLine); +#endif // VC/!VC + if ( szMsg != NULL ) { strcat(szBuf, ": "); strcat(szBuf, szMsg); @@ -960,22 +1018,26 @@ void wxOnAssert(const char *szFile, int nLine, const char *szMsg) // send it to the normal log destination wxLogDebug(szBuf); - strcat(szBuf, _("\nDo you want to stop the program?" + #if wxUSE_NOGUI + Trap(); + #else + strcat(szBuf, "\nDo you want to stop the program?" "\nYou can also choose [Cancel] to suppress " - "further warnings.")); + "further warnings."); - switch ( wxMessageBox(szBuf, _("Debug"), - wxYES_NO | wxCANCEL | wxICON_STOP ) ) { - case wxYES: - Trap(); - break; + switch ( wxMessageBox(szBuf, _("Debug"), + wxYES_NO | wxCANCEL | wxICON_STOP ) ) { + case wxYES: + Trap(); + break; - case wxCANCEL: - s_bNoAsserts = TRUE; - break; + case wxCANCEL: + s_bNoAsserts = TRUE; + break; - //case wxNO: nothing to do - } + //case wxNO: nothing to do + } + #endif // USE_NOGUI } s_bInAssert = FALSE;