|
Boost-Commit : |
Subject: [Boost-commit] svn:boost r63462 - in branches/release/tools/inspect: . build build/msvc
From: daniel_james_at_[hidden]
Date: 2010-06-30 19:33:34
Author: danieljames
Date: 2010-06-30 19:33:33 EDT (Wed, 30 Jun 2010)
New Revision: 63462
URL: http://svn.boost.org/trac/boost/changeset/63462
Log:
Merge inspect from trunk.
Added:
branches/release/tools/inspect/apple_macro_check.cpp
- copied, changed from r57825, /trunk/tools/inspect/apple_macro_check.cpp
branches/release/tools/inspect/apple_macro_check.hpp
- copied, changed from r57825, /trunk/tools/inspect/apple_macro_check.hpp
branches/release/tools/inspect/link_check_test.html
- copied unchanged from r59102, /trunk/tools/inspect/link_check_test.html
Properties modified:
branches/release/tools/inspect/ (props changed)
Text files modified:
branches/release/tools/inspect/apple_macro_check.cpp | 25 ++++-
branches/release/tools/inspect/apple_macro_check.hpp | 2
branches/release/tools/inspect/ascii_check.cpp | 3
branches/release/tools/inspect/build/Jamfile.v2 | 2
branches/release/tools/inspect/build/msvc/boost_inspect.vcproj | 28 +----
branches/release/tools/inspect/build/msvc/readme.txt | 2
branches/release/tools/inspect/inspect.cpp | 37 +++++++-
branches/release/tools/inspect/inspector.hpp | 3
branches/release/tools/inspect/link_check.cpp | 177 ++++++++++++++++++++++++++++++++-------
branches/release/tools/inspect/link_check.hpp | 13 ++
branches/release/tools/inspect/unnamed_namespace_check.cpp | 3
11 files changed, 222 insertions(+), 73 deletions(-)
Copied: branches/release/tools/inspect/apple_macro_check.cpp (from r57825, /trunk/tools/inspect/apple_macro_check.cpp)
==============================================================================
--- /trunk/tools/inspect/apple_macro_check.cpp (original)
+++ branches/release/tools/inspect/apple_macro_check.cpp 2010-06-30 19:33:33 EDT (Wed, 30 Jun 2010)
@@ -11,13 +11,16 @@
#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(min|max)\\b" // followed by min or max, whole word
+ "\\b(check|verify|require|check_error)\\b" // followed by apple macro name, whole word
")"
"|" // or (ignored)
"("
@@ -29,7 +32,7 @@
")"
"|" // or
"("
- "\\b(check|verify|require|check_error)\\b" // min or max, whole word
+ "\\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);
@@ -59,8 +62,15 @@
{
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, fs::initial_path() ), fs::no_check );
+ 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*/ )
{
@@ -79,12 +89,15 @@
}
}
- ++m_files_with_errors;
- error( library_name, full_path, string(name())
- + " violation of Boost apple-macro guidelines on line "
- + boost::lexical_cast<string>( line_number ) );
+ ++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
Copied: branches/release/tools/inspect/apple_macro_check.hpp (from r57825, /trunk/tools/inspect/apple_macro_check.hpp)
==============================================================================
--- /trunk/tools/inspect/apple_macro_check.hpp (original)
+++ branches/release/tools/inspect/apple_macro_check.hpp 2010-06-30 19:33:33 EDT (Wed, 30 Jun 2010)
@@ -31,7 +31,7 @@
const std::string & contents );
virtual ~apple_macro_check()
- { std::cout << " " << m_files_with_errors << " files with apple macros" << line_break(); }
+ { std::cout << " " << m_files_with_errors << " files with Apple macros" << line_break(); }
};
}
}
Modified: branches/release/tools/inspect/ascii_check.cpp
==============================================================================
--- branches/release/tools/inspect/ascii_check.cpp (original)
+++ branches/release/tools/inspect/ascii_check.cpp 2010-06-30 19:33:33 EDT (Wed, 30 Jun 2010)
@@ -91,8 +91,9 @@
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, string ( name()) + " non-ASCII: " + the_line );
+ error( library_name, full_path, "Non-ASCII: " + the_line, ln );
}
}
} // namespace inspect
Modified: branches/release/tools/inspect/build/Jamfile.v2
==============================================================================
--- branches/release/tools/inspect/build/Jamfile.v2 (original)
+++ branches/release/tools/inspect/build/Jamfile.v2 2010-06-30 19:33:33 EDT (Wed, 30 Jun 2010)
@@ -15,7 +15,7 @@
exe inspect
:
inspect.cpp license_check.cpp link_check.cpp path_name_check.cpp tab_check.cpp crlf_check.cpp end_check.cpp unnamed_namespace_check.cpp ascii_check.cpp
- copyright_check.cpp minmax_check.cpp
+ copyright_check.cpp minmax_check.cpp apple_macro_check.cpp
/boost//filesystem/<link>static
/boost//regex/<link>static
:
Modified: branches/release/tools/inspect/build/msvc/boost_inspect.vcproj
==============================================================================
--- branches/release/tools/inspect/build/msvc/boost_inspect.vcproj (original)
+++ branches/release/tools/inspect/build/msvc/boost_inspect.vcproj 2010-06-30 19:33:33 EDT (Wed, 30 Jun 2010)
@@ -2,7 +2,7 @@
<VisualStudioProject
ProjectType="Visual C++"
Version="9.00"
- Name="boost_inspect"
+ Name="inspect"
ProjectGUID="{0EC8AC1C-6D1F-47FC-A06A-9CC3F924BD82}"
RootNamespace="boost_inspect"
Keyword="Win32Proj"
@@ -42,7 +42,7 @@
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories="..\..\..\.."
- PreprocessorDefinitions="BOOST_SYSTEM_NO_LIB;BOOST_FILESYSTEM_NO_LIB;WIN32;_DEBUG;_CONSOLE"
+ PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE"
MinimalRebuild="true"
ExceptionHandling="2"
BasicRuntimeChecks="3"
@@ -118,7 +118,7 @@
Optimization="2"
EnableIntrinsicFunctions="true"
AdditionalIncludeDirectories="..\..\..\.."
- PreprocessorDefinitions="BOOST_SYSTEM_NO_LIB;BOOST_FILESYSTEM_NO_LIB;WIN32;NDEBUG;_CONSOLE"
+ PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE"
ExceptionHandling="2"
RuntimeLibrary="2"
EnableFunctionLevelLinking="true"
@@ -177,6 +177,10 @@
UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"
>
<File
+ RelativePath="..\..\apple_macro_check.cpp"
+ >
+ </File>
+ <File
RelativePath="..\..\ascii_check.cpp"
>
</File>
@@ -189,7 +193,7 @@
>
</File>
<File
- RelativePath="..\..\..\..\libs\system\src\error_code.cpp"
+ RelativePath="..\..\end_check.cpp"
>
</File>
<File
@@ -209,22 +213,10 @@
>
</File>
<File
- RelativePath="..\..\..\..\libs\filesystem\src\operations.cpp"
- >
- </File>
- <File
- RelativePath="..\..\..\..\libs\filesystem\src\path.cpp"
- >
- </File>
- <File
RelativePath="..\..\path_name_check.cpp"
>
</File>
<File
- RelativePath="..\..\..\..\libs\filesystem\src\portability.cpp"
- >
- </File>
- <File
RelativePath="..\..\tab_check.cpp"
>
</File>
@@ -232,10 +224,6 @@
RelativePath="..\..\unnamed_namespace_check.cpp"
>
</File>
- <File
- RelativePath="..\..\..\..\libs\filesystem\src\utf8_codecvt_facet.cpp"
- >
- </File>
</Filter>
<Filter
Name="Header Files"
Modified: branches/release/tools/inspect/build/msvc/readme.txt
==============================================================================
--- branches/release/tools/inspect/build/msvc/readme.txt (original)
+++ branches/release/tools/inspect/build/msvc/readme.txt 2010-06-30 19:33:33 EDT (Wed, 30 Jun 2010)
@@ -1,3 +1,3 @@
The provided Microsoft VC++ solution assumes the following has been run in the root directory"
- bjam --toolset=msvc-9.0express --build-type=complete --with-regex stage
\ No newline at end of file
+ bjam --toolset=msvc-9.0express --build-type=complete --with-filesystem,regex stage
\ No newline at end of file
Modified: branches/release/tools/inspect/inspect.cpp
==============================================================================
--- branches/release/tools/inspect/inspect.cpp (original)
+++ branches/release/tools/inspect/inspect.cpp 2010-06-30 19:33:33 EDT (Wed, 30 Jun 2010)
@@ -22,6 +22,7 @@
#include <cstring>
#include "boost/shared_ptr.hpp"
+#include "boost/lexical_cast.hpp"
#include "boost/filesystem/operations.hpp"
#include "boost/filesystem/fstream.hpp"
@@ -38,6 +39,7 @@
#include "path_name_check.hpp"
#include "tab_check.hpp"
#include "ascii_check.hpp"
+#include "apple_macro_check.hpp"
#include "minmax_check.hpp"
#include "unnamed_namespace_check.hpp"
@@ -75,6 +77,7 @@
string library;
string rel_path;
string msg;
+ int line_number;
bool operator<( const error_msg & rhs ) const
{
@@ -82,6 +85,8 @@
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;
}
};
@@ -399,11 +404,11 @@
}
std::cout << "\n";
}
- else
+ else // html
{
// display error messages with group indication
error_msg current;
- string sep;
+ bool first_sep = true;
bool first = true;
for ( error_msg_vector::iterator itr ( msgs.begin() );
itr != msgs.end(); ++itr )
@@ -419,14 +424,26 @@
{
std::cout << "\n";
std::cout << itr->rel_path;
- sep = ": ";
+ first_sep = true;
}
if ( current.library != itr->library
|| current.rel_path != itr->rel_path
|| current.msg != itr->msg )
{
- std::cout << sep << itr->msg;
- sep = ", ";
+ std::string sep;
+ if (first_sep)
+ if (itr->line_number) sep = ":<br> ";
+ else sep = ": ";
+ else
+ if (itr->line_number) sep = "<br> ";
+ else sep = ", ";
+
+ // print the message
+ if (itr->line_number)
+ std::cout << sep << "(line " << itr->line_number << ") " << itr->msg;
+ else std::cout << sep << itr->msg;
+
+ first_sep = false;
}
current.library = itr->library;
current.rel_path = itr->rel_path;
@@ -529,6 +546,7 @@
" -path_name\n"
" -tab\n"
" -ascii\n"
+ " -apple_macro\n"
" -minmax\n"
" -unnamed\n"
" default is all checks on; otherwise options specify desired checks"
@@ -579,13 +597,14 @@
// error -------------------------------------------------------------------//
void inspector::error( const string & library_name,
- const path & full_path, const string & msg )
+ const path & full_path, const string & msg, int line_number )
{
++error_count;
error_msg err_msg;
err_msg.library = library_name;
err_msg.rel_path = relative_to( full_path, fs::initial_path() );
err_msg.msg = msg;
+ err_msg.line_number = line_number;
msgs.push_back( err_msg );
// std::cout << library_name << ": "
@@ -699,6 +718,7 @@
bool path_name_ck = true;
bool tab_ck = true;
bool ascii_ck = true;
+ bool apple_ok = true;
bool minmax_ck = true;
bool unnamed_ck = true;
bool cvs = false;
@@ -731,6 +751,7 @@
path_name_ck = false;
tab_ck = false;
ascii_ck = false;
+ apple_ok = false;
minmax_ck = false;
unnamed_ck = false;
}
@@ -754,6 +775,8 @@
tab_ck = true;
else if ( std::strcmp( argv[1], "-ascii" ) == 0 )
ascii_ck = true;
+ else if ( std::strcmp( argv[1], "-apple_macro" ) == 0 )
+ apple_ok = true;
else if ( std::strcmp( argv[1], "-minmax" ) == 0 )
minmax_ck = true;
else if ( std::strcmp( argv[1], "-unnamed" ) == 0 )
@@ -797,6 +820,8 @@
inspectors.push_back( inspector_element( new boost::inspect::tab_check ) );
if ( ascii_ck )
inspectors.push_back( inspector_element( new boost::inspect::ascii_check ) );
+ if ( apple_ok )
+ inspectors.push_back( inspector_element( new boost::inspect::apple_macro_check ) );
if ( minmax_ck )
inspectors.push_back( inspector_element( new boost::inspect::minmax_check ) );
if ( unnamed_ck )
Modified: branches/release/tools/inspect/inspector.hpp
==============================================================================
--- branches/release/tools/inspect/inspector.hpp (original)
+++ branches/release/tools/inspect/inspector.hpp 2010-06-30 19:33:33 EDT (Wed, 30 Jun 2010)
@@ -64,7 +64,8 @@
void error(
const string & library_name,
const path & full_path,
- const string & msg );
+ const string & msg,
+ int line_number =0 ); // 0 if not available or not applicable
private:
string_set m_signatures;
Modified: branches/release/tools/inspect/link_check.cpp
==============================================================================
--- branches/release/tools/inspect/link_check.cpp (original)
+++ branches/release/tools/inspect/link_check.cpp 2010-06-30 19:33:33 EDT (Wed, 30 Jun 2010)
@@ -11,17 +11,26 @@
#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*(['\"])(.*?)\\2",
+ "\\s*=\\s*(['\"])\\s*(.*?)\\s*\\2"
+ "|<!--.*?-->",
boost::regbase::normal | boost::regbase::icase);
boost::regex css_url_regex(
- "(\\@import\\s*[\"']|url\\s*\\(\\s*[\"']?)([^\"')]*)",
+ "(\\@import\\s*[\"']|url\\s*\\(\\s*[\"']?)([^\"')]*)"
+ "|/\\*.*?\\*/",
boost::regbase::normal | boost::regbase::icase);
// Regular expression for parsing URLS from:
@@ -30,6 +39,10 @@
"^(([^:/?#]+):)?(//([^/?#]*))?([^?#]*)(\\?([^#]*))?(#(.*))?$",
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;
@@ -95,7 +108,7 @@
link_check::link_check()
: m_broken_errors(0), m_unlinked_errors(0), m_invalid_errors(0),
- m_bookmark_errors(0)
+ m_bookmark_errors(0), m_duplicate_bookmark_errors(0)
{
// HTML signatures are already registered by the base class,
// 'hypertext_inspector'
@@ -126,6 +139,65 @@
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;
@@ -138,14 +210,17 @@
// 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);
- 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" );
+ // 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
@@ -157,8 +232,13 @@
{
// what[0] contains the whole string iterators.
// what[2] contains the URL iterators.
- do_url( string( what[2].first, what[2].second ),
- library_name, full_path, no_link_errors, false );
+
+ 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
@@ -169,12 +249,14 @@
// 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 )
+ 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;
- error( library_name, source_path, string(name()) + " empty URL." );
+ int ln = std::count( contents_begin, url_start, '\n' ) + 1;
+ error( library_name, source_path, "Empty URL.", ln );
return;
}
@@ -183,7 +265,9 @@
if(decoded_url.empty()) {
if(!no_link_errors) {
++m_invalid_errors;
- error( library_name, source_path, string(name()) + " invalid URL (invalid ampersand encodings): " + url );
+ int ln = std::count( contents_begin, url_start, '\n' ) + 1;
+ error( library_name, source_path,
+ "Invalid URL (invalid ampersand encodings): " + url, ln );
}
return;
}
@@ -192,7 +276,8 @@
if(!boost::regex_match(decoded_url, m, url_decompose_regex)) {
if(!no_link_errors) {
++m_invalid_errors;
- error( library_name, source_path, string(name()) + " invalid URL: " + decoded_url );
+ int ln = std::count( contents_begin, url_start, '\n' ) + 1;
+ error( library_name, source_path, "Invalid URL: " + decoded_url, ln );
}
return;
}
@@ -212,7 +297,8 @@
if(!allow_external_content && (authority_matched || scheme_matched)) {
if(!no_link_errors) {
++m_invalid_errors;
- error( library_name, source_path, string(name()) + " external content: " + decoded_url );
+ int ln = std::count( contents_begin, url_start, '\n' ) + 1;
+ error( library_name, source_path, "External content: " + decoded_url, ln );
}
}
@@ -225,7 +311,8 @@
if(!authority_matched) {
if(!no_link_errors) {
++m_invalid_errors;
- error( library_name, source_path, string(name()) + " no hostname: " + decoded_url );
+ int ln = std::count( contents_begin, url_start, '\n' ) + 1;
+ error( library_name, source_path, "No hostname: " + decoded_url, ln );
}
}
@@ -234,19 +321,24 @@
else if(scheme == "file") {
if(!no_link_errors) {
++m_invalid_errors;
- error( library_name, source_path, string(name()) + " invalid URL (hardwired file): " + decoded_url );
+ 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;
- error( library_name, source_path, string(name()) + " invalid protocol for css: " + decoded_url );
+ 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;
- error( library_name, source_path, string(name()) + " unknown protocol: " + decoded_url );
+ int ln = std::count( contents_begin, url_start, '\n' ) + 1;
+ error( library_name, source_path, "Unknown protocol: '" + scheme + "' in url: " + decoded_url, ln );
}
}
@@ -257,7 +349,9 @@
if(authority_matched) {
if(!no_link_errors) {
++m_invalid_errors;
- error( library_name, source_path, string(name()) + " invalid URL (hostname without protocol): " + decoded_url );
+ int ln = std::count( contents_begin, url_start, '\n' ) + 1;
+ error( library_name, source_path,
+ "Invalid URL (hostname without protocol): " + decoded_url, ln );
}
}
@@ -266,14 +360,26 @@
if ( is_css(source_path) ) {
if ( !no_link_errors ) {
++m_invalid_errors;
- error( library_name, source_path, string(name()) + " fragment link in CSS: " + decoded_url );
+ 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;
- error( library_name, source_path, string(name()) + " invalid bookmark: " + decoded_url );
+ 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 );
}
}
@@ -285,23 +391,29 @@
if ( !no_link_errors && decoded_url.find_first_of( " <>\"{}|\\^[]'" ) != string::npos )
{
++m_invalid_errors;
- error( library_name, source_path, string(name()) + " invalid character in URL: " + decoded_url );
+ 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;
- error( library_name, source_path, string(name()) + " invalid URL (empty path in relative url): " + decoded_url );
+ 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 and ampersand encoded characters.
+ // Decode percent encoded characters.
string decoded_path = decode_percents(url_path);
if(decoded_path.empty()) {
if(!no_link_errors) {
++m_invalid_errors;
- error( library_name, source_path, string(name()) + " invalid URL (invalid character encodings): " + decoded_url );
+ int ln = std::count( contents_begin, url_start, '\n' ) + 1;
+ error( library_name, source_path,
+ "Invalid URL (invalid character encodings): " + decoded_url, ln );
}
return;
}
@@ -316,8 +428,10 @@
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, string(name()) + " invalid URL (error resolving path): " + decoded_url );
+ error( library_name, source_path,
+ "Invalid URL (error resolving path): " + decoded_url, ln );
}
return;
}
@@ -339,7 +453,8 @@
if ( !no_link_errors && (itr->second & m_present) == 0 )
{
++m_broken_errors;
- error( library_name, source_path, string(name()) + " broken link: " + decoded_url );
+ int ln = std::count( contents_begin, url_start, '\n' ) + 1;
+ error( library_name, source_path, "Broken link: " + decoded_url, ln );
}
}
@@ -362,7 +477,7 @@
{
++m_unlinked_errors;
path full_path( fs::initial_path() / path(itr->first, fs::no_check) );
- error( impute_library( full_path ), full_path, string(name()) + " unlinked file" );
+ error( impute_library( full_path ), full_path, "Unlinked file" );
}
}
}
Modified: branches/release/tools/inspect/link_check.hpp
==============================================================================
--- branches/release/tools/inspect/link_check.hpp (original)
+++ branches/release/tools/inspect/link_check.hpp 2010-06-30 19:33:33 EDT (Wed, 30 Jun 2010)
@@ -27,18 +27,22 @@
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 initial_path()
void do_url( const string & url, const string & library_name,
const path & full_source_path, bool no_link_errors,
- bool allow_external_links );
+ 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, invalid urls, broken links, unlinked files"; }
+ virtual const char * desc() const
+ { return "invalid bookmarks, duplicate bookmarks,"
+ " invalid urls, broken links, unlinked files"; }
virtual void inspect(
const std::string & library_name,
@@ -53,7 +57,10 @@
virtual ~link_check()
{
- std::cout << " " << m_bookmark_errors << " bookmarks with invalid characters" << line_break();
+ 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();
Modified: branches/release/tools/inspect/unnamed_namespace_check.cpp
==============================================================================
--- branches/release/tools/inspect/unnamed_namespace_check.cpp (original)
+++ branches/release/tools/inspect/unnamed_namespace_check.cpp 2010-06-30 19:33:33 EDT (Wed, 30 Jun 2010)
@@ -51,8 +51,7 @@
const string::size_type
ln = std::count( contents.begin(), (*cur)[0].first, '\n' ) + 1;
- error( library_name, full_path, string(name()) + " unnamed namespace at line "
- + lexical_cast<string>(ln) );
+ error( library_name, full_path, "Unnamed namespace", ln );
}
Boost-Commit list run by bdawes at acm.org, david.abrahams at rcn.com, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk