From c50072b108198a5c278c16967b700c713b0140a8 Mon Sep 17 00:00:00 2001 From: memchr <118117622+memchr@users.noreply.github.com> Date: Tue, 19 Sep 2023 08:44:54 +0000 Subject: [PATCH] varlist: cleanup unintuitive string splitting (#3369) * refactor(varlist): replace unintuitive string splitting * refactor(varlist): remove test asserts --- src/helpers/VarList.cpp | 46 ++++++++++++++++------------------------- src/helpers/VarList.hpp | 10 ++++++--- 2 files changed, 25 insertions(+), 31 deletions(-) diff --git a/src/helpers/VarList.cpp b/src/helpers/VarList.cpp index 0da86e15..c29a1e96 100644 --- a/src/helpers/VarList.cpp +++ b/src/helpers/VarList.cpp @@ -1,36 +1,26 @@ #include "VarList.hpp" +#include +#include -CVarList::CVarList(const std::string& in, long unsigned int lastArgNo, const char separator) { - std::string curitem = ""; - std::string argZ = in; - const bool SPACESEP = separator == 's'; +CVarList::CVarList(const std::string& in, const size_t lastArgNo, const char delim, const bool removeEmpty) { + if (in.empty()) + m_vArgs.emplace_back(""); - auto nextItem = [&]() { - auto idx = lastArgNo != 0 && m_vArgs.size() >= lastArgNo - 1 ? std::string::npos : ([&]() -> size_t { - if (!SPACESEP) - return argZ.find_first_of(separator); + std::string args{in}; + size_t idx = 0; + size_t pos = 0; + std::ranges::replace_if( + args, [&](const char& c) { return delim == 's' ? std::isspace(c) : c == delim; }, 0); - uint64_t pos = -1; - while (!std::isspace(argZ[++pos]) && pos < argZ.length()) - ; - - return pos < argZ.length() ? pos : std::string::npos; - }()); - - if (idx != std::string::npos) { - curitem = argZ.substr(0, idx); - argZ = argZ.substr(idx + 1); - } else { - curitem = argZ; - argZ = STRVAL_EMPTY; + for (const auto& s : args | std::views::split(0)) { + if (removeEmpty && s.empty()) + continue; + if (++idx == lastArgNo) { + m_vArgs.emplace_back(removeBeginEndSpacesTabs(in.substr(pos))); + break; } - }; - - nextItem(); - - while (curitem != STRVAL_EMPTY) { - m_vArgs.push_back(removeBeginEndSpacesTabs(curitem)); - nextItem(); + pos += s.size() + 1; + m_vArgs.emplace_back(removeBeginEndSpacesTabs(std::string_view{s}.data())); } } diff --git a/src/helpers/VarList.hpp b/src/helpers/VarList.hpp index 0c83a3db..60e9a551 100644 --- a/src/helpers/VarList.hpp +++ b/src/helpers/VarList.hpp @@ -5,8 +5,12 @@ class CVarList { public: - /* passing 's' as a separator will use std::isspace */ - CVarList(const std::string& in, long unsigned int lastArgNo = 0, const char separator = ','); + /** Split string into arg list + @param lastArgNo stop splitting after argv reaches maximum size, last arg will contain rest of unsplit args + @param delim if delimiter is 's', use std::isspace + @param removeEmpty remove empty args from argv + */ + CVarList(const std::string& in, const size_t maxSize = 0, const char delim = ',', const bool removeEmpty = false); ~CVarList() = default; @@ -16,7 +20,7 @@ class CVarList { std::string join(const std::string& joiner, size_t from = 0, size_t to = 0) const; - std::string operator[](const long unsigned int& idx) const { + std::string operator[](const size_t& idx) const { if (idx >= m_vArgs.size()) return ""; return m_vArgs[idx];