/* * * Copyright (c) 2003 Dr John Maddock * Use, modification and distribution is subject to 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) * */ #include "licence_info.hpp" #include "bcp_imp.hpp" #include "fileview.hpp" #include #include #include #include #include #include #include // // split_path is a small helper for outputting a path name, // complete with a link to that path: // struct split_path { const fs::path& root; const fs::path& file; split_path(const fs::path& r, const fs::path& f) : root(r), file(f){} }; std::ostream& operator << (std::ostream& os, const split_path& p) { os << "" << p.file.string() << ""; return os; } std::string make_link_target(const std::string& s) { // convert an arbitrary string into something suitable // for an name: std::string result; for(unsigned i = 0; i < s.size(); ++i) { result.append(1, static_cast(std::isalnum(s[i]) ? s[i] : '_')); } return result; } void bcp_implementation::output_license_info() { std::pair licenses = get_licenses(); std::map::const_iterator i, j; i = m_license_data.begin(); j = m_license_data.end(); std::ofstream os(m_dest_path.native_file_string().c_str()); if(!os) { std::string msg("Error opening "); msg += m_dest_path.string(); msg += " for output."; std::runtime_error e(msg); boost::throw_exception(e); } os << "\n" "\n" "\n" "Boost Licence Dependency Information"; if(m_module_list.size() == 1) { os << " for " << *(m_module_list.begin()); } os << "\n" "\n" "\n" "

Boost Licence Dependency Information"; if(m_module_list.size() == 1) { os << " for " << *(m_module_list.begin()); } os << "

\n" "

Contents

\n" "
Input Information\n";
   if(!m_bsl_summary_mode)
      os << "Licence Summary\n";
   os << "Licence Details\n";

   while(i != j)
   {
      // title:
      os << "   first].license_name) 
         << "\">" << licenses.first[i->first].license_name << "\n";
      ++i;
   }

   os << "Files with no recognised license\n"
      "Files with no recognised copyright holder\n";
   if(!m_bsl_summary_mode)
   {
      os <<
      "Moving to the Boost Software License...\n"
      "  Files that can be automatically converted to the Boost Software License\n"
      "  Files that can be manually converted to the Boost Software License\n"
      "  Files that can NOT be moved to the Boost Software License\n"
      "  Authors we need to move to the Boost Software License\n"
      "Copyright Holder Information\n";
   }
   os << 
      "File Dependency Information\n"
      "
"; // // input Information: // os << "

Input Information

\n"; if(m_scan_mode) os << "

The following files were scanned for boost dependencies:
"; else os << "

The following Boost modules were checked:
"; std::list::const_iterator si = m_module_list.begin(); std::list::const_iterator sj = m_module_list.end(); while(si != sj) { os << *si << "
"; ++si; } os << "

The Boost path was: " << m_boost_path.string() << "

"; // // extract the boost version number from the boost directory tree, // not from this app (which may have been built from a previous // version): // fileview version_file(m_boost_path / "boost/version.hpp"); static const boost::regex version_regex( "^[[:blank:]]*#[[:blank:]]*define[[:blank:]]+BOOST_VERSION[[:blank:]]+(\\d+)"); boost::cmatch what; if(boost::regex_search(version_file.begin(), version_file.end(), what, version_regex)) { int version = boost::lexical_cast(what.str(1)); os << "

The Boost version is: " << version / 100000 << "." << version / 100 % 1000 << "." << version % 100 << "

\n"; } // // output each license: // i = m_license_data.begin(); j = m_license_data.end(); if(!m_bsl_summary_mode) { // // start with the summary: // os << "

Licence Summary

\n"; while(i != j) { // title: os << "

" << licenses.first[i->first].license_name << "

\n"; // license text: os << "
" << licenses.first[i->first].license_text << "
"; // Copyright holders: os << "

This license is used by " << i->second.authors.size() << " authors and " << i->second.files.size() << " files first].license_name) << "\">(see details)"; os << "

\n"; ++i; } } // // and now the details: // i = m_license_data.begin(); j = m_license_data.end(); int license_index = 0; os << "

Licence Details

\n"; while(i != j) { // title: os << "

first].license_name) << "\">" << licenses.first[i->first].license_name << "

\n"; // license text: os << "
" << licenses.first[i->first].license_text << "
"; if(!m_bsl_summary_mode || (license_index >= 3)) { // Copyright holders: os << "

This license is used by the following " << i->second.authors.size() << " copyright holders:

\n

"; std::set::const_iterator x, y; x = i->second.authors.begin(); y = i->second.authors.end(); while(x != y) { os << *x << "
\n"; ++x; } os << "

\n"; // Files using this license: os << "

This license applies to the following " << i->second.files.size() << " files:

\n

"; std::set::const_iterator m, n; m = i->second.files.begin(); n = i->second.files.end(); while(m != n) { os << split_path(m_boost_path, *m) << "
\n"; ++m; } os << "

\n"; } else { os << "

This license is used by " << i->second.authors.size() << " authors (list omitted for brevity).

\n"; os << "

This license applies to " << i->second.files.size() << " files (list omitted for brevity).

\n"; } ++license_index; ++i; } // // Output list of files not found to be under license control: // os << "

Files With No Recognisable Licence

\n" "

The following " << m_unknown_licenses.size() << " files had no recognisable license information:

\n"; std::set::const_iterator i2, j2; i2 = m_unknown_licenses.begin(); j2 = m_unknown_licenses.end(); while(i2 != j2) { os << split_path(m_boost_path, *i2) << "
\n"; ++i2; } os << "

"; // // Output list of files with no found copyright holder: // os << "

Files With No Recognisable Copyright Holder

\n" "

The following " << m_unknown_authors.size() << " files had no recognisable copyright holder:

\n

"; i2 = m_unknown_authors.begin(); j2 = m_unknown_authors.end(); while(i2 != j2) { os << split_path(m_boost_path, *i2) << "
\n"; ++i2; } os << "

"; if(!m_bsl_summary_mode) { // // Output list of files that have been moved over to the Boost // Software License, along with enough information for human // verification. // os << "

Files that can be automatically converted to the Boost Software License

\n" << "

The following " << m_converted_to_bsl.size() << " files can be automatically converted to the Boost Software License, but require manual verification before they can be committed to CVS:

\n"; if (!m_converted_to_bsl.empty()) { typedef std::map, path_less> ::const_iterator conv_iterator; conv_iterator i = m_converted_to_bsl.begin(), ie = m_converted_to_bsl.end(); int file_num = 1; while (i != ie) { os << "

[" << file_num << "] File: " << split_path(m_boost_path, i->first) << "
\n\n \n \n \n \n
" 
               << i->second.first << "
"
               << i->second.second << "
\n"; ++i; ++file_num; } } // // Output list of files that could be moved over to the Boost Software License // os << "

Files that could be converted to the Boost Software License

\n" "

The following " << m_can_migrate_to_bsl.size() << " files could be manually converted to the Boost Software License, but have not yet been:

\n

"; i2 = m_can_migrate_to_bsl.begin(); j2 = m_can_migrate_to_bsl.end(); while(i2 != j2) { os << split_path(m_boost_path, *i2) << "
\n"; ++i2; } os << "

"; // // Output list of files that can not be moved over to the Boost Software License // os << "

Files that can NOT be converted to the Boost Software License

\n" "

The following " << m_cannot_migrate_to_bsl.size() << " files cannot be converted to the Boost Software License because we need the permission of more authors:

\n

"; i2 = m_cannot_migrate_to_bsl.begin(); j2 = m_cannot_migrate_to_bsl.end(); while(i2 != j2) { os << split_path(m_boost_path, *i2) << "
\n"; ++i2; } os << "

"; // // Output list of authors that we need permission for to move to the BSL // os << "

Authors we need for the BSL

\n" "

Permission of the following authors is needed before we can convert to the Boost Software License. The list of authors that have given their permission is contained in more/blanket-permission.txt.

\n

"; std::copy(m_authors_for_bsl_migration.begin(), m_authors_for_bsl_migration.end(), std::ostream_iterator(os, "
\n")); os << "

"; // // output a table of copyright information: // os << "

Copyright Holder Information

\n"; std::map >::const_iterator ad, ead; ad = m_author_data.begin(); ead = m_author_data.end(); while(ad != ead) { os << "\n"; ++ad; } os << "
" << ad->first << ""; std::set::const_iterator fi, efi; fi = ad->second.begin(); efi = ad->second.end(); while(fi != efi) { os << split_path(m_boost_path, *fi) << " "; ++fi; } os << "
\n"; } // // output file dependency information: // os << "

File Dependency Information

\n";
   std::map::const_iterator dep, last_dep;
   std::set::const_iterator fi, efi;
   fi = m_copy_paths.begin();
   efi = m_copy_paths.end();
   // if in summary mode, just figure out the "bad" files and print those only:
   std::set bad_paths;
   if(m_bsl_summary_mode)
   {
      bad_paths.insert(m_unknown_licenses.begin(), m_unknown_licenses.end());
      bad_paths.insert(m_unknown_authors.begin(), m_unknown_authors.end());
      bad_paths.insert(m_can_migrate_to_bsl.begin(), m_can_migrate_to_bsl.end());
      bad_paths.insert(m_cannot_migrate_to_bsl.begin(), m_cannot_migrate_to_bsl.end());
      typedef std::map, path_less>
         ::const_iterator conv_iterator;
      conv_iterator i = m_converted_to_bsl.begin(), 
                     ie = m_converted_to_bsl.end();
      while(i != ie)
      {
         bad_paths.insert(i->first);
         ++i;
      }
      fi = bad_paths.begin();
      efi = bad_paths.end();
      os << "

For brevity, only files not under the BSL are shown

\n"; } while(fi != efi) { os << split_path(m_boost_path, *fi); dep = m_dependencies.find(*fi); last_dep = m_dependencies.end(); std::set seen_deps; if (dep != last_dep) while(true) { os << " -> "; if(fs::exists(m_boost_path / dep->second)) os << split_path(m_boost_path, dep->second); else if(fs::exists(dep->second)) os << split_path(fs::path(), dep->second); else os << dep->second.string(); if(seen_deps.find(dep->second) != seen_deps.end()) { os << " (Circular dependency!)"; break; // circular dependency!!! } seen_deps.insert(dep->second); last_dep = dep; dep = m_dependencies.find(dep->second); if((dep == m_dependencies.end()) || (0 == compare_paths(dep->second, last_dep->second))) break; } os << "\n"; ++fi; } os << "
\n"; os << "\n"; if(!os) { std::string msg("Error writing to "); msg += m_dest_path.string(); msg += "."; std::runtime_error e(msg); boost::throw_exception(e); } }