|
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