| [12] | 1 | /* | 
|---|
 | 2 |  * | 
|---|
 | 3 |  * Copyright (c) 2003 Dr John Maddock | 
|---|
 | 4 |  * Use, modification and distribution is subject to the  | 
|---|
 | 5 |  * Boost Software License, Version 1.0. (See accompanying file  | 
|---|
 | 6 |  * LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) | 
|---|
 | 7 |  * | 
|---|
 | 8 |  * This file implements the following: | 
|---|
 | 9 |  *    void bcp_implementation::add_path(const fs::path& p) | 
|---|
 | 10 |  *    void bcp_implementation::add_directory(const fs::path& p) | 
|---|
 | 11 |  *    void bcp_implementation::add_file(const fs::path& p) | 
|---|
 | 12 |  *    void bcp_implementation::add_dependent_lib(const std::string& libname) | 
|---|
 | 13 |  */ | 
|---|
 | 14 |  | 
|---|
 | 15 | #include "bcp_imp.hpp" | 
|---|
 | 16 | #include "fileview.hpp" | 
|---|
 | 17 | #include <boost/regex.hpp> | 
|---|
 | 18 | #include <boost/filesystem/operations.hpp> | 
|---|
 | 19 | #include <boost/filesystem/exception.hpp> | 
|---|
 | 20 | #include <iostream> | 
|---|
 | 21 |  | 
|---|
 | 22 |  | 
|---|
 | 23 | void bcp_implementation::add_path(const fs::path& p) | 
|---|
 | 24 | { | 
|---|
 | 25 |    fs::path normalized_path = p; | 
|---|
 | 26 |    normalized_path.normalize(); | 
|---|
 | 27 |    if(fs::exists(m_boost_path / normalized_path)) | 
|---|
 | 28 |    { | 
|---|
 | 29 |       if(fs::is_directory(m_boost_path / normalized_path)) | 
|---|
 | 30 |          add_directory(normalized_path); | 
|---|
 | 31 |       else | 
|---|
 | 32 |          add_file(normalized_path); | 
|---|
 | 33 |    } | 
|---|
 | 34 |    else | 
|---|
 | 35 |    { | 
|---|
 | 36 |       std::cerr << "CAUTION: dependent file " << p.string() << " does not exist." << std::endl; | 
|---|
 | 37 |    } | 
|---|
 | 38 | } | 
|---|
 | 39 |  | 
|---|
 | 40 | void bcp_implementation::add_directory(const fs::path& p) | 
|---|
 | 41 | { | 
|---|
 | 42 |    // | 
|---|
 | 43 |    // don't add files created by build system | 
|---|
 | 44 |    // | 
|---|
 | 45 |    if((p.leaf() == "bin") || (p.leaf() == "bin-stage")) | 
|---|
 | 46 |       return;  | 
|---|
 | 47 |    // | 
|---|
 | 48 |    // don't add directories not under version control: | 
|---|
 | 49 |    // | 
|---|
 | 50 |    if(m_cvs_mode && !fs::exists(m_boost_path / p / "CVS/Entries")) | 
|---|
 | 51 |       return; | 
|---|
 | 52 |    // | 
|---|
 | 53 |    // enermerate files and directories: | 
|---|
 | 54 |    // | 
|---|
 | 55 |    fs::directory_iterator i(m_boost_path / p); | 
|---|
 | 56 |    fs::directory_iterator j; | 
|---|
 | 57 |    while(i != j) | 
|---|
 | 58 |    { | 
|---|
 | 59 |       // | 
|---|
 | 60 |       // we need to convert *i back into | 
|---|
 | 61 |       // a relative path, what follows is a hack: | 
|---|
 | 62 |       // | 
|---|
 | 63 |       std::string s(i->string()); | 
|---|
 | 64 |       if(m_boost_path.string().size()) | 
|---|
 | 65 |          s.erase(0, m_boost_path.string().size() + 1); | 
|---|
 | 66 |       if(!m_dependencies.count(fs::path(s)))  | 
|---|
 | 67 |          m_dependencies[fs::path(s)] = p; // set up dependency tree | 
|---|
 | 68 |       add_path(fs::path(s)); | 
|---|
 | 69 |       ++i; | 
|---|
 | 70 |    } | 
|---|
 | 71 | } | 
|---|
 | 72 |  | 
|---|
 | 73 | void bcp_implementation::add_file(const fs::path& p) | 
|---|
 | 74 | { | 
|---|
 | 75 |    // | 
|---|
 | 76 |    // if the file does not exist in cvs then don't do anything with it: | 
|---|
 | 77 |    // | 
|---|
 | 78 |    if(m_cvs_mode && (m_cvs_paths.find(p) == m_cvs_paths.end())) | 
|---|
 | 79 |       return; | 
|---|
 | 80 |    // | 
|---|
 | 81 |    // if we've already seen the file return: | 
|---|
 | 82 |    // | 
|---|
 | 83 |    if(m_copy_paths.find(p) != m_copy_paths.end()) | 
|---|
 | 84 |       return; | 
|---|
 | 85 |    // | 
|---|
 | 86 |    // add the file to our list: | 
|---|
 | 87 |    // | 
|---|
 | 88 |    m_copy_paths.insert(p); | 
|---|
 | 89 |    // | 
|---|
 | 90 |    // if this is a source file, scan for dependencies: | 
|---|
 | 91 |    // | 
|---|
 | 92 |    if(is_source_file(p)) | 
|---|
 | 93 |    { | 
|---|
 | 94 |       add_file_dependencies(p, false); | 
|---|
 | 95 |    } | 
|---|
 | 96 |    // | 
|---|
 | 97 |    // if this is a html file, scan for dependencies: | 
|---|
 | 98 |    // | 
|---|
 | 99 |    if(is_html_file(p)) | 
|---|
 | 100 |    { | 
|---|
 | 101 |       static const boost::regex e( | 
|---|
 | 102 |          "<(?:img[^>]*src=|link[^>]*href=)(\"[^\"]+\"|\\w+)[^>]*>" | 
|---|
 | 103 |          ); | 
|---|
 | 104 |  | 
|---|
 | 105 |       fileview view(m_boost_path / p); | 
|---|
 | 106 |       boost::regex_token_iterator<const char*> i(view.begin(), view.end(), e, 1); | 
|---|
 | 107 |       boost::regex_token_iterator<const char*> j; | 
|---|
 | 108 |       while(i != j) | 
|---|
 | 109 |       { | 
|---|
 | 110 |          // | 
|---|
 | 111 |          // extract the dependent name: | 
|---|
 | 112 |          // | 
|---|
 | 113 |          std::string s(*i); | 
|---|
 | 114 |          if(s[0] == '\"') | 
|---|
 | 115 |          { | 
|---|
 | 116 |             // remove quotes: | 
|---|
 | 117 |             assert(s.size() > 2); | 
|---|
 | 118 |             s.erase(0, 1); | 
|---|
 | 119 |             s.erase(s.size() - 1); | 
|---|
 | 120 |          } | 
|---|
 | 121 |          // | 
|---|
 | 122 |          // if the name starts with ./ remove it | 
|---|
 | 123 |          // or we'll get an error: | 
|---|
 | 124 |          if(s.compare(0, 2, "./") == 0) | 
|---|
 | 125 |             s.erase(0, 2); | 
|---|
 | 126 |          if(s.find(':') == std::string::npos) | 
|---|
 | 127 |          { | 
|---|
 | 128 |             // only concatonate if it's a relative path | 
|---|
 | 129 |             // rather than a URL: | 
|---|
 | 130 |             fs::path dep(p.branch_path() / s); | 
|---|
 | 131 |             if(!m_dependencies.count(dep))  | 
|---|
 | 132 |                m_dependencies[dep] = p; // set up dependency tree | 
|---|
 | 133 |             add_path(dep); | 
|---|
 | 134 |          } | 
|---|
 | 135 |          ++i; | 
|---|
 | 136 |       } | 
|---|
 | 137 |    } | 
|---|
 | 138 |    // | 
|---|
 | 139 |    // now scan for "special" dependencies: | 
|---|
 | 140 |    // anything that we can't automatically detect... | 
|---|
 | 141 |    // | 
|---|
 | 142 | static const std::pair<fs::path, fs::path> | 
|---|
 | 143 |    specials[] = { | 
|---|
 | 144 |       std::pair<fs::path, fs::path>("boost/config.hpp", "boost/config"), | 
|---|
 | 145 |       std::pair<fs::path, fs::path>("tools/build/allyourbase.jam", "Jamrules"), | 
|---|
 | 146 |       std::pair<fs::path, fs::path>("tools/build/allyourbase.jam", "project-root.jam"), | 
|---|
 | 147 |       std::pair<fs::path, fs::path>("tools/build/allyourbase.jam", "boost-build.jam"), | 
|---|
 | 148 |       std::pair<fs::path, fs::path>("boost/preprocessor/iterate.hpp", "boost/preprocessor/iteration"), | 
|---|
 | 149 |       std::pair<fs::path, fs::path>("boost/preprocessor/slot/slot.hpp", "boost/preprocessor/slot/detail"), | 
|---|
 | 150 |       std::pair<fs::path, fs::path>("boost/function.hpp", "boost/function/detail"), | 
|---|
 | 151 |       std::pair<fs::path, fs::path>("boost/regex/config.hpp", "boost/regex/user.hpp"), | 
|---|
 | 152 |       std::pair<fs::path, fs::path>("boost/signals/signal_template.hpp", "boost/function"), | 
|---|
 | 153 |       std::pair<fs::path, fs::path>("boost/mpl/list.hpp", "boost/mpl/list"), | 
|---|
 | 154 |       std::pair<fs::path, fs::path>("boost/mpl/list_c.hpp", "boost/mpl/list"), | 
|---|
 | 155 |       std::pair<fs::path, fs::path>("boost/mpl/vector.hpp", "boost/mpl/vector"), | 
|---|
 | 156 |       std::pair<fs::path, fs::path>("boost/mpl/deque.hpp", "boost/mpl/vector"), | 
|---|
 | 157 |       std::pair<fs::path, fs::path>("boost/mpl/vector_c.hpp", "boost/mpl/vector"), | 
|---|
 | 158 |       std::pair<fs::path, fs::path>("boost/mpl/map.hpp", "boost/mpl/map"), | 
|---|
 | 159 |       std::pair<fs::path, fs::path>("boost/mpl/set.hpp", "boost/mpl/set"), | 
|---|
 | 160 |       std::pair<fs::path, fs::path>("boost/mpl/set_c.hpp", "boost/mpl/set"), | 
|---|
 | 161 |       std::pair<fs::path, fs::path>("boost/mpl/aux_/include_preprocessed.hpp", "boost/mpl/aux_/preprocessed"), | 
|---|
 | 162 |       std::pair<fs::path, fs::path>("boost/mpl/vector/aux_/include_preprocessed.hpp", "boost/mpl/vector/aux_/preprocessed"), | 
|---|
 | 163 |       std::pair<fs::path, fs::path>("boost/mpl/set/aux_/include_preprocessed.hpp", "boost/mpl/set/aux_/preprocessed"), | 
|---|
 | 164 |       std::pair<fs::path, fs::path>("boost/mpl/map/aux_/include_preprocessed.hpp", "boost/mpl/map/aux_/preprocessed"), | 
|---|
 | 165 |       std::pair<fs::path, fs::path>("boost/mpl/list/aux_/include_preprocessed.hpp", "boost/mpl/list/aux_/preprocessed"), | 
|---|
 | 166 |       std::pair<fs::path, fs::path>("libs/graph/src/python/visitor.hpp", "libs/graph/src/python"), | 
|---|
 | 167 |    }; | 
|---|
 | 168 |  | 
|---|
 | 169 |    for(unsigned int n = 0; n < (sizeof(specials)/sizeof(specials[0])); ++n) | 
|---|
 | 170 |    { | 
|---|
 | 171 |       if(0 == compare_paths(specials[n].first, p)) | 
|---|
 | 172 |       { | 
|---|
 | 173 |          if(!m_dependencies.count(specials[n].second))  | 
|---|
 | 174 |             m_dependencies[specials[n].second] = p; // set up dependency tree | 
|---|
 | 175 |          add_path(specials[n].second); | 
|---|
 | 176 |       } | 
|---|
 | 177 |    } | 
|---|
 | 178 |  | 
|---|
 | 179 | } | 
|---|
 | 180 |  | 
|---|
 | 181 | void bcp_implementation::add_dependent_lib(const std::string& libname, const fs::path& p) | 
|---|
 | 182 | { | 
|---|
 | 183 |    // | 
|---|
 | 184 |    // if the boost library libname has source associated with it | 
|---|
 | 185 |    // then add the source to our list: | 
|---|
 | 186 |    // | 
|---|
 | 187 |    if(fs::exists(m_boost_path / "libs" / libname / "src")) | 
|---|
 | 188 |    { | 
|---|
 | 189 |       if(!m_dependencies.count(fs::path("libs") / libname / "src"))  | 
|---|
 | 190 |          m_dependencies[fs::path("libs") / libname / "src"] = p; // set up dependency tree | 
|---|
 | 191 |       add_path(fs::path("libs") / libname / "src"); | 
|---|
 | 192 |       if(fs::exists(m_boost_path / "libs" / libname / "build")) | 
|---|
 | 193 |       { | 
|---|
 | 194 |          if(!m_dependencies.count(fs::path("libs") / libname / "build"))  | 
|---|
 | 195 |             m_dependencies[fs::path("libs") / libname / "build"] = p; // set up dependency tree | 
|---|
 | 196 |          add_path(fs::path("libs") / libname / "build"); | 
|---|
 | 197 |       } | 
|---|
 | 198 |    } | 
|---|
 | 199 | } | 
|---|
 | 200 |  | 
|---|
 | 201 | void bcp_implementation::add_file_dependencies(const fs::path& p, bool scanfile) | 
|---|
 | 202 | { | 
|---|
 | 203 |    static const boost::regex e( | 
|---|
 | 204 |       "^[[:blank:]]*#[[:blank:]]*include[[:blank:]]*[\"<]([^\">]+)[\">]" | 
|---|
 | 205 |       ); | 
|---|
 | 206 |  | 
|---|
 | 207 |    if(!m_dependencies.count(p))  | 
|---|
 | 208 |       m_dependencies[p] = p; // set terminal dependency | 
|---|
 | 209 |  | 
|---|
 | 210 |    fileview view; | 
|---|
 | 211 |    if(scanfile) | 
|---|
 | 212 |       view.open(p); | 
|---|
 | 213 |    else | 
|---|
 | 214 |       view.open(m_boost_path / p); | 
|---|
 | 215 |    if(m_license_mode && !scanfile) | 
|---|
 | 216 |       scan_license(p, view); | 
|---|
 | 217 |    boost::regex_token_iterator<const char*> i(view.begin(), view.end(), e, 1); | 
|---|
 | 218 |    boost::regex_token_iterator<const char*> j; | 
|---|
 | 219 |    while(i != j) | 
|---|
 | 220 |    { | 
|---|
 | 221 |       // | 
|---|
 | 222 |       // *i contains the name of the include file, | 
|---|
 | 223 |       // check first for a file of that name in the | 
|---|
 | 224 |       // same directory as the file we are scanning, | 
|---|
 | 225 |       // and if that fails, then check the boost-root: | 
|---|
 | 226 |       // | 
|---|
 | 227 |       fs::path include_file; | 
|---|
 | 228 |       try{ | 
|---|
 | 229 |          include_file = i->str(); | 
|---|
 | 230 |       } | 
|---|
 | 231 |       catch(const fs::filesystem_error& e) | 
|---|
 | 232 |       { | 
|---|
 | 233 |          std::cerr << "Can't parse filename " << *i << " included by file " << p.string() << std::endl; | 
|---|
 | 234 |          ++i; | 
|---|
 | 235 |          continue; | 
|---|
 | 236 |       } | 
|---|
 | 237 |       fs::path test_file(m_boost_path / p.branch_path() / include_file); | 
|---|
 | 238 |       if(fs::exists(test_file) && !fs::is_directory(test_file) && (p.branch_path().string() != "boost")) | 
|---|
 | 239 |       { | 
|---|
 | 240 |          if(!m_dependencies.count(p.branch_path() / include_file))  | 
|---|
 | 241 |             m_dependencies[p.branch_path() / include_file] = p; | 
|---|
 | 242 |          add_path(p.branch_path() / include_file); | 
|---|
 | 243 |       } | 
|---|
 | 244 |       else if(fs::exists(m_boost_path / include_file)) | 
|---|
 | 245 |       { | 
|---|
 | 246 |          if(!m_dependencies.count(include_file))  | 
|---|
 | 247 |             m_dependencies[include_file] = p; | 
|---|
 | 248 |          add_path(include_file); | 
|---|
 | 249 |       } | 
|---|
 | 250 |       ++i; | 
|---|
 | 251 |    } | 
|---|
 | 252 |    // | 
|---|
 | 253 |    // Now we need to scan for Boost.Preprocessor includes that | 
|---|
 | 254 |    // are included via preprocessor iteration: | 
|---|
 | 255 |    // | 
|---|
 | 256 |    boost::regex ppfiles("^[[:blank:]]*#[[:blank:]]*define[[:blank:]]+(?:BOOST_PP_FILENAME|BOOST_PP_ITERATION_PARAMS|BOOST_PP_INDIRECT_SELF)[^\\n]+?[\"<]([^\">]+)[\">]"); | 
|---|
 | 257 |    i = boost::regex_token_iterator<const char*>(view.begin(), view.end(), ppfiles, 1); | 
|---|
 | 258 |    while(i != j) | 
|---|
 | 259 |    { | 
|---|
 | 260 |       // | 
|---|
 | 261 |       // *i contains the name of the include file, | 
|---|
 | 262 |       // check first for a file of that name in the | 
|---|
 | 263 |       // same directory as the file we are scanning, | 
|---|
 | 264 |       // and if that fails, then check the boost-root: | 
|---|
 | 265 |       // | 
|---|
 | 266 |       fs::path include_file; | 
|---|
 | 267 |       try{ | 
|---|
 | 268 |          include_file = i->str(); | 
|---|
 | 269 |       } | 
|---|
 | 270 |       catch(const fs::filesystem_error& e) | 
|---|
 | 271 |       { | 
|---|
 | 272 |          std::cerr << "Can't parse filename " << *i << " included by file " << p.string() << std::endl; | 
|---|
 | 273 |          ++i; | 
|---|
 | 274 |          continue; | 
|---|
 | 275 |       } | 
|---|
 | 276 |       fs::path test_file(m_boost_path / p.branch_path() / include_file); | 
|---|
 | 277 |       if(fs::exists(test_file) && !fs::is_directory(test_file) && (p.branch_path().string() != "boost")) | 
|---|
 | 278 |       { | 
|---|
 | 279 |          if(!m_dependencies.count(p.branch_path() / include_file))  | 
|---|
 | 280 |             m_dependencies[p.branch_path() / include_file] = p; | 
|---|
 | 281 |          add_path(p.branch_path() / include_file); | 
|---|
 | 282 |       } | 
|---|
 | 283 |       else if(fs::exists(m_boost_path / include_file)) | 
|---|
 | 284 |       { | 
|---|
 | 285 |          if(!m_dependencies.count(include_file))  | 
|---|
 | 286 |             m_dependencies[include_file] = p; | 
|---|
 | 287 |          add_path(include_file); | 
|---|
 | 288 |       } | 
|---|
 | 289 |       else | 
|---|
 | 290 |       { | 
|---|
 | 291 |          std::cerr << "CAUTION: Boost.Preprocessor iterated file " << include_file.string() << " does not exist." << std::endl; | 
|---|
 | 292 |       } | 
|---|
 | 293 |       ++i; | 
|---|
 | 294 |    } | 
|---|
 | 295 |  | 
|---|
 | 296 |    // | 
|---|
 | 297 |    // Scan for any #include MACRO includes that we don't recognise. | 
|---|
 | 298 |    // | 
|---|
 | 299 |    // Begin by declaring all of the macros that get #included that  | 
|---|
 | 300 |    // we know about and are correctly handled as special cases: | 
|---|
 | 301 |    // | 
|---|
 | 302 |    static const std::string known_macros[] = { | 
|---|
 | 303 |       "BOOST_USER_CONFIG", | 
|---|
 | 304 |       "BOOST_COMPILER_CONFIG", | 
|---|
 | 305 |       "BOOST_STDLIB_CONFIG", | 
|---|
 | 306 |       "BOOST_PLATFORM_CONFIG", | 
|---|
 | 307 |       "BOOST_PP_FILENAME_1", | 
|---|
 | 308 |       "BOOST_PP_ITERATION_PARAMS_1", | 
|---|
 | 309 |       "BOOST_PP_FILENAME_2", | 
|---|
 | 310 |       "BOOST_PP_ITERATION_PARAMS_2", | 
|---|
 | 311 |       "BOOST_PP_FILENAME_3", | 
|---|
 | 312 |       "BOOST_PP_ITERATION_PARAMS_3", | 
|---|
 | 313 |       "BOOST_PP_FILENAME_4", | 
|---|
 | 314 |       "BOOST_PP_ITERATION_PARAMS_4", | 
|---|
 | 315 |       "BOOST_PP_FILENAME_5", | 
|---|
 | 316 |       "BOOST_PP_ITERATION_PARAMS_5", | 
|---|
 | 317 |       "BOOST_PP_INDIRECT_SELF", | 
|---|
 | 318 |       "BOOST_PP_INCLUDE_SELF()", | 
|---|
 | 319 |       "BOOST_PP_ITERATE", | 
|---|
 | 320 |       "BOOST_PP_LOCAL_ITERATE", | 
|---|
 | 321 |       "BOOST_PP_ITERATE()", | 
|---|
 | 322 |       "BOOST_PP_LOCAL_ITERATE()", | 
|---|
 | 323 |       "BOOST_PP_ASSIGN_SLOT(1)", | 
|---|
 | 324 |       "BOOST_PP_ASSIGN_SLOT(2)", | 
|---|
 | 325 |       "BOOST_PP_ASSIGN_SLOT(3)", | 
|---|
 | 326 |       "BOOST_PP_ASSIGN_SLOT(4)", | 
|---|
 | 327 |       "BOOST_PP_ASSIGN_SLOT(5)", | 
|---|
 | 328 |       "BOOST_ABI_PREFIX", | 
|---|
 | 329 |       "BOOST_ABI_SUFFIX", | 
|---|
 | 330 |       "BOOST_PP_STRINGIZE(boost/mpl/aux_/preprocessed/AUX_PREPROCESSED_HEADER)", | 
|---|
 | 331 |       "BOOST_PP_STRINGIZE(boost/mpl/list/AUX778076_HEADER)", | 
|---|
 | 332 |       "BOOST_PP_STRINGIZE(boost/mpl/list/AUX778076_LIST_C_HEADER)", | 
|---|
 | 333 |       "BOOST_PP_STRINGIZE(boost/mpl/list/AUX778076_LIST_HEADER)", | 
|---|
 | 334 |       "BOOST_PP_STRINGIZE(boost/mpl/map/aux_/preprocessed/AUX778076_HEADER)", | 
|---|
 | 335 |       "BOOST_PP_STRINGIZE(boost/mpl/map/AUX778076_MAP_HEADER)", | 
|---|
 | 336 |       "BOOST_PP_STRINGIZE(boost/mpl/set/aux_/preprocessed/AUX778076_HEADER)", | 
|---|
 | 337 |       "BOOST_PP_STRINGIZE(boost/mpl/set/AUX778076_SET_HEADER)", | 
|---|
 | 338 |       "BOOST_PP_STRINGIZE(boost/mpl/set/AUX778076_SET_C_HEADER)", | 
|---|
 | 339 |       "BOOST_PP_STRINGIZE(boost/mpl/vector/AUX778076_VECTOR_HEADER)", | 
|---|
 | 340 |       "BOOST_PP_STRINGIZE(boost/mpl/vector/aux_/preprocessed/AUX778076_HEADER)", | 
|---|
 | 341 |       "BOOST_PP_STRINGIZE(boost/mpl/vector/AUX778076_DEQUE_HEADER)", | 
|---|
 | 342 |       "BOOST_PP_STRINGIZE(boost/mpl/vector/AUX778076_VECTOR_C_HEADER)", | 
|---|
 | 343 |       "BOOST_REGEX_USER_CONFIG", | 
|---|
 | 344 |       "BGL_PYTHON_EVENTS_HEADER", | 
|---|
 | 345 |    }; | 
|---|
 | 346 |  | 
|---|
 | 347 |    boost::regex indirect_includes("^[[:blank:]]*#[[:blank:]]*include[[:blank:]]+([^\"<][^\n]*?)[[:blank:]]*$"); | 
|---|
 | 348 |    i = boost::regex_token_iterator<const char*>(view.begin(), view.end(), indirect_includes, 1); | 
|---|
 | 349 |    while(i != j) | 
|---|
 | 350 |    { | 
|---|
 | 351 |       const std::string* known_macros_end = known_macros + sizeof(known_macros)/sizeof(known_macros[0]); | 
|---|
 | 352 |       if(known_macros_end == std::find(known_macros, known_macros_end, i->str())) | 
|---|
 | 353 |       { | 
|---|
 | 354 |          std::cerr << "CAUTION: don't know how to trace depenencies through macro: " << *i << " in file: " << p.string() << std::endl; | 
|---|
 | 355 |       } | 
|---|
 | 356 |       ++i; | 
|---|
 | 357 |    } | 
|---|
 | 358 |    // | 
|---|
 | 359 |    // if the file contains a cpp_main / unit_test_main / test_main | 
|---|
 | 360 |    // it is dependent upon Boost.test even if it doesn't | 
|---|
 | 361 |    // include any of the Boost.test headers directly. | 
|---|
 | 362 |    // | 
|---|
 | 363 |    static const boost::regex m("^\\s*int\\s+(?:cpp_main|test_main|unit_test_main)"); | 
|---|
 | 364 |    boost::cmatch what; | 
|---|
 | 365 |    if(boost::regex_search(view.begin(), view.end(), what, m)) | 
|---|
 | 366 |    { | 
|---|
 | 367 |       add_dependent_lib("test", p); | 
|---|
 | 368 |    } | 
|---|
 | 369 |    // | 
|---|
 | 370 |    // grab the name of the library to which the header belongs,  | 
|---|
 | 371 |    // and if that library has source then add the source to our | 
|---|
 | 372 |    // list: | 
|---|
 | 373 |    // | 
|---|
 | 374 |    // this regex catches boost/libname.hpp or boost/libname/whatever: | 
|---|
 | 375 |    // | 
|---|
 | 376 |    static const boost::regex lib1("boost/([^\\./]+)(?!detail).*"); | 
|---|
 | 377 |    boost::smatch swhat; | 
|---|
 | 378 |    if(boost::regex_match(p.string(), swhat, lib1)) | 
|---|
 | 379 |    { | 
|---|
 | 380 |       add_dependent_lib(swhat.str(1), p); | 
|---|
 | 381 |    } | 
|---|
 | 382 |    // | 
|---|
 | 383 |    // and this one catches boost/x/y/whatever (for example numeric/ublas): | 
|---|
 | 384 |    // | 
|---|
 | 385 |    static const boost::regex lib2("boost/([^/]+/[^/]+)/(?!detail).*"); | 
|---|
 | 386 |    if(boost::regex_match(p.string(), swhat, lib2)) | 
|---|
 | 387 |    { | 
|---|
 | 388 |       add_dependent_lib(swhat.str(1), p); | 
|---|
 | 389 |    } | 
|---|
 | 390 | } | 
|---|