Skip to content

Commit

Permalink
Merge bitcoin#25057: refactor: replace remaining boost::split with Sp…
Browse files Browse the repository at this point in the history
…litString

f849e63 fuzz: SplitString with multiple separators (Martin Leitner-Ankerl)
d1a9850 http: replace boost::split with SplitString (Martin Leitner-Ankerl)
0d7efcd core_read: Replace boost::split with SplitString (Martin Leitner-Ankerl)
b7ab9db Extend Split to work with multiple separators (Martin Leitner-Ankerl)

Pull request description:

  As a followup of bitcoin#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 f849e63

Tree-SHA512: f37d4dbe11cab2046e646045b0f018a75f978d521443a2c5001512737a1370e22b09247d5db0e5c9e4153229a4e2d66731903c1bba3713711c4cae8cedcc775d
  • Loading branch information
fanquake authored and jagdeep sidhu committed May 4, 2022
1 parent 9c3c48a commit ed600ce
Show file tree
Hide file tree
Showing 7 changed files with 49 additions and 18 deletions.
8 changes: 2 additions & 6 deletions src/core_read.cpp
Expand Up @@ -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>

Expand Down Expand Up @@ -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)))
{
Expand Down
8 changes: 4 additions & 4 deletions src/httprpc.cpp
Expand Up @@ -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\"";

Expand Down Expand Up @@ -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(),
Expand Down
7 changes: 6 additions & 1 deletion src/test/fuzz/string.cpp
Expand Up @@ -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};
Expand Down
13 changes: 13 additions & 0 deletions src/test/util_tests.cpp
Expand Up @@ -2397,6 +2397,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)
Expand Down
20 changes: 17 additions & 3 deletions src/util/spanparsing.h
Expand Up @@ -8,6 +8,7 @@
#include <span.h>

#include <string>
#include <string_view>
#include <vector>

namespace spanparsing {
Expand Down Expand Up @@ -36,21 +37,21 @@ 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.
*
* 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)
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;
}
Expand All @@ -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 // SYSCOIN_UTIL_SPANPARSING_H
6 changes: 6 additions & 0 deletions src/util/string.h
Expand Up @@ -14,13 +14,19 @@
#include <locale>
#include <sstream>
#include <string>
#include <string_view>
#include <vector>

[[nodiscard]] inline std::vector<std::string> SplitString(std::string_view str, char sep)
{
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);
Expand Down
5 changes: 1 addition & 4 deletions test/lint/lint-includes.py
Expand Up @@ -22,10 +22,7 @@
"src/univalue/",
"src/bls-dash/"]

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",
Expand Down

0 comments on commit ed600ce

Please sign in to comment.