// assert_macro_check implementation ------------------------------------------------// // Copyright Eric Niebler 2010. // Based on the assert_macro_check checker by Marshall Clow // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) #include "assert_macro_check.hpp" #include #include "boost/regex.hpp" #include "boost/lexical_cast.hpp" #include "boost/filesystem/operations.hpp" namespace fs = boost::filesystem; namespace { boost::regex assert_macro_regex( "(" "^\\s*#\\s*undef\\s*" // # undef "\\b(assert)\\b" // followed by assert macro, whole word ")" "|" // or (ignored) "(" "//[^\\n]*" // single line comments (//) "|" "/\\*.*?\\*/" // multi line comments (/**/) "|" "\"(?:\\\\\\\\|\\\\\"|[^\"])*\"" // string literals ")" "|" // or "(" "\\b(assert)\\b" // assert macro, whole word "\\s*\\(" // followed by 0 or more spaces and an opening paren ")" , boost::regex::normal); } // unnamed namespace namespace boost { namespace inspect { assert_macro_check::assert_macro_check() : m_files_with_errors(0) , m_from_boost_root( fs::exists(search_root_path() / "boost") && fs::exists(search_root_path() / "libs")) { register_signature( ".c" ); register_signature( ".cpp" ); register_signature( ".cxx" ); register_signature( ".h" ); register_signature( ".hpp" ); register_signature( ".hxx" ); register_signature( ".ipp" ); } void assert_macro_check::inspect( const string & library_name, const path & full_path, // example: c:/foo/boost/filesystem/path.hpp const string & contents ) // contents of file to be inspected { if (contents.find( "boostinspect:" "naassert_macro" ) != string::npos) return; // Check files iff (a) they are in the boost directory, or (b) they // are in the src directory under libs. if (m_from_boost_root) { path relative( relative_to( full_path, search_root_path() ) ); path::const_iterator pbeg = relative.begin(), pend = relative.end(); if (pbeg != std::find(pbeg, pend, "boost") && !(pbeg == std::find(pbeg, pend, "libs") && pend != std::find(pbeg, pend, "src"))) return; } long errors = 0; boost::sregex_iterator cur(contents.begin(), contents.end(), assert_macro_regex), end; for( ; cur != end; ++cur ) { if(!(*cur)[3].matched) { string::const_iterator it = contents.begin(); string::const_iterator match_it = (*cur)[0].first; string::const_iterator line_start = it; string::size_type line_number = 1; for ( ; it != match_it; ++it) { if (string::traits_type::eq(*it, '\n')) { ++line_number; line_start = it + 1; // could be end() } } ++errors; error( library_name, full_path, "C-style assert macro on line " + boost::lexical_cast( line_number ) ); } } if(errors > 0) ++m_files_with_errors; } } // namespace inspect } // namespace boost