comparison extern/vera/src/plugins/Exclusions.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 "Exclusions.h"
9 #include "Rules.h"
10 #include "../structures/SourceFiles.h"
11 #include "tcl/cpptcl-1.1.4/cpptcl.h"
12 #include <fstream>
13 #include <sstream>
14 #include <cstring>
15 #include <cerrno>
16 #include <boost/regex.hpp>
17 #include <boost/lexical_cast.hpp>
18 #include <boost/foreach.hpp>
19
20 #define foreach BOOST_FOREACH
21
22
23 namespace // unnamed
24 {
25
26 typedef std::set<Vera::Structures::SourceFiles::FileName> FileNameSet;
27 typedef std::map<Vera::Plugins::Rules::RuleName, FileNameSet> ExclusionMap;
28 ExclusionMap exclusions;
29
30 typedef std::vector<boost::regex> RegexList;
31 RegexList exclusionRegexs;
32
33 } // unnamed namespace
34
35 namespace Vera
36 {
37 namespace Plugins
38 {
39
40 void Exclusions::setExclusions(const ExclusionFileName & fileName)
41 {
42 try
43 {
44 setExclusionsTcl(fileName);
45 }
46 catch (...)
47 {
48 setExclusionsRegex(fileName);
49 }
50 }
51
52 void Exclusions::setExclusionsRegex(const ExclusionFileName & fileName)
53 {
54 std::ifstream exclusionsFile(fileName.c_str());
55 if (exclusionsFile.is_open() == false)
56 {
57 std::ostringstream ss;
58 ss << "Cannot open exclusions file " << fileName << ": "
59 << strerror(errno);
60 throw ExclusionError(ss.str());
61 }
62 std::string re;
63 while (std::getline(exclusionsFile, re))
64 {
65 // don't process empty lines and lines begining with a #
66 if (re.empty() == false && re.substr(0, 1) != "#")
67 {
68 exclusionRegexs.push_back(boost::regex(re));
69 }
70 }
71 if (exclusionsFile.bad())
72 {
73 throw std::runtime_error(
74 "Cannot read from " + fileName + ": " + strerror(errno));
75 }
76 }
77
78 void Exclusions::setExclusionsTcl(const ExclusionFileName & fileName)
79 {
80 std::ifstream exclusionsFile(fileName.c_str());
81 if (exclusionsFile.is_open() == false)
82 {
83 std::ostringstream ss;
84 ss << "Cannot open exclusions file " << fileName << ": "
85 << strerror(errno);
86 throw ExclusionError(ss.str());
87 }
88
89 Tcl::interpreter interp;
90 interp.eval(exclusionsFile);
91 if (exclusionsFile.bad())
92 {
93 throw std::runtime_error(
94 "Cannot read from " + fileName + ": " + strerror(errno));
95 }
96
97 const Tcl::object ruleNames = interp.eval("array names ruleExclusions");
98 const size_t ruleNamesLength = ruleNames.length(interp);
99 for (size_t i = 0; i != ruleNamesLength; ++i)
100 {
101 const std::string ruleName = ruleNames.at(interp, i).get();
102
103 const Tcl::object exceptionList = interp.eval("set ruleExclusions(" + ruleName + ")");
104 const size_t exceptionListLength = exceptionList.length(interp);
105
106 FileNameSet files;
107 for (size_t j = 0; j != exceptionListLength; ++j)
108 {
109 const Structures::SourceFiles::FileName file = exceptionList.at(interp, j).get();
110 files.insert(file);
111 }
112
113 exclusions[ruleName] = files;
114 }
115 }
116
117 bool Exclusions::isExcluded(const Structures::SourceFiles::FileName & name,
118 int lineNumber, const Rules::RuleName & currentRule, const std::string & msg)
119 {
120 std::string fmsg = name + ":" + boost::lexical_cast<std::string>(lineNumber)
121 + ": " + currentRule + ": " + msg;
122 foreach(boost::regex const& re, exclusionRegexs)
123 {
124 if (boost::regex_search(fmsg, re))
125 {
126 return true;
127 }
128 }
129 return false;
130 }
131
132 bool Exclusions::isExcluded(const Structures::SourceFiles::FileName & name)
133 {
134 const Rules::RuleName currentRule = Rules::getCurrentRule();
135
136 const ExclusionMap::const_iterator eit = exclusions.find(currentRule);
137 if (eit != exclusions.end())
138 {
139 const FileNameSet & files = eit->second;
140
141 const FileNameSet::const_iterator fit =
142 files.find(name.substr(name.find_last_of("\\/") + 1));
143 return fit != files.end();
144 }
145 else
146 {
147 return false;
148 }
149 }
150
151 }
152
153 }