Fixed bug in parsing escaped newline (it was being clipped like a regular newline)

This commit is contained in:
Jesse Beder
2012-01-11 17:55:27 -06:00
parent 4e350e5808
commit 8906ae9a0d
2 changed files with 29 additions and 2 deletions

View File

@@ -23,6 +23,7 @@ namespace YAML
bool emptyLine = false, moreIndented = false; bool emptyLine = false, moreIndented = false;
int foldedNewlineCount = 0; int foldedNewlineCount = 0;
bool foldedNewlineStartedMoreIndented = false; bool foldedNewlineStartedMoreIndented = false;
std::size_t lastEscapedChar = std::string::npos;
std::string scalar; std::string scalar;
params.leadingSpaces = false; params.leadingSpaces = false;
@@ -52,6 +53,7 @@ namespace YAML
// eat escape character and get out (but preserve trailing whitespace!) // eat escape character and get out (but preserve trailing whitespace!)
INPUT.get(); INPUT.get();
lastNonWhitespaceChar = scalar.size(); lastNonWhitespaceChar = scalar.size();
lastEscapedChar = scalar.size();
escapedNewline = true; escapedNewline = true;
break; break;
} }
@@ -60,6 +62,7 @@ namespace YAML
if(INPUT.peek() == params.escape) { if(INPUT.peek() == params.escape) {
scalar += Exp::Escape(INPUT); scalar += Exp::Escape(INPUT);
lastNonWhitespaceChar = scalar.size(); lastNonWhitespaceChar = scalar.size();
lastEscapedChar = scalar.size();
continue; continue;
} }
@@ -171,20 +174,32 @@ namespace YAML
// post-processing // post-processing
if(params.trimTrailingSpaces) { if(params.trimTrailingSpaces) {
std::size_t pos = scalar.find_last_not_of(' '); std::size_t pos = scalar.find_last_not_of(' ');
if(lastEscapedChar != std::string::npos) {
if(pos < lastEscapedChar || pos == std::string::npos)
pos = lastEscapedChar;
}
if(pos < scalar.size()) if(pos < scalar.size())
scalar.erase(pos + 1); scalar.erase(pos + 1);
} }
switch(params.chomp) { switch(params.chomp) {
case CLIP: { case CLIP: {
const std::size_t pos = scalar.find_last_not_of('\n'); std::size_t pos = scalar.find_last_not_of('\n');
if(lastEscapedChar != std::string::npos) {
if(pos < lastEscapedChar || pos == std::string::npos)
pos = lastEscapedChar;
}
if(pos == std::string::npos) if(pos == std::string::npos)
scalar.erase(); scalar.erase();
else if(pos + 1 < scalar.size()) else if(pos + 1 < scalar.size())
scalar.erase(pos + 2); scalar.erase(pos + 2);
} break; } break;
case STRIP: { case STRIP: {
const std::size_t pos = scalar.find_last_not_of('\n'); std::size_t pos = scalar.find_last_not_of('\n');
if(lastEscapedChar != std::string::npos) {
if(pos < lastEscapedChar || pos == std::string::npos)
pos = lastEscapedChar;
}
if(pos == std::string::npos) if(pos == std::string::npos)
scalar.erase(); scalar.erase();
else if(pos < scalar.size()) else if(pos < scalar.size())

View File

@@ -892,6 +892,17 @@ namespace Test
return doc.to<int>() == 5; return doc.to<int>() == 5;
} }
bool QuotedNewline()
{
std::string input = "foo: \"\\n\"";
std::stringstream stream(input);
YAML::Parser parser(stream);
YAML::Node doc;
parser.GetNextDocument(doc);
return doc["foo"].to<std::string>() == "\n";
}
} }
namespace { namespace {
@@ -1172,6 +1183,7 @@ namespace Test
RunParserTest(&Parser::NaN, "NaN", passed, total); RunParserTest(&Parser::NaN, "NaN", passed, total);
RunParserTest(&Parser::NonConstKey, "non const key", passed, total); RunParserTest(&Parser::NonConstKey, "non const key", passed, total);
RunParserTest(&Parser::SingleChar, "single char", passed, total); RunParserTest(&Parser::SingleChar, "single char", passed, total);
RunParserTest(&Parser::QuotedNewline, "quoted newline", passed, total);
RunEncodingTest(&EncodeToUtf8, false, "UTF-8, no BOM", passed, total); RunEncodingTest(&EncodeToUtf8, false, "UTF-8, no BOM", passed, total);
RunEncodingTest(&EncodeToUtf8, true, "UTF-8 with BOM", passed, total); RunEncodingTest(&EncodeToUtf8, true, "UTF-8 with BOM", passed, total);