Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: downloads/boost_1_33_1/tools/bcp/output_licence_info.cpp @ 12

Last change on this file since 12 was 12, checked in by landauf, 17 years ago

added boost

File size: 14.5 KB
Line 
1/*
2 *
3 * Copyright (c) 2003 Dr John Maddock
4 * Use, modification and distribution is subject to the
5 * Boost Software License, Version 1.0. (See accompanying file
6 * LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
7 *
8 */
9
10#include "licence_info.hpp"
11#include "bcp_imp.hpp"
12#include "fileview.hpp"
13#include <fstream>
14#include <iomanip>
15#include <cstring>
16#include <stdexcept>
17#include <boost/lexical_cast.hpp>
18#include <boost/filesystem/operations.hpp>
19#include <boost/throw_exception.hpp>
20
21//
22// split_path is a small helper for outputting a path name,
23// complete with a link to that path:
24//
25struct split_path
26{
27   const fs::path& root;
28   const fs::path& file;
29   split_path(const fs::path& r, const fs::path& f)
30      : root(r), file(f){}
31};
32
33std::ostream& operator << (std::ostream& os, const split_path& p)
34{
35   os << "<a href=\"" << (p.root / p.file).string() << "\">" << p.file.string() << "</a>";
36   return os;
37}
38
39std::string make_link_target(const std::string& s)
40{
41   // convert an arbitrary string into something suitable
42   // for an <a> name:
43   std::string result;
44   for(unsigned i = 0; i < s.size(); ++i)
45   {
46      result.append(1, static_cast<std::string::value_type>(std::isalnum(s[i]) ? s[i] : '_'));
47   }
48   return result;
49}
50
51
52void bcp_implementation::output_license_info()
53{
54   std::pair<const license_info*, int> licenses = get_licenses();
55
56   std::map<int, license_data>::const_iterator i, j;
57   i = m_license_data.begin();
58   j = m_license_data.end();
59
60   std::ofstream os(m_dest_path.native_file_string().c_str());
61   if(!os)
62   {
63      std::string msg("Error opening ");
64      msg += m_dest_path.string();
65      msg += " for output.";
66      std::runtime_error e(msg);
67      boost::throw_exception(e);
68   }
69   os << 
70      "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.0 Transitional//EN\">\n"
71      "<html>\n"
72      "<head>\n"
73      "<title>Boost Licence Dependency Information";
74   if(m_module_list.size() == 1)
75   {
76      os << " for " << *(m_module_list.begin());
77   }
78   os << 
79      "</title>\n"
80      "</head>\n"
81      "<body>\n"
82      "<H1>Boost Licence Dependency Information";
83   if(m_module_list.size() == 1)
84   {
85      os << " for " << *(m_module_list.begin());
86   }
87   os << 
88      "</H1>\n"
89      "<H2>Contents</h2>\n"
90      "<pre><a href=\"#input\">Input Information</a>\n";
91   if(!m_bsl_summary_mode)
92      os << "<a href=\"#summary\">Licence Summary</a>\n";
93   os << "<a href=\"#details\">Licence Details</a>\n";
94
95   while(i != j)
96   {
97      // title:
98      os << "   <A href=\"#" << make_link_target(licenses.first[i->first].license_name) 
99         << "\">" << licenses.first[i->first].license_name << "</a>\n";
100      ++i;
101   }
102
103   os << "<a href=\"#files\">Files with no recognised license</a>\n"
104      "<a href=\"#authors\">Files with no recognised copyright holder</a>\n";
105   if(!m_bsl_summary_mode)
106   {
107      os <<
108      "Moving to the Boost Software License...\n"
109      "  <a href=\"#bsl-converted\">Files that can be automatically converted to the Boost Software License</a>\n"
110      "  <a href=\"#to-bsl\">Files that can be manually converted to the Boost Software License</a>\n"
111      "  <a href=\"#not-to-bsl\">Files that can <b>NOT</b> be moved to the Boost Software License</a>\n"
112      "  <a href=\"#need-bsl-authors\">Authors we need to move to the Boost Software License</a>\n"
113      "<a href=\"#copyright\">Copyright Holder Information</a>\n";
114   }
115   os << 
116      "<a href=\"#depend\">File Dependency Information</a>\n"
117      "</pre>";
118
119   //
120   // input Information:
121   //
122   os << "<a name=\"input\"></a><h2>Input Information</h2>\n";
123   if(m_scan_mode)
124      os << "<P>The following files were scanned for boost dependencies:<BR>";
125   else
126      os << "<P>The following Boost modules were checked:<BR>";
127
128   std::list<std::string>::const_iterator si = m_module_list.begin();
129   std::list<std::string>::const_iterator sj = m_module_list.end();
130   while(si != sj)
131   {
132      os << *si << "<BR>";
133      ++si;
134   }
135   os << "</p><p>The Boost path was: <code>" << m_boost_path.string() << "</code></P>";
136   //
137   // extract the boost version number from the boost directory tree,
138   // not from this app (which may have been built from a previous
139   // version):
140   //
141   fileview version_file(m_boost_path / "boost/version.hpp");
142   boost::regex version_regex(
143      "^[[:blank:]]*#[[:blank:]]*define[[:blank:]]+BOOST_VERSION[[:blank:]]+(\\d+)");
144   boost::cmatch what;
145   if(boost::regex_search(version_file.begin(), version_file.end(), what, version_regex))
146   {
147      int version = boost::lexical_cast<int>(what.str(1));
148      os << "<p>The Boost version is: " << version / 100000 << "." << version / 100 % 1000 << "." << version % 100 << "</P>\n";
149   }
150
151   //
152   // output each license:
153   //
154   i = m_license_data.begin();
155   j = m_license_data.end();
156   if(!m_bsl_summary_mode)
157   {
158      //
159      // start with the summary:
160      //
161      os << "<a name=\"summary\"></a><h2>Licence Summary</h2>\n";
162      while(i != j)
163      {
164         // title:
165         os << 
166            "<H3>" << licenses.first[i->first].license_name << "</H3>\n";
167         // license text:
168         os << "<BLOCKQUOTE>" << licenses.first[i->first].license_text << "</BLOCKQUOTE>";
169         // Copyright holders:
170         os << "<P>This license is used by " << i->second.authors.size() 
171            << " authors and " << i->second.files.size() 
172            << " files <a href=\"#" << make_link_target(licenses.first[i->first].license_name) << "\">(see details)</a>";
173         os << "</P></BLOCKQUOTE>\n";
174         ++i;
175      }
176   }
177   //
178   // and now the details:
179   //
180   i = m_license_data.begin();
181   j = m_license_data.end();
182   int license_index = 0;
183   os << "<a name=\"details\"></a><h2>Licence Details</h2>\n";
184   while(i != j)
185   {
186      // title:
187      os << 
188         "<H3><A name=\"" << make_link_target(licenses.first[i->first].license_name) 
189         << "\"></a>" << licenses.first[i->first].license_name << "</H3>\n";
190      // license text:
191      os << "<BLOCKQUOTE>" << licenses.first[i->first].license_text << "</BLOCKQUOTE>";
192      if(!m_bsl_summary_mode || (license_index >= 3))
193      {
194         // Copyright holders:
195         os << "<P>This license is used by the following " << i->second.authors.size() << " copyright holders:</P>\n<BLOCKQUOTE><P>";
196         std::set<std::string>::const_iterator x, y;
197         x = i->second.authors.begin();
198         y = i->second.authors.end();
199         while(x != y)
200         {
201            os << *x << "<BR>\n";
202            ++x;
203         }
204         os << "</P></BLOCKQUOTE>\n";
205         // Files using this license:
206         os << "<P>This license applies to the following " << i->second.files.size() << " files:</P>\n<BLOCKQUOTE><P>";
207         std::set<fs::path, path_less>::const_iterator m, n;
208         m = i->second.files.begin();
209         n = i->second.files.end();
210         while(m != n)
211         {
212            os << split_path(m_boost_path, *m) << "<br>\n";
213            ++m;
214         }
215         os << "</P></BLOCKQUOTE>\n";
216      }
217      else
218      {
219         os << "<P>This license is used by " << i->second.authors.size() << " authors (list omitted for brevity).</P>\n";
220         os << "<P>This license applies to " << i->second.files.size() << " files (list omitted for brevity).</P>\n";
221      }
222      ++license_index;
223      ++i;
224   }
225   //
226   // Output list of files not found to be under license control:
227   //
228   os << "<h2><a name=\"files\"></a>Files With No Recognisable Licence</h2>\n"
229      "<P>The following " << m_unknown_licenses.size() << " files had no recognisable license information:</P><BLOCKQUOTE><P>\n";
230   std::set<fs::path, path_less>::const_iterator i2, j2;
231   i2 = m_unknown_licenses.begin();
232   j2 = m_unknown_licenses.end();
233   while(i2 != j2)
234   {
235      os << split_path(m_boost_path, *i2) << "<br>\n";
236      ++i2;
237   }
238   os << "</p></BLOCKQUOTE>";
239   //
240   // Output list of files with no found copyright holder:
241   //
242   os << "<h2><a name=\"authors\"></a>Files With No Recognisable Copyright Holder</h2>\n"
243      "<P>The following " << m_unknown_authors.size() << " files had no recognisable copyright holder:</P>\n<BLOCKQUOTE><P>";
244   i2 = m_unknown_authors.begin();
245   j2 = m_unknown_authors.end();
246   while(i2 != j2)
247   {
248      os << split_path(m_boost_path, *i2) << "<br>\n";
249      ++i2;
250   }
251   os << "</p></BLOCKQUOTE>";
252   if(!m_bsl_summary_mode)
253   {
254      //
255      // Output list of files that have been moved over to the Boost
256      // Software License, along with enough information for human
257      // verification.
258      //
259      os << "<h2><a name=\"bsl-converted\"></a>Files that can be automatically converted to the Boost Software License</h2>\n"
260         << "<P>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:</P>\n";
261      if (!m_converted_to_bsl.empty()) 
262      {
263         typedef std::map<fs::path, std::pair<std::string, std::string>, path_less>
264            ::const_iterator conv_iterator;
265         conv_iterator i = m_converted_to_bsl.begin(), 
266                        ie = m_converted_to_bsl.end();
267         int file_num = 1;
268         while (i != ie) 
269         {
270            os << "<P>[" << file_num << "] File: <tt>" << split_path(m_boost_path, i->first) 
271               << "</tt><br>\n<table border=\"1\">\n  <tr>\n    <td><pre>" 
272               << i->second.first << "</pre></td>\n    <td><pre>"
273               << i->second.second << "</pre></td>\n  </tr>\n</table>\n";
274            ++i;
275            ++file_num;
276         }
277      }
278      //
279      // Output list of files that could be moved over to the Boost Software License
280      //
281      os << "<h2><a name=\"to-bsl\"></a>Files that could be converted to the Boost Software License</h2>\n"
282      "<P>The following " << m_can_migrate_to_bsl.size() << " files could be manually converted to the Boost Software License, but have not yet been:</P>\n<BLOCKQUOTE><P>";
283      i2 = m_can_migrate_to_bsl.begin();
284      j2 = m_can_migrate_to_bsl.end();
285      while(i2 != j2)
286      {
287         os << split_path(m_boost_path, *i2) << "<br>\n";
288         ++i2;
289      }
290      os << "</p></BLOCKQUOTE>";
291      //
292      // Output list of files that can not be moved over to the Boost Software License
293      //
294      os << "<h2><a name=\"not-to-bsl\"></a>Files that can NOT be converted to the Boost Software License</h2>\n"
295      "<P>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:</P>\n<BLOCKQUOTE><P>";
296      i2 = m_cannot_migrate_to_bsl.begin();
297      j2 = m_cannot_migrate_to_bsl.end();
298      while(i2 != j2)
299      {
300         os << split_path(m_boost_path, *i2) << "<br>\n";
301         ++i2;
302      }
303      os << "</p></BLOCKQUOTE>";
304      //
305      // Output list of authors that we need permission for to move to the BSL
306      //
307      os << "<h2><a name=\"need-bsl-authors\"></a>Authors we need for the BSL</h2>\n"
308         "<P>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 <code>more/blanket-permission.txt</code>.</P>\n<BLOCKQUOTE><P>";
309      std::copy(m_authors_for_bsl_migration.begin(), m_authors_for_bsl_migration.end(),
310               std::ostream_iterator<std::string>(os, "<br>\n"));
311      os << "</p></BLOCKQUOTE>";
312      //
313      // output a table of copyright information:
314      //
315      os << "<H2><a name=\"copyright\"></a>Copyright Holder Information</H2><table border=\"1\">\n";
316      std::map<std::string, std::set<fs::path, path_less> >::const_iterator ad, ead; 
317      ad = m_author_data.begin();
318      ead = m_author_data.end();
319      while(ad != ead)
320      {
321         os << "<tr><td>" << ad->first << "</td><td>";
322         std::set<fs::path, path_less>::const_iterator fi, efi;
323         fi = ad->second.begin();
324         efi = ad->second.end();
325         while(fi != efi)
326         {
327            os << split_path(m_boost_path, *fi) << " ";
328            ++fi;
329         }
330         os << "</td></tr>\n";
331         ++ad;
332      }
333      os << "</table>\n";
334   }
335
336   //
337   // output file dependency information:
338   //
339   os << "<H2><a name=\"depend\"></a>File Dependency Information</H2><BLOCKQUOTE><pre>\n";
340   std::map<fs::path, fs::path, path_less>::const_iterator dep, last_dep;
341   std::set<fs::path, path_less>::const_iterator fi, efi;
342   fi = m_copy_paths.begin();
343   efi = m_copy_paths.end();
344   // if in summary mode, just figure out the "bad" files and print those only:
345   std::set<fs::path, path_less> bad_paths;
346   if(m_bsl_summary_mode)
347   {
348      bad_paths.insert(m_unknown_licenses.begin(), m_unknown_licenses.end());
349      bad_paths.insert(m_unknown_authors.begin(), m_unknown_authors.end());
350      bad_paths.insert(m_can_migrate_to_bsl.begin(), m_can_migrate_to_bsl.end());
351      bad_paths.insert(m_cannot_migrate_to_bsl.begin(), m_cannot_migrate_to_bsl.end());
352      typedef std::map<fs::path, std::pair<std::string, std::string>, path_less>
353         ::const_iterator conv_iterator;
354      conv_iterator i = m_converted_to_bsl.begin(), 
355                     ie = m_converted_to_bsl.end();
356      while(i != ie)
357      {
358         bad_paths.insert(i->first);
359         ++i;
360      }
361      fi = bad_paths.begin();
362      efi = bad_paths.end();
363      os << "<P>For brevity, only files not under the BSL are shown</P>\n";
364   }
365   while(fi != efi)
366   {
367      os << split_path(m_boost_path, *fi);
368      dep = m_dependencies.find(*fi);
369      last_dep = m_dependencies.end();
370      std::set<fs::path, path_less> seen_deps;
371      if (dep != last_dep) 
372        while(true)
373          {
374            os << " -> ";
375            if(fs::exists(m_boost_path / dep->second))
376              os << split_path(m_boost_path, dep->second);
377            else if(fs::exists(dep->second))
378              os << split_path(fs::path(), dep->second);
379            else
380              os << dep->second.string();
381            if(seen_deps.find(dep->second) != seen_deps.end())
382              {
383                os << " <I>(Circular dependency!)</I>";
384                break; // circular dependency!!!
385              }
386            seen_deps.insert(dep->second);
387            last_dep = dep;
388            dep = m_dependencies.find(dep->second);
389            if((dep == m_dependencies.end()) || (0 == compare_paths(dep->second, last_dep->second)))
390              break;
391          }
392      os << "\n";
393      ++fi;
394   }
395   os << "</pre></BLOCKQUOTE>\n";
396
397   os << "</body></html>\n";
398
399   if(!os)
400   {
401      std::string msg("Error writing to ");
402      msg += m_dest_path.string();
403      msg += ".";
404      std::runtime_error e(msg);
405      boost::throw_exception(e);
406   }
407
408}
Note: See TracBrowser for help on using the repository browser.