//  Generate Compiler Status HTML from jam regression test output  -----------//

//  Copyright Beman Dawes 2002.  Distributed under the Boost
//  Software License, Version 1.0. (See accompanying file
//  LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)

//  See http://www.boost.org/tools/regression/ for documentation.

/*******************************************************************************

    This program was designed to work unchanged on all platforms and
    configurations.  All output which is platform or configuration dependent
    is obtained from external sources such as the .xml file from
    process_jam_log execution, the tools/build/xxx-tools.jam files, or the
    output of the config_info tests.

    Please avoid adding platform or configuration dependencies during
    program maintenance.

*******************************************************************************/

#include <boost/config/warning_disable.hpp>

#include "boost/config.hpp"
#include "boost/filesystem/operations.hpp"
#include "boost/filesystem/convenience.hpp"
#include "boost/filesystem/fstream.hpp"
#include "detail/tiny_xml.hpp"
namespace fs = boost::filesystem;
namespace xml = boost::tiny_xml;

#include <cstdlib>  // for abort, exit
#include <cctype>   // for toupper
#include <string>
#include <vector>
#include <set>
#include <map>
#include <algorithm>
#include <iostream>
#include <fstream>
#include <ctime>
#include <stdexcept>
#include <cassert>

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 compile_time;
  bool run_time;
  bool ignore_pass;
  bool no_warn;
  bool no_links;
  bool boost_build_v2 = true;

  fs::path jamfile_path;

  fs::directory_iterator end_itr;

  // It's immportant for reliability that we find the same compilers for each
  // test, and that they match the column header.  So save the names at the
  // time column headings are generated.
  std::vector<string> toolsets;

  fs::ifstream jamfile;
  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;

  std::vector<int> error_count;

  // prefix for library and test hyperlink prefix
  string svn_root ( "http://svn.boost.org/trac/boost/browser/trunk/" );
  string url_prefix_dir_view( svn_root );
  string url_prefix_checkout_view( svn_root );
  string url_suffix_text_view( "" );

//  get revision number (as a string) if boost_root is svn working copy  -----//

  string revision( const fs::path & boost_root )
  {
    string rev;
    fs::path entries( boost_root / ".svn" / "entries" );
    fs::ifstream entries_file( entries );
    if ( entries_file )
    {
      std::getline( entries_file, rev );
      std::getline( entries_file, rev );
      std::getline( entries_file, rev );
      std::getline( entries_file, rev );  // revision number as a string
    }
    return rev;
  }


//  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;
  }

//  relative path between two paths  -----------------------------------------//

  void relative_path( const fs::path & from, const fs::path & to,
    fs::path & target )
  {
    if ( from.string().size() <= to.string().size() ) return;
    target /= "..";
    relative_path( from.branch_path(), to, target );
    return;
  }

//  extract object library name from target directory string  ----------------//

  string extract_object_library_name( const string & s )
  {
    string t( s );
    string::size_type pos = t.find( "/build/" );
    if ( pos != string::npos ) pos += 7;
    else if ( (pos = t.find( "/test/" )) != string::npos ) pos += 6;
    else return "";
    return t.substr( pos, t.find( "/", pos ) - pos );
  }

//  find_file  ---------------------------------------------------------------//
//  given a directory to recursively search

  bool find_file( const fs::path & dir_path, const string & name,
    fs::path & path_found, const string & ignore_dir_named="" )
  {
    if ( !fs::exists( dir_path ) ) return false;
    for ( fs::directory_iterator itr( dir_path ); itr != end_itr; ++itr )
      if ( fs::is_directory( *itr )
        && itr->filename() != ignore_dir_named )
      {
        if ( find_file( *itr, name, path_found ) ) return true;
      }
      else if ( itr->filename() == name )
      {
        path_found = *itr;
        return true;
      }
    return false;
  }

//  platform_desc  -----------------------------------------------------------//

  string platform_desc()
  {
    string result = BOOST_PLATFORM;
    result[0] = std::toupper( result[0] );
    return result;
  }

//  version_desc  ------------------------------------------------------------//
//  from locate-root/status/bin/config_info.test/xxx/.../config_info.output

  string version_desc( const string & compiler_name )
  {
    string result;
    fs::path dot_output_path;
    if ( find_file( locate_root / "bin/boost/status/config_info.test"
      / compiler_name, "config_info.output", dot_output_path )
      || find_file( locate_root / "status/bin/config_info.test"
      / compiler_name, "config_info.output", dot_output_path ) )
    {
      fs::ifstream file( dot_output_path );
      if ( file )
      {
        if( std::getline( file, result ) )
        {
          string::size_type pos = result.find( "version " );
          if ( pos != string::npos )
          {
            result.erase( 0, pos+8 );
          }
          else result.clear();
        }
      }
    }
    return result;
  }

//  compiler_desc  -----------------------------------------------------------//
//  from boost-root/tools/build/xxx-tools.jam

  string compiler_desc( const string & compiler_name )
  {
    string result;
    fs::path tools_path( boost_root / "tools/build/v1" / (compiler_name
      + "-tools.jam") );
    if ( !fs::exists( tools_path ) )
      tools_path = boost_root / "tools/build" / (compiler_name + "-tools.jam");
    fs::ifstream file( tools_path );
    if ( file )
    {
      while( std::getline( file, result ) )
      {
        if ( result.substr( 0, 3 ) == "#//" )
        {
          result.erase( 0, 3 );
          return result;
        }
      }
      result.clear();
    }
    return result;
  }

//  target_directory  --------------------------------------------------------//
//  this amounts to a request to find a unique leaf directory

  fs::path target_directory( const fs::path & root )
  {
    if ( !fs::exists( root ) ) return fs::path("no-such-path");
    fs::path child;
    for ( fs::directory_iterator itr( root ); itr != end_itr; ++itr )
    {
      if ( fs::is_directory( *itr ) )
      {
        // SunCC creates an internal subdirectory everywhere it writes
        // object files.  This confuses the target_directory() algorithm.
        // This patch ignores the SunCC internal directory. Jens Maurer
        if ( (*itr).filename() == "SunWS_cache" ) continue;
        // SGI does something similar for template instantiations. Jens Maurer
        if(  (*itr).filename() == "ii_files" ) continue; 

        if ( child.empty() ) child = *itr;
        else
        {
          std::cout << "Warning: only first of two target possibilities will be reported for: \n "
            << root.string() << ": " << child.filename()
            << " and " << (*itr).filename() << "\n";
        }
      }
    }
    if ( child.empty() ) return root; // this dir has no children
    return target_directory( child );
  }

//  element_content  ---------------------------------------------------------//

  const string & element_content(
    const xml::element & root, const string & name )
  {
    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;
  }

//  find_element  ------------------------------------------------------------//

  const xml::element empty_element;

  const xml::element & find_element(
    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;
  }

//  attribute_value  ----------------------------------------------------------//

const string & attribute_value( const xml::element & element,
                                const string & attribute_name )
{
  static const string empty_string;
  xml::attribute_list::const_iterator atr;
  for ( atr = element.attributes.begin();
        atr != element.attributes.end() && atr->name != attribute_name;
        ++atr ) {}
  return atr == element.attributes.end() ? empty_string : atr->value;
}

//  find_bin_path  -----------------------------------------------------------//

// Takes a relative path from boost root to a Jamfile.
// Returns the directory where the build targets from
// that Jamfile are located. If not found, emits a warning 
// and returns empty path.
const fs::path find_bin_path(const string& relative)
{
  fs::path bin_path;
  if (boost_build_v2)
  {
    if ( relative == "status" )
      bin_path = locate_root / "bin.v2" / "libs";
    else
    {
      bin_path = locate_root / "bin.v2" / relative;
      if (!fs::exists(bin_path))
        bin_path = locate_root / "bin" / relative;
    }
    if (!fs::exists(bin_path))
    {
      std::cerr << "warning: could not find build results for '" 
                << relative << "'.\n";
      std::cerr << "warning: tried directory " 
                << bin_path.native_directory_string() << "\n";
      bin_path = "";
    }
  }
  else
  {
    bin_path = locate_root / "bin/boost" / relative;
    if (!fs::exists(bin_path))
    {
      bin_path = locate_root / "bin" / relative / "bin";
      if (!fs::exists(bin_path))
      {
        bin_path = fs::path( locate_root / relative / "bin" );
        if (!fs::exists(bin_path))
        {
          bin_path = fs::path( locate_root / "bin/boost/libs" /
            relative.substr( relative.find( '/' )+1 ) );
        }
      }
    }
    if (!fs::exists(bin_path))
    {
      std::cerr << "warning: could not find build results for '" 
                << relative << "'.\n";
      bin_path = "";
    }
  }
  return bin_path;
}


//  generate_report  ---------------------------------------------------------//

  // return 0 if nothing generated, 1 otherwise, except 2 if compiler msgs
  int generate_report( const xml::element & db,
                       const string & source_library_name,
                       const string & test_type,
                       const string & test_name, // possibly object library name
                       const string & toolset,
                       bool pass,
                       bool always_show_run_output = false )
  {
    // compile msgs sometimes modified, so make a local copy
    string compile( ((pass && no_warn)
      ? empty_string :  element_content( db, "compile" )) );
    const string & link( pass ? empty_string : element_content( db, "link" ) );
    const string & run( (pass && !always_show_run_output)
      ? empty_string : element_content( db, "run" ) );
    string lib( (pass ? empty_string : element_content( db, "lib" )) );

    string::size_type pos;
    if ( (pos = compile.find("30 DAY EVALUATION LICENSE")) != string::npos )
    {
      compile.erase(pos, 25);
      while ( compile[0] == '\n' || compile[0] == '\r' ) compile.erase(0,1);
    }

    // some compilers output the filename even if there are no errors or
    // warnings; detect this if one line of output and it contains no space.
    pos = compile.find( '\n', 1 );
    if ( pos != string::npos && compile.size()-pos <= 2
        && compile.find( ' ' ) == string::npos ) compile.clear();

    if ( lib.empty()
      && (compile.empty() || test_type == "compile_fail")
      && link.empty() && run.empty() ) return 0;

    int result = 1; // some kind of msg for sure

    // limit compile message length
    if ( compile.size() > max_compile_msg_size )
    {
      compile.erase( max_compile_msg_size );
      compile += "...\n   (remainder deleted because of excessive size)\n";
    }

    links_file << "<h2><a name=\""
      << source_library_name << "-" << test_name << "-" << toolset << "\">"
      << source_library_name << " - " << test_name << " - " << toolset << "</a></h2>\n";

    if ( !compile.empty() )
    {
      ++result;
      links_file << "<h3>Compiler output:</h3><pre>"
        << compile << "</pre>\n";
    }
    if ( !link.empty() )
      links_file << "<h3>Linker output:</h3><pre>" << link << "</pre>\n";
    if ( !run.empty() )
      links_file << "<h3>Run output:</h3><pre>" << run << "</pre>\n";

    // for an object library failure, generate a reference to the object
    // library failure message, and (once only) generate the object
    // library failure message itself
    static std::set< string > failed_lib_target_dirs; // only generate once
    if ( !lib.empty() )
    {
      if ( lib[0] == '\n' ) lib.erase( 0, 1 );
      string object_library_name( extract_object_library_name( lib ) );

      // changing the target directory naming scheme breaks
      // extract_object_library_name()
      assert( !object_library_name.empty() );
      if ( object_library_name.empty() )
        std::cerr << "Failed to extract object library name from " << lib << "\n";

      links_file << "<h3>Library build failure: </h3>\n"
        "See <a href=\"#"
        << source_library_name << "-"
        << object_library_name << "-" << toolset << "\">"
        << source_library_name << " - "
        << object_library_name << " - " << toolset << "</a>";

      if ( failed_lib_target_dirs.find( lib ) == failed_lib_target_dirs.end() )
      {
        failed_lib_target_dirs.insert( lib );
        fs::path pth( locate_root / lib / "test_log.xml" );
        fs::ifstream file( pth );
        if ( file )
        {
          xml::element_ptr db = xml::parse( file, pth.string() );
          generate_report( *db, source_library_name, test_type, object_library_name, toolset, false );
        }
        else
        {
          links_file << "<h2><a name=\""
            << object_library_name << "-" << toolset << "\">"
            << object_library_name << " - " << toolset << "</a></h2>\n"
            "test_log.xml not found\n";
        }
      }
    }
    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>";
        }
      }
    }
  }

  //  get_notes  -------------------------------------------------------------//

  string get_notes( const string & toolset,
                    const string & library, const string & test, bool fail )
  {
    string sep;
    string target( "<sup>" );
    add_notes( toolset + "/" + library + "/" + test, fail, sep, target ); 
    add_notes( "*/" + library + "/" + test, fail, sep, target ); 
    add_notes( toolset + "/" + library + "/*", fail, sep, target ); 
    add_notes( "*/" + library + "/*", fail, sep, target );
    if ( target == "<sup>" ) target.clear();
    else target += "</sup>";
    return target;
  }

  //  do_cell  ---------------------------------------------------------------//

  bool do_cell(
    int compiler,
    const string & lib_name,
    const fs::path & test_dir,
    const string & test_type,
    const string & test_name,
    const string & toolset,
    string & target,
    bool always_show_run_output )
  // return true if any results except simple pass_msg
  {
    fs::path target_dir( target_directory( test_dir / toolset ) );
    bool pass = false;

    if ( !fs::exists( target_dir / "test_log.xml" ) )
    {
      std::cerr << "Missing jam_log.xml in target:\n "
        << target_dir.string() << "\n";
      target += "<td>" + missing_residue_msg + "</td>";
      return true;
    }

    int anything_generated = 0;
    bool note = false;

    fs::path pth( target_dir / "test_log.xml" );
    fs::ifstream file( pth );
    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;
    }

    xml::element_ptr dbp = xml::parse( file, pth.string() );
    const xml::element & db( *dbp );

    std::string test_type_base( test_type );
    if ( test_type_base == "run_pyd" ) test_type_base = "run";
    else if ( test_type_base.size() > 5 )
    {
      const string::size_type trailer = test_type_base.size() - 5;
      if ( test_type_base.substr( trailer ) == "_fail" )
      {
        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";

    if ( !no_links )
    {
      note = attribute_value( test_type_element, "result" ) == "note";

      // generate bookmarked report of results, and link to it
      anything_generated
        = generate_report( db, lib_name, test_type, test_name, toolset, pass,
          always_show_run_output || note );
    }

    target += "<td>";

    // generate the status table cell pass/warn/fail HTML
    if ( anything_generated != 0 )
    {
      target += "<a href=\"";
      target += links_name;
      target += "#";
      target += lib_name;
      target += "-";
      target += test_name;
      target += "-";
      target += toolset;
      target += "\">";
      target += pass
        ? (anything_generated < 2 ? pass_msg : warn_msg)
        : fail_msg;
      target += "</a>";
      if ( pass && note ) target += note_msg;
    }
    else  target += pass ? pass_msg : fail_msg;

    // if notes, generate the superscript HTML
    if ( !notes.empty() ) 
      target += get_notes( toolset, lib_name, test_name, !pass );

    // generate compile-time if requested
    if ( compile_time )
    {
      const xml::element & compile_element( find_element( db, "compile" ) );

      if ( !compile_element.name.empty() )
      {
        string times = attribute_value( compile_element, "timings" );
        if ( !times.empty() )
        {
          target += "<br>";
          target += times.substr( 0, times.find( " " ) );
        }
      }
    }
      
    // generate run-time if requested
    if ( run_time )
    {
      const xml::element & run_element( find_element( db, "run" ) );

      if ( !run_element.name.empty() )
      {
        string times = attribute_value( run_element, "timings" );
        if ( !times.empty() )
        {
          target += "<br>";
          target += times.substr( 0, times.find( " " ) );
        }
      }
    }

    if ( !pass ) ++error_count[compiler];
      
    target += "</td>";
    return (anything_generated != 0) || !pass;
  }

//  do_row  ------------------------------------------------------------------//

  void do_row(
    const fs::path & test_dir, // locate_root / "status/bin/any_test.test"
    const string & test_name, // "any_test"
    string & target )
  {
    // get library name, test-type, test-program path, etc., from the .xml file
    string lib_name;
    string test_path( test_name ); // test_name is default if missing .test
    string test_type( "unknown" );
    bool always_show_run_output( false );
    fs::path xml_file_path;
    if ( find_file( test_dir, "test_log.xml", xml_file_path ) )
    {
      fs::ifstream file( xml_file_path );
      if ( file )
      {
        xml::element_ptr dbp = xml::parse( file, xml_file_path.string() );
        const xml::element & db( *dbp );
        test_path = attribute_value( db, "test-program" );
        lib_name = attribute_value( db, "library" );
        test_type = attribute_value( db, "test-type" );
        always_show_run_output
          = attribute_value( db, "show-run-output" ) == "true";
      }
    }

    // generate the library name, test name, and test type table data
    string::size_type row_start_pos = target.size();
    target += "<tr><td><a href=\"" + url_prefix_dir_view + "/libs/" + lib_name
      + "\">"  + lib_name  + "</a></td>";
    target += "<td><a href=\"" + url_prefix_checkout_view + "/" + test_path
      + url_suffix_text_view + "\">" + test_name + "</a>";

    if ( compile_time ) target += "<br> Compile time:";
    if ( run_time ) target += "<br> Run time:";

    target += "</td>";
    target += "<td>" + test_type + "</td>";

    bool no_warn_save = no_warn;
    //if ( test_type.find( "fail" ) != string::npos ) no_warn = true;

    // for each compiler, generate <td>...</td> html
    bool anything_to_report = false;
    int compiler = 0;
    for ( std::vector<string>::const_iterator itr=toolsets.begin();
      itr != toolsets.end(); ++itr, ++compiler )
    {
      anything_to_report |= do_cell( compiler, lib_name, test_dir, test_type, test_name, *itr, target,
        always_show_run_output );
    }

    target += "</tr>";
    if ( ignore_pass && !anything_to_report ) target.erase( row_start_pos );
    no_warn = no_warn_save;
  }

//  do_rows_for_sub_tree  ----------------------------------------------------//

  void do_rows_for_sub_tree(
    const fs::path & bin_dir, std::vector<string> & results )
  {
    for ( fs::directory_iterator itr( bin_dir ); itr != end_itr; ++itr )
    {
      if ( fs::is_directory( *itr )
        && itr->string().find( ".test" ) == (itr->string().size()-5) )
      {
        results.push_back( std::string() ); 
        do_row( *itr,
                itr->filename().substr( 0, itr->filename().size()-5 ),
                results[results.size()-1] );
      }
    }
  }

//  find_compilers  ------------------------------------------------------------//

  void find_compilers(const fs::path & bin_dir)
  {
    fs::directory_iterator compiler_itr( bin_dir );
    if ( specific_compiler.empty() )
      std::clog << "Using " << bin_dir.string() << " to determine compilers\n";
    for (; compiler_itr != end_itr; ++compiler_itr )
    {
      if ( fs::is_directory( *compiler_itr )  // check just to be sure
        && compiler_itr->filename() != "test" ) // avoid strange directory (Jamfile bug?)
      {
        if ( specific_compiler.size() != 0
          && specific_compiler != compiler_itr->filename() ) continue;
        toolsets.push_back( compiler_itr->filename() );
        string desc( compiler_desc( compiler_itr->filename() ) );
        string vers( version_desc( compiler_itr->filename() ) );
        report << "<td>"
             << (desc.size() ? desc : compiler_itr->filename())
             << (vers.size() ? (string( "<br>" ) + vers ) : string( "" ))
             << "</td>\n";
        error_count.push_back( 0 );
      }
    }
  }

//  do_table_body  -----------------------------------------------------------//

  void do_table_body( const fs::path & bin_dir )
  {
    // rows are held in a vector so they can be sorted, if desired.
    std::vector<string> results;

    // do primary bin directory
    do_rows_for_sub_tree( bin_dir, results );

    // do subinclude bin directories
    jamfile.clear();
    jamfile.seekg(0);
    string line;
    bool run_tests = false;

    while( std::getline( jamfile, line ) )
    {
      bool v2(false);
      string::size_type sub_pos( line.find( "subinclude" ) );
      if ( sub_pos == string::npos ) {
        sub_pos = line.find( "build-project" );
        v2 = true;
      }
      if ( sub_pos != string::npos
        && line.find( '#' ) > sub_pos )
      {
        if (v2)
          sub_pos = line.find_first_not_of( " \t./", sub_pos+13 );
        else
          sub_pos = line.find_first_not_of( " \t./", sub_pos+10 );
      
        if ( sub_pos == string::npos ) continue;
        string subinclude_bin_dir(
          line.substr( sub_pos, line.find_first_of( " \t", sub_pos )-sub_pos ) );

        fs::path bin_path = find_bin_path(subinclude_bin_dir);
        if (!bin_path.empty())
          do_rows_for_sub_tree( bin_path, results );
      }
      if ( ! run_tests )
      {
        string::size_type run_pos = line.find("run-tests");
        if ( run_pos != string::npos && line.find_first_not_of(" \t") == run_pos )
          run_tests = true;
      }
      else
      {
        if ( line.find(";") != string::npos )
          run_tests = false;
        else
        {
          string::size_type pos = line.find_first_not_of( " \t" );
          if ( pos != string::npos && line[pos] != '#' )
          {
            string::size_type end_pos = line.find_first_of(" \t#", pos);
            string::iterator end = end_pos != string::npos ? line.begin() + end_pos : line.end();
            string run_tests_bin_dir(line.begin() + pos, end);
            fs::path bin_path = find_bin_path("libs/" + run_tests_bin_dir);
            if (!bin_path.empty())
              do_rows_for_sub_tree( bin_path, results );
          }
        }
      }
    }


    std::sort( results.begin(), results.end() );

    for ( std::vector<string>::iterator v(results.begin());
      v != results.end(); ++v )
      { report << *v << "\n"; }
  }

//  do_table  ----------------------------------------------------------------//

  void do_table()
  {
    // Find test result locations, trying:
    // - Boost.Build V1 location with ALL_LOCATE_TARGET
    // - Boost.Build V2 location with top-lelve "build-dir" 
    // - Boost.Build V1 location without ALL_LOCATE_TARGET
    string relative( fs::initial_path().string() );

#ifdef BOOST_WINDOWS_API
    if (relative.size() > 1 && relative[1] == ':') relative[0] = std::tolower(relative[0]);
#endif

    if ( relative.find(boost_root.string()) != string::npos )
      relative.erase( 0, boost_root.string().size()+1 );
    else if ( relative.find(locate_root.string()) != string::npos )
      relative.erase( 0, locate_root.string().size()+1 );
    fs::path bin_path = find_bin_path(relative);

    report << "<table border=\"1\" cellspacing=\"0\" cellpadding=\"5\">\n";

    // generate the column headings

    report << "<tr><td>Library</td><td>Test Name</td>\n"
      "<td><a href=\"compiler_status.html#test-type\">Test Type</a></td>\n";

    if ( relative == "status" )
    {
      fs::recursive_directory_iterator ritr( bin_path );
      fs::recursive_directory_iterator end_ritr;
      while ( ritr != end_ritr 
        && ((ritr->string().find( ".test" ) != (ritr->string().size()-5))
        || !fs::is_directory( *ritr )))
        ++ritr; // bypass chaff
      if ( ritr != end_ritr )
      {
        find_compilers( *ritr );
      }
    }
    else
    {
      fs::directory_iterator itr( bin_path );
      while ( itr != end_itr 
        && ((itr->string().find( ".test" ) != (itr->string().size()-5))
        || !fs::is_directory( *itr )))
        ++itr; // bypass chaff
      if ( itr != end_itr )
      {
        find_compilers( *itr );
      }
    }

    report << "</tr>\n";

    // now the rest of the table body

    do_table_body( bin_path );

    // error total row

    report << "<tr> <td> &nbsp;</td><td>Number of Failures</td><td> &nbsp;</td>\n";

    // for each compiler, generate <td>...</td> html
    int compiler = 0;
    for ( std::vector<string>::const_iterator itr=toolsets.begin();
      itr != toolsets.end(); ++itr, ++compiler )
    {
      report << "<td align=\"center\">" << error_count[compiler] << "</td>\n";
    }

    report << "</tr>\n</table>\n";
  }

} // unnamed namespace

//  main  --------------------------------------------------------------------//

#define BOOST_NO_CPP_MAIN_SUCCESS_MESSAGE
#include <boost/test/included/prg_exec_monitor.hpp>

int cpp_main( int argc, char * argv[] ) // note name!
{
  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], fs::native ); --argc; ++argv; }
    else if ( argc > 2 && std::strcmp( argv[1], "--comment" ) == 0 )
      { comment_path = fs::path( argv[2], fs::native ); --argc; ++argv; }
    else if ( argc > 2 && std::strcmp( argv[1], "--notes" ) == 0 )
      { notes_path = fs::path( argv[2], fs::native ); --argc; ++argv; }
    else if ( argc > 2 && std::strcmp( argv[1], "--notes-map" ) == 0 )
      { notes_map_path = fs::path( argv[2], fs::native ); --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], "--v1" ) == 0 ) boost_build_v2 = false;
    else if ( std::strcmp( argv[1], "--v2" ) == 0 ) boost_build_v2 = true;
    else if ( argc > 2 && std::strcmp( argv[1], "--jamfile" ) == 0)
      { jamfile_path = fs::path( argv[2], fs::native ); --argc; ++argv; }
    else if ( std::strcmp( argv[1], "--compile-time" ) == 0 ) compile_time = true;
    else if ( std::strcmp( argv[1], "--run-time" ) == 0 ) run_time = true;
    else { std::cerr << "Unknown option: " << argv[1] << "\n"; argc = 1; }
    --argc;
    ++argv;
  }

  if ( argc != 3 && argc != 4 )
  {
    std::cerr <<
      "Usage: compiler_status [options...] boost-root status-file [links-file]\n"
      "  boost-root is the path to the boost tree root directory.\n"
      "  status-file and links-file are paths to the output files.\n"
      "Must be run from directory containing Jamfile\n"
      "  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"
      "           --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"
      "           --jamfile path      Path to Jamfile. By default \"Jamfile\".\n"
      "           --v1                Assume Boost.Build version 1.\n"
      "           --v2                Assume Boost.Build version 2. (default)\n"
      "           --ignore-pass       Ignore passing tests.\n"
      "           --no-warn           Do not report warnings.\n"
      "           --compile-time      Show compile time.\n"
      "           --run-time          Show run time.\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"
      "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"
      ;
    return 1;
  }

  boost_root = fs::path( argv[1], fs::native );
  if ( locate_root.empty() ) locate_root = boost_root;
  
  if (jamfile_path.empty())
    if (boost_build_v2)
      jamfile_path = "Jamfile.v2";
    else
      jamfile_path = "Jamfile";
  jamfile_path = fs::complete( jamfile_path, fs::initial_path() );
  jamfile.open( jamfile_path );
  if ( !jamfile )
  {
    std::cerr << "Could not open Jamfile: " << jamfile_path.native_file_string() << std::endl;
    return 1;
  }

  report.open( fs::path( argv[2], fs::native ) );
  if ( !report )
  {
    std::cerr << "Could not open report output file: " << argv[2] << std::endl;
    return 1;
  }

  if ( argc == 4 )
  {
    fs::path links_path( argv[3], fs::native );
    links_name = links_path.filename();
    links_file.open( links_path );
    if ( !links_file )
    {
      std::cerr << "Could not open links output file: " << argv[3] << std::endl;
      return 1;
    }
  }
  else no_links = true;

  build_notes_bookmarks();

  char run_date[128];
  std::time_t tod;
  std::time( &tod );
  std::strftime( run_date, sizeof(run_date),
    "%X UTC, %A %d %B %Y", std::gmtime( &tod ) );

  std::string rev = revision( boost_root );

  report << "<html>\n"
          "<head>\n"
          "<title>Boost Test Results</title>\n"
          "</head>\n"
          "<body bgcolor=\"#ffffff\" text=\"#000000\">\n"
          "<table border=\"0\">\n"
          "<tr>\n"
          "<td><img border=\"0\" src=\"http://www.boost.org/boost.png\" width=\"277\" "
          "height=\"86\"></td>\n"
          "<td>\n"
          "<h1>Boost Test Results - " + platform_desc() + "</h1>\n"
          "<b>Run</b> "
       << run_date;
  if ( !rev.empty() ) report << ", <b>Revision</b> " << rev;
  report << "\n";

  
  if ( compile_time )
    report << "<p>Times reported are elapsed wall clock time in seconds.</p>\n";


  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 )
  {
    links_file
      << "<html>\n"
         "<head>\n"
         "<title>Boost Test Details</title>\n"
         "</head>\n"
         "<body bgcolor=\"#ffffff\" text=\"#000000\">\n"
         "<table border=\"0\">\n"
         "<tr>\n"
         "<td><img border=\"0\" src=\"http://www.boost.org/boost.png\" width=\"277\" "
         "height=\"86\"></td>\n"
         "<td>\n"
         "<h1>Boost Test Details - " + platform_desc() + "</h1>\n"
         "<b>Run Date:</b> "
      << run_date;
    if ( !rev.empty() ) links_file << ", <b>Revision</b> " << rev;
    links_file << "\n</td>\n</table>\n<br>\n";
  }

  do_table();

  if ( load_notes_html() ) report << notes_html << "\n";

  report << "</body>\n"
          "</html>\n"
          ;

  if ( !no_links )
  {
    links_file
      << "</body>\n"
         "</html>\n"
         ;
  }
  return 0;
}
