diff options
author | fanquake <fanquake@gmail.com> | 2022-05-04 18:09:35 +0100 |
---|---|---|
committer | fanquake <fanquake@gmail.com> | 2022-05-04 18:20:27 +0100 |
commit | bde5836f99966b382463a585db87faae27514a70 (patch) | |
tree | 31d75b513933af7b18a1d36a04097d37e96e06ca | |
parent | 9183c66cc6ae173e0f2efe52b09cb9a8e64d5550 (diff) | |
parent | f849e63bad963b8717d4bc45efdad9b08567a36e (diff) |
Merge bitcoin/bitcoin#25057: refactor: replace remaining boost::split with SplitString
f849e63bad963b8717d4bc45efdad9b08567a36e fuzz: SplitString with multiple separators (Martin Leitner-Ankerl)
d1a9850102fe572b8a1e00b80c757dd82bf39f9d http: replace boost::split with SplitString (Martin Leitner-Ankerl)
0d7efcdf75607e19fac77bcd146773a03af14492 core_read: Replace boost::split with SplitString (Martin Leitner-Ankerl)
b7ab9db545492927b774912e53aeb834a590621f Extend Split to work with multiple separators (Martin Leitner-Ankerl)
Pull request description:
As a followup of #22953, this removes the remaining occurrences of `boost::split` and replaces them with our own `SplitString`. To be able to do so, this extends the function `spanparsing::Split` to work with multiple separators. Finally this removes 3 more files from `lint-includes.py`.
ACKs for top commit:
theStack:
Code-review ACK f849e63bad963b8717d4bc45efdad9b08567a36e
Tree-SHA512: f37d4dbe11cab2046e646045b0f018a75f978d521443a2c5001512737a1370e22b09247d5db0e5c9e4153229a4e2d66731903c1bba3713711c4cae8cedcc775d
-rw-r--r-- | src/core_read.cpp | 8 | ||||
-rw-r--r-- | src/httprpc.cpp | 8 | ||||
-rw-r--r-- | src/test/fuzz/string.cpp | 7 | ||||
-rw-r--r-- | src/test/util_tests.cpp | 13 | ||||
-rw-r--r-- | src/util/spanparsing.h | 20 | ||||
-rw-r--r-- | src/util/string.h | 6 | ||||
-rwxr-xr-x | test/lint/lint-includes.py | 5 |
7 files changed, 49 insertions, 18 deletions
diff --git a/src/core_read.cpp b/src/core_read.cpp index 3bab5b5d98..77c516427a 100644 --- a/src/core_read.cpp +++ b/src/core_read.cpp @@ -14,9 +14,6 @@ #include <util/strencodings.h> #include <version.h> -#include <boost/algorithm/string/classification.hpp> -#include <boost/algorithm/string/split.hpp> - #include <algorithm> #include <string> @@ -66,12 +63,11 @@ CScript ParseScript(const std::string& s) { CScript result; - std::vector<std::string> words; - boost::algorithm::split(words, s, boost::algorithm::is_any_of(" \t\n"), boost::algorithm::token_compress_on); + std::vector<std::string> words = SplitString(s, " \t\n"); for (const std::string& w : words) { if (w.empty()) { - // Empty string, ignore. (boost::split given '' will return one word) + // Empty string, ignore. (SplitString doesn't combine multiple separators) } else if (std::all_of(w.begin(), w.end(), ::IsDigit) || (w.front() == '-' && w.size() > 1 && std::all_of(w.begin() + 1, w.end(), ::IsDigit))) { diff --git a/src/httprpc.cpp b/src/httprpc.cpp index af27ff3506..3bf165495c 100644 --- a/src/httprpc.cpp +++ b/src/httprpc.cpp @@ -21,8 +21,6 @@ #include <string> #include <vector> -#include <boost/algorithm/string.hpp> - /** WWW-Authenticate to present with 401 Unauthorized response */ static const char* WWW_AUTH_HEADER_DATA = "Basic realm=\"jsonrpc\""; @@ -276,8 +274,10 @@ static bool InitRPCAuthentication() std::set<std::string>& whitelist = g_rpc_whitelist[strUser]; if (pos != std::string::npos) { std::string strWhitelist = strRPCWhitelist.substr(pos + 1); - std::set<std::string> new_whitelist; - boost::split(new_whitelist, strWhitelist, boost::is_any_of(", ")); + std::vector<std::string> whitelist_split = SplitString(strWhitelist, ", "); + std::set<std::string> new_whitelist{ + std::make_move_iterator(whitelist_split.begin()), + std::make_move_iterator(whitelist_split.end())}; if (intersect) { std::set<std::string> tmp_whitelist; std::set_intersection(new_whitelist.begin(), new_whitelist.end(), diff --git a/src/test/fuzz/string.cpp b/src/test/fuzz/string.cpp index e6064d19b6..94399faf04 100644 --- a/src/test/fuzz/string.cpp +++ b/src/test/fuzz/string.cpp @@ -224,7 +224,12 @@ FUZZ_TARGET(string) int64_t amount_out; (void)ParseFixedPoint(random_string_1, fuzzed_data_provider.ConsumeIntegralInRange<int>(0, 1024), &amount_out); } - (void)SplitString(random_string_1, fuzzed_data_provider.ConsumeIntegral<char>()); + { + const auto single_split{SplitString(random_string_1, fuzzed_data_provider.ConsumeIntegral<char>())}; + assert(single_split.size() >= 1); + const auto any_split{SplitString(random_string_1, random_string_2)}; + assert(any_split.size() >= 1); + } { (void)Untranslated(random_string_1); const bilingual_str bs1{random_string_1, random_string_2}; diff --git a/src/test/util_tests.cpp b/src/test/util_tests.cpp index b880a7a9fd..890b2f997e 100644 --- a/src/test/util_tests.cpp +++ b/src/test/util_tests.cpp @@ -2396,6 +2396,19 @@ BOOST_AUTO_TEST_CASE(test_SplitString) BOOST_CHECK_EQUAL(result.size(), 1); BOOST_CHECK_EQUAL(result[0], "AAA"); } + + // multiple split characters + { + using V = std::vector<std::string>; + BOOST_TEST(SplitString("a,b.c:d;e", ",;") == V({"a", "b.c:d", "e"})); + BOOST_TEST(SplitString("a,b.c:d;e", ",;:.") == V({"a", "b", "c", "d", "e"})); + BOOST_TEST(SplitString("a,b.c:d;e", "") == V({"a,b.c:d;e"})); + BOOST_TEST(SplitString("aaa", "bcdefg") == V({"aaa"})); + BOOST_TEST(SplitString("x\0a,b"s, "\0"s) == V({"x", "a,b"})); + BOOST_TEST(SplitString("x\0a,b"s, '\0') == V({"x", "a,b"})); + BOOST_TEST(SplitString("x\0a,b"s, "\0,"s) == V({"x", "a", "b"})); + BOOST_TEST(SplitString("abcdefg", "bcd") == V({"a", "", "", "efg"})); + } } BOOST_AUTO_TEST_CASE(test_LogEscapeMessage) diff --git a/src/util/spanparsing.h b/src/util/spanparsing.h index ebec8714a7..51795271de 100644 --- a/src/util/spanparsing.h +++ b/src/util/spanparsing.h @@ -8,6 +8,7 @@ #include <span.h> #include <string> +#include <string_view> #include <vector> namespace spanparsing { @@ -36,7 +37,7 @@ bool Func(const std::string& str, Span<const char>& sp); */ Span<const char> Expr(Span<const char>& sp); -/** Split a string on every instance of sep, returning a vector. +/** Split a string on any char found in separators, returning a vector. * * If sep does not occur in sp, a singleton with the entirety of sp is returned. * @@ -44,13 +45,13 @@ Span<const char> Expr(Span<const char>& sp); * "foo(bar(1),2),3) on ',' will return {"foo(bar(1)", "2)", "3)"}. */ template <typename T = Span<const char>> -std::vector<T> Split(const Span<const char>& sp, char sep) +std::vector<T> Split(const Span<const char>& sp, std::string_view separators) { std::vector<T> ret; auto it = sp.begin(); auto start = it; while (it != sp.end()) { - if (*it == sep) { + if (separators.find(*it) != std::string::npos) { ret.emplace_back(start, it); start = it + 1; } @@ -60,6 +61,19 @@ std::vector<T> Split(const Span<const char>& sp, char sep) return ret; } +/** Split a string on every instance of sep, returning a vector. + * + * If sep does not occur in sp, a singleton with the entirety of sp is returned. + * + * Note that this function does not care about braces, so splitting + * "foo(bar(1),2),3) on ',' will return {"foo(bar(1)", "2)", "3)"}. + */ +template <typename T = Span<const char>> +std::vector<T> Split(const Span<const char>& sp, char sep) +{ + return Split<T>(sp, std::string_view{&sep, 1}); +} + } // namespace spanparsing #endif // BITCOIN_UTIL_SPANPARSING_H diff --git a/src/util/string.h b/src/util/string.h index 36b9787db4..2e91347b27 100644 --- a/src/util/string.h +++ b/src/util/string.h @@ -14,6 +14,7 @@ #include <locale> #include <sstream> #include <string> +#include <string_view> #include <vector> [[nodiscard]] inline std::vector<std::string> SplitString(std::string_view str, char sep) @@ -21,6 +22,11 @@ return spanparsing::Split<std::string>(str, sep); } +[[nodiscard]] inline std::vector<std::string> SplitString(std::string_view str, std::string_view separators) +{ + return spanparsing::Split<std::string>(str, separators); +} + [[nodiscard]] inline std::string_view TrimStringView(std::string_view str, std::string_view pattern = " \f\n\r\t\v") { std::string::size_type front = str.find_first_not_of(pattern); diff --git a/test/lint/lint-includes.py b/test/lint/lint-includes.py index b29c7f8b4d..ae62994642 100755 --- a/test/lint/lint-includes.py +++ b/test/lint/lint-includes.py @@ -21,10 +21,7 @@ EXCLUDED_DIRS = ["src/leveldb/", "src/minisketch/", "src/univalue/"] -EXPECTED_BOOST_INCLUDES = ["boost/algorithm/string.hpp", - "boost/algorithm/string/classification.hpp", - "boost/algorithm/string/replace.hpp", - "boost/algorithm/string/split.hpp", +EXPECTED_BOOST_INCLUDES = ["boost/algorithm/string/replace.hpp", "boost/date_time/posix_time/posix_time.hpp", "boost/multi_index/hashed_index.hpp", "boost/multi_index/ordered_index.hpp", |