Imported Upstream version 1.72.0
[platform/upstream/boost.git] / tools / bcp / bcp_imp.cpp
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  * This file implements the bcp_implementation virtuals.
9  */
10
11 #include "bcp_imp.hpp"
12 #include "licence_info.hpp"
13 #include <boost/filesystem/operations.hpp>
14 #include <boost/filesystem/fstream.hpp>
15 #include <iostream>
16 #include <stdexcept>
17 #include <boost/regex.hpp>
18 #include <string>
19
20 bcp_implementation::bcp_implementation()
21   : m_list_mode(false), m_list_summary_mode(false), m_license_mode(false), m_cvs_mode(false), 
22   m_svn_mode(false), m_unix_lines(false), m_scan_mode(false), m_bsl_convert_mode(false), 
23   m_bsl_summary_mode(false), m_namespace_alias(false), m_list_namespaces(false)
24 {
25 }
26
27 bcp_implementation::~bcp_implementation()
28 {
29 }
30
31 bcp_application::~bcp_application()
32 {
33 }
34
35 void bcp_implementation::enable_list_mode()
36 {
37    m_list_mode = true;
38 }
39
40 void bcp_implementation::enable_summary_list_mode()
41 {
42    m_list_mode = true;
43    m_list_summary_mode = true;
44 }
45
46 void bcp_implementation::enable_cvs_mode()
47 {
48    m_cvs_mode = true;
49 }
50
51 void bcp_implementation::enable_svn_mode()
52 {
53    m_svn_mode = true;
54 }
55
56 void bcp_implementation::enable_scan_mode()
57 {
58    m_scan_mode = true;
59 }
60
61 void bcp_implementation::enable_license_mode()
62 {
63    m_license_mode = true;
64 }
65
66 void bcp_implementation::enable_bsl_convert_mode()
67 {
68    m_bsl_convert_mode = true;
69 }
70
71 void bcp_implementation::enable_bsl_summary_mode()
72 {
73    m_bsl_summary_mode = true;
74 }
75
76 void bcp_implementation::enable_unix_lines()
77 {
78    m_unix_lines = true;
79 }
80
81 void bcp_implementation::set_boost_path(const char* p)
82 {
83    // Hack to strip trailing slashes from the path 
84    m_boost_path = (fs::path(p) / "boost").parent_path(); 
85    fs::path check = m_boost_path / "boost" / "version.hpp";
86    if(!fs::exists(check))
87    {
88       std::string s = "The Boost path appears to have been incorrectly set: could not find boost/version.hpp in ";
89       s += m_boost_path.string();
90       std::runtime_error e(s);
91       throw e;
92    }
93 }
94
95 void bcp_implementation::set_destination(const char* p)
96 {
97    m_dest_path = fs::path(p);
98 }
99
100 void bcp_implementation::add_module(const char* p)
101 {
102    m_module_list.push_back(p);
103 }
104
105 void bcp_implementation::set_namespace(const char* name)
106 {
107    m_namespace_name = name;
108 }
109
110 void bcp_implementation::set_namespace_alias(bool b)
111 {
112    m_namespace_alias = b;
113 }
114
115 void bcp_implementation::set_namespace_list(bool b)
116 {
117    m_list_namespaces = b;
118    m_list_mode = b;
119 }
120
121 fs::path get_short_path(const fs::path& p)
122 {
123    // truncate path no more than "x/y":
124    std::string s = p.generic_string();
125    std::string::size_type n = s.find('/');
126    if(n != std::string::npos)
127    {
128       n = s.find('/', n+1);
129       if(n != std::string::npos)
130          s.erase(n);
131    }
132    return s;
133 }
134
135 int bcp_implementation::run()
136 {
137    //
138    // check output path is OK:
139    //
140    if(!m_list_mode && !m_license_mode && !fs::exists(m_dest_path))
141    {
142       std::string msg("Destination path does not exist: ");
143       msg.append(m_dest_path.string());
144       std::runtime_error e(msg);
145       boost::throw_exception(e);
146    }
147    //
148    // Check Boost path is OK if it hasn't been checked already:
149    //
150    if(m_boost_path == "")
151    {
152       set_boost_path("");
153    }
154    // start by building a list of permitted files
155    // if m_cvs_mode is true:
156    if(m_cvs_mode)
157    {
158       std::cerr << "CAUTION: Boost is no longer in CVS, cvs mode may not work anymore!!!" << std::endl;
159       scan_cvs_path(fs::path());
160    }
161    if(m_svn_mode)
162    {
163       scan_svn_path(fs::path());
164    }
165    //
166    // if in license mode, try to load more/blanket_permission.txt
167    //
168    fs::path blanket_permission(m_boost_path / "more" / "blanket-permission.txt");
169    if (fs::exists(blanket_permission)) {
170      fs::ifstream in(blanket_permission);
171      std::string line;
172      while (std::getline(in, line)) {
173        static const boost::regex e("([^(]+)\\(");
174        boost::smatch result;
175        if (boost::regex_search(line, result, e))
176          m_bsl_authors.insert(format_authors_name(result[1]));
177      }
178    }
179
180    //
181    // scan through modules looking for the equivalent
182    // file to add to our list:
183    //
184    std::list<std::string>::const_iterator i = m_module_list.begin();
185    std::list<std::string>::const_iterator j = m_module_list.end();
186    while(i != j)
187    {
188       //
189       // convert *i to a path - could be native or portable:
190       //
191       fs::path module;
192       fs::path exmodule;
193       module = fs::path(*i);
194       exmodule = fs::path(*i + ".hpp");
195       
196       if(m_scan_mode)
197       {
198          // in scan mode each module must be a real file:
199          add_file_dependencies(module, true);
200       }
201       else
202       {
203          int count = 0;
204          if(fs::exists(m_boost_path / "tools" / module))
205          {
206             add_path(fs::path("tools") / module);
207             ++count;
208          }
209          if(fs::exists(m_boost_path / "libs" / module))
210          {
211             add_path(fs::path("libs") / module);
212             ++count;
213          }
214          if(fs::exists(m_boost_path / "boost" / module))
215          {
216             add_path(fs::path("boost") / module);
217             ++count;
218          }
219          if(fs::exists(m_boost_path / "boost" / exmodule))
220          {
221             add_path(fs::path("boost") / exmodule);
222             ++count;
223          }
224          if(fs::exists(m_boost_path / module))
225          {
226             add_path(module);
227             ++count;
228          }
229       }
230       ++i;
231    }
232    while (!m_pending_paths.empty())
233    {
234       add_path(m_pending_paths.front());
235       m_pending_paths.pop();
236    }
237    //
238    // now perform output:
239    //
240    if(m_list_namespaces)
241    {
242       // List the namespaces, in two lists, headers and source files
243       // first, then everything else afterwards:
244       //
245       boost::regex important_file("boost/.*|libs/[^/]*/(?:[^/]*/)?/src/.*");
246       std::map<std::string, fs::path>::const_iterator i, j;
247       i = m_top_namespaces.begin();
248       j = m_top_namespaces.end();
249       std::cout << "\n\nThe top level namespaces found for header and source files were:\n";
250       while(i != j)
251       {
252          if(regex_match(i->second.generic_string(), important_file))
253             std::cout << i->first << " (from " << i->second << ")" << std::endl;
254          ++i;
255       }
256
257       i = m_top_namespaces.begin();
258       std::cout << "\n\nThe top level namespaces found for all other source files were:\n";
259       while(i != j)
260       {
261          if(!regex_match(i->second.generic_string(), important_file))
262             std::cout << i->first << " (from " << i->second << ")" << std::endl;
263          ++i;
264       }
265       return 0;
266    }
267    std::set<fs::path, path_less>::iterator m, n;
268    std::set<fs::path, path_less> short_paths;
269    m = m_copy_paths.begin();
270    n = m_copy_paths.end();
271    if(!m_license_mode)
272    {
273       while(m != n)
274       {
275          if(m_list_summary_mode)
276          {
277             fs::path p = get_short_path(*m);
278             if(short_paths.find(p) == short_paths.end())
279             {
280                short_paths.insert(p);
281                std::cout << p.string() << "\n";
282             }
283          }
284          else if(m_list_mode)
285             std::cout << m->string() << "\n";
286          else
287             copy_path(*m);
288          ++m;
289       }
290    }
291    else
292       output_license_info();
293    return 0;
294 }
295
296 pbcp_application bcp_application::create()
297 {
298    pbcp_application result(static_cast<bcp_application*>(new bcp_implementation()));
299    return result;
300 }