diff --git a/lib/errorlogger.cpp b/lib/errorlogger.cpp index 752af2b3ded..e04a973f5d6 100644 --- a/lib/errorlogger.cpp +++ b/lib/errorlogger.cpp @@ -523,22 +523,6 @@ std::string ErrorMessage::toXML() const return printer.CStr(); } -/** - * Replace all occurrences of searchFor with replaceWith in the - * given source. - * @param source The string to modify - * @param searchFor What should be searched for - * @param replaceWith What will replace the found item - */ -static void findAndReplace(std::string &source, const std::string &searchFor, const std::string &replaceWith) -{ - std::string::size_type index = 0; - while ((index = source.find(searchFor, index)) != std::string::npos) { - source.replace(index, searchFor.length(), replaceWith); - index += replaceWith.length(); - } -} - // TODO: read info from some shared resource instead? static std::string readCode(const std::string &file, int linenr, int column, const char endl[]) { diff --git a/lib/preprocessor.cpp b/lib/preprocessor.cpp index c6c51d1a05b..70e2e560770 100644 --- a/lib/preprocessor.cpp +++ b/lib/preprocessor.cpp @@ -43,20 +43,6 @@ static bool sameline(const simplecpp::Token *tok1, const simplecpp::Token *tok2) return tok1 && tok2 && tok1->location.sameline(tok2->location); } -/** - * Remove heading and trailing whitespaces from the input parameter. - * If string is all spaces/tabs, return empty string. - * @param s The string to trim. - */ -static std::string trim(const std::string& s) -{ - const std::string::size_type beg = s.find_first_not_of(" \t"); - if (beg == std::string::npos) - return ""; - const std::string::size_type end = s.find_last_not_of(" \t"); - return s.substr(beg, end - beg + 1); -} - Directive::Directive(std::string _file, const int _linenr, const std::string &_str) : file(std::move(_file)), linenr(_linenr), diff --git a/lib/utils.cpp b/lib/utils.cpp index cf8c0d0cb67..ff52298deb6 100644 --- a/lib/utils.cpp +++ b/lib/utils.cpp @@ -129,3 +129,21 @@ void strTolower(std::string& str) return std::tolower(c); }); } + +std::string trim(const std::string& s, const std::string& t) +{ + const std::string::size_type beg = s.find_first_not_of(t); + if (beg == std::string::npos) + return ""; + const std::string::size_type end = s.find_last_not_of(t); + return s.substr(beg, end - beg + 1); +} + +void findAndReplace(std::string &source, const std::string &searchFor, const std::string &replaceWith) +{ + std::string::size_type index = 0; + while ((index = source.find(searchFor, index)) != std::string::npos) { + source.replace(index, searchFor.length(), replaceWith); + index += replaceWith.length(); + } +} diff --git a/lib/utils.h b/lib/utils.h index 740acf00f89..34502736863 100644 --- a/lib/utils.h +++ b/lib/utils.h @@ -347,6 +347,23 @@ static inline const char* bool_to_string(bool b) return b ? "true" : "false"; } +/** + * Remove heading and trailing whitespaces from the input parameter. + * If string is all spaces/tabs, return empty string. + * @param s The string to trim. + * @param t The characters to trim. + */ +CPPCHECKLIB std::string trim(const std::string& s, const std::string& t = " \t"); + +/** + * Replace all occurrences of searchFor with replaceWith in the + * given source. + * @param source The string to modify + * @param searchFor What should be searched for + * @param replaceWith What will replace the found item + */ +CPPCHECKLIB void findAndReplace(std::string &source, const std::string &searchFor, const std::string &replaceWith); + namespace cppcheck { NORETURN inline void unreachable() diff --git a/test/testutils.cpp b/test/testutils.cpp index af04a91cbbc..531b2f477ed 100644 --- a/test/testutils.cpp +++ b/test/testutils.cpp @@ -38,6 +38,8 @@ class TestUtils : public TestFixture { TEST_CASE(strToInt); TEST_CASE(id_string); TEST_CASE(startsWith); + TEST_CASE(trim); + TEST_CASE(findAndReplace); } void isValidGlobPattern() const { @@ -357,6 +359,74 @@ class TestUtils : public TestFixture { ASSERT(!::startsWith("2test", "t")); ASSERT(!::startsWith("t", "test")); } + + void trim() const + { + ASSERT_EQUALS("test", ::trim("test")); + ASSERT_EQUALS("test", ::trim(" test")); + ASSERT_EQUALS("test", ::trim("test ")); + ASSERT_EQUALS("test", ::trim(" test ")); + ASSERT_EQUALS("test", ::trim(" test")); + ASSERT_EQUALS("test", ::trim("test ")); + ASSERT_EQUALS("test", ::trim(" test ")); + ASSERT_EQUALS("test", ::trim("\ttest")); + ASSERT_EQUALS("test", ::trim("test\t")); + ASSERT_EQUALS("test", ::trim("\ttest\t")); + ASSERT_EQUALS("test", ::trim("\t\ttest")); + ASSERT_EQUALS("test", ::trim("test\t\t")); + ASSERT_EQUALS("test", ::trim("\t\ttest\t\t")); + ASSERT_EQUALS("test", ::trim(" \ttest")); + ASSERT_EQUALS("test", ::trim("test\t ")); + ASSERT_EQUALS("test", ::trim(" \ttest\t")); + ASSERT_EQUALS("test", ::trim("\t \ttest")); + ASSERT_EQUALS("test", ::trim("test\t \t")); + ASSERT_EQUALS("test", ::trim("\t \ttest\t \t")); + + ASSERT_EQUALS("test test", ::trim("test test")); + ASSERT_EQUALS("test test", ::trim(" test test")); + ASSERT_EQUALS("test test", ::trim("test test ")); + ASSERT_EQUALS("test test", ::trim(" test test ")); + ASSERT_EQUALS("test\ttest", ::trim(" test\ttest")); + ASSERT_EQUALS("test\ttest", ::trim("test\ttest ")); + ASSERT_EQUALS("test\ttest", ::trim(" test\ttest ")); + + ASSERT_EQUALS("test", ::trim("\ntest", "\n")); + ASSERT_EQUALS("test", ::trim("test\n", "\n")); + ASSERT_EQUALS("test", ::trim("\ntest\n", "\n")); + } + + void findAndReplace() const { + { + std::string s{"test"}; + ::findAndReplace(s, "test", "tset"); + ASSERT_EQUALS("tset", s); + } + { + std::string s{"testtest"}; + ::findAndReplace(s, "test", "tset"); + ASSERT_EQUALS("tsettset", s); + } + { + std::string s{"1test1test1"}; + ::findAndReplace(s, "test", "tset"); + ASSERT_EQUALS("1tset1tset1", s); + } + { + std::string s{"1test1test1"}; + ::findAndReplace(s, "test", ""); + ASSERT_EQUALS("111", s); + } + { + std::string s{"111"}; + ::findAndReplace(s, "test", "tset"); + ASSERT_EQUALS("111", s); + } + { + std::string s; + ::findAndReplace(s, "test", "tset"); + ASSERT_EQUALS("", s); + } + } }; REGISTER_TEST(TestUtils)