From 69113e2711e59da42df5658ab18c7d1847d6db12 Mon Sep 17 00:00:00 2001 From: Maxime Coste Date: Sun, 19 Oct 2014 16:27:36 +0100 Subject: [PATCH] Add a split function that does not take an escape and returns StringViews When an escape character is not present, split can just return sub strings of the parameter, so we can avoid duplicating the original string data. --- src/commands.cc | 2 +- src/file.cc | 5 +++-- src/string.cc | 16 ++++++++++++++++ src/string.hh | 4 +++- src/unit_tests.cc | 9 +++++++++ 5 files changed, 32 insertions(+), 4 deletions(-) diff --git a/src/commands.cc b/src/commands.cc index 1f8a72c5..cdab704f 100644 --- a/src/commands.cc +++ b/src/commands.cc @@ -691,7 +691,7 @@ void define_command(const ParametersParser& parser, Context& context) { "pos_in_token", to_string(pos_in_token) } }; String output = ShellManager::instance().eval(shell_cmd, context, params, vars); - return Completions{ 0_byte, params[token_to_complete].length(), split(output, '\n') }; + return Completions{ 0_byte, params[token_to_complete].length(), split(output, '\n', 0) }; }; } diff --git a/src/file.cc b/src/file.cc index 11159805..3f6b71aa 100644 --- a/src/file.cc +++ b/src/file.cc @@ -350,7 +350,7 @@ std::vector complete_command(StringView prefix, ByteCount cursor_pos) }; static std::unordered_map command_cache; - std::vector path; + std::vector path; if (dir_end != -1) { path.emplace_back(real_prefix.substr(0, dir_end + 1)); @@ -360,8 +360,9 @@ std::vector complete_command(StringView prefix, ByteCount cursor_pos) path = split(getenv("PATH"), ':'); std::vector res; - for (auto dirname : path) + for (auto dir : path) { + String dirname = dir; if (not dirname.empty() and dirname.back() != '/') dirname += '/'; diff --git a/src/string.cc b/src/string.cc index f31ed83f..79da055b 100644 --- a/src/string.cc +++ b/src/string.cc @@ -46,6 +46,22 @@ std::vector split(StringView str, char separator, char escape) return res; } +std::vector split(StringView str, char separator) +{ + std::vector res; + auto beg = str.begin(); + for (auto it = beg; it != str.end(); ++it) + { + if (*it == separator) + { + res.emplace_back(beg, it); + beg = it + 1; + } + } + res.emplace_back(beg, str.end()); + return res; +} + String escape(StringView str, char character, char escape) { String res; diff --git a/src/string.hh b/src/string.hh index e31a3173..afb3f64e 100644 --- a/src/string.hh +++ b/src/string.hh @@ -271,7 +271,9 @@ inline String operator+(StringView lhs, StringView rhs) return res; } -std::vector split(StringView str, char separator, char escape = 0); +std::vector split(StringView str, char separator, char escape); +std::vector split(StringView str, char separator); + String escape(StringView str, char character, char escape); String escape(StringView str, StringView characters, char escape); diff --git a/src/unit_tests.cc b/src/unit_tests.cc index 82dd3ca2..a74326fc 100644 --- a/src/unit_tests.cc +++ b/src/unit_tests.cc @@ -113,6 +113,15 @@ void test_string() kak_assert(splited[3] == "tchou:kanaky"); kak_assert(splited[4] == "hihi:"); + std::vector splitedview = split("youpi:matin::tchou\\:kanaky:hihi\\:", ':'); + kak_assert(splitedview[0] == "youpi"); + kak_assert(splitedview[1] == "matin"); + kak_assert(splitedview[2] == ""); + kak_assert(splitedview[3] == "tchou\\"); + kak_assert(splitedview[4] == "kanaky"); + kak_assert(splitedview[5] == "hihi\\"); + kak_assert(splitedview[6] == ""); + String escaped = escape("youpi:matin:tchou:", ':', '\\'); kak_assert(escaped == "youpi\\:matin\\:tchou\\:");