summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTobias Markmann <tm@ayena.de>2014-10-19 20:22:58 (GMT)
committerTobias Markmann <tm@ayena.de>2014-10-20 13:49:33 (GMT)
commit6b22dfcf59474dd016a0355a3102a1dd3692d92c (patch)
tree2b1fd33be433a91e81fee84fdc2bf1b52575d934 /3rdParty/Boost/src/boost/filesystem/operations.hpp
parent38b0cb785fea8eae5e48fae56440695fdfd10ee1 (diff)
downloadswift-6b22dfcf59474dd016a0355a3102a1dd3692d92c.zip
swift-6b22dfcf59474dd016a0355a3102a1dd3692d92c.tar.bz2
Update Boost in 3rdParty to version 1.56.0.
This updates Boost in our 3rdParty directory to version 1.56.0. Updated our update.sh script to stop on error. Changed error reporting in SwiftTools/CrashReporter.cpp to SWIFT_LOG due to missing include of <iostream> with newer Boost. Change-Id: I4b35c77de951333979a524097f35f5f83d325edc
Diffstat (limited to '3rdParty/Boost/src/boost/filesystem/operations.hpp')
-rw-r--r--3rdParty/Boost/src/boost/filesystem/operations.hpp378
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
@@ -30,14 +30,15 @@
#include <boost/system/system_error.hpp>
#include <boost/shared_ptr.hpp>
#include <boost/utility/enable_if.hpp>
#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>
#include <vector>
#include <stack>
@@ -51,12 +52,122 @@
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 //
//--------------------------------------------------------------------------------------//
enum file_type
{
@@ -105,26 +216,26 @@ namespace boost
others_read = 04, // S_IROTH, Read permission, others
others_write = 02, // S_IWOTH, Write permission, others
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
set_uid_on_exe = 04000, // S_ISUID, Set-user-ID on execution
set_gid_on_exe = 02000, // S_ISGID, Set-group-ID on execution
sticky_bit = 01000, // S_ISVTX,
// (POSIX XSI) On directories, restricted deletion flag
// (V7) 'sticky bit': save swapped text even after use
// (SunOS) On non-directories: don't cache this file
// (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
// options for permissions() function
add_perms = 0x1000, // adds the given permission bits to the current bits
@@ -718,12 +829,43 @@ namespace detail
void increment() { detail::directory_iterator_increment(*this, 0); }
bool equal(const directory_iterator& rhs) const
{ 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 //
// //
//--------------------------------------------------------------------------------------//
@@ -748,70 +890,115 @@ namespace detail
BOOST_SCOPED_ENUM(symlink_option) m_options;
recur_dir_itr_imp() : m_level(0), m_options(symlink_option::none) {}
void increment(system::error_code* ec); // ec == 0 means throw on error
+ bool push_directory(system::error_code& ec) BOOST_NOEXCEPT;
+
void pop();
};
// Implementation is inline to avoid dynamic linking difficulties with m_stack:
// Microsoft warning C4251, m_stack needs to have dll-interface to be used by
// 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;
else
{
// Logic for following predicate was contributed by Daniel Aarno to handle cyclic
// symlinks correctly and efficiently, fixing ticket #5652.
// if (((m_options & symlink_option::recurse) == symlink_option::recurse
// || !is_symlink(m_stack.top()->symlink_status()))
// && 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
void recur_dir_itr_imp::pop()
{
BOOST_ASSERT_MSG(m_level > 0,
@@ -964,122 +1151,51 @@ namespace detail
bool equal(const recursive_directory_iterator& rhs) const
{ return m_imp == rhs.m_imp; }
};
-# 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 -----------------------------------------------------------------------//
// Not part of the documented interface since false positives are possible;
// there is no law that says that an OS that has large stat.st_size
// actually supports large file sizes.