1 // assert_macro_check implementation ------------------------------------------------// 2 3 // Copyright Eric Niebler 2010. 4 // Based on the assert_macro_check checker by Marshall Clow 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 "assert_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 assert_macro_regex( 21 "(" 22 "^\\s*#\\s*undef\\s*" // # undef 23 "\\b(assert)\\b" // followed by assert macro, 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(assert)\\b" // assert macro, 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 { assert_macro_check()47 assert_macro_check::assert_macro_check() 48 : m_files_with_errors(0) 49 , m_from_boost_root( 50 fs::exists(search_root_path() / "boost") && 51 fs::exists(search_root_path() / "libs")) 52 { 53 register_signature( ".c" ); 54 register_signature( ".cpp" ); 55 register_signature( ".cxx" ); 56 register_signature( ".h" ); 57 register_signature( ".hpp" ); 58 register_signature( ".hxx" ); 59 register_signature( ".ipp" ); 60 } 61 inspect(const string & library_name,const path & full_path,const string & contents)62 void assert_macro_check::inspect( 63 const string & library_name, 64 const path & full_path, // example: c:/foo/boost/filesystem/path.hpp 65 const string & contents ) // contents of file to be inspected 66 { 67 if (contents.find( "boostinspect:" "naassert_macro" ) != string::npos) 68 return; 69 70 // Check files iff (a) they are in the boost directory, or (b) they 71 // are in the src directory under libs. 72 if (m_from_boost_root) { 73 path relative( relative_to( full_path, search_root_path() ) ); 74 path::const_iterator pbeg = relative.begin(), pend = relative.end(); 75 if (pbeg != std::find(pbeg, pend, "boost") && 76 !(pbeg == std::find(pbeg, pend, "libs") && pend != std::find(pbeg, pend, "src"))) 77 return; 78 } 79 80 long errors = 0; 81 boost::sregex_iterator cur(contents.begin(), contents.end(), assert_macro_regex), end; 82 for( ; cur != end; ++cur ) 83 { 84 if(!(*cur)[3].matched) 85 { 86 string::const_iterator it = contents.begin(); 87 string::const_iterator match_it = (*cur)[0].first; 88 89 string::const_iterator line_start = it; 90 91 string::size_type line_number = 1; 92 for ( ; it != match_it; ++it) { 93 if (string::traits_type::eq(*it, '\n')) { 94 ++line_number; 95 line_start = it + 1; // could be end() 96 } 97 } 98 99 ++errors; 100 error( library_name, full_path, "C-style assert macro on line " 101 + boost::lexical_cast<string>( line_number ) ); 102 } 103 } 104 if(errors > 0) 105 ++m_files_with_errors; 106 } 107 } // namespace inspect 108 } // namespace boost 109 110 111