From 09439b7bc79eced6eb072695a9a34fe3abd3b231 Mon Sep 17 00:00:00 2001 From: Christopher Dunn Date: Sat, 19 Apr 2014 21:19:24 +0000 Subject: [PATCH] Comment reading/write improvements This patch fixes some aspects of reading and writing comments: - Multiple C++-style comments before a Json value had extra newlines appended to them. This patch removes the addition of those newlines. - Comments written before Json values in the StyledWriter were not indented to match the indentation level of the value. This patch adds indentation to comments. - Fixed inconsistency in newlines following C- and C++-style comments being saved as part of the comment. All newlines at the end of a comment are now removed. - Added an additional test of comments. https://sourceforge.net/p/jsoncpp/patches/25/ --- src/lib_json/json_reader.cpp | 11 +++++++++++ src/lib_json/json_writer.cpp | 15 ++++++++++++++- test/data/test_comment_02.expected | 7 +++++++ test/data/test_comment_02.json | 16 ++++++++++++++++ 4 files changed, 48 insertions(+), 1 deletion(-) create mode 100644 test/data/test_comment_02.expected create mode 100644 test/data/test_comment_02.json diff --git a/src/lib_json/json_reader.cpp b/src/lib_json/json_reader.cpp index 0acbcd0..b9165a4 100644 --- a/src/lib_json/json_reader.cpp +++ b/src/lib_json/json_reader.cpp @@ -191,6 +191,17 @@ Reader::readValue() 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(); + } + currentValue().setComment( commentsBefore_, commentBefore ); commentsBefore_ = ""; } diff --git a/src/lib_json/json_writer.cpp b/src/lib_json/json_writer.cpp index dfbaa52..242bc57 100644 --- a/src/lib_json/json_writer.cpp +++ b/src/lib_json/json_writer.cpp @@ -483,7 +483,20 @@ StyledWriter::writeCommentBeforeValue( const Value &root ) { if ( !root.hasComment( commentBefore ) ) return; - document_ += normalizeEOL( root.getComment( commentBefore ) ); + + document_ += "\n"; + writeIndent(); + std::string normalizedComment = normalizeEOL( root.getComment( commentBefore ) ); + std::string::const_iterator iter = normalizedComment.begin(); + while ( iter != normalizedComment.end() ) + { + document_ += *iter; + if ( *iter == '\n' && *(iter+1) == '/' ) + writeIndent(); + ++iter; + } + + // Comments are stripped of newlines, so add one here document_ += "\n"; } diff --git a/test/data/test_comment_02.expected b/test/data/test_comment_02.expected new file mode 100644 index 0000000..09c745d --- /dev/null +++ b/test/data/test_comment_02.expected @@ -0,0 +1,7 @@ +.={} +.c-test={} +.c-test.a=1 +.c-test.b=2 +.cpp-test={} +.cpp-test.c=3 +.cpp-test.d=4 diff --git a/test/data/test_comment_02.json b/test/data/test_comment_02.json new file mode 100644 index 0000000..ccf631f --- /dev/null +++ b/test/data/test_comment_02.json @@ -0,0 +1,16 @@ +{ + /* C-style comment + + C-style-2 comment */ + "c-test" : { + "a" : 1, + /* Internal comment c-style */ + "b" : 2 + }, + // C++-style comment + "cpp-test" : { + // Internal comment cpp-style + "c" : 3, + "d" : 4 + } +}