1 // apple_macro_check implementation ------------------------------------------------//
3 // Copyright Marshall Clow 2007.
4 // Based on the tab-check checker by Beman Dawes
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)
10 #include "apple_macro_check.hpp"
12 #include "boost/regex.hpp"
13 #include "boost/lexical_cast.hpp"
14 #include "boost/filesystem/operations.hpp"
16 namespace fs
= boost::filesystem
;
20 boost::regex
apple_macro_regex(
22 "^\\s*#\\s*undef\\s*" // # undef
23 "\\b(check|verify|require|check_error)\\b" // followed by apple macro name, whole word
27 "//[^\\n]*" // single line comments (//)
29 "/\\*.*?\\*/" // multi line comments (/**/)
31 "\"(?:\\\\\\\\|\\\\\"|[^\"])*\"" // string literals
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
38 , boost::regex::normal
);
40 } // unnamed namespace
47 apple_macro_check::apple_macro_check() : m_files_with_errors(0)
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" );
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
63 if (contents
.find( "boostinspect:" "naapple_macros" ) != string::npos
) return;
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;
70 boost::sregex_iterator
cur(contents
.begin(), contents
.end(), apple_macro_regex
), end
;
74 for( ; cur
!= end
; ++cur
/*, ++m_files_with_errors*/ )
77 if(!(*cur
)[3].matched
)
79 string::const_iterator it
= contents
.begin();
80 string::const_iterator match_it
= (*cur
)[0].first
;
82 string::const_iterator line_start
= it
;
84 string::size_type line_number
= 1;
85 for ( ; it
!= match_it
; ++it
) {
86 if (string::traits_type::eq(*it
, '\n')) {
88 line_start
= it
+ 1; // could be end()
93 error( library_name
, full_path
,
94 "Apple macro clash: " + std::string((*cur
)[0].first
, (*cur
)[0].second
-1),
99 ++m_files_with_errors
;
102 } // namespace inspect