diff --git a/sakura_core/util/file.cpp b/sakura_core/util/file.cpp index aaf52e8319..c198ab0d2d 100644 --- a/sakura_core/util/file.cpp +++ b/sakura_core/util/file.cpp @@ -996,40 +996,38 @@ void my_splitpath_w ( // ----------------------------------------------------------------------------- int FileMatchScore( const WCHAR *file1, const WCHAR *file2 ); -// フルパスからファイル名の.以降を分離する -// 2014.06.15 フォルダ名に.が含まれた場合、フォルダが分離されたのを修正 -static void FileNameSepExt( const WCHAR *file, WCHAR* pszFile, WCHAR* pszExt ) +// フルパスからファイル名と拡張子(ファイル名の.以降)を分離する +// @date 2014/06/15 moca_skr フォルダ名に.が含まれた場合、フォルダが分離されたのを修正した対応で新規作成 +static void FileNameSepExt( std::wstring_view file, std::wstring& szFile, std::wstring& szExt ) { - const WCHAR* folderPos = file; - const WCHAR* x = folderPos; - while( x ){ - x = wcschr(folderPos, L'\\'); - if( x ){ - x++; - folderPos = x; - } + const WCHAR* folderPos; + folderPos = ::wcsrchr(file.data(), L'\\'); + if( folderPos ){ + folderPos++; + }else{ + folderPos = file.data(); } - const WCHAR* p = wcschr(folderPos, L'.'); - if( p ){ - wmemcpy(pszFile, file, p - file); - pszFile[p - file] = L'\0'; - wcscpy(pszExt, p); + + if (const auto p = ::wcschr(folderPos, L'.')) + { + szFile.assign(folderPos, p - folderPos); + szExt.assign(p); }else{ - wcscpy(pszFile, file); - pszExt[0] = L'\0'; + szFile.assign(folderPos); + szExt.clear(); } } -int FileMatchScoreSepExt( const WCHAR *file1, const WCHAR *file2 ) +int FileMatchScoreSepExt( std::wstring_view file1, std::wstring_view file2 ) { - WCHAR szFile1[_MAX_PATH]; - WCHAR szFile2[_MAX_PATH]; - WCHAR szFileExt1[_MAX_PATH]; - WCHAR szFileExt2[_MAX_PATH]; + std::wstring szFile1; + std::wstring szFile2; + std::wstring szFileExt1; + std::wstring szFileExt2; FileNameSepExt(file1, szFile1, szFileExt1); FileNameSepExt(file2, szFile2, szFileExt2); - int score = FileMatchScore(szFile1, szFile2); - score += FileMatchScore(szFileExt1, szFileExt2); + int score = FileMatchScore(szFile1.data(), szFile2.data()); + score += FileMatchScore(szFileExt1.data(), szFileExt2.data()); return score; } diff --git a/sakura_core/util/file.h b/sakura_core/util/file.h index 2efdd904b4..77a065a4e7 100644 --- a/sakura_core/util/file.h +++ b/sakura_core/util/file.h @@ -114,7 +114,7 @@ bool GetLastWriteTimestamp( const WCHAR* filename, CFileTime* pcFileTime ); // O void my_splitpath_w ( const wchar_t *comln , wchar_t *drv,wchar_t *dir,wchar_t *fnm,wchar_t *ext ); #define my_splitpath_t my_splitpath_w -int FileMatchScoreSepExt( const WCHAR *file1, const WCHAR *file2 ); +int FileMatchScoreSepExt( std::wstring_view file1, std::wstring_view file2 ); void GetStrTrancateWidth( WCHAR* dest, int nSize, const WCHAR* path, HDC hDC, int nPxWidth ); void GetShortViewPath(WCHAR* dest, int nSize, const WCHAR* path, HDC hDC, int nPxWidth, bool bFitMode ); diff --git a/tests/unittests/test-file.cpp b/tests/unittests/test-file.cpp index 33d41810d7..8aebb29f60 100644 --- a/tests/unittests/test-file.cpp +++ b/tests/unittests/test-file.cpp @@ -516,6 +516,86 @@ TEST(file, CalcDirectoryDepth) EXPECT_DEATH({ CalcDirectoryDepth(nullptr); }, ".*"); } +/*! + FileMatchScoreSepExtのテスト + */ +TEST(file, FileMatchScoreSepExt) +{ + int result = 0; + + // FileNameSepExtのテストパターン + result = FileMatchScoreSepExt( + LR"(C:\TEMP\test.txt)", + LR"(C:\TEMP\TEST.TXT)"); + ASSERT_EQ(_countof(LR"(test.txt)") - 1, result); + + // FileNameSepExtのテストパターン(パスにフォルダが含まれない) + result = FileMatchScoreSepExt( + LR"(TEST.TXT)", + LR"(test.txt)"); + ASSERT_EQ(_countof(LR"(test.txt)") - 1, result); + + // FileNameSepExtのテストパターン(ファイル名がない) + result = FileMatchScoreSepExt( + LR"(C:\TEMP\.txt)", + LR"(C:\TEMP\.txt)"); + ASSERT_EQ(_countof(LR"(.txt)") - 1, result); + + // FileNameSepExtのテストパターン(拡張子がない) + result = FileMatchScoreSepExt( + LR"(C:\TEMP\test)", + LR"(C:\TEMP\test)"); + ASSERT_EQ(_countof(LR"(test)") - 1, result); + + // 全く同じパス同士の比較(ファイル名+拡張子が完全一致) + result = FileMatchScoreSepExt( + LR"(C:\TEMP\test.txt)", + LR"(C:\TEMP\TEST.TXT)"); + ASSERT_EQ(_countof(LR"(test.txt)") - 1, result); + + // 異なるパスでファイル名+拡張子が同じ(ファイル名+拡張子が完全一致) + result = FileMatchScoreSepExt( + LR"(C:\TEMP1\TEST.TXT)", + LR"(C:\TEMP2\test.txt)"); + ASSERT_EQ(_countof(LR"(test.txt)") - 1, result); + + // ファイル名が異なる1(最長一致を取得) + result = FileMatchScoreSepExt( + LR"(C:\TEMP\test.txt)", + LR"(C:\TEMP\TEST1.TST)"); + ASSERT_EQ(_countof(LR"(test)") - 1 + _countof(LR"(.t)") - 1, result); + + // ファイル名が異なる2(最長一致を取得) + result = FileMatchScoreSepExt( + LR"(C:\TEMP\test1.tst)", + LR"(C:\TEMP\TEST.TXT)"); + ASSERT_EQ(_countof(LR"(test)") - 1 + _countof(LR"(.t)") - 1, result); + + // 拡張子が異なる1(最長一致を取得) + result = FileMatchScoreSepExt( + LR"(C:\TEMP\test.txt)", + LR"(C:\TEMP\TEXT.TXTX)"); + ASSERT_EQ(_countof(LR"(te)") - 1 + _countof(LR"(.txt)") - 1, result); + + // 拡張子が異なる2(最長一致を取得) + result = FileMatchScoreSepExt( + LR"(C:\TEMP\text.txtx)", + LR"(C:\TEMP\TEST.TXT)"); + ASSERT_EQ(_countof(LR"(te)") - 1 + _countof(LR"(.txt)") - 1, result); + + // サロゲート文字を含む1 + result = FileMatchScoreSepExt( + LR"(C:\TEMP\test👉👆.TST)", + LR"(C:\TEMP\TEST👉👇.txt)"); + ASSERT_EQ(_countof(LR"(test👉)") - 1 + _countof(LR"(.t)") - 1, result); + + // サロゲート文字を含む2 + result = FileMatchScoreSepExt( + LR"(C:\TEMP\TEST👉👇.txt)", + LR"(C:\TEMP\test👉👆.TST)"); + ASSERT_EQ(_countof(LR"(test👉)") - 1 + _countof(LR"(.t)") - 1, result); +} + /*! GetExtのテスト */