Skip to content

Commit 577006f

Browse files
committed
put metrics in xml output
1 parent 4bc359a commit 577006f

9 files changed

Lines changed: 86 additions & 2 deletions

File tree

cli/cmdlineparser.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -128,6 +128,12 @@ namespace {
128128
reportOut(msg.toXML());
129129
}
130130

131+
void reportMetric(const std::string &metric) override
132+
{
133+
/* Not used here */
134+
(void) metric;
135+
}
136+
131137
void reportProgress(const std::string & /*filename*/, const char /*stage*/[], const std::size_t /*value*/) override
132138
{}
133139
};

cli/cppcheckexecutor.cpp

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -277,6 +277,22 @@ namespace {
277277
*/
278278
void reportErr(const std::string &errmsg);
279279

280+
void reportMetric(const std::string &metric) override
281+
{
282+
mFileMetrics.push_back(metric);
283+
}
284+
285+
void reportMetrics()
286+
{
287+
if (!mFileMetrics.empty()) {
288+
std::cout << " <metrics>" << std::endl;
289+
for (const auto &metric : mFileMetrics) {
290+
reportOut(" " + metric);
291+
}
292+
std::cout << " </metrics>" << std::endl;
293+
}
294+
}
295+
280296
/**
281297
* @brief Write the checkers report
282298
*/
@@ -349,6 +365,11 @@ namespace {
349365
* Coding standard guideline mapping
350366
*/
351367
std::map<std::string, std::string> mGuidelineMapping;
368+
369+
/**
370+
* File metrics
371+
*/
372+
std::vector<std::string> mFileMetrics;
352373
};
353374
}
354375

@@ -483,6 +504,7 @@ int CppCheckExecutor::check_internal(const Settings& settings, Suppressions& sup
483504
stdLogger.writeCheckersReport(supprs);
484505

485506
if (settings.outputFormat == Settings::OutputFormat::xml) {
507+
stdLogger.reportMetrics();
486508
stdLogger.reportErr(ErrorMessage::getXMLFooter(settings.xml_version));
487509
}
488510

cli/processexecutor.cpp

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -78,7 +78,7 @@ ProcessExecutor::ProcessExecutor(const std::list<FileWithDetails> &files, const
7878
namespace {
7979
class PipeWriter : public ErrorLogger {
8080
public:
81-
enum PipeSignal : std::uint8_t {REPORT_OUT='1',REPORT_ERROR='2',REPORT_SUPPR_INLINE='3',REPORT_SUPPR='4',CHILD_END='5'};
81+
enum PipeSignal : std::uint8_t {REPORT_OUT='1',REPORT_ERROR='2',REPORT_SUPPR_INLINE='3',REPORT_SUPPR='4',CHILD_END='5',REPORT_METRIC='6'};
8282

8383
explicit PipeWriter(int pipe) : mWpipe(pipe) {}
8484

@@ -100,6 +100,10 @@ namespace {
100100
}
101101
}
102102

103+
void reportMetric(const std::string &metric) override {
104+
writeToPipe(REPORT_METRIC, metric);
105+
}
106+
103107
void writeEnd(const std::string& str) const {
104108
writeToPipe(CHILD_END, str);
105109
}
@@ -179,7 +183,8 @@ bool ProcessExecutor::handleRead(int rpipe, unsigned int &result, const std::str
179183
type != PipeWriter::REPORT_ERROR &&
180184
type != PipeWriter::REPORT_SUPPR_INLINE &&
181185
type != PipeWriter::REPORT_SUPPR &&
182-
type != PipeWriter::CHILD_END) {
186+
type != PipeWriter::CHILD_END &&
187+
type != PipeWriter::REPORT_METRIC) {
183188
std::cerr << "#### ThreadExecutor::handleRead(" << filename << ") invalid type " << int(type) << std::endl;
184189
std::exit(EXIT_FAILURE);
185190
}
@@ -256,6 +261,8 @@ bool ProcessExecutor::handleRead(int rpipe, unsigned int &result, const std::str
256261
} else if (type == PipeWriter::CHILD_END) {
257262
result += std::stoi(buf);
258263
res = false;
264+
} else if (type == PipeWriter::REPORT_METRIC) {
265+
mErrorLogger.reportMetric(buf);
259266
}
260267

261268
return res;

cli/threadexecutor.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,11 @@ class SyncLogForwarder : public ErrorLogger
6666
mErrorLogger.reportErr(msg);
6767
}
6868

69+
void reportMetric(const std::string &metric) override {
70+
std::lock_guard<std::mutex> lg(mReportSync);
71+
mErrorLogger.reportMetric(metric);
72+
}
73+
6974
void reportStatus(std::size_t fileindex, std::size_t filecount, std::size_t sizedone, std::size_t sizetotal) {
7075
std::lock_guard<std::mutex> lg(mReportSync);
7176
mThreadExecutor.reportStatus(fileindex, filecount, sizedone, sizetotal);

lib/cppcheck.cpp

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -257,6 +257,11 @@ class CppCheck::CppCheckLogger : public ErrorLogger
257257
mErrorLogger.reportOut(outmsg, c);
258258
}
259259

260+
void reportMetric(const std::string &metric) override
261+
{
262+
mErrorLogger.reportMetric(metric);
263+
}
264+
260265
void reportProgress(const std::string &filename, const char stage[], const std::size_t value) override
261266
{
262267
mErrorLogger.reportProgress(filename, stage, value);
@@ -1764,6 +1769,29 @@ void CppCheck::executeAddons(const std::vector<std::string>& files, const std::s
17641769
}
17651770
}
17661771

1772+
if (obj.count("metric") > 0) {
1773+
picojson::object metric_json = obj["metric"].get<picojson::object>();
1774+
1775+
std::stringstream ss;
1776+
ss << "<";
1777+
1778+
bool isFirst = true;
1779+
for (auto pair : metric_json) {
1780+
std::string sep = isFirst ? "" : " ";
1781+
isFirst = false;
1782+
const std::string id = pair.first;
1783+
if (pair.second.is<std::int64_t>())
1784+
ss << sep << id << "=\"" << pair.second.get<std::int64_t>() << "\"";
1785+
else if (pair.second.is<std::string>())
1786+
ss << sep << id << "=\"" << pair.second.get<std::string>() << "\"";
1787+
}
1788+
1789+
ss << "/>";
1790+
mErrorLogger.reportMetric(ss.str());
1791+
1792+
continue;
1793+
}
1794+
17671795
errmsg.id = obj["addon"].get<std::string>() + "-" + obj["errorId"].get<std::string>();
17681796
if (misraC2023 && startsWith(errmsg.id, "misra-c2012-"))
17691797
errmsg.id = "misra-c2023-" + errmsg.id.substr(12);

lib/errorlogger.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -245,6 +245,13 @@ class CPPCHECKLIB ErrorLogger {
245245
*/
246246
virtual void reportErr(const ErrorMessage &msg) = 0;
247247

248+
/**
249+
* Information about file metrics reported by addons.
250+
*
251+
* @param metric The file metric to report, as an XML object.
252+
*/
253+
virtual void reportMetric(const std::string &metric) = 0;
254+
248255
/**
249256
* Report progress to client
250257
* @param filename main file that is checked

oss-fuzz/main.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@ class DummyErrorLogger : public ErrorLogger {
4343
void reportProgress(const std::string& /*filename*/,
4444
const char /*stage*/[],
4545
const std::size_t /*value*/) override {}
46+
void reportMetric(const std::string & /*metric*/) override {}
4647
};
4748

4849
static Settings create_settings()

test/fixture.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -290,6 +290,10 @@ class TestFixture : public ErrorLogger {
290290

291291
void reportOut(const std::string &outmsg, Color c = Color::Reset) override;
292292
void reportErr(const ErrorMessage &msg) override;
293+
void reportMetric(const std::string &metric) override
294+
{
295+
(void) metric;
296+
}
293297
void run(const std::string &str);
294298

295299
public:

test/testcppcheck.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,10 @@ class TestCppcheck : public TestFixture {
5252
ids.push_back(msg.id);
5353
errmsgs.push_back(msg);
5454
}
55+
56+
void reportMetric(const std::string &metric) override {
57+
(void) metric;
58+
}
5559
};
5660

5761
void run() override {

0 commit comments

Comments
 (0)