summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
Diffstat (limited to '3rdParty/Boost/src/tools/bcp/add_dependent_lib.cpp')
-rw-r--r--3rdParty/Boost/src/tools/bcp/add_dependent_lib.cpp216
1 files changed, 216 insertions, 0 deletions
diff --git a/3rdParty/Boost/src/tools/bcp/add_dependent_lib.cpp b/3rdParty/Boost/src/tools/bcp/add_dependent_lib.cpp
new file mode 100644
index 0000000..bb1818a
--- /dev/null
+++ b/3rdParty/Boost/src/tools/bcp/add_dependent_lib.cpp
@@ -0,0 +1,216 @@
+/*
+ *
+ * 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*"
+ "\\{" // start of definition
+ "|"
+ "(\\<\\w+\\>)" // Maybe class name
+ "\\s*"
+ "(?:<[^>;{]*>)?" // Maybe template specialisation
+ "::\\s*"
+ "~?\\1" // function name, same as class name
+ "\\s*"
+ "\\("
+ "[^\\(\\);{}]*" // argument list
+ "\\)"
+ "\\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*;)";
+
+ 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"));
+ }
+ }
+ }
+ }
+ }
+}