diff --git a/sakura_core/CFileExt.cpp b/sakura_core/CFileExt.cpp index ea08cb42b0..7455e22aff 100644 --- a/sakura_core/CFileExt.cpp +++ b/sakura_core/CFileExt.cpp @@ -35,100 +35,73 @@ #include "CFileExt.h" #include "env/CDocTypeManager.h" -CFileExt::CFileExt() -{ - m_puFileExtInfo = NULL; - m_nCount = 0; - m_vstrFilter.resize( 1 ); - m_vstrFilter[0] = L'\0'; - -// //テキストエディタとして、既定でリストに載ってほしい拡張子 -// AppendExt( "すべてのファイル", "*" ); -// AppendExt( "テキストファイル", "txt" ); -} - -CFileExt::~CFileExt() -{ - if( m_puFileExtInfo ) free( m_puFileExtInfo ); - m_puFileExtInfo = NULL; - m_nCount = 0; -} - bool CFileExt::AppendExt( const WCHAR *pszName, const WCHAR *pszExt ) { - WCHAR szWork[_countof(m_puFileExtInfo[0].m_szExt) + 10]; - - if( !CDocTypeManager::ConvertTypesExtToDlgExt( pszExt, NULL, szWork ) ) return false; - return AppendExtRaw( pszName, szWork ); + std::wstring workExt = CDocTypeManager::ConvertTypesExtToDlgExt(pszExt, nullptr); + if (workExt.empty()) { + return false; + } + return AppendExtRaw( pszName, workExt.c_str() ); } bool CFileExt::AppendExtRaw( const WCHAR *pszName, const WCHAR *pszExt ) { - FileExtInfoTag *p; - if( NULL == pszName || pszName[0] == L'\0' ) return false; if( NULL == pszExt || pszExt[0] == L'\0' ) return false; - if( NULL == m_puFileExtInfo ) - { - p = (FileExtInfoTag*)malloc( sizeof( FileExtInfoTag ) * 1 ); - if( NULL == p ) return false; - } - else - { - p = (FileExtInfoTag*)realloc( m_puFileExtInfo, sizeof( FileExtInfoTag ) * ( m_nCount + 1 ) ); - if( NULL == p ) return false; - } - m_puFileExtInfo = p; + SFileExtInfo info; + info.m_sTypeName = pszName; + info.m_sExt = pszExt; - wcscpy( m_puFileExtInfo[m_nCount].m_szName, pszName ); - wcscpy( m_puFileExtInfo[m_nCount].m_szExt, pszExt ); - m_nCount++; + m_vFileExtInfo.push_back(std::move(info)); return true; } const WCHAR *CFileExt::GetName( int nIndex ) { - if( nIndex < 0 || nIndex >= m_nCount ) return NULL; + if( nIndex < 0 || nIndex >= GetCount() ) return nullptr; - return m_puFileExtInfo[nIndex].m_szName; + return m_vFileExtInfo[nIndex].m_sTypeName.c_str(); } const WCHAR *CFileExt::GetExt( int nIndex ) { - if( nIndex < 0 || nIndex >= m_nCount ) return NULL; + if( nIndex < 0 || nIndex >= GetCount() ) return nullptr; - return m_puFileExtInfo[nIndex].m_szExt; + return m_vFileExtInfo[nIndex].m_sExt.c_str(); } const WCHAR *CFileExt::GetExtFilter( void ) { - int i; + CreateExtFilter(m_vstrFilter); + return m_vstrFilter.data(); +} + +void CFileExt::CreateExtFilter(std::vector& output) const +{ std::wstring work; /* 拡張子フィルタの作成 */ - m_vstrFilter.resize(0); + output.resize(0); - for( i = 0; i < m_nCount; i++ ) + for (int i = 0; i < GetCount(); i++) { // "%s (%s)\0%s\0" - work = m_puFileExtInfo[i].m_szName; + work = m_vFileExtInfo[i].m_sTypeName; work.append(L" ("); - work.append(m_puFileExtInfo[i].m_szExt); + work.append(m_vFileExtInfo[i].m_sExt); work.append(L")"); work.append(L"\0", 1); - work.append(m_puFileExtInfo[i].m_szExt); + work.append(m_vFileExtInfo[i].m_sExt); work.append(L"\0", 1); - int i = (int)m_vstrFilter.size(); - m_vstrFilter.resize( i + work.length() ); - wmemcpy( &m_vstrFilter[i], &work[0], work.length() ); + size_t pos = output.size(); + output.resize(pos + work.length()); + wmemcpy(&output[pos], &work[0], work.length()); } - if( 0 == m_nCount ){ - m_vstrFilter.push_back( L'\0' ); + if( 0 == GetCount() ){ + output.push_back( L'\0' ); } - m_vstrFilter.push_back( L'\0' ); - - return &m_vstrFilter[0]; + output.push_back( L'\0' ); } diff --git a/sakura_core/CFileExt.h b/sakura_core/CFileExt.h index fabfb5f744..2bd82a5aef 100644 --- a/sakura_core/CFileExt.h +++ b/sakura_core/CFileExt.h @@ -40,8 +40,7 @@ class CFileExt { public: - CFileExt(); - ~CFileExt(); + CFileExt() = default; bool AppendExt( const WCHAR *pszName, const WCHAR *pszExt ); bool AppendExtRaw( const WCHAR *pszName, const WCHAR *pszExt ); @@ -52,21 +51,21 @@ class CFileExt //2回呼び出すと古いバッファが無効になることがあるのに注意 const WCHAR *GetExtFilter( void ); - int GetCount( void ) { return m_nCount; } + [[nodiscard]] int GetCount() const { return static_cast(m_vFileExtInfo.size()); } protected: // 2014.10.30 syat ConvertTypesExtToDlgExtをCDocTypeManagerに移動 //bool ConvertTypesExtToDlgExt( const WCHAR *pszSrcExt, WCHAR *pszDstExt ); private: + void CreateExtFilter(std::vector& output) const; - typedef struct { - WCHAR m_szName[64]; //名前(64文字以下のはず→m_szTypeName) - WCHAR m_szExt[MAX_TYPES_EXTS*3+1]; //拡張子(64文字以下のはず→m_szTypeExts) なお "*." を追加するのでそれなりに必要 - } FileExtInfoTag; + struct SFileExtInfo { + std::wstring m_sTypeName; //名前 + std::wstring m_sExt; //拡張子 + }; - int m_nCount; - FileExtInfoTag *m_puFileExtInfo; + std::vector m_vFileExtInfo; std::vector m_vstrFilter; DISALLOW_COPY_AND_ASSIGN(CFileExt); diff --git a/sakura_core/dlg/CDlgOpenFile_CommonFileDialog.cpp b/sakura_core/dlg/CDlgOpenFile_CommonFileDialog.cpp index 1678d39046..b27e974592 100644 --- a/sakura_core/dlg/CDlgOpenFile_CommonFileDialog.cpp +++ b/sakura_core/dlg/CDlgOpenFile_CommonFileDialog.cpp @@ -93,7 +93,7 @@ struct CDlgOpenFile_CommonFileDialog final : public IDlgOpenFile DLLSHAREDATA* m_pShareData; - SFilePath m_szDefaultWildCard; /* 「開く」での最初のワイルドカード(保存時の拡張子補完でも使用される) */ + std::wstring m_strDefaultWildCard{ L"*.*" }; /* 「開く」での最初のワイルドカード(保存時の拡張子補完でも使用される) */ SFilePath m_szInitialDir; /* 「開く」での初期ディレクトリ */ std::vector m_vMRU; @@ -418,7 +418,7 @@ UINT_PTR CALLBACK OFNHookProc( else{ switch( pData->m_pOf->nFilterIndex ){ // 選択されているファイルの種類 case 1: // ユーザー定義 - pszCur = pData->m_pcDlgOpenFile->m_szDefaultWildCard; + pszCur = pData->m_pcDlgOpenFile->m_strDefaultWildCard.data(); while( *pszCur != L'.' && *pszCur != L'\0' ) // '.'まで読み飛ばす pszCur = ::CharNext(pszCur); i = 0; @@ -667,8 +667,6 @@ CDlgOpenFile_CommonFileDialog::CDlgOpenFile_CommonFileDialog() wcscpy( m_szInitialDir, szDrive ); wcscat( m_szInitialDir, szDir ); - wcscpy( m_szDefaultWildCard, L"*.*" ); /*「開く」での最初のワイルドカード(保存時の拡張子補完でも使用される) */ - return; } @@ -687,7 +685,7 @@ void CDlgOpenFile_CommonFileDialog::Create( /* ユーザー定義ワイルドカード(保存時の拡張子補完でも使用される) */ if( NULL != pszUserWildCard ){ - wcscpy( m_szDefaultWildCard, pszUserWildCard ); + m_strDefaultWildCard = pszUserWildCard; } /* 「開く」での初期フォルダ */ @@ -722,7 +720,7 @@ bool CDlgOpenFile_CommonFileDialog::DoModal_GetOpenFileName( WCHAR* pszPath, EFi // 2003.05.12 MIK CFileExt cFileExt; - cFileExt.AppendExtRaw( LS(STR_DLGOPNFL_EXTNAME1), m_szDefaultWildCard ); + cFileExt.AppendExtRaw( LS(STR_DLGOPNFL_EXTNAME1), m_strDefaultWildCard.c_str() ); switch( eAddFilter ){ case EFITER_TEXT: @@ -740,7 +738,7 @@ bool CDlgOpenFile_CommonFileDialog::DoModal_GetOpenFileName( WCHAR* pszPath, EFi break; } - if( 0 != wcscmp(m_szDefaultWildCard, L"*.*") ){ + if (m_strDefaultWildCard != L"*.*") { cFileExt.AppendExtRaw( LS(STR_DLGOPNFL_EXTNAME3), L"*.*" ); } @@ -815,7 +813,7 @@ bool CDlgOpenFile_CommonFileDialog::DoModal_GetSaveFileName( WCHAR* pszPath ) // 2003.05.12 MIK CFileExt cFileExt; - cFileExt.AppendExtRaw( LS(STR_DLGOPNFL_EXTNAME1), m_szDefaultWildCard ); + cFileExt.AppendExtRaw( LS(STR_DLGOPNFL_EXTNAME1), m_strDefaultWildCard.c_str() ); cFileExt.AppendExtRaw( LS(STR_DLGOPNFL_EXTNAME2), L"*.txt" ); cFileExt.AppendExtRaw( LS(STR_DLGOPNFL_EXTNAME3), L"*.*" ); @@ -979,7 +977,7 @@ bool CDlgOpenFile_CommonFileDialog::DoModalSaveDlg( // 2003.05.12 MIK CFileExt cFileExt; - cFileExt.AppendExtRaw( LS(STR_DLGOPNFL_EXTNAME1), m_szDefaultWildCard ); + cFileExt.AppendExtRaw( LS(STR_DLGOPNFL_EXTNAME1), m_strDefaultWildCard.c_str() ); cFileExt.AppendExtRaw( LS(STR_DLGOPNFL_EXTNAME2), L"*.txt" ); cFileExt.AppendExtRaw( LS(STR_DLGOPNFL_EXTNAME3), L"*.*" ); diff --git a/sakura_core/dlg/CDlgOpenFile_CommonItemDialog.cpp b/sakura_core/dlg/CDlgOpenFile_CommonItemDialog.cpp index f6fea7305b..2e809ee199 100644 --- a/sakura_core/dlg/CDlgOpenFile_CommonItemDialog.cpp +++ b/sakura_core/dlg/CDlgOpenFile_CommonItemDialog.cpp @@ -77,7 +77,7 @@ struct CDlgOpenFile_CommonItemDialog final DLLSHAREDATA* m_pShareData; - SFilePath m_szDefaultWildCard; /* 「開く」での最初のワイルドカード(保存時の拡張子補完でも使用される) */ + std::wstring m_strDefaultWildCard{ L"*.*" }; /* 「開く」での最初のワイルドカード(保存時の拡張子補完でも使用される) */ SFilePath m_szInitialDir; /* 「開く」での初期ディレクトリ */ std::vector m_vMRU; @@ -416,7 +416,6 @@ CDlgOpenFile_CommonItemDialog::CDlgOpenFile_CommonItemDialog() wcscpy( m_szInitialDir, szDrive ); wcscat( m_szInitialDir, szDir ); - wcscpy( m_szDefaultWildCard, L"*.*" ); /*「開く」での最初のワイルドカード(保存時の拡張子補完でも使用される) */ return; } @@ -435,7 +434,7 @@ void CDlgOpenFile_CommonItemDialog::Create( /* ユーザー定義ワイルドカード(保存時の拡張子補完でも使用される) */ if( NULL != pszUserWildCard ){ - wcscpy( m_szDefaultWildCard, pszUserWildCard ); + m_strDefaultWildCard = pszUserWildCard; } /* 「開く」での初期フォルダ */ @@ -465,7 +464,7 @@ bool CDlgOpenFile_CommonItemDialog::DoModal_GetOpenFileName( WCHAR* pszPath, EFi strs.reserve(8); strs.push_back(LS(STR_DLGOPNFL_EXTNAME1)); - specs.push_back(COMDLG_FILTERSPEC{strs.back().c_str(), m_szDefaultWildCard}); + specs.push_back(COMDLG_FILTERSPEC{strs.back().c_str(), m_strDefaultWildCard.c_str()}); switch( eAddFilter ){ case EFITER_TEXT: @@ -484,7 +483,7 @@ bool CDlgOpenFile_CommonItemDialog::DoModal_GetOpenFileName( WCHAR* pszPath, EFi break; } - if( 0 != wcscmp(m_szDefaultWildCard, L"*.*") ){ + if (m_strDefaultWildCard != L"*.*") { strs.push_back(LS(STR_DLGOPNFL_EXTNAME3)); specs.push_back(COMDLG_FILTERSPEC{strs.back().c_str(), L"*.*"}); } @@ -700,15 +699,16 @@ bool CDlgOpenFile_CommonItemDialog::DoModalOpenDlg( specs[1].pszName = strs[1].c_str(); specs[1].pszSpec = L"*.txt"; CDocTypeManager docTypeMgr; - WCHAR szWork[_countof(STypeConfigMini::m_szTypeExts) * 3]; + std::wstring worksString; for( int i = 0; i < nTypesCount; i++ ){ const STypeConfigMini* type = NULL; if( !docTypeMgr.GetTypeConfigMini( CTypeConfig(i), &type ) ){ continue; } specs[2 + i].pszName = type->m_szTypeName; - if (CDocTypeManager::ConvertTypesExtToDlgExt(type->m_szTypeExts, NULL, szWork)) { - strs[2 + i] = szWork; + worksString = CDocTypeManager::ConvertTypesExtToDlgExt(type->m_szTypeExts, nullptr); + if (!worksString.empty()) { + strs[2 + i] = worksString; specs[2 + i].pszSpec = strs[2 + i].c_str(); } else { @@ -747,7 +747,7 @@ HRESULT CDlgOpenFile_CommonItemDialog::DoModalSaveDlgImpl1( strs[1] = LS(STR_DLGOPNFL_EXTNAME2); strs[2] = LS(STR_DLGOPNFL_EXTNAME3); specs[0].pszName = strs[0].c_str(); - specs[0].pszSpec = m_szDefaultWildCard; + specs[0].pszSpec = m_strDefaultWildCard.c_str(); specs[1].pszName = strs[1].c_str(); specs[1].pszSpec = L"*.txt"; specs[2].pszName = strs[2].c_str(); diff --git a/sakura_core/doc/CDocFileOperation.cpp b/sakura_core/doc/CDocFileOperation.cpp index 1702593be8..3e69f56798 100644 --- a/sakura_core/doc/CDocFileOperation.cpp +++ b/sakura_core/doc/CDocFileOperation.cpp @@ -225,7 +225,8 @@ bool CDocFileOperation::SaveFileDialog( //拡張子指定 // 一時適用や拡張子なしの場合の拡張子をタイプ別設定から持ってくる // 2008/6/14 大きく改造 Uchi - WCHAR szDefaultWildCard[_MAX_PATH + 10]; // ユーザー指定拡張子 + std::wstring strDefaultWildCard; // ユーザー指定拡張子 + { LPCWSTR szExt; @@ -241,28 +242,27 @@ bool CDocFileOperation::SaveFileDialog( // 基本 if (szExt[0] == L'\0') { // ファイルパスが無いまたは拡張子なし - wcscpy(szDefaultWildCard, L"*.txt"); + strDefaultWildCard = L"*.txt"; } else { // 拡張子あり - wcscpy(szDefaultWildCard, L"*"); - wcscat(szDefaultWildCard, szExt); + strDefaultWildCard = L"*"; + strDefaultWildCard += szExt; } } else { - szDefaultWildCard[0] = L'\0'; - CDocTypeManager::ConvertTypesExtToDlgExt(type.m_szTypeExts, szExt, szDefaultWildCard); + strDefaultWildCard = CDocTypeManager::ConvertTypesExtToDlgExt(type.m_szTypeExts, szExt); } if(!this->m_pcDocRef->m_cDocFile.GetFilePathClass().IsValidPath()){ //「新規から保存時は全ファイル表示」オプション // 2008/6/15 バグフィックス Uchi if( GetDllShareData().m_Common.m_sFile.m_bNoFilterSaveNew ) - wcscat(szDefaultWildCard, L";*.*"); // 全ファイル表示 + strDefaultWildCard += L";*.*"; // 全ファイル表示 } else { //「新規以外から保存時は全ファイル表示」オプション if( GetDllShareData().m_Common.m_sFile.m_bNoFilterSaveFile ) - wcscat(szDefaultWildCard, L";*.*"); // 全ファイル表示 + strDefaultWildCard += L";*.*"; // 全ファイル表示 } } @@ -281,7 +281,7 @@ bool CDocFileOperation::SaveFileDialog( cDlgOpenFile.Create( G_AppInstance(), CEditWnd::getInstance()->GetHwnd(), - szDefaultWildCard, + strDefaultWildCard.c_str(), CSakuraEnvironment::GetDlgInitialDir().c_str(), // 初期フォルダ CMRUFile().GetPathList(), // 最近のファイル CMRUFolder().GetPathList() // 最近のフォルダ diff --git a/sakura_core/env/CDocTypeManager.cpp b/sakura_core/env/CDocTypeManager.cpp index 02e6115f84..e787770ecf 100644 --- a/sakura_core/env/CDocTypeManager.cpp +++ b/sakura_core/env/CDocTypeManager.cpp @@ -215,45 +215,45 @@ void CDocTypeManager::GetFirstExt(const WCHAR* pszTypeExts, WCHAR szFirstExt[], } /*! タイプ別設定の拡張子リストをダイアログ用リストに変換する - @param pszSrcExt [in] 拡張子リスト 例「.c .cpp;.h」 - @param pszDstExt [out] 拡張子リスト 例「*.c;*.cpp;*.h」 - @param szExt [in] リストの先頭にする拡張子 例「.h」 + @param pszSrcExt [in] 拡張子リスト 例「.c cpp;.h」(ドットはオプション) + @param szExt [in] リストの先頭にする拡張子 例「.h」(ドット必須) + @return 拡張子リスト 例「*.h;*.c;*.cpp」 @date 2014.12.06 syat CFileExtから移動 */ -bool CDocTypeManager::ConvertTypesExtToDlgExt( const WCHAR *pszSrcExt, const WCHAR* szExt, WCHAR *pszDstExt ) +std::wstring CDocTypeManager::ConvertTypesExtToDlgExt(const WCHAR *pszSrcExt, const WCHAR* szExt) { - WCHAR *token; - WCHAR *p; - // 2003.08.14 MIK NULLじゃなくてfalse - if( NULL == pszSrcExt ) return false; - if( NULL == pszDstExt ) return false; - - p = _wcsdup( pszSrcExt ); - pszDstExt[0] = L'\0'; + if (pszSrcExt == nullptr) return L""; + std::wstring destExt; if (szExt != NULL && szExt[0] != L'\0') { // ファイルパスがあり、拡張子ありの場合、トップに指定 - wcscpy(pszDstExt, L"*"); - wcscat(pszDstExt, szExt); + destExt.assign(L"*"); + destExt.append(szExt); } - token = _wcstok(p, m_typeExtSeps); + std::wstring strSrcTokens = pszSrcExt; + WCHAR* context = nullptr; + WCHAR* token = wcstok_s(strSrcTokens.data(), m_typeExtSeps, &context); while( token ) { if (szExt == NULL || szExt[0] == L'\0' || wmemicmp(token, szExt + 1) != 0) { - if( pszDstExt[0] != '\0' ) wcscat( pszDstExt, L";" ); + if (0 < destExt.length()) { + destExt.append(L";"); + } // 拡張子指定なし、またはマッチした拡張子でない if (wcspbrk(token, m_typeExtWildcards) == NULL) { - if (L'.' == *token) wcscat(pszDstExt, L"*"); - else wcscat(pszDstExt, L"*."); + if (L'.' == *token) { + destExt.append(L"*"); + } + else { + destExt.append(L"*."); + } } - wcscat(pszDstExt, token); + destExt.append(token); } - - token = _wcstok( NULL, m_typeExtSeps ); + token = wcstok_s(nullptr, m_typeExtSeps, &context); } - free( p ); // 2003.05.20 MIK メモリ解放漏れ - return true; + return destExt; } diff --git a/sakura_core/env/CDocTypeManager.h b/sakura_core/env/CDocTypeManager.h index aa3a5edfc0..49a55e2340 100644 --- a/sakura_core/env/CDocTypeManager.h +++ b/sakura_core/env/CDocTypeManager.h @@ -51,7 +51,7 @@ class CDocTypeManager{ static bool IsFileNameMatch(const WCHAR* pszTypeExts, const WCHAR* pszFileName); // タイプ別拡張子にファイル名がマッチするか static void GetFirstExt(const WCHAR* pszTypeExts, WCHAR szFirstExt[], int nBuffSize); // タイプ別拡張子の先頭拡張子を取得する - static bool ConvertTypesExtToDlgExt( const WCHAR *pszSrcExt, const WCHAR* szExt, WCHAR *pszDstExt ); // タイプ別設定の拡張子リストをダイアログ用リストに変換する + static std::wstring ConvertTypesExtToDlgExt(const WCHAR *pszSrcExt, const WCHAR* szExt); // タイプ別設定の拡張子リストをダイアログ用リストに変換する static const WCHAR* m_typeExtSeps; // タイプ別拡張子の区切り文字 static const WCHAR* m_typeExtWildcards; // タイプ別拡張子のワイルドカード diff --git a/sakura_core/macro/CMacro.cpp b/sakura_core/macro/CMacro.cpp index e6db099ce5..3e822a1f35 100644 --- a/sakura_core/macro/CMacro.cpp +++ b/sakura_core/macro/CMacro.cpp @@ -1884,6 +1884,10 @@ bool CMacro::HandleFunction(CEditView *View, EFunctionCode ID, const VARIANT *Ar sFilter = Source; // フィルタ文字列 delete[] Source; } + // sDefaultの先はSFilePath型 + if (MAX_PATH <= sDefault.length()) { + return false; + } CDlgOpenFile cDlgOpenFile; cDlgOpenFile.Create( @@ -1929,6 +1933,10 @@ bool CMacro::HandleFunction(CEditView *View, EFunctionCode ID, const VARIANT *Ar sDefault = Source; // 既定のファイル名 delete[] Source; } + // sDefaultは[MAX_PATH] + if (MAX_PATH <= sDefault.length()) { + return false; + } WCHAR szPath[ _MAX_PATH ]; int nRet = SelectDir( View->GetHwnd(), sMessage.c_str(), sDefault.c_str(), szPath ); diff --git a/tests/unittests/test-cdlgopenfile.cpp b/tests/unittests/test-cdlgopenfile.cpp new file mode 100644 index 0000000000..90bc235cb9 --- /dev/null +++ b/tests/unittests/test-cdlgopenfile.cpp @@ -0,0 +1,126 @@ +/*! @file */ +/* + Copyright (C) 2018-2021, Sakura Editor Organization + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; + you must not claim that you wrote the original software. + If you use this software in a product, an acknowledgment + in the product documentation would be appreciated but is + not required. + + 2. Altered source versions must be plainly marked as such, + and must not be misrepresented as being the original software. + + 3. This notice may not be removed or altered from any source + distribution. +*/ +#include +#ifndef STRICT +#define STRICT 1 +#endif +#ifndef NOMINMAX +#define NOMINMAX +#endif /* #ifndef NOMINMAX */ +#include +#include +#include +#include "util/design_template.h" +#include "dlg/CDlgOpenFile.h" + +extern std::shared_ptr New_CDlgOpenFile_CommonFileDialog(); +extern std::shared_ptr New_CDlgOpenFile_CommonItemDialog(); + +TEST(CDlgOpenFile, Construct) +{ + CDlgOpenFile cDlgOpenFile; +} + +TEST(CDlgOpenFile, DISABLED_CommonItemDialogCreate) +{ + std::shared_ptrimpl = New_CDlgOpenFile_CommonItemDialog(); + impl->Create( + GetModuleHandle(nullptr), + nullptr, + L"*.txt", + L"C:\\Windows", + std::vector(), + std::vector() + ); +} + +TEST(CDlgOpenFile, DISABLED_CommonFileDialogCreate) +{ + std::shared_ptrimpl = New_CDlgOpenFile_CommonFileDialog(); + impl->Create( + GetModuleHandle(nullptr), + nullptr, + L"*.txt", + L"C:\\Windows", + std::vector(), + std::vector() + ); +} + +TEST(CDlgOpenFile, DISABLED_CommonItemDialogDefaltFilterLong) +{ + std::shared_ptrimpl = New_CDlgOpenFile_CommonItemDialog(); + // 落ちたり例外にならないこと + impl->Create( + GetModuleHandle(nullptr), + nullptr, + L".extension_250_long_long_long_long_long_long_long_long_long_long_long_long_long_long_long_long_long_long_long_long_long_long_long_long_long_long_long_long_long_long_long_long_long_long_long_long_long_long_long_long_long_long_long_long_long_long_LONG", + L"C:\\Windows", + std::vector(), + std::vector() + ); +} + +TEST(CDlgOpenFile, DISABLED_CommonFileDialogDefaltFilterLong) +{ + std::shared_ptrimpl = New_CDlgOpenFile_CommonFileDialog(); + // 落ちたり例外にならないこと + impl->Create( + GetModuleHandle(nullptr), + nullptr, + L"*.extension_250_long_long_long_long_long_long_long_long_long_long_long_long_long_long_long_long_long_long_long_long_long_long_long_long_long_long_long_long_long_long_long_long_long_long_long_long_long_long_long_long_long_long_long_long_long_long_LONG", + L"C:\\Windows", + std::vector(), + std::vector() + ); +} + +TEST(CDlgOpenFile, DISABLED_CommonFileDialogDefaltFilterMany) +{ + std::shared_ptrimpl = New_CDlgOpenFile_CommonFileDialog(); + // 落ちたり例外にならないこと + impl->Create( + GetModuleHandle(nullptr), + nullptr, + L"*.extension_50_0_long_long_long_long_long_long_LONG;*.extension_50_1_long_long_long_long_long_long_LONG;*.extension_50_2_long_long_long_long_long_long_LONG;*.extension_50_3_long_long_long_long_long_long_LONG;*.extension_50_4_long_long_long_long_long_long_LONG;*.extension_50_5_long_long_long_long_long_long_LONG;*.extension_50_6_long_long_long_long_long_long_LONG;*.extension_50_7_long_long_long_long_long_long_LONG;*.extension_50_8_long_long_long_long_long_long_LONG;*.extension_50_9_long_long_long_long_long_long_LONG", + L"C:\\Windows", + std::vector(), + std::vector() + ); +} + +TEST(CDlgOpenFile, DISABLED_CommonItemDialogDefaltFilterMany) +{ + std::shared_ptrimpl = New_CDlgOpenFile_CommonItemDialog(); + // 落ちたり例外にならないこと + impl->Create( + GetModuleHandle(nullptr), + nullptr, + L"*.extension_50_0_long_long_long_long_long_long_LONG;*.extension_50_1_long_long_long_long_long_long_LONG;*.extension_50_2_long_long_long_long_long_long_LONG;*.extension_50_3_long_long_long_long_long_long_LONG;*.extension_50_4_long_long_long_long_long_long_LONG;*.extension_50_5_long_long_long_long_long_long_LONG;*.extension_50_6_long_long_long_long_long_long_LONG;*.extension_50_7_long_long_long_long_long_long_LONG;*.extension_50_8_long_long_long_long_long_long_LONG;*.extension_50_9_long_long_long_long_long_long_LONG", + L"C:\\Windows", + std::vector(), + std::vector() + ); +} diff --git a/tests/unittests/test-cdoctypemanager.cpp b/tests/unittests/test-cdoctypemanager.cpp new file mode 100644 index 0000000000..ff946e5028 --- /dev/null +++ b/tests/unittests/test-cdoctypemanager.cpp @@ -0,0 +1,120 @@ +/* + Copyright (C) 2021, Sakura Editor Organization + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; + you must not claim that you wrote the original software. + If you use this software in a product, an acknowledgment + in the product documentation would be appreciated but is + not required. + + 2. Altered source versions must be plainly marked as such, + and must not be misrepresented as being the original software. + + 3. This notice may not be removed or altered from any source + distribution. +*/ + +#include +#include +#include +#include "mem/CNativeW.h" +#include "env/CDocTypeManager.h" + +TEST(CDocTypeManager, ConvertTypesExtToDlgExtNullptr1) +{ + const std::wstring expected = { L"" }; + std::wstring actual = CDocTypeManager::ConvertTypesExtToDlgExt(nullptr, nullptr); + EXPECT_EQ(expected, actual); +} + +TEST(CDocTypeManager, ConvertTypesExtToDlgExtNullptr2) +{ + const std::wstring expected = { L"" }; + std::wstring actual = CDocTypeManager::ConvertTypesExtToDlgExt(nullptr, L".txt"); + EXPECT_EQ(expected, actual); +} + +TEST(CDocTypeManager, ConvertTypesExtToDlgExtOnce) +{ + const std::wstring expected = { L"*.txt;*.cpp" }; + std::wstring actual = CDocTypeManager::ConvertTypesExtToDlgExt(L"cpp", L".txt"); + EXPECT_EQ(expected, actual); +} + +TEST(CDocTypeManager, ConvertTypesExtToDlgExtTwo) +{ + const std::wstring expected = { L"*.txt;*.cpp;*.h" }; + std::wstring actual = CDocTypeManager::ConvertTypesExtToDlgExt(L"cpp;h", L".txt"); + EXPECT_EQ(expected, actual); +} + +TEST(CDocTypeManager, ConvertTypesExtToDlgExtThree) +{ + const std::wstring expected = { L"*.txt;*.cpp;*.h;*.hpp" }; + std::wstring actual = CDocTypeManager::ConvertTypesExtToDlgExt(L"cpp;h;hpp", L".txt"); + EXPECT_EQ(expected, actual); +} + +TEST(CDocTypeManager, ConvertTypesExtToDlgExtAppendPeriod) +{ + const std::wstring expected = { L"*.txt;*.cpp;*.h" }; + std::wstring actual = CDocTypeManager::ConvertTypesExtToDlgExt(L".cpp;.h", L".txt"); + EXPECT_EQ(expected, actual); +} + +TEST(CDocTypeManager, ConvertTypesExtToDlgExtSeparatorSpace) +{ + const std::wstring expected = { L"*.txt;*.cpp;*.h" }; + std::wstring actual = CDocTypeManager::ConvertTypesExtToDlgExt(L"cpp h", L".txt"); + EXPECT_EQ(expected, actual); +} + +TEST(CDocTypeManager, ConvertTypesExtToDlgExtSeparatorComma) +{ + const std::wstring expected = { L"*.txt;*.cpp;*.h" } ; + std::wstring actual = CDocTypeManager::ConvertTypesExtToDlgExt(L"cpp,h", L".txt"); + EXPECT_EQ(expected, actual); +} + +TEST(CDocTypeManager, ConvertTypesExtToDlgExtTopNullptr) +{ + const std::wstring expected = { L"*.cpp;*.h" }; + std::wstring actual = CDocTypeManager::ConvertTypesExtToDlgExt(L"cpp,h", nullptr); + EXPECT_EQ(expected, actual); +} + +TEST(CDocTypeManager, ConvertTypesExtToDlgExtMerge) +{ + const std::wstring expected = { L"*.txt;*.cpp;*.h" }; + std::wstring actual = CDocTypeManager::ConvertTypesExtToDlgExt(L"txt,cpp,h", L".txt"); + EXPECT_EQ(expected, actual); +} + +TEST(CDocTypeManager, ConvertTypesExtToDlgExtMerge2) +{ + const std::wstring expected = { L"*.txt;*.cpp;*.h" }; + std::wstring actual = CDocTypeManager::ConvertTypesExtToDlgExt(L"cpp,h,txt", L".txt"); + EXPECT_EQ(expected, actual); +} + +TEST(CDocTypeManager, ConvertTypesExtToDlgExtExts64) +{ + const std::wstring expected = { L"*.txt;*.a;*.b;*.c;*.d;*.e;*.f;*.g;*.h;*.i;*.j;*.k;*.l;*.m;*.n;*.o;*.p;*.q;*.r;*.s;*.t;*.u;*.v;*.w;*.x;*.y;*.z;*.1;*.2;*.3;*.4;*.5;*.6" }; + std::wstring actual = CDocTypeManager::ConvertTypesExtToDlgExt(L"a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z,1,2,3,4,5,6", L".txt"); + EXPECT_EQ(expected, actual); +} + +TEST(CDocTypeManager, ConvertTypesExtToDlgExtExts64LongFileExt) +{ + const std::wstring expected = { L"*.extension_260_long_long_long_long_long_long_long_long_long_long_long_long_long_long_long_long_long_long_long_long_long_long_long_long_long_long_long_long_long_long_long_long_long_long_long_long_long_long_long_long_long_long_long_long_long_long_long_long_long;*.a;*.b;*.c;*.d;*.e;*.f;*.g;*.h;*.i;*.j;*.k;*.l;*.m;*.n;*.o;*.p;*.q;*.r;*.s;*.t;*.u;*.v;*.w;*.x;*.y;*.z;*.1;*.2;*.3;*.4;*.5;*.6" }; + std::wstring actual = CDocTypeManager::ConvertTypesExtToDlgExt(L"a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z,1,2,3,4,5,6", L".extension_260_long_long_long_long_long_long_long_long_long_long_long_long_long_long_long_long_long_long_long_long_long_long_long_long_long_long_long_long_long_long_long_long_long_long_long_long_long_long_long_long_long_long_long_long_long_long_long_long_long"); + EXPECT_EQ(expected, actual); +} diff --git a/tests/unittests/test-cfileext.cpp b/tests/unittests/test-cfileext.cpp new file mode 100644 index 0000000000..cf65b9fd27 --- /dev/null +++ b/tests/unittests/test-cfileext.cpp @@ -0,0 +1,91 @@ +/*! @file */ +/* + Copyright (C) 2018-2021, Sakura Editor Organization + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; + you must not claim that you wrote the original software. + If you use this software in a product, an acknowledgment + in the product documentation would be appreciated but is + not required. + + 2. Altered source versions must be plainly marked as such, + and must not be misrepresented as being the original software. + + 3. This notice may not be removed or altered from any source + distribution. +*/ +#include + +#ifndef NOMINMAX +#define NOMINMAX +#endif /* #ifndef NOMINMAX */ + +#include +#include "CFileExt.h" + + +static size_t GetFilterLength(const wchar_t* filter) +{ + size_t length = 0; + size_t i = 0; + while (!(filter[i] == L'\0' && filter[i+1] == L'\0')) { + ++i; + } + return i + 2; +} + +TEST(CFileExt, Construct) +{ + CFileExt cFileExt; +} + +TEST(CFileExt, CreateFilter) +{ + wchar_t result[] = L"ユーザー設定 (*.cpp;*.h;*.*)\0*.cpp;*.h;*.*\0テキスト (*.txt)\0*.txt\0すべてのファイル (*.*)\0*.*\0"; + + CFileExt cFileExt; + cFileExt.AppendExtRaw(L"ユーザー設定", L"*.cpp;*.h;*.*"); + cFileExt.AppendExtRaw(L"テキスト", L"*.txt"); + cFileExt.AppendExtRaw(L"すべてのファイル", L"*.*"); + + const wchar_t* filter = cFileExt.GetExtFilter(); + size_t length = GetFilterLength(filter); + std::wstring expected = {result, _countof(result)}; + std::wstring actual = {filter, length}; + EXPECT_EQ(expected, actual); +} + +TEST(CFileExt, RawLongFilter) +{ + CFileExt cFileExt; + cFileExt.AppendExtRaw( + L"ユーザ設定", + L"*.extensin_250_long_long_long_long_long_long_long_long_long_long_long_long_long_long_long_long_long_long_long_long_long_long_long_long_long_long_long_long_long_long_long_long_long_long_long_long_long_long_long_long_long_long_long_long_long_long_longX" + ); +} + +TEST(CFileExt, RawManyFilter) +{ + CFileExt cFileExt; + cFileExt.AppendExtRaw( + L"ユーザ指定", + L"*.extensin_50_0_long_long_long_long_long_long_long_l;*.extensin_50_1_long_long_long_long_long_long_long_l;*.extensin_50_2_long_long_long_long_long_long_long_l;*.extensin_50_3_long_long_long_long_long_long_long_l;*.extensin_50_4_long_long_long_long_long_long_long_l;*.extensin_50_5_long_long_long_long_long_long_long_l;*.extensin_50_6_long_long_long_long_long_long_long_l;*.extensin_50_7_long_long_long_long_long_long_long_l;*.extensin_50_8_long_long_long_long_long_long_long_l;*.extensin_50_9_long_long_long_long_long_long_long_l" + ); +} + +TEST(CFileExt, LongFilter) +{ + CFileExt cFileExt; + cFileExt.AppendExt( + L"ユーザ設定", + L"*.extensin_250_long_long_long_long_long_long_long_long_long_long_long_long_long_long_long_long_long_long_long_long_long_long_long_long_long_long_long_long_long_long_long_long_long_long_long_long_long_long_long_long_long_long_long_long_long_long_longX" + ); +} diff --git a/tests/unittests/tests1.vcxproj b/tests/unittests/tests1.vcxproj index 00fec312f2..3c3fc818d9 100644 --- a/tests/unittests/tests1.vcxproj +++ b/tests/unittests/tests1.vcxproj @@ -111,8 +111,11 @@ + + + diff --git a/tests/unittests/tests1.vcxproj.filters b/tests/unittests/tests1.vcxproj.filters index 4126fb8cea..931d2a1aa2 100644 --- a/tests/unittests/tests1.vcxproj.filters +++ b/tests/unittests/tests1.vcxproj.filters @@ -122,6 +122,15 @@ Test Files + + Test Files + + + Test Files + + + Test Files +