summaryrefslogtreecommitdiff
path: root/src/command_manager.cc
diff options
context:
space:
mode:
authorMaxime Coste <mawww@kakoune.org>2021-11-25 12:23:21 +1100
committerMaxime Coste <mawww@kakoune.org>2021-11-25 13:23:56 +1100
commit28ac8adbfce32dc1c7de20de8bf7a2075ae3d4ef (patch)
treed37dccf8b62686cff14f11e6f71b998ec0bd808b /src/command_manager.cc
parent16493a99bbd5c373a26e74752f204c901d286905 (diff)
Templatize parse_quoted to avoid utf8 decoding with ascii delimiter
Diffstat (limited to 'src/command_manager.cc')
-rw-r--r--src/command_manager.cc20
1 files changed, 15 insertions, 5 deletions
diff --git a/src/command_manager.cc b/src/command_manager.cc
index a8212d06..5663b1e3 100644
--- a/src/command_manager.cc
+++ b/src/command_manager.cc
@@ -90,7 +90,7 @@ struct parse_error : runtime_error
namespace
{
-bool is_command_separator(Codepoint c)
+bool is_command_separator(char c)
{
return c == ';' or c == '\n';
}
@@ -101,8 +101,17 @@ struct ParseResult
bool terminated;
};
-ParseResult parse_quoted(ParseState& state, Codepoint delimiter)
+template<typename Delimiter>
+ParseResult parse_quoted(ParseState& state, Delimiter delimiter)
{
+ static_assert(std::is_same_v<Delimiter, char> or std::is_same_v<Delimiter, Codepoint>);
+ auto read = [](const char*& it, const char* end) {
+ if constexpr (std::is_same_v<Delimiter, Codepoint>)
+ return utf8::read_codepoint(it, end);
+ else
+ return *it++;
+ };
+
const char* beg = state.pos;
const char* end = state.str.end();
String str;
@@ -110,11 +119,11 @@ ParseResult parse_quoted(ParseState& state, Codepoint delimiter)
while (state.pos != end)
{
const char* cur = state.pos;
- const Codepoint c = utf8::read_codepoint(state.pos, end);
+ const auto c = read(state.pos, end);
if (c == delimiter)
{
auto next = state.pos;
- if (utf8::read_codepoint(next, end) != delimiter)
+ if (read(next, end) != delimiter)
{
if (str.empty())
return {String{String::NoCopy{}, {beg, cur}}, true};
@@ -283,7 +292,8 @@ Token parse_percent_token(ParseState& state, bool throw_on_unterminated)
}
else
{
- auto quoted = parse_quoted(state, opening_delimiter);
+ const bool is_ascii = opening_delimiter < 128;
+ auto quoted = is_ascii ? parse_quoted(state, (char)opening_delimiter) : parse_quoted(state, opening_delimiter);
if (throw_on_unterminated and not quoted.terminated)
{