Skip to content

Commit d1cb702

Browse files
committed
track a separate "tool" attribute of defects
It can be propagated by csdiff's native JSON format and statically assigned or guessed for the other formats. Closes: #49
1 parent eb60f1b commit d1cb702

36 files changed

+14386
-1
lines changed

src/csparser.cc

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -612,6 +612,7 @@ bool CovParser::Private::parseNext(Defect *def)
612612
this->keDigger.initVerbosity(def);
613613
this->annotHdl.handleDef(def);
614614
this->digger.inferLangFromChecker(def);
615+
this->digger.inferToolFromChecker(def);
615616

616617
// all OK
617618
return true;

src/defect.hh

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,7 @@ struct Defect {
9494
int defectId = 0; ///< used only by the JSON format
9595
std::string function; ///< used only by the JSON format
9696
std::string language; ///< used only by the JSON format
97+
std::string tool; ///< used only by the JSON format
9798

9899
Defect() { }
99100

src/gcc-parser.cc

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -678,7 +678,8 @@ void GccPostProcessor::apply(Defect *pDef) const
678678
d->polishGccAnal(pDef);
679679
d->polishClangAnal(pDef);
680680

681-
d->digger.inferLangFromChecker(pDef);
681+
d->digger.inferLangFromChecker(pDef, /* onlyIfMissing */ false);
682+
d->digger.inferToolFromChecker(pDef, /* onlyIfMissing */ false);
682683
}
683684

684685
struct GccParser::Private {

src/json-parser.cc

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,8 @@ class SarifTreeDecoder: public AbstractTreeDecoder {
8989

9090
typedef std::map<std::string, int> TCweMap;
9191
TCweMap cweMap;
92+
93+
ImpliedAttrDigger digger;
9294
};
9395

9496
struct JsonParser::Private {
@@ -231,6 +233,7 @@ SimpleTreeDecoder::SimpleTreeDecoder(InStream &input):
231233
"imp",
232234
"key_event_idx",
233235
"language",
236+
"tool",
234237
};
235238

236239
// known per-event subnodes
@@ -312,6 +315,7 @@ bool SimpleTreeDecoder::readNode(
312315
def->imp = valueOf<int> (defNode, "imp" , 0);
313316
def->function = valueOf<std::string>(defNode, "function", "");
314317
def->language = valueOf<std::string>(defNode, "language", "");
318+
def->tool = valueOf<std::string>(defNode, "tool", "");
315319

316320
if (defNode.not_found() == defNode.find("key_event_idx")) {
317321
// key event not specified, try to guess it
@@ -349,6 +353,9 @@ bool CovTreeDecoder::readNode(
349353
def->function = valueOf<std::string>(defNode, "functionDisplayName", "");
350354
def->language = valueOf<std::string>(defNode, "code-language", "");
351355

356+
// out of the supported tools, only Coverity produces this data format
357+
def->tool = "coverity";
358+
352359
// read CWE if available
353360
const pt::ptree *checkerProps;
354361
if (findChildOf(&checkerProps, defNode, "checkerProperties"))
@@ -626,5 +633,8 @@ bool SarifTreeDecoder::readNode(
626633
if (findChildOf(&relatedLocs, defNode, "relatedLocations"))
627634
sarifReadComments(def, *relatedLocs);
628635

636+
this->digger.inferLangFromChecker(def);
637+
this->digger.inferToolFromChecker(def);
638+
629639
return true;
630640
}

src/json-writer.cc

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -111,6 +111,8 @@ void SimpleTreeEncoder::appendDef(const Defect &def)
111111
defNode.put<string>("function", def.function);
112112
if (!def.language.empty())
113113
defNode.put<string>("language", def.language);
114+
if (!def.tool.empty())
115+
defNode.put<string>("tool", def.tool);
114116

115117
defNode.put<int>("key_event_idx", def.keyEventIdx);
116118
defNode.put_child("events", evtList);

src/parser-common.cc

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,10 @@
1919

2020
#include "parser-common.hh"
2121

22+
#include "regex.hh"
23+
24+
#include <boost/algorithm/string.hpp>
25+
#include <boost/algorithm/string/replace.hpp>
2226
#include <boost/lexical_cast.hpp>
2327

2428
int parse_int(const std::string &str, const int fallback)
@@ -34,6 +38,8 @@ int parse_int(const std::string &str, const int fallback)
3438
struct ImpliedAttrDigger::Private {
3539
typedef std::map<std::string, std::string> TMap;
3640
TMap langByChecker;
41+
42+
const RE reToolWarning = RE("^([A-Z_]+)_WARNING$");
3743
};
3844

3945
ImpliedAttrDigger::ImpliedAttrDigger():
@@ -70,3 +76,30 @@ void ImpliedAttrDigger::inferLangFromChecker(
7076
// found --> assign from map
7177
pDef->language = it->second;
7278
}
79+
80+
void ImpliedAttrDigger::inferToolFromChecker(
81+
Defect *pDef,
82+
const bool onlyIfMissing)
83+
const
84+
{
85+
if (onlyIfMissing && !pDef->tool.empty())
86+
// tool already assigned
87+
return;
88+
89+
boost::smatch sm;
90+
if (boost::regex_match(pDef->checker, sm, d->reToolWarning)) {
91+
// extract tool="gcc-analyzer" out of checker="GCC_ANALYZER_WARNING"
92+
std::string tool = sm[/* tool */ 1];
93+
boost::algorithm::to_lower(tool);
94+
boost::algorithm::replace_all(tool, "_", "-");
95+
96+
if (tool == "compiler")
97+
// we use COMPILER_WARNING for "gcc" due to historical reasons
98+
tool = "gcc";
99+
100+
pDef->tool = tool;
101+
}
102+
else
103+
// no tool matched --> assume coverity
104+
pDef->tool = "coverity";
105+
}

src/parser-common.hh

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@ class ImpliedAttrDigger {
4141
~ImpliedAttrDigger();
4242

4343
void inferLangFromChecker(Defect *, bool onlyIfMissing = true) const;
44+
void inferToolFromChecker(Defect *, bool onlyIfMissing = true) const;
4445

4546
private:
4647
struct Private;

src/xml-parser.cc

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -114,6 +114,9 @@ void ValgrindTreeDecoder::readRoot(
114114
// valgrind reports will be at the same level in the XML tree
115115
*pDefList = root;
116116

117+
// only valgrind produces this data format
118+
this->defPrototype.tool = "valgrind";
119+
117120
const int pid = valueOf<int>(*root, "pid", 0);
118121
if (!pid)
119122
// insufficient data

0 commit comments

Comments
 (0)