From 4638ff004a15f304271d67859be999e27483f1eb Mon Sep 17 00:00:00 2001 From: doug1234 Date: Mon, 20 Feb 2023 10:18:06 -0500 Subject: [PATCH 1/2] Added new single and double quote tests for escape characters. --- test/lua/literals/_doublequote.lua | 3 +++ test/lua/literals/_singlequote.lua | 3 +++ test/lua/literals/doublequote.lua | 3 +++ test/lua/literals/singlequote.lua | 3 +++ 4 files changed, 12 insertions(+) diff --git a/test/lua/literals/_doublequote.lua b/test/lua/literals/_doublequote.lua index 2290916..f800c84 100644 --- a/test/lua/literals/_doublequote.lua +++ b/test/lua/literals/_doublequote.lua @@ -5,3 +5,6 @@ local bar = '"' local foobar = '\\\\"' local kek = '\\' local topkek = 'a\\' +local nothing = '' +local dir = 'C:\\\'Some Dir\'\\' +local escapedQuote = '\'' diff --git a/test/lua/literals/_singlequote.lua b/test/lua/literals/_singlequote.lua index a101ab6..fbf0027 100644 --- a/test/lua/literals/_singlequote.lua +++ b/test/lua/literals/_singlequote.lua @@ -5,3 +5,6 @@ local foo = "'" local foobar = "\\\\'" local kek = "\\" local topkek = "a\\" +local nothing = "" +local dir = "C:\\\"Some Dir\"\\" +local escapedQuote = "\"" diff --git a/test/lua/literals/doublequote.lua b/test/lua/literals/doublequote.lua index 7644216..497f335 100644 --- a/test/lua/literals/doublequote.lua +++ b/test/lua/literals/doublequote.lua @@ -5,3 +5,6 @@ local bar = "\"" local foobar = "\\\\\"" local kek = "\\" local topkek = "a\\" +local nothing = "" +local dir = "C:\\'Some Dir'\\" +local escapedQuote = "\'" diff --git a/test/lua/literals/singlequote.lua b/test/lua/literals/singlequote.lua index 730e90d..71d9589 100644 --- a/test/lua/literals/singlequote.lua +++ b/test/lua/literals/singlequote.lua @@ -5,3 +5,6 @@ local foo = '\'' local foobar = '\\\\\'' local kek = '\\' local topkek = 'a\\' +local nothing = '' +local dir = 'C:\\"Some Dir"\\' +local escapedQuote = '\"' From d7264fbd4b8abe83cde8e8e9309b0ad513c53637 Mon Sep 17 00:00:00 2001 From: doug1234 Date: Mon, 20 Feb 2023 11:15:37 -0500 Subject: [PATCH 2/2] Fix incorrect escape character handling for issue #274. Added a couple more tests. --- src/visitor/FormatVisitor.cpp | 45 ++++++++++++++++++++---------- test/lua/literals/_doublequote.lua | 2 ++ test/lua/literals/_singlequote.lua | 2 ++ test/lua/literals/doublequote.lua | 2 ++ test/lua/literals/singlequote.lua | 2 ++ 5 files changed, 38 insertions(+), 15 deletions(-) diff --git a/src/visitor/FormatVisitor.cpp b/src/visitor/FormatVisitor.cpp index 044a050..5b8fbf5 100644 --- a/src/visitor/FormatVisitor.cpp +++ b/src/visitor/FormatVisitor.cpp @@ -250,23 +250,38 @@ antlrcpp::Any FormatVisitor::visitString(LuaParser::StringContext* ctx) { assert(0); } - std::string oldstr = ctx->getText(); - std::string newstr; - - std::regex re_single("'", std::regex_constants::extended); - std::regex re_double("\"", std::regex_constants::extended); - std::regex re_escapedsingle("\\\\'", std::regex_constants::extended); - std::regex re_escapeddouble("\\\\\"", std::regex_constants::extended); - - if (quote == '\"') { - regex_replace(std::back_inserter(newstr), oldstr.begin() + 1, oldstr.end() - 1, re_escapedsingle, "'"); - newstr = regex_replace(newstr, re_double, "\\\""); - } else { - regex_replace(std::back_inserter(newstr), oldstr.begin() + 1, oldstr.end() - 1, re_single, "\\'"); - newstr = regex_replace(newstr, re_escapeddouble, "\""); + //Switch the type of quote + std::string newstr = ctx->getText(); + newstr.front() = quote; + newstr.back() = quote; + bool escaped = false; //Is the current character in the sequence escaped + const char oldChar = quote == '\'' ? '"' : '\''; + auto itr = ++newstr.begin(); + auto itrStop = --newstr.end(); + while (itr != itrStop) { + if (*itr == '\\') { + escaped = !escaped; //If the character isn't currently escaped, the next one will be escaped + } else { + if (*itr == quote) { + // Add the escape character before the non escaped old character + if (!escaped) { + itr = newstr.insert(itr, '\\'); + ++itr; // Extra incriment to get back to the previous character + itrStop = --newstr.end(); + } + } else if (*itr == oldChar) { + // Remove the escape before the previously escaped old character + if (escaped) { + itr = newstr.erase(--itr); + itrStop = --newstr.end(); + } + } + escaped = false; + } + ++itr; } - cur_writer() << quote + newstr + quote; + cur_writer() << newstr; return nullptr; } diff --git a/test/lua/literals/_doublequote.lua b/test/lua/literals/_doublequote.lua index f800c84..b7bb590 100644 --- a/test/lua/literals/_doublequote.lua +++ b/test/lua/literals/_doublequote.lua @@ -8,3 +8,5 @@ local topkek = 'a\\' local nothing = '' local dir = 'C:\\\'Some Dir\'\\' local escapedQuote = '\'' +local manyEscape1 = '\\\\\\\\\'' +local manyEscape2 = '\\\\\\\\\'' diff --git a/test/lua/literals/_singlequote.lua b/test/lua/literals/_singlequote.lua index fbf0027..69e04fb 100644 --- a/test/lua/literals/_singlequote.lua +++ b/test/lua/literals/_singlequote.lua @@ -8,3 +8,5 @@ local topkek = "a\\" local nothing = "" local dir = "C:\\\"Some Dir\"\\" local escapedQuote = "\"" +local manyEscape1 = "\\\\\\\\\"" +local manyEscape2 = "\\\\\\\\\"" diff --git a/test/lua/literals/doublequote.lua b/test/lua/literals/doublequote.lua index 497f335..3a8dc8c 100644 --- a/test/lua/literals/doublequote.lua +++ b/test/lua/literals/doublequote.lua @@ -8,3 +8,5 @@ local topkek = "a\\" local nothing = "" local dir = "C:\\'Some Dir'\\" local escapedQuote = "\'" +local manyEscape1 = "\\\\\\\\'" +local manyEscape2 = "\\\\\\\\\'" diff --git a/test/lua/literals/singlequote.lua b/test/lua/literals/singlequote.lua index 71d9589..32115d6 100644 --- a/test/lua/literals/singlequote.lua +++ b/test/lua/literals/singlequote.lua @@ -8,3 +8,5 @@ local topkek = 'a\\' local nothing = '' local dir = 'C:\\"Some Dir"\\' local escapedQuote = '\"' +local manyEscape1 = '\\\\\\\\"' +local manyEscape2 = '\\\\\\\\\"'