Mercurial > irccd
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, "&", "&"); | |
370 boost::algorithm::replace_all(res, "\"", """); | |
371 boost::algorithm::replace_all(res, "\'", "'"); | |
372 boost::algorithm::replace_all(res, "<", "<"); | |
373 boost::algorithm::replace_all(res, ">", ">"); | |
374 return res; | |
375 } | |
376 | |
377 } | |
378 } |