21
21
22
22
#include " csparser.hh" // for KeyEventDigger
23
23
24
+ #include < set>
25
+
24
26
#include < boost/foreach.hpp>
25
27
#include < boost/property_tree/json_parser.hpp>
26
28
@@ -44,10 +46,25 @@ class AbstractTreeDecoder {
44
46
// / tree decoder of the native JSON format of csdiff
45
47
class SimpleTreeDecoder : public AbstractTreeDecoder {
46
48
public:
49
+ SimpleTreeDecoder (const std::string &fileName, bool silent);
47
50
virtual void readNode (Defect *def, const pt::ptree &node);
48
51
49
52
private:
50
- KeyEventDigger keDigger;
53
+ enum ENodeKind {
54
+ NK_DEFECT,
55
+ NK_EVENT,
56
+ NK_LAST
57
+ };
58
+
59
+ void reportUnknownNodes (ENodeKind, const pt::ptree &) const ;
60
+
61
+ typedef std::set<std::string> TNodeSet;
62
+ typedef std::vector<TNodeSet> TNodeStore;
63
+
64
+ const std::string fileName_;
65
+ const bool silent_;
66
+ TNodeStore nodeStore_;
67
+ KeyEventDigger keDigger_;
51
68
};
52
69
53
70
// / tree decoder of the Coverity JSON format
@@ -145,7 +162,7 @@ JsonParser::JsonParser(
145
162
146
163
if (findChildOf (&d->defList , d->root , " defects" ))
147
164
// csdiff-native JSON format
148
- d->decoder = new SimpleTreeDecoder;
165
+ d->decoder = new SimpleTreeDecoder (fileName, silent) ;
149
166
else if (findChildOf (&d->defList , d->root , " issues" ))
150
167
// Coverity JSON format
151
168
d->decoder = new CovTreeDecoder;
@@ -214,13 +231,66 @@ bool JsonParser::getNext(Defect *def) {
214
231
}
215
232
}
216
233
234
+ SimpleTreeDecoder::SimpleTreeDecoder (const std::string &fileName, bool silent):
235
+ fileName_(fileName),
236
+ silent_(silent)
237
+ {
238
+ if (silent_)
239
+ // skip initialization of nodeStore_ because no lookup will ever happen
240
+ return ;
241
+
242
+ nodeStore_.resize (NK_LAST);
243
+
244
+ // known per-defect subnodes
245
+ nodeStore_[NK_DEFECT] = {
246
+ " annotation" ,
247
+ " checker" ,
248
+ " cwe" ,
249
+ " defect_id" ,
250
+ " events" ,
251
+ " function" ,
252
+ " imp" ,
253
+ " key_event_idx" ,
254
+ " language" ,
255
+ };
256
+
257
+ // known per-event subnodes
258
+ nodeStore_[NK_EVENT] = {
259
+ " column" ,
260
+ " event" ,
261
+ " file_name" ,
262
+ " line" ,
263
+ " message" ,
264
+ " verbosity_level" ,
265
+ };
266
+ }
267
+
268
+ void SimpleTreeDecoder::reportUnknownNodes (ENodeKind nk, const pt::ptree &node)
269
+ const
270
+ {
271
+ if (silent_)
272
+ return ;
273
+
274
+ const TNodeSet &nodeSet = nodeStore_[nk];
275
+
276
+ BOOST_FOREACH (const pt::ptree::value_type &item, node) {
277
+ const std::string &name = item.first ;
278
+ if (nodeSet.end () == nodeSet.find (name))
279
+ std::cerr << fileName_
280
+ << " : warning: unknown JSON node: " << name
281
+ << std::endl;
282
+ }
283
+ }
284
+
217
285
void SimpleTreeDecoder::readNode (
218
286
Defect *def,
219
287
const pt::ptree &defNode)
220
288
{
221
289
// make sure the Defect structure is properly initialized
222
290
(*def) = Defect ();
223
291
292
+ this ->reportUnknownNodes (NK_DEFECT, defNode);
293
+
224
294
// the checker field is mandatory
225
295
def->checker = defNode.get <std::string>(" checker" );
226
296
@@ -231,6 +301,7 @@ void SimpleTreeDecoder::readNode(
231
301
const pt::ptree &evtListSrc = defNode.get_child (" events" );
232
302
BOOST_FOREACH (const pt::ptree::value_type &evtItem, evtListSrc) {
233
303
const pt::ptree &evtNode = evtItem.second ;
304
+ this ->reportUnknownNodes (NK_EVENT, evtNode);
234
305
235
306
DefEvent evt;
236
307
evt.fileName = valueOf<std::string >(evtNode, " file_name" , " " );
@@ -254,7 +325,7 @@ void SimpleTreeDecoder::readNode(
254
325
255
326
if (defNode.not_found () == defNode.find (" key_event_idx" )) {
256
327
// key event not specified, try to guess it
257
- if (!this -> keDigger .guessKeyEvent (def))
328
+ if (!keDigger_ .guessKeyEvent (def))
258
329
throw pt::ptree_error (" failed to guess key event" );
259
330
}
260
331
else {
@@ -269,7 +340,7 @@ void SimpleTreeDecoder::readNode(
269
340
270
341
if (verbosityLevelNeedsInit)
271
342
// missing or incomplete verbosity_level, initialize it over
272
- this -> keDigger .initVerbosity (def);
343
+ keDigger_ .initVerbosity (def);
273
344
274
345
// read annotation if available
275
346
def->annotation = valueOf<std::string>(defNode, " annotation" , " " );
0 commit comments