OSDN Git Service

PATCH: [ 889334 ] Improve and enable logging
authorKimmo Varis <kimmov@gmail.com>
Tue, 3 Feb 2004 13:47:34 +0000 (13:47 +0000)
committerKimmo Varis <kimmov@gmail.com>
Tue, 3 Feb 2004 13:47:34 +0000 (13:47 +0000)
Src/Common/LogFile.cpp
Src/Common/LogFile.h
Src/DiffWrapper.cpp
Src/DirActions.cpp
Src/DirDoc.cpp
Src/DirScan.cpp
Src/MainFrm.cpp
Src/MergeDoc.cpp
Src/StdAfx.cpp
Src/readme.txt

index 633ee91..b471985 100644 (file)
@@ -1,6 +1,11 @@
-// LogFile.cpp: implementation of the CLogFile and CSQL LogFile classes.
-//
-//////////////////////////////////////////////////////////////////////
+/** 
+ * @file  LogFile.h
+ *
+ * @brief Implementation file for CLogFile
+ *
+ */
+// RCS ID line follows -- this is updated by CVS
+// $Id$
 
 #include "stdafx.h"
 #include "LogFile.h"
@@ -11,85 +16,208 @@ static char THIS_FILE[]=__FILE__;
 #define new DEBUG_NEW
 #endif
 
-//////////////////////////////////////////////////////////////////////
-// Construction/Destruction
-//////////////////////////////////////////////////////////////////////
+static const TCHAR MutexName[] = _T("WINMERGE_LOG_MUTEX");
 
-CLogFile::CLogFile(LPCTSTR szLogName, LPCTSTR szLogPath /*= NULL*/, BOOL bDeleteExisting /*=FALSE*/)
-       : m_nMaxSize(1024576)
+/**
+ * @brief Constructor
+ */
+CLogFile::CLogFile(LPCTSTR szLogName /*= NULL*/,
+        LPCTSTR szLogPath /*= NULL*/, BOOL bDeleteExisting /*=FALSE*/)
+       : m_nMaxSize(1024 * 1024) // 1MB
        , m_bEnabled(FALSE)
-// CString m_strLogPath
+       , m_nDefaultLevel(LOGLEVEL::LMSG)
+       , m_nMaskLevel(LOGLEVEL::LALL)
 {
+       SetFile(szLogName, szLogPath, bDeleteExisting);
+       m_hLogMutex = CreateMutex(NULL, FALSE, MutexName);
+}
 
-       TCHAR temp[MAX_PATH];
-
+/**
+ * @brief Destructor
+ */
+CLogFile::~CLogFile()
+{
+       EnableLogging(FALSE);
+       CloseHandle(m_hLogMutex);
+}
 
+/**
+ * @brief Set logfilename
+ * @param bDelExisting If TRUE, existing logfile with same name
+ * is deleted.
+ */
+CString CLogFile::SetFile(CString strFile, CString strPath,
+       BOOL bDelExisting /*= FALSE*/)
+{
+       TCHAR temp[MAX_PATH] = {0};
 
        // build the path to the logfile
-       if (szLogPath != NULL
-               && *szLogPath != _T('\0'))
-               m_strLogPath = szLogPath;
+       if (!strPath.IsEmpty())
+               m_strLogPath = strFile;
        else
        {
-               GetTempPath(MAX_PATH, temp);
-               m_strLogPath = temp;
+               if (GetTempPath(MAX_PATH, temp))
+                       m_strLogPath = temp;
        }
+       
        if (m_strLogPath.Right(1) != _T('\\'))
                m_strLogPath += _T('\\');
 
-       m_strLogPath += szLogName;
+       m_strLogPath += strFile;
 
-       if (bDeleteExisting)
+       if (bDelExisting)
                DeleteFile(m_strLogPath);
+       
+       return m_strLogPath;
+}
 
-       // write start banner
+/**
+ * @brief Enable/Disable writing log
+ */
+void CLogFile::EnableLogging(BOOL bEnable)
+{
        CTime t = CTime::GetCurrentTime();
-       CString s = t.Format(_T("Begin Log: %A, %B %d, %Y    %H:%M:%S"));
-       Write(_T("\n\n==========================================================================\n")
-               _T("==========================================================================\n")
-               _T("%s\n==========================================================================\n")
-               _T("==========================================================================\n"), s);
-       Write(m_strLogPath);
+       CString s = t.Format(_T(" %A, %B %d, %Y    %H:%M:%S"));
+
+       if (bEnable)
+       {
+               m_bEnabled = TRUE;
+               Write(_T("\n*******\nLog Started: %s"), s);
+               Write(_T("Path: %s\n*******\n"), m_strLogPath);
+       }
+       else
+       {
+               m_bEnabled = FALSE;
+               Write(_T("\n*******\nLog Stopped: %s\n"), s);
+               Write(_T("*******\n"));
+       }
 }
 
-CLogFile::~CLogFile()
+/**
+ * @brief Return default level for log messages
+ */
+UINT CLogFile::GetDefaultLevel() const
+{
+       return m_nDefaultLevel;
+}
+
+/**
+ * @brief Set default level for log messages
+ */
+void CLogFile::SetDefaultLevel(UINT logLevel)
 {
-       Write(_T("##### End Log #####\n"));
+       m_nDefaultLevel = logLevel;
 }
 
+/**
+ * @brief Get log message mask.
+ *
+ * Mask allows to select which level messages are written to log.
+ */
+UINT CLogFile::GetMaskLevel() const
+{
+       return m_nMaskLevel;
+}
+
+/**
+ * @brief Set log message mask
+ */
+void CLogFile::SetMaskLevel(UINT maskLevel)
+{
+       m_nMaskLevel = maskLevel;
+}
+
+/**
+ * @brief Write formatted message with default log level
+ */
 void CLogFile::Write(LPCTSTR pszFormat, ...)
 {
        if (!m_bEnabled)
                return;
 
-       TCHAR buf[2048]=_T("");
+       if ((m_nDefaultLevel & m_nMaskLevel) == 0)
+               return;
+
+       TCHAR buf[2*1024] = {0};
        va_list arglist;
        va_start(arglist, pszFormat);
        if (pszFormat != NULL)
                _vstprintf(buf, pszFormat, arglist);
        va_end(arglist);
        _tcscat(buf, _T("\n"));
-       //TRACE(buf);
+       
+       CString msg = GetPrefix(m_nDefaultLevel);
+       msg += buf;
 
-       FILE *f;
-       if ((f=_tfopen(m_strLogPath, _T("a"))) != NULL)
-       {
-               _fputts(buf, f);
+       Write(msg);
+}
+
+/**
+ * @brief Write message from resource with default level
+ */
+void CLogFile::Write(DWORD idFormatString, ...)
+{
+       if (!m_bEnabled)
+               return;
+
+       if ((m_nDefaultLevel & m_nMaskLevel) == 0)
+               return;
+
+       TCHAR buf[2*1024]=_T("");
+       CString strFormat;
 
-               // prune the log if it gets too big
-               if (ftell(f) >= (int)m_nMaxSize)
-                       Prune(f);
-               else
-                       fclose(f);
+       if (strFormat.LoadString(idFormatString))
+       {
+               va_list arglist;
+               va_start(arglist, idFormatString);
+               _vstprintf(buf, strFormat, arglist);
+               va_end(arglist);
+               _tcscat(buf, _T("\n"));
+               
+               CString msg = GetPrefix(m_nDefaultLevel);
+               msg += buf;
+               
+               Write(msg);
        }
 }
 
-void CLogFile::Write(DWORD idFormatString, ...)
+/**
+ * @brief Write formatted message to log with given level
+ */
+void CLogFile::Write(UINT level, LPCTSTR pszFormat, ...)
 {
        if (!m_bEnabled)
                return;
 
-       TCHAR buf[2048]=_T("");
+       if ((level & m_nMaskLevel) == 0)
+               return;
+
+       TCHAR buf[4*1024] = {0};
+       va_list arglist;
+       va_start(arglist, pszFormat);
+       if (pszFormat != NULL)
+               _vstprintf(buf, pszFormat, arglist);
+       va_end(arglist);
+       _tcscat(buf, _T("\n"));
+       
+       CString msg = GetPrefix(level);
+       msg += buf;
+
+       Write(msg);
+}
+
+/**
+ * @brief Write message from resource to log with given level
+ */
+void CLogFile::Write(UINT level, DWORD idFormatString, ...)
+{
+       if (!m_bEnabled)
+               return;
+
+       if ((level & m_nMaskLevel) == 0)
+               return;
+
+       TCHAR buf[2*1024]=_T("");
        CString strFormat;
 
        if (strFormat.LoadString(idFormatString))
@@ -99,18 +227,36 @@ void CLogFile::Write(DWORD idFormatString, ...)
                _vstprintf(buf, strFormat, arglist);
                va_end(arglist);
                _tcscat(buf, _T("\n"));
+               
+               CString msg = GetPrefix(m_nDefaultLevel);
+               msg += buf;
+               
+               Write(msg);
+       }
+}
 
+/**
+ * @brief Write new line to log.
+ * @note this function is used only internally by other write-functions.
+ */
+void CLogFile::Write(CString msg)
+{
+       DWORD dwWaitRes = WaitForSingleObject(m_hLogMutex, 10000);
+
+       if (dwWaitRes == WAIT_OBJECT_0)
+       {
                FILE *f;
                if ((f=_tfopen(m_strLogPath, _T("a"))) != NULL)
                {
-                       _fputts(buf, f);
-                               
+                       _fputts(msg, f);
+
                        // prune the log if it gets too big
                        if (ftell(f) >= (int)m_nMaxSize)
                                Prune(f);
                        else
                                fclose(f);
                }
+               ReleaseMutex(m_hLogMutex);
        }
 }
 
@@ -128,9 +274,11 @@ void CLogFile::WriteError(CString JobID, CString ProcessID, CString Event, long
        
        sWriteString.Format(_T("%s %s %s %ld %s"),JobID, ProcessID, Event, ecode, CIndex);
        Write(sWriteString);
-
 }
 
+/**
+ * @brief Prune log file if it exceeds max given size.
+ */
 void CLogFile::Prune(FILE *f)
 {
        TCHAR buf[8196] = {0};
@@ -152,3 +300,34 @@ void CLogFile::Prune(FILE *f)
                MoveFile(tempfile,m_strLogPath);
        }
 }
+
+/**
+ * @brief Return message prefix for given loglevel.
+ */
+CString CLogFile::GetPrefix(UINT level) const
+{
+       CString str;
+       switch (level)
+       {
+               case LOGLEVEL::LERROR:
+                       str = _T("ERROR: ");
+                       break;
+               case LOGLEVEL::LWARNING:
+                       str = _T("WARNING: ");
+                       break;
+               case LOGLEVEL::LNOTICE:
+                       str = _T("NOTICE: ");
+                       break;
+               case LOGLEVEL::LMSG:
+                       break;
+               case LOGLEVEL::LCODEFLOW:
+                       str = _T("FLOW: ");
+                       break;
+               case LOGLEVEL::LCOMPAREDATA:
+                       str = _T("COMPARE: ");
+                       break;
+               default:
+                       break;
+       }
+       return str;
+}
index e99d2f7..cef827b 100644 (file)
@@ -1,40 +1,82 @@
-// LogFile.h: interface for the CLogFile class.
-//
-//////////////////////////////////////////////////////////////////////
+/** 
+ * @file  LogFile.h
+ *
+ * @brief Declaration file for CLogFile
+ *
+ */
+// RCS ID line follows -- this is updated by CVS
+// $Id$
 
 #if !defined(AFX_LOGFILE_H__803A3641_FE03_11D0_95CD_444553540000__INCLUDED_)
 #define AFX_LOGFILE_H__803A3641_FE03_11D0_95CD_444553540000__INCLUDED_
 
-#if _MSC_VER >= 1000
-#pragma once
-#endif // _MSC_VER >= 1000
-
+/**
+ * @brief Messagelevels for log writing.
+ */
+namespace LOGLEVEL
+{
+       enum 
+       {
+               LALL = -1, /**< All messages written */
+               LERROR = 0x1, /**< Error messages */
+               LWARNING = 0x2, /**< Warning messages */ 
+               LNOTICE = 0x4, /**< Important messages */
+               LMSG = 0x8, /**< Normal messages */
+               LCODEFLOW = 0x10, /**< Code flow messages */
+               LCOMPAREDATA = 0x20,
+       };
+};
 
+/**
+ * @brief Class for writing log files.
+ *
+ * Allows setting masks and levels for messages. They are used for
+ * filtering messages written to log. For example usually its not
+ * needed to see all informal messages, but errors are always good
+ * to log. For simpler usage, default is that all messages are written
+ * and functions with take just message in are provided.
+ * @note User can easily define more levels, just add new constant to
+ * namespace LOGLEVEL above, and possibly prefix to GetPrefix(UINT level).
+ */
 class CLogFile  
 {
 public:
+       CLogFile(LPCTSTR szLogName = NULL, LPCTSTR szLogPath = NULL,
+               BOOL bDeleteExisting = FALSE);
+       virtual ~CLogFile();
 
-       CLogFile(LPCTSTR szLogName, LPCTSTR szLogPath = NULL, BOOL bDeleteExisting = FALSE);
+       CString SetFile(CString strFile, CString strPath = _T(""),
+               BOOL bDelExisting = FALSE);
+       void EnableLogging(BOOL bEnable);
+       UINT GetDefaultLevel() const;
+       void SetDefaultLevel(UINT logLevel);
+       UINT GetMaskLevel() const;
+       void SetMaskLevel(UINT maskLevel);
 
        void Write(LPCTSTR pszFormat, ...);
        void Write(DWORD idFormatString, ...);
+       void Write(UINT level, LPCTSTR pszFormat, ...);
+       void Write(UINT level, DWORD idFormatString, ...);
 
        // overloaded Write Function to map to Write to Error Set code //
        void WriteError(CString JobID, CString ProcessID, CString Event, long ecode, CString CIndex);
 
-       virtual ~CLogFile();
        void SetMaxLogSize(DWORD dwMax) { m_nMaxSize = dwMax; }
        CString GetPath() const { return m_strLogPath; }
-       void EnableLogging(BOOL enable) { m_bEnabled = enable; }
 
 
 protected:
        void Prune(FILE *f);
+       CString GetPrefix(UINT level) const;
+       void Write(CString msg);
 
+private:
+       HANDLE    m_hLogMutex;
        DWORD     m_nMaxSize;
        BOOL      m_bEnabled;
        CString   m_strLogPath;
-
+       UINT      m_nDefaultLevel;
+       UINT      m_nMaskLevel;
 };
 
 
index c480573..abf4bdf 100644 (file)
 #include "diffwrapper.h"
 #include "diff.h"
 #include "FileTransform.h"
+#include "LogFile.h"
 
 extern int recursive;
+extern CLogFile gLog;
 
 CDiffWrapper::CDiffWrapper()
 {
@@ -372,6 +374,8 @@ BOOL CDiffWrapper::RunFileDiff()
                {
                        LogErrorString(Fmt(_T("DeleteFile(%s) failed: %s"),
                                strFile1Temp, GetSysError(GetLastError())));
+                       gLog.Write(LOGLEVEL::LERROR, _T("DeleteFile(%s) failed: %s"),
+                               strFile1Temp, GetSysError(GetLastError()));
                }
                strFile1Temp.Empty();
        }
@@ -381,6 +385,8 @@ BOOL CDiffWrapper::RunFileDiff()
                {
                        LogErrorString(Fmt(_T("DeleteFile(%s) failed: %s"),
                                strFile2Temp, GetSysError(GetLastError())));
+                       gLog.Write(LOGLEVEL::LERROR, _T("DeleteFile(%s) failed: %s"),
+                               strFile2Temp, GetSysError(GetLastError()));
                }
                strFile2Temp.Empty();
        }
index 1ff8e93..63b7a38 100644 (file)
@@ -31,6 +31,8 @@
 static char THIS_FILE[] = __FILE__;
 #endif
 
+extern CLogFile gLog;
+
 // Prompt user to confirm a multiple item copy
 static BOOL ConfirmMultipleCopy(int count, int total)
 {
@@ -353,6 +355,7 @@ void CDirView::PerformActionList(ActionList & actionList)
                {
                        sText += actionList.errors.RemoveHead() + _T("\r\n\r\n");
                }
+               gLog.Write(LOGLEVEL::LERROR, sText);
                OutputBox(sTitle, sText);
        }
 }
index 817c3dc..f54c137 100644 (file)
@@ -217,7 +217,7 @@ void CDirDoc::Rescan()
 
        m_statusCursor = new CustomStatusCursor(0, IDC_APPSTARTING, LoadResString(IDS_STATUS_RESCANNING));
 
-       gLog.Write(_T("Starting directory scan:\r\n\tLeft: %s\r\n\tRight: %s\r\n"),
+       gLog.Write(LOGLEVEL::LNOTICE, _T("Starting directory scan:\n\tLeft: %s\n\tRight: %s\n"),
                        m_pCtxt->m_strLeft, m_pCtxt->m_strRight);
        pf->clearStatus();
        pf->ShowProcessingBar(TRUE);
@@ -576,7 +576,7 @@ void CDirDoc::UpdateChangedItem(LPCTSTR pathLeft, LPCTSTR pathRight, bool unifie
  */
 void CDirDoc::CompareReady()
 {
-       gLog.Write(_T("Directory scan complete\r\n"));
+       gLog.Write(LOGLEVEL::LNOTICE, _T("Directory scan complete\n"));
 
        // finish the cursor (the hourglass/pointer combo) we had open during display
        delete m_statusCursor;
@@ -787,6 +787,7 @@ BOOL CDirDoc::SaveModified()
  */
 void CDirDoc::AbortCurrentScan()
 {
+       gLog.Write(LOGLEVEL::LNOTICE, _T("Dircompare aborted!"));
        m_diffThread.Abort();
 }
 
@@ -808,4 +809,5 @@ void CDirDoc::SetDescriptions(CString strLeftDesc, CString strRightDesc)
 {
        m_strLeftDesc = strLeftDesc;
        m_strRightDesc = strRightDesc;
-}
\ No newline at end of file
+}
+
index 06f636d..15aa155 100644 (file)
@@ -236,7 +236,7 @@ prepAndCompareTwoFiles(const fentry & lent, const fentry & rent,
        // based on file date, it could be done here, with the same caveat
        // as above
 
-       gLog.Write(_T("Comparing: n0=%s, n1=%s, d0=%s, d1=%s")
+       gLog.Write(LOGLEVEL::LCOMPAREDATA, _T("Comparing: n0=%s, n1=%s, d0=%s, d1=%s")
                , lent.name, rent.name, sLeftDir, sRightDir);
        CString filepath1 = paths_ConcatPath(sLeftDir, lent.name);
        CString filepath2 = paths_ConcatPath(sRightDir, rent.name);
@@ -457,7 +457,7 @@ static void StoreDiffResult(const CString & sDir, const fentry * lent, const fen
                name = rent->name;
                rattrs = rent->attrs;
        }
-       gLog.Write(_T("name=<%s>, leftdir=<%s>, rightdir=<%s>, code=%d")
+       gLog.Write(LOGLEVEL::LCOMPAREDATA,_T("name=<%s>, leftdir=<%s>, rightdir=<%s>, code=%d")
                , (LPCTSTR)name, (LPCTSTR)leftdir, (LPCTSTR)rightdir, code);
        pCtxt->AddDiff(name, sDir, leftdir, rightdir
                , lmtime, rmtime, lctime, rctime, lsize, rsize, code, lattrs, rattrs
index 02505c5..4119a3a 100644 (file)
@@ -71,8 +71,8 @@
 static char THIS_FILE[] = __FILE__;
 #endif
 
+extern CLogFile gLog;
 CMainFrame *mf = NULL;
-CLogFile gLog(_T("WinMerge.log"), NULL, TRUE);
 
 // add a 
 static void add_regexp PARAMS((struct regexp_list **, char const*));
@@ -141,6 +141,18 @@ static UINT indicators[] =
  */
 CMainFrame::CMainFrame()
 {
+#if defined (_DEBUG) || defined (ENABLE_LOG)
+       gLog.SetFile(_T("WinMerge.log"));
+       gLog.EnableLogging(TRUE);
+       // Not interested about compare data (very noisy!)
+       gLog.SetMaskLevel(LOGLEVEL::LALL & ~LOGLEVEL::LCOMPAREDATA);
+#endif
+
+// Only log errors and warnings for release!
+//#ifndef _DEBUG
+//     gLog.SetMaskLevel(LOGLEVEL::LERROR | LOGLEVEL::LWARNING);
+//#endif
+
        m_bFontSpecified=FALSE;
        m_strSaveAsPath = _T("");
        m_bFirstTime = TRUE;
@@ -1182,7 +1194,13 @@ BOOL CMainFrame::DoFileOpen(LPCTSTR pszLeft /*=NULL*/, LPCTSTR pszRight /*=NULL*
                                        break;
                                if (strLeft.Find(path) == 0)
                                {
-                                       DeleteFile(strLeft);
+                                       if (!::DeleteFile(strLeft))
+                                       {
+                                               LogErrorString(Fmt(_T("DeleteFile(%s) failed: %s"),
+                                                       strLeft, GetSysError(GetLastError())));
+                                               gLog.Write(LOGLEVEL::LERROR, _T("DeleteFile(%s) failed: %s"),
+                                                       strLeft, GetSysError(GetLastError()));
+                                       }
                                }
                                strLeft.Delete(0, strLeft.ReverseFind('\\'));
                                int dot = strLeft.ReverseFind('.');
@@ -1207,7 +1225,13 @@ BOOL CMainFrame::DoFileOpen(LPCTSTR pszLeft /*=NULL*/, LPCTSTR pszRight /*=NULL*
                                                break;;
                                        if (strRight.Find(path) == 0)
                                        {
-                                               DeleteFile(strRight);
+                                               if (!::DeleteFile(strRight))
+                                               {
+                                                       LogErrorString(Fmt(_T("DeleteFile(%s) failed: %s"),
+                                                               strRight, GetSysError(GetLastError())));
+                                                       gLog.Write(LOGLEVEL::LERROR, _T("DeleteFile(%s) failed: %s"),
+                                                               strRight, GetSysError(GetLastError()));
+                                               }
                                        }
                                        strRight.Delete(0, strRight.ReverseFind('\\'));
                                        int dot = strRight.ReverseFind('.');
@@ -1252,6 +1276,9 @@ BOOL CMainFrame::DoFileOpen(LPCTSTR pszLeft /*=NULL*/, LPCTSTR pszRight /*=NULL*
                        CDiffContext *pCtxt = new CDiffContext(strLeft, strRight);
                        if (pCtxt != NULL)
                        {
+                               gLog.Write(LOGLEVEL::LNOTICE, _T("Open dirs: Left: %s\n\tRight: %s."),
+                                       strLeft, strRight);
+
                                pDirDoc->SetReadOnly(TRUE, bROLeft);
                                pDirDoc->SetReadOnly(FALSE, bRORight);
                                pDirDoc->SetRecursive(bRecurse);
@@ -1279,6 +1306,9 @@ BOOL CMainFrame::DoFileOpen(LPCTSTR pszLeft /*=NULL*/, LPCTSTR pszRight /*=NULL*
                if (files_isFileReadOnly(strRight))
                        bRORight = TRUE;
        
+               gLog.Write(LOGLEVEL::LNOTICE, _T("Open files: Left: %s\n\tRight: %s."),
+                       strLeft, strRight);
+               
                ShowMergeDoc(pDirDoc, strLeft, strRight, bROLeft, bRORight,
                        cpleft, cpright, &infoUnpacker);
        }
@@ -2267,6 +2297,9 @@ void CMainFrame::OnDropFiles(HDROP dropInfo)
                files[1] = files[0];
        }
 
+       gLog.Write(LOGLEVEL::LNOTICE, _T("D&D open: Left: %s\n\tRight: %s."),
+               files[0], files[1]);
+
        DoFileOpen(files[0], files[1], FFILEOPEN_NONE, FFILEOPEN_NONE, ctrlKey);
 }
 
@@ -2416,4 +2449,3 @@ void CMainFrame::OnFileNew()
        ShowMergeDoc(pDirDoc, _T(""), _T(""), FALSE, FALSE, 0, 0);
 }
 
-
index 93ad33f..8584201 100644 (file)
@@ -56,6 +56,7 @@
 static char THIS_FILE[] = __FILE__;
 #endif
 
+extern CLogFile gLog;
 
 /**
  * @brief EOL types
@@ -1357,7 +1358,13 @@ LoadFromFileExit:
 
        // delete the file that unpacking may have created
        if (_tcscmp(pszFileNameInit, pszFileName) != 0)
-               ::DeleteFile(pszFileName);
+               if (!::DeleteFile(pszFileName))
+               {
+                       LogErrorString(Fmt(_T("DeleteFile(%s) failed: %s"),
+                               pszFileName, GetSysError(GetLastError())));
+                       gLog.Write(LOGLEVEL::LERROR, _T("DeleteFile(%s) failed: %s"),
+                               pszFileName, GetSysError(GetLastError()));
+               }
 
        return nRetVal;
 }
@@ -1450,21 +1457,39 @@ int CMergeDoc::CDiffTextBuffer::SaveToFile (LPCTSTR pszFileName,
                infoUnpacker->subcode = unpackerSubcode;
                if (!FileTransform_Packing(csTempFileName, *infoUnpacker))
                {
-                       ::DeleteFile(sIntermediateFilename);
+                       if (!::DeleteFile(sIntermediateFilename))
+                       {
+                               LogErrorString(Fmt(_T("DeleteFile(%s) failed: %s"),
+                                       sIntermediateFilename, GetSysError(GetLastError())));
+                               gLog.Write(LOGLEVEL::LERROR, _T("DeleteFile(%s) failed: %s"),
+                                       sIntermediateFilename, GetSysError(GetLastError()));
+                       }
                        // returns now, don't overwrite the original file
                        return SAVE_PACK_FAILED;
                }
                // the temp filename may have changed during packing
                if (csTempFileName != sIntermediateFilename)
                {
-                       ::DeleteFile(sIntermediateFilename);
+                       if (!::DeleteFile(sIntermediateFilename))
+                       {
+                               LogErrorString(Fmt(_T("DeleteFile(%s) failed: %s"),
+                                       sIntermediateFilename, GetSysError(GetLastError())));
+                               gLog.Write(LOGLEVEL::LERROR, _T("DeleteFile(%s) failed: %s"),
+                                       sIntermediateFilename, GetSysError(GetLastError()));
+                       }
                        sIntermediateFilename = csTempFileName;
                }
 
                // Write tempfile over original file
                if (::CopyFile(sIntermediateFilename, pszFileName, FALSE))
                {
-                       ::DeleteFile(sIntermediateFilename);
+                       if (!::DeleteFile(sIntermediateFilename))
+                       {
+                               LogErrorString(Fmt(_T("DeleteFile(%s) failed: %s"),
+                                       sIntermediateFilename, GetSysError(GetLastError())));
+                               gLog.Write(LOGLEVEL::LERROR, _T("DeleteFile(%s) failed: %s"),
+                                       sIntermediateFilename, GetSysError(GetLastError()));
+                       }
                        if (bClearModifiedFlag)
                        {
                                SetModified(FALSE);
@@ -1586,16 +1611,24 @@ void CMergeDoc::CleanupTempFiles()
                if (::DeleteFile(m_strTempLeftFile))
                        m_strTempLeftFile = _T("");
                else
-                       LogErrorString(Fmt(_T("DeleteFile(%s) failed: %s")
-                               , m_strTempLeftFile, GetSysError(GetLastError())));
+               {
+                       LogErrorString(Fmt(_T("DeleteFile(%s) failed: %s"),
+                               m_strTempLeftFile, GetSysError(GetLastError())));
+                       gLog.Write(LOGLEVEL::LERROR, _T("DeleteFile(%s) failed: %s"),
+                               m_strTempLeftFile, GetSysError(GetLastError()));
+               }
        }
        if (!m_strTempRightFile.IsEmpty())
        {
                if (::DeleteFile(m_strTempRightFile))
                        m_strTempRightFile = _T("");
                else
-                       LogErrorString(Fmt(_T("DeleteFile(%s) failed: %s")
-                               , m_strTempRightFile, GetSysError(GetLastError())));
+               {
+                       LogErrorString(Fmt(_T("DeleteFile(%s) failed: %s"),
+                               m_strTempRightFile, GetSysError(GetLastError())));
+                       gLog.Write(LOGLEVEL::LERROR, _T("DeleteFile(%s) failed: %s"),
+                               m_strTempRightFile, GetSysError(GetLastError()));
+               }
        }
 }
 
@@ -2553,4 +2586,3 @@ void CMergeDoc::UpdateHeaderActivity(BOOL bLeft, BOOL bActivate)
        pf->GetHeaderInterface()->SetActive(nPane, bActivate);
 }
 
-
index 7d51d63..54f1c3d 100644 (file)
 //     stdafx.obj will contain the pre-compiled type information
 
 #include "stdafx.h"
+#include "LogFile.h"
+
+// Logging
+CLogFile gLog;
 
 // fix any nonascii characters
 // which got sign-extended to become negative integers
@@ -109,3 +113,4 @@ int GetClipTcharTextFormat()
        return CF_TEXT;
 #endif // _UNICODE
 }
+
index b48d485..df3050a 100644 (file)
@@ -3,6 +3,11 @@
   Src: DirActions.cpp
  PATCH: [ 889115 ] Delete transformed temp files in file compare
   Src: DiffWrapper.cpp
+ PATCH: [ 889334 ] Improve and enable logging
+  Logging is now enabled for debug builds, written to $temp/WinMerge.log
+  Common: LogFile.cpp LogFile.h
+  Src: DiffWrapper.cpp DirActions.cpp DirDoc.cpp DirScan.cpp
+   MainFrm.cpp MergeDoc.cpp StdAfx.cpp
 
 2004-02-01 Perry
  Cosmetic: fix copy&paste error in UniFile.cpp comment.