2121
2222#include " csparser.hh" // for KeyEventDigger
2323
24+ #include < set>
25+
2426#include < boost/foreach.hpp>
2527#include < boost/property_tree/json_parser.hpp>
2628
@@ -44,10 +46,25 @@ class AbstractTreeDecoder {
4446// / tree decoder of the native JSON format of csdiff
4547class SimpleTreeDecoder : public AbstractTreeDecoder {
4648 public:
49+ SimpleTreeDecoder (const std::string &fileName, bool silent);
4750 virtual void readNode (Defect *def, const pt::ptree &node);
4851
4952 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_;
5168};
5269
5370// / tree decoder of the Coverity JSON format
@@ -145,7 +162,7 @@ JsonParser::JsonParser(
145162
146163 if (findChildOf (&d->defList , d->root , " defects" ))
147164 // csdiff-native JSON format
148- d->decoder = new SimpleTreeDecoder;
165+ d->decoder = new SimpleTreeDecoder (fileName, silent) ;
149166 else if (findChildOf (&d->defList , d->root , " issues" ))
150167 // Coverity JSON format
151168 d->decoder = new CovTreeDecoder;
@@ -214,13 +231,66 @@ bool JsonParser::getNext(Defect *def) {
214231 }
215232}
216233
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+
217285void SimpleTreeDecoder::readNode (
218286 Defect *def,
219287 const pt::ptree &defNode)
220288{
221289 // make sure the Defect structure is properly initialized
222290 (*def) = Defect ();
223291
292+ this ->reportUnknownNodes (NK_DEFECT, defNode);
293+
224294 // the checker field is mandatory
225295 def->checker = defNode.get <std::string>(" checker" );
226296
@@ -231,6 +301,7 @@ void SimpleTreeDecoder::readNode(
231301 const pt::ptree &evtListSrc = defNode.get_child (" events" );
232302 BOOST_FOREACH (const pt::ptree::value_type &evtItem, evtListSrc) {
233303 const pt::ptree &evtNode = evtItem.second ;
304+ this ->reportUnknownNodes (NK_EVENT, evtNode);
234305
235306 DefEvent evt;
236307 evt.fileName = valueOf<std::string >(evtNode, " file_name" , " " );
@@ -254,7 +325,7 @@ void SimpleTreeDecoder::readNode(
254325
255326 if (defNode.not_found () == defNode.find (" key_event_idx" )) {
256327 // key event not specified, try to guess it
257- if (!this -> keDigger .guessKeyEvent (def))
328+ if (!keDigger_ .guessKeyEvent (def))
258329 throw pt::ptree_error (" failed to guess key event" );
259330 }
260331 else {
@@ -269,7 +340,7 @@ void SimpleTreeDecoder::readNode(
269340
270341 if (verbosityLevelNeedsInit)
271342 // missing or incomplete verbosity_level, initialize it over
272- this -> keDigger .initVerbosity (def);
343+ keDigger_ .initVerbosity (def);
273344
274345 // read annotation if available
275346 def->annotation = valueOf<std::string>(defNode, " annotation" , " " );
0 commit comments