| 1 | // inspect program ---------------------------------------------------------// |
|---|
| 2 | |
|---|
| 3 | // Copyright Beman Dawes 2002. |
|---|
| 4 | // Copyright Rene Rivera 2004. |
|---|
| 5 | // Distributed under the Boost Software License, Version 1.0. |
|---|
| 6 | // (See accompanying file LICENSE_1_0.txt or copy at |
|---|
| 7 | // http://www.boost.org/LICENSE_1_0.txt) |
|---|
| 8 | |
|---|
| 9 | // This program recurses through sub-directories looking for various problems. |
|---|
| 10 | // It contains some Boost specific features, like ignoring "CVS" and "bin", |
|---|
| 11 | // and the code that identifies library names assumes the Boost directory |
|---|
| 12 | // structure. |
|---|
| 13 | |
|---|
| 14 | // See http://www.boost.org/tools/inspect for more information. |
|---|
| 15 | |
|---|
| 16 | #include <boost/shared_ptr.hpp> |
|---|
| 17 | #include <boost/filesystem/exception.hpp> |
|---|
| 18 | #include <boost/filesystem/operations.hpp> |
|---|
| 19 | #include <boost/filesystem/fstream.hpp> |
|---|
| 20 | |
|---|
| 21 | #include <iostream> |
|---|
| 22 | #include <cassert> |
|---|
| 23 | #include <vector> |
|---|
| 24 | #include <list> |
|---|
| 25 | #include <utility> |
|---|
| 26 | #include <algorithm> |
|---|
| 27 | #include <cstring> |
|---|
| 28 | |
|---|
| 29 | #include "inspector.hpp" // includes <string>, <boost/filesystem/path.hpp>, |
|---|
| 30 | // <iostream>, <set> |
|---|
| 31 | // and gives using for string and path. |
|---|
| 32 | #include "copyright_check.hpp" |
|---|
| 33 | #include "crlf_check.hpp" |
|---|
| 34 | #include "license_check.hpp" |
|---|
| 35 | #include "link_check.hpp" |
|---|
| 36 | #include "long_name_check.hpp" |
|---|
| 37 | #include "tab_check.hpp" |
|---|
| 38 | #include "minmax_check.hpp" |
|---|
| 39 | #include "cvs_iterator.hpp" |
|---|
| 40 | |
|---|
| 41 | namespace fs = boost::filesystem; |
|---|
| 42 | |
|---|
| 43 | namespace |
|---|
| 44 | { |
|---|
| 45 | typedef boost::shared_ptr< boost::inspect::inspector > inspector_ptr; |
|---|
| 46 | |
|---|
| 47 | struct inspector_element |
|---|
| 48 | { |
|---|
| 49 | inspector_ptr inspector; |
|---|
| 50 | |
|---|
| 51 | inspector_element( boost::inspect::inspector * p ) : inspector(p) {} |
|---|
| 52 | }; |
|---|
| 53 | |
|---|
| 54 | typedef std::list< inspector_element > inspector_list; |
|---|
| 55 | |
|---|
| 56 | long file_count; |
|---|
| 57 | long directory_count; |
|---|
| 58 | long error_count; |
|---|
| 59 | |
|---|
| 60 | boost::inspect::string_set content_signatures; |
|---|
| 61 | |
|---|
| 62 | struct error_msg |
|---|
| 63 | { |
|---|
| 64 | string library; |
|---|
| 65 | string rel_path; |
|---|
| 66 | string msg; |
|---|
| 67 | |
|---|
| 68 | bool operator<( const error_msg & rhs ) const |
|---|
| 69 | { |
|---|
| 70 | if ( library < rhs.library ) return true; |
|---|
| 71 | if ( library > rhs.library ) return false; |
|---|
| 72 | if ( rel_path < rhs.rel_path ) return true; |
|---|
| 73 | if ( rel_path > rhs.rel_path ) return false; |
|---|
| 74 | return msg < rhs.msg; |
|---|
| 75 | } |
|---|
| 76 | }; |
|---|
| 77 | |
|---|
| 78 | typedef std::vector< error_msg > error_msg_vector; |
|---|
| 79 | error_msg_vector msgs; |
|---|
| 80 | |
|---|
| 81 | // visit_predicate (determines which directories are visited) --------------// |
|---|
| 82 | |
|---|
| 83 | typedef bool(*pred_type)(const path&); |
|---|
| 84 | |
|---|
| 85 | bool visit_predicate( const path & pth ) |
|---|
| 86 | { |
|---|
| 87 | string leaf( pth.leaf() ); |
|---|
| 88 | return |
|---|
| 89 | leaf != "CVS" |
|---|
| 90 | && leaf != "bin" |
|---|
| 91 | && leaf != "jam_src" // this really out of our hands |
|---|
| 92 | && leaf != "status" // too many issues with generated HTML files |
|---|
| 93 | ; |
|---|
| 94 | } |
|---|
| 95 | |
|---|
| 96 | // library_from_content ----------------------------------------------------// |
|---|
| 97 | |
|---|
| 98 | string library_from_content( const string & content ) |
|---|
| 99 | { |
|---|
| 100 | string::size_type pos( content.find( "www.boost.org/libs/" ) ); |
|---|
| 101 | |
|---|
| 102 | if ( pos == string::npos ) return "unknown"; |
|---|
| 103 | |
|---|
| 104 | string lib; |
|---|
| 105 | pos += 19; |
|---|
| 106 | while ( content[pos] != ' ' |
|---|
| 107 | && content[pos] != '/' |
|---|
| 108 | && content[pos] != '\n' |
|---|
| 109 | && content[pos] != '\r' |
|---|
| 110 | && content[pos] != '\t' ) lib += content[pos++]; |
|---|
| 111 | return lib; |
|---|
| 112 | } |
|---|
| 113 | |
|---|
| 114 | // find_signature ----------------------------------------------------------// |
|---|
| 115 | |
|---|
| 116 | bool find_signature( const path & file_path, |
|---|
| 117 | const boost::inspect::string_set & signatures ) |
|---|
| 118 | { |
|---|
| 119 | string name( file_path.leaf() ); |
|---|
| 120 | if ( signatures.find( name ) == signatures.end() ) |
|---|
| 121 | { |
|---|
| 122 | string::size_type pos( name.rfind( '.' ) ); |
|---|
| 123 | if ( pos == string::npos |
|---|
| 124 | || signatures.find( name.substr( pos ) ) |
|---|
| 125 | == signatures.end() ) return false; |
|---|
| 126 | } |
|---|
| 127 | return true; |
|---|
| 128 | } |
|---|
| 129 | |
|---|
| 130 | // load_content ------------------------------------------------------------// |
|---|
| 131 | |
|---|
| 132 | void load_content( const path & file_path, string & target ) |
|---|
| 133 | { |
|---|
| 134 | target = ""; |
|---|
| 135 | |
|---|
| 136 | if ( !find_signature( file_path, content_signatures ) ) return; |
|---|
| 137 | |
|---|
| 138 | fs::ifstream fin( file_path, std::ios_base::in|std::ios_base::binary ); |
|---|
| 139 | if ( !fin ) |
|---|
| 140 | throw string( "could not open input file: " ) + file_path.string(); |
|---|
| 141 | std::getline( fin, target, '\0' ); // read the whole file |
|---|
| 142 | } |
|---|
| 143 | |
|---|
| 144 | // check -------------------------------------------------------------------// |
|---|
| 145 | |
|---|
| 146 | void check( const string & lib, |
|---|
| 147 | const path & pth, const string & content, const inspector_list & insp_list ) |
|---|
| 148 | { |
|---|
| 149 | // invoke each inspector |
|---|
| 150 | for ( inspector_list::const_iterator itr = insp_list.begin(); |
|---|
| 151 | itr != insp_list.end(); ++itr ) |
|---|
| 152 | { |
|---|
| 153 | itr->inspector->inspect( lib, pth ); // always call two-argument form |
|---|
| 154 | if ( find_signature( pth, itr->inspector->signatures() ) ) |
|---|
| 155 | { |
|---|
| 156 | itr->inspector->inspect( lib, pth, content ); |
|---|
| 157 | } |
|---|
| 158 | } |
|---|
| 159 | } |
|---|
| 160 | |
|---|
| 161 | // visit_all ---------------------------------------------------------------// |
|---|
| 162 | |
|---|
| 163 | template< class DirectoryIterator > |
|---|
| 164 | void visit_all( const string & lib, |
|---|
| 165 | const path & dir_path, const inspector_list & insps ) |
|---|
| 166 | { |
|---|
| 167 | static DirectoryIterator end_itr; |
|---|
| 168 | ++directory_count; |
|---|
| 169 | |
|---|
| 170 | for ( DirectoryIterator itr( dir_path ); itr != end_itr; ++itr ) |
|---|
| 171 | { |
|---|
| 172 | |
|---|
| 173 | if ( fs::is_directory( *itr ) ) |
|---|
| 174 | { |
|---|
| 175 | if ( visit_predicate( *itr ) ) |
|---|
| 176 | { |
|---|
| 177 | string cur_lib( boost::inspect::impute_library( *itr ) ); |
|---|
| 178 | check( cur_lib, *itr, "", insps ); |
|---|
| 179 | visit_all<DirectoryIterator>( cur_lib, *itr, insps ); |
|---|
| 180 | } |
|---|
| 181 | } |
|---|
| 182 | else |
|---|
| 183 | { |
|---|
| 184 | ++file_count; |
|---|
| 185 | string content; |
|---|
| 186 | load_content( *itr, content ); |
|---|
| 187 | check( lib == "unknown" |
|---|
| 188 | ? library_from_content( content ) : lib, *itr, content, insps ); |
|---|
| 189 | } |
|---|
| 190 | } |
|---|
| 191 | } |
|---|
| 192 | |
|---|
| 193 | // display_summary_helper --------------------------------------------------// |
|---|
| 194 | |
|---|
| 195 | void display_summary_helper( const string & current_library, int err_count ) |
|---|
| 196 | { |
|---|
| 197 | std::cout << " <tr><td><a href=\"#" |
|---|
| 198 | << current_library |
|---|
| 199 | << "\">" << current_library |
|---|
| 200 | << "</a></td><td align=\"center\">" |
|---|
| 201 | << err_count << "</td></tr>\n"; |
|---|
| 202 | } |
|---|
| 203 | |
|---|
| 204 | // display_summary ---------------------------------------------------------// |
|---|
| 205 | |
|---|
| 206 | void display_summary() |
|---|
| 207 | { |
|---|
| 208 | std::cout << "</pre>\n" |
|---|
| 209 | "<h2>Summary</h2>\n" |
|---|
| 210 | "<table border=\"1\" cellpadding=\"5\" cellspacing=\"0\">\n" |
|---|
| 211 | " <tr>\n" |
|---|
| 212 | " <td><b>Library</b></td>\n" |
|---|
| 213 | " <td><b>Problems</b></td>\n" |
|---|
| 214 | " </tr>\n" |
|---|
| 215 | ; |
|---|
| 216 | string current_library( msgs.begin()->library ); |
|---|
| 217 | int err_count = 0; |
|---|
| 218 | for ( error_msg_vector::iterator itr ( msgs.begin() ); |
|---|
| 219 | itr != msgs.end(); ++itr ) |
|---|
| 220 | { |
|---|
| 221 | if ( current_library != itr->library ) |
|---|
| 222 | { |
|---|
| 223 | display_summary_helper( current_library, err_count ); |
|---|
| 224 | current_library = itr->library; |
|---|
| 225 | err_count = 0; |
|---|
| 226 | } |
|---|
| 227 | ++err_count; |
|---|
| 228 | } |
|---|
| 229 | display_summary_helper( current_library, err_count ); |
|---|
| 230 | |
|---|
| 231 | std::cout << "</table>\n"; |
|---|
| 232 | } |
|---|
| 233 | |
|---|
| 234 | |
|---|
| 235 | // display_details ---------------------------------------------------------// |
|---|
| 236 | |
|---|
| 237 | void display_details() |
|---|
| 238 | { |
|---|
| 239 | std::cout << "<h2>Details</h2>\n"; |
|---|
| 240 | |
|---|
| 241 | // display error messages with group indication |
|---|
| 242 | error_msg current; |
|---|
| 243 | string sep; |
|---|
| 244 | bool first = true; |
|---|
| 245 | for ( error_msg_vector::iterator itr ( msgs.begin() ); |
|---|
| 246 | itr != msgs.end(); ++itr ) |
|---|
| 247 | { |
|---|
| 248 | if ( current.library != itr->library ) |
|---|
| 249 | { |
|---|
| 250 | if ( !first ) std::cout << "</pre>\n"; |
|---|
| 251 | std::cout << "\n<h3><a name=\"" << itr->library |
|---|
| 252 | << "\">" << itr->library << "</a></h3>\n<pre>"; |
|---|
| 253 | } |
|---|
| 254 | if ( current.library != itr->library |
|---|
| 255 | || current.rel_path != itr->rel_path ) |
|---|
| 256 | { |
|---|
| 257 | std::cout << "\n"; |
|---|
| 258 | std::cout << itr->rel_path; |
|---|
| 259 | sep = ": "; |
|---|
| 260 | } |
|---|
| 261 | if ( current.library != itr->library |
|---|
| 262 | || current.rel_path != itr->rel_path |
|---|
| 263 | || current.msg != itr->msg ) |
|---|
| 264 | { |
|---|
| 265 | std::cout << sep << itr->msg; |
|---|
| 266 | sep = ", "; |
|---|
| 267 | } |
|---|
| 268 | current.library = itr->library; |
|---|
| 269 | current.rel_path = itr->rel_path; |
|---|
| 270 | current.msg = itr->msg; |
|---|
| 271 | first = false; |
|---|
| 272 | } |
|---|
| 273 | std::cout << "</pre>\n"; |
|---|
| 274 | } |
|---|
| 275 | |
|---|
| 276 | const char * options() |
|---|
| 277 | { |
|---|
| 278 | return |
|---|
| 279 | " -license\n" |
|---|
| 280 | " -copyright\n" |
|---|
| 281 | " -crlf\n" |
|---|
| 282 | " -link\n" |
|---|
| 283 | " -long_name\n" |
|---|
| 284 | " -tab\n" |
|---|
| 285 | " -minmax\n" |
|---|
| 286 | "default is all checks on; otherwise options specify desired checks\n"; |
|---|
| 287 | } |
|---|
| 288 | |
|---|
| 289 | } // unnamed namespace |
|---|
| 290 | |
|---|
| 291 | namespace boost |
|---|
| 292 | { |
|---|
| 293 | namespace inspect |
|---|
| 294 | { |
|---|
| 295 | |
|---|
| 296 | // register_signature ------------------------------------------------------// |
|---|
| 297 | |
|---|
| 298 | void inspector::register_signature( const string & signature ) |
|---|
| 299 | { |
|---|
| 300 | m_signatures.insert( signature ); |
|---|
| 301 | content_signatures.insert( signature ); |
|---|
| 302 | } |
|---|
| 303 | |
|---|
| 304 | // error -------------------------------------------------------------------// |
|---|
| 305 | |
|---|
| 306 | void inspector::error( const string & library_name, |
|---|
| 307 | const path & full_path, const string & msg ) |
|---|
| 308 | { |
|---|
| 309 | ++error_count; |
|---|
| 310 | error_msg err_msg; |
|---|
| 311 | err_msg.library = library_name; |
|---|
| 312 | err_msg.rel_path = relative_to( full_path, fs::initial_path() ); |
|---|
| 313 | err_msg.msg = msg; |
|---|
| 314 | msgs.push_back( err_msg ); |
|---|
| 315 | |
|---|
| 316 | // std::cout << library_name << ": " |
|---|
| 317 | // << full_path.string() << ": " |
|---|
| 318 | // << msg << '\n'; |
|---|
| 319 | |
|---|
| 320 | } |
|---|
| 321 | |
|---|
| 322 | source_inspector::source_inspector() |
|---|
| 323 | { |
|---|
| 324 | // C/C++ source code... |
|---|
| 325 | register_signature( ".c" ); |
|---|
| 326 | register_signature( ".cpp" ); |
|---|
| 327 | register_signature( ".css" ); |
|---|
| 328 | register_signature( ".cxx" ); |
|---|
| 329 | register_signature( ".h" ); |
|---|
| 330 | register_signature( ".hpp" ); |
|---|
| 331 | register_signature( ".hxx" ); |
|---|
| 332 | register_signature( ".inc" ); |
|---|
| 333 | register_signature( ".ipp" ); |
|---|
| 334 | |
|---|
| 335 | // Boost.Build BJam source code... |
|---|
| 336 | register_signature( "Jamfile" ); |
|---|
| 337 | register_signature( ".jam" ); |
|---|
| 338 | register_signature( ".v2" ); |
|---|
| 339 | |
|---|
| 340 | // Other scripts; Python, shell, autoconfig, etc. |
|---|
| 341 | register_signature( "configure.in" ); |
|---|
| 342 | register_signature( "GNUmakefile" ); |
|---|
| 343 | register_signature( "Makefile" ); |
|---|
| 344 | register_signature( ".bat" ); |
|---|
| 345 | register_signature( ".mak" ); |
|---|
| 346 | register_signature( ".pl" ); |
|---|
| 347 | register_signature( ".py" ); |
|---|
| 348 | register_signature( ".sh" ); |
|---|
| 349 | |
|---|
| 350 | // Hypertext, Boost.Book, and other text... |
|---|
| 351 | register_signature( "news" ); |
|---|
| 352 | register_signature( "readme" ); |
|---|
| 353 | register_signature( "todo" ); |
|---|
| 354 | register_signature( "NEWS" ); |
|---|
| 355 | register_signature( "README" ); |
|---|
| 356 | register_signature( "TODO" ); |
|---|
| 357 | register_signature( ".boostbook" ); |
|---|
| 358 | register_signature( ".htm" ); |
|---|
| 359 | register_signature( ".html" ); |
|---|
| 360 | register_signature( ".rst" ); |
|---|
| 361 | register_signature( ".sgml" ); |
|---|
| 362 | register_signature( ".shtml" ); |
|---|
| 363 | register_signature( ".txt" ); |
|---|
| 364 | register_signature( ".xml" ); |
|---|
| 365 | register_signature( ".xsd" ); |
|---|
| 366 | register_signature( ".xsl" ); |
|---|
| 367 | } |
|---|
| 368 | |
|---|
| 369 | hypertext_inspector::hypertext_inspector() |
|---|
| 370 | { |
|---|
| 371 | register_signature( ".htm" ); |
|---|
| 372 | register_signature( ".html" ); |
|---|
| 373 | register_signature( ".shtml" ); |
|---|
| 374 | } |
|---|
| 375 | |
|---|
| 376 | // impute_library ----------------------------------------------------------// |
|---|
| 377 | |
|---|
| 378 | string impute_library( const path & full_dir_path ) |
|---|
| 379 | { |
|---|
| 380 | path relative( relative_to( full_dir_path, fs::initial_path() ), |
|---|
| 381 | fs::no_check ); |
|---|
| 382 | if ( relative.empty() ) return "boost-root"; |
|---|
| 383 | string first( *relative.begin() ); |
|---|
| 384 | string second = // borland 5.61 requires op= |
|---|
| 385 | ++relative.begin() == relative.end() |
|---|
| 386 | ? string() : *++relative.begin(); |
|---|
| 387 | |
|---|
| 388 | if ( first == "boost" ) |
|---|
| 389 | return second.empty() ? string( "unknown" ) : second; |
|---|
| 390 | |
|---|
| 391 | return (( first == "libs" || first == "tools" ) && !second.empty()) |
|---|
| 392 | ? second : first; |
|---|
| 393 | } |
|---|
| 394 | |
|---|
| 395 | } // namespace inspect |
|---|
| 396 | } // namespace boost |
|---|
| 397 | |
|---|
| 398 | // cpp_main() --------------------------------------------------------------// |
|---|
| 399 | |
|---|
| 400 | #include <boost/test/included/prg_exec_monitor.hpp> |
|---|
| 401 | |
|---|
| 402 | int cpp_main( int argc, char * argv[] ) |
|---|
| 403 | { |
|---|
| 404 | fs::initial_path(); |
|---|
| 405 | |
|---|
| 406 | if ( argc > 1 && (std::strcmp( argv[1], "-help" ) == 0 |
|---|
| 407 | || std::strcmp( argv[1], "--help" ) == 0 ) ) |
|---|
| 408 | { |
|---|
| 409 | std::clog << "Usage: inspect [-cvs] [options...]\n" |
|---|
| 410 | "options:\n" |
|---|
| 411 | << options(); |
|---|
| 412 | return 1; |
|---|
| 413 | } |
|---|
| 414 | |
|---|
| 415 | bool license_ck = true; |
|---|
| 416 | bool copyright_ck = true; |
|---|
| 417 | bool crlf_ck = true; |
|---|
| 418 | bool link_ck = true; |
|---|
| 419 | bool long_name_ck = true; |
|---|
| 420 | bool tab_ck = true; |
|---|
| 421 | bool minmax_ck = true; |
|---|
| 422 | bool cvs = false; |
|---|
| 423 | |
|---|
| 424 | if ( argc > 1 && std::strcmp( argv[1], "-cvs" ) == 0 ) |
|---|
| 425 | { |
|---|
| 426 | cvs = true; |
|---|
| 427 | --argc; ++argv; |
|---|
| 428 | } |
|---|
| 429 | |
|---|
| 430 | if ( argc > 1 && *argv[1] == '-' ) |
|---|
| 431 | { |
|---|
| 432 | license_ck = false; |
|---|
| 433 | copyright_ck = false; |
|---|
| 434 | crlf_ck = false; |
|---|
| 435 | link_ck = false; |
|---|
| 436 | long_name_ck = false; |
|---|
| 437 | tab_ck = false; |
|---|
| 438 | minmax_ck = false; |
|---|
| 439 | } |
|---|
| 440 | |
|---|
| 441 | for(; argc > 1; --argc, ++argv ) |
|---|
| 442 | { |
|---|
| 443 | if ( std::strcmp( argv[1], "-license" ) == 0 ) |
|---|
| 444 | license_ck = true; |
|---|
| 445 | else if ( std::strcmp( argv[1], "-copyright" ) == 0 ) |
|---|
| 446 | copyright_ck = true; |
|---|
| 447 | else if ( std::strcmp( argv[1], "-crlf" ) == 0 ) |
|---|
| 448 | crlf_ck = true; |
|---|
| 449 | else if ( std::strcmp( argv[1], "-link" ) == 0 ) |
|---|
| 450 | link_ck = true; |
|---|
| 451 | else if ( std::strcmp( argv[1], "-long_name" ) == 0 ) |
|---|
| 452 | long_name_ck = true; |
|---|
| 453 | else if ( std::strcmp( argv[1], "-tab" ) == 0 ) |
|---|
| 454 | tab_ck = true; |
|---|
| 455 | else if ( std::strcmp( argv[1], "-minmax" ) == 0 ) |
|---|
| 456 | minmax_ck = true; |
|---|
| 457 | else |
|---|
| 458 | { |
|---|
| 459 | std::cerr << "unknown option: " << argv[1] |
|---|
| 460 | << "\nvalid options are:\n" |
|---|
| 461 | << options(); |
|---|
| 462 | return 1; |
|---|
| 463 | } |
|---|
| 464 | } |
|---|
| 465 | |
|---|
| 466 | inspector_list inspectors; |
|---|
| 467 | |
|---|
| 468 | if ( license_ck ) |
|---|
| 469 | inspectors.push_back( inspector_element( new boost::inspect::license_check ) ); |
|---|
| 470 | if ( copyright_ck ) |
|---|
| 471 | inspectors.push_back( inspector_element( new boost::inspect::copyright_check ) ); |
|---|
| 472 | if ( crlf_ck ) |
|---|
| 473 | inspectors.push_back( inspector_element( new boost::inspect::crlf_check ) ); |
|---|
| 474 | if ( link_ck ) |
|---|
| 475 | inspectors.push_back( inspector_element( new boost::inspect::link_check ) ); |
|---|
| 476 | if ( long_name_ck ) |
|---|
| 477 | inspectors.push_back( inspector_element( new boost::inspect::long_name_check ) ); |
|---|
| 478 | if ( tab_ck ) |
|---|
| 479 | inspectors.push_back( inspector_element( new boost::inspect::tab_check ) ); |
|---|
| 480 | if ( minmax_ck ) |
|---|
| 481 | inspectors.push_back( inspector_element( new boost::inspect::minmax_check ) ); |
|---|
| 482 | |
|---|
| 483 | // perform the actual inspection, using the requested type of iteration |
|---|
| 484 | if ( cvs ) |
|---|
| 485 | visit_all<hack::cvs_iterator>( "boost-root", |
|---|
| 486 | fs::initial_path(), inspectors ); |
|---|
| 487 | else |
|---|
| 488 | visit_all<fs::directory_iterator>( "boost-root", |
|---|
| 489 | fs::initial_path(), inspectors ); |
|---|
| 490 | |
|---|
| 491 | // close |
|---|
| 492 | for ( inspector_list::iterator itr = inspectors.begin(); |
|---|
| 493 | itr != inspectors.end(); ++itr ) |
|---|
| 494 | { |
|---|
| 495 | itr->inspector->close(); |
|---|
| 496 | } |
|---|
| 497 | |
|---|
| 498 | char run_date[128]; |
|---|
| 499 | std::time_t tod; |
|---|
| 500 | std::time( &tod ); |
|---|
| 501 | std::strftime( run_date, sizeof(run_date), |
|---|
| 502 | "%X UTC, %A %d %B %Y", std::gmtime( &tod ) ); |
|---|
| 503 | |
|---|
| 504 | std::cout << "<html>\n" |
|---|
| 505 | "<head>\n" |
|---|
| 506 | "<title>Boost Inspection Report</title>\n" |
|---|
| 507 | "</head>\n" |
|---|
| 508 | "<body bgcolor=\"#ffffff\" text=\"#000000\">\n" |
|---|
| 509 | "<table border=\"0\">\n" |
|---|
| 510 | "<tr>\n" |
|---|
| 511 | "<td><img border=\"0\" src=\"../boost.png\" width=\"277\" " |
|---|
| 512 | "height=\"86\"></td>\n" |
|---|
| 513 | "<td align=\"center\">\n" |
|---|
| 514 | "<h1>Boost Inspection Report</h1>\n" |
|---|
| 515 | "<b>Run Date:</b> " << run_date << "\n" |
|---|
| 516 | "</td>\n" |
|---|
| 517 | "</table>\n" |
|---|
| 518 | "<p>An <a href=\"http://www.boost.org/tools/inspect/index.html\">inspection\n" |
|---|
| 519 | "program</a> checks each file in the current Boost CVS for various problems,\n" |
|---|
| 520 | "generating this web page as output. Problems detected include tabs in files,\n" |
|---|
| 521 | "missing copyrights, broken URL's, and similar misdemeanors.</p>\n" |
|---|
| 522 | ; |
|---|
| 523 | |
|---|
| 524 | std::cout << "<h2>Totals</h2>\n<pre>" |
|---|
| 525 | << file_count << " files scanned\n" |
|---|
| 526 | << directory_count << " directories scanned\n" |
|---|
| 527 | << error_count << " problems reported\n"; |
|---|
| 528 | |
|---|
| 529 | std::cout << "\nproblem counts:\n"; |
|---|
| 530 | |
|---|
| 531 | for ( inspector_list::iterator itr = inspectors.begin(); |
|---|
| 532 | itr != inspectors.end(); ++itr ) |
|---|
| 533 | { |
|---|
| 534 | itr->inspector.reset(); |
|---|
| 535 | } |
|---|
| 536 | |
|---|
| 537 | std::sort( msgs.begin(), msgs.end() ); |
|---|
| 538 | |
|---|
| 539 | if ( !msgs.empty() ) |
|---|
| 540 | { |
|---|
| 541 | display_summary(); |
|---|
| 542 | display_details(); |
|---|
| 543 | } |
|---|
| 544 | |
|---|
| 545 | std::cout << "</body>\n" |
|---|
| 546 | "</html>\n"; |
|---|
| 547 | return 0; |
|---|
| 548 | } |
|---|