| // inspect program ---------------------------------------------------------// |
| |
| // Copyright Beman Dawes 2002. |
| // Copyright Rene Rivera 2004-2006. |
| // Copyright Gennaro Prota 2006. |
| |
| // 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) |
| |
| // This program recurses through sub-directories looking for various problems. |
| // It contains some Boost specific features, like ignoring "CVS" and "bin", |
| // and the code that identifies library names assumes the Boost directory |
| // structure. |
| |
| // See http://www.boost.org/tools/inspect/ for more information. |
| |
| |
| #include <vector> |
| #include <list> |
| #include <algorithm> |
| #include <cstring> |
| |
| #include "boost/shared_ptr.hpp" |
| #include "boost/lexical_cast.hpp" |
| #include "boost/filesystem/operations.hpp" |
| #include "boost/filesystem/fstream.hpp" |
| |
| #include "time_string.hpp" |
| |
| #include "inspector.hpp" |
| |
| // the inspectors |
| #include "copyright_check.hpp" |
| #include "crlf_check.hpp" |
| #include "end_check.hpp" |
| #include "license_check.hpp" |
| #include "link_check.hpp" |
| #include "path_name_check.hpp" |
| #include "tab_check.hpp" |
| #include "ascii_check.hpp" |
| #include "apple_macro_check.hpp" |
| #include "minmax_check.hpp" |
| #include "unnamed_namespace_check.hpp" |
| |
| #include "cvs_iterator.hpp" |
| |
| #include "boost/test/included/prg_exec_monitor.hpp" |
| |
| namespace fs = boost::filesystem; |
| |
| using namespace boost::inspect; |
| |
| namespace |
| { |
| class inspector_element |
| { |
| typedef boost::shared_ptr< boost::inspect::inspector > inspector_ptr; |
| |
| public: |
| inspector_ptr inspector; |
| explicit |
| inspector_element( boost::inspect::inspector * p ) : inspector(p) {} |
| }; |
| |
| typedef std::list< inspector_element > inspector_list; |
| |
| long file_count = 0; |
| long directory_count = 0; |
| long error_count = 0; |
| const int max_offenders = 5; // maximum "worst offenders" to display |
| |
| boost::inspect::string_set content_signatures; |
| |
| struct error_msg |
| { |
| string library; |
| string rel_path; |
| string msg; |
| int line_number; |
| |
| bool operator<( const error_msg & rhs ) const |
| { |
| if ( library < rhs.library ) return true; |
| if ( library > rhs.library ) return false; |
| if ( rel_path < rhs.rel_path ) return true; |
| if ( rel_path > rhs.rel_path ) return false; |
| if ( line_number < rhs.line_number ) return true; |
| if ( line_number > rhs.line_number ) return false; |
| return msg < rhs.msg; |
| } |
| }; |
| |
| typedef std::vector< error_msg > error_msg_vector; |
| error_msg_vector msgs; |
| |
| struct lib_error_count |
| { |
| int error_count; |
| string library; |
| |
| bool operator<( const lib_error_count & rhs ) const |
| { |
| return error_count > rhs.error_count; |
| } |
| }; |
| |
| typedef std::vector< lib_error_count > lib_error_count_vector; |
| lib_error_count_vector libs; |
| |
| // get info (as a string) if inspect_root is svn working copy --------------// |
| |
| void extract_info( fs::ifstream & entries_file, string & rev, string & repos ) |
| { |
| std::getline( entries_file, rev ); |
| std::getline( entries_file, rev ); |
| std::getline( entries_file, rev ); |
| std::getline( entries_file, rev ); // revision number as a string |
| std::getline( entries_file, repos ); // repository as a string |
| } |
| |
| string info( const fs::path & inspect_root ) |
| { |
| string rev( "?" ); |
| string repos( "unknown" ); |
| fs::path entries( inspect_root / ".svn" / "entries" ); |
| fs::ifstream entries_file( entries ); |
| if ( entries_file ) |
| extract_info( entries_file, rev, repos ); |
| else |
| { |
| entries = inspect_root / ".." / "svn_info" / ".svn" / "entries"; |
| fs::ifstream entries_file( entries ); |
| if ( entries_file ) |
| extract_info( entries_file, rev, repos ); |
| } |
| return repos + " at revision " + rev; |
| } |
| |
| // visit_predicate (determines which directories are visited) --------------// |
| |
| typedef bool(*pred_type)(const path&); |
| |
| bool visit_predicate( const path & pth ) |
| { |
| string local( boost::inspect::relative_to( pth, fs::initial_path() ) ); |
| string leaf( pth.leaf() ); |
| return |
| // so we can inspect a checkout |
| leaf != "CVS" |
| // don't look at binaries |
| && leaf != "bin" |
| && leaf != "bin.v2" |
| // this really out of our hands |
| && leaf != "jam_src" |
| && local.find("tools/jam/src") != 0 |
| && local.find("tools/build/v2/engine") != 0 |
| // too many issues with generated HTML files |
| && leaf != "status" |
| // no point in checking doxygen xml output |
| && local.find("doc/xml") != 0 |
| // ignore some web files |
| && leaf != ".htaccess" |
| // ignore svn files: |
| && leaf != ".svn" |
| // ignore other version control files |
| && leaf != ".git" |
| && leaf != ".bzr" |
| // ignore OS X directory info files: |
| && leaf != ".DS_Store" |
| ; |
| } |
| |
| // library_from_content ----------------------------------------------------// |
| |
| string library_from_content( const string & content ) |
| { |
| const string unknown_library ( "unknown" ); |
| const string lib_root ( "www.boost.org/libs/" ); |
| string::size_type pos( content.find( lib_root ) ); |
| |
| string lib = unknown_library; |
| |
| if ( pos != string::npos ) { |
| |
| pos += lib_root.length(); |
| |
| const char delims[] = " " // space and... |
| "/\n\r\t"; |
| |
| string::size_type n = content.find_first_of( string(delims), pos ); |
| if (n != string::npos) |
| lib = string(content, pos, n - pos); |
| |
| } |
| |
| return lib; |
| } |
| |
| // find_signature ----------------------------------------------------------// |
| |
| bool find_signature( const path & file_path, |
| const boost::inspect::string_set & signatures ) |
| { |
| string name( file_path.leaf() ); |
| if ( signatures.find( name ) == signatures.end() ) |
| { |
| string::size_type pos( name.rfind( '.' ) ); |
| if ( pos == string::npos |
| || signatures.find( name.substr( pos ) ) |
| == signatures.end() ) return false; |
| } |
| return true; |
| } |
| |
| // load_content ------------------------------------------------------------// |
| |
| void load_content( const path & file_path, string & target ) |
| { |
| target = ""; |
| |
| if ( !find_signature( file_path, content_signatures ) ) return; |
| |
| fs::ifstream fin( file_path, std::ios_base::in|std::ios_base::binary ); |
| if ( !fin ) |
| throw string( "could not open input file: " ) + file_path.string(); |
| std::getline( fin, target, '\0' ); // read the whole file |
| } |
| |
| // check -------------------------------------------------------------------// |
| |
| void check( const string & lib, |
| const path & pth, const string & content, const inspector_list & insp_list ) |
| { |
| // invoke each inspector |
| for ( inspector_list::const_iterator itr = insp_list.begin(); |
| itr != insp_list.end(); ++itr ) |
| { |
| itr->inspector->inspect( lib, pth ); // always call two-argument form |
| if ( find_signature( pth, itr->inspector->signatures() ) ) |
| { |
| itr->inspector->inspect( lib, pth, content ); |
| } |
| } |
| } |
| |
| // visit_all ---------------------------------------------------------------// |
| |
| template< class DirectoryIterator > |
| void visit_all( const string & lib, |
| const path & dir_path, const inspector_list & insps ) |
| { |
| static DirectoryIterator end_itr; |
| ++directory_count; |
| |
| for ( DirectoryIterator itr( dir_path ); itr != end_itr; ++itr ) |
| { |
| |
| if ( fs::is_directory( *itr ) ) |
| { |
| if ( visit_predicate( *itr ) ) |
| { |
| string cur_lib( boost::inspect::impute_library( *itr ) ); |
| check( cur_lib, *itr, "", insps ); |
| visit_all<DirectoryIterator>( cur_lib, *itr, insps ); |
| } |
| } |
| else |
| { |
| ++file_count; |
| string content; |
| load_content( *itr, content ); |
| check( lib.empty() |
| ? library_from_content( content ) : lib |
| , *itr, content, insps ); |
| } |
| } |
| } |
| |
| // display -----------------------------------------------------------------// |
| |
| enum display_format_type |
| { |
| display_html, display_text |
| } |
| display_format = display_html; |
| |
| enum display_mode_type |
| { |
| display_full, display_brief |
| } |
| display_mode = display_full; |
| |
| // display_summary_helper --------------------------------------------------// |
| |
| void display_summary_helper( const string & current_library, int err_count ) |
| { |
| if (display_text == display_format) |
| { |
| std::cout << " " << current_library << " (" << err_count << ")\n"; |
| } |
| else |
| { |
| std::cout |
| << " <a href=\"#" |
| << current_library // what about malformed for URI refs? [gps] |
| << "\">" << current_library |
| << "</a> (" |
| << err_count << ")<br>\n"; |
| } |
| } |
| |
| // display_summary ---------------------------------------------------------// |
| |
| void display_summary() |
| { |
| if (display_text == display_format) |
| { |
| std::cout << "Summary:\n"; |
| } |
| else |
| { |
| std::cout << |
| "<h2>Summary</h2>\n" |
| "<blockquote>\n" |
| ; |
| } |
| |
| string current_library( msgs.begin()->library ); |
| int err_count = 0; |
| for ( error_msg_vector::iterator itr ( msgs.begin() ); |
| itr != msgs.end(); ++itr ) |
| { |
| if ( current_library != itr->library ) |
| { |
| display_summary_helper( current_library, err_count ); |
| current_library = itr->library; |
| err_count = 0; |
| } |
| ++err_count; |
| } |
| display_summary_helper( current_library, err_count ); |
| |
| if (display_text == display_format) |
| std::cout << "\n"; |
| else |
| std::cout << "</blockquote>\n"; |
| } |
| |
| |
| // display_details ---------------------------------------------------------// |
| |
| void display_details() |
| { |
| // gps - review this |
| |
| if (display_text == display_format) |
| { |
| // display error messages with group indication |
| error_msg current; |
| string sep; |
| for ( error_msg_vector::iterator itr ( msgs.begin() ); |
| itr != msgs.end(); ++itr ) |
| { |
| if ( current.library != itr->library ) |
| { |
| if ( display_full == display_mode ) |
| std::cout << "\n|" << itr->library << "|\n"; |
| else |
| std::cout << "\n\n|" << itr->library << '|'; |
| } |
| |
| if ( current.library != itr->library |
| || current.rel_path != itr->rel_path ) |
| { |
| if ( display_full == display_mode ) |
| { |
| std::cout << " " << itr->rel_path << ":\n"; |
| } |
| else |
| { |
| path current_rel_path(current.rel_path); |
| path this_rel_path(itr->rel_path); |
| if (current_rel_path.branch_path() != this_rel_path.branch_path()) |
| { |
| std::cout << "\n " << this_rel_path.branch_path().string() << '/'; |
| } |
| std::cout << "\n " << this_rel_path.leaf() << ':'; |
| } |
| } |
| if ( current.library != itr->library |
| || current.rel_path != itr->rel_path |
| || current.msg != itr->msg ) |
| { |
| const string m = itr->msg; |
| |
| if ( display_full == display_mode ) |
| std::cout << " " << m << '\n'; |
| else |
| std::cout << ' ' << m; |
| } |
| current.library = itr->library; |
| current.rel_path = itr->rel_path; |
| current.msg = itr->msg; |
| } |
| std::cout << "\n"; |
| } |
| else // html |
| { |
| // display error messages with group indication |
| error_msg current; |
| bool first_sep = true; |
| bool first = true; |
| for ( error_msg_vector::iterator itr ( msgs.begin() ); |
| itr != msgs.end(); ++itr ) |
| { |
| if ( current.library != itr->library ) |
| { |
| if ( !first ) std::cout << "</pre>\n"; |
| std::cout << "\n<h3><a name=\"" << itr->library |
| << "\">" << itr->library << "</a></h3>\n<pre>"; |
| } |
| if ( current.library != itr->library |
| || current.rel_path != itr->rel_path ) |
| { |
| std::cout << "\n"; |
| std::cout << itr->rel_path; |
| first_sep = true; |
| } |
| if ( current.library != itr->library |
| || current.rel_path != itr->rel_path |
| || current.msg != itr->msg ) |
| { |
| std::string sep; |
| if (first_sep) |
| if (itr->line_number) sep = ":<br> "; |
| else sep = ": "; |
| else |
| if (itr->line_number) sep = "<br> "; |
| else sep = ", "; |
| |
| // print the message |
| if (itr->line_number) |
| std::cout << sep << "(line " << itr->line_number << ") " << itr->msg; |
| else std::cout << sep << itr->msg; |
| |
| first_sep = false; |
| } |
| current.library = itr->library; |
| current.rel_path = itr->rel_path; |
| current.msg = itr->msg; |
| first = false; |
| } |
| std::cout << "</pre>\n"; |
| } |
| } |
| |
| |
| // worst_offenders_count_helper --------------------------------------------------// |
| |
| void worst_offenders_count_helper( const string & current_library, int err_count ) |
| { |
| lib_error_count lec; |
| lec.library = current_library; |
| lec.error_count = err_count; |
| libs.push_back( lec ); |
| } |
| // worst_offenders_count -----------------------------------------------------// |
| |
| void worst_offenders_count() |
| { |
| if ( msgs.empty() ) |
| { |
| return; |
| } |
| string current_library( msgs.begin()->library ); |
| int err_count = 0; |
| for ( error_msg_vector::iterator itr ( msgs.begin() ); |
| itr != msgs.end(); ++itr ) |
| { |
| if ( current_library != itr->library ) |
| { |
| worst_offenders_count_helper( current_library, err_count ); |
| current_library = itr->library; |
| err_count = 0; |
| } |
| ++err_count; |
| } |
| worst_offenders_count_helper( current_library, err_count ); |
| } |
| |
| // display_worst_offenders -------------------------------------------------// |
| |
| void display_worst_offenders() |
| { |
| if (display_text == display_format) |
| { |
| std::cout << "Worst Offenders:\n"; |
| } |
| else |
| { |
| std::cout << |
| "<h2>Worst Offenders</h2>\n" |
| "<blockquote>\n" |
| ; |
| } |
| |
| int display_count = 0; |
| int last_error_count = 0; |
| for ( lib_error_count_vector::iterator itr ( libs.begin() ); |
| itr != libs.end() |
| && (display_count < max_offenders |
| || itr->error_count == last_error_count); |
| ++itr, ++display_count ) |
| { |
| if (display_text == display_format) |
| { |
| std::cout << itr->library << " " << itr->error_count << "\n"; |
| } |
| else |
| { |
| std::cout |
| << " <a href=\"#" |
| << itr->library |
| << "\">" << itr->library |
| << "</a> (" |
| << itr->error_count << ")<br>\n"; |
| } |
| last_error_count = itr->error_count; |
| } |
| |
| if (display_text == display_format) |
| std::cout << "\n"; |
| else |
| std::cout << "</blockquote>\n"; |
| } |
| |
| |
| const char * options() |
| { |
| return |
| " -license\n" |
| " -copyright\n" |
| " -crlf\n" |
| " -end\n" |
| " -link\n" |
| " -path_name\n" |
| " -tab\n" |
| " -ascii\n" |
| " -apple_macro\n" |
| " -minmax\n" |
| " -unnamed\n" |
| " default is all checks on; otherwise options specify desired checks" |
| "\n"; |
| } |
| |
| const char * doctype_declaration() |
| { |
| return |
| "<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Strict//EN\"\n" |
| "\"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd\">" |
| ; |
| } |
| |
| std::string validator_link(const std::string & text) |
| { |
| return |
| // with link to validation service |
| "<a href=\"http://validator.w3.org/check?uri=referer\">" |
| + text |
| + "</a>" |
| ; |
| } |
| |
| } // unnamed namespace |
| |
| namespace boost |
| { |
| namespace inspect |
| { |
| |
| // line_break --------------------------------------------------------------// |
| |
| const char * line_break() |
| { |
| return display_format ? "\n" : "<br>\n"; |
| } |
| |
| |
| // register_signature ------------------------------------------------------// |
| |
| void inspector::register_signature( const string & signature ) |
| { |
| m_signatures.insert( signature ); |
| content_signatures.insert( signature ); |
| } |
| |
| // error -------------------------------------------------------------------// |
| |
| void inspector::error( const string & library_name, |
| const path & full_path, const string & msg, int line_number ) |
| { |
| ++error_count; |
| error_msg err_msg; |
| err_msg.library = library_name; |
| err_msg.rel_path = relative_to( full_path, fs::initial_path() ); |
| err_msg.msg = msg; |
| err_msg.line_number = line_number; |
| msgs.push_back( err_msg ); |
| |
| // std::cout << library_name << ": " |
| // << full_path.string() << ": " |
| // << msg << '\n'; |
| |
| } |
| |
| source_inspector::source_inspector() |
| { |
| // C/C++ source code... |
| register_signature( ".c" ); |
| register_signature( ".cpp" ); |
| register_signature( ".css" ); |
| register_signature( ".cxx" ); |
| register_signature( ".h" ); |
| register_signature( ".hpp" ); |
| register_signature( ".hxx" ); |
| register_signature( ".inc" ); |
| register_signature( ".ipp" ); |
| |
| // Boost.Build BJam source code... |
| register_signature( "Jamfile" ); |
| register_signature( ".jam" ); |
| register_signature( ".v2" ); |
| |
| // Other scripts; Python, shell, autoconfig, etc. |
| register_signature( "configure.in" ); |
| register_signature( "GNUmakefile" ); |
| register_signature( "Makefile" ); |
| register_signature( ".bat" ); |
| register_signature( ".mak" ); |
| register_signature( ".pl" ); |
| register_signature( ".py" ); |
| register_signature( ".sh" ); |
| |
| // Hypertext, Boost.Book, and other text... |
| register_signature( "news" ); |
| register_signature( "readme" ); |
| register_signature( "todo" ); |
| register_signature( "NEWS" ); |
| register_signature( "README" ); |
| register_signature( "TODO" ); |
| register_signature( ".boostbook" ); |
| register_signature( ".htm" ); |
| register_signature( ".html" ); |
| register_signature( ".rst" ); |
| register_signature( ".sgml" ); |
| register_signature( ".shtml" ); |
| register_signature( ".txt" ); |
| register_signature( ".xml" ); |
| register_signature( ".xsd" ); |
| register_signature( ".xsl" ); |
| register_signature( ".qbk" ); |
| } |
| |
| hypertext_inspector::hypertext_inspector() |
| { |
| register_signature( ".htm" ); |
| register_signature( ".html" ); |
| register_signature( ".shtml" ); |
| } |
| |
| // impute_library ----------------------------------------------------------// |
| |
| // may return an empty string [gps] |
| string impute_library( const path & full_dir_path ) |
| { |
| path relative( relative_to( full_dir_path, fs::initial_path() ), |
| fs::no_check ); |
| if ( relative.empty() ) return "boost-root"; |
| string first( *relative.begin() ); |
| string second = // borland 5.61 requires op= |
| ++relative.begin() == relative.end() |
| ? string() : *++relative.begin(); |
| |
| if ( first == "boost" ) |
| return second; |
| |
| return (( first == "libs" || first == "tools" ) && !second.empty()) |
| ? second : first; |
| } |
| |
| } // namespace inspect |
| } // namespace boost |
| |
| // cpp_main() --------------------------------------------------------------// |
| |
| int cpp_main( int argc_param, char * argv_param[] ) |
| { |
| // <hack> for the moment, let's be on the safe side |
| // and ensure we don't modify anything being pointed to; |
| // then we'll do some cleanup here |
| int argc = argc_param; |
| const char* const * argv = &argv_param[0]; |
| |
| if ( argc > 1 && (std::strcmp( argv[1], "-help" ) == 0 |
| || std::strcmp( argv[1], "--help" ) == 0 ) ) |
| { |
| std::clog << "Usage: inspect [-cvs] [-text] [-brief] [options...]\n\n" |
| " Options:\n" |
| << options() << '\n'; |
| return 0; |
| } |
| |
| bool license_ck = true; |
| bool copyright_ck = true; |
| bool crlf_ck = true; |
| bool end_ck = true; |
| bool link_ck = true; |
| bool path_name_ck = true; |
| bool tab_ck = true; |
| bool ascii_ck = true; |
| bool apple_ok = true; |
| bool minmax_ck = true; |
| bool unnamed_ck = true; |
| bool cvs = false; |
| |
| if ( argc > 1 && std::strcmp( argv[1], "-cvs" ) == 0 ) |
| { |
| cvs = true; |
| --argc; ++argv; |
| } |
| |
| if ( argc > 1 && std::strcmp( argv[1], "-text" ) == 0 ) |
| { |
| display_format = display_text; |
| --argc; ++argv; |
| } |
| |
| if ( argc > 1 && std::strcmp( argv[1], "-brief" ) == 0 ) |
| { |
| display_mode = display_brief; |
| --argc; ++argv; |
| } |
| |
| if ( argc > 1 && *argv[1] == '-' ) |
| { |
| license_ck = false; |
| copyright_ck = false; |
| crlf_ck = false; |
| end_ck = false; |
| link_ck = false; |
| path_name_ck = false; |
| tab_ck = false; |
| ascii_ck = false; |
| apple_ok = false; |
| minmax_ck = false; |
| unnamed_ck = false; |
| } |
| |
| bool invalid_options = false; |
| for(; argc > 1; --argc, ++argv ) |
| { |
| if ( std::strcmp( argv[1], "-license" ) == 0 ) |
| license_ck = true; |
| else if ( std::strcmp( argv[1], "-copyright" ) == 0 ) |
| copyright_ck = true; |
| else if ( std::strcmp( argv[1], "-crlf" ) == 0 ) |
| crlf_ck = true; |
| else if ( std::strcmp( argv[1], "-end" ) == 0 ) |
| end_ck = true; |
| else if ( std::strcmp( argv[1], "-link" ) == 0 ) |
| link_ck = true; |
| else if ( std::strcmp( argv[1], "-path_name" ) == 0 ) |
| path_name_ck = true; |
| else if ( std::strcmp( argv[1], "-tab" ) == 0 ) |
| tab_ck = true; |
| else if ( std::strcmp( argv[1], "-ascii" ) == 0 ) |
| ascii_ck = true; |
| else if ( std::strcmp( argv[1], "-apple_macro" ) == 0 ) |
| apple_ok = true; |
| else if ( std::strcmp( argv[1], "-minmax" ) == 0 ) |
| minmax_ck = true; |
| else if ( std::strcmp( argv[1], "-unnamed" ) == 0 ) |
| unnamed_ck = true; |
| else |
| { |
| std::cerr << "unknown option: " << argv[1] << '\n'; |
| invalid_options = true; |
| } |
| } |
| if ( invalid_options ) { |
| std::cerr << "\nvalid options are:\n" |
| << options(); |
| return 1; |
| } |
| |
| string inspector_keys; |
| fs::initial_path(); |
| |
| |
| { // begin reporting block |
| |
| // since this is in its own block; reporting will happen |
| // automatically, from each registered inspector, when |
| // leaving, due to destruction of the inspector_list object |
| inspector_list inspectors; |
| |
| if ( license_ck ) |
| inspectors.push_back( inspector_element( new boost::inspect::license_check ) ); |
| if ( copyright_ck ) |
| inspectors.push_back( inspector_element( new boost::inspect::copyright_check ) ); |
| if ( crlf_ck ) |
| inspectors.push_back( inspector_element( new boost::inspect::crlf_check ) ); |
| if ( end_ck ) |
| inspectors.push_back( inspector_element( new boost::inspect::end_check ) ); |
| if ( link_ck ) |
| inspectors.push_back( inspector_element( new boost::inspect::link_check ) ); |
| if ( path_name_ck ) |
| inspectors.push_back( inspector_element( new boost::inspect::file_name_check ) ); |
| if ( tab_ck ) |
| inspectors.push_back( inspector_element( new boost::inspect::tab_check ) ); |
| if ( ascii_ck ) |
| inspectors.push_back( inspector_element( new boost::inspect::ascii_check ) ); |
| if ( apple_ok ) |
| inspectors.push_back( inspector_element( new boost::inspect::apple_macro_check ) ); |
| if ( minmax_ck ) |
| inspectors.push_back( inspector_element( new boost::inspect::minmax_check ) ); |
| if ( unnamed_ck ) |
| inspectors.push_back( inspector_element( new boost::inspect::unnamed_namespace_check ) ); |
| |
| // perform the actual inspection, using the requested type of iteration |
| if ( cvs ) |
| visit_all<hack::cvs_iterator>( "boost-root", |
| fs::initial_path(), inspectors ); |
| else |
| visit_all<fs::directory_iterator>( "boost-root", |
| fs::initial_path(), inspectors ); |
| |
| // close |
| for ( inspector_list::iterator itr = inspectors.begin(); |
| itr != inspectors.end(); ++itr ) |
| { |
| itr->inspector->close(); |
| } |
| |
| string run_date ( "n/a" ); |
| boost::time_string( run_date ); |
| |
| if (display_text == display_format) |
| { |
| std::cout |
| << |
| "Boost Inspection Report\n" |
| "Run Date: " << run_date << "\n" |
| "\n" |
| "An inspection program <http://www.boost.org/tools/inspect/index.html>\n" |
| "checks each file in the current Boost CVS for various problems,\n" |
| "generating an HTML page as output.\n" |
| "\n" |
| ; |
| |
| std::cout |
| << "Totals:\n" |
| << " " << file_count << " files scanned\n" |
| << " " << directory_count << " directories scanned (including root)\n" |
| << " " << error_count << " problems reported\n" |
| << '\n' |
| ; |
| } |
| else |
| { |
| // |
| std::cout << doctype_declaration() << '\n'; |
| |
| std::cout |
| << "<html>\n" |
| "<head>\n" |
| "<style> body { font-family: sans-serif; } </style>\n" |
| "<title>Boost Inspection Report</title>\n" |
| "</head>\n" |
| |
| "<body>\n" |
| // we should not use a table, of course [gps] |
| "<table>\n" |
| "<tr>\n" |
| "<td><img src=\"http://www.boost.org/boost.png\" alt=\"Boost logo\" />" |
| "</td>\n" |
| "<td>\n" |
| "<h1>Boost Inspection Report</h1>\n" |
| "<b>Run Date:</b> " << run_date << "\n" |
| //" / " << validator_link( "validate me" ) << " /\n" |
| "</td>\n" |
| "</tr>\n" |
| "</table>\n" |
| |
| "<p>This report is generated by an <a href=\"http://www.boost.org/tools/inspect/index.html\">inspection\n" |
| "program</a> that checks files for the problems noted below.</p>\n" |
| ; |
| std::cout |
| << "<p>The files checked were from " |
| << info( fs::initial_path() ) |
| << ".</p>\n"; |
| |
| |
| std::cout |
| << "<h2>Totals</h2>\n" |
| << file_count << " files scanned<br>\n" |
| << directory_count << " directories scanned (including root)<br>\n" |
| << error_count << " problems reported\n<p>"; |
| } |
| |
| for ( inspector_list::iterator itr = inspectors.begin(); |
| itr != inspectors.end(); ++itr ) |
| { |
| |
| inspector_keys += static_cast<string>(" ") |
| + itr->inspector->name() |
| + ' ' + itr->inspector->desc() |
| + line_break() |
| ; |
| } |
| |
| if (display_text == display_format) |
| std::cout << "\nProblem counts:\n"; |
| else |
| std::cout << "\n<h2>Problem counts</h2>\n<blockquote><p>\n" ; |
| |
| } // end of block: starts reporting |
| |
| if (display_text == display_format) |
| std::cout << "\n" ; |
| else |
| std::cout << "</blockquote>\n"; |
| |
| std::sort( msgs.begin(), msgs.end() ); |
| |
| worst_offenders_count(); |
| std::stable_sort( libs.begin(), libs.end() ); |
| |
| if ( !libs.empty() ) |
| display_worst_offenders(); |
| |
| if ( !msgs.empty() ) |
| { |
| display_summary(); |
| |
| if (display_text == display_format) |
| { |
| std::cout << "Details:\n" << inspector_keys; |
| } |
| else |
| { |
| std::cout << "<h2>Details</h2>\n" << inspector_keys; |
| } |
| display_details(); |
| } |
| |
| if (display_text == display_format) |
| { |
| std::cout << "\n\n" ; |
| } |
| else |
| { |
| std::cout |
| << "</body>\n" |
| "</html>\n"; |
| } |
| |
| return 0; |
| } |