Mercurial > irccd
diff 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 |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/extern/vera/src/plugins/Reports.cpp Wed Nov 22 20:10:03 2017 +0100 @@ -0,0 +1,378 @@ +// +// Copyright (C) 2006-2007 Maciej Sobczak +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// + +#include "Reports.h" +#include "Rules.h" +#include "Exclusions.h" +#include <sstream> +#include <map> +#include <utility> +#include <stdexcept> +#include <boost/algorithm/string/replace.hpp> + + +namespace // unnamed +{ + +// for a single report +typedef std::pair<Vera::Plugins::Rules::RuleName, Vera::Plugins::Reports::Message> SingleReport; + +// for a single file (line number -> single report) +typedef std::multimap<int, SingleReport> FileMessagesCollection; + +// for all reports +typedef std::map<Vera::Plugins::Reports::FileName, FileMessagesCollection> MessagesCollection; + +MessagesCollection messages_; + +bool showRules_; +bool vcFormat_; +bool xmlReport_; +std::string prefix_; + +} // unnamed namespace + +namespace Vera +{ +namespace Plugins +{ + +void Reports::setShowRules(bool show) +{ + showRules_ = show; +} + +void Reports::setXMLReport(bool xmlReport) +{ + xmlReport_ = xmlReport; +} + +void Reports::setVCFormat(bool vc) +{ + vcFormat_ = vc; +} + +void Reports::setPrefix(std::string prefix) +{ + prefix_ = prefix; +} + +int Reports::count() +{ + return messages_.size(); +} + +void Reports::add(const FileName & name, int lineNumber, const Message & msg) +{ + if (lineNumber <= 0) + { + std::ostringstream ss; + ss << "Line number out of range: " << lineNumber; + throw std::out_of_range(ss.str()); + } + const Rules::RuleName currentRule = Rules::getCurrentRule(); + if (Exclusions::isExcluded(name, lineNumber, currentRule, msg) == false) + { + messages_[name].insert(make_pair(lineNumber, make_pair(currentRule, msg))); + } +} + +void Reports::internal(const FileName & name, int lineNumber, const Message & msg) +{ + const Rules::RuleName currentRule = "vera++ internal"; + + messages_[name].insert(make_pair(lineNumber, make_pair(currentRule, msg))); +} + +void Reports::dumpAll(std::ostream & os, bool omitDuplicates) +{ + if (xmlReport_) + { + dumpAllXML(os, omitDuplicates); + } + else + { + dumpAllNormal(os, omitDuplicates); + } +} + +void Reports::dumpAllNormal(std::ostream & os, bool omitDuplicates) +{ + + for (MessagesCollection::iterator it = messages_.begin(), end = messages_.end(); + it != end; ++it) + { + const FileName & name = it->first; + + FileMessagesCollection & fileMessages = it->second; + + FileMessagesCollection::iterator fit = fileMessages.begin(); + FileMessagesCollection::iterator fend = fileMessages.end(); + + int lastLineNumber = 0; + SingleReport lastReport; + for ( ; fit != fend; ++fit) + { + int lineNumber = fit->first; + const SingleReport & report = fit->second; + const Rules::RuleName & rule = report.first; + const Message & msg = report.second; + + if (omitDuplicates == false || + lineNumber != lastLineNumber || report != lastReport) + { + if (showRules_) + { + if (vcFormat_) + { + os << name << '(' << lineNumber << ") : " + << '(' << rule << ") " << msg << '\n'; + } + else + { + os << name << ':' << lineNumber << ": " + << '(' << rule << ") " << msg << '\n'; + } + } + else + { + if (vcFormat_) + { + os << name << '(' << lineNumber << ") : " + << msg << '\n'; + } + else + { + os << name << ':' << lineNumber << ": " + << msg << '\n'; + } + } + + lastLineNumber = lineNumber; + lastReport = report; + } + } + } +} + +void Reports::dumpAllXML(std::ostream & os, bool omitDuplicates) +{ + writeXml(os, omitDuplicates); +} + +void Reports::writeStd(std::ostream & os, bool omitDuplicates) +{ + + for (MessagesCollection::iterator it = messages_.begin(), end = messages_.end(); + it != end; ++it) + { + const FileName & name = it->first; + + FileMessagesCollection & fileMessages = it->second; + + FileMessagesCollection::iterator fit = fileMessages.begin(); + FileMessagesCollection::iterator fend = fileMessages.end(); + + int lastLineNumber = 0; + SingleReport lastReport; + for ( ; fit != fend; ++fit) + { + int lineNumber = fit->first; + const SingleReport & report = fit->second; + const Rules::RuleName & rule = report.first; + const Message & msg = report.second; + + if (omitDuplicates == false || + lineNumber != lastLineNumber || report != lastReport) + { + os << name; + os << ':' << lineNumber << ":"; + if (prefix_ != "") + { + os << " " << prefix_; + } + if (showRules_) + { + os << " " << rule; + } + if (showRules_ || prefix_ != "") + { + os << ":"; + } + os << " " << msg << std::endl; + + lastLineNumber = lineNumber; + lastReport = report; + } + } + } +} + +void Reports::writeVc(std::ostream & os, bool omitDuplicates) +{ + + for (MessagesCollection::iterator it = messages_.begin(), end = messages_.end(); + it != end; ++it) + { + const FileName & name = it->first; + + FileMessagesCollection & fileMessages = it->second; + + FileMessagesCollection::iterator fit = fileMessages.begin(); + FileMessagesCollection::iterator fend = fileMessages.end(); + + int lastLineNumber = 0; + SingleReport lastReport; + for ( ; fit != fend; ++fit) + { + int lineNumber = fit->first; + const SingleReport & report = fit->second; + const Rules::RuleName & rule = report.first; + const Message & msg = report.second; + + if (omitDuplicates == false || + lineNumber != lastLineNumber || report != lastReport) + { + os << name; + os << '(' << lineNumber << "):"; + if (prefix_ != "") + { + os << " " << prefix_; + } + if (showRules_) + { + os << " " << rule; + } + if (showRules_ || prefix_ != "") + { + os << ":"; + } + os << " " << msg << std::endl; + + lastLineNumber = lineNumber; + lastReport = report; + } + } + } +} + +void Reports::writeXml(std::ostream & os, bool omitDuplicates) +{ + os<< "<?xml version=\"1.0\" encoding=\"UTF-8\"?>" << std::endl; + os << "<vera>\n"; + + for (MessagesCollection::iterator it = messages_.begin(), end = messages_.end(); + it != end; ++it) + { + const FileName & name = it->first; + + os << " <file name=\"" << name << "\">\n"; + + FileMessagesCollection & fileMessages = it->second; + + FileMessagesCollection::iterator fit = fileMessages.begin(); + FileMessagesCollection::iterator fend = fileMessages.end(); + + int lastLineNumber = 0; + SingleReport lastReport; + for ( ; fit != fend; ++fit) + { + int lineNumber = fit->first; + const SingleReport & report = fit->second; + const Rules::RuleName & rule = report.first; + const Message & msg = report.second; + + if (omitDuplicates == false || + lineNumber != lastLineNumber || report != lastReport) + { + if (showRules_) + { + os << " <report rule=\"" << xmlEscape(rule) + << "\" line=\"" << lineNumber + << "\">![CDATA[" << msg << "]]</report>\n"; + } + else + { + os << " <report line=\"" << lineNumber + << "\">![CDATA[" << msg << "]]</report>\n"; + } + + lastLineNumber = lineNumber; + lastReport = report; + } + } + + os << " </file>\n"; + } + + os << "</vera>\n"; +} + +void Reports::writeCheckStyle(std::ostream & os, bool omitDuplicates) +{ + std::string severity = prefix_; + if (severity == "") + { + severity = "info"; + } + os<< "<?xml version=\"1.0\" encoding=\"UTF-8\"?>" << std::endl; + os << "<checkstyle version=\"5.0\">\n"; + + for (MessagesCollection::iterator it = messages_.begin(), end = messages_.end(); + it != end; ++it) + { + const FileName & name = it->first; + + os << " <file name=\"" << name << "\">\n"; + + FileMessagesCollection & fileMessages = it->second; + + FileMessagesCollection::iterator fit = fileMessages.begin(); + FileMessagesCollection::iterator fend = fileMessages.end(); + + int lastLineNumber = 0; + SingleReport lastReport; + for ( ; fit != fend; ++fit) + { + int lineNumber = fit->first; + const SingleReport & report = fit->second; + const Rules::RuleName & rule = report.first; + const Message & msg = report.second; + + if (omitDuplicates == false || + lineNumber != lastLineNumber || report != lastReport) + { + os << " <error source=\"" << xmlEscape(rule) + << "\" severity=\"" << xmlEscape(severity) + << "\" line=\"" << lineNumber + << "\" message=\"" << xmlEscape(msg) + << "\" />\n"; + + lastLineNumber = lineNumber; + lastReport = report; + } + } + + os << " </file>\n"; + } + + os << "</checkstyle>\n"; +} + +std::string Reports::xmlEscape(const std::string & msg) +{ + std::string res = msg; + boost::algorithm::replace_all(res, "&", "&"); + boost::algorithm::replace_all(res, "\"", """); + boost::algorithm::replace_all(res, "\'", "'"); + boost::algorithm::replace_all(res, "<", "<"); + boost::algorithm::replace_all(res, ">", ">"); + return res; +} + +} +}