mirror of
https://github.com/open-source-parsers/jsoncpp.git
synced 2025-10-15 23:20:05 +02:00
Normalize comment EOLs while reading instead of while writing
Tests are currently failing when git cloning on Windows with autocrlf = true. In that setup multiline comments contain \r\n EOLs. The test code assumes that comments contain \n EOLs and opens the .actual files (etc.) with "wt" which converts \n to \r\n. Thus we end up with \r\r\n EOLs in the output, which triggers a test failure. Instead we should cannonicalize comments while reading so that they contain only \n EOLs. This approach simplifies other parts of the reader and writer logic, and requires no changes to the test. It is a breaking change, but probably the Right Thing going forward. This change also fixes dereferencing past the end of the comment string in StyledWriter::writeCommentBeforeValue. Tests should be added with appropriate .gitattributes for the input files to ensure that we run tests for DOS, Mac, and Unix EOL files on all platforms. For now this change is enough to unblock Windows builds. issue #116
This commit is contained in:

committed by
Christopher Dunn

parent
ec727e2f6b
commit
e39fb0083c
@@ -135,14 +135,9 @@ bool Reader::readValue() {
|
||||
bool successful = true;
|
||||
|
||||
if (collectComments_ && !commentsBefore_.empty()) {
|
||||
// Remove newline characters at the end of the comments
|
||||
size_t lastNonNewline = commentsBefore_.find_last_not_of("\r\n");
|
||||
if (lastNonNewline != std::string::npos) {
|
||||
commentsBefore_.erase(lastNonNewline + 1);
|
||||
} else {
|
||||
commentsBefore_.clear();
|
||||
}
|
||||
|
||||
// Remove newline at the end of the comment
|
||||
if (commentsBefore_[commentsBefore_.size() - 1] == '\n')
|
||||
commentsBefore_.resize(commentsBefore_.size() - 1);
|
||||
currentValue().setComment(commentsBefore_, commentBefore);
|
||||
commentsBefore_ = "";
|
||||
}
|
||||
@@ -337,14 +332,34 @@ bool Reader::readComment() {
|
||||
return true;
|
||||
}
|
||||
|
||||
static std::string normalizeEOL(Reader::Location begin, Reader::Location end) {
|
||||
std::string normalized;
|
||||
normalized.reserve(end - begin);
|
||||
Reader::Location current = begin;
|
||||
while (current != end) {
|
||||
char c = *current++;
|
||||
if (c == '\r') {
|
||||
if (current != end && *current == '\n')
|
||||
// convert dos EOL
|
||||
++current;
|
||||
// convert Mac EOL
|
||||
normalized += '\n';
|
||||
} else {
|
||||
normalized += c;
|
||||
}
|
||||
}
|
||||
return normalized;
|
||||
}
|
||||
|
||||
void
|
||||
Reader::addComment(Location begin, Location end, CommentPlacement placement) {
|
||||
assert(collectComments_);
|
||||
const std::string& normalized = normalizeEOL(begin, end);
|
||||
if (placement == commentAfterOnSameLine) {
|
||||
assert(lastValue_ != 0);
|
||||
lastValue_->setComment(std::string(begin, end), placement);
|
||||
lastValue_->setComment(normalized, placement);
|
||||
} else {
|
||||
commentsBefore_ += std::string(begin, end);
|
||||
commentsBefore_ += normalized;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -360,8 +375,15 @@ bool Reader::readCStyleComment() {
|
||||
bool Reader::readCppStyleComment() {
|
||||
while (current_ != end_) {
|
||||
Char c = getNextChar();
|
||||
if (c == '\r' || c == '\n')
|
||||
if (c == '\n')
|
||||
break;
|
||||
if (c == '\r') {
|
||||
// Consume DOS EOL. It will be normalized in addComment.
|
||||
if (current_ != end_ && *current_ == '\n')
|
||||
getNextChar();
|
||||
// Break on Moc OS 9 EOL.
|
||||
break;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
Reference in New Issue
Block a user