LifeV
inspect.cpp
Go to the documentation of this file.
1 // inspect program ---------------------------------------------------------//
2 
3 // Copyright Beman Dawes 2002.
4 // Copyright Rene Rivera 2004.
5 // Distributed under the Boost Software License, Version 1.0.
6 // (See accompanying file LICENSE_1_0.txt or copy at
7 // http://www.boost.org/LICENSE_1_0.txt)
8 
9 // This program recurses through sub-directories looking for various problems.
10 // It contains some Boost specific features, like ignoring "CVS" and "bin",
11 // and the code that identifies library names assumes the Boost directory
12 // structure.
13 
14 // See http://www.boost.org/tools/inspect for more information.
15 
16 #include <boost/shared_ptr.hpp>
17 #include <boost/filesystem/exception.hpp>
18 #include <boost/filesystem/operations.hpp>
19 #include <boost/filesystem/fstream.hpp>
20 
21 #include <iostream>
22 #include <cassert>
23 #include <vector>
24 #include <list>
25 #include <utility>
26 #include <algorithm>
27 #include <cstring>
28 
29 #include "inspector.hpp" // includes <string>, <boost/filesystem/path.hpp>,
30 // <iostream>, <set>
31 // and gives using for string and path.
32 #include "copyright_check.hpp"
33 #include "crlf_check.hpp"
34 #include "license_check.hpp"
35 #include "long_name_check.hpp"
36 #include "tab_check.hpp"
37 #include "minmax_check.hpp"
38 #include "cvs_iterator.hpp"
39 
40 namespace fs = boost::filesystem;
41 
42 std::string
44 {
45  return "BODY {\n"
46  " color: #000;\n"
47  " font: 100% \"Lucida Grande\", Verdana, Lucida, Helvetica, Arial, sans-serif;\n"
48  " background-color: White;\n"
49  " color: Black;\n"
50  " margin: 0;\n"
51  " padding: 0;\n"
52  " /* background: #eeeeee;*/\n"
53  " /*background: #FFE;\n"
54  " margin-left: 0em;\n"
55  " margin-right: 0em;\n"
56  " font-family: \"Arial\", \"Helvetica\", sans-serif;*/\n"
57  " /* line-height: 1.35; */ /* This would break MacIE 3 */\n"
58  " }\n"
59  "\n"
60  "p {\n"
61  " margin: 1em 1em 1em 1em;\n"
62  " line-height: 1.5em;\n"
63  " }\n"
64  "p a {\n"
65  " text-decoration: underline;\n"
66  " }\n"
67  "p a:visited {\n"
68  " color: Purple;\n"
69  " background-color: transparent;\n"
70  "}\n"
71  "p a:active {\n"
72  " color: Red;\n"
73  " background-color: transparent;\n"
74  "}\n"
75  "p img {\n"
76  " border: 0;\n"
77  " margin: 0;\n"
78  "}\n"
79  "h1, h2, h3, h4, h5, h6 {\n"
80  " color: Black;\n"
81  " background-color: transparent;\n"
82  " font-family: \"Lucida Grande\", Verdana, Lucida, Helvetica, Arial, sans-serif;\n"
83  " font-size: 100%;\n"
84  " font-weight: normal;\n"
85  " margin: 0;\n"
86  " padding-top: 0.5em;\n"
87  " border-bottom: 1px solid #8cacbb;\n"
88  "}\n"
89  "\n"
90  "h1 a,\n"
91  "h2 a,\n"
92  "h3 a,\n"
93  "h4 a,\n"
94  "h5 a,\n"
95  "h6 a {\n"
96  " color: Black ! important; \n"
97  "}\n"
98  "\n"
99  "h1 {\n"
100  " font-size: 180%;\n"
101  "}\n"
102  "\n"
103  "h2 {\n"
104  " font-size: 160%;\n"
105  "}\n"
106  "\n"
107  "h3 {\n"
108  " font-size: 130%;\n"
109  " border-bottom: none;\n"
110  " /*font-weight: bold;*/\n"
111  " margin-left: 1em;\n"
112  "}\n"
113  "\n"
114  "h4 {\n"
115  " font-size: 120%;\n"
116  " border-bottom: none;\n"
117  " font-weight: bold;\n"
118  " text-align: right;\n"
119  " text-transform: capitalize\n"
120  "}\n"
121  "\n"
122  "h5 {\n"
123  " font-size: 100%;\n"
124  " border-bottom: none;\n"
125  " font-weight: bold;\n"
126  "}\n"
127  "\n"
128  "h6 {\n"
129  " font-size: 85%;\n"
130  " border-bottom: none;\n"
131  " font-weight: bold;\n"
132  "}\n"
133  "\n"
134  "pre {\n"
135  " font-size: 90%;\n"
136  " padding: 1em;\n"
137  " border: 1px dashed #8cacbb;\n"
138  " color: Black;\n"
139  " background-color: #dee7ec;\n"
140  " overflow: auto;\n"
141  "}\n"
142  ".pre a {\n"
143  " text-decoration: underline;\n"
144  "}\n"
145  "\n"
146  "div.error{ color: #ff0000;font-size: 120%;font-weight: bold }\n"
147  "div.command{ margin-left:2em;margin-right:2em}\n"
148  "\n"
149  "#topmenu {position: absolute; top: 2em; right: 0; width: 15em; margin: 0; padding: 0; font-family: Arial, sans-serif;}\n"
150  "#topmenu ul {padding: 0; margin: 0; border-bottom: 1px solid silver; font: 1em sans-serif;}\n"
151  "#topmenu ul li {list-style-type: none; border: 1px solid silver; border-width: 1px 1px 0 3px; position: relative; margin: 0; padding: 0;}\n"
152  "#topmenu ul ul {display: none;}\n"
153  "#topmenu ul li:hover > ul {display: block; position: absolute; top: -1px; left: 100%;}\n"
154  "#topmenu li > a {display: block; padding: 5px 7px; text-decoration: none; background: #ffff00; margin-left: -10.2em; }\n"
155  "/*\n"
156  "#topmenu li:hover {background-color: #EED;display: block; }\n"
157  "#topmenu li.sub:hover {margin-left: -10.2em; border: 1px solid gray; background: #DDB;}\n"
158  "#topmenu li.sub:hover > a {color: #330;}\n"
159  "#topmenu li.sub:hover > ul {top: 1.75em; left: -1px; background: #FEFEFC;}*/\n"
160  "#topmenu ul li a:hover {background: #DDB;display:block;}\n"
161  "#topmenu li.sub > a {font-weight: bold; background: #DDB;}\n"
162  "#topmenu ul {width: 15em;}\n"
163  "#topmenu ul > li:hover > ul {width: 10em; top: 1.5em; left: -3px;}\n"
164  "\n"
165  "#rtnv { position: absolute; top: 2em; right: 0; width: 15em; \n"
166  " margin: 0; padding: 0; font-family: Arial, sans-serif;background: #dddddd fixed;\n"
167  " position: fixed; float:right; border: 1px solid black; border-width:\n"
168  "1px; /*opacity: .5;-khtml-opacity: .5*/\n"
169  " }\n"
170  "/*#rtnv > ul {width: 9em; margin-left: -1px; font-size: 85%;}\n"
171  "#rtnv ul {border: 1px solid silver; border-width: 0 0 0 1px}*/\n"
172  "#rtnv ul {padding: 0; margin: 0; border-bottom: 1px solid silver; font: 1em sans-serif;}\n"
173  "#rtnv ul li {list-style-type: none; border: 1px solid silver; border-width:\n"
174  "1px 1px 0 3px; position: relative; margin: 0; padding:\n"
175  "0;text-align=left;}\n"
176  "#rtnv ul ul {display: none;}\n"
177  "/*#rtnv ul li {list-style-type: none; border-width: 1px 0; border-color: white; padding: 0 0 0 5px; line-height: 1.25em;}\n"
178  "#rtnv ul ul {border-width: 0 1px 1px 1px; border-color: gray silver gray gray;}*/\n"
179  "#rtnv ul ul li {border-color: #FEFEFC;}\n"
180  "#rtnv ul li:hover > ul {display: block; position: absolute; top: -1px; left: 100%;}\n"
181  "#rtnv li > a {background-color: transparent; padding: 3px;display: block; }\n"
182  "#rtnv li a:hover {background-color: #EED;display: block; }\n"
183  "#rtnv li.sub:hover {margin-left: -15em; border: 1px solid gray; background: #DDB;}\n"
184  "#rtnv li.sub:hover > a {color: #330;}\n"
185  "#rtnv li.sub:hover > ul {top: 1.75em; left: -1px; background: #DDA;}\n";
186 }
187 
188 namespace
189 {
191 
193 {
195 
197 };
198 
200 
204 
206 
207 
208 
209 struct error_msg
210 {
211  string library;
212  string rel_path;
213  string msg;
214 
215  bool operator< ( const error_msg& rhs ) const
216  {
217  if ( library < rhs.library )
218  {
219  return true;
220  }
221  if ( library > rhs.library )
222  {
223  return false;
224  }
225  if ( rel_path < rhs.rel_path )
226  {
227  return true;
228  }
229  if ( rel_path > rhs.rel_path )
230  {
231  return false;
232  }
233  return msg < rhs.msg;
234  }
235 };
236 
239 
240 // visit_predicate (determines which directories are visited) --------------//
241 
242 typedef bool (*pred_type) (const path&);
243 
244 bool visit_predicate ( const path& pth )
245 {
246  string leaf ( pth.leaf() );
247  return
248  leaf != "CVS"
249  && leaf != "admin"
250  && leaf != ".deps"
251  && leaf != ".libs"
252  && leaf != "autom4te.cache"
253  && leaf != "Templates"
254  && leaf != "bin"
255  && leaf != "jam_src" // this really out of our hands
256  && leaf != "status" // too many issues with generated HTML files
257  ;
258 }
259 
260 // library_from_content ----------------------------------------------------//
261 
262 string library_from_content ( const string& content )
263 {
264  string::size_type pos ( content.find ( "www.boost.org/libs/" ) );
265 
266  if ( pos == string::npos )
267  {
268  return "unknown";
269  }
270 
271  string lib;
272  pos += 19;
273  while ( content[pos] != ' '
274  && content[pos] != '/'
275  && content[pos] != '\n'
276  && content[pos] != '\r'
277  && content[pos] != '\t' )
278  {
279  lib += content[pos++];
280  }
281  return lib;
282 }
283 
284 // find_signature ----------------------------------------------------------//
285 
286 bool find_signature ( const path& file_path,
287  const boost::inspect::string_set& signatures )
288 {
289  string name ( file_path.leaf() );
290  if ( signatures.find ( name ) == signatures.end() )
291  {
292  string::size_type pos ( name.rfind ( '.' ) );
293  if ( pos == string::npos
294  || signatures.find ( name.substr ( pos ) )
295  == signatures.end() )
296  {
297  return false;
298  }
299  }
300  return true;
301 }
302 
303 // load_content ------------------------------------------------------------//
304 
305 void load_content ( const path& file_path, string& target )
306 {
307  target = "";
308 
309  if ( !find_signature ( file_path, content_signatures ) )
310  {
311  return;
312  }
313 
314  fs::ifstream fin ( file_path, std::ios_base::in | std::ios_base::binary );
315  if ( !fin )
316  {
317  throw string ( "could not open input file: " ) + file_path.string();
318  }
319  std::getline ( fin, target, '\0' ); // read the whole file
320 }
321 
322 // check -------------------------------------------------------------------//
323 
324 void check ( const string& lib,
325  const path& pth, const string& content, const inspector_list& insp_list )
326 {
327  // invoke each inspector
328  for ( inspector_list::const_iterator itr = insp_list.begin();
329  itr != insp_list.end(); ++itr )
330  {
331  itr->inspector->inspect ( lib, pth ); // always call two-argument form
332  if ( find_signature ( pth, itr->inspector->signatures() ) )
333  {
334  itr->inspector->inspect ( lib, pth, content );
335  }
336  }
337 }
338 
339 // visit_all ---------------------------------------------------------------//
340 
341 template< class DirectoryIterator >
342 void visit_all ( const string& lib,
343  const path& dir_path, const inspector_list& insps )
344 {
345  static DirectoryIterator end_itr;
346  ++directory_count;
347 
348  for ( DirectoryIterator itr ( dir_path ); itr != end_itr; ++itr )
349  {
350 
351  if ( fs::is_directory ( *itr ) )
352  {
353  if ( visit_predicate ( *itr ) )
354  {
355  string cur_lib ( boost::inspect::impute_library ( *itr ) );
356  check ( cur_lib, *itr, "", insps );
357  visit_all<DirectoryIterator> ( cur_lib, *itr, insps );
358  }
359  }
360  else
361  {
362  ++file_count;
363  string content;
364  load_content ( *itr, content );
365  check ( lib == "unknown"
366  ? library_from_content ( content ) : lib, *itr, content, insps );
367  }
368  }
369 }
370 
371 // display_summary_helper --------------------------------------------------//
372 
373 void display_summary_helper ( const string& current_library, int err_count )
374 {
375  std::cout << " <tr><td><a href=\"#"
376  << current_library
377  << "\">" << current_library
378  << "</a></td><td align=\"center\">"
379  << err_count << "</td></tr>\n";
380 }
381 
382 // display_summary ---------------------------------------------------------//
383 
385 {
386  std::cout << "</pre>\n"
387  "<h2>Summary</h2>\n"
388  "<table border=\"1\" cellpadding=\"5\" cellspacing=\"0\">\n"
389  " <tr>\n"
390  " <td><b>Library</b></td>\n"
391  " <td><b>Problems</b></td>\n"
392  " </tr>\n"
393  ;
394  string current_library ( msgs.begin()->library );
395  int err_count = 0;
396  for ( error_msg_vector::iterator itr ( msgs.begin() );
397  itr != msgs.end(); ++itr )
398  {
399  if ( current_library != itr->library )
400  {
401  display_summary_helper ( current_library, err_count );
402  current_library = itr->library;
403  err_count = 0;
404  }
405  ++err_count;
406  }
407  display_summary_helper ( current_library, err_count );
408 
409  std::cout << "</table>\n";
410 }
411 
412 
413 // display_details ---------------------------------------------------------//
414 
416 {
417  std::cout << "<h2>Details</h2>\n";
418 
419  // display error messages with group indication
420  error_msg current;
421  string sep;
422  bool first = true;
423  for ( error_msg_vector::iterator itr ( msgs.begin() );
424  itr != msgs.end(); ++itr )
425  {
426  if ( current.library != itr->library )
427  {
428  if ( !first )
429  {
430  std::cout << "</pre>\n";
431  }
432  std::cout << "\n<h3><a name=\"" << itr->library
433  << "\">" << itr->library << "</a></h3>\n<pre>";
434  }
435  if ( current.library != itr->library
436  || current.rel_path != itr->rel_path )
437  {
438  std::cout << "\n";
439  std::cout << itr->rel_path;
440  sep = ": ";
441  }
442  if ( current.library != itr->library
443  || current.rel_path != itr->rel_path
444  || current.msg != itr->msg )
445  {
446  std::cout << sep << itr->msg;
447  sep = ", ";
448  }
449  current.library = itr->library;
450  current.rel_path = itr->rel_path;
451  current.msg = itr->msg;
452  first = false;
453  }
454  std::cout << "</pre>\n";
455 }
456 
457 const char* options()
458 {
459  return
460  " -license\n"
461  " -copyright\n"
462  " -crlf\n"
463  " -link\n"
464  " -long_name\n"
465  " -tab\n"
466  " -minmax\n"
467  "default is all checks on; otherwise options specify desired checks\n";
468 }
469 
470 } // unnamed namespace
471 
472 namespace boost
473 {
474 namespace inspect
475 {
476 
477 // register_signature ------------------------------------------------------//
478 
479 void inspector::register_signature ( const string& signature )
480 {
481  m_signatures.insert ( signature );
482  content_signatures.insert ( signature );
483 }
484 
485 // error -------------------------------------------------------------------//
486 
487 void inspector::error ( const string& library_name,
488  const path& full_path, const string& msg )
489 {
490  ++error_count;
491  error_msg err_msg;
492  err_msg.library = library_name;
493  err_msg.rel_path = relative_to ( full_path, fs::initial_path() );
494  err_msg.msg = msg;
495  msgs.push_back ( err_msg );
496 
497  // std::cout << library_name << ": "
498  // << full_path.string() << ": "
499  // << msg << '\n';
500 
501 }
502 
504 {
505  // C/C++ source code...
506  register_signature ( ".c" );
507  register_signature ( ".cpp" );
508  register_signature ( ".css" );
509  register_signature ( ".cxx" );
510  register_signature ( ".h" );
511  register_signature ( ".hpp" );
512  register_signature ( ".hxx" );
513  register_signature ( ".inc" );
514  register_signature ( ".ipp" );
515 
516  // Boost.Build BJam source code...
517  register_signature ( "Jamfile" );
518  register_signature ( ".jam" );
519  register_signature ( ".v2" );
520 
521  // Other scripts; Python, shell, autoconfig, etc.
522  register_signature ( "configure.in.in" );
523  register_signature ( "GNUmakefile" );
524  register_signature ( "Makefile.am" );
525  register_signature ( ".bat" );
526  register_signature ( ".mak" );
527  register_signature ( ".pl" );
528  register_signature ( ".py" );
529  register_signature ( ".sh" );
530 
531  // Hypertext, Boost.Book, and other text...
532  register_signature ( "news" );
533  register_signature ( "readme" );
534  register_signature ( "todo" );
535  register_signature ( "NEWS" );
536  register_signature ( "README" );
537  register_signature ( "TODO" );
538  register_signature ( ".boostbook" );
539  register_signature ( ".htm" );
540  register_signature ( ".html" );
541  register_signature ( ".rst" );
542  register_signature ( ".sgml" );
543  register_signature ( ".shtml" );
544  register_signature ( ".txt" );
545  register_signature ( ".xml" );
546  register_signature ( ".xsd" );
547  register_signature ( ".xsl" );
548 }
549 
551 {
552  register_signature ( ".htm" );
553  register_signature ( ".html" );
554  register_signature ( ".shtml" );
555 }
556 
557 // impute_library ----------------------------------------------------------//
558 
559 string impute_library ( const path& full_dir_path )
560 {
561  path relative ( relative_to ( full_dir_path, fs::initial_path() ),
562  fs::no_check );
563  if ( relative.empty() )
564  {
565  return "lifev-root";
566  }
567  string first ( *relative.begin() );
568  string second = // borland 5.61 requires op=
569  ++relative.begin() == relative.end()
570  ? string() : *++relative.begin();
571 
572  if ( first == "life" )
573  {
574  return second.empty() ? string ( "unknown" ) : second;
575  }
576 
577  return ( ( first == "testsuite" || first == "tools" ) && !second.empty() )
578  ? second : first;
579 }
580 
581 } // namespace inspect
582 } // namespace boost
583 
584 // cpp_main() --------------------------------------------------------------//
585 
586 #include <boost/test/included/prg_exec_monitor.hpp>
587 
588 int cpp_main ( int argc, char* argv[] )
589 {
590  fs::initial_path();
591 
592  if ( argc > 1 && (std::strcmp ( argv[1], "-help" ) == 0
593  || std::strcmp ( argv[1], "--help" ) == 0 ) )
594  {
595  std::clog << "Usage: inspect [-cvs] [options...]\n"
596  "options:\n"
597  << options();
598  return 1;
599  }
600 
601  bool license_ck = true;
602  bool copyright_ck = true;
603  bool crlf_ck = true;
604  bool link_ck = true;
605  bool long_name_ck = true;
606  bool tab_ck = true;
607  bool minmax_ck = true;
608  bool cvs = false;
609 
610  if ( argc > 1 && std::strcmp ( argv[1], "-cvs" ) == 0 )
611  {
612  cvs = true;
613  --argc;
614  ++argv;
615  }
616 
617  if ( argc > 1 && *argv[1] == '-' )
618  {
619  license_ck = false;
620  copyright_ck = false;
621  crlf_ck = false;
622  link_ck = false;
623  long_name_ck = false;
624  tab_ck = false;
625  minmax_ck = false;
626  }
627 
628  for (; argc > 1; --argc, ++argv )
629  {
630  if ( std::strcmp ( argv[1], "-license" ) == 0 )
631  {
632  license_ck = true;
633  }
634  else if ( std::strcmp ( argv[1], "-copyright" ) == 0 )
635  {
636  copyright_ck = true;
637  }
638  else if ( std::strcmp ( argv[1], "-crlf" ) == 0 )
639  {
640  crlf_ck = true;
641  }
642  else if ( std::strcmp ( argv[1], "-link" ) == 0 )
643  {
644  link_ck = true;
645  }
646  else if ( std::strcmp ( argv[1], "-long_name" ) == 0 )
647  {
648  long_name_ck = true;
649  }
650  else if ( std::strcmp ( argv[1], "-tab" ) == 0 )
651  {
652  tab_ck = true;
653  }
654  else if ( std::strcmp ( argv[1], "-minmax" ) == 0 )
655  {
656  minmax_ck = true;
657  }
658  else
659  {
660  std::cerr << "unknown option: " << argv[1]
661  << "\nvalid options are:\n"
662  << options();
663  return 1;
664  }
665  }
666 
667  inspector_list inspectors;
668 
669  if ( license_ck )
670  {
671  inspectors.push_back ( inspector_element ( new boost::inspect::license_check ) );
672  }
673  if ( copyright_ck )
674  {
675  inspectors.push_back ( inspector_element ( new boost::inspect::copyright_check ) );
676  }
677  if ( crlf_ck )
678  {
679  inspectors.push_back ( inspector_element ( new boost::inspect::crlf_check ) );
680  }
681  //if ( link_ck )
682  //inspectors.push_back( inspector_element( new boost::inspect::link_check ) );
683  if ( long_name_ck )
684  {
685  inspectors.push_back ( inspector_element ( new boost::inspect::long_name_check ) );
686  }
687  if ( tab_ck )
688  {
689  inspectors.push_back ( inspector_element ( new boost::inspect::tab_check ) );
690  }
691  if ( minmax_ck )
692  {
693  inspectors.push_back ( inspector_element ( new boost::inspect::minmax_check ) );
694  }
695 
696  // perform the actual inspection, using the requested type of iteration
697  if ( cvs )
698  visit_all<hack::cvs_iterator> ( "lifev-root",
699  fs::initial_path(), inspectors );
700  else
701  visit_all<fs::directory_iterator> ( "lifev-root",
702  fs::initial_path(), inspectors );
703 
704  // close
705  for ( inspector_list::iterator itr = inspectors.begin();
706  itr != inspectors.end(); ++itr )
707  {
708  itr->inspector->close();
709  }
710 
711  char run_date[128];
712  std::time_t tod;
713  std::time ( &tod );
714  std::strftime ( run_date, sizeof (run_date),
715  "%X UTC, %A %d %B %Y", std::gmtime ( &tod ) );
716 
717  std::cout << "<html>\n"
718  "<head>\n"
719  "<title>LifeV Inspection Report</title>\n"
720  "<style type=\"text/css\">\n"
721  << css_style() <<
722  "</style>\n"
723  "</head>\n"
724  "<body bgcolor=\"#ffffff\" text=\"#000000\">\n"
725  "<h1>LifeV Inspection Report(95% based on Boost Inspection tool)</h1>\n"
726  "<p><b>Run Date:</b> " << run_date << "</p>\n"
727  "<h2>Introduction</h2>\n"
728  "<p>The <a href=\"http://www.boost.org/tools/inspect/index.html\">inspection\n"
729  "program</a> checks each file in the current Life CVS for various problems,\n"
730  "generating this web page as output. Problems detected include tabs in files,\n"
731  "missing copyrights, broken URL's, and similar misdemeanors.</p>\n";
732 
733  std::cout <<
734  "<p> Differences between <tt>LifeV::inspect</tt> and <tt>boost::inspect</tt>\n"
735  "<ul>\n"
736  "<li>LifeV::inspect is good looking thanks to proper css usage :)</li>\n"
737  "<li>LifeV::inspect does not check in admin, Templates and autom4te.cache</li>\n"
738  "<li>LifeV::inspect checks for GPL and LGPL presence in header and not Boost License</li>\n"
739  "<li>LifeV::inspect does not check for links</li>\n"
740  "</ul>\n";
741 
742  std::cout << "<h2>Totals</h2>\n<pre>"
743  << file_count << " files scanned\n"
744  << directory_count << " directories scanned\n"
745  << error_count << " problems reported\n";
746 
747  std::cout << "\nproblem counts:\n";
748 
749  for ( inspector_list::iterator itr = inspectors.begin();
750  itr != inspectors.end(); ++itr )
751  {
752  itr->inspector.reset();
753  }
754 
755  std::sort ( msgs.begin(), msgs.end() );
756 
757  if ( !msgs.empty() )
758  {
761  }
762 
763  std::cout << "</body>\n"
764  "</html>\n";
765  return 0;
766 }
string impute_library(const path &full_dir_path)
Definition: inspect.cpp:559
int cpp_main(int argc, char *argv[])
Definition: inspect.cpp:588
inspector_element(boost::inspect::inspector *p)
Definition: inspect.cpp:196
bool operator<(const error_msg &rhs) const
Definition: inspect.cpp:215
std::vector< error_msg > error_msg_vector
Definition: inspect.cpp:237
void visit_all(const string &lib, const path &dir_path, const inspector_list &insps)
Definition: inspect.cpp:342
void load_content(const path &file_path, string &target)
Definition: inspect.cpp:305
bool(* pred_type)(const path &)
Definition: inspect.cpp:242
std::set< string > string_set
Definition: inspector.hpp:24
string relative_to(const path &src_arg, const path &base_arg)
Definition: inspector.hpp:82
void check(const string &lib, const path &pth, const string &content, const inspector_list &insp_list)
Definition: inspect.cpp:324
std::shared_ptr< boost::inspect::inspector > inspector_ptr
Definition: inspect.cpp:190
boost::inspect::string_set content_signatures
Definition: inspect.cpp:205
std::list< inspector_element > inspector_list
Definition: inspect.cpp:199
void display_summary_helper(const string &current_library, int err_count)
Definition: inspect.cpp:373
string library_from_content(const string &content)
Definition: inspect.cpp:262
bool find_signature(const path &file_path, const boost::inspect::string_set &signatures)
Definition: inspect.cpp:286
std::string css_style()
Definition: inspect.cpp:43
bool visit_predicate(const path &pth)
Definition: inspect.cpp:244