123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260 |
- // Generate an HTML table showing path decomposition ---------------------------------//
- // Copyright Beman Dawes 2005.
- // Distributed under the Boost Software License, Version 1.0.
- // See http://www.boost.org/LICENSE_1_0.txt
- // See http://www.boost.org/libs/filesystem for documentation.
- // For purposes of generating the table, support both POSIX and Windows paths
- #include "boost/filesystem.hpp"
- #include <iostream>
- #include <fstream>
- using boost::filesystem::path;
- using std::string;
- using std::cout;
- namespace
- {
- std::ifstream infile;
- std::ofstream posix_outfile;
- std::ifstream posix_infile;
- std::ofstream outfile;
- bool posix;
- const string empty_string;
- struct column_base
- {
- virtual string heading() const = 0;
- virtual string cell_value( const path & p ) const = 0;
- };
- struct c0 : public column_base
- {
- string heading() const { return string("<code>string()</code>"); }
- string cell_value( const path & p ) const { return p.string(); }
- } o0;
- struct c1 : public column_base
- {
- string heading() const { return string("<code>generic_<br>string()</code>"); }
- string cell_value( const path & p ) const { return p.generic_string(); }
- } o1;
- struct c2 : public column_base
- {
- string heading() const { return string("Iteration<br>over<br>Elements"); }
- string cell_value( const path & p ) const
- {
- string s;
- for( path::iterator i(p.begin()); i != p.end(); ++i )
- {
- if ( i != p.begin() ) s += ',';
- s += (*i).string();
- }
- return s;
- }
- } o2;
- struct c3 : public column_base
- {
- string heading() const { return string("<code>root_<br>path()</code>"); }
- string cell_value( const path & p ) const { return p.root_path().string(); }
- } o3;
- struct c4 : public column_base
- {
- string heading() const { return string("<code>root_<br>name()</code>"); }
- string cell_value( const path & p ) const { return p.root_name().string(); }
- } o4;
- struct c5 : public column_base
- {
- string heading() const { return string("<code>root_<br>directory()</code>"); }
- string cell_value( const path & p ) const { return p.root_directory().string(); }
- } o5;
- struct c6 : public column_base
- {
- string heading() const { return string("<code>relative_<br>path()</code>"); }
- string cell_value( const path & p ) const { return p.relative_path().string(); }
- } o6;
- struct c7 : public column_base
- {
- string heading() const { return string("<code>parent_<br>path()</code>"); }
- string cell_value( const path & p ) const { return p.parent_path().string(); }
- } o7;
- struct c8 : public column_base
- {
- string heading() const { return string("<code>filename()</code>"); }
- string cell_value( const path & p ) const { return p.filename().string(); }
- } o8;
- const column_base * column[] = { &o2, &o0, &o1, &o3, &o4, &o5, &o6, &o7, &o8 };
- // do_cell ---------------------------------------------------------------//
- void do_cell( const string & test_case, int i )
- {
- string temp = column[i]->cell_value(path(test_case));
- string value;
- outfile << "<td>";
- if (temp.empty())
- value = "<font size=\"-1\"><i>empty</i></font>";
- else
- value = string("<code>") + temp + "</code>";
- if (posix)
- posix_outfile << value << '\n';
- else
- {
- std::getline(posix_infile, temp);
- if (value != temp) // POSIX and Windows differ
- {
- value.insert(0, "<br>");
- value.insert(0, temp);
- value.insert(0, "<span style=\"background-color: #CCFFCC\">");
- value += "</span>";
- }
- outfile << value;
- }
- outfile << "</td>\n";
- }
- // do_row ------------------------------------------------------------------//
- void do_row( const string & test_case )
- {
- outfile << "<tr>\n";
- if (test_case.empty())
- outfile << "<td><font size=\"-1\"><i>empty</i></font></td>\n";
- else
- outfile << "<td><code>" << test_case << "</code></td>\n";
-
- for ( int i = 0; i < sizeof(column)/sizeof(column_base&); ++i )
- {
- do_cell( test_case, i );
- }
- outfile << "</tr>\n";
- }
- // do_table ----------------------------------------------------------------//
- void do_table()
- {
- outfile <<
- "<h1>Path Decomposition Table</h1>\n"
- "<p>Shaded entries indicate cases where <i>POSIX</i> and <i>Windows</i>\n"
- "implementations yield different results. The top value is the\n"
- "<i>POSIX</i> result and the bottom value is the <i>Windows</i> result.\n"
- "<table border=\"1\" cellspacing=\"0\" cellpadding=\"5\">\n"
- "<p>\n"
- ;
- // generate the column headings
- outfile << "<tr><td><b>Constructor<br>argument</b></td>\n";
- for ( int i = 0; i < sizeof(column)/sizeof(column_base&); ++i )
- {
- outfile << "<td><b>" << column[i]->heading() << "</b></td>\n";
- }
- outfile << "</tr>\n";
- // generate a row for each input line
- string test_case;
- while ( std::getline( infile, test_case ) )
- {
- if (!test_case.empty() && *--test_case.end() == '\r')
- test_case.erase(test_case.size()-1);
- if (test_case.empty() || test_case[0] != '#')
- do_row( test_case );
- }
- outfile << "</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!
- {
- if ( argc != 5 )
- {
- std::cerr <<
- "Usage: path_table \"POSIX\"|\"Windows\" input-file posix-file output-file\n"
- "Run on POSIX first, then on Windows\n"
- " \"POSIX\" causes POSIX results to be saved in posix-file;\n"
- " \"Windows\" causes POSIX results read from posix-file\n"
- " input-file contains the paths to appear in the table.\n"
- " posix-file will be used for POSIX results\n"
- " output-file will contain the generated HTML.\n"
- ;
- return 1;
- }
- infile.open( argv[2] );
- if ( !infile )
- {
- std::cerr << "Could not open input file: " << argv[2] << std::endl;
- return 1;
- }
- if (string(argv[1]) == "POSIX")
- {
- posix = true;
- posix_outfile.open( argv[3] );
- if ( !posix_outfile )
- {
- std::cerr << "Could not open POSIX output file: " << argv[3] << std::endl;
- return 1;
- }
- }
- else
- {
- posix = false;
- posix_infile.open( argv[3] );
- if ( !posix_infile )
- {
- std::cerr << "Could not open POSIX input file: " << argv[3] << std::endl;
- return 1;
- }
- }
- outfile.open( argv[4] );
- if ( !outfile )
- {
- std::cerr << "Could not open output file: " << argv[2] << std::endl;
- return 1;
- }
- outfile << "<html>\n"
- "<head>\n"
- "<title>Path Decomposition Table</title>\n"
- "</head>\n"
- "<body bgcolor=\"#ffffff\" text=\"#000000\">\n"
- ;
- do_table();
- outfile << "</body>\n"
- "</html>\n"
- ;
- return 0;
- }
|