comparison extern/vera/src/plugins/Reports.cpp @ 548:a7c0eb100760

CMake: import vera++ 1.3.0, closes #729
author David Demelier <markand@malikania.fr>
date Wed, 22 Nov 2017 20:10:03 +0100
parents
children
comparison
equal deleted inserted replaced
547:a95954e53589 548:a7c0eb100760
1 //
2 // Copyright (C) 2006-2007 Maciej Sobczak
3 // Distributed under the Boost Software License, Version 1.0.
4 // (See accompanying file LICENSE_1_0.txt or copy at
5 // http://www.boost.org/LICENSE_1_0.txt)
6 //
7
8 #include "Reports.h"
9 #include "Rules.h"
10 #include "Exclusions.h"
11 #include <sstream>
12 #include <map>
13 #include <utility>
14 #include <stdexcept>
15 #include <boost/algorithm/string/replace.hpp>
16
17
18 namespace // unnamed
19 {
20
21 // for a single report
22 typedef std::pair<Vera::Plugins::Rules::RuleName, Vera::Plugins::Reports::Message> SingleReport;
23
24 // for a single file (line number -> single report)
25 typedef std::multimap<int, SingleReport> FileMessagesCollection;
26
27 // for all reports
28 typedef std::map<Vera::Plugins::Reports::FileName, FileMessagesCollection> MessagesCollection;
29
30 MessagesCollection messages_;
31
32 bool showRules_;
33 bool vcFormat_;
34 bool xmlReport_;
35 std::string prefix_;
36
37 } // unnamed namespace
38
39 namespace Vera
40 {
41 namespace Plugins
42 {
43
44 void Reports::setShowRules(bool show)
45 {
46 showRules_ = show;
47 }
48
49 void Reports::setXMLReport(bool xmlReport)
50 {
51 xmlReport_ = xmlReport;
52 }
53
54 void Reports::setVCFormat(bool vc)
55 {
56 vcFormat_ = vc;
57 }
58
59 void Reports::setPrefix(std::string prefix)
60 {
61 prefix_ = prefix;
62 }
63
64 int Reports::count()
65 {
66 return messages_.size();
67 }
68
69 void Reports::add(const FileName & name, int lineNumber, const Message & msg)
70 {
71 if (lineNumber <= 0)
72 {
73 std::ostringstream ss;
74 ss << "Line number out of range: " << lineNumber;
75 throw std::out_of_range(ss.str());
76 }
77 const Rules::RuleName currentRule = Rules::getCurrentRule();
78 if (Exclusions::isExcluded(name, lineNumber, currentRule, msg) == false)
79 {
80 messages_[name].insert(make_pair(lineNumber, make_pair(currentRule, msg)));
81 }
82 }
83
84 void Reports::internal(const FileName & name, int lineNumber, const Message & msg)
85 {
86 const Rules::RuleName currentRule = "vera++ internal";
87
88 messages_[name].insert(make_pair(lineNumber, make_pair(currentRule, msg)));
89 }
90
91 void Reports::dumpAll(std::ostream & os, bool omitDuplicates)
92 {
93 if (xmlReport_)
94 {
95 dumpAllXML(os, omitDuplicates);
96 }
97 else
98 {
99 dumpAllNormal(os, omitDuplicates);
100 }
101 }
102
103 void Reports::dumpAllNormal(std::ostream & os, bool omitDuplicates)
104 {
105
106 for (MessagesCollection::iterator it = messages_.begin(), end = messages_.end();
107 it != end; ++it)
108 {
109 const FileName & name = it->first;
110
111 FileMessagesCollection & fileMessages = it->second;
112
113 FileMessagesCollection::iterator fit = fileMessages.begin();
114 FileMessagesCollection::iterator fend = fileMessages.end();
115
116 int lastLineNumber = 0;
117 SingleReport lastReport;
118 for ( ; fit != fend; ++fit)
119 {
120 int lineNumber = fit->first;
121 const SingleReport & report = fit->second;
122 const Rules::RuleName & rule = report.first;
123 const Message & msg = report.second;
124
125 if (omitDuplicates == false ||
126 lineNumber != lastLineNumber || report != lastReport)
127 {
128 if (showRules_)
129 {
130 if (vcFormat_)
131 {
132 os << name << '(' << lineNumber << ") : "
133 << '(' << rule << ") " << msg << '\n';
134 }
135 else
136 {
137 os << name << ':' << lineNumber << ": "
138 << '(' << rule << ") " << msg << '\n';
139 }
140 }
141 else
142 {
143 if (vcFormat_)
144 {
145 os << name << '(' << lineNumber << ") : "
146 << msg << '\n';
147 }
148 else
149 {
150 os << name << ':' << lineNumber << ": "
151 << msg << '\n';
152 }
153 }
154
155 lastLineNumber = lineNumber;
156 lastReport = report;
157 }
158 }
159 }
160 }
161
162 void Reports::dumpAllXML(std::ostream & os, bool omitDuplicates)
163 {
164 writeXml(os, omitDuplicates);
165 }
166
167 void Reports::writeStd(std::ostream & os, bool omitDuplicates)
168 {
169
170 for (MessagesCollection::iterator it = messages_.begin(), end = messages_.end();
171 it != end; ++it)
172 {
173 const FileName & name = it->first;
174
175 FileMessagesCollection & fileMessages = it->second;
176
177 FileMessagesCollection::iterator fit = fileMessages.begin();
178 FileMessagesCollection::iterator fend = fileMessages.end();
179
180 int lastLineNumber = 0;
181 SingleReport lastReport;
182 for ( ; fit != fend; ++fit)
183 {
184 int lineNumber = fit->first;
185 const SingleReport & report = fit->second;
186 const Rules::RuleName & rule = report.first;
187 const Message & msg = report.second;
188
189 if (omitDuplicates == false ||
190 lineNumber != lastLineNumber || report != lastReport)
191 {
192 os << name;
193 os << ':' << lineNumber << ":";
194 if (prefix_ != "")
195 {
196 os << " " << prefix_;
197 }
198 if (showRules_)
199 {
200 os << " " << rule;
201 }
202 if (showRules_ || prefix_ != "")
203 {
204 os << ":";
205 }
206 os << " " << msg << std::endl;
207
208 lastLineNumber = lineNumber;
209 lastReport = report;
210 }
211 }
212 }
213 }
214
215 void Reports::writeVc(std::ostream & os, bool omitDuplicates)
216 {
217
218 for (MessagesCollection::iterator it = messages_.begin(), end = messages_.end();
219 it != end; ++it)
220 {
221 const FileName & name = it->first;
222
223 FileMessagesCollection & fileMessages = it->second;
224
225 FileMessagesCollection::iterator fit = fileMessages.begin();
226 FileMessagesCollection::iterator fend = fileMessages.end();
227
228 int lastLineNumber = 0;
229 SingleReport lastReport;
230 for ( ; fit != fend; ++fit)
231 {
232 int lineNumber = fit->first;
233 const SingleReport & report = fit->second;
234 const Rules::RuleName & rule = report.first;
235 const Message & msg = report.second;
236
237 if (omitDuplicates == false ||
238 lineNumber != lastLineNumber || report != lastReport)
239 {
240 os << name;
241 os << '(' << lineNumber << "):";
242 if (prefix_ != "")
243 {
244 os << " " << prefix_;
245 }
246 if (showRules_)
247 {
248 os << " " << rule;
249 }
250 if (showRules_ || prefix_ != "")
251 {
252 os << ":";
253 }
254 os << " " << msg << std::endl;
255
256 lastLineNumber = lineNumber;
257 lastReport = report;
258 }
259 }
260 }
261 }
262
263 void Reports::writeXml(std::ostream & os, bool omitDuplicates)
264 {
265 os<< "<?xml version=\"1.0\" encoding=\"UTF-8\"?>" << std::endl;
266 os << "<vera>\n";
267
268 for (MessagesCollection::iterator it = messages_.begin(), end = messages_.end();
269 it != end; ++it)
270 {
271 const FileName & name = it->first;
272
273 os << " <file name=\"" << name << "\">\n";
274
275 FileMessagesCollection & fileMessages = it->second;
276
277 FileMessagesCollection::iterator fit = fileMessages.begin();
278 FileMessagesCollection::iterator fend = fileMessages.end();
279
280 int lastLineNumber = 0;
281 SingleReport lastReport;
282 for ( ; fit != fend; ++fit)
283 {
284 int lineNumber = fit->first;
285 const SingleReport & report = fit->second;
286 const Rules::RuleName & rule = report.first;
287 const Message & msg = report.second;
288
289 if (omitDuplicates == false ||
290 lineNumber != lastLineNumber || report != lastReport)
291 {
292 if (showRules_)
293 {
294 os << " <report rule=\"" << xmlEscape(rule)
295 << "\" line=\"" << lineNumber
296 << "\">![CDATA[" << msg << "]]</report>\n";
297 }
298 else
299 {
300 os << " <report line=\"" << lineNumber
301 << "\">![CDATA[" << msg << "]]</report>\n";
302 }
303
304 lastLineNumber = lineNumber;
305 lastReport = report;
306 }
307 }
308
309 os << " </file>\n";
310 }
311
312 os << "</vera>\n";
313 }
314
315 void Reports::writeCheckStyle(std::ostream & os, bool omitDuplicates)
316 {
317 std::string severity = prefix_;
318 if (severity == "")
319 {
320 severity = "info";
321 }
322 os<< "<?xml version=\"1.0\" encoding=\"UTF-8\"?>" << std::endl;
323 os << "<checkstyle version=\"5.0\">\n";
324
325 for (MessagesCollection::iterator it = messages_.begin(), end = messages_.end();
326 it != end; ++it)
327 {
328 const FileName & name = it->first;
329
330 os << " <file name=\"" << name << "\">\n";
331
332 FileMessagesCollection & fileMessages = it->second;
333
334 FileMessagesCollection::iterator fit = fileMessages.begin();
335 FileMessagesCollection::iterator fend = fileMessages.end();
336
337 int lastLineNumber = 0;
338 SingleReport lastReport;
339 for ( ; fit != fend; ++fit)
340 {
341 int lineNumber = fit->first;
342 const SingleReport & report = fit->second;
343 const Rules::RuleName & rule = report.first;
344 const Message & msg = report.second;
345
346 if (omitDuplicates == false ||
347 lineNumber != lastLineNumber || report != lastReport)
348 {
349 os << " <error source=\"" << xmlEscape(rule)
350 << "\" severity=\"" << xmlEscape(severity)
351 << "\" line=\"" << lineNumber
352 << "\" message=\"" << xmlEscape(msg)
353 << "\" />\n";
354
355 lastLineNumber = lineNumber;
356 lastReport = report;
357 }
358 }
359
360 os << " </file>\n";
361 }
362
363 os << "</checkstyle>\n";
364 }
365
366 std::string Reports::xmlEscape(const std::string & msg)
367 {
368 std::string res = msg;
369 boost::algorithm::replace_all(res, "&", "&amp;");
370 boost::algorithm::replace_all(res, "\"", "&quot;");
371 boost::algorithm::replace_all(res, "\'", "&apos;");
372 boost::algorithm::replace_all(res, "<", "&lt;");
373 boost::algorithm::replace_all(res, ">", "&gt;");
374 return res;
375 }
376
377 }
378 }