1 | // minmax_check implementation --------------------------------------------// |
---|
2 | |
---|
3 | // Copyright Beman Dawes 2002. |
---|
4 | // Copyright Gennaro Prota 2006. |
---|
5 | // |
---|
6 | // Distributed under the Boost Software License, Version 1.0. |
---|
7 | // (See accompanying file LICENSE_1_0.txt or copy at |
---|
8 | // http://www.boost.org/LICENSE_1_0.txt) |
---|
9 | |
---|
10 | |
---|
11 | #include <algorithm> |
---|
12 | |
---|
13 | #include "minmax_check.hpp" |
---|
14 | #include "boost/regex.hpp" |
---|
15 | #include "boost/lexical_cast.hpp" |
---|
16 | |
---|
17 | namespace |
---|
18 | { |
---|
19 | boost::regex minmax_regex( |
---|
20 | "(" |
---|
21 | "^\\s*#\\s*undef\\s*" // # undef |
---|
22 | "\\b(min|max)\\b" // followed by min or max, whole word |
---|
23 | ")" |
---|
24 | "|" // or |
---|
25 | "(" |
---|
26 | "\\b(min|max)\\b" // min or max, whole word |
---|
27 | "\\s*\\(" // followed by 0 or more spaces and an opening paren |
---|
28 | ")" |
---|
29 | , boost::regex::normal); |
---|
30 | |
---|
31 | } // unnamed namespace |
---|
32 | |
---|
33 | namespace boost |
---|
34 | { |
---|
35 | namespace inspect |
---|
36 | { |
---|
37 | |
---|
38 | // minmax_check constructor -------------------------------------------// |
---|
39 | |
---|
40 | minmax_check::minmax_check() |
---|
41 | : m_errors(0) |
---|
42 | { |
---|
43 | // C/C++ source code... |
---|
44 | register_signature( ".c" ); |
---|
45 | register_signature( ".cpp" ); |
---|
46 | register_signature( ".cxx" ); |
---|
47 | register_signature( ".h" ); |
---|
48 | register_signature( ".hpp" ); |
---|
49 | register_signature( ".hxx" ); |
---|
50 | register_signature( ".inc" ); |
---|
51 | register_signature( ".ipp" ); |
---|
52 | } |
---|
53 | |
---|
54 | // inspect ( C++ source files ) ---------------------------------------// |
---|
55 | |
---|
56 | void minmax_check::inspect( |
---|
57 | const string & library_name, |
---|
58 | const path & full_path, // example: c:/foo/boost/filesystem/path.hpp |
---|
59 | const string & contents) // contents of file to be inspected |
---|
60 | { |
---|
61 | if (contents.find( "boostinspect:" "nominmax" ) != string::npos) return; |
---|
62 | |
---|
63 | boost::sregex_iterator cur(contents.begin(), contents.end(), minmax_regex), end; |
---|
64 | |
---|
65 | for( ; cur != end; ++cur /*, ++m_errors*/ ) |
---|
66 | { |
---|
67 | // ~ experimental: try to filter out apparent |
---|
68 | // ~ min/max guideline violations in one-line comments |
---|
69 | // |
---|
70 | // This is just a quick hack to avoid impacting the |
---|
71 | // overall application design. To be on the safe side, |
---|
72 | // we only aim at one-line comments; the comment must be |
---|
73 | // the only non-blank content of the line, and no quote |
---|
74 | // character or "*/" shall appear within it. Otherwise we |
---|
75 | // give up filtering, at the cost of possible false positives. |
---|
76 | // |
---|
77 | const string one_line_comment_line ( "^\\s*//" ); |
---|
78 | |
---|
79 | string::const_iterator it = contents.begin(); |
---|
80 | string::const_iterator match_it = (*cur)[0].first; |
---|
81 | |
---|
82 | string::const_iterator line_start = it; |
---|
83 | |
---|
84 | string::size_type line_number = 1; |
---|
85 | for ( ; it != match_it; ++it) { |
---|
86 | if (string::traits_type::eq(*it, '\n')) { |
---|
87 | ++line_number; |
---|
88 | line_start = it + 1; // could be end() |
---|
89 | } |
---|
90 | } |
---|
91 | |
---|
92 | string::const_iterator past_line_content = |
---|
93 | std::find(it, contents.end(), '\n'); |
---|
94 | |
---|
95 | // one-line comment spanning the whole line |
---|
96 | // with no quotes and no "*/" pair |
---|
97 | // |
---|
98 | match_results<string::const_iterator> m; |
---|
99 | const string whole_line( line_start, past_line_content ); |
---|
100 | const bool filter_out = |
---|
101 | regex_search( line_start, past_line_content |
---|
102 | , m, boost::regex(one_line_comment_line) ) |
---|
103 | && string::npos == whole_line.find('\"') |
---|
104 | && string::npos == whole_line.find("*/") |
---|
105 | ; |
---|
106 | |
---|
107 | if (!filter_out) { |
---|
108 | |
---|
109 | ++m_errors; |
---|
110 | error( library_name, full_path, string(name()) |
---|
111 | + " violation of Boost min/max guidelines on line " |
---|
112 | + boost::lexical_cast<string>( line_number ) ); |
---|
113 | } |
---|
114 | |
---|
115 | } |
---|
116 | } |
---|
117 | |
---|
118 | } // namespace inspect |
---|
119 | } // namespace boost |
---|
120 | |
---|