diff options
Diffstat (limited to '3rdParty/Boost/src/boost/filesystem')
-rw-r--r-- | 3rdParty/Boost/src/boost/filesystem/operations.hpp | 378 |
1 files changed, 247 insertions, 131 deletions
diff --git a/3rdParty/Boost/src/boost/filesystem/operations.hpp b/3rdParty/Boost/src/boost/filesystem/operations.hpp index dc01b7d..9005b3e 100644 --- a/3rdParty/Boost/src/boost/filesystem/operations.hpp +++ b/3rdParty/Boost/src/boost/filesystem/operations.hpp @@ -33,8 +33,9 @@ #include <boost/type_traits/is_same.hpp> #include <boost/iterator.hpp> #include <boost/cstdint.hpp> +#include <boost/range/mutable_iterator.hpp> +#include <boost/range/const_iterator.hpp> #include <boost/assert.hpp> - #include <string> #include <utility> // for pair #include <ctime> @@ -54,6 +55,116 @@ namespace boost namespace filesystem { + //--------------------------------------------------------------------------------------// + // // + // class filesystem_error // + // // + //--------------------------------------------------------------------------------------// + + class BOOST_SYMBOL_VISIBLE filesystem_error : public system::system_error + { + // see http://www.boost.org/more/error_handling.html for design rationale + + // all functions are inline to avoid issues with crossing dll boundaries + + // functions previously throw() are now BOOST_NOEXCEPT_OR_NOTHROW + // functions previously without throw() are now BOOST_NOEXCEPT + + public: + // compiler generates copy constructor and copy assignment + + filesystem_error( + const std::string & what_arg, system::error_code ec) BOOST_NOEXCEPT + : system::system_error(ec, what_arg) + { + try + { + m_imp_ptr.reset(new m_imp); + } + catch (...) { m_imp_ptr.reset(); } + } + + filesystem_error( + const std::string & what_arg, const path& path1_arg, + system::error_code ec) BOOST_NOEXCEPT + : system::system_error(ec, what_arg) + { + try + { + m_imp_ptr.reset(new m_imp); + m_imp_ptr->m_path1 = path1_arg; + } + catch (...) { m_imp_ptr.reset(); } + } + + filesystem_error( + const std::string & what_arg, const path& path1_arg, + const path& path2_arg, system::error_code ec) BOOST_NOEXCEPT + : system::system_error(ec, what_arg) + { + try + { + m_imp_ptr.reset(new m_imp); + m_imp_ptr->m_path1 = path1_arg; + m_imp_ptr->m_path2 = path2_arg; + } + catch (...) { m_imp_ptr.reset(); } + } + + ~filesystem_error() BOOST_NOEXCEPT_OR_NOTHROW{} + + const path& path1() const BOOST_NOEXCEPT + { + static const path empty_path; + return m_imp_ptr.get() ? m_imp_ptr->m_path1 : empty_path; + } + const path& path2() const BOOST_NOEXCEPT + { + static const path empty_path; + return m_imp_ptr.get() ? m_imp_ptr->m_path2 : empty_path; + } + + const char* what() const BOOST_NOEXCEPT_OR_NOTHROW + { + if (!m_imp_ptr.get()) + return system::system_error::what(); + + try + { + if (m_imp_ptr->m_what.empty()) + { + m_imp_ptr->m_what = system::system_error::what(); + if (!m_imp_ptr->m_path1.empty()) + { + m_imp_ptr->m_what += ": \""; + m_imp_ptr->m_what += m_imp_ptr->m_path1.string(); + m_imp_ptr->m_what += "\""; + } + if (!m_imp_ptr->m_path2.empty()) + { + m_imp_ptr->m_what += ", \""; + m_imp_ptr->m_what += m_imp_ptr->m_path2.string(); + m_imp_ptr->m_what += "\""; + } + } + return m_imp_ptr->m_what.c_str(); + } + catch (...) + { + return system::system_error::what(); + } + } + + private: + struct m_imp + { + path m_path1; // may be empty() + path m_path2; // may be empty() + std::string m_what; // not built until needed + }; + boost::shared_ptr<m_imp> m_imp_ptr; + }; + //--------------------------------------------------------------------------------------// // file_type // //--------------------------------------------------------------------------------------// @@ -108,7 +219,7 @@ namespace boost others_exe = 01, // S_IXOTH, Execute/search permission, others others_all = 07, // S_IRWXO, Read, write, execute/search by others - all_all = owner_all|group_all|others_all, // 0777 + all_all = 0777, // owner_all|group_all|others_all // other POSIX bits @@ -121,7 +232,7 @@ namespace boost // (SVID-v4.2) On directories: restricted deletion flag // Also see http://en.wikipedia.org/wiki/Sticky_bit - perms_mask = all_all|set_uid_on_exe|set_gid_on_exe|sticky_bit, // 07777 + perms_mask = 07777, // all_all|set_uid_on_exe|set_gid_on_exe|sticky_bit perms_not_known = 0xFFFF, // present when directory_entry cache not loaded @@ -721,6 +832,37 @@ namespace detail { return m_imp == rhs.m_imp; } }; + // enable C++11 range-base for statement use ---------------------------------------// + + // begin() and end() are only used by a range-based for statement in the context of + // auto - thus the top-level const is stripped - so returning const is harmless and + // emphasizes begin() is just a pass through. + inline + const directory_iterator& begin(const directory_iterator& iter) {return iter;} + inline + directory_iterator end(const directory_iterator&) {return directory_iterator();} + + // enable BOOST_FOREACH ------------------------------------------------------------// + + inline + directory_iterator& range_begin(directory_iterator& iter) {return iter;} + inline + directory_iterator range_begin(const directory_iterator& iter) {return iter;} + inline + directory_iterator range_end(const directory_iterator&) {return directory_iterator();} + } // namespace filesystem + + // namespace boost template specializations + template<> + struct range_mutable_iterator<boost::filesystem::directory_iterator> + { typedef boost::filesystem::directory_iterator type; }; + template<> + struct range_const_iterator <boost::filesystem::directory_iterator> + { typedef boost::filesystem::directory_iterator type; }; + +namespace filesystem +{ + //--------------------------------------------------------------------------------------// // // // recursive_directory_iterator helpers // @@ -751,6 +893,8 @@ namespace detail void increment(system::error_code* ec); // ec == 0 means throw on error + bool push_directory(system::error_code& ec) BOOST_NOEXCEPT; + void pop(); }; @@ -760,9 +904,14 @@ namespace detail // clients of struct 'boost::filesystem::detail::recur_dir_itr_imp' inline - void recur_dir_itr_imp::increment(system::error_code* ec) - // ec == 0 means throw on error + bool recur_dir_itr_imp::push_directory(system::error_code& ec) BOOST_NOEXCEPT + // Returns: true if push occurs, otherwise false. Always returns false on error. { + ec.clear(); + + // Discover if the iterator is for a directory that needs to be recursed into, + // taking symlinks and options into account. + if ((m_options & symlink_option::_detail_no_push) == symlink_option::_detail_no_push) m_options &= ~symlink_option::_detail_no_push; @@ -775,40 +924,78 @@ namespace detail // && is_directory(m_stack.top()->status())) ... // The predicate code has since been rewritten to pass error_code arguments, // per ticket #5653. - bool or_pred = (m_options & symlink_option::recurse) == symlink_option::recurse - || (ec == 0 ? !is_symlink(m_stack.top()->symlink_status()) - : !is_symlink(m_stack.top()->symlink_status(*ec))); - if (ec != 0 && *ec) - return; - bool and_pred = or_pred && (ec == 0 ? is_directory(m_stack.top()->status()) - : is_directory(m_stack.top()->status(*ec))); - if (ec != 0 && *ec) - return; - - if (and_pred) + + file_status symlink_stat; + + if ((m_options & symlink_option::recurse) != symlink_option::recurse) { - if (ec == 0) - m_stack.push(directory_iterator(m_stack.top()->path())); - else - { - m_stack.push(directory_iterator(m_stack.top()->path(), *ec)); - if (*ec) - return; - } - if (m_stack.top() != directory_iterator()) + symlink_stat = m_stack.top()->symlink_status(ec); + if (ec) + return false; + } + + if ((m_options & symlink_option::recurse) == symlink_option::recurse + || !is_symlink(symlink_stat)) + { + file_status stat = m_stack.top()->status(ec); + if (ec || !is_directory(stat)) + return false; + + directory_iterator next(m_stack.top()->path(), ec); + if (!ec && next != directory_iterator()) { + m_stack.push(next); ++m_level; - return; + return true; } - m_stack.pop(); } } + return false; + } + + inline + void recur_dir_itr_imp::increment(system::error_code* ec) + // ec == 0 means throw on error + // + // Invariant: On return, the top of the iterator stack is the next valid (possibly + // end) iterator, regardless of whether or not an error is reported, and regardless of + // whether any error is reported by exception or error code. In other words, progress + // is always made so a loop on the iterator will always eventually terminate + // regardless of errors. + { + system::error_code ec_push_directory; + + // if various conditions are met, push a directory_iterator into the iterator stack + if (push_directory(ec_push_directory)) + { + if (ec) + ec->clear(); + return; + } + // Do the actual increment operation on the top iterator in the iterator + // stack, popping the stack if necessary, until either the stack is empty or a + // non-end iterator is reached. while (!m_stack.empty() && ++m_stack.top() == directory_iterator()) { m_stack.pop(); --m_level; } + + // report errors if any + if (ec_push_directory) + { + if (ec) + *ec = ec_push_directory; + else + { + BOOST_FILESYSTEM_THROW(filesystem_error( + "filesystem::recursive_directory_iterator directory error", + ec_push_directory)); + } + } + else if (ec) + ec->clear(); } inline @@ -967,116 +1154,45 @@ namespace detail }; -# if !defined(BOOST_FILESYSTEM_NO_DEPRECATED) - typedef recursive_directory_iterator wrecursive_directory_iterator; -# endif + // enable C++11 range-base for statement use ---------------------------------------// -//--------------------------------------------------------------------------------------// -// // -// class filesystem_error // -// // -//--------------------------------------------------------------------------------------// - - class BOOST_SYMBOL_VISIBLE filesystem_error : public system::system_error - { - // see http://www.boost.org/more/error_handling.html for design rationale - - // all functions are inline to avoid issues with crossing dll boundaries - - public: - // compiler generates copy constructor and copy assignment - - filesystem_error( - const std::string & what_arg, system::error_code ec) - : system::system_error(ec, what_arg) - { - try - { - m_imp_ptr.reset(new m_imp); - } - catch (...) { m_imp_ptr.reset(); } - } - - filesystem_error( - const std::string & what_arg, const path& path1_arg, - system::error_code ec) - : system::system_error(ec, what_arg) - { - try - { - m_imp_ptr.reset(new m_imp); - m_imp_ptr->m_path1 = path1_arg; - } - catch (...) { m_imp_ptr.reset(); } - } - - filesystem_error( - const std::string & what_arg, const path& path1_arg, - const path& path2_arg, system::error_code ec) - : system::system_error(ec, what_arg) - { - try - { - m_imp_ptr.reset(new m_imp); - m_imp_ptr->m_path1 = path1_arg; - m_imp_ptr->m_path2 = path2_arg; - } - catch (...) { m_imp_ptr.reset(); } - } + // begin() and end() are only used by a range-based for statement in the context of + // auto - thus the top-level const is stripped - so returning const is harmless and + // emphasizes begin() is just a pass through. + inline + const recursive_directory_iterator& begin(const recursive_directory_iterator& iter) + {return iter;} + inline + recursive_directory_iterator end(const recursive_directory_iterator&) + {return recursive_directory_iterator();} - ~filesystem_error() throw() {} + // enable BOOST_FOREACH ------------------------------------------------------------// - const path& path1() const - { - static const path empty_path; - return m_imp_ptr.get() ? m_imp_ptr->m_path1 : empty_path ; - } - const path& path2() const - { - static const path empty_path; - return m_imp_ptr.get() ? m_imp_ptr->m_path2 : empty_path ; - } + inline + recursive_directory_iterator& range_begin(recursive_directory_iterator& iter) + {return iter;} + inline + recursive_directory_iterator range_begin(const recursive_directory_iterator& iter) + {return iter;} + inline + recursive_directory_iterator range_end(const recursive_directory_iterator&) + {return recursive_directory_iterator();} + } // namespace filesystem - const char* what() const throw() - { - if (!m_imp_ptr.get()) - return system::system_error::what(); + // namespace boost template specializations + template<> + struct range_mutable_iterator<boost::filesystem::recursive_directory_iterator> + { typedef boost::filesystem::recursive_directory_iterator type; }; + template<> + struct range_const_iterator <boost::filesystem::recursive_directory_iterator> + { typedef boost::filesystem::recursive_directory_iterator type; }; - try - { - if (m_imp_ptr->m_what.empty()) - { - m_imp_ptr->m_what = system::system_error::what(); - if (!m_imp_ptr->m_path1.empty()) - { - m_imp_ptr->m_what += ": \""; - m_imp_ptr->m_what += m_imp_ptr->m_path1.string(); - m_imp_ptr->m_what += "\""; - } - if (!m_imp_ptr->m_path2.empty()) - { - m_imp_ptr->m_what += ", \""; - m_imp_ptr->m_what += m_imp_ptr->m_path2.string(); - m_imp_ptr->m_what += "\""; - } - } - return m_imp_ptr->m_what.c_str(); - } - catch (...) - { - return system::system_error::what(); - } - } +namespace filesystem +{ - private: - struct m_imp - { - path m_path1; // may be empty() - path m_path2; // may be empty() - std::string m_what; // not built until needed - }; - boost::shared_ptr<m_imp> m_imp_ptr; - }; +# if !defined(BOOST_FILESYSTEM_NO_DEPRECATED) + typedef recursive_directory_iterator wrecursive_directory_iterator; +# endif // test helper -----------------------------------------------------------------------// |