• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 //  apple_macro_check implementation  ------------------------------------------------//
2 
3 //  Copyright Marshall Clow 2007.
4 //  Based on the tab-check checker by Beman Dawes
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 #include "apple_macro_check.hpp"
11 #include <functional>
12 #include "boost/regex.hpp"
13 #include "boost/lexical_cast.hpp"
14 #include "boost/filesystem/operations.hpp"
15 
16 namespace fs = boost::filesystem;
17 
18 namespace
19 {
20   boost::regex apple_macro_regex(
21     "("
22     "^\\s*#\\s*undef\\s*" // # undef
23     "\\b(check|verify|require|check_error)\\b"     // followed by apple macro name, whole word
24     ")"
25     "|"                   // or (ignored)
26     "("
27     "//[^\\n]*"           // single line comments (//)
28     "|"
29     "/\\*.*?\\*/"         // multi line comments (/**/)
30     "|"
31     "\"(?:\\\\\\\\|\\\\\"|[^\"])*\"" // string literals
32     ")"
33     "|"                   // or
34     "("
35     "\\b(check|verify|require|check_error)\\b" // apple macro name, whole word
36     "\\s*\\("         // followed by 0 or more spaces and an opening paren
37     ")"
38     , boost::regex::normal);
39 
40 } // unnamed namespace
41 
42 
43 namespace boost
44 {
45   namespace inspect
46   {
apple_macro_check()47    apple_macro_check::apple_macro_check() : m_files_with_errors(0)
48    {
49      register_signature( ".c" );
50      register_signature( ".cpp" );
51      register_signature( ".cxx" );
52      register_signature( ".h" );
53      register_signature( ".hpp" );
54      register_signature( ".hxx" );
55      register_signature( ".ipp" );
56    }
57 
inspect(const string & library_name,const path & full_path,const string & contents)58    void apple_macro_check::inspect(
59       const string & library_name,
60       const path & full_path,   // example: c:/foo/boost/filesystem/path.hpp
61       const string & contents )     // contents of file to be inspected
62     {
63       if (contents.find( "boostinspect:" "naapple_macros" ) != string::npos) return;
64 
65       // Only check files in the boost directory, as we can avoid including the
66       // apple test headers elsewhere.
67       path relative( relative_to( full_path, search_root_path() ) );
68       if ( relative.empty() || *relative.begin() != "boost") return;
69 
70       boost::sregex_iterator cur(contents.begin(), contents.end(), apple_macro_regex), end;
71 
72       long errors = 0;
73 
74       for( ; cur != end; ++cur /*, ++m_files_with_errors*/ )
75       {
76 
77         if(!(*cur)[3].matched)
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           ++errors;
93           error( library_name, full_path,
94             "Apple macro clash: " + std::string((*cur)[0].first, (*cur)[0].second-1),
95             line_number );
96         }
97       }
98       if(errors > 0) {
99         ++m_files_with_errors;
100       }
101     }
102   } // namespace inspect
103 } // namespace boost
104 
105 
106