varlist: cleanup unintuitive string splitting (#3369)

* refactor(varlist): replace unintuitive string splitting

* refactor(varlist): remove test asserts
This commit is contained in:
memchr 2023-09-19 08:44:54 +00:00 committed by GitHub
parent 60f10e6037
commit c50072b108
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 25 additions and 31 deletions

View file

@ -1,36 +1,26 @@
#include "VarList.hpp" #include "VarList.hpp"
#include <ranges>
#include <algorithm>
CVarList::CVarList(const std::string& in, long unsigned int lastArgNo, const char separator) { CVarList::CVarList(const std::string& in, const size_t lastArgNo, const char delim, const bool removeEmpty) {
std::string curitem = ""; if (in.empty())
std::string argZ = in; m_vArgs.emplace_back("");
const bool SPACESEP = separator == 's';
auto nextItem = [&]() { std::string args{in};
auto idx = lastArgNo != 0 && m_vArgs.size() >= lastArgNo - 1 ? std::string::npos : ([&]() -> size_t { size_t idx = 0;
if (!SPACESEP) size_t pos = 0;
return argZ.find_first_of(separator); std::ranges::replace_if(
args, [&](const char& c) { return delim == 's' ? std::isspace(c) : c == delim; }, 0);
uint64_t pos = -1; for (const auto& s : args | std::views::split(0)) {
while (!std::isspace(argZ[++pos]) && pos < argZ.length()) if (removeEmpty && s.empty())
; continue;
if (++idx == lastArgNo) {
return pos < argZ.length() ? pos : std::string::npos; m_vArgs.emplace_back(removeBeginEndSpacesTabs(in.substr(pos)));
}()); break;
if (idx != std::string::npos) {
curitem = argZ.substr(0, idx);
argZ = argZ.substr(idx + 1);
} else {
curitem = argZ;
argZ = STRVAL_EMPTY;
} }
}; pos += s.size() + 1;
m_vArgs.emplace_back(removeBeginEndSpacesTabs(std::string_view{s}.data()));
nextItem();
while (curitem != STRVAL_EMPTY) {
m_vArgs.push_back(removeBeginEndSpacesTabs(curitem));
nextItem();
} }
} }

View file

@ -5,8 +5,12 @@
class CVarList { class CVarList {
public: public:
/* passing 's' as a separator will use std::isspace */ /** Split string into arg list
CVarList(const std::string& in, long unsigned int lastArgNo = 0, const char separator = ','); @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; ~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 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()) if (idx >= m_vArgs.size())
return ""; return "";
return m_vArgs[idx]; return m_vArgs[idx];