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 following:
9 * void bcp_implementation::copy_path(const fs::path& p)
10 * void bcp_implementation::create_path(const fs::path& p)
11 */
12
13#include "bcp_imp.hpp"
14#include "fileview.hpp"
15#include <boost/filesystem/operations.hpp>
16#include <boost/filesystem/fstream.hpp>
17#include <boost/regex.hpp>
18#include <fstream>
19#include <iterator>
20#include <algorithm>
21#include <iostream>
22
23struct get_new_library_name
24{
25 get_new_library_name(const std::string& n) : m_new_name(n) {}
26 template <class I>
27 std::string operator()(const boost::match_results<I>& what)
28 {
29 std::string s = what[0];
30 std::string::size_type n = s.find(s: "boost");
31 if(n == std::string::npos)
32 {
33 s.insert(pos1: 0, str: m_new_name);
34 }
35 else
36 {
37 s.replace(pos: n, n: 5, str: m_new_name);
38 }
39 return s;
40 }
41private:
42 std::string m_new_name;
43};
44
45void bcp_implementation::copy_path(const fs::path& p)
46{
47 assert(!fs::is_directory(m_boost_path / p));
48 if(fs::exists(p: m_dest_path / p))
49 {
50 std::cout << "Copying (and overwriting) file: " << p.string() << "\n";
51 fs::remove(p: m_dest_path / p);
52 }
53 else
54 std::cout << "Copying file: " << p.string() << "\n";
55 //
56 // create the path to the new file if it doesn't already exist:
57 //
58 create_path(p: p.branch_path());
59 //
60 // do text based copy if requested:
61 //
62 if(p.leaf() == "Jamroot")
63 {
64 static std::vector<char> v1, v2;
65 v1.clear();
66 v2.clear();
67 boost::filesystem::ifstream is((m_boost_path / p));
68 std::copy(first: std::istreambuf_iterator<char>(is), last: std::istreambuf_iterator<char>(), result: std::back_inserter(x&: v1));
69
70 static boost::regex libname_matcher;
71 if(libname_matcher.empty())
72 {
73 libname_matcher.assign(p: "boost_");
74 }
75
76 regex_replace(out: std::back_inserter(x&: v2), first: v1.begin(), last: v1.end(), e: libname_matcher, fmt: m_namespace_name + "_");
77 std::swap(x&: v1, y&: v2);
78 v2.clear();
79
80 boost::filesystem::ofstream os;
81 if(m_unix_lines)
82 os.open(p: (m_dest_path / p), mode: std::ios_base::binary | std::ios_base::out);
83 else
84 os.open(p: (m_dest_path / p), mode: std::ios_base::out);
85 os.write(s: &*v1.begin(), n: v1.size());
86 os.close();
87 }
88 else if(m_namespace_name.size() && m_lib_names.size() && is_jam_file(p))
89 {
90 static std::vector<char> v1, v2;
91 v1.clear();
92 v2.clear();
93 boost::filesystem::ifstream is((m_boost_path / p));
94 std::copy(first: std::istreambuf_iterator<char>(is), last: std::istreambuf_iterator<char>(), result: std::back_inserter(x&: v1));
95
96 static boost::regex libname_matcher;
97 if(libname_matcher.empty())
98 {
99 std::string re = "\\<";
100 re += *m_lib_names.begin();
101 for(std::set<std::string>::const_iterator i = ++m_lib_names.begin(); i != m_lib_names.end(); ++i)
102 {
103 re += "|" + *i;
104 }
105 re += "\\>";
106 libname_matcher.assign(s: re);
107 }
108
109 regex_replace(out: std::back_inserter(x&: v2), first: v1.begin(), last: v1.end(), e: libname_matcher, fmt: get_new_library_name(m_namespace_name));
110 std::swap(x&: v1, y&: v2);
111 v2.clear();
112
113 boost::filesystem::ofstream os;
114 if(m_unix_lines)
115 os.open(p: (m_dest_path / p), mode: std::ios_base::binary | std::ios_base::out);
116 else
117 os.open(p: (m_dest_path / p), mode: std::ios_base::out);
118 os.write(s: &*v1.begin(), n: v1.size());
119 os.close();
120 }
121 else if(m_namespace_name.size() && is_source_file(p))
122 {
123 //
124 // v1 hold the current content, v2 is temp buffer.
125 // Each time we do a search and replace the new content
126 // ends up in v2: we then swap v1 and v2, and clear v2.
127 //
128 static std::vector<char> v1, v2;
129 v1.clear();
130 v2.clear();
131 boost::filesystem::ifstream is((m_boost_path / p));
132 std::copy(first: std::istreambuf_iterator<char>(is), last: std::istreambuf_iterator<char>(), result: std::back_inserter(x&: v1));
133
134 static const boost::regex namespace_matcher(
135 "(?|"
136 "(namespace\\s+)boost(_\\w+)?(?:(\\s*::\\s*)phoenix)?"
137 "|"
138 "(namespace\\s+(?:detail::)?)(adstl|phoenix|rapidxml)\\>"
139 "|"
140 "()\\<boost((?:_(?!intrusive_tags)\\w+)?\\s*(?:::))(?:(\\s*)phoenix)?"
141 "|"
142 "()\\<((?:adstl|phoenix|rapidxml)\\s*(?:::))"
143 "|"
144 "(namespace\\s+\\w+\\s*=\\s*(?:::\\s*)?)boost(_\\w+)?(?:(\\s*::\\s*)phoenix)?"
145 "|"
146 "(namespace\\s+\\w+\\s*=\\s*(?:::\\s*)?(?:\\w+\\s*::\\s*)?)(adstl|phoenix|rapidxml)\\>"
147 "|"
148 "(^\\s*#\\s*define\\s+\\w+\\s+)boost((?:_\\w+)?\\s*)$"
149 "|"
150 "(^\\s*#\\s*define[^\\n]+)((?:adstl|phoenix|rapidxml)\\s*)$"
151 "|"
152 "()boost(_asio_detail_posix_thread_function|_regex_free_static_mutex)"
153 "|"
154 "()\\<(lw_thread_routine|at_thread_exit|on_process_enter|on_process_exit|on_thread_enter|on_thread_exit|tss_cleanup_implemented)\\>"
155 "|"
156 "(BOOST_CLASS_REQUIRE4?[^;]*)boost((?:_\\w+)?\\s*,)"
157 "|"
158 "(::tr1::|TR1_DECL\\s+)boost(_\\w+\\s*)" // math tr1
159 "|"
160 "(\\(\\s*)boost(\\s*\\))\\s*(\\(\\s*)phoenix(\\s*\\))"
161 "|"
162 "(\\(\\s*)boost(\\s*\\))"
163 ")"
164 );
165
166 regex_replace(out: std::back_inserter(x&: v2), first: v1.begin(), last: v1.end(), e: namespace_matcher, fmt: "$1" + m_namespace_name + "$2(?3$3" + m_namespace_name + "phoenix?4$4)", flags: boost::regex_constants::format_all);
167 std::swap(x&: v1, y&: v2);
168 v2.clear();
169
170 if(m_namespace_alias)
171 {
172 static const boost::regex namespace_alias(
173 /*
174 "namespace\\s+" + m_namespace_name +
175 "\\s*"
176 "("
177 "\\{"
178 "(?:"
179 "(?>[^\\{\\}/]+)"
180 "(?>"
181 "(?:"
182 "(?1)"
183 "|//[^\\n]+$"
184 "|/[^/]"
185 "|(?:^\\s*#[^\\n]*"
186 "(?:(?<=\\\\)\\n[^\\n]*)*)"
187 ")"
188 "[^\\{\\}]+"
189 ")*"
190 ")*"
191 "\\}"
192 ")"
193 */
194 /*
195 "(namespace\\s+" + m_namespace_name +
196 "\\s*\\{.*"
197 "\\})([^\\{\\};]*)\\z"
198 */
199 "(namespace)(\\s+)(" + m_namespace_name + ")"
200 "(adstl|phoenix|rapidxml)?(\\s*\\{)"
201 );
202 regex_replace(out: std::back_inserter(x&: v2), first: v1.begin(), last: v1.end(), e: namespace_alias,
203 fmt: "$1 $3$4 {} $1 (?4$4:boost) = $3$4; $1$2$3$4$5", flags: boost::regex_constants::format_all);
204 std::swap(x&: v1, y&: v2);
205 v2.clear();
206 }
207
208 boost::filesystem::ofstream os;
209 if(m_unix_lines)
210 os.open(p: (m_dest_path / p), mode: std::ios_base::binary | std::ios_base::out);
211 else
212 os.open(p: (m_dest_path / p), mode: std::ios_base::out);
213 if(v1.size())
214 os.write(s: &*v1.begin(), n: v1.size());
215 os.close();
216 }
217 else if(m_unix_lines && !is_binary_file(p))
218 {
219 boost::filesystem::ifstream is((m_boost_path / p));
220 std::istreambuf_iterator<char> isi(is);
221 std::istreambuf_iterator<char> end;
222
223 boost::filesystem::ofstream os((m_dest_path / p), std::ios_base::binary | std::ios_base::out);
224 std::ostreambuf_iterator<char> osi(os);
225
226 std::copy(first: isi, last: end, result: osi);
227 }
228 else
229 {
230 // binary copy:
231 fs::copy_file(from: m_boost_path / p, to: m_dest_path / p);
232 }
233}
234
235void bcp_implementation::create_path(const fs::path& p)
236{
237 if(!fs::exists(p: m_dest_path / p))
238 {
239 // recurse then create the path:
240 create_path(p: p.branch_path());
241 fs::create_directory(p: m_dest_path / p);
242 }
243}
244
245
246

source code of boost/tools/bcp/copy_path.cpp