diff --git a/CBot/src/CBot/CBotDebug.cpp b/CBot/src/CBot/CBotDebug.cpp
index fa21acaf..1f39fd83 100644
--- a/CBot/src/CBot/CBotDebug.cpp
+++ b/CBot/src/CBot/CBotDebug.cpp
@@ -63,13 +63,25 @@ void CBotDebug::DumpCompiledProgram(CBotProgram* program)
if (finished.find(instr) != finished.end()) return;
finished.insert(instr);
- std::string label = ""+instr->GetDebugName()+"\n";
+ auto replaceAll = [](std::string& text, const std::string& from, const std::string& to)
+ {
+ std::size_t pos = 0;
+
+ while ((pos = text.find(from, pos)) != std::string::npos)
+ {
+ text.replace(pos, from.length(), to);
+ pos += to.length();
+ }
+ };
+
std::string data = instr->GetDebugData();
- boost::algorithm::replace_all(data, "&", "&");
- boost::algorithm::replace_all(data, "<", "<");
- boost::algorithm::replace_all(data, ">", ">");
+ replaceAll(data, "&", "&");
+ replaceAll(data, "<", "<");
+ replaceAll(data, ">", ">");
+
+ std::string label = ""+instr->GetDebugName()+"\n";
label += data;
- boost::algorithm::replace_all(label, "\n", "
");
+ replaceAll(label, "\n", "
");
std::string additional = "";
if (instr->GetDebugName() == "CBotFunction")
diff --git a/src/common/stringutils.cpp b/src/common/stringutils.cpp
index 8ce69cbb..4c49d3f3 100644
--- a/src/common/stringutils.cpp
+++ b/src/common/stringutils.cpp
@@ -76,7 +76,7 @@ std::string StrUtils::Replace(const std::string &str, const std::string &oldStr,
{
std::string result = str;
std::size_t pos = 0;
- while ((pos = str.find(oldStr, pos)) != std::string::npos)
+ while ((pos = result.find(oldStr, pos)) != std::string::npos)
{
result.replace(pos, oldStr.length(), newStr);
pos += newStr.length();
diff --git a/src/level/parser/parser.cpp b/src/level/parser/parser.cpp
index c79519d5..b90c150d 100644
--- a/src/level/parser/parser.cpp
+++ b/src/level/parser/parser.cpp
@@ -167,7 +167,7 @@ void CLevelParser::Load()
{
lineNumber++;
- boost::replace_all(line, "\t", " "); // replace tab by space
+ line = StrUtils::Replace(line, "\t", " "); // replace tab by space
// ignore comments
size_t pos = 0;
@@ -337,9 +337,9 @@ void CLevelParser::SetLevelPaths(LevelCategory category, int chapter, int rank)
std::string CLevelParser::InjectLevelPaths(const std::string& path, const std::string& defaultDir)
{
std::string newPath = path;
- if(!m_pathLvl.empty() ) boost::replace_all(newPath, "%lvl%", m_pathLvl);
- if(!m_pathChap.empty()) boost::replace_all(newPath, "%chap%", m_pathChap);
- if(!m_pathCat.empty() ) boost::replace_all(newPath, "%cat%", m_pathCat);
+ if(!m_pathLvl.empty() ) newPath = StrUtils::Replace(newPath, "%lvl%", m_pathLvl);
+ if(!m_pathChap.empty()) newPath = StrUtils::Replace(newPath, "%chap%", m_pathChap);
+ if(!m_pathCat.empty() ) newPath = StrUtils::Replace(newPath, "%cat%", m_pathCat);
if(newPath == path && !path.empty())
{
newPath = defaultDir + (!defaultDir.empty() ? "/" : "") + newPath;
@@ -347,12 +347,12 @@ std::string CLevelParser::InjectLevelPaths(const std::string& path, const std::s
std::string langPath = newPath;
std::string langStr(1, CApplication::GetInstancePointer()->GetLanguageChar());
- boost::replace_all(langPath, "%lng%", langStr);
+ langPath = StrUtils::Replace(langPath, "%lng%", langStr);
if(CResourceManager::Exists(langPath))
return langPath;
// Fallback to English if file doesn't exist
- boost::replace_all(newPath, "%lng%", "E");
+ newPath = StrUtils::Replace(newPath, "%lng%", "E");
if(CResourceManager::Exists(newPath))
return newPath;
diff --git a/src/ui/controls/edit.cpp b/src/ui/controls/edit.cpp
index f52f392b..d0cb235f 100644
--- a/src/ui/controls/edit.cpp
+++ b/src/ui/controls/edit.cpp
@@ -820,7 +820,7 @@ void CEdit::HyperJump(std::string name, std::string marker)
std::string filename = name + std::string(".txt");
filename = InjectLevelPathsForCurrentLevel(filename, "help/%lng%");
- boost::replace_all(filename, "\\", "/"); //TODO: Fix this in files
+ filename = StrUtils::Replace(filename, "\\", "/"); //TODO: Fix this in files
if ( ReadText(filename) )
{
@@ -1172,7 +1172,7 @@ static std::string PrepareImageFilename(std::string name)
std::string filename;
filename = name + ".png";
filename = InjectLevelPathsForCurrentLevel(filename, "icons");
- boost::replace_all(filename, "\\", "/"); // TODO: Fix this in files
+ filename = StrUtils::Replace(filename, "\\", "/"); // TODO: Fix this in files
return filename;
}
diff --git a/test/unit/CMakeLists.txt b/test/unit/CMakeLists.txt
index 99affae8..8b7792c2 100644
--- a/test/unit/CMakeLists.txt
+++ b/test/unit/CMakeLists.txt
@@ -15,6 +15,7 @@ add_executable(colobot_ut
CBot/CBotFileUtils_test.cpp
CBot/CBotToken_test.cpp
common/config_file_test.cpp
+ common/stringutils_test.cpp
common/timeutils_test.cpp
#graphics/engine/lightman_test.cpp
math/func_test.cpp
diff --git a/test/unit/common/stringutils_test.cpp b/test/unit/common/stringutils_test.cpp
new file mode 100644
index 00000000..9411bdb9
--- /dev/null
+++ b/test/unit/common/stringutils_test.cpp
@@ -0,0 +1,60 @@
+/*
+ * This file is part of the Colobot: Gold Edition source code
+ * Copyright (C) 2001-2023, Daniel Roux, EPSITEC SA & TerranovaTeam
+ * http://epsitec.ch; http://colobot.info; http://github.com/colobot
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ * See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see http://gnu.org/licenses
+ */
+
+#include "common/stringutils.h"
+
+#include
+
+namespace StringUtilsTesta
+{
+
+TEST(StringUtilTests, ReplaceShortToLong)
+{
+ std::string text = "Test {123}, {123}, {123}{123} Test";
+
+ auto result = StrUtils::Replace(text, "{123}", "[0987654]");
+
+ std::string expected = "Test [0987654], [0987654], [0987654][0987654] Test";
+
+ EXPECT_TRUE(result == expected);
+}
+
+TEST(StringUtilTests, ReplaceLongToShort)
+{
+ std::string text = "Test {1234567}, {1234567}, {1234567}{1234567} Test";
+
+ auto result = StrUtils::Replace(text, "{1234567}", "[64]");
+
+ std::string expected = "Test [64], [64], [64][64] Test";
+
+ EXPECT_TRUE(result == expected);
+}
+
+TEST(StringUtilTests, ReplaceSameLength)
+{
+ std::string text = "Test {123}, {123}, {123}{123} Test";
+
+ auto result = StrUtils::Replace(text, "{123}", "[432]");
+
+ std::string expected = "Test [432], [432], [432][432] Test";
+
+ EXPECT_TRUE(result == expected);
+}
+
+} // namespace StringUtils