summaryrefslogtreecommitdiffstats
path: root/src/boost/tools/inspect
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--src/boost/tools/inspect/apple_macro_check.cpp105
-rw-r--r--src/boost/tools/inspect/apple_macro_check.hpp39
-rw-r--r--src/boost/tools/inspect/ascii_check.cpp102
-rw-r--r--src/boost/tools/inspect/ascii_check.hpp38
-rw-r--r--src/boost/tools/inspect/assert_macro_check.cpp110
-rw-r--r--src/boost/tools/inspect/assert_macro_check.hpp40
-rw-r--r--src/boost/tools/inspect/build/Jamfile.v256
-rw-r--r--src/boost/tools/inspect/build/msvc/boost_inspect.sln20
-rw-r--r--src/boost/tools/inspect/build/msvc/boost_inspect.vcxproj117
-rw-r--r--src/boost/tools/inspect/build/msvc/readme.txt8
-rw-r--r--src/boost/tools/inspect/copyright_check.cpp35
-rw-r--r--src/boost/tools/inspect/copyright_check.hpp39
-rw-r--r--src/boost/tools/inspect/crlf_check.cpp97
-rw-r--r--src/boost/tools/inspect/crlf_check.hpp40
-rw-r--r--src/boost/tools/inspect/deprecated_macro_check.cpp146
-rw-r--r--src/boost/tools/inspect/deprecated_macro_check.hpp40
-rw-r--r--src/boost/tools/inspect/end_check.cpp58
-rw-r--r--src/boost/tools/inspect/end_check.hpp40
-rw-r--r--src/boost/tools/inspect/index.html55
-rw-r--r--src/boost/tools/inspect/inspect.cpp1041
-rw-r--r--src/boost/tools/inspect/inspector.hpp108
-rw-r--r--src/boost/tools/inspect/license_check.cpp48
-rw-r--r--src/boost/tools/inspect/license_check.hpp40
-rw-r--r--src/boost/tools/inspect/link_check.cpp487
-rw-r--r--src/boost/tools/inspect/link_check.hpp72
-rw-r--r--src/boost/tools/inspect/link_check_test.html24
-rw-r--r--src/boost/tools/inspect/minmax_check.cpp102
-rw-r--r--src/boost/tools/inspect/minmax_check.hpp45
-rw-r--r--src/boost/tools/inspect/path_name_check.cpp110
-rw-r--r--src/boost/tools/inspect/path_name_check.hpp48
-rw-r--r--src/boost/tools/inspect/tab_check.cpp44
-rw-r--r--src/boost/tools/inspect/tab_check.hpp37
-rw-r--r--src/boost/tools/inspect/time_string.hpp55
-rw-r--r--src/boost/tools/inspect/unnamed_namespace_check.cpp62
-rw-r--r--src/boost/tools/inspect/unnamed_namespace_check.hpp39
-rw-r--r--src/boost/tools/inspect/wrong_line_ends_test.cpp1
36 files changed, 3548 insertions, 0 deletions
diff --git a/src/boost/tools/inspect/apple_macro_check.cpp b/src/boost/tools/inspect/apple_macro_check.cpp
new file mode 100644
index 000000000..7afb8f9fd
--- /dev/null
+++ b/src/boost/tools/inspect/apple_macro_check.cpp
@@ -0,0 +1,105 @@
+// apple_macro_check implementation ------------------------------------------------//
+
+// Copyright Marshall Clow 2007.
+// Based on the tab-check checker by Beman Dawes
+//
+// 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 "apple_macro_check.hpp"
+#include <functional>
+#include "boost/regex.hpp"
+#include "boost/lexical_cast.hpp"
+#include "boost/filesystem/operations.hpp"
+
+namespace fs = boost::filesystem;
+
+namespace
+{
+ boost::regex apple_macro_regex(
+ "("
+ "^\\s*#\\s*undef\\s*" // # undef
+ "\\b(check|verify|require|check_error)\\b" // followed by apple macro name, whole word
+ ")"
+ "|" // or (ignored)
+ "("
+ "//[^\\n]*" // single line comments (//)
+ "|"
+ "/\\*.*?\\*/" // multi line comments (/**/)
+ "|"
+ "\"(?:\\\\\\\\|\\\\\"|[^\"])*\"" // string literals
+ ")"
+ "|" // or
+ "("
+ "\\b(check|verify|require|check_error)\\b" // apple macro name, whole word
+ "\\s*\\(" // followed by 0 or more spaces and an opening paren
+ ")"
+ , boost::regex::normal);
+
+} // unnamed namespace
+
+
+namespace boost
+{
+ namespace inspect
+ {
+ apple_macro_check::apple_macro_check() : m_files_with_errors(0)
+ {
+ register_signature( ".c" );
+ register_signature( ".cpp" );
+ register_signature( ".cxx" );
+ register_signature( ".h" );
+ register_signature( ".hpp" );
+ register_signature( ".hxx" );
+ register_signature( ".ipp" );
+ }
+
+ void apple_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:" "naapple_macros" ) != string::npos) return;
+
+ // Only check files in the boost directory, as we can avoid including the
+ // apple test headers elsewhere.
+ path relative( relative_to( full_path, search_root_path() ) );
+ if ( relative.empty() || *relative.begin() != "boost") return;
+
+ boost::sregex_iterator cur(contents.begin(), contents.end(), apple_macro_regex), end;
+
+ long errors = 0;
+
+ for( ; cur != end; ++cur /*, ++m_files_with_errors*/ )
+ {
+
+ 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,
+ "Apple macro clash: " + std::string((*cur)[0].first, (*cur)[0].second-1),
+ line_number );
+ }
+ }
+ if(errors > 0) {
+ ++m_files_with_errors;
+ }
+ }
+ } // namespace inspect
+} // namespace boost
+
+
diff --git a/src/boost/tools/inspect/apple_macro_check.hpp b/src/boost/tools/inspect/apple_macro_check.hpp
new file mode 100644
index 000000000..5acdcf70c
--- /dev/null
+++ b/src/boost/tools/inspect/apple_macro_check.hpp
@@ -0,0 +1,39 @@
+// apple_macro_check header --------------------------------------------------------//
+
+// Copyright Marshall Clow 2007.
+// Based on the tab-check checker by Beman Dawes
+// 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)
+
+#ifndef BOOST_APPLE_MACRO_CHECK_HPP
+#define BOOST_APPLE_MACRO_CHECK_HPP
+
+#include "inspector.hpp"
+
+
+namespace boost
+{
+ namespace inspect
+ {
+ class apple_macro_check : public inspector
+ {
+ long m_files_with_errors;
+ public:
+
+ apple_macro_check();
+ virtual const char * name() const { return "*APPLE-MACROS*"; }
+ virtual const char * desc() const { return "calls to Apple's debugging macros in file"; }
+
+ virtual void inspect(
+ const std::string & library_name,
+ const path & full_path,
+ const std::string & contents );
+
+ virtual ~apple_macro_check()
+ { std::cout << " " << m_files_with_errors << " files with Apple macros" << line_break(); }
+ };
+ }
+}
+
+#endif // BOOST_APPLE_MACRO_CHECK_HPP
diff --git a/src/boost/tools/inspect/ascii_check.cpp b/src/boost/tools/inspect/ascii_check.cpp
new file mode 100644
index 000000000..da2aa4020
--- /dev/null
+++ b/src/boost/tools/inspect/ascii_check.cpp
@@ -0,0 +1,102 @@
+// ascii_check implementation ------------------------------------------------//
+
+// Copyright Marshall Clow 2007.
+// Based on the tab-check checker by Beman Dawes
+//
+// 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 is a test.
+
+#include "ascii_check.hpp"
+#include <functional>
+
+namespace boost
+{
+ namespace inspect
+ {
+
+ static const string gPunct ( "$_{}[]#()<>%:;.?*+-/ˆ&|~!=,\\\"'@^`" );
+
+ // Legal characters for a source file are defined in section 2.2 of the standard
+ // I have added '@', '^', and '`' to the "legal" chars because they are commonly
+ // used in comments, and they are strictly ASCII.
+ struct non_ascii : public std::unary_function<char, bool> {
+ public:
+ non_ascii () {}
+ ~non_ascii () {}
+ bool operator () ( char c ) const
+ {
+ if ( c == ' ' ) return false;
+ if ( c >= 'a' && c <= 'z' ) return false;
+ if ( c >= 'A' && c <= 'Z' ) return false;
+ if ( c >= '0' && c <= '9' ) return false;
+ // Horizontal/Vertical tab, newline, and form feed
+ if ( c == '\t' || c == '\n' || c == '\r' || c == '\v' || c == '\f' ) return false;
+ return gPunct.find ( c ) == string::npos;
+ }
+ };
+
+ struct is_CRLF : public std::unary_function<char, bool> {
+ public:
+ is_CRLF () {}
+ ~is_CRLF () {}
+ bool operator () ( char c ) const
+ {
+ return c == '\015' || c == '\012';
+ }
+ };
+
+ const char *kCRLF = "\012\015";
+
+// Given a position in the file, extract and return the line
+ std::string find_line ( const std::string &contents, std::string::const_iterator iter_pos )
+ {
+ std::size_t pos = iter_pos - contents.begin ();
+
+ // Search backwards for a CR or LR
+ std::size_t start_pos = contents.find_last_of ( kCRLF, pos );
+ std::string::const_iterator line_start = contents.begin () + ( start_pos == std::string::npos ? 0 : start_pos + 1 );
+
+
+ // Search forwards for a CR or LF
+ std::size_t end_pos = contents.find_first_of ( kCRLF, pos + 1 );
+ std::string::const_iterator line_end;
+ if ( end_pos == std::string::npos )
+ line_end = contents.end ();
+ else
+ line_end = contents.begin () + end_pos - 1;
+
+ return std::string ( line_start, line_end );
+ }
+
+ ascii_check::ascii_check() : m_files_with_errors(0)
+ {
+ register_signature( ".c" );
+ register_signature( ".cpp" );
+ register_signature( ".cxx" );
+ register_signature( ".h" );
+ register_signature( ".hpp" );
+ register_signature( ".hxx" );
+ register_signature( ".ipp" );
+ }
+
+ void ascii_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:" "noascii" ) != string::npos) return;
+ string::const_iterator bad_char = std::find_if ( contents.begin (), contents.end (), non_ascii ());
+ if ( bad_char != contents.end ())
+ {
+ ++m_files_with_errors;
+ int ln = std::count( contents.begin(), bad_char, '\n' ) + 1;
+ string the_line = find_line ( contents, bad_char );
+ error( library_name, full_path, "Non-ASCII: " + the_line, ln );
+ }
+ }
+ } // namespace inspect
+} // namespace boost
+
+
diff --git a/src/boost/tools/inspect/ascii_check.hpp b/src/boost/tools/inspect/ascii_check.hpp
new file mode 100644
index 000000000..6094ce856
--- /dev/null
+++ b/src/boost/tools/inspect/ascii_check.hpp
@@ -0,0 +1,38 @@
+// ascii_check header --------------------------------------------------------//
+
+// Copyright Marshall Clow 2007.
+// Based on the tab-check checker by Beman Dawes
+// 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)
+
+#ifndef BOOST_ASCII_CHECK_HPP
+#define BOOST_ASCII_CHECK_HPP
+
+#include "inspector.hpp"
+
+namespace boost
+{
+ namespace inspect
+ {
+ class ascii_check : public inspector
+ {
+ long m_files_with_errors;
+ public:
+
+ ascii_check();
+ virtual const char * name() const { return "*ASCII*"; }
+ virtual const char * desc() const { return "non-ASCII chars in file"; }
+
+ virtual void inspect(
+ const std::string & library_name,
+ const path & full_path,
+ const std::string & contents );
+
+ virtual ~ascii_check()
+ { std::cout << " " << m_files_with_errors << " files with non-ASCII chars" << line_break(); }
+ };
+ }
+}
+
+#endif // BOOST_ASCII_CHECK_HPP
diff --git a/src/boost/tools/inspect/assert_macro_check.cpp b/src/boost/tools/inspect/assert_macro_check.cpp
new file mode 100644
index 000000000..340a9f5ba
--- /dev/null
+++ b/src/boost/tools/inspect/assert_macro_check.cpp
@@ -0,0 +1,110 @@
+// 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 <functional>
+#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<string>( line_number ) );
+ }
+ }
+ if(errors > 0)
+ ++m_files_with_errors;
+ }
+ } // namespace inspect
+} // namespace boost
+
+
diff --git a/src/boost/tools/inspect/assert_macro_check.hpp b/src/boost/tools/inspect/assert_macro_check.hpp
new file mode 100644
index 000000000..c28a377f3
--- /dev/null
+++ b/src/boost/tools/inspect/assert_macro_check.hpp
@@ -0,0 +1,40 @@
+// assert_macro_check header --------------------------------------------------------//
+
+// Copyright Eric Niebler 2010.
+// Based on the apple_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)
+
+#ifndef BOOST_ASSERT_MACRO_CHECK_HPP
+#define BOOST_ASSERT_MACRO_CHECK_HPP
+
+#include "inspector.hpp"
+
+
+namespace boost
+{
+ namespace inspect
+ {
+ class assert_macro_check : public inspector
+ {
+ long m_files_with_errors;
+ bool m_from_boost_root;
+ public:
+
+ assert_macro_check();
+ virtual const char * name() const { return "*ASSERT-MACROS*"; }
+ virtual const char * desc() const { return "presence of C-style assert macro in file (use BOOST_ASSERT instead)"; }
+
+ virtual void inspect(
+ const std::string & library_name,
+ const path & full_path,
+ const std::string & contents );
+
+ virtual ~assert_macro_check()
+ { std::cout << " " << m_files_with_errors << " files with a C-style assert macro" << line_break(); }
+ };
+ }
+}
+
+#endif // BOOST_ASSERT_MACRO_CHECK_HPP
diff --git a/src/boost/tools/inspect/build/Jamfile.v2 b/src/boost/tools/inspect/build/Jamfile.v2
new file mode 100644
index 000000000..e3a53a03d
--- /dev/null
+++ b/src/boost/tools/inspect/build/Jamfile.v2
@@ -0,0 +1,56 @@
+# Inspect Jamfile
+
+# Copyright Vladimir Prus
+
+# Distributed under the Boost Software License, Version 1.0.
+# See http://www.boost.org/LICENSE_1_0.txt
+
+project
+ :
+ requirements
+ :
+ source-location ..
+ ;
+
+exe inspect
+ :
+ apple_macro_check.cpp
+ ascii_check.cpp
+ assert_macro_check.cpp
+ copyright_check.cpp
+ crlf_check.cpp
+ deprecated_macro_check.cpp
+ end_check.cpp
+ inspect.cpp
+ license_check.cpp
+ link_check.cpp
+ minmax_check.cpp
+ path_name_check.cpp
+ tab_check.cpp
+ unnamed_namespace_check.cpp
+ /boost//filesystem/<link>static
+ /boost//regex/<link>static
+ :
+ :
+ release
+ ;
+
+install dist-bin
+ :
+ inspect
+ :
+ <install-type>EXE
+ <location>../../../dist/bin
+ :
+ release
+ ;
+
+install dist-lib
+ :
+ inspect
+ :
+ <install-type>LIB
+ <location>../../../dist/lib
+ :
+ release
+ ;
diff --git a/src/boost/tools/inspect/build/msvc/boost_inspect.sln b/src/boost/tools/inspect/build/msvc/boost_inspect.sln
new file mode 100644
index 000000000..a4a1a40ab
--- /dev/null
+++ b/src/boost/tools/inspect/build/msvc/boost_inspect.sln
@@ -0,0 +1,20 @@
+
+Microsoft Visual Studio Solution File, Format Version 11.00
+# Visual C++ Express 2010
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "inspect", "boost_inspect.vcxproj", "{0EC8AC1C-6D1F-47FC-A06A-9CC3F924BD82}"
+EndProject
+Global
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug|Win32 = Debug|Win32
+ Release|Win32 = Release|Win32
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {0EC8AC1C-6D1F-47FC-A06A-9CC3F924BD82}.Debug|Win32.ActiveCfg = Debug|Win32
+ {0EC8AC1C-6D1F-47FC-A06A-9CC3F924BD82}.Debug|Win32.Build.0 = Debug|Win32
+ {0EC8AC1C-6D1F-47FC-A06A-9CC3F924BD82}.Release|Win32.ActiveCfg = Release|Win32
+ {0EC8AC1C-6D1F-47FC-A06A-9CC3F924BD82}.Release|Win32.Build.0 = Release|Win32
+ EndGlobalSection
+ GlobalSection(SolutionProperties) = preSolution
+ HideSolutionNode = FALSE
+ EndGlobalSection
+EndGlobal
diff --git a/src/boost/tools/inspect/build/msvc/boost_inspect.vcxproj b/src/boost/tools/inspect/build/msvc/boost_inspect.vcxproj
new file mode 100644
index 000000000..3c35c22b8
--- /dev/null
+++ b/src/boost/tools/inspect/build/msvc/boost_inspect.vcxproj
@@ -0,0 +1,117 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <ItemGroup Label="ProjectConfigurations">
+ <ProjectConfiguration Include="Debug|Win32">
+ <Configuration>Debug</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Release|Win32">
+ <Configuration>Release</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ </ItemGroup>
+ <PropertyGroup Label="Globals">
+ <ProjectName>inspect</ProjectName>
+ <ProjectGuid>{0EC8AC1C-6D1F-47FC-A06A-9CC3F924BD82}</ProjectGuid>
+ <RootNamespace>boost_inspect</RootNamespace>
+ <Keyword>Win32Proj</Keyword>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
+ <ConfigurationType>Application</ConfigurationType>
+ <CharacterSet>Unicode</CharacterSet>
+ <WholeProgramOptimization>true</WholeProgramOptimization>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
+ <ConfigurationType>Application</ConfigurationType>
+ <CharacterSet>Unicode</CharacterSet>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
+ <ImportGroup Label="ExtensionSettings">
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <PropertyGroup Label="UserMacros" />
+ <PropertyGroup>
+ <_ProjectFileVersion>10.0.40219.1</_ProjectFileVersion>
+ <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(SolutionDir)$(Configuration)\</OutDir>
+ <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(Configuration)\</IntDir>
+ <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</LinkIncremental>
+ <OutDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(SolutionDir)$(Configuration)\</OutDir>
+ <IntDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(Configuration)\</IntDir>
+ <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">false</LinkIncremental>
+ </PropertyGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+ <ClCompile>
+ <Optimization>Disabled</Optimization>
+ <AdditionalIncludeDirectories>..\..\..\..;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <MinimalRebuild>true</MinimalRebuild>
+ <ExceptionHandling>Async</ExceptionHandling>
+ <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
+ <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
+ <PrecompiledHeader>
+ </PrecompiledHeader>
+ <WarningLevel>Level3</WarningLevel>
+ <DebugInformationFormat>EditAndContinue</DebugInformationFormat>
+ </ClCompile>
+ <Link>
+ <AdditionalLibraryDirectories>..\..\..\..\stage\lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
+ <GenerateDebugInformation>true</GenerateDebugInformation>
+ <SubSystem>Console</SubSystem>
+ <TargetMachine>MachineX86</TargetMachine>
+ </Link>
+ <PostBuildEvent>
+ <Command>"$(TargetDir)\$(TargetName).exe" ../.. -text -brief</Command>
+ </PostBuildEvent>
+ <PostBuildEvent>
+ <Message>Executing test $(TargetName).exe...</Message>
+ </PostBuildEvent>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+ <ClCompile>
+ <Optimization>MaxSpeed</Optimization>
+ <IntrinsicFunctions>true</IntrinsicFunctions>
+ <AdditionalIncludeDirectories>..\..\..\..;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <ExceptionHandling>Async</ExceptionHandling>
+ <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
+ <FunctionLevelLinking>true</FunctionLevelLinking>
+ <PrecompiledHeader>
+ </PrecompiledHeader>
+ <WarningLevel>Level3</WarningLevel>
+ <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+ </ClCompile>
+ <Link>
+ <AdditionalLibraryDirectories>..\..\..\..\stage\lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
+ <GenerateDebugInformation>true</GenerateDebugInformation>
+ <SubSystem>Console</SubSystem>
+ <OptimizeReferences>true</OptimizeReferences>
+ <EnableCOMDATFolding>true</EnableCOMDATFolding>
+ <TargetMachine>MachineX86</TargetMachine>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemGroup>
+ <ClCompile Include="..\..\apple_macro_check.cpp" />
+ <ClCompile Include="..\..\ascii_check.cpp" />
+ <ClCompile Include="..\..\assert_macro_check.cpp" />
+ <ClCompile Include="..\..\copyright_check.cpp" />
+ <ClCompile Include="..\..\crlf_check.cpp" />
+ <ClCompile Include="..\..\deprecated_macro_check.cpp" />
+ <ClCompile Include="..\..\end_check.cpp" />
+ <ClCompile Include="..\..\inspect.cpp" />
+ <ClCompile Include="..\..\license_check.cpp" />
+ <ClCompile Include="..\..\link_check.cpp" />
+ <ClCompile Include="..\..\minmax_check.cpp" />
+ <ClCompile Include="..\..\path_name_check.cpp" />
+ <ClCompile Include="..\..\tab_check.cpp" />
+ <ClCompile Include="..\..\unnamed_namespace_check.cpp" />
+ </ItemGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
+ <ImportGroup Label="ExtensionTargets">
+ </ImportGroup>
+</Project> \ No newline at end of file
diff --git a/src/boost/tools/inspect/build/msvc/readme.txt b/src/boost/tools/inspect/build/msvc/readme.txt
new file mode 100644
index 000000000..a549811ad
--- /dev/null
+++ b/src/boost/tools/inspect/build/msvc/readme.txt
@@ -0,0 +1,8 @@
+The provided Microsoft VC++ 10 solution assumes the following commands have been run
+in the root directory:
+
+ b2 --toolset=msvc-10.0express --build-type=complete --with-filesystem stage
+ b2 --toolset=msvc-10.0express --build-type=complete --with-regex stage
+
+boost-no-inspect
+
diff --git a/src/boost/tools/inspect/copyright_check.cpp b/src/boost/tools/inspect/copyright_check.cpp
new file mode 100644
index 000000000..f56bbc955
--- /dev/null
+++ b/src/boost/tools/inspect/copyright_check.cpp
@@ -0,0 +1,35 @@
+// copyright_check implementation ------------------------------------------------//
+
+// Copyright Beman Dawes 2002.
+// 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 "copyright_check.hpp"
+
+namespace boost
+{
+ namespace inspect
+ {
+ copyright_check::copyright_check() : m_files_with_errors(0)
+ {
+ }
+
+ void copyright_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:" "nocopyright" ) != string::npos) return;
+
+ if ( contents.find( "Copyright" ) == string::npos
+ && contents.find( "copyright" ) == string::npos )
+ {
+ ++m_files_with_errors;
+ error( library_name, full_path, name() );
+ }
+ }
+ } // namespace inspect
+} // namespace boost
+
+
diff --git a/src/boost/tools/inspect/copyright_check.hpp b/src/boost/tools/inspect/copyright_check.hpp
new file mode 100644
index 000000000..278596e3e
--- /dev/null
+++ b/src/boost/tools/inspect/copyright_check.hpp
@@ -0,0 +1,39 @@
+// copyright_check header --------------------------------------------------//
+
+// Copyright Beman Dawes 2002, 2003.
+// Copyright Rene Rivera 2004.
+//
+// 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)
+
+#ifndef BOOST_COPYRIGHT_CHECK_HPP
+#define BOOST_COPYRIGHT_CHECK_HPP
+
+#include "inspector.hpp"
+
+namespace boost
+{
+ namespace inspect
+ {
+ class copyright_check : public source_inspector
+ {
+ long m_files_with_errors;
+ public:
+
+ copyright_check();
+ virtual const char * name() const { return "*C*"; }
+ virtual const char * desc() const { return "missing copyright notice"; }
+
+ virtual void inspect(
+ const std::string & library_name,
+ const path & full_path,
+ const std::string & contents );
+
+ virtual ~copyright_check()
+ { std::cout << " " << m_files_with_errors << " files " << desc() << line_break(); }
+ };
+ }
+}
+
+#endif // BOOST_COPYRIGHT_CHECK_HPP
diff --git a/src/boost/tools/inspect/crlf_check.cpp b/src/boost/tools/inspect/crlf_check.cpp
new file mode 100644
index 000000000..c38271140
--- /dev/null
+++ b/src/boost/tools/inspect/crlf_check.cpp
@@ -0,0 +1,97 @@
+// crlf_check implementation ------------------------------------------------//
+
+// Copyright Beman Dawes 2002.
+//
+// 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)
+
+// Contributed by Joerg Walter
+
+#include "crlf_check.hpp"
+
+namespace boost
+{
+ namespace inspect
+ {
+ crlf_check::crlf_check() : m_files_with_errors(0)
+ {
+ }
+
+ void crlf_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:" "nocrlf" ) != string::npos) return;
+
+ // this file deliberately contains errors
+ const char test_file_name[] = "wrong_line_ends_test.cpp";
+
+ bool failed = false;
+ // The understanding on line endings, as I remember it, was that
+ // either "\n" or "\r\n" is OK, and they can be mixed, but "\r" alone
+ // is not acceptable. Mixed line endings are allowed because Boost files
+ // are commonly edited in both Windows and UNIX environments, and editors
+ // in those environments generally accept either ending. Even Mac people
+ // agreed with this policy. --Beman
+
+ // Joerg's original implementation is saved below,
+ // in case we change our minds!
+
+ for ( std::string::const_iterator itr ( contents.begin() );
+ itr != contents.end(); ++itr )
+ {
+ if ( *itr == '\r' && ((itr+1) == contents.end() || *(itr+1) != '\n') )
+ {
+ failed = true;
+ break;
+ }
+ }
+
+ if (failed && full_path.leaf() != test_file_name)
+ {
+ ++m_files_with_errors;
+ error( library_name, full_path, name() );
+ }
+
+ if (!failed && full_path.leaf() == test_file_name)
+ {
+ ++m_files_with_errors;
+ error( library_name, full_path, string(name()) + " should have cr-only line endings" );
+ }
+
+/*
+ size_t cr_count = 0;
+ size_t lf_count = 0;
+ size_t crlf_count = 0;
+ bool had_cr = false;
+ for ( size_t i = 0; i < contents.length(); ++i )
+ {
+ switch ( contents[i] )
+ {
+ case '\r':
+ had_cr = true;
+ ++cr_count;
+ break;
+ case '\n':
+ ++lf_count;
+ if ( had_cr )
+ ++crlf_count;
+ // fallthrough
+ default:
+ had_cr = false;
+ break;
+ }
+ }
+ if ( cr_count > 0 && lf_count != crlf_count )
+ {
+ ++m_files_with_errors;
+ error( library_name, full_path, desc() );
+ }
+*/
+ }
+ } // namespace inspect
+} // namespace boost
+
+
diff --git a/src/boost/tools/inspect/crlf_check.hpp b/src/boost/tools/inspect/crlf_check.hpp
new file mode 100644
index 000000000..c6627ceee
--- /dev/null
+++ b/src/boost/tools/inspect/crlf_check.hpp
@@ -0,0 +1,40 @@
+// crfl_check header --------------------------------------------------------//
+
+// Copyright Beman Dawes 2002.
+// Copyright Rene Rivera 2004.
+// 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)
+
+// Contributed by Joerg Walter
+
+#ifndef BOOST_CRLF_CHECK_HPP
+#define BOOST_CRLF_CHECK_HPP
+
+#include "inspector.hpp"
+
+namespace boost
+{
+ namespace inspect
+ {
+ class crlf_check : public source_inspector
+ {
+ long m_files_with_errors;
+ public:
+
+ crlf_check();
+ virtual const char * name() const { return "*EOL*"; }
+ virtual const char * desc() const { return "invalid (cr only) line-ending"; }
+
+ virtual void inspect(
+ const std::string & library_name,
+ const path & full_path,
+ const std::string & contents );
+
+ virtual ~crlf_check()
+ { std::cout << " " << m_files_with_errors << " files with invalid line endings" << line_break(); }
+ };
+ }
+}
+
+#endif // BOOST_CRLF_CHECK_HPP
diff --git a/src/boost/tools/inspect/deprecated_macro_check.cpp b/src/boost/tools/inspect/deprecated_macro_check.cpp
new file mode 100644
index 000000000..7eeeda00c
--- /dev/null
+++ b/src/boost/tools/inspect/deprecated_macro_check.cpp
@@ -0,0 +1,146 @@
+// deprecated macro check implementation ---------------------------------------------//
+// Protect against ourself: boostinspect:ndprecated_macros
+
+// 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 "deprecated_macro_check.hpp"
+#include <functional>
+#include "boost/regex.hpp"
+#include "boost/lexical_cast.hpp"
+#include "boost/filesystem/operations.hpp"
+
+namespace fs = boost::filesystem;
+
+namespace
+{
+ const char * boost150macros [] = {
+ "BOOST_NO_0X_HDR_ARRAY",
+ "BOOST_NO_0X_HDR_CHRONO",
+ "BOOST_NO_0X_HDR_CODECVT",
+ "BOOST_NO_0X_HDR_CONDITION_VARIABLE",
+ "BOOST_NO_0X_HDR_FORWARD_LIST",
+ "BOOST_NO_0X_HDR_FUTURE",
+ "BOOST_NO_0X_HDR_INITIALIZER_LIST",
+ "BOOST_NO_INITIALIZER_LISTS",
+ "BOOST_NO_0X_HDR_MUTEX",
+ "BOOST_NO_0X_HDR_RANDOM",
+ "BOOST_NO_0X_HDR_RATIO",
+ "BOOST_NO_0X_HDR_REGEX",
+ "BOOST_NO_0X_HDR_SYSTEM_ERROR",
+ "BOOST_NO_0X_HDR_THREAD",
+ "BOOST_NO_0X_HDR_TUPLE",
+ "BOOST_NO_0X_HDR_TYPE_TRAITS",
+ "BOOST_NO_0X_HDR_TYPEINDEX",
+ "BOOST_NO_0X_HDR_UNORDERED_SET",
+ "BOOST_NO_0X_HDR_UNORDERED_MAP",
+ "BOOST_NO_STD_UNORDERED",
+ NULL
+ };
+
+ const char * boost151macros [] = {
+ "BOOST_NO_AUTO_DECLARATIONS",
+ "BOOST_NO_AUTO_MULTIDECLARATIONS",
+ "BOOST_NO_CHAR16_T",
+ "BOOST_NO_CHAR32_T",
+ "BOOST_NO_TEMPLATE_ALIASES",
+ "BOOST_NO_CONSTEXPR",
+ "BOOST_NO_DECLTYPE",
+ "BOOST_NO_DECLTYPE_N3276",
+ "BOOST_NO_DEFAULTED_FUNCTIONS",
+ "BOOST_NO_DELETED_FUNCTIONS",
+ "BOOST_NO_EXPLICIT_CONVERSION_OPERATORS",
+ "BOOST_NO_EXTERN_TEMPLATE",
+ "BOOST_NO_FUNCTION_TEMPLATE_DEFAULT_ARGS",
+ "BOOST_NO_LAMBDAS",
+ "BOOST_NO_LOCAL_CLASS_TEMPLATE_PARAMETERS",
+ "BOOST_NO_NOEXCEPT",
+ "BOOST_NO_NULLPTR",
+ "BOOST_NO_RAW_LITERALS",
+ "BOOST_NO_RVALUE_REFERENCES",
+ "BOOST_NO_SCOPED_ENUMS",
+ "BOOST_NO_STATIC_ASSERT",
+ "BOOST_NO_STD_UNORDERED",
+ "BOOST_NO_UNICODE_LITERALS",
+ "BOOST_NO_UNIFIED_INITIALIZATION_SYNTAX",
+ "BOOST_NO_VARIADIC_TEMPLATES",
+ "BOOST_NO_VARIADIC_MACROS",
+ "BOOST_NO_NUMERIC_LIMITS_LOWEST",
+ NULL
+ };
+
+ const char * boost153macros [] = {
+ "BOOST_HAS_STATIC_ASSERT",
+ "BOOST_HAS_RVALUE_REFS",
+ "BOOST_HAS_VARIADIC_TMPL",
+ "BOOST_HAS_CHAR16_T",
+ "BOOST_HAS_CHAR32_T",
+ NULL
+ };
+} // unnamed namespace
+
+
+namespace boost
+{
+ namespace inspect
+ {
+ deprecated_macro_check::deprecated_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 deprecated_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:" "ndprecated_macros" ) != string::npos)
+ return;
+
+ const char **ptr;
+ long errors = 0;
+ for ( ptr = boost150macros; *ptr != NULL; ++ptr )
+ {
+ if ( contents.find( *ptr ) != string::npos ) {
+ ++errors;
+ error( library_name, full_path, string ( "Boost macro deprecated in 1.50: " ) + *ptr );
+ }
+ }
+
+ for ( ptr = boost151macros; *ptr != NULL; ++ptr )
+ {
+ if ( contents.find( *ptr ) != string::npos ) {
+ ++errors;
+ error( library_name, full_path, string ( "Boost macro deprecated in 1.51: " ) + *ptr );
+ }
+ }
+
+ for ( ptr = boost153macros; *ptr != NULL; ++ptr )
+ {
+ if ( contents.find( *ptr ) != string::npos ) {
+ ++errors;
+ error( library_name, full_path, string ( "Boost macro deprecated in 1.53: " ) + *ptr );
+ }
+ }
+
+ if(errors > 0)
+ ++m_files_with_errors;
+ }
+ } // namespace inspect
+} // namespace boost
+
+
diff --git a/src/boost/tools/inspect/deprecated_macro_check.hpp b/src/boost/tools/inspect/deprecated_macro_check.hpp
new file mode 100644
index 000000000..c9093907d
--- /dev/null
+++ b/src/boost/tools/inspect/deprecated_macro_check.hpp
@@ -0,0 +1,40 @@
+// deprecated_macro_check header --------------------------------------------------------//
+
+// Copyright Eric Niebler 2010.
+// Based on the apple_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)
+
+#ifndef BOOST_DEPRECATED_MACRO_CHECK_HPP
+#define BOOST_DEPRECATED_MACRO_CHECK_HPP
+
+#include "inspector.hpp"
+
+
+namespace boost
+{
+ namespace inspect
+ {
+ class deprecated_macro_check : public inspector
+ {
+ long m_files_with_errors;
+ bool m_from_boost_root;
+ public:
+
+ deprecated_macro_check();
+ virtual const char * name() const { return "*DEPRECATED-MACROS*"; }
+ virtual const char * desc() const { return "presence of deprecated BOOST macro in file (see docs for replacements)"; }
+
+ virtual void inspect(
+ const std::string & library_name,
+ const path & full_path,
+ const std::string & contents );
+
+ virtual ~deprecated_macro_check()
+ { std::cout << " " << m_files_with_errors << " files with a deprecated BOOST macro" << line_break(); }
+ };
+ }
+}
+
+#endif // BOOST_DEPRECATED_MACRO_CHECK_HPP
diff --git a/src/boost/tools/inspect/end_check.cpp b/src/boost/tools/inspect/end_check.cpp
new file mode 100644
index 000000000..9c1e438af
--- /dev/null
+++ b/src/boost/tools/inspect/end_check.cpp
@@ -0,0 +1,58 @@
+// end_check implementation -------------------------------------------------//
+
+// Copyright Beman Dawes 2002.
+// Copyright Daniel James 2009.
+//
+// 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 "end_check.hpp"
+#include <boost/next_prior.hpp>
+
+namespace boost
+{
+ namespace inspect
+ {
+ end_check::end_check() : m_files_with_errors(0)
+ {
+ register_signature( ".c" );
+ register_signature( ".cpp" );
+ register_signature( ".cxx" );
+ register_signature( ".h" );
+ register_signature( ".hpp" );
+ register_signature( ".hxx" );
+ register_signature( ".ipp" );
+ }
+
+ void end_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:" "noend" ) != string::npos) return;
+
+ // this file deliberately contains errors
+ const char test_file_name[] = "wrong_line_ends_test.cpp";
+
+ char final_char = contents.begin() == contents.end() ? '\0'
+ : *(boost::prior(contents.end()));
+
+ bool failed = final_char != '\n' && final_char != '\r';
+
+ if (failed && full_path.leaf() != test_file_name)
+ {
+ ++m_files_with_errors;
+ error( library_name, full_path, string(name()) + ' ' + desc() );
+ }
+
+ if (!failed && full_path.leaf() == test_file_name)
+ {
+ ++m_files_with_errors;
+ error( library_name, full_path, string(name()) + " should not end with a newline" );
+ }
+ }
+ } // namespace inspect
+} // namespace boost
+
+
diff --git a/src/boost/tools/inspect/end_check.hpp b/src/boost/tools/inspect/end_check.hpp
new file mode 100644
index 000000000..41e5041ce
--- /dev/null
+++ b/src/boost/tools/inspect/end_check.hpp
@@ -0,0 +1,40 @@
+// end_check header ---------------------------------------------------------//
+
+// Copyright Beman Dawes 2002.
+// Copyright Rene Rivera 2004.
+// Copyright Daniel James 2009.
+//
+// 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)
+
+#ifndef BOOST_END_CHECK_HPP
+#define BOOST_END_CHECK_HPP
+
+#include "inspector.hpp"
+
+namespace boost
+{
+ namespace inspect
+ {
+ class end_check : public inspector
+ {
+ long m_files_with_errors;
+ public:
+
+ end_check();
+ virtual const char * name() const { return "*END*"; }
+ virtual const char * desc() const { return "file doesn't end with a newline"; }
+
+ virtual void inspect(
+ const std::string & library_name,
+ const path & full_path,
+ const std::string & contents );
+
+ virtual ~end_check()
+ { std::cout << " " << m_files_with_errors << " files that don't end with a newline" << line_break(); }
+ };
+ }
+}
+
+#endif // BOOST_END_CHECK_HPP
diff --git a/src/boost/tools/inspect/index.html b/src/boost/tools/inspect/index.html
new file mode 100644
index 000000000..c8abdf337
--- /dev/null
+++ b/src/boost/tools/inspect/index.html
@@ -0,0 +1,55 @@
+<html>
+
+<head>
+<meta http-equiv="Content-Language" content="en-us">
+<meta name="GENERATOR" content="Microsoft FrontPage 5.0">
+<meta name="ProgId" content="FrontPage.Editor.Document">
+<meta http-equiv="Content-Type" content="text/html; charset=windows-1252">
+<title>Inspect Tool</title>
+</head>
+
+<body bgcolor="#FFFFFF">
+
+<h1>
+<img src="../../boost.png" alt="boost.png (6897 bytes)" align="center" width="277" height="86">Inspect
+Tool</h1>
+<p>It is not uncommon for various common errors or
+<a href="http://www.boost.org/more/lib_guide.htm">guideline violations</a> to creep into the
+Boost libraries. The <i>inspect</i> program detects and reports several common
+problems. It can be used to scan a proposed Boost submission to identify various
+failures.</p>
+<p>The <i>inspect</i> program is written in C++ to limit tool chain
+dependencies, and should be portable to any system.</p>
+<p>The program is run in the directory to be scanned for errors. Sub-directories
+are also included in the scan.</p>
+<p>If the first program argument is <code>-help</code>, a usage message is
+displayed, showing all available program options.</p>
+<p>The program sources include:</p>
+<ul>
+ <li><a href="inspector.hpp">inspect.hpp</a> and <a href="inspect.cpp">
+ inspect.cpp</a></li>
+ <li><a href="link_check.hpp">link_check.hpp</a> and <a href="link_check.cpp">
+ link_check.cpp</a></li>
+ <li><a href="path_name_check.hpp">path_name_check.hpp</a> and
+ <a href="path_name_check.cpp">path_name_check.cpp</a></li>
+ <li><a href="tab_check.hpp">tab_check.hpp</a> and <a href="tab_check.cpp">
+ tab_check.cpp</a></li>
+</ul>
+<p>A <a href="build/Jamfile.v2">Jamfile</a> is provided to build the program
+using Boost.Build.</p>
+<p>A Microsoft Visual Studio solution file is provided to aid maintenance. See
+<a href="build/msvc/readme.txt">readme.txt</a>
+before using it.</p>
+<hr>
+<p>Revised
+<!--webbot bot="Timestamp" S-Type="EDITED" S-Format="%d %B, %Y" startspan -->29 June, 2008<!--webbot bot="Timestamp" endspan i-checksum="19976" --></p>
+
+<p>© Copyright Beman Dawes, 2003</p>
+<p> Distributed under the Boost Software
+License, Version 1.0. (See accompanying file <a href="../../LICENSE_1_0.txt">
+LICENSE_1_0.txt</a> or copy at <a href="http://www.boost.org/LICENSE_1_0.txt">
+www.boost.org/LICENSE_1_0.txt</a>)</p>
+
+</body>
+
+</html>
diff --git a/src/boost/tools/inspect/inspect.cpp b/src/boost/tools/inspect/inspect.cpp
new file mode 100644
index 000000000..eb759fb3e
--- /dev/null
+++ b/src/boost/tools/inspect/inspect.cpp
@@ -0,0 +1,1041 @@
+// 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 "bin",
+// and the code that identifies library names assumes the Boost directory
+// structure.
+
+// 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>
+#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 <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"
+
+// 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 "assert_macro_check.hpp"
+#include "deprecated_macro_check.hpp"
+#include "minmax_check.hpp"
+#include "unnamed_namespace_check.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;
+
+using namespace boost::inspect;
+
+namespace
+{
+ fs::path search_root = fs::initial_path();
+
+ 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;
+
+// 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, 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
+ // don't look at binaries
+ leaf != "bin"
+ && leaf != "bin.v2"
+ // no point in checking doxygen xml output
+ && local.find("doc/xml") != 0
+ && local.find("doc\\xml") != 0
+ // ignore if tag file present
+ && !boost::filesystem::exists(pth / boost_no_inspect)
+ ;
+ }
+
+// 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().string() );
+ 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 if (itr->path().leaf().string()[0] != '.') // ignore if hidden
+ {
+ ++file_count;
+ string content;
+ load_content( *itr, content );
+ if (content.find(boost_no_inspect) == string::npos)
+ 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_format == display_text)
+ {
+ 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_format == display_text)
+ {
+ 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_format == display_text)
+ std::cout << "\n";
+ else
+ std::cout << "</blockquote>\n";
+ }
+
+// html_encode -------------------------------------------------------------//
+
+ std::string html_encode(std::string const& text)
+ {
+ std::string result;
+
+ for(std::string::const_iterator it = text.begin(),
+ end = text.end(); it != end; ++it)
+ {
+ switch(*it) {
+ case '<':
+ result += "&lt;";
+ break;
+ case '>':
+ result += "&gt;";
+ break;
+ case '&':
+ result += "&amp;";
+ break;
+ default:
+ result += *it;
+ }
+ }
+
+ return result;
+ }
+
+// display_details ---------------------------------------------------------//
+
+ void display_details()
+ {
+ if (display_format == display_text)
+ {
+ // 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>&nbsp;&nbsp;&nbsp; ";
+ else sep = ": ";
+ else
+ if (itr->line_number) sep = "<br>&nbsp;&nbsp;&nbsp; ";
+ else sep = ", ";
+
+ // print the message
+ if (itr->line_number)
+ std::cout << sep << "(line " << itr->line_number << ") " << html_encode(itr->msg);
+ else std::cout << sep << html_encode(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_mode == display_brief)
+ return;
+ if (display_format == display_text)
+ {
+ 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_format == display_text)
+ {
+ 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_format == display_text)
+ std::cout << "\n";
+ else
+ std::cout << "</blockquote>\n";
+ }
+
+
+ const char * options()
+ {
+ return
+ " Output Options:\n\n"
+ " -brief\n"
+ " -text\n"
+ " -version-string <version message>\n"
+ "\n"
+ " Checks:\n\n"
+ " -license\n"
+ " -copyright\n"
+ " -crlf\n"
+ " -end\n"
+ " -link\n"
+ " -path_name\n"
+ " -tab\n"
+ " -ascii\n"
+ " -apple_macro\n"
+ " -assert_macro\n"
+ " -deprecated_macro\n"
+ " -minmax\n"
+ " -unnamed\n"
+ " -version-string <version message>\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";
+ }
+
+// search_root_path --------------------------------------------------------//
+
+ path search_root_path()
+ {
+ return search_root;
+ }
+
+// 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, search_root_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, search_root_path() ) );
+ if ( relative.empty() ) return "boost-root";
+ string first( (*relative.begin()).string() );
+ string second = // borland 5.61 requires op=
+ ++relative.begin() == relative.end()
+ ? string() : (*++relative.begin()).string();
+
+ if ( first == "boost" )
+ return second;
+
+ return (( first == "libs" || first == "tools" ) && !second.empty())
+ ? second : first;
+ }
+
+ } // namespace inspect
+} // 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;
+ // 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 [search-root] [options...]\n\n"
+ " search-root default is the current directory (i.e. '.')\n\n"
+ << options() << '\n';
+ return 0;
+ }
+
+ bool options_not_set = true;
+ bool license_ck = false;
+ bool copyright_ck = false;
+ bool crlf_ck = false;
+ bool end_ck = false;
+ bool link_ck = false;
+ bool path_name_ck = false;
+ bool tab_ck = false;
+ bool ascii_ck = false;
+ bool apple_ck = false;
+ bool assert_ck = false;
+ bool deprecated_ck = false;
+ bool minmax_ck = false;
+ bool unnamed_ck = false;
+ const char* version_string = 0;
+
+ if ( argc > 1 && *argv[1] != '-' )
+ {
+ search_root = fs::canonical(fs::absolute(argv[1], fs::initial_path()));
+ --argc; ++argv;
+ }
+
+ bool invalid_options = false;
+ for(; argc > 1; --argc, ++argv )
+ {
+ if ( std::strcmp( argv[1], "-license" ) == 0 ) {
+ options_not_set = false;
+ license_ck = true;
+ }
+ else if ( std::strcmp( argv[1], "-copyright" ) == 0 ) {
+ options_not_set = false;
+ copyright_ck = true;
+ }
+ else if ( std::strcmp( argv[1], "-crlf" ) == 0 ) {
+ options_not_set = false;
+ crlf_ck = true;
+ }
+ else if ( std::strcmp( argv[1], "-end" ) == 0 ) {
+ options_not_set = false;
+ end_ck = true;
+ }
+ else if ( std::strcmp( argv[1], "-link" ) == 0 ) {
+ options_not_set = false;
+ link_ck = true;
+ }
+ else if ( std::strcmp( argv[1], "-path_name" ) == 0 ) {
+ options_not_set = false;
+ path_name_ck = true;
+ }
+ else if ( std::strcmp( argv[1], "-tab" ) == 0 ) {
+ options_not_set = false;
+ tab_ck = true;
+ }
+ else if ( std::strcmp( argv[1], "-ascii" ) == 0 ) {
+ options_not_set = false;
+ ascii_ck = true;
+ }
+ else if ( std::strcmp( argv[1], "-apple_macro" ) == 0 ) {
+ options_not_set = false;
+ apple_ck = true;
+ }
+ else if ( std::strcmp( argv[1], "-assert_macro" ) == 0 ) {
+ options_not_set = false;
+ assert_ck = true;
+ }
+ else if ( std::strcmp( argv[1], "-deprecated_macro" ) == 0 ) {
+ options_not_set = false;
+ deprecated_ck = true;
+ }
+ else if ( std::strcmp( argv[1], "-minmax" ) == 0 ) {
+ options_not_set = false;
+ minmax_ck = true;
+ }
+ else if ( std::strcmp( argv[1], "-unnamed" ) == 0 ) {
+ options_not_set = false;
+ unnamed_ck = true;
+ }
+ else if ( argc > 1 && std::strcmp( argv[1], "-text" ) == 0 )
+ {
+ display_format = display_text;
+ }
+ else if ( argc > 1 && std::strcmp( argv[1], "-brief" ) == 0 )
+ {
+ display_mode = display_brief;
+ }
+ else if ( std::strcmp( argv[1], "-version-string" ) == 0 ) {
+ if (argc == 2 || argv[2][0] == '-') {
+ std::cerr << "Missing value for -version-string.\n";
+ invalid_options = true;
+ }
+ else {
+ --argc, ++argv;
+ version_string = argv[1];
+ }
+ }
+ else
+ {
+ std::cerr << "unknown option: " << argv[1] << '\n';
+ invalid_options = true;
+ }
+ }
+ if ( invalid_options ) {
+ std::cerr << "\nvalid options are:\n"
+ << options();
+ return 1;
+ }
+
+ if (options_not_set) {
+ license_ck = true;
+ copyright_ck = true;
+ crlf_ck = true;
+ end_ck = true;
+ link_ck = true;
+ path_name_ck = true;
+ tab_ck = true;
+ ascii_ck = true;
+ apple_ck = true;
+ assert_ck = true;
+ deprecated_ck = true;
+ minmax_ck = true;
+ unnamed_ck = true;
+ }
+
+ string inspector_keys;
+
+ { // 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_ck )
+ inspectors.push_back( inspector_element( new boost::inspect::apple_macro_check ) );
+ 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 ) );
+
+ visit_all<fs::directory_iterator>( search_root.leaf().string(),
+ search_root, 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_format == display_text)
+ {
+ std::cout
+ <<
+ "Boost Inspection Report\n"
+ "Run Date: " << run_date << "\n"
+ "\n"
+ ;
+
+ if (version_string) {
+ std::cout
+ << "The files checked were from "
+ << version_string
+ << ".\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"
+ //"&nbsp;&nbsp;/ " << 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"
+ ;
+ if (version_string) {
+ std::cout
+ << "<p>The files checked were from "
+ << html_encode(version_string)
+ << ".</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_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_format == display_text)
+ 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_mode != display_brief)
+ display_worst_offenders();
+
+ if ( !msgs.empty() )
+ {
+ display_summary();
+
+ 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_format == display_text)
+ {
+ std::cout << "\n\n" ;
+ }
+ else
+ {
+ std::cout
+ << "</body>\n"
+ "</html>\n";
+ }
+
+ return error_count ? 1 : 0;
+}
diff --git a/src/boost/tools/inspect/inspector.hpp b/src/boost/tools/inspect/inspector.hpp
new file mode 100644
index 000000000..408a4f868
--- /dev/null
+++ b/src/boost/tools/inspect/inspector.hpp
@@ -0,0 +1,108 @@
+// inspector header --------------------------------------------------------//
+
+// Copyright Beman Dawes 2002.
+// Copyright Rene Rivera 2004.
+// 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)
+
+#ifndef BOOST_INSPECTOR_HPP
+#define BOOST_INSPECTOR_HPP
+
+#include <set>
+#include <iostream>
+#include <ostream>
+#include <string>
+#include "boost/filesystem/path.hpp"
+
+using std::string;
+using boost::filesystem::path;
+
+namespace boost
+{
+ namespace inspect
+ {
+ typedef std::set< string > string_set;
+
+ const char * line_break();
+
+ path search_root_path();
+
+ class inspector
+ {
+ protected:
+ inspector() {}
+
+ public:
+ virtual ~inspector() {}
+
+ virtual const char * name() const = 0; // example: "tab-check"
+ virtual const char * desc() const = 0; // example: "verify no tabs"
+
+ // always called:
+ virtual void inspect(
+ const string & /*library_name*/, // "filesystem"
+ const path & /*full_path*/ ) {} // "c:/foo/boost/filesystem/path.hpp"
+
+ // called only for registered leaf() signatures:
+ virtual void inspect(
+ const string & library_name, // "filesystem"
+ const path & full_path, // "c:/foo/boost/filesystem/path.hpp"
+ const string & contents ) // contents of file
+ = 0
+ ;
+
+ // called after all paths visited, but still in time to call error():
+ virtual void close() {}
+
+ // callback used by constructor to register leaf() signature.
+ // Signature can be a full file name (Jamfile) or partial (.cpp)
+ void register_signature( const string & signature );
+ const string_set & signatures() const { return m_signatures; }
+
+ // report error callback (from inspect(), close() ):
+ void error(
+ const string & library_name,
+ const path & full_path,
+ const string & msg,
+ int line_number =0 ); // 0 if not available or not applicable
+
+ private:
+ string_set m_signatures;
+ };
+
+ // for inspection of source code of one form or other
+ class source_inspector : public inspector
+ {
+ public:
+ // registers the basic set of known source signatures
+ source_inspector();
+ };
+
+ // for inspection of hypertext, specifically html
+ class hypertext_inspector : public inspector
+ {
+ public:
+ // registers the set of known html source signatures
+ hypertext_inspector();
+ };
+
+ inline string relative_to( const path & src_arg, const path & base_arg )
+ {
+ path base( base_arg );
+ base.normalize();
+ string::size_type pos( base.string().size() );
+ path src( src_arg.string().substr(pos) );
+ src.normalize();
+ return src.string().substr(1);
+ }
+
+ string impute_library( const path & full_dir_path );
+
+ }
+}
+
+#endif // BOOST_INSPECTOR_HPP
+
diff --git a/src/boost/tools/inspect/license_check.cpp b/src/boost/tools/inspect/license_check.cpp
new file mode 100644
index 000000000..86d1d20e7
--- /dev/null
+++ b/src/boost/tools/inspect/license_check.cpp
@@ -0,0 +1,48 @@
+// license_check implementation --------------------------------------------//
+
+// Copyright Beman Dawes 2002-2003.
+// 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 "boost/regex.hpp"
+#include "license_check.hpp"
+
+namespace
+{
+ boost::regex license_regex(
+ //~ The next two lines change the regex so that it detects when the license
+ //~ doesn't follow the prefered statement. Disabled because it currently
+ //~ generates a large number of issues.
+ //~ "Distributed[\\s\\W]+"
+ //~ "under[\\s\\W]+the[\\s\\W]+"
+ "boost[\\s\\W]+software[\\s\\W]+license",
+ boost::regbase::normal | boost::regbase::icase);
+
+} // unnamed namespace
+
+namespace boost
+{
+ namespace inspect
+ {
+ license_check::license_check() : m_files_with_errors(0)
+ {
+ }
+
+ void license_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:" "nolicense" ) != string::npos) return;
+
+ if ( !boost::regex_search( contents, license_regex ) )
+ {
+ ++m_files_with_errors;
+ error( library_name, full_path, name() );
+ }
+ }
+ } // namespace inspect
+} // namespace boost
+
+
diff --git a/src/boost/tools/inspect/license_check.hpp b/src/boost/tools/inspect/license_check.hpp
new file mode 100644
index 000000000..831202363
--- /dev/null
+++ b/src/boost/tools/inspect/license_check.hpp
@@ -0,0 +1,40 @@
+// license_check header ----------------------------------------------------//
+
+// Copyright Beman Dawes 2002, 2003.
+// Copyright Rene Rivera 2004.
+//
+// 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)
+
+#ifndef BOOST_LICENSE_CHECK_HPP
+#define BOOST_LICENSE_CHECK_HPP
+
+#include "inspector.hpp"
+
+namespace boost
+{
+ namespace inspect
+ {
+ class license_check : public source_inspector
+ {
+ long m_files_with_errors;
+ public:
+
+ license_check();
+ virtual const char * name() const { return "*Lic*"; }
+ virtual const char * desc() const { return "missing Boost license info, or wrong reference text"; }
+
+ virtual void inspect(
+ const std::string & library_name,
+ const path & full_path,
+ const std::string & contents );
+
+ virtual ~license_check()
+ { std::cout << " "
+ << m_files_with_errors << " files missing Boost license info or having wrong reference text" << line_break(); }
+ };
+ }
+}
+
+#endif // BOOST_LICENSE_CHECK_HPP
diff --git a/src/boost/tools/inspect/link_check.cpp b/src/boost/tools/inspect/link_check.cpp
new file mode 100644
index 000000000..182af3bf7
--- /dev/null
+++ b/src/boost/tools/inspect/link_check.cpp
@@ -0,0 +1,487 @@
+// link_check implementation -----------------------------------------------//
+
+// Copyright Beman Dawes 2002.
+//
+// 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 "link_check.hpp"
+#include "boost/regex.hpp"
+#include "boost/filesystem/operations.hpp"
+#include <boost/algorithm/string/case_conv.hpp>
+#include <cstdlib>
+#include <set>
+
+// #include <iostream>
+
+namespace fs = boost::filesystem;
+
+namespace
+{
+ boost::regex html_bookmark_regex(
+ "<([^\\s<>]*)\\s*[^<>]*\\s+(NAME|ID)\\s*=\\s*(['\"])(.*?)\\3"
+ "|<!--.*?-->",
+ boost::regbase::normal | boost::regbase::icase);
+ boost::regex html_url_regex(
+ "<([^\\s<>]*)\\s*[^<>]*\\s+(?:HREF|SRC)" // HREF or SRC
+ "\\s*=\\s*(['\"])\\s*(.*?)\\s*\\2"
+ "|<!--.*?-->",
+ boost::regbase::normal | boost::regbase::icase);
+ boost::regex css_url_regex(
+ "(\\@import\\s*[\"']|url\\s*\\(\\s*[\"']?)([^\"')]*)"
+ "|/\\*.*?\\*/",
+ boost::regbase::normal | boost::regbase::icase);
+
+ // Regular expression for parsing URLS from:
+ // http://tools.ietf.org/html/rfc3986#appendix-B
+ boost::regex url_decompose_regex(
+ "^(([^:/?#]+):)?(//([^/?#]*))?([^?#]*)(\\?([^#]*))?(#(.*))?$",
+ boost::regbase::normal);
+
+ typedef std::set<std::string> bookmark_set;
+ bookmark_set bookmarks;
+ bookmark_set bookmarks_lowercase; // duplicate check needs case insensitive
+
+ // Decode html escapsed ampersands, returns an empty string if there's an error.
+ std::string decode_ampersands(std::string const& url_path) {
+ std::string::size_type pos = 0, next;
+ std::string result;
+ result.reserve(url_path.length());
+
+ while((next = url_path.find('&', pos)) != std::string::npos) {
+ result.append(url_path, pos, next - pos);
+ pos = next;
+ if(url_path.substr(pos, 5) == "&amp;") {
+ result += '&'; pos += 5;
+ }
+ else {
+ result += '&'; pos += 1;
+ }
+ break;
+ }
+
+ result.append(url_path, pos, url_path.length());
+
+ return result;
+ }
+
+ // Decode percent encoded characters, returns an empty string if there's an error.
+ std::string decode_percents(std::string const& url_path) {
+ std::string::size_type pos = 0, next;
+ std::string result;
+ result.reserve(url_path.length());
+
+ while((next = url_path.find('%', pos)) != std::string::npos) {
+ result.append(url_path, pos, next - pos);
+ pos = next;
+ switch(url_path[pos]) {
+ case '%': {
+ if(url_path.length() - next < 3) return "";
+ char hex[3] = { url_path[next + 1], url_path[next + 2], '\0' };
+ char* end_ptr;
+ result += (char) std::strtol(hex, &end_ptr, 16);
+ if(*end_ptr) return "";
+ pos = next + 3;
+ break;
+ }
+ }
+ }
+
+ result.append(url_path, pos, url_path.length());
+
+ return result;
+ }
+
+ bool is_css(const path & p) {
+ return p.extension() == ".css";
+ }
+
+} // unnamed namespace
+
+namespace boost
+{
+ namespace inspect
+ {
+
+// link_check constructor --------------------------------------------------//
+
+ link_check::link_check()
+ : m_broken_errors(0), m_unlinked_errors(0), m_invalid_errors(0),
+ m_bookmark_errors(0), m_duplicate_bookmark_errors(0)
+ {
+ // HTML signatures are already registered by the base class,
+ // 'hypertext_inspector'
+ register_signature(".css");
+ }
+
+// inspect (all) -----------------------------------------------------------//
+
+ void link_check::inspect(
+ const string & /*library_name*/,
+ const path & full_path )
+ {
+ // keep track of paths already encountered to reduce disk activity
+ if ( !fs::is_directory( full_path ) )
+ m_paths[ relative_to( full_path, search_root_path() ) ] |= m_present;
+ }
+
+// inspect ( .htm, .html, .shtml, .css ) -----------------------------------//
+
+ void link_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:" "nounlinked" ) != string::npos)
+ m_paths[ relative_to( full_path, search_root_path() ) ] |= m_nounlinked_errors;
+
+ bool no_link_errors =
+ (contents.find( "boostinspect:" "nolink" ) != string::npos);
+
+ // build bookmarks databases
+ bookmarks.clear();
+ bookmarks_lowercase.clear();
+ string::const_iterator a_start( contents.begin() );
+ string::const_iterator a_end( contents.end() );
+ boost::match_results< string::const_iterator > a_what;
+ boost::match_flag_type a_flags = boost::match_default;
+
+ if(!is_css(full_path))
+ {
+ string previous_id;
+
+ while( boost::regex_search( a_start, a_end, a_what, html_bookmark_regex, a_flags) )
+ {
+ // a_what[0] contains the whole string iterators.
+ // a_what[1] contains the tag iterators.
+ // a_what[2] contains the attribute name.
+ // a_what[4] contains the bookmark iterators.
+
+ if (a_what[4].matched)
+ {
+ string tag( a_what[1].first, a_what[1].second );
+ boost::algorithm::to_lower(tag);
+ string attribute( a_what[2].first, a_what[2].second );
+ boost::algorithm::to_lower(attribute);
+ string bookmark( a_what[4].first, a_what[4].second );
+
+ bool name_following_id = ( attribute == "name" && previous_id == bookmark );
+ if ( tag != "meta" && attribute == "id" ) previous_id = bookmark;
+ else previous_id.clear();
+
+ if ( tag != "meta" && !name_following_id )
+ {
+ bookmarks.insert( bookmark );
+// std::cout << "******************* " << bookmark << '\n';
+
+ // w3.org recommends case-insensitive checking for duplicate bookmarks
+ // since some browsers do a case-insensitive match.
+ string bookmark_lowercase( bookmark );
+ boost::algorithm::to_lower(bookmark_lowercase);
+
+ std::pair<bookmark_set::iterator, bool> result
+ = bookmarks_lowercase.insert( bookmark_lowercase );
+ if (!result.second)
+ {
+ ++m_duplicate_bookmark_errors;
+ int ln = std::count( contents.begin(), a_what[3].first, '\n' ) + 1;
+ error( library_name, full_path, "Duplicate bookmark: " + bookmark, ln );
+ }
+ }
+ }
+
+ a_start = a_what[0].second; // update search position
+ a_flags |= boost::match_prev_avail; // update flags
+ a_flags |= boost::match_not_bob;
+ }
+ }
+
+ // process urls
+ string::const_iterator start( contents.begin() );
+ string::const_iterator end( contents.end() );
+ boost::match_results< string::const_iterator > what;
+ boost::match_flag_type flags = boost::match_default;
+
+ if(!is_css(full_path))
+ {
+ while( boost::regex_search( start, end, what, html_url_regex, flags) )
+ {
+ // what[0] contains the whole string iterators.
+ // what[1] contains the element type iterators.
+ // what[3] contains the URL iterators.
+
+ if(what[3].matched)
+ {
+ string type( what[1].first, what[1].second );
+ boost::algorithm::to_lower(type);
+
+ // TODO: Complain if 'link' tags use external stylesheets.
+ do_url( string( what[3].first, what[3].second ),
+ library_name, full_path, no_link_errors,
+ type == "a" || type == "link", contents.begin(), what[3].first );
+ }
+
+ start = what[0].second; // update search position
+ flags |= boost::match_prev_avail; // update flags
+ flags |= boost::match_not_bob;
+ }
+ }
+
+ while( boost::regex_search( start, end, what, css_url_regex, flags) )
+ {
+ // what[0] contains the whole string iterators.
+ // what[2] contains the URL iterators.
+
+ if(what[2].matched)
+ {
+ do_url( string( what[2].first, what[2].second ),
+ library_name, full_path, no_link_errors, false,
+ contents.begin(), what[3].first );
+ }
+
+ start = what[0].second; // update search position
+ flags |= boost::match_prev_avail; // update flags
+ flags |= boost::match_not_bob;
+ }
+ }
+
+// do_url ------------------------------------------------------------------//
+
+ void link_check::do_url( const string & url, const string & library_name,
+ const path & source_path, bool no_link_errors, bool allow_external_content,
+ std::string::const_iterator contents_begin, std::string::const_iterator url_start )
+ // precondition: source_path.is_complete()
+ {
+ if(!no_link_errors && url.empty()) {
+ ++m_invalid_errors;
+ int ln = std::count( contents_begin, url_start, '\n' ) + 1;
+ error( library_name, source_path, "Empty URL.", ln );
+ return;
+ }
+
+ // Decode ampersand encoded characters.
+ string decoded_url = is_css(source_path) ? url : decode_ampersands(url);
+ if(decoded_url.empty()) {
+ if(!no_link_errors) {
+ ++m_invalid_errors;
+ int ln = std::count( contents_begin, url_start, '\n' ) + 1;
+ error( library_name, source_path,
+ "Invalid URL (invalid ampersand encodings): " + url, ln );
+ }
+ return;
+ }
+
+ boost::smatch m;
+ if(!boost::regex_match(decoded_url, m, url_decompose_regex)) {
+ if(!no_link_errors) {
+ ++m_invalid_errors;
+ int ln = std::count( contents_begin, url_start, '\n' ) + 1;
+ error( library_name, source_path, "Invalid URL: " + decoded_url, ln );
+ }
+ return;
+ }
+
+ bool scheme_matched = m[2].matched,
+ authority_matched = m[4].matched,
+ //query_matched = m[7].matched,
+ fragment_matched = m[9].matched;
+
+ std::string scheme(m[2]),
+ authority(m[4]),
+ url_path(m[5]),
+ //query(m[7]),
+ fragment(m[9]);
+
+ // Check for external content
+ if(!allow_external_content && (authority_matched || scheme_matched)) {
+ if(!no_link_errors) {
+ ++m_invalid_errors;
+ int ln = std::count( contents_begin, url_start, '\n' ) + 1;
+ error( library_name, source_path, "External content: " + decoded_url, ln );
+ }
+ }
+
+ // Protocol checks
+ if(scheme_matched) {
+ if(scheme == "http" || scheme == "https") {
+ // All http links should have a hostname. Generally if they don't
+ // it's by mistake. If they shouldn't, then a protocol isn't
+ // required.
+ if(!authority_matched) {
+ if(!no_link_errors) {
+ ++m_invalid_errors;
+ int ln = std::count( contents_begin, url_start, '\n' ) + 1;
+ error( library_name, source_path, "No hostname: " + decoded_url, ln );
+ }
+ }
+
+ return;
+ }
+ else if(scheme == "file") {
+ if(!no_link_errors) {
+ ++m_invalid_errors;
+ int ln = std::count( contents_begin, url_start, '\n' ) + 1;
+ error( library_name, source_path,
+ "Invalid URL (hardwired file): " + decoded_url, ln );
+ }
+ }
+ else if(scheme == "mailto" || scheme == "ftp" || scheme == "news" || scheme == "javascript") {
+ if ( !no_link_errors && is_css(source_path) ) {
+ ++m_invalid_errors;
+ int ln = std::count( contents_begin, url_start, '\n' ) + 1;
+ error( library_name, source_path,
+ "Invalid protocol for css: " + decoded_url, ln );
+ }
+ }
+ else {
+ if(!no_link_errors) {
+ ++m_invalid_errors;
+ int ln = std::count( contents_begin, url_start, '\n' ) + 1;
+ error( library_name, source_path, "Unknown protocol: '" + scheme + "' in url: " + decoded_url, ln );
+ }
+ }
+
+ return;
+ }
+
+ // Hostname without protocol.
+ if(authority_matched) {
+ if(!no_link_errors) {
+ ++m_invalid_errors;
+ int ln = std::count( contents_begin, url_start, '\n' ) + 1;
+ error( library_name, source_path,
+ "Invalid URL (hostname without protocol): " + decoded_url, ln );
+ }
+ }
+
+ // Check the fragment identifier
+ if ( fragment_matched ) {
+ if ( is_css(source_path) ) {
+ if ( !no_link_errors ) {
+ ++m_invalid_errors;
+ int ln = std::count( contents_begin, url_start, '\n' ) + 1;
+ error( library_name, source_path,
+ "Fragment link in CSS: " + decoded_url, ln );
+ }
+ }
+ else {
+ if ( !no_link_errors && fragment.find( '#' ) != string::npos )
+ {
+ ++m_bookmark_errors;
+ int ln = std::count( contents_begin, url_start, '\n' ) + 1;
+ error( library_name, source_path, "Invalid bookmark: " + decoded_url, ln );
+ }
+ else if ( !no_link_errors && url_path.empty() && !fragment.empty()
+ // w3.org recommends case-sensitive broken bookmark checking
+ // since some browsers do a case-sensitive match.
+ && bookmarks.find(decode_percents(fragment)) == bookmarks.end() )
+ {
+ ++m_broken_errors;
+ int ln = std::count( contents_begin, url_start, '\n' ) + 1;
+ error( library_name, source_path, "Unknown bookmark: " + decoded_url, ln );
+ }
+ }
+
+ // No more to do if it's just a fragment identifier
+ if(url_path.empty()) return;
+ }
+
+ // Detect characters banned by RFC2396:
+ if ( !no_link_errors && decoded_url.find_first_of( " <>\"{}|\\^[]'" ) != string::npos )
+ {
+ ++m_invalid_errors;
+ int ln = std::count( contents_begin, url_start, '\n' ) + 1;
+ error( library_name, source_path,
+ "Invalid character in URL: " + decoded_url, ln );
+ }
+
+ // Check that we actually have a path.
+ if(url_path.empty()) {
+ if(!no_link_errors) {
+ ++m_invalid_errors;
+ int ln = std::count( contents_begin, url_start, '\n' ) + 1;
+ error( library_name, source_path,
+ "Invalid URL (empty path in relative url): " + decoded_url, ln );
+ }
+ }
+
+ // Decode percent encoded characters.
+ string decoded_path = decode_percents(url_path);
+ if(decoded_path.empty()) {
+ if(!no_link_errors) {
+ ++m_invalid_errors;
+ int ln = std::count( contents_begin, url_start, '\n' ) + 1;
+ error( library_name, source_path,
+ "Invalid URL (invalid character encodings): " + decoded_url, ln );
+ }
+ return;
+ }
+
+ // strip url of references to current dir
+ if ( decoded_path[0]=='.' && decoded_path[1]=='/' ) decoded_path.erase( 0, 2 );
+
+ // url is relative source_path.branch()
+ // convert to target_path, which is_complete()
+ path target_path;
+ try { target_path = source_path.branch_path() /= path( decoded_path ); }
+ catch ( const fs::filesystem_error & )
+ {
+ if(!no_link_errors) {
+ int ln = std::count( contents_begin, url_start, '\n' ) + 1;
+ ++m_invalid_errors;
+ error( library_name, source_path,
+ "Invalid URL (error resolving path): " + decoded_url, ln );
+ }
+ return;
+ }
+
+ // create a m_paths entry if necessary
+ std::pair< const string, int > entry(
+ relative_to( target_path, search_root_path() ), 0 );
+ m_path_map::iterator itr( m_paths.find( entry.first ) );
+ if ( itr == m_paths.end() )
+ {
+ if ( fs::exists( target_path ) ) entry.second = m_present;
+ itr = m_paths.insert( entry ).first;
+ }
+
+ // itr now points to the m_paths entry
+ itr->second |= m_linked_to;
+
+ // if target isn't present, the link is broken
+ if ( !no_link_errors && (itr->second & m_present) == 0 )
+ {
+ ++m_broken_errors;
+ int ln = std::count( contents_begin, url_start, '\n' ) + 1;
+ error( library_name, source_path, "Broken link: " + decoded_url, ln );
+ }
+ }
+
+// close -------------------------------------------------------------------//
+
+ void link_check::close()
+ {
+ for ( m_path_map::const_iterator itr = m_paths.begin();
+ itr != m_paths.end(); ++itr )
+ {
+// std::clog << itr->first << " " << itr->second << "\n";
+ if ( (itr->second & m_linked_to) != m_linked_to
+ && (itr->second & m_nounlinked_errors) != m_nounlinked_errors
+ && (itr->first.rfind( ".html" ) == itr->first.size()-5
+ || itr->first.rfind( ".htm" ) == itr->first.size()-4
+ || itr->first.rfind( ".css" ) == itr->first.size()-4)
+ // because they may be redirectors, it is OK if these are unlinked:
+ && itr->first.rfind( "index.html" ) == string::npos
+ && itr->first.rfind( "index.htm" ) == string::npos )
+ {
+ ++m_unlinked_errors;
+ path full_path( search_root_path() / path(itr->first) );
+ error( impute_library( full_path ), full_path, "Unlinked file" );
+ }
+ }
+ }
+
+ } // namespace inspect
+} // namespace boost
+
diff --git a/src/boost/tools/inspect/link_check.hpp b/src/boost/tools/inspect/link_check.hpp
new file mode 100644
index 000000000..726cd91f4
--- /dev/null
+++ b/src/boost/tools/inspect/link_check.hpp
@@ -0,0 +1,72 @@
+// link_check header -------------------------------------------------------//
+
+// Copyright Beman Dawes 2002
+// Copyright Rene Rivera 2004.
+// 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)
+
+#ifndef BOOST_LINK_CHECK_HPP
+#define BOOST_LINK_CHECK_HPP
+
+#include <map>
+
+#include "inspector.hpp"
+
+namespace boost
+{
+ namespace inspect
+ {
+ const int m_linked_to = 1;
+ const int m_present = 2;
+ const int m_nounlinked_errors = 4;
+
+ class link_check : public hypertext_inspector
+ {
+ long m_broken_errors;
+ long m_unlinked_errors;
+ long m_invalid_errors;
+ long m_bookmark_errors;
+ long m_duplicate_bookmark_errors;
+
+ typedef std::map< string, int > m_path_map;
+ m_path_map m_paths; // first() is relative to search_root_path()
+
+ void do_url( const string & url, const string & library_name,
+ const path & full_source_path, bool no_link_errors,
+ bool allow_external_links,
+ std::string::const_iterator contents_begin, std::string::const_iterator url_start);
+ public:
+
+ link_check();
+ virtual const char * name() const { return "*LINK*"; }
+ virtual const char * desc() const
+ { return "invalid bookmarks, duplicate bookmarks,"
+ " invalid urls, broken links, unlinked files"; }
+
+ virtual void inspect(
+ const std::string & library_name,
+ const path & full_path );
+
+ virtual void inspect(
+ const std::string & library_name,
+ const path & full_path,
+ const std::string & contents );
+
+ virtual void close();
+
+ virtual ~link_check()
+ {
+ std::cout << " " << m_bookmark_errors
+ << " bookmarks with invalid characters" << line_break();
+ std::cout << " " << m_duplicate_bookmark_errors
+ << " duplicate bookmarks" << line_break();
+ std::cout << " " << m_invalid_errors << " invalid urls" << line_break();
+ std::cout << " " << m_broken_errors << " broken links" << line_break();
+ std::cout << " " << m_unlinked_errors << " unlinked files" << line_break();
+ }
+ };
+ }
+}
+
+#endif // BOOST_LINK_CHECK_HPP
diff --git a/src/boost/tools/inspect/link_check_test.html b/src/boost/tools/inspect/link_check_test.html
new file mode 100644
index 000000000..2d1e9845e
--- /dev/null
+++ b/src/boost/tools/inspect/link_check_test.html
@@ -0,0 +1,24 @@
+<html>
+
+<head>
+<meta http-equiv="Content-Language" content="en-us">
+<meta name="GENERATOR" content="Microsoft FrontPage 5.0">
+<meta name="ProgId" content="FrontPage.Editor.Document">
+<meta http-equiv="Content-Type" content="text/html; charset=windows-1252">
+<title>valid link</title>
+</head>
+
+<body>
+
+<p><a href="#link-target">valid bookmark link</a></p>
+<p><a href="link_check_test.html">valid relative link</a></p>
+<p><a href="foo.html#bar">broken relative link with bookmark</a></p>
+<p><a href="#broken">broken bookmark link</a></p>
+<p><a name="link-target">bookmark</a></p>
+<p><a name="second-target">second bookmark</a></p>
+<p><a name="SECOND-TARGET">duplicate second bookmark</a></p>
+<p>&nbsp;</p>
+
+</body>
+
+</html> \ No newline at end of file
diff --git a/src/boost/tools/inspect/minmax_check.cpp b/src/boost/tools/inspect/minmax_check.cpp
new file mode 100644
index 000000000..00cc44bca
--- /dev/null
+++ b/src/boost/tools/inspect/minmax_check.cpp
@@ -0,0 +1,102 @@
+// minmax_check implementation --------------------------------------------//
+
+// Copyright Beman Dawes 2002.
+// 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)
+
+
+#include <algorithm>
+
+#include "minmax_check.hpp"
+#include "boost/regex.hpp"
+#include "boost/lexical_cast.hpp"
+
+namespace
+{
+ boost::regex minmax_regex(
+ "("
+ "^\\s*#\\s*undef\\s*" // # undef
+ "\\b(min|max)\\b" // followed by min or max, whole word
+ ")"
+ "|" // or (ignored)
+ "("
+ "//[^\\n]*" // single line comments (//)
+ "|"
+ "/\\*.*?\\*/" // multi line comments (/**/)
+ "|"
+ "\"(?:\\\\\\\\|\\\\\"|[^\"])*\"" // string literals
+ ")"
+ "|" // or
+ "("
+ "\\b(min|max)\\b" // min or max, whole word
+ "\\s*\\(" // followed by 0 or more spaces and an opening paren
+ ")"
+ , boost::regex::normal);
+
+} // unnamed namespace
+
+namespace boost
+{
+ namespace inspect
+ {
+
+ // minmax_check constructor -------------------------------------------//
+
+ minmax_check::minmax_check()
+ : m_errors(0)
+ {
+ // C/C++ source code...
+ register_signature( ".c" );
+ register_signature( ".cpp" );
+ register_signature( ".cxx" );
+ register_signature( ".h" );
+ register_signature( ".hpp" );
+ register_signature( ".hxx" );
+ register_signature( ".inc" );
+ register_signature( ".ipp" );
+ }
+
+ // inspect ( C++ source files ) ---------------------------------------//
+
+ void minmax_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:" "nominmax" ) != string::npos) return;
+
+ boost::sregex_iterator cur(contents.begin(), contents.end(), minmax_regex), end;
+
+ for( ; cur != end; ++cur /*, ++m_errors*/ )
+ {
+
+ 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()
+ }
+ }
+
+ ++m_errors;
+ error( library_name, full_path, string(name())
+ + " violation of Boost min/max guidelines on line "
+ + boost::lexical_cast<string>( line_number ) );
+ }
+
+ }
+ }
+
+ } // namespace inspect
+} // namespace boost
+
diff --git a/src/boost/tools/inspect/minmax_check.hpp b/src/boost/tools/inspect/minmax_check.hpp
new file mode 100644
index 000000000..03ff923ea
--- /dev/null
+++ b/src/boost/tools/inspect/minmax_check.hpp
@@ -0,0 +1,45 @@
+// minmax_check header -------------------------------------------------------//
+
+// Copyright Beman Dawes 2002
+// Copyright Rene Rivera 2004.
+// 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)
+
+#ifndef BOOST_MINMAX_CHECK_HPP
+#define BOOST_MINMAX_CHECK_HPP
+
+#include "inspector.hpp"
+
+namespace boost
+{
+ namespace inspect
+ {
+ class minmax_check : public inspector
+ {
+ long m_errors;
+
+ public:
+
+ minmax_check();
+ virtual const char * name() const { return "*M*"; }
+ virtual const char * desc() const { return "uses of min or max that"
+ " have not been protected from the min/max macros,"
+ " or unallowed #undef-s"; }
+
+ virtual void inspect(
+ const std::string & library_name,
+ const path & full_path,
+ const std::string & contents);
+
+ virtual ~minmax_check()
+ {
+ std::cout << " " << m_errors << " violations of the Boost min/max guidelines" << line_break();
+ }
+ };
+ }
+}
+
+#endif // BOOST_MINMAX_CHECK_HPP
diff --git a/src/boost/tools/inspect/path_name_check.cpp b/src/boost/tools/inspect/path_name_check.cpp
new file mode 100644
index 000000000..0714e20c0
--- /dev/null
+++ b/src/boost/tools/inspect/path_name_check.cpp
@@ -0,0 +1,110 @@
+// path_name_check implementation ------------------------------------------//
+
+// Copyright Beman Dawes 2002.
+// 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)
+
+#include "path_name_check.hpp"
+
+#include "boost/filesystem/operations.hpp"
+#include "boost/lexical_cast.hpp"
+
+#include <string>
+#include <algorithm>
+#include <cctype>
+#include <cstring>
+
+using std::string;
+
+namespace
+{
+ const char allowable[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789_-.";
+ const char initial_char[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789_";
+}
+
+namespace boost
+{
+ namespace inspect
+ {
+
+
+ file_name_check::file_name_check() : m_name_errors(0) {}
+
+ void file_name_check::inspect(
+ const string & library_name,
+ const path & full_path )
+ {
+ string::size_type pos;
+
+ // called for each file and directory, so only the leaf need be tested
+ string const leaf( full_path.leaf().string() );
+
+ // includes only allowable characters
+ if ( (pos = leaf.find_first_not_of( allowable )) != string::npos )
+ {
+ ++m_name_errors;
+ error( library_name, full_path, string(name())
+ + " file or directory name contains unacceptable character '"
+ + leaf[pos] + "'" );
+ }
+
+ // allowable initial character
+ if ( std::strchr( initial_char, leaf[0] ) == 0 )
+ {
+ ++m_name_errors;
+ error( library_name, full_path, string(name())
+ + " file or directory name begins with an unacceptable character" );
+ }
+
+ // rules for dot characters differ slightly for directories and files
+ if ( filesystem::is_directory( full_path ) )
+ {
+ if ( std::strchr( leaf.c_str(), '.' ) )
+ {
+ ++m_name_errors;
+ error( library_name, full_path, string(name())
+ + " directory name contains a dot character ('.')" );
+ }
+ }
+ //else // not a directory
+ //{
+ // // includes at most one dot character
+ // const char * first_dot = std::strchr( leaf.c_str(), '.' );
+ // if ( first_dot && std::strchr( first_dot+1, '.' ) )
+ // {
+ // ++m_name_errors;
+ // error( library_name, full_path, string(name())
+ // + " file name with more than one dot character ('.')" );
+ // }
+ //}
+
+ // the path, including a presumed root, does not exceed the maximum size
+ path const relative_path( relative_to( full_path, search_root_path() ) );
+ const unsigned max_relative_path = 207; // ISO 9660:1999 sets this limit
+ const string generic_root( "boost_X_XX_X/" );
+ if ( relative_path.string().size() >
+ ( max_relative_path - generic_root.size() ) )
+ {
+ ++m_name_errors;
+ error( library_name, full_path,
+ string(name())
+ + " path will exceed "
+ + boost::lexical_cast<string>(max_relative_path)
+ + " characters in a directory tree with a root in the form "
+ + generic_root + ", and this exceeds ISO 9660:1999 limit of 207" )
+ ;
+ }
+
+ }
+
+ file_name_check::~file_name_check()
+ {
+ std::cout << " " << m_name_errors << " " << desc() << line_break();
+ }
+
+
+ } // namespace inspect
+} // namespace boost
diff --git a/src/boost/tools/inspect/path_name_check.hpp b/src/boost/tools/inspect/path_name_check.hpp
new file mode 100644
index 000000000..ec1218ace
--- /dev/null
+++ b/src/boost/tools/inspect/path_name_check.hpp
@@ -0,0 +1,48 @@
+// long_name_check header --------------------------------------------------//
+// (main class renamed to: file_name_check) - gps
+
+// Copyright Beman Dawes 2002.
+// 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)
+
+#ifndef BOOST_FILE_NAME_CHECK_HPP
+#define BOOST_FILE_NAME_CHECK_HPP
+
+#include "inspector.hpp"
+
+namespace boost
+{
+ namespace inspect
+ {
+ class file_name_check : public inspector
+ {
+ long m_name_errors;
+
+ public:
+
+ file_name_check();
+ virtual ~file_name_check();
+
+ virtual const char * name() const { return "*N*"; }
+ virtual const char * desc() const { return "file and directory name issues"; }
+
+ virtual void inspect(
+ const string & library_name,
+ const path & full_path );
+
+ virtual void inspect(
+ const string &, // "filesystem"
+ const path &, // "c:/foo/boost/filesystem/path.hpp"
+ const string &)
+ { /* empty */ }
+
+
+
+ };
+ }
+}
+
+#endif // BOOST_FILE_NAME_CHECK_HPP
diff --git a/src/boost/tools/inspect/tab_check.cpp b/src/boost/tools/inspect/tab_check.cpp
new file mode 100644
index 000000000..e84d088da
--- /dev/null
+++ b/src/boost/tools/inspect/tab_check.cpp
@@ -0,0 +1,44 @@
+// tab_check implementation ------------------------------------------------//
+
+// Copyright Beman Dawes 2002.
+//
+// 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 "tab_check.hpp"
+
+namespace boost
+{
+ namespace inspect
+ {
+ tab_check::tab_check() : m_files_with_errors(0)
+ {
+ register_signature( ".c" );
+ register_signature( ".cpp" );
+ register_signature( ".cxx" );
+ register_signature( ".h" );
+ register_signature( ".hpp" );
+ register_signature( ".hxx" );
+ register_signature( ".ipp" );
+ register_signature( "Jamfile" );
+ register_signature( ".py" );
+ }
+
+ void tab_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:" "notab" ) != string::npos) return;
+
+ if ( contents.find( '\t' ) != string::npos )
+ {
+ ++m_files_with_errors;
+ error( library_name, full_path, name() );
+ }
+ }
+ } // namespace inspect
+} // namespace boost
+
+
diff --git a/src/boost/tools/inspect/tab_check.hpp b/src/boost/tools/inspect/tab_check.hpp
new file mode 100644
index 000000000..fb7f617ba
--- /dev/null
+++ b/src/boost/tools/inspect/tab_check.hpp
@@ -0,0 +1,37 @@
+// tab_check header --------------------------------------------------------//
+
+// Copyright Beman Dawes 2002.
+// 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)
+
+#ifndef BOOST_TAB_CHECK_HPP
+#define BOOST_TAB_CHECK_HPP
+
+#include "inspector.hpp"
+
+namespace boost
+{
+ namespace inspect
+ {
+ class tab_check : public inspector
+ {
+ long m_files_with_errors;
+ public:
+
+ tab_check();
+ virtual const char * name() const { return "*Tabs*"; }
+ virtual const char * desc() const { return "tabs in file"; }
+
+ virtual void inspect(
+ const std::string & library_name,
+ const path & full_path,
+ const std::string & contents );
+
+ virtual ~tab_check()
+ { std::cout << " " << m_files_with_errors << " files with tabs" << line_break(); }
+ };
+ }
+}
+
+#endif // BOOST_TAB_CHECK_HPP
diff --git a/src/boost/tools/inspect/time_string.hpp b/src/boost/tools/inspect/time_string.hpp
new file mode 100644
index 000000000..72ca43968
--- /dev/null
+++ b/src/boost/tools/inspect/time_string.hpp
@@ -0,0 +1,55 @@
+// ---- time_string: thin wrapper around std::strftime -------- //
+//
+// 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)
+//
+// ------------------------------------------------------------------
+//
+// $Id$
+
+#ifndef BOOST_TIME_STRING_HPP_GP_20060731
+#define BOOST_TIME_STRING_HPP_GP_20060731
+
+#include <string>
+#include <ctime>
+
+#include <boost/config/warning_disable.hpp>
+
+namespace boost {
+
+// Many of the boost tools just need a quick way to obtain
+// a formatted "run date" string or similar. This is one.
+//
+// In case of failure false is returned and result is
+// unchanged.
+//
+inline
+bool time_string(std::string & result
+ , const std::string & format = "%X UTC, %A %d %B %Y")
+{
+ // give up qualifying names and using std::size_t,
+ // to avoid including "config.hpp"
+ using namespace std;
+
+ const int sz = 256;
+ char buffer [ sz ] = { 0 };
+ const time_t no_cal_time ( -1 );
+ time_t tod;
+
+ const bool ok =
+ time ( &tod ) != no_cal_time
+ && strftime( buffer, sz, format.c_str(), gmtime( &tod ) ) != 0
+ ;
+
+ if (ok)
+ result = buffer;
+
+ return ok;
+}
+
+}
+
+#endif // include guard
diff --git a/src/boost/tools/inspect/unnamed_namespace_check.cpp b/src/boost/tools/inspect/unnamed_namespace_check.cpp
new file mode 100644
index 000000000..92431a171
--- /dev/null
+++ b/src/boost/tools/inspect/unnamed_namespace_check.cpp
@@ -0,0 +1,62 @@
+// unnamed_namespace_check -----------------------------------------//
+
+// 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)
+
+#include "boost/regex.hpp"
+#include "boost/lexical_cast.hpp"
+#include "unnamed_namespace_check.hpp"
+
+
+namespace
+{
+
+ boost::regex unnamed_namespace_regex(
+ "\\<namespace\\s*(\\?\\?<|\\{)" // trigraph ??< or {
+ );
+
+} // unnamed namespace (ironical? :-)
+
+
+
+namespace boost
+{
+ namespace inspect
+ {
+ unnamed_namespace_check::unnamed_namespace_check() : m_errors(0)
+ {
+ register_signature( ".h" );
+ register_signature( ".hh" ); // just in case
+ register_signature( ".hpp" );
+ register_signature( ".hxx" ); // just in case
+ register_signature( ".inc" );
+ register_signature( ".ipp" );
+ register_signature( ".inl" );
+ }
+
+ void unnamed_namespace_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:" "nounnamed" ) != string::npos) return;
+
+
+ boost::sregex_iterator cur(contents.begin(), contents.end(), unnamed_namespace_regex), end;
+ for( ; cur != end; ++cur, ++m_errors )
+ {
+ const string::size_type
+ ln = std::count( contents.begin(), (*cur)[0].first, '\n' ) + 1;
+
+ error( library_name, full_path, "Unnamed namespace", ln );
+ }
+
+
+ }
+ } // namespace inspect
+} // namespace boost
+
+
diff --git a/src/boost/tools/inspect/unnamed_namespace_check.hpp b/src/boost/tools/inspect/unnamed_namespace_check.hpp
new file mode 100644
index 000000000..87f36b717
--- /dev/null
+++ b/src/boost/tools/inspect/unnamed_namespace_check.hpp
@@ -0,0 +1,39 @@
+// unnamed_namespace_check -----------------------------------------//
+
+// 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)
+
+#ifndef BOOST_UNNAMED_NAMESPACE_CHECK_HPP_GP_20060718
+#define BOOST_UNNAMED_NAMESPACE_CHECK_HPP_GP_20060718
+
+#include "inspector.hpp"
+
+namespace boost
+{
+ namespace inspect
+ {
+ class unnamed_namespace_check : public inspector
+ {
+ long m_errors;
+ public:
+
+ unnamed_namespace_check();
+ virtual const char * name() const { return "*U*"; }
+ virtual const char * desc() const { return "unnamed namespace in header"; }
+
+ virtual void inspect(
+ const std::string & library_name,
+ const path & full_path,
+ const std::string & contents );
+
+ virtual ~unnamed_namespace_check()
+ { std::cout << " " << m_errors << " usages of unnamed namespaces in headers (including .ipp files)" << line_break(); }
+ };
+ }
+}
+
+
+#endif // include guard
diff --git a/src/boost/tools/inspect/wrong_line_ends_test.cpp b/src/boost/tools/inspect/wrong_line_ends_test.cpp
new file mode 100644
index 000000000..05d1a1b42
--- /dev/null
+++ b/src/boost/tools/inspect/wrong_line_ends_test.cpp
@@ -0,0 +1 @@
+// this is a test file; it isn't supposed to have correct line endings // Copyright Beman Dawes, 2003. // 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) line ending with cr line ending without any cr or nl \ No newline at end of file