OSDN Git Service

Fix a crash problem when the Diff algorithm is set to something other than default...
[winmerge-jp/winmerge-jp.git] / Src / 7zCommon.cpp
index b5923c2..aff4d10 100644 (file)
@@ -151,17 +151,17 @@ Merge7z::Format *ArchiveGuessFormat(const String& path)
                return nullptr;\r
        String path2(path);\r
        // Map extensions through ExternalArchiveFormat.ini\r
-       static TCHAR null[] = _T("");\r
-       static const TCHAR section[] = _T("extensions");\r
+       static tchar_t null[] = _T("");\r
+       static const tchar_t section[] = _T("extensions");\r
        String entry = paths::FindExtension(path);\r
-       TCHAR value[20];\r
-       static LPCTSTR filename = nullptr;\r
+       tchar_t value[20];\r
+       static const tchar_t* filename = nullptr;\r
        if (filename == nullptr)\r
        {\r
-               TCHAR cPath[INTERNET_MAX_PATH_LENGTH];\r
+               tchar_t cPath[INTERNET_MAX_PATH_LENGTH];\r
                DWORD cchPath = SearchPath(nullptr, _T("ExternalArchiveFormat.ini"), nullptr,\r
                        INTERNET_MAX_PATH_LENGTH, cPath, nullptr);\r
-               filename = cchPath && cchPath < INTERNET_MAX_PATH_LENGTH ? _tcsdup(cPath) : null;\r
+               filename = cchPath && cchPath < INTERNET_MAX_PATH_LENGTH ? tc::tcsdup(cPath) : null;\r
        }\r
        if (*filename &&\r
                GetPrivateProfileString(section, entry.c_str(), null, value, 20, filename) &&\r
@@ -169,7 +169,7 @@ Merge7z::Format *ArchiveGuessFormat(const String& path)
        {\r
                // Remove end-of-line comments (in string returned from GetPrivateProfileString)\r
                // that is, remove semicolon & whatever follows it\r
-               if (LPTSTR p = StrChr(value, ';'))\r
+               if (tchar_t* p = StrChr(value, ';'))\r
                {\r
                        *p = '\0';\r
                        StrTrim(value, _T(" \t"));\r
@@ -190,7 +190,9 @@ Merge7z::Format *ArchiveGuessFormat(const String& path)
 \r
        try\r
        {\r
-               Merge7z::Format *pFormat = m_Merge7z->GuessFormat(path2.c_str());\r
+               Merge7z::Format* pFormat = nullptr;\r
+               if (!paths::IsURL(path2))\r
+                       pFormat = m_Merge7z->GuessFormat(path2.c_str());\r
                if (pFormat == nullptr)\r
                        pFormat = Merge7zFormatRegister::GuessFormat(path2);\r
                return pFormat;\r
@@ -316,7 +318,7 @@ Merge7z::Envelope *SingleItemEnumerator::Enum(Item &item)
 /**\r
  * @brief SingleFileEnumerator constructor.\r
  */\r
-SingleItemEnumerator::SingleItemEnumerator(LPCTSTR path, LPCTSTR FullPath, LPCTSTR Name)\r
+SingleItemEnumerator::SingleItemEnumerator(const tchar_t* path, const tchar_t* FullPath, const tchar_t* Name)\r
 : FullPath(FullPath)\r
 , Name(Name)\r
 {\r
@@ -406,9 +408,17 @@ const DIFFITEM &DirItemEnumerator::Next()
        while ((m_nIndex = pView(m_pView)->GetNextItem(m_nIndex, m_nFlags & nMask)) == -1)\r
        {\r
                m_strFolderPrefix = *m_curFolderPrefix++;\r
-               m_index = 1;\r
+               m_index++;\r
        }\r
-       return m_pView->GetDiffItem(m_nIndex);\r
+       const auto& di = m_pView->GetDiffItem(m_nIndex);\r
+       for (const auto* pfdi : m_selectedFolderDiffItems)\r
+       {\r
+               if (di.IsAncestor(pfdi))\r
+                       return *DIFFITEM::GetEmptyItem();\r
+       }\r
+       if (di.diffcode.isDirectory())\r
+               m_selectedFolderDiffItems.push_back(&di);\r
+       return di;\r
 }\r
 \r
 /**\r
@@ -430,7 +440,7 @@ Merge7z::Envelope *DirItemEnumerator::Enum(Item &item)
        const CDiffContext& ctxt = m_pView->GetDiffContext();\r
        const DIFFITEM &di = Next();\r
 \r
-       if ((m_nFlags & DiffsOnly) && !IsItemNavigableDiff(ctxt, di))\r
+       if (di.isEmpty() || ((m_nFlags & DiffsOnly) && !IsItemNavigableDiff(ctxt, di)))\r
        {\r
                return 0;\r
        }\r
@@ -492,7 +502,7 @@ Merge7z::Envelope *DirItemEnumerator::Enum(Item &item)
 /**\r
  * @brief Apply appropriate handlers from left to right.\r
  */\r
-bool DirItemEnumerator::MultiStepCompressArchive(LPCTSTR path)\r
+bool DirItemEnumerator::MultiStepCompressArchive(const tchar_t* path)\r
 {\r
        DeleteFile(path);\r
        Merge7z::Format *piHandler = ArchiveGuessFormat(path);\r
@@ -523,14 +533,14 @@ bool DirItemEnumerator::MultiStepCompressArchive(LPCTSTR path)
 /**\r
  * @brief Generate archive from DirView items.\r
  */\r
-void DirItemEnumerator::CompressArchive(LPCTSTR path)\r
+void DirItemEnumerator::CompressArchive(const tchar_t* path)\r
 {\r
        String strPath;\r
        if (path == nullptr)\r
        {\r
                // 7z311 can only write 7z, zip, and tar(.gz|.bz2) archives, so don't\r
                // offer other formats here!\r
-               static const TCHAR _T_Filter[]\r
+               static const tchar_t _T_Filter[]\r
                (\r
                        _T("7z|*.7z|")\r
                        //_T("z|*.z|")\r
@@ -600,8 +610,8 @@ DecompressResult DecompressArchive(HWND hWnd, const PathContext& files)
        DecompressResult res(files, nullptr, paths::IS_EXISTING_DIR);\r
        try\r
        {\r
+               HRESULT hr;\r
                String path;\r
-               USES_CONVERSION;\r
                // Handle archives using 7-zip\r
                Merge7z::Format *piHandler;\r
                piHandler = ArchiveGuessFormat(res.files[0]);\r
@@ -615,14 +625,18 @@ DecompressResult DecompressArchive(HWND hWnd, const PathContext& files)
                                res.files[1].erase();\r
                        do\r
                        {\r
-                               if (FAILED(piHandler->DeCompressArchive(hWnd, res.files[0].c_str(), path.c_str())))\r
+                               hr = piHandler->DeCompressArchive(hWnd, res.files[0].c_str(), path.c_str());\r
+                               if (FAILED(hr))\r
+                               {\r
+                                       res.hr = hr;\r
                                        break;\r
+                               }\r
                                if (res.files[0].find(path) == 0)\r
                                {\r
                                        VERIFY(::DeleteFile(res.files[0].c_str()) || (LogErrorString(strutils::format(_T("DeleteFile(%s) failed"), res.files[0])), false));\r
                                }\r
                                BSTR pTmp = piHandler->GetDefaultName(hWnd, res.files[0].c_str());\r
-                               res.files[0] = OLE2T(pTmp);\r
+                               res.files[0] = ucr::toTString(pTmp);\r
                                SysFreeString(pTmp);\r
                                res.files[0].insert(0, _T("\\"));\r
                                res.files[0].insert(0, path);\r
@@ -643,8 +657,12 @@ DecompressResult DecompressArchive(HWND hWnd, const PathContext& files)
                        path = env::GetTempChildPath();\r
                        do\r
                        {\r
-                               if (FAILED(piHandler->DeCompressArchive(hWnd, res.files[1].c_str(), path.c_str())))\r
-                                       break;;\r
+                               hr = piHandler->DeCompressArchive(hWnd, res.files[1].c_str(), path.c_str());\r
+                               if (FAILED(hr))\r
+                               {\r
+                                       res.hr = hr;\r
+                                       break;\r
+                               }\r
                                if (res.files[1].find(path) == 0)\r
                                {\r
                                        VERIFY(::DeleteFile(res.files[1].c_str()) || (LogErrorString(strutils::format(_T("DeleteFile(%s) failed"), res.files[1])), false));\r
@@ -670,8 +688,12 @@ DecompressResult DecompressArchive(HWND hWnd, const PathContext& files)
                        path = env::GetTempChildPath();\r
                        do\r
                        {\r
-                               if (FAILED(piHandler->DeCompressArchive(hWnd, res.files[2].c_str(), path.c_str())))\r
-                                       break;;\r
+                               hr = piHandler->DeCompressArchive(hWnd, res.files[2].c_str(), path.c_str());\r
+                               if (FAILED(hr))\r
+                               {\r
+                                       res.hr = hr;\r
+                                       break;\r
+                               }\r
                                if (res.files[2].find(path) == 0)\r
                                {\r
                                        VERIFY(::DeleteFile(res.files[2].c_str()) || (LogErrorString(strutils::format(_T("DeleteFile(%s) failed"), res.files[2])), false));\r
@@ -694,7 +716,8 @@ DecompressResult DecompressArchive(HWND hWnd, const PathContext& files)
                        if (!PathFileExists(res.files[0].c_str()) || !PathFileExists(res.files[1].c_str()))\r
                        {\r
                                // not a Perry style patch: diff with itself...\r
-                               res.files[0] = res.files[1] = path;\r
+                               res.files[0] = path;\r
+                               res.files[1] = std::move(path);\r
                        }\r
                        else\r
                        {\r
@@ -705,6 +728,7 @@ DecompressResult DecompressArchive(HWND hWnd, const PathContext& files)
        }\r
        catch (CException *e)\r
        {\r
+               res.hr = E_FAIL;\r
                e->Delete();\r
        }\r
        return res;\r