File indexing completed on 2025-01-18 09:53:40
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011 #if !defined(BOOST_CPP_INCLUDE_PATHS_HPP_AF620DA4_B3D2_4221_AD91_8A1ABFFB6944_INCLUDED)
0012 #define BOOST_CPP_INCLUDE_PATHS_HPP_AF620DA4_B3D2_4221_AD91_8A1ABFFB6944_INCLUDED
0013
0014 #include <string>
0015 #include <list>
0016 #include <utility>
0017
0018 #include <boost/assert.hpp>
0019 #include <boost/wave/wave_config.hpp>
0020 #include <boost/wave/util/filesystem_compatibility.hpp>
0021
0022 #if BOOST_WAVE_SUPPORT_PRAGMA_ONCE != 0
0023 #include <boost/multi_index_container.hpp>
0024 #include <boost/multi_index/member.hpp>
0025 #include <boost/multi_index/ordered_index.hpp>
0026 #endif
0027
0028 #if BOOST_WAVE_SERIALIZATION != 0
0029 #include <boost/serialization/serialization.hpp>
0030 #include <boost/serialization/utility.hpp>
0031 #include <boost/serialization/collections_save_imp.hpp>
0032 #include <boost/serialization/collections_load_imp.hpp>
0033 #include <boost/serialization/split_free.hpp>
0034 #endif
0035
0036 #include <boost/filesystem/path.hpp>
0037 #include <boost/filesystem/operations.hpp>
0038
0039
0040 #ifdef BOOST_HAS_ABI_HEADERS
0041 #include BOOST_ABI_PREFIX
0042 #endif
0043
0044
0045 namespace boost { namespace wave { namespace util {
0046
0047 #if BOOST_WAVE_SUPPORT_PRAGMA_ONCE != 0
0048
0049
0050 struct from {};
0051 struct to {};
0052
0053
0054
0055
0056 template<typename FromType, typename ToType>
0057 struct bidirectional_map
0058 {
0059 typedef std::pair<FromType, ToType> value_type;
0060
0061 #if defined(BOOST_NO_POINTER_TO_MEMBER_TEMPLATE_PARAMETERS) || \
0062 (defined(BOOST_MSVC) && (BOOST_MSVC == 1600) ) || \
0063 (defined(BOOST_INTEL_CXX_VERSION) && \
0064 (defined(_MSC_VER) && (BOOST_INTEL_CXX_VERSION <= 700)))
0065
0066 BOOST_STATIC_CONSTANT(unsigned, from_offset = offsetof(value_type, first));
0067 BOOST_STATIC_CONSTANT(unsigned, to_offset = offsetof(value_type, second));
0068
0069 typedef boost::multi_index::multi_index_container<
0070 value_type,
0071 boost::multi_index::indexed_by<
0072 boost::multi_index::ordered_unique<
0073 boost::multi_index::tag<from>,
0074 boost::multi_index::member_offset<value_type, FromType, from_offset>
0075 >,
0076 boost::multi_index::ordered_non_unique<
0077 boost::multi_index::tag<to>,
0078 boost::multi_index::member_offset<value_type, ToType, to_offset>
0079 >
0080 >
0081 > type;
0082
0083 #else
0084
0085 typedef boost::multi_index::multi_index_container<
0086 value_type,
0087 boost::multi_index::indexed_by<
0088 boost::multi_index::ordered_unique<
0089 boost::multi_index::tag<from>,
0090 boost::multi_index::member<value_type, FromType, &value_type::first>
0091 >,
0092 boost::multi_index::ordered_non_unique<
0093 boost::multi_index::tag<to>,
0094 boost::multi_index::member<value_type, ToType, &value_type::second>
0095 >
0096 >
0097 > type;
0098
0099 #endif
0100 };
0101 #endif
0102
0103 #if BOOST_WAVE_SERIALIZATION != 0
0104 struct load_filepos
0105 {
0106 static unsigned int get_line() { return 0; }
0107 static unsigned int get_column() { return 0; }
0108 static std::string get_file() { return "<loading-state>"; }
0109 };
0110 #endif
0111
0112
0113
0114
0115
0116
0117
0118
0119
0120
0121
0122
0123
0124
0125
0126
0127
0128
0129
0130
0131
0132
0133
0134
0135
0136
0137
0138 class include_paths
0139 {
0140 private:
0141 typedef std::list<std::pair<boost::filesystem::path, std::string> >
0142 include_list_type;
0143 typedef include_list_type::value_type include_value_type;
0144
0145 #if BOOST_WAVE_SUPPORT_PRAGMA_ONCE != 0
0146 typedef bidirectional_map<std::string, std::string>::type
0147 pragma_once_set_type;
0148 #endif
0149
0150 public:
0151 include_paths()
0152 : was_sys_include_path(false),
0153 current_dir(initial_path()),
0154 current_rel_dir(initial_path())
0155 {}
0156
0157 bool add_include_path(char const *path_, bool is_system = false)
0158 {
0159 return add_include_path(path_, (is_system || was_sys_include_path) ?
0160 system_include_paths : user_include_paths);
0161 }
0162 void set_sys_include_delimiter() { was_sys_include_path = true; }
0163 bool find_include_file (std::string &s, std::string &dir, bool is_system,
0164 char const *current_file) const;
0165 void set_current_directory(char const *path_);
0166 boost::filesystem::path get_current_directory() const
0167 { return current_dir; }
0168
0169 protected:
0170 bool find_include_file (std::string &s, std::string &dir,
0171 include_list_type const &pathes, char const *) const;
0172 bool add_include_path(char const *path_, include_list_type &pathes_);
0173
0174 private:
0175 include_list_type user_include_paths;
0176 include_list_type system_include_paths;
0177 bool was_sys_include_path;
0178 boost::filesystem::path current_dir;
0179 boost::filesystem::path current_rel_dir;
0180
0181 #if BOOST_WAVE_SUPPORT_PRAGMA_ONCE != 0
0182 public:
0183 bool has_pragma_once(std::string const &filename)
0184 {
0185 using boost::multi_index::get;
0186 return get<from>(pragma_once_files).find(filename) != pragma_once_files.end();
0187 }
0188 bool add_pragma_once_header(std::string const &filename,
0189 std::string const& guard_name)
0190 {
0191 typedef pragma_once_set_type::value_type value_type;
0192 return pragma_once_files.insert(value_type(filename, guard_name)).second;
0193 }
0194 bool remove_pragma_once_header(std::string const& guard_name)
0195 {
0196 typedef pragma_once_set_type::index_iterator<to>::type to_iterator;
0197 typedef std::pair<to_iterator, to_iterator> range_type;
0198
0199 range_type r = pragma_once_files.get<to>().equal_range(guard_name);
0200 if (r.first != r.second) {
0201 using boost::multi_index::get;
0202 get<to>(pragma_once_files).erase(r.first, r.second);
0203 return true;
0204 }
0205 return false;
0206 }
0207
0208 private:
0209 pragma_once_set_type pragma_once_files;
0210 #endif
0211
0212 #if BOOST_WAVE_SERIALIZATION != 0
0213 public:
0214 BOOST_STATIC_CONSTANT(unsigned int, version = 0x10);
0215 BOOST_STATIC_CONSTANT(unsigned int, version_mask = 0x0f);
0216
0217 private:
0218 friend class boost::serialization::access;
0219 template<typename Archive>
0220 void save(Archive & ar, const unsigned int version) const
0221 {
0222 using namespace boost::serialization;
0223 #if BOOST_WAVE_SUPPORT_PRAGMA_ONCE != 0
0224 ar & make_nvp("pragma_once_files", pragma_once_files);
0225 #endif
0226 ar & make_nvp("user_include_paths", user_include_paths);
0227 ar & make_nvp("system_include_paths", system_include_paths);
0228 ar & make_nvp("was_sys_include_path", was_sys_include_path);
0229 }
0230 template<typename Archive>
0231 void load(Archive & ar, const unsigned int loaded_version)
0232 {
0233 using namespace boost::serialization;
0234 if (version != (loaded_version & ~version_mask)) {
0235 BOOST_WAVE_THROW(preprocess_exception, incompatible_config,
0236 "cpp_include_path state version", load_filepos());
0237 return;
0238 }
0239
0240 #if BOOST_WAVE_SUPPORT_PRAGMA_ONCE != 0
0241 ar & make_nvp("pragma_once_files", pragma_once_files);
0242 #endif
0243
0244 include_list_type user_paths, system_paths;
0245 ar & make_nvp("user_include_paths", user_paths);
0246 ar & make_nvp("system_include_paths", system_paths);
0247
0248 if (user_paths != user_include_paths)
0249 {
0250 BOOST_WAVE_THROW(preprocess_exception, incompatible_config,
0251 "user include paths", load_filepos());
0252 return;
0253 }
0254 if (system_paths != system_include_paths)
0255 {
0256 BOOST_WAVE_THROW(preprocess_exception, incompatible_config,
0257 "system include paths", load_filepos());
0258 return;
0259 }
0260
0261 ar & make_nvp("was_sys_include_path", was_sys_include_path);
0262 }
0263 BOOST_SERIALIZATION_SPLIT_MEMBER()
0264 #endif
0265 };
0266
0267
0268
0269
0270 inline
0271 bool include_paths::add_include_path (
0272 char const *path_, include_list_type &pathes_)
0273 {
0274 namespace fs = boost::filesystem;
0275 if (path_) {
0276 fs::path newpath = util::complete_path(create_path(path_), current_dir);
0277
0278 if (!fs::exists(newpath) || !fs::is_directory(newpath)) {
0279
0280
0281 return false;
0282 }
0283
0284 pathes_.push_back (include_value_type(newpath, path_));
0285 return true;
0286 }
0287 return false;
0288 }
0289
0290
0291
0292 inline
0293 bool include_paths::find_include_file (std::string &s, std::string &dir,
0294 include_list_type const &pathes, char const *current_file) const
0295 {
0296 namespace fs = boost::filesystem;
0297 typedef include_list_type::const_iterator const_include_list_iter_t;
0298
0299 const_include_list_iter_t it = pathes.begin();
0300 const_include_list_iter_t include_paths_end = pathes.end();
0301
0302 #if BOOST_WAVE_SUPPORT_INCLUDE_NEXT != 0
0303 if (0 != current_file) {
0304
0305
0306
0307
0308
0309
0310
0311
0312 fs::path file_path (create_path(current_file));
0313 for (; it != include_paths_end; ++it) {
0314 fs::path currpath (create_path((*it).first.string()));
0315 if (std::equal(currpath.begin(), currpath.end(), file_path.begin()))
0316 {
0317 ++it;
0318 break;
0319 }
0320 }
0321 }
0322 #endif
0323
0324 for (; it != include_paths_end; ++it) {
0325 fs::path currpath (create_path(s));
0326 if (!currpath.has_root_directory()) {
0327 currpath = create_path((*it).first.string());
0328 currpath /= create_path(s);
0329 }
0330
0331 if (fs::exists(currpath)) {
0332 fs::path dirpath (create_path(s));
0333 if (!dirpath.has_root_directory()) {
0334 dirpath = create_path((*it).second);
0335 dirpath /= create_path(s);
0336 }
0337
0338 dir = dirpath.string();
0339 s = normalize(currpath).string();
0340 return true;
0341 }
0342 }
0343 return false;
0344 }
0345
0346
0347
0348
0349 inline bool
0350 include_paths::find_include_file (std::string &s, std::string &dir,
0351 bool is_system, char const *current_file) const
0352 {
0353 namespace fs = boost::filesystem;
0354
0355
0356 if (!is_system) {
0357 if (!was_sys_include_path) {
0358
0359 fs::path currpath(create_path(s));
0360 if (!currpath.has_root_directory()) {
0361 currpath = create_path(current_dir.string());
0362 currpath /= create_path(s);
0363 }
0364
0365 if (fs::exists(currpath) && 0 == current_file) {
0366
0367
0368 fs::path dirpath(create_path(s));
0369 if (!dirpath.has_root_directory()) {
0370 dirpath = create_path(current_rel_dir.string());
0371 dirpath /= create_path(s);
0372 }
0373
0374 dir = dirpath.string();
0375 s = normalize(currpath).string();
0376 return true;
0377 }
0378
0379
0380 if (find_include_file(s, dir, user_include_paths, current_file))
0381 return true;
0382
0383
0384 }
0385 else {
0386
0387
0388 return find_include_file(s, dir, user_include_paths, current_file);
0389 }
0390
0391
0392
0393 }
0394
0395
0396 return find_include_file (s, dir, system_include_paths, current_file);
0397 }
0398
0399
0400
0401
0402 inline bool
0403 as_relative_to(boost::filesystem::path const& path,
0404 boost::filesystem::path const& base, boost::filesystem::path& result)
0405 {
0406 if (path.has_root_path()) {
0407 if (path.root_path() == base.root_path())
0408 return as_relative_to(path.relative_path(), base.relative_path(), result);
0409
0410 result = path;
0411 }
0412 else {
0413 if (base.has_root_path()) {
0414
0415 return false;
0416 }
0417 else {
0418 typedef boost::filesystem::path::const_iterator path_iterator;
0419 path_iterator path_it = path.begin();
0420 path_iterator base_it = base.begin();
0421 while (path_it != path.end() && base_it != base.end() ) {
0422 if (*path_it != *base_it)
0423 break;
0424 ++path_it; ++base_it;
0425 }
0426
0427 for (; base_it != base.end(); ++base_it)
0428 result /= "..";
0429
0430 for (; path_it != path.end(); ++path_it)
0431 result /= *path_it;
0432 }
0433 }
0434 return true;
0435 }
0436
0437
0438 inline
0439 void include_paths::set_current_directory(char const *path_)
0440 {
0441 namespace fs = boost::filesystem;
0442
0443 fs::path filepath (create_path(path_));
0444 fs::path filename = util::complete_path(filepath, current_dir);
0445
0446 BOOST_ASSERT(!(fs::exists(filename) && fs::is_directory(filename)));
0447
0448 current_rel_dir.clear();
0449 if (!as_relative_to(branch_path(filepath), current_dir, current_rel_dir))
0450 current_rel_dir = branch_path(filepath);
0451 current_dir = branch_path(filename);
0452 }
0453
0454
0455 }}}
0456
0457 #if BOOST_WAVE_SERIALIZATION != 0
0458
0459 namespace boost { namespace serialization {
0460
0461
0462
0463 template<class Archive>
0464 inline void save (Archive & ar, boost::filesystem::path const& p,
0465 const unsigned int )
0466 {
0467 using namespace boost::serialization;
0468 std::string path_str(p.native_file_string());
0469 ar & make_nvp("filepath", path_str);
0470 }
0471
0472 template<class Archive>
0473 inline void load (Archive & ar, boost::filesystem::path &p,
0474 const unsigned int )
0475 {
0476 using namespace boost::serialization;
0477 std::string path_str;
0478 ar & make_nvp("filepath", path_str);
0479 p = wave::util::create_path(path_str);
0480 }
0481
0482
0483
0484 template<class Archive>
0485 inline void serialize (Archive & ar, boost::filesystem::path &p,
0486 const unsigned int file_version)
0487 {
0488 boost::serialization::split_free(ar, p, file_version);
0489 }
0490
0491
0492
0493 template<class Archive>
0494 inline void save (Archive & ar,
0495 const typename boost::wave::util::bidirectional_map<
0496 std::string, std::string
0497 >::type &t,
0498 const unsigned int )
0499 {
0500 boost::serialization::stl::save_collection<
0501 Archive,
0502 typename boost::wave::util::bidirectional_map<
0503 std::string, std::string
0504 >::type
0505 >(ar, t);
0506 }
0507
0508 template<class Archive>
0509 inline void load (Archive & ar,
0510 typename boost::wave::util::bidirectional_map<std::string, std::string>::type &t,
0511 const unsigned int )
0512 {
0513 typedef typename boost::wave::util::bidirectional_map<
0514 std::string, std::string
0515 >::type map_type;
0516 boost::serialization::stl::load_collection<
0517 Archive, map_type,
0518 boost::serialization::stl::archive_input_unique<Archive, map_type>,
0519 boost::serialization::stl::no_reserve_imp<map_type>
0520 >(ar, t);
0521 }
0522
0523
0524
0525 template<class Archive>
0526 inline void serialize (Archive & ar,
0527 typename boost::wave::util::bidirectional_map<
0528 std::string, std::string
0529 >::type &t,
0530 const unsigned int file_version)
0531 {
0532 boost::serialization::split_free(ar, t, file_version);
0533 }
0534
0535
0536 }}
0537
0538 BOOST_CLASS_VERSION(boost::wave::util::include_paths,
0539 boost::wave::util::include_paths::version);
0540
0541 #endif
0542
0543
0544 #ifdef BOOST_HAS_ABI_HEADERS
0545 #include BOOST_ABI_SUFFIX
0546 #endif
0547
0548 #endif