From b0f895b8d2ec261e2e09840fe31cce0fcba1444d Mon Sep 17 00:00:00 2001 From: Bcorde5 Date: Mon, 19 Oct 2015 12:21:17 -0500 Subject: [PATCH] Enhanced the inspect tool to take user directly to the problem with hyperlinks. Includes a new header file and changes to the base inspect file. Questions and advice are welcome. --- tools/inspect/apple_macro_check.cpp | 3 + tools/inspect/ascii_check.cpp | 4 +- tools/inspect/assert_macro_check.cpp | 5 +- tools/inspect/copyright_check.cpp | 4 +- tools/inspect/crlf_check.cpp | 3 +- tools/inspect/deprecated_macro_check.cpp | 7 ++- tools/inspect/end_check.cpp | 13 +++- tools/inspect/endline_whitespace_check.cpp | 6 +- tools/inspect/function_hyper.hpp | 46 +++++++++++++++ tools/inspect/inspect.cpp | 18 +++++- tools/inspect/length_check.cpp | 3 +- tools/inspect/license_check.cpp | 3 +- tools/inspect/minmax_check.cpp | 3 +- tools/inspect/path_name_check.cpp | 9 +-- tools/inspect/tab_check.cpp | 69 ++++++++++++++++++---- tools/inspect/unnamed_namespace_check.cpp | 4 +- 16 files changed, 167 insertions(+), 33 deletions(-) create mode 100644 tools/inspect/function_hyper.hpp diff --git a/tools/inspect/apple_macro_check.cpp b/tools/inspect/apple_macro_check.cpp index daf5562becf3..1dd576072015 100644 --- a/tools/inspect/apple_macro_check.cpp +++ b/tools/inspect/apple_macro_check.cpp @@ -8,7 +8,9 @@ // http://www.boost.org/LICENSE_1_0.txt) #include "apple_macro_check.hpp" +#include "function_hyper.hpp" #include +#include #include "boost/regex.hpp" #include "boost/lexical_cast.hpp" #include "boost/filesystem/operations.hpp" @@ -89,6 +91,7 @@ namespace boost } } + std::string lineloc = linelink(full_path, std::to_string(line_number)); ++errors; error( library_name, full_path, "Apple macro clash: " + std::string((*cur)[0].first, (*cur)[0].second-1), diff --git a/tools/inspect/ascii_check.cpp b/tools/inspect/ascii_check.cpp index 373cdae49252..b3c1582902c4 100644 --- a/tools/inspect/ascii_check.cpp +++ b/tools/inspect/ascii_check.cpp @@ -9,6 +9,7 @@ // √ -- this is a test. #include "ascii_check.hpp" +#include "function_hyper.hpp" #include namespace boost @@ -93,7 +94,8 @@ namespace boost ++m_files_with_errors; std::size_t 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 ); + string location = linelink(full_path, the_line); + error( library_name, full_path, "Non-ASCII: ", ln ); } } } // namespace inspect diff --git a/tools/inspect/assert_macro_check.cpp b/tools/inspect/assert_macro_check.cpp index 9c7d6f69e37f..eb75488fed74 100644 --- a/tools/inspect/assert_macro_check.cpp +++ b/tools/inspect/assert_macro_check.cpp @@ -9,6 +9,7 @@ #include "assert_macro_check.hpp" #include +#include "function_hyper.hpp" #include "boost/regex.hpp" #include "boost/lexical_cast.hpp" #include "boost/filesystem/operations.hpp" @@ -95,10 +96,10 @@ namespace boost line_start = it + 1; // could be end() } } - + std::string lineloc = linelink (full_path, boost::lexical_cast(line_number)); ++errors; error( library_name, full_path, "C-style assert macro on line " - + boost::lexical_cast( line_number ) ); + + lineloc ); } } if(errors > 0) diff --git a/tools/inspect/copyright_check.cpp b/tools/inspect/copyright_check.cpp index 3d4ed29ec33f..c620095b28c2 100644 --- a/tools/inspect/copyright_check.cpp +++ b/tools/inspect/copyright_check.cpp @@ -6,6 +6,7 @@ // http://www.boost.org/LICENSE_1_0.txt) #include "copyright_check.hpp" +#include "function_hyper.hpp" namespace boost { @@ -26,7 +27,8 @@ namespace boost && contents.find( "copyright" ) == string::npos ) { ++m_files_with_errors; - error( library_name, full_path, name() ); + std::string lineloc = loclink(full_path, name()); + error( library_name, full_path, lineloc ); } } } // namespace inspect diff --git a/tools/inspect/crlf_check.cpp b/tools/inspect/crlf_check.cpp index 16cf5bc6e12e..01c701490628 100644 --- a/tools/inspect/crlf_check.cpp +++ b/tools/inspect/crlf_check.cpp @@ -9,6 +9,7 @@ // Contributed by Joerg Walter #include "crlf_check.hpp" +#include "function_hyper.hpp" namespace boost { @@ -58,7 +59,7 @@ namespace boost 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" ); + error( library_name, full_path, loclink(full_path, string(name()) + " should have cr-only line endings" )); } /* diff --git a/tools/inspect/deprecated_macro_check.cpp b/tools/inspect/deprecated_macro_check.cpp index f5ce1f0b6ee8..d6bf8f3f59df 100644 --- a/tools/inspect/deprecated_macro_check.cpp +++ b/tools/inspect/deprecated_macro_check.cpp @@ -10,6 +10,7 @@ #include "deprecated_macro_check.hpp" #include +#include "function_hyper.hpp" #include "boost/regex.hpp" #include "boost/lexical_cast.hpp" #include "boost/filesystem/operations.hpp" @@ -117,7 +118,7 @@ namespace boost { if ( contents.find( *ptr ) != string::npos ) { ++errors; - error( library_name, full_path, string ( "Boost macro deprecated in 1.50: " ) + *ptr ); + error( library_name, full_path, loclink(full_path, string ( "Boost macro deprecated in 1.50: " ) + *ptr )); } } @@ -125,7 +126,7 @@ namespace boost { if ( contents.find( *ptr ) != string::npos ) { ++errors; - error( library_name, full_path, string ( "Boost macro deprecated in 1.51: " ) + *ptr ); + error( library_name, full_path, loclink(full_path, string("Boost macro deprecated in 1.51: ") + *ptr)); } } @@ -133,7 +134,7 @@ namespace boost { if ( contents.find( *ptr ) != string::npos ) { ++errors; - error( library_name, full_path, string ( "Boost macro deprecated in 1.53: " ) + *ptr ); + error( library_name, full_path, loclink(full_path, string("Boost macro deprecated in 1.53: ") + *ptr)); } } diff --git a/tools/inspect/end_check.cpp b/tools/inspect/end_check.cpp index 0c8fd3997fb9..656c0e059389 100644 --- a/tools/inspect/end_check.cpp +++ b/tools/inspect/end_check.cpp @@ -8,6 +8,9 @@ // http://www.boost.org/LICENSE_1_0.txt) #include "end_check.hpp" +#include "function_hyper.hpp" +#include +#include #include namespace boost @@ -31,7 +34,13 @@ namespace boost const string & contents ) // contents of file to be inspected { if (contents.find( "hpxinspect:" "noend" ) != string::npos) return; - + int linenumb = 0; + char_separator sep("\n", "", boost::keep_empty_tokens); + tokenizer> tokens(contents, sep); + for (const auto& t : tokens) { + linenumb++; + } + std::string lineloc = std::to_string(linenumb); // this file deliberately contains errors const char test_file_name[] = "wrong_line_ends_test.cpp"; @@ -49,7 +58,7 @@ namespace boost 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" ); + error( library_name, full_path, string(name()) + wordlink(full_path, lineloc, " should end with a newline") ); } } } // namespace inspect diff --git a/tools/inspect/endline_whitespace_check.cpp b/tools/inspect/endline_whitespace_check.cpp index b867668597c8..65ec14cb0a72 100644 --- a/tools/inspect/endline_whitespace_check.cpp +++ b/tools/inspect/endline_whitespace_check.cpp @@ -7,6 +7,7 @@ // http://www.boost.org/LICENSE_1_0.txt) #include "endline_whitespace_check.hpp" +#include "function_hyper.hpp" #include #include #include @@ -16,6 +17,7 @@ #include "boost/lexical_cast.hpp" #include "boost/filesystem/operations.hpp" + using namespace std; namespace fs = boost::filesystem; @@ -95,7 +97,7 @@ namespace boost p = 0; while (p < lineorder.size()) { - total += lineorder[p]; + total += linelink(full_path, lineorder[p]); //linelink is located in function_hyper.hpp if (p < lineorder.size() - 1) { total += ", "; @@ -104,7 +106,7 @@ namespace boost } if (errors > 0) { - string errored = "Endline Whitespace*: " + total; + string errored = "*Endline Whitespace*: " + total; error(library_name, full_path, errored); ++m_files_with_errors; } diff --git a/tools/inspect/function_hyper.hpp b/tools/inspect/function_hyper.hpp new file mode 100644 index 000000000000..043412de8ff9 --- /dev/null +++ b/tools/inspect/function_hyper.hpp @@ -0,0 +1,46 @@ +// Hyperlink Function ------------------------------------------// + +// Copyright (c) 2015 Brandon Cordes +// 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 FUNCTION_HYPER_HPP +#define FUNCTION_HYPER_HPP + +#include "boost/filesystem/path.hpp" +#include +#include + +using boost::filesystem::path; +//When you have a specific line and the line is the location of the link +inline std::string linelink(const path & full_path, std::string linenumb) +{ + std::string commit = HPX_HAVE_GIT_COMMIT; + std::string total, location = full_path.string(); + total += "†a href = \"https://github.com/STEllAR-GROUP/hpx/blob/" + commit + "/" + location + "#L" + linenumb + "\"‡"; + total = total + linenumb; + total = total + "†/a‡"; + return total; +} +//When you have a specific line, but a word is the location of the link +inline std::string wordlink(const path & full_path, std::string linenumb, std::string word) +{ + std::string commit = HPX_HAVE_GIT_COMMIT; + std::string total, location = full_path.string(); + total += "†a href = \"https://github.com/STEllAR-GROUP/hpx/blob/" + commit + "/" + location + "#L" + linenumb + "\"‡"; + total = total + word; + total = total + "†/a‡"; + return total; +} +//When you don't have a specific line +inline std::string loclink(const path & full_path, std::string word) +{ + std::string commit = HPX_HAVE_GIT_COMMIT; + std::string total, location = full_path.string(); + total += "†a href = \"https://github.com/STEllAR-GROUP/hpx/blob/" + commit + "/" + location + "\"‡"; + total = total + word; + total = total + "†/a‡"; + return total; +} +#endif \ No newline at end of file diff --git a/tools/inspect/inspect.cpp b/tools/inspect/inspect.cpp index d3e937fcaef2..d4c3737ac867 100644 --- a/tools/inspect/inspect.cpp +++ b/tools/inspect/inspect.cpp @@ -28,12 +28,14 @@ const char* hpx_no_inspect = "hpx-" "no-inspect"; #include #include #include +#include #include "boost/shared_ptr.hpp" #include "boost/lexical_cast.hpp" #include "boost/filesystem/operations.hpp" #include "boost/filesystem/fstream.hpp" #include "boost/program_options.hpp" +#include "function_hyper.hpp" #include // for popen, pclose #if defined(_MSC_VER) @@ -444,6 +446,13 @@ namespace case '&': result += "&"; break; + //† and ‡ are used to force html formatting when needed, as these obscure ascii characters are practically unused + case '†': + result += "<"; + break; + case '‡': + result += ">"; + break; default: result += *it; } @@ -520,7 +529,7 @@ namespace { if ( !first ) out << "\n"; out << "\n

library - << "\">" << itr->library << "

\n
";
+              << "\">" << itr->library << "\n
";
         }
         if ( current.library != itr->library
           || current.rel_path != itr->rel_path )
@@ -543,7 +552,12 @@ namespace
 
           // print the message
           if (itr->line_number)
-            out << sep << "(line " << itr->line_number << ") " << html_encode(itr->msg);
+          {
+              string line = std::to_string(itr->line_number);
+              const path & full_path = itr->library;
+              string link = linelink(full_path, line);
+              out << sep << "(line " << link << ") " << html_encode(itr->msg);
+          }
           else out << sep << html_encode(itr->msg);
 
           first_sep = false;
diff --git a/tools/inspect/length_check.cpp b/tools/inspect/length_check.cpp
index 56e10c9ba4e3..b6f93a958164 100644
--- a/tools/inspect/length_check.cpp
+++ b/tools/inspect/length_check.cpp
@@ -7,6 +7,7 @@
 //  http://www.boost.org/LICENSE_1_0.txt)
 
 #include "length_check.hpp"
+#include "function_hyper.hpp"
 #include 
 #include 
 #include 
@@ -111,7 +112,7 @@ namespace boost
             p = 0;
             while (p < lineorder.size())
             {
-                total += lineorder[p];
+                total += linelink(full_path, lineorder[p]);  //linelink is located in function_hyper.hpp
                 if (p < lineorder.size() - 1)
                 {
                     total += ", ";
diff --git a/tools/inspect/license_check.cpp b/tools/inspect/license_check.cpp
index b5f8f5f7fde6..f9f148db4c92 100644
--- a/tools/inspect/license_check.cpp
+++ b/tools/inspect/license_check.cpp
@@ -7,6 +7,7 @@
 
 #include "boost/regex.hpp"
 #include "license_check.hpp"
+#include "function_hyper.hpp"
 
 namespace
 {
@@ -39,7 +40,7 @@ namespace boost
       if ( !boost::regex_search( contents, license_regex ) )
       {
         ++m_files_with_errors;
-        error( library_name, full_path, name() );
+        error( library_name, full_path, loclink(full_path, name()) );
       }
     }
   } // namespace inspect
diff --git a/tools/inspect/minmax_check.cpp b/tools/inspect/minmax_check.cpp
index 5ff7817672c9..b4312fadd70c 100644
--- a/tools/inspect/minmax_check.cpp
+++ b/tools/inspect/minmax_check.cpp
@@ -13,6 +13,7 @@
 #include "minmax_check.hpp"
 #include "boost/regex.hpp"
 #include "boost/lexical_cast.hpp"
+#include "function_hyper.hpp"
 
 namespace
 {
@@ -91,7 +92,7 @@ namespace boost
           ++m_errors;
           error( library_name, full_path, string(name())
               + " violation of Boost min/max guidelines on line "
-              + boost::lexical_cast( line_number ) );
+              + linelink(full_path, boost::lexical_cast(line_number)));
         }
 
       }
diff --git a/tools/inspect/path_name_check.cpp b/tools/inspect/path_name_check.cpp
index 849dabaa6848..07e68b8b4701 100644
--- a/tools/inspect/path_name_check.cpp
+++ b/tools/inspect/path_name_check.cpp
@@ -11,6 +11,7 @@
 
 #include "boost/filesystem/operations.hpp"
 #include "boost/lexical_cast.hpp"
+#include "function_hyper.hpp"
 
 #include 
 #include 
@@ -46,7 +47,7 @@ namespace boost
       if ( (pos = leaf.find_first_not_of( allowable )) != string::npos )
       {
         ++m_name_errors;
-        error( library_name, full_path, string(name())
+        error( library_name, full_path, loclink(full_path, string(name()))
             + " file or directory name contains unacceptable character '"
             + leaf[pos] + "'" );
       }
@@ -55,7 +56,7 @@ namespace boost
       if ( std::strchr( initial_char, leaf[0] ) == 0 )
       {
         ++m_name_errors;
-        error( library_name, full_path, string(name())
+        error( library_name, full_path, loclink(full_path, string(name()))
             + " file or directory name begins with an unacceptable character" );
       }
 
@@ -65,7 +66,7 @@ namespace boost
         if ( std::strchr( leaf.c_str(), '.' ) )
         {
           ++m_name_errors;
-          error( library_name, full_path, string(name())
+          error( library_name, full_path, loclink(full_path, string(name()))
               + " directory name contains a dot character ('.')" );
         }
       }
@@ -90,7 +91,7 @@ namespace boost
       {
         ++m_name_errors;
         error( library_name, full_path,
-            string(name())
+            loclink(full_path, string(name()))
             + " path will exceed "
             + boost::lexical_cast(max_relative_path)
             + " characters in a directory tree with a root in the form "
diff --git a/tools/inspect/tab_check.cpp b/tools/inspect/tab_check.cpp
index d6cf02982637..b3032b50ec96 100644
--- a/tools/inspect/tab_check.cpp
+++ b/tools/inspect/tab_check.cpp
@@ -7,6 +7,10 @@
 //  http://www.boost.org/LICENSE_1_0.txt)
 
 #include "tab_check.hpp"
+#include "function_hyper.hpp"
+#include 
+#include 
+#include 
 
 namespace boost
 {
@@ -26,18 +30,61 @@ namespace boost
    }
 
    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( "hpxinspect:" "notab" ) != string::npos) return;
+       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("hpxinspect:" "notab") != string::npos) return;
+       string total, linenum;
+       long errors = 0, currline = 0;
+       size_t p = 0, extend = 0;
+       std::vector someline, lineorder;
 
-      if ( contents.find( '\t' ) != string::npos )
-      {
-        ++m_files_with_errors;
-        error( library_name, full_path, name() );
-      }
-    }
+       char_separator sep("\n", "", boost::keep_empty_tokens);
+       tokenizer> tokens(contents, sep);
+       for (const auto& t : tokens) {
+           size_t rend = t.find_first_of("\r"), size = t.size();
+           if (rend == size - 1)
+           {
+               someline.push_back(t);
+           }
+           else
+           {
+               char_separator sep2("\r", "", boost::keep_empty_tokens);
+               tokenizer> tokens2(t, sep2);
+               for (const auto& u : tokens2) {
+                   someline.push_back(u);
+               }
+           }
+       }
+       while (p < someline.size())
+       {
+           currline++;
+           if (someline[p].find('\t') != string::npos)
+           {
+               errors++;
+               linenum = std::to_string(currline);
+               lineorder.push_back(linenum);
+           }
+           p++;
+       }
+       p = 0;
+       while (p < lineorder.size())
+       {
+           total += linelink(full_path, lineorder[p]);  //linelink is located in function_hyper.hpp
+           if (p < lineorder.size() - 1)
+           {
+               total += ", ";
+           }
+           p++;
+       }
+       if (errors > 0)
+       {
+           string errored = name() + total;
+           error(library_name, full_path, errored);
+           ++m_files_with_errors;
+       }
+   }
   } // namespace inspect
 } // namespace boost
 
diff --git a/tools/inspect/unnamed_namespace_check.cpp b/tools/inspect/unnamed_namespace_check.cpp
index 0bcf1c70d622..b28142de5ba6 100644
--- a/tools/inspect/unnamed_namespace_check.cpp
+++ b/tools/inspect/unnamed_namespace_check.cpp
@@ -9,6 +9,8 @@
 #include "boost/regex.hpp"
 #include "boost/lexical_cast.hpp"
 #include "unnamed_namespace_check.hpp"
+#include "function_hyper.hpp"
+#include 
 
 
 namespace
@@ -51,7 +53,7 @@ namespace boost
         const string::size_type
          ln = std::count( contents.begin(), (*cur)[0].first, '\n' ) + 1;
 
-        error( library_name, full_path, "Unnamed namespace", ln );
+        error( library_name, full_path, "Unnamed namespace" + linelink(full_path, std::to_string(ln)));
       }