Skip to content

Commit

Permalink
Use std::string_view for MISC::replace_str() (#949)
Browse files Browse the repository at this point in the history
変更不可の文字列のポインターと長さを渡している関数の引数を
`std::string_view`に交換して整理します。

- テストを追加して動作をチェックします
- 無限ループしないように引数のチェックを追加します
  • Loading branch information
ma8ma committed Apr 2, 2022
1 parent 4ae1bdd commit 8455510
Show file tree
Hide file tree
Showing 4 changed files with 49 additions and 13 deletions.
22 changes: 14 additions & 8 deletions src/jdlib/miscutil.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -444,23 +444,29 @@ std::string MISC::cut_str( const std::string& str, const std::string& str1, cons
}


//
// str1 を str2 に置き換え
//
std::string MISC::replace_str( const std::string& str, const std::string& str1, const std::string& str2 )
/** @brief pattern を replacement に置き換える
*
* @param[in] str 置き換えを実行する文字列
* @param[in] pattern 置き換える文字列のパターン
* @param[in] replacement マッチした文字列を置き換える内容
* @return 置き換えを実行した結果。str や pattern が空文字列のときは str をそのまま返す。
*/
std::string MISC::replace_str( std::string_view str, std::string_view pattern, std::string_view replacement )
{
if( str.empty() || pattern.empty() ) return std::string( str );

size_t i, pos = 0;
if( ( i = str.find( str1 , pos ) ) == std::string::npos ) return str;
if( ( i = str.find( pattern ) ) == std::string_view::npos ) return std::string( str );

std::string str_out;
str_out.reserve( str.length() );

do {
str_out.append( str, pos, ( i - pos ) );
str_out.append( str2 );
pos = i + str1.length();
str_out.append( replacement );
pos = i + pattern.length();
}
while( ( i = str.find( str1 , pos ) ) != std::string::npos );
while( ( i = str.find( pattern, pos ) ) != std::string_view::npos );

str_out.append( str, pos, str.length() );
return str_out;
Expand Down
4 changes: 2 additions & 2 deletions src/jdlib/miscutil.h
Original file line number Diff line number Diff line change
Expand Up @@ -109,8 +109,8 @@ namespace MISC
// str1, str2 に囲まれた文字列を切り出す
std::string cut_str( const std::string& str, const std::string& str1, const std::string& str2 );

// str1str2 に置き換え
std::string replace_str( const std::string& str, const std::string& str1, const std::string& str2 );
/// patternreplacement に置き換える
std::string replace_str( std::string_view str, std::string_view pattern, std::string_view replacement );

// list_inから str1 を str2 に置き換えてリストを返す
std::list< std::string > replace_str_list( const std::list< std::string >& list_in,
Expand Down
5 changes: 2 additions & 3 deletions src/skeleton/editview.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -525,10 +525,9 @@ void EditTextView::slot_quote_clipboard()
if( m_context_menu ) m_context_menu->hide();

Glib::RefPtr< Gtk::Clipboard > clip = Gtk::Clipboard::get();
Glib::ustring text = clip->wait_for_text();
std::string text = clip->wait_for_text();

std::string str_res;
str_res = CONFIG::get_ref_prefix();
std::string str_res = CONFIG::get_ref_prefix();

text = MISC::replace_str( text, "\n", "\n" + str_res );
insert_str( str_res + text, false );
Expand Down
31 changes: 31 additions & 0 deletions test/gtest_jdlib_miscutil.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -150,6 +150,37 @@ TEST_F(RemoveStrStartEndTest, much_end_marks)
}


class ReplaceStrTest : public ::testing::Test {};

TEST_F(ReplaceStrTest, empty_data)
{
EXPECT_EQ( "", MISC::replace_str( "", "", "" ) );
EXPECT_EQ( "", MISC::replace_str( "", "AA", "" ) );
EXPECT_EQ( "", MISC::replace_str( "", "AA", "BB" ) );
EXPECT_EQ( "", MISC::replace_str( "", "", "BB" ) );
}

TEST_F(ReplaceStrTest, empty_match)
{
EXPECT_EQ( "Quick Brown Fox", MISC::replace_str( "Quick Brown Fox", "", "Red" ) );
}

TEST_F(ReplaceStrTest, replace_with_empty)
{
EXPECT_EQ( "Quick//Fox", MISC::replace_str( "Quick/Brown/Fox", "Brown", "" ) );
}

TEST_F(ReplaceStrTest, not_match)
{
EXPECT_EQ( "Quick Brown Fox", MISC::replace_str( "Quick Brown Fox", "Red", "Blue" ) );
}

TEST_F(ReplaceStrTest, multi_match)
{
EXPECT_EQ( "Quick Red Red Fox", MISC::replace_str( "Quick Brown Brown Fox", "Brown", "Red" ) );
}


class IsUrlSchemeTest : public ::testing::Test {};

TEST_F(IsUrlSchemeTest, url_none)
Expand Down

0 comments on commit 8455510

Please sign in to comment.