summaryrefslogtreecommitdiff
path: root/tools/inspect/inspect.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'tools/inspect/inspect.cpp')
-rw-r--r--tools/inspect/inspect.cpp265
1 files changed, 180 insertions, 85 deletions
diff --git a/tools/inspect/inspect.cpp b/tools/inspect/inspect.cpp
index 00e72f9935..9aa93809b8 100644
--- a/tools/inspect/inspect.cpp
+++ b/tools/inspect/inspect.cpp
@@ -1,4 +1,4 @@
-// inspect program ---------------------------------------------------------//
+// inspect program -------------------------------------------------------------------//
// Copyright Beman Dawes 2002.
// Copyright Rene Rivera 2004-2006.
@@ -15,6 +15,11 @@
// See http://www.boost.org/tools/inspect/ for more information.
+const char* boost_no_inspect = "boost-" "no-inspect";
+
+// Directories with a file name of the boost_no_inspect value are not inspected.
+// Files that contain the boost_no_inspect value are not inspected.
+
#include <vector>
#include <list>
@@ -26,6 +31,15 @@
#include "boost/filesystem/operations.hpp"
#include "boost/filesystem/fstream.hpp"
+#include <stdio.h> // for popen, pclose
+#if defined(_MSC_VER)
+# define POPEN _popen
+# define PCLOSE _pclose
+#else
+# define POPEN popen
+# define PCLOSE pclose
+#endif
+
#include "time_string.hpp"
#include "inspector.hpp"
@@ -41,12 +55,19 @@
#include "ascii_check.hpp"
#include "apple_macro_check.hpp"
#include "assert_macro_check.hpp"
+#include "deprecated_macro_check.hpp"
#include "minmax_check.hpp"
#include "unnamed_namespace_check.hpp"
-#include "cvs_iterator.hpp"
+//#include "cvs_iterator.hpp"
+#if !defined(INSPECT_USE_BOOST_TEST)
+#define INSPECT_USE_BOOST_TEST 0
+#endif
+
+#if INSPECT_USE_BOOST_TEST
#include "boost/test/included/prg_exec_monitor.hpp"
+#endif
namespace fs = boost::filesystem;
@@ -54,6 +75,8 @@ using namespace boost::inspect;
namespace
{
+ fs::path search_root = fs::initial_path();
+
class inspector_element
{
typedef boost::shared_ptr< boost::inspect::inspector > inspector_ptr;
@@ -109,33 +132,89 @@ namespace
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 --------------//
+// run subversion to get revisions info ------------------------------------//
+//
+// implemented as function object that can be passed to boost::execution_monitor
+// in order to swallow any errors from 'svn info'.
- 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
+ struct svn_check
+ {
+ explicit svn_check(const fs::path & inspect_root) :
+ inspect_root(inspect_root), fp(0) {}
+
+ int operator()() {
+ string rev("unknown");
+ string repos("unknown");
+ string command("cd ");
+ command += inspect_root.string() + " && svn info";
+
+ fp = (POPEN(command.c_str(), "r"));
+ if (fp)
+ {
+ static const int line_max = 128;
+ char line[line_max];
+ while (fgets(line, line_max, fp) != NULL)
+ {
+ string ln(line);
+ string::size_type pos;
+ if ((pos = ln.find("Revision: ")) != string::npos)
+ rev = ln.substr(pos + 10);
+ else if ((pos = ln.find("URL: ")) != string::npos)
+ repos = ln.substr(pos + 5);
+ }
+ }
+
+ result = repos + " at revision " + rev;
+ return 0;
}
+ ~svn_check() { if (fp) PCLOSE(fp); }
+
+ const fs::path & inspect_root;
+ std::string result;
+ FILE* fp;
+ private:
+ svn_check(svn_check const&);
+ svn_check const& operator=(svn_check const&);
+ };
+
+ // Small helper class because svn_check can't be passed by copy.
+ template <typename F, typename R>
+ struct nullary_function_ref
+ {
+ explicit nullary_function_ref(F& f) : f(f) {}
+ R operator()() const { return f(); }
+ F& f;
+ };
+
+// get info (as a string) if inspect_root is svn working copy --------------//
+
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 );
+ svn_check check(inspect_root);
+
+#if !INSPECT_USE_BOOST_TEST
+ check();
+#else
+
+ try {
+ boost::execution_monitor e;
+ e.execute(nullary_function_ref<svn_check, int>(check));
}
- return repos + " at revision " + rev;
+ catch(boost::execution_exception const& e) {
+ if (e.code() == boost::execution_exception::system_error) {
+ // There was an error running 'svn info' - it probably
+ // wasn't run in a subversion repo.
+ return string("unknown");
+ }
+ else {
+ throw;
+ }
+ }
+
+#endif
+
+ return check.result;
}
// visit_predicate (determines which directories are visited) --------------//
@@ -144,10 +223,13 @@ namespace
bool visit_predicate( const path & pth )
{
- string local( boost::inspect::relative_to( pth, fs::initial_path() ) );
+ string local( boost::inspect::relative_to( pth, search_root_path() ) );
string leaf( pth.leaf().string() );
+ if (leaf[0] == '.') // ignore hidden by convention directories such as
+ return false; // .htaccess, .git, .svn, .bzr, .DS_Store, etc.
+
return
- // so we can inspect a checkout
+ // so we can inspect a CVS checkout
leaf != "CVS"
// don't look at binaries
&& leaf != "bin"
@@ -155,17 +237,8 @@ namespace
// no point in checking doxygen xml output
&& local.find("doc/xml") != 0
&& 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"
// ignore if tag file present
- && !boost::filesystem::exists(pth / "boost-no-inspect")
+ && !boost::filesystem::exists(pth / boost_no_inspect)
;
}
@@ -253,7 +326,6 @@ namespace
for ( DirectoryIterator itr( dir_path ); itr != end_itr; ++itr )
{
-
if ( fs::is_directory( *itr ) )
{
if ( visit_predicate( *itr ) )
@@ -263,14 +335,14 @@ namespace
visit_all<DirectoryIterator>( cur_lib, *itr, insps );
}
}
- else
+ else if (itr->path().leaf().string()[0] != '.') // ignore if hidden
{
++file_count;
string content;
load_content( *itr, content );
- check( lib.empty()
- ? library_from_content( content ) : lib
- , *itr, content, insps );
+ if (content.find(boost_no_inspect) == string::npos)
+ check( lib.empty() ? library_from_content( content ) : lib,
+ *itr, content, insps );
}
}
}
@@ -293,7 +365,7 @@ namespace
void display_summary_helper( const string & current_library, int err_count )
{
- if (display_text == display_format)
+ if (display_format == display_text)
{
std::cout << " " << current_library << " (" << err_count << ")\n";
}
@@ -312,7 +384,7 @@ namespace
void display_summary()
{
- if (display_text == display_format)
+ if (display_format == display_text)
{
std::cout << "Summary:\n";
}
@@ -339,7 +411,7 @@ namespace
}
display_summary_helper( current_library, err_count );
- if (display_text == display_format)
+ if (display_format == display_text)
std::cout << "\n";
else
std::cout << "</blockquote>\n";
@@ -376,9 +448,7 @@ namespace
void display_details()
{
- // gps - review this
-
- if (display_text == display_format)
+ if (display_format == display_text)
{
// display error messages with group indication
error_msg current;
@@ -517,7 +587,9 @@ namespace
void display_worst_offenders()
{
- if (display_text == display_format)
+ if (display_mode == display_brief)
+ return;
+ if (display_format == display_text)
{
std::cout << "Worst Offenders:\n";
}
@@ -537,7 +609,7 @@ namespace
|| itr->error_count == last_error_count);
++itr, ++display_count )
{
- if (display_text == display_format)
+ if (display_format == display_text)
{
std::cout << itr->library << " " << itr->error_count << "\n";
}
@@ -553,7 +625,7 @@ namespace
last_error_count = itr->error_count;
}
- if (display_text == display_format)
+ if (display_format == display_text)
std::cout << "\n";
else
std::cout << "</blockquote>\n";
@@ -573,6 +645,7 @@ namespace
" -ascii\n"
" -apple_macro\n"
" -assert_macro\n"
+ " -deprecated_macro\n"
" -minmax\n"
" -unnamed\n"
" default is all checks on; otherwise options specify desired checks"
@@ -611,6 +684,12 @@ namespace boost
return display_format ? "\n" : "<br>\n";
}
+// search_root_path --------------------------------------------------------//
+
+ path search_root_path()
+ {
+ return search_root;
+ }
// register_signature ------------------------------------------------------//
@@ -628,7 +707,7 @@ namespace boost
++error_count;
error_msg err_msg;
err_msg.library = library_name;
- err_msg.rel_path = relative_to( full_path, fs::initial_path() );
+ err_msg.rel_path = relative_to( full_path, search_root_path() );
err_msg.msg = msg;
err_msg.line_number = line_number;
msgs.push_back( err_msg );
@@ -699,7 +778,7 @@ namespace boost
// may return an empty string [gps]
string impute_library( const path & full_dir_path )
{
- path relative( relative_to( full_dir_path, fs::initial_path() ) );
+ path relative( relative_to( full_dir_path, search_root_path() ) );
if ( relative.empty() ) return "boost-root";
string first( (*relative.begin()).string() );
string second = // borland 5.61 requires op=
@@ -718,7 +797,11 @@ namespace boost
// cpp_main() --------------------------------------------------------------//
+#if !INSPECT_USE_BOOST_TEST
+int main( int argc_param, char * argv_param[] )
+#else
int cpp_main( int argc_param, char * argv_param[] )
+#endif
{
// <hack> for the moment, let's be on the safe side
// and ensure we don't modify anything being pointed to;
@@ -729,7 +812,9 @@ int cpp_main( int argc_param, char * argv_param[] )
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"
+ //std::clog << "Usage: inspect [search-root] [-cvs] [-text] [-brief] [options...]\n\n"
+ std::clog << "Usage: inspect [search-root] [-text] [-brief] [options...]\n\n"
+ " search-root default is the current directory (i.e. '.')\n\n"
" Options:\n"
<< options() << '\n';
return 0;
@@ -743,18 +828,25 @@ int cpp_main( int argc_param, char * argv_param[] )
bool path_name_ck = true;
bool tab_ck = true;
bool ascii_ck = true;
- bool apple_ok = true;
- bool assert_ok = true;
+ bool apple_ck = true;
+ bool assert_ck = true;
+ bool deprecated_ck = true;
bool minmax_ck = true;
bool unnamed_ck = true;
- bool cvs = false;
+ //bool cvs = false;
- if ( argc > 1 && std::strcmp( argv[1], "-cvs" ) == 0 )
+ if ( argc > 1 && *argv[1] != '-' )
{
- cvs = true;
+ search_root = fs::canonical(fs::absolute(argv[1], fs::initial_path()));
--argc; ++argv;
}
+ //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;
@@ -777,8 +869,9 @@ int cpp_main( int argc_param, char * argv_param[] )
path_name_ck = false;
tab_ck = false;
ascii_ck = false;
- apple_ok = false;
- assert_ok = false;
+ apple_ck = false;
+ assert_ck = false;
+ deprecated_ck = false;
minmax_ck = false;
unnamed_ck = false;
}
@@ -803,9 +896,11 @@ int cpp_main( int argc_param, char * argv_param[] )
else if ( std::strcmp( argv[1], "-ascii" ) == 0 )
ascii_ck = true;
else if ( std::strcmp( argv[1], "-apple_macro" ) == 0 )
- apple_ok = true;
+ apple_ck = true;
else if ( std::strcmp( argv[1], "-assert_macro" ) == 0 )
- assert_ok = true;
+ assert_ck = true;
+ else if ( std::strcmp( argv[1], "-deprecated_macro" ) == 0 )
+ deprecated_ck = true;
else if ( std::strcmp( argv[1], "-minmax" ) == 0 )
minmax_ck = true;
else if ( std::strcmp( argv[1], "-unnamed" ) == 0 )
@@ -823,8 +918,6 @@ int cpp_main( int argc_param, char * argv_param[] )
}
string inspector_keys;
- fs::initial_path();
-
{ // begin reporting block
@@ -849,22 +942,24 @@ int cpp_main( int argc_param, char * argv_param[] )
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 )
+ if ( apple_ck )
inspectors.push_back( inspector_element( new boost::inspect::apple_macro_check ) );
- if ( assert_ok )
+ if ( assert_ck )
inspectors.push_back( inspector_element( new boost::inspect::assert_macro_check ) );
+ if ( deprecated_ck )
+ inspectors.push_back( inspector_element( new boost::inspect::deprecated_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 );
+ //// perform the actual inspection, using the requested type of iteration
+ //if ( cvs )
+ // visit_all<hack::cvs_iterator>( search_root.leaf().string(),
+ // search_root, inspectors );
+ //else
+ visit_all<fs::directory_iterator>( search_root.leaf().string(),
+ search_root, inspectors );
// close
for ( inspector_list::iterator itr = inspectors.begin();
@@ -876,17 +971,13 @@ int cpp_main( int argc_param, char * argv_param[] )
string run_date ( "n/a" );
boost::time_string( run_date );
- if (display_text == display_format)
+ if (display_format == display_text)
{
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
@@ -928,7 +1019,7 @@ int cpp_main( int argc_param, char * argv_param[] )
;
std::cout
<< "<p>The files checked were from "
- << info( fs::initial_path() )
+ << info( search_root_path() )
<< ".</p>\n";
@@ -950,14 +1041,14 @@ int cpp_main( int argc_param, char * argv_param[] )
;
}
- if (display_text == display_format)
+ if (display_format == display_text)
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)
+ if (display_format == display_text)
std::cout << "\n" ;
else
std::cout << "</blockquote>\n";
@@ -967,25 +1058,29 @@ int cpp_main( int argc_param, char * argv_param[] )
worst_offenders_count();
std::stable_sort( libs.begin(), libs.end() );
- if ( !libs.empty() )
+ if ( !libs.empty() && display_mode != display_brief)
display_worst_offenders();
if ( !msgs.empty() )
{
display_summary();
- if (display_text == display_format)
+ if (display_format == display_text)
{
std::cout << "Details:\n" << inspector_keys;
- }
+ std::cout << "\nDirectories with a file named \"" << boost_no_inspect << "\" will not be inspected.\n"
+ "Files containing \"" << boost_no_inspect << "\" will not be inspected.\n";
+ }
else
{
std::cout << "<h2>Details</h2>\n" << inspector_keys;
+ std::cout << "\n<p>Directories with a file named \"" << boost_no_inspect << "\" will not be inspected.<br>\n"
+ "Files containing \"" << boost_no_inspect << "\" will not be inspected.</p>\n";
}
display_details();
}
- if (display_text == display_format)
+ if (display_format == display_text)
{
std::cout << "\n\n" ;
}
@@ -996,5 +1091,5 @@ int cpp_main( int argc_param, char * argv_param[] )
"</html>\n";
}
- return 0;
+ return error_count ? 1 : 0;
}