OSDN Git Service

PATCH: [ 1460749 ] Print relative paths to patch files
authorKimmo Varis <kimmov@gmail.com>
Wed, 5 Apr 2006 15:01:32 +0000 (15:01 +0000)
committerKimmo Varis <kimmov@gmail.com>
Wed, 5 Apr 2006 15:01:32 +0000 (15:01 +0000)
Src/Changes.txt
Src/DiffWrapper.cpp
Src/DiffWrapper.h
Src/MainFrm.cpp
Src/MergeDoc.cpp
Src/PatchDlg.h
Src/PatchTool.cpp
Src/PatchTool.h

index 32759d5..05b3f22 100644 (file)
@@ -2,6 +2,11 @@ Src\Changes.txt
 Add new items to top.
 (This summarizes all changes to all files under Src, including Src\Languages.)
 
+2006-04-05 Kimmo
+ PATCH: [ 1460749 ] Print relative paths to patch files
+  Src: DiffWrapper.cpp DiffWrapper.h MainFrm.cpp MergeDoc.cpp PatchDlg.h
+   PatchTool.cpp PatchTool.h
+
 2006-04-05 Takashi
  BUG: [ 1458714 ] [Replace All] doesn't work
   Src/editlib: ceditreplacedlg.cpp
index e74ba15..3e57e75 100644 (file)
@@ -86,6 +86,9 @@ CDiffWrapper::CDiffWrapper()
        line_end_char = '\n';
 }
 
+/**
+ * @brief Destructor.
+ */
 CDiffWrapper::~CDiffWrapper()
 {
        if (m_infoPrediffer)
@@ -93,16 +96,20 @@ CDiffWrapper::~CDiffWrapper()
 }
 
 /**
- * @brief Sets filename of produced patch-file
+ * @brief Sets filename of produced patch-file.
+ * @param [in] file Filename of patch file.
  */
-void CDiffWrapper::SetPatchFile(CString file)
+void CDiffWrapper::SetPatchFile(const CString &file)
 {
        m_sPatchFile = file;
        m_sPatchFile.Replace('/', '\\');
 }
 
 /**
- * @brief Sets pointer to external diff-list filled when analysing files
+ * @brief Sets pointer to DiffList getting compare results.
+ * CDiffWrapper adds compare results to DiffList. This function
+ * sets external DiffList which gets compare results.
+ * @param [in] difflist Pointer to DiffList getting compare results.
  */
 void CDiffWrapper::SetDiffList(DiffList *diffList)
 {
@@ -111,18 +118,24 @@ void CDiffWrapper::SetDiffList(DiffList *diffList)
 }
 
 /**
- * @brief Returns current set of options used by diff-engine
+ * @brief Returns current set of options used by diff-engine.
+ * This function converts internally used diff-options to
+ * format used outside CDiffWrapper and returns them.
+ * @param [in,out] options Pointer to structure getting used options.
  */
-void CDiffWrapper::GetOptions(DIFFOPTIONS *options)
+void CDiffWrapper::GetOptions(DIFFOPTIONS *options) const
 {
        ASSERT(options);
        InternalGetOptions(options);
 }
 
 /**
- * @brief Set options used by diff-engine
+ * @brief Set options for Diff-engine.
+ * This function converts given options to format CDiffWrapper uses
+ * internally and stores them.
+ * @param [in] options Pointer to structure having new options.
  */
-void CDiffWrapper::SetOptions(DIFFOPTIONS *options)
+void CDiffWrapper::SetOptions(const DIFFOPTIONS *options)
 {
        ASSERT(options);
        InternalSetOptions(options);
@@ -132,7 +145,7 @@ void CDiffWrapper::SetOptions(DIFFOPTIONS *options)
  * @brief Set text tested to find the prediffer automatically.
  * Most probably a concatenated string of both filenames.
  */
-void CDiffWrapper::SetTextForAutomaticPrediff(CString text)
+void CDiffWrapper::SetTextForAutomaticPrediff(const CString &text)
 {
        m_sToFindPrediffer = text;
 }
@@ -153,9 +166,10 @@ void CDiffWrapper::GetPrediffer(PrediffingInfo * prediffer)
 }
 
 /**
- * @brief Get options used for patch creation
+ * @brief Returns current set of options used for patch-file creation.
+ * @param [in, out] options Pointer to structure where options are stored.
  */
-void CDiffWrapper::GetPatchOptions(PATCHOPTIONS *options)
+void CDiffWrapper::GetPatchOptions(PATCHOPTIONS *options) const
 {
        ASSERT(options);
        options->nContext = m_settings.context;
@@ -164,9 +178,10 @@ void CDiffWrapper::GetPatchOptions(PATCHOPTIONS *options)
 }
 
 /**
- * @brief Set options used for patch creation
+ * @brief Set options used for patch-file creation.
+ * @param [in] options Pointer to structure having new options.
  */
-void CDiffWrapper::SetPatchOptions(PATCHOPTIONS *options)
+void CDiffWrapper::SetPatchOptions(const PATCHOPTIONS *options)
 {
        ASSERT(options);
        m_settings.context = options->nContext;
@@ -175,7 +190,11 @@ void CDiffWrapper::SetPatchOptions(PATCHOPTIONS *options)
 }
 
 /**
- * @brief Determines if external diff-list is used
+ * @brief Determines if external results-list is used.
+ * When diff'ing files results are stored to external DiffList,
+ * set by SetDiffList(). This function determines if we are currently
+ * using that external list.
+ * @return TRUE if results are added to external DiffList.
  */
 BOOL CDiffWrapper::GetUseDiffList() const
 {
@@ -183,7 +202,11 @@ BOOL CDiffWrapper::GetUseDiffList() const
 }
 
 /**
- * @brief Enables/disables external diff-list usage
+ * @brief Enables/disables external result-list.
+ * CDiffWrapper uses external DiffList to return compare results.
+ * This function enables/disables usage of that external DiffList.
+ * @param [in] bUseDifList TRUE if external DiffList is used.
+ * @return Old value of the setting.
  */
 BOOL CDiffWrapper::SetUseDiffList(BOOL bUseDiffList)
 {
@@ -193,7 +216,8 @@ BOOL CDiffWrapper::SetUseDiffList(BOOL bUseDiffList)
 }
 
 /**
- * @brief Determines if patch-file is created
+ * @brief Determines if patch-file is created.
+ * @return TRUE if patch file will be created.
  */
 BOOL CDiffWrapper::GetCreatePatchFile() const 
 {
@@ -201,7 +225,9 @@ BOOL CDiffWrapper::GetCreatePatchFile() const
 }
 
 /**
- * @brief Enables/disables creation of patch-file
+ * @brief Enables/disables creation of patch-file.
+ * @param [in] bCreatePatchFile If TRUE patch file will be created.
+ * @return Previous value for setting.
  */
 BOOL CDiffWrapper::SetCreatePatchFile(BOOL bCreatePatchFile)
 {
@@ -211,10 +237,38 @@ BOOL CDiffWrapper::SetCreatePatchFile(BOOL bCreatePatchFile)
 }
 
 /**
- * @brief Runs diff-engine
+ * @brief Set source paths for diffing two files.
+ * Sets full paths to two files we are diffing.
+ * @param [in] filepath1 First file to compare "original file".
+ * @param [in] filepath2 Second file to compare "changed file".
+ */
+void CDiffWrapper::SetPaths(const CString &filepath1, const CString &filepath2)
+{
+       m_s1File = filepath1;
+       m_s2File = filepath2;
+}
+
+/**
+ * @brief Set alternative paths for compared files.
+ * Sets alternative paths for diff'ed files. These alternative paths might not
+ * be real paths. For example when creating a patch file from folder compare
+ * we want to use relative paths.
+ * @param [in] altPath1 Alternative file path of first file.
+ * @param [in] altPath2 Alternative file path of second file.
  */
-BOOL CDiffWrapper::RunFileDiff(CString & filepath1, CString & filepath2, ARETEMPFILES areTempFiles)
+void CDiffWrapper::SetAlternativePaths(const CString &altPath1, const CString &altPath2)
 {
+       m_s1AlternativePath = altPath1;
+       m_s2AlternativePath = altPath2;
+}
+
+/**
+ * @brief Runs diff-engine.
+ */
+BOOL CDiffWrapper::RunFileDiff(ARETEMPFILES areTempFiles)
+{
+       CString filepath1(m_s1File);
+       CString filepath2(m_s2File);
        filepath1.Replace('/', '\\');
        filepath2.Replace('/', '\\');
 
@@ -329,7 +383,7 @@ BOOL CDiffWrapper::RunFileDiff(CString & filepath1, CString & filepath2, ARETEMP
        // Create patch file
        if (!m_status.bBinaries && m_bCreatePatchFile)
        {
-               WritePatchFile(script, filepath1, filepath1, &inf[0]);
+               WritePatchFile(script, &inf[0]);
        }
        
        // Go through diffs adding them to WinMerge's diff list
@@ -372,7 +426,7 @@ BOOL CDiffWrapper::RunFileDiff(CString & filepath1, CString & filepath2, ARETEMP
 /**
  * @brief Return current diffutils options
  */
-void CDiffWrapper::InternalGetOptions(DIFFOPTIONS *options)
+void CDiffWrapper::InternalGetOptions(DIFFOPTIONS *options) const
 {
        int nIgnoreWhitespace = 0;
 
@@ -391,7 +445,7 @@ void CDiffWrapper::InternalGetOptions(DIFFOPTIONS *options)
 /**
  * @brief Set diffutils options
  */
-void CDiffWrapper::InternalSetOptions(DIFFOPTIONS *options)
+void CDiffWrapper::InternalSetOptions(const DIFFOPTIONS *options)
 {
        m_settings.ignoreAllSpace = (options->nIgnoreWhitespace == WHITESPACE_IGNORE_ALL);
        m_settings.ignoreSpaceChange = (options->nIgnoreWhitespace == WHITESPACE_IGNORE_CHANGE);
@@ -1877,24 +1931,27 @@ CDiffWrapper::LoadWinMergeDiffsFromDiffUtilsScript(struct change * script, const
  * Writes patch file using already computed diffutils script. Converts path
  * delimiters from \ to / since we want to keep compatibility with patch-tools.
  * @param [in] script list of changes.
- * @param [in] filepath1 first file
- * @param [in] filepath2 second file
  * @param [in] inf file_data table containing filenames
  * @todo filepath1 and filepath2 aren't really needed, paths are already in inf.
  */
-void CDiffWrapper::WritePatchFile(struct change * script,
-               const CString & filepath1, const CString & filepath2,
-               file_data * inf)
+void CDiffWrapper::WritePatchFile(struct change * script, file_data * inf)
 {
        USES_CONVERSION;
        file_data inf_patch[2] = {0};
        CopyMemory(&inf_patch, inf, sizeof(file_data) * 2);
-       CString pathLeft = inf_patch[0].name;
-       pathLeft.Replace('\\', '/');
-       CString pathRight = inf_patch[1].name;
-       pathRight.Replace('\\', '/');
-       inf_patch[0].name = strdup(T2CA(pathLeft));
-       inf_patch[1].name = strdup(T2CA(pathRight));
+       
+       // Get paths, primarily use alternative paths, only if they are empty
+       // use full filepaths
+       CString path1(m_s1AlternativePath);
+       CString path2(m_s2AlternativePath);
+       if (path1.IsEmpty())
+               path1 = m_s1File;
+       if (path2.IsEmpty())
+               path2 = m_s2File;
+       path1.Replace('\\', '/');
+       path2.Replace('\\', '/');
+       inf_patch[0].name = strdup(T2CA(path1));
+       inf_patch[1].name = strdup(T2CA(path2));
 
        outfile = NULL;
        if (!m_sPatchFile.IsEmpty())
@@ -1914,7 +1971,7 @@ void CDiffWrapper::WritePatchFile(struct change * script,
        {
                CString switches = FormatSwitchString();
                _ftprintf(outfile, _T("diff%s %s %s\n"),
-                       switches, filepath1, filepath2);
+                       switches, path1, path2);
        }
 
        // Output patchfile
index f0fa5b0..5743745 100644 (file)
@@ -84,10 +84,10 @@ typedef enum {
  */
 struct DIFFOPTIONS
 {
-       int nIgnoreWhitespace;
-       BOOL bIgnoreCase;
-       BOOL bIgnoreBlankLines;
-       BOOL bIgnoreEol;
+       int nIgnoreWhitespace; /**< Ignore whitespace -option. */
+       BOOL bIgnoreCase; /**< Ignore case -option. */
+       BOOL bIgnoreBlankLines; /**< Ignore blank lines -option. */
+       BOOL bIgnoreEol; /**< Ignore EOL differences -option. */
 };
 
 /**
@@ -95,9 +95,9 @@ struct DIFFOPTIONS
  */
 struct PATCHOPTIONS
 {
-       enum output_style outputStyle;
-       int nContext;
-       BOOL bAddCommandline;
+       enum output_style outputStyle; /**< Patch file style. */
+       int nContext; /**< Number of context lines. */
+       BOOL bAddCommandline; /**< Add diff-style commandline to patch file. */
 };
 
 /**
@@ -142,15 +142,15 @@ class CDiffWrapper
 public:
        CDiffWrapper();
        ~CDiffWrapper();
-       void SetPatchFile(CString file);
+       void SetPatchFile(const CString &file);
        void SetDiffList(DiffList *diffList);
-       void GetOptions(DIFFOPTIONS *options);
-       void SetOptions(DIFFOPTIONS *options);
-       void SetTextForAutomaticPrediff(CString text);
+       void GetOptions(DIFFOPTIONS *options) const;
+       void SetOptions(const DIFFOPTIONS *options);
+       void SetTextForAutomaticPrediff(const CString &text);
        void SetPrediffer(PrediffingInfo * prediffer =NULL);
        void GetPrediffer(PrediffingInfo * prediffer);
-       void GetPatchOptions(PATCHOPTIONS *options);
-       void SetPatchOptions(PATCHOPTIONS *options);
+       void GetPatchOptions(PATCHOPTIONS *options) const;
+       void SetPatchOptions(const PATCHOPTIONS *options);
        BOOL GetUseDiffList() const;
        BOOL SetUseDiffList(BOOL bUseDiffList);
        void SetDetectMovedBlocks(BOOL bDetectMovedBlocks) { m_bDetectMovedBlocks = bDetectMovedBlocks; }
@@ -159,7 +159,9 @@ public:
        BOOL SetAppendFiles(BOOL bAppendFiles);
        BOOL GetCreatePatchFile() const;
        BOOL SetCreatePatchFile(BOOL bCreatePatchFile);
-       BOOL RunFileDiff(CString & filepath1, CString & filepath2, ARETEMPFILES areTempFiles);
+       void SetPaths(const CString &filepath1, const CString &filepath2);
+       void SetAlternativePaths(const CString &altPath1, const CString &altPath2);
+       BOOL RunFileDiff(ARETEMPFILES areTempFiles);
        void GetDiffStatus(DIFFSTATUS *status);
        void AddDiffRange(UINT begin0, UINT end0, UINT begin1, UINT end1, BYTE op);
        void FixLastDiffRange(int leftBufferLines, int rightBufferLines, BOOL left);
@@ -172,30 +174,34 @@ public:
        void ClearMovedLists();
 
 protected:
-       void InternalGetOptions(DIFFOPTIONS *options);
-       void InternalSetOptions(DIFFOPTIONS *options);
+       void InternalGetOptions(DIFFOPTIONS *options) const;
+       void InternalSetOptions(const DIFFOPTIONS *options);
        void SwapToInternalSettings();
        void SwapToGlobalSettings();
        CString FormatSwitchString();
        BOOL Diff2Files(struct change ** diffs, DiffFileData *diffData,
                int * bin_status);
        void LoadWinMergeDiffsFromDiffUtilsScript(struct change * script, const file_data * inf);
-       void WritePatchFile(struct change * script, const CString & filepath1, const CString & filepath2, file_data * inf);
+       void WritePatchFile(struct change * script, file_data * inf);
 
 private:
-       DIFFSETTINGS m_settings;
+       DIFFSETTINGS m_settings; 
        DIFFSETTINGS m_globalSettings;  // Temp for storing globals
        DIFFSTATUS m_status;
-       CString m_sPatchFile;
+       CString m_s1File; /**< Full path to first diff'ed file. */
+       CString m_s2File; /**< Full path to second diff'ed file. */
+       CString m_s1AlternativePath; /**< First file's alternative path (may be relative). */
+       CString m_s2AlternativePath; /**< Second file's alternative path (may be relative). */
+       CString m_sPatchFile; /**< Full path to created patch file. */
        /// prediffer info are stored only for MergeDoc
        PrediffingInfo * m_infoPrediffer;
        /// prediffer info are stored only for MergeDoc
        CString m_sToFindPrediffer;
-       BOOL m_bUseDiffList;
-       BOOL m_bDetectMovedBlocks;
-       BOOL m_bCreatePatchFile;
-       BOOL m_bAddCmdLine;
-       BOOL m_bAppendFiles;
+       BOOL m_bUseDiffList; /**< Are results returned in difflist? */
+       BOOL m_bDetectMovedBlocks; /**< Are moved blocks detected? */
+       BOOL m_bCreatePatchFile; /**< Do we create a patch file? */
+       BOOL m_bAddCmdLine; /**< Do we add commandline to patch file? */
+       BOOL m_bAppendFiles; /**< Do we append to existing patch file? */
        int m_nDiffs;
        DiffList *m_pDiffList;
        CMap<int, int, int, int> m_moved0;
index 4953035..3accd04 100644 (file)
@@ -1966,26 +1966,46 @@ void CMainFrame::OnToolsGeneratePatch()
                CDirView *pView = pDoc->GetMainView();
 
                // Get selected items from folder compare
+               BOOL bValidFiles = TRUE;
                int ind = pView->GetFirstSelectedInd();
-               while (ind != -1)
+               while (ind != -1 && bValidFiles)
                {
                        const DIFFITEM item = pView->GetItemAt(ind);
                        if (item.isBin())
+                       {
                                AfxMessageBox(IDS_CANNOT_CREATE_BINARYPATCH, MB_ICONWARNING |
                                        MB_DONT_DISPLAY_AGAIN, IDS_CANNOT_CREATE_BINARYPATCH);
+                               bValidFiles = FALSE;
+                       }
                        else if (item.isDirectory())
+                       {
                                AfxMessageBox(IDS_CANNOT_CREATE_DIRPATCH, MB_ICONWARNING |
                                        MB_DONT_DISPLAY_AGAIN, IDS_CANNOT_CREATE_DIRPATCH);
+                               bValidFiles = FALSE;
+                       }
 
-                       CString leftFile = item.getLeftFilepath(pDoc->GetLeftBasePath());
-                       if (!leftFile.IsEmpty())
-                               leftFile += _T("\\") + item.sLeftFilename;
-                       CString rightFile = item.getRightFilepath(pDoc->GetRightBasePath());
-                       if (!rightFile.IsEmpty())
-                               rightFile += _T("\\") + item.sRightFilename;
-
-                       patcher.AddFiles(leftFile, rightFile);
-                       pView->GetNextSelectedInd(ind);
+                       if (bValidFiles)
+                       {
+                               // Format full paths to files (leftFile/rightFile)
+                               CString leftFile = item.getLeftFilepath(pDoc->GetLeftBasePath());
+                               if (!leftFile.IsEmpty())
+                                       leftFile += _T("\\") + item.sLeftFilename;
+                               CString rightFile = item.getRightFilepath(pDoc->GetRightBasePath());
+                               if (!rightFile.IsEmpty())
+                                       rightFile += _T("\\") + item.sRightFilename;
+
+                               // Format relative paths to files in folder compare
+                               CString leftpatch = item.sLeftSubdir;
+                               if (!leftpatch.IsEmpty())
+                                       leftpatch += _T("/");
+                               leftpatch += item.sLeftFilename;
+                               CString rightpatch = item.sRightSubdir;
+                               if (!rightpatch.IsEmpty())
+                                       rightpatch += _T("/");
+                               rightpatch += item.sRightFilename;
+                               patcher.AddFiles(leftFile, leftpatch, rightFile, rightpatch);
+                               pView->GetNextSelectedInd(ind);
+                       }
                }
        }
 
index bb81c05..143628a 100644 (file)
@@ -430,10 +430,9 @@ int CMergeDoc::Rescan(BOOL &bBinary, BOOL &bIdentical,
        // Clear moved lines lists
        m_diffWrapper.ClearMovedLists();
 
-       // Run diff
-       CString sLeftFilepath = m_pTempFiles->GetLeft();
-       CString sRightFilepath = m_pTempFiles->GetRight();
-       diffSuccess = m_diffWrapper.RunFileDiff(sLeftFilepath, sRightFilepath, YESTEMPFILES);
+       // Set paths for diffing and run diff
+       m_diffWrapper.SetPaths(m_pTempFiles->GetLeft(), m_pTempFiles->GetRight());
+       diffSuccess = m_diffWrapper.RunFileDiff(YESTEMPFILES);
 
        // Read diff-status
        DIFFSTATUS status;
index 8a8e4f6..6af6d27 100644 (file)
 struct PATCHFILES
 {
        CString lfile; /**< Left file */
+       CString pathLeft; /**< Left path added to patch file */
        CString rfile; /**< Right file */
+       CString pathRight; /**< Right path added to patch file */
        time_t ltime; /**< Left time */
        time_t rtime; /**< Right time */
+       PATCHFILES() : ltime(0), rtime(0) {};
 };
 
 /** 
index 5086e9b..a6766d4 100644 (file)
@@ -32,7 +32,7 @@
 /** 
  * @brief Adds files to list for patching
  */
-void CPatchTool::AddFiles(CString file1, CString file2)
+void CPatchTool::AddFiles(const CString &file1, const CString &file2)
 {
        PATCHFILES files;
        files.lfile = file1;
@@ -42,6 +42,19 @@ void CPatchTool::AddFiles(CString file1, CString file2)
        m_fileList.AddTail(files);
 }
 
+void CPatchTool::AddFiles(const CString &file1, const CString &altPath1,
+               const CString &file2, const CString &altPath2)
+{
+       PATCHFILES files;
+       files.lfile = file1;
+       files.rfile = file2;
+       files.pathLeft = altPath1;
+       files.pathRight = altPath2;
+
+       // TODO: Read and add file's timestamps
+       m_fileList.AddTail(files);
+}
+
 /** 
  * @brief Create patch from files given
  * @note Files can be given using AddFiles() or selecting using
@@ -90,7 +103,9 @@ int CPatchTool::CreatePatch()
                        
                        // Set up DiffWrapper
                        m_diffWrapper.SetPrediffer(NULL);
-                       bDiffSuccess = m_diffWrapper.RunFileDiff(filename1, filename2, NOTEMPFILES);
+                       m_diffWrapper.SetPaths(files.lfile, files.rfile);
+                       m_diffWrapper.SetAlternativePaths(files.pathLeft, files.pathRight);
+                       bDiffSuccess = m_diffWrapper.RunFileDiff(NOTEMPFILES);
                        m_diffWrapper.GetDiffStatus(&status);
 
                        if (!bDiffSuccess)
index 0e23c95..3f60614 100644 (file)
 #include "PatchDlg.h"
 
 /** 
- * @brief Provides patch creation functionality
+ * @brief Provides patch creation functionality.
  */
 class CPatchTool
 {
 public:
-       void AddFiles(CString file1, CString file2);
+       void AddFiles(const CString &file1, const CString &file2);
+       void AddFiles(const CString &file1, const CString &altPath1,
+               const CString &file2, const CString &altPath2);
        int CreatePatch();
        CString GetPatchFile() const;
        BOOL GetOpenToEditor() const;
@@ -42,11 +44,11 @@ protected:
        BOOL ShowDialog();
 
 private:
-       CList<PATCHFILES,PATCHFILES> m_fileList;
-       CDiffWrapper m_diffWrapper;
-       CPatchDlg m_dlgPatch;
-       CString m_sPatchFile;
-       BOOL m_bOpenToEditor;
+       CList<PATCHFILES, PATCHFILES&> m_fileList; /**< List of files to patch. */
+       CDiffWrapper m_diffWrapper; /**< DiffWrapper instance we use to create patch. */
+       CPatchDlg m_dlgPatch; /**< Dialog for selecting files and options. */
+       CString m_sPatchFile; /**< Patch file path and filename. */
+       BOOL m_bOpenToEditor; /**< Is patch file opened to external editor? */
 };
 
 #endif // _PATCHTOOL_H_
\ No newline at end of file