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)
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)
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 <boost/assert.hpp>
24 struct get_new_library_name
26 get_new_library_name(const std::string& n) : m_new_name(n) {}
28 std::string operator()(const boost::match_results<I>& what)
30 std::string s = what[0];
31 std::string::size_type n = s.find("boost");
32 if(n == std::string::npos)
34 s.insert(0, m_new_name);
38 s.replace(n, 5, m_new_name);
43 std::string m_new_name;
46 void bcp_implementation::copy_path(const fs::path& p)
48 BOOST_ASSERT(!fs::is_directory(m_boost_path / p));
49 if(fs::exists(m_dest_path / p))
51 std::cout << "Copying (and overwriting) file: " << p.string() << "\n";
52 fs::remove(m_dest_path / p);
55 std::cout << "Copying file: " << p.string() << "\n";
57 // create the path to the new file if it doesn't already exist:
59 create_path(p.branch_path());
61 // do text based copy if requested:
63 if((p.leaf() == "Jamroot") && m_namespace_name.size())
65 static std::vector<char> v1, v2;
68 boost::filesystem::ifstream is((m_boost_path / p));
69 std::copy(std::istreambuf_iterator<char>(is), std::istreambuf_iterator<char>(), std::back_inserter(v1));
71 static boost::regex libname_matcher;
72 if(libname_matcher.empty())
74 libname_matcher.assign("boost_");
77 regex_replace(std::back_inserter(v2), v1.begin(), v1.end(), libname_matcher, m_namespace_name + "_");
81 boost::filesystem::ofstream os;
83 os.open((m_dest_path / p), std::ios_base::binary | std::ios_base::out);
85 os.open((m_dest_path / p), std::ios_base::out);
86 os.write(&*v1.begin(), v1.size());
89 else if(m_namespace_name.size() && m_lib_names.size() && is_jam_file(p))
91 static std::vector<char> v1, v2;
94 boost::filesystem::ifstream is((m_boost_path / p));
95 std::copy(std::istreambuf_iterator<char>(is), std::istreambuf_iterator<char>(), std::back_inserter(v1));
97 static boost::regex libname_matcher;
98 if(libname_matcher.empty())
100 std::string re = "\\<";
101 re += *m_lib_names.begin();
102 for(std::set<std::string>::const_iterator i = ++m_lib_names.begin(); i != m_lib_names.end(); ++i)
107 libname_matcher.assign(re);
110 regex_replace(std::back_inserter(v2), v1.begin(), v1.end(), libname_matcher, get_new_library_name(m_namespace_name));
114 boost::filesystem::ofstream os;
116 os.open((m_dest_path / p), std::ios_base::binary | std::ios_base::out);
118 os.open((m_dest_path / p), std::ios_base::out);
119 os.write(&*v1.begin(), v1.size());
122 else if(m_namespace_name.size() && is_source_file(p))
125 // v1 hold the current content, v2 is temp buffer.
126 // Each time we do a search and replace the new content
127 // ends up in v2: we then swap v1 and v2, and clear v2.
129 static std::vector<char> v1, v2;
132 boost::filesystem::ifstream is((m_boost_path / p));
133 std::copy(std::istreambuf_iterator<char>(is), std::istreambuf_iterator<char>(), std::back_inserter(v1));
135 static const boost::regex namespace_matcher(
137 "(namespace\\s+)boost(_\\w+)?(?:(\\s*::\\s*)phoenix)?"
139 "(namespace\\s+(?:detail::)?)(adstl|phoenix|rapidxml)\\>"
141 "()\\<boost((?:_(?!intrusive_tags)\\w+)?\\s*(?:::))(?:(\\s*)phoenix)?"
143 "()\\<((?:adstl|phoenix|rapidxml)\\s*(?:::))"
145 "(namespace\\s+\\w+\\s*=\\s*(?:::\\s*)?)boost(_\\w+)?(?:(\\s*::\\s*)phoenix)?"
147 "(namespace\\s+\\w+\\s*=\\s*(?:::\\s*)?(?:\\w+\\s*::\\s*)?)(adstl|phoenix|rapidxml)\\>"
149 "(^\\s*#\\s*define\\s+\\w+\\s+)boost((?:_\\w+)?\\s*)$"
151 "(^\\s*#\\s*define[^\\n]+)((?:adstl|phoenix|rapidxml)\\s*)$"
153 "()boost(_asio_detail_posix_thread_function|_regex_free_static_mutex)"
155 "()\\<(lw_thread_routine|at_thread_exit|on_process_enter|on_process_exit|on_thread_enter|on_thread_exit|tss_cleanup_implemented)\\>"
157 "(BOOST_CLASS_REQUIRE4?[^;]*)boost((?:_\\w+)?\\s*,)"
159 "(::tr1::|TR1_DECL\\s+)boost(_\\w+\\s*)" // math tr1
161 "(\\(\\s*)boost(\\s*\\))\\s*(\\(\\s*)phoenix(\\s*\\))"
163 "(\\(\\s*)boost(\\s*\\))"
165 "(BOOST_UNORDERED_CONSTRUCT_FROM_TUPLE[^\\)]*)boost(\\))"
169 regex_replace(std::back_inserter(v2), v1.begin(), v1.end(), namespace_matcher, "$1" + m_namespace_name + "$2(?3$3" + m_namespace_name + "phoenix?4$4)", boost::regex_constants::format_all);
173 if(m_namespace_alias)
175 static const boost::regex namespace_alias(
177 "namespace\\s+" + m_namespace_name +
189 "(?:(?<=\\\\)\\n[^\\n]*)*)"
198 "(namespace\\s+" + m_namespace_name +
200 "\\})([^\\{\\};]*)\\z"
202 "(namespace)(\\s+)(" + m_namespace_name + ")"
203 "(adstl|phoenix|rapidxml)?(\\s*\\{)"
205 regex_replace(std::back_inserter(v2), v1.begin(), v1.end(), namespace_alias,
206 "$1 $3$4 {} $1 (?4$4:boost) = $3$4; $1$2$3$4$5", boost::regex_constants::format_all);
211 boost::filesystem::ofstream os;
213 os.open((m_dest_path / p), std::ios_base::binary | std::ios_base::out);
215 os.open((m_dest_path / p), std::ios_base::out);
217 os.write(&*v1.begin(), v1.size());
220 else if(m_unix_lines && !is_binary_file(p))
222 boost::filesystem::ifstream is((m_boost_path / p));
223 std::istreambuf_iterator<char> isi(is);
224 std::istreambuf_iterator<char> end;
226 boost::filesystem::ofstream os((m_dest_path / p), std::ios_base::binary | std::ios_base::out);
227 std::ostreambuf_iterator<char> osi(os);
229 std::copy(isi, end, osi);
234 fs::copy_file(m_boost_path / p, m_dest_path / p);
238 void bcp_implementation::create_path(const fs::path& p)
240 if(!fs::exists(m_dest_path / p))
242 // recurse then create the path:
243 create_path(p.branch_path());
244 fs::create_directory(m_dest_path / p);