|
@@ -1,5 +1,6 @@
|
|
|
// Generate Library Status HTML from jam regression test output -----------//
|
|
// Generate Library Status HTML from jam regression test output -----------//
|
|
|
|
|
|
|
|
|
|
+// Copyright Robert Ramey 2012
|
|
|
// Copyright Bryce Lelbach 2011
|
|
// Copyright Bryce Lelbach 2011
|
|
|
// Copyright Beman Dawes 2002-2011.
|
|
// Copyright Beman Dawes 2002-2011.
|
|
|
|
|
|
|
@@ -24,15 +25,16 @@ program maintenance.
|
|
|
|
|
|
|
|
*******************************************************************************/
|
|
*******************************************************************************/
|
|
|
|
|
|
|
|
-#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;
|
|
namespace fs = boost::filesystem;
|
|
|
|
|
|
|
|
#include "detail/tiny_xml.hpp"
|
|
#include "detail/tiny_xml.hpp"
|
|
|
namespace xml = boost::tiny_xml;
|
|
namespace xml = boost::tiny_xml;
|
|
|
|
|
|
|
|
-#include "boost/iterator/transform_iterator.hpp"
|
|
|
|
|
|
|
+#include <boost/iterator/transform_iterator.hpp>
|
|
|
|
|
|
|
|
#include <cstdlib> // for abort, exit
|
|
#include <cstdlib> // for abort, exit
|
|
|
#include <string>
|
|
#include <string>
|
|
@@ -40,39 +42,35 @@ namespace xml = boost::tiny_xml;
|
|
|
#include <set>
|
|
#include <set>
|
|
|
#include <utility> // for make_pair on STLPort
|
|
#include <utility> // for make_pair on STLPort
|
|
|
#include <map>
|
|
#include <map>
|
|
|
-#include <algorithm>
|
|
|
|
|
|
|
+#include <algorithm> // max_element, find_if
|
|
|
#include <iostream>
|
|
#include <iostream>
|
|
|
#include <fstream>
|
|
#include <fstream>
|
|
|
#include <ctime>
|
|
#include <ctime>
|
|
|
#include <stdexcept>
|
|
#include <stdexcept>
|
|
|
#include <cassert>
|
|
#include <cassert>
|
|
|
-#include <utility>
|
|
|
|
|
|
|
+#include <utility> // for pair
|
|
|
|
|
|
|
|
using std::string;
|
|
using std::string;
|
|
|
|
|
|
|
|
const string pass_msg( "Pass" );
|
|
const string pass_msg( "Pass" );
|
|
|
const string warn_msg( "<i>Warn</i>" );
|
|
const string warn_msg( "<i>Warn</i>" );
|
|
|
const string fail_msg( "<font color=\"#FF0000\"><i>Fail</i></font>" );
|
|
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 string missing_residue_msg( "<i>Missing</i>" );
|
|
|
|
|
|
|
|
const std::size_t max_compile_msg_size = 10000;
|
|
const std::size_t max_compile_msg_size = 10000;
|
|
|
|
|
|
|
|
namespace
|
|
namespace
|
|
|
{
|
|
{
|
|
|
- fs::path boost_root; // boost-root complete path
|
|
|
|
|
fs::path locate_root; // locate-root (AKA ALL_LOCATE_TARGET) complete path
|
|
fs::path locate_root; // locate-root (AKA ALL_LOCATE_TARGET) complete path
|
|
|
bool ignore_pass = false;
|
|
bool ignore_pass = false;
|
|
|
bool no_warn = false;
|
|
bool no_warn = false;
|
|
|
bool no_links = false;
|
|
bool no_links = false;
|
|
|
|
|
|
|
|
- fs::directory_iterator end_itr;
|
|
|
|
|
-
|
|
|
|
|
// transform pathname to something html can accept
|
|
// transform pathname to something html can accept
|
|
|
struct char_xlate {
|
|
struct char_xlate {
|
|
|
typedef char result_type;
|
|
typedef char result_type;
|
|
|
result_type operator()(char c) const{
|
|
result_type operator()(char c) const{
|
|
|
- if(c == '/')
|
|
|
|
|
|
|
+ if(c == '/' || c == '\\')
|
|
|
return '-';
|
|
return '-';
|
|
|
return c;
|
|
return c;
|
|
|
}
|
|
}
|
|
@@ -91,12 +89,13 @@ namespace
|
|
|
|
|
|
|
|
struct col_node {
|
|
struct col_node {
|
|
|
int rows, cols;
|
|
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;
|
|
typedef std::map<std::string, col_node> subcolumns_t;
|
|
|
subcolumns_t m_subcolumns;
|
|
subcolumns_t m_subcolumns;
|
|
|
bool operator<(const col_node &cn) const;
|
|
bool operator<(const col_node &cn) const;
|
|
|
col_node() :
|
|
col_node() :
|
|
|
- has_leaf(false)
|
|
|
|
|
|
|
+ is_leaf(false)
|
|
|
{}
|
|
{}
|
|
|
std::pair<int, int> get_spans();
|
|
std::pair<int, int> get_spans();
|
|
|
};
|
|
};
|
|
@@ -104,14 +103,16 @@ namespace
|
|
|
std::pair<int, int> col_node::get_spans(){
|
|
std::pair<int, int> col_node::get_spans(){
|
|
|
rows = 1;
|
|
rows = 1;
|
|
|
cols = 0;
|
|
cols = 0;
|
|
|
- if(has_leaf){
|
|
|
|
|
|
|
+ if(is_leaf){
|
|
|
cols = 1;
|
|
cols = 1;
|
|
|
}
|
|
}
|
|
|
if(! m_subcolumns.empty()){
|
|
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;
|
|
std::pair<int, int> spans;
|
|
|
- spans = itr->second.get_spans();
|
|
|
|
|
|
|
+ spans = s.second.get_spans();
|
|
|
rows = (std::max)(rows, spans.first);
|
|
rows = (std::max)(rows, spans.first);
|
|
|
cols += spans.second;
|
|
cols += spans.second;
|
|
|
}
|
|
}
|
|
@@ -121,86 +122,40 @@ namespace
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
void build_node_tree(const fs::path & dir_root, col_node & node){
|
|
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
|
|
std::pair<col_node::subcolumns_t::iterator, bool> result
|
|
|
= node.m_subcolumns.insert(
|
|
= node.m_subcolumns.insert(
|
|
|
- std::make_pair(itr->path().native(), 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 report;
|
|
|
fs::ofstream links_file;
|
|
fs::ofstream links_file;
|
|
|
string links_name;
|
|
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
|
|
string specific_compiler; // if running on one toolset only
|
|
|
|
|
|
|
|
const string empty_string;
|
|
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 ----------------//
|
|
// extract object library name from target directory string ----------------//
|
|
|
|
|
|
|
|
string extract_object_library_name( const string & s )
|
|
string extract_object_library_name( const string & s )
|
|
@@ -213,30 +168,36 @@ namespace
|
|
|
return t.substr( pos, t.find( "/", pos ) - pos );
|
|
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;
|
|
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 ----------------------------------------------------------//
|
|
// attribute_value ----------------------------------------------------------//
|
|
@@ -245,17 +206,26 @@ namespace
|
|
|
const xml::element & element,
|
|
const xml::element & element,
|
|
|
const string & attribute_name
|
|
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 ---------------------------------------------------------//
|
|
// generate_report ---------------------------------------------------------//
|
|
@@ -303,15 +273,17 @@ namespace
|
|
|
compile += "...\n (remainder deleted because of excessive size)\n";
|
|
compile += "...\n (remainder deleted because of excessive size)\n";
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
+ const string target_dir_string = target_dir.string();
|
|
|
|
|
+
|
|
|
links_file << "<h2><a name=\"";
|
|
links_file << "<h2><a name=\"";
|
|
|
links_file << std::make_pair(
|
|
links_file << std::make_pair(
|
|
|
- html_from_path(target_dir.string().begin()),
|
|
|
|
|
- html_from_path(target_dir.string().end())
|
|
|
|
|
|
|
+ html_from_path(target_dir_string.begin()),
|
|
|
|
|
+ html_from_path(target_dir_string.end())
|
|
|
)
|
|
)
|
|
|
<< "\">"
|
|
<< "\">"
|
|
|
<< std::make_pair(
|
|
<< std::make_pair(
|
|
|
- html_from_path(target_dir.string().begin()),
|
|
|
|
|
- html_from_path(target_dir.string().end())
|
|
|
|
|
|
|
+ html_from_path(target_dir_string.begin()),
|
|
|
|
|
+ html_from_path(target_dir_string.end())
|
|
|
)
|
|
)
|
|
|
;
|
|
;
|
|
|
links_file << "</a></h2>\n";;
|
|
links_file << "</a></h2>\n";;
|
|
@@ -347,14 +319,14 @@ namespace
|
|
|
<< source_library_name << "-"
|
|
<< source_library_name << "-"
|
|
|
<< object_library_name << "-"
|
|
<< object_library_name << "-"
|
|
|
<< std::make_pair(
|
|
<< std::make_pair(
|
|
|
- html_from_path(target_dir.string().begin()),
|
|
|
|
|
- html_from_path(target_dir.string().end())
|
|
|
|
|
|
|
+ html_from_path(target_dir_string.begin()),
|
|
|
|
|
+ html_from_path(target_dir_string.end())
|
|
|
)
|
|
)
|
|
|
<< source_library_name << " - "
|
|
<< source_library_name << " - "
|
|
|
<< object_library_name << " - "
|
|
<< object_library_name << " - "
|
|
|
<< std::make_pair(
|
|
<< std::make_pair(
|
|
|
- html_from_path(target_dir.string().begin()),
|
|
|
|
|
- html_from_path(target_dir.string().end())
|
|
|
|
|
|
|
+ html_from_path(target_dir_string.begin()),
|
|
|
|
|
+ html_from_path(target_dir_string.end())
|
|
|
)
|
|
)
|
|
|
<< "</a>";
|
|
<< "</a>";
|
|
|
if ( failed_lib_target_dirs.find( lib ) == failed_lib_target_dirs.end() )
|
|
if ( failed_lib_target_dirs.find( lib ) == failed_lib_target_dirs.end() )
|
|
@@ -379,14 +351,14 @@ namespace
|
|
|
links_file << "<h2><a name=\""
|
|
links_file << "<h2><a name=\""
|
|
|
<< object_library_name << "-"
|
|
<< object_library_name << "-"
|
|
|
<< std::make_pair(
|
|
<< std::make_pair(
|
|
|
- html_from_path(target_dir.string().begin()),
|
|
|
|
|
- html_from_path(target_dir.string().end())
|
|
|
|
|
|
|
+ html_from_path(target_dir_string.begin()),
|
|
|
|
|
+ html_from_path(target_dir_string.end())
|
|
|
)
|
|
)
|
|
|
<< "\">"
|
|
<< "\">"
|
|
|
<< object_library_name << " - "
|
|
<< object_library_name << " - "
|
|
|
<< std::make_pair(
|
|
<< std::make_pair(
|
|
|
- html_from_path(target_dir.string().begin()),
|
|
|
|
|
- html_from_path(target_dir.string().end())
|
|
|
|
|
|
|
+ html_from_path(target_dir_string.begin()),
|
|
|
|
|
+ html_from_path(target_dir_string.end())
|
|
|
)
|
|
)
|
|
|
<< "</a></h2>\n"
|
|
<< "</a></h2>\n"
|
|
|
<< "test_log.xml not found\n";
|
|
<< "test_log.xml not found\n";
|
|
@@ -396,36 +368,11 @@ namespace
|
|
|
return result;
|
|
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 ---------------------------------------------------------------//
|
|
// do_cell ---------------------------------------------------------------//
|
|
|
bool do_cell(
|
|
bool do_cell(
|
|
|
const fs::path & target_dir,
|
|
const fs::path & target_dir,
|
|
|
const string & lib_name,
|
|
const string & lib_name,
|
|
|
|
|
+ const string & test_name,
|
|
|
string & target,
|
|
string & target,
|
|
|
bool profile
|
|
bool profile
|
|
|
){
|
|
){
|
|
@@ -435,36 +382,28 @@ namespace
|
|
|
fs::path xml_file_path( target_dir / "test_log.xml" );
|
|
fs::path xml_file_path( target_dir / "test_log.xml" );
|
|
|
if ( !fs::exists( xml_file_path ) )
|
|
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;
|
|
return true;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
int anything_generated = 0;
|
|
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" );
|
|
string test_type( "unknown" );
|
|
|
bool always_show_run_output( false );
|
|
bool always_show_run_output( false );
|
|
|
|
|
|
|
|
|
|
+ fs::ifstream file( xml_file_path );
|
|
|
xml::element_ptr dbp = xml::parse( file, xml_file_path.string() );
|
|
xml::element_ptr dbp = xml::parse( file, xml_file_path.string() );
|
|
|
const xml::element & db( *dbp );
|
|
const xml::element & db( *dbp );
|
|
|
- test_type = attribute_value( db, "test-type" );
|
|
|
|
|
|
|
+
|
|
|
always_show_run_output
|
|
always_show_run_output
|
|
|
= attribute_value( db, "show-run-output" ) == "true";
|
|
= attribute_value( db, "show-run-output" ) == "true";
|
|
|
|
|
|
|
|
|
|
+ /*
|
|
|
|
|
+ test_type = attribute_value( db, "test-type" );
|
|
|
std::string test_type_base( test_type );
|
|
std::string test_type_base( test_type );
|
|
|
if ( test_type_base.size() > 5 )
|
|
if ( test_type_base.size() > 5 )
|
|
|
{
|
|
{
|
|
@@ -482,14 +421,15 @@ namespace
|
|
|
test_type_base.erase( trailer );
|
|
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 (!no_links){
|
|
|
- if(!test_type_element.name.empty())
|
|
|
|
|
- note = attribute_value( test_type_element, "result" ) == "note";
|
|
|
|
|
anything_generated =
|
|
anything_generated =
|
|
|
generate_report(
|
|
generate_report(
|
|
|
db,
|
|
db,
|
|
@@ -497,7 +437,7 @@ namespace
|
|
|
test_type,
|
|
test_type,
|
|
|
target_dir,
|
|
target_dir,
|
|
|
pass,
|
|
pass,
|
|
|
- always_show_run_output || note
|
|
|
|
|
|
|
+ always_show_run_output
|
|
|
);
|
|
);
|
|
|
}
|
|
}
|
|
|
|
|
|
|
@@ -508,9 +448,10 @@ namespace
|
|
|
target += "<a href=\"";
|
|
target += "<a href=\"";
|
|
|
target += links_name;
|
|
target += links_name;
|
|
|
target += "#";
|
|
target += "#";
|
|
|
|
|
+ const string target_dir_string = target_dir.string();
|
|
|
std::copy(
|
|
std::copy(
|
|
|
- html_from_path(target_dir.string().begin()),
|
|
|
|
|
- html_from_path(target_dir.string().end()),
|
|
|
|
|
|
|
+ html_from_path(target_dir_string.begin()),
|
|
|
|
|
+ html_from_path(target_dir_string.end()),
|
|
|
std::back_inserter(target)
|
|
std::back_inserter(target)
|
|
|
);
|
|
);
|
|
|
target += "\">";
|
|
target += "\">";
|
|
@@ -518,7 +459,6 @@ namespace
|
|
|
? (anything_generated < 2 ? pass_msg : warn_msg)
|
|
? (anything_generated < 2 ? pass_msg : warn_msg)
|
|
|
: fail_msg;
|
|
: fail_msg;
|
|
|
target += "</a>";
|
|
target += "</a>";
|
|
|
- if ( pass && note ) target += note_msg;
|
|
|
|
|
}
|
|
}
|
|
|
else target += pass ? pass_msg : fail_msg;
|
|
else target += pass ? pass_msg : fail_msg;
|
|
|
|
|
|
|
@@ -529,11 +469,6 @@ namespace
|
|
|
target += (target_dir / "profile.txt").string();
|
|
target += (target_dir / "profile.txt").string();
|
|
|
target += "\"><i>Profile</i></a>";
|
|
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>";
|
|
target += "</td>";
|
|
|
return (anything_generated != 0) || !pass;
|
|
return (anything_generated != 0) || !pass;
|
|
|
}
|
|
}
|
|
@@ -542,32 +477,32 @@ namespace
|
|
|
const col_node & node,
|
|
const col_node & node,
|
|
|
fs::path dir_root,
|
|
fs::path dir_root,
|
|
|
const string & lib_name,
|
|
const string & lib_name,
|
|
|
|
|
+ const string & test_name,
|
|
|
string & target,
|
|
string & target,
|
|
|
bool profile
|
|
bool profile
|
|
|
){
|
|
){
|
|
|
bool retval = false;
|
|
bool retval = false;
|
|
|
- if(node.has_leaf){
|
|
|
|
|
|
|
+ if(node.is_leaf){
|
|
|
retval = do_cell(
|
|
retval = do_cell(
|
|
|
dir_root,
|
|
dir_root,
|
|
|
lib_name,
|
|
lib_name,
|
|
|
|
|
+ test_name,
|
|
|
target,
|
|
target,
|
|
|
profile
|
|
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(
|
|
retval |= visit_node_tree(
|
|
|
- col_itr->second,
|
|
|
|
|
|
|
+ s.second,
|
|
|
subdir,
|
|
subdir,
|
|
|
lib_name,
|
|
lib_name,
|
|
|
|
|
+ test_name,
|
|
|
target,
|
|
target,
|
|
|
- col_itr->first == "profile"
|
|
|
|
|
|
|
+ s.first == "profile"
|
|
|
);
|
|
);
|
|
|
}
|
|
}
|
|
|
return retval;
|
|
return retval;
|
|
@@ -588,20 +523,17 @@ namespace
|
|
|
target += "<td>";
|
|
target += "<td>";
|
|
|
//target += "<a href=\"" + url_prefix_dir_view + "/libs/" + lib_name + "\">";
|
|
//target += "<a href=\"" + url_prefix_dir_view + "/libs/" + lib_name + "\">";
|
|
|
target += test_name;
|
|
target += test_name;
|
|
|
- target += "</a>";
|
|
|
|
|
|
|
+ //target += "</a>";
|
|
|
target += "</td>";
|
|
target += "</td>";
|
|
|
|
|
|
|
|
-// target += "<td>" + test_type + "</td>";
|
|
|
|
|
-
|
|
|
|
|
bool no_warn_save = no_warn;
|
|
bool no_warn_save = no_warn;
|
|
|
|
|
|
|
|
-// if ( test_type.find( "fail" ) != string::npos ) no_warn = true;
|
|
|
|
|
-
|
|
|
|
|
// emit cells on this row
|
|
// emit cells on this row
|
|
|
bool anything_to_report = visit_node_tree(
|
|
bool anything_to_report = visit_node_tree(
|
|
|
test_node,
|
|
test_node,
|
|
|
test_dir,
|
|
test_dir,
|
|
|
lib_name,
|
|
lib_name,
|
|
|
|
|
+ test_name,
|
|
|
target,
|
|
target,
|
|
|
false
|
|
false
|
|
|
);
|
|
);
|
|
@@ -625,25 +557,26 @@ namespace
|
|
|
// rows are held in a vector so they can be sorted, if desired.
|
|
// rows are held in a vector so they can be sorted, if desired.
|
|
|
std::vector<string> results;
|
|
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;
|
|
continue;
|
|
|
-
|
|
|
|
|
- string test_name = itr->path().native();
|
|
|
|
|
|
|
+
|
|
|
// if the file name contains ".test"
|
|
// 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;
|
|
continue;
|
|
|
|
|
|
|
|
|
|
+ string test_name = d.path().stem().string();
|
|
|
|
|
+
|
|
|
results.push_back( std::string() );
|
|
results.push_back( std::string() );
|
|
|
do_row(
|
|
do_row(
|
|
|
root_node, //*test_node_itr++,
|
|
root_node, //*test_node_itr++,
|
|
|
- *itr, // test dir
|
|
|
|
|
|
|
+ d, // test dir
|
|
|
lib_name,
|
|
lib_name,
|
|
|
test_name,
|
|
test_name,
|
|
|
results[results.size()-1]
|
|
results[results.size()-1]
|
|
@@ -652,21 +585,18 @@ namespace
|
|
|
|
|
|
|
|
std::sort( results.begin(), results.end() );
|
|
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-----------------------------------------------------------//
|
|
// column header-----------------------------------------------------------//
|
|
|
int header_depth(const col_node & root){
|
|
int header_depth(const col_node & root){
|
|
|
- col_node::subcolumns_t::const_iterator itr;
|
|
|
|
|
int max_depth = 1;
|
|
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;
|
|
return max_depth;
|
|
|
}
|
|
}
|
|
@@ -692,23 +622,30 @@ namespace
|
|
|
){
|
|
){
|
|
|
if(current_row < display_row){
|
|
if(current_row < display_row){
|
|
|
if(! node.m_subcolumns.empty()){
|
|
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;
|
|
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(""));
|
|
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
|
|
else
|
|
|
- header_cell(1, itr->second.cols, itr->first);
|
|
|
|
|
|
|
+ header_cell(1, s.second.cols, s.first);
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
|
|
|
|
@@ -716,9 +653,8 @@ namespace
|
|
|
// walk up from the path were we started until we find
|
|
// walk up from the path were we started until we find
|
|
|
// bin or bin.v2
|
|
// bin or bin.v2
|
|
|
|
|
|
|
|
- fs::path::const_iterator it = initial_path.end(), end = initial_path.end();
|
|
|
|
|
fs::path test_lib_dir = initial_path;
|
|
fs::path test_lib_dir = initial_path;
|
|
|
- for(;;){
|
|
|
|
|
|
|
+ do{
|
|
|
if(fs::is_directory( test_lib_dir / "bin.v2")){
|
|
if(fs::is_directory( test_lib_dir / "bin.v2")){
|
|
|
test_lib_dir /= "bin.v2";
|
|
test_lib_dir /= "bin.v2";
|
|
|
break;
|
|
break;
|
|
@@ -726,44 +662,47 @@ namespace
|
|
|
if(fs::is_directory( test_lib_dir / "bin")){
|
|
if(fs::is_directory( test_lib_dir / "bin")){
|
|
|
// v1 includes the word boost
|
|
// v1 includes the word boost
|
|
|
test_lib_dir /= "bin";
|
|
test_lib_dir /= "bin";
|
|
|
- test_lib_dir /= "boost";
|
|
|
|
|
|
|
+ if(fs::is_directory( test_lib_dir / "boost")){
|
|
|
|
|
+ test_lib_dir /= "boost";
|
|
|
|
|
+ }
|
|
|
break;
|
|
break;
|
|
|
}
|
|
}
|
|
|
- if(test_lib_dir.empty())
|
|
|
|
|
- throw std::string("binary path not found");
|
|
|
|
|
- if(*it != "libs")
|
|
|
|
|
- --it;
|
|
|
|
|
- test_lib_dir.remove_filename();
|
|
|
|
|
- }
|
|
|
|
|
|
|
+ }while(! test_lib_dir.empty());
|
|
|
|
|
|
|
|
- if(it == end)
|
|
|
|
|
- throw std::string("must be run from within a library directory");
|
|
|
|
|
|
|
+ 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;
|
|
return test_lib_dir;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- // note : uncomment the #if/#endif and what this compile !!!
|
|
|
|
|
string find_lib_name(fs::path lib_test_dir){
|
|
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();
|
|
fs::path::iterator e_itr = lib_test_dir.end();
|
|
|
- for(count = 0;; ++count){
|
|
|
|
|
|
|
+ while(lib_test_dir.begin() != e_itr){
|
|
|
if(*--e_itr == "libs")
|
|
if(*--e_itr == "libs")
|
|
|
break;
|
|
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).native());
|
|
|
|
|
- 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;
|
|
|
}
|
|
}
|
|
|
- return library_name;
|
|
|
|
|
|
|
+ // 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;
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ 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){
|
|
fs::path find_boost_root(fs::path initial_path){
|
|
@@ -781,19 +720,25 @@ namespace
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
// do_table ----------------------------------------------------------------//
|
|
// 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;
|
|
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;
|
|
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
|
|
// visit directory nodes and record nodetree
|
|
|
report << "<table border=\"1\" cellspacing=\"0\" cellpadding=\"5\">\n";
|
|
report << "<table border=\"1\" cellspacing=\"0\" cellpadding=\"5\">\n";
|
|
|
|
|
|
|
@@ -829,21 +774,12 @@ int cpp_main( int argc, char * argv[] ) // note name!
|
|
|
{
|
|
{
|
|
|
fs::path initial_path = fs::initial_path();
|
|
fs::path initial_path = fs::initial_path();
|
|
|
|
|
|
|
|
- fs::path comment_path;
|
|
|
|
|
while ( argc > 1 && *argv[1] == '-' )
|
|
while ( argc > 1 && *argv[1] == '-' )
|
|
|
{
|
|
{
|
|
|
if ( argc > 2 && std::strcmp( argv[1], "--compiler" ) == 0 )
|
|
if ( argc > 2 && std::strcmp( argv[1], "--compiler" ) == 0 )
|
|
|
{ specific_compiler = argv[2]; --argc; ++argv; }
|
|
{ specific_compiler = argv[2]; --argc; ++argv; }
|
|
|
else if ( argc > 2 && std::strcmp( argv[1], "--locate-root" ) == 0 )
|
|
else if ( argc > 2 && std::strcmp( argv[1], "--locate-root" ) == 0 )
|
|
|
{ locate_root = fs::path( argv[2] ); --argc; ++argv; }
|
|
{ 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], "--ignore-pass" ) == 0 ) ignore_pass = true;
|
|
|
else if ( std::strcmp( argv[1], "--no-warn" ) == 0 ) no_warn = true;
|
|
else if ( std::strcmp( argv[1], "--no-warn" ) == 0 ) no_warn = true;
|
|
|
else if ( std::strcmp( argv[1], "--v2" ) == 0 )
|
|
else if ( std::strcmp( argv[1], "--v2" ) == 0 )
|
|
@@ -864,27 +800,19 @@ int cpp_main( int argc, char * argv[] ) // note name!
|
|
|
" options: --compiler name Run for named compiler only\n"
|
|
" options: --compiler name Run for named compiler only\n"
|
|
|
" --ignore-pass Do not report tests which pass all compilers\n"
|
|
" --ignore-pass Do not report tests which pass all compilers\n"
|
|
|
" --no-warn Warnings not reported if test passes\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"
|
|
" --locate-root path Path to ALL_LOCATE_TARGET for bjam;\n"
|
|
|
" default boost-root.\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"
|
|
"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;
|
|
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] ) );
|
|
report.open( fs::path( argv[1] ) );
|
|
|
if ( !report )
|
|
if ( !report )
|
|
@@ -896,7 +824,7 @@ int cpp_main( int argc, char * argv[] ) // note name!
|
|
|
if ( argc == 3 )
|
|
if ( argc == 3 )
|
|
|
{
|
|
{
|
|
|
fs::path links_path( argv[2] );
|
|
fs::path links_path( argv[2] );
|
|
|
- links_name = links_path.native();
|
|
|
|
|
|
|
+ links_name = links_path.filename().string();
|
|
|
links_file.open( links_path );
|
|
links_file.open( links_path );
|
|
|
if ( !links_file )
|
|
if ( !links_file )
|
|
|
{
|
|
{
|
|
@@ -906,8 +834,6 @@ int cpp_main( int argc, char * argv[] ) // note name!
|
|
|
}
|
|
}
|
|
|
else no_links = true;
|
|
else no_links = true;
|
|
|
|
|
|
|
|
- build_notes_bookmarks();
|
|
|
|
|
-
|
|
|
|
|
const string library_name = find_lib_name(initial_path);
|
|
const string library_name = find_lib_name(initial_path);
|
|
|
|
|
|
|
|
char run_date[128];
|
|
char run_date[128];
|
|
@@ -923,31 +849,12 @@ int cpp_main( int argc, char * argv[] ) // note name!
|
|
|
<< "</head>\n"
|
|
<< "</head>\n"
|
|
|
<< "<body bgcolor=\"#ffffff\" text=\"#000000\">\n"
|
|
<< "<body bgcolor=\"#ffffff\" text=\"#000000\">\n"
|
|
|
<< "<table border=\"0\">\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"
|
|
<< "<h1>Library Status: " + library_name + "</h1>\n"
|
|
|
<< "<b>Run Date:</b> "
|
|
<< "<b>Run Date:</b> "
|
|
|
<< run_date
|
|
<< 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";
|
|
report << "</td>\n</table>\n<br>\n";
|
|
|
|
|
|
|
|
if ( !no_links )
|
|
if ( !no_links )
|
|
@@ -959,22 +866,25 @@ int cpp_main( int argc, char * argv[] ) // note name!
|
|
|
<< "</head>\n"
|
|
<< "</head>\n"
|
|
|
<< "<body bgcolor=\"#ffffff\" text=\"#000000\">\n"
|
|
<< "<body bgcolor=\"#ffffff\" text=\"#000000\">\n"
|
|
|
<< "<table border=\"0\">\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"
|
|
<< "<h1>Library Status: " + library_name + "</h1>\n"
|
|
|
<< "<b>Run Date:</b> "
|
|
<< "<b>Run Date:</b> "
|
|
|
<< run_date
|
|
<< 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"
|
|
report << "</body>\n"
|
|
|
"</html>\n"
|
|
"</html>\n"
|