12
12
#endif // if !defined(JSON_IS_AMALGAMATION)
13
13
#include < cassert>
14
14
#include < cstring>
15
+ #include < iostream>
15
16
#include < istream>
16
17
#include < limits>
17
18
#include < memory>
@@ -942,7 +943,7 @@ class OurReader {
942
943
void skipSpaces ();
943
944
bool match (const Char* pattern, int patternLength);
944
945
bool readComment ();
945
- bool readCStyleComment ();
946
+ bool readCStyleComment (bool * containsNewLineResult );
946
947
bool readCppStyleComment ();
947
948
bool readString ();
948
949
bool readStringSingleQuote ();
@@ -977,18 +978,20 @@ class OurReader {
977
978
static bool containsNewLine (Location begin, Location end);
978
979
979
980
using Nodes = std::stack<Value*>;
980
- Nodes nodes_;
981
- Errors errors_;
982
- String document_;
983
- Location begin_;
984
- Location end_;
985
- Location current_;
986
- Location lastValueEnd_;
987
- Value* lastValue_;
988
- String commentsBefore_;
981
+
982
+ Nodes nodes_{};
983
+ Errors errors_{};
984
+ String document_{};
985
+ Location begin_ = nullptr ;
986
+ Location end_ = nullptr ;
987
+ Location current_ = nullptr ;
988
+ Location lastValueEnd_ = nullptr ;
989
+ Value* lastValue_ = nullptr ;
990
+ bool lastValueHasAComment_ = false ;
991
+ String commentsBefore_{};
989
992
990
993
OurFeatures const features_;
991
- bool collectComments_;
994
+ bool collectComments_ = false ;
992
995
}; // OurReader
993
996
994
997
// complete copy of Read impl, for OurReader
@@ -1001,9 +1004,7 @@ bool OurReader::containsNewLine(OurReader::Location begin,
1001
1004
return false ;
1002
1005
}
1003
1006
1004
- OurReader::OurReader (OurFeatures const & features)
1005
- : begin_(), end_(), current_(), lastValueEnd_(), lastValue_(),
1006
- features_ (features), collectComments_() {}
1007
+ OurReader::OurReader (OurFeatures const & features) : features_(features) {}
1007
1008
1008
1009
bool OurReader::parse (const char * beginDoc, const char * endDoc, Value& root,
1009
1010
bool collectComments) {
@@ -1134,6 +1135,7 @@ bool OurReader::readValue() {
1134
1135
1135
1136
if (collectComments_) {
1136
1137
lastValueEnd_ = current_;
1138
+ lastValueHasAComment_ = false ;
1137
1139
lastValue_ = ¤tValue ();
1138
1140
}
1139
1141
@@ -1280,21 +1282,32 @@ bool OurReader::match(const Char* pattern, int patternLength) {
1280
1282
}
1281
1283
1282
1284
bool OurReader::readComment () {
1283
- Location commentBegin = current_ - 1 ;
1284
- Char c = getNextChar ();
1285
+ const Location commentBegin = current_ - 1 ;
1286
+ const Char c = getNextChar ();
1285
1287
bool successful = false ;
1286
- if (c == ' *' )
1287
- successful = readCStyleComment ();
1288
- else if (c == ' /' )
1288
+ bool cStyleWithEmbeddedNewline = false ;
1289
+
1290
+ const bool isCStyleComment = (c == ' *' );
1291
+ const bool isCppStyleComment = (c == ' /' );
1292
+ if (isCStyleComment) {
1293
+ successful = readCStyleComment (&cStyleWithEmbeddedNewline);
1294
+ } else if (isCppStyleComment) {
1289
1295
successful = readCppStyleComment ();
1296
+ }
1297
+
1290
1298
if (!successful)
1291
1299
return false ;
1292
1300
1293
1301
if (collectComments_) {
1294
1302
CommentPlacement placement = commentBefore;
1295
- if (lastValueEnd_ && !containsNewLine (lastValueEnd_, commentBegin)) {
1296
- if (c != ' *' || !containsNewLine (commentBegin, current_))
1297
- placement = commentAfterOnSameLine;
1303
+
1304
+ if (!lastValueHasAComment_) {
1305
+ if (lastValueEnd_ && !containsNewLine (lastValueEnd_, commentBegin)) {
1306
+ if (isCppStyleComment || !cStyleWithEmbeddedNewline) {
1307
+ placement = commentAfterOnSameLine;
1308
+ lastValueHasAComment_ = true ;
1309
+ }
1310
+ }
1298
1311
}
1299
1312
1300
1313
addComment (commentBegin, current_, placement);
@@ -1334,12 +1347,18 @@ void OurReader::addComment(Location begin, Location end,
1334
1347
}
1335
1348
}
1336
1349
1337
- bool OurReader::readCStyleComment () {
1350
+ bool OurReader::readCStyleComment (bool * containsNewLineResult) {
1351
+ *containsNewLineResult = false ;
1352
+
1338
1353
while ((current_ + 1 ) < end_) {
1339
1354
Char c = getNextChar ();
1340
- if (c == ' *' && *current_ == ' /' )
1355
+ if (c == ' *' && *current_ == ' /' ) {
1341
1356
break ;
1357
+ } else if (c == ' \n ' ) {
1358
+ *containsNewLineResult = true ;
1359
+ }
1342
1360
}
1361
+
1343
1362
return getNextChar () == ' /' ;
1344
1363
}
1345
1364
0 commit comments