Boost logo

Boost-Commit :

Subject: [Boost-commit] svn:boost r81228 - trunk/tools/regression/src
From: ramey_at_[hidden]
Date: 2012-11-06 16:20:29


Author: ramey
Date: 2012-11-06 16:20:28 EST (Tue, 06 Nov 2012)
New Revision: 81228
URL: http://svn.boost.org/trac/boost/changeset/81228

Log:
simplify program to make it more robust
eliminate the requirement that test_log.xml exists
(but will be used if available)
Text files modified:
   trunk/tools/regression/src/library_status.cpp | 510 ++++++++++++++++-----------------------
   1 files changed, 208 insertions(+), 302 deletions(-)

Modified: trunk/tools/regression/src/library_status.cpp
==============================================================================
--- trunk/tools/regression/src/library_status.cpp (original)
+++ trunk/tools/regression/src/library_status.cpp 2012-11-06 16:20:28 EST (Tue, 06 Nov 2012)
@@ -24,15 +24,16 @@
 
 *******************************************************************************/
 
-#include "boost/filesystem/operations.hpp"
-#include "boost/filesystem/fstream.hpp"
+#include <boost/filesystem/operations.hpp>
+#include <boost/filesystem/fstream.hpp>
+#include <boost/foreach.hpp>
 
 namespace fs = boost::filesystem;
 
 #include "detail/tiny_xml.hpp"
 namespace xml = boost::tiny_xml;
 
-#include "boost/iterator/transform_iterator.hpp"
+#include <boost/iterator/transform_iterator.hpp>
 
 #include <cstdlib> // for abort, exit
 #include <string>
@@ -40,34 +41,30 @@
 #include <set>
 #include <utility> // for make_pair on STLPort
 #include <map>
-#include <algorithm>
+#include <algorithm> // max_element, find_if
 #include <iostream>
 #include <fstream>
 #include <ctime>
 #include <stdexcept>
 #include <cassert>
-#include <utility>
+#include <utility> // for pair
 
 using std::string;
 
 const string pass_msg( "Pass" );
 const string warn_msg( "<i>Warn</i>" );
 const string fail_msg( "<font color=\"#FF0000\"><i>Fail</i></font>" );
-const string note_msg( "<sup>*</sup>" );
 const string missing_residue_msg( "<i>Missing</i>" );
 
 const std::size_t max_compile_msg_size = 10000;
 
 namespace
 {
- fs::path boost_root; // boost-root complete path
     fs::path locate_root; // locate-root (AKA ALL_LOCATE_TARGET) complete path
     bool ignore_pass = false;
     bool no_warn = false;
     bool no_links = false;
 
- fs::directory_iterator end_itr;
-
     // transform pathname to something html can accept
     struct char_xlate {
         typedef char result_type;
@@ -91,12 +88,13 @@
 
     struct col_node {
         int rows, cols;
- bool has_leaf;
+ bool is_leaf;
+ typedef std::pair<const std::string, col_node> subcolumn;
         typedef std::map<std::string, col_node> subcolumns_t;
         subcolumns_t m_subcolumns;
         bool operator<(const col_node &cn) const;
         col_node() :
- has_leaf(false)
+ is_leaf(false)
         {}
         std::pair<int, int> get_spans();
     };
@@ -104,14 +102,16 @@
     std::pair<int, int> col_node::get_spans(){
         rows = 1;
         cols = 0;
- if(has_leaf){
+ if(is_leaf){
             cols = 1;
         }
         if(! m_subcolumns.empty()){
- subcolumns_t::iterator itr;
- for(itr = m_subcolumns.begin(); itr != m_subcolumns.end(); ++itr){
+ BOOST_FOREACH(
+ subcolumn & s,
+ m_subcolumns
+ ){
                 std::pair<int, int> spans;
- spans = itr->second.get_spans();
+ spans = s.second.get_spans();
                 rows = (std::max)(rows, spans.first);
                 cols += spans.second;
             }
@@ -121,86 +121,40 @@
     }
 
     void build_node_tree(const fs::path & dir_root, col_node & node){
- fs::path xml_file_path( dir_root / "test_log.xml" );
- if (fs::exists( xml_file_path ) )
- {
- node.has_leaf = true;
- }
- fs::directory_iterator itr(dir_root);
- while(itr != end_itr){
- if(fs::is_directory(*itr)){
+ bool has_directories = false;
+ bool has_files = false;
+ BOOST_FOREACH(
+ fs::directory_entry & d,
+ std::make_pair(
+ fs::directory_iterator(dir_root),
+ fs::directory_iterator()
+ )
+ ){
+ if(fs::is_directory(d)){
+ has_directories = true;
                 std::pair<col_node::subcolumns_t::iterator, bool> result
                     = node.m_subcolumns.insert(
- std::make_pair(itr->path().filename().string(), col_node())
+ std::make_pair(d.path().filename().string(), col_node())
                     );
- build_node_tree(*itr, result.first->second);
- }
- ++itr;
- }
+ build_node_tree(d, result.first->second);
+ }
+ else{
+ has_files = true;
+ }
+ }
+ if(has_directories && has_files)
+ throw std::string("invalid bin directory structure");
+ node.is_leaf = has_files;
     }
 
     fs::ofstream report;
     fs::ofstream links_file;
     string links_name;
 
- fs::path notes_path;
- string notes_html;
-
- fs::path notes_map_path;
- typedef std::multimap< string, string > notes_map; // key is test_name-toolset,
- // value is note bookmark
- notes_map notes;
-
     string specific_compiler; // if running on one toolset only
 
     const string empty_string;
 
- // build notes_bookmarks from notes HTML -----------------------------------//
-
- void build_notes_bookmarks()
- {
- if ( notes_map_path.empty() ) return;
- fs::ifstream notes_map_file( notes_map_path );
- if ( !notes_map_file )
- {
- std::cerr << "Could not open --notes-map input file: " << notes_map_path.string() << std::endl;
- std::exit( 1 );
- }
- string line;
- while( std::getline( notes_map_file, line ) )
- {
- string::size_type pos = 0;
- if ( (pos = line.find( ',', pos )) == string::npos ) continue;
- string key(line.substr( 0, pos ) );
- string bookmark( line.substr( pos+1 ) );
-
- // std::cout << "inserting \"" << key << "\",\"" << bookmark << "\"\n";
- notes.insert( notes_map::value_type( key, bookmark ) );
- }
- }
-
- // load_notes_html ---------------------------------------------------------//
-
- bool load_notes_html()
- {
- if ( notes_path.empty() ) return false;
- fs::ifstream notes_file( notes_path );
- if ( !notes_file )
- {
- std::cerr << "Could not open --notes input file: " << notes_path.string() << std::endl;
- std::exit( 1 );
- }
- string line;
- bool in_body( false );
- while( std::getline( notes_file, line ) )
- {
- if ( in_body && line.find( "</body>" ) != string::npos ) in_body = false;
- if ( in_body ) notes_html += line;
- else if ( line.find( "<body>" ) ) in_body = true;
- }
- return true;
- }
-
     // extract object library name from target directory string ----------------//
 
     string extract_object_library_name( const string & s )
@@ -213,30 +167,36 @@
         return t.substr( pos, t.find( "/", pos ) - pos );
     }
 
- // element_content ---------------------------------------------------------//
+ // find_element ------------------------------------------------------------//
 
- const string & element_content(
- const xml::element & root, const string & name )
- {
- const static string empty_string;
- xml::element_list::const_iterator itr;
- for ( itr = root.elements.begin();
- itr != root.elements.end() && (*itr)->name != name;
- ++itr ) {}
- return itr != root.elements.end() ? (*itr)->content : empty_string;
+ xml::element_list::const_iterator find_element(
+ const xml::element & root, const string & name
+ ){
+ struct element_equal {
+ const string & m_name;
+ element_equal(const string & name) :
+ m_name(name)
+ {}
+ bool operator()(const xml::element_ptr & xep) const {
+ return xep.get()->name == m_name;
+ }
+ };
+ return std::find_if(
+ root.elements.begin(),
+ root.elements.end(),
+ element_equal(name)
+ );
     }
 
- // find_element ------------------------------------------------------------//
-
- const xml::element & find_element(
- const xml::element & root, const string & name )
- {
- static const xml::element empty_element;
+ // element_content ---------------------------------------------------------//
+ const string & element_content(
+ const xml::element & root, const string & name
+ ){
         xml::element_list::const_iterator itr;
- for ( itr = root.elements.begin();
- itr != root.elements.end() && (*itr)->name != name;
- ++itr ) {}
- return itr != root.elements.end() ? *((*itr).get()) : empty_element;
+ itr = find_element(root, name);
+ if(root.elements.end() == itr)
+ return empty_string;
+ return (*itr)->content;
     }
 
     // attribute_value ----------------------------------------------------------//
@@ -245,17 +205,26 @@
         const xml::element & element,
         const string & attribute_name
     ){
- xml::attribute_list::const_iterator atr;
- for(
- atr = element.attributes.begin();
- atr != element.attributes.end();
- ++atr
- ){
- if(atr->name == attribute_name)
- return atr->value;
+ struct attribute_equal {
+ const string & m_name;
+ attribute_equal(const string & name) :
+ m_name(name)
+ {}
+ bool operator()(const xml::attribute & a) const {
+ return a.name == m_name;
+ }
+ };
+ xml::attribute_list::const_iterator itr;
+ itr = std::find_if(
+ element.attributes.begin(),
+ element.attributes.end(),
+ attribute_equal(attribute_name)
+ );
+ if(element.attributes.end() == itr){
+ static const string empty_string;
+ return empty_string;
         }
- static const string empty_string;
- return empty_string;
+ return itr->value;
     }
 
     // generate_report ---------------------------------------------------------//
@@ -398,36 +367,11 @@
         return result;
     }
 
- // add_notes --------------------------------------------------------------//
-
- void add_notes( const string & key, bool fail, string & sep, string & target )
- {
- notes_map::const_iterator itr = notes.lower_bound( key );
- if ( itr != notes.end() && itr->first == key )
- {
- for ( ; itr != notes.end() && itr->first == key; ++itr )
- {
- string note_desc( itr->second[0] == '-'
- ? itr->second.substr( 1 ) : itr->second );
- if ( fail || itr->second[0] == '-' )
- {
- target += sep;
- sep = ",";
- target += "<a href=\"";
- target += "#";
- target += note_desc;
- target += "\">";
- target += note_desc;
- target += "</a>";
- }
- }
- }
- }
-
     // do_cell ---------------------------------------------------------------//
     bool do_cell(
         const fs::path & target_dir,
         const string & lib_name,
+ const string & test_name,
         string & target,
         bool profile
     ){
@@ -437,36 +381,28 @@
         fs::path xml_file_path( target_dir / "test_log.xml" );
         if ( !fs::exists( xml_file_path ) )
         {
- // suppress message because there are too many of them.
- // "missing" is a legitmate result as its not a requirement
- // that every test be run in every figuration.
- //std::cerr << "Missing jam_log.xml in target:\n "
- // << target_dir.string() << "\n";
- target += "<td align=\"right\">" + missing_residue_msg + "</td>";
+ fs::path test_path = target_dir / (test_name + ".test");
+ target += "<td align=\"right\">";
+ target += fs::exists( test_path) ? pass_msg : fail_msg;
+ target += "</td>";
             return true;
         }
 
         int anything_generated = 0;
- bool note = false;
 
- fs::ifstream file( xml_file_path );
- if ( !file ) // could not open jam_log.xml
- {
- std::cerr << "Can't open jam_log.xml in target:\n "
- << target_dir.string() << "\n";
- target += "<td>" + missing_residue_msg + "</td>";
- return false;
- }
 
         string test_type( "unknown" );
         bool always_show_run_output( false );
 
+ fs::ifstream file( xml_file_path );
         xml::element_ptr dbp = xml::parse( file, xml_file_path.string() );
         const xml::element & db( *dbp );
- test_type = attribute_value( db, "test-type" );
+
         always_show_run_output
             = attribute_value( db, "show-run-output" ) == "true";
 
+ /*
+ test_type = attribute_value( db, "test-type" );
         std::string test_type_base( test_type );
         if ( test_type_base.size() > 5 )
         {
@@ -484,14 +420,15 @@
                 test_type_base.erase( trailer );
             }
         }
- const xml::element & test_type_element( find_element( db, test_type_base ) );
-
- pass = !test_type_element.name.empty()
- && attribute_value( test_type_element, "result" ) != "fail";
+
+ xml::element_list::const_iterator itr;
+ itr = find_element( db, test_type_base );
+ if(db.elements.end() == itr)
+ return pass;
+ */
+ pass = (attribute_value( db, "result" ) != "fail");
 
         if (!no_links){
- if(!test_type_element.name.empty())
- note = attribute_value( test_type_element, "result" ) == "note";
             anything_generated =
                 generate_report(
                 db,
@@ -499,7 +436,7 @@
                 test_type,
                 target_dir,
                 pass,
- always_show_run_output || note
+ always_show_run_output
             );
         }
 
@@ -521,7 +458,6 @@
                 ? (anything_generated < 2 ? pass_msg : warn_msg)
                 : fail_msg;
             target += "</a>";
- if ( pass && note ) target += note_msg;
         }
         else target += pass ? pass_msg : fail_msg;
 
@@ -532,11 +468,6 @@
             target += (target_dir / "profile.txt").string();
             target += "\"><i>Profile</i></a>";
         }
-
- // if notes, generate the superscript HTML
-// if ( !notes.empty() )
-// target += get_notes( toolset, lib_name, test_name, !pass );
-
         target += "</td>";
         return (anything_generated != 0) || !pass;
     }
@@ -545,32 +476,32 @@
         const col_node & node,
         fs::path dir_root,
         const string & lib_name,
+ const string & test_name,
         string & target,
         bool profile
     ){
         bool retval = false;
- if(node.has_leaf){
+ if(node.is_leaf){
             retval = do_cell(
                 dir_root,
                 lib_name,
+ test_name,
                 target,
                 profile
             );
         }
-
- col_node::subcolumns_t::const_iterator col_itr;
- for(
- col_itr = node.m_subcolumns.begin();
- col_itr != node.m_subcolumns.end();
- ++col_itr
+ BOOST_FOREACH(
+ const col_node::subcolumn & s,
+ node.m_subcolumns
         ){
- fs::path subdir = dir_root / col_itr->first;
+ fs::path subdir = dir_root / s.first;
             retval |= visit_node_tree(
- col_itr->second,
+ s.second,
                 subdir,
                 lib_name,
+ test_name,
                 target,
- col_itr->first == "profile"
+ s.first == "profile"
             );
         }
         return retval;
@@ -594,17 +525,14 @@
         //target += "</a>";
         target += "</td>";
 
-// target += "<td>" + test_type + "</td>";
-
         bool no_warn_save = no_warn;
 
-// if ( test_type.find( "fail" ) != string::npos ) no_warn = true;
-
         // emit cells on this row
         bool anything_to_report = visit_node_tree(
             test_node,
             test_dir,
             lib_name,
+ test_name,
             target,
             false
         );
@@ -628,25 +556,26 @@
         // rows are held in a vector so they can be sorted, if desired.
         std::vector<string> results;
 
- for ( fs::directory_iterator itr( test_lib_dir ); itr != end_itr; ++itr )
- {
- if(! fs::is_directory(*itr))
+ BOOST_FOREACH(
+ fs::directory_entry & d,
+ std::make_pair(
+ fs::directory_iterator(test_lib_dir),
+ fs::directory_iterator()
+ )
+ ){
+ if(! fs::is_directory(d))
                 continue;
-
- string test_name = itr->path().filename().string();
+
             // if the file name contains ".test"
- string::size_type s = test_name.find( ".test" );
- if(string::npos != s)
- // strip it off
- test_name.resize(s);
- else
- // if it doesn't - skip this directory
+ if(d.path().extension() != ".test")
                 continue;
 
+ string test_name = d.path().stem().string();
+
             results.push_back( std::string() );
             do_row(
                 root_node, //*test_node_itr++,
- *itr, // test dir
+ d, // test dir
                 lib_name,
                 test_name,
                 results[results.size()-1]
@@ -655,21 +584,18 @@
 
         std::sort( results.begin(), results.end() );
 
- for (
- std::vector<string>::iterator v(results.begin());
- v != results.end();
- ++v
- ){
- report << *v << "\n";
- }
+ BOOST_FOREACH(string &s, results)
+ report << s << "\n";
     }
 
     // column header-----------------------------------------------------------//
     int header_depth(const col_node & root){
- col_node::subcolumns_t::const_iterator itr;
         int max_depth = 1;
- for(itr = root.m_subcolumns.begin(); itr != root.m_subcolumns.end(); ++itr){
- max_depth = (std::max)(max_depth, itr->second.rows);
+ BOOST_FOREACH(
+ const col_node::subcolumn &s,
+ root.m_subcolumns
+ ){
+ max_depth = (std::max)(max_depth, s.second.rows);
         }
         return max_depth;
     }
@@ -695,23 +621,30 @@
     ){
         if(current_row < display_row){
             if(! node.m_subcolumns.empty()){
- col_node::subcolumns_t::const_iterator itr;
- for(itr = node.m_subcolumns.begin(); itr != node.m_subcolumns.end(); ++itr){
- emit_column_headers(itr->second, display_row, current_row + 1, row_count);
+ BOOST_FOREACH(
+ const col_node::subcolumn &s,
+ node.m_subcolumns
+ ){
+ emit_column_headers(
+ s.second,
+ display_row,
+ current_row + 1,
+ row_count
+ );
                 }
             }
             return;
         }
- if(node.has_leaf && ! node.m_subcolumns.empty()){
+ /*
+ if(node.is_leaf && ! node.m_subcolumns.empty()){
             header_cell(row_count - current_row, 1, std::string(""));
         }
-
- col_node::subcolumns_t::const_iterator itr;
- for(itr = node.m_subcolumns.begin(); itr != node.m_subcolumns.end(); ++itr){
- if(1 == itr->second.rows)
- header_cell(row_count - current_row, itr->second.cols, itr->first);
+ */
+ BOOST_FOREACH(col_node::subcolumn s, node.m_subcolumns){
+ if(1 == s.second.rows)
+ header_cell(row_count - current_row, s.second.cols, s.first);
             else
- header_cell(1, itr->second.cols, itr->first);
+ header_cell(1, s.second.cols, s.first);
         }
     }
 
@@ -719,9 +652,8 @@
         // walk up from the path were we started until we find
         // bin or bin.v2
 
- fs::path::const_iterator it = initial_path.end(), end = initial_path.end();
         fs::path test_lib_dir = initial_path;
- for(;;){
+ do{
             if(fs::is_directory( test_lib_dir / "bin.v2")){
                 test_lib_dir /= "bin.v2";
                 break;
@@ -729,44 +661,47 @@
             if(fs::is_directory( test_lib_dir / "bin")){
                 // v1 includes the word boost
                 test_lib_dir /= "bin";
- test_lib_dir /= "boost";
+ if(fs::is_directory( test_lib_dir / "boost")){
+ test_lib_dir /= "boost";
+ }
                 break;
             }
- if(test_lib_dir.empty())
- throw std::string("binary path not found");
- if(*it != "libs")
- --it;
- test_lib_dir.remove_filename();
- }
-
- if(it == end)
- throw std::string("must be run from within a library directory");
+ }while(! test_lib_dir.empty());
 
+ if(test_lib_dir.empty())
+ throw std::string("binary path not found");
 
- for(;it != end; ++it){
- test_lib_dir /= *it; // append "libs"
- }
         return test_lib_dir;
     }
 
- // note : uncomment the #if/#endif and what this compile !!!
     string find_lib_name(fs::path lib_test_dir){
- unsigned int count;
+ // search the path backwards for the magic name "libs"
         fs::path::iterator e_itr = lib_test_dir.end();
- for(count = 0;; ++count){
+ while(lib_test_dir.begin() != e_itr){
             if(*--e_itr == "libs")
                 break;
- if(lib_test_dir.empty())
- throw std::string("must be run from within a library directory");
         }
- string library_name;
- for(;;){
- library_name.append((*++e_itr).string());
- if(1 == --count)
- break;
- library_name.append("/");
+
+ // if its found
+ if(lib_test_dir.begin() != e_itr){
+ // use the whole path since the "libs"
+ ++e_itr;
+ }
+ // otherwise, just use the last two components
+ else{
+ e_itr = lib_test_dir.end();
+ if(e_itr != lib_test_dir.begin()){
+ if(--e_itr != lib_test_dir.begin()){
+ --e_itr;
+ }
+ }
         }
- return library_name;
+
+ fs::path library_name;
+ while(lib_test_dir.end() != e_itr){
+ library_name /= *e_itr++;
+ }
+ return library_name.string();
     }
 
     fs::path find_boost_root(fs::path initial_path){
@@ -784,19 +719,25 @@
     }
 
     // do_table ----------------------------------------------------------------//
- void do_table(fs::path const& initial_path, const string & lib_name)
+ void do_table(const fs::path & lib_test_dir, const string & lib_name)
     {
         col_node root_node;
 
- fs::path lib_test_dir = find_lib_test_dir(initial_path);
-
- for ( fs::directory_iterator itr(lib_test_dir); itr != end_itr; ++itr )
- {
- if(! fs::is_directory(*itr))
+ BOOST_FOREACH(
+ fs::directory_entry & d,
+ std::make_pair(
+ fs::directory_iterator(lib_test_dir),
+ fs::directory_iterator()
+ )
+ ){
+ if(! fs::is_directory(d))
                 continue;
- build_node_tree(*itr, root_node);
+ fs::path p = d.path();
+ if(p.extension() != ".test")
+ continue;
+ build_node_tree(d, root_node);
         }
-
+
         // visit directory nodes and record nodetree
         report << "<table border=\"1\" cellspacing=\"0\" cellpadding=\"5\">\n";
 
@@ -832,21 +773,12 @@
 {
     fs::path initial_path = fs::initial_path();
 
- fs::path comment_path;
     while ( argc > 1 && *argv[1] == '-' )
     {
         if ( argc > 2 && std::strcmp( argv[1], "--compiler" ) == 0 )
         { specific_compiler = argv[2]; --argc; ++argv; }
         else if ( argc > 2 && std::strcmp( argv[1], "--locate-root" ) == 0 )
         { locate_root = fs::path( argv[2] ); --argc; ++argv; }
- else if ( argc > 2 && std::strcmp( argv[1], "--boost-root" ) == 0 )
- { boost_root = fs::path( argv[2] ); --argc; ++argv; }
- else if ( argc > 2 && std::strcmp( argv[1], "--comment" ) == 0 )
- { comment_path = fs::path( argv[2] ); --argc; ++argv; }
- else if ( argc > 2 && std::strcmp( argv[1], "--notes" ) == 0 )
- { notes_path = fs::path( argv[2] ); --argc; ++argv; }
- else if ( argc > 2 && std::strcmp( argv[1], "--notes-map" ) == 0 )
- { notes_map_path = fs::path( argv[2] ); --argc; ++argv; }
         else if ( std::strcmp( argv[1], "--ignore-pass" ) == 0 ) ignore_pass = true;
         else if ( std::strcmp( argv[1], "--no-warn" ) == 0 ) no_warn = true;
         else if ( std::strcmp( argv[1], "--v2" ) == 0 )
@@ -867,27 +799,19 @@
             " options: --compiler name Run for named compiler only\n"
             " --ignore-pass Do not report tests which pass all compilers\n"
             " --no-warn Warnings not reported if test passes\n"
- " --boost-root path default derived from current path.\n"
             " --locate-root path Path to ALL_LOCATE_TARGET for bjam;\n"
             " default boost-root.\n"
- " --comment path Path to file containing HTML\n"
- " to be copied into status-file.\n"
- " --notes path Path to file containing HTML\n"
- " to be copied into status-file.\n"
- " --notes-map path Path to file of toolset/test,n lines, where\n"
- " n is number of note bookmark in --notes file.\n"
- "Example: compiler_status --compiler gcc /boost-root cs.html cs-links.html\n"
- "Note: Only the leaf of the links-file path and --notes file string are\n"
+ "Example: library_status --compiler gcc /boost-root cs.html cs-links.html\n"
+ "Note: Only the leaf of the links-file path is\n"
             "used in status-file HTML links. Thus for browsing, status-file,\n"
- "links-file, and --notes file must all be in the same directory.\n"
+ "links-file must be in the same directory.\n"
             ;
         return 1;
     }
 
- if(boost_root.empty())
- boost_root = find_boost_root(initial_path);
- if ( locate_root.empty() )
- locate_root = boost_root;
+ if(locate_root.empty())
+ if(! fs::exists("bin") && ! fs::exists("bin.v2"))
+ locate_root = find_boost_root(initial_path);
 
     report.open( fs::path( argv[1] ) );
     if ( !report )
@@ -909,8 +833,6 @@
     }
     else no_links = true;
 
- build_notes_bookmarks();
-
     const string library_name = find_lib_name(initial_path);
 
     char run_date[128];
@@ -926,31 +848,12 @@
         << "</head>\n"
         << "<body bgcolor=\"#ffffff\" text=\"#000000\">\n"
         << "<table border=\"0\">\n"
- << "<tr>\n"
- << "<td><img border=\"0\" "
- << "src=\""
- << boost_root / "boost.png"
- << "\" width=\"277\" "
- << "height=\"86\"></td>\n"
- << "<td>\n"
         << "<h1>Library Status: " + library_name + "</h1>\n"
         << "<b>Run Date:</b> "
         << run_date
- << "\n"
+ << "\n<br>"
         ;
 
- if ( !comment_path.empty() )
- {
- fs::ifstream comment_file( comment_path );
- if ( !comment_file )
- {
- std::cerr << "Could not open \"--comment\" input file: " << comment_path.string() << std::endl;
- return 1;
- }
- char c;
- while ( comment_file.get( c ) ) { report.put( c ); }
- }
-
     report << "</td>\n</table>\n<br>\n";
 
     if ( !no_links )
@@ -962,22 +865,25 @@
             << "</head>\n"
             << "<body bgcolor=\"#ffffff\" text=\"#000000\">\n"
             << "<table border=\"0\">\n"
- << "<tr>\n"
- << "<td><img border=\"0\" src=\""
- << boost_root / "boost.png"
- << "\" width=\"277\" "
- << "height=\"86\"></td>\n"
- << "<td>\n"
             << "<h1>Library Status: " + library_name + "</h1>\n"
             << "<b>Run Date:</b> "
             << run_date
- << "\n</td>\n</table>\n<br>\n"
+ << "\n<br></table>\n<br>\n"
             ;
     }
 
- do_table(initial_path, library_name);
+ // detect whether in a a directory which looks like
+ // bin/<library name>/test
+ // or just
+ // bin
+ fs::path library_test_directory = find_lib_test_dir(locate_root);
+ // if libs exists, drop down a couple of levels
+ if(fs::is_directory( library_test_directory / "libs")){
+ library_test_directory /= "libs";
+ library_test_directory /= library_name;
+ }
 
- if ( load_notes_html() ) report << notes_html << "\n";
+ do_table(library_test_directory, library_name);
 
     report << "</body>\n"
         "</html>\n"


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