Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-18 09:53:40

0001 /*=============================================================================
0002     Boost.Wave: A Standard compliant C++ preprocessor library
0003 
0004     http://www.boost.org/
0005 
0006     Copyright (c) 2001-2012 Hartmut Kaiser. Distributed under the Boost
0007     Software License, Version 1.0. (See accompanying file
0008     LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
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 // this must occur after all of the includes and before any code appears
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 //  Tags for accessing both sides of a bidirectional map
0050 struct from {};
0051 struct to {};
0052 
0053 ///////////////////////////////////////////////////////////////////////////////
0054 //  The class template bidirectional_map wraps the specification
0055 //  of a bidirectional map based on multi_index_container.
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 // BOOST_WAVE_SUPPORT_PRAGMA_ONCE != 0
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 //  include_paths - controlling the include path search order
0115 //
0116 //  General notes:
0117 //
0118 //      Any directories specified with the 'add_include_path()' function before
0119 //      the function 'set_sys_include_delimiter()' is called are searched only
0120 //      for the case of '#include "file"' directives, they are not searched for
0121 //      '#include <file>' directives. If additional directories are specified
0122 //      with the 'add_include_path()' function after a call to the function
0123 //      'set_sys_include_delimiter()', these directories are searched for all
0124 //      '#include' directives.
0125 //
0126 //      In addition, a call to the function 'set_sys_include_delimiter()'
0127 //      inhibits the use of the current directory as the first search directory
0128 //      for '#include "file"' directives. Therefore, the current directory is
0129 //      searched only if it is requested explicitly with a call to the function
0130 //      'add_include_path(".")'.
0131 //
0132 //      Calling both functions, the 'set_sys_include_delimiter()' and
0133 //      'add_include_path(".")' allows you to control precisely which
0134 //      directories are searched before the current one and which are searched
0135 //      after.
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;          // saw a set_sys_include_delimiter()
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         // verify that the old include paths match the current ones
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 //  Add an include path to one of the search lists (user include path or system
0269 //  include path).
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             // the given path does not form a name of a valid file system directory
0280             // item
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 //  Find an include file by traversing the list of include directories
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         // re-locate the directory of the current file (#include_next handling)
0305 
0306         // #include_next does not distinguish between <file> and "file"
0307         // inclusion, nor does it check that the file you specify has the same
0308         // name as the current file.  It simply looks for the file named, starting
0309         // with the directory in the search path after the one where the current
0310         // file was found.
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;     // start searching with the next directory
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);      // append filename
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();    // found the required file
0340             return true;
0341         }
0342     }
0343     return false;
0344 }
0345 
0346 ///////////////////////////////////////////////////////////////////////////////
0347 //  Find an include file by searching the user and system includes in the
0348 //  correct sequence (as it was configured by the user of the driver program)
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     // if not system include (<...>), then search current directory first
0356     if (!is_system) {
0357         if (!was_sys_include_path) { // set_sys_include_delimiter() not called
0358                                      // first have a look at the current directory
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                 // if 0 != current_path (#include_next handling) it can't be
0367                 // the file in the current directory
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();    // found in local directory
0376                 return true;
0377             }
0378 
0379             // iterate all user include file directories to find the file
0380             if (find_include_file(s, dir, user_include_paths, current_file))
0381                 return true;
0382 
0383             // ... fall through
0384         }
0385         else {
0386             //  if set_sys_include_delimiter() was called, then user include files
0387             //  are searched in the user search path only
0388             return find_include_file(s, dir, user_include_paths, current_file);
0389         }
0390 
0391         // if nothing found, fall through
0392         // ...
0393     }
0394 
0395     // iterate all system include file directories to find the file
0396     return find_include_file (s, dir, system_include_paths, current_file);
0397 }
0398 
0399 ///////////////////////////////////////////////////////////////////////////////
0400 //  Set current directory from a given file name
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;    // that's our result
0411     }
0412     else {
0413         if (base.has_root_path()) {
0414             // cannot find relative path from a relative path and a rooted base
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 }}}   // namespace boost::wave::util
0456 
0457 #if BOOST_WAVE_SERIALIZATION != 0
0458 ///////////////////////////////////////////////////////////////////////////////
0459 namespace boost { namespace serialization {
0460 
0461 ///////////////////////////////////////////////////////////////////////////////
0462 //  Serialization support for boost::filesystem::path
0463 template<class Archive>
0464 inline void save (Archive & ar, boost::filesystem::path const& p,
0465     const unsigned int /* file_version */)
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 /* file_version */)
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 // split non-intrusive serialization function member into separate
0483 // non intrusive save/load member functions
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 //  Serialization support for the used multi_index
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 /* file_version */)
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 /* file_version */)
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 // split non-intrusive serialization function member into separate
0524 // non intrusive save/load member functions
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 }}  // namespace boost::serialization
0537 
0538 BOOST_CLASS_VERSION(boost::wave::util::include_paths,
0539     boost::wave::util::include_paths::version);
0540 
0541 #endif  // BOOST_WAVE_SERIALIZATION != 0
0542 
0543 // the suffix header occurs after all of the code
0544 #ifdef BOOST_HAS_ABI_HEADERS
0545 #include BOOST_ABI_SUFFIX
0546 #endif
0547 
0548 #endif // !defined(BOOST_CPP_INCLUDE_PATHS_HPP_AF620DA4_B3D2_4221_AD91_8A1ABFFB6944_INCLUDED)