Skip to content

Commit

Permalink
strprintf/vstrprintfを追加
Browse files Browse the repository at this point in the history
  • Loading branch information
sanomari committed Oct 26, 2020
1 parent 336cc8e commit 9934db7
Show file tree
Hide file tree
Showing 6 changed files with 394 additions and 304 deletions.
9 changes: 3 additions & 6 deletions sakura_core/debug/Debug1.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@
#include <stdio.h>
#include <stdarg.h>

#include "util/string_ex.h"

#if defined(_DEBUG) || defined(USE_RELPRINT)

// -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- //
Expand Down Expand Up @@ -54,13 +56,8 @@ void DebugOutW( LPCWSTR lpFmt, ...)

::DebugBreak();

const int count = _vscwprintf( lpFmt, argList );

std::wstring strTooLongMessage;
strTooLongMessage.reserve( count );

::_vsnwprintf_s( strTooLongMessage.data(), count + 1, _TRUNCATE, lpFmt, argList );
strTooLongMessage.assign( strTooLongMessage.data(), count );
vstrprintf( strTooLongMessage, lpFmt, argList );

::OutputDebugStringW( strTooLongMessage.c_str() );
}
Expand Down
47 changes: 47 additions & 0 deletions sakura_core/util/string_ex.h
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,8 @@
#define SAKURA_STRING_EX_87282FEB_4B23_4112_9C5A_419F43618705_H_
#pragma once

#include <string>

// 2007.10.19 kobake
// string.h で定義されている関数を拡張したようなモノ達

Expand Down Expand Up @@ -200,6 +202,51 @@ inline int auto_vsprintf(WCHAR* buf, const WCHAR* format, va_list& v){ return tc
inline int auto_vsprintf_s(ACHAR* buf, size_t nBufCount, const ACHAR* format, va_list& v){ return tchar_vsprintf_s(buf, nBufCount, format, v); }
inline int auto_vsprintf_s(WCHAR* buf, size_t nBufCount, const WCHAR* format, va_list& v){ return tchar_vsprintf_s(buf, nBufCount, format, v); }

template<typename ChType>
inline int vstrprintf( std::basic_string<ChType>& strOut, const ChType* pszFormat, va_list& argList )
{
static_assert( 0, "not implemented" );
return -1;
}

template<typename ChType>
inline int strprintf( std::basic_string<ChType>& strOut, const ChType* pszFormat, ... )
{
static_assert( 0, "not implemented" );
return -1;
}

template<>
inline int vstrprintf<WCHAR>( std::wstring& strOut, const WCHAR* pszFormat, va_list& argList )
{
strOut.clear();

const int cchOut = _vscwprintf( pszFormat, argList );
if( cchOut > 0 ){

strOut.reserve( cchOut );

::vswprintf_s( strOut.data(), strOut.capacity(), pszFormat, argList );

strOut.assign( strOut.data(), cchOut );
}

return cchOut;
}

template<>
inline int strprintf<WCHAR>( std::wstring& strOut, const WCHAR* pszFormat, ... )
{
va_list argList;
va_start( argList, pszFormat );

const int nRet = vstrprintf( strOut, pszFormat, argList );

va_end( argList );

return nRet;
}

// -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- //
// 文字コード変換 //
// -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- //
Expand Down
99 changes: 31 additions & 68 deletions tests/unittests/test-int2dec.cpp
Original file line number Diff line number Diff line change
@@ -1,79 +1,42 @@
#include <gtest/gtest.h>
/*! @file */
/*
Copyright (C) 2018-2020 Sakura Editor Organization
#include <limits>
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.
#ifndef NOMINMAX
#define NOMINMAX
#endif /* #ifndef NOMINMAX */

#include <Windows.h>
#include <tchar.h>
#include "basis/primitive.h"
#include "util/string_ex2.h"
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:
template <typename T>
void test_int2dec(T value, ptrdiff_t lenExpected, const wchar_t* strExpected)
{
wchar_t buff[int2dec_destBufferSufficientLength<T>()];
ptrdiff_t len = int2dec(value, buff);
EXPECT_EQ(len, lenExpected);
EXPECT_STREQ(buff, strExpected);
}
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.
template <typename T>
void test_plusminus(T plusValue, ptrdiff_t lenExpected, const wchar_t* strExpected)
{
test_int2dec(plusValue, lenExpected, strExpected);
test_int2dec(-plusValue, 1+lenExpected, (std::wstring(L"-")+strExpected).c_str());
}

static
void test_32_64_plus_minus(int value, ptrdiff_t lenExpected, const wchar_t* strExpected)
{
test_plusminus<int32_t>(value, lenExpected, strExpected);
test_plusminus<int64_t>(value, lenExpected, strExpected);
}
2. Altered source versions must be plainly marked as such,
and must not be misrepresented as being the original software.
TEST(int2dec_test, zero)
{
test_int2dec<int32_t>(0, 1, L"0");
test_int2dec<int64_t>(0, 1, L"0");
}
3. This notice may not be removed or altered from any source
distribution.
*/
#include <gtest/gtest.h>

TEST(int2dec_test, digits)
{
test_32_64_plus_minus(2, 1, L"2");
test_32_64_plus_minus(3, 1, L"3");
test_32_64_plus_minus(4, 1, L"4");
test_32_64_plus_minus(5, 1, L"5");
test_32_64_plus_minus(6, 1, L"6");
test_32_64_plus_minus(7, 1, L"7");
test_32_64_plus_minus(8, 1, L"8");
test_32_64_plus_minus(9, 1, L"9");
}
#ifndef NOMINMAX
#define NOMINMAX
#endif /* #ifndef NOMINMAX */

TEST(int2dec_test, max)
{
test_int2dec<int32_t>(std::numeric_limits<int32_t>::max(), 10, L"2147483647");
test_int2dec<int64_t>(std::numeric_limits<int64_t>::max(), 19, L"9223372036854775807");
}
#include <tchar.h>
#include <Windows.h>

TEST(int2dec_test, min)
{
test_int2dec<int32_t>(std::numeric_limits<int32_t>::min(), 11, L"-2147483648");
test_int2dec<int64_t>(std::numeric_limits<int64_t>::min(), 20, L"-9223372036854775808");
}
#include "basis/primitive.h"
#include "util/string_ex.h"

TEST(int2dec_test, group_sequence)
TEST(string_ex, strprintf)
{
test_32_64_plus_minus(1, 1, L"1");
test_32_64_plus_minus(12, 2, L"12");
test_32_64_plus_minus(123, 3, L"123");
test_32_64_plus_minus(1234, 4, L"1234");
test_32_64_plus_minus(12345, 5, L"12345");
test_32_64_plus_minus(123456, 6, L"123456");
test_32_64_plus_minus(1234567, 7, L"1234567");
test_32_64_plus_minus(12345678, 8, L"12345678");
test_32_64_plus_minus(123456789, 9, L"123456789");
test_32_64_plus_minus(1234567890, 10, L"1234567890");
std::wstring text;
strprintf( text, L"%s-%d", L"test", 1 );
ASSERT_STREQ(L"test-1", text.c_str());
}
79 changes: 79 additions & 0 deletions tests/unittests/test-string_ex.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
#include <gtest/gtest.h>

#include <limits>

#ifndef NOMINMAX
#define NOMINMAX
#endif /* #ifndef NOMINMAX */

#include <Windows.h>
#include <tchar.h>
#include "basis/primitive.h"
#include "util/string_ex2.h"

template <typename T>
void test_int2dec(T value, ptrdiff_t lenExpected, const wchar_t* strExpected)
{
wchar_t buff[int2dec_destBufferSufficientLength<T>()];
ptrdiff_t len = int2dec(value, buff);
EXPECT_EQ(len, lenExpected);
EXPECT_STREQ(buff, strExpected);
}

template <typename T>
void test_plusminus(T plusValue, ptrdiff_t lenExpected, const wchar_t* strExpected)
{
test_int2dec(plusValue, lenExpected, strExpected);
test_int2dec(-plusValue, 1+lenExpected, (std::wstring(L"-")+strExpected).c_str());
}

static
void test_32_64_plus_minus(int value, ptrdiff_t lenExpected, const wchar_t* strExpected)
{
test_plusminus<int32_t>(value, lenExpected, strExpected);
test_plusminus<int64_t>(value, lenExpected, strExpected);
}

TEST(int2dec_test, zero)
{
test_int2dec<int32_t>(0, 1, L"0");
test_int2dec<int64_t>(0, 1, L"0");
}

TEST(int2dec_test, digits)
{
test_32_64_plus_minus(2, 1, L"2");
test_32_64_plus_minus(3, 1, L"3");
test_32_64_plus_minus(4, 1, L"4");
test_32_64_plus_minus(5, 1, L"5");
test_32_64_plus_minus(6, 1, L"6");
test_32_64_plus_minus(7, 1, L"7");
test_32_64_plus_minus(8, 1, L"8");
test_32_64_plus_minus(9, 1, L"9");
}

TEST(int2dec_test, max)
{
test_int2dec<int32_t>(std::numeric_limits<int32_t>::max(), 10, L"2147483647");
test_int2dec<int64_t>(std::numeric_limits<int64_t>::max(), 19, L"9223372036854775807");
}

TEST(int2dec_test, min)
{
test_int2dec<int32_t>(std::numeric_limits<int32_t>::min(), 11, L"-2147483648");
test_int2dec<int64_t>(std::numeric_limits<int64_t>::min(), 20, L"-9223372036854775808");
}

TEST(int2dec_test, group_sequence)
{
test_32_64_plus_minus(1, 1, L"1");
test_32_64_plus_minus(12, 2, L"12");
test_32_64_plus_minus(123, 3, L"123");
test_32_64_plus_minus(1234, 4, L"1234");
test_32_64_plus_minus(12345, 5, L"12345");
test_32_64_plus_minus(123456, 6, L"123456");
test_32_64_plus_minus(1234567, 7, L"1234567");
test_32_64_plus_minus(12345678, 8, L"12345678");
test_32_64_plus_minus(123456789, 9, L"123456789");
test_32_64_plus_minus(1234567890, 10, L"1234567890");
}
Loading

0 comments on commit 9934db7

Please sign in to comment.