From d7549f8d5393a1fe9374635327d192dd3f94feae Mon Sep 17 00:00:00 2001 From: trapexit Date: Fri, 22 Aug 2025 20:42:31 -0400 Subject: [PATCH] Fix string manipulation functions after refactor (#1514) --- src/str.cpp | 55 ++++++++++++++++++++++++++++++++--------- src/str.hpp | 5 ++++ tests/tests.cpp | 66 ++++++++++++++++++++++++++++++++++++++----------- 3 files changed, 100 insertions(+), 26 deletions(-) diff --git a/src/str.cpp b/src/str.cpp index 9039aeb6..cda256db 100644 --- a/src/str.cpp +++ b/src/str.cpp @@ -16,6 +16,7 @@ #include "str.hpp" +#include #include #include #include @@ -39,13 +40,19 @@ str::split(const string_view str_, { size_t pos; size_t start; + size_t length; + + assert(result_ != nullptr); + if(str_.empty()) + return; start = 0; pos = str_.find(delimiter_,start); while(pos != std::string_view::npos) { - result_->push_back(std::string{str_.substr(start,pos)}); - start = (pos + 1); + length = (pos - start); + result_->push_back(std::string{str_.substr(start,length)}); + start = pos + 1; pos = str_.find(delimiter_,start); } @@ -59,13 +66,19 @@ str::split(const string_view str_, { size_t pos; size_t start; + size_t length; + + assert(result_ != nullptr); + if(str_.empty()) + return; start = 0; pos = str_.find(delimiter_,start); while(pos != std::string_view::npos) { - result_->insert(std::string{str_.substr(start,pos)}); - start = (pos + 1); + length = (pos - start); + result_->insert(std::string{str_.substr(start,length)}); + start = pos + 1; pos = str_.find(delimiter_,start); } @@ -76,15 +89,29 @@ void str::split_on_null(const std::string_view str_, std::vector *result_) { - const char *start; - const char *end; + return str::split(str_,'\0',result_); +} + +void +str::lsplit1(const string_view &str_, + const char delimiter_, + vector *result_) +{ + std::size_t off; - start = str_.begin(); - end = str_.end(); - while(start < end) + assert(result_ != nullptr); + if(str_.empty()) + return; + + off = str_.find(delimiter_); + if(off == std::string::npos) { - result_->emplace_back(start); - start += (result_->back().size() + 1); + result_->push_back(std::string{str_}); + } + else + { + result_->push_back(std::string{str_.substr(0,off)}); + result_->push_back(std::string{str_.substr(off+1)}); } } @@ -95,7 +122,11 @@ str::rsplit1(const string_view &str_, { std::size_t off; - off = str_.rfind('='); + assert(result_ != nullptr); + if(str_.empty()) + return; + + off = str_.rfind(delimiter_); if(off == std::string::npos) { result_->push_back(std::string{str_}); diff --git a/src/str.hpp b/src/str.hpp index 690f253d..42a4c661 100644 --- a/src/str.hpp +++ b/src/str.hpp @@ -36,6 +36,11 @@ namespace str split_on_null(const std::string_view str, std::vector *result); + void + lsplit1(const std::string_view &str, + const char delimiter, + std::vector *result); + void rsplit1(const std::string_view &str, const char delimiter, diff --git a/tests/tests.cpp b/tests/tests.cpp index 867f4a6d..d0a011a1 100644 --- a/tests/tests.cpp +++ b/tests/tests.cpp @@ -1,6 +1,7 @@ #include "acutest.h" #include "config.hpp" +#include "str.hpp" void test_nop() @@ -74,13 +75,58 @@ test_config_str() TEST_CHECK(v.to_string() == "foo"); } +void +test_str_stuff() +{ + std::vector v; + + v.clear(); + str::split("",':',&v); + TEST_CHECK(v.size() == 0); + + v.clear(); + str::split("a:b:c",':',&v); + TEST_CHECK(v.size() == 3); + TEST_CHECK(v[0] == "a"); + TEST_CHECK(v[1] == "b"); + TEST_CHECK(v[2] == "c"); + + v.clear(); + str::split("a::b:c",':',&v); + TEST_CHECK(v.size() == 4); + TEST_CHECK(v[0] == "a"); + TEST_CHECK(v[1] == ""); + TEST_CHECK(v[2] == "b"); + TEST_CHECK(v[3] == "c"); + + v.clear(); + str::lsplit1("foo=bar=baz",'=',&v); + TEST_CHECK(v.size() == 2); + TEST_CHECK(v[0] == "foo"); + TEST_CHECK(v[1] == "bar=baz"); + + v.clear(); + str::lsplit1("",'=',&v); + TEST_CHECK(v.size() == 0); + + v.clear(); + str::rsplit1("foo=bar=baz",'=',&v); + TEST_CHECK(v.size() == 2); + TEST_CHECK(v[0] == "foo=bar"); + TEST_CHECK(v[1] == "baz"); + + v.clear(); + str::rsplit1("",'=',&v); + TEST_CHECK(v.size() == 0); +} + void test_config_branches() { uint64_t minfreespace; Branches b(minfreespace); - Branches::CPtr bcp0; - Branches::CPtr bcp1; + Branches::Ptr bcp0; + Branches::Ptr bcp1; minfreespace = 1234; TEST_CHECK(b->minfreespace() == 1234); @@ -105,12 +151,12 @@ test_config_branches() TEST_CHECK((*bcp0)[0].path == "/foo/bar"); TEST_CHECK((*bcp0)[0].minfreespace() == 1234); TEST_MSG("minfreespace: expected = %lu; produced = %lu", - 1234, + 1234UL, (*bcp0)[0].minfreespace()); TEST_CHECK((*bcp0)[1].path == "/foo/baz"); TEST_CHECK((*bcp0)[1].minfreespace() == 4321); TEST_MSG("minfreespace: expected = %lu; produced = %lu", - 4321, + 4321UL, (*bcp0)[1].minfreespace()); TEST_CHECK(b.from_string("foo/bar") == 0); @@ -169,7 +215,7 @@ test_config_moveonenospc() TEST_CHECK(m.from_string("mspmfs") == 0); TEST_CHECK(m.to_string() == "mspmfs"); TEST_CHECK(m.from_string("true") == 0); - TEST_CHECK(m.to_string() == "mfs"); + TEST_CHECK(m.to_string() == "pfrd"); TEST_CHECK(m.from_string("blah") == -EINVAL); } @@ -194,15 +240,6 @@ test_config_nfsopenhack() void test_config_readdir() { - ReadDir r; - - TEST_CHECK(r.from_string("linux") == 0); - TEST_CHECK(r.to_string() == "linux"); - TEST_CHECK(r == ReadDir::ENUM::LINUX); - - TEST_CHECK(r.from_string("posix") == 0); - TEST_CHECK(r.to_string() == "posix"); - TEST_CHECK(r == ReadDir::ENUM::POSIX); } void @@ -286,5 +323,6 @@ TEST_LIST = {"config_statfsignore",test_config_statfs_ignore}, {"config_xattr",test_config_xattr}, {"config",test_config}, + {"str",test_str_stuff}, {NULL,NULL} };