Skip to content

Commit d7264fb

Browse files
committed
Fix incorrect escape character handling for issue #274. Added a couple more tests.
1 parent 4638ff0 commit d7264fb

File tree

5 files changed

+38
-15
lines changed

5 files changed

+38
-15
lines changed

src/visitor/FormatVisitor.cpp

Lines changed: 30 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -250,23 +250,38 @@ antlrcpp::Any FormatVisitor::visitString(LuaParser::StringContext* ctx) {
250250
assert(0);
251251
}
252252

253-
std::string oldstr = ctx->getText();
254-
std::string newstr;
255-
256-
std::regex re_single("'", std::regex_constants::extended);
257-
std::regex re_double("\"", std::regex_constants::extended);
258-
std::regex re_escapedsingle("\\\\'", std::regex_constants::extended);
259-
std::regex re_escapeddouble("\\\\\"", std::regex_constants::extended);
260-
261-
if (quote == '\"') {
262-
regex_replace(std::back_inserter(newstr), oldstr.begin() + 1, oldstr.end() - 1, re_escapedsingle, "'");
263-
newstr = regex_replace(newstr, re_double, "\\\"");
264-
} else {
265-
regex_replace(std::back_inserter(newstr), oldstr.begin() + 1, oldstr.end() - 1, re_single, "\\'");
266-
newstr = regex_replace(newstr, re_escapeddouble, "\"");
253+
//Switch the type of quote
254+
std::string newstr = ctx->getText();
255+
newstr.front() = quote;
256+
newstr.back() = quote;
257+
bool escaped = false; //Is the current character in the sequence escaped
258+
const char oldChar = quote == '\'' ? '"' : '\'';
259+
auto itr = ++newstr.begin();
260+
auto itrStop = --newstr.end();
261+
while (itr != itrStop) {
262+
if (*itr == '\\') {
263+
escaped = !escaped; //If the character isn't currently escaped, the next one will be escaped
264+
} else {
265+
if (*itr == quote) {
266+
// Add the escape character before the non escaped old character
267+
if (!escaped) {
268+
itr = newstr.insert(itr, '\\');
269+
++itr; // Extra incriment to get back to the previous character
270+
itrStop = --newstr.end();
271+
}
272+
} else if (*itr == oldChar) {
273+
// Remove the escape before the previously escaped old character
274+
if (escaped) {
275+
itr = newstr.erase(--itr);
276+
itrStop = --newstr.end();
277+
}
278+
}
279+
escaped = false;
280+
}
281+
++itr;
267282
}
268283

269-
cur_writer() << quote + newstr + quote;
284+
cur_writer() << newstr;
270285
return nullptr;
271286
}
272287

test/lua/literals/_doublequote.lua

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,3 +8,5 @@ local topkek = 'a\\'
88
local nothing = ''
99
local dir = 'C:\\\'Some Dir\'\\'
1010
local escapedQuote = '\''
11+
local manyEscape1 = '\\\\\\\\\''
12+
local manyEscape2 = '\\\\\\\\\''

test/lua/literals/_singlequote.lua

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,3 +8,5 @@ local topkek = "a\\"
88
local nothing = ""
99
local dir = "C:\\\"Some Dir\"\\"
1010
local escapedQuote = "\""
11+
local manyEscape1 = "\\\\\\\\\""
12+
local manyEscape2 = "\\\\\\\\\""

test/lua/literals/doublequote.lua

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,3 +8,5 @@ local topkek = "a\\"
88
local nothing = ""
99
local dir = "C:\\'Some Dir'\\"
1010
local escapedQuote = "\'"
11+
local manyEscape1 = "\\\\\\\\'"
12+
local manyEscape2 = "\\\\\\\\\'"

test/lua/literals/singlequote.lua

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,3 +8,5 @@ local topkek = 'a\\'
88
local nothing = ''
99
local dir = 'C:\\"Some Dir"\\'
1010
local escapedQuote = '\"'
11+
local manyEscape1 = '\\\\\\\\"'
12+
local manyEscape2 = '\\\\\\\\\"'

0 commit comments

Comments
 (0)