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