refactor: introduce single-separator split helper SplitString

This helper uses spanparsing::Split internally and enables to replace
all calls to boost::split where only a single separator is passed.

Co-authored-by: Martin Ankerl <Martin.Ankerl@gmail.com>
Co-authored-by: MarcoFalke <falke.marco@gmail.com>
This commit is contained in:
Sebastian Falbesoner 2021-09-11 13:02:47 +02:00
parent 2b5a741e98
commit 9cc8e876e4
12 changed files with 47 additions and 71 deletions

View file

@ -31,8 +31,6 @@
#include <memory> #include <memory>
#include <stdio.h> #include <stdio.h>
#include <boost/algorithm/string.hpp>
static bool fCreateBlank; static bool fCreateBlank;
static std::map<std::string,UniValue> registers; static std::map<std::string,UniValue> registers;
static const int CONTINUE_EXECUTION=-1; static const int CONTINUE_EXECUTION=-1;
@ -251,8 +249,7 @@ static T TrimAndParse(const std::string& int_str, const std::string& err)
static void MutateTxAddInput(CMutableTransaction& tx, const std::string& strInput) static void MutateTxAddInput(CMutableTransaction& tx, const std::string& strInput)
{ {
std::vector<std::string> vStrInputParts; std::vector<std::string> vStrInputParts = SplitString(strInput, ':');
boost::split(vStrInputParts, strInput, boost::is_any_of(":"));
// separate TXID:VOUT in string // separate TXID:VOUT in string
if (vStrInputParts.size()<2) if (vStrInputParts.size()<2)
@ -287,8 +284,7 @@ static void MutateTxAddInput(CMutableTransaction& tx, const std::string& strInpu
static void MutateTxAddOutAddr(CMutableTransaction& tx, const std::string& strInput) static void MutateTxAddOutAddr(CMutableTransaction& tx, const std::string& strInput)
{ {
// Separate into VALUE:ADDRESS // Separate into VALUE:ADDRESS
std::vector<std::string> vStrInputParts; std::vector<std::string> vStrInputParts = SplitString(strInput, ':');
boost::split(vStrInputParts, strInput, boost::is_any_of(":"));
if (vStrInputParts.size() != 2) if (vStrInputParts.size() != 2)
throw std::runtime_error("TX output missing or too many separators"); throw std::runtime_error("TX output missing or too many separators");
@ -312,8 +308,7 @@ static void MutateTxAddOutAddr(CMutableTransaction& tx, const std::string& strIn
static void MutateTxAddOutPubKey(CMutableTransaction& tx, const std::string& strInput) static void MutateTxAddOutPubKey(CMutableTransaction& tx, const std::string& strInput)
{ {
// Separate into VALUE:PUBKEY[:FLAGS] // Separate into VALUE:PUBKEY[:FLAGS]
std::vector<std::string> vStrInputParts; std::vector<std::string> vStrInputParts = SplitString(strInput, ':');
boost::split(vStrInputParts, strInput, boost::is_any_of(":"));
if (vStrInputParts.size() < 2 || vStrInputParts.size() > 3) if (vStrInputParts.size() < 2 || vStrInputParts.size() > 3)
throw std::runtime_error("TX output missing or too many separators"); throw std::runtime_error("TX output missing or too many separators");
@ -356,8 +351,7 @@ static void MutateTxAddOutPubKey(CMutableTransaction& tx, const std::string& str
static void MutateTxAddOutMultiSig(CMutableTransaction& tx, const std::string& strInput) static void MutateTxAddOutMultiSig(CMutableTransaction& tx, const std::string& strInput)
{ {
// Separate into VALUE:REQUIRED:NUMKEYS:PUBKEY1:PUBKEY2:....[:FLAGS] // Separate into VALUE:REQUIRED:NUMKEYS:PUBKEY1:PUBKEY2:....[:FLAGS]
std::vector<std::string> vStrInputParts; std::vector<std::string> vStrInputParts = SplitString(strInput, ':');
boost::split(vStrInputParts, strInput, boost::is_any_of(":"));
// Check that there are enough parameters // Check that there are enough parameters
if (vStrInputParts.size()<3) if (vStrInputParts.size()<3)
@ -460,8 +454,7 @@ static void MutateTxAddOutData(CMutableTransaction& tx, const std::string& strIn
static void MutateTxAddOutScript(CMutableTransaction& tx, const std::string& strInput) static void MutateTxAddOutScript(CMutableTransaction& tx, const std::string& strInput)
{ {
// separate VALUE:SCRIPT[:FLAGS] // separate VALUE:SCRIPT[:FLAGS]
std::vector<std::string> vStrInputParts; std::vector<std::string> vStrInputParts = SplitString(strInput, ':');
boost::split(vStrInputParts, strInput, boost::is_any_of(":"));
if (vStrInputParts.size() < 2) if (vStrInputParts.size() < 2)
throw std::runtime_error("TX output missing separator"); throw std::runtime_error("TX output missing separator");

View file

@ -10,13 +10,11 @@
#include <deploymentinfo.h> #include <deploymentinfo.h>
#include <hash.h> // for signet block challenge hash #include <hash.h> // for signet block challenge hash
#include <script/interpreter.h> #include <script/interpreter.h>
#include <util/string.h>
#include <util/system.h> #include <util/system.h>
#include <assert.h> #include <assert.h>
#include <boost/algorithm/string/classification.hpp>
#include <boost/algorithm/string/split.hpp>
static CBlock CreateGenesisBlock(const char* pszTimestamp, const CScript& genesisOutputScript, uint32_t nTime, uint32_t nNonce, uint32_t nBits, int32_t nVersion, const CAmount& genesisReward) static CBlock CreateGenesisBlock(const char* pszTimestamp, const CScript& genesisOutputScript, uint32_t nTime, uint32_t nNonce, uint32_t nBits, int32_t nVersion, const CAmount& genesisReward)
{ {
CMutableTransaction txNew; CMutableTransaction txNew;
@ -528,8 +526,7 @@ void CRegTestParams::UpdateActivationParametersFromArgs(const ArgsManager& args)
if (!args.IsArgSet("-vbparams")) return; if (!args.IsArgSet("-vbparams")) return;
for (const std::string& strDeployment : args.GetArgs("-vbparams")) { for (const std::string& strDeployment : args.GetArgs("-vbparams")) {
std::vector<std::string> vDeploymentParams; std::vector<std::string> vDeploymentParams = SplitString(strDeployment, ':');
boost::split(vDeploymentParams, strDeployment, boost::is_any_of(":"));
if (vDeploymentParams.size() < 3 || 4 < vDeploymentParams.size()) { if (vDeploymentParams.size() < 3 || 4 < vDeploymentParams.size()) {
throw std::runtime_error("Version bits parameters malformed, expecting deployment:start:end[:min_activation_height]"); throw std::runtime_error("Version bits parameters malformed, expecting deployment:start:end[:min_activation_height]");
} }

View file

@ -32,8 +32,6 @@
#include <any> #include <any>
#include <string> #include <string>
#include <boost/algorithm/string.hpp>
#include <univalue.h> #include <univalue.h>
using node::GetTransaction; using node::GetTransaction;
@ -192,8 +190,7 @@ static bool rest_headers(const std::any& context,
return false; return false;
std::string param; std::string param;
const RESTResponseFormat rf = ParseDataFormat(param, strURIPart); const RESTResponseFormat rf = ParseDataFormat(param, strURIPart);
std::vector<std::string> path; std::vector<std::string> path = SplitString(param, '/');
boost::split(path, param, boost::is_any_of("/"));
std::string raw_count; std::string raw_count;
std::string hashStr; std::string hashStr;
@ -363,8 +360,7 @@ static bool rest_filter_header(const std::any& context, HTTPRequest* req, const
std::string param; std::string param;
const RESTResponseFormat rf = ParseDataFormat(param, strURIPart); const RESTResponseFormat rf = ParseDataFormat(param, strURIPart);
std::vector<std::string> uri_parts; std::vector<std::string> uri_parts = SplitString(param, '/');
boost::split(uri_parts, param, boost::is_any_of("/"));
std::string raw_count; std::string raw_count;
std::string raw_blockhash; std::string raw_blockhash;
if (uri_parts.size() == 3) { if (uri_parts.size() == 3) {
@ -484,8 +480,7 @@ static bool rest_block_filter(const std::any& context, HTTPRequest* req, const s
const RESTResponseFormat rf = ParseDataFormat(param, strURIPart); const RESTResponseFormat rf = ParseDataFormat(param, strURIPart);
// request is sent over URI scheme /rest/blockfilter/filtertype/blockhash // request is sent over URI scheme /rest/blockfilter/filtertype/blockhash
std::vector<std::string> uri_parts; std::vector<std::string> uri_parts = SplitString(param, '/');
boost::split(uri_parts, param, boost::is_any_of("/"));
if (uri_parts.size() != 2) { if (uri_parts.size() != 2) {
return RESTERR(req, HTTP_BAD_REQUEST, "Invalid URI format. Expected /rest/blockfilter/<filtertype>/<blockhash>"); return RESTERR(req, HTTP_BAD_REQUEST, "Invalid URI format. Expected /rest/blockfilter/<filtertype>/<blockhash>");
} }
@ -713,7 +708,7 @@ static bool rest_getutxos(const std::any& context, HTTPRequest* req, const std::
if (param.length() > 1) if (param.length() > 1)
{ {
std::string strUriParams = param.substr(1); std::string strUriParams = param.substr(1);
boost::split(uriParts, strUriParams, boost::is_any_of("/")); uriParts = SplitString(strUriParams, '/');
} }
// throw exception in case of an empty request // throw exception in case of an empty request

View file

@ -9,10 +9,9 @@
#include <shutdown.h> #include <shutdown.h>
#include <sync.h> #include <sync.h>
#include <util/strencodings.h> #include <util/strencodings.h>
#include <util/string.h>
#include <util/system.h> #include <util/system.h>
#include <boost/algorithm/string/classification.hpp>
#include <boost/algorithm/string/split.hpp>
#include <boost/signals2/signal.hpp> #include <boost/signals2/signal.hpp>
#include <cassert> #include <cassert>
@ -407,8 +406,7 @@ static inline JSONRPCRequest transformNamedArguments(const JSONRPCRequest& in, c
// Process expected parameters. // Process expected parameters.
int hole = 0; int hole = 0;
for (const std::string &argNamePattern: argNames) { for (const std::string &argNamePattern: argNames) {
std::vector<std::string> vargNames; std::vector<std::string> vargNames = SplitString(argNamePattern, '|');
boost::algorithm::split(vargNames, argNamePattern, boost::algorithm::is_any_of("|"));
auto fr = argsIn.end(); auto fr = argsIn.end();
for (const std::string & argName : vargNames) { for (const std::string & argName : vargNames) {
fr = argsIn.find(argName); fr = argsIn.find(argName);

View file

@ -15,9 +15,6 @@
#include <tuple> #include <tuple>
#include <boost/algorithm/string/classification.hpp>
#include <boost/algorithm/string/split.hpp>
const std::string UNIX_EPOCH_TIME = "UNIX epoch time"; const std::string UNIX_EPOCH_TIME = "UNIX epoch time";
const std::string EXAMPLE_ADDRESS[2] = {"bc1q09vm5lfy0j5reeulh4x5752q25uqqvz34hufdl", "bc1q02ad21edsxd23d32dfgqqsz4vv4nmtfzuklhy3"}; const std::string EXAMPLE_ADDRESS[2] = {"bc1q09vm5lfy0j5reeulh4x5752q25uqqvz34hufdl", "bc1q02ad21edsxd23d32dfgqqsz4vv4nmtfzuklhy3"};
@ -513,8 +510,7 @@ RPCHelpMan::RPCHelpMan(std::string name, std::string description, std::vector<RP
{ {
std::set<std::string> named_args; std::set<std::string> named_args;
for (const auto& arg : m_args) { for (const auto& arg : m_args) {
std::vector<std::string> names; std::vector<std::string> names = SplitString(arg.m_names, '|');
boost::split(names, arg.m_names, boost::is_any_of("|"));
// Should have unique named arguments // Should have unique named arguments
for (const std::string& name : names) { for (const std::string& name : names) {
CHECK_NONFATAL(named_args.insert(name).second); CHECK_NONFATAL(named_args.insert(name).second);
@ -665,8 +661,7 @@ UniValue RPCHelpMan::GetArgMap() const
UniValue arr{UniValue::VARR}; UniValue arr{UniValue::VARR};
for (int i{0}; i < int(m_args.size()); ++i) { for (int i{0}; i < int(m_args.size()); ++i) {
const auto& arg = m_args.at(i); const auto& arg = m_args.at(i);
std::vector<std::string> arg_names; std::vector<std::string> arg_names = SplitString(arg.m_names, '|');
boost::split(arg_names, arg.m_names, boost::is_any_of("|"));
for (const auto& arg_name : arg_names) { for (const auto& arg_name : arg_names) {
UniValue map{UniValue::VARR}; UniValue map{UniValue::VARR};
map.push_back(m_name); map.push_back(m_name);

View file

@ -11,8 +11,8 @@
#include <streams.h> #include <streams.h>
#include <univalue.h> #include <univalue.h>
#include <util/strencodings.h> #include <util/strencodings.h>
#include <util/string.h>
#include <boost/algorithm/string.hpp>
#include <cstdint> #include <cstdint>
#include <string> #include <string>
#include <vector> #include <vector>
@ -130,8 +130,7 @@ unsigned int ParseScriptFlags(const std::string& str)
if (str.empty()) return 0; if (str.empty()) return 0;
unsigned int flags = 0; unsigned int flags = 0;
std::vector<std::string> words; std::vector<std::string> words = SplitString(str, ',');
boost::algorithm::split(words, str, boost::algorithm::is_any_of(","));
for (const std::string& word : words) { for (const std::string& word : words) {
auto it = FLAG_NAMES.find(word); auto it = FLAG_NAMES.find(word);

View file

@ -31,8 +31,6 @@
#include <map> #include <map>
#include <string> #include <string>
#include <boost/algorithm/string/classification.hpp>
#include <boost/algorithm/string/split.hpp>
#include <boost/test/unit_test.hpp> #include <boost/test/unit_test.hpp>
#include <univalue.h> #include <univalue.h>
@ -70,8 +68,7 @@ unsigned int ParseScriptFlags(std::string strFlags)
{ {
if (strFlags.empty() || strFlags == "NONE") return 0; if (strFlags.empty() || strFlags == "NONE") return 0;
unsigned int flags = 0; unsigned int flags = 0;
std::vector<std::string> words; std::vector<std::string> words = SplitString(strFlags, ',');
boost::algorithm::split(words, strFlags, boost::algorithm::is_any_of(","));
for (const std::string& word : words) for (const std::string& word : words)
{ {

View file

@ -24,9 +24,7 @@
#include <set> #include <set>
#include <vector> #include <vector>
#include <boost/algorithm/string/classification.hpp>
#include <boost/algorithm/string/replace.hpp> #include <boost/algorithm/string/replace.hpp>
#include <boost/algorithm/string/split.hpp>
#include <event2/buffer.h> #include <event2/buffer.h>
#include <event2/bufferevent.h> #include <event2/bufferevent.h>
@ -347,8 +345,8 @@ void TorController::get_socks_cb(TorControlConnection& _conn, const TorControlRe
for (const auto& line : reply.lines) { for (const auto& line : reply.lines) {
if (0 == line.compare(0, 20, "net/listeners/socks=")) { if (0 == line.compare(0, 20, "net/listeners/socks=")) {
const std::string port_list_str = line.substr(20); const std::string port_list_str = line.substr(20);
std::vector<std::string> port_list; std::vector<std::string> port_list = SplitString(port_list_str, ' ');
boost::split(port_list, port_list_str, boost::is_any_of(" "));
for (auto& portstr : port_list) { for (auto& portstr : port_list) {
if (portstr.empty()) continue; if (portstr.empty()) continue;
if ((portstr[0] == '"' || portstr[0] == '\'') && portstr.size() >= 2 && (*portstr.rbegin() == portstr[0])) { if ((portstr[0] == '"' || portstr[0] == '\'') && portstr.size() >= 2 && (*portstr.rbegin() == portstr[0])) {
@ -542,8 +540,10 @@ void TorController::protocolinfo_cb(TorControlConnection& _conn, const TorContro
if (l.first == "AUTH") { if (l.first == "AUTH") {
std::map<std::string,std::string> m = ParseTorReplyMapping(l.second); std::map<std::string,std::string> m = ParseTorReplyMapping(l.second);
std::map<std::string,std::string>::iterator i; std::map<std::string,std::string>::iterator i;
if ((i = m.find("METHODS")) != m.end()) if ((i = m.find("METHODS")) != m.end()) {
boost::split(methods, i->second, boost::is_any_of(",")); std::vector<std::string> m_vec = SplitString(i->second, ',');
methods = std::set<std::string>(m_vec.begin(), m_vec.end());
}
if ((i = m.find("COOKIEFILE")) != m.end()) if ((i = m.find("COOKIEFILE")) != m.end())
cookiefile = i->second; cookiefile = i->second;
} else if (l.first == "VERSION") { } else if (l.first == "VERSION") {

View file

@ -48,20 +48,4 @@ Span<const char> Expr(Span<const char>& sp)
return ret; return ret;
} }
std::vector<Span<const char>> Split(const Span<const char>& sp, char sep)
{
std::vector<Span<const char>> ret;
auto it = sp.begin();
auto start = it;
while (it != sp.end()) {
if (*it == sep) {
ret.emplace_back(start, it);
start = it + 1;
}
++it;
}
ret.emplace_back(start, it);
return ret;
}
} // namespace spanparsing } // namespace spanparsing

View file

@ -43,7 +43,22 @@ Span<const char> Expr(Span<const char>& sp);
* Note that this function does not care about braces, so splitting * Note that this function does not care about braces, so splitting
* "foo(bar(1),2),3) on ',' will return {"foo(bar(1)", "2)", "3)"}. * "foo(bar(1),2),3) on ',' will return {"foo(bar(1)", "2)", "3)"}.
*/ */
std::vector<Span<const char>> Split(const Span<const char>& sp, char sep); template <typename T = Span<const char>>
std::vector<T> Split(const Span<const char>& sp, char sep)
{
std::vector<T> ret;
auto it = sp.begin();
auto start = it;
while (it != sp.end()) {
if (*it == sep) {
ret.emplace_back(start, it);
start = it + 1;
}
++it;
}
ret.emplace_back(start, it);
return ret;
}
} // namespace spanparsing } // namespace spanparsing

View file

@ -6,6 +6,7 @@
#define BITCOIN_UTIL_STRING_H #define BITCOIN_UTIL_STRING_H
#include <attributes.h> #include <attributes.h>
#include <util/spanparsing.h>
#include <algorithm> #include <algorithm>
#include <array> #include <array>
@ -15,6 +16,11 @@
#include <string> #include <string>
#include <vector> #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::string TrimString(const std::string& str, const std::string& pattern = " \f\n\r\t\v") [[nodiscard]] inline std::string TrimString(const std::string& str, const std::string& pattern = " \f\n\r\t\v")
{ {
std::string::size_type front = str.find_first_not_of(pattern); std::string::size_type front = str.find_first_not_of(pattern);

View file

@ -26,8 +26,6 @@
#include <tuple> #include <tuple>
#include <string> #include <string>
#include <boost/algorithm/string.hpp>
#include <univalue.h> #include <univalue.h>
@ -546,8 +544,7 @@ RPCHelpMan importwallet()
if (line.empty() || line[0] == '#') if (line.empty() || line[0] == '#')
continue; continue;
std::vector<std::string> vstr; std::vector<std::string> vstr = SplitString(line, ' ');
boost::split(vstr, line, boost::is_any_of(" "));
if (vstr.size() < 2) if (vstr.size() < 2)
continue; continue;
CKey key = DecodeSecret(vstr[0]); CKey key = DecodeSecret(vstr[0]);