diff options
Diffstat (limited to 'src/boost/tools/bcp')
-rw-r--r-- | src/boost/tools/bcp/Jamfile.v2 | 36 | ||||
-rw-r--r-- | src/boost/tools/bcp/README.md | 24 | ||||
-rw-r--r-- | src/boost/tools/bcp/add_dependent_lib.cpp | 230 | ||||
-rw-r--r-- | src/boost/tools/bcp/add_path.cpp | 569 | ||||
-rw-r--r-- | src/boost/tools/bcp/bcp.hpp | 47 | ||||
-rw-r--r-- | src/boost/tools/bcp/bcp_imp.cpp | 300 | ||||
-rw-r--r-- | src/boost/tools/bcp/bcp_imp.hpp | 121 | ||||
-rw-r--r-- | src/boost/tools/bcp/copy_path.cpp | 248 | ||||
-rw-r--r-- | src/boost/tools/bcp/file_types.cpp | 72 | ||||
-rw-r--r-- | src/boost/tools/bcp/fileview.cpp | 143 | ||||
-rw-r--r-- | src/boost/tools/bcp/fileview.hpp | 72 | ||||
-rw-r--r-- | src/boost/tools/bcp/index.html | 17 | ||||
-rw-r--r-- | src/boost/tools/bcp/licence_info.cpp | 721 | ||||
-rw-r--r-- | src/boost/tools/bcp/licence_info.hpp | 39 | ||||
-rw-r--r-- | src/boost/tools/bcp/main.cpp | 183 | ||||
-rw-r--r-- | src/boost/tools/bcp/output_licence_info.cpp | 410 | ||||
-rw-r--r-- | src/boost/tools/bcp/path_operations.cpp | 41 | ||||
-rw-r--r-- | src/boost/tools/bcp/scan_cvs_path.cpp | 147 | ||||
-rw-r--r-- | src/boost/tools/bcp/scan_licence.cpp | 275 | ||||
-rw-r--r-- | src/boost/tools/bcp/test/Jamfile.v2 | 25 |
20 files changed, 3720 insertions, 0 deletions
diff --git a/src/boost/tools/bcp/Jamfile.v2 b/src/boost/tools/bcp/Jamfile.v2 new file mode 100644 index 000000000..b89a15362 --- /dev/null +++ b/src/boost/tools/bcp/Jamfile.v2 @@ -0,0 +1,36 @@ +# (C) Copyright John Maddock 2006. +# Distributed under the Boost Software License, Version 1.0. +# (See accompanying file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt) + +exe bcp + : + add_dependent_lib.cpp add_path.cpp bcp_imp.cpp copy_path.cpp file_types.cpp + fileview.cpp main.cpp path_operations.cpp scan_cvs_path.cpp + licence_info.cpp scan_licence.cpp output_licence_info.cpp + /boost/filesystem//boost_filesystem + /boost/regex//boost_regex + : + : + release + ; + +install dist-bin + : + bcp + : + <install-type>EXE + <location>../../dist/bin + : + release + ; + +install dist-lib + : + bcp + : + <install-type>LIB + <location>../../dist/lib + : + release + ; + diff --git a/src/boost/tools/bcp/README.md b/src/boost/tools/bcp/README.md new file mode 100644 index 000000000..b3f2b4d72 --- /dev/null +++ b/src/boost/tools/bcp/README.md @@ -0,0 +1,24 @@ +BCP Tool [![Build Status](https://travis-ci.org/boostorg/bcp.svg?branch=develop)](https://travis-ci.org/boostorg/bcp) +================== + +The bcp utility is a tool for extracting subsets of Boost, it's useful for Boost authors who want to distribute +their library separately from Boost, and for Boost users who want to distribute a subset of Boost with their application. + +bcp can also report on which parts of Boost your code is dependent on, and what licences are used by those dependencies. + +The full documentation is available on [boost.org](http://www.boost.org/doc/libs/release/tools/bcp). + +| | Master | Develop | +|------------------|----------|-------------| +| Travis | [![Build Status](https://travis-ci.org/boostorg/bcp.svg?branch=master)](https://travis-ci.org/boostorg/bcp) | [![Build Status](https://travis-ci.org/boostorg/bcp.svg)](https://travis-ci.org/boostorg/bcp) | + + + +## Support, bugs and feature requests ## + +Bugs and feature requests can be reported through the [Gitub issue tracker](https://github.com/boostorg/bcp/issues) +(see [open issues](https://github.com/boostorg/bcp/issues) and +[closed issues](https://github.com/boostorg/bcp/issues?utf8=%E2%9C%93&q=is%3Aissue+is%3Aclosed)). + +You can submit your changes through a [pull request](https://github.com/boostorg/bcp/pulls). + diff --git a/src/boost/tools/bcp/add_dependent_lib.cpp b/src/boost/tools/bcp/add_dependent_lib.cpp new file mode 100644 index 000000000..48529142f --- /dev/null +++ b/src/boost/tools/bcp/add_dependent_lib.cpp @@ -0,0 +1,230 @@ +/* + * + * Copyright (c) 2009 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) + * + * This file implements the following: + * void bcp_implementation::add_path(const fs::path& p) + * void bcp_implementation::add_directory(const fs::path& p) + * void bcp_implementation::add_file(const fs::path& p) + * void bcp_implementation::add_dependent_lib(const std::string& libname, const fs::path& p, const fileview& view) + */ + +#include "bcp_imp.hpp" +#include "fileview.hpp" +#include <boost/regex.hpp> +#include <boost/filesystem/operations.hpp> +#include <boost/filesystem/exception.hpp> +#include <iostream> + +// +// This file contains the code required to work out whether the source/header file being scanned +// is actually dependent upon some library's source code or not. +// + +static std::map<std::string, boost::regex> scanner; + +static std::map<std::string, std::set<std::string> > free_function_names; +static std::map<std::string, std::set<std::string> > class_names; +static std::map<std::string, std::set<std::string> > variable_names; + +static void init_library_scanner(const fs::path& p, bool cvs_mode, const std::string& libname, bool recurse = false) +{ + /* + if(free_function_names.count(libname) == 0) + { + free_function_names[libname] = "[\\x0]"; + class_names[libname] = "[\\x0]"; + variable_names[libname] = "[\\x0]"; + } + */ + // + // Don't add files created by build system: + // + if((p.leaf() == "bin") || (p.leaf() == "bin-stage")) + return; + // + // Don't add version control directories: + // + if((p.leaf() == "CVS") || (p.leaf() == ".svn")) + return; + // + // don't add directories not under version control: + // + if(cvs_mode && !fs::exists(p / "CVS/Entries")) + return; + if(cvs_mode && !fs::exists(p / ".svn/entries")) + return; + // + // Enumerate files and directories: + // + fs::directory_iterator i(p); + fs::directory_iterator j; + while(i != j) + { + if(fs::is_directory(*i)) + init_library_scanner(*i, cvs_mode, libname, true); + if(bcp_implementation::is_source_file(*i)) + { + static boost::regex function_scanner( + "(?|" // Branch reset group + "(?:\\<\\w+\\>[^>;{},:]*)" // Return type + "(?:" + "(\\<\\w+\\>)" // Maybe class name + "\\s*" + "(?:<[^>;{]*>)?" // Maybe template specialisation + "::\\s*)?" + "(\\<(?!throw|if|while|for|catch)\\w+\\>)" // function name + "\\s*" + "\\(" + "[^\\(\\);{}]*" // argument list + "\\)" + "\\s*(?:BOOST[_A-Z]+\\s*)?" + "\\{" // start of definition + "|" + "(\\<\\w+\\>)" // Maybe class name + "\\s*" + "(?:<[^>;{]*>)?" // Maybe template specialisation + "::\\s*" + "~?\\1" // function name, same as class name + "\\s*" + "\\(" + "[^\\(\\);{}]*" // argument list + "\\)" + "\\s*(?:BOOST[_A-Z]+\\s*)?" + "\\{" // start of definition + ")" // end branch reset + ); + fileview view(*i); + boost::regex_iterator<const char*> a(view.begin(), view.end(), function_scanner); + boost::regex_iterator<const char*> b; + while(a != b) + { + if((*a)[1].matched) + { + std::string n = a->str(1); + class_names[libname].insert(n); + } + else + { + std::string n = a->str(2); + free_function_names[libname].insert(n); + } + ++a; + } + } + ++i; + } + + if(recurse == false) + { + // + // Build the regular expressions: + // + const char* e1 = + "^(?>[[:blank:]]*)(?!#)[^;{}\\r\\n]*" + "(?|" + "(?:class|struct)[^:;{}#]*" + "("; + // list of class names goes here... + const char* e2 = + ")\\s*(?:<[^;{>]*>\\s*)?(?::[^;{]*)?\\{" + "|" + "\\<(?!return)\\w+\\>[^:;{}#=<>!~%.\\w]*("; + // List of function names goes here... + const char* e3 = + ")\\s*\\([^;()]*\\)\\s*(?:BOOST[_A-Z]+\\s*)?;)"; + + std::string class_name_list; + std::set<std::string>::const_iterator i = class_names[libname].begin(), j = class_names[libname].end(); + if(i != j) + { + class_name_list = *i; + ++i; + while(i != j) + { + class_name_list += "|" + *i; + ++i; + } + } + else + { + class_name_list = "[\\x0]"; + } + std::string function_name_list; + i = free_function_names[libname].begin(); + j = free_function_names[libname].end(); + if(i != j) + { + function_name_list = *i; + ++i; + while(i != j) + { + function_name_list += "|" + *i; + ++i; + } + } + else + { + function_name_list = "[\\x0]"; + } + + scanner[libname] = boost::regex(e1 + class_name_list + e2 + function_name_list + e3); + } +} + +void bcp_implementation::add_dependent_lib(const std::string& libname, const fs::path& p, const fileview& view) +{ + // + // if the boost library libname has source associated with it + // then add the source to our list: + // + if(fs::exists(m_boost_path / "libs" / libname / "src")) + { + if(!m_dependencies.count(fs::path("libs") / libname / "src")) + { + if(scanner.count(libname) == 0) + init_library_scanner(m_boost_path / "libs" / libname / "src", m_cvs_mode, libname); + boost::cmatch what; + if(regex_search(view.begin(), view.end(), what, scanner[libname])) + { + std::cout << "INFO: tracking source dependencies of library " << libname + << " due to presence of \"" << what << "\" in file " << p << std::endl; + //std::cout << "Full text match was: " << what << std::endl; + m_dependencies[fs::path("libs") / libname / "src"] = p; // set up dependency tree + add_path(fs::path("libs") / libname / "src"); + + if(fs::exists(m_boost_path / "libs" / libname / "build")) + { + if(!m_dependencies.count(fs::path("libs") / libname / "build")) + { + m_dependencies[fs::path("libs") / libname / "build"] = p; // set up dependency tree + add_path(fs::path("libs") / libname / "build"); + //m_dependencies[fs::path("boost-build.jam")] = p; + //add_path(fs::path("boost-build.jam")); + m_dependencies[fs::path("Jamroot")] = p; + add_path(fs::path("Jamroot")); + //m_dependencies[fs::path("tools/build")] = p; + //add_path(fs::path("tools/build")); + } + } + if(fs::exists(m_boost_path / "libs" / libname / "config")) + { + if(!m_dependencies.count(fs::path("libs") / libname / "config")) + { + m_dependencies[fs::path("libs") / libname / "config"] = p; // set up dependency tree + add_path(fs::path("libs") / libname / "config"); + //m_dependencies[fs::path("boost-build.jam")] = p; + //add_path(fs::path("boost-build.jam")); + m_dependencies[fs::path("Jamroot")] = p; + add_path(fs::path("Jamroot")); + //m_dependencies[fs::path("tools/build")] = p; + //add_path(fs::path("tools/build")); + } + } + } + } + } +} diff --git a/src/boost/tools/bcp/add_path.cpp b/src/boost/tools/bcp/add_path.cpp new file mode 100644 index 000000000..669fc92e7 --- /dev/null +++ b/src/boost/tools/bcp/add_path.cpp @@ -0,0 +1,569 @@ +/* + * + * 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) + * + * This file implements the following: + * void bcp_implementation::add_path(const fs::path& p) + * void bcp_implementation::add_directory(const fs::path& p) + * void bcp_implementation::add_file(const fs::path& p) + * void bcp_implementation::add_dependent_lib(const std::string& libname, const fs::path& p, const fileview& view) + */ + +#include "bcp_imp.hpp" +#include "fileview.hpp" +#include <boost/regex.hpp> +#include <boost/filesystem/operations.hpp> +#include <boost/filesystem/exception.hpp> +#include <iostream> + + +void bcp_implementation::add_path(const fs::path& p) +{ + fs::path normalized_path = p; + normalized_path.normalize(); + if(fs::exists(m_boost_path / normalized_path)) + { + if(fs::is_directory(m_boost_path / normalized_path)) + add_directory(normalized_path); + else + add_file(normalized_path); + } + else + { + std::cerr << "CAUTION: dependent file " << p.string() << " does not exist." << std::endl; + std::cerr << " Found while scanning file " << m_dependencies[p].string() << std::endl; + } +} + +void bcp_implementation::add_directory(const fs::path& p) +{ + // + // Don't add files created by build system: + // + if((p.leaf() == "bin") || (p.leaf() == "bin-stage")) + return; + // + // Don't add version control directories: + // + if((p.leaf() == "CVS") || (p.leaf() == ".svn")) + return; + // + // don't add directories not under version control: + // + if(m_cvs_mode && !fs::exists(m_boost_path / p / "CVS/Entries")) + return; + if(m_svn_mode && !fs::exists(m_boost_path / p / ".svn/entries")) + return; + // + // enermerate files and directories: + // + fs::directory_iterator i(m_boost_path / p); + fs::directory_iterator j; + while(i != j) + { + // + // we need to convert *i back into + // a relative path, what follows is a hack: + // + std::string s(i->path().string()); + if(m_boost_path.string().size()) + s.erase(0, m_boost_path.string().size() + 1); + fs::path np = s; + if(!m_dependencies.count(np)) + { + m_dependencies[np] = p; // set up dependency tree + add_pending_path(np); + } + ++i; + } +} + +void bcp_implementation::add_file(const fs::path& p) +{ + // + // if the file does not exist in cvs then don't do anything with it: + // + if((m_cvs_mode || m_svn_mode) && (m_cvs_paths.find(p) == m_cvs_paths.end())) + return; + // + // if we've already seen the file return: + // + if(m_copy_paths.find(p) != m_copy_paths.end()) + return; + // + // add the file to our list: + // + m_copy_paths.insert(p); + // + // if this is a source file, scan for dependencies: + // + if(is_source_file(p)) + { + add_file_dependencies(p, false); + } + if(is_jam_file(p) && m_namespace_name.size() && ((std::distance(p.begin(), p.end()) < 3) || (*p.begin() != "tools") || (*++p.begin() != "build"))) + { + // + // We're doing a rename of namespaces and library names + // so scan for names of libraries: + // + static const boost::regex e( + "\\<lib\\s+(boost\\w+)\\s+[:;]" + ); + + fileview view(m_boost_path / p); + boost::regex_token_iterator<const char*> i(view.begin(), view.end(), e, 1); + boost::regex_token_iterator<const char*> j; + while(i != j) + { + m_lib_names.insert(*i); + ++i; + } + static const std::pair<fs::path, std::string> specials_library_names[] = { + std::pair<fs::path, std::string>("libs/python/build/Jamfile.v2", "boost_python"), + std::pair<fs::path, std::string>("libs/python/build/Jamfile.v2", "boost_python3"), + }; + + for(unsigned int n = 0; n < (sizeof(specials_library_names)/sizeof(specials_library_names[0])); ++n) + { + if(0 == compare_paths(specials_library_names[n].first, p)) + { + m_lib_names.insert(specials_library_names[n].second); + } + } + } + // + // if this is a html file, scan for dependencies: + // + if(is_html_file(p)) + { + static const boost::regex e( + "<(?:img[^>]*src=|link[^>]*href=)(\"[^\"]+\"|\\w+)[^>]*>" + ); + + fileview view(m_boost_path / p); + boost::regex_token_iterator<const char*> i(view.begin(), view.end(), e, 1); + boost::regex_token_iterator<const char*> j; + while(i != j) + { + // + // extract the dependent name: + // + std::string s(*i); + if(s[0] == '\"') + { + // remove quotes: + assert(s.size() > 2); + s.erase(0, 1); + s.erase(s.size() - 1); + } + // + // Remove any target suffix: + // + std::string::size_type n = s.find('#'); + if(n != std::string::npos) + { + s.erase(n); + } + // + // if the name starts with ./ remove it + // or we'll get an error: + if(s.compare(0, 2, "./") == 0) + s.erase(0, 2); + if(s.find(':') == std::string::npos) + { + // only concatonate if it's a relative path + // rather than a URL: + fs::path dep(p.branch_path() / s); + if(!m_dependencies.count(dep)) + { + m_dependencies[dep] = p; // set up dependency tree + add_pending_path(dep); + } + } + ++i; + } + } + // + // now scan for "special" dependencies: + // anything that we can't automatically detect... + // +static const std::pair<fs::path, fs::path> + specials[] = { + std::pair<fs::path, fs::path>("tools/build/src/kernel/modules.jam", "libs/predef/check"), + std::pair<fs::path, fs::path>("tools/build/src/kernel/modules.jam", "libs/predef/tools"), + std::pair<fs::path, fs::path>("tools/build/src/kernel/modules.jam", "tools/boost_install/boost-install.jam"), + std::pair<fs::path, fs::path>("tools/build/src/kernel/modules.jam", "tools/boost_install/boost-install-dirs.jam"), + std::pair<fs::path, fs::path>("tools/build/src/kernel/modules.jam", "tools/boost_install/Jamfile"), + std::pair<fs::path, fs::path>("tools/build/src/kernel/modules.jam", "libs/headers"), + std::pair<fs::path, fs::path>("libs/test/build/Jamfile.v2", "libs/timer/src"), + std::pair<fs::path, fs::path>("libs/test/build/Jamfile.v2", "libs/timer/build"), + std::pair<fs::path, fs::path>("boost/atomic/capabilities.hpp", "boost/atomic/detail"), + std::pair<fs::path, fs::path>("boost/chrono/chrono.hpp", "libs/chrono/src"), + std::pair<fs::path, fs::path>("boost/chrono/chrono.hpp", "libs/chrono/build"), + std::pair<fs::path, fs::path>("boost/context/execution_context.hpp", "libs/context/src"), + std::pair<fs::path, fs::path>("boost/context/execution_context.hpp", "libs/context/build"), + std::pair<fs::path, fs::path>("boost/context/fcontext.hpp", "libs/context/src"), + std::pair<fs::path, fs::path>("boost/context/fcontext.hpp", "libs/context/build"), + std::pair<fs::path, fs::path>("boost/context/fixedsize_stack.hpp", "libs/context/src"), + std::pair<fs::path, fs::path>("boost/context/fixedsize_stack.hpp", "libs/context/build"), + std::pair<fs::path, fs::path>("boost/context/protected_fixedsize_stack.hpp", "libs/context/src"), + std::pair<fs::path, fs::path>("boost/context/protected_fixedsize_stack.hpp", "libs/context/build"), + std::pair<fs::path, fs::path>("boost/context/segmented_stack.hpp", "libs/context/src"), + std::pair<fs::path, fs::path>("boost/context/segmented_stack.hpp", "libs/context/build"), + std::pair<fs::path, fs::path>("boost/context/stack_context.hpp", "libs/context/src"), + std::pair<fs::path, fs::path>("boost/context/stack_context.hpp", "libs/context/build"), + std::pair<fs::path, fs::path>("boost/context/stack_traits.hpp", "libs/context/src"), + std::pair<fs::path, fs::path>("boost/context/stack_traits.hpp", "libs/context/build"), + std::pair<fs::path, fs::path>("boost/cerrno.hpp", "libs/system/build"), + std::pair<fs::path, fs::path>("boost/cerrno.hpp", "libs/system/src"), + std::pair<fs::path, fs::path>("libs/thread/build", "boost/system"), + std::pair<fs::path, fs::path>("libs/thread/build", "boost/cerrno.hpp"), + std::pair<fs::path, fs::path>("libs/thread/build", "boost/chrono"), + std::pair<fs::path, fs::path>("boost/filesystem/convenience.hpp", "boost/filesystem.hpp"), + std::pair<fs::path, fs::path>("boost/filesystem/exception.hpp", "boost/filesystem.hpp"), + std::pair<fs::path, fs::path>("boost/filesystem/fstream.hpp", "boost/filesystem.hpp"), + std::pair<fs::path, fs::path>("boost/filesystem/operations.hpp", "boost/filesystem.hpp"), + std::pair<fs::path, fs::path>("boost/filesystem/path.hpp", "boost/filesystem.hpp"), + std::pair<fs::path, fs::path>("boost/filesystem.hpp", "libs/filesystem/build"), + std::pair<fs::path, fs::path>("boost/filesystem.hpp", "libs/filesystem/v2"), + std::pair<fs::path, fs::path>("boost/filesystem.hpp", "libs/filesystem/v3"), + std::pair<fs::path, fs::path>("boost/config.hpp", "boost/config"), + std::pair<fs::path, fs::path>("tools/build/boost-build.jam", "libs/config/checks"), + std::pair<fs::path, fs::path>("tools/build/boost-build.jam", "libs/config/test"), + std::pair<fs::path, fs::path>("tools/build/boost-build.jam", "libs/headers/build"), + std::pair<fs::path, fs::path>("tools/build/boost-build.jam", "tools/boost_install/BoostConfig.cmake"), + std::pair<fs::path, fs::path>("tools/build/boost-build.jam", "tools/boost_install/BoostDetectToolset.cmake"), + std::pair<fs::path, fs::path>("tools/build/boost-build.jam", "tools/boost_install/boost-install.jam"), + std::pair<fs::path, fs::path>("tools/build/boost-build.jam", "tools/boost_install/boost-install-dirs.jam"), + std::pair<fs::path, fs::path>("tools/build/boost-build.jam", "boost-build.jam"), + std::pair<fs::path, fs::path>("tools/build/boost-build.jam", "boostcpp.jam"), + std::pair<fs::path, fs::path>("tools/build/boost-build.jam", "bootstrap.bat"), + std::pair<fs::path, fs::path>("tools/build/boost-build.jam", "bootstrap.sh"), + std::pair<fs::path, fs::path>("tools/build/boost-build.jam", "Jamroot"), + std::pair<fs::path, fs::path>("tools/build/boost-build.jam", "INSTALL"), + std::pair<fs::path, fs::path>("tools/build/boost-build.jam", "LICENSE_1_0.txt"), + std::pair<fs::path, fs::path>("boost/preprocessor/iterate.hpp", "boost/preprocessor/iteration"), + std::pair<fs::path, fs::path>("boost/preprocessor/slot/slot.hpp", "boost/preprocessor/slot/detail"), + std::pair<fs::path, fs::path>("boost/function.hpp", "boost/function/detail"), + std::pair<fs::path, fs::path>("boost/regex/config.hpp", "boost/regex/user.hpp"), + std::pair<fs::path, fs::path>("boost/signals/signal_template.hpp", "boost/function"), + std::pair<fs::path, fs::path>("boost/mpl/list.hpp", "boost/mpl/list"), + std::pair<fs::path, fs::path>("boost/mpl/list_c.hpp", "boost/mpl/list"), + std::pair<fs::path, fs::path>("boost/mpl/vector.hpp", "boost/mpl/vector"), + std::pair<fs::path, fs::path>("boost/mpl/deque.hpp", "boost/mpl/vector"), + std::pair<fs::path, fs::path>("boost/mpl/vector_c.hpp", "boost/mpl/vector"), + std::pair<fs::path, fs::path>("boost/mpl/map.hpp", "boost/mpl/map"), + std::pair<fs::path, fs::path>("boost/mpl/set.hpp", "boost/mpl/set"), + std::pair<fs::path, fs::path>("boost/mpl/set_c.hpp", "boost/mpl/set"), + std::pair<fs::path, fs::path>("boost/mpl/aux_/include_preprocessed.hpp", "boost/mpl/aux_/preprocessed"), + std::pair<fs::path, fs::path>("boost/mpl/vector/aux_/include_preprocessed.hpp", "boost/mpl/vector/aux_/preprocessed"), + std::pair<fs::path, fs::path>("boost/mpl/set/aux_/include_preprocessed.hpp", "boost/mpl/set/aux_/preprocessed"), + std::pair<fs::path, fs::path>("boost/mpl/map/aux_/include_preprocessed.hpp", "boost/mpl/map/aux_/preprocessed"), + std::pair<fs::path, fs::path>("boost/mpl/list/aux_/include_preprocessed.hpp", "boost/mpl/list/aux_/preprocessed"), + std::pair<fs::path, fs::path>("libs/graph/src/python/visitor.hpp", "libs/graph/src/python"), + std::pair<fs::path, fs::path>("boost/test/detail/config.hpp", "libs/test/src"), + std::pair<fs::path, fs::path>("boost/test/detail/config.hpp", "libs/test/build"), + std::pair<fs::path, fs::path>("boost/test/detail/config.hpp", "libs/predef/build.jam"), + std::pair<fs::path, fs::path>("boost/test/detail/config.hpp", "libs/predef/check"), + std::pair<fs::path, fs::path>("boost/typeof.hpp", "boost/typeof/incr_registration_group.hpp"), + std::pair<fs::path, fs::path>("boost/function_types/detail/pp_loop.hpp", "boost/function_types/detail/pp_cc_loop"), + std::pair<fs::path, fs::path>("boost/function_types/components.hpp", "boost/function_types/detail/components_impl"), + std::pair<fs::path, fs::path>("boost/function_types/detail/pp_loop.hpp", "boost/function_types/detail"), + std::pair<fs::path, fs::path>("boost/math/tools/rational.hpp", "boost/math/tools/detail"), + std::pair<fs::path, fs::path>("boost/proto/repeat.hpp", "boost/proto/detail/local.hpp"), + std::pair<fs::path, fs::path>("boost/signals/signal_template.hpp", "boost/function"), + std::pair<fs::path, fs::path>("boost/preprocessor/slot/counter.hpp", "boost/preprocessor/slot/detail/counter.hpp"), + std::pair<fs::path, fs::path>("boost/graph/distributed/detail/tag_allocator.hpp", "libs/graph_parallel"), + std::pair<fs::path, fs::path>("boost/graph/distributed/mpi_process_group.hpp", "libs/graph_parallel"), + std::pair<fs::path, fs::path>("libs/coroutine/build/Jamfile.v2", "libs/context/src"), + std::pair<fs::path, fs::path>("libs/coroutine/build/Jamfile.v2", "libs/context/build"), + std::pair<fs::path, fs::path>("libs/fiber/build/Jamfile.v2", "libs/context/src"), + std::pair<fs::path, fs::path>("libs/fiber/build/Jamfile.v2", "libs/context/build"), + }; + + for(unsigned int n = 0; n < (sizeof(specials)/sizeof(specials[0])); ++n) + { + if(0 == compare_paths(specials[n].first, p)) + { + if(!m_dependencies.count(specials[n].second)) + { + m_dependencies[specials[n].second] = p; // set up dependency tree + add_pending_path(specials[n].second); + } + } + } + +} + +void bcp_implementation::add_file_dependencies(const fs::path& p, bool scanfile) +{ + static const boost::regex e( + "^[[:blank:]]*(?://@bcp[[:blank:]]+([^\\n]*)\n)?#[[:blank:]]*include[[:blank:]]*[\"<]([^\">]+)[\">]" + ); + + if(!m_dependencies.count(p)) + m_dependencies[p] = p; // set terminal dependency + + fileview view; + if(scanfile) + view.open(p); + else + view.open(m_boost_path / p); + if(m_license_mode && !scanfile) + scan_license(p, view); + const int subs[] = { 1, 2 }; + boost::regex_token_iterator<const char*> i(view.begin(), view.end(), e, subs); + boost::regex_token_iterator<const char*> j; + while(i != j) + { + // + // *i contains the name of the include file, + // check first for a file of that name in the + // same directory as the file we are scanning, + // and if that fails, then check the boost-root: + // + fs::path include_file; + try{ + std::string discart_message = *i; + ++i; + if(discart_message.size()) + { + // The include is optional and should be discarded: + std::cout << "Optional functionality won't be copied: " << discart_message << std::endl; + std::cout << "Add the file " << *i << " to the list of dependencies to extract to copy this functionality." << std::endl; + ++i; + continue; + } + include_file = i->str(); + fs::path test_file(m_boost_path / p.branch_path() / include_file); + if(fs::exists(test_file) && !fs::is_directory(test_file) && (p.branch_path().string() != "boost")) + { + if(!m_dependencies.count(p.branch_path() / include_file)) + { + m_dependencies[p.branch_path() / include_file] = p; + add_pending_path(p.branch_path() / include_file); + } + } + else if(fs::exists(m_boost_path / include_file)) + { + if(!m_dependencies.count(include_file)) + { + m_dependencies[include_file] = p; + add_pending_path(include_file); + } + } + ++i; + } + catch(const fs::filesystem_error&) + { + std::cerr << "Can't parse filename " << *i << " included by file " << p.string() << std::endl; + ++i; + continue; + } + } + // + // Now we need to scan for Boost.Preprocessor includes that + // are included via preprocessor iteration: + // + static const boost::regex ppfiles("^[[:blank:]]*#[[:blank:]]*define[[:blank:]]+(?:BOOST_PP_FILENAME|BOOST_PP_ITERATION_PARAMS|BOOST_PP_INDIRECT_SELF)(?:[^\\n]|\\\\\\n)+?[\"<]([^\">]+)[\">]"); + i = boost::regex_token_iterator<const char*>(view.begin(), view.end(), ppfiles, 1); + while(i != j) + { + // + // *i contains the name of the include file, + // check first for a file of that name in the + // same directory as the file we are scanning, + // and if that fails, then check the boost-root: + // + fs::path include_file; + try{ + include_file = i->str(); + } + catch(const fs::filesystem_error&) + { + std::cerr << "Can't parse filename " << *i << " included by file " << p.string() << std::endl; + ++i; + continue; + } + fs::path test_file(m_boost_path / p.branch_path() / include_file); + if(fs::exists(test_file) && !fs::is_directory(test_file) && (p.branch_path().string() != "boost")) + { + if(!m_dependencies.count(p.branch_path() / include_file)) + { + m_dependencies[p.branch_path() / include_file] = p; + add_pending_path(p.branch_path() / include_file); + } + } + else if(fs::exists(m_boost_path / include_file)) + { + if(!m_dependencies.count(include_file)) + { + m_dependencies[include_file] = p; + add_pending_path(include_file); + } + } + else + { + std::cerr << "CAUTION: Boost.Preprocessor iterated file " << include_file.string() << " does not exist." << std::endl; + } + ++i; + } + + // + // Scan for any #include MACRO includes that we don't recognise. + // + // Begin by declaring all of the macros that get #included that + // we know about and are correctly handled as special cases: + // + static const std::string known_macros[] = { + "AUX778076_INCLUDE_STRING", + "BOOST_PP_STRINGIZE(boost/mpl/aux_/preprocessed/AUX778076_PREPROCESSED_HEADER)", + "BOOST_USER_CONFIG", + "BOOST_COMPILER_CONFIG", + "BOOST_STDLIB_CONFIG", + "BOOST_PLATFORM_CONFIG", + "BOOST_PP_FILENAME_1", + "BOOST_PP_ITERATION_PARAMS_1", + "BOOST_PP_FILENAME_2", + "BOOST_PP_ITERATION_PARAMS_2", + "BOOST_PP_FILENAME_3", + "BOOST_PP_ITERATION_PARAMS_3", + "BOOST_PP_FILENAME_4", + "BOOST_PP_ITERATION_PARAMS_4", + "BOOST_PP_FILENAME_5", + "BOOST_PP_ITERATION_PARAMS_5", + "BOOST_PP_INDIRECT_SELF", + "BOOST_PP_INCLUDE_SELF()", + "BOOST_PP_ITERATE", + "BOOST_PP_LOCAL_ITERATE", + "BOOST_PP_ITERATE()", + "BOOST_PP_LOCAL_ITERATE()", + "BOOST_PP_ASSIGN_SLOT(1)", + "BOOST_PP_ASSIGN_SLOT(2)", + "BOOST_PP_ASSIGN_SLOT(3)", + "BOOST_PP_ASSIGN_SLOT(4)", + "BOOST_PP_ASSIGN_SLOT(5)", + "BOOST_ABI_PREFIX", + "BOOST_ABI_SUFFIX", + "BOOST_PP_STRINGIZE(boost/mpl/aux_/preprocessed/AUX_PREPROCESSED_HEADER)", + "BOOST_PP_STRINGIZE(boost/mpl/list/AUX778076_HEADER)", + "BOOST_PP_STRINGIZE(boost/mpl/list/AUX778076_LIST_C_HEADER)", + "BOOST_PP_STRINGIZE(boost/mpl/list/AUX778076_LIST_HEADER)", + "BOOST_PP_STRINGIZE(boost/mpl/map/aux_/preprocessed/AUX778076_HEADER)", + "BOOST_PP_STRINGIZE(boost/mpl/map/AUX778076_MAP_HEADER)", + "BOOST_PP_STRINGIZE(boost/mpl/set/aux_/preprocessed/AUX778076_HEADER)", + "BOOST_PP_STRINGIZE(boost/mpl/set/AUX778076_SET_HEADER)", + "BOOST_PP_STRINGIZE(boost/mpl/set/AUX778076_SET_C_HEADER)", + "BOOST_PP_STRINGIZE(boost/mpl/vector/AUX778076_VECTOR_HEADER)", + "BOOST_PP_STRINGIZE(boost/mpl/vector/aux_/preprocessed/AUX778076_HEADER)", + "BOOST_PP_STRINGIZE(boost/mpl/vector/AUX778076_DEQUE_HEADER)", + "BOOST_PP_STRINGIZE(boost/mpl/vector/AUX778076_VECTOR_C_HEADER)", + "BOOST_REGEX_USER_CONFIG", + "BGL_PYTHON_EVENTS_HEADER", + "B1", + "B2", + "BOOST_TYPEOF_INCREMENT_REGISTRATION_GROUP()", + "BOOST_SLIST_HEADER", + "BOOST_HASH_SET_HEADER", + "BOOST_HASH_MAP_HEADER", + "BOOST_INTRUSIVE_INVARIANT_ASSERT_INCLUDE", + "BOOST_INTRUSIVE_SAFE_HOOK_DEFAULT_ASSERT_INCLUDE", + "BOOST_INTRUSIVE_SAFE_HOOK_DESTRUCTOR_ASSERT_INCLUDE", + "BOOST_FT_loop", + "BOOST_FT_AL_PREPROCESSED", + "BOOST_FT_AL_INCLUDE_FILE", + "__FILE__", + "BOOST_FT_cc_file", + "BOOST_FT_variate_file", + "BOOST_USER_CONFIG", + "BOOST_HEADER()", + "BOOST_TR1_STD_HEADER(utility)", + "BOOST_TR1_STD_HEADER(BOOST_TR1_PATH(tuple))", + "BOOST_TR1_STD_HEADER(BOOST_TR1_PATH(random))", + "BOOST_TR1_STD_HEADER(BOOST_TR1_PATH(array))", + "BOOST_TR1_HEADER(cmath)", + "BOOST_TR1_STD_HEADER(BOOST_TR1_PATH(complex))", + "BOOST_TR1_STD_HEADER(BOOST_TR1_PATH(functional))", + "BOOST_TR1_STD_HEADER(BOOST_TR1_PATH(memory))", + "BOOST_TR1_STD_HEADER(BOOST_TR1_PATH(regex))", + "BOOST_TR1_STD_HEADER(BOOST_TR1_PATH(type_traits))", + "BOOST_TR1_STD_HEADER(BOOST_TR1_PATH(unordered_map))", + "BOOST_TR1_STD_HEADER(BOOST_TR1_PATH(unordered_set))", + "BOOST_TR1_STD_HEADER(BOOST_TR1_PATH(utility))", + "BOOST_PROTO_LOCAL_ITERATE()", + "BOOST_SIGNAL_FUNCTION_N_HEADER", + "BOOST_PP_UPDATE_COUNTER()", + }; + + static const boost::regex indirect_includes("^[[:blank:]]*#[[:blank:]]*include[[:blank:]]+([^\"<][^\n]*?)[[:blank:]]*$"); + i = boost::regex_token_iterator<const char*>(view.begin(), view.end(), indirect_includes, 1); + while(i != j) + { + const std::string* known_macros_end = known_macros + sizeof(known_macros)/sizeof(known_macros[0]); + if(known_macros_end == std::find(known_macros, known_macros_end, i->str())) + { + std::cerr << "CAUTION: don't know how to trace depenencies through macro: \"" << *i << "\" in file: " << p.string() << std::endl; + } + ++i; + } + // + // if the file contains a cpp_main / unit_test_main / test_main + // it is dependent upon Boost.test even if it doesn't + // include any of the Boost.test headers directly. + // + static const boost::regex m("^\\s*int\\s+(?:cpp_main|test_main|unit_test_main)"); + boost::cmatch what; + if(boost::regex_search(view.begin(), view.end(), what, m)) + { + add_dependent_lib("test", p, view); + } + if(!scanfile) + { + // + // grab the name of the library to which the header belongs, + // and if that library has source then add the source to our + // list: + // + // this regex catches boost/libname.hpp or boost/libname/whatever: + // + static const boost::regex lib1("boost/([^\\./]+)(?!detail).*"); + boost::smatch swhat; + std::string gs(p.generic_string()); + if(boost::regex_match(gs, swhat, lib1)) + { + add_dependent_lib(swhat.str(1), p, view); + } + // + // and this one catches boost/x/y/whatever (for example numeric/ublas): + // + static const boost::regex lib2("boost/([^/]+/[^/]+)/(?!detail).*"); + gs = p.generic_string(); + if(boost::regex_match(gs, swhat, lib2)) + { + add_dependent_lib(swhat.str(1), p, view); + } + } + if(m_list_namespaces) + { + // + // scan for top level namespaces and add to our list: + // + static const boost::regex namespace_scanner( + "^(?<!\\\\\\n)[[:blank:]]*+namespace\\s++(\\w++)\\s++(\\{[^{}]*(?:(?2)[^{}]*)*\\})" + ); + i = boost::regex_token_iterator<const char*>(view.begin(), view.end(), namespace_scanner, 1); + while(i != j) + { + if(m_top_namespaces.count(*i) == 0) + { + //std::cout << *i << " (Found in " << p << ")" << std::endl; + m_top_namespaces[*i] = p; + } + ++i; + } + } +} diff --git a/src/boost/tools/bcp/bcp.hpp b/src/boost/tools/bcp/bcp.hpp new file mode 100644 index 000000000..bec63641c --- /dev/null +++ b/src/boost/tools/bcp/bcp.hpp @@ -0,0 +1,47 @@ +/* + * + * 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 <boost/shared_ptr.hpp> + +#if defined(BOOST_FILESYSTEM_VERSION) && (BOOST_FILESYSTEM_VERSION != 3) +# error "This library must be built with Boost.Filesystem version 3" +#else +#define BOOST_FILESYSTEM_VERSION 3 +#endif + +class bcp_application; +typedef boost::shared_ptr<bcp_application> pbcp_application; + +class bcp_application +{ +public: + virtual ~bcp_application(); + + virtual void enable_list_mode() = 0; + virtual void enable_summary_list_mode() = 0; + virtual void enable_cvs_mode() = 0; + virtual void enable_svn_mode() = 0; + virtual void enable_unix_lines() = 0; + virtual void enable_scan_mode() = 0; + virtual void enable_license_mode() = 0; + virtual void enable_bsl_convert_mode() = 0; + virtual void enable_bsl_summary_mode() = 0; + virtual void set_boost_path(const char* p) = 0; + virtual void set_destination(const char* p) = 0; + virtual void add_module(const char* p) = 0; + virtual void set_namespace(const char* name) = 0; + virtual void set_namespace_alias(bool) = 0; + virtual void set_namespace_list(bool) = 0; + + virtual int run() = 0; + + static pbcp_application create(); +}; + + diff --git a/src/boost/tools/bcp/bcp_imp.cpp b/src/boost/tools/bcp/bcp_imp.cpp new file mode 100644 index 000000000..1fe8cf926 --- /dev/null +++ b/src/boost/tools/bcp/bcp_imp.cpp @@ -0,0 +1,300 @@ +/* + * + * 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) + * + * This file implements the bcp_implementation virtuals. + */ + +#include "bcp_imp.hpp" +#include "licence_info.hpp" +#include <boost/filesystem/operations.hpp> +#include <boost/filesystem/fstream.hpp> +#include <iostream> +#include <stdexcept> +#include <boost/regex.hpp> +#include <string> + +bcp_implementation::bcp_implementation() + : m_list_mode(false), m_list_summary_mode(false), m_license_mode(false), m_cvs_mode(false), + m_svn_mode(false), m_unix_lines(false), m_scan_mode(false), m_bsl_convert_mode(false), + m_bsl_summary_mode(false), m_namespace_alias(false), m_list_namespaces(false) +{ +} + +bcp_implementation::~bcp_implementation() +{ +} + +bcp_application::~bcp_application() +{ +} + +void bcp_implementation::enable_list_mode() +{ + m_list_mode = true; +} + +void bcp_implementation::enable_summary_list_mode() +{ + m_list_mode = true; + m_list_summary_mode = true; +} + +void bcp_implementation::enable_cvs_mode() +{ + m_cvs_mode = true; +} + +void bcp_implementation::enable_svn_mode() +{ + m_svn_mode = true; +} + +void bcp_implementation::enable_scan_mode() +{ + m_scan_mode = true; +} + +void bcp_implementation::enable_license_mode() +{ + m_license_mode = true; +} + +void bcp_implementation::enable_bsl_convert_mode() +{ + m_bsl_convert_mode = true; +} + +void bcp_implementation::enable_bsl_summary_mode() +{ + m_bsl_summary_mode = true; +} + +void bcp_implementation::enable_unix_lines() +{ + m_unix_lines = true; +} + +void bcp_implementation::set_boost_path(const char* p) +{ + // Hack to strip trailing slashes from the path + m_boost_path = (fs::path(p) / "boost").parent_path(); + fs::path check = m_boost_path / "boost" / "version.hpp"; + if(!fs::exists(check)) + { + std::string s = "The Boost path appears to have been incorrectly set: could not find boost/version.hpp in "; + s += m_boost_path.string(); + std::runtime_error e(s); + throw e; + } +} + +void bcp_implementation::set_destination(const char* p) +{ + m_dest_path = fs::path(p); +} + +void bcp_implementation::add_module(const char* p) +{ + m_module_list.push_back(p); +} + +void bcp_implementation::set_namespace(const char* name) +{ + m_namespace_name = name; +} + +void bcp_implementation::set_namespace_alias(bool b) +{ + m_namespace_alias = b; +} + +void bcp_implementation::set_namespace_list(bool b) +{ + m_list_namespaces = b; + m_list_mode = b; +} + +fs::path get_short_path(const fs::path& p) +{ + // truncate path no more than "x/y": + std::string s = p.generic_string(); + std::string::size_type n = s.find('/'); + if(n != std::string::npos) + { + n = s.find('/', n+1); + if(n != std::string::npos) + s.erase(n); + } + return s; +} + +int bcp_implementation::run() +{ + // + // check output path is OK: + // + if(!m_list_mode && !m_license_mode && !fs::exists(m_dest_path)) + { + std::string msg("Destination path does not exist: "); + msg.append(m_dest_path.string()); + std::runtime_error e(msg); + boost::throw_exception(e); + } + // + // Check Boost path is OK if it hasn't been checked already: + // + if(m_boost_path == "") + { + set_boost_path(""); + } + // start by building a list of permitted files + // if m_cvs_mode is true: + if(m_cvs_mode) + { + std::cerr << "CAUTION: Boost is no longer in CVS, cvs mode may not work anymore!!!" << std::endl; + scan_cvs_path(fs::path()); + } + if(m_svn_mode) + { + scan_svn_path(fs::path()); + } + // + // if in license mode, try to load more/blanket_permission.txt + // + fs::path blanket_permission(m_boost_path / "more" / "blanket-permission.txt"); + if (fs::exists(blanket_permission)) { + fs::ifstream in(blanket_permission); + std::string line; + while (std::getline(in, line)) { + static const boost::regex e("([^(]+)\\("); + boost::smatch result; + if (boost::regex_search(line, result, e)) + m_bsl_authors.insert(format_authors_name(result[1])); + } + } + + // + // scan through modules looking for the equivalent + // file to add to our list: + // + std::list<std::string>::const_iterator i = m_module_list.begin(); + std::list<std::string>::const_iterator j = m_module_list.end(); + while(i != j) + { + // + // convert *i to a path - could be native or portable: + // + fs::path module; + fs::path exmodule; + module = fs::path(*i); + exmodule = fs::path(*i + ".hpp"); + + if(m_scan_mode) + { + // in scan mode each module must be a real file: + add_file_dependencies(module, true); + } + else + { + int count = 0; + if(fs::exists(m_boost_path / "tools" / module)) + { + add_path(fs::path("tools") / module); + ++count; + } + if(fs::exists(m_boost_path / "libs" / module)) + { + add_path(fs::path("libs") / module); + ++count; + } + if(fs::exists(m_boost_path / "boost" / module)) + { + add_path(fs::path("boost") / module); + ++count; + } + if(fs::exists(m_boost_path / "boost" / exmodule)) + { + add_path(fs::path("boost") / exmodule); + ++count; + } + if(fs::exists(m_boost_path / module)) + { + add_path(module); + ++count; + } + } + ++i; + } + while (!m_pending_paths.empty()) + { + add_path(m_pending_paths.front()); + m_pending_paths.pop(); + } + // + // now perform output: + // + if(m_list_namespaces) + { + // List the namespaces, in two lists, headers and source files + // first, then everything else afterwards: + // + boost::regex important_file("boost/.*|libs/[^/]*/(?:[^/]*/)?/src/.*"); + std::map<std::string, fs::path>::const_iterator i, j; + i = m_top_namespaces.begin(); + j = m_top_namespaces.end(); + std::cout << "\n\nThe top level namespaces found for header and source files were:\n"; + while(i != j) + { + if(regex_match(i->second.generic_string(), important_file)) + std::cout << i->first << " (from " << i->second << ")" << std::endl; + ++i; + } + + i = m_top_namespaces.begin(); + std::cout << "\n\nThe top level namespaces found for all other source files were:\n"; + while(i != j) + { + if(!regex_match(i->second.generic_string(), important_file)) + std::cout << i->first << " (from " << i->second << ")" << std::endl; + ++i; + } + return 0; + } + std::set<fs::path, path_less>::iterator m, n; + std::set<fs::path, path_less> short_paths; + m = m_copy_paths.begin(); + n = m_copy_paths.end(); + if(!m_license_mode) + { + while(m != n) + { + if(m_list_summary_mode) + { + fs::path p = get_short_path(*m); + if(short_paths.find(p) == short_paths.end()) + { + short_paths.insert(p); + std::cout << p.string() << "\n"; + } + } + else if(m_list_mode) + std::cout << m->string() << "\n"; + else + copy_path(*m); + ++m; + } + } + else + output_license_info(); + return 0; +} + +pbcp_application bcp_application::create() +{ + pbcp_application result(static_cast<bcp_application*>(new bcp_implementation())); + return result; +} diff --git a/src/boost/tools/bcp/bcp_imp.hpp b/src/boost/tools/bcp/bcp_imp.hpp new file mode 100644 index 000000000..ffe407237 --- /dev/null +++ b/src/boost/tools/bcp/bcp_imp.hpp @@ -0,0 +1,121 @@ +/* + * + * 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 "bcp.hpp" +#include <string> +#include <cstring> +#include <list> +#include <set> +#include <map> +#include <queue> +#include <boost/filesystem/path.hpp> + +namespace fs = boost::filesystem; + +class fileview; + +// +//path operations: +// +int compare_paths(const fs::path& a, const fs::path& b); +inline bool equal_paths(const fs::path& a, const fs::path& b) +{ return compare_paths(a, b) == 0; } + +struct path_less +{ + bool operator()(const fs::path& a, const fs::path& b)const + { return compare_paths(a, b) < 0; } +}; + +struct license_data +{ + std::set<fs::path, path_less> files; + std::set<std::string> authors; +}; + +class bcp_implementation + : public bcp_application +{ +public: + bcp_implementation(); + ~bcp_implementation(); + static bool is_source_file(const fs::path& p); + static bool is_html_file(const fs::path& p); + static bool is_jam_file(const fs::path& p); +private: + // + // the following are the overridden virtuals from the base class: + // + void enable_list_mode(); + void enable_summary_list_mode(); + void enable_cvs_mode(); + void enable_svn_mode(); + void enable_unix_lines(); + void enable_scan_mode(); + void enable_license_mode(); + void enable_bsl_convert_mode(); + void enable_bsl_summary_mode(); + void set_boost_path(const char* p); + void set_destination(const char* p); + void add_module(const char* p); + void set_namespace(const char* name); + void set_namespace_alias(bool); + void set_namespace_list(bool); + + virtual int run(); + + // internal helper functions: + bool is_binary_file(const fs::path& p); + void scan_cvs_path(const fs::path& p); + void scan_svn_path(const fs::path& p); + void add_path(const fs::path& p); + void add_pending_path(const fs::path& p) { m_pending_paths.push(p); } + void add_directory(const fs::path& p); + void add_file(const fs::path& p); + void copy_path(const fs::path& p); + void add_file_dependencies(const fs::path& p, bool scanfile); + void add_dependent_lib(const std::string& libname, const fs::path& p, const fileview& view); + void create_path(const fs::path& p); + // license code: + void scan_license(const fs::path& p, const fileview& v); + void output_license_info(); + + std::list<std::string> m_module_list; // the modules to process + bool m_list_mode; // list files only + bool m_list_summary_mode; // list file summary only + bool m_license_mode; // generate license information for files listed + bool m_cvs_mode; // check cvs for files + bool m_svn_mode; // check svn for files + bool m_unix_lines; // fix line endings + bool m_scan_mode; // scan non-boost files. + bool m_bsl_convert_mode; // try to convert to the BSL + bool m_bsl_summary_mode; // summarise BSL issues only + bool m_namespace_alias; // make "boost" a namespace alias when doing a namespace rename. + bool m_list_namespaces; // list all the top level namespaces found. + fs::path m_boost_path; // the path to the boost root + fs::path m_dest_path; // the path to copy to + std::map<fs::path, bool, path_less> m_cvs_paths; // valid files under cvs control + std::set<fs::path, path_less> m_copy_paths; // list of files to copy + std::map<int, license_data> m_license_data; // licenses in use + std::set<fs::path, path_less> m_unknown_licenses; // files with no known license + std::set<fs::path, path_less> m_unknown_authors; // files with no known copyright/author + std::set<fs::path, path_less> m_can_migrate_to_bsl; // files that can migrate to the BSL + std::set<fs::path, path_less> m_cannot_migrate_to_bsl; // files that cannot migrate to the BSL + std::set<std::string> m_bsl_authors; // authors giving blanket permission to use the BSL + std::set<std::string> m_authors_for_bsl_migration; // authors we need for BSL migration + std::map<fs::path, std::pair<std::string, std::string>, path_less> + m_converted_to_bsl; + std::map<std::string, std::set<fs::path, path_less> > m_author_data; // all the authors + std::map<fs::path, fs::path, path_less> m_dependencies; // dependency information + std::string m_namespace_name; // namespace rename. + std::set<std::string> m_lib_names; // List of library binary names + std::map<std::string, fs::path> m_top_namespaces; // List of top level namespace names + std::queue<fs::path, std::list<fs::path> > m_pending_paths; // Queue of paths we haven't scanned yet. +}; + diff --git a/src/boost/tools/bcp/copy_path.cpp b/src/boost/tools/bcp/copy_path.cpp new file mode 100644 index 000000000..4143c79e6 --- /dev/null +++ b/src/boost/tools/bcp/copy_path.cpp @@ -0,0 +1,248 @@ +/* + * + * 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) + * + * This file implements the following: + * void bcp_implementation::copy_path(const fs::path& p) + * void bcp_implementation::create_path(const fs::path& p) + */ + +#include "bcp_imp.hpp" +#include "fileview.hpp" +#include <boost/filesystem/operations.hpp> +#include <boost/filesystem/fstream.hpp> +#include <boost/regex.hpp> +#include <boost/assert.hpp> +#include <fstream> +#include <iterator> +#include <algorithm> +#include <iostream> + +struct get_new_library_name +{ + get_new_library_name(const std::string& n) : m_new_name(n) {} + template <class I> + std::string operator()(const boost::match_results<I>& what) + { + std::string s = what[0]; + std::string::size_type n = s.find("boost"); + if(n == std::string::npos) + { + s.insert(0, m_new_name); + } + else + { + s.replace(n, 5, m_new_name); + } + return s; + } +private: + std::string m_new_name; +}; + +void bcp_implementation::copy_path(const fs::path& p) +{ + BOOST_ASSERT(!fs::is_directory(m_boost_path / p)); + if(fs::exists(m_dest_path / p)) + { + std::cout << "Copying (and overwriting) file: " << p.string() << "\n"; + fs::remove(m_dest_path / p); + } + else + std::cout << "Copying file: " << p.string() << "\n"; + // + // create the path to the new file if it doesn't already exist: + // + create_path(p.branch_path()); + // + // do text based copy if requested: + // + if((p.leaf() == "Jamroot") && m_namespace_name.size()) + { + static std::vector<char> v1, v2; + v1.clear(); + v2.clear(); + boost::filesystem::ifstream is((m_boost_path / p)); + std::copy(std::istreambuf_iterator<char>(is), std::istreambuf_iterator<char>(), std::back_inserter(v1)); + + static boost::regex libname_matcher; + if(libname_matcher.empty()) + { + libname_matcher.assign("boost_"); + } + + regex_replace(std::back_inserter(v2), v1.begin(), v1.end(), libname_matcher, m_namespace_name + "_"); + std::swap(v1, v2); + v2.clear(); + + boost::filesystem::ofstream os; + if(m_unix_lines) + os.open((m_dest_path / p), std::ios_base::binary | std::ios_base::out); + else + os.open((m_dest_path / p), std::ios_base::out); + os.write(&*v1.begin(), v1.size()); + os.close(); + } + else if(m_namespace_name.size() && m_lib_names.size() && is_jam_file(p)) + { + static std::vector<char> v1, v2; + v1.clear(); + v2.clear(); + boost::filesystem::ifstream is((m_boost_path / p)); + std::copy(std::istreambuf_iterator<char>(is), std::istreambuf_iterator<char>(), std::back_inserter(v1)); + + static boost::regex libname_matcher; + if(libname_matcher.empty()) + { + std::string re = "\\<"; + re += *m_lib_names.begin(); + for(std::set<std::string>::const_iterator i = ++m_lib_names.begin(); i != m_lib_names.end(); ++i) + { + re += "|" + *i; + } + re += "\\>"; + libname_matcher.assign(re); + } + + regex_replace(std::back_inserter(v2), v1.begin(), v1.end(), libname_matcher, get_new_library_name(m_namespace_name)); + std::swap(v1, v2); + v2.clear(); + + boost::filesystem::ofstream os; + if(m_unix_lines) + os.open((m_dest_path / p), std::ios_base::binary | std::ios_base::out); + else + os.open((m_dest_path / p), std::ios_base::out); + os.write(&*v1.begin(), v1.size()); + os.close(); + } + else if(m_namespace_name.size() && is_source_file(p)) + { + // + // v1 hold the current content, v2 is temp buffer. + // Each time we do a search and replace the new content + // ends up in v2: we then swap v1 and v2, and clear v2. + // + static std::vector<char> v1, v2; + v1.clear(); + v2.clear(); + boost::filesystem::ifstream is((m_boost_path / p)); + std::copy(std::istreambuf_iterator<char>(is), std::istreambuf_iterator<char>(), std::back_inserter(v1)); + + static const boost::regex namespace_matcher( + "(?|" + "(namespace\\s+)boost(_\\w+)?(?:(\\s*::\\s*)phoenix)?" + "|" + "(namespace\\s+(?:detail::)?)(adstl|phoenix|rapidxml)\\>" + "|" + "()\\<boost((?:_(?!intrusive_tags)\\w+)?\\s*(?:::))(?:(\\s*)phoenix)?" + "|" + "()\\<((?:adstl|phoenix|rapidxml)\\s*(?:::))" + "|" + "(namespace\\s+\\w+\\s*=\\s*(?:::\\s*)?)boost(_\\w+)?(?:(\\s*::\\s*)phoenix)?" + "|" + "(namespace\\s+\\w+\\s*=\\s*(?:::\\s*)?(?:\\w+\\s*::\\s*)?)(adstl|phoenix|rapidxml)\\>" + "|" + "(^\\s*#\\s*define\\s+\\w+\\s+)boost((?:_\\w+)?\\s*)$" + "|" + "(^\\s*#\\s*define[^\\n]+)((?:adstl|phoenix|rapidxml)\\s*)$" + "|" + "()boost(_asio_detail_posix_thread_function|_regex_free_static_mutex)" + "|" + "()\\<(lw_thread_routine|at_thread_exit|on_process_enter|on_process_exit|on_thread_enter|on_thread_exit|tss_cleanup_implemented)\\>" + "|" + "(BOOST_CLASS_REQUIRE4?[^;]*)boost((?:_\\w+)?\\s*,)" + "|" + "(::tr1::|TR1_DECL\\s+)boost(_\\w+\\s*)" // math tr1 + "|" + "(\\(\\s*)boost(\\s*\\))\\s*(\\(\\s*)phoenix(\\s*\\))" + "|" + "(\\(\\s*)boost(\\s*\\))" + "|" + "(BOOST_UNORDERED_CONSTRUCT_FROM_TUPLE[^\\)]*)boost(\\))" + ")" + ); + + 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); + std::swap(v1, v2); + v2.clear(); + + if(m_namespace_alias) + { + static const boost::regex namespace_alias( + /* + "namespace\\s+" + m_namespace_name + + "\\s*" + "(" + "\\{" + "(?:" + "(?>[^\\{\\}/]+)" + "(?>" + "(?:" + "(?1)" + "|//[^\\n]+$" + "|/[^/]" + "|(?:^\\s*#[^\\n]*" + "(?:(?<=\\\\)\\n[^\\n]*)*)" + ")" + "[^\\{\\}]+" + ")*" + ")*" + "\\}" + ")" + */ + /* + "(namespace\\s+" + m_namespace_name + + "\\s*\\{.*" + "\\})([^\\{\\};]*)\\z" + */ + "(namespace)(\\s+)(" + m_namespace_name + ")" + "(adstl|phoenix|rapidxml)?(\\s*\\{)" + ); + regex_replace(std::back_inserter(v2), v1.begin(), v1.end(), namespace_alias, + "$1 $3$4 {} $1 (?4$4:boost) = $3$4; $1$2$3$4$5", boost::regex_constants::format_all); + std::swap(v1, v2); + v2.clear(); + } + + boost::filesystem::ofstream os; + if(m_unix_lines) + os.open((m_dest_path / p), std::ios_base::binary | std::ios_base::out); + else + os.open((m_dest_path / p), std::ios_base::out); + if(v1.size()) + os.write(&*v1.begin(), v1.size()); + os.close(); + } + else if(m_unix_lines && !is_binary_file(p)) + { + boost::filesystem::ifstream is((m_boost_path / p)); + std::istreambuf_iterator<char> isi(is); + std::istreambuf_iterator<char> end; + + boost::filesystem::ofstream os((m_dest_path / p), std::ios_base::binary | std::ios_base::out); + std::ostreambuf_iterator<char> osi(os); + + std::copy(isi, end, osi); + } + else + { + // binary copy: + fs::copy_file(m_boost_path / p, m_dest_path / p); + } +} + +void bcp_implementation::create_path(const fs::path& p) +{ + if(!fs::exists(m_dest_path / p)) + { + // recurse then create the path: + create_path(p.branch_path()); + fs::create_directory(m_dest_path / p); + } +} + + diff --git a/src/boost/tools/bcp/file_types.cpp b/src/boost/tools/bcp/file_types.cpp new file mode 100644 index 000000000..297d304cf --- /dev/null +++ b/src/boost/tools/bcp/file_types.cpp @@ -0,0 +1,72 @@ +/* + * + * 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) + * + * This file implements the following: + * void bcp_implementation::is_source_file(const fs::path& p) + * void bcp_implementation::is_html_file(const fs::path& p) + * void bcp_implementation::is_binary_file(const fs::path& p) + */ + +#include "bcp_imp.hpp" +#include <boost/regex.hpp> + +bool bcp_implementation::is_source_file(const fs::path& p) +{ + static const boost::regex e( + ".*\\." + "(?:" + "c|cxx|h|hxx|inc|inl|.?pp|yy?" + ")", + boost::regex::perl | boost::regex::icase + ); + return boost::regex_match(p.filename().generic_string(), e); +} + +bool bcp_implementation::is_html_file(const fs::path& p) +{ + static const boost::regex e( + ".*\\." + "(?:" + "html?|css" + ")" + ); + return boost::regex_match(p.filename().generic_string(), e); +} + +bool bcp_implementation::is_binary_file(const fs::path& p) +{ + if(m_cvs_mode || m_svn_mode) + { + std::map<fs::path, bool, path_less>::iterator pos = m_cvs_paths.find(p); + if(pos != m_cvs_paths.end()) return pos->second; + } + static const boost::regex e( + ".*\\." + "(?:" + "c|cxx|cpp|h|hxx|hpp|inc|html?|css|mak|in" + ")" + "|" + "(Jamfile|makefile|configure)", + boost::regex::perl | boost::regex::icase); + return !boost::regex_match(p.leaf().generic_string(), e); + +} + +bool bcp_implementation::is_jam_file(const fs::path& p) +{ + static const boost::regex e( + ".*\\." + "(?:" + "jam|v2" + ")" + "|" + "(Jamfile|Jamroot)\\.?", + boost::regex::perl | boost::regex::icase + ); + return boost::regex_match(p.filename().generic_string(), e); +} + diff --git a/src/boost/tools/bcp/fileview.cpp b/src/boost/tools/bcp/fileview.cpp new file mode 100644 index 000000000..36e785062 --- /dev/null +++ b/src/boost/tools/bcp/fileview.cpp @@ -0,0 +1,143 @@ +/* + * + * 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) + * + * This file implements the fileview class + */ + +#include "fileview.hpp" +#include <boost/filesystem/fstream.hpp> +#include <vector> +#include <algorithm> +#include <string> +#include <fstream> +#include <istream> +#include <stdexcept> + +struct fileview::implementation +{ + std::vector<char> m_data; +}; + + +// construct: +fileview::fileview() +{ + pimpl.reset(new implementation()); +} + +fileview::fileview(const boost::filesystem::path& p) +{ + pimpl.reset(new implementation()); + open(p); +} + +fileview::~fileview() +{ +} + +fileview::fileview(const fileview& ) +{ +} + +fileview& fileview::operator=(const fileview& that) +{ + pimpl = that.pimpl; + return *this; +} + +void fileview::close() +{ + cow(); + pimpl->m_data.clear(); +} + +void fileview::open(const boost::filesystem::path& p) +{ + cow(); + boost::filesystem::ifstream is(p); + if(!is) + { + std::string msg("Bad file name: "); + msg += p.string(); + std::runtime_error e(msg); + boost::throw_exception(e); + } + std::istreambuf_iterator<char> in(is); + std::istreambuf_iterator<char> end; + std::copy(in, end, std::back_inserter(pimpl->m_data)); +} + +// iterators: +fileview::const_iterator fileview::begin() const +{ + return pimpl->m_data.size() ? &(pimpl->m_data[0]) : 0; +} + +fileview::const_iterator fileview::end() const +{ + return begin() + pimpl->m_data.size(); +} + +#ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION +fileview::const_reverse_iterator fileview::rbegin() const +{ + return const_reverse_iterator(end()); +} + +fileview::const_reverse_iterator fileview::rend() const +{ + return const_reverse_iterator(begin()); +} +#endif + +// capacity: +fileview::size_type fileview::size() const +{ + return pimpl->m_data.size(); +} + +fileview::size_type fileview::max_size() const +{ + return pimpl->m_data.max_size(); +} + +bool fileview::empty() const +{ + return pimpl->m_data.empty(); +} + +// element access: +fileview::const_reference fileview::operator[](fileview::size_type n) const +{ + return pimpl->m_data[n]; +} + +fileview::const_reference fileview::at(size_type n) const +{ + return pimpl->m_data.at(n); +} + +fileview::const_reference fileview::front() const +{ + return pimpl->m_data.front(); +} + +fileview::const_reference fileview::back() const +{ + return pimpl->m_data.back(); +} + +void fileview::swap(fileview& that) +{ + pimpl.swap(that.pimpl); +} + +void fileview::cow() +{ + if(!pimpl.unique()) + pimpl.reset(new implementation(*pimpl)); +} diff --git a/src/boost/tools/bcp/fileview.hpp b/src/boost/tools/bcp/fileview.hpp new file mode 100644 index 000000000..fe76f84ea --- /dev/null +++ b/src/boost/tools/bcp/fileview.hpp @@ -0,0 +1,72 @@ +/* + * + * 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) + * + */ + +#if defined(BOOST_FILESYSTEM_VERSION) && (BOOST_FILESYSTEM_VERSION != 3) +# error "This library must be built with Boost.Filesystem version 3" +#else +#define BOOST_FILESYSTEM_VERSION 3 +#endif + +#include <boost/shared_ptr.hpp> +#include <boost/filesystem/path.hpp> + +class fileview +{ +public: + // types: + typedef const char& reference; + typedef reference const_reference; + typedef const char* iterator; // See _lib.container.requirements_ + typedef iterator const_iterator; // See _lib.container.requirements_ + typedef std::size_t size_type; + typedef std::ptrdiff_t difference_type; + typedef char value_type; + typedef const char* pointer; + typedef pointer const_pointer; +#ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION + typedef std::reverse_iterator<iterator> reverse_iterator; + typedef std::reverse_iterator<const_iterator> const_reverse_iterator; +#endif + + // construct: + fileview(); + fileview(const boost::filesystem::path& p); + ~fileview(); + fileview(const fileview& that); + fileview& operator=(const fileview& that); + void close(); + void open(const boost::filesystem::path& p); + + // iterators: + const_iterator begin() const; + const_iterator end() const; +#ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION + const_reverse_iterator rbegin() const; + const_reverse_iterator rend() const; +#endif + + // capacity: + size_type size() const; + size_type max_size() const; + bool empty() const; + + // element access: + const_reference operator[](size_type n) const; + const_reference at(size_type n) const; + const_reference front() const; + const_reference back() const; + void swap(fileview& that); + +private: + void cow(); + struct implementation; + boost::shared_ptr<implementation> pimpl; +}; + + diff --git a/src/boost/tools/bcp/index.html b/src/boost/tools/bcp/index.html new file mode 100644 index 000000000..34e938c60 --- /dev/null +++ b/src/boost/tools/bcp/index.html @@ -0,0 +1,17 @@ +<html> + <head> + <meta http-equiv="refresh" content="0; URL=doc/html/index.html"> + </head> + <body> + <p> + Automatic redirection failed, please go to <a href="doc/html/index.html">doc/html/index.html</a>. + </p> + <p>Copyright John Maddock 2007</p> + <p>Distributed under the Boost Software License, Version 1.0. (See accompanying file <a href="../../LICENSE_1_0.txt"> + LICENSE_1_0.txt</a> or copy at <a href="http://www.boost.org/LICENSE_1_0.txt">www.boost.org/LICENSE_1_0.txt</a>).</p> + </body> +</html> + + + + diff --git a/src/boost/tools/bcp/licence_info.cpp b/src/boost/tools/bcp/licence_info.cpp new file mode 100644 index 000000000..0e527fa48 --- /dev/null +++ b/src/boost/tools/bcp/licence_info.cpp @@ -0,0 +1,721 @@ +/* + * + * 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) + * + * boostinspect:noascii + */ + +#include "licence_info.hpp" + + +std::pair<const license_info*, int> get_licenses() +{ + static const char* generic_author_sig = + "(?:" + "(?:" + "Copyright|\\(c\\)|\xA9" + ")[[:blank:]]+" + "){1,2}" + "(?:" + "\\d[^[:alpha:]]+" + "([[:alpha:]]" + "(?:" + "(?!Use\\b|Permission\\b|All\\b|<P|(?:-\\s*)\\w+(?:://|@)|\\\\" + ")[^\\n\\d]" + ")+" + ")" + "|" + "([[:alpha:]][^\\n\\d]+" + "(?:\\n[^\\n\\d]+" + ")??" + ")(?:19|20)\\d{2}" + ")" + "|" + "Authors:[[:blank:]]+" + "([[:alpha:]][^\\n\\d]+" + "|" + "((?:The|This) code is considered to be in the public domain)" + ")"; + + static const char* generic_author_format = + "(?1$1)(?2$2)(?3$3)(?4Public Domain)"; + + static const license_info licenses[] = + { + license_info( boost::regex("distributed\\W+under" + "(\\W+the)?[^\"[:word:]]+Boost\\W+Software\\W+License\\W+Version\\W+1.0", boost::regex::perl | boost::regex::icase) + , + boost::regex(generic_author_sig, boost::regex::perl | boost::regex::icase) + , + generic_author_format + , + "Boost Software License, Version 1.0" + , + "<P>Copyright (c) <I>Date</I> <I>Author</I></P>" + "<P>Distributed under the " + "Boost Software License, Version 1.0. (See accompanying file " + "LICENSE_1_0.txt or copy at <a href=\"http://www.boost.org/LICENSE_1_0.txt\">http://www.boost.org/LICENSE_1_0.txt)</a></P>" + ) + , + license_info( boost::regex("Use\\W+\\modification\\W+and\\W+distribution(\\W+is|\\W+are)\\W+subject\\W+to" + "(\\W+the)?[^\"[:word:]]+Boost\\W+Software\\W+License\\W+Version\\W+1.0", boost::regex::perl | boost::regex::icase) + , + boost::regex(generic_author_sig, boost::regex::perl | boost::regex::icase) + , + generic_author_format + , + "Boost Software License, Version 1.0 (variant #1)" + , + "<P>Copyright (c) <I>Date</I> <I>Author</I></P>" + "<P>Use, modification and distribution is subject to the " + "Boost Software License, Version 1.0. (See accompanying file " + "LICENSE_1_0.txt or copy at <a href=\"http://www.boost.org/LICENSE_1_0.txt\">http://www.boost.org/LICENSE_1_0.txt)</a></P>" + ) + , + license_info( boost::regex("(?!is)\\w\\w\\W+subject\\W+to" + "(\\W+the)?[^\"[:word:]]+Boost\\W+Software\\W+License\\W+Version\\W+1.0", boost::regex::perl | boost::regex::icase) + , + boost::regex(generic_author_sig, boost::regex::perl | boost::regex::icase) + , + generic_author_format + , + "Boost Software License, Version 1.0 (variant #2)" + , + "<P>Copyright (c) <I>Date</I> <I>Author</I></P>" + "<P>Subject to the " + "Boost Software License, Version 1.0. (See accompanying file " + "LICENSE_1_0.txt or copy at <a href=\"http://www.boost.org/LICENSE_1_0.txt\">http://www.boost.org/LICENSE_1_0.txt)</a></P>" + ) + , + license_info( boost::regex("Copyright\\W+(c)\\W+2001\\W+2002\\W+Python\\W+Software\\W+Foundation\\W+All\\W+Rights\\W+Reserved", boost::regex::perl | boost::regex::icase) + , + boost::regex(generic_author_sig, boost::regex::perl | boost::regex::icase) + , + generic_author_format + , + "Python Software License" + , + "<p>Copyright (c) 2001, 2002 Python Software Foundation;</p>" + "<P>All Rights Reserved</P>" + ) + , + license_info( boost::regex("Permission\\W+to\\W+use\\W+copy\\W+modify\\W+distribute\\W+and\\W+sell\\W+this\\W+software\\W+and\\W+its\\W+documentation" + "\\W+for\\W+any\\W+purpose\\W+is\\W+hereby\\W+granted\\W+without\\W+fee" + "\\W+provided\\W+that\\W+the\\W+above\\W+copyright\\W+notice\\W+appears?\\W+in\\W+all\\W+copies\\W+and" + "\\W+that\\W+both\\W+(the|that)\\W+copyright\\W+notice\\W+and\\W+this\\W+permission\\W+notice\\W+appears?" + "\\W+in\\W+supporting\\W+documentation[^<>]{1, 100}\\W+no\\W+representations" + "\\W+(are\\W+made\\W+)?about\\W+the\\W+suitability\\W+of\\W+this\\W+software\\W+for\\W+any\\W+purpose" + "\\W+It\\W+is\\W+provided\\W+as\\W+is\\W+without\\W+express\\W+or\\W+implied\\W+warranty" + , boost::regex::perl | boost::regex::icase) + , + boost::regex(generic_author_sig, boost::regex::perl | boost::regex::icase) + , + generic_author_format + , + "SGI Style License" + , + "<P>Copyright (c) <I>Date</I><BR>" + "<I>Author</I><BR>" + "<BR>" + "Permission to use, copy, modify, distribute and sell this software " + "and its documentation for any purpose is hereby granted without fee, " + "provided that the above copyright notice appear in all copies and " + "that both that copyright notice and this permission notice appear " + "in supporting documentation. <I>Author</I> makes no representations " + "about the suitability of this software for any purpose. " + "It is provided \"as is\" without express or implied warranty.</P>" + ) + , + license_info( boost::regex("Permission\\W+to\\W+use\\W+copy\\W+modify\\W+distribute\\W+and\\W+sell\\W+this\\W+software" + "\\W+for\\W+any\\W+purpose\\W+is\\W+hereby\\W+granted\\W+without\\W+fee" + "\\W+provided\\W+that\\W+the\\W+above\\W+copyright\\W+notice\\W+appears?\\W+in\\W+all\\W+copies\\W+and" + "\\W+that\\W+both\\W+(the|that)\\W+copyright\\W+notice\\W+and\\W+this\\W+permission\\W+notice\\W+appears?" + "\\W+in\\W+supporting\\W+documentation[^<>]{1, 100}\\W+no\\W+representations" + "\\W+(are\\W+made\\W+)?about\\W+the\\W+suitability\\W+of\\W+this\\W+software\\W+for\\W+any\\W+purpose" + "\\W+It\\W+is\\W+provided\\W+as\\W+is\\W+without\\W+express(ed)?\\W+or\\W+implied\\W+warranty", boost::regex::perl | boost::regex::icase) + , + boost::regex(generic_author_sig, boost::regex::perl | boost::regex::icase) + , + generic_author_format + , + "Old style Boost license #1" + , + "<P>Copyright (c) <I>Date</I><BR>" + "<I>Author</I><BR>" + "<BR>" + "Permission to use, copy, modify, distribute and sell this software " + "for any purpose is hereby granted without fee, " + "provided that the above copyright notice appear in all copies and " + "that both that copyright notice and this permission notice appears? " + "in supporting documentation. <I>Author</I> makes no representations " + "about the suitability of this software for any purpose. " + "It is provided \"as is\" without express or implied warranty.</P>" + ) + , + license_info( + boost::regex( + "Permission\\W+to\\W+copy\\W+use\\W+modify\\W+sell\\W+and\\W+distribute\\W+this\\W+software" + "\\W+is\\W+granted\\W+provided\\W+this\\W+copyright\\W+notice\\W+appears\\W+in\\W+all\\W+copies" + "\\W+This\\W+software\\W+is\\W+provided\\W+as\\W+is\\W+without\\W+express\\W+or\\W+implied" + "\\W+warranty\\W+and\\W+with\\W+no\\W+claim\\W+as\\W+to\\W+its\\W+suitability\\W+for\\W+any\\W+purpose" + , boost::regex::perl | boost::regex::icase + ) + , + boost::regex(generic_author_sig, boost::regex::perl | boost::regex::icase) + , + generic_author_format + , + "Old style Boost license #2" + , + "<P>Copyright (c) <I>Date</I> <I>Author</I>.<BR><BR>\n" + "Permission to copy, use, modify, sell and distribute this software<BR>\n" + "is granted provided this copyright notice appears in all copies.<BR>\n" + "This software is provided \"as is\" without express or implied<BR>\n" + "warranty, and with no claim as to its suitability for any purpose.</P>\n" + ) + , + license_info( + boost::regex( + "Permission\\W+to\\W+copy\\W+use[^\"[:word:]]+modify\\W+sell\\W+and\\W+distribute\\W+this\\W+software\\W+is\\W+granted\\W+provided" + "\\W+this\\W+copyright\\W+notice\\W+appears\\W+in\\W+all\\W+copies\\W+This\\W+software\\W+is" + "\\W+provided\\W+as\\W+is\\W+without\\W+express\\W+or\\W+implied\\W+warranty\\W+and\\W+with" + "\\W+no\\W+claim\\W+at\\W+to\\W+its\\W+suitability\\W+for\\W+any\\W+purpose" + , boost::regex::perl | boost::regex::icase + ) + , + boost::regex(generic_author_sig, boost::regex::perl | boost::regex::icase) + , + generic_author_format + , + "Old style Boost license #3" + , + "<P>(C) Copyright <I>Author</I> <I>Date</I>. Permission to copy, use, " + "modify, sell, and distribute this software is granted provided " + "this copyright notice appears in all copies. This software is " + "provided \"as is\" without express or implied warranty, and with " + "no claim at to its suitability for any purpose.</p>\n" + ) + , + license_info( boost::regex("Permission\\W+to\\W+copy\\W+use\\W+sell\\W+and\\W+distribute\\W+this\\W+software\\W+is\\W+granted" + "\\W+provided\\W+this\\W+copyright\\W+notice\\W+appears\\W+in\\W+all\\W+copies" + "\\W+Permission\\W+to\\W+modify\\W+the\\W+code\\W+and\\W+to\\W+distribute\\W+modified\\W+code\\W+is\\W+granted" + "\\W+provided\\W+this\\W+copyright\\W+notice\\W+appears\\W+in\\W+all\\W+copies\\W+and\\W+a\\W+notice" + "\\W+that\\W+the\\W+code\\W+was\\W+modified\\W+is\\W+included\\W+with\\W+the\\W+copyright\\W+notice" + "\\W+This\\W+software\\W+is\\W+provided\\W+as\\W+is\\W+without\\W+express\\W+or\\W+implied\\W+warranty\\W+and\\W+with\\W+no\\W+claim\\W+as\\W+to\\W+its\\W+suitability\\W+for\\W+any\\W+purpose" + , boost::regex::perl | boost::regex::icase) + , + boost::regex(generic_author_sig, boost::regex::perl | boost::regex::icase) + , + generic_author_format + , + "Old style Boost license #4" + , + "<P>Copyright (C) <I>Date Author</I><BR>" + "<BR>" + "Permission to copy, use, sell and distribute this software is granted\n" + "provided this copyright notice appears in all copies.\n" + "Permission to modify the code and to distribute modified code is granted\n" + "provided this copyright notice appears in all copies, and a notice\n" + "that the code was modified is included with the copyright notice.</P>\n" + "<P>This software is provided \"as is\" without express or implied warranty,\n" + "and with no claim as to its suitability for any purpose.</P>" + ) + , + license_info( boost::regex("This\\W+file\\W+is\\W+part\\W+of\\W+the\\W+(Boost\\W+Graph|Generic\\W+Graph\\W+Component)\\W+Library" + "\\W+You\\W+should\\W+have\\W+received\\W+a\\W+copy\\W+of\\W+the\\W+License\\W+Agreement\\W+for\\W+the" + "\\W+(Boost|Generic)\\W+Graph\\W+(Component\\W+)?Library\\W+along\\W+with\\W+the\\W+software;\\W+see\\W+the\\W+file\\W+LICENSE" + "(\\W+If\\W+not\\W+contact\\W+Office\\W+of\\W+Research\\W+University\\W+of\\W+Notre\\W+Dame\\W+Notre" + "\\W+Dame\\W+IN\\W+46556)?" + "\\W+Permission\\W+to\\W+modify\\W+the\\W+code\\W+and\\W+to\\W+distribute(\\W+modified|\\W+the)\\W+code\\W+is" + "\\W+granted\\W+provided\\W+the\\W+text\\W+of\\W+this\\W+NOTICE\\W+is\\W+retained\\W+a\\W+notice\\W+(that|if)" + "\\W+the\\W+code\\W+was\\W+modified\\W+is\\W+included\\W+with\\W+the\\W+above\\W+COPYRIGHT\\W+NOTICE\\W+and" + "\\W+with\\W+the\\W+COPYRIGHT\\W+NOTICE\\W+in\\W+the\\W+LICENSE\\W+file\\W+and\\W+that\\W+the\\W+LICENSE" + "\\W+file\\W+is\\W+distributed\\W+with\\W+the\\W+modified\\W+code\\W+" + "\\W+LICENSOR\\W+MAKES\\W+NO\\W+REPRESENTATIONS\\W+OR\\W+WARRANTIES\\W+EXPRESS\\W+OR\\W+IMPLIED" + "\\W+By\\W+way\\W+of\\W+example\\W+but\\W+not\\W+limitation\\W+Licensor\\W+MAKES\\W+NO" + "\\W+REPRESENTATIONS\\W+OR\\W+WARRANTIES\\W+OF\\W+MERCHANTABILITY\\W+OR\\W+FITNESS\\W+FOR\\W+ANY" + "\\W+PARTICULAR\\W+PURPOSE\\W+OR\\W+THAT\\W+THE\\W+USE\\W+OF\\W+THE\\W+LICENSED\\W+SOFTWARE\\W+COMPONENTS" + "\\W+OR\\W+DOCUMENTATION\\W+WILL\\W+NOT\\W+INFRINGE\\W+ANY\\W+PATENTS\\W+COPYRIGHTS\\W+TRADEMARKS" + "\\W+OR\\W+OTHER\\W+RIGHTS" + , boost::regex::perl | boost::regex::icase) + , + boost::regex(generic_author_sig, boost::regex::perl | boost::regex::icase) + , + generic_author_format + , + "Boost.Graph license (Notre Dame)" + , + "<P>Copyright <I>Date</I> University of Notre Dame.<BR>" + "Authors: Andrew Lumsdaine, Lie-Quan Lee, Jeremy G. Siek</P>" + "<P>This file is part of the Boost Graph Library</P>" + "<P>You should have received a copy of the <A href=\"http://www.boost.org/libs/graph/LICENCE\">License Agreement</a> for the " + "Boost Graph Library along with the software; see the file <A href=\"http://www.boost.org/libs/graph/LICENCE\">LICENSE</a>. " + "If not, contact Office of Research, University of Notre Dame, Notre " + "Dame, IN 46556.</P>" + "<P>Permission to modify the code and to distribute modified code is " + "granted, provided the text of this NOTICE is retained, a notice that " + "the code was modified is included with the above COPYRIGHT NOTICE and " + "with the COPYRIGHT NOTICE in the <A href=\"http://www.boost.org/libs/graph/LICENCE\">LICENSE</a> file, and that the <A href=\"http://www.boost.org/libs/graph/LICENCE\">LICENSE</a> " + "file is distributed with the modified code.</P>" + "<P>LICENSOR MAKES NO REPRESENTATIONS OR WARRANTIES, EXPRESS OR IMPLIED.<BR> " + "By way of example, but not limitation, Licensor MAKES NO " + "REPRESENTATIONS OR WARRANTIES OF MERCHANTABILITY OR FITNESS FOR ANY " + "PARTICULAR PURPOSE OR THAT THE USE OF THE LICENSED SOFTWARE COMPONENTS " + "OR DOCUMENTATION WILL NOT INFRINGE ANY PATENTS, COPYRIGHTS, TRADEMARKS " + "OR OTHER RIGHTS.</P>" + ) + , + license_info( boost::regex("This\\W+file\\W+is\\W+part\\W+of\\W+the\\W+(Boost\\W+Graph|Generic\\W+Graph\\W+Component)\\W+Library" + "\\W+You\\W+should\\W+have\\W+received\\W+a\\W+copy\\W+of\\W+the\\W+License\\W+Agreement\\W+for\\W+the" + "\\W+(Boost|Generic)\\W+Graph\\W+(Component\\W+)?Library\\W+along\\W+with\\W+the\\W+software;\\W+see\\W+the\\W+file\\W+LICENSE" + "(\\W+If\\W+not\\W+contact\\W+Office\\W+of\\W+Research\\W+Indiana\\W+University\\W+Bloomington\\W+IN\\W+47405)?" + "\\W+Permission\\W+to\\W+modify\\W+the\\W+code\\W+and\\W+to\\W+distribute(\\W+modified|\\W+the)\\W+code\\W+is" + "\\W+granted\\W+provided\\W+the\\W+text\\W+of\\W+this\\W+NOTICE\\W+is\\W+retained\\W+a\\W+notice\\W+(that|if)" + "\\W+the\\W+code\\W+was\\W+modified\\W+is\\W+included\\W+with\\W+the\\W+above\\W+COPYRIGHT\\W+NOTICE\\W+and" + "\\W+with\\W+the\\W+COPYRIGHT\\W+NOTICE\\W+in\\W+the\\W+LICENSE\\W+file\\W+and\\W+that\\W+the\\W+LICENSE" + "\\W+file\\W+is\\W+distributed\\W+with\\W+the\\W+modified\\W+code\\W+" + "\\W+LICENSOR\\W+MAKES\\W+NO\\W+REPRESENTATIONS\\W+OR\\W+WARRANTIES\\W+EXPRESS\\W+OR\\W+IMPLIED" + "\\W+By\\W+way\\W+of\\W+example\\W+but\\W+not\\W+limitation\\W+Licensor\\W+MAKES\\W+NO" + "\\W+REPRESENTATIONS\\W+OR\\W+WARRANTIES\\W+OF\\W+MERCHANTABILITY\\W+OR\\W+FITNESS\\W+FOR\\W+ANY" + "\\W+PARTICULAR\\W+PURPOSE\\W+OR\\W+THAT\\W+THE\\W+USE\\W+OF\\W+THE\\W+LICENSED\\W+SOFTWARE\\W+COMPONENTS" + "\\W+OR\\W+DOCUMENTATION\\W+WILL\\W+NOT\\W+INFRINGE\\W+ANY\\W+PATENTS\\W+COPYRIGHTS\\W+TRADEMARKS" + "\\W+OR\\W+OTHER\\W+RIGHTS" + , boost::regex::perl | boost::regex::icase) + , + boost::regex(generic_author_sig, boost::regex::perl | boost::regex::icase) + , + generic_author_format + , + "Boost.Graph license (Indiana University)" + , + "<P>Copyright <I>Date</I> Indiana University.<BR>" + "Authors: Andrew Lumsdaine, Lie-Quan Lee, Jeremy G. Siek</P>" + "<P>This file is part of the Boost Graph Library</P>" + "<P>You should have received a copy of the <A href=\"http://www.boost.org/libs/graph/LICENCE\">License Agreement</a> for the " + "Boost Graph Library along with the software; see the file <A href=\"http://www.boost.org/libs/graph/LICENCE\">LICENSE</a>. " + "If not, contact Office of Research, Indiana University, Bloomington," + "IN 47404.</P>" + "<P>Permission to modify the code and to distribute modified code is " + "granted, provided the text of this NOTICE is retained, a notice that " + "the code was modified is included with the above COPYRIGHT NOTICE and " + "with the COPYRIGHT NOTICE in the <A href=\"http://www.boost.org/libs/graph/LICENCE\">LICENSE</a> file, and that the <A href=\"http://www.boost.org/libs/graph/LICENCE\">LICENSE</a> " + "file is distributed with the modified code.</P>" + "<P>LICENSOR MAKES NO REPRESENTATIONS OR WARRANTIES, EXPRESS OR IMPLIED.<BR> " + "By way of example, but not limitation, Licensor MAKES NO " + "REPRESENTATIONS OR WARRANTIES OF MERCHANTABILITY OR FITNESS FOR ANY " + "PARTICULAR PURPOSE OR THAT THE USE OF THE LICENSED SOFTWARE COMPONENTS " + "OR DOCUMENTATION WILL NOT INFRINGE ANY PATENTS, COPYRIGHTS, TRADEMARKS " + "OR OTHER RIGHTS.</P>" + ) + , + license_info( boost::regex("Permission\\W+to\\W+copy\\W+use\\W+modify\\W+sell\\W+and\\W+distribute\\W+this\\W+software\\W+is" + "[^\"[:word:]]+granted\\W+provided\\W+this\\W+copyright\\W+notice\\W+appears\\W+in\\W+all\\W+copies\\W+and" + "\\W+modified\\W+version\\W+are\\W+clearly\\W+marked\\W+as\\W+such\\W+This\\W+software\\W+is\\W+provided" + "\\W+as\\W+is\\W+without\\W+express\\W+or\\W+implied\\W+warranty\\W+and\\W+with\\W+no\\W+claim\\W+as\\W+to\\W+its" + "\\W+suitability\\W+for\\W+any\\W+purpose" + , boost::regex::perl | boost::regex::icase) + , + boost::regex(generic_author_sig, boost::regex::perl | boost::regex::icase) + , + generic_author_format + , + "Old style Boost license #5" + , + "<P>Copyright (C) <I>Date Author</I></P>" + "<p>Permission to copy, use, modify, sell and distribute this software is " + "granted, provided this copyright notice appears in all copies and " + "modified version are clearly marked as such. This software is provided " + "\"as is\" without express or implied warranty, and with no claim as to its " + "suitability for any purpose.</P>" + ) + , + license_info( boost::regex("This\\W+file\\W+can\\W+be\\W+redistributed\\W+and\\W+or\\W+modified\\W+under\\W+the\\W+terms\\W+found" + "\\W+in\\W+copyright\\W+html" + "\\W+This\\W+software\\W+and\\W+its\\W+documentation\\W+is\\W+provided\\W+as\\W+is\\W+without\\W+express\\W+or" + "\\W+implied\\W+warranty\\W+and\\W+with\\W+no\\W+claim\\W+as\\W+to\\W+its\\W+suitability\\W+for\\W+any\\W+purpose" + , boost::regex::perl | boost::regex::icase) + , + boost::regex(generic_author_sig, boost::regex::perl | boost::regex::icase) + , + generic_author_format + , + "Boost.Pool license" + , + "<P>This file can be redistributed and/or modified under the terms found " + "in <a href=\"http://www.boost.org/libs/pool/doc/copyright.html\">copyright.html</a></P>\n" + "<P>This software and its documentation is provided \"as is\" without express or " + "implied warranty, and with no claim as to its suitability for any purpose</P>" + ) + , + license_info(boost::regex("Permission\\W+to\\W+use\\W+copy\\W+modify\\W+sell\\W+and\\W+distribute\\W+this\\W+software" + "\\W+is\\W+hereby\\W+granted\\W+without\\W+fee\\W+provided\\W+that\\W+the\\W+above\\W+copyright\\W+notice" + "\\W+appears\\W+in\\W+all\\W+copies\\W+and\\W+that\\W+both\\W+that\\W+copyright\\W+notice\\W+and\\W+this" + "\\W+permission\\W+notice\\W+appear\\W+in\\W+supporting\\W+documentation" + "[^<>]{1,100}\\W+(make\\W+any\\W+representation|makes\\W+no\\W+representations)\\W+about\\W+the\\W+suitability\\W+of\\W+this" + "\\W+software\\W+for\\W+any\\W+purpose\\W+It\\W+is\\W+provided\\W+as\\W+is\\W+without\\W+express\\W+or" + "\\W+implied\\W+warranty" + , boost::regex::perl | boost::regex::icase) + , + boost::regex(generic_author_sig, boost::regex::perl | boost::regex::icase) + , + generic_author_format + , + "Old style Boost license #6" + , + "<P>Copyright <I>Author Data</I></P>" + "<P>Permission to use, copy, modify, sell, and distribute this software " + "is hereby granted without fee provided that the above copyright notice " + "appears in all copies and that both that copyright notice and this " + "permission notice appear in supporting documentation, " + "<I>Author</I> makes no representations about the suitability of this " + "software for any purpose. It is provided \"as is\" without express or " + "implied warranty.</P>" + ) + , + license_info( boost::regex("Permission\\W+to\\W+copy" + "[^\"[:word:]]+use\\W+modify\\W+sell\\W+and\\W+distribute\\W+this\\W+software\\W+is\\W+granted\\W+provided" + "\\W+this\\W+copyright\\W+notice\\W+appears\\W+in\\W+all\\W+copies\\W+of\\W+the\\W+source\\W+This" + "\\W+software\\W+is\\W+provided\\W+as\\W+is\\W+without\\W+express\\W+or\\W+implied\\W+warranty" + "\\W+and\\W+with\\W+no\\W+claim\\W+as\\W+to\\W+its\\W+suitability\\W+for\\W+any\\W+purpose" + , boost::regex::perl | boost::regex::icase) + , + boost::regex(generic_author_sig, boost::regex::perl | boost::regex::icase) + , + generic_author_format + , + "Old style Boost license #7" + , + "<P>Copyright <I>Author Date</I>. Permission to copy, " + "use, modify, sell and distribute this software is granted provided " + "this copyright notice appears in all copies of the source. This " + "software is provided \"as is\" without express or implied warranty, " + "and with no claim as to its suitability for any purpose." + ) + , + license_info(boost::regex("This\\W+software\\W+is\\W+provided\\W+as-is\\W+without\\W+any\\W+express\\W+or\\W+implied" + "\\W+warranty\\W+In\\W+no\\W+event\\W+will\\W+the\\W+copyright\\W+holder\\W+be\\W+held\\W+liable\\W+for" + "\\W+any\\W+damages\\W+arising\\W+from\\W+the\\W+use\\W+of\\W+this\\W+software" + "\\W+Permission\\W+is\\W+granted\\W+to\\W+anyone\\W+to\\W+use\\W+this\\W+software\\W+for\\W+any\\W+purpose" + "\\W+including\\W+commercial\\W+applications\\W+and\\W+to\\W+alter\\W+it\\W+and\\W+redistribute" + "\\W+it\\W+freely\\W+subject\\W+to\\W+the\\W+following\\W+restrictions:" + "\\W+1\\W+The\\W+origin\\W+of\\W+this\\W+software\\W+must\\W+not\\W+be\\W+misrepresented;\\W+you\\W+must" + "\\W+not\\W+claim\\W+that\\W+you\\W+wrote\\W+the\\W+original\\W+software\\W+If\\W+you\\W+use\\W+this" + "\\W+software\\W+in\\W+a\\W+product\\W+an\\W+acknowledgment\\W+in\\W+the\\W+product\\W+documentation" + "\\W+would\\W+be\\W+appreciated\\W+but\\W+is\\W+not\\W+required" + "\\W+2\\W+Altered\\W+source\\W+versions\\W+must\\W+be\\W+plainly\\W+marked\\W+as\\W+such\\W+and\\W+must" + "\\W+not\\W+be\\W+misrepresented\\W+as\\W+being\\W+the\\W+original\\W+software" + "\\W+3\\W+This\\W+notice\\W+may\\W+not\\W+be\\W+removed\\W+or\\W+altered\\W+from\\W+any\\W+source" + "\\W+distribution" + , boost::regex::perl | boost::regex::icase) + , + boost::regex(generic_author_sig, boost::regex::perl | boost::regex::icase) + , + generic_author_format + , + "Old style Boost license #8" + , + "<P>Phoenix V0.9<BR>Copyright (c) <I>Date</I> Joel de Guzman</P>" + "<P>This software is provided 'as-is', without any express or implied " + "warranty. In no event will the copyright holder be held liable for " + "any damages arising from the use of this software.</P>" + "<P>Permission is granted to anyone to use this software for any purpose, " + "including commercial applications, and to alter it and redistribute " + "it freely, subject to the following restrictions:</P>" + "<P>1. The origin of this software must not be misrepresented; you must " + "not claim that you wrote the original software. If you use this " + "software in a product, an acknowledgment in the product documentation " + "would be appreciated but is not required.</P>" + "2. Altered source versions must be plainly marked as such, and must " + "not be misrepresented as being the original software. </P>" + "<P>3. This notice may not be removed or altered from any source " + "distribution. " + ) + , + license_info( boost::regex("Permission\\W+to\\W+use\\W+copy\\W+modify\\W+sell\\W+and\\W+distribute\\W+this\\W+software" + "\\W+is\\W+hereby\\W+granted\\W+without\\W+fee\\W+provided\\W+that\\W+the\\W+above\\W+copyright\\W+notice" + "\\W+appears\\W+in\\W+all\\W+copies\\W+and\\W+that\\W+both\\W+that\\W+copyright\\W+notice\\W+and\\W+this" + "\\W+permission\\W+notice\\W+appear\\W+in\\W+supporting\\W+documentation" + "\\W+None\\W+of\\W+the\\W+above\\W+authors\\W+nor.{1,100}make\\W+any" + "\\W+representation\\W+about\\W+the\\W+suitability\\W+of\\W+this\\W+software\\W+for\\W+any" + "\\W+purpose\\W+It\\W+is\\W+provided\\W+as\\W+is\\W+without\\W+express\\W+or\\W+implied\\W+warranty" + , boost::regex::perl | boost::regex::icase) + , + boost::regex(generic_author_sig, boost::regex::perl | boost::regex::icase) + , + generic_author_format + , + "Old style Boost license #9" + , + "<P>Copyright <I> Author Date</I><BR>" + "Permission to use, copy, modify, sell, and distribute this software " + "is hereby granted without fee provided that the above copyright notice " + "appears in all copies and that both that copyright notice and this " + "permission notice appear in supporting documentation, <BR>" + "None of the above authors nor <I>Author's Organisation</I> make any " + "representation about the suitability of this software for any " + "purpose. It is provided \"as is\" without express or implied warranty." + ) + , + license_info( boost::regex("Permission\\W+to\\W+use\\W+copy\\W+modify\\W+and\\W+distribute\\W+this\\W+software\\W+for\\W+any" + "\\W+purpose\\W+is\\W+hereby\\W+granted\\W+without\\W+fee\\W+provided\\W+that\\W+this\\W+copyright\\W+and" + "\\W+permissions\\W+notice\\W+appear\\W+in\\W+all\\W+copies\\W+and\\W+derivatives" + "\\W+This\\W+software\\W+is\\W+provided\\W+as\\W+is\\W+without\\W+express\\W+or\\W+implied\\W+warranty" + , boost::regex::perl | boost::regex::icase) + , + boost::regex(generic_author_sig, boost::regex::perl | boost::regex::icase) + , + generic_author_format + , + "Old style Boost license #10" + , + "<P>Copyright <I>Author Date</I>. All rights reserved.</P>" + "<P>Permission to use, copy, modify, and distribute this software for any " + "purpose is hereby granted without fee, provided that this copyright and " + "permissions notice appear in all copies and derivatives.</P>" + "<P>This software is provided \"as is\" without express or implied warranty.</P>" + ) + , + license_info( boost::regex("This\\W+material\\W+is\\W+provided\\W+as\\W+is\\W+with\\W+absolutely\\W+no\\W+warranty\\W+expressed" + "\\W+or\\W+implied\\W+Any\\W+use\\W+is\\W+at\\W+your\\W+own\\W+risk" + "\\W+Permission\\W+to\\W+use\\W+or\\W+copy\\W+this\\W+software\\W+for\\W+any\\W+purpose\\W+is\\W+hereby\\W+granted" + "\\W+without\\W+fee\\W+provided\\W+the\\W+above\\W+notices\\W+are\\W+retained\\W+on\\W+all\\W+copies" + "\\W+Permission\\W+to\\W+modify\\W+the\\W+code\\W+and\\W+to\\W+distribute\\W+modified\\W+code\\W+is\\W+granted" + "\\W+provided\\W+the\\W+above\\W+notices\\W+are\\W+retained\\W+and\\W+a\\W+notice\\W+that\\W+the\\W+code\\W+was" + "\\W+modified\\W+is\\W+included\\W+with\\W+the\\W+above\\W+copyright\\W+notice" + , boost::regex::perl | boost::regex::icase) + , + boost::regex(generic_author_sig, boost::regex::perl | boost::regex::icase) + , + generic_author_format + , + "Old style Boost license #11" + , + "<P>This material is provided \"as is\", with absolutely no warranty expressed " + "or implied. Any use is at your own risk.</P>" + "<P>Permission to use or copy this software for any purpose is hereby granted " + "without fee, provided the above notices are retained on all copies. " + "Permission to modify the code and to distribute modified code is granted, " + "provided the above notices are retained, and a notice that the code was " + "modified is included with the above copyright notice.</P>" + ) + , + license_info( boost::regex("Permission\\W+to\\W+copy\\W+use\\W+and\\W+distribute\\W+this\\W+software\\W+is\\W+granted\\W+provided" + "\\W+that\\W+this\\W+copyright\\W+notice\\W+appears\\W+in\\W+all\\W+copies" + "\\W+Permission\\W+to\\W+modify\\W+the\\W+code\\W+and\\W+to\\W+distribute\\W+modified\\W+code\\W+is\\W+granted" + "\\W+provided\\W+that\\W+this\\W+copyright\\W+notice\\W+appears\\W+in\\W+all\\W+copies\\W+and\\W+a\\W+notice" + "\\W+that\\W+the\\W+code\\W+was\\W+modified\\W+is\\W+included\\W+with\\W+the\\W+copyright\\W+notice" + "\\W+This\\W+software\\W+is\\W+provided\\W+as\\W+is\\W+without\\W+express\\W+or\\W+implied\\W+warranty\\W+and" + "\\W+with\\W+no\\W+claim\\W+as\\W+to\\W+its\\W+suitability\\W+for\\W+any\\W+purpose" + , boost::regex::perl | boost::regex::icase) + , + boost::regex(generic_author_sig, boost::regex::perl | boost::regex::icase) + , + generic_author_format + , + "Old style Boost license #12" + , + "<P>Copyright (C) <I>Date Author</I></P><P>Permission to copy, use, and distribute this software is granted, provided " + "that this copyright notice appears in all copies.<BR>" + "Permission to modify the code and to distribute modified code is granted, " + "provided that this copyright notice appears in all copies, and a notice " + "that the code was modified is included with the copyright notice.</P>" + "<P>This software is provided \"as is\" without express or implied warranty, and " + "with no claim as to its suitability for any purpose.</P>" + ) + , + license_info( boost::regex("Permission\\W+to\\W+copy\\W+and\\W+use\\W+this\\W+software\\W+is\\W+granted" + "\\W+provided\\W+this\\W+copyright\\W+notice\\W+appears\\W+in\\W+all\\W+copies" + "\\W+Permission\\W+to\\W+modify\\W+the\\W+code\\W+and\\W+to\\W+distribute\\W+modified\\W+code\\W+is\\W+granted" + "\\W+provided\\W+this\\W+copyright\\W+notice\\W+appears\\W+in\\W+all\\W+copies\\W+and\\W+a\\W+notice" + "\\W+that\\W+the\\W+code\\W+was\\W+modified\\W+is\\W+included\\W+with\\W+the\\W+copyright\\W+notice" + "\\W+This\\W+software\\W+is\\W+provided\\W+as\\W+is\\W+without\\W+express\\W+or\\W+implied\\W+warranty" + "\\W+and\\W+with\\W+no\\W+claim\\W+as\\W+to\\W+its\\W+suitability\\W+for\\W+any\\W+purpose" + , boost::regex::perl | boost::regex::icase) + , + boost::regex(generic_author_sig, boost::regex::perl | boost::regex::icase) + , + generic_author_format + , + "Old style Boost license #13" + , + "<P>Copyright (C) <I>Date Author</I></P>" + "<P>Permission to copy and use this software is granted, " + "provided this copyright notice appears in all copies. " + "Permission to modify the code and to distribute modified code is granted, " + "provided this copyright notice appears in all copies, and a notice " + "that the code was modified is included with the copyright notice.</P>" + "<P>This software is provided \"as is\" without express or implied warranty, " + "and with no claim as to its suitability for any purpose.</P>" + ) + , + license_info( boost::regex("Copyright\\W+Kevlin\\W+Henney\\W+2000\\W+All\\W+rights\\W+reserved\\W+" + "Permission\\W+to\\W+use\\W+copy\\W+modify\\W+and\\W+distribute\\W+this\\W+software\\W+for\\W+any" + "\\W+purpose\\W+is\\W+hereby\\W+granted\\W+without\\W+fee\\W+provided\\W+that\\W+this\\W+copyright\\W+and" + "\\W+permissions\\W+notice\\W+appear\\W+in\\W+all\\W+copies\\W+and\\W+derivatives\\W+and\\W+that\\W+no" + "\\W+charge\\W+may\\W+be\\W+made\\W+for\\W+the\\W+software\\W+and\\W+its\\W+documentation\\W+except\\W+to\\W+cover" + "\\W+cost\\W+of\\W+distribution" + "\\W+This\\W+software\\W+is\\W+provided\\W+as\\W+is\\W+without\\W+express\\W+or\\W+implied\\W+warranty\\W+" + , boost::regex::perl | boost::regex::icase) + , + boost::regex(generic_author_sig, boost::regex::perl | boost::regex::icase) + , + generic_author_format + , + "Old style Boost license #14" + , + "<P>Copyright The Author, The Date. All rights reserved.</P>" + "<P>Permission to use, copy, modify, and distribute this software for any" + " purpose is hereby granted without fee, provided that this copyright and" + " permissions notice appear in all copies and derivatives, and that no" + " charge may be made for the software and its documentation except to cover" + " cost of distribution.</P>" + "<P>This software is provided \"as is\" without express or implied warranty.</P>" + ) + , + license_info( boost::regex("preprocessed\\W+version\\W+of\\W+boost/mpl/.*\\.hpp\\W+header\\W+see\\W+the\\W+original\\W+for\\W+copyright\\W+information", boost::regex::perl | boost::regex::icase) + , + boost::regex(generic_author_sig, boost::regex::perl | boost::regex::icase) + , + generic_author_format + , + "SGI Style Licence (MPL preprocessed file)" + , + "<P>Copyright (c) <I>Date</I><BR>" + "<I>Author</I><BR>" + "<BR>" + "Permission to use, copy, modify, distribute and sell this software " + "and its documentation for any purpose is hereby granted without fee, " + "provided that the above copyright notice appear in all copies and " + "that both that copyright notice and this permission notice appear " + "in supporting documentation. <I>Author</I> makes no representations " + "about the suitability of this software for any purpose. " + "It is provided \"as is\" without express or implied warranty.</P>" + ) + , + license_info( boost::regex( + "This\\W+file\\W+is\\W+part\\W+of\\W+jam\\W+" + "License\\W+is\\W+hereby\\W+granted\\W+to\\W+use\\W+this\\W+software\\W+and\\W+distribute\\W+it\\W+" + "freely\\W+as\\W+long\\W+as\\W+this\\W+copyright\\W+notice\\W+is\\W+retained\\W+and\\W+modifications\\W+" + "are\\W+clearly\\W+marked\\W+" + "ALL\\W+WARRANTIES\\W+ARE\\W+HEREBY\\W+DISCLAIMED" + "|" + "This\\W+file\\W+is\\W+part\\W+of\\W+Jam\\W+see\\W+jam\\.c\\W+for\\W+Copyright\\W+information" + "|This file has been donated to Jam" + "|Generated by mkjambase from Jambase" , boost::regex::perl | boost::regex::icase) + , + boost::regex(generic_author_sig + std::string("|(Craig\\W+W\\W+McPheeters\\W+Alias\\W+Wavefront)|(Generated by mkjambase from Jambase)"), boost::regex::perl | boost::regex::icase) + , + generic_author_format + std::string("(?4Craig W. McPheeters, Alias|Wavefront)(?5Christopher Seiwald and Perforce Software, Inc)") + , + "Perforce Jam License" + , + "<P>Copyright 1993-2002 Christopher Seiwald and Perforce Software, Inc.</P>" + "<P>This file is part of jam.</P>" + "<P>License is hereby granted to use this software and distribute it " + "freely, as long as this copyright notice is retained and modifications " + " are clearly marked.</P>" + "<P>ALL WARRANTIES ARE HEREBY DISCLAIMED</P>" + ) + , + license_info( boost::regex( + "Permission\\W+is\\W+granted\\W+to\\W+anyone\\W+to\\W+use\\W+this\\W+software\\W+for\\W+any\\W+" + "purpose\\W+on\\W+any\\W+computer\\W+system\\W+and\\W+to\\W+redistribute\\W+it\\W+freely\\W+" + "subject\\W+to\\W+the\\W+following\\W+restrictions\\W+" + "1\\W+The\\W+author\\W+is\\W+not\\W+responsible\\W+for\\W+the\\W+consequences\\W+of\\W+use\\W+of\\W+" + "this\\W+software\\W+no\\W+matter\\W+how\\W+awful\\W+even\\W+if\\W+they\\W+arise\\W+" + "from\\W+defects\\W+in\\W+it\\W+" + "2\\W+The\\W+origin\\W+of\\W+this\\W+software\\W+must\\W+not\\W+be\\W+misrepresented\\W+either\\W+" + "by\\W+explicit\\W+claim\\W+or\\W+by\\W+omission\\W+" + "3\\W+Altered\\W+versions\\W+must\\W+be\\W+plainly\\W+marked\\W+as\\W+such\\W+and\\W+must\\W+not\\W+" + "be\\W+misrepresented\\W+as\\W+being\\W+the\\W+original\\W+software" + "|Definitions\\W+etc\\W+for\\W+regexp\\W+3\\W+routines", boost::regex::perl | boost::regex::icase) + , + boost::regex(generic_author_sig + std::string("|(Definitions\\W+etc\\W+for\\W+regexp\\W+3\\W+routines)"), boost::regex::perl | boost::regex::icase) + , + generic_author_format + std::string("(?4University of Toronto)") + , + "BSD Regex License" + , + "<P>Copyright (c) 1986 by University of Toronto.</P>" + "<P>Written by Henry Spencer. Not derived from licensed software.</P>" + "<P>Permission is granted to anyone to use this software for any" + "purpose on any computer system, and to redistribute it freely," + "subject to the following restrictions:</P>" + "<P>The author is not responsible for the consequences of use of" + "this software, no matter how awful, even if they arise" + "from defects in it.</P>" + "<p>The origin of this software must not be misrepresented, either" + "by explicit claim or by omission.</p>" + "<p>Altered versions must be plainly marked as such, and must not" + "be misrepresented as being the original software.</P>" + ) + , + license_info( boost::regex( + "Skeleton\\W+parser\\W+for\\W+Yacc\\W+like\\W+parsing\\W+with\\W+Bison\\W+" + "Copyright.{0,100}Free\\W+Software\\W+Foundation\\W+Inc\\W+" + "\\W+This\\W+program\\W+is\\W+free\\W+software\\W+you\\W+can\\W+redistribute\\W+it\\W+and\\W+or\\W+modify\\W+" + "it\\W+under\\W+the\\W+terms\\W+of\\W+the\\W+GNU\\W+General\\W+Public\\W+License\\W+as\\W+published\\W+by\\W+" + "the\\W+Free\\W+Software\\W+Foundation\\W+either\\W+version\\W+2\\W+or\\W+at\\W+your\\W+option\\W+" + "any\\W+later\\W+version" + "|" + // this part matches the start of jamgramtab.h which is under the same licence + // but bison does not output it's usual licence declaration: + "\\{\\s*\"!\"\\s*,\\s*_BANG_t\\s*\\}", boost::regex::perl | boost::regex::icase) + , + boost::regex(generic_author_sig + std::string("|(\\{\\s*\"!\"\\s*,\\s*_BANG_t\\s*\\})"), boost::regex::perl | boost::regex::icase) + , + generic_author_format + std::string("(?4Free Software Foundation, Inc)") + , + "GNU Parser Licence" + , + "<P>Skeleton parser for Yacc-like parsing with Bison,<BR>" + "Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002 Free Software Foundation, Inc.</P>" + "<P>This program is free software; you can redistribute it and/or modify" + "it under the terms of the GNU General Public License as published by" + "the Free Software Foundation; either version 2, or (at your option)" + "any later version.</P>" + "<P>This program is distributed in the hope that it will be useful," + "but WITHOUT ANY WARRANTY; without even the implied warranty of" + "MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the" + "GNU General Public License for more details.</P>" + "<P>You should have received a copy of the GNU General Public License" + "along with this program; if not, write to the Free Software" + "Foundation, Inc., 59 Temple Place - Suite 330," + "Boston, MA 02111-1307, USA.</P>" + "<P>As a special exception, when this file is copied by Bison into a" + "Bison output file, you may use that output file without restriction." + "This special exception was added by the Free Software Foundation" + "in version 1.24 of Bison.</P>" + ) + , + license_info( boost::regex( + "(?:The|This)\\W+code\\W+is\\W+considered\\W+to\\W+be\\W+in\\W+the\\W+public\\W+domain", boost::regex::perl | boost::regex::icase) + , + boost::regex(generic_author_sig, boost::regex::perl | boost::regex::icase) + , + generic_author_format + , + "Public Domain" + , + "<P>The code has no license terms, it has been explicity placed in the\n" + "public domain by it's author(s).</P>" + ) + , + }; + return std::pair<const license_info*, int>(licenses, static_cast<int>(sizeof(licenses)/sizeof(licenses[0]))); +} + +std::string format_authors_name(const std::string& name) +{ + // put name into a consistent format, so that we don't get too much + // of a proliferation of names (lots of versions of the same basic form). + + static const boost::regex e("(^)?[^-(<a-zA-ZÀ-þ]+(([(<].*)?$)?"); + static const char* formatter = "(?1:(?2: ))"; + + return boost::regex_replace(name, e, formatter, boost::match_default | boost::format_all); +} + diff --git a/src/boost/tools/bcp/licence_info.hpp b/src/boost/tools/bcp/licence_info.hpp new file mode 100644 index 000000000..e4ced2572 --- /dev/null +++ b/src/boost/tools/bcp/licence_info.hpp @@ -0,0 +1,39 @@ +/* + * + * 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 <boost/regex.hpp> +#include <utility> + +struct license_info +{ + boost::regex license_signature; + boost::regex copyright_signature; + std::string copyright_formatter; + std::string license_name; + std::string license_text; + // + // we should really be able to initialize license_info as an + // aggregate, but some compilers reject this, so use a constructor + //instead: + // + license_info(const boost::regex& e1, + const boost::regex& e2, + const std::string& s1, + const std::string& s2, + const std::string& s3) + : license_signature(e1), + copyright_signature(e2), + copyright_formatter(s1), + license_name(s2), + license_text(s3){} +}; + +std::pair<const license_info*, int> get_licenses(); + +std::string format_authors_name(const std::string& name); diff --git a/src/boost/tools/bcp/main.cpp b/src/boost/tools/bcp/main.cpp new file mode 100644 index 000000000..214c6d820 --- /dev/null +++ b/src/boost/tools/bcp/main.cpp @@ -0,0 +1,183 @@ +/* + * + * 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) + * + * This file implements the cpp_main entry point + */ + + +#include <iostream> +#include <cstring> +#include <string> +#include <list> +#include "bcp.hpp" +#include <boost/filesystem/path.hpp> +#include <boost/version.hpp> +#include <boost/detail/lightweight_main.hpp> + +#ifdef BOOST_NO_STDC_NAMESPACE +namespace std{ + using ::strcmp; + using ::strncmp; +} +#endif + +void show_usage() +{ + std::cout << + "Usage:\n" + " bcp --list [options] module-list\n" + " bcp --list-short [options] module-list\n" + " bcp --report [options] module-list html-file\n" + " bcp [options] module-list output-path\n" + "\n" + "Options:\n" + " --boost=path sets the location of the boost tree to path\n" + " --scan treat the module list as a list of (possibly non-boost)\n" + " files to scan for boost dependencies\n" + " --svn only copy files under cvs version control\n" + " --unix-lines make sure that all copied files use Unix style line endings\n" + " --namespace=name rename the boost namespace to name (also changes library names).\n" + " --namespace-alias Makes namespace boost an alias of the namespace set with --namespace.\n" + "\n" + "module-list: a list of boost files or library names to copy\n" + "html-file: the name of a html file to which the report will be written\n" + "output-path: the path to which files will be copied\n"; +} + +bool filesystem_name_check( const std::string & ) +{ + return true; +} + +int cpp_main(int argc, char* argv[]) +{ + // + // Before anything else replace Boost.filesystem's file + // name checker with one that does nothing (we only deal + // with files that already exist, if they're not portable + // names it's too late for us to do anything about it). + // + /*boost::filesystem::path::default_name_check(filesystem_name_check);*/ + // + // without arguments just show help: + // + if(argc < 2) + { + std::cout << "Error: insufficient arguments, don't know what to do." << std::endl; + show_usage(); + return 1; + } + // + // create the application object: + // + pbcp_application papp(bcp_application::create()); + // + // work through args, and tell the application + // object what ir needs to do: + // + bool list_mode = false; + std::list<const char*> positional_args; + for(int i = 1; i < argc; ++i) + { + if(0 == std::strcmp("-h", argv[i]) + || 0 == std::strcmp("--help", argv[i])) + { + show_usage(); + return 0; + } + if(0 == std::strcmp("-v", argv[i]) + || 0 == std::strcmp("--version", argv[i])) + { + std::cout << "bcp " << (BOOST_VERSION / 100000) << "." << (BOOST_VERSION / 100 % 1000) << "." << (BOOST_VERSION % 100) << std::endl; + std::cout << __DATE__ << std::endl; + return 0; + } + else if(0 == std::strcmp("--list", argv[i])) + { + list_mode = true; + papp->enable_list_mode(); + } + else if(0 == std::strcmp("--list-short", argv[i])) + { + list_mode = true; + papp->enable_summary_list_mode(); + } + else if(0 == std::strcmp("--report", argv[i])) + { + papp->enable_license_mode(); + } + else if(0 == std::strcmp("--cvs", argv[i])) + { + papp->enable_cvs_mode(); + } + else if(0 == std::strcmp("--svn", argv[i])) + { + papp->enable_svn_mode(); + } + else if(0 == std::strcmp("--scan", argv[i])) + { + papp->enable_scan_mode(); + } + else if(0 == std::strcmp("--bsl-convert", argv[i])) + { + papp->enable_bsl_convert_mode(); + } + else if(0 == std::strcmp("--bsl-summary", argv[i])) + { + papp->enable_bsl_summary_mode(); + } + else if(0 == std::strcmp("--unix-lines", argv[i])) + { + papp->enable_unix_lines(); + } + else if(0 == std::strncmp("--boost=", argv[i], 8)) + { + papp->set_boost_path(argv[i] + 8); + } + else if(0 == std::strncmp("--namespace=", argv[i], 12)) + { + papp->set_namespace(argv[i] + 12); + } + else if(0 == std::strncmp("--namespace-alias", argv[i], 17)) + { + papp->set_namespace_alias(true); + } + else if(0 == std::strncmp("--list-namespaces", argv[i], 17)) + { + list_mode = true; + papp->set_namespace_list(true); + } + else if(argv[i][0] == '-') + { + std::cout << "Error: Unknown argument " << argv[i] << std::endl; + show_usage(); + return 1; + } + else + { + positional_args.push_back(argv[i]); + } + } + // + // Handle positional args last: + // + for(std::list<const char*>::const_iterator i = positional_args.begin(); + i != positional_args.end(); ++i) + { + if(!list_mode && (i == --positional_args.end())) + papp->set_destination(*i); + else + papp->add_module(*i); + } + // + // run the application object: + // + return papp->run(); +} + + + diff --git a/src/boost/tools/bcp/output_licence_info.cpp b/src/boost/tools/bcp/output_licence_info.cpp new file mode 100644 index 000000000..d42268fdb --- /dev/null +++ b/src/boost/tools/bcp/output_licence_info.cpp @@ -0,0 +1,410 @@ +/* + * + * 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 <fstream> +#include <iomanip> +#include <cstring> +#include <stdexcept> +#include <boost/lexical_cast.hpp> +#include <boost/filesystem/operations.hpp> +#include <boost/throw_exception.hpp> + +// +// 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){} +private: + split_path& operator=(const split_path&); +}; + +std::ostream& operator << (std::ostream& os, const split_path& p) +{ + os << "<a href=\"" << (p.root / p.file).string() << "\">" << p.file.string() << "</a>"; + return os; +} + +std::string make_link_target(const std::string& s) +{ + // convert an arbitrary string into something suitable + // for an <a> name: + std::string result; + for(unsigned i = 0; i < s.size(); ++i) + { + result.append(1, static_cast<std::string::value_type>(std::isalnum(s[i]) ? s[i] : '_')); + } + return result; +} + + +void bcp_implementation::output_license_info() +{ + std::pair<const license_info*, int> licenses = get_licenses(); + + std::map<int, license_data>::const_iterator i, j; + i = m_license_data.begin(); + j = m_license_data.end(); + + std::ofstream os(m_dest_path.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 << + "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.0 Transitional//EN\">\n" + "<html>\n" + "<head>\n" + "<title>Boost Licence Dependency Information"; + if(m_module_list.size() == 1) + { + os << " for " << *(m_module_list.begin()); + } + os << + "</title>\n" + "</head>\n" + "<body>\n" + "<H1>Boost Licence Dependency Information"; + if(m_module_list.size() == 1) + { + os << " for " << *(m_module_list.begin()); + } + os << + "</H1>\n" + "<H2>Contents</h2>\n" + "<pre><a href=\"#input\">Input Information</a>\n"; + if(!m_bsl_summary_mode) + os << "<a href=\"#summary\">Licence Summary</a>\n"; + os << "<a href=\"#details\">Licence Details</a>\n"; + + while(i != j) + { + // title: + os << " <A href=\"#" << make_link_target(licenses.first[i->first].license_name) + << "\">" << licenses.first[i->first].license_name << "</a>\n"; + ++i; + } + + os << "<a href=\"#files\">Files with no recognised license</a>\n" + "<a href=\"#authors\">Files with no recognised copyright holder</a>\n"; + if(!m_bsl_summary_mode) + { + os << + "Moving to the Boost Software License...\n" + " <a href=\"#bsl-converted\">Files that can be automatically converted to the Boost Software License</a>\n" + " <a href=\"#to-bsl\">Files that can be manually converted to the Boost Software License</a>\n" + " <a href=\"#not-to-bsl\">Files that can <b>NOT</b> be moved to the Boost Software License</a>\n" + " <a href=\"#need-bsl-authors\">Authors we need to move to the Boost Software License</a>\n" + "<a href=\"#copyright\">Copyright Holder Information</a>\n"; + } + os << + "<a href=\"#depend\">File Dependency Information</a>\n" + "</pre>"; + + // + // input Information: + // + os << "<a name=\"input\"></a><h2>Input Information</h2>\n"; + if(m_scan_mode) + os << "<P>The following files were scanned for boost dependencies:<BR>"; + else + os << "<P>The following Boost modules were checked:<BR>"; + + std::list<std::string>::const_iterator si = m_module_list.begin(); + std::list<std::string>::const_iterator sj = m_module_list.end(); + while(si != sj) + { + os << *si << "<BR>"; + ++si; + } + os << "</p><p>The Boost path was: <code>" << m_boost_path.string() << "</code></P>"; + // + // 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<int>(what.str(1)); + os << "<p>The Boost version is: " << version / 100000 << "." << version / 100 % 1000 << "." << version % 100 << "</P>\n"; + } + + // + // output each license: + // + i = m_license_data.begin(); + j = m_license_data.end(); + if(!m_bsl_summary_mode) + { + // + // start with the summary: + // + os << "<a name=\"summary\"></a><h2>Licence Summary</h2>\n"; + while(i != j) + { + // title: + os << + "<H3>" << licenses.first[i->first].license_name << "</H3>\n"; + // license text: + os << "<BLOCKQUOTE>" << licenses.first[i->first].license_text << "</BLOCKQUOTE>"; + // Copyright holders: + os << "<P>This license is used by " << i->second.authors.size() + << " authors and " << i->second.files.size() + << " files <a href=\"#" << make_link_target(licenses.first[i->first].license_name) << "\">(see details)</a>"; + os << "</P></BLOCKQUOTE>\n"; + ++i; + } + } + // + // and now the details: + // + i = m_license_data.begin(); + j = m_license_data.end(); + int license_index = 0; + os << "<a name=\"details\"></a><h2>Licence Details</h2>\n"; + while(i != j) + { + // title: + os << + "<H3><A name=\"" << make_link_target(licenses.first[i->first].license_name) + << "\"></a>" << licenses.first[i->first].license_name << "</H3>\n"; + // license text: + os << "<BLOCKQUOTE>" << licenses.first[i->first].license_text << "</BLOCKQUOTE>"; + if(!m_bsl_summary_mode || (license_index >= 3)) + { + // Copyright holders: + os << "<P>This license is used by the following " << i->second.authors.size() << " copyright holders:</P>\n<BLOCKQUOTE><P>"; + std::set<std::string>::const_iterator x, y; + x = i->second.authors.begin(); + y = i->second.authors.end(); + while(x != y) + { + os << *x << "<BR>\n"; + ++x; + } + os << "</P></BLOCKQUOTE>\n"; + // Files using this license: + os << "<P>This license applies to the following " << i->second.files.size() << " files:</P>\n<BLOCKQUOTE><P>"; + std::set<fs::path, path_less>::const_iterator m, n; + m = i->second.files.begin(); + n = i->second.files.end(); + while(m != n) + { + os << split_path(m_boost_path, *m) << "<br>\n"; + ++m; + } + os << "</P></BLOCKQUOTE>\n"; + } + else + { + os << "<P>This license is used by " << i->second.authors.size() << " authors (list omitted for brevity).</P>\n"; + os << "<P>This license applies to " << i->second.files.size() << " files (list omitted for brevity).</P>\n"; + } + ++license_index; + ++i; + } + // + // Output list of files not found to be under license control: + // + os << "<h2><a name=\"files\"></a>Files With No Recognisable Licence</h2>\n" + "<P>The following " << m_unknown_licenses.size() << " files had no recognisable license information:</P><BLOCKQUOTE><P>\n"; + std::set<fs::path, path_less>::const_iterator i2, j2; + i2 = m_unknown_licenses.begin(); + j2 = m_unknown_licenses.end(); + while(i2 != j2) + { + os << split_path(m_boost_path, *i2) << "<br>\n"; + ++i2; + } + os << "</p></BLOCKQUOTE>"; + // + // Output list of files with no found copyright holder: + // + os << "<h2><a name=\"authors\"></a>Files With No Recognisable Copyright Holder</h2>\n" + "<P>The following " << m_unknown_authors.size() << " files had no recognisable copyright holder:</P>\n<BLOCKQUOTE><P>"; + i2 = m_unknown_authors.begin(); + j2 = m_unknown_authors.end(); + while(i2 != j2) + { + os << split_path(m_boost_path, *i2) << "<br>\n"; + ++i2; + } + os << "</p></BLOCKQUOTE>"; + 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 << "<h2><a name=\"bsl-converted\"></a>Files that can be automatically converted to the Boost Software License</h2>\n" + << "<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"; + if (!m_converted_to_bsl.empty()) + { + typedef std::map<fs::path, std::pair<std::string, std::string>, 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 << "<P>[" << file_num << "] File: <tt>" << split_path(m_boost_path, i->first) + << "</tt><br>\n<table border=\"1\">\n <tr>\n <td><pre>" + << i->second.first << "</pre></td>\n <td><pre>" + << i->second.second << "</pre></td>\n </tr>\n</table>\n"; + ++i; + ++file_num; + } + } + // + // Output list of files that could be moved over to the Boost Software License + // + os << "<h2><a name=\"to-bsl\"></a>Files that could be converted to the Boost Software License</h2>\n" + "<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>"; + i2 = m_can_migrate_to_bsl.begin(); + j2 = m_can_migrate_to_bsl.end(); + while(i2 != j2) + { + os << split_path(m_boost_path, *i2) << "<br>\n"; + ++i2; + } + os << "</p></BLOCKQUOTE>"; + // + // Output list of files that can not be moved over to the Boost Software License + // + os << "<h2><a name=\"not-to-bsl\"></a>Files that can NOT be converted to the Boost Software License</h2>\n" + "<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>"; + i2 = m_cannot_migrate_to_bsl.begin(); + j2 = m_cannot_migrate_to_bsl.end(); + while(i2 != j2) + { + os << split_path(m_boost_path, *i2) << "<br>\n"; + ++i2; + } + os << "</p></BLOCKQUOTE>"; + // + // Output list of authors that we need permission for to move to the BSL + // + os << "<h2><a name=\"need-bsl-authors\"></a>Authors we need for the BSL</h2>\n" + "<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>"; + std::copy(m_authors_for_bsl_migration.begin(), m_authors_for_bsl_migration.end(), + std::ostream_iterator<std::string>(os, "<br>\n")); + os << "</p></BLOCKQUOTE>"; + // + // output a table of copyright information: + // + os << "<H2><a name=\"copyright\"></a>Copyright Holder Information</H2><table border=\"1\">\n"; + std::map<std::string, std::set<fs::path, path_less> >::const_iterator ad, ead; + ad = m_author_data.begin(); + ead = m_author_data.end(); + while(ad != ead) + { + os << "<tr><td>" << ad->first << "</td><td>"; + std::set<fs::path, path_less>::const_iterator fi, efi; + fi = ad->second.begin(); + efi = ad->second.end(); + while(fi != efi) + { + os << split_path(m_boost_path, *fi) << " "; + ++fi; + } + os << "</td></tr>\n"; + ++ad; + } + os << "</table>\n"; + } + + // + // output file dependency information: + // + os << "<H2><a name=\"depend\"></a>File Dependency Information</H2><BLOCKQUOTE><pre>\n"; + std::map<fs::path, fs::path, path_less>::const_iterator dep, last_dep; + std::set<fs::path, path_less>::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<fs::path, path_less> 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<fs::path, std::pair<std::string, std::string>, 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 << "<P>For brevity, only files not under the BSL are shown</P>\n"; + } + while(fi != efi) + { + os << split_path(m_boost_path, *fi); + dep = m_dependencies.find(*fi); + last_dep = m_dependencies.end(); + std::set<fs::path, path_less> 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 << " <I>(Circular dependency!)</I>"; + 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 << "</pre></BLOCKQUOTE>\n"; + + os << "</body></html>\n"; + + if(!os) + { + std::string msg("Error writing to "); + msg += m_dest_path.string(); + msg += "."; + std::runtime_error e(msg); + boost::throw_exception(e); + } + +} diff --git a/src/boost/tools/bcp/path_operations.cpp b/src/boost/tools/bcp/path_operations.cpp new file mode 100644 index 000000000..aebbc4e6f --- /dev/null +++ b/src/boost/tools/bcp/path_operations.cpp @@ -0,0 +1,41 @@ +/* + * + * 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) + * + * This file implements path comparisons + */ + + +#include "bcp_imp.hpp" +#include <cctype> + +#ifdef BOOST_NO_STDC_NAMESPACE +namespace std{ + using ::tolower; +} +#endif + + +int compare_paths(const fs::path& a, const fs::path& b) +{ + const std::string& as = a.generic_string(); + const std::string& bs = b.generic_string(); + std::string::const_iterator i, j, k, l; + i = as.begin(); + j = as.end(); + k = bs.begin(); + l = bs.end(); + while(i != j) + { + if(k == l) + return -1; + int r = std::tolower(*i) - std::tolower(*k); + if(r) return r; + ++i; + ++k; + } + return (k == l) ? 0 : 1; +} diff --git a/src/boost/tools/bcp/scan_cvs_path.cpp b/src/boost/tools/bcp/scan_cvs_path.cpp new file mode 100644 index 000000000..6d2eb3a60 --- /dev/null +++ b/src/boost/tools/bcp/scan_cvs_path.cpp @@ -0,0 +1,147 @@ +/* + * + * Copyright (c) 2003-7 John Maddock + * Copyright (c) 2007 Bjorn Roald + * 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) + * + * This file implements the following: + * void bcp_implementation::scan_cvs_path(const fs::path& p) + */ + + + +#include "bcp_imp.hpp" +#include "fileview.hpp" +#include <boost/regex.hpp> +#include <boost/filesystem/operations.hpp> +#include <boost/detail/workaround.hpp> +#include <iostream> + +void bcp_implementation::scan_cvs_path(const fs::path& p) +{ + // + // scan through the cvs admin files to build a list + // of all the files under cvs version control + // and whether they are text or binary: + // + static const char* file_list[] = { "CVS/Entries", "CVS/Entries.Log" }; + static const boost::regex file_expression("^(?:A\\s+)?/([^/\\n]+)/[^/\\n]*/[^/\\n]*/[^k/\\n]*(kb[^/\\n]*)?/[^/\\n]*"); + static const boost::regex dir_expression("^(?:A\\s+)?D/([^/\\n]+)/"); + static const int file_subs[] = {1,2,}; + + for(std::size_t entry = 0; entry < sizeof(file_list)/sizeof(file_list[0]); ++entry) + { + fs::path entries(m_boost_path / p / file_list[entry]); + if(fs::exists(entries)) + { + fileview view(entries); + boost::regex_token_iterator<const char*> i(view.begin(), view.end(), dir_expression, 1); + boost::regex_token_iterator<const char*> j; + while(i != j) + { + fs::path recursion_dir(p / i->str()); + scan_cvs_path(recursion_dir); + ++i; + } + #if BOOST_WORKAROUND(BOOST_MSVC, < 1300) || BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x570)) + std::vector<int> v(file_subs, file_subs + 2); + i = boost::regex_token_iterator<const char*>(view.begin(), view.end(), file_expression, v); + #else + i = boost::regex_token_iterator<const char*>(view.begin(), view.end(), file_expression, file_subs); + #endif + while(i != j) + { + fs::path file = p / i->str(); + ++i; + bool binary = i->length() ? true : false; + ++i; + m_cvs_paths[file] = binary; + } + + } + } +} + +void bcp_implementation::scan_svn_path(const fs::path& p) +{ + // + // scan through the svn entries files to build a list + // of all the files under svn version control + // and whether they are text or binary: + // + static const boost::regex entry_expression("^\\f([^\\f]*)"); + static const boost::regex entry_line_expression("\\n[[:blank:]]*([^\\n]*)"); + // static const boost::regex + // mime_type_expression("\\nsvn:mime-type\\nV [[digit]]*\\n([^/]*)[^\\n]*"); + + fs::path entries(m_boost_path / p / ".svn" / "entries"); + if(fs::exists(entries)) + { + fileview view(entries); + boost::cregex_token_iterator + i(view.begin(), view.end(), entry_expression, 1), j; + + while(i != j) // entries + { + std::string entr = i->str(); + boost::sregex_token_iterator + atr_it(entr.begin(), entr.end(), entry_line_expression, 1), atr_j; + + if(atr_it != atr_j) + { + std::string name = atr_it->str(); // name of file or directory + fs::path fpath = p / name; + if(++atr_it != atr_j) + { + std::string kind = atr_it->str(); + if(kind == "file") + { + // find if binary, we asume text unless mime type is + // set in property file + bool binary = false; // + + // skip some lines type | example + if( ++atr_it != atr_j && // revnum | + ++atr_it != atr_j && // url | + ++atr_it != atr_j && // repos | + ++atr_it != atr_j && // scedule attr | + ++atr_it != atr_j && // text timestamp | 2007-09-02T... + ++atr_it != atr_j && // checksum | 58f4bfa7860... + ++atr_it != atr_j && // cmt_date | 2007-05-09T... + ++atr_it != atr_j && // cmt_rev | 37654 + ++atr_it != atr_j && // cmt_author | dgregor + ++atr_it != atr_j ) // has_props | has-props + { + if(atr_it->str() == "has-props") + { + // we need to check properties file for mime-type + // that does not start with "text/", if found file is binary + fs::path properties(m_boost_path / p / ".svn" / "prop-base" + / (name + ".svn-base") ); + if(fs::exists(properties)) + { + fileview prop(properties); + + static const boost::regex mime_type( + "svn:mime-type[[:blank:]]*(?:\\n|\\r|\\r\\n)[^\\r\\n]*(?:\\n|\\r|\\r\\n)[[:blank:]]*text/"); + binary = regex_search(prop.begin(), prop.end(), mime_type) ? false : true; + } + } + } + m_cvs_paths[fpath] = binary; + } // kind == "file" + else if(kind == "dir") + { + scan_svn_path(fpath); // recursion for directory entries + } + // else + // std::cerr << "WARNING: unknown entry kind for entry " << name + // << "in " << entries << std::endl; + } + } + ++i; + } // while + } +} diff --git a/src/boost/tools/bcp/scan_licence.cpp b/src/boost/tools/bcp/scan_licence.cpp new file mode 100644 index 000000000..4dc461c14 --- /dev/null +++ b/src/boost/tools/bcp/scan_licence.cpp @@ -0,0 +1,275 @@ +/* + * + * 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 <fstream> +#include <iostream> + + +const int boost_license_lines = 3; +static const std::string boost_license_text[boost_license_lines] = { + "Distributed under 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)" +}; + +fileview::const_iterator +context_before_license(const fileview& v, fileview::const_iterator start, + int context_lines = 3) +{ + char last_char = '\0'; + while (start != v.begin() && context_lines >= 0) { + if (((*start == '\r') || (*start == '\n')) + && ((last_char == *start) || ((last_char != '\r') && (last_char != '\n')))) + --context_lines; + + last_char = *start; + --start; + } + + // Unless we hit the beginning, we need to step forward one to start + // on the next line. + if (start != v.begin()) ++start; + + return start; +} + +fileview::const_iterator +context_after_license(const fileview& v, fileview::const_iterator end, + int context_lines = 3) +{ + char last_char = '\0'; + while (end != v.end() && context_lines >= 0) { + if ((*end == '\r' || *end == '\n') + && (last_char == *end || (last_char != '\r' && last_char != '\n'))) + --context_lines; + + last_char = *end; + ++end; + } + + return end; +} + +static std::string +find_prefix(const fileview& v, fileview::const_iterator start_of_line) +{ + while (start_of_line != v.begin() + && *start_of_line != '\n' + && *start_of_line != '\r') + --start_of_line; + if (start_of_line != v.begin()) + ++start_of_line; + + fileview::const_iterator first_noncomment_char = start_of_line; + while (*first_noncomment_char == '/' + || *first_noncomment_char == '*' + || *first_noncomment_char == ' ' + || *first_noncomment_char == '#') + ++first_noncomment_char; + + return std::string(start_of_line, first_noncomment_char); +} + +static std::string +html_escape(fileview::const_iterator first, fileview::const_iterator last) +{ + std::string result; + while (first != last) { + switch (*first) { + case '<': result += "<"; break; + case '>': result += ">"; break; + case '&': result += "&"; break; + default: result += *first; + } + ++first; + } + return result; +} + +static bool is_non_bsl_license(int index) +{ + return index > 2; +} + +void bcp_implementation::scan_license(const fs::path& p, const fileview& v) +{ + std::pair<const license_info*, int> licenses = get_licenses(); + // + // scan file for all the licenses in the list: + // + int license_count = 0; + int author_count = 0; + int nonbsl_author_count = 0; + bool has_non_bsl_license = false; + fileview::const_iterator start_of_license = v.begin(), + end_of_license = v.end(); + bool start_in_middle_of_line = false; + + for(int i = 0; i < licenses.second; ++i) + { + boost::match_results<fileview::const_iterator> m; + if(boost::regex_search(v.begin(), v.end(), m, licenses.first[i].license_signature)) + { + start_of_license = m[0].first; + end_of_license = m[0].second; + + if (is_non_bsl_license(i) && i < licenses.second - 1) + has_non_bsl_license = true; + + // add this license to the list: + m_license_data[i].files.insert(p); + ++license_count; + // + // scan for the associated copyright declarations: + // + boost::regex_iterator<const char*> cpy(v.begin(), v.end(), licenses.first[i].copyright_signature); + boost::regex_iterator<const char*> ecpy; + while(cpy != ecpy) + { +#if 0 + // Not dealing with copyrights because we don't have the years + if ((*cpy)[0].first < start_of_license) + start_of_license = (*cpy)[0].first; + if ((*cpy)[0].second > end_of_license) + end_of_license = (*cpy)[0].second; +#endif + + // extract the copy holders as a list: + std::string author_list = cpy->format(licenses.first[i].copyright_formatter, boost::format_all); + // now enumerate that list for all the names: + static const boost::regex author_separator("(?:\\s*,(?!\\s*(?:inc|ltd)\\b)\\s*|\\s+(,\\s*)?(and|&)\\s+)|by\\s+", boost::regex::perl | boost::regex::icase); + boost::regex_token_iterator<std::string::const_iterator> atr(author_list.begin(), author_list.end(), author_separator, -1); + boost::regex_token_iterator<std::string::const_iterator> eatr; + while(atr != eatr) + { + // get the reformatted authors name: + std::string name = format_authors_name(*atr); + // add to list of authors for this file: + if(name.size() && name[0] != '-') + { + m_license_data[i].authors.insert(name); + // add file to author index: + m_author_data[name].insert(p); + ++author_count; + + // If this is not the Boost Software License (license 0), and the author hasn't given + // blanket permission, note this for the report. + if (has_non_bsl_license + && m_bsl_authors.find(name) == m_bsl_authors.end()) { + ++nonbsl_author_count; + m_authors_for_bsl_migration.insert(name); + } + } + ++atr; + } + ++cpy; + } + + while (start_of_license != v.begin() + && *start_of_license != '\r' + && *start_of_license != '\n' + && *start_of_license != '.') + --start_of_license; + + if (start_of_license != v.begin()) { + if (*start_of_license == '.') + start_in_middle_of_line = true; + ++start_of_license; + } + + while (end_of_license != v.end() + && *end_of_license != '\r' + && *end_of_license != '\n') + ++end_of_license; + } + } + if(license_count == 0) + m_unknown_licenses.insert(p); + if(license_count && !author_count) + m_unknown_authors.insert(p); + + if (has_non_bsl_license) { + bool converted = false; + if (nonbsl_author_count == 0 + && license_count == 1) { + // Grab a few lines of context + fileview::const_iterator context_start = + context_before_license(v, start_of_license); + fileview::const_iterator context_end = + context_after_license(v, end_of_license); + + // TBD: For files that aren't C++ code, this will have to + // change. + std::string prefix = find_prefix(v, start_of_license); + + // Create enough information to permit manual verification of + // the correctness of the transformation + std::string before_conversion = + html_escape(context_start, start_of_license); + before_conversion += "<b>"; + before_conversion += html_escape(start_of_license, end_of_license); + before_conversion += "</b>"; + before_conversion += html_escape(end_of_license, context_end); + + std::string after_conversion = + html_escape(context_start, start_of_license); + if (start_in_middle_of_line) + after_conversion += '\n'; + + after_conversion += "<b>"; + for (int i = 0; i < boost_license_lines; ++i) { + if (i > 0) after_conversion += '\n'; + after_conversion += prefix + boost_license_text[i]; + } + after_conversion += "</b>"; + after_conversion += html_escape(end_of_license, context_end); + + m_converted_to_bsl[p] = + std::make_pair(before_conversion, after_conversion); + + // Perform the actual conversion + if (m_bsl_convert_mode) { + try{ + std::ofstream out((m_boost_path / p).string().c_str()); + if (!out) { + std::string msg("Cannot open file for license conversion: "); + msg += p.string(); + std::runtime_error e(msg); + boost::throw_exception(e); + } + + out << std::string(v.begin(), start_of_license); + if (start_in_middle_of_line) + out << std::endl; + + for (int j = 0; j < boost_license_lines; ++j) { + if (j > 0) out << std::endl; + out << prefix << boost_license_text[j]; + } + out << std::string(end_of_license, v.end()); + + converted = true; + } + catch(const std::exception& e) + { + std::cerr << e.what() << std::endl; + } + } + } + + if (!converted) { + if (nonbsl_author_count > 0) m_cannot_migrate_to_bsl.insert(p); + else m_can_migrate_to_bsl.insert(p); + } + } +} + diff --git a/src/boost/tools/bcp/test/Jamfile.v2 b/src/boost/tools/bcp/test/Jamfile.v2 new file mode 100644 index 000000000..bea522489 --- /dev/null +++ b/src/boost/tools/bcp/test/Jamfile.v2 @@ -0,0 +1,25 @@ +# (C) Copyright John Maddock 2006. +# Distributed under the Boost Software License, Version 1.0. +# (See accompanying file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt) + +path-constant boost-path : ../../.. ; + +run + # sources + ../add_dependent_lib.cpp ../add_path.cpp ../bcp_imp.cpp ../copy_path.cpp ../file_types.cpp + ../fileview.cpp ../main.cpp ../path_operations.cpp ../scan_cvs_path.cpp + ../licence_info.cpp ../scan_licence.cpp ../output_licence_info.cpp + /boost/filesystem//boost_filesystem + /boost/regex//boost_regex + /boost/test//boost_prg_exec_monitor + : # args + --boost=$(boost-path) --list boost + : # input-files + : # requirements + release + : # target-name + bcp-test + : # default-build + release + ; + |