From b5db256384f981833f85ad9019be6e212fffcc6b Mon Sep 17 00:00:00 2001 From: Maxime Coste Date: Wed, 24 Jul 2013 22:37:17 +0200 Subject: [PATCH] string escaping support functions the split function now takes an additional escape parameter and does not split on separators that have the escaper before it. An utility escape function that adds escape before separators is also added. --- src/string.cc | 42 +++++++++++++++++++++++++++++++++++------- src/string.hh | 3 ++- src/unit_tests.cc | 8 ++++++-- 3 files changed, 43 insertions(+), 10 deletions(-) diff --git a/src/string.cc b/src/string.cc index 2c6bb140..dcfc1037 100644 --- a/src/string.cc +++ b/src/string.cc @@ -5,7 +5,7 @@ namespace Kakoune { -std::vector split(const String& str, char separator) +std::vector split(const String& str, char separator, char escape) { auto begin = str.begin(); auto end = str.begin(); @@ -13,12 +13,40 @@ std::vector split(const String& str, char separator) std::vector res; while (end != str.end()) { - while (end != str.end() and *end != separator) - ++end; - res.push_back(String(begin, end)); - if (end == str.end()) - break; - begin = ++end; + res.emplace_back(); + String& element = res.back(); + while (end != str.end()) + { + auto c = *end; + if (c == escape and end + 1 != end and *(end+1) == separator) + { + element += separator; + end += 2; + } + else if (c == separator) + { + ++end; + break; + } + else + { + element += c; + ++end; + } + } + begin = end; + } + return res; +} + +String escape(const String& str, char character, char escape) +{ + String res; + for (auto& c : str) + { + if (c == character) + res += escape; + res += c; } return res; } diff --git a/src/string.hh b/src/string.hh index a64bf180..f4a93309 100644 --- a/src/string.hh +++ b/src/string.hh @@ -84,7 +84,8 @@ inline String operator+(Codepoint lhs, const String& rhs) return String(lhs) + rhs; } -std::vector split(const String& str, char separator); +std::vector split(const String& str, char separator, char escape = 0); +String escape(const String& str, char character, char escape); inline String operator"" _str(const char* str, size_t) { diff --git a/src/unit_tests.cc b/src/unit_tests.cc index e0537123..5058bb91 100644 --- a/src/unit_tests.cc +++ b/src/unit_tests.cc @@ -120,11 +120,15 @@ void test_string() { kak_assert(String("youpi ") + "matin" == "youpi matin"); - std::vector splited = split("youpi:matin::tchou", ':'); + std::vector splited = split("youpi:matin::tchou\\:kanaky:hihi\\:", ':', '\\'); kak_assert(splited[0] == "youpi"); kak_assert(splited[1] == "matin"); kak_assert(splited[2] == ""); - kak_assert(splited[3] == "tchou"); + kak_assert(splited[3] == "tchou:kanaky"); + kak_assert(splited[4] == "hihi:"); + + String escaped = escape("youpi:matin:tchou:", ':', '\\'); + kak_assert(escaped == "youpi\\:matin\\:tchou\\:"); } void test_keys()