From 04ae8aa718e9875ac67f7679f46324f6c77adca2 Mon Sep 17 00:00:00 2001 From: berryzplus Date: Sun, 27 Feb 2022 16:36:53 +0900 Subject: [PATCH] =?UTF-8?q?=E4=BE=8B=E5=A4=96=E3=82=92=E6=8A=95=E3=81=92?= =?UTF-8?q?=E3=82=8B=E6=A7=8B=E9=80=A0=E3=82=92=E3=82=84=E3=82=81=E3=82=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- sakura_core/util/string_ex.cpp | 64 ++++++++++-------------------- tests/unittests/test-string_ex.cpp | 19 --------- 2 files changed, 22 insertions(+), 61 deletions(-) diff --git a/sakura_core/util/string_ex.cpp b/sakura_core/util/string_ex.cpp index 5b840943cb..0ff4a1a628 100644 --- a/sakura_core/util/string_ex.cpp +++ b/sakura_core/util/string_ex.cpp @@ -39,21 +39,6 @@ int __cdecl my_internal_icmp( const char *s1, const char *s2, unsigned int n, unsigned int dcount, bool flag ); -/*! - * va_list型のスマートポインタを実現するためのdeleterクラス - */ -struct vaList_ender -{ - void operator()(va_list argList) const - { - va_end(argList); - } -}; - -//! va_list型のスマートポインタ -using vaListHolder = std::unique_ptr::type, vaList_ender>; - - // -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- // // 文字 // // -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- // @@ -266,12 +251,13 @@ const char* stristr_j( const char* s1, const char* s2 ) @returns 出力された文字数。NUL終端を含まない。 @retval >= 0 正常終了 @retval < 0 異常終了 -*/ + */ int vstrprintf(std::wstring& strOut, const WCHAR* pszFormat, va_list& argList) { // _vscwprintf() はフォーマットに必要な文字数を返す。 const int cchOut = ::_vscwprintf(pszFormat, argList); if (cchOut <= 0) { + strOut.clear(); return cchOut; } @@ -307,12 +293,13 @@ int vstrprintf(std::wstring& strOut, const WCHAR* pszFormat, va_list& argList) @returns 出力された文字数。NUL終端を含まない。 @retval >= 0 正常終了 @retval < 0 異常終了 -*/ + */ int vstrprintf(std::string& strOut, const CHAR* pszFormat, va_list& argList) { // _vscwprintf() はフォーマットに必要な文字数を返す。 const int cchOut = ::_vscprintf(pszFormat, argList); if (cchOut <= 0) { + strOut.clear(); return cchOut; } @@ -336,7 +323,6 @@ int vstrprintf(std::string& strOut, const CHAR* pszFormat, va_list& argList) strOut.assign(strOut.data(), cchOut); } - return cchOut; } @@ -349,7 +335,7 @@ int vstrprintf(std::string& strOut, const CHAR* pszFormat, va_list& argList) @returns 出力された文字数。NUL終端を含まない。 @retval >= 0 正常終了 @retval < 0 異常終了 -*/ + */ int strprintf(std::wstring& strOut, const WCHAR* pszFormat, ...) { va_list argList; @@ -371,7 +357,7 @@ int strprintf(std::wstring& strOut, const WCHAR* pszFormat, ...) @returns 出力された文字数。NUL終端を含まない。 @retval >= 0 正常終了 @retval < 0 異常終了 -*/ + */ int strprintf(std::string& strOut, const CHAR* pszFormat, ...) { va_list argList; @@ -390,15 +376,14 @@ int strprintf(std::string& strOut, const CHAR* pszFormat, ...) @param[in] pszFormat フォーマット文字列 @param[in] ... 引数リスト @returns フォーマットされた文字列 - @throws invalid_argument フォーマット文字列が正しくないとき -*/ + */ std::wstring vstrprintf(const WCHAR* pszFormat, va_list& argList) { // 出力バッファを確保する std::wstring strOut; - // 戻り値が0未満ならエラーだが、再現させられないのでハンドルしない - vstrprintf(strOut, pszFormat, argList); + const auto nRet = vstrprintf(strOut, pszFormat, argList); + assert(nRet >= 0); return strOut; } @@ -409,21 +394,14 @@ std::wstring vstrprintf(const WCHAR* pszFormat, va_list& argList) @param[in] pszFormat フォーマット文字列 @param[in] ... 引数リスト @returns フォーマットされた文字列 - @throws invalid_argument フォーマット文字列が正しくないとき -*/ + */ std::string vstrprintf(const CHAR* pszFormat, va_list& argList) { // 出力バッファを確保する std::string strOut; - // 戻り値が0未満ならエラー - if (const int nRet = vstrprintf(strOut, pszFormat, argList); - 0 > nRet) - { - std::array msg; - ::strerror_s(msg.data(), msg.size(), nRet); - throw std::invalid_argument(msg.data()); - } + const int nRet = vstrprintf(strOut, pszFormat, argList); + assert(nRet >= 0); return strOut; } @@ -434,16 +412,17 @@ std::string vstrprintf(const CHAR* pszFormat, va_list& argList) @param[in] pszFormat フォーマット文字列 @param[in] ... 引数リスト @returns フォーマットされた文字列 - @throws invalid_argument フォーマット文字列が正しくないとき -*/ + */ std::wstring strprintf(const WCHAR* pszFormat, ...) { va_list argList; va_start(argList, pszFormat); - vaListHolder holder(argList); + const auto strOut = vstrprintf(pszFormat, argList); - return vstrprintf(pszFormat, argList); + va_end(argList); + + return strOut; } /*! @@ -452,16 +431,17 @@ std::wstring strprintf(const WCHAR* pszFormat, ...) @param[in] pszFormat フォーマット文字列 @param[in] ... 引数リスト @returns フォーマットされた文字列 - @throws invalid_argument フォーマット文字列が正しくないとき -*/ + */ std::string strprintf(const CHAR* pszFormat, ...) { va_list argList; va_start(argList, pszFormat); - vaListHolder holder(argList); + const auto strOut = vstrprintf(pszFormat, argList); + + va_end(argList); - return vstrprintf(pszFormat, argList); + return strOut; } // -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- // diff --git a/tests/unittests/test-string_ex.cpp b/tests/unittests/test-string_ex.cpp index 771070bf8e..8cc6c9b5b8 100644 --- a/tests/unittests/test-string_ex.cpp +++ b/tests/unittests/test-string_ex.cpp @@ -240,25 +240,6 @@ TEST(string_ex, strprintfA_small_output) EXPECT_STREQ("1234567890123456", text.c_str()); } -/*! - @brief 独自定義のフォーマット関数(C-Style風)。 - - Cロケールを設定し忘れた場合、SJISバイナリから標準文字列への変換は失敗する。 - テスト作成時に混乱する可能性があるので、例外を投げるようにしてある。 - CRT関数が「フォーマットが不正ならクラッシュさせる」という設計なので、 - フォーマットチェック機構としては役立たずである点に注意すること。 - */ -TEST(string_ex, strprintfA_throws) -{ - // Cのロケールを設定し忘れた場合、エラーが返る - setlocale(LC_ALL, "English"); - EXPECT_THROW(strprintf("%ls", L"てすと"), std::invalid_argument); - - // Cのロケールを日本語にした場合、正しく変換できる - setlocale(LC_ALL, "Japanese"); - EXPECT_STREQ("てすと", strprintf("%ls", L"てすと").data()); -} - /*! @brief 独自定義の文字列比較関数。 */