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.
This commit is contained in:
Maxime Coste 2014-10-19 16:27:36 +01:00
parent 2e0b4d02b7
commit 69113e2711
5 changed files with 32 additions and 4 deletions

View File

@ -691,7 +691,7 @@ void define_command(const ParametersParser& parser, Context& context)
{ "pos_in_token", to_string(pos_in_token) } { "pos_in_token", to_string(pos_in_token) }
}; };
String output = ShellManager::instance().eval(shell_cmd, context, params, vars); 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) };
}; };
} }

View File

@ -350,7 +350,7 @@ std::vector<String> complete_command(StringView prefix, ByteCount cursor_pos)
}; };
static std::unordered_map<String, CommandCache> command_cache; static std::unordered_map<String, CommandCache> command_cache;
std::vector<String> path; std::vector<StringView> path;
if (dir_end != -1) if (dir_end != -1)
{ {
path.emplace_back(real_prefix.substr(0, dir_end + 1)); path.emplace_back(real_prefix.substr(0, dir_end + 1));
@ -360,8 +360,9 @@ std::vector<String> complete_command(StringView prefix, ByteCount cursor_pos)
path = split(getenv("PATH"), ':'); path = split(getenv("PATH"), ':');
std::vector<String> res; std::vector<String> res;
for (auto dirname : path) for (auto dir : path)
{ {
String dirname = dir;
if (not dirname.empty() and dirname.back() != '/') if (not dirname.empty() and dirname.back() != '/')
dirname += '/'; dirname += '/';

View File

@ -46,6 +46,22 @@ std::vector<String> split(StringView str, char separator, char escape)
return res; return res;
} }
std::vector<StringView> split(StringView str, char separator)
{
std::vector<StringView> 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 escape(StringView str, char character, char escape)
{ {
String res; String res;

View File

@ -271,7 +271,9 @@ inline String operator+(StringView lhs, StringView rhs)
return res; return res;
} }
std::vector<String> split(StringView str, char separator, char escape = 0); std::vector<String> split(StringView str, char separator, char escape);
std::vector<StringView> split(StringView str, char separator);
String escape(StringView str, char character, char escape); String escape(StringView str, char character, char escape);
String escape(StringView str, StringView characters, char escape); String escape(StringView str, StringView characters, char escape);

View File

@ -113,6 +113,15 @@ void test_string()
kak_assert(splited[3] == "tchou:kanaky"); kak_assert(splited[3] == "tchou:kanaky");
kak_assert(splited[4] == "hihi:"); kak_assert(splited[4] == "hihi:");
std::vector<StringView> 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:", ':', '\\'); String escaped = escape("youpi:matin:tchou:", ':', '\\');
kak_assert(escaped == "youpi\\:matin\\:tchou\\:"); kak_assert(escaped == "youpi\\:matin\\:tchou\\:");