|
Boost-Commit : |
Subject: [Boost-commit] svn:boost r68913 - in branches/release: boost boost/filesystem boost/filesystem/v3 libs/filesystem libs/filesystem/test libs/filesystem/v3/doc libs/filesystem/v3/src libs/filesystem/v3/test libs/filesystem/v3/test/msvc10 libs/filesystem/v3/test/msvc10/tut5 libs/filesystem/v3/test/msvc10/tut6a libs/filesystem/v3/test/msvc10/tut6b libs/filesystem/v3/test/msvc10/tut6c
From: bdawes_at_[hidden]
Date: 2011-02-15 10:18:20
Author: bemandawes
Date: 2011-02-15 10:18:19 EST (Tue, 15 Feb 2011)
New Revision: 68913
URL: http://svn.boost.org/trac/boost/changeset/68913
Log:
Merge trunk, including reparse point bug fix
Added:
branches/release/libs/filesystem/v3/test/msvc10/tut5/
- copied from r68912, /trunk/libs/filesystem/v3/test/msvc10/tut5/
branches/release/libs/filesystem/v3/test/msvc10/tut5/tut5.vcxproj
- copied unchanged from r68912, /trunk/libs/filesystem/v3/test/msvc10/tut5/tut5.vcxproj
branches/release/libs/filesystem/v3/test/msvc10/tut6a/
- copied from r68912, /trunk/libs/filesystem/v3/test/msvc10/tut6a/
branches/release/libs/filesystem/v3/test/msvc10/tut6a/tut6a.vcxproj
- copied unchanged from r68912, /trunk/libs/filesystem/v3/test/msvc10/tut6a/tut6a.vcxproj
branches/release/libs/filesystem/v3/test/msvc10/tut6b/
- copied from r68912, /trunk/libs/filesystem/v3/test/msvc10/tut6b/
branches/release/libs/filesystem/v3/test/msvc10/tut6b/tut6b.vcxproj
- copied unchanged from r68912, /trunk/libs/filesystem/v3/test/msvc10/tut6b/tut6b.vcxproj
branches/release/libs/filesystem/v3/test/msvc10/tut6c/
- copied from r68912, /trunk/libs/filesystem/v3/test/msvc10/tut6c/
branches/release/libs/filesystem/v3/test/msvc10/tut6c/tut6c.vcxproj
- copied unchanged from r68912, /trunk/libs/filesystem/v3/test/msvc10/tut6c/tut6c.vcxproj
Properties modified:
branches/release/boost/filesystem/ (props changed)
branches/release/boost/filesystem.hpp (props changed)
branches/release/libs/filesystem/ (props changed)
Text files modified:
branches/release/boost/filesystem/v3/operations.hpp | 81 +++++++--
branches/release/libs/filesystem/test/Jamfile.v2 | 2
branches/release/libs/filesystem/v3/doc/path_table.cpp | 2
branches/release/libs/filesystem/v3/doc/reference.html | 260 +++++++++++++++++++++++---------
branches/release/libs/filesystem/v3/src/operations.cpp | 25 ++
branches/release/libs/filesystem/v3/test/msvc10/filesystem-v3.sln | 10 +
branches/release/libs/filesystem/v3/test/operations_test.cpp | 311 ++++++++++++++++++++++++++++-----------
7 files changed, 501 insertions(+), 190 deletions(-)
Modified: branches/release/boost/filesystem/v3/operations.hpp
==============================================================================
--- branches/release/boost/filesystem/v3/operations.hpp (original)
+++ branches/release/boost/filesystem/v3/operations.hpp 2011-02-15 10:18:19 EST (Tue, 15 Feb 2011)
@@ -25,6 +25,7 @@
#include <boost/filesystem/v3/path.hpp>
#include <boost/detail/scoped_enum_emulation.hpp>
+#include <boost/detail/bitmask.hpp>
#include <boost/system/error_code.hpp>
#include <boost/system/system_error.hpp>
#include <boost/shared_ptr.hpp>
@@ -84,7 +85,8 @@
class BOOST_FILESYSTEM_DECL file_status
{
public:
- explicit file_status(file_type v = status_error) : m_value(v) {}
+ file_status() : m_value(status_error) {}
+ explicit file_status(file_type v) : m_value(v) {}
void type(file_type v) { m_value = v; }
file_type type() const { return m_value; }
@@ -122,7 +124,7 @@
};
BOOST_SCOPED_ENUM_START(copy_option)
- {fail_if_exists, overwrite_if_exists};
+ {none, fail_if_exists = none, overwrite_if_exists};
BOOST_SCOPED_ENUM_END
//--------------------------------------------------------------------------------------//
@@ -331,17 +333,17 @@
void create_directory_symlink(const path& to, const path& from, system::error_code& ec)
{detail::create_directory_symlink(to, from, &ec);}
inline
- void create_hard_link(const path& to, const path& from) {detail::create_hard_link(to, from);}
+ void create_hard_link(const path& to, const path& new_hard_link) {detail::create_hard_link(to, new_hard_link);}
inline
- void create_hard_link(const path& to, const path& from, system::error_code& ec)
- {detail::create_hard_link(to, from, &ec);}
+ void create_hard_link(const path& to, const path& new_hard_link, system::error_code& ec)
+ {detail::create_hard_link(to, new_hard_link, &ec);}
inline
- void create_symlink(const path& to, const path& from) {detail::create_symlink(to, from);}
+ void create_symlink(const path& to, const path& new_symlink) {detail::create_symlink(to, new_symlink);}
inline
- void create_symlink(const path& to, const path& from, system::error_code& ec)
- {detail::create_symlink(to, from, &ec);}
+ void create_symlink(const path& to, const path& new_symlink, system::error_code& ec)
+ {detail::create_symlink(to, new_symlink, &ec);}
inline
path current_path() {return detail::current_path();}
@@ -637,6 +639,17 @@
// //
//--------------------------------------------------------------------------------------//
+ BOOST_SCOPED_ENUM_START(symlink_option)
+ {
+ none,
+ no_recurse = none, // don't follow directory symlinks (default behavior)
+ recurse, // follow directory symlinks
+ _detail_no_push = recurse << 1 // internal use only
+ };
+ BOOST_SCOPED_ENUM_END
+
+ BOOST_BITMASK(BOOST_SCOPED_ENUM(symlink_option))
+
namespace detail
{
struct recur_dir_itr_imp
@@ -644,9 +657,9 @@
typedef directory_iterator element_type;
std::stack< element_type, std::vector< element_type > > m_stack;
int m_level;
- bool m_no_push_request;
+ BOOST_SCOPED_ENUM(symlink_option) m_options;
- recur_dir_itr_imp() : m_level(0), m_no_push_request(false) {}
+ recur_dir_itr_imp() : m_level(0), m_options(symlink_option::none) {}
void increment(system::error_code* ec); // ec == 0 means throw on error
@@ -662,9 +675,11 @@
void recur_dir_itr_imp::increment(system::error_code* ec)
// ec == 0 means throw on error
{
- if (m_no_push_request)
- { m_no_push_request = false; }
- else if (is_directory(m_stack.top()->status()))
+ if ((m_options & symlink_option::_detail_no_push) == symlink_option::_detail_no_push)
+ m_options &= ~symlink_option::_detail_no_push;
+ else if (is_directory(m_stack.top()->status())
+ && (!is_symlink(m_stack.top()->symlink_status())
+ || (m_options & symlink_option::recurse) == symlink_option::recurse))
{
if (ec == 0)
m_stack.push(directory_iterator(m_stack.top()->path()));
@@ -718,27 +733,41 @@
recursive_directory_iterator(){} // creates the "end" iterator
- explicit recursive_directory_iterator(const path& dir_path)
+ explicit recursive_directory_iterator(const path& dir_path,
+ BOOST_SCOPED_ENUM(symlink_option) opt = symlink_option::none)
: m_imp(new detail::recur_dir_itr_imp)
{
+ m_imp->m_options = opt;
m_imp->m_stack.push(directory_iterator(dir_path));
if (m_imp->m_stack.top() == directory_iterator())
{ m_imp.reset (); }
}
recursive_directory_iterator(const path& dir_path,
+ BOOST_SCOPED_ENUM(symlink_option) opt,
system::error_code & ec)
: m_imp(new detail::recur_dir_itr_imp)
{
+ m_imp->m_options = opt;
m_imp->m_stack.push(directory_iterator(dir_path, ec));
if (m_imp->m_stack.top() == directory_iterator())
{ m_imp.reset (); }
}
- recursive_directory_iterator& increment(system::error_code* ec)
+ recursive_directory_iterator(const path& dir_path,
+ system::error_code & ec)
+ : m_imp(new detail::recur_dir_itr_imp)
+ {
+ m_imp->m_options = symlink_option::none;
+ m_imp->m_stack.push(directory_iterator(dir_path, ec));
+ if (m_imp->m_stack.top() == directory_iterator())
+ { m_imp.reset (); }
+ }
+
+ recursive_directory_iterator& increment(system::error_code& ec)
{
BOOST_ASSERT(m_imp.get() && "increment() on end recursive_directory_iterator");
- m_imp->increment(ec);
+ m_imp->increment(&ec);
return *this;
}
@@ -748,12 +777,17 @@
return m_imp->m_level;
}
- bool no_push_request() const
+ bool no_push_pending() const
{
- BOOST_ASSERT(m_imp.get() && "no_push_request() on end recursive_directory_iterator");
- return m_imp->m_no_push_request;
+ BOOST_ASSERT(m_imp.get() && "is_no_push_requested() on end recursive_directory_iterator");
+ return (m_imp->m_options & symlink_option::_detail_no_push)
+ == symlink_option::_detail_no_push;
}
+# ifndef BOOST_FILESYSTEM_NO_DEPRECATED
+ bool no_push_request() const { return no_push_pending(); }
+# endif
+
void pop()
{
BOOST_ASSERT(m_imp.get() && "pop() on end recursive_directory_iterator");
@@ -761,10 +795,13 @@
if (m_imp->m_stack.empty()) m_imp.reset(); // done, so make end iterator
}
- void no_push()
+ void no_push(bool value=true)
{
BOOST_ASSERT(m_imp.get() && "no_push() on end recursive_directory_iterator");
- m_imp->m_no_push_request = true;
+ if (value)
+ m_imp->m_options |= symlink_option::_detail_no_push;
+ else
+ m_imp->m_options &= ~symlink_option::_detail_no_push;
}
file_status status() const
@@ -979,6 +1016,7 @@
using filesystem3::read_symlink;
using filesystem3::recursive_directory_iterator;
using filesystem3::regular_file;
+ using filesystem3::reparse_file;
using filesystem3::remove;
using filesystem3::remove_all;
using filesystem3::rename;
@@ -990,6 +1028,7 @@
using filesystem3::status_error;
using filesystem3::status_known;
using filesystem3::symlink_file;
+ using filesystem3::symlink_option;
using filesystem3::symlink_status;
using filesystem3::system_complete;
using filesystem3::temp_directory_path;
Modified: branches/release/libs/filesystem/test/Jamfile.v2
==============================================================================
--- branches/release/libs/filesystem/test/Jamfile.v2 (original)
+++ branches/release/libs/filesystem/test/Jamfile.v2 2011-02-15 10:18:19 EST (Tue, 15 Feb 2011)
@@ -21,7 +21,7 @@
[ run ../v3/test/path_unit_test.cpp : : : : v3_path_unit_test ]
[ run ../v3/test/path_test.cpp : : : : v3_path_test ]
[ run ../v3/test/operations_unit_test.cpp : : : : v3_operations_unit_test ]
- [ run ../v3/test/operations_test.cpp : : : : v3_operations_test ]
+ [ run ../v3/test/operations_test.cpp : : : <test-info>always_show_run_output : v3_operations_test ]
[ run ../v3/test/fstream_test.cpp : : : : v3_fstream_test ]
[ run ../v3/test/convenience_test.cpp : : : : v3_convenience_test ]
[ run ../v3/test/large_file_support_test.cpp : : : : v3_large_file_support_test ]
Modified: branches/release/libs/filesystem/v3/doc/path_table.cpp
==============================================================================
--- branches/release/libs/filesystem/v3/doc/path_table.cpp (original)
+++ branches/release/libs/filesystem/v3/doc/path_table.cpp 2011-02-15 10:18:19 EST (Tue, 15 Feb 2011)
@@ -199,7 +199,7 @@
std::cerr <<
"Usage: path_table \"POSIX\"|\"Windows\" input-file posix-file output-file\n"
"Run on POSIX first, then on Windows\n"
- " \"POSIX\" causes POSIX results to be save in posix-file;\n"
+ " \"POSIX\" causes POSIX results to be saved in posix-file;\n"
" \"Windows\" causes POSIX results read from posix-file\n"
" input-file contains the paths to appear in the table.\n"
" posix-file will be used for POSIX results\n"
Modified: branches/release/libs/filesystem/v3/doc/reference.html
==============================================================================
--- branches/release/libs/filesystem/v3/doc/reference.html (original)
+++ branches/release/libs/filesystem/v3/doc/reference.html 2011-02-15 10:18:19 EST (Tue, 15 Feb 2011)
@@ -89,7 +89,10 @@
<a href="#Operational-functions">
Operational functions</a><br>
  absolute<br>
+ copy<br>
+ copy_directory<br>
copy_file<br>
+ copy_symlink<br>
  create_directories<br>
  create_directory<br>
  create_hard_link<br>
@@ -98,6 +101,7 @@
  exists<br>
  equivalent<br>
  file_size<br>
+ hard_link_count<br>
initial_path<br>
  is_directory<br>
  is_empty<br>
@@ -330,20 +334,29 @@
BOOST_SCOPED_ENUM_START(<a name="copy_option">copy_option</a>)
{
- fail_if_exists,
+ none
+ fail_if_exists = none,
overwrite_if_exists
};
BOOST_SCOPED_ENUM_END
+ BOOST_SCOPED_ENUM_START(<a name="symlink_option">symlink_option</a>)
+ {
+ none
+ no_recurse = none,
+ recurse
+ };
+ BOOST_SCOPED_ENUM_END
+
// operational functions
</span> path absolute(const path& p, const path& base=current_path());
- void copy(const path& from, const path& to);
- void copy(const path& from, const path& to, system::error_code& ec);
+ void copy(const path& from, const path& to);
+ void copy(const path& from, const path& to, system::error_code& ec);
- void copy_directory(const path& from, const path& to);
- void copy_directory(const path& from, const path& to, system::error_code& ec);
+ void copy_directory(const path& from, const path& to);
+ void copy_directory(const path& from, const path& to, system::error_code& ec);
void copy_file(const path& from, const path& to);
void copy_file(const path& from, const path& to, system::error_code& ec);
@@ -351,8 +364,8 @@
void copy_file(const path& from, const path& to, BOOST_SCOPED_ENUM(copy_option) option,
system::error_code& ec);
- void copy_symlink(const path& existing_symlink, const path& new_symlink);
- void copy_symlink(const path& existing_symlink, const path& new_symlink, system::error_code& ec);
+ void copy_symlink(const path& existing_symlink, const path& new_symlink);
+ void copy_symlink(const path& existing_symlink, const path& new_symlink, system::error_code& ec);
bool create_directories(const path& p);
bool create_directories(const path& p, system::error_code& ec);
@@ -360,8 +373,8 @@
bool create_directory(const path& p);
bool create_directory(const path& p, system::error_code& ec);
-<span style="background-color: #FFFFFF"> void create_directory_symlink(const path& to, const path& </span>new_symlink<span style="background-color: #FFFFFF">);
- void create_directory_symlink(const path& to, const path& </span>new_symlink, system::error_code& ec<span style="background-color: #FFFFFF">);
+<span style="background-color: #FFFFFF"> void create_directory_symlink(const path& to, const path& </span>new_symlink<span style="background-color: #FFFFFF">);
+ void create_directory_symlink(const path& to, const path& </span>new_symlink, system::error_code& ec<span style="background-color: #FFFFFF">);
</span>
void create_hard_link(const path& to, const path& new_hard_link);
void create_hard_link(const path& to, const path& new_hard_link, system::error_code& ec);
@@ -383,8 +396,8 @@
<span style="background-color: #FFFFFF; ">uintmax_t</span> file_size(const path& p);
<span style="background-color: #FFFFFF; ">uintmax_t</span> file_size(const path& p, system::error_code& ec);</pre>
-<pre> uintmax_t hard_link_count(const path& p);
- uintmax_t hard_link_count(const path& p, system::error_code& ec);
+<pre> uintmax_t hard_link_count(const path& p);
+ uintmax_t hard_link_count(const path& p, system::error_code& ec);
<span style="background-color: #FFFFFF">const path& initial_path();
const path& initial_path(</span><code>system::error_code& ec</code><span style="background-color: #FFFFFF">);
@@ -425,8 +438,8 @@
void rename(const path& from, const path& to);
void rename(const path& from, const path& to, system::error_code& ec);
- void resize_file(const path& p, uintmax_t size);
- void resize_file(const path& p, uintmax_t size, system::error_code& ec);
+ void resize_file(const path& p, uintmax_t size);
+ void resize_file(const path& p, uintmax_t size, system::error_code& ec);
<span style="background-color: #FFFFFF"> space_info space(const path& p);
<a href="#space_info">space_info</a> <a href="#space">space</a>(const path& p</span>, system::error_code& ec<span style="background-color: #FFFFFF">);
@@ -703,7 +716,7 @@
<font size="4">path</font></code> constructors</a></h3>
<pre>path();</pre>
<blockquote>
- <p><i>Postconditions:</i> <code>empty()</code>.</p>
+ <p><i>Postcondition:</i> <code>empty()</code>.</p>
</blockquote>
<pre>template <class Source>
path(Source const& source, const codecvt_type& cvt=codecvt());</pre>
@@ -1231,7 +1244,7 @@
<h4> <a name="filesystem_error-members"> <code>filesystem_error</code> members</a></h4>
<pre><a name="filesystem_error-2-arg">filesystem_error</a>(const std::string& <span style="background-color: #FFFFFF">what_arg</span>, error_code ec);</pre>
<blockquote>
- <p><i>Postconditions:</i></p>
+ <p><i>Postcondition:</i></p>
<table border="1" cellpadding="5" cellspacing="0" style="border-collapse: collapse" bordercolor="#111111" width="46%">
<tr>
<td width="18%"><b>Expression</b></td>
@@ -1259,7 +1272,7 @@
</blockquote>
<pre><a name="filesystem_error-3-arg">filesystem_error</a>(const std::string& <span style="background-color: #FFFFFF">what_arg</span>, const path_type& p1, error_code ec);</pre>
<blockquote>
- <p><i>Postconditions:</i></p>
+ <p><i>Postcondition:</i></p>
<table border="1" cellpadding="5" cellspacing="0" style="border-collapse: collapse" bordercolor="#111111" width="46%">
<tr>
<td width="18%"><b>Expression</b></td>
@@ -1288,7 +1301,7 @@
</blockquote>
<pre><a name="filesystem_error-4-arg">filesystem_error</a>(const std::string& <span style="background-color: #FFFFFF">what_arg</span>, const path_type& p1, const path_type& p2, error_code ec);</pre>
<blockquote>
- <p><i>Postconditions:</i></p>
+ <p><i>Postcondition:</i></p>
<table border="1" cellpadding="5" cellspacing="0" style="border-collapse: collapse" bordercolor="#111111" width="46%">
<tr>
<td width="18%"><b>Expression</b></td>
@@ -1394,7 +1407,7 @@
<h4> <a name="directory_entry-constructors"> <code>directory_entry </code>constructors</a></h4>
<pre>directory_entry();</pre>
<blockquote>
- <p><i>Postconditions:</i></p>
+ <p><i>Postcondition:</i></p>
<table border="1" cellpadding="5" cellspacing="0" style="border-collapse: collapse" bordercolor="#111111" width="36%">
<tr>
<td width="18%"><b>Expression</b></td>
@@ -1416,7 +1429,7 @@
</blockquote>
<pre>explicit directory_entry(const path_type& p, <span style="background-color: #FFFFFF">file_status</span> st=file_status(), <span style="background-color: #FFFFFF">file_status</span> symlink_st=file_status());</pre>
<blockquote>
- <p><i>Postconditions:</i></p>
+ <p><i>Postcondition:</i></p>
<table border="1" cellpadding="5" cellspacing="0" style="border-collapse: collapse" bordercolor="#111111" width="36%">
<tr>
<td width="18%"><b>Expression</b></td>
@@ -1439,7 +1452,7 @@
<h4> <a name="directory_entry-modifiers"> <code>directory_entry </code>modifiers</a></h4>
<pre>void assign(const path_type& p, <span style="background-color: #FFFFFF">file_status</span> st=file_status(), <span style="background-color: #FFFFFF">file_status</span> symlink_st=file_status());</pre>
<blockquote>
- <p><i>Postconditions:</i></p>
+ <p><i>Postcondition:</i></p>
<table border="1" cellpadding="5" cellspacing="0" style="border-collapse: collapse" bordercolor="#111111" width="36%">
<tr>
<td width="18%"><b>Expression</b></td>
@@ -1461,7 +1474,7 @@
</blockquote>
<pre>void replace_filename(const path& p, <span style="background-color: #FFFFFF">file_status</span> st=file_status(), <span style="background-color: #FFFFFF">file_status</span> symlink_st=file_status());</pre>
<blockquote>
- <p><i>Postconditions:</i></p>
+ <p><i>Postcondition:</i></p>
<table border="1" cellpadding="5" cellspacing="0" style="border-collapse: collapse" bordercolor="#111111" width="43%">
<tr>
<td width="18%"><b>Expression</b></td>
@@ -1674,7 +1687,7 @@
</blockquote>
<h3><a name="Class-recursive_directory_iterator">Class <code>recursive_directory_iterator</code></a></h3>
-<p>Objects of type <code>directory_iterator</code> provide standard library
+<p>Objects of type <code>recursive_directory_iterator</code> provide standard library
compliant iteration over the contents of a directory, including recursion into
its sub-directories.</p>
<pre> namespace boost
@@ -1682,20 +1695,23 @@
namespace filesystem
{
class recursive_directory_iterator :
- public iterator<input_iterator_tag, directory_entry >
+ public iterator<input_iterator_tag, directory_entry>
{
public:
// constructors and destructor
recursive_directory_iterator();
recursive_directory_iterator(const recursive_directory_iterator&);
- explicit recursive_directory_iterator(const path& p);
+ explicit recursive_directory_iterator(const path& p,
+ BOOST_SCOPED_ENUM(symlink_option) opt = symlink_option::none);
+ recursive_directory_iterator(const path& p,
+ BOOST_SCOPED_ENUM(symlink_option) opt, system::error_code& ec);
recursive_directory_iterator(const path& p, system::error_code& ec);
~recursive_directory_iterator();
// observers
int level() const;
- bool no_push<code>_request</code>() const;
+ bool no_push<code>_pending</code>() const;
// modifiers
recursive_directory_iterator& operator=(const recursive_directory_iterator&);
@@ -1704,31 +1720,33 @@
recursive_directory_iterator& increment(system::error_code& ec);
void pop();
- void no_push();
+ void no_push(bool value=true);
// other members as required by
// C++ Std, 24.1.2 Input iterators [input.iterators]
private:
- int m_level; <b><i> // for exposition only</i></b>
- bool m_no_<code>push_request</code>; <b><i>// for exposition only</i></b>
+<i><b> // actual data members will probably be stored in a shared pimpl object,
+ // or some similar mechanism, to achieve the required input iterator copy semantics
+</b></i> int m_level; <b><i> // for exposition only</i></b>
+ bool m_no_<code>push</code>; <i><b> // for exposition only
+ </b></i>BOOST_SCOPED_ENUM(symlink_option) m_options; <i><b>// for exposition only</b></i>
};
} // namespace filesystem
} // namespace boost</pre>
+
<p>The behavior of a <code>recursive_directory_iterator</code> is the same
as a <code>directory_iterator</code> unless otherwise specified.</p>
<ul>
- <li>When an iterator reaches the end of the directory currently being iterated
+ <li>Incrementing a <code>recursive_directory_iterator</code> pointing to a
+ directory causes that directory itself to be iterated ovee, as specified by
+ the <code>operator++</code> and <code>increment</code> functions.<br>
+ </li>
+ <li>When a <code>recursive_directory_iterator</code> reaches the end of the directory currently being iterated
over, or when <code>pop()</code> is called, <code>m_level</code> is
- decremented, and iteration continues with the parent directory, until the
- directory specified in the constructor argument is reached.</li>
+ decremented, and iteration of the parent directory continues.</li>
</ul>
-<blockquote>
- <p>[<i>Note:</i> One of the uses of <code>no_push()</code> is to prevent
- unwanted recursion into a directory symlink. This may be necessary to
- prevent loops on some operating systems. <i>--end note</i>]</p>
-</blockquote>
<pre>recursive_directory_iterator();</pre>
<blockquote>
@@ -1738,15 +1756,18 @@
</blockquote>
-<pre><code>explicit </code>recursive_<code>directory_iterator(</code>const path& p<code>);
-</code>recursive_<code>directory_iterator(</code>const path& p, system::error_code& ec<code>);</code></pre>
+<pre>explicit recursive_directory_iterator(const path& p, BOOST_SCOPED_ENUM(symlink_option) opt = symlink_option::none);
+recursive_directory_iterator(const path& p, BOOST_SCOPED_ENUM(symlink_option) opt, system::error_code& ec);
+recursive_<code>directory_iterator(</code>const path& p, system::error_code& ec<code>);</code></pre>
<blockquote>
<p><i>Effects:</i> Constructs a iterator representing the first
entry in the directory <code>p</code> resolves to, if any; otherwise, the end iterator.</p>
-<p><i>Postconditions: </i>Unless the end iterator was constructed,<i> </i><code>
-level() == 0</code>, <code>no_push_request() == false</code>.</p>
+<p dir="ltr"><i>Postcondition: </i>Unless the end iterator was constructed,<i> </i>
+<code>level() == 0 && no_push_pending() == false && m_options == opt</code>.
+For the signature without a <code>symlink_option</code> argument, <code>opt</code>
+is assumed to be <code>symlink_option::none</code>.</p>
<p><i>Throws:</i> As specified in
<a href="#Error-reporting">
@@ -1755,6 +1776,11 @@
<p>[<i>Note:</i> To iterate over the current directory, use <code>recursive_directory_iterator(".")</code> rather than
<code>recursive_directory_iterator("")</code>.
<i>-- end note</i>]</p>
+
+<p>[<i>Note:</i> By default, <code>recursive_directory_iterator</code> does not
+follow directory symlinks. To follow directory symlinks, specify <code>opt</code>
+as <code>symlink_option::recurse</code>
+<i>-- end note</i>]</p>
</blockquote>
<pre>int level() const;</pre>
<blockquote>
@@ -1762,10 +1788,10 @@
<p><i>Returns:</i> <code>m_level</code>.</p>
<p><i>Throws:</i> Nothing.</p>
</blockquote>
-<pre>bool <code>no_push_request</code>() const;</pre>
+<pre>bool <code>no_push_pending</code>() const;</pre>
<blockquote>
<p><i>Requires:</i> <code>*this != recursive_directory_iterator()</code>.</p>
- <p><i>Returns:</i> <code>m_no_push_request</code>.</p>
+ <p><i>Returns:</i> <code>m_no_push</code>.</p>
<p><i>Throws:</i> Nothing.</p>
</blockquote>
<pre><code>recursive_directory_iterator</code>& <a name="recursive_directory_iterator-increment">operator++</a>();
@@ -1773,10 +1799,23 @@
<blockquote>
<p><i>Effects:</i> As specified by the C++ Standard, 24.1.1 Input iterators [input.iterators],
-except that if <code>(*this)->is_directory() && !no_push_requested()</code> then <code>m_level</code>
-is incremented and <code>(*this)->path()</code> is recursively iterated into.</p>
+except:</p>
+
+<ul>
+ <li dir="ltr">
-<p><i>Postconditions:</i> <code>no_push_request() == false</code>.</p>
+<p dir="ltr">if <code>!no_push_pending() && is_directory(this->status())
+&& (!is_symlink(this->symlink_status()) || (m_options
+& symlink_option::recurse) != 0)</code> then <code>m_level</code>
+is incremented and directory <code>(*this)->path()</code> is recursively iterated into.<br>
+ </p>
+
+ </li>
+ <li>if there are no more directory entries at this level then <code>m_level</code>
+is decremented and iteration of the parent directory resumes.</li>
+</ul>
+
+<p><i>Postcondition:</i> <code>no_push_pending() == false</code>.</p>
<p><i>Returns:</i> <code>*this</code>.</p>
@@ -1793,14 +1832,13 @@
iterated over, and continue iteration over the parent directory.</p>
<p><i>Throws:</i> Nothing.</p>
</blockquote>
-<pre>void no_push();</pre>
+<pre>void no_push(bool value=true);</pre>
<blockquote>
<p><i>Requires:</i> <code>*this != recursive_directory_iterator()</code>.</p>
-<p><i>Postconditions:</i> <code>no_push_request() == true</code>.</p>
+<p><i>Postcondition:</i> <code>no_push_pending() == value</code>.</p>
<p><i>Throws:</i> Nothing.</p>
- <p>[<i>Note:</i> One of the uses of <code>no_push()</code> is to prevent
- unwanted recursion into a directory symlink. This may be necessary to
- prevent loops on some operating systems. <i>--end note</i>]</p>
+ <p>[<i>Note:</i> <code>no_push()</code> is used to prevent
+ unwanted recursion into a directory. <i>--end note</i>]</p>
</blockquote>
<h3><a name="file_status">Class file_status</a></h3>
<pre> namespace boost
@@ -1879,25 +1917,47 @@
<td align="center"><code>return absolute(base) / p</code></td>
</tr>
</table>
- <p><i>Postconditions:</i> For the returned path, <code>rp,</code> <code>
+ <p><i>Postcondition:</i> For the returned path, <code>rp,</code> <code>
rp.is_absolute()</code> is true.</p>
<p><i>Throws:</i> If <code>base.is_absolute()</code> is true, throws only if
memory allocation fails.</p>
</blockquote>
-<pre>void copy_file(const path& from, const path& to);</pre>
+<pre>void <a name="copy">copy</a>(const path& from, const path& to);
+void copy(const path& from, const path& to, system::error_code& ec);</pre>
<blockquote>
- <p><i>Effects: </i><code>copy_file(from, to,
- copy_option::fail_if_exists)</code>.</p>
+ <p><i>Effects:</i> As if</p>
+
+ <blockquote>
+ <pre>file_status s(symlink_status(from<i>[</i><code>, ec</code><i>]</i>));
+if(is_symlink(s))
+ copy_symlink(from, to<i>[</i><code>, ec</code><i>]</i>);
+else if(is_directory(s))
+ copy_directory(from, to<i>[</i><code>, ec</code><i>]</i>);
+else if(is_regular_file(s))
+ copy_file(from, to, copy_option::fail_if_exists<i>[</i><code>, ec</code><i>]</i>);
+else
+<i> Report error as specified in Error reporting.</i></pre>
+ </blockquote>
+ <p><i>Throws:</i> As specified in
+ <a href="#Error-reporting">
+ Error reporting</a>.</p>
+
+</blockquote>
+<pre>void <a name="copy_directory">copy_directory</a>(const path& from, const path& to);
+void copy_directory(const path& from, const path& to, system::error_code& ec);</pre>
+<blockquote>
+ <p><i>Effects: </i></p>
<p><i>Throws:</i> As specified in
<a href="#Error-reporting">
Error reporting</a>.</p>
</blockquote>
-<pre>void copy_file(const path& from, const path& to, system::error_code& ec);</pre>
+<pre>void copy_file(const path& from, const path& to);
+void copy_file(const path& from, const path& to, system::error_code& ec);</pre>
<blockquote>
<p><i>Effects: </i><code>copy_file(from, to,
- copy_option::fail_if_exists, ec)</code>.</p>
+ copy_option::fail_if_exists</code><i>[</i><code>, ec</code><i>]</i><code>)</code>.</p>
<p><i>Throws:</i> As specified in
<a href="#Error-reporting">
@@ -1914,13 +1974,24 @@
<a href="#Error-reporting">
Error reporting</a>.</p>
</blockquote>
+<pre>void <a name="copy_symlink">copy_symlink</a>(const path& existing_symlink, const path& new_symlink);
+void copy_symlink(const path& existing_symlink, const path& new_symlink, system::error_code& ec);</pre>
+<blockquote>
+ <p><i>Effects: </i><code>create_symlink(read_symlink(existing_symlink</code><i>[</i><code>, ec</code><i>]</i><code>),
+ new_symlink</code><i>[</i><code>, ec</code><i>]</i><code>)</code>.</p>
+
+ <p><i>Throws:</i> As specified in
+ <a href="#Error-reporting">
+ Error reporting</a>.</p>
+
+</blockquote>
<pre>bool <a name="create_directories">create_directories</a>(const path& p);
bool <a name="create_directories2">create_directories</a>(const path& p, system::error_code& ec);</pre>
<blockquote>
<p><i>Requires:</i> <code>p.empty() || <br>
forall px: px == p || is_parent(px, p): is_directory(px) || !exists( px )</code>
</p>
- <p><i>Postconditions:</i> <code>is_directory(p)</code></p>
+ <p><i>Postcondition:</i> <code>is_directory(p)</code></p>
<p><i>Returns:</i> The value of <code>!exists(p)</code> prior to the
establishment of the postcondition.</p>
<p><i>Throws:</i> As specified in
@@ -1940,19 +2011,51 @@
<a href="#Error-reporting">
Error reporting</a>.</p>
</blockquote>
-<pre><span style="background-color: #FFFFFF">void <a name="create_hard_link">create_hard_link</a>(const path& to, const path& from);
-void <a name="create_hard_link2">create_hard_link</a>(const path& to, const path& from, system::error_code& ec);</span></pre>
+<pre><span style="background-color: #FFFFFF">void <a name="create_directory_symlink">create_directory_symlink</a>(const path& to, const path& new_symlink);
+void create_directory_symlink(const path& to, const path& new_symlink, system::error_code& ec);</span></pre>
+<blockquote style="font-size: 10pt">
+ <p style="font-size: 10pt"><i><span style="background-color: #FFFFFF">Effects:</span></i><span style="background-color: #FFFFFF">
+ Establishes the postcondition, as if by </span><i>
+ <span style="background-color: #FFFFFF">POSIX</span></i><span style="background-color: #FFFFFF">
+ </span><code><span style="background-color: #FFFFFF">
+ <a href="http://www.opengroup.org/onlinepubs/000095399/functions/symlink.html">
+ symlink()</a></span></code><span style="background-color: #FFFFFF">.</span></p>
+ <p style="font-size: 10pt"><span style="background-color: #FFFFFF"><i>
+ Postcondition:</i> <code>new_symlink</code> resolves to a symbolic link file that
+ contains an unspecified representation of <code>to</code>.</span></p>
+ <p style="font-size: 10pt"><i>Throws:</i> As specified in
+ <a href="#Error-reporting">
+ Error reporting</a>.</p>
+ <p style="font-size: 10pt"><span style="background-color: #FFFFFF">[</span><i><span style="background-color: #FFFFFF">Note:</span></i><span style="background-color: #FFFFFF">
+ Some <b>operating systems</b>, such as Windows, require symlink creation to
+ identify that the link is to a directory. Portable code should use <code>
+ create_directory_symlink()</code> to create directory symlinks rather than
+ <code>create_symlink()</code> </span> <i><span style="background-color: #FFFFFF">-- end note</span></i><span style="background-color: #FFFFFF">]</span></p>
+ <p><span style="background-color: #FFFFFF">[</span><i><span style="background-color: #FFFFFF">Note:</span></i><span style="background-color: #FFFFFF">
+ Some <b>operating systems</b> do not support symbolic links at all or support
+ them only for regular files. Windows prior to Vista, for example, did not
+ support symbolic links.
+ Some <b>file systems</b> do not
+ support
+ symbolic links regardless of the operating system - the FAT system used on floppy discs, memory cards and flash
+ drives,
+ for example. Thus symbolic links should only be used if these situations are
+ not concerns, or if workarounds are provided. </span> <i><span style="background-color: #FFFFFF">-- end note</span></i><span style="background-color: #FFFFFF">]</span></p>
+ </blockquote>
+<pre><span style="background-color: #FFFFFF">void <a name="create_hard_link">create_hard_link</a>(const path& to, const path& new_hard_link);
+void <a name="create_hard_link2">create_hard_link</a>(const path& to, const path& new_hard_link, system::error_code& ec);</span></pre>
<blockquote>
<p><i><span style="background-color: #FFFFFF">Effects:</span></i><span style="background-color: #FFFFFF"> Establishes the postcondition, as if by
</span> <i><span style="background-color: #FFFFFF">POSIX</span></i><span style="background-color: #FFFFFF">
</span> <code>
<a href="http://www.opengroup.org/onlinepubs/000095399/functions/link.html">
<span style="background-color: #FFFFFF">link()</span></a></code><span style="background-color: #FFFFFF">.</span></p>
- <p><i><span style="background-color: #FFFFFF">Postconditions:</span></i></p>
+ <p><i><span style="background-color: #FFFFFF">Postcondition:</span></i></p>
<ul>
<li><span style="background-color: #FFFFFF"> </span><code><span style="background-color: #FFFFFF">exists(to) &&
- exists(from) && equivalent(to,
- from)</span></code></li>
+ exists(</span></code><span style="background-color: #FFFFFF"><code>new_hard_link</code></span><code><span style="background-color: #FFFFFF">) && equivalent(to,
+
+ </span></code><span style="background-color: #FFFFFF"><code>new_hard_link</code></span><code><span style="background-color: #FFFFFF">)</span></code></li>
<li><span style="background-color: #FFFFFF">The contents of the file or directory
<code>to</code> resolves to are unchanged.</span></li>
</ul>
@@ -1967,8 +2070,8 @@
number of links per file. Thus hard links should only be used if these
situations are not concerns, or if workarounds are provided. </span> <i><span style="background-color: #FFFFFF">-- end note</span></i><span style="background-color: #FFFFFF">]</span></p>
</blockquote>
-<pre><span style="background-color: #FFFFFF">void <a name="create_symlink">create_symlink</a>(const path& to, const path& from);
-void <a name="create_symlink2">create_symlink</a>(const path& to, const path& from, system::error_code& ec);</span></pre>
+<pre><span style="background-color: #FFFFFF">void <a name="create_symlink">create_symlink</a>(const path& to, const path& new_symlink);
+void <a name="create_symlink2">create_symlink</a>(const path& to, const path& new_symlink, system::error_code& ec);</span></pre>
<blockquote style="font-size: 10pt">
<p style="font-size: 10pt"><i><span style="background-color: #FFFFFF">Effects:</span></i><span style="background-color: #FFFFFF">
Establishes the postcondition, as if by </span><i>
@@ -1977,7 +2080,7 @@
<a href="http://www.opengroup.org/onlinepubs/000095399/functions/symlink.html">
symlink()</a></span></code><span style="background-color: #FFFFFF">.</span></p>
<p style="font-size: 10pt"><span style="background-color: #FFFFFF"><i>
- Postconditions:</i> <code>from</code> resolves to a symbolic link file that
+ Postcondition:</i> <code>new_symlink</code> resolves to a symbolic link file that
contains an unspecified representation of <code>to</code>.</span></p>
<p style="font-size: 10pt"><i>Throws:</i> As specified in
<a href="#Error-reporting">
@@ -2019,7 +2122,7 @@
</span><code><span style="background-color: #FFFFFF">
<a href="http://www.opengroup.org/onlinepubs/000095399/functions/chdir.html">
chdir()</a></span></code><span style="background-color: #FFFFFF">.</span></p>
-<p><i>Postconditions:</i> <code>equivalent(p, current_path())</code>.</p>
+<p><i>Postcondition:</i> <code>equivalent(p, current_path())</code>.</p>
<p><i>Throws:</i> As specified in
<a href="#Error-reporting">
Error reporting</a>.</p>
@@ -2094,6 +2197,17 @@
<a href="#Error-reporting">
Error reporting</a>.</p>
</blockquote>
+<pre>uintmax_t <a name="hard_link_count">hard_link_count</a>(const path& p);
+uintmax_t hard_link_count(const path& p, system::error_code& ec);</pre>
+<blockquote>
+
+ <p><i>Returns:</i> The number of hard links for <code>p</code>.</p>
+ <p style="font-size: 10pt"><i>Throws:</i> As specified in
+ <a href="#Error-reporting">
+ Error reporting</a>.</p>
+
+</blockquote>
+
<pre><span style="background-color: #FFFFFF">const path& <a name="initial_path">initial_path</a>();
const path& <a name="initial_path">initial_path</a>(</span><code>system::error_code& ec</code><span style="background-color: #FFFFFF">);</span></pre>
<blockquote>
@@ -2280,7 +2394,7 @@
<pre>void <a name="resize_file">resize_file</a>(const path& p, <span style="background-color: #FFFFFF; ">uintmax_t new_size</span>);
void <a name="resize_file2">resize_file</a>(const path& p, <span style="background-color: #FFFFFF; ">uintmax_t new_size, </span>system::error_code& ec);</pre>
<blockquote>
-<p><i>Postconditions:</i> <code>file_size() == new_size</code>.</p>
+<p><i>Postcondition:</i> <code>file_size() == new_size</code>.</p>
<p><i>Throws:</i> As specified in
<a href="#Error-reporting">
Error reporting</a>.</p>
@@ -2449,7 +2563,7 @@
same rules used by the operating system to resolve a path passed as the
filename argument to standard library open functions.</p>
<p><i>Returns:</i> The composed path.</p>
- <p><i>Postconditions:</i> For the returned path, <code>rp,</code> <code>
+ <p><i>Postcondition:</i> For the returned path, <code>rp,</code> <code>
rp.is_absolute()</code> is true.</p>
<p>[<i>Note:</i> For <i>POSIX</i>, <code>system_complete(p)</code> has the same semantics as
<code>complete(p, current_path())</code>.</p>
@@ -2569,10 +2683,10 @@
<p>Shaded entries indicate cases where <i>POSIX</i> and <i>Windows</i>
implementations yield different results. The top value is the
<i>POSIX</i> result and the bottom value is the <i>Windows</i> result. <br>
- <table border="1" cellspacing="0" cellpadding="5">
+<table border="1" cellspacing="0" cellpadding="5">
<p>
-<tr><td><b><font size="2">Constructor<br>argument</font></b></td>
-<td><b><font size="2">Iteration<br>over<br>Elements</font></b></td>
+<tr><td><b>Constructor<br>argument</b></td>
+<td><b>Iteration<br>over<br>Elements</b></td>
<td><b><code>string()</code></b></td>
<td><b><code>generic_<br>string()</code></b></td>
<td><b><code>root_<br>path()</code></b></td>
@@ -3063,8 +3177,6 @@
<td><span style="background-color: #CCFFCC"><code>foo\bar</code><br><code>bar</code></span></td>
</tr>
</table>
-<table border="1" cellspacing="0" cellpadding="5" width="1066">
-</table>
<h2><a name="Acknowledgements">Acknowledgements</a></h2>
<p>This Filesystem Library is dedicated to my wife, Sonda, who provided the
support necessary to see both a trial implementation and the proposal itself
@@ -3109,7 +3221,7 @@
<p>Distributed under the Boost Software License, Version 1.0. See
<a href="http://www.boost.org/LICENSE_1_0.txt">www.boost.org/LICENSE_1_0.txt</a></p>
<p>Revised
-<!--webbot bot="Timestamp" S-Type="EDITED" S-Format="%d %B %Y" startspan -->02 January 2011<!--webbot bot="Timestamp" endspan i-checksum="32200" --></p>
+<!--webbot bot="Timestamp" S-Type="EDITED" S-Format="%d %B %Y" startspan -->12 February 2011<!--webbot bot="Timestamp" endspan i-checksum="40670" --></p>
</body>
Modified: branches/release/libs/filesystem/v3/src/operations.cpp
==============================================================================
--- branches/release/libs/filesystem/v3/src/operations.cpp (original)
+++ branches/release/libs/filesystem/v3/src/operations.cpp 2011-02-15 10:18:19 EST (Tue, 15 Feb 2011)
@@ -1799,9 +1799,13 @@
? 0 : ::GetLastError(), system_category() );
}
target = data.cFileName;
- if (data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
- { sf.type(fs::directory_file); symlink_sf.type(fs::directory_file); }
- else { sf.type(fs::regular_file); symlink_sf.type(fs::regular_file); }
+ if (data.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT)
+ // reparse points are complex, so don't try to handle them here
+ { sf.type(fs::status_error); symlink_sf.type(fs::status_error); }
+ else if (data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
+ { sf.type(fs::directory_file); symlink_sf.type(fs::directory_file); }
+ else
+ { sf.type(fs::regular_file); symlink_sf.type(fs::regular_file); }
return error_code();
}
@@ -1816,9 +1820,13 @@
return error_code(error == ERROR_NO_MORE_FILES ? 0 : error, system_category());
}
target = data.cFileName;
- if (data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
+ if (data.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT)
+ // reparse points are complex, so don't try to handle them here
+ { sf.type(fs::status_error); symlink_sf.type(fs::status_error); }
+ else if (data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
{ sf.type(fs::directory_file); symlink_sf.type(fs::directory_file); }
- else { sf.type(fs::regular_file); symlink_sf.type(fs::regular_file); }
+ else
+ { sf.type(fs::regular_file); symlink_sf.type(fs::regular_file); }
return error_code();
}
#endif
@@ -1935,7 +1943,12 @@
}
else if (ec != 0) ec->clear();
- if (it.m_imp->handle == 0){ it.m_imp.reset(); return; } // eof, make end
+ if (it.m_imp->handle == 0) // eof, make end
+ {
+ it.m_imp.reset();
+ return;
+ }
+
if (!(filename[0] == dot // !(dot or dot-dot)
&& (filename.size()== 1
|| (filename[1] == dot
Modified: branches/release/libs/filesystem/v3/test/msvc10/filesystem-v3.sln
==============================================================================
--- branches/release/libs/filesystem/v3/test/msvc10/filesystem-v3.sln (original)
+++ branches/release/libs/filesystem/v3/test/msvc10/filesystem-v3.sln 2011-02-15 10:18:19 EST (Tue, 15 Feb 2011)
@@ -53,6 +53,12 @@
{FFD738F7-96F0-445C-81EA-551665EF53D1} = {FFD738F7-96F0-445C-81EA-551665EF53D1}
EndProjectSection
EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "tut6c", "tut6c\tut6c.vcxproj", "{17C6DD1B-EF6F-4561-B4FF-CF39F975ED29}"
+ ProjectSection(ProjectDependencies) = postProject
+ {F94CCADD-A90B-480C-A304-C19D015D36B1} = {F94CCADD-A90B-480C-A304-C19D015D36B1}
+ {FFD738F7-96F0-445C-81EA-551665EF53D1} = {FFD738F7-96F0-445C-81EA-551665EF53D1}
+ EndProjectSection
+EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Win32 = Debug|Win32
@@ -128,6 +134,10 @@
{4A77CA6A-8E72-4CC6-9FE7-2C555C51815C}.Debug|Win32.Build.0 = Debug|Win32
{4A77CA6A-8E72-4CC6-9FE7-2C555C51815C}.Release|Win32.ActiveCfg = Release|Win32
{4A77CA6A-8E72-4CC6-9FE7-2C555C51815C}.Release|Win32.Build.0 = Release|Win32
+ {17C6DD1B-EF6F-4561-B4FF-CF39F975ED29}.Debug|Win32.ActiveCfg = Debug|Win32
+ {17C6DD1B-EF6F-4561-B4FF-CF39F975ED29}.Debug|Win32.Build.0 = Debug|Win32
+ {17C6DD1B-EF6F-4561-B4FF-CF39F975ED29}.Release|Win32.ActiveCfg = Release|Win32
+ {17C6DD1B-EF6F-4561-B4FF-CF39F975ED29}.Release|Win32.Build.0 = Release|Win32
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
Modified: branches/release/libs/filesystem/v3/test/operations_test.cpp
==============================================================================
--- branches/release/libs/filesystem/v3/test/operations_test.cpp (original)
+++ branches/release/libs/filesystem/v3/test/operations_test.cpp 2011-02-15 10:18:19 EST (Tue, 15 Feb 2011)
@@ -38,6 +38,10 @@
#include <fstream>
#include <iostream>
+
+using std::cout;
+using std::endl;
+
#include <string>
#include <vector>
#include <algorithm>
@@ -98,6 +102,7 @@
fs::path d1f1;
bool create_symlink_ok(true);
+
fs::path ng(" no-way, Jose");
unsigned short language_id; // 0 except for Windows
@@ -136,17 +141,17 @@
if (report_throws)
{
// use the what() convenience function to display exceptions
- std::cout << "\n" << ex.what() << "\n";
+ cout << "\n" << ex.what() << "\n";
}
if (en == 0
|| en == ex.code().default_error_condition().value()) return true;
- std::cout
+ cout
<< "\nWarning: line " << line
<< " exception reports default_error_condition().value() "
<< ex.code().default_error_condition().value()
<< ", should be " << en
<< "\n value() is " << ex.code().value()
- << std::endl;
+ << endl;
return true;
}
return false;
@@ -214,16 +219,55 @@
fs::path to;
};
+ //------------------------------ debugging aids --------------------------------------//
+
+ std::ostream& operator<<(std::ostream& os, const fs::file_status& s)
+ {
+ if (s.type() == fs::status_error) { os << "status_error"; }
+ else if (s.type() == fs::file_not_found) { os << "file_not_found"; }
+ else if (s.type() == fs::regular_file) { os << "regular_file"; }
+ else if (s.type() == fs::directory_file) { os << "directory_file"; }
+ else if (s.type() == fs::symlink_file) { os << "symlink_file"; }
+ else if (s.type() == fs::block_file) { os << "block_file"; }
+ else if (s.type() == fs::character_file) { os << "character_file"; }
+ else if (s.type() == fs::fifo_file) { os << "fifo_file"; }
+ else if (s.type() == fs::socket_file) { os << "socket_file"; }
+ else if (s.type() == fs::reparse_file) { os << "reparse_file"; }
+ else if (s.type() == fs::type_unknown) { os << "type_unknown"; }
+ else { os << "_detail_directory_symlink"; }
+ return os;
+ }
+
+ void dump_tree(const fs::path & root)
+ {
+ cout << "dumping tree rooted at " << root << endl;
+ for (fs::recursive_directory_iterator it (root, fs::symlink_option::recurse);
+ it != fs::recursive_directory_iterator();
+ ++it)
+ {
+ for (int i = 0; i <= it.level(); ++i)
+ cout << " ";
+
+ cout << it->path();
+ if (fs::is_symlink(it->path()))
+ {
+ cout << " [symlink]" << endl;
+ }
+ else
+ cout << endl;
+ }
+ }
+
// exception_tests() ---------------------------------------------------------------//
void exception_tests()
{
- std::cout << "exception_tests..." << std::endl;
+ cout << "exception_tests..." << endl;
bool exception_thrown;
// catch runtime_error by value
- std::cout << " catch runtime_error by value" << std::endl;
+ cout << " catch runtime_error by value" << endl;
exception_thrown = false;
try
{
@@ -232,7 +276,7 @@
catch (std::runtime_error x)
{
exception_thrown = true;
- if (report_throws) std::cout << x.what() << std::endl;
+ if (report_throws) cout << x.what() << endl;
if (platform == "Windows" && language_id == 0x0409) // English (United States)
// the stdcxx standard library apparently appends additional info
// to what(), so check only the initial portion:
@@ -244,7 +288,7 @@
// catch system_error by value
- std::cout << " catch system_error by value" << std::endl;
+ cout << " catch system_error by value" << endl;
exception_thrown = false;
try
{
@@ -253,7 +297,7 @@
catch (system_error x)
{
exception_thrown = true;
- if (report_throws) std::cout << x.what() << std::endl;
+ if (report_throws) cout << x.what() << endl;
if (platform == "Windows" && language_id == 0x0409) // English (United States)
BOOST_TEST(std::strcmp(x.what(),
"boost::filesystem::create_directory: The system cannot find the path specified") == 0);
@@ -262,7 +306,7 @@
// catch filesystem_error by value
- std::cout << " catch filesystem_error by value" << std::endl;
+ cout << " catch filesystem_error by value" << endl;
exception_thrown = false;
try
{
@@ -271,7 +315,7 @@
catch (fs::filesystem_error x)
{
exception_thrown = true;
- if (report_throws) std::cout << x.what() << std::endl;
+ if (report_throws) cout << x.what() << endl;
if (platform == "Windows" && language_id == 0x0409) // English (United States)
{
bool ok (std::strcmp(x.what(),
@@ -279,7 +323,7 @@
BOOST_TEST(ok);
if (!ok)
{
- std::cout << "what returns \"" << x.what() << "\"" << std::endl;
+ cout << "what returns \"" << x.what() << "\"" << endl;
}
}
}
@@ -287,7 +331,7 @@
// catch filesystem_error by const reference
- std::cout << " catch filesystem_error by const reference" << std::endl;
+ cout << " catch filesystem_error by const reference" << endl;
exception_thrown = false;
try
{
@@ -296,7 +340,7 @@
catch (const fs::filesystem_error & x)
{
exception_thrown = true;
- if (report_throws) std::cout << x.what() << std::endl;
+ if (report_throws) cout << x.what() << endl;
if (platform == "Windows" && language_id == 0x0409) // English (United States)
{
bool ok (std::strcmp(x.what(),
@@ -304,7 +348,7 @@
BOOST_TEST(ok);
if (!ok)
{
- std::cout << "what returns \"" << x.what() << "\"" << std::endl;
+ cout << "what returns \"" << x.what() << "\"" << endl;
}
}
}
@@ -327,7 +371,7 @@
BOOST_TEST(ex.path1().string() == " no-way, Jose");
}
- std::cout << " exception_tests complete" << std::endl;
+ cout << " exception_tests complete" << endl;
}
// create a directory tree that can be used by subsequent tests ---------------------//
@@ -385,7 +429,7 @@
void directory_iterator_tests()
{
- std::cout << "directory_iterator_tests..." << std::endl;
+ cout << "directory_iterator_tests..." << endl;
bool dir_itr_exception(false);
try { fs::directory_iterator it(""); }
@@ -418,20 +462,6 @@
catch (const fs::filesystem_error &) { dir_itr_exception = true; }
BOOST_TEST(!dir_itr_exception);
- {
- // probe query function overloads
- fs::directory_iterator dir_itr(dir);
- // BOOST_TEST(fs::is_directory(*dir_itr));
- BOOST_TEST(fs::is_directory(dir_itr->status())
- || fs::is_regular_file(dir_itr->status()));
- // BOOST_TEST(fs::is_directory(fs::symlink_status(*dir_itr)));
- BOOST_TEST(fs::is_directory(dir_itr->symlink_status())
- || fs::is_regular_file(dir_itr->symlink_status()));
- BOOST_TEST(dir_itr->path().filename() == "d1"
- || dir_itr->path().filename() == "d2" || dir_itr->path().filename() == "f0"
- || dir_itr->path().filename() == "f1");
- }
-
// create a second directory named d2
d2 = dir / "d2";
fs::create_directory(d2);
@@ -552,14 +582,117 @@
BOOST_TEST(++di != fs::directory_iterator());
}
- std::cout << " directory_iterator_tests complete" << std::endl;
+ cout << " directory_iterator_tests complete" << endl;
+ }
+
+ // recursive_directory_iterator_tests ----------------------------------------------//
+
+ int walk_tree(bool recursive)
+ {
+ int d1f1_count = 0;
+ for (fs::recursive_directory_iterator it (dir,
+ recursive ? fs::symlink_option::recurse : fs::symlink_option::no_recurse);
+ it != fs::recursive_directory_iterator();
+ ++it)
+ {
+ if (it->path().filename() == "d1f1")
+ ++d1f1_count;
+ }
+ return d1f1_count;
+ }
+
+ void recursive_directory_iterator_tests()
+ {
+ cout << "recursive_directory_iterator_tests..." << endl;
+ BOOST_TEST(walk_tree(false) == 1);
+ if (create_symlink_ok)
+ BOOST_TEST(walk_tree(true) > 1);
+ cout << " recursive_directory_iterator_tests complete" << endl;
+ }
+
+ // iterator_status_tests -----------------------------------------------------------//
+
+ void iterator_status_tests()
+ {
+ cout << "iterator_status_tests..." << endl;
+
+ error_code ec;
+ // harmless if these fail:
+ fs::create_symlink(dir/"f0", dir/"f0_symlink", ec);
+ fs::create_symlink(dir/"no such file", dir/"dangling_symlink", ec);
+ fs::create_directory_symlink(dir/"d1", dir/"d1_symlink", ec);
+ fs::create_directory_symlink(dir/"no such directory",
+ dir/"dangling_directory_symlink", ec);
+
+ for (fs::directory_iterator it(dir);
+ it != fs::directory_iterator(); ++it)
+ {
+ BOOST_TEST(fs::status(it->path()).type() == it->status().type());
+ BOOST_TEST(fs::symlink_status(it->path()).type() == it->symlink_status().type());
+ if (it->path().filename() == "d1")
+ {
+ BOOST_TEST(fs::is_directory(it->status()));
+ BOOST_TEST(fs::is_directory(it->symlink_status()));
+ }
+ else if (it->path().filename() == "d2")
+ {
+ BOOST_TEST(fs::is_directory(it->status()));
+ BOOST_TEST(fs::is_directory(it->symlink_status()));
+ }
+ else if (it->path().filename() == "f0")
+ {
+ BOOST_TEST(fs::is_regular_file(it->status()));
+ BOOST_TEST(fs::is_regular_file(it->symlink_status()));
+ }
+ else if (it->path().filename() == "f1")
+ {
+ BOOST_TEST(fs::is_regular_file(it->status()));
+ BOOST_TEST(fs::is_regular_file(it->symlink_status()));
+ }
+ else if (it->path().filename() == "f0_symlink")
+ {
+ BOOST_TEST(fs::is_regular_file(it->status()));
+ BOOST_TEST(fs::is_symlink(it->symlink_status()));
+ }
+ else if (it->path().filename() == "dangling_symlink")
+ {
+ BOOST_TEST(it->status().type() == fs::file_not_found);
+ BOOST_TEST(fs::is_symlink(it->symlink_status()));
+ }
+ else if (it->path().filename() == "d1_symlink")
+ {
+ BOOST_TEST(fs::is_directory(it->status()));
+ BOOST_TEST(fs::is_symlink(it->symlink_status()));
+ }
+ else if (it->path().filename() == "dangling_directory_symlink")
+ {
+ BOOST_TEST(it->status().type() == fs::file_not_found);
+ BOOST_TEST(fs::is_symlink(it->symlink_status()));
+ }
+ //else
+ // cout << " Note: unexpected directory entry " << it->path().filename() << endl;
+ }
+ }
+
+ // recursive_iterator_status_tests -------------------------------------------------//
+
+ void recursive_iterator_status_tests()
+ {
+ cout << "recursive_iterator_status_tests..." << endl;
+ for (fs::recursive_directory_iterator it (dir);
+ it != fs::recursive_directory_iterator();
+ ++it)
+ {
+ BOOST_TEST(fs::status(it->path()).type() == it->status().type());
+ BOOST_TEST(fs::symlink_status(it->path()).type() == it->symlink_status().type());
+ }
}
// create_hard_link_tests ----------------------------------------------------------//
void create_hard_link_tests()
{
- std::cout << "create_hard_link_tests..." << std::endl;
+ cout << "create_hard_link_tests..." << endl;
fs::path from_ph(dir / "f3");
fs::path f1(dir / "f1");
@@ -571,7 +704,7 @@
catch (const fs::filesystem_error & ex)
{
create_hard_link_ok = false;
- std::cout
+ cout
<< " *** For information only ***\n"
" create_hard_link() attempt failed\n"
" filesystem_error.what() reports: " << ex.what() << "\n"
@@ -580,7 +713,7 @@
if (create_hard_link_ok)
{
- std::cout
+ cout
<< " *** For information only ***\n"
" create_hard_link() succeeded\n";
BOOST_TEST(fs::exists(from_ph));
@@ -605,7 +738,7 @@
void create_symlink_tests()
{
- std::cout << "create_symlink_tests..." << std::endl;
+ cout << "create_symlink_tests..." << endl;
fs::path from_ph(dir / "f4");
fs::path f1(dir / "f1");
@@ -615,7 +748,7 @@
catch (const fs::filesystem_error & ex)
{
create_symlink_ok = false;
- std::cout
+ cout
<< " *** For information only ***\n"
" create_symlink() attempt failed\n"
" filesystem_error.what() reports: " << ex.what() << "\n"
@@ -624,7 +757,7 @@
if (create_symlink_ok)
{
- std::cout
+ cout
<< " *** For information only ***\n"
" create_symlink() succeeded\n";
BOOST_TEST(fs::exists(from_ph));
@@ -667,7 +800,7 @@
void rename_tests()
{
- std::cout << "rename_tests..." << std::endl;
+ cout << "rename_tests..." << endl;
fs::path f1(dir / "f1");
BOOST_TEST(fs::exists(f1));
@@ -772,7 +905,7 @@
void predicate_and_status_tests()
{
- std::cout << "predicate_and_status_tests..." << std::endl;
+ cout << "predicate_and_status_tests..." << endl;
BOOST_TEST(!fs::exists(ng));
BOOST_TEST(!fs::is_directory(ng));
@@ -798,7 +931,7 @@
void create_directory_tests()
{
- std::cout << "create_directory_tests..." << std::endl;
+ cout << "create_directory_tests..." << endl;
// create a directory, then check it for consistency
// take extra care to report problems, since if this fails
@@ -810,7 +943,7 @@
catch (const fs::filesystem_error & x)
{
- std::cout << x.what() << "\n\n"
+ cout << x.what() << "\n\n"
"***** Creating directory " << dir << " failed. *****\n"
"***** This is a serious error that will prevent further tests *****\n"
"***** from returning useful results. Further testing is aborted. *****\n\n";
@@ -819,7 +952,7 @@
catch (...)
{
- std::cout << "\n\n"
+ cout << "\n\n"
"***** Creating directory " << dir << " failed. *****\n"
"***** This is a serious error that will prevent further tests *****\n"
"***** from returning useful results. Further testing is aborted. *****\n\n";
@@ -839,14 +972,14 @@
BOOST_TEST(!fs::is_other(stat));
BOOST_TEST(!fs::is_symlink(stat));
- std::cout << " create_directory_tests complete" << std::endl;
+ cout << " create_directory_tests complete" << endl;
}
// current_directory_tests ---------------------------------------------------------//
void current_directory_tests()
{
- std::cout << "current_directory_tests..." << std::endl;
+ cout << "current_directory_tests..." << endl;
// set the current directory, then check it for consistency
fs::path original_dir = fs::current_path();
@@ -871,7 +1004,7 @@
void create_directories_tests()
{
- std::cout << "create_directories_tests..." << std::endl;
+ cout << "create_directories_tests..." << endl;
fs::path p = dir / "level1" / "level2";
@@ -885,7 +1018,7 @@
void resize_file_tests()
{
- std::cout << "resize_file_tests..." << std::endl;
+ cout << "resize_file_tests..." << endl;
fs::path p(dir / "resize_file_test.txt");
@@ -910,7 +1043,7 @@
void status_of_nonexistent_tests()
{
- std::cout << "status_of_nonexistent_tests..." << std::endl;
+ cout << "status_of_nonexistent_tests..." << endl;
fs::path p ("nosuch");
BOOST_TEST(!fs::exists(p));
BOOST_TEST(!fs::is_regular_file(p));
@@ -932,7 +1065,7 @@
void status_error_reporting_tests()
{
- std::cout << "status_error_reporting_tests..." << std::endl;
+ cout << "status_error_reporting_tests..." << endl;
error_code ec;
@@ -994,7 +1127,7 @@
void remove_tests(const fs::path& dir)
{
- std::cout << "remove_tests..." << std::endl;
+ cout << "remove_tests..." << endl;
// remove() file
fs::path f1 = dir / "shortlife";
@@ -1024,7 +1157,7 @@
void remove_symlink_tests()
{
- std::cout << "remove_symlink_tests..." << std::endl;
+ cout << "remove_symlink_tests..." << endl;
// remove() dangling symbolic link
fs::path link("dangling_link");
@@ -1088,7 +1221,7 @@
void absolute_tests()
{
- std::cout << "absolute_tests..." << std::endl;
+ cout << "absolute_tests..." << endl;
BOOST_TEST_EQ(fs::absolute(""), fs::current_path() );
BOOST_TEST_EQ(fs::absolute(fs::current_path() / "foo/bar"), fs::current_path() / "foo/bar");
@@ -1162,15 +1295,15 @@
void copy_file_tests(const fs::path& f1, const fs::path& d1)
{
- std::cout << "copy_file_tests..." << std::endl;
+ cout << "copy_file_tests..." << endl;
BOOST_TEST(fs::exists(f1));
fs::remove(d1 / "f2"); // remove possible residue from prior testing
BOOST_TEST(fs::exists(d1));
BOOST_TEST(!fs::exists(d1 / "f2"));
- std::cout << " copy " << f1 << " to " << d1 / "f2" << std::endl;
+ cout << " copy " << f1 << " to " << d1 / "f2" << endl;
fs::copy_file(f1, d1 / "f2");
- std::cout << " copy complete" << std::endl;
+ cout << " copy complete" << endl;
BOOST_TEST(fs::exists(f1));
BOOST_TEST(fs::exists(d1 / "f2"));
BOOST_TEST(!fs::is_directory(d1 / "f2"));
@@ -1200,7 +1333,7 @@
void symlink_status_tests()
{
- std::cout << "symlink_status_tests..." << std::endl;
+ cout << "symlink_status_tests..." << endl;
boost::system::error_code ec;
@@ -1262,7 +1395,7 @@
void copy_symlink_tests(const fs::path& f1, const fs::path& d1)
{
- std::cout << "copy_symlink_tests..." << std::endl;
+ cout << "copy_symlink_tests..." << endl;
BOOST_TEST(fs::exists(f1));
BOOST_TEST(fs::exists(d1));
@@ -1295,7 +1428,7 @@
void write_time_tests(const fs::path& dir)
{
- std::cout << "write_time_tests..." << std::endl;
+ cout << "write_time_tests..." << endl;
fs::path f1 = dir / "foobar2";
create_file(f1, "foobar2");
@@ -1310,25 +1443,25 @@
// if time_t is local or UTC.
std::time_t ft = fs::last_write_time(f1);
- std::cout << "\n UTC last_write_time() for a file just created is "
- << std::asctime(std::gmtime(&ft)) << std::endl;
+ cout << "\n UTC last_write_time() for a file just created is "
+ << std::asctime(std::gmtime(&ft)) << endl;
std::tm * tmp = std::localtime(&ft);
- std::cout << "\n Year is " << tmp->tm_year << std::endl;
+ cout << "\n Year is " << tmp->tm_year << endl;
--tmp->tm_year;
- std::cout << " Change year to " << tmp->tm_year << std::endl;
+ cout << " Change year to " << tmp->tm_year << endl;
fs::last_write_time(f1, std::mktime(tmp));
std::time_t ft2 = fs::last_write_time(f1);
- std::cout << " last_write_time() for the file is now "
- << std::asctime(std::gmtime(&ft2)) << std::endl;
+ cout << " last_write_time() for the file is now "
+ << std::asctime(std::gmtime(&ft2)) << endl;
BOOST_TEST(ft != fs::last_write_time(f1));
- std::cout << "\n Reset to current time" << std::endl;
+ cout << "\n Reset to current time" << endl;
fs::last_write_time(f1, ft);
double time_diff = std::difftime(ft, fs::last_write_time(f1));
- std::cout
+ cout
<< " original last_write_time() - current last_write_time() is "
- << time_diff << " seconds" << std::endl;
+ << time_diff << " seconds" << endl;
BOOST_TEST(time_diff >= -60.0 && time_diff <= 60.0);
}
@@ -1339,8 +1472,8 @@
// Windows only tests
if (platform == "Windows")
{
- std::cout << "Window specific tests..."
- "\n (may take several seconds)" << std::endl;
+ cout << "Window specific tests..."
+ "\n (may take several seconds)" << endl;
BOOST_TEST(!fs::exists(fs::path("//share-not")));
BOOST_TEST(!fs::exists(fs::path("//share-not/")));
@@ -1375,7 +1508,7 @@
else if (platform == "POSIX")
{
- std::cout << "POSIX specific tests..." << std::endl;
+ cout << "POSIX specific tests..." << endl;
BOOST_TEST(fs::system_complete("").empty());
BOOST_TEST(fs::initial_path().root_path().string() == "/");
BOOST_TEST(fs::system_complete("/").string() == "/");
@@ -1390,9 +1523,9 @@
void initial_tests()
{
- std::cout << "initial_tests..." << std::endl;
+ cout << "initial_tests..." << endl;
- std::cout << " current_path().string() is\n \""
+ cout << " current_path().string() is\n \""
<< fs::initial_path().string()
<< "\"\n\n";
BOOST_TEST(fs::initial_path() == fs::current_path());
@@ -1406,7 +1539,7 @@
void space_tests()
{
- std::cout << "space_tests..." << std::endl;
+ cout << "space_tests..." << endl;
// make some reasonable assuptions for testing purposes
fs::space_info spi(fs::space(dir));
@@ -1417,9 +1550,9 @@
// it is convenient to display space, but older VC++ versions choke
# if !defined(BOOST_MSVC) || _MSC_VER >= 1300 // 1300 == VC++ 7.0
- std::cout << " capacity = " << spi.capacity << '\n';
- std::cout << " free = " << spi.free << '\n';
- std::cout << " available = " << spi.available << '\n';
+ cout << " capacity = " << spi.capacity << '\n';
+ cout << " free = " << spi.free << '\n';
+ cout << " available = " << spi.available << '\n';
# endif
}
@@ -1427,7 +1560,7 @@
void equivalent_tests(const fs::path& f1)
{
- std::cout << "equivalent_tests..." << std::endl;
+ cout << "equivalent_tests..." << endl;
BOOST_TEST(CHECK_EXCEPTION(bad_equivalent, ENOENT));
BOOST_TEST(fs::equivalent(f1, dir / "f1"));
@@ -1485,7 +1618,7 @@
void temp_directory_path_tests()
{
{
- std::cout << "temp_directory_path_tests..." << std::endl;
+ cout << "temp_directory_path_tests..." << endl;
BOOST_TEST(!fs::temp_directory_path().empty());
BOOST_TEST(exists(fs::temp_directory_path()));
@@ -1611,7 +1744,7 @@
void _tests()
{
- std::cout << "_tests..." << std::endl;
+ cout << "_tests..." << endl;
}
} // unnamed namespace
@@ -1626,10 +1759,10 @@
{
// document state of critical macros
#ifdef BOOST_POSIX_API
- std::cout << "BOOST_POSIX_API is defined\n";
+ cout << "BOOST_POSIX_API is defined\n";
#endif
#ifdef BOOST_WINDOWS_API
- std::cout << "BOOST_WINDOWS_API is defined\n";
+ cout << "BOOST_WINDOWS_API is defined\n";
#endif
if (argc > 1 && *argv[1]=='-' && *(argv[1]+1)=='t') report_throws = true;
@@ -1650,19 +1783,19 @@
# else
# error neither BOOST_POSIX_API nor BOOST_WINDOWS_API is defined. See boost/system/api_config.hpp
# endif
- std::cout << "API is " << platform << std::endl;
+ cout << "API is " << platform << endl;
dir = fs::initial_path() / temp_dir_name;
if (fs::exists(dir))
{
- std::cout << "remove residue from prior failed tests..." << std::endl;
+ cout << "remove residue from prior failed tests..." << endl;
fs::remove_all(dir);
}
BOOST_TEST(!fs::exists(dir));
// several functions give unreasonable results if uintmax_t isn't 64-bits
- std::cout << "sizeof(boost::uintmax_t) = " << sizeof(boost::uintmax_t) << '\n';
+ cout << "sizeof(boost::uintmax_t) = " << sizeof(boost::uintmax_t) << '\n';
BOOST_TEST(sizeof(boost::uintmax_t) >= 8);
initial_tests();
@@ -1709,6 +1842,10 @@
symlink_status_tests();
copy_symlink_tests(f1, d1);
}
+ iterator_status_tests(); // lots of cases by now, so a good time to test
+// dump_tree(dir);
+ recursive_directory_iterator_tests();
+ recursive_iterator_status_tests(); // lots of cases by now, so a good time to test
rename_tests();
remove_tests(dir);
if (create_symlink_ok) // only if symlinks supported
@@ -1717,20 +1854,20 @@
temp_directory_path_tests();
- std::cout << "testing complete" << std::endl;
+ cout << "testing complete" << endl;
// post-test cleanup
if (cleanup)
{
- std::cout << "post-test removal of " << dir << std::endl;
+ cout << "post-test removal of " << dir << endl;
BOOST_TEST(fs::remove_all(dir) != 0);
// above was added just to simplify testing, but it ended up detecting
// a bug (failure to close an internal search handle).
- std::cout << "post-test removal complete" << std::endl;
+ cout << "post-test removal complete" << endl;
BOOST_TEST(!fs::exists(dir));
BOOST_TEST(fs::remove_all(dir) == 0);
}
- std::cout << "returning from main()" << std::endl;
+ cout << "returning from main()" << endl;
return ::boost::report_errors();
} // main
Boost-Commit list run by bdawes at acm.org, david.abrahams at rcn.com, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk